aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Rutkovsky <alexvru@mail.ru>2022-02-10 16:47:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:47:39 +0300
commitf3646f91e0de459836a7800b9ce3e8dc57a2ab3a (patch)
tree25c1423200152570c1f8307e5b8304b9bc3840c5
parentfccc62e9bfdce9be2fe7e0f23479da3a5512211a (diff)
downloadydb-f3646f91e0de459836a7800b9ce3e8dc57a2ab3a.tar.gz
Restoring authorship annotation for Alexander Rutkovsky <alexvru@mail.ru>. Commit 1 of 2.
-rw-r--r--contrib/libs/grpc/src/cpp/common/channel_arguments.cc2
-rw-r--r--library/cpp/actors/core/actor.cpp54
-rw-r--r--library/cpp/actors/core/actor.h106
-rw-r--r--library/cpp/actors/core/actor_bootstrapped.h34
-rw-r--r--library/cpp/actors/core/actor_coroutine.cpp234
-rw-r--r--library/cpp/actors/core/actor_coroutine.h224
-rw-r--r--library/cpp/actors/core/actor_coroutine_ut.cpp236
-rw-r--r--library/cpp/actors/core/actorsystem.cpp62
-rw-r--r--library/cpp/actors/core/actorsystem.h58
-rw-r--r--library/cpp/actors/core/defs.h34
-rw-r--r--library/cpp/actors/core/event.cpp14
-rw-r--r--library/cpp/actors/core/event.h102
-rw-r--r--library/cpp/actors/core/event_load.h166
-rw-r--r--library/cpp/actors/core/event_local.h18
-rw-r--r--library/cpp/actors/core/event_pb.cpp314
-rw-r--r--library/cpp/actors/core/event_pb.h512
-rw-r--r--library/cpp/actors/core/event_pb_payload_ut.cpp72
-rw-r--r--library/cpp/actors/core/event_pb_ut.cpp102
-rw-r--r--library/cpp/actors/core/events.h52
-rw-r--r--library/cpp/actors/core/events_undelivered.cpp36
-rw-r--r--library/cpp/actors/core/executelater.h12
-rw-r--r--library/cpp/actors/core/executor_pool_io.cpp30
-rw-r--r--library/cpp/actors/core/executor_pool_io.h6
-rw-r--r--library/cpp/actors/core/executor_thread.h2
-rw-r--r--library/cpp/actors/core/hfunc.h10
-rw-r--r--library/cpp/actors/core/interconnect.cpp342
-rw-r--r--library/cpp/actors/core/interconnect.h252
-rw-r--r--library/cpp/actors/core/invoke.h204
-rw-r--r--library/cpp/actors/core/io_dispatcher.cpp466
-rw-r--r--library/cpp/actors/core/io_dispatcher.h76
-rw-r--r--library/cpp/actors/core/log_settings.h4
-rw-r--r--library/cpp/actors/core/mailbox.h48
-rw-r--r--library/cpp/actors/core/mon.h80
-rw-r--r--library/cpp/actors/core/probes.h10
-rw-r--r--library/cpp/actors/core/scheduler_actor.cpp244
-rw-r--r--library/cpp/actors/core/ut/ya.make16
-rw-r--r--library/cpp/actors/core/ya.make32
-rw-r--r--library/cpp/actors/helpers/activeactors.h10
-rw-r--r--library/cpp/actors/helpers/mon_histogram_helper.h6
-rw-r--r--library/cpp/actors/helpers/selfping_actor.cpp106
-rw-r--r--library/cpp/actors/helpers/selfping_actor.h18
-rw-r--r--library/cpp/actors/helpers/selfping_actor_ut.cpp48
-rw-r--r--library/cpp/actors/http/http.h2
-rw-r--r--library/cpp/actors/http/http_proxy_acceptor.cpp34
-rw-r--r--library/cpp/actors/http/http_proxy_incoming.cpp218
-rw-r--r--library/cpp/actors/http/http_proxy_outgoing.cpp126
-rw-r--r--library/cpp/actors/http/http_proxy_sock_impl.h48
-rw-r--r--library/cpp/actors/interconnect/channel_scheduler.h226
-rw-r--r--library/cpp/actors/interconnect/event_filter.h142
-rw-r--r--library/cpp/actors/interconnect/event_holder_pool.h242
-rw-r--r--library/cpp/actors/interconnect/events_local.h162
-rw-r--r--library/cpp/actors/interconnect/interconnect.h70
-rw-r--r--library/cpp/actors/interconnect/interconnect_address.cpp128
-rw-r--r--library/cpp/actors/interconnect/interconnect_address.h36
-rw-r--r--library/cpp/actors/interconnect/interconnect_channel.cpp306
-rw-r--r--library/cpp/actors/interconnect/interconnect_channel.h178
-rw-r--r--library/cpp/actors/interconnect/interconnect_common.h122
-rw-r--r--library/cpp/actors/interconnect/interconnect_counters.cpp436
-rw-r--r--library/cpp/actors/interconnect/interconnect_counters.h20
-rw-r--r--library/cpp/actors/interconnect/interconnect_handshake.cpp1864
-rw-r--r--library/cpp/actors/interconnect/interconnect_handshake.h32
-rw-r--r--library/cpp/actors/interconnect/interconnect_impl.h32
-rw-r--r--library/cpp/actors/interconnect/interconnect_mon.cpp524
-rw-r--r--library/cpp/actors/interconnect/interconnect_mon.h24
-rw-r--r--library/cpp/actors/interconnect/interconnect_nameserver_table.cpp50
-rw-r--r--library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp94
-rw-r--r--library/cpp/actors/interconnect/interconnect_proxy_wrapper.h24
-rw-r--r--library/cpp/actors/interconnect/interconnect_stream.cpp926
-rw-r--r--library/cpp/actors/interconnect/interconnect_stream.h192
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp902
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp1236
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_proxy.h710
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_server.cpp172
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_server.h58
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_session.cpp1620
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_session.h754
-rw-r--r--library/cpp/actors/interconnect/load.cpp716
-rw-r--r--library/cpp/actors/interconnect/load.h28
-rw-r--r--library/cpp/actors/interconnect/logging.h84
-rw-r--r--library/cpp/actors/interconnect/mock/ic_mock.cpp572
-rw-r--r--library/cpp/actors/interconnect/mock/ic_mock.h38
-rw-r--r--library/cpp/actors/interconnect/mock/ya.make28
-rw-r--r--library/cpp/actors/interconnect/packet.cpp54
-rw-r--r--library/cpp/actors/interconnect/packet.h596
-rw-r--r--library/cpp/actors/interconnect/poller.h20
-rw-r--r--library/cpp/actors/interconnect/poller_actor.cpp488
-rw-r--r--library/cpp/actors/interconnect/poller_actor.h108
-rw-r--r--library/cpp/actors/interconnect/poller_actor_darwin.h190
-rw-r--r--library/cpp/actors/interconnect/poller_actor_linux.h228
-rw-r--r--library/cpp/actors/interconnect/poller_actor_win.h206
-rw-r--r--library/cpp/actors/interconnect/poller_tcp.cpp20
-rw-r--r--library/cpp/actors/interconnect/poller_tcp.h28
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit.cpp68
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit.h56
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp76
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_epoll.h26
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_select.cpp72
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_select.h18
-rw-r--r--library/cpp/actors/interconnect/profiler.h274
-rw-r--r--library/cpp/actors/interconnect/slowpoke_actor.h84
-rw-r--r--library/cpp/actors/interconnect/types.cpp1128
-rw-r--r--library/cpp/actors/interconnect/types.h86
-rw-r--r--library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp216
-rw-r--r--library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp358
-rw-r--r--library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp100
-rw-r--r--library/cpp/actors/interconnect/ut/interconnect_ut.cpp354
-rw-r--r--library/cpp/actors/interconnect/ut/large.cpp156
-rw-r--r--library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h12
-rw-r--r--library/cpp/actors/interconnect/ut/lib/interrupter.h22
-rw-r--r--library/cpp/actors/interconnect/ut/lib/node.h130
-rw-r--r--library/cpp/actors/interconnect/ut/lib/test_actors.h28
-rw-r--r--library/cpp/actors/interconnect/ut/poller_actor_ut.cpp258
-rw-r--r--library/cpp/actors/interconnect/ut/ya.make12
-rw-r--r--library/cpp/actors/interconnect/ut_fat/ya.make2
-rw-r--r--library/cpp/actors/interconnect/watchdog_timer.h126
-rw-r--r--library/cpp/actors/interconnect/ya.make134
-rw-r--r--library/cpp/actors/protos/interconnect.proto134
-rw-r--r--library/cpp/actors/protos/services_common.proto8
-rw-r--r--library/cpp/actors/protos/unittests.proto10
-rw-r--r--library/cpp/actors/protos/ya.make6
-rw-r--r--library/cpp/actors/testlib/test_runtime.cpp46
-rw-r--r--library/cpp/actors/testlib/test_runtime.h14
-rw-r--r--library/cpp/actors/testlib/ya.make2
-rw-r--r--library/cpp/actors/util/named_tuple.h46
-rw-r--r--library/cpp/actors/util/rope.h2000
-rw-r--r--library/cpp/actors/util/rope_cont_deque.h362
-rw-r--r--library/cpp/actors/util/rope_cont_list.h318
-rw-r--r--library/cpp/actors/util/rope_ut.cpp460
-rw-r--r--library/cpp/actors/util/ut/ya.make14
-rw-r--r--library/cpp/actors/util/ya.make6
-rw-r--r--library/cpp/actors/wilson/wilson_event.h198
-rw-r--r--library/cpp/actors/wilson/wilson_trace.h262
-rw-r--r--library/cpp/actors/wilson/ya.make4
-rw-r--r--library/cpp/grpc/server/grpc_counters.h36
-rw-r--r--library/cpp/grpc/server/grpc_request.h4
-rw-r--r--library/cpp/grpc/server/grpc_server.cpp20
-rw-r--r--library/cpp/grpc/server/grpc_server.h16
-rw-r--r--library/cpp/messagebus/oldmodule/module.h4
-rw-r--r--library/cpp/monlib/dynamic_counters/contention_ut.cpp110
-rw-r--r--library/cpp/monlib/dynamic_counters/counters.cpp152
-rw-r--r--library/cpp/monlib/dynamic_counters/counters.h98
-rw-r--r--library/cpp/monlib/dynamic_counters/ut/ya.make2
-rw-r--r--util/generic/bitmap.h18
-rw-r--r--util/generic/bitmap_ut.cpp24
-rw-r--r--util/generic/ptr.h6
-rw-r--r--ydb/core/actorlib_impl/actor_bootstrapped_ut.cpp84
-rw-r--r--ydb/core/actorlib_impl/actor_tracker.cpp368
-rw-r--r--ydb/core/actorlib_impl/actor_tracker.h246
-rw-r--r--ydb/core/actorlib_impl/actor_tracker_ut.cpp218
-rw-r--r--ydb/core/actorlib_impl/async_destroyer.h4
-rw-r--r--ydb/core/actorlib_impl/connect_socket_protocol.cpp2
-rw-r--r--ydb/core/actorlib_impl/defs.h4
-rw-r--r--ydb/core/actorlib_impl/load_network.cpp4
-rw-r--r--ydb/core/actorlib_impl/long_timer.cpp2
-rw-r--r--ydb/core/actorlib_impl/node_identifier.cpp2
-rw-r--r--ydb/core/actorlib_impl/read_data_protocol.cpp38
-rw-r--r--ydb/core/actorlib_impl/send_data_protocol.cpp20
-rw-r--r--ydb/core/actorlib_impl/test_interconnect_ut.cpp1214
-rw-r--r--ydb/core/actorlib_impl/ut/ya.make6
-rw-r--r--ydb/core/actorlib_impl/ya.make14
-rw-r--r--ydb/core/base/appdata.cpp4
-rw-r--r--ydb/core/base/appdata.h12
-rw-r--r--ydb/core/base/blobstorage.cpp114
-rw-r--r--ydb/core/base/blobstorage.h614
-rw-r--r--ydb/core/base/blobstorage_grouptype.cpp40
-rw-r--r--ydb/core/base/blobstorage_grouptype.h12
-rw-r--r--ydb/core/base/blobstorage_grouptype_ut.cpp26
-rw-r--r--ydb/core/base/board_lookup.cpp4
-rw-r--r--ydb/core/base/board_publish.cpp8
-rw-r--r--ydb/core/base/board_replica.cpp4
-rw-r--r--ydb/core/base/compile_time_flags.h12
-rw-r--r--ydb/core/base/config_units.h24
-rw-r--r--ydb/core/base/counters.cpp2
-rw-r--r--ydb/core/base/event_filter.cpp16
-rw-r--r--ydb/core/base/event_filter.h126
-rw-r--r--ydb/core/base/events.h2
-rw-r--r--ydb/core/base/group_stat.cpp218
-rw-r--r--ydb/core/base/group_stat.h522
-rw-r--r--ydb/core/base/interconnect_channels.h8
-rw-r--r--ydb/core/base/location.h2
-rw-r--r--ydb/core/base/logoblob.h30
-rw-r--r--ydb/core/base/pool_stats_collector.cpp4
-rw-r--r--ydb/core/base/services/blobstorage_service_id.h26
-rw-r--r--ydb/core/base/services_assert.cpp2
-rw-r--r--ydb/core/base/statestorage_guardian.cpp12
-rw-r--r--ydb/core/base/statestorage_monitoring.cpp4
-rw-r--r--ydb/core/base/statestorage_proxy.cpp20
-rw-r--r--ydb/core/base/statestorage_replica.cpp4
-rw-r--r--ydb/core/base/tablet_killer.cpp4
-rw-r--r--ydb/core/base/tablet_pipe.h2
-rw-r--r--ydb/core/base/tablet_status_checker.cpp4
-rw-r--r--ydb/core/base/tablet_types.h2
-rw-r--r--ydb/core/base/ya.make8
-rw-r--r--ydb/core/blobstorage/backpressure/common.h34
-rw-r--r--ydb/core/blobstorage/backpressure/defs.h12
-rw-r--r--ydb/core/blobstorage/backpressure/event.cpp178
-rw-r--r--ydb/core/blobstorage/backpressure/event.h266
-rw-r--r--ydb/core/blobstorage/backpressure/queue.cpp666
-rw-r--r--ydb/core/blobstorage/backpressure/queue.h456
-rw-r--r--ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp1592
-rw-r--r--ydb/core/blobstorage/backpressure/queue_backpressure_client.h58
-rw-r--r--ydb/core/blobstorage/backpressure/queue_backpressure_client_ut.cpp526
-rw-r--r--ydb/core/blobstorage/backpressure/queue_backpressure_server.h176
-rw-r--r--ydb/core/blobstorage/backpressure/queue_backpressure_server_ut.cpp90
-rw-r--r--ydb/core/blobstorage/backpressure/unisched.cpp374
-rw-r--r--ydb/core/blobstorage/backpressure/unisched.h34
-rw-r--r--ydb/core/blobstorage/backpressure/ut/ya.make2
-rw-r--r--ydb/core/blobstorage/backpressure/ut_client/backpressure_ut.cpp170
-rw-r--r--ydb/core/blobstorage/backpressure/ut_client/defs.h6
-rw-r--r--ydb/core/blobstorage/backpressure/ut_client/loader.h188
-rw-r--r--ydb/core/blobstorage/backpressure/ut_client/skeleton_front_mock.h324
-rw-r--r--ydb/core/blobstorage/backpressure/ut_client/ya.make38
-rw-r--r--ydb/core/blobstorage/backpressure/ya.make16
-rw-r--r--ydb/core/blobstorage/base/blobstorage_events.h292
-rw-r--r--ydb/core/blobstorage/base/blobstorage_vdiskid.h36
-rw-r--r--ydb/core/blobstorage/base/bufferwithgaps.h160
-rw-r--r--ydb/core/blobstorage/base/bufferwithgaps_ut.cpp64
-rw-r--r--ydb/core/blobstorage/base/ptr.h18
-rw-r--r--ydb/core/blobstorage/base/ptr_ut.cpp4
-rw-r--r--ydb/core/blobstorage/base/transparent.h10
-rw-r--r--ydb/core/blobstorage/base/utility.h74
-rw-r--r--ydb/core/blobstorage/base/vdisk_sync_common.h2
-rw-r--r--ydb/core/blobstorage/base/wilson_events.h216
-rw-r--r--ydb/core/blobstorage/crypto/crypto.cpp4
-rw-r--r--ydb/core/blobstorage/crypto/crypto.h12
-rw-r--r--ydb/core/blobstorage/dsproxy/defs.h26
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy.h768
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_blackboard.cpp206
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h104
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h198
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_block.cpp206
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_collect.cpp256
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp518
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp1348
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_discover_m3of4.cpp730
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_encrypt.cpp128
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_get.cpp266
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp332
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_get_impl.h186
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_impl.cpp158
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_impl.h804
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_indexrestoreget.cpp406
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp168
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_mon.h354
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_monactor.cpp622
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_monactor.h28
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_multicollect.cpp142
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_multiget.cpp190
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_nodemon.cpp54
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_nodemon.h36
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_nodemonactor.cpp30
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_patch.cpp34
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_put.cpp364
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_put_impl.cpp36
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_put_impl.h40
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h206
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_range.cpp590
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_request.cpp584
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_responsiveness.h236
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_stat.cpp128
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_state.cpp596
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_status.cpp132
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put.h10
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put_m3dc.h20
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp156
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.h6
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_bold.h52
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_basic.h398
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h228
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3of4.h354
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_block.h100
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_mirror.h118
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_m3of4_base.h100
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3dc.h36
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3of4.h370
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h112
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_timestats.h402
-rw-r--r--ydb/core/blobstorage/dsproxy/group_sessions.cpp240
-rw-r--r--ydb/core/blobstorage/dsproxy/group_sessions.h452
-rw-r--r--ydb/core/blobstorage/dsproxy/log_acc.h438
-rw-r--r--ydb/core/blobstorage/dsproxy/mock/defs.h4
-rw-r--r--ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.cpp162
-rw-r--r--ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h28
-rw-r--r--ydb/core/blobstorage/dsproxy/mock/model.h22
-rw-r--r--ydb/core/blobstorage/dsproxy/mock/ya.make4
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/defs.h4
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_counters_ut.cpp4
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_env_mock_ut.h20
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut.cpp114
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_base.h380
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h220
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get.h146
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get_hardened.h550
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_put.h156
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_range.h232
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h114
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_get_ut.cpp264
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_patch_ut.cpp42
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_put_ut.cpp60
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_quorum_tracker_ut.cpp98
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp174
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_test_state_ut.h30
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/dsproxy_vdisk_mock_ut.h14
-rw-r--r--ydb/core/blobstorage/dsproxy/ut/ya.make24
-rw-r--r--ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp258
-rw-r--r--ydb/core/blobstorage/dsproxy/ya.make48
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp1104
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h332
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.cpp290
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.h60
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap_ut.cpp410
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h660
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter_ut.cpp212
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.cpp220
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h314
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout_ut.cpp206
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h672
-rw-r--r--ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_ut.cpp350
-rw-r--r--ydb/core/blobstorage/groupinfo/defs.h4
-rw-r--r--ydb/core/blobstorage/incrhuge/defs.h112
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge.h376
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_data.h102
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h526
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper.cpp378
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper.h164
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.cpp174
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.h62
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.cpp26
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.h592
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.cpp572
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.h134
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.cpp656
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.h92
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.cpp1390
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h426
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.cpp174
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.h82
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.cpp1004
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.h164
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.cpp256
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.h30
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.cpp322
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.h36
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.cpp1196
-rw-r--r--ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.h232
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/faulty_pdisk.h44
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/incrhuge_basic_ut.cpp440
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/incrhuge_id_dict_ut.cpp68
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/incrhuge_log_merger_ut.cpp10
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/test_actor_concurrent.h802
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/test_actor_seq.h410
-rw-r--r--ydb/core/blobstorage/incrhuge/ut/ya.make4
-rw-r--r--ydb/core/blobstorage/incrhuge/ya.make4
-rw-r--r--ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.cpp2
-rw-r--r--ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h10
-rw-r--r--ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp94
-rw-r--r--ydb/core/blobstorage/nodewarden/defs.h50
-rw-r--r--ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp172
-rw-r--r--ydb/core/blobstorage/nodewarden/group_stat_aggregator.h108
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden.h52
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_cache.cpp468
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_group.cpp536
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_group_resolver.cpp652
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_impl.cpp688
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_impl.h942
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_mon.cpp70
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp502
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_pipe.cpp182
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_proxy.cpp140
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_resource.cpp216
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_scrub.cpp212
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_stat_aggr.cpp102
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp606
-rw-r--r--ydb/core/blobstorage/nodewarden/ut/ya.make20
-rw-r--r--ydb/core/blobstorage/nodewarden/ut_sequence/dsproxy_config_retrieval.cpp354
-rw-r--r--ydb/core/blobstorage/nodewarden/ut_sequence/ya.make22
-rw-r--r--ydb/core/blobstorage/nodewarden/ya.make24
-rw-r--r--ydb/core/blobstorage/other/mon_blob_range_page.cpp416
-rw-r--r--ydb/core/blobstorage/other/mon_blob_range_page.h20
-rw-r--r--ydb/core/blobstorage/other/mon_get_blob_page.cpp638
-rw-r--r--ydb/core/blobstorage/other/mon_get_blob_page.h18
-rw-r--r--ydb/core/blobstorage/other/mon_vdisk_stream.cpp238
-rw-r--r--ydb/core/blobstorage/other/mon_vdisk_stream.h20
-rw-r--r--ydb/core/blobstorage/other/ya.make4
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk.h74
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp38
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice.h2
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice_async.cpp16
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_color_limits.h20
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_drivemodel.h18
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_factory.h4
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp36
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_http.cpp4
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp18
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp2
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp14
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h24
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h44
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_requestimpl.h14
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_signature.h6
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_state.h2
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp28
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.cpp6
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_base_test.h6
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_writer.cpp2
-rw-r--r--ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp1328
-rw-r--r--ydb/core/blobstorage/pdisk/mock/pdisk_mock.h62
-rw-r--r--ydb/core/blobstorage/pdisk/mock/ya.make4
-rw-r--r--ydb/core/blobstorage/testload/test_load_actor.cpp418
-rw-r--r--ydb/core/blobstorage/testload/test_load_actor.h64
-rw-r--r--ydb/core/blobstorage/testload/test_load_gen.h74
-rw-r--r--ydb/core/blobstorage/testload/test_load_interval_gen.h152
-rw-r--r--ydb/core/blobstorage/testload/test_load_keyvalue_write.cpp14
-rw-r--r--ydb/core/blobstorage/testload/test_load_kqp.cpp4
-rw-r--r--ydb/core/blobstorage/testload/test_load_pdisk_log.cpp34
-rw-r--r--ydb/core/blobstorage/testload/test_load_pdisk_read.cpp24
-rw-r--r--ydb/core/blobstorage/testload/test_load_pdisk_write.cpp748
-rw-r--r--ydb/core/blobstorage/testload/test_load_quantile.h112
-rw-r--r--ydb/core/blobstorage/testload/test_load_size_gen.h52
-rw-r--r--ydb/core/blobstorage/testload/test_load_speed.h68
-rw-r--r--ydb/core/blobstorage/testload/test_load_time_series.h84
-rw-r--r--ydb/core/blobstorage/testload/test_load_vdisk_write.cpp522
-rw-r--r--ydb/core/blobstorage/testload/test_load_write.cpp1072
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/big_cluster.cpp38
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/block_race.cpp94
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/counting_events.cpp32
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/defrag.cpp286
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/donor.cpp170
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/encryption.cpp114
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/gc_quorum_3dc.cpp360
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/incorrect_queries.cpp88
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/activity.h406
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/defs.h18
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/env.h1244
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock.h256
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_bsc.cpp448
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_pipe.cpp68
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.cpp184
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.h124
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h288
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/lib/ya.make4
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/main.cpp212
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/mirror3of4.cpp242
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/multiget.cpp122
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/osiris.cpp702
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/patch.cpp96
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/race.cpp472
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/replication.cpp638
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/scrub.cpp796
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/space_check.cpp404
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/sync.cpp240
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/ut_group_reconfiguration/ya.make18
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/ut_osiris/ya.make12
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/ut_replication/ya.make12
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/ut_scrub/ya.make12
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/ya.make24
-rw-r--r--ydb/core/blobstorage/ut_group/main.cpp1262
-rw-r--r--ydb/core/blobstorage/ut_group/ya.make12
-rw-r--r--ydb/core/blobstorage/ut_mirror3of4/main.cpp788
-rw-r--r--ydb/core/blobstorage/ut_mirror3of4/ya.make12
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.cpp1526
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h132
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h550
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.cpp92
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.h44
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/state_manager.h170
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/lib/ya.make6
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/pdiskfit/pdiskfit.cpp180
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/ut/main.cpp54
-rw-r--r--ydb/core/blobstorage/ut_pdiskfit/ya.make2
-rw-r--r--ydb/core/blobstorage/ut_vdisk/gen_restarts.cpp20
-rw-r--r--ydb/core/blobstorage/ut_vdisk/gen_restarts.h20
-rw-r--r--ydb/core/blobstorage/ut_vdisk/huge_migration_ut.cpp8
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/astest.h16
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/dataset.cpp16
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/helpers.cpp200
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/helpers.h22
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/http_client.cpp8
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/http_client.h4
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp50
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/prepare.h80
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/setup.h8
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_brokendevice.cpp2
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_defrag.cpp14
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_faketablet.cpp2
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_gc.cpp118
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_huge.cpp54
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.cpp48
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.h16
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_many.cpp64
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_many.h16
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_repl.cpp316
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_repl.h22
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.cpp160
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.h4
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/test_synclog.cpp22
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.cpp854
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h132
-rw-r--r--ydb/core/blobstorage/ut_vdisk/lib/ya.make4
-rw-r--r--ydb/core/blobstorage/ut_vdisk/mon_reregister_ut.cpp6
-rw-r--r--ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp152
-rw-r--r--ydb/core/blobstorage/ut_vdisk2/defs.h6
-rw-r--r--ydb/core/blobstorage/ut_vdisk2/env.h342
-rw-r--r--ydb/core/blobstorage/ut_vdisk2/huge.cpp276
-rw-r--r--ydb/core/blobstorage/ut_vdisk2/ya.make14
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis.cpp22
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis_osiris.h2
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisproxy.cpp24
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.cpp20
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.h2
-rw-r--r--ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp88
-rw-r--r--ydb/core/blobstorage/vdisk/common/align.h52
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.cpp120
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.h2
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.cpp186
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h20
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp60
-rw-r--r--ydb/core/blobstorage/vdisk/common/blobstorage_status.h6
-rw-r--r--ydb/core/blobstorage/vdisk/common/disk_part.h40
-rw-r--r--ydb/core/blobstorage/vdisk/common/memusage.h924
-rw-r--r--ydb/core/blobstorage/vdisk/common/memusage_ut.cpp100
-rw-r--r--ydb/core/blobstorage/vdisk/common/sublog.h20
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_config.cpp58
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_config.h64
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_context.cpp26
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_context.h34
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_events.cpp40
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_events.h1292
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_histogram_latency.h2
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h8
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_log.cpp8
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_log.h2
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h8
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr_ut.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_mon.h32
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_mongroups.h16
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_private_events.h54
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_queues.h8
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_recoverylogwriter.cpp56
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_response.cpp66
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_response.h4
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors.h238
-rw-r--r--ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors_ut.cpp266
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_actor.cpp290
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_actor.h6
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_quantum.cpp160
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_quantum.h12
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.cpp50
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.h2
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defrag_search.h802
-rw-r--r--ydb/core/blobstorage/vdisk/defrag/defs.h2
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_basic.cpp6
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_basic.h2
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_delegate.cpp6
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h4
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_map.h28
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_mon.cpp40
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_mon.h2
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp54
-rw-r--r--ydb/core/blobstorage/vdisk/handoff/handoff_synclogproxy.cpp12
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.cpp488
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.h38
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge_ut.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedefs.h28
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.cpp62
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.h428
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.cpp58
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.h6
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ctx_ut.cpp6
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ut.cpp20
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.cpp72
-rw-r--r--ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.h8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_chain.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp16
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.cpp22
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.h12
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.cpp36
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.h74
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree_ut.cpp10
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_cache_barrier.h180
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_gcessence_defs.h208
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h550
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob_ut.cpp194
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hulldefs.h14
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h102
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier_ut.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h26
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h60
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h58
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullds_generic_it.h18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullds_glue.h54
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/base/hullds_ut.h2
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_defs.h10
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h20
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.cpp34
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.h50
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix_ut.cpp10
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.cpp18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.h24
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data_ut.cpp36
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.cpp18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.h28
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.cpp42
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.h88
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_impl.h216
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_ut.cpp92
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec.h76
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec_ut.cpp28
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/fresh/ya.make8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hulldatamerger.h18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullrecmerger.h320
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h1260
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp292
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.cpp98
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.h380
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.cpp18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.h18
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_leveledssts.h4
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.cpp70
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h44
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it.h10
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.cpp132
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.h88
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.cpp26
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.h46
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec_it.h2
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/generic/ya.make8
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h12
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h28
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.cpp328
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.h256
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.cpp62
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.h24
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.cpp78
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.h60
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block_ut.cpp168
-rw-r--r--ydb/core/blobstorage/vdisk/hulldb/test/testhull_index.cpp32
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp130
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h24
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp230
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h30
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcommit.h490
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h264
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue.h184
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue_ut.cpp382
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactworker.h1246
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h222
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.cpp78
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.h12
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllogcutternotify.cpp14
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch.h536
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch_ut.cpp172
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp.h6
-rw-r--r--ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp_ut.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.cpp436
-rw-r--r--ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h56
-rw-r--r--ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h30
-rw-r--r--ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp276
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_defs.h42
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.cpp86
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.h6
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.cpp306
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h32
-rw-r--r--ydb/core/blobstorage/vdisk/localrecovery/localrecovery_readbulksst.cpp32
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_barrier.cpp16
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_base.h52
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_dumpdb.h12
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_extr.cpp338
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_public.cpp64
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_public.h22
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_range.cpp64
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_readactor.cpp114
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_readactor.h6
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_readbatch.cpp152
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_readbatch.h152
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_spacetracker.h2
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_statalgo.h100
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_statdb.cpp18
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_statdb.h12
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_stathuge.cpp24
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_stathuge.h4
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_stattablet.cpp26
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_stattablet.h2
-rw-r--r--ydb/core/blobstorage/vdisk/query/query_stream.h622
-rw-r--r--ydb/core/blobstorage/vdisk/query/ya.make2
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp1480
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.h10
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h526
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst_ut.cpp400
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_repl.cpp822
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_repl.h112
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.cpp326
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h136
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replctx.h34
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.cpp674
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.h422
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine.h756
-rw-r--r--ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine_ut.cpp232
-rw-r--r--ydb/core/blobstorage/vdisk/repl/query_donor.h206
-rw-r--r--ydb/core/blobstorage/vdisk/repl/repl_quoter.h114
-rw-r--r--ydb/core/blobstorage/vdisk/repl/ut/ya.make2
-rw-r--r--ydb/core/blobstorage/vdisk/repl/ya.make4
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery.cpp42
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery.h198
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery_impl.h234
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery_process.cpp284
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery_queue.cpp100
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/blob_recovery_request.cpp130
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/defs.h8
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.cpp670
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h108
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor.cpp492
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor.h140
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp140
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge_blob_merger.h210
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_impl.h346
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_mon.cpp126
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_pdisk.cpp90
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_snapshot.cpp52
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst.cpp472
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h226
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp320
-rw-r--r--ydb/core/blobstorage/vdisk/scrub/ya.make12
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.h6
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp222
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h2
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp1280
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonerr.h434
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp1152
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.h4
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp30
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.h2
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp50
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.h4
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_capturevdisklayout.h174
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp8
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.h2
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp58
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.h34
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.cpp2
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.h6
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_tracker.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.cpp16
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.h8
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp16
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.cpp28
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.h10
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor.cpp48
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor_ut.cpp108
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/ya.make2
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer.cpp146
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.cpp50
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.h8
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.cpp8
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.h8
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data_ut.cpp12
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.cpp24
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.h2
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata.cpp42
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.cpp64
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.h2
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_scheduler.cpp126
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum.h26
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum_ut.cpp84
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_firstrun.cpp62
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_propagator.cpp26
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h44
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_proxyobtain.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_proxywrite.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/guid_recovery.cpp74
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/syncer_context.h6
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp62
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.h8
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/syncer_job_task.cpp26
-rw-r--r--ydb/core/blobstorage/vdisk/syncer/syncer_job_task.h14
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.cpp98
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.h2
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h8
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.cpp16
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.h8
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata_ut.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.cpp22
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.h44
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk_ut.cpp78
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.cpp72
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.h76
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_syncloghttp.cpp12
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.cpp46
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.h2
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_committer.cpp12
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.cpp12
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.h14
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_ut.cpp32
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.cpp18
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.h8
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem_ut.cpp6
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.cpp148
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.h62
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl_ut.cpp100
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.cpp144
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h44
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.cpp4
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.h44
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter_ut.cpp30
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.cpp6
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.h2
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogreader.cpp34
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.cpp28
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.h60
-rw-r--r--ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogwriteparts.h30
-rw-r--r--ydb/core/blobstorage/vdisk/vdisk_services.h2
-rw-r--r--ydb/core/blobstorage/vdisk/ya.make2
-rw-r--r--ydb/core/blobstorage/ya.make8
-rw-r--r--ydb/core/client/flat_ut.cpp8
-rw-r--r--ydb/core/client/flat_ut_client.h6
-rw-r--r--ydb/core/client/locks_ut.cpp2
-rw-r--r--ydb/core/client/minikql_compile/mkql_compile_service.cpp4
-rw-r--r--ydb/core/client/minikql_compile/yql_expr_minikql.cpp4
-rw-r--r--ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp4
-rw-r--r--ydb/core/client/server/grpc_proxy_status.cpp26
-rw-r--r--ydb/core/client/server/grpc_proxy_status.h2
-rw-r--r--ydb/core/client/server/grpc_server.cpp298
-rw-r--r--ydb/core/client/server/grpc_server.h44
-rw-r--r--ydb/core/client/server/msgbus_blobstorage_config.cpp108
-rw-r--r--ydb/core/client/server/msgbus_bsadm.cpp8
-rw-r--r--ydb/core/client/server/msgbus_http_server.cpp6
-rw-r--r--ydb/core/client/server/msgbus_securereq.h2
-rw-r--r--ydb/core/client/server/msgbus_server.cpp638
-rw-r--r--ydb/core/client/server/msgbus_server.h112
-rw-r--r--ydb/core/client/server/msgbus_server_cms.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_console.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_db.cpp16
-rw-r--r--ydb/core/client/server/msgbus_server_get.cpp164
-rw-r--r--ydb/core/client/server/msgbus_server_hive_create_tablet.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_ic_debug.cpp168
-rw-r--r--ydb/core/client/server/msgbus_server_keyvalue.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_load.cpp142
-rw-r--r--ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_local_minikql.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_local_scheme_tx.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_node_registration.cpp26
-rw-r--r--ydb/core/client/server/msgbus_server_persqueue.cpp12
-rw-r--r--ydb/core/client/server/msgbus_server_persqueue.h8
-rw-r--r--ydb/core/client/server/msgbus_server_pq_metarequest.cpp10
-rw-r--r--ydb/core/client/server/msgbus_server_pq_metarequest_ut.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_proxy.cpp18
-rw-r--r--ydb/core/client/server/msgbus_server_proxy.h10
-rw-r--r--ydb/core/client/server/msgbus_server_request.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_request.h2
-rw-r--r--ydb/core/client/server/msgbus_server_resolve_node.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_s3_listing.cpp8
-rw-r--r--ydb/core/client/server/msgbus_server_scheme_request.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_tablet_counters.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_tablet_kill.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_tablet_state.cpp6
-rw-r--r--ydb/core/client/server/msgbus_server_test_shard_request.cpp98
-rw-r--r--ydb/core/client/server/msgbus_server_tracer.cpp10
-rw-r--r--ydb/core/client/server/msgbus_server_tracer.h4
-rw-r--r--ydb/core/client/server/msgbus_server_tx_request.cpp2
-rw-r--r--ydb/core/client/server/msgbus_server_types.cpp4
-rw-r--r--ydb/core/client/server/msgbus_server_whoami.cpp4
-rw-r--r--ydb/core/client/server/msgbus_servicereq.h2
-rw-r--r--ydb/core/client/server/msgbus_tabletreq.h6
-rw-r--r--ydb/core/client/server/ya.make10
-rw-r--r--ydb/core/cms/cluster_info.cpp2
-rw-r--r--ydb/core/cms/cluster_info.h4
-rw-r--r--ydb/core/cms/cluster_info_ut.cpp10
-rw-r--r--ydb/core/cms/cms.cpp34
-rw-r--r--ydb/core/cms/cms_impl.h4
-rw-r--r--ydb/core/cms/cms_ut.cpp2
-rw-r--r--ydb/core/cms/cms_ut_common.cpp2
-rw-r--r--ydb/core/cms/config.h8
-rw-r--r--ydb/core/cms/console/config_helpers.cpp4
-rw-r--r--ydb/core/cms/console/configs_dispatcher.cpp4
-rw-r--r--ydb/core/cms/console/console_configs_manager.h4
-rw-r--r--ydb/core/cms/console/console_configs_provider.cpp8
-rw-r--r--ydb/core/cms/console/console_configs_provider.h4
-rw-r--r--ydb/core/cms/console/console_configs_subscriber.cpp2
-rw-r--r--ydb/core/cms/console/console_impl.h4
-rw-r--r--ydb/core/cms/console/console_tenants_manager.cpp18
-rw-r--r--ydb/core/cms/console/console_tenants_manager.h4
-rw-r--r--ydb/core/cms/console/console_ut_tenants.cpp12
-rw-r--r--ydb/core/cms/console/immediate_controls_configurator.cpp4
-rw-r--r--ydb/core/cms/console/log_settings_configurator.cpp4
-rw-r--r--ydb/core/cms/console/shared_cache_configurator.cpp4
-rw-r--r--ydb/core/cms/http.cpp24
-rw-r--r--ydb/core/cms/json_proxy.h4
-rw-r--r--ydb/core/cms/json_proxy_proto.h6
-rw-r--r--ydb/core/cms/pdisk_state.h2
-rw-r--r--ydb/core/cms/sentinel.cpp60
-rw-r--r--ydb/core/cms/sentinel_impl.h2
-rw-r--r--ydb/core/cms/sentinel_ut.cpp50
-rw-r--r--ydb/core/cms/walle_api_handler.cpp4
-rw-r--r--ydb/core/cms/walle_check_task_adapter.cpp4
-rw-r--r--ydb/core/cms/walle_create_task_adapter.cpp4
-rw-r--r--ydb/core/cms/walle_list_tasks_adapter.cpp4
-rw-r--r--ydb/core/cms/walle_remove_task_adapter.cpp4
-rw-r--r--ydb/core/control/immediate_control_board_actor.cpp4
-rw-r--r--ydb/core/driver_lib/cli_base/cli_cmds_db.cpp102
-rw-r--r--ydb/core/driver_lib/cli_config_base/config_base.h2
-rw-r--r--ydb/core/driver_lib/cli_utils/cli.h2
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp30
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmd_config.h74
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp6
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_config.cpp348
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp560
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp624
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_get.cpp174
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp8
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp390
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp6
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_keyvalue.cpp186
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_load.cpp122
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp6
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp6
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_persqueue.cpp2
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_persqueue_stress.cpp10
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp6
-rw-r--r--ydb/core/driver_lib/cli_utils/proto_common.h60
-rw-r--r--ydb/core/driver_lib/cli_utils/ya.make8
-rw-r--r--ydb/core/driver_lib/run/config.cpp8
-rw-r--r--ydb/core/driver_lib/run/config.h6
-rw-r--r--ydb/core/driver_lib/run/config_parser.cpp34
-rw-r--r--ydb/core/driver_lib/run/driver.h2
-rw-r--r--ydb/core/driver_lib/run/kikimr_services_initializers.cpp512
-rw-r--r--ydb/core/driver_lib/run/kikimr_services_initializers.h22
-rw-r--r--ydb/core/driver_lib/run/main.cpp4
-rw-r--r--ydb/core/driver_lib/run/run.cpp98
-rw-r--r--ydb/core/driver_lib/run/ut/ya.make8
-rw-r--r--ydb/core/driver_lib/run/version.cpp114
-rw-r--r--ydb/core/driver_lib/run/version.h14
-rw-r--r--ydb/core/driver_lib/run/version_ut.cpp20
-rw-r--r--ydb/core/driver_lib/run/ya.make4
-rw-r--r--ydb/core/engine/minikql/flat_local_tx_read_columns.h2
-rw-r--r--ydb/core/erasure/erasure.cpp54
-rw-r--r--ydb/core/erasure/erasure.h18
-rw-r--r--ydb/core/erasure/erasure_rope.cpp6
-rw-r--r--ydb/core/erasure/erasure_rope.h8
-rw-r--r--ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp6
-rw-r--r--ydb/core/grpc_services/grpc_helper.cpp2
-rw-r--r--ydb/core/grpc_services/grpc_mon.cpp4
-rw-r--r--ydb/core/grpc_services/grpc_request_proxy.cpp2
-rw-r--r--ydb/core/grpc_services/rpc_discovery.cpp8
-rw-r--r--ydb/core/grpc_services/rpc_get_shard_locations.cpp4
-rw-r--r--ydb/core/grpc_services/rpc_read_columns.cpp4
-rw-r--r--ydb/core/grpc_services/rpc_read_table.cpp4
-rw-r--r--ydb/core/grpc_services/rpc_stream_execute_scan_query.cpp4
-rw-r--r--ydb/core/grpc_services/ut/ya.make8
-rw-r--r--ydb/core/health_check/health_check.cpp46
-rw-r--r--ydb/core/kesus/proxy/proxy.cpp8
-rw-r--r--ydb/core/kesus/proxy/proxy_actor.cpp4
-rw-r--r--ydb/core/kesus/tablet/tablet_impl.h4
-rw-r--r--ydb/core/keyvalue/channel_balancer.h342
-rw-r--r--ydb/core/keyvalue/keyvalue_collector.cpp4
-rw-r--r--ydb/core/keyvalue/keyvalue_events.h8
-rw-r--r--ydb/core/keyvalue/keyvalue_flat_impl.h70
-rw-r--r--ydb/core/keyvalue/keyvalue_intermediate.cpp4
-rw-r--r--ydb/core/keyvalue/keyvalue_intermediate.h18
-rw-r--r--ydb/core/keyvalue/keyvalue_state.cpp992
-rw-r--r--ydb/core/keyvalue/keyvalue_state.h454
-rw-r--r--ydb/core/keyvalue/keyvalue_storage_request.cpp388
-rw-r--r--ydb/core/keyvalue/keyvalue_ut.cpp308
-rw-r--r--ydb/core/kqp/executer/kqp_scan_executer.cpp4
-rw-r--r--ydb/core/kqp/kqp.h16
-rw-r--r--ydb/core/kqp/kqp_ic_gateway.cpp6
-rw-r--r--ydb/core/kqp/kqp_worker_actor.cpp4
-rw-r--r--ydb/core/kqp/proxy/kqp_proxy_peer_stats_calculator.cpp12
-rw-r--r--ydb/core/kqp/proxy/kqp_proxy_service.cpp10
-rw-r--r--ydb/core/kqp/proxy/kqp_proxy_service.h2
-rw-r--r--ydb/core/kqp/proxy/kqp_proxy_ut.cpp6
-rw-r--r--ydb/core/mind/bscontroller/bsc.cpp720
-rw-r--r--ydb/core/mind/bscontroller/bsc.h14
-rw-r--r--ydb/core/mind/bscontroller/cmds_box.cpp380
-rw-r--r--ydb/core/mind/bscontroller/cmds_drive_status.cpp228
-rw-r--r--ydb/core/mind/bscontroller/cmds_host_config.cpp178
-rw-r--r--ydb/core/mind/bscontroller/cmds_storage_pool.cpp1098
-rw-r--r--ydb/core/mind/bscontroller/config.cpp1830
-rw-r--r--ydb/core/mind/bscontroller/config.h454
-rw-r--r--ydb/core/mind/bscontroller/config_cmd.cpp666
-rw-r--r--ydb/core/mind/bscontroller/config_fit_groups.cpp1164
-rw-r--r--ydb/core/mind/bscontroller/config_fit_pdisks.cpp416
-rw-r--r--ydb/core/mind/bscontroller/defs.h28
-rw-r--r--ydb/core/mind/bscontroller/diff.h268
-rw-r--r--ydb/core/mind/bscontroller/disk_metrics.cpp230
-rw-r--r--ydb/core/mind/bscontroller/drop_donor.cpp100
-rw-r--r--ydb/core/mind/bscontroller/error.h398
-rw-r--r--ydb/core/mind/bscontroller/get_group.cpp92
-rw-r--r--ydb/core/mind/bscontroller/group_geometry_info.h198
-rw-r--r--ydb/core/mind/bscontroller/group_mapper.cpp1586
-rw-r--r--ydb/core/mind/bscontroller/group_mapper.h120
-rw-r--r--ydb/core/mind/bscontroller/group_mapper_ut.cpp1226
-rw-r--r--ydb/core/mind/bscontroller/group_reconfigure_wipe.cpp186
-rw-r--r--ydb/core/mind/bscontroller/grouper.cpp668
-rw-r--r--ydb/core/mind/bscontroller/grouper.h56
-rw-r--r--ydb/core/mind/bscontroller/grouper_ut.cpp288
-rw-r--r--ydb/core/mind/bscontroller/impl.h3536
-rw-r--r--ydb/core/mind/bscontroller/indir.h148
-rw-r--r--ydb/core/mind/bscontroller/init_scheme.cpp106
-rw-r--r--ydb/core/mind/bscontroller/load_everything.cpp922
-rw-r--r--ydb/core/mind/bscontroller/migrate.cpp426
-rw-r--r--ydb/core/mind/bscontroller/monitoring.cpp1964
-rw-r--r--ydb/core/mind/bscontroller/mood.h42
-rw-r--r--ydb/core/mind/bscontroller/mv_object_map.h620
-rw-r--r--ydb/core/mind/bscontroller/mv_object_map_ut.cpp216
-rw-r--r--ydb/core/mind/bscontroller/node_report.cpp230
-rw-r--r--ydb/core/mind/bscontroller/propose_group_key.cpp92
-rw-r--r--ydb/core/mind/bscontroller/register_node.cpp528
-rw-r--r--ydb/core/mind/bscontroller/request_controller_info.cpp134
-rw-r--r--ydb/core/mind/bscontroller/resources.h142
-rw-r--r--ydb/core/mind/bscontroller/scheme.h666
-rw-r--r--ydb/core/mind/bscontroller/scrub.cpp1660
-rw-r--r--ydb/core/mind/bscontroller/select_groups.cpp270
-rw-r--r--ydb/core/mind/bscontroller/select_groups.h126
-rw-r--r--ydb/core/mind/bscontroller/self_heal.cpp1282
-rw-r--r--ydb/core/mind/bscontroller/self_heal.h68
-rw-r--r--ydb/core/mind/bscontroller/stat_processor.cpp300
-rw-r--r--ydb/core/mind/bscontroller/stat_processor.h40
-rw-r--r--ydb/core/mind/bscontroller/storage_pool_stat.h264
-rw-r--r--ydb/core/mind/bscontroller/sys_view.cpp886
-rw-r--r--ydb/core/mind/bscontroller/sys_view.h24
-rw-r--r--ydb/core/mind/bscontroller/table_merger.h214
-rw-r--r--ydb/core/mind/bscontroller/types.h936
-rw-r--r--ydb/core/mind/bscontroller/update_group_latencies.cpp160
-rw-r--r--ydb/core/mind/bscontroller/update_last_seen_ready.cpp66
-rw-r--r--ydb/core/mind/bscontroller/update_seen_operational.cpp68
-rw-r--r--ydb/core/mind/bscontroller/ut/ya.make26
-rw-r--r--ydb/core/mind/bscontroller/ut_bscontroller/main.cpp1730
-rw-r--r--ydb/core/mind/bscontroller/ut_bscontroller/ya.make12
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/defs.h18
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/env.h406
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/events.h22
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/main.cpp158
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/node_warden_mock.h360
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/self_heal_actor_ut.cpp216
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/timer_actor.h88
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/vdisk_mock.h242
-rw-r--r--ydb/core/mind/bscontroller/ut_selfheal/ya.make46
-rw-r--r--ydb/core/mind/bscontroller/vdisk_status_tracker.h58
-rw-r--r--ydb/core/mind/bscontroller/ya.make118
-rw-r--r--ydb/core/mind/configured_tablet_bootstrapper.cpp6
-rw-r--r--ydb/core/mind/defs.h14
-rw-r--r--ydb/core/mind/dynamic_nameserver.cpp44
-rw-r--r--ydb/core/mind/dynamic_nameserver_impl.h52
-rw-r--r--ydb/core/mind/dynamic_nameserver_mon.cpp6
-rw-r--r--ydb/core/mind/hive/balancer.cpp4
-rw-r--r--ydb/core/mind/hive/drain.cpp4
-rw-r--r--ydb/core/mind/hive/fill.cpp4
-rw-r--r--ydb/core/mind/hive/follower_group.h14
-rw-r--r--ydb/core/mind/hive/hive.h2
-rw-r--r--ydb/core/mind/hive/hive_impl.cpp62
-rw-r--r--ydb/core/mind/hive/hive_impl.h8
-rw-r--r--ydb/core/mind/hive/hive_schema.h14
-rw-r--r--ydb/core/mind/hive/hive_ut.cpp44
-rw-r--r--ydb/core/mind/hive/leader_tablet_info.cpp4
-rw-r--r--ydb/core/mind/hive/monitoring.cpp154
-rw-r--r--ydb/core/mind/hive/node_info.cpp10
-rw-r--r--ydb/core/mind/hive/node_info.h6
-rw-r--r--ydb/core/mind/hive/tx__create_tablet.cpp68
-rw-r--r--ydb/core/mind/hive/tx__load_everything.cpp40
-rw-r--r--ydb/core/mind/hive/tx__seize_tablets_reply.cpp14
-rw-r--r--ydb/core/mind/hive/tx__update_tablet_groups.cpp6
-rw-r--r--ydb/core/mind/labels_maintainer.cpp4
-rw-r--r--ydb/core/mind/lease_holder.cpp4
-rw-r--r--ydb/core/mind/local.cpp12
-rw-r--r--ydb/core/mind/node_broker.cpp244
-rw-r--r--ydb/core/mind/node_broker__register_node.cpp48
-rw-r--r--ydb/core/mind/node_broker__scheme.h6
-rw-r--r--ydb/core/mind/node_broker_impl.h18
-rw-r--r--ydb/core/mind/node_broker_ut.cpp36
-rw-r--r--ydb/core/mind/table_adapter.h1092
-rw-r--r--ydb/core/mind/tenant_node_enumeration_ut.cpp8
-rw-r--r--ydb/core/mind/tenant_pool.cpp8
-rw-r--r--ydb/core/mind/tenant_slot_broker.cpp30
-rw-r--r--ydb/core/mind/tenant_slot_broker.h2
-rw-r--r--ydb/core/mind/tenant_slot_broker__alter_tenant.cpp2
-rw-r--r--ydb/core/mind/tenant_slot_broker__update_node_location.cpp2
-rw-r--r--ydb/core/mind/tenant_slot_broker__update_pool_status.cpp2
-rw-r--r--ydb/core/mind/tenant_slot_broker_impl.h10
-rw-r--r--ydb/core/mind/tenant_ut_broker.cpp82
-rw-r--r--ydb/core/mind/tenant_ut_local.cpp8
-rw-r--r--ydb/core/mind/tenant_ut_pool.cpp30
-rw-r--r--ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp104
-rw-r--r--ydb/core/mind/ya.make2
-rw-r--r--ydb/core/mon/crossref.cpp282
-rw-r--r--ydb/core/mon/crossref.h86
-rw-r--r--ydb/core/mon/mon.cpp4
-rw-r--r--ydb/core/mon/ya.make4
-rw-r--r--ydb/core/node_whiteboard/node_whiteboard.h204
-rw-r--r--ydb/core/persqueue/events/global.h4
-rw-r--r--ydb/core/persqueue/events/internal.h2
-rw-r--r--ydb/core/persqueue/partition.cpp28
-rw-r--r--ydb/core/persqueue/partition.h18
-rw-r--r--ydb/core/persqueue/pq_impl.cpp48
-rw-r--r--ydb/core/persqueue/pq_impl.h20
-rw-r--r--ydb/core/persqueue/pq_l2_cache.h4
-rw-r--r--ydb/core/persqueue/read.h4
-rw-r--r--ydb/core/persqueue/read_balancer.h4
-rw-r--r--ydb/core/persqueue/user_info.cpp4
-rw-r--r--ydb/core/persqueue/user_info.h2
-rw-r--r--ydb/core/protos/blobstorage.proto962
-rw-r--r--ydb/core/protos/blobstorage_config.proto1098
-rw-r--r--ydb/core/protos/blobstorage_disk.proto150
-rw-r--r--ydb/core/protos/blobstorage_disk_color.proto30
-rw-r--r--ydb/core/protos/blobstorage_vdisk_config.proto22
-rw-r--r--ydb/core/protos/blobstorage_vdisk_internal.proto190
-rw-r--r--ydb/core/protos/config.proto120
-rw-r--r--ydb/core/protos/config_units.proto26
-rw-r--r--ydb/core/protos/counters.proto2
-rw-r--r--ydb/core/protos/counters_bs_controller.proto302
-rw-r--r--ydb/core/protos/counters_testshard.proto42
-rw-r--r--ydb/core/protos/follower_group.proto4
-rw-r--r--ydb/core/protos/grpc.proto56
-rw-r--r--ydb/core/protos/hive.proto8
-rw-r--r--ydb/core/protos/kqp.proto4
-rw-r--r--ydb/core/protos/local.proto2
-rw-r--r--ydb/core/protos/msgbus.proto206
-rw-r--r--ydb/core/protos/msgbus_health.proto2
-rw-r--r--ydb/core/protos/msgbus_kv.proto22
-rw-r--r--ydb/core/protos/msgbus_pq.proto2
-rw-r--r--ydb/core/protos/node_broker.proto10
-rw-r--r--ydb/core/protos/node_whiteboard.proto68
-rw-r--r--ydb/core/protos/out/out.cpp4
-rw-r--r--ydb/core/protos/pdiskfit.proto82
-rw-r--r--ydb/core/protos/services.proto862
-rw-r--r--ydb/core/protos/sys_view.proto64
-rw-r--r--ydb/core/protos/tablet.proto4
-rw-r--r--ydb/core/protos/tablet_pipe.proto2
-rw-r--r--ydb/core/protos/tenant_slot_broker.proto4
-rw-r--r--ydb/core/protos/test_shard.proto122
-rw-r--r--ydb/core/protos/ya.make16
-rw-r--r--ydb/core/quoter/kesus_quoter_proxy.cpp14
-rw-r--r--ydb/core/quoter/quoter_service_impl.h4
-rw-r--r--ydb/core/security/ticket_parser.cpp2
-rw-r--r--ydb/core/sys_view/common/events.h22
-rw-r--r--ydb/core/sys_view/common/schema.cpp2
-rw-r--r--ydb/core/sys_view/common/schema.h52
-rw-r--r--ydb/core/sys_view/scan.cpp8
-rw-r--r--ydb/core/sys_view/storage/base.h378
-rw-r--r--ydb/core/sys_view/storage/groups.cpp60
-rw-r--r--ydb/core/sys_view/storage/pdisks.cpp64
-rw-r--r--ydb/core/sys_view/storage/storage_pools.cpp58
-rw-r--r--ydb/core/sys_view/storage/storage_stats.cpp76
-rw-r--r--ydb/core/sys_view/storage/storage_stats.h18
-rw-r--r--ydb/core/sys_view/storage/vslots.cpp60
-rw-r--r--ydb/core/sys_view/storage/ya.make4
-rw-r--r--ydb/core/sys_view/ut_kqp.cpp80
-rw-r--r--ydb/core/tablet/bootstrapper.cpp10
-rw-r--r--ydb/core/tablet/node_tablet_monitor.cpp16
-rw-r--r--ydb/core/tablet/node_whiteboard.cpp140
-rw-r--r--ydb/core/tablet/resource_broker_impl.h4
-rw-r--r--ydb/core/tablet/tablet_counters.h48
-rw-r--r--ydb/core/tablet/tablet_counters_aggregator.cpp26
-rw-r--r--ydb/core/tablet/tablet_counters_aggregator_ut.cpp14
-rw-r--r--ydb/core/tablet/tablet_counters_protobuf.h22
-rw-r--r--ydb/core/tablet/tablet_monitoring_proxy.cpp8
-rw-r--r--ydb/core/tablet/tablet_pipe_client.cpp8
-rw-r--r--ydb/core/tablet/tablet_pipe_server.cpp6
-rw-r--r--ydb/core/tablet/tablet_pipecache.cpp4
-rw-r--r--ydb/core/tablet/tablet_req_blockbs.cpp8
-rw-r--r--ydb/core/tablet/tablet_req_delete.cpp26
-rw-r--r--ydb/core/tablet/tablet_req_findlatest.cpp4
-rw-r--r--ydb/core/tablet/tablet_req_rebuildhistory.cpp8
-rw-r--r--ydb/core/tablet/tablet_req_reset.cpp4
-rw-r--r--ydb/core/tablet/tablet_req_writelog.cpp4
-rw-r--r--ydb/core/tablet/tablet_resolver.cpp34
-rw-r--r--ydb/core/tablet/tablet_responsiveness_pinger.h4
-rw-r--r--ydb/core/tablet/tablet_sys.h4
-rw-r--r--ydb/core/tablet_flat/flat_bio_actor.cpp2
-rw-r--r--ydb/core/tablet_flat/flat_cxx_database.h76
-rw-r--r--ydb/core/tablet_flat/flat_cxx_database_ut.cpp30
-rw-r--r--ydb/core/tablet_flat/flat_executor.h4
-rw-r--r--ydb/core/tablet_flat/flat_executor_counters.cpp26
-rw-r--r--ydb/core/tablet_flat/flat_mem_warm.h2
-rw-r--r--ydb/core/tablet_flat/flat_ops_compact.h2
-rw-r--r--ydb/core/tablet_flat/shared_sausagecache.cpp4
-rw-r--r--ydb/core/tablet_flat/test/libs/exec/dummy.h2
-rw-r--r--ydb/core/tablet_flat/test/libs/exec/owner.h2
-rw-r--r--ydb/core/tablet_flat/test/libs/exec/storage.h2
-rw-r--r--ydb/core/tablet_flat/test/libs/exec/warden.h2
-rw-r--r--ydb/core/tablet_flat/test/libs/rows/heap.h4
-rw-r--r--ydb/core/test_tablet/defs.h12
-rw-r--r--ydb/core/test_tablet/events.h52
-rw-r--r--ydb/core/test_tablet/load_actor_delete.cpp154
-rw-r--r--ydb/core/test_tablet/load_actor_impl.cpp280
-rw-r--r--ydb/core/test_tablet/load_actor_impl.h332
-rw-r--r--ydb/core/test_tablet/load_actor_mon.cpp308
-rw-r--r--ydb/core/test_tablet/load_actor_read_validate.cpp876
-rw-r--r--ydb/core/test_tablet/load_actor_state.cpp168
-rw-r--r--ydb/core/test_tablet/load_actor_write.cpp128
-rw-r--r--ydb/core/test_tablet/scheme.h40
-rw-r--r--ydb/core/test_tablet/state_server_interface.cpp542
-rw-r--r--ydb/core/test_tablet/state_server_interface.h82
-rw-r--r--ydb/core/test_tablet/test_shard_impl.h264
-rw-r--r--ydb/core/test_tablet/test_shard_mon.cpp172
-rw-r--r--ydb/core/test_tablet/test_tablet.cpp20
-rw-r--r--ydb/core/test_tablet/test_tablet.h18
-rw-r--r--ydb/core/test_tablet/time_series.h188
-rw-r--r--ydb/core/test_tablet/tx_init_scheme.cpp50
-rw-r--r--ydb/core/test_tablet/tx_initialize.cpp92
-rw-r--r--ydb/core/test_tablet/tx_load_everything.cpp78
-rw-r--r--ydb/core/test_tablet/ya.make12
-rw-r--r--ydb/core/testlib/basics/helpers.cpp2
-rw-r--r--ydb/core/testlib/basics/helpers.h2
-rw-r--r--ydb/core/testlib/basics/runtime.cpp28
-rw-r--r--ydb/core/testlib/basics/runtime.h6
-rw-r--r--ydb/core/testlib/basics/services.cpp10
-rw-r--r--ydb/core/testlib/basics/storage.h8
-rw-r--r--ydb/core/testlib/fake_coordinator.h6
-rw-r--r--ydb/core/testlib/fake_scheme_shard.h4
-rw-r--r--ydb/core/testlib/tablet_flat_dummy.cpp4
-rw-r--r--ydb/core/testlib/tablet_helpers.cpp10
-rw-r--r--ydb/core/testlib/tenant_runtime.cpp24
-rw-r--r--ydb/core/testlib/test_client.cpp48
-rw-r--r--ydb/core/testlib/test_client.h8
-rw-r--r--ydb/core/tracing/tablet_info.cpp18
-rw-r--r--ydb/core/tx/coordinator/coordinator_impl.h4
-rw-r--r--ydb/core/tx/coordinator/mediator_queue.cpp4
-rw-r--r--ydb/core/tx/datashard/datashard__conditional_erase_rows.cpp2
-rw-r--r--ydb/core/tx/datashard/datashard__read_columns.cpp2
-rw-r--r--ydb/core/tx/datashard/datashard__stats.cpp2
-rw-r--r--ydb/core/tx/datashard/datashard_distributed_erase.cpp4
-rw-r--r--ydb/core/tx/datashard/datashard_impl.h4
-rw-r--r--ydb/core/tx/datashard/read_table_scan.cpp4
-rw-r--r--ydb/core/tx/mediator/execute_queue.cpp4
-rw-r--r--ydb/core/tx/mediator/mediator_impl.h4
-rw-r--r--ydb/core/tx/mediator/tablet_queue.cpp12
-rw-r--r--ydb/core/tx/scheme_board/cache.cpp4
-rw-r--r--ydb/core/tx/scheme_board/populator.cpp8
-rw-r--r--ydb/core/tx/scheme_board/replica.cpp4
-rw-r--r--ydb/core/tx/scheme_board/subscriber.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_impl.h4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.cpp2
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/ls_checks.cpp6
-rw-r--r--ydb/core/tx/schemeshard/ut_pq/ya.make32
-rw-r--r--ydb/core/tx/schemeshard/ut_reboots.cpp90
-rw-r--r--ydb/core/tx/schemeshard/ut_reboots/ya.make8
-rw-r--r--ydb/core/tx/schemeshard/ut_rtmr.cpp8
-rw-r--r--ydb/core/tx/schemeshard/ut_rtmr/ya.make30
-rw-r--r--ydb/core/tx/schemeshard/ut_split_merge/ya.make8
-rw-r--r--ydb/core/tx/schemeshard/ut_subdomain/ya.make32
-rw-r--r--ydb/core/tx/time_cast/time_cast.cpp4
-rw-r--r--ydb/core/tx/tx_allocator/txallocator_impl.h4
-rw-r--r--ydb/core/tx/tx_proxy/datareq.cpp4
-rw-r--r--ydb/core/tx/tx_proxy/describe.cpp4
-rw-r--r--ydb/core/tx/tx_proxy/proxy.h2
-rw-r--r--ydb/core/tx/tx_proxy/proxy_impl.cpp4
-rw-r--r--ydb/core/util/defs.h10
-rw-r--r--ydb/core/util/failure_injection.cpp440
-rw-r--r--ydb/core/util/failure_injection.h16
-rw-r--r--ydb/core/util/format.cpp106
-rw-r--r--ydb/core/util/format.h18
-rw-r--r--ydb/core/util/fragmented_buffer.cpp34
-rw-r--r--ydb/core/util/fragmented_buffer.h28
-rw-r--r--ydb/core/util/fragmented_buffer_ut.cpp28
-rw-r--r--ydb/core/util/interval_set.h18
-rw-r--r--ydb/core/util/interval_set_ut.cpp180
-rw-r--r--ydb/core/util/iterator.h112
-rw-r--r--ydb/core/util/lz4_data_generator.h40
-rw-r--r--ydb/core/util/pb.h18
-rw-r--r--ydb/core/util/queue_inplace.h34
-rw-r--r--ydb/core/util/single_thread_ic_mock.cpp904
-rw-r--r--ydb/core/util/single_thread_ic_mock.h60
-rw-r--r--ydb/core/util/stlog.h448
-rw-r--r--ydb/core/util/testactorsys.cpp372
-rw-r--r--ydb/core/util/testactorsys.h1374
-rw-r--r--ydb/core/util/throughput_meter.h140
-rw-r--r--ydb/core/util/wrapped_value.h54
-rw-r--r--ydb/core/util/ya.make16
-rw-r--r--ydb/core/viewer/browse.h8
-rw-r--r--ydb/core/viewer/browse_pq.h8
-rw-r--r--ydb/core/viewer/content/v2/storage.js2
-rw-r--r--ydb/core/viewer/content/v2/vdisk.js18
-rw-r--r--ydb/core/viewer/content/viewer.js38
-rw-r--r--ydb/core/viewer/json_browse.h4
-rw-r--r--ydb/core/viewer/json_bscontrollerinfo.h4
-rw-r--r--ydb/core/viewer/json_cluster.h4
-rw-r--r--ydb/core/viewer/json_compute.h4
-rw-r--r--ydb/core/viewer/json_config.h4
-rw-r--r--ydb/core/viewer/json_content.h4
-rw-r--r--ydb/core/viewer/json_counters.h6
-rw-r--r--ydb/core/viewer/json_describe.h4
-rw-r--r--ydb/core/viewer/json_hiveinfo.h4
-rw-r--r--ydb/core/viewer/json_hivestats.h4
-rw-r--r--ydb/core/viewer/json_labeledcounters.h4
-rw-r--r--ydb/core/viewer/json_metainfo.h4
-rw-r--r--ydb/core/viewer/json_netinfo.h4
-rw-r--r--ydb/core/viewer/json_nodelist.h20
-rw-r--r--ydb/core/viewer/json_pqconsumerinfo.h4
-rw-r--r--ydb/core/viewer/json_query.h4
-rw-r--r--ydb/core/viewer/json_storage.h4
-rw-r--r--ydb/core/viewer/json_tabletcounters.h4
-rw-r--r--ydb/core/viewer/json_tenantinfo.h6
-rw-r--r--ydb/core/viewer/json_tenants.h4
-rw-r--r--ydb/core/viewer/json_topicinfo.h4
-rw-r--r--ydb/core/viewer/json_wb_req.h4
-rw-r--r--ydb/core/viewer/json_whoami.h4
-rw-r--r--ydb/core/viewer/protos/viewer.proto2
-rw-r--r--ydb/core/viewer/viewer.cpp28
-rw-r--r--ydb/core/viewer/wb_group.h14
-rw-r--r--ydb/core/ydb_convert/table_description.cpp2
-rw-r--r--ydb/core/ydb_convert/ydb_convert.cpp2
-rw-r--r--ydb/core/ymq/actor/action.h4
-rw-r--r--ydb/core/ymq/actor/executor.h4
-rw-r--r--ydb/core/ymq/actor/fifo_cleanup.h4
-rw-r--r--ydb/core/ymq/actor/metering.cpp4
-rw-r--r--ydb/core/ymq/actor/migration.cpp4
-rw-r--r--ydb/core/ymq/actor/migration.h4
-rw-r--r--ydb/core/ymq/actor/ping.h4
-rw-r--r--ydb/core/ymq/actor/proxy_actor.h4
-rw-r--r--ydb/core/ymq/actor/proxy_service.h4
-rw-r--r--ydb/core/ymq/actor/purge.h4
-rw-r--r--ydb/core/ymq/actor/queue_leader.h2
-rw-r--r--ydb/core/ymq/actor/queue_schema.h8
-rw-r--r--ydb/core/ymq/actor/retention.h4
-rw-r--r--ydb/core/ymq/actor/schema.cpp4
-rw-r--r--ydb/core/ymq/actor/schema.h12
-rw-r--r--ydb/core/ymq/actor/service.h4
-rw-r--r--ydb/core/ymq/actor/user_settings_reader.h4
-rw-r--r--ydb/library/wilson/wilson_event.h2
-rw-r--r--ydb/library/wilson/wilson_trace.h2
-rw-r--r--ydb/library/wilson/ya.make6
-rw-r--r--ydb/library/yql/ast/yql_expr.cpp2
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_join.cpp16
-rw-r--r--ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp2
-rw-r--r--ydb/library/yql/providers/common/udf_resolve/yql_udf_resolver_with_index.cpp2
-rw-r--r--ydb/library/yql/providers/dq/service/interconnect_helpers.cpp4
-rw-r--r--ydb/library/yql/sql/v0/context.cpp2
-rw-r--r--ydb/library/yql/sql/v0/node.cpp8
-rw-r--r--ydb/library/yql/sql/v0/select.cpp2
-rw-r--r--ydb/library/yql/sql/v0/sql.cpp8
-rw-r--r--ydb/library/yql/sql/v1/node.cpp6
-rw-r--r--ydb/library/yql/sql/v1/select.cpp2
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp8
-rw-r--r--ydb/library/yql/utils/log/log.cpp2
-rw-r--r--ydb/public/lib/base/msgbus.cpp12
-rw-r--r--ydb/public/lib/base/msgbus.h118
-rw-r--r--ydb/public/lib/deprecated/client/grpc_client.cpp346
-rw-r--r--ydb/public/lib/deprecated/client/grpc_client.h158
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_client.cpp2
-rw-r--r--ydb/public/lib/deprecated/client/msgbus_client.h2
-rw-r--r--ydb/public/lib/deprecated/kicli/dynamic_node.cpp26
-rw-r--r--ydb/public/lib/deprecated/kicli/error.cpp2
-rw-r--r--ydb/public/lib/deprecated/kicli/kicli.h24
-rw-r--r--ydb/public/lib/deprecated/kicli/kikimr.cpp32
-rw-r--r--ydb/public/lib/deprecated/kicli/result.cpp18
-rw-r--r--ydb/public/lib/deprecated/kicli/schema.cpp6
-rw-r--r--ydb/public/lib/deprecated/kicli/ya.make2
-rw-r--r--ydb/services/kesus/grpc_service.cpp4
-rw-r--r--ydb/services/persqueue_v1/grpc_pq_actor.h6
-rw-r--r--ydb/services/persqueue_v1/grpc_pq_read_actor.cpp2
-rw-r--r--ydb/services/ydb/ydb_operation.cpp2
-rw-r--r--ydb/services/ydb/ydb_scheme.cpp2
-rw-r--r--ydb/services/ydb/ydb_table.cpp2
-rw-r--r--ydb/tests/library/common/protobuf.py4
-rw-r--r--ydb/tests/library/common/types.py2
-rw-r--r--ydb/tests/library/harness/kikimr_client.py10
1364 files changed, 98780 insertions, 98780 deletions
diff --git a/contrib/libs/grpc/src/cpp/common/channel_arguments.cc b/contrib/libs/grpc/src/cpp/common/channel_arguments.cc
index 5a5dd91b5ec..6aaaeab1044 100644
--- a/contrib/libs/grpc/src/cpp/common/channel_arguments.cc
+++ b/contrib/libs/grpc/src/cpp/common/channel_arguments.cc
@@ -101,7 +101,7 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
GPR_ASSERT(!replaced);
arg.value.pointer.vtable->destroy(arg.value.pointer.p);
arg.value.pointer = mutator_arg.value.pointer;
- replaced = true;
+ replaced = true;
}
}
diff --git a/library/cpp/actors/core/actor.cpp b/library/cpp/actors/core/actor.cpp
index 6f9ba6a42bb..081a8ae21c8 100644
--- a/library/cpp/actors/core/actor.cpp
+++ b/library/cpp/actors/core/actor.cpp
@@ -8,13 +8,13 @@ namespace NActors {
TlsActivationContext((TActivationContext*)nullptr);
bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const {
- return Send(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId)));
- }
-
- bool TActorContext::Send(TAutoPtr<IEventHandle> ev) const {
- return ExecutorThread.Send(ev);
+ return Send(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId)));
}
+ bool TActorContext::Send(TAutoPtr<IEventHandle> ev) const {
+ return ExecutorThread.Send(ev);
+ }
+
void IActor::Registered(TActorSystem* sys, const TActorId& owner) {
// fallback to legacy method, do not use it anymore
if (auto eh = AfterRegister(SelfId(), owner))
@@ -49,18 +49,18 @@ namespace NActors {
return TActivationContext::Send(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId)));
}
- void TActorIdentity::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
- return TActivationContext::Schedule(deadline, new IEventHandle(*this, {}, ev), cookie);
- }
-
- void TActorIdentity::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
- return TActivationContext::Schedule(deadline, new IEventHandle(*this, {}, ev), cookie);
- }
-
- void TActorIdentity::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const {
- return TActivationContext::Schedule(delta, new IEventHandle(*this, {}, ev), cookie);
- }
-
+ void TActorIdentity::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
+ return TActivationContext::Schedule(deadline, new IEventHandle(*this, {}, ev), cookie);
+ }
+
+ void TActorIdentity::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
+ return TActivationContext::Schedule(deadline, new IEventHandle(*this, {}, ev), cookie);
+ }
+
+ void TActorIdentity::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const {
+ return TActivationContext::Schedule(delta, new IEventHandle(*this, {}, ev), cookie);
+ }
+
TActorId TActivationContext::RegisterWithSameMailbox(IActor* actor, TActorId parentId) {
Y_VERIFY_DEBUG(parentId);
auto& ctx = *TlsActivationContext;
@@ -135,18 +135,18 @@ namespace NActors {
return TlsActivationContext->ExecutorThread.ActorSystem->Monotonic();
}
- TInstant TActorContext::Now() const {
- return ExecutorThread.ActorSystem->Timestamp();
- }
-
- TMonotonic TActorContext::Monotonic() const {
- return ExecutorThread.ActorSystem->Monotonic();
- }
-
- NLog::TSettings* TActivationContext::LoggerSettings() const {
- return ExecutorThread.ActorSystem->LoggerSettings();
+ TInstant TActorContext::Now() const {
+ return ExecutorThread.ActorSystem->Timestamp();
}
+ TMonotonic TActorContext::Monotonic() const {
+ return ExecutorThread.ActorSystem->Monotonic();
+ }
+
+ NLog::TSettings* TActivationContext::LoggerSettings() const {
+ return ExecutorThread.ActorSystem->LoggerSettings();
+ }
+
std::pair<ui32, ui32> TActorContext::CountMailboxEvents(ui32 maxTraverse) const {
return Mailbox.CountMailboxEvents(SelfID.LocalId(), maxTraverse);
}
diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h
index ed29bd14b9e..bfbc9d5a08a 100644
--- a/library/cpp/actors/core/actor.h
+++ b/library/cpp/actors/core/actor.h
@@ -66,10 +66,10 @@ namespace NActors {
static TInstant Now();
static TMonotonic Monotonic();
- NLog::TSettings* LoggerSettings() const;
+ NLog::TSettings* LoggerSettings() const;
// register new actor in ActorSystem on new fresh mailbox.
- static TActorId Register(IActor* actor, TActorId parentId = TActorId(), TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>());
+ static TActorId Register(IActor* actor, TActorId parentId = TActorId(), TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>());
// Register new actor in ActorSystem on same _mailbox_ as current actor.
// There is one thread per mailbox to execute actor, which mean
@@ -102,11 +102,11 @@ namespace NActors {
bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
return Send(recipient, static_cast<IEventBase*>(ev.Release()), flags, cookie, std::move(traceId));
}
- bool Send(TAutoPtr<IEventHandle> ev) const;
-
- TInstant Now() const;
- TMonotonic Monotonic() const;
+ bool Send(TAutoPtr<IEventHandle> ev) const;
+ TInstant Now() const;
+ TMonotonic Monotonic() const;
+
/**
* Schedule one-shot event that will be send at given time point in the future.
*
@@ -164,9 +164,9 @@ namespace NActors {
}
bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const;
- void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
- void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
- void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
+ void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
+ void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
+ void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
};
class IActor;
@@ -223,16 +223,16 @@ namespace NActors {
friend class TDecorator;
public:
- /// @sa services.proto NKikimrServices::TActivity::EType
+ /// @sa services.proto NKikimrServices::TActivity::EType
enum EActorActivity {
OTHER = 0,
ACTOR_SYSTEM = 1,
ACTORLIB_COMMON = 2,
ACTORLIB_STATS = 3,
- LOG_ACTOR = 4,
- INTERCONNECT_PROXY_TCP = 12,
- INTERCONNECT_SESSION_TCP = 13,
- INTERCONNECT_COMMON = 171,
+ LOG_ACTOR = 4,
+ INTERCONNECT_PROXY_TCP = 12,
+ INTERCONNECT_SESSION_TCP = 13,
+ INTERCONNECT_COMMON = 171,
SELF_PING_ACTOR = 207,
TEST_ACTOR_RUNTIME = 283,
INTERCONNECT_HANDSHAKE = 284,
@@ -241,11 +241,11 @@ namespace NActors {
ACTOR_SYSTEM_SCHEDULER_ACTOR = 312,
ACTOR_FUTURE_CALLBACK = 337,
INTERCONNECT_MONACTOR = 362,
- INTERCONNECT_LOAD_ACTOR = 376,
- INTERCONNECT_LOAD_RESPONDER = 377,
- NAMESERVICE = 450,
+ INTERCONNECT_LOAD_ACTOR = 376,
+ INTERCONNECT_LOAD_RESPONDER = 377,
+ NAMESERVICE = 450,
DNS_RESOLVER = 481,
- INTERCONNECT_PROXY_WRAPPER = 546,
+ INTERCONNECT_PROXY_WRAPPER = 546,
};
using EActivityType = EActorActivity;
@@ -275,16 +275,16 @@ namespace NActors {
StateFunc = static_cast<TReceiveFunc>(stateFunc);
}
- template <typename T, typename... TArgs>
- void Become(T stateFunc, const TActorContext& ctx, TArgs&&... args) {
+ template <typename T, typename... TArgs>
+ void Become(T stateFunc, const TActorContext& ctx, TArgs&&... args) {
StateFunc = static_cast<TReceiveFunc>(stateFunc);
- ctx.Schedule(std::forward<TArgs>(args)...);
+ ctx.Schedule(std::forward<TArgs>(args)...);
}
- template <typename T, typename... TArgs>
- void Become(T stateFunc, TArgs&&... args) {
+ template <typename T, typename... TArgs>
+ void Become(T stateFunc, TArgs&&... args) {
StateFunc = static_cast<TReceiveFunc>(stateFunc);
- Schedule(std::forward<TArgs>(args)...);
+ Schedule(std::forward<TArgs>(args)...);
}
protected:
@@ -304,25 +304,25 @@ namespace NActors {
HandledEvents++;
}
- // must be called to wrap any call trasitions from one actor to another
- template<typename TActor, typename TMethod, typename... TArgs>
- static decltype((std::declval<TActor>().*std::declval<TMethod>())(std::declval<TArgs>()...))
- InvokeOtherActor(TActor& actor, TMethod&& method, TArgs&&... args) {
- struct TRecurseContext : TActorContext {
- TActivationContext *Prev;
+ // must be called to wrap any call trasitions from one actor to another
+ template<typename TActor, typename TMethod, typename... TArgs>
+ static decltype((std::declval<TActor>().*std::declval<TMethod>())(std::declval<TArgs>()...))
+ InvokeOtherActor(TActor& actor, TMethod&& method, TArgs&&... args) {
+ struct TRecurseContext : TActorContext {
+ TActivationContext *Prev;
TRecurseContext(const TActorId& actorId)
- : TActorContext(TActivationContext::ActorContextFor(actorId))
- , Prev(TlsActivationContext)
- {
- TlsActivationContext = this;
- }
- ~TRecurseContext() {
- TlsActivationContext = Prev;
- }
- } context(actor.SelfId());
- return (actor.*method)(std::forward<TArgs>(args)...);
- }
-
+ : TActorContext(TActivationContext::ActorContextFor(actorId))
+ , Prev(TlsActivationContext)
+ {
+ TlsActivationContext = this;
+ }
+ ~TRecurseContext() {
+ TlsActivationContext = Prev;
+ }
+ } context(actor.SelfId());
+ return (actor.*method)(std::forward<TArgs>(args)...);
+ }
+
virtual void Registered(TActorSystem* sys, const TActorId& owner);
virtual TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) {
@@ -435,20 +435,20 @@ namespace NActors {
#define STFUNC_SIG TAutoPtr< ::NActors::IEventHandle>&ev, const ::NActors::TActorContext &ctx
-#define STATEFN_SIG TAutoPtr<::NActors::IEventHandle>& ev
+#define STATEFN_SIG TAutoPtr<::NActors::IEventHandle>& ev
#define STFUNC(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& ctx)
#define STATEFN(funcName) void funcName(TAutoPtr< ::NActors::IEventHandle>& ev, const ::NActors::TActorContext& )
-#define STRICT_STFUNC(NAME, HANDLERS) \
- void NAME(STFUNC_SIG) { \
- Y_UNUSED(ctx); \
- switch (const ui32 etype = ev->GetTypeRewrite()) { \
- HANDLERS \
- default: \
- Y_VERIFY_DEBUG(false, "%s: unexpected message type 0x%08" PRIx32, __func__, etype); \
- } \
- }
-
+#define STRICT_STFUNC(NAME, HANDLERS) \
+ void NAME(STFUNC_SIG) { \
+ Y_UNUSED(ctx); \
+ switch (const ui32 etype = ev->GetTypeRewrite()) { \
+ HANDLERS \
+ default: \
+ Y_VERIFY_DEBUG(false, "%s: unexpected message type 0x%08" PRIx32, __func__, etype); \
+ } \
+ }
+
inline const TActorContext& TActivationContext::AsActorContext() {
TActivationContext* tls = TlsActivationContext;
return *static_cast<TActorContext*>(tls);
diff --git a/library/cpp/actors/core/actor_bootstrapped.h b/library/cpp/actors/core/actor_bootstrapped.h
index a37887c9398..96298d7372e 100644
--- a/library/cpp/actors/core/actor_bootstrapped.h
+++ b/library/cpp/actors/core/actor_bootstrapped.h
@@ -4,34 +4,34 @@
#include "events.h"
namespace NActors {
- template<typename T> struct dependent_false : std::false_type {};
-
- template<typename TDerived>
- class TActorBootstrapped : public TActor<TDerived> {
+ template<typename T> struct dependent_false : std::false_type {};
+
+ template<typename TDerived>
+ class TActorBootstrapped : public TActor<TDerived> {
protected:
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override {
- return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parentId, {}, 0);
+ return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parentId, {}, 0);
}
STFUNC(StateBootstrap) {
- Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap, "Unexpected bootstrap message");
- using T = decltype(&TDerived::Bootstrap);
- TDerived& self = static_cast<TDerived&>(*this);
- if constexpr (std::is_invocable_v<T, TDerived, const TActorContext&>) {
- self.Bootstrap(ctx);
+ Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap, "Unexpected bootstrap message");
+ using T = decltype(&TDerived::Bootstrap);
+ TDerived& self = static_cast<TDerived&>(*this);
+ if constexpr (std::is_invocable_v<T, TDerived, const TActorContext&>) {
+ self.Bootstrap(ctx);
} else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&, const TActorContext&>) {
- self.Bootstrap(ev->Sender, ctx);
- } else if constexpr (std::is_invocable_v<T, TDerived>) {
- self.Bootstrap();
+ self.Bootstrap(ev->Sender, ctx);
+ } else if constexpr (std::is_invocable_v<T, TDerived>) {
+ self.Bootstrap();
} else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&>) {
- self.Bootstrap(ev->Sender);
- } else {
- static_assert(dependent_false<TDerived>::value, "No correct Bootstrap() signature");
+ self.Bootstrap(ev->Sender);
+ } else {
+ static_assert(dependent_false<TDerived>::value, "No correct Bootstrap() signature");
}
}
TActorBootstrapped()
: TActor<TDerived>(&TDerived::StateBootstrap)
- {}
+ {}
};
}
diff --git a/library/cpp/actors/core/actor_coroutine.cpp b/library/cpp/actors/core/actor_coroutine.cpp
index 0ab4d2b24de..8fb203bf664 100644
--- a/library/cpp/actors/core/actor_coroutine.cpp
+++ b/library/cpp/actors/core/actor_coroutine.cpp
@@ -1,165 +1,165 @@
-#include "actor_coroutine.h"
-#include "executor_thread.h"
-
+#include "actor_coroutine.h"
+#include "executor_thread.h"
+
#include <util/system/sanitizers.h>
#include <util/system/type_name.h>
-namespace NActors {
+namespace NActors {
static constexpr size_t StackOverflowGap = 4096;
static char GoodStack[StackOverflowGap];
-
+
static struct TInitGoodStack {
TInitGoodStack() {
// fill stack with some pseudo-random pattern
for (size_t k = 0; k < StackOverflowGap; ++k) {
GoodStack[k] = k + k * 91;
}
- }
+ }
} initGoodStack;
-
- TActorCoroImpl::TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill, bool allowUnhandledDtor)
- : Stack(stackSize)
- , AllowUnhandledPoisonPill(allowUnhandledPoisonPill)
- , AllowUnhandledDtor(allowUnhandledDtor)
+
+ TActorCoroImpl::TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill, bool allowUnhandledDtor)
+ : Stack(stackSize)
+ , AllowUnhandledPoisonPill(allowUnhandledPoisonPill)
+ , AllowUnhandledDtor(allowUnhandledDtor)
, FiberClosure{this, TArrayRef(Stack.Begin(), Stack.End())}
- , FiberContext(FiberClosure)
- {
-#ifndef NDEBUG
+ , FiberContext(FiberClosure)
+ {
+#ifndef NDEBUG
char* p;
-#if STACK_GROW_DOWN
+#if STACK_GROW_DOWN
p = Stack.Begin();
-#else
+#else
p = Stack.End() - StackOverflowGap;
-#endif
+#endif
memcpy(p, GoodStack, StackOverflowGap);
-#endif
- }
-
- TActorCoroImpl::~TActorCoroImpl() {
- if (!Finished && !NSan::TSanIsOn()) { // only resume when we have bootstrapped and Run() was entered and not yet finished; in other case simply terminate
- Y_VERIFY(!PendingEvent);
- Resume();
- }
- }
-
- bool TActorCoroImpl::Send(TAutoPtr<IEventHandle> ev) {
- return GetActorContext().ExecutorThread.Send(ev);
+#endif
}
-
- THolder<IEventHandle> TActorCoroImpl::WaitForEvent(TInstant deadline) {
- const ui64 cookie = ++WaitCookie;
- if (deadline != TInstant::Max()) {
- ActorContext->ExecutorThread.Schedule(deadline - Now(), new IEventHandle(SelfActorId, {}, new TEvCoroTimeout,
- 0, cookie));
- }
-
+
+ TActorCoroImpl::~TActorCoroImpl() {
+ if (!Finished && !NSan::TSanIsOn()) { // only resume when we have bootstrapped and Run() was entered and not yet finished; in other case simply terminate
+ Y_VERIFY(!PendingEvent);
+ Resume();
+ }
+ }
+
+ bool TActorCoroImpl::Send(TAutoPtr<IEventHandle> ev) {
+ return GetActorContext().ExecutorThread.Send(ev);
+ }
+
+ THolder<IEventHandle> TActorCoroImpl::WaitForEvent(TInstant deadline) {
+ const ui64 cookie = ++WaitCookie;
+ if (deadline != TInstant::Max()) {
+ ActorContext->ExecutorThread.Schedule(deadline - Now(), new IEventHandle(SelfActorId, {}, new TEvCoroTimeout,
+ 0, cookie));
+ }
+
// ensure we have no unprocessed event and return back to actor system to receive one
Y_VERIFY(!PendingEvent);
ReturnToActorSystem();
-
+
// obtain pending event and ensure we've got one
- while (THolder<IEventHandle> event = std::exchange(PendingEvent, {})) {
- if (event->GetTypeRewrite() != TEvents::TSystem::CoroTimeout) {
- // special handling for poison pill -- we throw exception
- if (event->GetTypeRewrite() == TEvents::TEvPoisonPill::EventType) {
- throw TPoisonPillException();
- }
-
- // otherwise just return received event
- return event;
- } else if (event->Cookie == cookie) {
- return nullptr; // it is not a race -- we've got timeout exactly for our current wait
- } else {
- ReturnToActorSystem(); // drop this event and wait for the next one
- }
+ while (THolder<IEventHandle> event = std::exchange(PendingEvent, {})) {
+ if (event->GetTypeRewrite() != TEvents::TSystem::CoroTimeout) {
+ // special handling for poison pill -- we throw exception
+ if (event->GetTypeRewrite() == TEvents::TEvPoisonPill::EventType) {
+ throw TPoisonPillException();
+ }
+
+ // otherwise just return received event
+ return event;
+ } else if (event->Cookie == cookie) {
+ return nullptr; // it is not a race -- we've got timeout exactly for our current wait
+ } else {
+ ReturnToActorSystem(); // drop this event and wait for the next one
+ }
}
- Y_FAIL("no pending event");
- }
-
- const TActorContext& TActorCoroImpl::GetActorContext() const {
- Y_VERIFY(ActorContext);
- return *ActorContext;
+ Y_FAIL("no pending event");
+ }
+
+ const TActorContext& TActorCoroImpl::GetActorContext() const {
+ Y_VERIFY(ActorContext);
+ return *ActorContext;
}
-
- bool TActorCoroImpl::ProcessEvent(THolder<IEventHandle> ev) {
+
+ bool TActorCoroImpl::ProcessEvent(THolder<IEventHandle> ev) {
Y_VERIFY(!PendingEvent);
- if (!SelfActorId) { // process bootstrap message, extract actor ids
- Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap);
- SelfActorId = ev->Recipient;
- ParentActorId = ev->Sender;
- } else { // process further messages
- PendingEvent = std::move(ev);
- }
-
- // prepare actor context for in-coroutine use
+ if (!SelfActorId) { // process bootstrap message, extract actor ids
+ Y_VERIFY(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap);
+ SelfActorId = ev->Recipient;
+ ParentActorId = ev->Sender;
+ } else { // process further messages
+ PendingEvent = std::move(ev);
+ }
+
+ // prepare actor context for in-coroutine use
TActivationContext *ac = TlsActivationContext;
TlsActivationContext = nullptr;
- TActorContext ctx(ac->Mailbox, ac->ExecutorThread, ac->EventStart, SelfActorId);
- ActorContext = &ctx;
-
- Resume();
-
- // drop actor context
- TlsActivationContext = ac;
- ActorContext = nullptr;
-
- return Finished;
+ TActorContext ctx(ac->Mailbox, ac->ExecutorThread, ac->EventStart, SelfActorId);
+ ActorContext = &ctx;
+
+ Resume();
+
+ // drop actor context
+ TlsActivationContext = ac;
+ ActorContext = nullptr;
+
+ return Finished;
}
-
- void TActorCoroImpl::Resume() {
+
+ void TActorCoroImpl::Resume() {
// save caller context for a later return
Y_VERIFY(!ActorSystemContext);
- TExceptionSafeContext actorSystemContext;
+ TExceptionSafeContext actorSystemContext;
ActorSystemContext = &actorSystemContext;
-
+
// go to actor coroutine
- BeforeResume();
- ActorSystemContext->SwitchTo(&FiberContext);
-
- // check for stack overflow
-#ifndef NDEBUG
+ BeforeResume();
+ ActorSystemContext->SwitchTo(&FiberContext);
+
+ // check for stack overflow
+#ifndef NDEBUG
const char* p;
-#if STACK_GROW_DOWN
+#if STACK_GROW_DOWN
p = Stack.Begin();
-#else
+#else
p = Stack.End() - StackOverflowGap;
-#endif
+#endif
Y_VERIFY_DEBUG(memcmp(p, GoodStack, StackOverflowGap) == 0);
-#endif
- }
-
- void TActorCoroImpl::DoRun() {
+#endif
+ }
+
+ void TActorCoroImpl::DoRun() {
try {
- if (ActorContext) { // ActorContext may be nullptr here if the destructor was invoked before bootstrapping
- Y_VERIFY(!PendingEvent);
- Run();
- }
+ if (ActorContext) { // ActorContext may be nullptr here if the destructor was invoked before bootstrapping
+ Y_VERIFY(!PendingEvent);
+ Run();
+ }
} catch (const TPoisonPillException& /*ex*/) {
if (!AllowUnhandledPoisonPill) {
Y_FAIL("unhandled TPoisonPillException");
}
- } catch (const TDtorException& /*ex*/) {
- if (!AllowUnhandledDtor) {
- Y_FAIL("unhandled TDtorException");
- }
- } catch (const std::exception& ex) {
+ } catch (const TDtorException& /*ex*/) {
+ if (!AllowUnhandledDtor) {
+ Y_FAIL("unhandled TDtorException");
+ }
+ } catch (const std::exception& ex) {
Y_FAIL("unhandled exception of type %s", TypeName(ex).data());
- } catch (...) {
- Y_FAIL("unhandled exception of type not derived from std::exception");
- }
+ } catch (...) {
+ Y_FAIL("unhandled exception of type not derived from std::exception");
+ }
Finished = true;
ReturnToActorSystem();
- }
-
- void TActorCoroImpl::ReturnToActorSystem() {
- TExceptionSafeContext* returnContext = std::exchange(ActorSystemContext, nullptr);
+ }
+
+ void TActorCoroImpl::ReturnToActorSystem() {
+ TExceptionSafeContext* returnContext = std::exchange(ActorSystemContext, nullptr);
Y_VERIFY(returnContext);
FiberContext.SwitchTo(returnContext);
- if (!PendingEvent) {
- // we have returned from the actor system and it kindly asks us to terminate the coroutine as it is being
- // stopped
- throw TDtorException();
- }
+ if (!PendingEvent) {
+ // we have returned from the actor system and it kindly asks us to terminate the coroutine as it is being
+ // stopped
+ throw TDtorException();
+ }
}
-
+
}
diff --git a/library/cpp/actors/core/actor_coroutine.h b/library/cpp/actors/core/actor_coroutine.h
index 6bcb768eafc..6b57dfc8562 100644
--- a/library/cpp/actors/core/actor_coroutine.h
+++ b/library/cpp/actors/core/actor_coroutine.h
@@ -1,32 +1,32 @@
-#pragma once
-
-#include <util/system/context.h>
-#include <util/system/filemap.h>
-
-#include "actor_bootstrapped.h"
-#include "executor_thread.h"
-#include "event_local.h"
-
-namespace NActors {
-
- class TActorCoro;
-
- class TActorCoroImpl : public ITrampoLine {
+#pragma once
+
+#include <util/system/context.h>
+#include <util/system/filemap.h>
+
+#include "actor_bootstrapped.h"
+#include "executor_thread.h"
+#include "event_local.h"
+
+namespace NActors {
+
+ class TActorCoro;
+
+ class TActorCoroImpl : public ITrampoLine {
TMappedAllocation Stack;
bool AllowUnhandledPoisonPill;
- bool AllowUnhandledDtor;
+ bool AllowUnhandledDtor;
TContClosure FiberClosure;
- TExceptionSafeContext FiberContext;
- TExceptionSafeContext* ActorSystemContext = nullptr;
+ TExceptionSafeContext FiberContext;
+ TExceptionSafeContext* ActorSystemContext = nullptr;
THolder<IEventHandle> PendingEvent;
- bool Finished = false;
- ui64 WaitCookie = 0;
- TActorContext *ActorContext = nullptr;
-
- protected:
+ bool Finished = false;
+ ui64 WaitCookie = 0;
+ TActorContext *ActorContext = nullptr;
+
+ protected:
TActorIdentity SelfActorId = TActorIdentity(TActorId());
TActorId ParentActorId;
-
+
private:
template <typename TFirstEvent, typename... TOtherEvents>
struct TIsOneOf: public TIsOneOf<TOtherEvents...> {
@@ -34,141 +34,141 @@ namespace NActors {
return ev.GetTypeRewrite() == TFirstEvent::EventType || TIsOneOf<TOtherEvents...>()(ev);
}
};
-
+
template <typename TSingleEvent>
struct TIsOneOf<TSingleEvent> {
bool operator()(IEventHandle& ev) const {
return ev.GetTypeRewrite() == TSingleEvent::EventType;
}
};
-
- struct TEvCoroTimeout : TEventLocal<TEvCoroTimeout, TEvents::TSystem::CoroTimeout> {};
-
- protected:
- struct TPoisonPillException : yexception {};
- struct TDtorException : yexception {};
+
+ struct TEvCoroTimeout : TEventLocal<TEvCoroTimeout, TEvents::TSystem::CoroTimeout> {};
+
+ protected:
+ struct TPoisonPillException : yexception {};
+ struct TDtorException : yexception {};
public:
- TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill = false, bool allowUnhandledDtor = false);
- // specify stackSize explicitly for each actor; don't forget about overflow control gap
-
- virtual ~TActorCoroImpl();
-
+ TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill = false, bool allowUnhandledDtor = false);
+ // specify stackSize explicitly for each actor; don't forget about overflow control gap
+
+ virtual ~TActorCoroImpl();
+
virtual void Run() = 0;
-
- virtual void BeforeResume() {}
-
+
+ virtual void BeforeResume() {}
+
// Handle all events that are not expected in wait loops.
virtual void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) = 0;
-
+
// Release execution ownership and wait for some event to arrive. When PoisonPill event is received, then
// TPoisonPillException is thrown.
- THolder<IEventHandle> WaitForEvent(TInstant deadline = TInstant::Max());
-
+ THolder<IEventHandle> WaitForEvent(TInstant deadline = TInstant::Max());
+
// Wait for specific event set by filter functor. Function returns first event that matches filter. On any other
// kind of event ProcessUnexpectedEvent() is called.
//
// Example: WaitForSpecificEvent([](IEventHandle& ev) { return ev.Cookie == 42; });
template <typename TFunc>
- THolder<IEventHandle> WaitForSpecificEvent(TFunc&& filter, TInstant deadline = TInstant::Max()) {
+ THolder<IEventHandle> WaitForSpecificEvent(TFunc&& filter, TInstant deadline = TInstant::Max()) {
for (;;) {
- if (THolder<IEventHandle> event = WaitForEvent(deadline); !event) {
- return nullptr;
- } else if (filter(*event)) {
+ if (THolder<IEventHandle> event = WaitForEvent(deadline); !event) {
+ return nullptr;
+ } else if (filter(*event)) {
return event;
} else {
ProcessUnexpectedEvent(event);
}
- }
- }
-
+ }
+ }
+
// Wait for specific event or set of events. Function returns first event that matches enlisted type. On any other
// kind of event ProcessUnexpectedEvent() is called.
//
// Example: WaitForSpecificEvent<TEvReadResult, TEvFinished>();
template <typename TFirstEvent, typename TSecondEvent, typename... TOtherEvents>
- THolder<IEventHandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) {
+ THolder<IEventHandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) {
TIsOneOf<TFirstEvent, TSecondEvent, TOtherEvents...> filter;
- return WaitForSpecificEvent(filter, deadline);
+ return WaitForSpecificEvent(filter, deadline);
}
-
+
// Wait for single specific event.
template <typename TEventType>
- THolder<typename TEventType::THandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) {
+ THolder<typename TEventType::THandle> WaitForSpecificEvent(TInstant deadline = TInstant::Max()) {
auto filter = [](IEventHandle& ev) {
return ev.GetTypeRewrite() == TEventType::EventType;
};
- THolder<IEventHandle> event = WaitForSpecificEvent(filter, deadline);
+ THolder<IEventHandle> event = WaitForSpecificEvent(filter, deadline);
return THolder<typename TEventType::THandle>(static_cast<typename TEventType::THandle*>(event ? event.Release() : nullptr));
}
-
- protected: // Actor System compatibility section
+
+ protected: // Actor System compatibility section
const TActorContext& GetActorContext() const;
- TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; }
- TInstant Now() const { return GetActorContext().Now(); }
-
+ TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; }
+ TInstant Now() const { return GetActorContext().Now(); }
+
bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
- return GetActorContext().Send(recipient, ev, flags, cookie, std::move(traceId));
- }
-
- template <typename TEvent>
+ return GetActorContext().Send(recipient, ev, flags, cookie, std::move(traceId));
+ }
+
+ template <typename TEvent>
bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
- return GetActorContext().Send(recipient, ev.Release(), flags, cookie, std::move(traceId));
- }
-
- bool Send(TAutoPtr<IEventHandle> ev);
-
- void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
- return GetActorContext().Schedule(delta, ev, cookie);
- }
-
- void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
- return GetActorContext().Schedule(deadline, ev, cookie);
- }
-
- void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
- return GetActorContext().Schedule(deadline, ev, cookie);
- }
-
+ return GetActorContext().Send(recipient, ev.Release(), flags, cookie, std::move(traceId));
+ }
+
+ bool Send(TAutoPtr<IEventHandle> ev);
+
+ void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
+ return GetActorContext().Schedule(delta, ev, cookie);
+ }
+
+ void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
+ return GetActorContext().Schedule(deadline, ev, cookie);
+ }
+
+ void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) {
+ return GetActorContext().Schedule(deadline, ev, cookie);
+ }
+
TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) {
- return GetActorContext().Register(actor, mailboxType, poolId);
- }
-
+ return GetActorContext().Register(actor, mailboxType, poolId);
+ }
+
TActorId RegisterWithSameMailbox(IActor* actor) {
- return GetActorContext().RegisterWithSameMailbox(actor);
- }
-
- private:
- friend class TActorCoro;
- bool ProcessEvent(THolder<IEventHandle> ev);
-
+ return GetActorContext().RegisterWithSameMailbox(actor);
+ }
+
private:
+ friend class TActorCoro;
+ bool ProcessEvent(THolder<IEventHandle> ev);
+
+ private:
/* Resume() function goes to actor coroutine context and continues (or starts) to execute it until actor finishes
- * his job or it is blocked on WaitForEvent. Then the function returns. */
- void Resume();
+ * his job or it is blocked on WaitForEvent. Then the function returns. */
+ void Resume();
void ReturnToActorSystem();
- void DoRun() override final;
+ void DoRun() override final;
};
-
- class TActorCoro : public IActor {
- THolder<TActorCoroImpl> Impl;
-
- public:
+
+ class TActorCoro : public IActor {
+ THolder<TActorCoroImpl> Impl;
+
+ public:
TActorCoro(THolder<TActorCoroImpl> impl, ui32 activityType = IActor::ACTORLIB_COMMON)
- : IActor(static_cast<TReceiveFunc>(&TActorCoro::StateFunc), activityType)
- , Impl(std::move(impl))
- {}
-
+ : IActor(static_cast<TReceiveFunc>(&TActorCoro::StateFunc), activityType)
+ , Impl(std::move(impl))
+ {}
+
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override {
- return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parent, {}, 0);
- }
-
- private:
- STATEFN(StateFunc) {
- if (Impl->ProcessEvent(ev)) {
- PassAway();
- }
- }
- };
-
+ return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parent, {}, 0);
+ }
+
+ private:
+ STATEFN(StateFunc) {
+ if (Impl->ProcessEvent(ev)) {
+ PassAway();
+ }
+ }
+ };
+
}
diff --git a/library/cpp/actors/core/actor_coroutine_ut.cpp b/library/cpp/actors/core/actor_coroutine_ut.cpp
index 951512b8772..c642dff3349 100644
--- a/library/cpp/actors/core/actor_coroutine_ut.cpp
+++ b/library/cpp/actors/core/actor_coroutine_ut.cpp
@@ -1,141 +1,141 @@
-#include "actor_coroutine.h"
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "scheduler_basic.h"
-#include "events.h"
-#include "event_local.h"
-#include "hfunc.h"
+#include "actor_coroutine.h"
+#include "actorsystem.h"
+#include "executor_pool_basic.h"
+#include "scheduler_basic.h"
+#include "events.h"
+#include "event_local.h"
+#include "hfunc.h"
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/system/sanitizers.h>
-using namespace NActors;
-
+using namespace NActors;
+
Y_UNIT_TEST_SUITE(ActorCoro) {
- enum {
- Begin = EventSpaceBegin(TEvents::ES_USERSPACE),
- Request,
- Response,
- Enough
- };
-
+ enum {
+ Begin = EventSpaceBegin(TEvents::ES_USERSPACE),
+ Request,
+ Response,
+ Enough
+ };
+
struct TEvRequest: public TEventLocal<TEvRequest, Request> {
- };
-
+ };
+
struct TEvResponse: public TEventLocal<TEvResponse, Response> {
- };
-
+ };
+
struct TEvEnough: public TEventLocal<TEvEnough, Enough> {
- };
-
+ };
+
class TBasicResponderActor: public TActorBootstrapped<TBasicResponderActor> {
TDeque<TActorId> RespondTo;
-
- public:
- TBasicResponderActor() {
- }
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- Become(&TBasicResponderActor::StateFunc);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvRequest, Handle);
- HFunc(TEvents::TEvWakeup, Handle);
- HFunc(TEvents::TEvPoisonPill, Handle);
- }
- }
-
- void Handle(TEvRequest::TPtr& ev, const TActorContext& ctx) {
- RespondTo.push_back(ev->Sender);
- ctx.Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
- }
-
- void Handle(TEvents::TEvWakeup::TPtr& /*ev*/, const TActorContext& ctx) {
- ctx.Send(RespondTo.front(), new TEvResponse());
- RespondTo.pop_front();
- }
-
- void Handle(TEvents::TEvPoisonPill::TPtr& /*ev*/, const TActorContext& ctx) {
- Die(ctx);
- }
- };
-
- class TCoroActor: public TActorCoroImpl {
- TManualEvent& DoneEvent;
- TAtomic& ItemsProcessed;
- bool Finish;
-
- public:
- TCoroActor(TManualEvent& doneEvent, TAtomic& itemsProcessed)
- : TActorCoroImpl(1 << 20)
- , DoneEvent(doneEvent)
- , ItemsProcessed(itemsProcessed)
- , Finish(false)
+
+ public:
+ TBasicResponderActor() {
+ }
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ Become(&TBasicResponderActor::StateFunc);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvRequest, Handle);
+ HFunc(TEvents::TEvWakeup, Handle);
+ HFunc(TEvents::TEvPoisonPill, Handle);
+ }
+ }
+
+ void Handle(TEvRequest::TPtr& ev, const TActorContext& ctx) {
+ RespondTo.push_back(ev->Sender);
+ ctx.Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
+ }
+
+ void Handle(TEvents::TEvWakeup::TPtr& /*ev*/, const TActorContext& ctx) {
+ ctx.Send(RespondTo.front(), new TEvResponse());
+ RespondTo.pop_front();
+ }
+
+ void Handle(TEvents::TEvPoisonPill::TPtr& /*ev*/, const TActorContext& ctx) {
+ Die(ctx);
+ }
+ };
+
+ class TCoroActor: public TActorCoroImpl {
+ TManualEvent& DoneEvent;
+ TAtomic& ItemsProcessed;
+ bool Finish;
+
+ public:
+ TCoroActor(TManualEvent& doneEvent, TAtomic& itemsProcessed)
+ : TActorCoroImpl(1 << 20)
+ , DoneEvent(doneEvent)
+ , ItemsProcessed(itemsProcessed)
+ , Finish(false)
{
}
-
- void Run() override {
+
+ void Run() override {
TActorId child = GetActorContext().Register(new TBasicResponderActor);
- ui32 itemsProcessed = 0;
- try {
- while (!Finish) {
- GetActorContext().Send(child, new TEvRequest());
- THolder<IEventHandle> resp = WaitForSpecificEvent<TEvResponse>();
- UNIT_ASSERT_EQUAL(resp->GetTypeRewrite(), TEvResponse::EventType);
- ++itemsProcessed;
- }
- } catch (const TPoisonPillException& /*ex*/) {
- }
- GetActorContext().Send(child, new TEvents::TEvPoisonPill);
-
- AtomicSet(ItemsProcessed, itemsProcessed);
- DoneEvent.Signal();
- }
-
+ ui32 itemsProcessed = 0;
+ try {
+ while (!Finish) {
+ GetActorContext().Send(child, new TEvRequest());
+ THolder<IEventHandle> resp = WaitForSpecificEvent<TEvResponse>();
+ UNIT_ASSERT_EQUAL(resp->GetTypeRewrite(), TEvResponse::EventType);
+ ++itemsProcessed;
+ }
+ } catch (const TPoisonPillException& /*ex*/) {
+ }
+ GetActorContext().Send(child, new TEvents::TEvPoisonPill);
+
+ AtomicSet(ItemsProcessed, itemsProcessed);
+ DoneEvent.Signal();
+ }
+
void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> event) override {
- if (event->GetTypeRewrite() == Enough) {
- Finish = true;
- }
- }
- };
-
+ if (event->GetTypeRewrite() == Enough) {
+ Finish = true;
+ }
+ }
+ };
+
void Check(THolder<IEventBase> && message) {
THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 0;
- setup->ExecutorsCount = 1;
+ setup->NodeId = 0;
+ setup->ExecutorsCount = 1;
setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
- for (ui32 i = 0; i < setup->ExecutorsCount; ++i) {
- setup->Executors[i] = new TBasicExecutorPool(i, 5, 10, "basic");
- }
- setup->Scheduler = new TBasicSchedulerThread;
-
- TActorSystem actorSystem(setup);
-
- actorSystem.Start();
-
- TManualEvent doneEvent;
- TAtomic itemsProcessed = 0;
+ for (ui32 i = 0; i < setup->ExecutorsCount; ++i) {
+ setup->Executors[i] = new TBasicExecutorPool(i, 5, 10, "basic");
+ }
+ setup->Scheduler = new TBasicSchedulerThread;
+
+ TActorSystem actorSystem(setup);
+
+ actorSystem.Start();
+
+ TManualEvent doneEvent;
+ TAtomic itemsProcessed = 0;
TActorId actor = actorSystem.Register(new TActorCoro(MakeHolder<TCoroActor>(doneEvent, itemsProcessed)));
- NanoSleep(3UL * 1000 * 1000 * 1000);
- actorSystem.Send(actor, message.Release());
- doneEvent.WaitI();
-
- UNIT_ASSERT(AtomicGet(itemsProcessed) >= 2);
-
- actorSystem.Stop();
- }
-
+ NanoSleep(3UL * 1000 * 1000 * 1000);
+ actorSystem.Send(actor, message.Release());
+ doneEvent.WaitI();
+
+ UNIT_ASSERT(AtomicGet(itemsProcessed) >= 2);
+
+ actorSystem.Stop();
+ }
+
Y_UNIT_TEST(Basic) {
if (NSan::TSanIsOn()) {
// TODO https://st.yandex-team.ru/DEVTOOLS-3154
return;
}
- Check(MakeHolder<TEvEnough>());
- }
-
+ Check(MakeHolder<TEvEnough>());
+ }
+
Y_UNIT_TEST(PoisonPill) {
- Check(MakeHolder<TEvents::TEvPoisonPill>());
- }
-}
+ Check(MakeHolder<TEvents::TEvPoisonPill>());
+ }
+}
diff --git a/library/cpp/actors/core/actorsystem.cpp b/library/cpp/actors/core/actorsystem.cpp
index c58698a2061..1130e5eacbc 100644
--- a/library/cpp/actors/core/actorsystem.cpp
+++ b/library/cpp/actors/core/actorsystem.cpp
@@ -80,29 +80,29 @@ namespace NActors {
recipient.ToString().c_str());
recipient = InterconnectProxy(recpNodeId);
ev->Rewrite(TEvInterconnect::EvForward, recipient);
- }
- if (recipient.IsService()) {
- TActorId target = ServiceMap->LookupLocal(recipient);
- if (!target && IsInterconnectProxyId(recipient) && ProxyWrapperFactory) {
- const TActorId actorId = ProxyWrapperFactory(const_cast<TActorSystem*>(this),
- GetInterconnectProxyNode(recipient));
- with_lock(ProxyCreationLock) {
- target = ServiceMap->LookupLocal(recipient);
- if (!target) {
- target = actorId;
- ServiceMap->RegisterLocalService(recipient, target);
- }
- }
- if (target != actorId) {
- // a race has occured, terminate newly created actor
- Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
- }
- }
- recipient = target;
- ev->Rewrite(ev->GetTypeRewrite(), recipient);
+ }
+ if (recipient.IsService()) {
+ TActorId target = ServiceMap->LookupLocal(recipient);
+ if (!target && IsInterconnectProxyId(recipient) && ProxyWrapperFactory) {
+ const TActorId actorId = ProxyWrapperFactory(const_cast<TActorSystem*>(this),
+ GetInterconnectProxyNode(recipient));
+ with_lock(ProxyCreationLock) {
+ target = ServiceMap->LookupLocal(recipient);
+ if (!target) {
+ target = actorId;
+ ServiceMap->RegisterLocalService(recipient, target);
+ }
+ }
+ if (target != actorId) {
+ // a race has occured, terminate newly created actor
+ Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
+ }
+ }
+ recipient = target;
+ ev->Rewrite(ev->GetTypeRewrite(), recipient);
}
- Y_VERIFY_DEBUG(recipient == ev->GetRecipientRewrite());
+ Y_VERIFY_DEBUG(recipient == ev->GetRecipientRewrite());
const ui32 recpPool = recipient.PoolID();
if (recipient && recpPool < ExecutorPoolCount) {
if (CpuManager->GetExecutorPool(recpPool)->Send(ev)) {
@@ -153,7 +153,7 @@ namespace NActors {
return promise.GetFuture();
}
- ui64 TActorSystem::AllocateIDSpace(ui64 count) {
+ ui64 TActorSystem::AllocateIDSpace(ui64 count) {
Y_VERIFY_DEBUG(count < Max<ui32>() / 65536);
static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)");
@@ -176,21 +176,21 @@ namespace NActors {
TActorId TActorSystem::InterconnectProxy(ui32 destinationNode) const {
if (destinationNode < InterconnectCount)
return Interconnect[destinationNode];
- else if (destinationNode != NodeId)
- return MakeInterconnectProxyId(destinationNode);
+ else if (destinationNode != NodeId)
+ return MakeInterconnectProxyId(destinationNode);
else
return TActorId();
}
ui32 TActorSystem::BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>& eventFabric) {
- // TODO: get rid of this method
+ // TODO: get rid of this method
for (ui32 i = 0; i < InterconnectCount; ++i) {
Send(eventFabric(Interconnect[i]));
}
return InterconnectCount;
}
- TActorId TActorSystem::LookupLocalService(const TActorId& x) const {
+ TActorId TActorSystem::LookupLocalService(const TActorId& x) const {
return ServiceMap->LookupLocal(x);
}
@@ -225,7 +225,7 @@ namespace NActors {
Y_VERIFY(!!Interconnect[i]);
}
}
- ProxyWrapperFactory = std::move(SystemSetup->Interconnect.ProxyWrapperFactory);
+ ProxyWrapperFactory = std::move(SystemSetup->Interconnect.ProxyWrapperFactory);
}
// setup local services
@@ -254,10 +254,10 @@ namespace NActors {
StopExecuted = true;
- for (auto&& fn : std::exchange(DeferredPreStop, {})) {
- fn();
- }
-
+ for (auto&& fn : std::exchange(DeferredPreStop, {})) {
+ fn();
+ }
+
Scheduler->PrepareStop();
CpuManager->PrepareStop();
Scheduler->Stop();
diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h
index 40499d7586f..2a8cc83ffbc 100644
--- a/library/cpp/actors/core/actorsystem.h
+++ b/library/cpp/actors/core/actorsystem.h
@@ -15,7 +15,7 @@
#include <util/generic/vector.h>
#include <util/datetime/base.h>
-#include <util/system/mutex.h>
+#include <util/system/mutex.h>
namespace NActors {
class TActorSystem;
@@ -23,23 +23,23 @@ namespace NActors {
class IExecutorPool;
struct TWorkerContext;
- inline TActorId MakeInterconnectProxyId(ui32 destNodeId) {
- char data[12];
- memcpy(data, "ICProxy@", 8);
- memcpy(data + 8, &destNodeId, sizeof(ui32));
+ inline TActorId MakeInterconnectProxyId(ui32 destNodeId) {
+ char data[12];
+ memcpy(data, "ICProxy@", 8);
+ memcpy(data + 8, &destNodeId, sizeof(ui32));
return TActorId(0, TStringBuf(data, 12));
- }
-
- inline bool IsInterconnectProxyId(const TActorId& actorId) {
- return actorId.IsService() && !memcmp(actorId.ServiceId().data(), "ICProxy@", 8);
- }
-
- inline ui32 GetInterconnectProxyNode(const TActorId& actorId) {
- ui32 nodeId;
- memcpy(&nodeId, actorId.ServiceId().data() + 8, sizeof(ui32));
- return nodeId;
- }
-
+ }
+
+ inline bool IsInterconnectProxyId(const TActorId& actorId) {
+ return actorId.IsService() && !memcmp(actorId.ServiceId().data(), "ICProxy@", 8);
+ }
+
+ inline ui32 GetInterconnectProxyNode(const TActorId& actorId) {
+ ui32 nodeId;
+ memcpy(&nodeId, actorId.ServiceId().data() + 8, sizeof(ui32));
+ return nodeId;
+ }
+
namespace NSchedulerQueue {
class TReader;
struct TQueueType;
@@ -170,11 +170,11 @@ namespace NActors {
}
};
- using TProxyWrapperFactory = std::function<TActorId(TActorSystem*, ui32)>;
-
+ using TProxyWrapperFactory = std::function<TActorId(TActorSystem*, ui32)>;
+
struct TInterconnectSetup {
TVector<TActorSetupCmd> ProxyActors;
- TProxyWrapperFactory ProxyWrapperFactory;
+ TProxyWrapperFactory ProxyWrapperFactory;
};
struct TActorSystemSetup {
@@ -238,14 +238,14 @@ namespace NActors {
TActorId DefSelfID;
void* AppData0;
TIntrusivePtr<NLog::TSettings> LoggerSettings0;
- TProxyWrapperFactory ProxyWrapperFactory;
- TMutex ProxyCreationLock;
+ TProxyWrapperFactory ProxyWrapperFactory;
+ TMutex ProxyCreationLock;
bool StartExecuted;
bool StopExecuted;
bool CleanupExecuted;
-
- std::deque<std::function<void()>> DeferredPreStop;
+
+ std::deque<std::function<void()>> DeferredPreStop;
public:
TActorSystem(THolder<TActorSystemSetup>& setup, void* appData = nullptr,
TIntrusivePtr<NLog::TSettings> loggerSettings = TIntrusivePtr<NLog::TSettings>(nullptr));
@@ -329,7 +329,7 @@ namespace NActors {
void UpdateLinkStatus(ui8 status, ui32 destinationNode);
ui8 LinkStatus(ui32 destinationNode);
- TActorId LookupLocalService(const TActorId& x) const;
+ TActorId LookupLocalService(const TActorId& x) const;
TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId);
ui32 GetMaxActivityType() const {
@@ -355,10 +355,10 @@ namespace NActors {
void GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const;
- void DeferPreStop(std::function<void()> fn) {
- DeferredPreStop.push_back(std::move(fn));
- }
-
+ void DeferPreStop(std::function<void()> fn) {
+ DeferredPreStop.push_back(std::move(fn));
+ }
+
/* This is the base for memory profiling tags.
System sets memory profiling tag for debug version of lfalloc.
The tag is set as "base_tag + actor_activity_type". */
diff --git a/library/cpp/actors/core/defs.h b/library/cpp/actors/core/defs.h
index 980b7d767bc..d65100e1f50 100644
--- a/library/cpp/actors/core/defs.h
+++ b/library/cpp/actors/core/defs.h
@@ -3,8 +3,8 @@
// unique tag to fix pragma once gcc glueing: ./library/actorlib/core/defs.h
#include <library/cpp/actors/util/defs.h>
-#include <util/generic/hash.h>
-#include <util/string/printf.h>
+#include <util/generic/hash.h>
+#include <util/string/printf.h>
// Enables collection of
// event send/receive counts
@@ -18,7 +18,7 @@ namespace NActors {
static constexpr TPoolId PoolBits = 6;
static constexpr TPoolId MaxPools = (1 << PoolBits) - 1; // maximum amount of pools (poolid=63 is reserved)
static constexpr TPoolsMask WaitPoolsFlag = (1ull << MaxPools); // wait-for-slow-workers flag bitmask
-
+
// Special TPoolId values used by TCpuState
static constexpr TPoolId CpuSpinning = MaxPools; // fast-worker is actively spinning, no slow-workers
static constexpr TPoolId CpuBlocked = MaxPools + 1; // fast-worker is blocked, no slow-workers
@@ -50,20 +50,20 @@ namespace NActors {
//Virtual
};
};
-
- struct TScopeId : std::pair<ui64, ui64> {
- using TBase = std::pair<ui64, ui64>;
- using TBase::TBase;
- static const TScopeId LocallyGenerated;
- };
-
- static inline TString ScopeIdToString(const TScopeId& scopeId) {
- return Sprintf("<%" PRIu64 ":%" PRIu64 ">", scopeId.first, scopeId.second);
- }
-
+
+ struct TScopeId : std::pair<ui64, ui64> {
+ using TBase = std::pair<ui64, ui64>;
+ using TBase::TBase;
+ static const TScopeId LocallyGenerated;
+ };
+
+ static inline TString ScopeIdToString(const TScopeId& scopeId) {
+ return Sprintf("<%" PRIu64 ":%" PRIu64 ">", scopeId.first, scopeId.second);
+ }
+
}
-template<>
-struct hash<NActors::TScopeId> : hash<std::pair<ui64, ui64>> {};
-
+template<>
+struct hash<NActors::TScopeId> : hash<std::pair<ui64, ui64>> {};
+
class TAffinity;
diff --git a/library/cpp/actors/core/event.cpp b/library/cpp/actors/core/event.cpp
index 33f8ce2aaf3..2ab190344e6 100644
--- a/library/cpp/actors/core/event.cpp
+++ b/library/cpp/actors/core/event.cpp
@@ -2,11 +2,11 @@
#include "event_pb.h"
namespace NActors {
-
- const TScopeId TScopeId::LocallyGenerated{
- Max<ui64>(), Max<ui64>()
- };
-
+
+ const TScopeId TScopeId::LocallyGenerated{
+ Max<ui64>(), Max<ui64>()
+ };
+
TIntrusivePtr<TEventSerializedData> IEventHandle::ReleaseChainBuffer() {
if (Buffer) {
TIntrusivePtr<TEventSerializedData> result;
@@ -17,7 +17,7 @@ namespace NActors {
if (Event) {
TAllocChunkSerializer serializer;
Event->SerializeToArcadiaStream(&serializer);
- auto chainBuf = serializer.Release(Event->IsExtendedFormat());
+ auto chainBuf = serializer.Release(Event->IsExtendedFormat());
Event.Reset();
return chainBuf;
}
@@ -30,7 +30,7 @@ namespace NActors {
if (Event) {
TAllocChunkSerializer serializer;
Event->SerializeToArcadiaStream(&serializer);
- Buffer = serializer.Release(Event->IsExtendedFormat());
+ Buffer = serializer.Release(Event->IsExtendedFormat());
return Buffer;
}
return new TEventSerializedData;
diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h
index 6ff02aaf943..68440de225e 100644
--- a/library/cpp/actors/core/event.h
+++ b/library/cpp/actors/core/event.h
@@ -6,9 +6,9 @@
#include "event_load.h"
#include <library/cpp/actors/wilson/wilson_trace.h>
-
+
#include <util/system/hp_timer.h>
-#include <util/generic/maybe.h>
+#include <util/generic/maybe.h>
namespace NActors {
class TChunkSerializer;
@@ -36,13 +36,13 @@ namespace NActors {
}
virtual ui32 Type() const = 0;
virtual bool SerializeToArcadiaStream(TChunkSerializer*) const = 0;
- virtual bool IsSerializable() const = 0;
- virtual bool IsExtendedFormat() const {
- return false;
- }
- virtual ui32 CalculateSerializedSizeCached() const {
- return CalculateSerializedSize();
- }
+ virtual bool IsSerializable() const = 0;
+ virtual bool IsExtendedFormat() const {
+ return false;
+ }
+ virtual ui32 CalculateSerializedSizeCached() const {
+ return CalculateSerializedSize();
+ }
};
// fat handle
@@ -70,12 +70,12 @@ namespace NActors {
Y_FAIL("Event type %" PRIu32 " doesn't match the expected type %" PRIu32, Type, TEventType::EventType);
if (!Event) {
- Event.Reset(TEventType::Load(Buffer.Get()));
+ Event.Reset(TEventType::Load(Buffer.Get()));
}
- if (Event) {
+ if (Event) {
return static_cast<TEventType*>(Event.Get());
- }
+ }
Y_FAIL("Failed to Load() event type %" PRIu32 " class %s", Type, TypeName<TEventType>().data());
}
@@ -93,8 +93,8 @@ namespace NActors {
FlagForwardOnNondelivery = 1 << 1,
FlagSubscribeOnSession = 1 << 2,
FlagUseSubChannel = 1 << 3,
- FlagGenerateUnsureUndelivered = 1 << 4,
- FlagExtendedFormat = 1 << 5,
+ FlagGenerateUnsureUndelivered = 1 << 4,
+ FlagExtendedFormat = 1 << 5,
};
const ui32 Type;
@@ -102,11 +102,11 @@ namespace NActors {
const TActorId Recipient;
const TActorId Sender;
const ui64 Cookie;
- const TScopeId OriginScopeId = TScopeId::LocallyGenerated; // filled in when the message is received from Interconnect
+ const TScopeId OriginScopeId = TScopeId::LocallyGenerated; // filled in when the message is received from Interconnect
// if set, used by ActorSystem/Interconnect to report tracepoints
NWilson::TTraceId TraceId;
-
+
// filled if feeded by interconnect session
const TActorId InterconnectSession;
@@ -142,7 +142,7 @@ namespace NActors {
ui32 RewriteType;
THolder<TOnNondelivery> OnNondeliveryHolder; // only for local events
-
+
public:
void Rewrite(ui32 typeRewrite, TActorId recipientRewrite) {
RewriteRecipient = recipientRewrite;
@@ -218,14 +218,14 @@ namespace NActors {
const TActorId& sender,
TIntrusivePtr<TEventSerializedData> buffer,
ui64 cookie,
- TScopeId originScopeId,
- NWilson::TTraceId traceId) noexcept
+ TScopeId originScopeId,
+ NWilson::TTraceId traceId) noexcept
: Type(type)
, Flags(flags)
, Recipient(recipient)
, Sender(sender)
, Cookie(cookie)
- , OriginScopeId(originScopeId)
+ , OriginScopeId(originScopeId)
, TraceId(std::move(traceId))
, InterconnectSession(session)
#ifdef ACTORSLIB_COLLECT_EXEC_STATS
@@ -237,16 +237,16 @@ namespace NActors {
{
}
- TIntrusivePtr<TEventSerializedData> GetChainBuffer();
- TIntrusivePtr<TEventSerializedData> ReleaseChainBuffer();
+ TIntrusivePtr<TEventSerializedData> GetChainBuffer();
+ TIntrusivePtr<TEventSerializedData> ReleaseChainBuffer();
- ui32 GetSize() const {
+ ui32 GetSize() const {
if (Buffer) {
- return Buffer->GetSize();
- } else if (Event) {
- return Event->CalculateSerializedSize();
- } else {
- return 0;
+ return Buffer->GetSize();
+ } else if (Event) {
+ return Event->CalculateSerializedSize();
+ } else {
+ return 0;
}
}
@@ -283,7 +283,7 @@ namespace NActors {
return new IEventHandle(Type, Flags, dest, Sender, Buffer, Cookie, nullptr, std::move(TraceId));
}
- TAutoPtr<IEventHandle> ForwardOnNondelivery(ui32 reason, bool unsure = false);
+ TAutoPtr<IEventHandle> ForwardOnNondelivery(ui32 reason, bool unsure = false);
};
template <typename TEventType>
@@ -314,31 +314,31 @@ namespace NActors {
typedef TAutoPtr<THandle> TPtr;
};
-#define DEFINE_SIMPLE_LOCAL_EVENT(eventType, header) \
- TString ToStringHeader() const override { \
- return TString(header); \
- } \
+#define DEFINE_SIMPLE_LOCAL_EVENT(eventType, header) \
+ TString ToStringHeader() const override { \
+ return TString(header); \
+ } \
bool SerializeToArcadiaStream(NActors::TChunkSerializer*) const override { \
- Y_FAIL("Local event " #eventType " is not serializable"); \
- } \
- static IEventBase* Load(NActors::TEventSerializedData*) { \
- Y_FAIL("Local event " #eventType " has no load method"); \
- } \
- bool IsSerializable() const override { \
- return false; \
+ Y_FAIL("Local event " #eventType " is not serializable"); \
+ } \
+ static IEventBase* Load(NActors::TEventSerializedData*) { \
+ Y_FAIL("Local event " #eventType " has no load method"); \
+ } \
+ bool IsSerializable() const override { \
+ return false; \
}
-#define DEFINE_SIMPLE_NONLOCAL_EVENT(eventType, header) \
- TString ToStringHeader() const override { \
- return TString(header); \
- } \
+#define DEFINE_SIMPLE_NONLOCAL_EVENT(eventType, header) \
+ TString ToStringHeader() const override { \
+ return TString(header); \
+ } \
bool SerializeToArcadiaStream(NActors::TChunkSerializer*) const override { \
- return true; \
- } \
- static IEventBase* Load(NActors::TEventSerializedData*) { \
- return new eventType(); \
- } \
- bool IsSerializable() const override { \
- return true; \
+ return true; \
+ } \
+ static IEventBase* Load(NActors::TEventSerializedData*) { \
+ return new eventType(); \
+ } \
+ bool IsSerializable() const override { \
+ return true; \
}
}
diff --git a/library/cpp/actors/core/event_load.h b/library/cpp/actors/core/event_load.h
index 0dab1dd374c..267345f0c92 100644
--- a/library/cpp/actors/core/event_load.h
+++ b/library/cpp/actors/core/event_load.h
@@ -1,6 +1,6 @@
#pragma once
-#include <util/stream/walk.h>
+#include <util/stream/walk.h>
#include <util/system/types.h>
#include <util/generic/string.h>
#include <library/cpp/actors/util/rope.h>
@@ -19,94 +19,94 @@ namespace NActors {
size_t Size;
};
- class TEventSerializedData
- : public TThrRefBase
- {
- TRope Rope;
- bool ExtendedFormat = false;
-
- public:
- TEventSerializedData() = default;
-
- TEventSerializedData(TRope&& rope, bool extendedFormat)
- : Rope(std::move(rope))
- , ExtendedFormat(extendedFormat)
- {}
-
- TEventSerializedData(const TEventSerializedData& original, TString extraBuffer)
- : Rope(original.Rope)
- , ExtendedFormat(original.ExtendedFormat)
- {
- Append(std::move(extraBuffer));
- }
-
- TEventSerializedData(TString buffer, bool extendedFormat)
- : ExtendedFormat(extendedFormat)
+ class TEventSerializedData
+ : public TThrRefBase
+ {
+ TRope Rope;
+ bool ExtendedFormat = false;
+
+ public:
+ TEventSerializedData() = default;
+
+ TEventSerializedData(TRope&& rope, bool extendedFormat)
+ : Rope(std::move(rope))
+ , ExtendedFormat(extendedFormat)
+ {}
+
+ TEventSerializedData(const TEventSerializedData& original, TString extraBuffer)
+ : Rope(original.Rope)
+ , ExtendedFormat(original.ExtendedFormat)
{
- Append(std::move(buffer));
- }
-
- void SetExtendedFormat() {
- ExtendedFormat = true;
- }
-
- bool IsExtendedFormat() const {
- return ExtendedFormat;
- }
-
- TRope::TConstIterator GetBeginIter() const {
- return Rope.Begin();
- }
-
- size_t GetSize() const {
- return Rope.GetSize();
+ Append(std::move(extraBuffer));
}
-
- TString GetString() const {
- TString result;
- result.reserve(GetSize());
- for (auto it = Rope.Begin(); it.Valid(); it.AdvanceToNextContiguousBlock()) {
- result.append(it.ContiguousData(), it.ContiguousSize());
- }
- return result;
- }
-
- TRope EraseBack(size_t count) {
- Y_VERIFY(count <= Rope.GetSize());
- TRope::TIterator iter = Rope.End();
- iter -= count;
- return Rope.Extract(iter, Rope.End());
+
+ TEventSerializedData(TString buffer, bool extendedFormat)
+ : ExtendedFormat(extendedFormat)
+ {
+ Append(std::move(buffer));
+ }
+
+ void SetExtendedFormat() {
+ ExtendedFormat = true;
+ }
+
+ bool IsExtendedFormat() const {
+ return ExtendedFormat;
+ }
+
+ TRope::TConstIterator GetBeginIter() const {
+ return Rope.Begin();
+ }
+
+ size_t GetSize() const {
+ return Rope.GetSize();
+ }
+
+ TString GetString() const {
+ TString result;
+ result.reserve(GetSize());
+ for (auto it = Rope.Begin(); it.Valid(); it.AdvanceToNextContiguousBlock()) {
+ result.append(it.ContiguousData(), it.ContiguousSize());
+ }
+ return result;
+ }
+
+ TRope EraseBack(size_t count) {
+ Y_VERIFY(count <= Rope.GetSize());
+ TRope::TIterator iter = Rope.End();
+ iter -= count;
+ return Rope.Extract(iter, Rope.End());
+ }
+
+ void Append(TRope&& from) {
+ Rope.Insert(Rope.End(), std::move(from));
}
- void Append(TRope&& from) {
- Rope.Insert(Rope.End(), std::move(from));
- }
-
- void Append(TString buffer) {
- if (buffer) {
- Rope.Insert(Rope.End(), TRope(std::move(buffer)));
- }
+ void Append(TString buffer) {
+ if (buffer) {
+ Rope.Insert(Rope.End(), TRope(std::move(buffer)));
+ }
}
};
}
-class TChainBufWalk : public IWalkInput {
- TIntrusivePtr<NActors::TEventSerializedData> Buffer;
- TRope::TConstIterator Iter;
-
-public:
- TChainBufWalk(TIntrusivePtr<NActors::TEventSerializedData> buffer)
- : Buffer(std::move(buffer))
- , Iter(Buffer->GetBeginIter())
- {}
-
-private:
- size_t DoUnboundedNext(const void **ptr) override {
- const size_t size = Iter.ContiguousSize();
- *ptr = Iter.ContiguousData();
- if (Iter.Valid()) {
- Iter.AdvanceToNextContiguousBlock();
- }
- return size;
+class TChainBufWalk : public IWalkInput {
+ TIntrusivePtr<NActors::TEventSerializedData> Buffer;
+ TRope::TConstIterator Iter;
+
+public:
+ TChainBufWalk(TIntrusivePtr<NActors::TEventSerializedData> buffer)
+ : Buffer(std::move(buffer))
+ , Iter(Buffer->GetBeginIter())
+ {}
+
+private:
+ size_t DoUnboundedNext(const void **ptr) override {
+ const size_t size = Iter.ContiguousSize();
+ *ptr = Iter.ContiguousData();
+ if (Iter.Valid()) {
+ Iter.AdvanceToNextContiguousBlock();
+ }
+ return size;
}
-};
+};
diff --git a/library/cpp/actors/core/event_local.h b/library/cpp/actors/core/event_local.h
index 2845aa94dd9..3d490161852 100644
--- a/library/cpp/actors/core/event_local.h
+++ b/library/cpp/actors/core/event_local.h
@@ -18,9 +18,9 @@ namespace NActors {
}
bool IsSerializable() const override {
- return false;
- }
-
+ return false;
+ }
+
static IEventBase* Load(TEventSerializedData*) {
Y_FAIL("Loading of local event %s type %" PRIu32, TypeName<TEv>().data(), TEventType);
}
@@ -55,14 +55,14 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer* /*serializer*/) const override {
- static_assert(sizeof(TEv) == sizeof(TEventSimple<TEv, TEventType>), "Descendant should be an empty class");
- return true;
- }
-
- bool IsSerializable() const override {
- return true;
+ static_assert(sizeof(TEv) == sizeof(TEventSimple<TEv, TEventType>), "Descendant should be an empty class");
+ return true;
}
+ bool IsSerializable() const override {
+ return true;
+ }
+
static IEventBase* Load(NActors::TEventSerializedData*) {
return new TEv();
}
diff --git a/library/cpp/actors/core/event_pb.cpp b/library/cpp/actors/core/event_pb.cpp
index 018ff9ac34e..ae231649b27 100644
--- a/library/cpp/actors/core/event_pb.cpp
+++ b/library/cpp/actors/core/event_pb.cpp
@@ -1,126 +1,126 @@
#include "event_pb.h"
namespace NActors {
- bool TRopeStream::Next(const void** data, int* size) {
- *data = Iter.ContiguousData();
- *size = Iter.ContiguousSize();
- if (size_t(*size + TotalByteCount) > Size) {
- *size = Size - TotalByteCount;
- Iter += *size;
- } else if (Iter.Valid()) {
- Iter.AdvanceToNextContiguousBlock();
+ bool TRopeStream::Next(const void** data, int* size) {
+ *data = Iter.ContiguousData();
+ *size = Iter.ContiguousSize();
+ if (size_t(*size + TotalByteCount) > Size) {
+ *size = Size - TotalByteCount;
+ Iter += *size;
+ } else if (Iter.Valid()) {
+ Iter.AdvanceToNextContiguousBlock();
}
- TotalByteCount += *size;
- return *size != 0;
+ TotalByteCount += *size;
+ return *size != 0;
}
- void TRopeStream::BackUp(int count) {
- Y_VERIFY(count <= TotalByteCount);
- Iter -= count;
- TotalByteCount -= count;
+ void TRopeStream::BackUp(int count) {
+ Y_VERIFY(count <= TotalByteCount);
+ Iter -= count;
+ TotalByteCount -= count;
}
- bool TRopeStream::Skip(int count) {
- if (static_cast<size_t>(TotalByteCount + count) > Size) {
- count = Size - TotalByteCount;
+ bool TRopeStream::Skip(int count) {
+ if (static_cast<size_t>(TotalByteCount + count) > Size) {
+ count = Size - TotalByteCount;
}
- Iter += count;
- TotalByteCount += count;
- return static_cast<size_t>(TotalByteCount) != Size;
+ Iter += count;
+ TotalByteCount += count;
+ return static_cast<size_t>(TotalByteCount) != Size;
}
TCoroutineChunkSerializer::TCoroutineChunkSerializer()
: TotalSerializedDataSize(0)
- , Stack(64 * 1024)
- , SelfClosure{this, TArrayRef(Stack.Begin(), Stack.End())}
+ , Stack(64 * 1024)
+ , SelfClosure{this, TArrayRef(Stack.Begin(), Stack.End())}
, InnerContext(SelfClosure)
- {}
+ {}
TCoroutineChunkSerializer::~TCoroutineChunkSerializer() {
CancelFlag = true;
- Resume();
- Y_VERIFY(Finished);
+ Resume();
+ Y_VERIFY(Finished);
}
bool TCoroutineChunkSerializer::AllowsAliasing() const {
return true;
}
- bool TCoroutineChunkSerializer::Produce(const void *data, size_t size) {
- Y_VERIFY(size <= SizeRemain);
- SizeRemain -= size;
- TotalSerializedDataSize += size;
-
- if (NumChunks) {
- auto& last = Chunks[NumChunks - 1];
- if (last.first + last.second == data) {
- last.second += size; // just extend the last buffer
- return true;
- }
- }
-
- if (NumChunks == MaxChunks) {
- InnerContext.SwitchTo(BufFeedContext);
- if (CancelFlag || AbortFlag) {
- return false;
- }
- }
-
- Y_VERIFY(NumChunks < MaxChunks);
- Chunks[NumChunks++] = {static_cast<const char*>(data), size};
- return true;
- }
-
+ bool TCoroutineChunkSerializer::Produce(const void *data, size_t size) {
+ Y_VERIFY(size <= SizeRemain);
+ SizeRemain -= size;
+ TotalSerializedDataSize += size;
+
+ if (NumChunks) {
+ auto& last = Chunks[NumChunks - 1];
+ if (last.first + last.second == data) {
+ last.second += size; // just extend the last buffer
+ return true;
+ }
+ }
+
+ if (NumChunks == MaxChunks) {
+ InnerContext.SwitchTo(BufFeedContext);
+ if (CancelFlag || AbortFlag) {
+ return false;
+ }
+ }
+
+ Y_VERIFY(NumChunks < MaxChunks);
+ Chunks[NumChunks++] = {static_cast<const char*>(data), size};
+ return true;
+ }
+
bool TCoroutineChunkSerializer::WriteAliasedRaw(const void* data, int size) {
Y_VERIFY(size >= 0);
- while (size) {
- if (CancelFlag || AbortFlag) {
+ while (size) {
+ if (CancelFlag || AbortFlag) {
return false;
- } else if (const size_t bytesToAppend = Min<size_t>(size, SizeRemain)) {
- if (!Produce(data, bytesToAppend)) {
- return false;
- }
- data = static_cast<const char*>(data) + bytesToAppend;
- size -= bytesToAppend;
- } else {
- InnerContext.SwitchTo(BufFeedContext);
- }
+ } else if (const size_t bytesToAppend = Min<size_t>(size, SizeRemain)) {
+ if (!Produce(data, bytesToAppend)) {
+ return false;
+ }
+ data = static_cast<const char*>(data) + bytesToAppend;
+ size -= bytesToAppend;
+ } else {
+ InnerContext.SwitchTo(BufFeedContext);
+ }
}
return true;
}
bool TCoroutineChunkSerializer::Next(void** data, int* size) {
- if (CancelFlag || AbortFlag) {
+ if (CancelFlag || AbortFlag) {
return false;
- }
- if (!SizeRemain) {
+ }
+ if (!SizeRemain) {
InnerContext.SwitchTo(BufFeedContext);
- if (CancelFlag || AbortFlag) {
+ if (CancelFlag || AbortFlag) {
return false;
- }
+ }
}
- Y_VERIFY(SizeRemain);
- *data = BufferPtr;
- *size = SizeRemain;
- BufferPtr += SizeRemain;
- return Produce(*data, *size);
+ Y_VERIFY(SizeRemain);
+ *data = BufferPtr;
+ *size = SizeRemain;
+ BufferPtr += SizeRemain;
+ return Produce(*data, *size);
}
void TCoroutineChunkSerializer::BackUp(int count) {
- if (!count) {
+ if (!count) {
return;
- }
- Y_VERIFY(count > 0);
- Y_VERIFY(NumChunks);
- TChunk& buf = Chunks[NumChunks - 1];
- Y_VERIFY((size_t)count <= buf.second);
- Y_VERIFY(buf.first + buf.second == BufferPtr);
- buf.second -= count;
- if (!buf.second) {
- --NumChunks;
- }
- BufferPtr -= count;
- SizeRemain += count;
+ }
+ Y_VERIFY(count > 0);
+ Y_VERIFY(NumChunks);
+ TChunk& buf = Chunks[NumChunks - 1];
+ Y_VERIFY((size_t)count <= buf.second);
+ Y_VERIFY(buf.first + buf.second == BufferPtr);
+ buf.second -= count;
+ if (!buf.second) {
+ --NumChunks;
+ }
+ BufferPtr -= count;
+ SizeRemain += count;
TotalSerializedDataSize -= count;
}
@@ -128,96 +128,96 @@ namespace NActors {
TContMachineContext feedContext;
BufFeedContext = &feedContext;
feedContext.SwitchTo(&InnerContext);
- BufFeedContext = nullptr;
- }
-
- bool TCoroutineChunkSerializer::WriteRope(const TRope *rope) {
- for (auto iter = rope->Begin(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
- if (!WriteAliasedRaw(iter.ContiguousData(), iter.ContiguousSize())) {
- return false;
- }
- }
- return true;
- }
-
- bool TCoroutineChunkSerializer::WriteString(const TString *s) {
- return WriteAliasedRaw(s->data(), s->length());
- }
-
- std::pair<TCoroutineChunkSerializer::TChunk*, TCoroutineChunkSerializer::TChunk*> TCoroutineChunkSerializer::FeedBuf(void* data, size_t size) {
- // fill in base params
- BufferPtr = static_cast<char*>(data);
- SizeRemain = size;
-
- // transfer control to the coroutine
- Y_VERIFY(Event);
- NumChunks = 0;
- Resume();
-
- return {Chunks, Chunks + NumChunks};
- }
-
- void TCoroutineChunkSerializer::SetSerializingEvent(const IEventBase *event) {
- Y_VERIFY(Event == nullptr);
- Event = event;
+ BufFeedContext = nullptr;
+ }
+
+ bool TCoroutineChunkSerializer::WriteRope(const TRope *rope) {
+ for (auto iter = rope->Begin(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
+ if (!WriteAliasedRaw(iter.ContiguousData(), iter.ContiguousSize())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool TCoroutineChunkSerializer::WriteString(const TString *s) {
+ return WriteAliasedRaw(s->data(), s->length());
+ }
+
+ std::pair<TCoroutineChunkSerializer::TChunk*, TCoroutineChunkSerializer::TChunk*> TCoroutineChunkSerializer::FeedBuf(void* data, size_t size) {
+ // fill in base params
+ BufferPtr = static_cast<char*>(data);
+ SizeRemain = size;
+
+ // transfer control to the coroutine
+ Y_VERIFY(Event);
+ NumChunks = 0;
+ Resume();
+
+ return {Chunks, Chunks + NumChunks};
+ }
+
+ void TCoroutineChunkSerializer::SetSerializingEvent(const IEventBase *event) {
+ Y_VERIFY(Event == nullptr);
+ Event = event;
TotalSerializedDataSize = 0;
- AbortFlag = false;
- }
-
- void TCoroutineChunkSerializer::Abort() {
- Y_VERIFY(Event);
- AbortFlag = true;
- Resume();
+ AbortFlag = false;
}
+ void TCoroutineChunkSerializer::Abort() {
+ Y_VERIFY(Event);
+ AbortFlag = true;
+ Resume();
+ }
+
void TCoroutineChunkSerializer::DoRun() {
- while (!CancelFlag) {
- Y_VERIFY(Event);
+ while (!CancelFlag) {
+ Y_VERIFY(Event);
SerializationSuccess = Event->SerializeToArcadiaStream(this);
- Event = nullptr;
- if (!CancelFlag) { // cancel flag may have been received during serialization
- InnerContext.SwitchTo(BufFeedContext);
- }
+ Event = nullptr;
+ if (!CancelFlag) { // cancel flag may have been received during serialization
+ InnerContext.SwitchTo(BufFeedContext);
+ }
}
- Finished = true;
- InnerContext.SwitchTo(BufFeedContext);
+ Finished = true;
+ InnerContext.SwitchTo(BufFeedContext);
}
bool TAllocChunkSerializer::Next(void** pdata, int* psize) {
- if (Backup) {
- // we have some data in backup rope -- move the first chunk from the backup rope to the buffer and return
- // pointer to the buffer; it is safe to remove 'const' here as we uniquely own this buffer
- TRope::TIterator iter = Backup.Begin();
- *pdata = const_cast<char*>(iter.ContiguousData());
- *psize = iter.ContiguousSize();
- iter.AdvanceToNextContiguousBlock();
- Buffers->Append(Backup.Extract(Backup.Begin(), iter));
- } else {
- // no backup buffer, so we have to create new one
- auto item = TRopeAlignedBuffer::Allocate(4096);
- *pdata = item->GetBuffer();
- *psize = item->GetCapacity();
- Buffers->Append(TRope(std::move(item)));
- }
+ if (Backup) {
+ // we have some data in backup rope -- move the first chunk from the backup rope to the buffer and return
+ // pointer to the buffer; it is safe to remove 'const' here as we uniquely own this buffer
+ TRope::TIterator iter = Backup.Begin();
+ *pdata = const_cast<char*>(iter.ContiguousData());
+ *psize = iter.ContiguousSize();
+ iter.AdvanceToNextContiguousBlock();
+ Buffers->Append(Backup.Extract(Backup.Begin(), iter));
+ } else {
+ // no backup buffer, so we have to create new one
+ auto item = TRopeAlignedBuffer::Allocate(4096);
+ *pdata = item->GetBuffer();
+ *psize = item->GetCapacity();
+ Buffers->Append(TRope(std::move(item)));
+ }
return true;
}
void TAllocChunkSerializer::BackUp(int count) {
- Backup.Insert(Backup.Begin(), Buffers->EraseBack(count));
+ Backup.Insert(Backup.Begin(), Buffers->EraseBack(count));
}
bool TAllocChunkSerializer::WriteAliasedRaw(const void*, int) {
Y_VERIFY(false);
return false;
}
-
- bool TAllocChunkSerializer::WriteRope(const TRope *rope) {
- Buffers->Append(TRope(*rope));
- return true;
- }
-
- bool TAllocChunkSerializer::WriteString(const TString *s) {
- Buffers->Append(*s);
- return true;
- }
+
+ bool TAllocChunkSerializer::WriteRope(const TRope *rope) {
+ Buffers->Append(TRope(*rope));
+ return true;
+ }
+
+ bool TAllocChunkSerializer::WriteString(const TString *s) {
+ Buffers->Append(*s);
+ return true;
+ }
}
diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h
index d7546b901a0..f88519e1083 100644
--- a/library/cpp/actors/core/event_pb.h
+++ b/library/cpp/actors/core/event_pb.h
@@ -12,81 +12,81 @@
#include <array>
namespace NActors {
-
- class TRopeStream : public NProtoBuf::io::ZeroCopyInputStream {
- TRope::TConstIterator Iter;
- const size_t Size;
-
+
+ class TRopeStream : public NProtoBuf::io::ZeroCopyInputStream {
+ TRope::TConstIterator Iter;
+ const size_t Size;
+
public:
- TRopeStream(TRope::TConstIterator iter, size_t size)
- : Iter(iter)
- , Size(size)
- {}
-
- bool Next(const void** data, int* size) override;
- void BackUp(int count) override;
- bool Skip(int count) override;
+ TRopeStream(TRope::TConstIterator iter, size_t size)
+ : Iter(iter)
+ , Size(size)
+ {}
+
+ bool Next(const void** data, int* size) override;
+ void BackUp(int count) override;
+ bool Skip(int count) override;
int64_t ByteCount() const override {
return TotalByteCount;
}
- private:
+ private:
int64_t TotalByteCount = 0;
};
- class TChunkSerializer : public NProtoBuf::io::ZeroCopyOutputStream {
+ class TChunkSerializer : public NProtoBuf::io::ZeroCopyOutputStream {
public:
- TChunkSerializer() = default;
- virtual ~TChunkSerializer() = default;
-
- virtual bool WriteRope(const TRope *rope) = 0;
- virtual bool WriteString(const TString *s) = 0;
+ TChunkSerializer() = default;
+ virtual ~TChunkSerializer() = default;
+
+ virtual bool WriteRope(const TRope *rope) = 0;
+ virtual bool WriteString(const TString *s) = 0;
};
- class TAllocChunkSerializer final : public TChunkSerializer {
+ class TAllocChunkSerializer final : public TChunkSerializer {
public:
- bool Next(void** data, int* size) override;
- void BackUp(int count) override;
+ bool Next(void** data, int* size) override;
+ void BackUp(int count) override;
int64_t ByteCount() const override {
return Buffers->GetSize();
}
- bool WriteAliasedRaw(const void* data, int size) override;
+ bool WriteAliasedRaw(const void* data, int size) override;
- // WARNING: these methods require owner to retain ownership and immutability of passed objects
- bool WriteRope(const TRope *rope) override;
- bool WriteString(const TString *s) override;
-
- inline TIntrusivePtr<TEventSerializedData> Release(bool extendedFormat) {
- if (extendedFormat) {
- Buffers->SetExtendedFormat();
- }
- return std::move(Buffers);
+ // WARNING: these methods require owner to retain ownership and immutability of passed objects
+ bool WriteRope(const TRope *rope) override;
+ bool WriteString(const TString *s) override;
+
+ inline TIntrusivePtr<TEventSerializedData> Release(bool extendedFormat) {
+ if (extendedFormat) {
+ Buffers->SetExtendedFormat();
+ }
+ return std::move(Buffers);
}
protected:
- TIntrusivePtr<TEventSerializedData> Buffers = new TEventSerializedData;
- TRope Backup;
+ TIntrusivePtr<TEventSerializedData> Buffers = new TEventSerializedData;
+ TRope Backup;
};
- class TCoroutineChunkSerializer final : public TChunkSerializer, protected ITrampoLine {
+ class TCoroutineChunkSerializer final : public TChunkSerializer, protected ITrampoLine {
public:
- using TChunk = std::pair<const char*, size_t>;
-
+ using TChunk = std::pair<const char*, size_t>;
+
TCoroutineChunkSerializer();
~TCoroutineChunkSerializer();
- void SetSerializingEvent(const IEventBase *event);
- void Abort();
- std::pair<TChunk*, TChunk*> FeedBuf(void* data, size_t size);
+ void SetSerializingEvent(const IEventBase *event);
+ void Abort();
+ std::pair<TChunk*, TChunk*> FeedBuf(void* data, size_t size);
bool IsComplete() const {
- return !Event;
+ return !Event;
}
bool IsSuccessfull() const {
return SerializationSuccess;
}
- const IEventBase *GetCurrentEvent() const {
- return Event;
- }
+ const IEventBase *GetCurrentEvent() const {
+ return Event;
+ }
bool Next(void** data, int* size) override;
void BackUp(int count) override;
@@ -96,42 +96,42 @@ namespace NActors {
bool WriteAliasedRaw(const void* data, int size) override;
bool AllowsAliasing() const override;
- bool WriteRope(const TRope *rope) override;
- bool WriteString(const TString *s) override;
-
+ bool WriteRope(const TRope *rope) override;
+ bool WriteString(const TString *s) override;
+
protected:
void DoRun() override;
void Resume();
- bool Produce(const void *data, size_t size);
+ bool Produce(const void *data, size_t size);
i64 TotalSerializedDataSize;
TMappedAllocation Stack;
TContClosure SelfClosure;
TContMachineContext InnerContext;
- TContMachineContext *BufFeedContext = nullptr;
- char *BufferPtr;
- size_t SizeRemain;
- static constexpr size_t MaxChunks = 16;
- TChunk Chunks[MaxChunks];
- size_t NumChunks = 0;
- const IEventBase *Event = nullptr;
- bool CancelFlag = false;
- bool AbortFlag;
- bool SerializationSuccess;
- bool Finished = false;
+ TContMachineContext *BufFeedContext = nullptr;
+ char *BufferPtr;
+ size_t SizeRemain;
+ static constexpr size_t MaxChunks = 16;
+ TChunk Chunks[MaxChunks];
+ size_t NumChunks = 0;
+ const IEventBase *Event = nullptr;
+ bool CancelFlag = false;
+ bool AbortFlag;
+ bool SerializationSuccess;
+ bool Finished = false;
};
-#ifdef ACTORLIB_HUGE_PB_SIZE
- static const size_t EventMaxByteSize = 140 << 20; // (140MB)
-#else
- static const size_t EventMaxByteSize = 67108000;
-#endif
-
+#ifdef ACTORLIB_HUGE_PB_SIZE
+ static const size_t EventMaxByteSize = 140 << 20; // (140MB)
+#else
+ static const size_t EventMaxByteSize = 67108000;
+#endif
+
template <typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType, typename TRecHolder>
class TEventPBBase: public TEventBase<TEv, TEventType> , public TRecHolder {
- // a vector of data buffers referenced by record; if filled, then extended serialization mechanism applies
- TVector<TRope> Payload;
-
+ // a vector of data buffers referenced by record; if filled, then extended serialization mechanism applies
+ TVector<TRope> Payload;
+
public:
using TRecHolder::Record;
@@ -155,218 +155,218 @@ namespace NActors {
}
TString ToString() const override {
- return Record.ShortDebugString();
- }
-
- bool IsSerializable() const override {
- return true;
- }
-
- bool IsExtendedFormat() const override {
- return static_cast<bool>(Payload);
+ return Record.ShortDebugString();
}
+ bool IsSerializable() const override {
+ return true;
+ }
+
+ bool IsExtendedFormat() const override {
+ return static_cast<bool>(Payload);
+ }
+
bool SerializeToArcadiaStream(TChunkSerializer* chunker) const override {
- // serialize payload first
- if (Payload) {
- void *data;
- int size = 0;
- auto append = [&](const char *p, size_t len) {
- while (len) {
- if (size) {
- const size_t numBytesToCopy = std::min<size_t>(size, len);
- memcpy(data, p, numBytesToCopy);
- data = static_cast<char*>(data) + numBytesToCopy;
- size -= numBytesToCopy;
- p += numBytesToCopy;
- len -= numBytesToCopy;
- } else if (!chunker->Next(&data, &size)) {
- return false;
- }
- }
- return true;
- };
- auto appendNumber = [&](size_t number) {
- char buf[MaxNumberBytes];
- return append(buf, SerializeNumber(number, buf));
- };
- char marker = PayloadMarker;
- append(&marker, 1);
- if (!appendNumber(Payload.size())) {
- return false;
- }
- for (const TRope& rope : Payload) {
- if (!appendNumber(rope.GetSize())) {
- return false;
- }
- if (rope) {
- if (size) {
- chunker->BackUp(std::exchange(size, 0));
- }
- if (!chunker->WriteRope(&rope)) {
- return false;
- }
- }
- }
- if (size) {
- chunker->BackUp(size);
- }
- }
-
+ // serialize payload first
+ if (Payload) {
+ void *data;
+ int size = 0;
+ auto append = [&](const char *p, size_t len) {
+ while (len) {
+ if (size) {
+ const size_t numBytesToCopy = std::min<size_t>(size, len);
+ memcpy(data, p, numBytesToCopy);
+ data = static_cast<char*>(data) + numBytesToCopy;
+ size -= numBytesToCopy;
+ p += numBytesToCopy;
+ len -= numBytesToCopy;
+ } else if (!chunker->Next(&data, &size)) {
+ return false;
+ }
+ }
+ return true;
+ };
+ auto appendNumber = [&](size_t number) {
+ char buf[MaxNumberBytes];
+ return append(buf, SerializeNumber(number, buf));
+ };
+ char marker = PayloadMarker;
+ append(&marker, 1);
+ if (!appendNumber(Payload.size())) {
+ return false;
+ }
+ for (const TRope& rope : Payload) {
+ if (!appendNumber(rope.GetSize())) {
+ return false;
+ }
+ if (rope) {
+ if (size) {
+ chunker->BackUp(std::exchange(size, 0));
+ }
+ if (!chunker->WriteRope(&rope)) {
+ return false;
+ }
+ }
+ }
+ if (size) {
+ chunker->BackUp(size);
+ }
+ }
+
return Record.SerializeToZeroCopyStream(chunker);
}
ui32 CalculateSerializedSize() const override {
- ssize_t result = Record.ByteSize();
- if (result >= 0 && Payload) {
- ++result; // marker
- char buf[MaxNumberBytes];
- result += SerializeNumber(Payload.size(), buf);
- for (const TRope& rope : Payload) {
- result += SerializeNumber(rope.GetSize(), buf);
- result += rope.GetSize();
- }
- }
+ ssize_t result = Record.ByteSize();
+ if (result >= 0 && Payload) {
+ ++result; // marker
+ char buf[MaxNumberBytes];
+ result += SerializeNumber(Payload.size(), buf);
+ for (const TRope& rope : Payload) {
+ result += SerializeNumber(rope.GetSize(), buf);
+ result += rope.GetSize();
+ }
+ }
return result;
}
static IEventBase* Load(TIntrusivePtr<TEventSerializedData> input) {
THolder<TEventPBBase> ev(new TEv());
- if (!input->GetSize()) {
+ if (!input->GetSize()) {
Y_PROTOBUF_SUPPRESS_NODISCARD ev->Record.ParseFromString(TString());
- } else {
- TRope::TConstIterator iter = input->GetBeginIter();
- ui64 size = input->GetSize();
-
- if (input->IsExtendedFormat()) {
- // check marker
- if (!iter.Valid() || *iter.ContiguousData() != PayloadMarker) {
- Y_FAIL("invalid event");
- }
- // skip marker
- iter += 1;
- --size;
- // parse number of payload ropes
- size_t numRopes = DeserializeNumber(iter, size);
- if (numRopes == Max<size_t>()) {
- Y_FAIL("invalid event");
- }
- while (numRopes--) {
- // parse length of the rope
- const size_t len = DeserializeNumber(iter, size);
- if (len == Max<size_t>() || size < len) {
- Y_FAIL("invalid event len# %zu size# %" PRIu64, len, size);
- }
- // extract the rope
- TRope::TConstIterator begin = iter;
- iter += len;
- size -= len;
- ev->Payload.emplace_back(begin, iter);
- }
- }
-
- // parse the protobuf
- TRopeStream stream(iter, size);
- if (!ev->Record.ParseFromZeroCopyStream(&stream)) {
+ } else {
+ TRope::TConstIterator iter = input->GetBeginIter();
+ ui64 size = input->GetSize();
+
+ if (input->IsExtendedFormat()) {
+ // check marker
+ if (!iter.Valid() || *iter.ContiguousData() != PayloadMarker) {
+ Y_FAIL("invalid event");
+ }
+ // skip marker
+ iter += 1;
+ --size;
+ // parse number of payload ropes
+ size_t numRopes = DeserializeNumber(iter, size);
+ if (numRopes == Max<size_t>()) {
+ Y_FAIL("invalid event");
+ }
+ while (numRopes--) {
+ // parse length of the rope
+ const size_t len = DeserializeNumber(iter, size);
+ if (len == Max<size_t>() || size < len) {
+ Y_FAIL("invalid event len# %zu size# %" PRIu64, len, size);
+ }
+ // extract the rope
+ TRope::TConstIterator begin = iter;
+ iter += len;
+ size -= len;
+ ev->Payload.emplace_back(begin, iter);
+ }
+ }
+
+ // parse the protobuf
+ TRopeStream stream(iter, size);
+ if (!ev->Record.ParseFromZeroCopyStream(&stream)) {
Y_FAIL("Failed to parse protobuf event type %" PRIu32 " class %s", TEventType, TypeName(ev->Record).data());
- }
+ }
}
- ev->CachedByteSize = input->GetSize();
- return ev.Release();
+ ev->CachedByteSize = input->GetSize();
+ return ev.Release();
}
- size_t GetCachedByteSize() const {
- if (CachedByteSize == 0) {
- CachedByteSize = CalculateSerializedSize();
+ size_t GetCachedByteSize() const {
+ if (CachedByteSize == 0) {
+ CachedByteSize = CalculateSerializedSize();
}
return CachedByteSize;
}
- ui32 CalculateSerializedSizeCached() const override {
- return GetCachedByteSize();
- }
-
+ ui32 CalculateSerializedSizeCached() const override {
+ return GetCachedByteSize();
+ }
+
void InvalidateCachedByteSize() {
CachedByteSize = 0;
}
- public:
+ public:
void ReservePayload(size_t size) {
Payload.reserve(size);
}
- ui32 AddPayload(TRope&& rope) {
- const ui32 id = Payload.size();
- Payload.push_back(std::move(rope));
- InvalidateCachedByteSize();
- return id;
- }
-
- const TRope& GetPayload(ui32 id) const {
- Y_VERIFY(id < Payload.size());
- return Payload[id];
- }
-
- ui32 GetPayloadCount() const {
- return Payload.size();
- }
-
- void StripPayload() {
- Payload.clear();
- }
-
- protected:
+ ui32 AddPayload(TRope&& rope) {
+ const ui32 id = Payload.size();
+ Payload.push_back(std::move(rope));
+ InvalidateCachedByteSize();
+ return id;
+ }
+
+ const TRope& GetPayload(ui32 id) const {
+ Y_VERIFY(id < Payload.size());
+ return Payload[id];
+ }
+
+ ui32 GetPayloadCount() const {
+ return Payload.size();
+ }
+
+ void StripPayload() {
+ Payload.clear();
+ }
+
+ protected:
mutable size_t CachedByteSize = 0;
-
- static constexpr char PayloadMarker = 0x07;
- static constexpr size_t MaxNumberBytes = (sizeof(size_t) * CHAR_BIT + 6) / 7;
-
- static size_t SerializeNumber(size_t num, char *buffer) {
- char *begin = buffer;
- do {
- *buffer++ = (num & 0x7F) | (num >= 128 ? 0x80 : 0x00);
- num >>= 7;
- } while (num);
- return buffer - begin;
- }
-
- static size_t DeserializeNumber(const char **ptr, const char *end) {
- const char *p = *ptr;
- size_t res = 0;
- size_t offset = 0;
- for (;;) {
- if (p == end) {
- return Max<size_t>();
- }
- const char byte = *p++;
- res |= (static_cast<size_t>(byte) & 0x7F) << offset;
- offset += 7;
- if (!(byte & 0x80)) {
- break;
- }
- }
- *ptr = p;
- return res;
- }
-
- static size_t DeserializeNumber(TRope::TConstIterator& iter, ui64& size) {
- size_t res = 0;
- size_t offset = 0;
- for (;;) {
- if (!iter.Valid()) {
- return Max<size_t>();
- }
- const char byte = *iter.ContiguousData();
- iter += 1;
- --size;
- res |= (static_cast<size_t>(byte) & 0x7F) << offset;
- offset += 7;
- if (!(byte & 0x80)) {
- break;
- }
- }
- return res;
- }
+
+ static constexpr char PayloadMarker = 0x07;
+ static constexpr size_t MaxNumberBytes = (sizeof(size_t) * CHAR_BIT + 6) / 7;
+
+ static size_t SerializeNumber(size_t num, char *buffer) {
+ char *begin = buffer;
+ do {
+ *buffer++ = (num & 0x7F) | (num >= 128 ? 0x80 : 0x00);
+ num >>= 7;
+ } while (num);
+ return buffer - begin;
+ }
+
+ static size_t DeserializeNumber(const char **ptr, const char *end) {
+ const char *p = *ptr;
+ size_t res = 0;
+ size_t offset = 0;
+ for (;;) {
+ if (p == end) {
+ return Max<size_t>();
+ }
+ const char byte = *p++;
+ res |= (static_cast<size_t>(byte) & 0x7F) << offset;
+ offset += 7;
+ if (!(byte & 0x80)) {
+ break;
+ }
+ }
+ *ptr = p;
+ return res;
+ }
+
+ static size_t DeserializeNumber(TRope::TConstIterator& iter, ui64& size) {
+ size_t res = 0;
+ size_t offset = 0;
+ for (;;) {
+ if (!iter.Valid()) {
+ return Max<size_t>();
+ }
+ const char byte = *iter.ContiguousData();
+ iter += 1;
+ --size;
+ res |= (static_cast<size_t>(byte) & 0x7F) << offset;
+ offset += 7;
+ if (!(byte & 0x80)) {
+ break;
+ }
+ }
+ return res;
+ }
};
// Protobuf record not using arena
@@ -468,7 +468,7 @@ namespace NActors {
}
TString ToString() const override {
- return GetRecord().ShortDebugString();
+ return GetRecord().ShortDebugString();
}
bool SerializeToArcadiaStream(TChunkSerializer* chunker) const override {
@@ -482,10 +482,10 @@ namespace NActors {
size_t GetCachedByteSize() const {
return PreSerializedData.size() + TBase::GetCachedByteSize();
}
-
- ui32 CalculateSerializedSizeCached() const override {
- return GetCachedByteSize();
- }
+
+ ui32 CalculateSerializedSizeCached() const override {
+ return GetCachedByteSize();
+ }
};
inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) {
diff --git a/library/cpp/actors/core/event_pb_payload_ut.cpp b/library/cpp/actors/core/event_pb_payload_ut.cpp
index eab007bc15d..212a83b62d9 100644
--- a/library/cpp/actors/core/event_pb_payload_ut.cpp
+++ b/library/cpp/actors/core/event_pb_payload_ut.cpp
@@ -1,53 +1,53 @@
-#include "event_pb.h"
-#include "events.h"
-
+#include "event_pb.h"
+#include "events.h"
+
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/actors/protos/unittests.pb.h>
-
-using namespace NActors;
-
-enum {
- EvMessageWithPayload = EventSpaceBegin(TEvents::ES_PRIVATE),
+
+using namespace NActors;
+
+enum {
+ EvMessageWithPayload = EventSpaceBegin(TEvents::ES_PRIVATE),
EvArenaMessage,
EvArenaMessageBig,
EvMessageWithPayloadPreSerialized
-};
-
-struct TEvMessageWithPayload : TEventPB<TEvMessageWithPayload, TMessageWithPayload, EvMessageWithPayload> {
+};
+
+struct TEvMessageWithPayload : TEventPB<TEvMessageWithPayload, TMessageWithPayload, EvMessageWithPayload> {
TEvMessageWithPayload() = default;
explicit TEvMessageWithPayload(const TMessageWithPayload& p)
: TEventPB<TEvMessageWithPayload, TMessageWithPayload, EvMessageWithPayload>(p)
{}
-};
-
+};
+
struct TEvMessageWithPayloadPreSerialized : TEventPreSerializedPB<TEvMessageWithPayloadPreSerialized, TMessageWithPayload, EvMessageWithPayloadPreSerialized> {
};
-TRope MakeStringRope(const TString& message) {
- return message ? TRope(message) : TRope();
-}
-
-TString MakeString(size_t len) {
- TString res;
- for (size_t i = 0; i < len; ++i) {
- res += RandomNumber<char>();
- }
- return res;
-}
-
-Y_UNIT_TEST_SUITE(TEventProtoWithPayload) {
-
+TRope MakeStringRope(const TString& message) {
+ return message ? TRope(message) : TRope();
+}
+
+TString MakeString(size_t len) {
+ TString res;
+ for (size_t i = 0; i < len; ++i) {
+ res += RandomNumber<char>();
+ }
+ return res;
+}
+
+Y_UNIT_TEST_SUITE(TEventProtoWithPayload) {
+
template <class TEventFrom, class TEventTo>
void TestSerializeDeserialize(size_t size1, size_t size2) {
static_assert(TEventFrom::EventType == TEventTo::EventType, "Must be same event type");
-
+
TEventFrom msg;
msg.Record.SetMeta("hello, world!");
msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size1))));
msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size2))));
msg.Record.AddSomeData(MakeString((size1 + size2) % 50 + 11));
-
+
auto serializer = MakeHolder<TAllocChunkSerializer>();
msg.SerializeToArcadiaStream(serializer.Get());
auto buffers = serializer->Release(msg.IsExtendedFormat());
@@ -59,11 +59,11 @@ Y_UNIT_TEST_SUITE(TEventProtoWithPayload) {
chunker.SetSerializingEvent(&msg);
while (!chunker.IsComplete()) {
char buffer[4096];
- auto range = chunker.FeedBuf(buffer, sizeof(buffer));
- for (auto p = range.first; p != range.second; ++p) {
- chunkerRes += TString(p->first, p->second);
- }
- }
+ auto range = chunker.FeedBuf(buffer, sizeof(buffer));
+ for (auto p = range.first; p != range.second; ++p) {
+ chunkerRes += TString(p->first, p->second);
+ }
+ }
UNIT_ASSERT_VALUES_EQUAL(chunkerRes, ser);
THolder<IEventBase> ev2 = THolder(TEventTo::Load(buffers));
@@ -71,7 +71,7 @@ Y_UNIT_TEST_SUITE(TEventProtoWithPayload) {
UNIT_ASSERT_VALUES_EQUAL(msg2.Record.GetMeta(), msg.Record.GetMeta());
UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(0)), msg.GetPayload(msg.Record.GetPayloadId(0)));
UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(1)), msg.GetPayload(msg.Record.GetPayloadId(1)));
- }
+ }
template <class TEvent>
void TestAllSizes(size_t step1 = 100, size_t step2 = 111) {
@@ -151,4 +151,4 @@ Y_UNIT_TEST_SUITE(TEventProtoWithPayload) {
UNIT_ASSERT_VALUES_EQUAL(record.GetPayloadId(0), msg.GetPayloadId(0));
UNIT_ASSERT_VALUES_EQUAL(record.GetPayloadId(1), msg.GetPayloadId(1));
}
-}
+}
diff --git a/library/cpp/actors/core/event_pb_ut.cpp b/library/cpp/actors/core/event_pb_ut.cpp
index a16c3092b3b..2e1d8953401 100644
--- a/library/cpp/actors/core/event_pb_ut.cpp
+++ b/library/cpp/actors/core/event_pb_ut.cpp
@@ -1,15 +1,15 @@
-#include "event_pb.h"
-
+#include "event_pb.h"
+
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/actors/protos/unittests.pb.h>
-
+
Y_UNIT_TEST_SUITE(TEventSerialization) {
- struct TMockEvent: public NActors::IEventBase {
- TBigMessage* msg;
+ struct TMockEvent: public NActors::IEventBase {
+ TBigMessage* msg;
bool
SerializeToArcadiaStream(NActors::TChunkSerializer* chunker) const override {
- return msg->SerializeToZeroCopyStream(chunker);
- }
+ return msg->SerializeToZeroCopyStream(chunker);
+ }
bool IsSerializable() const override {
return true;
}
@@ -22,50 +22,50 @@ Y_UNIT_TEST_SUITE(TEventSerialization) {
ui32 Type() const override {
return 0;
};
- };
-
+ };
+
Y_UNIT_TEST(Coroutine) {
- TString strA(507, 'a');
- TString strB(814, 'b');
- TString strC(198, 'c');
-
- TBigMessage bm;
-
- TSimple* simple0 = bm.AddSimples();
- simple0->SetStr1(strA);
- simple0->SetStr2(strB);
- simple0->SetNumber1(213431324);
-
- TSimple* simple1 = bm.AddSimples();
- simple1->SetStr1(strC);
- simple1->SetStr2(strA);
- simple1->SetNumber1(21039313);
-
- bm.AddManyStr(strA);
- bm.AddManyStr(strC);
- bm.AddManyStr(strB);
-
- bm.SetOneMoreStr(strB);
- bm.SetYANumber(394143);
-
- TString bmSerialized;
+ TString strA(507, 'a');
+ TString strB(814, 'b');
+ TString strC(198, 'c');
+
+ TBigMessage bm;
+
+ TSimple* simple0 = bm.AddSimples();
+ simple0->SetStr1(strA);
+ simple0->SetStr2(strB);
+ simple0->SetNumber1(213431324);
+
+ TSimple* simple1 = bm.AddSimples();
+ simple1->SetStr1(strC);
+ simple1->SetStr2(strA);
+ simple1->SetNumber1(21039313);
+
+ bm.AddManyStr(strA);
+ bm.AddManyStr(strC);
+ bm.AddManyStr(strB);
+
+ bm.SetOneMoreStr(strB);
+ bm.SetYANumber(394143);
+
+ TString bmSerialized;
Y_PROTOBUF_SUPPRESS_NODISCARD bm.SerializeToString(&bmSerialized);
- UNIT_ASSERT_UNEQUAL(bmSerialized.size(), 0);
-
- NActors::TCoroutineChunkSerializer chunker;
- for (int i = 0; i < 4; ++i) {
- TMockEvent event;
- event.msg = &bm;
- chunker.SetSerializingEvent(&event);
+ UNIT_ASSERT_UNEQUAL(bmSerialized.size(), 0);
+
+ NActors::TCoroutineChunkSerializer chunker;
+ for (int i = 0; i < 4; ++i) {
+ TMockEvent event;
+ event.msg = &bm;
+ chunker.SetSerializingEvent(&event);
char buf1[87];
- TString bmChunkedSerialized;
- while (!chunker.IsComplete()) {
- auto range = chunker.FeedBuf(&buf1[0], sizeof(buf1));
- for (auto p = range.first; p != range.second; ++p) {
- bmChunkedSerialized.append(p->first, p->second);
- }
- }
- UNIT_ASSERT_EQUAL(bmSerialized, bmChunkedSerialized);
- }
- }
-}
+ TString bmChunkedSerialized;
+ while (!chunker.IsComplete()) {
+ auto range = chunker.FeedBuf(&buf1[0], sizeof(buf1));
+ for (auto p = range.first; p != range.second; ++p) {
+ bmChunkedSerialized.append(p->first, p->second);
+ }
+ }
+ UNIT_ASSERT_EQUAL(bmSerialized, bmChunkedSerialized);
+ }
+ }
+}
diff --git a/library/cpp/actors/core/events.h b/library/cpp/actors/core/events.h
index 702cf50fadf..841537888a2 100644
--- a/library/cpp/actors/core/events.h
+++ b/library/cpp/actors/core/events.h
@@ -64,16 +64,16 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Blob);
+ return serializer->WriteString(&Blob);
}
static IEventBase* Load(TEventSerializedData* bufs) noexcept {
- return new TEvBlob(bufs->GetString());
- }
-
- bool IsSerializable() const override {
- return true;
+ return new TEvBlob(bufs->GetString());
}
+
+ bool IsSerializable() const override {
+ return true;
+ }
};
struct TSystem {
@@ -94,9 +94,9 @@ namespace NActors {
Gone, // Generic notification of actor death
TrackActor,
UntrackActor,
- InvokeResult,
- CoroTimeout,
- InvokeQuery,
+ InvokeResult,
+ CoroTimeout,
+ InvokeQuery,
End,
// Compatibility section
@@ -139,33 +139,33 @@ namespace NActors {
};
const ui32 SourceType;
const EReason Reason;
- const bool Unsure;
- const TString Data;
+ const bool Unsure;
+ const TString Data;
- TEvUndelivered(ui32 sourceType, ui32 reason, bool unsure = false)
+ TEvUndelivered(ui32 sourceType, ui32 reason, bool unsure = false)
: SourceType(sourceType)
, Reason(static_cast<EReason>(reason))
- , Unsure(unsure)
- , Data(MakeData(sourceType, reason))
- {}
+ , Unsure(unsure)
+ , Data(MakeData(sourceType, reason))
+ {}
TString ToStringHeader() const override;
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override;
static IEventBase* Load(TEventSerializedData* bufs);
- bool IsSerializable() const override;
-
- ui32 CalculateSerializedSize() const override { return 2 * sizeof(ui32); }
+ bool IsSerializable() const override;
+ ui32 CalculateSerializedSize() const override { return 2 * sizeof(ui32); }
+
static void Out(IOutputStream& o, EReason x);
-
- private:
- static TString MakeData(ui32 sourceType, ui32 reason) {
- TString s = TString::Uninitialized(sizeof(ui32) + sizeof(ui32));
+
+ private:
+ static TString MakeData(ui32 sourceType, ui32 reason) {
+ TString s = TString::Uninitialized(sizeof(ui32) + sizeof(ui32));
char *p = s.Detach();
WriteUnaligned<ui32>(p + 0, sourceType);
WriteUnaligned<ui32>(p + 4, reason);
- return s;
- }
+ return s;
+ }
};
struct TEvCompleted: public TEventBase<TEvCompleted, TSystem::Completed> {
@@ -209,8 +209,8 @@ namespace NActors {
DEFINE_SIMPLE_LOCAL_EVENT(TEvGone, "System: TEvGone")
};
- struct TEvInvokeResult;
-
+ struct TEvInvokeResult;
+
using TEvPoisonPill = TEvPoison; // Legacy name, deprecated
using TEvActorDied = TEvGone;
};
diff --git a/library/cpp/actors/core/events_undelivered.cpp b/library/cpp/actors/core/events_undelivered.cpp
index 23deaffd106..44d609597d2 100644
--- a/library/cpp/actors/core/events_undelivered.cpp
+++ b/library/cpp/actors/core/events_undelivered.cpp
@@ -1,5 +1,5 @@
#include "events.h"
-#include "actorsystem.h"
+#include "actorsystem.h"
namespace NActors {
TString TEvents::TEvUndelivered::ToStringHeader() const {
@@ -7,8 +7,8 @@ namespace NActors {
}
bool TEvents::TEvUndelivered::SerializeToArcadiaStream(TChunkSerializer *serializer) const {
- Y_VERIFY(!Unsure); // these are local-only events generated by Interconnect
- return serializer->WriteString(&Data);
+ Y_VERIFY(!Unsure); // these are local-only events generated by Interconnect
+ return serializer->WriteString(&Data);
}
void TEvents::TEvUndelivered::Out(IOutputStream& o, EReason x) {
@@ -25,12 +25,12 @@ namespace NActors {
}
}
- bool TEvents::TEvUndelivered::IsSerializable() const {
- return true;
- }
-
+ bool TEvents::TEvUndelivered::IsSerializable() const {
+ return true;
+ }
+
IEventBase* TEvents::TEvUndelivered::Load(TEventSerializedData* bufs) {
- TString str = bufs->GetString();
+ TString str = bufs->GetString();
Y_VERIFY(str.size() == (sizeof(ui32) + sizeof(ui32)));
const char* p = str.data();
const ui64 sourceType = ReadUnaligned<ui32>(p + 0);
@@ -38,23 +38,23 @@ namespace NActors {
return new TEvUndelivered(sourceType, reason);
}
- TAutoPtr<IEventHandle> IEventHandle::ForwardOnNondelivery(ui32 reason, bool unsure) {
- if (Flags & FlagForwardOnNondelivery) {
+ TAutoPtr<IEventHandle> IEventHandle::ForwardOnNondelivery(ui32 reason, bool unsure) {
+ if (Flags & FlagForwardOnNondelivery) {
const ui32 updatedFlags = Flags & ~(FlagForwardOnNondelivery | FlagSubscribeOnSession);
const TActorId recp = OnNondeliveryHolder ? OnNondeliveryHolder->Recipient : TActorId();
if (Event)
return new IEventHandle(recp, Sender, Event.Release(), updatedFlags, Cookie, &Recipient, TraceId.Clone());
else
- return new IEventHandle(Type, updatedFlags, recp, Sender, Buffer, Cookie, &Recipient, TraceId.Clone());
- }
-
- if (Flags & FlagTrackDelivery) {
- const ui32 updatedFlags = Flags & ~(FlagTrackDelivery | FlagSubscribeOnSession | FlagGenerateUnsureUndelivered);
- return new IEventHandle(Sender, Recipient, new TEvents::TEvUndelivered(Type, reason, unsure), updatedFlags,
- Cookie, nullptr, TraceId.Clone());
+ return new IEventHandle(Type, updatedFlags, recp, Sender, Buffer, Cookie, &Recipient, TraceId.Clone());
}
- return nullptr;
+ if (Flags & FlagTrackDelivery) {
+ const ui32 updatedFlags = Flags & ~(FlagTrackDelivery | FlagSubscribeOnSession | FlagGenerateUnsureUndelivered);
+ return new IEventHandle(Sender, Recipient, new TEvents::TEvUndelivered(Type, reason, unsure), updatedFlags,
+ Cookie, nullptr, TraceId.Clone());
+ }
+
+ return nullptr;
}
}
diff --git a/library/cpp/actors/core/executelater.h b/library/cpp/actors/core/executelater.h
index e7a13c10053..fec7aede1f8 100644
--- a/library/cpp/actors/core/executelater.h
+++ b/library/cpp/actors/core/executelater.h
@@ -35,13 +35,13 @@ namespace NActors {
TEvCallbackCompletion */
auto local = std::move(Callback);
- using T = decltype(local);
+ using T = decltype(local);
- if constexpr (std::is_invocable_v<T, const TActorContext&>) {
- local(ctx);
- } else {
- local();
- }
+ if constexpr (std::is_invocable_v<T, const TActorContext&>) {
+ local(ctx);
+ } else {
+ local();
+ }
}
if (ReportCompletionTo) {
diff --git a/library/cpp/actors/core/executor_pool_io.cpp b/library/cpp/actors/core/executor_pool_io.cpp
index fb557ae6b00..2d3adda0c0b 100644
--- a/library/cpp/actors/core/executor_pool_io.cpp
+++ b/library/cpp/actors/core/executor_pool_io.cpp
@@ -133,19 +133,19 @@ namespace NActors {
for (ui32 i = 0; i != PoolThreads; ++i)
Threads[i].Thread->Join();
}
-
- void TIOExecutorPool::GetCurrentStats(TExecutorPoolStats& /*poolStats*/, TVector<TExecutorThreadStats>& statsCopy) const {
- statsCopy.resize(PoolThreads + 1);
- // Save counters from the pool object
- statsCopy[0] = TExecutorThreadStats();
- statsCopy[0].Aggregate(Stats);
- // Per-thread stats
- for (size_t i = 0; i < PoolThreads; ++i) {
- Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]);
- }
- }
-
- TString TIOExecutorPool::GetName() const {
- return PoolName;
- }
+
+ void TIOExecutorPool::GetCurrentStats(TExecutorPoolStats& /*poolStats*/, TVector<TExecutorThreadStats>& statsCopy) const {
+ statsCopy.resize(PoolThreads + 1);
+ // Save counters from the pool object
+ statsCopy[0] = TExecutorThreadStats();
+ statsCopy[0].Aggregate(Stats);
+ // Per-thread stats
+ for (size_t i = 0; i < PoolThreads; ++i) {
+ Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]);
+ }
+ }
+
+ TString TIOExecutorPool::GetName() const {
+ return PoolName;
+ }
}
diff --git a/library/cpp/actors/core/executor_pool_io.h b/library/cpp/actors/core/executor_pool_io.h
index e576d642a1d..2d4991f14e7 100644
--- a/library/cpp/actors/core/executor_pool_io.h
+++ b/library/cpp/actors/core/executor_pool_io.h
@@ -42,8 +42,8 @@ namespace NActors {
void Start() override;
void PrepareStop() override;
void Shutdown() override;
-
- void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override;
- TString GetName() const override;
+
+ void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override;
+ TString GetName() const override;
};
}
diff --git a/library/cpp/actors/core/executor_thread.h b/library/cpp/actors/core/executor_thread.h
index 9d3c573f0d6..b114f481dd7 100644
--- a/library/cpp/actors/core/executor_thread.h
+++ b/library/cpp/actors/core/executor_thread.h
@@ -44,7 +44,7 @@ namespace NActors {
TActorId RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId = TActorId());
void UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId);
void DropUnregistered();
- const std::vector<THolder<IActor>>& GetUnregistered() const { return DyingActors; }
+ const std::vector<THolder<IActor>>& GetUnregistered() const { return DyingActors; }
void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
diff --git a/library/cpp/actors/core/hfunc.h b/library/cpp/actors/core/hfunc.h
index 26f3c65013c..a013ad3914b 100644
--- a/library/cpp/actors/core/hfunc.h
+++ b/library/cpp/actors/core/hfunc.h
@@ -74,11 +74,11 @@
HandleFunc(ev, ctx); \
break;
-#define fFunc(TEventType, HandleFunc) \
- case TEventType: \
- HandleFunc(ev); \
- break;
-
+#define fFunc(TEventType, HandleFunc) \
+ case TEventType: \
+ HandleFunc(ev); \
+ break;
+
#define IgnoreFunc(TEvType) \
case TEvType::EventType: \
break;
diff --git a/library/cpp/actors/core/interconnect.cpp b/library/cpp/actors/core/interconnect.cpp
index a42278e669e..d66b135d462 100644
--- a/library/cpp/actors/core/interconnect.cpp
+++ b/library/cpp/actors/core/interconnect.cpp
@@ -1,171 +1,171 @@
-#include "interconnect.h"
-#include <util/digest/murmur.h>
-#include <google/protobuf/text_format.h>
-
-namespace NActors {
-
- TNodeLocation::TNodeLocation(const NActorsInterconnect::TNodeLocation& location) {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
- const NActorsInterconnect::TNodeLocation *locp = &location;
- NActorsInterconnect::TNodeLocation temp; // for legacy location case
-
- // WalleConfig compatibility section
- if (locp->HasBody()) {
- if (locp == &location) {
- temp.CopyFrom(*locp);
- locp = &temp;
- }
- temp.SetUnit(::ToString(temp.GetBody()));
- temp.ClearBody();
- }
-
- // legacy value processing
- if (locp->HasDataCenterNum() || locp->HasRoomNum() || locp->HasRackNum() || locp->HasBodyNum()) {
- if (locp == &location) {
- temp.CopyFrom(*locp);
- locp = &temp;
- }
- LegacyValue = TLegacyValue{temp.GetDataCenterNum(), temp.GetRoomNum(), temp.GetRackNum(), temp.GetBodyNum()};
- temp.ClearDataCenterNum();
- temp.ClearRoomNum();
- temp.ClearRackNum();
- temp.ClearBodyNum();
-
- const NProtoBuf::Reflection *reflection = temp.GetReflection();
- bool fieldsFromNewFormat = false;
- for (int i = 0, count = descriptor->field_count(); !fieldsFromNewFormat && i < count; ++i) {
- fieldsFromNewFormat |= reflection->HasField(temp, descriptor->field(i));
- }
- if (!fieldsFromNewFormat) {
- const auto& v = LegacyValue->DataCenter;
- const char *p = reinterpret_cast<const char*>(&v);
- temp.SetDataCenter(TString(p, strnlen(p, sizeof(ui32))));
- temp.SetModule(::ToString(LegacyValue->Room));
- temp.SetRack(::ToString(LegacyValue->Rack));
- temp.SetUnit(::ToString(LegacyValue->Body));
- }
- }
-
- auto makeString = [&] {
- NProtoBuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString s;
- p.PrintToString(*locp, &s);
- return s;
- };
-
- // modern format parsing
- const NProtoBuf::Reflection *reflection = locp->GetReflection();
- for (int i = 0, count = descriptor->field_count(); i < count; ++i) {
- const NProtoBuf::FieldDescriptor *field = descriptor->field(i);
- if (reflection->HasField(*locp, field)) {
- Y_VERIFY(field->type() == NProtoBuf::FieldDescriptor::TYPE_STRING, "Location# %s", makeString().data());
- Items.emplace_back(TKeys::E(field->number()), reflection->GetString(*locp, field));
- }
- }
- const NProtoBuf::UnknownFieldSet& unknown = locp->unknown_fields();
- for (int i = 0, count = unknown.field_count(); i < count; ++i) {
- const NProtoBuf::UnknownField& field = unknown.field(i);
- Y_VERIFY(field.type() == NProtoBuf::UnknownField::TYPE_LENGTH_DELIMITED, "Location# %s", makeString().data());
- Items.emplace_back(TKeys::E(field.number()), field.length_delimited());
- }
- std::sort(Items.begin(), Items.end());
- }
-
- TNodeLocation::TNodeLocation(TFromSerialized, const TString& s)
- : TNodeLocation(ParseLocation(s))
- {}
-
- NActorsInterconnect::TNodeLocation TNodeLocation::ParseLocation(const TString& s) {
- NActorsInterconnect::TNodeLocation res;
- const bool success = res.ParseFromString(s);
- Y_VERIFY(success);
- return res;
- }
-
- TString TNodeLocation::ToStringUpTo(TKeys::E upToKey) const {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
-
- TStringBuilder res;
- for (const auto& [key, value] : Items) {
- if (upToKey < key) {
- break;
- }
- TString name;
- if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
- name = field->options().GetExtension(NActorsInterconnect::PrintName);
- } else {
- name = ::ToString(int(key));
- }
- if (key != upToKey) {
- res << name << "=" << value << "/";
- } else {
- res << value;
- }
- }
- return res;
- }
-
- void TNodeLocation::Serialize(NActorsInterconnect::TNodeLocation *pb) const {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
- const NProtoBuf::Reflection *reflection = pb->GetReflection();
- NProtoBuf::UnknownFieldSet *unknown = pb->mutable_unknown_fields();
- for (const auto& [key, value] : Items) {
- if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
- reflection->SetString(pb, field, value);
- } else {
- unknown->AddLengthDelimited(key)->assign(value);
- }
- }
- }
-
- TString TNodeLocation::GetSerializedLocation() const {
- NActorsInterconnect::TNodeLocation pb;
- Serialize(&pb);
- TString s;
- const bool success = pb.SerializeToString(&s);
- Y_VERIFY(success);
- return s;
- }
-
- TNodeLocation::TLegacyValue TNodeLocation::GetLegacyValue() const {
- if (LegacyValue) {
- return *LegacyValue;
- }
-
- ui32 dataCenterId = 0, moduleId = 0, rackId = 0, unitId = 0;
-
- for (const auto& [key, value] : Items) {
- switch (key) {
- case TKeys::DataCenter:
- memcpy(&dataCenterId, value.data(), Min<size_t>(sizeof(dataCenterId), value.length()));
- break;
-
- case TKeys::Module: {
- const bool success = TryFromString(value, moduleId);
- Y_VERIFY(success);
- break;
- }
-
- case TKeys::Rack:
- // hacky way to obtain numeric id by a rack name
- if (!TryFromString(value, rackId)) {
- rackId = MurmurHash<ui32>(value.data(), value.length());
- }
- break;
-
- case TKeys::Unit: {
- const bool success = TryFromString(value, unitId);
- Y_VERIFY(success);
- break;
- }
-
- default:
- Y_FAIL("unexpected legacy key# %d", key);
- }
- }
-
- return {dataCenterId, moduleId, rackId, unitId};
- }
-
-} // NActors
+#include "interconnect.h"
+#include <util/digest/murmur.h>
+#include <google/protobuf/text_format.h>
+
+namespace NActors {
+
+ TNodeLocation::TNodeLocation(const NActorsInterconnect::TNodeLocation& location) {
+ const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
+ const NActorsInterconnect::TNodeLocation *locp = &location;
+ NActorsInterconnect::TNodeLocation temp; // for legacy location case
+
+ // WalleConfig compatibility section
+ if (locp->HasBody()) {
+ if (locp == &location) {
+ temp.CopyFrom(*locp);
+ locp = &temp;
+ }
+ temp.SetUnit(::ToString(temp.GetBody()));
+ temp.ClearBody();
+ }
+
+ // legacy value processing
+ if (locp->HasDataCenterNum() || locp->HasRoomNum() || locp->HasRackNum() || locp->HasBodyNum()) {
+ if (locp == &location) {
+ temp.CopyFrom(*locp);
+ locp = &temp;
+ }
+ LegacyValue = TLegacyValue{temp.GetDataCenterNum(), temp.GetRoomNum(), temp.GetRackNum(), temp.GetBodyNum()};
+ temp.ClearDataCenterNum();
+ temp.ClearRoomNum();
+ temp.ClearRackNum();
+ temp.ClearBodyNum();
+
+ const NProtoBuf::Reflection *reflection = temp.GetReflection();
+ bool fieldsFromNewFormat = false;
+ for (int i = 0, count = descriptor->field_count(); !fieldsFromNewFormat && i < count; ++i) {
+ fieldsFromNewFormat |= reflection->HasField(temp, descriptor->field(i));
+ }
+ if (!fieldsFromNewFormat) {
+ const auto& v = LegacyValue->DataCenter;
+ const char *p = reinterpret_cast<const char*>(&v);
+ temp.SetDataCenter(TString(p, strnlen(p, sizeof(ui32))));
+ temp.SetModule(::ToString(LegacyValue->Room));
+ temp.SetRack(::ToString(LegacyValue->Rack));
+ temp.SetUnit(::ToString(LegacyValue->Body));
+ }
+ }
+
+ auto makeString = [&] {
+ NProtoBuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString s;
+ p.PrintToString(*locp, &s);
+ return s;
+ };
+
+ // modern format parsing
+ const NProtoBuf::Reflection *reflection = locp->GetReflection();
+ for (int i = 0, count = descriptor->field_count(); i < count; ++i) {
+ const NProtoBuf::FieldDescriptor *field = descriptor->field(i);
+ if (reflection->HasField(*locp, field)) {
+ Y_VERIFY(field->type() == NProtoBuf::FieldDescriptor::TYPE_STRING, "Location# %s", makeString().data());
+ Items.emplace_back(TKeys::E(field->number()), reflection->GetString(*locp, field));
+ }
+ }
+ const NProtoBuf::UnknownFieldSet& unknown = locp->unknown_fields();
+ for (int i = 0, count = unknown.field_count(); i < count; ++i) {
+ const NProtoBuf::UnknownField& field = unknown.field(i);
+ Y_VERIFY(field.type() == NProtoBuf::UnknownField::TYPE_LENGTH_DELIMITED, "Location# %s", makeString().data());
+ Items.emplace_back(TKeys::E(field.number()), field.length_delimited());
+ }
+ std::sort(Items.begin(), Items.end());
+ }
+
+ TNodeLocation::TNodeLocation(TFromSerialized, const TString& s)
+ : TNodeLocation(ParseLocation(s))
+ {}
+
+ NActorsInterconnect::TNodeLocation TNodeLocation::ParseLocation(const TString& s) {
+ NActorsInterconnect::TNodeLocation res;
+ const bool success = res.ParseFromString(s);
+ Y_VERIFY(success);
+ return res;
+ }
+
+ TString TNodeLocation::ToStringUpTo(TKeys::E upToKey) const {
+ const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
+
+ TStringBuilder res;
+ for (const auto& [key, value] : Items) {
+ if (upToKey < key) {
+ break;
+ }
+ TString name;
+ if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
+ name = field->options().GetExtension(NActorsInterconnect::PrintName);
+ } else {
+ name = ::ToString(int(key));
+ }
+ if (key != upToKey) {
+ res << name << "=" << value << "/";
+ } else {
+ res << value;
+ }
+ }
+ return res;
+ }
+
+ void TNodeLocation::Serialize(NActorsInterconnect::TNodeLocation *pb) const {
+ const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
+ const NProtoBuf::Reflection *reflection = pb->GetReflection();
+ NProtoBuf::UnknownFieldSet *unknown = pb->mutable_unknown_fields();
+ for (const auto& [key, value] : Items) {
+ if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
+ reflection->SetString(pb, field, value);
+ } else {
+ unknown->AddLengthDelimited(key)->assign(value);
+ }
+ }
+ }
+
+ TString TNodeLocation::GetSerializedLocation() const {
+ NActorsInterconnect::TNodeLocation pb;
+ Serialize(&pb);
+ TString s;
+ const bool success = pb.SerializeToString(&s);
+ Y_VERIFY(success);
+ return s;
+ }
+
+ TNodeLocation::TLegacyValue TNodeLocation::GetLegacyValue() const {
+ if (LegacyValue) {
+ return *LegacyValue;
+ }
+
+ ui32 dataCenterId = 0, moduleId = 0, rackId = 0, unitId = 0;
+
+ for (const auto& [key, value] : Items) {
+ switch (key) {
+ case TKeys::DataCenter:
+ memcpy(&dataCenterId, value.data(), Min<size_t>(sizeof(dataCenterId), value.length()));
+ break;
+
+ case TKeys::Module: {
+ const bool success = TryFromString(value, moduleId);
+ Y_VERIFY(success);
+ break;
+ }
+
+ case TKeys::Rack:
+ // hacky way to obtain numeric id by a rack name
+ if (!TryFromString(value, rackId)) {
+ rackId = MurmurHash<ui32>(value.data(), value.length());
+ }
+ break;
+
+ case TKeys::Unit: {
+ const bool success = TryFromString(value, unitId);
+ Y_VERIFY(success);
+ break;
+ }
+
+ default:
+ Y_FAIL("unexpected legacy key# %d", key);
+ }
+ }
+
+ return {dataCenterId, moduleId, rackId, unitId};
+ }
+
+} // NActors
diff --git a/library/cpp/actors/core/interconnect.h b/library/cpp/actors/core/interconnect.h
index 679a4b8cc6f..60151eba48a 100644
--- a/library/cpp/actors/core/interconnect.h
+++ b/library/cpp/actors/core/interconnect.h
@@ -1,118 +1,118 @@
#pragma once
-
-#include "events.h"
-#include "event_local.h"
+
+#include "events.h"
+#include "event_local.h"
#include <library/cpp/actors/protos/interconnect.pb.h>
-#include <util/string/cast.h>
-#include <util/string/builder.h>
+#include <util/string/cast.h>
+#include <util/string/builder.h>
namespace NActors {
- class TNodeLocation {
- public:
- struct TKeys {
- enum E : int {
- DataCenter = 10,
- Module = 20,
- Rack = 30,
- Unit = 40,
- };
- };
-
- struct TLegacyValue {
- ui32 DataCenter;
- ui32 Room;
- ui32 Rack;
- ui32 Body;
-
- auto ConvertToTuple() const { return std::make_tuple(DataCenter, Room, Rack, Body); }
-
- int Compare(const TLegacyValue& other) const {
- const auto x = ConvertToTuple();
- const auto y = other.ConvertToTuple();
- if (x < y) {
- return -1;
- } else if (y < x) {
- return 1;
- } else {
- return 0;
- }
- }
-
- friend bool operator ==(const TLegacyValue& x, const TLegacyValue& y) { return x.Compare(y) == 0; }
-
- void Serialize(NActorsInterconnect::TNodeLocation *pb) const {
- pb->SetDataCenterNum(DataCenter);
- pb->SetRoomNum(Room);
- pb->SetRackNum(Rack);
- pb->SetBodyNum(Body);
- }
- };
-
- private:
- std::optional<TLegacyValue> LegacyValue;
- std::vector<std::pair<TKeys::E, TString>> Items;
-
+ class TNodeLocation {
public:
- // generic ctors
- TNodeLocation() = default;
- TNodeLocation(const TNodeLocation&) = default;
- TNodeLocation(TNodeLocation&&) = default;
-
- // protobuf-parser ctor
- explicit TNodeLocation(const NActorsInterconnect::TNodeLocation& location);
-
- // serialized protobuf ctor
- static constexpr struct TFromSerialized {} FromSerialized {};
- TNodeLocation(TFromSerialized, const TString& s);
-
- // parser helper function
- static NActorsInterconnect::TNodeLocation ParseLocation(const TString& s);
-
- // assignment operators
- TNodeLocation& operator =(const TNodeLocation&) = default;
- TNodeLocation& operator =(TNodeLocation&&) = default;
-
- void Serialize(NActorsInterconnect::TNodeLocation *pb) const;
- TString GetSerializedLocation() const;
-
- TString GetDataCenterId() const { return ToStringUpTo(TKeys::DataCenter); }
- TString GetModuleId() const { return ToStringUpTo(TKeys::Module); }
- TString GetRackId() const { return ToStringUpTo(TKeys::Rack); }
- TString ToString() const { return ToStringUpTo(TKeys::E(Max<int>())); }
- TString ToStringUpTo(TKeys::E upToKey) const;
-
- TLegacyValue GetLegacyValue() const;
-
- const std::vector<std::pair<TKeys::E, TString>>& GetItems() const { return Items; }
-
- bool HasKey(TKeys::E key) const {
- auto comp = [](const auto& p, TKeys::E value) { return p.first < value; };
- const auto it = std::lower_bound(Items.begin(), Items.end(), key, comp);
- return it != Items.end() && it->first == key;
- }
-
- int Compare(const TNodeLocation& other) const {
- if (LegacyValue || other.LegacyValue) {
- return GetLegacyValue().Compare(other.GetLegacyValue());
- } else if (Items < other.Items) {
- return -1;
- } else if (other.Items < Items) {
- return 1;
- } else {
- return 0;
- }
- }
-
- void InheritLegacyValue(const TNodeLocation& other) {
- LegacyValue = other.GetLegacyValue();
- }
-
- friend bool operator ==(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) == 0; }
- friend bool operator !=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) != 0; }
- friend bool operator < (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) < 0; }
- friend bool operator <=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) <= 0; }
- friend bool operator > (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) > 0; }
- friend bool operator >=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) >= 0; }
+ struct TKeys {
+ enum E : int {
+ DataCenter = 10,
+ Module = 20,
+ Rack = 30,
+ Unit = 40,
+ };
+ };
+
+ struct TLegacyValue {
+ ui32 DataCenter;
+ ui32 Room;
+ ui32 Rack;
+ ui32 Body;
+
+ auto ConvertToTuple() const { return std::make_tuple(DataCenter, Room, Rack, Body); }
+
+ int Compare(const TLegacyValue& other) const {
+ const auto x = ConvertToTuple();
+ const auto y = other.ConvertToTuple();
+ if (x < y) {
+ return -1;
+ } else if (y < x) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ friend bool operator ==(const TLegacyValue& x, const TLegacyValue& y) { return x.Compare(y) == 0; }
+
+ void Serialize(NActorsInterconnect::TNodeLocation *pb) const {
+ pb->SetDataCenterNum(DataCenter);
+ pb->SetRoomNum(Room);
+ pb->SetRackNum(Rack);
+ pb->SetBodyNum(Body);
+ }
+ };
+
+ private:
+ std::optional<TLegacyValue> LegacyValue;
+ std::vector<std::pair<TKeys::E, TString>> Items;
+
+ public:
+ // generic ctors
+ TNodeLocation() = default;
+ TNodeLocation(const TNodeLocation&) = default;
+ TNodeLocation(TNodeLocation&&) = default;
+
+ // protobuf-parser ctor
+ explicit TNodeLocation(const NActorsInterconnect::TNodeLocation& location);
+
+ // serialized protobuf ctor
+ static constexpr struct TFromSerialized {} FromSerialized {};
+ TNodeLocation(TFromSerialized, const TString& s);
+
+ // parser helper function
+ static NActorsInterconnect::TNodeLocation ParseLocation(const TString& s);
+
+ // assignment operators
+ TNodeLocation& operator =(const TNodeLocation&) = default;
+ TNodeLocation& operator =(TNodeLocation&&) = default;
+
+ void Serialize(NActorsInterconnect::TNodeLocation *pb) const;
+ TString GetSerializedLocation() const;
+
+ TString GetDataCenterId() const { return ToStringUpTo(TKeys::DataCenter); }
+ TString GetModuleId() const { return ToStringUpTo(TKeys::Module); }
+ TString GetRackId() const { return ToStringUpTo(TKeys::Rack); }
+ TString ToString() const { return ToStringUpTo(TKeys::E(Max<int>())); }
+ TString ToStringUpTo(TKeys::E upToKey) const;
+
+ TLegacyValue GetLegacyValue() const;
+
+ const std::vector<std::pair<TKeys::E, TString>>& GetItems() const { return Items; }
+
+ bool HasKey(TKeys::E key) const {
+ auto comp = [](const auto& p, TKeys::E value) { return p.first < value; };
+ const auto it = std::lower_bound(Items.begin(), Items.end(), key, comp);
+ return it != Items.end() && it->first == key;
+ }
+
+ int Compare(const TNodeLocation& other) const {
+ if (LegacyValue || other.LegacyValue) {
+ return GetLegacyValue().Compare(other.GetLegacyValue());
+ } else if (Items < other.Items) {
+ return -1;
+ } else if (other.Items < Items) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ void InheritLegacyValue(const TNodeLocation& other) {
+ LegacyValue = other.GetLegacyValue();
+ }
+
+ friend bool operator ==(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) == 0; }
+ friend bool operator !=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) != 0; }
+ friend bool operator < (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) < 0; }
+ friend bool operator <=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) <= 0; }
+ friend bool operator > (const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) > 0; }
+ friend bool operator >=(const TNodeLocation& x, const TNodeLocation& y) { return x.Compare(y) >= 0; }
};
struct TEvInterconnect {
@@ -131,13 +131,13 @@ namespace NActors {
EvDisconnect,
EvGetNode,
EvNodeInfo,
- EvClosePeerSocket,
- EvCloseInputSession,
- EvPoisonSession,
- EvTerminate,
+ EvClosePeerSocket,
+ EvCloseInputSession,
+ EvPoisonSession,
+ EvTerminate,
EvEnd
};
-
+
enum ESubscribes {
SubConnected,
SubDisconnected,
@@ -184,7 +184,7 @@ namespace NActors {
TString Host;
TString ResolveHost;
ui16 Port;
- TNodeLocation Location;
+ TNodeLocation Location;
TNodeInfo() = default;
TNodeInfo(const TNodeInfo&) = default;
@@ -194,7 +194,7 @@ namespace NActors {
const TString& host,
const TString& resolveHost,
ui16 port,
- const TNodeLocation& location)
+ const TNodeLocation& location)
: NodeId(nodeId)
, Address(address)
, Host(host)
@@ -225,11 +225,11 @@ namespace NActors {
struct TEvGetNode: public TEventLocal<TEvGetNode, EvGetNode> {
ui32 NodeId;
- TInstant Deadline;
+ TInstant Deadline;
- TEvGetNode(ui32 nodeId, TInstant deadline = TInstant::Max())
+ TEvGetNode(ui32 nodeId, TInstant deadline = TInstant::Max())
: NodeId(nodeId)
- , Deadline(deadline)
+ , Deadline(deadline)
{
}
};
@@ -243,13 +243,13 @@ namespace NActors {
ui32 NodeId;
THolder<TNodeInfo> Node;
};
-
+
struct TEvClosePeerSocket : TEventLocal<TEvClosePeerSocket, EvClosePeerSocket> {};
-
+
struct TEvCloseInputSession : TEventLocal<TEvCloseInputSession, EvCloseInputSession> {};
-
- struct TEvPoisonSession : TEventLocal<TEvPoisonSession, EvPoisonSession> {};
-
- struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {};
+
+ struct TEvPoisonSession : TEventLocal<TEvPoisonSession, EvPoisonSession> {};
+
+ struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {};
};
}
diff --git a/library/cpp/actors/core/invoke.h b/library/cpp/actors/core/invoke.h
index 931a9767ddd..000f21727c2 100644
--- a/library/cpp/actors/core/invoke.h
+++ b/library/cpp/actors/core/invoke.h
@@ -1,110 +1,110 @@
-#pragma once
-
-#include "actor_bootstrapped.h"
-#include "events.h"
-#include "event_local.h"
-
-#include <any>
-#include <type_traits>
-#include <utility>
-#include <variant>
-
+#pragma once
+
+#include "actor_bootstrapped.h"
+#include "events.h"
+#include "event_local.h"
+
+#include <any>
+#include <type_traits>
+#include <utility>
+#include <variant>
+
#include <util/system/type_name.h>
-namespace NActors {
-
- struct TEvents::TEvInvokeResult
- : TEventLocal<TEvInvokeResult, TSystem::InvokeResult>
- {
- using TProcessCallback = std::function<void(TEvInvokeResult&, const TActorContext&)>;
- TProcessCallback ProcessCallback;
- std::variant<std::any /* the value */, std::exception_ptr> Result;
-
- // This constructor creates TEvInvokeResult with the result of calling callback(args...) or exception_ptr,
- // if exception occurs during evaluation.
- template<typename TCallback, typename... TArgs>
- TEvInvokeResult(TProcessCallback&& process, TCallback&& callback, TArgs&&... args)
- : ProcessCallback(std::move(process))
- {
- try {
- if constexpr (std::is_void_v<std::invoke_result_t<TCallback, TArgs...>>) {
- // just invoke callback without saving any value
- std::invoke(std::forward<TCallback>(callback), std::forward<TArgs>(args)...);
- } else {
- Result.emplace<std::any>(std::invoke(std::forward<TCallback>(callback), std::forward<TArgs>(args)...));
- }
- } catch (...) {
- Result.emplace<std::exception_ptr>(std::current_exception());
- }
- }
-
- void Process(const TActorContext& ctx) {
- ProcessCallback(*this, ctx);
- }
-
- template<typename TCallback>
- std::invoke_result_t<TCallback, const TActorContext&> GetResult() {
- using T = std::invoke_result_t<TCallback, const TActorContext&>;
- return std::visit([](auto& arg) -> T {
- using TArg = std::decay_t<decltype(arg)>;
- if constexpr (std::is_same_v<TArg, std::exception_ptr>) {
- std::rethrow_exception(arg);
- } else if constexpr (std::is_void_v<T>) {
- Y_VERIFY(!arg.has_value());
- } else if (auto *value = std::any_cast<T>(&arg)) {
- return std::move(*value);
- } else {
- Y_FAIL("unspported return type for TEvInvokeResult: actual# %s != expected# %s",
+namespace NActors {
+
+ struct TEvents::TEvInvokeResult
+ : TEventLocal<TEvInvokeResult, TSystem::InvokeResult>
+ {
+ using TProcessCallback = std::function<void(TEvInvokeResult&, const TActorContext&)>;
+ TProcessCallback ProcessCallback;
+ std::variant<std::any /* the value */, std::exception_ptr> Result;
+
+ // This constructor creates TEvInvokeResult with the result of calling callback(args...) or exception_ptr,
+ // if exception occurs during evaluation.
+ template<typename TCallback, typename... TArgs>
+ TEvInvokeResult(TProcessCallback&& process, TCallback&& callback, TArgs&&... args)
+ : ProcessCallback(std::move(process))
+ {
+ try {
+ if constexpr (std::is_void_v<std::invoke_result_t<TCallback, TArgs...>>) {
+ // just invoke callback without saving any value
+ std::invoke(std::forward<TCallback>(callback), std::forward<TArgs>(args)...);
+ } else {
+ Result.emplace<std::any>(std::invoke(std::forward<TCallback>(callback), std::forward<TArgs>(args)...));
+ }
+ } catch (...) {
+ Result.emplace<std::exception_ptr>(std::current_exception());
+ }
+ }
+
+ void Process(const TActorContext& ctx) {
+ ProcessCallback(*this, ctx);
+ }
+
+ template<typename TCallback>
+ std::invoke_result_t<TCallback, const TActorContext&> GetResult() {
+ using T = std::invoke_result_t<TCallback, const TActorContext&>;
+ return std::visit([](auto& arg) -> T {
+ using TArg = std::decay_t<decltype(arg)>;
+ if constexpr (std::is_same_v<TArg, std::exception_ptr>) {
+ std::rethrow_exception(arg);
+ } else if constexpr (std::is_void_v<T>) {
+ Y_VERIFY(!arg.has_value());
+ } else if (auto *value = std::any_cast<T>(&arg)) {
+ return std::move(*value);
+ } else {
+ Y_FAIL("unspported return type for TEvInvokeResult: actual# %s != expected# %s",
TypeName(arg.type()).data(), TypeName<T>().data());
- }
- }, Result);
- }
- };
-
- // Invoke Actor is used to make different procedure calls in specific threads pools.
- //
- // Actor is created by CreateInvokeActor(callback, complete) where `callback` is the function that will be invoked
- // upon actor registration, which will issue then TEvInvokeResult to the parent actor with the result of called
- // function. If the called function throws exception, then the exception will arrive in the result. Receiver of
- // this message can either handle it by its own means calling ev.GetResult() (which will rethrow exception if it
- // has occured in called function or return its return value; notice that when there is no return value, then
- // GetResult() should also be called to prevent losing exception), or invoke ev.Process(), which will invoke
- // callback provided as `complete` parameter to the CreateInvokeActor function. Complete handler is invoked with
- // the result-getter lambda as the first argument and the actor system context as the second one. Result-getter
- // should be called to obtain resulting value or exception like the GetResult() method of the TEvInvokeResult event.
- //
- // Notice that `callback` execution usually occurs in separate actor on separate mailbox and should not use parent
- // actor's class. But `complete` handler is invoked in parent context and can use its contents. Do not forget to
- // handle TEvInvokeResult event by calling Process/GetResult method, whichever is necessary.
-
+ }
+ }, Result);
+ }
+ };
+
+ // Invoke Actor is used to make different procedure calls in specific threads pools.
+ //
+ // Actor is created by CreateInvokeActor(callback, complete) where `callback` is the function that will be invoked
+ // upon actor registration, which will issue then TEvInvokeResult to the parent actor with the result of called
+ // function. If the called function throws exception, then the exception will arrive in the result. Receiver of
+ // this message can either handle it by its own means calling ev.GetResult() (which will rethrow exception if it
+ // has occured in called function or return its return value; notice that when there is no return value, then
+ // GetResult() should also be called to prevent losing exception), or invoke ev.Process(), which will invoke
+ // callback provided as `complete` parameter to the CreateInvokeActor function. Complete handler is invoked with
+ // the result-getter lambda as the first argument and the actor system context as the second one. Result-getter
+ // should be called to obtain resulting value or exception like the GetResult() method of the TEvInvokeResult event.
+ //
+ // Notice that `callback` execution usually occurs in separate actor on separate mailbox and should not use parent
+ // actor's class. But `complete` handler is invoked in parent context and can use its contents. Do not forget to
+ // handle TEvInvokeResult event by calling Process/GetResult method, whichever is necessary.
+
template<typename TCallback, typename TCompletion, ui32 Activity>
- class TInvokeActor : public TActorBootstrapped<TInvokeActor<TCallback, TCompletion, Activity>> {
- TCallback Callback;
- TCompletion Complete;
-
- public:
+ class TInvokeActor : public TActorBootstrapped<TInvokeActor<TCallback, TCompletion, Activity>> {
+ TCallback Callback;
+ TCompletion Complete;
+
+ public:
static constexpr auto ActorActivityType() {
return static_cast<IActor::EActorActivity>(Activity);
- }
-
- TInvokeActor(TCallback&& callback, TCompletion&& complete)
- : Callback(std::move(callback))
- , Complete(std::move(complete))
- {}
-
+ }
+
+ TInvokeActor(TCallback&& callback, TCompletion&& complete)
+ : Callback(std::move(callback))
+ , Complete(std::move(complete))
+ {}
+
void Bootstrap(const TActorId& parentId, const TActorContext& ctx) {
- auto process = [complete = std::move(Complete)](TEvents::TEvInvokeResult& res, const TActorContext& ctx) {
- complete([&] { return res.GetResult<TCallback>(); }, ctx);
- };
- ctx.Send(parentId, new TEvents::TEvInvokeResult(std::move(process), std::move(Callback), ctx));
- TActorBootstrapped<TInvokeActor>::Die(ctx);
- }
- };
-
+ auto process = [complete = std::move(Complete)](TEvents::TEvInvokeResult& res, const TActorContext& ctx) {
+ complete([&] { return res.GetResult<TCallback>(); }, ctx);
+ };
+ ctx.Send(parentId, new TEvents::TEvInvokeResult(std::move(process), std::move(Callback), ctx));
+ TActorBootstrapped<TInvokeActor>::Die(ctx);
+ }
+ };
+
template<ui32 Activity, typename TCallback, typename TCompletion>
- std::unique_ptr<IActor> CreateInvokeActor(TCallback&& callback, TCompletion&& complete) {
- return std::make_unique<TInvokeActor<std::decay_t<TCallback>, std::decay_t<TCompletion>, Activity>>(
- std::forward<TCallback>(callback), std::forward<TCompletion>(complete));
- }
-
-} // NActors
+ std::unique_ptr<IActor> CreateInvokeActor(TCallback&& callback, TCompletion&& complete) {
+ return std::make_unique<TInvokeActor<std::decay_t<TCallback>, std::decay_t<TCompletion>, Activity>>(
+ std::forward<TCallback>(callback), std::forward<TCompletion>(complete));
+ }
+
+} // NActors
diff --git a/library/cpp/actors/core/io_dispatcher.cpp b/library/cpp/actors/core/io_dispatcher.cpp
index 90699ff16c7..89816367c11 100644
--- a/library/cpp/actors/core/io_dispatcher.cpp
+++ b/library/cpp/actors/core/io_dispatcher.cpp
@@ -1,234 +1,234 @@
-#include "io_dispatcher.h"
-#include "actor_bootstrapped.h"
-#include "hfunc.h"
-#include <util/system/mutex.h>
-#include <util/system/condvar.h>
-#include <util/system/thread.h>
-#include <map>
-#include <list>
-
-namespace NActors {
-
- class TIoDispatcherActor : public TActorBootstrapped<TIoDispatcherActor> {
- enum {
- EvNotifyThreadStopped = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // IO task queue
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- class TTask {
- TInstant Timestamp;
- std::function<void()> Callback;
-
- public:
- TTask(TInstant timestamp, TEvInvokeQuery *ev)
- : Timestamp(timestamp)
- , Callback(std::move(ev->Callback))
- {}
-
- void Execute() {
- Callback();
- }
-
- TInstant GetTimestamp() const {
- return Timestamp;
- }
- };
-
- class TTaskQueue {
- std::list<TTask> Tasks;
- TMutex Mutex;
- TCondVar CondVar;
- size_t NumThreadsToStop = 0;
-
- public:
- void Enqueue(TInstant timestamp, TEvInvokeQuery *ev) {
- std::list<TTask> list;
- list.emplace_back(timestamp, ev);
- with_lock (Mutex) {
- Tasks.splice(Tasks.end(), std::move(list));
- }
- CondVar.Signal();
- }
-
- bool Dequeue(std::list<TTask>& list, bool *sendNotify) {
- with_lock (Mutex) {
- CondVar.Wait(Mutex, [&] { return NumThreadsToStop || !Tasks.empty(); });
- if (NumThreadsToStop) {
- *sendNotify = NumThreadsToStop != Max<size_t>();
- if (*sendNotify) {
- --NumThreadsToStop;
- }
- return false;
- } else {
- list.splice(list.end(), Tasks, Tasks.begin());
- return true;
- }
- }
- }
-
- void Stop() {
- with_lock (Mutex) {
- NumThreadsToStop = Max<size_t>();
- }
- CondVar.BroadCast();
- }
-
- void StopOne() {
- with_lock (Mutex) {
- ++NumThreadsToStop;
- Y_VERIFY(NumThreadsToStop);
- }
- CondVar.Signal();
- }
-
- std::optional<TInstant> GetEarliestTaskTimestamp() {
- with_lock (Mutex) {
- return Tasks.empty() ? std::nullopt : std::make_optional(Tasks.front().GetTimestamp());
- }
- }
- };
-
- TTaskQueue TaskQueue;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // IO dispatcher threads
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- class TThread : public ISimpleThread {
- TIoDispatcherActor& Actor;
- TActorSystem* const ActorSystem;
-
- public:
- TThread(TIoDispatcherActor& actor, TActorSystem *actorSystem)
- : Actor(actor)
- , ActorSystem(actorSystem)
- {
- Start();
- }
-
- void *ThreadProc() override {
- SetCurrentThreadName("kikimr IO");
- for (;;) {
- std::list<TTask> tasks;
- bool sendNotify;
- if (!Actor.TaskQueue.Dequeue(tasks, &sendNotify)) {
- if (sendNotify) {
- ActorSystem->Send(new IEventHandle(EvNotifyThreadStopped, 0, Actor.SelfId(), TActorId(),
- nullptr, TThread::CurrentThreadId()));
- }
- break;
- }
- for (TTask& task : tasks) {
- task.Execute();
- ++*Actor.TasksCompleted;
- }
- }
- return nullptr;
- }
- };
-
- static constexpr size_t MinThreadCount = 4;
- static constexpr size_t MaxThreadCount = 64;
- std::map<TThread::TId, std::unique_ptr<TThread>> Threads;
- size_t NumRunningThreads = 0;
-
- void StartThread() {
- auto thread = std::make_unique<TThread>(*this, TlsActivationContext->ExecutorThread.ActorSystem);
- const TThread::TId id = thread->Id();
- Threads.emplace(id, std::move(thread));
- *NumThreads = ++NumRunningThreads;
- ++*ThreadsStarted;
- }
-
- void StopThread() {
- Y_VERIFY(Threads.size());
- TaskQueue.StopOne();
- *NumThreads = --NumRunningThreads;
- ++*ThreadsStopped;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Counters
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- NMonitoring::TDynamicCounters::TCounterPtr NumThreads;
- NMonitoring::TDynamicCounters::TCounterPtr TasksAdded;
- NMonitoring::TDynamicCounters::TCounterPtr TasksCompleted;
- NMonitoring::TDynamicCounters::TCounterPtr ThreadsStarted;
- NMonitoring::TDynamicCounters::TCounterPtr ThreadsStopped;
-
- public:
- TIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters)
- : NumThreads(counters->GetCounter("NumThreads"))
- , TasksAdded(counters->GetCounter("TasksAdded", true))
- , TasksCompleted(counters->GetCounter("TasksCompleted", true))
- , ThreadsStarted(counters->GetCounter("ThreadsStarted", true))
- , ThreadsStopped(counters->GetCounter("ThreadsStopped", true))
- {}
-
+#include "io_dispatcher.h"
+#include "actor_bootstrapped.h"
+#include "hfunc.h"
+#include <util/system/mutex.h>
+#include <util/system/condvar.h>
+#include <util/system/thread.h>
+#include <map>
+#include <list>
+
+namespace NActors {
+
+ class TIoDispatcherActor : public TActorBootstrapped<TIoDispatcherActor> {
+ enum {
+ EvNotifyThreadStopped = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // IO task queue
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class TTask {
+ TInstant Timestamp;
+ std::function<void()> Callback;
+
+ public:
+ TTask(TInstant timestamp, TEvInvokeQuery *ev)
+ : Timestamp(timestamp)
+ , Callback(std::move(ev->Callback))
+ {}
+
+ void Execute() {
+ Callback();
+ }
+
+ TInstant GetTimestamp() const {
+ return Timestamp;
+ }
+ };
+
+ class TTaskQueue {
+ std::list<TTask> Tasks;
+ TMutex Mutex;
+ TCondVar CondVar;
+ size_t NumThreadsToStop = 0;
+
+ public:
+ void Enqueue(TInstant timestamp, TEvInvokeQuery *ev) {
+ std::list<TTask> list;
+ list.emplace_back(timestamp, ev);
+ with_lock (Mutex) {
+ Tasks.splice(Tasks.end(), std::move(list));
+ }
+ CondVar.Signal();
+ }
+
+ bool Dequeue(std::list<TTask>& list, bool *sendNotify) {
+ with_lock (Mutex) {
+ CondVar.Wait(Mutex, [&] { return NumThreadsToStop || !Tasks.empty(); });
+ if (NumThreadsToStop) {
+ *sendNotify = NumThreadsToStop != Max<size_t>();
+ if (*sendNotify) {
+ --NumThreadsToStop;
+ }
+ return false;
+ } else {
+ list.splice(list.end(), Tasks, Tasks.begin());
+ return true;
+ }
+ }
+ }
+
+ void Stop() {
+ with_lock (Mutex) {
+ NumThreadsToStop = Max<size_t>();
+ }
+ CondVar.BroadCast();
+ }
+
+ void StopOne() {
+ with_lock (Mutex) {
+ ++NumThreadsToStop;
+ Y_VERIFY(NumThreadsToStop);
+ }
+ CondVar.Signal();
+ }
+
+ std::optional<TInstant> GetEarliestTaskTimestamp() {
+ with_lock (Mutex) {
+ return Tasks.empty() ? std::nullopt : std::make_optional(Tasks.front().GetTimestamp());
+ }
+ }
+ };
+
+ TTaskQueue TaskQueue;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // IO dispatcher threads
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class TThread : public ISimpleThread {
+ TIoDispatcherActor& Actor;
+ TActorSystem* const ActorSystem;
+
+ public:
+ TThread(TIoDispatcherActor& actor, TActorSystem *actorSystem)
+ : Actor(actor)
+ , ActorSystem(actorSystem)
+ {
+ Start();
+ }
+
+ void *ThreadProc() override {
+ SetCurrentThreadName("kikimr IO");
+ for (;;) {
+ std::list<TTask> tasks;
+ bool sendNotify;
+ if (!Actor.TaskQueue.Dequeue(tasks, &sendNotify)) {
+ if (sendNotify) {
+ ActorSystem->Send(new IEventHandle(EvNotifyThreadStopped, 0, Actor.SelfId(), TActorId(),
+ nullptr, TThread::CurrentThreadId()));
+ }
+ break;
+ }
+ for (TTask& task : tasks) {
+ task.Execute();
+ ++*Actor.TasksCompleted;
+ }
+ }
+ return nullptr;
+ }
+ };
+
+ static constexpr size_t MinThreadCount = 4;
+ static constexpr size_t MaxThreadCount = 64;
+ std::map<TThread::TId, std::unique_ptr<TThread>> Threads;
+ size_t NumRunningThreads = 0;
+
+ void StartThread() {
+ auto thread = std::make_unique<TThread>(*this, TlsActivationContext->ExecutorThread.ActorSystem);
+ const TThread::TId id = thread->Id();
+ Threads.emplace(id, std::move(thread));
+ *NumThreads = ++NumRunningThreads;
+ ++*ThreadsStarted;
+ }
+
+ void StopThread() {
+ Y_VERIFY(Threads.size());
+ TaskQueue.StopOne();
+ *NumThreads = --NumRunningThreads;
+ ++*ThreadsStopped;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Counters
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ NMonitoring::TDynamicCounters::TCounterPtr NumThreads;
+ NMonitoring::TDynamicCounters::TCounterPtr TasksAdded;
+ NMonitoring::TDynamicCounters::TCounterPtr TasksCompleted;
+ NMonitoring::TDynamicCounters::TCounterPtr ThreadsStarted;
+ NMonitoring::TDynamicCounters::TCounterPtr ThreadsStopped;
+
+ public:
+ TIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters)
+ : NumThreads(counters->GetCounter("NumThreads"))
+ , TasksAdded(counters->GetCounter("TasksAdded", true))
+ , TasksCompleted(counters->GetCounter("TasksCompleted", true))
+ , ThreadsStarted(counters->GetCounter("ThreadsStarted", true))
+ , ThreadsStopped(counters->GetCounter("ThreadsStopped", true))
+ {}
+
~TIoDispatcherActor() override {
- TaskQueue.Stop();
- }
-
- void Bootstrap() {
- while (NumRunningThreads < MinThreadCount) {
- StartThread();
- }
- HandleWakeup();
- Become(&TThis::StateFunc);
- }
-
- void HandleThreadStopped(TAutoPtr<IEventHandle> ev) {
- auto it = Threads.find(ev->Cookie);
- Y_VERIFY(it != Threads.end());
- it->second->Join();
- Threads.erase(it);
- }
-
- void Handle(TEvInvokeQuery::TPtr ev) {
- ++*TasksAdded;
- TaskQueue.Enqueue(TActivationContext::Now(), ev->Get());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Thread usage counter logic
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- std::optional<TInstant> IdleTimestamp;
- static constexpr TDuration ThreadStartTime = TDuration::MilliSeconds(500);
- static constexpr TDuration ThreadStopTime = TDuration::MilliSeconds(500);
-
- void HandleWakeup() {
- const TInstant now = TActivationContext::Now();
- std::optional<TInstant> earliest = TaskQueue.GetEarliestTaskTimestamp();
- if (earliest) {
- if (now >= *earliest + ThreadStartTime && NumRunningThreads < MaxThreadCount) {
- StartThread();
- }
- IdleTimestamp.reset();
- } else if (!IdleTimestamp) {
- IdleTimestamp = now;
- } else if (now >= *IdleTimestamp + ThreadStopTime) {
- IdleTimestamp.reset();
- if (NumRunningThreads > MinThreadCount) {
- StopThread();
- }
- }
- Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
- }
-
- STRICT_STFUNC(StateFunc, {
- fFunc(EvNotifyThreadStopped, HandleThreadStopped);
- hFunc(TEvInvokeQuery, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- cFunc(TEvents::TSystem::Poison, PassAway);
- })
- };
-
- IActor *CreateIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters) {
- return new TIoDispatcherActor(counters);
- }
-
-} // NActors
+ TaskQueue.Stop();
+ }
+
+ void Bootstrap() {
+ while (NumRunningThreads < MinThreadCount) {
+ StartThread();
+ }
+ HandleWakeup();
+ Become(&TThis::StateFunc);
+ }
+
+ void HandleThreadStopped(TAutoPtr<IEventHandle> ev) {
+ auto it = Threads.find(ev->Cookie);
+ Y_VERIFY(it != Threads.end());
+ it->second->Join();
+ Threads.erase(it);
+ }
+
+ void Handle(TEvInvokeQuery::TPtr ev) {
+ ++*TasksAdded;
+ TaskQueue.Enqueue(TActivationContext::Now(), ev->Get());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Thread usage counter logic
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ std::optional<TInstant> IdleTimestamp;
+ static constexpr TDuration ThreadStartTime = TDuration::MilliSeconds(500);
+ static constexpr TDuration ThreadStopTime = TDuration::MilliSeconds(500);
+
+ void HandleWakeup() {
+ const TInstant now = TActivationContext::Now();
+ std::optional<TInstant> earliest = TaskQueue.GetEarliestTaskTimestamp();
+ if (earliest) {
+ if (now >= *earliest + ThreadStartTime && NumRunningThreads < MaxThreadCount) {
+ StartThread();
+ }
+ IdleTimestamp.reset();
+ } else if (!IdleTimestamp) {
+ IdleTimestamp = now;
+ } else if (now >= *IdleTimestamp + ThreadStopTime) {
+ IdleTimestamp.reset();
+ if (NumRunningThreads > MinThreadCount) {
+ StopThread();
+ }
+ }
+ Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ fFunc(EvNotifyThreadStopped, HandleThreadStopped);
+ hFunc(TEvInvokeQuery, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ })
+ };
+
+ IActor *CreateIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters) {
+ return new TIoDispatcherActor(counters);
+ }
+
+} // NActors
diff --git a/library/cpp/actors/core/io_dispatcher.h b/library/cpp/actors/core/io_dispatcher.h
index b0e4e60d1a7..e818d6fbe8e 100644
--- a/library/cpp/actors/core/io_dispatcher.h
+++ b/library/cpp/actors/core/io_dispatcher.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#include "actor.h"
-#include "event_local.h"
-#include "events.h"
-#include "actorsystem.h"
-#include "executor_thread.h"
-#include "executelater.h"
-
-namespace NActors {
-
- struct TEvInvokeQuery : TEventLocal<TEvInvokeQuery, TEvents::TSystem::InvokeQuery> {
- std::function<void()> Callback;
-
- TEvInvokeQuery(std::function<void()>&& callback)
- : Callback(std::move(callback))
- {}
- };
-
- inline TActorId MakeIoDispatcherActorId() {
- return TActorId(0, TStringBuf("IoDispatcher", 12));
- }
-
- extern IActor *CreateIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters);
-
- /* InvokeIoCallback enqueues callback() to be executed in IO thread pool and then return result in TEvInvokeResult
- * message to parentId actor.
- */
- template<typename TCallback>
- static void InvokeIoCallback(TCallback&& callback, ui32 poolId, IActor::EActivityType activityType) {
- if (!TActivationContext::Send(new IEventHandle(MakeIoDispatcherActorId(), TActorId(),
- new TEvInvokeQuery(callback)))) {
- TActivationContext::Register(CreateExecuteLaterActor(std::move(callback), activityType), TActorId(),
- TMailboxType::HTSwap, poolId);
- }
- }
-
-} // NActors
+#pragma once
+
+#include "actor.h"
+#include "event_local.h"
+#include "events.h"
+#include "actorsystem.h"
+#include "executor_thread.h"
+#include "executelater.h"
+
+namespace NActors {
+
+ struct TEvInvokeQuery : TEventLocal<TEvInvokeQuery, TEvents::TSystem::InvokeQuery> {
+ std::function<void()> Callback;
+
+ TEvInvokeQuery(std::function<void()>&& callback)
+ : Callback(std::move(callback))
+ {}
+ };
+
+ inline TActorId MakeIoDispatcherActorId() {
+ return TActorId(0, TStringBuf("IoDispatcher", 12));
+ }
+
+ extern IActor *CreateIoDispatcherActor(const NMonitoring::TDynamicCounterPtr& counters);
+
+ /* InvokeIoCallback enqueues callback() to be executed in IO thread pool and then return result in TEvInvokeResult
+ * message to parentId actor.
+ */
+ template<typename TCallback>
+ static void InvokeIoCallback(TCallback&& callback, ui32 poolId, IActor::EActivityType activityType) {
+ if (!TActivationContext::Send(new IEventHandle(MakeIoDispatcherActorId(), TActorId(),
+ new TEvInvokeQuery(callback)))) {
+ TActivationContext::Register(CreateExecuteLaterActor(std::move(callback), activityType), TActorId(),
+ TMailboxType::HTSwap, poolId);
+ }
+ }
+
+} // NActors
diff --git a/library/cpp/actors/core/log_settings.h b/library/cpp/actors/core/log_settings.h
index 7fe4504edd9..ceeb0a9b9a2 100644
--- a/library/cpp/actors/core/log_settings.h
+++ b/library/cpp/actors/core/log_settings.h
@@ -130,8 +130,8 @@ namespace NActors {
// priority <= sampling level ==> apply sampling
ui32 samplingRate = settings.Raw.X.SamplingRate;
if (samplingRate) {
- ui32 samplingValue = sampleBy ? MurmurHash<ui32>((const char*)&sampleBy, sizeof(sampleBy))
- : samplingRate != 1 ? RandomNumber<ui32>() : 0;
+ ui32 samplingValue = sampleBy ? MurmurHash<ui32>((const char*)&sampleBy, sizeof(sampleBy))
+ : samplingRate != 1 ? RandomNumber<ui32>() : 0;
return (samplingValue % samplingRate == 0);
} else {
// sampling rate not set ==> do not log
diff --git a/library/cpp/actors/core/mailbox.h b/library/cpp/actors/core/mailbox.h
index 0bd9c4d314e..f29e4b5f9b0 100644
--- a/library/cpp/actors/core/mailbox.h
+++ b/library/cpp/actors/core/mailbox.h
@@ -99,30 +99,30 @@ namespace NActors {
return (ActorPack == TMailboxActorPack::Simple && ActorsInfo.Simple.ActorId == 0);
}
- template<typename T>
- void ForEach(T&& callback) noexcept {
- switch (ActorPack) {
- case TMailboxActorPack::Simple:
- if (ActorsInfo.Simple.ActorId) {
- callback(ActorsInfo.Simple.ActorId, ActorsInfo.Simple.Actor);
- }
- break;
-
- case TMailboxActorPack::Map:
- for (const auto& [actorId, actor] : *ActorsInfo.Map.ActorsMap) {
- callback(actorId, actor);
- }
- break;
-
- case TMailboxActorPack::Array:
- for (ui64 i = 0; i < ActorsInfo.Array.ActorsCount; ++i) {
- auto& row = ActorsInfo.Array.ActorsArray->Actors[i];
- callback(row.ActorId, row.Actor);
- }
- break;
- }
- }
-
+ template<typename T>
+ void ForEach(T&& callback) noexcept {
+ switch (ActorPack) {
+ case TMailboxActorPack::Simple:
+ if (ActorsInfo.Simple.ActorId) {
+ callback(ActorsInfo.Simple.ActorId, ActorsInfo.Simple.Actor);
+ }
+ break;
+
+ case TMailboxActorPack::Map:
+ for (const auto& [actorId, actor] : *ActorsInfo.Map.ActorsMap) {
+ callback(actorId, actor);
+ }
+ break;
+
+ case TMailboxActorPack::Array:
+ for (ui64 i = 0; i < ActorsInfo.Array.ActorsCount; ++i) {
+ auto& row = ActorsInfo.Array.ActorsArray->Actors[i];
+ callback(row.ActorId, row.Actor);
+ }
+ break;
+ }
+ }
+
IActor* FindActor(ui64 localActorId) noexcept {
switch (ActorPack) {
case TMailboxActorPack::Simple: {
diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h
index c450f2338eb..0b851878a2c 100644
--- a/library/cpp/actors/core/mon.h
+++ b/library/cpp/actors/core/mon.h
@@ -112,19 +112,19 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Query);
- }
-
- ui32 CalculateSerializedSize() const override {
- return Query.size();
- }
-
- bool IsSerializable() const override {
- return true;
+ return serializer->WriteString(&Query);
}
+ ui32 CalculateSerializedSize() const override {
+ return Query.size();
+ }
+
+ bool IsSerializable() const override {
+ return true;
+ }
+
static IEventBase* Load(TEventSerializedData* bufs) {
- return new TEvRemoteHttpInfo(bufs->GetString());
+ return new TEvRemoteHttpInfo(bufs->GetString());
}
HTTP_METHOD GetMethod() const
@@ -149,19 +149,19 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Html);
- }
-
- ui32 CalculateSerializedSize() const override {
- return Html.size();
- }
-
- bool IsSerializable() const override {
- return true;
+ return serializer->WriteString(&Html);
}
+ ui32 CalculateSerializedSize() const override {
+ return Html.size();
+ }
+
+ bool IsSerializable() const override {
+ return true;
+ }
+
static IEventBase* Load(TEventSerializedData* bufs) {
- return new TEvRemoteHttpInfoRes(bufs->GetString());
+ return new TEvRemoteHttpInfoRes(bufs->GetString());
}
};
@@ -181,19 +181,19 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Json);
- }
-
- ui32 CalculateSerializedSize() const override {
- return Json.size();
- }
-
- bool IsSerializable() const override {
- return true;
+ return serializer->WriteString(&Json);
}
+ ui32 CalculateSerializedSize() const override {
+ return Json.size();
+ }
+
+ bool IsSerializable() const override {
+ return true;
+ }
+
static IEventBase* Load(TEventSerializedData* bufs) {
- return new TEvRemoteJsonInfoRes(bufs->GetString());
+ return new TEvRemoteJsonInfoRes(bufs->GetString());
}
};
@@ -213,19 +213,19 @@ namespace NActors {
}
bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Blob);
- }
-
- ui32 CalculateSerializedSize() const override {
- return Blob.size();
- }
-
- bool IsSerializable() const override {
- return true;
+ return serializer->WriteString(&Blob);
}
+ ui32 CalculateSerializedSize() const override {
+ return Blob.size();
+ }
+
+ bool IsSerializable() const override {
+ return true;
+ }
+
static IEventBase* Load(TEventSerializedData* bufs) {
- return new TEvRemoteBinaryInfoRes(bufs->GetString());
+ return new TEvRemoteBinaryInfoRes(bufs->GetString());
}
};
diff --git a/library/cpp/actors/core/probes.h b/library/cpp/actors/core/probes.h
index 4912d6dd26c..9a1370c1f95 100644
--- a/library/cpp/actors/core/probes.h
+++ b/library/cpp/actors/core/probes.h
@@ -65,12 +65,12 @@
PROBE(SlowICPushSendQueue, GROUPS("ActorLibSlowIC"), \
TYPES(ui32, double), \
NAMES("peerId", "icPushSendQueueMs")) \
- PROBE(SlowICWriteData, GROUPS("ActorLibSlowIC"), \
+ PROBE(SlowICWriteData, GROUPS("ActorLibSlowIC"), \
TYPES(ui32, double), \
- NAMES("peerId", "icWriteDataMs")) \
- PROBE(SlowICDropConfirmed, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- NAMES("peerId", "icDropConfirmedMs")) \
+ NAMES("peerId", "icWriteDataMs")) \
+ PROBE(SlowICDropConfirmed, GROUPS("ActorLibSlowIC"), \
+ TYPES(ui32, double), \
+ NAMES("peerId", "icDropConfirmedMs")) \
PROBE(ActorsystemScheduler, GROUPS("Durations"), \
TYPES(ui64, ui64, ui32, ui32, ui64, ui64), \
NAMES("timeUs", "timerfd_expirations", "eventsGottenFromQueues", "eventsSent", \
diff --git a/library/cpp/actors/core/scheduler_actor.cpp b/library/cpp/actors/core/scheduler_actor.cpp
index febc5e40dd2..7cbe40f5d1b 100644
--- a/library/cpp/actors/core/scheduler_actor.cpp
+++ b/library/cpp/actors/core/scheduler_actor.cpp
@@ -19,7 +19,7 @@ namespace NActors {
public:
TTimerDescriptor()
- : Descriptor(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK))
+ : Descriptor(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK))
{
Y_VERIFY(Descriptor != -1, "timerfd_create() failed with %s", strerror(errno));
}
@@ -40,7 +40,7 @@ namespace NActors {
TVector<NSchedulerQueue::TReader*> Readers;
TActorId PollerActor;
- TPollerToken::TPtr PollerToken;
+ TPollerToken::TPtr PollerToken;
ui64 RealTime;
ui64 MonotonicTime;
@@ -93,8 +93,8 @@ namespace NActors {
new_time.it_interval.tv_nsec = Cfg.ResolutionMicroseconds * 1000;
int ret = timerfd_settime(TimerDescriptor->GetDescriptor(), 0, &new_time, NULL);
Y_VERIFY(ret != -1, "timerfd_settime() failed with %s", strerror(errno));
- const bool success = ctx.Send(PollerActor, new TEvPollerRegister(TimerDescriptor, SelfId(), {}));
- Y_VERIFY(success);
+ const bool success = ctx.Send(PollerActor, new TEvPollerRegister(TimerDescriptor, SelfId(), {}));
+ Y_VERIFY(success);
RealTime = RelaxedLoad(CurrentTimestamp);
MonotonicTime = RelaxedLoad(CurrentMonotonic);
@@ -102,11 +102,11 @@ namespace NActors {
ActiveTick = AlignUp<ui64>(MonotonicTime, IntrasecondThreshold);
}
- void Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx) {
- PollerToken = ev->Get()->PollerToken;
- HandleSchedule(ctx);
- }
-
+ void Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx) {
+ PollerToken = ev->Get()->PollerToken;
+ HandleSchedule(ctx);
+ }
+
void UpdateTime() {
RealTime = TInstant::Now().MicroSeconds();
MonotonicTime = Max(MonotonicTime, GetMonotonicMicroSeconds());
@@ -125,135 +125,135 @@ namespace NActors {
}
void HandleSchedule(const TActorContext& ctx) {
- for (;;) {
- NHPTimer::STime schedulingStart;
- GetTimeFast(&schedulingStart);
- NHPTimer::STime lastTimeUpdate = schedulingStart;
-
- ui64 expired;
- ssize_t bytesRead;
- bytesRead = read(TimerDescriptor->GetDescriptor(), &expired, sizeof(expired));
- if (bytesRead == -1) {
- if (errno == EAGAIN) {
- PollerToken->Request(true, false);
- break;
- } else if (errno == EINTR) {
- continue;
- }
- }
- Y_VERIFY(bytesRead == sizeof(expired), "Error while reading from timerfd, strerror# %s", strerror(errno));
- UpdateTime();
-
- ui32 eventsGottenFromQueues = 0;
- // collect everything from queues
- for (ui32 i = 0; i != Readers.size(); ++i) {
- while (NSchedulerQueue::TEntry* x = Readers[i]->Pop()) {
- const ui64 instant = AlignUp<ui64>(x->InstantMicroseconds, Cfg.ResolutionMicroseconds);
- IEventHandle* const ev = x->Ev;
- ISchedulerCookie* const cookie = x->Cookie;
-
- // check is cookie still valid? looks like it will hurt performance w/o sagnificant memory save
-
- if (instant <= ActiveTick) {
- if (!ActiveSec)
- ActiveSec.Reset(new TMomentMap());
- TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*ActiveSec)[instant];
- if (!queue)
- queue.Reset(new NSchedulerQueue::TQueueType());
- queue->Writer.Push(instant, ev, cookie);
- } else {
- const ui64 intrasecond = AlignUp<ui64>(instant, IntrasecondThreshold);
- TAutoPtr<TMomentMap>& msec = ScheduleMap[intrasecond];
- if (!msec)
- msec.Reset(new TMomentMap());
- TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*msec)[instant];
- if (!queue)
- queue.Reset(new NSchedulerQueue::TQueueType());
- queue->Writer.Push(instant, ev, cookie);
- }
- ++eventsGottenFromQueues;
- TryUpdateTime(&lastTimeUpdate);
+ for (;;) {
+ NHPTimer::STime schedulingStart;
+ GetTimeFast(&schedulingStart);
+ NHPTimer::STime lastTimeUpdate = schedulingStart;
+
+ ui64 expired;
+ ssize_t bytesRead;
+ bytesRead = read(TimerDescriptor->GetDescriptor(), &expired, sizeof(expired));
+ if (bytesRead == -1) {
+ if (errno == EAGAIN) {
+ PollerToken->Request(true, false);
+ break;
+ } else if (errno == EINTR) {
+ continue;
+ }
+ }
+ Y_VERIFY(bytesRead == sizeof(expired), "Error while reading from timerfd, strerror# %s", strerror(errno));
+ UpdateTime();
+
+ ui32 eventsGottenFromQueues = 0;
+ // collect everything from queues
+ for (ui32 i = 0; i != Readers.size(); ++i) {
+ while (NSchedulerQueue::TEntry* x = Readers[i]->Pop()) {
+ const ui64 instant = AlignUp<ui64>(x->InstantMicroseconds, Cfg.ResolutionMicroseconds);
+ IEventHandle* const ev = x->Ev;
+ ISchedulerCookie* const cookie = x->Cookie;
+
+ // check is cookie still valid? looks like it will hurt performance w/o sagnificant memory save
+
+ if (instant <= ActiveTick) {
+ if (!ActiveSec)
+ ActiveSec.Reset(new TMomentMap());
+ TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*ActiveSec)[instant];
+ if (!queue)
+ queue.Reset(new NSchedulerQueue::TQueueType());
+ queue->Writer.Push(instant, ev, cookie);
+ } else {
+ const ui64 intrasecond = AlignUp<ui64>(instant, IntrasecondThreshold);
+ TAutoPtr<TMomentMap>& msec = ScheduleMap[intrasecond];
+ if (!msec)
+ msec.Reset(new TMomentMap());
+ TAutoPtr<NSchedulerQueue::TQueueType>& queue = (*msec)[instant];
+ if (!queue)
+ queue.Reset(new NSchedulerQueue::TQueueType());
+ queue->Writer.Push(instant, ev, cookie);
+ }
+ ++eventsGottenFromQueues;
+ TryUpdateTime(&lastTimeUpdate);
}
}
- ui64 eventSchedulingErrorUs = 0;
- // send everything triggered on schedule
- for (;;) {
- while (!!ActiveSec && !ActiveSec->empty()) {
- TMomentMap::iterator it = ActiveSec->begin();
- if (it->first <= MonotonicTime) {
- if (NSchedulerQueue::TQueueType* q = it->second.Get()) {
- while (NSchedulerQueue::TEntry* x = q->Reader.Pop()) {
- Y_VERIFY_DEBUG(x->InstantMicroseconds <= ActiveTick);
- if (eventSchedulingErrorUs == 0 && MonotonicTime > x->InstantMicroseconds) {
- eventSchedulingErrorUs = MonotonicTime - x->InstantMicroseconds;
- }
- IEventHandle* ev = x->Ev;
- ISchedulerCookie* cookie = x->Cookie;
- if (cookie) {
- if (cookie->Detach()) {
- EventsToBeSent.push_back(ev);
- } else {
- delete ev;
- }
- } else {
+ ui64 eventSchedulingErrorUs = 0;
+ // send everything triggered on schedule
+ for (;;) {
+ while (!!ActiveSec && !ActiveSec->empty()) {
+ TMomentMap::iterator it = ActiveSec->begin();
+ if (it->first <= MonotonicTime) {
+ if (NSchedulerQueue::TQueueType* q = it->second.Get()) {
+ while (NSchedulerQueue::TEntry* x = q->Reader.Pop()) {
+ Y_VERIFY_DEBUG(x->InstantMicroseconds <= ActiveTick);
+ if (eventSchedulingErrorUs == 0 && MonotonicTime > x->InstantMicroseconds) {
+ eventSchedulingErrorUs = MonotonicTime - x->InstantMicroseconds;
+ }
+ IEventHandle* ev = x->Ev;
+ ISchedulerCookie* cookie = x->Cookie;
+ if (cookie) {
+ if (cookie->Detach()) {
+ EventsToBeSent.push_back(ev);
+ } else {
+ delete ev;
+ }
+ } else {
EventsToBeSent.push_back(ev);
}
- TryUpdateTime(&lastTimeUpdate);
+ TryUpdateTime(&lastTimeUpdate);
}
}
- ActiveSec->erase(it);
- } else {
- break;
+ ActiveSec->erase(it);
+ } else {
+ break;
}
}
- if (ActiveTick <= MonotonicTime) {
- Y_VERIFY_DEBUG(!ActiveSec || ActiveSec->empty());
- ActiveSec.Destroy();
- ActiveTick += IntrasecondThreshold;
- TScheduleMap::iterator it = ScheduleMap.find(ActiveTick);
- if (it != ScheduleMap.end()) {
- ActiveSec = it->second;
- ScheduleMap.erase(it);
- }
- continue;
+ if (ActiveTick <= MonotonicTime) {
+ Y_VERIFY_DEBUG(!ActiveSec || ActiveSec->empty());
+ ActiveSec.Destroy();
+ ActiveTick += IntrasecondThreshold;
+ TScheduleMap::iterator it = ScheduleMap.find(ActiveTick);
+ if (it != ScheduleMap.end()) {
+ ActiveSec = it->second;
+ ScheduleMap.erase(it);
+ }
+ continue;
}
-
- // ok, if we are here - then nothing is ready, so send step complete
- break;
- }
-
- // Send all from buffer queue
- const ui64 eventsToBeSentSize = EventsToBeSent.size();
- ui32 sentCount = 0;
- if (eventsToBeSentSize > Cfg.RelaxedSendThresholdEventsPerCycle) {
- sentCount = Cfg.RelaxedSendPaceEventsPerCycle +
- (eventsToBeSentSize - Cfg.RelaxedSendThresholdEventsPerCycle) / 2;
- } else {
- sentCount = Min(eventsToBeSentSize, Cfg.RelaxedSendPaceEventsPerCycle);
- }
- for (ui32 i = 0; i < sentCount; ++i) {
- ctx.Send(EventsToBeSent.front());
- EventsToBeSent.pop_front();
+
+ // ok, if we are here - then nothing is ready, so send step complete
+ break;
}
- NHPTimer::STime hpnow;
- GetTimeFast(&hpnow);
- const ui64 processingTime = hpnow > schedulingStart ? hpnow - schedulingStart : 0;
- const ui64 elapsedTimeMicroseconds = processingTime / (NHPTimer::GetCyclesPerSecond() / IntrasecondThreshold);
- LWPROBE(ActorsystemScheduler, elapsedTimeMicroseconds, expired, eventsGottenFromQueues, sentCount,
- eventsToBeSentSize, eventSchedulingErrorUs);
- TryUpdateTime(&lastTimeUpdate);
+ // Send all from buffer queue
+ const ui64 eventsToBeSentSize = EventsToBeSent.size();
+ ui32 sentCount = 0;
+ if (eventsToBeSentSize > Cfg.RelaxedSendThresholdEventsPerCycle) {
+ sentCount = Cfg.RelaxedSendPaceEventsPerCycle +
+ (eventsToBeSentSize - Cfg.RelaxedSendThresholdEventsPerCycle) / 2;
+ } else {
+ sentCount = Min(eventsToBeSentSize, Cfg.RelaxedSendPaceEventsPerCycle);
+ }
+ for (ui32 i = 0; i < sentCount; ++i) {
+ ctx.Send(EventsToBeSent.front());
+ EventsToBeSent.pop_front();
+ }
+
+ NHPTimer::STime hpnow;
+ GetTimeFast(&hpnow);
+ const ui64 processingTime = hpnow > schedulingStart ? hpnow - schedulingStart : 0;
+ const ui64 elapsedTimeMicroseconds = processingTime / (NHPTimer::GetCyclesPerSecond() / IntrasecondThreshold);
+ LWPROBE(ActorsystemScheduler, elapsedTimeMicroseconds, expired, eventsGottenFromQueues, sentCount,
+ eventsToBeSentSize, eventSchedulingErrorUs);
+ TryUpdateTime(&lastTimeUpdate);
}
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSchedulerInitialize, Handle)
- CFunc(TEvPollerReady::EventType, HandleSchedule)
- CFunc(TEvents::TSystem::PoisonPill, Die)
- HFunc(TEvPollerRegisterResult, Handle)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSchedulerInitialize, Handle)
+ CFunc(TEvPollerReady::EventType, HandleSchedule)
+ CFunc(TEvents::TSystem::PoisonPill, Die)
+ HFunc(TEvPollerRegisterResult, Handle)
+ )
};
IActor* CreateSchedulerActor(const TSchedulerConfig& cfg) {
diff --git a/library/cpp/actors/core/ut/ya.make b/library/cpp/actors/core/ut/ya.make
index 3ee28d58503..b3958720a26 100644
--- a/library/cpp/actors/core/ut/ya.make
+++ b/library/cpp/actors/core/ut/ya.make
@@ -1,11 +1,11 @@
UNITTEST_FOR(library/cpp/actors/core)
-
+
OWNER(
alexvru
g:kikimr
)
-
-FORK_SUBTESTS()
+
+FORK_SUBTESTS()
IF (SANITIZER_TYPE)
SIZE(LARGE)
TIMEOUT(1200)
@@ -28,19 +28,19 @@ PEERDIR(
library/cpp/actors/testlib
)
-SRCS(
+SRCS(
actor_coroutine_ut.cpp
actor_ut.cpp
actorsystem_ut.cpp
ask_ut.cpp
balancer_ut.cpp
event_pb_payload_ut.cpp
- event_pb_ut.cpp
+ event_pb_ut.cpp
executor_pool_basic_ut.cpp
executor_pool_united_ut.cpp
log_ut.cpp
memory_tracker_ut.cpp
scheduler_actor_ut.cpp
-)
-
-END()
+)
+
+END()
diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make
index 880a9d00dba..9b51c56d521 100644
--- a/library/cpp/actors/core/ya.make
+++ b/library/cpp/actors/core/ya.make
@@ -20,13 +20,13 @@ ENDIF()
SRCS(
actor_bootstrapped.h
- actor_coroutine.cpp
- actor_coroutine.h
- actor.cpp
- actor.h
- actorid.cpp
+ actor_coroutine.cpp
+ actor_coroutine.h
+ actor.cpp
+ actor.h
+ actorid.cpp
actorid.h
- actorsystem.cpp
+ actorsystem.cpp
actorsystem.h
ask.cpp
ask.h
@@ -41,15 +41,15 @@ SRCS(
cpu_manager.h
cpu_state.h
defs.h
- event.cpp
+ event.cpp
event.h
- event_load.h
- event_local.h
+ event_load.h
+ event_local.h
event_pb.cpp
event_pb.h
events.h
events_undelivered.cpp
- executelater.h
+ executelater.h
executor_pool_base.cpp
executor_pool_base.h
executor_pool_basic.cpp
@@ -61,17 +61,17 @@ SRCS(
executor_thread.cpp
executor_thread.h
hfunc.h
- interconnect.cpp
+ interconnect.cpp
interconnect.h
- invoke.h
- io_dispatcher.cpp
- io_dispatcher.h
+ invoke.h
+ io_dispatcher.cpp
+ io_dispatcher.h
lease.h
log.cpp
log.h
log_settings.cpp
log_settings.h
- mailbox.cpp
+ mailbox.cpp
mailbox.h
mailbox_queue_revolving.h
mailbox_queue_simple.h
@@ -85,7 +85,7 @@ SRCS(
monotonic.h
worker_context.cpp
worker_context.h
- probes.cpp
+ probes.cpp
probes.h
process_stats.cpp
process_stats.h
diff --git a/library/cpp/actors/helpers/activeactors.h b/library/cpp/actors/helpers/activeactors.h
index 0fdb0fab108..9f8f6a28208 100644
--- a/library/cpp/actors/helpers/activeactors.h
+++ b/library/cpp/actors/helpers/activeactors.h
@@ -1,11 +1,11 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/events.h>
#include <util/generic/hash_set.h>
-
+
namespace NActors {
-
+
////////////////////////////////////////////////////////////////////////////
// TActiveActors
// This class helps manage created actors and kill them all on PoisonPill.
@@ -38,5 +38,5 @@ namespace NActors {
}
};
-} // NKikimr
+} // NKikimr
diff --git a/library/cpp/actors/helpers/mon_histogram_helper.h b/library/cpp/actors/helpers/mon_histogram_helper.h
index a9a57e38238..dade3c6506c 100644
--- a/library/cpp/actors/helpers/mon_histogram_helper.h
+++ b/library/cpp/actors/helpers/mon_histogram_helper.h
@@ -1,7 +1,7 @@
#pragma once
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
+
#include <util/string/cast.h>
namespace NActors {
@@ -14,8 +14,8 @@ namespace NActors {
{
}
- THistogramCounterHelper(const THistogramCounterHelper&) = default;
-
+ THistogramCounterHelper(const THistogramCounterHelper&) = default;
+
void Init(NMonitoring::TDynamicCounters* group, const TString& baseName, const TString& unit,
ui64 firstBucket, ui64 bucketCnt, bool useSensorLabelName = true)
{
diff --git a/library/cpp/actors/helpers/selfping_actor.cpp b/library/cpp/actors/helpers/selfping_actor.cpp
index f9bfaf8dc09..97f9c0a856d 100644
--- a/library/cpp/actors/helpers/selfping_actor.cpp
+++ b/library/cpp/actors/helpers/selfping_actor.cpp
@@ -1,15 +1,15 @@
-#include "selfping_actor.h"
-
+#include "selfping_actor.h"
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
-
+
#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <library/cpp/sliding_window/sliding_window.h>
-
-namespace NActors {
-
-namespace {
-
+
+namespace NActors {
+
+namespace {
+
struct TEvPing: public TEventLocal<TEvPing, TEvents::THelloWorld::Ping> {
TEvPing(double timeStart)
: TimeStart(timeStart)
@@ -58,47 +58,47 @@ struct TAvgOperation {
};
-class TSelfPingActor : public TActorBootstrapped<TSelfPingActor> {
-private:
- const TDuration SendInterval;
- const NMonitoring::TDynamicCounters::TCounterPtr Counter;
+class TSelfPingActor : public TActorBootstrapped<TSelfPingActor> {
+private:
+ const TDuration SendInterval;
+ const NMonitoring::TDynamicCounters::TCounterPtr Counter;
const NMonitoring::TDynamicCounters::TCounterPtr CalculationTimeCounter;
-
+
NSlidingWindow::TSlidingWindow<NSlidingWindow::TMaxOperation<ui64>> SlidingWindow;
NSlidingWindow::TSlidingWindow<TAvgOperation<ui64>> CalculationSlidingWindow;
-
+
THPTimer Timer;
-public:
+public:
static constexpr auto ActorActivityType() {
return SELF_PING_ACTOR;
}
TSelfPingActor(TDuration sendInterval, const NMonitoring::TDynamicCounters::TCounterPtr& counter,
const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter)
- : SendInterval(sendInterval)
- , Counter(counter)
+ : SendInterval(sendInterval)
+ , Counter(counter)
, CalculationTimeCounter(calculationTimeCounter)
- , SlidingWindow(TDuration::Seconds(15), 100)
+ , SlidingWindow(TDuration::Seconds(15), 100)
, CalculationSlidingWindow(TDuration::Seconds(15), 100)
- {
- }
-
- void Bootstrap(const TActorContext& ctx)
- {
- Become(&TSelfPingActor::RunningState);
+ {
+ }
+
+ void Bootstrap(const TActorContext& ctx)
+ {
+ Become(&TSelfPingActor::RunningState);
SchedulePing(ctx, Timer.Passed());
- }
-
- STFUNC(RunningState)
- {
- switch (ev->GetTypeRewrite()) {
+ }
+
+ STFUNC(RunningState)
+ {
+ switch (ev->GetTypeRewrite()) {
HFunc(TEvPing, HandlePing);
- default:
- Y_FAIL("TSelfPingActor::RunningState: unexpected event 0x%08" PRIx32, ev->GetTypeRewrite());
- }
- }
-
+ default:
+ Y_FAIL("TSelfPingActor::RunningState: unexpected event 0x%08" PRIx32, ev->GetTypeRewrite());
+ }
+ }
+
ui64 MeasureTaskDurationNs() {
// Prepare worm test data
// 11 * 11 * 3 * 8 = 2904 bytes, fits in L1 cache
@@ -147,37 +147,37 @@ public:
}
void HandlePing(TEvPing::TPtr &ev, const TActorContext &ctx)
- {
+ {
const auto now = ctx.Now();
const double hpNow = Timer.Passed();
- const auto& e = *ev->Get();
+ const auto& e = *ev->Get();
const double passedTime = hpNow - e.TimeStart;
const ui64 delayUs = passedTime > 0.0 ? static_cast<ui64>(passedTime * 1e6) : 0;
-
+
*Counter = SlidingWindow.Update(delayUs, now);
-
+
ui64 d = MeasureTaskDurationNs();
auto res = CalculationSlidingWindow.Update({1, d}, now);
*CalculationTimeCounter = double(res.Sum) / double(res.Count + 1);
SchedulePing(ctx, hpNow);
- }
-
-private:
+ }
+
+private:
void SchedulePing(const TActorContext &ctx, double hpNow) const
- {
+ {
ctx.Schedule(SendInterval, new TEvPing(hpNow));
- }
-};
-
-} // namespace
-
-IActor* CreateSelfPingActor(
- TDuration sendInterval,
+ }
+};
+
+} // namespace
+
+IActor* CreateSelfPingActor(
+ TDuration sendInterval,
const NMonitoring::TDynamicCounters::TCounterPtr& counter,
const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter)
-{
+{
return new TSelfPingActor(sendInterval, counter, calculationTimeCounter);
-}
-
-} // NActors
+}
+
+} // NActors
diff --git a/library/cpp/actors/helpers/selfping_actor.h b/library/cpp/actors/helpers/selfping_actor.h
index d7d07f9fa8b..945863d81d8 100644
--- a/library/cpp/actors/helpers/selfping_actor.h
+++ b/library/cpp/actors/helpers/selfping_actor.h
@@ -1,13 +1,13 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NActors {
-
-NActors::IActor* CreateSelfPingActor(
- TDuration sendInterval,
+
+namespace NActors {
+
+NActors::IActor* CreateSelfPingActor(
+ TDuration sendInterval,
const NMonitoring::TDynamicCounters::TCounterPtr& counter,
const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter);
-
-} // NActors
+
+} // NActors
diff --git a/library/cpp/actors/helpers/selfping_actor_ut.cpp b/library/cpp/actors/helpers/selfping_actor_ut.cpp
index 459635fa24a..1959ace6383 100644
--- a/library/cpp/actors/helpers/selfping_actor_ut.cpp
+++ b/library/cpp/actors/helpers/selfping_actor_ut.cpp
@@ -1,11 +1,11 @@
-#include "selfping_actor.h"
-
+#include "selfping_actor.h"
+
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/actors/testlib/test_runtime.h>
-
-namespace NActors {
-namespace Tests {
-
+
+namespace NActors {
+namespace Tests {
+
THolder<TTestActorRuntimeBase> CreateRuntime() {
auto runtime = MakeHolder<TTestActorRuntimeBase>();
runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; });
@@ -15,31 +15,31 @@ THolder<TTestActorRuntimeBase> CreateRuntime() {
Y_UNIT_TEST_SUITE(TSelfPingTest) {
Y_UNIT_TEST(Basic)
- {
+ {
auto runtime = CreateRuntime();
-
+
//const TActorId sender = runtime.AllocateEdgeActor();
-
- NMonitoring::TDynamicCounters::TCounterPtr counter(new NMonitoring::TCounterForPtr());
+
+ NMonitoring::TDynamicCounters::TCounterPtr counter(new NMonitoring::TCounterForPtr());
NMonitoring::TDynamicCounters::TCounterPtr counter2(new NMonitoring::TCounterForPtr());
-
- auto actor = CreateSelfPingActor(
- TDuration::MilliSeconds(100), // sendInterval (unused in test)
+
+ auto actor = CreateSelfPingActor(
+ TDuration::MilliSeconds(100), // sendInterval (unused in test)
counter, counter2);
-
+
UNIT_ASSERT_VALUES_EQUAL(counter->Val(), 0);
UNIT_ASSERT_VALUES_EQUAL(counter2->Val(), 0);
const TActorId actorId = runtime->Register(actor);
Y_UNUSED(actorId);
-
+
//runtime.Send(new IEventHandle(actorId, sender, new TEvSelfPing::TEvPing(0.0)));
-
- // TODO check after events are handled
- //Sleep(TDuration::Seconds(1));
- //UNIT_ASSERT((intmax_t)counter->Val() >= (intmax_t)Delay.MicroSeconds());
- }
-}
-
-} // namespace Tests
-} // namespace NActors
+
+ // TODO check after events are handled
+ //Sleep(TDuration::Seconds(1));
+ //UNIT_ASSERT((intmax_t)counter->Val() >= (intmax_t)Delay.MicroSeconds());
+ }
+}
+
+} // namespace Tests
+} // namespace NActors
diff --git a/library/cpp/actors/http/http.h b/library/cpp/actors/http/http.h
index 96c5c1ec48e..311c8175566 100644
--- a/library/cpp/actors/http/http.h
+++ b/library/cpp/actors/http/http.h
@@ -62,7 +62,7 @@ struct TCookies {
};
struct TCookiesBuilder : TCookies {
- TDeque<std::pair<TString, TString>> Data;
+ TDeque<std::pair<TString, TString>> Data;
TCookiesBuilder();
void Set(TStringBuf name, TStringBuf data);
diff --git a/library/cpp/actors/http/http_proxy_acceptor.cpp b/library/cpp/actors/http/http_proxy_acceptor.cpp
index 9780541b71f..e94073c4180 100644
--- a/library/cpp/actors/http/http_proxy_acceptor.cpp
+++ b/library/cpp/actors/http/http_proxy_acceptor.cpp
@@ -10,7 +10,7 @@ public:
const TActorId Owner;
const TActorId Poller;
TIntrusivePtr<TSocketDescriptor> Socket;
- NActors::TPollerToken::TPtr PollerToken;
+ NActors::TPollerToken::TPtr PollerToken;
THashSet<TActorId> Connections;
TDeque<THttpIncomingRequestPtr> RecycledRequests;
TEndpointInfo Endpoint;
@@ -31,8 +31,8 @@ public:
protected:
STFUNC(StateListening) {
switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerRegisterResult, Handle);
- HFunc(NActors::TEvPollerReady, Handle);
+ HFunc(NActors::TEvPollerRegisterResult, Handle);
+ HFunc(NActors::TEvPollerReady, Handle);
HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
HFunc(TEvHttpProxy::TEvReportSensors, Handle);
}
@@ -70,7 +70,7 @@ protected:
if (err == 0) {
LOG_INFO_S(ctx, HttpLog, "Listening on " << bindAddress.ToString());
SetNonBlock(Socket->Socket);
- ctx.Send(Poller, new NActors::TEvPollerRegister(Socket, SelfId(), SelfId()));
+ ctx.Send(Poller, new NActors::TEvPollerRegister(Socket, SelfId(), SelfId()));
TBase::Become(&TAcceptorActor::StateListening);
ctx.Send(event->Sender, new TEvHttpProxy::TEvConfirmListen(bindAddress), 0, event->Cookie);
return;
@@ -87,16 +87,16 @@ protected:
}
}
- void Handle(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& /*ctx*/) {
- PollerToken = std::move(ev->Get()->PollerToken);
- PollerToken->Request(true, false); // request read polling
- }
-
- void Handle(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
+ void Handle(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& /*ctx*/) {
+ PollerToken = std::move(ev->Get()->PollerToken);
+ PollerToken->Request(true, false); // request read polling
+ }
+
+ void Handle(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
TIntrusivePtr<TSocketDescriptor> socket = new TSocketDescriptor();
SocketAddressType addr;
- int err;
- while ((err = Socket->Socket.Accept(&socket->Socket, &addr)) == 0) {
+ int err;
+ while ((err = Socket->Socket.Accept(&socket->Socket, &addr)) == 0) {
NActors::IActor* connectionSocket = nullptr;
if (RecycledRequests.empty()) {
connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr);
@@ -105,14 +105,14 @@ protected:
RecycledRequests.pop_front();
}
NActors::TActorId connectionId = ctx.Register(connectionSocket);
- ctx.Send(Poller, new NActors::TEvPollerRegister(socket, connectionId, connectionId));
+ ctx.Send(Poller, new NActors::TEvPollerRegister(socket, connectionId, connectionId));
Connections.emplace(connectionId);
socket = new TSocketDescriptor();
}
- if (err == -EAGAIN || err == -EWOULDBLOCK) { // request poller for further connection polling
- Y_VERIFY(PollerToken);
- PollerToken->Request(true, false);
- }
+ if (err == -EAGAIN || err == -EWOULDBLOCK) { // request poller for further connection polling
+ Y_VERIFY(PollerToken);
+ PollerToken->Request(true, false);
+ }
}
void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
diff --git a/library/cpp/actors/http/http_proxy_incoming.cpp b/library/cpp/actors/http/http_proxy_incoming.cpp
index 80fe2af53d0..7aca73a8add 100644
--- a/library/cpp/actors/http/http_proxy_incoming.cpp
+++ b/library/cpp/actors/http/http_proxy_incoming.cpp
@@ -3,8 +3,8 @@
namespace NHttp {
-using namespace NActors;
-
+using namespace NActors;
+
template <typename TSocketImpl>
class TIncomingConnectionActor : public TActor<TIncomingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
public:
@@ -19,12 +19,12 @@ public:
THttpOutgoingResponsePtr CurrentResponse;
TDeque<THttpIncomingRequestPtr> RecycledRequests;
- THPTimer InactivityTimer;
+ THPTimer InactivityTimer;
static constexpr TDuration InactivityTimeout = TDuration::Minutes(2);
- TEvPollerReady* InactivityEvent = nullptr;
-
- TPollerToken::TPtr PollerToken;
-
+ TEvPollerReady* InactivityEvent = nullptr;
+
+ TPollerToken::TPtr PollerToken;
+
TIncomingConnectionActor(
const TEndpointInfo& endpoint,
TIntrusivePtr<TSocketDescriptor> socket,
@@ -57,9 +57,9 @@ public:
}
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override {
- return new IEventHandle(self, parent, new TEvents::TEvBootstrap());
- }
-
+ return new IEventHandle(self, parent, new TEvents::TEvBootstrap());
+ }
+
void Die(const TActorContext& ctx) override {
ctx.Send(Endpoint.Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID, std::move(RecycledRequests)));
TSocketImpl::Shutdown();
@@ -67,117 +67,117 @@ public:
}
protected:
- void Bootstrap(const TActorContext& ctx) {
- InactivityTimer.Reset();
- ctx.Schedule(InactivityTimeout, InactivityEvent = new TEvPollerReady(nullptr, false, false));
+ void Bootstrap(const TActorContext& ctx) {
+ InactivityTimer.Reset();
+ ctx.Schedule(InactivityTimeout, InactivityEvent = new TEvPollerReady(nullptr, false, false));
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") incoming connection opened");
OnAccept(ctx);
- }
-
+ }
+
void OnAccept(const NActors::TActorContext& ctx) {
- int res;
- bool read = false, write = false;
- if ((res = TSocketImpl::OnAccept(Endpoint, read, write)) != 1) {
- if (-res == EAGAIN) {
- if (PollerToken) {
- PollerToken->Request(read, write);
- }
- return; // wait for further notifications
- } else {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Accept: " << strerror(-res));
- return Die(ctx);
+ int res;
+ bool read = false, write = false;
+ if ((res = TSocketImpl::OnAccept(Endpoint, read, write)) != 1) {
+ if (-res == EAGAIN) {
+ if (PollerToken) {
+ PollerToken->Request(read, write);
+ }
+ return; // wait for further notifications
+ } else {
+ LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Accept: " << strerror(-res));
+ return Die(ctx);
}
}
TBase::Become(&TIncomingConnectionActor::StateConnected);
- ctx.Send(ctx.SelfID, new TEvPollerReady(nullptr, true, true));
+ ctx.Send(ctx.SelfID, new TEvPollerReady(nullptr, true, true));
}
- void HandleAccepting(TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
- PollerToken = std::move(ev->Get()->PollerToken);
+ void HandleAccepting(TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
+ PollerToken = std::move(ev->Get()->PollerToken);
OnAccept(ctx);
}
- void HandleAccepting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
+ void HandleAccepting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
OnAccept(ctx);
}
- void HandleConnected(TEvPollerReady::TPtr event, const TActorContext& ctx) {
- if (event->Get()->Read) {
- for (;;) {
- if (CurrentRequest == nullptr) {
- if (RecycleRequests && !RecycledRequests.empty()) {
- CurrentRequest = std::move(RecycledRequests.front());
- RecycledRequests.pop_front();
- } else {
- CurrentRequest = new THttpIncomingRequest();
- }
- CurrentRequest->Address = Address;
- CurrentRequest->WorkerName = Endpoint.WorkerName;
+ void HandleConnected(TEvPollerReady::TPtr event, const TActorContext& ctx) {
+ if (event->Get()->Read) {
+ for (;;) {
+ if (CurrentRequest == nullptr) {
+ if (RecycleRequests && !RecycledRequests.empty()) {
+ CurrentRequest = std::move(RecycledRequests.front());
+ RecycledRequests.pop_front();
+ } else {
+ CurrentRequest = new THttpIncomingRequest();
+ }
+ CurrentRequest->Address = Address;
+ CurrentRequest->WorkerName = Endpoint.WorkerName;
CurrentRequest->Secure = Endpoint.Secure;
}
- if (!CurrentRequest->EnsureEnoughSpaceAvailable()) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - not enough space available");
- return Die(ctx);
- }
- ssize_t need = CurrentRequest->Avail();
- bool read = false, write = false;
- ssize_t res = TSocketImpl::Recv(CurrentRequest->Pos(), need, read, write);
- if (res > 0) {
- InactivityTimer.Reset();
- CurrentRequest->Advance(res);
- if (CurrentRequest->IsDone()) {
- Requests.emplace_back(CurrentRequest);
- CurrentRequest->Timer.Reset();
- if (CurrentRequest->IsReady()) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -> (" << CurrentRequest->Method << " " << CurrentRequest->URL << ")");
- ctx.Send(Endpoint.Proxy, new TEvHttpProxy::TEvHttpIncomingRequest(CurrentRequest));
- CurrentRequest = nullptr;
- } else if (CurrentRequest->IsError()) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -! (" << CurrentRequest->Method << " " << CurrentRequest->URL << ")");
+ if (!CurrentRequest->EnsureEnoughSpaceAvailable()) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - not enough space available");
+ return Die(ctx);
+ }
+ ssize_t need = CurrentRequest->Avail();
+ bool read = false, write = false;
+ ssize_t res = TSocketImpl::Recv(CurrentRequest->Pos(), need, read, write);
+ if (res > 0) {
+ InactivityTimer.Reset();
+ CurrentRequest->Advance(res);
+ if (CurrentRequest->IsDone()) {
+ Requests.emplace_back(CurrentRequest);
+ CurrentRequest->Timer.Reset();
+ if (CurrentRequest->IsReady()) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -> (" << CurrentRequest->Method << " " << CurrentRequest->URL << ")");
+ ctx.Send(Endpoint.Proxy, new TEvHttpProxy::TEvHttpIncomingRequest(CurrentRequest));
+ CurrentRequest = nullptr;
+ } else if (CurrentRequest->IsError()) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -! (" << CurrentRequest->Method << " " << CurrentRequest->URL << ")");
bool success = Respond(CurrentRequest->CreateResponseBadRequest(), ctx);
if (!success) {
return;
}
- CurrentRequest = nullptr;
- }
- }
- } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
- if (PollerToken) {
- if (!read && !write) {
- read = true;
- }
- PollerToken->Request(read, write);
+ CurrentRequest = nullptr;
+ }
}
+ } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
+ if (PollerToken) {
+ if (!read && !write) {
+ read = true;
+ }
+ PollerToken->Request(read, write);
+ }
break;
- } else if (-res == EINTR) {
- continue;
- } else if (!res) {
- // connection closed
+ } else if (-res == EINTR) {
+ continue;
+ } else if (!res) {
+ // connection closed
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
return Die(ctx);
- } else {
+ } else {
LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Receive: " << strerror(-res));
return Die(ctx);
}
}
- if (event->Get() == InactivityEvent) {
- const TDuration passed = TDuration::Seconds(std::abs(InactivityTimer.Passed()));
- if (passed >= InactivityTimeout) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed by inactivity timeout");
- return Die(ctx); // timeout
- } else {
- ctx.Schedule(InactivityTimeout - passed, InactivityEvent = new TEvPollerReady(nullptr, false, false));
- }
- }
- }
- if (event->Get()->Write) {
- FlushOutput(ctx);
- }
+ if (event->Get() == InactivityEvent) {
+ const TDuration passed = TDuration::Seconds(std::abs(InactivityTimer.Passed()));
+ if (passed >= InactivityTimeout) {
+ LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed by inactivity timeout");
+ return Die(ctx); // timeout
+ } else {
+ ctx.Schedule(InactivityTimeout - passed, InactivityEvent = new TEvPollerReady(nullptr, false, false));
+ }
+ }
+ }
+ if (event->Get()->Write) {
+ FlushOutput(ctx);
+ }
}
- void HandleConnected(TEvPollerRegisterResult::TPtr ev, const TActorContext& /*ctx*/) {
- PollerToken = std::move(ev->Get()->PollerToken);
- PollerToken->Request(true, true);
+ void HandleConnected(TEvPollerRegisterResult::TPtr ev, const TActorContext& /*ctx*/) {
+ PollerToken = std::move(ev->Get()->PollerToken);
+ PollerToken->Request(true, true);
}
void HandleConnected(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const TActorContext& ctx) {
@@ -246,23 +246,23 @@ protected:
}
}
}
- bool read = false, write = false;
- ssize_t res = TSocketImpl::Send(CurrentResponse->Data(), size, read, write);
+ bool read = false, write = false;
+ ssize_t res = TSocketImpl::Send(CurrentResponse->Data(), size, read, write);
if (res > 0) {
CurrentResponse->ChopHead(res);
- } else if (-res == EINTR) {
- continue;
- } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
- if (PollerToken) {
- if (!read && !write) {
- write = true;
- }
- PollerToken->Request(read, write);
+ } else if (-res == EINTR) {
+ continue;
+ } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
+ if (PollerToken) {
+ if (!read && !write) {
+ write = true;
+ }
+ PollerToken->Request(read, write);
}
break;
- } else {
- CleanupResponse(CurrentResponse);
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in FlushOutput: " << strerror(-res));
+ } else {
+ CleanupResponse(CurrentResponse);
+ LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in FlushOutput: " << strerror(-res));
Die(ctx);
return false;
}
@@ -272,17 +272,17 @@ protected:
STFUNC(StateAccepting) {
switch (ev->GetTypeRewrite()) {
- CFunc(TEvents::TEvBootstrap::EventType, Bootstrap);
- HFunc(TEvPollerReady, HandleAccepting);
- HFunc(TEvPollerRegisterResult, HandleAccepting);
+ CFunc(TEvents::TEvBootstrap::EventType, Bootstrap);
+ HFunc(TEvPollerReady, HandleAccepting);
+ HFunc(TEvPollerRegisterResult, HandleAccepting);
}
}
STFUNC(StateConnected) {
switch (ev->GetTypeRewrite()) {
- HFunc(TEvPollerReady, HandleConnected);
+ HFunc(TEvPollerReady, HandleConnected);
HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, HandleConnected);
- HFunc(TEvPollerRegisterResult, HandleConnected);
+ HFunc(TEvPollerRegisterResult, HandleConnected);
}
}
};
diff --git a/library/cpp/actors/http/http_proxy_outgoing.cpp b/library/cpp/actors/http/http_proxy_outgoing.cpp
index d9189dba8ab..e2a8c2c4330 100644
--- a/library/cpp/actors/http/http_proxy_outgoing.cpp
+++ b/library/cpp/actors/http/http_proxy_outgoing.cpp
@@ -17,7 +17,7 @@ public:
THttpIncomingResponsePtr Response;
TInstant LastActivity;
TDuration ConnectionTimeout = CONNECTION_TIMEOUT;
- NActors::TPollerToken::TPtr PollerToken;
+ NActors::TPollerToken::TPtr PollerToken;
TOutgoingConnectionActor(const TActorId& owner, const TString& host, const TActorId& poller)
: TBase(&TSelf::StateWaiting)
@@ -82,90 +82,90 @@ protected:
void FlushOutput(const NActors::TActorContext& ctx) {
if (Request != nullptr) {
Request->Finish();
- while (auto size = Request->Size()) {
- bool read = false, write = false;
- ssize_t res = TSocketImpl::Send(Request->Data(), size, read, write);
+ while (auto size = Request->Size()) {
+ bool read = false, write = false;
+ ssize_t res = TSocketImpl::Send(Request->Data(), size, read, write);
if (res > 0) {
Request->ChopHead(res);
- } else if (-res == EINTR) {
- continue;
- } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
- if (PollerToken) {
- if (!read && !write) {
- write = true;
- }
- PollerToken->Request(read, write);
- }
- break;
+ } else if (-res == EINTR) {
+ continue;
+ } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
+ if (PollerToken) {
+ if (!read && !write) {
+ write = true;
+ }
+ PollerToken->Request(read, write);
+ }
+ break;
} else {
- if (!res) {
+ if (!res) {
ReplyAndDie(ctx);
- } else {
+ } else {
ReplyErrorAndDie(ctx, strerror(-res));
}
- break;
+ break;
}
}
}
}
void PullInput(const NActors::TActorContext& ctx) {
- for (;;) {
+ for (;;) {
if (Response == nullptr) {
Response = new THttpIncomingResponse(Request);
}
if (!Response->EnsureEnoughSpaceAvailable()) {
return ReplyErrorAndDie(ctx, "Not enough space in socket buffer");
}
- bool read = false, write = false;
- ssize_t res = TSocketImpl::Recv(Response->Pos(), Response->Avail(), read, write);
+ bool read = false, write = false;
+ ssize_t res = TSocketImpl::Recv(Response->Pos(), Response->Avail(), read, write);
if (res > 0) {
Response->Advance(res);
- if (Response->IsDone() && Response->IsReady()) {
- return ReplyAndDie(ctx);
- }
- } else if (-res == EINTR) {
- continue;
- } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
- if (PollerToken) {
- if (!read && !write) {
- read = true;
+ if (Response->IsDone() && Response->IsReady()) {
+ return ReplyAndDie(ctx);
+ }
+ } else if (-res == EINTR) {
+ continue;
+ } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
+ if (PollerToken) {
+ if (!read && !write) {
+ read = true;
}
- PollerToken->Request(read, write);
+ PollerToken->Request(read, write);
}
- return;
+ return;
} else {
- if (!res) {
+ if (!res) {
Response->ConnectionClosed();
}
- if (Response->IsDone() && Response->IsReady()) {
- return ReplyAndDie(ctx);
- }
- return ReplyErrorAndDie(ctx, strerror(-res));
+ if (Response->IsDone() && Response->IsReady()) {
+ return ReplyAndDie(ctx);
+ }
+ return ReplyErrorAndDie(ctx, strerror(-res));
}
- }
+ }
}
void RegisterPoller(const NActors::TActorContext& ctx) {
- ctx.Send(Poller, new NActors::TEvPollerRegister(TSocketImpl::Socket, ctx.SelfID, ctx.SelfID));
+ ctx.Send(Poller, new NActors::TEvPollerRegister(TSocketImpl::Socket, ctx.SelfID, ctx.SelfID));
}
void OnConnect(const NActors::TActorContext& ctx) {
- bool read = false, write = false;
- if (int res = TSocketImpl::OnConnect(read, write); res != 1) {
- if (-res == EAGAIN) {
- if (PollerToken) {
- PollerToken->Request(read, write);
- }
+ bool read = false, write = false;
+ if (int res = TSocketImpl::OnConnect(read, write); res != 1) {
+ if (-res == EAGAIN) {
+ if (PollerToken) {
+ PollerToken->Request(read, write);
+ }
return;
- } else {
- return ReplyErrorAndDie(ctx, strerror(-res));
+ } else {
+ return ReplyErrorAndDie(ctx, strerror(-res));
}
}
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") outgoing connection opened");
TBase::Become(&TOutgoingConnectionActor::StateConnected);
LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << Request->Method << " " << Request->URL << ")");
- ctx.Send(ctx.SelfID, new NActors::TEvPollerReady(nullptr, true, true));
+ ctx.Send(ctx.SelfID, new NActors::TEvPollerReady(nullptr, true, true));
}
void HandleResolving(TEvHttpProxy::TEvResolveHostResponse::TPtr event, const NActors::TActorContext& ctx) {
@@ -180,7 +180,7 @@ protected:
Connect(ctx);
}
- void HandleConnecting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
+ void HandleConnecting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
LastActivity = ctx.Now();
int res = TSocketImpl::GetError();
if (res == 0) {
@@ -190,8 +190,8 @@ protected:
}
}
- void HandleConnecting(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
- PollerToken = std::move(ev->Get()->PollerToken);
+ void HandleConnecting(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
+ PollerToken = std::move(ev->Get()->PollerToken);
LastActivity = ctx.Now();
int res = TSocketImpl::GetError();
if (res == 0) {
@@ -218,20 +218,20 @@ protected:
TBase::Become(&TOutgoingConnectionActor::StateResolving);
}
- void HandleConnected(NActors::TEvPollerReady::TPtr event, const NActors::TActorContext& ctx) {
+ void HandleConnected(NActors::TEvPollerReady::TPtr event, const NActors::TActorContext& ctx) {
LastActivity = ctx.Now();
- if (event->Get()->Read) {
- PullInput(ctx);
- }
- if (event->Get()->Write) {
- FlushOutput(ctx);
+ if (event->Get()->Read) {
+ PullInput(ctx);
}
+ if (event->Get()->Write) {
+ FlushOutput(ctx);
+ }
}
- void HandleConnected(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
- PollerToken = std::move(ev->Get()->PollerToken);
+ void HandleConnected(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
+ PollerToken = std::move(ev->Get()->PollerToken);
LastActivity = ctx.Now();
- PullInput(ctx);
+ PullInput(ctx);
FlushOutput(ctx);
}
@@ -266,17 +266,17 @@ protected:
STFUNC(StateConnecting) {
switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerReady, HandleConnecting);
+ HFunc(NActors::TEvPollerReady, HandleConnecting);
CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- HFunc(NActors::TEvPollerRegisterResult, HandleConnecting);
+ HFunc(NActors::TEvPollerRegisterResult, HandleConnecting);
}
}
STFUNC(StateConnected) {
switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerReady, HandleConnected);
+ HFunc(NActors::TEvPollerReady, HandleConnected);
CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- HFunc(NActors::TEvPollerRegisterResult, HandleConnected);
+ HFunc(NActors::TEvPollerRegisterResult, HandleConnected);
}
}
diff --git a/library/cpp/actors/http/http_proxy_sock_impl.h b/library/cpp/actors/http/http_proxy_sock_impl.h
index bf8c71d05ad..edef338d71d 100644
--- a/library/cpp/actors/http/http_proxy_sock_impl.h
+++ b/library/cpp/actors/http/http_proxy_sock_impl.h
@@ -45,12 +45,12 @@ struct TPlainSocketImpl : virtual public THttpConfig {
return Socket->Socket.Connect(&address);
}
- static constexpr int OnConnect(bool&, bool&) {
- return 1;
+ static constexpr int OnConnect(bool&, bool&) {
+ return 1;
}
- static constexpr int OnAccept(const TEndpointInfo&, bool&, bool&) {
- return 1;
+ static constexpr int OnAccept(const TEndpointInfo&, bool&, bool&) {
+ return 1;
}
bool IsGood() {
@@ -65,11 +65,11 @@ struct TPlainSocketImpl : virtual public THttpConfig {
return res;
}
- ssize_t Send(const void* data, size_t size, bool&, bool&) {
+ ssize_t Send(const void* data, size_t size, bool&, bool&) {
return Socket->Socket.Send(data, size);
}
- ssize_t Recv(void* data, size_t size, bool&, bool&) {
+ ssize_t Recv(void* data, size_t size, bool&, bool&) {
return Socket->Socket.Recv(data, size);
}
};
@@ -180,16 +180,16 @@ struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
void Flush() {}
- ssize_t Send(const void* data, size_t size, bool& read, bool& write) {
+ ssize_t Send(const void* data, size_t size, bool& read, bool& write) {
ssize_t res = SSL_write(Ssl.Get(), data, size);
if (res < 0) {
res = SSL_get_error(Ssl.Get(), res);
switch(res) {
case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
+ read = true;
+ return -EAGAIN;
case SSL_ERROR_WANT_WRITE:
- write = true;
+ write = true;
return -EAGAIN;
default:
return -EIO;
@@ -198,16 +198,16 @@ struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
return res;
}
- ssize_t Recv(void* data, size_t size, bool& read, bool& write) {
+ ssize_t Recv(void* data, size_t size, bool& read, bool& write) {
ssize_t res = SSL_read(Ssl.Get(), data, size);
if (res < 0) {
res = SSL_get_error(Ssl.Get(), res);
switch(res) {
case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
+ read = true;
+ return -EAGAIN;
case SSL_ERROR_WANT_WRITE:
- write = true;
+ write = true;
return -EAGAIN;
default:
return -EIO;
@@ -216,19 +216,19 @@ struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
return res;
}
- int OnConnect(bool& read, bool& write) {
+ int OnConnect(bool& read, bool& write) {
if (!Ssl) {
InitClientSsl();
}
int res = SSL_connect(Ssl.Get());
- if (res <= 0) {
+ if (res <= 0) {
res = SSL_get_error(Ssl.Get(), res);
switch(res) {
case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
+ read = true;
+ return -EAGAIN;
case SSL_ERROR_WANT_WRITE:
- write = true;
+ write = true;
return -EAGAIN;
default:
return -EIO;
@@ -237,19 +237,19 @@ struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
return res;
}
- int OnAccept(const TEndpointInfo& endpoint, bool& read, bool& write) {
+ int OnAccept(const TEndpointInfo& endpoint, bool& read, bool& write) {
if (!Ssl) {
InitServerSsl(endpoint.SecureContext.Get());
}
int res = SSL_accept(Ssl.Get());
- if (res <= 0) {
+ if (res <= 0) {
res = SSL_get_error(Ssl.Get(), res);
switch(res) {
case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
+ read = true;
+ return -EAGAIN;
case SSL_ERROR_WANT_WRITE:
- write = true;
+ write = true;
return -EAGAIN;
default:
return -EIO;
diff --git a/library/cpp/actors/interconnect/channel_scheduler.h b/library/cpp/actors/interconnect/channel_scheduler.h
index 551a4cb61a1..da2fce0fd36 100644
--- a/library/cpp/actors/interconnect/channel_scheduler.h
+++ b/library/cpp/actors/interconnect/channel_scheduler.h
@@ -1,120 +1,120 @@
-#pragma once
-
-#include "interconnect_channel.h"
-#include "event_holder_pool.h"
-
+#pragma once
+
+#include "interconnect_channel.h"
+#include "event_holder_pool.h"
+
#include <memory>
-namespace NActors {
-
- class TChannelScheduler {
- const ui32 PeerNodeId;
- std::array<std::optional<TEventOutputChannel>, 16> ChannelArray;
- THashMap<ui16, TEventOutputChannel> ChannelMap;
+namespace NActors {
+
+ class TChannelScheduler {
+ const ui32 PeerNodeId;
+ std::array<std::optional<TEventOutputChannel>, 16> ChannelArray;
+ THashMap<ui16, TEventOutputChannel> ChannelMap;
std::shared_ptr<IInterconnectMetrics> Metrics;
- TEventHolderPool& Pool;
- const ui32 MaxSerializedEventSize;
- const TSessionParams Params;
-
- struct THeapItem {
- TEventOutputChannel *Channel;
- ui64 WeightConsumed = 0;
-
- friend bool operator <(const THeapItem& x, const THeapItem& y) {
- return x.WeightConsumed > y.WeightConsumed;
- }
- };
-
- std::vector<THeapItem> Heap;
-
- public:
- TChannelScheduler(ui32 peerNodeId, const TChannelsConfig& predefinedChannels,
+ TEventHolderPool& Pool;
+ const ui32 MaxSerializedEventSize;
+ const TSessionParams Params;
+
+ struct THeapItem {
+ TEventOutputChannel *Channel;
+ ui64 WeightConsumed = 0;
+
+ friend bool operator <(const THeapItem& x, const THeapItem& y) {
+ return x.WeightConsumed > y.WeightConsumed;
+ }
+ };
+
+ std::vector<THeapItem> Heap;
+
+ public:
+ TChannelScheduler(ui32 peerNodeId, const TChannelsConfig& predefinedChannels,
std::shared_ptr<IInterconnectMetrics> metrics, TEventHolderPool& pool, ui32 maxSerializedEventSize,
- TSessionParams params)
- : PeerNodeId(peerNodeId)
+ TSessionParams params)
+ : PeerNodeId(peerNodeId)
, Metrics(std::move(metrics))
- , Pool(pool)
- , MaxSerializedEventSize(maxSerializedEventSize)
- , Params(std::move(params))
- {
- for (const auto& item : predefinedChannels) {
- GetOutputChannel(item.first);
- }
- }
-
- TEventOutputChannel *PickChannelWithLeastConsumedWeight() {
- Y_VERIFY(!Heap.empty());
- return Heap.front().Channel;
- }
-
- void AddToHeap(TEventOutputChannel& channel, ui64 counter) {
- if (channel.IsWorking()) {
- ui64 weight = channel.WeightConsumedOnPause;
- weight -= Min(weight, counter - channel.EqualizeCounterOnPause);
- Heap.push_back(THeapItem{&channel, weight});
- std::push_heap(Heap.begin(), Heap.end());
- }
- }
-
- void FinishPick(ui64 weightConsumed, ui64 counter) {
- std::pop_heap(Heap.begin(), Heap.end());
- auto& item = Heap.back();
- item.WeightConsumed += weightConsumed;
- if (item.Channel->IsWorking()) { // reschedule
- std::push_heap(Heap.begin(), Heap.end());
- } else { // remove from heap
- item.Channel->EqualizeCounterOnPause = counter;
- item.Channel->WeightConsumedOnPause = item.WeightConsumed;
- Heap.pop_back();
- }
- }
-
- TEventOutputChannel& GetOutputChannel(ui16 channel) {
- if (channel < ChannelArray.size()) {
- auto& res = ChannelArray[channel];
- if (Y_UNLIKELY(!res)) {
+ , Pool(pool)
+ , MaxSerializedEventSize(maxSerializedEventSize)
+ , Params(std::move(params))
+ {
+ for (const auto& item : predefinedChannels) {
+ GetOutputChannel(item.first);
+ }
+ }
+
+ TEventOutputChannel *PickChannelWithLeastConsumedWeight() {
+ Y_VERIFY(!Heap.empty());
+ return Heap.front().Channel;
+ }
+
+ void AddToHeap(TEventOutputChannel& channel, ui64 counter) {
+ if (channel.IsWorking()) {
+ ui64 weight = channel.WeightConsumedOnPause;
+ weight -= Min(weight, counter - channel.EqualizeCounterOnPause);
+ Heap.push_back(THeapItem{&channel, weight});
+ std::push_heap(Heap.begin(), Heap.end());
+ }
+ }
+
+ void FinishPick(ui64 weightConsumed, ui64 counter) {
+ std::pop_heap(Heap.begin(), Heap.end());
+ auto& item = Heap.back();
+ item.WeightConsumed += weightConsumed;
+ if (item.Channel->IsWorking()) { // reschedule
+ std::push_heap(Heap.begin(), Heap.end());
+ } else { // remove from heap
+ item.Channel->EqualizeCounterOnPause = counter;
+ item.Channel->WeightConsumedOnPause = item.WeightConsumed;
+ Heap.pop_back();
+ }
+ }
+
+ TEventOutputChannel& GetOutputChannel(ui16 channel) {
+ if (channel < ChannelArray.size()) {
+ auto& res = ChannelArray[channel];
+ if (Y_UNLIKELY(!res)) {
res.emplace(Pool, channel, PeerNodeId, MaxSerializedEventSize, Metrics,
- Params);
- }
- return *res;
- } else {
- auto it = ChannelMap.find(channel);
- if (Y_UNLIKELY(it == ChannelMap.end())) {
- it = ChannelMap.emplace(std::piecewise_construct, std::forward_as_tuple(channel),
- std::forward_as_tuple(Pool, channel, PeerNodeId, MaxSerializedEventSize,
+ Params);
+ }
+ return *res;
+ } else {
+ auto it = ChannelMap.find(channel);
+ if (Y_UNLIKELY(it == ChannelMap.end())) {
+ it = ChannelMap.emplace(std::piecewise_construct, std::forward_as_tuple(channel),
+ std::forward_as_tuple(Pool, channel, PeerNodeId, MaxSerializedEventSize,
Metrics, Params)).first;
- }
- return it->second;
- }
- }
-
- ui64 Equalize() {
- if (Heap.empty()) {
- return 0; // nothing to do here -- no working channels
- }
-
- // find the minimum consumed weight among working channels and then adjust weights
- ui64 min = Max<ui64>();
- for (THeapItem& item : Heap) {
- min = Min(min, item.WeightConsumed);
- }
- for (THeapItem& item : Heap) {
- item.WeightConsumed -= min;
- }
- return min;
- }
-
- template<typename TCallback>
- void ForEach(TCallback&& callback) {
- for (auto& channel : ChannelArray) {
- if (channel) {
- callback(*channel);
- }
- }
- for (auto& [id, channel] : ChannelMap) {
- callback(channel);
- }
- }
- };
-
-} // NActors
+ }
+ return it->second;
+ }
+ }
+
+ ui64 Equalize() {
+ if (Heap.empty()) {
+ return 0; // nothing to do here -- no working channels
+ }
+
+ // find the minimum consumed weight among working channels and then adjust weights
+ ui64 min = Max<ui64>();
+ for (THeapItem& item : Heap) {
+ min = Min(min, item.WeightConsumed);
+ }
+ for (THeapItem& item : Heap) {
+ item.WeightConsumed -= min;
+ }
+ return min;
+ }
+
+ template<typename TCallback>
+ void ForEach(TCallback&& callback) {
+ for (auto& channel : ChannelArray) {
+ if (channel) {
+ callback(*channel);
+ }
+ }
+ for (auto& [id, channel] : ChannelMap) {
+ callback(channel);
+ }
+ }
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/event_filter.h b/library/cpp/actors/interconnect/event_filter.h
index 47dabf5f164..b6734762a00 100644
--- a/library/cpp/actors/interconnect/event_filter.h
+++ b/library/cpp/actors/interconnect/event_filter.h
@@ -1,72 +1,72 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/event.h>
-
-namespace NActors {
-
- enum class ENodeClass {
- SYSTEM,
- LOCAL_TENANT,
- PEER_TENANT,
- COUNT
- };
-
- class TEventFilter : TNonCopyable {
- using TRouteMask = ui16;
-
- TVector<TVector<TRouteMask>> ScopeRoutes;
-
- public:
- TEventFilter()
- : ScopeRoutes(65536)
- {}
-
- void RegisterEvent(ui32 type, TRouteMask routes) {
- auto& evSpaceIndex = ScopeRoutes[type >> 16];
- const ui16 subtype = type & 65535;
- size_t size = (subtype + 512) & ~511;
- if (evSpaceIndex.size() < size) {
- evSpaceIndex.resize(size);
- }
- evSpaceIndex[subtype] = routes;
- }
-
- bool CheckIncomingEvent(const IEventHandle& ev, const TScopeId& localScopeId) const {
- TRouteMask routes = 0;
- if (const auto& evSpaceIndex = ScopeRoutes[ev.Type >> 16]) {
- const ui16 subtype = ev.Type & 65535;
- routes = subtype < evSpaceIndex.size() ? evSpaceIndex[subtype] : 0;
- } else {
- routes = ~TRouteMask(); // allow unfilled event spaces by default
- }
- return routes & MakeRouteMask(GetNodeClass(ev.OriginScopeId, localScopeId), GetNodeClass(localScopeId, ev.OriginScopeId));
- }
-
- static ENodeClass GetNodeClass(const TScopeId& scopeId, const TScopeId& localScopeId) {
- if (scopeId.first == 0) {
- // system scope, or null scope
- return scopeId.second ? ENodeClass::SYSTEM : ENodeClass::COUNT;
- } else if (scopeId == localScopeId) {
- return ENodeClass::LOCAL_TENANT;
- } else {
- return ENodeClass::PEER_TENANT;
- }
- }
-
- static TRouteMask MakeRouteMask(ENodeClass from, ENodeClass to) {
- if (from == ENodeClass::COUNT || to == ENodeClass::COUNT) {
- return 0;
- }
- return 1U << (static_cast<unsigned>(from) * static_cast<unsigned>(ENodeClass::COUNT) + static_cast<unsigned>(to));
- }
-
- static TRouteMask MakeRouteMask(std::initializer_list<std::pair<ENodeClass, ENodeClass>> items) {
- TRouteMask mask = 0;
- for (const auto& p : items) {
- mask |= MakeRouteMask(p.first, p.second);
- }
- return mask;
- }
- };
-
-} // NActors
+
+namespace NActors {
+
+ enum class ENodeClass {
+ SYSTEM,
+ LOCAL_TENANT,
+ PEER_TENANT,
+ COUNT
+ };
+
+ class TEventFilter : TNonCopyable {
+ using TRouteMask = ui16;
+
+ TVector<TVector<TRouteMask>> ScopeRoutes;
+
+ public:
+ TEventFilter()
+ : ScopeRoutes(65536)
+ {}
+
+ void RegisterEvent(ui32 type, TRouteMask routes) {
+ auto& evSpaceIndex = ScopeRoutes[type >> 16];
+ const ui16 subtype = type & 65535;
+ size_t size = (subtype + 512) & ~511;
+ if (evSpaceIndex.size() < size) {
+ evSpaceIndex.resize(size);
+ }
+ evSpaceIndex[subtype] = routes;
+ }
+
+ bool CheckIncomingEvent(const IEventHandle& ev, const TScopeId& localScopeId) const {
+ TRouteMask routes = 0;
+ if (const auto& evSpaceIndex = ScopeRoutes[ev.Type >> 16]) {
+ const ui16 subtype = ev.Type & 65535;
+ routes = subtype < evSpaceIndex.size() ? evSpaceIndex[subtype] : 0;
+ } else {
+ routes = ~TRouteMask(); // allow unfilled event spaces by default
+ }
+ return routes & MakeRouteMask(GetNodeClass(ev.OriginScopeId, localScopeId), GetNodeClass(localScopeId, ev.OriginScopeId));
+ }
+
+ static ENodeClass GetNodeClass(const TScopeId& scopeId, const TScopeId& localScopeId) {
+ if (scopeId.first == 0) {
+ // system scope, or null scope
+ return scopeId.second ? ENodeClass::SYSTEM : ENodeClass::COUNT;
+ } else if (scopeId == localScopeId) {
+ return ENodeClass::LOCAL_TENANT;
+ } else {
+ return ENodeClass::PEER_TENANT;
+ }
+ }
+
+ static TRouteMask MakeRouteMask(ENodeClass from, ENodeClass to) {
+ if (from == ENodeClass::COUNT || to == ENodeClass::COUNT) {
+ return 0;
+ }
+ return 1U << (static_cast<unsigned>(from) * static_cast<unsigned>(ENodeClass::COUNT) + static_cast<unsigned>(to));
+ }
+
+ static TRouteMask MakeRouteMask(std::initializer_list<std::pair<ENodeClass, ENodeClass>> items) {
+ TRouteMask mask = 0;
+ for (const auto& p : items) {
+ mask |= MakeRouteMask(p.first, p.second);
+ }
+ return mask;
+ }
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/event_holder_pool.h b/library/cpp/actors/interconnect/event_holder_pool.h
index b6090a3bc84..a872f6fcfa3 100644
--- a/library/cpp/actors/interconnect/event_holder_pool.h
+++ b/library/cpp/actors/interconnect/event_holder_pool.h
@@ -1,128 +1,128 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/containers/stack_vector/stack_vec.h>
-
-#include "packet.h"
-
-namespace NActors {
- struct TEvFreeItems : TEventLocal<TEvFreeItems, EventSpaceBegin(TEvents::ES_PRIVATE)> {
- static constexpr size_t MaxEvents = 256;
-
- TList<TTcpPacketOutTask> Items;
- std::list<TEventHolder> FreeQueue;
- TStackVec<THolder<IEventBase>, MaxEvents> Events;
- TStackVec<THolder<TEventSerializedData>, MaxEvents> Buffers;
+
+#include "packet.h"
+
+namespace NActors {
+ struct TEvFreeItems : TEventLocal<TEvFreeItems, EventSpaceBegin(TEvents::ES_PRIVATE)> {
+ static constexpr size_t MaxEvents = 256;
+
+ TList<TTcpPacketOutTask> Items;
+ std::list<TEventHolder> FreeQueue;
+ TStackVec<THolder<IEventBase>, MaxEvents> Events;
+ TStackVec<THolder<TEventSerializedData>, MaxEvents> Buffers;
std::shared_ptr<std::atomic<TAtomicBase>> Counter;
- ui64 NumBytes = 0;
-
- ~TEvFreeItems() {
- if (Counter) {
+ ui64 NumBytes = 0;
+
+ ~TEvFreeItems() {
+ if (Counter) {
TAtomicBase res = Counter->fetch_sub(NumBytes) - NumBytes;
- Y_VERIFY(res >= 0);
- }
- }
-
- bool GetInLineForDestruction(const TIntrusivePtr<TInterconnectProxyCommon>& common) {
- Y_VERIFY(!Counter);
- const auto& counter = common->DestructorQueueSize;
- const auto& max = common->MaxDestructorQueueSize;
+ Y_VERIFY(res >= 0);
+ }
+ }
+
+ bool GetInLineForDestruction(const TIntrusivePtr<TInterconnectProxyCommon>& common) {
+ Y_VERIFY(!Counter);
+ const auto& counter = common->DestructorQueueSize;
+ const auto& max = common->MaxDestructorQueueSize;
if (counter && (TAtomicBase)(counter->fetch_add(NumBytes) + NumBytes) > max) {
counter->fetch_sub(NumBytes);
- return false;
- }
- Counter = counter;
- return true;
- }
- };
-
- class TEventHolderPool {
- using TDestroyCallback = std::function<void(THolder<IEventBase>)>;
-
- static constexpr size_t MaxFreeQueueItems = 32;
- static constexpr size_t FreeQueueTrimThreshold = MaxFreeQueueItems * 2;
- static constexpr ui64 MaxBytesPerMessage = 10 * 1024 * 1024;
-
- TIntrusivePtr<TInterconnectProxyCommon> Common;
- std::list<TEventHolder> Cache;
- THolder<TEvFreeItems> PendingFreeEvent;
- TDestroyCallback DestroyCallback;
-
- public:
- TEventHolderPool(TIntrusivePtr<TInterconnectProxyCommon> common,
- TDestroyCallback destroyCallback)
- : Common(std::move(common))
- , DestroyCallback(std::move(destroyCallback))
- {}
-
- TEventHolder& Allocate(std::list<TEventHolder>& queue) {
- if (Cache.empty()) {
- queue.emplace_back();
- } else {
- queue.splice(queue.end(), Cache, Cache.begin());
- }
- return queue.back();
- }
-
- void Release(std::list<TEventHolder>& queue) {
- for (auto it = queue.begin(); it != queue.end(); ) {
- Release(queue, it++);
- }
- }
-
- void Release(std::list<TEventHolder>& queue, std::list<TEventHolder>::iterator event) {
- bool trim = false;
-
- // release held event, if any
- if (THolder<IEventBase> ev = std::move(event->Event)) {
- auto p = GetPendingEvent();
- p->NumBytes += event->EventSerializedSize;
- auto& events = p->Events;
- events.push_back(std::move(ev));
- trim = trim || events.size() >= TEvFreeItems::MaxEvents || p->NumBytes >= MaxBytesPerMessage;
- }
-
- // release buffer, if any
- if (event->Buffer && event->Buffer.RefCount() == 1) {
- auto p = GetPendingEvent();
- p->NumBytes += event->EventSerializedSize;
- auto& buffers = p->Buffers;
- buffers.emplace_back(event->Buffer.Release());
- trim = trim || buffers.size() >= TEvFreeItems::MaxEvents || p->NumBytes >= MaxBytesPerMessage;
- }
-
- // free event and trim the cache if its size is exceeded
- event->Clear();
- Cache.splice(Cache.end(), queue, event);
- if (Cache.size() >= FreeQueueTrimThreshold) {
- auto& freeQueue = GetPendingEvent()->FreeQueue;
- auto it = Cache.begin();
- std::advance(it, Cache.size() - MaxFreeQueueItems);
- freeQueue.splice(freeQueue.end(), Cache, Cache.begin(), it);
- trim = true;
- }
-
- // release items if we have hit the limit
- if (trim) {
- Trim();
- }
- }
-
- void Trim() {
- if (auto ev = std::move(PendingFreeEvent); ev && ev->GetInLineForDestruction(Common)) {
- DestroyCallback(std::move(ev));
- }
-
- // ensure it is dropped
- PendingFreeEvent.Reset();
- }
-
- private:
+ return false;
+ }
+ Counter = counter;
+ return true;
+ }
+ };
+
+ class TEventHolderPool {
+ using TDestroyCallback = std::function<void(THolder<IEventBase>)>;
+
+ static constexpr size_t MaxFreeQueueItems = 32;
+ static constexpr size_t FreeQueueTrimThreshold = MaxFreeQueueItems * 2;
+ static constexpr ui64 MaxBytesPerMessage = 10 * 1024 * 1024;
+
+ TIntrusivePtr<TInterconnectProxyCommon> Common;
+ std::list<TEventHolder> Cache;
+ THolder<TEvFreeItems> PendingFreeEvent;
+ TDestroyCallback DestroyCallback;
+
+ public:
+ TEventHolderPool(TIntrusivePtr<TInterconnectProxyCommon> common,
+ TDestroyCallback destroyCallback)
+ : Common(std::move(common))
+ , DestroyCallback(std::move(destroyCallback))
+ {}
+
+ TEventHolder& Allocate(std::list<TEventHolder>& queue) {
+ if (Cache.empty()) {
+ queue.emplace_back();
+ } else {
+ queue.splice(queue.end(), Cache, Cache.begin());
+ }
+ return queue.back();
+ }
+
+ void Release(std::list<TEventHolder>& queue) {
+ for (auto it = queue.begin(); it != queue.end(); ) {
+ Release(queue, it++);
+ }
+ }
+
+ void Release(std::list<TEventHolder>& queue, std::list<TEventHolder>::iterator event) {
+ bool trim = false;
+
+ // release held event, if any
+ if (THolder<IEventBase> ev = std::move(event->Event)) {
+ auto p = GetPendingEvent();
+ p->NumBytes += event->EventSerializedSize;
+ auto& events = p->Events;
+ events.push_back(std::move(ev));
+ trim = trim || events.size() >= TEvFreeItems::MaxEvents || p->NumBytes >= MaxBytesPerMessage;
+ }
+
+ // release buffer, if any
+ if (event->Buffer && event->Buffer.RefCount() == 1) {
+ auto p = GetPendingEvent();
+ p->NumBytes += event->EventSerializedSize;
+ auto& buffers = p->Buffers;
+ buffers.emplace_back(event->Buffer.Release());
+ trim = trim || buffers.size() >= TEvFreeItems::MaxEvents || p->NumBytes >= MaxBytesPerMessage;
+ }
+
+ // free event and trim the cache if its size is exceeded
+ event->Clear();
+ Cache.splice(Cache.end(), queue, event);
+ if (Cache.size() >= FreeQueueTrimThreshold) {
+ auto& freeQueue = GetPendingEvent()->FreeQueue;
+ auto it = Cache.begin();
+ std::advance(it, Cache.size() - MaxFreeQueueItems);
+ freeQueue.splice(freeQueue.end(), Cache, Cache.begin(), it);
+ trim = true;
+ }
+
+ // release items if we have hit the limit
+ if (trim) {
+ Trim();
+ }
+ }
+
+ void Trim() {
+ if (auto ev = std::move(PendingFreeEvent); ev && ev->GetInLineForDestruction(Common)) {
+ DestroyCallback(std::move(ev));
+ }
+
+ // ensure it is dropped
+ PendingFreeEvent.Reset();
+ }
+
+ private:
TEvFreeItems* GetPendingEvent() {
- if (!PendingFreeEvent) {
- PendingFreeEvent.Reset(new TEvFreeItems);
- }
- return PendingFreeEvent.Get();
- }
- };
-
+ if (!PendingFreeEvent) {
+ PendingFreeEvent.Reset(new TEvFreeItems);
+ }
+ return PendingFreeEvent.Get();
+ }
+ };
+
}
diff --git a/library/cpp/actors/interconnect/events_local.h b/library/cpp/actors/interconnect/events_local.h
index 8a46ffd535f..be3f74bd509 100644
--- a/library/cpp/actors/interconnect/events_local.h
+++ b/library/cpp/actors/interconnect/events_local.h
@@ -8,7 +8,7 @@
#include "interconnect_stream.h"
#include "packet.h"
-#include "types.h"
+#include "types.h"
namespace NActors {
struct TProgramInfo {
@@ -23,7 +23,7 @@ namespace NActors {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Start = EventSpaceBegin(TEvents::ES_INTERCONNECT_TCP),
-
+
SocketReadyRead = Start,
SocketReadyWrite,
SocketError,
@@ -32,7 +32,7 @@ namespace NActors {
IncomingConnection,
HandshakeAsk,
HandshakeAck,
- HandshakeNak,
+ HandshakeNak,
HandshakeDone,
HandshakeFail,
Kick,
@@ -50,16 +50,16 @@ namespace NActors {
ConnectProtocolWakeup,
HTTPProtocolRetry,
EvPollerRegister,
- EvPollerRegisterResult,
- EvPollerReady,
+ EvPollerRegisterResult,
+ EvPollerReady,
EvUpdateFromInputSession,
- EvConfirmUpdate,
+ EvConfirmUpdate,
EvSessionBufferSizeRequest,
EvSessionBufferSizeResponse,
- EvProcessPingRequest,
- EvGetSecureSocket,
- EvSecureSocket,
-
+ EvProcessPingRequest,
+ EvGetSecureSocket,
+ EvSecureSocket,
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// nonlocal messages; their indices must be preserved in order to work properly while doing rolling update
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -67,7 +67,7 @@ namespace NActors {
// interconnect load test message
EvLoadMessage = Start + 256,
};
-
+
struct TEvSocketReadyRead: public TEventLocal<TEvSocketReadyRead, ui32(ENetwork::SocketReadyRead)> {
DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketReadyRead, "Network: TEvSocketReadyRead")
};
@@ -97,10 +97,10 @@ namespace NActors {
struct TEvSocketDisconnect: public TEventLocal<TEvSocketDisconnect, ui32(ENetwork::Disconnect)> {
DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketDisconnect, "Network: TEvSocketDisconnect")
- TDisconnectReason Reason;
-
- TEvSocketDisconnect(TDisconnectReason reason)
- : Reason(std::move(reason))
+ TDisconnectReason Reason;
+
+ TEvSocketDisconnect(TDisconnectReason reason)
+ : Reason(std::move(reason))
{
}
};
@@ -126,18 +126,18 @@ namespace NActors {
TEvHandshakeAck(const TActorId& self, ui64 nextPacket, TSessionParams params)
: Self(self)
, NextPacket(nextPacket)
- , Params(std::move(params))
- {}
+ , Params(std::move(params))
+ {}
const TActorId Self;
const ui64 NextPacket;
- const TSessionParams Params;
- };
-
- struct TEvHandshakeNak : TEventLocal<TEvHandshakeNak, ui32(ENetwork::HandshakeNak)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketReadyRead, "Network: TEvHandshakeNak")
+ const TSessionParams Params;
};
+ struct TEvHandshakeNak : TEventLocal<TEvHandshakeNak, ui32(ENetwork::HandshakeNak)> {
+ DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketReadyRead, "Network: TEvHandshakeNak")
+ };
+
struct TEvHandshakeRequest
: public TEventLocal<TEvHandshakeRequest,
ui32(ENetwork::HandshakeRequest)> {
@@ -173,29 +173,29 @@ namespace NActors {
DEFINE_SIMPLE_LOCAL_EVENT(TEvIncomingConnection, "Network: TEvIncomingConnection")
TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
NInterconnect::TAddress Address;
-
- TEvIncomingConnection(TIntrusivePtr<NInterconnect::TStreamSocket> socket, NInterconnect::TAddress address)
- : Socket(std::move(socket))
- , Address(std::move(address))
- {}
+
+ TEvIncomingConnection(TIntrusivePtr<NInterconnect::TStreamSocket> socket, NInterconnect::TAddress address)
+ : Socket(std::move(socket))
+ , Address(std::move(address))
+ {}
};
struct TEvHandshakeDone: public TEventLocal<TEvHandshakeDone, ui32(ENetwork::HandshakeDone)> {
DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeDone, "Network: TEvHandshakeDone")
TEvHandshakeDone(
- TIntrusivePtr<NInterconnect::TStreamSocket> socket,
+ TIntrusivePtr<NInterconnect::TStreamSocket> socket,
const TActorId& peer,
const TActorId& self,
- ui64 nextPacket,
- TAutoPtr<TProgramInfo>&& programInfo,
- TSessionParams params)
+ ui64 nextPacket,
+ TAutoPtr<TProgramInfo>&& programInfo,
+ TSessionParams params)
: Socket(std::move(socket))
, Peer(peer)
, Self(self)
, NextPacket(nextPacket)
, ProgramInfo(std::move(programInfo))
- , Params(std::move(params))
+ , Params(std::move(params))
{
}
@@ -204,7 +204,7 @@ namespace NActors {
const TActorId Self;
const ui64 NextPacket;
TAutoPtr<TProgramInfo> ProgramInfo;
- const TSessionParams Params;
+ const TSessionParams Params;
};
struct TEvHandshakeFail: public TEventLocal<TEvHandshakeFail, ui32(ENetwork::HandshakeFail)> {
@@ -318,48 +318,48 @@ namespace NActors {
TEvLoadMessage() = default;
template <typename TContainer>
- TEvLoadMessage(const TContainer& route, const TString& id, const TString* payload) {
+ TEvLoadMessage(const TContainer& route, const TString& id, const TString* payload) {
for (const TActorId& actorId : route) {
auto* hop = Record.AddHops();
- if (actorId) {
+ if (actorId) {
ActorIdToProto(actorId, hop->MutableNextHop());
- }
+ }
}
Record.SetId(id);
if (payload) {
- Record.SetPayload(*payload);
+ Record.SetPayload(*payload);
}
}
-
- template <typename TContainer>
- TEvLoadMessage(const TContainer& route, const TString& id, TRope&& payload) {
- for (const TActorId& actorId : route) {
- auto* hop = Record.AddHops();
- if (actorId) {
- ActorIdToProto(actorId, hop->MutableNextHop());
- }
- }
- Record.SetId(id);
- AddPayload(std::move(payload));
- }
+
+ template <typename TContainer>
+ TEvLoadMessage(const TContainer& route, const TString& id, TRope&& payload) {
+ for (const TActorId& actorId : route) {
+ auto* hop = Record.AddHops();
+ if (actorId) {
+ ActorIdToProto(actorId, hop->MutableNextHop());
+ }
+ }
+ Record.SetId(id);
+ AddPayload(std::move(payload));
+ }
};
struct TEvUpdateFromInputSession : TEventLocal<TEvUpdateFromInputSession, static_cast<ui32>(ENetwork::EvUpdateFromInputSession)> {
ui64 ConfirmedByInput; // latest Confirm value from processed input packet
ui64 NumDataBytes;
- TDuration Ping;
-
- TEvUpdateFromInputSession(ui64 confirmedByInput, ui64 numDataBytes, TDuration ping)
+ TDuration Ping;
+
+ TEvUpdateFromInputSession(ui64 confirmedByInput, ui64 numDataBytes, TDuration ping)
: ConfirmedByInput(confirmedByInput)
, NumDataBytes(numDataBytes)
- , Ping(ping)
+ , Ping(ping)
{
}
};
-
- struct TEvConfirmUpdate : TEventLocal<TEvConfirmUpdate, static_cast<ui32>(ENetwork::EvConfirmUpdate)>
- {};
-
+
+ struct TEvConfirmUpdate : TEventLocal<TEvConfirmUpdate, static_cast<ui32>(ENetwork::EvConfirmUpdate)>
+ {};
+
struct TEvSessionBufferSizeRequest : TEventLocal<TEvSessionBufferSizeRequest, static_cast<ui32>(ENetwork::EvSessionBufferSizeRequest)> {
//DEFINE_SIMPLE_LOCAL_EVENT(TEvSessionBufferSizeRequest, "Session: TEvSessionBufferSizeRequest")
DEFINE_SIMPLE_LOCAL_EVENT(TEvSessionBufferSizeRequest, "Network: TEvSessionBufferSizeRequest");
@@ -376,28 +376,28 @@ namespace NActors {
ui64 BufferSize;
};
- struct TEvProcessPingRequest : TEventLocal<TEvProcessPingRequest, static_cast<ui32>(ENetwork::EvProcessPingRequest)> {
- const ui64 Payload;
-
- TEvProcessPingRequest(ui64 payload)
- : Payload(payload)
- {}
- };
-
- struct TEvGetSecureSocket : TEventLocal<TEvGetSecureSocket, (ui32)ENetwork::EvGetSecureSocket> {
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
-
- TEvGetSecureSocket(TIntrusivePtr<NInterconnect::TStreamSocket> socket)
- : Socket(std::move(socket))
- {}
- };
-
- struct TEvSecureSocket : TEventLocal<TEvSecureSocket, (ui32)ENetwork::EvSecureSocket> {
- TIntrusivePtr<NInterconnect::TSecureSocket> Socket;
-
- TEvSecureSocket(TIntrusivePtr<NInterconnect::TSecureSocket> socket)
- : Socket(std::move(socket))
- {}
- };
-
+ struct TEvProcessPingRequest : TEventLocal<TEvProcessPingRequest, static_cast<ui32>(ENetwork::EvProcessPingRequest)> {
+ const ui64 Payload;
+
+ TEvProcessPingRequest(ui64 payload)
+ : Payload(payload)
+ {}
+ };
+
+ struct TEvGetSecureSocket : TEventLocal<TEvGetSecureSocket, (ui32)ENetwork::EvGetSecureSocket> {
+ TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
+
+ TEvGetSecureSocket(TIntrusivePtr<NInterconnect::TStreamSocket> socket)
+ : Socket(std::move(socket))
+ {}
+ };
+
+ struct TEvSecureSocket : TEventLocal<TEvSecureSocket, (ui32)ENetwork::EvSecureSocket> {
+ TIntrusivePtr<NInterconnect::TSecureSocket> Socket;
+
+ TEvSecureSocket(TIntrusivePtr<NInterconnect::TSecureSocket> socket)
+ : Socket(std::move(socket))
+ {}
+ };
+
}
diff --git a/library/cpp/actors/interconnect/interconnect.h b/library/cpp/actors/interconnect/interconnect.h
index 225a5243fd9..20eb942b5a4 100644
--- a/library/cpp/actors/interconnect/interconnect.h
+++ b/library/cpp/actors/interconnect/interconnect.h
@@ -1,74 +1,74 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/core/interconnect.h>
-#include <util/generic/map.h>
-#include <util/network/address.h>
-
-namespace NActors {
+#include <util/generic/map.h>
+#include <util/network/address.h>
+
+namespace NActors {
struct TInterconnectGlobalState: public TThrRefBase {
TString SelfAddress;
ui32 SelfPort;
-
+
TVector<TActorId> GlobalNameservers; // todo: add some info about (like expected reply time)
};
-
+
struct TInterconnectProxySetup: public TThrRefBase {
// synchronous (session -> proxy)
struct IProxy : TNonCopyable {
virtual ~IProxy() {
}
-
+
virtual void ActivateSession(const TActorContext& ctx) = 0; // session activated
virtual void DetachSession(const TActorContext& ctx) = 0; // session is dead
};
-
+
// synchronous (proxy -> session)
struct ISession : TNonCopyable {
virtual ~ISession() {
}
-
+
virtual void DetachSession(const TActorContext& ownerCtx, const TActorContext& sessionCtx) = 0; // kill yourself
virtual void ForwardPacket(TAutoPtr<IEventHandle>& ev, const TActorContext& ownerCtx, const TActorContext& sessionCtx) = 0; // receive packet for forward
virtual void Connect(const TActorContext& ownerCtx, const TActorContext& sessionCtx) = 0; // begin connection
virtual bool ReceiveIncomingSession(TAutoPtr<IEventHandle>& ev, const TActorContext& ownerCtx, const TActorContext& sessionCtx) = 0; // handle incoming session, if returns true - then session is dead and must be recreated with new one
};
-
+
ui32 DestinationNode;
-
+
TString StaticAddress; // if set - would be used as main destination address
int StaticPort;
-
+
TIntrusivePtr<TInterconnectGlobalState> GlobalState;
-
+
virtual IActor* CreateSession(const TActorId& ownerId, IProxy* owner) = 0; // returned actor is session and would be attached to same mailbox as proxy to allow sync calls
virtual TActorSetupCmd CreateAcceptor() = 0;
};
-
+
struct TNameserverSetup {
TActorId ServiceID;
-
+
TIntrusivePtr<TInterconnectGlobalState> GlobalState;
};
-
+
struct TTableNameserverSetup: public TThrRefBase {
struct TNodeInfo {
TString Address;
TString Host;
TString ResolveHost;
ui16 Port;
- TNodeLocation Location;
+ TNodeLocation Location;
TString& first;
ui16& second;
-
+
TNodeInfo()
: first(Address)
, second(Port)
{
}
-
- TNodeInfo(const TNodeInfo&) = default;
-
+
+ TNodeInfo(const TNodeInfo&) = default;
+
// for testing purposes only
TNodeInfo(const TString& address, const TString& host, ui16 port)
: TNodeInfo()
@@ -78,12 +78,12 @@ namespace NActors {
ResolveHost = host;
Port = port;
}
-
+
TNodeInfo(const TString& address,
const TString& host,
const TString& resolveHost,
ui16 port,
- const TNodeLocation& location)
+ const TNodeLocation& location)
: TNodeInfo()
{
Address = address;
@@ -92,7 +92,7 @@ namespace NActors {
Port = port;
Location = location;
}
-
+
// for testing purposes only
TNodeInfo& operator=(const std::pair<TString, ui32>& pr) {
Address = pr.first;
@@ -101,7 +101,7 @@ namespace NActors {
Port = pr.second;
return *this;
}
-
+
TNodeInfo& operator=(const TNodeInfo& ni) {
Address = ni.Address;
Host = ni.Host;
@@ -111,20 +111,20 @@ namespace NActors {
return *this;
}
};
-
+
TMap<ui32, TNodeInfo> StaticNodeTable;
bool IsEntriesUnique() const;
- };
-
+ };
+
struct TNodeRegistrarSetup {
TActorId ServiceID;
-
+
TIntrusivePtr<TInterconnectGlobalState> GlobalState;
};
-
+
TActorId GetNameserviceActorId();
-
+
/**
* Const table-lookup based name service
*/
@@ -132,7 +132,7 @@ namespace NActors {
IActor* CreateNameserverTable(
const TIntrusivePtr<TTableNameserverSetup>& setup,
ui32 poolId = 0);
-
+
/**
* Name service which can be paired with external discovery service.
* Copies information from setup on the start (table may be empty).
@@ -176,4 +176,4 @@ namespace NActors {
const TString& host, ui16 port,
const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline);
-}
+}
diff --git a/library/cpp/actors/interconnect/interconnect_address.cpp b/library/cpp/actors/interconnect/interconnect_address.cpp
index 8f474f5a399..9caabd51984 100644
--- a/library/cpp/actors/interconnect/interconnect_address.cpp
+++ b/library/cpp/actors/interconnect/interconnect_address.cpp
@@ -1,94 +1,94 @@
-#include "interconnect_address.h"
-
-#include <util/string/cast.h>
-#include <util/system/file.h>
-
-#if defined(_linux_)
-#include <sys/un.h>
-#include <sys/stat.h>
-#endif
-
-namespace NInterconnect {
+#include "interconnect_address.h"
+
+#include <util/string/cast.h>
+#include <util/system/file.h>
+
+#if defined(_linux_)
+#include <sys/un.h>
+#include <sys/stat.h>
+#endif
+
+namespace NInterconnect {
TAddress::TAddress() {
- memset(&Addr, 0, sizeof(Addr));
+ memset(&Addr, 0, sizeof(Addr));
}
-
- TAddress::TAddress(NAddr::IRemoteAddr& addr) {
- socklen_t len = addr.Len();
- Y_VERIFY(len <= sizeof(Addr));
- memcpy(&Addr.Generic, addr.Addr(), len);
- }
-
+
+ TAddress::TAddress(NAddr::IRemoteAddr& addr) {
+ socklen_t len = addr.Len();
+ Y_VERIFY(len <= sizeof(Addr));
+ memcpy(&Addr.Generic, addr.Addr(), len);
+ }
+
int TAddress::GetFamily() const {
- return Addr.Generic.sa_family;
+ return Addr.Generic.sa_family;
}
-
+
socklen_t TAddress::Size() const {
- switch (Addr.Generic.sa_family) {
+ switch (Addr.Generic.sa_family) {
case AF_INET6:
- return sizeof(sockaddr_in6);
+ return sizeof(sockaddr_in6);
case AF_INET:
- return sizeof(sockaddr_in);
+ return sizeof(sockaddr_in);
default:
return 0;
}
}
-
+
sockaddr* TAddress::SockAddr() {
- return &Addr.Generic;
- }
-
+ return &Addr.Generic;
+ }
+
const sockaddr* TAddress::SockAddr() const {
- return &Addr.Generic;
+ return &Addr.Generic;
}
-
+
ui16 TAddress::GetPort() const {
- switch (Addr.Generic.sa_family) {
+ switch (Addr.Generic.sa_family) {
case AF_INET6:
- return ntohs(Addr.Ipv6.sin6_port);
+ return ntohs(Addr.Ipv6.sin6_port);
case AF_INET:
- return ntohs(Addr.Ipv4.sin_port);
+ return ntohs(Addr.Ipv4.sin_port);
default:
return 0;
}
}
-
+
TString TAddress::ToString() const {
return GetAddress() + ":" + ::ToString(GetPort());
- }
-
- TAddress::TAddress(const char* addr, ui16 port) {
- memset(&Addr, 0, sizeof(Addr));
- if (inet_pton(Addr.Ipv6.sin6_family = AF_INET6, addr, &Addr.Ipv6.sin6_addr)) {
- Addr.Ipv6.sin6_port = htons(port);
- } else if (inet_pton(Addr.Ipv4.sin_family = AF_INET, addr, &Addr.Ipv4.sin_addr)) {
- Addr.Ipv4.sin_port = htons(port);
+ }
+
+ TAddress::TAddress(const char* addr, ui16 port) {
+ memset(&Addr, 0, sizeof(Addr));
+ if (inet_pton(Addr.Ipv6.sin6_family = AF_INET6, addr, &Addr.Ipv6.sin6_addr)) {
+ Addr.Ipv6.sin6_port = htons(port);
+ } else if (inet_pton(Addr.Ipv4.sin_family = AF_INET, addr, &Addr.Ipv4.sin_addr)) {
+ Addr.Ipv4.sin_port = htons(port);
}
}
-
- TAddress::TAddress(const TString& addr, ui16 port)
- : TAddress(addr.data(), port)
- {}
-
- TString TAddress::GetAddress() const {
- const void *src;
- socklen_t size;
-
- switch (Addr.Generic.sa_family) {
+
+ TAddress::TAddress(const TString& addr, ui16 port)
+ : TAddress(addr.data(), port)
+ {}
+
+ TString TAddress::GetAddress() const {
+ const void *src;
+ socklen_t size;
+
+ switch (Addr.Generic.sa_family) {
case AF_INET6:
- std::tie(src, size) = std::make_tuple(&Addr.Ipv6.sin6_addr, INET6_ADDRSTRLEN);
- break;
-
+ std::tie(src, size) = std::make_tuple(&Addr.Ipv6.sin6_addr, INET6_ADDRSTRLEN);
+ break;
+
case AF_INET:
- std::tie(src, size) = std::make_tuple(&Addr.Ipv4.sin_addr, INET_ADDRSTRLEN);
- break;
-
+ std::tie(src, size) = std::make_tuple(&Addr.Ipv4.sin_addr, INET_ADDRSTRLEN);
+ break;
+
default:
return TString();
}
-
- char *buffer = static_cast<char*>(alloca(size));
- const char *p = inet_ntop(Addr.Generic.sa_family, const_cast<void*>(src), buffer, size);
- return p ? TString(p) : TString();
- }
-}
+
+ char *buffer = static_cast<char*>(alloca(size));
+ const char *p = inet_ntop(Addr.Generic.sa_family, const_cast<void*>(src), buffer, size);
+ return p ? TString(p) : TString();
+ }
+}
diff --git a/library/cpp/actors/interconnect/interconnect_address.h b/library/cpp/actors/interconnect/interconnect_address.h
index e9e0faec814..f517e02b4c1 100644
--- a/library/cpp/actors/interconnect/interconnect_address.h
+++ b/library/cpp/actors/interconnect/interconnect_address.h
@@ -1,23 +1,23 @@
-#pragma once
-
-#include <util/system/defaults.h>
-#include <util/network/init.h>
-#include <util/network/address.h>
-#include <util/generic/string.h>
-
-namespace NInterconnect {
+#pragma once
+
+#include <util/system/defaults.h>
+#include <util/network/init.h>
+#include <util/network/address.h>
+#include <util/generic/string.h>
+
+namespace NInterconnect {
class TAddress {
- union {
- sockaddr Generic;
- sockaddr_in Ipv4;
- sockaddr_in6 Ipv6;
- } Addr;
-
+ union {
+ sockaddr Generic;
+ sockaddr_in Ipv4;
+ sockaddr_in6 Ipv6;
+ } Addr;
+
public:
TAddress();
TAddress(const char* addr, ui16 port);
- TAddress(const TString& addr, ui16 port);
- TAddress(NAddr::IRemoteAddr& addr);
+ TAddress(const TString& addr, ui16 port);
+ TAddress(NAddr::IRemoteAddr& addr);
int GetFamily() const;
socklen_t Size() const;
::sockaddr* SockAddr();
@@ -25,5 +25,5 @@ namespace NInterconnect {
ui16 GetPort() const;
TString GetAddress() const;
TString ToString() const;
- };
-}
+ };
+}
diff --git a/library/cpp/actors/interconnect/interconnect_channel.cpp b/library/cpp/actors/interconnect/interconnect_channel.cpp
index a66ba2a154d..b31b3a4f030 100644
--- a/library/cpp/actors/interconnect/interconnect_channel.cpp
+++ b/library/cpp/actors/interconnect/interconnect_channel.cpp
@@ -1,5 +1,5 @@
-#include "interconnect_channel.h"
-
+#include "interconnect_channel.h"
+
#include <library/cpp/actors/core/events.h>
#include <library/cpp/actors/core/executor_thread.h>
#include <library/cpp/actors/core/log.h>
@@ -7,170 +7,170 @@
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/actors/prof/tag.h>
#include <library/cpp/digest/crc32c/crc32c.h>
-
+
LWTRACE_USING(ACTORLIB_PROVIDER);
-namespace NActors {
+namespace NActors {
DECLARE_WILSON_EVENT(EventSentToSocket);
DECLARE_WILSON_EVENT(EventReceivedFromSocket);
-
- bool TEventOutputChannel::FeedDescriptor(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
+
+ bool TEventOutputChannel::FeedDescriptor(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
const size_t amount = sizeof(TChannelPart) + sizeof(TEventDescr);
- if (task.GetVirtualFreeAmount() < amount) {
- return false;
- }
-
- NWilson::TTraceId traceId(event.Descr.TraceId);
-// if (ctx) {
-// WILSON_TRACE(*ctx, &traceId, EventSentToSocket);
-// }
- traceId.Serialize(&event.Descr.TraceId);
+ if (task.GetVirtualFreeAmount() < amount) {
+ return false;
+ }
+
+ NWilson::TTraceId traceId(event.Descr.TraceId);
+// if (ctx) {
+// WILSON_TRACE(*ctx, &traceId, EventSentToSocket);
+// }
+ traceId.Serialize(&event.Descr.TraceId);
LWTRACK(SerializeToPacketEnd, event.Orbit, PeerNodeId, ChannelId, OutputQueueSize, task.GetDataSize());
task.Orbit.Take(event.Orbit);
-
- event.Descr.Flags = (event.Descr.Flags & ~IEventHandle::FlagForwardOnNondelivery) |
- (ExtendedFormat ? IEventHandle::FlagExtendedFormat : 0);
-
- TChannelPart *part = static_cast<TChannelPart*>(task.GetFreeArea());
+
+ event.Descr.Flags = (event.Descr.Flags & ~IEventHandle::FlagForwardOnNondelivery) |
+ (ExtendedFormat ? IEventHandle::FlagExtendedFormat : 0);
+
+ TChannelPart *part = static_cast<TChannelPart*>(task.GetFreeArea());
part->Channel = ChannelId | TChannelPart::LastPartFlag;
part->Size = sizeof(TEventDescr);
- memcpy(part + 1, &event.Descr, sizeof(TEventDescr));
- task.AppendBuf(part, amount);
- *weightConsumed += amount;
- OutputQueueSize -= part->Size;
+ memcpy(part + 1, &event.Descr, sizeof(TEventDescr));
+ task.AppendBuf(part, amount);
+ *weightConsumed += amount;
+ OutputQueueSize -= part->Size;
Metrics->UpdateOutputChannelEvents(ChannelId);
-
- return true;
+
+ return true;
}
- void TEventOutputChannel::DropConfirmed(ui64 confirm) {
- LOG_DEBUG_IC_SESSION("ICOCH98", "Dropping confirmed messages");
- for (auto it = NotYetConfirmed.begin(); it != NotYetConfirmed.end() && it->Serial <= confirm; ) {
- Pool.Release(NotYetConfirmed, it++);
+ void TEventOutputChannel::DropConfirmed(ui64 confirm) {
+ LOG_DEBUG_IC_SESSION("ICOCH98", "Dropping confirmed messages");
+ for (auto it = NotYetConfirmed.begin(); it != NotYetConfirmed.end() && it->Serial <= confirm; ) {
+ Pool.Release(NotYetConfirmed, it++);
}
- }
-
- bool TEventOutputChannel::FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed) {
- for (;;) {
- Y_VERIFY(!Queue.empty());
- TEventHolder& event = Queue.front();
-
- switch (State) {
- case EState::INITIAL:
- event.InitChecksum();
+ }
+
+ bool TEventOutputChannel::FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed) {
+ for (;;) {
+ Y_VERIFY(!Queue.empty());
+ TEventHolder& event = Queue.front();
+
+ switch (State) {
+ case EState::INITIAL:
+ event.InitChecksum();
LWTRACK(SerializeToPacketBegin, event.Orbit, PeerNodeId, ChannelId, OutputQueueSize);
- if (event.Event) {
- State = EState::CHUNKER;
- IEventBase *base = event.Event.Get();
- Chunker.SetSerializingEvent(base);
- ExtendedFormat = base->IsExtendedFormat();
- } else if (event.Buffer) {
- State = EState::BUFFER;
- Iter = event.Buffer->GetBeginIter();
- ExtendedFormat = event.Buffer->IsExtendedFormat();
- } else {
- State = EState::DESCRIPTOR;
- ExtendedFormat = false;
- }
- break;
-
- case EState::CHUNKER:
- case EState::BUFFER: {
- size_t maxBytes = task.GetVirtualFreeAmount();
- if (maxBytes <= sizeof(TChannelPart)) {
- return false;
- }
-
- TChannelPart *part = static_cast<TChannelPart*>(task.GetFreeArea());
- part->Channel = ChannelId;
- part->Size = 0;
- task.AppendBuf(part, sizeof(TChannelPart));
- maxBytes -= sizeof(TChannelPart);
- Y_VERIFY(maxBytes);
-
- auto addChunk = [&](const void *data, size_t len) {
- event.UpdateChecksum(Params, data, len);
- task.AppendBuf(data, len);
- part->Size += len;
- Y_VERIFY_DEBUG(maxBytes >= len);
- maxBytes -= len;
-
- event.EventActuallySerialized += len;
- if (event.EventActuallySerialized > MaxSerializedEventSize) {
- throw TExSerializedEventTooLarge(event.Descr.Type);
- }
- };
-
- bool complete = false;
- if (State == EState::CHUNKER) {
- Y_VERIFY_DEBUG(task.GetFreeArea() == part + 1);
- while (!complete && maxBytes) {
- const auto [first, last] = Chunker.FeedBuf(task.GetFreeArea(), maxBytes);
- for (auto p = first; p != last; ++p) {
- addChunk(p->first, p->second);
- }
- complete = Chunker.IsComplete();
- }
- Y_VERIFY(!complete || Chunker.IsSuccessfull());
- Y_VERIFY_DEBUG(complete || !maxBytes);
- } else { // BUFFER
- while (const size_t numb = Min(maxBytes, Iter.ContiguousSize())) {
- const char *obuf = Iter.ContiguousData();
- addChunk(obuf, numb);
- Iter += numb;
- }
- complete = !Iter.Valid();
- }
- if (complete) {
- Y_VERIFY(event.EventActuallySerialized == event.EventSerializedSize,
- "EventActuallySerialized# %" PRIu32 " EventSerializedSize# %" PRIu32 " Type# 0x%08" PRIx32,
- event.EventActuallySerialized, event.EventSerializedSize, event.Descr.Type);
- }
-
- if (!part->Size) {
- task.Undo(sizeof(TChannelPart));
- } else {
- *weightConsumed += sizeof(TChannelPart) + part->Size;
- OutputQueueSize -= part->Size;
- }
- if (complete) {
- State = EState::DESCRIPTOR;
- }
- break;
- }
-
- case EState::DESCRIPTOR:
- if (!FeedDescriptor(task, event, weightConsumed)) {
- return false;
- }
- event.Serial = serial;
- NotYetConfirmed.splice(NotYetConfirmed.end(), Queue, Queue.begin()); // move event to not-yet-confirmed queue
- State = EState::INITIAL;
- return true; // we have processed whole event, signal to the caller
+ if (event.Event) {
+ State = EState::CHUNKER;
+ IEventBase *base = event.Event.Get();
+ Chunker.SetSerializingEvent(base);
+ ExtendedFormat = base->IsExtendedFormat();
+ } else if (event.Buffer) {
+ State = EState::BUFFER;
+ Iter = event.Buffer->GetBeginIter();
+ ExtendedFormat = event.Buffer->IsExtendedFormat();
+ } else {
+ State = EState::DESCRIPTOR;
+ ExtendedFormat = false;
+ }
+ break;
+
+ case EState::CHUNKER:
+ case EState::BUFFER: {
+ size_t maxBytes = task.GetVirtualFreeAmount();
+ if (maxBytes <= sizeof(TChannelPart)) {
+ return false;
+ }
+
+ TChannelPart *part = static_cast<TChannelPart*>(task.GetFreeArea());
+ part->Channel = ChannelId;
+ part->Size = 0;
+ task.AppendBuf(part, sizeof(TChannelPart));
+ maxBytes -= sizeof(TChannelPart);
+ Y_VERIFY(maxBytes);
+
+ auto addChunk = [&](const void *data, size_t len) {
+ event.UpdateChecksum(Params, data, len);
+ task.AppendBuf(data, len);
+ part->Size += len;
+ Y_VERIFY_DEBUG(maxBytes >= len);
+ maxBytes -= len;
+
+ event.EventActuallySerialized += len;
+ if (event.EventActuallySerialized > MaxSerializedEventSize) {
+ throw TExSerializedEventTooLarge(event.Descr.Type);
+ }
+ };
+
+ bool complete = false;
+ if (State == EState::CHUNKER) {
+ Y_VERIFY_DEBUG(task.GetFreeArea() == part + 1);
+ while (!complete && maxBytes) {
+ const auto [first, last] = Chunker.FeedBuf(task.GetFreeArea(), maxBytes);
+ for (auto p = first; p != last; ++p) {
+ addChunk(p->first, p->second);
+ }
+ complete = Chunker.IsComplete();
+ }
+ Y_VERIFY(!complete || Chunker.IsSuccessfull());
+ Y_VERIFY_DEBUG(complete || !maxBytes);
+ } else { // BUFFER
+ while (const size_t numb = Min(maxBytes, Iter.ContiguousSize())) {
+ const char *obuf = Iter.ContiguousData();
+ addChunk(obuf, numb);
+ Iter += numb;
+ }
+ complete = !Iter.Valid();
+ }
+ if (complete) {
+ Y_VERIFY(event.EventActuallySerialized == event.EventSerializedSize,
+ "EventActuallySerialized# %" PRIu32 " EventSerializedSize# %" PRIu32 " Type# 0x%08" PRIx32,
+ event.EventActuallySerialized, event.EventSerializedSize, event.Descr.Type);
+ }
+
+ if (!part->Size) {
+ task.Undo(sizeof(TChannelPart));
+ } else {
+ *weightConsumed += sizeof(TChannelPart) + part->Size;
+ OutputQueueSize -= part->Size;
+ }
+ if (complete) {
+ State = EState::DESCRIPTOR;
+ }
+ break;
+ }
+
+ case EState::DESCRIPTOR:
+ if (!FeedDescriptor(task, event, weightConsumed)) {
+ return false;
+ }
+ event.Serial = serial;
+ NotYetConfirmed.splice(NotYetConfirmed.end(), Queue, Queue.begin()); // move event to not-yet-confirmed queue
+ State = EState::INITIAL;
+ return true; // we have processed whole event, signal to the caller
}
+ }
+ }
+
+ void TEventOutputChannel::NotifyUndelivered() {
+ LOG_DEBUG_IC_SESSION("ICOCH89", "Notyfying about Undelivered messages! NotYetConfirmed size: %zu, Queue size: %zu", NotYetConfirmed.size(), Queue.size());
+ if (State == EState::CHUNKER) {
+ Y_VERIFY(!Chunker.IsComplete()); // chunk must have an event being serialized
+ Y_VERIFY(!Queue.empty()); // this event must be the first event in queue
+ TEventHolder& event = Queue.front();
+ Y_VERIFY(Chunker.GetCurrentEvent() == event.Event.Get()); // ensure the event is valid
+ Chunker.Abort(); // stop serializing current event
+ Y_VERIFY(Chunker.IsComplete());
+ }
+ for (auto& item : NotYetConfirmed) {
+ if (item.Descr.Flags & IEventHandle::FlagGenerateUnsureUndelivered) { // notify only when unsure flag is set
+ item.ForwardOnNondelivery(true);
+ }
+ }
+ Pool.Release(NotYetConfirmed);
+ for (auto& item : Queue) {
+ item.ForwardOnNondelivery(false);
}
- }
-
- void TEventOutputChannel::NotifyUndelivered() {
- LOG_DEBUG_IC_SESSION("ICOCH89", "Notyfying about Undelivered messages! NotYetConfirmed size: %zu, Queue size: %zu", NotYetConfirmed.size(), Queue.size());
- if (State == EState::CHUNKER) {
- Y_VERIFY(!Chunker.IsComplete()); // chunk must have an event being serialized
- Y_VERIFY(!Queue.empty()); // this event must be the first event in queue
- TEventHolder& event = Queue.front();
- Y_VERIFY(Chunker.GetCurrentEvent() == event.Event.Get()); // ensure the event is valid
- Chunker.Abort(); // stop serializing current event
- Y_VERIFY(Chunker.IsComplete());
- }
- for (auto& item : NotYetConfirmed) {
- if (item.Descr.Flags & IEventHandle::FlagGenerateUnsureUndelivered) { // notify only when unsure flag is set
- item.ForwardOnNondelivery(true);
- }
- }
- Pool.Release(NotYetConfirmed);
- for (auto& item : Queue) {
- item.ForwardOnNondelivery(false);
- }
- Pool.Release(Queue);
- }
-
-}
+ Pool.Release(Queue);
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_channel.h b/library/cpp/actors/interconnect/interconnect_channel.h
index e4a0ae3cdab..56d6e31ba72 100644
--- a/library/cpp/actors/interconnect/interconnect_channel.h
+++ b/library/cpp/actors/interconnect/interconnect_channel.h
@@ -1,46 +1,46 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/core/event_load.h>
#include <library/cpp/actors/util/rope.h>
-#include <util/generic/deque.h>
-#include <util/generic/vector.h>
-#include <util/generic/map.h>
-#include <util/stream/walk.h>
+#include <util/generic/deque.h>
+#include <util/generic/vector.h>
+#include <util/generic/map.h>
+#include <util/stream/walk.h>
#include <library/cpp/actors/wilson/wilson_event.h>
#include <library/cpp/actors/helpers/mon_histogram_helper.h>
-
-#include "interconnect_common.h"
-#include "interconnect_counters.h"
-#include "packet.h"
-#include "event_holder_pool.h"
-
-namespace NActors {
-#pragma pack(push, 1)
+
+#include "interconnect_common.h"
+#include "interconnect_counters.h"
+#include "packet.h"
+#include "event_holder_pool.h"
+
+namespace NActors {
+#pragma pack(push, 1)
struct TChannelPart {
ui16 Channel;
ui16 Size;
-
+
static constexpr ui16 LastPartFlag = ui16(1) << 15;
-
- TString ToString() const {
- return TStringBuilder() << "{Channel# " << (Channel & ~LastPartFlag)
- << " LastPartFlag# " << ((Channel & LastPartFlag) ? "true" : "false")
- << " Size# " << Size << "}";
- }
- };
-#pragma pack(pop)
-
- struct TExSerializedEventTooLarge : std::exception {
- const ui32 Type;
-
- TExSerializedEventTooLarge(ui32 type)
- : Type(type)
- {}
+
+ TString ToString() const {
+ return TStringBuilder() << "{Channel# " << (Channel & ~LastPartFlag)
+ << " LastPartFlag# " << ((Channel & LastPartFlag) ? "true" : "false")
+ << " Size# " << Size << "}";
+ }
};
-
- class TEventOutputChannel : public TInterconnectLoggingBase {
+#pragma pack(pop)
+
+ struct TExSerializedEventTooLarge : std::exception {
+ const ui32 Type;
+
+ TExSerializedEventTooLarge(ui32 type)
+ : Type(type)
+ {}
+ };
+
+ class TEventOutputChannel : public TInterconnectLoggingBase {
public:
TEventOutputChannel(TEventHolderPool& pool, ui16 id, ui32 peerNodeId, ui32 maxSerializedEventSize,
std::shared_ptr<IInterconnectMetrics> metrics, TSessionParams params)
@@ -49,79 +49,79 @@ namespace NActors {
, PeerNodeId(peerNodeId)
, ChannelId(id)
, Metrics(std::move(metrics))
- , Params(std::move(params))
- , MaxSerializedEventSize(maxSerializedEventSize)
- {}
-
- ~TEventOutputChannel() {
- }
-
+ , Params(std::move(params))
+ , MaxSerializedEventSize(maxSerializedEventSize)
+ {}
+
+ ~TEventOutputChannel() {
+ }
+
std::pair<ui32, TEventHolder*> Push(IEventHandle& ev) {
- TEventHolder& event = Pool.Allocate(Queue);
- const ui32 bytes = event.Fill(ev) + sizeof(TEventDescr);
- OutputQueueSize += bytes;
+ TEventHolder& event = Pool.Allocate(Queue);
+ const ui32 bytes = event.Fill(ev) + sizeof(TEventDescr);
+ OutputQueueSize += bytes;
return std::make_pair(bytes, &event);
}
-
- void DropConfirmed(ui64 confirm);
-
- bool FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed);
-
+
+ void DropConfirmed(ui64 confirm);
+
+ bool FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed);
+
bool IsEmpty() const {
- return Queue.empty();
- }
-
- bool IsWorking() const {
- return !IsEmpty();
+ return Queue.empty();
}
-
+
+ bool IsWorking() const {
+ return !IsEmpty();
+ }
+
ui32 GetQueueSize() const {
return (ui32)Queue.size();
}
-
- ui64 GetBufferedAmountOfData() const {
+
+ ui64 GetBufferedAmountOfData() const {
return OutputQueueSize;
}
-
- void NotifyUndelivered();
-
+
+ void NotifyUndelivered();
+
TEventHolderPool& Pool;
const ui32 PeerNodeId;
const ui16 ChannelId;
std::shared_ptr<IInterconnectMetrics> Metrics;
- const TSessionParams Params;
- const ui32 MaxSerializedEventSize;
- ui64 UnaccountedTraffic = 0;
- ui64 EqualizeCounterOnPause = 0;
- ui64 WeightConsumedOnPause = 0;
-
- enum class EState {
- INITIAL,
- CHUNKER,
- BUFFER,
- DESCRIPTOR,
- };
- EState State = EState::INITIAL;
-
- static constexpr ui16 MinimumFreeSpace = sizeof(TChannelPart) + sizeof(TEventDescr);
-
+ const TSessionParams Params;
+ const ui32 MaxSerializedEventSize;
+ ui64 UnaccountedTraffic = 0;
+ ui64 EqualizeCounterOnPause = 0;
+ ui64 WeightConsumedOnPause = 0;
+
+ enum class EState {
+ INITIAL,
+ CHUNKER,
+ BUFFER,
+ DESCRIPTOR,
+ };
+ EState State = EState::INITIAL;
+
+ static constexpr ui16 MinimumFreeSpace = sizeof(TChannelPart) + sizeof(TEventDescr);
+
protected:
- ui64 OutputQueueSize = 0;
-
- std::list<TEventHolder> Queue;
- std::list<TEventHolder> NotYetConfirmed;
- TRope::TConstIterator Iter;
- TCoroutineChunkSerializer Chunker;
- bool ExtendedFormat = false;
-
- bool FeedDescriptor(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed);
-
- void AccountTraffic() {
- if (const ui64 amount = std::exchange(UnaccountedTraffic, 0)) {
+ ui64 OutputQueueSize = 0;
+
+ std::list<TEventHolder> Queue;
+ std::list<TEventHolder> NotYetConfirmed;
+ TRope::TConstIterator Iter;
+ TCoroutineChunkSerializer Chunker;
+ bool ExtendedFormat = false;
+
+ bool FeedDescriptor(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed);
+
+ void AccountTraffic() {
+ if (const ui64 amount = std::exchange(UnaccountedTraffic, 0)) {
Metrics->UpdateOutputChannelTraffic(ChannelId, amount);
- }
+ }
}
-
+
friend class TInterconnectSessionTCP;
};
-}
+}
diff --git a/library/cpp/actors/interconnect/interconnect_common.h b/library/cpp/actors/interconnect/interconnect_common.h
index 285709a00cf..a74af724d93 100644
--- a/library/cpp/actors/interconnect/interconnect_common.h
+++ b/library/cpp/actors/interconnect/interconnect_common.h
@@ -1,28 +1,28 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actorid.h>
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/util/datetime.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/monlib/metrics/metric_registry.h>
-#include <util/generic/map.h>
-#include <util/generic/set.h>
-#include <util/system/datetime.h>
-
-#include "poller_tcp.h"
+#include <util/generic/map.h>
+#include <util/generic/set.h>
+#include <util/system/datetime.h>
+
+#include "poller_tcp.h"
#include "logging.h"
-#include "event_filter.h"
-
+#include "event_filter.h"
+
#include <atomic>
-namespace NActors {
- enum class EEncryptionMode {
- DISABLED, // no encryption is required at all
- OPTIONAL, // encryption is enabled when supported by both peers
- REQUIRED, // encryption is mandatory
- };
-
- struct TInterconnectSettings {
+namespace NActors {
+ enum class EEncryptionMode {
+ DISABLED, // no encryption is required at all
+ OPTIONAL, // encryption is enabled when supported by both peers
+ REQUIRED, // encryption is mandatory
+ };
+
+ struct TInterconnectSettings {
TDuration Handshake;
TDuration DeadPeer;
TDuration CloseOnIdle;
@@ -30,56 +30,56 @@ namespace NActors {
ui64 OutputBuffersTotalSizeLimitInMB = 0;
ui32 TotalInflightAmountOfData = 0;
bool MergePerPeerCounters = false;
- bool MergePerDataCenterCounters = false;
+ bool MergePerDataCenterCounters = false;
ui32 TCPSocketBufferSize = 0;
TDuration PingPeriod = TDuration::Seconds(3);
TDuration ForceConfirmPeriod = TDuration::Seconds(1);
- TDuration LostConnection;
- TDuration BatchPeriod;
- bool BindOnAllAddresses = true;
- EEncryptionMode EncryptionMode = EEncryptionMode::DISABLED;
- bool TlsAuthOnly = false;
- TString Certificate; // certificate data in PEM format
- TString PrivateKey; // private key for the certificate in PEM format
- TString CaFilePath; // path to certificate authority file
- TString CipherList; // encryption algorithms
- TDuration MessagePendingTimeout = TDuration::Seconds(1); // timeout for which messages are queued while in PendingConnection state
- ui64 MessagePendingSize = Max<ui64>(); // size of the queue
- ui32 MaxSerializedEventSize = NActors::EventMaxByteSize;
-
- ui32 GetSendBufferSize() const {
- ui32 res = 512 * 1024; // 512 kb is the default value for send buffer
- if (TCPSocketBufferSize) {
- res = TCPSocketBufferSize;
- }
- return res;
- }
+ TDuration LostConnection;
+ TDuration BatchPeriod;
+ bool BindOnAllAddresses = true;
+ EEncryptionMode EncryptionMode = EEncryptionMode::DISABLED;
+ bool TlsAuthOnly = false;
+ TString Certificate; // certificate data in PEM format
+ TString PrivateKey; // private key for the certificate in PEM format
+ TString CaFilePath; // path to certificate authority file
+ TString CipherList; // encryption algorithms
+ TDuration MessagePendingTimeout = TDuration::Seconds(1); // timeout for which messages are queued while in PendingConnection state
+ ui64 MessagePendingSize = Max<ui64>(); // size of the queue
+ ui32 MaxSerializedEventSize = NActors::EventMaxByteSize;
+
+ ui32 GetSendBufferSize() const {
+ ui32 res = 512 * 1024; // 512 kb is the default value for send buffer
+ if (TCPSocketBufferSize) {
+ res = TCPSocketBufferSize;
+ }
+ return res;
+ }
};
-
+
struct TChannelSettings {
ui16 Weight;
};
-
+
typedef TMap<ui16, TChannelSettings> TChannelsConfig;
-
+
using TRegisterMonPageCallback = std::function<void(const TString& path, const TString& title,
TActorSystem* actorSystem, const TActorId& actorId)>;
-
+
using TInitWhiteboardCallback = std::function<void(ui16 icPort, TActorSystem* actorSystem)>;
- using TUpdateWhiteboardCallback = std::function<void(const TString& peer, bool connected, bool green, bool yellow,
+ using TUpdateWhiteboardCallback = std::function<void(const TString& peer, bool connected, bool green, bool yellow,
bool orange, bool red, TActorSystem* actorSystem)>;
-
+
struct TInterconnectProxyCommon : TAtomicRefCount<TInterconnectProxyCommon> {
TActorId NameserviceId;
NMonitoring::TDynamicCounterPtr MonCounters;
std::shared_ptr<NMonitoring::IMetricRegistry> Metrics;
- TChannelsConfig ChannelsConfig;
- TInterconnectSettings Settings;
+ TChannelsConfig ChannelsConfig;
+ TInterconnectSettings Settings;
TRegisterMonPageCallback RegisterMonPage;
TActorId DestructorId;
std::shared_ptr<std::atomic<TAtomicBase>> DestructorQueueSize;
- TAtomicBase MaxDestructorQueueSize = 1024 * 1024 * 1024;
+ TAtomicBase MaxDestructorQueueSize = 1024 * 1024 * 1024;
TString ClusterUUID;
TVector<TString> AcceptUUID;
ui64 StartTime = GetCycleCountFast();
@@ -88,19 +88,19 @@ namespace NActors {
TUpdateWhiteboardCallback UpdateWhiteboard;
ui32 HandshakeBallastSize = 0;
TAtomic StartedSessionKiller = 0;
- TScopeId LocalScopeId;
- std::shared_ptr<TEventFilter> EventFilter;
- TString Cookie; // unique random identifier of a node instance (generated randomly at every start)
- std::unordered_map<ui16, TString> ChannelName;
-
- struct TVersionInfo {
- TString Tag; // version tag for this node
- TSet<TString> AcceptedTags; // we accept all enlisted version tags of peer nodes, but no others; empty = accept all
- };
-
- TMaybe<TVersionInfo> VersionInfo;
-
- using TPtr = TIntrusivePtr<TInterconnectProxyCommon>;
+ TScopeId LocalScopeId;
+ std::shared_ptr<TEventFilter> EventFilter;
+ TString Cookie; // unique random identifier of a node instance (generated randomly at every start)
+ std::unordered_map<ui16, TString> ChannelName;
+
+ struct TVersionInfo {
+ TString Tag; // version tag for this node
+ TSet<TString> AcceptedTags; // we accept all enlisted version tags of peer nodes, but no others; empty = accept all
+ };
+
+ TMaybe<TVersionInfo> VersionInfo;
+
+ using TPtr = TIntrusivePtr<TInterconnectProxyCommon>;
};
-
+
}
diff --git a/library/cpp/actors/interconnect/interconnect_counters.cpp b/library/cpp/actors/interconnect/interconnect_counters.cpp
index 224160d4b4f..de7e3b8a36a 100644
--- a/library/cpp/actors/interconnect/interconnect_counters.cpp
+++ b/library/cpp/actors/interconnect/interconnect_counters.cpp
@@ -1,123 +1,123 @@
#include "interconnect_counters.h"
-
+
#include <library/cpp/monlib/metrics/metric_registry.h>
#include <library/cpp/monlib/metrics/metric_sub_registry.h>
-
+
#include <unordered_map>
-
-namespace NActors {
-
+
+namespace NActors {
+
namespace {
class TInterconnectCounters: public IInterconnectMetrics {
- public:
- struct TOutputChannel {
- NMonitoring::TDynamicCounters::TCounterPtr Traffic;
- NMonitoring::TDynamicCounters::TCounterPtr Events;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingTraffic;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingEvents;
-
- TOutputChannel() = default;
-
- TOutputChannel(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- NMonitoring::TDynamicCounters::TCounterPtr traffic,
- NMonitoring::TDynamicCounters::TCounterPtr events)
- : Traffic(std::move(traffic))
- , Events(std::move(events))
- , OutgoingTraffic(counters->GetCounter("OutgoingTraffic", true))
- , OutgoingEvents(counters->GetCounter("OutgoingEvents", true))
- {}
-
- TOutputChannel(const TOutputChannel&) = default;
- };
-
- struct TInputChannel {
- NMonitoring::TDynamicCounters::TCounterPtr Traffic;
- NMonitoring::TDynamicCounters::TCounterPtr Events;
- NMonitoring::TDynamicCounters::TCounterPtr ScopeErrors;
- NMonitoring::TDynamicCounters::TCounterPtr IncomingTraffic;
- NMonitoring::TDynamicCounters::TCounterPtr IncomingEvents;
-
- TInputChannel() = default;
-
- TInputChannel(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- NMonitoring::TDynamicCounters::TCounterPtr traffic,
- NMonitoring::TDynamicCounters::TCounterPtr events,
- NMonitoring::TDynamicCounters::TCounterPtr scopeErrors)
- : Traffic(std::move(traffic))
- , Events(std::move(events))
- , ScopeErrors(std::move(scopeErrors))
- , IncomingTraffic(counters->GetCounter("IncomingTraffic", true))
- , IncomingEvents(counters->GetCounter("IncomingEvents", true))
- {}
-
- TInputChannel(const TInputChannel&) = default;
- };
-
- struct TInputChannels : std::unordered_map<ui16, TInputChannel> {
- TInputChannel OtherInputChannel;
-
- TInputChannels() = default;
-
- TInputChannels(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const std::unordered_map<ui16, TString>& names,
- NMonitoring::TDynamicCounters::TCounterPtr traffic,
- NMonitoring::TDynamicCounters::TCounterPtr events,
- NMonitoring::TDynamicCounters::TCounterPtr scopeErrors)
- : OtherInputChannel(counters->GetSubgroup("channel", "other"), traffic, events, scopeErrors)
- {
- for (const auto& [id, name] : names) {
- try_emplace(id, counters->GetSubgroup("channel", name), traffic, events, scopeErrors);
- }
- }
-
- TInputChannels(const TInputChannels&) = default;
-
- const TInputChannel& Get(ui16 id) const {
- const auto it = find(id);
- return it != end() ? it->second : OtherInputChannel;
- }
- };
-
- private:
- const TInterconnectProxyCommon::TPtr Common;
- const bool MergePerDataCenterCounters;
- const bool MergePerPeerCounters;
- NMonitoring::TDynamicCounterPtr Counters;
- NMonitoring::TDynamicCounterPtr PerSessionCounters;
- NMonitoring::TDynamicCounterPtr PerDataCenterCounters;
- NMonitoring::TDynamicCounterPtr& AdaptiveCounters;
-
- bool Initialized = false;
-
- NMonitoring::TDynamicCounters::TCounterPtr Traffic;
- NMonitoring::TDynamicCounters::TCounterPtr Events;
- NMonitoring::TDynamicCounters::TCounterPtr ScopeErrors;
-
- public:
- TInterconnectCounters(const TInterconnectProxyCommon::TPtr& common)
- : Common(common)
- , MergePerDataCenterCounters(common->Settings.MergePerDataCenterCounters)
- , MergePerPeerCounters(common->Settings.MergePerPeerCounters)
- , Counters(common->MonCounters)
+ public:
+ struct TOutputChannel {
+ NMonitoring::TDynamicCounters::TCounterPtr Traffic;
+ NMonitoring::TDynamicCounters::TCounterPtr Events;
+ NMonitoring::TDynamicCounters::TCounterPtr OutgoingTraffic;
+ NMonitoring::TDynamicCounters::TCounterPtr OutgoingEvents;
+
+ TOutputChannel() = default;
+
+ TOutputChannel(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ NMonitoring::TDynamicCounters::TCounterPtr traffic,
+ NMonitoring::TDynamicCounters::TCounterPtr events)
+ : Traffic(std::move(traffic))
+ , Events(std::move(events))
+ , OutgoingTraffic(counters->GetCounter("OutgoingTraffic", true))
+ , OutgoingEvents(counters->GetCounter("OutgoingEvents", true))
+ {}
+
+ TOutputChannel(const TOutputChannel&) = default;
+ };
+
+ struct TInputChannel {
+ NMonitoring::TDynamicCounters::TCounterPtr Traffic;
+ NMonitoring::TDynamicCounters::TCounterPtr Events;
+ NMonitoring::TDynamicCounters::TCounterPtr ScopeErrors;
+ NMonitoring::TDynamicCounters::TCounterPtr IncomingTraffic;
+ NMonitoring::TDynamicCounters::TCounterPtr IncomingEvents;
+
+ TInputChannel() = default;
+
+ TInputChannel(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ NMonitoring::TDynamicCounters::TCounterPtr traffic,
+ NMonitoring::TDynamicCounters::TCounterPtr events,
+ NMonitoring::TDynamicCounters::TCounterPtr scopeErrors)
+ : Traffic(std::move(traffic))
+ , Events(std::move(events))
+ , ScopeErrors(std::move(scopeErrors))
+ , IncomingTraffic(counters->GetCounter("IncomingTraffic", true))
+ , IncomingEvents(counters->GetCounter("IncomingEvents", true))
+ {}
+
+ TInputChannel(const TInputChannel&) = default;
+ };
+
+ struct TInputChannels : std::unordered_map<ui16, TInputChannel> {
+ TInputChannel OtherInputChannel;
+
+ TInputChannels() = default;
+
+ TInputChannels(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const std::unordered_map<ui16, TString>& names,
+ NMonitoring::TDynamicCounters::TCounterPtr traffic,
+ NMonitoring::TDynamicCounters::TCounterPtr events,
+ NMonitoring::TDynamicCounters::TCounterPtr scopeErrors)
+ : OtherInputChannel(counters->GetSubgroup("channel", "other"), traffic, events, scopeErrors)
+ {
+ for (const auto& [id, name] : names) {
+ try_emplace(id, counters->GetSubgroup("channel", name), traffic, events, scopeErrors);
+ }
+ }
+
+ TInputChannels(const TInputChannels&) = default;
+
+ const TInputChannel& Get(ui16 id) const {
+ const auto it = find(id);
+ return it != end() ? it->second : OtherInputChannel;
+ }
+ };
+
+ private:
+ const TInterconnectProxyCommon::TPtr Common;
+ const bool MergePerDataCenterCounters;
+ const bool MergePerPeerCounters;
+ NMonitoring::TDynamicCounterPtr Counters;
+ NMonitoring::TDynamicCounterPtr PerSessionCounters;
+ NMonitoring::TDynamicCounterPtr PerDataCenterCounters;
+ NMonitoring::TDynamicCounterPtr& AdaptiveCounters;
+
+ bool Initialized = false;
+
+ NMonitoring::TDynamicCounters::TCounterPtr Traffic;
+ NMonitoring::TDynamicCounters::TCounterPtr Events;
+ NMonitoring::TDynamicCounters::TCounterPtr ScopeErrors;
+
+ public:
+ TInterconnectCounters(const TInterconnectProxyCommon::TPtr& common)
+ : Common(common)
+ , MergePerDataCenterCounters(common->Settings.MergePerDataCenterCounters)
+ , MergePerPeerCounters(common->Settings.MergePerPeerCounters)
+ , Counters(common->MonCounters)
, AdaptiveCounters(MergePerDataCenterCounters
? PerDataCenterCounters :
MergePerPeerCounters ? Counters : PerSessionCounters)
- {}
-
- void AddInflightDataAmount(ui64 value) override {
+ {}
+
+ void AddInflightDataAmount(ui64 value) override {
*InflightDataAmount += value;
}
- void SubInflightDataAmount(ui64 value) override {
+ void SubInflightDataAmount(ui64 value) override {
*InflightDataAmount -= value;
}
- void AddTotalBytesWritten(ui64 value) override {
+ void AddTotalBytesWritten(ui64 value) override {
*TotalBytesWritten += value;
}
- void SetClockSkewMicrosec(i64 value) override {
+ void SetClockSkewMicrosec(i64 value) override {
*ClockSkewMicrosec = value;
}
@@ -141,15 +141,15 @@ namespace {
*SubscribersCount -= value;
}
- void SubOutputBuffersTotalSize(ui64 value) override {
+ void SubOutputBuffersTotalSize(ui64 value) override {
*OutputBuffersTotalSize -= value;
}
- void AddOutputBuffersTotalSize(ui64 value) override {
+ void AddOutputBuffersTotalSize(ui64 value) override {
*OutputBuffersTotalSize += value;
}
- ui64 GetOutputBuffersTotalSize() const override {
+ ui64 GetOutputBuffersTotalSize() const override {
return *OutputBuffersTotalSize;
}
@@ -187,7 +187,7 @@ namespace {
}
}
- void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
+ void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
auto& ch = InputChannels.Get(channel);
*ch.IncomingTraffic += incomingTraffic;
}
@@ -201,7 +201,7 @@ namespace {
++*RecvSyscalls;
}
- void AddTotalBytesRead(ui64 value) override {
+ void AddTotalBytesRead(ui64 value) override {
*TotalBytesRead += value;
}
@@ -210,7 +210,7 @@ namespace {
PingTimeHistogram->Collect(value);
}
- void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
+ void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
if (GetOutputChannel(channel).OutgoingTraffic) {
*(GetOutputChannel(channel).OutgoingTraffic) += value;
}
@@ -229,117 +229,117 @@ namespace {
}
void SetPeerInfo(const TString& name, const TString& dataCenterId) override {
- if (name != std::exchange(HumanFriendlyPeerHostName, name)) {
- PerSessionCounters.Reset();
- }
+ if (name != std::exchange(HumanFriendlyPeerHostName, name)) {
+ PerSessionCounters.Reset();
+ }
VALGRIND_MAKE_READABLE(&DataCenterId, sizeof(DataCenterId));
- if (dataCenterId != std::exchange(DataCenterId, dataCenterId)) {
- PerDataCenterCounters.Reset();
- }
-
- const bool updatePerDataCenter = !PerDataCenterCounters && MergePerDataCenterCounters;
- if (updatePerDataCenter) {
- PerDataCenterCounters = Counters->GetSubgroup("dataCenterId", *DataCenterId);
- }
-
- const bool updatePerSession = !PerSessionCounters || updatePerDataCenter;
- if (updatePerSession) {
- auto base = MergePerDataCenterCounters ? PerDataCenterCounters : Counters;
- PerSessionCounters = base->GetSubgroup("peer", *HumanFriendlyPeerHostName);
- }
-
- const bool updateGlobal = !Initialized;
-
- const bool updateAdaptive =
- &AdaptiveCounters == &Counters ? updateGlobal :
- &AdaptiveCounters == &PerSessionCounters ? updatePerSession :
- &AdaptiveCounters == &PerDataCenterCounters ? updatePerDataCenter :
- false;
-
- if (updatePerSession) {
- Connected = PerSessionCounters->GetCounter("Connected");
- Disconnections = PerSessionCounters->GetCounter("Disconnections", true);
- ClockSkewMicrosec = PerSessionCounters->GetCounter("ClockSkewMicrosec");
- Traffic = PerSessionCounters->GetCounter("Traffic", true);
- Events = PerSessionCounters->GetCounter("Events", true);
- ScopeErrors = PerSessionCounters->GetCounter("ScopeErrors", true);
-
- for (const auto& [id, name] : Common->ChannelName) {
- OutputChannels.try_emplace(id, Counters->GetSubgroup("channel", name), Traffic, Events);
- }
- OtherOutputChannel = TOutputChannel(Counters->GetSubgroup("channel", "other"), Traffic, Events);
-
- InputChannels = TInputChannels(Counters, Common->ChannelName, Traffic, Events, ScopeErrors);
- }
-
- if (updateAdaptive) {
- SessionDeaths = AdaptiveCounters->GetCounter("Session_Deaths", true);
- HandshakeFails = AdaptiveCounters->GetCounter("Handshake_Fails", true);
- InflyLimitReach = AdaptiveCounters->GetCounter("InflyLimitReach", true);
- InflightDataAmount = AdaptiveCounters->GetCounter("Inflight_Data");
-
+ if (dataCenterId != std::exchange(DataCenterId, dataCenterId)) {
+ PerDataCenterCounters.Reset();
+ }
+
+ const bool updatePerDataCenter = !PerDataCenterCounters && MergePerDataCenterCounters;
+ if (updatePerDataCenter) {
+ PerDataCenterCounters = Counters->GetSubgroup("dataCenterId", *DataCenterId);
+ }
+
+ const bool updatePerSession = !PerSessionCounters || updatePerDataCenter;
+ if (updatePerSession) {
+ auto base = MergePerDataCenterCounters ? PerDataCenterCounters : Counters;
+ PerSessionCounters = base->GetSubgroup("peer", *HumanFriendlyPeerHostName);
+ }
+
+ const bool updateGlobal = !Initialized;
+
+ const bool updateAdaptive =
+ &AdaptiveCounters == &Counters ? updateGlobal :
+ &AdaptiveCounters == &PerSessionCounters ? updatePerSession :
+ &AdaptiveCounters == &PerDataCenterCounters ? updatePerDataCenter :
+ false;
+
+ if (updatePerSession) {
+ Connected = PerSessionCounters->GetCounter("Connected");
+ Disconnections = PerSessionCounters->GetCounter("Disconnections", true);
+ ClockSkewMicrosec = PerSessionCounters->GetCounter("ClockSkewMicrosec");
+ Traffic = PerSessionCounters->GetCounter("Traffic", true);
+ Events = PerSessionCounters->GetCounter("Events", true);
+ ScopeErrors = PerSessionCounters->GetCounter("ScopeErrors", true);
+
+ for (const auto& [id, name] : Common->ChannelName) {
+ OutputChannels.try_emplace(id, Counters->GetSubgroup("channel", name), Traffic, Events);
+ }
+ OtherOutputChannel = TOutputChannel(Counters->GetSubgroup("channel", "other"), Traffic, Events);
+
+ InputChannels = TInputChannels(Counters, Common->ChannelName, Traffic, Events, ScopeErrors);
+ }
+
+ if (updateAdaptive) {
+ SessionDeaths = AdaptiveCounters->GetCounter("Session_Deaths", true);
+ HandshakeFails = AdaptiveCounters->GetCounter("Handshake_Fails", true);
+ InflyLimitReach = AdaptiveCounters->GetCounter("InflyLimitReach", true);
+ InflightDataAmount = AdaptiveCounters->GetCounter("Inflight_Data");
+
LegacyPingTimeHist = {};
LegacyPingTimeHist.Init(AdaptiveCounters.Get(), "PingTimeHist", "mks", 125, 18);
PingTimeHistogram = AdaptiveCounters->GetHistogram(
"PingTimeUs", NMonitoring::ExponentialHistogram(18, 2, 125));
- }
-
- if (updateGlobal) {
- OutputBuffersTotalSize = Counters->GetCounter("OutputBuffersTotalSize");
- SendSyscalls = Counters->GetCounter("SendSyscalls", true);
- RecvSyscalls = Counters->GetCounter("RecvSyscalls", true);
- SpuriousReadWakeups = Counters->GetCounter("SpuriousReadWakeups", true);
- UsefulReadWakeups = Counters->GetCounter("UsefulReadWakeups", true);
- SpuriousWriteWakeups = Counters->GetCounter("SpuriousWriteWakeups", true);
- UsefulWriteWakeups = Counters->GetCounter("UsefulWriteWakeups", true);
- SubscribersCount = AdaptiveCounters->GetCounter("SubscribersCount");
- TotalBytesWritten = Counters->GetCounter("TotalBytesWritten", true);
- TotalBytesRead = Counters->GetCounter("TotalBytesRead", true);
-
- auto disconnectReasonGroup = Counters->GetSubgroup("subsystem", "disconnectReason");
- for (const char *reason : TDisconnectReason::Reasons) {
+ }
+
+ if (updateGlobal) {
+ OutputBuffersTotalSize = Counters->GetCounter("OutputBuffersTotalSize");
+ SendSyscalls = Counters->GetCounter("SendSyscalls", true);
+ RecvSyscalls = Counters->GetCounter("RecvSyscalls", true);
+ SpuriousReadWakeups = Counters->GetCounter("SpuriousReadWakeups", true);
+ UsefulReadWakeups = Counters->GetCounter("UsefulReadWakeups", true);
+ SpuriousWriteWakeups = Counters->GetCounter("SpuriousWriteWakeups", true);
+ UsefulWriteWakeups = Counters->GetCounter("UsefulWriteWakeups", true);
+ SubscribersCount = AdaptiveCounters->GetCounter("SubscribersCount");
+ TotalBytesWritten = Counters->GetCounter("TotalBytesWritten", true);
+ TotalBytesRead = Counters->GetCounter("TotalBytesRead", true);
+
+ auto disconnectReasonGroup = Counters->GetSubgroup("subsystem", "disconnectReason");
+ for (const char *reason : TDisconnectReason::Reasons) {
DisconnectByReason[reason] = disconnectReasonGroup->GetCounter(reason, true);
- }
- }
-
- Initialized = true;
- }
-
- TOutputChannel GetOutputChannel(ui16 index) const {
- Y_VERIFY(Initialized);
- const auto it = OutputChannels.find(index);
- return it != OutputChannels.end() ? it->second : OtherOutputChannel;
- }
-
+ }
+ }
+
+ Initialized = true;
+ }
+
+ TOutputChannel GetOutputChannel(ui16 index) const {
+ Y_VERIFY(Initialized);
+ const auto it = OutputChannels.find(index);
+ return it != OutputChannels.end() ? it->second : OtherOutputChannel;
+ }
+
private:
- NMonitoring::TDynamicCounters::TCounterPtr SessionDeaths;
- NMonitoring::TDynamicCounters::TCounterPtr HandshakeFails;
- NMonitoring::TDynamicCounters::TCounterPtr Connected;
- NMonitoring::TDynamicCounters::TCounterPtr Disconnections;
- NMonitoring::TDynamicCounters::TCounterPtr InflightDataAmount;
- NMonitoring::TDynamicCounters::TCounterPtr InflyLimitReach;
- NMonitoring::TDynamicCounters::TCounterPtr OutputBuffersTotalSize;
- NMonitoring::TDynamicCounters::TCounterPtr QueueUtilization;
- NMonitoring::TDynamicCounters::TCounterPtr SubscribersCount;
- NMonitoring::TDynamicCounters::TCounterPtr SendSyscalls;
- NMonitoring::TDynamicCounters::TCounterPtr ClockSkewMicrosec;
- NMonitoring::TDynamicCounters::TCounterPtr RecvSyscalls;
- NMonitoring::TDynamicCounters::TCounterPtr UsefulReadWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr SpuriousReadWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr UsefulWriteWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr SpuriousWriteWakeups;
+ NMonitoring::TDynamicCounters::TCounterPtr SessionDeaths;
+ NMonitoring::TDynamicCounters::TCounterPtr HandshakeFails;
+ NMonitoring::TDynamicCounters::TCounterPtr Connected;
+ NMonitoring::TDynamicCounters::TCounterPtr Disconnections;
+ NMonitoring::TDynamicCounters::TCounterPtr InflightDataAmount;
+ NMonitoring::TDynamicCounters::TCounterPtr InflyLimitReach;
+ NMonitoring::TDynamicCounters::TCounterPtr OutputBuffersTotalSize;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueUtilization;
+ NMonitoring::TDynamicCounters::TCounterPtr SubscribersCount;
+ NMonitoring::TDynamicCounters::TCounterPtr SendSyscalls;
+ NMonitoring::TDynamicCounters::TCounterPtr ClockSkewMicrosec;
+ NMonitoring::TDynamicCounters::TCounterPtr RecvSyscalls;
+ NMonitoring::TDynamicCounters::TCounterPtr UsefulReadWakeups;
+ NMonitoring::TDynamicCounters::TCounterPtr SpuriousReadWakeups;
+ NMonitoring::TDynamicCounters::TCounterPtr UsefulWriteWakeups;
+ NMonitoring::TDynamicCounters::TCounterPtr SpuriousWriteWakeups;
NMon::THistogramCounterHelper LegacyPingTimeHist;
NMonitoring::THistogramPtr PingTimeHistogram;
- std::unordered_map<ui16, TOutputChannel> OutputChannels;
- TOutputChannel OtherOutputChannel;
- TInputChannels InputChannels;
- THashMap<TString, NMonitoring::TDynamicCounters::TCounterPtr> DisconnectByReason;
-
- NMonitoring::TDynamicCounters::TCounterPtr TotalBytesWritten, TotalBytesRead;
- };
-
+ std::unordered_map<ui16, TOutputChannel> OutputChannels;
+ TOutputChannel OtherOutputChannel;
+ TInputChannels InputChannels;
+ THashMap<TString, NMonitoring::TDynamicCounters::TCounterPtr> DisconnectByReason;
+
+ NMonitoring::TDynamicCounters::TCounterPtr TotalBytesWritten, TotalBytesRead;
+ };
+
class TInterconnectMetrics: public IInterconnectMetrics {
public:
struct TOutputChannel {
@@ -420,19 +420,19 @@ namespace {
MergePerPeerMetrics_ ? Metrics_ : PerSessionMetrics_)
{}
- void AddInflightDataAmount(ui64 value) override {
+ void AddInflightDataAmount(ui64 value) override {
InflightDataAmount_->Add(value);
}
- void SubInflightDataAmount(ui64 value) override {
+ void SubInflightDataAmount(ui64 value) override {
InflightDataAmount_->Add(-value);
}
- void AddTotalBytesWritten(ui64 value) override {
+ void AddTotalBytesWritten(ui64 value) override {
TotalBytesWritten_->Add(value);
}
- void SetClockSkewMicrosec(i64 value) override {
+ void SetClockSkewMicrosec(i64 value) override {
ClockSkewMicrosec_->Set(value);
}
@@ -456,15 +456,15 @@ namespace {
SubscribersCount_->Add(-value);
}
- void SubOutputBuffersTotalSize(ui64 value) override {
+ void SubOutputBuffersTotalSize(ui64 value) override {
OutputBuffersTotalSize_->Add(-value);
}
- void AddOutputBuffersTotalSize(ui64 value) override {
+ void AddOutputBuffersTotalSize(ui64 value) override {
OutputBuffersTotalSize_->Add(value);
}
- ui64 GetOutputBuffersTotalSize() const override {
+ ui64 GetOutputBuffersTotalSize() const override {
return OutputBuffersTotalSize_->Get();
}
@@ -502,7 +502,7 @@ namespace {
}
}
- void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
+ void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
auto& ch = InputChannels_.Get(channel);
ch.IncomingTraffic->Add(incomingTraffic);
}
@@ -516,7 +516,7 @@ namespace {
RecvSyscalls_->Inc();
}
- void AddTotalBytesRead(ui64 value) override {
+ void AddTotalBytesRead(ui64 value) override {
TotalBytesRead_->Add(value);
}
@@ -524,7 +524,7 @@ namespace {
PingTimeHistogram_->Record(value);
}
- void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
+ void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
if (GetOutputChannel(channel).OutgoingTraffic) {
GetOutputChannel(channel).OutgoingTraffic->Add(value);
}
@@ -689,4 +689,4 @@ std::unique_ptr<IInterconnectMetrics> CreateInterconnectMetrics(const TInterconn
return std::make_unique<TInterconnectMetrics>(common);
}
-} // NActors
+} // NActors
diff --git a/library/cpp/actors/interconnect/interconnect_counters.h b/library/cpp/actors/interconnect/interconnect_counters.h
index e30f03a0bcc..b6f7d288d44 100644
--- a/library/cpp/actors/interconnect/interconnect_counters.h
+++ b/library/cpp/actors/interconnect/interconnect_counters.h
@@ -17,18 +17,18 @@ class IInterconnectMetrics {
public:
virtual ~IInterconnectMetrics() = default;
- virtual void AddInflightDataAmount(ui64 value) = 0;
- virtual void SubInflightDataAmount(ui64 value) = 0;
- virtual void AddTotalBytesWritten(ui64 value) = 0;
- virtual void SetClockSkewMicrosec(i64 value) = 0;
+ virtual void AddInflightDataAmount(ui64 value) = 0;
+ virtual void SubInflightDataAmount(ui64 value) = 0;
+ virtual void AddTotalBytesWritten(ui64 value) = 0;
+ virtual void SetClockSkewMicrosec(i64 value) = 0;
virtual void IncSessionDeaths() = 0;
virtual void IncHandshakeFails() = 0;
virtual void SetConnected(ui32 value) = 0;
virtual void IncSubscribersCount() = 0;
virtual void SubSubscribersCount(ui32 value) = 0;
- virtual void SubOutputBuffersTotalSize(ui64 value) = 0;
- virtual void AddOutputBuffersTotalSize(ui64 value) = 0;
- virtual ui64 GetOutputBuffersTotalSize() const = 0;
+ virtual void SubOutputBuffersTotalSize(ui64 value) = 0;
+ virtual void AddOutputBuffersTotalSize(ui64 value) = 0;
+ virtual ui64 GetOutputBuffersTotalSize() const = 0;
virtual void IncDisconnections() = 0;
virtual void IncUsefulWriteWakeups() = 0;
virtual void IncSpuriousWriteWakeups() = 0;
@@ -38,12 +38,12 @@ public:
virtual void IncUsefulReadWakeups() = 0;
virtual void IncSpuriousReadWakeups() = 0;
virtual void SetPeerInfo(const TString& name, const TString& dataCenterId) = 0;
- virtual void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) = 0;
+ virtual void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) = 0;
virtual void IncInputChannelsIncomingEvents(ui16 channel) = 0;
virtual void IncRecvSyscalls() = 0;
- virtual void AddTotalBytesRead(ui64 value) = 0;
+ virtual void AddTotalBytesRead(ui64 value) = 0;
virtual void UpdateLegacyPingTimeHist(ui64 value) = 0;
- virtual void UpdateOutputChannelTraffic(ui16 channel, ui64 value) = 0;
+ virtual void UpdateOutputChannelTraffic(ui16 channel, ui64 value) = 0;
virtual void UpdateOutputChannelEvents(ui16 channel) = 0;
TString GetHumanFriendlyPeerHostName() const {
return HumanFriendlyPeerHostName.value_or(TString());
diff --git a/library/cpp/actors/interconnect/interconnect_handshake.cpp b/library/cpp/actors/interconnect/interconnect_handshake.cpp
index 9ede998d8e7..ce5dc7f705f 100644
--- a/library/cpp/actors/interconnect/interconnect_handshake.cpp
+++ b/library/cpp/actors/interconnect/interconnect_handshake.cpp
@@ -1,995 +1,995 @@
-#include "interconnect_handshake.h"
-#include "interconnect_tcp_proxy.h"
-
+#include "interconnect_handshake.h"
+#include "interconnect_tcp_proxy.h"
+
#include <library/cpp/actors/core/actor_coroutine.h>
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-#include <util/system/getpid.h>
-
+#include <util/system/getpid.h>
+
#include <google/protobuf/text_format.h>
-
+
#include <variant>
-namespace NActors {
- static constexpr size_t StackSize = 64 * 1024; // 64k should be enough
-
- class THandshakeActor
- : public TActorCoroImpl
- , public TInterconnectLoggingBase
- {
- struct TExHandshakeFailed : yexception {};
-
- static constexpr TDuration ResolveTimeout = TDuration::Seconds(1);
-
-#pragma pack(push, 1)
-
- struct TInitialPacket {
- struct {
+namespace NActors {
+ static constexpr size_t StackSize = 64 * 1024; // 64k should be enough
+
+ class THandshakeActor
+ : public TActorCoroImpl
+ , public TInterconnectLoggingBase
+ {
+ struct TExHandshakeFailed : yexception {};
+
+ static constexpr TDuration ResolveTimeout = TDuration::Seconds(1);
+
+#pragma pack(push, 1)
+
+ struct TInitialPacket {
+ struct {
TActorId SelfVirtualId;
TActorId PeerVirtualId;
- ui64 NextPacket;
- ui64 Version;
- } Header;
- ui32 Checksum;
-
- TInitialPacket() = default;
-
+ ui64 NextPacket;
+ ui64 Version;
+ } Header;
+ ui32 Checksum;
+
+ TInitialPacket() = default;
+
TInitialPacket(const TActorId& self, const TActorId& peer, ui64 nextPacket, ui64 version) {
- Header.SelfVirtualId = self;
- Header.PeerVirtualId = peer;
- Header.NextPacket = nextPacket;
- Header.Version = version;
- Checksum = Crc32cExtendMSanCompatible(0, &Header, sizeof(Header));
- }
-
- bool Check() const {
- return Checksum == Crc32cExtendMSanCompatible(0, &Header, sizeof(Header));
- }
-
- TString ToString() const {
- return TStringBuilder()
- << "{SelfVirtualId# " << Header.SelfVirtualId.ToString()
- << " PeerVirtualId# " << Header.PeerVirtualId.ToString()
- << " NextPacket# " << Header.NextPacket
- << " Version# " << Header.Version
- << "}";
- }
- };
-
- struct TExHeader {
- static constexpr ui32 MaxSize = 1024 * 1024;
-
- ui32 Checksum;
- ui32 Size;
-
+ Header.SelfVirtualId = self;
+ Header.PeerVirtualId = peer;
+ Header.NextPacket = nextPacket;
+ Header.Version = version;
+ Checksum = Crc32cExtendMSanCompatible(0, &Header, sizeof(Header));
+ }
+
+ bool Check() const {
+ return Checksum == Crc32cExtendMSanCompatible(0, &Header, sizeof(Header));
+ }
+
+ TString ToString() const {
+ return TStringBuilder()
+ << "{SelfVirtualId# " << Header.SelfVirtualId.ToString()
+ << " PeerVirtualId# " << Header.PeerVirtualId.ToString()
+ << " NextPacket# " << Header.NextPacket
+ << " Version# " << Header.Version
+ << "}";
+ }
+ };
+
+ struct TExHeader {
+ static constexpr ui32 MaxSize = 1024 * 1024;
+
+ ui32 Checksum;
+ ui32 Size;
+
ui32 CalculateChecksum(const void* data, size_t len) const {
- return Crc32cExtendMSanCompatible(Crc32cExtendMSanCompatible(0, &Size, sizeof(Size)), data, len);
- }
-
+ return Crc32cExtendMSanCompatible(Crc32cExtendMSanCompatible(0, &Size, sizeof(Size)), data, len);
+ }
+
void Sign(const void* data, size_t len) {
- Checksum = CalculateChecksum(data, len);
- }
-
+ Checksum = CalculateChecksum(data, len);
+ }
+
bool Check(const void* data, size_t len) const {
- return Checksum == CalculateChecksum(data, len);
- }
- };
-
-#pragma pack(pop)
-
- private:
- TInterconnectProxyCommon::TPtr Common;
+ return Checksum == CalculateChecksum(data, len);
+ }
+ };
+
+#pragma pack(pop)
+
+ private:
+ TInterconnectProxyCommon::TPtr Common;
TActorId SelfVirtualId;
TActorId PeerVirtualId;
- ui32 PeerNodeId = 0;
- ui64 NextPacketToPeer = 0;
- TMaybe<ui64> NextPacketFromPeer; // will be obtained from incoming initial packet
- TString PeerHostName;
- TString PeerAddr;
- TSocketPtr Socket;
- TPollerToken::TPtr PollerToken;
- TString State;
- TString HandshakeKind;
- TMaybe<THolder<TProgramInfo>> ProgramInfo; // filled in in case of successful handshake; even if null
- TSessionParams Params;
- bool ResolveTimedOut = false;
+ ui32 PeerNodeId = 0;
+ ui64 NextPacketToPeer = 0;
+ TMaybe<ui64> NextPacketFromPeer; // will be obtained from incoming initial packet
+ TString PeerHostName;
+ TString PeerAddr;
+ TSocketPtr Socket;
+ TPollerToken::TPtr PollerToken;
+ TString State;
+ TString HandshakeKind;
+ TMaybe<THolder<TProgramInfo>> ProgramInfo; // filled in in case of successful handshake; even if null
+ TSessionParams Params;
+ bool ResolveTimedOut = false;
THashMap<ui32, TInstant> LastLogNotice;
const TDuration MuteDuration = TDuration::Seconds(15);
- TInstant Deadline;
-
- public:
+ TInstant Deadline;
+
+ public:
static constexpr IActor::EActivityType ActorActivityType() {
return IActor::INTERCONNECT_HANDSHAKE;
}
THandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, const TActorId& peer,
- ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params)
- : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors
- , Common(std::move(common))
- , SelfVirtualId(self)
- , PeerVirtualId(peer)
- , PeerNodeId(nodeId)
- , NextPacketToPeer(nextPacket)
- , PeerHostName(std::move(peerHostName))
- , HandshakeKind("outgoing handshake")
- , Params(std::move(params))
- {
- Y_VERIFY(SelfVirtualId);
- Y_VERIFY(SelfVirtualId.NodeId());
- Y_VERIFY(PeerNodeId);
- }
-
- THandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket)
- : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors
- , Common(std::move(common))
- , Socket(std::move(socket))
- , HandshakeKind("incoming handshake")
- {
- Y_VERIFY(Socket);
- PeerAddr = TString::Uninitialized(1024);
- if (GetRemoteAddr(*Socket, PeerAddr.Detach(), PeerAddr.size())) {
+ ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params)
+ : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors
+ , Common(std::move(common))
+ , SelfVirtualId(self)
+ , PeerVirtualId(peer)
+ , PeerNodeId(nodeId)
+ , NextPacketToPeer(nextPacket)
+ , PeerHostName(std::move(peerHostName))
+ , HandshakeKind("outgoing handshake")
+ , Params(std::move(params))
+ {
+ Y_VERIFY(SelfVirtualId);
+ Y_VERIFY(SelfVirtualId.NodeId());
+ Y_VERIFY(PeerNodeId);
+ }
+
+ THandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket)
+ : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors
+ , Common(std::move(common))
+ , Socket(std::move(socket))
+ , HandshakeKind("incoming handshake")
+ {
+ Y_VERIFY(Socket);
+ PeerAddr = TString::Uninitialized(1024);
+ if (GetRemoteAddr(*Socket, PeerAddr.Detach(), PeerAddr.size())) {
PeerAddr.resize(strlen(PeerAddr.data()));
- } else {
- PeerAddr.clear();
- }
- }
-
- void UpdatePrefix() {
- SetPrefix(Sprintf("Handshake %s [node %" PRIu32 "]", SelfActorId.ToString().data(), PeerNodeId));
- }
-
- void Run() override {
- UpdatePrefix();
-
- // set up overall handshake process timer
- TDuration timeout = Common->Settings.Handshake;
- if (timeout == TDuration::Zero()) {
- timeout = DEFAULT_HANDSHAKE_TIMEOUT;
- }
- timeout += ResolveTimeout * 2;
- Deadline = Now() + timeout;
- Schedule(Deadline, new TEvents::TEvWakeup);
-
- try {
- if (Socket) {
- PerformIncomingHandshake();
- } else {
- PerformOutgoingHandshake();
- }
-
- // establish encrypted channel, or, in case when encryption is disabled, check if it matches settings
- if (ProgramInfo) {
- if (Params.Encryption) {
- EstablishSecureConnection();
- } else if (Common->Settings.EncryptionMode == EEncryptionMode::REQUIRED && !Params.AuthOnly) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Peer doesn't support encryption, which is required");
- }
- }
- } catch (const TExHandshakeFailed&) {
- ProgramInfo.Clear();
- }
-
- if (ProgramInfo) {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH04", NLog::PRI_INFO, "handshake succeeded");
- Y_VERIFY(NextPacketFromPeer);
- if (PollerToken) {
- Y_VERIFY(PollerToken->RefCount() == 1);
- PollerToken.Reset(); // ensure we are going to destroy poller token here as we will re-register the socket within other actor
- }
- SendToProxy(MakeHolder<TEvHandshakeDone>(std::move(Socket), PeerVirtualId, SelfVirtualId,
- *NextPacketFromPeer, ProgramInfo->Release(), std::move(Params)));
- }
-
- Socket.Reset();
- }
-
- void EstablishSecureConnection() {
- Y_VERIFY(PollerToken && PollerToken->RefCount() == 1);
- PollerToken.Reset();
- auto ev = AskProxy<TEvSecureSocket>(MakeHolder<TEvGetSecureSocket>(Socket), "AskProxy(TEvSecureContext)");
- Socket = std::move(ev->Get()->Socket);
- RegisterInPoller();
- const ui32 myNodeId = GetActorSystem()->NodeId;
- const bool server = myNodeId < PeerNodeId; // keep server/client role permanent to enable easy TLS session resuming
- for (;;) {
- TString err;
- auto& secure = static_cast<NInterconnect::TSecureSocket&>(*Socket);
- switch (secure.Establish(server, Params.AuthOnly, err)) {
- case NInterconnect::TSecureSocket::EStatus::SUCCESS:
- if (Params.AuthOnly) {
- Params.Encryption = false;
- Params.AuthCN = secure.GetPeerCommonName();
- Y_VERIFY(PollerToken && PollerToken->RefCount() == 1);
- PollerToken.Reset();
- Socket = secure.Detach();
- }
- return;
-
- case NInterconnect::TSecureSocket::EStatus::ERROR:
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, err, true);
+ } else {
+ PeerAddr.clear();
+ }
+ }
+
+ void UpdatePrefix() {
+ SetPrefix(Sprintf("Handshake %s [node %" PRIu32 "]", SelfActorId.ToString().data(), PeerNodeId));
+ }
+
+ void Run() override {
+ UpdatePrefix();
+
+ // set up overall handshake process timer
+ TDuration timeout = Common->Settings.Handshake;
+ if (timeout == TDuration::Zero()) {
+ timeout = DEFAULT_HANDSHAKE_TIMEOUT;
+ }
+ timeout += ResolveTimeout * 2;
+ Deadline = Now() + timeout;
+ Schedule(Deadline, new TEvents::TEvWakeup);
+
+ try {
+ if (Socket) {
+ PerformIncomingHandshake();
+ } else {
+ PerformOutgoingHandshake();
+ }
+
+ // establish encrypted channel, or, in case when encryption is disabled, check if it matches settings
+ if (ProgramInfo) {
+ if (Params.Encryption) {
+ EstablishSecureConnection();
+ } else if (Common->Settings.EncryptionMode == EEncryptionMode::REQUIRED && !Params.AuthOnly) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Peer doesn't support encryption, which is required");
+ }
+ }
+ } catch (const TExHandshakeFailed&) {
+ ProgramInfo.Clear();
+ }
+
+ if (ProgramInfo) {
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH04", NLog::PRI_INFO, "handshake succeeded");
+ Y_VERIFY(NextPacketFromPeer);
+ if (PollerToken) {
+ Y_VERIFY(PollerToken->RefCount() == 1);
+ PollerToken.Reset(); // ensure we are going to destroy poller token here as we will re-register the socket within other actor
+ }
+ SendToProxy(MakeHolder<TEvHandshakeDone>(std::move(Socket), PeerVirtualId, SelfVirtualId,
+ *NextPacketFromPeer, ProgramInfo->Release(), std::move(Params)));
+ }
+
+ Socket.Reset();
+ }
+
+ void EstablishSecureConnection() {
+ Y_VERIFY(PollerToken && PollerToken->RefCount() == 1);
+ PollerToken.Reset();
+ auto ev = AskProxy<TEvSecureSocket>(MakeHolder<TEvGetSecureSocket>(Socket), "AskProxy(TEvSecureContext)");
+ Socket = std::move(ev->Get()->Socket);
+ RegisterInPoller();
+ const ui32 myNodeId = GetActorSystem()->NodeId;
+ const bool server = myNodeId < PeerNodeId; // keep server/client role permanent to enable easy TLS session resuming
+ for (;;) {
+ TString err;
+ auto& secure = static_cast<NInterconnect::TSecureSocket&>(*Socket);
+ switch (secure.Establish(server, Params.AuthOnly, err)) {
+ case NInterconnect::TSecureSocket::EStatus::SUCCESS:
+ if (Params.AuthOnly) {
+ Params.Encryption = false;
+ Params.AuthCN = secure.GetPeerCommonName();
+ Y_VERIFY(PollerToken && PollerToken->RefCount() == 1);
+ PollerToken.Reset();
+ Socket = secure.Detach();
+ }
+ return;
+
+ case NInterconnect::TSecureSocket::EStatus::ERROR:
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, err, true);
[[fallthrough]];
-
- case NInterconnect::TSecureSocket::EStatus::WANT_READ:
- WaitPoller(true, false, "ReadEstablish");
- break;
-
- case NInterconnect::TSecureSocket::EStatus::WANT_WRITE:
- WaitPoller(false, true, "WriteEstablish");
- break;
- }
- }
- }
-
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- case TEvents::TSystem::Wakeup:
+
+ case NInterconnect::TSecureSocket::EStatus::WANT_READ:
+ WaitPoller(true, false, "ReadEstablish");
+ break;
+
+ case NInterconnect::TSecureSocket::EStatus::WANT_WRITE:
+ WaitPoller(false, true, "WriteEstablish");
+ break;
+ }
+ }
+ }
+
+ void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ case TEvents::TSystem::Wakeup:
Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, Sprintf("Handshake timed out, State# %s", State.data()), true);
[[fallthrough]];
-
- case ui32(ENetwork::NodeInfo):
- case TEvInterconnect::EvNodeAddress:
- case ui32(ENetwork::ResolveError):
- break; // most likely a race with resolve timeout
-
- case TEvPollerReady::EventType:
- break;
-
- default:
- Y_FAIL("unexpected event 0x%08" PRIx32, type);
- }
- }
-
- template<typename T>
- void SetupVersionTag(T& proto) {
- if (Common->VersionInfo) {
- proto.SetVersionTag(Common->VersionInfo->Tag);
- for (const TString& accepted : Common->VersionInfo->AcceptedTags) {
- proto.AddAcceptedVersionTags(accepted);
- }
- }
- }
-
- template<typename T>
- void SetupClusterUUID(T& proto) {
- auto *pb = proto.MutableClusterUUIDs();
- pb->SetClusterUUID(Common->ClusterUUID);
- for (const TString& uuid : Common->AcceptUUID) {
- pb->AddAcceptUUID(uuid);
- }
- }
-
- template<typename T, typename TCallback>
- void ValidateVersionTag(const T& proto, TCallback&& errorCallback) {
- // check if we will accept peer's version tag (if peer provides one and if we have accepted list non-empty)
- if (Common->VersionInfo) {
- if (!proto.HasVersionTag()) {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH06", NLog::PRI_WARN,
- "peer did not report VersionTag, accepting by default");
- } else if (!Common->VersionInfo->AcceptedTags.count(proto.GetVersionTag())) {
- // we will not accept peer's tag, so check if remote peer would accept our version tag
- size_t i;
- for (i = 0; i < proto.AcceptedVersionTagsSize() && Common->VersionInfo->Tag != proto.GetAcceptedVersionTags(i); ++i)
- {}
- if (i == proto.AcceptedVersionTagsSize()) {
- // peer will neither accept our version -- this is total failure
- TStringStream s("local/peer version tags did not match accepted ones");
- s << " local Tag# " << Common->VersionInfo->Tag << " accepted Tags# [";
- bool first = true;
- for (const auto& tag : Common->VersionInfo->AcceptedTags) {
- s << (std::exchange(first, false) ? "" : " ") << tag;
- }
- s << "] peer Tag# " << proto.GetVersionTag() << " accepted Tags# [";
- first = true;
- for (const auto& tag : proto.GetAcceptedVersionTags()) {
- s << (std::exchange(first, false) ? "" : " ") << tag;
- }
- s << "]";
- errorCallback(s.Str());
- }
- }
- }
- }
-
- template<typename T, typename TCallback>
- void ValidateClusterUUID(const T& proto, TCallback&& errorCallback, const TMaybe<TString>& uuid = {}) {
- auto formatList = [](const auto& list) {
- TStringStream s;
- s << "[";
- for (auto it = list.begin(); it != list.end(); ++it) {
- if (it != list.begin()) {
- s << " ";
- }
- s << *it;
- }
- s << "]";
- return s.Str();
- };
- if (!Common->AcceptUUID) {
- return; // promiscuous mode -- we accept every other peer
- }
- if (!proto.HasClusterUUIDs()) {
- if (uuid) {
- // old-style checking, peer does not support symmetric protoocol
- bool matching = false;
- for (const TString& accepted : Common->AcceptUUID) {
- if (*uuid == accepted) {
- matching = true;
- break;
- }
- }
- if (!matching) {
+
+ case ui32(ENetwork::NodeInfo):
+ case TEvInterconnect::EvNodeAddress:
+ case ui32(ENetwork::ResolveError):
+ break; // most likely a race with resolve timeout
+
+ case TEvPollerReady::EventType:
+ break;
+
+ default:
+ Y_FAIL("unexpected event 0x%08" PRIx32, type);
+ }
+ }
+
+ template<typename T>
+ void SetupVersionTag(T& proto) {
+ if (Common->VersionInfo) {
+ proto.SetVersionTag(Common->VersionInfo->Tag);
+ for (const TString& accepted : Common->VersionInfo->AcceptedTags) {
+ proto.AddAcceptedVersionTags(accepted);
+ }
+ }
+ }
+
+ template<typename T>
+ void SetupClusterUUID(T& proto) {
+ auto *pb = proto.MutableClusterUUIDs();
+ pb->SetClusterUUID(Common->ClusterUUID);
+ for (const TString& uuid : Common->AcceptUUID) {
+ pb->AddAcceptUUID(uuid);
+ }
+ }
+
+ template<typename T, typename TCallback>
+ void ValidateVersionTag(const T& proto, TCallback&& errorCallback) {
+ // check if we will accept peer's version tag (if peer provides one and if we have accepted list non-empty)
+ if (Common->VersionInfo) {
+ if (!proto.HasVersionTag()) {
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH06", NLog::PRI_WARN,
+ "peer did not report VersionTag, accepting by default");
+ } else if (!Common->VersionInfo->AcceptedTags.count(proto.GetVersionTag())) {
+ // we will not accept peer's tag, so check if remote peer would accept our version tag
+ size_t i;
+ for (i = 0; i < proto.AcceptedVersionTagsSize() && Common->VersionInfo->Tag != proto.GetAcceptedVersionTags(i); ++i)
+ {}
+ if (i == proto.AcceptedVersionTagsSize()) {
+ // peer will neither accept our version -- this is total failure
+ TStringStream s("local/peer version tags did not match accepted ones");
+ s << " local Tag# " << Common->VersionInfo->Tag << " accepted Tags# [";
+ bool first = true;
+ for (const auto& tag : Common->VersionInfo->AcceptedTags) {
+ s << (std::exchange(first, false) ? "" : " ") << tag;
+ }
+ s << "] peer Tag# " << proto.GetVersionTag() << " accepted Tags# [";
+ first = true;
+ for (const auto& tag : proto.GetAcceptedVersionTags()) {
+ s << (std::exchange(first, false) ? "" : " ") << tag;
+ }
+ s << "]";
+ errorCallback(s.Str());
+ }
+ }
+ }
+ }
+
+ template<typename T, typename TCallback>
+ void ValidateClusterUUID(const T& proto, TCallback&& errorCallback, const TMaybe<TString>& uuid = {}) {
+ auto formatList = [](const auto& list) {
+ TStringStream s;
+ s << "[";
+ for (auto it = list.begin(); it != list.end(); ++it) {
+ if (it != list.begin()) {
+ s << " ";
+ }
+ s << *it;
+ }
+ s << "]";
+ return s.Str();
+ };
+ if (!Common->AcceptUUID) {
+ return; // promiscuous mode -- we accept every other peer
+ }
+ if (!proto.HasClusterUUIDs()) {
+ if (uuid) {
+ // old-style checking, peer does not support symmetric protoocol
+ bool matching = false;
+ for (const TString& accepted : Common->AcceptUUID) {
+ if (*uuid == accepted) {
+ matching = true;
+ break;
+ }
+ }
+ if (!matching) {
errorCallback(Sprintf("Peer ClusterUUID# %s mismatch, AcceptUUID# %s", uuid->data(), formatList(Common->AcceptUUID).data()));
- }
- }
- return; // remote side did not fill in this field -- old version, symmetric protocol is not supported
- }
-
- const auto& uuids = proto.GetClusterUUIDs();
-
- // check if our UUID matches remote accept list
- for (const TString& item : uuids.GetAcceptUUID()) {
- if (item == Common->ClusterUUID) {
- return; // match
- }
- }
-
- // check if remote UUID matches our accept list
- const TString& remoteUUID = uuids.GetClusterUUID();
- for (const TString& item : Common->AcceptUUID) {
- if (item == remoteUUID) {
- return; // match
- }
- }
-
- // no match
+ }
+ }
+ return; // remote side did not fill in this field -- old version, symmetric protocol is not supported
+ }
+
+ const auto& uuids = proto.GetClusterUUIDs();
+
+ // check if our UUID matches remote accept list
+ for (const TString& item : uuids.GetAcceptUUID()) {
+ if (item == Common->ClusterUUID) {
+ return; // match
+ }
+ }
+
+ // check if remote UUID matches our accept list
+ const TString& remoteUUID = uuids.GetClusterUUID();
+ for (const TString& item : Common->AcceptUUID) {
+ if (item == remoteUUID) {
+ return; // match
+ }
+ }
+
+ // no match
errorCallback(Sprintf("Peer ClusterUUID# %s mismatch, AcceptUUID# %s", remoteUUID.data(), formatList(Common->AcceptUUID).data()));
- }
-
- void ParsePeerScopeId(const NActorsInterconnect::TScopeId& proto) {
- Params.PeerScopeId = {proto.GetX1(), proto.GetX2()};
- }
-
- void FillInScopeId(NActorsInterconnect::TScopeId& proto) {
- const TScopeId& scope = Common->LocalScopeId;
- proto.SetX1(scope.first);
- proto.SetX2(scope.second);
- }
-
- template<typename T>
- void ReportProto(const T& protobuf, const char *msg) {
- auto formatString = [&] {
- google::protobuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString s;
- p.PrintToString(protobuf, &s);
- return s;
- };
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH07", NLog::PRI_DEBUG, "%s %s", msg,
- formatString().data());
- }
-
- bool CheckPeerCookie(const TString& cookie, TString *error) {
- // create a temporary socket to connect to the peer
- TSocketPtr tempSocket;
- std::swap(tempSocket, Socket);
- TPollerToken::TPtr tempPollerToken;
- std::swap(tempPollerToken, PollerToken);
-
- // set up virtual self id to ensure peer will not drop our connection
- char buf[12] = {'c', 'o', 'o', 'k', 'i', 'e', ' ', 'c', 'h', 'e', 'c', 'k'};
+ }
+
+ void ParsePeerScopeId(const NActorsInterconnect::TScopeId& proto) {
+ Params.PeerScopeId = {proto.GetX1(), proto.GetX2()};
+ }
+
+ void FillInScopeId(NActorsInterconnect::TScopeId& proto) {
+ const TScopeId& scope = Common->LocalScopeId;
+ proto.SetX1(scope.first);
+ proto.SetX2(scope.second);
+ }
+
+ template<typename T>
+ void ReportProto(const T& protobuf, const char *msg) {
+ auto formatString = [&] {
+ google::protobuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString s;
+ p.PrintToString(protobuf, &s);
+ return s;
+ };
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH07", NLog::PRI_DEBUG, "%s %s", msg,
+ formatString().data());
+ }
+
+ bool CheckPeerCookie(const TString& cookie, TString *error) {
+ // create a temporary socket to connect to the peer
+ TSocketPtr tempSocket;
+ std::swap(tempSocket, Socket);
+ TPollerToken::TPtr tempPollerToken;
+ std::swap(tempPollerToken, PollerToken);
+
+ // set up virtual self id to ensure peer will not drop our connection
+ char buf[12] = {'c', 'o', 'o', 'k', 'i', 'e', ' ', 'c', 'h', 'e', 'c', 'k'};
SelfVirtualId = TActorId(SelfActorId.NodeId(), TStringBuf(buf, 12));
-
- bool success = true;
- try {
- // issue connection and send initial packet
- Connect(false);
- SendInitialPacket();
-
- // wait for basic response
- TInitialPacket response;
- ReceiveData(&response, sizeof(response), "ReceiveResponse");
- if (!response.Check()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
- } else if (response.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, response.Header.Version));
- }
-
- // issue cookie check request
- NActorsInterconnect::THandshakeRequest request;
- request.SetProtocol(INTERCONNECT_PROTOCOL_VERSION);
- request.SetProgramPID(0);
- request.SetProgramStartTime(0);
- request.SetSerial(0);
- request.SetReceiverNodeId(0);
+
+ bool success = true;
+ try {
+ // issue connection and send initial packet
+ Connect(false);
+ SendInitialPacket();
+
+ // wait for basic response
+ TInitialPacket response;
+ ReceiveData(&response, sizeof(response), "ReceiveResponse");
+ if (!response.Check()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
+ } else if (response.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, response.Header.Version));
+ }
+
+ // issue cookie check request
+ NActorsInterconnect::THandshakeRequest request;
+ request.SetProtocol(INTERCONNECT_PROTOCOL_VERSION);
+ request.SetProgramPID(0);
+ request.SetProgramStartTime(0);
+ request.SetSerial(0);
+ request.SetReceiverNodeId(0);
request.SetSenderActorId(TString());
- request.SetCookie(cookie);
- request.SetDoCheckCookie(true);
- SendExBlock(request, "SendExBlockDoCheckCookie");
-
- // process cookie check reply
- NActorsInterconnect::THandshakeReply reply;
- if (!reply.ParseFromString(ReceiveExBlock("ReceiveExBlockDoCheckCookie"))) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect packet from peer");
- } else if (reply.HasCookieCheckResult() && !reply.GetCookieCheckResult()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Cookie check error -- possible network problem");
- }
- } catch (const TExHandshakeFailed& e) {
- *error = e.what();
- success = false;
- }
-
- // restore state
+ request.SetCookie(cookie);
+ request.SetDoCheckCookie(true);
+ SendExBlock(request, "SendExBlockDoCheckCookie");
+
+ // process cookie check reply
+ NActorsInterconnect::THandshakeReply reply;
+ if (!reply.ParseFromString(ReceiveExBlock("ReceiveExBlockDoCheckCookie"))) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect packet from peer");
+ } else if (reply.HasCookieCheckResult() && !reply.GetCookieCheckResult()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Cookie check error -- possible network problem");
+ }
+ } catch (const TExHandshakeFailed& e) {
+ *error = e.what();
+ success = false;
+ }
+
+ // restore state
SelfVirtualId = TActorId();
- std::swap(tempSocket, Socket);
- std::swap(tempPollerToken, PollerToken);
- return success;
- }
-
- void PerformOutgoingHandshake() {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH01", NLog::PRI_DEBUG,
- "starting outgoing handshake");
-
- // perform connection
- Connect(true);
-
- // send initial request packet
- SendInitialPacket();
-
- TInitialPacket response;
- ReceiveData(&response, sizeof(response), "ReceiveResponse");
- if (!response.Check()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
- } else if (response.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, response.Header.Version));
- }
-
- // extract next packet
- NextPacketFromPeer = response.Header.NextPacket;
-
- if (!PeerVirtualId) {
- // creating new session -- we have to generate request
- NActorsInterconnect::THandshakeRequest request;
-
- request.SetProtocol(INTERCONNECT_PROTOCOL_VERSION);
- request.SetProgramPID(GetPID());
- request.SetProgramStartTime(Common->StartTime);
- request.SetSerial(SelfVirtualId.LocalId());
- request.SetReceiverNodeId(PeerNodeId);
+ std::swap(tempSocket, Socket);
+ std::swap(tempPollerToken, PollerToken);
+ return success;
+ }
+
+ void PerformOutgoingHandshake() {
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH01", NLog::PRI_DEBUG,
+ "starting outgoing handshake");
+
+ // perform connection
+ Connect(true);
+
+ // send initial request packet
+ SendInitialPacket();
+
+ TInitialPacket response;
+ ReceiveData(&response, sizeof(response), "ReceiveResponse");
+ if (!response.Check()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
+ } else if (response.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, response.Header.Version));
+ }
+
+ // extract next packet
+ NextPacketFromPeer = response.Header.NextPacket;
+
+ if (!PeerVirtualId) {
+ // creating new session -- we have to generate request
+ NActorsInterconnect::THandshakeRequest request;
+
+ request.SetProtocol(INTERCONNECT_PROTOCOL_VERSION);
+ request.SetProgramPID(GetPID());
+ request.SetProgramStartTime(Common->StartTime);
+ request.SetSerial(SelfVirtualId.LocalId());
+ request.SetReceiverNodeId(PeerNodeId);
request.SetSenderActorId(SelfVirtualId.ToString());
- request.SetSenderHostName(Common->TechnicalSelfHostName);
- request.SetReceiverHostName(PeerHostName);
-
- if (Common->LocalScopeId != TScopeId()) {
- FillInScopeId(*request.MutableClientScopeId());
- }
-
- if (Common->Cookie) {
- request.SetCookie(Common->Cookie);
- }
- if (Common->ClusterUUID) {
- request.SetUUID(Common->ClusterUUID);
- }
- SetupClusterUUID(request);
- SetupVersionTag(request);
-
- if (const ui32 size = Common->HandshakeBallastSize) {
- TString ballast(size, 0);
+ request.SetSenderHostName(Common->TechnicalSelfHostName);
+ request.SetReceiverHostName(PeerHostName);
+
+ if (Common->LocalScopeId != TScopeId()) {
+ FillInScopeId(*request.MutableClientScopeId());
+ }
+
+ if (Common->Cookie) {
+ request.SetCookie(Common->Cookie);
+ }
+ if (Common->ClusterUUID) {
+ request.SetUUID(Common->ClusterUUID);
+ }
+ SetupClusterUUID(request);
+ SetupVersionTag(request);
+
+ if (const ui32 size = Common->HandshakeBallastSize) {
+ TString ballast(size, 0);
char* data = ballast.Detach();
- for (ui32 i = 0; i < size; ++i) {
- data[i] = i;
- }
- request.SetBallast(ballast);
- }
-
- switch (Common->Settings.EncryptionMode) {
- case EEncryptionMode::DISABLED:
- break;
-
- case EEncryptionMode::OPTIONAL:
- request.SetRequireEncryption(false);
- break;
-
- case EEncryptionMode::REQUIRED:
- request.SetRequireEncryption(true);
- break;
- }
-
- request.SetRequestModernFrame(true);
- request.SetRequestAuthOnly(Common->Settings.TlsAuthOnly);
-
- SendExBlock(request, "ExRequest");
-
- NActorsInterconnect::THandshakeReply reply;
- if (!reply.ParseFromString(ReceiveExBlock("ExReply"))) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect THandshakeReply");
- }
- ReportProto(reply, "ReceiveExBlock ExReply");
-
- if (reply.HasErrorExplaination()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "error from peer: " + reply.GetErrorExplaination());
- } else if (!reply.HasSuccess()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "empty reply");
- }
-
- auto generateError = [this](TString msg) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, msg);
- };
-
- const auto& success = reply.GetSuccess();
- ValidateClusterUUID(success, generateError);
- ValidateVersionTag(success, generateError);
-
+ for (ui32 i = 0; i < size; ++i) {
+ data[i] = i;
+ }
+ request.SetBallast(ballast);
+ }
+
+ switch (Common->Settings.EncryptionMode) {
+ case EEncryptionMode::DISABLED:
+ break;
+
+ case EEncryptionMode::OPTIONAL:
+ request.SetRequireEncryption(false);
+ break;
+
+ case EEncryptionMode::REQUIRED:
+ request.SetRequireEncryption(true);
+ break;
+ }
+
+ request.SetRequestModernFrame(true);
+ request.SetRequestAuthOnly(Common->Settings.TlsAuthOnly);
+
+ SendExBlock(request, "ExRequest");
+
+ NActorsInterconnect::THandshakeReply reply;
+ if (!reply.ParseFromString(ReceiveExBlock("ExReply"))) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect THandshakeReply");
+ }
+ ReportProto(reply, "ReceiveExBlock ExReply");
+
+ if (reply.HasErrorExplaination()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "error from peer: " + reply.GetErrorExplaination());
+ } else if (!reply.HasSuccess()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "empty reply");
+ }
+
+ auto generateError = [this](TString msg) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, msg);
+ };
+
+ const auto& success = reply.GetSuccess();
+ ValidateClusterUUID(success, generateError);
+ ValidateVersionTag(success, generateError);
+
const auto& s = success.GetSenderActorId();
- PeerVirtualId.Parse(s.data(), s.size());
-
- // recover flags
- Params.Encryption = success.GetStartEncryption();
- Params.UseModernFrame = success.GetUseModernFrame();
- Params.AuthOnly = Params.Encryption && success.GetAuthOnly();
- if (success.HasServerScopeId()) {
- ParsePeerScopeId(success.GetServerScopeId());
- }
-
- // recover peer process info from peer's reply
- ProgramInfo = GetProgramInfo(success);
- } else if (!response.Header.SelfVirtualId) {
- // peer reported error -- empty ack was generated by proxy for this request
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH, "Peer rejected session continuation handshake");
- } else if (response.Header.SelfVirtualId != PeerVirtualId || response.Header.PeerVirtualId != SelfVirtualId) {
- // resuming existing session; check that virtual ids of peers match each other
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH, "Session virtual ID mismatch");
- } else {
- ProgramInfo.ConstructInPlace(); // successful handshake
- }
- }
-
- void PerformIncomingHandshake() {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH02", NLog::PRI_DEBUG,
- "starting incoming handshake");
-
- // set up incoming socket
- SetupSocket();
-
- // wait for initial request packet
- TInitialPacket request;
- ReceiveData(&request, sizeof(request), "ReceiveRequest");
- if (!request.Check()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
- } else if (request.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, request.Header.Version));
- }
-
- // extract peer node id from the peer
- PeerNodeId = request.Header.SelfVirtualId.NodeId();
- if (!PeerNodeId) {
+ PeerVirtualId.Parse(s.data(), s.size());
+
+ // recover flags
+ Params.Encryption = success.GetStartEncryption();
+ Params.UseModernFrame = success.GetUseModernFrame();
+ Params.AuthOnly = Params.Encryption && success.GetAuthOnly();
+ if (success.HasServerScopeId()) {
+ ParsePeerScopeId(success.GetServerScopeId());
+ }
+
+ // recover peer process info from peer's reply
+ ProgramInfo = GetProgramInfo(success);
+ } else if (!response.Header.SelfVirtualId) {
+ // peer reported error -- empty ack was generated by proxy for this request
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH, "Peer rejected session continuation handshake");
+ } else if (response.Header.SelfVirtualId != PeerVirtualId || response.Header.PeerVirtualId != SelfVirtualId) {
+ // resuming existing session; check that virtual ids of peers match each other
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH, "Session virtual ID mismatch");
+ } else {
+ ProgramInfo.ConstructInPlace(); // successful handshake
+ }
+ }
+
+ void PerformIncomingHandshake() {
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH02", NLog::PRI_DEBUG,
+ "starting incoming handshake");
+
+ // set up incoming socket
+ SetupSocket();
+
+ // wait for initial request packet
+ TInitialPacket request;
+ ReceiveData(&request, sizeof(request), "ReceiveRequest");
+ if (!request.Check()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Initial packet CRC error");
+ } else if (request.Header.Version != INTERCONNECT_PROTOCOL_VERSION) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Incompatible protocol %" PRIu64, request.Header.Version));
+ }
+
+ // extract peer node id from the peer
+ PeerNodeId = request.Header.SelfVirtualId.NodeId();
+ if (!PeerNodeId) {
Y_VERIFY_DEBUG(false, "PeerNodeId is zero request# %s", request.ToString().data());
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "SelfVirtualId.NodeId is empty in initial packet");
- }
- UpdatePrefix();
-
- // extract next packet
- NextPacketFromPeer = request.Header.NextPacket;
-
- if (request.Header.PeerVirtualId) {
- // issue request to the proxy and wait for the response
- auto reply = AskProxy<TEvHandshakeAck, TEvHandshakeNak>(MakeHolder<TEvHandshakeAsk>(
- request.Header.SelfVirtualId, request.Header.PeerVirtualId, request.Header.NextPacket),
- "TEvHandshakeAsk");
- if (auto *ack = reply->CastAsLocal<TEvHandshakeAck>()) {
- // extract self/peer virtual ids
- SelfVirtualId = ack->Self;
- PeerVirtualId = request.Header.SelfVirtualId;
- NextPacketToPeer = ack->NextPacket;
- Params = ack->Params;
-
- // only succeed in case when proxy returned valid SelfVirtualId; otherwise it wants us to terminate
- // the handshake process and it does not expect the handshake reply
- ProgramInfo.ConstructInPlace();
- } else {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH08", NLog::PRI_NOTICE,
- "Continuation request rejected by proxy");
-
- // report continuation reject to peer
- SelfVirtualId = TActorId();
- PeerVirtualId = TActorId();
- NextPacketToPeer = 0;
- }
-
- // issue response to the peer
- SendInitialPacket();
- } else {
- // peer wants a new session, clear fields and send initial packet
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "SelfVirtualId.NodeId is empty in initial packet");
+ }
+ UpdatePrefix();
+
+ // extract next packet
+ NextPacketFromPeer = request.Header.NextPacket;
+
+ if (request.Header.PeerVirtualId) {
+ // issue request to the proxy and wait for the response
+ auto reply = AskProxy<TEvHandshakeAck, TEvHandshakeNak>(MakeHolder<TEvHandshakeAsk>(
+ request.Header.SelfVirtualId, request.Header.PeerVirtualId, request.Header.NextPacket),
+ "TEvHandshakeAsk");
+ if (auto *ack = reply->CastAsLocal<TEvHandshakeAck>()) {
+ // extract self/peer virtual ids
+ SelfVirtualId = ack->Self;
+ PeerVirtualId = request.Header.SelfVirtualId;
+ NextPacketToPeer = ack->NextPacket;
+ Params = ack->Params;
+
+ // only succeed in case when proxy returned valid SelfVirtualId; otherwise it wants us to terminate
+ // the handshake process and it does not expect the handshake reply
+ ProgramInfo.ConstructInPlace();
+ } else {
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH08", NLog::PRI_NOTICE,
+ "Continuation request rejected by proxy");
+
+ // report continuation reject to peer
+ SelfVirtualId = TActorId();
+ PeerVirtualId = TActorId();
+ NextPacketToPeer = 0;
+ }
+
+ // issue response to the peer
+ SendInitialPacket();
+ } else {
+ // peer wants a new session, clear fields and send initial packet
SelfVirtualId = TActorId();
PeerVirtualId = TActorId();
- NextPacketToPeer = 0;
- SendInitialPacket();
-
- // wait for extended request
- auto ev = MakeHolder<TEvHandshakeRequest>();
- auto& request = ev->Record;
- if (!request.ParseFromString(ReceiveExBlock("ExRequest"))) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect THandshakeRequest");
- }
- ReportProto(request, "ReceiveExBlock ExRequest");
-
- auto generateError = [this](TString msg) {
- // issue reply to the peer to prevent repeating connection retries
- NActorsInterconnect::THandshakeReply reply;
- reply.SetErrorExplaination(msg);
- SendExBlock(reply, "ExReply");
-
- // terminate ths handshake
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, msg);
- };
-
- // check request cookie
- TString error;
- if (request.HasDoCheckCookie()) {
- NActorsInterconnect::THandshakeReply reply;
- reply.SetCookieCheckResult(request.GetCookie() == Common->Cookie);
- SendExBlock(reply, "ExReplyDoCheckCookie");
- throw TExHandshakeFailed();
- } else if (request.HasCookie() && !CheckPeerCookie(request.GetCookie(), &error)) {
- generateError(TStringBuilder() << "Peer connectivity-checking failed, error# " << error);
- }
-
- // update log prefix with the reported peer host name
- PeerHostName = request.GetSenderHostName();
-
- // parse peer virtual id
+ NextPacketToPeer = 0;
+ SendInitialPacket();
+
+ // wait for extended request
+ auto ev = MakeHolder<TEvHandshakeRequest>();
+ auto& request = ev->Record;
+ if (!request.ParseFromString(ReceiveExBlock("ExRequest"))) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect THandshakeRequest");
+ }
+ ReportProto(request, "ReceiveExBlock ExRequest");
+
+ auto generateError = [this](TString msg) {
+ // issue reply to the peer to prevent repeating connection retries
+ NActorsInterconnect::THandshakeReply reply;
+ reply.SetErrorExplaination(msg);
+ SendExBlock(reply, "ExReply");
+
+ // terminate ths handshake
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, msg);
+ };
+
+ // check request cookie
+ TString error;
+ if (request.HasDoCheckCookie()) {
+ NActorsInterconnect::THandshakeReply reply;
+ reply.SetCookieCheckResult(request.GetCookie() == Common->Cookie);
+ SendExBlock(reply, "ExReplyDoCheckCookie");
+ throw TExHandshakeFailed();
+ } else if (request.HasCookie() && !CheckPeerCookie(request.GetCookie(), &error)) {
+ generateError(TStringBuilder() << "Peer connectivity-checking failed, error# " << error);
+ }
+
+ // update log prefix with the reported peer host name
+ PeerHostName = request.GetSenderHostName();
+
+ // parse peer virtual id
const auto& str = request.GetSenderActorId();
- PeerVirtualId.Parse(str.data(), str.size());
-
- // validate request
- ValidateClusterUUID(request, generateError, request.GetUUID());
- if (request.GetReceiverNodeId() != SelfActorId.NodeId()) {
- generateError(Sprintf("Incorrect ReceiverNodeId# %" PRIu32 " from the peer, expected# %" PRIu32,
- request.GetReceiverNodeId(), SelfActorId.NodeId()));
- } else if (request.GetReceiverHostName() != Common->TechnicalSelfHostName) {
+ PeerVirtualId.Parse(str.data(), str.size());
+
+ // validate request
+ ValidateClusterUUID(request, generateError, request.GetUUID());
+ if (request.GetReceiverNodeId() != SelfActorId.NodeId()) {
+ generateError(Sprintf("Incorrect ReceiverNodeId# %" PRIu32 " from the peer, expected# %" PRIu32,
+ request.GetReceiverNodeId(), SelfActorId.NodeId()));
+ } else if (request.GetReceiverHostName() != Common->TechnicalSelfHostName) {
generateError(Sprintf("ReceiverHostName# %s mismatch, expected# %s", request.GetReceiverHostName().data(),
Common->TechnicalSelfHostName.data()));
- }
- ValidateVersionTag(request, generateError);
-
- // check peer node
- auto peerNodeInfo = GetPeerNodeInfo();
- if (!peerNodeInfo) {
- generateError("Peer node not registered in nameservice");
- } else if (peerNodeInfo->Host != request.GetSenderHostName()) {
- generateError("SenderHostName mismatch");
- }
-
- // check request against encryption
- switch (Common->Settings.EncryptionMode) {
- case EEncryptionMode::DISABLED:
- if (request.GetRequireEncryption()) {
- generateError("Peer requested encryption, but it is disabled locally");
- }
- break;
-
- case EEncryptionMode::OPTIONAL:
- Params.Encryption = request.HasRequireEncryption();
- break;
-
- case EEncryptionMode::REQUIRED:
- if (!request.HasRequireEncryption()) {
- generateError("Peer did not request encryption, but it is required locally");
- }
- Params.Encryption = true;
- break;
- }
-
- Params.UseModernFrame = request.GetRequestModernFrame();
- Params.AuthOnly = Params.Encryption && request.GetRequestAuthOnly() && Common->Settings.TlsAuthOnly;
-
- if (request.HasClientScopeId()) {
- ParsePeerScopeId(request.GetClientScopeId());
- }
-
- // remember program info (assuming successful handshake)
- ProgramInfo = GetProgramInfo(request);
-
- // send to proxy
- auto reply = AskProxy<TEvHandshakeReplyOK, TEvHandshakeReplyError>(std::move(ev), "TEvHandshakeRequest");
-
- // parse it
- if (auto ev = reply->CastAsLocal<TEvHandshakeReplyOK>()) {
- // issue successful reply to the peer
- auto& record = ev->Record;
- Y_VERIFY(record.HasSuccess());
- auto& success = *record.MutableSuccess();
- SetupClusterUUID(success);
- SetupVersionTag(success);
- success.SetStartEncryption(Params.Encryption);
- if (Common->LocalScopeId != TScopeId()) {
- FillInScopeId(*success.MutableServerScopeId());
- }
- success.SetUseModernFrame(Params.UseModernFrame);
- success.SetAuthOnly(Params.AuthOnly);
- SendExBlock(record, "ExReply");
-
- // extract sender actor id (self virtual id)
+ }
+ ValidateVersionTag(request, generateError);
+
+ // check peer node
+ auto peerNodeInfo = GetPeerNodeInfo();
+ if (!peerNodeInfo) {
+ generateError("Peer node not registered in nameservice");
+ } else if (peerNodeInfo->Host != request.GetSenderHostName()) {
+ generateError("SenderHostName mismatch");
+ }
+
+ // check request against encryption
+ switch (Common->Settings.EncryptionMode) {
+ case EEncryptionMode::DISABLED:
+ if (request.GetRequireEncryption()) {
+ generateError("Peer requested encryption, but it is disabled locally");
+ }
+ break;
+
+ case EEncryptionMode::OPTIONAL:
+ Params.Encryption = request.HasRequireEncryption();
+ break;
+
+ case EEncryptionMode::REQUIRED:
+ if (!request.HasRequireEncryption()) {
+ generateError("Peer did not request encryption, but it is required locally");
+ }
+ Params.Encryption = true;
+ break;
+ }
+
+ Params.UseModernFrame = request.GetRequestModernFrame();
+ Params.AuthOnly = Params.Encryption && request.GetRequestAuthOnly() && Common->Settings.TlsAuthOnly;
+
+ if (request.HasClientScopeId()) {
+ ParsePeerScopeId(request.GetClientScopeId());
+ }
+
+ // remember program info (assuming successful handshake)
+ ProgramInfo = GetProgramInfo(request);
+
+ // send to proxy
+ auto reply = AskProxy<TEvHandshakeReplyOK, TEvHandshakeReplyError>(std::move(ev), "TEvHandshakeRequest");
+
+ // parse it
+ if (auto ev = reply->CastAsLocal<TEvHandshakeReplyOK>()) {
+ // issue successful reply to the peer
+ auto& record = ev->Record;
+ Y_VERIFY(record.HasSuccess());
+ auto& success = *record.MutableSuccess();
+ SetupClusterUUID(success);
+ SetupVersionTag(success);
+ success.SetStartEncryption(Params.Encryption);
+ if (Common->LocalScopeId != TScopeId()) {
+ FillInScopeId(*success.MutableServerScopeId());
+ }
+ success.SetUseModernFrame(Params.UseModernFrame);
+ success.SetAuthOnly(Params.AuthOnly);
+ SendExBlock(record, "ExReply");
+
+ // extract sender actor id (self virtual id)
const auto& str = success.GetSenderActorId();
- SelfVirtualId.Parse(str.data(), str.size());
- } else if (auto ev = reply->CastAsLocal<TEvHandshakeReplyError>()) {
- // in case of error just send reply to the peer and terminate handshake
- SendExBlock(ev->Record, "ExReply");
- ProgramInfo.Clear(); // do not issue reply to the proxy
- } else {
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, reply->GetTypeRewrite());
- }
- }
- }
-
+ SelfVirtualId.Parse(str.data(), str.size());
+ } else if (auto ev = reply->CastAsLocal<TEvHandshakeReplyError>()) {
+ // in case of error just send reply to the peer and terminate handshake
+ SendExBlock(ev->Record, "ExReply");
+ ProgramInfo.Clear(); // do not issue reply to the proxy
+ } else {
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, reply->GetTypeRewrite());
+ }
+ }
+ }
+
template <typename T>
- void SendExBlock(const T& proto, const char* what) {
- TString data;
+ void SendExBlock(const T& proto, const char* what) {
+ TString data;
Y_PROTOBUF_SUPPRESS_NODISCARD proto.SerializeToString(&data);
- Y_VERIFY(data.size() <= TExHeader::MaxSize);
-
- ReportProto(proto, Sprintf("SendExBlock %s", what).data());
-
- TExHeader header;
- header.Size = data.size();
- header.Sign(data.data(), data.size());
- SendData(&header, sizeof(header), Sprintf("Send%sHeader", what));
- SendData(data.data(), data.size(), Sprintf("Send%sData", what));
- }
-
- TString ReceiveExBlock(const char* what) {
- TExHeader header;
- ReceiveData(&header, sizeof(header), Sprintf("Receive%sHeader", what));
- if (header.Size > TExHeader::MaxSize) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect extended header size");
- }
-
- TString data;
- data.resize(header.Size);
- ReceiveData(data.Detach(), data.size(), Sprintf("Receive%sData", what));
-
- if (!header.Check(data.data(), data.size())) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Extended header CRC error");
- }
-
- return data;
- }
-
- private:
- void SendToProxy(THolder<IEventBase> ev) {
- Y_VERIFY(PeerNodeId);
- Send(GetActorSystem()->InterconnectProxy(PeerNodeId), ev.Release());
- }
-
- template <typename TEvent>
- THolder<typename TEvent::THandle> WaitForSpecificEvent(TString state, TInstant deadline = TInstant::Max()) {
- State = std::move(state);
- return TActorCoroImpl::WaitForSpecificEvent<TEvent>(deadline);
- }
-
- template <typename T1, typename T2, typename... TEvents>
- THolder<IEventHandle> WaitForSpecificEvent(TString state, TInstant deadline = TInstant::Max()) {
- State = std::move(state);
- return TActorCoroImpl::WaitForSpecificEvent<T1, T2, TEvents...>(deadline);
- }
-
+ Y_VERIFY(data.size() <= TExHeader::MaxSize);
+
+ ReportProto(proto, Sprintf("SendExBlock %s", what).data());
+
+ TExHeader header;
+ header.Size = data.size();
+ header.Sign(data.data(), data.size());
+ SendData(&header, sizeof(header), Sprintf("Send%sHeader", what));
+ SendData(data.data(), data.size(), Sprintf("Send%sData", what));
+ }
+
+ TString ReceiveExBlock(const char* what) {
+ TExHeader header;
+ ReceiveData(&header, sizeof(header), Sprintf("Receive%sHeader", what));
+ if (header.Size > TExHeader::MaxSize) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect extended header size");
+ }
+
+ TString data;
+ data.resize(header.Size);
+ ReceiveData(data.Detach(), data.size(), Sprintf("Receive%sData", what));
+
+ if (!header.Check(data.data(), data.size())) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, "Extended header CRC error");
+ }
+
+ return data;
+ }
+
+ private:
+ void SendToProxy(THolder<IEventBase> ev) {
+ Y_VERIFY(PeerNodeId);
+ Send(GetActorSystem()->InterconnectProxy(PeerNodeId), ev.Release());
+ }
+
template <typename TEvent>
- THolder<typename TEvent::THandle> AskProxy(THolder<IEventBase> ev, TString state) {
- SendToProxy(std::move(ev));
- return WaitForSpecificEvent<TEvent>(std::move(state));
- }
-
+ THolder<typename TEvent::THandle> WaitForSpecificEvent(TString state, TInstant deadline = TInstant::Max()) {
+ State = std::move(state);
+ return TActorCoroImpl::WaitForSpecificEvent<TEvent>(deadline);
+ }
+
+ template <typename T1, typename T2, typename... TEvents>
+ THolder<IEventHandle> WaitForSpecificEvent(TString state, TInstant deadline = TInstant::Max()) {
+ State = std::move(state);
+ return TActorCoroImpl::WaitForSpecificEvent<T1, T2, TEvents...>(deadline);
+ }
+
+ template <typename TEvent>
+ THolder<typename TEvent::THandle> AskProxy(THolder<IEventBase> ev, TString state) {
+ SendToProxy(std::move(ev));
+ return WaitForSpecificEvent<TEvent>(std::move(state));
+ }
+
template <typename T1, typename T2, typename... TOther>
- THolder<IEventHandle> AskProxy(THolder<IEventBase> ev, TString state) {
- SendToProxy(std::move(ev));
- return WaitForSpecificEvent<T1, T2, TOther...>(std::move(state));
- }
-
- void Fail(TEvHandshakeFail::EnumHandshakeFail reason, TString explanation, bool network = false) {
- TString msg = Sprintf("%s Peer# %s(%s) %s%s", HandshakeKind.data(), PeerHostName ? PeerHostName.data() : "<unknown>",
- PeerAddr.size() ? PeerAddr.data() : "<unknown>", ResolveTimedOut ? "[resolve timeout] " : "",
- explanation.data());
-
- if (network) {
- TInstant now = Now();
+ THolder<IEventHandle> AskProxy(THolder<IEventBase> ev, TString state) {
+ SendToProxy(std::move(ev));
+ return WaitForSpecificEvent<T1, T2, TOther...>(std::move(state));
+ }
+
+ void Fail(TEvHandshakeFail::EnumHandshakeFail reason, TString explanation, bool network = false) {
+ TString msg = Sprintf("%s Peer# %s(%s) %s%s", HandshakeKind.data(), PeerHostName ? PeerHostName.data() : "<unknown>",
+ PeerAddr.size() ? PeerAddr.data() : "<unknown>", ResolveTimedOut ? "[resolve timeout] " : "",
+ explanation.data());
+
+ if (network) {
+ TInstant now = Now();
TInstant prevLog = LastLogNotice[PeerNodeId];
NActors::NLog::EPriority logPriority = NActors::NLog::PRI_DEBUG;
if (now - prevLog > MuteDuration) {
logPriority = NActors::NLog::PRI_NOTICE;
LastLogNotice[PeerNodeId] = now;
}
- LOG_LOG_NET_X(logPriority, PeerNodeId, "network-related error occured on handshake: %s", msg.data());
- } else {
- // calculate log severity based on failure type; permanent failures lead to error log messages
- auto severity = reason == TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT
- ? NActors::NLog::PRI_NOTICE
- : NActors::NLog::PRI_INFO;
-
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH03", severity, "handshake failed, explanation# %s", msg.data());
- }
-
- if (PeerNodeId) {
- SendToProxy(MakeHolder<TEvHandshakeFail>(reason, std::move(msg)));
- }
-
- throw TExHandshakeFailed() << explanation;
- }
-
- private:
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // COMMUNICATION BLOCK
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Connect(bool updatePeerAddr) {
- // issue request to a nameservice to resolve peer node address
- Send(Common->NameserviceId, new TEvInterconnect::TEvResolveNode(PeerNodeId, Deadline));
-
- // wait for the result
- auto ev = WaitForSpecificEvent<TEvResolveError, TEvLocalNodeInfo, TEvInterconnect::TEvNodeAddress>("ResolveNode",
- Now() + ResolveTimeout);
-
- // extract address from the result
- NInterconnect::TAddress address;
- if (!ev) {
- ResolveTimedOut = true;
- if (auto peerNodeInfo = GetPeerNodeInfo(); peerNodeInfo && peerNodeInfo->Address) {
- address = {peerNodeInfo->Address, peerNodeInfo->Port};
- } else {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve timed out and no static address defined", true);
- }
- } else if (auto *p = ev->CastAsLocal<TEvLocalNodeInfo>()) {
- if (!p->Address) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: no address returned", true);
- }
- address = {*p->Address};
- } else if (auto *p = ev->CastAsLocal<TEvInterconnect::TEvNodeAddress>()) {
- const auto& r = p->Record;
- if (!r.HasAddress() || !r.HasPort()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: no address returned", true);
- }
- address = {r.GetAddress(), static_cast<ui16>(r.GetPort())};
- } else {
- Y_VERIFY(ev->GetTypeRewrite() == ui32(ENetwork::ResolveError));
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: " + ev->Get<TEvResolveError>()->Explain, true);
- }
-
- // create the socket with matching address family
- Socket = NInterconnect::TStreamSocket::Make(address.GetFamily());
- if (*Socket == -1) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: failed to create socket");
- }
-
- // extract peer address
- if (updatePeerAddr) {
- PeerAddr = address.ToString();
- }
-
- // set up socket parameters
- SetupSocket();
-
- // start connecting
- switch (int err = -Socket->Connect(address)) {
- case 0: // successful connection
- break;
-
- case EINPROGRESS: // connection in progress
- WaitPoller(false, true, "WaitConnect");
- err = Socket->GetConnectStatus();
- if (err) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Connection failed: %s", strerror(err)), true);
- }
- break;
+ LOG_LOG_NET_X(logPriority, PeerNodeId, "network-related error occured on handshake: %s", msg.data());
+ } else {
+ // calculate log severity based on failure type; permanent failures lead to error log messages
+ auto severity = reason == TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT
+ ? NActors::NLog::PRI_NOTICE
+ : NActors::NLog::PRI_INFO;
+
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH03", severity, "handshake failed, explanation# %s", msg.data());
+ }
+
+ if (PeerNodeId) {
+ SendToProxy(MakeHolder<TEvHandshakeFail>(reason, std::move(msg)));
+ }
+
+ throw TExHandshakeFailed() << explanation;
+ }
+
+ private:
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // COMMUNICATION BLOCK
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void Connect(bool updatePeerAddr) {
+ // issue request to a nameservice to resolve peer node address
+ Send(Common->NameserviceId, new TEvInterconnect::TEvResolveNode(PeerNodeId, Deadline));
+
+ // wait for the result
+ auto ev = WaitForSpecificEvent<TEvResolveError, TEvLocalNodeInfo, TEvInterconnect::TEvNodeAddress>("ResolveNode",
+ Now() + ResolveTimeout);
+
+ // extract address from the result
+ NInterconnect::TAddress address;
+ if (!ev) {
+ ResolveTimedOut = true;
+ if (auto peerNodeInfo = GetPeerNodeInfo(); peerNodeInfo && peerNodeInfo->Address) {
+ address = {peerNodeInfo->Address, peerNodeInfo->Port};
+ } else {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve timed out and no static address defined", true);
+ }
+ } else if (auto *p = ev->CastAsLocal<TEvLocalNodeInfo>()) {
+ if (!p->Address) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: no address returned", true);
+ }
+ address = {*p->Address};
+ } else if (auto *p = ev->CastAsLocal<TEvInterconnect::TEvNodeAddress>()) {
+ const auto& r = p->Record;
+ if (!r.HasAddress() || !r.HasPort()) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: no address returned", true);
+ }
+ address = {r.GetAddress(), static_cast<ui16>(r.GetPort())};
+ } else {
+ Y_VERIFY(ev->GetTypeRewrite() == ui32(ENetwork::ResolveError));
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: " + ev->Get<TEvResolveError>()->Explain, true);
+ }
+
+ // create the socket with matching address family
+ Socket = NInterconnect::TStreamSocket::Make(address.GetFamily());
+ if (*Socket == -1) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: failed to create socket");
+ }
+
+ // extract peer address
+ if (updatePeerAddr) {
+ PeerAddr = address.ToString();
+ }
+
+ // set up socket parameters
+ SetupSocket();
+
+ // start connecting
+ switch (int err = -Socket->Connect(address)) {
+ case 0: // successful connection
+ break;
+
+ case EINPROGRESS: // connection in progress
+ WaitPoller(false, true, "WaitConnect");
+ err = Socket->GetConnectStatus();
+ if (err) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, Sprintf("Connection failed: %s", strerror(err)), true);
+ }
+ break;
default:
break;
- }
-
+ }
+
auto it = LastLogNotice.find(PeerNodeId);
NActors::NLog::EPriority logPriority = NActors::NLog::PRI_DEBUG;
if (it != LastLogNotice.end()) {
LastLogNotice.erase(it);
logPriority = NActors::NLog::PRI_NOTICE;
}
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH05", logPriority, "connected to peer");
- }
-
- void SetupSocket() {
- // switch to nonblocking mode
- try {
- SetNonBlock(*Socket);
- SetNoDelay(*Socket, true);
- } catch (...) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: can't up nonblocking mode for socket");
- }
-
- // setup send buffer size
- Socket->SetSendBufferSize(Common->Settings.GetSendBufferSize());
-
- // register in poller
- RegisterInPoller();
- }
-
- void RegisterInPoller() {
- const bool success = Send(MakePollerActorId(), new TEvPollerRegister(Socket, SelfActorId, SelfActorId));
- Y_VERIFY(success);
- auto result = WaitForSpecificEvent<TEvPollerRegisterResult>("RegisterPoller");
- PollerToken = std::move(result->Get()->PollerToken);
- Y_VERIFY(PollerToken);
- Y_VERIFY(PollerToken->RefCount() == 1); // ensure exclusive ownership
- }
-
- void SendInitialPacket() {
- TInitialPacket packet(SelfVirtualId, PeerVirtualId, NextPacketToPeer, INTERCONNECT_PROTOCOL_VERSION);
- SendData(&packet, sizeof(packet), "SendInitialPacket");
- }
-
- void WaitPoller(bool read, bool write, TString state) {
- PollerToken->Request(read, write);
- WaitForSpecificEvent<TEvPollerReady>(std::move(state));
- }
-
- template <typename TDataPtr, typename TSendRecvFunc>
- void Process(TDataPtr buffer, size_t len, TSendRecvFunc&& sendRecv, bool read, bool write, TString state) {
- Y_VERIFY(Socket);
+ LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH05", logPriority, "connected to peer");
+ }
+
+ void SetupSocket() {
+ // switch to nonblocking mode
+ try {
+ SetNonBlock(*Socket);
+ SetNoDelay(*Socket, true);
+ } catch (...) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: can't up nonblocking mode for socket");
+ }
+
+ // setup send buffer size
+ Socket->SetSendBufferSize(Common->Settings.GetSendBufferSize());
+
+ // register in poller
+ RegisterInPoller();
+ }
+
+ void RegisterInPoller() {
+ const bool success = Send(MakePollerActorId(), new TEvPollerRegister(Socket, SelfActorId, SelfActorId));
+ Y_VERIFY(success);
+ auto result = WaitForSpecificEvent<TEvPollerRegisterResult>("RegisterPoller");
+ PollerToken = std::move(result->Get()->PollerToken);
+ Y_VERIFY(PollerToken);
+ Y_VERIFY(PollerToken->RefCount() == 1); // ensure exclusive ownership
+ }
+
+ void SendInitialPacket() {
+ TInitialPacket packet(SelfVirtualId, PeerVirtualId, NextPacketToPeer, INTERCONNECT_PROTOCOL_VERSION);
+ SendData(&packet, sizeof(packet), "SendInitialPacket");
+ }
+
+ void WaitPoller(bool read, bool write, TString state) {
+ PollerToken->Request(read, write);
+ WaitForSpecificEvent<TEvPollerReady>(std::move(state));
+ }
+
+ template <typename TDataPtr, typename TSendRecvFunc>
+ void Process(TDataPtr buffer, size_t len, TSendRecvFunc&& sendRecv, bool read, bool write, TString state) {
+ Y_VERIFY(Socket);
NInterconnect::TStreamSocket* sock = Socket.Get();
- ssize_t (NInterconnect::TStreamSocket::*pfn)(TDataPtr, size_t, TString*) const = sendRecv;
- size_t processed = 0;
-
- auto error = [&](TString msg) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, Sprintf("Socket error# %s state# %s processed# %zu remain# %zu",
- msg.data(), state.data(), processed, len), true);
- };
-
- while (len) {
- TString err;
- ssize_t nbytes = (sock->*pfn)(buffer, len, &err);
- if (nbytes > 0) {
- buffer = (char*)buffer + nbytes;
- len -= nbytes;
- processed += nbytes;
- } else if (-nbytes == EAGAIN || -nbytes == EWOULDBLOCK) {
- WaitPoller(read, write, state);
- } else if (!nbytes) {
- error("connection unexpectedly closed");
- } else if (-nbytes != EINTR) {
- error(err ? err : TString(strerror(-nbytes)));
- }
- }
- }
-
- void SendData(const void* buffer, size_t len, TString state) {
- Process(buffer, len, &NInterconnect::TStreamSocket::Send, false, true, std::move(state));
- }
-
- void ReceiveData(void* buffer, size_t len, TString state) {
- Process(buffer, len, &NInterconnect::TStreamSocket::Recv, true, false, std::move(state));
- }
-
- THolder<TEvInterconnect::TNodeInfo> GetPeerNodeInfo() {
- Y_VERIFY(PeerNodeId);
- Send(Common->NameserviceId, new TEvInterconnect::TEvGetNode(PeerNodeId, Deadline));
- auto response = WaitForSpecificEvent<TEvInterconnect::TEvNodeInfo>("GetPeerNodeInfo");
- return std::move(response->Get()->Node);
- }
-
+ ssize_t (NInterconnect::TStreamSocket::*pfn)(TDataPtr, size_t, TString*) const = sendRecv;
+ size_t processed = 0;
+
+ auto error = [&](TString msg) {
+ Fail(TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT, Sprintf("Socket error# %s state# %s processed# %zu remain# %zu",
+ msg.data(), state.data(), processed, len), true);
+ };
+
+ while (len) {
+ TString err;
+ ssize_t nbytes = (sock->*pfn)(buffer, len, &err);
+ if (nbytes > 0) {
+ buffer = (char*)buffer + nbytes;
+ len -= nbytes;
+ processed += nbytes;
+ } else if (-nbytes == EAGAIN || -nbytes == EWOULDBLOCK) {
+ WaitPoller(read, write, state);
+ } else if (!nbytes) {
+ error("connection unexpectedly closed");
+ } else if (-nbytes != EINTR) {
+ error(err ? err : TString(strerror(-nbytes)));
+ }
+ }
+ }
+
+ void SendData(const void* buffer, size_t len, TString state) {
+ Process(buffer, len, &NInterconnect::TStreamSocket::Send, false, true, std::move(state));
+ }
+
+ void ReceiveData(void* buffer, size_t len, TString state) {
+ Process(buffer, len, &NInterconnect::TStreamSocket::Recv, true, false, std::move(state));
+ }
+
+ THolder<TEvInterconnect::TNodeInfo> GetPeerNodeInfo() {
+ Y_VERIFY(PeerNodeId);
+ Send(Common->NameserviceId, new TEvInterconnect::TEvGetNode(PeerNodeId, Deadline));
+ auto response = WaitForSpecificEvent<TEvInterconnect::TEvNodeInfo>("GetPeerNodeInfo");
+ return std::move(response->Get()->Node);
+ }
+
template <typename T>
- static THolder<TProgramInfo> GetProgramInfo(const T& proto) {
- auto programInfo = MakeHolder<TProgramInfo>();
- programInfo->PID = proto.GetProgramPID();
- programInfo->StartTime = proto.GetProgramStartTime();
- programInfo->Serial = proto.GetSerial();
- return programInfo;
- }
- };
-
+ static THolder<TProgramInfo> GetProgramInfo(const T& proto) {
+ auto programInfo = MakeHolder<TProgramInfo>();
+ programInfo->PID = proto.GetProgramPID();
+ programInfo->StartTime = proto.GetProgramStartTime();
+ programInfo->Serial = proto.GetSerial();
+ return programInfo;
+ }
+ };
+
IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self,
const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName,
- TSessionParams params) {
- return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), self, peer, nodeId, nextPacket,
- std::move(peerHostName), std::move(params)));
- }
-
- IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket) {
- return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), std::move(socket)));
- }
-
-}
+ TSessionParams params) {
+ return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), self, peer, nodeId, nextPacket,
+ std::move(peerHostName), std::move(params)));
+ }
+
+ IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket) {
+ return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), std::move(socket)));
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_handshake.h b/library/cpp/actors/interconnect/interconnect_handshake.h
index b3c0db6c5db..12763a0b1ae 100644
--- a/library/cpp/actors/interconnect/interconnect_handshake.h
+++ b/library/cpp/actors/interconnect/interconnect_handshake.h
@@ -1,24 +1,24 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/core/events.h>
-
-#include "interconnect_common.h"
-#include "interconnect_impl.h"
-#include "poller_tcp.h"
-#include "events_local.h"
-
-namespace NActors {
+
+#include "interconnect_common.h"
+#include "interconnect_impl.h"
+#include "poller_tcp.h"
+#include "events_local.h"
+
+namespace NActors {
static constexpr TDuration DEFAULT_HANDSHAKE_TIMEOUT = TDuration::Seconds(1);
static constexpr ui64 INTERCONNECT_PROTOCOL_VERSION = 2;
-
+
using TSocketPtr = TIntrusivePtr<NInterconnect::TStreamSocket>;
-
+
IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self,
const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName,
- TSessionParams params);
-
- IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket);
-
-}
+ TSessionParams params);
+
+ IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket);
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_impl.h b/library/cpp/actors/interconnect/interconnect_impl.h
index ee29e4d3971..fd6e1d67b03 100644
--- a/library/cpp/actors/interconnect/interconnect_impl.h
+++ b/library/cpp/actors/interconnect/interconnect_impl.h
@@ -1,45 +1,45 @@
-#pragma once
+#pragma once
-#include "interconnect.h"
+#include "interconnect.h"
#include <library/cpp/actors/protos/interconnect.pb.h>
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/helpers/mon_histogram_helper.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NActors {
+
+namespace NActors {
// resolve node info
struct TEvInterconnect::TEvResolveNode: public TEventPB<TEvInterconnect::TEvResolveNode, NActorsInterconnect::TEvResolveNode, TEvInterconnect::EvResolveNode> {
TEvResolveNode() {
}
-
- TEvResolveNode(ui32 nodeId, TInstant deadline = TInstant::Max()) {
+
+ TEvResolveNode(ui32 nodeId, TInstant deadline = TInstant::Max()) {
Record.SetNodeId(nodeId);
- if (deadline != TInstant::Max()) {
- Record.SetDeadline(deadline.GetValue());
- }
+ if (deadline != TInstant::Max()) {
+ Record.SetDeadline(deadline.GetValue());
+ }
}
};
-
+
// node info
struct TEvInterconnect::TEvNodeAddress: public TEventPB<TEvInterconnect::TEvNodeAddress, NActorsInterconnect::TEvNodeInfo, TEvInterconnect::EvNodeAddress> {
TEvNodeAddress() {
}
-
+
TEvNodeAddress(ui32 nodeId) {
Record.SetNodeId(nodeId);
}
};
-
+
// register node
struct TEvInterconnect::TEvRegisterNode: public TEventBase<TEvInterconnect::TEvRegisterNode, TEvInterconnect::EvRegisterNode> {
};
-
+
// reply on register node
struct TEvInterconnect::TEvRegisterNodeResult: public TEventBase<TEvInterconnect::TEvRegisterNodeResult, TEvInterconnect::EvRegisterNodeResult> {
};
-
+
// disconnect
struct TEvInterconnect::TEvDisconnect: public TEventLocal<TEvInterconnect::TEvDisconnect, TEvInterconnect::EvDisconnect> {
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_mon.cpp b/library/cpp/actors/interconnect/interconnect_mon.cpp
index cf924ccbf9d..db7c05a9350 100644
--- a/library/cpp/actors/interconnect/interconnect_mon.cpp
+++ b/library/cpp/actors/interconnect/interconnect_mon.cpp
@@ -1,276 +1,276 @@
-#include "interconnect_mon.h"
-#include "interconnect_tcp_proxy.h"
+#include "interconnect_mon.h"
+#include "interconnect_tcp_proxy.h"
#include <library/cpp/json/json_value.h>
#include <library/cpp/json/json_writer.h>
#include <library/cpp/monlib/service/pages/templates.h>
-
-#include <openssl/ssl.h>
-#include <openssl/pem.h>
-
-namespace NInterconnect {
-
- using namespace NActors;
-
- class TInterconnectMonActor : public TActor<TInterconnectMonActor> {
- class TQueryProcessor : public TActorBootstrapped<TQueryProcessor> {
+
+#include <openssl/ssl.h>
+#include <openssl/pem.h>
+
+namespace NInterconnect {
+
+ using namespace NActors;
+
+ class TInterconnectMonActor : public TActor<TInterconnectMonActor> {
+ class TQueryProcessor : public TActorBootstrapped<TQueryProcessor> {
const TActorId Sender;
- const bool Json;
- TMap<ui32, TInterconnectProxyTCP::TProxyStats> Stats;
- ui32 PendingReplies = 0;
-
- public:
+ const bool Json;
+ TMap<ui32, TInterconnectProxyTCP::TProxyStats> Stats;
+ ui32 PendingReplies = 0;
+
+ public:
static constexpr IActor::EActorActivity ActorActivityType() {
return INTERCONNECT_MONACTOR;
}
TQueryProcessor(const TActorId& sender, bool json)
- : Sender(sender)
- , Json(json)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc, ctx, TDuration::Seconds(5), new TEvents::TEvWakeup);
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr ev, const TActorContext& ctx) {
- TActorSystem* const as = ctx.ExecutorThread.ActorSystem;
- for (const auto& node : ev->Get()->Nodes) {
- Send(as->InterconnectProxy(node.NodeId), new TInterconnectProxyTCP::TEvQueryStats, IEventHandle::FlagTrackDelivery);
- ++PendingReplies;
- }
- GenerateResultWhenReady(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvInterconnect::TEvNodesInfo, Handle)
- HFunc(TInterconnectProxyTCP::TEvStats, Handle)
- CFunc(TEvents::TSystem::Undelivered, HandleUndelivered)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- )
-
- void Handle(TInterconnectProxyTCP::TEvStats::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- Stats.emplace(msg->PeerNodeId, std::move(msg->ProxyStats));
- --PendingReplies;
- GenerateResultWhenReady(ctx);
- }
-
- void HandleUndelivered(const TActorContext& ctx) {
- --PendingReplies;
- GenerateResultWhenReady(ctx);
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- PendingReplies = 0;
- GenerateResultWhenReady(ctx);
- }
-
- void GenerateResultWhenReady(const TActorContext& ctx) {
- if (!PendingReplies) {
- if (Json) {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(GenerateJson(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- } else {
- ctx.Send(Sender, new NMon::TEvHttpInfoRes(GenerateHtml()));
- }
- Die(ctx);
- }
- }
-
- TString GenerateHtml() {
- TStringStream str;
- HTML(str) {
- TABLE_CLASS("table-sortable table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "Peer node id"; }
- TABLEH() { str << "State"; }
- TABLEH() { str << "Ping"; }
- TABLEH() { str << "Clock skew"; }
- TABLEH() { str << "Scope id"; }
- TABLEH() { str << "Encryption"; }
- TABLEH() { str << "LastSessionDieTime"; }
- TABLEH() { str << "TotalOutputQueueSize"; }
- TABLEH() { str << "Connected"; }
- TABLEH() { str << "Host"; }
- TABLEH() { str << "Port"; }
- TABLEH() { str << "LastErrorTimestamp"; }
- TABLEH() { str << "LastErrorKind"; }
- TABLEH() { str << "LastErrorExplanation"; }
- }
- }
- TABLEBODY() {
- for (const auto& kv : Stats) {
- TABLER() {
- TABLED() { str << "<a href='" << kv.second.Path << "'>" << kv.first << "</a>"; }
- TABLED() { str << kv.second.State; }
- TABLED() {
- if (kv.second.Ping != TDuration::Zero()) {
- str << kv.second.Ping;
- }
- }
- TABLED() {
- if (kv.second.ClockSkew < 0) {
- str << "-" << TDuration::MicroSeconds(-kv.second.ClockSkew);
- } else {
- str << "+" << TDuration::MicroSeconds(kv.second.ClockSkew);
- }
- }
- TABLED() { str << ScopeIdToString(kv.second.PeerScopeId); }
- TABLED() {
- const char *color = kv.second.Encryption != "none" ? "green" : "red";
- str << "<font color='" << color << "'>" << kv.second.Encryption << "</font>";
- }
- TABLED() {
- if (kv.second.LastSessionDieTime != TInstant::Zero()) {
- str << kv.second.LastSessionDieTime;
- }
- }
- TABLED() { str << kv.second.TotalOutputQueueSize; }
- TABLED() { str << (kv.second.Connected ? "yes" : "<strong>no</strong>"); }
- TABLED() { str << kv.second.Host; }
- TABLED() { str << kv.second.Port; }
- TABLED() {
- str << "<strong>";
- if (kv.second.LastErrorTimestamp != TInstant::Zero()) {
- str << kv.second.LastErrorTimestamp;
- }
- str << "</strong>";
- }
- TABLED() { str << "<strong>" << kv.second.LastErrorKind << "</strong>"; }
- TABLED() { str << "<strong>" << kv.second.LastErrorExplanation << "</strong>"; }
- }
- }
- }
- }
- }
- return str.Str();
- }
-
- TString GenerateJson() {
- NJson::TJsonValue json;
- for (const auto& [nodeId, info] : Stats) {
- NJson::TJsonValue item;
- item["NodeId"] = nodeId;
-
- auto id = [](const auto& x) { return x; };
- auto toString = [](const auto& x) { return x.ToString(); };
-
-#define JSON(NAME, FUN) item[#NAME] = FUN(info.NAME);
- JSON(Path, id)
- JSON(State, id)
- JSON(PeerScopeId, ScopeIdToString)
- JSON(LastSessionDieTime, toString)
- JSON(TotalOutputQueueSize, id)
- JSON(Connected, id)
- JSON(Host, id)
- JSON(Port, id)
- JSON(LastErrorTimestamp, toString)
- JSON(LastErrorKind, id)
- JSON(LastErrorExplanation, id)
- JSON(Ping, toString)
- JSON(ClockSkew, id)
- JSON(Encryption, id)
-#undef JSON
-
- json[ToString(nodeId)] = item;
- }
- TStringStream str(NMonitoring::HTTPOKJSON);
- NJson::WriteJson(&str, &json);
- return str.Str();
- }
- };
-
- private:
- TIntrusivePtr<TInterconnectProxyCommon> Common;
-
- public:
+ : Sender(sender)
+ , Json(json)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc, ctx, TDuration::Seconds(5), new TEvents::TEvWakeup);
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr ev, const TActorContext& ctx) {
+ TActorSystem* const as = ctx.ExecutorThread.ActorSystem;
+ for (const auto& node : ev->Get()->Nodes) {
+ Send(as->InterconnectProxy(node.NodeId), new TInterconnectProxyTCP::TEvQueryStats, IEventHandle::FlagTrackDelivery);
+ ++PendingReplies;
+ }
+ GenerateResultWhenReady(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvInterconnect::TEvNodesInfo, Handle)
+ HFunc(TInterconnectProxyTCP::TEvStats, Handle)
+ CFunc(TEvents::TSystem::Undelivered, HandleUndelivered)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ )
+
+ void Handle(TInterconnectProxyTCP::TEvStats::TPtr& ev, const TActorContext& ctx) {
+ auto *msg = ev->Get();
+ Stats.emplace(msg->PeerNodeId, std::move(msg->ProxyStats));
+ --PendingReplies;
+ GenerateResultWhenReady(ctx);
+ }
+
+ void HandleUndelivered(const TActorContext& ctx) {
+ --PendingReplies;
+ GenerateResultWhenReady(ctx);
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ PendingReplies = 0;
+ GenerateResultWhenReady(ctx);
+ }
+
+ void GenerateResultWhenReady(const TActorContext& ctx) {
+ if (!PendingReplies) {
+ if (Json) {
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(GenerateJson(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ } else {
+ ctx.Send(Sender, new NMon::TEvHttpInfoRes(GenerateHtml()));
+ }
+ Die(ctx);
+ }
+ }
+
+ TString GenerateHtml() {
+ TStringStream str;
+ HTML(str) {
+ TABLE_CLASS("table-sortable table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "Peer node id"; }
+ TABLEH() { str << "State"; }
+ TABLEH() { str << "Ping"; }
+ TABLEH() { str << "Clock skew"; }
+ TABLEH() { str << "Scope id"; }
+ TABLEH() { str << "Encryption"; }
+ TABLEH() { str << "LastSessionDieTime"; }
+ TABLEH() { str << "TotalOutputQueueSize"; }
+ TABLEH() { str << "Connected"; }
+ TABLEH() { str << "Host"; }
+ TABLEH() { str << "Port"; }
+ TABLEH() { str << "LastErrorTimestamp"; }
+ TABLEH() { str << "LastErrorKind"; }
+ TABLEH() { str << "LastErrorExplanation"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& kv : Stats) {
+ TABLER() {
+ TABLED() { str << "<a href='" << kv.second.Path << "'>" << kv.first << "</a>"; }
+ TABLED() { str << kv.second.State; }
+ TABLED() {
+ if (kv.second.Ping != TDuration::Zero()) {
+ str << kv.second.Ping;
+ }
+ }
+ TABLED() {
+ if (kv.second.ClockSkew < 0) {
+ str << "-" << TDuration::MicroSeconds(-kv.second.ClockSkew);
+ } else {
+ str << "+" << TDuration::MicroSeconds(kv.second.ClockSkew);
+ }
+ }
+ TABLED() { str << ScopeIdToString(kv.second.PeerScopeId); }
+ TABLED() {
+ const char *color = kv.second.Encryption != "none" ? "green" : "red";
+ str << "<font color='" << color << "'>" << kv.second.Encryption << "</font>";
+ }
+ TABLED() {
+ if (kv.second.LastSessionDieTime != TInstant::Zero()) {
+ str << kv.second.LastSessionDieTime;
+ }
+ }
+ TABLED() { str << kv.second.TotalOutputQueueSize; }
+ TABLED() { str << (kv.second.Connected ? "yes" : "<strong>no</strong>"); }
+ TABLED() { str << kv.second.Host; }
+ TABLED() { str << kv.second.Port; }
+ TABLED() {
+ str << "<strong>";
+ if (kv.second.LastErrorTimestamp != TInstant::Zero()) {
+ str << kv.second.LastErrorTimestamp;
+ }
+ str << "</strong>";
+ }
+ TABLED() { str << "<strong>" << kv.second.LastErrorKind << "</strong>"; }
+ TABLED() { str << "<strong>" << kv.second.LastErrorExplanation << "</strong>"; }
+ }
+ }
+ }
+ }
+ }
+ return str.Str();
+ }
+
+ TString GenerateJson() {
+ NJson::TJsonValue json;
+ for (const auto& [nodeId, info] : Stats) {
+ NJson::TJsonValue item;
+ item["NodeId"] = nodeId;
+
+ auto id = [](const auto& x) { return x; };
+ auto toString = [](const auto& x) { return x.ToString(); };
+
+#define JSON(NAME, FUN) item[#NAME] = FUN(info.NAME);
+ JSON(Path, id)
+ JSON(State, id)
+ JSON(PeerScopeId, ScopeIdToString)
+ JSON(LastSessionDieTime, toString)
+ JSON(TotalOutputQueueSize, id)
+ JSON(Connected, id)
+ JSON(Host, id)
+ JSON(Port, id)
+ JSON(LastErrorTimestamp, toString)
+ JSON(LastErrorKind, id)
+ JSON(LastErrorExplanation, id)
+ JSON(Ping, toString)
+ JSON(ClockSkew, id)
+ JSON(Encryption, id)
+#undef JSON
+
+ json[ToString(nodeId)] = item;
+ }
+ TStringStream str(NMonitoring::HTTPOKJSON);
+ NJson::WriteJson(&str, &json);
+ return str.Str();
+ }
+ };
+
+ private:
+ TIntrusivePtr<TInterconnectProxyCommon> Common;
+
+ public:
static constexpr IActor::EActorActivity ActorActivityType() {
return INTERCONNECT_MONACTOR;
}
- TInterconnectMonActor(TIntrusivePtr<TInterconnectProxyCommon> common)
- : TActor(&TThis::StateFunc)
- , Common(std::move(common))
- {}
-
- STRICT_STFUNC(StateFunc,
- HFunc(NMon::TEvHttpInfo, Handle)
- )
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- const auto& params = ev->Get()->Request.GetParams();
- int certinfo = 0;
- if (TryFromString(params.Get("certinfo"), certinfo) && certinfo) {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(GetCertInfoJson(), ev->Get()->SubRequestId,
- NMon::TEvHttpInfoRes::Custom));
- } else {
- const bool json = params.Has("fmt") && params.Get("fmt") == "json";
- ctx.Register(new TQueryProcessor(ev->Sender, json));
- }
- }
-
- TString GetCertInfoJson() const {
- NJson::TJsonValue json(NJson::JSON_MAP);
- if (const TString cert = Common ? Common->Settings.Certificate : TString()) {
- struct TEx : yexception {};
- try {
- const auto& cert = Common->Settings.Certificate;
- std::unique_ptr<BIO, void(*)(BIO*)> bio(BIO_new_mem_buf(cert.data(), cert.size()), &BIO_vfree);
- if (!bio) {
- throw TEx() << "BIO_new_mem_buf failed";
- }
- std::unique_ptr<X509, void(*)(X509*)> x509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr),
- &X509_free);
- if (!x509) {
- throw TEx() << "PEM_read_bio_X509 failed";
- }
- X509_NAME *name = X509_get_subject_name(x509.get());
- if (!name) {
- throw TEx() << "X509_get_subject_name failed";
- }
- char buffer[4096];
- if (char *p = X509_NAME_oneline(name, buffer, sizeof(buffer))) {
- json["Subject"] = p;
- }
- if (int loc = X509_NAME_get_index_by_NID(name, NID_commonName, -1); loc >= 0) {
- if (X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, loc)) {
- if (ASN1_STRING *data = X509_NAME_ENTRY_get_data(entry)) {
- unsigned char *cn;
- if (const int len = ASN1_STRING_to_UTF8(&cn, data); len >= 0) {
- json["CommonName"] = TString(reinterpret_cast<char*>(cn), len);
- OPENSSL_free(cn);
- }
- }
- }
- }
- auto time = [](const ASN1_TIME *t, const char *name) -> TString {
- if (t) {
- struct tm tm;
- if (ASN1_TIME_to_tm(t, &tm)) {
- return Strftime("%Y-%m-%dT%H:%M:%S%z", &tm);
- } else {
- throw TEx() << "ASN1_TIME_to_tm failed";
- }
- } else {
- throw TEx() << name << " failed";
- }
- };
- json["NotBefore"] = time(X509_get0_notBefore(x509.get()), "X509_get0_notBefore");
- json["NotAfter"] = time(X509_get0_notAfter(x509.get()), "X509_get0_notAfter");
- } catch (const TEx& ex) {
- json["Error"] = ex.what();
- }
- }
- TStringStream str(NMonitoring::HTTPOKJSON);
- NJson::WriteJson(&str, &json);
- return str.Str();
- }
- };
-
- IActor *CreateInterconnectMonActor(TIntrusivePtr<TInterconnectProxyCommon> common) {
- return new TInterconnectMonActor(std::move(common));
- }
-
-} // NInterconnect
+ TInterconnectMonActor(TIntrusivePtr<TInterconnectProxyCommon> common)
+ : TActor(&TThis::StateFunc)
+ , Common(std::move(common))
+ {}
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(NMon::TEvHttpInfo, Handle)
+ )
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ const auto& params = ev->Get()->Request.GetParams();
+ int certinfo = 0;
+ if (TryFromString(params.Get("certinfo"), certinfo) && certinfo) {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(GetCertInfoJson(), ev->Get()->SubRequestId,
+ NMon::TEvHttpInfoRes::Custom));
+ } else {
+ const bool json = params.Has("fmt") && params.Get("fmt") == "json";
+ ctx.Register(new TQueryProcessor(ev->Sender, json));
+ }
+ }
+
+ TString GetCertInfoJson() const {
+ NJson::TJsonValue json(NJson::JSON_MAP);
+ if (const TString cert = Common ? Common->Settings.Certificate : TString()) {
+ struct TEx : yexception {};
+ try {
+ const auto& cert = Common->Settings.Certificate;
+ std::unique_ptr<BIO, void(*)(BIO*)> bio(BIO_new_mem_buf(cert.data(), cert.size()), &BIO_vfree);
+ if (!bio) {
+ throw TEx() << "BIO_new_mem_buf failed";
+ }
+ std::unique_ptr<X509, void(*)(X509*)> x509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr),
+ &X509_free);
+ if (!x509) {
+ throw TEx() << "PEM_read_bio_X509 failed";
+ }
+ X509_NAME *name = X509_get_subject_name(x509.get());
+ if (!name) {
+ throw TEx() << "X509_get_subject_name failed";
+ }
+ char buffer[4096];
+ if (char *p = X509_NAME_oneline(name, buffer, sizeof(buffer))) {
+ json["Subject"] = p;
+ }
+ if (int loc = X509_NAME_get_index_by_NID(name, NID_commonName, -1); loc >= 0) {
+ if (X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, loc)) {
+ if (ASN1_STRING *data = X509_NAME_ENTRY_get_data(entry)) {
+ unsigned char *cn;
+ if (const int len = ASN1_STRING_to_UTF8(&cn, data); len >= 0) {
+ json["CommonName"] = TString(reinterpret_cast<char*>(cn), len);
+ OPENSSL_free(cn);
+ }
+ }
+ }
+ }
+ auto time = [](const ASN1_TIME *t, const char *name) -> TString {
+ if (t) {
+ struct tm tm;
+ if (ASN1_TIME_to_tm(t, &tm)) {
+ return Strftime("%Y-%m-%dT%H:%M:%S%z", &tm);
+ } else {
+ throw TEx() << "ASN1_TIME_to_tm failed";
+ }
+ } else {
+ throw TEx() << name << " failed";
+ }
+ };
+ json["NotBefore"] = time(X509_get0_notBefore(x509.get()), "X509_get0_notBefore");
+ json["NotAfter"] = time(X509_get0_notAfter(x509.get()), "X509_get0_notAfter");
+ } catch (const TEx& ex) {
+ json["Error"] = ex.what();
+ }
+ }
+ TStringStream str(NMonitoring::HTTPOKJSON);
+ NJson::WriteJson(&str, &json);
+ return str.Str();
+ }
+ };
+
+ IActor *CreateInterconnectMonActor(TIntrusivePtr<TInterconnectProxyCommon> common) {
+ return new TInterconnectMonActor(std::move(common));
+ }
+
+} // NInterconnect
diff --git a/library/cpp/actors/interconnect/interconnect_mon.h b/library/cpp/actors/interconnect/interconnect_mon.h
index 3fb26053fbe..2c4d4fa5503 100644
--- a/library/cpp/actors/interconnect/interconnect_mon.h
+++ b/library/cpp/actors/interconnect/interconnect_mon.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor.h>
-#include "interconnect_common.h"
-
-namespace NInterconnect {
-
- NActors::IActor *CreateInterconnectMonActor(TIntrusivePtr<NActors::TInterconnectProxyCommon> common = nullptr);
-
+#include "interconnect_common.h"
+
+namespace NInterconnect {
+
+ NActors::IActor *CreateInterconnectMonActor(TIntrusivePtr<NActors::TInterconnectProxyCommon> common = nullptr);
+
static inline NActors::TActorId MakeInterconnectMonActorId(ui32 nodeId) {
- char s[12] = {'I', 'C', 'O', 'v', 'e', 'r', 'v', 'i', 'e', 'w', 0, 0};
+ char s[12] = {'I', 'C', 'O', 'v', 'e', 'r', 'v', 'i', 'e', 'w', 0, 0};
return NActors::TActorId(nodeId, TStringBuf(s, 12));
- }
-
-} // NInterconnect
+ }
+
+} // NInterconnect
diff --git a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp b/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
index 43419bf70d3..5c14a3a9f5d 100644
--- a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
+++ b/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
@@ -1,29 +1,29 @@
-#include "interconnect.h"
-#include "interconnect_impl.h"
-#include "interconnect_address.h"
+#include "interconnect.h"
+#include "interconnect_impl.h"
+#include "interconnect_address.h"
#include "interconnect_nameserver_base.h"
-#include "events_local.h"
-
+#include "events_local.h"
+
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/memory_log/memlog.h>
-
-namespace NActors {
+
+namespace NActors {
class TInterconnectNameserverTable: public TInterconnectNameserverBase<TInterconnectNameserverTable> {
TIntrusivePtr<TTableNameserverSetup> Config;
-
+
public:
static constexpr EActivityType ActorActivityType() {
- return NAMESERVICE;
+ return NAMESERVICE;
}
-
+
TInterconnectNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 /*resolvePoolId*/)
: TInterconnectNameserverBase<TInterconnectNameserverTable>(&TInterconnectNameserverTable::StateFunc, setup->StaticNodeTable)
, Config(setup)
{
Y_VERIFY(Config->IsEntriesUnique());
}
-
+
STFUNC(StateFunc) {
try {
switch (ev->GetTypeRewrite()) {
@@ -34,34 +34,34 @@ namespace NActors {
}
} catch (...) {
// on error - do nothing
- }
- }
+ }
+ }
};
-
- IActor* CreateNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 poolId) {
+
+ IActor* CreateNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 poolId) {
return new TInterconnectNameserverTable(setup, poolId);
- }
-
+ }
+
bool TTableNameserverSetup::IsEntriesUnique() const {
TVector<const TNodeInfo*> infos;
infos.reserve(StaticNodeTable.size());
for (const auto& x : StaticNodeTable)
infos.push_back(&x.second);
-
+
auto CompareAddressLambda =
[](const TNodeInfo* left, const TNodeInfo* right) {
return left->Port == right->Port ? left->Address < right->Address : left->Port < right->Port;
};
-
+
Sort(infos, CompareAddressLambda);
-
+
for (ui32 idx = 1, end = StaticNodeTable.size(); idx < end; ++idx) {
const TNodeInfo* left = infos[idx - 1];
const TNodeInfo* right = infos[idx];
if (left->Address && left->Address == right->Address && left->Port == right->Port)
return false;
}
-
+
auto CompareHostLambda =
[](const TNodeInfo* left, const TNodeInfo* right) {
return left->Port == right->Port ? left->ResolveHost < right->ResolveHost : left->Port < right->Port;
@@ -78,9 +78,9 @@ namespace NActors {
return true;
}
-
+
TActorId GetNameserviceActorId() {
return TActorId(0, "namesvc");
- }
-
-}
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp b/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
index 1c44b4c59b4..7fe99c6261e 100644
--- a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
+++ b/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
@@ -1,47 +1,47 @@
-#include "interconnect_proxy_wrapper.h"
-#include "interconnect_tcp_proxy.h"
-#include <library/cpp/actors/interconnect/mock/ic_mock.h>
-
-namespace NActors {
-
- class TInterconnectProxyWrapper : public IActor {
- TIntrusivePtr<TInterconnectProxyCommon> Common;
- const ui32 NodeId;
- TInterconnectMock *Mock;
- IActor *Proxy = nullptr;
-
- public:
- TInterconnectProxyWrapper(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 nodeId, TInterconnectMock *mock)
- : IActor(static_cast<TReceiveFunc>(&TInterconnectProxyWrapper::StateFunc), INTERCONNECT_PROXY_WRAPPER)
- , Common(std::move(common))
- , NodeId(nodeId)
- , Mock(mock)
- {}
-
- STFUNC(StateFunc) {
- if (ev->GetTypeRewrite() == TEvents::TSystem::Poison && !Proxy) {
- PassAway();
- } else {
- if (!Proxy) {
- IActor *actor = Mock
- ? Mock->CreateProxyMock(TActivationContext::ActorSystem()->NodeId, NodeId, Common)
- : new TInterconnectProxyTCP(NodeId, Common, &Proxy);
- RegisterWithSameMailbox(actor);
- if (Mock) {
- Proxy = actor;
- }
- Y_VERIFY(Proxy);
- }
- InvokeOtherActor(*Proxy, &IActor::Receive, ev, ctx);
- }
- }
- };
-
- TProxyWrapperFactory CreateProxyWrapperFactory(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 poolId,
- TInterconnectMock *mock) {
- return [=](TActorSystem *as, ui32 nodeId) -> TActorId {
- return as->Register(new TInterconnectProxyWrapper(common, nodeId, mock), TMailboxType::HTSwap, poolId);
- };
- }
-
-} // NActors
+#include "interconnect_proxy_wrapper.h"
+#include "interconnect_tcp_proxy.h"
+#include <library/cpp/actors/interconnect/mock/ic_mock.h>
+
+namespace NActors {
+
+ class TInterconnectProxyWrapper : public IActor {
+ TIntrusivePtr<TInterconnectProxyCommon> Common;
+ const ui32 NodeId;
+ TInterconnectMock *Mock;
+ IActor *Proxy = nullptr;
+
+ public:
+ TInterconnectProxyWrapper(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 nodeId, TInterconnectMock *mock)
+ : IActor(static_cast<TReceiveFunc>(&TInterconnectProxyWrapper::StateFunc), INTERCONNECT_PROXY_WRAPPER)
+ , Common(std::move(common))
+ , NodeId(nodeId)
+ , Mock(mock)
+ {}
+
+ STFUNC(StateFunc) {
+ if (ev->GetTypeRewrite() == TEvents::TSystem::Poison && !Proxy) {
+ PassAway();
+ } else {
+ if (!Proxy) {
+ IActor *actor = Mock
+ ? Mock->CreateProxyMock(TActivationContext::ActorSystem()->NodeId, NodeId, Common)
+ : new TInterconnectProxyTCP(NodeId, Common, &Proxy);
+ RegisterWithSameMailbox(actor);
+ if (Mock) {
+ Proxy = actor;
+ }
+ Y_VERIFY(Proxy);
+ }
+ InvokeOtherActor(*Proxy, &IActor::Receive, ev, ctx);
+ }
+ }
+ };
+
+ TProxyWrapperFactory CreateProxyWrapperFactory(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 poolId,
+ TInterconnectMock *mock) {
+ return [=](TActorSystem *as, ui32 nodeId) -> TActorId {
+ return as->Register(new TInterconnectProxyWrapper(common, nodeId, mock), TMailboxType::HTSwap, poolId);
+ };
+ }
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.h b/library/cpp/actors/interconnect/interconnect_proxy_wrapper.h
index e5942351a72..de7250d200f 100644
--- a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.h
+++ b/library/cpp/actors/interconnect/interconnect_proxy_wrapper.h
@@ -1,12 +1,12 @@
-#pragma once
-
-#include "interconnect_common.h"
-
-#include <library/cpp/actors/core/actorsystem.h>
-
-namespace NActors {
-
- TProxyWrapperFactory CreateProxyWrapperFactory(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 poolId,
- class TInterconnectMock *mock = nullptr);
-
-}
+#pragma once
+
+#include "interconnect_common.h"
+
+#include <library/cpp/actors/core/actorsystem.h>
+
+namespace NActors {
+
+ TProxyWrapperFactory CreateProxyWrapperFactory(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 poolId,
+ class TInterconnectMock *mock = nullptr);
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_stream.cpp b/library/cpp/actors/interconnect/interconnect_stream.cpp
index 158ebc9e1d5..d1cfff2c4a6 100644
--- a/library/cpp/actors/interconnect/interconnect_stream.cpp
+++ b/library/cpp/actors/interconnect/interconnect_stream.cpp
@@ -1,44 +1,44 @@
-#include "interconnect_stream.h"
-#include "logging.h"
+#include "interconnect_stream.h"
+#include "logging.h"
#include <library/cpp/openssl/init/init.h>
-#include <util/network/socket.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-
-#if defined(_win_)
-#include <util/system/file.h>
-#define SOCK_NONBLOCK 0
-#elif defined(_darwin_)
-#define SOCK_NONBLOCK 0
-#else
-#include <sys/un.h>
-#include <sys/stat.h>
-#endif //_win_
-
-#if !defined(_win_)
-#include <sys/ioctl.h>
-#endif
-
-#include <cerrno>
-
-namespace NInterconnect {
+#include <util/network/socket.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+#if defined(_win_)
+#include <util/system/file.h>
+#define SOCK_NONBLOCK 0
+#elif defined(_darwin_)
+#define SOCK_NONBLOCK 0
+#else
+#include <sys/un.h>
+#include <sys/stat.h>
+#endif //_win_
+
+#if !defined(_win_)
+#include <sys/ioctl.h>
+#endif
+
+#include <cerrno>
+
+namespace NInterconnect {
namespace {
inline int
LastSocketError() {
-#if defined(_win_)
+#if defined(_win_)
return WSAGetLastError();
-#else
+#else
return errno;
-#endif
+#endif
}
}
-
+
TSocket::TSocket(SOCKET fd)
: Descriptor(fd)
{
}
-
+
TSocket::~TSocket() {
if (Descriptor == INVALID_SOCKET) {
return;
@@ -57,30 +57,30 @@ namespace NInterconnect {
default:
Y_FAIL("It's something unexpected");
}
- }
-
+ }
+
int TSocket::GetDescriptor() {
return Descriptor;
- }
-
+ }
+
int
TSocket::Bind(const TAddress& addr) const {
const auto ret = ::bind(Descriptor, addr.SockAddr(), addr.Size());
if (ret < 0)
return -LastSocketError();
-
+
return 0;
}
-
+
int
TSocket::Shutdown(int how) const {
const auto ret = ::shutdown(Descriptor, how);
if (ret < 0)
return -LastSocketError();
-
+
return 0;
}
-
+
int TSocket::GetConnectStatus() const {
int err = 0;
socklen_t len = sizeof(err);
@@ -88,190 +88,190 @@ namespace NInterconnect {
err = LastSocketError();
}
return err;
- }
-
+ }
+
/////////////////////////////////////////////////////////////////
-
- TIntrusivePtr<TStreamSocket> TStreamSocket::Make(int domain) {
- const SOCKET res = ::socket(domain, SOCK_STREAM | SOCK_NONBLOCK, 0);
- if (res == -1) {
- const int err = LastSocketError();
- Y_VERIFY(err != EMFILE && err != ENFILE);
- }
- return MakeIntrusive<TStreamSocket>(res);
- }
-
+
+ TIntrusivePtr<TStreamSocket> TStreamSocket::Make(int domain) {
+ const SOCKET res = ::socket(domain, SOCK_STREAM | SOCK_NONBLOCK, 0);
+ if (res == -1) {
+ const int err = LastSocketError();
+ Y_VERIFY(err != EMFILE && err != ENFILE);
+ }
+ return MakeIntrusive<TStreamSocket>(res);
+ }
+
TStreamSocket::TStreamSocket(SOCKET fd)
: TSocket(fd)
{
}
-
+
ssize_t
- TStreamSocket::Send(const void* msg, size_t len, TString* /*err*/) const {
- const auto ret = ::send(Descriptor, static_cast<const char*>(msg), int(len), 0);
+ TStreamSocket::Send(const void* msg, size_t len, TString* /*err*/) const {
+ const auto ret = ::send(Descriptor, static_cast<const char*>(msg), int(len), 0);
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
ssize_t
- TStreamSocket::Recv(void* buf, size_t len, TString* /*err*/) const {
- const auto ret = ::recv(Descriptor, static_cast<char*>(buf), int(len), 0);
+ TStreamSocket::Recv(void* buf, size_t len, TString* /*err*/) const {
+ const auto ret = ::recv(Descriptor, static_cast<char*>(buf), int(len), 0);
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
ssize_t
TStreamSocket::WriteV(const struct iovec* iov, int iovcnt) const {
-#ifndef _win_
+#ifndef _win_
const auto ret = ::writev(Descriptor, iov, iovcnt);
if (ret < 0)
return -LastSocketError();
return ret;
-#else
- Y_FAIL("WriteV() unsupported on Windows");
-#endif
+#else
+ Y_FAIL("WriteV() unsupported on Windows");
+#endif
}
-
+
ssize_t
TStreamSocket::ReadV(const struct iovec* iov, int iovcnt) const {
-#ifndef _win_
+#ifndef _win_
const auto ret = ::readv(Descriptor, iov, iovcnt);
if (ret < 0)
return -LastSocketError();
return ret;
-#else
- Y_FAIL("ReadV() unsupported on Windows");
-#endif
+#else
+ Y_FAIL("ReadV() unsupported on Windows");
+#endif
}
-
+
ssize_t TStreamSocket::GetUnsentQueueSize() const {
int num = -1;
-#ifndef _win_ // we have no means to determine output queue size on Windows
+#ifndef _win_ // we have no means to determine output queue size on Windows
if (ioctl(Descriptor, TIOCOUTQ, &num) == -1) {
num = -1;
}
#endif
return num;
- }
-
+ }
+
int
TStreamSocket::Connect(const TAddress& addr) const {
const auto ret = ::connect(Descriptor, addr.SockAddr(), addr.Size());
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
int
TStreamSocket::Connect(const NAddr::IRemoteAddr* addr) const {
const auto ret = ::connect(Descriptor, addr->Addr(), addr->Len());
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
int
TStreamSocket::Listen(int backlog) const {
const auto ret = ::listen(Descriptor, backlog);
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
int
TStreamSocket::Accept(TAddress& acceptedAddr) const {
socklen_t acceptedSize = sizeof(::sockaddr_in6);
const auto ret = ::accept(Descriptor, acceptedAddr.SockAddr(), &acceptedSize);
if (ret == INVALID_SOCKET)
return -LastSocketError();
-
+
return ret;
}
-
+
void
TStreamSocket::SetSendBufferSize(i32 len) const {
(void)SetSockOpt(Descriptor, SOL_SOCKET, SO_SNDBUF, len);
}
-
- ui32 TStreamSocket::GetSendBufferSize() const {
- ui32 res = 0;
- CheckedGetSockOpt(Descriptor, SOL_SOCKET, SO_SNDBUF, res, "SO_SNDBUF");
- return res;
- }
-
+
+ ui32 TStreamSocket::GetSendBufferSize() const {
+ ui32 res = 0;
+ CheckedGetSockOpt(Descriptor, SOL_SOCKET, SO_SNDBUF, res, "SO_SNDBUF");
+ return res;
+ }
+
//////////////////////////////////////////////////////
-
- TDatagramSocket::TPtr TDatagramSocket::Make(int domain) {
- const SOCKET res = ::socket(domain, SOCK_DGRAM, 0);
- if (res == -1) {
- const int err = LastSocketError();
- Y_VERIFY(err != EMFILE && err != ENFILE);
- }
- return std::make_shared<TDatagramSocket>(res);
- }
-
+
+ TDatagramSocket::TPtr TDatagramSocket::Make(int domain) {
+ const SOCKET res = ::socket(domain, SOCK_DGRAM, 0);
+ if (res == -1) {
+ const int err = LastSocketError();
+ Y_VERIFY(err != EMFILE && err != ENFILE);
+ }
+ return std::make_shared<TDatagramSocket>(res);
+ }
+
TDatagramSocket::TDatagramSocket(SOCKET fd)
: TSocket(fd)
{
}
-
+
ssize_t
TDatagramSocket::SendTo(const void* msg, size_t len, const TAddress& toAddr) const {
const auto ret = ::sendto(Descriptor, static_cast<const char*>(msg), int(len), 0, toAddr.SockAddr(), toAddr.Size());
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
+
ssize_t
TDatagramSocket::RecvFrom(void* buf, size_t len, TAddress& fromAddr) const {
socklen_t fromSize = sizeof(::sockaddr_in6);
const auto ret = ::recvfrom(Descriptor, static_cast<char*>(buf), int(len), 0, fromAddr.SockAddr(), &fromSize);
if (ret < 0)
return -LastSocketError();
-
+
return ret;
}
-
-
- // deleter for SSL objects
- struct TDeleter {
- void operator ()(BIO *bio) const {
- BIO_free(bio);
- }
-
- void operator ()(X509 *x509) const {
- X509_free(x509);
- }
-
- void operator ()(RSA *rsa) const {
- RSA_free(rsa);
- }
-
- void operator ()(SSL_CTX *ctx) const {
- SSL_CTX_free(ctx);
- }
- };
-
- class TSecureSocketContext::TImpl {
- std::unique_ptr<SSL_CTX, TDeleter> Ctx;
-
- public:
- TImpl(const TString& certificate, const TString& privateKey, const TString& caFilePath,
- const TString& ciphers) {
+
+
+ // deleter for SSL objects
+ struct TDeleter {
+ void operator ()(BIO *bio) const {
+ BIO_free(bio);
+ }
+
+ void operator ()(X509 *x509) const {
+ X509_free(x509);
+ }
+
+ void operator ()(RSA *rsa) const {
+ RSA_free(rsa);
+ }
+
+ void operator ()(SSL_CTX *ctx) const {
+ SSL_CTX_free(ctx);
+ }
+ };
+
+ class TSecureSocketContext::TImpl {
+ std::unique_ptr<SSL_CTX, TDeleter> Ctx;
+
+ public:
+ TImpl(const TString& certificate, const TString& privateKey, const TString& caFilePath,
+ const TString& ciphers) {
int ret;
- InitOpenSSL();
+ InitOpenSSL();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
- Ctx.reset(SSL_CTX_new(TLSv1_2_method()));
- Y_VERIFY(Ctx, "SSL_CTX_new() failed");
+ Ctx.reset(SSL_CTX_new(TLSv1_2_method()));
+ Y_VERIFY(Ctx, "SSL_CTX_new() failed");
#else
Ctx.reset(SSL_CTX_new(TLS_method()));
Y_VERIFY(Ctx, "SSL_CTX_new() failed");
@@ -280,19 +280,19 @@ namespace NInterconnect {
ret = SSL_CTX_set_max_proto_version(Ctx.get(), TLS1_2_VERSION);
Y_VERIFY(ret == 1, "failed to set max proto version");
#endif
- SSL_CTX_set_verify(Ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, &Verify);
- SSL_CTX_set_mode(*this, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
- // apply certificates in SSL context
- if (certificate) {
- std::unique_ptr<BIO, TDeleter> bio(BIO_new_mem_buf(certificate.data(), certificate.size()));
- Y_VERIFY(bio);
+ SSL_CTX_set_verify(Ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, &Verify);
+ SSL_CTX_set_mode(*this, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+
+ // apply certificates in SSL context
+ if (certificate) {
+ std::unique_ptr<BIO, TDeleter> bio(BIO_new_mem_buf(certificate.data(), certificate.size()));
+ Y_VERIFY(bio);
// first certificate in the chain is expected to be a leaf
- std::unique_ptr<X509, TDeleter> cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
- Y_VERIFY(cert, "failed to parse certificate");
- ret = SSL_CTX_use_certificate(Ctx.get(), cert.get());
- Y_VERIFY(ret == 1);
+ std::unique_ptr<X509, TDeleter> cert(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+ Y_VERIFY(cert, "failed to parse certificate");
+ ret = SSL_CTX_use_certificate(Ctx.get(), cert.get());
+ Y_VERIFY(ret == 1);
// loading additional certificates in the chain, if any
while(true) {
@@ -304,325 +304,325 @@ namespace NInterconnect {
Y_VERIFY(ret == 1);
// we must not free memory if certificate was added successfully by SSL_CTX_add0_chain_cert
}
- }
- if (privateKey) {
- std::unique_ptr<BIO, TDeleter> bio(BIO_new_mem_buf(privateKey.data(), privateKey.size()));
- Y_VERIFY(bio);
- std::unique_ptr<RSA, TDeleter> pkey(PEM_read_bio_RSAPrivateKey(bio.get(), nullptr, nullptr, nullptr));
- Y_VERIFY(pkey);
- ret = SSL_CTX_use_RSAPrivateKey(Ctx.get(), pkey.get());
- Y_VERIFY(ret == 1);
- }
- if (caFilePath) {
- ret = SSL_CTX_load_verify_locations(Ctx.get(), caFilePath.data(), nullptr);
- Y_VERIFY(ret == 1);
- }
-
- int success = SSL_CTX_set_cipher_list(Ctx.get(), ciphers ? ciphers.data() : "AES128-GCM-SHA256");
- Y_VERIFY(success, "failed to set cipher list");
- }
-
- operator SSL_CTX*() const {
- return Ctx.get();
- }
-
- static int GetExIndex() {
- static int index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
- return index;
- }
-
- private:
- static int Verify(int preverify, X509_STORE_CTX *ctx) {
- if (!preverify) {
- X509 *badCert = X509_STORE_CTX_get_current_cert(ctx);
- int err = X509_STORE_CTX_get_error(ctx);
- int depth = X509_STORE_CTX_get_error_depth(ctx);
- SSL *ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
- TString *errp = static_cast<TString*>(SSL_get_ex_data(ssl, GetExIndex()));
- char buffer[1024];
- X509_NAME_oneline(X509_get_subject_name(badCert), buffer, sizeof(buffer));
- TStringBuilder s;
- s << "Error during certificate validation"
- << " error# " << X509_verify_cert_error_string(err)
- << " depth# " << depth
- << " cert# " << buffer;
- if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) {
- X509_NAME_oneline(X509_get_issuer_name(badCert), buffer, sizeof(buffer));
- s << " issuer# " << buffer;
- }
- *errp = s;
- }
- return preverify;
- }
- };
-
- TSecureSocketContext::TSecureSocketContext(const TString& certificate, const TString& privateKey,
- const TString& caFilePath, const TString& ciphers)
- : Impl(new TImpl(certificate, privateKey, caFilePath, ciphers))
- {}
-
- TSecureSocketContext::~TSecureSocketContext()
- {}
-
- class TSecureSocket::TImpl {
- SSL *Ssl;
- TString ErrorDescription;
- bool WantRead_ = false;
- bool WantWrite_ = false;
-
- public:
- TImpl(SSL_CTX *ctx, int fd)
- : Ssl(SSL_new(ctx))
- {
- Y_VERIFY(Ssl, "SSL_new() failed");
- SSL_set_fd(Ssl, fd);
- SSL_set_ex_data(Ssl, TSecureSocketContext::TImpl::GetExIndex(), &ErrorDescription);
- }
-
- ~TImpl() {
- SSL_free(Ssl);
- }
-
- TString GetErrorStack() {
- if (ErrorDescription) {
- return ErrorDescription;
- }
- std::unique_ptr<BIO, int(*)(BIO*)> mem(BIO_new(BIO_s_mem()), BIO_free);
- ERR_print_errors(mem.get());
- char *p = nullptr;
- auto len = BIO_get_mem_data(mem.get(), &p);
- return TString(p, len);
- }
-
- EStatus ConvertResult(int res, TString& err) {
- switch (res) {
- case SSL_ERROR_NONE:
- return EStatus::SUCCESS;
-
- case SSL_ERROR_WANT_READ:
- return EStatus::WANT_READ;
-
- case SSL_ERROR_WANT_WRITE:
- return EStatus::WANT_WRITE;
-
- case SSL_ERROR_SYSCALL:
- err = TStringBuilder() << "syscall error: " << strerror(LastSocketError()) << ": " << GetErrorStack();
- break;
-
- case SSL_ERROR_ZERO_RETURN:
- err = "TLS negotiation failed";
- break;
-
- case SSL_ERROR_SSL:
- err = "SSL error: " + GetErrorStack();
- break;
-
- default:
- err = "unknown OpenSSL error";
- break;
- }
- return EStatus::ERROR;
- }
-
- enum EConnectState {
- CONNECT,
- SHUTDOWN,
- READ,
- } ConnectState = EConnectState::CONNECT;
-
- EStatus Establish(bool server, bool authOnly, TString& err) {
- switch (ConnectState) {
- case EConnectState::CONNECT: {
- auto callback = server ? SSL_accept : SSL_connect;
- const EStatus status = ConvertResult(SSL_get_error(Ssl, callback(Ssl)), err);
- if (status != EStatus::SUCCESS || !authOnly) {
- return status;
- }
- ConnectState = EConnectState::SHUTDOWN;
- [[fallthrough]];
- }
-
- case EConnectState::SHUTDOWN: {
- const int res = SSL_shutdown(Ssl);
- if (res == 1) {
- return EStatus::SUCCESS;
- } else if (res != 0) {
- return ConvertResult(SSL_get_error(Ssl, res), err);
- }
- ConnectState = EConnectState::READ;
- [[fallthrough]];
- }
-
- case EConnectState::READ: {
- char data[256];
- size_t numRead = 0;
- const int res = SSL_get_error(Ssl, SSL_read_ex(Ssl, data, sizeof(data), &numRead));
- if (res == SSL_ERROR_ZERO_RETURN) {
- return EStatus::SUCCESS;
- } else if (res != SSL_ERROR_NONE) {
- return ConvertResult(res, err);
- } else if (numRead) {
- err = "non-zero return from SSL_read_ex: " + ToString(numRead);
- return EStatus::ERROR;
- } else {
- return EStatus::SUCCESS;
- }
- }
- }
- Y_FAIL();
- }
-
- std::optional<std::pair<const void*, size_t>> BlockedSend;
-
- ssize_t Send(const void* msg, size_t len, TString *err) {
- Y_VERIFY(!BlockedSend || *BlockedSend == std::make_pair(msg, len));
- const ssize_t res = Operate(msg, len, &SSL_write_ex, err);
- if (res == -EAGAIN) {
- BlockedSend.emplace(msg, len);
- } else {
- BlockedSend.reset();
- }
- return res;
- }
-
- std::optional<std::pair<void*, size_t>> BlockedReceive;
-
- ssize_t Recv(void* msg, size_t len, TString *err) {
- Y_VERIFY(!BlockedReceive || *BlockedReceive == std::make_pair(msg, len));
- const ssize_t res = Operate(msg, len, &SSL_read_ex, err);
- if (res == -EAGAIN) {
- BlockedReceive.emplace(msg, len);
- } else {
- BlockedReceive.reset();
- }
- return res;
- }
-
- TString GetCipherName() const {
- return SSL_get_cipher_name(Ssl);
- }
-
- int GetCipherBits() const {
- return SSL_get_cipher_bits(Ssl, nullptr);
- }
-
- TString GetProtocolName() const {
- return SSL_get_cipher_version(Ssl);
- }
-
- TString GetPeerCommonName() const {
- TString res;
- if (X509 *cert = SSL_get_peer_certificate(Ssl)) {
- char buffer[256];
- memset(buffer, 0, sizeof(buffer));
- if (X509_NAME *name = X509_get_subject_name(cert)) {
- X509_NAME_get_text_by_NID(name, NID_commonName, buffer, sizeof(buffer));
- }
- X509_free(cert);
- res = TString(buffer, strnlen(buffer, sizeof(buffer)));
- }
- return res;
- }
-
- bool WantRead() const {
- return WantRead_;
- }
-
- bool WantWrite() const {
- return WantWrite_;
- }
-
- private:
- template<typename TBuffer, typename TOp>
- ssize_t Operate(TBuffer* buffer, size_t len, TOp&& op, TString *err) {
- WantRead_ = WantWrite_ = false;
- size_t processed = 0;
- int ret = op(Ssl, buffer, len, &processed);
- if (ret == 1) {
- return processed;
- }
- switch (const int status = SSL_get_error(Ssl, ret)) {
- case SSL_ERROR_ZERO_RETURN:
- return 0;
-
- case SSL_ERROR_WANT_READ:
- WantRead_ = true;
- return -EAGAIN;
-
- case SSL_ERROR_WANT_WRITE:
- WantWrite_ = true;
- return -EAGAIN;
-
- case SSL_ERROR_SYSCALL:
- return -LastSocketError();
-
- case SSL_ERROR_SSL:
- if (err) {
- *err = GetErrorStack();
- }
- return -EPROTO;
-
- default:
- Y_FAIL("unexpected SSL_get_error() status# %d", status);
- }
- }
- };
-
- TSecureSocket::TSecureSocket(TStreamSocket& socket, TSecureSocketContext::TPtr context)
- : TStreamSocket(socket.ReleaseDescriptor())
- , Context(std::move(context))
- , Impl(new TImpl(*Context->Impl, Descriptor))
- {}
-
- TSecureSocket::~TSecureSocket()
- {}
-
- TSecureSocket::EStatus TSecureSocket::Establish(bool server, bool authOnly, TString& err) const {
- return Impl->Establish(server, authOnly, err);
- }
-
- TIntrusivePtr<TStreamSocket> TSecureSocket::Detach() {
- return MakeIntrusive<TStreamSocket>(ReleaseDescriptor());
- }
-
- ssize_t TSecureSocket::Send(const void* msg, size_t len, TString *err) const {
- return Impl->Send(msg, len, err);
- }
-
- ssize_t TSecureSocket::Recv(void* msg, size_t len, TString *err) const {
- return Impl->Recv(msg, len, err);
- }
-
- ssize_t TSecureSocket::WriteV(const struct iovec* /*iov*/, int /*iovcnt*/) const {
- Y_FAIL("unsupported on SSL sockets");
- }
-
- ssize_t TSecureSocket::ReadV(const struct iovec* /*iov*/, int /*iovcnt*/) const {
- Y_FAIL("unsupported on SSL sockets");
- }
-
- TString TSecureSocket::GetCipherName() const {
- return Impl->GetCipherName();
- }
-
- int TSecureSocket::GetCipherBits() const {
- return Impl->GetCipherBits();
- }
-
- TString TSecureSocket::GetProtocolName() const {
- return Impl->GetProtocolName();
- }
-
- TString TSecureSocket::GetPeerCommonName() const {
- return Impl->GetPeerCommonName();
- }
-
- bool TSecureSocket::WantRead() const {
- return Impl->WantRead();
- }
-
- bool TSecureSocket::WantWrite() const {
- return Impl->WantWrite();
- }
-
-}
+ }
+ if (privateKey) {
+ std::unique_ptr<BIO, TDeleter> bio(BIO_new_mem_buf(privateKey.data(), privateKey.size()));
+ Y_VERIFY(bio);
+ std::unique_ptr<RSA, TDeleter> pkey(PEM_read_bio_RSAPrivateKey(bio.get(), nullptr, nullptr, nullptr));
+ Y_VERIFY(pkey);
+ ret = SSL_CTX_use_RSAPrivateKey(Ctx.get(), pkey.get());
+ Y_VERIFY(ret == 1);
+ }
+ if (caFilePath) {
+ ret = SSL_CTX_load_verify_locations(Ctx.get(), caFilePath.data(), nullptr);
+ Y_VERIFY(ret == 1);
+ }
+
+ int success = SSL_CTX_set_cipher_list(Ctx.get(), ciphers ? ciphers.data() : "AES128-GCM-SHA256");
+ Y_VERIFY(success, "failed to set cipher list");
+ }
+
+ operator SSL_CTX*() const {
+ return Ctx.get();
+ }
+
+ static int GetExIndex() {
+ static int index = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+ return index;
+ }
+
+ private:
+ static int Verify(int preverify, X509_STORE_CTX *ctx) {
+ if (!preverify) {
+ X509 *badCert = X509_STORE_CTX_get_current_cert(ctx);
+ int err = X509_STORE_CTX_get_error(ctx);
+ int depth = X509_STORE_CTX_get_error_depth(ctx);
+ SSL *ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+ TString *errp = static_cast<TString*>(SSL_get_ex_data(ssl, GetExIndex()));
+ char buffer[1024];
+ X509_NAME_oneline(X509_get_subject_name(badCert), buffer, sizeof(buffer));
+ TStringBuilder s;
+ s << "Error during certificate validation"
+ << " error# " << X509_verify_cert_error_string(err)
+ << " depth# " << depth
+ << " cert# " << buffer;
+ if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) {
+ X509_NAME_oneline(X509_get_issuer_name(badCert), buffer, sizeof(buffer));
+ s << " issuer# " << buffer;
+ }
+ *errp = s;
+ }
+ return preverify;
+ }
+ };
+
+ TSecureSocketContext::TSecureSocketContext(const TString& certificate, const TString& privateKey,
+ const TString& caFilePath, const TString& ciphers)
+ : Impl(new TImpl(certificate, privateKey, caFilePath, ciphers))
+ {}
+
+ TSecureSocketContext::~TSecureSocketContext()
+ {}
+
+ class TSecureSocket::TImpl {
+ SSL *Ssl;
+ TString ErrorDescription;
+ bool WantRead_ = false;
+ bool WantWrite_ = false;
+
+ public:
+ TImpl(SSL_CTX *ctx, int fd)
+ : Ssl(SSL_new(ctx))
+ {
+ Y_VERIFY(Ssl, "SSL_new() failed");
+ SSL_set_fd(Ssl, fd);
+ SSL_set_ex_data(Ssl, TSecureSocketContext::TImpl::GetExIndex(), &ErrorDescription);
+ }
+
+ ~TImpl() {
+ SSL_free(Ssl);
+ }
+
+ TString GetErrorStack() {
+ if (ErrorDescription) {
+ return ErrorDescription;
+ }
+ std::unique_ptr<BIO, int(*)(BIO*)> mem(BIO_new(BIO_s_mem()), BIO_free);
+ ERR_print_errors(mem.get());
+ char *p = nullptr;
+ auto len = BIO_get_mem_data(mem.get(), &p);
+ return TString(p, len);
+ }
+
+ EStatus ConvertResult(int res, TString& err) {
+ switch (res) {
+ case SSL_ERROR_NONE:
+ return EStatus::SUCCESS;
+
+ case SSL_ERROR_WANT_READ:
+ return EStatus::WANT_READ;
+
+ case SSL_ERROR_WANT_WRITE:
+ return EStatus::WANT_WRITE;
+
+ case SSL_ERROR_SYSCALL:
+ err = TStringBuilder() << "syscall error: " << strerror(LastSocketError()) << ": " << GetErrorStack();
+ break;
+
+ case SSL_ERROR_ZERO_RETURN:
+ err = "TLS negotiation failed";
+ break;
+
+ case SSL_ERROR_SSL:
+ err = "SSL error: " + GetErrorStack();
+ break;
+
+ default:
+ err = "unknown OpenSSL error";
+ break;
+ }
+ return EStatus::ERROR;
+ }
+
+ enum EConnectState {
+ CONNECT,
+ SHUTDOWN,
+ READ,
+ } ConnectState = EConnectState::CONNECT;
+
+ EStatus Establish(bool server, bool authOnly, TString& err) {
+ switch (ConnectState) {
+ case EConnectState::CONNECT: {
+ auto callback = server ? SSL_accept : SSL_connect;
+ const EStatus status = ConvertResult(SSL_get_error(Ssl, callback(Ssl)), err);
+ if (status != EStatus::SUCCESS || !authOnly) {
+ return status;
+ }
+ ConnectState = EConnectState::SHUTDOWN;
+ [[fallthrough]];
+ }
+
+ case EConnectState::SHUTDOWN: {
+ const int res = SSL_shutdown(Ssl);
+ if (res == 1) {
+ return EStatus::SUCCESS;
+ } else if (res != 0) {
+ return ConvertResult(SSL_get_error(Ssl, res), err);
+ }
+ ConnectState = EConnectState::READ;
+ [[fallthrough]];
+ }
+
+ case EConnectState::READ: {
+ char data[256];
+ size_t numRead = 0;
+ const int res = SSL_get_error(Ssl, SSL_read_ex(Ssl, data, sizeof(data), &numRead));
+ if (res == SSL_ERROR_ZERO_RETURN) {
+ return EStatus::SUCCESS;
+ } else if (res != SSL_ERROR_NONE) {
+ return ConvertResult(res, err);
+ } else if (numRead) {
+ err = "non-zero return from SSL_read_ex: " + ToString(numRead);
+ return EStatus::ERROR;
+ } else {
+ return EStatus::SUCCESS;
+ }
+ }
+ }
+ Y_FAIL();
+ }
+
+ std::optional<std::pair<const void*, size_t>> BlockedSend;
+
+ ssize_t Send(const void* msg, size_t len, TString *err) {
+ Y_VERIFY(!BlockedSend || *BlockedSend == std::make_pair(msg, len));
+ const ssize_t res = Operate(msg, len, &SSL_write_ex, err);
+ if (res == -EAGAIN) {
+ BlockedSend.emplace(msg, len);
+ } else {
+ BlockedSend.reset();
+ }
+ return res;
+ }
+
+ std::optional<std::pair<void*, size_t>> BlockedReceive;
+
+ ssize_t Recv(void* msg, size_t len, TString *err) {
+ Y_VERIFY(!BlockedReceive || *BlockedReceive == std::make_pair(msg, len));
+ const ssize_t res = Operate(msg, len, &SSL_read_ex, err);
+ if (res == -EAGAIN) {
+ BlockedReceive.emplace(msg, len);
+ } else {
+ BlockedReceive.reset();
+ }
+ return res;
+ }
+
+ TString GetCipherName() const {
+ return SSL_get_cipher_name(Ssl);
+ }
+
+ int GetCipherBits() const {
+ return SSL_get_cipher_bits(Ssl, nullptr);
+ }
+
+ TString GetProtocolName() const {
+ return SSL_get_cipher_version(Ssl);
+ }
+
+ TString GetPeerCommonName() const {
+ TString res;
+ if (X509 *cert = SSL_get_peer_certificate(Ssl)) {
+ char buffer[256];
+ memset(buffer, 0, sizeof(buffer));
+ if (X509_NAME *name = X509_get_subject_name(cert)) {
+ X509_NAME_get_text_by_NID(name, NID_commonName, buffer, sizeof(buffer));
+ }
+ X509_free(cert);
+ res = TString(buffer, strnlen(buffer, sizeof(buffer)));
+ }
+ return res;
+ }
+
+ bool WantRead() const {
+ return WantRead_;
+ }
+
+ bool WantWrite() const {
+ return WantWrite_;
+ }
+
+ private:
+ template<typename TBuffer, typename TOp>
+ ssize_t Operate(TBuffer* buffer, size_t len, TOp&& op, TString *err) {
+ WantRead_ = WantWrite_ = false;
+ size_t processed = 0;
+ int ret = op(Ssl, buffer, len, &processed);
+ if (ret == 1) {
+ return processed;
+ }
+ switch (const int status = SSL_get_error(Ssl, ret)) {
+ case SSL_ERROR_ZERO_RETURN:
+ return 0;
+
+ case SSL_ERROR_WANT_READ:
+ WantRead_ = true;
+ return -EAGAIN;
+
+ case SSL_ERROR_WANT_WRITE:
+ WantWrite_ = true;
+ return -EAGAIN;
+
+ case SSL_ERROR_SYSCALL:
+ return -LastSocketError();
+
+ case SSL_ERROR_SSL:
+ if (err) {
+ *err = GetErrorStack();
+ }
+ return -EPROTO;
+
+ default:
+ Y_FAIL("unexpected SSL_get_error() status# %d", status);
+ }
+ }
+ };
+
+ TSecureSocket::TSecureSocket(TStreamSocket& socket, TSecureSocketContext::TPtr context)
+ : TStreamSocket(socket.ReleaseDescriptor())
+ , Context(std::move(context))
+ , Impl(new TImpl(*Context->Impl, Descriptor))
+ {}
+
+ TSecureSocket::~TSecureSocket()
+ {}
+
+ TSecureSocket::EStatus TSecureSocket::Establish(bool server, bool authOnly, TString& err) const {
+ return Impl->Establish(server, authOnly, err);
+ }
+
+ TIntrusivePtr<TStreamSocket> TSecureSocket::Detach() {
+ return MakeIntrusive<TStreamSocket>(ReleaseDescriptor());
+ }
+
+ ssize_t TSecureSocket::Send(const void* msg, size_t len, TString *err) const {
+ return Impl->Send(msg, len, err);
+ }
+
+ ssize_t TSecureSocket::Recv(void* msg, size_t len, TString *err) const {
+ return Impl->Recv(msg, len, err);
+ }
+
+ ssize_t TSecureSocket::WriteV(const struct iovec* /*iov*/, int /*iovcnt*/) const {
+ Y_FAIL("unsupported on SSL sockets");
+ }
+
+ ssize_t TSecureSocket::ReadV(const struct iovec* /*iov*/, int /*iovcnt*/) const {
+ Y_FAIL("unsupported on SSL sockets");
+ }
+
+ TString TSecureSocket::GetCipherName() const {
+ return Impl->GetCipherName();
+ }
+
+ int TSecureSocket::GetCipherBits() const {
+ return Impl->GetCipherBits();
+ }
+
+ TString TSecureSocket::GetProtocolName() const {
+ return Impl->GetProtocolName();
+ }
+
+ TString TSecureSocket::GetPeerCommonName() const {
+ return Impl->GetPeerCommonName();
+ }
+
+ bool TSecureSocket::WantRead() const {
+ return Impl->WantRead();
+ }
+
+ bool TSecureSocket::WantWrite() const {
+ return Impl->WantWrite();
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_stream.h b/library/cpp/actors/interconnect/interconnect_stream.h
index 074adc6e74c..fd427f2c2f1 100644
--- a/library/cpp/actors/interconnect/interconnect_stream.h
+++ b/library/cpp/actors/interconnect/interconnect_stream.h
@@ -1,131 +1,131 @@
-#pragma once
-
-#include <util/generic/string.h>
-#include <util/generic/noncopyable.h>
-#include <util/network/address.h>
-#include <util/network/init.h>
-#include <util/system/defaults.h>
-
-#include "poller.h"
-
-#include "interconnect_address.h"
-
-#include <memory>
-
+#pragma once
+
+#include <util/generic/string.h>
+#include <util/generic/noncopyable.h>
+#include <util/network/address.h>
+#include <util/network/init.h>
+#include <util/system/defaults.h>
+
+#include "poller.h"
+
+#include "interconnect_address.h"
+
+#include <memory>
+
#include <sys/uio.h>
-namespace NInterconnect {
+namespace NInterconnect {
class TSocket: public NActors::TSharedDescriptor, public TNonCopyable {
protected:
TSocket(SOCKET fd);
-
+
virtual ~TSocket() override;
-
- SOCKET Descriptor;
-
+
+ SOCKET Descriptor;
+
virtual int GetDescriptor() override;
-
- private:
- friend class TSecureSocket;
-
- SOCKET ReleaseDescriptor() {
- return std::exchange(Descriptor, INVALID_SOCKET);
- }
-
+
+ private:
+ friend class TSecureSocket;
+
+ SOCKET ReleaseDescriptor() {
+ return std::exchange(Descriptor, INVALID_SOCKET);
+ }
+
public:
operator SOCKET() const {
return Descriptor;
}
-
+
int Bind(const TAddress& addr) const;
int Shutdown(int how) const;
int GetConnectStatus() const;
};
-
+
class TStreamSocket: public TSocket {
public:
TStreamSocket(SOCKET fd);
-
+
static TIntrusivePtr<TStreamSocket> Make(int domain);
-
- virtual ssize_t Send(const void* msg, size_t len, TString *err = nullptr) const;
- virtual ssize_t Recv(void* buf, size_t len, TString *err = nullptr) const;
-
- virtual ssize_t WriteV(const struct iovec* iov, int iovcnt) const;
- virtual ssize_t ReadV(const struct iovec* iov, int iovcnt) const;
-
+
+ virtual ssize_t Send(const void* msg, size_t len, TString *err = nullptr) const;
+ virtual ssize_t Recv(void* buf, size_t len, TString *err = nullptr) const;
+
+ virtual ssize_t WriteV(const struct iovec* iov, int iovcnt) const;
+ virtual ssize_t ReadV(const struct iovec* iov, int iovcnt) const;
+
int Connect(const TAddress& addr) const;
int Connect(const NAddr::IRemoteAddr* addr) const;
int Listen(int backlog) const;
int Accept(TAddress& acceptedAddr) const;
-
+
ssize_t GetUnsentQueueSize() const;
-
+
void SetSendBufferSize(i32 len) const;
- ui32 GetSendBufferSize() const;
+ ui32 GetSendBufferSize() const;
};
-
- class TSecureSocketContext {
- class TImpl;
- THolder<TImpl> Impl;
-
- friend class TSecureSocket;
-
- public:
- TSecureSocketContext(const TString& certificate, const TString& privateKey, const TString& caFilePath,
- const TString& ciphers);
- ~TSecureSocketContext();
-
- public:
+
+ class TSecureSocketContext {
+ class TImpl;
+ THolder<TImpl> Impl;
+
+ friend class TSecureSocket;
+
+ public:
+ TSecureSocketContext(const TString& certificate, const TString& privateKey, const TString& caFilePath,
+ const TString& ciphers);
+ ~TSecureSocketContext();
+
+ public:
using TPtr = std::shared_ptr<TSecureSocketContext>;
- };
-
- class TSecureSocket : public TStreamSocket {
- TSecureSocketContext::TPtr Context;
-
- class TImpl;
- THolder<TImpl> Impl;
-
- public:
- enum class EStatus {
- SUCCESS,
- ERROR,
- WANT_READ,
- WANT_WRITE,
- };
-
- public:
- TSecureSocket(TStreamSocket& socket, TSecureSocketContext::TPtr context);
- ~TSecureSocket();
-
- EStatus Establish(bool server, bool authOnly, TString& err) const;
- TIntrusivePtr<TStreamSocket> Detach();
-
- ssize_t Send(const void* msg, size_t len, TString *err) const override;
- ssize_t Recv(void* msg, size_t len, TString *err) const override;
-
- ssize_t WriteV(const struct iovec* iov, int iovcnt) const override;
- ssize_t ReadV(const struct iovec* iov, int iovcnt) const override;
-
- TString GetCipherName() const;
- int GetCipherBits() const;
- TString GetProtocolName() const;
- TString GetPeerCommonName() const;
-
- bool WantRead() const;
- bool WantWrite() const;
- };
-
+ };
+
+ class TSecureSocket : public TStreamSocket {
+ TSecureSocketContext::TPtr Context;
+
+ class TImpl;
+ THolder<TImpl> Impl;
+
+ public:
+ enum class EStatus {
+ SUCCESS,
+ ERROR,
+ WANT_READ,
+ WANT_WRITE,
+ };
+
+ public:
+ TSecureSocket(TStreamSocket& socket, TSecureSocketContext::TPtr context);
+ ~TSecureSocket();
+
+ EStatus Establish(bool server, bool authOnly, TString& err) const;
+ TIntrusivePtr<TStreamSocket> Detach();
+
+ ssize_t Send(const void* msg, size_t len, TString *err) const override;
+ ssize_t Recv(void* msg, size_t len, TString *err) const override;
+
+ ssize_t WriteV(const struct iovec* iov, int iovcnt) const override;
+ ssize_t ReadV(const struct iovec* iov, int iovcnt) const override;
+
+ TString GetCipherName() const;
+ int GetCipherBits() const;
+ TString GetProtocolName() const;
+ TString GetPeerCommonName() const;
+
+ bool WantRead() const;
+ bool WantWrite() const;
+ };
+
class TDatagramSocket: public TSocket {
public:
typedef std::shared_ptr<TDatagramSocket> TPtr;
-
+
TDatagramSocket(SOCKET fd);
-
+
static TPtr Make(int domain);
-
+
ssize_t SendTo(const void* msg, size_t len, const TAddress& toAddr) const;
ssize_t RecvFrom(void* buf, size_t len, TAddress& fromAddr) const;
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp b/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
index 0abe9fe6598..36cd322bf6a 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
+++ b/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
@@ -1,476 +1,476 @@
-#include "interconnect_tcp_session.h"
-#include "interconnect_tcp_proxy.h"
+#include "interconnect_tcp_session.h"
+#include "interconnect_tcp_proxy.h"
#include <library/cpp/actors/core/probes.h>
#include <library/cpp/actors/util/datetime.h>
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
+
+namespace NActors {
+ LWTRACE_USING(ACTORLIB_PROVIDER);
+
TInputSessionTCP::TInputSessionTCP(const TActorId& sessionId, TIntrusivePtr<NInterconnect::TStreamSocket> socket,
- TIntrusivePtr<TReceiveContext> context, TInterconnectProxyCommon::TPtr common,
+ TIntrusivePtr<TReceiveContext> context, TInterconnectProxyCommon::TPtr common,
std::shared_ptr<IInterconnectMetrics> metrics, ui32 nodeId, ui64 lastConfirmed,
- TDuration deadPeerTimeout, TSessionParams params)
- : SessionId(sessionId)
- , Socket(std::move(socket))
- , Context(std::move(context))
- , Common(std::move(common))
- , NodeId(nodeId)
- , Params(std::move(params))
- , ConfirmedByInput(lastConfirmed)
+ TDuration deadPeerTimeout, TSessionParams params)
+ : SessionId(sessionId)
+ , Socket(std::move(socket))
+ , Context(std::move(context))
+ , Common(std::move(common))
+ , NodeId(nodeId)
+ , Params(std::move(params))
+ , ConfirmedByInput(lastConfirmed)
, Metrics(std::move(metrics))
- , DeadPeerTimeout(deadPeerTimeout)
- {
- Y_VERIFY(Context);
- Y_VERIFY(Socket);
- Y_VERIFY(SessionId);
-
- AtomicSet(Context->PacketsReadFromSocket, 0);
-
+ , DeadPeerTimeout(deadPeerTimeout)
+ {
+ Y_VERIFY(Context);
+ Y_VERIFY(Socket);
+ Y_VERIFY(SessionId);
+
+ AtomicSet(Context->PacketsReadFromSocket, 0);
+
Metrics->SetClockSkewMicrosec(0);
-
- Context->UpdateState = EUpdateState::NONE;
-
- // ensure that we do not spawn new session while the previous one is still alive
- TAtomicBase sessions = AtomicIncrement(Context->NumInputSessions);
- Y_VERIFY(sessions == 1, "sessions# %" PRIu64, ui64(sessions));
- }
-
- void TInputSessionTCP::Bootstrap() {
+
+ Context->UpdateState = EUpdateState::NONE;
+
+ // ensure that we do not spawn new session while the previous one is still alive
+ TAtomicBase sessions = AtomicIncrement(Context->NumInputSessions);
+ Y_VERIFY(sessions == 1, "sessions# %" PRIu64, ui64(sessions));
+ }
+
+ void TInputSessionTCP::Bootstrap() {
SetPrefix(Sprintf("InputSession %s [node %" PRIu32 "]", SelfId().ToString().data(), NodeId));
- Become(&TThis::WorkingState, DeadPeerTimeout, new TEvCheckDeadPeer);
- LOG_DEBUG_IC_SESSION("ICIS01", "InputSession created");
- LastReceiveTimestamp = TActivationContext::Now();
- ReceiveData();
- }
-
- void TInputSessionTCP::CloseInputSession() {
- CloseInputSessionRequested = true;
- ReceiveData();
- }
-
- void TInputSessionTCP::Handle(TEvPollerReady::TPtr ev) {
- if (Context->ReadPending) {
+ Become(&TThis::WorkingState, DeadPeerTimeout, new TEvCheckDeadPeer);
+ LOG_DEBUG_IC_SESSION("ICIS01", "InputSession created");
+ LastReceiveTimestamp = TActivationContext::Now();
+ ReceiveData();
+ }
+
+ void TInputSessionTCP::CloseInputSession() {
+ CloseInputSessionRequested = true;
+ ReceiveData();
+ }
+
+ void TInputSessionTCP::Handle(TEvPollerReady::TPtr ev) {
+ if (Context->ReadPending) {
Metrics->IncUsefulReadWakeups();
- } else if (!ev->Cookie) {
+ } else if (!ev->Cookie) {
Metrics->IncSpuriousReadWakeups();
- }
- Context->ReadPending = false;
- ReceiveData();
- if (Params.Encryption && Context->WriteBlockedByFullSendBuffer && !ev->Cookie) {
- Send(SessionId, ev->Release().Release(), 0, 1);
- }
- }
-
- void TInputSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
- PollerToken = std::move(ev->Get()->PollerToken);
- ReceiveData();
- }
-
- void TInputSessionTCP::HandleResumeReceiveData() {
- ReceiveData();
- }
-
- void TInputSessionTCP::ReceiveData() {
- TTimeLimit limit(GetMaxCyclesPerEvent());
- ui64 numDataBytes = 0;
- const size_t headerLen = Params.UseModernFrame ? sizeof(TTcpPacketHeader_v2) : sizeof(TTcpPacketHeader_v1);
-
- LOG_DEBUG_IC_SESSION("ICIS02", "ReceiveData called");
-
- for (int iteration = 0; Socket; ++iteration) {
- if (iteration && limit.CheckExceeded()) {
- // we have hit processing time limit for this message, send notification to resume processing a bit later
- Send(SelfId(), new TEvResumeReceiveData);
- break;
- }
-
- switch (State) {
- case EState::HEADER:
- if (IncomingData.GetSize() < headerLen) {
- break;
- } else {
- ProcessHeader(headerLen);
- }
- continue;
-
- case EState::PAYLOAD:
- if (!IncomingData) {
- break;
- } else {
- ProcessPayload(numDataBytes);
- }
- continue;
- }
-
- // if we have reached this point, it means that we do not have enough data in read buffer; try to obtain some
- if (!ReadMore()) {
- // we have no data from socket, so we have some free time to spend -- preallocate buffers using this time
- PreallocateBuffers();
- break;
- }
- }
-
- // calculate ping time
- auto it = std::min_element(PingQ.begin(), PingQ.end());
- const TDuration ping = it != PingQ.end() ? *it : TDuration::Zero();
-
- // send update to main session actor if something valuable has changed
- if (!UpdateFromInputSession) {
- UpdateFromInputSession = MakeHolder<TEvUpdateFromInputSession>(ConfirmedByInput, numDataBytes, ping);
- } else {
- Y_VERIFY(ConfirmedByInput >= UpdateFromInputSession->ConfirmedByInput);
- UpdateFromInputSession->ConfirmedByInput = ConfirmedByInput;
- UpdateFromInputSession->NumDataBytes += numDataBytes;
- UpdateFromInputSession->Ping = Min(UpdateFromInputSession->Ping, ping);
- }
-
- for (;;) {
- EUpdateState state = Context->UpdateState;
- EUpdateState next;
-
- // calculate next state
- switch (state) {
- case EUpdateState::NONE:
- case EUpdateState::CONFIRMING:
- // we have no inflight messages to session actor, we will issue one a bit later
- next = EUpdateState::INFLIGHT;
- break;
-
- case EUpdateState::INFLIGHT:
- case EUpdateState::INFLIGHT_AND_PENDING:
- // we already have inflight message, so we will keep pending message and session actor will issue
- // TEvConfirmUpdate to kick processing
- next = EUpdateState::INFLIGHT_AND_PENDING;
- break;
- }
-
- if (Context->UpdateState.compare_exchange_weak(state, next)) {
- switch (next) {
- case EUpdateState::INFLIGHT:
- Send(SessionId, UpdateFromInputSession.Release());
- break;
-
- case EUpdateState::INFLIGHT_AND_PENDING:
- Y_VERIFY(UpdateFromInputSession);
- break;
-
- default:
- Y_FAIL("unexpected state");
- }
- break;
- }
- }
- }
-
- void TInputSessionTCP::ProcessHeader(size_t headerLen) {
- const bool success = IncomingData.ExtractFrontPlain(Header.Data, headerLen);
- Y_VERIFY(success);
- if (Params.UseModernFrame) {
- PayloadSize = Header.v2.PayloadLength;
- HeaderSerial = Header.v2.Serial;
- HeaderConfirm = Header.v2.Confirm;
- if (!Params.Encryption) {
- ChecksumExpected = std::exchange(Header.v2.Checksum, 0);
- Checksum = Crc32cExtendMSanCompatible(0, &Header.v2, sizeof(Header.v2)); // start calculating checksum now
- if (!PayloadSize && Checksum != ChecksumExpected) {
- LOG_ERROR_IC_SESSION("ICIS10", "payload checksum error");
- return ReestablishConnection(TDisconnectReason::ChecksumError());
- }
- }
- } else if (!Header.v1.Check()) {
- LOG_ERROR_IC_SESSION("ICIS03", "header checksum error");
- return ReestablishConnection(TDisconnectReason::ChecksumError());
- } else {
- PayloadSize = Header.v1.DataSize;
- HeaderSerial = Header.v1.Serial;
- HeaderConfirm = Header.v1.Confirm;
- ChecksumExpected = Header.v1.PayloadCRC32;
- Checksum = 0;
- }
- if (PayloadSize >= 65536) {
- LOG_CRIT_IC_SESSION("ICIS07", "payload is way too big");
- return DestroySession(TDisconnectReason::FormatError());
- }
- if (ConfirmedByInput < HeaderConfirm) {
- ConfirmedByInput = HeaderConfirm;
- if (AtomicGet(Context->ControlPacketId) <= HeaderConfirm && !NewPingProtocol) {
- ui64 sendTime = AtomicGet(Context->ControlPacketSendTimer);
+ }
+ Context->ReadPending = false;
+ ReceiveData();
+ if (Params.Encryption && Context->WriteBlockedByFullSendBuffer && !ev->Cookie) {
+ Send(SessionId, ev->Release().Release(), 0, 1);
+ }
+ }
+
+ void TInputSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
+ PollerToken = std::move(ev->Get()->PollerToken);
+ ReceiveData();
+ }
+
+ void TInputSessionTCP::HandleResumeReceiveData() {
+ ReceiveData();
+ }
+
+ void TInputSessionTCP::ReceiveData() {
+ TTimeLimit limit(GetMaxCyclesPerEvent());
+ ui64 numDataBytes = 0;
+ const size_t headerLen = Params.UseModernFrame ? sizeof(TTcpPacketHeader_v2) : sizeof(TTcpPacketHeader_v1);
+
+ LOG_DEBUG_IC_SESSION("ICIS02", "ReceiveData called");
+
+ for (int iteration = 0; Socket; ++iteration) {
+ if (iteration && limit.CheckExceeded()) {
+ // we have hit processing time limit for this message, send notification to resume processing a bit later
+ Send(SelfId(), new TEvResumeReceiveData);
+ break;
+ }
+
+ switch (State) {
+ case EState::HEADER:
+ if (IncomingData.GetSize() < headerLen) {
+ break;
+ } else {
+ ProcessHeader(headerLen);
+ }
+ continue;
+
+ case EState::PAYLOAD:
+ if (!IncomingData) {
+ break;
+ } else {
+ ProcessPayload(numDataBytes);
+ }
+ continue;
+ }
+
+ // if we have reached this point, it means that we do not have enough data in read buffer; try to obtain some
+ if (!ReadMore()) {
+ // we have no data from socket, so we have some free time to spend -- preallocate buffers using this time
+ PreallocateBuffers();
+ break;
+ }
+ }
+
+ // calculate ping time
+ auto it = std::min_element(PingQ.begin(), PingQ.end());
+ const TDuration ping = it != PingQ.end() ? *it : TDuration::Zero();
+
+ // send update to main session actor if something valuable has changed
+ if (!UpdateFromInputSession) {
+ UpdateFromInputSession = MakeHolder<TEvUpdateFromInputSession>(ConfirmedByInput, numDataBytes, ping);
+ } else {
+ Y_VERIFY(ConfirmedByInput >= UpdateFromInputSession->ConfirmedByInput);
+ UpdateFromInputSession->ConfirmedByInput = ConfirmedByInput;
+ UpdateFromInputSession->NumDataBytes += numDataBytes;
+ UpdateFromInputSession->Ping = Min(UpdateFromInputSession->Ping, ping);
+ }
+
+ for (;;) {
+ EUpdateState state = Context->UpdateState;
+ EUpdateState next;
+
+ // calculate next state
+ switch (state) {
+ case EUpdateState::NONE:
+ case EUpdateState::CONFIRMING:
+ // we have no inflight messages to session actor, we will issue one a bit later
+ next = EUpdateState::INFLIGHT;
+ break;
+
+ case EUpdateState::INFLIGHT:
+ case EUpdateState::INFLIGHT_AND_PENDING:
+ // we already have inflight message, so we will keep pending message and session actor will issue
+ // TEvConfirmUpdate to kick processing
+ next = EUpdateState::INFLIGHT_AND_PENDING;
+ break;
+ }
+
+ if (Context->UpdateState.compare_exchange_weak(state, next)) {
+ switch (next) {
+ case EUpdateState::INFLIGHT:
+ Send(SessionId, UpdateFromInputSession.Release());
+ break;
+
+ case EUpdateState::INFLIGHT_AND_PENDING:
+ Y_VERIFY(UpdateFromInputSession);
+ break;
+
+ default:
+ Y_FAIL("unexpected state");
+ }
+ break;
+ }
+ }
+ }
+
+ void TInputSessionTCP::ProcessHeader(size_t headerLen) {
+ const bool success = IncomingData.ExtractFrontPlain(Header.Data, headerLen);
+ Y_VERIFY(success);
+ if (Params.UseModernFrame) {
+ PayloadSize = Header.v2.PayloadLength;
+ HeaderSerial = Header.v2.Serial;
+ HeaderConfirm = Header.v2.Confirm;
+ if (!Params.Encryption) {
+ ChecksumExpected = std::exchange(Header.v2.Checksum, 0);
+ Checksum = Crc32cExtendMSanCompatible(0, &Header.v2, sizeof(Header.v2)); // start calculating checksum now
+ if (!PayloadSize && Checksum != ChecksumExpected) {
+ LOG_ERROR_IC_SESSION("ICIS10", "payload checksum error");
+ return ReestablishConnection(TDisconnectReason::ChecksumError());
+ }
+ }
+ } else if (!Header.v1.Check()) {
+ LOG_ERROR_IC_SESSION("ICIS03", "header checksum error");
+ return ReestablishConnection(TDisconnectReason::ChecksumError());
+ } else {
+ PayloadSize = Header.v1.DataSize;
+ HeaderSerial = Header.v1.Serial;
+ HeaderConfirm = Header.v1.Confirm;
+ ChecksumExpected = Header.v1.PayloadCRC32;
+ Checksum = 0;
+ }
+ if (PayloadSize >= 65536) {
+ LOG_CRIT_IC_SESSION("ICIS07", "payload is way too big");
+ return DestroySession(TDisconnectReason::FormatError());
+ }
+ if (ConfirmedByInput < HeaderConfirm) {
+ ConfirmedByInput = HeaderConfirm;
+ if (AtomicGet(Context->ControlPacketId) <= HeaderConfirm && !NewPingProtocol) {
+ ui64 sendTime = AtomicGet(Context->ControlPacketSendTimer);
TDuration duration = CyclesToDuration(GetCycleCountFast() - sendTime);
const auto durationUs = duration.MicroSeconds();
Metrics->UpdateLegacyPingTimeHist(durationUs);
- PingQ.push_back(duration);
- if (PingQ.size() > 16) {
- PingQ.pop_front();
- }
- AtomicSet(Context->ControlPacketId, 0ULL);
- }
- }
- if (PayloadSize) {
- const ui64 expected = Context->GetLastProcessedPacketSerial() + 1;
- if (HeaderSerial == 0 || HeaderSerial > expected) {
- LOG_CRIT_IC_SESSION("ICIS06", "packet serial %" PRIu64 ", but %" PRIu64 " expected", HeaderSerial, expected);
- return DestroySession(TDisconnectReason::FormatError());
- }
- IgnorePayload = HeaderSerial != expected;
- State = EState::PAYLOAD;
- } else if (HeaderSerial & TTcpPacketBuf::PingRequestMask) {
- Send(SessionId, new TEvProcessPingRequest(HeaderSerial & ~TTcpPacketBuf::PingRequestMask));
- } else if (HeaderSerial & TTcpPacketBuf::PingResponseMask) {
- const ui64 sent = HeaderSerial & ~TTcpPacketBuf::PingResponseMask;
+ PingQ.push_back(duration);
+ if (PingQ.size() > 16) {
+ PingQ.pop_front();
+ }
+ AtomicSet(Context->ControlPacketId, 0ULL);
+ }
+ }
+ if (PayloadSize) {
+ const ui64 expected = Context->GetLastProcessedPacketSerial() + 1;
+ if (HeaderSerial == 0 || HeaderSerial > expected) {
+ LOG_CRIT_IC_SESSION("ICIS06", "packet serial %" PRIu64 ", but %" PRIu64 " expected", HeaderSerial, expected);
+ return DestroySession(TDisconnectReason::FormatError());
+ }
+ IgnorePayload = HeaderSerial != expected;
+ State = EState::PAYLOAD;
+ } else if (HeaderSerial & TTcpPacketBuf::PingRequestMask) {
+ Send(SessionId, new TEvProcessPingRequest(HeaderSerial & ~TTcpPacketBuf::PingRequestMask));
+ } else if (HeaderSerial & TTcpPacketBuf::PingResponseMask) {
+ const ui64 sent = HeaderSerial & ~TTcpPacketBuf::PingResponseMask;
const ui64 received = GetCycleCountFast();
- HandlePingResponse(CyclesToDuration(received - sent));
- } else if (HeaderSerial & TTcpPacketBuf::ClockMask) {
- HandleClock(TInstant::MicroSeconds(HeaderSerial & ~TTcpPacketBuf::ClockMask));
- }
- }
-
- void TInputSessionTCP::ProcessPayload(ui64& numDataBytes) {
- const size_t numBytes = Min(PayloadSize, IncomingData.GetSize());
- IncomingData.ExtractFront(numBytes, &Payload);
- numDataBytes += numBytes;
- PayloadSize -= numBytes;
- if (PayloadSize) {
- return; // there is still some data to receive in the Payload rope
- }
- State = EState::HEADER; // we'll continue with header next time
- if (!Params.UseModernFrame || !Params.Encryption) { // see if we are checksumming packet body
- for (const auto&& [data, size] : Payload) {
- Checksum = Crc32cExtendMSanCompatible(Checksum, data, size);
- }
- if (Checksum != ChecksumExpected) { // validate payload checksum
- LOG_ERROR_IC_SESSION("ICIS04", "payload checksum error");
- return ReestablishConnection(TDisconnectReason::ChecksumError());
- }
- }
- if (Y_UNLIKELY(IgnorePayload)) {
- return;
- }
- if (!Context->AdvanceLastProcessedPacketSerial()) {
- return DestroySession(TDisconnectReason::NewSession());
- }
-
- while (Payload && Socket) {
- // extract channel part header from the payload stream
- TChannelPart part;
- if (!Payload.ExtractFrontPlain(&part, sizeof(part))) {
- LOG_CRIT_IC_SESSION("ICIS14", "missing TChannelPart header in payload");
- return DestroySession(TDisconnectReason::FormatError());
- }
- if (!part.Size) { // bogus frame
- continue;
- } else if (Payload.GetSize() < part.Size) {
- LOG_CRIT_IC_SESSION("ICIS08", "payload format error ChannelPart# %s", part.ToString().data());
- return DestroySession(TDisconnectReason::FormatError());
- }
-
- const ui16 channel = part.Channel & ~TChannelPart::LastPartFlag;
- TRope *eventData = channel < Context->ChannelArray.size()
- ? &Context->ChannelArray[channel]
- : &Context->ChannelMap[channel];
-
+ HandlePingResponse(CyclesToDuration(received - sent));
+ } else if (HeaderSerial & TTcpPacketBuf::ClockMask) {
+ HandleClock(TInstant::MicroSeconds(HeaderSerial & ~TTcpPacketBuf::ClockMask));
+ }
+ }
+
+ void TInputSessionTCP::ProcessPayload(ui64& numDataBytes) {
+ const size_t numBytes = Min(PayloadSize, IncomingData.GetSize());
+ IncomingData.ExtractFront(numBytes, &Payload);
+ numDataBytes += numBytes;
+ PayloadSize -= numBytes;
+ if (PayloadSize) {
+ return; // there is still some data to receive in the Payload rope
+ }
+ State = EState::HEADER; // we'll continue with header next time
+ if (!Params.UseModernFrame || !Params.Encryption) { // see if we are checksumming packet body
+ for (const auto&& [data, size] : Payload) {
+ Checksum = Crc32cExtendMSanCompatible(Checksum, data, size);
+ }
+ if (Checksum != ChecksumExpected) { // validate payload checksum
+ LOG_ERROR_IC_SESSION("ICIS04", "payload checksum error");
+ return ReestablishConnection(TDisconnectReason::ChecksumError());
+ }
+ }
+ if (Y_UNLIKELY(IgnorePayload)) {
+ return;
+ }
+ if (!Context->AdvanceLastProcessedPacketSerial()) {
+ return DestroySession(TDisconnectReason::NewSession());
+ }
+
+ while (Payload && Socket) {
+ // extract channel part header from the payload stream
+ TChannelPart part;
+ if (!Payload.ExtractFrontPlain(&part, sizeof(part))) {
+ LOG_CRIT_IC_SESSION("ICIS14", "missing TChannelPart header in payload");
+ return DestroySession(TDisconnectReason::FormatError());
+ }
+ if (!part.Size) { // bogus frame
+ continue;
+ } else if (Payload.GetSize() < part.Size) {
+ LOG_CRIT_IC_SESSION("ICIS08", "payload format error ChannelPart# %s", part.ToString().data());
+ return DestroySession(TDisconnectReason::FormatError());
+ }
+
+ const ui16 channel = part.Channel & ~TChannelPart::LastPartFlag;
+ TRope *eventData = channel < Context->ChannelArray.size()
+ ? &Context->ChannelArray[channel]
+ : &Context->ChannelMap[channel];
+
Metrics->AddInputChannelsIncomingTraffic(channel, sizeof(part) + part.Size);
-
- TEventDescr descr;
- if (~part.Channel & TChannelPart::LastPartFlag) {
- Payload.ExtractFront(part.Size, eventData);
- } else if (part.Size != sizeof(descr)) {
- LOG_CRIT_IC_SESSION("ICIS11", "incorrect last part of an event");
- return DestroySession(TDisconnectReason::FormatError());
- } else if (Payload.ExtractFrontPlain(&descr, sizeof(descr))) {
+
+ TEventDescr descr;
+ if (~part.Channel & TChannelPart::LastPartFlag) {
+ Payload.ExtractFront(part.Size, eventData);
+ } else if (part.Size != sizeof(descr)) {
+ LOG_CRIT_IC_SESSION("ICIS11", "incorrect last part of an event");
+ return DestroySession(TDisconnectReason::FormatError());
+ } else if (Payload.ExtractFrontPlain(&descr, sizeof(descr))) {
Metrics->IncInputChannelsIncomingEvents(channel);
- ProcessEvent(*eventData, descr);
- *eventData = TRope();
- } else {
- Y_FAIL();
- }
- }
- }
-
- void TInputSessionTCP::ProcessEvent(TRope& data, TEventDescr& descr) {
- if (!Params.UseModernFrame || descr.Checksum) {
- ui32 checksum = 0;
- for (const auto&& [data, size] : data) {
- checksum = Crc32cExtendMSanCompatible(checksum, data, size);
- }
- if (checksum != descr.Checksum) {
- LOG_CRIT_IC_SESSION("ICIS05", "event checksum error");
- return ReestablishConnection(TDisconnectReason::ChecksumError());
- }
- }
- auto ev = std::make_unique<IEventHandle>(SessionId,
- descr.Type,
- descr.Flags & ~IEventHandle::FlagExtendedFormat,
- descr.Recipient,
- descr.Sender,
- MakeIntrusive<TEventSerializedData>(std::move(data), bool(descr.Flags & IEventHandle::FlagExtendedFormat)),
- descr.Cookie,
- Params.PeerScopeId,
- NWilson::TTraceId(descr.TraceId));
- if (Common->EventFilter && !Common->EventFilter->CheckIncomingEvent(*ev, Common->LocalScopeId)) {
- LOG_CRIT_IC_SESSION("ICIC03", "Event dropped due to scope error LocalScopeId# %s PeerScopeId# %s Type# 0x%08" PRIx32,
- ScopeIdToString(Common->LocalScopeId).data(), ScopeIdToString(Params.PeerScopeId).data(), descr.Type);
- ev.reset();
- }
- if (ev) {
- TActivationContext::Send(ev.release());
- }
- }
-
- void TInputSessionTCP::HandleConfirmUpdate() {
- for (;;) {
- switch (EUpdateState state = Context->UpdateState) {
- case EUpdateState::NONE:
- case EUpdateState::INFLIGHT:
- case EUpdateState::INFLIGHT_AND_PENDING:
- // here we may have a race
- return;
-
- case EUpdateState::CONFIRMING:
- Y_VERIFY(UpdateFromInputSession);
- if (Context->UpdateState.compare_exchange_weak(state, EUpdateState::INFLIGHT)) {
- Send(SessionId, UpdateFromInputSession.Release());
- return;
- }
- }
- }
- }
-
- bool TInputSessionTCP::ReadMore() {
- PreallocateBuffers();
-
- TStackVec<TIoVec, NumPreallocatedBuffers> buffs;
+ ProcessEvent(*eventData, descr);
+ *eventData = TRope();
+ } else {
+ Y_FAIL();
+ }
+ }
+ }
+
+ void TInputSessionTCP::ProcessEvent(TRope& data, TEventDescr& descr) {
+ if (!Params.UseModernFrame || descr.Checksum) {
+ ui32 checksum = 0;
+ for (const auto&& [data, size] : data) {
+ checksum = Crc32cExtendMSanCompatible(checksum, data, size);
+ }
+ if (checksum != descr.Checksum) {
+ LOG_CRIT_IC_SESSION("ICIS05", "event checksum error");
+ return ReestablishConnection(TDisconnectReason::ChecksumError());
+ }
+ }
+ auto ev = std::make_unique<IEventHandle>(SessionId,
+ descr.Type,
+ descr.Flags & ~IEventHandle::FlagExtendedFormat,
+ descr.Recipient,
+ descr.Sender,
+ MakeIntrusive<TEventSerializedData>(std::move(data), bool(descr.Flags & IEventHandle::FlagExtendedFormat)),
+ descr.Cookie,
+ Params.PeerScopeId,
+ NWilson::TTraceId(descr.TraceId));
+ if (Common->EventFilter && !Common->EventFilter->CheckIncomingEvent(*ev, Common->LocalScopeId)) {
+ LOG_CRIT_IC_SESSION("ICIC03", "Event dropped due to scope error LocalScopeId# %s PeerScopeId# %s Type# 0x%08" PRIx32,
+ ScopeIdToString(Common->LocalScopeId).data(), ScopeIdToString(Params.PeerScopeId).data(), descr.Type);
+ ev.reset();
+ }
+ if (ev) {
+ TActivationContext::Send(ev.release());
+ }
+ }
+
+ void TInputSessionTCP::HandleConfirmUpdate() {
+ for (;;) {
+ switch (EUpdateState state = Context->UpdateState) {
+ case EUpdateState::NONE:
+ case EUpdateState::INFLIGHT:
+ case EUpdateState::INFLIGHT_AND_PENDING:
+ // here we may have a race
+ return;
+
+ case EUpdateState::CONFIRMING:
+ Y_VERIFY(UpdateFromInputSession);
+ if (Context->UpdateState.compare_exchange_weak(state, EUpdateState::INFLIGHT)) {
+ Send(SessionId, UpdateFromInputSession.Release());
+ return;
+ }
+ }
+ }
+ }
+
+ bool TInputSessionTCP::ReadMore() {
+ PreallocateBuffers();
+
+ TStackVec<TIoVec, NumPreallocatedBuffers> buffs;
for (const auto& item : Buffers) {
- TIoVec iov{item->GetBuffer(), item->GetCapacity()};
- buffs.push_back(iov);
- if (Params.Encryption) {
- break; // do not put more than one buffer in queue to prevent using ReadV
- }
- }
-
+ TIoVec iov{item->GetBuffer(), item->GetCapacity()};
+ buffs.push_back(iov);
+ if (Params.Encryption) {
+ break; // do not put more than one buffer in queue to prevent using ReadV
+ }
+ }
+
const struct iovec* iovec = reinterpret_cast<const struct iovec*>(buffs.data());
- int iovcnt = buffs.size();
-
- ssize_t recvres = 0;
- TString err;
- LWPROBE_IF_TOO_LONG(SlowICReadFromSocket, ms) {
- do {
-#ifndef _win_
- recvres = iovcnt == 1 ? Socket->Recv(iovec->iov_base, iovec->iov_len, &err) : Socket->ReadV(iovec, iovcnt);
-#else
- recvres = Socket->Recv(iovec[0].iov_base, iovec[0].iov_len, &err);
-#endif
+ int iovcnt = buffs.size();
+
+ ssize_t recvres = 0;
+ TString err;
+ LWPROBE_IF_TOO_LONG(SlowICReadFromSocket, ms) {
+ do {
+#ifndef _win_
+ recvres = iovcnt == 1 ? Socket->Recv(iovec->iov_base, iovec->iov_len, &err) : Socket->ReadV(iovec, iovcnt);
+#else
+ recvres = Socket->Recv(iovec[0].iov_base, iovec[0].iov_len, &err);
+#endif
Metrics->IncRecvSyscalls();
- } while (recvres == -EINTR);
- }
-
- LOG_DEBUG_IC_SESSION("ICIS12", "ReadMore recvres# %zd iovcnt# %d err# %s", recvres, iovcnt, err.data());
-
- if (recvres <= 0 || CloseInputSessionRequested) {
- if ((-recvres != EAGAIN && -recvres != EWOULDBLOCK) || CloseInputSessionRequested) {
- TString message = CloseInputSessionRequested ? "connection closed by debug command"
- : recvres == 0 ? "connection closed by peer"
- : err ? err
- : Sprintf("socket: %s", strerror(-recvres));
+ } while (recvres == -EINTR);
+ }
+
+ LOG_DEBUG_IC_SESSION("ICIS12", "ReadMore recvres# %zd iovcnt# %d err# %s", recvres, iovcnt, err.data());
+
+ if (recvres <= 0 || CloseInputSessionRequested) {
+ if ((-recvres != EAGAIN && -recvres != EWOULDBLOCK) || CloseInputSessionRequested) {
+ TString message = CloseInputSessionRequested ? "connection closed by debug command"
+ : recvres == 0 ? "connection closed by peer"
+ : err ? err
+ : Sprintf("socket: %s", strerror(-recvres));
LOG_NOTICE_NET(NodeId, "%s", message.data());
- ReestablishConnection(CloseInputSessionRequested ? TDisconnectReason::Debug() :
- recvres == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-recvres));
- } else if (PollerToken && !std::exchange(Context->ReadPending, true)) {
- if (Params.Encryption) {
- auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
- const bool wantRead = secure->WantRead(), wantWrite = secure->WantWrite();
- Y_VERIFY_DEBUG(wantRead || wantWrite);
- PollerToken->Request(wantRead, wantWrite);
- } else {
- PollerToken->Request(true, false);
- }
- }
- return false;
- }
-
- Y_VERIFY(recvres > 0);
+ ReestablishConnection(CloseInputSessionRequested ? TDisconnectReason::Debug() :
+ recvres == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-recvres));
+ } else if (PollerToken && !std::exchange(Context->ReadPending, true)) {
+ if (Params.Encryption) {
+ auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
+ const bool wantRead = secure->WantRead(), wantWrite = secure->WantWrite();
+ Y_VERIFY_DEBUG(wantRead || wantWrite);
+ PollerToken->Request(wantRead, wantWrite);
+ } else {
+ PollerToken->Request(true, false);
+ }
+ }
+ return false;
+ }
+
+ Y_VERIFY(recvres > 0);
Metrics->AddTotalBytesRead(recvres);
- TDeque<TIntrusivePtr<TRopeAlignedBuffer>>::iterator it;
- for (it = Buffers.begin(); recvres; ++it) {
- Y_VERIFY(it != Buffers.end());
- const size_t bytesFromFrontBuffer = Min<size_t>(recvres, (*it)->GetCapacity());
- (*it)->AdjustSize(bytesFromFrontBuffer);
- IncomingData.Insert(IncomingData.End(), TRope(std::move(*it)));
- recvres -= bytesFromFrontBuffer;
- }
- Buffers.erase(Buffers.begin(), it);
-
- LastReceiveTimestamp = TActivationContext::Now();
-
- return true;
- }
-
- void TInputSessionTCP::PreallocateBuffers() {
- // ensure that we have exactly "numBuffers" in queue
- LWPROBE_IF_TOO_LONG(SlowICReadLoopAdjustSize, ms) {
- const ui32 target = Params.Encryption ? 1 : NumPreallocatedBuffers;
- while (Buffers.size() < target) {
- Buffers.emplace_back(TRopeAlignedBuffer::Allocate(sizeof(TTcpPacketBuf)));
- }
- }
- }
-
- void TInputSessionTCP::ReestablishConnection(TDisconnectReason reason) {
- LOG_DEBUG_IC_SESSION("ICIS09", "ReestablishConnection, reason# %s", reason.ToString().data());
- AtomicDecrement(Context->NumInputSessions);
- Send(SessionId, new TEvSocketDisconnect(std::move(reason)));
- PassAway();
- Socket.Reset();
- }
-
- void TInputSessionTCP::DestroySession(TDisconnectReason reason) {
- LOG_DEBUG_IC_SESSION("ICIS13", "DestroySession, reason# %s", reason.ToString().data());
- AtomicDecrement(Context->NumInputSessions);
- Send(SessionId, TInterconnectSessionTCP::NewEvTerminate(std::move(reason)));
- PassAway();
- Socket.Reset();
- }
-
- void TInputSessionTCP::HandleCheckDeadPeer() {
- const TInstant now = TActivationContext::Now();
- if (now >= LastReceiveTimestamp + DeadPeerTimeout) {
- ReceiveData();
- if (Socket && now >= LastReceiveTimestamp + DeadPeerTimeout) {
- // nothing has changed, terminate session
- DestroySession(TDisconnectReason::DeadPeer());
- }
- }
- Schedule(LastReceiveTimestamp + DeadPeerTimeout - now, new TEvCheckDeadPeer);
- }
-
- void TInputSessionTCP::HandlePingResponse(TDuration passed) {
- PingQ.push_back(passed);
- if (PingQ.size() > 16) {
- PingQ.pop_front();
- }
- const TDuration ping = *std::min_element(PingQ.begin(), PingQ.end());
+ TDeque<TIntrusivePtr<TRopeAlignedBuffer>>::iterator it;
+ for (it = Buffers.begin(); recvres; ++it) {
+ Y_VERIFY(it != Buffers.end());
+ const size_t bytesFromFrontBuffer = Min<size_t>(recvres, (*it)->GetCapacity());
+ (*it)->AdjustSize(bytesFromFrontBuffer);
+ IncomingData.Insert(IncomingData.End(), TRope(std::move(*it)));
+ recvres -= bytesFromFrontBuffer;
+ }
+ Buffers.erase(Buffers.begin(), it);
+
+ LastReceiveTimestamp = TActivationContext::Now();
+
+ return true;
+ }
+
+ void TInputSessionTCP::PreallocateBuffers() {
+ // ensure that we have exactly "numBuffers" in queue
+ LWPROBE_IF_TOO_LONG(SlowICReadLoopAdjustSize, ms) {
+ const ui32 target = Params.Encryption ? 1 : NumPreallocatedBuffers;
+ while (Buffers.size() < target) {
+ Buffers.emplace_back(TRopeAlignedBuffer::Allocate(sizeof(TTcpPacketBuf)));
+ }
+ }
+ }
+
+ void TInputSessionTCP::ReestablishConnection(TDisconnectReason reason) {
+ LOG_DEBUG_IC_SESSION("ICIS09", "ReestablishConnection, reason# %s", reason.ToString().data());
+ AtomicDecrement(Context->NumInputSessions);
+ Send(SessionId, new TEvSocketDisconnect(std::move(reason)));
+ PassAway();
+ Socket.Reset();
+ }
+
+ void TInputSessionTCP::DestroySession(TDisconnectReason reason) {
+ LOG_DEBUG_IC_SESSION("ICIS13", "DestroySession, reason# %s", reason.ToString().data());
+ AtomicDecrement(Context->NumInputSessions);
+ Send(SessionId, TInterconnectSessionTCP::NewEvTerminate(std::move(reason)));
+ PassAway();
+ Socket.Reset();
+ }
+
+ void TInputSessionTCP::HandleCheckDeadPeer() {
+ const TInstant now = TActivationContext::Now();
+ if (now >= LastReceiveTimestamp + DeadPeerTimeout) {
+ ReceiveData();
+ if (Socket && now >= LastReceiveTimestamp + DeadPeerTimeout) {
+ // nothing has changed, terminate session
+ DestroySession(TDisconnectReason::DeadPeer());
+ }
+ }
+ Schedule(LastReceiveTimestamp + DeadPeerTimeout - now, new TEvCheckDeadPeer);
+ }
+
+ void TInputSessionTCP::HandlePingResponse(TDuration passed) {
+ PingQ.push_back(passed);
+ if (PingQ.size() > 16) {
+ PingQ.pop_front();
+ }
+ const TDuration ping = *std::min_element(PingQ.begin(), PingQ.end());
const auto pingUs = ping.MicroSeconds();
Context->PingRTT_us = pingUs;
- NewPingProtocol = true;
+ NewPingProtocol = true;
Metrics->UpdateLegacyPingTimeHist(pingUs);
- }
-
- void TInputSessionTCP::HandleClock(TInstant clock) {
- const TInstant here = TInstant::Now(); // wall clock
- const TInstant remote = clock + TDuration::MicroSeconds(Context->PingRTT_us / 2);
- i64 skew = remote.MicroSeconds() - here.MicroSeconds();
- SkewQ.push_back(skew);
- if (SkewQ.size() > 16) {
- SkewQ.pop_front();
- }
- i64 clockSkew = SkewQ.front();
- for (i64 skew : SkewQ) {
- if (abs(skew) < abs(clockSkew)) {
- clockSkew = skew;
- }
- }
- Context->ClockSkew_us = clockSkew;
+ }
+
+ void TInputSessionTCP::HandleClock(TInstant clock) {
+ const TInstant here = TInstant::Now(); // wall clock
+ const TInstant remote = clock + TDuration::MicroSeconds(Context->PingRTT_us / 2);
+ i64 skew = remote.MicroSeconds() - here.MicroSeconds();
+ SkewQ.push_back(skew);
+ if (SkewQ.size() > 16) {
+ SkewQ.pop_front();
+ }
+ i64 clockSkew = SkewQ.front();
+ for (i64 skew : SkewQ) {
+ if (abs(skew) < abs(clockSkew)) {
+ clockSkew = skew;
+ }
+ }
+ Context->ClockSkew_us = clockSkew;
Metrics->SetClockSkewMicrosec(clockSkew);
- }
-
-
+ }
+
+
}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp b/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
index 7e2d8ccb948..4f8acd7c574 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
+++ b/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
@@ -1,421 +1,421 @@
-#include "interconnect_tcp_proxy.h"
-#include "interconnect_handshake.h"
-#include "interconnect_tcp_session.h"
+#include "interconnect_tcp_proxy.h"
+#include "interconnect_handshake.h"
+#include "interconnect_tcp_session.h"
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/monlib/service/pages/templates.h>
-#include <util/system/getpid.h>
-
-namespace NActors {
+#include <util/system/getpid.h>
+
+namespace NActors {
static constexpr TDuration GetNodeRequestTimeout = TDuration::Seconds(5);
-
+
static constexpr TDuration FirstErrorSleep = TDuration::MilliSeconds(10);
static constexpr TDuration MaxErrorSleep = TDuration::Seconds(10);
static constexpr ui32 SleepRetryMultiplier = 4;
-
+
static TString PeerNameForHuman(ui32 nodeNum, const TString& longName, ui16 port) {
TStringBuf token;
TStringBuf(longName).NextTok('.', token);
return ToString<ui32>(nodeNum) + ":" + (token.size() > 0 ? TString(token) : longName) + ":" + ToString<ui16>(port);
}
-
- TInterconnectProxyTCP::TInterconnectProxyTCP(const ui32 node, TInterconnectProxyCommon::TPtr common,
- IActor **dynamicPtr)
- : TActor(&TThis::StateInit)
- , PeerNodeId(node)
- , DynamicPtr(dynamicPtr)
- , Common(std::move(common))
- , SecureContext(new NInterconnect::TSecureSocketContext(Common->Settings.Certificate, Common->Settings.PrivateKey,
- Common->Settings.CaFilePath, Common->Settings.CipherList))
+
+ TInterconnectProxyTCP::TInterconnectProxyTCP(const ui32 node, TInterconnectProxyCommon::TPtr common,
+ IActor **dynamicPtr)
+ : TActor(&TThis::StateInit)
+ , PeerNodeId(node)
+ , DynamicPtr(dynamicPtr)
+ , Common(std::move(common))
+ , SecureContext(new NInterconnect::TSecureSocketContext(Common->Settings.Certificate, Common->Settings.PrivateKey,
+ Common->Settings.CaFilePath, Common->Settings.CipherList))
{
- Y_VERIFY(Common);
- Y_VERIFY(Common->NameserviceId);
- if (DynamicPtr) {
- Y_VERIFY(!*DynamicPtr);
- *DynamicPtr = this;
- }
- }
-
- void TInterconnectProxyTCP::Bootstrap() {
+ Y_VERIFY(Common);
+ Y_VERIFY(Common->NameserviceId);
+ if (DynamicPtr) {
+ Y_VERIFY(!*DynamicPtr);
+ *DynamicPtr = this;
+ }
+ }
+
+ void TInterconnectProxyTCP::Bootstrap() {
SetPrefix(Sprintf("Proxy %s [node %" PRIu32 "]", SelfId().ToString().data(), PeerNodeId));
-
- SwitchToInitialState();
- PassAwayTimestamp = TActivationContext::Now() + TDuration::Seconds(15);
-
- LOG_INFO_IC("ICP01", "ready to work");
+
+ SwitchToInitialState();
+ PassAwayTimestamp = TActivationContext::Now() + TDuration::Seconds(15);
+
+ LOG_INFO_IC("ICP01", "ready to work");
}
-
+
void TInterconnectProxyTCP::Registered(TActorSystem* sys, const TActorId& owner) {
- if (!DynamicPtr) {
- // perform usual bootstrap for static nodes
- sys->Send(new IEventHandle(TEvents::TSystem::Bootstrap, 0, SelfId(), owner, nullptr, 0));
- }
- if (const auto& mon = Common->RegisterMonPage) {
- TString path = Sprintf("peer%04" PRIu32, PeerNodeId);
- TString title = Sprintf("Peer #%04" PRIu32, PeerNodeId);
+ if (!DynamicPtr) {
+ // perform usual bootstrap for static nodes
+ sys->Send(new IEventHandle(TEvents::TSystem::Bootstrap, 0, SelfId(), owner, nullptr, 0));
+ }
+ if (const auto& mon = Common->RegisterMonPage) {
+ TString path = Sprintf("peer%04" PRIu32, PeerNodeId);
+ TString title = Sprintf("Peer #%04" PRIu32, PeerNodeId);
mon(path, title, sys, SelfId());
}
- }
-
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingActivation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TInterconnectProxyTCP::RequestNodeInfo(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
+
+ void TInterconnectProxyTCP::RequestNodeInfo(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor && !PendingIncomingHandshakeEvents && !PendingSessionEvents);
- EnqueueSessionEvent(ev);
- StartConfiguring();
- }
-
- void TInterconnectProxyTCP::RequestNodeInfoForIncomingHandshake(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- if (!Terminated) {
- Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor && !PendingIncomingHandshakeEvents && !PendingSessionEvents);
- EnqueueIncomingHandshakeEvent(ev);
- StartConfiguring();
- }
- }
-
+ EnqueueSessionEvent(ev);
+ StartConfiguring();
+ }
+
+ void TInterconnectProxyTCP::RequestNodeInfoForIncomingHandshake(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
+ if (!Terminated) {
+ Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor && !PendingIncomingHandshakeEvents && !PendingSessionEvents);
+ EnqueueIncomingHandshakeEvent(ev);
+ StartConfiguring();
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingNodeInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TInterconnectProxyTCP::StartConfiguring() {
- ICPROXY_PROFILED;
-
+
+ void TInterconnectProxyTCP::StartConfiguring() {
+ ICPROXY_PROFILED;
+
Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor);
-
+
// issue node info request
- Send(Common->NameserviceId, new TEvInterconnect::TEvGetNode(PeerNodeId));
-
+ Send(Common->NameserviceId, new TEvInterconnect::TEvGetNode(PeerNodeId));
+
// arm configure timer; store pointer to event to ensure that we will handle correct one if there were any other
// wakeup events in flight
- SwitchToState(__LINE__, "PendingNodeInfo", &TThis::PendingNodeInfo, GetNodeRequestTimeout,
+ SwitchToState(__LINE__, "PendingNodeInfo", &TThis::PendingNodeInfo, GetNodeRequestTimeout,
ConfigureTimeoutCookie = new TEvents::TEvWakeup);
}
-
- void TInterconnectProxyTCP::Configure(TEvInterconnect::TEvNodeInfo::TPtr& ev) {
- ICPROXY_PROFILED;
-
- Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor && !Session);
-
+
+ void TInterconnectProxyTCP::Configure(TEvInterconnect::TEvNodeInfo::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor && !Session);
+
if (!ev->Get()->Node) {
- TransitToErrorState("cannot get node info");
+ TransitToErrorState("cannot get node info");
} else {
auto& info = *ev->Get()->Node;
- TString name = PeerNameForHuman(PeerNodeId, info.Host, info.Port);
+ TString name = PeerNameForHuman(PeerNodeId, info.Host, info.Port);
TechnicalPeerHostName = info.Host;
if (!Metrics) {
Metrics = Common->Metrics ? CreateInterconnectMetrics(Common) : CreateInterconnectCounters(Common);
- }
+ }
Metrics->SetPeerInfo(name, info.Location.GetDataCenterId());
-
- LOG_DEBUG_IC("ICP02", "configured for host %s", name.data());
-
- ProcessConfigured();
- }
- }
-
- void TInterconnectProxyTCP::ConfigureTimeout(TEvents::TEvWakeup::TPtr& ev) {
- ICPROXY_PROFILED;
-
+
+ LOG_DEBUG_IC("ICP02", "configured for host %s", name.data());
+
+ ProcessConfigured();
+ }
+ }
+
+ void TInterconnectProxyTCP::ConfigureTimeout(TEvents::TEvWakeup::TPtr& ev) {
+ ICPROXY_PROFILED;
+
if (ev->Get() == ConfigureTimeoutCookie) {
- TransitToErrorState("timed out while waiting for node info");
- }
- }
-
- void TInterconnectProxyTCP::ProcessConfigured() {
- ICPROXY_PROFILED;
-
- // if the request was initiated by some activity involving Interconnect, then we are expected to start handshake
- if (PendingSessionEvents) {
- StartInitialHandshake();
- }
-
- // process incoming handshake requests; all failures were ejected from the queue along with the matching initiation requests
- for (THolder<IEventHandle>& ev : PendingIncomingHandshakeEvents) {
- TAutoPtr<IEventHandle> x(ev.Release());
- IncomingHandshake(x);
- }
- PendingIncomingHandshakeEvents.clear();
-
- // possible situation -- incoming handshake arrives, but actually it is not satisfied and rejected; in this case
- // we are going to return to initial state as we have nothing to do
- if (!IncomingHandshakeActor && !OutgoingHandshakeActor) {
- SwitchToInitialState();
- }
- }
-
- void TInterconnectProxyTCP::StartInitialHandshake() {
- ICPROXY_PROFILED;
-
+ TransitToErrorState("timed out while waiting for node info");
+ }
+ }
+
+ void TInterconnectProxyTCP::ProcessConfigured() {
+ ICPROXY_PROFILED;
+
+ // if the request was initiated by some activity involving Interconnect, then we are expected to start handshake
+ if (PendingSessionEvents) {
+ StartInitialHandshake();
+ }
+
+ // process incoming handshake requests; all failures were ejected from the queue along with the matching initiation requests
+ for (THolder<IEventHandle>& ev : PendingIncomingHandshakeEvents) {
+ TAutoPtr<IEventHandle> x(ev.Release());
+ IncomingHandshake(x);
+ }
+ PendingIncomingHandshakeEvents.clear();
+
+ // possible situation -- incoming handshake arrives, but actually it is not satisfied and rejected; in this case
+ // we are going to return to initial state as we have nothing to do
+ if (!IncomingHandshakeActor && !OutgoingHandshakeActor) {
+ SwitchToInitialState();
+ }
+ }
+
+ void TInterconnectProxyTCP::StartInitialHandshake() {
+ ICPROXY_PROFILED;
+
// since we are starting initial handshake for some reason, we'll drop any existing handshakes, if any
- DropHandshakes();
-
+ DropHandshakes();
+
// create and register handshake actor
- OutgoingHandshakeActor = Register(CreateOutgoingHandshakeActor(Common, GenerateSessionVirtualId(),
- TActorId(), PeerNodeId, 0, TechnicalPeerHostName, TSessionParams()), TMailboxType::ReadAsFilled);
- OutgoingHandshakeActorCreated = TActivationContext::Now();
-
- // prepare for new handshake
- PrepareNewSessionHandshake();
- }
-
- void TInterconnectProxyTCP::StartResumeHandshake(ui64 inputCounter) {
- ICPROXY_PROFILED;
-
+ OutgoingHandshakeActor = Register(CreateOutgoingHandshakeActor(Common, GenerateSessionVirtualId(),
+ TActorId(), PeerNodeId, 0, TechnicalPeerHostName, TSessionParams()), TMailboxType::ReadAsFilled);
+ OutgoingHandshakeActorCreated = TActivationContext::Now();
+
+ // prepare for new handshake
+ PrepareNewSessionHandshake();
+ }
+
+ void TInterconnectProxyTCP::StartResumeHandshake(ui64 inputCounter) {
+ ICPROXY_PROFILED;
+
// drop outgoing handshake if we have one; keep incoming handshakes as they may be useful
- DropOutgoingHandshake();
-
+ DropOutgoingHandshake();
+
// ensure that we have session
Y_VERIFY(Session);
-
+
// ensure that we have both virtual ids
Y_VERIFY(SessionVirtualId);
Y_VERIFY(RemoteSessionVirtualId);
-
+
// create and register handshake actor
- OutgoingHandshakeActor = Register(CreateOutgoingHandshakeActor(Common, SessionVirtualId,
- RemoteSessionVirtualId, PeerNodeId, inputCounter, TechnicalPeerHostName, Session->Params),
- TMailboxType::ReadAsFilled);
- OutgoingHandshakeActorCreated = TActivationContext::Now();
- }
-
- void TInterconnectProxyTCP::IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId,
- THolder<IEventBase> event) {
- ICPROXY_PROFILED;
-
+ OutgoingHandshakeActor = Register(CreateOutgoingHandshakeActor(Common, SessionVirtualId,
+ RemoteSessionVirtualId, PeerNodeId, inputCounter, TechnicalPeerHostName, Session->Params),
+ TMailboxType::ReadAsFilled);
+ OutgoingHandshakeActorCreated = TActivationContext::Now();
+ }
+
+ void TInterconnectProxyTCP::IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId,
+ THolder<IEventBase> event) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(!IncomingHandshakeActor);
IncomingHandshakeActor = handshakeId;
- IncomingHandshakeActorFilledIn = TActivationContext::Now();
- Y_VERIFY(!LastSerialFromIncomingHandshake || *LastSerialFromIncomingHandshake <= peerLocalId);
- LastSerialFromIncomingHandshake = peerLocalId;
-
- if (OutgoingHandshakeActor && SelfId().NodeId() < PeerNodeId) {
+ IncomingHandshakeActorFilledIn = TActivationContext::Now();
+ Y_VERIFY(!LastSerialFromIncomingHandshake || *LastSerialFromIncomingHandshake <= peerLocalId);
+ LastSerialFromIncomingHandshake = peerLocalId;
+
+ if (OutgoingHandshakeActor && SelfId().NodeId() < PeerNodeId) {
// Both outgoing and incoming handshake are in progress. To prevent race condition during semultanous handshake
// incoming handshake must be held till outgoing handshake is complete or failed
LOG_DEBUG_IC("ICP06", "reply for incoming handshake (actor %s) is held", IncomingHandshakeActor.ToString().data());
HeldHandshakeReply = std::move(event);
-
+
// Check that we are in one of acceptable states that would properly handle handshake statuses.
const auto state = CurrentStateFunc();
Y_VERIFY(state == &TThis::PendingConnection || state == &TThis::StateWork, "invalid handshake request in state# %s", State);
} else {
LOG_DEBUG_IC("ICP07", "issued incoming handshake reply");
-
+
// No race, so we can send reply immediately.
Y_VERIFY(!HeldHandshakeReply);
- Send(IncomingHandshakeActor, event.Release());
-
+ Send(IncomingHandshakeActor, event.Release());
+
// Start waiting for handshake reply, if not yet started; also, if session is already created, then we don't
// switch from working state.
if (!Session) {
- LOG_INFO_IC("ICP08", "No active sessions, becoming PendingConnection");
- SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection);
+ LOG_INFO_IC("ICP08", "No active sessions, becoming PendingConnection");
+ SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection);
} else {
Y_VERIFY(CurrentStateFunc() == &TThis::StateWork);
}
- }
- }
-
- void TInterconnectProxyTCP::IncomingHandshake(TEvHandshakeAsk::TPtr& ev) {
- ICPROXY_PROFILED;
-
- TEvHandshakeAsk *msg = ev->Get();
-
- // TEvHandshakeAsk is only applicable for continuation requests
+ }
+ }
+
+ void TInterconnectProxyTCP::IncomingHandshake(TEvHandshakeAsk::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ TEvHandshakeAsk *msg = ev->Get();
+
+ // TEvHandshakeAsk is only applicable for continuation requests
LOG_DEBUG_IC("ICP09", "(actor %s) from: %s for: %s", ev->Sender.ToString().data(),
ev->Get()->Self.ToString().data(), ev->Get()->Peer.ToString().data());
-
- if (!Session) {
- // if there is no open session, report error -- continuation request works only with open sessions
- LOG_NOTICE_IC("ICP12", "(actor %s) peer tries to resume nonexistent session Self# %s Peer# %s",
+
+ if (!Session) {
+ // if there is no open session, report error -- continuation request works only with open sessions
+ LOG_NOTICE_IC("ICP12", "(actor %s) peer tries to resume nonexistent session Self# %s Peer# %s",
ev->Sender.ToString().data(), msg->Self.ToString().data(), msg->Peer.ToString().data());
- } else if (SessionVirtualId != ev->Get()->Peer || RemoteSessionVirtualId != ev->Get()->Self) {
- // check session virtual ids for continuation
- LOG_NOTICE_IC("ICP13", "(actor %s) virtual id mismatch with existing session (Peer: %s Self: %s"
+ } else if (SessionVirtualId != ev->Get()->Peer || RemoteSessionVirtualId != ev->Get()->Self) {
+ // check session virtual ids for continuation
+ LOG_NOTICE_IC("ICP13", "(actor %s) virtual id mismatch with existing session (Peer: %s Self: %s"
" SessionVirtualId: %s RemoteSessionVirtualId: %s)", ev->Sender.ToString().data(),
ev->Get()->Peer.ToString().data(), ev->Get()->Self.ToString().data(), SessionVirtualId.ToString().data(),
RemoteSessionVirtualId.ToString().data());
- } else {
- // if we already have incoming handshake, then terminate existing one
- DropIncomingHandshake();
+ } else {
+ // if we already have incoming handshake, then terminate existing one
+ DropIncomingHandshake();
// issue reply to the sender, possibly holding it while outgoing handshake is at race
- THolder<IEventBase> reply = IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::ProcessHandshakeRequest, ev);
- return IssueIncomingHandshakeReply(ev->Sender, RemoteSessionVirtualId.LocalId(), std::move(reply));
- }
-
- // error case -- report error to the handshake actor
- Send(ev->Sender, new TEvHandshakeNak);
- }
-
- void TInterconnectProxyTCP::IncomingHandshake(TEvHandshakeRequest::TPtr& ev) {
- ICPROXY_PROFILED;
-
+ THolder<IEventBase> reply = IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::ProcessHandshakeRequest, ev);
+ return IssueIncomingHandshakeReply(ev->Sender, RemoteSessionVirtualId.LocalId(), std::move(reply));
+ }
+
+ // error case -- report error to the handshake actor
+ Send(ev->Sender, new TEvHandshakeNak);
+ }
+
+ void TInterconnectProxyTCP::IncomingHandshake(TEvHandshakeRequest::TPtr& ev) {
+ ICPROXY_PROFILED;
+
LOG_DEBUG_IC("ICP17", "incoming handshake (actor %s)", ev->Sender.ToString().data());
-
- const auto& record = ev->Get()->Record;
- ui64 remotePID = record.GetProgramPID();
- ui64 remoteStartTime = record.GetProgramStartTime();
- ui64 remoteSerial = record.GetSerial();
-
+
+ const auto& record = ev->Get()->Record;
+ ui64 remotePID = record.GetProgramPID();
+ ui64 remoteStartTime = record.GetProgramStartTime();
+ ui64 remoteSerial = record.GetSerial();
+
if (RemoteProgramInfo && remotePID == RemoteProgramInfo->PID && remoteStartTime == RemoteProgramInfo->StartTime) {
if (remoteSerial < RemoteProgramInfo->Serial) {
LOG_INFO_IC("ICP18", "handshake (actor %s) is too old", ev->Sender.ToString().data());
- Send(ev->Sender, new TEvents::TEvPoisonPill);
+ Send(ev->Sender, new TEvents::TEvPoisonPill);
return;
} else {
RemoteProgramInfo->Serial = remoteSerial;
}
- } else {
+ } else {
const auto ptr = new TProgramInfo;
ptr->PID = remotePID;
ptr->StartTime = remoteStartTime;
ptr->Serial = remoteSerial;
RemoteProgramInfo.Reset(ptr);
- }
-
+ }
+
/* Let's check peer technical hostname */
- if (record.HasSenderHostName() && TechnicalPeerHostName != record.GetSenderHostName()) {
- Send(ev->Sender, new TEvHandshakeReplyError("host name mismatch"));
+ if (record.HasSenderHostName() && TechnicalPeerHostName != record.GetSenderHostName()) {
+ Send(ev->Sender, new TEvHandshakeReplyError("host name mismatch"));
return;
}
-
- // check sender actor id and check if it is not very old
- if (LastSerialFromIncomingHandshake) {
- const ui64 serial = record.GetSerial();
- if (serial < *LastSerialFromIncomingHandshake) {
- LOG_NOTICE_IC("ICP15", "Handshake# %s has duplicate serial# %" PRIu64
+
+ // check sender actor id and check if it is not very old
+ if (LastSerialFromIncomingHandshake) {
+ const ui64 serial = record.GetSerial();
+ if (serial < *LastSerialFromIncomingHandshake) {
+ LOG_NOTICE_IC("ICP15", "Handshake# %s has duplicate serial# %" PRIu64
" LastSerialFromIncomingHandshake# %" PRIu64, ev->Sender.ToString().data(),
- serial, *LastSerialFromIncomingHandshake);
- Send(ev->Sender, new TEvHandshakeReplyError("duplicate serial"));
- return;
- } else if (serial == *LastSerialFromIncomingHandshake) {
- LOG_NOTICE_IC("ICP15", "Handshake# %s is obsolete, serial# %" PRIu64
+ serial, *LastSerialFromIncomingHandshake);
+ Send(ev->Sender, new TEvHandshakeReplyError("duplicate serial"));
+ return;
+ } else if (serial == *LastSerialFromIncomingHandshake) {
+ LOG_NOTICE_IC("ICP15", "Handshake# %s is obsolete, serial# %" PRIu64
" LastSerialFromIncomingHandshake# %" PRIu64, ev->Sender.ToString().data(),
- serial, *LastSerialFromIncomingHandshake);
- Send(ev->Sender, new TEvents::TEvPoisonPill);
- return;
- }
- }
-
+ serial, *LastSerialFromIncomingHandshake);
+ Send(ev->Sender, new TEvents::TEvPoisonPill);
+ return;
+ }
+ }
+
// drop incoming handshake as this is definitely more recent
- DropIncomingHandshake();
-
+ DropIncomingHandshake();
+
// prepare for new session
- PrepareNewSessionHandshake();
-
+ PrepareNewSessionHandshake();
+
auto event = MakeHolder<TEvHandshakeReplyOK>();
auto* pb = event->Record.MutableSuccess();
const TActorId virtualId = GenerateSessionVirtualId();
pb->SetProtocol(INTERCONNECT_PROTOCOL_VERSION);
pb->SetSenderActorId(virtualId.ToString());
pb->SetProgramPID(GetPID());
- pb->SetProgramStartTime(Common->StartTime);
+ pb->SetProgramStartTime(Common->StartTime);
pb->SetSerial(virtualId.LocalId());
-
- IssueIncomingHandshakeReply(ev->Sender, 0, std::move(event));
- }
-
- void TInterconnectProxyTCP::HandleHandshakeStatus(TEvHandshakeDone::TPtr& ev) {
- ICPROXY_PROFILED;
-
- TEvHandshakeDone *msg = ev->Get();
-
+
+ IssueIncomingHandshakeReply(ev->Sender, 0, std::move(event));
+ }
+
+ void TInterconnectProxyTCP::HandleHandshakeStatus(TEvHandshakeDone::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ TEvHandshakeDone *msg = ev->Get();
+
// Terminate handshake actor working in opposite direction, if set up.
if (ev->Sender == IncomingHandshakeActor) {
LOG_INFO_IC("ICP19", "incoming handshake succeeded");
- DropIncomingHandshake(false);
- DropOutgoingHandshake();
+ DropIncomingHandshake(false);
+ DropOutgoingHandshake();
} else if (ev->Sender == OutgoingHandshakeActor) {
LOG_INFO_IC("ICP20", "outgoing handshake succeeded");
- DropIncomingHandshake();
- DropOutgoingHandshake(false);
+ DropIncomingHandshake();
+ DropOutgoingHandshake(false);
} else {
- /* It seems to be an old handshake. */
+ /* It seems to be an old handshake. */
return;
- }
-
+ }
+
Y_VERIFY(!IncomingHandshakeActor && !OutgoingHandshakeActor);
- SwitchToState(__LINE__, "StateWork", &TThis::StateWork);
-
+ SwitchToState(__LINE__, "StateWork", &TThis::StateWork);
+
if (Session) {
- // this is continuation request, check that virtual ids match
- Y_VERIFY(SessionVirtualId == msg->Self && RemoteSessionVirtualId == msg->Peer);
+ // this is continuation request, check that virtual ids match
+ Y_VERIFY(SessionVirtualId == msg->Self && RemoteSessionVirtualId == msg->Peer);
} else {
- // this is initial request, check that we have virtual ids not filled in
- Y_VERIFY(!SessionVirtualId && !RemoteSessionVirtualId);
- }
-
- auto error = [&](const char* description) {
- TransitToErrorState(description);
- };
-
+ // this is initial request, check that we have virtual ids not filled in
+ Y_VERIFY(!SessionVirtualId && !RemoteSessionVirtualId);
+ }
+
+ auto error = [&](const char* description) {
+ TransitToErrorState(description);
+ };
+
// If session is not created, then create new one.
if (!Session) {
- RemoteProgramInfo = std::move(msg->ProgramInfo);
- if (!RemoteProgramInfo) {
- // we have received resume handshake, but session was closed concurrently while handshaking
- return error("Session continuation race");
- }
-
- // Create new session actor.
+ RemoteProgramInfo = std::move(msg->ProgramInfo);
+ if (!RemoteProgramInfo) {
+ // we have received resume handshake, but session was closed concurrently while handshaking
+ return error("Session continuation race");
+ }
+
+ // Create new session actor.
SessionID = RegisterWithSameMailbox(Session = new TInterconnectSessionTCP(this, msg->Params));
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Init);
- SessionVirtualId = msg->Self;
- RemoteSessionVirtualId = msg->Peer;
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Init);
+ SessionVirtualId = msg->Self;
+ RemoteSessionVirtualId = msg->Peer;
LOG_INFO_IC("ICP22", "created new session: %s", SessionID.ToString().data());
- }
-
- // ensure that we have session local/peer virtual ids
- Y_VERIFY(Session && SessionVirtualId && RemoteSessionVirtualId);
-
+ }
+
+ // ensure that we have session local/peer virtual ids
+ Y_VERIFY(Session && SessionVirtualId && RemoteSessionVirtualId);
+
// Set up new connection for the session.
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::SetNewConnection, ev);
-
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::SetNewConnection, ev);
+
// Reset retry timer
HoldByErrorWakeupDuration = TDuration::Zero();
-
+
/* Forward all held events */
- ProcessPendingSessionEvents();
- }
-
- void TInterconnectProxyTCP::HandleHandshakeStatus(TEvHandshakeFail::TPtr& ev) {
- ICPROXY_PROFILED;
-
- // update error state log; this fail is inconclusive unless this is the last pending handshake
- const bool inconclusive = (ev->Sender != IncomingHandshakeActor && ev->Sender != OutgoingHandshakeActor) ||
- (IncomingHandshakeActor && OutgoingHandshakeActor);
- LogHandshakeFail(ev, inconclusive);
-
+ ProcessPendingSessionEvents();
+ }
+
+ void TInterconnectProxyTCP::HandleHandshakeStatus(TEvHandshakeFail::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ // update error state log; this fail is inconclusive unless this is the last pending handshake
+ const bool inconclusive = (ev->Sender != IncomingHandshakeActor && ev->Sender != OutgoingHandshakeActor) ||
+ (IncomingHandshakeActor && OutgoingHandshakeActor);
+ LogHandshakeFail(ev, inconclusive);
+
if (ev->Sender == IncomingHandshakeActor) {
LOG_NOTICE_IC("ICP24", "incoming handshake failed, temporary: %" PRIu32 " explanation: %s outgoing: %s",
ui32(ev->Get()->Temporary), ev->Get()->Explanation.data(), OutgoingHandshakeActor.ToString().data());
- DropIncomingHandshake(false);
+ DropIncomingHandshake(false);
} else if (ev->Sender == OutgoingHandshakeActor) {
LOG_NOTICE_IC("ICP25", "outgoing handshake failed, temporary: %" PRIu32 " explanation: %s incoming: %s held: %s",
ui32(ev->Get()->Temporary), ev->Get()->Explanation.data(), IncomingHandshakeActor.ToString().data(),
HeldHandshakeReply ? "yes" : "no");
- DropOutgoingHandshake(false);
-
+ DropOutgoingHandshake(false);
+
if (IEventBase* reply = HeldHandshakeReply.Release()) {
Y_VERIFY(IncomingHandshakeActor);
LOG_DEBUG_IC("ICP26", "sent held handshake reply to %s", IncomingHandshakeActor.ToString().data());
- Send(IncomingHandshakeActor, reply);
+ Send(IncomingHandshakeActor, reply);
}
-
- // if we have no current session, then we have to drop all pending events as the outgoing handshake has failed
- ProcessPendingSessionEvents();
+
+ // if we have no current session, then we have to drop all pending events as the outgoing handshake has failed
+ ProcessPendingSessionEvents();
} else {
/* It seems to be an old fail, just ignore it */
- LOG_NOTICE_IC("ICP27", "obsolete handshake fail ignored");
+ LOG_NOTICE_IC("ICP27", "obsolete handshake fail ignored");
return;
- }
-
+ }
+
if (Metrics) {
Metrics->IncHandshakeFails();
}
@@ -425,197 +425,197 @@ namespace NActors {
LOG_DEBUG_IC("ICP28", "other handshake is still going on");
return;
}
-
+
switch (ev->Get()->Temporary) {
case TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT:
- if (!Session) {
- if (PendingSessionEvents) {
- // try to start outgoing handshake as we have some events enqueued
- StartInitialHandshake();
- } else {
- // return back to initial state as we have no session and no pending handshakes
- SwitchToInitialState();
- }
- } else if (Session->Socket) {
- // try to reestablish connection -- meaning restart handshake from the last known position
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::ReestablishConnectionWithHandshake,
- TDisconnectReason::HandshakeFailTransient());
- } else {
- // we have no active connection in that session, so just restart handshake from last known position
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::StartHandshake);
- }
+ if (!Session) {
+ if (PendingSessionEvents) {
+ // try to start outgoing handshake as we have some events enqueued
+ StartInitialHandshake();
+ } else {
+ // return back to initial state as we have no session and no pending handshakes
+ SwitchToInitialState();
+ }
+ } else if (Session->Socket) {
+ // try to reestablish connection -- meaning restart handshake from the last known position
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::ReestablishConnectionWithHandshake,
+ TDisconnectReason::HandshakeFailTransient());
+ } else {
+ // we have no active connection in that session, so just restart handshake from last known position
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::StartHandshake);
+ }
break;
case TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH:
- StartInitialHandshake();
+ StartInitialHandshake();
break;
case TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT:
TString timeExplanation = " LastSessionDieTime# " + LastSessionDieTime.ToString();
if (Session) {
- InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate,
- TDisconnectReason::HandshakeFailPermanent());
- }
+ InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate,
+ TDisconnectReason::HandshakeFailPermanent());
+ }
TransitToErrorState(ev->Get()->Explanation + timeExplanation, false);
break;
}
}
-
- void TInterconnectProxyTCP::LogHandshakeFail(TEvHandshakeFail::TPtr& ev, bool inconclusive) {
- ICPROXY_PROFILED;
-
- TString kind = "unknown";
- switch (ev->Get()->Temporary) {
- case TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT:
- kind = Session ? "transient w/session" : "transient w/o session";
- break;
-
- case TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH:
- kind = "session_mismatch";
- break;
-
- case TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT:
- kind = "permanent";
- break;
- }
- if (inconclusive) {
- kind += " inconclusive";
- }
- UpdateErrorStateLog(TActivationContext::Now(), kind, ev->Get()->Explanation);
- }
-
- void TInterconnectProxyTCP::ProcessPendingSessionEvents() {
- ICPROXY_PROFILED;
-
+
+ void TInterconnectProxyTCP::LogHandshakeFail(TEvHandshakeFail::TPtr& ev, bool inconclusive) {
+ ICPROXY_PROFILED;
+
+ TString kind = "unknown";
+ switch (ev->Get()->Temporary) {
+ case TEvHandshakeFail::HANDSHAKE_FAIL_TRANSIENT:
+ kind = Session ? "transient w/session" : "transient w/o session";
+ break;
+
+ case TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH:
+ kind = "session_mismatch";
+ break;
+
+ case TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT:
+ kind = "permanent";
+ break;
+ }
+ if (inconclusive) {
+ kind += " inconclusive";
+ }
+ UpdateErrorStateLog(TActivationContext::Now(), kind, ev->Get()->Explanation);
+ }
+
+ void TInterconnectProxyTCP::ProcessPendingSessionEvents() {
+ ICPROXY_PROFILED;
+
while (PendingSessionEvents) {
- TPendingSessionEvent ev = std::move(PendingSessionEvents.front());
- PendingSessionEventsSize -= ev.Size;
- TAutoPtr<IEventHandle> event(ev.Event.Release());
+ TPendingSessionEvent ev = std::move(PendingSessionEvents.front());
+ PendingSessionEventsSize -= ev.Size;
+ TAutoPtr<IEventHandle> event(ev.Event.Release());
PendingSessionEvents.pop_front();
-
- if (Session) {
- ForwardSessionEventToSession(event);
+
+ if (Session) {
+ ForwardSessionEventToSession(event);
} else {
- DropSessionEvent(event);
- }
- }
- }
-
- void TInterconnectProxyTCP::DropSessionEvent(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- ValidateEvent(ev, "DropSessionEvent");
+ DropSessionEvent(event);
+ }
+ }
+ }
+
+ void TInterconnectProxyTCP::DropSessionEvent(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
+ ValidateEvent(ev, "DropSessionEvent");
switch (ev->GetTypeRewrite()) {
case TEvInterconnect::EvForward:
if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
}
- TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
+ TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
break;
-
+
case TEvInterconnect::TEvConnectNode::EventType:
case TEvents::TEvSubscribe::EventType:
Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
break;
-
+
case TEvents::TEvUnsubscribe::EventType:
/* Do nothing */
break;
-
+
default:
Y_FAIL("Unexpected type of event in held event queue");
}
- }
-
- void TInterconnectProxyTCP::UnregisterSession(TInterconnectSessionTCP* session) {
- ICPROXY_PROFILED;
-
+ }
+
+ void TInterconnectProxyTCP::UnregisterSession(TInterconnectSessionTCP* session) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(Session && Session == session && SessionID);
-
+
LOG_INFO_IC("ICP30", "unregister session Session# %s VirtualId# %s", SessionID.ToString().data(),
SessionVirtualId.ToString().data());
-
+
Session = nullptr;
SessionID = TActorId();
-
+
// drop all pending events as we are closed
- ProcessPendingSessionEvents();
-
+ ProcessPendingSessionEvents();
+
// reset virtual ids as this session is terminated
SessionVirtualId = TActorId();
RemoteSessionVirtualId = TActorId();
-
+
if (Metrics) {
Metrics->IncSessionDeaths();
}
- LastSessionDieTime = TActivationContext::Now();
-
- if (IncomingHandshakeActor || OutgoingHandshakeActor) {
- PrepareNewSessionHandshake();
- } else {
- SwitchToInitialState();
- }
- }
-
- void TInterconnectProxyTCP::EnqueueSessionEvent(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- ValidateEvent(ev, "EnqueueSessionEvent");
- const ui32 size = ev->GetSize();
- PendingSessionEventsSize += size;
- PendingSessionEvents.emplace_back(TActivationContext::Now() + Common->Settings.MessagePendingTimeout, size, ev);
- ScheduleCleanupEventQueue();
- CleanupEventQueue();
- }
-
- void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- // enqueue handshake request
- Y_UNUSED();
+ LastSessionDieTime = TActivationContext::Now();
+
+ if (IncomingHandshakeActor || OutgoingHandshakeActor) {
+ PrepareNewSessionHandshake();
+ } else {
+ SwitchToInitialState();
+ }
+ }
+
+ void TInterconnectProxyTCP::EnqueueSessionEvent(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
+ ValidateEvent(ev, "EnqueueSessionEvent");
+ const ui32 size = ev->GetSize();
+ PendingSessionEventsSize += size;
+ PendingSessionEvents.emplace_back(TActivationContext::Now() + Common->Settings.MessagePendingTimeout, size, ev);
+ ScheduleCleanupEventQueue();
+ CleanupEventQueue();
+ }
+
+ void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
+ // enqueue handshake request
+ Y_UNUSED();
PendingIncomingHandshakeEvents.emplace_back(ev);
}
-
- void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(TEvHandshakeDone::TPtr& /*ev*/) {
- ICPROXY_PROFILED;
-
- // TEvHandshakeDone can't get into the queue, because we have to process handshake request first; this may be the
- // race with the previous handshakes, so simply ignore it
- }
-
- void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(TEvHandshakeFail::TPtr& ev) {
- ICPROXY_PROFILED;
-
- for (auto it = PendingIncomingHandshakeEvents.begin(); it != PendingIncomingHandshakeEvents.end(); ++it) {
- THolder<IEventHandle>& pendingEvent = *it;
- if (pendingEvent->Sender == ev->Sender) {
- // we have found cancellation request for the pending handshake request; so simply remove it from the
- // deque, as we are not interested in failure reason; must likely it happens because of handshake timeout
- if (pendingEvent->GetTypeRewrite() == TEvHandshakeFail::EventType) {
- TEvHandshakeFail::TPtr tmp(static_cast<TEventHandle<TEvHandshakeFail>*>(pendingEvent.Release()));
- LogHandshakeFail(tmp, true);
- }
- PendingIncomingHandshakeEvents.erase(it);
- break;
- }
- }
- }
-
- void TInterconnectProxyTCP::ForwardSessionEventToSession(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
+
+ void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(TEvHandshakeDone::TPtr& /*ev*/) {
+ ICPROXY_PROFILED;
+
+ // TEvHandshakeDone can't get into the queue, because we have to process handshake request first; this may be the
+ // race with the previous handshakes, so simply ignore it
+ }
+
+ void TInterconnectProxyTCP::EnqueueIncomingHandshakeEvent(TEvHandshakeFail::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ for (auto it = PendingIncomingHandshakeEvents.begin(); it != PendingIncomingHandshakeEvents.end(); ++it) {
+ THolder<IEventHandle>& pendingEvent = *it;
+ if (pendingEvent->Sender == ev->Sender) {
+ // we have found cancellation request for the pending handshake request; so simply remove it from the
+ // deque, as we are not interested in failure reason; must likely it happens because of handshake timeout
+ if (pendingEvent->GetTypeRewrite() == TEvHandshakeFail::EventType) {
+ TEvHandshakeFail::TPtr tmp(static_cast<TEventHandle<TEvHandshakeFail>*>(pendingEvent.Release()));
+ LogHandshakeFail(tmp, true);
+ }
+ PendingIncomingHandshakeEvents.erase(it);
+ break;
+ }
+ }
+ }
+
+ void TInterconnectProxyTCP::ForwardSessionEventToSession(STATEFN_SIG) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(Session && SessionID);
- ValidateEvent(ev, "ForwardSessionEventToSession");
- InvokeOtherActor(*Session, &TInterconnectSessionTCP::Receive, ev, TActivationContext::ActorContextFor(SessionID));
- }
-
- void TInterconnectProxyTCP::GenerateHttpInfo(NMon::TEvHttpInfo::TPtr& ev) {
- ICPROXY_PROFILED;
-
- LOG_INFO_IC("ICP31", "proxy http called");
-
+ ValidateEvent(ev, "ForwardSessionEventToSession");
+ InvokeOtherActor(*Session, &TInterconnectSessionTCP::Receive, ev, TActivationContext::ActorContextFor(SessionID));
+ }
+
+ void TInterconnectProxyTCP::GenerateHttpInfo(NMon::TEvHttpInfo::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ LOG_INFO_IC("ICP31", "proxy http called");
+
TStringStream str;
-
+
HTML(str) {
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
@@ -642,9 +642,9 @@ namespace NActors {
str << NAME; \
} \
}
-
+
TABLEBODY() {
- MON_VAR(TActivationContext::Now())
+ MON_VAR(TActivationContext::Now())
MON_VAR(SessionID)
MON_VAR(LastSessionDieTime)
MON_VAR(IncomingHandshakeActor)
@@ -655,11 +655,11 @@ namespace NActors {
MON_VAR(OutgoingHandshakeActorReset)
MON_VAR(State)
MON_VAR(StateSwitchTime)
- }
- }
- }
- }
-
+ }
+ }
+ }
+ }
+
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
str << "Error Log";
@@ -667,23 +667,23 @@ namespace NActors {
DIV_CLASS("panel-body") {
TABLE_CLASS("table") {
TABLEHEAD() {
- TABLER() {
+ TABLER() {
TABLEH() {
str << "Timestamp";
- }
+ }
TABLEH() {
str << "Elapsed";
- }
+ }
TABLEH() {
str << "Kind";
- }
+ }
TABLEH() {
str << "Explanation";
- }
- }
- }
+ }
+ }
+ }
TABLEBODY() {
- const TInstant now = TActivationContext::Now();
+ const TInstant now = TActivationContext::Now();
const TInstant barrier = now - TDuration::Minutes(1);
for (auto it = ErrorStateLog.rbegin(); it != ErrorStateLog.rend(); ++it) {
auto wrapper = [&](const auto& lambda) {
@@ -715,222 +715,222 @@ namespace NActors {
wrapper([&] {
str << std::get<2>(*it);
});
-
- ui32 rep = std::get<3>(*it);
- if (rep != 1) {
- str << " <strong>x" << rep << "</strong>";
- }
+
+ ui32 rep = std::get<3>(*it);
+ if (rep != 1) {
+ str << " <strong>x" << rep << "</strong>";
+ }
}
}
}
}
- }
- }
- }
- }
-
+ }
+ }
+ }
+ }
+
if (Session != nullptr) {
- Session->GenerateHttpInfo(str);
+ Session->GenerateHttpInfo(str);
}
- Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
- }
-
- void TInterconnectProxyTCP::TransitToErrorState(TString explanation, bool updateErrorLog) {
- ICPROXY_PROFILED;
-
+ Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ }
+
+ void TInterconnectProxyTCP::TransitToErrorState(TString explanation, bool updateErrorLog) {
+ ICPROXY_PROFILED;
+
LOG_NOTICE_IC("ICP32", "transit to hold-by-error state Explanation# %s", explanation.data());
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] error state: %s", PeerNodeId, explanation.data());
-
- if (updateErrorLog) {
- UpdateErrorStateLog(TActivationContext::Now(), "permanent conclusive", explanation);
- }
-
+ LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] error state: %s", PeerNodeId, explanation.data());
+
+ if (updateErrorLog) {
+ UpdateErrorStateLog(TActivationContext::Now(), "permanent conclusive", explanation);
+ }
+
Y_VERIFY(Session == nullptr);
Y_VERIFY(!SessionID);
-
+
// recalculate wakeup timeout -- if this is the first failure, then we sleep for default timeout; otherwise we
// sleep N times longer than the previous try, but not longer than desired number of seconds
HoldByErrorWakeupDuration = HoldByErrorWakeupDuration != TDuration::Zero()
? Min(HoldByErrorWakeupDuration * SleepRetryMultiplier, MaxErrorSleep)
: FirstErrorSleep;
-
+
// transit to required state and arm wakeup timer
- if (Terminated) {
- // switch to this state permanently
- SwitchToState(__LINE__, "HoldByError", &TThis::HoldByError);
- HoldByErrorWakeupCookie = nullptr;
- } else {
- SwitchToState(__LINE__, "HoldByError", &TThis::HoldByError, HoldByErrorWakeupDuration,
- HoldByErrorWakeupCookie = new TEvents::TEvWakeup);
- }
-
+ if (Terminated) {
+ // switch to this state permanently
+ SwitchToState(__LINE__, "HoldByError", &TThis::HoldByError);
+ HoldByErrorWakeupCookie = nullptr;
+ } else {
+ SwitchToState(__LINE__, "HoldByError", &TThis::HoldByError, HoldByErrorWakeupDuration,
+ HoldByErrorWakeupCookie = new TEvents::TEvWakeup);
+ }
+
/* Process all pending events. */
- ProcessPendingSessionEvents();
-
+ ProcessPendingSessionEvents();
+
/* Terminate handshakes */
- DropHandshakes();
-
+ DropHandshakes();
+
/* Terminate pending incoming handshake requests. */
for (auto& ev : PendingIncomingHandshakeEvents) {
- Send(ev->Sender, new TEvents::TEvPoisonPill);
- if (ev->GetTypeRewrite() == TEvHandshakeFail::EventType) {
- TEvHandshakeFail::TPtr tmp(static_cast<TEventHandle<TEvHandshakeFail>*>(ev.Release()));
- LogHandshakeFail(tmp, true);
- }
+ Send(ev->Sender, new TEvents::TEvPoisonPill);
+ if (ev->GetTypeRewrite() == TEvHandshakeFail::EventType) {
+ TEvHandshakeFail::TPtr tmp(static_cast<TEventHandle<TEvHandshakeFail>*>(ev.Release()));
+ LogHandshakeFail(tmp, true);
+ }
}
PendingIncomingHandshakeEvents.clear();
- }
-
- void TInterconnectProxyTCP::WakeupFromErrorState(TEvents::TEvWakeup::TPtr& ev) {
- ICPROXY_PROFILED;
-
- LOG_INFO_IC("ICP33", "wake up from error state");
-
+ }
+
+ void TInterconnectProxyTCP::WakeupFromErrorState(TEvents::TEvWakeup::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ LOG_INFO_IC("ICP33", "wake up from error state");
+
if (ev->Get() == HoldByErrorWakeupCookie) {
- SwitchToInitialState();
+ SwitchToInitialState();
}
- }
-
- void TInterconnectProxyTCP::Disconnect() {
- ICPROXY_PROFILED;
-
+ }
+
+ void TInterconnectProxyTCP::Disconnect() {
+ ICPROXY_PROFILED;
+
// terminate handshakes (if any)
- DropHandshakes();
-
+ DropHandshakes();
+
if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::UserRequest());
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::UserRequest());
} else {
- TransitToErrorState("forced disconnect");
+ TransitToErrorState("forced disconnect");
}
- }
-
- void TInterconnectProxyTCP::ScheduleCleanupEventQueue() {
- ICPROXY_PROFILED;
-
+ }
+
+ void TInterconnectProxyTCP::ScheduleCleanupEventQueue() {
+ ICPROXY_PROFILED;
+
if (!CleanupEventQueueScheduled && PendingSessionEvents) {
- // apply batching at 50 ms granularity
- Schedule(Max(TDuration::MilliSeconds(50), PendingSessionEvents.front().Deadline - TActivationContext::Now()), new TEvCleanupEventQueue);
+ // apply batching at 50 ms granularity
+ Schedule(Max(TDuration::MilliSeconds(50), PendingSessionEvents.front().Deadline - TActivationContext::Now()), new TEvCleanupEventQueue);
CleanupEventQueueScheduled = true;
}
- }
-
- void TInterconnectProxyTCP::HandleCleanupEventQueue() {
- ICPROXY_PROFILED;
-
+ }
+
+ void TInterconnectProxyTCP::HandleCleanupEventQueue() {
+ ICPROXY_PROFILED;
+
Y_VERIFY(CleanupEventQueueScheduled);
CleanupEventQueueScheduled = false;
- CleanupEventQueue();
- ScheduleCleanupEventQueue();
- }
-
- void TInterconnectProxyTCP::CleanupEventQueue() {
- ICPROXY_PROFILED;
-
- const TInstant now = TActivationContext::Now();
- while (PendingSessionEvents) {
- TPendingSessionEvent& ev = PendingSessionEvents.front();
- if (now >= ev.Deadline || PendingSessionEventsSize > Common->Settings.MessagePendingSize) {
- TAutoPtr<IEventHandle> event(ev.Event.Release());
- PendingSessionEventsSize -= ev.Size;
- DropSessionEvent(event);
- PendingSessionEvents.pop_front();
- } else {
- break;
- }
- }
- }
-
- void TInterconnectProxyTCP::HandleClosePeerSocket() {
- ICPROXY_PROFILED;
-
+ CleanupEventQueue();
+ ScheduleCleanupEventQueue();
+ }
+
+ void TInterconnectProxyTCP::CleanupEventQueue() {
+ ICPROXY_PROFILED;
+
+ const TInstant now = TActivationContext::Now();
+ while (PendingSessionEvents) {
+ TPendingSessionEvent& ev = PendingSessionEvents.front();
+ if (now >= ev.Deadline || PendingSessionEventsSize > Common->Settings.MessagePendingSize) {
+ TAutoPtr<IEventHandle> event(ev.Event.Release());
+ PendingSessionEventsSize -= ev.Size;
+ DropSessionEvent(event);
+ PendingSessionEvents.pop_front();
+ } else {
+ break;
+ }
+ }
+ }
+
+ void TInterconnectProxyTCP::HandleClosePeerSocket() {
+ ICPROXY_PROFILED;
+
if (Session && Session->Socket) {
- LOG_INFO_IC("ICP34", "closed connection by debug command");
+ LOG_INFO_IC("ICP34", "closed connection by debug command");
Session->Socket->Shutdown(SHUT_RDWR);
}
- }
-
- void TInterconnectProxyTCP::HandleCloseInputSession() {
- ICPROXY_PROFILED;
-
- if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::CloseInputSession);
- }
- }
-
- void TInterconnectProxyTCP::HandlePoisonSession() {
- ICPROXY_PROFILED;
-
+ }
+
+ void TInterconnectProxyTCP::HandleCloseInputSession() {
+ ICPROXY_PROFILED;
+
if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::Debug());
- }
- }
-
- void TInterconnectProxyTCP::HandleSessionBufferSizeRequest(TEvSessionBufferSizeRequest::TPtr& ev) {
- ICPROXY_PROFILED;
-
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::CloseInputSession);
+ }
+ }
+
+ void TInterconnectProxyTCP::HandlePoisonSession() {
+ ICPROXY_PROFILED;
+
+ if (Session) {
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::Debug());
+ }
+ }
+
+ void TInterconnectProxyTCP::HandleSessionBufferSizeRequest(TEvSessionBufferSizeRequest::TPtr& ev) {
+ ICPROXY_PROFILED;
+
ui64 bufSize = 0;
if (Session) {
bufSize = Session->TotalOutputQueueSize;
}
- Send(ev->Sender, new TEvSessionBufferSizeResponse(SessionID, bufSize));
- }
-
- void TInterconnectProxyTCP::Handle(TEvQueryStats::TPtr& ev) {
- ICPROXY_PROFILED;
-
- TProxyStats stats;
- stats.Path = Sprintf("peer%04" PRIu32, PeerNodeId);
- stats.State = State;
- stats.PeerScopeId = Session ? Session->Params.PeerScopeId : TScopeId();
- stats.LastSessionDieTime = LastSessionDieTime;
- stats.TotalOutputQueueSize = Session ? Session->TotalOutputQueueSize : 0;
- stats.Connected = Session ? (bool)Session->Socket : false;
- stats.Host = TechnicalPeerHostName;
- stats.Port = 0;
- ui32 rep = 0;
- std::tie(stats.LastErrorTimestamp, stats.LastErrorKind, stats.LastErrorExplanation, rep) = ErrorStateLog
- ? ErrorStateLog.back()
- : std::make_tuple(TInstant(), TString(), TString(), 1U);
- if (rep != 1) {
- stats.LastErrorExplanation += Sprintf(" x%" PRIu32, rep);
- }
- stats.Ping = Session ? Session->GetPingRTT() : TDuration::Zero();
- stats.ClockSkew = Session ? Session->GetClockSkew() : 0;
- if (Session) {
- if (auto *x = dynamic_cast<NInterconnect::TSecureSocket*>(Session->Socket.Get())) {
- stats.Encryption = Sprintf("%s/%u", x->GetCipherName().data(), x->GetCipherBits());
- } else {
- stats.Encryption = "none";
- }
- }
-
- auto response = MakeHolder<TEvStats>();
- response->PeerNodeId = PeerNodeId;
- response->ProxyStats = std::move(stats);
- Send(ev->Sender, response.Release());
- }
-
- void TInterconnectProxyTCP::HandleTerminate() {
- ICPROXY_PROFILED;
-
- if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason());
- }
- Terminated = true;
- TransitToErrorState("terminated");
- }
-
- void TInterconnectProxyTCP::PassAway() {
- if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason());
- }
- if (DynamicPtr) {
- Y_VERIFY(*DynamicPtr == this);
- *DynamicPtr = nullptr;
- }
- // TODO: unregister actor mon page
- TActor::PassAway();
- }
-}
+ Send(ev->Sender, new TEvSessionBufferSizeResponse(SessionID, bufSize));
+ }
+
+ void TInterconnectProxyTCP::Handle(TEvQueryStats::TPtr& ev) {
+ ICPROXY_PROFILED;
+
+ TProxyStats stats;
+ stats.Path = Sprintf("peer%04" PRIu32, PeerNodeId);
+ stats.State = State;
+ stats.PeerScopeId = Session ? Session->Params.PeerScopeId : TScopeId();
+ stats.LastSessionDieTime = LastSessionDieTime;
+ stats.TotalOutputQueueSize = Session ? Session->TotalOutputQueueSize : 0;
+ stats.Connected = Session ? (bool)Session->Socket : false;
+ stats.Host = TechnicalPeerHostName;
+ stats.Port = 0;
+ ui32 rep = 0;
+ std::tie(stats.LastErrorTimestamp, stats.LastErrorKind, stats.LastErrorExplanation, rep) = ErrorStateLog
+ ? ErrorStateLog.back()
+ : std::make_tuple(TInstant(), TString(), TString(), 1U);
+ if (rep != 1) {
+ stats.LastErrorExplanation += Sprintf(" x%" PRIu32, rep);
+ }
+ stats.Ping = Session ? Session->GetPingRTT() : TDuration::Zero();
+ stats.ClockSkew = Session ? Session->GetClockSkew() : 0;
+ if (Session) {
+ if (auto *x = dynamic_cast<NInterconnect::TSecureSocket*>(Session->Socket.Get())) {
+ stats.Encryption = Sprintf("%s/%u", x->GetCipherName().data(), x->GetCipherBits());
+ } else {
+ stats.Encryption = "none";
+ }
+ }
+
+ auto response = MakeHolder<TEvStats>();
+ response->PeerNodeId = PeerNodeId;
+ response->ProxyStats = std::move(stats);
+ Send(ev->Sender, response.Release());
+ }
+
+ void TInterconnectProxyTCP::HandleTerminate() {
+ ICPROXY_PROFILED;
+
+ if (Session) {
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason());
+ }
+ Terminated = true;
+ TransitToErrorState("terminated");
+ }
+
+ void TInterconnectProxyTCP::PassAway() {
+ if (Session) {
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason());
+ }
+ if (DynamicPtr) {
+ Y_VERIFY(*DynamicPtr == this);
+ *DynamicPtr = nullptr;
+ }
+ // TODO: unregister actor mon page
+ TActor::PassAway();
+ }
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_proxy.h b/library/cpp/actors/interconnect/interconnect_tcp_proxy.h
index 023e5bd1eee..729122f0f04 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.h
+++ b/library/cpp/actors/interconnect/interconnect_tcp_proxy.h
@@ -1,208 +1,208 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/core/events.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-#include "interconnect_common.h"
-#include "interconnect_counters.h"
-#include "interconnect_tcp_session.h"
-#include "profiler.h"
-
-#define ICPROXY_PROFILED TFunction func(*this, __func__, __LINE__)
-
-namespace NActors {
-
-
+
+#include "interconnect_common.h"
+#include "interconnect_counters.h"
+#include "interconnect_tcp_session.h"
+#include "profiler.h"
+
+#define ICPROXY_PROFILED TFunction func(*this, __func__, __LINE__)
+
+namespace NActors {
+
+
/* WARNING: all proxy actors should be alive during actorsystem activity */
- class TInterconnectProxyTCP
- : public TActor<TInterconnectProxyTCP>
- , public TInterconnectLoggingBase
- , public TProfiled
- {
+ class TInterconnectProxyTCP
+ : public TActor<TInterconnectProxyTCP>
+ , public TInterconnectLoggingBase
+ , public TProfiled
+ {
enum {
EvCleanupEventQueue = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvQueryStats,
- EvStats,
- EvPassAwayIfNeeded,
+ EvQueryStats,
+ EvStats,
+ EvPassAwayIfNeeded,
};
-
+
struct TEvCleanupEventQueue : TEventLocal<TEvCleanupEventQueue, EvCleanupEventQueue> {};
-
+
public:
- struct TEvQueryStats : TEventLocal<TEvQueryStats, EvQueryStats> {};
-
- struct TProxyStats {
- TString Path;
- TString State;
- TScopeId PeerScopeId;
- TInstant LastSessionDieTime;
- ui64 TotalOutputQueueSize;
- bool Connected;
- TString Host;
- ui16 Port;
- TInstant LastErrorTimestamp;
- TString LastErrorKind;
- TString LastErrorExplanation;
- TDuration Ping;
- i64 ClockSkew;
- TString Encryption;
- };
-
- struct TEvStats : TEventLocal<TEvStats, EvStats> {
- ui32 PeerNodeId;
- TProxyStats ProxyStats;
- };
-
+ struct TEvQueryStats : TEventLocal<TEvQueryStats, EvQueryStats> {};
+
+ struct TProxyStats {
+ TString Path;
+ TString State;
+ TScopeId PeerScopeId;
+ TInstant LastSessionDieTime;
+ ui64 TotalOutputQueueSize;
+ bool Connected;
+ TString Host;
+ ui16 Port;
+ TInstant LastErrorTimestamp;
+ TString LastErrorKind;
+ TString LastErrorExplanation;
+ TDuration Ping;
+ i64 ClockSkew;
+ TString Encryption;
+ };
+
+ struct TEvStats : TEventLocal<TEvStats, EvStats> {
+ ui32 PeerNodeId;
+ TProxyStats ProxyStats;
+ };
+
static constexpr EActivityType ActorActivityType() {
return INTERCONNECT_PROXY_TCP;
}
-
- TInterconnectProxyTCP(const ui32 node, TInterconnectProxyCommon::TPtr common, IActor **dynamicPtr = nullptr);
-
- STFUNC(StateInit) {
- Bootstrap();
- if (ev->Type != TEvents::TSystem::Bootstrap) { // for dynamic nodes we do not receive Bootstrap event
- Receive(ev, ctx);
- }
- }
-
- void Bootstrap();
+
+ TInterconnectProxyTCP(const ui32 node, TInterconnectProxyCommon::TPtr common, IActor **dynamicPtr = nullptr);
+
+ STFUNC(StateInit) {
+ Bootstrap();
+ if (ev->Type != TEvents::TSystem::Bootstrap) { // for dynamic nodes we do not receive Bootstrap event
+ Receive(ev, ctx);
+ }
+ }
+
+ void Bootstrap();
void Registered(TActorSystem* sys, const TActorId& owner) override;
-
+
private:
friend class TInterconnectSessionTCP;
friend class TInterconnectSessionTCPv0;
friend class THandshake;
friend class TInputSessionTCP;
-
- void UnregisterSession(TInterconnectSessionTCP* session);
-
-#define SESSION_EVENTS(HANDLER) \
- fFunc(TEvInterconnect::EvForward, HANDLER) \
- fFunc(TEvInterconnect::TEvConnectNode::EventType, HANDLER) \
- fFunc(TEvents::TEvSubscribe::EventType, HANDLER) \
- fFunc(TEvents::TEvUnsubscribe::EventType, HANDLER)
-
-#define INCOMING_HANDSHAKE_EVENTS(HANDLER) \
- fFunc(TEvHandshakeAsk::EventType, HANDLER) \
- fFunc(TEvHandshakeRequest::EventType, HANDLER)
-
-#define HANDSHAKE_STATUS_EVENTS(HANDLER) \
- hFunc(TEvHandshakeDone, HANDLER) \
- hFunc(TEvHandshakeFail, HANDLER)
-
-#define PROXY_STFUNC(STATE, SESSION_HANDLER, INCOMING_HANDSHAKE_HANDLER, \
- HANDSHAKE_STATUS_HANDLER, DISCONNECT_HANDLER, \
- WAKEUP_HANDLER, NODE_INFO_HANDLER) \
- STATEFN(STATE) { \
- const ui32 type = ev->GetTypeRewrite(); \
- const bool profiled = type != TEvInterconnect::EvForward \
- && type != TEvInterconnect::EvConnectNode \
- && type != TEvents::TSystem::Subscribe \
- && type != TEvents::TSystem::Unsubscribe; \
- if (profiled) { \
- TProfiled::Start(); \
- } \
- { \
- TProfiled::TFunction func(*this, __func__, __LINE__); \
- switch (type) { \
- SESSION_EVENTS(SESSION_HANDLER) \
- INCOMING_HANDSHAKE_EVENTS(INCOMING_HANDSHAKE_HANDLER) \
- HANDSHAKE_STATUS_EVENTS(HANDSHAKE_STATUS_HANDLER) \
- cFunc(TEvInterconnect::EvDisconnect, DISCONNECT_HANDLER) \
- hFunc(TEvents::TEvWakeup, WAKEUP_HANDLER) \
- hFunc(TEvGetSecureSocket, Handle) \
- hFunc(NMon::TEvHttpInfo, GenerateHttpInfo) \
- cFunc(EvCleanupEventQueue, HandleCleanupEventQueue) \
- hFunc(TEvInterconnect::TEvNodeInfo, NODE_INFO_HANDLER) \
- cFunc(TEvInterconnect::EvClosePeerSocket, HandleClosePeerSocket) \
- cFunc(TEvInterconnect::EvCloseInputSession, HandleCloseInputSession) \
- cFunc(TEvInterconnect::EvPoisonSession, HandlePoisonSession) \
- hFunc(TEvSessionBufferSizeRequest, HandleSessionBufferSizeRequest) \
- hFunc(TEvQueryStats, Handle) \
- cFunc(TEvInterconnect::EvTerminate, HandleTerminate) \
- cFunc(EvPassAwayIfNeeded, HandlePassAwayIfNeeded) \
- default: \
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, type); \
- } \
- } \
- if (profiled) { \
- if (TProfiled::Duration() >= TDuration::MilliSeconds(16)) { \
- const TString report = TProfiled::Format(); \
- LOG_ERROR_IC("ICP35", "event processing took too much time %s", report.data()); \
- } \
- TProfiled::Finish(); \
- } \
- }
-
+
+ void UnregisterSession(TInterconnectSessionTCP* session);
+
+#define SESSION_EVENTS(HANDLER) \
+ fFunc(TEvInterconnect::EvForward, HANDLER) \
+ fFunc(TEvInterconnect::TEvConnectNode::EventType, HANDLER) \
+ fFunc(TEvents::TEvSubscribe::EventType, HANDLER) \
+ fFunc(TEvents::TEvUnsubscribe::EventType, HANDLER)
+
+#define INCOMING_HANDSHAKE_EVENTS(HANDLER) \
+ fFunc(TEvHandshakeAsk::EventType, HANDLER) \
+ fFunc(TEvHandshakeRequest::EventType, HANDLER)
+
+#define HANDSHAKE_STATUS_EVENTS(HANDLER) \
+ hFunc(TEvHandshakeDone, HANDLER) \
+ hFunc(TEvHandshakeFail, HANDLER)
+
+#define PROXY_STFUNC(STATE, SESSION_HANDLER, INCOMING_HANDSHAKE_HANDLER, \
+ HANDSHAKE_STATUS_HANDLER, DISCONNECT_HANDLER, \
+ WAKEUP_HANDLER, NODE_INFO_HANDLER) \
+ STATEFN(STATE) { \
+ const ui32 type = ev->GetTypeRewrite(); \
+ const bool profiled = type != TEvInterconnect::EvForward \
+ && type != TEvInterconnect::EvConnectNode \
+ && type != TEvents::TSystem::Subscribe \
+ && type != TEvents::TSystem::Unsubscribe; \
+ if (profiled) { \
+ TProfiled::Start(); \
+ } \
+ { \
+ TProfiled::TFunction func(*this, __func__, __LINE__); \
+ switch (type) { \
+ SESSION_EVENTS(SESSION_HANDLER) \
+ INCOMING_HANDSHAKE_EVENTS(INCOMING_HANDSHAKE_HANDLER) \
+ HANDSHAKE_STATUS_EVENTS(HANDSHAKE_STATUS_HANDLER) \
+ cFunc(TEvInterconnect::EvDisconnect, DISCONNECT_HANDLER) \
+ hFunc(TEvents::TEvWakeup, WAKEUP_HANDLER) \
+ hFunc(TEvGetSecureSocket, Handle) \
+ hFunc(NMon::TEvHttpInfo, GenerateHttpInfo) \
+ cFunc(EvCleanupEventQueue, HandleCleanupEventQueue) \
+ hFunc(TEvInterconnect::TEvNodeInfo, NODE_INFO_HANDLER) \
+ cFunc(TEvInterconnect::EvClosePeerSocket, HandleClosePeerSocket) \
+ cFunc(TEvInterconnect::EvCloseInputSession, HandleCloseInputSession) \
+ cFunc(TEvInterconnect::EvPoisonSession, HandlePoisonSession) \
+ hFunc(TEvSessionBufferSizeRequest, HandleSessionBufferSizeRequest) \
+ hFunc(TEvQueryStats, Handle) \
+ cFunc(TEvInterconnect::EvTerminate, HandleTerminate) \
+ cFunc(EvPassAwayIfNeeded, HandlePassAwayIfNeeded) \
+ default: \
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, type); \
+ } \
+ } \
+ if (profiled) { \
+ if (TProfiled::Duration() >= TDuration::MilliSeconds(16)) { \
+ const TString report = TProfiled::Format(); \
+ LOG_ERROR_IC("ICP35", "event processing took too much time %s", report.data()); \
+ } \
+ TProfiled::Finish(); \
+ } \
+ }
+
template <typename T>
- void Ignore(T& /*ev*/) {
- ICPROXY_PROFILED;
+ void Ignore(T& /*ev*/) {
+ ICPROXY_PROFILED;
}
-
- void Ignore() {
- ICPROXY_PROFILED;
+
+ void Ignore() {
+ ICPROXY_PROFILED;
}
-
- void Ignore(TEvHandshakeDone::TPtr& ev) {
- ICPROXY_PROFILED;
-
+
+ void Ignore(TEvHandshakeDone::TPtr& ev) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(ev->Sender != IncomingHandshakeActor);
Y_VERIFY(ev->Sender != OutgoingHandshakeActor);
}
-
- void Ignore(TEvHandshakeFail::TPtr& ev) {
- ICPROXY_PROFILED;
-
+
+ void Ignore(TEvHandshakeFail::TPtr& ev) {
+ ICPROXY_PROFILED;
+
Y_VERIFY(ev->Sender != IncomingHandshakeActor);
Y_VERIFY(ev->Sender != OutgoingHandshakeActor);
- LogHandshakeFail(ev, true);
+ LogHandshakeFail(ev, true);
}
-
+
const char* State = nullptr;
TInstant StateSwitchTime;
-
+
template <typename... TArgs>
- void SwitchToState(int line, const char* name, TArgs&&... args) {
- ICPROXY_PROFILED;
-
- LOG_DEBUG_IC("ICP77", "@%d %s -> %s", line, State, name);
+ void SwitchToState(int line, const char* name, TArgs&&... args) {
+ ICPROXY_PROFILED;
+
+ LOG_DEBUG_IC("ICP77", "@%d %s -> %s", line, State, name);
State = name;
- StateSwitchTime = TActivationContext::Now();
+ StateSwitchTime = TActivationContext::Now();
Become(std::forward<TArgs>(args)...);
- Y_VERIFY(!Terminated || CurrentStateFunc() == &TThis::HoldByError); // ensure we never escape this state
- if (CurrentStateFunc() != &TThis::PendingActivation) {
- PassAwayTimestamp = TInstant::Max();
- }
+ Y_VERIFY(!Terminated || CurrentStateFunc() == &TThis::HoldByError); // ensure we never escape this state
+ if (CurrentStateFunc() != &TThis::PendingActivation) {
+ PassAwayTimestamp = TInstant::Max();
+ }
}
-
- TInstant PassAwayTimestamp;
- bool PassAwayScheduled = false;
-
- void SwitchToInitialState() {
- ICPROXY_PROFILED;
-
- Y_VERIFY(!PendingSessionEvents && !PendingIncomingHandshakeEvents, "%s PendingSessionEvents# %zu"
+
+ TInstant PassAwayTimestamp;
+ bool PassAwayScheduled = false;
+
+ void SwitchToInitialState() {
+ ICPROXY_PROFILED;
+
+ Y_VERIFY(!PendingSessionEvents && !PendingIncomingHandshakeEvents, "%s PendingSessionEvents# %zu"
" PendingIncomingHandshakeEvents# %zu State# %s", LogPrefix.data(), PendingSessionEvents.size(),
- PendingIncomingHandshakeEvents.size(), State);
- SwitchToState(__LINE__, "PendingActivation", &TThis::PendingActivation);
- if (DynamicPtr && !PassAwayScheduled && PassAwayTimestamp != TInstant::Max()) {
- TActivationContext::Schedule(PassAwayTimestamp, new IEventHandle(EvPassAwayIfNeeded, 0, SelfId(),
- {}, nullptr, 0));
- PassAwayScheduled = true;
- }
+ PendingIncomingHandshakeEvents.size(), State);
+ SwitchToState(__LINE__, "PendingActivation", &TThis::PendingActivation);
+ if (DynamicPtr && !PassAwayScheduled && PassAwayTimestamp != TInstant::Max()) {
+ TActivationContext::Schedule(PassAwayTimestamp, new IEventHandle(EvPassAwayIfNeeded, 0, SelfId(),
+ {}, nullptr, 0));
+ PassAwayScheduled = true;
+ }
}
-
- void HandlePassAwayIfNeeded() {
- Y_VERIFY(PassAwayScheduled);
- if (PassAwayTimestamp != TInstant::Max()) {
- PassAway();
- }
- }
-
+
+ void HandlePassAwayIfNeeded() {
+ Y_VERIFY(PassAwayScheduled);
+ if (PassAwayTimestamp != TInstant::Max()) {
+ PassAway();
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingActivation
//
@@ -213,7 +213,7 @@ namespace NActors {
// Upon receiving such event, we put it to corresponding queue and initiate start up by calling IssueGetNodeRequest,
// which, as the name says, issued TEvGetNode to the nameservice and arms timer to handle timeout (which should not
// occur, but we want to be sure we don't hang on this), and then switches to PendingNodeInfo state.
-
+
PROXY_STFUNC(PendingActivation,
RequestNodeInfo, // Session events
RequestNodeInfoForIncomingHandshake, // Incoming handshake requests
@@ -221,8 +221,8 @@ namespace NActors {
Ignore, // Disconnect request
Ignore, // Wakeup
Ignore // Node info
- )
-
+ )
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingNodeInfo
//
@@ -234,7 +234,7 @@ namespace NActors {
// NOTE: handshake status events are also enqueued as the handshake actor may have generated failure event due to
// timeout or some other reason without waiting for acknowledge, and it must be processed correctly to prevent
// session hang
-
+
PROXY_STFUNC(PendingNodeInfo,
EnqueueSessionEvent, // Session events
EnqueueIncomingHandshakeEvent, // Incoming handshake requests
@@ -242,8 +242,8 @@ namespace NActors {
Disconnect, // Disconnect request
ConfigureTimeout, // Wakeup
Configure // Node info
- )
-
+ )
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingConnection
//
@@ -251,7 +251,7 @@ namespace NActors {
// the status of the handshake. When one if handshakes finishes, we use this status to establish connection (or to
// go to error state). When one handshake terminates with error while other is running, we will still wait for the
// second one to finish.
-
+
PROXY_STFUNC(PendingConnection,
EnqueueSessionEvent, // Session events
IncomingHandshake, // Incoming handshake requests
@@ -259,14 +259,14 @@ namespace NActors {
Disconnect, // Disconnect request
Ignore, // Wakeup
Ignore // Node info
- )
-
+ )
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// StateWork
//
// We have accepted session and process any incoming messages with the session. Incoming handshakes are accepted
// concurrently and applied when finished.
-
+
PROXY_STFUNC(StateWork,
ForwardSessionEventToSession, // Session events
IncomingHandshake, // Incoming handshake requests
@@ -274,14 +274,14 @@ namespace NActors {
Disconnect, // Disconnect request
Ignore, // Wakeup
Ignore // Node info
- )
-
+ )
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// HoldByError
//
// When something bad happens with the connection, we sleep in this state. After wake up we go back to
// PendingActivation.
-
+
PROXY_STFUNC(HoldByError,
DropSessionEvent, // Session events
RequestNodeInfoForIncomingHandshake, // Incoming handshake requests
@@ -289,249 +289,249 @@ namespace NActors {
Ignore, // Disconnect request
WakeupFromErrorState, // Wakeup
Ignore // Node info
- )
-
-#undef SESSION_EVENTS
-#undef INCOMING_HANDSHAKE_EVENTS
-#undef HANDSHAKE_STATUS_EVENTS
-#undef PROXY_STFUNC
-
- void ForwardSessionEventToSession(STATEFN_SIG);
- void EnqueueSessionEvent(STATEFN_SIG);
-
- // Incoming handshake handlers, including special wrapper when the IncomingHandshake is used as fFunc
- void IncomingHandshake(STATEFN_SIG) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvHandshakeAsk, IncomingHandshake);
- hFunc(TEvHandshakeRequest, IncomingHandshake);
- default:
- Y_FAIL();
- }
- }
- void IncomingHandshake(TEvHandshakeAsk::TPtr& ev);
- void IncomingHandshake(TEvHandshakeRequest::TPtr& ev);
-
- void RequestNodeInfo(STATEFN_SIG);
- void RequestNodeInfoForIncomingHandshake(STATEFN_SIG);
-
- void StartInitialHandshake();
- void StartResumeHandshake(ui64 inputCounter);
-
+ )
+
+#undef SESSION_EVENTS
+#undef INCOMING_HANDSHAKE_EVENTS
+#undef HANDSHAKE_STATUS_EVENTS
+#undef PROXY_STFUNC
+
+ void ForwardSessionEventToSession(STATEFN_SIG);
+ void EnqueueSessionEvent(STATEFN_SIG);
+
+ // Incoming handshake handlers, including special wrapper when the IncomingHandshake is used as fFunc
+ void IncomingHandshake(STATEFN_SIG) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvHandshakeAsk, IncomingHandshake);
+ hFunc(TEvHandshakeRequest, IncomingHandshake);
+ default:
+ Y_FAIL();
+ }
+ }
+ void IncomingHandshake(TEvHandshakeAsk::TPtr& ev);
+ void IncomingHandshake(TEvHandshakeRequest::TPtr& ev);
+
+ void RequestNodeInfo(STATEFN_SIG);
+ void RequestNodeInfoForIncomingHandshake(STATEFN_SIG);
+
+ void StartInitialHandshake();
+ void StartResumeHandshake(ui64 inputCounter);
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Incoming handshake event queue processing
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void EnqueueIncomingHandshakeEvent(STATEFN_SIG);
- void EnqueueIncomingHandshakeEvent(TEvHandshakeDone::TPtr& ev);
- void EnqueueIncomingHandshakeEvent(TEvHandshakeFail::TPtr& ev);
-
+
+ void EnqueueIncomingHandshakeEvent(STATEFN_SIG);
+ void EnqueueIncomingHandshakeEvent(TEvHandshakeDone::TPtr& ev);
+ void EnqueueIncomingHandshakeEvent(TEvHandshakeFail::TPtr& ev);
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PendingNodeInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
IEventBase* ConfigureTimeoutCookie; // pointer to the scheduled event used to match sent and received events
-
- void StartConfiguring();
- void Configure(TEvInterconnect::TEvNodeInfo::TPtr& ev);
- void ConfigureTimeout(TEvents::TEvWakeup::TPtr& ev);
- void ProcessConfigured();
-
- void HandleHandshakeStatus(TEvHandshakeDone::TPtr& ev);
- void HandleHandshakeStatus(TEvHandshakeFail::TPtr& ev);
-
- void TransitToErrorState(TString Explanation, bool updateErrorLog = true);
- void WakeupFromErrorState(TEvents::TEvWakeup::TPtr& ev);
- void Disconnect();
-
+
+ void StartConfiguring();
+ void Configure(TEvInterconnect::TEvNodeInfo::TPtr& ev);
+ void ConfigureTimeout(TEvents::TEvWakeup::TPtr& ev);
+ void ProcessConfigured();
+
+ void HandleHandshakeStatus(TEvHandshakeDone::TPtr& ev);
+ void HandleHandshakeStatus(TEvHandshakeFail::TPtr& ev);
+
+ void TransitToErrorState(TString Explanation, bool updateErrorLog = true);
+ void WakeupFromErrorState(TEvents::TEvWakeup::TPtr& ev);
+ void Disconnect();
+
const ui32 PeerNodeId;
- IActor **DynamicPtr;
-
- void ValidateEvent(TAutoPtr<IEventHandle>& ev, const char* func) {
- if (SelfId().NodeId() == PeerNodeId) {
- TString msg = Sprintf("Event Type# 0x%08" PRIx32 " TypeRewrite# 0x%08" PRIx32
- " from Sender# %s sent to the proxy for the node itself via Interconnect;"
- " THIS IS NOT A BUG IN INTERCONNECT, check the event sender instead",
+ IActor **DynamicPtr;
+
+ void ValidateEvent(TAutoPtr<IEventHandle>& ev, const char* func) {
+ if (SelfId().NodeId() == PeerNodeId) {
+ TString msg = Sprintf("Event Type# 0x%08" PRIx32 " TypeRewrite# 0x%08" PRIx32
+ " from Sender# %s sent to the proxy for the node itself via Interconnect;"
+ " THIS IS NOT A BUG IN INTERCONNECT, check the event sender instead",
ev->Type, ev->GetTypeRewrite(), ev->Sender.ToString().data());
LOG_ERROR_IC("ICP03", "%s", msg.data());
Y_VERIFY_DEBUG(false, "%s", msg.data());
- }
-
- Y_VERIFY(ev->GetTypeRewrite() != TEvInterconnect::EvForward || ev->Recipient.NodeId() == PeerNodeId,
- "Recipient/Proxy NodeId mismatch Recipient# %s Type# 0x%08" PRIx32 " PeerNodeId# %" PRIu32 " Func# %s",
+ }
+
+ Y_VERIFY(ev->GetTypeRewrite() != TEvInterconnect::EvForward || ev->Recipient.NodeId() == PeerNodeId,
+ "Recipient/Proxy NodeId mismatch Recipient# %s Type# 0x%08" PRIx32 " PeerNodeId# %" PRIu32 " Func# %s",
ev->Recipient.ToString().data(), ev->Type, PeerNodeId, func);
- }
-
- // Common with helpers
+ }
+
+ // Common with helpers
// All proxy actors share the same information in the object
// read only
- TInterconnectProxyCommon::TPtr const Common;
-
+ TInterconnectProxyCommon::TPtr const Common;
+
const TActorId& GetNameserviceId() const {
- return Common->NameserviceId;
+ return Common->NameserviceId;
}
-
+
TString TechnicalPeerHostName;
-
+
std::shared_ptr<IInterconnectMetrics> Metrics;
-
- void HandleClosePeerSocket();
- void HandleCloseInputSession();
- void HandlePoisonSession();
-
- void HandleSessionBufferSizeRequest(TEvSessionBufferSizeRequest::TPtr& ev);
+
+ void HandleClosePeerSocket();
+ void HandleCloseInputSession();
+ void HandlePoisonSession();
+
+ void HandleSessionBufferSizeRequest(TEvSessionBufferSizeRequest::TPtr& ev);
bool CleanupEventQueueScheduled = false;
- void ScheduleCleanupEventQueue();
- void HandleCleanupEventQueue();
- void CleanupEventQueue();
-
+ void ScheduleCleanupEventQueue();
+ void HandleCleanupEventQueue();
+ void CleanupEventQueue();
+
// hold all events before connection is established
- struct TPendingSessionEvent {
- TInstant Deadline;
- ui32 Size;
- THolder<IEventHandle> Event;
-
- TPendingSessionEvent(TInstant deadline, ui32 size, TAutoPtr<IEventHandle> event)
- : Deadline(deadline)
- , Size(size)
- , Event(event)
- {}
- };
- TDeque<TPendingSessionEvent> PendingSessionEvents;
- ui64 PendingSessionEventsSize = 0;
- void ProcessPendingSessionEvents();
- void DropSessionEvent(STATEFN_SIG);
-
+ struct TPendingSessionEvent {
+ TInstant Deadline;
+ ui32 Size;
+ THolder<IEventHandle> Event;
+
+ TPendingSessionEvent(TInstant deadline, ui32 size, TAutoPtr<IEventHandle> event)
+ : Deadline(deadline)
+ , Size(size)
+ , Event(event)
+ {}
+ };
+ TDeque<TPendingSessionEvent> PendingSessionEvents;
+ ui64 PendingSessionEventsSize = 0;
+ void ProcessPendingSessionEvents();
+ void DropSessionEvent(STATEFN_SIG);
+
TInterconnectSessionTCP* Session = nullptr;
TActorId SessionID;
-
+
// virtual ids used during handshake to check if it is the connection
// for the same session or to find out the latest shandshake
// it's virtual because session actor apears after successfull handshake
TActorId SessionVirtualId;
TActorId RemoteSessionVirtualId;
-
+
TActorId GenerateSessionVirtualId() {
- ICPROXY_PROFILED;
-
- const ui64 localId = TlsActivationContext->ExecutorThread.ActorSystem->AllocateIDSpace(1);
+ ICPROXY_PROFILED;
+
+ const ui64 localId = TlsActivationContext->ExecutorThread.ActorSystem->AllocateIDSpace(1);
return NActors::TActorId(SelfId().NodeId(), 0, localId, 0);
}
-
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
TActorId IncomingHandshakeActor;
TInstant IncomingHandshakeActorFilledIn;
TInstant IncomingHandshakeActorReset;
- TMaybe<ui64> LastSerialFromIncomingHandshake;
+ TMaybe<ui64> LastSerialFromIncomingHandshake;
THolder<IEventBase> HeldHandshakeReply;
-
- void DropIncomingHandshake(bool poison = true) {
- ICPROXY_PROFILED;
-
+
+ void DropIncomingHandshake(bool poison = true) {
+ ICPROXY_PROFILED;
+
if (const TActorId& actorId = std::exchange(IncomingHandshakeActor, TActorId())) {
LOG_DEBUG_IC("ICP111", "dropped incoming handshake: %s poison: %s", actorId.ToString().data(),
poison ? "true" : "false");
if (poison) {
- Send(actorId, new TEvents::TEvPoisonPill);
+ Send(actorId, new TEvents::TEvPoisonPill);
}
- LastSerialFromIncomingHandshake.Clear();
+ LastSerialFromIncomingHandshake.Clear();
HeldHandshakeReply.Reset();
- IncomingHandshakeActorReset = TActivationContext::Now();
- }
- }
-
- void DropOutgoingHandshake(bool poison = true) {
- ICPROXY_PROFILED;
-
+ IncomingHandshakeActorReset = TActivationContext::Now();
+ }
+ }
+
+ void DropOutgoingHandshake(bool poison = true) {
+ ICPROXY_PROFILED;
+
if (const TActorId& actorId = std::exchange(OutgoingHandshakeActor, TActorId())) {
LOG_DEBUG_IC("ICP112", "dropped outgoing handshake: %s poison: %s", actorId.ToString().data(),
poison ? "true" : "false");
if (poison) {
- Send(actorId, new TEvents::TEvPoisonPill);
+ Send(actorId, new TEvents::TEvPoisonPill);
}
- OutgoingHandshakeActorReset = TActivationContext::Now();
- }
- }
-
- void DropHandshakes() {
- ICPROXY_PROFILED;
-
- DropIncomingHandshake();
- DropOutgoingHandshake();
- }
-
- void PrepareNewSessionHandshake() {
- ICPROXY_PROFILED;
-
+ OutgoingHandshakeActorReset = TActivationContext::Now();
+ }
+ }
+
+ void DropHandshakes() {
+ ICPROXY_PROFILED;
+
+ DropIncomingHandshake();
+ DropOutgoingHandshake();
+ }
+
+ void PrepareNewSessionHandshake() {
+ ICPROXY_PROFILED;
+
// drop existing session if we have one
if (Session) {
LOG_INFO_IC("ICP04", "terminating current session as we are negotiating a new one");
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::NewSession());
+ IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::NewSession());
}
-
+
// ensure we have no current session
Y_VERIFY(!Session);
-
+
// switch to pending connection state -- we wait for handshakes, we want more handshakes!
- SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection);
+ SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection);
}
-
+
void IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId,
THolder<IEventBase> event);
-
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
TActorId OutgoingHandshakeActor;
TInstant OutgoingHandshakeActorCreated;
TInstant OutgoingHandshakeActorReset;
-
+
TInstant LastSessionDieTime;
-
- void GenerateHttpInfo(NMon::TEvHttpInfo::TPtr& ev);
-
- void Handle(TEvQueryStats::TPtr& ev);
-
+
+ void GenerateHttpInfo(NMon::TEvHttpInfo::TPtr& ev);
+
+ void Handle(TEvQueryStats::TPtr& ev);
+
TDuration HoldByErrorWakeupDuration = TDuration::Zero();
TEvents::TEvWakeup* HoldByErrorWakeupCookie;
-
+
THolder<TProgramInfo> RemoteProgramInfo;
- NInterconnect::TSecureSocketContext::TPtr SecureContext;
-
- void Handle(TEvGetSecureSocket::TPtr ev) {
- auto socket = MakeIntrusive<NInterconnect::TSecureSocket>(*ev->Get()->Socket, SecureContext);
- Send(ev->Sender, new TEvSecureSocket(std::move(socket)));
- }
-
+ NInterconnect::TSecureSocketContext::TPtr SecureContext;
+
+ void Handle(TEvGetSecureSocket::TPtr ev) {
+ auto socket = MakeIntrusive<NInterconnect::TSecureSocket>(*ev->Get()->Socket, SecureContext);
+ Send(ev->Sender, new TEvSecureSocket(std::move(socket)));
+ }
+
TDeque<THolder<IEventHandle>> PendingIncomingHandshakeEvents;
-
- TDeque<std::tuple<TInstant, TString, TString, ui32>> ErrorStateLog;
+
+ TDeque<std::tuple<TInstant, TString, TString, ui32>> ErrorStateLog;
void UpdateErrorStateLog(TInstant now, TString kind, TString explanation) {
- ICPROXY_PROFILED;
-
- if (ErrorStateLog) {
- auto& back = ErrorStateLog.back();
- TString lastKind, lastExpl;
- if (kind == std::get<1>(back) && explanation == std::get<2>(back)) {
- std::get<0>(back) = now;
- ++std::get<3>(back);
- return;
- }
- }
-
- ErrorStateLog.emplace_back(now, std::move(kind), std::move(explanation), 1);
+ ICPROXY_PROFILED;
+
+ if (ErrorStateLog) {
+ auto& back = ErrorStateLog.back();
+ TString lastKind, lastExpl;
+ if (kind == std::get<1>(back) && explanation == std::get<2>(back)) {
+ std::get<0>(back) = now;
+ ++std::get<3>(back);
+ return;
+ }
+ }
+
+ ErrorStateLog.emplace_back(now, std::move(kind), std::move(explanation), 1);
if (ErrorStateLog.size() > 20) {
ErrorStateLog.pop_front();
}
- }
-
- void LogHandshakeFail(TEvHandshakeFail::TPtr& ev, bool inconclusive);
-
- bool Terminated = false;
- void HandleTerminate();
-
- void PassAway() override;
+ }
+
+ void LogHandshakeFail(TEvHandshakeFail::TPtr& ev, bool inconclusive);
+
+ bool Terminated = false;
+ void HandleTerminate();
+
+ void PassAway() override;
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
index b95c994598d..c2800d86b29 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
+++ b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
@@ -1,12 +1,12 @@
-#include "interconnect_tcp_server.h"
-#include "interconnect_handshake.h"
-
+#include "interconnect_tcp_server.h"
+#include "interconnect_handshake.h"
+
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-
-#include "interconnect_common.h"
-
-namespace NActors {
+
+#include "interconnect_common.h"
+
+namespace NActors {
TInterconnectListenerTCP::TInterconnectListenerTCP(const TString& address, ui16 port, TInterconnectProxyCommon::TPtr common, const TMaybe<SOCKET>& socket)
: TActor(&TThis::Initial)
, TInterconnectLoggingBase(Sprintf("ICListener: %s", SelfId().ToString().data()))
@@ -22,96 +22,96 @@ namespace NActors {
SetNonBlock(*Listener);
}
}
-
+
TAutoPtr<IEventHandle> TInterconnectListenerTCP::AfterRegister(const TActorId& self, const TActorId& parentId) {
return new IEventHandle(self, parentId, new TEvents::TEvBootstrap, 0);
}
-
+
void TInterconnectListenerTCP::Die(const TActorContext& ctx) {
- LOG_DEBUG_IC("ICL08", "Dying");
+ LOG_DEBUG_IC("ICL08", "Dying");
TActor::Die(ctx);
}
-
- int TInterconnectListenerTCP::Bind() {
- NInterconnect::TAddress addr = Address;
-
- if (ProxyCommonCtx->Settings.BindOnAllAddresses) {
- switch (addr.GetFamily()) {
- case AF_INET: {
- auto *sa = reinterpret_cast<sockaddr_in*>(addr.SockAddr());
- sa->sin_addr = {INADDR_ANY};
- break;
- }
-
- case AF_INET6: {
- auto *sa = reinterpret_cast<sockaddr_in6*>(addr.SockAddr());
- sa->sin6_addr = in6addr_any;
- break;
- }
-
- default:
- Y_FAIL("Unsupported address family");
- }
+
+ int TInterconnectListenerTCP::Bind() {
+ NInterconnect::TAddress addr = Address;
+
+ if (ProxyCommonCtx->Settings.BindOnAllAddresses) {
+ switch (addr.GetFamily()) {
+ case AF_INET: {
+ auto *sa = reinterpret_cast<sockaddr_in*>(addr.SockAddr());
+ sa->sin_addr = {INADDR_ANY};
+ break;
+ }
+
+ case AF_INET6: {
+ auto *sa = reinterpret_cast<sockaddr_in6*>(addr.SockAddr());
+ sa->sin6_addr = in6addr_any;
+ break;
+ }
+
+ default:
+ Y_FAIL("Unsupported address family");
+ }
+ }
+
+ Listener = NInterconnect::TStreamSocket::Make(addr.GetFamily());
+ if (*Listener == -1) {
+ return errno;
}
-
- Listener = NInterconnect::TStreamSocket::Make(addr.GetFamily());
- if (*Listener == -1) {
- return errno;
+ SetNonBlock(*Listener);
+ Listener->SetSendBufferSize(ProxyCommonCtx->Settings.GetSendBufferSize()); // TODO(alexvru): WTF?
+ SetSockOpt(*Listener, SOL_SOCKET, SO_REUSEADDR, 1);
+ if (const auto e = -Listener->Bind(addr)) {
+ return e;
+ } else if (const auto e = -Listener->Listen(SOMAXCONN)) {
+ return e;
+ } else {
+ return 0;
}
- SetNonBlock(*Listener);
- Listener->SetSendBufferSize(ProxyCommonCtx->Settings.GetSendBufferSize()); // TODO(alexvru): WTF?
- SetSockOpt(*Listener, SOL_SOCKET, SO_REUSEADDR, 1);
- if (const auto e = -Listener->Bind(addr)) {
- return e;
- } else if (const auto e = -Listener->Listen(SOMAXCONN)) {
- return e;
- } else {
- return 0;
- }
- }
-
- void TInterconnectListenerTCP::Bootstrap(const TActorContext& ctx) {
- if (!Listener) {
- if (const int err = Bind()) {
- LOG_ERROR_IC("ICL01", "Bind failed: %s (%s)", strerror(err), Address.ToString().data());
- Listener.Reset();
- Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
- return;
- }
+ }
+
+ void TInterconnectListenerTCP::Bootstrap(const TActorContext& ctx) {
+ if (!Listener) {
+ if (const int err = Bind()) {
+ LOG_ERROR_IC("ICL01", "Bind failed: %s (%s)", strerror(err), Address.ToString().data());
+ Listener.Reset();
+ Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
+ return;
+ }
}
if (const auto& callback = ProxyCommonCtx->InitWhiteboard) {
callback(Address.GetPort(), TlsActivationContext->ExecutorThread.ActorSystem);
}
- const bool success = ctx.Send(MakePollerActorId(), new TEvPollerRegister(Listener, SelfId(), {}));
- Y_VERIFY(success);
- Become(&TThis::Listen);
- }
-
- void TInterconnectListenerTCP::Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx) {
- PollerToken = std::move(ev->Get()->PollerToken);
- Process(ctx);
- }
-
- void TInterconnectListenerTCP::Process(const TActorContext& ctx) {
- for (;;) {
- NInterconnect::TAddress address;
- const int r = Listener->Accept(address);
- if (r >= 0) {
- LOG_DEBUG_IC("ICL04", "Accepted from: %s", address.ToString().data());
- auto socket = MakeIntrusive<NInterconnect::TStreamSocket>(static_cast<SOCKET>(r));
- ctx.Register(CreateIncomingHandshakeActor(ProxyCommonCtx, std::move(socket)));
- continue;
- } else if (-r != EAGAIN && -r != EWOULDBLOCK) {
+ const bool success = ctx.Send(MakePollerActorId(), new TEvPollerRegister(Listener, SelfId(), {}));
+ Y_VERIFY(success);
+ Become(&TThis::Listen);
+ }
+
+ void TInterconnectListenerTCP::Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx) {
+ PollerToken = std::move(ev->Get()->PollerToken);
+ Process(ctx);
+ }
+
+ void TInterconnectListenerTCP::Process(const TActorContext& ctx) {
+ for (;;) {
+ NInterconnect::TAddress address;
+ const int r = Listener->Accept(address);
+ if (r >= 0) {
+ LOG_DEBUG_IC("ICL04", "Accepted from: %s", address.ToString().data());
+ auto socket = MakeIntrusive<NInterconnect::TStreamSocket>(static_cast<SOCKET>(r));
+ ctx.Register(CreateIncomingHandshakeActor(ProxyCommonCtx, std::move(socket)));
+ continue;
+ } else if (-r != EAGAIN && -r != EWOULDBLOCK) {
Y_VERIFY(-r != ENFILE && -r != EMFILE && !ExternalSocket);
- LOG_ERROR_IC("ICL06", "Listen failed: %s (%s)", strerror(-r), Address.ToString().data());
- Listener.Reset();
- PollerToken.Reset();
- Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
- } else if (PollerToken) {
- PollerToken->Request(true, false);
- }
- break;
- }
+ LOG_ERROR_IC("ICL06", "Listen failed: %s (%s)", strerror(-r), Address.ToString().data());
+ Listener.Reset();
+ PollerToken.Reset();
+ Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
+ } else if (PollerToken) {
+ PollerToken->Request(true, false);
+ }
+ break;
+ }
}
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.h b/library/cpp/actors/interconnect/interconnect_tcp_server.h
index fc71073c2df..adac74052d8 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_server.h
+++ b/library/cpp/actors/interconnect/interconnect_tcp_server.h
@@ -1,57 +1,57 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/core/events.h>
-
-#include "interconnect_common.h"
-#include "poller_actor.h"
-#include "events_local.h"
-
-namespace NActors {
+
+#include "interconnect_common.h"
+#include "poller_actor.h"
+#include "events_local.h"
+
+namespace NActors {
class TInterconnectListenerTCP: public TActor<TInterconnectListenerTCP>, public TInterconnectLoggingBase {
public:
static constexpr EActivityType ActorActivityType() {
return INTERCONNECT_COMMON;
}
-
+
TInterconnectListenerTCP(const TString& address, ui16 port, TInterconnectProxyCommon::TPtr common, const TMaybe<SOCKET>& socket = Nothing());
- int Bind();
-
+ int Bind();
+
private:
STFUNC(Initial) {
switch (ev->GetTypeRewrite()) {
CFunc(TEvents::TEvBootstrap::EventType, Bootstrap);
CFunc(TEvents::TEvPoisonPill::EventType, Die);
}
- }
-
+ }
+
STFUNC(Listen) {
switch (ev->GetTypeRewrite()) {
CFunc(TEvents::TEvPoisonPill::EventType, Die);
- HFunc(TEvPollerRegisterResult, Handle);
- CFunc(TEvPollerReady::EventType, Process);
+ HFunc(TEvPollerRegisterResult, Handle);
+ CFunc(TEvPollerReady::EventType, Process);
}
- }
-
+ }
+
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override;
-
+
void Die(const TActorContext& ctx) override;
-
+
void Bootstrap(const TActorContext& ctx);
- void Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx);
-
- void Process(const TActorContext& ctx);
-
+ void Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx);
+
+ void Process(const TActorContext& ctx);
+
const NInterconnect::TAddress Address;
TIntrusivePtr<NInterconnect::TStreamSocket> Listener;
const bool ExternalSocket;
- TPollerToken::TPtr PollerToken;
- TInterconnectProxyCommon::TPtr const ProxyCommonCtx;
+ TPollerToken::TPtr PollerToken;
+ TInterconnectProxyCommon::TPtr const ProxyCommonCtx;
};
-
+
static inline TActorId MakeInterconnectListenerActorId(bool dynamic) {
- char x[12] = {'I', 'C', 'L', 'i', 's', 't', 'e', 'n', 'e', 'r', '/', dynamic ? 'D' : 'S'};
+ char x[12] = {'I', 'C', 'L', 'i', 's', 't', 'e', 'n', 'e', 'r', '/', dynamic ? 'D' : 'S'};
return TActorId(0, TStringBuf(x, 12));
- }
-}
+ }
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_session.cpp b/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
index 2ded7f9f537..8f13d89f358 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
+++ b/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
@@ -1,40 +1,40 @@
-#include "interconnect_tcp_proxy.h"
-#include "interconnect_tcp_session.h"
-#include "interconnect_handshake.h"
-
+#include "interconnect_tcp_proxy.h"
+#include "interconnect_tcp_session.h"
+#include "interconnect_handshake.h"
+
#include <library/cpp/actors/core/probes.h>
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/core/interconnect.h>
#include <library/cpp/actors/util/datetime.h>
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NActors {
+
+namespace NActors {
LWTRACE_USING(ACTORLIB_PROVIDER);
-
+
DECLARE_WILSON_EVENT(OutputQueuePush, (ui32, QueueSizeInEvents), (ui64, QueueSizeInBytes));
-
- template<typename T>
- T Coalesce(T&& x) {
- return x;
+
+ template<typename T>
+ T Coalesce(T&& x) {
+ return x;
}
-
- template<typename T, typename T2, typename... TRest>
- typename std::common_type<T, T2, TRest...>::type Coalesce(T&& first, T2&& mid, TRest&&... rest) {
- if (first != typename std::remove_reference<T>::type()) {
- return first;
- } else {
- return Coalesce(std::forward<T2>(mid), std::forward<TRest>(rest)...);
- }
+
+ template<typename T, typename T2, typename... TRest>
+ typename std::common_type<T, T2, TRest...>::type Coalesce(T&& first, T2&& mid, TRest&&... rest) {
+ if (first != typename std::remove_reference<T>::type()) {
+ return first;
+ } else {
+ return Coalesce(std::forward<T2>(mid), std::forward<TRest>(rest)...);
+ }
}
-
- TInterconnectSessionTCP::TInterconnectSessionTCP(TInterconnectProxyTCP* const proxy, TSessionParams params)
+
+ TInterconnectSessionTCP::TInterconnectSessionTCP(TInterconnectProxyTCP* const proxy, TSessionParams params)
: TActor(&TInterconnectSessionTCP::StateFunc)
- , Created(TInstant::Now())
+ , Created(TInstant::Now())
, Proxy(proxy)
- , CloseOnIdleWatchdog(GetCloseOnIdleTimeout(), std::bind(&TThis::OnCloseOnIdleTimerHit, this))
- , LostConnectionWatchdog(GetLostConnectionTimeout(), std::bind(&TThis::OnLostConnectionTimerHit, this))
- , Params(std::move(params))
+ , CloseOnIdleWatchdog(GetCloseOnIdleTimeout(), std::bind(&TThis::OnCloseOnIdleTimerHit, this))
+ , LostConnectionWatchdog(GetLostConnectionTimeout(), std::bind(&TThis::OnLostConnectionTimerHit, this))
+ , Params(std::move(params))
, TotalOutputQueueSize(0)
, OutputStuckFlag(false)
, OutputQueueUtilization(16)
@@ -42,92 +42,92 @@ namespace NActors {
{
Proxy->Metrics->SetConnected(0);
ReceiveContext.Reset(new TReceiveContext);
- }
-
- TInterconnectSessionTCP::~TInterconnectSessionTCP() {
- // close socket ASAP when actor system is being shut down
- if (Socket) {
- Socket->Shutdown(SHUT_RDWR);
- }
- }
-
- void TInterconnectSessionTCP::Init() {
- auto destroyCallback = [as = TlsActivationContext->ExecutorThread.ActorSystem, id = Proxy->Common->DestructorId](THolder<IEventBase> event) {
- as->Send(id, event.Release());
- };
- Pool.ConstructInPlace(Proxy->Common, std::move(destroyCallback));
+ }
+
+ TInterconnectSessionTCP::~TInterconnectSessionTCP() {
+ // close socket ASAP when actor system is being shut down
+ if (Socket) {
+ Socket->Shutdown(SHUT_RDWR);
+ }
+ }
+
+ void TInterconnectSessionTCP::Init() {
+ auto destroyCallback = [as = TlsActivationContext->ExecutorThread.ActorSystem, id = Proxy->Common->DestructorId](THolder<IEventBase> event) {
+ as->Send(id, event.Release());
+ };
+ Pool.ConstructInPlace(Proxy->Common, std::move(destroyCallback));
ChannelScheduler.ConstructInPlace(Proxy->PeerNodeId, Proxy->Common->ChannelsConfig, Proxy->Metrics, *Pool,
- Proxy->Common->Settings.MaxSerializedEventSize, Params);
-
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] session created", Proxy->PeerNodeId);
+ Proxy->Common->Settings.MaxSerializedEventSize, Params);
+
+ LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] session created", Proxy->PeerNodeId);
SetPrefix(Sprintf("Session %s [node %" PRIu32 "]", SelfId().ToString().data(), Proxy->PeerNodeId));
- SendUpdateToWhiteboard();
+ SendUpdateToWhiteboard();
}
-
- void TInterconnectSessionTCP::CloseInputSession() {
- Send(ReceiverId, new TEvInterconnect::TEvCloseInputSession);
- }
-
- void TInterconnectSessionTCP::Handle(TEvTerminate::TPtr& ev) {
- Terminate(ev->Get()->Reason);
- }
-
- void TInterconnectSessionTCP::HandlePoison() {
- Terminate(TDisconnectReason());
- }
-
- void TInterconnectSessionTCP::Terminate(TDisconnectReason reason) {
- LOG_INFO_IC_SESSION("ICS01", "socket: %" PRIi64, (Socket ? i64(*Socket) : -1));
-
- IActor::InvokeOtherActor(*Proxy, &TInterconnectProxyTCP::UnregisterSession, this);
- ShutdownSocket(std::move(reason));
-
+
+ void TInterconnectSessionTCP::CloseInputSession() {
+ Send(ReceiverId, new TEvInterconnect::TEvCloseInputSession);
+ }
+
+ void TInterconnectSessionTCP::Handle(TEvTerminate::TPtr& ev) {
+ Terminate(ev->Get()->Reason);
+ }
+
+ void TInterconnectSessionTCP::HandlePoison() {
+ Terminate(TDisconnectReason());
+ }
+
+ void TInterconnectSessionTCP::Terminate(TDisconnectReason reason) {
+ LOG_INFO_IC_SESSION("ICS01", "socket: %" PRIi64, (Socket ? i64(*Socket) : -1));
+
+ IActor::InvokeOtherActor(*Proxy, &TInterconnectProxyTCP::UnregisterSession, this);
+ ShutdownSocket(std::move(reason));
+
for (const auto& kv : Subscribers) {
Send(kv.first, new TEvInterconnect::TEvNodeDisconnected(Proxy->PeerNodeId), 0, kv.second);
}
Proxy->Metrics->SubSubscribersCount(Subscribers.size());
- Subscribers.clear();
-
- ChannelScheduler->ForEach([&](TEventOutputChannel& channel) {
- channel.NotifyUndelivered();
- });
-
- if (ReceiverId) {
- Send(ReceiverId, new TEvents::TEvPoisonPill);
- }
-
- SendUpdateToWhiteboard(false);
-
+ Subscribers.clear();
+
+ ChannelScheduler->ForEach([&](TEventOutputChannel& channel) {
+ channel.NotifyUndelivered();
+ });
+
+ if (ReceiverId) {
+ Send(ReceiverId, new TEvents::TEvPoisonPill);
+ }
+
+ SendUpdateToWhiteboard(false);
+
Proxy->Metrics->SubOutputBuffersTotalSize(TotalOutputQueueSize);
Proxy->Metrics->SubInflightDataAmount(InflightDataAmount);
+
+ LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] session destroyed", Proxy->PeerNodeId);
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] session destroyed", Proxy->PeerNodeId);
-
- if (!Subscribers.empty()) {
+ if (!Subscribers.empty()) {
Proxy->Metrics->SubSubscribersCount(Subscribers.size());
- }
-
- TActor::PassAway();
- }
-
- void TInterconnectSessionTCP::PassAway() {
- Y_FAIL("TInterconnectSessionTCP::PassAway() can't be called directly");
+ }
+
+ TActor::PassAway();
}
-
- void TInterconnectSessionTCP::Forward(STATEFN_SIG) {
- Proxy->ValidateEvent(ev, "Forward");
-
+
+ void TInterconnectSessionTCP::PassAway() {
+ Y_FAIL("TInterconnectSessionTCP::PassAway() can't be called directly");
+ }
+
+ void TInterconnectSessionTCP::Forward(STATEFN_SIG) {
+ Proxy->ValidateEvent(ev, "Forward");
+
LOG_DEBUG_IC_SESSION("ICS02", "send event from: %s to: %s", ev->Sender.ToString().data(), ev->Recipient.ToString().data());
++MessagesGot;
-
+
if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
- Subscribe(ev);
+ Subscribe(ev);
}
-
+
ui16 evChannel = ev->GetChannel();
- auto& oChannel = ChannelScheduler->GetOutputChannel(evChannel);
- const bool wasWorking = oChannel.IsWorking();
-
+ auto& oChannel = ChannelScheduler->GetOutputChannel(evChannel);
+ const bool wasWorking = oChannel.IsWorking();
+
const auto [dataSize, event] = oChannel.Push(*ev);
LWTRACK(ForwardEvent, event->Orbit, Proxy->PeerNodeId, event->Descr.Type, event->Descr.Flags, LWACTORID(event->Descr.Recipient), LWACTORID(event->Descr.Sender), event->Descr.Cookie, event->EventSerializedSize);
@@ -137,268 +137,268 @@ namespace NActors {
// this channel has returned to work -- it was empty and this we have just put first event in the queue
ChannelScheduler->AddToHeap(oChannel, EqualizeCounter);
}
-
+
SetOutputStuckFlag(true);
- ++NumEventsInReadyChannels;
-
+ ++NumEventsInReadyChannels;
+
LWTRACK(EnqueueEvent, event->Orbit, Proxy->PeerNodeId, NumEventsInReadyChannels, GetWriteBlockedTotal(), evChannel, oChannel.GetQueueSize(), oChannel.GetBufferedAmountOfData());
- WILSON_TRACE(*TlsActivationContext, &ev->TraceId, OutputQueuePush,
+ WILSON_TRACE(*TlsActivationContext, &ev->TraceId, OutputQueuePush,
QueueSizeInEvents = oChannel.GetQueueSize(),
- QueueSizeInBytes = oChannel.GetBufferedAmountOfData());
-
+ QueueSizeInBytes = oChannel.GetBufferedAmountOfData());
+
// check for overloaded queues
- ui64 sendBufferDieLimit = Proxy->Common->Settings.SendBufferDieLimitInMB * ui64(1 << 20);
+ ui64 sendBufferDieLimit = Proxy->Common->Settings.SendBufferDieLimitInMB * ui64(1 << 20);
if (sendBufferDieLimit != 0 && TotalOutputQueueSize > sendBufferDieLimit) {
- LOG_ERROR_IC_SESSION("ICS03", "socket: %" PRIi64 " output queue is overloaded, actual %" PRIu64 " bytes, limit is %" PRIu64,
+ LOG_ERROR_IC_SESSION("ICS03", "socket: %" PRIi64 " output queue is overloaded, actual %" PRIu64 " bytes, limit is %" PRIu64,
Socket ? i64(*Socket) : -1, TotalOutputQueueSize, sendBufferDieLimit);
- return Terminate(TDisconnectReason::QueueOverload());
+ return Terminate(TDisconnectReason::QueueOverload());
}
-
- ui64 outputBuffersTotalSizeLimit = Proxy->Common->Settings.OutputBuffersTotalSizeLimitInMB * ui64(1 << 20);
+
+ ui64 outputBuffersTotalSizeLimit = Proxy->Common->Settings.OutputBuffersTotalSizeLimitInMB * ui64(1 << 20);
if (outputBuffersTotalSizeLimit != 0 && static_cast<ui64>(Proxy->Metrics->GetOutputBuffersTotalSize()) > outputBuffersTotalSizeLimit) {
- LOG_ERROR_IC_SESSION("ICS77", "Exceeded total limit on output buffers size");
- if (AtomicTryLock(&Proxy->Common->StartedSessionKiller)) {
- CreateSessionKillingActor(Proxy->Common);
+ LOG_ERROR_IC_SESSION("ICS77", "Exceeded total limit on output buffers size");
+ if (AtomicTryLock(&Proxy->Common->StartedSessionKiller)) {
+ CreateSessionKillingActor(Proxy->Common);
}
}
-
- if (RamInQueue && !RamInQueue->Batching) {
- // we have pending TEvRam, so GenerateTraffic will be called no matter what
- } else if (InflightDataAmount >= GetTotalInflightAmountOfData() || !Socket || ReceiveContext->WriteBlockedByFullSendBuffer) {
- // we can't issue more traffic now; GenerateTraffic will be called upon unblocking
- } else if (TotalOutputQueueSize >= 64 * 1024) {
- // output queue size is quite big to issue some traffic
- GenerateTraffic();
- } else if (!RamInQueue) {
- Y_VERIFY_DEBUG(NumEventsInReadyChannels == 1);
- RamInQueue = new TEvRam(true);
- auto *ev = new IEventHandle(SelfId(), {}, RamInQueue);
- const TDuration batchPeriod = Proxy->Common->Settings.BatchPeriod;
- if (batchPeriod != TDuration()) {
- TActivationContext::Schedule(batchPeriod, ev);
- } else {
- TActivationContext::Send(ev);
- }
+
+ if (RamInQueue && !RamInQueue->Batching) {
+ // we have pending TEvRam, so GenerateTraffic will be called no matter what
+ } else if (InflightDataAmount >= GetTotalInflightAmountOfData() || !Socket || ReceiveContext->WriteBlockedByFullSendBuffer) {
+ // we can't issue more traffic now; GenerateTraffic will be called upon unblocking
+ } else if (TotalOutputQueueSize >= 64 * 1024) {
+ // output queue size is quite big to issue some traffic
+ GenerateTraffic();
+ } else if (!RamInQueue) {
+ Y_VERIFY_DEBUG(NumEventsInReadyChannels == 1);
+ RamInQueue = new TEvRam(true);
+ auto *ev = new IEventHandle(SelfId(), {}, RamInQueue);
+ const TDuration batchPeriod = Proxy->Common->Settings.BatchPeriod;
+ if (batchPeriod != TDuration()) {
+ TActivationContext::Schedule(batchPeriod, ev);
+ } else {
+ TActivationContext::Send(ev);
+ }
LWPROBE(StartBatching, Proxy->PeerNodeId, batchPeriod.MillisecondsFloat());
- LOG_DEBUG_IC_SESSION("ICS17", "batching started");
- }
+ LOG_DEBUG_IC_SESSION("ICS17", "batching started");
+ }
}
- void TInterconnectSessionTCP::Subscribe(STATEFN_SIG) {
+ void TInterconnectSessionTCP::Subscribe(STATEFN_SIG) {
LOG_DEBUG_IC_SESSION("ICS04", "subscribe for session state for %s", ev->Sender.ToString().data());
const auto [it, inserted] = Subscribers.emplace(ev->Sender, ev->Cookie);
- if (inserted) {
+ if (inserted) {
Proxy->Metrics->IncSubscribersCount();
} else {
it->second = ev->Cookie;
- }
+ }
Send(ev->Sender, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, ev->Cookie);
- }
-
- void TInterconnectSessionTCP::Unsubscribe(STATEFN_SIG) {
+ }
+
+ void TInterconnectSessionTCP::Unsubscribe(STATEFN_SIG) {
LOG_DEBUG_IC_SESSION("ICS05", "unsubscribe for session state for %s", ev->Sender.ToString().data());
Proxy->Metrics->SubSubscribersCount( Subscribers.erase(ev->Sender));
}
-
- THolder<TEvHandshakeAck> TInterconnectSessionTCP::ProcessHandshakeRequest(TEvHandshakeAsk::TPtr& ev) {
- TEvHandshakeAsk *msg = ev->Get();
-
+
+ THolder<TEvHandshakeAck> TInterconnectSessionTCP::ProcessHandshakeRequest(TEvHandshakeAsk::TPtr& ev) {
+ TEvHandshakeAsk *msg = ev->Get();
+
// close existing input session, if any, and do nothing upon its destruction
- ReestablishConnection({}, false, TDisconnectReason::NewSession());
- const ui64 lastInputSerial = ReceiveContext->LockLastProcessedPacketSerial();
-
- LOG_INFO_IC_SESSION("ICS08", "incoming handshake Self# %s Peer# %s Counter# %" PRIu64 " LastInputSerial# %" PRIu64,
- msg->Self.ToString().data(), msg->Peer.ToString().data(), msg->Counter, lastInputSerial);
-
- return MakeHolder<TEvHandshakeAck>(msg->Peer, lastInputSerial, Params);
+ ReestablishConnection({}, false, TDisconnectReason::NewSession());
+ const ui64 lastInputSerial = ReceiveContext->LockLastProcessedPacketSerial();
+
+ LOG_INFO_IC_SESSION("ICS08", "incoming handshake Self# %s Peer# %s Counter# %" PRIu64 " LastInputSerial# %" PRIu64,
+ msg->Self.ToString().data(), msg->Peer.ToString().data(), msg->Counter, lastInputSerial);
+
+ return MakeHolder<TEvHandshakeAck>(msg->Peer, lastInputSerial, Params);
}
-
- void TInterconnectSessionTCP::SetNewConnection(TEvHandshakeDone::TPtr& ev) {
+
+ void TInterconnectSessionTCP::SetNewConnection(TEvHandshakeDone::TPtr& ev) {
if (ReceiverId) {
// upon destruction of input session actor invoke this callback again
- ReestablishConnection(std::move(ev), false, TDisconnectReason::NewSession());
+ ReestablishConnection(std::move(ev), false, TDisconnectReason::NewSession());
return;
}
-
- LOG_INFO_IC_SESSION("ICS09", "handshake done sender: %s self: %s peer: %s socket: %" PRIi64,
- ev->Sender.ToString().data(), ev->Get()->Self.ToString().data(), ev->Get()->Peer.ToString().data(),
- i64(*ev->Get()->Socket));
-
- NewConnectionSet = TActivationContext::Now();
+
+ LOG_INFO_IC_SESSION("ICS09", "handshake done sender: %s self: %s peer: %s socket: %" PRIi64,
+ ev->Sender.ToString().data(), ev->Get()->Self.ToString().data(), ev->Get()->Peer.ToString().data(),
+ i64(*ev->Get()->Socket));
+
+ NewConnectionSet = TActivationContext::Now();
PacketsWrittenToSocket = 0;
-
- SendBufferSize = ev->Get()->Socket->GetSendBufferSize();
- Socket = std::move(ev->Get()->Socket);
-
- // there may be a race
- const ui64 nextPacket = Max(LastConfirmed, ev->Get()->NextPacket);
-
+
+ SendBufferSize = ev->Get()->Socket->GetSendBufferSize();
+ Socket = std::move(ev->Get()->Socket);
+
+ // there may be a race
+ const ui64 nextPacket = Max(LastConfirmed, ev->Get()->NextPacket);
+
// arm watchdogs
- CloseOnIdleWatchdog.Arm(SelfId());
-
+ CloseOnIdleWatchdog.Arm(SelfId());
+
// reset activity timestamps
- LastInputActivityTimestamp = LastPayloadActivityTimestamp = TActivationContext::Now();
-
- LOG_INFO_IC_SESSION("ICS10", "traffic start");
-
+ LastInputActivityTimestamp = LastPayloadActivityTimestamp = TActivationContext::Now();
+
+ LOG_INFO_IC_SESSION("ICS10", "traffic start");
+
// create input session actor
- auto actor = MakeHolder<TInputSessionTCP>(SelfId(), Socket, ReceiveContext, Proxy->Common,
+ auto actor = MakeHolder<TInputSessionTCP>(SelfId(), Socket, ReceiveContext, Proxy->Common,
Proxy->Metrics, Proxy->PeerNodeId, nextPacket, GetDeadPeerTimeout(), Params);
- ReceiveContext->UnlockLastProcessedPacketSerial();
+ ReceiveContext->UnlockLastProcessedPacketSerial();
ReceiverId = Params.Encryption ? RegisterWithSameMailbox(actor.Release()) : Register(actor.Release(), TMailboxType::ReadAsFilled);
-
+
// register our socket in poller actor
- LOG_DEBUG_IC_SESSION("ICS11", "registering socket in PollerActor");
- const bool success = Send(MakePollerActorId(), new TEvPollerRegister(Socket, ReceiverId, SelfId()));
- Y_VERIFY(success);
- ReceiveContext->WriteBlockedByFullSendBuffer = false;
-
- LostConnectionWatchdog.Disarm();
+ LOG_DEBUG_IC_SESSION("ICS11", "registering socket in PollerActor");
+ const bool success = Send(MakePollerActorId(), new TEvPollerRegister(Socket, ReceiverId, SelfId()));
+ Y_VERIFY(success);
+ ReceiveContext->WriteBlockedByFullSendBuffer = false;
+
+ LostConnectionWatchdog.Disarm();
Proxy->Metrics->SetConnected(1);
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] connected", Proxy->PeerNodeId);
-
+ LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] connected", Proxy->PeerNodeId);
+
// arm pinger timer
- ResetFlushLogic();
-
+ ResetFlushLogic();
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// REINITIALIZE SEND QUEUE
//
// scan through send queue and leave only those packets who have data -- we will simply resend them; drop all other
// auxiliary packets; also reset packet metrics to zero to start sending from the beginning
// also reset SendQueuePos
-
+
// drop confirmed packets first as we do not need unwanted retransmissions
SendQueuePos = SendQueue.end();
- DropConfirmed(nextPacket);
-
- for (TSendQueue::iterator it = SendQueue.begin(); it != SendQueue.end(); ) {
+ DropConfirmed(nextPacket);
+
+ for (TSendQueue::iterator it = SendQueue.begin(); it != SendQueue.end(); ) {
const TSendQueue::iterator next = std::next(it);
if (it->IsEmpty()) {
- SendQueueCache.splice(SendQueueCache.begin(), SendQueue, it);
+ SendQueueCache.splice(SendQueueCache.begin(), SendQueue, it);
} else {
it->ResetBufs();
}
it = next;
}
- TrimSendQueueCache();
+ TrimSendQueueCache();
SendQueuePos = SendQueue.begin();
-
- TMaybe<ui64> s;
- for (auto it = SendQueuePos; it != SendQueue.end(); ++it) {
- if (!it->IsEmpty()) {
- s = it->GetSerial();
- }
- }
- const ui64 serial = s.GetOrElse(Max<ui64>());
-
+
+ TMaybe<ui64> s;
+ for (auto it = SendQueuePos; it != SendQueue.end(); ++it) {
+ if (!it->IsEmpty()) {
+ s = it->GetSerial();
+ }
+ }
+ const ui64 serial = s.GetOrElse(Max<ui64>());
+
Y_VERIFY(serial > LastConfirmed, "%s serial# %" PRIu64 " LastConfirmed# %" PRIu64, LogPrefix.data(), serial, LastConfirmed);
- LOG_DEBUG_IC_SESSION("ICS06", "rewind SendQueue size# %zu LastConfirmed# %" PRIu64 " SendQueuePos.Serial# %" PRIu64 "\n",
- SendQueue.size(), LastConfirmed, serial);
-
+ LOG_DEBUG_IC_SESSION("ICS06", "rewind SendQueue size# %zu LastConfirmed# %" PRIu64 " SendQueuePos.Serial# %" PRIu64 "\n",
+ SendQueue.size(), LastConfirmed, serial);
+
BytesUnwritten = 0;
for (const auto& packet : SendQueue) {
- BytesUnwritten += (Params.UseModernFrame ? sizeof(TTcpPacketHeader_v2) : sizeof(TTcpPacketHeader_v1)) +
- packet.GetDataSize();
+ BytesUnwritten += (Params.UseModernFrame ? sizeof(TTcpPacketHeader_v2) : sizeof(TTcpPacketHeader_v1)) +
+ packet.GetDataSize();
}
-
+
SwitchStuckPeriod();
-
- LastHandshakeDone = TActivationContext::Now();
-
- RamInQueue = nullptr;
- GenerateTraffic();
- }
-
- void TInterconnectSessionTCP::Handle(TEvUpdateFromInputSession::TPtr& ev) {
+
+ LastHandshakeDone = TActivationContext::Now();
+
+ RamInQueue = nullptr;
+ GenerateTraffic();
+ }
+
+ void TInterconnectSessionTCP::Handle(TEvUpdateFromInputSession::TPtr& ev) {
if (ev->Sender == ReceiverId) {
TEvUpdateFromInputSession& msg = *ev->Get();
-
- // update ping time
- Ping = msg.Ping;
+
+ // update ping time
+ Ping = msg.Ping;
LWPROBE(UpdateFromInputSession, Proxy->PeerNodeId, Ping.MillisecondsFloat());
-
+
bool needConfirm = false;
-
+
// update activity timer for dead peer checker
- LastInputActivityTimestamp = TActivationContext::Now();
-
- if (msg.NumDataBytes) {
+ LastInputActivityTimestamp = TActivationContext::Now();
+
+ if (msg.NumDataBytes) {
UnconfirmedBytes += msg.NumDataBytes;
- if (UnconfirmedBytes >= GetTotalInflightAmountOfData() / 4) {
+ if (UnconfirmedBytes >= GetTotalInflightAmountOfData() / 4) {
needConfirm = true;
} else {
- SetForcePacketTimestamp(Proxy->Common->Settings.ForceConfirmPeriod);
+ SetForcePacketTimestamp(Proxy->Common->Settings.ForceConfirmPeriod);
}
-
+
// reset payload watchdog that controls close-on-idle behaviour
- LastPayloadActivityTimestamp = TActivationContext::Now();
- CloseOnIdleWatchdog.Reset();
+ LastPayloadActivityTimestamp = TActivationContext::Now();
+ CloseOnIdleWatchdog.Reset();
}
-
- bool unblockedSomething = false;
- LWPROBE_IF_TOO_LONG(SlowICDropConfirmed, Proxy->PeerNodeId, ms) {
- unblockedSomething = DropConfirmed(msg.ConfirmedByInput);
+
+ bool unblockedSomething = false;
+ LWPROBE_IF_TOO_LONG(SlowICDropConfirmed, Proxy->PeerNodeId, ms) {
+ unblockedSomething = DropConfirmed(msg.ConfirmedByInput);
}
-
- // generate more traffic if we have unblocked state now
- if (unblockedSomething) {
+
+ // generate more traffic if we have unblocked state now
+ if (unblockedSomething) {
LWPROBE(UnblockByDropConfirmed, Proxy->PeerNodeId, NHPTimer::GetSeconds(GetCycleCountFast() - ev->SendTime) * 1000.0);
- GenerateTraffic();
+ GenerateTraffic();
}
-
+
// if we haven't generated any packets, then make a lone Flush packet without any data
if (needConfirm && Socket) {
++ConfirmPacketsForcedBySize;
- MakePacket(false);
- }
-
- for (;;) {
- switch (EUpdateState state = ReceiveContext->UpdateState) {
- case EUpdateState::NONE:
- case EUpdateState::CONFIRMING:
- Y_FAIL("unexpected state");
-
- case EUpdateState::INFLIGHT:
- // this message we are processing was the only one in flight, so we can reset state to NONE here
- if (ReceiveContext->UpdateState.compare_exchange_weak(state, EUpdateState::NONE)) {
- return;
- }
- break;
-
- case EUpdateState::INFLIGHT_AND_PENDING:
- // there is more messages pending from the input session actor, so we have to inform it to release
- // that message
- if (ReceiveContext->UpdateState.compare_exchange_weak(state, EUpdateState::CONFIRMING)) {
- Send(ev->Sender, new TEvConfirmUpdate);
- return;
- }
- break;
- }
- }
- }
+ MakePacket(false);
+ }
+
+ for (;;) {
+ switch (EUpdateState state = ReceiveContext->UpdateState) {
+ case EUpdateState::NONE:
+ case EUpdateState::CONFIRMING:
+ Y_FAIL("unexpected state");
+
+ case EUpdateState::INFLIGHT:
+ // this message we are processing was the only one in flight, so we can reset state to NONE here
+ if (ReceiveContext->UpdateState.compare_exchange_weak(state, EUpdateState::NONE)) {
+ return;
+ }
+ break;
+
+ case EUpdateState::INFLIGHT_AND_PENDING:
+ // there is more messages pending from the input session actor, so we have to inform it to release
+ // that message
+ if (ReceiveContext->UpdateState.compare_exchange_weak(state, EUpdateState::CONFIRMING)) {
+ Send(ev->Sender, new TEvConfirmUpdate);
+ return;
+ }
+ break;
+ }
+ }
+ }
}
-
- void TInterconnectSessionTCP::HandleRam(TEvRam::TPtr& ev) {
- if (ev->Get() == RamInQueue) {
+
+ void TInterconnectSessionTCP::HandleRam(TEvRam::TPtr& ev) {
+ if (ev->Get() == RamInQueue) {
LWPROBE(FinishRam, Proxy->PeerNodeId, NHPTimer::GetSeconds(GetCycleCountFast() - ev->SendTime) * 1000.0);
- RamInQueue = nullptr;
- GenerateTraffic();
- }
- }
-
- void TInterconnectSessionTCP::GenerateTraffic() {
- // generate ping request, if needed
- IssuePingRequest();
-
- if (RamInQueue && !RamInQueue->Batching) {
+ RamInQueue = nullptr;
+ GenerateTraffic();
+ }
+ }
+
+ void TInterconnectSessionTCP::GenerateTraffic() {
+ // generate ping request, if needed
+ IssuePingRequest();
+
+ if (RamInQueue && !RamInQueue->Batching) {
LWPROBE(SkipGenerateTraffic, Proxy->PeerNodeId, NHPTimer::GetSeconds(GetCycleCountFast() - RamStartedCycles) * 1000.0);
- return; // we'll do it a bit later
- } else {
- RamInQueue = nullptr;
- }
-
- LOG_DEBUG_IC_SESSION("ICS19", "GenerateTraffic");
-
+ return; // we'll do it a bit later
+ } else {
+ RamInQueue = nullptr;
+ }
+
+ LOG_DEBUG_IC_SESSION("ICS19", "GenerateTraffic");
+
// There is a tradeoff between fairness and efficiency.
// The less traffic is generated here, the less buffering is after fair scheduler,
// the more fair system is, the less latency is present.
@@ -406,27 +406,27 @@ namespace NActors {
// the less cpu is consumed.
static const ui64 generateLimit = 64 * 1024;
- const ui64 sizeBefore = TotalOutputQueueSize;
+ const ui64 sizeBefore = TotalOutputQueueSize;
ui32 generatedPackets = 0;
ui64 generatedBytes = 0;
ui64 generateStarted = GetCycleCountFast();
-
- // apply traffic changes
- auto accountTraffic = [&] { ChannelScheduler->ForEach([](TEventOutputChannel& channel) { channel.AccountTraffic(); }); };
-
+
+ // apply traffic changes
+ auto accountTraffic = [&] { ChannelScheduler->ForEach([](TEventOutputChannel& channel) { channel.AccountTraffic(); }); };
+
// first, we create as many data packets as we can generate under certain conditions; they include presence
// of events in channels queues and in flight fitting into requested limit; after we hit one of these conditions
// we exit cycle
while (Socket && NumEventsInReadyChannels && InflightDataAmount < GetTotalInflightAmountOfData() && !ReceiveContext->WriteBlockedByFullSendBuffer) {
if (generatedBytes >= generateLimit) {
// resume later but ensure that we have issued at least one packet
- RamInQueue = new TEvRam(false);
- Send(SelfId(), RamInQueue);
+ RamInQueue = new TEvRam(false);
+ Send(SelfId(), RamInQueue);
RamStartedCycles = GetCycleCountFast();
LWPROBE(StartRam, Proxy->PeerNodeId);
break;
- }
-
+ }
+
try {
generatedBytes += MakePacket(true);
++generatedPackets;
@@ -435,292 +435,292 @@ namespace NActors {
accountTraffic();
LOG_CRIT_IC("ICS31", "serialized event Type# 0x%08" PRIx32 " is too large", ex.Type);
return Terminate(TDisconnectReason::EventTooLarge());
- }
- }
-
+ }
+ }
+
if (Socket) {
WriteData();
}
LWPROBE(GenerateTraffic, Proxy->PeerNodeId, NHPTimer::GetSeconds(GetCycleCountFast() - generateStarted) * 1000.0, sizeBefore - TotalOutputQueueSize, generatedPackets, generatedBytes);
- accountTraffic();
- EqualizeCounter += ChannelScheduler->Equalize();
+ accountTraffic();
+ EqualizeCounter += ChannelScheduler->Equalize();
+ }
+
+ void TInterconnectSessionTCP::StartHandshake() {
+ LOG_INFO_IC_SESSION("ICS15", "start handshake");
+ IActor::InvokeOtherActor(*Proxy, &TInterconnectProxyTCP::StartResumeHandshake, ReceiveContext->LockLastProcessedPacketSerial());
}
- void TInterconnectSessionTCP::StartHandshake() {
- LOG_INFO_IC_SESSION("ICS15", "start handshake");
- IActor::InvokeOtherActor(*Proxy, &TInterconnectProxyTCP::StartResumeHandshake, ReceiveContext->LockLastProcessedPacketSerial());
+ void TInterconnectSessionTCP::ReestablishConnectionWithHandshake(TDisconnectReason reason) {
+ ReestablishConnection({}, true, std::move(reason));
}
-
- void TInterconnectSessionTCP::ReestablishConnectionWithHandshake(TDisconnectReason reason) {
- ReestablishConnection({}, true, std::move(reason));
- }
-
- void TInterconnectSessionTCP::ReestablishConnection(TEvHandshakeDone::TPtr&& ev, bool startHandshakeOnSessionClose,
- TDisconnectReason reason) {
+
+ void TInterconnectSessionTCP::ReestablishConnection(TEvHandshakeDone::TPtr&& ev, bool startHandshakeOnSessionClose,
+ TDisconnectReason reason) {
if (Socket) {
- LOG_INFO_IC_SESSION("ICS13", "reestablish connection");
- ShutdownSocket(std::move(reason)); // stop sending/receiving on socket
- PendingHandshakeDoneEvent = std::move(ev);
- StartHandshakeOnSessionClose = startHandshakeOnSessionClose;
+ LOG_INFO_IC_SESSION("ICS13", "reestablish connection");
+ ShutdownSocket(std::move(reason)); // stop sending/receiving on socket
+ PendingHandshakeDoneEvent = std::move(ev);
+ StartHandshakeOnSessionClose = startHandshakeOnSessionClose;
if (!ReceiverId) {
- ReestablishConnectionExecute();
+ ReestablishConnectionExecute();
}
- }
- }
-
- void TInterconnectSessionTCP::OnDisconnect(TEvSocketDisconnect::TPtr& ev) {
+ }
+ }
+
+ void TInterconnectSessionTCP::OnDisconnect(TEvSocketDisconnect::TPtr& ev) {
if (ev->Sender == ReceiverId) {
const bool wasConnected(Socket);
- LOG_INFO_IC_SESSION("ICS07", "socket disconnect %" PRIi64 " reason# %s", Socket ? i64(*Socket) : -1, ev->Get()->Reason.ToString().data());
+ LOG_INFO_IC_SESSION("ICS07", "socket disconnect %" PRIi64 " reason# %s", Socket ? i64(*Socket) : -1, ev->Get()->Reason.ToString().data());
ReceiverId = TActorId(); // reset receiver actor id as we have no more receiver yet
if (wasConnected) {
// we were sucessfully connected and did not expect failure, so it arrived from the input side; we should
// restart handshake process, closing our part of socket first
- ShutdownSocket(ev->Get()->Reason);
- StartHandshake();
+ ShutdownSocket(ev->Get()->Reason);
+ StartHandshake();
} else {
- ReestablishConnectionExecute();
+ ReestablishConnectionExecute();
}
- }
- }
-
- void TInterconnectSessionTCP::ShutdownSocket(TDisconnectReason reason) {
+ }
+ }
+
+ void TInterconnectSessionTCP::ShutdownSocket(TDisconnectReason reason) {
if (Socket) {
- if (const TString& s = reason.ToString()) {
+ if (const TString& s = reason.ToString()) {
Proxy->Metrics->IncDisconnectByReason(s);
- }
-
- LOG_INFO_IC_SESSION("ICS25", "shutdown socket, reason# %s", reason.ToString().data());
- Proxy->UpdateErrorStateLog(TActivationContext::Now(), "close_socket", reason.ToString().data());
+ }
+
+ LOG_INFO_IC_SESSION("ICS25", "shutdown socket, reason# %s", reason.ToString().data());
+ Proxy->UpdateErrorStateLog(TActivationContext::Now(), "close_socket", reason.ToString().data());
Socket->Shutdown(SHUT_RDWR);
Socket.Reset();
Proxy->Metrics->IncDisconnections();
CloseOnIdleWatchdog.Disarm();
- LostConnectionWatchdog.Arm(SelfId());
+ LostConnectionWatchdog.Arm(SelfId());
Proxy->Metrics->SetConnected(0);
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] disconnected", Proxy->PeerNodeId);
+ LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] disconnected", Proxy->PeerNodeId);
}
- }
-
- void TInterconnectSessionTCP::ReestablishConnectionExecute() {
- bool startHandshakeOnSessionClose = std::exchange(StartHandshakeOnSessionClose, false);
- TEvHandshakeDone::TPtr ev = std::move(PendingHandshakeDoneEvent);
-
- if (startHandshakeOnSessionClose) {
- StartHandshake();
- } else if (ev) {
- SetNewConnection(ev);
+ }
+
+ void TInterconnectSessionTCP::ReestablishConnectionExecute() {
+ bool startHandshakeOnSessionClose = std::exchange(StartHandshakeOnSessionClose, false);
+ TEvHandshakeDone::TPtr ev = std::move(PendingHandshakeDoneEvent);
+
+ if (startHandshakeOnSessionClose) {
+ StartHandshake();
+ } else if (ev) {
+ SetNewConnection(ev);
}
- }
-
- void TInterconnectSessionTCP::Handle(TEvPollerReady::TPtr& ev) {
- LOG_DEBUG_IC_SESSION("ICS29", "HandleReadyWrite WriteBlockedByFullSendBuffer# %s",
- ReceiveContext->WriteBlockedByFullSendBuffer ? "true" : "false");
- if (std::exchange(ReceiveContext->WriteBlockedByFullSendBuffer, false)) {
+ }
+
+ void TInterconnectSessionTCP::Handle(TEvPollerReady::TPtr& ev) {
+ LOG_DEBUG_IC_SESSION("ICS29", "HandleReadyWrite WriteBlockedByFullSendBuffer# %s",
+ ReceiveContext->WriteBlockedByFullSendBuffer ? "true" : "false");
+ if (std::exchange(ReceiveContext->WriteBlockedByFullSendBuffer, false)) {
Proxy->Metrics->IncUsefulWriteWakeups();
ui64 nowCycles = GetCycleCountFast();
double blockedUs = NHPTimer::GetSeconds(nowCycles - WriteBlockedCycles) * 1000000.0;
LWPROBE(ReadyWrite, Proxy->PeerNodeId, NHPTimer::GetSeconds(nowCycles - ev->SendTime) * 1000.0, blockedUs / 1000.0);
WriteBlockedTotal += TDuration::MicroSeconds(blockedUs);
- GenerateTraffic();
- } else if (!ev->Cookie) {
+ GenerateTraffic();
+ } else if (!ev->Cookie) {
Proxy->Metrics->IncSpuriousWriteWakeups();
}
- if (Params.Encryption && ReceiveContext->ReadPending && !ev->Cookie) {
- Send(ReceiverId, ev->Release().Release(), 0, 1);
- }
- }
-
- void TInterconnectSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
- PollerToken = std::move(ev->Get()->PollerToken);
- if (ReceiveContext->WriteBlockedByFullSendBuffer) {
- if (Params.Encryption) {
- auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
- PollerToken->Request(secure->WantRead(), secure->WantWrite());
- } else {
- PollerToken->Request(false, true);
- }
- }
- }
-
- void TInterconnectSessionTCP::WriteData() {
- ui64 written = 0;
-
+ if (Params.Encryption && ReceiveContext->ReadPending && !ev->Cookie) {
+ Send(ReceiverId, ev->Release().Release(), 0, 1);
+ }
+ }
+
+ void TInterconnectSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
+ PollerToken = std::move(ev->Get()->PollerToken);
+ if (ReceiveContext->WriteBlockedByFullSendBuffer) {
+ if (Params.Encryption) {
+ auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
+ PollerToken->Request(secure->WantRead(), secure->WantWrite());
+ } else {
+ PollerToken->Request(false, true);
+ }
+ }
+ }
+
+ void TInterconnectSessionTCP::WriteData() {
+ ui64 written = 0;
+
Y_VERIFY(Socket); // ensure that socket wasn't closed
-
- LWPROBE_IF_TOO_LONG(SlowICWriteData, Proxy->PeerNodeId, ms) {
+
+ LWPROBE_IF_TOO_LONG(SlowICWriteData, Proxy->PeerNodeId, ms) {
constexpr ui32 iovLimit = 256;
-#ifdef _linux_
- ui32 maxElementsInIOV = Min<ui32>(iovLimit, sysconf(_SC_IOV_MAX));
-#else
- ui32 maxElementsInIOV = 64;
-#endif
- if (Params.Encryption) {
- maxElementsInIOV = 1;
- }
-
+#ifdef _linux_
+ ui32 maxElementsInIOV = Min<ui32>(iovLimit, sysconf(_SC_IOV_MAX));
+#else
+ ui32 maxElementsInIOV = 64;
+#endif
+ if (Params.Encryption) {
+ maxElementsInIOV = 1;
+ }
+
// vector of write buffers with preallocated stack space
TStackVec<TConstIoVec, iovLimit> wbuffers;
-
- LOG_DEBUG_IC_SESSION("ICS30", "WriteData WriteBlockedByFullSendBuffer# %s SendQueue.size# %zu",
- ReceiveContext->WriteBlockedByFullSendBuffer ? "true" : "false", SendQueue.size());
-
- // update last confirmed packet number if it has changed
- if (SendQueuePos != SendQueue.end()) {
- SendQueuePos->UpdateConfirmIfPossible(ReceiveContext->GetLastProcessedPacketSerial());
- }
-
- while (SendQueuePos != SendQueue.end() && !ReceiveContext->WriteBlockedByFullSendBuffer) {
- for (auto it = SendQueuePos; it != SendQueue.end() && wbuffers.size() < maxElementsInIOV; ++it) {
+
+ LOG_DEBUG_IC_SESSION("ICS30", "WriteData WriteBlockedByFullSendBuffer# %s SendQueue.size# %zu",
+ ReceiveContext->WriteBlockedByFullSendBuffer ? "true" : "false", SendQueue.size());
+
+ // update last confirmed packet number if it has changed
+ if (SendQueuePos != SendQueue.end()) {
+ SendQueuePos->UpdateConfirmIfPossible(ReceiveContext->GetLastProcessedPacketSerial());
+ }
+
+ while (SendQueuePos != SendQueue.end() && !ReceiveContext->WriteBlockedByFullSendBuffer) {
+ for (auto it = SendQueuePos; it != SendQueue.end() && wbuffers.size() < maxElementsInIOV; ++it) {
it->AppendToIoVector(wbuffers, maxElementsInIOV);
- }
-
+ }
+
const struct iovec* iovec = reinterpret_cast<const struct iovec*>(wbuffers.data());
int iovcnt = wbuffers.size();
-
+
Y_VERIFY(iovcnt > 0);
Y_VERIFY(iovec->iov_len > 0);
-
- TString err;
- ssize_t r = 0;
- do {
-#ifndef _win_
- r = iovcnt == 1 ? Socket->Send(iovec[0].iov_base, iovec[0].iov_len, &err) : Socket->WriteV(iovec, iovcnt);
-#else
- r = Socket->Send(iovec[0].iov_base, iovec[0].iov_len, &err);
-#endif
+
+ TString err;
+ ssize_t r = 0;
+ do {
+#ifndef _win_
+ r = iovcnt == 1 ? Socket->Send(iovec[0].iov_base, iovec[0].iov_len, &err) : Socket->WriteV(iovec, iovcnt);
+#else
+ r = Socket->Send(iovec[0].iov_base, iovec[0].iov_len, &err);
+#endif
Proxy->Metrics->IncSendSyscalls();
- } while (r == -EINTR);
-
- LOG_DEBUG_IC_SESSION("ICS16", "written# %zd iovcnt# %d err# %s", r, iovcnt, err.data());
-
+ } while (r == -EINTR);
+
+ LOG_DEBUG_IC_SESSION("ICS16", "written# %zd iovcnt# %d err# %s", r, iovcnt, err.data());
+
wbuffers.clear();
-
+
if (r > 0) {
Y_VERIFY(static_cast<size_t>(r) <= BytesUnwritten);
BytesUnwritten -= r;
- written += r;
+ written += r;
ui64 packets = 0;
-
+
// advance SendQueuePos to eat all processed items
for (size_t amount = r; amount && SendQueuePos->DropBufs(amount); ++SendQueuePos) {
- if (!SendQueuePos->IsEmpty()) {
- LastSentSerial = Max(LastSentSerial, SendQueuePos->GetSerial());
- }
+ if (!SendQueuePos->IsEmpty()) {
+ LastSentSerial = Max(LastSentSerial, SendQueuePos->GetSerial());
+ }
++PacketsWrittenToSocket;
++packets;
LWTRACK(PacketWrittenToSocket, SendQueuePos->Orbit, Proxy->PeerNodeId, PacketsWrittenToSocket, SendQueuePos->TriedWriting, SendQueuePos->GetDataSize(), BytesUnwritten, GetWriteBlockedTotal(), (SOCKET)*Socket);
}
LWPROBE(WriteToSocket, Proxy->PeerNodeId, r, packets, PacketsWrittenToSocket, BytesUnwritten, GetWriteBlockedTotal(), (SOCKET)*Socket);
- } else if (-r != EAGAIN && -r != EWOULDBLOCK) {
- const TString message = r == 0 ? "connection closed by peer"
- : err ? err
- : Sprintf("socket: %s", strerror(-r));
+ } else if (-r != EAGAIN && -r != EWOULDBLOCK) {
+ const TString message = r == 0 ? "connection closed by peer"
+ : err ? err
+ : Sprintf("socket: %s", strerror(-r));
LOG_NOTICE_NET(Proxy->PeerNodeId, "%s", message.data());
- if (written) {
+ if (written) {
Proxy->Metrics->AddTotalBytesWritten(written);
- }
- return ReestablishConnectionWithHandshake(r == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-r));
+ }
+ return ReestablishConnectionWithHandshake(r == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-r));
} else {
- // we have to do some hack for secure socket -- mark the packet as 'tried writing'
- if (Params.Encryption) {
- Y_VERIFY(SendQueuePos != SendQueue.end());
- SendQueuePos->MarkTriedWriting(); // do not try to replace buffer under SSL
- }
-
+ // we have to do some hack for secure socket -- mark the packet as 'tried writing'
+ if (Params.Encryption) {
+ Y_VERIFY(SendQueuePos != SendQueue.end());
+ SendQueuePos->MarkTriedWriting(); // do not try to replace buffer under SSL
+ }
+
// we have received EAGAIN error code, this means that we can't issue more data until we have received
// TEvPollerReadyWrite event from poller; set up flag meaning this and wait for that event
- Y_VERIFY(!ReceiveContext->WriteBlockedByFullSendBuffer);
- ReceiveContext->WriteBlockedByFullSendBuffer = true;
+ Y_VERIFY(!ReceiveContext->WriteBlockedByFullSendBuffer);
+ ReceiveContext->WriteBlockedByFullSendBuffer = true;
WriteBlockedCycles = GetCycleCountFast();
LWPROBE(BlockedWrite, Proxy->PeerNodeId, SendQueue.size(), written);
- LOG_DEBUG_IC_SESSION("ICS18", "hit send buffer limit");
-
- if (PollerToken) {
- if (Params.Encryption) {
- auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
- PollerToken->Request(secure->WantRead(), secure->WantWrite());
- } else {
- PollerToken->Request(false, true);
- }
+ LOG_DEBUG_IC_SESSION("ICS18", "hit send buffer limit");
+
+ if (PollerToken) {
+ if (Params.Encryption) {
+ auto *secure = static_cast<NInterconnect::TSecureSocket*>(Socket.Get());
+ PollerToken->Request(secure->WantRead(), secure->WantWrite());
+ } else {
+ PollerToken->Request(false, true);
+ }
}
- }
- }
- }
- if (written) {
+ }
+ }
+ }
+ if (written) {
Proxy->Metrics->AddTotalBytesWritten(written);
- }
- }
-
- void TInterconnectSessionTCP::SetForcePacketTimestamp(TDuration period) {
+ }
+ }
+
+ void TInterconnectSessionTCP::SetForcePacketTimestamp(TDuration period) {
if (period != TDuration::Max()) {
- const TInstant when = TActivationContext::Now() + period;
+ const TInstant when = TActivationContext::Now() + period;
if (when < ForcePacketTimestamp) {
ForcePacketTimestamp = when;
- ScheduleFlush();
- }
- }
- }
-
- void TInterconnectSessionTCP::ScheduleFlush() {
- if (FlushSchedule.empty() || ForcePacketTimestamp < FlushSchedule.top()) {
- Schedule(ForcePacketTimestamp - TActivationContext::Now(), new TEvFlush);
- FlushSchedule.push(ForcePacketTimestamp);
- MaxFlushSchedule = Max(MaxFlushSchedule, FlushSchedule.size());
- ++FlushEventsScheduled;
- }
- }
-
- void TInterconnectSessionTCP::HandleFlush() {
- const TInstant now = TActivationContext::Now();
- while (FlushSchedule && now >= FlushSchedule.top()) {
- FlushSchedule.pop();
- }
- IssuePingRequest();
- if (Socket) {
- if (now >= ForcePacketTimestamp) {
- ++ConfirmPacketsForcedByTimeout;
- ++FlushEventsProcessed;
- MakePacket(false); // just generate confirmation packet if we have preconditions for this
- } else if (ForcePacketTimestamp != TInstant::Max()) {
- ScheduleFlush();
+ ScheduleFlush();
}
+ }
+ }
+
+ void TInterconnectSessionTCP::ScheduleFlush() {
+ if (FlushSchedule.empty() || ForcePacketTimestamp < FlushSchedule.top()) {
+ Schedule(ForcePacketTimestamp - TActivationContext::Now(), new TEvFlush);
+ FlushSchedule.push(ForcePacketTimestamp);
+ MaxFlushSchedule = Max(MaxFlushSchedule, FlushSchedule.size());
+ ++FlushEventsScheduled;
}
- }
-
- void TInterconnectSessionTCP::ResetFlushLogic() {
+ }
+
+ void TInterconnectSessionTCP::HandleFlush() {
+ const TInstant now = TActivationContext::Now();
+ while (FlushSchedule && now >= FlushSchedule.top()) {
+ FlushSchedule.pop();
+ }
+ IssuePingRequest();
+ if (Socket) {
+ if (now >= ForcePacketTimestamp) {
+ ++ConfirmPacketsForcedByTimeout;
+ ++FlushEventsProcessed;
+ MakePacket(false); // just generate confirmation packet if we have preconditions for this
+ } else if (ForcePacketTimestamp != TInstant::Max()) {
+ ScheduleFlush();
+ }
+ }
+ }
+
+ void TInterconnectSessionTCP::ResetFlushLogic() {
ForcePacketTimestamp = TInstant::Max();
UnconfirmedBytes = 0;
- const TDuration ping = Proxy->Common->Settings.PingPeriod;
- if (ping != TDuration::Zero() && !NumEventsInReadyChannels) {
- SetForcePacketTimestamp(ping);
- }
- }
-
- void TInterconnectSessionTCP::TrimSendQueueCache() {
- static constexpr size_t maxItems = 32;
- static constexpr size_t trimThreshold = maxItems * 2;
- if (SendQueueCache.size() >= trimThreshold) {
- auto it = SendQueueCache.end();
- for (size_t n = SendQueueCache.size() - maxItems; n; --n) {
- --it;
- }
-
- auto ev = std::make_unique<TEvFreeItems>();
- ev->Items.splice(ev->Items.end(), SendQueueCache, it, SendQueueCache.end());
- ev->NumBytes = ev->Items.size() * sizeof(TTcpPacketOutTask);
- if (ev->GetInLineForDestruction(Proxy->Common)) {
- Send(Proxy->Common->DestructorId, ev.release());
- }
+ const TDuration ping = Proxy->Common->Settings.PingPeriod;
+ if (ping != TDuration::Zero() && !NumEventsInReadyChannels) {
+ SetForcePacketTimestamp(ping);
}
- }
-
+ }
+
+ void TInterconnectSessionTCP::TrimSendQueueCache() {
+ static constexpr size_t maxItems = 32;
+ static constexpr size_t trimThreshold = maxItems * 2;
+ if (SendQueueCache.size() >= trimThreshold) {
+ auto it = SendQueueCache.end();
+ for (size_t n = SendQueueCache.size() - maxItems; n; --n) {
+ --it;
+ }
+
+ auto ev = std::make_unique<TEvFreeItems>();
+ ev->Items.splice(ev->Items.end(), SendQueueCache, it, SendQueueCache.end());
+ ev->NumBytes = ev->Items.size() * sizeof(TTcpPacketOutTask);
+ if (ev->GetInLineForDestruction(Proxy->Common)) {
+ Send(Proxy->Common->DestructorId, ev.release());
+ }
+ }
+ }
+
ui64 TInterconnectSessionTCP::MakePacket(bool data, TMaybe<ui64> pingMask) {
Y_VERIFY(Socket);
-
+
TSendQueue::iterator packet;
if (SendQueueCache) {
// we have entries in cache, take one and move it to the end of SendQueue
@@ -729,191 +729,191 @@ namespace NActors {
packet->Reuse(); // reset packet to initial state
} else {
// we have to allocate new packet, so just do it
- LWPROBE_IF_TOO_LONG(SlowICAllocPacketBuffer, Proxy->PeerNodeId, ms) {
- packet = SendQueue.emplace(SendQueue.end(), Params);
+ LWPROBE_IF_TOO_LONG(SlowICAllocPacketBuffer, Proxy->PeerNodeId, ms) {
+ packet = SendQueue.emplace(SendQueue.end(), Params);
}
- }
-
- // update send queue position
- if (SendQueuePos == SendQueue.end()) {
- SendQueuePos = packet; // start sending this packet if we are not sending anything for now
- }
-
- ui64 serial = 0;
-
+ }
+
+ // update send queue position
+ if (SendQueuePos == SendQueue.end()) {
+ SendQueuePos = packet; // start sending this packet if we are not sending anything for now
+ }
+
+ ui64 serial = 0;
+
if (data) {
- // generate serial for this data packet
- serial = ++OutputCounter;
-
- // fill the data packet
- Y_VERIFY(NumEventsInReadyChannels);
- LWPROBE_IF_TOO_LONG(SlowICFillSendingBuffer, Proxy->PeerNodeId, ms) {
- FillSendingBuffer(*packet, serial);
+ // generate serial for this data packet
+ serial = ++OutputCounter;
+
+ // fill the data packet
+ Y_VERIFY(NumEventsInReadyChannels);
+ LWPROBE_IF_TOO_LONG(SlowICFillSendingBuffer, Proxy->PeerNodeId, ms) {
+ FillSendingBuffer(*packet, serial);
}
- Y_VERIFY(!packet->IsEmpty());
-
- InflightDataAmount += packet->GetDataSize();
+ Y_VERIFY(!packet->IsEmpty());
+
+ InflightDataAmount += packet->GetDataSize();
Proxy->Metrics->AddInflightDataAmount(packet->GetDataSize());
- if (InflightDataAmount > GetTotalInflightAmountOfData()) {
+ if (InflightDataAmount > GetTotalInflightAmountOfData()) {
Proxy->Metrics->IncInflyLimitReach();
}
-
+
if (AtomicGet(ReceiveContext->ControlPacketId) == 0) {
AtomicSet(ReceiveContext->ControlPacketSendTimer, GetCycleCountFast());
AtomicSet(ReceiveContext->ControlPacketId, OutputCounter);
}
// update payload activity timer
- LastPayloadActivityTimestamp = TActivationContext::Now();
- } else if (pingMask) {
- serial = *pingMask;
-
- // make this packet a priority one
- if (SendQueuePos != packet) {
- Y_VERIFY(SendQueuePos != SendQueue.end());
- if (SendQueuePos->IsAtBegin()) {
- // insert this packet just before the next being sent and step back
- SendQueue.splice(SendQueuePos, SendQueue, packet);
- --SendQueuePos;
- Y_VERIFY(SendQueuePos == packet);
- } else {
- // current packet is already being sent, so move new packet just after it
- SendQueue.splice(std::next(SendQueuePos), SendQueue, packet);
- }
- }
+ LastPayloadActivityTimestamp = TActivationContext::Now();
+ } else if (pingMask) {
+ serial = *pingMask;
+
+ // make this packet a priority one
+ if (SendQueuePos != packet) {
+ Y_VERIFY(SendQueuePos != SendQueue.end());
+ if (SendQueuePos->IsAtBegin()) {
+ // insert this packet just before the next being sent and step back
+ SendQueue.splice(SendQueuePos, SendQueue, packet);
+ --SendQueuePos;
+ Y_VERIFY(SendQueuePos == packet);
+ } else {
+ // current packet is already being sent, so move new packet just after it
+ SendQueue.splice(std::next(SendQueuePos), SendQueue, packet);
+ }
+ }
}
-
- const ui64 lastInputSerial = ReceiveContext->GetLastProcessedPacketSerial();
- packet->SetMetadata(serial, lastInputSerial);
+
+ const ui64 lastInputSerial = ReceiveContext->GetLastProcessedPacketSerial();
+ packet->SetMetadata(serial, lastInputSerial);
packet->Sign();
-
+
// count number of bytes pending for write
ui64 packetSize = (Params.UseModernFrame ? sizeof(TTcpPacketHeader_v2) : sizeof(TTcpPacketHeader_v1)) + packet->GetDataSize();
BytesUnwritten += packetSize;
-
- LOG_DEBUG_IC_SESSION("ICS22", "outgoing packet Serial# %" PRIu64 " Confirm# %" PRIu64 " DataSize# %zu"
- " InflightDataAmount# %" PRIu64 " BytesUnwritten# %" PRIu64, serial, lastInputSerial, packet->GetDataSize(),
- InflightDataAmount, BytesUnwritten);
-
+
+ LOG_DEBUG_IC_SESSION("ICS22", "outgoing packet Serial# %" PRIu64 " Confirm# %" PRIu64 " DataSize# %zu"
+ " InflightDataAmount# %" PRIu64 " BytesUnwritten# %" PRIu64, serial, lastInputSerial, packet->GetDataSize(),
+ InflightDataAmount, BytesUnwritten);
+
// reset forced packet sending timestamp as we have confirmed all received data
- ResetFlushLogic();
-
+ ResetFlushLogic();
+
++PacketsGenerated;
LWTRACK(PacketGenerated, packet->Orbit, Proxy->PeerNodeId, BytesUnwritten, InflightDataAmount, PacketsGenerated, packetSize);
-
+
if (!data) {
- WriteData();
+ WriteData();
}
return packetSize;
- }
-
- bool TInterconnectSessionTCP::DropConfirmed(ui64 confirm) {
- LOG_DEBUG_IC_SESSION("ICS23", "confirm count: %" PRIu64, confirm);
-
- Y_VERIFY(LastConfirmed <= confirm && confirm <= LastSentSerial && LastSentSerial <= OutputCounter,
- "%s confirm# %" PRIu64 " LastConfirmed# %" PRIu64 " OutputCounter# %" PRIu64 " LastSentSerial# %" PRIu64,
- LogPrefix.data(), confirm, LastConfirmed, OutputCounter, LastSentSerial);
+ }
+
+ bool TInterconnectSessionTCP::DropConfirmed(ui64 confirm) {
+ LOG_DEBUG_IC_SESSION("ICS23", "confirm count: %" PRIu64, confirm);
+
+ Y_VERIFY(LastConfirmed <= confirm && confirm <= LastSentSerial && LastSentSerial <= OutputCounter,
+ "%s confirm# %" PRIu64 " LastConfirmed# %" PRIu64 " OutputCounter# %" PRIu64 " LastSentSerial# %" PRIu64,
+ LogPrefix.data(), confirm, LastConfirmed, OutputCounter, LastSentSerial);
LastConfirmed = confirm;
-
+
ui64 droppedDataAmount = 0;
ui32 numDropped = 0;
-
+
// drop confirmed packets; this also includes any auxiliary packets as their serial is set to zero, effectively
// making Serial <= confirm true
TSendQueue::iterator it;
- ui64 lastDroppedSerial = 0;
- for (it = SendQueue.begin(); it != SendQueuePos && it->Confirmed(confirm); ++it) {
- if (!it->IsEmpty()) {
- lastDroppedSerial = it->GetSerial();
- }
- droppedDataAmount += it->GetDataSize();
+ ui64 lastDroppedSerial = 0;
+ for (it = SendQueue.begin(); it != SendQueuePos && it->Confirmed(confirm); ++it) {
+ if (!it->IsEmpty()) {
+ lastDroppedSerial = it->GetSerial();
+ }
+ droppedDataAmount += it->GetDataSize();
++numDropped;
- }
- SendQueueCache.splice(SendQueueCache.begin(), SendQueue, SendQueue.begin(), it);
- TrimSendQueueCache();
- ChannelScheduler->ForEach([&](TEventOutputChannel& channel) {
- channel.DropConfirmed(lastDroppedSerial);
- });
-
+ }
+ SendQueueCache.splice(SendQueueCache.begin(), SendQueue, SendQueue.begin(), it);
+ TrimSendQueueCache();
+ ChannelScheduler->ForEach([&](TEventOutputChannel& channel) {
+ channel.DropConfirmed(lastDroppedSerial);
+ });
+
const ui64 current = InflightDataAmount;
const ui64 limit = GetTotalInflightAmountOfData();
const bool unblockedSomething = current >= limit && current < limit + droppedDataAmount;
-
+
PacketsConfirmed += numDropped;
- InflightDataAmount -= droppedDataAmount;
+ InflightDataAmount -= droppedDataAmount;
Proxy->Metrics->SubInflightDataAmount(droppedDataAmount);
LWPROBE(DropConfirmed, Proxy->PeerNodeId, droppedDataAmount, InflightDataAmount);
-
- LOG_DEBUG_IC_SESSION("ICS24", "exit InflightDataAmount: %" PRIu64 " bytes droppedDataAmount: %" PRIu64 " bytes"
- " dropped %" PRIu32 " packets", InflightDataAmount, droppedDataAmount, numDropped);
-
- Pool->Trim(); // send any unsent free requests
-
- return unblockedSomething;
+
+ LOG_DEBUG_IC_SESSION("ICS24", "exit InflightDataAmount: %" PRIu64 " bytes droppedDataAmount: %" PRIu64 " bytes"
+ " dropped %" PRIu32 " packets", InflightDataAmount, droppedDataAmount, numDropped);
+
+ Pool->Trim(); // send any unsent free requests
+
+ return unblockedSomething;
}
-
- void TInterconnectSessionTCP::FillSendingBuffer(TTcpPacketOutTask& task, ui64 serial) {
- ui32 bytesGenerated = 0;
-
- Y_VERIFY(NumEventsInReadyChannels);
- while (NumEventsInReadyChannels) {
- TEventOutputChannel *channel = ChannelScheduler->PickChannelWithLeastConsumedWeight();
- Y_VERIFY_DEBUG(!channel->IsEmpty());
-
- // generate some data within this channel
- const ui64 netBefore = channel->GetBufferedAmountOfData();
- ui64 gross = 0;
- const bool eventDone = channel->FeedBuf(task, serial, &gross);
- channel->UnaccountedTraffic += gross;
- const ui64 netAfter = channel->GetBufferedAmountOfData();
- Y_VERIFY_DEBUG(netAfter <= netBefore); // net amount should shrink
- const ui64 net = netBefore - netAfter; // number of net bytes serialized
-
+
+ void TInterconnectSessionTCP::FillSendingBuffer(TTcpPacketOutTask& task, ui64 serial) {
+ ui32 bytesGenerated = 0;
+
+ Y_VERIFY(NumEventsInReadyChannels);
+ while (NumEventsInReadyChannels) {
+ TEventOutputChannel *channel = ChannelScheduler->PickChannelWithLeastConsumedWeight();
+ Y_VERIFY_DEBUG(!channel->IsEmpty());
+
+ // generate some data within this channel
+ const ui64 netBefore = channel->GetBufferedAmountOfData();
+ ui64 gross = 0;
+ const bool eventDone = channel->FeedBuf(task, serial, &gross);
+ channel->UnaccountedTraffic += gross;
+ const ui64 netAfter = channel->GetBufferedAmountOfData();
+ Y_VERIFY_DEBUG(netAfter <= netBefore); // net amount should shrink
+ const ui64 net = netBefore - netAfter; // number of net bytes serialized
+
// adjust metrics for local and global queue size
- TotalOutputQueueSize -= net;
+ TotalOutputQueueSize -= net;
Proxy->Metrics->SubOutputBuffersTotalSize(net);
- bytesGenerated += gross;
- Y_VERIFY_DEBUG(!!net == !!gross && gross >= net, "net# %" PRIu64 " gross# %" PRIu64, net, gross);
-
- // return it back to queue or delete, depending on whether this channel is still working or not
- ChannelScheduler->FinishPick(gross, EqualizeCounter);
-
- // update some stats if the packet was fully serialized
- if (eventDone) {
- ++MessagesWrittenToBuffer;
-
- Y_VERIFY(NumEventsInReadyChannels);
- --NumEventsInReadyChannels;
-
- if (!NumEventsInReadyChannels) {
- SetOutputStuckFlag(false);
- }
- }
-
- if (!gross) { // no progress -- almost full packet buffer
- break;
- }
- }
-
+ bytesGenerated += gross;
+ Y_VERIFY_DEBUG(!!net == !!gross && gross >= net, "net# %" PRIu64 " gross# %" PRIu64, net, gross);
+
+ // return it back to queue or delete, depending on whether this channel is still working or not
+ ChannelScheduler->FinishPick(gross, EqualizeCounter);
+
+ // update some stats if the packet was fully serialized
+ if (eventDone) {
+ ++MessagesWrittenToBuffer;
+
+ Y_VERIFY(NumEventsInReadyChannels);
+ --NumEventsInReadyChannels;
+
+ if (!NumEventsInReadyChannels) {
+ SetOutputStuckFlag(false);
+ }
+ }
+
+ if (!gross) { // no progress -- almost full packet buffer
+ break;
+ }
+ }
+
LWTRACK(FillSendingBuffer, task.Orbit, Proxy->PeerNodeId, bytesGenerated, NumEventsInReadyChannels, WriteBlockedTotal);
- Y_VERIFY(bytesGenerated); // ensure we are not stalled in serialization
- }
-
- ui32 TInterconnectSessionTCP::CalculateQueueUtilization() {
- SwitchStuckPeriod();
- ui64 sumBusy = 0, sumPeriod = 0;
- for (auto iter = OutputQueueUtilization.begin(); iter != OutputQueueUtilization.end() - 1; ++iter) {
- sumBusy += iter->first;
- sumPeriod += iter->second;
- }
- return sumBusy * 1000000 / sumPeriod;
- }
-
- void TInterconnectSessionTCP::SendUpdateToWhiteboard(bool connected) {
- const ui32 utilization = Socket ? CalculateQueueUtilization() : 0;
-
- if (const auto& callback = Proxy->Common->UpdateWhiteboard) {
+ Y_VERIFY(bytesGenerated); // ensure we are not stalled in serialization
+ }
+
+ ui32 TInterconnectSessionTCP::CalculateQueueUtilization() {
+ SwitchStuckPeriod();
+ ui64 sumBusy = 0, sumPeriod = 0;
+ for (auto iter = OutputQueueUtilization.begin(); iter != OutputQueueUtilization.end() - 1; ++iter) {
+ sumBusy += iter->first;
+ sumPeriod += iter->second;
+ }
+ return sumBusy * 1000000 / sumPeriod;
+ }
+
+ void TInterconnectSessionTCP::SendUpdateToWhiteboard(bool connected) {
+ const ui32 utilization = Socket ? CalculateQueueUtilization() : 0;
+
+ if (const auto& callback = Proxy->Common->UpdateWhiteboard) {
enum class EFlag {
GREEN,
YELLOW,
@@ -921,59 +921,59 @@ namespace NActors {
RED,
};
EFlag flagState = EFlag::RED;
-
+
if (Socket) {
flagState = EFlag::GREEN;
-
+
do {
- auto lastInputDelay = TActivationContext::Now() - LastInputActivityTimestamp;
+ auto lastInputDelay = TActivationContext::Now() - LastInputActivityTimestamp;
if (lastInputDelay * 4 >= GetDeadPeerTimeout() * 3) {
flagState = EFlag::ORANGE;
break;
} else if (lastInputDelay * 2 >= GetDeadPeerTimeout()) {
flagState = EFlag::YELLOW;
}
-
+
// check utilization
- if (utilization > 875000) { // 7/8
+ if (utilization > 875000) { // 7/8
flagState = EFlag::ORANGE;
break;
- } else if (utilization > 500000) { // 1/2
+ } else if (utilization > 500000) { // 1/2
flagState = EFlag::YELLOW;
}
} while (false);
}
-
+
callback(Proxy->Metrics->GetHumanFriendlyPeerHostName(),
connected,
flagState == EFlag::GREEN,
flagState == EFlag::YELLOW,
flagState == EFlag::ORANGE,
flagState == EFlag::RED,
- TlsActivationContext->ExecutorThread.ActorSystem);
- }
-
- if (connected) {
- Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
- }
- }
-
+ TlsActivationContext->ExecutorThread.ActorSystem);
+ }
+
+ if (connected) {
+ Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
+ }
+ }
+
void TInterconnectSessionTCP::SetOutputStuckFlag(bool state) {
if (OutputStuckFlag == state)
return;
-
+
if (OutputQueueUtilization.Size() == 0)
return;
-
+
auto& lastpair = OutputQueueUtilization.Last();
if (state)
lastpair.first -= GetCycleCountFast();
else
lastpair.first += GetCycleCountFast();
-
+
OutputStuckFlag = state;
}
-
+
void TInterconnectSessionTCP::SwitchStuckPeriod() {
auto now = GetCycleCountFast();
if (OutputQueueUtilization.Size() != 0) {
@@ -984,51 +984,51 @@ namespace NActors {
}
OutputQueueUtilization.Push(std::pair<ui64, ui64>(0, now));
- if (OutputStuckFlag)
+ if (OutputStuckFlag)
OutputQueueUtilization.Last().first -= now;
- }
-
- TDuration TInterconnectSessionTCP::GetDeadPeerTimeout() const {
- return Coalesce(Proxy->Common->Settings.DeadPeer, DEFAULT_DEADPEER_TIMEOUT);
- }
-
- TDuration TInterconnectSessionTCP::GetCloseOnIdleTimeout() const {
- return Proxy->Common->Settings.CloseOnIdle;
- }
-
- TDuration TInterconnectSessionTCP::GetLostConnectionTimeout() const {
- return Coalesce(Proxy->Common->Settings.LostConnection, DEFAULT_LOST_CONNECTION_TIMEOUT);
- }
-
- ui32 TInterconnectSessionTCP::GetTotalInflightAmountOfData() const {
- return Coalesce(Proxy->Common->Settings.TotalInflightAmountOfData, DEFAULT_TOTAL_INFLIGHT_DATA);
- }
-
- ui64 TInterconnectSessionTCP::GetMaxCyclesPerEvent() const {
+ }
+
+ TDuration TInterconnectSessionTCP::GetDeadPeerTimeout() const {
+ return Coalesce(Proxy->Common->Settings.DeadPeer, DEFAULT_DEADPEER_TIMEOUT);
+ }
+
+ TDuration TInterconnectSessionTCP::GetCloseOnIdleTimeout() const {
+ return Proxy->Common->Settings.CloseOnIdle;
+ }
+
+ TDuration TInterconnectSessionTCP::GetLostConnectionTimeout() const {
+ return Coalesce(Proxy->Common->Settings.LostConnection, DEFAULT_LOST_CONNECTION_TIMEOUT);
+ }
+
+ ui32 TInterconnectSessionTCP::GetTotalInflightAmountOfData() const {
+ return Coalesce(Proxy->Common->Settings.TotalInflightAmountOfData, DEFAULT_TOTAL_INFLIGHT_DATA);
+ }
+
+ ui64 TInterconnectSessionTCP::GetMaxCyclesPerEvent() const {
return DurationToCycles(TDuration::MicroSeconds(50));
- }
-
- void TInterconnectSessionTCP::IssuePingRequest() {
- const TInstant now = TActivationContext::Now();
- if (now >= LastPingTimestamp + PingPeriodicity) {
- LOG_DEBUG_IC_SESSION("ICS22", "Issuing ping request");
- if (Socket) {
+ }
+
+ void TInterconnectSessionTCP::IssuePingRequest() {
+ const TInstant now = TActivationContext::Now();
+ if (now >= LastPingTimestamp + PingPeriodicity) {
+ LOG_DEBUG_IC_SESSION("ICS22", "Issuing ping request");
+ if (Socket) {
MakePacket(false, GetCycleCountFast() | TTcpPacketBuf::PingRequestMask);
- }
- if (Socket) {
- MakePacket(false, TInstant::Now().MicroSeconds() | TTcpPacketBuf::ClockMask);
- }
- LastPingTimestamp = now;
- }
- }
-
- void TInterconnectSessionTCP::Handle(TEvProcessPingRequest::TPtr ev) {
- if (Socket) {
- MakePacket(false, ev->Get()->Payload | TTcpPacketBuf::PingResponseMask);
- }
- }
-
- void TInterconnectSessionTCP::GenerateHttpInfo(TStringStream& str) {
+ }
+ if (Socket) {
+ MakePacket(false, TInstant::Now().MicroSeconds() | TTcpPacketBuf::ClockMask);
+ }
+ LastPingTimestamp = now;
+ }
+ }
+
+ void TInterconnectSessionTCP::Handle(TEvProcessPingRequest::TPtr ev) {
+ if (Socket) {
+ MakePacket(false, ev->Get()->Payload | TTcpPacketBuf::PingResponseMask);
+ }
+ }
+
+ void TInterconnectSessionTCP::GenerateHttpInfo(TStringStream& str) {
HTML(str) {
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
@@ -1045,76 +1045,76 @@ namespace NActors {
str << "Value";
}
}
- }
+ }
TABLEBODY() {
TABLER() {
TABLED() {
- str << "Encryption";
- }
- TABLED() {
- str << (Params.Encryption ? "<font color=green>Enabled</font>" : "<font color=red>Disabled</font>");
- }
- }
- if (auto *x = dynamic_cast<NInterconnect::TSecureSocket*>(Socket.Get())) {
- TABLER() {
- TABLED() {
- str << "Cipher name";
- }
- TABLED() {
- str << x->GetCipherName();
- }
- }
- TABLER() {
- TABLED() {
- str << "Cipher bits";
- }
- TABLED() {
- str << x->GetCipherBits();
- }
- }
- TABLER() {
- TABLED() {
- str << "Protocol";
- }
- TABLED() {
- str << x->GetProtocolName();
- }
- }
- TABLER() {
- TABLED() {
- str << "Peer CN";
- }
- TABLED() {
- str << x->GetPeerCommonName();
- }
- }
- }
- TABLER() {
- TABLED() { str << "AuthOnly CN"; }
- TABLED() { str << Params.AuthCN; }
- }
- TABLER() {
- TABLED() {
- str << "Local scope id";
- }
- TABLED() {
- str << ScopeIdToString(Proxy->Common->LocalScopeId);
- }
- }
- TABLER() {
- TABLED() {
- str << "Peer scope id";
- }
- TABLED() {
- str << ScopeIdToString(Params.PeerScopeId);
- }
- }
- TABLER() {
- TABLED() {
+ str << "Encryption";
+ }
+ TABLED() {
+ str << (Params.Encryption ? "<font color=green>Enabled</font>" : "<font color=red>Disabled</font>");
+ }
+ }
+ if (auto *x = dynamic_cast<NInterconnect::TSecureSocket*>(Socket.Get())) {
+ TABLER() {
+ TABLED() {
+ str << "Cipher name";
+ }
+ TABLED() {
+ str << x->GetCipherName();
+ }
+ }
+ TABLER() {
+ TABLED() {
+ str << "Cipher bits";
+ }
+ TABLED() {
+ str << x->GetCipherBits();
+ }
+ }
+ TABLER() {
+ TABLED() {
+ str << "Protocol";
+ }
+ TABLED() {
+ str << x->GetProtocolName();
+ }
+ }
+ TABLER() {
+ TABLED() {
+ str << "Peer CN";
+ }
+ TABLED() {
+ str << x->GetPeerCommonName();
+ }
+ }
+ }
+ TABLER() {
+ TABLED() { str << "AuthOnly CN"; }
+ TABLED() { str << Params.AuthCN; }
+ }
+ TABLER() {
+ TABLED() {
+ str << "Local scope id";
+ }
+ TABLED() {
+ str << ScopeIdToString(Proxy->Common->LocalScopeId);
+ }
+ }
+ TABLER() {
+ TABLED() {
+ str << "Peer scope id";
+ }
+ TABLED() {
+ str << ScopeIdToString(Params.PeerScopeId);
+ }
+ }
+ TABLER() {
+ TABLED() {
str << "This page generated at";
}
TABLED() {
- str << TActivationContext::Now() << " / " << Now();
+ str << TActivationContext::Now() << " / " << Now();
}
}
TABLER() {
@@ -1122,13 +1122,13 @@ namespace NActors {
str << "SelfID";
}
TABLED() {
- str << SelfId().ToString();
+ str << SelfId().ToString();
}
}
- TABLER() {
- TABLED() { str << "Frame version/Checksum"; }
- TABLED() { str << (!Params.UseModernFrame ? "v1/crc32c" : Params.Encryption ? "v2/none" : "v2/crc32c"); }
- }
+ TABLER() {
+ TABLED() { str << "Frame version/Checksum"; }
+ TABLED() { str << (!Params.UseModernFrame ? "v1/crc32c" : Params.Encryption ? "v2/none" : "v2/crc32c"); }
+ }
#define MON_VAR(NAME) \
TABLER() { \
TABLED() { \
@@ -1138,7 +1138,7 @@ namespace NActors {
str << NAME; \
} \
}
-
+
MON_VAR(Created)
MON_VAR(NewConnectionSet)
MON_VAR(ReceiverId)
@@ -1150,7 +1150,7 @@ namespace NActors {
MON_VAR(AtomicGet(ReceiveContext->PacketsReadFromSocket))
MON_VAR(ConfirmPacketsForcedBySize)
MON_VAR(ConfirmPacketsForcedByTimeout)
-
+
TABLER() {
TABLED() {
str << "Virtual self ID";
@@ -1158,7 +1158,7 @@ namespace NActors {
TABLED() {
str << Proxy->SessionVirtualId.ToString();
}
- }
+ }
TABLER() {
TABLED() {
str << "Virtual peer ID";
@@ -1175,54 +1175,54 @@ namespace NActors {
str << (Socket ? i64(*Socket) : -1);
}
}
-
- ui32 unsentQueueSize = Socket ? Socket->GetUnsentQueueSize() : 0;
-
+
+ ui32 unsentQueueSize = Socket ? Socket->GetUnsentQueueSize() : 0;
+
MON_VAR(OutputStuckFlag)
MON_VAR(SendQueue.size())
MON_VAR(SendQueueCache.size())
- MON_VAR(NumEventsInReadyChannels)
+ MON_VAR(NumEventsInReadyChannels)
MON_VAR(TotalOutputQueueSize)
MON_VAR(BytesUnwritten)
- MON_VAR(InflightDataAmount)
- MON_VAR(unsentQueueSize)
- MON_VAR(SendBufferSize)
+ MON_VAR(InflightDataAmount)
+ MON_VAR(unsentQueueSize)
+ MON_VAR(SendBufferSize)
MON_VAR(LastInputActivityTimestamp)
MON_VAR(LastPayloadActivityTimestamp)
MON_VAR(LastHandshakeDone)
MON_VAR(OutputCounter)
- MON_VAR(LastSentSerial)
- MON_VAR(ReceiveContext->GetLastProcessedPacketSerial())
+ MON_VAR(LastSentSerial)
+ MON_VAR(ReceiveContext->GetLastProcessedPacketSerial())
MON_VAR(LastConfirmed)
- MON_VAR(FlushSchedule.size())
- MON_VAR(MaxFlushSchedule)
- MON_VAR(FlushEventsScheduled)
- MON_VAR(FlushEventsProcessed)
-
- TString clockSkew;
- i64 x = GetClockSkew();
- if (x < 0) {
- clockSkew = Sprintf("-%s", TDuration::MicroSeconds(-x).ToString().data());
- } else {
- clockSkew = Sprintf("+%s", TDuration::MicroSeconds(x).ToString().data());
- }
-
- MON_VAR(LastPingTimestamp)
- MON_VAR(GetPingRTT())
- MON_VAR(clockSkew)
-
+ MON_VAR(FlushSchedule.size())
+ MON_VAR(MaxFlushSchedule)
+ MON_VAR(FlushEventsScheduled)
+ MON_VAR(FlushEventsProcessed)
+
+ TString clockSkew;
+ i64 x = GetClockSkew();
+ if (x < 0) {
+ clockSkew = Sprintf("-%s", TDuration::MicroSeconds(-x).ToString().data());
+ } else {
+ clockSkew = Sprintf("+%s", TDuration::MicroSeconds(x).ToString().data());
+ }
+
+ MON_VAR(LastPingTimestamp)
+ MON_VAR(GetPingRTT())
+ MON_VAR(clockSkew)
+
MON_VAR(GetDeadPeerTimeout())
- MON_VAR(GetTotalInflightAmountOfData())
- MON_VAR(GetCloseOnIdleTimeout())
- MON_VAR(Subscribers.size())
+ MON_VAR(GetTotalInflightAmountOfData())
+ MON_VAR(GetCloseOnIdleTimeout())
+ MON_VAR(Subscribers.size())
}
- }
- }
- }
- }
- }
-
- void CreateSessionKillingActor(TInterconnectProxyCommon::TPtr common) {
- TlsActivationContext->ExecutorThread.ActorSystem->Register(new TInterconnectSessionKiller(common));
+ }
+ }
+ }
+ }
+ }
+
+ void CreateSessionKillingActor(TInterconnectProxyCommon::TPtr common) {
+ TlsActivationContext->ExecutorThread.ActorSystem->Register(new TInterconnectSessionKiller(common));
}
-}
+}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_session.h b/library/cpp/actors/interconnect/interconnect_tcp_session.h
index 7fc00dbcc5a..21b121ff389 100644
--- a/library/cpp/actors/interconnect/interconnect_tcp_session.h
+++ b/library/cpp/actors/interconnect/interconnect_tcp_session.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/core/events.h>
@@ -12,36 +12,36 @@
#include <library/cpp/actors/util/recentwnd.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
-
-#include <util/generic/queue.h>
-#include <util/generic/deque.h>
-#include <util/datetime/cputimer.h>
-
-#include "interconnect_impl.h"
-#include "poller_tcp.h"
-#include "poller_actor.h"
-#include "interconnect_channel.h"
+
+#include <util/generic/queue.h>
+#include <util/generic/deque.h>
+#include <util/datetime/cputimer.h>
+
+#include "interconnect_impl.h"
+#include "poller_tcp.h"
+#include "poller_actor.h"
+#include "interconnect_channel.h"
#include "logging.h"
-#include "watchdog_timer.h"
-#include "event_holder_pool.h"
-#include "channel_scheduler.h"
-
-#include <unordered_set>
-#include <unordered_map>
-
-namespace NActors {
+#include "watchdog_timer.h"
+#include "event_holder_pool.h"
+#include "channel_scheduler.h"
+
+#include <unordered_set>
+#include <unordered_map>
+
+namespace NActors {
class TSlowPathChecker {
using TTraceCallback = std::function<void(double)>;
TTraceCallback Callback;
const NHPTimer::STime Start;
-
+
public:
TSlowPathChecker(TTraceCallback&& callback)
: Callback(std::move(callback))
, Start(GetCycleCountFast())
{
}
-
+
~TSlowPathChecker() {
const NHPTimer::STime end = GetCycleCountFast();
const NHPTimer::STime elapsed = end - Start;
@@ -49,265 +49,265 @@ namespace NActors {
Callback(NHPTimer::GetSeconds(elapsed) * 1000);
}
}
-
+
operator bool() const {
return false;
- }
+ }
};
-
+
#define LWPROBE_IF_TOO_LONG(...) \
if (auto __x = TSlowPathChecker{[&](double ms) { LWPROBE(__VA_ARGS__); }}) \
; \
else
-
+
class TTimeLimit {
public:
TTimeLimit(ui64 limitInCycles)
: UpperLimit(limitInCycles == 0 ? 0 : GetCycleCountFast() + limitInCycles)
{
}
-
+
TTimeLimit(ui64 startTS, ui64 limitInCycles)
: UpperLimit(limitInCycles == 0 ? 0 : startTS + limitInCycles)
{
}
-
+
bool CheckExceeded() {
return UpperLimit != 0 && GetCycleCountFast() > UpperLimit;
}
-
+
const ui64 UpperLimit;
};
-
+
static constexpr TDuration DEFAULT_DEADPEER_TIMEOUT = TDuration::Seconds(10);
- static constexpr TDuration DEFAULT_LOST_CONNECTION_TIMEOUT = TDuration::Seconds(10);
+ static constexpr TDuration DEFAULT_LOST_CONNECTION_TIMEOUT = TDuration::Seconds(10);
static constexpr ui32 DEFAULT_MAX_INFLIGHT_DATA = 10240 * 1024;
static constexpr ui32 DEFAULT_TOTAL_INFLIGHT_DATA = 4 * 10240 * 1024;
-
+
class TInterconnectProxyTCP;
-
- enum class EUpdateState : ui8 {
- NONE, // no updates generated by input session yet
- INFLIGHT, // one update is inflight, and no more pending
- INFLIGHT_AND_PENDING, // one update is inflight, and one is pending
- CONFIRMING, // confirmation inflight
- };
-
+
+ enum class EUpdateState : ui8 {
+ NONE, // no updates generated by input session yet
+ INFLIGHT, // one update is inflight, and no more pending
+ INFLIGHT_AND_PENDING, // one update is inflight, and one is pending
+ CONFIRMING, // confirmation inflight
+ };
+
struct TReceiveContext: public TAtomicRefCount<TReceiveContext> {
/* All invokations to these fields should be thread-safe */
-
+
ui64 ControlPacketSendTimer = 0;
ui64 ControlPacketId = 0;
-
+
// number of packets received by input session
TAtomic PacketsReadFromSocket = 0;
TAtomic DataPacketsReadFromSocket = 0;
-
- // last processed packet by input session
- std::atomic_uint64_t LastProcessedPacketSerial = 0;
- static constexpr uint64_t LastProcessedPacketSerialLockBit = uint64_t(1) << 63;
-
+
+ // last processed packet by input session
+ std::atomic_uint64_t LastProcessedPacketSerial = 0;
+ static constexpr uint64_t LastProcessedPacketSerialLockBit = uint64_t(1) << 63;
+
// for hardened checks
TAtomic NumInputSessions = 0;
-
- NHPTimer::STime StartTime;
-
- std::atomic<ui64> PingRTT_us = 0;
- std::atomic<i64> ClockSkew_us = 0;
-
- std::atomic<EUpdateState> UpdateState;
- static_assert(std::atomic<EUpdateState>::is_always_lock_free);
-
- bool WriteBlockedByFullSendBuffer = false;
- bool ReadPending = false;
-
- std::array<TRope, 16> ChannelArray;
- std::unordered_map<ui16, TRope> ChannelMap;
-
- TReceiveContext() {
+
+ NHPTimer::STime StartTime;
+
+ std::atomic<ui64> PingRTT_us = 0;
+ std::atomic<i64> ClockSkew_us = 0;
+
+ std::atomic<EUpdateState> UpdateState;
+ static_assert(std::atomic<EUpdateState>::is_always_lock_free);
+
+ bool WriteBlockedByFullSendBuffer = false;
+ bool ReadPending = false;
+
+ std::array<TRope, 16> ChannelArray;
+ std::unordered_map<ui16, TRope> ChannelMap;
+
+ TReceiveContext() {
GetTimeFast(&StartTime);
- }
-
- // returns false if sessions needs to be terminated and packet not to be processed
- bool AdvanceLastProcessedPacketSerial() {
- for (;;) {
- uint64_t value = LastProcessedPacketSerial.load();
- if (value & LastProcessedPacketSerialLockBit) {
- return false;
- }
- if (LastProcessedPacketSerial.compare_exchange_weak(value, value + 1)) {
- return true;
- }
- }
- }
-
- ui64 LockLastProcessedPacketSerial() {
- for (;;) {
- uint64_t value = LastProcessedPacketSerial.load();
- if (value & LastProcessedPacketSerialLockBit) {
- return value & ~LastProcessedPacketSerialLockBit;
- }
- if (LastProcessedPacketSerial.compare_exchange_strong(value, value | LastProcessedPacketSerialLockBit)) {
- return value;
- }
- }
- }
-
- void UnlockLastProcessedPacketSerial() {
- LastProcessedPacketSerial = LastProcessedPacketSerial.load() & ~LastProcessedPacketSerialLockBit;
- }
-
- ui64 GetLastProcessedPacketSerial() {
- return LastProcessedPacketSerial.load() & ~LastProcessedPacketSerialLockBit;
- }
+ }
+
+ // returns false if sessions needs to be terminated and packet not to be processed
+ bool AdvanceLastProcessedPacketSerial() {
+ for (;;) {
+ uint64_t value = LastProcessedPacketSerial.load();
+ if (value & LastProcessedPacketSerialLockBit) {
+ return false;
+ }
+ if (LastProcessedPacketSerial.compare_exchange_weak(value, value + 1)) {
+ return true;
+ }
+ }
+ }
+
+ ui64 LockLastProcessedPacketSerial() {
+ for (;;) {
+ uint64_t value = LastProcessedPacketSerial.load();
+ if (value & LastProcessedPacketSerialLockBit) {
+ return value & ~LastProcessedPacketSerialLockBit;
+ }
+ if (LastProcessedPacketSerial.compare_exchange_strong(value, value | LastProcessedPacketSerialLockBit)) {
+ return value;
+ }
+ }
+ }
+
+ void UnlockLastProcessedPacketSerial() {
+ LastProcessedPacketSerial = LastProcessedPacketSerial.load() & ~LastProcessedPacketSerialLockBit;
+ }
+
+ ui64 GetLastProcessedPacketSerial() {
+ return LastProcessedPacketSerial.load() & ~LastProcessedPacketSerialLockBit;
+ }
};
-
+
class TInputSessionTCP
- : public TActorBootstrapped<TInputSessionTCP>
- , public TInterconnectLoggingBase
- {
- enum {
- EvCheckDeadPeer = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvResumeReceiveData,
- };
-
- struct TEvCheckDeadPeer : TEventLocal<TEvCheckDeadPeer, EvCheckDeadPeer> {};
- struct TEvResumeReceiveData : TEventLocal<TEvResumeReceiveData, EvResumeReceiveData> {};
-
+ : public TActorBootstrapped<TInputSessionTCP>
+ , public TInterconnectLoggingBase
+ {
+ enum {
+ EvCheckDeadPeer = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvResumeReceiveData,
+ };
+
+ struct TEvCheckDeadPeer : TEventLocal<TEvCheckDeadPeer, EvCheckDeadPeer> {};
+ struct TEvResumeReceiveData : TEventLocal<TEvResumeReceiveData, EvResumeReceiveData> {};
+
public:
static constexpr EActivityType ActorActivityType() {
return INTERCONNECT_SESSION_TCP;
}
-
+
TInputSessionTCP(const TActorId& sessionId,
TIntrusivePtr<NInterconnect::TStreamSocket> socket,
TIntrusivePtr<TReceiveContext> context,
- TInterconnectProxyCommon::TPtr common,
+ TInterconnectProxyCommon::TPtr common,
std::shared_ptr<IInterconnectMetrics> metrics,
- ui32 nodeId,
- ui64 lastConfirmed,
- TDuration deadPeerTimeout,
- TSessionParams params);
+ ui32 nodeId,
+ ui64 lastConfirmed,
+ TDuration deadPeerTimeout,
+ TSessionParams params);
private:
friend class TActorBootstrapped<TInputSessionTCP>;
-
- void Bootstrap();
-
- STRICT_STFUNC(WorkingState,
- cFunc(TEvents::TSystem::PoisonPill, PassAway)
- hFunc(TEvPollerReady, Handle)
- hFunc(TEvPollerRegisterResult, Handle)
- cFunc(EvResumeReceiveData, HandleResumeReceiveData)
- cFunc(TEvInterconnect::TEvCloseInputSession::EventType, CloseInputSession)
- cFunc(EvCheckDeadPeer, HandleCheckDeadPeer)
- cFunc(TEvConfirmUpdate::EventType, HandleConfirmUpdate)
- )
-
+
+ void Bootstrap();
+
+ STRICT_STFUNC(WorkingState,
+ cFunc(TEvents::TSystem::PoisonPill, PassAway)
+ hFunc(TEvPollerReady, Handle)
+ hFunc(TEvPollerRegisterResult, Handle)
+ cFunc(EvResumeReceiveData, HandleResumeReceiveData)
+ cFunc(TEvInterconnect::TEvCloseInputSession::EventType, CloseInputSession)
+ cFunc(EvCheckDeadPeer, HandleCheckDeadPeer)
+ cFunc(TEvConfirmUpdate::EventType, HandleConfirmUpdate)
+ )
+
private:
- TRope IncomingData;
-
- const TActorId SessionId;
+ TRope IncomingData;
+
+ const TActorId SessionId;
TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- TPollerToken::TPtr PollerToken;
+ TPollerToken::TPtr PollerToken;
TIntrusivePtr<TReceiveContext> Context;
- TInterconnectProxyCommon::TPtr Common;
- const ui32 NodeId;
- const TSessionParams Params;
-
- // header we are currently processing (parsed from the stream)
- union {
- TTcpPacketHeader_v1 v1;
- TTcpPacketHeader_v2 v2;
- char Data[1];
- } Header;
- ui64 HeaderConfirm, HeaderSerial;
-
- size_t PayloadSize;
- ui32 ChecksumExpected, Checksum;
- bool IgnorePayload;
- TRope Payload;
- enum class EState {
- HEADER,
- PAYLOAD,
- };
- EState State = EState::HEADER;
-
- THolder<TEvUpdateFromInputSession> UpdateFromInputSession;
-
+ TInterconnectProxyCommon::TPtr Common;
+ const ui32 NodeId;
+ const TSessionParams Params;
+
+ // header we are currently processing (parsed from the stream)
+ union {
+ TTcpPacketHeader_v1 v1;
+ TTcpPacketHeader_v2 v2;
+ char Data[1];
+ } Header;
+ ui64 HeaderConfirm, HeaderSerial;
+
+ size_t PayloadSize;
+ ui32 ChecksumExpected, Checksum;
+ bool IgnorePayload;
+ TRope Payload;
+ enum class EState {
+ HEADER,
+ PAYLOAD,
+ };
+ EState State = EState::HEADER;
+
+ THolder<TEvUpdateFromInputSession> UpdateFromInputSession;
+
ui64 ConfirmedByInput;
-
+
std::shared_ptr<IInterconnectMetrics> Metrics;
-
+
bool CloseInputSessionRequested = false;
-
- void CloseInputSession();
-
- void Handle(TEvPollerReady::TPtr ev);
- void Handle(TEvPollerRegisterResult::TPtr ev);
- void HandleResumeReceiveData();
- void HandleConfirmUpdate();
- void ReceiveData();
- void ProcessHeader(size_t headerLen);
- void ProcessPayload(ui64& numDataBytes);
- void ProcessEvent(TRope& data, TEventDescr& descr);
- bool ReadMore();
-
- void ReestablishConnection(TDisconnectReason reason);
- void DestroySession(TDisconnectReason reason);
-
- TDeque<TIntrusivePtr<TRopeAlignedBuffer>> Buffers;
-
+
+ void CloseInputSession();
+
+ void Handle(TEvPollerReady::TPtr ev);
+ void Handle(TEvPollerRegisterResult::TPtr ev);
+ void HandleResumeReceiveData();
+ void HandleConfirmUpdate();
+ void ReceiveData();
+ void ProcessHeader(size_t headerLen);
+ void ProcessPayload(ui64& numDataBytes);
+ void ProcessEvent(TRope& data, TEventDescr& descr);
+ bool ReadMore();
+
+ void ReestablishConnection(TDisconnectReason reason);
+ void DestroySession(TDisconnectReason reason);
+
+ TDeque<TIntrusivePtr<TRopeAlignedBuffer>> Buffers;
+
static constexpr size_t NumPreallocatedBuffers = 16;
void PreallocateBuffers();
-
+
inline ui64 GetMaxCyclesPerEvent() const {
- return DurationToCycles(TDuration::MicroSeconds(500));
+ return DurationToCycles(TDuration::MicroSeconds(500));
}
-
- const TDuration DeadPeerTimeout;
- TInstant LastReceiveTimestamp;
- void HandleCheckDeadPeer();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // pinger logic
-
- bool NewPingProtocol = false;
- TDeque<TDuration> PingQ; // last N ping samples
- TDeque<i64> SkewQ; // last N calculated clock skew samples
-
- void HandlePingResponse(TDuration passed);
- void HandleClock(TInstant clock);
+
+ const TDuration DeadPeerTimeout;
+ TInstant LastReceiveTimestamp;
+ void HandleCheckDeadPeer();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // pinger logic
+
+ bool NewPingProtocol = false;
+ TDeque<TDuration> PingQ; // last N ping samples
+ TDeque<i64> SkewQ; // last N calculated clock skew samples
+
+ void HandlePingResponse(TDuration passed);
+ void HandleClock(TInstant clock);
};
-
+
class TInterconnectSessionTCP
- : public TActor<TInterconnectSessionTCP>
- , public TInterconnectLoggingBase
- {
+ : public TActor<TInterconnectSessionTCP>
+ , public TInterconnectLoggingBase
+ {
enum {
- EvCheckCloseOnIdle = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvCheckLostConnection,
- EvRam,
- EvTerminate,
- EvFreeItems,
+ EvCheckCloseOnIdle = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvCheckLostConnection,
+ EvRam,
+ EvTerminate,
+ EvFreeItems,
};
-
+
struct TEvCheckCloseOnIdle : TEventLocal<TEvCheckCloseOnIdle, EvCheckCloseOnIdle> {};
- struct TEvCheckLostConnection : TEventLocal<TEvCheckLostConnection, EvCheckLostConnection> {};
-
- struct TEvRam : TEventLocal<TEvRam, EvRam> {
- const bool Batching;
- TEvRam(bool batching) : Batching(batching) {}
- };
-
- struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {
- TDisconnectReason Reason;
-
- TEvTerminate(TDisconnectReason reason)
- : Reason(std::move(reason))
- {}
- };
-
+ struct TEvCheckLostConnection : TEventLocal<TEvCheckLostConnection, EvCheckLostConnection> {};
+
+ struct TEvRam : TEventLocal<TEvRam, EvRam> {
+ const bool Batching;
+ TEvRam(bool batching) : Batching(batching) {}
+ };
+
+ struct TEvTerminate : TEventLocal<TEvTerminate, EvTerminate> {
+ TDisconnectReason Reason;
+
+ TEvTerminate(TDisconnectReason reason)
+ : Reason(std::move(reason))
+ {}
+ };
+
const TInstant Created;
TInstant NewConnectionSet;
ui64 MessagesGot = 0;
@@ -315,139 +315,139 @@ namespace NActors {
ui64 PacketsGenerated = 0;
ui64 PacketsWrittenToSocket = 0;
ui64 PacketsConfirmed = 0;
-
+
public:
static constexpr EActivityType ActorActivityType() {
return INTERCONNECT_SESSION_TCP;
}
-
- TInterconnectSessionTCP(TInterconnectProxyTCP* const proxy, TSessionParams params);
- ~TInterconnectSessionTCP();
-
- void Init();
- void CloseInputSession();
-
- static TEvTerminate* NewEvTerminate(TDisconnectReason reason) {
- return new TEvTerminate(std::move(reason));
- }
-
- TDuration GetPingRTT() const {
- return TDuration::MicroSeconds(ReceiveContext->PingRTT_us);
- }
-
- i64 GetClockSkew() const {
- return ReceiveContext->ClockSkew_us;
- }
-
+
+ TInterconnectSessionTCP(TInterconnectProxyTCP* const proxy, TSessionParams params);
+ ~TInterconnectSessionTCP();
+
+ void Init();
+ void CloseInputSession();
+
+ static TEvTerminate* NewEvTerminate(TDisconnectReason reason) {
+ return new TEvTerminate(std::move(reason));
+ }
+
+ TDuration GetPingRTT() const {
+ return TDuration::MicroSeconds(ReceiveContext->PingRTT_us);
+ }
+
+ i64 GetClockSkew() const {
+ return ReceiveContext->ClockSkew_us;
+ }
+
private:
friend class TInterconnectProxyTCP;
-
- void Handle(TEvTerminate::TPtr& ev);
- void HandlePoison();
- void Terminate(TDisconnectReason reason);
- void PassAway() override;
-
- void Forward(STATEFN_SIG);
- void Subscribe(STATEFN_SIG);
- void Unsubscribe(STATEFN_SIG);
-
- STRICT_STFUNC(StateFunc,
- fFunc(TEvInterconnect::EvForward, Forward)
- cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison)
- fFunc(TEvInterconnect::TEvConnectNode::EventType, Subscribe)
- fFunc(TEvents::TEvSubscribe::EventType, Subscribe)
- fFunc(TEvents::TEvUnsubscribe::EventType, Unsubscribe)
- cFunc(TEvFlush::EventType, HandleFlush)
- hFunc(TEvPollerReady, Handle)
- hFunc(TEvPollerRegisterResult, Handle)
- hFunc(TEvUpdateFromInputSession, Handle)
- hFunc(TEvRam, HandleRam)
- hFunc(TEvCheckCloseOnIdle, CloseOnIdleWatchdog)
- hFunc(TEvCheckLostConnection, LostConnectionWatchdog)
- cFunc(TEvents::TSystem::Wakeup, SendUpdateToWhiteboard)
- hFunc(TEvSocketDisconnect, OnDisconnect)
- hFunc(TEvTerminate, Handle)
- hFunc(TEvProcessPingRequest, Handle)
- )
-
- void Handle(TEvUpdateFromInputSession::TPtr& ev);
-
- void OnDisconnect(TEvSocketDisconnect::TPtr& ev);
-
- THolder<TEvHandshakeAck> ProcessHandshakeRequest(TEvHandshakeAsk::TPtr& ev);
- void SetNewConnection(TEvHandshakeDone::TPtr& ev);
-
- TEvRam* RamInQueue = nullptr;
+
+ void Handle(TEvTerminate::TPtr& ev);
+ void HandlePoison();
+ void Terminate(TDisconnectReason reason);
+ void PassAway() override;
+
+ void Forward(STATEFN_SIG);
+ void Subscribe(STATEFN_SIG);
+ void Unsubscribe(STATEFN_SIG);
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(TEvInterconnect::EvForward, Forward)
+ cFunc(TEvents::TEvPoisonPill::EventType, HandlePoison)
+ fFunc(TEvInterconnect::TEvConnectNode::EventType, Subscribe)
+ fFunc(TEvents::TEvSubscribe::EventType, Subscribe)
+ fFunc(TEvents::TEvUnsubscribe::EventType, Unsubscribe)
+ cFunc(TEvFlush::EventType, HandleFlush)
+ hFunc(TEvPollerReady, Handle)
+ hFunc(TEvPollerRegisterResult, Handle)
+ hFunc(TEvUpdateFromInputSession, Handle)
+ hFunc(TEvRam, HandleRam)
+ hFunc(TEvCheckCloseOnIdle, CloseOnIdleWatchdog)
+ hFunc(TEvCheckLostConnection, LostConnectionWatchdog)
+ cFunc(TEvents::TSystem::Wakeup, SendUpdateToWhiteboard)
+ hFunc(TEvSocketDisconnect, OnDisconnect)
+ hFunc(TEvTerminate, Handle)
+ hFunc(TEvProcessPingRequest, Handle)
+ )
+
+ void Handle(TEvUpdateFromInputSession::TPtr& ev);
+
+ void OnDisconnect(TEvSocketDisconnect::TPtr& ev);
+
+ THolder<TEvHandshakeAck> ProcessHandshakeRequest(TEvHandshakeAsk::TPtr& ev);
+ void SetNewConnection(TEvHandshakeDone::TPtr& ev);
+
+ TEvRam* RamInQueue = nullptr;
ui64 RamStartedCycles = 0;
- void HandleRam(TEvRam::TPtr& ev);
- void GenerateTraffic();
-
- void SendUpdateToWhiteboard(bool connected = true);
- ui32 CalculateQueueUtilization();
-
- void Handle(TEvPollerReady::TPtr& ev);
- void Handle(TEvPollerRegisterResult::TPtr ev);
- void WriteData();
-
+ void HandleRam(TEvRam::TPtr& ev);
+ void GenerateTraffic();
+
+ void SendUpdateToWhiteboard(bool connected = true);
+ ui32 CalculateQueueUtilization();
+
+ void Handle(TEvPollerReady::TPtr& ev);
+ void Handle(TEvPollerRegisterResult::TPtr ev);
+ void WriteData();
+
ui64 MakePacket(bool data, TMaybe<ui64> pingMask = {});
- void FillSendingBuffer(TTcpPacketOutTask& packet, ui64 serial);
- bool DropConfirmed(ui64 confirm);
- void ShutdownSocket(TDisconnectReason reason);
-
- void StartHandshake();
- void ReestablishConnection(TEvHandshakeDone::TPtr&& ev, bool startHandshakeOnSessionClose,
- TDisconnectReason reason);
- void ReestablishConnectionWithHandshake(TDisconnectReason reason);
- void ReestablishConnectionExecute();
-
+ void FillSendingBuffer(TTcpPacketOutTask& packet, ui64 serial);
+ bool DropConfirmed(ui64 confirm);
+ void ShutdownSocket(TDisconnectReason reason);
+
+ void StartHandshake();
+ void ReestablishConnection(TEvHandshakeDone::TPtr&& ev, bool startHandshakeOnSessionClose,
+ TDisconnectReason reason);
+ void ReestablishConnectionWithHandshake(TDisconnectReason reason);
+ void ReestablishConnectionExecute();
+
TInterconnectProxyTCP* const Proxy;
-
- // various connection settings access
- TDuration GetDeadPeerTimeout() const;
- TDuration GetCloseOnIdleTimeout() const;
- TDuration GetLostConnectionTimeout() const;
- ui32 GetTotalInflightAmountOfData() const;
- ui64 GetMaxCyclesPerEvent() const;
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // pinger
-
- TInstant LastPingTimestamp;
- static constexpr TDuration PingPeriodicity = TDuration::Seconds(1);
- void IssuePingRequest();
- void Handle(TEvProcessPingRequest::TPtr ev);
-
+
+ // various connection settings access
+ TDuration GetDeadPeerTimeout() const;
+ TDuration GetCloseOnIdleTimeout() const;
+ TDuration GetLostConnectionTimeout() const;
+ ui32 GetTotalInflightAmountOfData() const;
+ ui64 GetMaxCyclesPerEvent() const;
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // pinger
+
+ TInstant LastPingTimestamp;
+ static constexpr TDuration PingPeriodicity = TDuration::Seconds(1);
+ void IssuePingRequest();
+ void Handle(TEvProcessPingRequest::TPtr ev);
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
TInstant LastInputActivityTimestamp;
TInstant LastPayloadActivityTimestamp;
TWatchdogTimer<TEvCheckCloseOnIdle> CloseOnIdleWatchdog;
- TWatchdogTimer<TEvCheckLostConnection> LostConnectionWatchdog;
-
- void OnCloseOnIdleTimerHit() {
- LOG_INFO_IC("ICS27", "CloseOnIdle timer hit, session terminated");
- Terminate(TDisconnectReason::CloseOnIdle());
- }
-
- void OnLostConnectionTimerHit() {
- LOG_ERROR_IC("ICS28", "LostConnection timer hit, session terminated");
- Terminate(TDisconnectReason::LostConnection());
- }
-
+ TWatchdogTimer<TEvCheckLostConnection> LostConnectionWatchdog;
+
+ void OnCloseOnIdleTimerHit() {
+ LOG_INFO_IC("ICS27", "CloseOnIdle timer hit, session terminated");
+ Terminate(TDisconnectReason::CloseOnIdle());
+ }
+
+ void OnLostConnectionTimerHit() {
+ LOG_ERROR_IC("ICS28", "LostConnection timer hit, session terminated");
+ Terminate(TDisconnectReason::LostConnection());
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const TSessionParams Params;
- TMaybe<TEventHolderPool> Pool;
- TMaybe<TChannelScheduler> ChannelScheduler;
+
+ const TSessionParams Params;
+ TMaybe<TEventHolderPool> Pool;
+ TMaybe<TChannelScheduler> ChannelScheduler;
ui64 TotalOutputQueueSize;
bool OutputStuckFlag;
TRecentWnd<std::pair<ui64, ui64>> OutputQueueUtilization;
- size_t NumEventsInReadyChannels = 0;
-
+ size_t NumEventsInReadyChannels = 0;
+
void SetOutputStuckFlag(bool state);
void SwitchStuckPeriod();
-
+
using TSendQueue = TList<TTcpPacketOutTask>;
TSendQueue SendQueue;
TSendQueue SendQueueCache;
@@ -455,11 +455,11 @@ namespace NActors {
ui64 WriteBlockedCycles = 0; // start of current block period
TDuration WriteBlockedTotal; // total incremental duration that session has been blocked
ui64 BytesUnwritten = 0;
-
- void TrimSendQueueCache();
-
+
+ void TrimSendQueueCache();
+
TDuration GetWriteBlockedTotal() const {
- if (ReceiveContext->WriteBlockedByFullSendBuffer) {
+ if (ReceiveContext->WriteBlockedByFullSendBuffer) {
double blockedUs = NHPTimer::GetSeconds(GetCycleCountFast() - WriteBlockedCycles) * 1000000.0;
return WriteBlockedTotal + TDuration::MicroSeconds(blockedUs); // append current blocking period if any
} else {
@@ -468,98 +468,98 @@ namespace NActors {
}
ui64 OutputCounter;
- ui64 LastSentSerial = 0;
-
+ ui64 LastSentSerial = 0;
+
TInstant LastHandshakeDone;
-
+
TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- TPollerToken::TPtr PollerToken;
- ui32 SendBufferSize;
- ui64 InflightDataAmount = 0;
-
+ TPollerToken::TPtr PollerToken;
+ ui32 SendBufferSize;
+ ui64 InflightDataAmount = 0;
+
std::unordered_map<TActorId, ui64, TActorId::THash> Subscribers;
-
+
// time at which we want to send confirmation packet even if there was no outgoing data
ui64 UnconfirmedBytes = 0;
TInstant ForcePacketTimestamp = TInstant::Max();
- TPriorityQueue<TInstant, TVector<TInstant>, std::greater<TInstant>> FlushSchedule;
- size_t MaxFlushSchedule = 0;
- ui64 FlushEventsScheduled = 0;
- ui64 FlushEventsProcessed = 0;
-
- void SetForcePacketTimestamp(TDuration period);
- void ScheduleFlush();
- void HandleFlush();
- void ResetFlushLogic();
-
- void GenerateHttpInfo(TStringStream& str);
-
+ TPriorityQueue<TInstant, TVector<TInstant>, std::greater<TInstant>> FlushSchedule;
+ size_t MaxFlushSchedule = 0;
+ ui64 FlushEventsScheduled = 0;
+ ui64 FlushEventsProcessed = 0;
+
+ void SetForcePacketTimestamp(TDuration period);
+ void ScheduleFlush();
+ void HandleFlush();
+ void ResetFlushLogic();
+
+ void GenerateHttpInfo(TStringStream& str);
+
TIntrusivePtr<TReceiveContext> ReceiveContext;
TActorId ReceiverId;
- TDuration Ping;
-
+ TDuration Ping;
+
ui64 ConfirmPacketsForcedBySize = 0;
ui64 ConfirmPacketsForcedByTimeout = 0;
-
+
ui64 LastConfirmed = 0;
-
- TEvHandshakeDone::TPtr PendingHandshakeDoneEvent;
- bool StartHandshakeOnSessionClose = false;
-
- ui64 EqualizeCounter = 0;
+
+ TEvHandshakeDone::TPtr PendingHandshakeDoneEvent;
+ bool StartHandshakeOnSessionClose = false;
+
+ ui64 EqualizeCounter = 0;
};
-
+
class TInterconnectSessionKiller
: public TActorBootstrapped<TInterconnectSessionKiller> {
ui32 RepliesReceived = 0;
ui32 RepliesNumber = 0;
TActorId LargestSession = TActorId();
ui64 MaxBufferSize = 0;
- TInterconnectProxyCommon::TPtr Common;
+ TInterconnectProxyCommon::TPtr Common;
public:
static constexpr EActivityType ActorActivityType() {
return INTERCONNECT_SESSION_KILLER;
}
- TInterconnectSessionKiller(TInterconnectProxyCommon::TPtr common)
+ TInterconnectSessionKiller(TInterconnectProxyCommon::TPtr common)
: Common(common)
{
}
- void Bootstrap() {
+ void Bootstrap() {
auto sender = SelfId();
const auto eventFabric = [&sender](const TActorId& recp) -> IEventHandle* {
auto ev = new TEvSessionBufferSizeRequest();
return new IEventHandle(recp, sender, ev, IEventHandle::FlagTrackDelivery);
};
- RepliesNumber = TlsActivationContext->ExecutorThread.ActorSystem->BroadcastToProxies(eventFabric);
+ RepliesNumber = TlsActivationContext->ExecutorThread.ActorSystem->BroadcastToProxies(eventFabric);
Become(&TInterconnectSessionKiller::StateFunc);
}
- STRICT_STFUNC(StateFunc,
- hFunc(TEvSessionBufferSizeResponse, ProcessResponse)
- cFunc(TEvents::TEvUndelivered::EventType, ProcessUndelivered)
- )
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvSessionBufferSizeResponse, ProcessResponse)
+ cFunc(TEvents::TEvUndelivered::EventType, ProcessUndelivered)
+ )
- void ProcessResponse(TEvSessionBufferSizeResponse::TPtr& ev) {
+ void ProcessResponse(TEvSessionBufferSizeResponse::TPtr& ev) {
RepliesReceived++;
if (MaxBufferSize < ev->Get()->BufferSize) {
MaxBufferSize = ev->Get()->BufferSize;
LargestSession = ev->Get()->SessionID;
}
if (RepliesReceived == RepliesNumber) {
- Send(LargestSession, new TEvents::TEvPoisonPill);
+ Send(LargestSession, new TEvents::TEvPoisonPill);
AtomicUnlock(&Common->StartedSessionKiller);
- PassAway();
+ PassAway();
}
}
- void ProcessUndelivered() {
+ void ProcessUndelivered() {
RepliesReceived++;
}
};
- void CreateSessionKillingActor(TInterconnectProxyCommon::TPtr common);
+ void CreateSessionKillingActor(TInterconnectProxyCommon::TPtr common);
-}
+}
diff --git a/library/cpp/actors/interconnect/load.cpp b/library/cpp/actors/interconnect/load.cpp
index 2a8443da71f..a31aeb07b7b 100644
--- a/library/cpp/actors/interconnect/load.cpp
+++ b/library/cpp/actors/interconnect/load.cpp
@@ -1,405 +1,405 @@
-#include "load.h"
-#include "interconnect_common.h"
-#include "events_local.h"
+#include "load.h"
+#include "interconnect_common.h"
+#include "events_local.h"
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/events.h>
#include <library/cpp/actors/core/hfunc.h>
-#include <util/generic/queue.h>
-
-namespace NInterconnect {
- using namespace NActors;
-
- enum {
- EvGenerateMessages = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvPublishResults,
- EvQueryTrafficCounter,
- EvTrafficCounter,
- };
-
- struct TEvQueryTrafficCounter : TEventLocal<TEvQueryTrafficCounter, EvQueryTrafficCounter> {};
-
- struct TEvTrafficCounter : TEventLocal<TEvTrafficCounter, EvTrafficCounter> {
- std::shared_ptr<std::atomic_uint64_t> Traffic;
-
- TEvTrafficCounter(std::shared_ptr<std::atomic_uint64_t> traffic)
- : Traffic(std::move(traffic))
- {}
- };
-
- class TLoadResponderActor : public TActor<TLoadResponderActor> {
- STRICT_STFUNC(StateFunc,
- HFunc(TEvLoadMessage, Handle);
- CFunc(TEvents::TSystem::PoisonPill, Die);
- )
-
+#include <util/generic/queue.h>
+
+namespace NInterconnect {
+ using namespace NActors;
+
+ enum {
+ EvGenerateMessages = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvPublishResults,
+ EvQueryTrafficCounter,
+ EvTrafficCounter,
+ };
+
+ struct TEvQueryTrafficCounter : TEventLocal<TEvQueryTrafficCounter, EvQueryTrafficCounter> {};
+
+ struct TEvTrafficCounter : TEventLocal<TEvTrafficCounter, EvTrafficCounter> {
+ std::shared_ptr<std::atomic_uint64_t> Traffic;
+
+ TEvTrafficCounter(std::shared_ptr<std::atomic_uint64_t> traffic)
+ : Traffic(std::move(traffic))
+ {}
+ };
+
+ class TLoadResponderActor : public TActor<TLoadResponderActor> {
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvLoadMessage, Handle);
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ )
+
void Handle(TEvLoadMessage::TPtr& ev, const TActorContext& ctx) {
- ui64 bytes = ev->Get()->CalculateSerializedSizeCached();
+ ui64 bytes = ev->Get()->CalculateSerializedSizeCached();
auto& record = ev->Get()->Record;
- auto *hops = record.MutableHops();
- while (!hops->empty() && !hops->begin()->HasNextHop()) {
- record.ClearPayload();
- ev->Get()->StripPayload();
- hops->erase(hops->begin());
- }
- if (!hops->empty()) {
- // extract actor id of the next hop
- const TActorId nextHopActorId = ActorIdFromProto(hops->begin()->GetNextHop());
- hops->erase(hops->begin());
-
- // forward message to next hop; preserve flags and cookie
- auto msg = MakeHolder<TEvLoadMessage>();
- record.Swap(&msg->Record);
- bytes += msg->CalculateSerializedSizeCached();
- ctx.Send(nextHopActorId, msg.Release(), ev->Flags, ev->Cookie);
- }
- *Traffic += bytes;
- }
-
- public:
- TLoadResponderActor(std::shared_ptr<std::atomic_uint64_t> traffic)
- : TActor(&TLoadResponderActor::StateFunc)
- , Traffic(std::move(traffic))
- {}
+ auto *hops = record.MutableHops();
+ while (!hops->empty() && !hops->begin()->HasNextHop()) {
+ record.ClearPayload();
+ ev->Get()->StripPayload();
+ hops->erase(hops->begin());
+ }
+ if (!hops->empty()) {
+ // extract actor id of the next hop
+ const TActorId nextHopActorId = ActorIdFromProto(hops->begin()->GetNextHop());
+ hops->erase(hops->begin());
+
+ // forward message to next hop; preserve flags and cookie
+ auto msg = MakeHolder<TEvLoadMessage>();
+ record.Swap(&msg->Record);
+ bytes += msg->CalculateSerializedSizeCached();
+ ctx.Send(nextHopActorId, msg.Release(), ev->Flags, ev->Cookie);
+ }
+ *Traffic += bytes;
+ }
+
+ public:
+ TLoadResponderActor(std::shared_ptr<std::atomic_uint64_t> traffic)
+ : TActor(&TLoadResponderActor::StateFunc)
+ , Traffic(std::move(traffic))
+ {}
static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::INTERCONNECT_LOAD_RESPONDER;
+ return IActor::INTERCONNECT_LOAD_RESPONDER;
}
-
- private:
- std::shared_ptr<std::atomic_uint64_t> Traffic;
- };
-
- class TLoadResponderMasterActor : public TActorBootstrapped<TLoadResponderMasterActor> {
+
+ private:
+ std::shared_ptr<std::atomic_uint64_t> Traffic;
+ };
+
+ class TLoadResponderMasterActor : public TActorBootstrapped<TLoadResponderMasterActor> {
TVector<TActorId> Slaves;
- ui32 SlaveIndex = 0;
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvLoadMessage, Handle);
- HFunc(TEvQueryTrafficCounter, Handle);
- CFunc(TEvents::TSystem::PoisonPill, Die);
- )
-
+ ui32 SlaveIndex = 0;
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvLoadMessage, Handle);
+ HFunc(TEvQueryTrafficCounter, Handle);
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ )
+
void Handle(TEvLoadMessage::TPtr& ev, const TActorContext& ctx) {
- ctx.ExecutorThread.ActorSystem->Send(ev->Forward(Slaves[SlaveIndex]));
- if (++SlaveIndex == Slaves.size()) {
- SlaveIndex = 0;
- }
- }
-
- void Handle(TEvQueryTrafficCounter::TPtr ev, const TActorContext& ctx) {
- ctx.Send(ev->Sender, new TEvTrafficCounter(Traffic));
- }
-
- void Die(const TActorContext& ctx) override {
+ ctx.ExecutorThread.ActorSystem->Send(ev->Forward(Slaves[SlaveIndex]));
+ if (++SlaveIndex == Slaves.size()) {
+ SlaveIndex = 0;
+ }
+ }
+
+ void Handle(TEvQueryTrafficCounter::TPtr ev, const TActorContext& ctx) {
+ ctx.Send(ev->Sender, new TEvTrafficCounter(Traffic));
+ }
+
+ void Die(const TActorContext& ctx) override {
for (const TActorId& actorId : Slaves) {
- ctx.Send(actorId, new TEvents::TEvPoisonPill);
- }
- TActorBootstrapped::Die(ctx);
- }
-
- public:
+ ctx.Send(actorId, new TEvents::TEvPoisonPill);
+ }
+ TActorBootstrapped::Die(ctx);
+ }
+
+ public:
static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::INTERCONNECT_LOAD_RESPONDER;
+ return IActor::INTERCONNECT_LOAD_RESPONDER;
}
- TLoadResponderMasterActor()
- {}
-
+ TLoadResponderMasterActor()
+ {}
+
void Bootstrap(const TActorContext& ctx) {
- Become(&TLoadResponderMasterActor::StateFunc);
- while (Slaves.size() < 10) {
- Slaves.push_back(ctx.Register(new TLoadResponderActor(Traffic)));
- }
- }
-
- private:
- std::shared_ptr<std::atomic_uint64_t> Traffic = std::make_shared<std::atomic_uint64_t>();
- };
-
+ Become(&TLoadResponderMasterActor::StateFunc);
+ while (Slaves.size() < 10) {
+ Slaves.push_back(ctx.Register(new TLoadResponderActor(Traffic)));
+ }
+ }
+
+ private:
+ std::shared_ptr<std::atomic_uint64_t> Traffic = std::make_shared<std::atomic_uint64_t>();
+ };
+
IActor* CreateLoadResponderActor() {
- return new TLoadResponderMasterActor();
- }
-
+ return new TLoadResponderMasterActor();
+ }
+
TActorId MakeLoadResponderActorId(ui32 nodeId) {
- char x[12] = {'I', 'C', 'L', 'o', 'a', 'd', 'R', 'e', 's', 'p', 'A', 'c'};
+ char x[12] = {'I', 'C', 'L', 'o', 'a', 'd', 'R', 'e', 's', 'p', 'A', 'c'};
return TActorId(nodeId, TStringBuf(x, 12));
- }
-
+ }
+
class TLoadActor: public TActorBootstrapped<TLoadActor> {
- struct TEvGenerateMessages : TEventLocal<TEvGenerateMessages, EvGenerateMessages> {};
- struct TEvPublishResults : TEventLocal<TEvPublishResults, EvPublishResults> {};
-
- struct TMessageInfo {
- TInstant SendTimestamp;
-
+ struct TEvGenerateMessages : TEventLocal<TEvGenerateMessages, EvGenerateMessages> {};
+ struct TEvPublishResults : TEventLocal<TEvPublishResults, EvPublishResults> {};
+
+ struct TMessageInfo {
+ TInstant SendTimestamp;
+
TMessageInfo(const TInstant& sendTimestamp)
- : SendTimestamp(sendTimestamp)
+ : SendTimestamp(sendTimestamp)
{
}
- };
-
- const TLoadParams Params;
- TInstant NextMessageTimestamp;
- THashMap<TString, TMessageInfo> InFly;
- ui64 NextId = 1;
+ };
+
+ const TLoadParams Params;
+ TInstant NextMessageTimestamp;
+ THashMap<TString, TMessageInfo> InFly;
+ ui64 NextId = 1;
TVector<TActorId> Hops;
TActorId FirstHop;
- ui64 NumDropped = 0;
- std::shared_ptr<std::atomic_uint64_t> Traffic;
-
- public:
+ ui64 NumDropped = 0;
+ std::shared_ptr<std::atomic_uint64_t> Traffic;
+
+ public:
static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::INTERCONNECT_LOAD_ACTOR;
+ return IActor::INTERCONNECT_LOAD_ACTOR;
}
TLoadActor(const TLoadParams& params)
- : Params(params)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TLoadActor::QueryTrafficCounter);
- ctx.Send(MakeLoadResponderActorId(SelfId().NodeId()), new TEvQueryTrafficCounter);
+ : Params(params)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TLoadActor::QueryTrafficCounter);
+ ctx.Send(MakeLoadResponderActorId(SelfId().NodeId()), new TEvQueryTrafficCounter);
}
-
- void Handle(TEvTrafficCounter::TPtr ev, const TActorContext& ctx) {
- Traffic = std::move(ev->Get()->Traffic);
-
- for (const ui32 nodeId : Params.NodeHops) {
+
+ void Handle(TEvTrafficCounter::TPtr ev, const TActorContext& ctx) {
+ Traffic = std::move(ev->Get()->Traffic);
+
+ for (const ui32 nodeId : Params.NodeHops) {
const TActorId& actorId = nodeId ? MakeLoadResponderActorId(nodeId) : TActorId();
- if (!FirstHop) {
- FirstHop = actorId;
- } else {
- Hops.push_back(actorId);
- }
- }
-
- Hops.push_back(ctx.SelfID);
-
- Become(&TLoadActor::StateFunc);
- NextMessageTimestamp = ctx.Now();
- ResetThroughput(NextMessageTimestamp, *Traffic);
- GenerateMessages(ctx);
- ctx.Schedule(Params.Duration, new TEvents::TEvPoisonPill);
- SchedulePublishResults(ctx);
- }
-
+ if (!FirstHop) {
+ FirstHop = actorId;
+ } else {
+ Hops.push_back(actorId);
+ }
+ }
+
+ Hops.push_back(ctx.SelfID);
+
+ Become(&TLoadActor::StateFunc);
+ NextMessageTimestamp = ctx.Now();
+ ResetThroughput(NextMessageTimestamp, *Traffic);
+ GenerateMessages(ctx);
+ ctx.Schedule(Params.Duration, new TEvents::TEvPoisonPill);
+ SchedulePublishResults(ctx);
+ }
+
void GenerateMessages(const TActorContext& ctx) {
while (InFly.size() < Params.InFlyMax && ctx.Now() >= NextMessageTimestamp) {
- // generate payload
- const ui32 size = Params.SizeMin + RandomNumber(Params.SizeMax - Params.SizeMin + 1);
-
- // generate message id
- const ui64 cookie = NextId++;
- TString id = Sprintf("%" PRIu64, cookie);
-
- // create message and send it to the first hop
- THolder<TEvLoadMessage> ev;
- if (Params.UseProtobufWithPayload && size) {
- auto buffer = TRopeAlignedBuffer::Allocate(size);
- memset(buffer->GetBuffer(), '*', size);
- ev.Reset(new TEvLoadMessage(Hops, id, TRope(buffer)));
- } else {
- TString payload;
- if (size) {
- payload = TString::Uninitialized(size);
- memset(payload.Detach(), '*', size);
- }
- ev.Reset(new TEvLoadMessage(Hops, id, payload ? &payload : nullptr));
- }
- UpdateThroughput(ev->CalculateSerializedSizeCached());
- ctx.Send(FirstHop, ev.Release(), IEventHandle::MakeFlags(Params.Channel, 0), cookie);
-
- // register in the map
- InFly.emplace(id, TMessageInfo(ctx.Now()));
-
- // put item into timeout queue
- PutTimeoutQueueItem(ctx, id);
-
+ // generate payload
+ const ui32 size = Params.SizeMin + RandomNumber(Params.SizeMax - Params.SizeMin + 1);
+
+ // generate message id
+ const ui64 cookie = NextId++;
+ TString id = Sprintf("%" PRIu64, cookie);
+
+ // create message and send it to the first hop
+ THolder<TEvLoadMessage> ev;
+ if (Params.UseProtobufWithPayload && size) {
+ auto buffer = TRopeAlignedBuffer::Allocate(size);
+ memset(buffer->GetBuffer(), '*', size);
+ ev.Reset(new TEvLoadMessage(Hops, id, TRope(buffer)));
+ } else {
+ TString payload;
+ if (size) {
+ payload = TString::Uninitialized(size);
+ memset(payload.Detach(), '*', size);
+ }
+ ev.Reset(new TEvLoadMessage(Hops, id, payload ? &payload : nullptr));
+ }
+ UpdateThroughput(ev->CalculateSerializedSizeCached());
+ ctx.Send(FirstHop, ev.Release(), IEventHandle::MakeFlags(Params.Channel, 0), cookie);
+
+ // register in the map
+ InFly.emplace(id, TMessageInfo(ctx.Now()));
+
+ // put item into timeout queue
+ PutTimeoutQueueItem(ctx, id);
+
const TDuration duration = TDuration::MicroSeconds(Params.IntervalMin.GetValue() +
- RandomNumber(Params.IntervalMax.GetValue() - Params.IntervalMin.GetValue() + 1));
- if (Params.SoftLoad) {
- NextMessageTimestamp += duration;
- } else {
- NextMessageTimestamp = ctx.Now() + duration;
- }
- }
-
- // schedule next generate messages call
- if (NextMessageTimestamp > ctx.Now() && InFly.size() < Params.InFlyMax) {
- ctx.Schedule(NextMessageTimestamp - ctx.Now(), new TEvGenerateMessages);
- }
- }
-
+ RandomNumber(Params.IntervalMax.GetValue() - Params.IntervalMin.GetValue() + 1));
+ if (Params.SoftLoad) {
+ NextMessageTimestamp += duration;
+ } else {
+ NextMessageTimestamp = ctx.Now() + duration;
+ }
+ }
+
+ // schedule next generate messages call
+ if (NextMessageTimestamp > ctx.Now() && InFly.size() < Params.InFlyMax) {
+ ctx.Schedule(NextMessageTimestamp - ctx.Now(), new TEvGenerateMessages);
+ }
+ }
+
void Handle(TEvLoadMessage::TPtr& ev, const TActorContext& ctx) {
const auto& record = ev->Get()->Record;
- auto it = InFly.find(record.GetId());
- if (it != InFly.end()) {
- // record message rtt
- const TDuration rtt = ctx.Now() - it->second.SendTimestamp;
- UpdateHistogram(ctx.Now(), rtt);
-
- // update throughput
- UpdateThroughput(ev->Get()->CalculateSerializedSizeCached());
-
- // remove message from the in fly map
- InFly.erase(it);
- } else {
- ++NumDropped;
- }
- GenerateMessages(ctx);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // RTT HISTOGRAM
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const TDuration AggregationPeriod = TDuration::Seconds(20);
- TDeque<std::pair<TInstant, TDuration>> Histogram;
-
- void UpdateHistogram(TInstant when, TDuration rtt) {
- Histogram.emplace_back(when, rtt);
-
- const TInstant barrier = when - AggregationPeriod;
- while (Histogram && Histogram.front().first < barrier) {
- Histogram.pop_front();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // THROUGHPUT
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TInstant ThroughputFirstSample = TInstant::Zero();
- ui64 ThroughputSamples = 0;
- ui64 ThroughputBytes = 0;
- ui64 TrafficAtBegin = 0;
-
- void UpdateThroughput(ui64 bytes) {
- ThroughputBytes += bytes;
- ++ThroughputSamples;
- }
-
- void ResetThroughput(TInstant when, ui64 traffic) {
- ThroughputFirstSample = when;
- ThroughputSamples = 0;
- ThroughputBytes = 0;
- TrafficAtBegin = traffic;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TIMEOUT QUEUE OPERATIONS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TQueue<std::pair<TInstant, TString>> TimeoutQueue;
-
+ auto it = InFly.find(record.GetId());
+ if (it != InFly.end()) {
+ // record message rtt
+ const TDuration rtt = ctx.Now() - it->second.SendTimestamp;
+ UpdateHistogram(ctx.Now(), rtt);
+
+ // update throughput
+ UpdateThroughput(ev->Get()->CalculateSerializedSizeCached());
+
+ // remove message from the in fly map
+ InFly.erase(it);
+ } else {
+ ++NumDropped;
+ }
+ GenerateMessages(ctx);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // RTT HISTOGRAM
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ const TDuration AggregationPeriod = TDuration::Seconds(20);
+ TDeque<std::pair<TInstant, TDuration>> Histogram;
+
+ void UpdateHistogram(TInstant when, TDuration rtt) {
+ Histogram.emplace_back(when, rtt);
+
+ const TInstant barrier = when - AggregationPeriod;
+ while (Histogram && Histogram.front().first < barrier) {
+ Histogram.pop_front();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // THROUGHPUT
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TInstant ThroughputFirstSample = TInstant::Zero();
+ ui64 ThroughputSamples = 0;
+ ui64 ThroughputBytes = 0;
+ ui64 TrafficAtBegin = 0;
+
+ void UpdateThroughput(ui64 bytes) {
+ ThroughputBytes += bytes;
+ ++ThroughputSamples;
+ }
+
+ void ResetThroughput(TInstant when, ui64 traffic) {
+ ThroughputFirstSample = when;
+ ThroughputSamples = 0;
+ ThroughputBytes = 0;
+ TrafficAtBegin = traffic;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TIMEOUT QUEUE OPERATIONS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TQueue<std::pair<TInstant, TString>> TimeoutQueue;
+
void PutTimeoutQueueItem(const TActorContext& ctx, TString id) {
- TimeoutQueue.emplace(ctx.Now() + TDuration::Minutes(1), std::move(id));
- if (TimeoutQueue.size() == 1) {
- ScheduleWakeup(ctx);
- }
- }
-
+ TimeoutQueue.emplace(ctx.Now() + TDuration::Minutes(1), std::move(id));
+ if (TimeoutQueue.size() == 1) {
+ ScheduleWakeup(ctx);
+ }
+ }
+
void ScheduleWakeup(const TActorContext& ctx) {
- ctx.Schedule(TimeoutQueue.front().first - ctx.Now(), new TEvents::TEvWakeup);
- }
-
+ ctx.Schedule(TimeoutQueue.front().first - ctx.Now(), new TEvents::TEvWakeup);
+ }
+
void HandleWakeup(const TActorContext& ctx) {
- ui32 numDropped = 0;
-
- while (TimeoutQueue && TimeoutQueue.front().first <= ctx.Now()) {
- numDropped += InFly.erase(TimeoutQueue.front().second);
- TimeoutQueue.pop();
- }
- if (TimeoutQueue) {
- // we still have some elements in timeout queue, so schedule next wake up to tidy up
- ScheduleWakeup(ctx);
- }
-
- GenerateMessages(ctx);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // RESULT PUBLISHING
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const TDuration ResultPublishPeriod = TDuration::Seconds(15);
-
+ ui32 numDropped = 0;
+
+ while (TimeoutQueue && TimeoutQueue.front().first <= ctx.Now()) {
+ numDropped += InFly.erase(TimeoutQueue.front().second);
+ TimeoutQueue.pop();
+ }
+ if (TimeoutQueue) {
+ // we still have some elements in timeout queue, so schedule next wake up to tidy up
+ ScheduleWakeup(ctx);
+ }
+
+ GenerateMessages(ctx);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // RESULT PUBLISHING
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ const TDuration ResultPublishPeriod = TDuration::Seconds(15);
+
void SchedulePublishResults(const TActorContext& ctx) {
- ctx.Schedule(ResultPublishPeriod, new TEvPublishResults);
- }
-
+ ctx.Schedule(ResultPublishPeriod, new TEvPublishResults);
+ }
+
void PublishResults(const TActorContext& ctx, bool schedule = true) {
- const TInstant now = ctx.Now();
-
- TStringStream msg;
-
- msg << "Load# '" << Params.Name << "'";
-
- msg << " Throughput# ";
- const TDuration duration = now - ThroughputFirstSample;
- const ui64 traffic = *Traffic;
- msg << "{window# " << duration
- << " bytes# " << ThroughputBytes
- << " samples# " << ThroughputSamples
- << " b/s# " << ui64(ThroughputBytes * 1000000 / duration.MicroSeconds())
- << " common# " << ui64((traffic - TrafficAtBegin) * 1000000 / duration.MicroSeconds())
- << "}";
- ResetThroughput(now, traffic);
-
- msg << " RTT# ";
- if (Histogram) {
- const TDuration duration = Histogram.back().first - Histogram.front().first;
- msg << "{window# " << duration << " samples# " << Histogram.size();
- TVector<TDuration> v;
- v.reserve(Histogram.size());
+ const TInstant now = ctx.Now();
+
+ TStringStream msg;
+
+ msg << "Load# '" << Params.Name << "'";
+
+ msg << " Throughput# ";
+ const TDuration duration = now - ThroughputFirstSample;
+ const ui64 traffic = *Traffic;
+ msg << "{window# " << duration
+ << " bytes# " << ThroughputBytes
+ << " samples# " << ThroughputSamples
+ << " b/s# " << ui64(ThroughputBytes * 1000000 / duration.MicroSeconds())
+ << " common# " << ui64((traffic - TrafficAtBegin) * 1000000 / duration.MicroSeconds())
+ << "}";
+ ResetThroughput(now, traffic);
+
+ msg << " RTT# ";
+ if (Histogram) {
+ const TDuration duration = Histogram.back().first - Histogram.front().first;
+ msg << "{window# " << duration << " samples# " << Histogram.size();
+ TVector<TDuration> v;
+ v.reserve(Histogram.size());
for (const auto& item : Histogram) {
- v.push_back(item.second);
- }
- std::sort(v.begin(), v.end());
- for (double q : {0.5, 0.9, 0.99, 0.999, 0.9999, 1.0}) {
- const size_t pos = q * (v.size() - 1);
+ v.push_back(item.second);
+ }
+ std::sort(v.begin(), v.end());
+ for (double q : {0.5, 0.9, 0.99, 0.999, 0.9999, 1.0}) {
+ const size_t pos = q * (v.size() - 1);
msg << Sprintf(" %.4f# %s", q, v[pos].ToString().data());
- }
- msg << "}";
- } else {
- msg << "<empty>";
- }
-
- msg << " NumDropped# " << NumDropped;
-
- if (!schedule) {
- msg << " final";
- }
-
+ }
+ msg << "}";
+ } else {
+ msg << "<empty>";
+ }
+
+ msg << " NumDropped# " << NumDropped;
+
+ if (!schedule) {
+ msg << " final";
+ }
+
LOG_NOTICE(ctx, NActorsServices::INTERCONNECT_SPEED_TEST, "%s", msg.Str().data());
-
- if (schedule) {
- SchedulePublishResults(ctx);
- }
- }
-
- STRICT_STFUNC(QueryTrafficCounter,
- HFunc(TEvTrafficCounter, Handle);
- )
-
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::PoisonPill, Die);
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- CFunc(EvPublishResults, PublishResults);
- CFunc(EvGenerateMessages, GenerateMessages);
- HFunc(TEvLoadMessage, Handle);
- )
-
- void Die(const TActorContext& ctx) override {
- PublishResults(ctx, false);
- TActorBootstrapped::Die(ctx);
- }
- };
-
+
+ if (schedule) {
+ SchedulePublishResults(ctx);
+ }
+ }
+
+ STRICT_STFUNC(QueryTrafficCounter,
+ HFunc(TEvTrafficCounter, Handle);
+ )
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ CFunc(EvPublishResults, PublishResults);
+ CFunc(EvGenerateMessages, GenerateMessages);
+ HFunc(TEvLoadMessage, Handle);
+ )
+
+ void Die(const TActorContext& ctx) override {
+ PublishResults(ctx, false);
+ TActorBootstrapped::Die(ctx);
+ }
+ };
+
IActor* CreateLoadActor(const TLoadParams& params) {
- return new TLoadActor(params);
- }
-
+ return new TLoadActor(params);
+ }
+
}
diff --git a/library/cpp/actors/interconnect/load.h b/library/cpp/actors/interconnect/load.h
index 0a01a0dc048..4e122f6e53e 100644
--- a/library/cpp/actors/interconnect/load.h
+++ b/library/cpp/actors/interconnect/load.h
@@ -1,24 +1,24 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor.h>
-
-namespace NInterconnect {
- // load responder -- lives on every node as a service actor
+
+namespace NInterconnect {
+ // load responder -- lives on every node as a service actor
NActors::IActor* CreateLoadResponderActor();
NActors::TActorId MakeLoadResponderActorId(ui32 node);
-
- // load actor -- generates load with specific parameters
- struct TLoadParams {
- TString Name;
- ui32 Channel;
+
+ // load actor -- generates load with specific parameters
+ struct TLoadParams {
+ TString Name;
+ ui32 Channel;
TVector<ui32> NodeHops; // node ids for the message route
ui32 SizeMin, SizeMax; // min and max size for payloads
ui32 InFlyMax; // maximum number of in fly messages
- TDuration IntervalMin, IntervalMax; // min and max intervals between sending messages
+ TDuration IntervalMin, IntervalMax; // min and max intervals between sending messages
bool SoftLoad; // is the load soft?
TDuration Duration; // test duration
- bool UseProtobufWithPayload; // store payload separately
- };
+ bool UseProtobufWithPayload; // store payload separately
+ };
NActors::IActor* CreateLoadActor(const TLoadParams& params);
-
+
}
diff --git a/library/cpp/actors/interconnect/logging.h b/library/cpp/actors/interconnect/logging.h
index c429d1cade7..62c40d77c32 100644
--- a/library/cpp/actors/interconnect/logging.h
+++ b/library/cpp/actors/interconnect/logging.h
@@ -2,24 +2,24 @@
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-
-#define LOG_LOG_IC_X(component, marker, priority, ...) \
- do { \
- LOG_LOG(this->GetActorContext(), (priority), (component), "%s " marker " %s", LogPrefix.data(), Sprintf(__VA_ARGS__).data()); \
- } while (false)
-
-#define LOG_LOG_NET_X(priority, NODE_ID, FMT, ...) \
- do { \
- const TActorContext& ctx = this->GetActorContext(); \
- LOG_LOG(ctx, (priority), ::NActorsServices::INTERCONNECT_NETWORK, "[%" PRIu32 " <-> %" PRIu32 "] %s", \
- ctx.SelfID.NodeId(), (NODE_ID), Sprintf(FMT, __VA_ARGS__).data()); \
- } while (false)
-
-#define LOG_LOG_IC(component, marker, priority, ...) \
- do { \
- LOG_LOG(::NActors::TActivationContext::AsActorContext(), (priority), (component), "%s " marker " %s", LogPrefix.data(), Sprintf(__VA_ARGS__).data()); \
+
+#define LOG_LOG_IC_X(component, marker, priority, ...) \
+ do { \
+ LOG_LOG(this->GetActorContext(), (priority), (component), "%s " marker " %s", LogPrefix.data(), Sprintf(__VA_ARGS__).data()); \
+ } while (false)
+
+#define LOG_LOG_NET_X(priority, NODE_ID, FMT, ...) \
+ do { \
+ const TActorContext& ctx = this->GetActorContext(); \
+ LOG_LOG(ctx, (priority), ::NActorsServices::INTERCONNECT_NETWORK, "[%" PRIu32 " <-> %" PRIu32 "] %s", \
+ ctx.SelfID.NodeId(), (NODE_ID), Sprintf(FMT, __VA_ARGS__).data()); \
+ } while (false)
+
+#define LOG_LOG_IC(component, marker, priority, ...) \
+ do { \
+ LOG_LOG(::NActors::TActivationContext::AsActorContext(), (priority), (component), "%s " marker " %s", LogPrefix.data(), Sprintf(__VA_ARGS__).data()); \
} while (false)
-
+
#define LOG_LOG_NET(priority, NODE_ID, FMT, ...) \
do { \
const TActorContext& ctx = ::NActors::TActivationContext::AsActorContext(); \
@@ -27,42 +27,42 @@
ctx.SelfID.NodeId(), (NODE_ID), Sprintf(FMT, __VA_ARGS__).data()); \
} while (false)
-#define LOG_EMER_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_EMER, __VA_ARGS__)
-#define LOG_ALERT_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_ALERT, __VA_ARGS__)
-#define LOG_CRIT_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_CRIT, __VA_ARGS__)
-#define LOG_ERROR_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_ERROR, __VA_ARGS__)
-#define LOG_WARN_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_WARN, __VA_ARGS__)
-#define LOG_NOTICE_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_NOTICE, __VA_ARGS__)
-#define LOG_INFO_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_INFO, __VA_ARGS__)
-#define LOG_DEBUG_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_DEBUG, __VA_ARGS__)
-
-#define LOG_EMER_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_EMER, __VA_ARGS__)
-#define LOG_ALERT_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_ALERT, __VA_ARGS__)
-#define LOG_CRIT_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_CRIT, __VA_ARGS__)
-#define LOG_ERROR_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_ERROR, __VA_ARGS__)
-#define LOG_WARN_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_WARN, __VA_ARGS__)
-#define LOG_NOTICE_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_NOTICE, __VA_ARGS__)
-#define LOG_INFO_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_INFO, __VA_ARGS__)
-#define LOG_DEBUG_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_DEBUG, __VA_ARGS__)
-
+#define LOG_EMER_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_EMER, __VA_ARGS__)
+#define LOG_ALERT_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_ALERT, __VA_ARGS__)
+#define LOG_CRIT_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_CRIT, __VA_ARGS__)
+#define LOG_ERROR_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_ERROR, __VA_ARGS__)
+#define LOG_WARN_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_WARN, __VA_ARGS__)
+#define LOG_NOTICE_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_NOTICE, __VA_ARGS__)
+#define LOG_INFO_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_INFO, __VA_ARGS__)
+#define LOG_DEBUG_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_DEBUG, __VA_ARGS__)
+
+#define LOG_EMER_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_EMER, __VA_ARGS__)
+#define LOG_ALERT_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_ALERT, __VA_ARGS__)
+#define LOG_CRIT_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_CRIT, __VA_ARGS__)
+#define LOG_ERROR_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_ERROR, __VA_ARGS__)
+#define LOG_WARN_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_WARN, __VA_ARGS__)
+#define LOG_NOTICE_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_NOTICE, __VA_ARGS__)
+#define LOG_INFO_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_INFO, __VA_ARGS__)
+#define LOG_DEBUG_IC_SESSION(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT_SESSION, marker, ::NActors::NLog::PRI_DEBUG, __VA_ARGS__)
+
#define LOG_NOTICE_NET(NODE_ID, FMT, ...) LOG_LOG_NET(::NActors::NLog::PRI_NOTICE, NODE_ID, FMT, __VA_ARGS__)
#define LOG_DEBUG_NET(NODE_ID, FMT, ...) LOG_LOG_NET(::NActors::NLog::PRI_DEBUG, NODE_ID, FMT, __VA_ARGS__)
-
+
namespace NActors {
class TInterconnectLoggingBase {
protected:
const TString LogPrefix;
public:
- TInterconnectLoggingBase() = default;
-
- TInterconnectLoggingBase(const TString& prefix)
+ TInterconnectLoggingBase() = default;
+
+ TInterconnectLoggingBase(const TString& prefix)
: LogPrefix(prefix)
{
}
-
- void SetPrefix(TString logPrefix) const {
- logPrefix.swap(const_cast<TString&>(LogPrefix));
+
+ void SetPrefix(TString logPrefix) const {
+ logPrefix.swap(const_cast<TString&>(LogPrefix));
}
};
}
diff --git a/library/cpp/actors/interconnect/mock/ic_mock.cpp b/library/cpp/actors/interconnect/mock/ic_mock.cpp
index 884503e6022..ffb0f9dc8d6 100644
--- a/library/cpp/actors/interconnect/mock/ic_mock.cpp
+++ b/library/cpp/actors/interconnect/mock/ic_mock.cpp
@@ -1,298 +1,298 @@
-#include "ic_mock.h"
-#include <library/cpp/actors/core/interconnect.h>
-#include <util/system/yield.h>
-#include <thread>
-
-namespace NActors {
-
- class TInterconnectMock::TImpl {
- enum {
- EvInject = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvCheckSession,
- EvRam,
- };
-
- struct TEvInject : TEventLocal<TEvInject, EvInject> {
- std::deque<std::unique_ptr<IEventHandle>> Messages;
- const TScopeId OriginScopeId;
- const ui64 SenderSessionId;
-
- TEvInject(std::deque<std::unique_ptr<IEventHandle>>&& messages, const TScopeId& originScopeId, ui64 senderSessionId)
- : Messages(std::move(messages))
- , OriginScopeId(originScopeId)
- , SenderSessionId(senderSessionId)
- {}
- };
-
- class TProxyMockActor;
-
- class TConnectionState {
- struct TPeerInfo {
- TRWMutex Mutex;
- TActorSystem *ActorSystem = nullptr;
- TActorId ProxyId;
- };
-
- const ui64 Key;
- TPeerInfo PeerInfo[2];
- std::atomic_uint64_t SessionId = 0;
-
- public:
- TConnectionState(ui64 key)
- : Key(key)
- {}
-
+#include "ic_mock.h"
+#include <library/cpp/actors/core/interconnect.h>
+#include <util/system/yield.h>
+#include <thread>
+
+namespace NActors {
+
+ class TInterconnectMock::TImpl {
+ enum {
+ EvInject = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvCheckSession,
+ EvRam,
+ };
+
+ struct TEvInject : TEventLocal<TEvInject, EvInject> {
+ std::deque<std::unique_ptr<IEventHandle>> Messages;
+ const TScopeId OriginScopeId;
+ const ui64 SenderSessionId;
+
+ TEvInject(std::deque<std::unique_ptr<IEventHandle>>&& messages, const TScopeId& originScopeId, ui64 senderSessionId)
+ : Messages(std::move(messages))
+ , OriginScopeId(originScopeId)
+ , SenderSessionId(senderSessionId)
+ {}
+ };
+
+ class TProxyMockActor;
+
+ class TConnectionState {
+ struct TPeerInfo {
+ TRWMutex Mutex;
+ TActorSystem *ActorSystem = nullptr;
+ TActorId ProxyId;
+ };
+
+ const ui64 Key;
+ TPeerInfo PeerInfo[2];
+ std::atomic_uint64_t SessionId = 0;
+
+ public:
+ TConnectionState(ui64 key)
+ : Key(key)
+ {}
+
void Attach(ui32 nodeId, TActorSystem *as, const TActorId& actorId) {
- TPeerInfo *peer = GetPeer(nodeId);
- auto guard = TWriteGuard(peer->Mutex);
- Y_VERIFY(!peer->ActorSystem);
- peer->ActorSystem = as;
- peer->ProxyId = actorId;
- as->DeferPreStop([peer] {
- auto guard = TWriteGuard(peer->Mutex);
- peer->ActorSystem = nullptr;
- });
- }
-
- void Inject(ui32 peerNodeId, std::deque<std::unique_ptr<IEventHandle>>&& messages,
- const TScopeId& originScopeId, ui64 senderSessionId) {
- TPeerInfo *peer = GetPeer(peerNodeId);
- auto guard = TReadGuard(peer->Mutex);
- if (peer->ActorSystem) {
- peer->ActorSystem->Send(new IEventHandle(peer->ProxyId, TActorId(), new TEvInject(std::move(messages),
- originScopeId, senderSessionId)));
- } else {
- for (auto&& ev : messages) {
- TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
- }
- }
- }
-
- ui64 GetValidSessionId() const {
- return SessionId;
- }
-
- void InvalidateSessionId(ui32 peerNodeId) {
- ++SessionId;
- TPeerInfo *peer = GetPeer(peerNodeId);
- auto guard = TReadGuard(peer->Mutex);
- if (peer->ActorSystem) {
- peer->ActorSystem->Send(new IEventHandle(EvCheckSession, 0, peer->ProxyId, {}, nullptr, 0));
- }
- }
-
- private:
- TPeerInfo *GetPeer(ui32 nodeId) {
- if (nodeId == ui32(Key)) {
- return PeerInfo;
- } else if (nodeId == ui32(Key >> 32)) {
- return PeerInfo + 1;
- } else {
- Y_FAIL();
- }
- }
- };
-
- class TProxyMockActor : public TActor<TProxyMockActor> {
- class TSessionMockActor : public TActor<TSessionMockActor> {
+ TPeerInfo *peer = GetPeer(nodeId);
+ auto guard = TWriteGuard(peer->Mutex);
+ Y_VERIFY(!peer->ActorSystem);
+ peer->ActorSystem = as;
+ peer->ProxyId = actorId;
+ as->DeferPreStop([peer] {
+ auto guard = TWriteGuard(peer->Mutex);
+ peer->ActorSystem = nullptr;
+ });
+ }
+
+ void Inject(ui32 peerNodeId, std::deque<std::unique_ptr<IEventHandle>>&& messages,
+ const TScopeId& originScopeId, ui64 senderSessionId) {
+ TPeerInfo *peer = GetPeer(peerNodeId);
+ auto guard = TReadGuard(peer->Mutex);
+ if (peer->ActorSystem) {
+ peer->ActorSystem->Send(new IEventHandle(peer->ProxyId, TActorId(), new TEvInject(std::move(messages),
+ originScopeId, senderSessionId)));
+ } else {
+ for (auto&& ev : messages) {
+ TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
+ }
+ }
+ }
+
+ ui64 GetValidSessionId() const {
+ return SessionId;
+ }
+
+ void InvalidateSessionId(ui32 peerNodeId) {
+ ++SessionId;
+ TPeerInfo *peer = GetPeer(peerNodeId);
+ auto guard = TReadGuard(peer->Mutex);
+ if (peer->ActorSystem) {
+ peer->ActorSystem->Send(new IEventHandle(EvCheckSession, 0, peer->ProxyId, {}, nullptr, 0));
+ }
+ }
+
+ private:
+ TPeerInfo *GetPeer(ui32 nodeId) {
+ if (nodeId == ui32(Key)) {
+ return PeerInfo;
+ } else if (nodeId == ui32(Key >> 32)) {
+ return PeerInfo + 1;
+ } else {
+ Y_FAIL();
+ }
+ }
+ };
+
+ class TProxyMockActor : public TActor<TProxyMockActor> {
+ class TSessionMockActor : public TActor<TSessionMockActor> {
std::map<TActorId, ui64> Subscribers;
- TProxyMockActor* const Proxy;
- std::deque<std::unique_ptr<IEventHandle>> Queue;
-
- public:
- const ui64 SessionId;
-
- public:
- TSessionMockActor(TProxyMockActor *proxy, ui64 sessionId)
- : TActor(&TThis::StateFunc)
- , Proxy(proxy)
- , SessionId(sessionId)
- {}
-
- void Terminate() {
- for (auto&& ev : std::exchange(Queue, {})) {
- TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
- }
+ TProxyMockActor* const Proxy;
+ std::deque<std::unique_ptr<IEventHandle>> Queue;
+
+ public:
+ const ui64 SessionId;
+
+ public:
+ TSessionMockActor(TProxyMockActor *proxy, ui64 sessionId)
+ : TActor(&TThis::StateFunc)
+ , Proxy(proxy)
+ , SessionId(sessionId)
+ {}
+
+ void Terminate() {
+ for (auto&& ev : std::exchange(Queue, {})) {
+ TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
+ }
for (const auto& kv : Subscribers) {
Send(kv.first, new TEvInterconnect::TEvNodeDisconnected(Proxy->PeerNodeId), 0, kv.second);
- }
- Y_VERIFY(Proxy->Session == this);
- Proxy->Session = nullptr;
- PassAway();
- }
-
- void HandleForward(TAutoPtr<IEventHandle> ev) {
- if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
+ }
+ Y_VERIFY(Proxy->Session == this);
+ Proxy->Session = nullptr;
+ PassAway();
+ }
+
+ void HandleForward(TAutoPtr<IEventHandle> ev) {
+ if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
Subscribe(ev->Sender, ev->Cookie);
- }
- if (Queue.empty()) {
- TActivationContext::Send(new IEventHandle(EvRam, 0, SelfId(), {}, {}, 0));
- }
- Queue.emplace_back(ev.Release());
- }
-
- void HandleRam() {
- if (SessionId != Proxy->State.GetValidSessionId()) {
- Terminate();
- } else {
- Proxy->PeerInject(std::exchange(Queue, {}));
- }
- }
-
- void Handle(TEvInterconnect::TEvConnectNode::TPtr ev) {
+ }
+ if (Queue.empty()) {
+ TActivationContext::Send(new IEventHandle(EvRam, 0, SelfId(), {}, {}, 0));
+ }
+ Queue.emplace_back(ev.Release());
+ }
+
+ void HandleRam() {
+ if (SessionId != Proxy->State.GetValidSessionId()) {
+ Terminate();
+ } else {
+ Proxy->PeerInject(std::exchange(Queue, {}));
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvConnectNode::TPtr ev) {
Subscribe(ev->Sender, ev->Cookie);
- }
-
- void Handle(TEvents::TEvSubscribe::TPtr ev) {
+ }
+
+ void Handle(TEvents::TEvSubscribe::TPtr ev) {
Subscribe(ev->Sender, ev->Cookie);
- }
-
- void Handle(TEvents::TEvUnsubscribe::TPtr ev) {
- Subscribers.erase(ev->Sender);
- }
-
- void HandlePoison() {
- Proxy->Disconnect();
- }
-
- STRICT_STFUNC(StateFunc,
- fFunc(TEvInterconnect::EvForward, HandleForward)
- hFunc(TEvInterconnect::TEvConnectNode, Handle)
- hFunc(TEvents::TEvSubscribe, Handle)
- hFunc(TEvents::TEvUnsubscribe, Handle)
- cFunc(TEvents::TSystem::Poison, HandlePoison)
- cFunc(EvRam, HandleRam)
- )
-
- private:
+ }
+
+ void Handle(TEvents::TEvUnsubscribe::TPtr ev) {
+ Subscribers.erase(ev->Sender);
+ }
+
+ void HandlePoison() {
+ Proxy->Disconnect();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(TEvInterconnect::EvForward, HandleForward)
+ hFunc(TEvInterconnect::TEvConnectNode, Handle)
+ hFunc(TEvents::TEvSubscribe, Handle)
+ hFunc(TEvents::TEvUnsubscribe, Handle)
+ cFunc(TEvents::TSystem::Poison, HandlePoison)
+ cFunc(EvRam, HandleRam)
+ )
+
+ private:
void Subscribe(const TActorId& actorId, ui64 cookie) {
Subscribers[actorId] = cookie;
Send(actorId, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, cookie);
- }
- };
-
- friend class TSessionMockActor;
-
- const ui32 NodeId;
- const ui32 PeerNodeId;
- TConnectionState& State;
- const TInterconnectProxyCommon::TPtr Common;
- TSessionMockActor *Session = nullptr;
-
- public:
- TProxyMockActor(ui32 nodeId, ui32 peerNodeId, TConnectionState& state, TInterconnectProxyCommon::TPtr common)
- : TActor(&TThis::StateFunc)
- , NodeId(nodeId)
- , PeerNodeId(peerNodeId)
- , State(state)
- , Common(std::move(common))
- {}
-
+ }
+ };
+
+ friend class TSessionMockActor;
+
+ const ui32 NodeId;
+ const ui32 PeerNodeId;
+ TConnectionState& State;
+ const TInterconnectProxyCommon::TPtr Common;
+ TSessionMockActor *Session = nullptr;
+
+ public:
+ TProxyMockActor(ui32 nodeId, ui32 peerNodeId, TConnectionState& state, TInterconnectProxyCommon::TPtr common)
+ : TActor(&TThis::StateFunc)
+ , NodeId(nodeId)
+ , PeerNodeId(peerNodeId)
+ , State(state)
+ , Common(std::move(common))
+ {}
+
void Registered(TActorSystem *as, const TActorId& parent) override {
- TActor::Registered(as, parent);
- State.Attach(NodeId, as, SelfId());
- }
-
- void Handle(TEvInject::TPtr ev) {
- auto *msg = ev->Get();
- if (Session && Session->SessionId != msg->SenderSessionId) {
- return; // drop messages from other sessions
- }
- if (auto *session = GetSession()) {
- for (auto&& ev : ev->Get()->Messages) {
- auto fw = std::make_unique<IEventHandle>(
- session->SelfId(),
- ev->Type,
- ev->Flags & ~IEventHandle::FlagForwardOnNondelivery,
- ev->Recipient,
- ev->Sender,
- ev->ReleaseChainBuffer(),
- ev->Cookie,
- msg->OriginScopeId,
- std::move(ev->TraceId)
- );
- if (!Common->EventFilter || Common->EventFilter->CheckIncomingEvent(*fw, Common->LocalScopeId)) {
- TActivationContext::Send(fw.release());
- }
- }
- }
- }
-
- void PassAway() override {
- Disconnect();
- TActor::PassAway();
- }
-
- TSessionMockActor *GetSession() {
- CheckSession();
- if (!Session) {
- Session = new TSessionMockActor(this, State.GetValidSessionId());
+ TActor::Registered(as, parent);
+ State.Attach(NodeId, as, SelfId());
+ }
+
+ void Handle(TEvInject::TPtr ev) {
+ auto *msg = ev->Get();
+ if (Session && Session->SessionId != msg->SenderSessionId) {
+ return; // drop messages from other sessions
+ }
+ if (auto *session = GetSession()) {
+ for (auto&& ev : ev->Get()->Messages) {
+ auto fw = std::make_unique<IEventHandle>(
+ session->SelfId(),
+ ev->Type,
+ ev->Flags & ~IEventHandle::FlagForwardOnNondelivery,
+ ev->Recipient,
+ ev->Sender,
+ ev->ReleaseChainBuffer(),
+ ev->Cookie,
+ msg->OriginScopeId,
+ std::move(ev->TraceId)
+ );
+ if (!Common->EventFilter || Common->EventFilter->CheckIncomingEvent(*fw, Common->LocalScopeId)) {
+ TActivationContext::Send(fw.release());
+ }
+ }
+ }
+ }
+
+ void PassAway() override {
+ Disconnect();
+ TActor::PassAway();
+ }
+
+ TSessionMockActor *GetSession() {
+ CheckSession();
+ if (!Session) {
+ Session = new TSessionMockActor(this, State.GetValidSessionId());
RegisterWithSameMailbox(Session);
- }
- return Session;
- }
-
- void HandleSessionEvent(TAutoPtr<IEventHandle> ev) {
- auto *session = GetSession();
- InvokeOtherActor(*session, &TSessionMockActor::Receive, ev,
- TActivationContext::ActorContextFor(session->SelfId()));
- }
-
- void Disconnect() {
- State.InvalidateSessionId(PeerNodeId);
- if (Session) {
- Session->Terminate();
- }
- }
-
- void CheckSession() {
- if (Session && Session->SessionId != State.GetValidSessionId()) {
- Session->Terminate();
- }
- }
-
- void PeerInject(std::deque<std::unique_ptr<IEventHandle>>&& messages) {
- Y_VERIFY(Session);
- return State.Inject(PeerNodeId, std::move(messages), Common->LocalScopeId, Session->SessionId);
- }
-
- STRICT_STFUNC(StateFunc,
- cFunc(TEvents::TSystem::Poison, PassAway)
- fFunc(TEvInterconnect::EvForward, HandleSessionEvent)
- fFunc(TEvInterconnect::EvConnectNode, HandleSessionEvent)
- fFunc(TEvents::TSystem::Subscribe, HandleSessionEvent)
- fFunc(TEvents::TSystem::Unsubscribe, HandleSessionEvent)
- cFunc(TEvInterconnect::EvDisconnect, Disconnect)
- IgnoreFunc(TEvInterconnect::TEvClosePeerSocket)
- IgnoreFunc(TEvInterconnect::TEvCloseInputSession)
- cFunc(TEvInterconnect::EvPoisonSession, Disconnect)
- hFunc(TEvInject, Handle)
- cFunc(EvCheckSession, CheckSession)
- )
- };
-
- std::unordered_map<ui64, TConnectionState> States;
-
- public:
- IActor *CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common) {
- Y_VERIFY(nodeId != peerNodeId);
- Y_VERIFY(nodeId);
- Y_VERIFY(peerNodeId);
- const ui64 key = std::min(nodeId, peerNodeId) | ui64(std::max(nodeId, peerNodeId)) << 32;
- auto it = States.try_emplace(key, key).first;
- return new TProxyMockActor(nodeId, peerNodeId, it->second, std::move(common));
- }
- };
-
- TInterconnectMock::TInterconnectMock()
- : Impl(std::make_unique<TImpl>())
- {}
-
- TInterconnectMock::~TInterconnectMock()
- {}
-
- IActor *TInterconnectMock::CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common) {
- return Impl->CreateProxyMock(nodeId, peerNodeId, std::move(common));
- }
-
-} // NActors
+ }
+ return Session;
+ }
+
+ void HandleSessionEvent(TAutoPtr<IEventHandle> ev) {
+ auto *session = GetSession();
+ InvokeOtherActor(*session, &TSessionMockActor::Receive, ev,
+ TActivationContext::ActorContextFor(session->SelfId()));
+ }
+
+ void Disconnect() {
+ State.InvalidateSessionId(PeerNodeId);
+ if (Session) {
+ Session->Terminate();
+ }
+ }
+
+ void CheckSession() {
+ if (Session && Session->SessionId != State.GetValidSessionId()) {
+ Session->Terminate();
+ }
+ }
+
+ void PeerInject(std::deque<std::unique_ptr<IEventHandle>>&& messages) {
+ Y_VERIFY(Session);
+ return State.Inject(PeerNodeId, std::move(messages), Common->LocalScopeId, Session->SessionId);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ fFunc(TEvInterconnect::EvForward, HandleSessionEvent)
+ fFunc(TEvInterconnect::EvConnectNode, HandleSessionEvent)
+ fFunc(TEvents::TSystem::Subscribe, HandleSessionEvent)
+ fFunc(TEvents::TSystem::Unsubscribe, HandleSessionEvent)
+ cFunc(TEvInterconnect::EvDisconnect, Disconnect)
+ IgnoreFunc(TEvInterconnect::TEvClosePeerSocket)
+ IgnoreFunc(TEvInterconnect::TEvCloseInputSession)
+ cFunc(TEvInterconnect::EvPoisonSession, Disconnect)
+ hFunc(TEvInject, Handle)
+ cFunc(EvCheckSession, CheckSession)
+ )
+ };
+
+ std::unordered_map<ui64, TConnectionState> States;
+
+ public:
+ IActor *CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common) {
+ Y_VERIFY(nodeId != peerNodeId);
+ Y_VERIFY(nodeId);
+ Y_VERIFY(peerNodeId);
+ const ui64 key = std::min(nodeId, peerNodeId) | ui64(std::max(nodeId, peerNodeId)) << 32;
+ auto it = States.try_emplace(key, key).first;
+ return new TProxyMockActor(nodeId, peerNodeId, it->second, std::move(common));
+ }
+ };
+
+ TInterconnectMock::TInterconnectMock()
+ : Impl(std::make_unique<TImpl>())
+ {}
+
+ TInterconnectMock::~TInterconnectMock()
+ {}
+
+ IActor *TInterconnectMock::CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common) {
+ return Impl->CreateProxyMock(nodeId, peerNodeId, std::move(common));
+ }
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/mock/ic_mock.h b/library/cpp/actors/interconnect/mock/ic_mock.h
index 636bdc2b7fb..5018cd7f354 100644
--- a/library/cpp/actors/interconnect/mock/ic_mock.h
+++ b/library/cpp/actors/interconnect/mock/ic_mock.h
@@ -1,19 +1,19 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-
-#include <library/cpp/actors/interconnect/interconnect_common.h>
-
-namespace NActors {
-
- class TInterconnectMock {
- class TImpl;
- std::unique_ptr<TImpl> Impl;
-
- public:
- TInterconnectMock();
- ~TInterconnectMock();
- IActor *CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common);
- };
-
-} // NActors
+#pragma once
+
+#include <library/cpp/actors/core/actor.h>
+
+#include <library/cpp/actors/interconnect/interconnect_common.h>
+
+namespace NActors {
+
+ class TInterconnectMock {
+ class TImpl;
+ std::unique_ptr<TImpl> Impl;
+
+ public:
+ TInterconnectMock();
+ ~TInterconnectMock();
+ IActor *CreateProxyMock(ui32 nodeId, ui32 peerNodeId, TInterconnectProxyCommon::TPtr common);
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/mock/ya.make b/library/cpp/actors/interconnect/mock/ya.make
index 19a28341626..eb1a28a6302 100644
--- a/library/cpp/actors/interconnect/mock/ya.make
+++ b/library/cpp/actors/interconnect/mock/ya.make
@@ -1,16 +1,16 @@
-LIBRARY()
-
-OWNER(alexvru)
-
-SRCS(
- ic_mock.cpp
- ic_mock.h
-)
-
+LIBRARY()
+
+OWNER(alexvru)
+
+SRCS(
+ ic_mock.cpp
+ ic_mock.h
+)
+
SUPPRESSIONS(tsan.supp)
-PEERDIR(
- library/cpp/actors/interconnect
-)
-
-END()
+PEERDIR(
+ library/cpp/actors/interconnect
+)
+
+END()
diff --git a/library/cpp/actors/interconnect/packet.cpp b/library/cpp/actors/interconnect/packet.cpp
index e2c289ed592..b217941d69b 100644
--- a/library/cpp/actors/interconnect/packet.cpp
+++ b/library/cpp/actors/interconnect/packet.cpp
@@ -1,32 +1,32 @@
-#include "packet.h"
-
+#include "packet.h"
+
#include <library/cpp/actors/core/probes.h>
-#include <util/system/datetime.h>
-
+#include <util/system/datetime.h>
+
LWTRACE_USING(ACTORLIB_PROVIDER);
-ui32 TEventHolder::Fill(IEventHandle& ev) {
- Serial = 0;
- Descr.Type = ev.Type;
- Descr.Flags = ev.Flags;
- Descr.Recipient = ev.Recipient;
- Descr.Sender = ev.Sender;
- Descr.Cookie = ev.Cookie;
- ev.TraceId.Serialize(&Descr.TraceId);
- ForwardRecipient = ev.GetForwardOnNondeliveryRecipient();
- EventActuallySerialized = 0;
- Descr.Checksum = 0;
-
- if (ev.HasBuffer()) {
- Buffer = ev.ReleaseChainBuffer();
- EventSerializedSize = Buffer->GetSize();
- } else if (ev.HasEvent()) {
- Event.Reset(ev.ReleaseBase());
- EventSerializedSize = Event->CalculateSerializedSize();
- } else {
- EventSerializedSize = 0;
- }
+ui32 TEventHolder::Fill(IEventHandle& ev) {
+ Serial = 0;
+ Descr.Type = ev.Type;
+ Descr.Flags = ev.Flags;
+ Descr.Recipient = ev.Recipient;
+ Descr.Sender = ev.Sender;
+ Descr.Cookie = ev.Cookie;
+ ev.TraceId.Serialize(&Descr.TraceId);
+ ForwardRecipient = ev.GetForwardOnNondeliveryRecipient();
+ EventActuallySerialized = 0;
+ Descr.Checksum = 0;
+
+ if (ev.HasBuffer()) {
+ Buffer = ev.ReleaseChainBuffer();
+ EventSerializedSize = Buffer->GetSize();
+ } else if (ev.HasEvent()) {
+ Event.Reset(ev.ReleaseBase());
+ EventSerializedSize = Event->CalculateSerializedSize();
+ } else {
+ EventSerializedSize = 0;
+ }
- return EventSerializedSize;
-}
+ return EventSerializedSize;
+}
diff --git a/library/cpp/actors/interconnect/packet.h b/library/cpp/actors/interconnect/packet.h
index 4ba50a2b5f4..52267bcc2ee 100644
--- a/library/cpp/actors/interconnect/packet.h
+++ b/library/cpp/actors/interconnect/packet.h
@@ -1,324 +1,324 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/event_pb.h>
#include <library/cpp/actors/core/event_load.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/events.h>
+#include <library/cpp/actors/core/actor.h>
#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <library/cpp/actors/util/rope.h>
#include <library/cpp/actors/prof/tag.h>
#include <library/cpp/digest/crc32c/crc32c.h>
#include <library/cpp/lwtrace/shuttle.h>
-#include <util/generic/string.h>
-#include <util/generic/list.h>
-
-#ifndef FORCE_EVENT_CHECKSUM
-#define FORCE_EVENT_CHECKSUM 0
-#endif
-
+#include <util/generic/string.h>
+#include <util/generic/list.h>
+
+#ifndef FORCE_EVENT_CHECKSUM
+#define FORCE_EVENT_CHECKSUM 0
+#endif
+
using NActors::IEventBase;
using NActors::IEventHandle;
using NActors::TActorId;
using NActors::TConstIoVec;
-using NActors::TEventSerializedData;
-
-Y_FORCE_INLINE ui32 Crc32cExtendMSanCompatible(ui32 checksum, const void *data, size_t len) {
- if constexpr (NSan::MSanIsOn()) {
- const char *begin = static_cast<const char*>(data);
- const char *end = begin + len;
- begin -= reinterpret_cast<uintptr_t>(begin) & 15;
- end += -reinterpret_cast<uintptr_t>(end) & 15;
- NSan::Unpoison(begin, end - begin);
- }
- return Crc32cExtend(checksum, data, len);
-}
-
-struct TSessionParams {
- bool Encryption = {};
- bool UseModernFrame = {};
- bool AuthOnly = {};
- TString AuthCN;
- NActors::TScopeId PeerScopeId;
-};
-
-struct TTcpPacketHeader_v1 {
- ui32 HeaderCRC32;
- ui32 PayloadCRC32;
- ui64 Confirm;
- ui64 Serial;
- ui64 DataSize;
-
- inline bool Check() const {
- ui32 actual = Crc32cExtendMSanCompatible(0, &PayloadCRC32, sizeof(TTcpPacketHeader_v1) - sizeof(HeaderCRC32));
- return actual == HeaderCRC32;
- }
-
- inline void Sign() {
- HeaderCRC32 = Crc32cExtendMSanCompatible(0, &PayloadCRC32, sizeof(TTcpPacketHeader_v1) - sizeof(HeaderCRC32));
- }
-
- TString ToString() const {
- return Sprintf("{Confirm# %" PRIu64 " Serial# %" PRIu64 " DataSize# %" PRIu64 "}", Confirm, Serial, DataSize);
- }
-};
-
-#pragma pack(push, 1)
-struct TTcpPacketHeader_v2 {
- ui64 Confirm;
- ui64 Serial;
- ui32 Checksum; // for the whole frame
- ui16 PayloadLength;
-};
-#pragma pack(pop)
-
-union TTcpPacketBuf {
- static constexpr ui64 PingRequestMask = 0x8000000000000000ULL;
- static constexpr ui64 PingResponseMask = 0x4000000000000000ULL;
- static constexpr ui64 ClockMask = 0x2000000000000000ULL;
-
- static constexpr size_t PacketDataLen = 4096 * 2 - 96 - Max(sizeof(TTcpPacketHeader_v1), sizeof(TTcpPacketHeader_v2));
- struct {
- TTcpPacketHeader_v1 Header;
- char Data[PacketDataLen];
- } v1;
- struct {
- TTcpPacketHeader_v2 Header;
- char Data[PacketDataLen];
- } v2;
-};
-
-#pragma pack(push, 1)
-struct TEventDescr {
- ui32 Type;
- ui32 Flags;
+using NActors::TEventSerializedData;
+
+Y_FORCE_INLINE ui32 Crc32cExtendMSanCompatible(ui32 checksum, const void *data, size_t len) {
+ if constexpr (NSan::MSanIsOn()) {
+ const char *begin = static_cast<const char*>(data);
+ const char *end = begin + len;
+ begin -= reinterpret_cast<uintptr_t>(begin) & 15;
+ end += -reinterpret_cast<uintptr_t>(end) & 15;
+ NSan::Unpoison(begin, end - begin);
+ }
+ return Crc32cExtend(checksum, data, len);
+}
+
+struct TSessionParams {
+ bool Encryption = {};
+ bool UseModernFrame = {};
+ bool AuthOnly = {};
+ TString AuthCN;
+ NActors::TScopeId PeerScopeId;
+};
+
+struct TTcpPacketHeader_v1 {
+ ui32 HeaderCRC32;
+ ui32 PayloadCRC32;
+ ui64 Confirm;
+ ui64 Serial;
+ ui64 DataSize;
+
+ inline bool Check() const {
+ ui32 actual = Crc32cExtendMSanCompatible(0, &PayloadCRC32, sizeof(TTcpPacketHeader_v1) - sizeof(HeaderCRC32));
+ return actual == HeaderCRC32;
+ }
+
+ inline void Sign() {
+ HeaderCRC32 = Crc32cExtendMSanCompatible(0, &PayloadCRC32, sizeof(TTcpPacketHeader_v1) - sizeof(HeaderCRC32));
+ }
+
+ TString ToString() const {
+ return Sprintf("{Confirm# %" PRIu64 " Serial# %" PRIu64 " DataSize# %" PRIu64 "}", Confirm, Serial, DataSize);
+ }
+};
+
+#pragma pack(push, 1)
+struct TTcpPacketHeader_v2 {
+ ui64 Confirm;
+ ui64 Serial;
+ ui32 Checksum; // for the whole frame
+ ui16 PayloadLength;
+};
+#pragma pack(pop)
+
+union TTcpPacketBuf {
+ static constexpr ui64 PingRequestMask = 0x8000000000000000ULL;
+ static constexpr ui64 PingResponseMask = 0x4000000000000000ULL;
+ static constexpr ui64 ClockMask = 0x2000000000000000ULL;
+
+ static constexpr size_t PacketDataLen = 4096 * 2 - 96 - Max(sizeof(TTcpPacketHeader_v1), sizeof(TTcpPacketHeader_v2));
+ struct {
+ TTcpPacketHeader_v1 Header;
+ char Data[PacketDataLen];
+ } v1;
+ struct {
+ TTcpPacketHeader_v2 Header;
+ char Data[PacketDataLen];
+ } v2;
+};
+
+#pragma pack(push, 1)
+struct TEventDescr {
+ ui32 Type;
+ ui32 Flags;
TActorId Recipient;
TActorId Sender;
- ui64 Cookie;
- // wilson trace id is stored as a serialized entity to avoid using complex object with prohibited copy ctor
- NWilson::TTraceId::TSerializedTraceId TraceId;
- ui32 Checksum;
-};
-#pragma pack(pop)
-
-struct TEventHolder : TNonCopyable {
- TEventDescr Descr;
+ ui64 Cookie;
+ // wilson trace id is stored as a serialized entity to avoid using complex object with prohibited copy ctor
+ NWilson::TTraceId::TSerializedTraceId TraceId;
+ ui32 Checksum;
+};
+#pragma pack(pop)
+
+struct TEventHolder : TNonCopyable {
+ TEventDescr Descr;
TActorId ForwardRecipient;
- THolder<IEventBase> Event;
- TIntrusivePtr<TEventSerializedData> Buffer;
- ui64 Serial;
- ui32 EventSerializedSize;
- ui32 EventActuallySerialized;
+ THolder<IEventBase> Event;
+ TIntrusivePtr<TEventSerializedData> Buffer;
+ ui64 Serial;
+ ui32 EventSerializedSize;
+ ui32 EventActuallySerialized;
mutable NLWTrace::TOrbit Orbit;
-
- ui32 Fill(IEventHandle& ev);
-
- void InitChecksum() {
- Descr.Checksum = 0;
- }
-
- void UpdateChecksum(const TSessionParams& params, const void *buffer, size_t len) {
- if (FORCE_EVENT_CHECKSUM || !params.UseModernFrame) {
- Descr.Checksum = Crc32cExtendMSanCompatible(Descr.Checksum, buffer, len);
- }
- }
-
- void ForwardOnNondelivery(bool unsure) {
- TEventDescr& d = Descr;
- const TActorId& r = d.Recipient;
- const TActorId& s = d.Sender;
- const TActorId *f = ForwardRecipient ? &ForwardRecipient : nullptr;
- auto ev = Event
- ? std::make_unique<IEventHandle>(r, s, Event.Release(), d.Flags, d.Cookie, f, NWilson::TTraceId(d.TraceId))
- : std::make_unique<IEventHandle>(d.Type, d.Flags, r, s, std::move(Buffer), d.Cookie, f, NWilson::TTraceId(d.TraceId));
- NActors::TActivationContext::Send(ev->ForwardOnNondelivery(NActors::TEvents::TEvUndelivered::Disconnected, unsure));
- }
-
- void Clear() {
- Event.Reset();
- Buffer.Reset();
+
+ ui32 Fill(IEventHandle& ev);
+
+ void InitChecksum() {
+ Descr.Checksum = 0;
+ }
+
+ void UpdateChecksum(const TSessionParams& params, const void *buffer, size_t len) {
+ if (FORCE_EVENT_CHECKSUM || !params.UseModernFrame) {
+ Descr.Checksum = Crc32cExtendMSanCompatible(Descr.Checksum, buffer, len);
+ }
+ }
+
+ void ForwardOnNondelivery(bool unsure) {
+ TEventDescr& d = Descr;
+ const TActorId& r = d.Recipient;
+ const TActorId& s = d.Sender;
+ const TActorId *f = ForwardRecipient ? &ForwardRecipient : nullptr;
+ auto ev = Event
+ ? std::make_unique<IEventHandle>(r, s, Event.Release(), d.Flags, d.Cookie, f, NWilson::TTraceId(d.TraceId))
+ : std::make_unique<IEventHandle>(d.Type, d.Flags, r, s, std::move(Buffer), d.Cookie, f, NWilson::TTraceId(d.TraceId));
+ NActors::TActivationContext::Send(ev->ForwardOnNondelivery(NActors::TEvents::TEvUndelivered::Disconnected, unsure));
+ }
+
+ void Clear() {
+ Event.Reset();
+ Buffer.Reset();
Orbit.Reset();
- }
-};
-
-namespace NActors {
- class TEventOutputChannel;
+ }
+};
+
+namespace NActors {
+ class TEventOutputChannel;
}
-
-struct TTcpPacketOutTask : TNonCopyable {
- const TSessionParams& Params;
- TTcpPacketBuf Packet;
- size_t DataSize;
- TStackVec<TConstIoVec, 32> Bufs;
- size_t BufferIndex;
- size_t FirstBufferOffset;
- bool TriedWriting;
- char *FreeArea;
- char *End;
+
+struct TTcpPacketOutTask : TNonCopyable {
+ const TSessionParams& Params;
+ TTcpPacketBuf Packet;
+ size_t DataSize;
+ TStackVec<TConstIoVec, 32> Bufs;
+ size_t BufferIndex;
+ size_t FirstBufferOffset;
+ bool TriedWriting;
+ char *FreeArea;
+ char *End;
mutable NLWTrace::TOrbit Orbit;
-
-public:
- TTcpPacketOutTask(const TSessionParams& params)
- : Params(params)
- {
- Reuse();
- }
-
- template<typename T>
- auto ApplyToHeader(T&& callback) {
- return Params.UseModernFrame ? callback(Packet.v2.Header) : callback(Packet.v1.Header);
- }
-
- template<typename T>
- auto ApplyToHeader(T&& callback) const {
- return Params.UseModernFrame ? callback(Packet.v2.Header) : callback(Packet.v1.Header);
- }
-
- bool IsAtBegin() const {
- return !BufferIndex && !FirstBufferOffset && !TriedWriting;
- }
-
- void MarkTriedWriting() {
- TriedWriting = true;
- }
-
- void Reuse() {
- DataSize = 0;
- ApplyToHeader([this](auto& header) { Bufs.assign(1, {&header, sizeof(header)}); });
- BufferIndex = 0;
- FirstBufferOffset = 0;
- TriedWriting = false;
- FreeArea = Params.UseModernFrame ? Packet.v2.Data : Packet.v1.Data;
- End = FreeArea + TTcpPacketBuf::PacketDataLen;
+
+public:
+ TTcpPacketOutTask(const TSessionParams& params)
+ : Params(params)
+ {
+ Reuse();
+ }
+
+ template<typename T>
+ auto ApplyToHeader(T&& callback) {
+ return Params.UseModernFrame ? callback(Packet.v2.Header) : callback(Packet.v1.Header);
+ }
+
+ template<typename T>
+ auto ApplyToHeader(T&& callback) const {
+ return Params.UseModernFrame ? callback(Packet.v2.Header) : callback(Packet.v1.Header);
+ }
+
+ bool IsAtBegin() const {
+ return !BufferIndex && !FirstBufferOffset && !TriedWriting;
+ }
+
+ void MarkTriedWriting() {
+ TriedWriting = true;
+ }
+
+ void Reuse() {
+ DataSize = 0;
+ ApplyToHeader([this](auto& header) { Bufs.assign(1, {&header, sizeof(header)}); });
+ BufferIndex = 0;
+ FirstBufferOffset = 0;
+ TriedWriting = false;
+ FreeArea = Params.UseModernFrame ? Packet.v2.Data : Packet.v1.Data;
+ End = FreeArea + TTcpPacketBuf::PacketDataLen;
Orbit.Reset();
- }
-
+ }
+
bool IsEmpty() const {
- return !DataSize;
- }
-
- void SetMetadata(ui64 serial, ui64 confirm) {
- ApplyToHeader([&](auto& header) {
- header.Serial = serial;
- header.Confirm = confirm;
- });
- }
-
- void UpdateConfirmIfPossible(ui64 confirm) {
- // we don't want to recalculate whole packet checksum for single confirmation update on v2
- if (!Params.UseModernFrame && IsAtBegin() && confirm != Packet.v1.Header.Confirm) {
- Packet.v1.Header.Confirm = confirm;
- Packet.v1.Header.Sign();
- }
- }
-
- size_t GetDataSize() const { return DataSize; }
-
- ui64 GetSerial() const {
- return ApplyToHeader([](auto& header) { return header.Serial; });
- }
-
- bool Confirmed(ui64 confirm) const {
- return ApplyToHeader([&](auto& header) { return IsEmpty() || header.Serial <= confirm; });
- }
-
- void *GetFreeArea() {
- return FreeArea;
- }
-
- size_t GetVirtualFreeAmount() const {
- return TTcpPacketBuf::PacketDataLen - DataSize;
+ return !DataSize;
}
-
- void AppendBuf(const void *buf, size_t size) {
- DataSize += size;
- Y_VERIFY_DEBUG(DataSize <= TTcpPacketBuf::PacketDataLen, "DataSize# %zu AppendBuf buf# %p size# %zu"
- " FreeArea# %p End# %p", DataSize, buf, size, FreeArea, End);
-
- if (Bufs && static_cast<const char*>(Bufs.back().Data) + Bufs.back().Size == buf) {
- Bufs.back().Size += size;
- } else {
- Bufs.push_back({buf, size});
- }
-
- if (buf >= FreeArea && buf < End) {
- Y_VERIFY_DEBUG(buf == FreeArea);
- FreeArea = const_cast<char*>(static_cast<const char*>(buf)) + size;
- Y_VERIFY_DEBUG(FreeArea <= End);
- }
- }
-
- void Undo(size_t size) {
- Y_VERIFY(Bufs);
- auto& buf = Bufs.back();
- Y_VERIFY(buf.Data == FreeArea - buf.Size);
- buf.Size -= size;
- if (!buf.Size) {
- Bufs.pop_back();
- }
- FreeArea -= size;
- DataSize -= size;
- }
-
- bool DropBufs(size_t& amount) {
+
+ void SetMetadata(ui64 serial, ui64 confirm) {
+ ApplyToHeader([&](auto& header) {
+ header.Serial = serial;
+ header.Confirm = confirm;
+ });
+ }
+
+ void UpdateConfirmIfPossible(ui64 confirm) {
+ // we don't want to recalculate whole packet checksum for single confirmation update on v2
+ if (!Params.UseModernFrame && IsAtBegin() && confirm != Packet.v1.Header.Confirm) {
+ Packet.v1.Header.Confirm = confirm;
+ Packet.v1.Header.Sign();
+ }
+ }
+
+ size_t GetDataSize() const { return DataSize; }
+
+ ui64 GetSerial() const {
+ return ApplyToHeader([](auto& header) { return header.Serial; });
+ }
+
+ bool Confirmed(ui64 confirm) const {
+ return ApplyToHeader([&](auto& header) { return IsEmpty() || header.Serial <= confirm; });
+ }
+
+ void *GetFreeArea() {
+ return FreeArea;
+ }
+
+ size_t GetVirtualFreeAmount() const {
+ return TTcpPacketBuf::PacketDataLen - DataSize;
+ }
+
+ void AppendBuf(const void *buf, size_t size) {
+ DataSize += size;
+ Y_VERIFY_DEBUG(DataSize <= TTcpPacketBuf::PacketDataLen, "DataSize# %zu AppendBuf buf# %p size# %zu"
+ " FreeArea# %p End# %p", DataSize, buf, size, FreeArea, End);
+
+ if (Bufs && static_cast<const char*>(Bufs.back().Data) + Bufs.back().Size == buf) {
+ Bufs.back().Size += size;
+ } else {
+ Bufs.push_back({buf, size});
+ }
+
+ if (buf >= FreeArea && buf < End) {
+ Y_VERIFY_DEBUG(buf == FreeArea);
+ FreeArea = const_cast<char*>(static_cast<const char*>(buf)) + size;
+ Y_VERIFY_DEBUG(FreeArea <= End);
+ }
+ }
+
+ void Undo(size_t size) {
+ Y_VERIFY(Bufs);
+ auto& buf = Bufs.back();
+ Y_VERIFY(buf.Data == FreeArea - buf.Size);
+ buf.Size -= size;
+ if (!buf.Size) {
+ Bufs.pop_back();
+ }
+ FreeArea -= size;
+ DataSize -= size;
+ }
+
+ bool DropBufs(size_t& amount) {
while (BufferIndex != Bufs.size()) {
TConstIoVec& item = Bufs[BufferIndex];
- // calculate number of bytes to the end in current buffer
- const size_t remain = item.Size - FirstBufferOffset;
- if (amount >= remain) {
- // vector item completely fits into the received amount, drop it out and switch to next buffer
- amount -= remain;
- ++BufferIndex;
- FirstBufferOffset = 0;
- } else {
- // adjust first buffer by "amount" bytes forward and reset amount to zero
- FirstBufferOffset += amount;
- amount = 0;
- // return false meaning that we have some more data to send
- return false;
- }
- }
- return true;
- }
-
- void ResetBufs() {
- BufferIndex = FirstBufferOffset = 0;
- TriedWriting = false;
- }
-
+ // calculate number of bytes to the end in current buffer
+ const size_t remain = item.Size - FirstBufferOffset;
+ if (amount >= remain) {
+ // vector item completely fits into the received amount, drop it out and switch to next buffer
+ amount -= remain;
+ ++BufferIndex;
+ FirstBufferOffset = 0;
+ } else {
+ // adjust first buffer by "amount" bytes forward and reset amount to zero
+ FirstBufferOffset += amount;
+ amount = 0;
+ // return false meaning that we have some more data to send
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void ResetBufs() {
+ BufferIndex = FirstBufferOffset = 0;
+ TriedWriting = false;
+ }
+
template <typename TVectorType>
void AppendToIoVector(TVectorType& vector, size_t max) {
- for (size_t k = BufferIndex, offset = FirstBufferOffset; k != Bufs.size() && vector.size() < max; ++k, offset = 0) {
- TConstIoVec v = Bufs[k];
+ for (size_t k = BufferIndex, offset = FirstBufferOffset; k != Bufs.size() && vector.size() < max; ++k, offset = 0) {
+ TConstIoVec v = Bufs[k];
v.Data = static_cast<const char*>(v.Data) + offset;
- v.Size -= offset;
- vector.push_back(v);
- }
- }
-
- void Sign() {
- if (Params.UseModernFrame) {
- Packet.v2.Header.Checksum = 0;
- Packet.v2.Header.PayloadLength = DataSize;
- if (!Params.Encryption) {
- ui32 sum = 0;
- for (const auto& item : Bufs) {
- sum = Crc32cExtendMSanCompatible(sum, item.Data, item.Size);
- }
- Packet.v2.Header.Checksum = sum;
- }
- } else {
- Y_VERIFY(!Bufs.empty());
- auto it = Bufs.begin();
- static constexpr size_t headerLen = sizeof(TTcpPacketHeader_v1);
- Y_VERIFY(it->Data == &Packet.v1.Header && it->Size >= headerLen);
- ui32 sum = Crc32cExtendMSanCompatible(0, Packet.v1.Data, it->Size - headerLen);
- while (++it != Bufs.end()) {
- sum = Crc32cExtendMSanCompatible(sum, it->Data, it->Size);
- }
-
- Packet.v1.Header.PayloadCRC32 = sum;
- Packet.v1.Header.DataSize = DataSize;
- Packet.v1.Header.Sign();
- }
- }
-};
+ v.Size -= offset;
+ vector.push_back(v);
+ }
+ }
+
+ void Sign() {
+ if (Params.UseModernFrame) {
+ Packet.v2.Header.Checksum = 0;
+ Packet.v2.Header.PayloadLength = DataSize;
+ if (!Params.Encryption) {
+ ui32 sum = 0;
+ for (const auto& item : Bufs) {
+ sum = Crc32cExtendMSanCompatible(sum, item.Data, item.Size);
+ }
+ Packet.v2.Header.Checksum = sum;
+ }
+ } else {
+ Y_VERIFY(!Bufs.empty());
+ auto it = Bufs.begin();
+ static constexpr size_t headerLen = sizeof(TTcpPacketHeader_v1);
+ Y_VERIFY(it->Data == &Packet.v1.Header && it->Size >= headerLen);
+ ui32 sum = Crc32cExtendMSanCompatible(0, Packet.v1.Data, it->Size - headerLen);
+ while (++it != Bufs.end()) {
+ sum = Crc32cExtendMSanCompatible(sum, it->Data, it->Size);
+ }
+
+ Packet.v1.Header.PayloadCRC32 = sum;
+ Packet.v1.Header.DataSize = DataSize;
+ Packet.v1.Header.Sign();
+ }
+ }
+};
diff --git a/library/cpp/actors/interconnect/poller.h b/library/cpp/actors/interconnect/poller.h
index ff7979369f0..8c06d67f2f3 100644
--- a/library/cpp/actors/interconnect/poller.h
+++ b/library/cpp/actors/interconnect/poller.h
@@ -1,23 +1,23 @@
-#pragma once
-
-#include <functional>
+#pragma once
+
+#include <functional>
#include <library/cpp/actors/core/events.h>
-
-namespace NActors {
+
+namespace NActors {
class TSharedDescriptor: public TThrRefBase {
public:
virtual int GetDescriptor() = 0;
};
-
+
using TDelegate = std::function<void()>;
using TFDDelegate = std::function<TDelegate(const TIntrusivePtr<TSharedDescriptor>&)>;
-
+
class IPoller: public TThrRefBase {
public:
virtual ~IPoller() = default;
-
+
virtual void StartRead(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) = 0;
virtual void StartWrite(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) = 0;
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_actor.cpp b/library/cpp/actors/interconnect/poller_actor.cpp
index e75cbcaef43..d3db0b137a4 100644
--- a/library/cpp/actors/interconnect/poller_actor.cpp
+++ b/library/cpp/actors/interconnect/poller_actor.cpp
@@ -1,6 +1,6 @@
-#include "poller_actor.h"
+#include "poller_actor.h"
#include "interconnect_common.h"
-
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/core/hfunc.h>
@@ -9,286 +9,286 @@
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/actors/util/funnel_queue.h>
-#include <util/generic/intrlist.h>
-#include <util/system/thread.h>
-#include <util/system/event.h>
-#include <util/system/pipe.h>
-
-#include <variant>
+#include <util/generic/intrlist.h>
+#include <util/system/thread.h>
+#include <util/system/event.h>
+#include <util/system/pipe.h>
+
+#include <variant>
-namespace NActors {
+namespace NActors {
LWTRACE_USING(ACTORLIB_PROVIDER);
namespace {
- int LastSocketError() {
-#if defined(_win_)
- return WSAGetLastError();
-#else
- return errno;
-#endif
+ int LastSocketError() {
+#if defined(_win_)
+ return WSAGetLastError();
+#else
+ return errno;
+#endif
}
}
- struct TSocketRecord : TThrRefBase {
- const TIntrusivePtr<TSharedDescriptor> Socket;
- const TActorId ReadActorId;
- const TActorId WriteActorId;
- std::atomic_uint32_t Flags = 0;
-
+ struct TSocketRecord : TThrRefBase {
+ const TIntrusivePtr<TSharedDescriptor> Socket;
+ const TActorId ReadActorId;
+ const TActorId WriteActorId;
+ std::atomic_uint32_t Flags = 0;
+
TSocketRecord(TEvPollerRegister& ev)
- : Socket(std::move(ev.Socket))
- , ReadActorId(ev.ReadActorId)
- , WriteActorId(ev.WriteActorId)
- {}
- };
-
- template<typename TDerived>
- class TPollerThreadBase : public ISimpleThread {
- protected:
- struct TPollerExitThread {}; // issued then we need to terminate the poller thread
-
- struct TPollerWakeup {};
-
- struct TPollerUnregisterSocket {
- TIntrusivePtr<TSharedDescriptor> Socket;
-
- TPollerUnregisterSocket(TIntrusivePtr<TSharedDescriptor> socket)
- : Socket(std::move(socket))
- {}
- };
-
- using TPollerSyncOperation = std::variant<TPollerExitThread, TPollerWakeup, TPollerUnregisterSocket>;
-
- struct TPollerSyncOperationWrapper {
- TPollerSyncOperation Operation;
- TManualEvent Event;
-
- TPollerSyncOperationWrapper(TPollerSyncOperation&& operation)
- : Operation(std::move(operation))
- {}
-
- void Wait() {
- Event.WaitI();
- }
-
- void SignalDone() {
- Event.Signal();
- }
- };
-
- TActorSystem *ActorSystem;
- TPipeHandle ReadEnd, WriteEnd; // pipe for sync event processor
- TFunnelQueue<TPollerSyncOperationWrapper*> SyncOperationsQ; // operation queue
-
- public:
- TPollerThreadBase(TActorSystem *actorSystem)
- : ActorSystem(actorSystem)
- {
- // create a pipe for notifications
- try {
- TPipeHandle::Pipe(ReadEnd, WriteEnd, CloseOnExec);
- } catch (const TFileError& err) {
- Y_FAIL("failed to create pipe");
- }
-
- // switch the read/write ends to nonblocking mode
- SetNonBlock(ReadEnd);
- SetNonBlock(WriteEnd);
- }
-
- void UnregisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
- ExecuteSyncOperation(TPollerUnregisterSocket(record->Socket));
- }
-
- protected:
- void Notify(TSocketRecord *record, bool read, bool write) {
- auto issue = [&](const TActorId& recipient) {
- ActorSystem->Send(new IEventHandle(recipient, {}, new TEvPollerReady(record->Socket, read, write)));
- };
- if (read && record->ReadActorId) {
- issue(record->ReadActorId);
- if (write && record->WriteActorId && record->WriteActorId != record->ReadActorId) {
- issue(record->WriteActorId);
- }
- } else if (write && record->WriteActorId) {
- issue(record->WriteActorId);
- }
- }
-
- void Stop() {
- // signal poller thread to stop and wait for the thread
- ExecuteSyncOperation(TPollerExitThread());
- ISimpleThread::Join();
- }
-
- void ExecuteSyncOperation(TPollerSyncOperation&& op) {
- TPollerSyncOperationWrapper wrapper(std::move(op));
- if (SyncOperationsQ.Push(&wrapper)) {
- // this was the first entry, so we push notification through the pipe
- for (;;) {
- char buffer = '\x00';
- ssize_t nwritten = WriteEnd.Write(&buffer, sizeof(buffer));
- if (nwritten < 0) {
- const int err = LastSocketError();
- if (err == EINTR) {
- continue;
- } else {
- Y_FAIL("WriteEnd.Write() failed with %s", strerror(err));
- }
- } else {
- Y_VERIFY(nwritten);
- break;
- }
- }
- }
- // wait for operation to complete
- wrapper.Wait();
- }
-
- bool DrainReadEnd() {
- size_t totalRead = 0;
- char buffer[4096];
+ : Socket(std::move(ev.Socket))
+ , ReadActorId(ev.ReadActorId)
+ , WriteActorId(ev.WriteActorId)
+ {}
+ };
+
+ template<typename TDerived>
+ class TPollerThreadBase : public ISimpleThread {
+ protected:
+ struct TPollerExitThread {}; // issued then we need to terminate the poller thread
+
+ struct TPollerWakeup {};
+
+ struct TPollerUnregisterSocket {
+ TIntrusivePtr<TSharedDescriptor> Socket;
+
+ TPollerUnregisterSocket(TIntrusivePtr<TSharedDescriptor> socket)
+ : Socket(std::move(socket))
+ {}
+ };
+
+ using TPollerSyncOperation = std::variant<TPollerExitThread, TPollerWakeup, TPollerUnregisterSocket>;
+
+ struct TPollerSyncOperationWrapper {
+ TPollerSyncOperation Operation;
+ TManualEvent Event;
+
+ TPollerSyncOperationWrapper(TPollerSyncOperation&& operation)
+ : Operation(std::move(operation))
+ {}
+
+ void Wait() {
+ Event.WaitI();
+ }
+
+ void SignalDone() {
+ Event.Signal();
+ }
+ };
+
+ TActorSystem *ActorSystem;
+ TPipeHandle ReadEnd, WriteEnd; // pipe for sync event processor
+ TFunnelQueue<TPollerSyncOperationWrapper*> SyncOperationsQ; // operation queue
+
+ public:
+ TPollerThreadBase(TActorSystem *actorSystem)
+ : ActorSystem(actorSystem)
+ {
+ // create a pipe for notifications
+ try {
+ TPipeHandle::Pipe(ReadEnd, WriteEnd, CloseOnExec);
+ } catch (const TFileError& err) {
+ Y_FAIL("failed to create pipe");
+ }
+
+ // switch the read/write ends to nonblocking mode
+ SetNonBlock(ReadEnd);
+ SetNonBlock(WriteEnd);
+ }
+
+ void UnregisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
+ ExecuteSyncOperation(TPollerUnregisterSocket(record->Socket));
+ }
+
+ protected:
+ void Notify(TSocketRecord *record, bool read, bool write) {
+ auto issue = [&](const TActorId& recipient) {
+ ActorSystem->Send(new IEventHandle(recipient, {}, new TEvPollerReady(record->Socket, read, write)));
+ };
+ if (read && record->ReadActorId) {
+ issue(record->ReadActorId);
+ if (write && record->WriteActorId && record->WriteActorId != record->ReadActorId) {
+ issue(record->WriteActorId);
+ }
+ } else if (write && record->WriteActorId) {
+ issue(record->WriteActorId);
+ }
+ }
+
+ void Stop() {
+ // signal poller thread to stop and wait for the thread
+ ExecuteSyncOperation(TPollerExitThread());
+ ISimpleThread::Join();
+ }
+
+ void ExecuteSyncOperation(TPollerSyncOperation&& op) {
+ TPollerSyncOperationWrapper wrapper(std::move(op));
+ if (SyncOperationsQ.Push(&wrapper)) {
+ // this was the first entry, so we push notification through the pipe
+ for (;;) {
+ char buffer = '\x00';
+ ssize_t nwritten = WriteEnd.Write(&buffer, sizeof(buffer));
+ if (nwritten < 0) {
+ const int err = LastSocketError();
+ if (err == EINTR) {
+ continue;
+ } else {
+ Y_FAIL("WriteEnd.Write() failed with %s", strerror(err));
+ }
+ } else {
+ Y_VERIFY(nwritten);
+ break;
+ }
+ }
+ }
+ // wait for operation to complete
+ wrapper.Wait();
+ }
+
+ bool DrainReadEnd() {
+ size_t totalRead = 0;
+ char buffer[4096];
for (;;) {
- ssize_t n = ReadEnd.Read(buffer, sizeof(buffer));
- if (n < 0) {
- const int error = LastSocketError();
- if (error == EINTR) {
- continue;
- } else if (error == EAGAIN || error == EWOULDBLOCK) {
- break;
+ ssize_t n = ReadEnd.Read(buffer, sizeof(buffer));
+ if (n < 0) {
+ const int error = LastSocketError();
+ if (error == EINTR) {
+ continue;
+ } else if (error == EAGAIN || error == EWOULDBLOCK) {
+ break;
} else {
- Y_FAIL("read() failed with %s", strerror(errno));
+ Y_FAIL("read() failed with %s", strerror(errno));
}
- } else {
- Y_VERIFY(n);
- totalRead += n;
+ } else {
+ Y_VERIFY(n);
+ totalRead += n;
}
- }
- return totalRead;
- }
-
- bool ProcessSyncOpQueue() {
- if (DrainReadEnd()) {
- Y_VERIFY(!SyncOperationsQ.IsEmpty());
- do {
- TPollerSyncOperationWrapper *op = SyncOperationsQ.Top();
- if (auto *unregister = std::get_if<TPollerUnregisterSocket>(&op->Operation)) {
- static_cast<TDerived&>(*this).UnregisterSocketInLoop(unregister->Socket);
- op->SignalDone();
- } else if (std::get_if<TPollerExitThread>(&op->Operation)) {
- op->SignalDone();
- return false; // terminate the thread
- } else if (std::get_if<TPollerWakeup>(&op->Operation)) {
- op->SignalDone();
+ }
+ return totalRead;
+ }
+
+ bool ProcessSyncOpQueue() {
+ if (DrainReadEnd()) {
+ Y_VERIFY(!SyncOperationsQ.IsEmpty());
+ do {
+ TPollerSyncOperationWrapper *op = SyncOperationsQ.Top();
+ if (auto *unregister = std::get_if<TPollerUnregisterSocket>(&op->Operation)) {
+ static_cast<TDerived&>(*this).UnregisterSocketInLoop(unregister->Socket);
+ op->SignalDone();
+ } else if (std::get_if<TPollerExitThread>(&op->Operation)) {
+ op->SignalDone();
+ return false; // terminate the thread
+ } else if (std::get_if<TPollerWakeup>(&op->Operation)) {
+ op->SignalDone();
} else {
- Y_FAIL();
+ Y_FAIL();
}
- } while (SyncOperationsQ.Pop());
+ } while (SyncOperationsQ.Pop());
}
- return true;
+ return true;
}
- void *ThreadProc() override {
- SetCurrentThreadName("network poller");
- while (ProcessSyncOpQueue()) {
- static_cast<TDerived&>(*this).ProcessEventsInLoop();
+ void *ThreadProc() override {
+ SetCurrentThreadName("network poller");
+ while (ProcessSyncOpQueue()) {
+ static_cast<TDerived&>(*this).ProcessEventsInLoop();
}
- return nullptr;
+ return nullptr;
}
- };
+ };
-} // namespace NActors
+} // namespace NActors
-#if defined(_linux_)
-# include "poller_actor_linux.h"
-#elif defined(_darwin_)
-# include "poller_actor_darwin.h"
-#elif defined(_win_)
-# include "poller_actor_win.h"
-#else
-# error "Unsupported platform"
-#endif
+#if defined(_linux_)
+# include "poller_actor_linux.h"
+#elif defined(_darwin_)
+# include "poller_actor_darwin.h"
+#elif defined(_win_)
+# include "poller_actor_win.h"
+#else
+# error "Unsupported platform"
+#endif
-namespace NActors {
+namespace NActors {
- class TPollerToken::TImpl {
- std::weak_ptr<TPollerThread> Thread;
- TIntrusivePtr<TSocketRecord> Record; // valid only when Thread is held locked
+ class TPollerToken::TImpl {
+ std::weak_ptr<TPollerThread> Thread;
+ TIntrusivePtr<TSocketRecord> Record; // valid only when Thread is held locked
public:
- TImpl(std::shared_ptr<TPollerThread> thread, TIntrusivePtr<TSocketRecord> record)
- : Thread(thread)
- , Record(std::move(record))
+ TImpl(std::shared_ptr<TPollerThread> thread, TIntrusivePtr<TSocketRecord> record)
+ : Thread(thread)
+ , Record(std::move(record))
{
- thread->RegisterSocket(Record);
- }
+ thread->RegisterSocket(Record);
+ }
- ~TImpl() {
- if (auto thread = Thread.lock()) {
- thread->UnregisterSocket(Record);
+ ~TImpl() {
+ if (auto thread = Thread.lock()) {
+ thread->UnregisterSocket(Record);
}
}
- void Request(bool read, bool write) {
- if (auto thread = Thread.lock()) {
- thread->Request(Record, read, write);
+ void Request(bool read, bool write) {
+ if (auto thread = Thread.lock()) {
+ thread->Request(Record, read, write);
}
}
-
- const TIntrusivePtr<TSharedDescriptor>& Socket() const {
- return Record->Socket;
- }
+
+ const TIntrusivePtr<TSharedDescriptor>& Socket() const {
+ return Record->Socket;
+ }
};
- class TPollerActor: public TActorBootstrapped<TPollerActor> {
- // poller thread
- std::shared_ptr<TPollerThread> PollerThread;
-
- public:
+ class TPollerActor: public TActorBootstrapped<TPollerActor> {
+ // poller thread
+ std::shared_ptr<TPollerThread> PollerThread;
+
+ public:
static constexpr IActor::EActivityType ActorActivityType() {
return IActor::INTERCONNECT_POLLER;
}
- void Bootstrap() {
- PollerThread = std::make_shared<TPollerThread>(TlsActivationContext->ExecutorThread.ActorSystem);
- Become(&TPollerActor::StateFunc);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvPollerRegister, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- void Handle(TEvPollerRegister::TPtr& ev) {
- auto *msg = ev->Get();
- auto impl = std::make_unique<TPollerToken::TImpl>(PollerThread, MakeIntrusive<TSocketRecord>(*msg));
- auto socket = impl->Socket();
- TPollerToken::TPtr token(new TPollerToken(std::move(impl)));
- if (msg->ReadActorId && msg->WriteActorId && msg->WriteActorId != msg->ReadActorId) {
- Send(msg->ReadActorId, new TEvPollerRegisterResult(socket, token));
- Send(msg->WriteActorId, new TEvPollerRegisterResult(socket, std::move(token)));
- } else if (msg->ReadActorId) {
- Send(msg->ReadActorId, new TEvPollerRegisterResult(socket, std::move(token)));
- } else if (msg->WriteActorId) {
- Send(msg->WriteActorId, new TEvPollerRegisterResult(socket, std::move(token)));
- }
- }
- };
-
- TPollerToken::TPollerToken(std::unique_ptr<TImpl> impl)
- : Impl(std::move(impl))
- {}
-
- TPollerToken::~TPollerToken()
- {}
-
- void TPollerToken::Request(bool read, bool write) {
- Impl->Request(read, write);
- }
-
+ void Bootstrap() {
+ PollerThread = std::make_shared<TPollerThread>(TlsActivationContext->ExecutorThread.ActorSystem);
+ Become(&TPollerActor::StateFunc);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvPollerRegister, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ void Handle(TEvPollerRegister::TPtr& ev) {
+ auto *msg = ev->Get();
+ auto impl = std::make_unique<TPollerToken::TImpl>(PollerThread, MakeIntrusive<TSocketRecord>(*msg));
+ auto socket = impl->Socket();
+ TPollerToken::TPtr token(new TPollerToken(std::move(impl)));
+ if (msg->ReadActorId && msg->WriteActorId && msg->WriteActorId != msg->ReadActorId) {
+ Send(msg->ReadActorId, new TEvPollerRegisterResult(socket, token));
+ Send(msg->WriteActorId, new TEvPollerRegisterResult(socket, std::move(token)));
+ } else if (msg->ReadActorId) {
+ Send(msg->ReadActorId, new TEvPollerRegisterResult(socket, std::move(token)));
+ } else if (msg->WriteActorId) {
+ Send(msg->WriteActorId, new TEvPollerRegisterResult(socket, std::move(token)));
+ }
+ }
+ };
+
+ TPollerToken::TPollerToken(std::unique_ptr<TImpl> impl)
+ : Impl(std::move(impl))
+ {}
+
+ TPollerToken::~TPollerToken()
+ {}
+
+ void TPollerToken::Request(bool read, bool write) {
+ Impl->Request(read, write);
+ }
+
IActor* CreatePollerActor() {
- return new TPollerActor;
- }
-
+ return new TPollerActor;
+ }
+
}
diff --git a/library/cpp/actors/interconnect/poller_actor.h b/library/cpp/actors/interconnect/poller_actor.h
index f927b820893..ca40b4f3b89 100644
--- a/library/cpp/actors/interconnect/poller_actor.h
+++ b/library/cpp/actors/interconnect/poller_actor.h
@@ -1,60 +1,60 @@
-#pragma once
-
+#pragma once
+
#include "events_local.h"
-#include "poller.h"
+#include "poller.h"
#include <library/cpp/actors/core/actor.h>
-
-namespace NActors {
- struct TEvPollerRegister : TEventLocal<TEvPollerRegister, ui32(ENetwork::EvPollerRegister)> {
- const TIntrusivePtr<TSharedDescriptor> Socket; // socket to watch for
- const TActorId ReadActorId; // actor id to notify about read availability
- const TActorId WriteActorId; // actor id to notify about write availability; may be the same as the ReadActorId
-
- TEvPollerRegister(TIntrusivePtr<TSharedDescriptor> socket, const TActorId& readActorId, const TActorId& writeActorId)
- : Socket(std::move(socket))
- , ReadActorId(readActorId)
- , WriteActorId(writeActorId)
- {}
- };
-
- // poller token is sent in response to TEvPollerRegister; it allows requesting poll when read/write returns EAGAIN
- class TPollerToken : public TThrRefBase {
- class TImpl;
- std::unique_ptr<TImpl> Impl;
-
- friend class TPollerActor;
- TPollerToken(std::unique_ptr<TImpl> impl);
-
- public:
- ~TPollerToken();
- void Request(bool read, bool write);
-
- using TPtr = TIntrusivePtr<TPollerToken>;
- };
-
- struct TEvPollerRegisterResult : TEventLocal<TEvPollerRegisterResult, ui32(ENetwork::EvPollerRegisterResult)> {
- TIntrusivePtr<TSharedDescriptor> Socket;
- TPollerToken::TPtr PollerToken;
-
- TEvPollerRegisterResult(TIntrusivePtr<TSharedDescriptor> socket, TPollerToken::TPtr pollerToken)
- : Socket(std::move(socket))
- , PollerToken(std::move(pollerToken))
- {}
- };
-
- struct TEvPollerReady : TEventLocal<TEvPollerReady, ui32(ENetwork::EvPollerReady)> {
- TIntrusivePtr<TSharedDescriptor> Socket;
- const bool Read, Write;
-
- TEvPollerReady(TIntrusivePtr<TSharedDescriptor> socket, bool read, bool write)
- : Socket(std::move(socket))
- , Read(read)
- , Write(write)
- {}
- };
-
+
+namespace NActors {
+ struct TEvPollerRegister : TEventLocal<TEvPollerRegister, ui32(ENetwork::EvPollerRegister)> {
+ const TIntrusivePtr<TSharedDescriptor> Socket; // socket to watch for
+ const TActorId ReadActorId; // actor id to notify about read availability
+ const TActorId WriteActorId; // actor id to notify about write availability; may be the same as the ReadActorId
+
+ TEvPollerRegister(TIntrusivePtr<TSharedDescriptor> socket, const TActorId& readActorId, const TActorId& writeActorId)
+ : Socket(std::move(socket))
+ , ReadActorId(readActorId)
+ , WriteActorId(writeActorId)
+ {}
+ };
+
+ // poller token is sent in response to TEvPollerRegister; it allows requesting poll when read/write returns EAGAIN
+ class TPollerToken : public TThrRefBase {
+ class TImpl;
+ std::unique_ptr<TImpl> Impl;
+
+ friend class TPollerActor;
+ TPollerToken(std::unique_ptr<TImpl> impl);
+
+ public:
+ ~TPollerToken();
+ void Request(bool read, bool write);
+
+ using TPtr = TIntrusivePtr<TPollerToken>;
+ };
+
+ struct TEvPollerRegisterResult : TEventLocal<TEvPollerRegisterResult, ui32(ENetwork::EvPollerRegisterResult)> {
+ TIntrusivePtr<TSharedDescriptor> Socket;
+ TPollerToken::TPtr PollerToken;
+
+ TEvPollerRegisterResult(TIntrusivePtr<TSharedDescriptor> socket, TPollerToken::TPtr pollerToken)
+ : Socket(std::move(socket))
+ , PollerToken(std::move(pollerToken))
+ {}
+ };
+
+ struct TEvPollerReady : TEventLocal<TEvPollerReady, ui32(ENetwork::EvPollerReady)> {
+ TIntrusivePtr<TSharedDescriptor> Socket;
+ const bool Read, Write;
+
+ TEvPollerReady(TIntrusivePtr<TSharedDescriptor> socket, bool read, bool write)
+ : Socket(std::move(socket))
+ , Read(read)
+ , Write(write)
+ {}
+ };
+
IActor* CreatePollerActor();
-
+
inline TActorId MakePollerActorId() {
char x[12] = {'I', 'C', 'P', 'o', 'l', 'l', 'e', 'r', '\xDE', '\xAD', '\xBE', '\xEF'};
return TActorId(0, TStringBuf(std::begin(x), std::end(x)));
diff --git a/library/cpp/actors/interconnect/poller_actor_darwin.h b/library/cpp/actors/interconnect/poller_actor_darwin.h
index 4cb0a58f8dd..6d5d9142dd1 100644
--- a/library/cpp/actors/interconnect/poller_actor_darwin.h
+++ b/library/cpp/actors/interconnect/poller_actor_darwin.h
@@ -1,95 +1,95 @@
-#pragma once
-
-#include <sys/event.h>
-
-namespace NActors {
-
- class TKqueueThread : public TPollerThreadBase<TKqueueThread> {
- // KQueue file descriptor
- int KqDescriptor;
-
- void SafeKevent(const struct kevent* ev, int size) {
- int rc;
- do {
- rc = kevent(KqDescriptor, ev, size, nullptr, 0, nullptr);
- } while (rc == -1 && errno == EINTR);
- Y_VERIFY(rc != -1, "kevent() failed with %s", strerror(errno));
- }
-
- public:
- TKqueueThread(TActorSystem *actorSystem)
- : TPollerThreadBase(actorSystem)
- {
- // create kqueue
- KqDescriptor = kqueue();
- Y_VERIFY(KqDescriptor != -1, "kqueue() failed with %s", strerror(errno));
-
- // set close-on-exit flag
- {
- int flags = fcntl(KqDescriptor, F_GETFD);
- Y_VERIFY(flags >= 0, "fcntl(F_GETFD) failed with %s", strerror(errno));
- int rc = fcntl(KqDescriptor, F_SETFD, flags | FD_CLOEXEC);
- Y_VERIFY(rc != -1, "fcntl(F_SETFD, +FD_CLOEXEC) failed with %s", strerror(errno));
- }
-
- // register pipe's read end in poller
- struct kevent ev;
- EV_SET(&ev, (int)ReadEnd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, nullptr);
- SafeKevent(&ev, 1);
-
- ISimpleThread::Start(); // start poller thread
- }
-
- ~TKqueueThread() {
- Stop();
- close(KqDescriptor);
- }
-
- void ProcessEventsInLoop() {
- std::array<struct kevent, 256> events;
-
- int numReady = kevent(KqDescriptor, nullptr, 0, events.data(), events.size(), nullptr);
- if (numReady == -1) {
- if (errno == EINTR) {
- return;
- } else {
- Y_FAIL("kevent() failed with %s", strerror(errno));
- }
- }
-
- for (int i = 0; i < numReady; ++i) {
- const struct kevent& ev = events[i];
- if (ev.udata) {
- TSocketRecord *it = static_cast<TSocketRecord*>(ev.udata);
- const bool error = ev.flags & (EV_EOF | EV_ERROR);
- const bool read = error || ev.filter == EVFILT_READ;
- const bool write = error || ev.filter == EVFILT_WRITE;
- Notify(it, read, write);
- }
- }
- }
-
- void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
- struct kevent ev[2];
- const int fd = socket->GetDescriptor();
- EV_SET(&ev[0], fd, EVFILT_READ, EV_DELETE, 0, 0, nullptr);
- EV_SET(&ev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, nullptr);
- SafeKevent(ev, 2);
- }
-
- void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
- int flags = EV_ADD | EV_CLEAR | EV_ENABLE;
- struct kevent ev[2];
- const int fd = record->Socket->GetDescriptor();
- EV_SET(&ev[0], fd, EVFILT_READ, flags, 0, 0, record.Get());
- EV_SET(&ev[1], fd, EVFILT_WRITE, flags, 0, 0, record.Get());
- SafeKevent(ev, 2);
- }
-
- void Request(const TIntrusivePtr<TSocketRecord>& /*socket*/, bool /*read*/, bool /*write*/)
- {} // no special processing here as we use kqueue in edge-triggered mode
- };
-
- using TPollerThread = TKqueueThread;
-
-}
+#pragma once
+
+#include <sys/event.h>
+
+namespace NActors {
+
+ class TKqueueThread : public TPollerThreadBase<TKqueueThread> {
+ // KQueue file descriptor
+ int KqDescriptor;
+
+ void SafeKevent(const struct kevent* ev, int size) {
+ int rc;
+ do {
+ rc = kevent(KqDescriptor, ev, size, nullptr, 0, nullptr);
+ } while (rc == -1 && errno == EINTR);
+ Y_VERIFY(rc != -1, "kevent() failed with %s", strerror(errno));
+ }
+
+ public:
+ TKqueueThread(TActorSystem *actorSystem)
+ : TPollerThreadBase(actorSystem)
+ {
+ // create kqueue
+ KqDescriptor = kqueue();
+ Y_VERIFY(KqDescriptor != -1, "kqueue() failed with %s", strerror(errno));
+
+ // set close-on-exit flag
+ {
+ int flags = fcntl(KqDescriptor, F_GETFD);
+ Y_VERIFY(flags >= 0, "fcntl(F_GETFD) failed with %s", strerror(errno));
+ int rc = fcntl(KqDescriptor, F_SETFD, flags | FD_CLOEXEC);
+ Y_VERIFY(rc != -1, "fcntl(F_SETFD, +FD_CLOEXEC) failed with %s", strerror(errno));
+ }
+
+ // register pipe's read end in poller
+ struct kevent ev;
+ EV_SET(&ev, (int)ReadEnd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, nullptr);
+ SafeKevent(&ev, 1);
+
+ ISimpleThread::Start(); // start poller thread
+ }
+
+ ~TKqueueThread() {
+ Stop();
+ close(KqDescriptor);
+ }
+
+ void ProcessEventsInLoop() {
+ std::array<struct kevent, 256> events;
+
+ int numReady = kevent(KqDescriptor, nullptr, 0, events.data(), events.size(), nullptr);
+ if (numReady == -1) {
+ if (errno == EINTR) {
+ return;
+ } else {
+ Y_FAIL("kevent() failed with %s", strerror(errno));
+ }
+ }
+
+ for (int i = 0; i < numReady; ++i) {
+ const struct kevent& ev = events[i];
+ if (ev.udata) {
+ TSocketRecord *it = static_cast<TSocketRecord*>(ev.udata);
+ const bool error = ev.flags & (EV_EOF | EV_ERROR);
+ const bool read = error || ev.filter == EVFILT_READ;
+ const bool write = error || ev.filter == EVFILT_WRITE;
+ Notify(it, read, write);
+ }
+ }
+ }
+
+ void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
+ struct kevent ev[2];
+ const int fd = socket->GetDescriptor();
+ EV_SET(&ev[0], fd, EVFILT_READ, EV_DELETE, 0, 0, nullptr);
+ EV_SET(&ev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, nullptr);
+ SafeKevent(ev, 2);
+ }
+
+ void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
+ int flags = EV_ADD | EV_CLEAR | EV_ENABLE;
+ struct kevent ev[2];
+ const int fd = record->Socket->GetDescriptor();
+ EV_SET(&ev[0], fd, EVFILT_READ, flags, 0, 0, record.Get());
+ EV_SET(&ev[1], fd, EVFILT_WRITE, flags, 0, 0, record.Get());
+ SafeKevent(ev, 2);
+ }
+
+ void Request(const TIntrusivePtr<TSocketRecord>& /*socket*/, bool /*read*/, bool /*write*/)
+ {} // no special processing here as we use kqueue in edge-triggered mode
+ };
+
+ using TPollerThread = TKqueueThread;
+
+}
diff --git a/library/cpp/actors/interconnect/poller_actor_linux.h b/library/cpp/actors/interconnect/poller_actor_linux.h
index dd4f7c0124d..91f2179e309 100644
--- a/library/cpp/actors/interconnect/poller_actor_linux.h
+++ b/library/cpp/actors/interconnect/poller_actor_linux.h
@@ -1,114 +1,114 @@
-#pragma once
-
-#include <sys/epoll.h>
-
-namespace NActors {
-
- class TEpollThread : public TPollerThreadBase<TEpollThread> {
- // epoll file descriptor
- int EpollDescriptor;
-
- public:
- TEpollThread(TActorSystem *actorSystem)
- : TPollerThreadBase(actorSystem)
- {
- EpollDescriptor = epoll_create1(EPOLL_CLOEXEC);
- Y_VERIFY(EpollDescriptor != -1, "epoll_create1() failed with %s", strerror(errno));
-
- epoll_event event;
- event.data.ptr = nullptr;
- event.events = EPOLLIN;
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_ADD, ReadEnd, &event) == -1) {
- Y_FAIL("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
- }
-
- ISimpleThread::Start(); // start poller thread
- }
-
- ~TEpollThread() {
- Stop();
- close(EpollDescriptor);
- }
-
- void ProcessEventsInLoop() {
- // preallocated array for events
- std::array<epoll_event, 256> events;
-
- // wait indefinitely for event to arrive
- LWPROBE(EpollStartWaitIn);
- int numReady = epoll_wait(EpollDescriptor, events.data(), events.size(), -1);
- LWPROBE(EpollFinishWaitIn, numReady);
-
- // check return status for any errors
- if (numReady == -1) {
- if (errno == EINTR) {
- return; // restart the call a bit later
- } else {
- Y_FAIL("epoll_wait() failed with %s", strerror(errno));
- }
- }
-
- for (int i = 0; i < numReady; ++i) {
- const epoll_event& ev = events[i];
- if (auto *record = static_cast<TSocketRecord*>(ev.data.ptr)) {
- const bool read = ev.events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR);
- const bool write = ev.events & (EPOLLOUT | EPOLLERR);
-
- // remove hit flags from the bit set
- ui32 flags = record->Flags;
- const ui32 remove = (read ? EPOLLIN : 0) | (write ? EPOLLOUT : 0);
- while (!record->Flags.compare_exchange_weak(flags, flags & ~remove))
- {}
- flags &= ~remove;
-
- // rearm poller if some flags remain
- if (flags) {
- epoll_event event;
- event.events = EPOLLONESHOT | EPOLLRDHUP | flags;
- event.data.ptr = record;
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_MOD, record->Socket->GetDescriptor(), &event) == -1) {
- Y_FAIL("epoll_ctl(EPOLL_CTL_MOD) failed with %s", strerror(errno));
- }
- }
-
- // issue notifications
- Notify(record, read, write);
- }
- }
- }
-
- void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_DEL, socket->GetDescriptor(), nullptr) == -1) {
- Y_FAIL("epoll_ctl(EPOLL_CTL_DEL) failed with %s", strerror(errno));
- }
- }
-
- void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
- epoll_event event;
- event.events = EPOLLONESHOT | EPOLLRDHUP;
- event.data.ptr = record.Get();
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_ADD, record->Socket->GetDescriptor(), &event) == -1) {
- Y_FAIL("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
- }
- }
-
- void Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write) {
- const ui32 add = (read ? EPOLLIN : 0) | (write ? EPOLLOUT : 0);
- ui32 flags = record->Flags;
- while (!record->Flags.compare_exchange_weak(flags, flags | add))
- {}
- flags |= add;
- if (flags) {
- epoll_event event;
- event.events = EPOLLONESHOT | EPOLLRDHUP | flags;
- event.data.ptr = record.Get();
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_MOD, record->Socket->GetDescriptor(), &event) == -1) {
- Y_FAIL("epoll_ctl(EPOLL_CTL_MOD) failed with %s", strerror(errno));
- }
- }
- }
- };
-
- using TPollerThread = TEpollThread;
-
-} // namespace NActors
+#pragma once
+
+#include <sys/epoll.h>
+
+namespace NActors {
+
+ class TEpollThread : public TPollerThreadBase<TEpollThread> {
+ // epoll file descriptor
+ int EpollDescriptor;
+
+ public:
+ TEpollThread(TActorSystem *actorSystem)
+ : TPollerThreadBase(actorSystem)
+ {
+ EpollDescriptor = epoll_create1(EPOLL_CLOEXEC);
+ Y_VERIFY(EpollDescriptor != -1, "epoll_create1() failed with %s", strerror(errno));
+
+ epoll_event event;
+ event.data.ptr = nullptr;
+ event.events = EPOLLIN;
+ if (epoll_ctl(EpollDescriptor, EPOLL_CTL_ADD, ReadEnd, &event) == -1) {
+ Y_FAIL("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
+ }
+
+ ISimpleThread::Start(); // start poller thread
+ }
+
+ ~TEpollThread() {
+ Stop();
+ close(EpollDescriptor);
+ }
+
+ void ProcessEventsInLoop() {
+ // preallocated array for events
+ std::array<epoll_event, 256> events;
+
+ // wait indefinitely for event to arrive
+ LWPROBE(EpollStartWaitIn);
+ int numReady = epoll_wait(EpollDescriptor, events.data(), events.size(), -1);
+ LWPROBE(EpollFinishWaitIn, numReady);
+
+ // check return status for any errors
+ if (numReady == -1) {
+ if (errno == EINTR) {
+ return; // restart the call a bit later
+ } else {
+ Y_FAIL("epoll_wait() failed with %s", strerror(errno));
+ }
+ }
+
+ for (int i = 0; i < numReady; ++i) {
+ const epoll_event& ev = events[i];
+ if (auto *record = static_cast<TSocketRecord*>(ev.data.ptr)) {
+ const bool read = ev.events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR);
+ const bool write = ev.events & (EPOLLOUT | EPOLLERR);
+
+ // remove hit flags from the bit set
+ ui32 flags = record->Flags;
+ const ui32 remove = (read ? EPOLLIN : 0) | (write ? EPOLLOUT : 0);
+ while (!record->Flags.compare_exchange_weak(flags, flags & ~remove))
+ {}
+ flags &= ~remove;
+
+ // rearm poller if some flags remain
+ if (flags) {
+ epoll_event event;
+ event.events = EPOLLONESHOT | EPOLLRDHUP | flags;
+ event.data.ptr = record;
+ if (epoll_ctl(EpollDescriptor, EPOLL_CTL_MOD, record->Socket->GetDescriptor(), &event) == -1) {
+ Y_FAIL("epoll_ctl(EPOLL_CTL_MOD) failed with %s", strerror(errno));
+ }
+ }
+
+ // issue notifications
+ Notify(record, read, write);
+ }
+ }
+ }
+
+ void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
+ if (epoll_ctl(EpollDescriptor, EPOLL_CTL_DEL, socket->GetDescriptor(), nullptr) == -1) {
+ Y_FAIL("epoll_ctl(EPOLL_CTL_DEL) failed with %s", strerror(errno));
+ }
+ }
+
+ void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
+ epoll_event event;
+ event.events = EPOLLONESHOT | EPOLLRDHUP;
+ event.data.ptr = record.Get();
+ if (epoll_ctl(EpollDescriptor, EPOLL_CTL_ADD, record->Socket->GetDescriptor(), &event) == -1) {
+ Y_FAIL("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
+ }
+ }
+
+ void Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write) {
+ const ui32 add = (read ? EPOLLIN : 0) | (write ? EPOLLOUT : 0);
+ ui32 flags = record->Flags;
+ while (!record->Flags.compare_exchange_weak(flags, flags | add))
+ {}
+ flags |= add;
+ if (flags) {
+ epoll_event event;
+ event.events = EPOLLONESHOT | EPOLLRDHUP | flags;
+ event.data.ptr = record.Get();
+ if (epoll_ctl(EpollDescriptor, EPOLL_CTL_MOD, record->Socket->GetDescriptor(), &event) == -1) {
+ Y_FAIL("epoll_ctl(EPOLL_CTL_MOD) failed with %s", strerror(errno));
+ }
+ }
+ }
+ };
+
+ using TPollerThread = TEpollThread;
+
+} // namespace NActors
diff --git a/library/cpp/actors/interconnect/poller_actor_win.h b/library/cpp/actors/interconnect/poller_actor_win.h
index 4b4caa0ebd9..8dcd0e68624 100644
--- a/library/cpp/actors/interconnect/poller_actor_win.h
+++ b/library/cpp/actors/interconnect/poller_actor_win.h
@@ -1,103 +1,103 @@
-#pragma once
-
-namespace NActors {
-
- class TSelectThread : public TPollerThreadBase<TSelectThread> {
- TMutex Mutex;
- std::unordered_map<SOCKET, TIntrusivePtr<TSocketRecord>> Descriptors;
-
- enum {
- READ = 1,
- WRITE = 2,
- };
-
- public:
- TSelectThread(TActorSystem *actorSystem)
- : TPollerThreadBase(actorSystem)
- {
- Descriptors.emplace(ReadEnd, nullptr);
- ISimpleThread::Start();
- }
-
- ~TSelectThread() {
- Stop();
- }
-
- void ProcessEventsInLoop() {
- fd_set readfds, writefds, exceptfds;
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptfds);
- int nfds = 0;
- with_lock (Mutex) {
- for (const auto& [key, record] : Descriptors) {
- const int fd = key;
- auto add = [&](auto& set) {
- FD_SET(fd, &set);
- nfds = Max<int>(nfds, fd + 1);
- };
- if (!record || (record->Flags & READ)) {
- add(readfds);
- }
- if (!record || (record->Flags & WRITE)) {
- add(writefds);
- }
- add(exceptfds);
- }
- }
-
- int res = select(nfds, &readfds, &writefds, &exceptfds, nullptr);
- if (res == -1) {
- const int err = LastSocketError();
- if (err == EINTR) {
- return; // try a bit later
- } else {
- Y_FAIL("select() failed with %s", strerror(err));
- }
- }
-
- with_lock (Mutex) {
- for (const auto& [fd, record] : Descriptors) {
- if (record) {
- const bool error = FD_ISSET(fd, &exceptfds);
- const bool read = error || FD_ISSET(fd, &readfds);
- const bool write = error || FD_ISSET(fd, &writefds);
- if (read) {
- record->Flags &= ~READ;
- }
- if (write) {
- record->Flags &= ~WRITE;
- }
- Notify(record.Get(), read, write);
- }
- }
- }
- }
-
- void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
- with_lock (Mutex) {
- Descriptors.erase(socket->GetDescriptor());
- }
- }
-
- void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
- with_lock (Mutex) {
- Descriptors.emplace(record->Socket->GetDescriptor(), record);
- }
- ExecuteSyncOperation(TPollerWakeup());
- }
-
- void Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write) {
- with_lock (Mutex) {
- const auto it = Descriptors.find(record->Socket->GetDescriptor());
- Y_VERIFY(it != Descriptors.end());
- it->second->Flags |= (read ? READ : 0) | (write ? WRITE : 0);
- }
- ExecuteSyncOperation(TPollerWakeup());
- }
- };
-
- using TPollerThread = TSelectThread;
-
-} // NActors
+#pragma once
+
+namespace NActors {
+
+ class TSelectThread : public TPollerThreadBase<TSelectThread> {
+ TMutex Mutex;
+ std::unordered_map<SOCKET, TIntrusivePtr<TSocketRecord>> Descriptors;
+
+ enum {
+ READ = 1,
+ WRITE = 2,
+ };
+
+ public:
+ TSelectThread(TActorSystem *actorSystem)
+ : TPollerThreadBase(actorSystem)
+ {
+ Descriptors.emplace(ReadEnd, nullptr);
+ ISimpleThread::Start();
+ }
+
+ ~TSelectThread() {
+ Stop();
+ }
+
+ void ProcessEventsInLoop() {
+ fd_set readfds, writefds, exceptfds;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ int nfds = 0;
+ with_lock (Mutex) {
+ for (const auto& [key, record] : Descriptors) {
+ const int fd = key;
+ auto add = [&](auto& set) {
+ FD_SET(fd, &set);
+ nfds = Max<int>(nfds, fd + 1);
+ };
+ if (!record || (record->Flags & READ)) {
+ add(readfds);
+ }
+ if (!record || (record->Flags & WRITE)) {
+ add(writefds);
+ }
+ add(exceptfds);
+ }
+ }
+
+ int res = select(nfds, &readfds, &writefds, &exceptfds, nullptr);
+ if (res == -1) {
+ const int err = LastSocketError();
+ if (err == EINTR) {
+ return; // try a bit later
+ } else {
+ Y_FAIL("select() failed with %s", strerror(err));
+ }
+ }
+
+ with_lock (Mutex) {
+ for (const auto& [fd, record] : Descriptors) {
+ if (record) {
+ const bool error = FD_ISSET(fd, &exceptfds);
+ const bool read = error || FD_ISSET(fd, &readfds);
+ const bool write = error || FD_ISSET(fd, &writefds);
+ if (read) {
+ record->Flags &= ~READ;
+ }
+ if (write) {
+ record->Flags &= ~WRITE;
+ }
+ Notify(record.Get(), read, write);
+ }
+ }
+ }
+ }
+
+ void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
+ with_lock (Mutex) {
+ Descriptors.erase(socket->GetDescriptor());
+ }
+ }
+
+ void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
+ with_lock (Mutex) {
+ Descriptors.emplace(record->Socket->GetDescriptor(), record);
+ }
+ ExecuteSyncOperation(TPollerWakeup());
+ }
+
+ void Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write) {
+ with_lock (Mutex) {
+ const auto it = Descriptors.find(record->Socket->GetDescriptor());
+ Y_VERIFY(it != Descriptors.end());
+ it->second->Flags |= (read ? READ : 0) | (write ? WRITE : 0);
+ }
+ ExecuteSyncOperation(TPollerWakeup());
+ }
+ };
+
+ using TPollerThread = TSelectThread;
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/poller_tcp.cpp b/library/cpp/actors/interconnect/poller_tcp.cpp
index 8267df31eae..5eb7fa854ca 100644
--- a/library/cpp/actors/interconnect/poller_tcp.cpp
+++ b/library/cpp/actors/interconnect/poller_tcp.cpp
@@ -1,6 +1,6 @@
-#include "poller_tcp.h"
-
-namespace NInterconnect {
+#include "poller_tcp.h"
+
+namespace NInterconnect {
TPollerThreads::TPollerThreads(size_t units, bool useSelect)
: Units(units)
{
@@ -8,28 +8,28 @@ namespace NInterconnect {
for (auto& unit : Units)
unit = TPollerUnit::Make(useSelect);
}
-
+
TPollerThreads::~TPollerThreads() {
}
-
+
void TPollerThreads::Start() {
for (const auto& unit : Units)
unit->Start();
}
-
+
void TPollerThreads::Stop() {
for (const auto& unit : Units)
unit->Stop();
}
-
+
void TPollerThreads::StartRead(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) {
auto& unit = Units[THash<SOCKET>()(s->GetDescriptor()) % Units.size()];
unit->StartReadOperation(s, std::move(operation));
}
-
+
void TPollerThreads::StartWrite(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) {
auto& unit = Units[THash<SOCKET>()(s->GetDescriptor()) % Units.size()];
unit->StartWriteOperation(s, std::move(operation));
}
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp.h b/library/cpp/actors/interconnect/poller_tcp.h
index 310265eccd5..fd3075fc960 100644
--- a/library/cpp/actors/interconnect/poller_tcp.h
+++ b/library/cpp/actors/interconnect/poller_tcp.h
@@ -1,25 +1,25 @@
-#pragma once
-
-#include "poller_tcp_unit.h"
-#include "poller.h"
-
-#include <util/generic/vector.h>
-#include <util/generic/hash.h>
-
-namespace NInterconnect {
+#pragma once
+
+#include "poller_tcp_unit.h"
+#include "poller.h"
+
+#include <util/generic/vector.h>
+#include <util/generic/hash.h>
+
+namespace NInterconnect {
class TPollerThreads: public NActors::IPoller {
public:
TPollerThreads(size_t units = 1U, bool useSelect = false);
~TPollerThreads();
-
+
void Start();
void Stop();
-
+
void StartRead(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) override;
void StartWrite(const TIntrusivePtr<TSharedDescriptor>& s, TFDDelegate&& operation) override;
-
+
private:
TVector<TPollerUnit::TPtr> Units;
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit.cpp b/library/cpp/actors/interconnect/poller_tcp_unit.cpp
index 59e7dda8107..7b11cd1cb18 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit.cpp
+++ b/library/cpp/actors/interconnect/poller_tcp_unit.cpp
@@ -1,103 +1,103 @@
-#include "poller_tcp_unit.h"
-
-#if !defined(_win_) && !defined(_darwin_)
+#include "poller_tcp_unit.h"
+
+#if !defined(_win_) && !defined(_darwin_)
#include "poller_tcp_unit_epoll.h"
-#endif
-
-#include "poller_tcp_unit_select.h"
-#include "poller.h"
-
+#endif
+
+#include "poller_tcp_unit_select.h"
+#include "poller.h"
+
#include <library/cpp/actors/prof/tag.h>
#include <library/cpp/actors/util/intrinsics.h>
-#if defined _linux_
+#if defined _linux_
#include <pthread.h>
-#endif
-
-namespace NInterconnect {
+#endif
+
+namespace NInterconnect {
TPollerUnit::TPtr
TPollerUnit::Make(bool useSelect) {
-#if defined(_win_) || defined(_darwin_)
+#if defined(_win_) || defined(_darwin_)
Y_UNUSED(useSelect);
return TPtr(new TPollerUnitSelect);
-#else
+#else
return useSelect ? TPtr(new TPollerUnitSelect) : TPtr(new TPollerUnitEpoll);
-#endif
+#endif
}
-
+
TPollerUnit::TPollerUnit()
: StopFlag(true)
, ReadLoop(TThread::TParams(IdleThread<false>, this).SetName("network read"))
, WriteLoop(TThread::TParams(IdleThread<true>, this).SetName("network write"))
{
}
-
+
TPollerUnit::~TPollerUnit() {
if (!AtomicLoad(&StopFlag))
Stop();
}
-
+
void
TPollerUnit::Start() {
AtomicStore(&StopFlag, false);
ReadLoop.Start();
WriteLoop.Start();
}
-
+
void
TPollerUnit::Stop() {
AtomicStore(&StopFlag, true);
ReadLoop.Join();
WriteLoop.Join();
}
-
+
template <>
TPollerUnit::TSide&
TPollerUnit::GetSide<false>() {
return Read;
}
-
+
template <>
TPollerUnit::TSide&
TPollerUnit::GetSide<true>() {
return Write;
}
-
+
void
TPollerUnit::StartReadOperation(
- const TIntrusivePtr<TSharedDescriptor>& stream,
+ const TIntrusivePtr<TSharedDescriptor>& stream,
TFDDelegate&& operation) {
Y_VERIFY_DEBUG(stream);
if (AtomicLoad(&StopFlag))
return;
GetSide<false>().InputQueue.Push(TSide::TItem(stream, std::move(operation)));
}
-
+
void
TPollerUnit::StartWriteOperation(
- const TIntrusivePtr<TSharedDescriptor>& stream,
+ const TIntrusivePtr<TSharedDescriptor>& stream,
TFDDelegate&& operation) {
Y_VERIFY_DEBUG(stream);
if (AtomicLoad(&StopFlag))
return;
GetSide<true>().InputQueue.Push(TSide::TItem(stream, std::move(operation)));
}
-
+
template <bool IsWrite>
void*
TPollerUnit::IdleThread(void* param) {
- // TODO: musl-libc version of `sched_param` struct is for some reason different from pthread
- // version in Ubuntu 12.04
+ // TODO: musl-libc version of `sched_param` struct is for some reason different from pthread
+ // version in Ubuntu 12.04
#if defined(_linux_) && !defined(_musl_)
pthread_t threadSelf = pthread_self();
sched_param sparam = {20};
pthread_setschedparam(threadSelf, SCHED_FIFO, &sparam);
-#endif
-
+#endif
+
static_cast<TPollerUnit*>(param)->RunLoop<IsWrite>();
return nullptr;
}
-
+
template <>
void
TPollerUnit::RunLoop<false>() {
@@ -105,7 +105,7 @@ namespace NInterconnect {
while (!AtomicLoad(&StopFlag))
ProcessRead();
}
-
+
template <>
void
TPollerUnit::RunLoop<true>() {
@@ -113,7 +113,7 @@ namespace NInterconnect {
while (!AtomicLoad(&StopFlag))
ProcessWrite();
}
-
+
void
TPollerUnit::TSide::ProcessInput() {
if (!InputQueue.IsEmpty())
@@ -123,4 +123,4 @@ namespace NInterconnect {
Y_FAIL("Descriptor is already in pooler.");
} while (InputQueue.Pop());
}
-}
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit.h b/library/cpp/actors/interconnect/poller_tcp_unit.h
index 692168b9689..7e57c7dd505 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit.h
+++ b/library/cpp/actors/interconnect/poller_tcp_unit.h
@@ -1,67 +1,67 @@
-#pragma once
-
-#include <util/system/thread.h>
+#pragma once
+
+#include <util/system/thread.h>
#include <library/cpp/actors/util/funnel_queue.h>
-
-#include "interconnect_stream.h"
-
-#include <memory>
-#include <functional>
-#include <unordered_map>
-
-namespace NInterconnect {
+
+#include "interconnect_stream.h"
+
+#include <memory>
+#include <functional>
+#include <unordered_map>
+
+namespace NInterconnect {
using NActors::TFDDelegate;
using NActors::TSharedDescriptor;
-
+
class TPollerUnit {
public:
typedef std::unique_ptr<TPollerUnit> TPtr;
-
+
static TPtr Make(bool useSelect);
-
+
void Start();
void Stop();
-
+
virtual void StartReadOperation(
const TIntrusivePtr<TSharedDescriptor>& stream,
TFDDelegate&& operation);
-
+
virtual void StartWriteOperation(
const TIntrusivePtr<TSharedDescriptor>& stream,
TFDDelegate&& operation);
-
+
virtual ~TPollerUnit();
-
+
private:
virtual void ProcessRead() = 0;
virtual void ProcessWrite() = 0;
-
+
template <bool IsWrite>
static void* IdleThread(void* param);
-
+
template <bool IsWrite>
void RunLoop();
-
+
volatile bool StopFlag;
TThread ReadLoop, WriteLoop;
-
+
protected:
TPollerUnit();
-
+
struct TSide {
using TOperations =
std::unordered_map<SOCKET,
std::pair<TIntrusivePtr<TSharedDescriptor>, TFDDelegate>>;
-
+
TOperations Operations;
using TItem = TOperations::mapped_type;
TFunnelQueue<TItem> InputQueue;
-
+
void ProcessInput();
} Read, Write;
-
+
template <bool IsWrite>
TSide& GetSide();
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp b/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
index c78538b95bd..436cd532bf1 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
+++ b/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
@@ -1,13 +1,13 @@
-#include "poller_tcp_unit_epoll.h"
-#if !defined(_win_) && !defined(_darwin_)
-#include <unistd.h>
-#include <sys/epoll.h>
-
-#include <csignal>
-#include <cerrno>
-#include <cstring>
-
-namespace NInterconnect {
+#include "poller_tcp_unit_epoll.h"
+#if !defined(_win_) && !defined(_darwin_)
+#include <unistd.h>
+#include <sys/epoll.h>
+
+#include <csignal>
+#include <cerrno>
+#include <cstring>
+
+namespace NInterconnect {
namespace {
void
DeleteEpoll(int epoll, SOCKET stream) {
@@ -17,18 +17,18 @@ namespace NInterconnect {
Y_FAIL("epoll delete error!");
}
}
-
+
template <ui32 Events>
void
AddEpoll(int epoll, SOCKET stream) {
- ::epoll_event event = {.events = Events};
+ ::epoll_event event = {.events = Events};
event.data.fd = stream;
if (::epoll_ctl(epoll, EPOLL_CTL_ADD, stream, &event)) {
Cerr << "epoll_ctl errno: " << errno << Endl;
Y_FAIL("epoll add error!");
}
}
-
+
int
Initialize() {
const auto epoll = ::epoll_create(10000);
@@ -36,8 +36,8 @@ namespace NInterconnect {
return epoll;
}
- }
-
+ }
+
TPollerUnitEpoll::TPollerUnitEpoll()
: ReadDescriptor(Initialize())
, WriteDescriptor(Initialize())
@@ -46,58 +46,58 @@ namespace NInterconnect {
::sigemptyset(&sigmask);
::sigaddset(&sigmask, SIGPIPE);
::sigaddset(&sigmask, SIGTERM);
- }
-
+ }
+
TPollerUnitEpoll::~TPollerUnitEpoll() {
::close(ReadDescriptor);
::close(WriteDescriptor);
}
-
+
template <>
int TPollerUnitEpoll::GetDescriptor<false>() const {
return ReadDescriptor;
}
-
+
template <>
int TPollerUnitEpoll::GetDescriptor<true>() const {
return WriteDescriptor;
}
-
+
void
TPollerUnitEpoll::StartReadOperation(
- const TIntrusivePtr<TSharedDescriptor>& s,
+ const TIntrusivePtr<TSharedDescriptor>& s,
TFDDelegate&& operation) {
TPollerUnit::StartReadOperation(s, std::move(operation));
AddEpoll<EPOLLRDHUP | EPOLLIN>(ReadDescriptor, s->GetDescriptor());
}
-
+
void
TPollerUnitEpoll::StartWriteOperation(
- const TIntrusivePtr<TSharedDescriptor>& s,
+ const TIntrusivePtr<TSharedDescriptor>& s,
TFDDelegate&& operation) {
TPollerUnit::StartWriteOperation(s, std::move(operation));
AddEpoll<EPOLLRDHUP | EPOLLOUT>(WriteDescriptor, s->GetDescriptor());
}
-
+
constexpr int EVENTS_BUF_SIZE = 128;
-
+
template <bool WriteOp>
void
TPollerUnitEpoll::Process() {
::epoll_event events[EVENTS_BUF_SIZE];
-
+
const int epoll = GetDescriptor<WriteOp>();
-
+
/* Timeout just to check StopFlag sometimes */
const int result =
::epoll_pwait(epoll, events, EVENTS_BUF_SIZE, 200, &sigmask);
-
+
if (result == -1 && errno != EINTR)
Y_FAIL("epoll wait error!");
-
+
auto& side = GetSide<WriteOp>();
side.ProcessInput();
-
+
for (int i = 0; i < result; ++i) {
const auto it = side.Operations.find(events[i].data.fd);
if (side.Operations.end() == it)
@@ -107,19 +107,19 @@ namespace NInterconnect {
side.Operations.erase(it);
finalizer();
}
- }
- }
-
+ }
+ }
+
void
TPollerUnitEpoll::ProcessRead() {
Process<false>();
}
-
+
void
TPollerUnitEpoll::ProcessWrite() {
Process<true>();
}
-
-}
-
-#endif
+
+}
+
+#endif
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h b/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h
index ff7893eba2b..cff553f2b7b 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h
+++ b/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h
@@ -1,33 +1,33 @@
-#pragma once
-
-#include "poller_tcp_unit.h"
-
-namespace NInterconnect {
+#pragma once
+
+#include "poller_tcp_unit.h"
+
+namespace NInterconnect {
class TPollerUnitEpoll: public TPollerUnit {
public:
TPollerUnitEpoll();
virtual ~TPollerUnitEpoll();
-
+
private:
virtual void StartReadOperation(
const TIntrusivePtr<TSharedDescriptor>& s,
TFDDelegate&& operation) override;
-
+
virtual void StartWriteOperation(
const TIntrusivePtr<TSharedDescriptor>& s,
TFDDelegate&& operation) override;
-
+
virtual void ProcessRead() override;
virtual void ProcessWrite() override;
-
+
template <bool Write>
void Process();
-
+
template <bool Write>
int GetDescriptor() const;
-
+
const int ReadDescriptor, WriteDescriptor;
::sigset_t sigmask;
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp b/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
index ae7aaad5669..c1b6ae59a16 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
+++ b/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
@@ -1,67 +1,67 @@
-#include "poller_tcp_unit_select.h"
-
-#include <csignal>
-
-#if defined(_win_)
-#include <winsock2.h>
-#define SOCKET_ERROR_SOURCE ::WSAGetLastError()
-#elif defined(_darwin_)
-#include <cerrno>
-#define SOCKET_ERROR_SOURCE errno
-typedef timeval TIMEVAL;
-#else
-#include <cerrno>
-#define SOCKET_ERROR_SOURCE errno
-#endif
-
-namespace NInterconnect {
+#include "poller_tcp_unit_select.h"
+
+#include <csignal>
+
+#if defined(_win_)
+#include <winsock2.h>
+#define SOCKET_ERROR_SOURCE ::WSAGetLastError()
+#elif defined(_darwin_)
+#include <cerrno>
+#define SOCKET_ERROR_SOURCE errno
+typedef timeval TIMEVAL;
+#else
+#include <cerrno>
+#define SOCKET_ERROR_SOURCE errno
+#endif
+
+namespace NInterconnect {
TPollerUnitSelect::TPollerUnitSelect() {
}
-
+
TPollerUnitSelect::~TPollerUnitSelect() {
}
-
+
template <bool IsWrite>
void
TPollerUnitSelect::Process() {
auto& side = GetSide<IsWrite>();
side.ProcessInput();
-
+
enum : size_t { R,
W,
E };
static const auto O = IsWrite ? W : R;
-
+
::fd_set sets[3];
-
+
FD_ZERO(&sets[R]);
FD_ZERO(&sets[W]);
FD_ZERO(&sets[E]);
-
+
for (const auto& operation : side.Operations) {
FD_SET(operation.first, &sets[O]);
FD_SET(operation.first, &sets[E]);
}
-
-#if defined(_win_)
+
+#if defined(_win_)
::TIMEVAL timeout = {0L, 99991L};
const auto numberEvents = !side.Operations.empty() ? ::select(FD_SETSIZE, &sets[R], &sets[W], &sets[E], &timeout)
: (::Sleep(100), 0);
-#elif defined(_darwin_)
+#elif defined(_darwin_)
::TIMEVAL timeout = {0L, 99991L};
const auto numberEvents = ::select(FD_SETSIZE, &sets[R], &sets[W], &sets[E], &timeout);
-#else
+#else
::sigset_t sigmask;
::sigemptyset(&sigmask);
::sigaddset(&sigmask, SIGPIPE);
::sigaddset(&sigmask, SIGTERM);
-
+
struct ::timespec timeout = {0L, 99999989L};
const auto numberEvents = ::pselect(FD_SETSIZE, &sets[R], &sets[W], &sets[E], &timeout, &sigmask);
-#endif
-
+#endif
+
Y_VERIFY_DEBUG(numberEvents >= 0);
-
+
for (auto it = side.Operations.cbegin(); side.Operations.cend() != it;) {
if (FD_ISSET(it->first, &sets[O]) || FD_ISSET(it->first, &sets[E]))
if (const auto& finalizer = it->second.second(it->second.first)) {
@@ -71,16 +71,16 @@ namespace NInterconnect {
}
++it;
}
- }
-
+ }
+
void
TPollerUnitSelect::ProcessRead() {
Process<false>();
}
-
+
void
TPollerUnitSelect::ProcessWrite() {
Process<true>();
}
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit_select.h b/library/cpp/actors/interconnect/poller_tcp_unit_select.h
index 0c152177961..156ecc4478b 100644
--- a/library/cpp/actors/interconnect/poller_tcp_unit_select.h
+++ b/library/cpp/actors/interconnect/poller_tcp_unit_select.h
@@ -1,19 +1,19 @@
-#pragma once
-
-#include "poller_tcp_unit.h"
-
-namespace NInterconnect {
+#pragma once
+
+#include "poller_tcp_unit.h"
+
+namespace NInterconnect {
class TPollerUnitSelect: public TPollerUnit {
public:
TPollerUnitSelect();
virtual ~TPollerUnitSelect();
-
+
private:
virtual void ProcessRead() override;
virtual void ProcessWrite() override;
-
+
template <bool IsWrite>
void Process();
};
-
-}
+
+}
diff --git a/library/cpp/actors/interconnect/profiler.h b/library/cpp/actors/interconnect/profiler.h
index 77a59e31794..7c54c4737e2 100644
--- a/library/cpp/actors/interconnect/profiler.h
+++ b/library/cpp/actors/interconnect/profiler.h
@@ -1,142 +1,142 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/util/datetime.h>
-namespace NActors {
-
- class TProfiled {
- enum class EType : ui32 {
- ENTRY,
- EXIT,
- };
-
- struct TItem {
- EType Type; // entry kind
- int Line;
- const char *Marker; // name of the profiled function/part
+namespace NActors {
+
+ class TProfiled {
+ enum class EType : ui32 {
+ ENTRY,
+ EXIT,
+ };
+
+ struct TItem {
+ EType Type; // entry kind
+ int Line;
+ const char *Marker; // name of the profiled function/part
ui64 Timestamp; // cycles
- };
-
- bool Enable = false;
- mutable TDeque<TItem> Items;
-
- friend class TFunction;
-
- public:
- class TFunction {
- const TProfiled& Profiled;
-
- public:
- TFunction(const TProfiled& profiled, const char *name, int line)
- : Profiled(profiled)
- {
- Log(EType::ENTRY, name, line);
- }
-
- ~TFunction() {
- Log(EType::EXIT, nullptr, 0);
- }
-
- private:
- void Log(EType type, const char *marker, int line) {
- if (Profiled.Enable) {
- Profiled.Items.push_back(TItem{
- type,
- line,
- marker,
+ };
+
+ bool Enable = false;
+ mutable TDeque<TItem> Items;
+
+ friend class TFunction;
+
+ public:
+ class TFunction {
+ const TProfiled& Profiled;
+
+ public:
+ TFunction(const TProfiled& profiled, const char *name, int line)
+ : Profiled(profiled)
+ {
+ Log(EType::ENTRY, name, line);
+ }
+
+ ~TFunction() {
+ Log(EType::EXIT, nullptr, 0);
+ }
+
+ private:
+ void Log(EType type, const char *marker, int line) {
+ if (Profiled.Enable) {
+ Profiled.Items.push_back(TItem{
+ type,
+ line,
+ marker,
GetCycleCountFast()
- });
- }
- }
- };
-
- public:
- void Start() {
- Enable = true;
- }
-
- void Finish() {
- Items.clear();
- Enable = false;
- }
-
- TDuration Duration() const {
- return CyclesToDuration(Items ? Items.back().Timestamp - Items.front().Timestamp : 0);
- }
-
- TString Format() const {
- TDeque<TItem>::iterator it = Items.begin();
- TString res = FormatLevel(it);
- Y_VERIFY(it == Items.end());
- return res;
- }
-
- private:
- TString FormatLevel(TDeque<TItem>::iterator& it) const {
- struct TRecord {
- TString Marker;
- ui64 Duration;
- TString Interior;
-
- bool operator <(const TRecord& other) const {
- return Duration < other.Duration;
- }
- };
- TVector<TRecord> records;
-
- while (it != Items.end() && it->Type != EType::EXIT) {
- Y_VERIFY(it->Type == EType::ENTRY);
- const TString marker = Sprintf("%s:%d", it->Marker, it->Line);
- const ui64 begin = it->Timestamp;
- ++it;
- const TString interior = FormatLevel(it);
- Y_VERIFY(it != Items.end());
- Y_VERIFY(it->Type == EType::EXIT);
- const ui64 end = it->Timestamp;
- records.push_back(TRecord{marker, end - begin, interior});
- ++it;
- }
-
- TStringStream s;
- const ui64 cyclesPerMs = GetCyclesPerMillisecond();
-
- if (records.size() <= 10) {
- bool first = true;
- for (const TRecord& record : records) {
- if (first) {
- first = false;
- } else {
- s << " ";
+ });
+ }
+ }
+ };
+
+ public:
+ void Start() {
+ Enable = true;
+ }
+
+ void Finish() {
+ Items.clear();
+ Enable = false;
+ }
+
+ TDuration Duration() const {
+ return CyclesToDuration(Items ? Items.back().Timestamp - Items.front().Timestamp : 0);
+ }
+
+ TString Format() const {
+ TDeque<TItem>::iterator it = Items.begin();
+ TString res = FormatLevel(it);
+ Y_VERIFY(it == Items.end());
+ return res;
+ }
+
+ private:
+ TString FormatLevel(TDeque<TItem>::iterator& it) const {
+ struct TRecord {
+ TString Marker;
+ ui64 Duration;
+ TString Interior;
+
+ bool operator <(const TRecord& other) const {
+ return Duration < other.Duration;
+ }
+ };
+ TVector<TRecord> records;
+
+ while (it != Items.end() && it->Type != EType::EXIT) {
+ Y_VERIFY(it->Type == EType::ENTRY);
+ const TString marker = Sprintf("%s:%d", it->Marker, it->Line);
+ const ui64 begin = it->Timestamp;
+ ++it;
+ const TString interior = FormatLevel(it);
+ Y_VERIFY(it != Items.end());
+ Y_VERIFY(it->Type == EType::EXIT);
+ const ui64 end = it->Timestamp;
+ records.push_back(TRecord{marker, end - begin, interior});
+ ++it;
+ }
+
+ TStringStream s;
+ const ui64 cyclesPerMs = GetCyclesPerMillisecond();
+
+ if (records.size() <= 10) {
+ bool first = true;
+ for (const TRecord& record : records) {
+ if (first) {
+ first = false;
+ } else {
+ s << " ";
+ }
+ s << record.Marker << "(" << (record.Duration * 1000000 / cyclesPerMs) << "ns)";
+ if (record.Interior) {
+ s << " {" << record.Interior << "}";
+ }
+ }
+ } else {
+ TMap<TString, TVector<TRecord>> m;
+ for (TRecord& r : records) {
+ const TString key = r.Marker;
+ m[key].push_back(std::move(r));
+ }
+
+ s << "unordered ";
+ for (auto& [key, value] : m) {
+ auto i = std::max_element(value.begin(), value.end());
+ ui64 sum = 0;
+ for (const auto& item : value) {
+ sum += item.Duration;
+ }
+ sum = sum * 1000000 / cyclesPerMs;
+ s << key << " num# " << value.size() << " sum# " << sum << "ns max# " << (i->Duration * 1000000 / cyclesPerMs) << "ns";
+ if (i->Interior) {
+ s << " {" << i->Interior << "}";
}
- s << record.Marker << "(" << (record.Duration * 1000000 / cyclesPerMs) << "ns)";
- if (record.Interior) {
- s << " {" << record.Interior << "}";
- }
- }
- } else {
- TMap<TString, TVector<TRecord>> m;
- for (TRecord& r : records) {
- const TString key = r.Marker;
- m[key].push_back(std::move(r));
- }
-
- s << "unordered ";
- for (auto& [key, value] : m) {
- auto i = std::max_element(value.begin(), value.end());
- ui64 sum = 0;
- for (const auto& item : value) {
- sum += item.Duration;
- }
- sum = sum * 1000000 / cyclesPerMs;
- s << key << " num# " << value.size() << " sum# " << sum << "ns max# " << (i->Duration * 1000000 / cyclesPerMs) << "ns";
- if (i->Interior) {
- s << " {" << i->Interior << "}";
- }
- }
- }
-
- return s.Str();
- }
- };
-
-} // NActors
+ }
+ }
+
+ return s.Str();
+ }
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/slowpoke_actor.h b/library/cpp/actors/interconnect/slowpoke_actor.h
index 4b02e5da48c..7995d9ae5c1 100644
--- a/library/cpp/actors/interconnect/slowpoke_actor.h
+++ b/library/cpp/actors/interconnect/slowpoke_actor.h
@@ -1,47 +1,47 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
-
-namespace NActors {
-
- class TSlowpokeActor : public TActorBootstrapped<TSlowpokeActor> {
- const TDuration Duration;
- const TDuration SleepMin;
- const TDuration SleepMax;
- const TDuration RescheduleMin;
- const TDuration RescheduleMax;
-
- public:
+
+namespace NActors {
+
+ class TSlowpokeActor : public TActorBootstrapped<TSlowpokeActor> {
+ const TDuration Duration;
+ const TDuration SleepMin;
+ const TDuration SleepMax;
+ const TDuration RescheduleMin;
+ const TDuration RescheduleMax;
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::INTERCONNECT_COMMON;
}
- TSlowpokeActor(TDuration duration, TDuration sleepMin, TDuration sleepMax, TDuration rescheduleMin, TDuration rescheduleMax)
- : Duration(duration)
- , SleepMin(sleepMin)
- , SleepMax(sleepMax)
- , RescheduleMin(rescheduleMin)
- , RescheduleMax(rescheduleMax)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc, ctx, Duration, new TEvents::TEvPoisonPill);
- HandleWakeup(ctx);
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- Sleep(RandomDuration(SleepMin, SleepMax));
- ctx.Schedule(RandomDuration(RescheduleMin, RescheduleMax), new TEvents::TEvWakeup);
- }
-
- static TDuration RandomDuration(TDuration min, TDuration max) {
- return min + TDuration::FromValue(RandomNumber<ui64>(max.GetValue() - min.GetValue() + 1));
- }
-
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::PoisonPill, Die)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- )
- };
-
-} // NActors
+ TSlowpokeActor(TDuration duration, TDuration sleepMin, TDuration sleepMax, TDuration rescheduleMin, TDuration rescheduleMax)
+ : Duration(duration)
+ , SleepMin(sleepMin)
+ , SleepMax(sleepMax)
+ , RescheduleMin(rescheduleMin)
+ , RescheduleMax(rescheduleMax)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc, ctx, Duration, new TEvents::TEvPoisonPill);
+ HandleWakeup(ctx);
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ Sleep(RandomDuration(SleepMin, SleepMax));
+ ctx.Schedule(RandomDuration(RescheduleMin, RescheduleMax), new TEvents::TEvWakeup);
+ }
+
+ static TDuration RandomDuration(TDuration min, TDuration max) {
+ return min + TDuration::FromValue(RandomNumber<ui64>(max.GetValue() - min.GetValue() + 1));
+ }
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::PoisonPill, Die)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ )
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/types.cpp b/library/cpp/actors/interconnect/types.cpp
index 979c55f2777..cbbe347fbc0 100644
--- a/library/cpp/actors/interconnect/types.cpp
+++ b/library/cpp/actors/interconnect/types.cpp
@@ -1,564 +1,564 @@
-#include "types.h"
-#include <util/string/printf.h>
-#include <util/generic/vector.h>
-#include <errno.h>
-
-namespace NActors {
-
- TVector<const char*> TDisconnectReason::Reasons = {
- "EndOfStream",
- "CloseOnIdle",
- "LostConnection",
- "DeadPeer",
- "NewSession",
- "HandshakeFailTransient",
- "HandshakeFailPermanent",
- "UserRequest",
- "Debug",
- "ChecksumError",
- "FormatError",
- "EventTooLarge",
- "QueueOverload",
- "E2BIG",
- "EACCES",
- "EADDRINUSE",
- "EADDRNOTAVAIL",
- "EADV",
- "EAFNOSUPPORT",
- "EAGAIN",
- "EALREADY",
- "EBADE",
- "EBADF",
- "EBADFD",
- "EBADMSG",
- "EBADR",
- "EBADRQC",
- "EBADSLT",
- "EBFONT",
- "EBUSY",
- "ECANCELED",
- "ECHILD",
- "ECHRNG",
- "ECOMM",
- "ECONNABORTED",
- "ECONNREFUSED",
- "ECONNRESET",
- "EDEADLK",
- "EDEADLOCK",
- "EDESTADDRREQ",
- "EDOM",
- "EDOTDOT",
- "EDQUOT",
- "EEXIST",
- "EFAULT",
- "EFBIG",
- "EHOSTDOWN",
- "EHOSTUNREACH",
- "EHWPOISON",
- "EIDRM",
- "EILSEQ",
- "EINPROGRESS",
- "EINTR",
- "EINVAL",
- "EIO",
- "EISCONN",
- "EISDIR",
- "EISNAM",
- "EKEYEXPIRED",
- "EKEYREJECTED",
- "EKEYREVOKED",
- "EL2HLT",
- "EL2NSYNC",
- "EL3HLT",
- "EL3RST",
- "ELIBACC",
- "ELIBBAD",
- "ELIBEXEC",
- "ELIBMAX",
- "ELIBSCN",
- "ELNRNG",
- "ELOOP",
- "EMEDIUMTYPE",
- "EMFILE",
- "EMLINK",
- "EMSGSIZE",
- "EMULTIHOP",
- "ENAMETOOLONG",
- "ENAVAIL",
- "ENETDOWN",
- "ENETRESET",
- "ENETUNREACH",
- "ENFILE",
- "ENOANO",
- "ENOBUFS",
- "ENOCSI",
- "ENODATA",
- "ENODEV",
- "ENOENT",
- "ENOEXEC",
- "ENOKEY",
- "ENOLCK",
- "ENOLINK",
- "ENOMEDIUM",
- "ENOMEM",
- "ENOMSG",
- "ENONET",
- "ENOPKG",
- "ENOPROTOOPT",
- "ENOSPC",
- "ENOSR",
- "ENOSTR",
- "ENOSYS",
- "ENOTBLK",
- "ENOTCONN",
- "ENOTDIR",
- "ENOTEMPTY",
- "ENOTNAM",
- "ENOTRECOVERABLE",
- "ENOTSOCK",
- "ENOTTY",
- "ENOTUNIQ",
- "ENXIO",
- "EOPNOTSUPP",
- "EOVERFLOW",
- "EOWNERDEAD",
- "EPERM",
- "EPFNOSUPPORT",
- "EPIPE",
- "EPROTO",
- "EPROTONOSUPPORT",
- "EPROTOTYPE",
- "ERANGE",
- "EREMCHG",
- "EREMOTE",
- "EREMOTEIO",
- "ERESTART",
- "ERFKILL",
- "EROFS",
- "ESHUTDOWN",
- "ESOCKTNOSUPPORT",
- "ESPIPE",
- "ESRCH",
- "ESRMNT",
- "ESTALE",
- "ESTRPIPE",
- "ETIME",
- "ETIMEDOUT",
- "ETOOMANYREFS",
- "ETXTBSY",
- "EUCLEAN",
- "EUNATCH",
- "EUSERS",
- "EWOULDBLOCK",
- "EXDEV",
- "EXFULL",
- };
-
- TDisconnectReason TDisconnectReason::FromErrno(int err) {
- switch (err) {
-#define REASON(ERRNO) case ERRNO: return TDisconnectReason(TString(#ERRNO))
-#if defined(E2BIG)
- REASON(E2BIG);
-#endif
-#if defined(EACCES)
- REASON(EACCES);
-#endif
-#if defined(EADDRINUSE)
- REASON(EADDRINUSE);
-#endif
-#if defined(EADDRNOTAVAIL)
- REASON(EADDRNOTAVAIL);
-#endif
-#if defined(EADV)
- REASON(EADV);
-#endif
-#if defined(EAFNOSUPPORT)
- REASON(EAFNOSUPPORT);
-#endif
-#if defined(EAGAIN)
- REASON(EAGAIN);
-#endif
-#if defined(EALREADY)
- REASON(EALREADY);
-#endif
-#if defined(EBADE)
- REASON(EBADE);
-#endif
-#if defined(EBADF)
- REASON(EBADF);
-#endif
-#if defined(EBADFD)
- REASON(EBADFD);
-#endif
-#if defined(EBADMSG)
- REASON(EBADMSG);
-#endif
-#if defined(EBADR)
- REASON(EBADR);
-#endif
-#if defined(EBADRQC)
- REASON(EBADRQC);
-#endif
-#if defined(EBADSLT)
- REASON(EBADSLT);
-#endif
-#if defined(EBFONT)
- REASON(EBFONT);
-#endif
-#if defined(EBUSY)
- REASON(EBUSY);
-#endif
-#if defined(ECANCELED)
- REASON(ECANCELED);
-#endif
-#if defined(ECHILD)
- REASON(ECHILD);
-#endif
-#if defined(ECHRNG)
- REASON(ECHRNG);
-#endif
-#if defined(ECOMM)
- REASON(ECOMM);
-#endif
-#if defined(ECONNABORTED)
- REASON(ECONNABORTED);
-#endif
-#if defined(ECONNREFUSED)
- REASON(ECONNREFUSED);
-#endif
-#if defined(ECONNRESET)
- REASON(ECONNRESET);
-#endif
-#if defined(EDEADLK)
- REASON(EDEADLK);
-#endif
-#if defined(EDEADLOCK) && (!defined(EDEADLK) || EDEADLOCK != EDEADLK)
- REASON(EDEADLOCK);
-#endif
-#if defined(EDESTADDRREQ)
- REASON(EDESTADDRREQ);
-#endif
-#if defined(EDOM)
- REASON(EDOM);
-#endif
-#if defined(EDOTDOT)
- REASON(EDOTDOT);
-#endif
-#if defined(EDQUOT)
- REASON(EDQUOT);
-#endif
-#if defined(EEXIST)
- REASON(EEXIST);
-#endif
-#if defined(EFAULT)
- REASON(EFAULT);
-#endif
-#if defined(EFBIG)
- REASON(EFBIG);
-#endif
-#if defined(EHOSTDOWN)
- REASON(EHOSTDOWN);
-#endif
-#if defined(EHOSTUNREACH)
- REASON(EHOSTUNREACH);
-#endif
-#if defined(EHWPOISON)
- REASON(EHWPOISON);
-#endif
-#if defined(EIDRM)
- REASON(EIDRM);
-#endif
-#if defined(EILSEQ)
- REASON(EILSEQ);
-#endif
-#if defined(EINPROGRESS)
- REASON(EINPROGRESS);
-#endif
-#if defined(EINTR)
- REASON(EINTR);
-#endif
-#if defined(EINVAL)
- REASON(EINVAL);
-#endif
-#if defined(EIO)
- REASON(EIO);
-#endif
-#if defined(EISCONN)
- REASON(EISCONN);
-#endif
-#if defined(EISDIR)
- REASON(EISDIR);
-#endif
-#if defined(EISNAM)
- REASON(EISNAM);
-#endif
-#if defined(EKEYEXPIRED)
- REASON(EKEYEXPIRED);
-#endif
-#if defined(EKEYREJECTED)
- REASON(EKEYREJECTED);
-#endif
-#if defined(EKEYREVOKED)
- REASON(EKEYREVOKED);
-#endif
-#if defined(EL2HLT)
- REASON(EL2HLT);
-#endif
-#if defined(EL2NSYNC)
- REASON(EL2NSYNC);
-#endif
-#if defined(EL3HLT)
- REASON(EL3HLT);
-#endif
-#if defined(EL3RST)
- REASON(EL3RST);
-#endif
-#if defined(ELIBACC)
- REASON(ELIBACC);
-#endif
-#if defined(ELIBBAD)
- REASON(ELIBBAD);
-#endif
-#if defined(ELIBEXEC)
- REASON(ELIBEXEC);
-#endif
-#if defined(ELIBMAX)
- REASON(ELIBMAX);
-#endif
-#if defined(ELIBSCN)
- REASON(ELIBSCN);
-#endif
-#if defined(ELNRNG)
- REASON(ELNRNG);
-#endif
-#if defined(ELOOP)
- REASON(ELOOP);
-#endif
-#if defined(EMEDIUMTYPE)
- REASON(EMEDIUMTYPE);
-#endif
-#if defined(EMFILE)
- REASON(EMFILE);
-#endif
-#if defined(EMLINK)
- REASON(EMLINK);
-#endif
-#if defined(EMSGSIZE)
- REASON(EMSGSIZE);
-#endif
-#if defined(EMULTIHOP)
- REASON(EMULTIHOP);
-#endif
-#if defined(ENAMETOOLONG)
- REASON(ENAMETOOLONG);
-#endif
-#if defined(ENAVAIL)
- REASON(ENAVAIL);
-#endif
-#if defined(ENETDOWN)
- REASON(ENETDOWN);
-#endif
-#if defined(ENETRESET)
- REASON(ENETRESET);
-#endif
-#if defined(ENETUNREACH)
- REASON(ENETUNREACH);
-#endif
-#if defined(ENFILE)
- REASON(ENFILE);
-#endif
-#if defined(ENOANO)
- REASON(ENOANO);
-#endif
-#if defined(ENOBUFS)
- REASON(ENOBUFS);
-#endif
-#if defined(ENOCSI)
- REASON(ENOCSI);
-#endif
-#if defined(ENODATA)
- REASON(ENODATA);
-#endif
-#if defined(ENODEV)
- REASON(ENODEV);
-#endif
-#if defined(ENOENT)
- REASON(ENOENT);
-#endif
-#if defined(ENOEXEC)
- REASON(ENOEXEC);
-#endif
-#if defined(ENOKEY)
- REASON(ENOKEY);
-#endif
-#if defined(ENOLCK)
- REASON(ENOLCK);
-#endif
-#if defined(ENOLINK)
- REASON(ENOLINK);
-#endif
-#if defined(ENOMEDIUM)
- REASON(ENOMEDIUM);
-#endif
-#if defined(ENOMEM)
- REASON(ENOMEM);
-#endif
-#if defined(ENOMSG)
- REASON(ENOMSG);
-#endif
-#if defined(ENONET)
- REASON(ENONET);
-#endif
-#if defined(ENOPKG)
- REASON(ENOPKG);
-#endif
-#if defined(ENOPROTOOPT)
- REASON(ENOPROTOOPT);
-#endif
-#if defined(ENOSPC)
- REASON(ENOSPC);
-#endif
-#if defined(ENOSR)
- REASON(ENOSR);
-#endif
-#if defined(ENOSTR)
- REASON(ENOSTR);
-#endif
-#if defined(ENOSYS)
- REASON(ENOSYS);
-#endif
-#if defined(ENOTBLK)
- REASON(ENOTBLK);
-#endif
-#if defined(ENOTCONN)
- REASON(ENOTCONN);
-#endif
-#if defined(ENOTDIR)
- REASON(ENOTDIR);
-#endif
-#if defined(ENOTEMPTY)
- REASON(ENOTEMPTY);
-#endif
-#if defined(ENOTNAM)
- REASON(ENOTNAM);
-#endif
-#if defined(ENOTRECOVERABLE)
- REASON(ENOTRECOVERABLE);
-#endif
-#if defined(ENOTSOCK)
- REASON(ENOTSOCK);
-#endif
-#if defined(ENOTTY)
- REASON(ENOTTY);
-#endif
-#if defined(ENOTUNIQ)
- REASON(ENOTUNIQ);
-#endif
-#if defined(ENXIO)
- REASON(ENXIO);
-#endif
-#if defined(EOPNOTSUPP)
- REASON(EOPNOTSUPP);
-#endif
-#if defined(EOVERFLOW)
- REASON(EOVERFLOW);
-#endif
-#if defined(EOWNERDEAD)
- REASON(EOWNERDEAD);
-#endif
-#if defined(EPERM)
- REASON(EPERM);
-#endif
-#if defined(EPFNOSUPPORT)
- REASON(EPFNOSUPPORT);
-#endif
-#if defined(EPIPE)
- REASON(EPIPE);
-#endif
-#if defined(EPROTO)
- REASON(EPROTO);
-#endif
-#if defined(EPROTONOSUPPORT)
- REASON(EPROTONOSUPPORT);
-#endif
-#if defined(EPROTOTYPE)
- REASON(EPROTOTYPE);
-#endif
-#if defined(ERANGE)
- REASON(ERANGE);
-#endif
-#if defined(EREMCHG)
- REASON(EREMCHG);
-#endif
-#if defined(EREMOTE)
- REASON(EREMOTE);
-#endif
-#if defined(EREMOTEIO)
- REASON(EREMOTEIO);
-#endif
-#if defined(ERESTART)
- REASON(ERESTART);
-#endif
-#if defined(ERFKILL)
- REASON(ERFKILL);
-#endif
-#if defined(EROFS)
- REASON(EROFS);
-#endif
-#if defined(ESHUTDOWN)
- REASON(ESHUTDOWN);
-#endif
-#if defined(ESOCKTNOSUPPORT)
- REASON(ESOCKTNOSUPPORT);
-#endif
-#if defined(ESPIPE)
- REASON(ESPIPE);
-#endif
-#if defined(ESRCH)
- REASON(ESRCH);
-#endif
-#if defined(ESRMNT)
- REASON(ESRMNT);
-#endif
-#if defined(ESTALE)
- REASON(ESTALE);
-#endif
-#if defined(ESTRPIPE)
- REASON(ESTRPIPE);
-#endif
-#if defined(ETIME)
- REASON(ETIME);
-#endif
-#if defined(ETIMEDOUT)
- REASON(ETIMEDOUT);
-#endif
-#if defined(ETOOMANYREFS)
- REASON(ETOOMANYREFS);
-#endif
-#if defined(ETXTBSY)
- REASON(ETXTBSY);
-#endif
-#if defined(EUCLEAN)
- REASON(EUCLEAN);
-#endif
-#if defined(EUNATCH)
- REASON(EUNATCH);
-#endif
-#if defined(EUSERS)
- REASON(EUSERS);
-#endif
-#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN)
- REASON(EWOULDBLOCK);
-#endif
-#if defined(EXDEV)
- REASON(EXDEV);
-#endif
-#if defined(EXFULL)
- REASON(EXFULL);
-#endif
- default:
- return TDisconnectReason(Sprintf("errno=%d", errno));
- }
- }
-
-} // NActors
+#include "types.h"
+#include <util/string/printf.h>
+#include <util/generic/vector.h>
+#include <errno.h>
+
+namespace NActors {
+
+ TVector<const char*> TDisconnectReason::Reasons = {
+ "EndOfStream",
+ "CloseOnIdle",
+ "LostConnection",
+ "DeadPeer",
+ "NewSession",
+ "HandshakeFailTransient",
+ "HandshakeFailPermanent",
+ "UserRequest",
+ "Debug",
+ "ChecksumError",
+ "FormatError",
+ "EventTooLarge",
+ "QueueOverload",
+ "E2BIG",
+ "EACCES",
+ "EADDRINUSE",
+ "EADDRNOTAVAIL",
+ "EADV",
+ "EAFNOSUPPORT",
+ "EAGAIN",
+ "EALREADY",
+ "EBADE",
+ "EBADF",
+ "EBADFD",
+ "EBADMSG",
+ "EBADR",
+ "EBADRQC",
+ "EBADSLT",
+ "EBFONT",
+ "EBUSY",
+ "ECANCELED",
+ "ECHILD",
+ "ECHRNG",
+ "ECOMM",
+ "ECONNABORTED",
+ "ECONNREFUSED",
+ "ECONNRESET",
+ "EDEADLK",
+ "EDEADLOCK",
+ "EDESTADDRREQ",
+ "EDOM",
+ "EDOTDOT",
+ "EDQUOT",
+ "EEXIST",
+ "EFAULT",
+ "EFBIG",
+ "EHOSTDOWN",
+ "EHOSTUNREACH",
+ "EHWPOISON",
+ "EIDRM",
+ "EILSEQ",
+ "EINPROGRESS",
+ "EINTR",
+ "EINVAL",
+ "EIO",
+ "EISCONN",
+ "EISDIR",
+ "EISNAM",
+ "EKEYEXPIRED",
+ "EKEYREJECTED",
+ "EKEYREVOKED",
+ "EL2HLT",
+ "EL2NSYNC",
+ "EL3HLT",
+ "EL3RST",
+ "ELIBACC",
+ "ELIBBAD",
+ "ELIBEXEC",
+ "ELIBMAX",
+ "ELIBSCN",
+ "ELNRNG",
+ "ELOOP",
+ "EMEDIUMTYPE",
+ "EMFILE",
+ "EMLINK",
+ "EMSGSIZE",
+ "EMULTIHOP",
+ "ENAMETOOLONG",
+ "ENAVAIL",
+ "ENETDOWN",
+ "ENETRESET",
+ "ENETUNREACH",
+ "ENFILE",
+ "ENOANO",
+ "ENOBUFS",
+ "ENOCSI",
+ "ENODATA",
+ "ENODEV",
+ "ENOENT",
+ "ENOEXEC",
+ "ENOKEY",
+ "ENOLCK",
+ "ENOLINK",
+ "ENOMEDIUM",
+ "ENOMEM",
+ "ENOMSG",
+ "ENONET",
+ "ENOPKG",
+ "ENOPROTOOPT",
+ "ENOSPC",
+ "ENOSR",
+ "ENOSTR",
+ "ENOSYS",
+ "ENOTBLK",
+ "ENOTCONN",
+ "ENOTDIR",
+ "ENOTEMPTY",
+ "ENOTNAM",
+ "ENOTRECOVERABLE",
+ "ENOTSOCK",
+ "ENOTTY",
+ "ENOTUNIQ",
+ "ENXIO",
+ "EOPNOTSUPP",
+ "EOVERFLOW",
+ "EOWNERDEAD",
+ "EPERM",
+ "EPFNOSUPPORT",
+ "EPIPE",
+ "EPROTO",
+ "EPROTONOSUPPORT",
+ "EPROTOTYPE",
+ "ERANGE",
+ "EREMCHG",
+ "EREMOTE",
+ "EREMOTEIO",
+ "ERESTART",
+ "ERFKILL",
+ "EROFS",
+ "ESHUTDOWN",
+ "ESOCKTNOSUPPORT",
+ "ESPIPE",
+ "ESRCH",
+ "ESRMNT",
+ "ESTALE",
+ "ESTRPIPE",
+ "ETIME",
+ "ETIMEDOUT",
+ "ETOOMANYREFS",
+ "ETXTBSY",
+ "EUCLEAN",
+ "EUNATCH",
+ "EUSERS",
+ "EWOULDBLOCK",
+ "EXDEV",
+ "EXFULL",
+ };
+
+ TDisconnectReason TDisconnectReason::FromErrno(int err) {
+ switch (err) {
+#define REASON(ERRNO) case ERRNO: return TDisconnectReason(TString(#ERRNO))
+#if defined(E2BIG)
+ REASON(E2BIG);
+#endif
+#if defined(EACCES)
+ REASON(EACCES);
+#endif
+#if defined(EADDRINUSE)
+ REASON(EADDRINUSE);
+#endif
+#if defined(EADDRNOTAVAIL)
+ REASON(EADDRNOTAVAIL);
+#endif
+#if defined(EADV)
+ REASON(EADV);
+#endif
+#if defined(EAFNOSUPPORT)
+ REASON(EAFNOSUPPORT);
+#endif
+#if defined(EAGAIN)
+ REASON(EAGAIN);
+#endif
+#if defined(EALREADY)
+ REASON(EALREADY);
+#endif
+#if defined(EBADE)
+ REASON(EBADE);
+#endif
+#if defined(EBADF)
+ REASON(EBADF);
+#endif
+#if defined(EBADFD)
+ REASON(EBADFD);
+#endif
+#if defined(EBADMSG)
+ REASON(EBADMSG);
+#endif
+#if defined(EBADR)
+ REASON(EBADR);
+#endif
+#if defined(EBADRQC)
+ REASON(EBADRQC);
+#endif
+#if defined(EBADSLT)
+ REASON(EBADSLT);
+#endif
+#if defined(EBFONT)
+ REASON(EBFONT);
+#endif
+#if defined(EBUSY)
+ REASON(EBUSY);
+#endif
+#if defined(ECANCELED)
+ REASON(ECANCELED);
+#endif
+#if defined(ECHILD)
+ REASON(ECHILD);
+#endif
+#if defined(ECHRNG)
+ REASON(ECHRNG);
+#endif
+#if defined(ECOMM)
+ REASON(ECOMM);
+#endif
+#if defined(ECONNABORTED)
+ REASON(ECONNABORTED);
+#endif
+#if defined(ECONNREFUSED)
+ REASON(ECONNREFUSED);
+#endif
+#if defined(ECONNRESET)
+ REASON(ECONNRESET);
+#endif
+#if defined(EDEADLK)
+ REASON(EDEADLK);
+#endif
+#if defined(EDEADLOCK) && (!defined(EDEADLK) || EDEADLOCK != EDEADLK)
+ REASON(EDEADLOCK);
+#endif
+#if defined(EDESTADDRREQ)
+ REASON(EDESTADDRREQ);
+#endif
+#if defined(EDOM)
+ REASON(EDOM);
+#endif
+#if defined(EDOTDOT)
+ REASON(EDOTDOT);
+#endif
+#if defined(EDQUOT)
+ REASON(EDQUOT);
+#endif
+#if defined(EEXIST)
+ REASON(EEXIST);
+#endif
+#if defined(EFAULT)
+ REASON(EFAULT);
+#endif
+#if defined(EFBIG)
+ REASON(EFBIG);
+#endif
+#if defined(EHOSTDOWN)
+ REASON(EHOSTDOWN);
+#endif
+#if defined(EHOSTUNREACH)
+ REASON(EHOSTUNREACH);
+#endif
+#if defined(EHWPOISON)
+ REASON(EHWPOISON);
+#endif
+#if defined(EIDRM)
+ REASON(EIDRM);
+#endif
+#if defined(EILSEQ)
+ REASON(EILSEQ);
+#endif
+#if defined(EINPROGRESS)
+ REASON(EINPROGRESS);
+#endif
+#if defined(EINTR)
+ REASON(EINTR);
+#endif
+#if defined(EINVAL)
+ REASON(EINVAL);
+#endif
+#if defined(EIO)
+ REASON(EIO);
+#endif
+#if defined(EISCONN)
+ REASON(EISCONN);
+#endif
+#if defined(EISDIR)
+ REASON(EISDIR);
+#endif
+#if defined(EISNAM)
+ REASON(EISNAM);
+#endif
+#if defined(EKEYEXPIRED)
+ REASON(EKEYEXPIRED);
+#endif
+#if defined(EKEYREJECTED)
+ REASON(EKEYREJECTED);
+#endif
+#if defined(EKEYREVOKED)
+ REASON(EKEYREVOKED);
+#endif
+#if defined(EL2HLT)
+ REASON(EL2HLT);
+#endif
+#if defined(EL2NSYNC)
+ REASON(EL2NSYNC);
+#endif
+#if defined(EL3HLT)
+ REASON(EL3HLT);
+#endif
+#if defined(EL3RST)
+ REASON(EL3RST);
+#endif
+#if defined(ELIBACC)
+ REASON(ELIBACC);
+#endif
+#if defined(ELIBBAD)
+ REASON(ELIBBAD);
+#endif
+#if defined(ELIBEXEC)
+ REASON(ELIBEXEC);
+#endif
+#if defined(ELIBMAX)
+ REASON(ELIBMAX);
+#endif
+#if defined(ELIBSCN)
+ REASON(ELIBSCN);
+#endif
+#if defined(ELNRNG)
+ REASON(ELNRNG);
+#endif
+#if defined(ELOOP)
+ REASON(ELOOP);
+#endif
+#if defined(EMEDIUMTYPE)
+ REASON(EMEDIUMTYPE);
+#endif
+#if defined(EMFILE)
+ REASON(EMFILE);
+#endif
+#if defined(EMLINK)
+ REASON(EMLINK);
+#endif
+#if defined(EMSGSIZE)
+ REASON(EMSGSIZE);
+#endif
+#if defined(EMULTIHOP)
+ REASON(EMULTIHOP);
+#endif
+#if defined(ENAMETOOLONG)
+ REASON(ENAMETOOLONG);
+#endif
+#if defined(ENAVAIL)
+ REASON(ENAVAIL);
+#endif
+#if defined(ENETDOWN)
+ REASON(ENETDOWN);
+#endif
+#if defined(ENETRESET)
+ REASON(ENETRESET);
+#endif
+#if defined(ENETUNREACH)
+ REASON(ENETUNREACH);
+#endif
+#if defined(ENFILE)
+ REASON(ENFILE);
+#endif
+#if defined(ENOANO)
+ REASON(ENOANO);
+#endif
+#if defined(ENOBUFS)
+ REASON(ENOBUFS);
+#endif
+#if defined(ENOCSI)
+ REASON(ENOCSI);
+#endif
+#if defined(ENODATA)
+ REASON(ENODATA);
+#endif
+#if defined(ENODEV)
+ REASON(ENODEV);
+#endif
+#if defined(ENOENT)
+ REASON(ENOENT);
+#endif
+#if defined(ENOEXEC)
+ REASON(ENOEXEC);
+#endif
+#if defined(ENOKEY)
+ REASON(ENOKEY);
+#endif
+#if defined(ENOLCK)
+ REASON(ENOLCK);
+#endif
+#if defined(ENOLINK)
+ REASON(ENOLINK);
+#endif
+#if defined(ENOMEDIUM)
+ REASON(ENOMEDIUM);
+#endif
+#if defined(ENOMEM)
+ REASON(ENOMEM);
+#endif
+#if defined(ENOMSG)
+ REASON(ENOMSG);
+#endif
+#if defined(ENONET)
+ REASON(ENONET);
+#endif
+#if defined(ENOPKG)
+ REASON(ENOPKG);
+#endif
+#if defined(ENOPROTOOPT)
+ REASON(ENOPROTOOPT);
+#endif
+#if defined(ENOSPC)
+ REASON(ENOSPC);
+#endif
+#if defined(ENOSR)
+ REASON(ENOSR);
+#endif
+#if defined(ENOSTR)
+ REASON(ENOSTR);
+#endif
+#if defined(ENOSYS)
+ REASON(ENOSYS);
+#endif
+#if defined(ENOTBLK)
+ REASON(ENOTBLK);
+#endif
+#if defined(ENOTCONN)
+ REASON(ENOTCONN);
+#endif
+#if defined(ENOTDIR)
+ REASON(ENOTDIR);
+#endif
+#if defined(ENOTEMPTY)
+ REASON(ENOTEMPTY);
+#endif
+#if defined(ENOTNAM)
+ REASON(ENOTNAM);
+#endif
+#if defined(ENOTRECOVERABLE)
+ REASON(ENOTRECOVERABLE);
+#endif
+#if defined(ENOTSOCK)
+ REASON(ENOTSOCK);
+#endif
+#if defined(ENOTTY)
+ REASON(ENOTTY);
+#endif
+#if defined(ENOTUNIQ)
+ REASON(ENOTUNIQ);
+#endif
+#if defined(ENXIO)
+ REASON(ENXIO);
+#endif
+#if defined(EOPNOTSUPP)
+ REASON(EOPNOTSUPP);
+#endif
+#if defined(EOVERFLOW)
+ REASON(EOVERFLOW);
+#endif
+#if defined(EOWNERDEAD)
+ REASON(EOWNERDEAD);
+#endif
+#if defined(EPERM)
+ REASON(EPERM);
+#endif
+#if defined(EPFNOSUPPORT)
+ REASON(EPFNOSUPPORT);
+#endif
+#if defined(EPIPE)
+ REASON(EPIPE);
+#endif
+#if defined(EPROTO)
+ REASON(EPROTO);
+#endif
+#if defined(EPROTONOSUPPORT)
+ REASON(EPROTONOSUPPORT);
+#endif
+#if defined(EPROTOTYPE)
+ REASON(EPROTOTYPE);
+#endif
+#if defined(ERANGE)
+ REASON(ERANGE);
+#endif
+#if defined(EREMCHG)
+ REASON(EREMCHG);
+#endif
+#if defined(EREMOTE)
+ REASON(EREMOTE);
+#endif
+#if defined(EREMOTEIO)
+ REASON(EREMOTEIO);
+#endif
+#if defined(ERESTART)
+ REASON(ERESTART);
+#endif
+#if defined(ERFKILL)
+ REASON(ERFKILL);
+#endif
+#if defined(EROFS)
+ REASON(EROFS);
+#endif
+#if defined(ESHUTDOWN)
+ REASON(ESHUTDOWN);
+#endif
+#if defined(ESOCKTNOSUPPORT)
+ REASON(ESOCKTNOSUPPORT);
+#endif
+#if defined(ESPIPE)
+ REASON(ESPIPE);
+#endif
+#if defined(ESRCH)
+ REASON(ESRCH);
+#endif
+#if defined(ESRMNT)
+ REASON(ESRMNT);
+#endif
+#if defined(ESTALE)
+ REASON(ESTALE);
+#endif
+#if defined(ESTRPIPE)
+ REASON(ESTRPIPE);
+#endif
+#if defined(ETIME)
+ REASON(ETIME);
+#endif
+#if defined(ETIMEDOUT)
+ REASON(ETIMEDOUT);
+#endif
+#if defined(ETOOMANYREFS)
+ REASON(ETOOMANYREFS);
+#endif
+#if defined(ETXTBSY)
+ REASON(ETXTBSY);
+#endif
+#if defined(EUCLEAN)
+ REASON(EUCLEAN);
+#endif
+#if defined(EUNATCH)
+ REASON(EUNATCH);
+#endif
+#if defined(EUSERS)
+ REASON(EUSERS);
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || EWOULDBLOCK != EAGAIN)
+ REASON(EWOULDBLOCK);
+#endif
+#if defined(EXDEV)
+ REASON(EXDEV);
+#endif
+#if defined(EXFULL)
+ REASON(EXFULL);
+#endif
+ default:
+ return TDisconnectReason(Sprintf("errno=%d", errno));
+ }
+ }
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/types.h b/library/cpp/actors/interconnect/types.h
index 2662c50c220..1052b99461e 100644
--- a/library/cpp/actors/interconnect/types.h
+++ b/library/cpp/actors/interconnect/types.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#include <util/generic/string.h>
-
-namespace NActors {
-
- class TDisconnectReason {
- TString Text;
-
- private:
- explicit TDisconnectReason(TString text)
- : Text(std::move(text))
- {}
-
- public:
- TDisconnectReason() = default;
- TDisconnectReason(const TDisconnectReason&) = default;
- TDisconnectReason(TDisconnectReason&&) = default;
-
- static TDisconnectReason FromErrno(int err);
-
- static TDisconnectReason EndOfStream() { return TDisconnectReason("EndOfStream"); }
- static TDisconnectReason CloseOnIdle() { return TDisconnectReason("CloseOnIdle"); }
- static TDisconnectReason LostConnection() { return TDisconnectReason("LostConnection"); }
- static TDisconnectReason DeadPeer() { return TDisconnectReason("DeadPeer"); }
- static TDisconnectReason NewSession() { return TDisconnectReason("NewSession"); }
- static TDisconnectReason HandshakeFailTransient() { return TDisconnectReason("HandshakeFailTransient"); }
- static TDisconnectReason HandshakeFailPermanent() { return TDisconnectReason("HandshakeFailPermanent"); }
- static TDisconnectReason UserRequest() { return TDisconnectReason("UserRequest"); }
- static TDisconnectReason Debug() { return TDisconnectReason("Debug"); }
- static TDisconnectReason ChecksumError() { return TDisconnectReason("ChecksumError"); }
- static TDisconnectReason FormatError() { return TDisconnectReason("FormatError"); }
- static TDisconnectReason EventTooLarge() { return TDisconnectReason("EventTooLarge"); }
- static TDisconnectReason QueueOverload() { return TDisconnectReason("QueueOverload"); }
-
- TString ToString() const {
- return Text;
- }
-
- static TVector<const char*> Reasons;
- };
-
-} // NActors
+#pragma once
+
+#include <util/generic/string.h>
+
+namespace NActors {
+
+ class TDisconnectReason {
+ TString Text;
+
+ private:
+ explicit TDisconnectReason(TString text)
+ : Text(std::move(text))
+ {}
+
+ public:
+ TDisconnectReason() = default;
+ TDisconnectReason(const TDisconnectReason&) = default;
+ TDisconnectReason(TDisconnectReason&&) = default;
+
+ static TDisconnectReason FromErrno(int err);
+
+ static TDisconnectReason EndOfStream() { return TDisconnectReason("EndOfStream"); }
+ static TDisconnectReason CloseOnIdle() { return TDisconnectReason("CloseOnIdle"); }
+ static TDisconnectReason LostConnection() { return TDisconnectReason("LostConnection"); }
+ static TDisconnectReason DeadPeer() { return TDisconnectReason("DeadPeer"); }
+ static TDisconnectReason NewSession() { return TDisconnectReason("NewSession"); }
+ static TDisconnectReason HandshakeFailTransient() { return TDisconnectReason("HandshakeFailTransient"); }
+ static TDisconnectReason HandshakeFailPermanent() { return TDisconnectReason("HandshakeFailPermanent"); }
+ static TDisconnectReason UserRequest() { return TDisconnectReason("UserRequest"); }
+ static TDisconnectReason Debug() { return TDisconnectReason("Debug"); }
+ static TDisconnectReason ChecksumError() { return TDisconnectReason("ChecksumError"); }
+ static TDisconnectReason FormatError() { return TDisconnectReason("FormatError"); }
+ static TDisconnectReason EventTooLarge() { return TDisconnectReason("EventTooLarge"); }
+ static TDisconnectReason QueueOverload() { return TDisconnectReason("QueueOverload"); }
+
+ TString ToString() const {
+ return Text;
+ }
+
+ static TVector<const char*> Reasons;
+ };
+
+} // NActors
diff --git a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp b/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
index 565a511859e..ae996830aee 100644
--- a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
+++ b/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
@@ -1,115 +1,115 @@
#include <library/cpp/actors/interconnect/channel_scheduler.h>
#include <library/cpp/actors/interconnect/events_local.h>
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-
-Y_UNIT_TEST_SUITE(ChannelScheduler) {
-
- Y_UNIT_TEST(PriorityTraffic) {
- auto common = MakeIntrusive<TInterconnectProxyCommon>();
- common->MonCounters = MakeIntrusive<NMonitoring::TDynamicCounters>();
+
+using namespace NActors;
+
+Y_UNIT_TEST_SUITE(ChannelScheduler) {
+
+ Y_UNIT_TEST(PriorityTraffic) {
+ auto common = MakeIntrusive<TInterconnectProxyCommon>();
+ common->MonCounters = MakeIntrusive<NMonitoring::TDynamicCounters>();
std::shared_ptr<IInterconnectMetrics> ctr = CreateInterconnectCounters(common);
ctr->SetPeerInfo("peer", "1");
- auto callback = [](THolder<IEventBase>) {};
- TEventHolderPool pool(common, callback);
- TSessionParams p;
+ auto callback = [](THolder<IEventBase>) {};
+ TEventHolderPool pool(common, callback);
+ TSessionParams p;
TChannelScheduler scheduler(1, {}, ctr, pool, 64 << 20, p);
-
- ui32 numEvents = 0;
-
- auto pushEvent = [&](size_t size, int channel) {
- TString payload(size, 'X');
+
+ ui32 numEvents = 0;
+
+ auto pushEvent = [&](size_t size, int channel) {
+ TString payload(size, 'X');
auto ev = MakeHolder<IEventHandle>(1, 0, TActorId(), TActorId(), MakeIntrusive<TEventSerializedData>(payload, false), 0);
- auto& ch = scheduler.GetOutputChannel(channel);
- const bool wasWorking = ch.IsWorking();
- ch.Push(*ev);
- if (!wasWorking) {
- scheduler.AddToHeap(ch, 0);
- }
- ++numEvents;
- };
-
- for (ui32 i = 0; i < 100; ++i) {
- pushEvent(10000, 1);
- }
-
- for (ui32 i = 0; i < 1000; ++i) {
- pushEvent(1000, 2);
- }
-
- std::map<ui16, ui32> run;
- ui32 step = 0;
-
- std::deque<std::map<ui16, ui32>> window;
-
- for (; numEvents; ++step) {
- TTcpPacketOutTask task(p);
-
- if (step == 100) {
- for (ui32 i = 0; i < 200; ++i) {
- pushEvent(1000, 3);
- }
- }
-
- std::map<ui16, ui32> ch;
-
- while (numEvents) {
- TEventOutputChannel *channel = scheduler.PickChannelWithLeastConsumedWeight();
- ui32 before = task.GetDataSize();
- ui64 weightConsumed = 0;
- numEvents -= channel->FeedBuf(task, 0, &weightConsumed);
- ui32 after = task.GetDataSize();
- Y_VERIFY(after >= before);
- scheduler.FinishPick(weightConsumed, 0);
- const ui32 bytesAdded = after - before;
- if (!bytesAdded) {
- break;
- }
- ch[channel->ChannelId] += bytesAdded;
- }
-
- scheduler.Equalize();
-
- for (const auto& [key, value] : ch) {
- run[key] += value;
- }
- window.push_back(ch);
-
- if (window.size() == 32) {
- for (const auto& [key, value] : window.front()) {
- run[key] -= value;
- if (!run[key]) {
- run.erase(key);
- }
- }
- window.pop_front();
- }
-
- double mean = 0.0;
- for (const auto& [key, value] : run) {
- mean += value;
- }
- mean /= run.size();
-
- double dev = 0.0;
- for (const auto& [key, value] : run) {
- dev += (value - mean) * (value - mean);
- }
- dev = sqrt(dev / run.size());
-
- double devToMean = dev / mean;
-
- Cerr << step << ": ";
- for (const auto& [key, value] : run) {
- Cerr << "ch" << key << "=" << value << " ";
- }
- Cerr << "mean# " << mean << " dev# " << dev << " part# " << devToMean;
-
- Cerr << Endl;
-
- UNIT_ASSERT(devToMean < 1);
- }
- }
-
-}
+ auto& ch = scheduler.GetOutputChannel(channel);
+ const bool wasWorking = ch.IsWorking();
+ ch.Push(*ev);
+ if (!wasWorking) {
+ scheduler.AddToHeap(ch, 0);
+ }
+ ++numEvents;
+ };
+
+ for (ui32 i = 0; i < 100; ++i) {
+ pushEvent(10000, 1);
+ }
+
+ for (ui32 i = 0; i < 1000; ++i) {
+ pushEvent(1000, 2);
+ }
+
+ std::map<ui16, ui32> run;
+ ui32 step = 0;
+
+ std::deque<std::map<ui16, ui32>> window;
+
+ for (; numEvents; ++step) {
+ TTcpPacketOutTask task(p);
+
+ if (step == 100) {
+ for (ui32 i = 0; i < 200; ++i) {
+ pushEvent(1000, 3);
+ }
+ }
+
+ std::map<ui16, ui32> ch;
+
+ while (numEvents) {
+ TEventOutputChannel *channel = scheduler.PickChannelWithLeastConsumedWeight();
+ ui32 before = task.GetDataSize();
+ ui64 weightConsumed = 0;
+ numEvents -= channel->FeedBuf(task, 0, &weightConsumed);
+ ui32 after = task.GetDataSize();
+ Y_VERIFY(after >= before);
+ scheduler.FinishPick(weightConsumed, 0);
+ const ui32 bytesAdded = after - before;
+ if (!bytesAdded) {
+ break;
+ }
+ ch[channel->ChannelId] += bytesAdded;
+ }
+
+ scheduler.Equalize();
+
+ for (const auto& [key, value] : ch) {
+ run[key] += value;
+ }
+ window.push_back(ch);
+
+ if (window.size() == 32) {
+ for (const auto& [key, value] : window.front()) {
+ run[key] -= value;
+ if (!run[key]) {
+ run.erase(key);
+ }
+ }
+ window.pop_front();
+ }
+
+ double mean = 0.0;
+ for (const auto& [key, value] : run) {
+ mean += value;
+ }
+ mean /= run.size();
+
+ double dev = 0.0;
+ for (const auto& [key, value] : run) {
+ dev += (value - mean) * (value - mean);
+ }
+ dev = sqrt(dev / run.size());
+
+ double devToMean = dev / mean;
+
+ Cerr << step << ": ";
+ for (const auto& [key, value] : run) {
+ Cerr << "ch" << key << "=" << value << " ";
+ }
+ Cerr << "mean# " << mean << " dev# " << dev << " part# " << devToMean;
+
+ Cerr << Endl;
+
+ UNIT_ASSERT(devToMean < 1);
+ }
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp b/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
index 3c474979dce..75cb19bad9c 100644
--- a/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
+++ b/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
@@ -1,179 +1,179 @@
-#include <library/cpp/actors/interconnect/ut/lib/node.h>
-#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-TActorId MakeResponderServiceId(ui32 nodeId) {
- return TActorId(nodeId, TStringBuf("ResponderAct", 12));
-}
-
-class TArriveQueue {
- struct TArrivedItem {
- ui32 QueueId;
- ui32 Index;
- bool Success;
- };
-
- TMutex Lock;
- std::size_t Counter = 0;
- std::vector<TArrivedItem> Items;
-
-public:
- TArriveQueue(size_t capacity)
- : Items(capacity)
- {}
-
- bool Done() const {
- with_lock (Lock) {
- return Counter == Items.size();
- }
- }
-
- void Push(ui64 cookie, bool success) {
- with_lock (Lock) {
- const size_t pos = Counter++;
- TArrivedItem item{.QueueId = static_cast<ui32>(cookie >> 32), .Index = static_cast<ui32>(cookie & 0xffff'ffff),
- .Success = success};
- memcpy(&Items[pos], &item, sizeof(TArrivedItem));
- }
- }
-
- void Check() {
- struct TPerQueueState {
- std::vector<ui32> Ok, Error;
- };
- std::unordered_map<ui32, TPerQueueState> state;
- for (const TArrivedItem& item : Items) {
- auto& st = state[item.QueueId];
- auto& v = item.Success ? st.Ok : st.Error;
- v.push_back(item.Index);
- }
- for (const auto& [queueId, st] : state) {
- ui32 expected = 0;
- for (const ui32 index : st.Ok) {
- Y_VERIFY(index == expected);
- ++expected;
- }
- for (const ui32 index : st.Error) {
- Y_VERIFY(index == expected);
- ++expected;
- }
- if (st.Error.size()) {
- Cerr << "Error.size# " << st.Error.size() << Endl;
- }
- }
- }
-};
-
-class TResponder : public TActor<TResponder> {
- TArriveQueue& ArriveQueue;
-
-public:
- TResponder(TArriveQueue& arriveQueue)
- : TActor(&TResponder::StateFunc)
- , ArriveQueue(arriveQueue)
- {}
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvents::TEvPing, Handle);
- )
-
- void Handle(TEvents::TEvPing::TPtr ev) {
- ArriveQueue.Push(ev->Cookie, true);
- }
-};
-
-class TSender : public TActor<TSender> {
- TArriveQueue& ArriveQueue;
-
-public:
- TSender(TArriveQueue& arriveQueue)
- : TActor(&TThis::StateFunc)
- , ArriveQueue(arriveQueue)
- {}
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvents::TEvUndelivered, Handle);
- )
-
- void Handle(TEvents::TEvUndelivered::TPtr ev) {
- ArriveQueue.Push(ev->Cookie, false);
- }
-};
-
-void SenderThread(TMutex& lock, TActorSystem *as, ui32 nodeId, ui32 queueId, ui32 count, TArriveQueue& arriveQueue) {
- const TActorId sender = as->Register(new TSender(arriveQueue));
- with_lock(lock) {}
- const TActorId target = MakeResponderServiceId(nodeId);
- for (ui32 i = 0; i < count; ++i) {
- const ui32 flags = IEventHandle::FlagTrackDelivery;
- as->Send(new IEventHandle(TEvents::THelloWorld::Ping, flags, target, sender, nullptr, ((ui64)queueId << 32) | i));
- }
-}
-
-void RaceTestIter(ui32 numThreads, ui32 count) {
- TPortManager portman;
- THashMap<ui32, ui16> nodeToPort;
- const ui32 numNodes = 6; // total
- const ui32 numDynamicNodes = 3;
- for (ui32 i = 1; i <= numNodes; ++i) {
- nodeToPort.emplace(i, portman.GetPort());
- }
-
- NMonitoring::TDynamicCounterPtr counters = new NMonitoring::TDynamicCounters;
- std::list<TNode> nodes;
- for (ui32 i = 1; i <= numNodes; ++i) {
- nodes.emplace_back(i, numNodes, nodeToPort, "127.1.0.0", counters->GetSubgroup("nodeId", TStringBuilder() << i),
- TDuration::Seconds(10), TChannelsConfig(), numDynamicNodes, numThreads);
- }
-
- const ui32 numSenders = 10;
- TArriveQueue arriveQueue(numSenders * numNodes * (numNodes - 1) * count);
- for (TNode& node : nodes) {
- node.RegisterServiceActor(MakeResponderServiceId(node.GetActorSystem()->NodeId), new TResponder(arriveQueue));
- }
-
- TMutex lock;
- std::list<TThread> threads;
- ui32 queueId = 0;
- with_lock(lock) {
- for (TNode& from : nodes) {
- for (ui32 toId = 1; toId <= numNodes; ++toId) {
- if (toId == from.GetActorSystem()->NodeId) {
- continue;
- }
- for (ui32 i = 0; i < numSenders; ++i) {
- threads.emplace_back([=, &lock, &from, &arriveQueue] {
- SenderThread(lock, from.GetActorSystem(), toId, queueId, count, arriveQueue);
- });
- ++queueId;
- }
- }
- }
- for (auto& thread : threads) {
- thread.Start();
- }
- }
- for (auto& thread : threads) {
- thread.Join();
- }
-
- for (THPTimer timer; !arriveQueue.Done(); TDuration::MilliSeconds(10)) {
- Y_VERIFY(timer.Passed() < 10);
- }
-
- nodes.clear();
- arriveQueue.Check();
-}
-
-Y_UNIT_TEST_SUITE(DynamicProxy) {
- Y_UNIT_TEST(RaceCheck1) {
- for (ui32 iteration = 0; iteration < 100; ++iteration) {
- RaceTestIter(1 + iteration % 5, 1);
- }
- }
- Y_UNIT_TEST(RaceCheck10) {
- for (ui32 iteration = 0; iteration < 100; ++iteration) {
- RaceTestIter(1 + iteration % 5, 10);
- }
- }
-}
+#include <library/cpp/actors/interconnect/ut/lib/node.h>
+#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
+#include <library/cpp/testing/unittest/registar.h>
+
+TActorId MakeResponderServiceId(ui32 nodeId) {
+ return TActorId(nodeId, TStringBuf("ResponderAct", 12));
+}
+
+class TArriveQueue {
+ struct TArrivedItem {
+ ui32 QueueId;
+ ui32 Index;
+ bool Success;
+ };
+
+ TMutex Lock;
+ std::size_t Counter = 0;
+ std::vector<TArrivedItem> Items;
+
+public:
+ TArriveQueue(size_t capacity)
+ : Items(capacity)
+ {}
+
+ bool Done() const {
+ with_lock (Lock) {
+ return Counter == Items.size();
+ }
+ }
+
+ void Push(ui64 cookie, bool success) {
+ with_lock (Lock) {
+ const size_t pos = Counter++;
+ TArrivedItem item{.QueueId = static_cast<ui32>(cookie >> 32), .Index = static_cast<ui32>(cookie & 0xffff'ffff),
+ .Success = success};
+ memcpy(&Items[pos], &item, sizeof(TArrivedItem));
+ }
+ }
+
+ void Check() {
+ struct TPerQueueState {
+ std::vector<ui32> Ok, Error;
+ };
+ std::unordered_map<ui32, TPerQueueState> state;
+ for (const TArrivedItem& item : Items) {
+ auto& st = state[item.QueueId];
+ auto& v = item.Success ? st.Ok : st.Error;
+ v.push_back(item.Index);
+ }
+ for (const auto& [queueId, st] : state) {
+ ui32 expected = 0;
+ for (const ui32 index : st.Ok) {
+ Y_VERIFY(index == expected);
+ ++expected;
+ }
+ for (const ui32 index : st.Error) {
+ Y_VERIFY(index == expected);
+ ++expected;
+ }
+ if (st.Error.size()) {
+ Cerr << "Error.size# " << st.Error.size() << Endl;
+ }
+ }
+ }
+};
+
+class TResponder : public TActor<TResponder> {
+ TArriveQueue& ArriveQueue;
+
+public:
+ TResponder(TArriveQueue& arriveQueue)
+ : TActor(&TResponder::StateFunc)
+ , ArriveQueue(arriveQueue)
+ {}
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvents::TEvPing, Handle);
+ )
+
+ void Handle(TEvents::TEvPing::TPtr ev) {
+ ArriveQueue.Push(ev->Cookie, true);
+ }
+};
+
+class TSender : public TActor<TSender> {
+ TArriveQueue& ArriveQueue;
+
+public:
+ TSender(TArriveQueue& arriveQueue)
+ : TActor(&TThis::StateFunc)
+ , ArriveQueue(arriveQueue)
+ {}
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvents::TEvUndelivered, Handle);
+ )
+
+ void Handle(TEvents::TEvUndelivered::TPtr ev) {
+ ArriveQueue.Push(ev->Cookie, false);
+ }
+};
+
+void SenderThread(TMutex& lock, TActorSystem *as, ui32 nodeId, ui32 queueId, ui32 count, TArriveQueue& arriveQueue) {
+ const TActorId sender = as->Register(new TSender(arriveQueue));
+ with_lock(lock) {}
+ const TActorId target = MakeResponderServiceId(nodeId);
+ for (ui32 i = 0; i < count; ++i) {
+ const ui32 flags = IEventHandle::FlagTrackDelivery;
+ as->Send(new IEventHandle(TEvents::THelloWorld::Ping, flags, target, sender, nullptr, ((ui64)queueId << 32) | i));
+ }
+}
+
+void RaceTestIter(ui32 numThreads, ui32 count) {
+ TPortManager portman;
+ THashMap<ui32, ui16> nodeToPort;
+ const ui32 numNodes = 6; // total
+ const ui32 numDynamicNodes = 3;
+ for (ui32 i = 1; i <= numNodes; ++i) {
+ nodeToPort.emplace(i, portman.GetPort());
+ }
+
+ NMonitoring::TDynamicCounterPtr counters = new NMonitoring::TDynamicCounters;
+ std::list<TNode> nodes;
+ for (ui32 i = 1; i <= numNodes; ++i) {
+ nodes.emplace_back(i, numNodes, nodeToPort, "127.1.0.0", counters->GetSubgroup("nodeId", TStringBuilder() << i),
+ TDuration::Seconds(10), TChannelsConfig(), numDynamicNodes, numThreads);
+ }
+
+ const ui32 numSenders = 10;
+ TArriveQueue arriveQueue(numSenders * numNodes * (numNodes - 1) * count);
+ for (TNode& node : nodes) {
+ node.RegisterServiceActor(MakeResponderServiceId(node.GetActorSystem()->NodeId), new TResponder(arriveQueue));
+ }
+
+ TMutex lock;
+ std::list<TThread> threads;
+ ui32 queueId = 0;
+ with_lock(lock) {
+ for (TNode& from : nodes) {
+ for (ui32 toId = 1; toId <= numNodes; ++toId) {
+ if (toId == from.GetActorSystem()->NodeId) {
+ continue;
+ }
+ for (ui32 i = 0; i < numSenders; ++i) {
+ threads.emplace_back([=, &lock, &from, &arriveQueue] {
+ SenderThread(lock, from.GetActorSystem(), toId, queueId, count, arriveQueue);
+ });
+ ++queueId;
+ }
+ }
+ }
+ for (auto& thread : threads) {
+ thread.Start();
+ }
+ }
+ for (auto& thread : threads) {
+ thread.Join();
+ }
+
+ for (THPTimer timer; !arriveQueue.Done(); TDuration::MilliSeconds(10)) {
+ Y_VERIFY(timer.Passed() < 10);
+ }
+
+ nodes.clear();
+ arriveQueue.Check();
+}
+
+Y_UNIT_TEST_SUITE(DynamicProxy) {
+ Y_UNIT_TEST(RaceCheck1) {
+ for (ui32 iteration = 0; iteration < 100; ++iteration) {
+ RaceTestIter(1 + iteration % 5, 1);
+ }
+ }
+ Y_UNIT_TEST(RaceCheck10) {
+ for (ui32 iteration = 0; iteration < 100; ++iteration) {
+ RaceTestIter(1 + iteration % 5, 10);
+ }
+ }
+}
diff --git a/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp b/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
index e6b2bd4e4c4..2cf05566c0b 100644
--- a/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
+++ b/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
@@ -4,56 +4,56 @@
#include <library/cpp/actors/interconnect/interconnect_common.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/actors/interconnect/event_holder_pool.h>
-
+
#include <atomic>
-using namespace NActors;
-
-template<typename T>
-TEventHolderPool Setup(T&& callback) {
- auto common = MakeIntrusive<TInterconnectProxyCommon>();
+using namespace NActors;
+
+template<typename T>
+TEventHolderPool Setup(T&& callback) {
+ auto common = MakeIntrusive<TInterconnectProxyCommon>();
common->DestructorQueueSize = std::make_shared<std::atomic<TAtomicBase>>();
- common->MaxDestructorQueueSize = 1024 * 1024;
- return TEventHolderPool(common, callback);
-}
-
-Y_UNIT_TEST_SUITE(EventHolderPool) {
-
- Y_UNIT_TEST(Overflow) {
- TDeque<THolder<IEventBase>> freeQ;
- auto callback = [&](THolder<IEventBase> event) {
- freeQ.push_back(std::move(event));
- };
- auto pool = Setup(std::move(callback));
-
- std::list<TEventHolder> q;
-
- auto& ev1 = pool.Allocate(q);
- ev1.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
-
- auto& ev2 = pool.Allocate(q);
- ev2.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
-
- auto& ev3 = pool.Allocate(q);
- ev3.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
-
- auto& ev4 = pool.Allocate(q);
- ev4.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
-
- pool.Release(q, q.begin());
- pool.Release(q, q.begin());
- pool.Trim();
- UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
-
- pool.Release(q, q.begin());
- UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
-
- freeQ.clear();
- pool.Release(q, q.begin());
- pool.Trim();
- UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
-
- freeQ.clear(); // if we don't this, we may probablty crash due to the order of object destruction
- }
-
-}
+ common->MaxDestructorQueueSize = 1024 * 1024;
+ return TEventHolderPool(common, callback);
+}
+
+Y_UNIT_TEST_SUITE(EventHolderPool) {
+
+ Y_UNIT_TEST(Overflow) {
+ TDeque<THolder<IEventBase>> freeQ;
+ auto callback = [&](THolder<IEventBase> event) {
+ freeQ.push_back(std::move(event));
+ };
+ auto pool = Setup(std::move(callback));
+
+ std::list<TEventHolder> q;
+
+ auto& ev1 = pool.Allocate(q);
+ ev1.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
+
+ auto& ev2 = pool.Allocate(q);
+ ev2.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
+
+ auto& ev3 = pool.Allocate(q);
+ ev3.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
+
+ auto& ev4 = pool.Allocate(q);
+ ev4.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), true);
+
+ pool.Release(q, q.begin());
+ pool.Release(q, q.begin());
+ pool.Trim();
+ UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
+
+ pool.Release(q, q.begin());
+ UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
+
+ freeQ.clear();
+ pool.Release(q, q.begin());
+ pool.Trim();
+ UNIT_ASSERT_VALUES_EQUAL(freeQ.size(), 1);
+
+ freeQ.clear(); // if we don't this, we may probablty crash due to the order of object destruction
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/ut/interconnect_ut.cpp b/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
index 8ef0b1507c9..14982c85fbe 100644
--- a/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
+++ b/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
@@ -1,177 +1,177 @@
-#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/digest/md5/md5.h>
-#include <util/random/fast.h>
-
-using namespace NActors;
-
-class TSenderActor : public TActorBootstrapped<TSenderActor> {
- const TActorId Recipient;
- using TSessionToCookie = std::unordered_multimap<TActorId, ui64, THash<TActorId>>;
- TSessionToCookie SessionToCookie;
- std::unordered_map<ui64, std::pair<TSessionToCookie::iterator, TString>> InFlight;
- std::unordered_map<ui64, TString> Tentative;
- ui64 NextCookie = 0;
- TActorId SessionId;
- bool SubscribeInFlight = false;
-
-public:
- TSenderActor(TActorId recipient)
- : Recipient(recipient)
- {}
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
- Subscribe();
- }
-
- void Subscribe() {
- Cerr << (TStringBuilder() << "Subscribe" << Endl);
- Y_VERIFY(!SubscribeInFlight);
- SubscribeInFlight = true;
- Send(TActivationContext::InterconnectProxy(Recipient.NodeId()), new TEvents::TEvSubscribe);
- }
-
- void IssueQueries() {
- if (!SessionId) {
- return;
- }
- while (InFlight.size() < 10) {
- size_t len = RandomNumber<size_t>(65536) + 1;
- TString data = TString::Uninitialized(len);
- TReallyFastRng32 rng(RandomNumber<ui32>());
- char *p = data.Detach();
- for (size_t i = 0; i < len; ++i) {
- p[i] = rng();
- }
- const TSessionToCookie::iterator s2cIt = SessionToCookie.emplace(SessionId, NextCookie);
- InFlight.emplace(NextCookie, std::make_tuple(s2cIt, MD5::CalcRaw(data)));
- TActivationContext::Send(new IEventHandle(TEvents::THelloWorld::Ping, IEventHandle::FlagTrackDelivery, Recipient,
- SelfId(), MakeIntrusive<TEventSerializedData>(std::move(data), false), NextCookie));
-// Cerr << (TStringBuilder() << "Send# " << NextCookie << Endl);
- ++NextCookie;
- }
- }
-
- void HandlePong(TAutoPtr<IEventHandle> ev) {
-// Cerr << (TStringBuilder() << "Receive# " << ev->Cookie << Endl);
- if (const auto it = InFlight.find(ev->Cookie); it != InFlight.end()) {
- auto& [s2cIt, hash] = it->second;
- Y_VERIFY(hash == ev->GetChainBuffer()->GetString());
- SessionToCookie.erase(s2cIt);
- InFlight.erase(it);
- } else if (const auto it = Tentative.find(ev->Cookie); it != Tentative.end()) {
- Y_VERIFY(it->second == ev->GetChainBuffer()->GetString());
- Tentative.erase(it);
- } else {
- Y_FAIL("Cookie# %" PRIu64, ev->Cookie);
- }
- IssueQueries();
- }
-
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr ev) {
- Cerr << (TStringBuilder() << "TEvNodeConnected" << Endl);
- Y_VERIFY(SubscribeInFlight);
- SubscribeInFlight = false;
- Y_VERIFY(!SessionId);
- SessionId = ev->Sender;
- IssueQueries();
- }
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
- Cerr << (TStringBuilder() << "TEvNodeDisconnected" << Endl);
- SubscribeInFlight = false;
- if (SessionId) {
- Y_VERIFY(SessionId == ev->Sender);
- auto r = SessionToCookie.equal_range(SessionId);
- for (auto it = r.first; it != r.second; ++it) {
- const auto inFlightIt = InFlight.find(it->second);
- Y_VERIFY(inFlightIt != InFlight.end());
- Tentative.emplace(inFlightIt->first, inFlightIt->second.second);
- InFlight.erase(it->second);
- }
- SessionToCookie.erase(r.first, r.second);
- SessionId = TActorId();
- }
- Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr ev) {
- Cerr << (TStringBuilder() << "TEvUndelivered Cookie# " << ev->Cookie << Endl);
- if (const auto it = InFlight.find(ev->Cookie); it != InFlight.end()) {
- auto& [s2cIt, hash] = it->second;
- Tentative.emplace(it->first, hash);
- SessionToCookie.erase(s2cIt);
- InFlight.erase(it);
- IssueQueries();
- }
- }
-
- STRICT_STFUNC(StateFunc,
- fFunc(TEvents::THelloWorld::Pong, HandlePong);
- hFunc(TEvInterconnect::TEvNodeConnected, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
- hFunc(TEvents::TEvUndelivered, Handle);
- cFunc(TEvents::TSystem::Wakeup, Subscribe);
- )
-};
-
-class TRecipientActor : public TActor<TRecipientActor> {
-public:
- TRecipientActor()
- : TActor(&TThis::StateFunc)
- {}
-
- void HandlePing(TAutoPtr<IEventHandle>& ev) {
- const TString& data = ev->GetChainBuffer()->GetString();
- const TString& response = MD5::CalcRaw(data);
- TActivationContext::Send(new IEventHandle(TEvents::THelloWorld::Pong, 0, ev->Sender, SelfId(),
- MakeIntrusive<TEventSerializedData>(response, false), ev->Cookie));
- }
-
- STRICT_STFUNC(StateFunc,
- fFunc(TEvents::THelloWorld::Ping, HandlePing);
- )
-};
-
-Y_UNIT_TEST_SUITE(Interconnect) {
-
- Y_UNIT_TEST(SessionContinuation) {
- TTestICCluster cluster(2);
- const TActorId recipient = cluster.RegisterActor(new TRecipientActor, 1);
- cluster.RegisterActor(new TSenderActor(recipient), 2);
- for (ui32 i = 0; i < 100; ++i) {
- const ui32 nodeId = 1 + RandomNumber(2u);
- const ui32 peerNodeId = 3 - nodeId;
- const ui32 action = RandomNumber(3u);
- auto *node = cluster.GetNode(nodeId);
- TActorId proxyId = node->InterconnectProxy(peerNodeId);
-
- switch (action) {
- case 0:
- node->Send(proxyId, new TEvInterconnect::TEvClosePeerSocket);
- Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
- << " TEvClosePeerSocket" << Endl);
- break;
-
- case 1:
- node->Send(proxyId, new TEvInterconnect::TEvCloseInputSession);
- Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
- << " TEvCloseInputSession" << Endl);
- break;
-
- case 2:
- node->Send(proxyId, new TEvInterconnect::TEvPoisonSession);
- Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
- << " TEvPoisonSession" << Endl);
- break;
-
- default:
- Y_FAIL();
- }
-
- Sleep(TDuration::MilliSeconds(RandomNumber<ui32>(500) + 100));
- }
- }
-
-}
+#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
+#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/digest/md5/md5.h>
+#include <util/random/fast.h>
+
+using namespace NActors;
+
+class TSenderActor : public TActorBootstrapped<TSenderActor> {
+ const TActorId Recipient;
+ using TSessionToCookie = std::unordered_multimap<TActorId, ui64, THash<TActorId>>;
+ TSessionToCookie SessionToCookie;
+ std::unordered_map<ui64, std::pair<TSessionToCookie::iterator, TString>> InFlight;
+ std::unordered_map<ui64, TString> Tentative;
+ ui64 NextCookie = 0;
+ TActorId SessionId;
+ bool SubscribeInFlight = false;
+
+public:
+ TSenderActor(TActorId recipient)
+ : Recipient(recipient)
+ {}
+
+ void Bootstrap() {
+ Become(&TThis::StateFunc);
+ Subscribe();
+ }
+
+ void Subscribe() {
+ Cerr << (TStringBuilder() << "Subscribe" << Endl);
+ Y_VERIFY(!SubscribeInFlight);
+ SubscribeInFlight = true;
+ Send(TActivationContext::InterconnectProxy(Recipient.NodeId()), new TEvents::TEvSubscribe);
+ }
+
+ void IssueQueries() {
+ if (!SessionId) {
+ return;
+ }
+ while (InFlight.size() < 10) {
+ size_t len = RandomNumber<size_t>(65536) + 1;
+ TString data = TString::Uninitialized(len);
+ TReallyFastRng32 rng(RandomNumber<ui32>());
+ char *p = data.Detach();
+ for (size_t i = 0; i < len; ++i) {
+ p[i] = rng();
+ }
+ const TSessionToCookie::iterator s2cIt = SessionToCookie.emplace(SessionId, NextCookie);
+ InFlight.emplace(NextCookie, std::make_tuple(s2cIt, MD5::CalcRaw(data)));
+ TActivationContext::Send(new IEventHandle(TEvents::THelloWorld::Ping, IEventHandle::FlagTrackDelivery, Recipient,
+ SelfId(), MakeIntrusive<TEventSerializedData>(std::move(data), false), NextCookie));
+// Cerr << (TStringBuilder() << "Send# " << NextCookie << Endl);
+ ++NextCookie;
+ }
+ }
+
+ void HandlePong(TAutoPtr<IEventHandle> ev) {
+// Cerr << (TStringBuilder() << "Receive# " << ev->Cookie << Endl);
+ if (const auto it = InFlight.find(ev->Cookie); it != InFlight.end()) {
+ auto& [s2cIt, hash] = it->second;
+ Y_VERIFY(hash == ev->GetChainBuffer()->GetString());
+ SessionToCookie.erase(s2cIt);
+ InFlight.erase(it);
+ } else if (const auto it = Tentative.find(ev->Cookie); it != Tentative.end()) {
+ Y_VERIFY(it->second == ev->GetChainBuffer()->GetString());
+ Tentative.erase(it);
+ } else {
+ Y_FAIL("Cookie# %" PRIu64, ev->Cookie);
+ }
+ IssueQueries();
+ }
+
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr ev) {
+ Cerr << (TStringBuilder() << "TEvNodeConnected" << Endl);
+ Y_VERIFY(SubscribeInFlight);
+ SubscribeInFlight = false;
+ Y_VERIFY(!SessionId);
+ SessionId = ev->Sender;
+ IssueQueries();
+ }
+
+ void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
+ Cerr << (TStringBuilder() << "TEvNodeDisconnected" << Endl);
+ SubscribeInFlight = false;
+ if (SessionId) {
+ Y_VERIFY(SessionId == ev->Sender);
+ auto r = SessionToCookie.equal_range(SessionId);
+ for (auto it = r.first; it != r.second; ++it) {
+ const auto inFlightIt = InFlight.find(it->second);
+ Y_VERIFY(inFlightIt != InFlight.end());
+ Tentative.emplace(inFlightIt->first, inFlightIt->second.second);
+ InFlight.erase(it->second);
+ }
+ SessionToCookie.erase(r.first, r.second);
+ SessionId = TActorId();
+ }
+ Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr ev) {
+ Cerr << (TStringBuilder() << "TEvUndelivered Cookie# " << ev->Cookie << Endl);
+ if (const auto it = InFlight.find(ev->Cookie); it != InFlight.end()) {
+ auto& [s2cIt, hash] = it->second;
+ Tentative.emplace(it->first, hash);
+ SessionToCookie.erase(s2cIt);
+ InFlight.erase(it);
+ IssueQueries();
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(TEvents::THelloWorld::Pong, HandlePong);
+ hFunc(TEvInterconnect::TEvNodeConnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
+ hFunc(TEvents::TEvUndelivered, Handle);
+ cFunc(TEvents::TSystem::Wakeup, Subscribe);
+ )
+};
+
+class TRecipientActor : public TActor<TRecipientActor> {
+public:
+ TRecipientActor()
+ : TActor(&TThis::StateFunc)
+ {}
+
+ void HandlePing(TAutoPtr<IEventHandle>& ev) {
+ const TString& data = ev->GetChainBuffer()->GetString();
+ const TString& response = MD5::CalcRaw(data);
+ TActivationContext::Send(new IEventHandle(TEvents::THelloWorld::Pong, 0, ev->Sender, SelfId(),
+ MakeIntrusive<TEventSerializedData>(response, false), ev->Cookie));
+ }
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(TEvents::THelloWorld::Ping, HandlePing);
+ )
+};
+
+Y_UNIT_TEST_SUITE(Interconnect) {
+
+ Y_UNIT_TEST(SessionContinuation) {
+ TTestICCluster cluster(2);
+ const TActorId recipient = cluster.RegisterActor(new TRecipientActor, 1);
+ cluster.RegisterActor(new TSenderActor(recipient), 2);
+ for (ui32 i = 0; i < 100; ++i) {
+ const ui32 nodeId = 1 + RandomNumber(2u);
+ const ui32 peerNodeId = 3 - nodeId;
+ const ui32 action = RandomNumber(3u);
+ auto *node = cluster.GetNode(nodeId);
+ TActorId proxyId = node->InterconnectProxy(peerNodeId);
+
+ switch (action) {
+ case 0:
+ node->Send(proxyId, new TEvInterconnect::TEvClosePeerSocket);
+ Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
+ << " TEvClosePeerSocket" << Endl);
+ break;
+
+ case 1:
+ node->Send(proxyId, new TEvInterconnect::TEvCloseInputSession);
+ Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
+ << " TEvCloseInputSession" << Endl);
+ break;
+
+ case 2:
+ node->Send(proxyId, new TEvInterconnect::TEvPoisonSession);
+ Cerr << (TStringBuilder() << "nodeId# " << nodeId << " peerNodeId# " << peerNodeId
+ << " TEvPoisonSession" << Endl);
+ break;
+
+ default:
+ Y_FAIL();
+ }
+
+ Sleep(TDuration::MilliSeconds(RandomNumber<ui32>(500) + 100));
+ }
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/ut/large.cpp b/library/cpp/actors/interconnect/ut/large.cpp
index ba2a50c6f6f..e0497ca911c 100644
--- a/library/cpp/actors/interconnect/ut/large.cpp
+++ b/library/cpp/actors/interconnect/ut/large.cpp
@@ -1,85 +1,85 @@
-#include "lib/ic_test_cluster.h"
-#include "lib/test_events.h"
-#include "lib/test_actors.h"
-
+#include "lib/ic_test_cluster.h"
+#include "lib/test_events.h"
+#include "lib/test_actors.h"
+
#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-
+
#include <library/cpp/testing/unittest/tests_data.h>
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/system/event.h>
-#include <util/system/sanitizers.h>
-
-Y_UNIT_TEST_SUITE(LargeMessage) {
- using namespace NActors;
-
- class TProducer: public TActorBootstrapped<TProducer> {
+
+#include <util/system/event.h>
+#include <util/system/sanitizers.h>
+
+Y_UNIT_TEST_SUITE(LargeMessage) {
+ using namespace NActors;
+
+ class TProducer: public TActorBootstrapped<TProducer> {
const TActorId RecipientActorId;
-
- public:
+
+ public:
TProducer(const TActorId& recipientActorId)
- : RecipientActorId(recipientActorId)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc);
- ctx.Send(RecipientActorId, new TEvTest(1, "hello"), IEventHandle::FlagTrackDelivery, 1);
- ctx.Send(RecipientActorId, new TEvTest(2, TString(128 * 1024 * 1024, 'X')), IEventHandle::FlagTrackDelivery, 2);
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& ctx) {
- if (ev->Cookie == 2) {
- Cerr << "TEvUndelivered\n";
- ctx.Send(RecipientActorId, new TEvTest(3, "hello"), IEventHandle::FlagTrackDelivery, 3);
- }
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvUndelivered, Handle)
- )
- };
-
- class TConsumer : public TActorBootstrapped<TConsumer> {
- TManualEvent& Done;
+ : RecipientActorId(recipientActorId)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc);
+ ctx.Send(RecipientActorId, new TEvTest(1, "hello"), IEventHandle::FlagTrackDelivery, 1);
+ ctx.Send(RecipientActorId, new TEvTest(2, TString(128 * 1024 * 1024, 'X')), IEventHandle::FlagTrackDelivery, 2);
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& ctx) {
+ if (ev->Cookie == 2) {
+ Cerr << "TEvUndelivered\n";
+ ctx.Send(RecipientActorId, new TEvTest(3, "hello"), IEventHandle::FlagTrackDelivery, 3);
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvUndelivered, Handle)
+ )
+ };
+
+ class TConsumer : public TActorBootstrapped<TConsumer> {
+ TManualEvent& Done;
TActorId SessionId;
-
- public:
- TConsumer(TManualEvent& done)
- : Done(done)
- {
- }
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- Become(&TThis::StateFunc);
- }
-
- void Handle(TEvTest::TPtr ev, const TActorContext& /*ctx*/) {
- const auto& record = ev->Get()->Record;
- Cerr << "RECEIVED TEvTest\n";
- if (record.GetSequenceNumber() == 1) {
- Y_VERIFY(!SessionId);
- SessionId = ev->InterconnectSession;
- } else if (record.GetSequenceNumber() == 3) {
- Y_VERIFY(SessionId != ev->InterconnectSession);
- Done.Signal();
- } else {
- Y_FAIL("incorrect sequence number");
- }
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvTest, Handle)
- )
- };
-
- Y_UNIT_TEST(Test) {
- TTestICCluster testCluster(2);
-
- TManualEvent done;
- TConsumer* consumer = new TConsumer(done);
+
+ public:
+ TConsumer(TManualEvent& done)
+ : Done(done)
+ {
+ }
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ Become(&TThis::StateFunc);
+ }
+
+ void Handle(TEvTest::TPtr ev, const TActorContext& /*ctx*/) {
+ const auto& record = ev->Get()->Record;
+ Cerr << "RECEIVED TEvTest\n";
+ if (record.GetSequenceNumber() == 1) {
+ Y_VERIFY(!SessionId);
+ SessionId = ev->InterconnectSession;
+ } else if (record.GetSequenceNumber() == 3) {
+ Y_VERIFY(SessionId != ev->InterconnectSession);
+ Done.Signal();
+ } else {
+ Y_FAIL("incorrect sequence number");
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvTest, Handle)
+ )
+ };
+
+ Y_UNIT_TEST(Test) {
+ TTestICCluster testCluster(2);
+
+ TManualEvent done;
+ TConsumer* consumer = new TConsumer(done);
const TActorId recp = testCluster.RegisterActor(consumer, 1);
- testCluster.RegisterActor(new TProducer(recp), 2);
- done.WaitI();
- }
-
-}
+ testCluster.RegisterActor(new TProducer(recp), 2);
+ done.WaitI();
+ }
+
+}
diff --git a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h b/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h
index 2b6d27cd3f3..d61bea14607 100644
--- a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h
+++ b/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h
@@ -58,8 +58,8 @@ public:
}
for (ui32 i = 1; i <= NumNodes; ++i) {
- auto& portMap = tiSettings ? specificNodePortMap[i] : nodeToPortMap;
- Nodes.emplace(i, MakeHolder<TNode>(i, NumNodes, portMap, Address, Counters, DeadPeerTimeout, ChannelsConfig));
+ auto& portMap = tiSettings ? specificNodePortMap[i] : nodeToPortMap;
+ Nodes.emplace(i, MakeHolder<TNode>(i, NumNodes, portMap, Address, Counters, DeadPeerTimeout, ChannelsConfig));
}
}
@@ -74,10 +74,10 @@ public:
return Nodes[nodeId]->RegisterActor(actor);
}
- TActorId InterconnectProxy(ui32 peerNodeId, ui32 nodeId) {
- return Nodes[nodeId]->InterconnectProxy(peerNodeId);
- }
-
+ TActorId InterconnectProxy(ui32 peerNodeId, ui32 nodeId) {
+ return Nodes[nodeId]->InterconnectProxy(peerNodeId);
+ }
+
void KillActor(ui32 nodeId, const TActorId& id) {
Nodes[nodeId]->Send(id, new NActors::TEvents::TEvPoisonPill);
}
diff --git a/library/cpp/actors/interconnect/ut/lib/interrupter.h b/library/cpp/actors/interconnect/ut/lib/interrupter.h
index 48851de2c52..2707f82a067 100644
--- a/library/cpp/actors/interconnect/ut/lib/interrupter.h
+++ b/library/cpp/actors/interconnect/ut/lib/interrupter.h
@@ -35,7 +35,7 @@ class TTrafficInterrupter
TInet6StreamSocket* Source = nullptr;
TInet6StreamSocket* Destination = nullptr;
TList<TConnectionDescriptor>::iterator ListIterator;
- TInstant Timestamp;
+ TInstant Timestamp;
TPriorityQueue<std::pair<TInstant, TDelayedPacket>, TVector<std::pair<TInstant, TDelayedPacket>>, TCompare> DelayedQueue;
TDirectedConnection(TInet6StreamSocket* source, TInet6StreamSocket* destination)
@@ -89,10 +89,10 @@ public:
Y_VERIFY(ListenSocket.Bind(&addr) == 0);
Y_VERIFY(ListenSocket.Listen(5) == 0);
- DelayTraffic = (Bandwidth == 0.0) ? false : true;
-
+ DelayTraffic = (Bandwidth == 0.0) ? false : true;
+
ForwardAddrress.Reset(new TSockAddrInet6(Address.data(), ForwardPort));
- const ui32 BufSize = DelayTraffic ? 4096 : 65536 + 4096;
+ const ui32 BufSize = DelayTraffic ? 4096 : 65536 + 4096;
Buf.resize(BufSize);
}
@@ -154,7 +154,7 @@ private:
RandomlyDisconnect();
}
if (!RejectingTraffic) {
- TDuration timeout = DefaultPollTimeout;
+ TDuration timeout = DefaultPollTimeout;
auto updateTimout = [&timeout](TDirectedConnection& conn) {
if (conn.DelayedQueue) {
timeout = Min(timeout, conn.DelayedQueue.top().first - TInstant::Now());
@@ -163,7 +163,7 @@ private:
for (auto& it : Connections) {
updateTimout(it.ForwardConnection);
updateTimout(it.BackwardConnection);
- }
+ }
pollReadyCount = SocketPoller.WaitT(Events.data(), Events.size(), timeout);
if (pollReadyCount > 0) {
for (int i = 0; i < pollReadyCount; i++) {
@@ -229,11 +229,11 @@ private:
if (DelayTraffic) {
// put packet into DelayQueue
const TDuration baseDelay = TDuration::MicroSeconds(recvSize * 1e6 / Bandwidth);
- const TInstant now = TInstant::Now();
- directedConnection->Timestamp = Max(now, directedConnection->Timestamp) + baseDelay;
- TDelayedPacket pkt;
- pkt.ForwardSocket = directedConnection->Destination;
- pkt.Data.resize(recvSize);
+ const TInstant now = TInstant::Now();
+ directedConnection->Timestamp = Max(now, directedConnection->Timestamp) + baseDelay;
+ TDelayedPacket pkt;
+ pkt.ForwardSocket = directedConnection->Destination;
+ pkt.Data.resize(recvSize);
memcpy(pkt.Data.data(), Buf.data(), recvSize);
directedConnection->DelayedQueue.emplace(directedConnection->Timestamp, std::move(pkt));
} else {
diff --git a/library/cpp/actors/interconnect/ut/lib/node.h b/library/cpp/actors/interconnect/ut/lib/node.h
index ff30b1445e8..ac57f5b6a8a 100644
--- a/library/cpp/actors/interconnect/ut/lib/node.h
+++ b/library/cpp/actors/interconnect/ut/lib/node.h
@@ -3,73 +3,73 @@
#include <library/cpp/actors/core/actorsystem.h>
#include <library/cpp/actors/core/executor_pool_basic.h>
#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/core/mailbox.h>
+#include <library/cpp/actors/core/mailbox.h>
#include <library/cpp/actors/dnsresolver/dnsresolver.h>
#include <library/cpp/actors/interconnect/interconnect_tcp_server.h>
#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
-
-using namespace NActors;
+#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
+using namespace NActors;
+
class TNode {
- THolder<TActorSystem> ActorSystem;
+ THolder<TActorSystem> ActorSystem;
public:
TNode(ui32 nodeId, ui32 numNodes, const THashMap<ui32, ui16>& nodeToPort, const TString& address,
- NMonitoring::TDynamicCounterPtr counters, TDuration deadPeerTimeout,
- TChannelsConfig channelsSettings = TChannelsConfig(),
- ui32 numDynamicNodes = 0, ui32 numThreads = 1) {
- TActorSystemSetup setup;
+ NMonitoring::TDynamicCounterPtr counters, TDuration deadPeerTimeout,
+ TChannelsConfig channelsSettings = TChannelsConfig(),
+ ui32 numDynamicNodes = 0, ui32 numThreads = 1) {
+ TActorSystemSetup setup;
setup.NodeId = nodeId;
setup.ExecutorsCount = 1;
- setup.Executors.Reset(new TAutoPtr<IExecutorPool>[setup.ExecutorsCount]);
+ setup.Executors.Reset(new TAutoPtr<IExecutorPool>[setup.ExecutorsCount]);
for (ui32 i = 0; i < setup.ExecutorsCount; ++i) {
- setup.Executors[i].Reset(new TBasicExecutorPool(i, numThreads, 20 /* magic number */));
+ setup.Executors[i].Reset(new TBasicExecutorPool(i, numThreads, 20 /* magic number */));
}
- setup.Scheduler.Reset(new TBasicSchedulerThread());
+ setup.Scheduler.Reset(new TBasicSchedulerThread());
const ui32 interconnectPoolId = 0;
- auto common = MakeIntrusive<TInterconnectProxyCommon>();
- common->NameserviceId = GetNameserviceActorId();
+ auto common = MakeIntrusive<TInterconnectProxyCommon>();
+ common->NameserviceId = GetNameserviceActorId();
common->MonCounters = counters->GetSubgroup("nodeId", ToString(nodeId));
common->ChannelsConfig = channelsSettings;
common->ClusterUUID = "cluster";
common->AcceptUUID = {common->ClusterUUID};
common->TechnicalSelfHostName = address;
- common->Settings.Handshake = TDuration::Seconds(1);
- common->Settings.DeadPeer = deadPeerTimeout;
- common->Settings.CloseOnIdle = TDuration::Minutes(1);
- common->Settings.SendBufferDieLimitInMB = 512;
- common->Settings.TotalInflightAmountOfData = 512 * 1024;
- common->Settings.TCPSocketBufferSize = 2048 * 1024;
-
- setup.Interconnect.ProxyActors.resize(numNodes + 1 - numDynamicNodes);
- setup.Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(common, interconnectPoolId);
-
+ common->Settings.Handshake = TDuration::Seconds(1);
+ common->Settings.DeadPeer = deadPeerTimeout;
+ common->Settings.CloseOnIdle = TDuration::Minutes(1);
+ common->Settings.SendBufferDieLimitInMB = 512;
+ common->Settings.TotalInflightAmountOfData = 512 * 1024;
+ common->Settings.TCPSocketBufferSize = 2048 * 1024;
+
+ setup.Interconnect.ProxyActors.resize(numNodes + 1 - numDynamicNodes);
+ setup.Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(common, interconnectPoolId);
+
for (ui32 i = 1; i <= numNodes; ++i) {
- if (i == nodeId) {
- // create listener actor for local node "nodeId"
- setup.LocalServices.emplace_back(TActorId(), TActorSetupCmd(new TInterconnectListenerTCP(address,
- nodeToPort.at(nodeId), common), TMailboxType::ReadAsFilled, interconnectPoolId));
- } else if (i <= numNodes - numDynamicNodes) {
+ if (i == nodeId) {
+ // create listener actor for local node "nodeId"
+ setup.LocalServices.emplace_back(TActorId(), TActorSetupCmd(new TInterconnectListenerTCP(address,
+ nodeToPort.at(nodeId), common), TMailboxType::ReadAsFilled, interconnectPoolId));
+ } else if (i <= numNodes - numDynamicNodes) {
// create proxy actor to reach node "i"
- setup.Interconnect.ProxyActors[i] = {new TInterconnectProxyTCP(i, common),
- TMailboxType::ReadAsFilled, interconnectPoolId};
+ setup.Interconnect.ProxyActors[i] = {new TInterconnectProxyTCP(i, common),
+ TMailboxType::ReadAsFilled, interconnectPoolId};
}
}
- setup.LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(),
- TMailboxType::ReadAsFilled, 0));
-
+ setup.LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(),
+ TMailboxType::ReadAsFilled, 0));
+
const TActorId loggerActorId(0, "logger");
constexpr ui32 LoggerComponentId = 410; // NKikimrServices::LOGGER
- auto loggerSettings = MakeIntrusive<NLog::TSettings>(
+ auto loggerSettings = MakeIntrusive<NLog::TSettings>(
loggerActorId,
- (NLog::EComponent)LoggerComponentId,
- NLog::PRI_INFO,
- NLog::PRI_DEBUG,
+ (NLog::EComponent)LoggerComponentId,
+ NLog::PRI_INFO,
+ NLog::PRI_DEBUG,
0U);
loggerSettings->Append(
@@ -82,31 +82,31 @@ public:
static const TString WilsonComponentName = "WILSON";
loggerSettings->Append(
- (NLog::EComponent)WilsonComponentId,
- (NLog::EComponent)WilsonComponentId + 1,
- [](NLog::EComponent) -> const TString & { return WilsonComponentName; });
+ (NLog::EComponent)WilsonComponentId,
+ (NLog::EComponent)WilsonComponentId + 1,
+ [](NLog::EComponent) -> const TString & { return WilsonComponentName; });
// register nameserver table
- auto names = MakeIntrusive<TTableNameserverSetup>();
+ auto names = MakeIntrusive<TTableNameserverSetup>();
for (ui32 i = 1; i <= numNodes; ++i) {
- names->StaticNodeTable[i] = TTableNameserverSetup::TNodeInfo(address, address, nodeToPort.at(i));
+ names->StaticNodeTable[i] = TTableNameserverSetup::TNodeInfo(address, address, nodeToPort.at(i));
}
setup.LocalServices.emplace_back(
- NDnsResolver::MakeDnsResolverActorId(),
- TActorSetupCmd(
- NDnsResolver::CreateOnDemandDnsResolver(),
- TMailboxType::ReadAsFilled, interconnectPoolId));
- setup.LocalServices.emplace_back(GetNameserviceActorId(), TActorSetupCmd(
- CreateNameserverTable(names, interconnectPoolId), TMailboxType::ReadAsFilled,
- interconnectPoolId));
+ NDnsResolver::MakeDnsResolverActorId(),
+ TActorSetupCmd(
+ NDnsResolver::CreateOnDemandDnsResolver(),
+ TMailboxType::ReadAsFilled, interconnectPoolId));
+ setup.LocalServices.emplace_back(GetNameserviceActorId(), TActorSetupCmd(
+ CreateNameserverTable(names, interconnectPoolId), TMailboxType::ReadAsFilled,
+ interconnectPoolId));
// register logger
- setup.LocalServices.emplace_back(loggerActorId, TActorSetupCmd(new TLoggerActor(loggerSettings,
- CreateStderrBackend(), counters->GetSubgroup("subsystem", "logger")),
- TMailboxType::ReadAsFilled, interconnectPoolId));
+ setup.LocalServices.emplace_back(loggerActorId, TActorSetupCmd(new TLoggerActor(loggerSettings,
+ CreateStderrBackend(), counters->GetSubgroup("subsystem", "logger")),
+ TMailboxType::ReadAsFilled, interconnectPoolId));
- auto sp = MakeHolder<TActorSystemSetup>(std::move(setup));
- ActorSystem.Reset(new TActorSystem(sp, nullptr, loggerSettings));
+ auto sp = MakeHolder<TActorSystemSetup>(std::move(setup));
+ ActorSystem.Reset(new TActorSystem(sp, nullptr, loggerSettings));
ActorSystem->Start();
}
@@ -118,20 +118,20 @@ public:
return ActorSystem->Send(recipient, ev);
}
- TActorId RegisterActor(IActor* actor) {
+ TActorId RegisterActor(IActor* actor) {
return ActorSystem->Register(actor);
}
- TActorId InterconnectProxy(ui32 peerNodeId) {
- return ActorSystem->InterconnectProxy(peerNodeId);
- }
-
- void RegisterServiceActor(const TActorId& serviceId, IActor* actor) {
+ TActorId InterconnectProxy(ui32 peerNodeId) {
+ return ActorSystem->InterconnectProxy(peerNodeId);
+ }
+
+ void RegisterServiceActor(const TActorId& serviceId, IActor* actor) {
const TActorId actorId = ActorSystem->Register(actor);
ActorSystem->RegisterLocalService(serviceId, actorId);
}
-
- TActorSystem *GetActorSystem() const {
- return ActorSystem.Get();
- }
+
+ TActorSystem *GetActorSystem() const {
+ return ActorSystem.Get();
+ }
};
diff --git a/library/cpp/actors/interconnect/ut/lib/test_actors.h b/library/cpp/actors/interconnect/ut/lib/test_actors.h
index 7591200471b..178aa89ee22 100644
--- a/library/cpp/actors/interconnect/ut/lib/test_actors.h
+++ b/library/cpp/actors/interconnect/ut/lib/test_actors.h
@@ -20,7 +20,7 @@ namespace NActors {
virtual void Bootstrap(const TActorContext& ctx) {
Become(&TSenderBaseActor::StateFunc);
- ctx.Send(ctx.ExecutorThread.ActorSystem->InterconnectProxy(RecipientActorId.NodeId()), new TEvInterconnect::TEvConnectNode);
+ ctx.Send(ctx.ExecutorThread.ActorSystem->InterconnectProxy(RecipientActorId.NodeId()), new TEvInterconnect::TEvConnectNode);
}
virtual void SendMessagesIfPossible(const TActorContext& ctx) {
@@ -41,8 +41,8 @@ namespace NActors {
SendMessagesIfPossible(ctx);
}
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr& /*ev*/, const TActorContext& ctx) {
- SendMessagesIfPossible(ctx);
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr& /*ev*/, const TActorContext& ctx) {
+ SendMessagesIfPossible(ctx);
}
void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr& /*ev*/, const TActorContext& /*ctx*/) {
@@ -52,13 +52,13 @@ namespace NActors {
Die(ctx);
}
- virtual STRICT_STFUNC(StateFunc,
- HFunc(TEvTestResponse, Handle)
- HFunc(TEvents::TEvUndelivered, Handle)
- HFunc(TEvents::TEvPoisonPill, Handle)
- HFunc(TEvInterconnect::TEvNodeConnected, Handle)
- HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
- )
+ virtual STRICT_STFUNC(StateFunc,
+ HFunc(TEvTestResponse, Handle)
+ HFunc(TEvents::TEvUndelivered, Handle)
+ HFunc(TEvents::TEvPoisonPill, Handle)
+ HFunc(TEvInterconnect::TEvNodeConnected, Handle)
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
+ )
};
class TReceiverBaseActor: public TActor<TReceiverBaseActor> {
@@ -74,10 +74,10 @@ namespace NActors {
virtual ~TReceiverBaseActor() {
}
- virtual STRICT_STFUNC(StateFunc,
- HFunc(TEvTest, Handle)
- )
+ virtual STRICT_STFUNC(StateFunc,
+ HFunc(TEvTest, Handle)
+ )
- virtual void Handle(TEvTest::TPtr& /*ev*/, const TActorContext& /*ctx*/) {}
+ virtual void Handle(TEvTest::TPtr& /*ev*/, const TActorContext& /*ctx*/) {}
};
}
diff --git a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp b/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
index 23d846a2fd8..9d06c377c88 100644
--- a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
+++ b/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
@@ -33,47 +33,47 @@ std::pair<TTestSocketPtr, TTestSocketPtr> NonBlockSockets() {
return {MakeIntrusive<TTestSocket>(fds[0]), MakeIntrusive<TTestSocket>(fds[1])};
}
-std::pair<TTestSocketPtr, TTestSocketPtr> TcpSockets() {
- // create server (listening) socket
- SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
- Y_VERIFY(server != -1, "socket() failed with %s", strerror(errno));
-
- // bind it to local address with automatically picked port
- sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- if (bind(server, (sockaddr*)&addr, sizeof(addr)) == -1) {
- Y_FAIL("bind() failed with %s", strerror(errno));
- } else if (listen(server, 1) == -1) {
- Y_FAIL("listen() failed with %s", strerror(errno));
- }
-
- // obtain local address for client
- socklen_t len = sizeof(addr);
- if (getsockname(server, (sockaddr*)&addr, &len) == -1) {
- Y_FAIL("getsockname() failed with %s", strerror(errno));
- }
-
- // create client socket
- SOCKET client = socket(AF_INET, SOCK_STREAM, 0);
- Y_VERIFY(client != -1, "socket() failed with %s", strerror(errno));
-
- // connect to server
- if (connect(client, (sockaddr*)&addr, len) == -1) {
- Y_FAIL("connect() failed with %s", strerror(errno));
- }
-
- // accept connection from the other side
- SOCKET accepted = accept(server, nullptr, nullptr);
- Y_VERIFY(accepted != -1, "accept() failed with %s", strerror(errno));
-
- // close server socket
- closesocket(server);
-
- return std::make_pair(MakeIntrusive<TTestSocket>(client), MakeIntrusive<TTestSocket>(accepted));
-}
-
+std::pair<TTestSocketPtr, TTestSocketPtr> TcpSockets() {
+ // create server (listening) socket
+ SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
+ Y_VERIFY(server != -1, "socket() failed with %s", strerror(errno));
+
+ // bind it to local address with automatically picked port
+ sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ if (bind(server, (sockaddr*)&addr, sizeof(addr)) == -1) {
+ Y_FAIL("bind() failed with %s", strerror(errno));
+ } else if (listen(server, 1) == -1) {
+ Y_FAIL("listen() failed with %s", strerror(errno));
+ }
+
+ // obtain local address for client
+ socklen_t len = sizeof(addr);
+ if (getsockname(server, (sockaddr*)&addr, &len) == -1) {
+ Y_FAIL("getsockname() failed with %s", strerror(errno));
+ }
+
+ // create client socket
+ SOCKET client = socket(AF_INET, SOCK_STREAM, 0);
+ Y_VERIFY(client != -1, "socket() failed with %s", strerror(errno));
+
+ // connect to server
+ if (connect(client, (sockaddr*)&addr, len) == -1) {
+ Y_FAIL("connect() failed with %s", strerror(errno));
+ }
+
+ // accept connection from the other side
+ SOCKET accepted = accept(server, nullptr, nullptr);
+ Y_VERIFY(accepted != -1, "accept() failed with %s", strerror(errno));
+
+ // close server socket
+ closesocket(server);
+
+ return std::make_pair(MakeIntrusive<TTestSocket>(client), MakeIntrusive<TTestSocket>(accepted));
+}
+
class TPollerActorTest: public TTestBase {
UNIT_TEST_SUITE(TPollerActorTest);
UNIT_TEST(Registration)
@@ -99,32 +99,32 @@ public:
auto readerId = ActorSystem_->AllocateEdgeActor();
auto writerId = ActorSystem_->AllocateEdgeActor();
- RegisterSocket(s1, readerId, writerId);
+ RegisterSocket(s1, readerId, writerId);
// reader should receive event after socket registration
- TPollerToken::TPtr token;
+ TPollerToken::TPtr token;
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(readerId);
- token = ev->Get()->PollerToken;
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(readerId);
+ token = ev->Get()->PollerToken;
}
// writer should receive event after socket registration
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(writerId);
- UNIT_ASSERT_EQUAL(token, ev->Get()->PollerToken);
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(writerId);
+ UNIT_ASSERT_EQUAL(token, ev->Get()->PollerToken);
}
}
void ReadNotification() {
auto [r, w] = NonBlockSockets();
auto clientId = ActorSystem_->AllocateEdgeActor();
- RegisterSocket(r, clientId, {});
+ RegisterSocket(r, clientId, {});
// notification after registration
- TPollerToken::TPtr token;
+ TPollerToken::TPtr token;
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
- token = ev->Get()->PollerToken;
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
+ token = ev->Get()->PollerToken;
}
char buf;
@@ -133,18 +133,18 @@ public:
UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1);
UNIT_ASSERT(errno == EWOULDBLOCK);
- // request read poll
- token->Request(true, false);
-
+ // request read poll
+ token->Request(true, false);
+
// write data
UNIT_ASSERT(write(w->GetDescriptor(), "x", 1) == 1);
// notification after socket become readable
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
- UNIT_ASSERT_EQUAL(ev->Get()->Socket, r);
- UNIT_ASSERT(ev->Get()->Read);
- UNIT_ASSERT(!ev->Get()->Write);
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
+ UNIT_ASSERT_EQUAL(ev->Get()->Socket, r);
+ UNIT_ASSERT(ev->Get()->Read);
+ UNIT_ASSERT(!ev->Get()->Write);
}
// read data
@@ -157,102 +157,102 @@ public:
}
void WriteNotification() {
- auto [r, w] = TcpSockets();
+ auto [r, w] = TcpSockets();
auto clientId = ActorSystem_->AllocateEdgeActor();
- SetNonBlock(w->GetDescriptor());
- RegisterSocket(w, TActorId{}, clientId);
+ SetNonBlock(w->GetDescriptor());
+ RegisterSocket(w, TActorId{}, clientId);
// notification after registration
- TPollerToken::TPtr token;
- {
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
- token = ev->Get()->PollerToken;
+ TPollerToken::TPtr token;
+ {
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
+ token = ev->Get()->PollerToken;
}
- char buffer[4096];
- memset(buffer, 'x', sizeof(buffer));
-
- for (int i = 0; i < 1000; ++i) {
- // write as much as possible to send buffer
- ssize_t written = 0;
- for (;;) {
- ssize_t res = send(w->GetDescriptor(), buffer, sizeof(buffer), 0);
- if (res > 0) {
- written += res;
- } else if (res == 0) {
- UNIT_FAIL("unexpected zero return from send()");
+ char buffer[4096];
+ memset(buffer, 'x', sizeof(buffer));
+
+ for (int i = 0; i < 1000; ++i) {
+ // write as much as possible to send buffer
+ ssize_t written = 0;
+ for (;;) {
+ ssize_t res = send(w->GetDescriptor(), buffer, sizeof(buffer), 0);
+ if (res > 0) {
+ written += res;
+ } else if (res == 0) {
+ UNIT_FAIL("unexpected zero return from send()");
} else {
- UNIT_ASSERT(res == -1);
- if (errno == EINTR) {
- continue;
- } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
- token->Request(false, true);
- break;
- } else {
- UNIT_FAIL("unexpected error from send()");
- }
+ UNIT_ASSERT(res == -1);
+ if (errno == EINTR) {
+ continue;
+ } else if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ token->Request(false, true);
+ break;
+ } else {
+ UNIT_FAIL("unexpected error from send()");
+ }
}
}
- Cerr << "written " << written << " bytes" << Endl;
-
- // read all written data from the read end
- for (;;) {
- char buffer[4096];
- ssize_t res = recv(r->GetDescriptor(), buffer, sizeof(buffer), 0);
- if (res > 0) {
- UNIT_ASSERT(written >= res);
- written -= res;
- if (!written) {
- break;
- }
- } else if (res == 0) {
- UNIT_FAIL("unexpected zero return from recv()");
- } else {
- UNIT_ASSERT(res == -1);
- if (errno == EINTR) {
- continue;
- } else {
- UNIT_FAIL("unexpected error from recv()");
- }
- }
- }
-
- // wait for notification after socket becomes writable again
- {
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
- UNIT_ASSERT_EQUAL(ev->Get()->Socket, w);
- UNIT_ASSERT(!ev->Get()->Read);
- UNIT_ASSERT(ev->Get()->Write);
- }
+ Cerr << "written " << written << " bytes" << Endl;
+
+ // read all written data from the read end
+ for (;;) {
+ char buffer[4096];
+ ssize_t res = recv(r->GetDescriptor(), buffer, sizeof(buffer), 0);
+ if (res > 0) {
+ UNIT_ASSERT(written >= res);
+ written -= res;
+ if (!written) {
+ break;
+ }
+ } else if (res == 0) {
+ UNIT_FAIL("unexpected zero return from recv()");
+ } else {
+ UNIT_ASSERT(res == -1);
+ if (errno == EINTR) {
+ continue;
+ } else {
+ UNIT_FAIL("unexpected error from recv()");
+ }
+ }
+ }
+
+ // wait for notification after socket becomes writable again
+ {
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
+ UNIT_ASSERT_EQUAL(ev->Get()->Socket, w);
+ UNIT_ASSERT(!ev->Get()->Read);
+ UNIT_ASSERT(ev->Get()->Write);
+ }
}
}
void HangupNotification() {
auto [r, w] = NonBlockSockets();
auto clientId = ActorSystem_->AllocateEdgeActor();
- RegisterSocket(r, clientId, TActorId{});
+ RegisterSocket(r, clientId, TActorId{});
// notification after registration
- TPollerToken::TPtr token;
+ TPollerToken::TPtr token;
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
- token = ev->Get()->PollerToken;
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
+ token = ev->Get()->PollerToken;
}
- token->Request(true, false);
- ShutDown(w->GetDescriptor(), SHUT_RDWR);
+ token->Request(true, false);
+ ShutDown(w->GetDescriptor(), SHUT_RDWR);
- // notification after peer shuts down its socket
+ // notification after peer shuts down its socket
{
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
- UNIT_ASSERT_EQUAL(ev->Get()->Socket, r);
- UNIT_ASSERT(ev->Get()->Read);
+ auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId);
+ UNIT_ASSERT_EQUAL(ev->Get()->Socket, r);
+ UNIT_ASSERT(ev->Get()->Read);
}
}
private:
- void RegisterSocket(TTestSocketPtr socket, TActorId readActorId, TActorId writeActorId) {
- auto ev = new TEvPollerRegister{socket, readActorId, writeActorId};
+ void RegisterSocket(TTestSocketPtr socket, TActorId readActorId, TActorId writeActorId) {
+ auto ev = new TEvPollerRegister{socket, readActorId, writeActorId};
ActorSystem_->Send(new IEventHandle(PollerId_, TActorId{}, ev));
}
diff --git a/library/cpp/actors/interconnect/ut/ya.make b/library/cpp/actors/interconnect/ut/ya.make
index 2f5b13352ef..6793bf895a3 100644
--- a/library/cpp/actors/interconnect/ut/ya.make
+++ b/library/cpp/actors/interconnect/ut/ya.make
@@ -1,7 +1,7 @@
UNITTEST()
OWNER(
- alexvru
+ alexvru
g:kikimr
)
@@ -16,11 +16,11 @@ ENDIF()
SRCS(
channel_scheduler_ut.cpp
- event_holder_pool_ut.cpp
- interconnect_ut.cpp
- large.cpp
+ event_holder_pool_ut.cpp
+ interconnect_ut.cpp
+ large.cpp
poller_actor_ut.cpp
- dynamic_proxy_ut.cpp
+ dynamic_proxy_ut.cpp
)
PEERDIR(
@@ -29,7 +29,7 @@ PEERDIR(
library/cpp/actors/interconnect/ut/lib
library/cpp/actors/interconnect/ut/protos
library/cpp/actors/testlib
- library/cpp/digest/md5
+ library/cpp/digest/md5
library/cpp/testing/unittest
)
diff --git a/library/cpp/actors/interconnect/ut_fat/ya.make b/library/cpp/actors/interconnect/ut_fat/ya.make
index 6e58d081548..40548b8b13f 100644
--- a/library/cpp/actors/interconnect/ut_fat/ya.make
+++ b/library/cpp/actors/interconnect/ut_fat/ya.make
@@ -16,7 +16,7 @@ SRCS(
PEERDIR(
library/cpp/actors/core
library/cpp/actors/interconnect
- library/cpp/actors/interconnect/mock
+ library/cpp/actors/interconnect/mock
library/cpp/actors/interconnect/ut/lib
library/cpp/actors/interconnect/ut/protos
library/cpp/testing/unittest
diff --git a/library/cpp/actors/interconnect/watchdog_timer.h b/library/cpp/actors/interconnect/watchdog_timer.h
index c190105a592..3481113e1a0 100644
--- a/library/cpp/actors/interconnect/watchdog_timer.h
+++ b/library/cpp/actors/interconnect/watchdog_timer.h
@@ -1,68 +1,68 @@
-#pragma once
-
-namespace NActors {
+#pragma once
+
+namespace NActors {
template <typename TEvent>
- class TWatchdogTimer {
- using TCallback = std::function<void()>;
-
- const TDuration Timeout;
- const TCallback Callback;
-
- TInstant LastResetTimestamp;
+ class TWatchdogTimer {
+ using TCallback = std::function<void()>;
+
+ const TDuration Timeout;
+ const TCallback Callback;
+
+ TInstant LastResetTimestamp;
TEvent* ExpectedEvent = nullptr;
- ui32 Iteration = 0;
-
- static constexpr ui32 NumIterationsBeforeFiring = 2;
-
- public:
- TWatchdogTimer(TDuration timeout, TCallback callback)
- : Timeout(timeout)
- , Callback(std::move(callback))
+ ui32 Iteration = 0;
+
+ static constexpr ui32 NumIterationsBeforeFiring = 2;
+
+ public:
+ TWatchdogTimer(TDuration timeout, TCallback callback)
+ : Timeout(timeout)
+ , Callback(std::move(callback))
{
}
-
- void Arm(const TActorIdentity& actor) {
- if (Timeout != TDuration::Zero() && Timeout != TDuration::Max()) {
- Schedule(Timeout, actor);
- Reset();
- }
- }
-
- void Reset() {
- LastResetTimestamp = TActivationContext::Now();
- }
-
- void Disarm() {
- ExpectedEvent = nullptr;
- }
-
- void operator()(typename TEvent::TPtr& ev) {
- if (ev->Get() == ExpectedEvent) {
- const TInstant now = TActivationContext::Now();
- const TInstant barrier = LastResetTimestamp + Timeout;
- if (now < barrier) {
- // the time hasn't come yet
- Schedule(barrier - now, TActorIdentity(ev->Recipient));
- } else if (Iteration < NumIterationsBeforeFiring) {
- // time has come, but we will still give actor a chance to process some messages and rearm timer
- ++Iteration;
- TActivationContext::Send(ev.Release()); // send this event into queue once more
- } else {
- // no chance to disarm, fire callback
- Callback();
- ExpectedEvent = nullptr;
- Iteration = 0;
- }
- }
- }
-
- private:
- void Schedule(TDuration timeout, const TActorIdentity& actor) {
- auto ev = MakeHolder<TEvent>();
- ExpectedEvent = ev.Get();
- Iteration = 0;
- actor.Schedule(timeout, ev.Release());
- }
- };
-
+
+ void Arm(const TActorIdentity& actor) {
+ if (Timeout != TDuration::Zero() && Timeout != TDuration::Max()) {
+ Schedule(Timeout, actor);
+ Reset();
+ }
+ }
+
+ void Reset() {
+ LastResetTimestamp = TActivationContext::Now();
+ }
+
+ void Disarm() {
+ ExpectedEvent = nullptr;
+ }
+
+ void operator()(typename TEvent::TPtr& ev) {
+ if (ev->Get() == ExpectedEvent) {
+ const TInstant now = TActivationContext::Now();
+ const TInstant barrier = LastResetTimestamp + Timeout;
+ if (now < barrier) {
+ // the time hasn't come yet
+ Schedule(barrier - now, TActorIdentity(ev->Recipient));
+ } else if (Iteration < NumIterationsBeforeFiring) {
+ // time has come, but we will still give actor a chance to process some messages and rearm timer
+ ++Iteration;
+ TActivationContext::Send(ev.Release()); // send this event into queue once more
+ } else {
+ // no chance to disarm, fire callback
+ Callback();
+ ExpectedEvent = nullptr;
+ Iteration = 0;
+ }
+ }
+ }
+
+ private:
+ void Schedule(TDuration timeout, const TActorIdentity& actor) {
+ auto ev = MakeHolder<TEvent>();
+ ExpectedEvent = ev.Get();
+ Iteration = 0;
+ actor.Schedule(timeout, ev.Release());
+ }
+ };
+
}
diff --git a/library/cpp/actors/interconnect/ya.make b/library/cpp/actors/interconnect/ya.make
index 60d29b0fc0c..0ec679ab5f4 100644
--- a/library/cpp/actors/interconnect/ya.make
+++ b/library/cpp/actors/interconnect/ya.make
@@ -1,79 +1,79 @@
-LIBRARY()
-
-OWNER(
- ddoarn
- alexvru
- g:kikimr
-)
-
+LIBRARY()
+
+OWNER(
+ ddoarn
+ alexvru
+ g:kikimr
+)
+
NO_WSHADOW()
IF (PROFILE_MEMORY_ALLOCATIONS)
CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS)
ENDIF()
-SRCS(
- channel_scheduler.h
- event_filter.h
- event_holder_pool.h
+SRCS(
+ channel_scheduler.h
+ event_filter.h
+ event_holder_pool.h
events_local.h
- interconnect_address.cpp
- interconnect_address.h
- interconnect_channel.cpp
- interconnect_channel.h
- interconnect_common.h
+ interconnect_address.cpp
+ interconnect_address.h
+ interconnect_channel.cpp
+ interconnect_channel.h
+ interconnect_common.h
interconnect_counters.cpp
- interconnect.h
- interconnect_handshake.cpp
- interconnect_handshake.h
- interconnect_impl.h
- interconnect_mon.cpp
- interconnect_mon.h
+ interconnect.h
+ interconnect_handshake.cpp
+ interconnect_handshake.h
+ interconnect_impl.h
+ interconnect_mon.cpp
+ interconnect_mon.h
interconnect_nameserver_dynamic.cpp
- interconnect_nameserver_table.cpp
- interconnect_proxy_wrapper.cpp
- interconnect_proxy_wrapper.h
+ interconnect_nameserver_table.cpp
+ interconnect_proxy_wrapper.cpp
+ interconnect_proxy_wrapper.h
interconnect_resolve.cpp
- interconnect_stream.cpp
- interconnect_stream.h
- interconnect_tcp_input_session.cpp
- interconnect_tcp_proxy.cpp
- interconnect_tcp_proxy.h
- interconnect_tcp_server.cpp
- interconnect_tcp_server.h
- interconnect_tcp_session.cpp
- interconnect_tcp_session.h
- load.cpp
- load.h
+ interconnect_stream.cpp
+ interconnect_stream.h
+ interconnect_tcp_input_session.cpp
+ interconnect_tcp_proxy.cpp
+ interconnect_tcp_proxy.h
+ interconnect_tcp_server.cpp
+ interconnect_tcp_server.h
+ interconnect_tcp_session.cpp
+ interconnect_tcp_session.h
+ load.cpp
+ load.h
logging.h
- packet.cpp
- packet.h
- poller_actor.cpp
- poller_actor.h
- poller.h
- poller_tcp.cpp
- poller_tcp.h
- poller_tcp_unit.cpp
- poller_tcp_unit.h
- poller_tcp_unit_select.cpp
- poller_tcp_unit_select.h
- profiler.h
- slowpoke_actor.h
- types.cpp
- types.h
- watchdog_timer.h
-)
-
-IF (OS_LINUX)
- SRCS(
- poller_tcp_unit_epoll.cpp
- poller_tcp_unit_epoll.h
- )
-ENDIF()
-
-PEERDIR(
+ packet.cpp
+ packet.h
+ poller_actor.cpp
+ poller_actor.h
+ poller.h
+ poller_tcp.cpp
+ poller_tcp.h
+ poller_tcp_unit.cpp
+ poller_tcp_unit.h
+ poller_tcp_unit_select.cpp
+ poller_tcp_unit_select.h
+ profiler.h
+ slowpoke_actor.h
+ types.cpp
+ types.h
+ watchdog_timer.h
+)
+
+IF (OS_LINUX)
+ SRCS(
+ poller_tcp_unit_epoll.cpp
+ poller_tcp_unit_epoll.h
+ )
+ENDIF()
+
+PEERDIR(
contrib/libs/libc_compat
- contrib/libs/openssl
+ contrib/libs/openssl
library/cpp/actors/core
library/cpp/actors/dnscachelib
library/cpp/actors/dnsresolver
@@ -89,6 +89,6 @@ PEERDIR(
library/cpp/monlib/service/pages/tablesorter
library/cpp/openssl/init
library/cpp/packedtypes
-)
-
-END()
+)
+
+END()
diff --git a/library/cpp/actors/protos/interconnect.proto b/library/cpp/actors/protos/interconnect.proto
index 2e3b0d0d15d..4bfaa54179b 100644
--- a/library/cpp/actors/protos/interconnect.proto
+++ b/library/cpp/actors/protos/interconnect.proto
@@ -1,12 +1,12 @@
import "library/cpp/actors/protos/actors.proto";
-import "google/protobuf/descriptor.proto";
-
+import "google/protobuf/descriptor.proto";
+
package NActorsInterconnect;
option java_package = "ru.yandex.kikimr.proto";
message TEvResolveNode {
optional uint32 NodeId = 1;
- optional uint64 Deadline = 2;
+ optional uint64 Deadline = 2;
}
message TEvNodeInfo {
@@ -15,34 +15,34 @@ message TEvNodeInfo {
optional uint32 Port = 3;
}
-extend google.protobuf.FieldOptions {
- optional string PrintName = 50376;
-}
-
-message TNodeLocation {
- // compatibility section -- will be removed in future versions
- optional uint32 DataCenterNum = 1 [deprecated=true];
- optional uint32 RoomNum = 2 [deprecated=true];
- optional uint32 RackNum = 3 [deprecated=true];
- optional uint32 BodyNum = 4 [deprecated=true];
- optional uint32 Body = 100500 [deprecated=true]; // for compatibility with WalleLocation
-
- optional string DataCenter = 10 [(PrintName) = "DC"];
- optional string Module = 20 [(PrintName) = "M"];
- optional string Rack = 30 [(PrintName) = "R"];
- optional string Unit = 40 [(PrintName) = "U"];
-}
-
-message TClusterUUIDs {
- optional string ClusterUUID = 1;
- repeated string AcceptUUID = 2;
-}
-
-message TScopeId {
- optional fixed64 X1 = 1;
- optional fixed64 X2 = 2;
+extend google.protobuf.FieldOptions {
+ optional string PrintName = 50376;
}
+message TNodeLocation {
+ // compatibility section -- will be removed in future versions
+ optional uint32 DataCenterNum = 1 [deprecated=true];
+ optional uint32 RoomNum = 2 [deprecated=true];
+ optional uint32 RackNum = 3 [deprecated=true];
+ optional uint32 BodyNum = 4 [deprecated=true];
+ optional uint32 Body = 100500 [deprecated=true]; // for compatibility with WalleLocation
+
+ optional string DataCenter = 10 [(PrintName) = "DC"];
+ optional string Module = 20 [(PrintName) = "M"];
+ optional string Rack = 30 [(PrintName) = "R"];
+ optional string Unit = 40 [(PrintName) = "U"];
+}
+
+message TClusterUUIDs {
+ optional string ClusterUUID = 1;
+ repeated string AcceptUUID = 2;
+}
+
+message TScopeId {
+ optional fixed64 X1 = 1;
+ optional fixed64 X2 = 2;
+}
+
message THandshakeRequest {
required uint64 Protocol = 1;
@@ -56,22 +56,22 @@ message THandshakeRequest {
optional string SenderHostName = 7;
optional string ReceiverHostName = 8;
optional string UUID = 9;
- optional TClusterUUIDs ClusterUUIDs = 13;
-
- optional bytes Ballast = 10;
-
- optional string VersionTag = 11;
- repeated string AcceptedVersionTags = 12;
-
- optional bool RequireEncryption = 14;
- optional TScopeId ClientScopeId = 15;
-
- optional string Cookie = 16;
- optional bool DoCheckCookie = 17;
-
- optional bool RequestModernFrame = 18;
-
- optional bool RequestAuthOnly = 19;
+ optional TClusterUUIDs ClusterUUIDs = 13;
+
+ optional bytes Ballast = 10;
+
+ optional string VersionTag = 11;
+ repeated string AcceptedVersionTags = 12;
+
+ optional bool RequireEncryption = 14;
+ optional TScopeId ClientScopeId = 15;
+
+ optional string Cookie = 16;
+ optional bool DoCheckCookie = 17;
+
+ optional bool RequestModernFrame = 18;
+
+ optional bool RequestAuthOnly = 19;
}
message THandshakeSuccess {
@@ -82,32 +82,32 @@ message THandshakeSuccess {
required uint64 Serial = 4;
required string SenderActorId = 5;
-
- optional string VersionTag = 6;
- repeated string AcceptedVersionTags = 7;
-
- optional TClusterUUIDs ClusterUUIDs = 8;
-
- optional bool StartEncryption = 9;
- optional TScopeId ServerScopeId = 10;
-
- optional bool UseModernFrame = 11;
-
- optional bool AuthOnly = 12;
+
+ optional string VersionTag = 6;
+ repeated string AcceptedVersionTags = 7;
+
+ optional TClusterUUIDs ClusterUUIDs = 8;
+
+ optional bool StartEncryption = 9;
+ optional TScopeId ServerScopeId = 10;
+
+ optional bool UseModernFrame = 11;
+
+ optional bool AuthOnly = 12;
}
message THandshakeReply {
optional THandshakeSuccess Success = 1;
optional string ErrorExplaination = 2;
- optional bool CookieCheckResult = 3;
+ optional bool CookieCheckResult = 3;
}
-
-message TEvLoadMessage {
- message THop {
+
+message TEvLoadMessage {
+ message THop {
optional NActorsProto.TActorId NextHop = 1; // if zero, then the payload is trimmed out of the message
- }
-
- repeated THop Hops = 1; // the route for the message
- optional string Id = 3; // message identifier
- optional bytes Payload = 4; // data payload
-}
+ }
+
+ repeated THop Hops = 1; // the route for the message
+ optional string Id = 3; // message identifier
+ optional bytes Payload = 4; // data payload
+}
diff --git a/library/cpp/actors/protos/services_common.proto b/library/cpp/actors/protos/services_common.proto
index afa0ec0073d..855968f2a15 100644
--- a/library/cpp/actors/protos/services_common.proto
+++ b/library/cpp/actors/protos/services_common.proto
@@ -9,10 +9,10 @@ enum EServiceCommon {
INTERCONNECT = 1;
TEST = 2;
PROTOCOLS = 3;
- INTERCONNECT_SPEED_TEST = 4;
- INTERCONNECT_STATUS = 5;
- INTERCONNECT_NETWORK = 6;
- INTERCONNECT_SESSION = 7;
+ INTERCONNECT_SPEED_TEST = 4;
+ INTERCONNECT_STATUS = 5;
+ INTERCONNECT_NETWORK = 6;
+ INTERCONNECT_SESSION = 7;
HTTP = 8;
// This value is reserved boundary. Is must not be aliased with any values
diff --git a/library/cpp/actors/protos/unittests.proto b/library/cpp/actors/protos/unittests.proto
index a856b0942ad..b11465f9625 100644
--- a/library/cpp/actors/protos/unittests.proto
+++ b/library/cpp/actors/protos/unittests.proto
@@ -12,9 +12,9 @@ message TBigMessage {
optional string OneMoreStr = 3;
optional uint64 YANumber = 4;
}
-
-message TMessageWithPayload {
- optional string Meta = 1;
- repeated uint32 PayloadId = 2;
+
+message TMessageWithPayload {
+ optional string Meta = 1;
+ repeated uint32 PayloadId = 2;
repeated string SomeData = 3;
-}
+}
diff --git a/library/cpp/actors/protos/ya.make b/library/cpp/actors/protos/ya.make
index 3a1488d78ea..7c79c2591d6 100644
--- a/library/cpp/actors/protos/ya.make
+++ b/library/cpp/actors/protos/ya.make
@@ -4,9 +4,9 @@ OWNER(g:kikimr)
SRCS(
actors.proto
- interconnect.proto
- services_common.proto
- unittests.proto
+ interconnect.proto
+ services_common.proto
+ unittests.proto
)
EXCLUDE_TAGS(GO_PROTO)
diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp
index 6fa25b99656..db9d20b7ace 100644
--- a/library/cpp/actors/testlib/test_runtime.cpp
+++ b/library/cpp/actors/testlib/test_runtime.cpp
@@ -11,7 +11,7 @@
#include <library/cpp/random_provider/random_provider.h>
#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
+#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
#include <util/generic/maybe.h>
#include <util/generic/bt_exception.h>
@@ -487,9 +487,9 @@ namespace NActors {
void TTestActorRuntimeBase::InitNode(TNodeDataBase* node, size_t nodeIndex) {
const NActors::TActorId loggerActorId = NActors::TActorId(FirstNodeId + nodeIndex, "logger");
- node->LogSettings = new NActors::NLog::TSettings(loggerActorId, 410 /* NKikimrServices::LOGGER */,
+ node->LogSettings = new NActors::NLog::TSettings(loggerActorId, 410 /* NKikimrServices::LOGGER */,
NActors::NLog::PRI_WARN, NActors::NLog::PRI_WARN, 0);
- node->LogSettings->SetAllowDrop(false);
+ node->LogSettings->SetAllowDrop(false);
node->LogSettings->SetThrottleDelay(TDuration::Zero());
node->DynamicCounters = new NMonitoring::TDynamicCounters;
@@ -642,8 +642,8 @@ namespace NActors {
while (!scheduledEvents.empty() && scheduledEvents.begin()->Deadline == time) {
static THashMap<std::pair<TActorId, TString>, ui64> eventTypes;
auto& item = *scheduledEvents.begin();
- TString name = item.Event->GetBase() ? TypeName(*item.Event->GetBase()) : Sprintf("%08" PRIx32, item.Event->Type);
- eventTypes[std::make_pair(item.Event->Recipient, name)]++;
+ TString name = item.Event->GetBase() ? TypeName(*item.Event->GetBase()) : Sprintf("%08" PRIx32, item.Event->Type);
+ eventTypes[std::make_pair(item.Event->Recipient, name)]++;
runtime.ScheduledCount++;
if (runtime.ScheduledCount > runtime.ScheduledLimit) {
// TScheduledTreeItem root("Root");
@@ -1653,11 +1653,11 @@ namespace NActors {
common->TechnicalSelfHostName = "::1";
if (!UseRealThreads) {
- common->Settings.DeadPeer = TDuration::Max();
- common->Settings.CloseOnIdle = TDuration::Max();
- common->Settings.PingPeriod = TDuration::Max();
- common->Settings.ForceConfirmPeriod = TDuration::Max();
- common->Settings.Handshake = TDuration::Max();
+ common->Settings.DeadPeer = TDuration::Max();
+ common->Settings.CloseOnIdle = TDuration::Max();
+ common->Settings.PingPeriod = TDuration::Max();
+ common->Settings.ForceConfirmPeriod = TDuration::Max();
+ common->Settings.Handshake = TDuration::Max();
}
common->ClusterUUID = ClusterUUID;
@@ -1667,22 +1667,22 @@ namespace NActors {
if (proxyNodeIndex == nodeIndex)
continue;
- const ui32 peerNodeId = FirstNodeId + proxyNodeIndex;
+ const ui32 peerNodeId = FirstNodeId + proxyNodeIndex;
- IActor *proxyActor = UseRealInterconnect
- ? new TInterconnectProxyTCP(peerNodeId, common)
- : InterconnectMock.CreateProxyMock(setup->NodeId, peerNodeId, common);
-
- setup->Interconnect.ProxyActors[peerNodeId] = {proxyActor, TMailboxType::ReadAsFilled, InterconnectPoolId()};
+ IActor *proxyActor = UseRealInterconnect
+ ? new TInterconnectProxyTCP(peerNodeId, common)
+ : InterconnectMock.CreateProxyMock(setup->NodeId, peerNodeId, common);
+
+ setup->Interconnect.ProxyActors[peerNodeId] = {proxyActor, TMailboxType::ReadAsFilled, InterconnectPoolId()};
}
- setup->Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(common, InterconnectPoolId(), &InterconnectMock);
-
- if (UseRealInterconnect) {
- setup->LocalServices.emplace_back(MakePollerActorId(), NActors::TActorSetupCmd(CreatePollerActor(),
- NActors::TMailboxType::Simple, InterconnectPoolId()));
- }
+ setup->Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(common, InterconnectPoolId(), &InterconnectMock);
+ if (UseRealInterconnect) {
+ setup->LocalServices.emplace_back(MakePollerActorId(), NActors::TActorSetupCmd(CreatePollerActor(),
+ NActors::TMailboxType::Simple, InterconnectPoolId()));
+ }
+
if (!SingleSysEnv) { // Single system env should do this self
TAutoPtr<TLogBackend> logBackend = LogBackend ? LogBackend : NActors::CreateStderrBackend();
NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor(node->LogSettings,
@@ -1852,7 +1852,7 @@ namespace NActors {
ReplyChecker->OnRequest(ev);
TAutoPtr<IEventHandle> forwardedEv = ev->HasEvent()
? new IEventHandle(Delegatee, ReplyId, ev->ReleaseBase().Release(), ev->Flags, ev->Cookie)
- : new IEventHandle(ev->GetTypeRewrite(), ev->Flags, Delegatee, ReplyId, ev->ReleaseChainBuffer(), ev->Cookie);
+ : new IEventHandle(ev->GetTypeRewrite(), ev->Flags, Delegatee, ReplyId, ev->ReleaseChainBuffer(), ev->Cookie);
return forwardedEv;
}
diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h
index 26e3b45c984..ebf445f8a5b 100644
--- a/library/cpp/actors/testlib/test_runtime.h
+++ b/library/cpp/actors/testlib/test_runtime.h
@@ -8,7 +8,7 @@
#include <library/cpp/actors/core/mailbox.h>
#include <library/cpp/actors/util/should_continue.h>
#include <library/cpp/actors/interconnect/poller_tcp.h>
-#include <library/cpp/actors/interconnect/mock/ic_mock.h>
+#include <library/cpp/actors/interconnect/mock/ic_mock.h>
#include <library/cpp/random_provider/random_provider.h>
#include <library/cpp/time_provider/time_provider.h>
#include <library/cpp/testing/unittest/tests_data.h>
@@ -467,10 +467,10 @@ namespace NActors {
const TVector<ui64>& GetTxAllocatorTabletIds() const { return TxAllocatorTabletIds; }
void SetTxAllocatorTabletIds(const TVector<ui64>& ids) { TxAllocatorTabletIds = ids; }
- void SetUseRealInterconnect() {
- UseRealInterconnect = true;
- }
-
+ void SetUseRealInterconnect() {
+ UseRealInterconnect = true;
+ }
+
protected:
struct TNodeDataBase;
TNodeDataBase* GetRawNode(ui32 node) const {
@@ -508,8 +508,8 @@ namespace NActors {
const TThread::TId MainThreadId;
protected:
- bool UseRealInterconnect = false;
- TInterconnectMock InterconnectMock;
+ bool UseRealInterconnect = false;
+ TInterconnectMock InterconnectMock;
bool IsInitialized = false;
bool SingleSysEnv = false;
const TString ClusterUUID;
diff --git a/library/cpp/actors/testlib/ya.make b/library/cpp/actors/testlib/ya.make
index 1afb3f60591..c42f9306d78 100644
--- a/library/cpp/actors/testlib/ya.make
+++ b/library/cpp/actors/testlib/ya.make
@@ -10,7 +10,7 @@ SRCS(
PEERDIR(
library/cpp/actors/core
- library/cpp/actors/interconnect/mock
+ library/cpp/actors/interconnect/mock
library/cpp/actors/protos
library/cpp/random_provider
library/cpp/time_provider
diff --git a/library/cpp/actors/util/named_tuple.h b/library/cpp/actors/util/named_tuple.h
index 67f185bba8b..bd8e7c44b25 100644
--- a/library/cpp/actors/util/named_tuple.h
+++ b/library/cpp/actors/util/named_tuple.h
@@ -1,30 +1,30 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
template <typename TDerived>
-struct TNamedTupleBase {
+struct TNamedTupleBase {
friend bool operator==(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() == y.ConvertToTuple();
- }
-
+ return x.ConvertToTuple() == y.ConvertToTuple();
+ }
+
friend bool operator!=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() != y.ConvertToTuple();
- }
-
+ return x.ConvertToTuple() != y.ConvertToTuple();
+ }
+
friend bool operator<(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() < y.ConvertToTuple();
- }
-
+ return x.ConvertToTuple() < y.ConvertToTuple();
+ }
+
friend bool operator<=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() <= y.ConvertToTuple();
- }
-
+ return x.ConvertToTuple() <= y.ConvertToTuple();
+ }
+
friend bool operator>(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() > y.ConvertToTuple();
- }
-
+ return x.ConvertToTuple() > y.ConvertToTuple();
+ }
+
friend bool operator>=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() >= y.ConvertToTuple();
- }
-};
+ return x.ConvertToTuple() >= y.ConvertToTuple();
+ }
+};
diff --git a/library/cpp/actors/util/rope.h b/library/cpp/actors/util/rope.h
index f5595efbaa6..9d3c3896c8d 100644
--- a/library/cpp/actors/util/rope.h
+++ b/library/cpp/actors/util/rope.h
@@ -1,998 +1,998 @@
-#pragma once
-
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/hash_set.h>
-#include <util/stream/str.h>
+#pragma once
+
+#include <util/generic/ptr.h>
+#include <util/generic/string.h>
+#include <util/generic/hash_set.h>
+#include <util/stream/str.h>
#include <util/system/sanitizers.h>
#include <util/system/valgrind.h>
-
-// exactly one of them must be included
-#include "rope_cont_list.h"
-//#include "rope_cont_deque.h"
-
-struct IRopeChunkBackend : TThrRefBase {
- using TData = std::tuple<const char*, size_t>;
- virtual ~IRopeChunkBackend() = default;
- virtual TData GetData() const = 0;
- virtual size_t GetCapacity() const = 0;
- using TPtr = TIntrusivePtr<IRopeChunkBackend>;
-};
-
-class TRopeAlignedBuffer : public IRopeChunkBackend {
- static constexpr size_t Alignment = 16;
- static constexpr size_t MallocAlignment = sizeof(size_t);
-
- ui32 Size;
- const ui32 Capacity;
- const ui32 Offset;
- alignas(Alignment) char Data[];
-
- TRopeAlignedBuffer(size_t size)
- : Size(size)
- , Capacity(size)
- , Offset((Alignment - reinterpret_cast<uintptr_t>(Data)) & (Alignment - 1))
- {
- Y_VERIFY(Offset <= Alignment - MallocAlignment);
- }
-
-public:
- static TIntrusivePtr<TRopeAlignedBuffer> Allocate(size_t size) {
- return new(malloc(sizeof(TRopeAlignedBuffer) + size + Alignment - MallocAlignment)) TRopeAlignedBuffer(size);
- }
-
- void *operator new(size_t) {
- Y_FAIL();
- }
-
- void *operator new(size_t, void *ptr) {
- return ptr;
- }
-
- void operator delete(void *ptr) {
- free(ptr);
- }
-
+
+// exactly one of them must be included
+#include "rope_cont_list.h"
+//#include "rope_cont_deque.h"
+
+struct IRopeChunkBackend : TThrRefBase {
+ using TData = std::tuple<const char*, size_t>;
+ virtual ~IRopeChunkBackend() = default;
+ virtual TData GetData() const = 0;
+ virtual size_t GetCapacity() const = 0;
+ using TPtr = TIntrusivePtr<IRopeChunkBackend>;
+};
+
+class TRopeAlignedBuffer : public IRopeChunkBackend {
+ static constexpr size_t Alignment = 16;
+ static constexpr size_t MallocAlignment = sizeof(size_t);
+
+ ui32 Size;
+ const ui32 Capacity;
+ const ui32 Offset;
+ alignas(Alignment) char Data[];
+
+ TRopeAlignedBuffer(size_t size)
+ : Size(size)
+ , Capacity(size)
+ , Offset((Alignment - reinterpret_cast<uintptr_t>(Data)) & (Alignment - 1))
+ {
+ Y_VERIFY(Offset <= Alignment - MallocAlignment);
+ }
+
+public:
+ static TIntrusivePtr<TRopeAlignedBuffer> Allocate(size_t size) {
+ return new(malloc(sizeof(TRopeAlignedBuffer) + size + Alignment - MallocAlignment)) TRopeAlignedBuffer(size);
+ }
+
+ void *operator new(size_t) {
+ Y_FAIL();
+ }
+
+ void *operator new(size_t, void *ptr) {
+ return ptr;
+ }
+
+ void operator delete(void *ptr) {
+ free(ptr);
+ }
+
void operator delete(void* p, void* ptr) {
Y_UNUSED(p);
Y_UNUSED(ptr);
}
- TData GetData() const override {
- return {Data + Offset, Size};
- }
-
- size_t GetCapacity() const override {
- return Capacity;
- }
-
- char *GetBuffer() {
- return Data + Offset;
- }
-
- void AdjustSize(size_t size) {
- Y_VERIFY(size <= Capacity);
- Size = size;
- }
-};
-
-namespace NRopeDetails {
-
- template<bool IsConst, typename TRope, typename TList>
- struct TIteratorTraits;
-
- template<typename TRope, typename TList>
- struct TIteratorTraits<true, TRope, TList> {
- using TRopePtr = const TRope*;
- using TListIterator = typename TList::const_iterator;
- };
-
- template<typename TRope, typename TList>
- struct TIteratorTraits<false, TRope, TList> {
- using TRopePtr = TRope*;
- using TListIterator = typename TList::iterator;
- };
-
-} // NRopeDetails
-
-class TRopeArena;
-
-template<typename T>
-struct always_false : std::false_type {};
-
-class TRope {
- friend class TRopeArena;
-
- struct TChunk
- {
- class TBackend {
- enum class EType : uintptr_t {
- STRING,
- ROPE_CHUNK_BACKEND,
- };
-
- uintptr_t Owner = 0; // lower bits contain type of the owner
-
- public:
- TBackend() = delete;
-
- TBackend(const TBackend& other)
- : Owner(Clone(other.Owner))
- {}
-
- TBackend(TBackend&& other)
- : Owner(std::exchange(other.Owner, 0))
- {}
-
- TBackend(TString s)
- : Owner(Construct<TString>(EType::STRING, std::move(s)))
- {}
-
- TBackend(IRopeChunkBackend::TPtr backend)
- : Owner(Construct<IRopeChunkBackend::TPtr>(EType::ROPE_CHUNK_BACKEND, std::move(backend)))
- {}
-
- ~TBackend() {
- if (Owner) {
- Destroy(Owner);
- }
- }
-
- TBackend& operator =(const TBackend& other) {
- if (Owner) {
- Destroy(Owner);
- }
- Owner = Clone(other.Owner);
- return *this;
- }
-
- TBackend& operator =(TBackend&& other) {
- if (Owner) {
- Destroy(Owner);
- }
- Owner = std::exchange(other.Owner, 0);
- return *this;
- }
-
- bool operator ==(const TBackend& other) const {
- return Owner == other.Owner;
- }
-
- const void *UniqueId() const {
- return reinterpret_cast<const void*>(Owner);
- }
-
- const IRopeChunkBackend::TData GetData() const {
- return Visit(Owner, [](EType, auto& value) -> IRopeChunkBackend::TData {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TString>) {
- return {value.data(), value.size()};
- } else if constexpr (std::is_same_v<T, IRopeChunkBackend::TPtr>) {
- return value->GetData();
- } else {
- return {};
- }
- });
- }
-
- size_t GetCapacity() const {
- return Visit(Owner, [](EType, auto& value) {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TString>) {
- return value.capacity();
- } else if constexpr (std::is_same_v<T, IRopeChunkBackend::TPtr>) {
- return value->GetCapacity();
- } else {
- Y_FAIL();
- }
- });
- }
-
- private:
- static constexpr uintptr_t TypeMask = (1 << 3) - 1;
- static constexpr uintptr_t ValueMask = ~TypeMask;
-
- template<typename T>
- struct TObjectHolder {
- struct TWrappedObject : TThrRefBase {
- T Value;
- TWrappedObject(T&& value)
- : Value(std::move(value))
- {}
- };
- TIntrusivePtr<TWrappedObject> Object;
-
- TObjectHolder(T&& object)
- : Object(MakeIntrusive<TWrappedObject>(std::move(object)))
- {}
- };
-
- template<typename TObject>
- static uintptr_t Construct(EType type, TObject object) {
- if constexpr (sizeof(TObject) <= sizeof(uintptr_t)) {
- uintptr_t res = 0;
- new(&res) TObject(std::move(object));
- Y_VERIFY_DEBUG((res & ValueMask) == res);
- return res | static_cast<uintptr_t>(type);
- } else {
- return Construct<TObjectHolder<TObject>>(type, TObjectHolder<TObject>(std::move(object)));
- }
- }
-
- template<typename TCallback>
- static std::invoke_result_t<TCallback, EType, TString&> VisitRaw(uintptr_t value, TCallback&& callback) {
- Y_VERIFY_DEBUG(value);
- const EType type = static_cast<EType>(value & TypeMask);
- value &= ValueMask;
- auto caller = [&](auto& value) { return std::invoke(std::forward<TCallback>(callback), type, value); };
- auto wrapper = [&](auto& value) {
- using T = std::decay_t<decltype(value)>;
- if constexpr (sizeof(T) <= sizeof(uintptr_t)) {
- return caller(value);
- } else {
- return caller(reinterpret_cast<TObjectHolder<T>&>(value));
- }
- };
- switch (type) {
- case EType::STRING: return wrapper(reinterpret_cast<TString&>(value));
- case EType::ROPE_CHUNK_BACKEND: return wrapper(reinterpret_cast<IRopeChunkBackend::TPtr&>(value));
- }
+ TData GetData() const override {
+ return {Data + Offset, Size};
+ }
+
+ size_t GetCapacity() const override {
+ return Capacity;
+ }
+
+ char *GetBuffer() {
+ return Data + Offset;
+ }
+
+ void AdjustSize(size_t size) {
+ Y_VERIFY(size <= Capacity);
+ Size = size;
+ }
+};
+
+namespace NRopeDetails {
+
+ template<bool IsConst, typename TRope, typename TList>
+ struct TIteratorTraits;
+
+ template<typename TRope, typename TList>
+ struct TIteratorTraits<true, TRope, TList> {
+ using TRopePtr = const TRope*;
+ using TListIterator = typename TList::const_iterator;
+ };
+
+ template<typename TRope, typename TList>
+ struct TIteratorTraits<false, TRope, TList> {
+ using TRopePtr = TRope*;
+ using TListIterator = typename TList::iterator;
+ };
+
+} // NRopeDetails
+
+class TRopeArena;
+
+template<typename T>
+struct always_false : std::false_type {};
+
+class TRope {
+ friend class TRopeArena;
+
+ struct TChunk
+ {
+ class TBackend {
+ enum class EType : uintptr_t {
+ STRING,
+ ROPE_CHUNK_BACKEND,
+ };
+
+ uintptr_t Owner = 0; // lower bits contain type of the owner
+
+ public:
+ TBackend() = delete;
+
+ TBackend(const TBackend& other)
+ : Owner(Clone(other.Owner))
+ {}
+
+ TBackend(TBackend&& other)
+ : Owner(std::exchange(other.Owner, 0))
+ {}
+
+ TBackend(TString s)
+ : Owner(Construct<TString>(EType::STRING, std::move(s)))
+ {}
+
+ TBackend(IRopeChunkBackend::TPtr backend)
+ : Owner(Construct<IRopeChunkBackend::TPtr>(EType::ROPE_CHUNK_BACKEND, std::move(backend)))
+ {}
+
+ ~TBackend() {
+ if (Owner) {
+ Destroy(Owner);
+ }
+ }
+
+ TBackend& operator =(const TBackend& other) {
+ if (Owner) {
+ Destroy(Owner);
+ }
+ Owner = Clone(other.Owner);
+ return *this;
+ }
+
+ TBackend& operator =(TBackend&& other) {
+ if (Owner) {
+ Destroy(Owner);
+ }
+ Owner = std::exchange(other.Owner, 0);
+ return *this;
+ }
+
+ bool operator ==(const TBackend& other) const {
+ return Owner == other.Owner;
+ }
+
+ const void *UniqueId() const {
+ return reinterpret_cast<const void*>(Owner);
+ }
+
+ const IRopeChunkBackend::TData GetData() const {
+ return Visit(Owner, [](EType, auto& value) -> IRopeChunkBackend::TData {
+ using T = std::decay_t<decltype(value)>;
+ if constexpr (std::is_same_v<T, TString>) {
+ return {value.data(), value.size()};
+ } else if constexpr (std::is_same_v<T, IRopeChunkBackend::TPtr>) {
+ return value->GetData();
+ } else {
+ return {};
+ }
+ });
+ }
+
+ size_t GetCapacity() const {
+ return Visit(Owner, [](EType, auto& value) {
+ using T = std::decay_t<decltype(value)>;
+ if constexpr (std::is_same_v<T, TString>) {
+ return value.capacity();
+ } else if constexpr (std::is_same_v<T, IRopeChunkBackend::TPtr>) {
+ return value->GetCapacity();
+ } else {
+ Y_FAIL();
+ }
+ });
+ }
+
+ private:
+ static constexpr uintptr_t TypeMask = (1 << 3) - 1;
+ static constexpr uintptr_t ValueMask = ~TypeMask;
+
+ template<typename T>
+ struct TObjectHolder {
+ struct TWrappedObject : TThrRefBase {
+ T Value;
+ TWrappedObject(T&& value)
+ : Value(std::move(value))
+ {}
+ };
+ TIntrusivePtr<TWrappedObject> Object;
+
+ TObjectHolder(T&& object)
+ : Object(MakeIntrusive<TWrappedObject>(std::move(object)))
+ {}
+ };
+
+ template<typename TObject>
+ static uintptr_t Construct(EType type, TObject object) {
+ if constexpr (sizeof(TObject) <= sizeof(uintptr_t)) {
+ uintptr_t res = 0;
+ new(&res) TObject(std::move(object));
+ Y_VERIFY_DEBUG((res & ValueMask) == res);
+ return res | static_cast<uintptr_t>(type);
+ } else {
+ return Construct<TObjectHolder<TObject>>(type, TObjectHolder<TObject>(std::move(object)));
+ }
+ }
+
+ template<typename TCallback>
+ static std::invoke_result_t<TCallback, EType, TString&> VisitRaw(uintptr_t value, TCallback&& callback) {
+ Y_VERIFY_DEBUG(value);
+ const EType type = static_cast<EType>(value & TypeMask);
+ value &= ValueMask;
+ auto caller = [&](auto& value) { return std::invoke(std::forward<TCallback>(callback), type, value); };
+ auto wrapper = [&](auto& value) {
+ using T = std::decay_t<decltype(value)>;
+ if constexpr (sizeof(T) <= sizeof(uintptr_t)) {
+ return caller(value);
+ } else {
+ return caller(reinterpret_cast<TObjectHolder<T>&>(value));
+ }
+ };
+ switch (type) {
+ case EType::STRING: return wrapper(reinterpret_cast<TString&>(value));
+ case EType::ROPE_CHUNK_BACKEND: return wrapper(reinterpret_cast<IRopeChunkBackend::TPtr&>(value));
+ }
Y_FAIL("Unexpected type# %" PRIu64, static_cast<ui64>(type));
- }
-
- template<typename TCallback>
- static std::invoke_result_t<TCallback, EType, TString&> Visit(uintptr_t value, TCallback&& callback) {
- return VisitRaw(value, [&](EType type, auto& value) {
- return std::invoke(std::forward<TCallback>(callback), type, Unwrap(value));
- });
- }
-
- template<typename T> static T& Unwrap(T& object) { return object; }
- template<typename T> static T& Unwrap(TObjectHolder<T>& holder) { return holder.Object->Value; }
-
- static uintptr_t Clone(uintptr_t value) {
- return VisitRaw(value, [](EType type, auto& value) { return Construct(type, value); });
- }
-
- static void Destroy(uintptr_t value) {
- VisitRaw(value, [](EType, auto& value) { CallDtor(value); });
- }
-
- template<typename T>
- static void CallDtor(T& value) {
- value.~T();
- }
- };
-
- TBackend Backend; // who actually holds the data
- const char *Begin; // data start
- const char *End; // data end
-
- static constexpr struct TSlice {} Slice{};
-
- template<typename T>
- TChunk(T&& backend, const IRopeChunkBackend::TData& data)
- : Backend(std::move(backend))
- , Begin(std::get<0>(data))
- , End(Begin + std::get<1>(data))
- {
- Y_VERIFY_DEBUG(Begin != End);
- }
-
- TChunk(TString s)
- : Backend(std::move(s))
- {
- size_t size;
- std::tie(Begin, size) = Backend.GetData();
- End = Begin + size;
- }
-
- TChunk(IRopeChunkBackend::TPtr backend)
- : TChunk(backend, backend->GetData())
- {}
-
- TChunk(TSlice, const char *data, size_t size, const TChunk& from)
- : TChunk(from.Backend, {data, size})
- {}
-
- TChunk(TSlice, const char *begin, const char *end, const TChunk& from)
- : TChunk(Slice, begin, end - begin, from)
- {}
-
- explicit TChunk(const TChunk& other)
- : Backend(other.Backend)
- , Begin(other.Begin)
- , End(other.End)
- {}
-
- TChunk(TChunk&& other)
- : Backend(std::move(other.Backend))
- , Begin(other.Begin)
- , End(other.End)
- {}
-
- TChunk& operator =(const TChunk&) = default;
- TChunk& operator =(TChunk&&) = default;
-
- size_t GetSize() const {
- return End - Begin;
- }
-
- static void Clear(TChunk& chunk) {
- chunk.Begin = nullptr;
- }
-
- static bool IsInUse(const TChunk& chunk) {
- return chunk.Begin != nullptr;
- }
-
- size_t GetCapacity() const {
- return Backend.GetCapacity();
- }
- };
-
- using TChunkList = NRopeDetails::TChunkList<TChunk>;
-
-private:
- // we use list here to store chain items as we have to keep valid iterators when erase/insert operations are invoked;
- // iterator uses underlying container's iterator, so we have to use container that keeps valid iterators on delete,
- // thus, the list
- TChunkList Chain;
- size_t Size = 0;
-
-private:
- template<bool IsConst>
- class TIteratorImpl {
- using TTraits = NRopeDetails::TIteratorTraits<IsConst, TRope, TChunkList>;
-
- typename TTraits::TRopePtr Rope;
- typename TTraits::TListIterator Iter;
- const char *Ptr; // ptr is always nullptr when iterator is positioned at the rope end
-
-#ifndef NDEBUG
- ui32 ValidityToken;
-#endif
-
- private:
- TIteratorImpl(typename TTraits::TRopePtr rope, typename TTraits::TListIterator iter, const char *ptr = nullptr)
- : Rope(rope)
- , Iter(iter)
- , Ptr(ptr)
-#ifndef NDEBUG
- , ValidityToken(Rope->GetValidityToken())
-#endif
- {}
-
- public:
- TIteratorImpl()
- : Rope(nullptr)
- , Ptr(nullptr)
- {}
-
- template<bool IsOtherConst>
- TIteratorImpl(const TIteratorImpl<IsOtherConst>& other)
- : Rope(other.Rope)
- , Iter(other.Iter)
- , Ptr(other.Ptr)
-#ifndef NDEBUG
- , ValidityToken(other.ValidityToken)
-#endif
- {}
-
- void CheckValid() const {
-#ifndef NDEBUG
- Y_VERIFY(ValidityToken == Rope->GetValidityToken());
-#endif
- }
-
- TIteratorImpl& operator +=(size_t amount) {
- CheckValid();
-
- while (amount) {
- Y_VERIFY_DEBUG(Valid());
- const size_t max = ContiguousSize();
- const size_t num = std::min(amount, max);
- amount -= num;
- Ptr += num;
- if (Ptr == Iter->End) {
- AdvanceToNextContiguousBlock();
- }
- }
-
- return *this;
- }
-
- TIteratorImpl operator +(size_t amount) const {
- CheckValid();
-
- return TIteratorImpl(*this) += amount;
- }
-
- TIteratorImpl& operator -=(size_t amount) {
- CheckValid();
-
- while (amount) {
- const size_t num = Ptr ? std::min<size_t>(amount, Ptr - Iter->Begin) : 0;
- amount -= num;
- Ptr -= num;
- if (amount) {
- Y_VERIFY_DEBUG(Iter != GetChainBegin());
- --Iter;
- Ptr = Iter->End;
- }
- }
-
- return *this;
- }
-
- TIteratorImpl operator -(size_t amount) const {
- CheckValid();
- return TIteratorImpl(*this) -= amount;
- }
-
- std::pair<const char*, size_t> operator *() const {
- return {ContiguousData(), ContiguousSize()};
- }
-
- TIteratorImpl& operator ++() {
- AdvanceToNextContiguousBlock();
- return *this;
- }
-
- TIteratorImpl operator ++(int) const {
- auto it(*this);
- it.AdvanceToNextContiguousBlock();
- return it;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Operation with contiguous data
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // Get the pointer to the contiguous block of data; valid locations are [Data; Data + Size).
- const char *ContiguousData() const {
- CheckValid();
- return Ptr;
- }
-
- // Get the amount of contiguous block.
- size_t ContiguousSize() const {
- CheckValid();
- return Ptr ? Iter->End - Ptr : 0;
- }
-
+ }
+
+ template<typename TCallback>
+ static std::invoke_result_t<TCallback, EType, TString&> Visit(uintptr_t value, TCallback&& callback) {
+ return VisitRaw(value, [&](EType type, auto& value) {
+ return std::invoke(std::forward<TCallback>(callback), type, Unwrap(value));
+ });
+ }
+
+ template<typename T> static T& Unwrap(T& object) { return object; }
+ template<typename T> static T& Unwrap(TObjectHolder<T>& holder) { return holder.Object->Value; }
+
+ static uintptr_t Clone(uintptr_t value) {
+ return VisitRaw(value, [](EType type, auto& value) { return Construct(type, value); });
+ }
+
+ static void Destroy(uintptr_t value) {
+ VisitRaw(value, [](EType, auto& value) { CallDtor(value); });
+ }
+
+ template<typename T>
+ static void CallDtor(T& value) {
+ value.~T();
+ }
+ };
+
+ TBackend Backend; // who actually holds the data
+ const char *Begin; // data start
+ const char *End; // data end
+
+ static constexpr struct TSlice {} Slice{};
+
+ template<typename T>
+ TChunk(T&& backend, const IRopeChunkBackend::TData& data)
+ : Backend(std::move(backend))
+ , Begin(std::get<0>(data))
+ , End(Begin + std::get<1>(data))
+ {
+ Y_VERIFY_DEBUG(Begin != End);
+ }
+
+ TChunk(TString s)
+ : Backend(std::move(s))
+ {
+ size_t size;
+ std::tie(Begin, size) = Backend.GetData();
+ End = Begin + size;
+ }
+
+ TChunk(IRopeChunkBackend::TPtr backend)
+ : TChunk(backend, backend->GetData())
+ {}
+
+ TChunk(TSlice, const char *data, size_t size, const TChunk& from)
+ : TChunk(from.Backend, {data, size})
+ {}
+
+ TChunk(TSlice, const char *begin, const char *end, const TChunk& from)
+ : TChunk(Slice, begin, end - begin, from)
+ {}
+
+ explicit TChunk(const TChunk& other)
+ : Backend(other.Backend)
+ , Begin(other.Begin)
+ , End(other.End)
+ {}
+
+ TChunk(TChunk&& other)
+ : Backend(std::move(other.Backend))
+ , Begin(other.Begin)
+ , End(other.End)
+ {}
+
+ TChunk& operator =(const TChunk&) = default;
+ TChunk& operator =(TChunk&&) = default;
+
+ size_t GetSize() const {
+ return End - Begin;
+ }
+
+ static void Clear(TChunk& chunk) {
+ chunk.Begin = nullptr;
+ }
+
+ static bool IsInUse(const TChunk& chunk) {
+ return chunk.Begin != nullptr;
+ }
+
+ size_t GetCapacity() const {
+ return Backend.GetCapacity();
+ }
+ };
+
+ using TChunkList = NRopeDetails::TChunkList<TChunk>;
+
+private:
+ // we use list here to store chain items as we have to keep valid iterators when erase/insert operations are invoked;
+ // iterator uses underlying container's iterator, so we have to use container that keeps valid iterators on delete,
+ // thus, the list
+ TChunkList Chain;
+ size_t Size = 0;
+
+private:
+ template<bool IsConst>
+ class TIteratorImpl {
+ using TTraits = NRopeDetails::TIteratorTraits<IsConst, TRope, TChunkList>;
+
+ typename TTraits::TRopePtr Rope;
+ typename TTraits::TListIterator Iter;
+ const char *Ptr; // ptr is always nullptr when iterator is positioned at the rope end
+
+#ifndef NDEBUG
+ ui32 ValidityToken;
+#endif
+
+ private:
+ TIteratorImpl(typename TTraits::TRopePtr rope, typename TTraits::TListIterator iter, const char *ptr = nullptr)
+ : Rope(rope)
+ , Iter(iter)
+ , Ptr(ptr)
+#ifndef NDEBUG
+ , ValidityToken(Rope->GetValidityToken())
+#endif
+ {}
+
+ public:
+ TIteratorImpl()
+ : Rope(nullptr)
+ , Ptr(nullptr)
+ {}
+
+ template<bool IsOtherConst>
+ TIteratorImpl(const TIteratorImpl<IsOtherConst>& other)
+ : Rope(other.Rope)
+ , Iter(other.Iter)
+ , Ptr(other.Ptr)
+#ifndef NDEBUG
+ , ValidityToken(other.ValidityToken)
+#endif
+ {}
+
+ void CheckValid() const {
+#ifndef NDEBUG
+ Y_VERIFY(ValidityToken == Rope->GetValidityToken());
+#endif
+ }
+
+ TIteratorImpl& operator +=(size_t amount) {
+ CheckValid();
+
+ while (amount) {
+ Y_VERIFY_DEBUG(Valid());
+ const size_t max = ContiguousSize();
+ const size_t num = std::min(amount, max);
+ amount -= num;
+ Ptr += num;
+ if (Ptr == Iter->End) {
+ AdvanceToNextContiguousBlock();
+ }
+ }
+
+ return *this;
+ }
+
+ TIteratorImpl operator +(size_t amount) const {
+ CheckValid();
+
+ return TIteratorImpl(*this) += amount;
+ }
+
+ TIteratorImpl& operator -=(size_t amount) {
+ CheckValid();
+
+ while (amount) {
+ const size_t num = Ptr ? std::min<size_t>(amount, Ptr - Iter->Begin) : 0;
+ amount -= num;
+ Ptr -= num;
+ if (amount) {
+ Y_VERIFY_DEBUG(Iter != GetChainBegin());
+ --Iter;
+ Ptr = Iter->End;
+ }
+ }
+
+ return *this;
+ }
+
+ TIteratorImpl operator -(size_t amount) const {
+ CheckValid();
+ return TIteratorImpl(*this) -= amount;
+ }
+
+ std::pair<const char*, size_t> operator *() const {
+ return {ContiguousData(), ContiguousSize()};
+ }
+
+ TIteratorImpl& operator ++() {
+ AdvanceToNextContiguousBlock();
+ return *this;
+ }
+
+ TIteratorImpl operator ++(int) const {
+ auto it(*this);
+ it.AdvanceToNextContiguousBlock();
+ return it;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Operation with contiguous data
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // Get the pointer to the contiguous block of data; valid locations are [Data; Data + Size).
+ const char *ContiguousData() const {
+ CheckValid();
+ return Ptr;
+ }
+
+ // Get the amount of contiguous block.
+ size_t ContiguousSize() const {
+ CheckValid();
+ return Ptr ? Iter->End - Ptr : 0;
+ }
+
size_t ChunkOffset() const {
return Ptr ? Ptr - Iter->Begin : 0;
}
- // Advance to next contiguous block of data.
- void AdvanceToNextContiguousBlock() {
- CheckValid();
- Y_VERIFY_DEBUG(Valid());
- ++Iter;
- Ptr = Iter != GetChainEnd() ? Iter->Begin : nullptr;
- }
-
- // Extract some data and advance. Size is not checked here, to it must be provided valid.
- void ExtractPlainDataAndAdvance(void *buffer, size_t len) {
- CheckValid();
-
- while (len) {
- Y_VERIFY_DEBUG(Ptr);
-
- // calculate amount of bytes we need to move
- const size_t max = ContiguousSize();
- const size_t num = std::min(len, max);
-
- // copy data to the buffer and advance buffer pointers
- memcpy(buffer, Ptr, num);
- buffer = static_cast<char*>(buffer) + num;
- len -= num;
-
- // advance iterator itself
- Ptr += num;
- if (Ptr == Iter->End) {
- AdvanceToNextContiguousBlock();
- }
- }
- }
-
- // Checks if the iterator points to the end of the rope or not.
- bool Valid() const {
- CheckValid();
- return Ptr;
- }
-
- template<bool IsOtherConst>
- bool operator ==(const TIteratorImpl<IsOtherConst>& other) const {
- Y_VERIFY_DEBUG(Rope == other.Rope);
- CheckValid();
- other.CheckValid();
- return Iter == other.Iter && Ptr == other.Ptr;
- }
-
- template<bool IsOtherConst>
- bool operator !=(const TIteratorImpl<IsOtherConst>& other) const {
- CheckValid();
- other.CheckValid();
- return !(*this == other);
- }
-
- private:
- friend class TRope;
-
- typename TTraits::TListIterator operator ->() const {
- CheckValid();
- return Iter;
- }
-
- const TChunk& GetChunk() const {
- CheckValid();
- return *Iter;
- }
-
- typename TTraits::TListIterator GetChainBegin() const {
- CheckValid();
- return Rope->Chain.begin();
- }
-
- typename TTraits::TListIterator GetChainEnd() const {
- CheckValid();
- return Rope->Chain.end();
- }
-
- bool PointsToChunkMiddle() const {
- CheckValid();
- return Ptr && Ptr != Iter->Begin;
- }
- };
-
-public:
-#ifndef NDEBUG
- ui32 ValidityToken = 0;
- ui32 GetValidityToken() const { return ValidityToken; }
- void InvalidateIterators() { ++ValidityToken; }
-#else
- void InvalidateIterators() {}
-#endif
-
-public:
- using TConstIterator = TIteratorImpl<true>;
- using TIterator = TIteratorImpl<false>;
-
-public:
- TRope() = default;
- TRope(const TRope& rope) = default;
-
- TRope(TRope&& rope)
- : Chain(std::move(rope.Chain))
- , Size(std::exchange(rope.Size, 0))
- {
- rope.InvalidateIterators();
- }
-
- TRope(TString s) {
- if (s) {
- Size = s.size();
+ // Advance to next contiguous block of data.
+ void AdvanceToNextContiguousBlock() {
+ CheckValid();
+ Y_VERIFY_DEBUG(Valid());
+ ++Iter;
+ Ptr = Iter != GetChainEnd() ? Iter->Begin : nullptr;
+ }
+
+ // Extract some data and advance. Size is not checked here, to it must be provided valid.
+ void ExtractPlainDataAndAdvance(void *buffer, size_t len) {
+ CheckValid();
+
+ while (len) {
+ Y_VERIFY_DEBUG(Ptr);
+
+ // calculate amount of bytes we need to move
+ const size_t max = ContiguousSize();
+ const size_t num = std::min(len, max);
+
+ // copy data to the buffer and advance buffer pointers
+ memcpy(buffer, Ptr, num);
+ buffer = static_cast<char*>(buffer) + num;
+ len -= num;
+
+ // advance iterator itself
+ Ptr += num;
+ if (Ptr == Iter->End) {
+ AdvanceToNextContiguousBlock();
+ }
+ }
+ }
+
+ // Checks if the iterator points to the end of the rope or not.
+ bool Valid() const {
+ CheckValid();
+ return Ptr;
+ }
+
+ template<bool IsOtherConst>
+ bool operator ==(const TIteratorImpl<IsOtherConst>& other) const {
+ Y_VERIFY_DEBUG(Rope == other.Rope);
+ CheckValid();
+ other.CheckValid();
+ return Iter == other.Iter && Ptr == other.Ptr;
+ }
+
+ template<bool IsOtherConst>
+ bool operator !=(const TIteratorImpl<IsOtherConst>& other) const {
+ CheckValid();
+ other.CheckValid();
+ return !(*this == other);
+ }
+
+ private:
+ friend class TRope;
+
+ typename TTraits::TListIterator operator ->() const {
+ CheckValid();
+ return Iter;
+ }
+
+ const TChunk& GetChunk() const {
+ CheckValid();
+ return *Iter;
+ }
+
+ typename TTraits::TListIterator GetChainBegin() const {
+ CheckValid();
+ return Rope->Chain.begin();
+ }
+
+ typename TTraits::TListIterator GetChainEnd() const {
+ CheckValid();
+ return Rope->Chain.end();
+ }
+
+ bool PointsToChunkMiddle() const {
+ CheckValid();
+ return Ptr && Ptr != Iter->Begin;
+ }
+ };
+
+public:
+#ifndef NDEBUG
+ ui32 ValidityToken = 0;
+ ui32 GetValidityToken() const { return ValidityToken; }
+ void InvalidateIterators() { ++ValidityToken; }
+#else
+ void InvalidateIterators() {}
+#endif
+
+public:
+ using TConstIterator = TIteratorImpl<true>;
+ using TIterator = TIteratorImpl<false>;
+
+public:
+ TRope() = default;
+ TRope(const TRope& rope) = default;
+
+ TRope(TRope&& rope)
+ : Chain(std::move(rope.Chain))
+ , Size(std::exchange(rope.Size, 0))
+ {
+ rope.InvalidateIterators();
+ }
+
+ TRope(TString s) {
+ if (s) {
+ Size = s.size();
s.reserve(32);
- Chain.PutToEnd(std::move(s));
- }
- }
-
- TRope(IRopeChunkBackend::TPtr item) {
- std::tie(std::ignore, Size) = item->GetData();
- Chain.PutToEnd(std::move(item));
- }
-
- TRope(TConstIterator begin, TConstIterator end) {
- Y_VERIFY_DEBUG(begin.Rope == end.Rope);
- if (begin.Rope == this) {
- TRope temp(begin, end);
- *this = std::move(temp);
- return;
- }
-
- while (begin.Iter != end.Iter) {
- const size_t size = begin.ContiguousSize();
- Chain.PutToEnd(TChunk::Slice, begin.ContiguousData(), size, begin.GetChunk());
- begin.AdvanceToNextContiguousBlock();
- Size += size;
- }
-
- if (begin != end && end.PointsToChunkMiddle()) {
- Chain.PutToEnd(TChunk::Slice, begin.Ptr, end.Ptr, begin.GetChunk());
- Size += end.Ptr - begin.Ptr;
- }
- }
-
- ~TRope() {
- }
-
- // creates a copy of rope with chunks with inefficient storage ratio being copied with arena allocator
- static TRope CopySpaceOptimized(TRope&& origin, size_t worstRatioPer1k, TRopeArena& arena);
-
- TRope& operator=(const TRope& other) {
- Chain = other.Chain;
- Size = other.Size;
- return *this;
- }
-
- TRope& operator=(TRope&& other) {
- Chain = std::move(other.Chain);
- Size = std::exchange(other.Size, 0);
- InvalidateIterators();
- other.InvalidateIterators();
- return *this;
- }
-
- size_t GetSize() const {
- return Size;
- }
-
- bool IsEmpty() const {
- return !Size;
- }
-
- operator bool() const {
- return Chain;
- }
-
- TIterator Begin() {
- return *this ? TIterator(this, Chain.begin(), Chain.GetFirstChunk().Begin) : End();
- }
-
- TIterator End() {
- return TIterator(this, Chain.end());
- }
-
- TIterator Iterator(TChunkList::iterator it) {
- return TIterator(this, it, it != Chain.end() ? it->Begin : nullptr);
- }
-
- TIterator Position(size_t index) {
- return Begin() + index;
- }
-
- TConstIterator Begin() const {
- return *this ? TConstIterator(this, Chain.begin(), Chain.GetFirstChunk().Begin) : End();
- }
-
- TConstIterator End() const {
- return TConstIterator(this, Chain.end());
- }
-
- TConstIterator Position(size_t index) const {
- return Begin() + index;
- }
-
- TConstIterator begin() const { return Begin(); }
- TConstIterator end() const { return End(); }
-
- void Erase(TIterator begin, TIterator end) {
- Cut(begin, end, nullptr);
- }
-
- TRope Extract(TIterator begin, TIterator end) {
- TRope res;
- Cut(begin, end, &res);
- return res;
- }
-
- void ExtractFront(size_t num, TRope *dest) {
- Y_VERIFY(Size >= num);
- if (num == Size && !*dest) {
- *dest = std::move(*this);
- return;
- }
- Size -= num;
- dest->Size += num;
- TChunkList::iterator it, first = Chain.begin();
- for (it = first; num && num >= it->GetSize(); ++it) {
- num -= it->GetSize();
- }
- if (it != first) {
- if (dest->Chain) {
- auto& last = dest->Chain.GetLastChunk();
- if (last.Backend == first->Backend && last.End == first->Begin) {
- last.End = first->End;
- first = Chain.Erase(first); // TODO(alexvru): "it" gets invalidated here on some containers
- }
- }
- dest->Chain.Splice(dest->Chain.end(), Chain, first, it);
- }
- if (num) {
- auto it = Chain.begin();
- if (dest->Chain) {
- auto& last = dest->Chain.GetLastChunk();
- if (last.Backend == first->Backend && last.End == first->Begin) {
- first->Begin += num;
- last.End = first->Begin;
- return;
- }
- }
- dest->Chain.PutToEnd(TChunk::Slice, it->Begin, it->Begin + num, *it);
- it->Begin += num;
- }
- }
-
- void Insert(TIterator pos, TRope&& rope) {
- Y_VERIFY_DEBUG(this == pos.Rope);
- Y_VERIFY_DEBUG(this != &rope);
-
- if (!rope) {
- return; // do nothing for empty rope
- }
-
- // adjust size
- Size += std::exchange(rope.Size, 0);
-
- // check if we have to split the block
- if (pos.PointsToChunkMiddle()) {
- pos.Iter = Chain.InsertBefore(pos.Iter, TChunk::Slice, pos->Begin, pos.Ptr, pos.GetChunk());
- ++pos.Iter;
- pos->Begin = pos.Ptr;
- }
-
- // perform glueing if possible
- TChunk *ropeLeft = &rope.Chain.GetFirstChunk();
- TChunk *ropeRight = &rope.Chain.GetLastChunk();
- bool gluedLeft = false, gluedRight = false;
- if (pos.Iter != Chain.begin()) { // glue left part whenever possible
- // obtain iterator to previous chunk
- auto prev(pos.Iter);
- --prev;
- if (prev->End == ropeLeft->Begin && prev->Backend == ropeLeft->Backend) { // it is glueable
- prev->End = ropeLeft->End;
- gluedLeft = true;
- }
- }
- if (pos.Iter != Chain.end() && ropeRight->End == pos->Begin && ropeRight->Backend == pos->Backend) {
- pos->Begin = ropeRight->Begin;
- gluedRight = true;
- }
- if (gluedLeft) {
- rope.Chain.EraseFront();
- }
- if (gluedRight) {
- if (rope) {
- rope.Chain.EraseBack();
- } else { // it looks like double-glueing for the same chunk, we have to drop previous one
- auto prev(pos.Iter);
- --prev;
- pos->Begin = prev->Begin;
- pos.Iter = Chain.Erase(prev);
- }
- }
- if (rope) { // insert remains
- Chain.Splice(pos.Iter, rope.Chain, rope.Chain.begin(), rope.Chain.end());
- }
- Y_VERIFY_DEBUG(!rope);
- InvalidateIterators();
- }
-
- void EraseFront(size_t len) {
- Y_VERIFY_DEBUG(Size >= len);
- Size -= len;
-
- while (len) {
- Y_VERIFY_DEBUG(Chain);
- TChunk& item = Chain.GetFirstChunk();
- const size_t itemSize = item.GetSize();
- if (len >= itemSize) {
- Chain.EraseFront();
- len -= itemSize;
- } else {
- item.Begin += len;
- break;
- }
- }
-
- InvalidateIterators();
- }
-
- void EraseBack(size_t len) {
- Y_VERIFY_DEBUG(Size >= len);
- Size -= len;
-
- while (len) {
- Y_VERIFY_DEBUG(Chain);
- TChunk& item = Chain.GetLastChunk();
- const size_t itemSize = item.GetSize();
- if (len >= itemSize) {
- Chain.EraseBack();
- len -= itemSize;
- } else {
- item.End -= len;
- break;
- }
- }
-
- InvalidateIterators();
- }
-
- bool ExtractFrontPlain(void *buffer, size_t len) {
- // check if we have enough data in the rope
- if (Size < len) {
- return false;
- }
- Size -= len;
- while (len) {
- auto& chunk = Chain.GetFirstChunk();
- const size_t num = Min(len, chunk.GetSize());
- memcpy(buffer, chunk.Begin, num);
- buffer = static_cast<char*>(buffer) + num;
- len -= num;
- chunk.Begin += num;
- if (chunk.Begin == chunk.End) {
- Chain.Erase(Chain.begin());
- }
- }
- InvalidateIterators();
- return true;
- }
-
- bool FetchFrontPlain(char **ptr, size_t *remain) {
- const size_t num = Min(*remain, Size);
- ExtractFrontPlain(*ptr, num);
- *ptr += num;
- *remain -= num;
- return !*remain;
- }
-
- static int Compare(const TRope& x, const TRope& y) {
- TConstIterator xIter = x.Begin(), yIter = y.Begin();
- while (xIter.Valid() && yIter.Valid()) {
- const size_t step = std::min(xIter.ContiguousSize(), yIter.ContiguousSize());
- if (int res = memcmp(xIter.ContiguousData(), yIter.ContiguousData(), step)) {
- return res;
- }
- xIter += step;
- yIter += step;
- }
- return xIter.Valid() - yIter.Valid();
- }
-
- // Use this method carefully -- it may significantly reduce performance when misused.
- TString ConvertToString() const {
- TString res = TString::Uninitialized(GetSize());
- Begin().ExtractPlainDataAndAdvance(res.Detach(), res.size());
- return res;
- }
-
- TString DebugString() const {
- TStringStream s;
- s << "{Size# " << Size;
- for (const auto& chunk : Chain) {
- const char *data;
- std::tie(data, std::ignore) = chunk.Backend.GetData();
- s << " [" << chunk.Begin - data << ", " << chunk.End - data << ")@" << chunk.Backend.UniqueId();
- }
- s << "}";
- return s.Str();
- }
-
- friend bool operator==(const TRope& x, const TRope& y) { return Compare(x, y) == 0; }
- friend bool operator!=(const TRope& x, const TRope& y) { return Compare(x, y) != 0; }
- friend bool operator< (const TRope& x, const TRope& y) { return Compare(x, y) < 0; }
- friend bool operator<=(const TRope& x, const TRope& y) { return Compare(x, y) <= 0; }
- friend bool operator> (const TRope& x, const TRope& y) { return Compare(x, y) > 0; }
- friend bool operator>=(const TRope& x, const TRope& y) { return Compare(x, y) >= 0; }
-
-private:
- void Cut(TIterator begin, TIterator end, TRope *target) {
- // ensure all iterators are belong to us
- Y_VERIFY_DEBUG(this == begin.Rope && this == end.Rope);
-
- // if begin and end are equal, we do nothing -- checking this case allows us to find out that begin does not
- // point to End(), for example
- if (begin == end) {
- return;
- }
-
- auto addBlock = [&](const TChunk& from, const char *begin, const char *end) {
- if (target) {
- target->Chain.PutToEnd(TChunk::Slice, begin, end, from);
- target->Size += end - begin;
- }
- Size -= end - begin;
- };
-
- // consider special case -- when begin and end point to the same block; in this case we have to split up this
- // block into two parts
- if (begin.Iter == end.Iter) {
- addBlock(begin.GetChunk(), begin.Ptr, end.Ptr);
- const char *firstChunkBegin = begin.PointsToChunkMiddle() ? begin->Begin : nullptr;
- begin->Begin = end.Ptr; // this affects both begin and end iterator pointed values
- if (firstChunkBegin) {
- Chain.InsertBefore(begin.Iter, TChunk::Slice, firstChunkBegin, begin.Ptr, begin.GetChunk());
- }
- } else {
- // check the first iterator -- if it starts not from the begin of the block, we have to adjust end of the
- // first block to match begin iterator and switch to next block
- if (begin.PointsToChunkMiddle()) {
- addBlock(begin.GetChunk(), begin.Ptr, begin->End);
- begin->End = begin.Ptr;
- begin.AdvanceToNextContiguousBlock();
- }
-
- // now drop full blocks
- size_t rangeSize = 0;
- for (auto it = begin.Iter; it != end.Iter; ++it) {
- Y_VERIFY_DEBUG(it->GetSize());
- rangeSize += it->GetSize();
- }
- if (rangeSize) {
- if (target) {
- end.Iter = target->Chain.Splice(target->Chain.end(), Chain, begin.Iter, end.Iter);
- target->Size += rangeSize;
- } else {
- end.Iter = Chain.Erase(begin.Iter, end.Iter);
- }
- Size -= rangeSize;
- }
-
- // and cut the last block if necessary
- if (end.PointsToChunkMiddle()) {
- addBlock(end.GetChunk(), end->Begin, end.Ptr);
- end->Begin = end.Ptr;
- }
- }
-
- InvalidateIterators();
- }
-};
-
-class TRopeArena {
- using TAllocateCallback = std::function<TIntrusivePtr<IRopeChunkBackend>()>;
-
- TAllocateCallback Allocator;
- TRope Arena;
- size_t Size = 0;
- THashSet<const void*> AccountedBuffers;
-
-public:
- TRopeArena(TAllocateCallback&& allocator)
- : Allocator(std::move(allocator))
- {}
-
- TRope CreateRope(const void *buffer, size_t len) {
- TRope res;
-
- while (len) {
- if (Arena) {
- auto iter = Arena.Begin();
- Y_VERIFY_DEBUG(iter.Valid());
- char *dest = const_cast<char*>(iter.ContiguousData());
- const size_t bytesToCopy = std::min(len, iter.ContiguousSize());
- memcpy(dest, buffer, bytesToCopy);
- buffer = static_cast<const char*>(buffer) + bytesToCopy;
- len -= bytesToCopy;
- res.Insert(res.End(), Arena.Extract(Arena.Begin(), Arena.Position(bytesToCopy)));
- } else {
- Arena.Insert(Arena.End(), TRope(Allocator()));
- }
- }
-
- // align arena on 8-byte boundary
- const size_t align = 8;
- if (const size_t padding = Arena.GetSize() % align) {
- Arena.EraseFront(padding);
- }
-
- return res;
- }
-
- size_t GetSize() const {
- return Size;
- }
-
- void AccountChunk(const TRope::TChunk& chunk) {
- if (AccountedBuffers.insert(chunk.Backend.UniqueId()).second) {
- Size += chunk.GetCapacity();
- }
- }
-};
-
+ Chain.PutToEnd(std::move(s));
+ }
+ }
+
+ TRope(IRopeChunkBackend::TPtr item) {
+ std::tie(std::ignore, Size) = item->GetData();
+ Chain.PutToEnd(std::move(item));
+ }
+
+ TRope(TConstIterator begin, TConstIterator end) {
+ Y_VERIFY_DEBUG(begin.Rope == end.Rope);
+ if (begin.Rope == this) {
+ TRope temp(begin, end);
+ *this = std::move(temp);
+ return;
+ }
+
+ while (begin.Iter != end.Iter) {
+ const size_t size = begin.ContiguousSize();
+ Chain.PutToEnd(TChunk::Slice, begin.ContiguousData(), size, begin.GetChunk());
+ begin.AdvanceToNextContiguousBlock();
+ Size += size;
+ }
+
+ if (begin != end && end.PointsToChunkMiddle()) {
+ Chain.PutToEnd(TChunk::Slice, begin.Ptr, end.Ptr, begin.GetChunk());
+ Size += end.Ptr - begin.Ptr;
+ }
+ }
+
+ ~TRope() {
+ }
+
+ // creates a copy of rope with chunks with inefficient storage ratio being copied with arena allocator
+ static TRope CopySpaceOptimized(TRope&& origin, size_t worstRatioPer1k, TRopeArena& arena);
+
+ TRope& operator=(const TRope& other) {
+ Chain = other.Chain;
+ Size = other.Size;
+ return *this;
+ }
+
+ TRope& operator=(TRope&& other) {
+ Chain = std::move(other.Chain);
+ Size = std::exchange(other.Size, 0);
+ InvalidateIterators();
+ other.InvalidateIterators();
+ return *this;
+ }
+
+ size_t GetSize() const {
+ return Size;
+ }
+
+ bool IsEmpty() const {
+ return !Size;
+ }
+
+ operator bool() const {
+ return Chain;
+ }
+
+ TIterator Begin() {
+ return *this ? TIterator(this, Chain.begin(), Chain.GetFirstChunk().Begin) : End();
+ }
+
+ TIterator End() {
+ return TIterator(this, Chain.end());
+ }
+
+ TIterator Iterator(TChunkList::iterator it) {
+ return TIterator(this, it, it != Chain.end() ? it->Begin : nullptr);
+ }
+
+ TIterator Position(size_t index) {
+ return Begin() + index;
+ }
+
+ TConstIterator Begin() const {
+ return *this ? TConstIterator(this, Chain.begin(), Chain.GetFirstChunk().Begin) : End();
+ }
+
+ TConstIterator End() const {
+ return TConstIterator(this, Chain.end());
+ }
+
+ TConstIterator Position(size_t index) const {
+ return Begin() + index;
+ }
+
+ TConstIterator begin() const { return Begin(); }
+ TConstIterator end() const { return End(); }
+
+ void Erase(TIterator begin, TIterator end) {
+ Cut(begin, end, nullptr);
+ }
+
+ TRope Extract(TIterator begin, TIterator end) {
+ TRope res;
+ Cut(begin, end, &res);
+ return res;
+ }
+
+ void ExtractFront(size_t num, TRope *dest) {
+ Y_VERIFY(Size >= num);
+ if (num == Size && !*dest) {
+ *dest = std::move(*this);
+ return;
+ }
+ Size -= num;
+ dest->Size += num;
+ TChunkList::iterator it, first = Chain.begin();
+ for (it = first; num && num >= it->GetSize(); ++it) {
+ num -= it->GetSize();
+ }
+ if (it != first) {
+ if (dest->Chain) {
+ auto& last = dest->Chain.GetLastChunk();
+ if (last.Backend == first->Backend && last.End == first->Begin) {
+ last.End = first->End;
+ first = Chain.Erase(first); // TODO(alexvru): "it" gets invalidated here on some containers
+ }
+ }
+ dest->Chain.Splice(dest->Chain.end(), Chain, first, it);
+ }
+ if (num) {
+ auto it = Chain.begin();
+ if (dest->Chain) {
+ auto& last = dest->Chain.GetLastChunk();
+ if (last.Backend == first->Backend && last.End == first->Begin) {
+ first->Begin += num;
+ last.End = first->Begin;
+ return;
+ }
+ }
+ dest->Chain.PutToEnd(TChunk::Slice, it->Begin, it->Begin + num, *it);
+ it->Begin += num;
+ }
+ }
+
+ void Insert(TIterator pos, TRope&& rope) {
+ Y_VERIFY_DEBUG(this == pos.Rope);
+ Y_VERIFY_DEBUG(this != &rope);
+
+ if (!rope) {
+ return; // do nothing for empty rope
+ }
+
+ // adjust size
+ Size += std::exchange(rope.Size, 0);
+
+ // check if we have to split the block
+ if (pos.PointsToChunkMiddle()) {
+ pos.Iter = Chain.InsertBefore(pos.Iter, TChunk::Slice, pos->Begin, pos.Ptr, pos.GetChunk());
+ ++pos.Iter;
+ pos->Begin = pos.Ptr;
+ }
+
+ // perform glueing if possible
+ TChunk *ropeLeft = &rope.Chain.GetFirstChunk();
+ TChunk *ropeRight = &rope.Chain.GetLastChunk();
+ bool gluedLeft = false, gluedRight = false;
+ if (pos.Iter != Chain.begin()) { // glue left part whenever possible
+ // obtain iterator to previous chunk
+ auto prev(pos.Iter);
+ --prev;
+ if (prev->End == ropeLeft->Begin && prev->Backend == ropeLeft->Backend) { // it is glueable
+ prev->End = ropeLeft->End;
+ gluedLeft = true;
+ }
+ }
+ if (pos.Iter != Chain.end() && ropeRight->End == pos->Begin && ropeRight->Backend == pos->Backend) {
+ pos->Begin = ropeRight->Begin;
+ gluedRight = true;
+ }
+ if (gluedLeft) {
+ rope.Chain.EraseFront();
+ }
+ if (gluedRight) {
+ if (rope) {
+ rope.Chain.EraseBack();
+ } else { // it looks like double-glueing for the same chunk, we have to drop previous one
+ auto prev(pos.Iter);
+ --prev;
+ pos->Begin = prev->Begin;
+ pos.Iter = Chain.Erase(prev);
+ }
+ }
+ if (rope) { // insert remains
+ Chain.Splice(pos.Iter, rope.Chain, rope.Chain.begin(), rope.Chain.end());
+ }
+ Y_VERIFY_DEBUG(!rope);
+ InvalidateIterators();
+ }
+
+ void EraseFront(size_t len) {
+ Y_VERIFY_DEBUG(Size >= len);
+ Size -= len;
+
+ while (len) {
+ Y_VERIFY_DEBUG(Chain);
+ TChunk& item = Chain.GetFirstChunk();
+ const size_t itemSize = item.GetSize();
+ if (len >= itemSize) {
+ Chain.EraseFront();
+ len -= itemSize;
+ } else {
+ item.Begin += len;
+ break;
+ }
+ }
+
+ InvalidateIterators();
+ }
+
+ void EraseBack(size_t len) {
+ Y_VERIFY_DEBUG(Size >= len);
+ Size -= len;
+
+ while (len) {
+ Y_VERIFY_DEBUG(Chain);
+ TChunk& item = Chain.GetLastChunk();
+ const size_t itemSize = item.GetSize();
+ if (len >= itemSize) {
+ Chain.EraseBack();
+ len -= itemSize;
+ } else {
+ item.End -= len;
+ break;
+ }
+ }
+
+ InvalidateIterators();
+ }
+
+ bool ExtractFrontPlain(void *buffer, size_t len) {
+ // check if we have enough data in the rope
+ if (Size < len) {
+ return false;
+ }
+ Size -= len;
+ while (len) {
+ auto& chunk = Chain.GetFirstChunk();
+ const size_t num = Min(len, chunk.GetSize());
+ memcpy(buffer, chunk.Begin, num);
+ buffer = static_cast<char*>(buffer) + num;
+ len -= num;
+ chunk.Begin += num;
+ if (chunk.Begin == chunk.End) {
+ Chain.Erase(Chain.begin());
+ }
+ }
+ InvalidateIterators();
+ return true;
+ }
+
+ bool FetchFrontPlain(char **ptr, size_t *remain) {
+ const size_t num = Min(*remain, Size);
+ ExtractFrontPlain(*ptr, num);
+ *ptr += num;
+ *remain -= num;
+ return !*remain;
+ }
+
+ static int Compare(const TRope& x, const TRope& y) {
+ TConstIterator xIter = x.Begin(), yIter = y.Begin();
+ while (xIter.Valid() && yIter.Valid()) {
+ const size_t step = std::min(xIter.ContiguousSize(), yIter.ContiguousSize());
+ if (int res = memcmp(xIter.ContiguousData(), yIter.ContiguousData(), step)) {
+ return res;
+ }
+ xIter += step;
+ yIter += step;
+ }
+ return xIter.Valid() - yIter.Valid();
+ }
+
+ // Use this method carefully -- it may significantly reduce performance when misused.
+ TString ConvertToString() const {
+ TString res = TString::Uninitialized(GetSize());
+ Begin().ExtractPlainDataAndAdvance(res.Detach(), res.size());
+ return res;
+ }
+
+ TString DebugString() const {
+ TStringStream s;
+ s << "{Size# " << Size;
+ for (const auto& chunk : Chain) {
+ const char *data;
+ std::tie(data, std::ignore) = chunk.Backend.GetData();
+ s << " [" << chunk.Begin - data << ", " << chunk.End - data << ")@" << chunk.Backend.UniqueId();
+ }
+ s << "}";
+ return s.Str();
+ }
+
+ friend bool operator==(const TRope& x, const TRope& y) { return Compare(x, y) == 0; }
+ friend bool operator!=(const TRope& x, const TRope& y) { return Compare(x, y) != 0; }
+ friend bool operator< (const TRope& x, const TRope& y) { return Compare(x, y) < 0; }
+ friend bool operator<=(const TRope& x, const TRope& y) { return Compare(x, y) <= 0; }
+ friend bool operator> (const TRope& x, const TRope& y) { return Compare(x, y) > 0; }
+ friend bool operator>=(const TRope& x, const TRope& y) { return Compare(x, y) >= 0; }
+
+private:
+ void Cut(TIterator begin, TIterator end, TRope *target) {
+ // ensure all iterators are belong to us
+ Y_VERIFY_DEBUG(this == begin.Rope && this == end.Rope);
+
+ // if begin and end are equal, we do nothing -- checking this case allows us to find out that begin does not
+ // point to End(), for example
+ if (begin == end) {
+ return;
+ }
+
+ auto addBlock = [&](const TChunk& from, const char *begin, const char *end) {
+ if (target) {
+ target->Chain.PutToEnd(TChunk::Slice, begin, end, from);
+ target->Size += end - begin;
+ }
+ Size -= end - begin;
+ };
+
+ // consider special case -- when begin and end point to the same block; in this case we have to split up this
+ // block into two parts
+ if (begin.Iter == end.Iter) {
+ addBlock(begin.GetChunk(), begin.Ptr, end.Ptr);
+ const char *firstChunkBegin = begin.PointsToChunkMiddle() ? begin->Begin : nullptr;
+ begin->Begin = end.Ptr; // this affects both begin and end iterator pointed values
+ if (firstChunkBegin) {
+ Chain.InsertBefore(begin.Iter, TChunk::Slice, firstChunkBegin, begin.Ptr, begin.GetChunk());
+ }
+ } else {
+ // check the first iterator -- if it starts not from the begin of the block, we have to adjust end of the
+ // first block to match begin iterator and switch to next block
+ if (begin.PointsToChunkMiddle()) {
+ addBlock(begin.GetChunk(), begin.Ptr, begin->End);
+ begin->End = begin.Ptr;
+ begin.AdvanceToNextContiguousBlock();
+ }
+
+ // now drop full blocks
+ size_t rangeSize = 0;
+ for (auto it = begin.Iter; it != end.Iter; ++it) {
+ Y_VERIFY_DEBUG(it->GetSize());
+ rangeSize += it->GetSize();
+ }
+ if (rangeSize) {
+ if (target) {
+ end.Iter = target->Chain.Splice(target->Chain.end(), Chain, begin.Iter, end.Iter);
+ target->Size += rangeSize;
+ } else {
+ end.Iter = Chain.Erase(begin.Iter, end.Iter);
+ }
+ Size -= rangeSize;
+ }
+
+ // and cut the last block if necessary
+ if (end.PointsToChunkMiddle()) {
+ addBlock(end.GetChunk(), end->Begin, end.Ptr);
+ end->Begin = end.Ptr;
+ }
+ }
+
+ InvalidateIterators();
+ }
+};
+
+class TRopeArena {
+ using TAllocateCallback = std::function<TIntrusivePtr<IRopeChunkBackend>()>;
+
+ TAllocateCallback Allocator;
+ TRope Arena;
+ size_t Size = 0;
+ THashSet<const void*> AccountedBuffers;
+
+public:
+ TRopeArena(TAllocateCallback&& allocator)
+ : Allocator(std::move(allocator))
+ {}
+
+ TRope CreateRope(const void *buffer, size_t len) {
+ TRope res;
+
+ while (len) {
+ if (Arena) {
+ auto iter = Arena.Begin();
+ Y_VERIFY_DEBUG(iter.Valid());
+ char *dest = const_cast<char*>(iter.ContiguousData());
+ const size_t bytesToCopy = std::min(len, iter.ContiguousSize());
+ memcpy(dest, buffer, bytesToCopy);
+ buffer = static_cast<const char*>(buffer) + bytesToCopy;
+ len -= bytesToCopy;
+ res.Insert(res.End(), Arena.Extract(Arena.Begin(), Arena.Position(bytesToCopy)));
+ } else {
+ Arena.Insert(Arena.End(), TRope(Allocator()));
+ }
+ }
+
+ // align arena on 8-byte boundary
+ const size_t align = 8;
+ if (const size_t padding = Arena.GetSize() % align) {
+ Arena.EraseFront(padding);
+ }
+
+ return res;
+ }
+
+ size_t GetSize() const {
+ return Size;
+ }
+
+ void AccountChunk(const TRope::TChunk& chunk) {
+ if (AccountedBuffers.insert(chunk.Backend.UniqueId()).second) {
+ Size += chunk.GetCapacity();
+ }
+ }
+};
+
struct TRopeUtils {
static void Memset(TRope::TConstIterator dst, char c, size_t size) {
while (size) {
@@ -1117,24 +1117,24 @@ public:
}
};
-inline TRope TRope::CopySpaceOptimized(TRope&& origin, size_t worstRatioPer1k, TRopeArena& arena) {
- TRope res;
- for (TChunk& chunk : origin.Chain) {
- size_t ratio = chunk.GetSize() * 1024 / chunk.GetCapacity();
- if (ratio < 1024 - worstRatioPer1k) {
- res.Insert(res.End(), arena.CreateRope(chunk.Begin, chunk.GetSize()));
- } else {
- res.Chain.PutToEnd(std::move(chunk));
- }
- }
- res.Size = origin.Size;
- origin = TRope();
- for (const TChunk& chunk : res.Chain) {
- arena.AccountChunk(chunk);
- }
- return res;
-}
-
+inline TRope TRope::CopySpaceOptimized(TRope&& origin, size_t worstRatioPer1k, TRopeArena& arena) {
+ TRope res;
+ for (TChunk& chunk : origin.Chain) {
+ size_t ratio = chunk.GetSize() * 1024 / chunk.GetCapacity();
+ if (ratio < 1024 - worstRatioPer1k) {
+ res.Insert(res.End(), arena.CreateRope(chunk.Begin, chunk.GetSize()));
+ } else {
+ res.Chain.PutToEnd(std::move(chunk));
+ }
+ }
+ res.Size = origin.Size;
+ origin = TRope();
+ for (const TChunk& chunk : res.Chain) {
+ arena.AccountChunk(chunk);
+ }
+ return res;
+}
+
#if defined(WITH_VALGRIND) || defined(_msan_enabled_)
diff --git a/library/cpp/actors/util/rope_cont_deque.h b/library/cpp/actors/util/rope_cont_deque.h
index d1d122c49c6..856995ebfa4 100644
--- a/library/cpp/actors/util/rope_cont_deque.h
+++ b/library/cpp/actors/util/rope_cont_deque.h
@@ -1,181 +1,181 @@
-#pragma once
-
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-#include <deque>
-
-namespace NRopeDetails {
-
-template<typename TChunk>
-class TChunkList {
- std::deque<TChunk> Chunks;
-
- static constexpr size_t MaxInplaceItems = 4;
- using TInplace = TStackVec<TChunk, MaxInplaceItems>;
- TInplace Inplace;
-
-private:
- template<typename TChunksIt, typename TInplaceIt, typename TValue>
- struct TIterator {
- TChunksIt ChunksIt;
- TInplaceIt InplaceIt;
-
- TIterator() = default;
-
- TIterator(TChunksIt chunksIt, TInplaceIt inplaceIt)
- : ChunksIt(std::move(chunksIt))
- , InplaceIt(inplaceIt)
- {}
-
- template<typename A, typename B, typename C>
- TIterator(const TIterator<A, B, C>& other)
- : ChunksIt(other.ChunksIt)
- , InplaceIt(other.InplaceIt)
- {}
-
- TIterator(const TIterator&) = default;
- TIterator(TIterator&&) = default;
- TIterator& operator =(const TIterator&) = default;
- TIterator& operator =(TIterator&&) = default;
-
- TValue& operator *() const { return InplaceIt != TInplaceIt() ? *InplaceIt : *ChunksIt; }
- TValue* operator ->() const { return InplaceIt != TInplaceIt() ? &*InplaceIt : &*ChunksIt; }
-
- TIterator& operator ++() {
- if (InplaceIt != TInplaceIt()) {
- ++InplaceIt;
- } else {
- ++ChunksIt;
- }
- return *this;
- }
-
- TIterator& operator --() {
- if (InplaceIt != TInplaceIt()) {
- --InplaceIt;
- } else {
- --ChunksIt;
- }
- return *this;
- }
-
- template<typename A, typename B, typename C>
- bool operator ==(const TIterator<A, B, C>& other) const {
- return ChunksIt == other.ChunksIt && InplaceIt == other.InplaceIt;
- }
-
- template<typename A, typename B, typename C>
- bool operator !=(const TIterator<A, B, C>& other) const {
- return ChunksIt != other.ChunksIt || InplaceIt != other.InplaceIt;
- }
- };
-
-public:
- using iterator = TIterator<typename std::deque<TChunk>::iterator, typename TInplace::iterator, TChunk>;
- using const_iterator = TIterator<typename std::deque<TChunk>::const_iterator, typename TInplace::const_iterator, const TChunk>;
-
-public:
- TChunkList() = default;
- TChunkList(const TChunkList& other) = default;
- TChunkList(TChunkList&& other) = default;
- TChunkList& operator=(const TChunkList& other) = default;
- TChunkList& operator=(TChunkList&& other) = default;
-
- template<typename... TArgs>
- void PutToEnd(TArgs&&... args) {
- InsertBefore(end(), std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
- iterator InsertBefore(iterator pos, TArgs&&... args) {
- if (!Inplace) {
- pos.InplaceIt = Inplace.end();
- }
- if (Chunks.empty() && Inplace.size() < MaxInplaceItems) {
- return {{}, Inplace.emplace(pos.InplaceIt, std::forward<TArgs>(args)...)};
- } else {
- if (Inplace) {
- Y_VERIFY_DEBUG(Chunks.empty());
- for (auto& item : Inplace) {
- Chunks.push_back(std::move(item));
- }
- pos.ChunksIt = pos.InplaceIt - Inplace.begin() + Chunks.begin();
- Inplace.clear();
- }
- return {Chunks.emplace(pos.ChunksIt, std::forward<TArgs>(args)...), {}};
- }
- }
-
- iterator Erase(iterator pos) {
- if (Inplace) {
- return {{}, Inplace.erase(pos.InplaceIt)};
- } else {
- return {Chunks.erase(pos.ChunksIt), {}};
- }
- }
-
- iterator Erase(iterator first, iterator last) {
- if (Inplace) {
- return {{}, Inplace.erase(first.InplaceIt, last.InplaceIt)};
- } else {
- return {Chunks.erase(first.ChunksIt, last.ChunksIt), {}};
- }
- }
-
- void EraseFront() {
- if (Inplace) {
- Inplace.erase(Inplace.begin());
- } else {
- Chunks.pop_front();
- }
- }
-
- void EraseBack() {
- if (Inplace) {
- Inplace.pop_back();
- } else {
- Chunks.pop_back();
- }
- }
-
- iterator Splice(iterator pos, TChunkList& from, iterator first, iterator last) {
- if (!Inplace) {
- pos.InplaceIt = Inplace.end();
- }
- size_t n = 0;
- for (auto it = first; it != last; ++it, ++n)
- {}
- if (Chunks.empty() && Inplace.size() + n <= MaxInplaceItems) {
- if (first.InplaceIt != typename TInplace::iterator()) {
- Inplace.insert(pos.InplaceIt, first.InplaceIt, last.InplaceIt);
- } else {
- Inplace.insert(pos.InplaceIt, first.ChunksIt, last.ChunksIt);
- }
- } else {
- if (Inplace) {
- Y_VERIFY_DEBUG(Chunks.empty());
- for (auto& item : Inplace) {
- Chunks.push_back(std::move(item));
- }
- pos.ChunksIt = pos.InplaceIt - Inplace.begin() + Chunks.begin();
- Inplace.clear();
- }
- if (first.InplaceIt != typename TInplace::iterator()) {
- Chunks.insert(pos.ChunksIt, first.InplaceIt, last.InplaceIt);
- } else {
- Chunks.insert(pos.ChunksIt, first.ChunksIt, last.ChunksIt);
- }
- }
- return from.Erase(first, last);
- }
-
- operator bool() const { return !Inplace.empty() || !Chunks.empty(); }
- TChunk& GetFirstChunk() { return Inplace ? Inplace.front() : Chunks.front(); }
- const TChunk& GetFirstChunk() const { return Inplace ? Inplace.front() : Chunks.front(); }
- TChunk& GetLastChunk() { return Inplace ? Inplace.back() : Chunks.back(); }
- iterator begin() { return {Chunks.begin(), Inplace ? Inplace.begin() : typename TInplace::iterator()}; }
- const_iterator begin() const { return {Chunks.begin(), Inplace ? Inplace.begin() : typename TInplace::const_iterator()}; }
- iterator end() { return {Chunks.end(), Inplace ? Inplace.end() : typename TInplace::iterator()}; }
- const_iterator end() const { return {Chunks.end(), Inplace ? Inplace.end() : typename TInplace::const_iterator()}; }
-};
-
-} // NRopeDetails
+#pragma once
+
+#include <library/cpp/containers/stack_vector/stack_vec.h>
+#include <deque>
+
+namespace NRopeDetails {
+
+template<typename TChunk>
+class TChunkList {
+ std::deque<TChunk> Chunks;
+
+ static constexpr size_t MaxInplaceItems = 4;
+ using TInplace = TStackVec<TChunk, MaxInplaceItems>;
+ TInplace Inplace;
+
+private:
+ template<typename TChunksIt, typename TInplaceIt, typename TValue>
+ struct TIterator {
+ TChunksIt ChunksIt;
+ TInplaceIt InplaceIt;
+
+ TIterator() = default;
+
+ TIterator(TChunksIt chunksIt, TInplaceIt inplaceIt)
+ : ChunksIt(std::move(chunksIt))
+ , InplaceIt(inplaceIt)
+ {}
+
+ template<typename A, typename B, typename C>
+ TIterator(const TIterator<A, B, C>& other)
+ : ChunksIt(other.ChunksIt)
+ , InplaceIt(other.InplaceIt)
+ {}
+
+ TIterator(const TIterator&) = default;
+ TIterator(TIterator&&) = default;
+ TIterator& operator =(const TIterator&) = default;
+ TIterator& operator =(TIterator&&) = default;
+
+ TValue& operator *() const { return InplaceIt != TInplaceIt() ? *InplaceIt : *ChunksIt; }
+ TValue* operator ->() const { return InplaceIt != TInplaceIt() ? &*InplaceIt : &*ChunksIt; }
+
+ TIterator& operator ++() {
+ if (InplaceIt != TInplaceIt()) {
+ ++InplaceIt;
+ } else {
+ ++ChunksIt;
+ }
+ return *this;
+ }
+
+ TIterator& operator --() {
+ if (InplaceIt != TInplaceIt()) {
+ --InplaceIt;
+ } else {
+ --ChunksIt;
+ }
+ return *this;
+ }
+
+ template<typename A, typename B, typename C>
+ bool operator ==(const TIterator<A, B, C>& other) const {
+ return ChunksIt == other.ChunksIt && InplaceIt == other.InplaceIt;
+ }
+
+ template<typename A, typename B, typename C>
+ bool operator !=(const TIterator<A, B, C>& other) const {
+ return ChunksIt != other.ChunksIt || InplaceIt != other.InplaceIt;
+ }
+ };
+
+public:
+ using iterator = TIterator<typename std::deque<TChunk>::iterator, typename TInplace::iterator, TChunk>;
+ using const_iterator = TIterator<typename std::deque<TChunk>::const_iterator, typename TInplace::const_iterator, const TChunk>;
+
+public:
+ TChunkList() = default;
+ TChunkList(const TChunkList& other) = default;
+ TChunkList(TChunkList&& other) = default;
+ TChunkList& operator=(const TChunkList& other) = default;
+ TChunkList& operator=(TChunkList&& other) = default;
+
+ template<typename... TArgs>
+ void PutToEnd(TArgs&&... args) {
+ InsertBefore(end(), std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
+ iterator InsertBefore(iterator pos, TArgs&&... args) {
+ if (!Inplace) {
+ pos.InplaceIt = Inplace.end();
+ }
+ if (Chunks.empty() && Inplace.size() < MaxInplaceItems) {
+ return {{}, Inplace.emplace(pos.InplaceIt, std::forward<TArgs>(args)...)};
+ } else {
+ if (Inplace) {
+ Y_VERIFY_DEBUG(Chunks.empty());
+ for (auto& item : Inplace) {
+ Chunks.push_back(std::move(item));
+ }
+ pos.ChunksIt = pos.InplaceIt - Inplace.begin() + Chunks.begin();
+ Inplace.clear();
+ }
+ return {Chunks.emplace(pos.ChunksIt, std::forward<TArgs>(args)...), {}};
+ }
+ }
+
+ iterator Erase(iterator pos) {
+ if (Inplace) {
+ return {{}, Inplace.erase(pos.InplaceIt)};
+ } else {
+ return {Chunks.erase(pos.ChunksIt), {}};
+ }
+ }
+
+ iterator Erase(iterator first, iterator last) {
+ if (Inplace) {
+ return {{}, Inplace.erase(first.InplaceIt, last.InplaceIt)};
+ } else {
+ return {Chunks.erase(first.ChunksIt, last.ChunksIt), {}};
+ }
+ }
+
+ void EraseFront() {
+ if (Inplace) {
+ Inplace.erase(Inplace.begin());
+ } else {
+ Chunks.pop_front();
+ }
+ }
+
+ void EraseBack() {
+ if (Inplace) {
+ Inplace.pop_back();
+ } else {
+ Chunks.pop_back();
+ }
+ }
+
+ iterator Splice(iterator pos, TChunkList& from, iterator first, iterator last) {
+ if (!Inplace) {
+ pos.InplaceIt = Inplace.end();
+ }
+ size_t n = 0;
+ for (auto it = first; it != last; ++it, ++n)
+ {}
+ if (Chunks.empty() && Inplace.size() + n <= MaxInplaceItems) {
+ if (first.InplaceIt != typename TInplace::iterator()) {
+ Inplace.insert(pos.InplaceIt, first.InplaceIt, last.InplaceIt);
+ } else {
+ Inplace.insert(pos.InplaceIt, first.ChunksIt, last.ChunksIt);
+ }
+ } else {
+ if (Inplace) {
+ Y_VERIFY_DEBUG(Chunks.empty());
+ for (auto& item : Inplace) {
+ Chunks.push_back(std::move(item));
+ }
+ pos.ChunksIt = pos.InplaceIt - Inplace.begin() + Chunks.begin();
+ Inplace.clear();
+ }
+ if (first.InplaceIt != typename TInplace::iterator()) {
+ Chunks.insert(pos.ChunksIt, first.InplaceIt, last.InplaceIt);
+ } else {
+ Chunks.insert(pos.ChunksIt, first.ChunksIt, last.ChunksIt);
+ }
+ }
+ return from.Erase(first, last);
+ }
+
+ operator bool() const { return !Inplace.empty() || !Chunks.empty(); }
+ TChunk& GetFirstChunk() { return Inplace ? Inplace.front() : Chunks.front(); }
+ const TChunk& GetFirstChunk() const { return Inplace ? Inplace.front() : Chunks.front(); }
+ TChunk& GetLastChunk() { return Inplace ? Inplace.back() : Chunks.back(); }
+ iterator begin() { return {Chunks.begin(), Inplace ? Inplace.begin() : typename TInplace::iterator()}; }
+ const_iterator begin() const { return {Chunks.begin(), Inplace ? Inplace.begin() : typename TInplace::const_iterator()}; }
+ iterator end() { return {Chunks.end(), Inplace ? Inplace.end() : typename TInplace::iterator()}; }
+ const_iterator end() const { return {Chunks.end(), Inplace ? Inplace.end() : typename TInplace::const_iterator()}; }
+};
+
+} // NRopeDetails
diff --git a/library/cpp/actors/util/rope_cont_list.h b/library/cpp/actors/util/rope_cont_list.h
index 18c136284ed..7b58089be11 100644
--- a/library/cpp/actors/util/rope_cont_list.h
+++ b/library/cpp/actors/util/rope_cont_list.h
@@ -1,159 +1,159 @@
-#pragma once
-
-#include <util/generic/intrlist.h>
-
-namespace NRopeDetails {
-
-template<typename TChunk>
-class TChunkList {
- struct TItem : TIntrusiveListItem<TItem>, TChunk {
- // delegating constructor
- template<typename... TArgs> TItem(TArgs&&... args) : TChunk(std::forward<TArgs>(args)...) {}
- };
-
- using TList = TIntrusiveList<TItem>;
- TList List;
-
- static constexpr size_t NumInplaceItems = 2;
- char InplaceItems[sizeof(TItem) * NumInplaceItems];
-
- template<typename... TArgs>
- TItem *AllocateItem(TArgs&&... args) {
- for (size_t index = 0; index < NumInplaceItems; ++index) {
- TItem *chunk = GetInplaceItemPtr(index);
- if (!TItem::IsInUse(*chunk)) {
- return new(chunk) TItem(std::forward<TArgs>(args)...);
- }
- }
- return new TItem(std::forward<TArgs>(args)...);
- }
-
- void ReleaseItem(TItem *chunk) {
- if (IsInplaceItem(chunk)) {
- chunk->~TItem();
- TItem::Clear(*chunk);
- } else {
- delete chunk;
- }
- }
-
- void ReleaseItems(TList& list) {
- while (list) {
- ReleaseItem(list.Front());
- }
- }
-
- void Prepare() {
- for (size_t index = 0; index < NumInplaceItems; ++index) {
- TItem::Clear(*GetInplaceItemPtr(index));
- }
- }
-
- TItem *GetInplaceItemPtr(size_t index) { return reinterpret_cast<TItem*>(InplaceItems + index * sizeof(TItem)); }
- bool IsInplaceItem(TItem *chunk) { return chunk >= GetInplaceItemPtr(0) && chunk < GetInplaceItemPtr(NumInplaceItems); }
-
-public:
- using iterator = typename TList::iterator;
- using const_iterator = typename TList::const_iterator;
-
-public:
- TChunkList() {
- Prepare();
- }
-
- ~TChunkList() {
- ReleaseItems(List);
-#ifndef NDEBUG
- for (size_t index = 0; index < NumInplaceItems; ++index) {
- Y_VERIFY(!TItem::IsInUse(*GetInplaceItemPtr(index)));
- }
-#endif
- }
-
- TChunkList(const TChunkList& other) {
- Prepare();
- for (const TItem& chunk : other.List) {
- PutToEnd(TChunk(chunk));
- }
- }
-
- TChunkList(TChunkList&& other) {
- Prepare();
- Splice(end(), other, other.begin(), other.end());
- }
-
- TChunkList& operator=(const TChunkList& other) {
- if (this != &other) {
- ReleaseItems(List);
- for (const TItem& chunk : other.List) {
- PutToEnd(TChunk(chunk));
- }
- }
- return *this;
- }
-
- TChunkList& operator=(TChunkList&& other) {
- if (this != &other) {
- ReleaseItems(List);
- Splice(end(), other, other.begin(), other.end());
- }
- return *this;
- }
-
- template<typename... TArgs>
- void PutToEnd(TArgs&&... args) {
- InsertBefore(end(), std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
- iterator InsertBefore(iterator pos, TArgs&&... args) {
- TItem *item = AllocateItem<TArgs...>(std::forward<TArgs>(args)...);
- item->LinkBefore(pos.Item());
- return item;
- }
-
- iterator Erase(iterator pos) {
- ReleaseItem(&*pos++);
- return pos;
- }
-
- iterator Erase(iterator first, iterator last) {
- TList temp;
- TList::Cut(first, last, temp.end());
- ReleaseItems(temp);
- return last;
- }
-
- void EraseFront() {
- ReleaseItem(List.PopFront());
- }
-
- void EraseBack() {
- ReleaseItem(List.PopBack());
- }
-
- iterator Splice(iterator pos, TChunkList& from, iterator first, iterator last) {
- for (auto it = first; it != last; ) {
- if (from.IsInplaceItem(&*it)) {
- TList::Cut(first, it, pos);
- InsertBefore(pos, std::move(*it));
- it = first = from.Erase(it);
- } else {
- ++it;
- }
- }
- TList::Cut(first, last, pos);
- return last;
- }
-
- operator bool() const { return static_cast<bool>(List); }
- TChunk& GetFirstChunk() { return *List.Front(); }
- const TChunk& GetFirstChunk() const { return *List.Front(); }
- TChunk& GetLastChunk() { return *List.Back(); }
- iterator begin() { return List.begin(); }
- const_iterator begin() const { return List.begin(); }
- iterator end() { return List.end(); }
- const_iterator end() const { return List.end(); }
-};
-
-} // NRopeDetails
+#pragma once
+
+#include <util/generic/intrlist.h>
+
+namespace NRopeDetails {
+
+template<typename TChunk>
+class TChunkList {
+ struct TItem : TIntrusiveListItem<TItem>, TChunk {
+ // delegating constructor
+ template<typename... TArgs> TItem(TArgs&&... args) : TChunk(std::forward<TArgs>(args)...) {}
+ };
+
+ using TList = TIntrusiveList<TItem>;
+ TList List;
+
+ static constexpr size_t NumInplaceItems = 2;
+ char InplaceItems[sizeof(TItem) * NumInplaceItems];
+
+ template<typename... TArgs>
+ TItem *AllocateItem(TArgs&&... args) {
+ for (size_t index = 0; index < NumInplaceItems; ++index) {
+ TItem *chunk = GetInplaceItemPtr(index);
+ if (!TItem::IsInUse(*chunk)) {
+ return new(chunk) TItem(std::forward<TArgs>(args)...);
+ }
+ }
+ return new TItem(std::forward<TArgs>(args)...);
+ }
+
+ void ReleaseItem(TItem *chunk) {
+ if (IsInplaceItem(chunk)) {
+ chunk->~TItem();
+ TItem::Clear(*chunk);
+ } else {
+ delete chunk;
+ }
+ }
+
+ void ReleaseItems(TList& list) {
+ while (list) {
+ ReleaseItem(list.Front());
+ }
+ }
+
+ void Prepare() {
+ for (size_t index = 0; index < NumInplaceItems; ++index) {
+ TItem::Clear(*GetInplaceItemPtr(index));
+ }
+ }
+
+ TItem *GetInplaceItemPtr(size_t index) { return reinterpret_cast<TItem*>(InplaceItems + index * sizeof(TItem)); }
+ bool IsInplaceItem(TItem *chunk) { return chunk >= GetInplaceItemPtr(0) && chunk < GetInplaceItemPtr(NumInplaceItems); }
+
+public:
+ using iterator = typename TList::iterator;
+ using const_iterator = typename TList::const_iterator;
+
+public:
+ TChunkList() {
+ Prepare();
+ }
+
+ ~TChunkList() {
+ ReleaseItems(List);
+#ifndef NDEBUG
+ for (size_t index = 0; index < NumInplaceItems; ++index) {
+ Y_VERIFY(!TItem::IsInUse(*GetInplaceItemPtr(index)));
+ }
+#endif
+ }
+
+ TChunkList(const TChunkList& other) {
+ Prepare();
+ for (const TItem& chunk : other.List) {
+ PutToEnd(TChunk(chunk));
+ }
+ }
+
+ TChunkList(TChunkList&& other) {
+ Prepare();
+ Splice(end(), other, other.begin(), other.end());
+ }
+
+ TChunkList& operator=(const TChunkList& other) {
+ if (this != &other) {
+ ReleaseItems(List);
+ for (const TItem& chunk : other.List) {
+ PutToEnd(TChunk(chunk));
+ }
+ }
+ return *this;
+ }
+
+ TChunkList& operator=(TChunkList&& other) {
+ if (this != &other) {
+ ReleaseItems(List);
+ Splice(end(), other, other.begin(), other.end());
+ }
+ return *this;
+ }
+
+ template<typename... TArgs>
+ void PutToEnd(TArgs&&... args) {
+ InsertBefore(end(), std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
+ iterator InsertBefore(iterator pos, TArgs&&... args) {
+ TItem *item = AllocateItem<TArgs...>(std::forward<TArgs>(args)...);
+ item->LinkBefore(pos.Item());
+ return item;
+ }
+
+ iterator Erase(iterator pos) {
+ ReleaseItem(&*pos++);
+ return pos;
+ }
+
+ iterator Erase(iterator first, iterator last) {
+ TList temp;
+ TList::Cut(first, last, temp.end());
+ ReleaseItems(temp);
+ return last;
+ }
+
+ void EraseFront() {
+ ReleaseItem(List.PopFront());
+ }
+
+ void EraseBack() {
+ ReleaseItem(List.PopBack());
+ }
+
+ iterator Splice(iterator pos, TChunkList& from, iterator first, iterator last) {
+ for (auto it = first; it != last; ) {
+ if (from.IsInplaceItem(&*it)) {
+ TList::Cut(first, it, pos);
+ InsertBefore(pos, std::move(*it));
+ it = first = from.Erase(it);
+ } else {
+ ++it;
+ }
+ }
+ TList::Cut(first, last, pos);
+ return last;
+ }
+
+ operator bool() const { return static_cast<bool>(List); }
+ TChunk& GetFirstChunk() { return *List.Front(); }
+ const TChunk& GetFirstChunk() const { return *List.Front(); }
+ TChunk& GetLastChunk() { return *List.Back(); }
+ iterator begin() { return List.begin(); }
+ const_iterator begin() const { return List.begin(); }
+ iterator end() { return List.end(); }
+ const_iterator end() const { return List.end(); }
+};
+
+} // NRopeDetails
diff --git a/library/cpp/actors/util/rope_ut.cpp b/library/cpp/actors/util/rope_ut.cpp
index cabeed92306..a6ad078f1ca 100644
--- a/library/cpp/actors/util/rope_ut.cpp
+++ b/library/cpp/actors/util/rope_ut.cpp
@@ -1,231 +1,231 @@
-#include "rope.h"
+#include "rope.h"
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-
-class TRopeStringBackend : public IRopeChunkBackend {
- TString Buffer;
-
-public:
- TRopeStringBackend(TString buffer)
- : Buffer(std::move(buffer))
- {}
-
- TData GetData() const override {
- return {Buffer.data(), Buffer.size()};
- }
-
- size_t GetCapacity() const override {
- return Buffer.capacity();
- }
-};
-
-TRope CreateRope(TString s, size_t sliceSize) {
- TRope res;
- for (size_t i = 0; i < s.size(); ) {
- size_t len = std::min(sliceSize, s.size() - i);
- if (i % 2) {
- res.Insert(res.End(), TRope(MakeIntrusive<TRopeStringBackend>(s.substr(i, len))));
- } else {
- res.Insert(res.End(), TRope(s.substr(i, len)));
- }
- i += len;
- }
- return res;
-}
-
-TString RopeToString(const TRope& rope) {
- TString res;
- auto iter = rope.Begin();
- while (iter != rope.End()) {
- res.append(iter.ContiguousData(), iter.ContiguousSize());
- iter.AdvanceToNextContiguousBlock();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(rope.GetSize(), res.size());
-
- TString temp = TString::Uninitialized(rope.GetSize());
- rope.Begin().ExtractPlainDataAndAdvance(temp.Detach(), temp.size());
- UNIT_ASSERT_VALUES_EQUAL(temp, res);
-
- return res;
-}
-
-TString Text = "No elements are copied or moved, only the internal pointers of the list nodes are re-pointed.";
-
-Y_UNIT_TEST_SUITE(TRope) {
-
- Y_UNIT_TEST(Leak) {
- const size_t begin = 10, end = 20;
- TRope rope = CreateRope(Text, 10);
- rope.Erase(rope.Begin() + begin, rope.Begin() + end);
- }
-
- Y_UNIT_TEST(BasicRange) {
- TRope rope = CreateRope(Text, 10);
- for (size_t begin = 0; begin < Text.size(); ++begin) {
- for (size_t end = begin; end <= Text.size(); ++end) {
- TRope::TIterator rBegin = rope.Begin() + begin;
- TRope::TIterator rEnd = rope.Begin() + end;
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(TRope(rBegin, rEnd)), Text.substr(begin, end - begin));
- }
- }
- }
-
- Y_UNIT_TEST(Erase) {
- for (size_t begin = 0; begin < Text.size(); ++begin) {
- for (size_t end = begin; end <= Text.size(); ++end) {
- TRope rope = CreateRope(Text, 10);
- rope.Erase(rope.Begin() + begin, rope.Begin() + end);
- TString text = Text;
- text.erase(text.begin() + begin, text.begin() + end);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), text);
- }
- }
- }
-
- Y_UNIT_TEST(Insert) {
- TRope rope = CreateRope(Text, 10);
- for (size_t begin = 0; begin < Text.size(); ++begin) {
- for (size_t end = begin; end <= Text.size(); ++end) {
- TRope part = TRope(rope.Begin() + begin, rope.Begin() + end);
- for (size_t where = 0; where <= Text.size(); ++where) {
- TRope x(rope);
- x.Insert(x.Begin() + where, TRope(part));
- UNIT_ASSERT_VALUES_EQUAL(x.GetSize(), rope.GetSize() + part.GetSize());
- TString text = Text;
- text.insert(text.begin() + where, Text.begin() + begin, Text.begin() + end);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(x), text);
- }
- }
- }
- }
-
- Y_UNIT_TEST(Extract) {
- for (size_t begin = 0; begin < Text.size(); ++begin) {
- for (size_t end = begin; end <= Text.size(); ++end) {
- TRope rope = CreateRope(Text, 10);
- TRope part = rope.Extract(rope.Begin() + begin, rope.Begin() + end);
- TString text = Text;
- text.erase(text.begin() + begin, text.begin() + end);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), text);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(part), Text.substr(begin, end - begin));
- }
- }
- }
-
- Y_UNIT_TEST(EraseFront) {
- for (size_t pos = 0; pos <= Text.size(); ++pos) {
- TRope rope = CreateRope(Text, 10);
- rope.EraseFront(pos);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text.substr(pos));
- }
- }
-
- Y_UNIT_TEST(EraseBack) {
- for (size_t pos = 0; pos <= Text.size(); ++pos) {
- TRope rope = CreateRope(Text, 10);
- rope.EraseBack(pos);
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text.substr(0, Text.size() - pos));
- }
- }
-
- Y_UNIT_TEST(ExtractFront) {
- for (size_t step = 1; step <= Text.size(); ++step) {
- TRope rope = CreateRope(Text, 10);
- TRope out;
- while (const size_t len = Min(step, rope.GetSize())) {
- rope.ExtractFront(len, &out);
- UNIT_ASSERT(rope.GetSize() + out.GetSize() == Text.size());
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(out), Text.substr(0, out.GetSize()));
- }
- }
- }
-
- Y_UNIT_TEST(ExtractFrontPlain) {
- for (size_t step = 1; step <= Text.size(); ++step) {
- TRope rope = CreateRope(Text, 10);
- TString buffer = Text;
- auto it = rope.Begin();
- size_t remain = rope.GetSize();
- while (const size_t len = Min(step, remain)) {
- TString data = TString::Uninitialized(len);
- it.ExtractPlainDataAndAdvance(data.Detach(), data.size());
- UNIT_ASSERT_VALUES_EQUAL(data, buffer.substr(0, len));
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(TRope(it, rope.End())), buffer.substr(len));
- buffer = buffer.substr(len);
- remain -= len;
- }
- }
- }
-
- Y_UNIT_TEST(FetchFrontPlain) {
- char s[10];
- char *data = s;
- size_t remain = sizeof(s);
- TRope rope = TRope(TString("HELLO"));
- UNIT_ASSERT(!rope.FetchFrontPlain(&data, &remain));
- UNIT_ASSERT(!rope);
- rope.Insert(rope.End(), TRope(TString("WORLD!!!")));
- UNIT_ASSERT(rope.FetchFrontPlain(&data, &remain));
- UNIT_ASSERT(!remain);
- UNIT_ASSERT(rope.GetSize() == 3);
- UNIT_ASSERT_VALUES_EQUAL(rope.ConvertToString(), "!!!");
- UNIT_ASSERT(!strncmp(s, "HELLOWORLD", 10));
- }
-
- Y_UNIT_TEST(Glueing) {
- TRope rope = CreateRope(Text, 10);
- for (size_t begin = 0; begin <= Text.size(); ++begin) {
- for (size_t end = begin; end <= Text.size(); ++end) {
- TString repr = rope.DebugString();
- TRope temp = rope.Extract(rope.Position(begin), rope.Position(end));
- rope.Insert(rope.Position(begin), std::move(temp));
- UNIT_ASSERT_VALUES_EQUAL(repr, rope.DebugString());
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text);
- }
- }
- }
-
- Y_UNIT_TEST(IterWalk) {
- TRope rope = CreateRope(Text, 10);
- for (size_t step1 = 0; step1 <= rope.GetSize(); ++step1) {
- for (size_t step2 = 0; step2 <= step1; ++step2) {
- TRope::TConstIterator iter = rope.Begin();
- iter += step1;
- iter -= step2;
- UNIT_ASSERT(iter == rope.Position(step1 - step2));
- }
- }
- }
-
- Y_UNIT_TEST(Compare) {
- auto check = [](const TString& x, const TString& y) {
- const TRope xRope = CreateRope(x, 7);
- const TRope yRope = CreateRope(y, 11);
- UNIT_ASSERT_VALUES_EQUAL(xRope == yRope, x == y);
- UNIT_ASSERT_VALUES_EQUAL(xRope != yRope, x != y);
- UNIT_ASSERT_VALUES_EQUAL(xRope < yRope, x < y);
- UNIT_ASSERT_VALUES_EQUAL(xRope <= yRope, x <= y);
- UNIT_ASSERT_VALUES_EQUAL(xRope > yRope, x > y);
- UNIT_ASSERT_VALUES_EQUAL(xRope >= yRope, x >= y);
- };
-
- TVector<TString> pool;
- for (size_t k = 0; k < 10; ++k) {
- size_t len = RandomNumber<size_t>(100) + 100;
- TString s = TString::Uninitialized(len);
- char *p = s.Detach();
- for (size_t j = 0; j < len; ++j) {
- *p++ = RandomNumber<unsigned char>();
- }
- pool.push_back(std::move(s));
- }
-
- for (const TString& x : pool) {
- for (const TString& y : pool) {
- check(x, y);
- }
- }
- }
-
-}
+#include <util/random/random.h>
+
+class TRopeStringBackend : public IRopeChunkBackend {
+ TString Buffer;
+
+public:
+ TRopeStringBackend(TString buffer)
+ : Buffer(std::move(buffer))
+ {}
+
+ TData GetData() const override {
+ return {Buffer.data(), Buffer.size()};
+ }
+
+ size_t GetCapacity() const override {
+ return Buffer.capacity();
+ }
+};
+
+TRope CreateRope(TString s, size_t sliceSize) {
+ TRope res;
+ for (size_t i = 0; i < s.size(); ) {
+ size_t len = std::min(sliceSize, s.size() - i);
+ if (i % 2) {
+ res.Insert(res.End(), TRope(MakeIntrusive<TRopeStringBackend>(s.substr(i, len))));
+ } else {
+ res.Insert(res.End(), TRope(s.substr(i, len)));
+ }
+ i += len;
+ }
+ return res;
+}
+
+TString RopeToString(const TRope& rope) {
+ TString res;
+ auto iter = rope.Begin();
+ while (iter != rope.End()) {
+ res.append(iter.ContiguousData(), iter.ContiguousSize());
+ iter.AdvanceToNextContiguousBlock();
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(rope.GetSize(), res.size());
+
+ TString temp = TString::Uninitialized(rope.GetSize());
+ rope.Begin().ExtractPlainDataAndAdvance(temp.Detach(), temp.size());
+ UNIT_ASSERT_VALUES_EQUAL(temp, res);
+
+ return res;
+}
+
+TString Text = "No elements are copied or moved, only the internal pointers of the list nodes are re-pointed.";
+
+Y_UNIT_TEST_SUITE(TRope) {
+
+ Y_UNIT_TEST(Leak) {
+ const size_t begin = 10, end = 20;
+ TRope rope = CreateRope(Text, 10);
+ rope.Erase(rope.Begin() + begin, rope.Begin() + end);
+ }
+
+ Y_UNIT_TEST(BasicRange) {
+ TRope rope = CreateRope(Text, 10);
+ for (size_t begin = 0; begin < Text.size(); ++begin) {
+ for (size_t end = begin; end <= Text.size(); ++end) {
+ TRope::TIterator rBegin = rope.Begin() + begin;
+ TRope::TIterator rEnd = rope.Begin() + end;
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(TRope(rBegin, rEnd)), Text.substr(begin, end - begin));
+ }
+ }
+ }
+
+ Y_UNIT_TEST(Erase) {
+ for (size_t begin = 0; begin < Text.size(); ++begin) {
+ for (size_t end = begin; end <= Text.size(); ++end) {
+ TRope rope = CreateRope(Text, 10);
+ rope.Erase(rope.Begin() + begin, rope.Begin() + end);
+ TString text = Text;
+ text.erase(text.begin() + begin, text.begin() + end);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), text);
+ }
+ }
+ }
+
+ Y_UNIT_TEST(Insert) {
+ TRope rope = CreateRope(Text, 10);
+ for (size_t begin = 0; begin < Text.size(); ++begin) {
+ for (size_t end = begin; end <= Text.size(); ++end) {
+ TRope part = TRope(rope.Begin() + begin, rope.Begin() + end);
+ for (size_t where = 0; where <= Text.size(); ++where) {
+ TRope x(rope);
+ x.Insert(x.Begin() + where, TRope(part));
+ UNIT_ASSERT_VALUES_EQUAL(x.GetSize(), rope.GetSize() + part.GetSize());
+ TString text = Text;
+ text.insert(text.begin() + where, Text.begin() + begin, Text.begin() + end);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(x), text);
+ }
+ }
+ }
+ }
+
+ Y_UNIT_TEST(Extract) {
+ for (size_t begin = 0; begin < Text.size(); ++begin) {
+ for (size_t end = begin; end <= Text.size(); ++end) {
+ TRope rope = CreateRope(Text, 10);
+ TRope part = rope.Extract(rope.Begin() + begin, rope.Begin() + end);
+ TString text = Text;
+ text.erase(text.begin() + begin, text.begin() + end);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), text);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(part), Text.substr(begin, end - begin));
+ }
+ }
+ }
+
+ Y_UNIT_TEST(EraseFront) {
+ for (size_t pos = 0; pos <= Text.size(); ++pos) {
+ TRope rope = CreateRope(Text, 10);
+ rope.EraseFront(pos);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text.substr(pos));
+ }
+ }
+
+ Y_UNIT_TEST(EraseBack) {
+ for (size_t pos = 0; pos <= Text.size(); ++pos) {
+ TRope rope = CreateRope(Text, 10);
+ rope.EraseBack(pos);
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text.substr(0, Text.size() - pos));
+ }
+ }
+
+ Y_UNIT_TEST(ExtractFront) {
+ for (size_t step = 1; step <= Text.size(); ++step) {
+ TRope rope = CreateRope(Text, 10);
+ TRope out;
+ while (const size_t len = Min(step, rope.GetSize())) {
+ rope.ExtractFront(len, &out);
+ UNIT_ASSERT(rope.GetSize() + out.GetSize() == Text.size());
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(out), Text.substr(0, out.GetSize()));
+ }
+ }
+ }
+
+ Y_UNIT_TEST(ExtractFrontPlain) {
+ for (size_t step = 1; step <= Text.size(); ++step) {
+ TRope rope = CreateRope(Text, 10);
+ TString buffer = Text;
+ auto it = rope.Begin();
+ size_t remain = rope.GetSize();
+ while (const size_t len = Min(step, remain)) {
+ TString data = TString::Uninitialized(len);
+ it.ExtractPlainDataAndAdvance(data.Detach(), data.size());
+ UNIT_ASSERT_VALUES_EQUAL(data, buffer.substr(0, len));
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(TRope(it, rope.End())), buffer.substr(len));
+ buffer = buffer.substr(len);
+ remain -= len;
+ }
+ }
+ }
+
+ Y_UNIT_TEST(FetchFrontPlain) {
+ char s[10];
+ char *data = s;
+ size_t remain = sizeof(s);
+ TRope rope = TRope(TString("HELLO"));
+ UNIT_ASSERT(!rope.FetchFrontPlain(&data, &remain));
+ UNIT_ASSERT(!rope);
+ rope.Insert(rope.End(), TRope(TString("WORLD!!!")));
+ UNIT_ASSERT(rope.FetchFrontPlain(&data, &remain));
+ UNIT_ASSERT(!remain);
+ UNIT_ASSERT(rope.GetSize() == 3);
+ UNIT_ASSERT_VALUES_EQUAL(rope.ConvertToString(), "!!!");
+ UNIT_ASSERT(!strncmp(s, "HELLOWORLD", 10));
+ }
+
+ Y_UNIT_TEST(Glueing) {
+ TRope rope = CreateRope(Text, 10);
+ for (size_t begin = 0; begin <= Text.size(); ++begin) {
+ for (size_t end = begin; end <= Text.size(); ++end) {
+ TString repr = rope.DebugString();
+ TRope temp = rope.Extract(rope.Position(begin), rope.Position(end));
+ rope.Insert(rope.Position(begin), std::move(temp));
+ UNIT_ASSERT_VALUES_EQUAL(repr, rope.DebugString());
+ UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), Text);
+ }
+ }
+ }
+
+ Y_UNIT_TEST(IterWalk) {
+ TRope rope = CreateRope(Text, 10);
+ for (size_t step1 = 0; step1 <= rope.GetSize(); ++step1) {
+ for (size_t step2 = 0; step2 <= step1; ++step2) {
+ TRope::TConstIterator iter = rope.Begin();
+ iter += step1;
+ iter -= step2;
+ UNIT_ASSERT(iter == rope.Position(step1 - step2));
+ }
+ }
+ }
+
+ Y_UNIT_TEST(Compare) {
+ auto check = [](const TString& x, const TString& y) {
+ const TRope xRope = CreateRope(x, 7);
+ const TRope yRope = CreateRope(y, 11);
+ UNIT_ASSERT_VALUES_EQUAL(xRope == yRope, x == y);
+ UNIT_ASSERT_VALUES_EQUAL(xRope != yRope, x != y);
+ UNIT_ASSERT_VALUES_EQUAL(xRope < yRope, x < y);
+ UNIT_ASSERT_VALUES_EQUAL(xRope <= yRope, x <= y);
+ UNIT_ASSERT_VALUES_EQUAL(xRope > yRope, x > y);
+ UNIT_ASSERT_VALUES_EQUAL(xRope >= yRope, x >= y);
+ };
+
+ TVector<TString> pool;
+ for (size_t k = 0; k < 10; ++k) {
+ size_t len = RandomNumber<size_t>(100) + 100;
+ TString s = TString::Uninitialized(len);
+ char *p = s.Detach();
+ for (size_t j = 0; j < len; ++j) {
+ *p++ = RandomNumber<unsigned char>();
+ }
+ pool.push_back(std::move(s));
+ }
+
+ for (const TString& x : pool) {
+ for (const TString& y : pool) {
+ check(x, y);
+ }
+ }
+ }
+
+}
diff --git a/library/cpp/actors/util/ut/ya.make b/library/cpp/actors/util/ut/ya.make
index 3b08b779842..6e69c4aec3e 100644
--- a/library/cpp/actors/util/ut/ya.make
+++ b/library/cpp/actors/util/ut/ya.make
@@ -1,5 +1,5 @@
UNITTEST_FOR(library/cpp/actors/util)
-
+
IF (WITH_VALGRIND)
TIMEOUT(600)
SIZE(MEDIUM)
@@ -9,10 +9,10 @@ OWNER(
alexvru
g:kikimr
)
-
-SRCS(
- rope_ut.cpp
+
+SRCS(
+ rope_ut.cpp
unordered_cache_ut.cpp
-)
-
-END()
+)
+
+END()
diff --git a/library/cpp/actors/util/ya.make b/library/cpp/actors/util/ya.make
index 37488c39621..c258dbf021c 100644
--- a/library/cpp/actors/util/ya.make
+++ b/library/cpp/actors/util/ya.make
@@ -11,15 +11,15 @@ SRCS(
cpumask.h
datetime.h
defs.h
- funnel_queue.h
+ funnel_queue.h
futex.h
intrinsics.h
local_process_key.h
named_tuple.h
queue_chunk.h
queue_oneone_inplace.h
- recentwnd.h
- rope.h
+ recentwnd.h
+ rope.h
should_continue.cpp
should_continue.h
thread.h
diff --git a/library/cpp/actors/wilson/wilson_event.h b/library/cpp/actors/wilson/wilson_event.h
index 7d89c33b518..de3fbb8151a 100644
--- a/library/cpp/actors/wilson/wilson_event.h
+++ b/library/cpp/actors/wilson/wilson_event.h
@@ -1,15 +1,15 @@
-#pragma once
-
-#include "wilson_trace.h"
-
+#pragma once
+
+#include "wilson_trace.h"
+
#include <library/cpp/string_utils/base64/base64.h>
-
+
#include <library/cpp/actors/core/log.h>
-
-namespace NWilson {
-#if !defined(_win_)
-// works only for those compilers, who trait C++ as ISO IEC 14882, not their own standard
-
+
+namespace NWilson {
+#if !defined(_win_)
+// works only for those compilers, who trait C++ as ISO IEC 14882, not their own standard
+
#define __UNROLL_PARAMS_8(N, F, X, ...) \
F(X, N - 8) \
__UNROLL_PARAMS_7(N, F, ##__VA_ARGS__)
@@ -32,39 +32,39 @@ namespace NWilson {
F(X, N - 2) \
__UNROLL_PARAMS_1(N, F, ##__VA_ARGS__)
#define __UNROLL_PARAMS_1(N, F, X) F(X, N - 1)
-#define __UNROLL_PARAMS_0(N, F)
-#define __EX(...) __VA_ARGS__
-#define __NUM_PARAMS(...) __NUM_PARAMS_SELECT_N(__VA_ARGS__, __NUM_PARAMS_SEQ)
-#define __NUM_PARAMS_SELECT_N(...) __EX(__NUM_PARAMS_SELECT(__VA_ARGS__))
-#define __NUM_PARAMS_SELECT(X, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
-#define __NUM_PARAMS_SEQ 8, 7, 6, 5, 4, 3, 2, 1, 0, ERROR
+#define __UNROLL_PARAMS_0(N, F)
+#define __EX(...) __VA_ARGS__
+#define __NUM_PARAMS(...) __NUM_PARAMS_SELECT_N(__VA_ARGS__, __NUM_PARAMS_SEQ)
+#define __NUM_PARAMS_SELECT_N(...) __EX(__NUM_PARAMS_SELECT(__VA_ARGS__))
+#define __NUM_PARAMS_SELECT(X, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
+#define __NUM_PARAMS_SEQ 8, 7, 6, 5, 4, 3, 2, 1, 0, ERROR
#define __CAT(X, Y) X##Y
-#define __UNROLL_PARAMS_N(N, F, ...) __EX(__CAT(__UNROLL_PARAMS_, N)(N, F, ##__VA_ARGS__))
-#define __UNROLL_PARAMS(F, ...) __UNROLL_PARAMS_N(__NUM_PARAMS(X, ##__VA_ARGS__), F, ##__VA_ARGS__)
-#define __EX2(F, X, INDEX) __INVOKE(F, __EX X, INDEX)
-#define __INVOKE(F, ...) F(__VA_ARGS__)
-
-#define __DECLARE_PARAM(X, INDEX) __EX2(__DECLARE_PARAM_X, X, INDEX)
+#define __UNROLL_PARAMS_N(N, F, ...) __EX(__CAT(__UNROLL_PARAMS_, N)(N, F, ##__VA_ARGS__))
+#define __UNROLL_PARAMS(F, ...) __UNROLL_PARAMS_N(__NUM_PARAMS(X, ##__VA_ARGS__), F, ##__VA_ARGS__)
+#define __EX2(F, X, INDEX) __INVOKE(F, __EX X, INDEX)
+#define __INVOKE(F, ...) F(__VA_ARGS__)
+
+#define __DECLARE_PARAM(X, INDEX) __EX2(__DECLARE_PARAM_X, X, INDEX)
#define __DECLARE_PARAM_X(TYPE, NAME, INDEX) \
static const struct T##NAME##Param \
: ::NWilson::TParamBinder<INDEX, TYPE> { \
T##NAME##Param() { \
} \
- using ::NWilson::TParamBinder<INDEX, TYPE>::operator=; \
- } NAME;
-
-#define __TUPLE_PARAM(X, INDEX) __EX2(__TUPLE_PARAM_X, X, INDEX)
-#define __TUPLE_PARAM_X(TYPE, NAME, INDEX) TYPE,
-
-#define __OUTPUT_PARAM(X, INDEX) __EX2(__OUTPUT_PARAM_X, X, INDEX)
-#define __OUTPUT_PARAM_X(TYPE, NAME, INDEX) str << (INDEX ? ", " : "") << #NAME << "# " << std::get<INDEX>(ParamPack);
-
+ using ::NWilson::TParamBinder<INDEX, TYPE>::operator=; \
+ } NAME;
+
+#define __TUPLE_PARAM(X, INDEX) __EX2(__TUPLE_PARAM_X, X, INDEX)
+#define __TUPLE_PARAM_X(TYPE, NAME, INDEX) TYPE,
+
+#define __OUTPUT_PARAM(X, INDEX) __EX2(__OUTPUT_PARAM_X, X, INDEX)
+#define __OUTPUT_PARAM_X(TYPE, NAME, INDEX) str << (INDEX ? ", " : "") << #NAME << "# " << std::get<INDEX>(ParamPack);
+
#define __FILL_PARAM(P, INDEX) \
do { \
const auto& boundParam = (NParams::P); \
boundParam.Apply(event.ParamPack); \
} while (false);
-
+
#define DECLARE_WILSON_EVENT(EVENT_NAME, ...) \
namespace N##EVENT_NAME##Params { \
__UNROLL_PARAMS(__DECLARE_PARAM, ##__VA_ARGS__) \
@@ -81,38 +81,38 @@ namespace NWilson {
__UNROLL_PARAMS(__OUTPUT_PARAM, ##__VA_ARGS__) \
str << "}"; \
} \
- };
-
+ };
+
template <size_t INDEX, typename T>
- class TBoundParam {
- mutable T Value;
-
- public:
- TBoundParam(T&& value)
- : Value(std::move(value))
+ class TBoundParam {
+ mutable T Value;
+
+ public:
+ TBoundParam(T&& value)
+ : Value(std::move(value))
{
}
-
+
template <typename TParamPack>
- void Apply(TParamPack& pack) const {
- std::get<INDEX>(pack) = std::move(Value);
- }
- };
-
+ void Apply(TParamPack& pack) const {
+ std::get<INDEX>(pack) = std::move(Value);
+ }
+ };
+
template <size_t INDEX, typename T>
- struct TParamBinder {
+ struct TParamBinder {
template <typename TValue>
- TBoundParam<INDEX, T> operator=(const TValue& value) const {
- return TBoundParam<INDEX, T>(TValue(value));
- }
-
+ TBoundParam<INDEX, T> operator=(const TValue& value) const {
+ return TBoundParam<INDEX, T>(TValue(value));
+ }
+
template <typename TValue>
- TBoundParam<INDEX, T> operator=(TValue&& value) const {
- return TBoundParam<INDEX, T>(std::move(value));
- }
- };
-
-// generate wilson event having parent TRACE_ID and span TRACE_ID to become parent of logged event
+ TBoundParam<INDEX, T> operator=(TValue&& value) const {
+ return TBoundParam<INDEX, T>(std::move(value));
+ }
+ };
+
+// generate wilson event having parent TRACE_ID and span TRACE_ID to become parent of logged event
#define WILSON_TRACE(CTX, TRACE_ID, EVENT_NAME, ...) \
if (::NWilson::TraceEnabled(CTX)) { \
::NWilson::TTraceId* __traceId = (TRACE_ID); \
@@ -121,17 +121,17 @@ namespace NWilson {
T##EVENT_NAME event; \
namespace NParams = N##EVENT_NAME##Params; \
__UNROLL_PARAMS(__FILL_PARAM, ##__VA_ARGS__) \
- ::NWilson::TraceEvent((CTX), __traceId, event, now); \
+ ::NWilson::TraceEvent((CTX), __traceId, event, now); \
} \
}
-
- inline ui32 GetNodeId(const NActors::TActorSystem& actorSystem) {
- return actorSystem.NodeId;
- }
- inline ui32 GetNodeId(const NActors::TActivationContext& ac) {
- return GetNodeId(*ac.ExecutorThread.ActorSystem);
- }
-
+
+ inline ui32 GetNodeId(const NActors::TActorSystem& actorSystem) {
+ return actorSystem.NodeId;
+ }
+ inline ui32 GetNodeId(const NActors::TActivationContext& ac) {
+ return GetNodeId(*ac.ExecutorThread.ActorSystem);
+ }
+
constexpr ui32 WilsonComponentId = 430; // kikimrservices: wilson
template <typename TActorSystem>
@@ -142,40 +142,40 @@ namespace NWilson {
template <typename TActorSystem, typename TEvent>
void TraceEvent(const TActorSystem& actorSystem, TTraceId* traceId, TEvent&& event, TInstant timestamp) {
- // ensure that we are not using obsolete TraceId
- traceId->CheckConsistency();
-
- // store parent id (for logging) and generate child trace id
- TTraceId parentTraceId(std::move(*traceId));
- *traceId = parentTraceId.Span();
-
- // create encoded string buffer containing timestamp
- const ui64 timestampValue = timestamp.GetValue();
- const size_t base64size = Base64EncodeBufSize(sizeof(timestampValue));
- char base64[base64size];
+ // ensure that we are not using obsolete TraceId
+ traceId->CheckConsistency();
+
+ // store parent id (for logging) and generate child trace id
+ TTraceId parentTraceId(std::move(*traceId));
+ *traceId = parentTraceId.Span();
+
+ // create encoded string buffer containing timestamp
+ const ui64 timestampValue = timestamp.GetValue();
+ const size_t base64size = Base64EncodeBufSize(sizeof(timestampValue));
+ char base64[base64size];
char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(&timestampValue), sizeof(timestampValue));
-
- // cut trailing padding character to save some space
- Y_VERIFY(end > base64 && end[-1] == '=');
- --end;
-
- // generate log record
+
+ // cut trailing padding character to save some space
+ Y_VERIFY(end > base64 && end[-1] == '=');
+ --end;
+
+ // generate log record
TString finalMessage;
TStringOutput s(finalMessage);
- s << GetNodeId(actorSystem) << " " << TStringBuf(base64, end) << " ";
- traceId->Output(s, parentTraceId);
- s << " ";
- event.Output(s);
-
- // output wilson event FIXME: special facility for wilson events w/binary serialization
+ s << GetNodeId(actorSystem) << " " << TStringBuf(base64, end) << " ";
+ traceId->Output(s, parentTraceId);
+ s << " ";
+ event.Output(s);
+
+ // output wilson event FIXME: special facility for wilson events w/binary serialization
NActors::MemLogAdapter(actorSystem, NActors::NLog::PRI_DEBUG, WilsonComponentId, std::move(finalMessage));
- }
-
-#else
-
-#define DECLARE_WILSON_EVENT(...)
-#define WILSON_TRACE(...)
-
-#endif
-
-} // NWilson
+ }
+
+#else
+
+#define DECLARE_WILSON_EVENT(...)
+#define WILSON_TRACE(...)
+
+#endif
+
+} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_trace.h b/library/cpp/actors/wilson/wilson_trace.h
index 3d1ca505623..7648915b951 100644
--- a/library/cpp/actors/wilson/wilson_trace.h
+++ b/library/cpp/actors/wilson/wilson_trace.h
@@ -1,161 +1,161 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/string_utils/base64/base64.h>
-
-#include <util/stream/output.h>
-#include <util/random/random.h>
-
-#include <util/string/printf.h>
-
-namespace NWilson {
- class TTraceId {
- ui64 TraceId; // Random id of topmost client request
- ui64 SpanId; // Span id of part of request currently being executed
-
- private:
- TTraceId(ui64 traceId, ui64 spanId)
- : TraceId(traceId)
- , SpanId(spanId)
+
+#include <util/stream/output.h>
+#include <util/random/random.h>
+
+#include <util/string/printf.h>
+
+namespace NWilson {
+ class TTraceId {
+ ui64 TraceId; // Random id of topmost client request
+ ui64 SpanId; // Span id of part of request currently being executed
+
+ private:
+ TTraceId(ui64 traceId, ui64 spanId)
+ : TraceId(traceId)
+ , SpanId(spanId)
{
}
-
- static ui64 GenerateTraceId() {
- ui64 traceId = 0;
- while (!traceId) {
- traceId = RandomNumber<ui64>();
- }
- return traceId;
- }
-
- static ui64 GenerateSpanId() {
- return RandomNumber<ui64>();
- }
-
- public:
- using TSerializedTraceId = char[2 * sizeof(ui64)];
-
- public:
- TTraceId()
- : TraceId(0)
- , SpanId(0)
+
+ static ui64 GenerateTraceId() {
+ ui64 traceId = 0;
+ while (!traceId) {
+ traceId = RandomNumber<ui64>();
+ }
+ return traceId;
+ }
+
+ static ui64 GenerateSpanId() {
+ return RandomNumber<ui64>();
+ }
+
+ public:
+ using TSerializedTraceId = char[2 * sizeof(ui64)];
+
+ public:
+ TTraceId()
+ : TraceId(0)
+ , SpanId(0)
{
}
-
+
explicit TTraceId(ui64 traceId)
: TraceId(traceId)
, SpanId(0)
{
}
- TTraceId(const TSerializedTraceId& in)
+ TTraceId(const TSerializedTraceId& in)
: TraceId(reinterpret_cast<const ui64*>(in)[0])
, SpanId(reinterpret_cast<const ui64*>(in)[1])
{
}
-
- // allow move semantic
- TTraceId(TTraceId&& other)
- : TraceId(other.TraceId)
- , SpanId(other.SpanId)
- {
- other.TraceId = 0;
- other.SpanId = 1; // explicitly mark invalid
- }
-
+
+ // allow move semantic
+ TTraceId(TTraceId&& other)
+ : TraceId(other.TraceId)
+ , SpanId(other.SpanId)
+ {
+ other.TraceId = 0;
+ other.SpanId = 1; // explicitly mark invalid
+ }
+
TTraceId& operator=(TTraceId&& other) {
- TraceId = other.TraceId;
- SpanId = other.SpanId;
- other.TraceId = 0;
- other.SpanId = 1; // explicitly mark invalid
- return *this;
- }
-
- // do not allow implicit copy of trace id
- TTraceId(const TTraceId& other) = delete;
+ TraceId = other.TraceId;
+ SpanId = other.SpanId;
+ other.TraceId = 0;
+ other.SpanId = 1; // explicitly mark invalid
+ return *this;
+ }
+
+ // do not allow implicit copy of trace id
+ TTraceId(const TTraceId& other) = delete;
TTraceId& operator=(const TTraceId& other) = delete;
-
- static TTraceId NewTraceId() {
- return TTraceId(GenerateTraceId(), 0);
- }
-
- // create separate branch from this point
- TTraceId SeparateBranch() const {
- return Clone();
- }
-
- TTraceId Clone() const {
- return TTraceId(TraceId, SpanId);
- }
-
- TTraceId Span() const {
- return *this ? TTraceId(TraceId, GenerateSpanId()) : TTraceId();
- }
-
+
+ static TTraceId NewTraceId() {
+ return TTraceId(GenerateTraceId(), 0);
+ }
+
+ // create separate branch from this point
+ TTraceId SeparateBranch() const {
+ return Clone();
+ }
+
+ TTraceId Clone() const {
+ return TTraceId(TraceId, SpanId);
+ }
+
+ TTraceId Span() const {
+ return *this ? TTraceId(TraceId, GenerateSpanId()) : TTraceId();
+ }
+
ui64 GetTraceId() const {
return TraceId;
}
- // Check if request tracing is enabled
- operator bool() const {
- return TraceId != 0;
- }
-
- // Output trace id into a string stream
+ // Check if request tracing is enabled
+ operator bool() const {
+ return TraceId != 0;
+ }
+
+ // Output trace id into a string stream
void Output(IOutputStream& s, const TTraceId& parentTraceId) const {
- union {
- ui8 buffer[3 * sizeof(ui64)];
- struct {
- ui64 traceId;
- ui64 spanId;
- ui64 parentSpanId;
- } x;
- };
-
- x.traceId = TraceId;
- x.spanId = SpanId;
- x.parentSpanId = parentTraceId.SpanId;
-
- const size_t base64size = Base64EncodeBufSize(sizeof(x));
- char base64[base64size];
+ union {
+ ui8 buffer[3 * sizeof(ui64)];
+ struct {
+ ui64 traceId;
+ ui64 spanId;
+ ui64 parentSpanId;
+ } x;
+ };
+
+ x.traceId = TraceId;
+ x.spanId = SpanId;
+ x.parentSpanId = parentTraceId.SpanId;
+
+ const size_t base64size = Base64EncodeBufSize(sizeof(x));
+ char base64[base64size];
char* end = Base64Encode(base64, buffer, sizeof(x));
- s << TStringBuf(base64, end);
- }
-
- // output just span id into stream
+ s << TStringBuf(base64, end);
+ }
+
+ // output just span id into stream
void OutputSpanId(IOutputStream& s) const {
- const size_t base64size = Base64EncodeBufSize(sizeof(SpanId));
- char base64[base64size];
+ const size_t base64size = Base64EncodeBufSize(sizeof(SpanId));
+ char base64[base64size];
char* end = Base64Encode(base64, reinterpret_cast<const ui8*>(&SpanId), sizeof(SpanId));
-
- // cut trailing padding character
- Y_VERIFY(end > base64 && end[-1] == '=');
- --end;
-
- s << TStringBuf(base64, end);
- }
-
- void CheckConsistency() {
- // if TraceId is zero, then SpanId must be zero too
- Y_VERIFY_DEBUG(*this || !SpanId);
- }
-
+
+ // cut trailing padding character
+ Y_VERIFY(end > base64 && end[-1] == '=');
+ --end;
+
+ s << TStringBuf(base64, end);
+ }
+
+ void CheckConsistency() {
+ // if TraceId is zero, then SpanId must be zero too
+ Y_VERIFY_DEBUG(*this || !SpanId);
+ }
+
friend bool operator==(const TTraceId& x, const TTraceId& y) {
- return x.TraceId == y.TraceId && x.SpanId == y.SpanId;
- }
-
+ return x.TraceId == y.TraceId && x.SpanId == y.SpanId;
+ }
+
TString ToString() const {
- return Sprintf("%" PRIu64 ":%" PRIu64, TraceId, SpanId);
- }
-
- bool IsFromSameTree(const TTraceId& other) const {
- return TraceId == other.TraceId;
- }
-
+ return Sprintf("%" PRIu64 ":%" PRIu64, TraceId, SpanId);
+ }
+
+ bool IsFromSameTree(const TTraceId& other) const {
+ return TraceId == other.TraceId;
+ }
+
void Serialize(TSerializedTraceId* out) {
ui64* p = reinterpret_cast<ui64*>(*out);
- p[0] = TraceId;
- p[1] = SpanId;
- }
- };
-
+ p[0] = TraceId;
+ p[1] = SpanId;
+ }
+ };
+
}
diff --git a/library/cpp/actors/wilson/ya.make b/library/cpp/actors/wilson/ya.make
index e371f5061d5..036839c0da6 100644
--- a/library/cpp/actors/wilson/ya.make
+++ b/library/cpp/actors/wilson/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
PEERDIR(
library/cpp/string_utils/base64
@@ -11,4 +11,4 @@ SRCS(
wilson_trace.h
)
-END()
+END()
diff --git a/library/cpp/grpc/server/grpc_counters.h b/library/cpp/grpc/server/grpc_counters.h
index 0b6c36c84cc..9d2d53cf7e2 100644
--- a/library/cpp/grpc/server/grpc_counters.h
+++ b/library/cpp/grpc/server/grpc_counters.h
@@ -35,7 +35,7 @@ class TCounterBlock final : public ICounterBlock {
NMonitoring::TDynamicCounters::TCounterPtr ResponseBytes;
NMonitoring::TDynamicCounters::TCounterPtr NotAuthenticated;
NMonitoring::TDynamicCounters::TCounterPtr ResourceExhausted;
- bool Percentile = false;
+ bool Percentile = false;
NMonitoring::TPercentileTracker<4, 512, 15> RequestHistMs;
std::array<NMonitoring::TDynamicCounters::TCounterPtr, 2> GRpcStatusCounters;
@@ -46,10 +46,10 @@ public:
NMonitoring::TDynamicCounters::TCounterPtr notOkResponseCounter,
NMonitoring::TDynamicCounters::TCounterPtr requestBytes,
NMonitoring::TDynamicCounters::TCounterPtr inflyRequestBytes,
- NMonitoring::TDynamicCounters::TCounterPtr responseBytes,
+ NMonitoring::TDynamicCounters::TCounterPtr responseBytes,
NMonitoring::TDynamicCounters::TCounterPtr notAuthenticated,
NMonitoring::TDynamicCounters::TCounterPtr resourceExhausted,
- TIntrusivePtr<NMonitoring::TDynamicCounters> group)
+ TIntrusivePtr<NMonitoring::TDynamicCounters> group)
: TotalCounter(std::move(totalCounter))
, InflyCounter(std::move(inflyCounter))
, NotOkRequestCounter(std::move(notOkRequestCounter))
@@ -59,12 +59,12 @@ public:
, ResponseBytes(std::move(responseBytes))
, NotAuthenticated(std::move(notAuthenticated))
, ResourceExhausted(std::move(resourceExhausted))
- {
- if (group) {
- RequestHistMs.Initialize(group, "event", "request", "ms", {0.5f, 0.9f, 0.99f, 0.999f, 1.0f});
- Percentile = true;
- }
- }
+ {
+ if (group) {
+ RequestHistMs.Initialize(group, "event", "request", "ms", {0.5f, 0.9f, 0.99f, 0.999f, 1.0f});
+ Percentile = true;
+ }
+ }
void CountNotOkRequest() override {
NotOkRequestCounter->Inc();
@@ -108,20 +108,20 @@ public:
if (!ok) {
NotOkResponseCounter->Inc();
}
- if (Percentile) {
- RequestHistMs.Increment(requestDuration.MilliSeconds());
- }
+ if (Percentile) {
+ RequestHistMs.Increment(requestDuration.MilliSeconds());
+ }
}
-
+
ICounterBlockPtr Clone() override {
return this;
}
- void Update() {
- if (Percentile) {
- RequestHistMs.Update();
- }
- }
+ void Update() {
+ if (Percentile) {
+ RequestHistMs.Update();
+ }
+ }
};
using TCounterBlockPtr = TIntrusivePtr<TCounterBlock>;
diff --git a/library/cpp/grpc/server/grpc_request.h b/library/cpp/grpc/server/grpc_request.h
index 5bd8d3902b5..1cad232d9d8 100644
--- a/library/cpp/grpc/server/grpc_request.h
+++ b/library/cpp/grpc/server/grpc_request.h
@@ -367,7 +367,7 @@ private:
// Adjust counters.
RequestSize = Request_->ByteSize();
Counters_->StartProcessing(RequestSize);
- RequestTimer.Reset();
+ RequestTimer.Reset();
if (!SslServer()) {
Counters_->CountRequestWithoutTls();
@@ -499,7 +499,7 @@ private:
ui32 RequestSize = 0;
ui32 ResponseSize = 0;
ui32 ResponseStatus = 0;
- THPTimer RequestTimer;
+ THPTimer RequestTimer;
TAuthState AuthState_ = 0;
bool RequestRegistered_ = false;
diff --git a/library/cpp/grpc/server/grpc_server.cpp b/library/cpp/grpc/server/grpc_server.cpp
index 7437b7a8f5e..10ace01eb52 100644
--- a/library/cpp/grpc/server/grpc_server.cpp
+++ b/library/cpp/grpc/server/grpc_server.cpp
@@ -5,16 +5,16 @@
#include <util/system/thread.h>
#include <grpc++/resource_quota.h>
-#include <contrib/libs/grpc/src/core/lib/iomgr/socket_mutator.h>
-
-#if !defined(_WIN32) && !defined(_WIN64)
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#endif
-
+#include <contrib/libs/grpc/src/core/lib/iomgr/socket_mutator.h>
+
+#if !defined(_WIN32) && !defined(_WIN64)
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#endif
+
namespace NGrpc {
using NThreading::TFuture;
diff --git a/library/cpp/grpc/server/grpc_server.h b/library/cpp/grpc/server/grpc_server.h
index d6814a90a0d..5973d1de287 100644
--- a/library/cpp/grpc/server/grpc_server.h
+++ b/library/cpp/grpc/server/grpc_server.h
@@ -8,7 +8,7 @@
#include <util/generic/ptr.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
-#include <util/generic/maybe.h>
+#include <util/generic/maybe.h>
#include <util/generic/queue.h>
#include <util/generic/hash_set.h>
#include <util/system/types.h>
@@ -67,16 +67,16 @@ struct TServerOptions {
//! Use GRpc keepalive
DECLARE_FIELD(KeepAliveEnable, TMaybe<bool>, TMaybe<bool>());
-
+
//! GRPC_ARG_KEEPALIVE_TIME_MS setting
- DECLARE_FIELD(KeepAliveIdleTimeoutTriggerSec, int, 0);
-
+ DECLARE_FIELD(KeepAliveIdleTimeoutTriggerSec, int, 0);
+
//! Deprecated, ths option ignored. Will be removed soon.
- DECLARE_FIELD(KeepAliveMaxProbeCount, int, 0);
-
+ DECLARE_FIELD(KeepAliveMaxProbeCount, int, 0);
+
//! GRPC_ARG_KEEPALIVE_TIMEOUT_MS setting
- DECLARE_FIELD(KeepAliveProbeIntervalSec, int, 0);
-
+ DECLARE_FIELD(KeepAliveProbeIntervalSec, int, 0);
+
//! Max number of requests processing by services (global limit for grpc server)
DECLARE_FIELD(MaxGlobalRequestInFlight, size_t, 100000);
diff --git a/library/cpp/messagebus/oldmodule/module.h b/library/cpp/messagebus/oldmodule/module.h
index 8d1c4a5d52b..f6d10e1925d 100644
--- a/library/cpp/messagebus/oldmodule/module.h
+++ b/library/cpp/messagebus/oldmodule/module.h
@@ -71,8 +71,8 @@ namespace NBus {
TJobHandler(TBusHandlerPtr fptr = nullptr) {
MyPtr = fptr;
}
- TJobHandler(const TJobHandler&) = default;
- TJobHandler& operator =(const TJobHandler&) = default;
+ TJobHandler(const TJobHandler&) = default;
+ TJobHandler& operator =(const TJobHandler&) = default;
bool operator==(TJobHandler h) const {
return MyPtr == h.MyPtr;
}
diff --git a/library/cpp/monlib/dynamic_counters/contention_ut.cpp b/library/cpp/monlib/dynamic_counters/contention_ut.cpp
index 8798044ee3c..eac30069a6c 100644
--- a/library/cpp/monlib/dynamic_counters/contention_ut.cpp
+++ b/library/cpp/monlib/dynamic_counters/contention_ut.cpp
@@ -1,61 +1,61 @@
-#include "counters.h"
+#include "counters.h"
#include <library/cpp/testing/unittest/registar.h>
-#include <util/system/event.h>
-#include <util/system/thread.h>
-
-using namespace NMonitoring;
-
-Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) {
-
- Y_UNIT_TEST(EnsureNonlocking) {
- TDynamicCounterPtr counters = MakeIntrusive<TDynamicCounters>();
-
- class TConsumer : public ICountableConsumer {
- TAutoEvent Ev;
- TAutoEvent Response;
- TDynamicCounterPtr Counters;
- TThread Thread;
-
- public:
- TConsumer(TDynamicCounterPtr counters)
- : Counters(counters)
- , Thread(std::bind(&TConsumer::ThreadFunc, this))
- {
- Thread.Start();
- }
-
+#include <util/system/event.h>
+#include <util/system/thread.h>
+
+using namespace NMonitoring;
+
+Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) {
+
+ Y_UNIT_TEST(EnsureNonlocking) {
+ TDynamicCounterPtr counters = MakeIntrusive<TDynamicCounters>();
+
+ class TConsumer : public ICountableConsumer {
+ TAutoEvent Ev;
+ TAutoEvent Response;
+ TDynamicCounterPtr Counters;
+ TThread Thread;
+
+ public:
+ TConsumer(TDynamicCounterPtr counters)
+ : Counters(counters)
+ , Thread(std::bind(&TConsumer::ThreadFunc, this))
+ {
+ Thread.Start();
+ }
+
~TConsumer() override {
- Thread.Join();
- }
-
+ Thread.Join();
+ }
+
void OnCounter(const TString& /*labelName*/, const TString& /*labelValue*/, const TCounterForPtr* /*counter*/) override {
- Ev.Signal();
- Response.Wait();
- }
-
+ Ev.Signal();
+ Response.Wait();
+ }
+
void OnHistogram(const TString& /*labelName*/, const TString& /*labelValue*/, IHistogramSnapshotPtr /*snapshot*/, bool /*derivative*/) override {
- }
-
+ }
+
void OnGroupBegin(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override {
- }
-
+ }
+
void OnGroupEnd(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override {
- }
-
- private:
- void ThreadFunc() {
- // acts like a coroutine
- Ev.Wait();
- auto ctr = Counters->GetSubgroup("label", "value")->GetCounter("name");
- Y_VERIFY(*ctr == 42);
- Response.Signal();
- }
- };
-
- auto ctr = counters->GetSubgroup("label", "value")->GetCounter("name");
- *ctr = 42;
- TConsumer consumer(counters);
- counters->Accept({}, {}, consumer);
- }
-
-}
+ }
+
+ private:
+ void ThreadFunc() {
+ // acts like a coroutine
+ Ev.Wait();
+ auto ctr = Counters->GetSubgroup("label", "value")->GetCounter("name");
+ Y_VERIFY(*ctr == 42);
+ Response.Signal();
+ }
+ };
+
+ auto ctr = counters->GetSubgroup("label", "value")->GetCounter("name");
+ *ctr = 42;
+ TConsumer consumer(counters);
+ counters->Accept({}, {}, consumer);
+ }
+
+}
diff --git a/library/cpp/monlib/dynamic_counters/counters.cpp b/library/cpp/monlib/dynamic_counters/counters.cpp
index 3635d87d0d2..04003d28a56 100644
--- a/library/cpp/monlib/dynamic_counters/counters.cpp
+++ b/library/cpp/monlib/dynamic_counters/counters.cpp
@@ -107,66 +107,66 @@ void TDynamicCounters::RemoveCounter(const TString &value) {
}
void TDynamicCounters::RemoveNamedCounter(const TString& name, const TString &value) {
- auto g = LockForUpdate("RemoveNamedCounter", name, value);
- if (const auto it = Counters.find({name, value}); it != Counters.end() && AsCounter(it->second)) {
+ auto g = LockForUpdate("RemoveNamedCounter", name, value);
+ if (const auto it = Counters.find({name, value}); it != Counters.end() && AsCounter(it->second)) {
Counters.erase(it);
}
}
TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& name, const TString& value) {
- auto res = FindSubgroup(name, value);
- if (!res) {
- auto g = LockForUpdate("GetSubgroup", name, value);
- const TChildId key(name, value);
- if (const auto it = Counters.lower_bound(key); it != Counters.end() && it->first == key) {
- res = AsGroupRef(it->second);
- } else {
- res = MakeIntrusive<TDynamicCounters>(this);
- Counters.emplace_hint(it, key, res);
- }
+ auto res = FindSubgroup(name, value);
+ if (!res) {
+ auto g = LockForUpdate("GetSubgroup", name, value);
+ const TChildId key(name, value);
+ if (const auto it = Counters.lower_bound(key); it != Counters.end() && it->first == key) {
+ res = AsGroupRef(it->second);
+ } else {
+ res = MakeIntrusive<TDynamicCounters>(this);
+ Counters.emplace_hint(it, key, res);
+ }
}
- return res;
+ return res;
}
TIntrusivePtr<TDynamicCounters> TDynamicCounters::FindSubgroup(const TString& name, const TString& value) const {
- TReadGuard g(Lock);
- const auto it = Counters.find({name, value});
- return it != Counters.end() ? AsDynamicCounters(it->second) : nullptr;
+ TReadGuard g(Lock);
+ const auto it = Counters.find({name, value});
+ return it != Counters.end() ? AsDynamicCounters(it->second) : nullptr;
}
void TDynamicCounters::RemoveSubgroup(const TString& name, const TString& value) {
- auto g = LockForUpdate("RemoveSubgroup", name, value);
- if (const auto it = Counters.find({name, value}); it != Counters.end() && AsDynamicCounters(it->second)) {
+ auto g = LockForUpdate("RemoveSubgroup", name, value);
+ if (const auto it = Counters.find({name, value}); it != Counters.end() && AsDynamicCounters(it->second)) {
Counters.erase(it);
}
}
-void TDynamicCounters::ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) {
- auto g = LockForUpdate("ReplaceSubgroup", name, value);
- const auto it = Counters.find({name, value});
- Y_VERIFY(it != Counters.end() && AsDynamicCounters(it->second));
- it->second = std::move(subgroup);
+void TDynamicCounters::ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) {
+ auto g = LockForUpdate("ReplaceSubgroup", name, value);
+ const auto it = Counters.find({name, value});
+ Y_VERIFY(it != Counters.end() && AsDynamicCounters(it->second));
+ it->second = std::move(subgroup);
}
void TDynamicCounters::MergeWithSubgroup(const TString& name, const TString& value) {
- auto g = LockForUpdate("MergeWithSubgroup", name, value);
- auto it = Counters.find({name, value});
- Y_VERIFY(it != Counters.end());
- TIntrusivePtr<TDynamicCounters> subgroup = AsDynamicCounters(it->second);
+ auto g = LockForUpdate("MergeWithSubgroup", name, value);
+ auto it = Counters.find({name, value});
+ Y_VERIFY(it != Counters.end());
+ TIntrusivePtr<TDynamicCounters> subgroup = AsDynamicCounters(it->second);
Y_VERIFY(subgroup);
- Counters.erase(it);
- Counters.merge(subgroup->Resign());
- AtomicAdd(ExpiringCount, AtomicSwap(&subgroup->ExpiringCount, 0));
+ Counters.erase(it);
+ Counters.merge(subgroup->Resign());
+ AtomicAdd(ExpiringCount, AtomicSwap(&subgroup->ExpiringCount, 0));
}
void TDynamicCounters::ResetCounters(bool derivOnly) {
- TReadGuard g(Lock);
- for (auto& [key, value] : Counters) {
- if (auto counter = AsCounter(value)) {
- if (!derivOnly || counter->ForDerivative()) {
+ TReadGuard g(Lock);
+ for (auto& [key, value] : Counters) {
+ if (auto counter = AsCounter(value)) {
+ if (!derivOnly || counter->ForDerivative()) {
*counter = 0;
- }
- } else if (auto subgroup = AsDynamicCounters(value)) {
+ }
+ } else if (auto subgroup = AsDynamicCounters(value)) {
subgroup->ResetCounters(derivOnly);
}
}
@@ -174,9 +174,9 @@ void TDynamicCounters::ResetCounters(bool derivOnly) {
void TDynamicCounters::RegisterCountable(const TString& name, const TString& value, TCountablePtr countable) {
Y_VERIFY(countable);
- auto g = LockForUpdate("RegisterCountable", name, value);
- const bool inserted = Counters.emplace(TChildId(name, value), std::move(countable)).second;
- Y_VERIFY(inserted);
+ auto g = LockForUpdate("RegisterCountable", name, value);
+ const bool inserted = Counters.emplace(TChildId(name, value), std::move(countable)).second;
+ Y_VERIFY(inserted);
}
void TDynamicCounters::RegisterSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup) {
@@ -192,31 +192,31 @@ void TDynamicCounters::OutputHtml(IOutputStream& os) const {
}
void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const {
- TReadGuard g(Lock);
- for (const auto& [key, value] : Counters) {
- if (AsDynamicCounters(value)) {
- output(key.LabelName, key.LabelValue);
- }
- }
+ TReadGuard g(Lock);
+ for (const auto& [key, value] : Counters) {
+ if (AsDynamicCounters(value)) {
+ output(key.LabelName, key.LabelValue);
+ }
+ }
}
void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) const {
- auto snap = ReadSnapshot();
+ auto snap = ReadSnapshot();
// mark private records in plain text output
auto outputVisibilityMarker = [] (EVisibility vis) {
return vis == EVisibility::Private ? "\t[PRIVATE]" : "";
};
- for (const auto& [key, value] : snap) {
- if (const auto counter = AsCounter(value)) {
+ for (const auto& [key, value] : snap) {
+ if (const auto counter = AsCounter(value)) {
os << indent
- << key.LabelName << '=' << key.LabelValue
+ << key.LabelName << '=' << key.LabelValue
<< ": " << counter->Val()
<< outputVisibilityMarker(counter->Visibility())
<< '\n';
- } else if (const auto histogram = AsHistogram(value)) {
+ } else if (const auto histogram = AsHistogram(value)) {
os << indent
- << key.LabelName << '=' << key.LabelValue
+ << key.LabelName << '=' << key.LabelValue
<< ":"
<< outputVisibilityMarker(histogram->Visibility())
<< "\n";
@@ -235,10 +235,10 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent)
}
}
- for (const auto& [key, value] : snap) {
- if (const auto subgroup = AsDynamicCounters(value)) {
+ for (const auto& [key, value] : snap) {
+ if (const auto subgroup = AsDynamicCounters(value)) {
os << "\n";
- os << indent << key.LabelName << "=" << key.LabelValue << ":\n";
+ os << indent << key.LabelName << "=" << key.LabelValue << ":\n";
subgroup->OutputPlainText(os, indent + INDENT);
}
}
@@ -250,50 +250,50 @@ void TDynamicCounters::Accept(const TString& labelName, const TString& labelValu
}
consumer.OnGroupBegin(labelName, labelValue, this);
- for (auto& [key, value] : ReadSnapshot()) {
- value->Accept(key.LabelName, key.LabelValue, consumer);
+ for (auto& [key, value] : ReadSnapshot()) {
+ value->Accept(key.LabelName, key.LabelValue, consumer);
}
consumer.OnGroupEnd(labelName, labelValue, this);
}
void TDynamicCounters::RemoveExpired() const {
- if (AtomicGet(ExpiringCount) == 0) {
+ if (AtomicGet(ExpiringCount) == 0) {
return;
}
- TWriteGuard g(Lock);
- TAtomicBase count = 0;
-
+ TWriteGuard g(Lock);
+ TAtomicBase count = 0;
+
for (auto it = Counters.begin(); it != Counters.end();) {
if (IsExpiringCounter(it->second) && it->second->RefCount() == 1) {
it = Counters.erase(it);
- ++count;
+ ++count;
} else {
++it;
}
}
-
- AtomicSub(ExpiringCount, count);
+
+ AtomicSub(ExpiringCount, count);
}
template <bool expiring, class TCounterType, class... TArgs>
TDynamicCounters::TCountablePtr TDynamicCounters::GetNamedCounterImpl(const TString& name, const TString& value, TArgs&&... args) {
- {
- TReadGuard g(Lock);
- auto it = Counters.find({name, value});
- if (it != Counters.end()) {
- return it->second;
- }
+ {
+ TReadGuard g(Lock);
+ auto it = Counters.find({name, value});
+ if (it != Counters.end()) {
+ return it->second;
+ }
}
- auto g = LockForUpdate("GetNamedCounterImpl", name, value);
- const TChildId key(name, value);
- auto it = Counters.lower_bound(key);
- if (it == Counters.end() || it->first != key) {
- auto value = MakeIntrusive<TCounterType>(std::forward<TArgs>(args)...);
- it = Counters.emplace_hint(it, key, value);
+ auto g = LockForUpdate("GetNamedCounterImpl", name, value);
+ const TChildId key(name, value);
+ auto it = Counters.lower_bound(key);
+ if (it == Counters.end() || it->first != key) {
+ auto value = MakeIntrusive<TCounterType>(std::forward<TArgs>(args)...);
+ it = Counters.emplace_hint(it, key, value);
if constexpr (expiring) {
- AtomicIncrement(ExpiringCount);
+ AtomicIncrement(ExpiringCount);
}
}
return it->second;
diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h
index dc178cfbe01..7f9b7766455 100644
--- a/library/cpp/monlib/dynamic_counters/counters.h
+++ b/library/cpp/monlib/dynamic_counters/counters.h
@@ -5,12 +5,12 @@
#include <library/cpp/threading/light_rw_lock/lightrwlock.h>
#include <library/cpp/containers/stack_vector/stack_vec.h>
-
+
#include <util/generic/cast.h>
#include <util/generic/map.h>
#include <util/generic/ptr.h>
#include <util/string/cast.h>
-#include <util/system/rwlock.h>
+#include <util/system/rwlock.h>
#include <functional>
@@ -194,7 +194,7 @@ namespace NMonitoring {
using TOnLookupPtr = void (*)(const char *methodName, const TString &name, const TString &value);
private:
- TRWMutex Lock;
+ TRWMutex Lock;
TCounterPtr LookupCounter; // Counts lookups by name
TOnLookupPtr OnLookup = nullptr; // Called on each lookup if not nullptr, intended for lightweight tracing.
@@ -210,66 +210,66 @@ namespace NMonitoring {
, LabelValue(labelValue)
{
}
- auto AsTuple() const {
- return std::make_tuple(std::cref(LabelName), std::cref(LabelValue));
- }
- friend bool operator <(const TChildId& x, const TChildId& y) {
- return x.AsTuple() < y.AsTuple();
- }
- friend bool operator ==(const TChildId& x, const TChildId& y) {
- return x.AsTuple() == y.AsTuple();
- }
- friend bool operator !=(const TChildId& x, const TChildId& y) {
- return x.AsTuple() != y.AsTuple();
+ auto AsTuple() const {
+ return std::make_tuple(std::cref(LabelName), std::cref(LabelValue));
}
+ friend bool operator <(const TChildId& x, const TChildId& y) {
+ return x.AsTuple() < y.AsTuple();
+ }
+ friend bool operator ==(const TChildId& x, const TChildId& y) {
+ return x.AsTuple() == y.AsTuple();
+ }
+ friend bool operator !=(const TChildId& x, const TChildId& y) {
+ return x.AsTuple() != y.AsTuple();
+ }
};
- using TCounters = TMap<TChildId, TCountablePtr>;
+ using TCounters = TMap<TChildId, TCountablePtr>;
using TLabels = TVector<TChildId>;
/// XXX: hack for deferred removal of expired counters. Remove once Output* functions are not used for serialization
mutable TCounters Counters;
- mutable TAtomic ExpiringCount = 0;
+ mutable TAtomic ExpiringCount = 0;
public:
TDynamicCounters(TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
-
- TDynamicCounters(const TDynamicCounters *origin)
- : LookupCounter(origin->LookupCounter)
- , OnLookup(origin->OnLookup)
- {}
-
+
+ TDynamicCounters(const TDynamicCounters *origin)
+ : LookupCounter(origin->LookupCounter)
+ , OnLookup(origin->OnLookup)
+ {}
+
~TDynamicCounters() override;
// This counter allows to track lookups by name within the whole subtree
void SetLookupCounter(TCounterPtr lookupCounter) {
- TWriteGuard g(Lock);
+ TWriteGuard g(Lock);
LookupCounter = lookupCounter;
}
void SetOnLookup(TOnLookupPtr onLookup) {
- TWriteGuard g(Lock);
+ TWriteGuard g(Lock);
OnLookup = onLookup;
}
- TWriteGuard LockForUpdate(const char *method, const TString& name, const TString& value) {
- auto res = TWriteGuard(Lock);
- if (LookupCounter) {
- ++*LookupCounter;
- }
- if (OnLookup) {
- OnLookup(method, name, value);
- }
- return res;
- }
-
- TStackVec<TCounters::value_type, 256> ReadSnapshot() const {
- RemoveExpired();
- TReadGuard g(Lock);
- TStackVec<TCounters::value_type, 256> items(Counters.begin(), Counters.end());
- return items;
- }
-
+ TWriteGuard LockForUpdate(const char *method, const TString& name, const TString& value) {
+ auto res = TWriteGuard(Lock);
+ if (LookupCounter) {
+ ++*LookupCounter;
+ }
+ if (OnLookup) {
+ OnLookup(method, name, value);
+ }
+ return res;
+ }
+
+ TStackVec<TCounters::value_type, 256> ReadSnapshot() const {
+ RemoveExpired();
+ TReadGuard g(Lock);
+ TStackVec<TCounters::value_type, 256> items(Counters.begin(), Counters.end());
+ return items;
+ }
+
TCounterPtr GetCounter(
const TString& value,
bool derivative = false,
@@ -354,13 +354,13 @@ namespace NMonitoring {
ICountableConsumer& consumer) const override;
private:
- TCounters Resign() {
- TCounters counters;
- TWriteGuard g(Lock);
- Counters.swap(counters);
- return counters;
- }
-
+ TCounters Resign() {
+ TCounters counters;
+ TWriteGuard g(Lock);
+ Counters.swap(counters);
+ return counters;
+ }
+
void RegisterCountable(const TString& name, const TString& value, TCountablePtr countable);
void RemoveExpired() const;
diff --git a/library/cpp/monlib/dynamic_counters/ut/ya.make b/library/cpp/monlib/dynamic_counters/ut/ya.make
index 8242f2fe307..a334ef87dd2 100644
--- a/library/cpp/monlib/dynamic_counters/ut/ya.make
+++ b/library/cpp/monlib/dynamic_counters/ut/ya.make
@@ -3,7 +3,7 @@ UNITTEST_FOR(library/cpp/monlib/dynamic_counters)
OWNER(jamel)
SRCS(
- contention_ut.cpp
+ contention_ut.cpp
counters_ut.cpp
encode_ut.cpp
)
diff --git a/util/generic/bitmap.h b/util/generic/bitmap.h
index f77d1824607..adddfc67f5a 100644
--- a/util/generic/bitmap.h
+++ b/util/generic/bitmap.h
@@ -402,16 +402,16 @@ private:
const size_t endChunk = end >> DivCount;
const size_t endBitOffset = end & ModMask;
- size_t bitOffset = startBitOffset;
- for (size_t chunk = startChunk; chunk <= endChunk; ++chunk) {
- TChunk updateMask = FullChunk << bitOffset;
- if (chunk == endChunk) {
- updateMask ^= FullChunk << endBitOffset;
- if (!updateMask)
- break;
+ size_t bitOffset = startBitOffset;
+ for (size_t chunk = startChunk; chunk <= endChunk; ++chunk) {
+ TChunk updateMask = FullChunk << bitOffset;
+ if (chunk == endChunk) {
+ updateMask ^= FullChunk << endBitOffset;
+ if (!updateMask)
+ break;
}
- Mask.Data[chunk] = TUpdateOp::Op(Mask.Data[chunk], updateMask);
- bitOffset = 0;
+ Mask.Data[chunk] = TUpdateOp::Op(Mask.Data[chunk], updateMask);
+ bitOffset = 0;
}
}
diff --git a/util/generic/bitmap_ut.cpp b/util/generic/bitmap_ut.cpp
index 087d34a8dcc..eda5ff256f8 100644
--- a/util/generic/bitmap_ut.cpp
+++ b/util/generic/bitmap_ut.cpp
@@ -571,19 +571,19 @@ Y_UNIT_TEST_SUITE(TBitMapTest) {
UNIT_ASSERT_EQUAL(TBitMap4Chunks().Flip().Reset(50, 64), TBitMap4Chunks().Set(0, 50));
UNIT_ASSERT_EQUAL(TBitMap4Chunks().Flip().Reset(0, 10).Reset(50, 64), TBitMap4Chunks().Set(10, 50));
}
-
+
Y_UNIT_TEST(TestSetRangeDyn) {
- for (size_t start = 0; start < 192; ++start) {
- for (size_t end = start; end < 192; ++end) {
- TDynBitMap bm;
- bm.Reserve(192);
- bm.Set(start, end);
- for (size_t k = 0; k < 192; ++k) {
- UNIT_ASSERT_VALUES_EQUAL(bm.Get(k), k >= start && k < end ? 1 : 0);
- }
- }
- }
- }
+ for (size_t start = 0; start < 192; ++start) {
+ for (size_t end = start; end < 192; ++end) {
+ TDynBitMap bm;
+ bm.Reserve(192);
+ bm.Set(start, end);
+ for (size_t k = 0; k < 192; ++k) {
+ UNIT_ASSERT_VALUES_EQUAL(bm.Get(k), k >= start && k < end ? 1 : 0);
+ }
+ }
+ }
+ }
Y_UNIT_TEST(TestResetLargeRangeDyn) {
TDynBitMap bm;
diff --git a/util/generic/ptr.h b/util/generic/ptr.h
index 19db0e3ec55..c5b6c594f59 100644
--- a/util/generic/ptr.h
+++ b/util/generic/ptr.h
@@ -104,9 +104,9 @@ public:
using TValueType = T;
inline T* operator->() const noexcept {
- T* ptr = AsT();
- Y_ASSERT(ptr);
- return ptr;
+ T* ptr = AsT();
+ Y_ASSERT(ptr);
+ return ptr;
}
#ifndef __cpp_impl_three_way_comparison
diff --git a/ydb/core/actorlib_impl/actor_bootstrapped_ut.cpp b/ydb/core/actorlib_impl/actor_bootstrapped_ut.cpp
index 990330b321b..47ed3b8a5e8 100644
--- a/ydb/core/actorlib_impl/actor_bootstrapped_ut.cpp
+++ b/ydb/core/actorlib_impl/actor_bootstrapped_ut.cpp
@@ -2,55 +2,55 @@
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/testlib/basics/runtime.h>
#include <ydb/core/testlib/basics/appdata.h>
-
-using namespace NActors;
-
+
+using namespace NActors;
+
Y_UNIT_TEST_SUITE(ActorBootstrapped) {
- class TTestBoostrapped: public TActorBootstrapped<TTestBoostrapped>
- {
- public:
+ class TTestBoostrapped: public TActorBootstrapped<TTestBoostrapped>
+ {
+ public:
TTestBoostrapped(const TActorId& edge)
- : Edge(edge)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- ctx.Send(Edge, new TEvents::TEvWakeup);
- }
-
+ : Edge(edge)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ ctx.Send(Edge, new TEvents::TEvWakeup);
+ }
+
TActorId Edge;
- };
-
+ };
+
class TTestBoostrappedParent: public TActorBootstrapped<TTestBoostrappedParent>
- {
- public:
+ {
+ public:
TTestBoostrappedParent(const TActorId& edge)
- : Edge(edge)
- {}
-
+ : Edge(edge)
+ {}
+
void Bootstrap(const TActorId&, const TActorContext& ctx) {
- ctx.Send(Edge, new TEvents::TEvWakeup);
- }
-
+ ctx.Send(Edge, new TEvents::TEvWakeup);
+ }
+
TActorId Edge;
- };
-
- template <typename TDerivedActor>
- void TestBootrappedActor() {
- TTestActorRuntime runtime;
+ };
+
+ template <typename TDerivedActor>
+ void TestBootrappedActor() {
+ TTestActorRuntime runtime;
runtime.Initialize(NKikimr::TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- auto actor = new TDerivedActor(edge);
- runtime.Register(actor);
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
- }
-
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ auto actor = new TDerivedActor(edge);
+ runtime.Register(actor);
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
+ }
+
+
Y_UNIT_TEST(TestBootstrapped) {
- TestBootrappedActor<TTestBoostrapped>();
- }
-
+ TestBootrappedActor<TTestBoostrapped>();
+ }
+
Y_UNIT_TEST(TestBootstrappedParent) {
- TestBootrappedActor<TTestBoostrappedParent>();
- }
-}
+ TestBootrappedActor<TTestBoostrappedParent>();
+ }
+}
diff --git a/ydb/core/actorlib_impl/actor_tracker.cpp b/ydb/core/actorlib_impl/actor_tracker.cpp
index 99787dfce19..618c7cce993 100644
--- a/ydb/core/actorlib_impl/actor_tracker.cpp
+++ b/ydb/core/actorlib_impl/actor_tracker.cpp
@@ -1,198 +1,198 @@
-#include "actor_tracker.h"
+#include "actor_tracker.h"
#include <library/cpp/actors/core/executor_thread.h>
#include <library/cpp/actors/core/hfunc.h>
-
-namespace NActors {
-
- static constexpr TAtomicBase StopBit = TAtomicBase(1) << (sizeof(TAtomicBase) * CHAR_BIT - 1);
-
- void TActorTracker::BindToActor(const TActorContext& ctx) {
- ActorId = ctx.SelfID;
- }
-
- void TActorTracker::Handle(TEvTrackActor::TPtr& ev, const TActorContext& ctx) {
- // insert newly created actor into registered actors set and ensure it is not duplicate one
+
+namespace NActors {
+
+ static constexpr TAtomicBase StopBit = TAtomicBase(1) << (sizeof(TAtomicBase) * CHAR_BIT - 1);
+
+ void TActorTracker::BindToActor(const TActorContext& ctx) {
+ ActorId = ctx.SelfID;
+ }
+
+ void TActorTracker::Handle(TEvTrackActor::TPtr& ev, const TActorContext& ctx) {
+ // insert newly created actor into registered actors set and ensure it is not duplicate one
const TActorId& newSubactorId = ev->Get()->NewSubactorId;
- const bool inserted = RegisteredActors.insert(newSubactorId).second;
- Y_VERIFY(inserted);
-
- // check if we are not dying now; we can do this in non-atomic way, because this bit can be set only in
- // PoisonPill handler and this can'be done concurrently
- TAtomicBase status = AtomicDecrement(NumInFlightTracks);
- if (status & StopBit) {
- // we're stopping, so we have to issue TEvPoisonPill for newly created actor; we do it in safe manner --
- // request tracking, because that actor might die before processing this message
- ctx.Send(newSubactorId, new TEvents::TEvPoisonPill, IEventHandle::MakeFlags(0, IEventHandle::FlagTrackDelivery));
- }
- }
-
- void TActorTracker::Handle(TEvUntrackActor::TPtr& ev, const TActorContext& ctx) {
- // just remove actor from the list and do nothing more
- RemoveActorFromTrackList(ev->Sender, ctx);
- }
-
- void TActorTracker::Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
- // ensure we haven't received PoisonPill yet, then remember the id of actor who requested the poison
- Y_VERIFY(!KillerActorId);
- KillerActorId = ev->Sender;
-
- // set StopBit in thread-safe manner
- TAtomicBase newValue = AtomicAdd(NumInFlightTracks, StopBit);
- Y_VERIFY(newValue & StopBit);
-
- // propagate TEvPoisonPill to all currently registered actors; request delivery tracking as each actor may die
- // before processing TEvPosionPill message
+ const bool inserted = RegisteredActors.insert(newSubactorId).second;
+ Y_VERIFY(inserted);
+
+ // check if we are not dying now; we can do this in non-atomic way, because this bit can be set only in
+ // PoisonPill handler and this can'be done concurrently
+ TAtomicBase status = AtomicDecrement(NumInFlightTracks);
+ if (status & StopBit) {
+ // we're stopping, so we have to issue TEvPoisonPill for newly created actor; we do it in safe manner --
+ // request tracking, because that actor might die before processing this message
+ ctx.Send(newSubactorId, new TEvents::TEvPoisonPill, IEventHandle::MakeFlags(0, IEventHandle::FlagTrackDelivery));
+ }
+ }
+
+ void TActorTracker::Handle(TEvUntrackActor::TPtr& ev, const TActorContext& ctx) {
+ // just remove actor from the list and do nothing more
+ RemoveActorFromTrackList(ev->Sender, ctx);
+ }
+
+ void TActorTracker::Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
+ // ensure we haven't received PoisonPill yet, then remember the id of actor who requested the poison
+ Y_VERIFY(!KillerActorId);
+ KillerActorId = ev->Sender;
+
+ // set StopBit in thread-safe manner
+ TAtomicBase newValue = AtomicAdd(NumInFlightTracks, StopBit);
+ Y_VERIFY(newValue & StopBit);
+
+ // propagate TEvPoisonPill to all currently registered actors; request delivery tracking as each actor may die
+ // before processing TEvPosionPill message
for (const TActorId& subactorId : RegisteredActors) {
- ctx.Send(subactorId, new TEvents::TEvPoisonPill, IEventHandle::MakeFlags(0, IEventHandle::FlagTrackDelivery));
- }
-
- // check if we can respond to killer
- CheckIfPoisonPillDone(ctx);
- }
-
- void TActorTracker::Handle(TEvents::TEvPoisonTaken::TPtr& ev, const TActorContext& ctx) {
- // we have received response from child actor to TEvPoisonPill -- remove actor from list and check if the
- // TEvPoisonPill processing done
- RemoveActorFromTrackList(ev->Sender, ctx);
- }
-
+ ctx.Send(subactorId, new TEvents::TEvPoisonPill, IEventHandle::MakeFlags(0, IEventHandle::FlagTrackDelivery));
+ }
+
+ // check if we can respond to killer
+ CheckIfPoisonPillDone(ctx);
+ }
+
+ void TActorTracker::Handle(TEvents::TEvPoisonTaken::TPtr& ev, const TActorContext& ctx) {
+ // we have received response from child actor to TEvPoisonPill -- remove actor from list and check if the
+ // TEvPoisonPill processing done
+ RemoveActorFromTrackList(ev->Sender, ctx);
+ }
+
void TActorTracker::RemoveActorFromTrackList(const TActorId& subactorId, const TActorContext& ctx) {
- // erase subactor from set and check if we have finished processing PoisonPill (if we are processing it)
- const ui32 numErased = RegisteredActors.erase(subactorId);
- Y_VERIFY(numErased == 1);
- if (KillerActorId) {
- CheckIfPoisonPillDone(ctx);
- }
- }
-
- void TActorTracker::CheckIfPoisonPillDone(const TActorContext& ctx) {
- // ensure we have killing actor
- Y_VERIFY(KillerActorId);
-
- // ensure we have stop bit set
- TAtomicBase currentValue = AtomicGet(NumInFlightTracks);
- Y_VERIFY(currentValue & StopBit);
-
- // check if we have no more registered actors left and no more TEvTrackActor queries in flight -- in this case
- // we have finished processing the query; send TEvPoisonTaken message and Die
- if (currentValue == StopBit && RegisteredActors.empty()) {
- ctx.Send(KillerActorId, new TEvents::TEvPoisonTaken);
- ctx.ExecutorThread.UnregisterActor(&ctx.Mailbox, ctx.SelfID.LocalId());
- }
- }
-
- bool TActorTracker::HandleTracking(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvTrackActor, Handle);
- HFunc(TEvUntrackActor, Handle);
- HFunc(TEvents::TEvPoisonPill, Handle);
- HFunc(TEvents::TEvPoisonTaken, Handle);
-
- default:
- return false;
- }
-
- return true;
- }
-
- bool TActorTracker::PreRegister() {
- // check if we are stopping; in this case we return false meaning that no actor should be registered and the new
- // actor is simply destroyed
- TAtomicBase currentValue, newValue;
- do {
- currentValue = AtomicGet(NumInFlightTracks);
- if (currentValue & StopBit) {
- return false; // no actor going to be registered -- we're dying; good reaction is to call Die() too in caller code
- }
- newValue = currentValue + 1; // simply add one to current in flight TEvTrackActor message count
- } while (!AtomicCas(&NumInFlightTracks, newValue, currentValue));
-
- return true;
- }
-
+ // erase subactor from set and check if we have finished processing PoisonPill (if we are processing it)
+ const ui32 numErased = RegisteredActors.erase(subactorId);
+ Y_VERIFY(numErased == 1);
+ if (KillerActorId) {
+ CheckIfPoisonPillDone(ctx);
+ }
+ }
+
+ void TActorTracker::CheckIfPoisonPillDone(const TActorContext& ctx) {
+ // ensure we have killing actor
+ Y_VERIFY(KillerActorId);
+
+ // ensure we have stop bit set
+ TAtomicBase currentValue = AtomicGet(NumInFlightTracks);
+ Y_VERIFY(currentValue & StopBit);
+
+ // check if we have no more registered actors left and no more TEvTrackActor queries in flight -- in this case
+ // we have finished processing the query; send TEvPoisonTaken message and Die
+ if (currentValue == StopBit && RegisteredActors.empty()) {
+ ctx.Send(KillerActorId, new TEvents::TEvPoisonTaken);
+ ctx.ExecutorThread.UnregisterActor(&ctx.Mailbox, ctx.SelfID.LocalId());
+ }
+ }
+
+ bool TActorTracker::HandleTracking(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvTrackActor, Handle);
+ HFunc(TEvUntrackActor, Handle);
+ HFunc(TEvents::TEvPoisonPill, Handle);
+ HFunc(TEvents::TEvPoisonTaken, Handle);
+
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ bool TActorTracker::PreRegister() {
+ // check if we are stopping; in this case we return false meaning that no actor should be registered and the new
+ // actor is simply destroyed
+ TAtomicBase currentValue, newValue;
+ do {
+ currentValue = AtomicGet(NumInFlightTracks);
+ if (currentValue & StopBit) {
+ return false; // no actor going to be registered -- we're dying; good reaction is to call Die() too in caller code
+ }
+ newValue = currentValue + 1; // simply add one to current in flight TEvTrackActor message count
+ } while (!AtomicCas(&NumInFlightTracks, newValue, currentValue));
+
+ return true;
+ }
+
TActorId TActorTracker::RegisterSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx,
- TMailboxType::EType mailboxType, ui32 poolId) {
- if (!PreRegister()) {
+ TMailboxType::EType mailboxType, ui32 poolId) {
+ if (!PreRegister()) {
return TActorId();
- }
-
- // bind new actor to this tracker
- subactor->BindToTracker(this);
-
- // we create new actor and register it in pool now
+ }
+
+ // bind new actor to this tracker
+ subactor->BindToTracker(this);
+
+ // we create new actor and register it in pool now
TActorId subactorId = ctx.Register(subactor.Release(), mailboxType, poolId);
-
- // send TEvTrackActor message to tracker actor
- ctx.Send(ActorId, new TEvTrackActor(subactorId));
-
- return subactorId;
- }
-
+
+ // send TEvTrackActor message to tracker actor
+ ctx.Send(ActorId, new TEvTrackActor(subactorId));
+
+ return subactorId;
+ }
+
TActorId TActorTracker::RegisterLocalSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx) {
- if (!PreRegister()) {
+ if (!PreRegister()) {
return TActorId();
- }
-
- // bind new actor to this tracker
- subactor->BindToTracker(this);
-
- // we create new actor and register it in local pool
+ }
+
+ // bind new actor to this tracker
+ subactor->BindToTracker(this);
+
+ // we create new actor and register it in local pool
TActorId subactorId = ctx.RegisterWithSameMailbox(subactor.Release());
-
- // send TEvTrackActor message to tracker actor
- Y_VERIFY(ActorId);
- ctx.Send(ActorId, new TEvTrackActor(subactorId));
-
- return subactorId;
- }
-
- void TActorTracker::SendUntrack(const TActorContext& ctx) {
- Y_VERIFY(ActorId);
- ctx.Send(ActorId, new TEvUntrackActor);
- }
-
-
-
+
+ // send TEvTrackActor message to tracker actor
+ Y_VERIFY(ActorId);
+ ctx.Send(ActorId, new TEvTrackActor(subactorId));
+
+ return subactorId;
+ }
+
+ void TActorTracker::SendUntrack(const TActorContext& ctx) {
+ Y_VERIFY(ActorId);
+ ctx.Send(ActorId, new TEvUntrackActor);
+ }
+
+
+
TActorId TTrackedActorBase::RegisterSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx,
- TMailboxType::EType mailboxType, ui32 poolId) {
- Y_VERIFY(Tracker);
- return Tracker->RegisterSubactor(std::move(subactor), ctx, mailboxType, poolId);
- }
-
+ TMailboxType::EType mailboxType, ui32 poolId) {
+ Y_VERIFY(Tracker);
+ return Tracker->RegisterSubactor(std::move(subactor), ctx, mailboxType, poolId);
+ }
+
TActorId TTrackedActorBase::RegisterLocalSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx) {
- Y_VERIFY(Tracker);
- return Tracker->RegisterLocalSubactor(std::move(subactor), ctx);
- }
-
- void TTrackedActorBase::Die(const TActorContext& ctx) {
- // notify tracker
- Tracker->SendUntrack(ctx);
- // call default implementation to unregister actor from mailbox
- IActor::Die(ctx);
- }
-
- void TTrackedActorBase::HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
- // notify sender
- ctx.Send(ev->Sender, new TEvents::TEvPoisonTaken);
- // unregister from mailbox
- IActor::Die(ctx);
- }
-
+ Y_VERIFY(Tracker);
+ return Tracker->RegisterLocalSubactor(std::move(subactor), ctx);
+ }
+
+ void TTrackedActorBase::Die(const TActorContext& ctx) {
+ // notify tracker
+ Tracker->SendUntrack(ctx);
+ // call default implementation to unregister actor from mailbox
+ IActor::Die(ctx);
+ }
+
+ void TTrackedActorBase::HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
+ // notify sender
+ ctx.Send(ev->Sender, new TEvents::TEvPoisonTaken);
+ // unregister from mailbox
+ IActor::Die(ctx);
+ }
+
TAutoPtr<IEventHandle> TTrackedActorBase::AfterRegister(const TActorId& self, const TActorId& parent) {
- // send TEvBootstrap event locally
- return new IEventHandle(self, parent, new TEvents::TEvBootstrap);
- }
-
- void TTrackedActorBase::InitialReceiveFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
- // the first event MUST be the TEvBootstrap one
- Y_VERIFY(ev->GetTypeRewrite() == TEvents::TEvBootstrap::EventType);
- // notify implementation
- AfterBootstrap(ctx);
- }
-
- void TTrackedActorBase::BindToTracker(TActorTracker *tracker) {
- Y_VERIFY(!Tracker);
- Tracker = tracker;
- }
-
-} // NKikimr
+ // send TEvBootstrap event locally
+ return new IEventHandle(self, parent, new TEvents::TEvBootstrap);
+ }
+
+ void TTrackedActorBase::InitialReceiveFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
+ // the first event MUST be the TEvBootstrap one
+ Y_VERIFY(ev->GetTypeRewrite() == TEvents::TEvBootstrap::EventType);
+ // notify implementation
+ AfterBootstrap(ctx);
+ }
+
+ void TTrackedActorBase::BindToTracker(TActorTracker *tracker) {
+ Y_VERIFY(!Tracker);
+ Tracker = tracker;
+ }
+
+} // NKikimr
diff --git a/ydb/core/actorlib_impl/actor_tracker.h b/ydb/core/actorlib_impl/actor_tracker.h
index 66e953740d4..8178b9ef631 100644
--- a/ydb/core/actorlib_impl/actor_tracker.h
+++ b/ydb/core/actorlib_impl/actor_tracker.h
@@ -1,137 +1,137 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/event_local.h>
#include <library/cpp/actors/core/events.h>
-#include <util/generic/set.h>
-
-namespace NActors {
-
- // TEvTrackActor is sent by child actor in Register[Local]Subactor to an actor tracker to notify it about new
- // tracked subactor in pool.
- struct TEvTrackActor : TEventLocal<TEvTrackActor, TEvents::TSystem::TrackActor> {
+#include <util/generic/set.h>
+
+namespace NActors {
+
+ // TEvTrackActor is sent by child actor in Register[Local]Subactor to an actor tracker to notify it about new
+ // tracked subactor in pool.
+ struct TEvTrackActor : TEventLocal<TEvTrackActor, TEvents::TSystem::TrackActor> {
const TActorId NewSubactorId;
-
+
TEvTrackActor(const TActorId& newSubactorId)
- : NewSubactorId(newSubactorId)
- {}
- };
-
- struct TEvUntrackActor : TEventLocal<TEvUntrackActor, TEvents::TSystem::UntrackActor>
- {};
-
- class TTrackedActorBase;
-
- class TActorTracker {
- // our killer -- the one who sent TEvPoisonPill here
+ : NewSubactorId(newSubactorId)
+ {}
+ };
+
+ struct TEvUntrackActor : TEventLocal<TEvUntrackActor, TEvents::TSystem::UntrackActor>
+ {};
+
+ class TTrackedActorBase;
+
+ class TActorTracker {
+ // our killer -- the one who sent TEvPoisonPill here
TActorId KillerActorId;
-
- // a set of registered child actors we are tracking
+
+ // a set of registered child actors we are tracking
TSet<TActorId> RegisteredActors;
-
- // number of in flight TEvTrackActor messages coming to tracker, but not yet processed; high bit indicates if
- // we are stopping and can't register new actors
- TAtomic NumInFlightTracks = 0;
-
- // actor id for this tracker
+
+ // number of in flight TEvTrackActor messages coming to tracker, but not yet processed; high bit indicates if
+ // we are stopping and can't register new actors
+ TAtomic NumInFlightTracks = 0;
+
+ // actor id for this tracker
TActorId ActorId;
-
- public:
- void BindToActor(const TActorContext& ctx);
-
- // HandleTracking should be called from _ANY_ state function of containing actor in the following manner:
- //
- // STFUNC(...) {
- // if (Tracker.HandleTracking(ev, ctx)) {
- // return;
- // }
- // switch (ev->GetTypeRewrite()) {
- // ...
- // }
- // }
- //
- // Inside it handles TEvPoisonPill messages, controls RegisteredActors set, and dies when TEvPoisonPill
- // processing is finished.
- //
- // Since receiving TEvPoisonPill, the containing actor may continue to receive usual messages.
- bool HandleTracking(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
-
- // register subactor inside this tracker on a separate mailbox; should be called instead of ExecutorThread's
- // method
+
+ public:
+ void BindToActor(const TActorContext& ctx);
+
+ // HandleTracking should be called from _ANY_ state function of containing actor in the following manner:
+ //
+ // STFUNC(...) {
+ // if (Tracker.HandleTracking(ev, ctx)) {
+ // return;
+ // }
+ // switch (ev->GetTypeRewrite()) {
+ // ...
+ // }
+ // }
+ //
+ // Inside it handles TEvPoisonPill messages, controls RegisteredActors set, and dies when TEvPoisonPill
+ // processing is finished.
+ //
+ // Since receiving TEvPoisonPill, the containing actor may continue to receive usual messages.
+ bool HandleTracking(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
+
+ // register subactor inside this tracker on a separate mailbox; should be called instead of ExecutorThread's
+ // method
TActorId RegisterSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx,
- TMailboxType::EType mailboxType = TMailboxType::Simple, ui32 poolId = Max<ui32>());
-
- // register subactor inside the same mailbox as of the caller
+ TMailboxType::EType mailboxType = TMailboxType::Simple, ui32 poolId = Max<ui32>());
+
+ // register subactor inside the same mailbox as of the caller
TActorId RegisterLocalSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx);
-
- private:
- bool PreRegister();
- void Handle(TEvTrackActor::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvUntrackActor::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvents::TEvPoisonTaken::TPtr& ev, const TActorContext& ctx);
+
+ private:
+ bool PreRegister();
+ void Handle(TEvTrackActor::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvUntrackActor::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvents::TEvPoisonTaken::TPtr& ev, const TActorContext& ctx);
void RemoveActorFromTrackList(const TActorId& subactorId, const TActorContext& ctx);
- void CheckIfPoisonPillDone(const TActorContext& ctx);
-
- private:
- friend class TTrackedActorBase;
- void SendUntrack(const TActorContext& ctx);
- };
-
- class TTrackedActorBase : public IActor {
- // plain pointer to tracker; tracker always lives longer than the tracked actors, so it is safe to reference
- // it in this way; the reference is filled in when RegisterSubactor is called
- TActorTracker *Tracker = nullptr;
-
- protected:
- TTrackedActorBase()
- : IActor(static_cast<TReceiveFunc>(&TTrackedActorBase::InitialReceiveFunc))
- {}
-
- // subactor registration helpers
+ void CheckIfPoisonPillDone(const TActorContext& ctx);
+
+ private:
+ friend class TTrackedActorBase;
+ void SendUntrack(const TActorContext& ctx);
+ };
+
+ class TTrackedActorBase : public IActor {
+ // plain pointer to tracker; tracker always lives longer than the tracked actors, so it is safe to reference
+ // it in this way; the reference is filled in when RegisterSubactor is called
+ TActorTracker *Tracker = nullptr;
+
+ protected:
+ TTrackedActorBase()
+ : IActor(static_cast<TReceiveFunc>(&TTrackedActorBase::InitialReceiveFunc))
+ {}
+
+ // subactor registration helpers
TActorId RegisterSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx,
- TMailboxType::EType mailboxType = TMailboxType::Simple, ui32 poolId = Max<ui32>());
+ TMailboxType::EType mailboxType = TMailboxType::Simple, ui32 poolId = Max<ui32>());
TActorId RegisterLocalSubactor(THolder<TTrackedActorBase>&& subactor, const TActorContext& ctx);
-
- // an override for tracked actors that also informs tracker about the death of tracked actor
- void Die(const TActorContext& ctx) override;
-
- // HandlePoison should be called from _ANY_ state function of derived actor in response to TEvPoisonPill event;
- // internally it calls Die() to terminate this actor
- void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
-
+
+ // an override for tracked actors that also informs tracker about the death of tracked actor
+ void Die(const TActorContext& ctx) override;
+
+ // HandlePoison should be called from _ANY_ state function of derived actor in response to TEvPoisonPill event;
+ // internally it calls Die() to terminate this actor
+ void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx);
+
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& /*parent*/) override;
- virtual void AfterBootstrap(const TActorContext& ctx) = 0;
-
- private:
- void InitialReceiveFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
-
- private:
- friend class TActorTracker;
- void BindToTracker(TActorTracker *tracker);
- };
-
- template<typename TDerived>
- class TTrackedActorBootstrapped : public TTrackedActorBase {
- void AfterBootstrap(const TActorContext& ctx) {
- static_cast<TDerived&>(*this).Bootstrap(ctx);
- }
- };
-
- template<typename TDerived>
- class TTrackedActor : public TTrackedActorBase {
- using TDerivedReceiveFunc = void (TDerived::*)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
- TDerivedReceiveFunc UserReceiveFunc;
-
- void AfterBootstrap(const TActorContext& /*ctx*/) {
- Become(UserReceiveFunc);
- }
-
- public:
- TTrackedActor(TDerivedReceiveFunc userReceiveFunc)
- : UserReceiveFunc(userReceiveFunc)
- {}
- };
-
-} // NKikimr
+ virtual void AfterBootstrap(const TActorContext& ctx) = 0;
+
+ private:
+ void InitialReceiveFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
+
+ private:
+ friend class TActorTracker;
+ void BindToTracker(TActorTracker *tracker);
+ };
+
+ template<typename TDerived>
+ class TTrackedActorBootstrapped : public TTrackedActorBase {
+ void AfterBootstrap(const TActorContext& ctx) {
+ static_cast<TDerived&>(*this).Bootstrap(ctx);
+ }
+ };
+
+ template<typename TDerived>
+ class TTrackedActor : public TTrackedActorBase {
+ using TDerivedReceiveFunc = void (TDerived::*)(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
+ TDerivedReceiveFunc UserReceiveFunc;
+
+ void AfterBootstrap(const TActorContext& /*ctx*/) {
+ Become(UserReceiveFunc);
+ }
+
+ public:
+ TTrackedActor(TDerivedReceiveFunc userReceiveFunc)
+ : UserReceiveFunc(userReceiveFunc)
+ {}
+ };
+
+} // NKikimr
diff --git a/ydb/core/actorlib_impl/actor_tracker_ut.cpp b/ydb/core/actorlib_impl/actor_tracker_ut.cpp
index d804e3b9240..c908991dbfe 100644
--- a/ydb/core/actorlib_impl/actor_tracker_ut.cpp
+++ b/ydb/core/actorlib_impl/actor_tracker_ut.cpp
@@ -2,120 +2,120 @@
#include <ydb/core/testlib/basics/runtime.h>
#include <ydb/core/testlib/basics/appdata.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include "actor_tracker.h"
-
-using namespace NActors;
-
-TAtomic SubworkerNew = 0;
-TAtomic SubworkerBootstrap = 0;
-TAtomic SubworkerPoison = 0;
-TAtomic SubworkerDelete = 0;
-
-// the subworker
-class TSubworkerActor : public TTrackedActorBootstrapped<TSubworkerActor> {
- using TBase = TTrackedActorBootstrapped<TSubworkerActor>;
-
-public:
- TSubworkerActor() {
- AtomicIncrement(SubworkerNew);
- }
-
- ~TSubworkerActor() {
- AtomicIncrement(SubworkerDelete);
- }
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- AtomicIncrement(SubworkerBootstrap);
- Become(&TSubworkerActor::StateFunc);
- }
-
- void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
- AtomicIncrement(SubworkerPoison);
- TBase::HandlePoison(ev, ctx);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvents::TEvPoisonPill, HandlePoison);
- default:
- Y_FAIL();
- }
- }
-};
-
-// the basic worker -- it does some work and creates subworkers
-class TWorkerActor : public TTrackedActorBootstrapped<TWorkerActor> {
- using TBase = TTrackedActorBootstrapped<TWorkerActor>;
-
-public:
- void Bootstrap(const TActorContext& ctx) {
- // create some subworkers
- for (int i = 0; i < 3; ++i) {
+#include "actor_tracker.h"
+
+using namespace NActors;
+
+TAtomic SubworkerNew = 0;
+TAtomic SubworkerBootstrap = 0;
+TAtomic SubworkerPoison = 0;
+TAtomic SubworkerDelete = 0;
+
+// the subworker
+class TSubworkerActor : public TTrackedActorBootstrapped<TSubworkerActor> {
+ using TBase = TTrackedActorBootstrapped<TSubworkerActor>;
+
+public:
+ TSubworkerActor() {
+ AtomicIncrement(SubworkerNew);
+ }
+
+ ~TSubworkerActor() {
+ AtomicIncrement(SubworkerDelete);
+ }
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ AtomicIncrement(SubworkerBootstrap);
+ Become(&TSubworkerActor::StateFunc);
+ }
+
+ void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
+ AtomicIncrement(SubworkerPoison);
+ TBase::HandlePoison(ev, ctx);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvents::TEvPoisonPill, HandlePoison);
+ default:
+ Y_FAIL();
+ }
+ }
+};
+
+// the basic worker -- it does some work and creates subworkers
+class TWorkerActor : public TTrackedActorBootstrapped<TWorkerActor> {
+ using TBase = TTrackedActorBootstrapped<TWorkerActor>;
+
+public:
+ void Bootstrap(const TActorContext& ctx) {
+ // create some subworkers
+ for (int i = 0; i < 3; ++i) {
TActorId actorId = RegisterSubactor(MakeHolder<TSubworkerActor>(), ctx);
- if (!actorId) {
- Die(ctx);
- }
- }
-
- Become(&TWorkerActor::StateFunc);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvents::TEvPoisonPill, TBase::HandlePoison);
- default:
- Y_FAIL();
- }
- }
-};
-
-// the root manager -- the entity than controls all created workers and subworkers
-class TManagerActor : public TActorBootstrapped<TManagerActor> {
- TActorTracker Tracker;
-
-public:
- void Bootstrap(const TActorContext& ctx) {
- Tracker.BindToActor(ctx);
-
- // create some workers
- for (int i = 0; i < 2; ++i) {
+ if (!actorId) {
+ Die(ctx);
+ }
+ }
+
+ Become(&TWorkerActor::StateFunc);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvents::TEvPoisonPill, TBase::HandlePoison);
+ default:
+ Y_FAIL();
+ }
+ }
+};
+
+// the root manager -- the entity than controls all created workers and subworkers
+class TManagerActor : public TActorBootstrapped<TManagerActor> {
+ TActorTracker Tracker;
+
+public:
+ void Bootstrap(const TActorContext& ctx) {
+ Tracker.BindToActor(ctx);
+
+ // create some workers
+ for (int i = 0; i < 2; ++i) {
TActorId actorId = Tracker.RegisterSubactor(MakeHolder<TWorkerActor>(), ctx);
- if (!actorId) {
- // a race has occured
- Die(ctx);
- }
- }
-
- Become(&TManagerActor::StateFunc);
- }
-
- STFUNC(StateFunc) {
- if (Tracker.HandleTracking(ev, ctx)) {
- return;
- }
-
- switch (ev->GetTypeRewrite()) {
- }
- }
-};
-
+ if (!actorId) {
+ // a race has occured
+ Die(ctx);
+ }
+ }
+
+ Become(&TManagerActor::StateFunc);
+ }
+
+ STFUNC(StateFunc) {
+ if (Tracker.HandleTracking(ev, ctx)) {
+ return;
+ }
+
+ switch (ev->GetTypeRewrite()) {
+ }
+ }
+};
+
Y_UNIT_TEST_SUITE(TActorTracker) {
-
+
Y_UNIT_TEST(Basic) {
- {
+ {
TTestBasicRuntime runtime;
runtime.Initialize(NKikimr::TAppPrepare().Unwrap());
TActorId managerId = runtime.Register(new TManagerActor);
TActorId edge = runtime.AllocateEdgeActor();
- runtime.Schedule(new IEventHandle(managerId, edge, new TEvents::TEvPoisonPill), TDuration::Seconds(1));
- runtime.DispatchEvents();
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEventRethrow<TEvents::TEvPoisonTaken>(handle);
- }
- UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerNew), 6);
- UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerBootstrap), 6);
- UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerPoison), 6);
- UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerDelete), 6);
- }
-
-}
+ runtime.Schedule(new IEventHandle(managerId, edge, new TEvents::TEvPoisonPill), TDuration::Seconds(1));
+ runtime.DispatchEvents();
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEventRethrow<TEvents::TEvPoisonTaken>(handle);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerNew), 6);
+ UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerBootstrap), 6);
+ UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerPoison), 6);
+ UNIT_ASSERT_VALUES_EQUAL(AtomicGet(SubworkerDelete), 6);
+ }
+
+}
diff --git a/ydb/core/actorlib_impl/async_destroyer.h b/ydb/core/actorlib_impl/async_destroyer.h
index 9d0d6f4c4ca..d518839f599 100644
--- a/ydb/core/actorlib_impl/async_destroyer.h
+++ b/ydb/core/actorlib_impl/async_destroyer.h
@@ -9,8 +9,8 @@ namespace NKikimr {
template <class TVictim>
class TAsyncDestroyer : public NActors::TActorBootstrapped<TAsyncDestroyer<TVictim>> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::ASYNC_DESTROYER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::ASYNC_DESTROYER;
}
explicit TAsyncDestroyer(TAutoPtr<TVictim> victim)
diff --git a/ydb/core/actorlib_impl/connect_socket_protocol.cpp b/ydb/core/actorlib_impl/connect_socket_protocol.cpp
index c4c6db9f13b..168a20b64ac 100644
--- a/ydb/core/actorlib_impl/connect_socket_protocol.cpp
+++ b/ydb/core/actorlib_impl/connect_socket_protocol.cpp
@@ -155,7 +155,7 @@ void TConnectSocketProtocol::TryAgain(const TActorContext& ctx) noexcept {
return;
IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
- poller->StartWrite(Socket,
+ poller->StartWrite(Socket,
std::bind(CheckConnectionRoutine, std::placeholders::_1, ctx));
}
diff --git a/ydb/core/actorlib_impl/defs.h b/ydb/core/actorlib_impl/defs.h
index dffa5929b4e..476e6b80152 100644
--- a/ydb/core/actorlib_impl/defs.h
+++ b/ydb/core/actorlib_impl/defs.h
@@ -1,3 +1,3 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/defs.h>
diff --git a/ydb/core/actorlib_impl/load_network.cpp b/ydb/core/actorlib_impl/load_network.cpp
index ae6f1b248a3..034da6f5de0 100644
--- a/ydb/core/actorlib_impl/load_network.cpp
+++ b/ydb/core/actorlib_impl/load_network.cpp
@@ -16,8 +16,8 @@ using NActors::TEvents;
class TLoadNetwork: public NActors::TActorBootstrapped<TLoadNetwork> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TEST_ACTOR_RUNTIME;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TEST_ACTOR_RUNTIME;
}
TLoadNetwork(ui32 selfNodeId, ui32 totalNodesCount)
diff --git a/ydb/core/actorlib_impl/long_timer.cpp b/ydb/core/actorlib_impl/long_timer.cpp
index e3b139579fb..983bffef9b2 100644
--- a/ydb/core/actorlib_impl/long_timer.cpp
+++ b/ydb/core/actorlib_impl/long_timer.cpp
@@ -38,7 +38,7 @@ class TLongTimer : public TActor<TLongTimer> {
}
public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::ACTORLIB_LONG_TIMER;
+ return NKikimrServices::TActivity::ACTORLIB_LONG_TIMER;
}
TLongTimer(TMonotonic startTime, TMonotonic signalTime, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie)
diff --git a/ydb/core/actorlib_impl/node_identifier.cpp b/ydb/core/actorlib_impl/node_identifier.cpp
index 410fbede7cc..5e3dfd4bf57 100644
--- a/ydb/core/actorlib_impl/node_identifier.cpp
+++ b/ydb/core/actorlib_impl/node_identifier.cpp
@@ -142,7 +142,7 @@ class TNodeIdentifier : public TActorBootstrapped<TNodeIdentifier> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::NODE_IDENTIFIER; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::NODE_IDENTIFIER; }
void StateWork(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx) {
switch (ev->GetTypeRewrite()) {
diff --git a/ydb/core/actorlib_impl/read_data_protocol.cpp b/ydb/core/actorlib_impl/read_data_protocol.cpp
index 62045309f81..d6ef835a1e8 100644
--- a/ydb/core/actorlib_impl/read_data_protocol.cpp
+++ b/ydb/core/actorlib_impl/read_data_protocol.cpp
@@ -57,7 +57,7 @@ void TReadDataProtocolImpl::TryAgain(const TActorContext& ctx) noexcept {
continue;
}
} else {
- if (-recvResult == EAGAIN || -recvResult == EWOULDBLOCK) {
+ if (-recvResult == EAGAIN || -recvResult == EWOULDBLOCK) {
if (Filled > 0) {
if (Catcher->CatchReadDataComplete(ctx, Filled)) {
return;
@@ -69,26 +69,26 @@ void TReadDataProtocolImpl::TryAgain(const TActorContext& ctx) noexcept {
break;
}
- } else if (-recvResult == EINTR) {
- continue;
- } else if (!recvResult) {
- if (Filled > 0 && Catcher->CatchReadDataComplete(ctx, Filled)) {
- return;
- }
- Catcher->CatchReadDataClosed();
- return;
+ } else if (-recvResult == EINTR) {
+ continue;
+ } else if (!recvResult) {
+ if (Filled > 0 && Catcher->CatchReadDataComplete(ctx, Filled)) {
+ return;
+ }
+ Catcher->CatchReadDataClosed();
+ return;
}
break;
}
}
- if (-recvResult == EAGAIN || -recvResult == EWOULDBLOCK) {
- IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
- poller->StartRead(Socket,
- std::bind(NotifyReadyRead, std::placeholders::_1, ctx));
- return;
- }
-
+ if (-recvResult == EAGAIN || -recvResult == EWOULDBLOCK) {
+ IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
+ poller->StartRead(Socket,
+ std::bind(NotifyReadyRead, std::placeholders::_1, ctx));
+ return;
+ }
+
switch (-recvResult) {
case ECONNRESET:
Catcher->CatchReadDataError("Connection reset by peer");
@@ -118,10 +118,10 @@ void TReadDataProtocolImpl::TryAgain(const TActorContext& ctx) noexcept {
}
}
-void TReadDataProtocolImpl::CancelReadData(const TActorContext& /*ctx*/) noexcept {
+void TReadDataProtocolImpl::CancelReadData(const TActorContext& /*ctx*/) noexcept {
Cancelled = true;
-// IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
-// poller->CancelRead(Socket);
+// IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
+// poller->CancelRead(Socket);
}
}
diff --git a/ydb/core/actorlib_impl/send_data_protocol.cpp b/ydb/core/actorlib_impl/send_data_protocol.cpp
index 7d79c000396..1c012dc2de5 100644
--- a/ydb/core/actorlib_impl/send_data_protocol.cpp
+++ b/ydb/core/actorlib_impl/send_data_protocol.cpp
@@ -58,13 +58,13 @@ void TSendDataProtocol::TryAgain(const TActorContext& ctx) noexcept {
}
}
- if (-sendResult == EAGAIN || -sendResult == EWOULDBLOCK) {
- IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
- poller->StartWrite(Socket,
- std::bind(NotifyReadyWrite, std::placeholders::_1, ctx));
- return;
- }
-
+ if (-sendResult == EAGAIN || -sendResult == EWOULDBLOCK) {
+ IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
+ poller->StartWrite(Socket,
+ std::bind(NotifyReadyWrite, std::placeholders::_1, ctx));
+ return;
+ }
+
switch (-sendResult) {
case ECONNRESET:
CatchSendDataError("Connection reset by peer");
@@ -99,10 +99,10 @@ void TSendDataProtocol::TryAgain(const TActorContext& ctx) noexcept {
}
}
-void TSendDataProtocol::CancelSendData(const TActorContext& /*ctx*/) noexcept {
+void TSendDataProtocol::CancelSendData(const TActorContext& /*ctx*/) noexcept {
Cancelled = true;
-// IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
-// poller->CancelWrite(Socket);
+// IPoller* poller = NKikimr::AppData(ctx)->PollerThreads.Get();
+// poller->CancelWrite(Socket);
}
}
diff --git a/ydb/core/actorlib_impl/test_interconnect_ut.cpp b/ydb/core/actorlib_impl/test_interconnect_ut.cpp
index 0d9d3535ef6..556afe4cbf9 100644
--- a/ydb/core/actorlib_impl/test_interconnect_ut.cpp
+++ b/ydb/core/actorlib_impl/test_interconnect_ut.cpp
@@ -13,693 +13,693 @@
#include <library/cpp/testing/unittest/registar.h>
#include <util/system/sanitizers.h>
#include <util/thread/factory.h>
-
-namespace NKikimr {
- using namespace NActors;
-
+
+namespace NKikimr {
+ using namespace NActors;
+
Y_UNIT_TEST_SUITE(TInterconnectTest) {
- class TWall : public NActors::TActor<TWall> {
- public:
- TWall() noexcept
- : TActor(&TThis::StateFunc)
- {}
-
- private:
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- FFunc(TEvents::TEvPing::EventType, OnPing);
- }
- }
-
- void OnPing(STFUNC_SIG) noexcept
- {
- ctx.Send(ev->Sender, new TEvents::TEvPong, (ev->GetChannel() << IEventHandle::ChannelShift) | (ev->GetSubChannel() ? IEventHandle::FlagUseSubChannel : 0) , ev->Cookie);
- }
- };
-
- class TKiller : public NActors::TActor<TKiller> {
- public:
- TKiller() noexcept
- : TActor(&TThis::StateFunc)
- {}
-
- private:
- STFUNC(StateFunc) {
- ctx.Send(ev->InterconnectSession, new TEvents::TEvPoisonPill);
- }
- };
-
- class TFlooder : public NActors::TActor<TFlooder> {
- public:
+ class TWall : public NActors::TActor<TWall> {
+ public:
+ TWall() noexcept
+ : TActor(&TThis::StateFunc)
+ {}
+
+ private:
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ FFunc(TEvents::TEvPing::EventType, OnPing);
+ }
+ }
+
+ void OnPing(STFUNC_SIG) noexcept
+ {
+ ctx.Send(ev->Sender, new TEvents::TEvPong, (ev->GetChannel() << IEventHandle::ChannelShift) | (ev->GetSubChannel() ? IEventHandle::FlagUseSubChannel : 0) , ev->Cookie);
+ }
+ };
+
+ class TKiller : public NActors::TActor<TKiller> {
+ public:
+ TKiller() noexcept
+ : TActor(&TThis::StateFunc)
+ {}
+
+ private:
+ STFUNC(StateFunc) {
+ ctx.Send(ev->InterconnectSession, new TEvents::TEvPoisonPill);
+ }
+ };
+
+ class TFlooder : public NActors::TActor<TFlooder> {
+ public:
TFlooder(const TActorId& peer, const TActorId& edge, unsigned count) noexcept
- : TActor(&TThis::InitFunc), Peer(peer), Edge(edge), Counter(count), Responses(0ULL)
- {}
-
- private:
- STFUNC(InitFunc) {
- switch (ev->GetTypeRewrite()) {
- CFunc(TEvents::TSystem::Bootstrap, OnStart);
- }
- }
-
- STFUNC(WaitFunc) {
- switch (ev->GetTypeRewrite()) {
- CFunc(TEvInterconnect::EvNodeConnected, OnConnect);
- }
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- FFunc(TEvents::TEvPong::EventType, OnPong);
- }
- }
-
+ : TActor(&TThis::InitFunc), Peer(peer), Edge(edge), Counter(count), Responses(0ULL)
+ {}
+
+ private:
+ STFUNC(InitFunc) {
+ switch (ev->GetTypeRewrite()) {
+ CFunc(TEvents::TSystem::Bootstrap, OnStart);
+ }
+ }
+
+ STFUNC(WaitFunc) {
+ switch (ev->GetTypeRewrite()) {
+ CFunc(TEvInterconnect::EvNodeConnected, OnConnect);
+ }
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ FFunc(TEvents::TEvPong::EventType, OnPong);
+ }
+ }
+
TAutoPtr<IEventHandle> AfterRegister(const TActorId &self, const TActorId& parentId) noexcept override {
- return new IEventHandle(self, parentId, new TEvents::TEvBootstrap, 0);
- }
-
- void OnStart(const NActors::TActorContext &ctx) noexcept {
- Become(&TThis::WaitFunc);
+ return new IEventHandle(self, parentId, new TEvents::TEvBootstrap, 0);
+ }
+
+ void OnStart(const NActors::TActorContext &ctx) noexcept {
+ Become(&TThis::WaitFunc);
ctx.Send(TActivationContext::InterconnectProxy(Peer.NodeId()), new TEvInterconnect::TEvConnectNode, true);
- }
-
- void OnConnect(const NActors::TActorContext &ctx) noexcept {
- LOG_NOTICE(ctx, NActorsServices::TEST, "Node connected.");
- Become(&TThis::StateFunc);
- for (ui64 i = 0; i < Counter; ++i) {
- ctx.Send(Peer, new TEvents::TEvPing, 0, i);
- }
- }
-
- void OnPong(STFUNC_SIG) noexcept
- {
- UNIT_ASSERT_EQUAL(Responses, ev->Cookie);
-
- if (++Responses == Counter) {
- ctx.Send(Edge, new TEvents::TEvWakeup);
- LOG_NOTICE(ctx, NActorsServices::TEST, "Done.");
- }
- }
-
+ }
+
+ void OnConnect(const NActors::TActorContext &ctx) noexcept {
+ LOG_NOTICE(ctx, NActorsServices::TEST, "Node connected.");
+ Become(&TThis::StateFunc);
+ for (ui64 i = 0; i < Counter; ++i) {
+ ctx.Send(Peer, new TEvents::TEvPing, 0, i);
+ }
+ }
+
+ void OnPong(STFUNC_SIG) noexcept
+ {
+ UNIT_ASSERT_EQUAL(Responses, ev->Cookie);
+
+ if (++Responses == Counter) {
+ ctx.Send(Edge, new TEvents::TEvWakeup);
+ LOG_NOTICE(ctx, NActorsServices::TEST, "Done.");
+ }
+ }
+
const TActorId Peer, Edge;
- const unsigned Counter;
- unsigned Responses;
- };
-
- TAutoPtr<IEventHandle> GetSerialized(const TAutoPtr<IEventHandle>& ev) {
- NActors::TAllocChunkSerializer chunker;
+ const unsigned Counter;
+ unsigned Responses;
+ };
+
+ TAutoPtr<IEventHandle> GetSerialized(const TAutoPtr<IEventHandle>& ev) {
+ NActors::TAllocChunkSerializer chunker;
ev->GetBase()->SerializeToArcadiaStream(&chunker);
- auto Data = chunker.Release(ev->GetBase()->IsExtendedFormat());
- TAutoPtr<IEventHandle> serev =
- new IEventHandle(ev->GetBase()->Type(), ev->Flags,
- ev->Recipient, ev->Sender,
- std::move(Data), ev->Cookie);
- return serev;
- }
-
+ auto Data = chunker.Release(ev->GetBase()->IsExtendedFormat());
+ TAutoPtr<IEventHandle> serev =
+ new IEventHandle(ev->GetBase()->Type(), ev->Flags,
+ ev->Recipient, ev->Sender,
+ std::move(Data), ev->Cookie);
+ return serev;
+ }
+
Y_UNIT_TEST(TestSimplePingPong) {
TTestBasicRuntime runtime(2);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT,
- NActors::NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT,
+ NActors::NLog::PRI_DEBUG);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TWall, 1);
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, 7 << IEventHandle::ChannelShift, 13), 0);
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 13);
- UNIT_ASSERT_EQUAL(handle->GetChannel(), 7);
- }
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TWall, 1);
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, 7 << IEventHandle::ChannelShift, 13), 0);
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 13);
+ UNIT_ASSERT_EQUAL(handle->GetChannel(), 7);
+ }
+
Y_UNIT_TEST(TestManyEvents) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TWall, 1);
- runtime.Register(new TFlooder(wall, edge, 100000), 0);
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
- }
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TWall, 1);
+ runtime.Register(new TFlooder(wall, edge, 100000), 0);
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
+ }
+
Y_UNIT_TEST(TestCrossConnect) {
- TInstant time = TInstant::Now();
+ TInstant time = TInstant::Now();
constexpr ui64 iterations = NSan::PlainOrUnderSanitizer(200, 50);
for (ui64 i = 0; i < iterations; ++i) {
- Cerr << "Starting iteration " << i << Endl;
+ Cerr << "Starting iteration " << i << Endl;
TTestBasicRuntime runtime(2);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
- runtime.SetDispatcherRandomSeed(time, i);
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
+ runtime.SetDispatcherRandomSeed(time, i);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge0 = runtime.AllocateEdgeActor(0);
- const auto edge1 = runtime.AllocateEdgeActor(1);
- const auto wall0 = runtime.Register(new TWall, 0);
- const auto wall1 = runtime.Register(new TWall, 1);
-
- runtime.Register(new TFlooder(wall1, edge0, 10), 0);
- runtime.Register(new TFlooder(wall0, edge1, 10), 1);
-
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
- runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
- }
- }
-
+ const auto edge0 = runtime.AllocateEdgeActor(0);
+ const auto edge1 = runtime.AllocateEdgeActor(1);
+ const auto wall0 = runtime.Register(new TWall, 0);
+ const auto wall1 = runtime.Register(new TWall, 1);
+
+ runtime.Register(new TFlooder(wall1, edge0, 10), 0);
+ runtime.Register(new TFlooder(wall0, edge1, 10), 1);
+
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
+ runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
+ }
+ }
+
Y_UNIT_TEST(TestConnectAndDisconnect) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
-
- TAutoPtr<IEventHandle> handle;
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
- }
-
- runtime.Send(new IEventHandle(handle->Sender, edge, new TEvents::TEvPoisonPill), 0, true);
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
- }
-
- }
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
+
+ TAutoPtr<IEventHandle> handle;
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
+ }
+
+ runtime.Send(new IEventHandle(handle->Sender, edge, new TEvents::TEvPoisonPill), 0, true);
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
+ }
+
+ }
+
Y_UNIT_TEST(TestBlobEvent) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(100000, '@');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] = TString::value_type(i % 256);
-
- runtime.Send(new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 13), 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 13);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(100000, '@');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] = TString::value_type(i % 256);
+
+ runtime.Send(new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 13), 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 13);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+
Y_UNIT_TEST(TestBlobEventPreSerialized) {
TTestBasicRuntime runtime(2);
- runtime.SetDispatchTimeout(TDuration::Seconds(1));
+ runtime.SetDispatchTimeout(TDuration::Seconds(1));
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(100000, '@');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- TString::value_type(i % 256);
-
- for (int count = 0; count < 100; ++count) {
- NActors::TAllocChunkSerializer chunker;
- TAutoPtr<IEventHandle> raw =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 13);
- TAutoPtr<IEventHandle> serev = GetSerialized(raw);
-
- runtime.Send(serev.Release(), 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 13);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(100000, '@');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ TString::value_type(i % 256);
+
+ for (int count = 0; count < 100; ++count) {
+ NActors::TAllocChunkSerializer chunker;
+ TAutoPtr<IEventHandle> raw =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 13);
+ TAutoPtr<IEventHandle> serev = GetSerialized(raw);
+
+ runtime.Send(serev.Release(), 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 13);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestNotifyUndelivered) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge0 = runtime.AllocateEdgeActor(0);
- const auto edge1 = runtime.AllocateEdgeActor(1);
-
- const TString blob(10000000, '#');
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvInterconnect::TEvConnectNode), 0, true);
-
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
-
- runtime.Send(new IEventHandle(edge1, edge0, new TEvents::TEvBlob(blob), IEventHandle::FlagTrackDelivery, 777), 0, true);
- runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvPoisonPill), 0, true);
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvUndelivered>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 777);
- UNIT_ASSERT_EQUAL(event->SourceType, TEvents::TEvBlob::EventType);
- UNIT_ASSERT_EQUAL(event->Reason, TEvents::TEvUndelivered::Disconnected);
- }
-
+ const auto edge0 = runtime.AllocateEdgeActor(0);
+ const auto edge1 = runtime.AllocateEdgeActor(1);
+
+ const TString blob(10000000, '#');
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvInterconnect::TEvConnectNode), 0, true);
+
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+
+ runtime.Send(new IEventHandle(edge1, edge0, new TEvents::TEvBlob(blob), IEventHandle::FlagTrackDelivery, 777), 0, true);
+ runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvPoisonPill), 0, true);
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvUndelivered>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 777);
+ UNIT_ASSERT_EQUAL(event->SourceType, TEvents::TEvBlob::EventType);
+ UNIT_ASSERT_EQUAL(event->Reason, TEvents::TEvUndelivered::Disconnected);
+ }
+
Y_UNIT_TEST(TestSubscribeByFlag) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TKiller, 1);
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, IEventHandle::FlagSubscribeOnSession), 0);
- {
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
- }
- {
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TKiller, 1);
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, IEventHandle::FlagSubscribeOnSession), 0);
+ {
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
+ }
+ {
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
+ }
+ }
+
Y_UNIT_TEST(TestReconnect) {
TTestBasicRuntime runtime(2);
- runtime.SetUseRealInterconnect();
- runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT_SESSION, NActors::NLog::PRI_DEBUG);
- SOCKET s = INVALID_SOCKET;
+ runtime.SetUseRealInterconnect();
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT_SESSION, NActors::NLog::PRI_DEBUG);
+ SOCKET s = INVALID_SOCKET;
runtime.SetObserverFunc([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev) {
- if (auto *p = ev->CastAsLocal<TEvHandshakeDone>()) {
- s = *p->Socket;
- }
- return TTestActorRuntime::EEventAction::PROCESS;
- });
+ if (auto *p = ev->CastAsLocal<TEvHandshakeDone>()) {
+ s = *p->Socket;
+ }
+ return TTestActorRuntime::EEventAction::PROCESS;
+ });
runtime.Initialize(TAppPrepare().Unwrap());
-
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TWall, 1);
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
-
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- const auto session = handle->Sender;
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
- runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
-
- ShutDown(s, SHUT_RDWR);
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
- runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
-
- runtime.Send(new IEventHandle(session, edge, new TEvents::TEvPoisonPill));
- runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
- UNIT_ASSERT_EQUAL(handle->Sender, session);
- }
-
+
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TWall, 1);
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
+
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ const auto session = handle->Sender;
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
+ runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
+
+ ShutDown(s, SHUT_RDWR);
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
+ runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
+
+ runtime.Send(new IEventHandle(session, edge, new TEvents::TEvPoisonPill));
+ runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
+ UNIT_ASSERT_EQUAL(handle->Sender, session);
+ }
+
Y_UNIT_TEST(TestSubscribeAndUnsubsribeByEvent) {
TTestBasicRuntime runtime(3);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge0 = runtime.AllocateEdgeActor(0);
- const auto edge1 = runtime.AllocateEdgeActor(1);
-
- TAutoPtr<IEventHandle> handle;
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(1, 0), edge1, new TEvInterconnect::TEvConnectNode), 1, true);
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(0));
- }
-
- runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvUnsubscribe), 1, true);
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(1, 2), edge1, new TEvents::TEvSubscribe), 1, true);
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
- }
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvInterconnect::TEvConnectNode), 0, true);
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
- }
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 2), edge0, new TEvents::TEvSubscribe), 0, true);
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
- }
-
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvents::TEvUnsubscribe), 0, true);
- runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvPoisonPill));
-
- {
- const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
- UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
- }
- }
-
+ const auto edge0 = runtime.AllocateEdgeActor(0);
+ const auto edge1 = runtime.AllocateEdgeActor(1);
+
+ TAutoPtr<IEventHandle> handle;
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(1, 0), edge1, new TEvInterconnect::TEvConnectNode), 1, true);
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(0));
+ }
+
+ runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvUnsubscribe), 1, true);
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(1, 2), edge1, new TEvents::TEvSubscribe), 1, true);
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
+ }
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvInterconnect::TEvConnectNode), 0, true);
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(1));
+ }
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 2), edge0, new TEvents::TEvSubscribe), 0, true);
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
+ }
+
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge0, new TEvents::TEvUnsubscribe), 0, true);
+ runtime.Send(new IEventHandle(handle->Sender, edge0, new TEvents::TEvPoisonPill));
+
+ {
+ const auto event = runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeDisconnected>(handle);
+ UNIT_ASSERT_EQUAL(event->NodeId, runtime.GetNodeId(2));
+ }
+ }
+
Y_UNIT_TEST(TestManyEventsWithReconnect) {
TTestBasicRuntime runtime(2);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
- SOCKET s = INVALID_SOCKET;
- runtime.SetObserverFunc([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev) {
- if (auto *p = ev->CastAsLocal<TEvHandshakeDone>()) {
- s = *p->Socket;
- }
- return TTestActorRuntime::EEventAction::PROCESS;
- });
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
+ SOCKET s = INVALID_SOCKET;
+ runtime.SetObserverFunc([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev) {
+ if (auto *p = ev->CastAsLocal<TEvHandshakeDone>()) {
+ s = *p->Socket;
+ }
+ return TTestActorRuntime::EEventAction::PROCESS;
+ });
runtime.Initialize(TAppPrepare().Unwrap());
-
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TWall, 1);
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
-
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
- runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
-
- runtime.SetObserverFunc([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev){
- if (s != INVALID_SOCKET && TEvents::TEvPing::EventType == ev->Type && 666ULL == ev->Cookie) {
- ShutDown(s, SHUT_RDWR);
- s = INVALID_SOCKET;
- }
- return TTestActorRuntime::EEventAction::PROCESS;
- });
-
- runtime.Register(new TFlooder(wall, edge, 10000), 0);
-
- runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
- }
-
+
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TWall, 1);
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1), edge, new TEvInterconnect::TEvConnectNode), 0, true);
+
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing), 0, true);
+ runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
+
+ runtime.SetObserverFunc([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& ev){
+ if (s != INVALID_SOCKET && TEvents::TEvPing::EventType == ev->Type && 666ULL == ev->Cookie) {
+ ShutDown(s, SHUT_RDWR);
+ s = INVALID_SOCKET;
+ }
+ return TTestActorRuntime::EEventAction::PROCESS;
+ });
+
+ runtime.Register(new TFlooder(wall, edge, 10000), 0);
+
+ runtime.GrabEdgeEvent<TEvents::TEvWakeup>(handle);
+ }
+
Y_UNIT_TEST(TestBlobEvent220Bytes) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(220, '!');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- TString::value_type(i);
-
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 69);
- runtime.Send(ev.Release(), 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 69);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(220, '!');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ TString::value_type(i);
+
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 69);
+ runtime.Send(ev.Release(), 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 69);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+
Y_UNIT_TEST(TestBlobEvent220BytesPreSerialized) {
TTestBasicRuntime runtime(2);
- runtime.SetDispatchTimeout(TDuration::Seconds(1));
+ runtime.SetDispatchTimeout(TDuration::Seconds(1));
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(220, '!');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- TString::value_type(i);
-
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 69);
- TAutoPtr<IEventHandle> serev = GetSerialized(ev);
- runtime.Send(serev.Release(), 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 69);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(220, '!');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ TString::value_type(i);
+
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, 69);
+ TAutoPtr<IEventHandle> serev = GetSerialized(ev);
+ runtime.Send(serev.Release(), 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 69);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+
Y_UNIT_TEST(TestBlobEventDifferentSizes) {
TTestBasicRuntime runtime(2);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT, NActors::NLog::PRI_DEBUG);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s = 1; s <= 1024; ++s) {
- TString blob(s, '!');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- '0' + (i % 10);
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
- runtime.Send(ev.Release(), 0);
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s = 1; s <= 1024; ++s) {
+ TString blob(s, '!');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ '0' + (i % 10);
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
+ runtime.Send(ev.Release(), 0);
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestBlobEventDifferentSizesPreSerialized) {
TTestBasicRuntime runtime(2);
- runtime.SetDispatchTimeout(TDuration::Seconds(1));
+ runtime.SetDispatchTimeout(TDuration::Seconds(1));
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s = 1; s <= 1024; ++s) {
- TString blob(s, '!');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- '0' + (i % 10);
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
- TAutoPtr<IEventHandle> serev = GetSerialized(ev);
- runtime.Send(serev.Release(), 0);
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s = 1; s <= 1024; ++s) {
+ TString blob(s, '!');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ '0' + (i % 10);
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
+ TAutoPtr<IEventHandle> serev = GetSerialized(ev);
+ runtime.Send(serev.Release(), 0);
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestBlobEventDifferentSizesPreSerializedAndRaw) {
TTestBasicRuntime runtime(2);
- runtime.SetDispatchTimeout(TDuration::Seconds(1));
+ runtime.SetDispatchTimeout(TDuration::Seconds(1));
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s = 1; s <= 1024; ++s) {
- TString blob(s, '!');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- '0' + (i % 10);
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
- TAutoPtr<IEventHandle> serev = GetSerialized(ev);
- TAutoPtr<IEventHandle> handle;
-
- runtime.Send(serev.Release(), 0);
- const auto aevent = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(aevent->Blob, blob);
-
- runtime.Send(ev.Release(), 0);
- const auto bevent = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(bevent->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s = 1; s <= 1024; ++s) {
+ TString blob(s, '!');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ '0' + (i % 10);
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
+ TAutoPtr<IEventHandle> serev = GetSerialized(ev);
+ TAutoPtr<IEventHandle> handle;
+
+ runtime.Send(serev.Release(), 0);
+ const auto aevent = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(aevent->Blob, blob);
+
+ runtime.Send(ev.Release(), 0);
+ const auto bevent = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(bevent->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestNotifyUndeliveredOnMissedActor) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
-
- runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1),
- edge,
- new TEvInterconnect::TEvConnectNode),
- 0, true);
-
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+
+ runtime.Send(new IEventHandle(runtime.GetInterconnectProxy(0, 1),
+ edge,
+ new TEvInterconnect::TEvConnectNode),
+ 0, true);
+
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvInterconnect::TEvNodeConnected>(handle);
+
runtime.Send(new IEventHandle(TActorId(runtime.GetNodeId(1), "null"),
- edge,
- new TEvents::TEvPing,
- IEventHandle::FlagTrackDelivery, 13),
- 0, true);
-
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvUndelivered>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 13);
- UNIT_ASSERT_EQUAL(event->SourceType, TEvents::TEvPing::EventType);
- UNIT_ASSERT_EQUAL(event->Reason, TEvents::TEvUndelivered::ReasonActorUnknown);
- }
-
+ edge,
+ new TEvents::TEvPing,
+ IEventHandle::FlagTrackDelivery, 13),
+ 0, true);
+
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvUndelivered>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 13);
+ UNIT_ASSERT_EQUAL(event->SourceType, TEvents::TEvPing::EventType);
+ UNIT_ASSERT_EQUAL(event->Reason, TEvents::TEvUndelivered::ReasonActorUnknown);
+ }
+
Y_UNIT_TEST(TestBlobEventUpToMebibytes) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s = 3; s <= 23; ++s) {
- TString blob(1 << s, '!');
- for (ui64 i = 0U; i < blob.size() / sizeof(ui64); ++i)
- reinterpret_cast<ui64*>(const_cast<TString::value_type*>(blob.data()))[i] = i;
-
- runtime.Send(new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s), 0);
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s = 3; s <= 23; ++s) {
+ TString blob(1 << s, '!');
+ for (ui64 i = 0U; i < blob.size() / sizeof(ui64); ++i)
+ reinterpret_cast<ui64*>(const_cast<TString::value_type*>(blob.data()))[i] = i;
+
+ runtime.Send(new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s), 0);
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestPreSerializedBlobEventUpToMebibytes) {
TTestBasicRuntime runtime(2);
- runtime.SetDispatchTimeout(TDuration::Seconds(1));
+ runtime.SetDispatchTimeout(TDuration::Seconds(1));
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s = 3; s <= 23; ++s) {
- TString blob(1 << s, '!');
- for (ui64 i = 0U; i < blob.size() / sizeof(ui64); ++i)
- reinterpret_cast<ui64*>(
- const_cast<TString::value_type*>(blob.data()))[i] = i;
-
- TAutoPtr<IEventHandle> ev =
- new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
- TAutoPtr<IEventHandle> serev = GetSerialized(ev);
- runtime.Send(serev.Release(), 0, true);
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, s);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- }
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s = 3; s <= 23; ++s) {
+ TString blob(1 << s, '!');
+ for (ui64 i = 0U; i < blob.size() / sizeof(ui64); ++i)
+ reinterpret_cast<ui64*>(
+ const_cast<TString::value_type*>(blob.data()))[i] = i;
+
+ TAutoPtr<IEventHandle> ev =
+ new IEventHandle(edge, edge, new TEvents::TEvBlob(blob), 0, s);
+ TAutoPtr<IEventHandle> serev = GetSerialized(ev);
+ runtime.Send(serev.Release(), 0, true);
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, s);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ }
+ }
+
Y_UNIT_TEST(TestPingPongThroughSubChannel) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- const auto wall = runtime.Register(new TWall, 1);
-
- runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, IEventHandle::FlagUseSubChannel, 113), 0);
- TAutoPtr<IEventHandle> handle;
- runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 113);
- UNIT_ASSERT_EQUAL(handle->GetChannel(), 0);
- UNIT_ASSERT_EQUAL(handle->GetSubChannel(), wall.LocalId());
- }
-
+ const auto edge = runtime.AllocateEdgeActor(0);
+ const auto wall = runtime.Register(new TWall, 1);
+
+ runtime.Send(new IEventHandle(wall, edge, new TEvents::TEvPing, IEventHandle::FlagUseSubChannel, 113), 0);
+ TAutoPtr<IEventHandle> handle;
+ runtime.GrabEdgeEvent<TEvents::TEvPong>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 113);
+ UNIT_ASSERT_EQUAL(handle->GetChannel(), 0);
+ UNIT_ASSERT_EQUAL(handle->GetSubChannel(), wall.LocalId());
+ }
+
Y_UNIT_TEST(TestBlobEventsThroughSubChannels) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
-
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(100000, '@');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] = TString::value_type(i % 256);
-
- for (auto i = 0U; i < 100U; ++i) {
-
- const auto src = runtime.AllocateEdgeActor(0);
-
- runtime.Send(new IEventHandle(edge, src, new TEvents::TEvBlob(blob), IEventHandle::FlagUseSubChannel, i), 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, i);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- UNIT_ASSERT_EQUAL(handle->GetSubChannel(), src.LocalId());
- }
- }
-
+
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(100000, '@');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] = TString::value_type(i % 256);
+
+ for (auto i = 0U; i < 100U; ++i) {
+
+ const auto src = runtime.AllocateEdgeActor(0);
+
+ runtime.Send(new IEventHandle(edge, src, new TEvents::TEvBlob(blob), IEventHandle::FlagUseSubChannel, i), 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, i);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ UNIT_ASSERT_EQUAL(handle->GetSubChannel(), src.LocalId());
+ }
+ }
+
Y_UNIT_TEST(TestTraceIdPassThrough) {
TTestBasicRuntime runtime(2);
- runtime.SetLogPriority(NActorsServices::INTERCONNECT,
- NActors::NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NActorsServices::INTERCONNECT,
+ NActors::NLog::PRI_DEBUG);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- TString blob(100000, '@');
- for (auto i = 0U; i < blob.size(); ++i)
- const_cast<TString::value_type*>(blob.data())[i] =
- TString::value_type(i % 256);
-
- auto sentTraceId = NWilson::TTraceId::NewTraceId();
-
- runtime.Send(new IEventHandle(edge, edge,
- new TEvents::TEvBlob(blob),
- 0, 13, nullptr, sentTraceId.Clone()),
- 0);
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
- UNIT_ASSERT_EQUAL(handle->Cookie, 13);
- UNIT_ASSERT_EQUAL(event->Blob, blob);
- UNIT_ASSERT_EQUAL((bool)handle->TraceId, true);
- UNIT_ASSERT(handle->TraceId.IsFromSameTree(sentTraceId));
- }
-
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ TString blob(100000, '@');
+ for (auto i = 0U; i < blob.size(); ++i)
+ const_cast<TString::value_type*>(blob.data())[i] =
+ TString::value_type(i % 256);
+
+ auto sentTraceId = NWilson::TTraceId::NewTraceId();
+
+ runtime.Send(new IEventHandle(edge, edge,
+ new TEvents::TEvBlob(blob),
+ 0, 13, nullptr, sentTraceId.Clone()),
+ 0);
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvents::TEvBlob>(handle);
+ UNIT_ASSERT_EQUAL(handle->Cookie, 13);
+ UNIT_ASSERT_EQUAL(event->Blob, blob);
+ UNIT_ASSERT_EQUAL((bool)handle->TraceId, true);
+ UNIT_ASSERT(handle->TraceId.IsFromSameTree(sentTraceId));
+ }
+
Y_UNIT_TEST(TestAddressResolve) {
TTestBasicRuntime runtime(2);
runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(0);
- auto event = new TEvResolveAddress;
+ const auto edge = runtime.AllocateEdgeActor(0);
+ auto event = new TEvResolveAddress;
event->Address = "localhost";
- event->Port = 80;
+ event->Port = 80;
runtime.Send(new IEventHandle(GetNameserviceActorId(), edge, event), 0);
- TAutoPtr<IEventHandle> handle;
- const auto reply = runtime.GrabEdgeEvent<TEvAddressInfo>(handle);
- UNIT_ASSERT_VALUES_EQUAL(NAddr::PrintHostAndPort(*reply->Address),
+ TAutoPtr<IEventHandle> handle;
+ const auto reply = runtime.GrabEdgeEvent<TEvAddressInfo>(handle);
+ UNIT_ASSERT_VALUES_EQUAL(NAddr::PrintHostAndPort(*reply->Address),
"[::1]:80");
- }
-
- Y_UNIT_TEST(TestEventWithPayloadSerialization) {
- struct TEvMessage : TEventPB<TEvMessage, TMessageWithPayload, 12345> {};
-
- TTestBasicRuntime runtime(2);
- runtime.Initialize(TAppPrepare().Unwrap());
- const auto edge = runtime.AllocateEdgeActor(1);
-
- for (size_t s1 = 0; s1 <= 100000; s1 = s1 * 2 + 1) {
- for (size_t s2 = 0; s2 <= 100000; s2 = s2 * 2 + 1) {
- Cerr << s1 << " " << s2 << Endl;
-
- auto makeRope = [](size_t size) {
- TRope res;
-
- while (size) {
- size_t chunkLen = RandomNumber(size) + 1;
- TString s = TString::Uninitialized(chunkLen);
- char *p = s.Detach();
- for (size_t k = 0; k < s.size(); ++k) {
- *p++ = RandomNumber<unsigned char>();
- }
- res.Insert(res.End(), TRope(std::move(s)));
- size -= chunkLen;
- }
-
- return res;
- };
-
- TRope rope1 = makeRope(s1);
- UNIT_ASSERT_VALUES_EQUAL(rope1.GetSize(), s1);
-
- TRope rope2 = makeRope(s2);
- UNIT_ASSERT_VALUES_EQUAL(rope2.GetSize(), s2);
-
- TString meta = Sprintf("%zu/%zu %s %s", s1, s2, rope1.DebugString().data(), rope2.DebugString().data());
-
- {
- auto msg = MakeHolder<TEvMessage>();
- msg->Record.SetMeta(meta);
- msg->Record.AddPayloadId(msg->AddPayload(TRope(rope1)));
- msg->Record.AddPayloadId(msg->AddPayload(TRope(rope2)));
+ }
+
+ Y_UNIT_TEST(TestEventWithPayloadSerialization) {
+ struct TEvMessage : TEventPB<TEvMessage, TMessageWithPayload, 12345> {};
+
+ TTestBasicRuntime runtime(2);
+ runtime.Initialize(TAppPrepare().Unwrap());
+ const auto edge = runtime.AllocateEdgeActor(1);
+
+ for (size_t s1 = 0; s1 <= 100000; s1 = s1 * 2 + 1) {
+ for (size_t s2 = 0; s2 <= 100000; s2 = s2 * 2 + 1) {
+ Cerr << s1 << " " << s2 << Endl;
+
+ auto makeRope = [](size_t size) {
+ TRope res;
+
+ while (size) {
+ size_t chunkLen = RandomNumber(size) + 1;
+ TString s = TString::Uninitialized(chunkLen);
+ char *p = s.Detach();
+ for (size_t k = 0; k < s.size(); ++k) {
+ *p++ = RandomNumber<unsigned char>();
+ }
+ res.Insert(res.End(), TRope(std::move(s)));
+ size -= chunkLen;
+ }
+
+ return res;
+ };
+
+ TRope rope1 = makeRope(s1);
+ UNIT_ASSERT_VALUES_EQUAL(rope1.GetSize(), s1);
+
+ TRope rope2 = makeRope(s2);
+ UNIT_ASSERT_VALUES_EQUAL(rope2.GetSize(), s2);
+
+ TString meta = Sprintf("%zu/%zu %s %s", s1, s2, rope1.DebugString().data(), rope2.DebugString().data());
+
+ {
+ auto msg = MakeHolder<TEvMessage>();
+ msg->Record.SetMeta(meta);
+ msg->Record.AddPayloadId(msg->AddPayload(TRope(rope1)));
+ msg->Record.AddPayloadId(msg->AddPayload(TRope(rope2)));
runtime.Send(new IEventHandle(edge, TActorId(), msg.Release()), 0);
- }
-
- TAutoPtr<IEventHandle> handle;
- const auto event = runtime.GrabEdgeEvent<TEvMessage>(handle);
- UNIT_ASSERT_VALUES_EQUAL(event->Record.GetMeta(), meta);
- UNIT_ASSERT_VALUES_EQUAL(event->Record.PayloadIdSize(), 2);
- UNIT_ASSERT_EQUAL(event->GetPayload(event->Record.GetPayloadId(0)), rope1);
- UNIT_ASSERT_EQUAL(event->GetPayload(event->Record.GetPayloadId(1)), rope2);
- }
- }
- }
-}
-
-}
+ }
+
+ TAutoPtr<IEventHandle> handle;
+ const auto event = runtime.GrabEdgeEvent<TEvMessage>(handle);
+ UNIT_ASSERT_VALUES_EQUAL(event->Record.GetMeta(), meta);
+ UNIT_ASSERT_VALUES_EQUAL(event->Record.PayloadIdSize(), 2);
+ UNIT_ASSERT_EQUAL(event->GetPayload(event->Record.GetPayloadId(0)), rope1);
+ UNIT_ASSERT_EQUAL(event->GetPayload(event->Record.GetPayloadId(1)), rope2);
+ }
+ }
+ }
+}
+
+}
diff --git a/ydb/core/actorlib_impl/ut/ya.make b/ydb/core/actorlib_impl/ut/ya.make
index f76d57807a3..3facc0e1ce1 100644
--- a/ydb/core/actorlib_impl/ut/ya.make
+++ b/ydb/core/actorlib_impl/ut/ya.make
@@ -29,9 +29,9 @@ PEERDIR(
SRCS(
actor_activity_ut.cpp
- actor_bootstrapped_ut.cpp
- actor_tracker_ut.cpp
- test_interconnect_ut.cpp
+ actor_bootstrapped_ut.cpp
+ actor_tracker_ut.cpp
+ test_interconnect_ut.cpp
test_protocols_ut.cpp
)
diff --git a/ydb/core/actorlib_impl/ya.make b/ydb/core/actorlib_impl/ya.make
index ba63f39617f..ae4688ccd6f 100644
--- a/ydb/core/actorlib_impl/ya.make
+++ b/ydb/core/actorlib_impl/ya.make
@@ -7,24 +7,24 @@ OWNER(
)
SRCS(
- actor_tracker.cpp
- actor_tracker.h
+ actor_tracker.cpp
+ actor_tracker.h
async_destroyer.h
connect_socket_protocol.cpp
connect_socket_protocol.h
- defs.h
- destruct_actor.h
+ defs.h
+ destruct_actor.h
http_request_protocol.h
- load_network.cpp
+ load_network.cpp
load_network.h
long_timer.cpp
long_timer.h
- mad_squirrel.cpp
+ mad_squirrel.cpp
mad_squirrel.h
melancholic_gopher.cpp
name_service_client_protocol.cpp
name_service_client_protocol.h
- node_identifier.cpp
+ node_identifier.cpp
node_identifier.h
proto_ready_actor.h
read_data_protocol.cpp
diff --git a/ydb/core/base/appdata.cpp b/ydb/core/base/appdata.cpp
index f9e517fc424..919409ed740 100644
--- a/ydb/core/base/appdata.cpp
+++ b/ydb/core/base/appdata.cpp
@@ -27,7 +27,7 @@ TAppData::TAppData(
, BusMonPage(nullptr)
, Icb(new TControlBoard())
, InFlightLimiterRegistry(new NGRpcService::TInFlightLimiterRegistry(Icb))
- , StaticBlobStorageConfig(new NKikimrBlobStorage::TNodeWardenServiceSet)
+ , StaticBlobStorageConfig(new NKikimrBlobStorage::TNodeWardenServiceSet)
, KikimrShouldContinue(kikimrShouldContinue)
{}
@@ -44,7 +44,7 @@ TAppData::TDefaultTabletTypes::TDefaultTabletTypes()
, Hive(TTabletTypes::Hive)
, SysViewProcessor(TTabletTypes::SysViewProcessor)
, ColumnShard(TTabletTypes::COLUMNSHARD)
- , TestShard(TTabletTypes::TestShard)
+ , TestShard(TTabletTypes::TestShard)
, SequenceShard(TTabletTypes::SequenceShard)
, ReplicationController(TTabletTypes::ReplicationController)
{
diff --git a/ydb/core/base/appdata.h b/ydb/core/base/appdata.h
index c666f7468c0..ea61fba9772 100644
--- a/ydb/core/base/appdata.h
+++ b/ydb/core/base/appdata.h
@@ -7,7 +7,7 @@
#include "nameservice.h"
#include "tablet_types.h"
#include "resource_profile.h"
-#include "event_filter.h"
+#include "event_filter.h"
#include <ydb/core/control/immediate_control_board_impl.h>
#include <ydb/core/grpc_services/grpc_helper.h>
@@ -100,7 +100,7 @@ struct TAppData {
TTabletTypes::EType Hive;
TTabletTypes::EType SysViewProcessor;
TTabletTypes::EType ColumnShard;
- TTabletTypes::EType TestShard;
+ TTabletTypes::EType TestShard;
TTabletTypes::EType SequenceShard;
TTabletTypes::EType ReplicationController;
@@ -129,7 +129,7 @@ struct TAppData {
TIntrusivePtr<NInterconnect::TPollerThreads> PollerThreads;
- THolder<NKikimrBlobStorage::TNodeWardenServiceSet> StaticBlobStorageConfig;
+ THolder<NKikimrBlobStorage::TNodeWardenServiceSet> StaticBlobStorageConfig;
THolder<NKikimrCms::TCmsConfig> DefaultCmsConfig;
NKikimrStream::TStreamingConfig StreamingConfig;
@@ -155,7 +155,7 @@ struct TAppData {
TVector<TString> DefaultUserSIDs;
TString AllAuthenticatedUsers;
TResourceProfilesPtr ResourceProfiles;
-
+
TProgramShouldContinue * const KikimrShouldContinue;
bool EnableIntrospection = true;
@@ -169,8 +169,8 @@ struct TAppData {
// Used to disable object deletion in schemeshard for cleanup tests
bool DisableSchemeShardCleanupOnDropForTest = false;
- TKikimrScopeId LocalScopeId;
-
+ TKikimrScopeId LocalScopeId;
+
TAppData(
ui32 sysPoolId, ui32 userPoolId, ui32 ioPoolId, ui32 batchPoolId,
TMap<TString, ui32> servicePools,
diff --git a/ydb/core/base/blobstorage.cpp b/ydb/core/base/blobstorage.cpp
index 60bef7f4dff..c2979fe27e8 100644
--- a/ydb/core/base/blobstorage.cpp
+++ b/ydb/core/base/blobstorage.cpp
@@ -44,35 +44,35 @@ bool operator<(const TPDiskCategory x, const TPDiskCategory y) {
return std::make_tuple(x.Type(), x.Kind()) < std::make_tuple(y.Type(), y.Kind());
}
-std::unique_ptr<TEvBlobStorage::TEvPutResult> TEvBlobStorage::TEvPut::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
- auto res = std::make_unique<TEvPutResult>(status, Id, TStorageStatusFlags(), groupId, 0.0f);
- res->ErrorReason = errorReason;
- return res;
-}
-
-std::unique_ptr<TEvBlobStorage::TEvGetResult> TEvBlobStorage::TEvGet::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
- auto res = std::make_unique<TEvGetResult>(status, QuerySize, groupId);
- for (ui32 i = 0; i < QuerySize; ++i) {
- const auto& from = Queries[i];
- auto& to = res->Responses[i];
- to.Status = status;
- to.Id = from.Id;
- to.Shift = from.Shift;
- to.RequestedSize = from.Size;
- }
- res->ErrorReason = errorReason;
- return res;
-}
-
-std::unique_ptr<TEvBlobStorage::TEvBlockResult> TEvBlobStorage::TEvBlock::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
- auto res = std::make_unique<TEvBlockResult>(status);
- res->ErrorReason = errorReason;
- return res;
-}
-
+std::unique_ptr<TEvBlobStorage::TEvPutResult> TEvBlobStorage::TEvPut::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
+ auto res = std::make_unique<TEvPutResult>(status, Id, TStorageStatusFlags(), groupId, 0.0f);
+ res->ErrorReason = errorReason;
+ return res;
+}
+
+std::unique_ptr<TEvBlobStorage::TEvGetResult> TEvBlobStorage::TEvGet::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
+ auto res = std::make_unique<TEvGetResult>(status, QuerySize, groupId);
+ for (ui32 i = 0; i < QuerySize; ++i) {
+ const auto& from = Queries[i];
+ auto& to = res->Responses[i];
+ to.Status = status;
+ to.Id = from.Id;
+ to.Shift = from.Shift;
+ to.RequestedSize = from.Size;
+ }
+ res->ErrorReason = errorReason;
+ return res;
+}
+
+std::unique_ptr<TEvBlobStorage::TEvBlockResult> TEvBlobStorage::TEvBlock::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
+ auto res = std::make_unique<TEvBlockResult>(status);
+ res->ErrorReason = errorReason;
+ return res;
+}
+
std::unique_ptr<TEvBlobStorage::TEvPatchResult> TEvBlobStorage::TEvPatch::MakeErrorResponse(
NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
auto res = std::make_unique<TEvPatchResult>(status, PatchedId, TStorageStatusFlags(), groupId, 0.0f);
@@ -87,34 +87,34 @@ std::unique_ptr<TEvBlobStorage::TEvInplacePatchResult> TEvBlobStorage::TEvInplac
return res;
}
-std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> TEvBlobStorage::TEvDiscover::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
- auto res = std::make_unique<TEvDiscoverResult>(status, MinGeneration, 0);
- res->ErrorReason = errorReason;
- return res;
-}
-
-std::unique_ptr<TEvBlobStorage::TEvRangeResult> TEvBlobStorage::TEvRange::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
- auto res = std::make_unique<TEvRangeResult>(status, From, To, groupId);
- res->ErrorReason = errorReason;
- return res;
-}
-
-std::unique_ptr<TEvBlobStorage::TEvCollectGarbageResult> TEvBlobStorage::TEvCollectGarbage::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
- auto res = std::make_unique<TEvCollectGarbageResult>(status, TabletId, RecordGeneration, PerGenerationCounter, Channel);
- res->ErrorReason = errorReason;
- return res;
-}
-
-std::unique_ptr<TEvBlobStorage::TEvStatusResult> TEvBlobStorage::TEvStatus::MakeErrorResponse(
- NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
- auto res = std::make_unique<TEvStatusResult>(status, TStorageStatusFlags());
- res->ErrorReason = errorReason;
- return res;
-}
-
+std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> TEvBlobStorage::TEvDiscover::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
+ auto res = std::make_unique<TEvDiscoverResult>(status, MinGeneration, 0);
+ res->ErrorReason = errorReason;
+ return res;
+}
+
+std::unique_ptr<TEvBlobStorage::TEvRangeResult> TEvBlobStorage::TEvRange::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 groupId) {
+ auto res = std::make_unique<TEvRangeResult>(status, From, To, groupId);
+ res->ErrorReason = errorReason;
+ return res;
+}
+
+std::unique_ptr<TEvBlobStorage::TEvCollectGarbageResult> TEvBlobStorage::TEvCollectGarbage::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
+ auto res = std::make_unique<TEvCollectGarbageResult>(status, TabletId, RecordGeneration, PerGenerationCounter, Channel);
+ res->ErrorReason = errorReason;
+ return res;
+}
+
+std::unique_ptr<TEvBlobStorage::TEvStatusResult> TEvBlobStorage::TEvStatus::MakeErrorResponse(
+ NKikimrProto::EReplyStatus status, const TString& errorReason, ui32 /*groupId*/) {
+ auto res = std::make_unique<TEvStatusResult>(status, TStorageStatusFlags());
+ res->ErrorReason = errorReason;
+ return res;
+}
+
};
template<>
diff --git a/ydb/core/base/blobstorage.h b/ydb/core/base/blobstorage.h
index a2faee326e5..d874ffd3244 100644
--- a/ydb/core/base/blobstorage.h
+++ b/ydb/core/base/blobstorage.h
@@ -15,7 +15,7 @@
#include <ydb/core/util/yverify_stream.h>
#include <ydb/library/wilson/wilson_event.h>
-
+
#include <library/cpp/lwtrace/shuttle.h>
#include <util/stream/str.h>
@@ -23,13 +23,13 @@
namespace NKikimr {
-static constexpr ui32 MaxProtobufSize = 67108000;
-static constexpr ui32 MaxVDiskBlobSize = 10 << 20; // 10 megabytes
+static constexpr ui32 MaxProtobufSize = 67108000;
+static constexpr ui32 MaxVDiskBlobSize = 10 << 20; // 10 megabytes
static constexpr ui64 MaxCollectGarbageFlagsPerMessage = 10000;
-
-static constexpr TDuration VDiskCooldownTimeout = TDuration::Seconds(15);
-static constexpr TDuration VDiskCooldownTimeoutOnProxy = TDuration::Seconds(12);
-
+
+static constexpr TDuration VDiskCooldownTimeout = TDuration::Seconds(15);
+static constexpr TDuration VDiskCooldownTimeoutOnProxy = TDuration::Seconds(12);
+
struct TStorageStatusFlags {
ui32 Raw = 0;
@@ -40,12 +40,12 @@ struct TStorageStatusFlags {
: Raw(raw)
{}
- TStorageStatusFlags(const TStorageStatusFlags&) = default;
- TStorageStatusFlags& operator =(const TStorageStatusFlags&) = default;
-
- friend bool operator ==(const TStorageStatusFlags& x, const TStorageStatusFlags& y) { return x.Raw == y.Raw; }
- friend bool operator !=(const TStorageStatusFlags& x, const TStorageStatusFlags& y) { return x.Raw != y.Raw; }
+ TStorageStatusFlags(const TStorageStatusFlags&) = default;
+ TStorageStatusFlags& operator =(const TStorageStatusFlags&) = default;
+ friend bool operator ==(const TStorageStatusFlags& x, const TStorageStatusFlags& y) { return x.Raw == y.Raw; }
+ friend bool operator !=(const TStorageStatusFlags& x, const TStorageStatusFlags& y) { return x.Raw != y.Raw; }
+
void Merge(ui32 raw) {
if (raw & ui32(NKikimrBlobStorage::StatusIsValid)) {
Raw |= (raw & (
@@ -53,10 +53,10 @@ struct TStorageStatusFlags {
| ui32(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove)
| ui32(NKikimrBlobStorage::StatusDiskSpaceYellowStop)
| ui32(NKikimrBlobStorage::StatusDiskSpaceOrange)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceRed)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceBlack)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceCyan)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)));
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceRed)
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceBlack)
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceCyan)
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)));
}
}
@@ -71,16 +71,16 @@ struct TStorageStatusFlags {
}
void Output(IOutputStream &out) const {
- out << "{"
- << ((Raw & NKikimrBlobStorage::StatusIsValid) ? " Valid" : "")
- << ((Raw & NKikimrBlobStorage::StatusDiskSpaceCyan) ? " Cyan" : "")
+ out << "{"
+ << ((Raw & NKikimrBlobStorage::StatusIsValid) ? " Valid" : "")
+ << ((Raw & NKikimrBlobStorage::StatusDiskSpaceCyan) ? " Cyan" : "")
<< ((Raw & NKikimrBlobStorage::StatusDiskSpaceLightYellowMove) ? " LightYellow" : "")
<< ((Raw & NKikimrBlobStorage::StatusDiskSpaceYellowStop) ? " Yellow" : "")
- << ((Raw & NKikimrBlobStorage::StatusDiskSpaceLightOrange) ? " LightOrange" : "")
- << ((Raw & NKikimrBlobStorage::StatusDiskSpaceOrange) ? " Orange" : "")
- << ((Raw & NKikimrBlobStorage::StatusDiskSpaceRed) ? " Red" : "")
- << ((Raw & NKikimrBlobStorage::StatusDiskSpaceBlack) ? " Black" : "")
- << " }";
+ << ((Raw & NKikimrBlobStorage::StatusDiskSpaceLightOrange) ? " LightOrange" : "")
+ << ((Raw & NKikimrBlobStorage::StatusDiskSpaceOrange) ? " Orange" : "")
+ << ((Raw & NKikimrBlobStorage::StatusDiskSpaceRed) ? " Red" : "")
+ << ((Raw & NKikimrBlobStorage::StatusDiskSpaceBlack) ? " Black" : "")
+ << " }";
}
};
@@ -409,36 +409,36 @@ inline ui32 GroupIDFromBlobStorageProxyID(TActorId actorId) {
return blobStorageGroup;
}
-inline IEventHandle *CreateEventForBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, ui64 cookie,
- NWilson::TTraceId traceId = {}) {
- std::unique_ptr<IEventBase> ptr(ev);
- const ui32 flags = NActors::IEventHandle::FlagTrackDelivery | NActors::IEventHandle::FlagForwardOnNondelivery;
- const TActorId nw = MakeBlobStorageNodeWardenID(sender.NodeId());
- auto *res = new IEventHandle(recipient, sender, ptr.get(), flags, cookie, &nw, std::move(traceId));
- ptr.release();
- return res;
-}
-
-inline IEventHandle *CreateEventForBSProxy(TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie, NWilson::TTraceId traceId = {}) {
- return CreateEventForBSProxy(sender, MakeBlobStorageProxyID(groupId), ev, cookie, std::move(traceId));
-}
-
-inline bool SendToBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
- return TActivationContext::Send(CreateEventForBSProxy(sender, recipient, ev, cookie, std::move(traceId)));
+inline IEventHandle *CreateEventForBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, ui64 cookie,
+ NWilson::TTraceId traceId = {}) {
+ std::unique_ptr<IEventBase> ptr(ev);
+ const ui32 flags = NActors::IEventHandle::FlagTrackDelivery | NActors::IEventHandle::FlagForwardOnNondelivery;
+ const TActorId nw = MakeBlobStorageNodeWardenID(sender.NodeId());
+ auto *res = new IEventHandle(recipient, sender, ptr.get(), flags, cookie, &nw, std::move(traceId));
+ ptr.release();
+ return res;
+}
+
+inline IEventHandle *CreateEventForBSProxy(TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie, NWilson::TTraceId traceId = {}) {
+ return CreateEventForBSProxy(sender, MakeBlobStorageProxyID(groupId), ev, cookie, std::move(traceId));
}
+inline bool SendToBSProxy(TActorId sender, TActorId recipient, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
+ return TActivationContext::Send(CreateEventForBSProxy(sender, recipient, ev, cookie, std::move(traceId)));
+}
+
inline bool SendToBSProxy(const TActorContext &ctx, TActorId recipient, IEventBase *ev, ui64 cookie = 0,
- NWilson::TTraceId traceId = {}) {
- return ctx.Send(CreateEventForBSProxy(ctx.SelfID, recipient, ev, cookie, std::move(traceId)));
+ NWilson::TTraceId traceId = {}) {
+ return ctx.Send(CreateEventForBSProxy(ctx.SelfID, recipient, ev, cookie, std::move(traceId)));
}
inline bool SendToBSProxy(TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
- return TActivationContext::Send(CreateEventForBSProxy(sender, groupId, ev, cookie, std::move(traceId)));
+ return TActivationContext::Send(CreateEventForBSProxy(sender, groupId, ev, cookie, std::move(traceId)));
}
-inline bool SendToBSProxy(const TActorContext &ctx, ui32 groupId, IEventBase *ev, ui64 cookie = 0,
- NWilson::TTraceId traceId = {}) {
- return ctx.Send(CreateEventForBSProxy(ctx.SelfID, groupId, ev, cookie, std::move(traceId)));
+inline bool SendToBSProxy(const TActorContext &ctx, ui32 groupId, IEventBase *ev, ui64 cookie = 0,
+ NWilson::TTraceId traceId = {}) {
+ return ctx.Send(CreateEventForBSProxy(ctx.SelfID, groupId, ev, cookie, std::move(traceId)));
}
struct TEvBlobStorage {
@@ -479,7 +479,7 @@ struct TEvBlobStorage {
EvVReadyNotify,
EvVStatus,
EvVDbStat,
- EvVCheckReadiness,
+ EvVCheckReadiness,
EvVCompact, /// 268 633 098
EvVMultiPut,
EvVMovedPatch,
@@ -498,7 +498,7 @@ struct TEvBlobStorage {
EvVStatusResult,
EvVDbStatResult,
EvVWindowChange,
- EvVCheckReadinessResult,
+ EvVCheckReadinessResult,
EvVCompactResult,
EvVMultiPutResult,
EvVMovedPatchResult,
@@ -523,8 +523,8 @@ struct TEvBlobStorage {
EvCnt = EvPut + 6 * 512, /// 268 635 136
EvVGenerationChange,
EvRegisterPDiskLoadActor,
- EvStatusUpdate,
- EvDropDonor,
+ EvStatusUpdate,
+ EvDropDonor,
EvCntReply = EvPut + 7 * 512, /// 268 635 648
EvVGenerationChangeResult,
@@ -549,7 +549,7 @@ struct TEvBlobStorage {
EvSyncLogCommitDone,
EvSyncLogSnapshot,
EvSyncLogReadFinished,
- EvSyncLogPutSst,
+ EvSyncLogPutSst,
EvChunkReserve,
EvSkeletonBackSyncLogID, /// 268 636 180
EvHullConfirmedLsn,
@@ -570,13 +570,13 @@ struct TEvBlobStorage {
EvHullHugeWritten,
EvHullDelayedResult,
EvHullCompSelected,
- EvHullReleaseSnapshot,
+ EvHullReleaseSnapshot,
EvSyncJobDone, /// 268 636 200
EvLocalSyncData,
EvVDiskCutLog,
EvRunRepl,
- EvRecoveredHugeBlob,
- EvDetectedPhantomBlob,
+ EvRecoveredHugeBlob,
+ EvDetectedPhantomBlob,
EvAddBulkSst,
EvReplProxyNext,
EvSyncLogGetLastLsn,
@@ -587,30 +587,30 @@ struct TEvBlobStorage {
EvHandoffSyncLogFinished,
EvVDiskRequestCompleted,
EvFrontRecoveryStatus,
- EvPruneQueue,
+ EvPruneQueue,
EvPDiskFairSchedulerWake,
EvVDiskGuidObtained,
EvCompactionFinished,
EvKickEmergencyPutQueue, /// 268 636 220
EvWakeupEmergencyPutQueue,
EvTimeToUpdateWhiteboard,
- EvBulkSstsLoaded,
+ EvBulkSstsLoaded,
EvVDiskGuidWritten,
EvSyncerCommit,
EvSyncerCommitDone,
EvVDiskGuidRecovered,
- EvQueryReplToken,
- EvReplToken,
+ EvQueryReplToken,
+ EvReplToken,
EvReleaseReplToken, /// 268 636 230
- OBSOLETE_EvQueryReplDataToken,
- OBSOLETE_EvReplDataToken,
- EvQueryReplMemToken,
- EvReplMemToken,
- EvUpdateReplMemToken,
- EvReleaseReplMemToken,
+ OBSOLETE_EvQueryReplDataToken,
+ OBSOLETE_EvReplDataToken,
+ EvQueryReplMemToken,
+ EvReplMemToken,
+ EvUpdateReplMemToken,
+ EvReleaseReplMemToken,
EvSyncerCommitProxyDone,
EvSyncerNeedFullRecovery,
- EvThroughputUpdate,
+ EvThroughputUpdate,
EvThroughputAddRequest, /// 268 636 240
EvSyncerLostDataRecovered,
EvSyncerGuidFirstRunDone,
@@ -642,25 +642,25 @@ struct TEvBlobStorage {
EvPDiskFormattingFinished,
EvRecoveryLogReplayDone,
EvMonStreamQuery, // 268 636 270
- EvMonStreamActorDeathNote,
+ EvMonStreamActorDeathNote,
EvPDiskErrorStateChange,
EvMultiLog,
EvVMultiPutItemResult,
- EvEnrichNotYet,
- EvCommenceRepl, // for debugging purposes
- EvRecoverBlob,
- EvRecoverBlobResult,
- EvScrubAwait, // for debugging purposes
+ EvEnrichNotYet,
+ EvCommenceRepl, // for debugging purposes
+ EvRecoverBlob,
+ EvRecoverBlobResult,
+ EvScrubAwait, // for debugging purposes
EvScrubNotify, // 268 636 280
EvDefragQuantumResult,
- EvDefragStartQuantum,
- EvReportScrubStatus,
- EvRestoreCorruptedBlob,
- EvRestoreCorruptedBlobResult,
- EvCaptureVDiskLayout, // for debugging purposes
- EvCaptureVDiskLayoutResult,
- OBSOLETE_EvTriggerCompaction,
- OBSOLETE_EvTriggerCompactionResult,
+ EvDefragStartQuantum,
+ EvReportScrubStatus,
+ EvRestoreCorruptedBlob,
+ EvRestoreCorruptedBlobResult,
+ EvCaptureVDiskLayout, // for debugging purposes
+ EvCaptureVDiskLayoutResult,
+ OBSOLETE_EvTriggerCompaction,
+ OBSOLETE_EvTriggerCompactionResult,
EvHullCompact, // 268 636 290
EvHullCompactResult,
EvCompactVDisk,
@@ -668,10 +668,10 @@ struct TEvBlobStorage {
EvDefragRewritten,
EvVPatchDyingRequest,
EvVPatchDyingConfirm,
- EvNonrestoredCorruptedBlobNotify,
+ EvNonrestoredCorruptedBlobNotify,
EvHugeLockChunks,
EvHugeStat,
- EvForwardToSkeleton,
+ EvForwardToSkeleton,
EvYardInitResult = EvPut + 9 * 512, /// 268 636 672
EvLogResult,
@@ -690,7 +690,7 @@ struct TEvBlobStorage {
EvReadFormatResult,
EvReplStarted,
EvReplFinished,
- EvReplPlanFinished,
+ EvReplPlanFinished,
EvReplProxyNextResult,
EvSyncLogGetLastLsnResult,
EvLocalStatusResult, /// 268 636 692
@@ -710,8 +710,8 @@ struct TEvBlobStorage {
EvLogCommitDone,
EvSyncLogLocalStatus,
EvSyncLogLocalStatusResult,
- EvReplResume,
- EvReplDone,
+ EvReplResume,
+ EvReplDone,
EvFreshAppendixCompactionDone,
EvDeviceError,
EvHugeLockChunksResult,
@@ -724,73 +724,73 @@ struct TEvBlobStorage {
EvNotReadyRetryTimeout,
EvConfigureQueryTimeout,
EvEstablishingSessionTimeout,
- EvDeathNote, /// 268 637 191
+ EvDeathNote, /// 268 637 191
EvVDiskStateChanged,
EvAccelerate,
- EvUnusedLocal4, /// 268 637 194
+ EvUnusedLocal4, /// 268 637 194
EvProxyQueueState,
- EvAbortOperation,
+ EvAbortOperation,
EvResume,
- EvTimeStats,
+ EvTimeStats,
EvOverseerRequest, // Not used
EvOverseerLogLastLsn, // Not used
EvOverseerConfirm, // Not used
- EvLatencyReport,
- EvGroupStatReport,
+ EvLatencyReport,
+ EvGroupStatReport,
EvAccelerateGet,
EvAcceleratePut,
EvRequestProxyQueueState,
EvRequestProxySessionsState,
EvProxySessionsState,
- EvBunchOfEvents,
+ EvBunchOfEvents,
// blobstorage controller interface
- // EvControllerReadSchemeString = EvPut + 11 * 512,
- // EvControllerReadDataString,
- EvControllerRegisterNode = EvPut + 11 * 512 + 2,
+ // EvControllerReadSchemeString = EvPut + 11 * 512,
+ // EvControllerReadDataString,
+ EvControllerRegisterNode = EvPut + 11 * 512 + 2,
EvControllerCreatePDisk,
EvControllerCreateVDiskSlots,
EvControllerCreateGroup,
EvControllerSelectGroups,
EvControllerGetGroup,
- EvControllerUpdateDiskStatus,
- EvControllerUpdateGroupsUsage, // Not used.
- EvControllerConfigRequest,
- EvControllerConfigResponse,
- EvControllerProposeRequest,
- EvControllerProposeResponse,
- EvControllerVDiskStatusSubscribeRequest,
- EvControllerVDiskStatusReport,
- EvControllerGroupStatusRequest,
- EvControllerGroupStatusResponse,
- EvControllerUpdateGroup,
- EvControllerUpdateFaultyDisks,
+ EvControllerUpdateDiskStatus,
+ EvControllerUpdateGroupsUsage, // Not used.
+ EvControllerConfigRequest,
+ EvControllerConfigResponse,
+ EvControllerProposeRequest,
+ EvControllerProposeResponse,
+ EvControllerVDiskStatusSubscribeRequest,
+ EvControllerVDiskStatusReport,
+ EvControllerGroupStatusRequest,
+ EvControllerGroupStatusResponse,
+ EvControllerUpdateGroup,
+ EvControllerUpdateFaultyDisks,
EvControllerProposeGroupKey,
- EvControllerUpdateGroupLatencies, // Not used.
- EvControllerUpdateGroupStat,
- EvControllerNotifyGroupChange,
- EvControllerCommitGroupLatencies,
- EvControllerUpdateSelfHealInfo,
- EvControllerScrubQueryStartQuantum,
- EvControllerScrubQuantumFinished,
- EvControllerScrubReportQuantumInProgress,
+ EvControllerUpdateGroupLatencies, // Not used.
+ EvControllerUpdateGroupStat,
+ EvControllerNotifyGroupChange,
+ EvControllerCommitGroupLatencies,
+ EvControllerUpdateSelfHealInfo,
+ EvControllerScrubQueryStartQuantum,
+ EvControllerScrubQuantumFinished,
+ EvControllerScrubReportQuantumInProgress,
EvControllerUpdateNodeDrives,
- // EvControllerReadSchemeStringResult = EvPut + 12 * 512,
- // EvControllerReadDataStringResult,
- EvControllerNodeServiceSetUpdate = EvPut + 12 * 512 + 2,
+ // EvControllerReadSchemeStringResult = EvPut + 12 * 512,
+ // EvControllerReadDataStringResult,
+ EvControllerNodeServiceSetUpdate = EvPut + 12 * 512 + 2,
EvControllerCreatePDiskResult,
EvControllerCreateVDiskSlotsResult,
EvControllerCreateGroupResult,
EvControllerSelectGroupsResult,
EvRequestControllerInfo,
EvResponseControllerInfo,
- EvControllerGroupReconfigureReplace, // Not used.
- EvControllerGroupReconfigureReplaceResult, // Not used.
+ EvControllerGroupReconfigureReplace, // Not used.
+ EvControllerGroupReconfigureReplaceResult, // Not used.
EvControllerGroupReconfigureWipe,
EvControllerGroupReconfigureWipeResult,
EvControllerNodeReport,
- EvControllerScrubStartQuantum,
+ EvControllerScrubStartQuantum,
EvControllerMigrationPause,
EvControllerMigrationContinue,
@@ -803,61 +803,61 @@ struct TEvBlobStorage {
// proxy - node controller interface
EvConfigureProxy = EvPut + 13 * 512,
- EvProxyConfigurationRequest, // DEPRECATED
- EvUpdateGroupInfo,
- EvNotifyVDiskGenerationChange, // DEPRECATED
+ EvProxyConfigurationRequest, // DEPRECATED
+ EvUpdateGroupInfo,
+ EvNotifyVDiskGenerationChange, // DEPRECATED
// node controller internal messages
EvRegisterNodeRetry = EvPut + 14 * 512,
EvAskRestartPDisk,
EvRestartPDisk,
EvRestartPDiskResult,
- EvNodeWardenQueryGroupInfo,
- EvNodeWardenGroupInfo,
+ EvNodeWardenQueryGroupInfo,
+ EvNodeWardenGroupInfo,
// Other
EvRunActor = EvPut + 15 * 512,
- EvVMockCtlRequest,
- EvVMockCtlResponse,
-
- // load actor control
- EvTestLoadRequest = EvPut + 16 * 512,
- EvTestLoadFinished,
- EvTestLoadResponse,
-
- // incremental huge blob keeper
- EvIncrHugeInit = EvPut + 17 * 512,
- EvIncrHugeInitResult,
- EvIncrHugeWrite,
- EvIncrHugeWriteResult,
- EvIncrHugeRead,
- EvIncrHugeReadResult,
- EvIncrHugeDelete,
- EvIncrHugeDeleteResult,
- EvIncrHugeHarakiri,
- EvIncrHugeHarakiriResult,
- EvIncrHugeCallback,
- EvIncrHugeControlDefrag,
-
- EvIncrHugeReadLogResult,
- EvIncrHugeScanResult,
-
+ EvVMockCtlRequest,
+ EvVMockCtlResponse,
+
+ // load actor control
+ EvTestLoadRequest = EvPut + 16 * 512,
+ EvTestLoadFinished,
+ EvTestLoadResponse,
+
+ // incremental huge blob keeper
+ EvIncrHugeInit = EvPut + 17 * 512,
+ EvIncrHugeInitResult,
+ EvIncrHugeWrite,
+ EvIncrHugeWriteResult,
+ EvIncrHugeRead,
+ EvIncrHugeReadResult,
+ EvIncrHugeDelete,
+ EvIncrHugeDeleteResult,
+ EvIncrHugeHarakiri,
+ EvIncrHugeHarakiriResult,
+ EvIncrHugeCallback,
+ EvIncrHugeControlDefrag,
+
+ EvIncrHugeReadLogResult,
+ EvIncrHugeScanResult,
+
EvEnd
};
static_assert(EvEnd < EventSpaceEnd(TKikimrEvents::ES_BLOBSTORAGE),
"expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_BLOBSTORAGE)");
- struct TEvPutResult;
- struct TEvGetResult;
- struct TEvBlockResult;
- struct TEvDiscoverResult;
- struct TEvRangeResult;
- struct TEvCollectGarbageResult;
- struct TEvStatusResult;
+ struct TEvPutResult;
+ struct TEvGetResult;
+ struct TEvBlockResult;
+ struct TEvDiscoverResult;
+ struct TEvRangeResult;
+ struct TEvCollectGarbageResult;
+ struct TEvStatusResult;
struct TEvPatchResult;
struct TEvInplacePatchResult;
-
+
struct TEvPut : public TEventLocal<TEvPut, EvPut> {
enum ETactic {
TacticMaxThroughput = 0,
@@ -884,7 +884,7 @@ struct TEvBlobStorage {
const NKikimrBlobStorage::EPutHandleClass HandleClass;
const ETactic Tactic;
mutable NLWTrace::TOrbit Orbit;
- ui32 RestartCounter = 0;
+ ui32 RestartCounter = 0;
TEvPut(const TLogoBlobID &id, const TString &buffer, TInstant deadline,
NKikimrBlobStorage::EPutHandleClass handleClass = NKikimrBlobStorage::TabletLog,
@@ -897,7 +897,7 @@ struct TEvBlobStorage {
{
Y_VERIFY(Id, "EvPut invalid: LogoBlobId must have non-zero tablet field, id# %s", Id.ToString().c_str());
Y_VERIFY(buffer.size() < (40 * 1024 * 1024),
- "EvPut invalid: LogoBlobId# %s buffer.Size# %zu",
+ "EvPut invalid: LogoBlobId# %s buffer.Size# %zu",
id.ToString().data(), buffer.size());
Y_VERIFY(buffer.size() == id.BlobSize(),
"EvPut invalid: LogoBlobId# %s buffer.Size# %zu",
@@ -926,13 +926,13 @@ struct TEvBlobStorage {
TString ToString() const {
return Print(false);
}
-
- ui32 CalculateSize() const {
- return sizeof(*this) + Buffer.capacity();
- }
-
- std::unique_ptr<TEvPutResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this) + Buffer.capacity();
+ }
+
+ std::unique_ptr<TEvPutResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvPutResult : public TEventLocal<TEvPutResult, EvPutResult> {
@@ -1005,7 +1005,7 @@ struct TEvBlobStorage {
};
// todo: replace with queue-like thing
- const ui32 QuerySize;
+ const ui32 QuerySize;
TArrayHolder<TQuery> Queries;
TInstant Deadline;
bool MustRestoreFirst;
@@ -1015,34 +1015,34 @@ struct TEvBlobStorage {
bool AcquireBlockedGeneration = false; // get the blocked generation along with the blobs
bool IsIndexOnly;
bool IsVerboseNoDataEnabled; // Debug use only
- bool IsInternal = false; // set to true if generated by ds proxy
- bool CollectDebugInfo = false; // collect query debug info and return in response
+ bool IsInternal = false; // set to true if generated by ds proxy
+ bool CollectDebugInfo = false; // collect query debug info and return in response
ui32 ForceBlockedGeneration = 0;
- bool ReportDetailedPartMap = false;
- ui32 RestartCounter = 0;
- bool PhantomCheck = false;
+ bool ReportDetailedPartMap = false;
+ ui32 RestartCounter = 0;
+ bool PhantomCheck = false;
// NKikimrBlobStorage::EGetHandleClass::FastRead
- TEvGet(TArrayHolder<TQuery> &q, ui32 sz, TInstant deadline, NKikimrBlobStorage::EGetHandleClass getHandleClass,
- bool mustRestoreFirst = false, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0,
- bool isInternal = false, bool isVerboseNoDataEnabled = false, bool collectDebugInfo = false,
- bool reportDetailedPartMap = false)
+ TEvGet(TArrayHolder<TQuery> &q, ui32 sz, TInstant deadline, NKikimrBlobStorage::EGetHandleClass getHandleClass,
+ bool mustRestoreFirst = false, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0,
+ bool isInternal = false, bool isVerboseNoDataEnabled = false, bool collectDebugInfo = false,
+ bool reportDetailedPartMap = false)
: QuerySize(sz)
, Queries(q.Release())
, Deadline(deadline)
, MustRestoreFirst(mustRestoreFirst)
, GetHandleClass(getHandleClass)
, IsIndexOnly(isIndexOnly)
- , IsVerboseNoDataEnabled(isVerboseNoDataEnabled)
- , IsInternal(isInternal)
- , CollectDebugInfo(collectDebugInfo)
+ , IsVerboseNoDataEnabled(isVerboseNoDataEnabled)
+ , IsInternal(isInternal)
+ , CollectDebugInfo(collectDebugInfo)
, ForceBlockedGeneration(forceBlockedGeneration)
- , ReportDetailedPartMap(reportDetailedPartMap)
- {
- Y_VERIFY(QuerySize > 0, "can't execute empty get queries");
+ , ReportDetailedPartMap(reportDetailedPartMap)
+ {
+ Y_VERIFY(QuerySize > 0, "can't execute empty get queries");
VerifySameTabletId();
- }
+ }
TEvGet(const TLogoBlobID &id, ui32 shift, ui32 size, TInstant deadline,
NKikimrBlobStorage::EGetHandleClass getHandleClass,
@@ -1095,13 +1095,13 @@ struct TEvBlobStorage {
return Print(false);
}
- ui32 CalculateSize() const {
- return sizeof(*this) + QuerySize * sizeof(TQuery);
- }
-
- std::unique_ptr<TEvGetResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
-
+ ui32 CalculateSize() const {
+ return sizeof(*this) + QuerySize * sizeof(TQuery);
+ }
+
+ std::unique_ptr<TEvGetResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
+
private:
void VerifySameTabletId() const {
for (ui32 i = 1; i < QuerySize; ++i) {
@@ -1113,13 +1113,13 @@ struct TEvBlobStorage {
};
struct TEvGetResult : public TEventLocal<TEvGetResult, EvGetResult> {
- struct TPartMapItem {
- ui32 DiskOrderNumber;
- ui32 PartIdRequested;
- ui32 RequestIndex;
- ui32 ResponseIndex;
- TVector<std::pair<ui32, NKikimrProto::EReplyStatus>> Status;
- };
+ struct TPartMapItem {
+ ui32 DiskOrderNumber;
+ ui32 PartIdRequested;
+ ui32 RequestIndex;
+ ui32 ResponseIndex;
+ TVector<std::pair<ui32, NKikimrProto::EReplyStatus>> Status;
+ };
struct TResponse {
NKikimrProto::EReplyStatus Status;
@@ -1127,7 +1127,7 @@ struct TEvBlobStorage {
ui32 Shift;
ui32 RequestedSize;
TString Buffer;
- TVector<TPartMapItem> PartMap;
+ TVector<TPartMapItem> PartMap;
TResponse()
: Status(NKikimrProto::UNKNOWN)
@@ -1143,7 +1143,7 @@ struct TEvBlobStorage {
TArrayHolder<TResponse> Responses;
const ui32 GroupId;
ui32 BlockedGeneration = 0; // valid only for requests with non-zero TabletId and true AcquireBlockedGeneration.
- TString DebugInfo;
+ TString DebugInfo;
TString ErrorReason;
mutable NLWTrace::TOrbit Orbit;
@@ -1163,8 +1163,8 @@ struct TEvBlobStorage {
str << " ResponseSz# " << ResponseSz;
for (ui32 i = 0; i < ResponseSz; ++i) {
TResponse &response = Responses[i];
- str << " {" << response.Id.ToString();
- str << " " << NKikimrProto::EReplyStatus_Name(response.Status).data();
+ str << " {" << response.Id.ToString();
+ str << " " << NKikimrProto::EReplyStatus_Name(response.Status).data();
if (response.Shift) {
str << " Shift# " << response.Shift;
}
@@ -1204,9 +1204,9 @@ struct TEvBlobStorage {
const ui64 TabletId;
const ui32 Generation;
const TInstant Deadline;
- const ui64 IssuerGuid = RandomNumber<ui64>() | 1;
+ const ui64 IssuerGuid = RandomNumber<ui64>() | 1;
bool IsMonitored = true;
- ui32 RestartCounter = 0;
+ ui32 RestartCounter = 0;
TEvBlock(ui64 tabletId, ui32 generation, TInstant deadline)
: TabletId(tabletId)
@@ -1214,13 +1214,13 @@ struct TEvBlobStorage {
, Deadline(deadline)
{}
- TEvBlock(ui64 tabletId, ui32 generation, TInstant deadline, ui64 issuerGuid)
- : TabletId(tabletId)
- , Generation(generation)
- , Deadline(deadline)
- , IssuerGuid(issuerGuid)
- {}
-
+ TEvBlock(ui64 tabletId, ui32 generation, TInstant deadline, ui64 issuerGuid)
+ : TabletId(tabletId)
+ , Generation(generation)
+ , Deadline(deadline)
+ , IssuerGuid(issuerGuid)
+ {}
+
TString Print(bool isFull) const {
Y_UNUSED(isFull);
TStringStream str;
@@ -1235,13 +1235,13 @@ struct TEvBlobStorage {
TString ToString() const {
return Print(false);
}
-
- ui32 CalculateSize() const {
- return sizeof(*this);
- }
-
- std::unique_ptr<TEvBlockResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this);
+ }
+
+ std::unique_ptr<TEvBlockResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvBlockResult : public TEventLocal<TEvBlockResult, EvBlockResult> {
@@ -1564,7 +1564,7 @@ struct TEvBlobStorage {
const bool ReadBody;
const bool DiscoverBlockedGeneration;
const ui32 ForceBlockedGeneration;
- ui32 RestartCounter = 0;
+ ui32 RestartCounter = 0;
TEvDiscover(ui64 tabletId, ui32 minGeneration, bool readBody, bool discoverBlockedGeneration, TInstant deadline, ui32 forceBlockedGeneration)
: TabletId(tabletId)
@@ -1590,13 +1590,13 @@ struct TEvBlobStorage {
TString ToString() const {
return Print(false);
}
-
- ui32 CalculateSize() const {
- return sizeof(*this);
- }
-
- std::unique_ptr<TEvDiscoverResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this);
+ }
+
+ std::unique_ptr<TEvDiscoverResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvDiscoverResult : public TEventLocal<TEvDiscoverResult, EvDiscoverResult> {
@@ -1660,9 +1660,9 @@ struct TEvBlobStorage {
TLogoBlobID To;
const TInstant Deadline;
bool MustRestoreFirst;
- bool IsIndexOnly;
+ bool IsIndexOnly;
ui32 ForceBlockedGeneration;
- ui32 RestartCounter = 0;
+ ui32 RestartCounter = 0;
TEvRange(ui64 tabletId, const TLogoBlobID &from, const TLogoBlobID &to, const bool mustRestoreFirst,
TInstant deadline, bool isIndexOnly = false, ui32 forceBlockedGeneration = 0)
@@ -1671,7 +1671,7 @@ struct TEvBlobStorage {
, To(to)
, Deadline(deadline)
, MustRestoreFirst(mustRestoreFirst)
- , IsIndexOnly(isIndexOnly)
+ , IsIndexOnly(isIndexOnly)
, ForceBlockedGeneration(forceBlockedGeneration)
{}
@@ -1692,13 +1692,13 @@ struct TEvBlobStorage {
TString ToString() const {
return Print(false);
}
-
- ui32 CalculateSize() const {
- return sizeof(*this);
- }
-
- std::unique_ptr<TEvRangeResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this);
+ }
+
+ std::unique_ptr<TEvRangeResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvRangeResult : public TEventLocal<TEvRangeResult, EvRangeResult> {
@@ -1738,7 +1738,7 @@ struct TEvBlobStorage {
str << " Size# " << Responses.size();
for (ui32 i = 0; i < Responses.size(); ++i) {
const TResponse &response = Responses[i];
- str << " {" << response.Id.ToString();
+ str << " {" << response.Id.ToString();
str << " Size# " << response.Buffer.size();
if (isFull) {
str << " Buffer# " << response.Buffer.Quote();
@@ -1769,22 +1769,22 @@ struct TEvBlobStorage {
ui32 CollectGeneration;
ui32 CollectStep;
-
- // if set to true, this barrier does not take keep flags into account and is treated separately from soft barriers;
- // this means that all data before the hard barrier is destroyed without taking keep flags into account
- bool Hard;
-
+
+ // if set to true, this barrier does not take keep flags into account and is treated separately from soft barriers;
+ // this means that all data before the hard barrier is destroyed without taking keep flags into account
+ bool Hard;
+
bool Collect;
bool IsMultiCollectAllowed;
bool IsMonitored = true;
- ui32 RestartCounter = 0;
-
+ ui32 RestartCounter = 0;
+
TEvCollectGarbage(ui64 tabletId, ui32 recordGeneration, ui32 perGenerationCounter, ui32 channel,
bool collect, ui32 collectGeneration,
ui32 collectStep, TVector<TLogoBlobID> *keep, TVector<TLogoBlobID> *doNotKeep, TInstant deadline,
- bool isMultiCollectAllowed, bool hard = false)
+ bool isMultiCollectAllowed, bool hard = false)
: TabletId(tabletId)
, RecordGeneration(recordGeneration)
, PerGenerationCounter(perGenerationCounter)
@@ -1794,7 +1794,7 @@ struct TEvBlobStorage {
, Deadline(deadline)
, CollectGeneration(collectGeneration)
, CollectStep(collectStep)
- , Hard(hard)
+ , Hard(hard)
, Collect(collect)
, IsMultiCollectAllowed(isMultiCollectAllowed)
{}
@@ -1810,18 +1810,18 @@ struct TEvBlobStorage {
, Deadline(deadline)
, CollectGeneration(collectGeneration)
, CollectStep(collectStep)
- , Hard(false)
+ , Hard(false)
, Collect(collect)
, IsMultiCollectAllowed(true)
{}
- static THolder<TEvCollectGarbage> CreateHardBarrier(ui64 tabletId, ui32 recordGeneration,
- ui32 perGenerationCounter, ui32 channel, ui32 collectGeneration, ui32 collectStep, TInstant deadline) {
- return MakeHolder<TEvCollectGarbage>(tabletId, recordGeneration, perGenerationCounter, channel,
- true /*collect*/, collectGeneration, collectStep, nullptr /*keep*/, nullptr /*doNotKeep*/,
- deadline, false /*isMultiCollectAllowed*/, true /*hard*/);
- }
-
+ static THolder<TEvCollectGarbage> CreateHardBarrier(ui64 tabletId, ui32 recordGeneration,
+ ui32 perGenerationCounter, ui32 channel, ui32 collectGeneration, ui32 collectStep, TInstant deadline) {
+ return MakeHolder<TEvCollectGarbage>(tabletId, recordGeneration, perGenerationCounter, channel,
+ true /*collect*/, collectGeneration, collectStep, nullptr /*keep*/, nullptr /*doNotKeep*/,
+ deadline, false /*isMultiCollectAllowed*/, true /*hard*/);
+ }
+
TString Print(bool isFull) const {
Y_UNUSED(isFull);
TStringStream str;
@@ -1835,7 +1835,7 @@ struct TEvBlobStorage {
str << " CollectGeneration# " << CollectGeneration;
str << " CollectStep# " << CollectStep;
}
- str << " Hard# " << (Hard ? "true" : "false");
+ str << " Hard# " << (Hard ? "true" : "false");
str << " IsMultiCollectAllowed# " << IsMultiCollectAllowed;
str << " IsMonitored# " << IsMonitored;
if (Keep.Get()) {
@@ -1872,13 +1872,13 @@ struct TEvBlobStorage {
ui64 PerGenerationCounterStepSize() const {
return PerGenerationCounterStepSize(Keep.Get(), DoNotKeep.Get());
}
-
- ui32 CalculateSize() const {
- return sizeof(*this) + ((Keep ? Keep->size() : 0) + (DoNotKeep ? DoNotKeep->size() : 0)) * sizeof(TLogoBlobID);
- }
-
- std::unique_ptr<TEvCollectGarbageResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this) + ((Keep ? Keep->size() : 0) + (DoNotKeep ? DoNotKeep->size() : 0)) * sizeof(TLogoBlobID);
+ }
+
+ std::unique_ptr<TEvCollectGarbageResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvCollectGarbageResult : public TEventLocal<TEvCollectGarbageResult, EvCollectGarbageResult> {
@@ -1921,7 +1921,7 @@ struct TEvBlobStorage {
struct TEvStatus : public TEventLocal<TEvStatus, EvStatus> {
const TInstant Deadline;
- ui32 RestartCounter = 0;
+ ui32 RestartCounter = 0;
TEvStatus(TInstant deadline)
: Deadline(deadline)
@@ -1938,13 +1938,13 @@ struct TEvBlobStorage {
TString ToString() const {
return Print(false);
}
-
- ui32 CalculateSize() const {
- return sizeof(*this);
- }
-
- std::unique_ptr<TEvStatusResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
- ui32 groupId);
+
+ ui32 CalculateSize() const {
+ return sizeof(*this);
+ }
+
+ std::unique_ptr<TEvStatusResult> MakeErrorResponse(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ ui32 groupId);
};
struct TEvStatusResult : public TEventLocal<TEvStatusResult, EvStatusResult> {
@@ -1976,7 +1976,7 @@ struct TEvBlobStorage {
};
struct TEvConfigureProxy;
- struct TEvUpdateGroupInfo;
+ struct TEvUpdateGroupInfo;
struct TEvVMovedPatch;
struct TEvVMovedPatchResult;
@@ -2014,8 +2014,8 @@ struct TEvBlobStorage {
struct EvVBaldSyncLogResult;
struct TEvVDbStat;
struct TEvVDbStatResult;
- struct TEvVCheckReadiness;
- struct TEvVCheckReadinessResult;
+ struct TEvVCheckReadiness;
+ struct TEvVCheckReadinessResult;
struct TEvVCompact;
struct TEvVCompactResult;
struct TEvVBaldSyncLog;
@@ -2024,9 +2024,9 @@ struct TEvBlobStorage {
struct TEvLocalRecoveryDone;
struct THullChange;
struct TEvVReadyNotify;
- struct TEvEnrichNotYet;
- struct TEvCaptureVDiskLayout;
- struct TEvCaptureVDiskLayoutResult;
+ struct TEvEnrichNotYet;
+ struct TEvCaptureVDiskLayout;
+ struct TEvCaptureVDiskLayoutResult;
struct TEvVDefrag;
struct TEvVDefragResult;
@@ -2034,31 +2034,31 @@ struct TEvBlobStorage {
struct TEvControllerRegisterNode;
struct TEvControllerSelectGroups;
struct TEvControllerGetGroup;
- struct TEvControllerUpdateDiskStatus;
- struct TEvControllerUpdateGroupStat;
+ struct TEvControllerUpdateDiskStatus;
+ struct TEvControllerUpdateGroupStat;
struct TEvControllerUpdateNodeDrives;
- struct TEvControllerNodeServiceSetUpdate;
+ struct TEvControllerNodeServiceSetUpdate;
struct TEvControllerProposeGroupKey;
struct TEvControllerSelectGroupsResult;
struct TEvControllerGroupReconfigureWipe;
struct TEvControllerGroupReconfigureWipeResult;
struct TEvControllerNodeReport;
- struct TEvControllerConfigRequest;
- struct TEvControllerConfigResponse;
- struct TEvControllerScrubQueryStartQuantum;
- struct TEvControllerScrubStartQuantum;
- struct TEvControllerScrubQuantumFinished;
- struct TEvControllerScrubReportQuantumInProgress;
+ struct TEvControllerConfigRequest;
+ struct TEvControllerConfigResponse;
+ struct TEvControllerScrubQueryStartQuantum;
+ struct TEvControllerScrubStartQuantum;
+ struct TEvControllerScrubQuantumFinished;
+ struct TEvControllerScrubReportQuantumInProgress;
struct TEvRequestControllerInfo;
struct TEvResponseControllerInfo;
- struct TEvTestLoadRequest;
- struct TEvTestLoadResponse;
-
- struct TEvMonStreamQuery;
- struct TEvMonStreamActorDeathNote;
-
- struct TEvDropDonor;
- struct TEvBunchOfEvents;
+ struct TEvTestLoadRequest;
+ struct TEvTestLoadResponse;
+
+ struct TEvMonStreamQuery;
+ struct TEvMonStreamActorDeathNote;
+
+ struct TEvDropDonor;
+ struct TEvBunchOfEvents;
struct TEvAskRestartPDisk;
struct TEvRestartPDisk;
@@ -2086,8 +2086,8 @@ static inline NKikimrBlobStorage::EVDiskQueueId HandleClassToQueueId(NKikimrBlob
return NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead;
case NKikimrBlobStorage::EGetHandleClass::FastRead:
return NKikimrBlobStorage::EVDiskQueueId::GetFastRead;
- case NKikimrBlobStorage::EGetHandleClass::Discover:
- return NKikimrBlobStorage::EVDiskQueueId::GetDiscover;
+ case NKikimrBlobStorage::EGetHandleClass::Discover:
+ return NKikimrBlobStorage::EVDiskQueueId::GetDiscover;
case NKikimrBlobStorage::EGetHandleClass::LowRead:
return NKikimrBlobStorage::EVDiskQueueId::GetLowRead;
default:
@@ -2096,17 +2096,17 @@ static inline NKikimrBlobStorage::EVDiskQueueId HandleClassToQueueId(NKikimrBlob
}
-inline bool SendPutToGroup(const TActorContext &ctx, ui32 groupId, TTabletStorageInfo *storage,
- THolder<TEvBlobStorage::TEvPut> event, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
- auto checkGroupId = [&] {
- const TLogoBlobID &id = event->Id;
- const ui32 expectedGroupId = storage->GroupFor(id.Channel(), id.Generation());
- return id.TabletID() == storage->TabletID && expectedGroupId != Max<ui32>() && groupId == expectedGroupId;
- };
- Y_VERIFY(checkGroupId(), "groupId# %" PRIu32 " does not match actual one LogoBlobId# %s", groupId,
+inline bool SendPutToGroup(const TActorContext &ctx, ui32 groupId, TTabletStorageInfo *storage,
+ THolder<TEvBlobStorage::TEvPut> event, ui64 cookie = 0, NWilson::TTraceId traceId = {}) {
+ auto checkGroupId = [&] {
+ const TLogoBlobID &id = event->Id;
+ const ui32 expectedGroupId = storage->GroupFor(id.Channel(), id.Generation());
+ return id.TabletID() == storage->TabletID && expectedGroupId != Max<ui32>() && groupId == expectedGroupId;
+ };
+ Y_VERIFY(checkGroupId(), "groupId# %" PRIu32 " does not match actual one LogoBlobId# %s", groupId,
event->Id.ToString().data());
- return SendToBSProxy(ctx, groupId, event.Release(), cookie, std::move(traceId));
- // TODO(alexvru): check if return status is actually needed?
-}
-
+ return SendToBSProxy(ctx, groupId, event.Release(), cookie, std::move(traceId));
+ // TODO(alexvru): check if return status is actually needed?
+}
+
} // NKikimr
diff --git a/ydb/core/base/blobstorage_grouptype.cpp b/ydb/core/base/blobstorage_grouptype.cpp
index 66c79ba42cb..951fed4dd58 100644
--- a/ydb/core/base/blobstorage_grouptype.cpp
+++ b/ydb/core/base/blobstorage_grouptype.cpp
@@ -35,8 +35,8 @@ struct TBlobStorageErasureParameters {
ui32 Handoff; // number of selected hinted handoff (1 | 2)
};
-static const std::array<TBlobStorageErasureParameters, TErasureType::ErasureSpeciesCount>
- BlobStorageGroupErasureSpeciesParameters{{
+static const std::array<TBlobStorageErasureParameters, TErasureType::ErasureSpeciesCount>
+ BlobStorageGroupErasureSpeciesParameters{{
{0} // 0 = ErasureSpicies::ErasureNone
,{1} // 1 = ErasureSpicies::ErasureMirror3
,{1} // 2 = ErasureSpicies::Erasure3Plus1Block
@@ -45,8 +45,8 @@ static const std::array<TBlobStorageErasureParameters, TErasureType::ErasureSpec
,{2} // 5 = ErasureSpicies::Erasure3Plus2Block
,{2} // 6 = ErasureSpicies::Erasure4Plus2Stipe
,{2} // 7 = ErasureSpicies::Erasure3Plus2Stipe
- ,{2} // 8 = ErasureSpicies::ErasureMirror3Plus2
- ,{6} // 9 = ErasureSpicies::ErasireMirror3dc
+ ,{2} // 8 = ErasureSpicies::ErasureMirror3Plus2
+ ,{6} // 9 = ErasureSpicies::ErasireMirror3dc
,{3} // 10 = ErasureSpicies::Erasure4Plus3Block
,{3} // 11 = ErasureSpicies::Erasure4Plus3Stripe
,{3} // 12 = ErasureSpicies::Erasure3Plus3Block
@@ -55,11 +55,11 @@ static const std::array<TBlobStorageErasureParameters, TErasureType::ErasureSpec
,{3} // 15 = ErasureSpicies::Erasure2Plus3Stripe
,{2} // 16 = ErasureSpicies::Erasure2Plus2Block
,{2} // 17 = ErasureSpicies::Erasure2Plus2Stripe
- ,{5} // 18 = ErasureSpicies::ErasureMirror3of4
-}};
+ ,{5} // 18 = ErasureSpicies::ErasureMirror3of4
+}};
-ui32 TBlobStorageGroupType::BlobSubgroupSize() const {
+ui32 TBlobStorageGroupType::BlobSubgroupSize() const {
const TBlobStorageErasureParameters& erasure = BlobStorageGroupErasureSpeciesParameters[ErasureSpecies];
return DataParts() + ParityParts() + erasure.Handoff;
}
@@ -70,7 +70,7 @@ ui32 TBlobStorageGroupType::Handoff() const {
}
bool TBlobStorageGroupType::IsHandoffInSubgroup(ui32 idxInSubgroup) const {
- return idxInSubgroup >= DataParts() + ParityParts();
+ return idxInSubgroup >= DataParts() + ParityParts();
}
struct TReorderablePartLayout {
@@ -102,7 +102,7 @@ bool TBlobStorageGroupType::CorrectLayout(const TPartLayout &layout, TPartPlacem
TStackVec<ui8, 8> missingParts;
ui32 totalPartCount = TotalPartCount();
- ui32 blobSubgroupSize = BlobSubgroupSize();
+ ui32 blobSubgroupSize = BlobSubgroupSize();
const ui32 lastBit = 0x80000000;
@@ -131,7 +131,7 @@ bool TBlobStorageGroupType::CorrectLayout(const TPartLayout &layout, TPartPlacem
}
VERBOSE_COUT("handoffDestinedPartMaskInv# " << DebugFormatBits(ReverseMask(handoffDestinedPartMaskInv)) << Endl);
- for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
+ for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
if (vDiskMask & ~slowVDiskMask & (1 << i)) {
VERBOSE_COUT("layout.VDiskPartMask[" << i << "]# " << DebugFormatBits(layout.VDiskPartMask[i]) << Endl);
remaining.Records.push_back(TReorderablePartLayout::TVDiskParts(i, handoffDestinedPartMaskInv &
@@ -186,17 +186,17 @@ bool TBlobStorageGroupType::CorrectLayout(const TPartLayout &layout, TPartPlacem
}
ui64 TBlobStorageGroupType::PartSize(const TLogoBlobID &id) const {
- // Y_VERIFY(id.PartId()); // TODO(alexvru): uncomment when dsproxy is ready for KIKIMR-9881
- if (GetErasure() == TBlobStorageGroupType::ErasureMirror3of4 && id.PartId() == 3) {
- return 0;
- } else {
- return TErasureType::PartSize((TErasureType::ECrcMode)id.CrcMode(), id.BlobSize());
- }
+ // Y_VERIFY(id.PartId()); // TODO(alexvru): uncomment when dsproxy is ready for KIKIMR-9881
+ if (GetErasure() == TBlobStorageGroupType::ErasureMirror3of4 && id.PartId() == 3) {
+ return 0;
+ } else {
+ return TErasureType::PartSize((TErasureType::ECrcMode)id.CrcMode(), id.BlobSize());
+ }
}
-ui64 TBlobStorageGroupType::MaxPartSize(const TLogoBlobID &id) const {
- Y_VERIFY(!id.PartId());
- return TErasureType::PartSize((TErasureType::ECrcMode)id.CrcMode(), id.BlobSize());
-}
+ui64 TBlobStorageGroupType::MaxPartSize(const TLogoBlobID &id) const {
+ Y_VERIFY(!id.PartId());
+ return TErasureType::PartSize((TErasureType::ECrcMode)id.CrcMode(), id.BlobSize());
+}
}
diff --git a/ydb/core/base/blobstorage_grouptype.h b/ydb/core/base/blobstorage_grouptype.h
index cd38dfcfa86..da5fb45c1e7 100644
--- a/ydb/core/base/blobstorage_grouptype.h
+++ b/ydb/core/base/blobstorage_grouptype.h
@@ -12,8 +12,8 @@
namespace NKikimr {
-static constexpr ui32 BlobProtobufHeaderMaxSize = 80;
-
+static constexpr ui32 BlobProtobufHeaderMaxSize = 80;
+
struct TBloblStorageErasureParameters;
struct TBlobStorageGroupType : public TErasureType {
@@ -132,18 +132,18 @@ struct TBlobStorageGroupType : public TErasureType {
}
};
- ui32 BlobSubgroupSize() const; // _4_+_2_+_1_
+ ui32 BlobSubgroupSize() const; // _4_+_2_+_1_
ui32 Handoff() const; // 4 + 2 + _1_
bool IsHandoffInSubgroup(ui32 idxInSubgroup) const; // True for idx of a handoff disk in blob subgoup
bool CorrectLayout(const TPartLayout &layout, TPartPlacement &outCorrection) const;
-
+
ui32 GetExpectedVGetReplyProtobufSize(const TLogoBlobID &id) const {
return (BlobProtobufHeaderMaxSize + PartSize(id)) * TotalPartCount();
- }
+ }
ui64 PartSize(const TLogoBlobID &id) const;
- ui64 MaxPartSize(const TLogoBlobID &id) const;
+ ui64 MaxPartSize(const TLogoBlobID &id) const;
};
}
diff --git a/ydb/core/base/blobstorage_grouptype_ut.cpp b/ydb/core/base/blobstorage_grouptype_ut.cpp
index 1907b8e1274..40db5cb202c 100644
--- a/ydb/core/base/blobstorage_grouptype_ut.cpp
+++ b/ydb/core/base/blobstorage_grouptype_ut.cpp
@@ -15,15 +15,15 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupTypeTest) {
Y_UNIT_TEST(TestCorrectLayout) {
TBlobStorageGroupType groupType(TBlobStorageGroupType::Erasure3Plus1Stripe);
- ui32 blobSubgroupSize = groupType.BlobSubgroupSize();
+ ui32 blobSubgroupSize = groupType.BlobSubgroupSize();
ui32 totalPartCount = groupType.TotalPartCount();
TBlobStorageGroupType::TPartLayout layout;
- layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
- layout.VDiskPartMask.resize(blobSubgroupSize);
+ layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
+ layout.VDiskPartMask.resize(blobSubgroupSize);
for (ui32 i = 0; i < totalPartCount; ++i) {
layout.VDiskPartMask[i] = (1 << i);
}
- for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
+ for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
layout.VDiskPartMask[i] = 0;
}
TBlobStorageGroupType::TPartPlacement correction;
@@ -42,12 +42,12 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupTypeTest) {
UNIT_ASSERT_C(isCorrectable && correction.Records.size() == 0, CORRECTION_DESCRIPTION);
for (emptyDiskIdx = 0; emptyDiskIdx < totalPartCount; ++emptyDiskIdx) {
- layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
- layout.VDiskPartMask.resize(blobSubgroupSize);
+ layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
+ layout.VDiskPartMask.resize(blobSubgroupSize);
for (ui32 i = 0; i < totalPartCount; ++i) {
layout.VDiskPartMask[i] = (1 << i);
}
- for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
+ for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
layout.VDiskPartMask[i] = 0;
}
layout.VDiskPartMask[emptyDiskIdx] = 0;
@@ -67,12 +67,12 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupTypeTest) {
}
for (emptyDiskIdx = 0; emptyDiskIdx < totalPartCount; ++emptyDiskIdx) {
- layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
- layout.VDiskPartMask.resize(blobSubgroupSize);
+ layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
+ layout.VDiskPartMask.resize(blobSubgroupSize);
for (ui32 i = 0; i < totalPartCount; ++i) {
layout.VDiskPartMask[i] = (1 << i);
}
- for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
+ for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
layout.VDiskPartMask[i] = 0;
}
layout.VDiskMask &= ~((ui32)1 << emptyDiskIdx);
@@ -93,12 +93,12 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupTypeTest) {
for (emptyDiskIdx = 0; emptyDiskIdx < totalPartCount-1; ++emptyDiskIdx) {
for (ui32 emptyDisk2Idx = emptyDiskIdx + 1; emptyDisk2Idx < totalPartCount; ++emptyDisk2Idx) {
- layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
- layout.VDiskPartMask.resize(blobSubgroupSize);
+ layout.VDiskMask = ~((~(ui32)0) << blobSubgroupSize);
+ layout.VDiskPartMask.resize(blobSubgroupSize);
for (ui32 i = 0; i < totalPartCount; ++i) {
layout.VDiskPartMask[i] = (1 << i);
}
- for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
+ for (ui32 i = totalPartCount; i < blobSubgroupSize; ++i) {
layout.VDiskPartMask[i] = 0;
}
layout.VDiskMask &= ~((ui32)1 << emptyDiskIdx);
diff --git a/ydb/core/base/board_lookup.cpp b/ydb/core/base/board_lookup.cpp
index 890b88f6b9e..d431607bad4 100644
--- a/ydb/core/base/board_lookup.cpp
+++ b/ydb/core/base/board_lookup.cpp
@@ -166,8 +166,8 @@ class TBoardLookupActor : public TActorBootstrapped<TBoardLookupActor> {
CheckCompletion();
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BOARD_LOOKUP_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BOARD_LOOKUP_ACTOR;
}
TBoardLookupActor(const TString &path, TActorId owner, EBoardLookupMode mode, ui32 groupId)
diff --git a/ydb/core/base/board_publish.cpp b/ydb/core/base/board_publish.cpp
index cdd4bf6e489..3fd6120ce70 100644
--- a/ydb/core/base/board_publish.cpp
+++ b/ydb/core/base/board_publish.cpp
@@ -47,8 +47,8 @@ class TBoardReplicaPublishActor : public TActorBootstrapped<TBoardReplicaPublish
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BOARD_REPLICA_PUBLISH_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BOARD_REPLICA_PUBLISH_ACTOR;
}
TBoardReplicaPublishActor(const TString &path, const TString &payload, TActorId replica, TActorId publishActor)
@@ -146,8 +146,8 @@ class TBoardPublishActor : public TActorBootstrapped<TBoardPublishActor> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BOARD_PUBLISH_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BOARD_PUBLISH_ACTOR;
}
TBoardPublishActor(const TString &path, const TString &payload, const TActorId &owner, ui32 groupId, ui32 ttlMs, bool reg)
diff --git a/ydb/core/base/board_replica.cpp b/ydb/core/base/board_replica.cpp
index c38fd20e351..78952a4a618 100644
--- a/ydb/core/base/board_replica.cpp
+++ b/ydb/core/base/board_replica.cpp
@@ -197,8 +197,8 @@ class TBoardReplicaActor : public TActor<TBoardReplicaActor> {
}
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BOARD_REPLICA_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BOARD_REPLICA_ACTOR;
}
TBoardReplicaActor()
diff --git a/ydb/core/base/compile_time_flags.h b/ydb/core/base/compile_time_flags.h
index 4259148ee3d..7042aefa4b7 100644
--- a/ydb/core/base/compile_time_flags.h
+++ b/ydb/core/base/compile_time_flags.h
@@ -32,12 +32,12 @@
#ifndef KIKIMR_VDISK_SYNCLOG_ENTRY_POINT_PROTO_FORMAT
#define KIKIMR_VDISK_SYNCLOG_ENTRY_POINT_PROTO_FORMAT 0
#endif
-
-// This feature flag enables rope payload for protobuf events and may be switched
-// on after 19-6
-#ifndef KIKIMR_USE_PROTOBUF_WITH_PAYLOAD
-#define KIKIMR_USE_PROTOBUF_WITH_PAYLOAD 1
-#endif
+
+// This feature flag enables rope payload for protobuf events and may be switched
+// on after 19-6
+#ifndef KIKIMR_USE_PROTOBUF_WITH_PAYLOAD
+#define KIKIMR_USE_PROTOBUF_WITH_PAYLOAD 1
+#endif
// This feature flag enables use of column families in tables
// Runtime support is expected to ship in 19-6, may be enabled in 19-8
diff --git a/ydb/core/base/config_units.h b/ydb/core/base/config_units.h
index 1dffc6649c4..33d7f5fe367 100644
--- a/ydb/core/base/config_units.h
+++ b/ydb/core/base/config_units.h
@@ -1,13 +1,13 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/protos/config_units.pb.h>
-
-#include "defs.h"
-
-namespace NKikimr {
-
- inline TDuration DurationFromProto(const NKikimrConfigUnits::TDuration& pb) {
- return TDuration::MicroSeconds((pb.GetSeconds() * 1000 + pb.GetMilliseconds()) * 1000 + pb.GetMicroseconds());
- }
-
-} // NKikimr
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ inline TDuration DurationFromProto(const NKikimrConfigUnits::TDuration& pb) {
+ return TDuration::MicroSeconds((pb.GetSeconds() * 1000 + pb.GetMilliseconds()) * 1000 + pb.GetMicroseconds());
+ }
+
+} // NKikimr
diff --git a/ydb/core/base/counters.cpp b/ydb/core/base/counters.cpp
index b192fa36a1d..54935478a08 100644
--- a/ydb/core/base/counters.cpp
+++ b/ydb/core/base/counters.cpp
@@ -21,7 +21,7 @@ static const THashSet<TString> DATABASE_SERVICES
TString("proxy"),
TString("followers"),
TString("sqs"),
- TString("storage_pool_stat"),
+ TString("storage_pool_stat"),
TString("tablets"),
TString("utils"),
TString("auth"),
diff --git a/ydb/core/base/event_filter.cpp b/ydb/core/base/event_filter.cpp
index 029a4347c39..e1675b43d49 100644
--- a/ydb/core/base/event_filter.cpp
+++ b/ydb/core/base/event_filter.cpp
@@ -1,8 +1,8 @@
-#include "event_filter.h"
-#include "events.h"
-
-namespace NKikimr {
-
- const TKikimrScopeId TKikimrScopeId::DynamicTenantScopeId(Max<ui64>() /*SchemeshardId*/, 0);
-
-} // NKikimr
+#include "event_filter.h"
+#include "events.h"
+
+namespace NKikimr {
+
+ const TKikimrScopeId TKikimrScopeId::DynamicTenantScopeId(Max<ui64>() /*SchemeshardId*/, 0);
+
+} // NKikimr
diff --git a/ydb/core/base/event_filter.h b/ydb/core/base/event_filter.h
index 1df9899d5bf..fc77c37ee1a 100644
--- a/ydb/core/base/event_filter.h
+++ b/ydb/core/base/event_filter.h
@@ -1,64 +1,64 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/interconnect/interconnect_common.h>
-
-
-namespace NKikimr {
-
- class TKikimrScopeId {
- NActors::TScopeId ScopeId;
-
- public:
- TKikimrScopeId() = default;
- TKikimrScopeId(const TKikimrScopeId&) = default;
-
- explicit TKikimrScopeId(const NActors::TScopeId& scopeId)
- : ScopeId(scopeId)
- {}
-
- explicit TKikimrScopeId(ui64 schemeshardId, ui64 pathItemId)
- : ScopeId(schemeshardId, pathItemId)
- {}
-
- NActors::TScopeId GetInterconnectScopeId() const {
- return ScopeId;
- }
-
- ui64 GetSchemeshardId() const {
- return ScopeId.first;
- }
-
- ui64 GetPathItemId() const {
- Y_VERIFY(GetSchemeshardId() != 0);
- return ScopeId.second;
- }
-
- ui64 GetDomainId() const {
- Y_VERIFY(GetSchemeshardId() == 0);
- return ScopeId.second;
- }
-
- bool IsEmpty() const {
- return ScopeId.first == 0 && ScopeId.second == 0;
- }
-
- bool IsSystemScope() const {
- return GetSchemeshardId() == 0 && !IsEmpty();
- }
-
- bool IsTenantScope() const {
- return GetSchemeshardId() != 0;
- }
-
- friend bool operator ==(const TKikimrScopeId& x, const TKikimrScopeId& y) {
- return x.ScopeId == y.ScopeId;
- }
-
- friend bool operator !=(const TKikimrScopeId& x, const TKikimrScopeId& y) {
- return x.ScopeId != y.ScopeId;
- }
-
- static const TKikimrScopeId DynamicTenantScopeId;
- };
-
-} // NKikimr
+
+
+namespace NKikimr {
+
+ class TKikimrScopeId {
+ NActors::TScopeId ScopeId;
+
+ public:
+ TKikimrScopeId() = default;
+ TKikimrScopeId(const TKikimrScopeId&) = default;
+
+ explicit TKikimrScopeId(const NActors::TScopeId& scopeId)
+ : ScopeId(scopeId)
+ {}
+
+ explicit TKikimrScopeId(ui64 schemeshardId, ui64 pathItemId)
+ : ScopeId(schemeshardId, pathItemId)
+ {}
+
+ NActors::TScopeId GetInterconnectScopeId() const {
+ return ScopeId;
+ }
+
+ ui64 GetSchemeshardId() const {
+ return ScopeId.first;
+ }
+
+ ui64 GetPathItemId() const {
+ Y_VERIFY(GetSchemeshardId() != 0);
+ return ScopeId.second;
+ }
+
+ ui64 GetDomainId() const {
+ Y_VERIFY(GetSchemeshardId() == 0);
+ return ScopeId.second;
+ }
+
+ bool IsEmpty() const {
+ return ScopeId.first == 0 && ScopeId.second == 0;
+ }
+
+ bool IsSystemScope() const {
+ return GetSchemeshardId() == 0 && !IsEmpty();
+ }
+
+ bool IsTenantScope() const {
+ return GetSchemeshardId() != 0;
+ }
+
+ friend bool operator ==(const TKikimrScopeId& x, const TKikimrScopeId& y) {
+ return x.ScopeId == y.ScopeId;
+ }
+
+ friend bool operator !=(const TKikimrScopeId& x, const TKikimrScopeId& y) {
+ return x.ScopeId != y.ScopeId;
+ }
+
+ static const TKikimrScopeId DynamicTenantScopeId;
+ };
+
+} // NKikimr
diff --git a/ydb/core/base/events.h b/ydb/core/base/events.h
index f5fedfe19b2..d8c0d4ed536 100644
--- a/ydb/core/base/events.h
+++ b/ydb/core/base/events.h
@@ -124,7 +124,7 @@ struct TKikimrEvents : TEvents {
ES_IMPORT_SERVICE, // 4200
ES_TX_OLAPSHARD,
ES_TX_COLUMNSHARD,
- ES_CROSSREF,
+ ES_CROSSREF,
ES_SCHEME_BOARD_MON,
ES_YQL_ANALYTICS_PROXY = NYq::TEventIds::ES_YQL_ANALYTICS_PROXY,
ES_BLOB_CACHE,
diff --git a/ydb/core/base/group_stat.cpp b/ydb/core/base/group_stat.cpp
index b63dee59432..60503fd53ee 100644
--- a/ydb/core/base/group_stat.cpp
+++ b/ydb/core/base/group_stat.cpp
@@ -1,109 +1,109 @@
-#include "group_stat.h"
-
-namespace NKikimr {
-
- std::array<TDuration, NumGroupStatBuckets + 1> BucketValues{
- TDuration::Zero(),
- TDuration::MicroSeconds(250),
- TDuration::MicroSeconds(500),
- TDuration::MicroSeconds(750),
- TDuration::MilliSeconds(1),
- TDuration::MilliSeconds(2),
- TDuration::MilliSeconds(3),
- TDuration::MilliSeconds(4),
- TDuration::MilliSeconds(5),
- TDuration::MilliSeconds(6),
- TDuration::MilliSeconds(7),
- TDuration::MilliSeconds(8),
- TDuration::MilliSeconds(9),
- TDuration::MilliSeconds(10),
- TDuration::MilliSeconds(12),
- TDuration::MilliSeconds(14),
- TDuration::MilliSeconds(16),
- TDuration::MilliSeconds(18),
- TDuration::MilliSeconds(20),
- TDuration::MilliSeconds(24),
- TDuration::MilliSeconds(28),
- TDuration::MilliSeconds(32),
- TDuration::MilliSeconds(36),
- TDuration::MilliSeconds(40),
- TDuration::MilliSeconds(45),
- TDuration::MilliSeconds(50),
- TDuration::MilliSeconds(55),
- TDuration::MilliSeconds(60),
- TDuration::MilliSeconds(65),
- TDuration::MilliSeconds(70),
- TDuration::MilliSeconds(75),
- TDuration::MilliSeconds(80),
- TDuration::MilliSeconds(85),
- TDuration::MilliSeconds(90),
- TDuration::MilliSeconds(100),
- TDuration::MilliSeconds(120),
- TDuration::MilliSeconds(140),
- TDuration::MilliSeconds(160),
- TDuration::MilliSeconds(180),
- TDuration::MilliSeconds(200),
- TDuration::MilliSeconds(220),
- TDuration::MilliSeconds(240),
- TDuration::MilliSeconds(260),
- TDuration::MilliSeconds(280),
- TDuration::MilliSeconds(300),
- TDuration::MilliSeconds(320),
- TDuration::MilliSeconds(340),
- TDuration::MilliSeconds(360),
- TDuration::MilliSeconds(380),
- TDuration::MilliSeconds(400),
- TDuration::MilliSeconds(450),
- TDuration::MilliSeconds(500),
- TDuration::MilliSeconds(550),
- TDuration::MilliSeconds(600),
- TDuration::MilliSeconds(650),
- TDuration::MilliSeconds(700),
- TDuration::MilliSeconds(750),
- TDuration::MilliSeconds(800),
- TDuration::MilliSeconds(850),
- TDuration::MilliSeconds(900),
- TDuration::MilliSeconds(950),
- TDuration::MilliSeconds(1000),
- TDuration::MilliSeconds(1100),
- TDuration::MilliSeconds(1200),
- TDuration::MilliSeconds(1300),
- TDuration::MilliSeconds(1400),
- TDuration::MilliSeconds(1500),
- TDuration::MilliSeconds(1600),
- TDuration::MilliSeconds(1700),
- TDuration::MilliSeconds(1800),
- TDuration::MilliSeconds(1900),
- TDuration::MilliSeconds(2000),
- TDuration::MilliSeconds(2250),
- TDuration::MilliSeconds(2500),
- TDuration::MilliSeconds(2750),
- TDuration::MilliSeconds(3000),
- TDuration::MilliSeconds(3250),
- TDuration::MilliSeconds(3500),
- TDuration::MilliSeconds(3750),
- TDuration::MilliSeconds(4000),
- TDuration::MilliSeconds(4250),
- TDuration::MilliSeconds(4500),
- TDuration::MilliSeconds(4750),
- TDuration::MilliSeconds(5000),
- TDuration::MilliSeconds(5250),
- TDuration::MilliSeconds(5500),
- TDuration::MilliSeconds(5750),
- TDuration::MilliSeconds(6000),
- TDuration::MilliSeconds(6250),
- TDuration::MilliSeconds(6500),
- TDuration::MilliSeconds(6750),
- TDuration::MilliSeconds(7000),
- TDuration::MilliSeconds(7250),
- TDuration::MilliSeconds(7500),
- TDuration::MilliSeconds(7750),
- TDuration::MilliSeconds(8000),
- TDuration::MilliSeconds(8250),
- TDuration::MilliSeconds(8500),
- TDuration::MilliSeconds(8750),
- TDuration::MilliSeconds(9000),
- TDuration::Seconds(10)
- };
-
-} // NKikimr
+#include "group_stat.h"
+
+namespace NKikimr {
+
+ std::array<TDuration, NumGroupStatBuckets + 1> BucketValues{
+ TDuration::Zero(),
+ TDuration::MicroSeconds(250),
+ TDuration::MicroSeconds(500),
+ TDuration::MicroSeconds(750),
+ TDuration::MilliSeconds(1),
+ TDuration::MilliSeconds(2),
+ TDuration::MilliSeconds(3),
+ TDuration::MilliSeconds(4),
+ TDuration::MilliSeconds(5),
+ TDuration::MilliSeconds(6),
+ TDuration::MilliSeconds(7),
+ TDuration::MilliSeconds(8),
+ TDuration::MilliSeconds(9),
+ TDuration::MilliSeconds(10),
+ TDuration::MilliSeconds(12),
+ TDuration::MilliSeconds(14),
+ TDuration::MilliSeconds(16),
+ TDuration::MilliSeconds(18),
+ TDuration::MilliSeconds(20),
+ TDuration::MilliSeconds(24),
+ TDuration::MilliSeconds(28),
+ TDuration::MilliSeconds(32),
+ TDuration::MilliSeconds(36),
+ TDuration::MilliSeconds(40),
+ TDuration::MilliSeconds(45),
+ TDuration::MilliSeconds(50),
+ TDuration::MilliSeconds(55),
+ TDuration::MilliSeconds(60),
+ TDuration::MilliSeconds(65),
+ TDuration::MilliSeconds(70),
+ TDuration::MilliSeconds(75),
+ TDuration::MilliSeconds(80),
+ TDuration::MilliSeconds(85),
+ TDuration::MilliSeconds(90),
+ TDuration::MilliSeconds(100),
+ TDuration::MilliSeconds(120),
+ TDuration::MilliSeconds(140),
+ TDuration::MilliSeconds(160),
+ TDuration::MilliSeconds(180),
+ TDuration::MilliSeconds(200),
+ TDuration::MilliSeconds(220),
+ TDuration::MilliSeconds(240),
+ TDuration::MilliSeconds(260),
+ TDuration::MilliSeconds(280),
+ TDuration::MilliSeconds(300),
+ TDuration::MilliSeconds(320),
+ TDuration::MilliSeconds(340),
+ TDuration::MilliSeconds(360),
+ TDuration::MilliSeconds(380),
+ TDuration::MilliSeconds(400),
+ TDuration::MilliSeconds(450),
+ TDuration::MilliSeconds(500),
+ TDuration::MilliSeconds(550),
+ TDuration::MilliSeconds(600),
+ TDuration::MilliSeconds(650),
+ TDuration::MilliSeconds(700),
+ TDuration::MilliSeconds(750),
+ TDuration::MilliSeconds(800),
+ TDuration::MilliSeconds(850),
+ TDuration::MilliSeconds(900),
+ TDuration::MilliSeconds(950),
+ TDuration::MilliSeconds(1000),
+ TDuration::MilliSeconds(1100),
+ TDuration::MilliSeconds(1200),
+ TDuration::MilliSeconds(1300),
+ TDuration::MilliSeconds(1400),
+ TDuration::MilliSeconds(1500),
+ TDuration::MilliSeconds(1600),
+ TDuration::MilliSeconds(1700),
+ TDuration::MilliSeconds(1800),
+ TDuration::MilliSeconds(1900),
+ TDuration::MilliSeconds(2000),
+ TDuration::MilliSeconds(2250),
+ TDuration::MilliSeconds(2500),
+ TDuration::MilliSeconds(2750),
+ TDuration::MilliSeconds(3000),
+ TDuration::MilliSeconds(3250),
+ TDuration::MilliSeconds(3500),
+ TDuration::MilliSeconds(3750),
+ TDuration::MilliSeconds(4000),
+ TDuration::MilliSeconds(4250),
+ TDuration::MilliSeconds(4500),
+ TDuration::MilliSeconds(4750),
+ TDuration::MilliSeconds(5000),
+ TDuration::MilliSeconds(5250),
+ TDuration::MilliSeconds(5500),
+ TDuration::MilliSeconds(5750),
+ TDuration::MilliSeconds(6000),
+ TDuration::MilliSeconds(6250),
+ TDuration::MilliSeconds(6500),
+ TDuration::MilliSeconds(6750),
+ TDuration::MilliSeconds(7000),
+ TDuration::MilliSeconds(7250),
+ TDuration::MilliSeconds(7500),
+ TDuration::MilliSeconds(7750),
+ TDuration::MilliSeconds(8000),
+ TDuration::MilliSeconds(8250),
+ TDuration::MilliSeconds(8500),
+ TDuration::MilliSeconds(8750),
+ TDuration::MilliSeconds(9000),
+ TDuration::Seconds(10)
+ };
+
+} // NKikimr
diff --git a/ydb/core/base/group_stat.h b/ydb/core/base/group_stat.h
index e28f1505791..3d24858f71a 100644
--- a/ydb/core/base/group_stat.h
+++ b/ydb/core/base/group_stat.h
@@ -1,262 +1,262 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/protos/blobstorage.pb.h>
-
-#include <util/datetime/base.h>
-
-#include <array>
-#include <cmath>
-
-namespace NKikimr {
-
- static constexpr size_t NumGroupStatBuckets = 100;
-
- extern std::array<TDuration, NumGroupStatBuckets + 1> BucketValues;
-
- // latency statistics for a group
- struct TLatencyHistogram {
- static constexpr TDuration HalfFadeoutInterval = TDuration::Minutes(5);
-
- std::array<ui32, NumGroupStatBuckets> Buckets;
- TInstant LastFadeoutTimestamp;
-
- static TString GetBucketName(size_t i) {
- return Sprintf("%s..%s", BucketValues[i].ToString().data(), BucketValues[i + 1].ToString().data());
- }
-
- static TDuration GetBucketValue(size_t i) {
- return BucketValues[i];
- }
-
- static size_t GetBucket(TDuration sample) {
- const size_t index = std::upper_bound(BucketValues.begin(), BucketValues.end(), sample) - BucketValues.begin() - 1;
- return std::min(index, NumGroupStatBuckets - 1);
- }
-
- TLatencyHistogram() {
- Buckets.fill(0);
- }
-
- TLatencyHistogram(const TLatencyHistogram& other) = default;
-
- void Update(TDuration sample, TInstant now) {
- Fadeout(now);
- const size_t bucket = GetBucket(sample);
- ++Buckets[bucket];
- }
-
- void Add(const TLatencyHistogram& other) {
- for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
- Buckets[i] += other.Buckets[i];
- }
- }
-
- void Replace(const TLatencyHistogram& current, const TLatencyHistogram& previous) {
- for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
- Y_VERIFY_DEBUG(Buckets[i] + current.Buckets[i] >= previous.Buckets[i]);
- Buckets[i] += current.Buckets[i] - previous.Buckets[i];
- }
- }
-
- void Subtract(const TLatencyHistogram& other) {
- for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
- Y_VERIFY_DEBUG(Buckets[i] >= other.Buckets[i]);
- Buckets[i] -= other.Buckets[i];
- }
- }
-
- TMaybe<TDuration> Percentile(double p) const {
- std::array<ui64, NumGroupStatBuckets + 1> accum;
- ui64 counter = 0;
- for (size_t i = 0;; ++i) {
- accum[i] = counter;
- if (i < NumGroupStatBuckets) {
- counter += Buckets[i];
- } else {
- break;
- }
- }
- if (!counter) {
- return {};
- }
-
- // calculate the quantile value
- const double quantile = counter * p;
-
- // find it in the buckets array
- size_t index = std::upper_bound(accum.begin(), accum.end(), quantile) - accum.begin();
- Y_VERIFY(index > 0 && index <= NumGroupStatBuckets);
-
- const double w = (quantile - accum[index - 1]) / (accum[index] - accum[index - 1]);
- return TDuration::FromValue(GetBucketValue(index - 1).GetValue() * (1 - w) + GetBucketValue(index).GetValue() * w);
- }
-
- bool Fadeout(TInstant now) {
- if (LastFadeoutTimestamp != TInstant::Zero()) {
- const TDuration elapsed = now - LastFadeoutTimestamp;
-
- // number of full half-fadeout intervals
- const size_t shift = elapsed.GetValue() / HalfFadeoutInterval.GetValue();
-
- // number of ticks inside last full half-fadeout interval
- const ui64 subshift = elapsed.GetValue() % HalfFadeoutInterval.GetValue();
-
- // scale factors are calculated as 2**20 * pow(0.5, i / 256.0)
- static const ui64 factor[] = {
- 1048576, 1045740, 1042913, 1040093, 1037280, 1034476, 1031678, 1028889, 1026107, 1023332, 1020565,
- 1017806, 1015053, 1012309, 1009572, 1006842, 1004119, 1001404, 998696, 995996, 993303, 990617,
- 987939, 985267, 982603, 979946, 977296, 974654, 972019, 969390, 966769, 964155, 961548, 958948,
- 956355, 953769, 951190, 948618, 946053, 943495, 940944, 938400, 935862, 933332, 930808, 928291,
- 925781, 923278, 920781, 918292, 915809, 913332, 910863, 908400, 905944, 903494, 901051, 898615,
- 896185, 893762, 891345, 888935, 886531, 884134, 881743, 879359, 876981, 874610, 872245, 869887,
- 867535, 865189, 862849, 860516, 858189, 855869, 853555, 851247, 848945, 846650, 844360, 842077,
- 839800, 837529, 835265, 833006, 830754, 828508, 826267, 824033, 821805, 819583, 817367, 815157,
- 812953, 810754, 808562, 806376, 804195, 802021, 799852, 797690, 795533, 793382, 791236, 789097,
- 786963, 784835, 782713, 780597, 778486, 776381, 774282, 772188, 770100, 768018, 765941, 763870,
- 761805, 759745, 757690, 755642, 753598, 751561, 749529, 747502, 745481, 743465, 741455, 739450,
- 737450, 735456, 733468, 731484, 729507, 727534, 725567, 723605, 721648, 719697, 717751, 715810,
- 713875, 711944, 710019, 708100, 706185, 704275, 702371, 700472, 698578, 696689, 694805, 692926,
- 691053, 689184, 687321, 685462, 683609, 681760, 679917, 678078, 676245, 674416, 672593, 670774,
- 668960, 667152, 665348, 663549, 661754, 659965, 658181, 656401, 654626, 652856, 651091, 649330,
- 647574, 645823, 644077, 642336, 640599, 638867, 637139, 635416, 633698, 631985, 630276, 628572,
- 626872, 625177, 623487, 621801, 620119, 618443, 616770, 615103, 613439, 611781, 610126, 608477,
- 606831, 605191, 603554, 601922, 600295, 598671, 597053, 595438, 593828, 592223, 590621, 589024,
- 587432, 585843, 584259, 582679, 581104, 579532, 577965, 576403, 574844, 573290, 571740, 570194,
- 568652, 567114, 565581, 564052, 562526, 561005, 559488, 557976, 556467, 554962, 553462, 551965,
- 550473, 548984, 547500, 546019, 544543, 543070, 541602, 540138, 538677, 537221, 535768, 534319,
- 532874, 531434, 529997, 528564, 527134, 525709
- };
-
- // index into scale factor array
- const size_t numScaleFactors = sizeof(factor) / sizeof(factor[0]);
- size_t index = subshift * numScaleFactors / HalfFadeoutInterval.GetValue();
-
- ui32 numNonzeroItems = 0;
-
- if (shift + 20 < 64) {
- for (ui32& item : Buckets) {
- item = ui64(item) * factor[index] >> (shift + 20);
- numNonzeroItems += !!item;
- }
- } else {
- std::fill(Buckets.begin(), Buckets.end(), 0);
- }
-
- // adjust timestamp to keep fading precision
- LastFadeoutTimestamp += TDuration::FromValue((numScaleFactors * shift + index) * HalfFadeoutInterval.GetValue() / numScaleFactors);
-
- return numNonzeroItems;
- } else {
- LastFadeoutTimestamp = now;
- for (ui32 value : Buckets) {
- if (value) {
- return true;
- }
- }
- return false;
- }
- }
-
- void Serialize(NKikimrBlobStorage::TEvGroupStatReport::TLatencyHistogram *pb) const {
- pb->ClearBuckets();
- for (ui32 value : Buckets) {
- pb->AddBuckets(value);
- }
- }
-
- bool Deserialize(const NKikimrBlobStorage::TEvGroupStatReport::TLatencyHistogram& pb) {
- if (pb.BucketsSize() != NumGroupStatBuckets) {
- return false;
- }
- size_t i = 0;
- for (ui32 value : pb.GetBuckets()) {
- Buckets[i++] = value;
- }
- return true;
- }
- };
-
- class TGroupStat {
- TLatencyHistogram PutTabletLog;
- TLatencyHistogram PutUserData;
- TLatencyHistogram GetFast;
-
- public:
- enum class EKind {
- PUT_TABLET_LOG,
- PUT_USER_DATA,
- GET_FAST,
- };
-
- public:
- bool Fadeout(TInstant now) {
- const bool x1 = PutTabletLog.Fadeout(now);
- const bool x2 = PutUserData.Fadeout(now);
- const bool x3 = GetFast.Fadeout(now);
- return x1 || x2 || x3;
- }
-
- void Add(const TGroupStat& other) {
- PutTabletLog.Add(other.PutTabletLog);
- PutUserData.Add(other.PutUserData);
- GetFast.Add(other.GetFast);
- }
-
- void Replace(const TGroupStat& current, const TGroupStat& previous) {
- PutTabletLog.Replace(current.PutTabletLog, previous.PutTabletLog);
- PutUserData.Replace(current.PutUserData, previous.PutUserData);
- GetFast.Replace(current.GetFast, previous.GetFast);
- }
-
- void Subtract(const TGroupStat& other) {
- PutTabletLog.Subtract(other.PutTabletLog);
- PutUserData.Subtract(other.PutUserData);
- GetFast.Subtract(other.GetFast);
- }
-
- void Update(EKind kind, TDuration sample, TInstant now) {
- TLatencyHistogram& histogram = GetLatencyHistogram(kind);
- histogram.Update(sample, now);
- }
-
- void Serialize(NKikimrBlobStorage::TEvGroupStatReport *pb) const {
- PutTabletLog.Serialize(pb->MutablePutTabletLog());
- PutUserData.Serialize(pb->MutablePutUserData());
- GetFast.Serialize(pb->MutableGetFast());
- }
-
- bool Deserialize(const NKikimrBlobStorage::TEvGroupStatReport& pb) {
- return PutTabletLog.Deserialize(pb.GetPutTabletLog()) &&
- PutUserData.Deserialize(pb.GetPutUserData()) &&
- GetFast.Deserialize(pb.GetGetFast());
- }
-
- ui32 GetItem(EKind kind, size_t bucket) const {
- return GetLatencyHistogram(kind).Buckets[bucket];
- }
-
- TMaybe<TDuration> GetPercentile(EKind kind, double p) const {
- return GetLatencyHistogram(kind).Percentile(p);
- }
-
- private:
- const TLatencyHistogram& GetLatencyHistogram(EKind kind) const {
- return const_cast<TGroupStat&>(*this).GetLatencyHistogram(kind);
- }
-
- TLatencyHistogram& GetLatencyHistogram(EKind kind) {
- switch (kind) {
- case EKind::PUT_TABLET_LOG:
- return PutTabletLog;
- case EKind::PUT_USER_DATA:
- return PutUserData;
- case EKind::GET_FAST:
- return GetFast;
- }
- Y_FAIL("unexpected TGroupStat::EKind value");
- }
- };
-
-} // NKikimr
+
+#include <util/datetime/base.h>
+
+#include <array>
+#include <cmath>
+
+namespace NKikimr {
+
+ static constexpr size_t NumGroupStatBuckets = 100;
+
+ extern std::array<TDuration, NumGroupStatBuckets + 1> BucketValues;
+
+ // latency statistics for a group
+ struct TLatencyHistogram {
+ static constexpr TDuration HalfFadeoutInterval = TDuration::Minutes(5);
+
+ std::array<ui32, NumGroupStatBuckets> Buckets;
+ TInstant LastFadeoutTimestamp;
+
+ static TString GetBucketName(size_t i) {
+ return Sprintf("%s..%s", BucketValues[i].ToString().data(), BucketValues[i + 1].ToString().data());
+ }
+
+ static TDuration GetBucketValue(size_t i) {
+ return BucketValues[i];
+ }
+
+ static size_t GetBucket(TDuration sample) {
+ const size_t index = std::upper_bound(BucketValues.begin(), BucketValues.end(), sample) - BucketValues.begin() - 1;
+ return std::min(index, NumGroupStatBuckets - 1);
+ }
+
+ TLatencyHistogram() {
+ Buckets.fill(0);
+ }
+
+ TLatencyHistogram(const TLatencyHistogram& other) = default;
+
+ void Update(TDuration sample, TInstant now) {
+ Fadeout(now);
+ const size_t bucket = GetBucket(sample);
+ ++Buckets[bucket];
+ }
+
+ void Add(const TLatencyHistogram& other) {
+ for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
+ Buckets[i] += other.Buckets[i];
+ }
+ }
+
+ void Replace(const TLatencyHistogram& current, const TLatencyHistogram& previous) {
+ for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
+ Y_VERIFY_DEBUG(Buckets[i] + current.Buckets[i] >= previous.Buckets[i]);
+ Buckets[i] += current.Buckets[i] - previous.Buckets[i];
+ }
+ }
+
+ void Subtract(const TLatencyHistogram& other) {
+ for (size_t i = 0; i < NumGroupStatBuckets; ++i) {
+ Y_VERIFY_DEBUG(Buckets[i] >= other.Buckets[i]);
+ Buckets[i] -= other.Buckets[i];
+ }
+ }
+
+ TMaybe<TDuration> Percentile(double p) const {
+ std::array<ui64, NumGroupStatBuckets + 1> accum;
+ ui64 counter = 0;
+ for (size_t i = 0;; ++i) {
+ accum[i] = counter;
+ if (i < NumGroupStatBuckets) {
+ counter += Buckets[i];
+ } else {
+ break;
+ }
+ }
+ if (!counter) {
+ return {};
+ }
+
+ // calculate the quantile value
+ const double quantile = counter * p;
+
+ // find it in the buckets array
+ size_t index = std::upper_bound(accum.begin(), accum.end(), quantile) - accum.begin();
+ Y_VERIFY(index > 0 && index <= NumGroupStatBuckets);
+
+ const double w = (quantile - accum[index - 1]) / (accum[index] - accum[index - 1]);
+ return TDuration::FromValue(GetBucketValue(index - 1).GetValue() * (1 - w) + GetBucketValue(index).GetValue() * w);
+ }
+
+ bool Fadeout(TInstant now) {
+ if (LastFadeoutTimestamp != TInstant::Zero()) {
+ const TDuration elapsed = now - LastFadeoutTimestamp;
+
+ // number of full half-fadeout intervals
+ const size_t shift = elapsed.GetValue() / HalfFadeoutInterval.GetValue();
+
+ // number of ticks inside last full half-fadeout interval
+ const ui64 subshift = elapsed.GetValue() % HalfFadeoutInterval.GetValue();
+
+ // scale factors are calculated as 2**20 * pow(0.5, i / 256.0)
+ static const ui64 factor[] = {
+ 1048576, 1045740, 1042913, 1040093, 1037280, 1034476, 1031678, 1028889, 1026107, 1023332, 1020565,
+ 1017806, 1015053, 1012309, 1009572, 1006842, 1004119, 1001404, 998696, 995996, 993303, 990617,
+ 987939, 985267, 982603, 979946, 977296, 974654, 972019, 969390, 966769, 964155, 961548, 958948,
+ 956355, 953769, 951190, 948618, 946053, 943495, 940944, 938400, 935862, 933332, 930808, 928291,
+ 925781, 923278, 920781, 918292, 915809, 913332, 910863, 908400, 905944, 903494, 901051, 898615,
+ 896185, 893762, 891345, 888935, 886531, 884134, 881743, 879359, 876981, 874610, 872245, 869887,
+ 867535, 865189, 862849, 860516, 858189, 855869, 853555, 851247, 848945, 846650, 844360, 842077,
+ 839800, 837529, 835265, 833006, 830754, 828508, 826267, 824033, 821805, 819583, 817367, 815157,
+ 812953, 810754, 808562, 806376, 804195, 802021, 799852, 797690, 795533, 793382, 791236, 789097,
+ 786963, 784835, 782713, 780597, 778486, 776381, 774282, 772188, 770100, 768018, 765941, 763870,
+ 761805, 759745, 757690, 755642, 753598, 751561, 749529, 747502, 745481, 743465, 741455, 739450,
+ 737450, 735456, 733468, 731484, 729507, 727534, 725567, 723605, 721648, 719697, 717751, 715810,
+ 713875, 711944, 710019, 708100, 706185, 704275, 702371, 700472, 698578, 696689, 694805, 692926,
+ 691053, 689184, 687321, 685462, 683609, 681760, 679917, 678078, 676245, 674416, 672593, 670774,
+ 668960, 667152, 665348, 663549, 661754, 659965, 658181, 656401, 654626, 652856, 651091, 649330,
+ 647574, 645823, 644077, 642336, 640599, 638867, 637139, 635416, 633698, 631985, 630276, 628572,
+ 626872, 625177, 623487, 621801, 620119, 618443, 616770, 615103, 613439, 611781, 610126, 608477,
+ 606831, 605191, 603554, 601922, 600295, 598671, 597053, 595438, 593828, 592223, 590621, 589024,
+ 587432, 585843, 584259, 582679, 581104, 579532, 577965, 576403, 574844, 573290, 571740, 570194,
+ 568652, 567114, 565581, 564052, 562526, 561005, 559488, 557976, 556467, 554962, 553462, 551965,
+ 550473, 548984, 547500, 546019, 544543, 543070, 541602, 540138, 538677, 537221, 535768, 534319,
+ 532874, 531434, 529997, 528564, 527134, 525709
+ };
+
+ // index into scale factor array
+ const size_t numScaleFactors = sizeof(factor) / sizeof(factor[0]);
+ size_t index = subshift * numScaleFactors / HalfFadeoutInterval.GetValue();
+
+ ui32 numNonzeroItems = 0;
+
+ if (shift + 20 < 64) {
+ for (ui32& item : Buckets) {
+ item = ui64(item) * factor[index] >> (shift + 20);
+ numNonzeroItems += !!item;
+ }
+ } else {
+ std::fill(Buckets.begin(), Buckets.end(), 0);
+ }
+
+ // adjust timestamp to keep fading precision
+ LastFadeoutTimestamp += TDuration::FromValue((numScaleFactors * shift + index) * HalfFadeoutInterval.GetValue() / numScaleFactors);
+
+ return numNonzeroItems;
+ } else {
+ LastFadeoutTimestamp = now;
+ for (ui32 value : Buckets) {
+ if (value) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ void Serialize(NKikimrBlobStorage::TEvGroupStatReport::TLatencyHistogram *pb) const {
+ pb->ClearBuckets();
+ for (ui32 value : Buckets) {
+ pb->AddBuckets(value);
+ }
+ }
+
+ bool Deserialize(const NKikimrBlobStorage::TEvGroupStatReport::TLatencyHistogram& pb) {
+ if (pb.BucketsSize() != NumGroupStatBuckets) {
+ return false;
+ }
+ size_t i = 0;
+ for (ui32 value : pb.GetBuckets()) {
+ Buckets[i++] = value;
+ }
+ return true;
+ }
+ };
+
+ class TGroupStat {
+ TLatencyHistogram PutTabletLog;
+ TLatencyHistogram PutUserData;
+ TLatencyHistogram GetFast;
+
+ public:
+ enum class EKind {
+ PUT_TABLET_LOG,
+ PUT_USER_DATA,
+ GET_FAST,
+ };
+
+ public:
+ bool Fadeout(TInstant now) {
+ const bool x1 = PutTabletLog.Fadeout(now);
+ const bool x2 = PutUserData.Fadeout(now);
+ const bool x3 = GetFast.Fadeout(now);
+ return x1 || x2 || x3;
+ }
+
+ void Add(const TGroupStat& other) {
+ PutTabletLog.Add(other.PutTabletLog);
+ PutUserData.Add(other.PutUserData);
+ GetFast.Add(other.GetFast);
+ }
+
+ void Replace(const TGroupStat& current, const TGroupStat& previous) {
+ PutTabletLog.Replace(current.PutTabletLog, previous.PutTabletLog);
+ PutUserData.Replace(current.PutUserData, previous.PutUserData);
+ GetFast.Replace(current.GetFast, previous.GetFast);
+ }
+
+ void Subtract(const TGroupStat& other) {
+ PutTabletLog.Subtract(other.PutTabletLog);
+ PutUserData.Subtract(other.PutUserData);
+ GetFast.Subtract(other.GetFast);
+ }
+
+ void Update(EKind kind, TDuration sample, TInstant now) {
+ TLatencyHistogram& histogram = GetLatencyHistogram(kind);
+ histogram.Update(sample, now);
+ }
+
+ void Serialize(NKikimrBlobStorage::TEvGroupStatReport *pb) const {
+ PutTabletLog.Serialize(pb->MutablePutTabletLog());
+ PutUserData.Serialize(pb->MutablePutUserData());
+ GetFast.Serialize(pb->MutableGetFast());
+ }
+
+ bool Deserialize(const NKikimrBlobStorage::TEvGroupStatReport& pb) {
+ return PutTabletLog.Deserialize(pb.GetPutTabletLog()) &&
+ PutUserData.Deserialize(pb.GetPutUserData()) &&
+ GetFast.Deserialize(pb.GetGetFast());
+ }
+
+ ui32 GetItem(EKind kind, size_t bucket) const {
+ return GetLatencyHistogram(kind).Buckets[bucket];
+ }
+
+ TMaybe<TDuration> GetPercentile(EKind kind, double p) const {
+ return GetLatencyHistogram(kind).Percentile(p);
+ }
+
+ private:
+ const TLatencyHistogram& GetLatencyHistogram(EKind kind) const {
+ return const_cast<TGroupStat&>(*this).GetLatencyHistogram(kind);
+ }
+
+ TLatencyHistogram& GetLatencyHistogram(EKind kind) {
+ switch (kind) {
+ case EKind::PUT_TABLET_LOG:
+ return PutTabletLog;
+ case EKind::PUT_USER_DATA:
+ return PutUserData;
+ case EKind::GET_FAST:
+ return GetFast;
+ }
+ Y_FAIL("unexpected TGroupStat::EKind value");
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/base/interconnect_channels.h b/ydb/core/base/interconnect_channels.h
index 4e88f871c62..1e1a0b80592 100644
--- a/ydb/core/base/interconnect_channels.h
+++ b/ydb/core/base/interconnect_channels.h
@@ -7,10 +7,10 @@ struct TInterconnectChannels {
enum EInterconnectChannels {
IC_COMMON,
IC_BLOBSTORAGE,
- IC_BLOBSTORAGE_ASYNC_DATA,
- IC_BLOBSTORAGE_SYNCER,
- IC_BLOBSTORAGE_DISCOVER,
- IC_BLOBSTORAGE_SMALL_MSG,
+ IC_BLOBSTORAGE_ASYNC_DATA,
+ IC_BLOBSTORAGE_SYNCER,
+ IC_BLOBSTORAGE_DISCOVER,
+ IC_BLOBSTORAGE_SMALL_MSG,
IC_TABLETS_SMALL, // < 1 KB
IC_TABLETS_MEDIUM, // < 1 MB
IC_TABLETS_LARGE, // > 1 MB
diff --git a/ydb/core/base/location.h b/ydb/core/base/location.h
index fa6e4ff00d6..29381d03e54 100644
--- a/ydb/core/base/location.h
+++ b/ydb/core/base/location.h
@@ -7,7 +7,7 @@
namespace NKikimr {
inline ui32 DataCenterFromString(const TString &dc)
{
- ui32 res = 0;
+ ui32 res = 0;
strncpy(reinterpret_cast<char *>(&res), dc.data(), sizeof(res));
return res;
}
diff --git a/ydb/core/base/logoblob.h b/ydb/core/base/logoblob.h
index 36eea54393a..e7dc500c735 100644
--- a/ydb/core/base/logoblob.h
+++ b/ydb/core/base/logoblob.h
@@ -55,21 +55,21 @@ namespace NKikimr {
memcpy(Raw.X, raw, 3 * sizeof(ui64));
}
- static TLogoBlobID PrevFull(const TLogoBlobID& id, ui32 size) {
- Y_VERIFY(!id.PartId());
- ui64 tablet = id.TabletID();
- ui32 channel = id.Channel();
- ui32 generation = id.Generation();
- ui32 step = id.Step();
- ui32 cookie = id.Cookie();
- // decrement tuple and check for overflow condition
- const bool overflow = ((--cookie &= MaxCookie) == MaxCookie) && (--step == Max<ui32>()) &&
- (--generation == Max<ui32>()) && ((--channel &= MaxChannel) == MaxChannel) &&
- (--tablet == Max<ui64>());
- Y_VERIFY(!overflow);
- return TLogoBlobID(tablet, generation, step, channel, size, cookie);
- }
-
+ static TLogoBlobID PrevFull(const TLogoBlobID& id, ui32 size) {
+ Y_VERIFY(!id.PartId());
+ ui64 tablet = id.TabletID();
+ ui32 channel = id.Channel();
+ ui32 generation = id.Generation();
+ ui32 step = id.Step();
+ ui32 cookie = id.Cookie();
+ // decrement tuple and check for overflow condition
+ const bool overflow = ((--cookie &= MaxCookie) == MaxCookie) && (--step == Max<ui32>()) &&
+ (--generation == Max<ui32>()) && ((--channel &= MaxChannel) == MaxChannel) &&
+ (--tablet == Max<ui64>());
+ Y_VERIFY(!overflow);
+ return TLogoBlobID(tablet, generation, step, channel, size, cookie);
+ }
+
static TLogoBlobID Make(ui64 tabletId, ui32 generation, ui32 step, ui32 channel, ui32 blobSize, ui32 cookie,
ui32 crcMode) {
TLogoBlobID id;
diff --git a/ydb/core/base/pool_stats_collector.cpp b/ydb/core/base/pool_stats_collector.cpp
index 7dcbf28954d..73b4deabf5d 100644
--- a/ydb/core/base/pool_stats_collector.cpp
+++ b/ydb/core/base/pool_stats_collector.cpp
@@ -44,9 +44,9 @@ private:
MiniKQLPoolStats.Update();
TVector<std::tuple<TString, double, ui32>> pools;
- for (const auto& pool : PoolCounters) {
+ for (const auto& pool : PoolCounters) {
pools.emplace_back(pool.Name, pool.Usage, pool.Threads);
- }
+ }
ctx.Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId()), new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(pools));
}
diff --git a/ydb/core/base/services/blobstorage_service_id.h b/ydb/core/base/services/blobstorage_service_id.h
index 43f6eceda65..d30b9bf8065 100644
--- a/ydb/core/base/services/blobstorage_service_id.h
+++ b/ydb/core/base/services/blobstorage_service_id.h
@@ -45,19 +45,19 @@ inline TActorId MakeBlobStorageVDiskID(ui32 node, ui32 pDiskID, ui32 vDiskSlotID
return TActorId(node, TStringBuf(x, 12));
}
-inline std::tuple<ui32, ui32, ui32> DecomposeVDiskServiceId(const TActorId& actorId) {
- Y_VERIFY(actorId.IsService());
- const TStringBuf serviceId = actorId.ServiceId();
- const ui8 *ptr = reinterpret_cast<const ui8*>(serviceId.data());
- Y_VERIFY(serviceId.size() == 12);
- Y_VERIFY(memcmp(ptr, "bsvd", 4) == 0);
- const ui32 nodeId = actorId.NodeId();
- const ui32 pdiskId = (ui32)ptr[4] | (ui32)ptr[5] << 8 | (ui32)ptr[6] << 16 | (ui32)ptr[7] << 24;
- const ui32 vslotId = (ui32)ptr[8] | (ui32)ptr[9] << 8 | (ui32)ptr[10] << 16 | (ui32)ptr[11] << 24;
- Y_VERIFY_DEBUG(actorId == MakeBlobStorageVDiskID(nodeId, pdiskId, vslotId));
- return {nodeId, pdiskId, vslotId};
-}
-
+inline std::tuple<ui32, ui32, ui32> DecomposeVDiskServiceId(const TActorId& actorId) {
+ Y_VERIFY(actorId.IsService());
+ const TStringBuf serviceId = actorId.ServiceId();
+ const ui8 *ptr = reinterpret_cast<const ui8*>(serviceId.data());
+ Y_VERIFY(serviceId.size() == 12);
+ Y_VERIFY(memcmp(ptr, "bsvd", 4) == 0);
+ const ui32 nodeId = actorId.NodeId();
+ const ui32 pdiskId = (ui32)ptr[4] | (ui32)ptr[5] << 8 | (ui32)ptr[6] << 16 | (ui32)ptr[7] << 24;
+ const ui32 vslotId = (ui32)ptr[8] | (ui32)ptr[9] << 8 | (ui32)ptr[10] << 16 | (ui32)ptr[11] << 24;
+ Y_VERIFY_DEBUG(actorId == MakeBlobStorageVDiskID(nodeId, pdiskId, vslotId));
+ return {nodeId, pdiskId, vslotId};
+}
+
inline TActorId MakeBlobStoragePDiskID(ui32 node, ui32 pDiskID) {
char x[12] = {'b','s','p','d','i','s','k', 0};
x[8] = (char)pDiskID;
diff --git a/ydb/core/base/services_assert.cpp b/ydb/core/base/services_assert.cpp
index 97fa3b82221..c3ae5151f6a 100644
--- a/ydb/core/base/services_assert.cpp
+++ b/ydb/core/base/services_assert.cpp
@@ -2,4 +2,4 @@
#include <ydb/core/protos/services.pb.h>
static_assert(static_cast<ui32>(NKikimrServices::EServiceKikimr_MIN) > static_cast<ui32>(NActorsServices::EServiceCommon_MAX), "KIKIMR SERVICES IDs SHOULD BE GREATER THAN COMMON ONES");
-static_assert(NKikimrServices::TActivity::EType_ARRAYSIZE < 640, "ACTOR ACTIVITY TYPES MUST BE NOT VERY BIG TO BE ARRAY INDICES"); // If we would have many different actor activities, it is OK to increase this value.
+static_assert(NKikimrServices::TActivity::EType_ARRAYSIZE < 640, "ACTOR ACTIVITY TYPES MUST BE NOT VERY BIG TO BE ARRAY INDICES"); // If we would have many different actor activities, it is OK to increase this value.
diff --git a/ydb/core/base/statestorage_guardian.cpp b/ydb/core/base/statestorage_guardian.cpp
index f1df97896b5..4565cf8bfc3 100644
--- a/ydb/core/base/statestorage_guardian.cpp
+++ b/ydb/core/base/statestorage_guardian.cpp
@@ -171,8 +171,8 @@ class TReplicaGuardian : public TActorBootstrapped<TReplicaGuardian> {
}
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN;
}
TReplicaGuardian(TGuardedInfo *info, TActorId replica, TActorId guard)
@@ -295,8 +295,8 @@ class TFollowerGuardian : public TActorBootstrapped<TFollowerGuardian> {
DowntimeFrom = TInstant::Max();
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_REPLICA_GUARDIAN;
}
TFollowerGuardian(TFollowerInfo *info, const TActorId replica, const TActorId guard)
@@ -526,8 +526,8 @@ class TTabletGuardian : public TActorBootstrapped<TTabletGuardian> {
}
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_TABLET_GUARDIAN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_TABLET_GUARDIAN;
}
TTabletGuardian(TGuardedInfo *info)
diff --git a/ydb/core/base/statestorage_monitoring.cpp b/ydb/core/base/statestorage_monitoring.cpp
index 5bcc3ec67fa..8728016e2b6 100644
--- a/ydb/core/base/statestorage_monitoring.cpp
+++ b/ydb/core/base/statestorage_monitoring.cpp
@@ -198,8 +198,8 @@ class TStateStorageMonitoringActor : public TActorBootstrapped<TStateStorageMoni
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_MON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_MON;
}
TStateStorageMonitoringActor(ui64 tabletId, const TActorId &sender, const TString &query)
diff --git a/ydb/core/base/statestorage_proxy.cpp b/ydb/core/base/statestorage_proxy.cpp
index 13d396cb0f1..d062313c058 100644
--- a/ydb/core/base/statestorage_proxy.cpp
+++ b/ydb/core/base/statestorage_proxy.cpp
@@ -507,8 +507,8 @@ class TStateStorageProxyRequest : public TActor<TStateStorageProxyRequest> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_PROXY_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_PROXY_REQUEST;
}
TStateStorageProxyRequest(const TIntrusivePtr<TStateStorageInfo> &info, const TIntrusivePtr<TStateStorageInfo> &flowControlledInfo)
@@ -607,8 +607,8 @@ protected:
ui64 UndeliveredCount;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TStateStorageDumpRequest(const TActorId &sender, const TIntrusivePtr<TStateStorageInfo> &info)
@@ -675,8 +675,8 @@ protected:
ui64 TabletID;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TStateStorageDeleteRequest(const TActorId &sender, const TIntrusivePtr<TStateStorageInfo> &info, ui64 tabletId)
@@ -946,8 +946,8 @@ class TStateStorageProxy : public TActor<TStateStorageProxy> {
RegisterDerivedServices(sys, nullptr);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_PROXY;
}
TStateStorageProxy(
@@ -996,8 +996,8 @@ class TStateStorageProxyStub : public TActor<TStateStorageProxyStub> {
nullptr, 0, TMap<TActorId, TActorId>()));
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_PROXY_STUB;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_PROXY_STUB;
}
TStateStorageProxyStub()
diff --git a/ydb/core/base/statestorage_replica.cpp b/ydb/core/base/statestorage_replica.cpp
index aca41acb16a..4e956d82999 100644
--- a/ydb/core/base/statestorage_replica.cpp
+++ b/ydb/core/base/statestorage_replica.cpp
@@ -417,8 +417,8 @@ class TStateStorageReplica : public TActor<TStateStorageReplica> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SS_REPLICA;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SS_REPLICA;
}
TStateStorageReplica(const TIntrusivePtr<TStateStorageInfo> &info, ui32 replicaIndex)
diff --git a/ydb/core/base/tablet_killer.cpp b/ydb/core/base/tablet_killer.cpp
index d46e2c5c895..4cbc3eba636 100644
--- a/ydb/core/base/tablet_killer.cpp
+++ b/ydb/core/base/tablet_killer.cpp
@@ -35,8 +35,8 @@ private:
return Die(ctx);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_KILLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_KILLER;
}
TTabletKillRequest(ui64 tabletId, ui32 nodeId, ui32 maxGeneration)
diff --git a/ydb/core/base/tablet_pipe.h b/ydb/core/base/tablet_pipe.h
index a0420b86724..bd7f0e7fbe4 100644
--- a/ydb/core/base/tablet_pipe.h
+++ b/ydb/core/base/tablet_pipe.h
@@ -74,7 +74,7 @@ namespace NKikimr {
ActorIdToProto(sender, Record.MutableSender());
Record.SetBuffer(buffer.data(), buffer.size());
Record.SetCookie(cookie);
- Record.SetExtendedFormat(extendedFormat);
+ Record.SetExtendedFormat(extendedFormat);
}
void SetSeqNo(ui64 seqNo) {
diff --git a/ydb/core/base/tablet_status_checker.cpp b/ydb/core/base/tablet_status_checker.cpp
index bfb51b8e852..c87ef0f4d8f 100644
--- a/ydb/core/base/tablet_status_checker.cpp
+++ b/ydb/core/base/tablet_status_checker.cpp
@@ -34,8 +34,8 @@ private:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_ACTOR;
}
TTabletStatusCheckRequest(const TActorId &replyTo, TTabletStorageInfo *info)
diff --git a/ydb/core/base/tablet_types.h b/ydb/core/base/tablet_types.h
index f585819299c..a4ee7aa4b1c 100644
--- a/ydb/core/base/tablet_types.h
+++ b/ydb/core/base/tablet_types.h
@@ -38,7 +38,7 @@ public:
static constexpr EType KESUS = Kesus;
static constexpr EType SYS_VIEW_PROCESSOR = SysViewProcessor;
static constexpr EType FILESTORE = FileStore;
- static constexpr EType TESTSHARD = TestShard;
+ static constexpr EType TESTSHARD = TestShard;
static constexpr EType SEQUENCESHARD = SequenceShard;
static constexpr EType REPLICATION_CONTROLLER = ReplicationController;
diff --git a/ydb/core/base/ya.make b/ydb/core/base/ya.make
index 83db5825c3a..9084b9f191a 100644
--- a/ydb/core/base/ya.make
+++ b/ydb/core/base/ya.make
@@ -27,11 +27,11 @@ SRCS(
counters.h
defs.h
domain.h
- event_filter.cpp
- event_filter.h
+ event_filter.cpp
+ event_filter.h
events.h
- group_stat.cpp
- group_stat.h
+ group_stat.cpp
+ group_stat.h
hive.h
interconnect_channels.h
kikimr_issue.cpp
diff --git a/ydb/core/blobstorage/backpressure/common.h b/ydb/core/blobstorage/backpressure/common.h
index 6539a5db84e..435981ba283 100644
--- a/ydb/core/blobstorage/backpressure/common.h
+++ b/ydb/core/blobstorage/backpressure/common.h
@@ -1,17 +1,17 @@
-#pragma once
-
-#include "defs.h"
-
-#define QLOG_LOG_S(marker, priority, stream) LOG_LOG(ctx, priority, NKikimrServices::BS_QUEUE, "%s @%s: %s Marker# %s", \
- LogPrefix.data(), __func__, static_cast<TString>(TStringBuilder() << stream).data(), marker)
-
-#define QLOG_EMERG_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_EMERG , arg)
-#define QLOG_ALERT_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_ALERT , arg)
-#define QLOG_CRIT_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_CRIT , arg)
-#define QLOG_ERROR_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_ERROR , arg)
-#define QLOG_WARN_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_WARN , arg)
-#define QLOG_NOTICE_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_NOTICE, arg)
-#define QLOG_INFO_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_INFO , arg)
-#define QLOG_DEBUG_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_DEBUG , arg)
-
-LWTRACE_USING(BLOBSTORAGE_PROVIDER);
+#pragma once
+
+#include "defs.h"
+
+#define QLOG_LOG_S(marker, priority, stream) LOG_LOG(ctx, priority, NKikimrServices::BS_QUEUE, "%s @%s: %s Marker# %s", \
+ LogPrefix.data(), __func__, static_cast<TString>(TStringBuilder() << stream).data(), marker)
+
+#define QLOG_EMERG_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_EMERG , arg)
+#define QLOG_ALERT_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_ALERT , arg)
+#define QLOG_CRIT_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_CRIT , arg)
+#define QLOG_ERROR_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_ERROR , arg)
+#define QLOG_WARN_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_WARN , arg)
+#define QLOG_NOTICE_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_NOTICE, arg)
+#define QLOG_INFO_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_INFO , arg)
+#define QLOG_DEBUG_S(marker, arg) QLOG_LOG_S(marker, NActors::NLog::PRI_DEBUG , arg)
+
+LWTRACE_USING(BLOBSTORAGE_PROVIDER);
diff --git a/ydb/core/blobstorage/backpressure/defs.h b/ydb/core/blobstorage/backpressure/defs.h
index d510a3545eb..7765499dfd7 100644
--- a/ydb/core/blobstorage/backpressure/defs.h
+++ b/ydb/core/blobstorage/backpressure/defs.h
@@ -11,11 +11,11 @@
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/base/interconnect_channels.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/mailbox.h>
-#include <library/cpp/actors/core/mon.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/monlib/dynamic_counters/counters.h>
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/mailbox.h>
+#include <library/cpp/actors/core/mon.h>
#include <library/cpp/containers/intrusive_rb_tree/rb_tree.h>
#include <google/protobuf/message.h>
diff --git a/ydb/core/blobstorage/backpressure/event.cpp b/ydb/core/blobstorage/backpressure/event.cpp
index cc04981615a..5c1d60c811d 100644
--- a/ydb/core/blobstorage/backpressure/event.cpp
+++ b/ydb/core/blobstorage/backpressure/event.cpp
@@ -1,90 +1,90 @@
-#include "event.h"
-
-namespace NKikimr::NBsQueue {
-
-IEventBase *TEventHolder::MakeErrorReply(NKikimrProto::EReplyStatus status, const TString& errorReason,
- const NMonitoring::TDynamicCounters::TCounterPtr& deserItems,
- const NMonitoring::TDynamicCounters::TCounterPtr& deserBytes) {
- auto callback = [&](auto *event) -> IEventBase* {
- using T = std::remove_pointer_t<decltype(event)>;
- std::unique_ptr<T> temp;
-
- if (!event) {
- // if there is no local event in holder, we have to deserialize it
- temp.reset(static_cast<T*>(T::Load(Buffer.Get())));
- event = temp.get();
- ++*deserItems;
- *deserBytes += ByteSize;
- }
-
- auto res = std::make_unique<TMatchingResultTypeT<T>>();
- res->MakeError(status, std::move(errorReason), event->Record);
- return res.release();
- };
-
- return Apply(callback);
-}
-
+#include "event.h"
+
+namespace NKikimr::NBsQueue {
+
+IEventBase *TEventHolder::MakeErrorReply(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ const NMonitoring::TDynamicCounters::TCounterPtr& deserItems,
+ const NMonitoring::TDynamicCounters::TCounterPtr& deserBytes) {
+ auto callback = [&](auto *event) -> IEventBase* {
+ using T = std::remove_pointer_t<decltype(event)>;
+ std::unique_ptr<T> temp;
+
+ if (!event) {
+ // if there is no local event in holder, we have to deserialize it
+ temp.reset(static_cast<T*>(T::Load(Buffer.Get())));
+ event = temp.get();
+ ++*deserItems;
+ *deserBytes += ByteSize;
+ }
+
+ auto res = std::make_unique<TMatchingResultTypeT<T>>();
+ res->MakeError(status, std::move(errorReason), event->Record);
+ return res.release();
+ };
+
+ return Apply(callback);
+}
+
void TEventHolder::SendToVDisk(const TActorContext& ctx, const TActorId& remoteVDisk, ui64 queueCookie, ui64 msgId,
- ui64 sequenceId, bool sendMeCostSettings, NWilson::TTraceId traceId, const NBackpressure::TQueueClientId& clientId,
- const THPTimer& processingTimer) {
- // check that we are not discarded yet
- Y_VERIFY(Type != 0);
-
- auto processMsgQoS = [&](auto& record) {
- // prepare extra buffer with some changed params
- NKikimrBlobStorage::TMsgQoS& msgQoS = *record.MutableMsgQoS();
- if (sendMeCostSettings) {
- msgQoS.SetSendMeCostSettings(true);
- }
- NKikimrBlobStorage::TMessageId& id = *msgQoS.MutableMsgId();
- id.SetMsgId(msgId);
- id.SetSequenceId(sequenceId);
- clientId.Serialize(&msgQoS);
-
- // update in sender queue duration
- TDuration inSenderQueue = TDuration::Seconds(processingTimer.Passed());
- NKikimrBlobStorage::TExecTimeStats& execTimeStats = *msgQoS.MutableExecTimeStats();
- execTimeStats.SetInSenderQueue(inSenderQueue.GetValue());
- LWTRACK(DSQueueVPutIsSent, Orbit, inSenderQueue.SecondsFloat() * 1e3);
- };
-
- const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel, IEventHandle::FlagTrackDelivery);
-
- if (LocalEvent) {
- auto callback = [&](auto *ev) -> std::unique_ptr<IEventBase> {
- using T = std::remove_pointer_t<decltype(ev)>;
- processMsgQoS(ev->Record);
- auto clone = std::make_unique<T>();
- clone->Record.CopyFrom(ev->Record);
- for (ui32 i = 0, count = ev->GetPayloadCount(); i < count; ++i) {
- clone->AddPayload(TRope(ev->GetPayload(i)));
- }
- return clone;
- };
- ctx.Send(remoteVDisk, Apply(callback).release(), flags, queueCookie, std::move(traceId));
- } else {
- // FIXME: ensure that MsgQoS has the same field identifier in all structures
- NKikimrBlobStorage::TEvVPut record;
- processMsgQoS(record);
-
- // serialize that extra buffer
- TString buf;
- const bool status = record.SerializeToString(&buf);
- Y_VERIFY(status);
-
- // send it to disk
- ctx.ExecutorThread.Send(new IEventHandle(Type, flags, remoteVDisk, ctx.SelfID,
- MakeIntrusive<TEventSerializedData>(*Buffer, std::move(buf)), queueCookie, nullptr, std::move(traceId)));
- }
-}
-
-void TEventHolder::Discard() {
- if (std::exchange(Type, 0)) {
- BSProxyCtx->Queue.Subtract(ByteSize);
- Buffer.Reset();
- LocalEvent.reset();
- }
-}
-
-} // NKikimr::NBsQueue
+ ui64 sequenceId, bool sendMeCostSettings, NWilson::TTraceId traceId, const NBackpressure::TQueueClientId& clientId,
+ const THPTimer& processingTimer) {
+ // check that we are not discarded yet
+ Y_VERIFY(Type != 0);
+
+ auto processMsgQoS = [&](auto& record) {
+ // prepare extra buffer with some changed params
+ NKikimrBlobStorage::TMsgQoS& msgQoS = *record.MutableMsgQoS();
+ if (sendMeCostSettings) {
+ msgQoS.SetSendMeCostSettings(true);
+ }
+ NKikimrBlobStorage::TMessageId& id = *msgQoS.MutableMsgId();
+ id.SetMsgId(msgId);
+ id.SetSequenceId(sequenceId);
+ clientId.Serialize(&msgQoS);
+
+ // update in sender queue duration
+ TDuration inSenderQueue = TDuration::Seconds(processingTimer.Passed());
+ NKikimrBlobStorage::TExecTimeStats& execTimeStats = *msgQoS.MutableExecTimeStats();
+ execTimeStats.SetInSenderQueue(inSenderQueue.GetValue());
+ LWTRACK(DSQueueVPutIsSent, Orbit, inSenderQueue.SecondsFloat() * 1e3);
+ };
+
+ const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel, IEventHandle::FlagTrackDelivery);
+
+ if (LocalEvent) {
+ auto callback = [&](auto *ev) -> std::unique_ptr<IEventBase> {
+ using T = std::remove_pointer_t<decltype(ev)>;
+ processMsgQoS(ev->Record);
+ auto clone = std::make_unique<T>();
+ clone->Record.CopyFrom(ev->Record);
+ for (ui32 i = 0, count = ev->GetPayloadCount(); i < count; ++i) {
+ clone->AddPayload(TRope(ev->GetPayload(i)));
+ }
+ return clone;
+ };
+ ctx.Send(remoteVDisk, Apply(callback).release(), flags, queueCookie, std::move(traceId));
+ } else {
+ // FIXME: ensure that MsgQoS has the same field identifier in all structures
+ NKikimrBlobStorage::TEvVPut record;
+ processMsgQoS(record);
+
+ // serialize that extra buffer
+ TString buf;
+ const bool status = record.SerializeToString(&buf);
+ Y_VERIFY(status);
+
+ // send it to disk
+ ctx.ExecutorThread.Send(new IEventHandle(Type, flags, remoteVDisk, ctx.SelfID,
+ MakeIntrusive<TEventSerializedData>(*Buffer, std::move(buf)), queueCookie, nullptr, std::move(traceId)));
+ }
+}
+
+void TEventHolder::Discard() {
+ if (std::exchange(Type, 0)) {
+ BSProxyCtx->Queue.Subtract(ByteSize);
+ Buffer.Reset();
+ LocalEvent.reset();
+ }
+}
+
+} // NKikimr::NBsQueue
diff --git a/ydb/core/blobstorage/backpressure/event.h b/ydb/core/blobstorage/backpressure/event.h
index 7b8ea72d4c2..e120ba26eb8 100644
--- a/ydb/core/blobstorage/backpressure/event.h
+++ b/ydb/core/blobstorage/backpressure/event.h
@@ -1,144 +1,144 @@
-#pragma once
-
-#include "defs.h"
-#include "common.h"
-
-namespace NKikimr::NBsQueue {
-
-template<typename T> struct TMatchingResultType;
+#pragma once
+
+#include "defs.h"
+#include "common.h"
+
+namespace NKikimr::NBsQueue {
+
+template<typename T> struct TMatchingResultType;
template<> struct TMatchingResultType<TEvBlobStorage::TEvVMovedPatch> { using Type = TEvBlobStorage::TEvVMovedPatchResult; };
template<> struct TMatchingResultType<TEvBlobStorage::TEvVPatchStart> { using Type = TEvBlobStorage::TEvVPatchFoundParts; };
template<> struct TMatchingResultType<TEvBlobStorage::TEvVPatchDiff> { using Type = TEvBlobStorage::TEvVPatchResult; };
template<> struct TMatchingResultType<TEvBlobStorage::TEvVPatchXorDiff> { using Type = TEvBlobStorage::TEvVPatchXorDiffResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVPut> { using Type = TEvBlobStorage::TEvVPutResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVMultiPut> { using Type = TEvBlobStorage::TEvVMultiPutResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVGet> { using Type = TEvBlobStorage::TEvVGetResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVBlock> { using Type = TEvBlobStorage::TEvVBlockResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVGetBlock> { using Type = TEvBlobStorage::TEvVGetBlockResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVCollectGarbage> { using Type = TEvBlobStorage::TEvVCollectGarbageResult; };
-template<> struct TMatchingResultType<TEvBlobStorage::TEvVGetBarrier> { using Type = TEvBlobStorage::TEvVGetBarrierResult; };
-template<typename T> using TMatchingResultTypeT = typename TMatchingResultType<T>::Type;
-
-template<typename TPtr>
-inline NLWTrace::TOrbit MoveOrbit(TPtr&) {
- return {};
-}
-
-template<>
-inline NLWTrace::TOrbit MoveOrbit<TEvBlobStorage::TEvVPut::TPtr>(TEvBlobStorage::TEvVPut::TPtr& ev) {
- Y_VERIFY(ev->Get());
- return std::move(ev->Get()->Orbit);
-}
-
-class TEventHolder {
- ui32 Type;
- ui32 ByteSize;
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVPut> { using Type = TEvBlobStorage::TEvVPutResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVMultiPut> { using Type = TEvBlobStorage::TEvVMultiPutResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVGet> { using Type = TEvBlobStorage::TEvVGetResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVBlock> { using Type = TEvBlobStorage::TEvVBlockResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVGetBlock> { using Type = TEvBlobStorage::TEvVGetBlockResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVCollectGarbage> { using Type = TEvBlobStorage::TEvVCollectGarbageResult; };
+template<> struct TMatchingResultType<TEvBlobStorage::TEvVGetBarrier> { using Type = TEvBlobStorage::TEvVGetBarrierResult; };
+template<typename T> using TMatchingResultTypeT = typename TMatchingResultType<T>::Type;
+
+template<typename TPtr>
+inline NLWTrace::TOrbit MoveOrbit(TPtr&) {
+ return {};
+}
+
+template<>
+inline NLWTrace::TOrbit MoveOrbit<TEvBlobStorage::TEvVPut::TPtr>(TEvBlobStorage::TEvVPut::TPtr& ev) {
+ Y_VERIFY(ev->Get());
+ return std::move(ev->Get()->Orbit);
+}
+
+class TEventHolder {
+ ui32 Type;
+ ui32 ByteSize;
TActorId Sender;
- ui64 Cookie;
- ui32 InterconnectChannel;
- mutable NLWTrace::TOrbit Orbit;
- TIntrusivePtr<TEventSerializedData> Buffer;
- TBSProxyContextPtr BSProxyCtx;
- std::unique_ptr<IEventBase> LocalEvent;
-
-public:
- TEventHolder()
- : Type(0)
- , ByteSize(0)
- , Cookie(0)
- , InterconnectChannel(0)
- {}
-
- template<typename TPtr>
- TEventHolder(TPtr& ev, const NMonitoring::TDynamicCounters::TCounterPtr& serItems,
- const NMonitoring::TDynamicCounters::TCounterPtr& serBytes, const TBSProxyContextPtr& bspctx,
- ui32 interconnectChannel, bool local)
- : Type(ev->GetTypeRewrite())
- , Sender(ev->Sender)
- , Cookie(ev->Cookie)
- , InterconnectChannel(interconnectChannel)
- , Orbit(MoveOrbit(ev))
- , BSProxyCtx(bspctx)
- {
- // trace the event
- if constexpr (std::is_same_v<TPtr, TEvBlobStorage::TEvVPut::TPtr>) {
- const auto& record = ev->Get()->Record;
- TLogoBlobID blob = LogoBlobIDFromLogoBlobID(record.GetBlobID());
- TVDiskID vDiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- LWTRACK(DSQueueVPutIsQueued, Orbit, vDiskId.GroupID, blob.ToString(), blob.Channel(), blob.PartId(),
- blob.BlobSize());
- }
-
- if (local && ev->HasEvent()) {
- ByteSize = ev->Get()->GetCachedByteSize();
- LocalEvent.reset(ev->ReleaseBase().Release());
- } else {
- const bool hasEvent = ev->HasEvent();
- Buffer = ev->ReleaseChainBuffer();
- ByteSize = Buffer->GetSize();
- if (hasEvent) {
- ++*serItems;
- *serBytes += ByteSize;
- }
- }
-
- BSProxyCtx->Queue.Add(ByteSize);
- ev.Reset();
- }
-
- ~TEventHolder() {
- Discard();
- }
-
- ui32 GetByteSize() const {
- return ByteSize;
- }
-
- template<typename TCallable>
- auto Apply(TCallable&& callable) {
- switch (Type) {
-#define CASE(T) case TEvBlobStorage::T::EventType: return callable(static_cast<TEvBlobStorage::T*>(LocalEvent.get()))
+ ui64 Cookie;
+ ui32 InterconnectChannel;
+ mutable NLWTrace::TOrbit Orbit;
+ TIntrusivePtr<TEventSerializedData> Buffer;
+ TBSProxyContextPtr BSProxyCtx;
+ std::unique_ptr<IEventBase> LocalEvent;
+
+public:
+ TEventHolder()
+ : Type(0)
+ , ByteSize(0)
+ , Cookie(0)
+ , InterconnectChannel(0)
+ {}
+
+ template<typename TPtr>
+ TEventHolder(TPtr& ev, const NMonitoring::TDynamicCounters::TCounterPtr& serItems,
+ const NMonitoring::TDynamicCounters::TCounterPtr& serBytes, const TBSProxyContextPtr& bspctx,
+ ui32 interconnectChannel, bool local)
+ : Type(ev->GetTypeRewrite())
+ , Sender(ev->Sender)
+ , Cookie(ev->Cookie)
+ , InterconnectChannel(interconnectChannel)
+ , Orbit(MoveOrbit(ev))
+ , BSProxyCtx(bspctx)
+ {
+ // trace the event
+ if constexpr (std::is_same_v<TPtr, TEvBlobStorage::TEvVPut::TPtr>) {
+ const auto& record = ev->Get()->Record;
+ TLogoBlobID blob = LogoBlobIDFromLogoBlobID(record.GetBlobID());
+ TVDiskID vDiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ LWTRACK(DSQueueVPutIsQueued, Orbit, vDiskId.GroupID, blob.ToString(), blob.Channel(), blob.PartId(),
+ blob.BlobSize());
+ }
+
+ if (local && ev->HasEvent()) {
+ ByteSize = ev->Get()->GetCachedByteSize();
+ LocalEvent.reset(ev->ReleaseBase().Release());
+ } else {
+ const bool hasEvent = ev->HasEvent();
+ Buffer = ev->ReleaseChainBuffer();
+ ByteSize = Buffer->GetSize();
+ if (hasEvent) {
+ ++*serItems;
+ *serBytes += ByteSize;
+ }
+ }
+
+ BSProxyCtx->Queue.Add(ByteSize);
+ ev.Reset();
+ }
+
+ ~TEventHolder() {
+ Discard();
+ }
+
+ ui32 GetByteSize() const {
+ return ByteSize;
+ }
+
+ template<typename TCallable>
+ auto Apply(TCallable&& callable) {
+ switch (Type) {
+#define CASE(T) case TEvBlobStorage::T::EventType: return callable(static_cast<TEvBlobStorage::T*>(LocalEvent.get()))
CASE(TEvVMovedPatch);
CASE(TEvVPatchStart);
CASE(TEvVPatchDiff);
CASE(TEvVPatchXorDiff);
- CASE(TEvVPut);
- CASE(TEvVMultiPut);
- CASE(TEvVGet);
- CASE(TEvVBlock);
- CASE(TEvVGetBlock);
- CASE(TEvVCollectGarbage);
- CASE(TEvVGetBarrier);
- default: Y_FAIL();
-#undef CASE
- }
- }
-
- IEventBase *MakeErrorReply(NKikimrProto::EReplyStatus status, const TString& errorReason,
- const NMonitoring::TDynamicCounters::TCounterPtr& deserItems,
- const NMonitoring::TDynamicCounters::TCounterPtr& deserBytes);
-
- ui32 GetType() const {
- return Type;
- }
-
+ CASE(TEvVPut);
+ CASE(TEvVMultiPut);
+ CASE(TEvVGet);
+ CASE(TEvVBlock);
+ CASE(TEvVGetBlock);
+ CASE(TEvVCollectGarbage);
+ CASE(TEvVGetBarrier);
+ default: Y_FAIL();
+#undef CASE
+ }
+ }
+
+ IEventBase *MakeErrorReply(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ const NMonitoring::TDynamicCounters::TCounterPtr& deserItems,
+ const NMonitoring::TDynamicCounters::TCounterPtr& deserBytes);
+
+ ui32 GetType() const {
+ return Type;
+ }
+
const TActorId& GetSender() const {
- return Sender;
- }
-
- ui64 GetCookie() const {
- return Cookie;
- }
-
- NLWTrace::TOrbit& GetOrbit() const {
- return Orbit;
- }
-
+ return Sender;
+ }
+
+ ui64 GetCookie() const {
+ return Cookie;
+ }
+
+ NLWTrace::TOrbit& GetOrbit() const {
+ return Orbit;
+ }
+
void SendToVDisk(const TActorContext& ctx, const TActorId& remoteVDisk, ui64 queueCookie, ui64 msgId, ui64 sequenceId,
- bool sendMeCostSettings, NWilson::TTraceId traceId, const NBackpressure::TQueueClientId& clientId,
- const THPTimer& processingTimer);
-
- void Discard();
-};
-
-} // NKikimr::NBsQueue
+ bool sendMeCostSettings, NWilson::TTraceId traceId, const NBackpressure::TQueueClientId& clientId,
+ const THPTimer& processingTimer);
+
+ void Discard();
+};
+
+} // NKikimr::NBsQueue
diff --git a/ydb/core/blobstorage/backpressure/queue.cpp b/ydb/core/blobstorage/backpressure/queue.cpp
index c573b7b16b4..41834c482fa 100644
--- a/ydb/core/blobstorage/backpressure/queue.cpp
+++ b/ydb/core/blobstorage/backpressure/queue.cpp
@@ -1,21 +1,21 @@
-#include "queue.h"
-
-namespace NKikimr::NBsQueue {
-
-TBlobStorageQueue::TBlobStorageQueue(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, TString& logPrefix,
- const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, ui32 interconnectChannel,
+#include "queue.h"
+
+namespace NKikimr::NBsQueue {
+
+TBlobStorageQueue::TBlobStorageQueue(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, TString& logPrefix,
+ const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, ui32 interconnectChannel,
const TBlobStorageGroupType& gType, NMonitoring::TCountableBase::EVisibility visibility)
- : Queues(bspctx)
- , WindowSize(0)
- , InFlightCost(0)
- , NextMsgId(0)
- , CurrentSequenceId(1)
- , LogPrefix(logPrefix)
+ : Queues(bspctx)
+ , WindowSize(0)
+ , InFlightCost(0)
+ , NextMsgId(0)
+ , CurrentSequenceId(1)
+ , LogPrefix(logPrefix)
, CostModel(2000, 100000000, 50000000, 540000, 540000, 500000, gType) // default cost model
- , BSProxyCtx(bspctx)
- , ClientId(clientId)
- , BytesWaiting(0)
- , InterconnectChannel(interconnectChannel)
+ , BSProxyCtx(bspctx)
+ , ClientId(clientId)
+ , BytesWaiting(0)
+ , InterconnectChannel(interconnectChannel)
// use parent group visibility
, QueueWaitingItems(counters->GetCounter("QueueWaitingItems", false, visibility))
, QueueWaitingBytes(counters->GetCounter("QueueWaitingBytes", false, visibility))
@@ -38,327 +38,327 @@ TBlobStorageQueue::TBlobStorageQueue(const TIntrusivePtr<NMonitoring::TDynamicCo
, QueueDeserializedItems(counters->GetCounter("QueueDeserializedItems", true, visibility))
, QueueDeserializedBytes(counters->GetCounter("QueueDeserializedBytes", true, visibility))
, QueueSize(counters->GetCounter("QueueSize", false, visibility))
-{}
-
-TBlobStorageQueue::~TBlobStorageQueue() {
- SetMaxWindowSize(0);
- for (TItemList *queue : {&Queues.Waiting, &Queues.InFlight, &Queues.Unused}) {
- for (TItem& item : *queue) {
- SetItemQueue(item, EItemQueue::NotSet);
- }
- }
-}
-
+{}
+
+TBlobStorageQueue::~TBlobStorageQueue() {
+ SetMaxWindowSize(0);
+ for (TItemList *queue : {&Queues.Waiting, &Queues.InFlight, &Queues.Unused}) {
+ for (TItem& item : *queue) {
+ SetItemQueue(item, EItemQueue::NotSet);
+ }
+ }
+}
+
void TBlobStorageQueue::UpdateCostModel(TInstant now, const NKikimrBlobStorage::TVDiskCostSettings& settings,
const TBlobStorageGroupType& type) {
TCostModel newCostModel(settings, type);
- if (newCostModel != CostModel) {
- CostModel = std::move(newCostModel);
- InvalidateCosts();
- }
- CostSettingsUpdate = now + TDuration::Minutes(1);
-}
-
-void TBlobStorageQueue::InvalidateCosts() {
- for (TItem& item : Queues.Waiting) {
- item.DirtyCost = true;
- }
- for (TItem& item : Queues.InFlight) {
- item.DirtyCost = true;
- }
-}
-
-bool TBlobStorageQueue::SetMaxWindowSize(ui64 maxWindowSize) {
- if (WindowSize != maxWindowSize) {
- *QueueWindowSize += (i64)(maxWindowSize - WindowSize);
- WindowSize = maxWindowSize;
- return true;
- } else {
- return false;
- }
-}
-
-void TBlobStorageQueue::SetItemQueue(TItem& item, EItemQueue newQueue) {
- switch (item.Queue) {
- case EItemQueue::NotSet:
- break;
-
- case EItemQueue::Waiting:
- --*QueueWaitingItems;
- *QueueWaitingBytes -= item.GetByteSize();
- BytesWaiting -= item.GetByteSize();
- break;
-
- case EItemQueue::InFlight:
- --*QueueInFlightItems;
- *QueueInFlightBytes -= item.GetByteSize();
- *QueueInFlightCost -= item.Cost;
- break;
- }
-
- item.Queue = newQueue;
- switch (newQueue) {
- case EItemQueue::NotSet:
- break;
-
- case EItemQueue::Waiting:
- ++*QueueWaitingItems;
- *QueueWaitingBytes += item.GetByteSize();
- BytesWaiting += item.GetByteSize();
- break;
-
- case EItemQueue::InFlight:
- ++*QueueInFlightItems;
- *QueueInFlightBytes += item.GetByteSize();
- *QueueInFlightCost += item.Cost;
- break;
- }
-}
-
+ if (newCostModel != CostModel) {
+ CostModel = std::move(newCostModel);
+ InvalidateCosts();
+ }
+ CostSettingsUpdate = now + TDuration::Minutes(1);
+}
+
+void TBlobStorageQueue::InvalidateCosts() {
+ for (TItem& item : Queues.Waiting) {
+ item.DirtyCost = true;
+ }
+ for (TItem& item : Queues.InFlight) {
+ item.DirtyCost = true;
+ }
+}
+
+bool TBlobStorageQueue::SetMaxWindowSize(ui64 maxWindowSize) {
+ if (WindowSize != maxWindowSize) {
+ *QueueWindowSize += (i64)(maxWindowSize - WindowSize);
+ WindowSize = maxWindowSize;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void TBlobStorageQueue::SetItemQueue(TItem& item, EItemQueue newQueue) {
+ switch (item.Queue) {
+ case EItemQueue::NotSet:
+ break;
+
+ case EItemQueue::Waiting:
+ --*QueueWaitingItems;
+ *QueueWaitingBytes -= item.GetByteSize();
+ BytesWaiting -= item.GetByteSize();
+ break;
+
+ case EItemQueue::InFlight:
+ --*QueueInFlightItems;
+ *QueueInFlightBytes -= item.GetByteSize();
+ *QueueInFlightCost -= item.Cost;
+ break;
+ }
+
+ item.Queue = newQueue;
+ switch (newQueue) {
+ case EItemQueue::NotSet:
+ break;
+
+ case EItemQueue::Waiting:
+ ++*QueueWaitingItems;
+ *QueueWaitingBytes += item.GetByteSize();
+ BytesWaiting += item.GetByteSize();
+ break;
+
+ case EItemQueue::InFlight:
+ ++*QueueInFlightItems;
+ *QueueInFlightBytes += item.GetByteSize();
+ *QueueInFlightCost += item.Cost;
+ break;
+ }
+}
+
void TBlobStorageQueue::SendToVDisk(const TActorContext& ctx, const TActorId& remoteVDisk, IActor *actor) {
- const TInstant now = ctx.Now();
-
- const bool sendMeCostSettings = now >= CostSettingsUpdate;
-
- for (auto it = Queues.Waiting.begin(); !Paused && it != Queues.Waiting.end(); ) {
- Y_VERIFY(it == Queues.Waiting.begin());
- TItem& item = *it;
-
- // check if deadline occured
- if (now >= item.Deadline) {
- ReplyWithError(item, NKikimrProto::DEADLINE, "deadline exceeded", ctx);
- it = EraseItem(Queues.Waiting, it);
- continue;
- }
-
- // update item parameters
- item.MsgId = NextMsgId;
- item.SequenceId = CurrentSequenceId;
-
- // update item's cost if it is dirty
- if (item.DirtyCost) {
- item.Cost = CostModel.CalculateCost(item.CostEssence);
- item.DirtyCost = false;
- }
-
- const bool postpone = InFlightCost + item.Cost > WindowSize && InFlightCount();
-
- auto getTypeName = [&]() -> TString {
- switch (item.Event.GetType()) {
-#define TYPE_CASE(X) case X::EventType: return #X;
+ const TInstant now = ctx.Now();
+
+ const bool sendMeCostSettings = now >= CostSettingsUpdate;
+
+ for (auto it = Queues.Waiting.begin(); !Paused && it != Queues.Waiting.end(); ) {
+ Y_VERIFY(it == Queues.Waiting.begin());
+ TItem& item = *it;
+
+ // check if deadline occured
+ if (now >= item.Deadline) {
+ ReplyWithError(item, NKikimrProto::DEADLINE, "deadline exceeded", ctx);
+ it = EraseItem(Queues.Waiting, it);
+ continue;
+ }
+
+ // update item parameters
+ item.MsgId = NextMsgId;
+ item.SequenceId = CurrentSequenceId;
+
+ // update item's cost if it is dirty
+ if (item.DirtyCost) {
+ item.Cost = CostModel.CalculateCost(item.CostEssence);
+ item.DirtyCost = false;
+ }
+
+ const bool postpone = InFlightCost + item.Cost > WindowSize && InFlightCount();
+
+ auto getTypeName = [&]() -> TString {
+ switch (item.Event.GetType()) {
+#define TYPE_CASE(X) case X::EventType: return #X;
TYPE_CASE(TEvBlobStorage::TEvVMovedPatch)
- TYPE_CASE(TEvBlobStorage::TEvVPut)
- TYPE_CASE(TEvBlobStorage::TEvVMultiPut)
- TYPE_CASE(TEvBlobStorage::TEvVGet)
- TYPE_CASE(TEvBlobStorage::TEvVBlock)
- TYPE_CASE(TEvBlobStorage::TEvVGetBlock)
- TYPE_CASE(TEvBlobStorage::TEvVCollectGarbage)
- TYPE_CASE(TEvBlobStorage::TEvVGetBarrier)
- TYPE_CASE(TEvBlobStorage::TEvVStatus)
-#undef TYPE_CASE
- default:
- return Sprintf("0x%08" PRIx32, item.Event.GetType());
- }
- };
-
- QLOG_DEBUG_S("BSQ25", "sending"
- << " T# " << getTypeName()
- << " SequenceId# " << item.SequenceId
- << " MsgId# " << item.MsgId
- << " Cookie# " << item.QueueCookie
- << " InFlightCost# " << InFlightCost
- << " Cost# " << item.Cost
- << " WindowSize# " << WindowSize
- << " InFlightCount# " << InFlightCount()
- << " Postpone# " << (postpone ? "true" : "false")
- << " SendMeCostSettings# " << (sendMeCostSettings ? "true" : "false"));
-
- // check if window has enough space for such item
- if (postpone) {
- // can't send more items now
- QLOG_DEBUG_S("BSQ26", "Queue overflow: InFlightCost# " << InFlightCost << " WindowSize# "
- << WindowSize << " item.Cost# " << item.Cost << " InFlightCount# " << InFlightCount());
- ++*QueueOverflow;
- break;
- }
- InFlightCost += item.Cost;
-
- // move item to in-flight queue
- SetItemQueue(item, EItemQueue::InFlight);
- const bool inserted = InFlightLookup.emplace(std::make_pair(item.SequenceId, item.MsgId), it).second;
- Y_VERIFY(inserted);
- Queues.InFlight.splice(Queues.InFlight.end(), Queues.Waiting, it++);
- ++*QueueItemsSent;
-
- // send item
- WILSON_TRACE_FROM_ACTOR(ctx, *actor, &item.TraceId, EvBlobStorageQueueForward,
- InQueueWaitingItems = GetItemsWaiting(), InQueueWaitingBytes = GetBytesWaiting());
- item.Event.SendToVDisk(ctx, remoteVDisk, item.QueueCookie, item.MsgId, item.SequenceId, sendMeCostSettings,
- item.TraceId.Clone(), ClientId, item.ProcessingTimer);
-
- // update counters as far as item got sent
- ++NextMsgId;
- }
-}
-
-void TBlobStorageQueue::ReplyWithError(TItem& item, NKikimrProto::EReplyStatus status, const TString& errorReason,
- const TActorContext& ctx) {
- const TDuration processingTime = TDuration::Seconds(item.ProcessingTimer.Passed());
- QLOG_INFO_S("BSQ03", "Reply error type# " << item.Event.GetType()
- << " status# " << NKikimrProto::EReplyStatus_Name(status)
- << " errorReason# " << '"' << EscapeC(errorReason) << '"'
- << " cookie# " << item.Event.GetCookie()
- << " processingTime# " << processingTime);
-
- ctx.Send(item.Event.GetSender(), item.Event.MakeErrorReply(status, errorReason, QueueDeserializedItems,
- QueueDeserializedBytes), 0, item.Event.GetCookie());
-
- ++*QueueItemsRejected;
-}
-
-bool TBlobStorageQueue::Expecting(ui64 msgId, ui64 sequenceId) const {
- return InFlightLookup.count(std::make_pair(sequenceId, msgId));
-}
-
+ TYPE_CASE(TEvBlobStorage::TEvVPut)
+ TYPE_CASE(TEvBlobStorage::TEvVMultiPut)
+ TYPE_CASE(TEvBlobStorage::TEvVGet)
+ TYPE_CASE(TEvBlobStorage::TEvVBlock)
+ TYPE_CASE(TEvBlobStorage::TEvVGetBlock)
+ TYPE_CASE(TEvBlobStorage::TEvVCollectGarbage)
+ TYPE_CASE(TEvBlobStorage::TEvVGetBarrier)
+ TYPE_CASE(TEvBlobStorage::TEvVStatus)
+#undef TYPE_CASE
+ default:
+ return Sprintf("0x%08" PRIx32, item.Event.GetType());
+ }
+ };
+
+ QLOG_DEBUG_S("BSQ25", "sending"
+ << " T# " << getTypeName()
+ << " SequenceId# " << item.SequenceId
+ << " MsgId# " << item.MsgId
+ << " Cookie# " << item.QueueCookie
+ << " InFlightCost# " << InFlightCost
+ << " Cost# " << item.Cost
+ << " WindowSize# " << WindowSize
+ << " InFlightCount# " << InFlightCount()
+ << " Postpone# " << (postpone ? "true" : "false")
+ << " SendMeCostSettings# " << (sendMeCostSettings ? "true" : "false"));
+
+ // check if window has enough space for such item
+ if (postpone) {
+ // can't send more items now
+ QLOG_DEBUG_S("BSQ26", "Queue overflow: InFlightCost# " << InFlightCost << " WindowSize# "
+ << WindowSize << " item.Cost# " << item.Cost << " InFlightCount# " << InFlightCount());
+ ++*QueueOverflow;
+ break;
+ }
+ InFlightCost += item.Cost;
+
+ // move item to in-flight queue
+ SetItemQueue(item, EItemQueue::InFlight);
+ const bool inserted = InFlightLookup.emplace(std::make_pair(item.SequenceId, item.MsgId), it).second;
+ Y_VERIFY(inserted);
+ Queues.InFlight.splice(Queues.InFlight.end(), Queues.Waiting, it++);
+ ++*QueueItemsSent;
+
+ // send item
+ WILSON_TRACE_FROM_ACTOR(ctx, *actor, &item.TraceId, EvBlobStorageQueueForward,
+ InQueueWaitingItems = GetItemsWaiting(), InQueueWaitingBytes = GetBytesWaiting());
+ item.Event.SendToVDisk(ctx, remoteVDisk, item.QueueCookie, item.MsgId, item.SequenceId, sendMeCostSettings,
+ item.TraceId.Clone(), ClientId, item.ProcessingTimer);
+
+ // update counters as far as item got sent
+ ++NextMsgId;
+ }
+}
+
+void TBlobStorageQueue::ReplyWithError(TItem& item, NKikimrProto::EReplyStatus status, const TString& errorReason,
+ const TActorContext& ctx) {
+ const TDuration processingTime = TDuration::Seconds(item.ProcessingTimer.Passed());
+ QLOG_INFO_S("BSQ03", "Reply error type# " << item.Event.GetType()
+ << " status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " errorReason# " << '"' << EscapeC(errorReason) << '"'
+ << " cookie# " << item.Event.GetCookie()
+ << " processingTime# " << processingTime);
+
+ ctx.Send(item.Event.GetSender(), item.Event.MakeErrorReply(status, errorReason, QueueDeserializedItems,
+ QueueDeserializedBytes), 0, item.Event.GetCookie());
+
+ ++*QueueItemsRejected;
+}
+
+bool TBlobStorageQueue::Expecting(ui64 msgId, ui64 sequenceId) const {
+ return InFlightLookup.count(std::make_pair(sequenceId, msgId));
+}
+
bool TBlobStorageQueue::OnResponse(ui64 msgId, ui64 sequenceId, ui64 cookie, TActorId *outSender, ui64 *outCookie,
- TDuration *processingTime) {
- const auto lookupIt = InFlightLookup.find(std::make_pair(sequenceId, msgId));
- Y_VERIFY(lookupIt != InFlightLookup.end());
- const TItemList::iterator it = lookupIt->second;
-
- Y_VERIFY(cookie == it->QueueCookie || cookie == 0);
-
- Y_VERIFY(InFlightCost >= it->Cost);
- InFlightCost -= it->Cost;
-
- const bool discard = it->Discarded;
-
- *outSender = it->Event.GetSender();
- *outCookie = it->Event.GetCookie();
- *processingTime = TDuration::Seconds(it->ProcessingTimer.Passed());
- LWTRACK(DSQueueVPutResultRecieved, it->Event.GetOrbit(), processingTime->SecondsFloat() * 1e3,
- it->Event.GetByteSize(), discard);
-
- InFlightLookup.erase(lookupIt);
- EraseItem(Queues.InFlight, it);
-
- // unpause execution when InFlight queue gets empty
- if (!InFlightLookup) {
- Paused = false;
- }
-
- ++*QueueItemsProcessed;
- return !discard;
-}
-
-void TBlobStorageQueue::Unwind(ui64 failedMsgId, ui64 failedSequenceId, ui64 expectedMsgId, ui64 expectedSequenceId) {
- // find item in the InFlight queue; it MUST exist in that queue
- const auto lookupIt = InFlightLookup.find(std::make_pair(failedSequenceId, failedMsgId));
- Y_VERIFY(lookupIt != InFlightLookup.end());
- TItemList::iterator it = lookupIt->second;
-
- // process items
- ui64 cost = 0;
- for (auto x = it; x != Queues.InFlight.end(); ) {
- const ui32 erased = InFlightLookup.erase(std::make_pair(x->SequenceId, x->MsgId));
- Y_VERIFY(erased);
- cost += x->Cost; // count item's cost
- if (x->Discarded) {
- if (x == it) {
- ++it; // advance starting iterator as the item pointed to is being erased
- }
- x = EraseItem(Queues.InFlight, x);
- } else {
- SetItemQueue(*x, EItemQueue::Waiting);
- ++x;
- }
- }
- Y_VERIFY(cost <= InFlightCost);
- InFlightCost -= cost;
-
- // splice items into waiting queue's front
- Queues.Waiting.splice(Queues.Waiting.begin(), Queues.InFlight, it, Queues.InFlight.end());
-
- // adjust correct sequence ids
- NextMsgId = expectedMsgId;
- CurrentSequenceId = expectedSequenceId;
-
- // pause execution if we have something unanswered
- Paused = static_cast<bool>(InFlightLookup);
-}
-
-void TBlobStorageQueue::DrainQueue(NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext &ctx) {
- // remove all items from in-flight map
- InFlightCost = 0;
-
- // ACHTUNG: We may expect that if we drop the messages from the queue,
- // then we can safely restart from that point
-
- auto flushQueue = [&](TItemList& queue) {
- for (auto it = queue.begin(); it != queue.end(); it = EraseItem(queue, it)) {
- if (!it->Discarded) {
- ReplyWithError(*it, status, errorReason, ctx);
- }
- }
- };
-
- flushQueue(Queues.InFlight);
- flushQueue(Queues.Waiting);
- InFlightLookup.clear();
-
- Paused = false;
-}
-
-void TBlobStorageQueue::OnConnect() {
- SetMaxWindowSize(1000000000); // default value is one second
- CostSettingsUpdate = TInstant::Zero(); // request cost model update in first message
-}
-
-TBlobStorageQueue::TItemList::iterator TBlobStorageQueue::EraseItem(TItemList& queue, TItemList::iterator it) {
- SetItemQueue(*it, EItemQueue::NotSet);
- TItemList::iterator nextIter = std::next(it);
- if (Queues.Unused.size() < MaxUnusedItems) {
- Queues.Unused.splice(Queues.Unused.end(), queue, it);
- it->TSenderNode::UnLink();
- it->Event.Discard();
- } else {
- queue.erase(it);
- --*QueueSize;
- }
- return nextIter;
-}
-
+ TDuration *processingTime) {
+ const auto lookupIt = InFlightLookup.find(std::make_pair(sequenceId, msgId));
+ Y_VERIFY(lookupIt != InFlightLookup.end());
+ const TItemList::iterator it = lookupIt->second;
+
+ Y_VERIFY(cookie == it->QueueCookie || cookie == 0);
+
+ Y_VERIFY(InFlightCost >= it->Cost);
+ InFlightCost -= it->Cost;
+
+ const bool discard = it->Discarded;
+
+ *outSender = it->Event.GetSender();
+ *outCookie = it->Event.GetCookie();
+ *processingTime = TDuration::Seconds(it->ProcessingTimer.Passed());
+ LWTRACK(DSQueueVPutResultRecieved, it->Event.GetOrbit(), processingTime->SecondsFloat() * 1e3,
+ it->Event.GetByteSize(), discard);
+
+ InFlightLookup.erase(lookupIt);
+ EraseItem(Queues.InFlight, it);
+
+ // unpause execution when InFlight queue gets empty
+ if (!InFlightLookup) {
+ Paused = false;
+ }
+
+ ++*QueueItemsProcessed;
+ return !discard;
+}
+
+void TBlobStorageQueue::Unwind(ui64 failedMsgId, ui64 failedSequenceId, ui64 expectedMsgId, ui64 expectedSequenceId) {
+ // find item in the InFlight queue; it MUST exist in that queue
+ const auto lookupIt = InFlightLookup.find(std::make_pair(failedSequenceId, failedMsgId));
+ Y_VERIFY(lookupIt != InFlightLookup.end());
+ TItemList::iterator it = lookupIt->second;
+
+ // process items
+ ui64 cost = 0;
+ for (auto x = it; x != Queues.InFlight.end(); ) {
+ const ui32 erased = InFlightLookup.erase(std::make_pair(x->SequenceId, x->MsgId));
+ Y_VERIFY(erased);
+ cost += x->Cost; // count item's cost
+ if (x->Discarded) {
+ if (x == it) {
+ ++it; // advance starting iterator as the item pointed to is being erased
+ }
+ x = EraseItem(Queues.InFlight, x);
+ } else {
+ SetItemQueue(*x, EItemQueue::Waiting);
+ ++x;
+ }
+ }
+ Y_VERIFY(cost <= InFlightCost);
+ InFlightCost -= cost;
+
+ // splice items into waiting queue's front
+ Queues.Waiting.splice(Queues.Waiting.begin(), Queues.InFlight, it, Queues.InFlight.end());
+
+ // adjust correct sequence ids
+ NextMsgId = expectedMsgId;
+ CurrentSequenceId = expectedSequenceId;
+
+ // pause execution if we have something unanswered
+ Paused = static_cast<bool>(InFlightLookup);
+}
+
+void TBlobStorageQueue::DrainQueue(NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext &ctx) {
+ // remove all items from in-flight map
+ InFlightCost = 0;
+
+ // ACHTUNG: We may expect that if we drop the messages from the queue,
+ // then we can safely restart from that point
+
+ auto flushQueue = [&](TItemList& queue) {
+ for (auto it = queue.begin(); it != queue.end(); it = EraseItem(queue, it)) {
+ if (!it->Discarded) {
+ ReplyWithError(*it, status, errorReason, ctx);
+ }
+ }
+ };
+
+ flushQueue(Queues.InFlight);
+ flushQueue(Queues.Waiting);
+ InFlightLookup.clear();
+
+ Paused = false;
+}
+
+void TBlobStorageQueue::OnConnect() {
+ SetMaxWindowSize(1000000000); // default value is one second
+ CostSettingsUpdate = TInstant::Zero(); // request cost model update in first message
+}
+
+TBlobStorageQueue::TItemList::iterator TBlobStorageQueue::EraseItem(TItemList& queue, TItemList::iterator it) {
+ SetItemQueue(*it, EItemQueue::NotSet);
+ TItemList::iterator nextIter = std::next(it);
+ if (Queues.Unused.size() < MaxUnusedItems) {
+ Queues.Unused.splice(Queues.Unused.end(), queue, it);
+ it->TSenderNode::UnLink();
+ it->Event.Discard();
+ } else {
+ queue.erase(it);
+ --*QueueSize;
+ }
+ return nextIter;
+}
+
void TBlobStorageQueue::Prune(const TActorId& sender) {
- TSenderMap::TIterator it = SenderToItems.LowerBound(sender);
- while (it != SenderToItems.End()) {
- TItem& item = static_cast<TItem&>(*it++);
- if (item.Event.GetSender() != sender) {
- break;
- }
- switch (item.Queue) {
- case EItemQueue::Waiting:
- EraseItem(Queues.Waiting, item.Iterator);
- break;
-
- case EItemQueue::InFlight:
- item.Discard();
- break;
-
- default:
- Y_FAIL("incorrect item queue state");
- }
- ++*QueueItemsPruned;
- }
-}
-
-TMaybe<TDuration> TBlobStorageQueue::GetWorstRequestProcessingTime() const {
- if (Queues.InFlight.size()) {
- return TDuration::Seconds(Queues.InFlight.front().ProcessingTimer.Passed());
- } else if (Queues.Waiting.size()) {
- return TDuration::Seconds(Queues.Waiting.front().ProcessingTimer.Passed());
- } else {
- return {};
- }
-}
-
-} // NKikimr::NBsQueue
+ TSenderMap::TIterator it = SenderToItems.LowerBound(sender);
+ while (it != SenderToItems.End()) {
+ TItem& item = static_cast<TItem&>(*it++);
+ if (item.Event.GetSender() != sender) {
+ break;
+ }
+ switch (item.Queue) {
+ case EItemQueue::Waiting:
+ EraseItem(Queues.Waiting, item.Iterator);
+ break;
+
+ case EItemQueue::InFlight:
+ item.Discard();
+ break;
+
+ default:
+ Y_FAIL("incorrect item queue state");
+ }
+ ++*QueueItemsPruned;
+ }
+}
+
+TMaybe<TDuration> TBlobStorageQueue::GetWorstRequestProcessingTime() const {
+ if (Queues.InFlight.size()) {
+ return TDuration::Seconds(Queues.InFlight.front().ProcessingTimer.Passed());
+ } else if (Queues.Waiting.size()) {
+ return TDuration::Seconds(Queues.Waiting.front().ProcessingTimer.Passed());
+ } else {
+ return {};
+ }
+}
+
+} // NKikimr::NBsQueue
diff --git a/ydb/core/blobstorage/backpressure/queue.h b/ydb/core/blobstorage/backpressure/queue.h
index 209346cc2db..28a124a5f67 100644
--- a/ydb/core/blobstorage/backpressure/queue.h
+++ b/ydb/core/blobstorage/backpressure/queue.h
@@ -1,238 +1,238 @@
-#pragma once
-
-#include "defs.h"
-#include "common.h"
-#include "event.h"
-
-namespace NKikimr::NBsQueue {
-
-static constexpr size_t MaxUnusedItems = 1024;
-
-class TBlobStorageQueue {
- enum class EItemQueue {
- NotSet,
- Waiting,
- InFlight
- };
-
- template<typename TKey>
- struct TCompare {
- template<typename TItem>
- static bool Compare(const TItem& left, const TItem& right) {
- return left.GetKey() < right.GetKey();
- }
- template<typename TItem>
- static bool Compare(const TKey& left, const TItem& right) {
- return left < right.GetKey();
- }
- template<typename TItem>
- static bool Compare(const TItem& left, const TKey& right) {
- return left.GetKey() < right;
- }
- };
-
- template<typename TDerived>
+#pragma once
+
+#include "defs.h"
+#include "common.h"
+#include "event.h"
+
+namespace NKikimr::NBsQueue {
+
+static constexpr size_t MaxUnusedItems = 1024;
+
+class TBlobStorageQueue {
+ enum class EItemQueue {
+ NotSet,
+ Waiting,
+ InFlight
+ };
+
+ template<typename TKey>
+ struct TCompare {
+ template<typename TItem>
+ static bool Compare(const TItem& left, const TItem& right) {
+ return left.GetKey() < right.GetKey();
+ }
+ template<typename TItem>
+ static bool Compare(const TKey& left, const TItem& right) {
+ return left < right.GetKey();
+ }
+ template<typename TItem>
+ static bool Compare(const TItem& left, const TKey& right) {
+ return left.GetKey() < right;
+ }
+ };
+
+ template<typename TDerived>
struct TSenderNode : public TRbTreeItem<TSenderNode<TDerived>, TCompare<TActorId>> {
const TActorId& GetKey() const {
- return static_cast<const TDerived&>(*this).Event.GetSender();
- }
- };
-
- struct TItem
- : public TSenderNode<TItem>
- {
- EItemQueue Queue;
- TCostModel::TMessageCostEssence CostEssence;
- NWilson::TTraceId TraceId;
- TEventHolder Event;
- ui64 MsgId;
- ui64 SequenceId;
- TInstant Deadline;
- const ui64 QueueCookie;
- ui64 Cost;
- bool DirtyCost;
- bool Discarded;
- THPTimer ProcessingTimer;
- TTrackableList<TItem>::iterator Iterator;
-
- template<typename TPtr>
- TItem(TPtr& event, TInstant deadline,
- const NMonitoring::TDynamicCounters::TCounterPtr& serItems,
- const NMonitoring::TDynamicCounters::TCounterPtr& serBytes,
- const TBSProxyContextPtr& bspctx, ui32 interconnectChannel,
- bool local)
- : Queue(EItemQueue::NotSet)
- , CostEssence(*event->Get())
- , TraceId(std::move(event->TraceId))
- , Event(event, serItems, serBytes, bspctx, interconnectChannel, local)
- , MsgId(Max<ui64>())
- , SequenceId(0)
- , Deadline(deadline)
- , QueueCookie(RandomNumber<ui64>())
- , Cost(0)
- , DirtyCost(true)
- , Discarded(false)
- {}
-
- ~TItem() {
- Y_VERIFY(Queue == EItemQueue::NotSet, "Queue# %" PRIu32, ui32(Queue));
- }
-
- ui32 GetByteSize() const {
- return Event.GetByteSize();
- }
-
- void Discard() {
- Discarded = true;
- Event.Discard();
- }
- };
-
- using TItemList = TTrackableList<TItem>;
-
- struct TQueues {
- TItemList Waiting;
- TItemList InFlight;
- TItemList Unused;
-
- TQueues(const TBSProxyContextPtr& bspctx)
- : Waiting(TMemoryConsumer(bspctx->Queue))
- , InFlight(TMemoryConsumer(bspctx->Queue))
- , Unused(TMemoryConsumer(bspctx->Queue))
- {}
- };
-
+ return static_cast<const TDerived&>(*this).Event.GetSender();
+ }
+ };
+
+ struct TItem
+ : public TSenderNode<TItem>
+ {
+ EItemQueue Queue;
+ TCostModel::TMessageCostEssence CostEssence;
+ NWilson::TTraceId TraceId;
+ TEventHolder Event;
+ ui64 MsgId;
+ ui64 SequenceId;
+ TInstant Deadline;
+ const ui64 QueueCookie;
+ ui64 Cost;
+ bool DirtyCost;
+ bool Discarded;
+ THPTimer ProcessingTimer;
+ TTrackableList<TItem>::iterator Iterator;
+
+ template<typename TPtr>
+ TItem(TPtr& event, TInstant deadline,
+ const NMonitoring::TDynamicCounters::TCounterPtr& serItems,
+ const NMonitoring::TDynamicCounters::TCounterPtr& serBytes,
+ const TBSProxyContextPtr& bspctx, ui32 interconnectChannel,
+ bool local)
+ : Queue(EItemQueue::NotSet)
+ , CostEssence(*event->Get())
+ , TraceId(std::move(event->TraceId))
+ , Event(event, serItems, serBytes, bspctx, interconnectChannel, local)
+ , MsgId(Max<ui64>())
+ , SequenceId(0)
+ , Deadline(deadline)
+ , QueueCookie(RandomNumber<ui64>())
+ , Cost(0)
+ , DirtyCost(true)
+ , Discarded(false)
+ {}
+
+ ~TItem() {
+ Y_VERIFY(Queue == EItemQueue::NotSet, "Queue# %" PRIu32, ui32(Queue));
+ }
+
+ ui32 GetByteSize() const {
+ return Event.GetByteSize();
+ }
+
+ void Discard() {
+ Discarded = true;
+ Event.Discard();
+ }
+ };
+
+ using TItemList = TTrackableList<TItem>;
+
+ struct TQueues {
+ TItemList Waiting;
+ TItemList InFlight;
+ TItemList Unused;
+
+ TQueues(const TBSProxyContextPtr& bspctx)
+ : Waiting(TMemoryConsumer(bspctx->Queue))
+ , InFlight(TMemoryConsumer(bspctx->Queue))
+ , Unused(TMemoryConsumer(bspctx->Queue))
+ {}
+ };
+
using TSenderMap = TRbTree<TSenderNode<TItem>, TCompare<TActorId>>;
-
- TQueues Queues;
- TSenderMap SenderToItems;
- THashMap<std::pair<ui64, ui64>, TItemList::iterator> InFlightLookup;
-
- ui64 WindowSize;
- ui64 InFlightCost;
- ui64 NextMsgId;
- ui64 CurrentSequenceId;
-
- // queue gets "paused" when we are expecting to restart transmission with correct SequenceId/MsgId and we have
- // to wait for all out-of-order answers to arrive
- bool Paused = false;
-
- TString& LogPrefix;
-
- TCostModel CostModel;
- TInstant CostSettingsUpdate;
-
- TBSProxyContextPtr BSProxyCtx;
-
- NBackpressure::TQueueClientId ClientId;
-
- ui64 BytesWaiting;
-
- const ui32 InterconnectChannel;
-
-public:
- NMonitoring::TDynamicCounters::TCounterPtr QueueWaitingItems;
- NMonitoring::TDynamicCounters::TCounterPtr QueueWaitingBytes;
- NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightItems;
- NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightBytes;
- NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightCost;
- NMonitoring::TDynamicCounters::TCounterPtr QueueWindowSize;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPut;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPutBytes;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsProcessed;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsRejected;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPruned;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsSent;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsUndelivered;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsIncorrectMsgId;
- NMonitoring::TDynamicCounters::TCounterPtr QueueItemsWatermarkOverflow;
- NMonitoring::TDynamicCounters::TCounterPtr QueueOverflow;
- NMonitoring::TDynamicCounters::TCounterPtr QueueSerializedItems;
- NMonitoring::TDynamicCounters::TCounterPtr QueueSerializedBytes;
- NMonitoring::TDynamicCounters::TCounterPtr QueueDeserializedItems;
- NMonitoring::TDynamicCounters::TCounterPtr QueueDeserializedBytes;
- NMonitoring::TDynamicCounters::TCounterPtr QueueSize;
-
-public:
- TBlobStorageQueue(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, TString& logPrefix,
- const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, ui32 interconnectChannel,
+
+ TQueues Queues;
+ TSenderMap SenderToItems;
+ THashMap<std::pair<ui64, ui64>, TItemList::iterator> InFlightLookup;
+
+ ui64 WindowSize;
+ ui64 InFlightCost;
+ ui64 NextMsgId;
+ ui64 CurrentSequenceId;
+
+ // queue gets "paused" when we are expecting to restart transmission with correct SequenceId/MsgId and we have
+ // to wait for all out-of-order answers to arrive
+ bool Paused = false;
+
+ TString& LogPrefix;
+
+ TCostModel CostModel;
+ TInstant CostSettingsUpdate;
+
+ TBSProxyContextPtr BSProxyCtx;
+
+ NBackpressure::TQueueClientId ClientId;
+
+ ui64 BytesWaiting;
+
+ const ui32 InterconnectChannel;
+
+public:
+ NMonitoring::TDynamicCounters::TCounterPtr QueueWaitingItems;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueWaitingBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightItems;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueInFlightCost;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueWindowSize;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPut;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPutBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsProcessed;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsRejected;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsPruned;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsSent;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsUndelivered;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsIncorrectMsgId;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueItemsWatermarkOverflow;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueOverflow;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueSerializedItems;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueSerializedBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueDeserializedItems;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueDeserializedBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr QueueSize;
+
+public:
+ TBlobStorageQueue(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, TString& logPrefix,
+ const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, ui32 interconnectChannel,
const TBlobStorageGroupType &gType,
NMonitoring::TCountableBase::EVisibility visibility = NMonitoring::TCountableBase::EVisibility::Public);
-
- ~TBlobStorageQueue();
-
- const NBackpressure::TQueueClientId& GetClientId() const {
- return ClientId;
- }
-
- void SetMessageId(const NBackpressure::TMessageId& msgId) {
- Y_VERIFY(!InFlightCount());
- NextMsgId = msgId.MsgId;
- CurrentSequenceId = msgId.SequenceId;
- }
-
- ui64 GetBytesWaiting() const {
- return BytesWaiting;
- }
-
- ui64 GetItemsWaiting() const {
- return Queues.Waiting.size();
- }
-
- ui64 InFlightCount() {
- return Queues.InFlight.size();
- }
-
+
+ ~TBlobStorageQueue();
+
+ const NBackpressure::TQueueClientId& GetClientId() const {
+ return ClientId;
+ }
+
+ void SetMessageId(const NBackpressure::TMessageId& msgId) {
+ Y_VERIFY(!InFlightCount());
+ NextMsgId = msgId.MsgId;
+ CurrentSequenceId = msgId.SequenceId;
+ }
+
+ ui64 GetBytesWaiting() const {
+ return BytesWaiting;
+ }
+
+ ui64 GetItemsWaiting() const {
+ return Queues.Waiting.size();
+ }
+
+ ui64 InFlightCount() {
+ return Queues.InFlight.size();
+ }
+
void UpdateCostModel(TInstant now, const NKikimrBlobStorage::TVDiskCostSettings& settings,
const TBlobStorageGroupType& type);
- void InvalidateCosts();
- bool SetMaxWindowSize(ui64 maxWindowSize);
-
- void SetItemQueue(TItem& item, EItemQueue newQueue);
-
+ void InvalidateCosts();
+ bool SetMaxWindowSize(ui64 maxWindowSize);
+
+ void SetItemQueue(TItem& item, EItemQueue newQueue);
+
void SendToVDisk(const TActorContext& ctx, const TActorId& remoteVDisk, IActor *actor);
-
- void ReplyWithError(TItem& item, NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext& ctx);
- bool Expecting(ui64 msgId, ui64 sequenceId) const;
+
+ void ReplyWithError(TItem& item, NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext& ctx);
+ bool Expecting(ui64 msgId, ui64 sequenceId) const;
bool OnResponse(ui64 msgId, ui64 sequenceId, ui64 cookie, TActorId *outSender, ui64 *outCookie, TDuration *processingTime);
-
- void Unwind(ui64 failedMsgId, ui64 failedSequenceId, ui64 expectedMsgId, ui64 expectedSequenceId);
-
- void DrainQueue(NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext &ctx);
-
- void OnConnect();
-
- template<typename TPtr>
- void Enqueue(const TActorContext &ctx, TPtr& event, TInstant deadline, bool local) {
- Y_UNUSED(ctx);
-
- TItemList::iterator newIt;
- if (Queues.Unused.empty()) {
- newIt = Queues.Waiting.emplace(Queues.Waiting.end(), event, deadline,
- QueueSerializedItems, QueueSerializedBytes, BSProxyCtx, InterconnectChannel, local);
- ++*QueueSize;
- } else {
- newIt = Queues.Unused.begin();
- Queues.Waiting.splice(Queues.Waiting.end(), Queues.Unused, newIt);
- // reuse list item
- TItem& item = *newIt;
- item.~TItem();
- new(&item) TItem(event, deadline, QueueSerializedItems, QueueSerializedBytes, BSProxyCtx,
- InterconnectChannel, local);
- }
-
- newIt->Iterator = newIt;
- SetItemQueue(*newIt, EItemQueue::Waiting);
- SenderToItems.Insert(&*newIt);
-
- // count item
- ++*QueueItemsPut;
- *QueueItemsPutBytes += newIt->GetByteSize();
- }
-
- TItemList::iterator EraseItem(TItemList& queue, TItemList::iterator it);
+
+ void Unwind(ui64 failedMsgId, ui64 failedSequenceId, ui64 expectedMsgId, ui64 expectedSequenceId);
+
+ void DrainQueue(NKikimrProto::EReplyStatus status, const TString& errorReason, const TActorContext &ctx);
+
+ void OnConnect();
+
+ template<typename TPtr>
+ void Enqueue(const TActorContext &ctx, TPtr& event, TInstant deadline, bool local) {
+ Y_UNUSED(ctx);
+
+ TItemList::iterator newIt;
+ if (Queues.Unused.empty()) {
+ newIt = Queues.Waiting.emplace(Queues.Waiting.end(), event, deadline,
+ QueueSerializedItems, QueueSerializedBytes, BSProxyCtx, InterconnectChannel, local);
+ ++*QueueSize;
+ } else {
+ newIt = Queues.Unused.begin();
+ Queues.Waiting.splice(Queues.Waiting.end(), Queues.Unused, newIt);
+ // reuse list item
+ TItem& item = *newIt;
+ item.~TItem();
+ new(&item) TItem(event, deadline, QueueSerializedItems, QueueSerializedBytes, BSProxyCtx,
+ InterconnectChannel, local);
+ }
+
+ newIt->Iterator = newIt;
+ SetItemQueue(*newIt, EItemQueue::Waiting);
+ SenderToItems.Insert(&*newIt);
+
+ // count item
+ ++*QueueItemsPut;
+ *QueueItemsPutBytes += newIt->GetByteSize();
+ }
+
+ TItemList::iterator EraseItem(TItemList& queue, TItemList::iterator it);
void Prune(const TActorId& sender);
- TMaybe<TDuration> GetWorstRequestProcessingTime() const;
-};
-
-} // NKikimr::NBsQueue
+ TMaybe<TDuration> GetWorstRequestProcessingTime() const;
+};
+
+} // NKikimr::NBsQueue
diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp b/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp
index 200b85f616d..8e4225f0101 100644
--- a/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp
+++ b/ydb/core/blobstorage/backpressure/queue_backpressure_client.cpp
@@ -1,182 +1,182 @@
-#include "queue.h"
+#include "queue.h"
#include "queue_backpressure_client.h"
#include "queue_backpressure_server.h"
-#include "unisched.h"
-#include "common.h"
+#include "unisched.h"
+#include "common.h"
-//#define BSQUEUE_EVENT_COUNTERS 1
-
-namespace NKikimr::NBsQueue {
+//#define BSQUEUE_EVENT_COUNTERS 1
+
+namespace NKikimr::NBsQueue {
////////////////////////////////////////////////////////////////////////////
-// TVDiskBackpressureClientActor
+// TVDiskBackpressureClientActor
////////////////////////////////////////////////////////////////////////////
-class TVDiskBackpressureClientActor : public TActorBootstrapped<TVDiskBackpressureClientActor> {
- enum {
- EvQueueWatchdog = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvRequestReadiness,
- };
-
- struct TEvQueueWatchdog : TEventLocal<TEvQueueWatchdog, EvQueueWatchdog> {};
-
- struct TEvRequestReadiness : TEventLocal<TEvRequestReadiness, EvRequestReadiness> {
- ui64 Cookie;
-
- TEvRequestReadiness(ui64 cookie)
- : Cookie(cookie)
- {}
- };
-
- TBSProxyContextPtr BSProxyCtx;
+class TVDiskBackpressureClientActor : public TActorBootstrapped<TVDiskBackpressureClientActor> {
+ enum {
+ EvQueueWatchdog = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvRequestReadiness,
+ };
+
+ struct TEvQueueWatchdog : TEventLocal<TEvQueueWatchdog, EvQueueWatchdog> {};
+
+ struct TEvRequestReadiness : TEventLocal<TEvRequestReadiness, EvRequestReadiness> {
+ ui64 Cookie;
+
+ TEvRequestReadiness(ui64 cookie)
+ : Cookie(cookie)
+ {}
+ };
+
+ TBSProxyContextPtr BSProxyCtx;
TString LogPrefix;
const TString QueueName;
- const NMonitoring::TDynamicCounterPtr Counters;
+ const NMonitoring::TDynamicCounterPtr Counters;
TBlobStorageQueue Queue;
TActorId BlobStorageProxy;
- const TVDiskIdShort VDiskIdShort;
+ const TVDiskIdShort VDiskIdShort;
TActorId RemoteVDisk;
TVDiskID VDiskId;
- NKikimrBlobStorage::EVDiskQueueId QueueId;
- const TDuration QueueWatchdogTimeout;
- ui64 CheckReadinessCookie = 1;
+ NKikimrBlobStorage::EVDiskQueueId QueueId;
+ const TDuration QueueWatchdogTimeout;
+ ui64 CheckReadinessCookie = 1;
TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
- const ui32 InterconnectChannel;
+ const ui32 InterconnectChannel;
TActorId SessionId;
- std::optional<NKikimrBlobStorage::TGroupInfo> RecentGroup;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- TBlobStorageGroupType GType;
-
- enum class EState {
- INITIAL,
- CHECK_READINESS_SENT,
- EXPECT_READY_NOTIFY,
- READY
- };
- EState State = EState::INITIAL;
-
- const char *GetStateName() const {
- switch (State) {
- case EState::INITIAL: return "INITIAL";
- case EState::CHECK_READINESS_SENT: return "CHECK_READINESS_SENT";
- case EState::EXPECT_READY_NOTIFY: return "EXPECT_READY_NOTIFY";
- case EState::READY: return "READY";
- }
- return "<unknown>";
- }
-
+ std::optional<NKikimrBlobStorage::TGroupInfo> RecentGroup;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ TBlobStorageGroupType GType;
+
+ enum class EState {
+ INITIAL,
+ CHECK_READINESS_SENT,
+ EXPECT_READY_NOTIFY,
+ READY
+ };
+ EState State = EState::INITIAL;
+
+ const char *GetStateName() const {
+ switch (State) {
+ case EState::INITIAL: return "INITIAL";
+ case EState::CHECK_READINESS_SENT: return "CHECK_READINESS_SENT";
+ case EState::EXPECT_READY_NOTIFY: return "EXPECT_READY_NOTIFY";
+ case EState::READY: return "READY";
+ }
+ return "<unknown>";
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_QUEUE_ACTOR;
- }
-
- TVDiskBackpressureClientActor(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
- NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
- ui32 interconnectChannel, bool /*local*/, TDuration watchdogTimeout,
- TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility)
- : BSProxyCtx(bspctx)
- , QueueName(queueName)
- , Counters(counters->GetSubgroup("queue", queueName))
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_QUEUE_ACTOR;
+ }
+
+ TVDiskBackpressureClientActor(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
+ NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
+ ui32 interconnectChannel, bool /*local*/, TDuration watchdogTimeout,
+ TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility)
+ : BSProxyCtx(bspctx)
+ , QueueName(queueName)
+ , Counters(counters->GetSubgroup("queue", queueName))
, Queue(Counters, LogPrefix, bspctx, clientId, interconnectChannel,
(info ? info->Type : TErasureType::ErasureNone), visibility)
- , VDiskIdShort(vdiskId)
- , QueueId(queueId)
- , QueueWatchdogTimeout(watchdogTimeout)
+ , VDiskIdShort(vdiskId)
+ , QueueId(queueId)
+ , QueueWatchdogTimeout(watchdogTimeout)
, FlowRecord(flowRecord)
- , InterconnectChannel(interconnectChannel)
- , Info(info)
- , GType(info->Type)
- {
- Y_VERIFY(Info);
- }
+ , InterconnectChannel(interconnectChannel)
+ , Info(info)
+ , GType(info->Type)
+ {
+ Y_VERIFY(Info);
+ }
void Bootstrap(const TActorId& parent, const TActorContext& ctx) {
- ApplyGroupInfo(*std::exchange(Info, nullptr));
- QLOG_INFO_S("BSQ01", "starting parent# " << parent);
- InitCounters();
- RegisteredInUniversalScheduler = RegisterActorInUniversalScheduler(SelfId(), FlowRecord, ctx.ExecutorThread.ActorSystem);
- Y_VERIFY(!BlobStorageProxy);
- BlobStorageProxy = parent;
- RequestReadiness(nullptr, ctx);
- UpdateRequestTrackingStats(ctx);
- Become(&TThis::StateFuncWrapper);
- }
-
-private:
- void ApplyGroupInfo(const TBlobStorageGroupInfo& info) {
- Y_VERIFY(info.Type.GetErasure() == GType.GetErasure());
- VDiskId = info.CreateVDiskID(VDiskIdShort);
- RemoteVDisk = info.GetActorId(VDiskIdShort);
- LogPrefix = Sprintf("[%s TargetVDisk# %s Queue# %s]", SelfId().ToString().data(), VDiskId.ToString().data(), QueueName.data());
- RecentGroup = info.Group;
- }
-
+ ApplyGroupInfo(*std::exchange(Info, nullptr));
+ QLOG_INFO_S("BSQ01", "starting parent# " << parent);
+ InitCounters();
+ RegisteredInUniversalScheduler = RegisterActorInUniversalScheduler(SelfId(), FlowRecord, ctx.ExecutorThread.ActorSystem);
+ Y_VERIFY(!BlobStorageProxy);
+ BlobStorageProxy = parent;
+ RequestReadiness(nullptr, ctx);
+ UpdateRequestTrackingStats(ctx);
+ Become(&TThis::StateFuncWrapper);
+ }
+
+private:
+ void ApplyGroupInfo(const TBlobStorageGroupInfo& info) {
+ Y_VERIFY(info.Type.GetErasure() == GType.GetErasure());
+ VDiskId = info.CreateVDiskID(VDiskIdShort);
+ RemoteVDisk = info.GetActorId(VDiskIdShort);
+ LogPrefix = Sprintf("[%s TargetVDisk# %s Queue# %s]", SelfId().ToString().data(), VDiskId.ToString().data(), QueueName.data());
+ RecentGroup = info.Group;
+ }
+
////////////////////////////////////////////////////////////////////////
// UPDATE SECTOR
////////////////////////////////////////////////////////////////////////
- bool IsReady() const {
- return State == EState::READY;
- }
-
- void Pump(const TActorContext &ctx) {
- // if in 'Running' state, then send messages to VDisk
- if (IsReady()) {
- Queue.SendToVDisk(ctx, RemoteVDisk, this);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // WATCHDOG TIMER SECTOR
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TInstant WatchdogBarrier = TInstant::Max();
- bool WatchdogTimerScheduled = false;
-
- void ArmWatchdogTimer(const TActorContext& ctx) {
- const TInstant now = ctx.Now();
- ResetWatchdogTimer(now, true);
- if (!std::exchange(WatchdogTimerScheduled, true)) {
- ctx.Schedule(WatchdogBarrier - now, new TEvQueueWatchdog);
- }
- }
-
- void ResetWatchdogTimer(TInstant now, bool inverse = false) {
- if ((WatchdogBarrier == TInstant::Max()) == inverse) {
- WatchdogBarrier = now + QueueWatchdogTimeout;
- }
- }
-
- void DisarmWatchdogTimer() {
- WatchdogBarrier = TInstant::Max();
- }
-
- void HandleWatchdog(const TActorContext& ctx) {
- Y_VERIFY(WatchdogTimerScheduled);
- WatchdogTimerScheduled = false;
- const TInstant now = ctx.Now();
- if (now >= WatchdogBarrier) {
- // The disk is not responsive, because we had no advance in progress since it was scheduled/reset.
- QLOG_CRIT_S("BSQ19", "watchdog timer hit"
- << " InFlightCount# " << Queue.InFlightCount()
- << " StatusRequests.size# " << StatusRequests.size());
-
- // reset the connection
- ResetConnection(ctx, NKikimrProto::ERROR, "watchdog timer hit", TDuration::Seconds(1));
- } else if (WatchdogBarrier != TInstant::Max()) {
- // re-schedule event as the barrier has moved during past period
- ArmWatchdogTimer(ctx);
- }
- }
-
- void UpdateWatchdogStatus(const TActorContext& ctx) {
- if (Queue.InFlightCount() || StatusRequests.size()) {
- ArmWatchdogTimer(ctx);
- } else {
- DisarmWatchdogTimer();
- }
- }
-
+ bool IsReady() const {
+ return State == EState::READY;
+ }
+
+ void Pump(const TActorContext &ctx) {
+ // if in 'Running' state, then send messages to VDisk
+ if (IsReady()) {
+ Queue.SendToVDisk(ctx, RemoteVDisk, this);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WATCHDOG TIMER SECTOR
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TInstant WatchdogBarrier = TInstant::Max();
+ bool WatchdogTimerScheduled = false;
+
+ void ArmWatchdogTimer(const TActorContext& ctx) {
+ const TInstant now = ctx.Now();
+ ResetWatchdogTimer(now, true);
+ if (!std::exchange(WatchdogTimerScheduled, true)) {
+ ctx.Schedule(WatchdogBarrier - now, new TEvQueueWatchdog);
+ }
+ }
+
+ void ResetWatchdogTimer(TInstant now, bool inverse = false) {
+ if ((WatchdogBarrier == TInstant::Max()) == inverse) {
+ WatchdogBarrier = now + QueueWatchdogTimeout;
+ }
+ }
+
+ void DisarmWatchdogTimer() {
+ WatchdogBarrier = TInstant::Max();
+ }
+
+ void HandleWatchdog(const TActorContext& ctx) {
+ Y_VERIFY(WatchdogTimerScheduled);
+ WatchdogTimerScheduled = false;
+ const TInstant now = ctx.Now();
+ if (now >= WatchdogBarrier) {
+ // The disk is not responsive, because we had no advance in progress since it was scheduled/reset.
+ QLOG_CRIT_S("BSQ19", "watchdog timer hit"
+ << " InFlightCount# " << Queue.InFlightCount()
+ << " StatusRequests.size# " << StatusRequests.size());
+
+ // reset the connection
+ ResetConnection(ctx, NKikimrProto::ERROR, "watchdog timer hit", TDuration::Seconds(1));
+ } else if (WatchdogBarrier != TInstant::Max()) {
+ // re-schedule event as the barrier has moved during past period
+ ArmWatchdogTimer(ctx);
+ }
+ }
+
+ void UpdateWatchdogStatus(const TActorContext& ctx) {
+ if (Queue.InFlightCount() || StatusRequests.size()) {
+ ArmWatchdogTimer(ctx);
+ } else {
+ DisarmWatchdogTimer();
+ }
+ }
+
////////////////////////////////////////////////////////////////////////
// FORWARD SECTOR
////////////////////////////////////////////////////////////////////////
@@ -184,560 +184,560 @@ private:
template <typename P, typename T, typename R>
void HandleRequest(P &ev, const TActorContext &ctx) {
- const auto& record = ev->Get()->Record;
-
+ const auto& record = ev->Get()->Record;
+
TInstant deadline = TInstant::Max();
if (record.HasMsgQoS() && record.GetMsgQoS().HasDeadlineSeconds()) {
- deadline = TInstant::Seconds(record.GetMsgQoS().GetDeadlineSeconds());
- }
-
- QLOG_DEBUG_S("BSQ05", "T# " << TypeName<decltype(*ev->Get())>()
- << " deadline# " << deadline.ToString() << " State# " << GetStateName()
- << " cookie# " << ev->Cookie);
-
- if (IsReady()) {
- // trace wilson event if tracing is enabled for this request
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvBlobStorageQueuePut,
- InQueueWaitingItems = Queue.GetItemsWaiting(), InQueueWaitingBytes = Queue.GetBytesWaiting());
-
- Queue.Enqueue(ctx, ev, deadline, RemoteVDisk.NodeId() == SelfId().NodeId());
+ deadline = TInstant::Seconds(record.GetMsgQoS().GetDeadlineSeconds());
+ }
+
+ QLOG_DEBUG_S("BSQ05", "T# " << TypeName<decltype(*ev->Get())>()
+ << " deadline# " << deadline.ToString() << " State# " << GetStateName()
+ << " cookie# " << ev->Cookie);
+
+ if (IsReady()) {
+ // trace wilson event if tracing is enabled for this request
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvBlobStorageQueuePut,
+ InQueueWaitingItems = Queue.GetItemsWaiting(), InQueueWaitingBytes = Queue.GetBytesWaiting());
+
+ Queue.Enqueue(ctx, ev, deadline, RemoteVDisk.NodeId() == SelfId().NodeId());
Pump(ctx);
- UpdateRequestTrackingStats(ctx);
+ UpdateRequestTrackingStats(ctx);
} else {
- auto reply = std::make_unique<R>();
- reply->MakeError(NKikimrProto::NOTREADY, "BS_QUEUE is not ready", record);
- ctx.Send(ev->Sender, reply.release(), 0, ev->Cookie);
+ auto reply = std::make_unique<R>();
+ reply->MakeError(NKikimrProto::NOTREADY, "BS_QUEUE is not ready", record);
+ ctx.Send(ev->Sender, reply.release(), 0, ev->Cookie);
}
}
////////////////////////////////////////////////////////////////////////
// BACKWARD SECTOR
////////////////////////////////////////////////////////////////////////
- template<typename T>
- bool CheckReply(T& ev, const TActorContext& ctx) {
- if (ev->InterconnectSession) { // analyze only messages coming through IC
- ui32 expected = -1;
- switch (const ui32 type = ev->GetTypeRewrite()) {
+ template<typename T>
+ bool CheckReply(T& ev, const TActorContext& ctx) {
+ if (ev->InterconnectSession) { // analyze only messages coming through IC
+ ui32 expected = -1;
+ switch (const ui32 type = ev->GetTypeRewrite()) {
case TEvBlobStorage::EvVMovedPatchResult:
case TEvBlobStorage::EvVPatchFoundParts:
case TEvBlobStorage::EvVPatchXorDiffResult:
case TEvBlobStorage::EvVPatchResult:
- case TEvBlobStorage::EvVPutResult:
- case TEvBlobStorage::EvVMultiPutResult:
- case TEvBlobStorage::EvVBlockResult:
- case TEvBlobStorage::EvVGetBlockResult:
- case TEvBlobStorage::EvVCollectGarbageResult:
- case TEvBlobStorage::EvVGetBarrierResult:
- expected = TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG;
- break;
-
- case TEvBlobStorage::EvVGetResult:
- case TEvBlobStorage::EvVStatusResult:
- expected = InterconnectChannel;
- break;
-
- default:
- Y_FAIL("unexpected message type 0x%08" PRIx32, type);
- }
-
- if (ev->GetChannel() != expected) {
- QLOG_CRIT_S("BSQ40", "CheckReply"
- << " T# " << TypeName<decltype(*ev->Get())>()
- << " reply channel mismatch"
- << " received# " << ev->GetChannel()
- << " expected# " << expected);
- Y_VERIFY_DEBUG(false);
- }
- }
-
- return ev->InterconnectSession == SessionId;
- }
-
+ case TEvBlobStorage::EvVPutResult:
+ case TEvBlobStorage::EvVMultiPutResult:
+ case TEvBlobStorage::EvVBlockResult:
+ case TEvBlobStorage::EvVGetBlockResult:
+ case TEvBlobStorage::EvVCollectGarbageResult:
+ case TEvBlobStorage::EvVGetBarrierResult:
+ expected = TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG;
+ break;
+
+ case TEvBlobStorage::EvVGetResult:
+ case TEvBlobStorage::EvVStatusResult:
+ expected = InterconnectChannel;
+ break;
+
+ default:
+ Y_FAIL("unexpected message type 0x%08" PRIx32, type);
+ }
+
+ if (ev->GetChannel() != expected) {
+ QLOG_CRIT_S("BSQ40", "CheckReply"
+ << " T# " << TypeName<decltype(*ev->Get())>()
+ << " reply channel mismatch"
+ << " received# " << ev->GetChannel()
+ << " expected# " << expected);
+ Y_VERIFY_DEBUG(false);
+ }
+ }
+
+ return ev->InterconnectSession == SessionId;
+ }
+
template <typename T>
void HandleResponse(T &ev, const TActorContext &ctx) {
- if (!CheckReply(ev, ctx)) {
- return;
- }
- UpdateRequestTrackingStats(ctx);
-
- if (!IsReady()) {
- // may be this is message from the previous interconnect iteration -- we can drop it as we do not expect
- // this message
- QLOG_DEBUG_S("BSQ36", "T# " << TypeName<decltype(*ev->Get())>() << " NOT READY");
- return;
- }
-
- auto *msg = ev->Get();
- using TEv = decltype(*msg);
- const auto& record = msg->Record;
- NKikimrProto::EReplyStatus status;
- ui64 msgId, sequenceId;
-
- struct TExFatal : yexception {};
-
- try {
- auto getField = [&](const auto& base, auto hasfn, auto getfn, const char *baseName, const char *fieldName) {
- if (!(base.*hasfn)()) {
- throw TExFatal() << "missing " << fieldName << " in " << baseName << " T# " << TypeName<TEv>();
- }
- return (base.*getfn)();
- };
-
-#define F(BASE, NAME) getField((BASE), &std::decay_t<decltype(BASE)>::Has##NAME, &std::decay_t<decltype(BASE)>::Get##NAME, #BASE, #NAME)
-
- // parse the record
- status = F(record, Status);
- const auto& qos = F(record, MsgQoS);
- const auto& qosMsgId = F(qos, MsgId);
- msgId = F(qosMsgId, MsgId);
- sequenceId = F(qosMsgId, SequenceId);
-
- if (!Queue.Expecting(msgId, sequenceId)) {
- // this is none of expected responses, so we drop it without processing -- this may happen when interconnect
- // fails and after reconnecting we receive reply from the old query, but this query was already replied
- // to sender with ERROR status code upon disconnecting
- QLOG_DEBUG_S("BSQ37", "T# " << TypeName<TEv>() << " unexpected message"
- << " MsgId# " << msgId
- << " SequenceId# " << sequenceId);
- return;
- }
-
- // update cost model if received
- if (qos.HasCostSettings()) {
- Queue.UpdateCostModel(ctx.Now(), qos.GetCostSettings(), GType);
- }
- if (qos.HasWindow()) {
- HandleWindow(ctx, qos.GetWindow());
- }
-
- switch (status) {
- case NKikimrProto::TRYLATER_TIME: // this reply is never expected
- throw TExFatal() << "TRYLATER_TIME is never used";
-
- case NKikimrProto::NOTREADY:
- return ResetConnection(ctx, NKikimrProto::ERROR, "NOTREADY status in response", TDuration::Zero());
-
- case NKikimrProto::VDISK_ERROR_STATE:
- return ResetConnection(ctx, status, "VDISK_ERROR_STATE status in response", TDuration::Seconds(10));
-
- case NKikimrProto::TRYLATER_SIZE: // watermark overflow
- ResetWatchdogTimer(ctx.Now());
+ if (!CheckReply(ev, ctx)) {
+ return;
+ }
+ UpdateRequestTrackingStats(ctx);
+
+ if (!IsReady()) {
+ // may be this is message from the previous interconnect iteration -- we can drop it as we do not expect
+ // this message
+ QLOG_DEBUG_S("BSQ36", "T# " << TypeName<decltype(*ev->Get())>() << " NOT READY");
+ return;
+ }
+
+ auto *msg = ev->Get();
+ using TEv = decltype(*msg);
+ const auto& record = msg->Record;
+ NKikimrProto::EReplyStatus status;
+ ui64 msgId, sequenceId;
+
+ struct TExFatal : yexception {};
+
+ try {
+ auto getField = [&](const auto& base, auto hasfn, auto getfn, const char *baseName, const char *fieldName) {
+ if (!(base.*hasfn)()) {
+ throw TExFatal() << "missing " << fieldName << " in " << baseName << " T# " << TypeName<TEv>();
+ }
+ return (base.*getfn)();
+ };
+
+#define F(BASE, NAME) getField((BASE), &std::decay_t<decltype(BASE)>::Has##NAME, &std::decay_t<decltype(BASE)>::Get##NAME, #BASE, #NAME)
+
+ // parse the record
+ status = F(record, Status);
+ const auto& qos = F(record, MsgQoS);
+ const auto& qosMsgId = F(qos, MsgId);
+ msgId = F(qosMsgId, MsgId);
+ sequenceId = F(qosMsgId, SequenceId);
+
+ if (!Queue.Expecting(msgId, sequenceId)) {
+ // this is none of expected responses, so we drop it without processing -- this may happen when interconnect
+ // fails and after reconnecting we receive reply from the old query, but this query was already replied
+ // to sender with ERROR status code upon disconnecting
+ QLOG_DEBUG_S("BSQ37", "T# " << TypeName<TEv>() << " unexpected message"
+ << " MsgId# " << msgId
+ << " SequenceId# " << sequenceId);
+ return;
+ }
+
+ // update cost model if received
+ if (qos.HasCostSettings()) {
+ Queue.UpdateCostModel(ctx.Now(), qos.GetCostSettings(), GType);
+ }
+ if (qos.HasWindow()) {
+ HandleWindow(ctx, qos.GetWindow());
+ }
+
+ switch (status) {
+ case NKikimrProto::TRYLATER_TIME: // this reply is never expected
+ throw TExFatal() << "TRYLATER_TIME is never used";
+
+ case NKikimrProto::NOTREADY:
+ return ResetConnection(ctx, NKikimrProto::ERROR, "NOTREADY status in response", TDuration::Zero());
+
+ case NKikimrProto::VDISK_ERROR_STATE:
+ return ResetConnection(ctx, status, "VDISK_ERROR_STATE status in response", TDuration::Seconds(10));
+
+ case NKikimrProto::TRYLATER_SIZE: // watermark overflow
+ ResetWatchdogTimer(ctx.Now());
[[fallthrough]];
- case NKikimrProto::TRYLATER: { // unexpected MsgId/SequenceId on the remote end
- const auto& window = F(qos, Window);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // check the window status
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- const NKikimrBlobStorage::TWindowFeedback::EStatus ws = F(window, Status);
-
- const NKikimrBlobStorage::TWindowFeedback::EStatus expected = status == NKikimrProto::TRYLATER
- ? NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId
- : NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow;
-
- if (ws != expected) {
- throw TExFatal() << "window Status# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(ws)
- << " != expected Status# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(expected);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // check that the failed message id is correct
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- const auto& windowFailedMsgId = F(window, FailedMsgId);
- const ui64 failedMsgId = F(windowFailedMsgId, MsgId);
- const ui64 failedSequenceId = F(windowFailedMsgId, SequenceId);
- if (failedMsgId != msgId || failedSequenceId != sequenceId) {
- throw TExFatal() << "received msgId# " << msgId << " sequenceId# " << sequenceId
- << " != failedMsgId# " << failedMsgId << " failedSequenceId# " << failedSequenceId;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // extract expected message id
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- const auto& windowExpectedMsgId = F(window, ExpectedMsgId);
- const ui64 expectedMsgId = F(windowExpectedMsgId, MsgId);
- const ui64 expectedSequenceId = F(windowExpectedMsgId, SequenceId);
-
- QLOG_DEBUG_S("BSQ06", "T# " << TypeName<TEv>()
- << " failed message"
- << " msgId# " << msgId << " sequenceId# " << sequenceId
- << " expectedMsgId# " << expectedMsgId << " expectedSequenceId# " << expectedSequenceId
- << " status# " << NKikimrProto::EReplyStatus_Name(status)
- << " ws# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(ws));
-
- switch (ws) {
- case NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId:
- ++*Queue.QueueItemsIncorrectMsgId;
- break;
-
- case NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow:
- ++*Queue.QueueItemsWatermarkOverflow;
- break;
-
- default:
- Y_FAIL();
- }
-
- Queue.Unwind(msgId, sequenceId, expectedMsgId, expectedSequenceId);
- Pump(ctx);
- return;
- }
-
- default:
- break;
- }
- } catch (const TExFatal& ex) {
- const TString msg = TStringBuilder() << "fatal error: " << ex.what();
- QLOG_CRIT_S("BSQ38", msg);
- Y_VERIFY_DEBUG(false, "%s %s", LogPrefix.data(), msg.data());
- ResetConnection(ctx, NKikimrProto::ERROR, msg, TDuration::Zero());
- return;
- }
-
- // reset watchdog back to default interval -- we've got successful response
- ResetWatchdogTimer(ctx.Now());
+ case NKikimrProto::TRYLATER: { // unexpected MsgId/SequenceId on the remote end
+ const auto& window = F(qos, Window);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ // check the window status
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ const NKikimrBlobStorage::TWindowFeedback::EStatus ws = F(window, Status);
+
+ const NKikimrBlobStorage::TWindowFeedback::EStatus expected = status == NKikimrProto::TRYLATER
+ ? NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId
+ : NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow;
+
+ if (ws != expected) {
+ throw TExFatal() << "window Status# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(ws)
+ << " != expected Status# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(expected);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ // check that the failed message id is correct
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ const auto& windowFailedMsgId = F(window, FailedMsgId);
+ const ui64 failedMsgId = F(windowFailedMsgId, MsgId);
+ const ui64 failedSequenceId = F(windowFailedMsgId, SequenceId);
+ if (failedMsgId != msgId || failedSequenceId != sequenceId) {
+ throw TExFatal() << "received msgId# " << msgId << " sequenceId# " << sequenceId
+ << " != failedMsgId# " << failedMsgId << " failedSequenceId# " << failedSequenceId;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ // extract expected message id
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ const auto& windowExpectedMsgId = F(window, ExpectedMsgId);
+ const ui64 expectedMsgId = F(windowExpectedMsgId, MsgId);
+ const ui64 expectedSequenceId = F(windowExpectedMsgId, SequenceId);
+
+ QLOG_DEBUG_S("BSQ06", "T# " << TypeName<TEv>()
+ << " failed message"
+ << " msgId# " << msgId << " sequenceId# " << sequenceId
+ << " expectedMsgId# " << expectedMsgId << " expectedSequenceId# " << expectedSequenceId
+ << " status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " ws# " << NKikimrBlobStorage::TWindowFeedback_EStatus_Name(ws));
+
+ switch (ws) {
+ case NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId:
+ ++*Queue.QueueItemsIncorrectMsgId;
+ break;
+
+ case NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow:
+ ++*Queue.QueueItemsWatermarkOverflow;
+ break;
+
+ default:
+ Y_FAIL();
+ }
+
+ Queue.Unwind(msgId, sequenceId, expectedMsgId, expectedSequenceId);
+ Pump(ctx);
+ return;
+ }
+
+ default:
+ break;
+ }
+ } catch (const TExFatal& ex) {
+ const TString msg = TStringBuilder() << "fatal error: " << ex.what();
+ QLOG_CRIT_S("BSQ38", msg);
+ Y_VERIFY_DEBUG(false, "%s %s", LogPrefix.data(), msg.data());
+ ResetConnection(ctx, NKikimrProto::ERROR, msg, TDuration::Zero());
+ return;
+ }
+
+ // reset watchdog back to default interval -- we've got successful response
+ ResetWatchdogTimer(ctx.Now());
TActorId sender;
ui64 cookie = 0;
- TDuration processingTime;
- bool isOk = Queue.OnResponse(msgId, sequenceId, ev->Cookie, &sender, &cookie, &processingTime);
+ TDuration processingTime;
+ bool isOk = Queue.OnResponse(msgId, sequenceId, ev->Cookie, &sender, &cookie, &processingTime);
if (isOk) {
- NWilson::TTraceId traceId = std::move(ev->TraceId);
- ctx.Send(sender, ev->Release().Release(), 0, cookie, std::move(traceId));
- }
- QLOG_DEBUG_S("BSQ08", "T# " << TypeName<TEv>()
- << " sequenceId# " << sequenceId << " msgId# " << msgId
- << " status# " << NKikimrProto::EReplyStatus_Name(status)
- << " processingTime# " << processingTime
- << " isOk# " << isOk);
-
+ NWilson::TTraceId traceId = std::move(ev->TraceId);
+ ctx.Send(sender, ev->Release().Release(), 0, cookie, std::move(traceId));
+ }
+ QLOG_DEBUG_S("BSQ08", "T# " << TypeName<TEv>()
+ << " sequenceId# " << sequenceId << " msgId# " << msgId
+ << " status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " processingTime# " << processingTime
+ << " isOk# " << isOk);
+
Pump(ctx);
}
////////////////////////////////////////////////////////////////////////
// CONTROL SECTOR
////////////////////////////////////////////////////////////////////////
- void Handle(TEvPruneQueue::TPtr& ev, const TActorContext& /*ctx*/) {
- Queue.Prune(ev->Sender);
- }
-
- void HandleWindow(const TActorContext& ctx, const NKikimrBlobStorage::TWindowFeedback& window) {
- if (window.HasMaxWindowSize()) {
- const ui64 maxWindowSize = window.GetMaxWindowSize();
- if (Queue.SetMaxWindowSize(maxWindowSize)) {
- QLOG_DEBUG_S("BSQ10", "maxWindowSize# " << maxWindowSize);
- }
- }
- }
-
- void Handle(TEvBlobStorage::TEvVWindowChange::TPtr &ev, const TActorContext &ctx) {
+ void Handle(TEvPruneQueue::TPtr& ev, const TActorContext& /*ctx*/) {
+ Queue.Prune(ev->Sender);
+ }
+
+ void HandleWindow(const TActorContext& ctx, const NKikimrBlobStorage::TWindowFeedback& window) {
+ if (window.HasMaxWindowSize()) {
+ const ui64 maxWindowSize = window.GetMaxWindowSize();
+ if (Queue.SetMaxWindowSize(maxWindowSize)) {
+ QLOG_DEBUG_S("BSQ10", "maxWindowSize# " << maxWindowSize);
+ }
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVWindowChange::TPtr &ev, const TActorContext &ctx) {
QLOG_DEBUG_S("BSQ09", "WindowChange# " << ev->Get()->ToString());
- auto record = ev->Get()->Record;
- if (record.GetDropConnection()) {
- ResetConnection(ctx, NKikimrProto::VDISK_ERROR_STATE, "VDisk disconnected due to error", TDuration::Seconds(10));
- } else if (record.HasWindow()) {
- const auto& window = record.GetWindow();
- HandleWindow(ctx, window);
- ResetWatchdogTimer(ctx.Now());
+ auto record = ev->Get()->Record;
+ if (record.GetDropConnection()) {
+ ResetConnection(ctx, NKikimrProto::VDISK_ERROR_STATE, "VDisk disconnected due to error", TDuration::Seconds(10));
+ } else if (record.HasWindow()) {
+ const auto& window = record.GetWindow();
+ HandleWindow(ctx, window);
+ ResetWatchdogTimer(ctx.Now());
Pump(ctx);
}
}
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CONNECT SECTOR
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ResetConnection(const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
- TDuration timeout) {
- switch (State) {
- case EState::INITIAL:
- case EState::CHECK_READINESS_SENT:
- case EState::EXPECT_READY_NOTIFY:
- break;
-
- case EState::READY:
- QLOG_NOTICE_S("BSQ96", "connection lost status# " << NKikimrProto::EReplyStatus_Name(status)
- << " errorReason# " << errorReason << " timeout# " << timeout);
- ctx.Send(BlobStorageProxy, new TEvProxyQueueState(VDiskId, QueueId, false));
- Queue.DrainQueue(status, TStringBuilder() << "BS_QUEUE: " << errorReason, ctx);
- DrainStatus(status, ctx);
- break;
- }
- State = EState::INITIAL;
- ++CheckReadinessCookie;
- if (timeout != TDuration::Zero()) {
- ctx.Schedule(timeout, new TEvRequestReadiness(CheckReadinessCookie));
- } else {
- RequestReadiness(nullptr, ctx);
- }
- }
-
- void HandleConnected(TEvInterconnect::TEvNodeConnected::TPtr ev, const TActorContext& /*ctx*/) {
- if (ev->Get()->NodeId == RemoteVDisk.NodeId()) {
- Y_VERIFY(!SessionId || SessionId == ev->Sender, "SessionId# %s Sender# %s", SessionId.ToString().data(),
- ev->Sender.ToString().data());
- SessionId = ev->Sender;
- }
- }
-
- void HandleDisconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) {
- QLOG_INFO_S("BSQ13", "TEvNodeDisconnected NodeId# " << ev->Get()->NodeId);
- if (ev->Get()->NodeId == RemoteVDisk.NodeId()) {
- ResetConnection(ctx, NKikimrProto::ERROR, "node disconnected", TDuration::Seconds(1));
- Y_VERIFY(!SessionId || SessionId == ev->Sender);
- SessionId = {};
- }
- }
-
- // issue TEvVCheckReadiness message to VDisk; we ask for session subscription and delivery tracking, thus there are
- // the following cases:
- // * message reaches original VDisk and the TEvVCheckReadinessResult message is issued
- // * message is not delivered and we receive TEvUndelivered from Interconnect
- // * connection to the node is lost and we get TEvNodeDisconnected
- void RequestReadiness(TEvRequestReadiness::TPtr ev, const TActorContext& ctx) {
- if (ev && ev->Get()->Cookie != CheckReadinessCookie) {
- return; // obsolete scheduled event
- }
-
- QLOG_INFO_S("BSQ16", "called"
- << " CheckReadinessCookie# " << CheckReadinessCookie
- << " State# " << GetStateName());
-
- if (State != EState::INITIAL && State != EState::EXPECT_READY_NOTIFY) {
- return;
- }
-
- const bool notifyIfNotReady = State == EState::INITIAL; // only in initial state we want to subscribe for ready notifications
-
- const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel,
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
-
- auto checkEv = std::make_unique<TEvBlobStorage::TEvVCheckReadiness>(notifyIfNotReady);
- auto& record = checkEv->Record;
- VDiskIDFromVDiskID(VDiskId, record.MutableVDiskID());
- if (RecentGroup) {
- record.MutableRecentGroup()->CopyFrom(*RecentGroup);
- }
- auto *qos = record.MutableQoS();
- qos->SetExtQueueId(QueueId);
- Queue.GetClientId().Serialize(qos);
- ctx.Send(RemoteVDisk, checkEv.release(), flags, CheckReadinessCookie);
- State = EState::CHECK_READINESS_SENT;
-
- // after sending TEvVCheckReadiness we can either get:
- // 1. TEvVCheckReadinessResult in case when everything is okay or almost okay
- // 2. TEvNodeDisconnected when something gone wrong
- // 3. TEvUndelivered when message couldn't be delivered
- }
-
- void HandleCheckReadiness(TEvBlobStorage::TEvVCheckReadinessResult::TPtr& ev, const TActorContext& ctx) {
- QLOG_INFO_S("BSQ17", "received TEvVCheckReadinessResult"
- << " Cookie# " << ev->Cookie
- << " CheckReadinessCookie# " << CheckReadinessCookie
- << " State# " << GetStateName()
- << " Status# " << NKikimrProto::EReplyStatus_Name(ev->Get()->Record.GetStatus()));
-
- if (State != EState::CHECK_READINESS_SENT || ev->Cookie != CheckReadinessCookie) {
- return; // we don't expect this message right now, or this is some race reply
- }
-
- const auto& record = ev->Get()->Record;
- if (record.GetStatus() != NKikimrProto::NOTREADY) {
- ctx.Send(BlobStorageProxy, new TEvProxyQueueState(VDiskId, QueueId, true));
- if (record.HasExpectedMsgId()) {
- Queue.SetMessageId(NBackpressure::TMessageId(record.GetExpectedMsgId()));
- }
- if (record.HasCostSettings()) {
- Queue.UpdateCostModel(ctx.Now(), record.GetCostSettings(), GType);
- }
- Queue.OnConnect();
- State = EState::READY;
- } else {
- // we're still not ready, but we're expecting notification; however, target VDisk could be killed and wiped
- // out and we will never get this notification
- ctx.Schedule(TDuration::Seconds(10), new TEvRequestReadiness(CheckReadinessCookie));
- State = EState::EXPECT_READY_NOTIFY;
- }
- }
-
- void HandleReadyNotify(const TActorContext& ctx) {
- QLOG_INFO_S("BSQ18", "received TEvVReadyNotify"
- << " State# " << GetStateName());
-
- if (State == EState::EXPECT_READY_NOTIFY) {
- RequestReadiness(nullptr, ctx);
- }
- }
-
- void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
- QLOG_INFO_S("BSQ02", "Sender# " << ev->Sender
- << " RemoteVDisk# " << RemoteVDisk
- << " SourceType# " << ev->Get()->SourceType
- << " Cookie# " << ev->Cookie
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CONNECT SECTOR
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ResetConnection(const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TDuration timeout) {
+ switch (State) {
+ case EState::INITIAL:
+ case EState::CHECK_READINESS_SENT:
+ case EState::EXPECT_READY_NOTIFY:
+ break;
+
+ case EState::READY:
+ QLOG_NOTICE_S("BSQ96", "connection lost status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " errorReason# " << errorReason << " timeout# " << timeout);
+ ctx.Send(BlobStorageProxy, new TEvProxyQueueState(VDiskId, QueueId, false));
+ Queue.DrainQueue(status, TStringBuilder() << "BS_QUEUE: " << errorReason, ctx);
+ DrainStatus(status, ctx);
+ break;
+ }
+ State = EState::INITIAL;
+ ++CheckReadinessCookie;
+ if (timeout != TDuration::Zero()) {
+ ctx.Schedule(timeout, new TEvRequestReadiness(CheckReadinessCookie));
+ } else {
+ RequestReadiness(nullptr, ctx);
+ }
+ }
+
+ void HandleConnected(TEvInterconnect::TEvNodeConnected::TPtr ev, const TActorContext& /*ctx*/) {
+ if (ev->Get()->NodeId == RemoteVDisk.NodeId()) {
+ Y_VERIFY(!SessionId || SessionId == ev->Sender, "SessionId# %s Sender# %s", SessionId.ToString().data(),
+ ev->Sender.ToString().data());
+ SessionId = ev->Sender;
+ }
+ }
+
+ void HandleDisconnected(TEvInterconnect::TEvNodeDisconnected::TPtr& ev, const TActorContext &ctx) {
+ QLOG_INFO_S("BSQ13", "TEvNodeDisconnected NodeId# " << ev->Get()->NodeId);
+ if (ev->Get()->NodeId == RemoteVDisk.NodeId()) {
+ ResetConnection(ctx, NKikimrProto::ERROR, "node disconnected", TDuration::Seconds(1));
+ Y_VERIFY(!SessionId || SessionId == ev->Sender);
+ SessionId = {};
+ }
+ }
+
+ // issue TEvVCheckReadiness message to VDisk; we ask for session subscription and delivery tracking, thus there are
+ // the following cases:
+ // * message reaches original VDisk and the TEvVCheckReadinessResult message is issued
+ // * message is not delivered and we receive TEvUndelivered from Interconnect
+ // * connection to the node is lost and we get TEvNodeDisconnected
+ void RequestReadiness(TEvRequestReadiness::TPtr ev, const TActorContext& ctx) {
+ if (ev && ev->Get()->Cookie != CheckReadinessCookie) {
+ return; // obsolete scheduled event
+ }
+
+ QLOG_INFO_S("BSQ16", "called"
+ << " CheckReadinessCookie# " << CheckReadinessCookie
+ << " State# " << GetStateName());
+
+ if (State != EState::INITIAL && State != EState::EXPECT_READY_NOTIFY) {
+ return;
+ }
+
+ const bool notifyIfNotReady = State == EState::INITIAL; // only in initial state we want to subscribe for ready notifications
+
+ const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel,
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
+
+ auto checkEv = std::make_unique<TEvBlobStorage::TEvVCheckReadiness>(notifyIfNotReady);
+ auto& record = checkEv->Record;
+ VDiskIDFromVDiskID(VDiskId, record.MutableVDiskID());
+ if (RecentGroup) {
+ record.MutableRecentGroup()->CopyFrom(*RecentGroup);
+ }
+ auto *qos = record.MutableQoS();
+ qos->SetExtQueueId(QueueId);
+ Queue.GetClientId().Serialize(qos);
+ ctx.Send(RemoteVDisk, checkEv.release(), flags, CheckReadinessCookie);
+ State = EState::CHECK_READINESS_SENT;
+
+ // after sending TEvVCheckReadiness we can either get:
+ // 1. TEvVCheckReadinessResult in case when everything is okay or almost okay
+ // 2. TEvNodeDisconnected when something gone wrong
+ // 3. TEvUndelivered when message couldn't be delivered
+ }
+
+ void HandleCheckReadiness(TEvBlobStorage::TEvVCheckReadinessResult::TPtr& ev, const TActorContext& ctx) {
+ QLOG_INFO_S("BSQ17", "received TEvVCheckReadinessResult"
+ << " Cookie# " << ev->Cookie
+ << " CheckReadinessCookie# " << CheckReadinessCookie
+ << " State# " << GetStateName()
+ << " Status# " << NKikimrProto::EReplyStatus_Name(ev->Get()->Record.GetStatus()));
+
+ if (State != EState::CHECK_READINESS_SENT || ev->Cookie != CheckReadinessCookie) {
+ return; // we don't expect this message right now, or this is some race reply
+ }
+
+ const auto& record = ev->Get()->Record;
+ if (record.GetStatus() != NKikimrProto::NOTREADY) {
+ ctx.Send(BlobStorageProxy, new TEvProxyQueueState(VDiskId, QueueId, true));
+ if (record.HasExpectedMsgId()) {
+ Queue.SetMessageId(NBackpressure::TMessageId(record.GetExpectedMsgId()));
+ }
+ if (record.HasCostSettings()) {
+ Queue.UpdateCostModel(ctx.Now(), record.GetCostSettings(), GType);
+ }
+ Queue.OnConnect();
+ State = EState::READY;
+ } else {
+ // we're still not ready, but we're expecting notification; however, target VDisk could be killed and wiped
+ // out and we will never get this notification
+ ctx.Schedule(TDuration::Seconds(10), new TEvRequestReadiness(CheckReadinessCookie));
+ State = EState::EXPECT_READY_NOTIFY;
+ }
+ }
+
+ void HandleReadyNotify(const TActorContext& ctx) {
+ QLOG_INFO_S("BSQ18", "received TEvVReadyNotify"
+ << " State# " << GetStateName());
+
+ if (State == EState::EXPECT_READY_NOTIFY) {
+ RequestReadiness(nullptr, ctx);
+ }
+ }
+
+ void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev, const TActorContext &ctx) {
+ QLOG_INFO_S("BSQ02", "Sender# " << ev->Sender
+ << " RemoteVDisk# " << RemoteVDisk
+ << " SourceType# " << ev->Get()->SourceType
+ << " Cookie# " << ev->Cookie
<< " CheckReadinessCookie# " << CheckReadinessCookie
- << " State# " << GetStateName()
- << " Reason# " << ev->Get()->Reason);
-
- if (ev->Sender == RemoteVDisk) {
- ResetConnection(ctx, NKikimrProto::ERROR, "event undelivered", TDuration::Seconds(1));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- // STATUS SECTOR
+ << " State# " << GetStateName()
+ << " Reason# " << ev->Get()->Reason);
+
+ if (ev->Sender == RemoteVDisk) {
+ ResetConnection(ctx, NKikimrProto::ERROR, "event undelivered", TDuration::Seconds(1));
+ }
+ }
+
////////////////////////////////////////////////////////////////////////
-
- struct TStatusRequestItem {
+ // STATUS SECTOR
+ ////////////////////////////////////////////////////////////////////////
+
+ struct TStatusRequestItem {
TActorId Sender;
- ui64 Cookie;
- };
-
+ ui64 Cookie;
+ };
+
TDeque<TStatusRequestItem> StatusRequests;
ui64 StatusRequestCookie = 0; // 0 means there are no pending requests
- ui64 NextStatusRequestCookie = 1;
-
- void Handle(TEvBlobStorage::TEvVStatus::TPtr& ev, const TActorContext& ctx) {
- if (IsReady()) {
+ ui64 NextStatusRequestCookie = 1;
+
+ void Handle(TEvBlobStorage::TEvVStatus::TPtr& ev, const TActorContext& ctx) {
+ if (IsReady()) {
if (!StatusRequests) {
StatusRequestCookie = NextStatusRequestCookie++;
- SendStatusRequest(StatusRequestCookie, ctx);
+ SendStatusRequest(StatusRequestCookie, ctx);
}
StatusRequests.emplace_back(TStatusRequestItem{ev->Sender, ev->Cookie});
- } else {
- SendStatusErrorResponse(ev->Sender, ev->Cookie, NKikimrProto::NOTREADY, ctx);
- }
- }
-
- void SendStatusRequest(ui64 cookie, const TActorContext& ctx) {
- QLOG_DEBUG_S("BSQ33", "RemoteVDisk# " << RemoteVDisk
+ } else {
+ SendStatusErrorResponse(ev->Sender, ev->Cookie, NKikimrProto::NOTREADY, ctx);
+ }
+ }
+
+ void SendStatusRequest(ui64 cookie, const TActorContext& ctx) {
+ QLOG_DEBUG_S("BSQ33", "RemoteVDisk# " << RemoteVDisk
<< " VDiskId# " << VDiskId
- << " Cookie# " << cookie);
- const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel, IEventHandle::FlagTrackDelivery);
- ctx.Send(RemoteVDisk, new TEvBlobStorage::TEvVStatus(VDiskId), flags, cookie);
- }
-
- void DrainStatus(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- for (auto& request : std::exchange(StatusRequests, {})) {
+ << " Cookie# " << cookie);
+ const ui32 flags = IEventHandle::MakeFlags(InterconnectChannel, IEventHandle::FlagTrackDelivery);
+ ctx.Send(RemoteVDisk, new TEvBlobStorage::TEvVStatus(VDiskId), flags, cookie);
+ }
+
+ void DrainStatus(NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ for (auto& request : std::exchange(StatusRequests, {})) {
SendStatusErrorResponse(request.Sender, request.Cookie, status, ctx);
- }
+ }
StatusRequestCookie = 0;
- }
-
- void Handle(TEvBlobStorage::TEvVStatusResult::TPtr& ev, const TActorContext& ctx) {
- if (!CheckReply(ev, ctx)) {
- return;
- }
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatusResult::TPtr& ev, const TActorContext& ctx) {
+ if (!CheckReply(ev, ctx)) {
+ return;
+ }
if (ev->Cookie != StatusRequestCookie) {
// It's a response for an already replied request, just ignore it
return;
}
- for (auto& request : std::exchange(StatusRequests, {})) {
- auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>();
- response->Record = ev->Get()->Record;
- ctx.Send(request.Sender, response.release(), 0, request.Cookie);
- }
+ for (auto& request : std::exchange(StatusRequests, {})) {
+ auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>();
+ response->Record = ev->Get()->Record;
+ ctx.Send(request.Sender, response.release(), 0, request.Cookie);
+ }
StatusRequestCookie = 0;
-
- ResetWatchdogTimer(ctx.Now());
- Pump(ctx);
- }
-
+
+ ResetWatchdogTimer(ctx.Now());
+ Pump(ctx);
+ }
+
void SendStatusErrorResponse(const TActorId& sender, ui64 cookie, NKikimrProto::EReplyStatus status,
- const TActorContext& ctx) {
- QLOG_DEBUG_S("BSQ34", "Status# " << status
+ const TActorContext& ctx) {
+ QLOG_DEBUG_S("BSQ34", "Status# " << status
<< " VDiskId# " << VDiskId
- << " Cookie# " << cookie);
- auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(status, VDiskId, false, false, 0);
- ctx.Send(sender, response.release(), 0, cookie);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // REQUEST TIME TRACKING AND REPORTING SYSTEM
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0
-
- TInstant RequestTimeTrackingUpdateTimestamp;
- static constexpr TDuration RequestTimeTrackingUpdateDuration = TDuration::MilliSeconds(100);
- static constexpr size_t RequestTimeTrackingHistoryItems = 128;
- std::array<TDuration, RequestTimeTrackingHistoryItems> RequestTimeTrackingQ;
- size_t RequestTimeTrackingIndex = 0;
- bool UpdateRequestTrackingStatsScheduled = false;
- TDuration WorstDuration = TDuration::Zero();
- bool RegisteredInUniversalScheduler = false;
-
- void HandleUpdateRequestTrackingStats(const TActorContext& ctx) {
- Y_VERIFY(UpdateRequestTrackingStatsScheduled || RegisteredInUniversalScheduler);
- UpdateRequestTrackingStatsScheduled = false;
- UpdateRequestTrackingStats(ctx);
- }
-
- void UpdateRequestTrackingStats(const TActorContext& ctx) {
- const TInstant now = ctx.Now();
- if (!RequestTimeTrackingUpdateTimestamp) {
- RequestTimeTrackingUpdateTimestamp = now;
- }
-
- // set to true whether we should recalculate the predicted delay
- bool doUpdate = false;
-
- if (now > RequestTimeTrackingUpdateTimestamp) {
- // calculate number of periods we have to advance
- if (const size_t numPeriods = (now - RequestTimeTrackingUpdateTimestamp) / RequestTimeTrackingUpdateDuration) {
- RequestTimeTrackingUpdateTimestamp += RequestTimeTrackingUpdateDuration * numPeriods;
- if (numPeriods < RequestTimeTrackingHistoryItems) {
- for (size_t k = 0; k < numPeriods; ++k) {
- ++RequestTimeTrackingIndex;
- RequestTimeTrackingIndex %= RequestTimeTrackingHistoryItems;
- auto& m = RequestTimeTrackingQ[RequestTimeTrackingIndex];
- if (m == WorstDuration) {
- doUpdate = true; // recalculate the worst duration as we have dropped the maximum one from the queue
- }
- m = TDuration::Zero();
- }
- } else {
- RequestTimeTrackingQ.fill(TDuration::Zero());
- WorstDuration = TDuration::Zero();
- }
- }
- }
-
- // update the worst request time, if any
- auto& m = RequestTimeTrackingQ[RequestTimeTrackingIndex];
- if (const auto time = Queue.GetWorstRequestProcessingTime(); time && *time > m) {
- m = *time;
- WorstDuration = Max(WorstDuration, m);
- }
-
- if (doUpdate) {
- WorstDuration = *std::max_element(RequestTimeTrackingQ.begin(), RequestTimeTrackingQ.end());
- }
-
- // set the value
+ << " Cookie# " << cookie);
+ auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(status, VDiskId, false, false, 0);
+ ctx.Send(sender, response.release(), 0, cookie);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // REQUEST TIME TRACKING AND REPORTING SYSTEM
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0
+
+ TInstant RequestTimeTrackingUpdateTimestamp;
+ static constexpr TDuration RequestTimeTrackingUpdateDuration = TDuration::MilliSeconds(100);
+ static constexpr size_t RequestTimeTrackingHistoryItems = 128;
+ std::array<TDuration, RequestTimeTrackingHistoryItems> RequestTimeTrackingQ;
+ size_t RequestTimeTrackingIndex = 0;
+ bool UpdateRequestTrackingStatsScheduled = false;
+ TDuration WorstDuration = TDuration::Zero();
+ bool RegisteredInUniversalScheduler = false;
+
+ void HandleUpdateRequestTrackingStats(const TActorContext& ctx) {
+ Y_VERIFY(UpdateRequestTrackingStatsScheduled || RegisteredInUniversalScheduler);
+ UpdateRequestTrackingStatsScheduled = false;
+ UpdateRequestTrackingStats(ctx);
+ }
+
+ void UpdateRequestTrackingStats(const TActorContext& ctx) {
+ const TInstant now = ctx.Now();
+ if (!RequestTimeTrackingUpdateTimestamp) {
+ RequestTimeTrackingUpdateTimestamp = now;
+ }
+
+ // set to true whether we should recalculate the predicted delay
+ bool doUpdate = false;
+
+ if (now > RequestTimeTrackingUpdateTimestamp) {
+ // calculate number of periods we have to advance
+ if (const size_t numPeriods = (now - RequestTimeTrackingUpdateTimestamp) / RequestTimeTrackingUpdateDuration) {
+ RequestTimeTrackingUpdateTimestamp += RequestTimeTrackingUpdateDuration * numPeriods;
+ if (numPeriods < RequestTimeTrackingHistoryItems) {
+ for (size_t k = 0; k < numPeriods; ++k) {
+ ++RequestTimeTrackingIndex;
+ RequestTimeTrackingIndex %= RequestTimeTrackingHistoryItems;
+ auto& m = RequestTimeTrackingQ[RequestTimeTrackingIndex];
+ if (m == WorstDuration) {
+ doUpdate = true; // recalculate the worst duration as we have dropped the maximum one from the queue
+ }
+ m = TDuration::Zero();
+ }
+ } else {
+ RequestTimeTrackingQ.fill(TDuration::Zero());
+ WorstDuration = TDuration::Zero();
+ }
+ }
+ }
+
+ // update the worst request time, if any
+ auto& m = RequestTimeTrackingQ[RequestTimeTrackingIndex];
+ if (const auto time = Queue.GetWorstRequestProcessingTime(); time && *time > m) {
+ m = *time;
+ WorstDuration = Max(WorstDuration, m);
+ }
+
+ if (doUpdate) {
+ WorstDuration = *std::max_element(RequestTimeTrackingQ.begin(), RequestTimeTrackingQ.end());
+ }
+
+ // set the value
FlowRecord->SetPredictedDelayNs(WorstDuration.NanoSeconds());
-
- // set timer if we have job to do
- if (!RegisteredInUniversalScheduler && WorstDuration && !UpdateRequestTrackingStatsScheduled) {
- ctx.Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
- UpdateRequestTrackingStatsScheduled = true;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
+
+ // set timer if we have job to do
+ if (!RegisteredInUniversalScheduler && WorstDuration && !UpdateRequestTrackingStatsScheduled) {
+ ctx.Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
+ UpdateRequestTrackingStatsScheduled = true;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////
// STATES SECTOR
////////////////////////////////////////////////////////////////////////
- void Die(const TActorContext& ctx) override {
- QLOG_DEBUG_S("BSQ99", "terminating queue actor");
- if (RegisteredInUniversalScheduler) {
- RegisterActorInUniversalScheduler(SelfId(), nullptr, ctx.ExecutorThread.ActorSystem);
- }
- Unsubscribe(RemoteVDisk.NodeId(), ctx);
- return TActor::Die(ctx);
- }
-
- void Unsubscribe(const ui32 nodeId, const TActorContext& ctx) {
- ctx.Send(ctx.ExecutorThread.ActorSystem->InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
- SessionId = {};
- }
-
+ void Die(const TActorContext& ctx) override {
+ QLOG_DEBUG_S("BSQ99", "terminating queue actor");
+ if (RegisteredInUniversalScheduler) {
+ RegisterActorInUniversalScheduler(SelfId(), nullptr, ctx.ExecutorThread.ActorSystem);
+ }
+ Unsubscribe(RemoteVDisk.NodeId(), ctx);
+ return TActor::Die(ctx);
+ }
+
+ void Unsubscribe(const ui32 nodeId, const TActorContext& ctx) {
+ ctx.Send(ctx.ExecutorThread.ActorSystem->InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ SessionId = {};
+ }
+
void Handle(TEvRequestProxyQueueState::TPtr &ev, const TActorContext &ctx) {
bool isConnected = State == EState::READY;
QLOG_DEBUG_S("BSQ35", "RequestProxyQueueState"
@@ -760,163 +760,163 @@ private:
break; \
}
- void ChangeGroupInfo(const TBlobStorageGroupInfo& info, const TActorContext& ctx) {
- if (info.GroupGeneration > VDiskId.GroupGeneration) { // ignore any possible races with old generations
- const TActorId prevActorId = RemoteVDisk;
- ApplyGroupInfo(info);
- QLOG_DEBUG_S("BSQ97", "ChangeGroupInfo"
- << " Reconnect# " << (prevActorId != RemoteVDisk ? "true" : "false")
- << " State# " << GetStateName());
- if (prevActorId != RemoteVDisk) {
- Unsubscribe(prevActorId.NodeId(), ctx);
- ResetConnection(ctx, NKikimrProto::RACE, "target disk changed", TDuration::Zero());
- }
- }
- }
-
- void HandleGenerationChange(TEvVGenerationChange::TPtr& ev, const TActorContext& ctx) {
- QLOG_DEBUG_S("BSQ98", "ev# " << ev->Get()->ToString());
- ChangeGroupInfo(*ev->Get()->NewInfo, ctx);
- }
-
- void StateFuncWrapper(STFUNC_SIG) {
- StateFunc(ev, ctx);
- UpdateWatchdogStatus(ctx);
- }
-
-#if BSQUEUE_EVENT_COUNTERS
-
-#define DEFINE_EVENTS(XX) \
+ void ChangeGroupInfo(const TBlobStorageGroupInfo& info, const TActorContext& ctx) {
+ if (info.GroupGeneration > VDiskId.GroupGeneration) { // ignore any possible races with old generations
+ const TActorId prevActorId = RemoteVDisk;
+ ApplyGroupInfo(info);
+ QLOG_DEBUG_S("BSQ97", "ChangeGroupInfo"
+ << " Reconnect# " << (prevActorId != RemoteVDisk ? "true" : "false")
+ << " State# " << GetStateName());
+ if (prevActorId != RemoteVDisk) {
+ Unsubscribe(prevActorId.NodeId(), ctx);
+ ResetConnection(ctx, NKikimrProto::RACE, "target disk changed", TDuration::Zero());
+ }
+ }
+ }
+
+ void HandleGenerationChange(TEvVGenerationChange::TPtr& ev, const TActorContext& ctx) {
+ QLOG_DEBUG_S("BSQ98", "ev# " << ev->Get()->ToString());
+ ChangeGroupInfo(*ev->Get()->NewInfo, ctx);
+ }
+
+ void StateFuncWrapper(STFUNC_SIG) {
+ StateFunc(ev, ctx);
+ UpdateWatchdogStatus(ctx);
+ }
+
+#if BSQUEUE_EVENT_COUNTERS
+
+#define DEFINE_EVENTS(XX) \
XX(TEvBlobStorage::EvVMovedPatch, EvVMovedPatch) \
- XX(TEvBlobStorage::EvVPut, EvVPut) \
- XX(TEvBlobStorage::EvVMultiPut, EvVMultiPut) \
- XX(TEvBlobStorage::EvVGet, EvVGet) \
- XX(TEvBlobStorage::EvVBlock, EvVBlock) \
- XX(TEvBlobStorage::EvVGetBlock, EvVGetBlock) \
- XX(TEvBlobStorage::EvVCollectGarbage, EvVCollectGarbage) \
- XX(TEvBlobStorage::EvVGetBarrier, EvVGetBarrier) \
+ XX(TEvBlobStorage::EvVPut, EvVPut) \
+ XX(TEvBlobStorage::EvVMultiPut, EvVMultiPut) \
+ XX(TEvBlobStorage::EvVGet, EvVGet) \
+ XX(TEvBlobStorage::EvVBlock, EvVBlock) \
+ XX(TEvBlobStorage::EvVGetBlock, EvVGetBlock) \
+ XX(TEvBlobStorage::EvVCollectGarbage, EvVCollectGarbage) \
+ XX(TEvBlobStorage::EvVGetBarrier, EvVGetBarrier) \
XX(TEvBlobStorage::EvVMovedPatchResult, EvVMovedPatchResult) \
- XX(TEvBlobStorage::EvVPutResult, EvVPutResult) \
- XX(TEvBlobStorage::EvVMultiPutResult, EvVMultiPutResult) \
- XX(TEvBlobStorage::EvVGetResult, EvVGetResult) \
- XX(TEvBlobStorage::EvVBlockResult, EvVBlockResult) \
- XX(TEvBlobStorage::EvVGetBlockResult, EvVGetBlockResult) \
- XX(TEvBlobStorage::EvVCollectGarbageResult, EvVCollectGarbageResult) \
- XX(TEvBlobStorage::EvVGetBarrierResult, EvVGetBarrierResult) \
- XX(EvRequestReadiness, EvRequestReadiness) \
- XX(TEvBlobStorage::EvVCheckReadinessResult, EvVCheckReadinessResult) \
- XX(TEvBlobStorage::EvVReadyNotify, EvVReadyNotify) \
- XX(TEvBlobStorage::EvVStatus, EvVStatus) \
- XX(TEvBlobStorage::EvVStatusResult, EvVStatusResult) \
- XX(TEvBlobStorage::EvPruneQueue, EvPruneQueue) \
- XX(TEvBlobStorage::EvRequestProxyQueueState, EvRequestProxyQueueState) \
- XX(TEvBlobStorage::EvVWindowChange, EvVWindowChange) \
- XX(TEvInterconnect::EvNodeConnected, EvNodeConnected) \
- XX(TEvInterconnect::EvNodeDisconnected, EvNodeDisconnected) \
- XX(TEvents::TSystem::Undelivered, Undelivered) \
- XX(EvQueueWatchdog, EvQueueWatchdog) \
- XX(TEvents::TSystem::Wakeup, Wakeup) \
- XX(TEvBlobStorage::EvVGenerationChange, EvVGenerationChange) \
- XX(TEvents::TSystem::Poison, Poison) \
- // END
-
-#define XX(EVENT, NAME) NMonitoring::TDynamicCounters::TCounterPtr EventCounter##NAME;
- DEFINE_EVENTS(XX)
-#undef XX
-
- void InitCounters() {
- auto group = Counters->GetSubgroup("subsystem", "events");
-#define XX(EVENT, NAME) EventCounter##NAME = group->GetCounter(#NAME, true);
- DEFINE_EVENTS(XX)
-#undef XX
- }
-
-#else
-
- void InitCounters()
- {}
-
-#endif
-
- STFUNC(StateFunc) {
- const ui32 type = ev->GetTypeRewrite();
-#if BSQUEUE_EVENT_COUNTERS
- switch (type) {
-#define XX(EVENT, NAME) case EVENT: ++*EventCounter##NAME; break;
- DEFINE_EVENTS(XX)
-#undef XX
- default:
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
- }
-#endif
- switch (type) {
+ XX(TEvBlobStorage::EvVPutResult, EvVPutResult) \
+ XX(TEvBlobStorage::EvVMultiPutResult, EvVMultiPutResult) \
+ XX(TEvBlobStorage::EvVGetResult, EvVGetResult) \
+ XX(TEvBlobStorage::EvVBlockResult, EvVBlockResult) \
+ XX(TEvBlobStorage::EvVGetBlockResult, EvVGetBlockResult) \
+ XX(TEvBlobStorage::EvVCollectGarbageResult, EvVCollectGarbageResult) \
+ XX(TEvBlobStorage::EvVGetBarrierResult, EvVGetBarrierResult) \
+ XX(EvRequestReadiness, EvRequestReadiness) \
+ XX(TEvBlobStorage::EvVCheckReadinessResult, EvVCheckReadinessResult) \
+ XX(TEvBlobStorage::EvVReadyNotify, EvVReadyNotify) \
+ XX(TEvBlobStorage::EvVStatus, EvVStatus) \
+ XX(TEvBlobStorage::EvVStatusResult, EvVStatusResult) \
+ XX(TEvBlobStorage::EvPruneQueue, EvPruneQueue) \
+ XX(TEvBlobStorage::EvRequestProxyQueueState, EvRequestProxyQueueState) \
+ XX(TEvBlobStorage::EvVWindowChange, EvVWindowChange) \
+ XX(TEvInterconnect::EvNodeConnected, EvNodeConnected) \
+ XX(TEvInterconnect::EvNodeDisconnected, EvNodeDisconnected) \
+ XX(TEvents::TSystem::Undelivered, Undelivered) \
+ XX(EvQueueWatchdog, EvQueueWatchdog) \
+ XX(TEvents::TSystem::Wakeup, Wakeup) \
+ XX(TEvBlobStorage::EvVGenerationChange, EvVGenerationChange) \
+ XX(TEvents::TSystem::Poison, Poison) \
+ // END
+
+#define XX(EVENT, NAME) NMonitoring::TDynamicCounters::TCounterPtr EventCounter##NAME;
+ DEFINE_EVENTS(XX)
+#undef XX
+
+ void InitCounters() {
+ auto group = Counters->GetSubgroup("subsystem", "events");
+#define XX(EVENT, NAME) EventCounter##NAME = group->GetCounter(#NAME, true);
+ DEFINE_EVENTS(XX)
+#undef XX
+ }
+
+#else
+
+ void InitCounters()
+ {}
+
+#endif
+
+ STFUNC(StateFunc) {
+ const ui32 type = ev->GetTypeRewrite();
+#if BSQUEUE_EVENT_COUNTERS
+ switch (type) {
+#define XX(EVENT, NAME) case EVENT: ++*EventCounter##NAME; break;
+ DEFINE_EVENTS(XX)
+#undef XX
+ default:
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
+ }
+#endif
+ switch (type) {
QueueRequestHFunc(TEvBlobStorage::TEvVMovedPatch)
QueueRequestSpecialHFunc(TEvBlobStorage::TEvVPatchStart, TEvBlobStorage::TEvVPatchFoundParts)
QueueRequestSpecialHFunc(TEvBlobStorage::TEvVPatchDiff, TEvBlobStorage::TEvVPatchResult)
QueueRequestHFunc(TEvBlobStorage::TEvVPatchXorDiff)
- QueueRequestHFunc(TEvBlobStorage::TEvVPut)
- QueueRequestHFunc(TEvBlobStorage::TEvVMultiPut)
- QueueRequestHFunc(TEvBlobStorage::TEvVGet)
- QueueRequestHFunc(TEvBlobStorage::TEvVBlock)
- QueueRequestHFunc(TEvBlobStorage::TEvVGetBlock)
- QueueRequestHFunc(TEvBlobStorage::TEvVCollectGarbage)
- QueueRequestHFunc(TEvBlobStorage::TEvVGetBarrier)
+ QueueRequestHFunc(TEvBlobStorage::TEvVPut)
+ QueueRequestHFunc(TEvBlobStorage::TEvVMultiPut)
+ QueueRequestHFunc(TEvBlobStorage::TEvVGet)
+ QueueRequestHFunc(TEvBlobStorage::TEvVBlock)
+ QueueRequestHFunc(TEvBlobStorage::TEvVGetBlock)
+ QueueRequestHFunc(TEvBlobStorage::TEvVCollectGarbage)
+ QueueRequestHFunc(TEvBlobStorage::TEvVGetBarrier)
HFunc(TEvBlobStorage::TEvVMovedPatchResult, HandleResponse)
HFunc(TEvBlobStorage::TEvVPatchFoundParts, HandleResponse)
HFunc(TEvBlobStorage::TEvVPatchXorDiffResult, HandleResponse)
HFunc(TEvBlobStorage::TEvVPatchResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVPutResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVMultiPutResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVGetResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVBlockResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVGetBlockResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVCollectGarbageResult, HandleResponse)
- HFunc(TEvBlobStorage::TEvVGetBarrierResult, HandleResponse)
-
- HFunc(TEvRequestReadiness, RequestReadiness)
- HFunc(TEvBlobStorage::TEvVCheckReadinessResult, HandleCheckReadiness)
- CFunc(TEvBlobStorage::EvVReadyNotify, HandleReadyNotify)
-
- HFunc(TEvBlobStorage::TEvVStatus, Handle)
- HFunc(TEvBlobStorage::TEvVStatusResult, Handle)
-
- HFunc(TEvPruneQueue, Handle)
- HFunc(TEvRequestProxyQueueState, Handle)
-
- HFunc(TEvBlobStorage::TEvVWindowChange, Handle)
-
- HFunc(TEvInterconnect::TEvNodeConnected, HandleConnected)
- HFunc(TEvInterconnect::TEvNodeDisconnected, HandleDisconnected)
- HFunc(TEvents::TEvUndelivered, HandleUndelivered)
-
- CFunc(EvQueueWatchdog, HandleWatchdog)
- CFunc(TEvents::TSystem::Wakeup, HandleUpdateRequestTrackingStats)
-
- HFunc(TEvVGenerationChange, HandleGenerationChange)
-
- CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
-
- default:
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
- }
- }
+ HFunc(TEvBlobStorage::TEvVPutResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVMultiPutResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVGetResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVBlockResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVGetBlockResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVCollectGarbageResult, HandleResponse)
+ HFunc(TEvBlobStorage::TEvVGetBarrierResult, HandleResponse)
+
+ HFunc(TEvRequestReadiness, RequestReadiness)
+ HFunc(TEvBlobStorage::TEvVCheckReadinessResult, HandleCheckReadiness)
+ CFunc(TEvBlobStorage::EvVReadyNotify, HandleReadyNotify)
+
+ HFunc(TEvBlobStorage::TEvVStatus, Handle)
+ HFunc(TEvBlobStorage::TEvVStatusResult, Handle)
+
+ HFunc(TEvPruneQueue, Handle)
+ HFunc(TEvRequestProxyQueueState, Handle)
+
+ HFunc(TEvBlobStorage::TEvVWindowChange, Handle)
+
+ HFunc(TEvInterconnect::TEvNodeConnected, HandleConnected)
+ HFunc(TEvInterconnect::TEvNodeDisconnected, HandleDisconnected)
+ HFunc(TEvents::TEvUndelivered, HandleUndelivered)
+
+ CFunc(EvQueueWatchdog, HandleWatchdog)
+ CFunc(TEvents::TSystem::Wakeup, HandleUpdateRequestTrackingStats)
+
+ HFunc(TEvVGenerationChange, HandleGenerationChange)
+
+ CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
+
+ default:
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
+ }
+ }
};
-} // NKikimr::NBsQueue
-
-namespace NKikimr {
-
+} // NKikimr::NBsQueue
+
+namespace NKikimr {
+
////////////////////////////////////////////////////////////////////////////
// QUEUE CREATOR
////////////////////////////////////////////////////////////////////////////
-IActor* CreateVDiskBackpressureClient(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
- NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
- ui32 interconnectChannel, bool local, TDuration watchdogTimeout,
- TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility) {
- return new NBsQueue::TVDiskBackpressureClientActor(info, vdiskId, queueId, counters, bspctx, clientId, queueName,
- interconnectChannel, local, watchdogTimeout, flowRecord, visibility);
+IActor* CreateVDiskBackpressureClient(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
+ NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
+ ui32 interconnectChannel, bool local, TDuration watchdogTimeout,
+ TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility) {
+ return new NBsQueue::TVDiskBackpressureClientActor(info, vdiskId, queueId, counters, bspctx, clientId, queueName,
+ interconnectChannel, local, watchdogTimeout, flowRecord, visibility);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_client.h b/ydb/core/blobstorage/backpressure/queue_backpressure_client.h
index e6cc006a7a9..c6610efa8b6 100644
--- a/ydb/core/blobstorage/backpressure/queue_backpressure_client.h
+++ b/ydb/core/blobstorage/backpressure/queue_backpressure_client.h
@@ -5,42 +5,42 @@
namespace NKikimr {
- namespace NBackpressure {
- class TQueueClientId;
- } // NBackpressure
-
- struct TEvPruneQueue : public TEventLocal<TEvPruneQueue, TEvBlobStorage::EvPruneQueue>
- {};
-
- struct TEvProxyQueueState : public TEventLocal<TEvProxyQueueState, TEvBlobStorage::EvProxyQueueState> {
- TVDiskID VDiskId;
- NKikimrBlobStorage::EVDiskQueueId QueueId;
- bool IsConnected;
-
- TEvProxyQueueState(const TVDiskID &vDiskId, NKikimrBlobStorage::EVDiskQueueId queueId, bool isConnected)
- : VDiskId(vDiskId)
- , QueueId(queueId)
- , IsConnected(isConnected)
+ namespace NBackpressure {
+ class TQueueClientId;
+ } // NBackpressure
+
+ struct TEvPruneQueue : public TEventLocal<TEvPruneQueue, TEvBlobStorage::EvPruneQueue>
+ {};
+
+ struct TEvProxyQueueState : public TEventLocal<TEvProxyQueueState, TEvBlobStorage::EvProxyQueueState> {
+ TVDiskID VDiskId;
+ NKikimrBlobStorage::EVDiskQueueId QueueId;
+ bool IsConnected;
+
+ TEvProxyQueueState(const TVDiskID &vDiskId, NKikimrBlobStorage::EVDiskQueueId queueId, bool isConnected)
+ : VDiskId(vDiskId)
+ , QueueId(queueId)
+ , IsConnected(isConnected)
{}
-
+
TString ToString() const {
- TStringStream str;
- str << "{VDiskId# " << VDiskId.ToString();
- str << " QueueId# " << static_cast<ui32>(QueueId);
- str << " IsConnected# " << (IsConnected ? "true" : "false");
- str << "}";
- return str.Str();
- }
+ TStringStream str;
+ str << "{VDiskId# " << VDiskId.ToString();
+ str << " QueueId# " << static_cast<ui32>(QueueId);
+ str << " IsConnected# " << (IsConnected ? "true" : "false");
+ str << "}";
+ return str.Str();
+ }
};
struct TEvRequestProxyQueueState
: public TEventLocal<TEvRequestProxyQueueState, TEvBlobStorage::EvRequestProxyQueueState>
{};
- IActor* CreateVDiskBackpressureClient(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
- NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
- ui32 interconnectChannel, bool local, TDuration watchdogTimeout,
- TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility);
+ IActor* CreateVDiskBackpressureClient(const TIntrusivePtr<TBlobStorageGroupInfo>& info, TVDiskIdShort vdiskId,
+ NKikimrBlobStorage::EVDiskQueueId queueId,const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const TBSProxyContextPtr& bspctx, const NBackpressure::TQueueClientId& clientId, const TString& queueName,
+ ui32 interconnectChannel, bool local, TDuration watchdogTimeout,
+ TIntrusivePtr<NBackpressure::TFlowRecord> &flowRecord, NMonitoring::TCountableBase::EVisibility visibility);
} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_client_ut.cpp b/ydb/core/blobstorage/backpressure/queue_backpressure_client_ut.cpp
index af14a13f2d0..749120101e5 100644
--- a/ydb/core/blobstorage/backpressure/queue_backpressure_client_ut.cpp
+++ b/ydb/core/blobstorage/backpressure/queue_backpressure_client_ut.cpp
@@ -1,4 +1,4 @@
-#include "queue_backpressure_client.h"
+#include "queue_backpressure_client.h"
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/actors/core/actorsystem.h>
@@ -11,215 +11,215 @@
#include <ydb/core/blobstorage/vdisk/vdisk_actor.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_config.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
-#include <util/folder/tempdir.h>
-
-using namespace NKikimr;
-using namespace NActors;
-
-class TFilterActor : public TActorBootstrapped<TFilterActor> {
-public:
- using TFilterFunc = std::function<bool (IEventHandle&, const TActorContext&)>;
-
-private:
+#include <util/folder/tempdir.h>
+
+using namespace NKikimr;
+using namespace NActors;
+
+class TFilterActor : public TActorBootstrapped<TFilterActor> {
+public:
+ using TFilterFunc = std::function<bool (IEventHandle&, const TActorContext&)>;
+
+private:
TActorId QueueId;
TActorId VDiskId;
- TFilterFunc FilterFunc;
-
-public:
+ TFilterFunc FilterFunc;
+
+public:
TFilterActor(const TActorId& queueId, const TActorId& vdiskId, TFilterFunc&& filterFunc)
- : QueueId(queueId)
- , VDiskId(vdiskId)
- , FilterFunc(filterFunc)
- {}
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- Become(&TFilterActor::StateFunc);
- }
-
- template<typename TPtr>
- void HandleFw(TPtr& ev, const TActorContext& ctx) {
- ctx.ExecutorThread.Send(new IEventHandle(VDiskId, ctx.SelfID, ev->Release().Release(), 0, ev->Cookie));
- }
-
- template<typename TPtr>
- void HandleBw(TPtr& ev, const TActorContext& ctx) {
- ctx.ExecutorThread.Send(ev->Forward(QueueId));
- }
-
- template<typename TPtr>
- void HandleForward(TPtr& ev, const TActorContext& ctx) {
- ctx.ExecutorThread.Send(ev->Forward(VDiskId));
- }
-
- STFUNC(StateFunc) {
- if (FilterFunc(*ev, ctx)) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvBlobStorage::TEvVCheckReadiness, HandleFw);
- HFunc(TEvBlobStorage::TEvVGet, HandleFw);
- HFunc(TEvBlobStorage::TEvVCheckReadinessResult, HandleBw);
- HFunc(TEvBlobStorage::TEvVGetResult, HandleBw);
- HFunc(TEvBlobStorage::TEvVReadyNotify, HandleBw);
- HFunc(TEvBlobStorage::TEvVWindowChange, HandleBw);
- HFunc(TEvBlobStorage::TEvVSyncGuid, HandleForward);
- default: Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
- }
- }
- }
-};
-
-class TProxyActor : public TActorBootstrapped<TProxyActor> {
- const TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TVDiskID VDiskId;
- const TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ : QueueId(queueId)
+ , VDiskId(vdiskId)
+ , FilterFunc(filterFunc)
+ {}
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ Become(&TFilterActor::StateFunc);
+ }
+
+ template<typename TPtr>
+ void HandleFw(TPtr& ev, const TActorContext& ctx) {
+ ctx.ExecutorThread.Send(new IEventHandle(VDiskId, ctx.SelfID, ev->Release().Release(), 0, ev->Cookie));
+ }
+
+ template<typename TPtr>
+ void HandleBw(TPtr& ev, const TActorContext& ctx) {
+ ctx.ExecutorThread.Send(ev->Forward(QueueId));
+ }
+
+ template<typename TPtr>
+ void HandleForward(TPtr& ev, const TActorContext& ctx) {
+ ctx.ExecutorThread.Send(ev->Forward(VDiskId));
+ }
+
+ STFUNC(StateFunc) {
+ if (FilterFunc(*ev, ctx)) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, HandleFw);
+ HFunc(TEvBlobStorage::TEvVGet, HandleFw);
+ HFunc(TEvBlobStorage::TEvVCheckReadinessResult, HandleBw);
+ HFunc(TEvBlobStorage::TEvVGetResult, HandleBw);
+ HFunc(TEvBlobStorage::TEvVReadyNotify, HandleBw);
+ HFunc(TEvBlobStorage::TEvVWindowChange, HandleBw);
+ HFunc(TEvBlobStorage::TEvVSyncGuid, HandleForward);
+ default: Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
+ }
+ }
+ }
+};
+
+class TProxyActor : public TActorBootstrapped<TProxyActor> {
+ const TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TVDiskID VDiskId;
+ const TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
const TActorId QueueActorId;
-
-public:
- TProxyActor(TIntrusivePtr<TBlobStorageGroupInfo> info, const TVDiskID& vdiskId,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+
+public:
+ TProxyActor(TIntrusivePtr<TBlobStorageGroupInfo> info, const TVDiskID& vdiskId,
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
const TActorId& queueActorId)
- : Info(std::move(info))
- , VDiskId(vdiskId)
- , Counters(std::move(counters))
- , QueueActorId(queueActorId)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TProxyActor::StateFunc);
-
- TBSProxyContextPtr bsCtx;
- bsCtx = new TBSProxyContext{Counters};
+ : Info(std::move(info))
+ , VDiskId(vdiskId)
+ , Counters(std::move(counters))
+ , QueueActorId(queueActorId)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TProxyActor::StateFunc);
+
+ TBSProxyContextPtr bsCtx;
+ bsCtx = new TBSProxyContext{Counters};
TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
-
- TActorId actorId = ctx.Register(CreateVDiskBackpressureClient(Info, VDiskId, NKikimrBlobStorage::PutTabletLog,
- Counters, bsCtx, NBackpressure::TQueueClientId(), "PutTabletLog", 0, false, TDuration::Minutes(1),
- flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
-
- ctx.ExecutorThread.ActorSystem->RegisterLocalService(QueueActorId, actorId);
- }
-
- void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& /*ctx*/) {
- if (ev->Get()->IsConnected) {
- ConnectedEvent.Signal();
- }
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr& /*ev*/, const TActorContext& /*ctx*/) {
- if (!--NumResponsesPending) {
- CompletedEvent.Signal();
- }
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvProxyQueueState, Handle)
- HFunc(TEvBlobStorage::TEvVGetResult, Handle)
- )
-
- TAutoEvent ConnectedEvent;
- TAutoEvent CompletedEvent;
- ui32 NumResponsesPending = 0;
-};
-
-class TQueueTestRuntime {
- TTempDir TempDir;
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- std::unique_ptr<TActorSystem> ActorSystem;
+
+ TActorId actorId = ctx.Register(CreateVDiskBackpressureClient(Info, VDiskId, NKikimrBlobStorage::PutTabletLog,
+ Counters, bsCtx, NBackpressure::TQueueClientId(), "PutTabletLog", 0, false, TDuration::Minutes(1),
+ flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
+
+ ctx.ExecutorThread.ActorSystem->RegisterLocalService(QueueActorId, actorId);
+ }
+
+ void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& /*ctx*/) {
+ if (ev->Get()->IsConnected) {
+ ConnectedEvent.Signal();
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr& /*ev*/, const TActorContext& /*ctx*/) {
+ if (!--NumResponsesPending) {
+ CompletedEvent.Signal();
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvProxyQueueState, Handle)
+ HFunc(TEvBlobStorage::TEvVGetResult, Handle)
+ )
+
+ TAutoEvent ConnectedEvent;
+ TAutoEvent CompletedEvent;
+ ui32 NumResponsesPending = 0;
+};
+
+class TQueueTestRuntime {
+ TTempDir TempDir;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ std::unique_ptr<TActorSystem> ActorSystem;
TString Path;
- ui64 DiskSize;
- ui32 ChunkSize;
- ui64 PDiskGuid;
- NPDisk::TKey PDiskKey;
+ ui64 DiskSize;
+ ui32 ChunkSize;
+ ui64 PDiskGuid;
+ NPDisk::TKey PDiskKey;
TActorId PDiskId;
- std::unique_ptr<TAppData> AppData;
- TVDiskID VDiskId;
+ std::unique_ptr<TAppData> AppData;
+ TVDiskID VDiskId;
TActorId VDiskActorId;
TActorId QueueActorId;
TActorId FilterActorId;
TActorId ProxyActorId;
- TProxyActor *Proxy;
+ TProxyActor *Proxy;
TIntrusivePtr<NPDisk::TSectorMap> SectorMap;
-
-public:
- TQueueTestRuntime(TFilterActor::TFilterFunc&& func) {
- Counters.Reset(new NMonitoring::TDynamicCounters);
-
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 3;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[3]);
- setup->Executors[0].Reset(new TBasicExecutorPool(0, 2, 20));
- setup->Executors[1].Reset(new TBasicExecutorPool(1, 2, 20));
- setup->Executors[2].Reset(new TIOExecutorPool(2, 10));
- setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PDisk
+
+public:
+ TQueueTestRuntime(TFilterActor::TFilterFunc&& func) {
+ Counters.Reset(new NMonitoring::TDynamicCounters);
+
+ auto setup = MakeHolder<TActorSystemSetup>();
+ setup->NodeId = 1;
+ setup->ExecutorsCount = 3;
+ setup->Executors.Reset(new TAutoPtr<IExecutorPool>[3]);
+ setup->Executors[0].Reset(new TBasicExecutorPool(0, 2, 20));
+ setup->Executors[1].Reset(new TBasicExecutorPool(1, 2, 20));
+ setup->Executors[2].Reset(new TIOExecutorPool(2, 10));
+ setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PDisk
SectorMap.Reset(new NPDisk::TSectorMap(128ull << 30));
- Cerr << Path << Endl;
- ChunkSize = 128 << 20;
+ Cerr << Path << Endl;
+ ChunkSize = 128 << 20;
DiskSize = SectorMap->DeviceSize;
- PDiskGuid = 1;
- PDiskKey = 1;
+ PDiskGuid = 1;
+ PDiskKey = 1;
FormatPDisk(Path, DiskSize, 4096, ChunkSize, PDiskGuid, PDiskKey, PDiskKey, PDiskKey, PDiskKey, "queue_test",
false, false, SectorMap);
-
- PDiskId = MakeBlobStoragePDiskID(1, 1);
- ui64 pDiskCategory = 0;
- TIntrusivePtr<TPDiskConfig> pDiskConfig = new TPDiskConfig(Path, PDiskGuid, 1, pDiskCategory);
+
+ PDiskId = MakeBlobStoragePDiskID(1, 1);
+ ui64 pDiskCategory = 0;
+ TIntrusivePtr<TPDiskConfig> pDiskConfig = new TPDiskConfig(Path, PDiskGuid, 1, pDiskCategory);
pDiskConfig->GetDriveDataSwitch = NKikimrBlobStorage::TPDiskConfig::DoNotTouch;
pDiskConfig->WriteCacheSwitch = NKikimrBlobStorage::TPDiskConfig::DoNotTouch;
pDiskConfig->SectorMap = SectorMap;
pDiskConfig->EnableSectorEncryption = !pDiskConfig->SectorMap;
- TActorSetupCmd pDiskSetup(CreatePDisk(pDiskConfig.Get(), PDiskKey, Counters), TMailboxType::Revolving, 0);
- setup->LocalServices.emplace_back(PDiskId, pDiskSetup);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // BlobStorage group info
+ TActorSetupCmd pDiskSetup(CreatePDisk(pDiskConfig.Get(), PDiskKey, Counters), TMailboxType::Revolving, 0);
+ setup->LocalServices.emplace_back(PDiskId, pDiskSetup);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BlobStorage group info
FilterActorId = TActorId{1, "filter"};
QueueActorId = TActorId{1, "queue"};
ProxyActorId = TActorId{1, "proxy"};
VDiskActorId = TActorId{1, "vdisk"};
-
+
TVector<TActorId> actorIds{
- {FilterActorId} // actor id for our single VDisk that will be used by queue
- };
-
- VDiskId = TVDiskID{0, 1, 0, 0, 0};
- Info = new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 1, 1, 1, &actorIds);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDisk
+ {FilterActorId} // actor id for our single VDisk that will be used by queue
+ };
+
+ VDiskId = TVDiskID{0, 1, 0, 0, 0};
+ Info = new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 1, 1, 1, &actorIds);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDisk
TVDiskConfig::TBaseInfo baseInfo(
- VDiskId,
- PDiskId,
- PDiskGuid,
- 1,
+ VDiskId,
+ PDiskId,
+ PDiskGuid,
+ 1,
TPDiskCategory::DEVICE_TYPE_ROT,
0,
NKikimrBlobStorage::TVDiskKind::Default,
2,
{});
TIntrusivePtr<TVDiskConfig> vDiskConfig = new TVDiskConfig(baseInfo);
-
- IActor* vDisk = CreateVDisk(vDiskConfig, Info, Counters);
- TActorSetupCmd vDiskSetup(vDisk, TMailboxType::Revolving, 0);
- setup->LocalServices.emplace_back(VDiskActorId, vDiskSetup);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Filter
- IActor *filter = new TFilterActor{QueueActorId, VDiskActorId, std::move(func)};
- setup->LocalServices.emplace_back(FilterActorId, TActorSetupCmd{filter, TMailboxType::Simple, 0});
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Proxy
- Proxy = new TProxyActor(Info, VDiskId, Counters, QueueActorId);
- setup->LocalServices.emplace_back(ProxyActorId, TActorSetupCmd{Proxy, TMailboxType::Simple, 0});
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // LOGGER
+
+ IActor* vDisk = CreateVDisk(vDiskConfig, Info, Counters);
+ TActorSetupCmd vDiskSetup(vDisk, TMailboxType::Revolving, 0);
+ setup->LocalServices.emplace_back(VDiskActorId, vDiskSetup);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Filter
+ IActor *filter = new TFilterActor{QueueActorId, VDiskActorId, std::move(func)};
+ setup->LocalServices.emplace_back(FilterActorId, TActorSetupCmd{filter, TMailboxType::Simple, 0});
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Proxy
+ Proxy = new TProxyActor(Info, VDiskId, Counters, QueueActorId);
+ setup->LocalServices.emplace_back(ProxyActorId, TActorSetupCmd{Proxy, TMailboxType::Simple, 0});
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LOGGER
NActors::TActorId loggerActorId{1, "logger"};
- TIntrusivePtr<NActors::NLog::TSettings> logSettings{new NActors::NLog::TSettings{loggerActorId,
- NKikimrServices::LOGGER, NActors::NLog::PRI_ERROR, NActors::NLog::PRI_ERROR, 0}};
+ TIntrusivePtr<NActors::NLog::TSettings> logSettings{new NActors::NLog::TSettings{loggerActorId,
+ NKikimrServices::LOGGER, NActors::NLog::PRI_ERROR, NActors::NLog::PRI_ERROR, 0}};
logSettings->Append(
NActorsServices::EServiceCommon_MIN,
NActorsServices::EServiceCommon_MAX,
@@ -227,99 +227,99 @@ public:
);
logSettings->Append(
NKikimrServices::EServiceKikimr_MIN,
- NKikimrServices::EServiceKikimr_MAX,
+ NKikimrServices::EServiceKikimr_MAX,
NKikimrServices::EServiceKikimr_Name
);
-
+
TString explanation;
- logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_QUEUE, explanation);
-
- NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor{logSettings, NActors::CreateStderrBackend(),
- Counters};
- NActors::TActorSetupCmd loggerActorCmd{loggerActor, NActors::TMailboxType::Simple, 2};
- setup->LocalServices.emplace_back(loggerActorId, loggerActorCmd);
- AppData.reset(new TAppData(0, 1, 2, 1, TMap<TString, ui32>(), nullptr, nullptr, nullptr, nullptr));
-
- ActorSystem.reset(new TActorSystem{setup, AppData.get(), logSettings});
- }
-
- void Start() {
- ActorSystem->Start();
- }
-
- void Stop() {
- ActorSystem->Stop();
- ActorSystem.reset();
- }
-
- void SetNumResponsesPending(ui32 num) {
- Proxy->NumResponsesPending = num;
- }
-
- void WaitConnected() {
- Proxy->ConnectedEvent.WaitI();
- }
-
- void WaitCompleted() {
- Proxy->CompletedEvent.WaitI();
- }
-
- void Send(std::unique_ptr<IEventHandle>&& ev) {
- ActorSystem->Send(ev.release());
- }
-
+ logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_QUEUE, explanation);
+
+ NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor{logSettings, NActors::CreateStderrBackend(),
+ Counters};
+ NActors::TActorSetupCmd loggerActorCmd{loggerActor, NActors::TMailboxType::Simple, 2};
+ setup->LocalServices.emplace_back(loggerActorId, loggerActorCmd);
+ AppData.reset(new TAppData(0, 1, 2, 1, TMap<TString, ui32>(), nullptr, nullptr, nullptr, nullptr));
+
+ ActorSystem.reset(new TActorSystem{setup, AppData.get(), logSettings});
+ }
+
+ void Start() {
+ ActorSystem->Start();
+ }
+
+ void Stop() {
+ ActorSystem->Stop();
+ ActorSystem.reset();
+ }
+
+ void SetNumResponsesPending(ui32 num) {
+ Proxy->NumResponsesPending = num;
+ }
+
+ void WaitConnected() {
+ Proxy->ConnectedEvent.WaitI();
+ }
+
+ void WaitCompleted() {
+ Proxy->CompletedEvent.WaitI();
+ }
+
+ void Send(std::unique_ptr<IEventHandle>&& ev) {
+ ActorSystem->Send(ev.release());
+ }
+
const TActorId& GetProxyActorId() const {
- return ProxyActorId;
- }
-
+ return ProxyActorId;
+ }
+
const TActorId& GetQueueActorId() const {
- return QueueActorId;
- }
-
- const TVDiskID& GetVDiskId() const {
- return VDiskId;
- }
-};
-
+ return QueueActorId;
+ }
+
+ const TVDiskID& GetVDiskId() const {
+ return VDiskId;
+ }
+};
+
Y_UNIT_TEST_SUITE(TBlobStorageQueueTest) {
-
+
Y_UNIT_TEST(TMessageLost) {
- // https://st.yandex-team.ru/KIKIMR-9570 this test not is incorrect because we don't allow 'lost messages'
- // without proper interconnect notification; local messages can't be just lost while VDisk is operational
- return; // TODO(alexvru)
-
+ // https://st.yandex-team.ru/KIKIMR-9570 this test not is incorrect because we don't allow 'lost messages'
+ // without proper interconnect notification; local messages can't be just lost while VDisk is operational
+ return; // TODO(alexvru)
+
TVector<std::pair<ui64, ui64>> sequence;
- auto filterFunc = [&](IEventHandle& ev, const TActorContext& /*ctx*/) {
- if (ev.GetTypeRewrite() == TEvBlobStorage::TEvVGet::EventType) {
- TEventHandle<TEvBlobStorage::TEvVGet>& evv = reinterpret_cast<TEventHandle<TEvBlobStorage::TEvVGet>&>(ev);
- const auto& record = evv.Get()->Record;
- const auto& msgQoS = record.GetMsgQoS();
- const auto& id = msgQoS.GetMsgId();
- ui64 sequenceId = id.GetSequenceId();
- ui64 msgId = id.GetMsgId();
- sequence.emplace_back(sequenceId, msgId);
- if (sequenceId == 1 && msgId == 1) {
- return false;
- }
- }
- return true;
- };
- TQueueTestRuntime runtime{std::move(filterFunc)};
- runtime.Start();
- runtime.WaitConnected();
- runtime.SetNumResponsesPending(3);
- for (ui32 i = 0; i < 3; ++i) {
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(runtime.GetVDiskId(),
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {TLogoBlobID(1, 1, 1, 0, 10, i)});
- runtime.Send(std::make_unique<IEventHandle>(runtime.GetQueueActorId(), runtime.GetProxyActorId(), req.release()));
- }
- runtime.WaitCompleted();
- runtime.Stop();
+ auto filterFunc = [&](IEventHandle& ev, const TActorContext& /*ctx*/) {
+ if (ev.GetTypeRewrite() == TEvBlobStorage::TEvVGet::EventType) {
+ TEventHandle<TEvBlobStorage::TEvVGet>& evv = reinterpret_cast<TEventHandle<TEvBlobStorage::TEvVGet>&>(ev);
+ const auto& record = evv.Get()->Record;
+ const auto& msgQoS = record.GetMsgQoS();
+ const auto& id = msgQoS.GetMsgId();
+ ui64 sequenceId = id.GetSequenceId();
+ ui64 msgId = id.GetMsgId();
+ sequence.emplace_back(sequenceId, msgId);
+ if (sequenceId == 1 && msgId == 1) {
+ return false;
+ }
+ }
+ return true;
+ };
+ TQueueTestRuntime runtime{std::move(filterFunc)};
+ runtime.Start();
+ runtime.WaitConnected();
+ runtime.SetNumResponsesPending(3);
+ for (ui32 i = 0; i < 3; ++i) {
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(runtime.GetVDiskId(),
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {TLogoBlobID(1, 1, 1, 0, 10, i)});
+ runtime.Send(std::make_unique<IEventHandle>(runtime.GetQueueActorId(), runtime.GetProxyActorId(), req.release()));
+ }
+ runtime.WaitCompleted();
+ runtime.Stop();
UNIT_ASSERT_VALUES_EQUAL(sequence, (TVector<std::pair<ui64, ui64>>{{1, 0}, {1, 1}, {1, 2}, {2, 1}, {2, 2}}));
- }
-
-}
+ }
+
+}
diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_server.h b/ydb/core/blobstorage/backpressure/queue_backpressure_server.h
index c1f8a7e3952..a4c19f34d19 100644
--- a/ydb/core/blobstorage/backpressure/queue_backpressure_server.h
+++ b/ydb/core/blobstorage/backpressure/queue_backpressure_server.h
@@ -110,16 +110,16 @@ namespace NKikimr {
const ui64 DefHighWatermark;
const ui64 CostChangeUntilFrozen; // how much cost change we should skip to move from Fading to Frozen
const ui64 CostChangeUntilDeath; // how much cost change we should skip to remove window completely
- TInstant LastActivityTime;
- TDuration WindowTimeout;
- ui64 InFlight;
+ TInstant LastActivityTime;
+ TDuration WindowTimeout;
+ ui64 InFlight;
- void SetStatus(TWindowStatus *ptr, EStatus status, bool notify, const TMessageId &failedMsgId = {}) {
- const ui64 maxWindowSize = Min(LowWatermark, HighWatermark);
+ void SetStatus(TWindowStatus *ptr, EStatus status, bool notify, const TMessageId &failedMsgId = {}) {
+ const ui64 maxWindowSize = Min(LowWatermark, HighWatermark);
if (notify) {
- LastMaxWindowSize = maxWindowSize;
+ LastMaxWindowSize = maxWindowSize;
}
- ptr->Set(ClientId, ActorId, status, notify, Cost, maxWindowSize, ExpectedMsgId, failedMsgId);
+ ptr->Set(ClientId, ActorId, status, notify, Cost, maxWindowSize, ExpectedMsgId, failedMsgId);
}
void UpdateCountdown(ui64 costChange) {
@@ -144,11 +144,11 @@ namespace NKikimr {
public:
TWindow(TStatPtr globalStatPtr, const TClientId &clientId, const TActorId& actorId,
- ui64 percentThreshold, ui64 defLowWatermark, ui64 defHighWatermark, ui64 costChangeUntilFrozen,
- ui64 costChangeUntilDeath, TDuration windowTimeout, TInstant now)
+ ui64 percentThreshold, ui64 defLowWatermark, ui64 defHighWatermark, ui64 costChangeUntilFrozen,
+ ui64 costChangeUntilDeath, TDuration windowTimeout, TInstant now)
: GlobalStatPtr(globalStatPtr)
, ClientId(clientId)
- , ActorId(actorId)
+ , ActorId(actorId)
, ExpectedMsgId()
, Cost(0)
, LowWatermark(defLowWatermark)
@@ -161,47 +161,47 @@ namespace NKikimr {
, DefHighWatermark(defHighWatermark)
, CostChangeUntilFrozen(costChangeUntilFrozen)
, CostChangeUntilDeath(costChangeUntilDeath)
- , LastActivityTime(now)
- , WindowTimeout(windowTimeout)
- , InFlight(0)
+ , LastActivityTime(now)
+ , WindowTimeout(windowTimeout)
+ , InFlight(0)
{}
- void Push(bool checkMsgId, const TMessageId &msgId, ui64 cost, TWindowStatus *opStatus,
- TInstant now) {
+ void Push(bool checkMsgId, const TMessageId &msgId, ui64 cost, TWindowStatus *opStatus,
+ TInstant now) {
Y_VERIFY_DEBUG(LowWatermark != 0);
Y_VERIFY_DEBUG(LowWatermark <= HighWatermark);
- Y_VERIFY_DEBUG(cost > 0);
+ Y_VERIFY_DEBUG(cost > 0);
- if ((msgId.MsgId == ExpectedMsgId.MsgId && msgId.SequenceId >= ExpectedMsgId.SequenceId) || !checkMsgId) {
+ if ((msgId.MsgId == ExpectedMsgId.MsgId && msgId.SequenceId >= ExpectedMsgId.SequenceId) || !checkMsgId) {
// accept if msgId is correct
- if (Cost + cost <= HighWatermark || InFlight == 0) { // accept at least one message of any cost
+ if (Cost + cost <= HighWatermark || InFlight == 0) { // accept at least one message of any cost
GlobalStatPtr->IncSuccess();
CostChangeUntilFrozenCountdown = CostChangeUntilFrozen;
CostChangeUntilDeathCountdown = CostChangeUntilDeath;
- LastActivityTime = now;
+ LastActivityTime = now;
Cost += cost;
- ++InFlight;
- ExpectedMsgId = TMessageId(msgId.SequenceId, msgId.MsgId + 1);
+ ++InFlight;
+ ExpectedMsgId = TMessageId(msgId.SequenceId, msgId.MsgId + 1);
SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::Success, false);
} else {
- // reject message
- ExpectedMsgId.SequenceId = Max(ExpectedMsgId.SequenceId, msgId.SequenceId + 1);
- SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow, true, msgId);
- GlobalStatPtr->IncHighWatermarkOverflow();
+ // reject message
+ ExpectedMsgId.SequenceId = Max(ExpectedMsgId.SequenceId, msgId.SequenceId + 1);
+ SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::HighWatermarkOverflow, true, msgId);
+ GlobalStatPtr->IncHighWatermarkOverflow();
}
} else {
- ExpectedMsgId.SequenceId = Max(ExpectedMsgId.SequenceId, msgId.SequenceId + 1);
- SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId, true, msgId);
- GlobalStatPtr->IncIncorrectMsgId();
+ ExpectedMsgId.SequenceId = Max(ExpectedMsgId.SequenceId, msgId.SequenceId + 1);
+ SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId, true, msgId);
+ GlobalStatPtr->IncIncorrectMsgId();
}
}
- TWindowStatus *Processed(bool checkMsgId, const TMessageId &msgId, ui64 cost, TWindowStatus *opStatus) {
+ TWindowStatus *Processed(bool checkMsgId, const TMessageId &msgId, ui64 cost, TWindowStatus *opStatus) {
Y_UNUSED(checkMsgId);
Y_UNUSED(msgId);
Y_VERIFY(Cost >= cost);
Cost -= cost;
- --InFlight;
+ --InFlight;
SetStatus(opStatus, NKikimrBlobStorage::TWindowFeedback::Processed, true);
GlobalStatPtr->IncProcessed();
return opStatus;
@@ -228,21 +228,21 @@ namespace NKikimr {
return opStatus;
}
- EWindowState GetState(TInstant now) const {
- if (Cost > 0 || InFlight) {
+ EWindowState GetState(TInstant now) const {
+ if (Cost > 0 || InFlight) {
return EWindowState::Active;
} else if (LowWatermark > DefLowWatermark || CostChangeUntilFrozenCountdown > 0) {
return EWindowState::Fading;
- } else if (CostChangeUntilDeathCountdown > 0 || now < LastActivityTime + WindowTimeout) {
+ } else if (CostChangeUntilDeathCountdown > 0 || now < LastActivityTime + WindowTimeout) {
return EWindowState::Frozen;
} else {
- Y_ASSERT(CostChangeUntilFrozenCountdown == 0 && CostChangeUntilDeathCountdown == 0 &&
- now >= LastActivityTime + WindowTimeout);
+ Y_ASSERT(CostChangeUntilFrozenCountdown == 0 && CostChangeUntilDeathCountdown == 0 &&
+ now >= LastActivityTime + WindowTimeout);
return EWindowState::Dead;
}
}
- void Fade(EWindowState state, ui64 costChange, TInstant now) {
+ void Fade(EWindowState state, ui64 costChange, TInstant now) {
Y_VERIFY(state == GetState(now));
// TODO: we can implement more gracefull fading, take into account that beside this fading
@@ -261,10 +261,10 @@ namespace NKikimr {
return Cost;
}
- TMessageId GetExpectedMsgId() const {
- return ExpectedMsgId;
- }
-
+ TMessageId GetExpectedMsgId() const {
+ return ExpectedMsgId;
+ }
+
void Output(IOutputStream &str) const {
str << "ClientId# " << ClientId << " ExpectedMsgId# " << ExpectedMsgId
<< " Cost# " << Cost << " LowWatermark# " << LowWatermark
@@ -275,7 +275,7 @@ namespace NKikimr {
};
typedef TIntrusivePtr<TWindow> TWindowPtr;
- typedef THashMap<TActorId, TWindowPtr> TAllWindows;
+ typedef THashMap<TActorId, TWindowPtr> TAllWindows;
typedef TVector<TWindowPtr> TWindowPtrVec;
const bool CheckMsgId;
@@ -293,7 +293,7 @@ namespace NKikimr {
TWindowStatus RecalculateStatusCache;
TVector<TWindowStatus> OtherWindowsStatusVecCache;
TStatPtr GlobalStatPtr;
- TDuration WindowTimeout;
+ TDuration WindowTimeout;
void ClearRecalculateCache() {
@@ -302,8 +302,8 @@ namespace NKikimr {
OtherWindowsStatusVecCache.clear();
}
- void Recalculate(const TActorId& actorId, bool force, TInstant now) {
- if (CostChange < CostChangeToRecalculate && !force)
+ void Recalculate(const TActorId& actorId, bool force, TInstant now) {
+ if (CostChange < CostChangeToRecalculate && !force)
return;
ui64 actualCostChange = CostChange;
@@ -317,12 +317,12 @@ namespace NKikimr {
TIterator it = AllWindows.begin();
while (it != AllWindows.end()) {
TWindowPtr wPtr = it->second;
- EWindowState windowState = wPtr->GetState(now);
+ EWindowState windowState = wPtr->GetState(now);
switch (windowState) {
case EWindowState::Active: {
ActiveWindowsCache.push_back(wPtr);
totalCost += wPtr->GetCost();
- wPtr->Fade(windowState, actualCostChange, now);
+ wPtr->Fade(windowState, actualCostChange, now);
++it;
break;
}
@@ -331,13 +331,13 @@ namespace NKikimr {
Y_VERIFY(wPtr->GetCost() == 0);
ActiveWindowsCache.push_back(wPtr);
totalCost += wPtr->GetCost();
- wPtr->Fade(windowState, actualCostChange, now);
+ wPtr->Fade(windowState, actualCostChange, now);
++it;
break;
}
case EWindowState::Frozen: {
Y_VERIFY(wPtr->GetCost() == 0);
- wPtr->Fade(windowState, actualCostChange, now);
+ wPtr->Fade(windowState, actualCostChange, now);
++it;
break;
}
@@ -372,7 +372,7 @@ namespace NKikimr {
// adjust window
TWindowStatus *update = a->AdjustWindow(lowWatermark, highWatermark, &RecalculateStatusCache);
if (update->Notify) {
- if (a->ActorId == actorId) {
+ if (a->ActorId == actorId) {
StatusCache.WindowUpdate(*update);
} else {
OtherWindowsStatusVecCache.emplace_back(*update);
@@ -385,8 +385,8 @@ namespace NKikimr {
public:
TQueueBackpressure(bool checkMsgId, ui64 maxCost = 100u, ui64 costChangeToRecalculate = 10u,
ui64 minLowWatermark = 2u, ui64 maxLowWatermark = 20u, ui64 percentThreshold = 10u,
- ui64 costChangeUntilFrozen = 20u, ui64 costChangeUntilDeath = 30u,
- TDuration windowTimeout = TDuration::Seconds(20))
+ ui64 costChangeUntilFrozen = 20u, ui64 costChangeUntilDeath = 30u,
+ TDuration windowTimeout = TDuration::Seconds(20))
: CheckMsgId(checkMsgId)
, MaxCost(maxCost)
, CostChangeToRecalculate(costChangeToRecalculate)
@@ -402,68 +402,68 @@ namespace NKikimr {
, RecalculateStatusCache()
, OtherWindowsStatusVecCache()
, GlobalStatPtr(new TStat())
- , WindowTimeout(windowTimeout)
+ , WindowTimeout(windowTimeout)
{}
- std::optional<TMessageId> GetExpectedMsgId(const TActorId& actorId) const {
- if (const auto it = AllWindows.find(actorId); it != AllWindows.end()) {
- return it->second->GetExpectedMsgId();
- } else {
- return std::nullopt;
- }
- }
-
+ std::optional<TMessageId> GetExpectedMsgId(const TActorId& actorId) const {
+ if (const auto it = AllWindows.find(actorId); it != AllWindows.end()) {
+ return it->second->GetExpectedMsgId();
+ } else {
+ return std::nullopt;
+ }
+ }
+
TFeedback Push(const TClientId& clientId, const TActorId& actorId, const TMessageId &msgId, ui64 cost, TInstant now) {
- Y_VERIFY(actorId);
+ Y_VERIFY(actorId);
ClearRecalculateCache();
// find or create window
- bool newWindow = false;
- auto it = AllWindows.find(actorId);
+ bool newWindow = false;
+ auto it = AllWindows.find(actorId);
if (it == AllWindows.end()) {
// first connect, create window
ui64 defWindowLowWatermark = MinLowWatermark;
ui64 defWindowHighWatermark = MaxLowWatermark;
- TWindowPtr window(new TWindow(GlobalStatPtr, clientId, actorId, PercentThreshold,
+ TWindowPtr window(new TWindow(GlobalStatPtr, clientId, actorId, PercentThreshold,
defWindowLowWatermark, defWindowHighWatermark,
- CostChangeUntilFrozen, CostChangeUntilDeath,
- WindowTimeout, now));
- auto res = AllWindows.emplace(actorId, window);
+ CostChangeUntilFrozen, CostChangeUntilDeath,
+ WindowTimeout, now));
+ auto res = AllWindows.emplace(actorId, window);
it = res.first;
Y_VERIFY(res.second);
- newWindow = true;
+ newWindow = true;
}
TWindow &window = *(it->second);
// perform action
- window.Push(CheckMsgId, msgId, cost, &StatusCache, now);
+ window.Push(CheckMsgId, msgId, cost, &StatusCache, now);
CostChange += Good(StatusCache.Status) ? cost : 0;
- Recalculate(actorId, newWindow && Good(StatusCache.Status), now);
+ Recalculate(actorId, newWindow && Good(StatusCache.Status), now);
return TFeedback(StatusCache, OtherWindowsStatusVecCache);
}
- TFeedback Processed(const TActorId& actorId, const TMessageId &msgId, ui64 cost, TInstant now) {
+ TFeedback Processed(const TActorId& actorId, const TMessageId &msgId, ui64 cost, TInstant now) {
ClearRecalculateCache();
// find window
- auto it = AllWindows.find(actorId);
+ auto it = AllWindows.find(actorId);
Y_VERIFY(it != AllWindows.end());
TWindow &window = *(it->second);
// perform action
- window.Processed(CheckMsgId, msgId, cost, &StatusCache);
+ window.Processed(CheckMsgId, msgId, cost, &StatusCache);
CostChange += cost;
- Recalculate(actorId, false, now);
+ Recalculate(actorId, false, now);
return TFeedback(StatusCache, OtherWindowsStatusVecCache);
}
- template<typename TCallback>
- void ForEachWindow(TCallback&& callback) {
- for (const auto& [actorId, window] : AllWindows) {
- callback(window);
- }
- }
-
+ template<typename TCallback>
+ void ForEachWindow(TCallback&& callback) {
+ for (const auto& [actorId, window] : AllWindows) {
+ callback(window);
+ }
+ }
+
void Output(IOutputStream &str, TInstant now) const {
str << "MaxCost# " << MaxCost;
ui64 actualCost = 0;
@@ -471,7 +471,7 @@ namespace NKikimr {
ForEach(windowTypesHisto, windowTypesHisto + unsigned(EWindowState::Max), [](ui32 &x) {x = 0;});
for (const auto &x : AllWindows) {
actualCost += x.second->GetCost();
- windowTypesHisto[unsigned(x.second->GetState(now))]++;
+ windowTypesHisto[unsigned(x.second->GetState(now))]++;
}
str << " ActualCost# " << actualCost
<< " activeWindows# " << windowTypesHisto[unsigned(EWindowState::Active)]
@@ -499,15 +499,15 @@ inline void Out<NKikimr::NBackpressure::TMessageId>(IOutputStream& o,
return x.Out(o);
}
-template<>
+template<>
inline void Out<NKikimr::NBackpressure::TQueueClientId>(IOutputStream& o,
const NKikimr::NBackpressure::TQueueClientId &x) {
return x.Output(o);
}
template<>
-struct THash<NKikimr::NBackpressure::TQueueClientId> {
- size_t operator ()(const NKikimr::NBackpressure::TQueueClientId& clientId) const {
- return clientId.Hash();
- }
-};
+struct THash<NKikimr::NBackpressure::TQueueClientId> {
+ size_t operator ()(const NKikimr::NBackpressure::TQueueClientId& clientId) const {
+ return clientId.Hash();
+ }
+};
diff --git a/ydb/core/blobstorage/backpressure/queue_backpressure_server_ut.cpp b/ydb/core/blobstorage/backpressure/queue_backpressure_server_ut.cpp
index 4c6e357de6b..faec2984913 100644
--- a/ydb/core/blobstorage/backpressure/queue_backpressure_server_ut.cpp
+++ b/ydb/core/blobstorage/backpressure/queue_backpressure_server_ut.cpp
@@ -1,4 +1,4 @@
-#include "queue_backpressure_server.h"
+#include "queue_backpressure_server.h"
#include <library/cpp/testing/unittest/registar.h>
#include <util/stream/null.h>
@@ -18,36 +18,36 @@ namespace NKikimr {
Y_UNIT_TEST(CreateDelete) {
TQueueBackpressure<ui64> qb(true, 100u, 10u);
- TInstant now = Now();
- TActorId actorId(1, 1, 1, 1);
- qb.Push(5, actorId, TMessageId(0, 0), 1, now);
- qb.Push(5, actorId, TMessageId(0, 1), 1, now);
- qb.Push(5, actorId, TMessageId(0, 2), 1, now);
- qb.Push(5, actorId, TMessageId(0, 3), 1, now);
- qb.Processed(actorId, TMessageId(0, 0), 1, now);
- qb.Push(5, actorId, TMessageId(0, 4), 1, now);
- qb.Processed(actorId, TMessageId(0, 2), 1, now);
- qb.Processed(actorId, TMessageId(0, 1), 1, now);
- qb.Push(5, actorId, TMessageId(0, 4), 1, now);
- qb.Output(STR, now);
+ TInstant now = Now();
+ TActorId actorId(1, 1, 1, 1);
+ qb.Push(5, actorId, TMessageId(0, 0), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 1), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 2), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 3), 1, now);
+ qb.Processed(actorId, TMessageId(0, 0), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 4), 1, now);
+ qb.Processed(actorId, TMessageId(0, 2), 1, now);
+ qb.Processed(actorId, TMessageId(0, 1), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 4), 1, now);
+ qb.Output(STR, now);
}
Y_UNIT_TEST(IncorrectMessageId) {
TQueueBackpressure<ui64> qb(true, 100u, 10u);
- TInstant now = Now();
- TActorId actorId(1, 1, 1, 1);
- qb.Push(5, actorId, TMessageId(0, 0), 1, now);
- qb.Push(5, actorId, TMessageId(0, 1), 1, now);
- auto feedback = qb.Push(5, actorId, TMessageId(0, 1), 1, now);
+ TInstant now = Now();
+ TActorId actorId(1, 1, 1, 1);
+ qb.Push(5, actorId, TMessageId(0, 0), 1, now);
+ qb.Push(5, actorId, TMessageId(0, 1), 1, now);
+ auto feedback = qb.Push(5, actorId, TMessageId(0, 1), 1, now);
TString res = "{Status# 4 Notify# 1 ActualWindowSize# 2 MaxWindowSize# 20 "
- "ExpectedMsgId# [1 2] FailedMsgId# [0 1]}";
+ "ExpectedMsgId# [1 2] FailedMsgId# [0 1]}";
TStringStream str;
feedback.Output(str);
STR << res << "\n";
STR << str.Str() << "\n";
- UNIT_ASSERT_STRINGS_EQUAL(str.Str(), res);
+ UNIT_ASSERT_STRINGS_EQUAL(str.Str(), res);
}
@@ -62,26 +62,26 @@ namespace NKikimr {
: Id(id)
, MsgId()
, State(true)
- , ActorId(1, 1, Id, 1)
+ , ActorId(1, 1, Id, 1)
{}
TFeedback Work(TQueueBackpressure<ui64> &qb) {
- TInstant now = Now();
+ TInstant now = Now();
if (State) {
State = !State;
- return qb.Push(Id, ActorId, MsgId, 1, now);
+ return qb.Push(Id, ActorId, MsgId, 1, now);
} else {
State = !State;
- const TMessageId res = MsgId;
- ++MsgId.MsgId;
- return qb.Processed(ActorId, res, 1, now);
+ const TMessageId res = MsgId;
+ ++MsgId.MsgId;
+ return qb.Processed(ActorId, res, 1, now);
}
}
ui64 Id;
TMessageId MsgId;
bool State;
- TActorId ActorId;
+ TActorId ActorId;
};
struct TInFlightClient : public IClient {
@@ -91,19 +91,19 @@ namespace NKikimr {
, MaxInFlight(maxInFlight)
, InFlight(0)
, FullLoadObtained(false)
- , ActorId(1, 1, Id, 1)
+ , ActorId(1, 1, Id, 1)
{}
TFeedback Work(TQueueBackpressure<ui64> &qb) {
- TInstant now = Now();
+ TInstant now = Now();
if (!FullLoadObtained) {
// full load
while (true) {
- TFeedback res = qb.Push(Id, ActorId, MsgId, 1, now);
+ TFeedback res = qb.Push(Id, ActorId, MsgId, 1, now);
if (Good(res.first.Status)) {
VERBOSE_STR << "UNDERLOAD: Push OK MsgId# " << MsgId.ToString() << "\n";
InFlight++;
- MsgId.MsgId++;
+ MsgId.MsgId++;
if (InFlight == MaxInFlight) {
FullLoadObtained = true;
return res;
@@ -115,18 +115,18 @@ namespace NKikimr {
}
} else {
if (InFlight == MaxInFlight) {
- const TMessageId temp(MsgId.SequenceId, MsgId.MsgId - InFlight);
- auto res = qb.Processed(ActorId, temp, 1, now);
+ const TMessageId temp(MsgId.SequenceId, MsgId.MsgId - InFlight);
+ auto res = qb.Processed(ActorId, temp, 1, now);
Y_VERIFY(Good(res.first.Status));
- VERBOSE_STR << "LOAD: Processed: MsgId# " << temp.ToString() << "\n";
+ VERBOSE_STR << "LOAD: Processed: MsgId# " << temp.ToString() << "\n";
InFlight--;
return res;
} else {
- auto res = qb.Push(Id, ActorId, MsgId, 1, now);
+ auto res = qb.Push(Id, ActorId, MsgId, 1, now);
Y_VERIFY(Good(res.first.Status));
VERBOSE_STR << "LOAD: Push: MsgId# " << MsgId.ToString() << "\n";
InFlight++;
- MsgId.MsgId++;
+ MsgId.MsgId++;
return res;
}
}
@@ -137,7 +137,7 @@ namespace NKikimr {
const ui32 MaxInFlight;
ui32 InFlight;
bool FullLoadObtained;
- TActorId ActorId;
+ TActorId ActorId;
};
@@ -150,14 +150,14 @@ namespace NKikimr {
clients.emplace_back(new TTrivialClient(i));
}
- TInstant now = Now();
+ TInstant now = Now();
for (i = 0; i < 1000000; i++) {
for (auto &c : clients) {
c->Work(qb);
}
if (i % 100000 == 0) {
STR << "=========================\n";
- qb.Output(STR, now);
+ qb.Output(STR, now);
}
}
@@ -176,8 +176,8 @@ namespace NKikimr {
Y_UNIT_TEST(PerfInFlight) {
TQueueBackpressure<ui64> qb(true, 100u, 10u);
- TInstant now = Now();
-
+ TInstant now = Now();
+
TVector<IClientPtr> clients;
clients.emplace_back(new TInFlightClient(0, 30));
clients.emplace_back(new TInFlightClient(1, 10));
@@ -189,22 +189,22 @@ namespace NKikimr {
}
if (i % 100000 == 0) {
STR << "=========================\n";
- qb.Output(STR, now);
+ qb.Output(STR, now);
}
}
TStringStream s;
- qb.Output(s, now);
+ qb.Output(s, now);
TString res = "MaxCost# 100 ActualCost# 38 activeWindows# 2 fadingWindows# 0 "
"frozenWindows# 0 deadWindows# 0\n"
- "GlobalStat: NSuccess# 1000038 NWindowUpdate# 400005 NProcessed# 1000000 "
+ "GlobalStat: NSuccess# 1000038 NWindowUpdate# 400005 NProcessed# 1000000 "
"NIncorrectMsgId# 0 NHighWatermarkOverflow# 0\n"
"ClientId# 0 ExpectedMsgId# [0 500029] Cost# 29 LowWatermark# 20 HighWatermark# 76 "
"CostChangeUntilFrozenCountdown# 20 CostChangeUntilDeathCountdown# 30\n"
"ClientId# 1 ExpectedMsgId# [0 500009] Cost# 9 LowWatermark# 20 HighWatermark# 23 "
"CostChangeUntilFrozenCountdown# 20 CostChangeUntilDeathCountdown# 30\n";
STR << s.Str() << "\n";
- UNIT_ASSERT_STRINGS_EQUAL(s.Str(), res);
+ UNIT_ASSERT_STRINGS_EQUAL(s.Str(), res);
}
}
diff --git a/ydb/core/blobstorage/backpressure/unisched.cpp b/ydb/core/blobstorage/backpressure/unisched.cpp
index 0a0190fa1c3..17dfce4fa1a 100644
--- a/ydb/core/blobstorage/backpressure/unisched.cpp
+++ b/ydb/core/blobstorage/backpressure/unisched.cpp
@@ -1,200 +1,200 @@
-#include "unisched.h"
+#include "unisched.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/base/events.h>
-#include <util/generic/set.h>
-
-namespace NKikimr {
-
- using namespace NActors;
-
- class TUniversalSchedulerActor : public TActor<TUniversalSchedulerActor> {
- enum {
- EvRegister = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- };
-
- public:
- struct TEvRegister : TEventLocal<TEvRegister, EvRegister> {
+#include <util/generic/set.h>
+
+namespace NKikimr {
+
+ using namespace NActors;
+
+ class TUniversalSchedulerActor : public TActor<TUniversalSchedulerActor> {
+ enum {
+ EvRegister = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ };
+
+ public:
+ struct TEvRegister : TEventLocal<TEvRegister, EvRegister> {
const TActorId ActorId;
- TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
-
+ TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
+
TEvRegister(const TActorId& actorId, TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord)
- : ActorId(actorId)
- , FlowRecord(std::move(flowRecord))
- {}
- };
-
- private:
- class TSubschedulerActor : public TActorBootstrapped<TSubschedulerActor> {
- const TDuration Interval;
+ : ActorId(actorId)
+ , FlowRecord(std::move(flowRecord))
+ {}
+ };
+
+ private:
+ class TSubschedulerActor : public TActorBootstrapped<TSubschedulerActor> {
+ const TDuration Interval;
THashMap<TActorId, TIntrusivePtr<NBackpressure::TFlowRecord>> Subscribers;
-
- public:
- TSubschedulerActor(TDuration interval)
- : Interval(interval)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc);
- HandleWakeup(ctx);
- }
-
- void Handle(TEvRegister::TPtr& ev, const TActorContext& /*ctx*/) {
- TEvRegister *msg = ev->Get();
- if (msg->FlowRecord) {
- const bool inserted = Subscribers.emplace(msg->ActorId, std::move(msg->FlowRecord)).second;
- Y_VERIFY(inserted);
- } else {
- const ui32 numErased = Subscribers.erase(msg->ActorId);
- Y_VERIFY(numErased == 1);
- }
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- for (const auto& [key, value] : Subscribers) {
+
+ public:
+ TSubschedulerActor(TDuration interval)
+ : Interval(interval)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc);
+ HandleWakeup(ctx);
+ }
+
+ void Handle(TEvRegister::TPtr& ev, const TActorContext& /*ctx*/) {
+ TEvRegister *msg = ev->Get();
+ if (msg->FlowRecord) {
+ const bool inserted = Subscribers.emplace(msg->ActorId, std::move(msg->FlowRecord)).second;
+ Y_VERIFY(inserted);
+ } else {
+ const ui32 numErased = Subscribers.erase(msg->ActorId);
+ Y_VERIFY(numErased == 1);
+ }
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ for (const auto& [key, value] : Subscribers) {
if (value->GetPredictedDelayNs()) {
- ctx.Send(key, new TEvents::TEvWakeup);
- }
- }
- ctx.Schedule(GenerateIntervalWithJitter(), new TEvents::TEvWakeup);
- }
-
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::Poison, Die);
- HFunc(TEvRegister, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-
- private:
- TDuration GenerateIntervalWithJitter() const {
- auto range = Interval.GetValue() / 64 + 1;
- return TDuration::FromValue(Interval.GetValue() + RandomNumber(range) - range / 2);
- }
- };
-
- private:
- struct TSubschedulerInfo {
+ ctx.Send(key, new TEvents::TEvWakeup);
+ }
+ }
+ ctx.Schedule(GenerateIntervalWithJitter(), new TEvents::TEvWakeup);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::Poison, Die);
+ HFunc(TEvRegister, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+
+ private:
+ TDuration GenerateIntervalWithJitter() const {
+ auto range = Interval.GetValue() / 64 + 1;
+ return TDuration::FromValue(Interval.GetValue() + RandomNumber(range) - range / 2);
+ }
+ };
+
+ private:
+ struct TSubschedulerInfo {
TActorId ActorId;
- size_t NumSubscribers = 0;
-
+ size_t NumSubscribers = 0;
+
TSubschedulerInfo(const TActorId& actorId)
- : ActorId(actorId)
- {}
-
- friend bool operator <(const TSubschedulerInfo& x, const TSubschedulerInfo& y) {
- return x.NumSubscribers > y.NumSubscribers || // stored in reversed order
- (x.NumSubscribers == y.NumSubscribers && x.ActorId < y.ActorId);
- };
- };
-
- private:
- const size_t MaxActorsPerSubscheduler = 1024;
- const TDuration Interval;
+ : ActorId(actorId)
+ {}
+
+ friend bool operator <(const TSubschedulerInfo& x, const TSubschedulerInfo& y) {
+ return x.NumSubscribers > y.NumSubscribers || // stored in reversed order
+ (x.NumSubscribers == y.NumSubscribers && x.ActorId < y.ActorId);
+ };
+ };
+
+ private:
+ const size_t MaxActorsPerSubscheduler = 1024;
+ const TDuration Interval;
THashMap<TActorId, TActorId> SubscriberToSubscheduler; // subscriber to subscheduler actor id map
- using TOrderedSubschedulerSet = TSet<TSubschedulerInfo>;
- TOrderedSubschedulerSet PartialSubschedulers;
- TOrderedSubschedulerSet FullSubschedulers;
+ using TOrderedSubschedulerSet = TSet<TSubschedulerInfo>;
+ TOrderedSubschedulerSet PartialSubschedulers;
+ TOrderedSubschedulerSet FullSubschedulers;
THashMap<TActorId, TOrderedSubschedulerSet::iterator> SubschedulerToOrderedSetPosition;
-
- public:
- TUniversalSchedulerActor(const TDuration interval = TDuration::Seconds(1))
- : TActor(&TThis::StateFunc)
- , Interval(interval)
- {}
-
- void Handle(TEvRegister::TPtr& ev, const TActorContext& ctx) {
- TEvRegister *msg = ev->Get();
- (this->*(msg->FlowRecord ? &TThis::RegisterSubscriber : &TThis::UnregisterSubscriber))(msg->ActorId,
- std::unique_ptr<TEvRegister>(ev->Release().Release()), ctx);
- }
-
- void RegisterSubscriber(const TActorId& actorId, std::unique_ptr<TEvRegister> msg, const TActorContext& ctx) {
+
+ public:
+ TUniversalSchedulerActor(const TDuration interval = TDuration::Seconds(1))
+ : TActor(&TThis::StateFunc)
+ , Interval(interval)
+ {}
+
+ void Handle(TEvRegister::TPtr& ev, const TActorContext& ctx) {
+ TEvRegister *msg = ev->Get();
+ (this->*(msg->FlowRecord ? &TThis::RegisterSubscriber : &TThis::UnregisterSubscriber))(msg->ActorId,
+ std::unique_ptr<TEvRegister>(ev->Release().Release()), ctx);
+ }
+
+ void RegisterSubscriber(const TActorId& actorId, std::unique_ptr<TEvRegister> msg, const TActorContext& ctx) {
TActorId subschedulerActorId;
-
- // first, check if we have partially filled subscheduler actor -- if so, find the most filled one and stuff
- // it with one more subscriber
- if (!PartialSubschedulers) {
- PartialSubschedulers.emplace_hint(PartialSubschedulers.end(), ctx.Register(new TSubschedulerActor(Interval)));
- }
-
- // we must have one partial subscheduler actor here; if not, it was created a few lines ago
- TOrderedSubschedulerSet::iterator it;
- auto node = PartialSubschedulers.extract(PartialSubschedulers.begin());
- subschedulerActorId = node.value().ActorId;
-
- // update node usage counter
- if (++node.value().NumSubscribers == MaxActorsPerSubscheduler) {
- // this actor is now full one, so we have to move it to the full subschedulers set
- auto res = FullSubschedulers.insert(std::move(node));
- Y_VERIFY(res.inserted);
- it = res.position;
- } else {
- // put this actor back
- it = PartialSubschedulers.insert(PartialSubschedulers.begin(), std::move(node));
- }
-
- // update subscheduler actor reverse iterator mapping
- SubschedulerToOrderedSetPosition[subschedulerActorId] = it;
-
- // forward message to subscheduler actor
- const bool inserted = SubscriberToSubscheduler.emplace(actorId, subschedulerActorId).second;
- Y_VERIFY(inserted);
- ctx.Send(subschedulerActorId, msg.release());
- }
-
- void UnregisterSubscriber(const TActorId& actorId, std::unique_ptr<TEvRegister> msg, const TActorContext& ctx) {
- // find the subscheduler actor for this subscriber
- auto it = SubscriberToSubscheduler.find(actorId);
- Y_VERIFY(it != SubscriberToSubscheduler.end());
-
- // erase it from the map, remembering its actor id
+
+ // first, check if we have partially filled subscheduler actor -- if so, find the most filled one and stuff
+ // it with one more subscriber
+ if (!PartialSubschedulers) {
+ PartialSubschedulers.emplace_hint(PartialSubschedulers.end(), ctx.Register(new TSubschedulerActor(Interval)));
+ }
+
+ // we must have one partial subscheduler actor here; if not, it was created a few lines ago
+ TOrderedSubschedulerSet::iterator it;
+ auto node = PartialSubschedulers.extract(PartialSubschedulers.begin());
+ subschedulerActorId = node.value().ActorId;
+
+ // update node usage counter
+ if (++node.value().NumSubscribers == MaxActorsPerSubscheduler) {
+ // this actor is now full one, so we have to move it to the full subschedulers set
+ auto res = FullSubschedulers.insert(std::move(node));
+ Y_VERIFY(res.inserted);
+ it = res.position;
+ } else {
+ // put this actor back
+ it = PartialSubschedulers.insert(PartialSubschedulers.begin(), std::move(node));
+ }
+
+ // update subscheduler actor reverse iterator mapping
+ SubschedulerToOrderedSetPosition[subschedulerActorId] = it;
+
+ // forward message to subscheduler actor
+ const bool inserted = SubscriberToSubscheduler.emplace(actorId, subschedulerActorId).second;
+ Y_VERIFY(inserted);
+ ctx.Send(subschedulerActorId, msg.release());
+ }
+
+ void UnregisterSubscriber(const TActorId& actorId, std::unique_ptr<TEvRegister> msg, const TActorContext& ctx) {
+ // find the subscheduler actor for this subscriber
+ auto it = SubscriberToSubscheduler.find(actorId);
+ Y_VERIFY(it != SubscriberToSubscheduler.end());
+
+ // erase it from the map, remembering its actor id
const TActorId subschedulerActorId = it->second;
- SubscriberToSubscheduler.erase(it);
-
- // send unregister message to the actor
- ctx.Send(subschedulerActorId, msg.release());
-
- // find this subscheduler and its matching ordered set position
- auto subsIt = SubschedulerToOrderedSetPosition.find(subschedulerActorId);
- Y_VERIFY(subsIt != SubschedulerToOrderedSetPosition.end());
-
- // determine the set to which this subscheduler belongs and extract its node from the set
- auto& set = subsIt->second->NumSubscribers != MaxActorsPerSubscheduler ? PartialSubschedulers : FullSubschedulers;
- auto node = set.extract(subsIt->second);
- Y_VERIFY(node.value().ActorId == subschedulerActorId);
-
- if (!--node.value().NumSubscribers) {
- // this child actor has no more subscribers left -- kill the actor, forget it here
- ctx.Send(subschedulerActorId, new TEvents::TEvPoison);
- SubschedulerToOrderedSetPosition.erase(subsIt);
- } else {
- // this child actor still has subscribers, but it is in PartialSubschedulers for sure now
- auto res = PartialSubschedulers.insert(std::move(node));
- Y_VERIFY(res.inserted);
- subsIt->second = res.position;
- }
- }
-
- void Die(const TActorContext& ctx) override {
- for (const auto& [subschedulerActorId, it] : SubschedulerToOrderedSetPosition) {
- ctx.Send(subschedulerActorId, new TEvents::TEvPoison);
- }
- TActor::Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::Poison, Die);
- HFunc(TEvRegister, Handle);
- )
- };
-
- IActor *CreateUniversalSchedulerActor() {
- return new TUniversalSchedulerActor;
- }
-
+ SubscriberToSubscheduler.erase(it);
+
+ // send unregister message to the actor
+ ctx.Send(subschedulerActorId, msg.release());
+
+ // find this subscheduler and its matching ordered set position
+ auto subsIt = SubschedulerToOrderedSetPosition.find(subschedulerActorId);
+ Y_VERIFY(subsIt != SubschedulerToOrderedSetPosition.end());
+
+ // determine the set to which this subscheduler belongs and extract its node from the set
+ auto& set = subsIt->second->NumSubscribers != MaxActorsPerSubscheduler ? PartialSubschedulers : FullSubschedulers;
+ auto node = set.extract(subsIt->second);
+ Y_VERIFY(node.value().ActorId == subschedulerActorId);
+
+ if (!--node.value().NumSubscribers) {
+ // this child actor has no more subscribers left -- kill the actor, forget it here
+ ctx.Send(subschedulerActorId, new TEvents::TEvPoison);
+ SubschedulerToOrderedSetPosition.erase(subsIt);
+ } else {
+ // this child actor still has subscribers, but it is in PartialSubschedulers for sure now
+ auto res = PartialSubschedulers.insert(std::move(node));
+ Y_VERIFY(res.inserted);
+ subsIt->second = res.position;
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
+ for (const auto& [subschedulerActorId, it] : SubschedulerToOrderedSetPosition) {
+ ctx.Send(subschedulerActorId, new TEvents::TEvPoison);
+ }
+ TActor::Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::Poison, Die);
+ HFunc(TEvRegister, Handle);
+ )
+ };
+
+ IActor *CreateUniversalSchedulerActor() {
+ return new TUniversalSchedulerActor;
+ }
+
bool RegisterActorInUniversalScheduler(const TActorId& actorId, TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord,
- TActorSystem *actorSystem) {
- return actorSystem->Send(MakeUniversalSchedulerActorId(), new TUniversalSchedulerActor::TEvRegister(actorId,
- std::move(flowRecord)));
- }
-
-} // NKikimr
+ TActorSystem *actorSystem) {
+ return actorSystem->Send(MakeUniversalSchedulerActorId(), new TUniversalSchedulerActor::TEvRegister(actorId,
+ std::move(flowRecord)));
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/unisched.h b/ydb/core/blobstorage/backpressure/unisched.h
index 9331b43e70e..955072e3048 100644
--- a/ydb/core/blobstorage/backpressure/unisched.h
+++ b/ydb/core/blobstorage/backpressure/unisched.h
@@ -1,21 +1,21 @@
-#pragma once
-
-#include "defs.h"
-
-#include "queue_backpressure_common.h"
-
+#pragma once
+
+#include "defs.h"
+
+#include "queue_backpressure_common.h"
+
#include <library/cpp/actors/core/actor.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
inline TActorId MakeUniversalSchedulerActorId() {
- char name[12] = {'U', 'n', 'i', 'S', 'c', 'h', 'e', 'd', 'A', 'c', 't', 'r'};
+ char name[12] = {'U', 'n', 'i', 'S', 'c', 'h', 'e', 'd', 'A', 'c', 't', 'r'};
return TActorId(0, TStringBuf(name, sizeof(name)));
- }
-
- IActor *CreateUniversalSchedulerActor();
-
+ }
+
+ IActor *CreateUniversalSchedulerActor();
+
bool RegisterActorInUniversalScheduler(const TActorId& actorId, TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord,
- TActorSystem *actorSystem);
-
-} // NKikimr
+ TActorSystem *actorSystem);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/ut/ya.make b/ydb/core/blobstorage/backpressure/ut/ya.make
index ed318404abe..8399778b516 100644
--- a/ydb/core/blobstorage/backpressure/ut/ya.make
+++ b/ydb/core/blobstorage/backpressure/ut/ya.make
@@ -22,7 +22,7 @@ PEERDIR(
SRCS(
queue_backpressure_client_ut.cpp
- queue_backpressure_server_ut.cpp
+ queue_backpressure_server_ut.cpp
)
END()
diff --git a/ydb/core/blobstorage/backpressure/ut_client/backpressure_ut.cpp b/ydb/core/blobstorage/backpressure/ut_client/backpressure_ut.cpp
index 1a0760c6cf9..e22a81b0140 100644
--- a/ydb/core/blobstorage/backpressure/ut_client/backpressure_ut.cpp
+++ b/ydb/core/blobstorage/backpressure/ut_client/backpressure_ut.cpp
@@ -1,88 +1,88 @@
#include <ydb/core/util/testactorsys.h>
-#include "skeleton_front_mock.h"
-#include "loader.h"
-
-using namespace NKikimr;
-
-Y_UNIT_TEST_SUITE(Backpressure) {
-
- Y_UNIT_TEST(MonteCarlo) {
- TTestActorSystem runtime(1);
- runtime.Start();
-
- const TVDiskID vdiskId(0, 1, 0, 0, 0);
- TActorId vdiskActorId = runtime.Register(new TSkeletonFrontMockActor, TActorId(), 0, std::nullopt, 1);
-
+#include "skeleton_front_mock.h"
+#include "loader.h"
+
+using namespace NKikimr;
+
+Y_UNIT_TEST_SUITE(Backpressure) {
+
+ Y_UNIT_TEST(MonteCarlo) {
+ TTestActorSystem runtime(1);
+ runtime.Start();
+
+ const TVDiskID vdiskId(0, 1, 0, 0, 0);
+ TActorId vdiskActorId = runtime.Register(new TSkeletonFrontMockActor, TActorId(), 0, std::nullopt, 1);
+
std::vector<TActorId> clients;
- ui64 clientId = 1;
-
- const TInstant simDuration = TInstant::Hours(6);
- const TDuration minQ = TDuration::Seconds(10);
- const TDuration maxQ = TDuration::Seconds(20);
-
- TInstant start = TInstant::Now();
-
- while (runtime.GetClock() < simDuration) {
- Cerr << "Clock# " << runtime.GetClock()
- << " elapsed# " << (TInstant::Now() - start)
- << " EventsProcessed# " << runtime.GetEventsProcessed()
- << " clients.size# " << clients.size()
- << Endl;
-
- // TODO(alexvru): pause, resume, network disconnect, vdisk restart
- enum EActivity : ui32 {
- NOOP,
- ADD_CLIENT,
- TERM_CLIENT,
- COUNT // the last entry
- };
- std::array<ui32, EActivity::COUNT> weights;
- weights.fill(0);
- weights[NOOP] = 1000;
- weights[ADD_CLIENT] = clients.size() < 10 ? 100 : 0;
- weights[TERM_CLIENT] = clients.empty() ? 0 : 90;
- ui32 accum = 0;
- for (ui32& w : weights) {
- w = std::exchange(accum, accum + w);
- }
- const auto selector = RandomNumber(accum);
- const auto activity = std::upper_bound(weights.begin(), weights.end(), selector) - weights.begin() - 1;
- switch (activity) {
- case NOOP:
- break;
-
- case ADD_CLIENT: {
- const NBackpressure::TQueueClientId id(NBackpressure::EQueueClientType::VDiskLoad, clientId++);
- const TActorId actorId = runtime.Register(new TLoaderActor(id, vdiskId, vdiskActorId), TActorId(),
- 0, std::nullopt, 1);
- clients.push_back(actorId);
- break;
- }
-
- case TERM_CLIENT: {
- const size_t index = RandomNumber(clients.size());
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, clients[index], {}, {}, 0), 1);
- clients.erase(clients.begin() + index);
- break;
- }
-
- default:
- Y_FAIL();
- }
-
- const TDuration quantum = TDuration::FromValue(minQ.GetValue() + RandomNumber(maxQ.GetValue() - minQ.GetValue() + 1));
- const TInstant barrier = Min(simDuration, runtime.GetClock() + quantum);
- runtime.Schedule(barrier, nullptr, new TFakeSchedulerCookie, 1);
- runtime.Sim([&] { return runtime.GetClock() < barrier; });
- }
-
- // terminate loader actors and the disk
+ ui64 clientId = 1;
+
+ const TInstant simDuration = TInstant::Hours(6);
+ const TDuration minQ = TDuration::Seconds(10);
+ const TDuration maxQ = TDuration::Seconds(20);
+
+ TInstant start = TInstant::Now();
+
+ while (runtime.GetClock() < simDuration) {
+ Cerr << "Clock# " << runtime.GetClock()
+ << " elapsed# " << (TInstant::Now() - start)
+ << " EventsProcessed# " << runtime.GetEventsProcessed()
+ << " clients.size# " << clients.size()
+ << Endl;
+
+ // TODO(alexvru): pause, resume, network disconnect, vdisk restart
+ enum EActivity : ui32 {
+ NOOP,
+ ADD_CLIENT,
+ TERM_CLIENT,
+ COUNT // the last entry
+ };
+ std::array<ui32, EActivity::COUNT> weights;
+ weights.fill(0);
+ weights[NOOP] = 1000;
+ weights[ADD_CLIENT] = clients.size() < 10 ? 100 : 0;
+ weights[TERM_CLIENT] = clients.empty() ? 0 : 90;
+ ui32 accum = 0;
+ for (ui32& w : weights) {
+ w = std::exchange(accum, accum + w);
+ }
+ const auto selector = RandomNumber(accum);
+ const auto activity = std::upper_bound(weights.begin(), weights.end(), selector) - weights.begin() - 1;
+ switch (activity) {
+ case NOOP:
+ break;
+
+ case ADD_CLIENT: {
+ const NBackpressure::TQueueClientId id(NBackpressure::EQueueClientType::VDiskLoad, clientId++);
+ const TActorId actorId = runtime.Register(new TLoaderActor(id, vdiskId, vdiskActorId), TActorId(),
+ 0, std::nullopt, 1);
+ clients.push_back(actorId);
+ break;
+ }
+
+ case TERM_CLIENT: {
+ const size_t index = RandomNumber(clients.size());
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, clients[index], {}, {}, 0), 1);
+ clients.erase(clients.begin() + index);
+ break;
+ }
+
+ default:
+ Y_FAIL();
+ }
+
+ const TDuration quantum = TDuration::FromValue(minQ.GetValue() + RandomNumber(maxQ.GetValue() - minQ.GetValue() + 1));
+ const TInstant barrier = Min(simDuration, runtime.GetClock() + quantum);
+ runtime.Schedule(barrier, nullptr, new TFakeSchedulerCookie, 1);
+ runtime.Sim([&] { return runtime.GetClock() < barrier; });
+ }
+
+ // terminate loader actors and the disk
for (const TActorId& actorId : std::exchange(clients, {})) {
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, {}, 0), 1);
- }
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, vdiskActorId, {}, {}, 0), 1);
-
- runtime.Stop();
- }
-
-}
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, {}, 0), 1);
+ }
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, vdiskActorId, {}, {}, 0), 1);
+
+ runtime.Stop();
+ }
+
+}
diff --git a/ydb/core/blobstorage/backpressure/ut_client/defs.h b/ydb/core/blobstorage/backpressure/ut_client/defs.h
index 993165271b2..a026c726723 100644
--- a/ydb/core/blobstorage/backpressure/ut_client/defs.h
+++ b/ydb/core/blobstorage/backpressure/ut_client/defs.h
@@ -1,8 +1,8 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_server.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
#include <ydb/core/testlib/basics/appdata.h>
diff --git a/ydb/core/blobstorage/backpressure/ut_client/loader.h b/ydb/core/blobstorage/backpressure/ut_client/loader.h
index 2372d31d6c5..f511cc64fe7 100644
--- a/ydb/core/blobstorage/backpressure/ut_client/loader.h
+++ b/ydb/core/blobstorage/backpressure/ut_client/loader.h
@@ -1,98 +1,98 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
-class TLoaderActor : public TActorBootstrapped<TLoaderActor> {
- enum {
- EvIssuePutRequest = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- };
- struct TEvIssuePutRequest : TEventLocal<TEvIssuePutRequest, EvIssuePutRequest> {};
-
- const NBackpressure::TQueueClientId ClientId;
- const TVDiskID VDiskId;
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+class TLoaderActor : public TActorBootstrapped<TLoaderActor> {
+ enum {
+ EvIssuePutRequest = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ };
+ struct TEvIssuePutRequest : TEventLocal<TEvIssuePutRequest, EvIssuePutRequest> {};
+
+ const NBackpressure::TQueueClientId ClientId;
+ const TVDiskID VDiskId;
const TActorId VDiskActorId;
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TBSProxyContextPtr BSProxyCtx;
- TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TBSProxyContextPtr BSProxyCtx;
+ TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
TActorId QueueId;
- ui32 InFlightRemain = 16;
- bool Ready = false;
- ui32 BlobIdx = 1;
- TString Buffer = TString::Uninitialized(100 << 10);
- std::deque<TLogoBlobID> RequestQ;
-
-public:
+ ui32 InFlightRemain = 16;
+ bool Ready = false;
+ ui32 BlobIdx = 1;
+ TString Buffer = TString::Uninitialized(100 << 10);
+ std::deque<TLogoBlobID> RequestQ;
+
+public:
TLoaderActor(NBackpressure::TQueueClientId clientId, TVDiskID vdiskId, TActorId vdiskActorId)
- : ClientId(std::move(clientId))
- , VDiskId(std::move(vdiskId))
- , VDiskActorId(std::move(vdiskActorId))
- , Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
- , BSProxyCtx(MakeIntrusive<TBSProxyContext>(Counters))
- , FlowRecord(MakeIntrusive<NBackpressure::TFlowRecord>())
- {
- memset(Buffer.Detach(), '*', Buffer.size());
- }
-
- void Bootstrap() {
- LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s Bootstrap", ClientId.ToString().data());
- TVector<TActorId> vdiskIds;
- vdiskIds.push_back(VDiskActorId);
- auto info = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType(TBlobStorageGroupType::ErasureNone),
- 1u, 1u, 1u, &vdiskIds);
- QueueId = Register(CreateVDiskBackpressureClient(info, VDiskId, NKikimrBlobStorage::EVDiskQueueId::PutTabletLog,
- Counters, BSProxyCtx, ClientId, "test", 0, true, TDuration::Seconds(60), FlowRecord,
- NMonitoring::TCountableBase::EVisibility::Public));
- IssuePutRequest();
+ : ClientId(std::move(clientId))
+ , VDiskId(std::move(vdiskId))
+ , VDiskActorId(std::move(vdiskActorId))
+ , Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
+ , BSProxyCtx(MakeIntrusive<TBSProxyContext>(Counters))
+ , FlowRecord(MakeIntrusive<NBackpressure::TFlowRecord>())
+ {
+ memset(Buffer.Detach(), '*', Buffer.size());
+ }
+
+ void Bootstrap() {
+ LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s Bootstrap", ClientId.ToString().data());
+ TVector<TActorId> vdiskIds;
+ vdiskIds.push_back(VDiskActorId);
+ auto info = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType(TBlobStorageGroupType::ErasureNone),
+ 1u, 1u, 1u, &vdiskIds);
+ QueueId = Register(CreateVDiskBackpressureClient(info, VDiskId, NKikimrBlobStorage::EVDiskQueueId::PutTabletLog,
+ Counters, BSProxyCtx, ClientId, "test", 0, true, TDuration::Seconds(60), FlowRecord,
+ NMonitoring::TCountableBase::EVisibility::Public));
+ IssuePutRequest();
Become(&TThis::StateFunc);
- }
-
- void IssuePutRequest() {
- if (InFlightRemain && Ready) {
- const TLogoBlobID blobId(0x0123456789abcdefUL, 1, BlobIdx++, 0, 1, Buffer.size());
- LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s %s", ClientId.ToString().data(),
- blobId.ToString().data());
- Send(QueueId, new TEvBlobStorage::TEvVPut(blobId, Buffer, VDiskId, false, nullptr, TInstant::Max(),
- NKikimrBlobStorage::EPutHandleClass::TabletLog));
- RequestQ.push_back(blobId);
- --InFlightRemain;
- }
-
- Schedule(GenerateInactivityTimeout(), new TEvIssuePutRequest);
- }
-
- TDuration GenerateInactivityTimeout() {
- const ui32 ms = RandomNumber<ui32>(100) + 10;
- return TDuration::MilliSeconds(ms);
- }
-
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr ev) {
- ++InFlightRemain;
- auto& record = ev->Get()->Record;
- const auto& blobId = LogoBlobIDFromLogoBlobID(record.GetBlobID());
- UNIT_ASSERT(!RequestQ.empty());
- UNIT_ASSERT_VALUES_EQUAL(RequestQ.front(), blobId);
- RequestQ.pop_front();
- LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s %s %s", ClientId.ToString().data(),
- blobId.ToString().data(), NKikimrProto::EReplyStatus_Name(record.GetStatus()).data());
- }
-
- void Handle(TEvProxyQueueState::TPtr ev) {
- Ready = ev->Get()->IsConnected;
- }
-
- void PassAway() override {
- Send(QueueId, new TEvents::TEvPoison);
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StateFunc, {
- cFunc(TEvents::TSystem::Poison, PassAway);
- cFunc(EvIssuePutRequest, IssuePutRequest);
- hFunc(TEvBlobStorage::TEvVPutResult, Handle);
- hFunc(TEvProxyQueueState, Handle);
- })
-};
-
-} // NKikimr
+ }
+
+ void IssuePutRequest() {
+ if (InFlightRemain && Ready) {
+ const TLogoBlobID blobId(0x0123456789abcdefUL, 1, BlobIdx++, 0, 1, Buffer.size());
+ LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s %s", ClientId.ToString().data(),
+ blobId.ToString().data());
+ Send(QueueId, new TEvBlobStorage::TEvVPut(blobId, Buffer, VDiskId, false, nullptr, TInstant::Max(),
+ NKikimrBlobStorage::EPutHandleClass::TabletLog));
+ RequestQ.push_back(blobId);
+ --InFlightRemain;
+ }
+
+ Schedule(GenerateInactivityTimeout(), new TEvIssuePutRequest);
+ }
+
+ TDuration GenerateInactivityTimeout() {
+ const ui32 ms = RandomNumber<ui32>(100) + 10;
+ return TDuration::MilliSeconds(ms);
+ }
+
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr ev) {
+ ++InFlightRemain;
+ auto& record = ev->Get()->Record;
+ const auto& blobId = LogoBlobIDFromLogoBlobID(record.GetBlobID());
+ UNIT_ASSERT(!RequestQ.empty());
+ UNIT_ASSERT_VALUES_EQUAL(RequestQ.front(), blobId);
+ RequestQ.pop_front();
+ LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "%s %s %s", ClientId.ToString().data(),
+ blobId.ToString().data(), NKikimrProto::EReplyStatus_Name(record.GetStatus()).data());
+ }
+
+ void Handle(TEvProxyQueueState::TPtr ev) {
+ Ready = ev->Get()->IsConnected;
+ }
+
+ void PassAway() override {
+ Send(QueueId, new TEvents::TEvPoison);
+ TActorBootstrapped::PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ cFunc(EvIssuePutRequest, IssuePutRequest);
+ hFunc(TEvBlobStorage::TEvVPutResult, Handle);
+ hFunc(TEvProxyQueueState, Handle);
+ })
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/ut_client/skeleton_front_mock.h b/ydb/core/blobstorage/backpressure/ut_client/skeleton_front_mock.h
index 290c529ea56..fbb8455a593 100644
--- a/ydb/core/blobstorage/backpressure/ut_client/skeleton_front_mock.h
+++ b/ydb/core/blobstorage/backpressure/ut_client/skeleton_front_mock.h
@@ -1,166 +1,166 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
-class TSkeletonFrontMockActor : public TActorBootstrapped<TSkeletonFrontMockActor> {
- enum {
- EvProcessQueue = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- };
- struct TEvProcessQueue : TEventLocal<TEvProcessQueue, EvProcessQueue> {};
-
- bool Ready = false;
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+class TSkeletonFrontMockActor : public TActorBootstrapped<TSkeletonFrontMockActor> {
+ enum {
+ EvProcessQueue = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ };
+ struct TEvProcessQueue : TEventLocal<TEvProcessQueue, EvProcessQueue> {};
+
+ bool Ready = false;
std::set<TActorId> Notify;
- std::optional<TCostModel> CostModel;
- NBackpressure::TQueueBackpressure<NBackpressure::TQueueClientId> Server;
-
- struct TOperation {
- NBackpressure::TQueueClientId ClientId;
- NBackpressure::TMessageId MessageId;
- ui64 Cost;
- std::unique_ptr<IEventHandle> Result;
+ std::optional<TCostModel> CostModel;
+ NBackpressure::TQueueBackpressure<NBackpressure::TQueueClientId> Server;
+
+ struct TOperation {
+ NBackpressure::TQueueClientId ClientId;
+ NBackpressure::TMessageId MessageId;
+ ui64 Cost;
+ std::unique_ptr<IEventHandle> Result;
TActorId Sender;
- };
-
- std::deque<TOperation> Operations;
-
-public:
- TSkeletonFrontMockActor()
- : Server(true, 1000000, 100000, 20000, 200000, 100000, 200000, 300000, TDuration::Minutes(1))
- {}
-
- void Bootstrap() {
- NKikimrBlobStorage::TVDiskCostSettings settings;
- FillInCostSettings(&settings);
+ };
+
+ std::deque<TOperation> Operations;
+
+public:
+ TSkeletonFrontMockActor()
+ : Server(true, 1000000, 100000, 20000, 200000, 100000, 200000, 300000, TDuration::Minutes(1))
+ {}
+
+ void Bootstrap() {
+ NKikimrBlobStorage::TVDiskCostSettings settings;
+ FillInCostSettings(&settings);
CostModel.emplace(settings, TErasureType::ErasureNone);
-
- Become(&TThis::StateFunc, TDuration::Seconds(10), new TEvents::TEvWakeup);
- }
-
- void HandleWakeup() {
- LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "HandleWakeup");
- Ready = true;
+
+ Become(&TThis::StateFunc, TDuration::Seconds(10), new TEvents::TEvWakeup);
+ }
+
+ void HandleWakeup() {
+ LOG_DEBUG(*TlsActivationContext, NActorsServices::TEST, "HandleWakeup");
+ Ready = true;
for (const TActorId& id : std::exchange(Notify, {})) {
- Send(id, new TEvBlobStorage::TEvVReadyNotify);
- }
- }
-
- void Reply(IEventHandle& ev, IEventBase *reply) {
- Send(ev.Sender, reply, IEventHandle::MakeFlags(ev.GetChannel(), 0), ev.Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvVCheckReadiness::TPtr ev) {
- auto& record = ev->Get()->Record;
- if (!Ready && record.GetNotifyIfNotReady()) {
- Notify.insert(ev->Sender);
- }
- Reply(*ev, new TEvBlobStorage::TEvVCheckReadinessResult(Ready ? NKikimrProto::OK : NKikimrProto::NOTREADY));
- }
-
- void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
- auto& record = ev->Get()->Record;
-
- if (!Ready) {
- Reply(*ev, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::NOTREADY, record.GetVDiskID()));
- if (record.GetNotifyIfNotReady()) {
- Notify.insert(ev->Sender);
- }
- }
- }
-
- void Handle(TEvBlobStorage::TEvVPut::TPtr ev) {
- auto& record = ev->Get()->Record;
- const TLogoBlobID& blobId = LogoBlobIDFromLogoBlobID(record.GetBlobID());
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- const ui64 cookie = record.GetCookie();
-
- if (!Ready) {
- Reply(*ev, new TEvBlobStorage::TEvVPutResult(NKikimrProto::NOTREADY,
- blobId, vdiskId, record.HasCookie() ? &cookie : nullptr,
- TOutOfSpaceStatus(0, 0), TActivationContext::Now(), ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, record.GetBuffer().size(), {}, 0, TString()));
- if (record.GetNotifyIfNotReady()) {
- Notify.insert(ev->Sender);
- }
- return;
- }
-
- UNIT_ASSERT(record.HasMsgQoS());
-
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> reply(new TEvBlobStorage::TEvVPutResult(NKikimrProto::OK,
- blobId, vdiskId, record.HasCookie() ? &cookie : nullptr,
- TOutOfSpaceStatus(0, 0), TActivationContext::Now(), ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, record.GetBuffer().size(), {}, 0, TString()));
-
- auto *qos = reply->Record.MutableMsgQoS();
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Received " << SingleLineProto(*qos));
-
- if (qos->GetSendMeCostSettings()) {
- FillInCostSettings(qos->MutableCostSettings());
- }
-
- const NBackpressure::TQueueClientId clientId(*qos);
- const NBackpressure::TMessageId messageId(qos->GetMsgId());
- const ui64 cost = CostModel->GetCost(*ev->Get());
- auto feedback = Server.Push(clientId, ev->Sender, messageId, cost, TActivationContext::Now());
- feedback.first.Serialize(*qos->MutableWindow());
- NotifyClients(feedback.second);
- if (feedback.Good()) {
- if (Operations.empty()) {
- Schedule(TDuration::MicroSeconds((999 + cost) / 1000), new TEvProcessQueue);
- }
- Operations.push_back(TOperation{clientId, messageId, cost, std::make_unique<IEventHandle>(ev->Sender,
- SelfId(), reply.release(), IEventHandle::MakeFlags(ev->GetChannel(), 0), ev->Cookie), ev->Sender});
- } else {
- reply->Record.SetStatus(feedback.first.Status == NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId
- ? NKikimrProto::TRYLATER : NKikimrProto::TRYLATER_SIZE);
-
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Sending bad " << SingleLineProto(reply->Record));
-
- Reply(*ev, reply.release());
- }
- }
-
- void HandleProcessQueue() {
- TOperation& op = Operations.front();
-
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Sending " << SingleLineProto(op.Result->Get<TEvBlobStorage::TEvVPutResult>()->Record));
-
- TActivationContext::Send(op.Result.release());
-
- auto feedback = Server.Processed(op.Sender, op.MessageId, op.Cost, TActivationContext::Now());
- Send(op.Sender, new TEvBlobStorage::TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, feedback.first));
- NotifyClients(feedback.second);
- Operations.pop_front();
- if (!Operations.empty()) {
- Schedule(TDuration::MicroSeconds((999 + Operations.front().Cost) / 1000), new TEvProcessQueue);
- }
- }
-
- void NotifyClients(const std::vector<NBackpressure::TWindowStatus<NBackpressure::TQueueClientId>>& feedback) {
- for (const auto& item : feedback) {
- Send(item.ActorId, new TEvBlobStorage::TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, item));
- }
- }
-
- void FillInCostSettings(NKikimrBlobStorage::TVDiskCostSettings *settings) {
- settings->SetSeekTimeUs(60e6 / 7200); // HDD, for instance
- settings->SetReadSpeedBps(60e6);
- settings->SetWriteSpeedBps(60e6);
- settings->SetReadBlockSize(4096);
- settings->SetWriteBlockSize(4096);
- settings->SetMinREALHugeBlobInBytes(512 << 10);
- }
-
- STRICT_STFUNC(StateFunc, {
- cFunc(TEvents::TSystem::Poison, PassAway);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- cFunc(EvProcessQueue, HandleProcessQueue);
- hFunc(TEvBlobStorage::TEvVStatus, Handle);
- hFunc(TEvBlobStorage::TEvVCheckReadiness, Handle);
- hFunc(TEvBlobStorage::TEvVPut, Handle);
- })
-};
-
-} // NKikimr
+ Send(id, new TEvBlobStorage::TEvVReadyNotify);
+ }
+ }
+
+ void Reply(IEventHandle& ev, IEventBase *reply) {
+ Send(ev.Sender, reply, IEventHandle::MakeFlags(ev.GetChannel(), 0), ev.Cookie);
+ }
+
+ void Handle(TEvBlobStorage::TEvVCheckReadiness::TPtr ev) {
+ auto& record = ev->Get()->Record;
+ if (!Ready && record.GetNotifyIfNotReady()) {
+ Notify.insert(ev->Sender);
+ }
+ Reply(*ev, new TEvBlobStorage::TEvVCheckReadinessResult(Ready ? NKikimrProto::OK : NKikimrProto::NOTREADY));
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
+ auto& record = ev->Get()->Record;
+
+ if (!Ready) {
+ Reply(*ev, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::NOTREADY, record.GetVDiskID()));
+ if (record.GetNotifyIfNotReady()) {
+ Notify.insert(ev->Sender);
+ }
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVPut::TPtr ev) {
+ auto& record = ev->Get()->Record;
+ const TLogoBlobID& blobId = LogoBlobIDFromLogoBlobID(record.GetBlobID());
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ const ui64 cookie = record.GetCookie();
+
+ if (!Ready) {
+ Reply(*ev, new TEvBlobStorage::TEvVPutResult(NKikimrProto::NOTREADY,
+ blobId, vdiskId, record.HasCookie() ? &cookie : nullptr,
+ TOutOfSpaceStatus(0, 0), TActivationContext::Now(), ev->Get()->GetCachedByteSize(),
+ &record, nullptr, nullptr, nullptr, record.GetBuffer().size(), {}, 0, TString()));
+ if (record.GetNotifyIfNotReady()) {
+ Notify.insert(ev->Sender);
+ }
+ return;
+ }
+
+ UNIT_ASSERT(record.HasMsgQoS());
+
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> reply(new TEvBlobStorage::TEvVPutResult(NKikimrProto::OK,
+ blobId, vdiskId, record.HasCookie() ? &cookie : nullptr,
+ TOutOfSpaceStatus(0, 0), TActivationContext::Now(), ev->Get()->GetCachedByteSize(),
+ &record, nullptr, nullptr, nullptr, record.GetBuffer().size(), {}, 0, TString()));
+
+ auto *qos = reply->Record.MutableMsgQoS();
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Received " << SingleLineProto(*qos));
+
+ if (qos->GetSendMeCostSettings()) {
+ FillInCostSettings(qos->MutableCostSettings());
+ }
+
+ const NBackpressure::TQueueClientId clientId(*qos);
+ const NBackpressure::TMessageId messageId(qos->GetMsgId());
+ const ui64 cost = CostModel->GetCost(*ev->Get());
+ auto feedback = Server.Push(clientId, ev->Sender, messageId, cost, TActivationContext::Now());
+ feedback.first.Serialize(*qos->MutableWindow());
+ NotifyClients(feedback.second);
+ if (feedback.Good()) {
+ if (Operations.empty()) {
+ Schedule(TDuration::MicroSeconds((999 + cost) / 1000), new TEvProcessQueue);
+ }
+ Operations.push_back(TOperation{clientId, messageId, cost, std::make_unique<IEventHandle>(ev->Sender,
+ SelfId(), reply.release(), IEventHandle::MakeFlags(ev->GetChannel(), 0), ev->Cookie), ev->Sender});
+ } else {
+ reply->Record.SetStatus(feedback.first.Status == NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId
+ ? NKikimrProto::TRYLATER : NKikimrProto::TRYLATER_SIZE);
+
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Sending bad " << SingleLineProto(reply->Record));
+
+ Reply(*ev, reply.release());
+ }
+ }
+
+ void HandleProcessQueue() {
+ TOperation& op = Operations.front();
+
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, "Sending " << SingleLineProto(op.Result->Get<TEvBlobStorage::TEvVPutResult>()->Record));
+
+ TActivationContext::Send(op.Result.release());
+
+ auto feedback = Server.Processed(op.Sender, op.MessageId, op.Cost, TActivationContext::Now());
+ Send(op.Sender, new TEvBlobStorage::TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, feedback.first));
+ NotifyClients(feedback.second);
+ Operations.pop_front();
+ if (!Operations.empty()) {
+ Schedule(TDuration::MicroSeconds((999 + Operations.front().Cost) / 1000), new TEvProcessQueue);
+ }
+ }
+
+ void NotifyClients(const std::vector<NBackpressure::TWindowStatus<NBackpressure::TQueueClientId>>& feedback) {
+ for (const auto& item : feedback) {
+ Send(item.ActorId, new TEvBlobStorage::TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, item));
+ }
+ }
+
+ void FillInCostSettings(NKikimrBlobStorage::TVDiskCostSettings *settings) {
+ settings->SetSeekTimeUs(60e6 / 7200); // HDD, for instance
+ settings->SetReadSpeedBps(60e6);
+ settings->SetWriteSpeedBps(60e6);
+ settings->SetReadBlockSize(4096);
+ settings->SetWriteBlockSize(4096);
+ settings->SetMinREALHugeBlobInBytes(512 << 10);
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(EvProcessQueue, HandleProcessQueue);
+ hFunc(TEvBlobStorage::TEvVStatus, Handle);
+ hFunc(TEvBlobStorage::TEvVCheckReadiness, Handle);
+ hFunc(TEvBlobStorage::TEvVPut, Handle);
+ })
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/backpressure/ut_client/ya.make b/ydb/core/blobstorage/backpressure/ut_client/ya.make
index 3848d38a5e2..3c012a2466e 100644
--- a/ydb/core/blobstorage/backpressure/ut_client/ya.make
+++ b/ydb/core/blobstorage/backpressure/ut_client/ya.make
@@ -1,26 +1,26 @@
-UNITTEST()
-
-OWNER(g:kikimr)
-
-SIZE(MEDIUM)
-
-PEERDIR(
- library/cpp/actors/interconnect/mock
+UNITTEST()
+
+OWNER(g:kikimr)
+
+SIZE(MEDIUM)
+
+PEERDIR(
+ library/cpp/actors/interconnect/mock
ydb/core/blobstorage/backpressure
ydb/core/blobstorage/base
ydb/core/blobstorage/vdisk
ydb/core/blobstorage/vdisk/common
ydb/core/tx/scheme_board
ydb/library/yql/public/udf/service/stub
-)
-
-YQL_LAST_ABI_VERSION()
-
-SRCS(
- backpressure_ut.cpp
- defs.h
- loader.h
- skeleton_front_mock.h
-)
+)
+
+YQL_LAST_ABI_VERSION()
-END()
+SRCS(
+ backpressure_ut.cpp
+ defs.h
+ loader.h
+ skeleton_front_mock.h
+)
+
+END()
diff --git a/ydb/core/blobstorage/backpressure/ya.make b/ydb/core/blobstorage/backpressure/ya.make
index 9dcc8176598..1e60e99ced8 100644
--- a/ydb/core/blobstorage/backpressure/ya.make
+++ b/ydb/core/blobstorage/backpressure/ya.make
@@ -1,6 +1,6 @@
LIBRARY()
-OWNER(alexvru)
+OWNER(alexvru)
PEERDIR(
contrib/libs/protobuf
@@ -13,18 +13,18 @@ PEERDIR(
)
SRCS(
- common.h
+ common.h
defs.h
- event.cpp
- event.h
- queue.cpp
- queue.h
+ event.cpp
+ event.h
+ queue.cpp
+ queue.h
queue_backpressure_client.cpp
queue_backpressure_client.h
queue_backpressure_common.h
queue_backpressure_server.h
- unisched.cpp
- unisched.h
+ unisched.cpp
+ unisched.h
)
END()
diff --git a/ydb/core/blobstorage/base/blobstorage_events.h b/ydb/core/blobstorage/base/blobstorage_events.h
index ef170a085d8..3580519532b 100644
--- a/ydb/core/blobstorage/base/blobstorage_events.h
+++ b/ydb/core/blobstorage/base/blobstorage_events.h
@@ -16,15 +16,15 @@ namespace NKikimr {
TEvBlobStorage::EvControllerUpdateDiskStatus> {
TEvControllerUpdateDiskStatus() = default;
- TEvControllerUpdateDiskStatus(const TVDiskID& vDiskId, ui32 nodeId, ui32 pdiskId, ui32 vslotId,
- ui32 satisfactionRankPercent) {
+ TEvControllerUpdateDiskStatus(const TVDiskID& vDiskId, ui32 nodeId, ui32 pdiskId, ui32 vslotId,
+ ui32 satisfactionRankPercent) {
NKikimrBlobStorage::TVDiskMetrics* metric = Record.AddVDisksMetrics();
VDiskIDFromVDiskID(vDiskId, metric->MutableVDiskId());
metric->SetSatisfactionRank(satisfactionRankPercent);
- auto *p = metric->MutableVSlotId();
- p->SetNodeId(nodeId);
- p->SetPDiskId(pdiskId);
- p->SetVSlotId(vslotId);
+ auto *p = metric->MutableVSlotId();
+ p->SetNodeId(nodeId);
+ p->SetPDiskId(pdiskId);
+ p->SetVSlotId(vslotId);
}
};
@@ -36,7 +36,7 @@ namespace NKikimr {
TEvControllerRegisterNode()
{}
- TEvControllerRegisterNode(ui32 nodeID, const TVector<ui32>& startedDynamicGroups,
+ TEvControllerRegisterNode(ui32 nodeID, const TVector<ui32>& startedDynamicGroups,
const TVector<ui32>& groupGenerations, const TVector<NPDisk::TDriveData>& drivesData) {
Record.SetNodeID(nodeID);
for (auto groupId: startedDynamicGroups) {
@@ -112,11 +112,11 @@ namespace NKikimr {
TEvControllerGroupReconfigureWipe()
{}
- TEvControllerGroupReconfigureWipe(ui32 nodeId, ui32 pDiskId, ui32 vSlotId) {
- auto *id = Record.MutableVSlotId();
- id->SetNodeId(nodeId);
- id->SetPDiskId(pDiskId);
- id->SetVSlotId(vSlotId);
+ TEvControllerGroupReconfigureWipe(ui32 nodeId, ui32 pDiskId, ui32 vSlotId) {
+ auto *id = Record.MutableVSlotId();
+ id->SetNodeId(nodeId);
+ id->SetPDiskId(pDiskId);
+ id->SetVSlotId(vSlotId);
}
TString ToString() const override {
@@ -168,14 +168,14 @@ namespace NKikimr {
Record.AddGroupIDs(groupID);
}
- template<typename TBeginIter, typename TEndIter = TBeginIter>
- TEvControllerGetGroup(ui32 nodeID, TBeginIter beginIter, TEndIter&& endIter) {
- Record.SetNodeID(nodeID);
- while (beginIter != endIter) {
- Record.AddGroupIDs(*beginIter++);
- }
- }
-
+ template<typename TBeginIter, typename TEndIter = TBeginIter>
+ TEvControllerGetGroup(ui32 nodeID, TBeginIter beginIter, TEndIter&& endIter) {
+ Record.SetNodeID(nodeID);
+ while (beginIter != endIter) {
+ Record.AddGroupIDs(*beginIter++);
+ }
+ }
+
TString ToString() const override {
TStringStream str;
str << "{TEvControllerGetGroup NodeID# " << Record.GetNodeID();
@@ -202,7 +202,7 @@ namespace NKikimr {
TString ToString() const override {
TStringStream str;
- str << "{TEvControllerSelectGroups}";
+ str << "{TEvControllerSelectGroups}";
return str.Str();
}
};
@@ -265,7 +265,7 @@ namespace NKikimr {
struct TEvBlobStorage::TEvControllerConfigResponse : TEventPB<TEvBlobStorage::TEvControllerConfigResponse,
NKikimrBlobStorage::TEvControllerConfigResponse, TEvBlobStorage::EvControllerConfigResponse>
{
- TEvControllerConfigResponse() = default;
+ TEvControllerConfigResponse() = default;
};
struct TEvBlobStorage::TEvControllerProposeGroupKey : public TEventPB<
@@ -277,7 +277,7 @@ namespace NKikimr {
{}
TEvControllerProposeGroupKey(ui32 nodeId, ui32 groupId, ui32 lifeCyclePhase,
- const TString& mainKeyId, const TString& encryptedGroupKey, ui64 mainKeyVersion, ui64 groupKeyNonce) {
+ const TString& mainKeyId, const TString& encryptedGroupKey, ui64 mainKeyVersion, ui64 groupKeyNonce) {
Record.SetNodeId(nodeId);
Record.SetGroupId(groupId);
Record.SetLifeCyclePhase(lifeCyclePhase);
@@ -322,16 +322,16 @@ namespace NKikimr {
{
TEvVStatusResult() = default;
- TEvVStatusResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, bool joinedGroup, bool replicated,
- ui64 incarnationGuid)
+ TEvVStatusResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, bool joinedGroup, bool replicated,
+ ui64 incarnationGuid)
{
Record.SetStatus(status);
Record.SetJoinedGroup(joinedGroup);
Record.SetReplicated(replicated);
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
}
TEvVStatusResult(NKikimrProto::EReplyStatus status, const NKikimrBlobStorage::TVDiskID &vdisk) {
@@ -401,24 +401,24 @@ namespace NKikimr {
{}
};
- struct TEvBlobStorage::TEvDropDonor : TEventLocal<TEvDropDonor, EvDropDonor> {
- const ui32 NodeId;
- const ui32 PDiskId;
- const ui32 VSlotId;
- const TVDiskID VDiskId;
-
- TEvDropDonor(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- , VSlotId(vslotId)
- , VDiskId(vdiskId)
- {}
- };
-
- struct TEvBlobStorage::TEvBunchOfEvents : TEventLocal<TEvBunchOfEvents, EvBunchOfEvents> {
- std::vector<std::unique_ptr<IEventHandle>> Bunch;
- };
-
+ struct TEvBlobStorage::TEvDropDonor : TEventLocal<TEvDropDonor, EvDropDonor> {
+ const ui32 NodeId;
+ const ui32 PDiskId;
+ const ui32 VSlotId;
+ const TVDiskID VDiskId;
+
+ TEvDropDonor(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VSlotId(vslotId)
+ , VDiskId(vdiskId)
+ {}
+ };
+
+ struct TEvBlobStorage::TEvBunchOfEvents : TEventLocal<TEvBunchOfEvents, EvBunchOfEvents> {
+ std::vector<std::unique_ptr<IEventHandle>> Bunch;
+ };
+
struct TEvBlobStorage::TEvAskRestartPDisk : TEventLocal<TEvAskRestartPDisk, EvAskRestartPDisk> {
const ui32 PDiskId;
@@ -448,104 +448,104 @@ namespace NKikimr {
, Status(status)
{}
};
-
- struct TEvBlobStorage::TEvControllerScrubQueryStartQuantum : TEventPB<TEvControllerScrubQueryStartQuantum,
- NKikimrBlobStorage::TEvControllerScrubQueryStartQuantum, EvControllerScrubQueryStartQuantum> {
- TEvControllerScrubQueryStartQuantum() = default;
-
- TEvControllerScrubQueryStartQuantum(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
- auto *x = Record.MutableVSlotId();
- x->SetNodeId(nodeId);
- x->SetPDiskId(pdiskId);
- x->SetVSlotId(vslotId);
- }
- };
-
- struct TEvBlobStorage::TEvControllerScrubStartQuantum : TEventPB<TEvControllerScrubStartQuantum,
- NKikimrBlobStorage::TEvControllerScrubStartQuantum, EvControllerScrubStartQuantum> {
- TEvControllerScrubStartQuantum() = default;
-
- TEvControllerScrubStartQuantum(ui32 nodeId, ui32 pdiskId, ui32 vslotId, std::optional<TString> state) {
- auto *x = Record.MutableVSlotId();
- x->SetNodeId(nodeId);
- x->SetPDiskId(pdiskId);
- x->SetVSlotId(vslotId);
- if (state) {
- Record.SetState(*state);
- }
- }
- };
-
- struct TEvBlobStorage::TEvControllerScrubQuantumFinished : TEventPB<TEvControllerScrubQuantumFinished,
- NKikimrBlobStorage::TEvControllerScrubQuantumFinished, EvControllerScrubQuantumFinished> {
- TEvControllerScrubQuantumFinished() = default;
-
- TEvControllerScrubQuantumFinished(const NKikimrBlobStorage::TEvControllerScrubQuantumFinished& m) {
- Record.CopyFrom(m);
- }
-
- TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TString& state)
- : TEvControllerScrubQuantumFinished(nodeId, pdiskId, vslotId)
- {
- Record.SetState(state);
- }
-
- TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId, bool success)
- : TEvControllerScrubQuantumFinished(nodeId, pdiskId, vslotId)
- {
- Record.SetSuccess(success);
- }
-
- TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
- auto *x = Record.MutableVSlotId();
- x->SetNodeId(nodeId);
- x->SetPDiskId(pdiskId);
- x->SetVSlotId(vslotId);
- }
- };
-
- struct TEvBlobStorage::TEvControllerScrubReportQuantumInProgress : TEventPB<TEvControllerScrubReportQuantumInProgress,
- NKikimrBlobStorage::TEvControllerScrubReportQuantumInProgress, EvControllerScrubReportQuantumInProgress> {
- TEvControllerScrubReportQuantumInProgress() = default;
-
- TEvControllerScrubReportQuantumInProgress(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
- auto *x = Record.MutableVSlotId();
- x->SetNodeId(nodeId);
- x->SetPDiskId(pdiskId);
- x->SetVSlotId(vslotId);
- }
- };
-
- struct TEvNodeWardenQueryGroupInfo : TEventPB<TEvNodeWardenQueryGroupInfo, NKikimrBlobStorage::TEvNodeWardenQueryGroupInfo,
- TEvBlobStorage::EvNodeWardenQueryGroupInfo> {
- TEvNodeWardenQueryGroupInfo() = default;
-
- TEvNodeWardenQueryGroupInfo(ui32 groupId) {
- Record.SetGroupId(groupId);
- }
- };
-
- struct TEvNodeWardenGroupInfo : TEventPB<TEvNodeWardenGroupInfo, NKikimrBlobStorage::TEvNodeWardenGroupInfo,
- TEvBlobStorage::EvNodeWardenGroupInfo> {
- TEvNodeWardenGroupInfo() = default;
-
- TEvNodeWardenGroupInfo(const NKikimrBlobStorage::TGroupInfo& group) {
- Record.MutableGroup()->CopyFrom(group);
- }
- };
-
- struct TEvStatusUpdate : TEventLocal<TEvStatusUpdate, TEvBlobStorage::EvStatusUpdate> {
- ui32 NodeId;
- ui32 PDiskId;
- ui32 VSlotId;
- NKikimrBlobStorage::EVDiskStatus Status;
-
- TEvStatusUpdate(ui32 nodeId, ui32 pdiskId, ui32 vslotId, NKikimrBlobStorage::EVDiskStatus status)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- , VSlotId(vslotId)
- , Status(status)
- {}
- };
-
+
+ struct TEvBlobStorage::TEvControllerScrubQueryStartQuantum : TEventPB<TEvControllerScrubQueryStartQuantum,
+ NKikimrBlobStorage::TEvControllerScrubQueryStartQuantum, EvControllerScrubQueryStartQuantum> {
+ TEvControllerScrubQueryStartQuantum() = default;
+
+ TEvControllerScrubQueryStartQuantum(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
+ auto *x = Record.MutableVSlotId();
+ x->SetNodeId(nodeId);
+ x->SetPDiskId(pdiskId);
+ x->SetVSlotId(vslotId);
+ }
+ };
+
+ struct TEvBlobStorage::TEvControllerScrubStartQuantum : TEventPB<TEvControllerScrubStartQuantum,
+ NKikimrBlobStorage::TEvControllerScrubStartQuantum, EvControllerScrubStartQuantum> {
+ TEvControllerScrubStartQuantum() = default;
+
+ TEvControllerScrubStartQuantum(ui32 nodeId, ui32 pdiskId, ui32 vslotId, std::optional<TString> state) {
+ auto *x = Record.MutableVSlotId();
+ x->SetNodeId(nodeId);
+ x->SetPDiskId(pdiskId);
+ x->SetVSlotId(vslotId);
+ if (state) {
+ Record.SetState(*state);
+ }
+ }
+ };
+
+ struct TEvBlobStorage::TEvControllerScrubQuantumFinished : TEventPB<TEvControllerScrubQuantumFinished,
+ NKikimrBlobStorage::TEvControllerScrubQuantumFinished, EvControllerScrubQuantumFinished> {
+ TEvControllerScrubQuantumFinished() = default;
+
+ TEvControllerScrubQuantumFinished(const NKikimrBlobStorage::TEvControllerScrubQuantumFinished& m) {
+ Record.CopyFrom(m);
+ }
+
+ TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TString& state)
+ : TEvControllerScrubQuantumFinished(nodeId, pdiskId, vslotId)
+ {
+ Record.SetState(state);
+ }
+
+ TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId, bool success)
+ : TEvControllerScrubQuantumFinished(nodeId, pdiskId, vslotId)
+ {
+ Record.SetSuccess(success);
+ }
+
+ TEvControllerScrubQuantumFinished(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
+ auto *x = Record.MutableVSlotId();
+ x->SetNodeId(nodeId);
+ x->SetPDiskId(pdiskId);
+ x->SetVSlotId(vslotId);
+ }
+ };
+
+ struct TEvBlobStorage::TEvControllerScrubReportQuantumInProgress : TEventPB<TEvControllerScrubReportQuantumInProgress,
+ NKikimrBlobStorage::TEvControllerScrubReportQuantumInProgress, EvControllerScrubReportQuantumInProgress> {
+ TEvControllerScrubReportQuantumInProgress() = default;
+
+ TEvControllerScrubReportQuantumInProgress(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
+ auto *x = Record.MutableVSlotId();
+ x->SetNodeId(nodeId);
+ x->SetPDiskId(pdiskId);
+ x->SetVSlotId(vslotId);
+ }
+ };
+
+ struct TEvNodeWardenQueryGroupInfo : TEventPB<TEvNodeWardenQueryGroupInfo, NKikimrBlobStorage::TEvNodeWardenQueryGroupInfo,
+ TEvBlobStorage::EvNodeWardenQueryGroupInfo> {
+ TEvNodeWardenQueryGroupInfo() = default;
+
+ TEvNodeWardenQueryGroupInfo(ui32 groupId) {
+ Record.SetGroupId(groupId);
+ }
+ };
+
+ struct TEvNodeWardenGroupInfo : TEventPB<TEvNodeWardenGroupInfo, NKikimrBlobStorage::TEvNodeWardenGroupInfo,
+ TEvBlobStorage::EvNodeWardenGroupInfo> {
+ TEvNodeWardenGroupInfo() = default;
+
+ TEvNodeWardenGroupInfo(const NKikimrBlobStorage::TGroupInfo& group) {
+ Record.MutableGroup()->CopyFrom(group);
+ }
+ };
+
+ struct TEvStatusUpdate : TEventLocal<TEvStatusUpdate, TEvBlobStorage::EvStatusUpdate> {
+ ui32 NodeId;
+ ui32 PDiskId;
+ ui32 VSlotId;
+ NKikimrBlobStorage::EVDiskStatus Status;
+
+ TEvStatusUpdate(ui32 nodeId, ui32 pdiskId, ui32 vslotId, NKikimrBlobStorage::EVDiskStatus status)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VSlotId(vslotId)
+ , Status(status)
+ {}
+ };
+
} // NKikimr
diff --git a/ydb/core/blobstorage/base/blobstorage_vdiskid.h b/ydb/core/blobstorage/base/blobstorage_vdiskid.h
index c8d5a818b15..47b77fd2b38 100644
--- a/ydb/core/blobstorage/base/blobstorage_vdiskid.h
+++ b/ydb/core/blobstorage/base/blobstorage_vdiskid.h
@@ -1,9 +1,9 @@
#pragma once
-
+
#include "defs.h"
-
+
#include <ydb/core/protos/blobstorage.pb.h>
-
+
#include <util/str_stl.h>
#include <util/digest/numeric.h>
@@ -11,7 +11,7 @@ namespace NKikimr {
class TBlobStorageGroupInfo;
struct TVDiskIdShort;
-
+
////////////////////////////////////////////////////////////////////////////
// TVDiskID -- global vdisk identifier
////////////////////////////////////////////////////////////////////////////
@@ -28,11 +28,11 @@ struct TVDiskID {
TVDiskID(ui32 groupId, ui32 groupGen, TVDiskIdShort vdiskIdShort);
TVDiskID(IInputStream &str);
- TVDiskID(ui32 groupId, ui32 groupGen, ui8 failRealm, ui8 failDomain, ui8 vdisk)
+ TVDiskID(ui32 groupId, ui32 groupGen, ui8 failRealm, ui8 failDomain, ui8 vdisk)
: GroupID(groupId)
, GroupGeneration(groupGen)
- , FailRealm(failRealm)
- , FailDomain(failDomain)
+ , FailRealm(failRealm)
+ , FailDomain(failDomain)
, VDisk(vdisk)
{}
@@ -47,20 +47,20 @@ struct TVDiskID {
bool SameExceptGeneration(const TVDiskID &x) const {
return x.GroupID == GroupID && x.FailRealm == FailRealm && x.FailDomain == FailDomain && x.VDisk == VDisk;
}
-
+
bool SameDisk(const TVDiskID &x) const {
return *this == x;
}
bool SameDisk(const NKikimrBlobStorage::TVDiskID &x) const;
- auto ConvertToTuple() const {
- return std::make_tuple(GroupID, GroupGeneration, FailRealm, FailDomain, VDisk);
+ auto ConvertToTuple() const {
+ return std::make_tuple(GroupID, GroupGeneration, FailRealm, FailDomain, VDisk);
}
- friend bool operator ==(const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() == y.ConvertToTuple(); }
- friend bool operator !=(const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() != y.ConvertToTuple(); }
- friend bool operator < (const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() < y.ConvertToTuple(); }
+ friend bool operator ==(const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() == y.ConvertToTuple(); }
+ friend bool operator !=(const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() != y.ConvertToTuple(); }
+ friend bool operator < (const TVDiskID& x, const TVDiskID& y) { return x.ConvertToTuple() < y.ConvertToTuple(); }
TString ToString() const;
TString ToStringWOGeneration() const;
@@ -68,7 +68,7 @@ struct TVDiskID {
bool Deserialize(IInputStream &s);
ui64 Hash() const {
- ui32 x = (((ui32(FailRealm) << 8) | ui32(FailDomain)) << 8) | ui32(VDisk);
+ ui32 x = (((ui32(FailRealm) << 8) | ui32(FailDomain)) << 8) | ui32(VDisk);
ui64 y = GroupID;
y = y << 32ull;
y |= GroupGeneration;
@@ -92,7 +92,7 @@ struct TVDiskIdShort {
ui8 FailDomain = 0;
ui8 VDisk = 0;
ui8 Padding = 0;
-
+
TVDiskIdShort() = default;
explicit TVDiskIdShort(ui64 raw)
@@ -122,13 +122,13 @@ struct TVDiskIdShort {
FailDomain != x.FailDomain ? FailDomain < x.FailDomain :
VDisk != x.VDisk ? VDisk < x.VDisk : false;
}
-
+
bool operator==(const TVDiskIdShort &x) const {
return FailRealm == x.FailRealm &&
FailDomain == x.FailDomain &&
VDisk == x.VDisk;
}
-
+
bool operator!=(const TVDiskIdShort &x) const {
return !((*this)==x);
}
@@ -140,7 +140,7 @@ struct TVDiskIdShort {
str << " VDisk# " << (ui32)VDisk;
str << "}";
return str.Str();
- }
+ }
ui64 Hash() const {
ui32 x = (((ui32(FailRealm) << 8) | ui32(FailDomain)) << 8) | ui32(VDisk);
diff --git a/ydb/core/blobstorage/base/bufferwithgaps.h b/ydb/core/blobstorage/base/bufferwithgaps.h
index 28fc2f78ed9..7e5d7f6b7ad 100644
--- a/ydb/core/blobstorage/base/bufferwithgaps.h
+++ b/ydb/core/blobstorage/base/bufferwithgaps.h
@@ -1,41 +1,41 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <util/generic/string.h>
#include <util/generic/set.h>
#include <util/generic/map.h>
-#include <util/generic/vector.h>
-#include <util/generic/algorithm.h>
-
-namespace NKikimr {
-
- /* Buffer with gaps allows user to manipulate data obtained from Yard which can be partially unavailable.
- * Originally problem arises from cases when user reads data that was not yet written to disk. Consider
- * chunk with three blocks: block-0, block-1, block-2. User writes block-0, then block-2, while block-1 remains
- * untouched. Then, user reads data from block-0 and block-2. Request batcher contatenates those requests with
- * block-1 and reads all three blocks. But data in block-1 is invalid and cannot be read, so it contains a gap
- * marker at that place. Another case is when some part of data is corrupt and cannot be restored. In this case
- * vdisk receives gap marker and have to decide what to do -- crash, mark blob as corrupt and try to restore it
- * through replication, or do something else. */
-
- class TBufferWithGaps {
+#include <util/generic/vector.h>
+#include <util/generic/algorithm.h>
+
+namespace NKikimr {
+
+ /* Buffer with gaps allows user to manipulate data obtained from Yard which can be partially unavailable.
+ * Originally problem arises from cases when user reads data that was not yet written to disk. Consider
+ * chunk with three blocks: block-0, block-1, block-2. User writes block-0, then block-2, while block-1 remains
+ * untouched. Then, user reads data from block-0 and block-2. Request batcher contatenates those requests with
+ * block-1 and reads all three blocks. But data in block-1 is invalid and cannot be read, so it contains a gap
+ * marker at that place. Another case is when some part of data is corrupt and cannot be restored. In this case
+ * vdisk receives gap marker and have to decide what to do -- crash, mark blob as corrupt and try to restore it
+ * through replication, or do something else. */
+
+ class TBufferWithGaps {
TString Data;
// <begin, size>
TMap<ui32, ui32> Gaps;
- ui32 Offset; // Data's offset in Gaps space
+ ui32 Offset; // Data's offset in Gaps space
bool IsCommited;
-
- public:
- TBufferWithGaps()
- : Offset(0)
+
+ public:
+ TBufferWithGaps()
+ : Offset(0)
, IsCommited(false)
- {}
-
- TBufferWithGaps(ui32 offset)
- : Offset(offset)
+ {}
+
+ TBufferWithGaps(ui32 offset)
+ : Offset(offset)
, IsCommited(false)
- {}
-
+ {}
+
TBufferWithGaps(ui32 offset, ui32 size)
: Data(TString::Uninitialized(size))
, Offset(offset)
@@ -45,7 +45,7 @@ namespace NKikimr {
TBufferWithGaps(TBufferWithGaps &&) = default;
TBufferWithGaps &operator=(TBufferWithGaps &&) = default;
- void AddGap(ui32 begin, ui32 end) {
+ void AddGap(ui32 begin, ui32 end) {
// ensure gaps never overlap
ui32 size = end - begin;
auto f = Gaps.upper_bound(begin);
@@ -55,34 +55,34 @@ namespace NKikimr {
prev->second += size;
return;
}
- }
+ }
// add new gap
Gaps.emplace(begin, size);
- }
-
+ }
+
void SetData(TString&& data) {
- Data = std::move(data);
+ Data = std::move(data);
IsCommited = true;
- }
-
+ }
+
TString ToString() const {
Y_VERIFY(IsReadable(), "returned data is corrupt (or was never written) and therefore could not be used safely");
- return Data;
- }
-
+ return Data;
+ }
+
TString Substr(ui32 offset, ui32 len) const {
Y_VERIFY(IsReadable(offset, len), "returned data is corrupt (or was never written) at offset# %" PRIu32
- " len# %" PRIu32 " and therefore could not be used safely", offset, len);
- return Data.substr(offset, len);
- }
-
- template<typename T>
- const T *DataPtr(ui32 offset, ui32 len = sizeof(T)) const {
+ " len# %" PRIu32 " and therefore could not be used safely", offset, len);
+ return Data.substr(offset, len);
+ }
+
+ template<typename T>
+ const T *DataPtr(ui32 offset, ui32 len = sizeof(T)) const {
Y_VERIFY(IsReadable(offset, len), "returned data is corrupt (or was never written) at offset# %" PRIu32
- " len# %" PRIu32 " and therefore could not be used safely", offset, len);
+ " len# %" PRIu32 " and therefore could not be used safely", offset, len);
return reinterpret_cast<T *>(Data.data() + offset);
- }
-
+ }
+
ui8 *RawDataPtr(ui32 offset, ui32 len) {
Y_VERIFY(offset + len <= Data.size(), "Buffer has size# %zu less then requested offset# %" PRIu32
" len# %" PRIu32, Data.size(), offset, len);
@@ -94,19 +94,19 @@ namespace NKikimr {
IsCommited = true;
}
- bool IsReadable() const {
+ bool IsReadable() const {
Y_VERIFY(IsCommited, "returned data was not commited");
- return Gaps.empty();
- }
-
- bool IsReadable(ui32 offset, ui32 len) const {
+ return Gaps.empty();
+ }
+
+ bool IsReadable(ui32 offset, ui32 len) const {
Y_VERIFY(IsCommited, "returned data was not commited");
- if (offset + len > Data.size()) {
- return false;
- }
- const ui32 begin = Offset + offset;
- const ui32 end = begin + len;
-
+ if (offset + len > Data.size()) {
+ return false;
+ }
+ const ui32 begin = Offset + offset;
+ const ui32 end = begin + len;
+
auto f = Gaps.upper_bound(begin);
if (Gaps.empty()) {
return true;
@@ -125,33 +125,33 @@ namespace NKikimr {
auto prev = std::prev(f);
return prev->first + prev->second <= begin && (f == Gaps.end() || end <= f->first);
}
- }
-
- ui32 Size() const {
+ }
+
+ ui32 Size() const {
return Data.size();
- }
-
- void Swap(TBufferWithGaps& other) {
- Data.swap(other.Data);
- Gaps.swap(other.Gaps);
- DoSwap(Offset, other.Offset);
+ }
+
+ void Swap(TBufferWithGaps& other) {
+ Data.swap(other.Data);
+ Gaps.swap(other.Gaps);
+ DoSwap(Offset, other.Offset);
DoSwap(IsCommited, other.IsCommited);
- }
-
- void Clear() {
- Data.clear();
- Gaps.clear();
+ }
+
+ void Clear() {
+ Data.clear();
+ Gaps.clear();
Offset = 0;
IsCommited = false;
- }
-
+ }
+
bool IsDetached() const {
return Data.IsDetached();
}
- bool Empty() const {
- return Data.empty();
- }
+ bool Empty() const {
+ return Data.empty();
+ }
void Sanitize() const {
if (Data.size()) {
@@ -173,6 +173,6 @@ namespace NKikimr {
}
}
}
- };
-
-} // NKikimr
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/base/bufferwithgaps_ut.cpp b/ydb/core/blobstorage/base/bufferwithgaps_ut.cpp
index 71e1e1a5eb3..fc90bf22e35 100644
--- a/ydb/core/blobstorage/base/bufferwithgaps_ut.cpp
+++ b/ydb/core/blobstorage/base/bufferwithgaps_ut.cpp
@@ -1,43 +1,43 @@
-#include "bufferwithgaps.h"
+#include "bufferwithgaps.h"
#include <library/cpp/testing/unittest/registar.h>
-
-using NKikimr::TBufferWithGaps;
-
+
+using NKikimr::TBufferWithGaps;
+
Y_UNIT_TEST_SUITE(BufferWithGaps) {
-
+
Y_UNIT_TEST(Basic) {
- TBufferWithGaps buffer(0);
+ TBufferWithGaps buffer(0);
TString data = "Hello!";
buffer.SetData(TString(data));
- UNIT_ASSERT_STRINGS_EQUAL(data, buffer.Substr(0, buffer.Size()));
- }
-
+ UNIT_ASSERT_STRINGS_EQUAL(data, buffer.Substr(0, buffer.Size()));
+ }
+
Y_UNIT_TEST(IsReadable) {
- TBufferWithGaps buffer(0);
+ TBufferWithGaps buffer(0);
TString data = "Hello! How are you? I'm fine, and you? Me too, thanks!";
TString gaps = "G GGGG GG GGG G G";
buffer.SetData(TString(data));
for (size_t k = 0; k < gaps.size(); ++k) {
- if (gaps[k] != ' ') {
- buffer.AddGap(k, k + 1);
- }
- }
+ if (gaps[k] != ' ') {
+ buffer.AddGap(k, k + 1);
+ }
+ }
UNIT_ASSERT_EQUAL(buffer.Size(), data.size());
- for (size_t k = 0; k < buffer.Size(); ++k) {
- for (size_t len = 1; len <= buffer.Size() - k; ++len) {
- bool haveGaps = false;
- for (size_t i = k; i < k + len; ++i) {
- if (gaps[i] != ' ') {
- haveGaps = true;
- break;
- }
- }
- UNIT_ASSERT_EQUAL(!haveGaps, buffer.IsReadable(k, len));
- if (!haveGaps) {
- UNIT_ASSERT_STRINGS_EQUAL(buffer.Substr(k, len), data.substr(k, len));
- }
- }
- }
- }
-
-}
+ for (size_t k = 0; k < buffer.Size(); ++k) {
+ for (size_t len = 1; len <= buffer.Size() - k; ++len) {
+ bool haveGaps = false;
+ for (size_t i = k; i < k + len; ++i) {
+ if (gaps[i] != ' ') {
+ haveGaps = true;
+ break;
+ }
+ }
+ UNIT_ASSERT_EQUAL(!haveGaps, buffer.IsReadable(k, len));
+ if (!haveGaps) {
+ UNIT_ASSERT_STRINGS_EQUAL(buffer.Substr(k, len), data.substr(k, len));
+ }
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/base/ptr.h b/ydb/core/blobstorage/base/ptr.h
index ceb701c9f9f..bbb162e0e6f 100644
--- a/ydb/core/blobstorage/base/ptr.h
+++ b/ydb/core/blobstorage/base/ptr.h
@@ -40,7 +40,7 @@ namespace NKikimr {
TAtomicBase resultCount = Counter_.Sub(d);
Y_ASSERT(resultCount >= 0);
if (resultCount == 0) {
- Deleter_.Destroy(std::unique_ptr<T>(static_cast<T*>(this)));
+ Deleter_.Destroy(std::unique_ptr<T>(static_cast<T*>(this)));
}
}
@@ -87,22 +87,22 @@ namespace NKikimr {
friend class TActorBootstrapped<TThis>;
void Bootstrap(const TActorContext &ctx) {
- Obj.reset();
+ Obj.reset();
TThis::Die(ctx);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
}
- TObjDeleterActor(std::unique_ptr<T> obj)
+ TObjDeleterActor(std::unique_ptr<T> obj)
: TActorBootstrapped<TThis>()
- , Obj(std::move(obj))
+ , Obj(std::move(obj))
{}
private:
- std::unique_ptr<T> Obj;
+ std::unique_ptr<T> Obj;
};
////////////////////////////////////////////////////////////////////////////
@@ -115,12 +115,12 @@ namespace NKikimr {
{}
template <class T>
- inline void Destroy(std::unique_ptr<T> t) noexcept {
+ inline void Destroy(std::unique_ptr<T> t) noexcept {
AssertTypeComplete<T>();
if (ActorSystem) {
ui32 poolId = ActorSystem->AppData<::NKikimr::TAppData>()->BatchPoolId;
- ActorSystem->Register(new TObjDeleterActor<T>(std::move(t)), TMailboxType::HTSwap, poolId);
+ ActorSystem->Register(new TObjDeleterActor<T>(std::move(t)), TMailboxType::HTSwap, poolId);
}
}
diff --git a/ydb/core/blobstorage/base/ptr_ut.cpp b/ydb/core/blobstorage/base/ptr_ut.cpp
index 5554167ab26..d098c3f10a1 100644
--- a/ydb/core/blobstorage/base/ptr_ut.cpp
+++ b/ydb/core/blobstorage/base/ptr_ut.cpp
@@ -18,9 +18,9 @@ Y_UNIT_TEST_SUITE(PtrTest) {
}
template <class T>
- inline void Destroy(std::unique_ptr<T> t) noexcept {
+ inline void Destroy(std::unique_ptr<T> t) noexcept {
++(*Num);
- CheckedDelete<T>(t.release());
+ CheckedDelete<T>(t.release());
}
ui64 GetNum() const {
diff --git a/ydb/core/blobstorage/base/transparent.h b/ydb/core/blobstorage/base/transparent.h
index 2590ec7d9cf..5ba3e36778a 100644
--- a/ydb/core/blobstorage/base/transparent.h
+++ b/ydb/core/blobstorage/base/transparent.h
@@ -9,7 +9,7 @@
#include <ydb/core/blobstorage/vdisk/common/memusage.h>
#include <ydb/core/blobstorage/base/ptr.h>
-
+
namespace NKikimr {
/////////////////////////////////////////////////////////////////////////////////////////
@@ -18,7 +18,7 @@ namespace NKikimr {
class TTransparentMemoryPool {
public:
TTransparentMemoryPool(TMemoryConsumer&& consumer, size_t initial, TMemoryPool::IGrowPolicy* growPolicy)
- : Consumer(std::move(consumer))
+ : Consumer(std::move(consumer))
, MemoryPool(initial, growPolicy)
, TotalAllocated(0)
{}
@@ -34,18 +34,18 @@ namespace NKikimr {
void* Allocate(size_t len) noexcept {
i64 l = static_cast<i64>(len);
- Consumer.Add(l);
+ Consumer.Add(l);
TotalAllocated += l;
return MemoryPool.Allocate(len);
}
protected:
- TMemoryConsumer Consumer;
+ TMemoryConsumer Consumer;
TMemoryPool MemoryPool;
i64 TotalAllocated;
void TrackingFree() {
- Consumer.Subtract(TotalAllocated);
+ Consumer.Subtract(TotalAllocated);
TotalAllocated = 0;
}
};
diff --git a/ydb/core/blobstorage/base/utility.h b/ydb/core/blobstorage/base/utility.h
index afb519dcb86..eab726baaa6 100644
--- a/ydb/core/blobstorage/base/utility.h
+++ b/ydb/core/blobstorage/base/utility.h
@@ -1,12 +1,12 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <library/cpp/actors/helpers/activeactors.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/blobstorage.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
inline TString ToStringLocalTimeUpToSeconds(const TInstant &time) {
return time.GetValue() ? time.ToStringLocalUpToSeconds() : "0";
}
@@ -15,42 +15,42 @@ namespace NKikimr {
// RunInBatchPool
////////////////////////////////////////////////////////////////////////////
inline TActorId RunInBatchPool(const TActorContext &ctx, IActor *actor) {
- ui32 poolId = AppData(ctx)->BatchPoolId;
+ ui32 poolId = AppData(ctx)->BatchPoolId;
TActorId actorID = ctx.Register(actor, TMailboxType::HTSwap, poolId);
- return actorID;
- }
-
- template<typename T, typename A>
+ return actorID;
+ }
+
+ template<typename T, typename A>
inline void AppendToVector(TVector<T, A>& to, TVector<T, A>&& from) {
- if (to) {
- to.insert(to.end(), from.begin(), from.end());
- } else {
- to.swap(from);
- }
- }
-
- template<typename T, typename A>
+ if (to) {
+ to.insert(to.end(), from.begin(), from.end());
+ } else {
+ to.swap(from);
+ }
+ }
+
+ template<typename T, typename A>
inline void AppendToVector(TVector<T, A>& to, const TVector<T, A>& from) {
- to.insert(to.end(), from.begin(), from.end());
- }
+ to.insert(to.end(), from.begin(), from.end());
+ }
+
-
- template<typename TContainer>
+ template<typename TContainer>
inline TString FormatList(const TContainer& cont) {
- TStringStream str;
- str << "[";
- bool first = true;
- for (const auto& item : cont) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- str << item;
- }
- str << "]";
- return str.Str();
- }
+ TStringStream str;
+ str << "[";
+ bool first = true;
+ for (const auto& item : cont) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ str << item;
+ }
+ str << "]";
+ return str.Str();
+ }
template<typename TContainer>
inline void FormatList(IOutputStream &str, const TContainer& cont) {
@@ -147,5 +147,5 @@ namespace NKikimr {
TActorId NotifyId;
};
-} // NKikimr
+} // NKikimr
diff --git a/ydb/core/blobstorage/base/vdisk_sync_common.h b/ydb/core/blobstorage/base/vdisk_sync_common.h
index 9e0d2cf21de..be20de8eec0 100644
--- a/ydb/core/blobstorage/base/vdisk_sync_common.h
+++ b/ydb/core/blobstorage/base/vdisk_sync_common.h
@@ -8,6 +8,6 @@ namespace NKikimr {
// dictionary used to determine BS_QUEUE actor id for a specific VDisk inside group
// (identified by stable TVDiskIdShort)
using TQueueActorMap = THashMap<TVDiskIdShort, TActorId>;
- using TQueueActorMapPtr = std::shared_ptr<TQueueActorMap>;
+ using TQueueActorMapPtr = std::shared_ptr<TQueueActorMap>;
} // NKikimr
diff --git a/ydb/core/blobstorage/base/wilson_events.h b/ydb/core/blobstorage/base/wilson_events.h
index 7ed95284632..07315fe63e6 100644
--- a/ydb/core/blobstorage/base/wilson_events.h
+++ b/ydb/core/blobstorage/base/wilson_events.h
@@ -1,112 +1,112 @@
-#pragma once
-
-
+#pragma once
+
+
#include "blobstorage_vdiskid.h"
#include <ydb/library/wilson/wilson_event.h>
-
-#define WILSON_TRACE_FROM_ACTOR(CTX, ACTOR, TRACE_ID, EVENT_TYPE, ...) \
- WILSON_TRACE(CTX, TRACE_ID, EVENT_TYPE, \
- ActivityType = static_cast<NKikimrServices::TActivity::EType>((ACTOR).GetActivityType()), \
- ActorId = (ACTOR).SelfId(), \
- ##__VA_ARGS__);
-
-#define DECLARE_ACTOR_EVENT(EVENT_TYPE, ...) \
- DECLARE_WILSON_EVENT(EVENT_TYPE, \
- (::NKikimrServices::TActivity::EType, ActivityType), \
+
+#define WILSON_TRACE_FROM_ACTOR(CTX, ACTOR, TRACE_ID, EVENT_TYPE, ...) \
+ WILSON_TRACE(CTX, TRACE_ID, EVENT_TYPE, \
+ ActivityType = static_cast<NKikimrServices::TActivity::EType>((ACTOR).GetActivityType()), \
+ ActorId = (ACTOR).SelfId(), \
+ ##__VA_ARGS__);
+
+#define DECLARE_ACTOR_EVENT(EVENT_TYPE, ...) \
+ DECLARE_WILSON_EVENT(EVENT_TYPE, \
+ (::NKikimrServices::TActivity::EType, ActivityType), \
(::NActors::TActorId, ActorId), \
- ##__VA_ARGS__ \
- )
-
-namespace NKikimr {
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // DSPROXY
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_ACTOR_EVENT(MultiGetReceived);
- DECLARE_ACTOR_EVENT(EvGetSent);
- DECLARE_ACTOR_EVENT(EvGetReceived);
- DECLARE_ACTOR_EVENT(EvVGetSent);
- DECLARE_ACTOR_EVENT(EvVGetReceived);
- DECLARE_ACTOR_EVENT(EvVGetResultSent);
- DECLARE_ACTOR_EVENT(EvVGetResultReceived, (::NWilson::TTraceId, MergedNode));
- DECLARE_ACTOR_EVENT(EvGetResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus), (ui32, ResponseSize));
- DECLARE_ACTOR_EVENT(EvGetResultReceived, (::NWilson::TTraceId, MergedNode));
- DECLARE_ACTOR_EVENT(MultiGetResultSent);
-
- DECLARE_ACTOR_EVENT(RangeGetReceived);
- DECLARE_ACTOR_EVENT(RangeGetResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus), (ui32, ResponseSize));
-
- DECLARE_ACTOR_EVENT(EvPutReceived, (ui32, Size), (TLogoBlobID, LogoBlobId));
- DECLARE_ACTOR_EVENT(EvVPutSent);
- DECLARE_ACTOR_EVENT(EvVPutResultReceived, (::NWilson::TTraceId, MergedNode));
- DECLARE_ACTOR_EVENT(EvPutResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus));
-
- DECLARE_ACTOR_EVENT(EvDiscoverReceived, (ui32, GroupId), (TLogoBlobID, From), (TLogoBlobID, To));
- DECLARE_ACTOR_EVENT(EvDiscoverResultSent);
-
- DECLARE_ACTOR_EVENT(EvVGetBlockSent);
- DECLARE_ACTOR_EVENT(EvVGetBlockResultReceived, (::NWilson::TTraceId, MergedNode));
-
- DECLARE_ACTOR_EVENT(ReadBatcherStart);
- DECLARE_ACTOR_EVENT(ReadBatcherFinish, (::NWilson::TTraceId, MergedNode));
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDISK
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_ACTOR_EVENT(EvVPutReceived, (TVDiskID, VDiskId), (ui32, PDiskId), (ui32, VDiskSlotId));
- DECLARE_ACTOR_EVENT(EvPutIntoEmergQueue);
- DECLARE_ACTOR_EVENT(EvVPutResultSent);
+ ##__VA_ARGS__ \
+ )
+
+namespace NKikimr {
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DSPROXY
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_ACTOR_EVENT(MultiGetReceived);
+ DECLARE_ACTOR_EVENT(EvGetSent);
+ DECLARE_ACTOR_EVENT(EvGetReceived);
+ DECLARE_ACTOR_EVENT(EvVGetSent);
+ DECLARE_ACTOR_EVENT(EvVGetReceived);
+ DECLARE_ACTOR_EVENT(EvVGetResultSent);
+ DECLARE_ACTOR_EVENT(EvVGetResultReceived, (::NWilson::TTraceId, MergedNode));
+ DECLARE_ACTOR_EVENT(EvGetResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus), (ui32, ResponseSize));
+ DECLARE_ACTOR_EVENT(EvGetResultReceived, (::NWilson::TTraceId, MergedNode));
+ DECLARE_ACTOR_EVENT(MultiGetResultSent);
+
+ DECLARE_ACTOR_EVENT(RangeGetReceived);
+ DECLARE_ACTOR_EVENT(RangeGetResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus), (ui32, ResponseSize));
+
+ DECLARE_ACTOR_EVENT(EvPutReceived, (ui32, Size), (TLogoBlobID, LogoBlobId));
+ DECLARE_ACTOR_EVENT(EvVPutSent);
+ DECLARE_ACTOR_EVENT(EvVPutResultReceived, (::NWilson::TTraceId, MergedNode));
+ DECLARE_ACTOR_EVENT(EvPutResultSent, (::NKikimrProto::EReplyStatus, ReplyStatus));
+
+ DECLARE_ACTOR_EVENT(EvDiscoverReceived, (ui32, GroupId), (TLogoBlobID, From), (TLogoBlobID, To));
+ DECLARE_ACTOR_EVENT(EvDiscoverResultSent);
+
+ DECLARE_ACTOR_EVENT(EvVGetBlockSent);
+ DECLARE_ACTOR_EVENT(EvVGetBlockResultReceived, (::NWilson::TTraceId, MergedNode));
+
+ DECLARE_ACTOR_EVENT(ReadBatcherStart);
+ DECLARE_ACTOR_EVENT(ReadBatcherFinish, (::NWilson::TTraceId, MergedNode));
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDISK
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_ACTOR_EVENT(EvVPutReceived, (TVDiskID, VDiskId), (ui32, PDiskId), (ui32, VDiskSlotId));
+ DECLARE_ACTOR_EVENT(EvPutIntoEmergQueue);
+ DECLARE_ACTOR_EVENT(EvVPutResultSent);
DECLARE_ACTOR_EVENT(EvVMultiPutResultSent);
-
- DECLARE_ACTOR_EVENT(EvChunkReadSent, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size), (void*, YardCookie));
-
- DECLARE_ACTOR_EVENT(EvChunkReadResultReceived, (void*, YardCookie), (::NWilson::TTraceId, MergedNode));
-
- DECLARE_ACTOR_EVENT(EvHullWriteHugeBlobSent);
- DECLARE_ACTOR_EVENT(EvHullLogHugeBlobReceived);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // BS_QUEUE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_ACTOR_EVENT(EvBlobStorageQueuePut, (ui64, InQueueWaitingItems), (ui64, InQueueWaitingBytes));
- DECLARE_ACTOR_EVENT(EvBlobStorageQueueForward, (ui64, InQueueWaitingItems), (ui64, InQueueWaitingBytes));
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // SKELETON FRONT
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_ACTOR_EVENT(EvSkeletonFrontEnqueue);
- DECLARE_ACTOR_EVENT(EvSkeletonFrontProceed);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // YARD
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_WILSON_EVENT(EvChunkReadReceived, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size));
- DECLARE_WILSON_EVENT(AsyncReadScheduled, (ui64, DiskOffset), (ui32, Size));
-
- DECLARE_WILSON_EVENT(EvChunkWriteReceived, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size));
-
- DECLARE_WILSON_EVENT(EvLogReceived);
- DECLARE_WILSON_EVENT(EnqueueLogWrite);
- DECLARE_WILSON_EVENT(RouteLogWrite);
-
- DECLARE_WILSON_EVENT(BlockPwrite, (ui64, DiskOffset), (ui32, Size));
- DECLARE_WILSON_EVENT(BlockPread, (ui64, DiskOffset), (ui32, Size));
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // LIBAIO
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- DECLARE_WILSON_EVENT(AsyncIoInQueue);
- DECLARE_WILSON_EVENT(AsyncIoFinished);
-
-} // NKikimr
-
-template<>
-inline void Out<NKikimrServices::TActivity::EType>(IOutputStream& os, NKikimrServices::TActivity::EType status) {
- os << NKikimrServices::TActivity::EType_Name(status);
-}
+
+ DECLARE_ACTOR_EVENT(EvChunkReadSent, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size), (void*, YardCookie));
+
+ DECLARE_ACTOR_EVENT(EvChunkReadResultReceived, (void*, YardCookie), (::NWilson::TTraceId, MergedNode));
+
+ DECLARE_ACTOR_EVENT(EvHullWriteHugeBlobSent);
+ DECLARE_ACTOR_EVENT(EvHullLogHugeBlobReceived);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BS_QUEUE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_ACTOR_EVENT(EvBlobStorageQueuePut, (ui64, InQueueWaitingItems), (ui64, InQueueWaitingBytes));
+ DECLARE_ACTOR_EVENT(EvBlobStorageQueueForward, (ui64, InQueueWaitingItems), (ui64, InQueueWaitingBytes));
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SKELETON FRONT
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_ACTOR_EVENT(EvSkeletonFrontEnqueue);
+ DECLARE_ACTOR_EVENT(EvSkeletonFrontProceed);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // YARD
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_WILSON_EVENT(EvChunkReadReceived, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size));
+ DECLARE_WILSON_EVENT(AsyncReadScheduled, (ui64, DiskOffset), (ui32, Size));
+
+ DECLARE_WILSON_EVENT(EvChunkWriteReceived, (ui32, ChunkIdx), (ui32, Offset), (ui32, Size));
+
+ DECLARE_WILSON_EVENT(EvLogReceived);
+ DECLARE_WILSON_EVENT(EnqueueLogWrite);
+ DECLARE_WILSON_EVENT(RouteLogWrite);
+
+ DECLARE_WILSON_EVENT(BlockPwrite, (ui64, DiskOffset), (ui32, Size));
+ DECLARE_WILSON_EVENT(BlockPread, (ui64, DiskOffset), (ui32, Size));
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LIBAIO
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ DECLARE_WILSON_EVENT(AsyncIoInQueue);
+ DECLARE_WILSON_EVENT(AsyncIoFinished);
+
+} // NKikimr
+
+template<>
+inline void Out<NKikimrServices::TActivity::EType>(IOutputStream& os, NKikimrServices::TActivity::EType status) {
+ os << NKikimrServices::TActivity::EType_Name(status);
+}
diff --git a/ydb/core/blobstorage/crypto/crypto.cpp b/ydb/core/blobstorage/crypto/crypto.cpp
index 0d91e891644..6ad7ab1a38c 100644
--- a/ydb/core/blobstorage/crypto/crypto.cpp
+++ b/ydb/core/blobstorage/crypto/crypto.cpp
@@ -76,7 +76,7 @@ TCypherKey::~TCypherKey() {
////////////////////////////////////////////////////////////////////////////
THashCalculator::THashCalculator() {
- Poly = std::make_unique<Poly1305Vec>();
+ Poly = std::make_unique<Poly1305Vec>();
Clear();
}
@@ -170,7 +170,7 @@ TStreamCypher::TStreamCypher()
{
#if ENABLE_ENCRYPTION
memset(Key, 0, sizeof(Key));
- Cypher.reset(new ChaChaVec(CYPHER_ROUNDS));
+ Cypher.reset(new ChaChaVec(CYPHER_ROUNDS));
#else
Y_UNUSED(Leftover);
Y_UNUSED(Key);
diff --git a/ydb/core/blobstorage/crypto/crypto.h b/ydb/core/blobstorage/crypto/crypto.h
index 45fb647ba43..8d057a858aa 100644
--- a/ydb/core/blobstorage/crypto/crypto.h
+++ b/ydb/core/blobstorage/crypto/crypto.h
@@ -36,10 +36,10 @@ public:
void MutableKeyBytes(ui8** outKey, ui32 *outSizeBytes);
void Wipe();
~TCypherKey();
-
- friend bool operator ==(const TCypherKey& x, const TCypherKey& y) {
- return x.IsKeySet == y.IsKeySet && !memcmp(x.Key8, y.Key8, sizeof(x.Key8));
- }
+
+ friend bool operator ==(const TCypherKey& x, const TCypherKey& y) {
+ return x.IsKeySet == y.IsKeySet && !memcmp(x.Key8, y.Key8, sizeof(x.Key8));
+ }
};
////////////////////////////////////////////////////////////////////////////
@@ -51,7 +51,7 @@ class THashCalculator {
ui64 HashResult[2];
ui8 HashBytes[16];
};
- std::unique_ptr<Poly1305Vec> Poly;
+ std::unique_ptr<Poly1305Vec> Poly;
alignas(16) ui8 Key[32] = {'p', 'o', 'l', 'y', '1', '3', '0', '5', 'V', 'e', 'c', 'K', 'e', 'y', '1',
'D', 'u', 'm', 'm', 'y', 'C', 'o', 'n', 's', 't', 'a', 'n', 't', 'V', 'a'};
public:
@@ -96,7 +96,7 @@ class TStreamCypher {
alignas(16) ui8 Leftover[64 * 4];
alignas(16) ui64 Key[4];
alignas(16) i64 Nonce;
- std::unique_ptr<ChaChaVec> Cypher;
+ std::unique_ptr<ChaChaVec> Cypher;
ui32 UnusedBytes;
public:
TStreamCypher();
diff --git a/ydb/core/blobstorage/dsproxy/defs.h b/ydb/core/blobstorage/dsproxy/defs.h
index f2c837b4d66..20a8138043f 100644
--- a/ydb/core/blobstorage/dsproxy/defs.h
+++ b/ydb/core/blobstorage/dsproxy/defs.h
@@ -1,7 +1,7 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/defs.h>
-
+
#include <ydb/core/base/counters.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
@@ -11,14 +11,14 @@
#include <ydb/core/blobstorage/crypto/crypto.h>
#include <ydb/core/blobstorage/nodewarden/group_stat_aggregator.h>
#include <ydb/core/util/log_priority_mute_checker.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <library/cpp/digest/crc32c/crc32c.h>
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+#include <library/cpp/digest/crc32c/crc32c.h>
#include <ydb/core/base/interconnect_channels.h>
-#include <util/generic/deque.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/map.h>
-#include <util/string/escape.h>
-#include <library/cpp/monlib/service/pages/templates.h>
+#include <util/generic/deque.h>
+#include <util/generic/hash_set.h>
+#include <util/generic/map.h>
+#include <util/string/escape.h>
+#include <library/cpp/monlib/service/pages/templates.h>
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy.h b/ydb/core/blobstorage/dsproxy/dsproxy.h
index 27592e971f9..586568401a4 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy.h
@@ -1,11 +1,11 @@
#pragma once
-
+
#include "defs.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_responsiveness.h"
-#include "log_acc.h"
-#include "group_sessions.h"
-
+#include "dsproxy_mon.h"
+#include "dsproxy_responsiveness.h"
+#include "log_acc.h"
+#include "group_sessions.h"
+
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/storagepoolmon/storagepool_counters.h>
@@ -43,9 +43,9 @@ const ui64 BufferSizeThreshold = 1 << 20;
const bool IsHandoffAccelerationEnabled = false;
-const bool IsEarlyRequestAbortEnabled = false;
+const bool IsEarlyRequestAbortEnabled = false;
const bool IngressAsAReasonForErrorEnabled = false;
-
+
const ui32 BeginRequestSize = 10;
const ui32 MaxRequestSize = 1000;
@@ -62,44 +62,44 @@ constexpr bool WithMovingPatchRequestToStaticNode = true;
struct TEvDeathNote : public TEventLocal<TEvDeathNote, TEvBlobStorage::EvDeathNote> {
- TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> Responsiveness;
-
- TEvDeathNote(const TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> &responsiveness)
- : Responsiveness(responsiveness)
- {}
-};
-
-struct TEvAbortOperation : public TEventLocal<TEvAbortOperation, TEvBlobStorage::EvAbortOperation>
-{};
-
-struct TEvLatencyReport : public TEventLocal<TEvLatencyReport, TEvBlobStorage::EvLatencyReport> {
- TGroupStat::EKind Kind;
- TDuration Sample;
-
- TEvLatencyReport(TGroupStat::EKind kind, TDuration sample)
- : Kind(kind)
- , Sample(sample)
- {}
-};
-
-struct TNodeLayoutInfo : TThrRefBase {
- // indexed by NodeId
- TNodeLocation SelfLocation;
- TVector<TNodeLocation> LocationPerOrderNumber;
-
- TNodeLayoutInfo(const TNodeLocation& selfLocation, const TIntrusivePtr<TBlobStorageGroupInfo>& info,
- std::unordered_map<ui32, TNodeLocation>& map)
- : SelfLocation(selfLocation)
- , LocationPerOrderNumber(info->GetTotalVDisksNum())
- {
- for (ui32 i = 0; i < LocationPerOrderNumber.size(); ++i) {
- LocationPerOrderNumber[i] = map[info->GetActorId(i).NodeId()];
- }
- }
+ TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> Responsiveness;
+
+ TEvDeathNote(const TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> &responsiveness)
+ : Responsiveness(responsiveness)
+ {}
};
-using TNodeLayoutInfoPtr = TIntrusivePtr<TNodeLayoutInfo>;
-
+struct TEvAbortOperation : public TEventLocal<TEvAbortOperation, TEvBlobStorage::EvAbortOperation>
+{};
+
+struct TEvLatencyReport : public TEventLocal<TEvLatencyReport, TEvBlobStorage::EvLatencyReport> {
+ TGroupStat::EKind Kind;
+ TDuration Sample;
+
+ TEvLatencyReport(TGroupStat::EKind kind, TDuration sample)
+ : Kind(kind)
+ , Sample(sample)
+ {}
+};
+
+struct TNodeLayoutInfo : TThrRefBase {
+ // indexed by NodeId
+ TNodeLocation SelfLocation;
+ TVector<TNodeLocation> LocationPerOrderNumber;
+
+ TNodeLayoutInfo(const TNodeLocation& selfLocation, const TIntrusivePtr<TBlobStorageGroupInfo>& info,
+ std::unordered_map<ui32, TNodeLocation>& map)
+ : SelfLocation(selfLocation)
+ , LocationPerOrderNumber(info->GetTotalVDisksNum())
+ {
+ for (ui32 i = 0; i < LocationPerOrderNumber.size(); ++i) {
+ LocationPerOrderNumber[i] = map[info->GetActorId(i).NodeId()];
+ }
+ }
+};
+
+using TNodeLayoutInfoPtr = TIntrusivePtr<TNodeLayoutInfo>;
+
inline TStoragePoolCounters::EHandleClass HandleClassToHandleClass(NKikimrBlobStorage::EGetHandleClass handleClass) {
switch (handleClass) {
case NKikimrBlobStorage::FastRead:
@@ -126,254 +126,254 @@ inline TStoragePoolCounters::EHandleClass HandleClassToHandleClass(NKikimrBlobSt
return TStoragePoolCounters::EHandleClass::HcCount;
}
-NActors::NLog::EPriority PriorityForStatusOutbound(NKikimrProto::EReplyStatus status);
-NActors::NLog::EPriority PriorityForStatusResult(NKikimrProto::EReplyStatus status);
-NActors::NLog::EPriority PriorityForStatusInbound(NKikimrProto::EReplyStatus status);
-
-template<typename TDerived>
-class TBlobStorageGroupRequestActor : public TActorBootstrapped<TDerived> {
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_REQUEST;
+NActors::NLog::EPriority PriorityForStatusOutbound(NKikimrProto::EReplyStatus status);
+NActors::NLog::EPriority PriorityForStatusResult(NKikimrProto::EReplyStatus status);
+NActors::NLog::EPriority PriorityForStatusInbound(NKikimrProto::EReplyStatus status);
+
+template<typename TDerived>
+class TBlobStorageGroupRequestActor : public TActorBootstrapped<TDerived> {
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_REQUEST;
}
- TBlobStorageGroupRequestActor(TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TGroupQueues> groupQueues,
+ TBlobStorageGroupRequestActor(TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TGroupQueues> groupQueues,
TIntrusivePtr<TBlobStorageGroupProxyMon> mon, const TActorId& source, ui64 cookie, NWilson::TTraceId traceId,
- NKikimrServices::EServiceKikimr logComponent, bool logAccEnabled, TMaybe<TGroupStat::EKind> latencyQueueKind,
- TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters, ui32 restartCounter)
- : Info(std::move(info))
- , GroupQueues(std::move(groupQueues))
- , Mon(std::move(mon))
+ NKikimrServices::EServiceKikimr logComponent, bool logAccEnabled, TMaybe<TGroupStat::EKind> latencyQueueKind,
+ TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters, ui32 restartCounter)
+ : Info(std::move(info))
+ , GroupQueues(std::move(groupQueues))
+ , Mon(std::move(mon))
, PoolCounters(storagePoolCounters)
- , LogCtx(logComponent, logAccEnabled)
- , TraceId(std::move(traceId))
- , RestartCounter(restartCounter)
- , Source(source)
- , Cookie(cookie)
- , LatencyQueueKind(latencyQueueKind)
- , RequestStartTime(now)
- , RacingDomains(&Info->GetTopology())
- {
- TDerived::ActiveCounter(Mon)->Inc();
- }
-
- template<typename T>
- void CountEvent(const T &ev) const {
- ERequestType request = TDerived::RequestType();
- Mon->CountEvent(request, ev);
- }
-
+ , LogCtx(logComponent, logAccEnabled)
+ , TraceId(std::move(traceId))
+ , RestartCounter(restartCounter)
+ , Source(source)
+ , Cookie(cookie)
+ , LatencyQueueKind(latencyQueueKind)
+ , RequestStartTime(now)
+ , RacingDomains(&Info->GetTopology())
+ {
+ TDerived::ActiveCounter(Mon)->Inc();
+ }
+
+ template<typename T>
+ void CountEvent(const T &ev) const {
+ ERequestType request = TDerived::RequestType();
+ Mon->CountEvent(request, ev);
+ }
+
TActorId GetVDiskActorId(const TVDiskIdShort &shortId) const {
return Info->GetActorId(shortId);
- }
-
- template<typename TEvent>
- bool CheckForTermErrors(TAutoPtr<TEventHandle<TEvent>>& ev) {
- auto& record = ev->Get()->Record;
- auto& self = Derived();
-
- if (!record.HasStatus()) {
- return false; // we do not consider messages with missing status/vdisk fields
- }
-
- NKikimrProto::EReplyStatus status = record.GetStatus(); // obtain status from the reply
-
- if (status == NKikimrProto::NOTREADY) { // special case from BS_QUEUE -- when connection is not yet established
- record.SetStatus(NKikimrProto::ERROR); // rewrite this status as error for processing
- PostponedQ.emplace_back(ev.Release());
- CheckPostponedQueue();
- return true; // event has been processed early
- }
-
- if (!record.HasVDiskID()) {
- return false; // bad reply?
- }
-
- auto done = [&](NKikimrProto::EReplyStatus status, const TString& message) {
- ErrorReason = message;
- A_LOG_LOG_S(true, PriorityForStatusResult(status), "DSP10", "Query failed " << message);
- self.ReplyAndDie(status);
- return true;
- };
-
- // sanity check for matching group id
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- if (vdiskId.GroupID != Info->GroupID) {
- return done(NKikimrProto::ERROR, TStringBuilder() << "incorrect VDiskId# " << vdiskId << " GroupId# "
- << Info->GroupID);
- }
-
- // sanity check for correct VDisk generation ??? possible race
- Y_VERIFY_S(status == NKikimrProto::RACE || vdiskId.GroupGeneration <= Info->GroupGeneration ||
- TEvent::EventType == TEvBlobStorage::EvVStatusResult,
- "status# " << NKikimrProto::EReplyStatus_Name(status) << " vdiskId.GroupGeneration# " << vdiskId.GroupGeneration
- << " Info->GroupGeneration# " << Info->GroupGeneration);
-
- if (status != NKikimrProto::RACE && status != NKikimrProto::BLOCKED && status != NKikimrProto::DEADLINE) {
- return false; // these statuses are non-terminal
- } else if (status != NKikimrProto::RACE) {
- // this status is terminal and we have nothing to do about it
- return done(status, TStringBuilder() << "status# " << NKikimrProto::EReplyStatus_Name(status) << " from# "
- << vdiskId.ToString());
- }
-
- A_LOG_INFO_S("DSP99", "Handing RACE response from " << vdiskId << " GroupGeneration# " << Info->GroupGeneration
- << " Response# " << SingleLineProto(record));
-
- // process the RACE status
- const TActorId& nodeWardenId = MakeBlobStorageNodeWardenID(self.SelfId().NodeId());
- if (vdiskId.GroupGeneration < Info->GroupGeneration) { // vdisk is older than our group
- RacingDomains |= {&Info->GetTopology(), vdiskId};
- if (Info->GetQuorumChecker().CheckFailModelForGroupDomains(RacingDomains)) {
- record.SetStatus(NKikimrProto::ERROR);
- auto adjustStatus = [](auto *v) {
- for (int i = 0; i < v->size(); ++i) {
- auto *p = v->Mutable(i);
- if (p->GetStatus() == NKikimrProto::RACE) {
- p->SetStatus(NKikimrProto::ERROR);
- }
- }
- };
- if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvVGetResult>) {
- adjustStatus(record.MutableResult());
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvVMultiPutResult>) {
- adjustStatus(record.MutableItems());
- }
- return false;
- }
- } else if (Info->GroupGeneration < vdiskId.GroupGeneration) { // our config is older that vdisk's one
- std::optional<NKikimrBlobStorage::TGroupInfo> group;
- if (record.HasRecentGroup()) {
- group = record.GetRecentGroup();
- if (group->GetGroupID() != Info->GroupID || group->GetGroupGeneration() != vdiskId.GroupGeneration) {
- return done(NKikimrProto::ERROR, "incorrect RecentGroup for RACE response");
- }
- }
- self.Send(nodeWardenId, new TEvBlobStorage::TEvUpdateGroupInfo(vdiskId.GroupID, vdiskId.GroupGeneration,
- std::move(group)));
- }
-
- // make NodeWarden restart the query just after proxy reconfiguration
- const TActorId& proxyId = GetProxyActorId();
- Y_VERIFY_DEBUG(RestartCounter < 100);
- auto q = self.RestartQuery(RestartCounter + 1);
- ++*Mon->NodeMon->RestartHisto[Min<size_t>(Mon->NodeMon->RestartHisto.size() - 1, RestartCounter)];
- TActivationContext::Send(new IEventHandle(nodeWardenId, Source, q.release(), 0, Cookie, &proxyId, std::move(TraceId)));
- PassAway();
- return true;
- }
-
- bool ProcessEvent(TAutoPtr<IEventHandle>& ev) {
- switch (ev->GetTypeRewrite()) {
-#define CHECK(T) case TEvBlobStorage::T::EventType: return CheckForTermErrors(reinterpret_cast<TEvBlobStorage::T::TPtr&>(ev))
- CHECK(TEvVPutResult);
- CHECK(TEvVMultiPutResult);
- CHECK(TEvVGetResult);
- CHECK(TEvVBlockResult);
- CHECK(TEvVGetBlockResult);
- CHECK(TEvVCollectGarbageResult);
- CHECK(TEvVGetBarrierResult);
- CHECK(TEvVStatusResult);
-#undef CHECK
-
- case TEvBlobStorage::EvProxySessionsState: {
- GroupQueues = static_cast<TEvProxySessionsState*>(ev->GetBase())->GroupQueues;
- return true;
- }
-
- case TEvAbortOperation::EventType: {
- if (IsEarlyRequestAbortEnabled) {
+ }
+
+ template<typename TEvent>
+ bool CheckForTermErrors(TAutoPtr<TEventHandle<TEvent>>& ev) {
+ auto& record = ev->Get()->Record;
+ auto& self = Derived();
+
+ if (!record.HasStatus()) {
+ return false; // we do not consider messages with missing status/vdisk fields
+ }
+
+ NKikimrProto::EReplyStatus status = record.GetStatus(); // obtain status from the reply
+
+ if (status == NKikimrProto::NOTREADY) { // special case from BS_QUEUE -- when connection is not yet established
+ record.SetStatus(NKikimrProto::ERROR); // rewrite this status as error for processing
+ PostponedQ.emplace_back(ev.Release());
+ CheckPostponedQueue();
+ return true; // event has been processed early
+ }
+
+ if (!record.HasVDiskID()) {
+ return false; // bad reply?
+ }
+
+ auto done = [&](NKikimrProto::EReplyStatus status, const TString& message) {
+ ErrorReason = message;
+ A_LOG_LOG_S(true, PriorityForStatusResult(status), "DSP10", "Query failed " << message);
+ self.ReplyAndDie(status);
+ return true;
+ };
+
+ // sanity check for matching group id
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ if (vdiskId.GroupID != Info->GroupID) {
+ return done(NKikimrProto::ERROR, TStringBuilder() << "incorrect VDiskId# " << vdiskId << " GroupId# "
+ << Info->GroupID);
+ }
+
+ // sanity check for correct VDisk generation ??? possible race
+ Y_VERIFY_S(status == NKikimrProto::RACE || vdiskId.GroupGeneration <= Info->GroupGeneration ||
+ TEvent::EventType == TEvBlobStorage::EvVStatusResult,
+ "status# " << NKikimrProto::EReplyStatus_Name(status) << " vdiskId.GroupGeneration# " << vdiskId.GroupGeneration
+ << " Info->GroupGeneration# " << Info->GroupGeneration);
+
+ if (status != NKikimrProto::RACE && status != NKikimrProto::BLOCKED && status != NKikimrProto::DEADLINE) {
+ return false; // these statuses are non-terminal
+ } else if (status != NKikimrProto::RACE) {
+ // this status is terminal and we have nothing to do about it
+ return done(status, TStringBuilder() << "status# " << NKikimrProto::EReplyStatus_Name(status) << " from# "
+ << vdiskId.ToString());
+ }
+
+ A_LOG_INFO_S("DSP99", "Handing RACE response from " << vdiskId << " GroupGeneration# " << Info->GroupGeneration
+ << " Response# " << SingleLineProto(record));
+
+ // process the RACE status
+ const TActorId& nodeWardenId = MakeBlobStorageNodeWardenID(self.SelfId().NodeId());
+ if (vdiskId.GroupGeneration < Info->GroupGeneration) { // vdisk is older than our group
+ RacingDomains |= {&Info->GetTopology(), vdiskId};
+ if (Info->GetQuorumChecker().CheckFailModelForGroupDomains(RacingDomains)) {
+ record.SetStatus(NKikimrProto::ERROR);
+ auto adjustStatus = [](auto *v) {
+ for (int i = 0; i < v->size(); ++i) {
+ auto *p = v->Mutable(i);
+ if (p->GetStatus() == NKikimrProto::RACE) {
+ p->SetStatus(NKikimrProto::ERROR);
+ }
+ }
+ };
+ if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvVGetResult>) {
+ adjustStatus(record.MutableResult());
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvVMultiPutResult>) {
+ adjustStatus(record.MutableItems());
+ }
+ return false;
+ }
+ } else if (Info->GroupGeneration < vdiskId.GroupGeneration) { // our config is older that vdisk's one
+ std::optional<NKikimrBlobStorage::TGroupInfo> group;
+ if (record.HasRecentGroup()) {
+ group = record.GetRecentGroup();
+ if (group->GetGroupID() != Info->GroupID || group->GetGroupGeneration() != vdiskId.GroupGeneration) {
+ return done(NKikimrProto::ERROR, "incorrect RecentGroup for RACE response");
+ }
+ }
+ self.Send(nodeWardenId, new TEvBlobStorage::TEvUpdateGroupInfo(vdiskId.GroupID, vdiskId.GroupGeneration,
+ std::move(group)));
+ }
+
+ // make NodeWarden restart the query just after proxy reconfiguration
+ const TActorId& proxyId = GetProxyActorId();
+ Y_VERIFY_DEBUG(RestartCounter < 100);
+ auto q = self.RestartQuery(RestartCounter + 1);
+ ++*Mon->NodeMon->RestartHisto[Min<size_t>(Mon->NodeMon->RestartHisto.size() - 1, RestartCounter)];
+ TActivationContext::Send(new IEventHandle(nodeWardenId, Source, q.release(), 0, Cookie, &proxyId, std::move(TraceId)));
+ PassAway();
+ return true;
+ }
+
+ bool ProcessEvent(TAutoPtr<IEventHandle>& ev) {
+ switch (ev->GetTypeRewrite()) {
+#define CHECK(T) case TEvBlobStorage::T::EventType: return CheckForTermErrors(reinterpret_cast<TEvBlobStorage::T::TPtr&>(ev))
+ CHECK(TEvVPutResult);
+ CHECK(TEvVMultiPutResult);
+ CHECK(TEvVGetResult);
+ CHECK(TEvVBlockResult);
+ CHECK(TEvVGetBlockResult);
+ CHECK(TEvVCollectGarbageResult);
+ CHECK(TEvVGetBarrierResult);
+ CHECK(TEvVStatusResult);
+#undef CHECK
+
+ case TEvBlobStorage::EvProxySessionsState: {
+ GroupQueues = static_cast<TEvProxySessionsState*>(ev->GetBase())->GroupQueues;
+ return true;
+ }
+
+ case TEvAbortOperation::EventType: {
+ if (IsEarlyRequestAbortEnabled) {
ErrorReason = "Request got EvAbortOperation, IsEarlyRequestAbortEnabled# true";
- Derived().ReplyAndDie(NKikimrProto::ERROR);
- }
- return true;
- }
-
- case TEvents::TSystem::Poison: {
- ErrorReason = "Request got Poison";
- Derived().ReplyAndDie(NKikimrProto::ERROR);
- return true;
- }
- }
-
- return false;
- }
-
- void CountPuts(const TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>>& q) {
- for (const auto& item : q) {
- ++GeneratedSubrequests;
+ Derived().ReplyAndDie(NKikimrProto::ERROR);
+ }
+ return true;
+ }
+
+ case TEvents::TSystem::Poison: {
+ ErrorReason = "Request got Poison";
+ Derived().ReplyAndDie(NKikimrProto::ERROR);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void CountPuts(const TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>>& q) {
+ for (const auto& item : q) {
+ ++GeneratedSubrequests;
GeneratedSubrequestBytes += item->GetBufferBytes();
- }
- }
-
- void CountPuts(const TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>>& q) {
+ }
+ }
+
+ void CountPuts(const TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>>& q) {
for (const auto& item : q) {
++GeneratedSubrequests;
GeneratedSubrequestBytes += item->GetBufferBytes();
}
}
- template<typename T>
- void SendToQueue(std::unique_ptr<T> event, ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled = false) {
- const TActorId queueId = GroupQueues->Send(*this, Info->GetTopology(), std::move(event), cookie, std::move(traceId),
- timeStatsEnabled);
- ++InvolvedQueues[queueId];
- ++RequestsInFlight;
- }
-
- template<typename TPtr>
- void ProcessReplyFromQueue(const TPtr& ev) {
- auto it = InvolvedQueues.find(ev->Sender);
- Y_VERIFY(it != InvolvedQueues.end());
- if (!--it->second) {
- InvolvedQueues.erase(it);
- }
- Y_VERIFY(RequestsInFlight);
- --RequestsInFlight;
- CheckPostponedQueue();
- }
-
- void SendToQueues(TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, bool timeStatsEnabled) {
- for (auto& request : vGets) {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
+ template<typename T>
+ void SendToQueue(std::unique_ptr<T> event, ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled = false) {
+ const TActorId queueId = GroupQueues->Send(*this, Info->GetTopology(), std::move(event), cookie, std::move(traceId),
+ timeStatsEnabled);
+ ++InvolvedQueues[queueId];
+ ++RequestsInFlight;
+ }
+
+ template<typename TPtr>
+ void ProcessReplyFromQueue(const TPtr& ev) {
+ auto it = InvolvedQueues.find(ev->Sender);
+ Y_VERIFY(it != InvolvedQueues.end());
+ if (!--it->second) {
+ InvolvedQueues.erase(it);
+ }
+ Y_VERIFY(RequestsInFlight);
+ --RequestsInFlight;
+ CheckPostponedQueue();
+ }
+
+ void SendToQueues(TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, bool timeStatsEnabled) {
+ for (auto& request : vGets) {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
Y_VERIFY(request->Record.HasCookie());
ui64 messageCookie = request->Record.GetCookie();
CountEvent(*request);
const ui64 cyclesPerUs = NHPTimer::GetCyclesPerSecond() / 1000000;
request->Record.MutableTimestamps()->SetSentByDSProxyUs(GetCycleCountFast() / cyclesPerUs);
- SendToQueue(std::move(request), messageCookie, TraceId.SeparateBranch(), timeStatsEnabled);
+ SendToQueue(std::move(request), messageCookie, TraceId.SeparateBranch(), timeStatsEnabled);
}
}
- TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPut> &ev) {
+ TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPut> &ev) {
Y_VERIFY(ev->Record.HasBlobID());
return LogoBlobIDFromLogoBlobID(ev->Record.GetBlobID());
}
- TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVMultiPut> &ev) {
+ TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVMultiPut> &ev) {
Y_VERIFY(ev->Record.ItemsSize());
return LogoBlobIDFromLogoBlobID(ev->Record.GetItems(0).GetBlobID());
}
- TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVMovedPatch> &ev) {
+ TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVMovedPatch> &ev) {
Y_VERIFY(ev->Record.HasPatchedBlobId());
return LogoBlobIDFromLogoBlobID(ev->Record.GetPatchedBlobId());
}
- TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPatchStart> &ev) {
+ TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPatchStart> &ev) {
Y_VERIFY(ev->Record.HasOriginalBlobId());
return LogoBlobIDFromLogoBlobID(ev->Record.GetOriginalBlobId());
}
- TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> &ev) {
+ TLogoBlobID GetBlobId(std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> &ev) {
Y_VERIFY(ev->Record.HasPatchedPartBlobId());
return LogoBlobIDFromLogoBlobID(ev->Record.GetPatchedPartBlobId());
}
template <typename TEvent>
- void SendToQueues(TDeque<std::unique_ptr<TEvent>> &events, bool timeStatsEnabled) {
- for (auto& request : events) {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutSent);
+ void SendToQueues(TDeque<std::unique_ptr<TEvent>> &events, bool timeStatsEnabled) {
+ for (auto& request : events) {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutSent);
Y_VERIFY(request->Record.HasCookie());
ui64 messageCookie = request->Record.GetCookie();
CountEvent(*request);
@@ -383,85 +383,85 @@ public:
TVDiskID vDiskId = VDiskIDFromVDiskID(request->Record.GetVDiskID());
LWTRACK(DSProxyPutVPutIsSent, request->Orbit, Info->GetFailDomainOrderNumber(vDiskId),
Info->GroupID, id.Channel(), id.PartId(), id.ToString(), id.BlobSize());
- SendToQueue(std::move(request), messageCookie, TraceId.SeparateBranch(), timeStatsEnabled);
+ SendToQueue(std::move(request), messageCookie, TraceId.SeparateBranch(), timeStatsEnabled);
}
}
- void SendResponseAndDie(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats, TActorId source,
- ui64 cookie, NWilson::TTraceId traceId) {
- SendResponse(std::move(ev), timeStats, source, cookie, std::move(traceId));
- PassAway();
- }
-
- void SendResponseAndDie(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats = nullptr) {
- SendResponseAndDie(std::move(ev), timeStats, Source, Cookie, std::move(TraceId));
- }
-
- TActorId GetProxyActorId() const {
- return MakeBlobStorageProxyID(Info->GroupID);
- }
-
- void PassAway() override {
- // ensure that we are dying for the first time
- Y_VERIFY(!std::exchange(Dead, true));
+ void SendResponseAndDie(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats, TActorId source,
+ ui64 cookie, NWilson::TTraceId traceId) {
+ SendResponse(std::move(ev), timeStats, source, cookie, std::move(traceId));
+ PassAway();
+ }
+
+ void SendResponseAndDie(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats = nullptr) {
+ SendResponseAndDie(std::move(ev), timeStats, Source, Cookie, std::move(TraceId));
+ }
+
+ TActorId GetProxyActorId() const {
+ return MakeBlobStorageProxyID(Info->GroupID);
+ }
+
+ void PassAway() override {
+ // ensure that we are dying for the first time
+ Y_VERIFY(!std::exchange(Dead, true));
TDerived::ActiveCounter(Mon)->Dec();
- Derived().Send(GetProxyActorId(), new TEvDeathNote(Responsiveness));
- for (const auto& [queueId, numUnrepliedRequests] : InvolvedQueues) {
- Derived().Send(queueId, new TEvPruneQueue);
+ Derived().Send(GetProxyActorId(), new TEvDeathNote(Responsiveness));
+ for (const auto& [queueId, numUnrepliedRequests] : InvolvedQueues) {
+ Derived().Send(queueId, new TEvPruneQueue);
}
- TActorBootstrapped<TDerived>::PassAway();
- }
-
- void SendResponse(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats, TActorId source, ui64 cookie,
- NWilson::TTraceId traceId) {
- const TInstant now = TActivationContext::Now();
-
- switch (ev->Type()) {
-#define XX(T) \
- case TEvBlobStorage::Ev##T##Result: \
- Mon->RespStat##T->Account(static_cast<TEvBlobStorage::TEv##T##Result&>(*ev).Status); \
- break;
-
- XX(Put)
- XX(Get)
- XX(Block)
- XX(Discover)
- XX(Range)
- XX(CollectGarbage)
- XX(Status)
+ TActorBootstrapped<TDerived>::PassAway();
+ }
+
+ void SendResponse(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats, TActorId source, ui64 cookie,
+ NWilson::TTraceId traceId) {
+ const TInstant now = TActivationContext::Now();
+
+ switch (ev->Type()) {
+#define XX(T) \
+ case TEvBlobStorage::Ev##T##Result: \
+ Mon->RespStat##T->Account(static_cast<TEvBlobStorage::TEv##T##Result&>(*ev).Status); \
+ break;
+
+ XX(Put)
+ XX(Get)
+ XX(Block)
+ XX(Discover)
+ XX(Range)
+ XX(CollectGarbage)
+ XX(Status)
XX(Patch)
- default:
- Y_FAIL();
-#undef XX
- }
-
+ default:
+ Y_FAIL();
+#undef XX
+ }
+
// ensure that we are dying for the first time
Y_VERIFY(!Dead);
if (RequestHandleClass && PoolCounters) {
PoolCounters->GetItem(*RequestHandleClass, RequestBytes).Register(
RequestBytes, GeneratedSubrequests, GeneratedSubrequestBytes, Timer.Passed());
- }
-
- const TActorId proxyId = GetProxyActorId();
- if (timeStats) {
- Derived().Send(proxyId, new TEvTimeStats(std::move(*timeStats)));
- }
-
- if (LatencyQueueKind) {
- Derived().Send(proxyId, new TEvLatencyReport(*LatencyQueueKind, now - RequestStartTime));
- }
-
+ }
+
+ const TActorId proxyId = GetProxyActorId();
+ if (timeStats) {
+ Derived().Send(proxyId, new TEvTimeStats(std::move(*timeStats)));
+ }
+
+ if (LatencyQueueKind) {
+ Derived().Send(proxyId, new TEvLatencyReport(*LatencyQueueKind, now - RequestStartTime));
+ }
+
// KIKIMR-6737
- if (ev->Type() == TEvBlobStorage::EvGetResult) {
- static_cast<TEvBlobStorage::TEvGetResult&>(*ev).Sent = now;
+ if (ev->Type() == TEvBlobStorage::EvGetResult) {
+ static_cast<TEvBlobStorage::TEvGetResult&>(*ev).Sent = now;
}
// send the reply to original request sender
- Derived().Send(source, ev.release(), 0, cookie, std::move(traceId));
- };
-
- void SendResponse(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats = nullptr) {
- SendResponse(std::move(ev), timeStats, Source, Cookie, std::move(TraceId));
+ Derived().Send(source, ev.release(), 0, cookie, std::move(traceId));
+ };
+
+ void SendResponse(std::unique_ptr<IEventBase>&& ev, TBlobStorageGroupProxyTimeStats *timeStats = nullptr) {
+ SendResponse(std::move(ev), timeStats, Source, Cookie, std::move(TraceId));
}
static double GetStartTime(const NKikimrBlobStorage::TTimestamps& timestamps) {
@@ -476,68 +476,68 @@ public:
return double(timestamps.GetSentByVDiskUs() - timestamps.GetReceivedByVDiskUs())/1000.0;
}
-private:
- TDerived& Derived() {
- return static_cast<TDerived&>(*this);
- }
-
- void CheckPostponedQueue() {
- if (PostponedQ.size() == RequestsInFlight) {
- for (auto& ev : std::exchange(PostponedQ, {})) {
- TActivationContext::Send(ev.release());
- }
- }
- }
-
-protected:
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- TIntrusivePtr<TGroupQueues> GroupQueues;
- TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
+private:
+ TDerived& Derived() {
+ return static_cast<TDerived&>(*this);
+ }
+
+ void CheckPostponedQueue() {
+ if (PostponedQ.size() == RequestsInFlight) {
+ for (auto& ev : std::exchange(PostponedQ, {})) {
+ TActivationContext::Send(ev.release());
+ }
+ }
+ }
+
+protected:
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
TIntrusivePtr<TStoragePoolCounters> PoolCounters;
- TLogContext LogCtx;
- NWilson::TTraceId TraceId;
- TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> Responsiveness;
+ TLogContext LogCtx;
+ NWilson::TTraceId TraceId;
+ TStackVec<std::pair<TDiskResponsivenessTracker::TDiskId, TDuration>, 16> Responsiveness;
TString ErrorReason;
TMaybe<TStoragePoolCounters::EHandleClass> RequestHandleClass;
- ui32 RequestBytes = 0;
- ui32 GeneratedSubrequests = 0;
- ui32 GeneratedSubrequestBytes = 0;
- bool Dead = false;
- const ui32 RestartCounter = 0;
-
-private:
+ ui32 RequestBytes = 0;
+ ui32 GeneratedSubrequests = 0;
+ ui32 GeneratedSubrequestBytes = 0;
+ bool Dead = false;
+ const ui32 RestartCounter = 0;
+
+private:
const TActorId Source;
- const ui64 Cookie;
- THashMap<TActorId, ui32> InvolvedQueues;
- ui32 RequestsInFlight = 0;
- std::unique_ptr<IEventBase> Response;
- const TMaybe<TGroupStat::EKind> LatencyQueueKind;
- const TInstant RequestStartTime;
- THPTimer Timer;
- std::deque<std::unique_ptr<IEventHandle>> PostponedQ;
- TBlobStorageGroupInfo::TGroupFailDomains RacingDomains; // a set of domains we've received RACE from
-};
-
+ const ui64 Cookie;
+ THashMap<TActorId, ui32> InvolvedQueues;
+ ui32 RequestsInFlight = 0;
+ std::unique_ptr<IEventBase> Response;
+ const TMaybe<TGroupStat::EKind> LatencyQueueKind;
+ const TInstant RequestStartTime;
+ THPTimer Timer;
+ std::deque<std::unique_ptr<IEventHandle>> PostponedQ;
+ TBlobStorageGroupInfo::TGroupFailDomains RacingDomains; // a set of domains we've received RACE from
+};
+
void Encrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
const TBlobStorageGroupInfo &info);
void Decrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
const TBlobStorageGroupInfo &info);
IActor* CreateBlobStorageGroupRangeRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvPut *ev,
- ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
+ ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
TDiskResponsivenessTracker::TPerDiskStatsPtr stats,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters,
bool enableRequestMod3x3ForMinLatecy);
IActor* CreateBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state,
+ const TIntrusivePtr<TGroupQueues> &state,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon,
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &ev,
bool timeStatsEnabled,
@@ -547,9 +547,9 @@ IActor* CreateBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupIn
bool enableRequestMod3x3ForMinLatecy);
IActor* CreateBlobStorageGroupGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
- ui64 cookie, NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout,
+ ui64 cookie, NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters,
bool isVMultiPutMode);
@@ -560,61 +560,61 @@ IActor* CreateBlobStorageGroupPatchRequest(const TIntrusivePtr<TBlobStorageGroup
const TActorId &proxyId, bool useVPatch);
IActor* CreateBlobStorageGroupMultiGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
- ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
+ ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupIndexRestoreGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
- ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
+ ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
-IActor* CreateBlobStorageGroupMirror3dcDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+IActor* CreateBlobStorageGroupMirror3dcDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
-
-IActor* CreateBlobStorageGroupMirror3of4DiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
- ui64 cookie, NWilson::TTraceId traceId, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
-
+
+IActor* CreateBlobStorageGroupMirror3of4DiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+ ui64 cookie, NWilson::TTraceId traceId, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
+
IActor* CreateBlobStorageGroupCollectGarbageRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupMultiCollectRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupBlockRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupStatusRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvStatus *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters);
IActor* CreateBlobStorageGroupEjectedProxy(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon);
-
-IActor* CreateBlobStorageGroupProxyConfigured(TIntrusivePtr<TBlobStorageGroupInfo>&& info,
+
+IActor* CreateBlobStorageGroupProxyConfigured(TIntrusivePtr<TBlobStorageGroupInfo>&& info,
bool forceWaitAllDrives, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
- TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters, const TControlWrapper &enablePutBatching,
+ TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters, const TControlWrapper &enablePutBatching,
const TControlWrapper &enableVPatch);
-
-IActor* CreateBlobStorageGroupProxyUnconfigured(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
+
+IActor* CreateBlobStorageGroupProxyUnconfigured(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch);
}//NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.cpp
index eb6d8394f02..3cbcb5c81bd 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.cpp
@@ -22,16 +22,16 @@ void TBlobState::TState::AddPartToPut(TString &data) {
}
-void TBlobState::Init(const TLogoBlobID &id, const TBlobStorageGroupInfo &info) {
+void TBlobState::Init(const TLogoBlobID &id, const TBlobStorageGroupInfo &info) {
Id = id;
Parts.resize(info.Type.TotalPartCount());
- ui32 blobSubgroupSize = info.Type.BlobSubgroupSize();
- Disks.resize(blobSubgroupSize);
+ ui32 blobSubgroupSize = info.Type.BlobSubgroupSize();
+ Disks.resize(blobSubgroupSize);
TBlobStorageGroupInfo::TServiceIds vdisksSvc;
TBlobStorageGroupInfo::TVDiskIds vdisksId;
const ui32 hash = Id.Hash();
- info.PickSubgroup(hash, &vdisksId, &vdisksSvc);
- for (ui32 i = 0; i < blobSubgroupSize; ++i) {
+ info.PickSubgroup(hash, &vdisksId, &vdisksSvc);
+ for (ui32 i = 0; i < blobSubgroupSize; ++i) {
Disks[i].OrderNumber = info.GetOrderNumber(vdisksId[i]);
Disks[i].DiskParts.resize(info.Type.TotalPartCount());
}
@@ -53,8 +53,8 @@ void TBlobState::AddPartToPut(ui32 partIdx, TString &partData) {
}
void TBlobState::MarkBlobReadyToPut(ui8 blobIdx) {
- Y_VERIFY(WholeSituation == ESituation::Unknown || WholeSituation == ESituation::Present);
- WholeSituation = ESituation::Present;
+ Y_VERIFY(WholeSituation == ESituation::Unknown || WholeSituation == ESituation::Present);
+ WholeSituation = ESituation::Present;
BlobIdx = blobIdx;
IsChanged = true;
}
@@ -68,10 +68,10 @@ bool TBlobState::Restore(const TBlobStorageGroupInfo &info) {
const ui32 parts = info.Type.TotalPartCount();
ui32 partsPresent = 0;
for (ui32 i = 0; i < parts; ++i) {
- if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(Id, i + 1))) {
+ if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(Id, i + 1))) {
if (TIntervalVec<i32>(0, partSize).IsSubsetOf(Parts[i].Here)) {
- ++partsPresent;
- }
+ ++partsPresent;
+ }
}
}
if (partsPresent < info.Type.MinimalRestorablePartCount()) {
@@ -81,13 +81,13 @@ bool TBlobState::Restore(const TBlobStorageGroupInfo &info) {
TDataPartSet partSet;
partSet.Parts.resize(parts);
for (ui32 i = 0; i < parts; ++i) {
- if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(Id, i + 1))) {
+ if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(Id, i + 1))) {
if (TIntervalVec<i32>(0, partSize).IsSubsetOf(Parts[i].Here)) {
- partSet.PartsMask |= (1 << i);
- TString tmp = TString::Uninitialized(partSize);
- Parts[i].Data.Read(0, const_cast<char*>(tmp.data()), partSize);
- partSet.Parts[i].ReferenceTo(tmp);
- }
+ partSet.PartsMask |= (1 << i);
+ TString tmp = TString::Uninitialized(partSize);
+ Parts[i].Data.Read(0, const_cast<char*>(tmp.data()), partSize);
+ partSet.Parts[i].ReferenceTo(tmp);
+ }
}
}
partSet.FullDataSize = Id.BlobSize();
@@ -107,9 +107,9 @@ void TBlobState::AddResponseData(const TBlobStorageGroupInfo &info, const TLogoB
ui32 partIdx = id.PartId() - 1;
Y_VERIFY(partIdx < Parts.size());
const ui32 partSize = info.Type.PartSize(id);
- if (partSize) {
- Parts[partIdx].AddResponseData(partSize, shift, data);
- }
+ if (partSize) {
+ Parts[partIdx].AddResponseData(partSize, shift, data);
+ }
IsChanged = true;
// Mark part as present for the disk
bool isFound = false;
@@ -120,11 +120,11 @@ void TBlobState::AddResponseData(const TBlobStorageGroupInfo &info, const TLogoB
Y_VERIFY(partIdx < disk.DiskParts.size());
TDiskPart &diskPart = disk.DiskParts[partIdx];
//Cerr << Endl << "present diskIdx# " << diskIdx << " partIdx# " << partIdx << Endl << Endl;
- diskPart.Situation = ESituation::Present;
- if (partSize) {
- TIntervalVec<i32> responseInterval(shift, shift + data.size());
- diskPart.Requested.Subtract(responseInterval);
- }
+ diskPart.Situation = ESituation::Present;
+ if (partSize) {
+ TIntervalVec<i32> responseInterval(shift, shift + data.size());
+ diskPart.Requested.Subtract(responseInterval);
+ }
break;
}
}
@@ -145,7 +145,7 @@ void TBlobState::AddNoDataResponse(const TBlobStorageGroupInfo &info, const TLog
Y_VERIFY(partIdx < disk.DiskParts.size());
TDiskPart &diskPart = disk.DiskParts[partIdx];
//Cerr << Endl << "absent diskIdx# " << diskIdx << " partIdx# " << partIdx << Endl << Endl;
- diskPart.Situation = ESituation::Absent;
+ diskPart.Situation = ESituation::Absent;
diskPart.Requested.Clear();
break;
}
@@ -167,7 +167,7 @@ void TBlobState::AddPutOkResponse(const TBlobStorageGroupInfo &info, const TLogo
Y_VERIFY(partIdx < disk.DiskParts.size());
TDiskPart &diskPart = disk.DiskParts[partIdx];
//Cerr << Endl << "put ok diskIdx# " << diskIdx << " partIdx# " << partIdx << Endl << Endl;
- diskPart.Situation = ESituation::Present;
+ diskPart.Situation = ESituation::Present;
break;
}
}
@@ -188,7 +188,7 @@ void TBlobState::AddErrorResponse(const TBlobStorageGroupInfo &info, const TLogo
Y_VERIFY(partIdx < disk.DiskParts.size());
TDiskPart &diskPart = disk.DiskParts[partIdx];
//Cerr << Endl << "error diskIdx# " << diskIdx << " partIdx# " << partIdx << Endl << Endl;
- diskPart.Situation = ESituation::Error;
+ diskPart.Situation = ESituation::Error;
diskPart.Requested.Clear();
break;
}
@@ -210,7 +210,7 @@ void TBlobState::AddNotYetResponse(const TBlobStorageGroupInfo &info, const TLog
Y_VERIFY(partIdx < disk.DiskParts.size());
TDiskPart &diskPart = disk.DiskParts[partIdx];
//Cerr << Endl << "error diskIdx# " << diskIdx << " partIdx# " << partIdx << Endl << Endl;
- diskPart.Situation = ESituation::Lost;
+ diskPart.Situation = ESituation::Lost;
diskPart.Requested.Clear();
break;
}
@@ -218,20 +218,20 @@ void TBlobState::AddNotYetResponse(const TBlobStorageGroupInfo &info, const TLog
Y_VERIFY(isFound);
}
-ui64 TBlobState::GetPredictedDelayNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+ui64 TBlobState::GetPredictedDelayNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
ui32 diskIdxInSubring, NKikimrBlobStorage::EVDiskQueueId queueId) const {
Y_UNUSED(info);
- return groupQueues.GetPredictedDelayNsByOrderNumber(Disks[diskIdxInSubring].OrderNumber, queueId);
+ return groupQueues.GetPredictedDelayNsByOrderNumber(Disks[diskIdxInSubring].OrderNumber, queueId);
}
-void TBlobState::GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+void TBlobState::GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
NKikimrBlobStorage::EVDiskQueueId queueId,
ui64 *outWorstNs, ui64 *outNextToWorstNs, i32 *outWorstSubgroupIdx) const {
*outWorstSubgroupIdx = -1;
*outWorstNs = 0;
*outNextToWorstNs = 0;
for (ui32 diskIdx = 0; diskIdx < Disks.size(); ++diskIdx) {
- ui64 predictedNs = GetPredictedDelayNs(info, groupQueues, diskIdx, queueId);
+ ui64 predictedNs = GetPredictedDelayNs(info, groupQueues, diskIdx, queueId);
if (predictedNs > *outWorstNs) {
*outNextToWorstNs = *outWorstNs;
*outWorstNs = predictedNs;
@@ -268,18 +268,18 @@ TString TBlobState::ToString() const {
TString TBlobState::SituationToString(ESituation situation) {
switch (situation) {
- case ESituation::Unknown:
- return "ESituation::Unknown";
- case ESituation::Error:
- return "ESituation::Error";
- case ESituation::Absent:
- return "ESituation::Absent";
- case ESituation::Lost:
- return "ESituation::Lost";
- case ESituation::Present:
- return "ESituation::Present";
- case ESituation::Sent:
- return "ESituation::Sent";
+ case ESituation::Unknown:
+ return "ESituation::Unknown";
+ case ESituation::Error:
+ return "ESituation::Error";
+ case ESituation::Absent:
+ return "ESituation::Absent";
+ case ESituation::Lost:
+ return "ESituation::Lost";
+ case ESituation::Present:
+ return "ESituation::Present";
+ case ESituation::Sent:
+ return "ESituation::Sent";
}
Y_VERIFY(false, "Unexpected situation# %" PRIu64, ui64(situation));
return "";
@@ -367,7 +367,7 @@ void TBlackboard::AddNeeded(const TLogoBlobID &id, ui32 inShift, ui32 inSize) {
if (size > 0) {
TBlobState &state = BlobStates[id];;
if (!bool(state.Id)) {
- state.Init(id, *Info);
+ state.Init(id, *Info);
}
state.AddNeeded(shift, size);
} else {
@@ -456,65 +456,65 @@ void TBlackboard::AddErrorResponse(const TLogoBlobID &id, ui32 orderNumber) {
state.AddErrorResponse(*Info, id, orderNumber);
}
-EStrategyOutcome TBlackboard::RunStrategy(TLogContext &logCtx, const IStrategy& s, TBatchedVec<TBlobStates::value_type*> *finished) {
- IStrategy& temp = const_cast<IStrategy&>(s); // better UX
+EStrategyOutcome TBlackboard::RunStrategy(TLogContext &logCtx, const IStrategy& s, TBatchedVec<TBlobStates::value_type*> *finished) {
+ IStrategy& temp = const_cast<IStrategy&>(s); // better UX
Y_VERIFY(BlobStates.size());
EStrategyOutcome outcome = EStrategyOutcome::IN_PROGRESS;
- for (auto it = BlobStates.begin(); it != BlobStates.end(); ++it) {
- auto& blob = it->second;
+ for (auto it = BlobStates.begin(); it != BlobStates.end(); ++it) {
+ auto& blob = it->second;
if (!blob.IsChanged) {
continue;
}
blob.IsChanged = false;
- // recalculate blob outcome if it is not yet determined
- switch (auto res = temp.Process(logCtx, blob, *Info, *this, GroupDiskRequests)) {
- case EStrategyOutcome::IN_PROGRESS:
+ // recalculate blob outcome if it is not yet determined
+ switch (auto res = temp.Process(logCtx, blob, *Info, *this, GroupDiskRequests)) {
+ case EStrategyOutcome::IN_PROGRESS:
if (blob.IsDone) {
DoneCount--;
blob.IsDone = false;
}
- outcome = EStrategyOutcome::IN_PROGRESS;
- break;
-
- case EStrategyOutcome::ERROR:
- if (IsAllRequestsTogether) {
- return res;
- } else {
- blob.Status = NKikimrProto::ERROR;
- if (finished) {
- finished->push_back(&*it);
- }
+ outcome = EStrategyOutcome::IN_PROGRESS;
+ break;
+
+ case EStrategyOutcome::ERROR:
+ if (IsAllRequestsTogether) {
+ return res;
+ } else {
+ blob.Status = NKikimrProto::ERROR;
+ if (finished) {
+ finished->push_back(&*it);
+ }
if (outcome.ErrorReason) {
- outcome.ErrorReason += " && ";
- outcome.ErrorReason += res.ErrorReason;
+ outcome.ErrorReason += " && ";
+ outcome.ErrorReason += res.ErrorReason;
} else {
outcome.ErrorReason = res.ErrorReason;
- }
- }
+ }
+ }
if (!blob.IsDone) {
DoneCount++;
blob.IsDone = true;
}
- break;
-
- case EStrategyOutcome::DONE:
- if (!IsAllRequestsTogether) {
- blob.Status = NKikimrProto::OK;
- if (finished) {
- finished->push_back(&*it);
- }
- }
+ break;
+
+ case EStrategyOutcome::DONE:
+ if (!IsAllRequestsTogether) {
+ blob.Status = NKikimrProto::OK;
+ if (finished) {
+ finished->push_back(&*it);
+ }
+ }
if (!blob.IsDone) {
DoneCount++;
blob.IsDone = true;
}
- break;
+ break;
}
}
if (DoneCount == (BlobStates.size() + DoneBlobStates.size())) {
outcome = EStrategyOutcome::DONE;
}
- return outcome;
+ return outcome;
}
TBlobState& TBlackboard::GetState(const TLogoBlobID &id) {
@@ -531,32 +531,32 @@ TBlobState& TBlackboard::GetState(const TLogoBlobID &id) {
return state;
}
-ssize_t TBlackboard::AddPartMap(const TLogoBlobID &id, ui32 diskOrderNumber, ui32 requestIndex) {
- Y_VERIFY(id);
+ssize_t TBlackboard::AddPartMap(const TLogoBlobID &id, ui32 diskOrderNumber, ui32 requestIndex) {
+ Y_VERIFY(id);
TBlobState &state = GetState(id);
- ssize_t ret = state.PartMap.size();
- state.PartMap.emplace_back(TEvBlobStorage::TEvGetResult::TPartMapItem{
- diskOrderNumber,
- id.PartId(),
- requestIndex,
- Max<ui32>(),
- {},
- });
- return ret;
-}
-
-void TBlackboard::ReportPartMapStatus(const TLogoBlobID &id, ssize_t partMapIndex, ui32 responseIndex, NKikimrProto::EReplyStatus status) {
- Y_VERIFY(id);
- Y_VERIFY(partMapIndex >= 0);
+ ssize_t ret = state.PartMap.size();
+ state.PartMap.emplace_back(TEvBlobStorage::TEvGetResult::TPartMapItem{
+ diskOrderNumber,
+ id.PartId(),
+ requestIndex,
+ Max<ui32>(),
+ {},
+ });
+ return ret;
+}
+
+void TBlackboard::ReportPartMapStatus(const TLogoBlobID &id, ssize_t partMapIndex, ui32 responseIndex, NKikimrProto::EReplyStatus status) {
+ Y_VERIFY(id);
+ Y_VERIFY(partMapIndex >= 0);
TBlobState &state = GetState(id);
- Y_VERIFY(static_cast<size_t>(partMapIndex) < state.PartMap.size());
- TEvBlobStorage::TEvGetResult::TPartMapItem &item = state.PartMap[partMapIndex];
- Y_VERIFY(item.ResponseIndex == responseIndex || item.ResponseIndex == Max<ui32>());
- item.ResponseIndex = responseIndex;
- item.Status.emplace_back(id.PartId(), status);
-}
-
-void TBlackboard::GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+ Y_VERIFY(static_cast<size_t>(partMapIndex) < state.PartMap.size());
+ TEvBlobStorage::TEvGetResult::TPartMapItem &item = state.PartMap[partMapIndex];
+ Y_VERIFY(item.ResponseIndex == responseIndex || item.ResponseIndex == Max<ui32>());
+ item.ResponseIndex = responseIndex;
+ item.Status.emplace_back(id.PartId(), status);
+}
+
+void TBlackboard::GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
NKikimrBlobStorage::EVDiskQueueId queueId,
ui64 *outWorstNs, ui64 *outNextToWorstNs, i32 *outWorstOrderNumber) const {
*outWorstOrderNumber = -1;
@@ -564,7 +564,7 @@ void TBlackboard::GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, T
*outNextToWorstNs = 0;
ui32 totalVDisks = info.GetTotalVDisksNum();
for (ui32 orderNumber = 0; orderNumber < totalVDisks; ++orderNumber) {
- ui64 predictedNs = groupQueues.GetPredictedDelayNsByOrderNumber(orderNumber, queueId);
+ ui64 predictedNs = groupQueues.GetPredictedDelayNsByOrderNumber(orderNumber, queueId);
if (predictedNs > *outWorstNs) {
*outNextToWorstNs = *outWorstNs;
*outWorstNs = predictedNs;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h b/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h
index fe926648a83..41bba3f6f11 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h
@@ -11,40 +11,40 @@
namespace NKikimr {
-struct EStrategyOutcome {
- enum TValue {
- IN_PROGRESS,
- ERROR, // unrecoverable request error
- DONE,
- };
-
- EStrategyOutcome() = default;
- EStrategyOutcome(TValue value) : Value(value) {}
- EStrategyOutcome(const EStrategyOutcome&) = default;
- EStrategyOutcome(EStrategyOutcome&&) = default;
- EStrategyOutcome& operator =(const EStrategyOutcome&) = default;
- EStrategyOutcome& operator =(EStrategyOutcome&&) = default;
-
- static EStrategyOutcome Error(TString err) {
- EStrategyOutcome res(ERROR);
- res.ErrorReason = std::move(err);
- return res;
- }
-
- operator TValue() const { return Value; }
-
- TValue Value;
- TString ErrorReason;
-};
-
+struct EStrategyOutcome {
+ enum TValue {
+ IN_PROGRESS,
+ ERROR, // unrecoverable request error
+ DONE,
+ };
+
+ EStrategyOutcome() = default;
+ EStrategyOutcome(TValue value) : Value(value) {}
+ EStrategyOutcome(const EStrategyOutcome&) = default;
+ EStrategyOutcome(EStrategyOutcome&&) = default;
+ EStrategyOutcome& operator =(const EStrategyOutcome&) = default;
+ EStrategyOutcome& operator =(EStrategyOutcome&&) = default;
+
+ static EStrategyOutcome Error(TString err) {
+ EStrategyOutcome res(ERROR);
+ res.ErrorReason = std::move(err);
+ return res;
+ }
+
+ operator TValue() const { return Value; }
+
+ TValue Value;
+ TString ErrorReason;
+};
+
struct TBlobState {
- enum class ESituation {
- Unknown,
- Error,
- Absent,
- Lost,
- Present, // Restore strategy takes action only on theese
- Sent, // For Restore and Put strategies
+ enum class ESituation {
+ Unknown,
+ Error,
+ Absent,
+ Lost,
+ Present, // Restore strategy takes action only on theese
+ Sent, // For Restore and Put strategies
};
struct TState {
TFragmentedBuffer Data;
@@ -61,28 +61,28 @@ struct TBlobState {
};
struct TDiskPart {
TIntervalSet<i32> Requested;
- ESituation Situation = ESituation::Unknown;
+ ESituation Situation = ESituation::Unknown;
TString ToString() const;
};
struct TDisk {
ui32 OrderNumber;
- bool IsSlow = false;
+ bool IsSlow = false;
TStackVec<TDiskPart, TypicalPartsInBlob> DiskParts;
TString ToString() const;
};
TLogoBlobID Id;
TWholeState Whole;
- ESituation WholeSituation = ESituation::Unknown; // TODO(cthulhu): Use a specially tailored enum here
+ ESituation WholeSituation = ESituation::Unknown; // TODO(cthulhu): Use a specially tailored enum here
TStackVec<TState, TypicalPartsInBlob> Parts;
TStackVec<TDisk, TypicalDisksInSubring> Disks;
- TVector<TEvBlobStorage::TEvGetResult::TPartMapItem> PartMap;
+ TVector<TEvBlobStorage::TEvGetResult::TPartMapItem> PartMap;
ui8 BlobIdx;
NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
bool IsChanged = false;
bool IsDone = false;
- void Init(const TLogoBlobID &id, const TBlobStorageGroupInfo &Info);
+ void Init(const TLogoBlobID &id, const TBlobStorageGroupInfo &Info);
void AddNeeded(ui64 begin, ui64 size);
void AddPartToPut(ui32 partIdx, TString &partData);
void MarkBlobReadyToPut(ui8 blobIdx = 0);
@@ -93,9 +93,9 @@ struct TBlobState {
void AddNoDataResponse(const TBlobStorageGroupInfo &info, const TLogoBlobID &id, ui32 diskIdxInSubring);
void AddErrorResponse(const TBlobStorageGroupInfo &info, const TLogoBlobID &id, ui32 diskIdxInSubring);
void AddNotYetResponse(const TBlobStorageGroupInfo &info, const TLogoBlobID &id, ui32 diskIdxInSubring);
- ui64 GetPredictedDelayNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+ ui64 GetPredictedDelayNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
ui32 diskIdxInSubring, NKikimrBlobStorage::EVDiskQueueId queueId) const;
- void GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+ void GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
NKikimrBlobStorage::EVDiskQueueId queueId,
ui64 *outWorstNs, ui64 *outNextToWorstNs, i32 *outWorstSubgroupIdx) const;
TString ToString() const;
@@ -106,7 +106,7 @@ struct TDiskGetRequest {
const TLogoBlobID Id;
const ui32 Shift;
const ui32 Size;
- ssize_t PartMapIndex = -1;
+ ssize_t PartMapIndex = -1;
TDiskGetRequest(const TLogoBlobID &id, const ui32 shift, const ui32 size)
: Id(id)
@@ -158,8 +158,8 @@ struct TBlackboard;
class IStrategy {
public:
- virtual ~IStrategy() = default;
- virtual EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ virtual ~IStrategy() = default;
+ virtual EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
TBlackboard &blackboard, TGroupDiskRequests &groupDiskRequests) = 0;
};
@@ -169,24 +169,24 @@ struct TBlackboard {
AccelerationModeSkipMarked
};
- using TBlobStates = TMap<TLogoBlobID, TBlobState>;
- TBlobStates BlobStates;
+ using TBlobStates = TMap<TLogoBlobID, TBlobState>;
+ TBlobStates BlobStates;
TBlobStates DoneBlobStates;
TGroupDiskRequests GroupDiskRequests;
TIntrusivePtr<TBlobStorageGroupInfo> Info;
- TIntrusivePtr<TGroupQueues> GroupQueues; // To obtain FlowRecords only
+ TIntrusivePtr<TGroupQueues> GroupQueues; // To obtain FlowRecords only
EAccelerationMode AccelerationMode;
const NKikimrBlobStorage::EPutHandleClass PutHandleClass;
const NKikimrBlobStorage::EGetHandleClass GetHandleClass;
const bool IsAllRequestsTogether;
ui64 DoneCount = 0;
- TBlackboard(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &groupQueues,
+ TBlackboard(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &groupQueues,
NKikimrBlobStorage::EPutHandleClass putHandleClass, NKikimrBlobStorage::EGetHandleClass getHandleClass,
bool isAllRequestsTogether = true)
: GroupDiskRequests(info->GetTotalVDisksNum())
, Info(info)
- , GroupQueues(groupQueues)
+ , GroupQueues(groupQueues)
, AccelerationMode(AccelerationModeSkipOneSlowest)
, PutHandleClass(putHandleClass)
, GetHandleClass(getHandleClass)
@@ -202,11 +202,11 @@ struct TBlackboard {
void AddNoDataResponse(const TLogoBlobID &id, ui32 orderNumber);
void AddErrorResponse(const TLogoBlobID &id, ui32 orderNumber);
void AddNotYetResponse(const TLogoBlobID &id, ui32 orderNumber);
- EStrategyOutcome RunStrategy(TLogContext &logCtx, const IStrategy& s, TBatchedVec<TBlobStates::value_type*> *finished = nullptr);
+ EStrategyOutcome RunStrategy(TLogContext &logCtx, const IStrategy& s, TBatchedVec<TBlobStates::value_type*> *finished = nullptr);
TBlobState& GetState(const TLogoBlobID &id);
- ssize_t AddPartMap(const TLogoBlobID &id, ui32 diskOrderNumber, ui32 requestIndex);
- void ReportPartMapStatus(const TLogoBlobID &id, ssize_t partMapIndex, ui32 responseIndex, NKikimrProto::EReplyStatus status);
- void GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
+ ssize_t AddPartMap(const TLogoBlobID &id, ui32 diskOrderNumber, ui32 requestIndex);
+ void ReportPartMapStatus(const TLogoBlobID &id, ssize_t partMapIndex, ui32 responseIndex, NKikimrProto::EReplyStatus status);
+ void GetWorstPredictedDelaysNs(const TBlobStorageGroupInfo &info, TGroupQueues &groupQueues,
NKikimrBlobStorage::EVDiskQueueId queueId,
ui64 *outWorstNs, ui64 *outNextToWorstNs, i32 *outWorstOrderNumber) const;
TString ToString() const;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h b/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
index 147083490be..133c1e0f7e9 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_blob_tracker.h
@@ -1,109 +1,109 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
-
-namespace NKikimr {
-
- class TBlobStatusTracker {
- TLogoBlobID FullId;
-
- TSubgroupPartLayout PresentParts;
-
- // a mask of faulty disks in subgroup
- TBlobStorageGroupInfo::TSubgroupVDisks FaultyDisks;
-
- TIngress Ingress;
- bool HasIngress = true;
-
- public:
- TBlobStatusTracker(const TLogoBlobID& fullId, const TBlobStorageGroupInfo *info)
- : FullId(fullId)
+
+namespace NKikimr {
+
+ class TBlobStatusTracker {
+ TLogoBlobID FullId;
+
+ TSubgroupPartLayout PresentParts;
+
+ // a mask of faulty disks in subgroup
+ TBlobStorageGroupInfo::TSubgroupVDisks FaultyDisks;
+
+ TIngress Ingress;
+ bool HasIngress = true;
+
+ public:
+ TBlobStatusTracker(const TLogoBlobID& fullId, const TBlobStorageGroupInfo *info)
+ : FullId(fullId)
, FaultyDisks(&info->GetTopology())
- {}
-
+ {}
+
void Output(IOutputStream& str, const TBlobStorageGroupInfo *info) const {
- str << "{FullId# " << FullId.ToString() << " PresentParts# ";
+ str << "{FullId# " << FullId.ToString() << " PresentParts# ";
PresentParts.Output(str, info->Type);
- str << " FaultyDisks# ";
- FaultyDisks.Output(str);
- if (HasIngress) {
- str << " Ingress# " << Ingress.Raw();
- }
- str << "}";
- }
-
- void UpdateFromResponseData(const NKikimrBlobStorage::TQueryResult& result, const TVDiskID& vdisk,
- const TBlobStorageGroupInfo *info) {
- // ensure that we have blob id set in reply and that it matches stored one, which we are processing
- Y_VERIFY(result.HasBlobID());
- const TLogoBlobID id = LogoBlobIDFromLogoBlobID(result.GetBlobID());
- Y_VERIFY(id.FullID() == FullId);
-
- // check the status
- Y_VERIFY(result.HasStatus());
- const NKikimrProto::EReplyStatus status = result.GetStatus();
-
- // get the node id for this blob and check the part index
- ui32 nodeId = info->GetIdxInSubgroup(vdisk, FullId.Hash());
-
- // merge the ingress
- Ingress.Merge(TIngress(result.GetIngress()));
- HasIngress = HasIngress && result.HasIngress();
-
- if (result.HasIngress() && !id.PartId()) { // extract local parts from ingress when there is no specific part reply
- TIngress ingress(result.GetIngress());
- NMatrix::TVectorType parts = ingress.LocalParts(info->Type);
- for (ui8 partIdx = parts.FirstPosition(); partIdx != parts.GetSize(); partIdx = parts.NextPosition(partIdx)) {
- PresentParts.AddItem(nodeId, partIdx, info->Type);
- }
- }
-
- switch (status) {
- case NKikimrProto::OK: {
- const ui32 partId = id.PartId();
- if (partId > 0) {
+ str << " FaultyDisks# ";
+ FaultyDisks.Output(str);
+ if (HasIngress) {
+ str << " Ingress# " << Ingress.Raw();
+ }
+ str << "}";
+ }
+
+ void UpdateFromResponseData(const NKikimrBlobStorage::TQueryResult& result, const TVDiskID& vdisk,
+ const TBlobStorageGroupInfo *info) {
+ // ensure that we have blob id set in reply and that it matches stored one, which we are processing
+ Y_VERIFY(result.HasBlobID());
+ const TLogoBlobID id = LogoBlobIDFromLogoBlobID(result.GetBlobID());
+ Y_VERIFY(id.FullID() == FullId);
+
+ // check the status
+ Y_VERIFY(result.HasStatus());
+ const NKikimrProto::EReplyStatus status = result.GetStatus();
+
+ // get the node id for this blob and check the part index
+ ui32 nodeId = info->GetIdxInSubgroup(vdisk, FullId.Hash());
+
+ // merge the ingress
+ Ingress.Merge(TIngress(result.GetIngress()));
+ HasIngress = HasIngress && result.HasIngress();
+
+ if (result.HasIngress() && !id.PartId()) { // extract local parts from ingress when there is no specific part reply
+ TIngress ingress(result.GetIngress());
+ NMatrix::TVectorType parts = ingress.LocalParts(info->Type);
+ for (ui8 partIdx = parts.FirstPosition(); partIdx != parts.GetSize(); partIdx = parts.NextPosition(partIdx)) {
+ PresentParts.AddItem(nodeId, partIdx, info->Type);
+ }
+ }
+
+ switch (status) {
+ case NKikimrProto::OK: {
+ const ui32 partId = id.PartId();
+ if (partId > 0) {
PresentParts.AddItem(nodeId, partId - 1, info->Type);
- }
- break;
- }
-
- case NKikimrProto::NODATA:
- break;
-
+ }
+ break;
+ }
+
+ case NKikimrProto::NODATA:
+ break;
+
case NKikimrProto::NOT_YET:
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
FaultyDisks += TBlobStorageGroupInfo::TSubgroupVDisks(&info->GetTopology(), nodeId);
- break;
-
- default:
+ break;
+
+ default:
Y_FAIL("unexpected blob status# %s", NKikimrProto::EReplyStatus_Name(status).data());
- }
- }
-
- TBlobStorageGroupInfo::EBlobState GetBlobState(const TBlobStorageGroupInfo *info, bool *lostByIngress) const {
- const auto& checker = info->GetQuorumChecker();
- TBlobStorageGroupInfo::EBlobState state = checker.GetBlobState(PresentParts, FaultyDisks);
-
- // check if the blob was completely written according to returned Ingress information
- const bool fullByIngress = HasIngress &&
+ }
+ }
+
+ TBlobStorageGroupInfo::EBlobState GetBlobState(const TBlobStorageGroupInfo *info, bool *lostByIngress) const {
+ const auto& checker = info->GetQuorumChecker();
+ TBlobStorageGroupInfo::EBlobState state = checker.GetBlobState(PresentParts, FaultyDisks);
+
+ // check if the blob was completely written according to returned Ingress information
+ const bool fullByIngress = HasIngress &&
checker.GetBlobState(TSubgroupPartLayout::CreateFromIngress(Ingress, info->Type),
TBlobStorageGroupInfo::TSubgroupVDisks(&info->GetTopology())) == TBlobStorageGroupInfo::EBS_FULL;
-
- // in case we have an ingress and we don't have all the replicas, we can update the state accoring to ingress
- // by finding out if the blob was seen on all disks
- if (state == TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY && !fullByIngress) {
- state = TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED;
- }
-
- if (lostByIngress) {
- *lostByIngress = state == TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY && fullByIngress;
- }
-
- return state;
- }
- };
-
-} // NKikimr
+
+ // in case we have an ingress and we don't have all the replicas, we can update the state accoring to ingress
+ // by finding out if the blob was seen on all disks
+ if (state == TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY && !fullByIngress) {
+ state = TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED;
+ }
+
+ if (lostByIngress) {
+ *lostByIngress = state == TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY && fullByIngress;
+ }
+
+ return state;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_block.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_block.cpp
index dba0a2fd434..df528753309 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_block.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_block.cpp
@@ -1,6 +1,6 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
+#include "dsproxy_quorum_tracker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
@@ -11,25 +11,25 @@ namespace NKikimr {
// TODO: Both block and get block must operate in terms of FailDomains, not VDisks
// TODO: Get response should wait for 2 copies on mirror, not 1
-class TBlobStorageGroupBlockRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupBlockRequest> {
+class TBlobStorageGroupBlockRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupBlockRequest> {
const ui64 TabletId;
const ui32 Generation;
const TInstant Deadline;
- const ui64 IssuerGuid;
+ const ui64 IssuerGuid;
TInstant StartTime;
- bool SeenAlready = false;
+ bool SeenAlready = false;
- TGroupQuorumTracker QuorumTracker;
+ TGroupQuorumTracker QuorumTracker;
- void Handle(TEvBlobStorage::TEvVBlockResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
+ void Handle(TEvBlobStorage::TEvVBlockResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
const NKikimrBlobStorage::TEvVBlockResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
const NKikimrProto::EReplyStatus status = record.GetStatus();
Y_VERIFY(record.HasVDiskID());
const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
const TVDiskIdShort shortId(ev->Cookie);
-
+
Y_VERIFY(shortId.FailRealm == vdisk.FailRealm &&
shortId.FailDomain == vdisk.FailDomain &&
shortId.VDisk == vdisk.VDisk,
@@ -43,140 +43,140 @@ class TBlobStorageGroupBlockRequest : public TBlobStorageGroupRequestActor<TBlob
<< " From# " << vdisk.ToString()
<< " NodeId# " << Info->GetActorId(vdisk).NodeId());
- Process(status, vdisk, record.HasIncarnationGuid() ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
- }
-
- void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- const auto& record = ev->Get()->Record;
- if (record.HasStatus() && record.HasVDiskID()) {
- Process(record.GetStatus(), VDiskIDFromVDiskID(record.GetVDiskID()), record.HasIncarnationGuid()
- ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
- }
- }
-
- void Process(NKikimrProto::EReplyStatus status, const TVDiskID& vdisk, std::optional<ui64> incarnationGuid) {
- std::vector<TVDiskID> queryStatus, resend;
- if (status == NKikimrProto::ALREADY) {
- // ALREADY means that newly arrived Block is the same or older than existing one; we treat it as ERROR here
- // and reply with RACE only when no quorum could be obtained during the whole operation
- SeenAlready = true;
- status = NKikimrProto::ERROR;
- }
- switch (NKikimrProto::EReplyStatus newStatus = incarnationGuid
- ? QuorumTracker.ProcessReplyWithCooldown(vdisk, status, TActivationContext::Now(), *incarnationGuid, queryStatus, resend)
- : QuorumTracker.ProcessReply(vdisk, status)) {
- case NKikimrProto::OK:
- return ReplyAndDie(newStatus);
-
- case NKikimrProto::UNKNOWN:
- break;
+ Process(status, vdisk, record.HasIncarnationGuid() ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ const auto& record = ev->Get()->Record;
+ if (record.HasStatus() && record.HasVDiskID()) {
+ Process(record.GetStatus(), VDiskIDFromVDiskID(record.GetVDiskID()), record.HasIncarnationGuid()
+ ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
+ }
+ }
+
+ void Process(NKikimrProto::EReplyStatus status, const TVDiskID& vdisk, std::optional<ui64> incarnationGuid) {
+ std::vector<TVDiskID> queryStatus, resend;
+ if (status == NKikimrProto::ALREADY) {
+ // ALREADY means that newly arrived Block is the same or older than existing one; we treat it as ERROR here
+ // and reply with RACE only when no quorum could be obtained during the whole operation
+ SeenAlready = true;
+ status = NKikimrProto::ERROR;
+ }
+ switch (NKikimrProto::EReplyStatus newStatus = incarnationGuid
+ ? QuorumTracker.ProcessReplyWithCooldown(vdisk, status, TActivationContext::Now(), *incarnationGuid, queryStatus, resend)
+ : QuorumTracker.ProcessReply(vdisk, status)) {
+ case NKikimrProto::OK:
+ return ReplyAndDie(newStatus);
+
+ case NKikimrProto::UNKNOWN:
+ break;
case NKikimrProto::ERROR: {
TStringStream err;
- newStatus = SeenAlready ? NKikimrProto::RACE : NKikimrProto::ERROR;
- err << "Status# " << NKikimrProto::EReplyStatus_Name(newStatus)
+ newStatus = SeenAlready ? NKikimrProto::RACE : NKikimrProto::ERROR;
+ err << "Status# " << NKikimrProto::EReplyStatus_Name(newStatus)
<< " From# " << vdisk.ToString()
<< " NodeId# " << Info->GetActorId(vdisk).NodeId()
<< " QuorumTracker# ";
QuorumTracker.Output(err);
ErrorReason = err.Str();
- return ReplyAndDie(newStatus);
+ return ReplyAndDie(newStatus);
}
- default:
+ default:
Y_FAIL("unexpected newStatus# %s", NKikimrProto::EReplyStatus_Name(newStatus).data());
}
- for (const TVDiskID& vdiskId : queryStatus) {
- SendToQueue(std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId), 0, NWilson::TTraceId());
- }
- for (const TVDiskID& vdiskId : resend) {
- SendBlockRequest(vdiskId);
- }
+ for (const TVDiskID& vdiskId : queryStatus) {
+ SendToQueue(std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId), 0, NWilson::TTraceId());
+ }
+ for (const TVDiskID& vdiskId : resend) {
+ SendBlockRequest(vdiskId);
+ }
}
- friend class TBlobStorageGroupRequestActor<TBlobStorageGroupBlockRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvBlockResult> result(new TEvBlobStorage::TEvBlockResult(status));
+ friend class TBlobStorageGroupRequestActor<TBlobStorageGroupBlockRequest>;
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ std::unique_ptr<TEvBlobStorage::TEvBlockResult> result(new TEvBlobStorage::TEvBlockResult(status));
result->ErrorReason = ErrorReason;
A_LOG_LOG_S(true, PriorityForStatusResult(status), "DSPB04", "Result# " << result->Print(false));
- Mon->CountBlockResponseTime(TActivationContext::Now() - StartTime);
- return SendResponseAndDie(std::move(result));
- }
-
- void SendBlockRequest(const TVDiskID& vdiskId) {
- const ui64 cookie = TVDiskIdShort(vdiskId).GetRaw();
-
- A_LOG_DEBUG_S("DSPB03", "Sending TEvVBlock Tablet# " << TabletId
- << " Generation# " << Generation
- << " vdiskId# " << vdiskId
- << " node# " << Info->GetActorId(vdiskId).NodeId());
-
- auto msg = std::make_unique<TEvBlobStorage::TEvVBlock>(TabletId, Generation, vdiskId, Deadline, IssuerGuid);
- SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartBlock;
- auto ev = std::make_unique<TEvBlobStorage::TEvBlock>(TabletId, Generation, Deadline, IssuerGuid);
- ev->RestartCounter = counter;
- return ev;
+ Mon->CountBlockResponseTime(TActivationContext::Now() - StartTime);
+ return SendResponseAndDie(std::move(result));
}
+ void SendBlockRequest(const TVDiskID& vdiskId) {
+ const ui64 cookie = TVDiskIdShort(vdiskId).GetRaw();
+
+ A_LOG_DEBUG_S("DSPB03", "Sending TEvVBlock Tablet# " << TabletId
+ << " Generation# " << Generation
+ << " vdiskId# " << vdiskId
+ << " node# " << Info->GetActorId(vdiskId).NodeId());
+
+ auto msg = std::make_unique<TEvBlobStorage::TEvVBlock>(TabletId, Generation, vdiskId, Deadline, IssuerGuid);
+ SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
+ }
+
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartBlock;
+ auto ev = std::make_unique<TEvBlobStorage::TEvBlock>(TabletId, Generation, Deadline, IssuerGuid);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_BLOCK;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveBlock;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_BLOCK;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveBlock;
+ }
+
TBlobStorageGroupBlockRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
ui64 cookie, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
- NKikimrServices::BS_PROXY_BLOCK, false, {}, now, storagePoolCounters, ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
+ NKikimrServices::BS_PROXY_BLOCK, false, {}, now, storagePoolCounters, ev->RestartCounter)
, TabletId(ev->TabletId)
, Generation(ev->Generation)
, Deadline(ev->Deadline)
- , IssuerGuid(ev->IssuerGuid)
+ , IssuerGuid(ev->IssuerGuid)
, StartTime(now)
- , QuorumTracker(Info.Get())
- {}
+ , QuorumTracker(Info.Get())
+ {}
- void Bootstrap() {
+ void Bootstrap() {
A_LOG_DEBUG_S("DSPB05", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " TabletId# " << TabletId
- << " Generation# " << Generation
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
- for (const auto& vdisk : Info->GetVDisks()) {
- SendBlockRequest(Info->GetVDiskId(vdisk.OrderNumber));
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " TabletId# " << TabletId
+ << " Generation# " << Generation
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
+ for (const auto& vdisk : Info->GetVDisks()) {
+ SendBlockRequest(Info->GetVDiskId(vdisk.OrderNumber));
}
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVBlockResult, Handle);
- hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
+ hFunc(TEvBlobStorage::TEvVBlockResult, Handle);
+ hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupBlockRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvBlock *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupBlockRequest(info, state, source, mon, ev, cookie, now, storagePoolCounters);
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_collect.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_collect.cpp
index d12c819a745..fd73af218c3 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_collect.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_collect.cpp
@@ -1,6 +1,6 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
+#include "dsproxy_quorum_tracker.h"
#include <ydb/core/blobstorage/base/utility.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
@@ -12,27 +12,27 @@ namespace NKikimr {
// Blobs with generation < CollectGeneration, or generation == CollectGeneration and step <= CollectStep are collected.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class TBlobStorageGroupCollectGarbageRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupCollectGarbageRequest> {
+class TBlobStorageGroupCollectGarbageRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupCollectGarbageRequest> {
const ui64 TabletId;
const ui32 RecordGeneration;
const ui32 PerGenerationCounter;
const ui32 Channel;
const TInstant Deadline;
- std::unique_ptr<TVector<TLogoBlobID> > Keep;
- std::unique_ptr<TVector<TLogoBlobID> > DoNotKeep;
+ std::unique_ptr<TVector<TLogoBlobID> > Keep;
+ std::unique_ptr<TVector<TLogoBlobID> > DoNotKeep;
const ui32 CollectGeneration;
const ui32 CollectStep;
- const bool Hard;
+ const bool Hard;
const bool Collect;
- TGroupQuorumTracker QuorumTracker;
+ TGroupQuorumTracker QuorumTracker;
TInstant StartTime;
ui32 RequestsSent = 0;
ui32 ResponsesReceived = 0;
- void Handle(TEvBlobStorage::TEvVCollectGarbageResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
+ void Handle(TEvBlobStorage::TEvVCollectGarbageResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
ResponsesReceived++;
const NKikimrBlobStorage::TEvVCollectGarbageResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
@@ -40,40 +40,40 @@ class TBlobStorageGroupCollectGarbageRequest : public TBlobStorageGroupRequestAc
Y_VERIFY(record.HasVDiskID());
const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
- A_LOG_LOG_S(false, PriorityForStatusInbound(status), "DSPC01", "received"
- << " TEvVCollectGarbageResult# " << ev->Get()->ToString());
-
- Process(status, vdisk, record.HasIncarnationGuid() ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
- CheckProgress();
- }
-
- void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- ResponsesReceived++;
- const auto& record = ev->Get()->Record;
- if (record.HasStatus() && record.HasVDiskID()) {
- Process(record.GetStatus(), VDiskIDFromVDiskID(record.GetVDiskID()), record.HasIncarnationGuid()
- ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
- }
- CheckProgress();
- }
-
- void Process(NKikimrProto::EReplyStatus status, const TVDiskID& vdisk, std::optional<ui64> incarnationGuid) {
- std::vector<TVDiskID> queryStatus, resend;
- // replace already status to be treated as non-terminating OK for this kind of request
- status = status != NKikimrProto::ALREADY ? status : NKikimrProto::OK;
- switch (NKikimrProto::EReplyStatus newStatus = incarnationGuid
- ? QuorumTracker.ProcessReplyWithCooldown(vdisk, status, TActivationContext::Now(), *incarnationGuid, queryStatus, resend)
- : QuorumTracker.ProcessReply(vdisk, status)) {
- case NKikimrProto::OK:
- return ReplyAndDie(newStatus);
-
- case NKikimrProto::UNKNOWN:
- break;
-
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
- case NKikimrProto::OUT_OF_SPACE:
+ A_LOG_LOG_S(false, PriorityForStatusInbound(status), "DSPC01", "received"
+ << " TEvVCollectGarbageResult# " << ev->Get()->ToString());
+
+ Process(status, vdisk, record.HasIncarnationGuid() ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
+ CheckProgress();
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ ResponsesReceived++;
+ const auto& record = ev->Get()->Record;
+ if (record.HasStatus() && record.HasVDiskID()) {
+ Process(record.GetStatus(), VDiskIDFromVDiskID(record.GetVDiskID()), record.HasIncarnationGuid()
+ ? std::make_optional(record.GetIncarnationGuid()) : std::nullopt);
+ }
+ CheckProgress();
+ }
+
+ void Process(NKikimrProto::EReplyStatus status, const TVDiskID& vdisk, std::optional<ui64> incarnationGuid) {
+ std::vector<TVDiskID> queryStatus, resend;
+ // replace already status to be treated as non-terminating OK for this kind of request
+ status = status != NKikimrProto::ALREADY ? status : NKikimrProto::OK;
+ switch (NKikimrProto::EReplyStatus newStatus = incarnationGuid
+ ? QuorumTracker.ProcessReplyWithCooldown(vdisk, status, TActivationContext::Now(), *incarnationGuid, queryStatus, resend)
+ : QuorumTracker.ProcessReply(vdisk, status)) {
+ case NKikimrProto::OK:
+ return ReplyAndDie(newStatus);
+
+ case NKikimrProto::UNKNOWN:
+ break;
+
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ case NKikimrProto::OUT_OF_SPACE:
{
TStringStream str;
str << "Processed status# " << status << " from VDisk# " << vdisk;
@@ -85,66 +85,66 @@ class TBlobStorageGroupCollectGarbageRequest : public TBlobStorageGroupRequestAc
str << " QuorumTracker status# " << newStatus;
ErrorReason = str.Str();
}
- return ReplyAndDie(NKikimrProto::ERROR);
+ return ReplyAndDie(NKikimrProto::ERROR);
- default:
+ default:
Y_FAIL("unexpected newStatus# %s", NKikimrProto::EReplyStatus_Name(newStatus).data());
}
- for (const TVDiskID& vdiskId : queryStatus) {
- SendToQueue(std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId), 0, NWilson::TTraceId());
- RequestsSent++;
- }
- for (const TVDiskID& vdiskId : resend) {
- SendCollectGarbageRequest(vdiskId);
- }
- }
-
- void CheckProgress() {
- Y_VERIFY(Dead || ResponsesReceived < RequestsSent, "No more unreplied vdisk requests!"
- " QuorumTracker# %s RequestsSent# %" PRIu32 " ResponsesReceived# %" PRIu32,
- QuorumTracker.ToString().c_str(), RequestsSent, ResponsesReceived);
+ for (const TVDiskID& vdiskId : queryStatus) {
+ SendToQueue(std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId), 0, NWilson::TTraceId());
+ RequestsSent++;
+ }
+ for (const TVDiskID& vdiskId : resend) {
+ SendCollectGarbageRequest(vdiskId);
+ }
+ }
+
+ void CheckProgress() {
+ Y_VERIFY(Dead || ResponsesReceived < RequestsSent, "No more unreplied vdisk requests!"
+ " QuorumTracker# %s RequestsSent# %" PRIu32 " ResponsesReceived# %" PRIu32,
+ QuorumTracker.ToString().c_str(), RequestsSent, ResponsesReceived);
}
- friend class TBlobStorageGroupRequestActor<TBlobStorageGroupCollectGarbageRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- auto result = std::make_unique<TEvBlobStorage::TEvCollectGarbageResult>(status, TabletId, RecordGeneration,
- PerGenerationCounter, Channel);
+ friend class TBlobStorageGroupRequestActor<TBlobStorageGroupCollectGarbageRequest>;
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ auto result = std::make_unique<TEvBlobStorage::TEvCollectGarbageResult>(status, TabletId, RecordGeneration,
+ PerGenerationCounter, Channel);
result->ErrorReason = ErrorReason;
- A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSPC02", "Result# " << result->Print(false));
- SendResponseAndDie(std::move(result));
- }
-
- void SendCollectGarbageRequest(const TVDiskID& vdiskId) {
- const ui64 cookie = TVDiskIdShort(vdiskId).GetRaw();
- auto msg = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(TabletId, RecordGeneration, PerGenerationCounter,
- Channel, Collect, CollectGeneration, CollectStep, Hard, Keep.get(), DoNotKeep.get(), vdiskId, Deadline);
- SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
- RequestsSent++;
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartCollectGarbage;
- auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, RecordGeneration, PerGenerationCounter,
- Channel, Collect, CollectGeneration, CollectStep, Keep.release(), DoNotKeep.release(), Deadline, false, Hard);
- ev->RestartCounter = counter;
- return ev;
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSPC02", "Result# " << result->Print(false));
+ SendResponseAndDie(std::move(result));
}
+ void SendCollectGarbageRequest(const TVDiskID& vdiskId) {
+ const ui64 cookie = TVDiskIdShort(vdiskId).GetRaw();
+ auto msg = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(TabletId, RecordGeneration, PerGenerationCounter,
+ Channel, Collect, CollectGeneration, CollectStep, Hard, Keep.get(), DoNotKeep.get(), vdiskId, Deadline);
+ SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
+ RequestsSent++;
+ }
+
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartCollectGarbage;
+ auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, RecordGeneration, PerGenerationCounter,
+ Channel, Collect, CollectGeneration, CollectStep, Keep.release(), DoNotKeep.release(), Deadline, false, Hard);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_COLLECT_GARBAGE;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveCollectGarbage;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_COLLECT_GARBAGE;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveCollectGarbage;
+ }
+
TBlobStorageGroupCollectGarbageRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev, ui64 cookie,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev, ui64 cookie,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
- NKikimrServices::BS_PROXY_COLLECT, false, {}, now, storagePoolCounters, ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
+ NKikimrServices::BS_PROXY_COLLECT, false, {}, now, storagePoolCounters, ev->RestartCounter)
, TabletId(ev->TabletId)
, RecordGeneration(ev->RecordGeneration)
, PerGenerationCounter(ev->PerGenerationCounter)
@@ -154,56 +154,56 @@ public:
, DoNotKeep(ev->DoNotKeep.Release())
, CollectGeneration(ev->CollectGeneration)
, CollectStep(ev->CollectStep)
- , Hard(ev->Hard)
+ , Hard(ev->Hard)
, Collect(ev->Collect)
- , QuorumTracker(Info.Get())
+ , QuorumTracker(Info.Get())
, StartTime(now)
- {}
-
- void Bootstrap() {
- A_LOG_INFO_S("DSPC03", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " TabletId# " << TabletId
- << " Channel# " << Channel
- << " RecordGeneration# " << RecordGeneration
- << " PerGenerationCounter# " << PerGenerationCounter
- << " Deadline# " << Deadline
- << " CollectGeneration# " << CollectGeneration
- << " CollectStep# " << CollectStep
- << " Collect# " << (Collect ? "true" : "false")
- << " Hard# " << (Hard ? "true" : "false")
- << " RestartCounter# " << RestartCounter);
-
- for (const auto& item : Keep ? *Keep : TVector<TLogoBlobID>()) {
- A_LOG_INFO_S("DSPC04", "Keep# " << item);
- }
-
- for (const auto& item : DoNotKeep ? *DoNotKeep : TVector<TLogoBlobID>()) {
- A_LOG_INFO_S("DSPC05", "DoNotKeep# " << item);
- }
-
- for (const auto& vdisk : Info->GetVDisks()) {
- SendCollectGarbageRequest(Info->GetVDiskId(vdisk.OrderNumber));
+ {}
+
+ void Bootstrap() {
+ A_LOG_INFO_S("DSPC03", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " TabletId# " << TabletId
+ << " Channel# " << Channel
+ << " RecordGeneration# " << RecordGeneration
+ << " PerGenerationCounter# " << PerGenerationCounter
+ << " Deadline# " << Deadline
+ << " CollectGeneration# " << CollectGeneration
+ << " CollectStep# " << CollectStep
+ << " Collect# " << (Collect ? "true" : "false")
+ << " Hard# " << (Hard ? "true" : "false")
+ << " RestartCounter# " << RestartCounter);
+
+ for (const auto& item : Keep ? *Keep : TVector<TLogoBlobID>()) {
+ A_LOG_INFO_S("DSPC04", "Keep# " << item);
+ }
+
+ for (const auto& item : DoNotKeep ? *DoNotKeep : TVector<TLogoBlobID>()) {
+ A_LOG_INFO_S("DSPC05", "DoNotKeep# " << item);
+ }
+
+ for (const auto& vdisk : Info->GetVDisks()) {
+ SendCollectGarbageRequest(Info->GetVDiskId(vdisk.OrderNumber));
}
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVCollectGarbageResult, Handle);
- hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
+ hFunc(TEvBlobStorage::TEvVCollectGarbageResult, Handle);
+ hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupCollectGarbageRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupCollectGarbageRequest(info, state, source, mon, ev, cookie, now, storagePoolCounters);
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp
index 2605a19a2e9..cc9be278011 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_discover.cpp
@@ -1,5 +1,5 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
@@ -235,7 +235,7 @@ struct TGroupResponseTracker {
};
-class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupDiscoverRequest>{
+class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupDiscoverRequest>{
struct TBlobInfo {
TLogoBlobID Id;
@@ -272,16 +272,16 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
const ui64 TabletId;
const ui32 MinGeneration;
const bool ReadBody;
- const bool DiscoverBlockedGeneration;
+ const bool DiscoverBlockedGeneration;
const TInstant Deadline;
const TInstant StartTime;
TGroupResponseTracker GroupResponseTracker;
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> PendingResult;
-
- ui32 GetBlockReplies = 0;
- ui32 GetBlockErrors = 0;
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> PendingResult;
+ ui32 GetBlockReplies = 0;
+ ui32 GetBlockErrors = 0;
+
ui32 BlockedGen = 0;
ui32 VGetBlockedGen = 0;
bool IsGetBlockDone;
@@ -293,31 +293,31 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
const ui32 ForceBlockedGeneration;
- template<typename TPtr>
- void SendResult(TPtr& result) {
- Y_VERIFY(result);
- const TDuration duration = TActivationContext::Now() - StartTime;
+ template<typename TPtr>
+ void SendResult(TPtr& result) {
+ Y_VERIFY(result);
+ const TDuration duration = TActivationContext::Now() - StartTime;
Mon->CountDiscoverResponseTime(duration);
- const bool success = result->Status == NKikimrProto::OK;
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvDiscoverResultSent);
+ const bool success = result->Status == NKikimrProto::OK;
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvDiscoverResultSent);
LWPROBE(DSProxyRequestDuration, TEvBlobStorage::EvDiscover, 0, duration.SecondsFloat() * 1000.0,
TabletId, Info->GroupID, TLogoBlobID::MaxChannel, "", success);
- SendResponseAndDie(std::move(result));
- }
-
- friend class TBlobStorageGroupRequestActor<TBlobStorageGroupDiscoverRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(new TEvBlobStorage::TEvDiscoverResult(status, MinGeneration,
+ SendResponseAndDie(std::move(result));
+ }
+
+ friend class TBlobStorageGroupRequestActor<TBlobStorageGroupDiscoverRequest>;
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(new TEvBlobStorage::TEvDiscoverResult(status, MinGeneration,
BlockedGen));
result->ErrorReason = ErrorReason;
- A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "BSD01", "Result# " << result->Print(false));
- SendResult(result);
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "BSD01", "Result# " << result->Print(false));
+ SendResult(result);
}
- void Handle(TEvBlobStorage::TEvVGetBlockResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetBlockResultReceived, MergedNode = std::move(ev->TraceId));
-
+ void Handle(TEvBlobStorage::TEvVGetBlockResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetBlockResultReceived, MergedNode = std::move(ev->TraceId));
+
TotalRecieved++;
NKikimrBlobStorage::TEvVGetBlockResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
@@ -329,59 +329,59 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
Y_VERIFY(status == NKikimrProto::OK || status == NKikimrProto::NODATA || status == NKikimrProto::ERROR
|| status == NKikimrProto::VDISK_ERROR_STATE, "status# %" PRIu32, ui32(status));
- A_LOG_LOG_S(false, PriorityForStatusInbound(status), "BSD03",
+ A_LOG_LOG_S(false, PriorityForStatusInbound(status), "BSD03",
"Status# " << NKikimrProto::EReplyStatus_Name(status)
<< " vdisk# " << vdisk.ToString()
- << " NodeId# " << Info->GetActorId(vdisk).NodeId());
-
- ++GetBlockReplies;
+ << " NodeId# " << Info->GetActorId(vdisk).NodeId());
+
+ ++GetBlockReplies;
if (status == NKikimrProto::NODATA) {
// nothing
} else if (status == NKikimrProto::OK) {
Y_VERIFY(record.HasGeneration());
BlockedGen = Max(BlockedGen, record.GetGeneration());
} else if (status == NKikimrProto::ERROR || status == NKikimrProto::VDISK_ERROR_STATE) {
- ++GetBlockErrors;
+ ++GetBlockErrors;
} else {
Y_FAIL("status: %s" , NKikimrProto::EReplyStatus_Name(status).data());
}
- // Not Minimal Restorable, but minimal needed for write to succseed
- if (!IsGetBlockDone && GetBlockReplies == Info->Type.TotalPartCount()) {
- IsGetBlockDone = true;
- if (IsIterativeDone && (IsGetDataDone || !ReadBody)) {
- A_LOG_LOG_S(true, PriorityForStatusOutbound(PendingResult->Status), "BSD05",
- "Die. Result# "<< PendingResult->Print(false));
- SendResult(PendingResult);
- }
- }
+ // Not Minimal Restorable, but minimal needed for write to succseed
+ if (!IsGetBlockDone && GetBlockReplies == Info->Type.TotalPartCount()) {
+ IsGetBlockDone = true;
+ if (IsIterativeDone && (IsGetDataDone || !ReadBody)) {
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(PendingResult->Status), "BSD05",
+ "Die. Result# "<< PendingResult->Print(false));
+ SendResult(PendingResult);
+ }
+ }
}
- void HandleIgnore(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
-
+ void HandleIgnore(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
+
TotalRecieved++;
NKikimrBlobStorage::TEvVGetResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
const NKikimrProto::EReplyStatus status = record.GetStatus();
- R_LOG_DEBUG_S("BSD29", "Handle TEvVGetResult Ignore"
+ R_LOG_DEBUG_S("BSD29", "Handle TEvVGetResult Ignore"
<< " status# " << NKikimrProto::EReplyStatus_Name(status)
- << " ev# " << ev->Get()->ToString());
+ << " ev# " << ev->Get()->ToString());
Y_VERIFY(TotalRecieved < TotalSent);
return;
}
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
-
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
+
TotalRecieved++;
NKikimrBlobStorage::TEvVGetResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
@@ -400,13 +400,13 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
// todo: reconfigurable channels
VGetBlockedGen = Max(VGetBlockedGen, record.GetBlockedGeneration());
- TVDiskInfo &vDiskData = VDiskInfo.at(TVDiskIdShort(vdisk).GetRaw());
+ TVDiskInfo &vDiskData = VDiskInfo.at(TVDiskIdShort(vdisk).GetRaw());
- A_LOG_LOG_S(false, PriorityForStatusInbound(status), "BSD07", "Handle TEvVGetResult"
+ A_LOG_LOG_S(false, PriorityForStatusInbound(status), "BSD07", "Handle TEvVGetResult"
<< " Status# " << NKikimrProto::EReplyStatus_Name(status)
<< " vdisk# " << vdisk.ToString()
<< " NodeId# " << Info->GetActorId(vdisk).NodeId()
- << " ev# " << ev->Get()->ToString());
+ << " ev# " << ev->Get()->ToString());
vDiskData.IsResponsive = true;
@@ -465,39 +465,39 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
vDiskData.IsAllRead = true;
}
- GroupResponseTracker.OnReply(vdisk, replyStatus);
- if (!StepDiscovery()) {
+ GroupResponseTracker.OnReply(vdisk, replyStatus);
+ if (!StepDiscovery()) {
return;
}
if (TotalRecieved >= TotalSent) {
Sleep(TDuration::Seconds(1));
TStringStream str;
str << " logacc# ";
- LogCtx.LogAcc.Output(str);
+ LogCtx.LogAcc.Output(str);
str << " VERIFY FAILED ";
- str << "Group# " << Info->GroupID << " Discover# " << SelfId().ToString();
+ str << "Group# " << Info->GroupID << " Discover# " << SelfId().ToString();
Y_VERIFY(false, "%s", str.Str().data());
}
Y_VERIFY(TotalRecieved < TotalSent);
}
- bool StepDiscovery() {
+ bool StepDiscovery() {
// We intentionally stop working with too many domain failures, but in theory we can continue working until
// (ring.DomainReplies - ring.DomainSuccess >= Info->Type.MinimalRestorablePartCount())
// Always reply with ERROR if the ring has disintegrated to an unreadable state
- if (GroupResponseTracker.IsUnreadableDisintegrated()) {
- R_LOG_ERROR_S("BSD08", "StepDiscovery Die. Disintegrated."
- << " DomainRequestsSent# " << (ui32)GroupResponseTracker.DomainRequestsSent
- << " DomainReplies# " << (ui32)GroupResponseTracker.DomainReplies
- << " DomainSuccess# " << (ui32)GroupResponseTracker.DomainSuccess
+ if (GroupResponseTracker.IsUnreadableDisintegrated()) {
+ R_LOG_ERROR_S("BSD08", "StepDiscovery Die. Disintegrated."
+ << " DomainRequestsSent# " << (ui32)GroupResponseTracker.DomainRequestsSent
+ << " DomainReplies# " << (ui32)GroupResponseTracker.DomainReplies
+ << " DomainSuccess# " << (ui32)GroupResponseTracker.DomainSuccess
<< " ParityParts# " << (ui32)Info->Type.ParityParts()
- << " Handoff# " << (ui32)Info->Type.Handoff());
+ << " Handoff# " << (ui32)Info->Type.Handoff());
TStringStream str;
str << "Group# " << Info->GroupID << " disintegrated, type A.";
ErrorReason = str.Str();
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return false;
}
@@ -512,55 +512,55 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
for (TVDiskInfoContainer::iterator vDiskIt = VDiskInfo.begin(); vDiskIt != VDiskInfo.end(); ++vDiskIt) {
TVDiskIdShort vId(vDiskIt->first);
- TVDiskInfo &curVDisk = vDiskIt->second;
- if (!curVDisk.IsError && curVDisk.Blobs.size() > 0) {
+ TVDiskInfo &curVDisk = vDiskIt->second;
+ if (!curVDisk.IsError && curVDisk.Blobs.size() > 0) {
TLogoBlobID &last = curVDisk.Blobs.back().Id;
- if (isFirst || stepToId < last) {
- stepToId = TLogoBlobID(last, 0);
- isFirst = false;
+ if (isFirst || stepToId < last) {
+ stepToId = TLogoBlobID(last, 0);
+ isFirst = false;
}
- } else {
- if (!curVDisk.IsError && curVDisk.IsMoreRequested) {
- isAllDisksAbleToStep = false;
- ++unableToStepDiskCount;
+ } else {
+ if (!curVDisk.IsError && curVDisk.IsMoreRequested) {
+ isAllDisksAbleToStep = false;
+ ++unableToStepDiskCount;
}
}
- if (!curVDisk.IsError && !curVDisk.IsAllRead) {
- isAllRead = false;
- }
+ if (!curVDisk.IsError && !curVDisk.IsAllRead) {
+ isAllRead = false;
+ }
}
const ui32 totalPartCount = Info->Type.TotalPartCount();
if (isAllDisksAbleToStep && !isFirst) {
for (TVDiskInfoContainer::iterator vDiskIt = VDiskInfo.begin(); vDiskIt != VDiskInfo.end(); ++vDiskIt) {
TVDiskIdShort vId(vDiskIt->first);
- TVDiskInfo &curVDisk = vDiskIt->second;
- if (!curVDisk.IsError) {
- ui32 blobIdx;
- for (blobIdx = 0; blobIdx < curVDisk.Blobs.size(); ++blobIdx) {
- TLogoBlobID &id = curVDisk.Blobs[blobIdx].Id;
- if (id >= stepToId || isAllRead) {
- // Y_VERIFY(id.PartId() == 0);
- const TLogoBlobID fullid = id.FullID();
+ TVDiskInfo &curVDisk = vDiskIt->second;
+ if (!curVDisk.IsError) {
+ ui32 blobIdx;
+ for (blobIdx = 0; blobIdx < curVDisk.Blobs.size(); ++blobIdx) {
+ TLogoBlobID &id = curVDisk.Blobs[blobIdx].Id;
+ if (id >= stepToId || isAllRead) {
+ // Y_VERIFY(id.PartId() == 0);
+ const TLogoBlobID fullid = id.FullID();
TVDiskID vDiskId(Info->CreateVDiskID(vId));
- TIngress ingress = curVDisk.Blobs[blobIdx].Ingress;
- TEntryInfo &entry = GroupResponseTracker.EntryInfo[fullid];
- entry.RegisterBlob(ingress, Info.Get(), vDiskId, fullid);
- } else {
- break;
+ TIngress ingress = curVDisk.Blobs[blobIdx].Ingress;
+ TEntryInfo &entry = GroupResponseTracker.EntryInfo[fullid];
+ entry.RegisterBlob(ingress, Info.Get(), vDiskId, fullid);
+ } else {
+ break;
}
}
- curVDisk.Blobs.erase(curVDisk.Blobs.begin(), curVDisk.Blobs.begin() + blobIdx);
+ curVDisk.Blobs.erase(curVDisk.Blobs.begin(), curVDisk.Blobs.begin() + blobIdx);
}
}
}
- ui32 unknownCount = GroupResponseTracker.DomainRequestsSent - GroupResponseTracker.DomainSuccess;
+ ui32 unknownCount = GroupResponseTracker.DomainRequestsSent - GroupResponseTracker.DomainSuccess;
ui32 minimalRestorableParts = Info->Type.MinimalRestorablePartCount();
- A_LOG_DEBUG_S("BSD09", "StepDiscovery"
- << " DomainRequestsSent# " << (ui32)GroupResponseTracker.DomainRequestsSent
- << " DomainReplies# " << (ui32)GroupResponseTracker.DomainReplies
- << " DomainSuccess# " << (ui32)GroupResponseTracker.DomainSuccess
+ A_LOG_DEBUG_S("BSD09", "StepDiscovery"
+ << " DomainRequestsSent# " << (ui32)GroupResponseTracker.DomainRequestsSent
+ << " DomainReplies# " << (ui32)GroupResponseTracker.DomainReplies
+ << " DomainSuccess# " << (ui32)GroupResponseTracker.DomainSuccess
<< " ParityParts# " << (ui32)Info->Type.ParityParts()
<< " Handoff# " << (ui32)Info->Type.Handoff()
<< " isAllRead# " << isAllRead
@@ -568,27 +568,27 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< " isFirst# " << isFirst
<< " unknownCount# " << unknownCount
<< " minimalRestorableParts# " << minimalRestorableParts
- << " totalPartCount# " << totalPartCount);
+ << " totalPartCount# " << totalPartCount);
if (unknownCount <= Info->Type.ParityParts()) {
- const ui32 subgroupSize = Info->Type.BlobSubgroupSize();
- for (TEntryInfos::const_iterator it = GroupResponseTracker.EntryInfo.begin();
- it != GroupResponseTracker.EntryInfo.end(); ++it) {
+ const ui32 subgroupSize = Info->Type.BlobSubgroupSize();
+ for (TEntryInfos::const_iterator it = GroupResponseTracker.EntryInfo.begin();
+ it != GroupResponseTracker.EntryInfo.end(); ++it) {
const TEntryInfo &entryInfo = it->second;
const TLogoBlobID &logoBlobId = it->first;
- ui32 seenPartCount = TSubgroupPartLayout::CountEffectiveReplicas(entryInfo.Seen, Info->Type);
- ui32 partCount = TSubgroupPartLayout::CountEffectiveReplicas(entryInfo.Present, Info->Type);
- A_LOG_DEBUG_S("BSD27", "logoBlobId# " << logoBlobId.ToString()
+ ui32 seenPartCount = TSubgroupPartLayout::CountEffectiveReplicas(entryInfo.Seen, Info->Type);
+ ui32 partCount = TSubgroupPartLayout::CountEffectiveReplicas(entryInfo.Present, Info->Type);
+ A_LOG_DEBUG_S("BSD27", "logoBlobId# " << logoBlobId.ToString()
<< " partCount# " << partCount
- << " seenPartCount# " << seenPartCount);
+ << " seenPartCount# " << seenPartCount);
ui32 errorDomains = 0;
if (partCount >= minimalRestorableParts) {
- TBlobStorageGroupInfo::TServiceIds vDisksSvc;
- TBlobStorageGroupInfo::TVDiskIds vDisksId;
- Info->PickSubgroup(logoBlobId.Hash(), &vDisksId, &vDisksSvc);
- for (ui32 idx = 0; idx < subgroupSize; ++idx) {
+ TBlobStorageGroupInfo::TServiceIds vDisksSvc;
+ TBlobStorageGroupInfo::TVDiskIds vDisksId;
+ Info->PickSubgroup(logoBlobId.Hash(), &vDisksId, &vDisksSvc);
+ for (ui32 idx = 0; idx < subgroupSize; ++idx) {
const TVDiskID &id = vDisksId[idx];
- if (VDiskInfo.at(TVDiskIdShort(id).GetRaw()).IsError) {
+ if (VDiskInfo.at(TVDiskIdShort(id).GetRaw()).IsError) {
errorDomains++;
}
}
@@ -601,39 +601,39 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
// (?) do via proxy?
IsIterativeDone = true;
if (ReadBody) {
- std::unique_ptr<TEvBlobStorage::TEvGet> getRequest(new TEvBlobStorage::TEvGet(
- logoBlobId, 0, 0, Deadline, NKikimrBlobStorage::EGetHandleClass::Discover));
+ std::unique_ptr<TEvBlobStorage::TEvGet> getRequest(new TEvBlobStorage::TEvGet(
+ logoBlobId, 0, 0, Deadline, NKikimrBlobStorage::EGetHandleClass::Discover));
getRequest->MustRestoreFirst = true;
getRequest->IsVerboseNoDataEnabled = true;
- getRequest->IsInternal = true;
+ getRequest->IsInternal = true;
getRequest->TabletId = TabletId;
getRequest->AcquireBlockedGeneration = true;
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
- bool isSent = SendToBSProxy(SelfId(), Info->GroupID, getRequest.release(), 0, TraceId.SeparateBranch());
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
+ bool isSent = SendToBSProxy(SelfId(), Info->GroupID, getRequest.release(), 0, TraceId.SeparateBranch());
Y_VERIFY(isSent);
TotalSent++;
- A_LOG_DEBUG_S("BSD10", "Sent EvGet logoBlobId# " << logoBlobId.ToString());
+ A_LOG_DEBUG_S("BSD10", "Sent EvGet logoBlobId# " << logoBlobId.ToString());
Become(&TThis::StateWait);
return true;
} else if (IsGetBlockDone) {
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(
new TEvBlobStorage::TEvDiscoverResult(logoBlobId, MinGeneration, TString(), BlockedGen));
- A_LOG_LOG_S(true, PriorityForStatusOutbound(result->Status), "BSD11", "Die. Result# "
- << result->Print(false));
- SendResult(result);
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(result->Status), "BSD11", "Die. Result# "
+ << result->Print(false));
+ SendResult(result);
return false;
} else {
- PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(
+ PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(
logoBlobId, MinGeneration, TString(), BlockedGen));
- A_LOG_DEBUG_S("BSD12", "Pending result is set, Result# " << PendingResult->ToString());
+ A_LOG_DEBUG_S("BSD12", "Pending result is set, Result# " << PendingResult->ToString());
Become(&TThis::StateWait);
return false;
}
} else if (blobState & TBlobStorageGroupInfo::EBSF_DISINTEGRATED) {
// Reply with error.
- R_LOG_ERROR_S("BSD30", "StepDiscovery Die."
+ R_LOG_ERROR_S("BSD30", "StepDiscovery Die."
<< " Reply with ERROR! "
<< " logoBlobId# " << logoBlobId
<< " seenPartCount# " << seenPartCount
@@ -641,17 +641,17 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< " unknownCount# " << unknownCount
<< " minimalRestorableParts# " << minimalRestorableParts
<< " errorDomains# " << errorDomains
- << " totalPartCount# " << totalPartCount);
+ << " totalPartCount# " << totalPartCount);
TStringStream str;
str << "Group# " << Info->GroupID << " disintegrated, type B.";
ErrorReason = str.Str();
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return false;
}
if (partCount + unknownCount >= totalPartCount) {
// Unknown parts may decide the fate of the data.
- // TODO: consider only the nodes from the logoblobs subgroup here, so that fail domains out of this
- // subgroup, don't trigger false expectations and we successfully detect fantom blob here.
+ // TODO: consider only the nodes from the logoblobs subgroup here, so that fail domains out of this
+ // subgroup, don't trigger false expectations and we successfully detect fantom blob here.
// TIMEOUT also may mean that no definite answer can be obtained
return true;
}
@@ -670,7 +670,7 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< " totalPartCount# " << totalPartCount;
ErrorReason = str.Str();
R_LOG_ERROR_S("BSD28", "StepDiscovery Die. Reply with ERROR! " << ErrorReason);
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return false;
}
// There is not enough data to restore the blob, it must be a fantom
@@ -679,21 +679,21 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
if (isAllRead) {
// We are sure that we got nothing to reprot,
if (IsGetBlockDone) {
- R_LOG_INFO_S("BSD13", "isAllRead and IsGetBlockDone, but nothing to report, respond with NODATA Die.");
- ReplyAndDie(NKikimrProto::NODATA);
+ R_LOG_INFO_S("BSD13", "isAllRead and IsGetBlockDone, but nothing to report, respond with NODATA Die.");
+ ReplyAndDie(NKikimrProto::NODATA);
return false;
}
IsGetDataDone = true;
IsIterativeDone = true;
- PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::NODATA, MinGeneration,
+ PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::NODATA, MinGeneration,
BlockedGen));
- A_LOG_DEBUG_S("BSD14", "isAllRead, setting pending result, response# " << PendingResult->ToString());
+ A_LOG_DEBUG_S("BSD14", "isAllRead, setting pending result, response# " << PendingResult->ToString());
return true;
}
// Nothing found so far. Clear the buffer and continue.
// TODO: discard any data before the 'clearing' threshold (from slowpoke vdisks)
// TODO: don't count the data from the 'bad' domains
- GroupResponseTracker.EntryInfo.clear();
+ GroupResponseTracker.EntryInfo.clear();
GroupResponseTracker.CurrentRequestSize = Min(MaxRequestSize, GroupResponseTracker.CurrentRequestSize * 2);
}
@@ -703,47 +703,47 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
const TLogoBlobID to = TLogoBlobID(TabletId, MinGeneration, 0, 0, 0, 0, 1);
for (TVDiskInfoContainer::iterator vDiskIt = VDiskInfo.begin(); vDiskIt != VDiskInfo.end(); ++vDiskIt) {
TVDiskIdShort vId(vDiskIt->first);
- TVDiskInfo &curVDisk = vDiskIt->second;
+ TVDiskInfo &curVDisk = vDiskIt->second;
TVDiskID vDiskId = Info->CreateVDiskID(vId);
- if (!curVDisk.IsError && !curVDisk.IsAllRead && !curVDisk.IsMoreRequested) {
+ if (!curVDisk.IsError && !curVDisk.IsAllRead && !curVDisk.IsMoreRequested) {
const TActorId &vdisk = Info->GetActorId(vDiskId);
- auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId, Deadline,
- NKikimrBlobStorage::EGetHandleClass::Discover, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
+ auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId, Deadline,
+ NKikimrBlobStorage::EGetHandleClass::Discover, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
{}, curVDisk.nextLogoBlobId, to, GroupResponseTracker.CurrentRequestSize, nullptr,
ForceBlockedGeneration);
- msg->Record.SetSuppressBarrierCheck(true);
- const ui64 cookie = TVDiskIdShort(vDiskId).GetRaw();
- A_LOG_DEBUG_S("BSD15", "Request more data sending TEvVGet Tablet# " << TabletId
- << " vDiskId# " << vDiskId.ToString()
- << " node# " << vdisk.NodeId()
- << " msg# " << msg->ToString()
- << " cookie# " << cookie);
- CountEvent(*msg);
- SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
- TotalSent++;
-
- curVDisk.IsMoreRequested = true;
- curVDisk.LastRequestSize = GroupResponseTracker.CurrentRequestSize;
-
- // Subtract disk's answer from answer counters/reset ready flags
- GroupResponseTracker.AnotherRequest(vDiskId);
- } else {
- A_LOG_DEBUG_S("BSD26", "do not ask more data from vDiskId# " << vDiskId.ToString()
- << " IsError# " << curVDisk.IsError
- << " IsAllRead# " << curVDisk.IsAllRead
- << " IsMoreRequested# " << curVDisk.IsMoreRequested
- << " BlobsSize# " << curVDisk.Blobs.size());
+ msg->Record.SetSuppressBarrierCheck(true);
+ const ui64 cookie = TVDiskIdShort(vDiskId).GetRaw();
+ A_LOG_DEBUG_S("BSD15", "Request more data sending TEvVGet Tablet# " << TabletId
+ << " vDiskId# " << vDiskId.ToString()
+ << " node# " << vdisk.NodeId()
+ << " msg# " << msg->ToString()
+ << " cookie# " << cookie);
+ CountEvent(*msg);
+ SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
+ TotalSent++;
+
+ curVDisk.IsMoreRequested = true;
+ curVDisk.LastRequestSize = GroupResponseTracker.CurrentRequestSize;
+
+ // Subtract disk's answer from answer counters/reset ready flags
+ GroupResponseTracker.AnotherRequest(vDiskId);
+ } else {
+ A_LOG_DEBUG_S("BSD26", "do not ask more data from vDiskId# " << vDiskId.ToString()
+ << " IsError# " << curVDisk.IsError
+ << " IsAllRead# " << curVDisk.IsAllRead
+ << " IsMoreRequested# " << curVDisk.IsMoreRequested
+ << " BlobsSize# " << curVDisk.Blobs.size());
}
}
}
return true;
}
- void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
-
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
+
TotalRecieved++;
TEvBlobStorage::TEvGetResult *msg = ev->Get();
const NKikimrProto::EReplyStatus status = msg->Status;
@@ -757,18 +757,18 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
case NKikimrProto::OK:
IsGetDataDone = true;
if (IsGetBlockDone) {
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result(
new TEvBlobStorage::TEvDiscoverResult(
response.Id, MinGeneration, response.Buffer, BlockedGen));
- A_LOG_DEBUG_S("BSD16", "Handle TEvGetResult status# OK Die. TEvDiscoverResult# "
- << result->Print(false));
- SendResult(result);
+ A_LOG_DEBUG_S("BSD16", "Handle TEvGetResult status# OK Die. TEvDiscoverResult# "
+ << result->Print(false));
+ SendResult(result);
return;
}
- PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(response.Id, MinGeneration,
+ PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(response.Id, MinGeneration,
response.Buffer, BlockedGen));
- A_LOG_DEBUG_S("BSD17", "Handle TEvGetResult status# OK"
- << " Setting pending result# " << PendingResult->ToString());
+ A_LOG_DEBUG_S("BSD17", "Handle TEvGetResult status# OK"
+ << " Setting pending result# " << PendingResult->ToString());
Y_VERIFY(TotalRecieved < TotalSent);
return;
case NKikimrProto::NODATA: {
@@ -789,7 +789,7 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< " Can't read the blob id# " << response.Id.ToString();
ErrorReason = str.Str();
A_LOG_DEBUG_S("BSD32", "Handle " << ErrorReason << " Reply with ERROR");
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return;
}
@@ -803,14 +803,14 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< " VGetBlockedGen# " << VGetBlockedGen
<< " Get.BlockedGeneration# " << msg->BlockedGeneration
<< " response status# NODATA, Reply with ERROR! "
- << " looks like we have !!! LOST THE BLOB !!! id# " << response.Id.ToString();
+ << " looks like we have !!! LOST THE BLOB !!! id# " << response.Id.ToString();
- R_LOG_ALERT_S("BSD18", str.Str());
+ R_LOG_ALERT_S("BSD18", str.Str());
Sleep(TDuration::Seconds(1));
str << " logacc# ";
- LogCtx.LogAcc.Output(str);
+ LogCtx.LogAcc.Output(str);
str << " verboseNoData# ";
- str << msg->DebugInfo;
+ str << msg->DebugInfo;
Y_VERIFY(false, "%s", str.Str().data());
// TODO: Remove the lines above
@@ -820,16 +820,16 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
R_LOG_ERROR_S("BSD19", "Handle TEvGetResult Die. status# "
<< NKikimrProto::EReplyStatus_Name(status)
<< " Group# " << Info->GroupID
- << " for tablet# " << TabletId << " response status# NODATA, Reply with ERROR!");
- ReplyAndDie(NKikimrProto::ERROR);
+ << " for tablet# " << TabletId << " response status# NODATA, Reply with ERROR!");
+ ReplyAndDie(NKikimrProto::ERROR);
return;
}
- PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::ERROR, MinGeneration,
+ PendingResult.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::ERROR, MinGeneration,
BlockedGen));
R_LOG_ERROR_S("BSD20", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
- << " for tablet# " << TabletId << " response status# NODATA, set PendingResult to ERROR!");
+ << " for tablet# " << TabletId << " response status# NODATA, set PendingResult to ERROR!");
Y_VERIFY(TotalRecieved < TotalSent);
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return;
}
default: {
@@ -844,7 +844,7 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
<< NKikimrProto::EReplyStatus_Name(response.Status)
<< " " << msg->ToString();
ErrorReason = str.Str();
- ReplyAndDie(response.Status);
+ ReplyAndDie(response.Status);
}
return;
}
@@ -858,133 +858,133 @@ class TBlobStorageGroupDiscoverRequest : public TBlobStorageGroupRequestActor<TB
str << "Unexpected EvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
<< " " << msg->ToString();
ErrorReason = str.Str();
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
}
return;
}
Y_VERIFY(TotalRecieved < TotalSent);
}
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartDiscover;
- auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody, DiscoverBlockedGeneration,
- Deadline, ForceBlockedGeneration);
- ev->RestartCounter = counter;
- return ev;
- }
-
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartDiscover;
+ auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody, DiscoverBlockedGeneration,
+ Deadline, ForceBlockedGeneration);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_DISCOVER;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveDiscover;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Discover;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_DISCOVER;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveDiscover;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Discover;
+ }
+
TBlobStorageGroupDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
- NKikimrServices::BS_PROXY_DISCOVER, true, {}, now, storagePoolCounters, ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ NKikimrServices::BS_PROXY_DISCOVER, true, {}, now, storagePoolCounters, ev->RestartCounter)
, TabletId(ev->TabletId)
, MinGeneration(ev->MinGeneration)
, ReadBody(ev->ReadBody)
- , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
+ , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
, Deadline(ev->Deadline)
, StartTime(now)
, GroupResponseTracker(Info)
- , IsGetBlockDone(!DiscoverBlockedGeneration)
+ , IsGetBlockDone(!DiscoverBlockedGeneration)
, ForceBlockedGeneration(ev->ForceBlockedGeneration)
- {}
-
- void Bootstrap() {
- A_LOG_INFO_S("BSD31", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " TabletId# " << TabletId
- << " MinGeneration# " << MinGeneration
- << " ReadBody# " << (ReadBody ? "true" : "false")
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
+ {}
+
+ void Bootstrap() {
+ A_LOG_INFO_S("BSD31", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " TabletId# " << TabletId
+ << " MinGeneration# " << MinGeneration
+ << " ReadBody# " << (ReadBody ? "true" : "false")
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
const ui32 groupId = Info->GroupID;
const TLogoBlobID from = TLogoBlobID(TabletId, Max<ui32>(), Max<ui32>(), 0,
TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxChannel, TLogoBlobID::MaxPartId);
const TLogoBlobID to = TLogoBlobID(TabletId, MinGeneration, 0, 0, 0, 0, 1);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvDiscoverReceived, GroupId = groupId, From = from, To = to);
-
- for (const auto& vdisk : Info->GetVDisks()) {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvDiscoverReceived, GroupId = groupId, From = from, To = to);
+
+ for (const auto& vdisk : Info->GetVDisks()) {
auto vd = Info->GetVDiskId(vdisk.OrderNumber);
- if (!IsGetBlockDone) {
+ if (!IsGetBlockDone) {
const ui64 cookie = TVDiskIdShort(vd).GetRaw();
- auto getBlock = std::make_unique<TEvBlobStorage::TEvVGetBlock>(TabletId, vd, Deadline);
- A_LOG_DEBUG_S("BSD24", "Sending TEvVGetBlock Tablet# " << TabletId
+ auto getBlock = std::make_unique<TEvBlobStorage::TEvVGetBlock>(TabletId, vd, Deadline);
+ A_LOG_DEBUG_S("BSD24", "Sending TEvVGetBlock Tablet# " << TabletId
<< " vDiskId# " << vd
- << " cookie# " << cookie
- << " node# " << Info->GetActorId(vd).NodeId());
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetBlockSent);
- SendToQueue(std::move(getBlock), cookie, TraceId.SeparateBranch());
- TotalSent++;
- }
-
- auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vd, Deadline,
- NKikimrBlobStorage::EGetHandleClass::Discover, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
+ << " cookie# " << cookie
+ << " node# " << Info->GetActorId(vd).NodeId());
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetBlockSent);
+ SendToQueue(std::move(getBlock), cookie, TraceId.SeparateBranch());
+ TotalSent++;
+ }
+
+ auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vd, Deadline,
+ NKikimrBlobStorage::EGetHandleClass::Discover, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
{}, from, to, GroupResponseTracker.CurrentRequestSize, nullptr, ForceBlockedGeneration);
msg->Record.SetTabletId(TabletId);
msg->Record.SetAcquireBlockedGeneration(true);
const ui64 cookie = TVDiskIdShort(vd).GetRaw();
- A_LOG_DEBUG_S("BSD25", "Sending TEvVGet Tablet# " << TabletId
+ A_LOG_DEBUG_S("BSD25", "Sending TEvVGet Tablet# " << TabletId
<< " vDiskId# " << vd
<< " node# " << Info->GetActorId(vd).NodeId()
- << " msg# " << msg->ToString()
- << " cookie# " << cookie);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
- CountEvent(*msg);
- SendToQueue(std::move(msg), cookie, TraceId.SeparateBranch());
- TotalSent++;
+ << " msg# " << msg->ToString()
+ << " cookie# " << cookie);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
+ CountEvent(*msg);
+ SendToQueue(std::move(msg), cookie, TraceId.SeparateBranch());
+ TotalSent++;
TVDiskInfo &curVDisk = VDiskInfo[TVDiskIdShort(vd).GetRaw()];
- curVDisk.IsMoreRequested = true;
- curVDisk.LastRequestSize = GroupResponseTracker.CurrentRequestSize;
- curVDisk.nextLogoBlobId = from;
+ curVDisk.IsMoreRequested = true;
+ curVDisk.LastRequestSize = GroupResponseTracker.CurrentRequestSize;
+ curVDisk.nextLogoBlobId = from;
}
Become(&TThis::StateInit);
}
- STATEFN(StateInit) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateInit) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
}
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
- hFunc(TEvBlobStorage::TEvVGetResult, HandleIgnore);
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, HandleIgnore);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupDiscoverRequest(info, state, source, mon, ev, cookie, std::move(traceId), now,
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp
index a4e48dba76c..15adf04ec07 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3dc.cpp
@@ -1,744 +1,744 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
+#include "dsproxy_quorum_tracker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
LWTRACE_USING(BLOBSTORAGE_PROVIDER);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// DISCOVER request
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class TDiscoverVDiskWorker {
- static constexpr ui32 BlobsAtOnce = 100;
-
- const TVDiskID VDiskId;
-
- // is there an get unanswered get request?
- bool GetQueryInFlight = false;
-
- // has this VDisk finished?
- bool Finished = false;
-
- // is this VDisk erroneous?
- bool Erroneous = false;
-
- // is there possibly more blobs
- bool MoreBlobs = true;
-
- // first and last searched blob ids
- TLogoBlobID FirstBlob;
- const TLogoBlobID LastBlob;
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// DISCOVER request
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class TDiscoverVDiskWorker {
+ static constexpr ui32 BlobsAtOnce = 100;
+
+ const TVDiskID VDiskId;
+
+ // is there an get unanswered get request?
+ bool GetQueryInFlight = false;
+
+ // has this VDisk finished?
+ bool Finished = false;
+
+ // is this VDisk erroneous?
+ bool Erroneous = false;
+
+ // is there possibly more blobs
+ bool MoreBlobs = true;
+
+ // first and last searched blob ids
+ TLogoBlobID FirstBlob;
+ const TLogoBlobID LastBlob;
+
const ui32 ForceBlockedGeneration;
- struct TBlobQueueItem {
- TLogoBlobID Id; // identifier of this blob
- TIngress Ingress; // returned ingress
- NKikimrProto::EReplyStatus Status; // status for this blob
-
- TBlobQueueItem(const TBlobQueueItem& other) = default;
-
- TBlobQueueItem(const NKikimrBlobStorage::TQueryResult& item)
- : Id(LogoBlobIDFromLogoBlobID(item.GetBlobID()))
- , Ingress(item.GetIngress())
- , Status(item.GetStatus())
- {
- Y_VERIFY_DEBUG(item.HasBlobID() && item.HasIngress() && item.HasStatus());
- }
- };
-
- // queue of blobs in descending order
+ struct TBlobQueueItem {
+ TLogoBlobID Id; // identifier of this blob
+ TIngress Ingress; // returned ingress
+ NKikimrProto::EReplyStatus Status; // status for this blob
+
+ TBlobQueueItem(const TBlobQueueItem& other) = default;
+
+ TBlobQueueItem(const NKikimrBlobStorage::TQueryResult& item)
+ : Id(LogoBlobIDFromLogoBlobID(item.GetBlobID()))
+ , Ingress(item.GetIngress())
+ , Status(item.GetStatus())
+ {
+ Y_VERIFY_DEBUG(item.HasBlobID() && item.HasIngress() && item.HasStatus());
+ }
+ };
+
+ // queue of blobs in descending order
TDeque<TBlobQueueItem> BlobQueue;
-
-public:
+
+public:
TDiscoverVDiskWorker(const TVDiskID& vdiskId, ui64 tabletId, ui32 minGeneration, ui32 forceBlockedGeneration)
- : VDiskId(vdiskId)
- , FirstBlob(tabletId, Max<ui32>(), Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie)
- , LastBlob(tabletId, minGeneration, 0, 0, 0, 0)
+ : VDiskId(vdiskId)
+ , FirstBlob(tabletId, Max<ui32>(), Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie)
+ , LastBlob(tabletId, minGeneration, 0, 0, 0, 0)
, ForceBlockedGeneration(forceBlockedGeneration)
- {}
-
- // this function creates TEvVGet query to VDisk to be sent or returns nullptr if there is no query to send right now
- std::unique_ptr<TEvBlobStorage::TEvVGet> GenerateGetRequest(TInstant deadline) {
- if (!IsReady() && !GetQueryInFlight) {
- // create a query
- auto query = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(
- VDiskId, // vdisk
- deadline, // deadline
- NKikimrBlobStorage::Discover, // cls
- TEvBlobStorage::TEvVGet::EFlags::ShowInternals, // flags
- {}, // requestCookie
- FirstBlob, // fromId
- LastBlob, // toId
+ {}
+
+ // this function creates TEvVGet query to VDisk to be sent or returns nullptr if there is no query to send right now
+ std::unique_ptr<TEvBlobStorage::TEvVGet> GenerateGetRequest(TInstant deadline) {
+ if (!IsReady() && !GetQueryInFlight) {
+ // create a query
+ auto query = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(
+ VDiskId, // vdisk
+ deadline, // deadline
+ NKikimrBlobStorage::Discover, // cls
+ TEvBlobStorage::TEvVGet::EFlags::ShowInternals, // flags
+ {}, // requestCookie
+ FirstBlob, // fromId
+ LastBlob, // toId
BlobsAtOnce, // maxResults
nullptr, // cookie
ForceBlockedGeneration); // forceBlockedGeneration
-
-
- // disable barrier checking
- query->Record.SetSuppressBarrierCheck(true);
-
- // put query in queue and mark ourselves processing a query
- GetQueryInFlight = true;
- return query;
- }
-
- return nullptr;
- }
-
- // processor for received TEvVGetResult message
- bool Apply(TEvBlobStorage::TEvVGetResult *ev) {
- // the disk worker can't be ready while request is in processing
+
+
+ // disable barrier checking
+ query->Record.SetSuppressBarrierCheck(true);
+
+ // put query in queue and mark ourselves processing a query
+ GetQueryInFlight = true;
+ return query;
+ }
+
+ return nullptr;
+ }
+
+ // processor for received TEvVGetResult message
+ bool Apply(TEvBlobStorage::TEvVGetResult *ev) {
+ // the disk worker can't be ready while request is in processing
Y_VERIFY(!IsReady(), "Unexpected Finished# %s BlobQueue# %s Erroneous# %s MoreBlobs# %s GetQueryInFlight# %s",
Finished ? "true" : "false",
BlobQueue ? "true" : "false",
Erroneous ? "true" : "false",
MoreBlobs ? "true" : "false",
GetQueryInFlight ? "true" : "false");
-
- // ensure we have in flight query
- Y_VERIFY(GetQueryInFlight);
- GetQueryInFlight = false;
-
- // extract record and check it contains the status field
- const auto& record = ev->Record;
- Y_VERIFY(record.HasStatus());
-
- // ensure response came from our VDisk
- Y_VERIFY(record.HasVDiskID() && VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- // apply record according to the returned status
- switch (NKikimrProto::EReplyStatus status = record.GetStatus()) {
- case NKikimrProto::OK:
- // request has been successfully processed and we should put items into queue
+
+ // ensure we have in flight query
+ Y_VERIFY(GetQueryInFlight);
+ GetQueryInFlight = false;
+
+ // extract record and check it contains the status field
+ const auto& record = ev->Record;
+ Y_VERIFY(record.HasStatus());
+
+ // ensure response came from our VDisk
+ Y_VERIFY(record.HasVDiskID() && VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ // apply record according to the returned status
+ switch (NKikimrProto::EReplyStatus status = record.GetStatus()) {
+ case NKikimrProto::OK:
+ // request has been successfully processed and we should put items into queue
if (record.GetIsRangeOverflow() && !record.ResultSize()) {
- LOG_CRIT_S(*TlsActivationContext, NKikimrServices::BS_PROXY_DISCOVER,
+ LOG_CRIT_S(*TlsActivationContext, NKikimrServices::BS_PROXY_DISCOVER,
"Don't know how to process RangeOverflow with ResultSize# 0. Marker# DSPDM10");
Finished = true;
Erroneous = true;
} else {
ApplySuccessfulResult(record);
}
- break;
-
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
- // here we just start ignoring this VDisk; mark ourselves finished and continue working
- Finished = true;
- Erroneous = true;
- break;
-
- default:
+ break;
+
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ // here we just start ignoring this VDisk; mark ourselves finished and continue working
+ Finished = true;
+ Erroneous = true;
+ break;
+
+ default:
Y_FAIL("unexpected reply status# %s", NKikimrProto::EReplyStatus_Name(status).data());
- }
-
- return true;
- }
-
- // obtain the identifier of most recent blob contained within this structure
- TMaybe<TLogoBlobID> GetLatestBlob() const {
- Y_VERIFY(IsReady());
- return BlobQueue
- ? BlobQueue.front().Id
- : TMaybe<TLogoBlobID>();
- }
-
- // pop the blob with its status and other info; returns true if there is such blob and fields are filled in correctly;
- // false otherwise
- bool PopBlob(const TLogoBlobID& id, NKikimrProto::EReplyStatus *status, TIngress *ingress) {
- if (BlobQueue.empty()) {
- return false; // nothing to pop
- }
-
- TBlobQueueItem& item = BlobQueue.front();
- const TLogoBlobID& nextBlobId = item.Id;
- Y_VERIFY(id >= nextBlobId);
- if (id != nextBlobId) {
- return false; // blob id does not match requested one
- }
-
- *status = item.Status;
- *ingress = item.Ingress;
-
- BlobQueue.pop_front();
- if (BlobQueue.empty()) {
- Finished = !MoreBlobs;
- }
-
- return true;
- }
-
- // check if this worker is ready to issue logoblobs
- bool IsReady() const {
- return Finished || BlobQueue;
- }
-
- // check if worker is over erroneous vdisk
- bool IsErroneous() const {
- return Erroneous;
- }
-
- const TVDiskID& GetVDiskId() const {
- return VDiskId;
- }
-
-private:
- void ApplySuccessfulResult(const NKikimrBlobStorage::TEvVGetResult& record) {
- // ensure we haven't finished traversing index yet
- Y_VERIFY(!Finished);
-
- // the blob queue must be empty on entry -- otherwise we have no reason to request more blobs
- Y_VERIFY(BlobQueue.empty());
-
- // update queue with new items
- for (const NKikimrBlobStorage::TQueryResult& item : record.GetResult()) {
- TBlobQueueItem newItem(item);
- Y_VERIFY(newItem.Id.PartId() == 0);
- BlobQueue.emplace_back(newItem);
- }
+ }
+
+ return true;
+ }
+
+ // obtain the identifier of most recent blob contained within this structure
+ TMaybe<TLogoBlobID> GetLatestBlob() const {
+ Y_VERIFY(IsReady());
+ return BlobQueue
+ ? BlobQueue.front().Id
+ : TMaybe<TLogoBlobID>();
+ }
+
+ // pop the blob with its status and other info; returns true if there is such blob and fields are filled in correctly;
+ // false otherwise
+ bool PopBlob(const TLogoBlobID& id, NKikimrProto::EReplyStatus *status, TIngress *ingress) {
+ if (BlobQueue.empty()) {
+ return false; // nothing to pop
+ }
+
+ TBlobQueueItem& item = BlobQueue.front();
+ const TLogoBlobID& nextBlobId = item.Id;
+ Y_VERIFY(id >= nextBlobId);
+ if (id != nextBlobId) {
+ return false; // blob id does not match requested one
+ }
+
+ *status = item.Status;
+ *ingress = item.Ingress;
+
+ BlobQueue.pop_front();
+ if (BlobQueue.empty()) {
+ Finished = !MoreBlobs;
+ }
+
+ return true;
+ }
+
+ // check if this worker is ready to issue logoblobs
+ bool IsReady() const {
+ return Finished || BlobQueue;
+ }
+
+ // check if worker is over erroneous vdisk
+ bool IsErroneous() const {
+ return Erroneous;
+ }
+
+ const TVDiskID& GetVDiskId() const {
+ return VDiskId;
+ }
+
+private:
+ void ApplySuccessfulResult(const NKikimrBlobStorage::TEvVGetResult& record) {
+ // ensure we haven't finished traversing index yet
+ Y_VERIFY(!Finished);
+
+ // the blob queue must be empty on entry -- otherwise we have no reason to request more blobs
+ Y_VERIFY(BlobQueue.empty());
+
+ // update queue with new items
+ for (const NKikimrBlobStorage::TQueryResult& item : record.GetResult()) {
+ TBlobQueueItem newItem(item);
+ Y_VERIFY(newItem.Id.PartId() == 0);
+ BlobQueue.emplace_back(newItem);
+ }
if (record.ResultSize() < BlobsAtOnce && !record.GetIsRangeOverflow()) {
- MoreBlobs = false;
- }
-
- // and then check for strict ordering
- if (BlobQueue.size() > 1) {
- for (auto it1 = BlobQueue.begin(), it2 = std::next(it1); it2 != BlobQueue.end(); ++it1, ++it2) {
+ MoreBlobs = false;
+ }
+
+ // and then check for strict ordering
+ if (BlobQueue.size() > 1) {
+ for (auto it1 = BlobQueue.begin(), it2 = std::next(it1); it2 != BlobQueue.end(); ++it1, ++it2) {
Y_VERIFY(it1->Id > it2->Id, "id1# %s id2# %s", it1->Id.ToString().data(), it2->Id.ToString().data());
- }
- }
-
- // if there were no blobs in answer, we consired ourselves finished; otherwise we shall update our lower bound
- // and order to continue requesting
- if (BlobQueue) {
- // 'decrement' FirstBlob to continue processing
- const TLogoBlobID& least = BlobQueue.back().Id;
- const ui64 tabletId = least.TabletID();
- const ui32 channel = least.Channel();
- ui32 gen = least.Generation();
- ui32 step = least.Step();
- ui32 cookie = least.Cookie();
- if (cookie) {
- --cookie;
- } else {
- cookie = TLogoBlobID::MaxCookie;
- if (step) {
- --step;
- } else {
- step = Max<ui32>();
- if (gen) {
- --gen;
- } else {
- Finished = true;
- }
- }
- }
- FirstBlob = TLogoBlobID(tabletId, gen, step, channel, TLogoBlobID::MaxBlobSize, cookie);
- Finished |= FirstBlob < LastBlob;
- } else {
- Finished = true;
- }
- }
-};
-
-class TDiscoverWorker {
-public:
- struct TDiscoveryState {
- TLogoBlobID BlobId; // TLogoBlobID() when there are no blobs left
- bool MustExist; // set to true when this blob was written and surely confirmed to tablet
- };
-
-private:
- const TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ }
+ }
+
+ // if there were no blobs in answer, we consired ourselves finished; otherwise we shall update our lower bound
+ // and order to continue requesting
+ if (BlobQueue) {
+ // 'decrement' FirstBlob to continue processing
+ const TLogoBlobID& least = BlobQueue.back().Id;
+ const ui64 tabletId = least.TabletID();
+ const ui32 channel = least.Channel();
+ ui32 gen = least.Generation();
+ ui32 step = least.Step();
+ ui32 cookie = least.Cookie();
+ if (cookie) {
+ --cookie;
+ } else {
+ cookie = TLogoBlobID::MaxCookie;
+ if (step) {
+ --step;
+ } else {
+ step = Max<ui32>();
+ if (gen) {
+ --gen;
+ } else {
+ Finished = true;
+ }
+ }
+ }
+ FirstBlob = TLogoBlobID(tabletId, gen, step, channel, TLogoBlobID::MaxBlobSize, cookie);
+ Finished |= FirstBlob < LastBlob;
+ } else {
+ Finished = true;
+ }
+ }
+};
+
+class TDiscoverWorker {
+public:
+ struct TDiscoveryState {
+ TLogoBlobID BlobId; // TLogoBlobID() when there are no blobs left
+ bool MustExist; // set to true when this blob was written and surely confirmed to tablet
+ };
+
+private:
+ const TIntrusivePtr<TBlobStorageGroupInfo> Info;
TVector<TDiscoverVDiskWorker> VDiskWorkers;
- ui32 NumReadyWorkers = 0;
+ ui32 NumReadyWorkers = 0;
TQueue<TDiscoveryState> StateQ;
-
-public:
+
+public:
TDiscoverWorker(TIntrusivePtr<TBlobStorageGroupInfo> info, ui64 tabletId, ui32 minGeneration,
ui32 forceBlockedGeneration)
- : Info(std::move(info))
- {
- const ui32 numDisks = Info->GetTotalVDisksNum();
- VDiskWorkers.reserve(numDisks);
- for (ui32 i = 0; i < numDisks; ++i) {
+ : Info(std::move(info))
+ {
+ const ui32 numDisks = Info->GetTotalVDisksNum();
+ VDiskWorkers.reserve(numDisks);
+ for (ui32 i = 0; i < numDisks; ++i) {
VDiskWorkers.emplace_back(Info->GetVDiskId(i), tabletId, minGeneration, forceBlockedGeneration);
- }
- }
-
- void GenerateGetRequests(TVector<std::unique_ptr<TEvBlobStorage::TEvVGet>>& msgs, TInstant deadline) {
- for (TDiscoverVDiskWorker& worker : VDiskWorkers) {
- if (auto query = worker.GenerateGetRequest(deadline)) {
- msgs.push_back(std::move(query));
- }
- }
- }
-
- bool Apply(TEvBlobStorage::TEvVGetResult *ev) {
- // get a worker for this event
- const auto& record = ev->Record;
- Y_VERIFY(record.HasVDiskID());
- const TVDiskID vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ }
+ }
+
+ void GenerateGetRequests(TVector<std::unique_ptr<TEvBlobStorage::TEvVGet>>& msgs, TInstant deadline) {
+ for (TDiscoverVDiskWorker& worker : VDiskWorkers) {
+ if (auto query = worker.GenerateGetRequest(deadline)) {
+ msgs.push_back(std::move(query));
+ }
+ }
+ }
+
+ bool Apply(TEvBlobStorage::TEvVGetResult *ev) {
+ // get a worker for this event
+ const auto& record = ev->Record;
+ Y_VERIFY(record.HasVDiskID());
+ const TVDiskID vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
const TVDiskIdShort shortId(vdiskId);
ui32 index = Info->GetOrderNumber(shortId);
- Y_VERIFY(index < VDiskWorkers.size());
-
- // apply event
- TDiscoverVDiskWorker& worker = VDiskWorkers[index];
- if (!worker.Apply(ev)) {
- return false;
- }
- NumReadyWorkers += worker.IsReady();
-
- return ProcessDiscovery();
- }
-
- bool IsReady() const {
- return !StateQ.empty();
- }
-
- const TDiscoveryState& GetState() const {
- return StateQ.front();
- }
-
- void PopState() {
- StateQ.pop();
- }
-
-private:
- // this function checks whether erroneous disk count exceeds failure model for our erasure type or not; on success
- // returns true
- bool CheckGroupFailModel() {
+ Y_VERIFY(index < VDiskWorkers.size());
+
+ // apply event
+ TDiscoverVDiskWorker& worker = VDiskWorkers[index];
+ if (!worker.Apply(ev)) {
+ return false;
+ }
+ NumReadyWorkers += worker.IsReady();
+
+ return ProcessDiscovery();
+ }
+
+ bool IsReady() const {
+ return !StateQ.empty();
+ }
+
+ const TDiscoveryState& GetState() const {
+ return StateQ.front();
+ }
+
+ void PopState() {
+ StateQ.pop();
+ }
+
+private:
+ // this function checks whether erroneous disk count exceeds failure model for our erasure type or not; on success
+ // returns true
+ bool CheckGroupFailModel() {
TBlobStorageGroupInfo::TGroupVDisks failedGroupDisks(&Info->GetTopology());
- for (const TDiscoverVDiskWorker& worker : VDiskWorkers) {
- if (worker.IsErroneous()) {
+ for (const TDiscoverVDiskWorker& worker : VDiskWorkers) {
+ if (worker.IsErroneous()) {
failedGroupDisks += TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), worker.GetVDiskId());
- }
- }
- const auto& checker = Info->GetQuorumChecker();
- return checker.CheckFailModelForGroup(failedGroupDisks);
- }
-
- bool ProcessDiscovery() {
- // some of disks haven't replied yet, so we skip processing for now
- if (NumReadyWorkers != VDiskWorkers.size()) {
- return true;
- }
-
- // let's check that VDisk workers didn't register excessive failures
- if (!CheckGroupFailModel()) {
- return false;
- }
-
- while (NumReadyWorkers == VDiskWorkers.size()) {
- // find the most recent blob id; maxId will be empty if there are no blobs left
- TLogoBlobID maxId;
- for (TDiscoverVDiskWorker& worker : VDiskWorkers) {
- TMaybe<TLogoBlobID> vdiskBlobId = worker.GetLatestBlob();
- if (!vdiskBlobId) {
- continue;
- } else {
- maxId = Max(maxId, *vdiskBlobId);
- }
- }
-
- // check if there are no blobs -- it is successful discovery of empty tablet
- if (!maxId) {
- StateQ.push(TDiscoveryState{maxId, false});
- break;
- }
-
- // pick a subgroup of VDisks for this blob -- it is not necessary to check all the disks
- TBlobStorageGroupInfo::TVDiskIds vdisks;
- Info->PickSubgroup(maxId.Hash(), &vdisks, nullptr);
-
- // now we have logo blob id; merge ingress for this id and check whether this blob is restorable
- TIngress mergedIngress;
- TStackVec<NKikimrProto::EReplyStatus, 16> perDiskStatus;
- for (const TVDiskID& vdisk : vdisks) {
- // get order number for this vdisk and find matching worker
+ }
+ }
+ const auto& checker = Info->GetQuorumChecker();
+ return checker.CheckFailModelForGroup(failedGroupDisks);
+ }
+
+ bool ProcessDiscovery() {
+ // some of disks haven't replied yet, so we skip processing for now
+ if (NumReadyWorkers != VDiskWorkers.size()) {
+ return true;
+ }
+
+ // let's check that VDisk workers didn't register excessive failures
+ if (!CheckGroupFailModel()) {
+ return false;
+ }
+
+ while (NumReadyWorkers == VDiskWorkers.size()) {
+ // find the most recent blob id; maxId will be empty if there are no blobs left
+ TLogoBlobID maxId;
+ for (TDiscoverVDiskWorker& worker : VDiskWorkers) {
+ TMaybe<TLogoBlobID> vdiskBlobId = worker.GetLatestBlob();
+ if (!vdiskBlobId) {
+ continue;
+ } else {
+ maxId = Max(maxId, *vdiskBlobId);
+ }
+ }
+
+ // check if there are no blobs -- it is successful discovery of empty tablet
+ if (!maxId) {
+ StateQ.push(TDiscoveryState{maxId, false});
+ break;
+ }
+
+ // pick a subgroup of VDisks for this blob -- it is not necessary to check all the disks
+ TBlobStorageGroupInfo::TVDiskIds vdisks;
+ Info->PickSubgroup(maxId.Hash(), &vdisks, nullptr);
+
+ // now we have logo blob id; merge ingress for this id and check whether this blob is restorable
+ TIngress mergedIngress;
+ TStackVec<NKikimrProto::EReplyStatus, 16> perDiskStatus;
+ for (const TVDiskID& vdisk : vdisks) {
+ // get order number for this vdisk and find matching worker
const TVDiskIdShort shortId(vdisk);
ui32 orderNumber = Info->GetOrderNumber(shortId);
- Y_VERIFY(orderNumber < VDiskWorkers.size());
- TDiscoverVDiskWorker& worker = VDiskWorkers[orderNumber];
-
- // try to extract blob information from this worker and apply its status and ingress
- NKikimrProto::EReplyStatus status;
- TIngress ingress;
- if (!worker.PopBlob(maxId, &status, &ingress)) {
- status = NKikimrProto::NODATA; // this disk haven't synced this blob yet, so mark it as NODATA
- }
- perDiskStatus.push_back(status);
- mergedIngress.Merge(ingress);
- NumReadyWorkers -= !worker.IsReady();
- }
-
- // check for failure model; if number of reported errors exceeds failure model, return error in discovery
- TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&Info->GetTopology());
- if (!CheckSubgroupFailModel(perDiskStatus.data(), perDiskStatus.size(), failedSubgroupDisks)) {
- return false;
- }
-
- // TODO(alexvru): get rid of ingress here
- auto layout = TSubgroupPartLayout::CreateFromIngress(mergedIngress, Info->Type);
- const auto& checker = Info->GetQuorumChecker();
- auto state = checker.GetBlobState(layout, failedSubgroupDisks);
- if (state & (TBlobStorageGroupInfo::EBSF_FULL | TBlobStorageGroupInfo::EBSF_RECOVERABLE)) {
- const bool mustExist = state & TBlobStorageGroupInfo::EBSF_FULL;
- StateQ.push(TDiscoveryState{maxId, mustExist});
- }
- }
-
- return true;
- }
-
- bool CheckSubgroupFailModel(NKikimrProto::EReplyStatus *perDiskStatus, ui32 count,
- TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) {
- for (ui32 i = 0; i < count; ++i) {
- switch (NKikimrProto::EReplyStatus status = perDiskStatus[i]) {
- case NKikimrProto::OK:
- case NKikimrProto::NODATA:
- break;
-
- case NKikimrProto::ERROR:
+ Y_VERIFY(orderNumber < VDiskWorkers.size());
+ TDiscoverVDiskWorker& worker = VDiskWorkers[orderNumber];
+
+ // try to extract blob information from this worker and apply its status and ingress
+ NKikimrProto::EReplyStatus status;
+ TIngress ingress;
+ if (!worker.PopBlob(maxId, &status, &ingress)) {
+ status = NKikimrProto::NODATA; // this disk haven't synced this blob yet, so mark it as NODATA
+ }
+ perDiskStatus.push_back(status);
+ mergedIngress.Merge(ingress);
+ NumReadyWorkers -= !worker.IsReady();
+ }
+
+ // check for failure model; if number of reported errors exceeds failure model, return error in discovery
+ TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&Info->GetTopology());
+ if (!CheckSubgroupFailModel(perDiskStatus.data(), perDiskStatus.size(), failedSubgroupDisks)) {
+ return false;
+ }
+
+ // TODO(alexvru): get rid of ingress here
+ auto layout = TSubgroupPartLayout::CreateFromIngress(mergedIngress, Info->Type);
+ const auto& checker = Info->GetQuorumChecker();
+ auto state = checker.GetBlobState(layout, failedSubgroupDisks);
+ if (state & (TBlobStorageGroupInfo::EBSF_FULL | TBlobStorageGroupInfo::EBSF_RECOVERABLE)) {
+ const bool mustExist = state & TBlobStorageGroupInfo::EBSF_FULL;
+ StateQ.push(TDiscoveryState{maxId, mustExist});
+ }
+ }
+
+ return true;
+ }
+
+ bool CheckSubgroupFailModel(NKikimrProto::EReplyStatus *perDiskStatus, ui32 count,
+ TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) {
+ for (ui32 i = 0; i < count; ++i) {
+ switch (NKikimrProto::EReplyStatus status = perDiskStatus[i]) {
+ case NKikimrProto::OK:
+ case NKikimrProto::NODATA:
+ break;
+
+ case NKikimrProto::ERROR:
failedSubgroupDisks += TBlobStorageGroupInfo::TSubgroupVDisks(&Info->GetTopology(), i);
- break;
-
- default:
+ break;
+
+ default:
Y_FAIL("unexpected status# %s", NKikimrProto::EReplyStatus_Name(status).data());
- }
- }
-
- const auto& checker = Info->GetQuorumChecker();
- return checker.CheckFailModelForSubgroup(failedSubgroupDisks);
- }
-};
-
-class TBlobStorageGroupMirror3dcDiscoverRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupMirror3dcDiscoverRequest>{
- const ui64 TabletId;
- const ui32 MinGeneration;
+ }
+ }
+
+ const auto& checker = Info->GetQuorumChecker();
+ return checker.CheckFailModelForSubgroup(failedSubgroupDisks);
+ }
+};
+
+class TBlobStorageGroupMirror3dcDiscoverRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupMirror3dcDiscoverRequest>{
+ const ui64 TabletId;
+ const ui32 MinGeneration;
const TInstant StartTime;
- const TInstant Deadline;
- const bool ReadBody;
- const bool DiscoverBlockedGeneration;
+ const TInstant Deadline;
+ const bool ReadBody;
+ const bool DiscoverBlockedGeneration;
const ui32 ForceBlockedGeneration;
-
- std::unique_ptr<TDiscoverWorker> Worker;
- TVector<std::unique_ptr<TEvBlobStorage::TEvVGet>> Msgs;
-
- ui32 BlockedGeneration = 0;
+
+ std::unique_ptr<TDiscoverWorker> Worker;
+ TVector<std::unique_ptr<TEvBlobStorage::TEvVGet>> Msgs;
+
+ ui32 BlockedGeneration = 0;
TString Buffer;
- bool GetFinished = false;
- bool GetInFlight = false;
- TLogoBlobID ResultBlobId;
-
- // quorum tracker for EvVGetBlock queries
- TGroupQuorumTracker GetBlockTracker;
- bool GetBlockFinished = false;
-
- // number of in flight requests of all kind
- ui32 RequestsInFlight = 0;
- bool Responded = false;
-
-public:
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveDiscover;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Discover;
- }
-
- TBlobStorageGroupMirror3dcDiscoverRequest(TIntrusivePtr<TBlobStorageGroupInfo> info,
- TIntrusivePtr<TGroupQueues> state, const TActorId& source,
- TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TEvBlobStorage::TEvDiscover *ev,
+ bool GetFinished = false;
+ bool GetInFlight = false;
+ TLogoBlobID ResultBlobId;
+
+ // quorum tracker for EvVGetBlock queries
+ TGroupQuorumTracker GetBlockTracker;
+ bool GetBlockFinished = false;
+
+ // number of in flight requests of all kind
+ ui32 RequestsInFlight = 0;
+ bool Responded = false;
+
+public:
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveDiscover;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Discover;
+ }
+
+ TBlobStorageGroupMirror3dcDiscoverRequest(TIntrusivePtr<TBlobStorageGroupInfo> info,
+ TIntrusivePtr<TGroupQueues> state, const TActorId& source,
+ TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(std::move(info), std::move(state), std::move(mon), source, cookie,
- std::move(traceId), NKikimrServices::BS_PROXY_DISCOVER, false, {}, now, storagePoolCounters,
- ev->RestartCounter)
- , TabletId(ev->TabletId)
- , MinGeneration(ev->MinGeneration)
+ : TBlobStorageGroupRequestActor(std::move(info), std::move(state), std::move(mon), source, cookie,
+ std::move(traceId), NKikimrServices::BS_PROXY_DISCOVER, false, {}, now, storagePoolCounters,
+ ev->RestartCounter)
+ , TabletId(ev->TabletId)
+ , MinGeneration(ev->MinGeneration)
, StartTime(now)
- , Deadline(ev->Deadline)
- , ReadBody(ev->ReadBody)
- , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
+ , Deadline(ev->Deadline)
+ , ReadBody(ev->ReadBody)
+ , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
, ForceBlockedGeneration(ev->ForceBlockedGeneration)
- , GetBlockTracker(Info.Get())
- {}
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartDiscover;
- auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody, DiscoverBlockedGeneration,
- Deadline, ForceBlockedGeneration);
- ev->RestartCounter = counter;
- return ev;
- }
-
- void Bootstrap() {
- A_LOG_DEBUG_S("DSPDM01", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " TabletId# " << TabletId
- << " MinGeneration# " << MinGeneration
- << " Deadline# " << Deadline
- << " ReadBody# " << (ReadBody ? "true" : "false")
+ , GetBlockTracker(Info.Get())
+ {}
+
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartDiscover;
+ auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody, DiscoverBlockedGeneration,
+ Deadline, ForceBlockedGeneration);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
+ void Bootstrap() {
+ A_LOG_DEBUG_S("DSPDM01", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " TabletId# " << TabletId
+ << " MinGeneration# " << MinGeneration
+ << " Deadline# " << Deadline
+ << " ReadBody# " << (ReadBody ? "true" : "false")
<< " DiscoverBlockedGeneration# " << (DiscoverBlockedGeneration ? "true" : "false")
- << " ForceBlockedGeneration# " << ForceBlockedGeneration
- << " RestartCounter# " << RestartCounter);
-
- Worker = std::make_unique<TDiscoverWorker>(Info, TabletId, MinGeneration, ForceBlockedGeneration);
-
- // generate GetBlock queries if we need 'em
- if (DiscoverBlockedGeneration) {
- for (const auto& vdisk : Info->GetVDisks()) {
+ << " ForceBlockedGeneration# " << ForceBlockedGeneration
+ << " RestartCounter# " << RestartCounter);
+
+ Worker = std::make_unique<TDiscoverWorker>(Info, TabletId, MinGeneration, ForceBlockedGeneration);
+
+ // generate GetBlock queries if we need 'em
+ if (DiscoverBlockedGeneration) {
+ for (const auto& vdisk : Info->GetVDisks()) {
auto vd = Info->GetVDiskId(vdisk.OrderNumber);
- auto query = std::make_unique<TEvBlobStorage::TEvVGetBlock>(TabletId, vd, Deadline);
-
- A_LOG_DEBUG_S("DSPDM06", "sending TEvVGetBlock# " << query->ToString());
-
- SendToQueue(std::move(query), 0, NWilson::TTraceId());
- ++RequestsInFlight;
- }
- }
-
- // initial kick for workers -- send messages to corresponding VDisks
- SendWorkerMessages();
-
- // set correct state function
- Become(&TBlobStorageGroupMirror3dcDiscoverRequest::StateFunc);
- }
-
- void SendWorkerMessages() {
- Worker->GenerateGetRequests(Msgs, Deadline);
- for (auto& msg : Msgs) {
- A_LOG_DEBUG_S("DSPDM07", "sending TEvVGet# " << msg->ToString());
-
- CountEvent(*msg);
- SendToQueue(std::move(msg), 0, NWilson::TTraceId());
- ++RequestsInFlight;
- }
- Msgs.clear();
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr& ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
- Y_VERIFY(RequestsInFlight > 0);
- --RequestsInFlight;
-
- // extract VDisk id
- TEvBlobStorage::TEvVGetResult *msg = ev->Get();
- const auto& record = msg->Record;
- Y_VERIFY(record.HasVDiskID());
-
- A_LOG_DEBUG_S("DSPDM04", "received TEvVGetResult# " << msg->ToString());
-
- // get worker for this ring and apply result
- if (!Worker->Apply(msg)) {
- ReplyAndDie(NKikimrProto::ERROR);
- } else if (Worker->IsReady()) {
- // continue processing discovery
- TryToProcessNextProbe();
- } else {
- // may be we have to send even more messages to Vdisks, so let's do it
- SendWorkerMessages();
- }
-
- Y_VERIFY(RequestsInFlight || Responded);
- }
-
- void TryToProcessNextProbe() {
- if (Worker->IsReady() && !GetInFlight && !GetFinished) {
- const TDiscoverWorker::TDiscoveryState& state = Worker->GetState();
- ResultBlobId = state.BlobId;
- if (ResultBlobId) {
- GetInFlight = true;
- Y_VERIFY(ResultBlobId.PartId() == 0);
- auto query = std::make_unique<TEvBlobStorage::TEvGet>(ResultBlobId, 0U, 0U, Deadline,
- NKikimrBlobStorage::Discover, true, !ReadBody);
- query->IsInternal = true;
-
+ auto query = std::make_unique<TEvBlobStorage::TEvVGetBlock>(TabletId, vd, Deadline);
+
+ A_LOG_DEBUG_S("DSPDM06", "sending TEvVGetBlock# " << query->ToString());
+
+ SendToQueue(std::move(query), 0, NWilson::TTraceId());
+ ++RequestsInFlight;
+ }
+ }
+
+ // initial kick for workers -- send messages to corresponding VDisks
+ SendWorkerMessages();
+
+ // set correct state function
+ Become(&TBlobStorageGroupMirror3dcDiscoverRequest::StateFunc);
+ }
+
+ void SendWorkerMessages() {
+ Worker->GenerateGetRequests(Msgs, Deadline);
+ for (auto& msg : Msgs) {
+ A_LOG_DEBUG_S("DSPDM07", "sending TEvVGet# " << msg->ToString());
+
+ CountEvent(*msg);
+ SendToQueue(std::move(msg), 0, NWilson::TTraceId());
+ ++RequestsInFlight;
+ }
+ Msgs.clear();
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr& ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
+ Y_VERIFY(RequestsInFlight > 0);
+ --RequestsInFlight;
+
+ // extract VDisk id
+ TEvBlobStorage::TEvVGetResult *msg = ev->Get();
+ const auto& record = msg->Record;
+ Y_VERIFY(record.HasVDiskID());
+
+ A_LOG_DEBUG_S("DSPDM04", "received TEvVGetResult# " << msg->ToString());
+
+ // get worker for this ring and apply result
+ if (!Worker->Apply(msg)) {
+ ReplyAndDie(NKikimrProto::ERROR);
+ } else if (Worker->IsReady()) {
+ // continue processing discovery
+ TryToProcessNextProbe();
+ } else {
+ // may be we have to send even more messages to Vdisks, so let's do it
+ SendWorkerMessages();
+ }
+
+ Y_VERIFY(RequestsInFlight || Responded);
+ }
+
+ void TryToProcessNextProbe() {
+ if (Worker->IsReady() && !GetInFlight && !GetFinished) {
+ const TDiscoverWorker::TDiscoveryState& state = Worker->GetState();
+ ResultBlobId = state.BlobId;
+ if (ResultBlobId) {
+ GetInFlight = true;
+ Y_VERIFY(ResultBlobId.PartId() == 0);
+ auto query = std::make_unique<TEvBlobStorage::TEvGet>(ResultBlobId, 0U, 0U, Deadline,
+ NKikimrBlobStorage::Discover, true, !ReadBody);
+ query->IsInternal = true;
+
A_LOG_DEBUG_S("DSPDM17", "sending TEvGet# " << query->ToString());
-
- SendToBSProxy(SelfId(), Info->GroupID, query.release());
- ++RequestsInFlight;
- } else {
- GetFinished = true;
- TryToSatisfyRequest();
- }
- }
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev) {
- Y_VERIFY(RequestsInFlight > 0);
- --RequestsInFlight;
-
- A_LOG_DEBUG_S("DSPDM05", "received TEvGetResult# " << ev->Get()->ToString());
-
- // get item from probe queue and ensure that we receive answer for exactly this query
- Y_VERIFY(Worker->IsReady());
- const TDiscoverWorker::TDiscoveryState state = Worker->GetState();
- Y_VERIFY(state.BlobId == ResultBlobId);
- Worker->PopState();
-
- // verify in flight flag
- Y_VERIFY(GetInFlight);
- GetInFlight = false;
-
- // process message status -- any _message_ other than OK is treated as uncorrectable error (at least at this
- // point in time)
- TEvBlobStorage::TEvGetResult *msg = ev->Get();
- if (msg->Status != NKikimrProto::OK) {
- ReplyAndDie(NKikimrProto::ERROR);
- return;
- }
-
- Y_VERIFY(msg->ResponseSz == 1);
- auto& resp = msg->Responses[0];
- switch (resp.Status) {
- case NKikimrProto::OK:
- // okay response -- blob is read and stored in all replicas
- Y_VERIFY(resp.Id == ResultBlobId);
- Buffer = resp.Buffer;
- GetFinished = true;
- TryToSatisfyRequest();
- break;
-
- case NKikimrProto::ERROR:
- ReplyAndDie(NKikimrProto::ERROR);
- return;
-
- case NKikimrProto::NODATA:
- if (state.MustExist) {
- // we have just lost the blob
+
+ SendToBSProxy(SelfId(), Info->GroupID, query.release());
+ ++RequestsInFlight;
+ } else {
+ GetFinished = true;
+ TryToSatisfyRequest();
+ }
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev) {
+ Y_VERIFY(RequestsInFlight > 0);
+ --RequestsInFlight;
+
+ A_LOG_DEBUG_S("DSPDM05", "received TEvGetResult# " << ev->Get()->ToString());
+
+ // get item from probe queue and ensure that we receive answer for exactly this query
+ Y_VERIFY(Worker->IsReady());
+ const TDiscoverWorker::TDiscoveryState state = Worker->GetState();
+ Y_VERIFY(state.BlobId == ResultBlobId);
+ Worker->PopState();
+
+ // verify in flight flag
+ Y_VERIFY(GetInFlight);
+ GetInFlight = false;
+
+ // process message status -- any _message_ other than OK is treated as uncorrectable error (at least at this
+ // point in time)
+ TEvBlobStorage::TEvGetResult *msg = ev->Get();
+ if (msg->Status != NKikimrProto::OK) {
+ ReplyAndDie(NKikimrProto::ERROR);
+ return;
+ }
+
+ Y_VERIFY(msg->ResponseSz == 1);
+ auto& resp = msg->Responses[0];
+ switch (resp.Status) {
+ case NKikimrProto::OK:
+ // okay response -- blob is read and stored in all replicas
+ Y_VERIFY(resp.Id == ResultBlobId);
+ Buffer = resp.Buffer;
+ GetFinished = true;
+ TryToSatisfyRequest();
+ break;
+
+ case NKikimrProto::ERROR:
+ ReplyAndDie(NKikimrProto::ERROR);
+ return;
+
+ case NKikimrProto::NODATA:
+ if (state.MustExist) {
+ // we have just lost the blob
R_LOG_ALERT_S("DSPDM09", "!!! LOST THE BLOB !!! BlobId# " << ResultBlobId.ToString()
<< " Group# " << Info->GroupID);
- return ReplyAndDie(NKikimrProto::ERROR);
- } else if (Worker->IsReady()) {
- // try to process another probe in queue (if available) as this blob is not restorable, but this was
- // expectable
- TryToProcessNextProbe();
- } else {
- // worker is exhausted, so we have to issue more messages to VDisks to determine further blobs
- SendWorkerMessages();
- }
- break;
-
- default:
+ return ReplyAndDie(NKikimrProto::ERROR);
+ } else if (Worker->IsReady()) {
+ // try to process another probe in queue (if available) as this blob is not restorable, but this was
+ // expectable
+ TryToProcessNextProbe();
+ } else {
+ // worker is exhausted, so we have to issue more messages to VDisks to determine further blobs
+ SendWorkerMessages();
+ }
+ break;
+
+ default:
Y_FAIL("unexpected item status# %s", NKikimrProto::EReplyStatus_Name(resp.Status).data());
- }
-
- Y_VERIFY(RequestsInFlight || Responded, "Status# %s GetInFlight# %s GetBlockFinished# %s",
+ }
+
+ Y_VERIFY(RequestsInFlight || Responded, "Status# %s GetInFlight# %s GetBlockFinished# %s",
NKikimrProto::EReplyStatus_Name(resp.Status).data(), GetInFlight ? "true" : "false",
- GetBlockFinished ? "true" : "false");
- }
-
- void TryToSatisfyRequest() {
- if (GetFinished && GetBlockFinished) {
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response;
- if (ResultBlobId) {
- response.reset(new TEvBlobStorage::TEvDiscoverResult(ResultBlobId, MinGeneration,
+ GetBlockFinished ? "true" : "false");
+ }
+
+ void TryToSatisfyRequest() {
+ if (GetFinished && GetBlockFinished) {
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response;
+ if (ResultBlobId) {
+ response.reset(new TEvBlobStorage::TEvDiscoverResult(ResultBlobId, MinGeneration,
ReadBody ? Buffer : TString(), BlockedGeneration));
- } else {
- response.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::NODATA, MinGeneration,
+ } else {
+ response.reset(new TEvBlobStorage::TEvDiscoverResult(NKikimrProto::NODATA, MinGeneration,
BlockedGeneration));
- }
-
- R_LOG_DEBUG_S("DSPDM03", "Response# " << response->ToString());
-
- Y_VERIFY(!Responded);
- const TDuration duration = TActivationContext::Now() - StartTime;
+ }
+
+ R_LOG_DEBUG_S("DSPDM03", "Response# " << response->ToString());
+
+ Y_VERIFY(!Responded);
+ const TDuration duration = TActivationContext::Now() - StartTime;
LWPROBE(DSProxyRequestDuration, TEvBlobStorage::EvDiscover, 0, duration.SecondsFloat() * 1000.0,
TabletId, Info->GroupID, TLogoBlobID::MaxChannel, "", true);
- SendResponseAndDie(std::move(response));
- Responded = true;
- }
- }
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- R_LOG_ERROR_S("DSPDM02", "Status# " << NKikimrProto::EReplyStatus_Name(status));
-
- Y_VERIFY(!Responded);
- Y_VERIFY(status != NKikimrProto::OK);
- const TDuration duration = TActivationContext::Now() - StartTime;
+ SendResponseAndDie(std::move(response));
+ Responded = true;
+ }
+ }
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ R_LOG_ERROR_S("DSPDM02", "Status# " << NKikimrProto::EReplyStatus_Name(status));
+
+ Y_VERIFY(!Responded);
+ Y_VERIFY(status != NKikimrProto::OK);
+ const TDuration duration = TActivationContext::Now() - StartTime;
LWPROBE(DSProxyRequestDuration, TEvBlobStorage::EvDiscover, 0, duration.SecondsFloat() * 1000.0,
TabletId, Info->GroupID, TLogoBlobID::MaxChannel, "", false);
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response(new TEvBlobStorage::TEvDiscoverResult(
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response(new TEvBlobStorage::TEvDiscoverResult(
status, MinGeneration, 0U));
response->ErrorReason = ErrorReason;
- SendResponseAndDie(std::move(response));
- Responded = true;
- }
-
- void Handle(TEvBlobStorage::TEvVGetBlockResult::TPtr& ev) {
- ProcessReplyFromQueue(ev);
- Y_VERIFY(RequestsInFlight > 0);
- --RequestsInFlight;
-
- TEvBlobStorage::TEvVGetBlockResult *msg = ev->Get();
-
- A_LOG_DEBUG_S("DSPDM08", "received TEvVGetBlockResult# " << msg->ToString()
- << " BlockedGeneration# " << BlockedGeneration);
-
- const auto& record = msg->Record;
- Y_VERIFY(record.HasStatus());
-
- Y_VERIFY(record.HasVDiskID());
- const TVDiskID& vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
-
- // update blocked generation -- we need maximum
- NKikimrProto::EReplyStatus status = record.GetStatus();
- if (status == NKikimrProto::OK) {
- BlockedGeneration = Max(BlockedGeneration, record.GetGeneration());
- } else if (status == NKikimrProto::NODATA) {
- status = NKikimrProto::OK; // assume OK for quorum tracker
- }
-
- switch (NKikimrProto::EReplyStatus quorumStatus = GetBlockTracker.ProcessReply(vdisk, status)) {
- case NKikimrProto::OK:
- GetBlockFinished = true;
- TryToSatisfyRequest();
- break;
-
- case NKikimrProto::ERROR:
- return ReplyAndDie(NKikimrProto::ERROR);
-
- case NKikimrProto::UNKNOWN:
- break;
-
- default:
+ SendResponseAndDie(std::move(response));
+ Responded = true;
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetBlockResult::TPtr& ev) {
+ ProcessReplyFromQueue(ev);
+ Y_VERIFY(RequestsInFlight > 0);
+ --RequestsInFlight;
+
+ TEvBlobStorage::TEvVGetBlockResult *msg = ev->Get();
+
+ A_LOG_DEBUG_S("DSPDM08", "received TEvVGetBlockResult# " << msg->ToString()
+ << " BlockedGeneration# " << BlockedGeneration);
+
+ const auto& record = msg->Record;
+ Y_VERIFY(record.HasStatus());
+
+ Y_VERIFY(record.HasVDiskID());
+ const TVDiskID& vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
+
+ // update blocked generation -- we need maximum
+ NKikimrProto::EReplyStatus status = record.GetStatus();
+ if (status == NKikimrProto::OK) {
+ BlockedGeneration = Max(BlockedGeneration, record.GetGeneration());
+ } else if (status == NKikimrProto::NODATA) {
+ status = NKikimrProto::OK; // assume OK for quorum tracker
+ }
+
+ switch (NKikimrProto::EReplyStatus quorumStatus = GetBlockTracker.ProcessReply(vdisk, status)) {
+ case NKikimrProto::OK:
+ GetBlockFinished = true;
+ TryToSatisfyRequest();
+ break;
+
+ case NKikimrProto::ERROR:
+ return ReplyAndDie(NKikimrProto::ERROR);
+
+ case NKikimrProto::UNKNOWN:
+ break;
+
+ default:
Y_FAIL("unexpected TEvVGetBlockResult status# %s", NKikimrProto::EReplyStatus_Name(quorumStatus).data());
- }
-
- Y_VERIFY(RequestsInFlight || Responded);
- }
-
- STATEFN(StateFunc) {
- if (ProcessEvent(ev)) {
- return;
- }
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
- hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
- }
- }
-};
-
-IActor* CreateBlobStorageGroupMirror3dcDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+ }
+
+ Y_VERIFY(RequestsInFlight || Responded);
+ }
+
+ STATEFN(StateFunc) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetBlockResult, Handle);
+ }
+ }
+};
+
+IActor* CreateBlobStorageGroupMirror3dcDiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupMirror3dcDiscoverRequest(info, state, source, mon, ev, cookie, std::move(traceId), now,
storagePoolCounters);
-}
-
-}//NKikimr
+}
+
+}//NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3of4.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3of4.cpp
index 9e3393070ab..a908f6d693c 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3of4.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_discover_m3of4.cpp
@@ -1,370 +1,370 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
+#include "dsproxy_quorum_tracker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
-
-namespace NKikimr {
-
-class TBlobStorageGroupMirror3of4DiscoverRequest
- : public TBlobStorageGroupRequestActor<TBlobStorageGroupMirror3of4DiscoverRequest>
-{
- const ui64 TabletId;
- const ui32 MinGeneration;
- const TInstant StartTime;
- const TInstant Deadline;
- const bool ReadBody;
- const bool DiscoverBlockedGeneration;
- const ui32 ForceBlockedGeneration;
-
-public:
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveDiscover;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Discover;
- }
-
- TBlobStorageGroupMirror3of4DiscoverRequest(TIntrusivePtr<TBlobStorageGroupInfo> info,
- TIntrusivePtr<TGroupQueues> state, const TActorId& source,
- TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TEvBlobStorage::TEvDiscover *ev,
- ui64 cookie, NWilson::TTraceId traceId, TInstant now,
- TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(std::move(info), std::move(state), std::move(mon), source, cookie,
- std::move(traceId), NKikimrServices::BS_PROXY_DISCOVER, false, {}, now, storagePoolCounters,
- ev->RestartCounter)
- , TabletId(ev->TabletId)
- , MinGeneration(ev->MinGeneration)
- , StartTime(now)
- , Deadline(ev->Deadline)
- , ReadBody(ev->ReadBody)
- , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
- , ForceBlockedGeneration(ev->ForceBlockedGeneration)
- {
- for (size_t i = 0; i < DiskState.size(); ++i) {
- TDiskState& disk = DiskState[i];
- disk.VDiskId = Info->GetVDiskId(i);
- disk.From = MaxBlobId;
- }
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartDiscover;
- auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody,
- DiscoverBlockedGeneration, Deadline, ForceBlockedGeneration);
- ev->RestartCounter = counter;
- return ev;
- }
-
- void Bootstrap() {
- A_LOG_INFO_S("DSPDX01", "bootstrap"
- << " TabletId# " << TabletId
- << " MinGeneration# " << MinGeneration
- << " Deadline# " << Deadline
- << " ReadBody# " << (ReadBody ? "true" : "false")
- << " DiscoverBlockedGeneration# " << (DiscoverBlockedGeneration ? "true" : "false")
- << " ForceBlockedGeneration# " << ForceBlockedGeneration
- << " RestartCounter# " << RestartCounter);
-
- Become(&TThis::StateFunc);
-
- if (Deadline != TInstant::Max()) {
- Schedule(Deadline - TActivationContext::Now(), new TEvents::TEvWakeup);
- }
-
- // start discovery by issuing range-read queries to all disks of a group
- IssueRangeReadQueries();
- }
-
- void HandleWakeup() {
- ReplyAndDie(NKikimrProto::DEADLINE);
- }
-
- void ReplyAndDie(NKikimrProto::EReplyStatus status, std::optional<TString> errorReason = std::nullopt) {
- if (errorReason) {
- ErrorReason = std::move(*errorReason);
- }
- Y_VERIFY(status != NKikimrProto::OK);
- auto formatFailedGroupDisks = [&] {
- TStringBuilder s;
- s << "[";
- bool first = true;
- for (TDiskState& disk : DiskState) {
- if (FailedGroupDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), disk.VDiskId)) {
- s << (std::exchange(first, false) ? "" : " ") << disk.VDiskId;
- }
- }
- s << "]";
- return s;
- };
- R_LOG_ERROR_S("DSPDX02", "request failed"
- << " Status# " << NKikimrProto::EReplyStatus_Name(status)
- << " ErrorReason# " << (ErrorReason ? ErrorReason : "<none>")
- << " FailedGroupDisks# " << formatFailedGroupDisks());
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response(new TEvBlobStorage::TEvDiscoverResult(status, MinGeneration,
- 0U));
- response->ErrorReason = ErrorReason;
- SendResponseAndDie(std::move(response));
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Range-read scans
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- enum class EDiskState {
- IDLE,
- READ_PENDING,
- FINISHED,
- };
-
- struct TDiskState {
- TVDiskID VDiskId;
- EDiskState State = EDiskState::IDLE;
- TLogoBlobID From;
- bool Replied = false;
-
- // check if replies from this disk should cover provided blob id
- bool Covered(const TLogoBlobID& id) const {
- return State == EDiskState::FINISHED || From < id;
- }
- };
-
- static constexpr ui32 MaxBlobsAtOnce = 32;
- static constexpr auto HandleClass = NKikimrBlobStorage::EGetHandleClass::Discover;
- const TLogoBlobID MaxBlobId{TabletId, Max<ui32>(), Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie};
- std::vector<TDiskState> DiskState{Info->GetTotalVDisksNum()};
- std::map<TLogoBlobID, TSubgroupPartLayout> BlobMetadata; // obtained through range queries
- ui32 NumUnrepliedDisks = DiskState.size();
- TBlobStorageGroupInfo::TGroupVDisks FailedGroupDisks{&Info->GetTopology()};
- ui32 BlockedGeneration = 0;
- std::optional<TLogoBlobID> GetIssuedFor;
- bool Doubted = false;
-
- void IssueRangeReadQueries() {
- for (TDiskState& disk : DiskState) {
- IssueRangeReadQuery(disk);
- }
- }
-
- void IssueRangeReadQuery(TDiskState& state) {
- const TLogoBlobID to = TLogoBlobID(TabletId, MinGeneration, 0, 0, 0, 0);
- SendToQueue(TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(state.VDiskId, Deadline, HandleClass,
- TEvBlobStorage::TEvVGet::EFlags::None, Nothing(), state.From, to, MaxBlobsAtOnce, nullptr,
- ForceBlockedGeneration), 0, {} /*traceId*/);
- const EDiskState prev = std::exchange(state.State, EDiskState::READ_PENDING);
- Y_VERIFY(prev == EDiskState::IDLE);
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
- ProcessReplyFromQueue(ev);
- auto& record = ev->Get()->Record;
- if (!record.HasStatus() || !record.HasVDiskID()) {
- return ReplyAndDie(NKikimrProto::ERROR, "incorrect TEvVGetResult from VDisk");
- }
- if (record.HasBlockedGeneration() && record.GetBlockedGeneration() > BlockedGeneration) {
- BlockedGeneration = record.GetBlockedGeneration();
- }
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- TDiskState& disk = DiskState[Info->GetOrderNumber(vdiskId)];
- Y_VERIFY_DEBUG(disk.VDiskId == vdiskId);
- const EDiskState prev = std::exchange(disk.State, EDiskState::IDLE);
- Y_VERIFY(prev == EDiskState::READ_PENDING);
- NumUnrepliedDisks -= !std::exchange(disk.Replied, true);
- switch (record.GetStatus()) {
- case NKikimrProto::OK: {
- std::optional<TLogoBlobID> lastId;
- for (const auto& blob : record.GetResult()) {
- if (!blob.HasStatus() || !blob.HasBlobID()) {
- return ReplyAndDie(NKikimrProto::ERROR, "incorrect TEvVGetResult::TQueryResult from VDisk");
- } else if (blob.GetStatus() != NKikimrProto::OK) {
- return ReplyAndDie(NKikimrProto::ERROR, "incorrect blob status in returned index query");
- }
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(blob.GetBlobID());
- if (id.PartId()) {
- return ReplyAndDie(NKikimrProto::ERROR, "non-zero part id in returned index query");
- } else if (lastId && !(id < *lastId)) {
- return ReplyAndDie(NKikimrProto::ERROR, "incorrect sorting order in index query");
- }
- auto& layout = BlobMetadata[id];
- for (const ui32 partId : blob.GetParts()) {
- const ui32 nodeId = Info->GetIdxInSubgroup(vdiskId, id.Hash());
- if (nodeId == Info->Type.BlobSubgroupSize()) {
- return ReplyAndDie(NKikimrProto::ERROR, "blob does not match subgroup in index query");
- }
- layout.AddItem(nodeId, partId - 1, Info->Type);
- }
- lastId = id;
- }
- if (lastId) {
- // resume reading from this blob id
- disk.From = TLogoBlobID::PrevFull(*lastId, TLogoBlobID::MaxBlobSize);
- } else if (record.GetIsRangeOverflow()) {
- // not very sane answer
- return ReplyAndDie(NKikimrProto::ERROR, "empty index query result with overflow flag set");
- } else {
- // we got empty response and no overflow flag set -- this disk has definitely finished its stream
- disk.State = EDiskState::FINISHED;
- }
- break;
- }
-
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
- case NKikimrProto::OUT_OF_SPACE:
- FailedGroupDisks += {&Info->GetTopology(), vdiskId};
- if (!Info->GetTopology().GetQuorumChecker().CheckFailModelForGroup(FailedGroupDisks)) {
- return ReplyAndDie(NKikimrProto::ERROR, "failure model exceeded");
- } else {
- disk.State = EDiskState::FINISHED;
- }
- break;
-
- default:
- return ReplyAndDie(NKikimrProto::ERROR, "unexpected status code in TEvVGetResult");
- }
- // now we may have had some progress in reading blobs
- Process();
- }
-
- void Process() {
- if (GetIssuedFor || NumUnrepliedDisks) {
- return; // we have already issued Get-request, so wait for it to finish; otherwise wait for all disks to answer
- }
- while (!BlobMetadata.empty()) {
- const auto it = --BlobMetadata.end();
- const TLogoBlobID& id = it->first;
- const TSubgroupPartLayout& layout = it->second;
-
- // check the answer quorum for this blob
- TBlobStorageGroupInfo::TVDiskIds subgroup;
- ui32 numPendingDisks = Info->Type.BlobSubgroupSize();
- Info->PickSubgroup(id.Hash(), &subgroup, nullptr);
- for (const TVDiskID& vdiskId : subgroup) {
- TDiskState& disk = DiskState[Info->GetOrderNumber(vdiskId)];
- if (disk.Covered(id)) {
- --numPendingDisks; // this disk has already covered this blob
- } else if (disk.State == EDiskState::IDLE) {
- Y_VERIFY(disk.Replied);
- Y_VERIFY(disk.From != MaxBlobId);
- IssueRangeReadQuery(disk);
- } else {
- Y_VERIFY(disk.State == EDiskState::READ_PENDING);
- }
- }
- if (numPendingDisks) {
- return;
- }
- // this blob is fully answered, so we can make a decision whether it was written, can it be recovered,
- // can it be read, etc.
- TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&Info->GetTopology());
- for (ui32 nodeId = 0; nodeId < subgroup.size(); ++nodeId) {
- if (FailedGroupDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), subgroup[nodeId])) {
- failedSubgroupDisks |= {&Info->GetTopology(), nodeId};
- }
- }
- Doubted = false;
- switch (Info->GetTopology().GetQuorumChecker().GetBlobState(layout, failedSubgroupDisks)) {
- case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
- Y_FAIL("incorrect state"); // we should not reach this point as we check failure model a bit earlier
-
- case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
- // this blob is not recoverable, so, possibly, it must have never been written; we may skip it
- BlobMetadata.erase(it);
- break;
-
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
- Doubted = true;
+
+namespace NKikimr {
+
+class TBlobStorageGroupMirror3of4DiscoverRequest
+ : public TBlobStorageGroupRequestActor<TBlobStorageGroupMirror3of4DiscoverRequest>
+{
+ const ui64 TabletId;
+ const ui32 MinGeneration;
+ const TInstant StartTime;
+ const TInstant Deadline;
+ const bool ReadBody;
+ const bool DiscoverBlockedGeneration;
+ const ui32 ForceBlockedGeneration;
+
+public:
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveDiscover;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Discover;
+ }
+
+ TBlobStorageGroupMirror3of4DiscoverRequest(TIntrusivePtr<TBlobStorageGroupInfo> info,
+ TIntrusivePtr<TGroupQueues> state, const TActorId& source,
+ TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TEvBlobStorage::TEvDiscover *ev,
+ ui64 cookie, NWilson::TTraceId traceId, TInstant now,
+ TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
+ : TBlobStorageGroupRequestActor(std::move(info), std::move(state), std::move(mon), source, cookie,
+ std::move(traceId), NKikimrServices::BS_PROXY_DISCOVER, false, {}, now, storagePoolCounters,
+ ev->RestartCounter)
+ , TabletId(ev->TabletId)
+ , MinGeneration(ev->MinGeneration)
+ , StartTime(now)
+ , Deadline(ev->Deadline)
+ , ReadBody(ev->ReadBody)
+ , DiscoverBlockedGeneration(ev->DiscoverBlockedGeneration)
+ , ForceBlockedGeneration(ev->ForceBlockedGeneration)
+ {
+ for (size_t i = 0; i < DiskState.size(); ++i) {
+ TDiskState& disk = DiskState[i];
+ disk.VDiskId = Info->GetVDiskId(i);
+ disk.From = MaxBlobId;
+ }
+ }
+
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartDiscover;
+ auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, MinGeneration, ReadBody,
+ DiscoverBlockedGeneration, Deadline, ForceBlockedGeneration);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
+ void Bootstrap() {
+ A_LOG_INFO_S("DSPDX01", "bootstrap"
+ << " TabletId# " << TabletId
+ << " MinGeneration# " << MinGeneration
+ << " Deadline# " << Deadline
+ << " ReadBody# " << (ReadBody ? "true" : "false")
+ << " DiscoverBlockedGeneration# " << (DiscoverBlockedGeneration ? "true" : "false")
+ << " ForceBlockedGeneration# " << ForceBlockedGeneration
+ << " RestartCounter# " << RestartCounter);
+
+ Become(&TThis::StateFunc);
+
+ if (Deadline != TInstant::Max()) {
+ Schedule(Deadline - TActivationContext::Now(), new TEvents::TEvWakeup);
+ }
+
+ // start discovery by issuing range-read queries to all disks of a group
+ IssueRangeReadQueries();
+ }
+
+ void HandleWakeup() {
+ ReplyAndDie(NKikimrProto::DEADLINE);
+ }
+
+ void ReplyAndDie(NKikimrProto::EReplyStatus status, std::optional<TString> errorReason = std::nullopt) {
+ if (errorReason) {
+ ErrorReason = std::move(*errorReason);
+ }
+ Y_VERIFY(status != NKikimrProto::OK);
+ auto formatFailedGroupDisks = [&] {
+ TStringBuilder s;
+ s << "[";
+ bool first = true;
+ for (TDiskState& disk : DiskState) {
+ if (FailedGroupDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), disk.VDiskId)) {
+ s << (std::exchange(first, false) ? "" : " ") << disk.VDiskId;
+ }
+ }
+ s << "]";
+ return s;
+ };
+ R_LOG_ERROR_S("DSPDX02", "request failed"
+ << " Status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " ErrorReason# " << (ErrorReason ? ErrorReason : "<none>")
+ << " FailedGroupDisks# " << formatFailedGroupDisks());
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> response(new TEvBlobStorage::TEvDiscoverResult(status, MinGeneration,
+ 0U));
+ response->ErrorReason = ErrorReason;
+ SendResponseAndDie(std::move(response));
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Range-read scans
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ enum class EDiskState {
+ IDLE,
+ READ_PENDING,
+ FINISHED,
+ };
+
+ struct TDiskState {
+ TVDiskID VDiskId;
+ EDiskState State = EDiskState::IDLE;
+ TLogoBlobID From;
+ bool Replied = false;
+
+ // check if replies from this disk should cover provided blob id
+ bool Covered(const TLogoBlobID& id) const {
+ return State == EDiskState::FINISHED || From < id;
+ }
+ };
+
+ static constexpr ui32 MaxBlobsAtOnce = 32;
+ static constexpr auto HandleClass = NKikimrBlobStorage::EGetHandleClass::Discover;
+ const TLogoBlobID MaxBlobId{TabletId, Max<ui32>(), Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie};
+ std::vector<TDiskState> DiskState{Info->GetTotalVDisksNum()};
+ std::map<TLogoBlobID, TSubgroupPartLayout> BlobMetadata; // obtained through range queries
+ ui32 NumUnrepliedDisks = DiskState.size();
+ TBlobStorageGroupInfo::TGroupVDisks FailedGroupDisks{&Info->GetTopology()};
+ ui32 BlockedGeneration = 0;
+ std::optional<TLogoBlobID> GetIssuedFor;
+ bool Doubted = false;
+
+ void IssueRangeReadQueries() {
+ for (TDiskState& disk : DiskState) {
+ IssueRangeReadQuery(disk);
+ }
+ }
+
+ void IssueRangeReadQuery(TDiskState& state) {
+ const TLogoBlobID to = TLogoBlobID(TabletId, MinGeneration, 0, 0, 0, 0);
+ SendToQueue(TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(state.VDiskId, Deadline, HandleClass,
+ TEvBlobStorage::TEvVGet::EFlags::None, Nothing(), state.From, to, MaxBlobsAtOnce, nullptr,
+ ForceBlockedGeneration), 0, {} /*traceId*/);
+ const EDiskState prev = std::exchange(state.State, EDiskState::READ_PENDING);
+ Y_VERIFY(prev == EDiskState::IDLE);
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
+ ProcessReplyFromQueue(ev);
+ auto& record = ev->Get()->Record;
+ if (!record.HasStatus() || !record.HasVDiskID()) {
+ return ReplyAndDie(NKikimrProto::ERROR, "incorrect TEvVGetResult from VDisk");
+ }
+ if (record.HasBlockedGeneration() && record.GetBlockedGeneration() > BlockedGeneration) {
+ BlockedGeneration = record.GetBlockedGeneration();
+ }
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ TDiskState& disk = DiskState[Info->GetOrderNumber(vdiskId)];
+ Y_VERIFY_DEBUG(disk.VDiskId == vdiskId);
+ const EDiskState prev = std::exchange(disk.State, EDiskState::IDLE);
+ Y_VERIFY(prev == EDiskState::READ_PENDING);
+ NumUnrepliedDisks -= !std::exchange(disk.Replied, true);
+ switch (record.GetStatus()) {
+ case NKikimrProto::OK: {
+ std::optional<TLogoBlobID> lastId;
+ for (const auto& blob : record.GetResult()) {
+ if (!blob.HasStatus() || !blob.HasBlobID()) {
+ return ReplyAndDie(NKikimrProto::ERROR, "incorrect TEvVGetResult::TQueryResult from VDisk");
+ } else if (blob.GetStatus() != NKikimrProto::OK) {
+ return ReplyAndDie(NKikimrProto::ERROR, "incorrect blob status in returned index query");
+ }
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(blob.GetBlobID());
+ if (id.PartId()) {
+ return ReplyAndDie(NKikimrProto::ERROR, "non-zero part id in returned index query");
+ } else if (lastId && !(id < *lastId)) {
+ return ReplyAndDie(NKikimrProto::ERROR, "incorrect sorting order in index query");
+ }
+ auto& layout = BlobMetadata[id];
+ for (const ui32 partId : blob.GetParts()) {
+ const ui32 nodeId = Info->GetIdxInSubgroup(vdiskId, id.Hash());
+ if (nodeId == Info->Type.BlobSubgroupSize()) {
+ return ReplyAndDie(NKikimrProto::ERROR, "blob does not match subgroup in index query");
+ }
+ layout.AddItem(nodeId, partId - 1, Info->Type);
+ }
+ lastId = id;
+ }
+ if (lastId) {
+ // resume reading from this blob id
+ disk.From = TLogoBlobID::PrevFull(*lastId, TLogoBlobID::MaxBlobSize);
+ } else if (record.GetIsRangeOverflow()) {
+ // not very sane answer
+ return ReplyAndDie(NKikimrProto::ERROR, "empty index query result with overflow flag set");
+ } else {
+ // we got empty response and no overflow flag set -- this disk has definitely finished its stream
+ disk.State = EDiskState::FINISHED;
+ }
+ break;
+ }
+
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ case NKikimrProto::OUT_OF_SPACE:
+ FailedGroupDisks += {&Info->GetTopology(), vdiskId};
+ if (!Info->GetTopology().GetQuorumChecker().CheckFailModelForGroup(FailedGroupDisks)) {
+ return ReplyAndDie(NKikimrProto::ERROR, "failure model exceeded");
+ } else {
+ disk.State = EDiskState::FINISHED;
+ }
+ break;
+
+ default:
+ return ReplyAndDie(NKikimrProto::ERROR, "unexpected status code in TEvVGetResult");
+ }
+ // now we may have had some progress in reading blobs
+ Process();
+ }
+
+ void Process() {
+ if (GetIssuedFor || NumUnrepliedDisks) {
+ return; // we have already issued Get-request, so wait for it to finish; otherwise wait for all disks to answer
+ }
+ while (!BlobMetadata.empty()) {
+ const auto it = --BlobMetadata.end();
+ const TLogoBlobID& id = it->first;
+ const TSubgroupPartLayout& layout = it->second;
+
+ // check the answer quorum for this blob
+ TBlobStorageGroupInfo::TVDiskIds subgroup;
+ ui32 numPendingDisks = Info->Type.BlobSubgroupSize();
+ Info->PickSubgroup(id.Hash(), &subgroup, nullptr);
+ for (const TVDiskID& vdiskId : subgroup) {
+ TDiskState& disk = DiskState[Info->GetOrderNumber(vdiskId)];
+ if (disk.Covered(id)) {
+ --numPendingDisks; // this disk has already covered this blob
+ } else if (disk.State == EDiskState::IDLE) {
+ Y_VERIFY(disk.Replied);
+ Y_VERIFY(disk.From != MaxBlobId);
+ IssueRangeReadQuery(disk);
+ } else {
+ Y_VERIFY(disk.State == EDiskState::READ_PENDING);
+ }
+ }
+ if (numPendingDisks) {
+ return;
+ }
+ // this blob is fully answered, so we can make a decision whether it was written, can it be recovered,
+ // can it be read, etc.
+ TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&Info->GetTopology());
+ for (ui32 nodeId = 0; nodeId < subgroup.size(); ++nodeId) {
+ if (FailedGroupDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), subgroup[nodeId])) {
+ failedSubgroupDisks |= {&Info->GetTopology(), nodeId};
+ }
+ }
+ Doubted = false;
+ switch (Info->GetTopology().GetQuorumChecker().GetBlobState(layout, failedSubgroupDisks)) {
+ case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
+ Y_FAIL("incorrect state"); // we should not reach this point as we check failure model a bit earlier
+
+ case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
+ // this blob is not recoverable, so, possibly, it must have never been written; we may skip it
+ BlobMetadata.erase(it);
+ break;
+
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
+ Doubted = true;
[[fallthrough]];
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
- case TBlobStorageGroupInfo::EBS_FULL: {
- // we have to process this blob
- auto query = std::make_unique<TEvBlobStorage::TEvGet>(id, 0, 0, Deadline, HandleClass, true, !ReadBody, ForceBlockedGeneration);
- query->IsInternal = true;
- SendToBSProxy(SelfId(), Info->GroupID, query.release());
- GetIssuedFor = id;
- return;
- }
-
- default:
- Y_FAIL("unexpected blob state");
- }
- }
-
- // ensure there are no remaining blobs to handle
- Y_VERIFY(BlobMetadata.empty());
-
- // handle NODATA situation when all the disks are finished
- bool issuedMoreQueries = false;
- for (TDiskState& disk : DiskState) {
- if (disk.State == EDiskState::IDLE) {
- Y_VERIFY(disk.Replied);
- Y_VERIFY(disk.From != MaxBlobId);
- IssueRangeReadQuery(disk);
- issuedMoreQueries = true;
- }
- }
- if (!issuedMoreQueries) {
- SendResponseAndDie(std::make_unique<TEvBlobStorage::TEvDiscoverResult>(NKikimrProto::NODATA, MinGeneration,
- BlockedGeneration));
- }
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
- Y_VERIFY(GetIssuedFor);
- auto *msg = ev->Get();
- Y_VERIFY(msg->ResponseSz == 1);
- auto& resp = msg->Responses[0];
- Y_VERIFY(resp.Id == *GetIssuedFor);
- GetIssuedFor.reset();
- switch (resp.Status) {
- case NKikimrProto::NODATA:
- if (Doubted) {
- // we could not read correct (as we thought) blob
- ReplyAndDie(NKikimrProto::ERROR, "lost the blob");
- } else {
- // this blob recoverability is doubted, so we skip it and continue with the next blob
- BlobMetadata.erase(resp.Id);
- Process();
- }
- break;
-
- case NKikimrProto::ERROR:
- ReplyAndDie(NKikimrProto::ERROR, "TEvGet failed: " + msg->ErrorReason);
- break;
-
- case NKikimrProto::OK:
- SendResponseAndDie(std::make_unique<TEvBlobStorage::TEvDiscoverResult>(resp.Id, MinGeneration, resp.Buffer,
- BlockedGeneration));
- break;
-
- default:
- ReplyAndDie(NKikimrProto::ERROR, "unexpected TEvGetResult status");
- break;
- }
- }
-
- STATEFN(StateFunc) {
- if (ProcessEvent(ev)) {
- return;
- }
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
- }
- }
-};
-
-IActor* CreateBlobStorageGroupMirror3of4DiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
- ui64 cookie, NWilson::TTraceId traceId, TInstant now,
- TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
- return new TBlobStorageGroupMirror3of4DiscoverRequest(info, state, source, mon, ev, cookie, std::move(traceId), now,
- storagePoolCounters);
-}
-
-}//NKikimr
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
+ case TBlobStorageGroupInfo::EBS_FULL: {
+ // we have to process this blob
+ auto query = std::make_unique<TEvBlobStorage::TEvGet>(id, 0, 0, Deadline, HandleClass, true, !ReadBody, ForceBlockedGeneration);
+ query->IsInternal = true;
+ SendToBSProxy(SelfId(), Info->GroupID, query.release());
+ GetIssuedFor = id;
+ return;
+ }
+
+ default:
+ Y_FAIL("unexpected blob state");
+ }
+ }
+
+ // ensure there are no remaining blobs to handle
+ Y_VERIFY(BlobMetadata.empty());
+
+ // handle NODATA situation when all the disks are finished
+ bool issuedMoreQueries = false;
+ for (TDiskState& disk : DiskState) {
+ if (disk.State == EDiskState::IDLE) {
+ Y_VERIFY(disk.Replied);
+ Y_VERIFY(disk.From != MaxBlobId);
+ IssueRangeReadQuery(disk);
+ issuedMoreQueries = true;
+ }
+ }
+ if (!issuedMoreQueries) {
+ SendResponseAndDie(std::make_unique<TEvBlobStorage::TEvDiscoverResult>(NKikimrProto::NODATA, MinGeneration,
+ BlockedGeneration));
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
+ Y_VERIFY(GetIssuedFor);
+ auto *msg = ev->Get();
+ Y_VERIFY(msg->ResponseSz == 1);
+ auto& resp = msg->Responses[0];
+ Y_VERIFY(resp.Id == *GetIssuedFor);
+ GetIssuedFor.reset();
+ switch (resp.Status) {
+ case NKikimrProto::NODATA:
+ if (Doubted) {
+ // we could not read correct (as we thought) blob
+ ReplyAndDie(NKikimrProto::ERROR, "lost the blob");
+ } else {
+ // this blob recoverability is doubted, so we skip it and continue with the next blob
+ BlobMetadata.erase(resp.Id);
+ Process();
+ }
+ break;
+
+ case NKikimrProto::ERROR:
+ ReplyAndDie(NKikimrProto::ERROR, "TEvGet failed: " + msg->ErrorReason);
+ break;
+
+ case NKikimrProto::OK:
+ SendResponseAndDie(std::make_unique<TEvBlobStorage::TEvDiscoverResult>(resp.Id, MinGeneration, resp.Buffer,
+ BlockedGeneration));
+ break;
+
+ default:
+ ReplyAndDie(NKikimrProto::ERROR, "unexpected TEvGetResult status");
+ break;
+ }
+ }
+
+ STATEFN(StateFunc) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ }
+ }
+};
+
+IActor* CreateBlobStorageGroupMirror3of4DiscoverRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvDiscover *ev,
+ ui64 cookie, NWilson::TTraceId traceId, TInstant now,
+ TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
+ return new TBlobStorageGroupMirror3of4DiscoverRequest(info, state, source, mon, ev, cookie, std::move(traceId), now,
+ storagePoolCounters);
+}
+
+}//NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_encrypt.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_encrypt.cpp
index 85f2e913021..4a2a763dcf4 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_encrypt.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_encrypt.cpp
@@ -1,64 +1,64 @@
-#include "dsproxy_impl.h"
-
-namespace NKikimr {
-
- void Encrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
- const TBlobStorageGroupInfo &info) {
- switch (info.GetEncryptionMode()) {
- case TBlobStorageGroupInfo::EEM_NONE:
- {
- if (source != destination) {
- memcpy(destination, source, sizeBytes);
- }
- }
- return;
- case TBlobStorageGroupInfo::EEM_ENC_V1:
- {
- // Get the 'Tenant group key'
- const TCypherKey &tenantGroupKey = *info.GetCypherKey();
- Y_VERIFY(tenantGroupKey.GetIsKeySet());
- Y_VERIFY(tenantGroupKey.GetKeySizeBytes() == 32);
-
- // Obtain Hash_key(Tablet,Generation)
- THashCalculator keyHash;
- keyHash.SetKey(tenantGroupKey);
- ui64 tabletId = id.TabletID();
- keyHash.Hash(&tabletId, sizeof(ui64));
- ui32 generation = id.Generation();
- keyHash.Hash(&generation, sizeof(ui32));
- ui64 hash2 = 0;
- ui64 hash1 = keyHash.GetHashResult(&hash2);
-
- // Create the 'Blob key' in 2 steps:
- // 1) Copy the 'Teneat group key' to the 'Blob key'
- TCypherKey blobKey(tenantGroupKey);
- // 2) Mix-in the Hash_key(Tablet,Generation)
- ui8 *blobKeyData = nullptr;
- ui32 blobKeySizeBytes = 0;
- blobKey.MutableKeyBytes(&blobKeyData, &blobKeySizeBytes);
- Y_VERIFY(blobKeySizeBytes == 32);
- ui64 *p = (ui64*)blobKeyData;
- *p ^= hash1;
- p++;
- *p ^= hash2;
-
- // Preapre nonce = {Step(32), Cookie(24), Channel(8)}
- ui64 nonce = (ui64(id.Step()) << 32) | (ui64(id.Cookie()) << 8) | (ui64(id.Channel()));
-
- // Encrypt the data
- TStreamCypher cypher;
- cypher.SetKey(blobKey);
- cypher.StartMessage(nonce, shift);
- cypher.Encrypt(destination, source, sizeBytes);
- }
- return;
- }
- Y_VERIFY(false, "Unexpected Encryption Mode# %" PRIu64, (ui64)info.GetEncryptionMode());
- }
-
- void Decrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
- const TBlobStorageGroupInfo &info) {
- Encrypt(destination, source, shift, sizeBytes, id, info);
- }
-
-} // NKikimr
+#include "dsproxy_impl.h"
+
+namespace NKikimr {
+
+ void Encrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
+ const TBlobStorageGroupInfo &info) {
+ switch (info.GetEncryptionMode()) {
+ case TBlobStorageGroupInfo::EEM_NONE:
+ {
+ if (source != destination) {
+ memcpy(destination, source, sizeBytes);
+ }
+ }
+ return;
+ case TBlobStorageGroupInfo::EEM_ENC_V1:
+ {
+ // Get the 'Tenant group key'
+ const TCypherKey &tenantGroupKey = *info.GetCypherKey();
+ Y_VERIFY(tenantGroupKey.GetIsKeySet());
+ Y_VERIFY(tenantGroupKey.GetKeySizeBytes() == 32);
+
+ // Obtain Hash_key(Tablet,Generation)
+ THashCalculator keyHash;
+ keyHash.SetKey(tenantGroupKey);
+ ui64 tabletId = id.TabletID();
+ keyHash.Hash(&tabletId, sizeof(ui64));
+ ui32 generation = id.Generation();
+ keyHash.Hash(&generation, sizeof(ui32));
+ ui64 hash2 = 0;
+ ui64 hash1 = keyHash.GetHashResult(&hash2);
+
+ // Create the 'Blob key' in 2 steps:
+ // 1) Copy the 'Teneat group key' to the 'Blob key'
+ TCypherKey blobKey(tenantGroupKey);
+ // 2) Mix-in the Hash_key(Tablet,Generation)
+ ui8 *blobKeyData = nullptr;
+ ui32 blobKeySizeBytes = 0;
+ blobKey.MutableKeyBytes(&blobKeyData, &blobKeySizeBytes);
+ Y_VERIFY(blobKeySizeBytes == 32);
+ ui64 *p = (ui64*)blobKeyData;
+ *p ^= hash1;
+ p++;
+ *p ^= hash2;
+
+ // Preapre nonce = {Step(32), Cookie(24), Channel(8)}
+ ui64 nonce = (ui64(id.Step()) << 32) | (ui64(id.Cookie()) << 8) | (ui64(id.Channel()));
+
+ // Encrypt the data
+ TStreamCypher cypher;
+ cypher.SetKey(blobKey);
+ cypher.StartMessage(nonce, shift);
+ cypher.Encrypt(destination, source, sizeBytes);
+ }
+ return;
+ }
+ Y_VERIFY(false, "Unexpected Encryption Mode# %" PRIu64, (ui64)info.GetEncryptionMode());
+ }
+
+ void Decrypt(char *destination, const char *source, size_t shift, size_t sizeBytes, const TLogoBlobID &id,
+ const TBlobStorageGroupInfo &info) {
+ Encrypt(destination, source, shift, sizeBytes, id, info);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_get.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_get.cpp
index 9b08b418619..f5bb7e1eebd 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_get.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_get.cpp
@@ -1,5 +1,5 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
#include "root_cause.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h>
@@ -32,7 +32,7 @@ struct TEvAcceleratePut : public TEventLocal<TEvAcceleratePut, TEvBlobStorage::E
// GET request
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupGetRequest> {
+class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupGetRequest> {
TGetImpl GetImpl;
TRootCause RootCauseTrack;
NLWTrace::TOrbit Orbit;
@@ -44,7 +44,7 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
i64 ReportedBytes;
ui32 MaxSaneRequests = 0;
bool IsPutStarted = false;
-
+
struct TDiskCounters {
ui32 Sent = 0;
ui32 Received = 0;
@@ -59,62 +59,62 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
const bool IsVMultiPutMode = false;
- void Handle(TEvAccelerateGet::TPtr &ev) {
+ void Handle(TEvAccelerateGet::TPtr &ev) {
RootCauseTrack.OnAccelerate(ev->Get()->CauseIdx);
- AccelerateGet();
+ AccelerateGet();
}
- void Handle(TEvAcceleratePut::TPtr &ev) {
+ void Handle(TEvAcceleratePut::TPtr &ev) {
RootCauseTrack.OnAccelerate(ev->Get()->CauseIdx);
- AcceleratePut();
+ AcceleratePut();
}
- void AccelerateGet() {
+ void AccelerateGet() {
if (IsGetAccelerated) {
return;
}
IsGetAccelerated = true;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
if (IsVMultiPutMode) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
GetImpl.AccelerateGet(LogCtx, GetUnresponsiveDiskOrderNumber(), vGets, vMultiPuts);
*Mon->NodeMon->AccelerateEvVMultiPutCount += vMultiPuts.size();
*Mon->NodeMon->AccelerateEvVGetCount += vGets.size();
- SendVGetsAndVPuts(vGets, vMultiPuts);
+ SendVGetsAndVPuts(vGets, vMultiPuts);
} else {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
GetImpl.AccelerateGet(LogCtx, GetUnresponsiveDiskOrderNumber(), vGets, vPuts);
*Mon->NodeMon->AccelerateEvVPutCount += vPuts.size();
*Mon->NodeMon->AccelerateEvVGetCount += vGets.size();
- SendVGetsAndVPuts(vGets, vPuts);
+ SendVGetsAndVPuts(vGets, vPuts);
}
}
- void AcceleratePut() {
+ void AcceleratePut() {
if (IsPutAccelerated) {
return;
}
IsPutAccelerated = true;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
if (IsVMultiPutMode) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
GetImpl.AcceleratePut(LogCtx, GetUnresponsiveDiskOrderNumber(), vGets, vMultiPuts);
*Mon->NodeMon->AccelerateEvVMultiPutCount += vMultiPuts.size();
*Mon->NodeMon->AccelerateEvVGetCount += vGets.size();
- SendVGetsAndVPuts(vGets, vMultiPuts);
+ SendVGetsAndVPuts(vGets, vMultiPuts);
} else {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
GetImpl.AcceleratePut(LogCtx, GetUnresponsiveDiskOrderNumber(), vGets, vPuts);
*Mon->NodeMon->AccelerateEvVPutCount += vPuts.size();
*Mon->NodeMon->AccelerateEvVGetCount += vGets.size();
- SendVGetsAndVPuts(vGets, vPuts);
+ SendVGetsAndVPuts(vGets, vPuts);
}
}
- template <typename TPutEvent>
- void SendVGetsAndVPuts(TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TPutEvent>> &vPuts) {
+ template <typename TPutEvent>
+ void SendVGetsAndVPuts(TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TPutEvent>> &vPuts) {
ReportBytes(GetImpl.GrabBytesToReport());
RequestsSent += vGets.size();
RequestsSent += vPuts.size();
@@ -122,7 +122,7 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
if (vPuts.size()) {
if (!IsPutStarted) {
IsPutStarted = true;
- StartTimePut = TActivationContext::Now();
+ StartTimePut = TActivationContext::Now();
}
}
for (size_t i = 0; i < vGets.size(); ++i) {
@@ -157,8 +157,8 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
DiskCounters[orderNumber].Sent++;
}
- SendToQueues(vGets, false);
- SendToQueues(vPuts, false);
+ SendToQueues(vGets, false);
+ SendToQueues(vPuts, false);
}
ui32 CountDisksWithActiveRequests() {
@@ -181,15 +181,15 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
return unresponsiveDiskOrderNumber;
}
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
const ui64 cyclesPerUs = NHPTimer::GetCyclesPerSecond() / 1000000;
ev->Get()->Record.MutableTimestamps()->SetReceivedByDSProxyUs(GetCycleCountFast() / cyclesPerUs);
const NKikimrBlobStorage::TEvVGetResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
-
+
ui64 totalSize = 0;
ui64 tabletId = 0;
ui32 channel = 0;
@@ -202,8 +202,8 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
tabletId = blob.TabletID();
channel = blob.Channel();
}
- ++GeneratedSubrequests;
- GeneratedSubrequestBytes += totalSize;
+ ++GeneratedSubrequests;
+ GeneratedSubrequestBytes += totalSize;
Y_VERIFY(record.HasVDiskID());
const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
@@ -231,24 +231,24 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
DiskCounters[orderNumber].Received++;
- // generate wilson event with merging into trunk
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
-
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ // generate wilson event with merging into trunk
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
+
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
ResponsesReceived++;
if (IsVMultiPutMode) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
GetImpl.OnVGetResult(LogCtx, *ev->Get(), vGets, vMultiPuts, getResult);
- SendVGetsAndVPuts(vGets, vMultiPuts);
+ SendVGetsAndVPuts(vGets, vMultiPuts);
} else {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
GetImpl.OnVGetResult(LogCtx, *ev->Get(), vGets, vPuts, getResult);
- SendVGetsAndVPuts(vGets, vPuts);
+ SendVGetsAndVPuts(vGets, vPuts);
}
if (getResult) {
- SendReplyAndDie(getResult);
+ SendReplyAndDie(getResult);
return;
}
Y_VERIFY(RequestsSent > ResponsesReceived, "RequestsSent# %" PRIu32 " ResponsesReceived# %" PRIu32
@@ -256,12 +256,12 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
TryScheduleGetAcceleration();
if (IsPutStarted) {
- TrySchedulePutAcceleration();
+ TrySchedulePutAcceleration();
}
- SanityCheck(); // May Die
+ SanityCheck(); // May Die
}
- void SanityCheck() {
+ void SanityCheck() {
if (RequestsSent <= MaxSaneRequests) {
return;
}
@@ -271,7 +271,7 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
<< " requests, internal state# " << GetImpl.DumpFullState();
ErrorReason = err.Str();
R_LOG_CRIT_S("BPG70", ErrorReason);
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
}
TLogoBlobID GetFirstBlobId(TEvBlobStorage::TEvVPutResult::TPtr &ev) {
@@ -296,38 +296,38 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
return sum;
}
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- HandleVPutResult<TEvBlobStorage::TEvVPut, TEvBlobStorage::TEvVPutResult>(ev);
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ HandleVPutResult<TEvBlobStorage::TEvVPut, TEvBlobStorage::TEvVPutResult>(ev);
}
- void Handle(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- HandleVPutResult<TEvBlobStorage::TEvVMultiPut, TEvBlobStorage::TEvVMultiPutResult>(ev);
+ void Handle(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ HandleVPutResult<TEvBlobStorage::TEvVMultiPut, TEvBlobStorage::TEvVMultiPutResult>(ev);
}
- bool HandleVPutInnerErrorStatuses(TEvBlobStorage::TEvVPutResult::TPtr &ev,
+ bool HandleVPutInnerErrorStatuses(TEvBlobStorage::TEvVPutResult::TPtr &ev,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult)
{
- Y_UNUSED(ev, outGetResult);
+ Y_UNUSED(ev, outGetResult);
return false;
}
- bool HandleVPutInnerErrorStatuses(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev,
+ bool HandleVPutInnerErrorStatuses(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult)
{
const auto &record = ev->Get()->Record;
const NKikimrProto::EReplyStatus status = record.GetStatus();
const TVDiskID vDiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- for (auto &item : record.GetItems()) {
+ for (auto &item : record.GetItems()) {
Y_VERIFY(item.HasStatus());
Y_VERIFY(item.HasBlobID());
Y_VERIFY(item.HasCookie());
NKikimrProto::EReplyStatus itemStatus = item.GetStatus();
TLogoBlobID blobId = LogoBlobIDFromLogoBlobID(item.GetBlobID());
- Y_VERIFY(itemStatus != NKikimrProto::RACE); // we should get RACE for the whole request and handle it in CheckForTermErrors
- if (itemStatus == NKikimrProto::BLOCKED || itemStatus == NKikimrProto::DEADLINE) {
+ Y_VERIFY(itemStatus != NKikimrProto::RACE); // we should get RACE for the whole request and handle it in CheckForTermErrors
+ if (itemStatus == NKikimrProto::BLOCKED || itemStatus == NKikimrProto::DEADLINE) {
R_LOG_ERROR_S("BPG26", "Handle TEvVMultiPutResultItem"
<< " blobId# " << blobId.ToString()
<< " status# " << NKikimrProto::EReplyStatus_Name(status)
@@ -348,11 +348,11 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
template <typename TPutEvent, typename TPutEventResult>
- void HandleVPutResult(typename TPutEventResult::TPtr &ev) {
+ void HandleVPutResult(typename TPutEventResult::TPtr &ev) {
Y_VERIFY(ev->Get()->Record.HasStatus());
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
-
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
+
const ui64 cyclesPerUs = NHPTimer::GetCyclesPerSecond() / 1000000;
ev->Get()->Record.MutableTimestamps()->SetReceivedByDSProxyUs(GetCycleCountFast() / cyclesPerUs);
const auto &record = ev->Get()->Record;
@@ -362,7 +362,7 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
NActors::NLog::EPriority priority = PriorityForStatusInbound(status);
A_LOG_LOG_S(priority != NActors::NLog::PRI_DEBUG, priority, "BPG30", "Handle VPuEventResult"
<< " status# " << NKikimrProto::EReplyStatus_Name(status).data()
- << " node# " << GetVDiskActorId(shortId).NodeId());
+ << " node# " << GetVDiskActorId(shortId).NodeId());
const TLogoBlobID blob = GetFirstBlobId(ev);
ui64 sumBlobSize = SumBlobSize(ev);
@@ -389,27 +389,27 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
DiskCounters[orderNumber].Received++;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TPutEvent>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TPutEvent>> vPuts;
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
ResponsesReceived++;
- if (HandleVPutInnerErrorStatuses(ev, getResult)) {
+ if (HandleVPutInnerErrorStatuses(ev, getResult)) {
Y_VERIFY(getResult);
- SendReplyAndDie(getResult);
+ SendReplyAndDie(getResult);
return;
}
- GetImpl.OnVPutResult(LogCtx, *ev->Get(), vGets, vPuts, getResult);
- SendVGetsAndVPuts(vGets, vPuts);
+ GetImpl.OnVPutResult(LogCtx, *ev->Get(), vGets, vPuts, getResult);
+ SendVGetsAndVPuts(vGets, vPuts);
if (getResult) {
- SendReplyAndDie(getResult);
+ SendReplyAndDie(getResult);
return;
}
- Y_VERIFY(RequestsSent > ResponsesReceived, "RequestsSent# %" PRIu64 " ResponsesReceived# %" PRIu64,
- ui64(RequestsSent), ui64(ResponsesReceived));
+ Y_VERIFY(RequestsSent > ResponsesReceived, "RequestsSent# %" PRIu64 " ResponsesReceived# %" PRIu64,
+ ui64(RequestsSent), ui64(ResponsesReceived));
- TrySchedulePutAcceleration();
- SanityCheck(); // May Die
+ TrySchedulePutAcceleration();
+ SanityCheck(); // May Die
}
void TryScheduleGetAcceleration() {
@@ -431,12 +431,12 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
}
- void TrySchedulePutAcceleration() {
+ void TrySchedulePutAcceleration() {
if (!IsPutAccelerateScheduled && !IsPutAccelerated) {
// Count VDisks that have requests in flight, if there is exactly one such VDisk, Accelerate
if (CountDisksWithActiveRequests() <= 1) {
ui64 timeToAccelerateUs = GetImpl.GetTimeToAcceleratePutNs(LogCtx) / 1000;
- TInstant now = TActivationContext::Now();
+ TInstant now = TActivationContext::Now();
TDuration timeSinceStart = (now > StartTimePut) ? (now - StartTimePut) : TDuration::MilliSeconds(0);
if (timeSinceStart.MicroSeconds() < timeToAccelerateUs) {
ui64 causeIdx = RootCauseTrack.RegisterAccelerate();
@@ -444,22 +444,22 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
new TEvAcceleratePut(causeIdx));
IsPutAccelerateScheduled = true;
} else {
- AcceleratePut();
+ AcceleratePut();
}
}
}
}
- void SendReplyAndDie(TAutoPtr<TEvBlobStorage::TEvGetResult> &evResult) {
+ void SendReplyAndDie(TAutoPtr<TEvBlobStorage::TEvGetResult> &evResult) {
const NKikimrProto::EReplyStatus status = evResult->Status;
- const TInstant now = TActivationContext::Now();
+ const TInstant now = TActivationContext::Now();
const TDuration duration = (now > StartTime) ? (now - StartTime) : TDuration::MilliSeconds(0);
Mon->CountGetResponseTime(Info->GetDeviceType(), GetImpl.GetHandleClass(), evResult->PayloadSizeBytes(), duration);
*Mon->ActiveGetCapacity -= ReportedBytes;
ReportedBytes = 0;
- bool success = evResult->Status == NKikimrProto::OK;
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultSent, ReplyStatus = status,
- ResponseSize = GetImpl.GetReplyBytes());
+ bool success = evResult->Status == NKikimrProto::OK;
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultSent, ReplyStatus = status,
+ ResponseSize = GetImpl.GetReplyBytes());
ui64 requestSize = 0;
ui64 tabletId = 0;
ui32 channel = 0;
@@ -474,36 +474,36 @@ class TBlobStorageGroupGetRequest : public TBlobStorageGroupRequestActor<TBlobSt
LWPROBE(DSProxyRequestDuration, TEvBlobStorage::EvGet, requestSize, duration.SecondsFloat() * 1000.0, tabletId,
evResult->GroupId, channel, NKikimrBlobStorage::EGetHandleClass_Name(GetImpl.GetHandleClass()),
success);
- return SendResponseAndDie(std::unique_ptr<TEvBlobStorage::TEvGetResult>(evResult.Release()));
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartIndexRestoreGet;
- return GetImpl.RestartQuery(counter);
+ return SendResponseAndDie(std::unique_ptr<TEvBlobStorage::TEvGetResult>(evResult.Release()));
}
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartIndexRestoreGet;
+ return GetImpl.RestartQuery(counter);
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_GET_ACTOR;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Get;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveGet;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_GET_ACTOR;
}
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Get;
+ }
+
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveGet;
+ }
+
TBlobStorageGroupGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev, ui64 cookie,
- NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout, TMaybe<TGroupStat::EKind> latencyQueueKind,
+ NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout, TMaybe<TGroupStat::EKind> latencyQueueKind,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters, bool isVMultiPutMode)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
NKikimrServices::BS_PROXY_GET, ev->IsVerboseNoDataEnabled || ev->CollectDebugInfo,
- latencyQueueKind, now, storagePoolCounters, ev->RestartCounter)
- , GetImpl(info, state, ev, std::move(nodeLayout), LogCtx.RequestPrefix)
+ latencyQueueKind, now, storagePoolCounters, ev->RestartCounter)
+ , GetImpl(info, state, ev, std::move(nodeLayout), LogCtx.RequestPrefix)
, Orbit(std::move(ev->Orbit))
, Deadline(ev->Deadline)
, StartTime(now)
@@ -515,7 +515,7 @@ public:
{
ReportBytes(sizeof(*this));
MaxSaneRequests = ev->QuerySize * info->Type.TotalPartCount() * (1 + info->Type.Handoff()) * 3;
-
+
RequestBytes = GetImpl.CountRequestBytes();
RequestHandleClass = HandleClassToHandleClass(ev->GetHandleClass);
if (Orbit.HasShuttles()) {
@@ -528,58 +528,58 @@ public:
*Mon->ActiveGetCapacity += bytes;
}
- void Bootstrap() {
- A_LOG_INFO_S("BPG01", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " Query# " << GetImpl.DumpQuery()
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
+ void Bootstrap() {
+ A_LOG_INFO_S("BPG01", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " Query# " << GetImpl.DumpQuery()
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
LWTRACK(DSProxyGetBootstrap, Orbit);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetReceived);
-
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
- GetImpl.GenerateInitialRequests(LogCtx, vGets);
- SendVGetsAndVPuts(vGets, vPuts);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetReceived);
+
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ GetImpl.GenerateInitialRequests(LogCtx, vGets);
+ SendVGetsAndVPuts(vGets, vPuts);
TryScheduleGetAcceleration();
Y_VERIFY(RequestsSent > ResponsesReceived);
Become(&TThis::StateWait);
- SanityCheck(); // May Die
+ SanityCheck(); // May Die
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupGetRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- GetImpl.PrepareReply(status, LogCtx, getResult);
+ GetImpl.PrepareReply(status, LogCtx, getResult);
getResult->ErrorReason = ErrorReason;
- SendReplyAndDie(getResult);
+ SendReplyAndDie(getResult);
return;
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
- hFunc(TEvBlobStorage::TEvVPutResult, Handle);
- hFunc(TEvBlobStorage::TEvVMultiPutResult, Handle);
- hFunc(TEvAccelerateGet, Handle);
- hFunc(TEvAcceleratePut, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVPutResult, Handle);
+ hFunc(TEvBlobStorage::TEvVMultiPutResult, Handle);
+ hFunc(TEvAccelerateGet, Handle);
+ hFunc(TEvAcceleratePut, Handle);
}
}
};
IActor* CreateBlobStorageGroupGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
- ui64 cookie, NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout,
+ ui64 cookie, NWilson::TTraceId traceId, TNodeLayoutInfoPtr&& nodeLayout,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters, bool isVMultiPutMode) {
- return new TBlobStorageGroupGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
+ return new TBlobStorageGroupGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
std::move(nodeLayout), latencyQueueKind, now, storagePoolCounters, isVMultiPutMode);
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
index 0583b454df6..56c31231c81 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.cpp
@@ -4,19 +4,19 @@
#include "dsproxy_strategy_base.h"
#include "dsproxy_blackboard.h"
-#include "dsproxy_strategy_get_m3dc_basic.h"
-#include "dsproxy_strategy_get_m3dc_restore.h"
-#include "dsproxy_strategy_get_m3of4.h"
+#include "dsproxy_strategy_get_m3dc_basic.h"
+#include "dsproxy_strategy_get_m3dc_restore.h"
+#include "dsproxy_strategy_get_m3of4.h"
#include "dsproxy_strategy_restore.h"
#include "dsproxy_strategy_get_bold.h"
#include "dsproxy_strategy_get_min_iops_block.h"
#include "dsproxy_strategy_get_min_iops_mirror.h"
-
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
+
namespace NKikimr {
-void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx,
+void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
outGetResult.Reset(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
ReplyBytes = 0;
@@ -28,8 +28,8 @@ void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logC
TEvBlobStorage::TEvGetResult::TResponse &outResponse = outGetResult->Responses[i];
outResponse.Status = status;
outResponse.Id = query.Id;
- outResponse.Shift = query.Shift;
- outResponse.RequestedSize = query.Size;
+ outResponse.Shift = query.Shift;
+ outResponse.RequestedSize = query.Size;
}
} else {
for (ui32 i = 0, e = QuerySize; i != e; ++i) {
@@ -38,82 +38,82 @@ void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logC
const TBlobState &blobState = Blackboard.GetState(query.Id);
outResponse.Id = query.Id;
- outResponse.PartMap = blobState.PartMap;
- if (blobState.WholeSituation == TBlobState::ESituation::Absent) {
- bool okay = true;
-
- // extra validation code for phantom logic
- if (PhantomCheck) {
- TSubgroupPartLayout possiblyWritten;
-
- for (ui32 idxInSubgroup = 0; idxInSubgroup < blobState.Disks.size(); ++idxInSubgroup) {
- const auto& disk = blobState.Disks[idxInSubgroup];
- for (ui32 partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
- bool possible;
- switch (Info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- possible = partIdx == idxInSubgroup % 3;
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- possible = idxInSubgroup >= 4 || partIdx == (idxInSubgroup & 1) || partIdx == 2;
- break;
-
- default:
- possible = idxInSubgroup == partIdx || idxInSubgroup >= Info->Type.TotalPartCount();
- break;
- }
- if (!possible) {
- continue;
- }
- switch (disk.DiskParts[partIdx].Situation) {
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Error:
- case TBlobState::ESituation::Present:
- case TBlobState::ESituation::Sent:
- possiblyWritten.AddItem(idxInSubgroup, partIdx, Info->Type);
- break;
-
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
- // sure we don't have this part
- break;
- }
- }
- }
-
- switch (Info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- if (possiblyWritten.GetDisksWithPart(0) || possiblyWritten.GetDisksWithPart(1) ||
- possiblyWritten.GetDisksWithPart(2)) {
- okay = false;
- }
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- if (possiblyWritten.GetDisksWithPart(0) || possiblyWritten.GetDisksWithPart(1)) {
- okay = false;
- }
- break;
-
- default: {
- ui32 numDistinctParts = 0;
- for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
- if (possiblyWritten.GetDisksWithPart(partIdx)) {
- ++numDistinctParts;
- }
- }
- if (numDistinctParts >= Info->Type.MinimalRestorablePartCount()) {
- okay = false;
- }
- break;
- }
- }
- }
-
- outResponse.Status = okay ? NKikimrProto::NODATA : NKikimrProto::ERROR;
+ outResponse.PartMap = blobState.PartMap;
+ if (blobState.WholeSituation == TBlobState::ESituation::Absent) {
+ bool okay = true;
+
+ // extra validation code for phantom logic
+ if (PhantomCheck) {
+ TSubgroupPartLayout possiblyWritten;
+
+ for (ui32 idxInSubgroup = 0; idxInSubgroup < blobState.Disks.size(); ++idxInSubgroup) {
+ const auto& disk = blobState.Disks[idxInSubgroup];
+ for (ui32 partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
+ bool possible;
+ switch (Info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ possible = partIdx == idxInSubgroup % 3;
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ possible = idxInSubgroup >= 4 || partIdx == (idxInSubgroup & 1) || partIdx == 2;
+ break;
+
+ default:
+ possible = idxInSubgroup == partIdx || idxInSubgroup >= Info->Type.TotalPartCount();
+ break;
+ }
+ if (!possible) {
+ continue;
+ }
+ switch (disk.DiskParts[partIdx].Situation) {
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Error:
+ case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Sent:
+ possiblyWritten.AddItem(idxInSubgroup, partIdx, Info->Type);
+ break;
+
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
+ // sure we don't have this part
+ break;
+ }
+ }
+ }
+
+ switch (Info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ if (possiblyWritten.GetDisksWithPart(0) || possiblyWritten.GetDisksWithPart(1) ||
+ possiblyWritten.GetDisksWithPart(2)) {
+ okay = false;
+ }
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ if (possiblyWritten.GetDisksWithPart(0) || possiblyWritten.GetDisksWithPart(1)) {
+ okay = false;
+ }
+ break;
+
+ default: {
+ ui32 numDistinctParts = 0;
+ for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
+ if (possiblyWritten.GetDisksWithPart(partIdx)) {
+ ++numDistinctParts;
+ }
+ }
+ if (numDistinctParts >= Info->Type.MinimalRestorablePartCount()) {
+ okay = false;
+ }
+ break;
+ }
+ }
+ }
+
+ outResponse.Status = okay ? NKikimrProto::NODATA : NKikimrProto::ERROR;
IsNoData = true;
- } else if (blobState.WholeSituation == TBlobState::ESituation::Present) {
+ } else if (blobState.WholeSituation == TBlobState::ESituation::Present) {
outResponse.Status = NKikimrProto::OK;
outResponse.Shift = query.Shift;
outResponse.RequestedSize = query.Size;
@@ -121,16 +121,16 @@ void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logC
ui32 shift = Min(query.Shift, query.Id.BlobSize());
ui32 size = query.Size ? Min(query.Size, query.Id.BlobSize() - shift) : query.Id.BlobSize() - shift;
- if (!PhantomCheck) {
- TString data = TString::Uninitialized(size);
- char *dataBuffer = data.Detach();
- blobState.Whole.Data.Read(shift, dataBuffer, size);
- Decrypt(dataBuffer, dataBuffer, shift, size, query.Id, *Info);
- outResponse.Buffer = std::move(data);
- Y_VERIFY(outResponse.Buffer, "%s empty response buffer", RequestPrefix.data());
- ReplyBytes += outResponse.Buffer.size();
- }
- } else if (blobState.WholeSituation == TBlobState::ESituation::Error) {
+ if (!PhantomCheck) {
+ TString data = TString::Uninitialized(size);
+ char *dataBuffer = data.Detach();
+ blobState.Whole.Data.Read(shift, dataBuffer, size);
+ Decrypt(dataBuffer, dataBuffer, shift, size, query.Id, *Info);
+ outResponse.Buffer = std::move(data);
+ Y_VERIFY(outResponse.Buffer, "%s empty response buffer", RequestPrefix.data());
+ ReplyBytes += outResponse.Buffer.size();
+ }
+ } else if (blobState.WholeSituation == TBlobState::ESituation::Error) {
outResponse.Status = NKikimrProto::ERROR;
} else {
Y_VERIFY(false, "Id# %s BlobState# %s", query.Id.ToString().c_str(), blobState.ToString().data());
@@ -138,11 +138,11 @@ void TGetImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logC
}
}
NActors::NLog::EPriority priority = PriorityForStatusOutbound(status);
- A_LOG_LOG_SX(logCtx, priority != NActors::NLog::PRI_DEBUG, priority, "BPG29", "Response# " << outGetResult->Print(false));
- if (CollectDebugInfo || (IsVerboseNoDataEnabled && IsNoData)) {
+ A_LOG_LOG_SX(logCtx, priority != NActors::NLog::PRI_DEBUG, priority, "BPG29", "Response# " << outGetResult->Print(false));
+ if (CollectDebugInfo || (IsVerboseNoDataEnabled && IsNoData)) {
TStringStream str;
- logCtx.LogAcc.Output(str);
- outGetResult->DebugInfo = str.Str();
+ logCtx.LogAcc.Output(str);
+ outGetResult->DebugInfo = str.Str();
}
IsReplied = true;
}
@@ -156,12 +156,12 @@ ui64 TGetImpl::GetTimeToAccelerateNs(TLogContext &logCtx, NKikimrBlobStorage::EV
if (Blackboard.BlobStates.size() == 1) {
i32 worstSubgroupIdx = -1;
Blackboard.BlobStates.begin()->second.GetWorstPredictedDelaysNs(
- *Info, *Blackboard.GroupQueues, queueId,
+ *Info, *Blackboard.GroupQueues, queueId,
&worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
} else {
i32 worstOrderNumber = -1;
Blackboard.GetWorstPredictedDelaysNs(
- *Info, *Blackboard.GroupQueues, queueId,
+ *Info, *Blackboard.GroupQueues, queueId,
&worstPredictedNs, &nextToWorstPredictedNs, &worstOrderNumber);
}
return nextToWorstPredictedNs * 1;
@@ -235,7 +235,7 @@ TString TGetImpl::DumpFullState() const {
return str.Str();
}
-void TGetImpl::GenerateInitialRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets) {
+void TGetImpl::GenerateInitialRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets) {
Y_VERIFY(QuerySize != 0, "internal consistency error");
// TODO(cthulhu): query politics
@@ -245,21 +245,21 @@ void TGetImpl::GenerateInitialRequests(TLogContext &logCtx, TDeque<std::unique_p
for (ui32 queryIdx = 0; queryIdx < QuerySize; ++queryIdx) {
const TEvBlobStorage::TEvGet::TQuery &query = Queries[queryIdx];
- R_LOG_DEBUG_SX(logCtx, "BPG56", "query.Id# " << query.Id.ToString()
- << " shift# " << query.Shift
- << " size# " << query.Size);
+ R_LOG_DEBUG_SX(logCtx, "BPG56", "query.Id# " << query.Id.ToString()
+ << " shift# " << query.Shift
+ << " size# " << query.Size);
Blackboard.AddNeeded(query.Id, query.Shift, query.Size);
}
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> outVPuts;
- bool workDone = Step(logCtx, outVGets, outVPuts, getResult);
- Y_VERIFY(outVPuts.empty());
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> outVPuts;
+ bool workDone = Step(logCtx, outVGets, outVPuts, getResult);
+ Y_VERIFY(outVPuts.empty());
Y_VERIFY(getResult.Get() == nullptr);
- Y_VERIFY(workDone);
+ Y_VERIFY(workDone);
}
-void TGetImpl::PrepareRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets) {
+void TGetImpl::PrepareRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets) {
for (ui32 diskOrderNumber = 0; diskOrderNumber < Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber.size();
++diskOrderNumber) {
TDiskRequests &requests = Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber[diskOrderNumber];
@@ -267,33 +267,33 @@ void TGetImpl::PrepareRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBl
ui32 beginIdx = requests.FirstUnsentRequestIdx;
if (beginIdx < endIdx) {
- TVDiskID vDiskId = Info->GetVDiskId(diskOrderNumber);
+ TVDiskID vDiskId = Info->GetVDiskId(diskOrderNumber);
auto vGet = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId, Deadline, Blackboard.GetHandleClass,
TEvBlobStorage::TEvVGet::EFlags::None, TVGetCookie(beginIdx, endIdx), {}, ForceBlockedGeneration);
for (ui32 idx = beginIdx; idx < endIdx; ++idx) {
- TDiskGetRequest &get = requests.GetsToSend[idx];
+ TDiskGetRequest &get = requests.GetsToSend[idx];
ui64 cookie = idx;
vGet->AddExtremeQuery(get.Id, get.Shift, get.Size, &cookie);
- if (ReportDetailedPartMap) {
- get.PartMapIndex = Blackboard.AddPartMap(get.Id, diskOrderNumber, RequestIndex);
- }
+ if (ReportDetailedPartMap) {
+ get.PartMapIndex = Blackboard.AddPartMap(get.Id, diskOrderNumber, RequestIndex);
+ }
}
- vGet->Record.SetSuppressBarrierCheck(IsInternal);
+ vGet->Record.SetSuppressBarrierCheck(IsInternal);
vGet->Record.SetTabletId(TabletId);
vGet->Record.SetAcquireBlockedGeneration(AcquireBlockedGeneration);
- R_LOG_DEBUG_SX(logCtx, "BPG14", "Send get to orderNumber# " << diskOrderNumber
- << " beginIdx# " << beginIdx
- << " endIdx# " << endIdx
- << " vGet# " << vGet->ToString());
- outVGets.push_back(std::move(vGet));
- ++RequestIndex;
+ R_LOG_DEBUG_SX(logCtx, "BPG14", "Send get to orderNumber# " << diskOrderNumber
+ << " beginIdx# " << beginIdx
+ << " endIdx# " << endIdx
+ << " vGet# " << vGet->ToString());
+ outVGets.push_back(std::move(vGet));
+ ++RequestIndex;
Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber[diskOrderNumber].FirstUnsentRequestIdx = endIdx;
}
}
}
-void TGetImpl::PrepareVPuts(TLogContext &logCtx,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts) {
+void TGetImpl::PrepareVPuts(TLogContext &logCtx,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts) {
for (ui32 diskOrderNumber = 0; diskOrderNumber < Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber.size();
++diskOrderNumber) {
const TDiskRequests &requests = Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber[diskOrderNumber];
@@ -301,16 +301,16 @@ void TGetImpl::PrepareVPuts(TLogContext &logCtx,
ui32 beginIdx = requests.FirstUnsentPutIdx;
if (beginIdx < endIdx) {
- TVDiskID vDiskId = Info->GetVDiskId(diskOrderNumber);
+ TVDiskID vDiskId = Info->GetVDiskId(diskOrderNumber);
for (ui32 idx = beginIdx; idx < endIdx; ++idx) {
const TDiskPutRequest &put = requests.PutsToSend[idx];
ui64 cookie = TBlobCookie(diskOrderNumber, put.BlobIdx, put.Id.PartId(),
VPutRequests);
- auto vPut = std::make_unique<TEvBlobStorage::TEvVPut>(put.Id, put.Buffer, vDiskId, true, &cookie,
- Deadline, Blackboard.PutHandleClass);
- R_LOG_DEBUG_SX(logCtx, "BPG15", "Send put to orderNumber# " << diskOrderNumber << " idx# " << idx
- << " vPut# " << vPut->ToString());
- outVPuts.push_back(std::move(vPut));
+ auto vPut = std::make_unique<TEvBlobStorage::TEvVPut>(put.Id, put.Buffer, vDiskId, true, &cookie,
+ Deadline, Blackboard.PutHandleClass);
+ R_LOG_DEBUG_SX(logCtx, "BPG15", "Send put to orderNumber# " << diskOrderNumber << " idx# " << idx
+ << " vPut# " << vPut->ToString());
+ outVPuts.push_back(std::move(vPut));
++VPutRequests;
ReceivedVPutResponses.push_back(false);
}
@@ -320,7 +320,7 @@ void TGetImpl::PrepareVPuts(TLogContext &logCtx,
}
void TGetImpl::PrepareVPuts(TLogContext &logCtx,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts) {
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts) {
for (ui32 diskOrderNumber = 0; diskOrderNumber < Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber.size();
++diskOrderNumber) {
const TDiskRequests &requests = Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber[diskOrderNumber];
@@ -329,8 +329,8 @@ void TGetImpl::PrepareVPuts(TLogContext &logCtx,
if (beginIdx < endIdx) {
TVDiskID vDiskId = Info->GetVDiskId(diskOrderNumber);
// set cookie after adding items
- auto vMultiPut = std::make_unique<TEvBlobStorage::TEvVMultiPut>(vDiskId, Deadline, Blackboard.PutHandleClass,
- true, nullptr);
+ auto vMultiPut = std::make_unique<TEvBlobStorage::TEvVMultiPut>(vDiskId, Deadline, Blackboard.PutHandleClass,
+ true, nullptr);
ui64 bytes = 0;
ui64 lastItemCount = 0;
for (ui32 idx = beginIdx; idx < endIdx; ++idx) {
@@ -343,10 +343,10 @@ void TGetImpl::PrepareVPuts(TLogContext &logCtx,
ReceivedVMultiPutResponses.push_back(false);
R_LOG_DEBUG_SX(logCtx, "BPG16", "Send multiPut to orderNumber# " << diskOrderNumber << " count# "
<< vMultiPut->Record.ItemsSize() << " vMultiPut# " << vMultiPut->ToString());
- outVMultiPuts.push_back(std::move(vMultiPut));
+ outVMultiPuts.push_back(std::move(vMultiPut));
// set cookie after adding items
- vMultiPut = std::make_unique<TEvBlobStorage::TEvVMultiPut>(vDiskId, Deadline,
- Blackboard.PutHandleClass, true, nullptr);
+ vMultiPut = std::make_unique<TEvBlobStorage::TEvVMultiPut>(vDiskId, Deadline,
+ Blackboard.PutHandleClass, true, nullptr);
bytes = 0;
lastItemCount = 0;
}
@@ -359,55 +359,55 @@ void TGetImpl::PrepareVPuts(TLogContext &logCtx,
ReceivedVMultiPutResponses.push_back(false);
R_LOG_DEBUG_SX(logCtx, "BPG17", "Send multiPut to orderNumber# " << diskOrderNumber << " count# "
<< vMultiPut->Record.ItemsSize() << " vMultiPut# " << vMultiPut->ToString());
- outVMultiPuts.push_back(std::move(vMultiPut));
+ outVMultiPuts.push_back(std::move(vMultiPut));
Blackboard.GroupDiskRequests.DiskRequestsForOrderNumber[diskOrderNumber].FirstUnsentPutIdx = endIdx;
}
}
}
-EStrategyOutcome TGetImpl::RunBoldStrategy(TLogContext &logCtx) {
+EStrategyOutcome TGetImpl::RunBoldStrategy(TLogContext &logCtx) {
EStrategyOutcome outcome = Blackboard.RunStrategy(logCtx, TBoldStrategy(PhantomCheck));
- if (outcome == EStrategyOutcome::DONE && MustRestoreFirst) {
+ if (outcome == EStrategyOutcome::DONE && MustRestoreFirst) {
Blackboard.ChangeAll();
- outcome = Blackboard.RunStrategy(logCtx, TRestoreStrategy());
+ outcome = Blackboard.RunStrategy(logCtx, TRestoreStrategy());
}
- return outcome;
+ return outcome;
}
-EStrategyOutcome TGetImpl::RunMirror3dcStrategy(TLogContext &logCtx) {
- return MustRestoreFirst
- ? Blackboard.RunStrategy(logCtx, TMirror3dcGetWithRestoreStrategy())
- : Blackboard.RunStrategy(logCtx, TMirror3dcBasicGetStrategy(NodeLayout, PhantomCheck));
+EStrategyOutcome TGetImpl::RunMirror3dcStrategy(TLogContext &logCtx) {
+ return MustRestoreFirst
+ ? Blackboard.RunStrategy(logCtx, TMirror3dcGetWithRestoreStrategy())
+ : Blackboard.RunStrategy(logCtx, TMirror3dcBasicGetStrategy(NodeLayout, PhantomCheck));
}
-EStrategyOutcome TGetImpl::RunMirror3of4Strategy(TLogContext &logCtx) {
- // run basic get strategy and, if blob restoration is required and we have successful get, restore the blob to full amount of parts
- EStrategyOutcome outcome = Blackboard.RunStrategy(logCtx, TMirror3of4GetStrategy());
- if (outcome == EStrategyOutcome::DONE && MustRestoreFirst) {
+EStrategyOutcome TGetImpl::RunMirror3of4Strategy(TLogContext &logCtx) {
+ // run basic get strategy and, if blob restoration is required and we have successful get, restore the blob to full amount of parts
+ EStrategyOutcome outcome = Blackboard.RunStrategy(logCtx, TMirror3of4GetStrategy());
+ if (outcome == EStrategyOutcome::DONE && MustRestoreFirst) {
Blackboard.ChangeAll();
- outcome = Blackboard.RunStrategy(logCtx, TPut3of4Strategy(TEvBlobStorage::TEvPut::TacticMaxThroughput));
- }
- return outcome;
-}
-
-EStrategyOutcome TGetImpl::RunStrategies(TLogContext &logCtx) {
+ outcome = Blackboard.RunStrategy(logCtx, TPut3of4Strategy(TEvBlobStorage::TEvPut::TacticMaxThroughput));
+ }
+ return outcome;
+}
+
+EStrategyOutcome TGetImpl::RunStrategies(TLogContext &logCtx) {
if (Info->Type.GetErasure() == TErasureType::ErasureMirror3dc) {
- return RunMirror3dcStrategy(logCtx);
- } else if (Info->Type.GetErasure() == TErasureType::ErasureMirror3of4) {
- return RunMirror3of4Strategy(logCtx);
+ return RunMirror3dcStrategy(logCtx);
+ } else if (Info->Type.GetErasure() == TErasureType::ErasureMirror3of4) {
+ return RunMirror3of4Strategy(logCtx);
} else if (MustRestoreFirst || PhantomCheck) {
- return RunBoldStrategy(logCtx);
+ return RunBoldStrategy(logCtx);
} else if (Info->Type.ErasureFamily() == TErasureType::ErasureParityBlock) {
- return Blackboard.RunStrategy(logCtx, TMinIopsBlockStrategy());
+ return Blackboard.RunStrategy(logCtx, TMinIopsBlockStrategy());
} else if (Info->Type.ErasureFamily() == TErasureType::ErasureMirror) {
- return Blackboard.RunStrategy(logCtx, TMinIopsMirrorStrategy());
+ return Blackboard.RunStrategy(logCtx, TMinIopsMirrorStrategy());
} else {
- return RunBoldStrategy(logCtx);
+ return RunBoldStrategy(logCtx);
}
}
-void TGetImpl::OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVPutResult &ev,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts,
+void TGetImpl::OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVPutResult &ev,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
const NKikimrBlobStorage::TEvVPutResult &record = ev.Record;
Y_VERIFY(record.HasVDiskID());
@@ -438,16 +438,16 @@ void TGetImpl::OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVPutResult &
case NKikimrProto::OK:
case NKikimrProto::ALREADY:
Blackboard.AddPutOkResponse(blob, orderNumber);
- break;
+ break;
default:
Y_FAIL("Unexpected status# %s", NKikimrProto::EReplyStatus_Name(status).data());
}
- Step(logCtx, outVGets, outVPuts, outGetResult);
+ Step(logCtx, outVGets, outVPuts, outGetResult);
}
void TGetImpl::OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVMultiPutResult &ev,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
const NKikimrBlobStorage::TEvVMultiPutResult &record = ev.Record;
Y_VERIFY(record.HasVDiskID());
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.h b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.h
index 4908ae9bda4..b90998cfd51 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_get_impl.h
@@ -15,14 +15,14 @@ class TStrategyBase;
class TGetImpl {
const TInstant Deadline;
const TIntrusivePtr<TBlobStorageGroupInfo> Info;
- TArrayHolder<TEvBlobStorage::TEvGet::TQuery> Queries;
+ TArrayHolder<TEvBlobStorage::TEvGet::TQuery> Queries;
const TNodeLayoutInfoPtr NodeLayout;
const ui32 QuerySize;
- const bool IsInternal;
+ const bool IsInternal;
const bool IsVerboseNoDataEnabled;
- const bool CollectDebugInfo;
+ const bool CollectDebugInfo;
const bool MustRestoreFirst;
- const bool ReportDetailedPartMap;
+ const bool ReportDetailedPartMap;
const ui32 ForceBlockedGeneration;
ui64 ReplyBytes = 0;
@@ -40,59 +40,59 @@ class TGetImpl {
bool AcquireBlockedGeneration = false;
TBlackboard Blackboard;
-
- ui32 RequestIndex = 0;
- ui32 ResponseIndex = 0;
-
+
+ ui32 RequestIndex = 0;
+ ui32 ResponseIndex = 0;
+
TStackVec<bool, MaxBatchedPutRequests * TypicalDisksInSubring> ReceivedVPutResponses;
TStackVec<bool, MaxBatchedPutRequests * TypicalDisksInSubring> ReceivedVMultiPutResponses;
- const TString RequestPrefix;
-
- const bool PhantomCheck;
-
+ const TString RequestPrefix;
+
+ const bool PhantomCheck;
+
public:
- TGetImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &groupQueues,
- TEvBlobStorage::TEvGet *ev, TNodeLayoutInfoPtr&& nodeLayout, const TString& requestPrefix = {})
+ TGetImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &groupQueues,
+ TEvBlobStorage::TEvGet *ev, TNodeLayoutInfoPtr&& nodeLayout, const TString& requestPrefix = {})
: Deadline(ev->Deadline)
, Info(info)
, Queries(ev->Queries.Release())
, NodeLayout(std::move(nodeLayout))
, QuerySize(ev->QuerySize)
- , IsInternal(ev->IsInternal)
+ , IsInternal(ev->IsInternal)
, IsVerboseNoDataEnabled(ev->IsVerboseNoDataEnabled)
- , CollectDebugInfo(ev->CollectDebugInfo)
+ , CollectDebugInfo(ev->CollectDebugInfo)
, MustRestoreFirst(ev->MustRestoreFirst)
- , ReportDetailedPartMap(ev->ReportDetailedPartMap)
+ , ReportDetailedPartMap(ev->ReportDetailedPartMap)
, ForceBlockedGeneration(ev->ForceBlockedGeneration)
- , Blackboard(info, groupQueues, NKikimrBlobStorage::AsyncBlob, ev->GetHandleClass)
- , RequestPrefix(requestPrefix)
- , PhantomCheck(ev->PhantomCheck)
+ , Blackboard(info, groupQueues, NKikimrBlobStorage::AsyncBlob, ev->GetHandleClass)
+ , RequestPrefix(requestPrefix)
+ , PhantomCheck(ev->PhantomCheck)
{
Y_VERIFY(QuerySize > 0);
}
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(Queries, QuerySize, Deadline, GetHandleClass(), MustRestoreFirst,
- false /*isIndexOnly*/, ForceBlockedGeneration, IsInternal, IsVerboseNoDataEnabled, CollectDebugInfo,
- ReportDetailedPartMap);
- ev->RestartCounter = counter;
- return ev;
- }
-
- ui32 CountRequestBytes() const {
- ui32 res = 0;
- for (ui32 k = 0; k < QuerySize; ++k) {
- const auto& query = Queries[k];
- ui32 size = query.Size;
- if (!size) {
- size = Max<i32>(0, query.Id.BlobSize() - query.Shift);
- }
- res += size;
- }
- return res;
- }
-
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(Queries, QuerySize, Deadline, GetHandleClass(), MustRestoreFirst,
+ false /*isIndexOnly*/, ForceBlockedGeneration, IsInternal, IsVerboseNoDataEnabled, CollectDebugInfo,
+ ReportDetailedPartMap);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
+ ui32 CountRequestBytes() const {
+ ui32 res = 0;
+ for (ui32 k = 0; k < QuerySize; ++k) {
+ const auto& query = Queries[k];
+ ui32 size = query.Size;
+ if (!size) {
+ size = Max<i32>(0, query.Id.BlobSize() - query.Shift);
+ }
+ res += size;
+ }
+ return res;
+ }
+
ui64 GetReplyBytes() {
return ReplyBytes;
}
@@ -116,18 +116,18 @@ public:
}
TString DumpQuery() const {
- TStringStream str;
- str << "{";
- for (ui32 i = 0; i < QuerySize; ++i) {
- str << (i ? " " : "")
- << Queries[i].Id
- << "@" << Queries[i].Shift
- << ":" << Queries[i].Size;
- }
- str << "}";
- return str.Str();
- }
-
+ TStringStream str;
+ str << "{";
+ for (ui32 i = 0; i < QuerySize; ++i) {
+ str << (i ? " " : "")
+ << Queries[i].Id
+ << "@" << Queries[i].Shift
+ << ":" << Queries[i].Size;
+ }
+ str << "}";
+ return str.Str();
+ }
+
ui64 GetVPutRequests() const {
return VPutRequests;
}
@@ -153,11 +153,11 @@ public:
}
- void GenerateInitialRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets);
+ void GenerateInitialRequests(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets);
template <typename TVPutEvent>
- void OnVGetResult(TLogContext &logCtx, TEvBlobStorage::TEvVGetResult &ev,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts,
+ void OnVGetResult(TLogContext &logCtx, TEvBlobStorage::TEvVGetResult &ev,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
const NKikimrBlobStorage::TEvVGetResult &record = ev.Record;
Y_VERIFY(record.HasStatus());
@@ -239,22 +239,22 @@ public:
Step(logCtx, outVGets, outVPuts, outGetResult);
}
- void OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVPutResult &ev,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts,
+ void OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVPutResult &ev,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult);
void OnVPutResult(TLogContext &logCtx, TEvBlobStorage::TEvVMultiPutResult &ev,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult);
- void PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx,
+ void PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx,
TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult);
template <typename TVPutEvent>
void AccelerateGet(TLogContext &logCtx, i32 slowDiskOrderNumber,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
TAutoPtr<TEvBlobStorage::TEvGetResult> outGetResult;
TBlackboard::EAccelerationMode prevMode = Blackboard.AccelerationMode;
Blackboard.AccelerationMode = TBlackboard::AccelerationModeSkipMarked;
@@ -268,13 +268,13 @@ public:
Blackboard.ChangeAll();
Step(logCtx, outVGets, outVPuts, outGetResult);
Blackboard.AccelerationMode = prevMode;
- Y_VERIFY(!outGetResult, "%s Unexpected get result in AccelerateGet, outGetResult# %s, DumpFullState# %s",
- RequestPrefix.data(), outGetResult->Print(false).c_str(), DumpFullState().c_str());
+ Y_VERIFY(!outGetResult, "%s Unexpected get result in AccelerateGet, outGetResult# %s, DumpFullState# %s",
+ RequestPrefix.data(), outGetResult->Print(false).c_str(), DumpFullState().c_str());
}
template <typename TVPutEvent>
void AcceleratePut(TLogContext &logCtx, i32 slowDiskOrderNumber,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
AccelerateGet(logCtx, slowDiskOrderNumber, outVGets, outVPuts);
}
@@ -284,40 +284,40 @@ public:
TString DumpFullState() const;
protected:
- EStrategyOutcome RunBoldStrategy(TLogContext &logCtx);
- EStrategyOutcome RunMirror3dcStrategy(TLogContext &logCtx);
- EStrategyOutcome RunMirror3of4Strategy(TLogContext &logCtx);
- EStrategyOutcome RunStrategies(TLogContext &logCtx);
+ EStrategyOutcome RunBoldStrategy(TLogContext &logCtx);
+ EStrategyOutcome RunMirror3dcStrategy(TLogContext &logCtx);
+ EStrategyOutcome RunMirror3of4Strategy(TLogContext &logCtx);
+ EStrategyOutcome RunStrategies(TLogContext &logCtx);
// Returns true if there are additional requests to send
template <typename TVPutEvent>
- bool Step(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
- TDeque<std::unique_ptr<TVPutEvent>> &outVPuts, TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
- switch (auto outcome = RunStrategies(logCtx)) {
- case EStrategyOutcome::IN_PROGRESS: {
- const ui32 numRequests = outVGets.size() + outVPuts.size();
- PrepareRequests(logCtx, outVGets);
- PrepareVPuts(logCtx, outVPuts);
- return outVGets.size() + outVPuts.size() > numRequests;
- }
-
- case EStrategyOutcome::ERROR:
- PrepareReply(NKikimrProto::ERROR, logCtx, outGetResult);
- outGetResult->ErrorReason = outcome.ErrorReason;
- return false;
-
- case EStrategyOutcome::DONE:
- PrepareReply(NKikimrProto::OK, logCtx, outGetResult);
- return false;
+ bool Step(TLogContext &logCtx, TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets,
+ TDeque<std::unique_ptr<TVPutEvent>> &outVPuts, TAutoPtr<TEvBlobStorage::TEvGetResult> &outGetResult) {
+ switch (auto outcome = RunStrategies(logCtx)) {
+ case EStrategyOutcome::IN_PROGRESS: {
+ const ui32 numRequests = outVGets.size() + outVPuts.size();
+ PrepareRequests(logCtx, outVGets);
+ PrepareVPuts(logCtx, outVPuts);
+ return outVGets.size() + outVPuts.size() > numRequests;
+ }
+
+ case EStrategyOutcome::ERROR:
+ PrepareReply(NKikimrProto::ERROR, logCtx, outGetResult);
+ outGetResult->ErrorReason = outcome.ErrorReason;
+ return false;
+
+ case EStrategyOutcome::DONE:
+ PrepareReply(NKikimrProto::OK, logCtx, outGetResult);
+ return false;
}
}
- void PrepareRequests(TLogContext &logCtx,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets);
- void PrepareVPuts(TLogContext &logCtx,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts);
+ void PrepareRequests(TLogContext &logCtx,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &outVGets);
+ void PrepareVPuts(TLogContext &logCtx,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &outVPuts);
void PrepareVPuts(TLogContext &logCtx,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &outVMultiPuts);
ui64 GetTimeToAccelerateNs(TLogContext &logCtx, NKikimrBlobStorage::EVDiskQueueId queueId);
}; //TGetImpl
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_impl.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_impl.cpp
index dbf547ae745..8c95ec568ea 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_impl.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_impl.cpp
@@ -1,91 +1,91 @@
-#include "dsproxy_impl.h"
-
-namespace NKikimr {
-
- TBlobStorageGroupProxy::TBlobStorageGroupProxy(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
- TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
+#include "dsproxy_impl.h"
+
+namespace NKikimr {
+
+ TBlobStorageGroupProxy::TBlobStorageGroupProxy(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
+ TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch)
- : GroupId(info->GroupID)
- , Info(std::move(info))
- , Topology(Info->PickTopology())
- , NodeMon(nodeMon)
- , StoragePoolCounters(std::move(storagePoolCounters))
- , IsEjected(false)
- , ForceWaitAllDrives(forceWaitAllDrives)
+ : GroupId(info->GroupID)
+ , Info(std::move(info))
+ , Topology(Info->PickTopology())
+ , NodeMon(nodeMon)
+ , StoragePoolCounters(std::move(storagePoolCounters))
+ , IsEjected(false)
+ , ForceWaitAllDrives(forceWaitAllDrives)
, EnablePutBatching(enablePutBatching)
, EnableVPatch(enableVPatch)
- {}
-
- TBlobStorageGroupProxy::TBlobStorageGroupProxy(ui32 groupId, bool isEjected, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
+ {}
+
+ TBlobStorageGroupProxy::TBlobStorageGroupProxy(ui32 groupId, bool isEjected, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch)
- : GroupId(groupId)
- , NodeMon(nodeMon)
- , IsEjected(isEjected)
- , ForceWaitAllDrives(false)
+ : GroupId(groupId)
+ , NodeMon(nodeMon)
+ , IsEjected(isEjected)
+ , ForceWaitAllDrives(false)
, EnablePutBatching(enablePutBatching)
, EnableVPatch(enableVPatch)
- {}
-
- IActor* CreateBlobStorageGroupEjectedProxy(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon) {
+ {}
+
+ IActor* CreateBlobStorageGroupEjectedProxy(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon) {
return new TBlobStorageGroupProxy(groupId, true, nodeMon, TControlWrapper(false, false, true),
TControlWrapper(false, false, true));
- }
-
- IActor* CreateBlobStorageGroupProxyConfigured(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
- TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
+ }
+
+ IActor* CreateBlobStorageGroupProxyConfigured(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
+ TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch) {
- Y_VERIFY(info);
- return new TBlobStorageGroupProxy(std::move(info), forceWaitAllDrives, nodeMon, std::move(storagePoolCounters),
+ Y_VERIFY(info);
+ return new TBlobStorageGroupProxy(std::move(info), forceWaitAllDrives, nodeMon, std::move(storagePoolCounters),
enablePutBatching, enableVPatch);
- }
-
- IActor* CreateBlobStorageGroupProxyUnconfigured(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
+ }
+
+ IActor* CreateBlobStorageGroupProxyUnconfigured(ui32 groupId, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch) {
return new TBlobStorageGroupProxy(groupId, false, nodeMon, enablePutBatching, enableVPatch);
- }
-
- NActors::NLog::EPriority PriorityForStatusOutbound(NKikimrProto::EReplyStatus status) {
- switch (status) {
- case NKikimrProto::OK:
- case NKikimrProto::ALREADY:
- return NActors::NLog::EPriority::PRI_DEBUG;
- case NKikimrProto::NODATA:
- return NActors::NLog::EPriority::PRI_WARN;
- default:
- return NActors::NLog::EPriority::PRI_ERROR;
- }
- }
-
- NActors::NLog::EPriority PriorityForStatusResult(NKikimrProto::EReplyStatus status) {
- switch (status) {
- case NKikimrProto::OK:
- case NKikimrProto::ALREADY:
- return NActors::NLog::EPriority::PRI_DEBUG;
- case NKikimrProto::BLOCKED:
- case NKikimrProto::DEADLINE:
- case NKikimrProto::RACE:
- case NKikimrProto::ERROR:
- return NActors::NLog::EPriority::PRI_INFO;
- case NKikimrProto::NODATA:
- return NActors::NLog::EPriority::PRI_NOTICE;
- default:
- return NActors::NLog::EPriority::PRI_ERROR;
- }
- }
-
- NActors::NLog::EPriority PriorityForStatusInbound(NKikimrProto::EReplyStatus status) {
- switch (status) {
- case NKikimrProto::OK:
- case NKikimrProto::ALREADY:
- return NActors::NLog::EPriority::PRI_DEBUG;
- case NKikimrProto::NODATA:
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
- case NKikimrProto::OUT_OF_SPACE:
- return NActors::NLog::EPriority::PRI_INFO;
- default:
- return NActors::NLog::EPriority::PRI_ERROR;
- }
- }
-
-}//NKikimr
+ }
+
+ NActors::NLog::EPriority PriorityForStatusOutbound(NKikimrProto::EReplyStatus status) {
+ switch (status) {
+ case NKikimrProto::OK:
+ case NKikimrProto::ALREADY:
+ return NActors::NLog::EPriority::PRI_DEBUG;
+ case NKikimrProto::NODATA:
+ return NActors::NLog::EPriority::PRI_WARN;
+ default:
+ return NActors::NLog::EPriority::PRI_ERROR;
+ }
+ }
+
+ NActors::NLog::EPriority PriorityForStatusResult(NKikimrProto::EReplyStatus status) {
+ switch (status) {
+ case NKikimrProto::OK:
+ case NKikimrProto::ALREADY:
+ return NActors::NLog::EPriority::PRI_DEBUG;
+ case NKikimrProto::BLOCKED:
+ case NKikimrProto::DEADLINE:
+ case NKikimrProto::RACE:
+ case NKikimrProto::ERROR:
+ return NActors::NLog::EPriority::PRI_INFO;
+ case NKikimrProto::NODATA:
+ return NActors::NLog::EPriority::PRI_NOTICE;
+ default:
+ return NActors::NLog::EPriority::PRI_ERROR;
+ }
+ }
+
+ NActors::NLog::EPriority PriorityForStatusInbound(NKikimrProto::EReplyStatus status) {
+ switch (status) {
+ case NKikimrProto::OK:
+ case NKikimrProto::ALREADY:
+ return NActors::NLog::EPriority::PRI_DEBUG;
+ case NKikimrProto::NODATA:
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ case NKikimrProto::OUT_OF_SPACE:
+ return NActors::NLog::EPriority::PRI_INFO;
+ default:
+ return NActors::NLog::EPriority::PRI_ERROR;
+ }
+ }
+
+}//NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_impl.h b/ydb/core/blobstorage/dsproxy/dsproxy_impl.h
index 508eb10a055..57a5c7c7e09 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_impl.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_impl.h
@@ -1,407 +1,407 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy.h"
-
-namespace NKikimr {
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// TBlobStorageGroupProxy
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-static constexpr TDuration UpdateResponsivenessTimeout = TDuration::MilliSeconds(500);
-static constexpr TDuration ResponsivenessTrackerWindow = TDuration::Seconds(5);
-static constexpr ui32 ResponsivenessTrackerMaxQueue = 10000; // number of stat series items per single VDisk
-
-class TBlobStorageGroupProxy : public TActorBootstrapped<TBlobStorageGroupProxy> {
- enum {
- EvUpdateResponsiveness = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- EvUpdateGroupStat,
- EvStopBatchingPutRequests,
- EvStopBatchingGetRequests,
- EvConfigureQueryTimeout,
- EvEstablishingSessionTimeout,
- Ev5min,
- };
-
- struct TEvUpdateResponsiveness : TEventLocal<TEvUpdateResponsiveness, EvUpdateResponsiveness> {};
- struct TEvUpdateGroupStat : TEventLocal<TEvUpdateGroupStat, EvUpdateGroupStat> {};
- struct TEvStopBatchingPutRequests : TEventLocal<TEvStopBatchingPutRequests, EvStopBatchingPutRequests> {};
- struct TEvStopBatchingGetRequests : TEventLocal<TEvStopBatchingGetRequests, EvStopBatchingGetRequests> {};
- struct TEvConfigureQueryTimeout : TEventLocal<TEvConfigureQueryTimeout, EvConfigureQueryTimeout> {};
- struct TEvEstablishingSessionTimeout : TEventLocal<TEvEstablishingSessionTimeout, EvEstablishingSessionTimeout> {};
-
- template <typename TEventPtr>
- struct TBatchedQueue {
- TBatchedVec<TEventPtr> Queue;
- ui64 Bytes = 0;
- ui64 RequestCount = 0;
- };
-
- struct TPutBatchedBucket {
- NKikimrBlobStorage::EPutHandleClass HandleClass;
- TEvBlobStorage::TEvPut::ETactic Tactic;
-
- TPutBatchedBucket(NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic)
- : HandleClass(handleClass)
- , Tactic(tactic)
- {
- Y_VERIFY(NKikimrBlobStorage::EPutHandleClass_MIN <= handleClass &&
- NKikimrBlobStorage::EPutHandleClass_MAX >= handleClass, "incorrect PutHandleClass");
- Y_VERIFY(0 <= tactic && tactic < TEvBlobStorage::TEvPut::TacticCount, "incorrect PutTactic");
- }
- };
-
- const ui32 GroupId;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
- TIntrusivePtr<TDsProxyNodeMon> NodeMon;
- TIntrusivePtr<TStoragePoolCounters> StoragePoolCounters;
- TIntrusivePtr<TGroupSessions> Sessions;
- TDeque<std::unique_ptr<IEventHandle>> InitQueue;
- THashSet<TActorId, TActorId::THash> ActiveRequests;
- ui64 UnconfiguredBufferSize = 0;
- const bool IsEjected;
- bool ForceWaitAllDrives;
- bool IsLimitedKeyless = false;
- bool IsFullMonitoring = false; // current state of monitoring
-
- TActorId MonActor;
- TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
- TBSProxyContextPtr BSProxyCtx;
-
- TString ErrorDescription;
- TString ExtraLogInfo; // is empty or ends with a space
-
- // node layout -- obtained with bootstrap
- TNodeLayoutInfoPtr NodeLayoutInfo = nullptr;
-
- TDiskResponsivenessTracker ResponsivenessTracker = {ResponsivenessTrackerMaxQueue, ResponsivenessTrackerWindow};
- TDiskResponsivenessTracker::TPerDiskStatsPtr PerDiskStats = MakeIntrusive<TDiskResponsivenessTracker::TPerDiskStats>();
-
- TEvStopBatchingPutRequests::TPtr StopPutBatchingEvent;
- ui64 BatchedPutRequestCount = 0;
-
- static constexpr ui64 PutHandleClassCount = NKikimrBlobStorage::EPutHandleClass_MAX + 1;
- static_assert(NKikimrBlobStorage::EPutHandleClass_MIN == 1); // counting from one
- static_assert(PutHandleClassCount < 10);
- static constexpr ui64 PutTacticCount = TEvBlobStorage::TEvPut::TacticCount;
- static_assert(PutTacticCount <= 10);
-
- TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> BatchedPuts[PutHandleClassCount][PutTacticCount];
- static constexpr ui64 PutBatchecBucketCount = PutHandleClassCount * PutTacticCount;
- TStackVec<TPutBatchedBucket, PutBatchecBucketCount> PutBatchedBucketQueue;
-
- TEvStopBatchingGetRequests::TPtr StopGetBatchingEvent;
- ui64 BatchedGetRequestCount = 0;
-
- static constexpr ui64 GetHandleClassCount = NKikimrBlobStorage::EGetHandleClass_MAX + 1;
- static_assert(NKikimrBlobStorage::EGetHandleClass_MIN == 1); // counting from one
-
- TBatchedQueue<TEvBlobStorage::TEvGet::TPtr> BatchedGets[GetHandleClassCount];
- TStackVec<NKikimrBlobStorage::EGetHandleClass, GetHandleClassCount> GetBatchedBucketQueue;
-
+#pragma once
+
+#include "defs.h"
+#include "dsproxy.h"
+
+namespace NKikimr {
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TBlobStorageGroupProxy
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static constexpr TDuration UpdateResponsivenessTimeout = TDuration::MilliSeconds(500);
+static constexpr TDuration ResponsivenessTrackerWindow = TDuration::Seconds(5);
+static constexpr ui32 ResponsivenessTrackerMaxQueue = 10000; // number of stat series items per single VDisk
+
+class TBlobStorageGroupProxy : public TActorBootstrapped<TBlobStorageGroupProxy> {
+ enum {
+ EvUpdateResponsiveness = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ EvUpdateGroupStat,
+ EvStopBatchingPutRequests,
+ EvStopBatchingGetRequests,
+ EvConfigureQueryTimeout,
+ EvEstablishingSessionTimeout,
+ Ev5min,
+ };
+
+ struct TEvUpdateResponsiveness : TEventLocal<TEvUpdateResponsiveness, EvUpdateResponsiveness> {};
+ struct TEvUpdateGroupStat : TEventLocal<TEvUpdateGroupStat, EvUpdateGroupStat> {};
+ struct TEvStopBatchingPutRequests : TEventLocal<TEvStopBatchingPutRequests, EvStopBatchingPutRequests> {};
+ struct TEvStopBatchingGetRequests : TEventLocal<TEvStopBatchingGetRequests, EvStopBatchingGetRequests> {};
+ struct TEvConfigureQueryTimeout : TEventLocal<TEvConfigureQueryTimeout, EvConfigureQueryTimeout> {};
+ struct TEvEstablishingSessionTimeout : TEventLocal<TEvEstablishingSessionTimeout, EvEstablishingSessionTimeout> {};
+
+ template <typename TEventPtr>
+ struct TBatchedQueue {
+ TBatchedVec<TEventPtr> Queue;
+ ui64 Bytes = 0;
+ ui64 RequestCount = 0;
+ };
+
+ struct TPutBatchedBucket {
+ NKikimrBlobStorage::EPutHandleClass HandleClass;
+ TEvBlobStorage::TEvPut::ETactic Tactic;
+
+ TPutBatchedBucket(NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic)
+ : HandleClass(handleClass)
+ , Tactic(tactic)
+ {
+ Y_VERIFY(NKikimrBlobStorage::EPutHandleClass_MIN <= handleClass &&
+ NKikimrBlobStorage::EPutHandleClass_MAX >= handleClass, "incorrect PutHandleClass");
+ Y_VERIFY(0 <= tactic && tactic < TEvBlobStorage::TEvPut::TacticCount, "incorrect PutTactic");
+ }
+ };
+
+ const ui32 GroupId;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
+ TIntrusivePtr<TDsProxyNodeMon> NodeMon;
+ TIntrusivePtr<TStoragePoolCounters> StoragePoolCounters;
+ TIntrusivePtr<TGroupSessions> Sessions;
+ TDeque<std::unique_ptr<IEventHandle>> InitQueue;
+ THashSet<TActorId, TActorId::THash> ActiveRequests;
+ ui64 UnconfiguredBufferSize = 0;
+ const bool IsEjected;
+ bool ForceWaitAllDrives;
+ bool IsLimitedKeyless = false;
+ bool IsFullMonitoring = false; // current state of monitoring
+
+ TActorId MonActor;
+ TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
+ TBSProxyContextPtr BSProxyCtx;
+
+ TString ErrorDescription;
+ TString ExtraLogInfo; // is empty or ends with a space
+
+ // node layout -- obtained with bootstrap
+ TNodeLayoutInfoPtr NodeLayoutInfo = nullptr;
+
+ TDiskResponsivenessTracker ResponsivenessTracker = {ResponsivenessTrackerMaxQueue, ResponsivenessTrackerWindow};
+ TDiskResponsivenessTracker::TPerDiskStatsPtr PerDiskStats = MakeIntrusive<TDiskResponsivenessTracker::TPerDiskStats>();
+
+ TEvStopBatchingPutRequests::TPtr StopPutBatchingEvent;
+ ui64 BatchedPutRequestCount = 0;
+
+ static constexpr ui64 PutHandleClassCount = NKikimrBlobStorage::EPutHandleClass_MAX + 1;
+ static_assert(NKikimrBlobStorage::EPutHandleClass_MIN == 1); // counting from one
+ static_assert(PutHandleClassCount < 10);
+ static constexpr ui64 PutTacticCount = TEvBlobStorage::TEvPut::TacticCount;
+ static_assert(PutTacticCount <= 10);
+
+ TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> BatchedPuts[PutHandleClassCount][PutTacticCount];
+ static constexpr ui64 PutBatchecBucketCount = PutHandleClassCount * PutTacticCount;
+ TStackVec<TPutBatchedBucket, PutBatchecBucketCount> PutBatchedBucketQueue;
+
+ TEvStopBatchingGetRequests::TPtr StopGetBatchingEvent;
+ ui64 BatchedGetRequestCount = 0;
+
+ static constexpr ui64 GetHandleClassCount = NKikimrBlobStorage::EGetHandleClass_MAX + 1;
+ static_assert(NKikimrBlobStorage::EGetHandleClass_MIN == 1); // counting from one
+
+ TBatchedQueue<TEvBlobStorage::TEvGet::TPtr> BatchedGets[GetHandleClassCount];
+ TStackVec<NKikimrBlobStorage::EGetHandleClass, GetHandleClassCount> GetBatchedBucketQueue;
+
TMemorizableControlWrapper EnablePutBatching;
TMemorizableControlWrapper EnableVPatch;
-
- TInstant EstablishingSessionStartTime;
-
- const TDuration MuteDuration = TDuration::Seconds(5);
- TLogPriorityMuteChecker<NLog::PRI_INFO, NLog::PRI_DEBUG> EstablishingSessionsPutMuteChecker;
- TLogPriorityMuteChecker<NLog::PRI_INFO, NLog::PRI_DEBUG> ErrorStateMuteChecker;
- TLogPriorityMuteChecker<NLog::PRI_CRIT, NLog::PRI_DEBUG> InvalidGroupIdMuteChecker;
-
- bool HasInvalidGroupId() const { return GroupId == Max<ui32>(); }
- void ProcessInitQueue();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Enable monitoring
-
- // Create monitoring and ensure all counters if needed
- void EnsureMonitoring(bool fullIfPossible);
-
- template<typename TEvent>
- void IncMonEvent(const TEvent *ev) {
- if (!Mon) {
- return;
- }
- if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPut>) {
- Mon->CountPutEvent(ev->Buffer.size());
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvGet>) {
- Mon->EventGet->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvBlock>) {
- Mon->EventBlock->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvDiscover>) {
- Mon->EventDiscover->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvRange>) {
- Mon->EventRange->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvCollectGarbage>) {
- Mon->EventCollectGarbage->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvStatus>) {
- Mon->EventStatus->Inc();
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPatch>) {
- Mon->EventPatch->Inc();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Unconfigured state
-
- TEvEstablishingSessionTimeout *EstablishingSessionsTimeoutEv = nullptr;
- TEvConfigureQueryTimeout *ConfigureQueryTimeoutEv = nullptr;
- bool InEstablishingSessionsTimeout = false, InEstablishingSessionsTimeout5min = false;
- bool InUnconfiguredTimeout = false, InUnconfiguredTimeout5min = false;
- ui64 Cookie5min = 0;
-
- void Handle5min(TAutoPtr<IEventHandle> ev);
- void ClearTimeoutCounters();
-
- void SetStateEstablishingSessions();
- void SetStateEstablishingSessionsTimeout();
- void SetStateUnconfigured();
- void SetStateUnconfiguredTimeout();
- void SetStateWork();
-
- std::optional<TBlobStorageGroupInfo::EEncryptionMode> EncryptionMode;
- std::optional<TBlobStorageGroupInfo::ELifeCyclePhase> LifeCyclePhase;
- std::optional<ui64> GroupKeyNonce;
- std::optional<TCypherKey> CypherKey;
-
- void Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev);
- void ApplyGroupInfo(TIntrusivePtr<TBlobStorageGroupInfo>&& info, TIntrusivePtr<TStoragePoolCounters>&& counters);
-
- void WakeupUnconfigured(TEvConfigureQueryTimeout::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Establishing Sessions state
-
- void SwitchToWorkWhenGoodToGo();
- void WakeupEstablishingSessions(TEvEstablishingSessionTimeout::TPtr ev);
- void Handle(TEvProxyQueueState::TPtr& ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Put to init queue
-
- template<typename TEvent>
- void HandleEnqueue(TAutoPtr<TEventHandle<TEvent>> ev) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " HandleEnqueue# " << ev->Get()->Print(false) << " Marker# DSP17");
- if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvGet>) {
- LWTRACK(DSProxyGetEnqueue, ev->Get()->Orbit);
- } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPut>) {
- LWTRACK(DSProxyPutEnqueue, ev->Get()->Orbit);
- }
- UnconfiguredBufferSize += ev->Get()->CalculateSize();
- InitQueue.emplace_back(ev.Release());
- if (UnconfiguredBufferSize > UnconfiguredBufferSizeLimit && InitQueue.size() > 1) {
- LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " UnconfiguredBufferSize# " << UnconfiguredBufferSize << " > " << UnconfiguredBufferSizeLimit
- << ", dropping the queue (" << (ui64)InitQueue.size() << ")" << " Marker# DSP08");
- if (CurrentStateFunc() == &TThis::StateUnconfigured) {
- ErrorDescription = "Too many requests while waiting for configuration (DSPE2).";
- SetStateUnconfiguredTimeout();
- } else if (CurrentStateFunc() == &TThis::StateEstablishingSessions) {
- ErrorDescription = "Too many requests while establishing sessions (DSPE5).";
- SetStateEstablishingSessionsTimeout();
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Normal state
-
- template<typename TEventPtr>
- void EnableWilsonTracing(TEventPtr &ev, TAtomic &sampleRate) {
- if (!ev->TraceId) {
- const ui64 rate = AtomicGet(sampleRate);
- if (rate) {
- const ui64 num = RandomNumber<ui64>(1000000); // in range [0, 1000000)
- if (num < rate) {
- ev->TraceId = NWilson::TTraceId::NewTraceId();
- }
- }
- }
- }
-
- TMaybe<TGroupStat::EKind> PutHandleClassToGroupStatKind(NKikimrBlobStorage::EPutHandleClass handleClass) {
- switch (handleClass) {
- case NKikimrBlobStorage::TabletLog:
- return TGroupStat::EKind::PUT_TABLET_LOG;
-
- case NKikimrBlobStorage::UserData:
- return TGroupStat::EKind::PUT_USER_DATA;
-
- default:
- return {};
- }
- }
-
- void ProcessBatchedPutRequests(TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts,
- NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic);
- void Handle(TEvStopBatchingPutRequests::TPtr& ev);
- void Handle(TEvStopBatchingGetRequests::TPtr& ev);
-
- // todo: in-fly tracking for cancelation and
- void HandleNormal(TEvBlobStorage::TEvGet::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvPut::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvBlock::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvPatch::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvDiscover::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvRange::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvCollectGarbage::TPtr &ev);
- void HandleNormal(TEvBlobStorage::TEvStatus::TPtr &ev);
- void Handle(TEvBlobStorage::TEvBunchOfEvents::TPtr ev);
- void Handle(TEvDeathNote::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Error state
-
- NLog::EPriority CheckPriorityForErrorState() {
- TInstant now = TActivationContext::Now();
- if (HasInvalidGroupId()) {
- return InvalidGroupIdMuteChecker.Register(now, MuteDuration);
- } else {
- return ErrorStateMuteChecker.Register(now, MuteDuration);
- }
- }
-
- template<typename TEvent>
- void HandleError(TAutoPtr<TEventHandle<TEvent>> ev) {
- bool full = false;
- if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvBlock> || std::is_same_v<TEvent, TEvBlobStorage::TEvCollectGarbage>) {
- full = ev->Get()->IsMonitored;
- }
- EnsureMonitoring(full);
- IncMonEvent(ev->Get());
- const NKikimrProto::EReplyStatus status = (!IsEjected || HasInvalidGroupId())
- ? NKikimrProto::ERROR
- : NKikimrProto::NO_GROUP;
- auto response = ev->Get()->MakeErrorResponse(status, ErrorDescription, GroupId);
- NActors::NLog::EPriority priority = CheckPriorityForErrorState();
- LOG_LOG_S(*TlsActivationContext, priority, NKikimrServices::BS_PROXY, ExtraLogInfo << "Group# " << GroupId
- << " HandleError ev# " << ev->Get()->Print(false)
- << " Response# " << response->Print(false)
- << " Marker# DSP31");
- Send(ev->Sender, response.release(), 0, ev->Cookie);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // All states
-
- void PassAway() override;
-
- void Handle(TEvTimeStats::TPtr& ev);
- void Handle(TEvRequestProxySessionsState::TPtr &ev);
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_ACTOR;
- }
-
- TBlobStorageGroupProxy(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
- TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
+
+ TInstant EstablishingSessionStartTime;
+
+ const TDuration MuteDuration = TDuration::Seconds(5);
+ TLogPriorityMuteChecker<NLog::PRI_INFO, NLog::PRI_DEBUG> EstablishingSessionsPutMuteChecker;
+ TLogPriorityMuteChecker<NLog::PRI_INFO, NLog::PRI_DEBUG> ErrorStateMuteChecker;
+ TLogPriorityMuteChecker<NLog::PRI_CRIT, NLog::PRI_DEBUG> InvalidGroupIdMuteChecker;
+
+ bool HasInvalidGroupId() const { return GroupId == Max<ui32>(); }
+ void ProcessInitQueue();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Enable monitoring
+
+ // Create monitoring and ensure all counters if needed
+ void EnsureMonitoring(bool fullIfPossible);
+
+ template<typename TEvent>
+ void IncMonEvent(const TEvent *ev) {
+ if (!Mon) {
+ return;
+ }
+ if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPut>) {
+ Mon->CountPutEvent(ev->Buffer.size());
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvGet>) {
+ Mon->EventGet->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvBlock>) {
+ Mon->EventBlock->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvDiscover>) {
+ Mon->EventDiscover->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvRange>) {
+ Mon->EventRange->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvCollectGarbage>) {
+ Mon->EventCollectGarbage->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvStatus>) {
+ Mon->EventStatus->Inc();
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPatch>) {
+ Mon->EventPatch->Inc();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Unconfigured state
+
+ TEvEstablishingSessionTimeout *EstablishingSessionsTimeoutEv = nullptr;
+ TEvConfigureQueryTimeout *ConfigureQueryTimeoutEv = nullptr;
+ bool InEstablishingSessionsTimeout = false, InEstablishingSessionsTimeout5min = false;
+ bool InUnconfiguredTimeout = false, InUnconfiguredTimeout5min = false;
+ ui64 Cookie5min = 0;
+
+ void Handle5min(TAutoPtr<IEventHandle> ev);
+ void ClearTimeoutCounters();
+
+ void SetStateEstablishingSessions();
+ void SetStateEstablishingSessionsTimeout();
+ void SetStateUnconfigured();
+ void SetStateUnconfiguredTimeout();
+ void SetStateWork();
+
+ std::optional<TBlobStorageGroupInfo::EEncryptionMode> EncryptionMode;
+ std::optional<TBlobStorageGroupInfo::ELifeCyclePhase> LifeCyclePhase;
+ std::optional<ui64> GroupKeyNonce;
+ std::optional<TCypherKey> CypherKey;
+
+ void Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev);
+ void ApplyGroupInfo(TIntrusivePtr<TBlobStorageGroupInfo>&& info, TIntrusivePtr<TStoragePoolCounters>&& counters);
+
+ void WakeupUnconfigured(TEvConfigureQueryTimeout::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Establishing Sessions state
+
+ void SwitchToWorkWhenGoodToGo();
+ void WakeupEstablishingSessions(TEvEstablishingSessionTimeout::TPtr ev);
+ void Handle(TEvProxyQueueState::TPtr& ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Put to init queue
+
+ template<typename TEvent>
+ void HandleEnqueue(TAutoPtr<TEventHandle<TEvent>> ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " HandleEnqueue# " << ev->Get()->Print(false) << " Marker# DSP17");
+ if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvGet>) {
+ LWTRACK(DSProxyGetEnqueue, ev->Get()->Orbit);
+ } else if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvPut>) {
+ LWTRACK(DSProxyPutEnqueue, ev->Get()->Orbit);
+ }
+ UnconfiguredBufferSize += ev->Get()->CalculateSize();
+ InitQueue.emplace_back(ev.Release());
+ if (UnconfiguredBufferSize > UnconfiguredBufferSizeLimit && InitQueue.size() > 1) {
+ LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " UnconfiguredBufferSize# " << UnconfiguredBufferSize << " > " << UnconfiguredBufferSizeLimit
+ << ", dropping the queue (" << (ui64)InitQueue.size() << ")" << " Marker# DSP08");
+ if (CurrentStateFunc() == &TThis::StateUnconfigured) {
+ ErrorDescription = "Too many requests while waiting for configuration (DSPE2).";
+ SetStateUnconfiguredTimeout();
+ } else if (CurrentStateFunc() == &TThis::StateEstablishingSessions) {
+ ErrorDescription = "Too many requests while establishing sessions (DSPE5).";
+ SetStateEstablishingSessionsTimeout();
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Normal state
+
+ template<typename TEventPtr>
+ void EnableWilsonTracing(TEventPtr &ev, TAtomic &sampleRate) {
+ if (!ev->TraceId) {
+ const ui64 rate = AtomicGet(sampleRate);
+ if (rate) {
+ const ui64 num = RandomNumber<ui64>(1000000); // in range [0, 1000000)
+ if (num < rate) {
+ ev->TraceId = NWilson::TTraceId::NewTraceId();
+ }
+ }
+ }
+ }
+
+ TMaybe<TGroupStat::EKind> PutHandleClassToGroupStatKind(NKikimrBlobStorage::EPutHandleClass handleClass) {
+ switch (handleClass) {
+ case NKikimrBlobStorage::TabletLog:
+ return TGroupStat::EKind::PUT_TABLET_LOG;
+
+ case NKikimrBlobStorage::UserData:
+ return TGroupStat::EKind::PUT_USER_DATA;
+
+ default:
+ return {};
+ }
+ }
+
+ void ProcessBatchedPutRequests(TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts,
+ NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic);
+ void Handle(TEvStopBatchingPutRequests::TPtr& ev);
+ void Handle(TEvStopBatchingGetRequests::TPtr& ev);
+
+ // todo: in-fly tracking for cancelation and
+ void HandleNormal(TEvBlobStorage::TEvGet::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvPut::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvBlock::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvPatch::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvDiscover::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvRange::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvCollectGarbage::TPtr &ev);
+ void HandleNormal(TEvBlobStorage::TEvStatus::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvBunchOfEvents::TPtr ev);
+ void Handle(TEvDeathNote::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Error state
+
+ NLog::EPriority CheckPriorityForErrorState() {
+ TInstant now = TActivationContext::Now();
+ if (HasInvalidGroupId()) {
+ return InvalidGroupIdMuteChecker.Register(now, MuteDuration);
+ } else {
+ return ErrorStateMuteChecker.Register(now, MuteDuration);
+ }
+ }
+
+ template<typename TEvent>
+ void HandleError(TAutoPtr<TEventHandle<TEvent>> ev) {
+ bool full = false;
+ if constexpr (std::is_same_v<TEvent, TEvBlobStorage::TEvBlock> || std::is_same_v<TEvent, TEvBlobStorage::TEvCollectGarbage>) {
+ full = ev->Get()->IsMonitored;
+ }
+ EnsureMonitoring(full);
+ IncMonEvent(ev->Get());
+ const NKikimrProto::EReplyStatus status = (!IsEjected || HasInvalidGroupId())
+ ? NKikimrProto::ERROR
+ : NKikimrProto::NO_GROUP;
+ auto response = ev->Get()->MakeErrorResponse(status, ErrorDescription, GroupId);
+ NActors::NLog::EPriority priority = CheckPriorityForErrorState();
+ LOG_LOG_S(*TlsActivationContext, priority, NKikimrServices::BS_PROXY, ExtraLogInfo << "Group# " << GroupId
+ << " HandleError ev# " << ev->Get()->Print(false)
+ << " Response# " << response->Print(false)
+ << " Marker# DSP31");
+ Send(ev->Sender, response.release(), 0, ev->Cookie);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // All states
+
+ void PassAway() override;
+
+ void Handle(TEvTimeStats::TPtr& ev);
+ void Handle(TEvRequestProxySessionsState::TPtr &ev);
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_ACTOR;
+ }
+
+ TBlobStorageGroupProxy(TIntrusivePtr<TBlobStorageGroupInfo>&& info, bool forceWaitAllDrives,
+ TIntrusivePtr<TDsProxyNodeMon> &nodeMon, TIntrusivePtr<TStoragePoolCounters>&& storagePoolCounters,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch);
-
- TBlobStorageGroupProxy(ui32 groupId, bool isEjected, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
+
+ TBlobStorageGroupProxy(ui32 groupId, bool isEjected, TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
const TControlWrapper &enablePutBatching, const TControlWrapper &enableVPatch);
-
- void Bootstrap();
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Configuration process
-
- void HandleUpdateResponsiveness();
- void ScheduleUpdateResponsiveness();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Group statistics
-
- const TDuration GroupStatUpdateInterval = TDuration::Seconds(10);
- bool GroupStatUpdateScheduled = false;
- TGroupStat Stat;
-
- void HandleUpdateGroupStat();
- void ScheduleUpdateGroupStat();
- void Handle(TEvLatencyReport::TPtr& ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // State functions
-
- STRICT_STFUNC(StateCommon,
- hFunc(TEvStopBatchingPutRequests, Handle);
- hFunc(TEvStopBatchingGetRequests, Handle);
- hFunc(TEvDeathNote, Handle);
- hFunc(TEvRequestProxySessionsState, Handle);
- hFunc(TEvBlobStorage::TEvBunchOfEvents, Handle);
- hFunc(TEvTimeStats, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(TEvBlobStorage::TEvConfigureProxy, Handle);
- hFunc(TEvProxyQueueState, Handle);
- cFunc(EvUpdateResponsiveness, HandleUpdateResponsiveness);
- cFunc(EvUpdateGroupStat, HandleUpdateGroupStat);
- hFunc(TEvLatencyReport, Handle);
- IgnoreFunc(TEvConfigureQueryTimeout);
- IgnoreFunc(TEvEstablishingSessionTimeout);
- fFunc(Ev5min, Handle5min);
- )
-
-#define HANDLE_EVENTS(HANDLER) \
- hFunc(TEvBlobStorage::TEvPut, HANDLER); \
- hFunc(TEvBlobStorage::TEvGet, HANDLER); \
- hFunc(TEvBlobStorage::TEvBlock, HANDLER); \
- hFunc(TEvBlobStorage::TEvDiscover, HANDLER); \
- hFunc(TEvBlobStorage::TEvRange, HANDLER); \
- hFunc(TEvBlobStorage::TEvCollectGarbage, HANDLER); \
- hFunc(TEvBlobStorage::TEvStatus, HANDLER); \
- hFunc(TEvBlobStorage::TEvPatch, HANDLER); \
- /**/
-
- STFUNC(StateUnconfigured) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleEnqueue);
- hFunc(TEvConfigureQueryTimeout, WakeupUnconfigured);
+
+ void Bootstrap();
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Configuration process
+
+ void HandleUpdateResponsiveness();
+ void ScheduleUpdateResponsiveness();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Group statistics
+
+ const TDuration GroupStatUpdateInterval = TDuration::Seconds(10);
+ bool GroupStatUpdateScheduled = false;
+ TGroupStat Stat;
+
+ void HandleUpdateGroupStat();
+ void ScheduleUpdateGroupStat();
+ void Handle(TEvLatencyReport::TPtr& ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // State functions
+
+ STRICT_STFUNC(StateCommon,
+ hFunc(TEvStopBatchingPutRequests, Handle);
+ hFunc(TEvStopBatchingGetRequests, Handle);
+ hFunc(TEvDeathNote, Handle);
+ hFunc(TEvRequestProxySessionsState, Handle);
+ hFunc(TEvBlobStorage::TEvBunchOfEvents, Handle);
+ hFunc(TEvTimeStats, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(TEvBlobStorage::TEvConfigureProxy, Handle);
+ hFunc(TEvProxyQueueState, Handle);
+ cFunc(EvUpdateResponsiveness, HandleUpdateResponsiveness);
+ cFunc(EvUpdateGroupStat, HandleUpdateGroupStat);
+ hFunc(TEvLatencyReport, Handle);
+ IgnoreFunc(TEvConfigureQueryTimeout);
+ IgnoreFunc(TEvEstablishingSessionTimeout);
+ fFunc(Ev5min, Handle5min);
+ )
+
+#define HANDLE_EVENTS(HANDLER) \
+ hFunc(TEvBlobStorage::TEvPut, HANDLER); \
+ hFunc(TEvBlobStorage::TEvGet, HANDLER); \
+ hFunc(TEvBlobStorage::TEvBlock, HANDLER); \
+ hFunc(TEvBlobStorage::TEvDiscover, HANDLER); \
+ hFunc(TEvBlobStorage::TEvRange, HANDLER); \
+ hFunc(TEvBlobStorage::TEvCollectGarbage, HANDLER); \
+ hFunc(TEvBlobStorage::TEvStatus, HANDLER); \
+ hFunc(TEvBlobStorage::TEvPatch, HANDLER); \
+ /**/
+
+ STFUNC(StateUnconfigured) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleEnqueue);
+ hFunc(TEvConfigureQueryTimeout, WakeupUnconfigured);
+ default: return StateCommon(ev, ctx);
+ }
+ }
+
+ STFUNC(StateUnconfiguredTimeout) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleError);
+ default: return StateUnconfigured(ev, ctx);
+ }
+ }
+
+ STFUNC(StateEstablishingSessions) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleEnqueue);
+ hFunc(TEvEstablishingSessionTimeout, WakeupEstablishingSessions);
+ default: return StateCommon(ev, ctx);
+ }
+ }
+
+ STFUNC(StateEstablishingSessionsTimeout) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleError);
+ default: return StateEstablishingSessions(ev, ctx);
+ }
+ }
+
+ STFUNC(StateWork) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleNormal);
+ default: return StateCommon(ev, ctx);
+ }
+ }
+
+ STFUNC(StateEjected) {
+ switch (ev->GetTypeRewrite()) {
+ HANDLE_EVENTS(HandleError);
default: return StateCommon(ev, ctx);
- }
- }
-
- STFUNC(StateUnconfiguredTimeout) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleError);
- default: return StateUnconfigured(ev, ctx);
- }
- }
-
- STFUNC(StateEstablishingSessions) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleEnqueue);
- hFunc(TEvEstablishingSessionTimeout, WakeupEstablishingSessions);
- default: return StateCommon(ev, ctx);
- }
- }
-
- STFUNC(StateEstablishingSessionsTimeout) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleError);
- default: return StateEstablishingSessions(ev, ctx);
- }
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleNormal);
- default: return StateCommon(ev, ctx);
- }
- }
-
- STFUNC(StateEjected) {
- switch (ev->GetTypeRewrite()) {
- HANDLE_EVENTS(HandleError);
- default: return StateCommon(ev, ctx);
- }
- }
-};
-
-}
+ }
+ }
+};
+
+}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_indexrestoreget.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_indexrestoreget.cpp
index e1a634e5591..c5a5c78ccf1 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_indexrestoreget.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_indexrestoreget.cpp
@@ -1,7 +1,7 @@
#include "dsproxy.h"
#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
-#include "dsproxy_blob_tracker.h"
+#include "dsproxy_quorum_tracker.h"
+#include "dsproxy_blob_tracker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/base/wilson_events.h>
#include <util/generic/set.h>
@@ -15,13 +15,13 @@ namespace NKikimr {
class TBlobStorageGroupIndexRestoreGetRequest
: public TBlobStorageGroupRequestActor<TBlobStorageGroupIndexRestoreGetRequest> {
const ui32 QuerySize;
- TArrayHolder<TEvBlobStorage::TEvGet::TQuery> Queries;
+ TArrayHolder<TEvBlobStorage::TEvGet::TQuery> Queries;
const TInstant Deadline;
- const bool IsInternal;
+ const bool IsInternal;
- THashMap<ui64, TGroupQuorumTracker> QuorumTracker;
+ THashMap<ui64, TGroupQuorumTracker> QuorumTracker;
TVector<TBlobStatusTracker> BlobStatus;
- ui32 VGetsInFlight;
+ ui32 VGetsInFlight;
TInstant StartTime;
NKikimrBlobStorage::EGetHandleClass GetHandleClass;
@@ -30,131 +30,131 @@ class TBlobStorageGroupIndexRestoreGetRequest
ui64 RestoreQueriesStarted;
ui64 RestoreQueriesFinished;
- std::unique_ptr<TEvBlobStorage::TEvGetResult> PendingResult;
+ std::unique_ptr<TEvBlobStorage::TEvGetResult> PendingResult;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
A_LOG_DEBUG_S("DSPI14", "ReplyAndDie"
<< " Reply with status# " << NKikimrProto::EReplyStatus_Name(status)
<< " PendingResult# " << (PendingResult ? PendingResult->ToString().data() : "nullptr"));
if (status != NKikimrProto::OK) {
- PendingResult.reset(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
- for (ui32 i = 0; i < QuerySize; ++i) {
- auto& item = PendingResult->Responses[i];
- item.Status = status;
- item.Id = Queries[i].Id;
- item.Shift = Queries[i].Shift;
- item.RequestedSize = Queries[i].Size;
- }
+ PendingResult.reset(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
+ for (ui32 i = 0; i < QuerySize; ++i) {
+ auto& item = PendingResult->Responses[i];
+ item.Status = status;
+ item.Id = Queries[i].Id;
+ item.Shift = Queries[i].Shift;
+ item.RequestedSize = Queries[i].Size;
+ }
PendingResult->ErrorReason = ErrorReason;
}
Y_VERIFY(PendingResult);
- Mon->CountIndexRestoreGetResponseTime(TActivationContext::Now() - StartTime);
- SendResponseAndDie(std::move(PendingResult));
+ Mon->CountIndexRestoreGetResponseTime(TActivationContext::Now() - StartTime);
+ SendResponseAndDie(std::move(PendingResult));
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupIndexRestoreGetRequest>;
TString DumpBlobStatus() const {
- TStringStream str("{");
-
- for (ui32 i = 0; i < BlobStatus.size(); ++i) {
- if (i) {
- str << " ";
- }
- BlobStatus[i].Output(str, Info.Get());
- }
-
- str << "}";
- return str.Str();
- }
-
+ TStringStream str("{");
+
+ for (ui32 i = 0; i < BlobStatus.size(); ++i) {
+ if (i) {
+ str << " ";
+ }
+ BlobStatus[i].Output(str, Info.Get());
+ }
+
+ str << "}";
+ return str.Str();
+ }
+
TString DumpBlobStatus(ui32 i) const {
- TStringStream str;
- BlobStatus[i].Output(str, Info.Get());
- return str.Str();
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
+ TStringStream str;
+ BlobStatus[i].Output(str, Info.Get());
+ return str.Str();
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
const NKikimrBlobStorage::TEvVGetResult &record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
NKikimrProto::EReplyStatus status = record.GetStatus();
- Y_VERIFY(record.HasVDiskID());
- const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
-
- Y_VERIFY(VGetsInFlight > 0);
- --VGetsInFlight;
-
- A_LOG_DEBUG_S("DSPI10", "Handle TEvVGetResult"
+ Y_VERIFY(record.HasVDiskID());
+ const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
+
+ Y_VERIFY(VGetsInFlight > 0);
+ --VGetsInFlight;
+
+ A_LOG_DEBUG_S("DSPI10", "Handle TEvVGetResult"
<< " status# " << NKikimrProto::EReplyStatus_Name(status).data()
- << " VDiskId# " << vdisk
- << " ev# " << ev->Get()->ToString());
-
- Y_VERIFY(record.HasCookie());
- const ui64 queueId = record.GetCookie();
- Y_VERIFY(queueId > 0);
-
- auto it = QuorumTracker.find(queueId);
- Y_VERIFY(it != QuorumTracker.end());
-
- switch (NKikimrProto::EReplyStatus newStatus = it->second.ProcessReply(vdisk, status)) {
- case NKikimrProto::ERROR:
- return ReplyAndDie(NKikimrProto::ERROR);
-
- case NKikimrProto::OK:
- case NKikimrProto::UNKNOWN:
- break;
-
- default:
+ << " VDiskId# " << vdisk
+ << " ev# " << ev->Get()->ToString());
+
+ Y_VERIFY(record.HasCookie());
+ const ui64 queueId = record.GetCookie();
+ Y_VERIFY(queueId > 0);
+
+ auto it = QuorumTracker.find(queueId);
+ Y_VERIFY(it != QuorumTracker.end());
+
+ switch (NKikimrProto::EReplyStatus newStatus = it->second.ProcessReply(vdisk, status)) {
+ case NKikimrProto::ERROR:
+ return ReplyAndDie(NKikimrProto::ERROR);
+
+ case NKikimrProto::OK:
+ case NKikimrProto::UNKNOWN:
+ break;
+
+ default:
Y_FAIL("unexpected newStatus# %s", NKikimrProto::EReplyStatus_Name(newStatus).data());
}
- for (const auto& result : record.GetResult()) {
- const TLogoBlobID& blobId = LogoBlobIDFromLogoBlobID(result.GetBlobID());
- const ui32 queryIdx = result.GetCookie();
- Y_VERIFY(queryIdx < QuerySize && blobId == Queries[queryIdx].Id);
- BlobStatus[queryIdx].UpdateFromResponseData(result, vdisk, Info.Get());
+ for (const auto& result : record.GetResult()) {
+ const TLogoBlobID& blobId = LogoBlobIDFromLogoBlobID(result.GetBlobID());
+ const ui32 queryIdx = result.GetCookie();
+ Y_VERIFY(queryIdx < QuerySize && blobId == Queries[queryIdx].Id);
+ BlobStatus[queryIdx].UpdateFromResponseData(result, vdisk, Info.Get());
}
- if (!VGetsInFlight) {
- OnEnoughVGetResults();
+ if (!VGetsInFlight) {
+ OnEnoughVGetResults();
}
}
- void OnEnoughVGetResults() {
- PendingResult.reset(new TEvBlobStorage::TEvGetResult(NKikimrProto::OK, QuerySize, Info->GroupID));
- for (ui32 idx = 0; idx < QuerySize; ++idx) {
- const TBlobStatusTracker& blobTracker = BlobStatus[idx];
- bool lostByIngress;
- TBlobStorageGroupInfo::EBlobState blobState = blobTracker.GetBlobState(Info.Get(), &lostByIngress);
+ void OnEnoughVGetResults() {
+ PendingResult.reset(new TEvBlobStorage::TEvGetResult(NKikimrProto::OK, QuerySize, Info->GroupID));
+ for (ui32 idx = 0; idx < QuerySize; ++idx) {
+ const TBlobStatusTracker& blobTracker = BlobStatus[idx];
+ bool lostByIngress;
+ TBlobStorageGroupInfo::EBlobState blobState = blobTracker.GetBlobState(Info.Get(), &lostByIngress);
auto &q = Queries[idx];
auto &a = PendingResult->Responses[idx];
a.Id = q.Id;
- A_LOG_DEBUG_S("DSPI11", "OnEnoughVGetResults Id# " << q.Id << " BlobStatus# " << DumpBlobStatus(idx));
-
+ A_LOG_DEBUG_S("DSPI11", "OnEnoughVGetResults Id# " << q.Id << " BlobStatus# " << DumpBlobStatus(idx));
+
if (blobState == TBlobStorageGroupInfo::EBS_DISINTEGRATED) {
- R_LOG_ERROR_S("DSPI04", "OnEnoughVGetResults"
+ R_LOG_ERROR_S("DSPI04", "OnEnoughVGetResults"
<< " disintegrated, id# " << Queries[idx].Id.ToString()
- << " BlobStatus# " << DumpBlobStatus(idx));
- ReplyAndDie(NKikimrProto::ERROR);
+ << " BlobStatus# " << DumpBlobStatus(idx));
+ ReplyAndDie(NKikimrProto::ERROR);
return;
} else if (blobState == TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY) {
// The blob must have never been written.
a.Status = NKikimrProto::NODATA;
// Proove it using part bits from VDisks
- if (lostByIngress) {
+ if (lostByIngress) {
// The blob might actually be written! Report the error!
- R_LOG_ERROR_S("DSPI05", "OnEnoughVGetResults for tablet# " << TabletId
+ R_LOG_ERROR_S("DSPI05", "OnEnoughVGetResults for tablet# " << TabletId
<< " unrecoverable blob, id# " << Queries[idx].Id.ToString()
- << " BlobStatus# " << DumpBlobStatus(idx));
+ << " BlobStatus# " << DumpBlobStatus(idx));
if (IngressAsAReasonForErrorEnabled) {
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
return;
}
}
@@ -162,14 +162,14 @@ class TBlobStorageGroupIndexRestoreGetRequest
blobState == TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY) {
// Blob is not full, send EvGet to recover it
a.Status = NKikimrProto::OK;
- std::unique_ptr<TEvBlobStorage::TEvGet> get(new TEvBlobStorage::TEvGet(
+ std::unique_ptr<TEvBlobStorage::TEvGet> get(new TEvBlobStorage::TEvGet(
Queries[idx].Id, 0, 0, Deadline,
GetHandleClass, true));
- A_LOG_DEBUG_S("DSPI12", "OnEnoughVGetResults"
+ A_LOG_DEBUG_S("DSPI12", "OnEnoughVGetResults"
<< " recoverable blob, id# " << Queries[idx].Id.ToString()
- << " BlobStatus# " << DumpBlobStatus(idx)
- << " sending EvGet");
- SendToBSProxy(SelfId(), Info->GroupID, get.release(), 0);
+ << " BlobStatus# " << DumpBlobStatus(idx)
+ << " sending EvGet");
+ SendToBSProxy(SelfId(), Info->GroupID, get.release(), 0);
RestoreQueriesStarted++;
} else if (blobState == TBlobStorageGroupInfo::EBS_FULL) {
a.Status = NKikimrProto::OK;
@@ -177,26 +177,26 @@ class TBlobStorageGroupIndexRestoreGetRequest
}
if (RestoreQueriesStarted == 0) {
- ReplyAndDie(NKikimrProto::OK);
+ ReplyAndDie(NKikimrProto::OK);
return;
}
Become(&TThis::StateRestore);
- A_LOG_DEBUG_S("DSPI13", "OnEnoughVGetResults"
- << " Become StateRestore RestoreQueriesStarted# " << RestoreQueriesStarted);
+ A_LOG_DEBUG_S("DSPI13", "OnEnoughVGetResults"
+ << " Become StateRestore RestoreQueriesStarted# " << RestoreQueriesStarted);
return;
}
- void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
TEvBlobStorage::TEvGetResult &getResult = *ev->Get();
NKikimrProto::EReplyStatus status = getResult.Status;
if (status != NKikimrProto::OK) {
R_LOG_ERROR_S("DSPI06", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status).data()
<< " for tablet# " << TabletId
- << " BlobStatus# " << DumpBlobStatus());
- ReplyAndDie(status);
+ << " BlobStatus# " << DumpBlobStatus());
+ ReplyAndDie(status);
return;
}
@@ -204,20 +204,20 @@ class TBlobStorageGroupIndexRestoreGetRequest
for (ui32 i = 0; i < getResult.ResponseSz; ++i) {
TEvBlobStorage::TEvGetResult::TResponse &response = getResult.Responses[i];
if (response.Status != NKikimrProto::OK) {
- R_LOG_ERROR_S("DSPI07", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
+ R_LOG_ERROR_S("DSPI07", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
<< " Response[" << i << "]# " << NKikimrProto::EReplyStatus_Name(response.Status)
<< " for tablet# " << TabletId
- << " BlobStatus# " << DumpBlobStatus());
+ << " BlobStatus# " << DumpBlobStatus());
SetPendingResultResponseStatus(response.Id, response.Status);
}
}
- A_LOG_LOG_S(true, PriorityForStatusInbound(status), "DSPI08", "Result# " << getResult.Print(false)
+ A_LOG_LOG_S(true, PriorityForStatusInbound(status), "DSPI08", "Result# " << getResult.Print(false)
<< " RestoreQueriesStarted# " << RestoreQueriesStarted
- << " RestoreQueriesFinished# " << RestoreQueriesFinished);
+ << " RestoreQueriesFinished# " << RestoreQueriesFinished);
RestoreQueriesFinished++;
if (RestoreQueriesFinished == RestoreQueriesStarted) {
- ReplyAndDie(NKikimrProto::OK);
+ ReplyAndDie(NKikimrProto::OK);
return;
}
return;
@@ -233,40 +233,40 @@ class TBlobStorageGroupIndexRestoreGetRequest
}
}
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartIndexRestoreGet;
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(Queries, QuerySize, Deadline, GetHandleClass,
- true /*mustRestoreFirst*/, true /*isIndexOnly*/, 0u /*forceBlockedGeneration*/, IsInternal);
- ev->RestartCounter = counter;
- return ev;
- }
-
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartIndexRestoreGet;
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(Queries, QuerySize, Deadline, GetHandleClass,
+ true /*mustRestoreFirst*/, true /*isIndexOnly*/, 0u /*forceBlockedGeneration*/, IsInternal);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_INDEXRESTOREGET_ACTOR;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveIndexRestoreGet;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Get;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_INDEXRESTOREGET_ACTOR;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveIndexRestoreGet;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Get;
+ }
+
TBlobStorageGroupIndexRestoreGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev, ui64 cookie,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev, ui64 cookie,
NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
- NKikimrServices::BS_PROXY_INDEXRESTOREGET, false, latencyQueueKind, now, storagePoolCounters,
- ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ NKikimrServices::BS_PROXY_INDEXRESTOREGET, false, latencyQueueKind, now, storagePoolCounters,
+ ev->RestartCounter)
, QuerySize(ev->QuerySize)
, Queries(ev->Queries.Release())
, Deadline(ev->Deadline)
- , IsInternal(ev->IsInternal)
- , VGetsInFlight(0)
+ , IsInternal(ev->IsInternal)
+ , VGetsInFlight(0)
, StartTime(now)
, GetHandleClass(ev->GetHandleClass)
, RestoreQueriesStarted(0)
@@ -277,105 +277,105 @@ public:
} else {
TabletId = 0;
}
-
- BlobStatus.reserve(QuerySize);
- for (ui32 idx = 0; idx < QuerySize; ++idx) {
- BlobStatus.emplace_back(Queries[idx].Id, Info.Get());
- }
+
+ BlobStatus.reserve(QuerySize);
+ for (ui32 idx = 0; idx < QuerySize; ++idx) {
+ BlobStatus.emplace_back(Queries[idx].Id, Info.Get());
+ }
}
- void Bootstrap() {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetReceived);
-
- auto makeQueriesList = [this] {
- TStringStream str;
- str << "{";
- for (ui32 i = 0; i < QuerySize; ++i) {
- str << (i ? " " : "")
- << Queries[i].Id.ToString();
- }
- str << "}";
- return str.Str();
- };
- A_LOG_INFO_S("DSPI09", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " QuerySize# " << QuerySize
- << " Queries# " << makeQueriesList()
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
- for (const auto& vdisk : Info->GetVDisks()) {
+ void Bootstrap() {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetReceived);
+
+ auto makeQueriesList = [this] {
+ TStringStream str;
+ str << "{";
+ for (ui32 i = 0; i < QuerySize; ++i) {
+ str << (i ? " " : "")
+ << Queries[i].Id.ToString();
+ }
+ str << "}";
+ return str.Str();
+ };
+ A_LOG_INFO_S("DSPI09", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " QuerySize# " << QuerySize
+ << " Queries# " << makeQueriesList()
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
+ for (const auto& vdisk : Info->GetVDisks()) {
auto vd = Info->GetVDiskId(vdisk.OrderNumber);
- std::unique_ptr<TEvBlobStorage::TEvVGet> vget;
- ui64 queueId = 1;
-
- auto sendQuery = [&] {
- if (vget) {
- const ui64 cookie = TVDiskIdShort(vd).GetRaw();
- CountEvent(*vget);
- SendToQueue(std::move(vget), cookie, NWilson::TTraceId()); // FIXME: wilson
- vget.reset();
- ++VGetsInFlight;
- }
- };
-
- // Loop through the queries
- for (ui32 queryIdx = 0; queryIdx < QuerySize; ++queryIdx) {
- const TLogoBlobID &id = Queries[queryIdx].Id;
- // If the disk is a replica for the query logoblobid, add it to the vquerry
+ std::unique_ptr<TEvBlobStorage::TEvVGet> vget;
+ ui64 queueId = 1;
+
+ auto sendQuery = [&] {
+ if (vget) {
+ const ui64 cookie = TVDiskIdShort(vd).GetRaw();
+ CountEvent(*vget);
+ SendToQueue(std::move(vget), cookie, NWilson::TTraceId()); // FIXME: wilson
+ vget.reset();
+ ++VGetsInFlight;
+ }
+ };
+
+ // Loop through the queries
+ for (ui32 queryIdx = 0; queryIdx < QuerySize; ++queryIdx) {
+ const TLogoBlobID &id = Queries[queryIdx].Id;
+ // If the disk is a replica for the query logoblobid, add it to the vquerry
if (Info->BelongsToSubgroup(vd, id.Hash())) {
- if (!vget) {
- const ui64 cookie = queueId++;
- if (!QuorumTracker.count(cookie)) {
- QuorumTracker.emplace(cookie, Info.Get());
- }
-
- vget = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(vd, Deadline,
- NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::ShowInternals, cookie);
-
- vget->Record.SetSuppressBarrierCheck(IsInternal);
+ if (!vget) {
+ const ui64 cookie = queueId++;
+ if (!QuorumTracker.count(cookie)) {
+ QuorumTracker.emplace(cookie, Info.Get());
+ }
+
+ vget = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(vd, Deadline,
+ NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::ShowInternals, cookie);
+
+ vget->Record.SetSuppressBarrierCheck(IsInternal);
}
- const ui64 cookie = queryIdx;
- vget->AddExtremeQuery(id, 0, 0, &cookie);
- }
- if ((queryIdx + 1) % 65536 == 0) {
- sendQuery();
+ const ui64 cookie = queryIdx;
+ vget->AddExtremeQuery(id, 0, 0, &cookie);
}
+ if ((queryIdx + 1) % 65536 == 0) {
+ sendQuery();
+ }
}
- // If vqeurry array is not empty, send the query to the disk, else mark request replied
- sendQuery();
+ // If vqeurry array is not empty, send the query to the disk, else mark request replied
+ sendQuery();
}
Y_VERIFY(VGetsInFlight);
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
}
}
- STATEFN(StateRestore) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateRestore) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupIndexRestoreGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
- return new TBlobStorageGroupIndexRestoreGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
+ return new TBlobStorageGroupIndexRestoreGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
latencyQueueKind, now, storagePoolCounters);
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
index 73afac8121f..9168ce4c8a3 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_mon.cpp
@@ -1,12 +1,12 @@
-#include "dsproxy_mon.h"
+#include "dsproxy_mon.h"
static const TVector<float> Percentiles1 = {1.0f};
static const TVector<float> Percentiles4 = {0.5f, 0.9f, 0.95f, 1.0f};
namespace NKikimr {
-TBlobStorageGroupProxyMon::TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const TIntrusivePtr<NMonitoring::TDynamicCounters>& percentileCounters,
+TBlobStorageGroupProxyMon::TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const TIntrusivePtr<NMonitoring::TDynamicCounters>& percentileCounters,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& overviewCounters,
const TIntrusivePtr<TBlobStorageGroupInfo>& info,
const TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
@@ -18,13 +18,13 @@ TBlobStorageGroupProxyMon::TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonito
, LatencyOverviewGroup(overviewCounters->GetSubgroup("subsystem", "latency"))
, EventGroup(Counters->GetSubgroup("subsystem", "event"))
, HandoffGroup(Counters->GetSubgroup("subsystem", "handoff"))
- , ActiveRequestsGroup(Counters->GetSubgroup("subsystem", "requests"))
+ , ActiveRequestsGroup(Counters->GetSubgroup("subsystem", "requests"))
{
- if (info) {
+ if (info) {
const TBlobStorageGroupInfo::TDynamicInfo& dyn = info->GetDynamicInfo();
GroupIdGen = (ui64(dyn.GroupId) << 32) | dyn.GroupGeneration;
- }
-
+ }
+
BlockResponseTime.Initialize(ResponseGroup, "event", "block", "Response in millisec", Percentiles1);
if (!constructLimited) {
@@ -32,44 +32,44 @@ TBlobStorageGroupProxyMon::TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonito
}
// event counters
- EventPut = EventGroup->GetCounter("EvPut", true);
- EventPutBytes = EventGroup->GetCounter("EvPutBytes", true);
- EventGet = EventGroup->GetCounter("EvGet", true);
+ EventPut = EventGroup->GetCounter("EvPut", true);
+ EventPutBytes = EventGroup->GetCounter("EvPutBytes", true);
+ EventGet = EventGroup->GetCounter("EvGet", true);
EventGetResBytes = EventGroup->GetCounter("EvGetResBytes", true);
- EventBlock = EventGroup->GetCounter("EvBlock", true);
- EventDiscover = EventGroup->GetCounter("EvDiscover", true);
- EventRange = EventGroup->GetCounter("EvRange", true);
- EventCollectGarbage = EventGroup->GetCounter("EvCollectGarbage", true);
- EventMultiGet = EventGroup->GetCounter("EvMultiGet", true);
- EventIndexRestoreGet = EventGroup->GetCounter("EvIndexRestoreGet", true);
- EventMultiCollect = EventGroup->GetCounter("EvMultiCollect", true);
+ EventBlock = EventGroup->GetCounter("EvBlock", true);
+ EventDiscover = EventGroup->GetCounter("EvDiscover", true);
+ EventRange = EventGroup->GetCounter("EvRange", true);
+ EventCollectGarbage = EventGroup->GetCounter("EvCollectGarbage", true);
+ EventMultiGet = EventGroup->GetCounter("EvMultiGet", true);
+ EventIndexRestoreGet = EventGroup->GetCounter("EvIndexRestoreGet", true);
+ EventMultiCollect = EventGroup->GetCounter("EvMultiCollect", true);
EventStatus = EventGroup->GetCounter("EvStatus", true);
EventStopPutBatching = EventGroup->GetCounter("EvStopPutBatching", true);
EventStopGetBatching = EventGroup->GetCounter("EvStopGetBatching", true);
EventPatch = EventGroup->GetCounter("EvPatch", true);
-
+
PutsSentViaPutBatching = EventGroup->GetCounter("PutsSentViaPutBatching", true);
PutBatchesSent = EventGroup->GetCounter("PutBatchesSent", true);
- auto buckets = EventGroup->GetSubgroup("sensor", "EvPutBytesBuckets");
+ auto buckets = EventGroup->GetSubgroup("sensor", "EvPutBytesBuckets");
for (ui32 size : {0, 256, 4096, 65536, 250000, 1000000, 4000000}) {
EventPutBytesBuckets.emplace(size, buckets->GetNamedCounter("size", Sprintf("%" PRIu32, (ui32)size), true));
- }
+ }
// handoff use reason
- for (size_t i = 0; i < HandoffPartsSent.size(); ++i) {
- HandoffPartsSent[i] = HandoffGroup->GetSubgroup("handoffPartsSent", Sprintf("%zu", i))->GetCounter("events", true);
- }
-
- // active requests
- ActivePut = ActiveRequestsGroup->GetCounter("ActivePut");
+ for (size_t i = 0; i < HandoffPartsSent.size(); ++i) {
+ HandoffPartsSent[i] = HandoffGroup->GetSubgroup("handoffPartsSent", Sprintf("%zu", i))->GetCounter("events", true);
+ }
+
+ // active requests
+ ActivePut = ActiveRequestsGroup->GetCounter("ActivePut");
ActivePutCapacity = ActiveRequestsGroup->GetCounter("ActivePutCapacity");
- ActiveGet = ActiveRequestsGroup->GetCounter("ActiveGet");
+ ActiveGet = ActiveRequestsGroup->GetCounter("ActiveGet");
ActiveGetCapacity = ActiveRequestsGroup->GetCounter("ActiveGetCapacity");
- ActiveBlock = ActiveRequestsGroup->GetCounter("ActiveBlock");
- ActiveDiscover = ActiveRequestsGroup->GetCounter("ActiveDiscover");
- ActiveRange = ActiveRequestsGroup->GetCounter("ActiveRange");
- ActiveCollectGarbage = ActiveRequestsGroup->GetCounter("ActiveCollectGarbage");
+ ActiveBlock = ActiveRequestsGroup->GetCounter("ActiveBlock");
+ ActiveDiscover = ActiveRequestsGroup->GetCounter("ActiveDiscover");
+ ActiveRange = ActiveRequestsGroup->GetCounter("ActiveRange");
+ ActiveCollectGarbage = ActiveRequestsGroup->GetCounter("ActiveCollectGarbage");
ActiveStatus = ActiveRequestsGroup->GetCounter("ActiveStatus");
ActivePatch = ActiveRequestsGroup->GetCounter("ActivePatch");
@@ -78,38 +78,38 @@ TBlobStorageGroupProxyMon::TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonito
VPatchPartPlacementVerifyFailed = ActiveRequestsGroup->GetCounter("VPatchPartPlacementVerifyFailed");
PatchesWithFallback = ActiveRequestsGroup->GetCounter("PatchesWithFallback");
- // subevents
- {
- auto group = Counters->GetSubgroup("subsystem", "subevents");
- GetGroup.Init(group->GetSubgroup("request", "get"));
- PutGroup.Init(group->GetSubgroup("request", "put"));
- DiscoverGroup.Init(group->GetSubgroup("request", "discover"));
- RangeGroup.Init(group->GetSubgroup("request", "range"));
+ // subevents
+ {
+ auto group = Counters->GetSubgroup("subsystem", "subevents");
+ GetGroup.Init(group->GetSubgroup("request", "get"));
+ PutGroup.Init(group->GetSubgroup("request", "put"));
+ DiscoverGroup.Init(group->GetSubgroup("request", "discover"));
+ RangeGroup.Init(group->GetSubgroup("request", "range"));
PatchGroup.Init(group->GetSubgroup("request", "patch"));
- }
-
+ }
+
ActiveMultiGet = ActiveRequestsGroup->GetCounter("ActiveMultiGet");
ActiveIndexRestoreGet = ActiveRequestsGroup->GetCounter("ActiveIndexRestoreGet");
ActiveMultiCollect = ActiveRequestsGroup->GetCounter("ActiveMultiCollect");
-
- auto respStatGroup = NodeMon->Group->GetSubgroup("subsystem", "responseStatus");
- RespStatPut.emplace(respStatGroup->GetSubgroup("request", "put"));
- RespStatGet.emplace(respStatGroup->GetSubgroup("request", "get"));
- RespStatBlock.emplace(respStatGroup->GetSubgroup("request", "block"));
- RespStatDiscover.emplace(respStatGroup->GetSubgroup("request", "discover"));
- RespStatRange.emplace(respStatGroup->GetSubgroup("request", "range"));
- RespStatCollectGarbage.emplace(respStatGroup->GetSubgroup("request", "collectGarbage"));
- RespStatStatus.emplace(respStatGroup->GetSubgroup("request", "status"));
+
+ auto respStatGroup = NodeMon->Group->GetSubgroup("subsystem", "responseStatus");
+ RespStatPut.emplace(respStatGroup->GetSubgroup("request", "put"));
+ RespStatGet.emplace(respStatGroup->GetSubgroup("request", "get"));
+ RespStatBlock.emplace(respStatGroup->GetSubgroup("request", "block"));
+ RespStatDiscover.emplace(respStatGroup->GetSubgroup("request", "discover"));
+ RespStatRange.emplace(respStatGroup->GetSubgroup("request", "range"));
+ RespStatCollectGarbage.emplace(respStatGroup->GetSubgroup("request", "collectGarbage"));
+ RespStatStatus.emplace(respStatGroup->GetSubgroup("request", "status"));
RespStatPatch.emplace(respStatGroup->GetSubgroup("request", "patch"));
}
void TBlobStorageGroupProxyMon::BecomeFull() {
if (IsLimitedMon) {
ThroughputGroup = PercentileCounters->GetSubgroup("subsystem", "throughput");
- PutTabletLogThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putTabletLog", "bytes per second", Percentiles4));
- PutAsyncBlobThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putAsyncBlob", "bytes per second", Percentiles4));
- PutUserDataThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putUserData", "bytes per second", Percentiles4));
- PutThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "any", "bytes per second", Percentiles4));
+ PutTabletLogThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putTabletLog", "bytes per second", Percentiles4));
+ PutAsyncBlobThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putAsyncBlob", "bytes per second", Percentiles4));
+ PutUserDataThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "putUserData", "bytes per second", Percentiles4));
+ PutThroughput.reset(new TThroughputMeter(4, ThroughputGroup, "event", "any", "bytes per second", Percentiles4));
PutResponseTime.Initialize(ResponseGroup, "event", "put", "Response in millisec", Percentiles4);
@@ -135,45 +135,45 @@ void TBlobStorageGroupProxyMon::BecomeFull() {
IsLimitedMon = false;
}
-void TBlobStorageGroupProxyMon::SerializeToWhiteboard(NKikimrWhiteboard::TBSGroupStateInfo& pb, ui32 groupId) const {
- NKikimrWhiteboard::EFlag flag = NKikimrWhiteboard::EFlag::Green;
-
+void TBlobStorageGroupProxyMon::SerializeToWhiteboard(NKikimrWhiteboard::TBSGroupStateInfo& pb, ui32 groupId) const {
+ NKikimrWhiteboard::EFlag flag = NKikimrWhiteboard::EFlag::Green;
+
auto calculate = [&flag](const auto& tracker) {
- for (const auto& x : tracker.Percentiles) {
- const float percentile = x.first;
- const ui32 milliseconds = *x.second;
- if (percentile <= 0.95) {
- if (milliseconds >= 2000 && flag < NKikimrWhiteboard::EFlag::Red) {
- flag = NKikimrWhiteboard::EFlag::Red;
- } else if (milliseconds >= 1000 && flag < NKikimrWhiteboard::EFlag::Orange) {
- flag = NKikimrWhiteboard::EFlag::Orange;
- } else if (milliseconds >= 500 && flag < NKikimrWhiteboard::EFlag::Yellow) {
- flag = NKikimrWhiteboard::EFlag::Yellow;
- }
- }
- }
- };
-
+ for (const auto& x : tracker.Percentiles) {
+ const float percentile = x.first;
+ const ui32 milliseconds = *x.second;
+ if (percentile <= 0.95) {
+ if (milliseconds >= 2000 && flag < NKikimrWhiteboard::EFlag::Red) {
+ flag = NKikimrWhiteboard::EFlag::Red;
+ } else if (milliseconds >= 1000 && flag < NKikimrWhiteboard::EFlag::Orange) {
+ flag = NKikimrWhiteboard::EFlag::Orange;
+ } else if (milliseconds >= 500 && flag < NKikimrWhiteboard::EFlag::Yellow) {
+ flag = NKikimrWhiteboard::EFlag::Yellow;
+ }
+ }
+ }
+ };
+
if (!IsLimitedMon) {
calculate(PutResponseTime);
calculate(GetResponseTime);
}
- pb.SetGroupID(groupId);
+ pb.SetGroupID(groupId);
pb.SetLatency(flag);
-}
-
-bool TBlobStorageGroupProxyMon::GetGroupIdGen(ui32 *groupId, ui32 *groupGen) const {
+}
+
+bool TBlobStorageGroupProxyMon::GetGroupIdGen(ui32 *groupId, ui32 *groupGen) const {
ui64 value = GroupIdGen;
if (value != Max<ui64>()) {
const ui64 mask = Max<ui32>();
- *groupId = (value >> 32) & mask;
- *groupGen = value & mask;
- return true;
- } else {
- return false;
- }
-}
-
+ *groupId = (value >> 32) & mask;
+ *groupGen = value & mask;
+ return true;
+ } else {
+ return false;
+ }
+}
+
void TBlobStorageGroupProxyMon::Update() {
if (!IsLimitedMon) {
PutResponseTime.Update();
@@ -199,7 +199,7 @@ void TBlobStorageGroupProxyMon::Update() {
void TBlobStorageGroupProxyMon::ThroughputUpdate() {
if (!IsLimitedMon) {
for (auto *sensor : {&PutTabletLogThroughput, &PutAsyncBlobThroughput, &PutUserDataThroughput, &PutThroughput}) {
- sensor->get()->UpdateHistogram();
+ sensor->get()->UpdateHistogram();
}
}
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_mon.h b/ydb/core/blobstorage/dsproxy/dsproxy_mon.h
index 941bea6664a..9d3a3d9a378 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_mon.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_mon.h
@@ -1,10 +1,10 @@
#pragma once
-
+
#include "defs.h"
#include "dsproxy_nodemon.h"
-#include "dsproxy_timestats.h"
-
+#include "dsproxy_timestats.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/storagepoolmon/storagepool_counters.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
@@ -20,37 +20,37 @@ namespace NKikimr {
// BlobStorageProxy monitoring counters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-enum class ERequestType {
- Get,
- Put,
- Discover,
- Range,
+enum class ERequestType {
+ Get,
+ Put,
+ Discover,
+ Range,
Patch,
-};
-
-struct TRequestMonGroup {
- NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsIssued;
- NMonitoring::TDynamicCounters::TCounterPtr VGetRangesIssued;
- NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithData;
- NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithNoData;
- NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithErrors;
- NMonitoring::TDynamicCounters::TCounterPtr VPutBlobsIssued;
+};
+
+struct TRequestMonGroup {
+ NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsIssued;
+ NMonitoring::TDynamicCounters::TCounterPtr VGetRangesIssued;
+ NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithData;
+ NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithNoData;
+ NMonitoring::TDynamicCounters::TCounterPtr VGetBlobsReturnedWithErrors;
+ NMonitoring::TDynamicCounters::TCounterPtr VPutBlobsIssued;
NMonitoring::TDynamicCounters::TCounterPtr VMovedPatchBlobsIssued;
-
- void Init(const TIntrusivePtr<NMonitoring::TDynamicCounters> &group) {
- VGetBlobsIssued = group->GetCounter("VGetBlobsIssued", true);
- VGetRangesIssued = group->GetCounter("VGetRangesIssued", true);
- VGetBlobsReturnedWithData = group->GetCounter("VGetBlobsReturnedWithData", true);
- VGetBlobsReturnedWithNoData = group->GetCounter("VGetBlobsReturnedWithNoData", true);
- VGetBlobsReturnedWithErrors = group->GetCounter("VGetBlobsReturnedWithErrors", true);
- VPutBlobsIssued = group->GetCounter("VPutBlobsIssued", true);
+
+ void Init(const TIntrusivePtr<NMonitoring::TDynamicCounters> &group) {
+ VGetBlobsIssued = group->GetCounter("VGetBlobsIssued", true);
+ VGetRangesIssued = group->GetCounter("VGetRangesIssued", true);
+ VGetBlobsReturnedWithData = group->GetCounter("VGetBlobsReturnedWithData", true);
+ VGetBlobsReturnedWithNoData = group->GetCounter("VGetBlobsReturnedWithNoData", true);
+ VGetBlobsReturnedWithErrors = group->GetCounter("VGetBlobsReturnedWithErrors", true);
+ VPutBlobsIssued = group->GetCounter("VPutBlobsIssued", true);
VMovedPatchBlobsIssued = group->GetCounter("VMovedPatchBlobsIssued", true);
- }
-
- void CountEvent(const TEvBlobStorage::TEvVPut& /*ev*/) {
- VPutBlobsIssued->Inc();
- }
-
+ }
+
+ void CountEvent(const TEvBlobStorage::TEvVPut& /*ev*/) {
+ VPutBlobsIssued->Inc();
+ }
+
void CountEvent(const TEvBlobStorage::TEvVMultiPut& ev) {
*VPutBlobsIssued += ev.Record.ItemsSize();
}
@@ -65,78 +65,78 @@ struct TRequestMonGroup {
void CountEvent(const TEvBlobStorage::TEvVPatchDiff& /*ev*/) {
}
- void CountEvent(const TEvBlobStorage::TEvVGet &ev) {
- *VGetBlobsIssued += ev.Record.ExtremeQueriesSize();
- if (ev.Record.HasRangeQuery()) {
- VGetRangesIssued->Inc();
- }
- }
-
- void CountEvent(const TEvBlobStorage::TEvVGetResult &ev) {
- if (ev.Record.GetStatus() != NKikimrProto::OK) {
- *VGetBlobsReturnedWithErrors += ev.Record.ResultSize();
- } else {
- for (const NKikimrBlobStorage::TQueryResult &result : ev.Record.GetResult()) {
- switch (result.GetStatus()) {
- case NKikimrProto::OK:
- ++*VGetBlobsReturnedWithData;
- break;
-
- case NKikimrProto::NODATA:
- case NKikimrProto::NOT_YET:
- ++*VGetBlobsReturnedWithNoData;
- break;
-
- default:
- ++*VGetBlobsReturnedWithErrors;
- break;
- }
- }
- }
- }
-};
-
-struct TResponseStatusGroup : TThrRefBase {
-#define ENUM_STATUS(XX) \
- XX(OK) \
- XX(ERROR) \
- XX(DEADLINE) \
- XX(RACE) \
- XX(BLOCKED) \
- XX(ALREADY) \
- XX(NODATA) \
- // END
-
-#define XX(NAME) NMonitoring::TDynamicCounters::TCounterPtr Num##NAME;
- ENUM_STATUS(XX)
-#undef XX
-
- TResponseStatusGroup(const NMonitoring::TDynamicCounterPtr& group)
- : TThrRefBase()
-#define XX(NAME) , Num##NAME(group->GetCounter(#NAME, true))
- ENUM_STATUS(XX)
-#undef XX
- {}
-
- void Account(NKikimrProto::EReplyStatus status) {
- switch (status) {
-#define XX(NAME) \
- case NKikimrProto::NAME: \
- ++*Num##NAME; \
- break;
- ENUM_STATUS(XX)
-#undef XX
- default:
- Y_FAIL("unexpected Status# %s", NKikimrProto::EReplyStatus_Name(status).data());
- }
- }
-#undef ENUM_STATUS
-};
-
+ void CountEvent(const TEvBlobStorage::TEvVGet &ev) {
+ *VGetBlobsIssued += ev.Record.ExtremeQueriesSize();
+ if (ev.Record.HasRangeQuery()) {
+ VGetRangesIssued->Inc();
+ }
+ }
+
+ void CountEvent(const TEvBlobStorage::TEvVGetResult &ev) {
+ if (ev.Record.GetStatus() != NKikimrProto::OK) {
+ *VGetBlobsReturnedWithErrors += ev.Record.ResultSize();
+ } else {
+ for (const NKikimrBlobStorage::TQueryResult &result : ev.Record.GetResult()) {
+ switch (result.GetStatus()) {
+ case NKikimrProto::OK:
+ ++*VGetBlobsReturnedWithData;
+ break;
+
+ case NKikimrProto::NODATA:
+ case NKikimrProto::NOT_YET:
+ ++*VGetBlobsReturnedWithNoData;
+ break;
+
+ default:
+ ++*VGetBlobsReturnedWithErrors;
+ break;
+ }
+ }
+ }
+ }
+};
+
+struct TResponseStatusGroup : TThrRefBase {
+#define ENUM_STATUS(XX) \
+ XX(OK) \
+ XX(ERROR) \
+ XX(DEADLINE) \
+ XX(RACE) \
+ XX(BLOCKED) \
+ XX(ALREADY) \
+ XX(NODATA) \
+ // END
+
+#define XX(NAME) NMonitoring::TDynamicCounters::TCounterPtr Num##NAME;
+ ENUM_STATUS(XX)
+#undef XX
+
+ TResponseStatusGroup(const NMonitoring::TDynamicCounterPtr& group)
+ : TThrRefBase()
+#define XX(NAME) , Num##NAME(group->GetCounter(#NAME, true))
+ ENUM_STATUS(XX)
+#undef XX
+ {}
+
+ void Account(NKikimrProto::EReplyStatus status) {
+ switch (status) {
+#define XX(NAME) \
+ case NKikimrProto::NAME: \
+ ++*Num##NAME; \
+ break;
+ ENUM_STATUS(XX)
+#undef XX
+ default:
+ Y_FAIL("unexpected Status# %s", NKikimrProto::EReplyStatus_Name(status).data());
+ }
+ }
+#undef ENUM_STATUS
+};
+
class TBlobStorageGroupProxyMon : public TThrRefBase {
-public:
- TIntrusivePtr<TDsProxyNodeMon> NodeMon;
-
+public:
+ TIntrusivePtr<TDsProxyNodeMon> NodeMon;
+
protected:
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
TIntrusivePtr<NMonitoring::TDynamicCounters> PercentileCounters;
@@ -144,14 +144,14 @@ protected:
ui64 GroupIdGen = Max<ui64>(); // group id:group gen
std::atomic<bool> IsLimitedMon = ATOMIC_VAR_INIT(true);
- TIntrusivePtr<NMonitoring::TDynamicCounters> ThroughputGroup;
- std::unique_ptr<TThroughputMeter> PutTabletLogThroughput;
- std::unique_ptr<TThroughputMeter> PutAsyncBlobThroughput;
- std::unique_ptr<TThroughputMeter> PutUserDataThroughput;
- std::unique_ptr<TThroughputMeter> PutThroughput;
-
+ TIntrusivePtr<NMonitoring::TDynamicCounters> ThroughputGroup;
+ std::unique_ptr<TThroughputMeter> PutTabletLogThroughput;
+ std::unique_ptr<TThroughputMeter> PutAsyncBlobThroughput;
+ std::unique_ptr<TThroughputMeter> PutUserDataThroughput;
+ std::unique_ptr<TThroughputMeter> PutThroughput;
+
TIntrusivePtr<NMonitoring::TDynamicCounters> LatencyOverviewGroup;
-
+
// log response time
NMonitoring::TPercentileTrackerLg<3, 4, 3> PutResponseTime; // Used by whiteboard
@@ -174,7 +174,7 @@ protected:
// event counters
TIntrusivePtr<NMonitoring::TDynamicCounters> EventGroup;
NMonitoring::TDynamicCounters::TCounterPtr EventPut;
- NMonitoring::TDynamicCounters::TCounterPtr EventPutBytes;
+ NMonitoring::TDynamicCounters::TCounterPtr EventPutBytes;
NMonitoring::TDynamicCounters::TCounterPtr EventGetResBytes;
TMap<ui32, NMonitoring::TDynamicCounters::TCounterPtr> EventPutBytesBuckets;
@@ -216,74 +216,74 @@ public:
NMonitoring::TDynamicCounters::TCounterPtr PutsSentViaPutBatching;
NMonitoring::TDynamicCounters::TCounterPtr PutBatchesSent;
- // active event counters
- TIntrusivePtr<NMonitoring::TDynamicCounters> ActiveRequestsGroup;
- NMonitoring::TDynamicCounters::TCounterPtr ActivePut;
+ // active event counters
+ TIntrusivePtr<NMonitoring::TDynamicCounters> ActiveRequestsGroup;
+ NMonitoring::TDynamicCounters::TCounterPtr ActivePut;
NMonitoring::TDynamicCounters::TCounterPtr ActivePutCapacity;
- NMonitoring::TDynamicCounters::TCounterPtr ActiveGet;
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveGet;
NMonitoring::TDynamicCounters::TCounterPtr ActiveGetCapacity;
- NMonitoring::TDynamicCounters::TCounterPtr ActiveBlock;
- NMonitoring::TDynamicCounters::TCounterPtr ActiveDiscover;
- NMonitoring::TDynamicCounters::TCounterPtr ActiveRange;
- NMonitoring::TDynamicCounters::TCounterPtr ActiveCollectGarbage;
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveBlock;
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveDiscover;
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveRange;
+ NMonitoring::TDynamicCounters::TCounterPtr ActiveCollectGarbage;
NMonitoring::TDynamicCounters::TCounterPtr ActiveMultiGet;
NMonitoring::TDynamicCounters::TCounterPtr ActiveIndexRestoreGet;
NMonitoring::TDynamicCounters::TCounterPtr ActiveMultiCollect;
NMonitoring::TDynamicCounters::TCounterPtr ActiveStatus;
NMonitoring::TDynamicCounters::TCounterPtr ActivePatch;
-
- std::optional<TResponseStatusGroup> RespStatPut;
- std::optional<TResponseStatusGroup> RespStatGet;
- std::optional<TResponseStatusGroup> RespStatBlock;
- std::optional<TResponseStatusGroup> RespStatDiscover;
- std::optional<TResponseStatusGroup> RespStatRange;
- std::optional<TResponseStatusGroup> RespStatCollectGarbage;
- std::optional<TResponseStatusGroup> RespStatStatus;
+
+ std::optional<TResponseStatusGroup> RespStatPut;
+ std::optional<TResponseStatusGroup> RespStatGet;
+ std::optional<TResponseStatusGroup> RespStatBlock;
+ std::optional<TResponseStatusGroup> RespStatDiscover;
+ std::optional<TResponseStatusGroup> RespStatRange;
+ std::optional<TResponseStatusGroup> RespStatCollectGarbage;
+ std::optional<TResponseStatusGroup> RespStatStatus;
std::optional<TResponseStatusGroup> RespStatPatch;
-
+
// special patch counters
NMonitoring::TDynamicCounters::TCounterPtr VPatchContinueFailed;
NMonitoring::TDynamicCounters::TCounterPtr VPatchPartPlacementVerifyFailed;
NMonitoring::TDynamicCounters::TCounterPtr PatchesWithFallback;
- TRequestMonGroup& GetRequestMonGroup(ERequestType request) {
- switch (request) {
- case ERequestType::Get: return GetGroup;
- case ERequestType::Put: return PutGroup;
- case ERequestType::Discover: return DiscoverGroup;
- case ERequestType::Range: return RangeGroup;
+ TRequestMonGroup& GetRequestMonGroup(ERequestType request) {
+ switch (request) {
+ case ERequestType::Get: return GetGroup;
+ case ERequestType::Put: return PutGroup;
+ case ERequestType::Discover: return DiscoverGroup;
+ case ERequestType::Range: return RangeGroup;
case ERequestType::Patch: return PatchGroup;
- }
- Y_FAIL();
- }
-
- template<typename T>
- void CountEvent(ERequestType request, const T &ev) {
- GetRequestMonGroup(request).CountEvent(ev);
- }
-
-
- TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
- const TIntrusivePtr<NMonitoring::TDynamicCounters>& percentileCounters,
+ }
+ Y_FAIL();
+ }
+
+ template<typename T>
+ void CountEvent(ERequestType request, const T &ev) {
+ GetRequestMonGroup(request).CountEvent(ev);
+ }
+
+
+ TBlobStorageGroupProxyMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+ const TIntrusivePtr<NMonitoring::TDynamicCounters>& percentileCounters,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& overviewCounters,
const TIntrusivePtr<TBlobStorageGroupInfo>& info,
const TIntrusivePtr<TDsProxyNodeMon> &nodeMon,
bool isLimitedMon);
-
- bool GetGroupIdGen(ui32 *groupId, ui32 *groupGen) const;
-
+
+ bool GetGroupIdGen(ui32 *groupId, ui32 *groupGen) const;
+
void BecomeFull();
- void SerializeToWhiteboard(NKikimrWhiteboard::TBSGroupStateInfo& pb, ui32 groupId) const;
-
- void CountPutEvent(ui32 size) {
- ++*EventPut;
- *EventPutBytes += size;
- auto bucketIt = EventPutBytesBuckets.upper_bound(size);
+ void SerializeToWhiteboard(NKikimrWhiteboard::TBSGroupStateInfo& pb, ui32 groupId) const;
+
+ void CountPutEvent(ui32 size) {
+ ++*EventPut;
+ *EventPutBytes += size;
+ auto bucketIt = EventPutBytesBuckets.upper_bound(size);
Y_VERIFY(bucketIt != EventPutBytesBuckets.begin());
- ++*std::prev(bucketIt)->second;
- }
-
+ ++*std::prev(bucketIt)->second;
+ }
+
void CountThroughput(NKikimrBlobStorage::EPutHandleClass cls, ui32 size) {
switch (cls) {
case NKikimrBlobStorage::EPutHandleClass::TabletLog:
@@ -301,28 +301,28 @@ public:
void CountPutPesponseTime(TPDiskCategory::EDeviceType type, NKikimrBlobStorage::EPutHandleClass cls, ui32 size,
TDuration duration) {
- const ui32 durationMs = duration.MilliSeconds();
- PutResponseTime.Increment(durationMs);
- switch (cls) {
- case NKikimrBlobStorage::EPutHandleClass::TabletLog:
+ const ui32 durationMs = duration.MilliSeconds();
+ PutResponseTime.Increment(durationMs);
+ switch (cls) {
+ case NKikimrBlobStorage::EPutHandleClass::TabletLog:
PutTabletLogResponseTime.Increment(durationMs);
- if (size < (256 << 10)) {
- PutTabletLogResponseTime256.Increment(durationMs);
- } else if (size < (512 << 10)) {
- PutTabletLogResponseTime512.Increment(durationMs);
- }
- break;
- case NKikimrBlobStorage::EPutHandleClass::AsyncBlob:
- PutAsyncBlobResponseTime.Increment(durationMs);
- break;
- case NKikimrBlobStorage::EPutHandleClass::UserData:
- PutUserDataResponseTime.Increment(durationMs);
- break;
- default:
- Y_FAIL("Unexpected case, HandleClass# %" PRIu64, (ui64)cls);
- }
+ if (size < (256 << 10)) {
+ PutTabletLogResponseTime256.Increment(durationMs);
+ } else if (size < (512 << 10)) {
+ PutTabletLogResponseTime512.Increment(durationMs);
+ }
+ break;
+ case NKikimrBlobStorage::EPutHandleClass::AsyncBlob:
+ PutAsyncBlobResponseTime.Increment(durationMs);
+ break;
+ case NKikimrBlobStorage::EPutHandleClass::UserData:
+ PutUserDataResponseTime.Increment(durationMs);
+ break;
+ default:
+ Y_FAIL("Unexpected case, HandleClass# %" PRIu64, (ui64)cls);
+ }
NodeMon->CountPutPesponseTime(type, cls, size, duration);
- }
+ }
void CountGetResponseTime(TPDiskCategory::EDeviceType type, NKikimrBlobStorage::EGetHandleClass cls, ui32 size,
TDuration duration) {
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_monactor.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_monactor.cpp
index 96b492c415a..98610d99a77 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_monactor.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_monactor.cpp
@@ -1,5 +1,5 @@
-#include "dsproxy_monactor.h"
-#include "dsproxy_mon.h"
+#include "dsproxy_monactor.h"
+#include "dsproxy_mon.h"
#include "dsproxy.h"
#include <ydb/core/base/appdata.h>
@@ -9,247 +9,247 @@
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/mon.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/monlib/service/pages/templates.h>
namespace NKikimr {
-struct TEvThroughputUpdate : public TEventLocal<TEvThroughputUpdate, TEvBlobStorage::EvThroughputUpdate> {
-};
-
-class TMonQueryProcessor : public TActorBootstrapped<TMonQueryProcessor> {
+struct TEvThroughputUpdate : public TEventLocal<TEvThroughputUpdate, TEvBlobStorage::EvThroughputUpdate> {
+};
+
+class TMonQueryProcessor : public TActorBootstrapped<TMonQueryProcessor> {
TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
- TIntrusivePtr<TGroupQueues> GroupQueues;
- const ui32 GroupId;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- NMon::TEvHttpInfo::TPtr Ev;
- std::vector<TString> Urls;
- ui32 PendingReplyCount = 0;
-
+ TIntrusivePtr<TGroupQueues> GroupQueues;
+ const ui32 GroupId;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ NMon::TEvHttpInfo::TPtr Ev;
+ std::vector<TString> Urls;
+ ui32 PendingReplyCount = 0;
+
public:
- TMonQueryProcessor(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TIntrusivePtr<TGroupQueues> groupQueues,
- ui32 groupId, TIntrusivePtr<TBlobStorageGroupInfo> info, NMon::TEvHttpInfo::TPtr ev)
- : Mon(std::move(mon))
- , GroupQueues(std::move(groupQueues))
+ TMonQueryProcessor(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, TIntrusivePtr<TGroupQueues> groupQueues,
+ ui32 groupId, TIntrusivePtr<TBlobStorageGroupInfo> info, NMon::TEvHttpInfo::TPtr ev)
+ : Mon(std::move(mon))
+ , GroupQueues(std::move(groupQueues))
, GroupId(groupId)
- , Info(std::move(info))
- , Ev(ev)
+ , Info(std::move(info))
+ , Ev(ev)
{}
- void Bootstrap() {
- if (Info) {
- const TInstant deadline = TActivationContext::Now() + TDuration::Seconds(5);
- const TString pagePath(Ev->Get()->Request.GetPath());
-
- Urls.resize(Info->GetTotalVDisksNum());
- for (ui32 i = 0; i < Urls.size(); ++i) {
- const TActorId& serviceId = Info->GetActorId(i);
- ui32 nodeId, pdiskId, vslotId;
- std::tie(nodeId, pdiskId, vslotId) = DecomposeVDiskServiceId(serviceId);
- const TString path = Sprintf("actors/vdisks/vdisk%09" PRIu32 "_%09" PRIu32, pdiskId, vslotId);
- Send(NCrossRef::MakeCrossRefActorId(), new NCrossRef::TEvGenerateCrossRef(pagePath, nodeId, path, deadline), 0, i);
- ++PendingReplyCount;
- }
- }
- Become(&TThis::StateFunc);
- if (!PendingReplyCount) {
- GenerateResponse();
- }
- }
-
- void Handle(NCrossRef::TEvCrossRef::TPtr ev) {
- Urls[ev->Cookie] = ev->Get()->Url;
- if (!--PendingReplyCount) {
- GenerateResponse();
+ void Bootstrap() {
+ if (Info) {
+ const TInstant deadline = TActivationContext::Now() + TDuration::Seconds(5);
+ const TString pagePath(Ev->Get()->Request.GetPath());
+
+ Urls.resize(Info->GetTotalVDisksNum());
+ for (ui32 i = 0; i < Urls.size(); ++i) {
+ const TActorId& serviceId = Info->GetActorId(i);
+ ui32 nodeId, pdiskId, vslotId;
+ std::tie(nodeId, pdiskId, vslotId) = DecomposeVDiskServiceId(serviceId);
+ const TString path = Sprintf("actors/vdisks/vdisk%09" PRIu32 "_%09" PRIu32, pdiskId, vslotId);
+ Send(NCrossRef::MakeCrossRefActorId(), new NCrossRef::TEvGenerateCrossRef(pagePath, nodeId, path, deadline), 0, i);
+ ++PendingReplyCount;
+ }
+ }
+ Become(&TThis::StateFunc);
+ if (!PendingReplyCount) {
+ GenerateResponse();
}
}
- void GenerateResponse() {
- const TCgiParameters& cgi = Ev->Get()->Request.GetParams();
- if (cgi.Has("submit_timestats")) {
- Mon->TimeStats.Submit(cgi);
- }
-#define UPDATE_WILSON(NAME) \
- if (cgi.Has(#NAME "SamplingRate")) { \
+ void Handle(NCrossRef::TEvCrossRef::TPtr ev) {
+ Urls[ev->Cookie] = ev->Get()->Url;
+ if (!--PendingReplyCount) {
+ GenerateResponse();
+ }
+ }
+
+ void GenerateResponse() {
+ const TCgiParameters& cgi = Ev->Get()->Request.GetParams();
+ if (cgi.Has("submit_timestats")) {
+ Mon->TimeStats.Submit(cgi);
+ }
+#define UPDATE_WILSON(NAME) \
+ if (cgi.Has(#NAME "SamplingRate")) { \
const TString& item = cgi.Get(#NAME "SamplingRate"); \
- ui64 value; \
- if (TryFromString(item, value) && value <= 1000000) { \
- AtomicSet(Mon->NAME ## SamplePPM, value); \
- } \
- }
- UPDATE_WILSON(Get)
- UPDATE_WILSON(Put)
- UPDATE_WILSON(Discover)
-
-#define COMPONENT(NAME) \
+ ui64 value; \
+ if (TryFromString(item, value) && value <= 1000000) { \
+ AtomicSet(Mon->NAME ## SamplePPM, value); \
+ } \
+ }
+ UPDATE_WILSON(Get)
+ UPDATE_WILSON(Put)
+ UPDATE_WILSON(Discover)
+
+#define COMPONENT(NAME) \
TABLER() { \
TABLED() { \
- str << #NAME; \
+ str << #NAME; \
} \
TABLED() { \
TString value = ToString(Mon->NAME ## SamplePPM); \
- str << "<input name=\"" #NAME "SamplingRate\" type=\"number\"" \
- " value=\"" << value << "\" min=\"0\" max=\"1000000\"/>ppm"; \
+ str << "<input name=\"" #NAME "SamplingRate\" type=\"number\"" \
+ " value=\"" << value << "\" min=\"0\" max=\"1000000\"/>ppm"; \
} \
}
-
+
TStringStream str;
-
+
HTML(str) {
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
- str << "Group content";
- }
- DIV_CLASS("panel-body") {
- if (Info) {
- const auto& top = Info->GetTopology();
- DIV() {
- str << "GroupID: " << Info->GroupID << "<br/>" << "Generation: " << Info->GroupGeneration;
- }
- DIV() TABLE_CLASS("table table-bordered table-condensed") TABLEBODY() {
- ui32 maxFailDomain = 0;
- for (const auto& realm : top.FailRealms) {
- maxFailDomain = Max<ui32>(maxFailDomain, realm.FailDomains.size());
- }
- for (ui32 i = 0; i < maxFailDomain; ++i) {
- TABLER() {
- for (const auto& realm : top.FailRealms) {
- TABLED() {
- if (i < realm.FailDomains.size()) {
- const auto& domain = realm.FailDomains[i];
- bool first = true;
- for (const auto& vdisk : domain.VDisks) {
- if (first) {
- first = false;
- } else {
- str << "<br/>";
- }
-
- const TVDiskID vdiskId = Info->GetVDiskId(vdisk.VDiskIdShort);
- if (const auto& url = Urls[vdisk.OrderNumber]) {
- str << "<a href=\"" << url << "\">" << vdiskId << "</a>";
- } else {
- str << vdiskId;
- }
- }
- }
- }
- }
- }
- }
- }
- DIV() {
- TString mode = "<strong>incorrect</strong>";
- switch (Info->GetEncryptionMode()) {
- case TBlobStorageGroupInfo::EEM_NONE:
- mode = "no encryption";
- break;
- case TBlobStorageGroupInfo::EEM_ENC_V1:
- mode = "v1 (at proxy level, no MAC, no CRC)";
- break;
- }
- str << "EncryptionMode: " << mode;
-
- if (Info->GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
- str << "<br/>LifeCyclePhase: " << Info->GetLifeCyclePhase();
- }
- }
- }
- }
- }
-
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Blob query service";
+ str << "Group content";
+ }
+ DIV_CLASS("panel-body") {
+ if (Info) {
+ const auto& top = Info->GetTopology();
+ DIV() {
+ str << "GroupID: " << Info->GroupID << "<br/>" << "Generation: " << Info->GroupGeneration;
+ }
+ DIV() TABLE_CLASS("table table-bordered table-condensed") TABLEBODY() {
+ ui32 maxFailDomain = 0;
+ for (const auto& realm : top.FailRealms) {
+ maxFailDomain = Max<ui32>(maxFailDomain, realm.FailDomains.size());
+ }
+ for (ui32 i = 0; i < maxFailDomain; ++i) {
+ TABLER() {
+ for (const auto& realm : top.FailRealms) {
+ TABLED() {
+ if (i < realm.FailDomains.size()) {
+ const auto& domain = realm.FailDomains[i];
+ bool first = true;
+ for (const auto& vdisk : domain.VDisks) {
+ if (first) {
+ first = false;
+ } else {
+ str << "<br/>";
+ }
+
+ const TVDiskID vdiskId = Info->GetVDiskId(vdisk.VDiskIdShort);
+ if (const auto& url = Urls[vdisk.OrderNumber]) {
+ str << "<a href=\"" << url << "\">" << vdiskId << "</a>";
+ } else {
+ str << vdiskId;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ DIV() {
+ TString mode = "<strong>incorrect</strong>";
+ switch (Info->GetEncryptionMode()) {
+ case TBlobStorageGroupInfo::EEM_NONE:
+ mode = "no encryption";
+ break;
+ case TBlobStorageGroupInfo::EEM_ENC_V1:
+ mode = "v1 (at proxy level, no MAC, no CRC)";
+ break;
+ }
+ str << "EncryptionMode: " << mode;
+
+ if (Info->GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
+ str << "<br/>LifeCyclePhase: " << Info->GetLifeCyclePhase();
+ }
+ }
+ }
+ }
+ }
+
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Blob query service";
}
DIV_CLASS("panel-body") {
FORM_CLASS("form-horizontal") {
DIV_CLASS("control-group") {
LABEL_CLASS_FOR("control-label", "inputBlob") { str << "Blob ID"; }
DIV_CLASS("controls") {
- str << "<input id=\"inputBlob\" name=\"blob\" type=\"text\"/>";
+ str << "<input id=\"inputBlob\" name=\"blob\" type=\"text\"/>";
}
}
- str << "<input type=\"hidden\" name=\"groupId\" value=\"" << GroupId << "\">";
- str << "<input type=\"hidden\" name=\"debugInfo\" value=\"" << 1 << "\">";
+ str << "<input type=\"hidden\" name=\"groupId\" value=\"" << GroupId << "\">";
+ str << "<input type=\"hidden\" name=\"debugInfo\" value=\"" << 1 << "\">";
DIV_CLASS("control-group") {
DIV_CLASS("controls") {
- str << "<button type=\"submit\" formaction=\"/get_blob\" class=\"btn btn-default\">Query</button>";
+ str << "<button type=\"submit\" formaction=\"/get_blob\" class=\"btn btn-default\">Query</button>";
}
}
}
}
}
-
+
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
- str << "Blob range index query service";
- }
- DIV_CLASS("panel-body") {
- FORM_CLASS("form-horizontal") {
- DIV_CLASS("control-group") {
- LABEL_CLASS_FOR("control-label", "tabletId") { str << "Tablet ID"; }
- DIV_CLASS("controls") {
- str << "<input id=\"tabletId\" name=\"tabletId\" type=\"integer\"/>";
- }
- }
- DIV_CLASS("control-group") {
- LABEL_CLASS_FOR("control-label", "from") { str << "From ID"; }
- DIV_CLASS("controls") {
- str << "<input id=\"from\" name=\"from\" type=\"text\"/>";
- }
- }
- DIV_CLASS("control-group") {
- LABEL_CLASS_FOR("control-label", "to") { str << "To ID"; }
- DIV_CLASS("controls") {
- str << "<input id=\"to\" name=\"to\" type=\"text\"/>";
- }
- }
- str << "<input type=\"hidden\" name=\"groupId\" value=\"" << GroupId << "\">";
- DIV_CLASS("control-group") {
- DIV_CLASS("controls") {
- str << "<button type=\"submit\" formaction=\"/blob_range\" class=\"btn btn-default\">Query</button>";
- }
- }
- }
- }
- }
-
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Wilson tuning";
+ str << "Blob range index query service";
+ }
+ DIV_CLASS("panel-body") {
+ FORM_CLASS("form-horizontal") {
+ DIV_CLASS("control-group") {
+ LABEL_CLASS_FOR("control-label", "tabletId") { str << "Tablet ID"; }
+ DIV_CLASS("controls") {
+ str << "<input id=\"tabletId\" name=\"tabletId\" type=\"integer\"/>";
+ }
+ }
+ DIV_CLASS("control-group") {
+ LABEL_CLASS_FOR("control-label", "from") { str << "From ID"; }
+ DIV_CLASS("controls") {
+ str << "<input id=\"from\" name=\"from\" type=\"text\"/>";
+ }
+ }
+ DIV_CLASS("control-group") {
+ LABEL_CLASS_FOR("control-label", "to") { str << "To ID"; }
+ DIV_CLASS("controls") {
+ str << "<input id=\"to\" name=\"to\" type=\"text\"/>";
+ }
+ }
+ str << "<input type=\"hidden\" name=\"groupId\" value=\"" << GroupId << "\">";
+ DIV_CLASS("control-group") {
+ DIV_CLASS("controls") {
+ str << "<button type=\"submit\" formaction=\"/blob_range\" class=\"btn btn-default\">Query</button>";
+ }
+ }
+ }
+ }
+ }
+
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Wilson tuning";
}
DIV_CLASS("panel-body") {
FORM_CLASS("form-vertical") {
DIV() {
- str << "All sampling rates are provided as integer in range [0, 1000000] measured in ppm "
- " where 0 means disabled sampling for this kind of request";
+ str << "All sampling rates are provided as integer in range [0, 1000000] measured in ppm "
+ " where 0 means disabled sampling for this kind of request";
}
DIV() {
- str << "<b>NOTE</b> do not forget to enable WILSON logger at DEBUG level with 100% sampling"
- " at all nodes of the cluster";
+ str << "<b>NOTE</b> do not forget to enable WILSON logger at DEBUG level with 100% sampling"
+ " at all nodes of the cluster";
}
TABLE_CLASS ("table table-condensed") {
TABLEHEAD() {
TABLER() {
TABLEH() {
- str << "Query type";
+ str << "Query type";
}
TABLEH() {
- str << "Sampling rate";
+ str << "Sampling rate";
}
}
}
TABLEBODY() {
- COMPONENT(Put)
- COMPONENT(Get)
- COMPONENT(Discover)
+ COMPONENT(Put)
+ COMPONENT(Get)
+ COMPONENT(Discover)
}
}
DIV_CLASS("control-group") {
DIV_CLASS("controls") {
- str << "<button type=\"submit\" class=\"btn btn-default\">Commit</button>";
+ str << "<button type=\"submit\" class=\"btn btn-default\">Commit</button>";
}
}
}
@@ -261,8 +261,8 @@ public:
str << "Queue latencies, ms";
}
DIV_CLASS("panel-body") {
- if (!GroupQueues) {
- str << "No data available, GroupQueues is nullptr.";
+ if (!GroupQueues) {
+ str << "No data available, GroupQueues is nullptr.";
} else {
TABLE_CLASS ("table table-condensed") {
TABLEHEAD() {
@@ -279,11 +279,11 @@ public:
}
}
TABLEBODY() {
- for (size_t fdIdx = 0; fdIdx < GroupQueues->FailDomains.size(); ++fdIdx) {
- const TGroupQueues::TFailDomain &failDomain = GroupQueues->FailDomains[fdIdx];
+ for (size_t fdIdx = 0; fdIdx < GroupQueues->FailDomains.size(); ++fdIdx) {
+ const TGroupQueues::TFailDomain &failDomain = GroupQueues->FailDomains[fdIdx];
for (size_t vdIdx = 0; vdIdx < failDomain.VDisks.size(); ++vdIdx) {
- const TGroupQueues::TVDisk &vDisk = failDomain.VDisks[vdIdx];
- const TGroupQueues::TVDisk::TQueues &q = vDisk.Queues;
+ const TGroupQueues::TVDisk &vDisk = failDomain.VDisks[vdIdx];
+ const TGroupQueues::TVDisk::TQueues &q = vDisk.Queues;
TABLER() {
TABLED() { str << fdIdx; }
TABLED() { str << vdIdx; }
@@ -312,137 +312,137 @@ public:
}
}
}
-
- Mon->TimeStats.Render(str);
-
- Send(Ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
- PassAway();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(NCrossRef::TEvCrossRef, Handle);
- )
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// TBlobStorageProxyMonActor
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-class TBlobStorageGroupProxyMonActor : public TActorBootstrapped<TBlobStorageGroupProxyMonActor> {
- enum {
- EvNodeWhiteboardNotify = EventSpaceBegin(TKikimrEvents::ES_PRIVATE)
- };
-
- struct TEvNodeWhiteboardNotify : public TEventLocal<TEvNodeWhiteboardNotify, EvNodeWhiteboardNotify>
- {};
-
- TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
- const ui32 GroupId;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TActorId ProxyId;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_PROXY_MON;
- }
-
- TBlobStorageGroupProxyMonActor(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId)
- : Mon(std::move(mon))
- , GroupId(groupId)
- , Info(std::move(info))
- , ProxyId(proxyId)
- {}
-
- ~TBlobStorageGroupProxyMonActor() {
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Actor handlers
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Bootstrap state
- void Bootstrap() {
- NActors::TMon* mon = AppData()->Mon;
- if (mon) {
- NMonitoring::TIndexMonPage *actorsMonPage = mon->RegisterIndexPage("actors", "Actors");
- NMonitoring::TIndexMonPage *proxiesMonPage = actorsMonPage->RegisterIndexPage(
- "blobstorageproxies", "BlobStorageProxies");
-
- TString path = Sprintf("blobstorageproxy%09" PRIu32, (ui32)GroupId);
- TString name = Sprintf("BlobStorageProxy%09" PRIu32, (ui32)GroupId);
- mon->RegisterActorPage(proxiesMonPage, path, name, false, TlsActivationContext->ExecutorThread.ActorSystem,
- SelfId());
- }
-
- Become(&TThis::StateOnline);
- Schedule(TDuration::Seconds(5), new TEvents::TEvWakeup());
- Send(SelfId(), new TEvThroughputUpdate);
- Send(SelfId(), new TEvNodeWhiteboardNotify);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // All states
- void HandleWakeup() {
- Schedule(TDuration::Seconds(5), new TEvents::TEvWakeup());
- Mon->Update();
- }
-
- void HandleThroughputUpdate() {
- Mon->ThroughputUpdate();
- Schedule(TDuration::Seconds(15), new TEvThroughputUpdate);
- }
-
- void HandleNodeWhiteboardNotify() {
- ui32 groupId, groupGen;
- if (Mon->GetGroupIdGen(&groupId, &groupGen)) {
- auto event = std::make_unique<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate>();
- Mon->SerializeToWhiteboard(event->Record, groupId);
- Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), event.release());
- }
- Schedule(TDuration::Seconds(15), new TEvNodeWhiteboardNotify);
- }
-
- void Handle(TEvThroughputAddRequest::TPtr& ev) {
- TEvThroughputAddRequest *msg = ev->Get();
- Mon->CountThroughput(msg->PutHandleClass, msg->Bytes);
- }
-
- std::deque<NMon::TEvHttpInfo::TPtr> MonQueue;
-
- void Handle(NMon::TEvHttpInfo::TPtr &ev) {
- if (MonQueue.empty()) {
- Send(ProxyId, new TEvRequestProxySessionsState);
- }
- MonQueue.push_back(ev);
- }
-
- void Handle(TEvProxySessionsState::TPtr ev) {
- for (auto& monEv : std::exchange(MonQueue, {})) {
- Register(new TMonQueryProcessor(Mon, ev->Get()->GroupQueues, GroupId, Info, monEv));
- }
+
+ Mon->TimeStats.Render(str);
+
+ Send(Ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ PassAway();
}
- void Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev) {
- Info = std::move(ev->Get()->Info);
+ STRICT_STFUNC(StateFunc,
+ hFunc(NCrossRef::TEvCrossRef, Handle);
+ )
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TBlobStorageProxyMonActor
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class TBlobStorageGroupProxyMonActor : public TActorBootstrapped<TBlobStorageGroupProxyMonActor> {
+ enum {
+ EvNodeWhiteboardNotify = EventSpaceBegin(TKikimrEvents::ES_PRIVATE)
+ };
+
+ struct TEvNodeWhiteboardNotify : public TEventLocal<TEvNodeWhiteboardNotify, EvNodeWhiteboardNotify>
+ {};
+
+ TIntrusivePtr<TBlobStorageGroupProxyMon> Mon;
+ const ui32 GroupId;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TActorId ProxyId;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_PROXY_MON;
+ }
+
+ TBlobStorageGroupProxyMonActor(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId)
+ : Mon(std::move(mon))
+ , GroupId(groupId)
+ , Info(std::move(info))
+ , ProxyId(proxyId)
+ {}
+
+ ~TBlobStorageGroupProxyMonActor() {
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Actor handlers
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Bootstrap state
+ void Bootstrap() {
+ NActors::TMon* mon = AppData()->Mon;
+ if (mon) {
+ NMonitoring::TIndexMonPage *actorsMonPage = mon->RegisterIndexPage("actors", "Actors");
+ NMonitoring::TIndexMonPage *proxiesMonPage = actorsMonPage->RegisterIndexPage(
+ "blobstorageproxies", "BlobStorageProxies");
+
+ TString path = Sprintf("blobstorageproxy%09" PRIu32, (ui32)GroupId);
+ TString name = Sprintf("BlobStorageProxy%09" PRIu32, (ui32)GroupId);
+ mon->RegisterActorPage(proxiesMonPage, path, name, false, TlsActivationContext->ExecutorThread.ActorSystem,
+ SelfId());
+ }
+
+ Become(&TThis::StateOnline);
+ Schedule(TDuration::Seconds(5), new TEvents::TEvWakeup());
+ Send(SelfId(), new TEvThroughputUpdate);
+ Send(SelfId(), new TEvNodeWhiteboardNotify);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // All states
+ void HandleWakeup() {
+ Schedule(TDuration::Seconds(5), new TEvents::TEvWakeup());
+ Mon->Update();
+ }
+
+ void HandleThroughputUpdate() {
+ Mon->ThroughputUpdate();
+ Schedule(TDuration::Seconds(15), new TEvThroughputUpdate);
+ }
+
+ void HandleNodeWhiteboardNotify() {
+ ui32 groupId, groupGen;
+ if (Mon->GetGroupIdGen(&groupId, &groupGen)) {
+ auto event = std::make_unique<NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate>();
+ Mon->SerializeToWhiteboard(event->Record, groupId);
+ Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), event.release());
+ }
+ Schedule(TDuration::Seconds(15), new TEvNodeWhiteboardNotify);
+ }
+
+ void Handle(TEvThroughputAddRequest::TPtr& ev) {
+ TEvThroughputAddRequest *msg = ev->Get();
+ Mon->CountThroughput(msg->PutHandleClass, msg->Bytes);
+ }
+
+ std::deque<NMon::TEvHttpInfo::TPtr> MonQueue;
+
+ void Handle(NMon::TEvHttpInfo::TPtr &ev) {
+ if (MonQueue.empty()) {
+ Send(ProxyId, new TEvRequestProxySessionsState);
+ }
+ MonQueue.push_back(ev);
+ }
+
+ void Handle(TEvProxySessionsState::TPtr ev) {
+ for (auto& monEv : std::exchange(MonQueue, {})) {
+ Register(new TMonQueryProcessor(Mon, ev->Get()->GroupQueues, GroupId, Info, monEv));
+ }
}
+ void Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev) {
+ Info = std::move(ev->Get()->Info);
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor state functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- STATEFN(StateOnline) {
+ STATEFN(StateOnline) {
switch (ev->GetTypeRewrite()) {
- cFunc(NActors::TEvents::TSystem::Poison, PassAway);
- hFunc(NMon::TEvHttpInfo, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- cFunc(TEvBlobStorage::EvThroughputUpdate, HandleThroughputUpdate);
- cFunc(EvNodeWhiteboardNotify, HandleNodeWhiteboardNotify);
- hFunc(TEvThroughputAddRequest, Handle);
- hFunc(TEvProxySessionsState, Handle);
- hFunc(TEvBlobStorage::TEvConfigureProxy, Handle);
+ cFunc(NActors::TEvents::TSystem::Poison, PassAway);
+ hFunc(NMon::TEvHttpInfo, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(TEvBlobStorage::EvThroughputUpdate, HandleThroughputUpdate);
+ cFunc(EvNodeWhiteboardNotify, HandleNodeWhiteboardNotify);
+ hFunc(TEvThroughputAddRequest, Handle);
+ hFunc(TEvProxySessionsState, Handle);
+ hFunc(TEvBlobStorage::TEvConfigureProxy, Handle);
default:
break;
}
@@ -452,9 +452,9 @@ public:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Blob Storage Group Proxy Mon Creation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-IActor* CreateBlobStorageGroupProxyMon(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId) {
- return new TBlobStorageGroupProxyMonActor(std::move(mon), groupId, std::move(info), proxyId);
+IActor* CreateBlobStorageGroupProxyMon(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId) {
+ return new TBlobStorageGroupProxyMonActor(std::move(mon), groupId, std::move(info), proxyId);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_monactor.h b/ydb/core/blobstorage/dsproxy/dsproxy_monactor.h
index 32482560dd9..0ace33367a0 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_monactor.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_monactor.h
@@ -1,22 +1,22 @@
#pragma once
-
+
#include "defs.h"
-#include "dsproxy_mon.h"
+#include "dsproxy_mon.h"
namespace NKikimr {
-struct TEvThroughputAddRequest : public TEventLocal<TEvThroughputAddRequest, TEvBlobStorage::EvThroughputAddRequest> {
- NKikimrBlobStorage::EPutHandleClass PutHandleClass;
- ui64 Bytes;
-
- TEvThroughputAddRequest(NKikimrBlobStorage::EPutHandleClass putHandleClass, ui64 bytes)
- : PutHandleClass(putHandleClass)
- , Bytes(bytes)
- {}
-};
-
-IActor* CreateBlobStorageGroupProxyMon(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId);
+struct TEvThroughputAddRequest : public TEventLocal<TEvThroughputAddRequest, TEvBlobStorage::EvThroughputAddRequest> {
+ NKikimrBlobStorage::EPutHandleClass PutHandleClass;
+ ui64 Bytes;
+
+ TEvThroughputAddRequest(NKikimrBlobStorage::EPutHandleClass putHandleClass, ui64 bytes)
+ : PutHandleClass(putHandleClass)
+ , Bytes(bytes)
+ {}
+};
+
+IActor* CreateBlobStorageGroupProxyMon(TIntrusivePtr<TBlobStorageGroupProxyMon> mon, ui32 groupId,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId proxyId);
} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_multicollect.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_multicollect.cpp
index 54a74eba581..a418ff8f030 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_multicollect.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_multicollect.cpp
@@ -20,13 +20,13 @@ class TBlobStorageGroupMultiCollectRequest
const ui32 PerGenerationCounter; // monotone increasing cmd counter for RecordGeneration
const ui32 Channel;
- const std::unique_ptr<TVector<TLogoBlobID> > Keep;
- const std::unique_ptr<TVector<TLogoBlobID> > DoNotKeep;
+ const std::unique_ptr<TVector<TLogoBlobID> > Keep;
+ const std::unique_ptr<TVector<TLogoBlobID> > DoNotKeep;
const TInstant Deadline;
const ui32 CollectGeneration;
const ui32 CollectStep;
- const bool Hard;
+ const bool Hard;
const bool Collect;
ui64 FlagRequestsInFlight;
@@ -36,15 +36,15 @@ class TBlobStorageGroupMultiCollectRequest
TStackVec<TRequestInfo, TypicalDisksInGroup> RequestInfos;
- void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) {
+ void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr &ev) {
const TEvBlobStorage::TEvCollectGarbageResult &res = *ev->Get();
- R_LOG_ERROR_S("BPMC1", "Handle TEvCollectGarbageResult"
- << " status# " << NKikimrProto::EReplyStatus_Name(res.Status)
+ R_LOG_ERROR_S("BPMC1", "Handle TEvCollectGarbageResult"
+ << " status# " << NKikimrProto::EReplyStatus_Name(res.Status)
<< " FlagRequestsInFlight# " << FlagRequestsInFlight
- << " CollectRequestsInFlight " << CollectRequestsInFlight);
+ << " CollectRequestsInFlight " << CollectRequestsInFlight);
if (res.Status != NKikimrProto::OK) {
- ReplyAndDie(res.Status);
+ ReplyAndDie(res.Status);
return;
}
@@ -57,45 +57,45 @@ class TBlobStorageGroupMultiCollectRequest
FlagRequestsInFlight--;
if (FlagRequestsInFlight == 0) {
ui64 iterations =
- TEvBlobStorage::TEvCollectGarbage::PerGenerationCounterStepSize(Keep.get(), DoNotKeep.get());
+ TEvBlobStorage::TEvCollectGarbage::PerGenerationCounterStepSize(Keep.get(), DoNotKeep.get());
ui64 idx = iterations - 1;
- SendRequest(idx, true);
+ SendRequest(idx, true);
}
} else {
CollectRequestsInFlight--;
Y_VERIFY(CollectRequestsInFlight == 0);
- ReplyAndDie(NKikimrProto::OK);
+ ReplyAndDie(NKikimrProto::OK);
return;
}
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupMultiCollectRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvCollectGarbageResult> ev(new TEvBlobStorage::TEvCollectGarbageResult(
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ std::unique_ptr<TEvBlobStorage::TEvCollectGarbageResult> ev(new TEvBlobStorage::TEvCollectGarbageResult(
status, TabletId, RecordGeneration, PerGenerationCounter, Channel));
ev->ErrorReason = ErrorReason;
- SendResponseAndDie(std::move(ev));
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32) {
- Y_FAIL();
+ SendResponseAndDie(std::move(ev));
}
+ std::unique_ptr<IEventBase> RestartQuery(ui32) {
+ Y_FAIL();
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_MULTICOLLECT_ACTOR;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveMultiCollect;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_MULTICOLLECT_ACTOR;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveMultiCollect;
+ }
+
TBlobStorageGroupMultiCollectRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev, ui64 cookie,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
- NKikimrServices::BS_PROXY_MULTICOLLECT, false, {}, now, storagePoolCounters, 0)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
+ NKikimrServices::BS_PROXY_MULTICOLLECT, false, {}, now, storagePoolCounters, 0)
, TabletId(ev->TabletId)
, RecordGeneration(ev->RecordGeneration)
, PerGenerationCounter(ev->PerGenerationCounter)
@@ -105,20 +105,20 @@ public:
, Deadline(ev->Deadline)
, CollectGeneration(ev->CollectGeneration)
, CollectStep(ev->CollectStep)
- , Hard(ev->Hard)
+ , Hard(ev->Hard)
, Collect(ev->Collect)
, FlagRequestsInFlight(0)
, CollectRequestsInFlight(0)
, StartTime(now)
- {}
+ {}
- void SendRequest(ui64 idx, bool isLast) {
+ void SendRequest(ui64 idx, bool isLast) {
ui64 cookie = RequestInfos.size();
RequestInfos.push_back({false});
bool isCollect = isLast ? Collect : false;
- std::unique_ptr<TVector<TLogoBlobID>> keepPart;
- std::unique_ptr<TVector<TLogoBlobID>> doNotKeepPart;
+ std::unique_ptr<TVector<TLogoBlobID>> keepPart;
+ std::unique_ptr<TVector<TLogoBlobID>> doNotKeepPart;
ui64 keepCount = Keep ? Keep->size() : 0;
ui64 doNotKeepCount = DoNotKeep ? DoNotKeep->size() : 0;
ui64 keepPartCount = 0;
@@ -127,13 +127,13 @@ public:
ui64 end = begin + MaxCollectGarbageFlagsPerMessage;
if (begin < keepCount) {
keepPartCount = Min(MaxCollectGarbageFlagsPerMessage, keepCount - begin);
- keepPart.reset(new TVector<TLogoBlobID>(keepPartCount));
+ keepPart.reset(new TVector<TLogoBlobID>(keepPartCount));
for (ui64 keepIdx = 0; keepIdx < keepPartCount; ++keepIdx) {
(*keepPart)[keepIdx] = (*Keep)[begin + keepIdx];
}
if (end > keepCount) {
doNotKeepPartCount = Min(doNotKeepCount, MaxCollectGarbageFlagsPerMessage - keepPartCount);
- doNotKeepPart.reset(new TVector<TLogoBlobID>(doNotKeepPartCount));
+ doNotKeepPart.reset(new TVector<TLogoBlobID>(doNotKeepPartCount));
for (ui64 doNotKeepIdx = 0; doNotKeepIdx < doNotKeepPartCount; ++doNotKeepIdx) {
(*doNotKeepPart)[doNotKeepIdx] = (*DoNotKeep)[doNotKeepIdx];
}
@@ -141,20 +141,20 @@ public:
} else {
ui64 doNotKeepBegin = begin - keepCount;
doNotKeepPartCount = Min(MaxCollectGarbageFlagsPerMessage, doNotKeepCount - doNotKeepBegin);
- doNotKeepPart.reset(new TVector<TLogoBlobID>(doNotKeepPartCount));
+ doNotKeepPart.reset(new TVector<TLogoBlobID>(doNotKeepPartCount));
for (ui64 doNotKeepIdx = 0; doNotKeepIdx < doNotKeepPartCount; ++doNotKeepIdx) {
(*doNotKeepPart)[doNotKeepIdx] = (*DoNotKeep)[doNotKeepBegin + doNotKeepIdx];
}
}
- std::unique_ptr<TEvBlobStorage::TEvCollectGarbage> ev(new TEvBlobStorage::TEvCollectGarbage(
+ std::unique_ptr<TEvBlobStorage::TEvCollectGarbage> ev(new TEvBlobStorage::TEvCollectGarbage(
TabletId, RecordGeneration, PerGenerationCounter + idx, Channel,
- isCollect, CollectGeneration, CollectStep, keepPart.release(), doNotKeepPart.release(), Deadline, false,
- Hard));
- R_LOG_DEBUG_S("BPMC3", "SendRequest idx# " << idx
+ isCollect, CollectGeneration, CollectStep, keepPart.release(), doNotKeepPart.release(), Deadline, false,
+ Hard));
+ R_LOG_DEBUG_S("BPMC3", "SendRequest idx# " << idx
<< " isLast# " << isLast
- << " ev# " << ev->ToString());
- SendToBSProxy(SelfId(), Info->GroupID, ev.release(), cookie);
+ << " ev# " << ev->ToString());
+ SendToBSProxy(SelfId(), Info->GroupID, ev.release(), cookie);
if (isLast) {
CollectRequestsInFlight++;
@@ -163,47 +163,47 @@ public:
}
}
- void Bootstrap() {
- A_LOG_INFO_S("BPMC4", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " TabletId# " << TabletId
- << " Channel# " << Channel
- << " RecordGeneration# " << RecordGeneration
- << " PerGenerationCounter# " << PerGenerationCounter
- << " Deadline# " << Deadline
- << " CollectGeneration# " << CollectGeneration
- << " CollectStep# " << CollectStep
- << " Collect# " << (Collect ? "true" : "false")
- << " Hard# " << (Hard ? "true" : "false"));
-
- for (const auto& item : Keep ? *Keep : TVector<TLogoBlobID>()) {
- A_LOG_INFO_S("BPMC5", "Keep# " << item);
- }
-
- for (const auto& item : DoNotKeep ? *DoNotKeep : TVector<TLogoBlobID>()) {
- A_LOG_INFO_S("BPMC6", "DoNotKeep# " << item);
- }
-
- ui64 iterations = TEvBlobStorage::TEvCollectGarbage::PerGenerationCounterStepSize(Keep.get(), DoNotKeep.get());
+ void Bootstrap() {
+ A_LOG_INFO_S("BPMC4", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " TabletId# " << TabletId
+ << " Channel# " << Channel
+ << " RecordGeneration# " << RecordGeneration
+ << " PerGenerationCounter# " << PerGenerationCounter
+ << " Deadline# " << Deadline
+ << " CollectGeneration# " << CollectGeneration
+ << " CollectStep# " << CollectStep
+ << " Collect# " << (Collect ? "true" : "false")
+ << " Hard# " << (Hard ? "true" : "false"));
+
+ for (const auto& item : Keep ? *Keep : TVector<TLogoBlobID>()) {
+ A_LOG_INFO_S("BPMC5", "Keep# " << item);
+ }
+
+ for (const auto& item : DoNotKeep ? *DoNotKeep : TVector<TLogoBlobID>()) {
+ A_LOG_INFO_S("BPMC6", "DoNotKeep# " << item);
+ }
+
+ ui64 iterations = TEvBlobStorage::TEvCollectGarbage::PerGenerationCounterStepSize(Keep.get(), DoNotKeep.get());
for (ui64 idx = 0; idx < iterations - 1; ++idx) {
- SendRequest(idx, false);
+ SendRequest(idx, false);
}
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
+ hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupMultiCollectRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvCollectGarbage *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupMultiCollectRequest(info, state, source, mon, ev, cookie, now,
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_multiget.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_multiget.cpp
index 02d7849855c..66454c70134 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_multiget.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_multiget.cpp
@@ -1,5 +1,5 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
#include <ydb/core/blobstorage/base/wilson_events.h>
#include <ydb/core/blobstorage/vdisk/query/query_spacetracker.h>
@@ -22,7 +22,7 @@ class TBlobStorageGroupMultiGetRequest : public TBlobStorageGroupRequestActor<TB
const ui64 QuerySize;
const TArrayHolder<TEvBlobStorage::TEvGet::TQuery> Queries;
const TInstant Deadline;
- const bool IsInternal;
+ const bool IsInternal;
TArrayHolder<TEvBlobStorage::TEvGetResult::TResponse> Responses;
const TInstant StartTime;
@@ -30,21 +30,21 @@ class TBlobStorageGroupMultiGetRequest : public TBlobStorageGroupRequestActor<TB
const NKikimrBlobStorage::EGetHandleClass GetHandleClass;
const ui32 ForceBlockedGeneration;
- static constexpr ui64 MaxRequestsInFlight = 3;
- ui64 RequestsInFlight = 0;
- std::deque<std::pair<std::unique_ptr<TEvBlobStorage::TEvGet>, ui64>> PendingGets;
+ static constexpr ui64 MaxRequestsInFlight = 3;
+ ui64 RequestsInFlight = 0;
+ std::deque<std::pair<std::unique_ptr<TEvBlobStorage::TEvGet>, ui64>> PendingGets;
TStackVec<TRequestInfo, TypicalDisksInGroup> RequestInfos;
- void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
RequestsInFlight--;
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
-
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
+
const TEvBlobStorage::TEvGetResult &res = *ev->Get();
if (res.Status != NKikimrProto::OK) {
- R_LOG_ERROR_S("BPMG1", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(res.Status));
- ReplyAndDie(res.Status);
+ R_LOG_ERROR_S("BPMG1", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(res.Status));
+ ReplyAndDie(res.Status);
return;
}
@@ -58,107 +58,107 @@ class TBlobStorageGroupMultiGetRequest : public TBlobStorageGroupRequestActor<TB
Responses[info.BeginIdx + offset] = res.Responses[offset];
}
- SendRequests();
+ SendRequests();
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupMultiGetRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvGetResult> ev(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
- for (ui32 i = 0, e = QuerySize; i != e; ++i) {
- const TEvBlobStorage::TEvGet::TQuery &query = Queries[i];
- TEvBlobStorage::TEvGetResult::TResponse &x = ev->Responses[i];
- x.Status = NKikimrProto::UNKNOWN;
- x.Id = query.Id;
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ std::unique_ptr<TEvBlobStorage::TEvGetResult> ev(new TEvBlobStorage::TEvGetResult(status, QuerySize, Info->GroupID));
+ for (ui32 i = 0, e = QuerySize; i != e; ++i) {
+ const TEvBlobStorage::TEvGet::TQuery &query = Queries[i];
+ TEvBlobStorage::TEvGetResult::TResponse &x = ev->Responses[i];
+ x.Status = NKikimrProto::UNKNOWN;
+ x.Id = query.Id;
}
ev->ErrorReason = ErrorReason;
- Mon->CountGetResponseTime(Info->GetDeviceType(), GetHandleClass, ev->PayloadSizeBytes(), TActivationContext::Now() - StartTime);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetResultSent);
- Y_VERIFY(status != NKikimrProto::OK);
- SendResponseAndDie(std::move(ev));
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32) {
- Y_FAIL();
+ Mon->CountGetResponseTime(Info->GetDeviceType(), GetHandleClass, ev->PayloadSizeBytes(), TActivationContext::Now() - StartTime);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetResultSent);
+ Y_VERIFY(status != NKikimrProto::OK);
+ SendResponseAndDie(std::move(ev));
}
+ std::unique_ptr<IEventBase> RestartQuery(ui32) {
+ Y_FAIL();
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_MULTIGET_ACTOR;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveMultiGet;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_MULTIGET_ACTOR;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveMultiGet;
+ }
+
TBlobStorageGroupMultiGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev, ui64 cookie,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev, ui64 cookie,
NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
- NKikimrServices::BS_PROXY_MULTIGET, false, latencyQueueKind, now, storagePoolCounters, 0)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ NKikimrServices::BS_PROXY_MULTIGET, false, latencyQueueKind, now, storagePoolCounters, 0)
, QuerySize(ev->QuerySize)
, Queries(ev->Queries.Release())
, Deadline(ev->Deadline)
- , IsInternal(ev->IsInternal)
+ , IsInternal(ev->IsInternal)
, Responses(new TEvBlobStorage::TEvGetResult::TResponse[QuerySize])
, StartTime(now)
, MustRestoreFirst(ev->MustRestoreFirst)
, GetHandleClass(ev->GetHandleClass)
, ForceBlockedGeneration(ev->ForceBlockedGeneration)
- {}
+ {}
- void PrepareRequest(ui32 beginIdx, ui32 endIdx) {
- Y_VERIFY(endIdx > beginIdx);
+ void PrepareRequest(ui32 beginIdx, ui32 endIdx) {
+ Y_VERIFY(endIdx > beginIdx);
ui64 cookie = RequestInfos.size();
RequestInfos.push_back({beginIdx, endIdx, false});
TArrayHolder<TEvBlobStorage::TEvGet::TQuery> queries(new TEvBlobStorage::TEvGet::TQuery[endIdx - beginIdx]);
for (ui32 idx = beginIdx; idx < endIdx; ++idx) {
queries[idx - beginIdx] = Queries[idx];
}
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(queries, endIdx - beginIdx, Deadline, GetHandleClass,
- MustRestoreFirst, false, ForceBlockedGeneration);
- ev->IsInternal = IsInternal;
- PendingGets.emplace_back(std::move(ev), cookie);
- }
-
- void SendRequests() {
- for (; RequestsInFlight < MaxRequestsInFlight && !PendingGets.empty(); ++RequestsInFlight, PendingGets.pop_front()) {
- auto& [ev, cookie] = PendingGets.front();
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
- SendToBSProxy(SelfId(), Info->GroupID, ev.release(), cookie, TraceId.SeparateBranch());
- }
- if (!RequestsInFlight && PendingGets.empty()) {
- auto ev = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, 0, Info->GroupID);
- ev->ResponseSz = QuerySize;
- ev->Responses = std::move(Responses);
- Mon->CountGetResponseTime(Info->GetDeviceType(), GetHandleClass, ev->PayloadSizeBytes(), TActivationContext::Now() - StartTime);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetResultSent);
- SendResponseAndDie(std::move(ev));
- }
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(queries, endIdx - beginIdx, Deadline, GetHandleClass,
+ MustRestoreFirst, false, ForceBlockedGeneration);
+ ev->IsInternal = IsInternal;
+ PendingGets.emplace_back(std::move(ev), cookie);
+ }
+
+ void SendRequests() {
+ for (; RequestsInFlight < MaxRequestsInFlight && !PendingGets.empty(); ++RequestsInFlight, PendingGets.pop_front()) {
+ auto& [ev, cookie] = PendingGets.front();
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
+ SendToBSProxy(SelfId(), Info->GroupID, ev.release(), cookie, TraceId.SeparateBranch());
+ }
+ if (!RequestsInFlight && PendingGets.empty()) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, 0, Info->GroupID);
+ ev->ResponseSz = QuerySize;
+ ev->Responses = std::move(Responses);
+ Mon->CountGetResponseTime(Info->GetDeviceType(), GetHandleClass, ev->PayloadSizeBytes(), TActivationContext::Now() - StartTime);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetResultSent);
+ SendResponseAndDie(std::move(ev));
+ }
}
- void Bootstrap() {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetReceived);
-
- auto dumpQuery = [this] {
- TStringStream str;
- str << "{";
- for (ui32 i = 0; i < QuerySize; ++i) {
- str << (i ? " " : "")
- << Queries[i].Id
- << "@" << Queries[i].Shift
- << ":" << Queries[i].Size;
- }
- str << "}";
- return str.Str();
- };
- A_LOG_INFO_S("BPMG3", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " Query# " << dumpQuery()
- << " Deadline# " << Deadline);
-
+ void Bootstrap() {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, MultiGetReceived);
+
+ auto dumpQuery = [this] {
+ TStringStream str;
+ str << "{";
+ for (ui32 i = 0; i < QuerySize; ++i) {
+ str << (i ? " " : "")
+ << Queries[i].Id
+ << "@" << Queries[i].Shift
+ << ":" << Queries[i].Size;
+ }
+ str << "}";
+ return str.Str();
+ };
+ A_LOG_INFO_S("BPMG3", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " Query# " << dumpQuery()
+ << " Deadline# " << Deadline);
+
Y_VERIFY(QuerySize != 0); // reply with error?
ui32 beginIdx = 0;
TLogoBlobID lastBlobId;
@@ -173,37 +173,37 @@ public:
resultSize.AddAllPartsOfLogoBlob(Info->Type, query.Id);
if (queryIdx != beginIdx) {
- if (resultSize.IsOverflow() || queryIdx - beginIdx == 10000) {
- PrepareRequest(beginIdx, queryIdx);
+ if (resultSize.IsOverflow() || queryIdx - beginIdx == 10000) {
+ PrepareRequest(beginIdx, queryIdx);
beginIdx = queryIdx;
resultSize.Init();
resultSize.AddAllPartsOfLogoBlob(Info->Type, query.Id);
}
}
}
- PrepareRequest(beginIdx, QuerySize);
-
- SendRequests();
+ PrepareRequest(beginIdx, QuerySize);
+ SendRequests();
+
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupMultiGetRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvGet *ev,
- ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
+ ui64 cookie, NWilson::TTraceId traceId, TMaybe<TGroupStat::EKind> latencyQueueKind,
TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
- return new TBlobStorageGroupMultiGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
+ return new TBlobStorageGroupMultiGetRequest(info, state, source, mon, ev, cookie, std::move(traceId),
latencyQueueKind, now, storagePoolCounters);
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.cpp
index addca8c5330..26e822cffd8 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.cpp
@@ -45,28 +45,28 @@ TDsProxyNodeMon::TDsProxyNodeMon(TIntrusivePtr<NMonitoring::TDynamicCounters> &c
CheckNodeMonCountersForDeviceType(TPDiskCategory::DEVICE_TYPE_NVME);
CheckNodeMonCountersForDeviceType(TPDiskCategory::DEVICE_TYPE_UNKNOWN);
}
-
- // restart counters
- {
- auto group = Group->GetSubgroup("subsystem", "restart");
- RestartPut = group->GetCounter("EvPut", true);
- RestartGet = group->GetCounter("EvGet", true);
+
+ // restart counters
+ {
+ auto group = Group->GetSubgroup("subsystem", "restart");
+ RestartPut = group->GetCounter("EvPut", true);
+ RestartGet = group->GetCounter("EvGet", true);
RestartPatch = group->GetCounter("EvPatch", true);
- RestartBlock = group->GetCounter("EvBlock", true);
- RestartDiscover = group->GetCounter("EvDiscover", true);
- RestartRange = group->GetCounter("EvRange", true);
- RestartCollectGarbage = group->GetCounter("EvCollectGarbage", true);
- RestartIndexRestoreGet = group->GetCounter("EvIndexRestoreGet", true);
- RestartStatus = group->GetCounter("EvStatus", true);
- }
-
- {
- auto group = Group->GetSubgroup("subsystem", "restart_histo");
+ RestartBlock = group->GetCounter("EvBlock", true);
+ RestartDiscover = group->GetCounter("EvDiscover", true);
+ RestartRange = group->GetCounter("EvRange", true);
+ RestartCollectGarbage = group->GetCounter("EvCollectGarbage", true);
+ RestartIndexRestoreGet = group->GetCounter("EvIndexRestoreGet", true);
+ RestartStatus = group->GetCounter("EvStatus", true);
+ }
+
+ {
+ auto group = Group->GetSubgroup("subsystem", "restart_histo");
auto histoGroup = group->GetSubgroup("sensor", "restart_histo");
- for (size_t i = 0; i < RestartHisto.size(); ++i) {
+ for (size_t i = 0; i < RestartHisto.size(); ++i) {
RestartHisto[i] = histoGroup->GetNamedCounter("restartCount", ToString(i), true);
- }
- }
+ }
+ }
// Accelerate counters
{
auto group = Group->GetSubgroup("subsystem", "accelerate");
@@ -74,14 +74,14 @@ TDsProxyNodeMon::TDsProxyNodeMon(TIntrusivePtr<NMonitoring::TDynamicCounters> &c
AccelerateEvVMultiPutCount = group->GetCounter("EvVMultiPutCount", true);
AccelerateEvVGetCount = group->GetCounter("EvVGetCount", true);
}
- // malfunction counters
- {
- auto group = Group->GetSubgroup("subsystem", "malfunction");
- EstablishingSessionsTimeout = group->GetCounter("EstablishingSessionsTimeout", false);
- EstablishingSessionsTimeout5min = group->GetCounter("EstablishingSessionsTimeout5min", false);
- UnconfiguredTimeout = group->GetCounter("UnconfiguredTimeout", false);
- UnconfiguredTimeout5min = group->GetCounter("UnconfiguredTimeout5min", false);
- }
+ // malfunction counters
+ {
+ auto group = Group->GetSubgroup("subsystem", "malfunction");
+ EstablishingSessionsTimeout = group->GetCounter("EstablishingSessionsTimeout", false);
+ EstablishingSessionsTimeout5min = group->GetCounter("EstablishingSessionsTimeout5min", false);
+ UnconfiguredTimeout = group->GetCounter("UnconfiguredTimeout", false);
+ UnconfiguredTimeout5min = group->GetCounter("UnconfiguredTimeout5min", false);
+ }
}
ui32 IdxForType(TPDiskCategory::EDeviceType type) {
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.h b/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.h
index 150da172fb8..09402450119 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_nodemon.h
@@ -65,31 +65,31 @@ struct TDsProxyNodeMon : public TThrRefBase {
std::array<bool, KnownDeviceTypesCount> IsCountersPresentedForIdx;
- // restart counters
- NMonitoring::TDynamicCounters::TCounterPtr RestartPut;
- NMonitoring::TDynamicCounters::TCounterPtr RestartGet;
- NMonitoring::TDynamicCounters::TCounterPtr RestartBlock;
- NMonitoring::TDynamicCounters::TCounterPtr RestartDiscover;
- NMonitoring::TDynamicCounters::TCounterPtr RestartRange;
- NMonitoring::TDynamicCounters::TCounterPtr RestartCollectGarbage;
- NMonitoring::TDynamicCounters::TCounterPtr RestartIndexRestoreGet;
- NMonitoring::TDynamicCounters::TCounterPtr RestartStatus;
+ // restart counters
+ NMonitoring::TDynamicCounters::TCounterPtr RestartPut;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartGet;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartBlock;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartDiscover;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartRange;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartCollectGarbage;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartIndexRestoreGet;
+ NMonitoring::TDynamicCounters::TCounterPtr RestartStatus;
NMonitoring::TDynamicCounters::TCounterPtr RestartPatch;
-
- std::array<NMonitoring::TDynamicCounters::TCounterPtr, 4> RestartHisto;
-
+
+ std::array<NMonitoring::TDynamicCounters::TCounterPtr, 4> RestartHisto;
+
// accelerate counters
NMonitoring::TDynamicCounters::TCounterPtr AccelerateEvVPutCount;
NMonitoring::TDynamicCounters::TCounterPtr AccelerateEvVMultiPutCount;
NMonitoring::TDynamicCounters::TCounterPtr AccelerateEvVGetCount;
- // malfunction counters
- NMonitoring::TDynamicCounters::TCounterPtr EstablishingSessionsTimeout;
- NMonitoring::TDynamicCounters::TCounterPtr EstablishingSessionsTimeout5min;
- NMonitoring::TDynamicCounters::TCounterPtr UnconfiguredTimeout;
- NMonitoring::TDynamicCounters::TCounterPtr UnconfiguredTimeout5min;
-
+ // malfunction counters
+ NMonitoring::TDynamicCounters::TCounterPtr EstablishingSessionsTimeout;
+ NMonitoring::TDynamicCounters::TCounterPtr EstablishingSessionsTimeout5min;
+ NMonitoring::TDynamicCounters::TCounterPtr UnconfiguredTimeout;
+ NMonitoring::TDynamicCounters::TCounterPtr UnconfiguredTimeout5min;
+
TDsProxyNodeMon(TIntrusivePtr<NMonitoring::TDynamicCounters> &counters, bool initForAllDeviceTypes);
void CountPutPesponseTime(TPDiskCategory::EDeviceType type, NKikimrBlobStorage::EPutHandleClass cls, ui32 size,
TDuration duration);
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_nodemonactor.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_nodemonactor.cpp
index 5bf4b098362..6dac974aa47 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_nodemonactor.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_nodemonactor.cpp
@@ -20,8 +20,8 @@ class TDsProxyNodeMonActor : public TActorBootstrapped<TDsProxyNodeMonActor> {
TIntrusivePtr<TDsProxyNodeMon> Mon;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::DS_PROXY_NODE_MON_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::DS_PROXY_NODE_MON_ACTOR;
}
TDsProxyNodeMonActor(TIntrusivePtr<TDsProxyNodeMon> mon)
@@ -38,20 +38,20 @@ public:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Bootstrap state
- void Bootstrap() {
- NActors::TMon* mon = AppData()->Mon;
+ void Bootstrap() {
+ NActors::TMon* mon = AppData()->Mon;
if (mon) {
NMonitoring::TIndexMonPage *actorsMonPage = mon->RegisterIndexPage("actors", "Actors");
- mon->RegisterActorPage(actorsMonPage, "dsproxynode", "DsProxyNode", false, TlsActivationContext->ExecutorThread.ActorSystem,
- SelfId());
+ mon->RegisterActorPage(actorsMonPage, "dsproxynode", "DsProxyNode", false, TlsActivationContext->ExecutorThread.ActorSystem,
+ SelfId());
}
Become(&TThis::StateOnline);
- HandleWakeup();
+ HandleWakeup();
}
- void HandleWakeup() {
- Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
+ void HandleWakeup() {
+ Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup);
Mon->PutResponseTime.Update();
Mon->PutTabletLogResponseTime.Update();
@@ -70,7 +70,7 @@ public:
Mon->PatchResponseTime.Update();
}
- void Handle(NMon::TEvHttpInfo::TPtr &ev) {
+ void Handle(NMon::TEvHttpInfo::TPtr &ev) {
TStringStream str;
HTML(str) {
@@ -81,18 +81,18 @@ public:
}
}
- Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
+ Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor state functions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- STATEFN(StateOnline) {
+ STATEFN(StateOnline) {
switch (ev->GetTypeRewrite()) {
- cFunc(NActors::TEvents::TSystem::Poison, PassAway);
- hFunc(NMon::TEvHttpInfo, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(NActors::TEvents::TSystem::Poison, PassAway);
+ hFunc(NMon::TEvHttpInfo, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
default:
break;
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_patch.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_patch.cpp
index fcced0b6f85..43025548071 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_patch.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_patch.cpp
@@ -109,7 +109,7 @@ public:
}
void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvPatchResult> result = std::make_unique<TEvBlobStorage::TEvPatchResult>(status, PatchedId,
+ std::unique_ptr<TEvBlobStorage::TEvPatchResult> result = std::make_unique<TEvBlobStorage::TEvPatchResult>(status, PatchedId,
StatusFlags, Info->GroupID, ApproximateFreeSpaceShare);
result->ErrorReason = ErrorReason;
result->Orbit = std::move(Orbit);
@@ -170,10 +170,10 @@ public:
Buffer = result->Responses[0].Buffer;
ApplyDiffs();
- std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(PatchedId, Buffer, Deadline,
+ std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(PatchedId, Buffer, Deadline,
NKikimrBlobStorage::AsyncBlob, TEvBlobStorage::TEvPut::TacticDefault);
put->Orbit = std::move(Orbit);
- Send(ProxyActorId, put.release(), 0, OriginalId.Hash(), std::move(TraceId));
+ Send(ProxyActorId, put.release(), 0, OriginalId.Hash(), std::move(TraceId));
}
void Handle(TEvBlobStorage::TEvPutResult::TPtr &ev) {
@@ -386,13 +386,13 @@ public:
}
void SendStopDiffs() {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchDiff>> events;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchDiff>> events;
for (ui32 vdiskIdx = 0; vdiskIdx < VDisks.size(); ++vdiskIdx) {
if (!ErrorResponseFlags[vdiskIdx] && !EmptyResponseFlags[vdiskIdx] && ReceivedResponseFlags[vdiskIdx]) {
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(
OriginalId, PatchedId, VDisks[vdiskIdx], 0, Deadline, vdiskIdx);
ev->SetForceEnd();
- events.emplace_back(std::move(ev));
+ events.emplace_back(std::move(ev));
}
}
SendToQueues(events, false);
@@ -403,7 +403,7 @@ public:
}
void SendDiffs(const TStackVec<TPartPlacement, TypicalPartsInBlob> &placement) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchDiff>> events;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchDiff>> events;
TPartDiffSet diffSet;
TVector<TDiff> diffs;
@@ -444,8 +444,8 @@ public:
TLogoBlobID partchedPartBlobId(PatchedId, partPlacement.PartId);
ui32 waitedXorDiffs = (partPlacement.PartId > dataParts) ? dataPartCount : 0;
- auto ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(originalPartBlobId, partchedPartBlobId,
- VDisks[idxInSubgroup], waitedXorDiffs, Deadline, idxInSubgroup);
+ auto ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(originalPartBlobId, partchedPartBlobId,
+ VDisks[idxInSubgroup], waitedXorDiffs, Deadline, idxInSubgroup);
ui32 diffForPartIdx = 0;
if (Info->Type.ErasureFamily() != TErasureType::ErasureMirror) {
@@ -460,7 +460,7 @@ public:
ev->AddXorReceiver(VDisks[parity.VDiskIdxInSubgroup], parity.PartId);
}
- events.push_back(std::move(ev));
+ events.push_back(std::move(ev));
}
SendToQueues(events, false);
SendStopDiffs();
@@ -506,7 +506,7 @@ public:
subgroupIdx = RandomNumber<ui32>(Info->Type.TotalPartCount());
}
TVDiskID vDisk = Info->GetVDiskInSubgroup(subgroupIdx, OriginalId.Hash());
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMovedPatch>> events;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMovedPatch>> events;
ui64 cookie = ((ui64)OriginalId.Hash() << 32) | PatchedId.Hash();
events.emplace_back(new TEvBlobStorage::TEvVMovedPatch(OriginalGroupId, Info->GroupID,
@@ -527,13 +527,13 @@ public:
<< " PatchedBlob# " << PatchedId
<< " Deadline# " << Deadline);
Become(&TThis::NaiveState);
- auto get = std::make_unique<TEvBlobStorage::TEvGet>(OriginalId, 0, OriginalId.BlobSize(), Deadline,
- NKikimrBlobStorage::AsyncRead);
+ auto get = std::make_unique<TEvBlobStorage::TEvGet>(OriginalId, 0, OriginalId.BlobSize(), Deadline,
+ NKikimrBlobStorage::AsyncRead);
get->Orbit = std::move(Orbit);
if (OriginalGroupId == Info->GroupID) {
- Send(ProxyActorId, get.release(), 0, PatchedId.Hash(), std::move(TraceId));
+ Send(ProxyActorId, get.release(), 0, PatchedId.Hash(), std::move(TraceId));
} else {
- SendToBSProxy(SelfId(), OriginalGroupId, get.release(), PatchedId.Hash(), std::move(TraceId));
+ SendToBSProxy(SelfId(), OriginalGroupId, get.release(), PatchedId.Hash(), std::move(TraceId));
}
}
@@ -554,10 +554,10 @@ public:
ErrorResponseFlags.assign(VDisks.size(), false);
EmptyResponseFlags.assign(VDisks.size(), false);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchStart>> events;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPatchStart>> events;
for (ui32 idx = 0; idx < VDisks.size(); ++idx) {
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> ev = std::make_unique<TEvBlobStorage::TEvVPatchStart>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> ev = std::make_unique<TEvBlobStorage::TEvVPatchStart>(
OriginalId, PatchedId, VDisks[idx], Deadline, idx, true);
events.emplace_back(std::move(ev));
SendedStarts++;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
index d9e0e2b3202..1c31134b264 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
@@ -1,5 +1,5 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
#include "root_cause.h"
#include "dsproxy_put_impl.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
@@ -36,23 +36,23 @@ struct TEvAccelerate : public TEventLocal<TEvAccelerate, TEvBlobStorage::EvAccel
// PUT request
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupPutRequest> {
+class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupPutRequest> {
struct TMultiPutItemInfo {
TLogoBlobID BlobId;
TString Buffer;
ui64 BufferSize;
- TActorId Recipient;
+ TActorId Recipient;
ui64 Cookie;
NWilson::TTraceId TraceId;
NLWTrace::TOrbit Orbit;
- bool Replied = false;
+ bool Replied = false;
- TMultiPutItemInfo(TLogoBlobID id, const TString& buffer, TActorId recipient, ui64 cookie,
+ TMultiPutItemInfo(TLogoBlobID id, const TString& buffer, TActorId recipient, ui64 cookie,
NWilson::TTraceId traceId, NLWTrace::TOrbit &&orbit)
: BlobId(id)
, Buffer(buffer)
, BufferSize(buffer.size())
- , Recipient(recipient)
+ , Recipient(recipient)
, Cookie(cookie)
, TraceId(std::move(traceId))
, Orbit(std::move(orbit))
@@ -81,19 +81,19 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
THPTimer Timer;
i64 ReportedBytes;
- TBlobStorageGroupProxyTimeStats TimeStats;
- bool TimeStatsEnabled;
-
+ TBlobStorageGroupProxyTimeStats TimeStats;
+ bool TimeStatsEnabled;
+
const TEvBlobStorage::TEvPut::ETactic Tactic;
- TDiskResponsivenessTracker::TPerDiskStatsPtr Stats;
-
+ TDiskResponsivenessTracker::TPerDiskStatsPtr Stats;
+
bool IsAccelerated;
bool IsAccelerateScheduled;
-
+
const bool IsMultiPutMode;
- void SanityCheck() {
+ void SanityCheck() {
if (RequestsSent <= MaxSaneRequests) {
return;
}
@@ -103,49 +103,49 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
<< " requests, internal state# " << PutImpl.DumpFullState();
ErrorReason = err.Str();
R_LOG_CRIT_S("BPG21", ErrorReason);
- ReplyAndDie(NKikimrProto::ERROR);
+ ReplyAndDie(NKikimrProto::ERROR);
}
- void Handle(TEvAccelerate::TPtr &ev) {
+ void Handle(TEvAccelerate::TPtr &ev) {
RootCauseTrack.OnAccelerate(ev->Get()->CauseIdx);
- Accelerate();
- SanityCheck(); // May Die
+ Accelerate();
+ SanityCheck(); // May Die
}
- void Accelerate() {
+ void Accelerate() {
if (IsAccelerated) {
return;
}
IsAccelerated = true;
if (IsMultiPutMode) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
PutImpl.Accelerate(LogCtx, vMultiPuts);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVMultiPut, TVMultiPutCookie>(vMultiPuts);
RequestsSent += vMultiPuts.size();
*Mon->NodeMon->AccelerateEvVMultiPutCount += vMultiPuts.size();
CountPuts(vMultiPuts);
- SendToQueues(vMultiPuts, TimeStatsEnabled);
+ SendToQueues(vMultiPuts, TimeStatsEnabled);
} else {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
PutImpl.Accelerate(LogCtx, vPuts);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVPut, TBlobCookie>(vPuts);
RequestsSent += vPuts.size();
*Mon->NodeMon->AccelerateEvVPutCount += vPuts.size();
CountPuts(vPuts);
- SendToQueues(vPuts, TimeStatsEnabled);
+ SendToQueues(vPuts, TimeStatsEnabled);
}
}
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr &ev) {
- A_LOG_LOG_S(false, ev->Get()->Record.GetStatus() == NKikimrProto::OK ? NLog::PRI_DEBUG : NLog::PRI_NOTICE,
- "BPP01", "received " << ev->Get()->ToString() << " from# " << VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()));
-
- ProcessReplyFromQueue(ev);
- // generate wilson event about request completion
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr &ev) {
+ A_LOG_LOG_S(false, ev->Get()->Record.GetStatus() == NKikimrProto::OK ? NLog::PRI_DEBUG : NLog::PRI_NOTICE,
+ "BPP01", "received " << ev->Get()->ToString() << " from# " << VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()));
+
+ ProcessReplyFromQueue(ev);
+ // generate wilson event about request completion
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
ResponsesReceived++;
-
+
const ui64 cyclesPerUs = NHPTimer::GetCyclesPerSecond() / 1000000;
ev->Get()->Record.MutableTimestamps()->SetReceivedByDSProxyUs(GetCycleCountFast() / cyclesPerUs);
const NKikimrBlobStorage::TEvVPutResult &record = ev->Get()->Record;
@@ -155,7 +155,7 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
TBlobCookie cookie(record.GetCookie());
const ui64 idx = cookie.GetBlobIdx();
const ui64 vdisk = cookie.GetVDiskOrderNumber();
- const NKikimrProto::EReplyStatus status = record.GetStatus();
+ const NKikimrProto::EReplyStatus status = record.GetStatus();
Y_VERIFY(vdisk < WaitingVDiskResponseCount.size(), "blobIdx# %" PRIu64 " vdisk# %" PRIu64, idx, vdisk);
if (WaitingVDiskResponseCount[vdisk] == 1) {
@@ -165,9 +165,9 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
Y_VERIFY(idx < ItemsInfo.size());
Y_VERIFY(origBlobId == ItemsInfo[idx].BlobId);
- if (TimeStatsEnabled && record.GetMsgQoS().HasExecTimeStats()) {
+ if (TimeStatsEnabled && record.GetMsgQoS().HasExecTimeStats()) {
TimeStats.ApplyPut(ItemsInfo[idx].BufferSize, record.GetMsgQoS().GetExecTimeStats());
- }
+ }
Y_VERIFY(record.HasVDiskID());
TVDiskID vDiskId = VDiskIDFromVDiskID(record.GetVDiskID());
@@ -187,41 +187,41 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
GetVDiskTimeMs(record.GetTimestamps()));
}
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TPutImpl::TPutResultVec putResults;
PutImpl.OnVPutEventResult(LogCtx, ev->Sender, *ev->Get(), vPuts, putResults);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVPut, TBlobCookie>(vPuts);
RequestsSent += vPuts.size();
- CountPuts(vPuts);
- SendToQueues(vPuts, TimeStatsEnabled);
- if (ReplyAndDieWithLastResponse(putResults)) {
+ CountPuts(vPuts);
+ SendToQueues(vPuts, TimeStatsEnabled);
+ if (ReplyAndDieWithLastResponse(putResults)) {
return;
}
Y_VERIFY(RequestsSent > ResponsesReceived, "RequestsSent# %" PRIu64 " ResponsesReceived# %" PRIu64,
ui64(RequestsSent), ui64(ResponsesReceived));
-
+
if (!IsAccelerateScheduled && !IsAccelerated) {
if (WaitingVDiskCount == 1 && RequestsSent > 1) {
ui64 timeToAccelerateUs = PutImpl.GetTimeToAccelerateNs(LogCtx) / 1000;
- TDuration timeSinceStart = TActivationContext::Now() - StartTime;
+ TDuration timeSinceStart = TActivationContext::Now() - StartTime;
if (timeSinceStart.MicroSeconds() < timeToAccelerateUs) {
ui64 causeIdx = RootCauseTrack.RegisterAccelerate();
Schedule(TDuration::MicroSeconds(timeToAccelerateUs - timeSinceStart.MicroSeconds()),
new TEvAccelerate(causeIdx));
IsAccelerateScheduled = true;
} else {
- Accelerate();
+ Accelerate();
}
}
}
- SanityCheck(); // May Die
+ SanityCheck(); // May Die
}
- void Handle(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
+ void Handle(TEvBlobStorage::TEvVMultiPutResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
// generate wilson event about request completion
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVPutResultReceived, MergedNode = std::move(ev->TraceId));
ResponsesReceived++;
const ui64 cyclesPerUs = NHPTimer::GetCyclesPerSecond() / 1000000;
@@ -239,20 +239,20 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
Y_VERIFY(record.HasCookie());
TVMultiPutCookie cookie(record.GetCookie());
const ui64 vdisk = cookie.GetVDiskOrderNumber();
- const NKikimrProto::EReplyStatus status = record.GetStatus();
-
- auto prio = NLog::PRI_DEBUG;
- if (status != NKikimrProto::OK) {
- prio = NLog::PRI_INFO;
- }
- for (const auto& item : record.GetItems()) {
- if (item.GetStatus() != NKikimrProto::OK) {
- prio = NLog::PRI_INFO;
- }
- }
- A_LOG_LOG_S(false, prio, "BPP02", "received " << ev->Get()->ToString()
- << " from# " << VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()));
-
+ const NKikimrProto::EReplyStatus status = record.GetStatus();
+
+ auto prio = NLog::PRI_DEBUG;
+ if (status != NKikimrProto::OK) {
+ prio = NLog::PRI_INFO;
+ }
+ for (const auto& item : record.GetItems()) {
+ if (item.GetStatus() != NKikimrProto::OK) {
+ prio = NLog::PRI_INFO;
+ }
+ }
+ A_LOG_LOG_S(false, prio, "BPP02", "received " << ev->Get()->ToString()
+ << " from# " << VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()));
+
Y_VERIFY(vdisk < WaitingVDiskResponseCount.size(), " vdisk# %" PRIu64, vdisk);
if (WaitingVDiskResponseCount[vdisk] == 1) {
WaitingVDiskCount--;
@@ -291,26 +291,26 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
ui64 blobIdx = TBlobCookie(item.GetCookie()).GetBlobIdx();
NKikimrProto::EReplyStatus itemStatus = item.GetStatus();
TLogoBlobID blobId = LogoBlobIDFromLogoBlobID(item.GetBlobID());
- Y_VERIFY(itemStatus != NKikimrProto::RACE); // we should get RACE for the whole request and handle it in CheckForTermErrors
- if (itemStatus == NKikimrProto::BLOCKED || itemStatus == NKikimrProto::DEADLINE) {
+ Y_VERIFY(itemStatus != NKikimrProto::RACE); // we should get RACE for the whole request and handle it in CheckForTermErrors
+ if (itemStatus == NKikimrProto::BLOCKED || itemStatus == NKikimrProto::DEADLINE) {
TStringStream errorReason;
errorReason << "Got VMultiPutResult itemStatus# " << itemStatus << " from VDiskId# " << vDiskId;
ErrorReason = errorReason.Str();
PutImpl.PrepareOneReply(itemStatus, TLogoBlobID(blobId, 0), blobIdx, LogCtx, ErrorReason, putResults);
}
}
- if (ReplyAndDieWithLastResponse(putResults)) {
+ if (ReplyAndDieWithLastResponse(putResults)) {
return;
}
putResults.clear();
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
PutImpl.OnVPutEventResult(LogCtx, ev->Sender, *ev->Get(), vMultiPuts, putResults);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVMultiPut, TVMultiPutCookie>(vMultiPuts);
RequestsSent += vMultiPuts.size();
CountPuts(vMultiPuts);
- SendToQueues(vMultiPuts, TimeStatsEnabled);
- if (ReplyAndDieWithLastResponse(putResults)) {
+ SendToQueues(vMultiPuts, TimeStatsEnabled);
+ if (ReplyAndDieWithLastResponse(putResults)) {
return;
}
Y_VERIFY(RequestsSent > ResponsesReceived, "RequestsSent# %" PRIu64 " ResponsesReceived# %" PRIu64
@@ -320,50 +320,50 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
if (!IsAccelerateScheduled && !IsAccelerated) {
if (WaitingVDiskCount == 1 && RequestsSent > 1) {
ui64 timeToAccelerateUs = PutImpl.GetTimeToAccelerateNs(LogCtx) / 1000;
- TDuration timeSinceStart = TActivationContext::Now() - StartTime;
+ TDuration timeSinceStart = TActivationContext::Now() - StartTime;
if (timeSinceStart.MicroSeconds() < timeToAccelerateUs) {
ui64 causeIdx = RootCauseTrack.RegisterAccelerate();
Schedule(TDuration::MicroSeconds(timeToAccelerateUs - timeSinceStart.MicroSeconds()),
new TEvAccelerate(causeIdx));
IsAccelerateScheduled = true;
} else {
- Accelerate();
+ Accelerate();
}
}
}
- SanityCheck(); // May Die
+ SanityCheck(); // May Die
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupPutRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
TPutImpl::TPutResultVec putResults;
PutImpl.PrepareReply(status, LogCtx, ErrorReason, putResults);
- Y_VERIFY(ReplyAndDieWithLastResponse(putResults));
+ Y_VERIFY(ReplyAndDieWithLastResponse(putResults));
}
- bool ReplyAndDieWithLastResponse(TPutImpl::TPutResultVec &putResults) {
- for (auto& [blobIdx, result] : putResults) {
- Y_VERIFY(ResponsesSent != ItemsInfo.size());
- SendReply(result, blobIdx);
- }
- if (ResponsesSent == ItemsInfo.size()) {
- PassAway();
- return true;
+ bool ReplyAndDieWithLastResponse(TPutImpl::TPutResultVec &putResults) {
+ for (auto& [blobIdx, result] : putResults) {
+ Y_VERIFY(ResponsesSent != ItemsInfo.size());
+ SendReply(result, blobIdx);
}
+ if (ResponsesSent == ItemsInfo.size()) {
+ PassAway();
+ return true;
+ }
return false;
}
- void SendReply(std::unique_ptr<TEvBlobStorage::TEvPutResult> &putResult, ui64 blobIdx) {
+ void SendReply(std::unique_ptr<TEvBlobStorage::TEvPutResult> &putResult, ui64 blobIdx) {
NKikimrProto::EReplyStatus status = putResult->Status;
- A_LOG_LOG_S(false, status == NKikimrProto::OK ? NLog::PRI_DEBUG : NLog::PRI_NOTICE, "BPP21",
- "SendReply putResult# " << putResult->ToString() << " ResponsesSent# " << ResponsesSent
- << " ItemsInfo.size# " << ItemsInfo.size()
- << " Last# " << (ResponsesSent + 1 == ItemsInfo.size() ? "true" : "false"));
- const TDuration duration = TActivationContext::Now() - StartTime;
+ A_LOG_LOG_S(false, status == NKikimrProto::OK ? NLog::PRI_DEBUG : NLog::PRI_NOTICE, "BPP21",
+ "SendReply putResult# " << putResult->ToString() << " ResponsesSent# " << ResponsesSent
+ << " ItemsInfo.size# " << ItemsInfo.size()
+ << " Last# " << (ResponsesSent + 1 == ItemsInfo.size() ? "true" : "false"));
+ const TDuration duration = TActivationContext::Now() - StartTime;
TLogoBlobID blobId = putResult->Id;
TLogoBlobID origBlobId = TLogoBlobID(blobId, 0);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &ItemsInfo[blobIdx].TraceId, EvPutResultSent, ReplyStatus = status);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &ItemsInfo[blobIdx].TraceId, EvPutResultSent, ReplyStatus = status);
Mon->CountPutPesponseTime(Info->GetDeviceType(), HandleClass, ItemsInfo[blobIdx].BufferSize, duration);
*Mon->ActivePutCapacity -= ReportedBytes;
Y_VERIFY(PutImpl.GetHandoffPartsSent() <= Info->Type.TotalPartCount() * MaxHandoffNodes * ItemsInfo.size());
@@ -381,12 +381,12 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
LWTRACK(DSProxyPutReply, ItemsInfo[blobIdx].Orbit);
putResult->Orbit = std::move(ItemsInfo[blobIdx].Orbit);
if (!IsManyPuts) {
- SendResponse(std::move(putResult), TimeStatsEnabled ? &TimeStats : nullptr);
+ SendResponse(std::move(putResult), TimeStatsEnabled ? &TimeStats : nullptr);
} else {
- SendResponse(std::move(putResult), TimeStatsEnabled ? &TimeStats : nullptr,
- ItemsInfo[blobIdx].Recipient, ItemsInfo[blobIdx].Cookie,
+ SendResponse(std::move(putResult), TimeStatsEnabled ? &TimeStats : nullptr,
+ ItemsInfo[blobIdx].Recipient, ItemsInfo[blobIdx].Cookie,
std::move(ItemsInfo[blobIdx].TraceId));
- ItemsInfo[blobIdx].Replied = true;
+ ItemsInfo[blobIdx].Replied = true;
}
}
@@ -399,69 +399,69 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor<TBlobSt
}
blobIdsStr << ItemsInfo[blobIdx].BlobId.ToString();
}
- return blobIdsStr << ']';
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartPut;
- auto ev = std::make_unique<TEvBlobStorage::TEvBunchOfEvents>();
- for (auto& item : ItemsInfo) {
- if (item.Replied) {
- continue;
- }
- TEvBlobStorage::TEvPut *put;
-
- TString buffer = item.Buffer;
- char *data = buffer.Detach();
- Decrypt(data, data, 0, buffer.size(), item.BlobId, *Info);
-
- ev->Bunch.emplace_back(new IEventHandle(
- TActorId() /*recipient*/,
- item.Recipient,
- put = new TEvBlobStorage::TEvPut(item.BlobId, buffer, Deadline, HandleClass, Tactic),
- 0 /*flags*/,
- item.Cookie,
- nullptr /*forwardOnNondelivery*/,
- std::move(item.TraceId)
- ));
- put->RestartCounter = counter;
- }
- return ev;
+ return blobIdsStr << ']';
}
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartPut;
+ auto ev = std::make_unique<TEvBlobStorage::TEvBunchOfEvents>();
+ for (auto& item : ItemsInfo) {
+ if (item.Replied) {
+ continue;
+ }
+ TEvBlobStorage::TEvPut *put;
+
+ TString buffer = item.Buffer;
+ char *data = buffer.Detach();
+ Decrypt(data, data, 0, buffer.size(), item.BlobId, *Info);
+
+ ev->Bunch.emplace_back(new IEventHandle(
+ TActorId() /*recipient*/,
+ item.Recipient,
+ put = new TEvBlobStorage::TEvPut(item.BlobId, buffer, Deadline, HandleClass, Tactic),
+ 0 /*flags*/,
+ item.Cookie,
+ nullptr /*forwardOnNondelivery*/,
+ std::move(item.TraceId)
+ ));
+ put->RestartCounter = counter;
+ }
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_PUT_ACTOR;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActivePut;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Put;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_PUT_ACTOR;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActivePut;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Put;
+ }
+
TBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvPut *ev,
- ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
+ ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
TDiskResponsivenessTracker::TPerDiskStatsPtr stats,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters,
bool enableRequestMod3x3ForMinLatecy)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
- NKikimrServices::BS_PROXY_PUT, false, latencyQueueKind, now, storagePoolCounters,
- ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ NKikimrServices::BS_PROXY_PUT, false, latencyQueueKind, now, storagePoolCounters,
+ ev->RestartCounter)
, PutImpl(info, state, ev, mon, enableRequestMod3x3ForMinLatecy)
, WaitingVDiskResponseCount(info->GetTotalVDisksNum())
, Deadline(ev->Deadline)
, StartTime(now)
, HandleClass(ev->HandleClass)
, ReportedBytes(0)
- , TimeStatsEnabled(timeStatsEnabled)
+ , TimeStatsEnabled(timeStatsEnabled)
, Tactic(ev->Tactic)
- , Stats(std::move(stats))
+ , Stats(std::move(stats))
, IsAccelerated(false)
, IsAccelerateScheduled(false)
, IsMultiPutMode(false)
@@ -473,22 +473,22 @@ public:
LWPROBE(DSProxyBlobPutTactics, ItemsInfo[0].BlobId.TabletID(), Info->GroupID, ItemsInfo[0].BlobId.ToString(),
Tactic, NKikimrBlobStorage::EPutHandleClass_Name(HandleClass));
ReportBytes(ItemsInfo[0].Buffer.capacity() + sizeof(*this));
-
+
RequestBytes = ev->Buffer.size();
RequestHandleClass = HandleClassToHandleClass(HandleClass);
MaxSaneRequests = info->Type.TotalPartCount() * (1ull + info->Type.Handoff()) * 2;
}
- ui32 MaxRestartCounter(const TBatchedVec<TEvBlobStorage::TEvPut::TPtr>& events) {
- ui32 res = 0;
- for (const auto& ev : events) {
- res = Max(res, ev->Get()->RestartCounter);
- }
- return res;
- }
-
+ ui32 MaxRestartCounter(const TBatchedVec<TEvBlobStorage::TEvPut::TPtr>& events) {
+ ui32 res = 0;
+ for (const auto& ev : events) {
+ res = Max(res, ev->Get()->RestartCounter);
+ }
+ return res;
+ }
+
TBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state,
+ const TIntrusivePtr<TGroupQueues> &state,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &events,
bool timeStatsEnabled, TDiskResponsivenessTracker::TPerDiskStatsPtr stats,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
@@ -496,8 +496,8 @@ public:
NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic,
bool enableRequestMod3x3ForMinLatecy)
: TBlobStorageGroupRequestActor(info, state, mon, TActorId(), 0, NWilson::TTraceId(),
- NKikimrServices::BS_PROXY_PUT, false, latencyQueueKind, now, storagePoolCounters,
- MaxRestartCounter(events))
+ NKikimrServices::BS_PROXY_PUT, false, latencyQueueKind, now, storagePoolCounters,
+ MaxRestartCounter(events))
, PutImpl(info, state, events, mon, handleClass, tactic, enableRequestMod3x3ForMinLatecy)
, WaitingVDiskResponseCount(info->GetTotalVDisksNum())
, IsManyPuts(true)
@@ -545,17 +545,17 @@ public:
ReportedBytes += bytes;
}
- void Bootstrap() {
- A_LOG_INFO_S("BPP13", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
+ void Bootstrap() {
+ A_LOG_INFO_S("BPP13", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
<< " BlobCount# " << ItemsInfo.size()
<< " BlobIDs# " << BlobIdSequenceToString()
- << " HandleClass# " << NKikimrBlobStorage::EPutHandleClass_Name(HandleClass)
+ << " HandleClass# " << NKikimrBlobStorage::EPutHandleClass_Name(HandleClass)
<< " Tactic# " << TEvBlobStorage::TEvPut::TacticName(Tactic)
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
for (ui64 blobIdx = 0; blobIdx < ItemsInfo.size(); ++blobIdx) {
LWTRACK(DSProxyPutBootstrapStart, ItemsInfo[blobIdx].Orbit);
}
@@ -563,13 +563,13 @@ public:
Become(&TThis::StateWait);
Timer.Reset();
-
+
// TODO: how correct rewrite this?
WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvPutReceived, Size = RequestBytes,
LogoBlobId = ItemsInfo[0].BlobId);
-
+
double wilsonSec = Timer.PassedReset();
-
+
const ui32 totalParts = Info->Type.TotalPartCount();
TAutoPtr<TEvResume> resume(new TEvResume());
@@ -603,17 +603,17 @@ public:
if (RequestBytes < BufferSizeThreshold) {
ResumeBootstrap(resume);
} else {
- Send(SelfId(), resume.Release());
+ Send(SelfId(), resume.Release());
for (ui64 blobIdx = 0; blobIdx < ItemsInfo.size(); ++blobIdx) {
LWTRACK(DSProxyPutPauseBootstrap, ItemsInfo[blobIdx].Orbit);
}
}
- Schedule(TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
- SanityCheck(); // May Die
+ Schedule(TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
+ SanityCheck(); // May Die
}
- void Handle(TEvResume::TPtr &ev) {
+ void Handle(TEvResume::TPtr &ev) {
if (ev->Get()->Count == 0) {
// Record only the first resume to keep tracks structure simple
for (ui64 blobIdx = 0; blobIdx < ItemsInfo.size(); ++blobIdx) {
@@ -621,27 +621,27 @@ public:
}
}
ResumeBootstrap(ev->Release());
- SanityCheck(); // May Die
+ SanityCheck(); // May Die
}
- void Handle(TKikimrEvents::TEvWakeup::TPtr &ev) {
+ void Handle(TKikimrEvents::TEvWakeup::TPtr &ev) {
Y_UNUSED(ev);
A_LOG_WARN_S("BPP14", "Wakeup "
- << " ActorId# " << SelfId()
+ << " ActorId# " << SelfId()
<< " Group# " << Info->GroupID
<< " BlobIDs# " << BlobIdSequenceToString()
<< " Not answered in "
<< (TActivationContext::Now() - StartTime).Seconds() << " seconds");
if (TInstant::Now() > Deadline) {
ErrorReason = "Deadline exceeded";
- ReplyAndDie(NKikimrProto::DEADLINE);
+ ReplyAndDie(NKikimrProto::DEADLINE);
return;
}
- Schedule(TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
+ Schedule(TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
}
template <typename TPutEvent, typename TCookie>
- void UpdatePengingVDiskResponseCount(const TDeque<std::unique_ptr<TPutEvent>> &putEvents) {
+ void UpdatePengingVDiskResponseCount(const TDeque<std::unique_ptr<TPutEvent>> &putEvents) {
for (auto &event : putEvents) {
Y_VERIFY(event->Record.HasCookie());
TCookie cookie(event->Record.GetCookie());
@@ -687,14 +687,14 @@ public:
resume->WaitSec * 1000.0, resume->SplitSec * 1000.0, resume->Count, blobIdx);
}
if (IsMultiPutMode) {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts;
PutImpl.GenerateInitialRequests(LogCtx, resume->PartSets, vMultiPuts);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVMultiPut, TVMultiPutCookie>(vMultiPuts);
RequestsSent += vMultiPuts.size();
CountPuts(vMultiPuts);
SendToQueues(vMultiPuts, TimeStatsEnabled);
} else {
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
PutImpl.GenerateInitialRequests(LogCtx, resume->PartSets, vPuts);
UpdatePengingVDiskResponseCount<TEvBlobStorage::TEvVPut, TBlobCookie>(vPuts);
RequestsSent += vPuts.size();
@@ -706,34 +706,34 @@ public:
}
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVPutResult, Handle);
- hFunc(TEvBlobStorage::TEvVMultiPutResult, Handle);
- hFunc(TEvAccelerate, Handle);
- hFunc(TEvResume, Handle);
- hFunc(TKikimrEvents::TEvWakeup, Handle);
+ hFunc(TEvBlobStorage::TEvVPutResult, Handle);
+ hFunc(TEvBlobStorage::TEvVMultiPutResult, Handle);
+ hFunc(TEvAccelerate, Handle);
+ hFunc(TEvResume, Handle);
+ hFunc(TKikimrEvents::TEvWakeup, Handle);
}
}
};
IActor* CreateBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvPut *ev,
- ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
+ ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled,
TDiskResponsivenessTracker::TPerDiskStatsPtr stats,
TMaybe<TGroupStat::EKind> latencyQueueKind, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters,
bool enableRequestMod3x3ForMinLatecy) {
- return new TBlobStorageGroupPutRequest(info, state, source, mon, ev, cookie, std::move(traceId), timeStatsEnabled,
+ return new TBlobStorageGroupPutRequest(info, state, source, mon, ev, cookie, std::move(traceId), timeStatsEnabled,
std::move(stats), latencyQueueKind, now, storagePoolCounters, enableRequestMod3x3ForMinLatecy);
}
IActor* CreateBlobStorageGroupPutRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state,
+ const TIntrusivePtr<TGroupQueues> &state,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &ev,
bool timeStatsEnabled,
TDiskResponsivenessTracker::TPerDiskStatsPtr stats,
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.cpp
index 70b774636ca..8b91baede26 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.cpp
@@ -12,21 +12,21 @@ namespace NKikimr {
using TPutResultVec = TPutImpl::TPutResultVec;
bool TPutImpl::RunStrategies(TLogContext &logCtx, TPutResultVec &outPutResults) {
- switch (Info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
+ switch (Info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
return RunStrategy(logCtx, TPut3dcStrategy(Tactic, EnableRequestMod3x3ForMinLatecy), outPutResults);
- case TBlobStorageGroupType::ErasureMirror3of4:
- return RunStrategy(logCtx, TPut3of4Strategy(Tactic), outPutResults);
- default:
- return RunStrategy(logCtx, TRestoreStrategy(), outPutResults);
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ return RunStrategy(logCtx, TPut3of4Strategy(Tactic), outPutResults);
+ default:
+ return RunStrategy(logCtx, TRestoreStrategy(), outPutResults);
}
}
-bool TPutImpl::RunStrategy(TLogContext &logCtx, const IStrategy& strategy, TPutResultVec &outPutResults) {
- TBatchedVec<TBlackboard::TBlobStates::value_type*> finished;
- const EStrategyOutcome outcome = Blackboard.RunStrategy(logCtx, strategy, &finished);
- if (finished) {
- PrepareReply(logCtx, outcome.ErrorReason, finished, outPutResults);
+bool TPutImpl::RunStrategy(TLogContext &logCtx, const IStrategy& strategy, TPutResultVec &outPutResults) {
+ TBatchedVec<TBlackboard::TBlobStates::value_type*> finished;
+ const EStrategyOutcome outcome = Blackboard.RunStrategy(logCtx, strategy, &finished);
+ if (finished) {
+ PrepareReply(logCtx, outcome.ErrorReason, finished, outPutResults);
return true;
}
return false;
@@ -81,16 +81,16 @@ void TPutImpl::PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logC
}
void TPutImpl::PrepareReply(TLogContext &logCtx, TString errorReason,
- TBatchedVec<TBlackboard::TBlobStates::value_type*>& finished, TPutResultVec &outPutResults) {
+ TBatchedVec<TBlackboard::TBlobStates::value_type*>& finished, TPutResultVec &outPutResults) {
A_LOG_DEBUG_SX(logCtx, "BPP36", "PrepareReply errorReason# " << errorReason);
Y_VERIFY(IsInitialized);
- for (auto item : finished) {
- auto &[blobId, state] = *item;
- const ui64 idx = state.BlobIdx;
+ for (auto item : finished) {
+ auto &[blobId, state] = *item;
+ const ui64 idx = state.BlobIdx;
Y_VERIFY(blobId == BlobIds[idx], "BlobIdx# %" PRIu64 " BlobState# %s Blackboard# %s",
idx, state.ToString().c_str(), Blackboard.ToString().c_str());
Y_VERIFY(!IsDone[idx]);
- Y_VERIFY(state.Status != NKikimrProto::UNKNOWN);
+ Y_VERIFY(state.Status != NKikimrProto::UNKNOWN);
outPutResults.emplace_back(idx, new TEvBlobStorage::TEvPutResult(state.Status, blobId, StatusFlags,
Info->GroupID, ApproximateFreeSpaceShare));
outPutResults.back().second->ErrorReason = errorReason;
@@ -98,7 +98,7 @@ void TPutImpl::PrepareReply(TLogContext &logCtx, TString errorReason,
NLog::EPriority priority = GetPriorityForReply(Info->PutErrorMuteChecker, state.Status);
A_LOG_LOG_SX(logCtx, true, priority, "BPP37",
"PrepareReply Result# " << outPutResults.back().second->Print(false));
- MarkBlobAsSent(idx);
+ MarkBlobAsSent(idx);
}
}
@@ -111,7 +111,7 @@ ui64 TPutImpl::GetTimeToAccelerateNs(TLogContext &logCtx) {
// Find the slowest disk
i32 worstSubgroupIdx = -1;
ui64 worstPredictedNs = 0;
- state.GetWorstPredictedDelaysNs(*Info, *Blackboard.GroupQueues, HandleClassToQueueId(Blackboard.PutHandleClass),
+ state.GetWorstPredictedDelaysNs(*Info, *Blackboard.GroupQueues, HandleClassToQueueId(Blackboard.PutHandleClass),
&worstPredictedNs, &nextToWorstPredictedNsVec[idx], &worstSubgroupIdx);
idx++;
}
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.h b/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.h
index 34f675032b5..63c25c2c072 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_put_impl.h
@@ -8,7 +8,7 @@
#include "dsproxy_strategy_accelerate_put_m3dc.h"
#include "dsproxy_strategy_restore.h"
#include "dsproxy_strategy_put_m3dc.h"
-#include "dsproxy_strategy_put_m3of4.h"
+#include "dsproxy_strategy_put_m3of4.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/base/wilson_events.h>
#include <util/generic/set.h>
@@ -19,7 +19,7 @@ class TStrategyBase;
class TPutImpl {
public:
- using TPutResultVec = TBatchedVec<std::pair<ui64, std::unique_ptr<TEvBlobStorage::TEvPutResult>>>;
+ using TPutResultVec = TBatchedVec<std::pair<ui64, std::unique_ptr<TEvBlobStorage::TEvPutResult>>>;
private:
TBlobStorageGroupInfo::TServiceIds VDisksSvc;
@@ -55,7 +55,7 @@ private:
TString ErrorDescription;
public:
- TPutImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &state,
+ TPutImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &state,
TEvBlobStorage::TEvPut *ev, const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon,
bool enableRequestMod3x3ForMinLatecy)
: Deadline(ev->Deadline)
@@ -73,7 +73,7 @@ public:
Y_VERIFY(BlobIds.size() <= MaxBatchedPutRequests);
}
- TPutImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &state,
+ TPutImpl(const TIntrusivePtr<TBlobStorageGroupInfo> &info, const TIntrusivePtr<TGroupQueues> &state,
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &events, const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon,
NKikimrBlobStorage::EPutHandleClass putHandleClass, TEvBlobStorage::TEvPut::ETactic tactic,
bool enableRequestMod3x3ForMinLatecy)
@@ -108,7 +108,7 @@ public:
template <typename TVPutEvent>
void GenerateInitialRequests(TLogContext &logCtx, TBatchedVec<TDataPartSet> &partSets,
- TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
+ TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
Y_UNUSED(logCtx);
Y_VERIFY_S(partSets.size() == BlobIds.size(), "partSets.size# " << partSets.size()
<< " BlobIds.size# " << BlobIds.size());
@@ -334,26 +334,26 @@ public:
void PrepareReply(NKikimrProto::EReplyStatus status, TLogContext &logCtx, TString errorReason,
TPutResultVec &outPutResults);
- void PrepareReply(TLogContext &logCtx, TString errorReason, TBatchedVec<TBlackboard::TBlobStates::value_type*>& finished,
- TPutResultVec &outPutResults);
+ void PrepareReply(TLogContext &logCtx, TString errorReason, TBatchedVec<TBlackboard::TBlobStates::value_type*>& finished,
+ TPutResultVec &outPutResults);
void PrepareOneReply(NKikimrProto::EReplyStatus status, TLogoBlobID blobId, ui64 blobIdx, TLogContext &logCtx,
TString errorReason, TPutResultVec &outPutResults);
-
+
ui64 GetTimeToAccelerateNs(TLogContext &logCtx);
template <typename TVPutEvent>
- void Accelerate(TLogContext &logCtx, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
+ void Accelerate(TLogContext &logCtx, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts) {
Blackboard.ChangeAll();
- switch (Info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
+ switch (Info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
Blackboard.RunStrategy(logCtx, TAcceleratePut3dcStrategy(Tactic, EnableRequestMod3x3ForMinLatecy));
- break;
- case TBlobStorageGroupType::ErasureMirror3of4:
- Blackboard.RunStrategy(logCtx, TPut3of4Strategy(Tactic, true));
- break;
- default:
- Blackboard.RunStrategy(logCtx, TAcceleratePutStrategy());
- break;
+ break;
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ Blackboard.RunStrategy(logCtx, TPut3of4Strategy(Tactic, true));
+ break;
+ default:
+ Blackboard.RunStrategy(logCtx, TAcceleratePutStrategy());
+ break;
}
PrepareVPuts(logCtx, outVPuts);
}
@@ -367,11 +367,11 @@ public:
protected:
bool RunStrategies(TLogContext &logCtx, TPutResultVec &outPutResults);
- bool RunStrategy(TLogContext &logCtx, const IStrategy& strategy, TPutResultVec &outPutResults);
+ bool RunStrategy(TLogContext &logCtx, const IStrategy& strategy, TPutResultVec &outPutResults);
// Returns true if there are additional requests to send
template <typename TVPutEvent>
- bool Step(TLogContext &logCtx, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts,
+ bool Step(TLogContext &logCtx, TDeque<std::unique_ptr<TVPutEvent>> &outVPuts,
TPutResultVec &outPutResults) {
if (!RunStrategies(logCtx, outPutResults)) {
const ui32 numRequests = outVPuts.size();
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h b/ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h
index 9ce43372fda..dcc2de336b3 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
-namespace NKikimr {
-
- class TGroupQuorumTracker {
- const TBlobStorageGroupInfo *Info;
-
- // a set of disks that replied successfully (with OK)
- TBlobStorageGroupInfo::TGroupVDisks SuccessfulDisks;
-
- // a set of disks that replied with error (not OK, suddenly)
- TBlobStorageGroupInfo::TGroupVDisks ErroneousDisks;
-
- // per-vdisk record for VDisks that replied with success
- struct TVDiskInfo {
- TInstant ExpireTimestamp; // when the disk successful response expires
- std::optional<ui64> IncarnationGuid;
- };
- std::map<TVDiskID, TVDiskInfo> VDiskMap;
- ui32 NumResendsRemain;
- ui32 NumStatusRemain;
-
- public:
- TGroupQuorumTracker(const TBlobStorageGroupInfo *info)
- : Info(info)
+
+namespace NKikimr {
+
+ class TGroupQuorumTracker {
+ const TBlobStorageGroupInfo *Info;
+
+ // a set of disks that replied successfully (with OK)
+ TBlobStorageGroupInfo::TGroupVDisks SuccessfulDisks;
+
+ // a set of disks that replied with error (not OK, suddenly)
+ TBlobStorageGroupInfo::TGroupVDisks ErroneousDisks;
+
+ // per-vdisk record for VDisks that replied with success
+ struct TVDiskInfo {
+ TInstant ExpireTimestamp; // when the disk successful response expires
+ std::optional<ui64> IncarnationGuid;
+ };
+ std::map<TVDiskID, TVDiskInfo> VDiskMap;
+ ui32 NumResendsRemain;
+ ui32 NumStatusRemain;
+
+ public:
+ TGroupQuorumTracker(const TBlobStorageGroupInfo *info)
+ : Info(info)
, SuccessfulDisks(&Info->GetTopology())
, ErroneousDisks(&Info->GetTopology())
- , NumResendsRemain(Info->GetTotalVDisksNum())
- , NumStatusRemain(2 * Info->GetTotalVDisksNum())
- {}
-
+ , NumResendsRemain(Info->GetTotalVDisksNum())
+ , NumStatusRemain(2 * Info->GetTotalVDisksNum())
+ {}
+
void Output(IOutputStream &out) {
out << "{Erroneous# ";
ErroneousDisks.Output(out);
@@ -47,74 +47,74 @@ namespace NKikimr {
return str.Str();
}
- NKikimrProto::EReplyStatus ProcessReply(const TVDiskID& from, NKikimrProto::EReplyStatus status) {
- // should be handled in CheckForTermErrors
- Y_VERIFY(status != NKikimrProto::RACE && status != NKikimrProto::BLOCKED && status != NKikimrProto::DEADLINE);
-
- Y_VERIFY(status == NKikimrProto::OK || status == NKikimrProto::ERROR ||
- status == NKikimrProto::VDISK_ERROR_STATE || status == NKikimrProto::OUT_OF_SPACE,
- "unexpected status# %s", NKikimrProto::EReplyStatus_Name(status).data());
-
- const auto& mask = TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), from);
- if (status == NKikimrProto::OK) {
- SuccessfulDisks |= mask;
- ErroneousDisks -= mask;
- } else {
- ErroneousDisks |= mask;
- SuccessfulDisks -= mask;
- }
-
- return CalculateStatus();
- }
-
- NKikimrProto::EReplyStatus CalculateStatus() {
- const auto& checker = Info->GetQuorumChecker();
- return !checker.CheckFailModelForGroup(ErroneousDisks) ? NKikimrProto::ERROR :
- checker.CheckQuorumForGroup(SuccessfulDisks) ? NKikimrProto::OK :
- NKikimrProto::UNKNOWN;
- }
-
- NKikimrProto::EReplyStatus ProcessReplyWithCooldown(const TVDiskID& from, NKikimrProto::EReplyStatus status,
- TInstant now, ui64 incarnationGuid, std::vector<TVDiskID>& queryStatus, std::vector<TVDiskID>& resend) {
- if (status == NKikimrProto::OK) {
- auto& info = VDiskMap[from];
- info.ExpireTimestamp = now + VDiskCooldownTimeoutOnProxy;
- if (!info.IncarnationGuid) {
- info.IncarnationGuid = incarnationGuid;
- } else if (*info.IncarnationGuid != incarnationGuid) {
- if (NumResendsRemain) {
- --NumResendsRemain;
- resend.push_back(from);
- VDiskMap.erase(from);
- return NKikimrProto::UNKNOWN;
- } else {
- status = NKikimrProto::ERROR;
- }
- }
- }
-
- status = ProcessReply(from, status);
- if (status == NKikimrProto::OK) {
- for (auto& [vdiskId, info] : VDiskMap) {
- if (info.ExpireTimestamp <= now) {
- const auto& mask = TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdiskId);
- SuccessfulDisks -= mask;
- info.ExpireTimestamp = TInstant::Max();
- status = NKikimrProto::UNKNOWN;
- if (NumStatusRemain) {
- --NumStatusRemain;
- queryStatus.push_back(vdiskId);
- } else {
- ErroneousDisks += mask;
- }
- }
- }
- if (status == NKikimrProto::UNKNOWN) {
- status = CalculateStatus();
- }
- }
- return status;
- }
- };
-
-} // NKikimr
+ NKikimrProto::EReplyStatus ProcessReply(const TVDiskID& from, NKikimrProto::EReplyStatus status) {
+ // should be handled in CheckForTermErrors
+ Y_VERIFY(status != NKikimrProto::RACE && status != NKikimrProto::BLOCKED && status != NKikimrProto::DEADLINE);
+
+ Y_VERIFY(status == NKikimrProto::OK || status == NKikimrProto::ERROR ||
+ status == NKikimrProto::VDISK_ERROR_STATE || status == NKikimrProto::OUT_OF_SPACE,
+ "unexpected status# %s", NKikimrProto::EReplyStatus_Name(status).data());
+
+ const auto& mask = TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), from);
+ if (status == NKikimrProto::OK) {
+ SuccessfulDisks |= mask;
+ ErroneousDisks -= mask;
+ } else {
+ ErroneousDisks |= mask;
+ SuccessfulDisks -= mask;
+ }
+
+ return CalculateStatus();
+ }
+
+ NKikimrProto::EReplyStatus CalculateStatus() {
+ const auto& checker = Info->GetQuorumChecker();
+ return !checker.CheckFailModelForGroup(ErroneousDisks) ? NKikimrProto::ERROR :
+ checker.CheckQuorumForGroup(SuccessfulDisks) ? NKikimrProto::OK :
+ NKikimrProto::UNKNOWN;
+ }
+
+ NKikimrProto::EReplyStatus ProcessReplyWithCooldown(const TVDiskID& from, NKikimrProto::EReplyStatus status,
+ TInstant now, ui64 incarnationGuid, std::vector<TVDiskID>& queryStatus, std::vector<TVDiskID>& resend) {
+ if (status == NKikimrProto::OK) {
+ auto& info = VDiskMap[from];
+ info.ExpireTimestamp = now + VDiskCooldownTimeoutOnProxy;
+ if (!info.IncarnationGuid) {
+ info.IncarnationGuid = incarnationGuid;
+ } else if (*info.IncarnationGuid != incarnationGuid) {
+ if (NumResendsRemain) {
+ --NumResendsRemain;
+ resend.push_back(from);
+ VDiskMap.erase(from);
+ return NKikimrProto::UNKNOWN;
+ } else {
+ status = NKikimrProto::ERROR;
+ }
+ }
+ }
+
+ status = ProcessReply(from, status);
+ if (status == NKikimrProto::OK) {
+ for (auto& [vdiskId, info] : VDiskMap) {
+ if (info.ExpireTimestamp <= now) {
+ const auto& mask = TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdiskId);
+ SuccessfulDisks -= mask;
+ info.ExpireTimestamp = TInstant::Max();
+ status = NKikimrProto::UNKNOWN;
+ if (NumStatusRemain) {
+ --NumStatusRemain;
+ queryStatus.push_back(vdiskId);
+ } else {
+ ErroneousDisks += mask;
+ }
+ }
+ }
+ if (status == NKikimrProto::UNKNOWN) {
+ status = CalculateStatus();
+ }
+ }
+ return status;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_range.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_range.cpp
index e234f8c18e1..515ba67c7af 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_range.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_range.cpp
@@ -1,7 +1,7 @@
-#include "dsproxy.h"
-#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
-#include "dsproxy_blob_tracker.h"
+#include "dsproxy.h"
+#include "dsproxy_mon.h"
+#include "dsproxy_quorum_tracker.h"
+#include "dsproxy_blob_tracker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/base/wilson_events.h>
@@ -14,398 +14,398 @@ namespace NKikimr {
// RANGE request
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class TBlobStorageGroupRangeRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupRangeRequest> {
+class TBlobStorageGroupRangeRequest : public TBlobStorageGroupRequestActor<TBlobStorageGroupRangeRequest> {
static constexpr ui32 MaxBlobsToQueryAtOnce = 8096;
-
+
const ui64 TabletId;
const TLogoBlobID From;
const TLogoBlobID To;
const TInstant Deadline;
const bool MustRestoreFirst;
- const bool IsIndexOnly;
+ const bool IsIndexOnly;
const ui32 ForceBlockedGeneration;
TInstant StartTime;
TAutoPtr<TEvBlobStorage::TEvRangeResult> Reply;
TMap<TLogoBlobID, TBlobStatusTracker> BlobStatus;
- TBlobStorageGroupInfo::TGroupVDisks FailedDisks;
-
- ui32 NumVGetsPending = 0;
-
- struct TBlobQueryItem {
- TLogoBlobID BlobId;
- bool RequiredToBePresent;
-
- TBlobQueryItem(const TLogoBlobID& blobId, bool requiredToBePresent)
- : BlobId(blobId)
- , RequiredToBePresent(requiredToBePresent)
- {}
- };
+ TBlobStorageGroupInfo::TGroupVDisks FailedDisks;
+
+ ui32 NumVGetsPending = 0;
+
+ struct TBlobQueryItem {
+ TLogoBlobID BlobId;
+ bool RequiredToBePresent;
+
+ TBlobQueryItem(const TLogoBlobID& blobId, bool requiredToBePresent)
+ : BlobId(blobId)
+ , RequiredToBePresent(requiredToBePresent)
+ {}
+ };
TVector<TBlobQueryItem> BlobsToGet;
-
- template<typename TPtr>
- void SendReply(TPtr& reply) {
- ui32 size = 0;
- for (const TEvBlobStorage::TEvRangeResult::TResponse& resp : reply->Responses) {
+
+ template<typename TPtr>
+ void SendReply(TPtr& reply) {
+ ui32 size = 0;
+ for (const TEvBlobStorage::TEvRangeResult::TResponse& resp : reply->Responses) {
size += resp.Buffer.size();
- }
- Mon->CountRangeResponseTime(TActivationContext::Now() - StartTime);
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, RangeGetResultSent, ReplyStatus = reply->Status, ResponseSize = size);
- SendResponseAndDie(std::move(reply));
- }
-
- void SendQueryToVDisk(const TVDiskID &vdisk, const TLogoBlobID &from, const TLogoBlobID &to) {
- // prepare new index query message
- auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdisk, Deadline, NKikimrBlobStorage::EGetHandleClass::FastRead,
+ }
+ Mon->CountRangeResponseTime(TActivationContext::Now() - StartTime);
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, RangeGetResultSent, ReplyStatus = reply->Status, ResponseSize = size);
+ SendResponseAndDie(std::move(reply));
+ }
+
+ void SendQueryToVDisk(const TVDiskID &vdisk, const TLogoBlobID &from, const TLogoBlobID &to) {
+ // prepare new index query message
+ auto msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdisk, Deadline, NKikimrBlobStorage::EGetHandleClass::FastRead,
TEvBlobStorage::TEvVGet::EFlags::ShowInternals, {}, from, to, MaxBlobsToQueryAtOnce, nullptr,
ForceBlockedGeneration);
-
- // disable barrier checking
- msg->Record.SetSuppressBarrierCheck(true);
-
- // trace message and send it to queue
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
- CountEvent(*msg);
- SendToQueue(std::move(msg), 0, TraceId.SeparateBranch());
-
- // add pending count
- ++NumVGetsPending;
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- CountEvent(*ev->Get());
-
- const auto& record = ev->Get()->Record;
+
+ // disable barrier checking
+ msg->Record.SetSuppressBarrierCheck(true);
+
+ // trace message and send it to queue
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetSent);
+ CountEvent(*msg);
+ SendToQueue(std::move(msg), 0, TraceId.SeparateBranch());
+
+ // add pending count
+ ++NumVGetsPending;
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ CountEvent(*ev->Get());
+
+ const auto& record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
NKikimrProto::EReplyStatus status = record.GetStatus();
- Y_VERIFY(record.HasVDiskID());
- const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
-
- A_LOG_DEBUG_S("DSR01", "received"
- << " VDiskId# " << vdisk
- << " TEvVGetResult# " << ev->Get()->ToString());
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
-
- Y_VERIFY(NumVGetsPending > 0);
- --NumVGetsPending;
-
+ Y_VERIFY(record.HasVDiskID());
+ const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
+
+ A_LOG_DEBUG_S("DSR01", "received"
+ << " VDiskId# " << vdisk
+ << " TEvVGetResult# " << ev->Get()->ToString());
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvVGetResultReceived, MergedNode = std::move(ev->TraceId));
+
+ Y_VERIFY(NumVGetsPending > 0);
+ --NumVGetsPending;
+
bool isOk = status == NKikimrProto::OK;
- switch (status) {
- case NKikimrProto::ERROR:
- case NKikimrProto::VDISK_ERROR_STATE:
- case NKikimrProto::OUT_OF_SPACE:
- FailedDisks |= TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdisk);
- if (!Info->GetQuorumChecker().CheckFailModelForGroup(FailedDisks)) {
- return ReplyAndDie(NKikimrProto::ERROR);
- }
- break;
-
- case NKikimrProto::OK:
+ switch (status) {
+ case NKikimrProto::ERROR:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ case NKikimrProto::OUT_OF_SPACE:
+ FailedDisks |= TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdisk);
+ if (!Info->GetQuorumChecker().CheckFailModelForGroup(FailedDisks)) {
+ return ReplyAndDie(NKikimrProto::ERROR);
+ }
+ break;
+
+ case NKikimrProto::OK:
if (record.ResultSize() == 0 && record.GetIsRangeOverflow()) {
isOk = false;
A_LOG_CRIT_S("DSR09", "Don't know how to interpret an empty range with IsRangeOverflow set." <<
" TEvVGetResult# " << ev->Get()->ToString());
FailedDisks |= TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdisk);
if (!Info->GetQuorumChecker().CheckFailModelForGroup(FailedDisks)) {
- return ReplyAndDie(NKikimrProto::ERROR);
+ return ReplyAndDie(NKikimrProto::ERROR);
}
}
- break;
+ break;
- default:
+ default:
Y_FAIL("unexpected queryStatus# %s", NKikimrProto::EReplyStatus_Name(status).data());
}
if (isOk) {
TLogoBlobID lastBlobId = From;
- for (const NKikimrBlobStorage::TQueryResult& blob : record.GetResult()) {
- Y_VERIFY(blob.HasBlobID());
- const TLogoBlobID blobId(LogoBlobIDFromLogoBlobID(blob.GetBlobID()));
- const TLogoBlobID fullId(blobId.FullID());
-
- // as this is index only query, we operate only with full blob ids, not using parts
- Y_VERIFY(blobId == fullId);
-
- auto it = BlobStatus.find(fullId);
- if (it == BlobStatus.end()) {
- it = BlobStatus.emplace(fullId, TBlobStatusTracker(fullId, Info.Get())).first;
- }
- it->second.UpdateFromResponseData(blob, vdisk, Info.Get());
-
+ for (const NKikimrBlobStorage::TQueryResult& blob : record.GetResult()) {
+ Y_VERIFY(blob.HasBlobID());
+ const TLogoBlobID blobId(LogoBlobIDFromLogoBlobID(blob.GetBlobID()));
+ const TLogoBlobID fullId(blobId.FullID());
+
+ // as this is index only query, we operate only with full blob ids, not using parts
+ Y_VERIFY(blobId == fullId);
+
+ auto it = BlobStatus.find(fullId);
+ if (it == BlobStatus.end()) {
+ it = BlobStatus.emplace(fullId, TBlobStatusTracker(fullId, Info.Get())).first;
+ }
+ it->second.UpdateFromResponseData(blob, vdisk, Info.Get());
+
Y_VERIFY(From <= To ? lastBlobId <= fullId : lastBlobId >= fullId,
"Blob IDs are out of order in TEvVGetResult");
- // remember last processed blob id to resume query
- lastBlobId = fullId;
+ // remember last processed blob id to resume query
+ lastBlobId = fullId;
}
-
- // check if the response was full -- this means that we (may) have to continue querying
+
+ // check if the response was full -- this means that we (may) have to continue querying
if (record.ResultSize() >= MaxBlobsToQueryAtOnce || record.GetIsRangeOverflow()) {
- TLogoBlobID from(From), to(To);
- bool send = true;
-
- ui32 cookie = lastBlobId.Cookie();
- ui32 step = lastBlobId.Step();
- ui32 generation = lastBlobId.Generation();
- ui8 channel = lastBlobId.Channel();
-
- if (from <= to) {
- // forward query; we have to patch 'from' with successor of lastBlobId
- if (cookie++ == TLogoBlobID::MaxCookie) {
- cookie = 0; // overflow -- reset to zero
- if (step++ == Max<ui32>()) { // if the step was maximum possible, it is reset to zero
- if (generation++ == Max<ui32>()) {
- if (channel++ == Max<ui8>()) {
- send = false;
- }
- }
- }
- }
-
- from = TLogoBlobID(TabletId, generation, step, channel, 0 /* blobSize */, cookie);
- send = send && from <= to;
- } else {
- // backward query; we have to patch 'to' with predecessor of lastBlobId
- if (!cookie--) {
- cookie = TLogoBlobID::MaxCookie;
- if (!step--) { // if the step was zero, it is set to Max<ui32> automatically and so for generation
- if (!generation--) {
- if (!channel--) {
- send = false;
- }
- }
- }
- }
-
+ TLogoBlobID from(From), to(To);
+ bool send = true;
+
+ ui32 cookie = lastBlobId.Cookie();
+ ui32 step = lastBlobId.Step();
+ ui32 generation = lastBlobId.Generation();
+ ui8 channel = lastBlobId.Channel();
+
+ if (from <= to) {
+ // forward query; we have to patch 'from' with successor of lastBlobId
+ if (cookie++ == TLogoBlobID::MaxCookie) {
+ cookie = 0; // overflow -- reset to zero
+ if (step++ == Max<ui32>()) { // if the step was maximum possible, it is reset to zero
+ if (generation++ == Max<ui32>()) {
+ if (channel++ == Max<ui8>()) {
+ send = false;
+ }
+ }
+ }
+ }
+
+ from = TLogoBlobID(TabletId, generation, step, channel, 0 /* blobSize */, cookie);
+ send = send && from <= to;
+ } else {
+ // backward query; we have to patch 'to' with predecessor of lastBlobId
+ if (!cookie--) {
+ cookie = TLogoBlobID::MaxCookie;
+ if (!step--) { // if the step was zero, it is set to Max<ui32> automatically and so for generation
+ if (!generation--) {
+ if (!channel--) {
+ send = false;
+ }
+ }
+ }
+ }
+
from = TLogoBlobID(TabletId, generation, step, channel, TLogoBlobID::MaxBlobSize, cookie);
- send = send && to < from;
- }
-
- if (send) {
- SendQueryToVDisk(vdisk, from, to);
- }
- }
+ send = send && to < from;
+ }
+
+ if (send) {
+ SendQueryToVDisk(vdisk, from, to);
+ }
+ }
}
- if (!NumVGetsPending) {
- for (const auto& item : BlobStatus) {
- const TBlobStatusTracker& tracker = item.second;
- bool lostByIngress = false;
- bool requiredToBePresent = false;
- switch (tracker.GetBlobState(Info.Get(), &lostByIngress)) {
- case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
- R_LOG_ERROR_S("DSR02", "disintegrated");
- return ReplyAndDie(NKikimrProto::ERROR);
-
- case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
- // try to recover, but this try will fail; in case when we see that blob was confirmed, we
- // issue an error to tablet
- requiredToBePresent = lostByIngress && IngressAsAReasonForErrorEnabled;
- break;
-
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
- // blob is recoverable so we recover it
- requiredToBePresent = true;
- break;
-
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
- // there are doubts about blob's origin, we assume that it haven't been confirmed to writer
- break;
-
- case TBlobStorageGroupInfo::EBS_FULL:
- // the blob is full so it should be successfully read
- requiredToBePresent = true;
- break;
- }
-
- BlobsToGet.emplace_back(item.first, requiredToBePresent);
- }
-
- // send request
- if (BlobsToGet) {
- SendGetRequest();
- } else {
- // reply with empty set
- ReplyAndDie(NKikimrProto::OK);
+ if (!NumVGetsPending) {
+ for (const auto& item : BlobStatus) {
+ const TBlobStatusTracker& tracker = item.second;
+ bool lostByIngress = false;
+ bool requiredToBePresent = false;
+ switch (tracker.GetBlobState(Info.Get(), &lostByIngress)) {
+ case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
+ R_LOG_ERROR_S("DSR02", "disintegrated");
+ return ReplyAndDie(NKikimrProto::ERROR);
+
+ case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
+ // try to recover, but this try will fail; in case when we see that blob was confirmed, we
+ // issue an error to tablet
+ requiredToBePresent = lostByIngress && IngressAsAReasonForErrorEnabled;
+ break;
+
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
+ // blob is recoverable so we recover it
+ requiredToBePresent = true;
+ break;
+
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
+ // there are doubts about blob's origin, we assume that it haven't been confirmed to writer
+ break;
+
+ case TBlobStorageGroupInfo::EBS_FULL:
+ // the blob is full so it should be successfully read
+ requiredToBePresent = true;
+ break;
+ }
+
+ BlobsToGet.emplace_back(item.first, requiredToBePresent);
+ }
+
+ // send request
+ if (BlobsToGet) {
+ SendGetRequest();
+ } else {
+ // reply with empty set
+ ReplyAndDie(NKikimrProto::OK);
}
}
}
- void SendGetRequest() {
- // build array of queries to send to DS proxy
- const ui32 queryCount = BlobsToGet.size();
+ void SendGetRequest() {
+ // build array of queries to send to DS proxy
+ const ui32 queryCount = BlobsToGet.size();
TArrayHolder<TEvBlobStorage::TEvGet::TQuery> queries(new TEvBlobStorage::TEvGet::TQuery[queryCount]);
- TEvBlobStorage::TEvGet::TQuery *query = queries.Get();
- for (const TBlobQueryItem& item : BlobsToGet) {
+ TEvBlobStorage::TEvGet::TQuery *query = queries.Get();
+ for (const TBlobQueryItem& item : BlobsToGet) {
query->Set(item.BlobId, 0, 0);
- ++query;
+ ++query;
}
- Y_VERIFY(query == queries.Get() + queryCount);
+ Y_VERIFY(query == queries.Get() + queryCount);
- // register query in wilson and send it to DS proxy
- auto get = std::make_unique<TEvBlobStorage::TEvGet>(queries, queryCount, Deadline,
+ // register query in wilson and send it to DS proxy
+ auto get = std::make_unique<TEvBlobStorage::TEvGet>(queries, queryCount, Deadline,
NKikimrBlobStorage::EGetHandleClass::FastRead, MustRestoreFirst, IsIndexOnly, ForceBlockedGeneration);
- get->IsInternal = true;
-
- A_LOG_DEBUG_S("DSR08", "sending TEvGet# " << get->ToString());
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
- SendToBSProxy(SelfId(), Info->GroupID, get.release(), 0, TraceId.SeparateBranch());
-
- // switch state
+ get->IsInternal = true;
+
+ A_LOG_DEBUG_S("DSR08", "sending TEvGet# " << get->ToString());
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetSent);
+ SendToBSProxy(SelfId(), Info->GroupID, get.release(), 0, TraceId.SeparateBranch());
+
+ // switch state
Become(&TThis::StateGet);
}
TString DumpBlobsToGet() const {
- TStringStream str("[");
- for (ui32 i = 0; i < BlobsToGet.size(); ++i) {
- str << (i ? " " : "")
- << BlobsToGet[i].BlobId.ToString() << "/"
- << (BlobsToGet[i].RequiredToBePresent ? "true" : "false");
- }
- str << "]";
- return str.Str();
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
-
+ TStringStream str("[");
+ for (ui32 i = 0; i < BlobsToGet.size(); ++i) {
+ str << (i ? " " : "")
+ << BlobsToGet[i].BlobId.ToString() << "/"
+ << (BlobsToGet[i].RequiredToBePresent ? "true" : "false");
+ }
+ str << "]";
+ return str.Str();
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev) {
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, EvGetResultReceived, MergedNode = std::move(ev->TraceId));
+
TEvBlobStorage::TEvGetResult &getResult = *ev->Get();
NKikimrProto::EReplyStatus status = getResult.Status;
if (status != NKikimrProto::OK) {
R_LOG_ERROR_S("DSR03", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status).data());
- ReplyAndDie(status);
+ ReplyAndDie(status);
return;
}
- std::unique_ptr<TEvBlobStorage::TEvRangeResult> result(new TEvBlobStorage::TEvRangeResult(status, From, To, Info->GroupID));
+ std::unique_ptr<TEvBlobStorage::TEvRangeResult> result(new TEvBlobStorage::TEvRangeResult(status, From, To, Info->GroupID));
result->Responses.reserve(getResult.ResponseSz);
- Y_VERIFY(getResult.ResponseSz == BlobsToGet.size());
+ Y_VERIFY(getResult.ResponseSz == BlobsToGet.size());
for (ui32 i = 0; i < getResult.ResponseSz; ++i) {
TEvBlobStorage::TEvGetResult::TResponse &response = getResult.Responses[i];
- Y_VERIFY(response.Id == BlobsToGet[i].BlobId);
-
+ Y_VERIFY(response.Id == BlobsToGet[i].BlobId);
+
if (getResult.Responses[i].Status == NKikimrProto::OK) {
result->Responses.emplace_back(response.Id, response.Buffer);
- } else if (getResult.Responses[i].Status != NKikimrProto::NODATA || BlobsToGet[i].RequiredToBePresent) {
- // it's okay to get NODATA if blob wasn't confirmed -- this blob is simply thrown out of resulting
- // set; otherwise we return error about lost data
- R_LOG_ERROR_S("DSR04", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
+ } else if (getResult.Responses[i].Status != NKikimrProto::NODATA || BlobsToGet[i].RequiredToBePresent) {
+ // it's okay to get NODATA if blob wasn't confirmed -- this blob is simply thrown out of resulting
+ // set; otherwise we return error about lost data
+ R_LOG_ERROR_S("DSR04", "Handle TEvGetResult status# " << NKikimrProto::EReplyStatus_Name(status)
<< " Response[" << i << "]# " << NKikimrProto::EReplyStatus_Name(response.Status)
- << " BlobsToGet# " << DumpBlobsToGet()
- << " TEvGetResult# " << ev->Get()->ToString());
- ReplyAndDie(NKikimrProto::ERROR);
+ << " BlobsToGet# " << DumpBlobsToGet()
+ << " TEvGetResult# " << ev->Get()->ToString());
+ ReplyAndDie(NKikimrProto::ERROR);
return;
}
}
- if (To < From) {
- std::reverse(result->Responses.begin(), result->Responses.end());
- }
- A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSR05", "Result# " << result->Print(false));
- SendReply(result);
+ if (To < From) {
+ std::reverse(result->Responses.begin(), result->Responses.end());
+ }
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSR05", "Result# " << result->Print(false));
+ SendReply(result);
}
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- std::unique_ptr<TEvBlobStorage::TEvRangeResult> result(new TEvBlobStorage::TEvRangeResult(
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ std::unique_ptr<TEvBlobStorage::TEvRangeResult> result(new TEvBlobStorage::TEvRangeResult(
status, From, To, Info->GroupID));
result->ErrorReason = ErrorReason;
- A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSR06", "Result# " << result->Print(false));
- SendReply(result);
+ A_LOG_LOG_S(true, PriorityForStatusOutbound(status), "DSR06", "Result# " << result->Print(false));
+ SendReply(result);
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupRangeRequest>;
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartRange;
- auto ev = std::make_unique<TEvBlobStorage::TEvRange>(TabletId, From, To, MustRestoreFirst, Deadline, IsIndexOnly,
- ForceBlockedGeneration);
- ev->RestartCounter = counter;
- return ev;
- }
-
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartRange;
+ auto ev = std::make_unique<TEvBlobStorage::TEvRange>(TabletId, From, To, MustRestoreFirst, Deadline, IsIndexOnly,
+ ForceBlockedGeneration);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GROUP_RANGE;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveRange;
- }
-
- static constexpr ERequestType RequestType() {
- return ERequestType::Range;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GROUP_RANGE;
}
- TBlobStorageGroupRangeRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveRange;
+ }
+
+ static constexpr ERequestType RequestType() {
+ return ERequestType::Range;
+ }
+
+ TBlobStorageGroupRangeRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
- NKikimrServices::BS_PROXY_RANGE, false, {}, now, storagePoolCounters,
- ev->RestartCounter)
- , TabletId(ev->TabletId)
- , From(ev->From)
- , To(ev->To)
- , Deadline(ev->Deadline)
- , MustRestoreFirst(ev->MustRestoreFirst)
- , IsIndexOnly(ev->IsIndexOnly)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, std::move(traceId),
+ NKikimrServices::BS_PROXY_RANGE, false, {}, now, storagePoolCounters,
+ ev->RestartCounter)
+ , TabletId(ev->TabletId)
+ , From(ev->From)
+ , To(ev->To)
+ , Deadline(ev->Deadline)
+ , MustRestoreFirst(ev->MustRestoreFirst)
+ , IsIndexOnly(ev->IsIndexOnly)
, ForceBlockedGeneration(ev->ForceBlockedGeneration)
, StartTime(now)
- , FailedDisks(&Info->GetTopology())
- {}
-
- void Bootstrap() {
- A_LOG_INFO_S("DSR07", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " From# " << From.ToString()
- << " To# " << To.ToString()
- << " Deadline# " << Deadline.ToString()
- << " MustRestoreFirst# " << (MustRestoreFirst ? "true" : "false")
+ , FailedDisks(&Info->GetTopology())
+ {}
+
+ void Bootstrap() {
+ A_LOG_INFO_S("DSR07", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " From# " << From.ToString()
+ << " To# " << To.ToString()
+ << " Deadline# " << Deadline.ToString()
+ << " MustRestoreFirst# " << (MustRestoreFirst ? "true" : "false")
<< " IsIndexOnly# " << (IsIndexOnly ? "true" : "false")
- << " ForceBlockedGeneration# " << ForceBlockedGeneration
- << " RestartCounter# " << RestartCounter);
-
- WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, RangeGetReceived);
-
- // ensure we are querying ranges for the same tablet
- Y_VERIFY(TabletId == From.TabletID());
- Y_VERIFY(TabletId == To.TabletID());
-
- // issue queries to all VDisks
- for (const auto& vdisk : Info->GetVDisks()) {
- SendQueryToVDisk(Info->GetVDiskId(vdisk.OrderNumber), From, To);
+ << " ForceBlockedGeneration# " << ForceBlockedGeneration
+ << " RestartCounter# " << RestartCounter);
+
+ WILSON_TRACE_FROM_ACTOR(*TlsActivationContext, *this, &TraceId, RangeGetReceived);
+
+ // ensure we are querying ranges for the same tablet
+ Y_VERIFY(TabletId == From.TabletID());
+ Y_VERIFY(TabletId == To.TabletID());
+
+ // issue queries to all VDisks
+ for (const auto& vdisk : Info->GetVDisks()) {
+ SendQueryToVDisk(Info->GetVDiskId(vdisk.OrderNumber), From, To);
}
Become(&TThis::StateWait);
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
}
}
- STATEFN(StateGet) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateGet) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupRangeRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
- const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvRange *ev,
ui64 cookie, NWilson::TTraceId traceId, TInstant now,
TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupRangeRequest(info, state, source, mon, ev, cookie, std::move(traceId), now,
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
index 49986464a2f..1c51bbd7a83 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
@@ -1,310 +1,310 @@
-#include "dsproxy_impl.h"
-#include "dsproxy_monactor.h"
-
-namespace NKikimr {
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvGet::TPtr &ev) {
- if (IsLimitedKeyless && !ev->Get()->PhantomCheck) {
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
-
- if (StopGetBatchingEvent) {
- TActivationContext::Send(StopGetBatchingEvent.Release());
- }
- BatchedGetRequestCount++;
-
- EnsureMonitoring(true);
- LWTRACK(DSProxyGetHandle, ev->Get()->Orbit);
- EnableWilsonTracing(ev, Mon->GetSamplePPM);
- TActorId reqID;
- if (ev->Get()->IsIndexOnly) {
- Mon->EventIndexRestoreGet->Inc();
- reqID = Register(
- CreateBlobStorageGroupIndexRestoreGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), {}, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- } else {
- TLogoBlobID lastBlobId;
- const ui32 querySize = ev->Get()->QuerySize;
- TArrayHolder<TEvBlobStorage::TEvGet::TQuery> &queries = ev->Get()->Queries;
- ui32 differentBlobCount = 0;
- TQueryResultSizeTracker resultSize;
- resultSize.Init();
- for (ui32 queryIdx = 0; queryIdx < querySize; ++queryIdx) {
- const TEvBlobStorage::TEvGet::TQuery &query = queries[queryIdx];
- if (lastBlobId == query.Id && queryIdx != 0) {
- continue;
- }
- lastBlobId = query.Id;
- resultSize.AddAllPartsOfLogoBlob(Info->Type, query.Id);
- differentBlobCount++;
- }
- bool isSmall = !resultSize.IsOverflow() && querySize <= 10000;
-
- TMaybe<TGroupStat::EKind> kind;
- switch (ev->Get()->GetHandleClass) {
- case NKikimrBlobStorage::FastRead:
- // do not count async requests and discover requests
- kind = TGroupStat::EKind::GET_FAST;
- break;
-
- default:
- break;
- }
-
- if (differentBlobCount == 1 || isSmall) {
- Mon->EventGet->Inc();
- reqID = Register(
- CreateBlobStorageGroupGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), TNodeLayoutInfoPtr(NodeLayoutInfo),
- kind, TActivationContext::Now(), StoragePoolCounters, false));
- ActiveRequests.insert(reqID);
- } else {
- Mon->EventMultiGet->Inc();
- reqID = Register(
- CreateBlobStorageGroupMultiGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), kind, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
- }
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvPut::TPtr &ev) {
- if (IsLimitedKeyless) {
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
- LWTRACK(DSProxyPutHandle, ev->Get()->Orbit);
- EnsureMonitoring(true);
- const ui64 bytes = ev->Get()->Buffer.size();
- Mon->CountPutEvent(bytes);
- // Make sure actual data size matches one in the logoblobid.
- if (bytes != ev->Get()->Id.BlobSize()) {
- TStringStream str;
- str << "Actual data size# " << bytes
- << " does not match LogoBlobId# " << ev->Get()->Id
- << " Group# " << GroupId
- << " Marker# DSP53";
- std::unique_ptr<TEvBlobStorage::TEvPutResult> result(
- new TEvBlobStorage::TEvPutResult(NKikimrProto::ERROR, ev->Get()->Id, 0, GroupId, 0.f));
- result->ErrorReason = str.Str();
- LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY,
- "HandleNormal ev# " << ev->Get()->Print(false)
- << " result# " << result->Print(false)
- << " Marker# DSP54");
- Send(ev->Sender, result.release(), 0, ev->Cookie);
- return;
- }
-
- if (StopPutBatchingEvent) {
- TActivationContext::Send(StopPutBatchingEvent.Release());
- }
- BatchedPutRequestCount++;
-
- Send(MonActor, new TEvThroughputAddRequest(ev->Get()->HandleClass, bytes));
- EnableWilsonTracing(ev, Mon->PutSamplePPM);
+#include "dsproxy_impl.h"
+#include "dsproxy_monactor.h"
+
+namespace NKikimr {
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvGet::TPtr &ev) {
+ if (IsLimitedKeyless && !ev->Get()->PhantomCheck) {
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+
+ if (StopGetBatchingEvent) {
+ TActivationContext::Send(StopGetBatchingEvent.Release());
+ }
+ BatchedGetRequestCount++;
+ EnsureMonitoring(true);
+ LWTRACK(DSProxyGetHandle, ev->Get()->Orbit);
+ EnableWilsonTracing(ev, Mon->GetSamplePPM);
+ TActorId reqID;
+ if (ev->Get()->IsIndexOnly) {
+ Mon->EventIndexRestoreGet->Inc();
+ reqID = Register(
+ CreateBlobStorageGroupIndexRestoreGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), {}, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ } else {
+ TLogoBlobID lastBlobId;
+ const ui32 querySize = ev->Get()->QuerySize;
+ TArrayHolder<TEvBlobStorage::TEvGet::TQuery> &queries = ev->Get()->Queries;
+ ui32 differentBlobCount = 0;
+ TQueryResultSizeTracker resultSize;
+ resultSize.Init();
+ for (ui32 queryIdx = 0; queryIdx < querySize; ++queryIdx) {
+ const TEvBlobStorage::TEvGet::TQuery &query = queries[queryIdx];
+ if (lastBlobId == query.Id && queryIdx != 0) {
+ continue;
+ }
+ lastBlobId = query.Id;
+ resultSize.AddAllPartsOfLogoBlob(Info->Type, query.Id);
+ differentBlobCount++;
+ }
+ bool isSmall = !resultSize.IsOverflow() && querySize <= 10000;
+
+ TMaybe<TGroupStat::EKind> kind;
+ switch (ev->Get()->GetHandleClass) {
+ case NKikimrBlobStorage::FastRead:
+ // do not count async requests and discover requests
+ kind = TGroupStat::EKind::GET_FAST;
+ break;
+
+ default:
+ break;
+ }
+
+ if (differentBlobCount == 1 || isSmall) {
+ Mon->EventGet->Inc();
+ reqID = Register(
+ CreateBlobStorageGroupGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), TNodeLayoutInfoPtr(NodeLayoutInfo),
+ kind, TActivationContext::Now(), StoragePoolCounters, false));
+ ActiveRequests.insert(reqID);
+ } else {
+ Mon->EventMultiGet->Inc();
+ reqID = Register(
+ CreateBlobStorageGroupMultiGetRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), kind, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+ }
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvPut::TPtr &ev) {
+ if (IsLimitedKeyless) {
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+ LWTRACK(DSProxyPutHandle, ev->Get()->Orbit);
+ EnsureMonitoring(true);
+ const ui64 bytes = ev->Get()->Buffer.size();
+ Mon->CountPutEvent(bytes);
+ // Make sure actual data size matches one in the logoblobid.
+ if (bytes != ev->Get()->Id.BlobSize()) {
+ TStringStream str;
+ str << "Actual data size# " << bytes
+ << " does not match LogoBlobId# " << ev->Get()->Id
+ << " Group# " << GroupId
+ << " Marker# DSP53";
+ std::unique_ptr<TEvBlobStorage::TEvPutResult> result(
+ new TEvBlobStorage::TEvPutResult(NKikimrProto::ERROR, ev->Get()->Id, 0, GroupId, 0.f));
+ result->ErrorReason = str.Str();
+ LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY,
+ "HandleNormal ev# " << ev->Get()->Print(false)
+ << " result# " << result->Print(false)
+ << " Marker# DSP54");
+ Send(ev->Sender, result.release(), 0, ev->Cookie);
+ return;
+ }
+
+ if (StopPutBatchingEvent) {
+ TActivationContext::Send(StopPutBatchingEvent.Release());
+ }
+ BatchedPutRequestCount++;
+
+ Send(MonActor, new TEvThroughputAddRequest(ev->Get()->HandleClass, bytes));
+ EnableWilsonTracing(ev, Mon->PutSamplePPM);
+
if (EnablePutBatching && bytes < MaxBatchedPutSize) {
- NKikimrBlobStorage::EPutHandleClass handleClass = ev->Get()->HandleClass;
- TEvBlobStorage::TEvPut::ETactic tactic = ev->Get()->Tactic;
- Y_VERIFY((ui64)handleClass <= PutHandleClassCount);
- Y_VERIFY(tactic <= PutTacticCount);
-
- TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts = BatchedPuts[handleClass][tactic];
- if (batchedPuts.Queue.empty()) {
- PutBatchedBucketQueue.emplace_back(handleClass, tactic);
- }
-
- if (batchedPuts.Queue.size() == MaxBatchedPutRequests || batchedPuts.Bytes + bytes > MaxBatchedPutSize) {
+ NKikimrBlobStorage::EPutHandleClass handleClass = ev->Get()->HandleClass;
+ TEvBlobStorage::TEvPut::ETactic tactic = ev->Get()->Tactic;
+ Y_VERIFY((ui64)handleClass <= PutHandleClassCount);
+ Y_VERIFY(tactic <= PutTacticCount);
+
+ TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts = BatchedPuts[handleClass][tactic];
+ if (batchedPuts.Queue.empty()) {
+ PutBatchedBucketQueue.emplace_back(handleClass, tactic);
+ }
+
+ if (batchedPuts.Queue.size() == MaxBatchedPutRequests || batchedPuts.Bytes + bytes > MaxBatchedPutSize) {
*Mon->PutsSentViaPutBatching += batchedPuts.Queue.size();
++*Mon->PutBatchesSent;
- ProcessBatchedPutRequests(batchedPuts, handleClass, tactic);
- }
-
- batchedPuts.Queue.push_back(ev.Release());
- batchedPuts.Bytes += bytes;
- } else {
- TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(ev->Get()->HandleClass);
-
+ ProcessBatchedPutRequests(batchedPuts, handleClass, tactic);
+ }
+
+ batchedPuts.Queue.push_back(ev.Release());
+ batchedPuts.Bytes += bytes;
+ } else {
+ TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(ev->Get()->HandleClass);
+
TAppData *app = NKikimr::AppData(TActivationContext::AsActorContext());
bool enableRequestMod3x3ForMinLatency = app->FeatureFlags.GetEnable3x3RequestsForMirror3DCMinLatencyPut();
- // TODO(alexvru): MinLatency support
- const TActorId reqID = Register(
- CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), Mon->TimeStats.IsEnabled(),
+ // TODO(alexvru): MinLatency support
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), Mon->TimeStats.IsEnabled(),
PerDiskStats, kind, TActivationContext::Now(), StoragePoolCounters,
enableRequestMod3x3ForMinLatency));
- ActiveRequests.insert(reqID);
- }
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvBlock::TPtr &ev) {
- EnsureMonitoring(ev->Get()->IsMonitored);
- Mon->EventBlock->Inc();
- const TActorId reqID = Register(
- CreateBlobStorageGroupBlockRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvPatch::TPtr &ev) {
- if (IsLimitedKeyless) {
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
- EnsureMonitoring(true);
- Mon->EventPatch->Inc();
+ ActiveRequests.insert(reqID);
+ }
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvBlock::TPtr &ev) {
+ EnsureMonitoring(ev->Get()->IsMonitored);
+ Mon->EventBlock->Inc();
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupBlockRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvPatch::TPtr &ev) {
+ if (IsLimitedKeyless) {
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+ EnsureMonitoring(true);
+ Mon->EventPatch->Inc();
TInstant now = TActivationContext::Now();
- const TActorId reqId = Register(
- CreateBlobStorageGroupPatchRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ const TActorId reqId = Register(
+ CreateBlobStorageGroupPatchRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
ev->Get(), ev->Cookie, std::move(ev->TraceId), now,
StoragePoolCounters, SelfId(), EnableVPatch.Update(now)));
- ActiveRequests.insert(reqId);
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvDiscover::TPtr &ev) {
- if (IsLimitedKeyless) {
- // Consider adding && ev->Get()->ReadBody
- // to allow !ReadBody discovers (or even make a special discover flag for keyless case)
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
- EnsureMonitoring(true);
- Mon->EventDiscover->Inc();
- EnableWilsonTracing(ev, Mon->DiscoverSamplePPM);
- auto&& callback = Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc
- ? CreateBlobStorageGroupMirror3dcDiscoverRequest
- : Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3of4
- ? CreateBlobStorageGroupMirror3of4DiscoverRequest
- : CreateBlobStorageGroupDiscoverRequest;
- const TActorId reqID = Register(callback(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvRange::TPtr &ev) {
- if (IsLimitedKeyless) {
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
- EnsureMonitoring(true);
- Mon->EventRange->Inc();
- const TActorId reqID = Register(
- CreateBlobStorageGroupRangeRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, std::move(ev->TraceId), TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvCollectGarbage::TPtr &ev) {
- EnsureMonitoring(ev->Get()->IsMonitored);
-
- if (!ev->Get()->IsMultiCollectAllowed || ev->Get()->PerGenerationCounterStepSize() == 1) {
- Mon->EventCollectGarbage->Inc();
- const TActorId reqID = Register(
- CreateBlobStorageGroupCollectGarbageRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- } else {
- Mon->EventMultiCollect->Inc();
- const TActorId reqID = Register(
- CreateBlobStorageGroupMultiCollectRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
- }
-
- void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvStatus::TPtr &ev) {
- if (IsLimitedKeyless) {
- ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
- HandleError(ev);
- return;
- }
- EnsureMonitoring(true);
- Mon->EventStatus->Inc();
- const TActorId reqID = Register(
- CreateBlobStorageGroupStatusRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
- ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
- ActiveRequests.insert(reqID);
- }
-
- void TBlobStorageGroupProxy::Handle(TEvDeathNote::TPtr ev) {
- const bool wasEmpty = ResponsivenessTracker.IsEmpty();
- for (const auto &item : ev->Get()->Responsiveness) {
- ResponsivenessTracker.Register(item.first, TActivationContext::Now(), item.second);
- }
- if (wasEmpty && !ResponsivenessTracker.IsEmpty()) {
- ScheduleUpdateResponsiveness();
- }
- ActiveRequests.erase(ev->Sender);
- }
-
- void TBlobStorageGroupProxy::Handle(TEvBlobStorage::TEvBunchOfEvents::TPtr ev) {
- const TActorContext& ctx = TActivationContext::ActorContextFor(SelfId());
- for (auto& ev : ev->Get()->Bunch) {
- TAutoPtr<IEventHandle> handle(ev.release());
- Receive(handle, ctx);
- }
- }
-
- void TBlobStorageGroupProxy::ProcessBatchedPutRequests(TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts,
- NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic) {
- TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(handleClass);
-
- if (Info) {
+ ActiveRequests.insert(reqId);
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvDiscover::TPtr &ev) {
+ if (IsLimitedKeyless) {
+ // Consider adding && ev->Get()->ReadBody
+ // to allow !ReadBody discovers (or even make a special discover flag for keyless case)
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+ EnsureMonitoring(true);
+ Mon->EventDiscover->Inc();
+ EnableWilsonTracing(ev, Mon->DiscoverSamplePPM);
+ auto&& callback = Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc
+ ? CreateBlobStorageGroupMirror3dcDiscoverRequest
+ : Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3of4
+ ? CreateBlobStorageGroupMirror3of4DiscoverRequest
+ : CreateBlobStorageGroupDiscoverRequest;
+ const TActorId reqID = Register(callback(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvRange::TPtr &ev) {
+ if (IsLimitedKeyless) {
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+ EnsureMonitoring(true);
+ Mon->EventRange->Inc();
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupRangeRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, std::move(ev->TraceId), TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvCollectGarbage::TPtr &ev) {
+ EnsureMonitoring(ev->Get()->IsMonitored);
+
+ if (!ev->Get()->IsMultiCollectAllowed || ev->Get()->PerGenerationCounterStepSize() == 1) {
+ Mon->EventCollectGarbage->Inc();
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupCollectGarbageRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ } else {
+ Mon->EventMultiCollect->Inc();
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupMultiCollectRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+ }
+
+ void TBlobStorageGroupProxy::HandleNormal(TEvBlobStorage::TEvStatus::TPtr &ev) {
+ if (IsLimitedKeyless) {
+ ErrorDescription = "Created as LIMITED without keys. It happens when tenant keys are missing on the node.";
+ HandleError(ev);
+ return;
+ }
+ EnsureMonitoring(true);
+ Mon->EventStatus->Inc();
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupStatusRequest(Info, Sessions->GroupQueues, ev->Sender, Mon,
+ ev->Get(), ev->Cookie, TActivationContext::Now(), StoragePoolCounters));
+ ActiveRequests.insert(reqID);
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvDeathNote::TPtr ev) {
+ const bool wasEmpty = ResponsivenessTracker.IsEmpty();
+ for (const auto &item : ev->Get()->Responsiveness) {
+ ResponsivenessTracker.Register(item.first, TActivationContext::Now(), item.second);
+ }
+ if (wasEmpty && !ResponsivenessTracker.IsEmpty()) {
+ ScheduleUpdateResponsiveness();
+ }
+ ActiveRequests.erase(ev->Sender);
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvBlobStorage::TEvBunchOfEvents::TPtr ev) {
+ const TActorContext& ctx = TActivationContext::ActorContextFor(SelfId());
+ for (auto& ev : ev->Get()->Bunch) {
+ TAutoPtr<IEventHandle> handle(ev.release());
+ Receive(handle, ctx);
+ }
+ }
+
+ void TBlobStorageGroupProxy::ProcessBatchedPutRequests(TBatchedQueue<TEvBlobStorage::TEvPut::TPtr> &batchedPuts,
+ NKikimrBlobStorage::EPutHandleClass handleClass, TEvBlobStorage::TEvPut::ETactic tactic) {
+ TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(handleClass);
+
+ if (Info) {
TAppData *app = NKikimr::AppData(TActivationContext::AsActorContext());
bool enableRequestMod3x3ForMinLatency = app->FeatureFlags.GetEnable3x3RequestsForMirror3DCMinLatencyPut();
- // TODO(alexvru): MinLatency support
- if (batchedPuts.Queue.size() == 1) {
- const TActorId reqID = Register(
- CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues, batchedPuts.Queue.front()->Sender,
- Mon, batchedPuts.Queue.front()->Get(), batchedPuts.Queue.front()->Cookie,
- std::move(batchedPuts.Queue.front()->TraceId), Mon->TimeStats.IsEnabled(), PerDiskStats, kind,
+ // TODO(alexvru): MinLatency support
+ if (batchedPuts.Queue.size() == 1) {
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues, batchedPuts.Queue.front()->Sender,
+ Mon, batchedPuts.Queue.front()->Get(), batchedPuts.Queue.front()->Cookie,
+ std::move(batchedPuts.Queue.front()->TraceId), Mon->TimeStats.IsEnabled(), PerDiskStats, kind,
TActivationContext::Now(), StoragePoolCounters, enableRequestMod3x3ForMinLatency));
- ActiveRequests.insert(reqID);
- } else {
- const TActorId reqID = Register(
- CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues,
- Mon, batchedPuts.Queue, Mon->TimeStats.IsEnabled(), PerDiskStats, kind, TActivationContext::Now(),
+ ActiveRequests.insert(reqID);
+ } else {
+ const TActorId reqID = Register(
+ CreateBlobStorageGroupPutRequest(Info, Sessions->GroupQueues,
+ Mon, batchedPuts.Queue, Mon->TimeStats.IsEnabled(), PerDiskStats, kind, TActivationContext::Now(),
StoragePoolCounters, handleClass, tactic, enableRequestMod3x3ForMinLatency));
- ActiveRequests.insert(reqID);
- }
- } else {
- for (auto it = batchedPuts.Queue.begin(); it != batchedPuts.Queue.end(); ++it) {
- HandleError(*it);
- }
- }
-
- batchedPuts.Queue.clear();
- batchedPuts.Bytes = 0;
- }
-
- void TBlobStorageGroupProxy::Handle(TEvStopBatchingPutRequests::TPtr& ev) {
- StopPutBatchingEvent = ev;
- for (auto &bucket : PutBatchedBucketQueue) {
- auto &batchedPuts = BatchedPuts[bucket.HandleClass][bucket.Tactic];
- Y_VERIFY(!batchedPuts.Queue.empty());
+ ActiveRequests.insert(reqID);
+ }
+ } else {
+ for (auto it = batchedPuts.Queue.begin(); it != batchedPuts.Queue.end(); ++it) {
+ HandleError(*it);
+ }
+ }
+
+ batchedPuts.Queue.clear();
+ batchedPuts.Bytes = 0;
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvStopBatchingPutRequests::TPtr& ev) {
+ StopPutBatchingEvent = ev;
+ for (auto &bucket : PutBatchedBucketQueue) {
+ auto &batchedPuts = BatchedPuts[bucket.HandleClass][bucket.Tactic];
+ Y_VERIFY(!batchedPuts.Queue.empty());
*Mon->PutsSentViaPutBatching += batchedPuts.Queue.size();
++*Mon->PutBatchesSent;
- ProcessBatchedPutRequests(batchedPuts, bucket.HandleClass, bucket.Tactic);
- }
- PutBatchedBucketQueue.clear();
- ++*Mon->EventStopPutBatching;
- LWPROBE(DSProxyBatchedPutRequest, BatchedPutRequestCount, GroupId);
- BatchedPutRequestCount = 0;
+ ProcessBatchedPutRequests(batchedPuts, bucket.HandleClass, bucket.Tactic);
+ }
+ PutBatchedBucketQueue.clear();
+ ++*Mon->EventStopPutBatching;
+ LWPROBE(DSProxyBatchedPutRequest, BatchedPutRequestCount, GroupId);
+ BatchedPutRequestCount = 0;
EnablePutBatching.Update(TActivationContext::Now());
- }
-
- void TBlobStorageGroupProxy::Handle(TEvStopBatchingGetRequests::TPtr& ev) {
- StopGetBatchingEvent = ev;
- ++*Mon->EventStopGetBatching;
- LWPROBE(DSProxyBatchedGetRequest, BatchedGetRequestCount, GroupId);
- BatchedGetRequestCount = 0;
- }
-
-} // NKikimr
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvStopBatchingGetRequests::TPtr& ev) {
+ StopGetBatchingEvent = ev;
+ ++*Mon->EventStopGetBatching;
+ LWPROBE(DSProxyBatchedGetRequest, BatchedGetRequestCount, GroupId);
+ BatchedGetRequestCount = 0;
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_responsiveness.h b/ydb/core/blobstorage/dsproxy/dsproxy_responsiveness.h
index c0b01b06d17..9beb36bb9ca 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_responsiveness.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_responsiveness.h
@@ -1,123 +1,123 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- class TDiskResponsivenessTracker {
- public:
- using TDiskId = ui32; // VDisk order number inside group
-
- struct TPerDiskStats : TThrRefBase {
- struct TInfo {
- TDuration Responsiveness;
- ui32 NumRequests;
- TInstant Since;
- TInstant Until;
-
- TString ToString() const {
- const TInstant now = TInstant::Now();
- const TDuration since = now - Since;
- const TDuration until = now - Until;
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ class TDiskResponsivenessTracker {
+ public:
+ using TDiskId = ui32; // VDisk order number inside group
+
+ struct TPerDiskStats : TThrRefBase {
+ struct TInfo {
+ TDuration Responsiveness;
+ ui32 NumRequests;
+ TInstant Since;
+ TInstant Until;
+
+ TString ToString() const {
+ const TInstant now = TInstant::Now();
+ const TDuration since = now - Since;
+ const TDuration until = now - Until;
return Sprintf("%s/%" PRIu32 "/%s-%s", Responsiveness.ToString().data(), (ui32)NumRequests, since.ToString().data(),
until.ToString().data());
- }
- };
+ }
+ };
THashMap<TDiskId, TInfo> DiskData;
- };
-
- using TPerDiskStatsPtr = TIntrusivePtr<TPerDiskStats>;
-
- private:
- struct TItem {
- TInstant Timestamp;
- TDuration Value;
-
- TItem(TInstant timestamp, TDuration value)
- : Timestamp(timestamp)
- , Value(value)
- {}
- };
-
- const ui32 MaxItems;
- const TDuration Window;
+ };
+
+ using TPerDiskStatsPtr = TIntrusivePtr<TPerDiskStats>;
+
+ private:
+ struct TItem {
+ TInstant Timestamp;
+ TDuration Value;
+
+ TItem(TInstant timestamp, TDuration value)
+ : Timestamp(timestamp)
+ , Value(value)
+ {}
+ };
+
+ const ui32 MaxItems;
+ const TDuration Window;
THashMap<TDiskId, TDeque<TItem>> PerDiskQ;
-
- public:
- TDiskResponsivenessTracker(ui32 maxItems, TDuration window)
- : MaxItems(maxItems)
- , Window(window)
- {}
-
- void Register(const TDiskId &id, TInstant timestamp, TDuration value) {
- auto &q = PerDiskQ[id];
- if (q && timestamp < q.back().Timestamp) {
- timestamp = q.back().Timestamp;
- }
- q.emplace_back(timestamp, value);
- if (q.size() > MaxItems) {
- q.pop_front();
- }
- }
-
- TPerDiskStatsPtr Update(TInstant timestamp) {
- const TInstant barrier = timestamp - Window;
- TPerDiskStatsPtr result = MakeIntrusive<TPerDiskStats>();
-
- for (auto diskIt = PerDiskQ.begin(); diskIt != PerDiskQ.end(); ) {
- const TDiskId &id = diskIt->first;
- auto &q = diskIt->second;
-
- // find the 90-th percentile for this disk
+
+ public:
+ TDiskResponsivenessTracker(ui32 maxItems, TDuration window)
+ : MaxItems(maxItems)
+ , Window(window)
+ {}
+
+ void Register(const TDiskId &id, TInstant timestamp, TDuration value) {
+ auto &q = PerDiskQ[id];
+ if (q && timestamp < q.back().Timestamp) {
+ timestamp = q.back().Timestamp;
+ }
+ q.emplace_back(timestamp, value);
+ if (q.size() > MaxItems) {
+ q.pop_front();
+ }
+ }
+
+ TPerDiskStatsPtr Update(TInstant timestamp) {
+ const TInstant barrier = timestamp - Window;
+ TPerDiskStatsPtr result = MakeIntrusive<TPerDiskStats>();
+
+ for (auto diskIt = PerDiskQ.begin(); diskIt != PerDiskQ.end(); ) {
+ const TDiskId &id = diskIt->first;
+ auto &q = diskIt->second;
+
+ // find the 90-th percentile for this disk
TVector<TDuration> values;
- values.reserve(q.size());
- for (const TItem &item : q) {
- values.push_back(item.Value);
- }
- std::sort(values.begin(), values.end());
- TDuration value = TDuration::Zero();
- if (values) {
- const size_t pos = values.size() * 9 / 10;
- value = values[pos];
- }
-
- // clamp it to the maximum value of last 3 items
- auto qIter = q.rbegin();
- for (ui32 i = 0; i < 3 && qIter != q.rend(); ++i, ++qIter) {
- if (qIter->Value > value) {
- value = qIter->Value;
- }
- }
-
- // store it in the result
- TPerDiskStats::TInfo info;
- info.Responsiveness = value;
- info.NumRequests = q.size();
- info.Since = q ? q.front().Timestamp : TInstant();
- info.Until = q ? q.back().Timestamp : TInstant();
- result->DiskData.emplace(id, info);
-
- // cut excessive items
- auto comp = [](const TItem &x, const TInstant &y) {
- return x.Timestamp < y;
- };
- auto it = std::lower_bound(q.begin(), q.end(), barrier, comp);
- q.erase(q.begin(), it);
-
- // advance iterator and delete queue if it becomes empty
- auto current = diskIt;
- ++diskIt;
- if (q.empty()) {
- PerDiskQ.erase(current);
- }
- }
-
- return result;
- }
-
- bool IsEmpty() const {
- return PerDiskQ.empty();
- }
- };
-
-} // NKikimr
+ values.reserve(q.size());
+ for (const TItem &item : q) {
+ values.push_back(item.Value);
+ }
+ std::sort(values.begin(), values.end());
+ TDuration value = TDuration::Zero();
+ if (values) {
+ const size_t pos = values.size() * 9 / 10;
+ value = values[pos];
+ }
+
+ // clamp it to the maximum value of last 3 items
+ auto qIter = q.rbegin();
+ for (ui32 i = 0; i < 3 && qIter != q.rend(); ++i, ++qIter) {
+ if (qIter->Value > value) {
+ value = qIter->Value;
+ }
+ }
+
+ // store it in the result
+ TPerDiskStats::TInfo info;
+ info.Responsiveness = value;
+ info.NumRequests = q.size();
+ info.Since = q ? q.front().Timestamp : TInstant();
+ info.Until = q ? q.back().Timestamp : TInstant();
+ result->DiskData.emplace(id, info);
+
+ // cut excessive items
+ auto comp = [](const TItem &x, const TInstant &y) {
+ return x.Timestamp < y;
+ };
+ auto it = std::lower_bound(q.begin(), q.end(), barrier, comp);
+ q.erase(q.begin(), it);
+
+ // advance iterator and delete queue if it becomes empty
+ auto current = diskIt;
+ ++diskIt;
+ if (q.empty()) {
+ PerDiskQ.erase(current);
+ }
+ }
+
+ return result;
+ }
+
+ bool IsEmpty() const {
+ return PerDiskQ.empty();
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_stat.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_stat.cpp
index 7be4bd918a4..6e059ef97ed 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_stat.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_stat.cpp
@@ -1,64 +1,64 @@
-#include "dsproxy_impl.h"
-
-namespace NKikimr {
-
- void TBlobStorageGroupProxy::HandleUpdateResponsiveness() {
- PerDiskStats = ResponsivenessTracker.Update(TActivationContext::Now());
-
- auto formatResponsiveness = [&] {
- TStringStream str;
- str << "{";
- bool first = true;
- for (const auto &kv : PerDiskStats->DiskData) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- str << kv.first << ":" << kv.second.ToString();
- }
- str << "}";
- return str.Str();
- };
- LOG_TRACE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId << " Responsiveness# " << formatResponsiveness());
-
- if (!ResponsivenessTracker.IsEmpty()) {
- ScheduleUpdateResponsiveness();
- }
- }
-
- void TBlobStorageGroupProxy::ScheduleUpdateResponsiveness() {
- Schedule(UpdateResponsivenessTimeout, new TEvUpdateResponsiveness);
- }
-
- void TBlobStorageGroupProxy::HandleUpdateGroupStat() {
- Y_VERIFY(GroupStatUpdateScheduled);
- GroupStatUpdateScheduled = false;
- if (Info) {
- Stat.Fadeout(TActivationContext::Now());
- for (ui32 i = 0, num = Info->GetTotalVDisksNum(); i < num; ++i) {
- const TActorId vdiskServiceId = Info->GetActorId(i);
- const TActorId groupStatAggregatorId = MakeGroupStatAggregatorId(vdiskServiceId);
- Send(groupStatAggregatorId, new TEvGroupStatReport(TActorId(), GroupId, Stat));
- }
- }
- ScheduleUpdateGroupStat();
- }
-
- void TBlobStorageGroupProxy::ScheduleUpdateGroupStat() {
- if (!std::exchange(GroupStatUpdateScheduled, true)) {
- Schedule(GroupStatUpdateInterval, new TEvUpdateGroupStat);
- }
- }
-
- void TBlobStorageGroupProxy::Handle(TEvLatencyReport::TPtr& ev) {
- TEvLatencyReport *msg = ev->Get();
- Stat.Update(msg->Kind, msg->Sample, TActivationContext::Now());
- }
-
- void TBlobStorageGroupProxy::Handle(TEvTimeStats::TPtr& ev) {
- // handle TEvBlobStorage::TEvPut first
- Mon->TimeStats.MergeIn(std::move(ev->Get()->TimeStats));
- }
-
-} // NKikimr
+#include "dsproxy_impl.h"
+
+namespace NKikimr {
+
+ void TBlobStorageGroupProxy::HandleUpdateResponsiveness() {
+ PerDiskStats = ResponsivenessTracker.Update(TActivationContext::Now());
+
+ auto formatResponsiveness = [&] {
+ TStringStream str;
+ str << "{";
+ bool first = true;
+ for (const auto &kv : PerDiskStats->DiskData) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ str << kv.first << ":" << kv.second.ToString();
+ }
+ str << "}";
+ return str.Str();
+ };
+ LOG_TRACE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId << " Responsiveness# " << formatResponsiveness());
+
+ if (!ResponsivenessTracker.IsEmpty()) {
+ ScheduleUpdateResponsiveness();
+ }
+ }
+
+ void TBlobStorageGroupProxy::ScheduleUpdateResponsiveness() {
+ Schedule(UpdateResponsivenessTimeout, new TEvUpdateResponsiveness);
+ }
+
+ void TBlobStorageGroupProxy::HandleUpdateGroupStat() {
+ Y_VERIFY(GroupStatUpdateScheduled);
+ GroupStatUpdateScheduled = false;
+ if (Info) {
+ Stat.Fadeout(TActivationContext::Now());
+ for (ui32 i = 0, num = Info->GetTotalVDisksNum(); i < num; ++i) {
+ const TActorId vdiskServiceId = Info->GetActorId(i);
+ const TActorId groupStatAggregatorId = MakeGroupStatAggregatorId(vdiskServiceId);
+ Send(groupStatAggregatorId, new TEvGroupStatReport(TActorId(), GroupId, Stat));
+ }
+ }
+ ScheduleUpdateGroupStat();
+ }
+
+ void TBlobStorageGroupProxy::ScheduleUpdateGroupStat() {
+ if (!std::exchange(GroupStatUpdateScheduled, true)) {
+ Schedule(GroupStatUpdateInterval, new TEvUpdateGroupStat);
+ }
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvLatencyReport::TPtr& ev) {
+ TEvLatencyReport *msg = ev->Get();
+ Stat.Update(msg->Kind, msg->Sample, TActivationContext::Now());
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvTimeStats::TPtr& ev) {
+ // handle TEvBlobStorage::TEvPut first
+ Mon->TimeStats.MergeIn(std::move(ev->Get()->TimeStats));
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_state.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_state.cpp
index af2739699df..d4bd779d217 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_state.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_state.cpp
@@ -1,304 +1,304 @@
-#include "dsproxy_impl.h"
-#include "dsproxy_monactor.h"
-
-namespace NKikimr {
-
- void TBlobStorageGroupProxy::Handle5min(TAutoPtr<IEventHandle> ev) {
- if (ev->Cookie == Cookie5min) {
- if (CurrentStateFunc() == &TBlobStorageGroupProxy::StateEstablishingSessionsTimeout) {
- Y_VERIFY(!InEstablishingSessionsTimeout5min);
- ++*NodeMon->EstablishingSessionsTimeout5min;
- InEstablishingSessionsTimeout5min = true;
- } else if (CurrentStateFunc() == &TBlobStorageGroupProxy::StateUnconfiguredTimeout) {
- Y_VERIFY(!InUnconfiguredTimeout5min);
- ++*NodeMon->UnconfiguredTimeout5min;
- InUnconfiguredTimeout5min = true;
- }
- }
- }
-
- void TBlobStorageGroupProxy::ClearTimeoutCounters() {
- *NodeMon->EstablishingSessionsTimeout -= std::exchange(InEstablishingSessionsTimeout, false);
- *NodeMon->EstablishingSessionsTimeout5min -= std::exchange(InEstablishingSessionsTimeout5min, false);
- *NodeMon->UnconfiguredTimeout -= std::exchange(InUnconfiguredTimeout, false);
- *NodeMon->UnconfiguredTimeout5min -= std::exchange(InUnconfiguredTimeout5min, false);
- }
-
- void TBlobStorageGroupProxy::SetStateEstablishingSessions() {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " SetStateEstablishingSessions Marker# DSP03");
- EstablishingSessionStartTime = TActivationContext::Now();
- ConfigureQueryTimeoutEv = nullptr;
- ClearTimeoutCounters();
+#include "dsproxy_impl.h"
+#include "dsproxy_monactor.h"
+
+namespace NKikimr {
+
+ void TBlobStorageGroupProxy::Handle5min(TAutoPtr<IEventHandle> ev) {
+ if (ev->Cookie == Cookie5min) {
+ if (CurrentStateFunc() == &TBlobStorageGroupProxy::StateEstablishingSessionsTimeout) {
+ Y_VERIFY(!InEstablishingSessionsTimeout5min);
+ ++*NodeMon->EstablishingSessionsTimeout5min;
+ InEstablishingSessionsTimeout5min = true;
+ } else if (CurrentStateFunc() == &TBlobStorageGroupProxy::StateUnconfiguredTimeout) {
+ Y_VERIFY(!InUnconfiguredTimeout5min);
+ ++*NodeMon->UnconfiguredTimeout5min;
+ InUnconfiguredTimeout5min = true;
+ }
+ }
+ }
+
+ void TBlobStorageGroupProxy::ClearTimeoutCounters() {
+ *NodeMon->EstablishingSessionsTimeout -= std::exchange(InEstablishingSessionsTimeout, false);
+ *NodeMon->EstablishingSessionsTimeout5min -= std::exchange(InEstablishingSessionsTimeout5min, false);
+ *NodeMon->UnconfiguredTimeout -= std::exchange(InUnconfiguredTimeout, false);
+ *NodeMon->UnconfiguredTimeout5min -= std::exchange(InUnconfiguredTimeout5min, false);
+ }
+
+ void TBlobStorageGroupProxy::SetStateEstablishingSessions() {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " SetStateEstablishingSessions Marker# DSP03");
+ EstablishingSessionStartTime = TActivationContext::Now();
+ ConfigureQueryTimeoutEv = nullptr;
+ ClearTimeoutCounters();
EstablishingSessionsTimeoutEv = new TEvEstablishingSessionTimeout();
Become(&TThis::StateEstablishingSessions, ProxyEstablishSessionsTimeout, EstablishingSessionsTimeoutEv);
- SwitchToWorkWhenGoodToGo();
- }
-
- void TBlobStorageGroupProxy::SetStateEstablishingSessionsTimeout() {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " SetStateEstablishingSessionsTimeout Marker# DSP09");
- EstablishingSessionStartTime = TInstant::Zero();
- EstablishingSessionsPutMuteChecker.Unmute();
- EstablishingSessionsTimeoutEv = nullptr;
- ConfigureQueryTimeoutEv = nullptr;
- ClearTimeoutCounters();
- Become(&TThis::StateEstablishingSessionsTimeout);
- ++*NodeMon->EstablishingSessionsTimeout;
- InEstablishingSessionsTimeout = true;
- TActivationContext::Schedule(TDuration::Minutes(5), new IEventHandle(Ev5min, 0, SelfId(), {}, nullptr, ++Cookie5min));
- ProcessInitQueue();
- }
-
- void TBlobStorageGroupProxy::SetStateUnconfigured() {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " SetStateUnconfigured Marker# DSP07");
- ErrorDescription = "StateUnconfigured (DSPE9).";
- EstablishingSessionsTimeoutEv = nullptr;
- ClearTimeoutCounters();
+ SwitchToWorkWhenGoodToGo();
+ }
+
+ void TBlobStorageGroupProxy::SetStateEstablishingSessionsTimeout() {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " SetStateEstablishingSessionsTimeout Marker# DSP09");
+ EstablishingSessionStartTime = TInstant::Zero();
+ EstablishingSessionsPutMuteChecker.Unmute();
+ EstablishingSessionsTimeoutEv = nullptr;
+ ConfigureQueryTimeoutEv = nullptr;
+ ClearTimeoutCounters();
+ Become(&TThis::StateEstablishingSessionsTimeout);
+ ++*NodeMon->EstablishingSessionsTimeout;
+ InEstablishingSessionsTimeout = true;
+ TActivationContext::Schedule(TDuration::Minutes(5), new IEventHandle(Ev5min, 0, SelfId(), {}, nullptr, ++Cookie5min));
+ ProcessInitQueue();
+ }
+
+ void TBlobStorageGroupProxy::SetStateUnconfigured() {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " SetStateUnconfigured Marker# DSP07");
+ ErrorDescription = "StateUnconfigured (DSPE9).";
+ EstablishingSessionsTimeoutEv = nullptr;
+ ClearTimeoutCounters();
ConfigureQueryTimeoutEv = new TEvConfigureQueryTimeout();
Become(&TThis::StateUnconfigured, ProxyConfigurationTimeout, ConfigureQueryTimeoutEv);
- }
-
- void TBlobStorageGroupProxy::SetStateUnconfiguredTimeout() {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " SetStateUnconfiguredTimeout Marker# DSP14");
- EstablishingSessionsTimeoutEv = nullptr;
- ConfigureQueryTimeoutEv = nullptr;
- ClearTimeoutCounters();
- Become(&TThis::StateUnconfiguredTimeout);
- ++*NodeMon->UnconfiguredTimeout;
- InUnconfiguredTimeout = true;
- TActivationContext::Schedule(TDuration::Minutes(5), new IEventHandle(Ev5min, 0, SelfId(), {}, nullptr, ++Cookie5min));
- ProcessInitQueue();
- }
-
- void TBlobStorageGroupProxy::SetStateWork() {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " SetStateWork Marker# DSP15");
- EstablishingSessionsTimeoutEv = nullptr;
- ConfigureQueryTimeoutEv = nullptr;
- ClearTimeoutCounters();
- Become(&TThis::StateWork);
- ProcessInitQueue();
- }
-
- void TBlobStorageGroupProxy::Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev) {
- auto *msg = ev->Get();
- ApplyGroupInfo(std::move(msg->Info), std::move(msg->StoragePoolCounters));
- }
-
- void TBlobStorageGroupProxy::ApplyGroupInfo(TIntrusivePtr<TBlobStorageGroupInfo>&& info,
- TIntrusivePtr<TStoragePoolCounters>&& counters) {
- Info = std::move(info);
- if (Info) {
- if (Topology) {
- Y_VERIFY_DEBUG(Topology->EqualityCheck(Info->GetTopology()));
- } else {
- Topology = Info->PickTopology();
- }
- }
- NodeLayoutInfo = nullptr;
- Send(MonActor, new TEvBlobStorage::TEvConfigureProxy(Info));
- if (Info) {
- Y_VERIFY(!EncryptionMode || *EncryptionMode == Info->GetEncryptionMode());
- Y_VERIFY(!LifeCyclePhase || *LifeCyclePhase == Info->GetLifeCyclePhase());
- Y_VERIFY(!GroupKeyNonce || *GroupKeyNonce == Info->GetGroupKeyNonce());
- Y_VERIFY(!CypherKey || *CypherKey == *Info->GetCypherKey());
- EncryptionMode = Info->GetEncryptionMode();
- LifeCyclePhase = Info->GetLifeCyclePhase();
- GroupKeyNonce = Info->GetGroupKeyNonce();
- CypherKey = *Info->GetCypherKey();
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
- }
- if (counters) {
- StoragePoolCounters = std::move(counters);
- }
- IsLimitedKeyless = false;
- if (Info && Info->GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
- switch (Info->GetLifeCyclePhase()) {
- case TBlobStorageGroupInfo::ELCP_IN_USE:
- Y_VERIFY_S(Info->GetCypherKey()->GetIsKeySet(), "CypherKey must be set for Group# " << GroupId
- << " ActorId# " << SelfId() << " EncryptionMode# " << Info->GetEncryptionMode());
- break;
-
- case TBlobStorageGroupInfo::ELCP_PROPOSE:
- Y_VERIFY_DEBUG_S(false, "incorrect LifeCyclePhase# " << Info->GetLifeCyclePhase());
- [[fallthrough]];
- case TBlobStorageGroupInfo::ELCP_INITIAL:
- case TBlobStorageGroupInfo::ELCP_IN_TRANSITION:
- case TBlobStorageGroupInfo::ELCP_KEY_CRC_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_VERSION_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_ID_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_NOT_LOADED:
- IsLimitedKeyless = true;
- break;
- }
- }
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " TEvConfigureProxy received"
- << " GroupGeneration# " << (Info ? ToString(Info->GroupGeneration) : "<none>")
- << " IsLimitedKeyless# " << (IsLimitedKeyless ? "true" : "false")
- << " Marker# DSP02");
- if (Info) { // if the new group has arrived
- if (Sessions) { // queues are already created
- for (size_t i = 0; i < Sessions->GroupQueues->DisksByOrderNumber.size(); ++i) {
- const auto& disk = *Sessions->GroupQueues->DisksByOrderNumber[i];
- disk.Queues.ForEachQueue([&](const auto& queue) {
- Send(queue.ActorId, new TEvVGenerationChange(Info->GetVDiskId(i), Info));
- });
- }
- } else { // this is the first time configuration arrives -- no queues are created yet
- EnsureMonitoring(false);
- Sessions = MakeIntrusive<TGroupSessions>(Info, BSProxyCtx, MonActor, SelfId());
- }
- SetStateEstablishingSessions();
- } else { // configuration has been reset, we have to request it via NodeWarden
- SetStateUnconfigured();
- }
- }
-
- void TBlobStorageGroupProxy::WakeupUnconfigured(TEvConfigureQueryTimeout::TPtr ev) {
- if (ev && ev->Get() != ConfigureQueryTimeoutEv) {
- return;
- }
- LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " Unconfigured Wakeup TIMEOUT Marker# DSP05");
- ErrorDescription = "Configuration timeout occured (DSPE1).";
- EstablishingSessionsPutMuteChecker.Unmute();
- SetStateUnconfiguredTimeout();
- }
-
- void TBlobStorageGroupProxy::SwitchToWorkWhenGoodToGo() {
- Y_VERIFY(Sessions);
- if (Sessions->GoodToGo(*Topology, ForceWaitAllDrives)) {
- LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " -> StateWork" << " Marker# DSP11");
- ErrorDescription = "StateWork (DSPE3).";
- EstablishingSessionStartTime = TInstant::Zero();
- EstablishingSessionsPutMuteChecker.Unmute();
- ErrorStateMuteChecker.Unmute();
- SetStateWork();
- ScheduleUpdateGroupStat();
- }
- }
-
- void TBlobStorageGroupProxy::WakeupEstablishingSessions(TEvEstablishingSessionTimeout::TPtr ev) {
- if (ev && ev->Get() != EstablishingSessionsTimeoutEv) {
- return;
- }
- LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " StateEstablishingSessions Wakeup TIMEOUT Marker# DSP12");
- ErrorDescription = "Timeout while establishing sessions (DSPE4).";
- SetStateEstablishingSessionsTimeout();
- }
-
- void TBlobStorageGroupProxy::Handle(TEvProxyQueueState::TPtr& ev) {
- TInstant now = TActivationContext::Now();
- TDuration establishingSessionsDuration = now - EstablishingSessionStartTime;
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " Handle TEvProxyQueueState# "<< ev->Get()->ToString()
- << " Duration# " << establishingSessionsDuration
- << " Marker# DSP04");
- Y_VERIFY(Sessions);
- auto *msg = ev->Get();
- Y_VERIFY(Topology);
- Sessions->QueueConnectUpdate(Topology->GetOrderNumber(msg->VDiskId), msg->QueueId, msg->IsConnected);
- if (msg->IsConnected && (CurrentStateFunc() == &TThis::StateEstablishingSessions ||
- CurrentStateFunc() == &TThis::StateEstablishingSessionsTimeout)) {
- SwitchToWorkWhenGoodToGo();
- }
- }
-
- void TBlobStorageGroupProxy::Bootstrap() {
- if (IsEjected) {
- LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
- << " HasInvalidGroupId# " << HasInvalidGroupId() << " Bootstrap -> StateEjected Marker# DSP42");
- if (HasInvalidGroupId()) {
- ErrorDescription = "Created as unconfigured in error state (DSPE11). It happens when the request was sent for an invalid groupID";
- ExtraLogInfo = "The request was sent for an invalid groupID ";
- } else {
- ErrorDescription = "Created as unconfigured in error state (DSPE7). It happens when group doesn't present in BSC";
- }
- Become(&TThis::StateEjected);
- } else {
- StopPutBatchingEvent = static_cast<TEventHandle<TEvStopBatchingPutRequests>*>(
- new IEventHandle(SelfId(), SelfId(), new TEvStopBatchingPutRequests));
- StopGetBatchingEvent = static_cast<TEventHandle<TEvStopBatchingGetRequests>*>(
- new IEventHandle(SelfId(), SelfId(), new TEvStopBatchingGetRequests));
- ApplyGroupInfo(std::exchange(Info, {}), std::exchange(StoragePoolCounters, {}));
- }
- }
-
- void TBlobStorageGroupProxy::Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
- if (Info) {
- std::unordered_map<ui32, TNodeLocation> map;
- for (auto& info : ev->Get()->Nodes) {
- map[info.NodeId] = std::move(info.Location);
- }
- NodeLayoutInfo = MakeIntrusive<TNodeLayoutInfo>(map[TlsActivationContext->ExecutorThread.ActorSystem->NodeId],
- Info, map);
- }
- }
-
- void TBlobStorageGroupProxy::PassAway() {
- for (const TActorId actorId : ActiveRequests) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
- }
- if (Sessions) { // may be null if not properly configured yet
- Sessions->Poison();
- }
- if (MonActor) {
- Send(MonActor, new NActors::TEvents::TEvPoison());
- }
-
- // Reply error to all messages in the init queue
- ErrorDescription = "DsProxy got a Poison Pill";
- SetStateEstablishingSessionsTimeout();
-
- TActorBootstrapped::PassAway();
- // TODO: Unsubscribe
- }
-
- void TBlobStorageGroupProxy::ProcessInitQueue() {
- UnconfiguredBufferSize = 0;
- for (std::unique_ptr<IEventHandle>& ev : std::exchange(InitQueue, {})) {
- TAutoPtr<IEventHandle> x(ev.release());
- Receive(x, TActivationContext::ActorContextFor(SelfId()));
- }
- }
-
- void TBlobStorageGroupProxy::EnsureMonitoring(bool fullIfPossible) {
- if (MonActor && fullIfPossible && !IsFullMonitoring) {
- IsFullMonitoring = true;
- LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "EnsureMonitoring Group# " << GroupId
- << " IsLimitedKeyless# " << IsLimitedKeyless << " Marker# DSP57 initialize full monitoring");
- Mon->BecomeFull();
- } else if (!MonActor) {
- LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "EnsureMonitoring Group# " << GroupId
- << " IsLimitedKeyless# " << IsLimitedKeyless << " fullIfPossible# " << fullIfPossible << " Marker# DSP58");
-
- bool limited = IsLimitedKeyless || !fullIfPossible;
- IsFullMonitoring = IsLimitedKeyless || fullIfPossible;
-
- TString name = Sprintf("%09" PRIu32, GroupId);
- TIntrusivePtr<NMonitoring::TDynamicCounters> group = GetServiceCounters(
- AppData()->Counters, "dsproxy")->GetSubgroup("blobstorageproxy", name);
- TIntrusivePtr<NMonitoring::TDynamicCounters> percentileGroup = GetServiceCounters(
- AppData()->Counters, "dsproxy_percentile")->GetSubgroup("blobstorageproxy", name);
- TIntrusivePtr<NMonitoring::TDynamicCounters> overviewGroup = GetServiceCounters(
- AppData()->Counters, "dsproxy_overview");
-
- Mon.Reset(new TBlobStorageGroupProxyMon(group, percentileGroup, overviewGroup, Info, NodeMon, limited));
- BSProxyCtx.Reset(new TBSProxyContext(group->GetSubgroup("subsystem", "memproxy")));
- MonActor = Register(CreateBlobStorageGroupProxyMon(Mon, GroupId, Info, SelfId()));
- }
- }
-
- void TBlobStorageGroupProxy::Handle(TEvRequestProxySessionsState::TPtr &ev) {
+ }
+
+ void TBlobStorageGroupProxy::SetStateUnconfiguredTimeout() {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " SetStateUnconfiguredTimeout Marker# DSP14");
+ EstablishingSessionsTimeoutEv = nullptr;
+ ConfigureQueryTimeoutEv = nullptr;
+ ClearTimeoutCounters();
+ Become(&TThis::StateUnconfiguredTimeout);
+ ++*NodeMon->UnconfiguredTimeout;
+ InUnconfiguredTimeout = true;
+ TActivationContext::Schedule(TDuration::Minutes(5), new IEventHandle(Ev5min, 0, SelfId(), {}, nullptr, ++Cookie5min));
+ ProcessInitQueue();
+ }
+
+ void TBlobStorageGroupProxy::SetStateWork() {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " SetStateWork Marker# DSP15");
+ EstablishingSessionsTimeoutEv = nullptr;
+ ConfigureQueryTimeoutEv = nullptr;
+ ClearTimeoutCounters();
+ Become(&TThis::StateWork);
+ ProcessInitQueue();
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvBlobStorage::TEvConfigureProxy::TPtr ev) {
+ auto *msg = ev->Get();
+ ApplyGroupInfo(std::move(msg->Info), std::move(msg->StoragePoolCounters));
+ }
+
+ void TBlobStorageGroupProxy::ApplyGroupInfo(TIntrusivePtr<TBlobStorageGroupInfo>&& info,
+ TIntrusivePtr<TStoragePoolCounters>&& counters) {
+ Info = std::move(info);
+ if (Info) {
+ if (Topology) {
+ Y_VERIFY_DEBUG(Topology->EqualityCheck(Info->GetTopology()));
+ } else {
+ Topology = Info->PickTopology();
+ }
+ }
+ NodeLayoutInfo = nullptr;
+ Send(MonActor, new TEvBlobStorage::TEvConfigureProxy(Info));
+ if (Info) {
+ Y_VERIFY(!EncryptionMode || *EncryptionMode == Info->GetEncryptionMode());
+ Y_VERIFY(!LifeCyclePhase || *LifeCyclePhase == Info->GetLifeCyclePhase());
+ Y_VERIFY(!GroupKeyNonce || *GroupKeyNonce == Info->GetGroupKeyNonce());
+ Y_VERIFY(!CypherKey || *CypherKey == *Info->GetCypherKey());
+ EncryptionMode = Info->GetEncryptionMode();
+ LifeCyclePhase = Info->GetLifeCyclePhase();
+ GroupKeyNonce = Info->GetGroupKeyNonce();
+ CypherKey = *Info->GetCypherKey();
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
+ }
+ if (counters) {
+ StoragePoolCounters = std::move(counters);
+ }
+ IsLimitedKeyless = false;
+ if (Info && Info->GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
+ switch (Info->GetLifeCyclePhase()) {
+ case TBlobStorageGroupInfo::ELCP_IN_USE:
+ Y_VERIFY_S(Info->GetCypherKey()->GetIsKeySet(), "CypherKey must be set for Group# " << GroupId
+ << " ActorId# " << SelfId() << " EncryptionMode# " << Info->GetEncryptionMode());
+ break;
+
+ case TBlobStorageGroupInfo::ELCP_PROPOSE:
+ Y_VERIFY_DEBUG_S(false, "incorrect LifeCyclePhase# " << Info->GetLifeCyclePhase());
+ [[fallthrough]];
+ case TBlobStorageGroupInfo::ELCP_INITIAL:
+ case TBlobStorageGroupInfo::ELCP_IN_TRANSITION:
+ case TBlobStorageGroupInfo::ELCP_KEY_CRC_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_VERSION_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_ID_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_NOT_LOADED:
+ IsLimitedKeyless = true;
+ break;
+ }
+ }
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " TEvConfigureProxy received"
+ << " GroupGeneration# " << (Info ? ToString(Info->GroupGeneration) : "<none>")
+ << " IsLimitedKeyless# " << (IsLimitedKeyless ? "true" : "false")
+ << " Marker# DSP02");
+ if (Info) { // if the new group has arrived
+ if (Sessions) { // queues are already created
+ for (size_t i = 0; i < Sessions->GroupQueues->DisksByOrderNumber.size(); ++i) {
+ const auto& disk = *Sessions->GroupQueues->DisksByOrderNumber[i];
+ disk.Queues.ForEachQueue([&](const auto& queue) {
+ Send(queue.ActorId, new TEvVGenerationChange(Info->GetVDiskId(i), Info));
+ });
+ }
+ } else { // this is the first time configuration arrives -- no queues are created yet
+ EnsureMonitoring(false);
+ Sessions = MakeIntrusive<TGroupSessions>(Info, BSProxyCtx, MonActor, SelfId());
+ }
+ SetStateEstablishingSessions();
+ } else { // configuration has been reset, we have to request it via NodeWarden
+ SetStateUnconfigured();
+ }
+ }
+
+ void TBlobStorageGroupProxy::WakeupUnconfigured(TEvConfigureQueryTimeout::TPtr ev) {
+ if (ev && ev->Get() != ConfigureQueryTimeoutEv) {
+ return;
+ }
+ LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " Unconfigured Wakeup TIMEOUT Marker# DSP05");
+ ErrorDescription = "Configuration timeout occured (DSPE1).";
+ EstablishingSessionsPutMuteChecker.Unmute();
+ SetStateUnconfiguredTimeout();
+ }
+
+ void TBlobStorageGroupProxy::SwitchToWorkWhenGoodToGo() {
+ Y_VERIFY(Sessions);
+ if (Sessions->GoodToGo(*Topology, ForceWaitAllDrives)) {
+ LOG_INFO_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " -> StateWork" << " Marker# DSP11");
+ ErrorDescription = "StateWork (DSPE3).";
+ EstablishingSessionStartTime = TInstant::Zero();
+ EstablishingSessionsPutMuteChecker.Unmute();
+ ErrorStateMuteChecker.Unmute();
+ SetStateWork();
+ ScheduleUpdateGroupStat();
+ }
+ }
+
+ void TBlobStorageGroupProxy::WakeupEstablishingSessions(TEvEstablishingSessionTimeout::TPtr ev) {
+ if (ev && ev->Get() != EstablishingSessionsTimeoutEv) {
+ return;
+ }
+ LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " StateEstablishingSessions Wakeup TIMEOUT Marker# DSP12");
+ ErrorDescription = "Timeout while establishing sessions (DSPE4).";
+ SetStateEstablishingSessionsTimeout();
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvProxyQueueState::TPtr& ev) {
+ TInstant now = TActivationContext::Now();
+ TDuration establishingSessionsDuration = now - EstablishingSessionStartTime;
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " Handle TEvProxyQueueState# "<< ev->Get()->ToString()
+ << " Duration# " << establishingSessionsDuration
+ << " Marker# DSP04");
+ Y_VERIFY(Sessions);
+ auto *msg = ev->Get();
+ Y_VERIFY(Topology);
+ Sessions->QueueConnectUpdate(Topology->GetOrderNumber(msg->VDiskId), msg->QueueId, msg->IsConnected);
+ if (msg->IsConnected && (CurrentStateFunc() == &TThis::StateEstablishingSessions ||
+ CurrentStateFunc() == &TThis::StateEstablishingSessionsTimeout)) {
+ SwitchToWorkWhenGoodToGo();
+ }
+ }
+
+ void TBlobStorageGroupProxy::Bootstrap() {
+ if (IsEjected) {
+ LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << GroupId
+ << " HasInvalidGroupId# " << HasInvalidGroupId() << " Bootstrap -> StateEjected Marker# DSP42");
+ if (HasInvalidGroupId()) {
+ ErrorDescription = "Created as unconfigured in error state (DSPE11). It happens when the request was sent for an invalid groupID";
+ ExtraLogInfo = "The request was sent for an invalid groupID ";
+ } else {
+ ErrorDescription = "Created as unconfigured in error state (DSPE7). It happens when group doesn't present in BSC";
+ }
+ Become(&TThis::StateEjected);
+ } else {
+ StopPutBatchingEvent = static_cast<TEventHandle<TEvStopBatchingPutRequests>*>(
+ new IEventHandle(SelfId(), SelfId(), new TEvStopBatchingPutRequests));
+ StopGetBatchingEvent = static_cast<TEventHandle<TEvStopBatchingGetRequests>*>(
+ new IEventHandle(SelfId(), SelfId(), new TEvStopBatchingGetRequests));
+ ApplyGroupInfo(std::exchange(Info, {}), std::exchange(StoragePoolCounters, {}));
+ }
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) {
+ if (Info) {
+ std::unordered_map<ui32, TNodeLocation> map;
+ for (auto& info : ev->Get()->Nodes) {
+ map[info.NodeId] = std::move(info.Location);
+ }
+ NodeLayoutInfo = MakeIntrusive<TNodeLayoutInfo>(map[TlsActivationContext->ExecutorThread.ActorSystem->NodeId],
+ Info, map);
+ }
+ }
+
+ void TBlobStorageGroupProxy::PassAway() {
+ for (const TActorId actorId : ActiveRequests) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
+ }
+ if (Sessions) { // may be null if not properly configured yet
+ Sessions->Poison();
+ }
+ if (MonActor) {
+ Send(MonActor, new NActors::TEvents::TEvPoison());
+ }
+
+ // Reply error to all messages in the init queue
+ ErrorDescription = "DsProxy got a Poison Pill";
+ SetStateEstablishingSessionsTimeout();
+
+ TActorBootstrapped::PassAway();
+ // TODO: Unsubscribe
+ }
+
+ void TBlobStorageGroupProxy::ProcessInitQueue() {
+ UnconfiguredBufferSize = 0;
+ for (std::unique_ptr<IEventHandle>& ev : std::exchange(InitQueue, {})) {
+ TAutoPtr<IEventHandle> x(ev.release());
+ Receive(x, TActivationContext::ActorContextFor(SelfId()));
+ }
+ }
+
+ void TBlobStorageGroupProxy::EnsureMonitoring(bool fullIfPossible) {
+ if (MonActor && fullIfPossible && !IsFullMonitoring) {
+ IsFullMonitoring = true;
+ LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "EnsureMonitoring Group# " << GroupId
+ << " IsLimitedKeyless# " << IsLimitedKeyless << " Marker# DSP57 initialize full monitoring");
+ Mon->BecomeFull();
+ } else if (!MonActor) {
+ LOG_NOTICE_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "EnsureMonitoring Group# " << GroupId
+ << " IsLimitedKeyless# " << IsLimitedKeyless << " fullIfPossible# " << fullIfPossible << " Marker# DSP58");
+
+ bool limited = IsLimitedKeyless || !fullIfPossible;
+ IsFullMonitoring = IsLimitedKeyless || fullIfPossible;
+
+ TString name = Sprintf("%09" PRIu32, GroupId);
+ TIntrusivePtr<NMonitoring::TDynamicCounters> group = GetServiceCounters(
+ AppData()->Counters, "dsproxy")->GetSubgroup("blobstorageproxy", name);
+ TIntrusivePtr<NMonitoring::TDynamicCounters> percentileGroup = GetServiceCounters(
+ AppData()->Counters, "dsproxy_percentile")->GetSubgroup("blobstorageproxy", name);
+ TIntrusivePtr<NMonitoring::TDynamicCounters> overviewGroup = GetServiceCounters(
+ AppData()->Counters, "dsproxy_overview");
+
+ Mon.Reset(new TBlobStorageGroupProxyMon(group, percentileGroup, overviewGroup, Info, NodeMon, limited));
+ BSProxyCtx.Reset(new TBSProxyContext(group->GetSubgroup("subsystem", "memproxy")));
+ MonActor = Register(CreateBlobStorageGroupProxyMon(Mon, GroupId, Info, SelfId()));
+ }
+ }
+
+ void TBlobStorageGroupProxy::Handle(TEvRequestProxySessionsState::TPtr &ev) {
LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "RequestProxySessionsState Group# " << GroupId
<< " Marker# DSP59");
- Send(ev->Sender, new TEvProxySessionsState(Sessions ? Sessions->GroupQueues : nullptr));
- }
-
-} // NKikimr
+ Send(ev->Sender, new TEvProxySessionsState(Sessions ? Sessions->GroupQueues : nullptr));
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_status.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_status.cpp
index 2b4ec35fd52..281c7632f07 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_status.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_status.cpp
@@ -1,6 +1,6 @@
#include "dsproxy.h"
#include "dsproxy_mon.h"
-#include "dsproxy_quorum_tracker.h"
+#include "dsproxy_quorum_tracker.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
@@ -15,17 +15,17 @@ class TBlobStorageGroupStatusRequest : public TBlobStorageGroupRequestActor<TBlo
TStorageStatusFlags StatusFlags;
ui64 Requests;
ui64 Responses;
- TGroupQuorumTracker QuorumTracker;
+ TGroupQuorumTracker QuorumTracker;
- void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
- ProcessReplyFromQueue(ev);
- const NKikimrBlobStorage::TEvVStatusResult& record = ev->Get()->Record;
+ void Handle(TEvBlobStorage::TEvVStatusResult::TPtr &ev) {
+ ProcessReplyFromQueue(ev);
+ const NKikimrBlobStorage::TEvVStatusResult& record = ev->Get()->Record;
Y_VERIFY(record.HasStatus());
const NKikimrProto::EReplyStatus status = record.GetStatus();
Y_VERIFY(record.HasVDiskID());
const TVDiskID vdisk = VDiskIDFromVDiskID(record.GetVDiskID());
-
- A_LOG_LOG_S(false, PriorityForStatusInbound(status), "DSPS01", "Handle TEvVStatusResult"
+
+ A_LOG_LOG_S(false, PriorityForStatusInbound(status), "DSPS01", "Handle TEvVStatusResult"
<< " status# " << NKikimrProto::EReplyStatus_Name(status).data()
<< " From# " << vdisk.ToString()
<< " StatusFlags# " << (record.HasStatusFlags() ? Sprintf("%" PRIx32, record.GetStatusFlags()).data() : "NA")
@@ -34,100 +34,100 @@ class TBlobStorageGroupStatusRequest : public TBlobStorageGroupRequestActor<TBlo
if (record.HasStatusFlags()) {
StatusFlags.Merge(record.GetStatusFlags());
}
- ++Responses;
-
- switch (const NKikimrProto::EReplyStatus overallStatus = QuorumTracker.ProcessReply(vdisk, status)) {
- case NKikimrProto::OK:
- if (Responses == Requests) {
- ReplyAndDie(NKikimrProto::OK);
- }
- break;
-
- case NKikimrProto::ERROR:
- ReplyAndDie(NKikimrProto::ERROR);
- break;
-
- default:
- break;
+ ++Responses;
+
+ switch (const NKikimrProto::EReplyStatus overallStatus = QuorumTracker.ProcessReply(vdisk, status)) {
+ case NKikimrProto::OK:
+ if (Responses == Requests) {
+ ReplyAndDie(NKikimrProto::OK);
+ }
+ break;
+
+ case NKikimrProto::ERROR:
+ ReplyAndDie(NKikimrProto::ERROR);
+ break;
+
+ default:
+ break;
}
}
friend class TBlobStorageGroupRequestActor<TBlobStorageGroupStatusRequest>;
- void ReplyAndDie(NKikimrProto::EReplyStatus status) {
- auto result = std::make_unique<TEvBlobStorage::TEvStatusResult>(status, StatusFlags.Raw);
+ void ReplyAndDie(NKikimrProto::EReplyStatus status) {
+ auto result = std::make_unique<TEvBlobStorage::TEvStatusResult>(status, StatusFlags.Raw);
result->ErrorReason = ErrorReason;
- A_LOG_DEBUG_S("DSPS03", "ReplyAndDie Result# " << result->Print(false));
- SendResponseAndDie(std::move(result));
- }
-
- std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
- ++*Mon->NodeMon->RestartStatus;
- auto ev = std::make_unique<TEvBlobStorage::TEvStatus>(Deadline);
- ev->RestartCounter = counter;
- return ev;
+ A_LOG_DEBUG_S("DSPS03", "ReplyAndDie Result# " << result->Print(false));
+ SendResponseAndDie(std::move(result));
}
+ std::unique_ptr<IEventBase> RestartQuery(ui32 counter) {
+ ++*Mon->NodeMon->RestartStatus;
+ auto ev = std::make_unique<TEvBlobStorage::TEvStatus>(Deadline);
+ ev->RestartCounter = counter;
+ return ev;
+ }
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_STATUS_ACTOR;;
- }
-
- static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
- return mon->ActiveStatus;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_STATUS_ACTOR;;
}
+ static const auto& ActiveCounter(const TIntrusivePtr<TBlobStorageGroupProxyMon>& mon) {
+ return mon->ActiveStatus;
+ }
+
TBlobStorageGroupStatusRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvStatus *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters)
- : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
- NKikimrServices::BS_PROXY_STATUS, false, {}, now, storagePoolCounters,
- ev->RestartCounter)
+ : TBlobStorageGroupRequestActor(info, state, mon, source, cookie, NWilson::TTraceId(),
+ NKikimrServices::BS_PROXY_STATUS, false, {}, now, storagePoolCounters,
+ ev->RestartCounter)
, Deadline(ev->Deadline)
, Requests(0)
, Responses(0)
- , QuorumTracker(Info.Get())
- {}
-
- void Bootstrap() {
- A_LOG_INFO_S("DSPS05", "bootstrap"
- << " ActorId# " << SelfId()
- << " Group# " << Info->GroupID
- << " Deadline# " << Deadline
- << " RestartCounter# " << RestartCounter);
-
- for (const auto& vdisk : Info->GetVDisks()) {
+ , QuorumTracker(Info.Get())
+ {}
+
+ void Bootstrap() {
+ A_LOG_INFO_S("DSPS05", "bootstrap"
+ << " ActorId# " << SelfId()
+ << " Group# " << Info->GroupID
+ << " Deadline# " << Deadline
+ << " RestartCounter# " << RestartCounter);
+
+ for (const auto& vdisk : Info->GetVDisks()) {
const ui64 cookie = TVDiskIdShort(Info->GetVDiskId(vdisk.OrderNumber)).GetRaw();
auto vd = Info->GetVDiskId(vdisk.OrderNumber);
- A_LOG_DEBUG_S("DSPS04", "Sending TEvVStatus"
- << " vDiskId# " << vd
+ A_LOG_DEBUG_S("DSPS04", "Sending TEvVStatus"
+ << " vDiskId# " << vd
<< " node# " << Info->GetActorId(vd).NodeId());
- auto msg = std::make_unique<TEvBlobStorage::TEvVStatus>(vd);
- SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
- ++Requests;
+ auto msg = std::make_unique<TEvBlobStorage::TEvVStatus>(vd);
+ SendToQueue(std::move(msg), cookie, NWilson::TTraceId()); // FIXME: wilson
+ ++Requests;
}
Become(&TThis::StateWait);
if (Requests == 0) {
- ReplyAndDie(NKikimrProto::OK);
+ ReplyAndDie(NKikimrProto::OK);
}
}
- STATEFN(StateWait) {
- if (ProcessEvent(ev)) {
- return;
- }
+ STATEFN(StateWait) {
+ if (ProcessEvent(ev)) {
+ return;
+ }
switch (ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
+ hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
}
}
};
IActor* CreateBlobStorageGroupStatusRequest(const TIntrusivePtr<TBlobStorageGroupInfo> &info,
- const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
+ const TIntrusivePtr<TGroupQueues> &state, const TActorId &source,
const TIntrusivePtr<TBlobStorageGroupProxyMon> &mon, TEvBlobStorage::TEvStatus *ev,
ui64 cookie, TInstant now, TIntrusivePtr<TStoragePoolCounters> &storagePoolCounters) {
return new TBlobStorageGroupStatusRequest(info, state, source, mon, ev, cookie, now, storagePoolCounters);
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put.h
index a9ecb53953f..76017f3dd35 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put.h
@@ -10,15 +10,15 @@ namespace NKikimr {
class TAcceleratePutStrategy : public TStrategyBase {
public:
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
// Find the unput part and disk
i32 badDiskIdx = -1;
for (size_t diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
TBlobState::TDisk &disk = state.Disks[diskIdx];
for (size_t partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
TBlobState::TDiskPart &diskPart = disk.DiskParts[partIdx];
- if (diskPart.Situation == TBlobState::ESituation::Sent) {
+ if (diskPart.Situation == TBlobState::ESituation::Sent) {
badDiskIdx = diskIdx;
}
}
@@ -36,8 +36,8 @@ public:
PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
}
}
-
- return EStrategyOutcome::DONE;
+
+ return EStrategyOutcome::DONE;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put_m3dc.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put_m3dc.h
index a9e36aa68ba..fec7c2f8515 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put_m3dc.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_accelerate_put_m3dc.h
@@ -17,9 +17,9 @@ public:
const bool EnableRequestMod3x3ForMinLatecy;
TAcceleratePut3dcStrategy(TEvBlobStorage::TEvPut::ETactic tactic, bool enableRequestMod3x3ForMinLatecy)
- : Tactic(tactic)
+ : Tactic(tactic)
, EnableRequestMod3x3ForMinLatecy(enableRequestMod3x3ForMinLatecy)
- {}
+ {}
ui8 PreferredReplicasPerRealm(bool isDegraded) const {
// calculate the least number of replicas we have to provide per each realm
@@ -29,15 +29,15 @@ public:
return isDegraded ? 2 : 1;
}
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
// Find the unput part and disk
i32 badDiskIdx = -1;
for (size_t diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
TBlobState::TDisk &disk = state.Disks[diskIdx];
for (size_t partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
TBlobState::TDiskPart &diskPart = disk.DiskParts[partIdx];
- if (diskPart.Situation == TBlobState::ESituation::Sent) {
+ if (diskPart.Situation == TBlobState::ESituation::Sent) {
badDiskIdx = diskIdx;
}
}
@@ -57,7 +57,7 @@ public:
// check if we are in degraded mode -- that means that we have one fully failed realm
TBlobStorageGroupInfo::TSubgroupVDisks success(&info.GetTopology());
TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
- Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, true, success, error, degraded);
+ Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, true, success, error, degraded);
// check for failure tolerance; we issue ERROR in case when it is not possible to achieve success condition in
// any way; also check if we have already finished writing replicas
@@ -65,20 +65,20 @@ public:
if (checker.CheckFailModelForSubgroup(error)) {
if (checker.CheckQuorumForSubgroup(success)) {
// OK
- return EStrategyOutcome::DONE;
+ return EStrategyOutcome::DONE;
}
// now check every realm and check if we have to issue some write requests to it
Prepare3dcPartPlacement(state, NumFailRealms, NumFailDomainsPerFailRealm,
- PreferredReplicasPerRealm(degraded), true, partPlacement);
+ PreferredReplicasPerRealm(degraded), true, partPlacement);
if (IsPutNeeded(state, partPlacement)) {
PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
}
}
}
-
- return EStrategyOutcome::DONE;
+
+ return EStrategyOutcome::DONE;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp
index c73c20712ec..ff9a1b7ffda 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.cpp
@@ -34,12 +34,12 @@ void TStrategyBase::EvaluateCurrentLayout(TLogContext &logCtx, TBlobState &state
EDiskEvaluation diskEvaluation = ((considerSlowAsError && disk.IsSlow) ? EDE_ERROR : EDE_UNKNOWN);
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Error) {
+ if (partSituation == TBlobState::ESituation::Error) {
R_LOG_DEBUG_SX(logCtx, "BPG41", "Id# " << state.Id.ToString()
<< " Restore Disk# " << diskIdx << " Part# " << partIdx << " Error");
diskEvaluation = EDE_ERROR;
}
- if (partSituation == TBlobState::ESituation::Lost) {
+ if (partSituation == TBlobState::ESituation::Lost) {
R_LOG_DEBUG_SX(logCtx, "BPG65", "Id# " << state.Id.ToString()
<< " Restore Disk# " << diskIdx << " Part# " << partIdx << " Lost");
if (diskEvaluation != EDE_ERROR) {
@@ -58,7 +58,7 @@ void TStrategyBase::EvaluateCurrentLayout(TLogContext &logCtx, TBlobState &state
} else {
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Present) {
R_LOG_DEBUG_SX(logCtx, "BPG42", "Request# "
<< " Id# " << state.Id.ToString()
<< " Disk# " << diskIdx << " Part# " << partIdx << " Present");
@@ -66,13 +66,13 @@ void TStrategyBase::EvaluateCurrentLayout(TLogContext &logCtx, TBlobState &state
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
altruisticLayout.AddItem(diskIdx, partIdx, info.Type);
diskEvaluation = EDE_NORMAL;
- } else if (partSituation == TBlobState::ESituation::Unknown
- || partSituation == TBlobState::ESituation::Sent) {
+ } else if (partSituation == TBlobState::ESituation::Unknown
+ || partSituation == TBlobState::ESituation::Sent) {
R_LOG_DEBUG_SX(logCtx, "BPG43", "Id# " << state.Id.ToString()
<< " Disk# " << diskIdx << " Part# " << partIdx << " Unknown");
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
altruisticLayout.AddItem(diskIdx, partIdx, info.Type);
- } else if (partSituation == TBlobState::ESituation::Absent) {
+ } else if (partSituation == TBlobState::ESituation::Absent) {
diskEvaluation = EDE_NORMAL;
}
}
@@ -122,65 +122,65 @@ bool TStrategyBase::IsUnrecoverableAltruistic(TBlobStorageGroupInfo::EBlobState
return false;
}
-std::optional<EStrategyOutcome> TStrategyBase::SetAbsentForUnrecoverableAltruistic(
- TBlobStorageGroupInfo::EBlobState recoveryState, TBlobState &state) {
+std::optional<EStrategyOutcome> TStrategyBase::SetAbsentForUnrecoverableAltruistic(
+ TBlobStorageGroupInfo::EBlobState recoveryState, TBlobState &state) {
if (IsUnrecoverableAltruistic(recoveryState)) {
- state.WholeSituation = TBlobState::ESituation::Absent;
- return EStrategyOutcome::DONE;
+ state.WholeSituation = TBlobState::ESituation::Absent;
+ return EStrategyOutcome::DONE;
}
- return std::nullopt;
+ return std::nullopt;
}
-std::optional<EStrategyOutcome> TStrategyBase::ProcessOptimistic(TBlobStorageGroupInfo::EBlobState altruisticState,
+std::optional<EStrategyOutcome> TStrategyBase::ProcessOptimistic(TBlobStorageGroupInfo::EBlobState altruisticState,
TBlobStorageGroupInfo::EBlobState optimisticState, bool isDryRun, TBlobState &state) {
switch (optimisticState) {
- case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
- if (!isDryRun) {
- return EStrategyOutcome::Error(TStringBuilder() << "TStrategyBase saw optimisticState# "
+ case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
+ if (!isDryRun) {
+ return EStrategyOutcome::Error(TStringBuilder() << "TStrategyBase saw optimisticState# "
<< TBlobStorageGroupInfo::BlobStateToString(optimisticState));
}
- return EStrategyOutcome::DONE;
- case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
- if (altruisticState & TBlobStorageGroupInfo::EBSF_FRAGMENTARY) {
- if (!isDryRun) {
- state.WholeSituation = TBlobState::ESituation::Absent;
- }
- return EStrategyOutcome::DONE;
- } else {
- if (!isDryRun) {
- return EStrategyOutcome::Error(TStringBuilder() << "TStrategyBase saw optimisticState# "
+ return EStrategyOutcome::DONE;
+ case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
+ if (altruisticState & TBlobStorageGroupInfo::EBSF_FRAGMENTARY) {
+ if (!isDryRun) {
+ state.WholeSituation = TBlobState::ESituation::Absent;
+ }
+ return EStrategyOutcome::DONE;
+ } else {
+ if (!isDryRun) {
+ return EStrategyOutcome::Error(TStringBuilder() << "TStrategyBase saw optimisticState# "
<< TBlobStorageGroupInfo::BlobStateToString(optimisticState) << " with altruisticState# "
<< TBlobStorageGroupInfo::BlobStateToString(altruisticState));
- }
- return EStrategyOutcome::DONE;
+ }
+ return EStrategyOutcome::DONE;
}
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
- case TBlobStorageGroupInfo::EBS_FULL:
- break;
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
+ case TBlobStorageGroupInfo::EBS_FULL:
+ break;
}
- return std::nullopt;
+ return std::nullopt;
}
-std::optional<EStrategyOutcome> TStrategyBase::ProcessPessimistic(const TBlobStorageGroupInfo &info,
+std::optional<EStrategyOutcome> TStrategyBase::ProcessPessimistic(const TBlobStorageGroupInfo &info,
TBlobStorageGroupInfo::EBlobState pessimisticState, bool doVerify, TBlobState &state) {
switch (pessimisticState) {
- case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
- break;
- case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
- break;
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
- case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
- case TBlobStorageGroupInfo::EBS_FULL:
- if (state.Restore(info)) {
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE; // blob has been restored
+ case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
+ break;
+ case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
+ break;
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
+ case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
+ case TBlobStorageGroupInfo::EBS_FULL:
+ if (state.Restore(info)) {
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE; // blob has been restored
} else {
Y_VERIFY(!doVerify);
}
- break;
+ break;
}
- return std::nullopt;
+ return std::nullopt;
}
void TStrategyBase::AddGetRequest(TLogContext &logCtx, TGroupDiskRequests &groupDiskRequests, TLogoBlobID &fullId,
@@ -195,20 +195,20 @@ void TStrategyBase::AddGetRequest(TLogContext &logCtx, TGroupDiskRequests &group
bool TStrategyBase::VerifyTheWholeSituation(TBlobState &state) {
switch (state.WholeSituation) {
- case TBlobState::ESituation::Unknown:
- Y_FAIL("Blob Id# %s whole situation Unknown", state.Id.ToString().c_str());
- case TBlobState::ESituation::Lost:
- Y_FAIL("Blob Id# %s whole situation Lost", state.Id.ToString().c_str());
- case TBlobState::ESituation::Error:
- Y_FAIL("Blob Id# %s whole situation Error", state.Id.ToString().c_str());
- case TBlobState::ESituation::Sent:
- Y_FAIL("Blob Id# %s whole situation Sent", state.Id.ToString().c_str());
- case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Unknown:
+ Y_FAIL("Blob Id# %s whole situation Unknown", state.Id.ToString().c_str());
+ case TBlobState::ESituation::Lost:
+ Y_FAIL("Blob Id# %s whole situation Lost", state.Id.ToString().c_str());
+ case TBlobState::ESituation::Error:
+ Y_FAIL("Blob Id# %s whole situation Error", state.Id.ToString().c_str());
+ case TBlobState::ESituation::Sent:
+ Y_FAIL("Blob Id# %s whole situation Sent", state.Id.ToString().c_str());
+ case TBlobState::ESituation::Absent:
return true;
- case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Present:
return false;
}
- Y_FAIL("Blob Id# %s unexpected WholeSituation# %" PRIu32, state.Id.ToString().c_str(), (ui32)state.WholeSituation);
+ Y_FAIL("Blob Id# %s unexpected WholeSituation# %" PRIu32, state.Id.ToString().c_str(), (ui32)state.WholeSituation);
}
void TStrategyBase::PreparePartLayout(const TBlobState &state, const TBlobStorageGroupInfo &info,
@@ -226,7 +226,7 @@ void TStrategyBase::PreparePartLayout(const TBlobState &state, const TBlobStorag
bool isErrorDisk = false;
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Error) {
+ if (partSituation == TBlobState::ESituation::Error) {
isErrorDisk = true;
break;
}
@@ -234,7 +234,7 @@ void TStrategyBase::PreparePartLayout(const TBlobState &state, const TBlobStorag
if (!isErrorDisk) {
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Present ||
+ if (partSituation == TBlobState::ESituation::Present ||
(diskIdx != slowDiskIdx && partSituation == TBlobState::ESituation::Sent)) {
layout->VDiskPartMask[diskIdx] |= (1ul << partIdx);
}
@@ -257,15 +257,15 @@ bool TStrategyBase::IsPutNeeded(const TBlobState &state, const TBlobStorageGroup
const TBlobState::TDisk &disk = state.Disks[record.VDiskIdx];
TBlobState::ESituation partSituation = disk.DiskParts[record.PartIdx].Situation;
switch (partSituation) {
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
isNeeded = true;
break;
- case TBlobState::ESituation::Error:
- Y_FAIL("unexpected Situation");
- case TBlobState::ESituation::Present:
- case TBlobState::ESituation::Sent:
+ case TBlobState::ESituation::Error:
+ Y_FAIL("unexpected Situation");
+ case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Sent:
break;
}
}
@@ -312,17 +312,17 @@ void TStrategyBase::PreparePutsForPartPlacement(TLogContext &logCtx, TBlobState
<< " blob Id# " << TLogoBlobID(state.Id, record.PartIdx + 1).ToString());
bool isNeeded = false;
switch (partSituation) {
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
isNeeded = true;
break;
- case TBlobState::ESituation::Error:
+ case TBlobState::ESituation::Error:
Y_VERIFY(false);
break;
- case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Present:
break;
- case TBlobState::ESituation::Sent:
+ case TBlobState::ESituation::Sent:
break;
}
@@ -334,7 +334,7 @@ void TStrategyBase::PreparePutsForPartPlacement(TLogContext &logCtx, TBlobState
Y_VERIFY(state.Parts[record.PartIdx].Data.IsMonolith());
groupDiskRequests.AddPut(disk.OrderNumber, partId, state.Parts[record.PartIdx].Data.GetMonolith(),
TDiskPutRequest::ReasonInitial, info.Type.IsHandoffInSubgroup(record.VDiskIdx), state.BlobIdx);
- disk.DiskParts[record.PartIdx].Situation = TBlobState::ESituation::Sent;
+ disk.DiskParts[record.PartIdx].Situation = TBlobState::ESituation::Sent;
}
}
}
@@ -358,9 +358,9 @@ void TStrategyBase::Evaluate3dcSituation(const TBlobState &state,
const TBlobState::TDisk &disk = state.Disks[subgroupIdx];
const TBlobState::ESituation situation = disk.DiskParts[realm].Situation;
TBlobStorageGroupInfo::TSubgroupVDisks *subgroup = nullptr;
- if (situation == TBlobState::ESituation::Present) {
+ if (situation == TBlobState::ESituation::Present) {
subgroup = &inOutSuccess;
- } else if (situation == TBlobState::ESituation::Error || (considerSlowAsError && disk.IsSlow)) {
+ } else if (situation == TBlobState::ESituation::Error || (considerSlowAsError && disk.IsSlow)) {
subgroup = &inOutError;
numErrorsInRealm++;
}
@@ -385,11 +385,11 @@ void TStrategyBase::Prepare3dcPartPlacement(const TBlobState &state,
size_t subgroupIdx = RealmDomain2SubgroupIdx3dc(realm, domain, numFailRealms);
const TBlobState::TDisk &disk = state.Disks[subgroupIdx];
const TBlobState::ESituation situation = disk.DiskParts[realm].Situation;
- if (situation != TBlobState::ESituation::Error) {
- if (situation == TBlobState::ESituation::Present) {
+ if (situation != TBlobState::ESituation::Error) {
+ if (situation == TBlobState::ESituation::Present) {
placed++;
} else if (!considerSlowAsError || !disk.IsSlow) {
- if (situation != TBlobState::ESituation::Sent) {
+ if (situation != TBlobState::ESituation::Sent) {
outPartPlacement.Records.emplace_back(subgroupIdx, realm);
}
placed++;
@@ -407,7 +407,7 @@ i32 TStrategyBase::MarkSlowSubgroupDisk(TBlobState &state, const TBlobStorageGro
i32 worstSubgroupIdx = -1;
ui64 worstPredictedNs = 0;
ui64 nextToWorstPredictedNs = 0;
- state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
+ state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
(isPut ? HandleClassToQueueId(blackboard.PutHandleClass) :
HandleClassToQueueId(blackboard.GetHandleClass)),
&worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.h
index ca005dc9367..652f0681a87 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_base.h
@@ -26,10 +26,10 @@ protected:
TBlobStorageGroupInfo::EBlobState *optimisticState, TBlobStorageGroupInfo::EBlobState *altruisticState,
bool considerSlowAsError);
bool IsUnrecoverableAltruistic(TBlobStorageGroupInfo::EBlobState recoveryState);
- std::optional<EStrategyOutcome> SetAbsentForUnrecoverableAltruistic(TBlobStorageGroupInfo::EBlobState recoveryState, TBlobState &state);
- std::optional<EStrategyOutcome> ProcessOptimistic(TBlobStorageGroupInfo::EBlobState altruisticState,
+ std::optional<EStrategyOutcome> SetAbsentForUnrecoverableAltruistic(TBlobStorageGroupInfo::EBlobState recoveryState, TBlobState &state);
+ std::optional<EStrategyOutcome> ProcessOptimistic(TBlobStorageGroupInfo::EBlobState altruisticState,
TBlobStorageGroupInfo::EBlobState optimisticState, bool isDryRun, TBlobState &state);
- std::optional<EStrategyOutcome> ProcessPessimistic(const TBlobStorageGroupInfo &info, TBlobStorageGroupInfo::EBlobState pessimisticState,
+ std::optional<EStrategyOutcome> ProcessPessimistic(const TBlobStorageGroupInfo &info, TBlobStorageGroupInfo::EBlobState pessimisticState,
bool doVerify, TBlobState &state);
void AddGetRequest(TLogContext &logCtx, TGroupDiskRequests &groupDiskRequests, TLogoBlobID &fullId, ui32 partIdx,
TBlobState::TDisk &disk, TIntervalSet<i32> &intervalSet, const char *logMarker);
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_bold.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_bold.h
index 0ea411ef721..878b98d7cec 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_bold.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_bold.h
@@ -12,8 +12,8 @@ public:
PhantomCheck(phantomCheck) {
};
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
// Look at the current layout and set the status if possible
const ui32 totalPartCount = info.Type.TotalPartCount();
bool doLook = true;
@@ -46,37 +46,37 @@ public:
}
}
- // Prepare new request set
- const ui32 partSize = info.Type.PartSize(state.Id);
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- bool isHandoff = (diskIdx >= totalPartCount);
- ui32 beginPartIdx = (isHandoff ? 0 : diskIdx);
- ui32 endPartIdx = (isHandoff ? totalPartCount : (diskIdx + 1));
- for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
- TBlobState::TDisk &disk = state.Disks[diskIdx];
- TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
+ // Prepare new request set
+ const ui32 partSize = info.Type.PartSize(state.Id);
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ bool isHandoff = (diskIdx >= totalPartCount);
+ ui32 beginPartIdx = (isHandoff ? 0 : diskIdx);
+ ui32 endPartIdx = (isHandoff ? totalPartCount : (diskIdx + 1));
+ for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
+ TBlobState::TDisk &disk = state.Disks[diskIdx];
+ TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
TIntervalSet<i32> fullPartInterval(0, partSize);
- fullPartInterval.Subtract(state.Parts[partIdx].Here);
- fullPartInterval.Subtract(disk.DiskParts[partIdx].Requested);
- if (!fullPartInterval.IsEmpty()) {
- // TODO(cthulhu): Consider the case when we just need to know that there is a copy
- // and make an index request to avoid the data transfer.
- //
- // Actually consider that we dont need to prove anything if we can
- // read the data.
+ fullPartInterval.Subtract(state.Parts[partIdx].Here);
+ fullPartInterval.Subtract(disk.DiskParts[partIdx].Requested);
+ if (!fullPartInterval.IsEmpty()) {
+ // TODO(cthulhu): Consider the case when we just need to know that there is a copy
+ // and make an index request to avoid the data transfer.
+ //
+ // Actually consider that we dont need to prove anything if we can
+ // read the data.
- // TODO(cthulhu): Group logCtx, state, info and groupDiskRequests into a context.
+ // TODO(cthulhu): Group logCtx, state, info and groupDiskRequests into a context.
- AddGetRequest(logCtx, groupDiskRequests, state.Id, partIdx, disk,
- fullPartInterval, "BPG64");
+ AddGetRequest(logCtx, groupDiskRequests, state.Id, partIdx, disk,
+ fullPartInterval, "BPG64");
}
}
}
}
-
- return EStrategyOutcome::IN_PROGRESS;
+
+ return EStrategyOutcome::IN_PROGRESS;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_basic.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_basic.h
index c6476c941fb..eb9e219876f 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_basic.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_basic.h
@@ -1,32 +1,32 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include "dsproxy_blackboard.h"
-
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
-namespace NKikimr {
-
- class TMirror3dcBasicGetStrategy : public IStrategy {
- const TNodeLayoutInfoPtr& NodeLayout;
- const bool PhantomCheck;
-
- static constexpr ui32 NumRings = 3;
- static constexpr ui32 NumFailDomainsPerRing = 3;
-
- public:
- TMirror3dcBasicGetStrategy(const TNodeLayoutInfoPtr& nodeLayout, bool phantomCheck)
- : NodeLayout(nodeLayout)
- , PhantomCheck(phantomCheck)
- {}
-
+
+namespace NKikimr {
+
+ class TMirror3dcBasicGetStrategy : public IStrategy {
+ const TNodeLayoutInfoPtr& NodeLayout;
+ const bool PhantomCheck;
+
+ static constexpr ui32 NumRings = 3;
+ static constexpr ui32 NumFailDomainsPerRing = 3;
+
+ public:
+ TMirror3dcBasicGetStrategy(const TNodeLayoutInfoPtr& nodeLayout, bool phantomCheck)
+ : NodeLayout(nodeLayout)
+ , PhantomCheck(phantomCheck)
+ {}
+
bool DoRequestDisk(TBlobState& state, TGroupDiskRequests& groupDiskRequests, ui32 diskIdx) {
TBlobState::TDisk& disk = state.Disks[diskIdx];
// calculate part number from disk; ring always matches PartIdx
const ui32 partIdx = diskIdx % NumRings;
TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
switch (diskPart.Situation) {
- case TBlobState::ESituation::Unknown: {
+ case TBlobState::ESituation::Unknown: {
// get the request -- all the needed parts except already got and already requested
TIntervalSet<i32> request(state.Whole.Needed);
request.Subtract(state.Whole.Here);
@@ -43,198 +43,198 @@ namespace NKikimr {
// return true indicating that we have a request that is not yet satisfied
return true;
}
- case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Present:
break;
- case TBlobState::ESituation::Error:
+ case TBlobState::ESituation::Error:
break;
- case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Absent:
break;
- case TBlobState::ESituation::Lost:
+ case TBlobState::ESituation::Lost:
break;
- case TBlobState::ESituation::Sent:
+ case TBlobState::ESituation::Sent:
Y_FAIL("unexpected state");
}
return false;
}
- EStrategyOutcome Process(TLogContext& logCtx, TBlobState& state, const TBlobStorageGroupInfo& info,
+ EStrategyOutcome Process(TLogContext& logCtx, TBlobState& state, const TBlobStorageGroupInfo& info,
TBlackboard &blackboard, TGroupDiskRequests& groupDiskRequests) override {
- if (state.WholeSituation == TBlobState::ESituation::Present) {
- return EStrategyOutcome::DONE;
- }
-
- const ui32 totalPartCount = info.Type.TotalPartCount();
-
- // merge found data parts in our blob
- for (ui32 partIdx = 0; partIdx < totalPartCount; ++partIdx) {
- const TBlobState::TState& part = state.Parts[partIdx];
-
- // check if we can obtain some _new_ data from the part
- if (!part.Here.IsSubsetOf(state.Whole.Here)) {
- // scan through all the intervals
+ if (state.WholeSituation == TBlobState::ESituation::Present) {
+ return EStrategyOutcome::DONE;
+ }
+
+ const ui32 totalPartCount = info.Type.TotalPartCount();
+
+ // merge found data parts in our blob
+ for (ui32 partIdx = 0; partIdx < totalPartCount; ++partIdx) {
+ const TBlobState::TState& part = state.Parts[partIdx];
+
+ // check if we can obtain some _new_ data from the part
+ if (!part.Here.IsSubsetOf(state.Whole.Here)) {
+ // scan through all the intervals
for (const auto& range : part.Here) {
- ui64 begin = range.first;
- const ui64 end = range.second;
+ ui64 begin = range.first;
+ const ui64 end = range.second;
TIntervalVec<i32> interval(begin, end);
- // check if this interval contains some data which is not in state.Whole.Here
- if (!interval.IsSubsetOf(state.Whole.Here)) {
- char buffer[4096];
- while (begin != end) {
- const ui64 len = Min<ui64>(sizeof(buffer), end - begin);
- part.Data.Read(begin, buffer, len);
- state.Whole.Data.Write(begin, buffer, len);
- begin += len;
- }
- state.Whole.Here.Add(interval);
- }
+ // check if this interval contains some data which is not in state.Whole.Here
+ if (!interval.IsSubsetOf(state.Whole.Here)) {
+ char buffer[4096];
+ while (begin != end) {
+ const ui64 len = Min<ui64>(sizeof(buffer), end - begin);
+ part.Data.Read(begin, buffer, len);
+ state.Whole.Data.Write(begin, buffer, len);
+ begin += len;
+ }
+ state.Whole.Here.Add(interval);
+ }
+ }
+ }
+ }
+ if (state.Whole.Needed.IsSubsetOf(state.Whole.Here)) {
+ // we are not going to restore this blob and we have all required data read, so we can exit now
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
+ }
+
+ // issue request for a specific disk; returns true if the request was issued and not yet completed, otherwise
+ // false
+
+ // find the slowest disk and mark it
+ switch (blackboard.AccelerationMode) {
+ case TBlackboard::AccelerationModeSkipOneSlowest: {
+ i32 worstSubgroupIdx = -1;
+ ui64 worstPredictedNs = 0;
+ ui64 nextToWorstPredictedNs = 0;
+ state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
+ HandleClassToQueueId(blackboard.GetHandleClass),
+ &worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
+
+ // Check if the slowest disk exceptionally slow, or just not very fast
+ i32 slowDiskSubgroupIdx = -1;
+ if (nextToWorstPredictedNs > 0 && worstPredictedNs > nextToWorstPredictedNs * 2) {
+ slowDiskSubgroupIdx = worstSubgroupIdx;
+ }
+
+ // Mark single slow disk
+ for (size_t diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ state.Disks[diskIdx].IsSlow = false;
}
+ if (slowDiskSubgroupIdx >= 0) {
+ state.Disks[slowDiskSubgroupIdx].IsSlow = true;
+ }
+ break;
}
- }
- if (state.Whole.Needed.IsSubsetOf(state.Whole.Here)) {
- // we are not going to restore this blob and we have all required data read, so we can exit now
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
- }
-
- // issue request for a specific disk; returns true if the request was issued and not yet completed, otherwise
- // false
-
- // find the slowest disk and mark it
- switch (blackboard.AccelerationMode) {
- case TBlackboard::AccelerationModeSkipOneSlowest: {
- i32 worstSubgroupIdx = -1;
- ui64 worstPredictedNs = 0;
- ui64 nextToWorstPredictedNs = 0;
- state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
- HandleClassToQueueId(blackboard.GetHandleClass),
- &worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
-
- // Check if the slowest disk exceptionally slow, or just not very fast
- i32 slowDiskSubgroupIdx = -1;
- if (nextToWorstPredictedNs > 0 && worstPredictedNs > nextToWorstPredictedNs * 2) {
- slowDiskSubgroupIdx = worstSubgroupIdx;
- }
-
- // Mark single slow disk
- for (size_t diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- state.Disks[diskIdx].IsSlow = false;
- }
- if (slowDiskSubgroupIdx >= 0) {
- state.Disks[slowDiskSubgroupIdx].IsSlow = true;
- }
- break;
+ case TBlackboard::AccelerationModeSkipMarked:
+ // The slowest disk is already marked!
+ break;
+ }
+
+ // create an array defining order in which we traverse the disks
+ TStackVec<ui32, 32> diskIdxList;
+ for (ui32 i = 0; i < state.Disks.size(); ++i) {
+ diskIdxList.push_back(i);
+ }
+
+ // calculate distance (in relative units) to the disk from our node
+ // non-main replicas get +1 second-level score
+ // marked slow get +2 second-level score
+ // sort according to this distance high part indicates fail
+ // domain -- we want to scan for main replicas first, then scan handoff
+ auto distance = [&](ui32 diskIdx) {
+ const bool isMain = diskIdx < NumRings;
+ const bool isSlow = state.Disks[diskIdx].IsSlow;
+ ui64 score = static_cast<ui64>((isMain ? 0 : 1) + (isSlow ? 2 : 0)) << 32;
+
+ if (NodeLayout) {
+ const ui32 orderNumber = state.Disks[diskIdx].OrderNumber;
+ const auto& diskItems = NodeLayout->LocationPerOrderNumber[orderNumber].GetItems();
+ const auto& selfItems = NodeLayout->SelfLocation.GetItems();
+ i64 commonPrefixKey = Min<int>();
+ for (auto diskIt = diskItems.begin(), selfIt = selfItems.begin();; ++diskIt, ++selfIt) {
+ if (diskIt == diskItems.end() || selfIt == selfItems.end() || *diskIt != *selfIt) {
+ break;
+ }
+ commonPrefixKey = diskIt->first;
+ }
+ score += Max<int>() - commonPrefixKey;
+ }
+
+ return score;
+ };
+ auto compare = [&](ui32 x, ui32 y) {
+ return distance(x) < distance(y);
+ };
+ std::sort(diskIdxList.begin(), diskIdxList.end(), compare);
+
+
+ // scan all disks and try to generate new request
+ bool requested = false; // was the new request generated or not
+ for (ui32 diskIdx : diskIdxList) {
+ if ((requested = DoRequestDisk(state, groupDiskRequests, diskIdx))) {
+ break;
+ }
+ }
+
+ TBlobStorageGroupInfo::TSubgroupVDisks failed(&info.GetTopology()), possiblyWritten(&info.GetTopology());
+ TStackVec<TBlobState::ESituation, NumRings * NumFailDomainsPerRing> situations;
+ for (ui32 diskIdx : diskIdxList) {
+ TBlobState::TDisk& disk = state.Disks[diskIdx];
+ const ui32 partIdx = diskIdx % NumRings;
+ const TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
+ switch (diskPart.Situation) {
+ case TBlobState::ESituation::Error:
+ failed += TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ [[fallthrough]];
+ case TBlobState::ESituation::Lost:
+ possiblyWritten += TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ break;
+ default:
+ break;
}
- case TBlackboard::AccelerationModeSkipMarked:
- // The slowest disk is already marked!
- break;
- }
-
- // create an array defining order in which we traverse the disks
- TStackVec<ui32, 32> diskIdxList;
- for (ui32 i = 0; i < state.Disks.size(); ++i) {
- diskIdxList.push_back(i);
- }
-
- // calculate distance (in relative units) to the disk from our node
- // non-main replicas get +1 second-level score
- // marked slow get +2 second-level score
- // sort according to this distance high part indicates fail
- // domain -- we want to scan for main replicas first, then scan handoff
- auto distance = [&](ui32 diskIdx) {
- const bool isMain = diskIdx < NumRings;
- const bool isSlow = state.Disks[diskIdx].IsSlow;
- ui64 score = static_cast<ui64>((isMain ? 0 : 1) + (isSlow ? 2 : 0)) << 32;
-
- if (NodeLayout) {
- const ui32 orderNumber = state.Disks[diskIdx].OrderNumber;
- const auto& diskItems = NodeLayout->LocationPerOrderNumber[orderNumber].GetItems();
- const auto& selfItems = NodeLayout->SelfLocation.GetItems();
- i64 commonPrefixKey = Min<int>();
- for (auto diskIt = diskItems.begin(), selfIt = selfItems.begin();; ++diskIt, ++selfIt) {
- if (diskIt == diskItems.end() || selfIt == selfItems.end() || *diskIt != *selfIt) {
- break;
- }
- commonPrefixKey = diskIt->first;
- }
- score += Max<int>() - commonPrefixKey;
- }
-
- return score;
- };
- auto compare = [&](ui32 x, ui32 y) {
- return distance(x) < distance(y);
- };
- std::sort(diskIdxList.begin(), diskIdxList.end(), compare);
-
-
- // scan all disks and try to generate new request
- bool requested = false; // was the new request generated or not
- for (ui32 diskIdx : diskIdxList) {
- if ((requested = DoRequestDisk(state, groupDiskRequests, diskIdx))) {
- break;
- }
- }
-
- TBlobStorageGroupInfo::TSubgroupVDisks failed(&info.GetTopology()), possiblyWritten(&info.GetTopology());
- TStackVec<TBlobState::ESituation, NumRings * NumFailDomainsPerRing> situations;
- for (ui32 diskIdx : diskIdxList) {
- TBlobState::TDisk& disk = state.Disks[diskIdx];
- const ui32 partIdx = diskIdx % NumRings;
- const TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
- switch (diskPart.Situation) {
- case TBlobState::ESituation::Error:
- failed += TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- [[fallthrough]];
- case TBlobState::ESituation::Lost:
- possiblyWritten += TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- break;
- default:
- break;
- }
- situations.push_back(diskPart.Situation);
- }
-
- if (!info.GetQuorumChecker().CheckFailModelForSubgroup(failed)) {
- return EStrategyOutcome::Error("TMirror3dcBasicGetStrategy failed the Fail Model check");
- } else if (requested) {
- // we can't finish request now, because the VGet was just issued or still being executed, so we
- // drop status to UNKNOWN
- return EStrategyOutcome::IN_PROGRESS;
- } else if (!state.Whole.Needed.IsSubsetOf(state.Whole.Here)) {
- // we haven't requested anything, but there is no required data in buffer, so blob is lost
- R_LOG_WARN_SX(logCtx, "BPG48", "missing blob# " << state.Id.ToString() << " state# " << state.ToString());
- state.WholeSituation = TBlobState::ESituation::Absent;
- if (PhantomCheck || info.GetQuorumChecker().CheckQuorumForSubgroup(possiblyWritten)) {
- // this blob is either:
- // 1. Has full quorum of Lost & Error replies
- // 2. Is checked for being phantom during replication
- // in both cases we return Absent only when there are only Lost and Absent replies from the disks,
- // otherwise we return ERROR assuming this blob could be restored
- for (const TBlobState::ESituation situation : situations) {
- switch (situation) {
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
- // these statuses do not lead to error as they represent missing blob data
- break;
-
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Present:
- case TBlobState::ESituation::Sent:
- // unexpected state
- Y_VERIFY_DEBUG(false);
- [[fallthrough]];
- case TBlobState::ESituation::Error:
- state.WholeSituation = TBlobState::ESituation::Error;
- break;
- }
- }
- }
- return EStrategyOutcome::DONE;
- } else {
- Y_FAIL("must not reach this point");
- }
- }
- };
-
-} // NKikimr
+ situations.push_back(diskPart.Situation);
+ }
+
+ if (!info.GetQuorumChecker().CheckFailModelForSubgroup(failed)) {
+ return EStrategyOutcome::Error("TMirror3dcBasicGetStrategy failed the Fail Model check");
+ } else if (requested) {
+ // we can't finish request now, because the VGet was just issued or still being executed, so we
+ // drop status to UNKNOWN
+ return EStrategyOutcome::IN_PROGRESS;
+ } else if (!state.Whole.Needed.IsSubsetOf(state.Whole.Here)) {
+ // we haven't requested anything, but there is no required data in buffer, so blob is lost
+ R_LOG_WARN_SX(logCtx, "BPG48", "missing blob# " << state.Id.ToString() << " state# " << state.ToString());
+ state.WholeSituation = TBlobState::ESituation::Absent;
+ if (PhantomCheck || info.GetQuorumChecker().CheckQuorumForSubgroup(possiblyWritten)) {
+ // this blob is either:
+ // 1. Has full quorum of Lost & Error replies
+ // 2. Is checked for being phantom during replication
+ // in both cases we return Absent only when there are only Lost and Absent replies from the disks,
+ // otherwise we return ERROR assuming this blob could be restored
+ for (const TBlobState::ESituation situation : situations) {
+ switch (situation) {
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
+ // these statuses do not lead to error as they represent missing blob data
+ break;
+
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Sent:
+ // unexpected state
+ Y_VERIFY_DEBUG(false);
+ [[fallthrough]];
+ case TBlobState::ESituation::Error:
+ state.WholeSituation = TBlobState::ESituation::Error;
+ break;
+ }
+ }
+ }
+ return EStrategyOutcome::DONE;
+ } else {
+ Y_FAIL("must not reach this point");
+ }
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h
index 161a1b3f9f5..4b45cb850b2 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h
@@ -1,82 +1,82 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include "dsproxy_blackboard.h"
#include "dsproxy_strategy_put_m3dc.h"
-
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
-namespace NKikimr {
-
- class TMirror3dcGetWithRestoreStrategy : public IStrategy {
- static constexpr ui32 NumRings = 3;
- static constexpr ui32 NumFailDomainsPerRing = 3;
-
- public:
- EStrategyOutcome Process(TLogContext& logCtx, TBlobState& state, const TBlobStorageGroupInfo& info,
- TBlackboard& blackboard, TGroupDiskRequests& groupDiskRequests) override {
- if (state.WholeSituation == TBlobState::ESituation::Present) {
- return EStrategyOutcome::DONE;
- }
-
+
+namespace NKikimr {
+
+ class TMirror3dcGetWithRestoreStrategy : public IStrategy {
+ static constexpr ui32 NumRings = 3;
+ static constexpr ui32 NumFailDomainsPerRing = 3;
+
+ public:
+ EStrategyOutcome Process(TLogContext& logCtx, TBlobState& state, const TBlobStorageGroupInfo& info,
+ TBlackboard& blackboard, TGroupDiskRequests& groupDiskRequests) override {
+ if (state.WholeSituation == TBlobState::ESituation::Present) {
+ return EStrategyOutcome::DONE;
+ }
+
// The way to check disk status:
// Send reads to all disks
PrepareGets(logCtx, state, groupDiskRequests);
// If blob is absent, done
- if (auto res = CheckForFailureErrorNoData(logCtx, state, info)) {
- return *res;
+ if (auto res = CheckForFailureErrorNoData(logCtx, state, info)) {
+ return *res;
}
// If blob is present at main, done
// If blob is present in 2 domains x 2 rings, done
if (BlobIsPresentAtMainOr2x2(state)) {
- // everything is in place -- all data is present; generate output blob content and signal success for
- // this one
- CreateOutputBlob(state);
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
+ // everything is in place -- all data is present; generate output blob content and signal success for
+ // this one
+ CreateOutputBlob(state);
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
}
// Wait until fail-model is satisfied
if (!IsGetFailModelSatisfied(state, info)) {
// the request hasn't completed yet, so we shall wait for it; we will re-enter this function when
// something gets changed
- return EStrategyOutcome::IN_PROGRESS;
- }
+ return EStrategyOutcome::IN_PROGRESS;
+ }
// Remaining disks may never answer, start the restoration
CreateOutputBlob(state);
// Wait for at least one DATA response
if (!state.Whole.Needed.IsSubsetOf(state.Whole.Here)) {
- return EStrategyOutcome::IN_PROGRESS;
+ return EStrategyOutcome::IN_PROGRESS;
}
// Try to send puts considering the slow disk
// on failure, send puts
// On 'accelerate' signal, try to send more puts considering the slow disk
- Y_VERIFY(state.WholeSituation == TBlobState::ESituation::Unknown,
+ Y_VERIFY(state.WholeSituation == TBlobState::ESituation::Unknown,
"Blob Id# %s unexpected whole situation %" PRIu32,
state.Id.ToString().c_str(), ui32(state.WholeSituation));
- state.WholeSituation = TBlobState::ESituation::Present;
+ state.WholeSituation = TBlobState::ESituation::Present;
const EStrategyOutcome outcome = TPut3dcStrategy(TEvBlobStorage::TEvPut::TacticMaxThroughput, false).Process(logCtx,
- state, info, blackboard, groupDiskRequests);
- switch (outcome) {
- case EStrategyOutcome::IN_PROGRESS:
- state.WholeSituation = TBlobState::ESituation::Unknown;
- break;
-
- case EStrategyOutcome::ERROR:
- case EStrategyOutcome::DONE:
- break;
+ state, info, blackboard, groupDiskRequests);
+ switch (outcome) {
+ case EStrategyOutcome::IN_PROGRESS:
+ state.WholeSituation = TBlobState::ESituation::Unknown;
+ break;
+
+ case EStrategyOutcome::ERROR:
+ case EStrategyOutcome::DONE:
+ break;
}
- return outcome;
- }
-
- private:
+ return outcome;
+ }
+
+ private:
static void PrepareGets(TLogContext& logCtx, TBlobState& state, TGroupDiskRequests& groupDiskRequests) {
const TIntervalVec<i32> needed(0, state.Id.BlobSize()); // we need to query this interval
for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
TBlobState::TDisk& disk = state.Disks[diskIdx];
const ui32 partIdx = diskIdx % NumRings;
TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
- if (diskPart.Situation == TBlobState::ESituation::Unknown) {
+ if (diskPart.Situation == TBlobState::ESituation::Unknown) {
if (diskPart.Requested.IsEmpty()) {
TLogoBlobID id(state.Id, partIdx + 1);
groupDiskRequests.AddGet(disk.OrderNumber, id, needed);
@@ -99,7 +99,7 @@ namespace NKikimr {
const TBlobState::TDisk& disk = state.Disks[diskIdx];
const ui32 partIdx = diskIdx % NumRings;
const TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
- if (diskPart.Situation == TBlobState::ESituation::Unknown) {
+ if (diskPart.Situation == TBlobState::ESituation::Unknown) {
beingWaitedFor |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
}
}
@@ -110,25 +110,25 @@ namespace NKikimr {
static void CreateOutputBlob(TBlobState& state) {
- for (const TBlobState::TState& part : state.Parts) {
- // calculate the interval of the part buffer we have to copy into the output buffer
+ for (const TBlobState::TState& part : state.Parts) {
+ // calculate the interval of the part buffer we have to copy into the output buffer
TIntervalSet<i32> dataToAdd(part.Here);
- dataToAdd.Subtract(state.Whole.Here);
- state.Whole.Here.Add(dataToAdd);
+ dataToAdd.Subtract(state.Whole.Here);
+ state.Whole.Here.Add(dataToAdd);
for (const auto& range : dataToAdd) {
- ui32 begin = range.first;
- const ui32 end = range.second;
- char buffer[4096];
- while (begin != end) {
- const ui64 len = Min<ui64>(sizeof(buffer), end - begin);
- part.Data.Read(begin, buffer, len);
- state.Whole.Data.Write(begin, buffer, len);
- begin += len;
- }
- }
- }
- }
-
+ ui32 begin = range.first;
+ const ui32 end = range.second;
+ char buffer[4096];
+ while (begin != end) {
+ const ui64 len = Min<ui64>(sizeof(buffer), end - begin);
+ part.Data.Read(begin, buffer, len);
+ state.Whole.Data.Write(begin, buffer, len);
+ begin += len;
+ }
+ }
+ }
+ }
+
static bool BlobIsPresentAtMainOr2x2(const TBlobState& state) {
ui32 numPresentRings = 0;
ui32 numPresentX2Rings = 0;
@@ -136,71 +136,71 @@ namespace NKikimr {
ui32 numPresent = 0;
for (ui32 fd = 0; fd < NumFailDomainsPerRing; ++fd) {
const ui32 diskIdx = fd * NumRings + partIdx;
- numPresent += state.Disks[diskIdx].DiskParts[partIdx].Situation == TBlobState::ESituation::Present;
- }
+ numPresent += state.Disks[diskIdx].DiskParts[partIdx].Situation == TBlobState::ESituation::Present;
+ }
if (numPresent) {
++numPresentRings;
if (numPresent >= 2) {
++numPresentX2Rings;
}
}
- }
+ }
return numPresentRings == NumRings || numPresentX2Rings >= 2;
- }
-
- std::optional<EStrategyOutcome> CheckForFailureErrorNoData(TLogContext& logCtx, TBlobState& state,
- const TBlobStorageGroupInfo& info) {
+ }
+
+ std::optional<EStrategyOutcome> CheckForFailureErrorNoData(TLogContext& logCtx, TBlobState& state,
+ const TBlobStorageGroupInfo& info) {
ui32 altruisticPresentCount = 0;
- // calculate subsets of disks with present replicas and failed disks
- TBlobStorageGroupInfo::TSubgroupVDisks present(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks failed(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks possiblyWritten(&info.GetTopology());
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- const TBlobState::TDisk& disk = state.Disks[diskIdx];
- const ui32 partIdx = diskIdx % NumRings;
- const TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
- switch (diskPart.Situation) {
- case TBlobState::ESituation::Sent:
- case TBlobState::ESituation::Present:
- case TBlobState::ESituation::Unknown:
+ // calculate subsets of disks with present replicas and failed disks
+ TBlobStorageGroupInfo::TSubgroupVDisks present(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks failed(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks possiblyWritten(&info.GetTopology());
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ const TBlobState::TDisk& disk = state.Disks[diskIdx];
+ const ui32 partIdx = diskIdx % NumRings;
+ const TBlobState::TDiskPart& diskPart = disk.DiskParts[partIdx];
+ switch (diskPart.Situation) {
+ case TBlobState::ESituation::Sent:
+ case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Unknown:
++altruisticPresentCount;
- break;
-
- case TBlobState::ESituation::Absent:
- // just ignore this one
- break;
-
- case TBlobState::ESituation::Lost:
- possiblyWritten |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- break;
-
- case TBlobState::ESituation::Error:
- failed |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- break;
- }
- }
-
+ break;
+
+ case TBlobState::ESituation::Absent:
+ // just ignore this one
+ break;
+
+ case TBlobState::ESituation::Lost:
+ possiblyWritten |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ break;
+
+ case TBlobState::ESituation::Error:
+ failed |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ break;
+ }
+ }
+
A_LOG_DEBUG_SX(logCtx, "3DCGR02", "CheckForFailureErrorNoData"
- << " state# " << state.ToString());
-
- // check if we do not excess the fail model
- const auto& checker = info.GetQuorumChecker();
- if (!checker.CheckFailModelForSubgroup(failed)) {
- return EStrategyOutcome::Error("TMirror3dcGetWithRestoreStrategy failed the Fail Model check");
- }
-
+ << " state# " << state.ToString());
+
+ // check if we do not excess the fail model
+ const auto& checker = info.GetQuorumChecker();
+ if (!checker.CheckFailModelForSubgroup(failed)) {
+ return EStrategyOutcome::Error("TMirror3dcGetWithRestoreStrategy failed the Fail Model check");
+ }
+
// check if there is a part that can be used to put the blob (or at least some hope of obtaining such part)
if (altruisticPresentCount) {
- return std::nullopt;
- }
+ return std::nullopt;
+ }
// if we got here, the blob is definitely absent
-
+
possiblyWritten |= failed; // they may have been written too
state.WholeSituation = checker.CheckQuorumForSubgroup(possiblyWritten)
- ? TBlobState::ESituation::Error // this blob was probably written, but we can't reach it
- : TBlobState::ESituation::Absent; // this blob definitely wasn't written
- return EStrategyOutcome::DONE;
- }
- };
-
-} // NKikimr
+ ? TBlobState::ESituation::Error // this blob was probably written, but we can't reach it
+ : TBlobState::ESituation::Absent; // this blob definitely wasn't written
+ return EStrategyOutcome::DONE;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3of4.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3of4.h
index 30abbb26874..c6d9920902b 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3of4.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3of4.h
@@ -1,178 +1,178 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_strategy_m3of4_base.h"
-
-namespace NKikimr {
-
- class TMirror3of4GetStrategy : public TMirror3of4StrategyBase {
- public:
- EStrategyOutcome Process(TLogContext& /*logCtx*/, TBlobState& state, const TBlobStorageGroupInfo& info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests& groupDiskRequests) override {
- if (!CheckFailModel(state, info)) {
- state.WholeSituation = TBlobState::ESituation::Error;
- return EStrategyOutcome::Error("failure model exceeded");
- }
-
- // check if the blob is already restored and can be returned to caller
- if (state.WholeSituation == TBlobState::ESituation::Present || Restore(state, info)) {
- state.WholeSituation = TBlobState::ESituation::Present;
- Y_VERIFY(state.Whole.Data && state.Whole.Data.GetTotalSize(), "%s", state.ToString().data());
- return EStrategyOutcome::DONE;
- }
-
- TGroups groups;
-
- ui32 numRequested = 0;
- ui32 numDone = 0;
-
- TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&info.GetTopology());
-
- for (auto& group : groups.Groups) {
- ui32 untouched = 0;
- ui32 done = 0;
- for (const ui32 diskIdx : group.DiskIdx) {
- auto& p = state.Disks[diskIdx].DiskParts[group.PartIdx];
- switch (p.Situation) {
- // query is either unsent or unanswered for this disk/part
- case TBlobState::ESituation::Unknown:
- untouched += p.Requested.IsEmpty();
- break;
-
- // if this disk has answered the query
- case TBlobState::ESituation::Error:
- failedSubgroupDisks |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- [[fallthrough]];
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
- case TBlobState::ESituation::Present:
- ++done;
- break;
-
- default:
- Y_FAIL();
- }
- group.NumSlowDisks += state.Disks[diskIdx].IsSlow;
- }
- Y_VERIFY(untouched == 3 || untouched == 0);
- group.Requested = !untouched;
- numRequested += group.Requested;
- group.Done = done == 3;
- numDone += group.Done;
- }
-
- ui32 numRequestedMetadata = 0;
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- const auto& disk = state.Disks[diskIdx];
-
- switch (disk.DiskParts[MetadataPartIdx].Situation) {
- case TBlobState::ESituation::Unknown:
- break;
-
- case TBlobState::ESituation::Error:
- failedSubgroupDisks |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
- [[fallthrough]];
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
- case TBlobState::ESituation::Present:
- ++numRequestedMetadata;
- break;
-
- case TBlobState::ESituation::Sent:
- Y_FAIL();
- }
- }
-
- if (numRequested != numDone) { // any pending groups?
- Y_VERIFY(numRequested == numDone + 1);
- } else if (numRequested != std::size(groups.Groups)) {
- // we have to find the next group that is not requested yet
- TStackVec<TGroups::TGroupInfo*, 4> candidates;
- for (auto& group : groups.Groups) {
- if (!group.Requested) {
- candidates.push_back(&group);
- }
- }
- // leave the slow group for the last query
- auto pred = [](const auto *x, const auto *y) { return x->NumSlowDisks < y->NumSlowDisks; };
- std::stable_sort(candidates.begin(), candidates.end(), pred);
- // pick the first candidate
- Y_VERIFY(candidates);
- auto& group = *candidates.front();
- // issue queries
- for (const ui32 diskIdx : group.DiskIdx) {
- auto& disk = state.Disks[diskIdx];
- auto& part = disk.DiskParts[group.PartIdx];
- Y_VERIFY(part.Requested.IsEmpty()); // ensure we haven't requested any data yet
- const TLogoBlobID id(state.Id, group.PartIdx + 1);
- groupDiskRequests.AddGet(disk.OrderNumber, id, state.Whole.NotHere);
- part.Requested.Add(state.Whole.NotHere);
- }
- } else if (!numRequestedMetadata) { // no metadata was requested, but we need it to make decision -- issue queries to all disks
- for (auto& disk : state.Disks) {
- groupDiskRequests.AddGet(disk.OrderNumber, TLogoBlobID(state.Id, MetadataPartIdx + 1), 0, 0);
- }
- } else if (numRequestedMetadata == state.Disks.size()) {
- state.WholeSituation = CouldHaveBeenWritten(state, info)
- ? TBlobState::ESituation::Error // blob could have been written, we can't just report NODATA
- : TBlobState::ESituation::Absent; // blob couldn't have been written, we treat it as absent one
- return EStrategyOutcome::DONE;
- }
-
- return EStrategyOutcome::IN_PROGRESS; // shall wait for more answers
- }
-
- private:
- bool Restore(TBlobState& state, const TBlobStorageGroupInfo& info) {
- const ui32 totalParts = info.Type.TotalPartCount();
- for (ui32 i = 0; i < totalParts; ++i) {
- if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(state.Id, i + 1))) {
- TBlobState::TState& part = state.Parts[i];
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_strategy_m3of4_base.h"
+
+namespace NKikimr {
+
+ class TMirror3of4GetStrategy : public TMirror3of4StrategyBase {
+ public:
+ EStrategyOutcome Process(TLogContext& /*logCtx*/, TBlobState& state, const TBlobStorageGroupInfo& info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests& groupDiskRequests) override {
+ if (!CheckFailModel(state, info)) {
+ state.WholeSituation = TBlobState::ESituation::Error;
+ return EStrategyOutcome::Error("failure model exceeded");
+ }
+
+ // check if the blob is already restored and can be returned to caller
+ if (state.WholeSituation == TBlobState::ESituation::Present || Restore(state, info)) {
+ state.WholeSituation = TBlobState::ESituation::Present;
+ Y_VERIFY(state.Whole.Data && state.Whole.Data.GetTotalSize(), "%s", state.ToString().data());
+ return EStrategyOutcome::DONE;
+ }
+
+ TGroups groups;
+
+ ui32 numRequested = 0;
+ ui32 numDone = 0;
+
+ TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&info.GetTopology());
+
+ for (auto& group : groups.Groups) {
+ ui32 untouched = 0;
+ ui32 done = 0;
+ for (const ui32 diskIdx : group.DiskIdx) {
+ auto& p = state.Disks[diskIdx].DiskParts[group.PartIdx];
+ switch (p.Situation) {
+ // query is either unsent or unanswered for this disk/part
+ case TBlobState::ESituation::Unknown:
+ untouched += p.Requested.IsEmpty();
+ break;
+
+ // if this disk has answered the query
+ case TBlobState::ESituation::Error:
+ failedSubgroupDisks |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ [[fallthrough]];
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
+ case TBlobState::ESituation::Present:
+ ++done;
+ break;
+
+ default:
+ Y_FAIL();
+ }
+ group.NumSlowDisks += state.Disks[diskIdx].IsSlow;
+ }
+ Y_VERIFY(untouched == 3 || untouched == 0);
+ group.Requested = !untouched;
+ numRequested += group.Requested;
+ group.Done = done == 3;
+ numDone += group.Done;
+ }
+
+ ui32 numRequestedMetadata = 0;
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ const auto& disk = state.Disks[diskIdx];
+
+ switch (disk.DiskParts[MetadataPartIdx].Situation) {
+ case TBlobState::ESituation::Unknown:
+ break;
+
+ case TBlobState::ESituation::Error:
+ failedSubgroupDisks |= TBlobStorageGroupInfo::TSubgroupVDisks(&info.GetTopology(), diskIdx);
+ [[fallthrough]];
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
+ case TBlobState::ESituation::Present:
+ ++numRequestedMetadata;
+ break;
+
+ case TBlobState::ESituation::Sent:
+ Y_FAIL();
+ }
+ }
+
+ if (numRequested != numDone) { // any pending groups?
+ Y_VERIFY(numRequested == numDone + 1);
+ } else if (numRequested != std::size(groups.Groups)) {
+ // we have to find the next group that is not requested yet
+ TStackVec<TGroups::TGroupInfo*, 4> candidates;
+ for (auto& group : groups.Groups) {
+ if (!group.Requested) {
+ candidates.push_back(&group);
+ }
+ }
+ // leave the slow group for the last query
+ auto pred = [](const auto *x, const auto *y) { return x->NumSlowDisks < y->NumSlowDisks; };
+ std::stable_sort(candidates.begin(), candidates.end(), pred);
+ // pick the first candidate
+ Y_VERIFY(candidates);
+ auto& group = *candidates.front();
+ // issue queries
+ for (const ui32 diskIdx : group.DiskIdx) {
+ auto& disk = state.Disks[diskIdx];
+ auto& part = disk.DiskParts[group.PartIdx];
+ Y_VERIFY(part.Requested.IsEmpty()); // ensure we haven't requested any data yet
+ const TLogoBlobID id(state.Id, group.PartIdx + 1);
+ groupDiskRequests.AddGet(disk.OrderNumber, id, state.Whole.NotHere);
+ part.Requested.Add(state.Whole.NotHere);
+ }
+ } else if (!numRequestedMetadata) { // no metadata was requested, but we need it to make decision -- issue queries to all disks
+ for (auto& disk : state.Disks) {
+ groupDiskRequests.AddGet(disk.OrderNumber, TLogoBlobID(state.Id, MetadataPartIdx + 1), 0, 0);
+ }
+ } else if (numRequestedMetadata == state.Disks.size()) {
+ state.WholeSituation = CouldHaveBeenWritten(state, info)
+ ? TBlobState::ESituation::Error // blob could have been written, we can't just report NODATA
+ : TBlobState::ESituation::Absent; // blob couldn't have been written, we treat it as absent one
+ return EStrategyOutcome::DONE;
+ }
+
+ return EStrategyOutcome::IN_PROGRESS; // shall wait for more answers
+ }
+
+ private:
+ bool Restore(TBlobState& state, const TBlobStorageGroupInfo& info) {
+ const ui32 totalParts = info.Type.TotalPartCount();
+ for (ui32 i = 0; i < totalParts; ++i) {
+ if (const ui32 partSize = info.Type.PartSize(TLogoBlobID(state.Id, i + 1))) {
+ TBlobState::TState& part = state.Parts[i];
if (const TIntervalSet<i32> pending = part.Here & state.Whole.NotHere) {
- state.Whole.Data.CopyFrom(part.Data, pending);
- state.Whole.Here |= pending;
- state.Whole.NotHere -= pending;
- }
- }
- }
- return !state.Whole.NotHere;
- }
-
- bool CouldHaveBeenWritten(TBlobState& state, const TBlobStorageGroupInfo& info) {
- TBlobStorageGroupInfo::TSubgroupVDisks data(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks any(&info.GetTopology());
-
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- const auto& disk = state.Disks[diskIdx];
-
- for (ui32 partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
- const auto& part = disk.DiskParts[partIdx];
-
- switch (part.Situation) {
- case TBlobState::ESituation::Unknown: // we should have already probed all parts on all disks
- Y_VERIFY(!DiskPartsAllowed[partIdx][diskIdx]);
- break;
-
- case TBlobState::ESituation::Sent: // incorrect state
- Y_FAIL();
-
- case TBlobState::ESituation::Absent:
- break;
-
- case TBlobState::ESituation::Error: // on error we assume that the part is here
- case TBlobState::ESituation::Lost: // on NOT_YET we also assume that part was written here
- case TBlobState::ESituation::Present: // it is actually here :)
- any |= {&info.GetTopology(), diskIdx};
- if (info.Type.PartSize(TLogoBlobID(state.Id, partIdx + 1))) {
- data |= {&info.GetTopology(), diskIdx};
- }
- break;
- }
- }
- }
-
- return data.GetNumSetItems() >= 3 && any.GetNumSetItems() >= 5;
- }
- };
-
-} // NKikimr
+ state.Whole.Data.CopyFrom(part.Data, pending);
+ state.Whole.Here |= pending;
+ state.Whole.NotHere -= pending;
+ }
+ }
+ }
+ return !state.Whole.NotHere;
+ }
+
+ bool CouldHaveBeenWritten(TBlobState& state, const TBlobStorageGroupInfo& info) {
+ TBlobStorageGroupInfo::TSubgroupVDisks data(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks any(&info.GetTopology());
+
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ const auto& disk = state.Disks[diskIdx];
+
+ for (ui32 partIdx = 0; partIdx < disk.DiskParts.size(); ++partIdx) {
+ const auto& part = disk.DiskParts[partIdx];
+
+ switch (part.Situation) {
+ case TBlobState::ESituation::Unknown: // we should have already probed all parts on all disks
+ Y_VERIFY(!DiskPartsAllowed[partIdx][diskIdx]);
+ break;
+
+ case TBlobState::ESituation::Sent: // incorrect state
+ Y_FAIL();
+
+ case TBlobState::ESituation::Absent:
+ break;
+
+ case TBlobState::ESituation::Error: // on error we assume that the part is here
+ case TBlobState::ESituation::Lost: // on NOT_YET we also assume that part was written here
+ case TBlobState::ESituation::Present: // it is actually here :)
+ any |= {&info.GetTopology(), diskIdx};
+ if (info.Type.PartSize(TLogoBlobID(state.Id, partIdx + 1))) {
+ data |= {&info.GetTopology(), diskIdx};
+ }
+ break;
+ }
+ }
+ }
+
+ return data.GetNumSetItems() >= 3 && any.GetNumSetItems() >= 5;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_block.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_block.h
index d191f110060..90d96f888b3 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_block.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_block.h
@@ -7,7 +7,7 @@ namespace NKikimr {
class TMinIopsBlockStrategy : public TStrategyBase {
public:
- std::optional<EStrategyOutcome> RestoreWholeFromDataParts(TLogContext& /*logCtx*/, TBlobState &state,
+ std::optional<EStrategyOutcome> RestoreWholeFromDataParts(TLogContext& /*logCtx*/, TBlobState &state,
const TBlobStorageGroupInfo &info) {
TIntervalSet<i32> missing(state.Whole.NotHere);
TString tmp;
@@ -42,13 +42,13 @@ public:
}
}
if (state.Whole.NotHere.IsEmpty()) {
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
}
- return std::nullopt;
+ return std::nullopt;
}
- std::optional<EStrategyOutcome> RestoreWholeWithErasure(TLogContext& /*logCtx*/, TBlobState &state,
+ std::optional<EStrategyOutcome> RestoreWholeWithErasure(TLogContext& /*logCtx*/, TBlobState &state,
const TBlobStorageGroupInfo &info) {
const ui32 totalPartCount = info.Type.TotalPartCount();
const i32 handoff = info.Type.Handoff();
@@ -61,7 +61,7 @@ public:
TBlobState::TDisk &disk = state.Disks[diskIdx];
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
TIntervalSet<i32> &requested = disk.DiskParts[partIdx].Requested;
- if (partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Present) {
isMissing = false;
}
if (!requested.IsEmpty()) {
@@ -74,7 +74,7 @@ public:
}
if (partsMissing > info.Type.ParityParts() && responsesPending > 0) {
- return std::nullopt;
+ return std::nullopt;
}
// get intervals needed to restore the requested full data
@@ -98,7 +98,7 @@ public:
}
}
if (partsWithEnoughData < info.Type.MinimalRestorablePartCount()) {
- return std::nullopt;
+ return std::nullopt;
}
// We have enough parts for each interval needed and we can restore all the missing whole intervals
@@ -239,8 +239,8 @@ public:
}
}
Y_VERIFY(state.Whole.NotHere.IsEmpty());
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
}
void IssueGetRequestsForMinimal(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
@@ -263,8 +263,8 @@ public:
TBlobState::TDisk &disk = state.Disks[diskIdx];
if (!considerSlowAsError || !disk.IsSlow) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
TIntervalSet<i32> unrequestedInterval(partInterval);
unrequestedInterval.Subtract(disk.DiskParts[partIdx].Requested);
if (!unrequestedInterval.IsEmpty()) {
@@ -300,8 +300,8 @@ public:
TBlobState::TDisk &disk = state.Disks[diskIdx];
if (!considerSlowAsError || !disk.IsSlow) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
isThereAGoodPart = true;
}
}
@@ -344,9 +344,9 @@ public:
TBlobState::TDisk &disk = state.Disks[diskIdx];
if (!considerSlowAsError || !disk.IsSlow) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation != TBlobState::ESituation::Error &&
- partSituation != TBlobState::ESituation::Absent &&
- partSituation != TBlobState::ESituation::Lost) {
+ if (partSituation != TBlobState::ESituation::Error &&
+ partSituation != TBlobState::ESituation::Absent &&
+ partSituation != TBlobState::ESituation::Lost) {
isMissing = false;
}
}
@@ -377,8 +377,8 @@ public:
TBlobState::TDisk &disk = state.Disks[diskIdx];
if (!considerSlowAsError || !disk.IsSlow) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
TIntervalSet<i32> partIntervals(toRestore);
partIntervals.Subtract(state.Parts[partIdx].Here);
partIntervals.Subtract(disk.DiskParts[partIdx].Requested);
@@ -408,12 +408,12 @@ public:
}
}
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& blackboard, TGroupDiskRequests &groupDiskRequests) override {
- if (auto res = RestoreWholeFromDataParts(logCtx, state, info)) {
- return *res;
- } else if (auto res = RestoreWholeWithErasure(logCtx, state, info)) {
- return *res;
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& blackboard, TGroupDiskRequests &groupDiskRequests) override {
+ if (auto res = RestoreWholeFromDataParts(logCtx, state, info)) {
+ return *res;
+ } else if (auto res = RestoreWholeWithErasure(logCtx, state, info)) {
+ return *res;
}
// Look at the current layout and set the status if possible
TBlobStorageGroupInfo::EBlobState pessimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
@@ -421,35 +421,35 @@ public:
TBlobStorageGroupInfo::EBlobState altruisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
EvaluateCurrentLayout(logCtx, state, info, &pessimisticState, &optimisticState, &altruisticState, false);
- if (auto res = SetAbsentForUnrecoverableAltruistic(altruisticState, state)) {
- return *res;
- } else if (auto res = ProcessOptimistic(altruisticState, optimisticState, false, state)) {
- return *res;
- } else if (auto res = ProcessPessimistic(info, pessimisticState, false, state)) {
- return *res;
+ if (auto res = SetAbsentForUnrecoverableAltruistic(altruisticState, state)) {
+ return *res;
+ } else if (auto res = ProcessOptimistic(altruisticState, optimisticState, false, state)) {
+ return *res;
+ } else if (auto res = ProcessPessimistic(info, pessimisticState, false, state)) {
+ return *res;
}
-
- // Try excluding the slow disk
- bool isDone = false;
- // TODO: Mark disk that does not answer when accelerating requests
- i32 slowDiskSubgroupIdx = MarkSlowSubgroupDisk(state, info, blackboard, false);
- if (slowDiskSubgroupIdx >= 0) {
- TBlobStorageGroupInfo::EBlobState fastPessimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- TBlobStorageGroupInfo::EBlobState fastOptimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- TBlobStorageGroupInfo::EBlobState fastAltruisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- EvaluateCurrentLayout(logCtx, state, info, &fastPessimisticState, &fastOptimisticState,
- &fastAltruisticState, true);
- if (!IsUnrecoverableAltruistic(fastAltruisticState)
- && !ProcessOptimistic(fastAltruisticState, fastOptimisticState, true, state)) {
- IssueGetRequests(logCtx, state, info, true, groupDiskRequests);
- isDone = true;
- }
+
+ // Try excluding the slow disk
+ bool isDone = false;
+ // TODO: Mark disk that does not answer when accelerating requests
+ i32 slowDiskSubgroupIdx = MarkSlowSubgroupDisk(state, info, blackboard, false);
+ if (slowDiskSubgroupIdx >= 0) {
+ TBlobStorageGroupInfo::EBlobState fastPessimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ TBlobStorageGroupInfo::EBlobState fastOptimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ TBlobStorageGroupInfo::EBlobState fastAltruisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ EvaluateCurrentLayout(logCtx, state, info, &fastPessimisticState, &fastOptimisticState,
+ &fastAltruisticState, true);
+ if (!IsUnrecoverableAltruistic(fastAltruisticState)
+ && !ProcessOptimistic(fastAltruisticState, fastOptimisticState, true, state)) {
+ IssueGetRequests(logCtx, state, info, true, groupDiskRequests);
+ isDone = true;
+ }
}
- if (!isDone) {
- IssueGetRequests(logCtx, state, info, false, groupDiskRequests);
+ if (!isDone) {
+ IssueGetRequests(logCtx, state, info, false, groupDiskRequests);
}
- return EStrategyOutcome::IN_PROGRESS;
+ return EStrategyOutcome::IN_PROGRESS;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_mirror.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_mirror.h
index 4ec3edaf933..4e4b65d3cf6 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_mirror.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_min_iops_mirror.h
@@ -7,7 +7,7 @@ namespace NKikimr {
class TMinIopsMirrorStrategy : public TStrategyBase {
public:
- std::optional<EStrategyOutcome> RestoreWholeFromDataParts(TLogContext& /*logCtx*/, TBlobState &state,
+ std::optional<EStrategyOutcome> RestoreWholeFromDataParts(TLogContext& /*logCtx*/, TBlobState &state,
const TBlobStorageGroupInfo &info) {
TIntervalSet<i32> missing(state.Whole.NotHere);
const ui32 totalPartCount = info.Type.TotalPartCount();
@@ -26,16 +26,16 @@ public:
}
}
if (state.Whole.NotHere.IsEmpty()) {
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
}
- return std::nullopt;
+ return std::nullopt;
}
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
- if (auto res = RestoreWholeFromDataParts(logCtx, state, info)) {
- return *res;
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests &groupDiskRequests) override {
+ if (auto res = RestoreWholeFromDataParts(logCtx, state, info)) {
+ return *res;
}
// Look at the current layout and set the status if possible
TBlobStorageGroupInfo::EBlobState pessimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
@@ -43,41 +43,41 @@ public:
TBlobStorageGroupInfo::EBlobState altruisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
EvaluateCurrentLayout(logCtx, state, info, &pessimisticState, &optimisticState, &altruisticState, false);
- if (auto res = SetAbsentForUnrecoverableAltruistic(altruisticState, state)) {
- return *res;
- } else if (auto res = ProcessOptimistic(altruisticState, optimisticState, false, state)) {
- return *res;
- } else if (auto res = ProcessPessimistic(info, pessimisticState, false, state)) {
- return *res;
+ if (auto res = SetAbsentForUnrecoverableAltruistic(altruisticState, state)) {
+ return *res;
+ } else if (auto res = ProcessOptimistic(altruisticState, optimisticState, false, state)) {
+ return *res;
+ } else if (auto res = ProcessPessimistic(info, pessimisticState, false, state)) {
+ return *res;
}
-
- // Request minimal parts for each requested range of each blob
- const ui32 totalPartCount = info.Type.TotalPartCount();
- const i32 handoff = info.Type.Handoff();
- bool isMinimalPossible = true;
+
+ // Request minimal parts for each requested range of each blob
+ const ui32 totalPartCount = info.Type.TotalPartCount();
+ const i32 handoff = info.Type.Handoff();
+ bool isMinimalPossible = true;
for (auto it = state.Whole.NotHere.begin(); it != state.Whole.NotHere.end(); ++it) {
auto [begin, end] = *it;
- bool isThereAGoodPart = false;
- for (ui32 partIdx = 0; partIdx < totalPartCount; ++partIdx) {
+ bool isThereAGoodPart = false;
+ for (ui32 partIdx = 0; partIdx < totalPartCount; ++partIdx) {
TIntervalSet<i32> partInterval(begin, end);
- partInterval.Subtract(state.Parts[partIdx].Here);
- if (!partInterval.IsEmpty()) {
- for (i32 niche = -1; niche < handoff; ++niche) {
- ui32 diskIdx = (niche < 0 ? partIdx : totalPartCount + niche);
- TBlobState::TDisk &disk = state.Disks[diskIdx];
- TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
- isThereAGoodPart = true;
- }
- }
- }
- }
- if (!isThereAGoodPart) {
- isMinimalPossible = false;
- }
+ partInterval.Subtract(state.Parts[partIdx].Here);
+ if (!partInterval.IsEmpty()) {
+ for (i32 niche = -1; niche < handoff; ++niche) {
+ ui32 diskIdx = (niche < 0 ? partIdx : totalPartCount + niche);
+ TBlobState::TDisk &disk = state.Disks[diskIdx];
+ TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
+ isThereAGoodPart = true;
+ }
+ }
+ }
+ }
+ if (!isThereAGoodPart) {
+ isMinimalPossible = false;
+ }
}
- if (isMinimalPossible) {
+ if (isMinimalPossible) {
for (auto it = state.Whole.NotHere.begin(); it != state.Whole.NotHere.end(); ++it) {
auto [begin, end] = *it;
for (ui32 partIdx = 0; partIdx < totalPartCount; ++partIdx) {
@@ -88,38 +88,38 @@ public:
ui32 diskIdx = (niche < 0 ? partIdx : totalPartCount + niche);
TBlobState::TDisk &disk = state.Disks[diskIdx];
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
TIntervalSet<i32> unrequestedInterval(partInterval);
- unrequestedInterval.Subtract(disk.DiskParts[partIdx].Requested);
- if (!unrequestedInterval.IsEmpty()) {
+ unrequestedInterval.Subtract(disk.DiskParts[partIdx].Requested);
+ if (!unrequestedInterval.IsEmpty()) {
- AddGetRequest(logCtx, groupDiskRequests, state.Id, partIdx, disk,
- unrequestedInterval, "BPG45");
+ AddGetRequest(logCtx, groupDiskRequests, state.Id, partIdx, disk,
+ unrequestedInterval, "BPG45");
}
}
}
}
}
- }
- } else {
- // It must be actually impossible to get the blob at all if we got here (or we have already sent
- const ui32 totalPartCount = info.Type.TotalPartCount();
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- bool isHandoff = (diskIdx >= totalPartCount);
- ui32 beginPartIdx = (isHandoff ? 0 : diskIdx);
- ui32 endPartIdx = (isHandoff ? totalPartCount : (diskIdx + 1));
- for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
- TBlobState::TDisk &disk = state.Disks[diskIdx];
- TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Unknown ||
- partSituation == TBlobState::ESituation::Present) {
- Y_VERIFY(false, "Inconsistent state# %s", state.ToString().data());
+ }
+ } else {
+ // It must be actually impossible to get the blob at all if we got here (or we have already sent
+ const ui32 totalPartCount = info.Type.TotalPartCount();
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ bool isHandoff = (diskIdx >= totalPartCount);
+ ui32 beginPartIdx = (isHandoff ? 0 : diskIdx);
+ ui32 endPartIdx = (isHandoff ? totalPartCount : (diskIdx + 1));
+ for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
+ TBlobState::TDisk &disk = state.Disks[diskIdx];
+ TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
+ if (partSituation == TBlobState::ESituation::Unknown ||
+ partSituation == TBlobState::ESituation::Present) {
+ Y_VERIFY(false, "Inconsistent state# %s", state.ToString().data());
}
}
}
}
- return EStrategyOutcome::IN_PROGRESS;
+ return EStrategyOutcome::IN_PROGRESS;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_m3of4_base.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_m3of4_base.h
index 9acbc1d1b0e..649be23b298 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_m3of4_base.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_m3of4_base.h
@@ -1,52 +1,52 @@
-#pragma once
-
-#include "defs.h"
-
-#include "dsproxy_strategy_base.h"
-#include "dsproxy_blackboard.h"
-
+#pragma once
+
+#include "defs.h"
+
+#include "dsproxy_strategy_base.h"
+#include "dsproxy_blackboard.h"
+
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
-namespace NKikimr {
-
- class TMirror3of4StrategyBase : public IStrategy {
- protected:
- static constexpr ui32 MetadataPartIdx = 2;
-
- struct TGroups {
- struct TGroupInfo {
- ui32 DiskIdx[3];
- ui32 PartIdx;
- bool Requested = false;
- bool Done = false;
- ui32 NumSlowDisks = 0;
- } Groups[4] = {
- {{0, 4, 5}, 0},
- {{1, 4, 5}, 1},
- {{2, 6, 7}, 0},
- {{3, 6, 7}, 1},
- };
- };
-
- static constexpr bool DiskPartsAllowed[3][8] = {
- {true, false, true, false, true, true, true, true},
- {false, true, false, true, true, true, true, true},
- {true, true, true, true, true, true, true, true}
- };
-
- bool CheckFailModel(TBlobState& state, const TBlobStorageGroupInfo& info) {
- TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
- for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
- for (const auto& part : state.Disks[diskIdx].DiskParts) {
- if (part.Situation == TBlobState::ESituation::Error) {
- error |= {&info.GetTopology(), diskIdx};
- break;
- }
- }
- }
- return info.GetQuorumChecker().CheckFailModelForSubgroup(error);
- }
- };
-
-} // NKikimr
+
+namespace NKikimr {
+
+ class TMirror3of4StrategyBase : public IStrategy {
+ protected:
+ static constexpr ui32 MetadataPartIdx = 2;
+
+ struct TGroups {
+ struct TGroupInfo {
+ ui32 DiskIdx[3];
+ ui32 PartIdx;
+ bool Requested = false;
+ bool Done = false;
+ ui32 NumSlowDisks = 0;
+ } Groups[4] = {
+ {{0, 4, 5}, 0},
+ {{1, 4, 5}, 1},
+ {{2, 6, 7}, 0},
+ {{3, 6, 7}, 1},
+ };
+ };
+
+ static constexpr bool DiskPartsAllowed[3][8] = {
+ {true, false, true, false, true, true, true, true},
+ {false, true, false, true, true, true, true, true},
+ {true, true, true, true, true, true, true, true}
+ };
+
+ bool CheckFailModel(TBlobState& state, const TBlobStorageGroupInfo& info) {
+ TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
+ for (ui32 diskIdx = 0; diskIdx < state.Disks.size(); ++diskIdx) {
+ for (const auto& part : state.Disks[diskIdx].DiskParts) {
+ if (part.Situation == TBlobState::ESituation::Error) {
+ error |= {&info.GetTopology(), diskIdx};
+ break;
+ }
+ }
+ }
+ return info.GetQuorumChecker().CheckFailModelForSubgroup(error);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3dc.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3dc.h
index 77cc7529605..1556c0e4a0c 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3dc.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3dc.h
@@ -30,31 +30,31 @@ public:
return preferredReplicasPerRealm;
}
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
- TBlackboard& blackboard, TGroupDiskRequests &groupDiskRequests) override {
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ TBlackboard& blackboard, TGroupDiskRequests &groupDiskRequests) override {
TBlobStorageGroupType::TPartPlacement partPlacement;
bool degraded = false;
bool isDone = false;
i32 slowDiskSubgroupIdx = MarkSlowSubgroupDisk(state, info, blackboard, true);
- do {
- if (slowDiskSubgroupIdx < 0) {
- break; // ignore this case
- }
+ do {
+ if (slowDiskSubgroupIdx < 0) {
+ break; // ignore this case
+ }
TBlobStorageGroupInfo::TSubgroupVDisks success(&info.GetTopology());
TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
- Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, true, success, error, degraded);
- TBlobStorageGroupInfo::TSubgroupVDisks slow(&info.GetTopology(), slowDiskSubgroupIdx);
- if ((success | error) & slow) {
- break; // slow disk is already marked as successful or erroneous
- }
- error += slow;
+ Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, true, success, error, degraded);
+ TBlobStorageGroupInfo::TSubgroupVDisks slow(&info.GetTopology(), slowDiskSubgroupIdx);
+ if ((success | error) & slow) {
+ break; // slow disk is already marked as successful or erroneous
+ }
+ error += slow;
// check for failure tolerance; we issue ERROR in case when it is not possible to achieve success condition in
// any way; also check if we have already finished writing replicas
const auto& checker = info.GetQuorumChecker();
if (checker.CheckFailModelForSubgroup(error)) {
if (checker.CheckQuorumForSubgroup(success)) {
- return EStrategyOutcome::DONE;
+ return EStrategyOutcome::DONE;
}
// now check every realm and check if we have to issue some write requests to it
@@ -63,19 +63,19 @@ public:
true, partPlacement);
isDone = true;
}
- } while (false);
+ } while (false);
if (!isDone) {
TBlobStorageGroupInfo::TSubgroupVDisks success(&info.GetTopology());
TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
- Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, false, success, error, degraded);
+ Evaluate3dcSituation(state, NumFailRealms, NumFailDomainsPerFailRealm, info, false, success, error, degraded);
// check for failure tolerance; we issue ERROR in case when it is not possible to achieve success condition in
// any way; also check if we have already finished writing replicas
const auto& checker = info.GetQuorumChecker();
if (!checker.CheckFailModelForSubgroup(error)) {
- return EStrategyOutcome::Error("TPut3dcStrategy failed the Fail Model check");
+ return EStrategyOutcome::Error("TPut3dcStrategy failed the Fail Model check");
} else if (checker.CheckQuorumForSubgroup(success)) {
- return EStrategyOutcome::DONE;
+ return EStrategyOutcome::DONE;
}
// now check every realm and check if we have to issue some write requests to it
@@ -86,7 +86,7 @@ public:
if (IsPutNeeded(state, partPlacement)) {
PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
}
- return EStrategyOutcome::IN_PROGRESS;
+ return EStrategyOutcome::IN_PROGRESS;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3of4.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3of4.h
index b372e891ebd..f26107c4e93 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3of4.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_put_m3of4.h
@@ -1,187 +1,187 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_strategy_m3of4_base.h"
-
-namespace NKikimr {
-
-class TPut3of4Strategy : public TMirror3of4StrategyBase {
- // TODO(alexvru): use Accelerate property somehow
- const TEvBlobStorage::TEvPut::ETactic Tactic;
-
-public:
- TPut3of4Strategy(TEvBlobStorage::TEvPut::ETactic tactic, bool /*accelerate*/ = false)
- : Tactic(tactic)
- {}
-
- EStrategyOutcome Process(TLogContext& /*logCtx*/, TBlobState& state, const TBlobStorageGroupInfo& info,
- TBlackboard& /*blackboard*/, TGroupDiskRequests& groupDiskRequests) override {
- if (!CheckFailModel(state, info)) {
- state.WholeSituation = TBlobState::ESituation::Error;
- return EStrategyOutcome::Error("failure model exceeded");
- }
-
- if (state.WholeSituation != TBlobState::ESituation::Unknown && state.WholeSituation != TBlobState::ESituation::Present) {
- return EStrategyOutcome::DONE; // most likely this is get-with-restore put and the blob is absent
- }
-
- switch (Tactic) {
- case TEvBlobStorage::TEvPut::TacticMaxThroughput:
- return Process(state, info, groupDiskRequests, false);
-
- case TEvBlobStorage::TEvPut::TacticMinLatency:
- case TEvBlobStorage::TEvPut::TacticDefault:
- return Process(state, info, groupDiskRequests, true);
-
- default:
- Y_FAIL("unexpected Tactic");
- }
- }
-
-protected:
- TString GetDataBuffer(TBlobState& state, const TBlobStorageGroupInfo& info) {
- for (ui32 i = 0; i < info.Type.TotalPartCount(); ++i) {
- if (info.Type.PartSize(TLogoBlobID(state.Id, i + 1)) && state.Parts[i].Data.IsMonolith()) {
- return state.Parts[i].Data.GetMonolith();
- }
- }
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_strategy_m3of4_base.h"
+
+namespace NKikimr {
+
+class TPut3of4Strategy : public TMirror3of4StrategyBase {
+ // TODO(alexvru): use Accelerate property somehow
+ const TEvBlobStorage::TEvPut::ETactic Tactic;
+
+public:
+ TPut3of4Strategy(TEvBlobStorage::TEvPut::ETactic tactic, bool /*accelerate*/ = false)
+ : Tactic(tactic)
+ {}
+
+ EStrategyOutcome Process(TLogContext& /*logCtx*/, TBlobState& state, const TBlobStorageGroupInfo& info,
+ TBlackboard& /*blackboard*/, TGroupDiskRequests& groupDiskRequests) override {
+ if (!CheckFailModel(state, info)) {
+ state.WholeSituation = TBlobState::ESituation::Error;
+ return EStrategyOutcome::Error("failure model exceeded");
+ }
+
+ if (state.WholeSituation != TBlobState::ESituation::Unknown && state.WholeSituation != TBlobState::ESituation::Present) {
+ return EStrategyOutcome::DONE; // most likely this is get-with-restore put and the blob is absent
+ }
+
+ switch (Tactic) {
+ case TEvBlobStorage::TEvPut::TacticMaxThroughput:
+ return Process(state, info, groupDiskRequests, false);
+
+ case TEvBlobStorage::TEvPut::TacticMinLatency:
+ case TEvBlobStorage::TEvPut::TacticDefault:
+ return Process(state, info, groupDiskRequests, true);
+
+ default:
+ Y_FAIL("unexpected Tactic");
+ }
+ }
+
+protected:
+ TString GetDataBuffer(TBlobState& state, const TBlobStorageGroupInfo& info) {
+ for (ui32 i = 0; i < info.Type.TotalPartCount(); ++i) {
+ if (info.Type.PartSize(TLogoBlobID(state.Id, i + 1)) && state.Parts[i].Data.IsMonolith()) {
+ return state.Parts[i].Data.GetMonolith();
+ }
+ }
const TIntervalVec<i32> interval(0, state.Id.BlobSize());
Y_VERIFY(interval.IsSubsetOf(state.Whole.Here), "missing blob data State# %s", state.ToString().data());
- TString wholeBuffer = TString::Uninitialized(state.Id.BlobSize());
- state.Whole.Data.Read(0, const_cast<char*>(wholeBuffer.data()), state.Id.BlobSize());
- TDataPartSet partSet;
- info.Type.SplitData((TErasureType::ECrcMode)state.Id.CrcMode(), wholeBuffer, partSet);
- TString s = partSet.Parts[0].OwnedString;
- state.Parts[0].Data.SetMonolith(s);
- return s;
- }
-
- EStrategyOutcome Process(TBlobState& state, const TBlobStorageGroupInfo& info, TGroupDiskRequests& groupDiskRequests, bool minLatency) {
- // first of all, look around
- TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks dataPresent(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks anyPresent(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks data(&info.GetTopology());
- TBlobStorageGroupInfo::TSubgroupVDisks any(&info.GetTopology());
- for (ui8 diskIdx = 0; diskIdx < info.Type.BlobSubgroupSize(); ++diskIdx) {
- const TBlobStorageGroupInfo::TSubgroupVDisks mask(&info.GetTopology(), diskIdx);
- for (ui8 partIdx = 0; partIdx < info.Type.TotalPartCount(); ++partIdx) {
- const bool dataPart = info.Type.PartSize(TLogoBlobID(state.Id, partIdx + 1));
- switch (state.Disks[diskIdx].DiskParts[partIdx].Situation) {
- case TBlobState::ESituation::Error:
- error |= {&info.GetTopology(), diskIdx};
- break;
-
- case TBlobState::ESituation::Present:
- anyPresent |= mask;
- if (dataPart) {
- dataPresent |= mask;
- }
- [[fallthrough]];
-
- case TBlobState::ESituation::Sent:
- any |= mask;
- if (dataPart) {
- data |= mask;
- }
- break;
-
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost:
- break;
- }
- }
- }
- if (dataPresent.GetNumSetItems() >= 3 && anyPresent.GetNumSetItems() >= 5) {
- state.WholeSituation = TBlobState::ESituation::Present;
- return EStrategyOutcome::DONE;
- }
-
- TGroups groups;
- const ui32 requiredNumDataParts = minLatency ? 4 : 3;
- const ui32 requiredNumMetadataParts = minLatency ? 4 : 2;
- const ui32 requiredNumParts = requiredNumDataParts + requiredNumMetadataParts;
-
- for (bool ignoreSlowDisks : {true, false}) {
- for (bool considerLost : {true, false}) {
- // fix the data part of the subgroup
- for (auto& group : groups.Groups) {
- for (ui8 diskIdx : group.DiskIdx) {
- if (data.GetNumSetItems() >= requiredNumDataParts || dataPresent.GetNumSetItems() >= 3) {
- break; // we already have required set of data replicas
- }
- auto& disk = state.Disks[diskIdx];
- if (ignoreSlowDisks && disk.IsSlow) {
- continue;
- }
- auto& part = disk.DiskParts[group.PartIdx];
- switch (auto& s = part.Situation) {
- case TBlobState::ESituation::Error:
- case TBlobState::ESituation::Present:
- case TBlobState::ESituation::Sent:
- break; // this part/disk is ignored for now
-
- case TBlobState::ESituation::Unknown:
- case TBlobState::ESituation::Absent:
- case TBlobState::ESituation::Lost: {
- // look for the data counterpart situation -- can we use this part to store data?
- using E = TBlobState::ESituation;
- const auto cs = disk.DiskParts[!group.PartIdx].Situation;
- if (cs == E::Error || cs == E::Present || cs == E::Sent) {
- break; // we should not fill in this part
- }
- if (considerLost && s != TBlobState::ESituation::Lost) {
- break; // we are looking for lost parts now -- this is not the lost one
- }
- // send request to this disk
- groupDiskRequests.AddPut(disk.OrderNumber,
- TLogoBlobID(state.Id, group.PartIdx + 1),
- GetDataBuffer(state, info),
- diskIdx == group.DiskIdx[0] ? TDiskPutRequest::ReasonInitial : TDiskPutRequest::ReasonError,
- diskIdx != group.DiskIdx[0],
- state.BlobIdx);
- s = TBlobState::ESituation::Sent;
- any |= {&info.GetTopology(), diskIdx};
- data += {&info.GetTopology(), diskIdx};
- break;
- }
- }
- }
- }
-
- // then we restore required amount of metadata parts
- for (i8 diskIdx = info.Type.BlobSubgroupSize() - 1; diskIdx >= 0 &&
- any.GetNumSetItems() < requiredNumParts && anyPresent.GetNumSetItems() < 5; --diskIdx) {
- if (any[diskIdx] || error[diskIdx]) {
- continue; // we do not put metadata parts on disk already containing data or metadata parts
- }
- auto& disk = state.Disks[diskIdx];
- if (ignoreSlowDisks && disk.IsSlow) {
- continue;
- }
- auto& part = disk.DiskParts[2];
- Y_VERIFY(part.Situation != TBlobState::ESituation::Present && part.Situation != TBlobState::ESituation::Sent);
- if (considerLost && part.Situation != TBlobState::ESituation::Lost) {
- continue; // here we process only lost disks
- }
-
- const bool handoff = (ui8)diskIdx < info.Type.BlobSubgroupSize() - requiredNumMetadataParts;
- groupDiskRequests.AddPut(disk.OrderNumber,
- TLogoBlobID(state.Id, 3),
- TString(),
- handoff ? TDiskPutRequest::ReasonError : TDiskPutRequest::ReasonInitial,
- handoff,
- state.BlobIdx);
- part.Situation = TBlobState::ESituation::Sent;
- any |= {&info.GetTopology(), (ui8)diskIdx};
- }
- }
- }
-
- Y_VERIFY(anyPresent != any || dataPresent != data, "state# %s", state.ToString().data());
- return EStrategyOutcome::IN_PROGRESS;
- }
-};
-
-} // NKikimr
+ TString wholeBuffer = TString::Uninitialized(state.Id.BlobSize());
+ state.Whole.Data.Read(0, const_cast<char*>(wholeBuffer.data()), state.Id.BlobSize());
+ TDataPartSet partSet;
+ info.Type.SplitData((TErasureType::ECrcMode)state.Id.CrcMode(), wholeBuffer, partSet);
+ TString s = partSet.Parts[0].OwnedString;
+ state.Parts[0].Data.SetMonolith(s);
+ return s;
+ }
+
+ EStrategyOutcome Process(TBlobState& state, const TBlobStorageGroupInfo& info, TGroupDiskRequests& groupDiskRequests, bool minLatency) {
+ // first of all, look around
+ TBlobStorageGroupInfo::TSubgroupVDisks error(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks dataPresent(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks anyPresent(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks data(&info.GetTopology());
+ TBlobStorageGroupInfo::TSubgroupVDisks any(&info.GetTopology());
+ for (ui8 diskIdx = 0; diskIdx < info.Type.BlobSubgroupSize(); ++diskIdx) {
+ const TBlobStorageGroupInfo::TSubgroupVDisks mask(&info.GetTopology(), diskIdx);
+ for (ui8 partIdx = 0; partIdx < info.Type.TotalPartCount(); ++partIdx) {
+ const bool dataPart = info.Type.PartSize(TLogoBlobID(state.Id, partIdx + 1));
+ switch (state.Disks[diskIdx].DiskParts[partIdx].Situation) {
+ case TBlobState::ESituation::Error:
+ error |= {&info.GetTopology(), diskIdx};
+ break;
+
+ case TBlobState::ESituation::Present:
+ anyPresent |= mask;
+ if (dataPart) {
+ dataPresent |= mask;
+ }
+ [[fallthrough]];
+
+ case TBlobState::ESituation::Sent:
+ any |= mask;
+ if (dataPart) {
+ data |= mask;
+ }
+ break;
+
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost:
+ break;
+ }
+ }
+ }
+ if (dataPresent.GetNumSetItems() >= 3 && anyPresent.GetNumSetItems() >= 5) {
+ state.WholeSituation = TBlobState::ESituation::Present;
+ return EStrategyOutcome::DONE;
+ }
+
+ TGroups groups;
+ const ui32 requiredNumDataParts = minLatency ? 4 : 3;
+ const ui32 requiredNumMetadataParts = minLatency ? 4 : 2;
+ const ui32 requiredNumParts = requiredNumDataParts + requiredNumMetadataParts;
+
+ for (bool ignoreSlowDisks : {true, false}) {
+ for (bool considerLost : {true, false}) {
+ // fix the data part of the subgroup
+ for (auto& group : groups.Groups) {
+ for (ui8 diskIdx : group.DiskIdx) {
+ if (data.GetNumSetItems() >= requiredNumDataParts || dataPresent.GetNumSetItems() >= 3) {
+ break; // we already have required set of data replicas
+ }
+ auto& disk = state.Disks[diskIdx];
+ if (ignoreSlowDisks && disk.IsSlow) {
+ continue;
+ }
+ auto& part = disk.DiskParts[group.PartIdx];
+ switch (auto& s = part.Situation) {
+ case TBlobState::ESituation::Error:
+ case TBlobState::ESituation::Present:
+ case TBlobState::ESituation::Sent:
+ break; // this part/disk is ignored for now
+
+ case TBlobState::ESituation::Unknown:
+ case TBlobState::ESituation::Absent:
+ case TBlobState::ESituation::Lost: {
+ // look for the data counterpart situation -- can we use this part to store data?
+ using E = TBlobState::ESituation;
+ const auto cs = disk.DiskParts[!group.PartIdx].Situation;
+ if (cs == E::Error || cs == E::Present || cs == E::Sent) {
+ break; // we should not fill in this part
+ }
+ if (considerLost && s != TBlobState::ESituation::Lost) {
+ break; // we are looking for lost parts now -- this is not the lost one
+ }
+ // send request to this disk
+ groupDiskRequests.AddPut(disk.OrderNumber,
+ TLogoBlobID(state.Id, group.PartIdx + 1),
+ GetDataBuffer(state, info),
+ diskIdx == group.DiskIdx[0] ? TDiskPutRequest::ReasonInitial : TDiskPutRequest::ReasonError,
+ diskIdx != group.DiskIdx[0],
+ state.BlobIdx);
+ s = TBlobState::ESituation::Sent;
+ any |= {&info.GetTopology(), diskIdx};
+ data += {&info.GetTopology(), diskIdx};
+ break;
+ }
+ }
+ }
+ }
+
+ // then we restore required amount of metadata parts
+ for (i8 diskIdx = info.Type.BlobSubgroupSize() - 1; diskIdx >= 0 &&
+ any.GetNumSetItems() < requiredNumParts && anyPresent.GetNumSetItems() < 5; --diskIdx) {
+ if (any[diskIdx] || error[diskIdx]) {
+ continue; // we do not put metadata parts on disk already containing data or metadata parts
+ }
+ auto& disk = state.Disks[diskIdx];
+ if (ignoreSlowDisks && disk.IsSlow) {
+ continue;
+ }
+ auto& part = disk.DiskParts[2];
+ Y_VERIFY(part.Situation != TBlobState::ESituation::Present && part.Situation != TBlobState::ESituation::Sent);
+ if (considerLost && part.Situation != TBlobState::ESituation::Lost) {
+ continue; // here we process only lost disks
+ }
+
+ const bool handoff = (ui8)diskIdx < info.Type.BlobSubgroupSize() - requiredNumMetadataParts;
+ groupDiskRequests.AddPut(disk.OrderNumber,
+ TLogoBlobID(state.Id, 3),
+ TString(),
+ handoff ? TDiskPutRequest::ReasonError : TDiskPutRequest::ReasonInitial,
+ handoff,
+ state.BlobIdx);
+ part.Situation = TBlobState::ESituation::Sent;
+ any |= {&info.GetTopology(), (ui8)diskIdx};
+ }
+ }
+ }
+
+ Y_VERIFY(anyPresent != any || dataPresent != data, "state# %s", state.ToString().data());
+ return EStrategyOutcome::IN_PROGRESS;
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h
index 97c8fe3e847..dc989cd9834 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h
@@ -29,7 +29,7 @@ public:
bool isErrorDisk = false;
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Error) {
+ if (partSituation == TBlobState::ESituation::Error) {
R_LOG_DEBUG_SX(logCtx, "BPG50", "Id# " << state.Id.ToString()
<< " Restore disk# " << diskIdx << " part# " << partIdx << " error");
if (!isErrorDisk) {
@@ -42,27 +42,27 @@ public:
if (!isErrorDisk) {
for (ui32 partIdx = beginPartIdx; partIdx < endPartIdx; ++partIdx) {
TBlobState::ESituation partSituation = disk.DiskParts[partIdx].Situation;
- if (partSituation == TBlobState::ESituation::Absent) {
+ if (partSituation == TBlobState::ESituation::Absent) {
R_LOG_DEBUG_SX(logCtx, "BPG51", "Id# " << state.Id.ToString()
<< " restore disk# " << diskIdx << " part# " << partIdx << " absent");
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
isUnknownDisk = false;
- } else if (partSituation == TBlobState::ESituation::Lost) {
+ } else if (partSituation == TBlobState::ESituation::Lost) {
R_LOG_DEBUG_SX(logCtx, "BPG63", "Id# " << state.Id.ToString()
<< " restore disk# " << diskIdx << " part# " << partIdx << " lost");
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
isUnknownDisk = false;
- } else if (partSituation == TBlobState::ESituation::Present) {
+ } else if (partSituation == TBlobState::ESituation::Present) {
R_LOG_DEBUG_SX(logCtx, "BPG52", "Id# " << state.Id.ToString()
<< " restore disk# " << diskIdx << " part# " << partIdx << " present");
presentLayout.AddItem(diskIdx, partIdx, info.Type);
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
isUnknownDisk = false;
- } else if (partSituation == TBlobState::ESituation::Unknown) {
+ } else if (partSituation == TBlobState::ESituation::Unknown) {
R_LOG_DEBUG_SX(logCtx, "BPG53", "Id# " << state.Id.ToString()
<< " restore disk# " << diskIdx << " part# " << partIdx << " unknown");
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
- } else if (partSituation == TBlobState::ESituation::Sent) {
+ } else if (partSituation == TBlobState::ESituation::Sent) {
R_LOG_DEBUG_SX(logCtx, "BPG54", "Id# " << state.Id.ToString()
<< " restore disk# " << diskIdx << " part# " << partIdx << " sent");
optimisticLayout.AddItem(diskIdx, partIdx, info.Type);
@@ -85,21 +85,21 @@ public:
<< " optimisticState# " << TBlobStorageGroupInfo::BlobStateToString(*optimisticState));
}
- std::optional<EStrategyOutcome> SetErrorForUnrecoverableOptimistic(TBlobStorageGroupInfo::EBlobState optimisticState) {
+ std::optional<EStrategyOutcome> SetErrorForUnrecoverableOptimistic(TBlobStorageGroupInfo::EBlobState optimisticState) {
switch (optimisticState) {
case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
case TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY:
case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
- return EStrategyOutcome::Error(TStringBuilder() << "TRestoreStrategy saw optimisticState# "
- << TBlobStorageGroupInfo::BlobStateToString(optimisticState));
+ return EStrategyOutcome::Error(TStringBuilder() << "TRestoreStrategy saw optimisticState# "
+ << TBlobStorageGroupInfo::BlobStateToString(optimisticState));
case TBlobStorageGroupInfo::EBS_FULL:
- break;
+ break;
}
- return std::nullopt;
+ return std::nullopt;
}
- std::optional<EStrategyOutcome> IgnoreFullPessimistic(TBlobStorageGroupInfo::EBlobState pessimisticState) {
+ std::optional<EStrategyOutcome> IgnoreFullPessimistic(TBlobStorageGroupInfo::EBlobState pessimisticState) {
switch (pessimisticState) {
case TBlobStorageGroupInfo::EBS_DISINTEGRATED:
case TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY:
@@ -107,72 +107,72 @@ public:
case TBlobStorageGroupInfo::EBS_RECOVERABLE_DOUBTED:
break;
case TBlobStorageGroupInfo::EBS_FULL:
- return EStrategyOutcome::DONE; // TODO(alexvru): validate behaviour
+ return EStrategyOutcome::DONE; // TODO(alexvru): validate behaviour
}
- return std::nullopt;
+ return std::nullopt;
}
- EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
+ EStrategyOutcome Process(TLogContext &logCtx, TBlobState &state, const TBlobStorageGroupInfo &info,
TBlackboard &blackboard, TGroupDiskRequests &groupDiskRequests) override {
if (VerifyTheWholeSituation(state)) {
- // TODO(alexvru): ensure this branch does not hit when there are not enough parts present!
- return EStrategyOutcome::DONE; // blob is already marked as present
+ // TODO(alexvru): ensure this branch does not hit when there are not enough parts present!
+ return EStrategyOutcome::DONE; // blob is already marked as present
}
-
+
// Look at the current layout and set the status if possible
TBlobStorageGroupInfo::EBlobState pessimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
TBlobStorageGroupInfo::EBlobState optimisticState = TBlobStorageGroupInfo::EBS_DISINTEGRATED;
EvaluateRestoreLayout(logCtx, state, info, &pessimisticState, &optimisticState);
- if (auto res = SetErrorForUnrecoverableOptimistic(optimisticState)) {
- return *res;
- } else if (auto res = IgnoreFullPessimistic(pessimisticState)) {
- return *res;
- }
-
- // Find the slowest disk
- i32 worstSubgroupIdx = -1;
- ui64 worstPredictedNs = 0;
- ui64 nextToWorstPredictedNs = 0;
- state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
- HandleClassToQueueId(blackboard.PutHandleClass),
- &worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
-
- // Check if the slowest disk exceptionally slow, or just not very fast
- i32 slowDiskSubgroupIdx = -1;
- if (nextToWorstPredictedNs > 0 && worstPredictedNs > nextToWorstPredictedNs * 2) {
- slowDiskSubgroupIdx = worstSubgroupIdx;
+ if (auto res = SetErrorForUnrecoverableOptimistic(optimisticState)) {
+ return *res;
+ } else if (auto res = IgnoreFullPessimistic(pessimisticState)) {
+ return *res;
}
- bool isDone = false;
- if (slowDiskSubgroupIdx >= 0) {
- // If there is an exceptionally slow disk, try not touching it, mark isDone
- TBlobStorageGroupType::TPartLayout layout;
+ // Find the slowest disk
+ i32 worstSubgroupIdx = -1;
+ ui64 worstPredictedNs = 0;
+ ui64 nextToWorstPredictedNs = 0;
+ state.GetWorstPredictedDelaysNs(info, *blackboard.GroupQueues,
+ HandleClassToQueueId(blackboard.PutHandleClass),
+ &worstPredictedNs, &nextToWorstPredictedNs, &worstSubgroupIdx);
+
+ // Check if the slowest disk exceptionally slow, or just not very fast
+ i32 slowDiskSubgroupIdx = -1;
+ if (nextToWorstPredictedNs > 0 && worstPredictedNs > nextToWorstPredictedNs * 2) {
+ slowDiskSubgroupIdx = worstSubgroupIdx;
+ }
+
+ bool isDone = false;
+ if (slowDiskSubgroupIdx >= 0) {
+ // If there is an exceptionally slow disk, try not touching it, mark isDone
+ TBlobStorageGroupType::TPartLayout layout;
PreparePartLayout(state, info, &layout, slowDiskSubgroupIdx);
- TBlobStorageGroupType::TPartPlacement partPlacement;
- bool isCorrectable = info.Type.CorrectLayout(layout, partPlacement);
- if (isCorrectable) {
- isDone = true;
+ TBlobStorageGroupType::TPartPlacement partPlacement;
+ bool isCorrectable = info.Type.CorrectLayout(layout, partPlacement);
+ if (isCorrectable) {
+ isDone = true;
if (IsPutNeeded(state, partPlacement)) {
PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
}
}
}
- if (!isDone) {
- // Fill in the part layout
- TBlobStorageGroupType::TPartLayout layout;
+ if (!isDone) {
+ // Fill in the part layout
+ TBlobStorageGroupType::TPartLayout layout;
PreparePartLayout(state, info, &layout, InvalidVDiskIdx);
- TBlobStorageGroupType::TPartPlacement partPlacement;
- bool isCorrectable = info.Type.CorrectLayout(layout, partPlacement);
- Y_VERIFY(isCorrectable);
- if (IsPutNeeded(state, partPlacement)) {
- PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
- }
- }
-
- return EStrategyOutcome::IN_PROGRESS;
+ TBlobStorageGroupType::TPartPlacement partPlacement;
+ bool isCorrectable = info.Type.CorrectLayout(layout, partPlacement);
+ Y_VERIFY(isCorrectable);
+ if (IsPutNeeded(state, partPlacement)) {
+ PreparePutsForPartPlacement(logCtx, state, info, groupDiskRequests, partPlacement);
+ }
+ }
+
+ return EStrategyOutcome::IN_PROGRESS;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_timestats.h b/ydb/core/blobstorage/dsproxy/dsproxy_timestats.h
index 943b93858df..79d6a87d2a6 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_timestats.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_timestats.h
@@ -1,204 +1,204 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/blobstorage.h>
-
+
#include <library/cpp/monlib/service/pages/templates.h>
-
-#include <util/generic/queue.h>
-#include <util/datetime/parser.h>
-
-namespace NKikimr {
-
-class TBlobStorageGroupProxyTimeStats {
- template<typename TItem>
- class TTimeSeries {
- using TQueueItem = std::pair<TInstant, TItem>;
-
- struct TCompare {
- bool operator ()(const TQueueItem& x, const TQueueItem& y) const {
- return x.first < y.first;
- }
- };
-
- TDuration& AggrTime;
+
+#include <util/generic/queue.h>
+#include <util/datetime/parser.h>
+
+namespace NKikimr {
+
+class TBlobStorageGroupProxyTimeStats {
+ template<typename TItem>
+ class TTimeSeries {
+ using TQueueItem = std::pair<TInstant, TItem>;
+
+ struct TCompare {
+ bool operator ()(const TQueueItem& x, const TQueueItem& y) const {
+ return x.first < y.first;
+ }
+ };
+
+ TDuration& AggrTime;
TDeque<TQueueItem> Queue;
-
- public:
- TTimeSeries(TDuration& aggrTime)
- : AggrTime(aggrTime)
- {}
-
- void Add(TInstant now, TItem&& item) {
- Queue.emplace_back(now, std::move(item));
- Update(now);
- }
-
- void Update(TInstant now) {
- while (!Queue.empty() && Queue.front().first + AggrTime < now) {
- Queue.pop_front();
- }
- }
-
- void MergeIn(TTimeSeries&& other) {
- if (!other.Queue.empty()) {
+
+ public:
+ TTimeSeries(TDuration& aggrTime)
+ : AggrTime(aggrTime)
+ {}
+
+ void Add(TInstant now, TItem&& item) {
+ Queue.emplace_back(now, std::move(item));
+ Update(now);
+ }
+
+ void Update(TInstant now) {
+ while (!Queue.empty() && Queue.front().first + AggrTime < now) {
+ Queue.pop_front();
+ }
+ }
+
+ void MergeIn(TTimeSeries&& other) {
+ if (!other.Queue.empty()) {
TDeque<TQueueItem> res;
- std::set_union(Queue.begin(), Queue.end(), other.Queue.begin(), other.Queue.end(),
- std::back_inserter(res), TCompare());
- Queue.swap(res);
- }
- }
-
+ std::set_union(Queue.begin(), Queue.end(), other.Queue.begin(), other.Queue.end(),
+ std::back_inserter(res), TCompare());
+ Queue.swap(res);
+ }
+ }
+
const TDeque<TQueueItem>& GetVector() const {
- return Queue;
- }
- };
-
- struct TPutInfo {
- TDuration InSenderQueue;
- TDuration Total;
- TDuration InQueue;
- TDuration Execution;
- TDuration RTT;
- };
-
- struct THugePutInfo : public TPutInfo {
- TDuration HugeWriteTime;
- };
-
- template<typename T>
- struct TCompareTimeSeries {
- bool operator ()(ui32 key, const std::pair<ui32, T>& value) const {
- return key < value.first;
- }
- };
-
-private:
- TDuration AggrTime;
- double Percentile;
- bool Enabled;
+ return Queue;
+ }
+ };
+
+ struct TPutInfo {
+ TDuration InSenderQueue;
+ TDuration Total;
+ TDuration InQueue;
+ TDuration Execution;
+ TDuration RTT;
+ };
+
+ struct THugePutInfo : public TPutInfo {
+ TDuration HugeWriteTime;
+ };
+
+ template<typename T>
+ struct TCompareTimeSeries {
+ bool operator ()(ui32 key, const std::pair<ui32, T>& value) const {
+ return key < value.first;
+ }
+ };
+
+private:
+ TDuration AggrTime;
+ double Percentile;
+ bool Enabled;
TVector<std::pair<ui32, TTimeSeries<TPutInfo>>> Puts;
TVector<std::pair<ui32, TTimeSeries<THugePutInfo>>> HugePuts;
-
-public:
- TBlobStorageGroupProxyTimeStats(TDuration aggrTime = TDuration::Seconds(5))
- : AggrTime(aggrTime)
- , Percentile(0.9)
- , Enabled(false)
- {
- for (ui32 size : {0, 128, 1024, 4096, 65536, 1048576}) {
- Puts.emplace_back(size, aggrTime);
- }
- for (ui32 sizeKB : {0, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168}) {
- HugePuts.emplace_back(sizeKB << 10, aggrTime);
- }
- }
-
- void ApplyPut(ui32 size, const NKikimrBlobStorage::TExecTimeStats& execTimeStats) {
+
+public:
+ TBlobStorageGroupProxyTimeStats(TDuration aggrTime = TDuration::Seconds(5))
+ : AggrTime(aggrTime)
+ , Percentile(0.9)
+ , Enabled(false)
+ {
+ for (ui32 size : {0, 128, 1024, 4096, 65536, 1048576}) {
+ Puts.emplace_back(size, aggrTime);
+ }
+ for (ui32 sizeKB : {0, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168}) {
+ HugePuts.emplace_back(sizeKB << 10, aggrTime);
+ }
+ }
+
+ void ApplyPut(ui32 size, const NKikimrBlobStorage::TExecTimeStats& execTimeStats) {
TInstant submitTimestamp = TInstant::MicroSeconds(execTimeStats.GetSubmitTimestamp());
- TInstant now = TAppData::TimeProvider->Now();
- TDuration rtt = now - submitTimestamp;
-
- THugePutInfo info;
+ TInstant now = TAppData::TimeProvider->Now();
+ TDuration rtt = now - submitTimestamp;
+
+ THugePutInfo info;
info.InSenderQueue = TDuration::MicroSeconds(execTimeStats.GetInSenderQueue());
info.Total = TDuration::MicroSeconds(execTimeStats.GetTotal());
info.InQueue = TDuration::MicroSeconds(execTimeStats.GetInQueue());
info.Execution = TDuration::MicroSeconds(execTimeStats.GetExecution());
- info.RTT = rtt;
+ info.RTT = rtt;
info.HugeWriteTime = TDuration::MicroSeconds(execTimeStats.GetHugeWriteTime());
-
- if (execTimeStats.HasHugeWriteTime()) {
- auto it = std::upper_bound(HugePuts.begin(), HugePuts.end(), size, TCompareTimeSeries<TTimeSeries<THugePutInfo>>());
- Y_VERIFY(it != HugePuts.begin());
- --it;
- it->second.Add(now, std::move(info));
- } else {
- auto it = std::upper_bound(Puts.begin(), Puts.end(), size, TCompareTimeSeries<TTimeSeries<TPutInfo>>());
- Y_VERIFY(it != Puts.begin());
- --it;
- it->second.Add(now, std::move(info));
- }
- }
-
- void MergeIn(TBlobStorageGroupProxyTimeStats&& timeStats) {
- Y_VERIFY(Puts.size() == timeStats.Puts.size());
- for (auto it1 = Puts.begin(), it2 = timeStats.Puts.begin(); it1 != Puts.end(); ++it1, ++it2) {
- it1->second.MergeIn(std::move(it2->second));
- }
- Y_VERIFY(HugePuts.size() == timeStats.HugePuts.size());
- for (auto it1 = HugePuts.begin(), it2 = timeStats.HugePuts.begin(); it1 != HugePuts.end(); ++it1, ++it2) {
- it1->second.MergeIn(std::move(it2->second));
- }
- }
-
+
+ if (execTimeStats.HasHugeWriteTime()) {
+ auto it = std::upper_bound(HugePuts.begin(), HugePuts.end(), size, TCompareTimeSeries<TTimeSeries<THugePutInfo>>());
+ Y_VERIFY(it != HugePuts.begin());
+ --it;
+ it->second.Add(now, std::move(info));
+ } else {
+ auto it = std::upper_bound(Puts.begin(), Puts.end(), size, TCompareTimeSeries<TTimeSeries<TPutInfo>>());
+ Y_VERIFY(it != Puts.begin());
+ --it;
+ it->second.Add(now, std::move(info));
+ }
+ }
+
+ void MergeIn(TBlobStorageGroupProxyTimeStats&& timeStats) {
+ Y_VERIFY(Puts.size() == timeStats.Puts.size());
+ for (auto it1 = Puts.begin(), it2 = timeStats.Puts.begin(); it1 != Puts.end(); ++it1, ++it2) {
+ it1->second.MergeIn(std::move(it2->second));
+ }
+ Y_VERIFY(HugePuts.size() == timeStats.HugePuts.size());
+ for (auto it1 = HugePuts.begin(), it2 = timeStats.HugePuts.begin(); it1 != HugePuts.end(); ++it1, ++it2) {
+ it1->second.MergeIn(std::move(it2->second));
+ }
+ }
+
void Render(IOutputStream& str) {
- const TInstant now = TAppData::TimeProvider->Now();
-
-#define PARAM(NAME, V) \
- do { \
+ const TInstant now = TAppData::TimeProvider->Now();
+
+#define PARAM(NAME, V) \
+ do { \
TABLER() { \
TABLED() { str << "<b>" << #NAME << "</b>"; } \
- for (auto it = V.begin(); it != V.end(); ++it) { \
- auto& series = it->second; \
- series.Update(now); \
- const auto& v = series.GetVector(); \
- using T = decltype(std::declval<std::decay<decltype(v)>::type::value_type::second_type>().NAME); \
+ for (auto it = V.begin(); it != V.end(); ++it) { \
+ auto& series = it->second; \
+ series.Update(now); \
+ const auto& v = series.GetVector(); \
+ using T = decltype(std::declval<std::decay<decltype(v)>::type::value_type::second_type>().NAME); \
TVector<T> values; \
- values.reserve(v.size()); \
- for (const auto& item : v) { \
- values.push_back(item.second.NAME); \
- } \
- std::sort(values.begin(), values.end()); \
+ values.reserve(v.size()); \
+ for (const auto& item : v) { \
+ values.push_back(item.second.NAME); \
+ } \
+ std::sort(values.begin(), values.end()); \
TABLED() { \
- if (values) { \
- size_t index = perc * values.size(); \
- if (index >= values.size()) { \
- index = values.size() - 1; \
- } \
- str << values[index]; \
- } else { \
- str << "none"; \
- } \
+ if (values) { \
+ size_t index = perc * values.size(); \
+ if (index >= values.size()) { \
+ index = values.size() - 1; \
+ } \
+ str << values[index]; \
+ } else { \
+ str << "none"; \
+ } \
} \
- } \
+ } \
} \
- } while (false)
- double perc = Percentile;
+ } while (false)
+ double perc = Percentile;
HTML(str) {
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
- str << "Time accounting setup";
+ str << "Time accounting setup";
}
DIV_CLASS("panel-body") {
FORM_CLASS("form-horizontal") {
DIV_CLASS("control-group") {
DIV_CLASS("controls") {
LABEL_CLASS("checkbox") {
- str << "<input type=\"checkbox\" name=\"enabled\"";
- if (Enabled) {
- str << " checked=\"checked\"";
- }
- str << ">Enabled</input>";
+ str << "<input type=\"checkbox\" name=\"enabled\"";
+ if (Enabled) {
+ str << " checked=\"checked\"";
+ }
+ str << ">Enabled</input>";
}
}
}
DIV_CLASS("control-group") {
LABEL_CLASS_FOR("control-label", "inputAggrTime") { str << "Aggregation time"; }
DIV_CLASS("controls") {
- str << "<input id=\"inputAggrTime\" name=\"aggrTime\" type=\"text\" value=\"" << AggrTime << "\"/>";
+ str << "<input id=\"inputAggrTime\" name=\"aggrTime\" type=\"text\" value=\"" << AggrTime << "\"/>";
}
}
DIV_CLASS("control-group") {
LABEL_CLASS_FOR("control-label", "inputPercentile") { str << "Percentile"; }
DIV_CLASS("controls") {
- str << "<input id=\"inputPercentile\" name=\"percentile\" type=\"text\" value=\"" << Percentile << "\"/>";
+ str << "<input id=\"inputPercentile\" name=\"percentile\" type=\"text\" value=\"" << Percentile << "\"/>";
}
}
DIV_CLASS("control-group") {
DIV_CLASS("controls") {
- str << "<button type=\"submit\" name=\"submit_timestats\" class=\"btn btn-default\">Submit</button>";
+ str << "<button type=\"submit\" name=\"submit_timestats\" class=\"btn btn-default\">Submit</button>";
}
}
}
@@ -206,84 +206,84 @@ public:
}
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
- str << "Put stats percentile# " << perc;
+ str << "Put stats percentile# " << perc;
}
DIV_CLASS("panel-body") {
TABLE_CLASS ("table table-condensed") {
TABLEHEAD() {
TABLER() {
TABLEH() { str << "size"; }
- for (auto it = Puts.begin(); it != Puts.end(); ++it) {
+ for (auto it = Puts.begin(); it != Puts.end(); ++it) {
TABLEH() {
- str << it->first << "+";
+ str << it->first << "+";
}
- }
+ }
}
}
TABLEBODY() {
- PARAM(InSenderQueue, Puts);
- PARAM(Total, Puts);
- PARAM(InQueue, Puts);
- PARAM(Execution, Puts);
- PARAM(RTT, Puts);
+ PARAM(InSenderQueue, Puts);
+ PARAM(Total, Puts);
+ PARAM(InQueue, Puts);
+ PARAM(Execution, Puts);
+ PARAM(RTT, Puts);
}
}
}
}
DIV_CLASS("panel panel-info") {
DIV_CLASS("panel-heading") {
- str << "HugePut stats percentile# " << perc;
+ str << "HugePut stats percentile# " << perc;
}
DIV_CLASS("panel-body") {
TABLE_CLASS ("table table-condensed") {
TABLEHEAD() {
TABLER() {
TABLEH() { str << "size"; }
- for (auto it = HugePuts.begin(); it != HugePuts.end(); ++it) {
+ for (auto it = HugePuts.begin(); it != HugePuts.end(); ++it) {
TABLEH() {
- str << it->first << "+";
+ str << it->first << "+";
}
- }
+ }
}
}
TABLEBODY() {
- PARAM(InSenderQueue, HugePuts);
- PARAM(Total, HugePuts);
- PARAM(InQueue, HugePuts);
- PARAM(Execution, HugePuts);
- PARAM(RTT, HugePuts);
- PARAM(HugeWriteTime, HugePuts);
+ PARAM(InSenderQueue, HugePuts);
+ PARAM(Total, HugePuts);
+ PARAM(InQueue, HugePuts);
+ PARAM(Execution, HugePuts);
+ PARAM(RTT, HugePuts);
+ PARAM(HugeWriteTime, HugePuts);
}
}
}
}
}
- }
-
- template<typename TCgiParameters>
- void Submit(const TCgiParameters& cgi) {
- Enabled = cgi.Has("enabled");
- if (cgi.Has("aggrTime")) {
+ }
+
+ template<typename TCgiParameters>
+ void Submit(const TCgiParameters& cgi) {
+ Enabled = cgi.Has("enabled");
+ if (cgi.Has("aggrTime")) {
TString param = cgi.Get("aggrTime");
- TDurationParser parser;
+ TDurationParser parser;
if (parser.ParsePart(param.data(), param.size())) {
- AggrTime = parser.GetResult(AggrTime);
- }
- }
- }
-
- bool IsEnabled() const {
- return Enabled;
- }
-};
-
-struct TEvTimeStats : public TEventLocal<TEvTimeStats, TEvBlobStorage::EvTimeStats> {
- TBlobStorageGroupProxyTimeStats TimeStats;
-
- TEvTimeStats(TBlobStorageGroupProxyTimeStats&& timeStats)
- : TimeStats(std::move(timeStats))
- {}
-};
-
-} // NKikimr
+ AggrTime = parser.GetResult(AggrTime);
+ }
+ }
+ }
+
+ bool IsEnabled() const {
+ return Enabled;
+ }
+};
+
+struct TEvTimeStats : public TEventLocal<TEvTimeStats, TEvBlobStorage::EvTimeStats> {
+ TBlobStorageGroupProxyTimeStats TimeStats;
+
+ TEvTimeStats(TBlobStorageGroupProxyTimeStats&& timeStats)
+ : TimeStats(std::move(timeStats))
+ {}
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/group_sessions.cpp b/ydb/core/blobstorage/dsproxy/group_sessions.cpp
index 016952e1e2e..8fd7263e124 100644
--- a/ydb/core/blobstorage/dsproxy/group_sessions.cpp
+++ b/ydb/core/blobstorage/dsproxy/group_sessions.cpp
@@ -1,125 +1,125 @@
-#include "group_sessions.h"
+#include "group_sessions.h"
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
-
-namespace NKikimr {
-
-static NKikimrBlobStorage::EVDiskQueueId VDiskQueues[] = {
- NKikimrBlobStorage::EVDiskQueueId::PutTabletLog,
- NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob,
- NKikimrBlobStorage::EVDiskQueueId::PutUserData,
- NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead,
- NKikimrBlobStorage::EVDiskQueueId::GetFastRead,
- NKikimrBlobStorage::EVDiskQueueId::GetDiscover,
+
+namespace NKikimr {
+
+static NKikimrBlobStorage::EVDiskQueueId VDiskQueues[] = {
+ NKikimrBlobStorage::EVDiskQueueId::PutTabletLog,
+ NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob,
+ NKikimrBlobStorage::EVDiskQueueId::PutUserData,
+ NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead,
+ NKikimrBlobStorage::EVDiskQueueId::GetFastRead,
+ NKikimrBlobStorage::EVDiskQueueId::GetDiscover,
NKikimrBlobStorage::EVDiskQueueId::GetLowRead,
-};
-
-TString QueueIdName(NKikimrBlobStorage::EVDiskQueueId queueId) {
- switch (queueId) {
- case NKikimrBlobStorage::EVDiskQueueId::PutTabletLog: return "PutTabletLog";
- case NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob: return "PutAsyncBlob";
- case NKikimrBlobStorage::EVDiskQueueId::PutUserData: return "PutUserData";
- case NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead: return "GetAsyncRead";
- case NKikimrBlobStorage::EVDiskQueueId::GetFastRead: return "GetFastRead";
- case NKikimrBlobStorage::EVDiskQueueId::GetDiscover: return "GetDiscover";
+};
+
+TString QueueIdName(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ switch (queueId) {
+ case NKikimrBlobStorage::EVDiskQueueId::PutTabletLog: return "PutTabletLog";
+ case NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob: return "PutAsyncBlob";
+ case NKikimrBlobStorage::EVDiskQueueId::PutUserData: return "PutUserData";
+ case NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead: return "GetAsyncRead";
+ case NKikimrBlobStorage::EVDiskQueueId::GetFastRead: return "GetFastRead";
+ case NKikimrBlobStorage::EVDiskQueueId::GetDiscover: return "GetDiscover";
case NKikimrBlobStorage::EVDiskQueueId::GetLowRead: return "GetLowRead";
- default: Y_FAIL("unexpected EVDiskQueueId");
- }
-}
-
-TGroupSessions::TGroupSessions(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TBSProxyContextPtr& bspctx,
- const TActorId& monActor, const TActorId& proxyActor)
- : GroupQueues(MakeIntrusive<TGroupQueues>(info->GetTopology()))
- , ConnectedQueuesMask(info->GetTotalVDisksNum(), 0)
- , MonActor(monActor)
- , ProxyActor(proxyActor)
-{
- const ui32 nodeId = TlsActivationContext->ExecutorThread.ActorSystem->NodeId;
-
- for (const auto& vdisk : info->GetVDisks()) {
- auto vd = info->GetVDiskId(vdisk.OrderNumber);
- auto& stateVDisk = GroupQueues->FailDomains[vdisk.FailDomainOrderNumber].VDisks[vd.VDisk];
- const ui32 targetNodeId = info->GetActorId(vdisk.OrderNumber).NodeId();
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters = GetServiceCounters(AppData()->Counters, "dsproxy_queue");
-
- for (NKikimrBlobStorage::EVDiskQueueId queueId : VDiskQueues) {
- ui32 interconnectChannel = 0;
- switch (queueId) {
- case NKikimrBlobStorage::PutTabletLog:
- case NKikimrBlobStorage::PutUserData:
- case NKikimrBlobStorage::GetFastRead:
- interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE;
- break;
-
- case NKikimrBlobStorage::GetDiscover:
- interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_DISCOVER;
- break;
-
- case NKikimrBlobStorage::PutAsyncBlob:
- case NKikimrBlobStorage::GetAsyncRead:
+ default: Y_FAIL("unexpected EVDiskQueueId");
+ }
+}
+
+TGroupSessions::TGroupSessions(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TBSProxyContextPtr& bspctx,
+ const TActorId& monActor, const TActorId& proxyActor)
+ : GroupQueues(MakeIntrusive<TGroupQueues>(info->GetTopology()))
+ , ConnectedQueuesMask(info->GetTotalVDisksNum(), 0)
+ , MonActor(monActor)
+ , ProxyActor(proxyActor)
+{
+ const ui32 nodeId = TlsActivationContext->ExecutorThread.ActorSystem->NodeId;
+
+ for (const auto& vdisk : info->GetVDisks()) {
+ auto vd = info->GetVDiskId(vdisk.OrderNumber);
+ auto& stateVDisk = GroupQueues->FailDomains[vdisk.FailDomainOrderNumber].VDisks[vd.VDisk];
+ const ui32 targetNodeId = info->GetActorId(vdisk.OrderNumber).NodeId();
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters = GetServiceCounters(AppData()->Counters, "dsproxy_queue");
+
+ for (NKikimrBlobStorage::EVDiskQueueId queueId : VDiskQueues) {
+ ui32 interconnectChannel = 0;
+ switch (queueId) {
+ case NKikimrBlobStorage::PutTabletLog:
+ case NKikimrBlobStorage::PutUserData:
+ case NKikimrBlobStorage::GetFastRead:
+ interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE;
+ break;
+
+ case NKikimrBlobStorage::GetDiscover:
+ interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_DISCOVER;
+ break;
+
+ case NKikimrBlobStorage::PutAsyncBlob:
+ case NKikimrBlobStorage::GetAsyncRead:
case NKikimrBlobStorage::GetLowRead:
- interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_ASYNC_DATA;
- break;
-
- default:
- Y_FAIL("unexpected queue id");
- }
-
- TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
-
- std::unique_ptr<NActors::IActor> queueActor(CreateVDiskBackpressureClient(info, vd, queueId, counters, bspctx,
- NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, nodeId), QueueIdName(queueId),
- interconnectChannel, nodeId == targetNodeId, TDuration::Minutes(1), flowRecord,
- NMonitoring::TCountableBase::EVisibility::Public));
-
- TActorId queue = TActivationContext::Register(queueActor.release(), ProxyActor, TMailboxType::ReadAsFilled,
- AppData()->SystemPoolId);
-
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << info->GroupID
- << " Actor# " << ProxyActor
- << " Create Queue# " << queue.ToString()
- << " targetNodeId# " << targetNodeId
- << " Marker# DSP01");
-
- auto& q = stateVDisk.Queues.GetQueue(queueId);
- q.ActorId = queue;
- q.FlowRecord = std::move(flowRecord);
- }
- }
-}
-
-void TGroupSessions::Poison() {
- for (const auto& domain : GroupQueues->FailDomains) {
- for (const auto& vdisk : domain.VDisks) {
- vdisk.Queues.ForEachQueue([](const auto& queue) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, queue.ActorId, {}, nullptr, 0));
- });
- }
- }
-}
-
-bool TGroupSessions::GoodToGo(const TBlobStorageGroupInfo::TTopology& topology, bool waitForAllVDisks) {
- // create a set of connected disks
- TBlobStorageGroupInfo::TGroupVDisks connected(&topology);
- for (ui32 i = 0; i < ConnectedQueuesMask.size(); ++i) {
- if (ConnectedQueuesMask[i] == AllQueuesMask) {
- connected += TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&topology, ui64(1) << i);
- }
- }
-
- // check if we have quorum; in force mode we wait for all disks
- return waitForAllVDisks
- ? connected.GetNumSetItems() == topology.GetTotalVDisksNum()
- : topology.GetQuorumChecker().CheckQuorumForGroup(connected);
-}
-
-void TGroupSessions::QueueConnectUpdate(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId, bool connected) {
- if (connected) {
- ConnectedQueuesMask[orderNumber] |= 1 << queueId;
- } else {
- ConnectedQueuesMask[orderNumber] &= ~(1 << queueId);
- }
-}
-
-} // NKikimr
+ interconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_ASYNC_DATA;
+ break;
+
+ default:
+ Y_FAIL("unexpected queue id");
+ }
+
+ TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
+
+ std::unique_ptr<NActors::IActor> queueActor(CreateVDiskBackpressureClient(info, vd, queueId, counters, bspctx,
+ NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, nodeId), QueueIdName(queueId),
+ interconnectChannel, nodeId == targetNodeId, TDuration::Minutes(1), flowRecord,
+ NMonitoring::TCountableBase::EVisibility::Public));
+
+ TActorId queue = TActivationContext::Register(queueActor.release(), ProxyActor, TMailboxType::ReadAsFilled,
+ AppData()->SystemPoolId);
+
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Group# " << info->GroupID
+ << " Actor# " << ProxyActor
+ << " Create Queue# " << queue.ToString()
+ << " targetNodeId# " << targetNodeId
+ << " Marker# DSP01");
+
+ auto& q = stateVDisk.Queues.GetQueue(queueId);
+ q.ActorId = queue;
+ q.FlowRecord = std::move(flowRecord);
+ }
+ }
+}
+
+void TGroupSessions::Poison() {
+ for (const auto& domain : GroupQueues->FailDomains) {
+ for (const auto& vdisk : domain.VDisks) {
+ vdisk.Queues.ForEachQueue([](const auto& queue) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, queue.ActorId, {}, nullptr, 0));
+ });
+ }
+ }
+}
+
+bool TGroupSessions::GoodToGo(const TBlobStorageGroupInfo::TTopology& topology, bool waitForAllVDisks) {
+ // create a set of connected disks
+ TBlobStorageGroupInfo::TGroupVDisks connected(&topology);
+ for (ui32 i = 0; i < ConnectedQueuesMask.size(); ++i) {
+ if (ConnectedQueuesMask[i] == AllQueuesMask) {
+ connected += TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&topology, ui64(1) << i);
+ }
+ }
+
+ // check if we have quorum; in force mode we wait for all disks
+ return waitForAllVDisks
+ ? connected.GetNumSetItems() == topology.GetTotalVDisksNum()
+ : topology.GetQuorumChecker().CheckQuorumForGroup(connected);
+}
+
+void TGroupSessions::QueueConnectUpdate(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId, bool connected) {
+ if (connected) {
+ ConnectedQueuesMask[orderNumber] |= 1 << queueId;
+ } else {
+ ConnectedQueuesMask[orderNumber] &= ~(1 << queueId);
+ }
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/group_sessions.h b/ydb/core/blobstorage/dsproxy/group_sessions.h
index b4b9db6284e..3b625f05077 100644
--- a/ydb/core/blobstorage/dsproxy/group_sessions.h
+++ b/ydb/core/blobstorage/dsproxy/group_sessions.h
@@ -1,237 +1,237 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
-
+
#include <ydb/core/blobstorage/backpressure/queue_backpressure_common.h>
-
-namespace NKikimr {
-
- constexpr ui32 TypicalDisksInGroup = 32;
- constexpr ui32 TypicalFailDomainsInGroup = 8;
- constexpr ui32 TypicalDisksInFailDomain = 4;
-
- // TGroupQueues is a set of ActorIds for queues representing each queue for each disk in the group, also the shared
- // FlowRecord for every queue
- struct TGroupQueues : TThrRefBase {
- struct TVDisk {
- struct TQueues {
- struct TQueue {
- TActorId ActorId;
- TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
- };
- TQueue PutTabletLog;
- TQueue PutAsyncBlob;
- TQueue PutUserData;
- TQueue GetAsyncRead;
- TQueue GetFastRead;
- TQueue GetDiscover;
+
+namespace NKikimr {
+
+ constexpr ui32 TypicalDisksInGroup = 32;
+ constexpr ui32 TypicalFailDomainsInGroup = 8;
+ constexpr ui32 TypicalDisksInFailDomain = 4;
+
+ // TGroupQueues is a set of ActorIds for queues representing each queue for each disk in the group, also the shared
+ // FlowRecord for every queue
+ struct TGroupQueues : TThrRefBase {
+ struct TVDisk {
+ struct TQueues {
+ struct TQueue {
+ TActorId ActorId;
+ TIntrusivePtr<NBackpressure::TFlowRecord> FlowRecord;
+ };
+ TQueue PutTabletLog;
+ TQueue PutAsyncBlob;
+ TQueue PutUserData;
+ TQueue GetAsyncRead;
+ TQueue GetFastRead;
+ TQueue GetDiscover;
TQueue GetLowRead;
-
- template<typename T>
- void ForEachQueue(T&& callback) const {
- for (const TQueue *q : {&PutTabletLog, &PutAsyncBlob, &PutUserData, &GetAsyncRead, &GetFastRead,
+
+ template<typename T>
+ void ForEachQueue(T&& callback) const {
+ for (const TQueue *q : {&PutTabletLog, &PutAsyncBlob, &PutUserData, &GetAsyncRead, &GetFastRead,
&GetDiscover, &GetLowRead}) {
- callback(*q);
- }
- }
-
- template<typename T>
- static NKikimrBlobStorage::EVDiskQueueId VDiskQueueId(const T& event) {
- Y_VERIFY(event.Record.HasMsgQoS());
- auto &msgQoS = event.Record.GetMsgQoS();
- Y_VERIFY(msgQoS.HasExtQueueId());
- NKikimrBlobStorage::EVDiskQueueId queueId = msgQoS.GetExtQueueId();
- Y_VERIFY(queueId != NKikimrBlobStorage::EVDiskQueueId::Unknown);
- return queueId;
- }
-
- static NKikimrBlobStorage::EVDiskQueueId VDiskQueueId(const TEvBlobStorage::TEvVStatus&) {
- return NKikimrBlobStorage::EVDiskQueueId::GetFastRead;
- }
-
- TQueue& GetQueue(NKikimrBlobStorage::EVDiskQueueId queueId) {
- switch (queueId) {
- case NKikimrBlobStorage::EVDiskQueueId::PutTabletLog: return PutTabletLog;
- case NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob: return PutAsyncBlob;
- case NKikimrBlobStorage::EVDiskQueueId::PutUserData: return PutUserData;
- case NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead: return GetAsyncRead;
- case NKikimrBlobStorage::EVDiskQueueId::GetFastRead: return GetFastRead;
- case NKikimrBlobStorage::EVDiskQueueId::GetDiscover: return GetDiscover;
+ callback(*q);
+ }
+ }
+
+ template<typename T>
+ static NKikimrBlobStorage::EVDiskQueueId VDiskQueueId(const T& event) {
+ Y_VERIFY(event.Record.HasMsgQoS());
+ auto &msgQoS = event.Record.GetMsgQoS();
+ Y_VERIFY(msgQoS.HasExtQueueId());
+ NKikimrBlobStorage::EVDiskQueueId queueId = msgQoS.GetExtQueueId();
+ Y_VERIFY(queueId != NKikimrBlobStorage::EVDiskQueueId::Unknown);
+ return queueId;
+ }
+
+ static NKikimrBlobStorage::EVDiskQueueId VDiskQueueId(const TEvBlobStorage::TEvVStatus&) {
+ return NKikimrBlobStorage::EVDiskQueueId::GetFastRead;
+ }
+
+ TQueue& GetQueue(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ switch (queueId) {
+ case NKikimrBlobStorage::EVDiskQueueId::PutTabletLog: return PutTabletLog;
+ case NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob: return PutAsyncBlob;
+ case NKikimrBlobStorage::EVDiskQueueId::PutUserData: return PutUserData;
+ case NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead: return GetAsyncRead;
+ case NKikimrBlobStorage::EVDiskQueueId::GetFastRead: return GetFastRead;
+ case NKikimrBlobStorage::EVDiskQueueId::GetDiscover: return GetDiscover;
case NKikimrBlobStorage::EVDiskQueueId::GetLowRead: return GetLowRead;
- default: Y_FAIL("unexpected EVDiskQueueId");
- }
- }
-
- TActorId& QueueForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
- return GetQueue(queueId).ActorId;
- }
-
- TIntrusivePtr<NBackpressure::TFlowRecord>& FlowRecordForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
- return GetQueue(queueId).FlowRecord;
- }
-
- ui64 PredictedDelayNsForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
- const auto& flowRecord = FlowRecordForQueueId(queueId);
- return flowRecord ? flowRecord->GetPredictedDelayNs() : 0;
- }
-
- template<typename TEvent>
- TActorId QueueForEvent(const TEvent& event) {
- return QueueForQueueId(VDiskQueueId(event));
- }
-
- TString ToString() const {
- TStringStream s;
- s << "{PutTabletLog# " << PutTabletLog.ActorId
- << " PutAsyncBlob# " << PutAsyncBlob.ActorId
- << " PutUserData# " << PutUserData.ActorId
- << " GetAsyncRead# " << GetAsyncRead.ActorId
- << " GetFastRead# " << GetAsyncRead.ActorId
- << " GetDiscover# " << GetDiscover.ActorId
+ default: Y_FAIL("unexpected EVDiskQueueId");
+ }
+ }
+
+ TActorId& QueueForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ return GetQueue(queueId).ActorId;
+ }
+
+ TIntrusivePtr<NBackpressure::TFlowRecord>& FlowRecordForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ return GetQueue(queueId).FlowRecord;
+ }
+
+ ui64 PredictedDelayNsForQueueId(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ const auto& flowRecord = FlowRecordForQueueId(queueId);
+ return flowRecord ? flowRecord->GetPredictedDelayNs() : 0;
+ }
+
+ template<typename TEvent>
+ TActorId QueueForEvent(const TEvent& event) {
+ return QueueForQueueId(VDiskQueueId(event));
+ }
+
+ TString ToString() const {
+ TStringStream s;
+ s << "{PutTabletLog# " << PutTabletLog.ActorId
+ << " PutAsyncBlob# " << PutAsyncBlob.ActorId
+ << " PutUserData# " << PutUserData.ActorId
+ << " GetAsyncRead# " << GetAsyncRead.ActorId
+ << " GetFastRead# " << GetAsyncRead.ActorId
+ << " GetDiscover# " << GetDiscover.ActorId
<< " GetLowRead# " << GetLowRead.ActorId
-
- << " PutTabletLog_PredictedDelayNs# "
- << (PutTabletLog.FlowRecord ? PutTabletLog.FlowRecord->GetPredictedDelayNs() : 0)
- << " PutAsyncBlob_PredictedDelayNs# "
- << (PutAsyncBlob.FlowRecord ? PutAsyncBlob.FlowRecord->GetPredictedDelayNs() : 0)
- << " PutUserData_PredictedDelayNs# "
- << (PutUserData.FlowRecord ? PutUserData.FlowRecord->GetPredictedDelayNs() : 0)
- << " GetAsyncRead_PredictedDelayNs# "
- << (GetAsyncRead.FlowRecord ? GetAsyncRead.FlowRecord->GetPredictedDelayNs() : 0)
- << " GetFastRead_PredictedDelayNs# "
- << (GetAsyncRead.FlowRecord ? GetAsyncRead.FlowRecord->GetPredictedDelayNs() : 0)
- << " GetDiscover_PredictedDelayNs# "
- << (GetDiscover.FlowRecord ? GetDiscover.FlowRecord->GetPredictedDelayNs() : 0)
+
+ << " PutTabletLog_PredictedDelayNs# "
+ << (PutTabletLog.FlowRecord ? PutTabletLog.FlowRecord->GetPredictedDelayNs() : 0)
+ << " PutAsyncBlob_PredictedDelayNs# "
+ << (PutAsyncBlob.FlowRecord ? PutAsyncBlob.FlowRecord->GetPredictedDelayNs() : 0)
+ << " PutUserData_PredictedDelayNs# "
+ << (PutUserData.FlowRecord ? PutUserData.FlowRecord->GetPredictedDelayNs() : 0)
+ << " GetAsyncRead_PredictedDelayNs# "
+ << (GetAsyncRead.FlowRecord ? GetAsyncRead.FlowRecord->GetPredictedDelayNs() : 0)
+ << " GetFastRead_PredictedDelayNs# "
+ << (GetAsyncRead.FlowRecord ? GetAsyncRead.FlowRecord->GetPredictedDelayNs() : 0)
+ << " GetDiscover_PredictedDelayNs# "
+ << (GetDiscover.FlowRecord ? GetDiscover.FlowRecord->GetPredictedDelayNs() : 0)
<< " GetLowRead_PredictedDelayNs# "
<< (GetLowRead.FlowRecord ? GetLowRead.FlowRecord->GetPredictedDelayNs() : 0)
-
- << "}";
- return s.Str();
- }
- };
-
- TQueues Queues;
-
- TString ToString() const {
- return TStringBuilder() << "{Queues# " << Queues.ToString() << "}";
- }
- };
-
- struct TFailDomain {
- TStackVec<TVDisk, TypicalDisksInFailDomain> VDisks;
-
- // Ill-formed because TVDisk is not assignable.
- void operator=(const TFailDomain&) = delete;
-
- TString ToString() const {
- TStringStream str;
- str << "{VDisks# {";
- for (ui32 i = 0; i < VDisks.size(); ++i) {
- str << (i ? " " : "") << i << ":{" << VDisks[i].ToString() << "}";
- }
- str << "}}";
- return str.Str();
- }
- };
-
- TStackVec<TFailDomain, TypicalFailDomainsInGroup> FailDomains;
- TStackVec<TVDisk*, TypicalDisksInGroup> DisksByOrderNumber;
-
- TGroupQueues(const TBlobStorageGroupInfo::TTopology& topology)
- : FailDomains(topology.GetTotalFailDomainsNum())
- , DisksByOrderNumber(topology.GetTotalVDisksNum())
- {
- // create group-like structure, but with plain fail domains as an array indexed by fail domain order number
- for (TFailDomain& domain : FailDomains) {
- domain.VDisks.resize(topology.GetNumVDisksPerFailDomain());
- }
- for (const auto& vdisk : topology.GetVDisks()) {
- DisksByOrderNumber[vdisk.OrderNumber] =
- &FailDomains[vdisk.FailDomainOrderNumber].VDisks[vdisk.VDiskIdShort.VDisk];
- }
- }
-
- template<typename TEvent>
- void SetUpSubmitTimestamp(TEvent& event) {
- TInstant now = TAppData::TimeProvider->Now();
- auto& record = event.Record;
- auto& msgQoS = *record.MutableMsgQoS();
- auto& execTimeStats = *msgQoS.MutableExecTimeStats();
- execTimeStats.SetSubmitTimestamp(now.GetValue());
- }
-
- void SetUpSubmitTimestamp(TEvBlobStorage::TEvVStatus& /*event*/) {}
-
- template<typename TEvent>
- TActorId Send(const IActor& actor, const TBlobStorageGroupInfo::TTopology& topology, std::unique_ptr<TEvent> event,
- ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled) {
- if (timeStatsEnabled) {
- SetUpSubmitTimestamp(*event);
- }
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(event->Record.GetVDiskID());
- auto& queues = FailDomains[topology.GetFailDomainOrderNumber(vdiskId)].VDisks[vdiskId.VDisk].Queues;
- TActorId queueId = queues.QueueForEvent(*event);
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Send to queueId# " << queueId
- << " " << TypeName<TEvent>() << "# " << event->ToString() << " cookie# " << cookie);
- TActivationContext::Send(new IEventHandle(queueId, actor.SelfId(), event.release(), 0, cookie, nullptr, std::move(traceId)));
- return queueId;
- }
-
- ui64 GetPredictedDelayNsByOrderNumber(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId) {
- return DisksByOrderNumber[orderNumber]->Queues.PredictedDelayNsForQueueId(queueId);
- }
-
- template<typename TEvent>
- ui64 GetPredictedDelayNsForEvent(const TEvent& event, const TBlobStorageGroupInfo::TTopology& topology) {
- return GetPredictedDelayNsByOrderNumber(topology.GetOrderNumber(VDiskIDFromVDiskID(event.Record.GetVDiskID())),
- TVDisk::TQueues::VDiskQueueId(event));
- }
-
- TString ToString() const {
- TStringStream str;
- str << "{FailDomains# {";
- for (ui32 i = 0; i < FailDomains.size(); ++i) {
- str << (i ? " " : "") << i << ":{" << FailDomains[i].ToString() << "}";
- }
- str << "}}";
- return str.Str();
- }
- };
-
- struct TGroupSessions : TThrRefBase {
- const ui8 AllQueuesMask =
- 1 << NKikimrBlobStorage::EVDiskQueueId::PutTabletLog |
- 1 << NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob |
- 1 << NKikimrBlobStorage::EVDiskQueueId::PutUserData |
- 1 << NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead |
- 1 << NKikimrBlobStorage::EVDiskQueueId::GetFastRead |
+
+ << "}";
+ return s.Str();
+ }
+ };
+
+ TQueues Queues;
+
+ TString ToString() const {
+ return TStringBuilder() << "{Queues# " << Queues.ToString() << "}";
+ }
+ };
+
+ struct TFailDomain {
+ TStackVec<TVDisk, TypicalDisksInFailDomain> VDisks;
+
+ // Ill-formed because TVDisk is not assignable.
+ void operator=(const TFailDomain&) = delete;
+
+ TString ToString() const {
+ TStringStream str;
+ str << "{VDisks# {";
+ for (ui32 i = 0; i < VDisks.size(); ++i) {
+ str << (i ? " " : "") << i << ":{" << VDisks[i].ToString() << "}";
+ }
+ str << "}}";
+ return str.Str();
+ }
+ };
+
+ TStackVec<TFailDomain, TypicalFailDomainsInGroup> FailDomains;
+ TStackVec<TVDisk*, TypicalDisksInGroup> DisksByOrderNumber;
+
+ TGroupQueues(const TBlobStorageGroupInfo::TTopology& topology)
+ : FailDomains(topology.GetTotalFailDomainsNum())
+ , DisksByOrderNumber(topology.GetTotalVDisksNum())
+ {
+ // create group-like structure, but with plain fail domains as an array indexed by fail domain order number
+ for (TFailDomain& domain : FailDomains) {
+ domain.VDisks.resize(topology.GetNumVDisksPerFailDomain());
+ }
+ for (const auto& vdisk : topology.GetVDisks()) {
+ DisksByOrderNumber[vdisk.OrderNumber] =
+ &FailDomains[vdisk.FailDomainOrderNumber].VDisks[vdisk.VDiskIdShort.VDisk];
+ }
+ }
+
+ template<typename TEvent>
+ void SetUpSubmitTimestamp(TEvent& event) {
+ TInstant now = TAppData::TimeProvider->Now();
+ auto& record = event.Record;
+ auto& msgQoS = *record.MutableMsgQoS();
+ auto& execTimeStats = *msgQoS.MutableExecTimeStats();
+ execTimeStats.SetSubmitTimestamp(now.GetValue());
+ }
+
+ void SetUpSubmitTimestamp(TEvBlobStorage::TEvVStatus& /*event*/) {}
+
+ template<typename TEvent>
+ TActorId Send(const IActor& actor, const TBlobStorageGroupInfo::TTopology& topology, std::unique_ptr<TEvent> event,
+ ui64 cookie, NWilson::TTraceId traceId, bool timeStatsEnabled) {
+ if (timeStatsEnabled) {
+ SetUpSubmitTimestamp(*event);
+ }
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(event->Record.GetVDiskID());
+ auto& queues = FailDomains[topology.GetFailDomainOrderNumber(vdiskId)].VDisks[vdiskId.VDisk].Queues;
+ TActorId queueId = queues.QueueForEvent(*event);
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_PROXY, "Send to queueId# " << queueId
+ << " " << TypeName<TEvent>() << "# " << event->ToString() << " cookie# " << cookie);
+ TActivationContext::Send(new IEventHandle(queueId, actor.SelfId(), event.release(), 0, cookie, nullptr, std::move(traceId)));
+ return queueId;
+ }
+
+ ui64 GetPredictedDelayNsByOrderNumber(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId) {
+ return DisksByOrderNumber[orderNumber]->Queues.PredictedDelayNsForQueueId(queueId);
+ }
+
+ template<typename TEvent>
+ ui64 GetPredictedDelayNsForEvent(const TEvent& event, const TBlobStorageGroupInfo::TTopology& topology) {
+ return GetPredictedDelayNsByOrderNumber(topology.GetOrderNumber(VDiskIDFromVDiskID(event.Record.GetVDiskID())),
+ TVDisk::TQueues::VDiskQueueId(event));
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ str << "{FailDomains# {";
+ for (ui32 i = 0; i < FailDomains.size(); ++i) {
+ str << (i ? " " : "") << i << ":{" << FailDomains[i].ToString() << "}";
+ }
+ str << "}}";
+ return str.Str();
+ }
+ };
+
+ struct TGroupSessions : TThrRefBase {
+ const ui8 AllQueuesMask =
+ 1 << NKikimrBlobStorage::EVDiskQueueId::PutTabletLog |
+ 1 << NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob |
+ 1 << NKikimrBlobStorage::EVDiskQueueId::PutUserData |
+ 1 << NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead |
+ 1 << NKikimrBlobStorage::EVDiskQueueId::GetFastRead |
1 << NKikimrBlobStorage::EVDiskQueueId::GetDiscover |
1 << NKikimrBlobStorage::EVDiskQueueId::GetLowRead;
-
- TIntrusivePtr<TGroupQueues> GroupQueues;
- TStackVec<ui8, TypicalDisksInGroup> ConnectedQueuesMask;
- TActorId MonActor;
- TActorId ProxyActor;
-
- TGroupSessions(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TBSProxyContextPtr& bspctx,
- const TActorId& monActor, const TActorId& proxyActor);
- void Poison();
- bool GoodToGo(const TBlobStorageGroupInfo::TTopology& topology, bool waitForAllVDisks);
- void QueueConnectUpdate(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId, bool connected);
- };
-
- struct TEvRequestProxySessionsState : TEventLocal<TEvRequestProxySessionsState, TEvBlobStorage::EvRequestProxySessionsState>
- {};
-
- struct TEvProxySessionsState : TEventLocal<TEvProxySessionsState, TEvBlobStorage::EvProxySessionsState> {
- TIntrusivePtr<TGroupQueues> GroupQueues;
-
- TEvProxySessionsState(const TIntrusivePtr<TGroupQueues>& groupQueues)
- : GroupQueues(groupQueues)
- {}
- };
-
-} // NKikimr
+
+ TIntrusivePtr<TGroupQueues> GroupQueues;
+ TStackVec<ui8, TypicalDisksInGroup> ConnectedQueuesMask;
+ TActorId MonActor;
+ TActorId ProxyActor;
+
+ TGroupSessions(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TBSProxyContextPtr& bspctx,
+ const TActorId& monActor, const TActorId& proxyActor);
+ void Poison();
+ bool GoodToGo(const TBlobStorageGroupInfo::TTopology& topology, bool waitForAllVDisks);
+ void QueueConnectUpdate(ui32 orderNumber, NKikimrBlobStorage::EVDiskQueueId queueId, bool connected);
+ };
+
+ struct TEvRequestProxySessionsState : TEventLocal<TEvRequestProxySessionsState, TEvBlobStorage::EvRequestProxySessionsState>
+ {};
+
+ struct TEvProxySessionsState : TEventLocal<TEvProxySessionsState, TEvBlobStorage::EvProxySessionsState> {
+ TIntrusivePtr<TGroupQueues> GroupQueues;
+
+ TEvProxySessionsState(const TIntrusivePtr<TGroupQueues>& groupQueues)
+ : GroupQueues(groupQueues)
+ {}
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/log_acc.h b/ydb/core/blobstorage/dsproxy/log_acc.h
index a5938d5fdf4..fe801297da6 100644
--- a/ydb/core/blobstorage/dsproxy/log_acc.h
+++ b/ydb/core/blobstorage/dsproxy/log_acc.h
@@ -1,219 +1,219 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- struct TLogAccumulator {
- struct TLogLine {
- NLog::EPriority Priority;
- NLog::EComponent Component;
- TString Formatted;
-
- TLogLine(NLog::EPriority priority, NLog::EComponent component, TString formatted)
- : Priority(priority)
- , Component(component)
- , Formatted(formatted)
- {}
-
- };
-
- bool IsEnabled;
- bool IsLogEnabled;
- TInstant CreatedAt;
- TDeque<TLogLine> Lines;
-
- TLogAccumulator()
- : IsEnabled(false)
- , IsLogEnabled(true)
- , CreatedAt(TAppData::TimeProvider->Now())
- {}
-
- TLogAccumulator(bool isEnabled)
- : IsEnabled(isEnabled)
- , IsLogEnabled(true)
- , CreatedAt(TAppData::TimeProvider->Now())
- {}
-
- void Clear() {
- CreatedAt = TAppData::TimeProvider->Now();
- Lines.clear();
- }
-
- void Add(NLog::EPriority priority, NLog::EComponent component, TString formatted) {
- Lines.push_back(TLogLine(priority, component, formatted));
- }
-
- void UnleashUponLogger() {
- NLog::TSettings * const loggerSettings = TlsActivationContext->ExecutorThread.ActorSystem->LoggerSettings();
- if (!loggerSettings) {
- return;
- }
- TActorId logger = loggerSettings->LoggerActorId;
- for (auto it = Lines.begin(); it != Lines.end(); ++it) {
- TActivationContext::Send(new IEventHandle(logger, TActorId(), new ::NActors::NLog::TEvLog(it->Priority, it->Component, it->Formatted)));
- }
- Lines.clear();
- }
-
- ui64 LifeMs() {
- return (TAppData::TimeProvider->Now() - CreatedAt).MilliSeconds();
- }
-
- void Output(IOutputStream &out) {
- for (auto &line: Lines) {
- const auto prio = NActors::NLog::EPrio(line.Priority);
- out << ::NActors::NLog::PriorityToString(prio) << ": " << line.Formatted << Endl;
- }
- }
- };
-
- struct TLogContext {
- const TString RequestPrefix;
- const NKikimrServices::EServiceKikimr LogComponent;
- TLogAccumulator LogAcc;
-
- TLogContext(NKikimrServices::EServiceKikimr logComponent, bool logAccEnabled)
- : RequestPrefix(Sprintf("[%016" PRIx64 "]", TAppData::RandomProvider->GenRand64()))
- , LogComponent(logComponent)
- , LogAcc(logAccEnabled)
- {}
- };
-
-#define ENABLE_LOG_ACCUMULATION 0
-#define ENABLE_ALTERNATIVE_LOG_ACCUMULATION 1
-
-#if ENABLE_LOG_ACCUMULATION
- #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
- do { \
- ::NActors::NLog::TSettings *mSettings = \
- (::NActors::NLog::TSettings*)(TActivationContext::LoggerSettings()); \
- if (mSettings) { \
- ::NActors::NLog::EPriority mPriority = (::NActors::NLog::EPriority)(priority); \
- ::NActors::NLog::EComponent mComponent = (::NActors::NLog::EComponent)(component); \
- if (mSettings->Satisfies(mPriority, mComponent, 0ul)) { \
- if (isRelease) { \
- (accumulator).UnleashUponLogger(); \
- } \
- TStringBuilder logStringBuilder; \
- logStringBuilder << stream; \
- TActivationContext::Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), \
- new ::NActors::NLog::TEvLog(mPriority, mComponent, (TString)logStringBuilder)); \
- } else { \
- if (!(isRelease)) { \
- TStringBuilder logStringBuilder; \
- logStringBuilder << "(R) " << (accumulator).LifeMs() << " "; \
- logStringBuilder << stream; \
- (accumulator).Add(mPriority, mComponent, (TString)logStringBuilder); \
- }\
- }\
- } \
- } while (0)
-#elif ENABLE_ALTERNATIVE_LOG_ACCUMULATION
- #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
- do { \
- Y_UNUSED(isRelease); \
- if ((accumulator).IsEnabled) { \
- ::NActors::NLog::EPriority mPriorityAcc = (::NActors::NLog::EPriority)(priority); \
- ::NActors::NLog::EComponent mComponentAcc = (::NActors::NLog::EComponent)(component); \
- TStringBuilder logStringBuilderAcc2; \
- logStringBuilderAcc2 << stream; \
- TStringBuilder logStringBuilderAcc; \
- logStringBuilderAcc << "(R) " << (accumulator).LifeMs() << " "; \
- logStringBuilderAcc << (TString)logStringBuilderAcc2; \
- (accumulator).Add(mPriorityAcc, mComponentAcc, (TString)logStringBuilderAcc); \
- if ((accumulator).IsLogEnabled) { \
- LOG_LOG_S(*TlsActivationContext, mPriorityAcc, mComponentAcc, (TString)logStringBuilderAcc2); \
- } \
- } else { \
- if ((accumulator).IsLogEnabled) { \
- LOG_LOG_S(*TlsActivationContext, priority, (component), stream); \
- } \
- } \
- } while (0)
-#else
- #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
- do { \
- LOG_LOG_S(*TlsActivationContext, priority, component, stream); \
- } while (0)
-#endif
-
-#define A_LOG_LOG_SX(logCtx, isRelease, priority, marker, stream) \
- do { \
- auto& lc = (logCtx); \
- A_LOG_LOG_S_IMPL(isRelease, lc.LogAcc, priority, lc.LogComponent, \
- lc.RequestPrefix << " " << stream << " Marker# " << marker); \
- } while (false)
-
-#define A_LOG_LOG_S(isRelease, priority, marker, stream) \
- A_LOG_LOG_SX(LogCtx, isRelease, priority, marker, stream)
-
-#define A_LOG_EMERG_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_EMERG, marker, stream)
-#define A_LOG_ALERT_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_ALERT, marker, stream)
-#define A_LOG_CRIT_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_CRIT, marker, stream)
-#define A_LOG_ERROR_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_ERROR, marker, stream)
-#define A_LOG_WARN_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_WARN, marker, stream)
-#define A_LOG_NOTICE_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_NOTICE, marker, stream)
-#define A_LOG_INFO_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_INFO, marker, stream)
-#define A_LOG_DEBUG_S(marker, stream) \
- A_LOG_LOG_S(false, NActors::NLog::PRI_DEBUG, marker, stream)
-
-#define R_LOG_EMERG_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_EMERG, marker, stream)
-#define R_LOG_ALERT_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_ALERT, marker, stream)
-#define R_LOG_CRIT_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_CRIT, marker, stream)
-#define R_LOG_ERROR_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_ERROR, marker, stream)
-#define R_LOG_WARN_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_WARN, marker, stream)
-#define R_LOG_NOTICE_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_NOTICE, marker, stream)
-#define R_LOG_INFO_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_INFO, marker, stream)
-#define R_LOG_DEBUG_S(marker, stream) \
- A_LOG_LOG_S(true, NActors::NLog::PRI_DEBUG, marker, stream)
-
-#define A_LOG_EMERG_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_EMERG, marker, stream)
-#define A_LOG_ALERT_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_ALERT, marker, stream)
-#define A_LOG_CRIT_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_CRIT, marker, stream)
-#define A_LOG_ERROR_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_ERROR, marker, stream)
-#define A_LOG_WARN_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_WARN, marker, stream)
-#define A_LOG_NOTICE_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_NOTICE, marker, stream)
-#define A_LOG_INFO_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_INFO, marker, stream)
-#define A_LOG_DEBUG_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_DEBUG, marker, stream)
-
-#define R_LOG_EMERG_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_EMERG, marker, stream)
-#define R_LOG_ALERT_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_ALERT, marker, stream)
-#define R_LOG_CRIT_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_CRIT, marker, stream)
-#define R_LOG_ERROR_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_ERROR, marker, stream)
-#define R_LOG_WARN_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_WARN, marker, stream)
-#define R_LOG_NOTICE_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_NOTICE, marker, stream)
-#define R_LOG_INFO_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_INFO, marker, stream)
-#define R_LOG_DEBUG_SX(logCtx, marker, stream) \
- A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_DEBUG, marker, stream)
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ struct TLogAccumulator {
+ struct TLogLine {
+ NLog::EPriority Priority;
+ NLog::EComponent Component;
+ TString Formatted;
+
+ TLogLine(NLog::EPriority priority, NLog::EComponent component, TString formatted)
+ : Priority(priority)
+ , Component(component)
+ , Formatted(formatted)
+ {}
+
+ };
+
+ bool IsEnabled;
+ bool IsLogEnabled;
+ TInstant CreatedAt;
+ TDeque<TLogLine> Lines;
+
+ TLogAccumulator()
+ : IsEnabled(false)
+ , IsLogEnabled(true)
+ , CreatedAt(TAppData::TimeProvider->Now())
+ {}
+
+ TLogAccumulator(bool isEnabled)
+ : IsEnabled(isEnabled)
+ , IsLogEnabled(true)
+ , CreatedAt(TAppData::TimeProvider->Now())
+ {}
+
+ void Clear() {
+ CreatedAt = TAppData::TimeProvider->Now();
+ Lines.clear();
+ }
+
+ void Add(NLog::EPriority priority, NLog::EComponent component, TString formatted) {
+ Lines.push_back(TLogLine(priority, component, formatted));
+ }
+
+ void UnleashUponLogger() {
+ NLog::TSettings * const loggerSettings = TlsActivationContext->ExecutorThread.ActorSystem->LoggerSettings();
+ if (!loggerSettings) {
+ return;
+ }
+ TActorId logger = loggerSettings->LoggerActorId;
+ for (auto it = Lines.begin(); it != Lines.end(); ++it) {
+ TActivationContext::Send(new IEventHandle(logger, TActorId(), new ::NActors::NLog::TEvLog(it->Priority, it->Component, it->Formatted)));
+ }
+ Lines.clear();
+ }
+
+ ui64 LifeMs() {
+ return (TAppData::TimeProvider->Now() - CreatedAt).MilliSeconds();
+ }
+
+ void Output(IOutputStream &out) {
+ for (auto &line: Lines) {
+ const auto prio = NActors::NLog::EPrio(line.Priority);
+ out << ::NActors::NLog::PriorityToString(prio) << ": " << line.Formatted << Endl;
+ }
+ }
+ };
+
+ struct TLogContext {
+ const TString RequestPrefix;
+ const NKikimrServices::EServiceKikimr LogComponent;
+ TLogAccumulator LogAcc;
+
+ TLogContext(NKikimrServices::EServiceKikimr logComponent, bool logAccEnabled)
+ : RequestPrefix(Sprintf("[%016" PRIx64 "]", TAppData::RandomProvider->GenRand64()))
+ , LogComponent(logComponent)
+ , LogAcc(logAccEnabled)
+ {}
+ };
+
+#define ENABLE_LOG_ACCUMULATION 0
+#define ENABLE_ALTERNATIVE_LOG_ACCUMULATION 1
+
+#if ENABLE_LOG_ACCUMULATION
+ #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
+ do { \
+ ::NActors::NLog::TSettings *mSettings = \
+ (::NActors::NLog::TSettings*)(TActivationContext::LoggerSettings()); \
+ if (mSettings) { \
+ ::NActors::NLog::EPriority mPriority = (::NActors::NLog::EPriority)(priority); \
+ ::NActors::NLog::EComponent mComponent = (::NActors::NLog::EComponent)(component); \
+ if (mSettings->Satisfies(mPriority, mComponent, 0ul)) { \
+ if (isRelease) { \
+ (accumulator).UnleashUponLogger(); \
+ } \
+ TStringBuilder logStringBuilder; \
+ logStringBuilder << stream; \
+ TActivationContext::Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), \
+ new ::NActors::NLog::TEvLog(mPriority, mComponent, (TString)logStringBuilder)); \
+ } else { \
+ if (!(isRelease)) { \
+ TStringBuilder logStringBuilder; \
+ logStringBuilder << "(R) " << (accumulator).LifeMs() << " "; \
+ logStringBuilder << stream; \
+ (accumulator).Add(mPriority, mComponent, (TString)logStringBuilder); \
+ }\
+ }\
+ } \
+ } while (0)
+#elif ENABLE_ALTERNATIVE_LOG_ACCUMULATION
+ #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
+ do { \
+ Y_UNUSED(isRelease); \
+ if ((accumulator).IsEnabled) { \
+ ::NActors::NLog::EPriority mPriorityAcc = (::NActors::NLog::EPriority)(priority); \
+ ::NActors::NLog::EComponent mComponentAcc = (::NActors::NLog::EComponent)(component); \
+ TStringBuilder logStringBuilderAcc2; \
+ logStringBuilderAcc2 << stream; \
+ TStringBuilder logStringBuilderAcc; \
+ logStringBuilderAcc << "(R) " << (accumulator).LifeMs() << " "; \
+ logStringBuilderAcc << (TString)logStringBuilderAcc2; \
+ (accumulator).Add(mPriorityAcc, mComponentAcc, (TString)logStringBuilderAcc); \
+ if ((accumulator).IsLogEnabled) { \
+ LOG_LOG_S(*TlsActivationContext, mPriorityAcc, mComponentAcc, (TString)logStringBuilderAcc2); \
+ } \
+ } else { \
+ if ((accumulator).IsLogEnabled) { \
+ LOG_LOG_S(*TlsActivationContext, priority, (component), stream); \
+ } \
+ } \
+ } while (0)
+#else
+ #define A_LOG_LOG_S_IMPL(isRelease, accumulator, priority, component, stream) \
+ do { \
+ LOG_LOG_S(*TlsActivationContext, priority, component, stream); \
+ } while (0)
+#endif
+
+#define A_LOG_LOG_SX(logCtx, isRelease, priority, marker, stream) \
+ do { \
+ auto& lc = (logCtx); \
+ A_LOG_LOG_S_IMPL(isRelease, lc.LogAcc, priority, lc.LogComponent, \
+ lc.RequestPrefix << " " << stream << " Marker# " << marker); \
+ } while (false)
+
+#define A_LOG_LOG_S(isRelease, priority, marker, stream) \
+ A_LOG_LOG_SX(LogCtx, isRelease, priority, marker, stream)
+
+#define A_LOG_EMERG_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_EMERG, marker, stream)
+#define A_LOG_ALERT_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_ALERT, marker, stream)
+#define A_LOG_CRIT_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_CRIT, marker, stream)
+#define A_LOG_ERROR_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_ERROR, marker, stream)
+#define A_LOG_WARN_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_WARN, marker, stream)
+#define A_LOG_NOTICE_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_NOTICE, marker, stream)
+#define A_LOG_INFO_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_INFO, marker, stream)
+#define A_LOG_DEBUG_S(marker, stream) \
+ A_LOG_LOG_S(false, NActors::NLog::PRI_DEBUG, marker, stream)
+
+#define R_LOG_EMERG_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_EMERG, marker, stream)
+#define R_LOG_ALERT_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_ALERT, marker, stream)
+#define R_LOG_CRIT_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_CRIT, marker, stream)
+#define R_LOG_ERROR_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_ERROR, marker, stream)
+#define R_LOG_WARN_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_WARN, marker, stream)
+#define R_LOG_NOTICE_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_NOTICE, marker, stream)
+#define R_LOG_INFO_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_INFO, marker, stream)
+#define R_LOG_DEBUG_S(marker, stream) \
+ A_LOG_LOG_S(true, NActors::NLog::PRI_DEBUG, marker, stream)
+
+#define A_LOG_EMERG_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_EMERG, marker, stream)
+#define A_LOG_ALERT_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_ALERT, marker, stream)
+#define A_LOG_CRIT_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_CRIT, marker, stream)
+#define A_LOG_ERROR_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_ERROR, marker, stream)
+#define A_LOG_WARN_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_WARN, marker, stream)
+#define A_LOG_NOTICE_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_NOTICE, marker, stream)
+#define A_LOG_INFO_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_INFO, marker, stream)
+#define A_LOG_DEBUG_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, false, NActors::NLog::PRI_DEBUG, marker, stream)
+
+#define R_LOG_EMERG_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_EMERG, marker, stream)
+#define R_LOG_ALERT_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_ALERT, marker, stream)
+#define R_LOG_CRIT_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_CRIT, marker, stream)
+#define R_LOG_ERROR_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_ERROR, marker, stream)
+#define R_LOG_WARN_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_WARN, marker, stream)
+#define R_LOG_NOTICE_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_NOTICE, marker, stream)
+#define R_LOG_INFO_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_INFO, marker, stream)
+#define R_LOG_DEBUG_SX(logCtx, marker, stream) \
+ A_LOG_LOG_SX(logCtx, true, NActors::NLog::PRI_DEBUG, marker, stream)
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/mock/defs.h b/ydb/core/blobstorage/dsproxy/mock/defs.h
index d067528eb9e..49602b0fb9e 100644
--- a/ydb/core/blobstorage/dsproxy/mock/defs.h
+++ b/ydb/core/blobstorage/dsproxy/mock/defs.h
@@ -1,3 +1,3 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/defs.h>
diff --git a/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.cpp b/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.cpp
index c0e6d8f15c2..53618646314 100644
--- a/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.cpp
+++ b/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.cpp
@@ -1,95 +1,95 @@
-#include "dsproxy_mock.h"
+#include "dsproxy_mock.h"
#include "model.h"
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/util/stlog.h>
-
-namespace NKikimr {
-
- namespace {
-
- class TBlobStorageGroupProxyMockActor
- : public TActor<TBlobStorageGroupProxyMockActor>
- {
- TIntrusivePtr<NFake::TProxyDS> Model;
-
- void Handle(TEvBlobStorage::TEvPut::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM01, "TEvPut", (Msg, ev->Get()->ToString()));
+
+namespace NKikimr {
+
+ namespace {
+
+ class TBlobStorageGroupProxyMockActor
+ : public TActor<TBlobStorageGroupProxyMockActor>
+ {
+ TIntrusivePtr<NFake::TProxyDS> Model;
+
+ void Handle(TEvBlobStorage::TEvPut::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM01, "TEvPut", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()),0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvGet::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM02, "TEvGet", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvGet::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM02, "TEvGet", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()), 0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvBlock::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM03, "TEvBlock", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvBlock::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM03, "TEvBlock", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()), 0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvDiscover::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM04, "TEvDiscover", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvDiscover::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM04, "TEvDiscover", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()), 0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvRange::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM05, "TEvRange", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvRange::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM05, "TEvRange", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()), 0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvCollectGarbage::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM06, "TEvCollectGarbage", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvCollectGarbage::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM06, "TEvCollectGarbage", (Msg, ev->Get()->ToString()));
Send(ev->Sender, Model->Handle(ev->Get()), 0, ev->Cookie);
- }
-
- void Handle(TEvBlobStorage::TEvStatus::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM07, "TEvStatus", (Msg, ev->Get()->ToString()));
+ }
+
+ void Handle(TEvBlobStorage::TEvStatus::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM07, "TEvStatus", (Msg, ev->Get()->ToString()));
Send(ev->Sender, new TEvBlobStorage::TEvStatusResult(NKikimrProto::OK, Model->GetStorageStatusFlags()), 0,
- ev->Cookie);
- }
-
- void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_PROXY, BSPM08, "TEvPoisonPill");
+ ev->Cookie);
+ }
+
+ void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_PROXY, BSPM08, "TEvPoisonPill");
Send(ev->Sender, new TEvents::TEvPoisonTaken);
- PassAway();
+ PassAway();
+ }
+
+ STATEFN(StateFunc) {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ hFunc(TEvBlobStorage::TEvPut, Handle);
+ hFunc(TEvBlobStorage::TEvGet, Handle);
+ hFunc(TEvBlobStorage::TEvBlock, Handle);
+ hFunc(TEvBlobStorage::TEvDiscover, Handle);
+ hFunc(TEvBlobStorage::TEvRange, Handle);
+ hFunc(TEvBlobStorage::TEvCollectGarbage, Handle);
+ hFunc(TEvBlobStorage::TEvStatus, Handle);
+
+ hFunc(TEvents::TEvPoisonPill, HandlePoison);
+
+ default:
+ Y_FAIL("unexpected event 0x%08" PRIx32, type);
+ }
+ }
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_PROXY_ACTOR;
}
- STATEFN(StateFunc) {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- hFunc(TEvBlobStorage::TEvPut, Handle);
- hFunc(TEvBlobStorage::TEvGet, Handle);
- hFunc(TEvBlobStorage::TEvBlock, Handle);
- hFunc(TEvBlobStorage::TEvDiscover, Handle);
- hFunc(TEvBlobStorage::TEvRange, Handle);
- hFunc(TEvBlobStorage::TEvCollectGarbage, Handle);
- hFunc(TEvBlobStorage::TEvStatus, Handle);
-
- hFunc(TEvents::TEvPoisonPill, HandlePoison);
-
- default:
- Y_FAIL("unexpected event 0x%08" PRIx32, type);
- }
- }
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_PROXY_ACTOR;
- }
-
- TBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model)
- : TActor(&TBlobStorageGroupProxyMockActor::StateFunc)
- , Model(model ? std::move(model) : MakeIntrusive<NFake::TProxyDS>())
- {}
- };
- } // anon
-
- IActor *CreateBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model) {
- return new TBlobStorageGroupProxyMockActor(std::move(model));
- }
-
- IActor *CreateBlobStorageGroupProxyMockActor() {
- return new TBlobStorageGroupProxyMockActor(nullptr);
- }
-
-} // NKikimr
+ TBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model)
+ : TActor(&TBlobStorageGroupProxyMockActor::StateFunc)
+ , Model(model ? std::move(model) : MakeIntrusive<NFake::TProxyDS>())
+ {}
+ };
+ } // anon
+
+ IActor *CreateBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model) {
+ return new TBlobStorageGroupProxyMockActor(std::move(model));
+ }
+
+ IActor *CreateBlobStorageGroupProxyMockActor() {
+ return new TBlobStorageGroupProxyMockActor(nullptr);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h b/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h
index 59daaba5dce..74340f43953 100644
--- a/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h
+++ b/ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- namespace NFake {
- class TProxyDS;
- } // NFake
-
- IActor *CreateBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model);
- IActor *CreateBlobStorageGroupProxyMockActor();
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ namespace NFake {
+ class TProxyDS;
+ } // NFake
+
+ IActor *CreateBlobStorageGroupProxyMockActor(TIntrusivePtr<NFake::TProxyDS> model);
+ IActor *CreateBlobStorageGroupProxyMockActor();
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/mock/model.h b/ydb/core/blobstorage/dsproxy/mock/model.h
index 6161a6b8573..babf0035625 100644
--- a/ydb/core/blobstorage/dsproxy/mock/model.h
+++ b/ydb/core/blobstorage/dsproxy/mock/model.h
@@ -5,7 +5,7 @@
namespace NKikimr {
namespace NFake {
- class TProxyDS : public TThrRefBase {
+ class TProxyDS : public TThrRefBase {
using TTabletId = ui64;
using TChannel = ui8;
using TGeneration = ui32;
@@ -88,7 +88,7 @@ namespace NFake {
TEvBlobStorage::TEvGetResult* Handle(TEvBlobStorage::TEvGet *msg) {
// prepare result structure holding the returned data
- auto result = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, msg->QuerySize, 0u);
+ auto result = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, msg->QuerySize, 0u);
// traverse against requested blobs and process them
for (ui32 i = 0; i < msg->QuerySize; ++i) {
@@ -127,7 +127,7 @@ namespace NFake {
}
}
- return result.release();
+ return result.release();
}
TEvBlobStorage::TEvBlockResult* Handle(TEvBlobStorage::TEvBlock *msg) {
@@ -154,7 +154,7 @@ namespace NFake {
}
}
- std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result;
+ std::unique_ptr<TEvBlobStorage::TEvDiscoverResult> result;
TLogoBlobID id(msg->TabletId, Max<ui32>(), Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
auto it = Blobs.upper_bound(id);
@@ -168,17 +168,17 @@ namespace NFake {
buffer = it->second.Buffer;
}
- result = std::make_unique<TEvBlobStorage::TEvDiscoverResult>(lastBlobId, msg->MinGeneration, buffer,
+ result = std::make_unique<TEvBlobStorage::TEvDiscoverResult>(lastBlobId, msg->MinGeneration, buffer,
blockedGeneration);
}
}
if (!result) {
- result = std::make_unique<TEvBlobStorage::TEvDiscoverResult>(NKikimrProto::NODATA, msg->MinGeneration,
+ result = std::make_unique<TEvBlobStorage::TEvDiscoverResult>(NKikimrProto::NODATA, msg->MinGeneration,
blockedGeneration);
}
- return result.release();
+ return result.release();
}
TEvBlobStorage::TEvRangeResult* Handle(TEvBlobStorage::TEvRange *msg) {
@@ -189,7 +189,7 @@ namespace NFake {
Y_VERIFY(from.Channel() == to.Channel());
Y_VERIFY(from.TabletID() == msg->TabletId);
- auto result = std::make_unique<TEvBlobStorage::TEvRangeResult>(NKikimrProto::OK, from, to, 0u);
+ auto result = std::make_unique<TEvBlobStorage::TEvRangeResult>(NKikimrProto::OK, from, to, 0u);
auto process = [&](const TLogoBlobID& id, const TString& buffer) {
result->Responses.emplace_back(id, buffer);
@@ -212,12 +212,12 @@ namespace NFake {
}
}
- return result.release();
+ return result.release();
}
TEvBlobStorage::TEvCollectGarbageResult* Handle(TEvBlobStorage::TEvCollectGarbage *msg) {
- if (IsBlocked(msg->TabletId, msg->RecordGeneration) && (msg->CollectGeneration != Max<ui32>() ||
- msg->CollectStep != Max<ui32>() || Blocks.at(msg->TabletId) != Max<ui32>())) {
+ if (IsBlocked(msg->TabletId, msg->RecordGeneration) && (msg->CollectGeneration != Max<ui32>() ||
+ msg->CollectStep != Max<ui32>() || Blocks.at(msg->TabletId) != Max<ui32>())) {
return new TEvBlobStorage::TEvCollectGarbageResult(NKikimrProto::BLOCKED,
msg->TabletId, msg->RecordGeneration, msg->PerGenerationCounter, msg->Channel);
}
diff --git a/ydb/core/blobstorage/dsproxy/mock/ya.make b/ydb/core/blobstorage/dsproxy/mock/ya.make
index f71eed247c6..cdf4832adfb 100644
--- a/ydb/core/blobstorage/dsproxy/mock/ya.make
+++ b/ydb/core/blobstorage/dsproxy/mock/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
OWNER(
alexvru
@@ -17,4 +17,4 @@ SRCS(
dsproxy_mock.h
)
-END()
+END()
diff --git a/ydb/core/blobstorage/dsproxy/ut/defs.h b/ydb/core/blobstorage/dsproxy/ut/defs.h
index 8f5d40da4bb..73b2884b5de 100644
--- a/ydb/core/blobstorage/dsproxy/ut/defs.h
+++ b/ydb/core/blobstorage/dsproxy/ut/defs.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/dsproxy/defs.h>
#include <util/stream/null.h>
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_counters_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_counters_ut.cpp
index bb64b2711ae..644315494d3 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_counters_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_counters_ut.cpp
@@ -60,7 +60,7 @@ Y_UNIT_TEST(PutGeneratedSubrequestBytes) {
};
TEvBlobStorage::TEvPut::TPtr put = testState.CreatePutRequest(blobs[0], tactic, handleClass);
- runtime.Register(env.CreatePutRequestActor(put).release());
+ runtime.Register(env.CreatePutRequestActor(put).release());
TMap<TPartLocation, NKikimrProto::EReplyStatus> specialStatuses;
for (ui64 part = 1; part <= env.Info->Type.TotalPartCount(); ++part) {
@@ -114,7 +114,7 @@ Y_UNIT_TEST(MultiPutGeneratedSubrequestBytes) {
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> batched;
testState.CreatePutRequests(blobs, std::back_inserter(batched), tactic, handleClass);
- runtime.Register(env.CreatePutRequestActor(batched, tactic, handleClass).release());
+ runtime.Register(env.CreatePutRequestActor(batched, tactic, handleClass).release());
TMap<TPartLocation, NKikimrProto::EReplyStatus> specialStatuses;
for (ui64 part = 1; part <= env.Info->Type.TotalPartCount(); ++part) {
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_env_mock_ut.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_env_mock_ut.h
index 0f2350daf85..8488758fbc2 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_env_mock_ut.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_env_mock_ut.h
@@ -79,8 +79,8 @@ struct TDSProxyEnv {
TIntrusivePtr<TStoragePoolCounters> storagePoolCounters = perPoolCounters.GetPoolCounters("pool_name");
TControlWrapper enablePutBatching(DefaultEnablePutBatching, false, true);
TControlWrapper enableVPatch(DefaultEnableVPatch, false, true);
- IActor *dsproxy = CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(Info), true, nodeMon,
- std::move(storagePoolCounters), enablePutBatching, enableVPatch);
+ IActor *dsproxy = CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(Info), true, nodeMon,
+ std::move(storagePoolCounters), enablePutBatching, enableVPatch);
TActorId actorId = runtime.Register(dsproxy, nodeIndex);
runtime.RegisterService(RealProxyActorId, actorId, nodeIndex);
@@ -99,33 +99,33 @@ struct TDSProxyEnv {
Info = new TBlobStorageGroupInfo(Info, TVDiskID(Info->GroupID, generation, 0, 0, 0), VDisks[0]);
}
- std::unique_ptr<IActor> CreatePutRequestActor(TEvBlobStorage::TEvPut::TPtr &ev) {
+ std::unique_ptr<IActor> CreatePutRequestActor(TEvBlobStorage::TEvPut::TPtr &ev) {
TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(ev->Get()->HandleClass);
- return std::unique_ptr<IActor>(CreateBlobStorageGroupPutRequest(Info, GroupQueues, ev->Sender, Mon, ev->Get(),
+ return std::unique_ptr<IActor>(CreateBlobStorageGroupPutRequest(Info, GroupQueues, ev->Sender, Mon, ev->Get(),
ev->Cookie, std::move(ev->TraceId), Mon->TimeStats.IsEnabled(), PerDiskStatsPtr, kind,
TInstant::Now(), StoragePoolCounters, false));
}
- std::unique_ptr<IActor> CreatePutRequestActor(TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &batched,
+ std::unique_ptr<IActor> CreatePutRequestActor(TBatchedVec<TEvBlobStorage::TEvPut::TPtr> &batched,
TEvBlobStorage::TEvPut::ETactic tactic, NKikimrBlobStorage::EPutHandleClass handleClass)
{
TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(handleClass);
- return std::unique_ptr<IActor>(CreateBlobStorageGroupPutRequest(Info, GroupQueues,
+ return std::unique_ptr<IActor>(CreateBlobStorageGroupPutRequest(Info, GroupQueues,
Mon, batched, Mon->TimeStats.IsEnabled(), PerDiskStatsPtr, kind,TInstant::Now(),
StoragePoolCounters, handleClass, tactic, false));
}
- std::unique_ptr<IActor> CreateGetRequestActor(TEvBlobStorage::TEvGet::TPtr &ev,
+ std::unique_ptr<IActor> CreateGetRequestActor(TEvBlobStorage::TEvGet::TPtr &ev,
NKikimrBlobStorage::EPutHandleClass handleClass, bool withMultiPut)
{
TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(handleClass);
- return std::unique_ptr<IActor>(CreateBlobStorageGroupGetRequest(Info, GroupQueues, ev->Sender, Mon,
+ return std::unique_ptr<IActor>(CreateBlobStorageGroupGetRequest(Info, GroupQueues, ev->Sender, Mon,
ev->Get(), ev->Cookie, std::move(ev->TraceId), TNodeLayoutInfoPtr(NodeLayoutInfo),
kind, TInstant::Now(), StoragePoolCounters, withMultiPut));
}
- std::unique_ptr<IActor> CreatePatchRequestActor(TEvBlobStorage::TEvPatch::TPtr &ev, bool useVPatch = false) {
- return std::unique_ptr<IActor>(CreateBlobStorageGroupPatchRequest(Info, GroupQueues, ev->Sender, Mon,
+ std::unique_ptr<IActor> CreatePatchRequestActor(TEvBlobStorage::TEvPatch::TPtr &ev, bool useVPatch = false) {
+ return std::unique_ptr<IActor>(CreateBlobStorageGroupPatchRequest(Info, GroupQueues, ev->Sender, Mon,
ev->Get(), ev->Cookie, std::move(ev->TraceId), TInstant::Now(), StoragePoolCounters,
FakeProxyActorId, useVPatch));
}
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut.cpp
index 6a8fbff0e28..e0f48ab4935 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut.cpp
@@ -1,72 +1,72 @@
-#include "dsproxy_fault_tolerance_ut_runtime.h"
-#include "dsproxy_fault_tolerance_ut_get.h"
-#include "dsproxy_fault_tolerance_ut_get_hardened.h"
-#include "dsproxy_fault_tolerance_ut_discover.h"
-#include "dsproxy_fault_tolerance_ut_range.h"
-#include "dsproxy_fault_tolerance_ut_put.h"
-
-using namespace NActors;
-using namespace NKikimr;
-
-template<typename T>
+#include "dsproxy_fault_tolerance_ut_runtime.h"
+#include "dsproxy_fault_tolerance_ut_get.h"
+#include "dsproxy_fault_tolerance_ut_get_hardened.h"
+#include "dsproxy_fault_tolerance_ut_discover.h"
+#include "dsproxy_fault_tolerance_ut_range.h"
+#include "dsproxy_fault_tolerance_ut_put.h"
+
+using namespace NActors;
+using namespace NKikimr;
+
+template<typename T>
void RunTest(TBlobStorageGroupType groupType, bool minimum = false, ui32 testPartCount = 1, ui32 testPartIdx = 0) {
- ui32 numVDisks;
- ui32 numFailDomains;
- ui32 numFailRealms;
-
- switch (groupType.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- numVDisks = 1;
- numFailDomains = minimum ? 3 : 4;
- numFailRealms = 3;
- break;
-
- default:
- numVDisks = 1;
- numFailDomains = groupType.BlobSubgroupSize() + (minimum ? 0 : 1);
- numFailRealms = 1;
- break;
- }
-
- TFaultToleranceTestRuntime runtime;
- runtime.Setup(groupType, numFailDomains, numVDisks, numFailRealms);
-
- TAutoEvent finishEvent;
- std::exception_ptr eptr;
+ ui32 numVDisks;
+ ui32 numFailDomains;
+ ui32 numFailRealms;
+
+ switch (groupType.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ numVDisks = 1;
+ numFailDomains = minimum ? 3 : 4;
+ numFailRealms = 3;
+ break;
+
+ default:
+ numVDisks = 1;
+ numFailDomains = groupType.BlobSubgroupSize() + (minimum ? 0 : 1);
+ numFailRealms = 1;
+ break;
+ }
+
+ TFaultToleranceTestRuntime runtime;
+ runtime.Setup(groupType, numFailDomains, numVDisks, numFailRealms);
+
+ TAutoEvent finishEvent;
+ std::exception_ptr eptr;
auto test = MakeHolder<T>(&finishEvent, &eptr, NUnitTest::NPrivate::GetCurrentTest(), runtime,
testPartCount, testPartIdx);
runtime.ActorSystem->Register(new TActorCoro(std::move(test)), TMailboxType::Simple, 0, {});
- finishEvent.WaitI();
- runtime.Finish();
- if (eptr) {
- std::rethrow_exception(eptr);
- }
-}
-
+ finishEvent.WaitI();
+ runtime.Finish();
+ if (eptr) {
+ std::rethrow_exception(eptr);
+ }
+}
+
Y_UNIT_TEST_SUITE(TBsProxyFaultToleranceTest) {
-
-#define FAULT_TOLERANCE_TEST(ERASURE, T) \
+
+#define FAULT_TOLERANCE_TEST(ERASURE, T) \
Y_UNIT_TEST(Check##T##ERASURE) { \
- RunTest<T>(TBlobStorageGroupType::ERASURE); \
- }
-
-#define ERASURE_TEST(ERASURE) \
- FAULT_TOLERANCE_TEST(ERASURE, TGetWithRecoverFaultToleranceTest) \
- FAULT_TOLERANCE_TEST(ERASURE, TRangeFaultToleranceTest) \
- FAULT_TOLERANCE_TEST(ERASURE, TDiscoverFaultToleranceTest) \
- FAULT_TOLERANCE_TEST(ERASURE, TPutFaultToleranceTest)
-
+ RunTest<T>(TBlobStorageGroupType::ERASURE); \
+ }
+
+#define ERASURE_TEST(ERASURE) \
+ FAULT_TOLERANCE_TEST(ERASURE, TGetWithRecoverFaultToleranceTest) \
+ FAULT_TOLERANCE_TEST(ERASURE, TRangeFaultToleranceTest) \
+ FAULT_TOLERANCE_TEST(ERASURE, TDiscoverFaultToleranceTest) \
+ FAULT_TOLERANCE_TEST(ERASURE, TPutFaultToleranceTest)
+
//ERASURE_TEST(ErasureMirror3)
//ERASURE_TEST(Erasure3Plus1Block)
//ERASURE_TEST(Erasure3Plus1Stripe)
- ERASURE_TEST(Erasure4Plus2Block)
+ ERASURE_TEST(Erasure4Plus2Block)
//ERASURE_TEST(Erasure3Plus2Block)
//ERASURE_TEST(Erasure4Plus2Stripe)
//ERASURE_TEST(Erasure3Plus2Stripe)
//ERASURE_TEST(ErasureMirror3Plus2)
ERASURE_TEST(ErasureMirror3dc)
- ERASURE_TEST(ErasureMirror3of4)
-
+ ERASURE_TEST(ErasureMirror3of4)
+
Y_UNIT_TEST(CheckGetHardenedErasureMirror3dcCount4Idx0) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::ErasureMirror3dc, true, 4, 0); }
Y_UNIT_TEST(CheckGetHardenedErasureMirror3dcCount4Idx1) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::ErasureMirror3dc, true, 4, 1); }
Y_UNIT_TEST(CheckGetHardenedErasureMirror3dcCount4Idx2) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::ErasureMirror3dc, true, 4, 2); }
@@ -75,5 +75,5 @@ Y_UNIT_TEST_SUITE(TBsProxyFaultToleranceTest) {
Y_UNIT_TEST(CheckGetHardenedErasureBlock42Count4Idx1) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::Erasure4Plus2Block, true, 4, 1); }
Y_UNIT_TEST(CheckGetHardenedErasureBlock42Count4Idx2) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::Erasure4Plus2Block, true, 4, 2); }
Y_UNIT_TEST(CheckGetHardenedErasureBlock42Count4Idx3) { RunTest<TGetHardenedFaultToleranceTest>(TBlobStorageGroupType::Erasure4Plus2Block, true, 4, 3); }
-
-}
+
+}
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_base.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_base.h
index c4b5c76f39b..40a9a03b975 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_base.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_base.h
@@ -1,214 +1,214 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
#include <library/cpp/actors/core/actor_coroutine.h>
#include <library/cpp/testing/unittest/registar.h>
-
-namespace NKikimr {
-
-template<typename TDerived>
-class TFaultToleranceTestBase : public TActorCoroImpl {
+
+namespace NKikimr {
+
+template<typename TDerived>
+class TFaultToleranceTestBase : public TActorCoroImpl {
TSystemEvent *FinishEv;
- std::exception_ptr *Eptr;
- NUnitTest::TTestBase *Test;
-
-protected:
- TFaultToleranceTestRuntime& Runtime;
- const TIntrusivePtr<TBlobStorageGroupInfo>& Info;
-
- // a set of sets of failed disks that fit the fail model
+ std::exception_ptr *Eptr;
+ NUnitTest::TTestBase *Test;
+
+protected:
+ TFaultToleranceTestRuntime& Runtime;
+ const TIntrusivePtr<TBlobStorageGroupInfo>& Info;
+
+ // a set of sets of failed disks that fit the fail model
TSet<TBlobStorageGroupInfo::TGroupVDisks> FaultsFittingFailModel;
-
- // a set of sets of failed disks that exceed the fail model
+
+ // a set of sets of failed disks that exceed the fail model
TSet<TBlobStorageGroupInfo::TGroupVDisks> FaultsExceedingFailModel;
-
+
const ui32 TestPartCount;
const ui32 TestPartIdx;
-public:
+public:
TFaultToleranceTestBase(TSystemEvent *finishEv, std::exception_ptr *eptr, NUnitTest::TTestBase *test, TFaultToleranceTestRuntime& runtime,
ui32 testPartCount, ui32 testPartIdx)
- : TActorCoroImpl(8 << 20) // 8 MB stack size
- , FinishEv(finishEv)
- , Eptr(eptr)
- , Test(test)
- , Runtime(runtime)
- , Info(Runtime.GroupInfo)
+ : TActorCoroImpl(8 << 20) // 8 MB stack size
+ , FinishEv(finishEv)
+ , Eptr(eptr)
+ , Test(test)
+ , Runtime(runtime)
+ , Info(Runtime.GroupInfo)
, TestPartCount(testPartCount)
, TestPartIdx(testPartIdx)
- {}
-
- void GenerateFailModel() {
- const ui32 numDisks = Runtime.VDisks.size();
- for (ui64 mask = 0; mask < ((ui64)1 << numDisks); ++mask) {
+ {}
+
+ void GenerateFailModel() {
+ const ui32 numDisks = Runtime.VDisks.size();
+ for (ui64 mask = 0; mask < ((ui64)1 << numDisks); ++mask) {
TBlobStorageGroupInfo::TGroupVDisks disks = TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&Info->GetTopology(), mask);
- bool fits = Info->GetQuorumChecker().CheckFailModelForGroup(disks);
- (fits ? FaultsFittingFailModel : FaultsExceedingFailModel).emplace(std::move(disks));
- }
- }
-
- void Run() override final {
- GenerateFailModel();
- try {
- static_cast<TDerived *>(this)->RunTestAction();
- } catch (...) {
- *Eptr = std::current_exception();
- }
- FinishEv->Signal();
- }
-
- void BeforeResume() override final {
- if (!NUnitTest::NPrivate::GetCurrentTest()) {
- NUnitTest::NPrivate::SetUnittestThread(true);
- NUnitTest::NPrivate::SetCurrentTest(Test);
- }
- }
-
+ bool fits = Info->GetQuorumChecker().CheckFailModelForGroup(disks);
+ (fits ? FaultsFittingFailModel : FaultsExceedingFailModel).emplace(std::move(disks));
+ }
+ }
+
+ void Run() override final {
+ GenerateFailModel();
+ try {
+ static_cast<TDerived *>(this)->RunTestAction();
+ } catch (...) {
+ *Eptr = std::current_exception();
+ }
+ FinishEv->Signal();
+ }
+
+ void BeforeResume() override final {
+ if (!NUnitTest::NPrivate::GetCurrentTest()) {
+ NUnitTest::NPrivate::SetUnittestThread(true);
+ NUnitTest::NPrivate::SetCurrentTest(Test);
+ }
+ }
+
NKikimrProto::EReplyStatus PutWithResult(const TLogoBlobID& id, const TString& buffer, TEvBlobStorage::TEvPut::ETactic tactic
= TEvBlobStorage::TEvPut::TacticDefault) {
SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max(),
NKikimrBlobStorage::TabletLog, tactic));
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvPutResult>();
- CTEST << (TStringBuilder() << "PutResult: " << resp->Get()->ToString() << Endl);
- if (resp->Get()->Status == NKikimrProto::OK && Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3of4) {
- auto layout = GetActualPartLayout(id);
- const ui32 disksWithData = layout.GetDisksWithPart(0) | layout.GetDisksWithPart(1);
- const ui32 disksWithMetadata = layout.GetDisksWithPart(2);
- const ui32 numDisksWithData = PopCount(disksWithData);
- const ui32 numDisksWithAny = PopCount(disksWithData | disksWithMetadata);
- UNIT_ASSERT(numDisksWithAny >= 5);
- auto printLayout = [&] {
- TStringStream s;
- layout.Output(s, Info->Type);
- return s.Str();
- };
- switch (tactic) {
- case TEvBlobStorage::TEvPut::TacticDefault:
- case TEvBlobStorage::TEvPut::TacticMinLatency:
- UNIT_ASSERT_C(numDisksWithData >= 3 && numDisksWithData <= 4, "numDisksWithData# " << numDisksWithData
- << " layout# " << printLayout());
- break;
-
- case TEvBlobStorage::TEvPut::TacticMaxThroughput:
- UNIT_ASSERT_VALUES_EQUAL(numDisksWithData, 3);
- break;
-
- default:
- Y_FAIL();
- }
- }
- return resp->Get()->Status;
- }
-
- NKikimrProto::EReplyStatus PutToVDisk(ui32 vdiskOrderNum, const TLogoBlobID& id, const TString& part) {
- Send(Info->GetActorId(vdiskOrderNum), new TEvBlobStorage::TEvVPut(id, part, Info->GetVDiskId(vdiskOrderNum),
- false, nullptr, TInstant::Max(), NKikimrBlobStorage::TabletLog));
- auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVPutResult>();
- return ev->Get()->Record.GetStatus();
- }
-
- TSubgroupPartLayout GetActualPartLayout(const TLogoBlobID& id) {
- // issue queries
- TBlobStorageGroupInfo::TVDiskIds vdiskIds;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- Info->PickSubgroup(id.Hash(), &vdiskIds, &serviceIds);
- for (ui32 i = 0; i < Info->Type.BlobSubgroupSize(); ++i) {
- Send(serviceIds[i], TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskIds[i], TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None, Nothing(),
- id, id).release());
- }
-
- // collect answers
- TSubgroupPartLayout layout;
- for (ui32 i = 0; i < Info->Type.BlobSubgroupSize(); ++i) {
- auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID());
-
- //google::protobuf::TextFormat::Printer p;
- //p.SetSingleLineMode(true);
- //TString s;
- //p.PrintToString(ev->Get()->Record, &s);
- //CTEST << " " << s << Endl;
-
- for (auto& item : ev->Get()->Record.GetResult()) {
- for (ui32 partId : item.GetParts()) {
- layout.AddItem(Info->GetIdxInSubgroup(vdiskId, id.Hash()), partId - 1, Info->Type);
- }
- }
- }
-
- return layout;
- }
-
- void Put(const TLogoBlobID& id, const TString& buffer, NKikimrProto::EReplyStatus expectedStatus = NKikimrProto::OK,
- TEvBlobStorage::TEvPut::ETactic tactic = TEvBlobStorage::TEvPut::TacticDefault) {
- UNIT_ASSERT_VALUES_EQUAL(PutWithResult(id, buffer, tactic), expectedStatus);
- }
-
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvPutResult>();
+ CTEST << (TStringBuilder() << "PutResult: " << resp->Get()->ToString() << Endl);
+ if (resp->Get()->Status == NKikimrProto::OK && Info->Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3of4) {
+ auto layout = GetActualPartLayout(id);
+ const ui32 disksWithData = layout.GetDisksWithPart(0) | layout.GetDisksWithPart(1);
+ const ui32 disksWithMetadata = layout.GetDisksWithPart(2);
+ const ui32 numDisksWithData = PopCount(disksWithData);
+ const ui32 numDisksWithAny = PopCount(disksWithData | disksWithMetadata);
+ UNIT_ASSERT(numDisksWithAny >= 5);
+ auto printLayout = [&] {
+ TStringStream s;
+ layout.Output(s, Info->Type);
+ return s.Str();
+ };
+ switch (tactic) {
+ case TEvBlobStorage::TEvPut::TacticDefault:
+ case TEvBlobStorage::TEvPut::TacticMinLatency:
+ UNIT_ASSERT_C(numDisksWithData >= 3 && numDisksWithData <= 4, "numDisksWithData# " << numDisksWithData
+ << " layout# " << printLayout());
+ break;
+
+ case TEvBlobStorage::TEvPut::TacticMaxThroughput:
+ UNIT_ASSERT_VALUES_EQUAL(numDisksWithData, 3);
+ break;
+
+ default:
+ Y_FAIL();
+ }
+ }
+ return resp->Get()->Status;
+ }
+
+ NKikimrProto::EReplyStatus PutToVDisk(ui32 vdiskOrderNum, const TLogoBlobID& id, const TString& part) {
+ Send(Info->GetActorId(vdiskOrderNum), new TEvBlobStorage::TEvVPut(id, part, Info->GetVDiskId(vdiskOrderNum),
+ false, nullptr, TInstant::Max(), NKikimrBlobStorage::TabletLog));
+ auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVPutResult>();
+ return ev->Get()->Record.GetStatus();
+ }
+
+ TSubgroupPartLayout GetActualPartLayout(const TLogoBlobID& id) {
+ // issue queries
+ TBlobStorageGroupInfo::TVDiskIds vdiskIds;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ Info->PickSubgroup(id.Hash(), &vdiskIds, &serviceIds);
+ for (ui32 i = 0; i < Info->Type.BlobSubgroupSize(); ++i) {
+ Send(serviceIds[i], TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskIds[i], TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None, Nothing(),
+ id, id).release());
+ }
+
+ // collect answers
+ TSubgroupPartLayout layout;
+ for (ui32 i = 0; i < Info->Type.BlobSubgroupSize(); ++i) {
+ auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID());
+
+ //google::protobuf::TextFormat::Printer p;
+ //p.SetSingleLineMode(true);
+ //TString s;
+ //p.PrintToString(ev->Get()->Record, &s);
+ //CTEST << " " << s << Endl;
+
+ for (auto& item : ev->Get()->Record.GetResult()) {
+ for (ui32 partId : item.GetParts()) {
+ layout.AddItem(Info->GetIdxInSubgroup(vdiskId, id.Hash()), partId - 1, Info->Type);
+ }
+ }
+ }
+
+ return layout;
+ }
+
+ void Put(const TLogoBlobID& id, const TString& buffer, NKikimrProto::EReplyStatus expectedStatus = NKikimrProto::OK,
+ TEvBlobStorage::TEvPut::ETactic tactic = TEvBlobStorage::TEvPut::TacticDefault) {
+ UNIT_ASSERT_VALUES_EQUAL(PutWithResult(id, buffer, tactic), expectedStatus);
+ }
+
void CheckBlob(const TLogoBlobID& id, bool mustRestoreFirst, NKikimrProto::EReplyStatus status, const TString& buffer) {
- TString data;
- NKikimrProto::EReplyStatus res = GetBlob(id, mustRestoreFirst, buffer ? &data : nullptr);
- UNIT_ASSERT_VALUES_EQUAL(res, status);
- if (res == NKikimrProto::OK && buffer) {
- UNIT_ASSERT_VALUES_EQUAL(data, buffer);
- }
- }
-
- NKikimrProto::EReplyStatus GetBlob(const TLogoBlobID& id, bool mustRestoreFirst, TString *data, bool isRepl = false) {
- auto query = std::make_unique<TEvBlobStorage::TEvGet>(id, 0U /*shift*/, 0U /*size*/, TInstant::Max(),
- NKikimrBlobStorage::FastRead, mustRestoreFirst, !data);
- query->PhantomCheck = isRepl;
- SendToBSProxy(GetActorContext(), Info->GroupID, query.release());
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>();
- TEvBlobStorage::TEvGetResult *msg = resp->Get();
- UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
- const TEvBlobStorage::TEvGetResult::TResponse& item = msg->Responses[0];
- if (data) {
- *data = item.Buffer;
- }
- return item.Status;
- }
-
- void Delete(const TLogoBlobID& from, const TLogoBlobID& to, const TBlobStorageGroupInfo::TGroupVDisks& disks, bool wipe) {
- ui32 responsesPending = 0;
- for (const auto& pair : Runtime.VDisks) {
- const TVDiskID& vdiskId = pair.first;
+ TString data;
+ NKikimrProto::EReplyStatus res = GetBlob(id, mustRestoreFirst, buffer ? &data : nullptr);
+ UNIT_ASSERT_VALUES_EQUAL(res, status);
+ if (res == NKikimrProto::OK && buffer) {
+ UNIT_ASSERT_VALUES_EQUAL(data, buffer);
+ }
+ }
+
+ NKikimrProto::EReplyStatus GetBlob(const TLogoBlobID& id, bool mustRestoreFirst, TString *data, bool isRepl = false) {
+ auto query = std::make_unique<TEvBlobStorage::TEvGet>(id, 0U /*shift*/, 0U /*size*/, TInstant::Max(),
+ NKikimrBlobStorage::FastRead, mustRestoreFirst, !data);
+ query->PhantomCheck = isRepl;
+ SendToBSProxy(GetActorContext(), Info->GroupID, query.release());
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>();
+ TEvBlobStorage::TEvGetResult *msg = resp->Get();
+ UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
+ const TEvBlobStorage::TEvGetResult::TResponse& item = msg->Responses[0];
+ if (data) {
+ *data = item.Buffer;
+ }
+ return item.Status;
+ }
+
+ void Delete(const TLogoBlobID& from, const TLogoBlobID& to, const TBlobStorageGroupInfo::TGroupVDisks& disks, bool wipe) {
+ ui32 responsesPending = 0;
+ for (const auto& pair : Runtime.VDisks) {
+ const TVDiskID& vdiskId = pair.first;
TBlobStorageGroupInfo::TGroupVDisks curDisk(&Info->GetTopology(), vdiskId);
- if (disks & curDisk) {
- auto func = wipe
- ? TEvVMockCtlRequest::CreateWipeOutBlobsRequest
- : TEvVMockCtlRequest::CreateDeleteBlobsRequest;
- GetActorContext().Send(pair.second, func(from, to));
- ++responsesPending;
- }
- }
- while (responsesPending--) {
+ if (disks & curDisk) {
+ auto func = wipe
+ ? TEvVMockCtlRequest::CreateWipeOutBlobsRequest
+ : TEvVMockCtlRequest::CreateDeleteBlobsRequest;
+ GetActorContext().Send(pair.second, func(from, to));
+ ++responsesPending;
+ }
+ }
+ while (responsesPending--) {
auto resp = WaitForSpecificEvent<TEvVMockCtlResponse>();
// Cerr << (TStringBuilder() << "]] SpecEventDelete(wipe=" << wipe << "): " << resp->Get()->ToString() << Endl);
- }
- }
-
- void Delete(const TLogoBlobID& id, const TBlobStorageGroupInfo::TGroupVDisks& disks, bool wipe) {
- Delete(id, TLogoBlobID(id, TLogoBlobID::MaxPartId), disks, wipe);
- }
-
- void SetFailedDisks(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) {
- ui32 responsesPending = 0;
- for (const auto& pair : Runtime.VDisks) {
+ }
+ }
+
+ void Delete(const TLogoBlobID& id, const TBlobStorageGroupInfo::TGroupVDisks& disks, bool wipe) {
+ Delete(id, TLogoBlobID(id, TLogoBlobID::MaxPartId), disks, wipe);
+ }
+
+ void SetFailedDisks(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) {
+ ui32 responsesPending = 0;
+ for (const auto& pair : Runtime.VDisks) {
bool errorMode = static_cast<bool>(failedDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), pair.first));
- GetActorContext().Send(pair.second, TEvVMockCtlRequest::CreateErrorModeRequest(errorMode));
- ++responsesPending;
- }
- while (responsesPending--) {
- WaitForSpecificEvent<TEvVMockCtlResponse>();
- }
- }
-
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
- Y_FAIL("unexpected event received: Type# %08" PRIx32, ev->GetTypeRewrite());
- }
-};
-
-} // NKikimr
+ GetActorContext().Send(pair.second, TEvVMockCtlRequest::CreateErrorModeRequest(errorMode));
+ ++responsesPending;
+ }
+ while (responsesPending--) {
+ WaitForSpecificEvent<TEvVMockCtlResponse>();
+ }
+ }
+
+ void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
+ Y_FAIL("unexpected event received: Type# %08" PRIx32, ev->GetTypeRewrite());
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h
index 2e8df42324c..e48d445b3ab 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_discover.h
@@ -1,127 +1,127 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_fault_tolerance_ut_base.h"
-
-namespace NKikimr {
-
-class TDiscoverFaultToleranceTest : public TFaultToleranceTestBase<TDiscoverFaultToleranceTest> {
-public:
- using TFaultToleranceTestBase::TFaultToleranceTestBase;
-
- void RunTestAction() {
- const ui64 tabletId = 100500;
-
- // put some data
- TLogoBlobID lastBlobId;
- const ui32 numGenerations = 10;
- const ui32 numStepsPerGeneration = 3;
- for (ui32 i = 0; i < numGenerations; ++i) {
- for (ui32 j = 0; j < numStepsPerGeneration; ++j) {
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_fault_tolerance_ut_base.h"
+
+namespace NKikimr {
+
+class TDiscoverFaultToleranceTest : public TFaultToleranceTestBase<TDiscoverFaultToleranceTest> {
+public:
+ using TFaultToleranceTestBase::TFaultToleranceTestBase;
+
+ void RunTestAction() {
+ const ui64 tabletId = 100500;
+
+ // put some data
+ TLogoBlobID lastBlobId;
+ const ui32 numGenerations = 10;
+ const ui32 numStepsPerGeneration = 3;
+ for (ui32 i = 0; i < numGenerations; ++i) {
+ for (ui32 j = 0; j < numStepsPerGeneration; ++j) {
TString data = Sprintf("%" PRIu32 "/%" PRIu32, i + 1, j + 1);
- TLogoBlobID id(tabletId, i + 1, j + 1, 0, data.size(), 0);
- Put(id, data);
- lastBlobId = id;
- }
- }
-
- // find the location of last blob
+ TLogoBlobID id(tabletId, i + 1, j + 1, 0, data.size(), 0);
+ Put(id, data);
+ lastBlobId = id;
+ }
+ }
+
+ // find the location of last blob
THashSet<TVDiskID> vdisksWithLastBlob;
- for (const auto& pair : Runtime.VDisks) {
- auto ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(pair.first, TInstant::Max(), NKikimrBlobStorage::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::None, {}, {lastBlobId});
- GetActorContext().Send(pair.second, ev.release());
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
- const auto& record = resp->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
+ for (const auto& pair : Runtime.VDisks) {
+ auto ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(pair.first, TInstant::Max(), NKikimrBlobStorage::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::None, {}, {lastBlobId});
+ GetActorContext().Send(pair.second, ev.release());
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
+ const auto& record = resp->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
UNIT_ASSERT(record.ResultSize() >= 1);
- const auto& item = record.GetResult(0);
- if (item.GetStatus() == NKikimrProto::OK) {
- vdisksWithLastBlob.emplace(pair.first);
- }
- }
-
- // put blocks
- SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvBlock(1, numGenerations - 1, TInstant::Max()));
- auto response = WaitForSpecificEvent<TEvBlobStorage::TEvBlockResult>();
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Status, NKikimrProto::OK);
-
- TBlobStorageGroupInfo::TVDiskIds lastBlobSubgroup;
- Info->PickSubgroup(lastBlobId.Hash(), &lastBlobSubgroup, nullptr);
-
- for (const auto& failedDisks : FaultsExceedingFailModel) {
- ui32 num = 0;
- for (const TVDiskID& vdisk : vdisksWithLastBlob) {
+ const auto& item = record.GetResult(0);
+ if (item.GetStatus() == NKikimrProto::OK) {
+ vdisksWithLastBlob.emplace(pair.first);
+ }
+ }
+
+ // put blocks
+ SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvBlock(1, numGenerations - 1, TInstant::Max()));
+ auto response = WaitForSpecificEvent<TEvBlobStorage::TEvBlockResult>();
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Status, NKikimrProto::OK);
+
+ TBlobStorageGroupInfo::TVDiskIds lastBlobSubgroup;
+ Info->PickSubgroup(lastBlobId.Hash(), &lastBlobSubgroup, nullptr);
+
+ for (const auto& failedDisks : FaultsExceedingFailModel) {
+ ui32 num = 0;
+ for (const TVDiskID& vdisk : vdisksWithLastBlob) {
if (~failedDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdisk)) {
- ++num;
- }
- }
- const bool recoverable = num >= Info->Type.MinimalRestorablePartCount();
-
+ ++num;
+ }
+ }
+ const bool recoverable = num >= Info->Type.MinimalRestorablePartCount();
+
TBlobStorageGroupInfo::TSubgroupVDisks failedSubgroupDisks(&Info->GetTopology());
- for (const TVDiskID& vdisk : lastBlobSubgroup) {
+ for (const TVDiskID& vdisk : lastBlobSubgroup) {
if (failedDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vdisk)) {
- ui32 nodeId = Info->GetIdxInSubgroup(vdisk, lastBlobId.Hash());
+ ui32 nodeId = Info->GetIdxInSubgroup(vdisk, lastBlobId.Hash());
failedSubgroupDisks += TBlobStorageGroupInfo::TSubgroupVDisks(&Info->GetTopology(), nodeId);
- }
- }
- const bool restorable = Info->GetQuorumChecker().CheckFailModelForSubgroup(failedSubgroupDisks);
-
- SetFailedDisks(failedDisks);
- SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, false, false,
+ }
+ }
+ const bool restorable = Info->GetQuorumChecker().CheckFailModelForSubgroup(failedSubgroupDisks);
+
+ SetFailedDisks(failedDisks);
+ SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, false, false,
TInstant::Max(), 0));
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>();
-
- const NKikimrProto::EReplyStatus status = resp->Get()->Status;
-
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>();
+
+ const NKikimrProto::EReplyStatus status = resp->Get()->Status;
+
CTEST << "recoverable# " << (recoverable ? "true" : "false")
- << " restorable# " << (restorable ? "true" : "false")
- << " status# " << NKikimrProto::EReplyStatus_Name(status)
- << " vdisksWithLastBlob# [";
- for (auto it = vdisksWithLastBlob.begin(); it != vdisksWithLastBlob.end(); ++it) {
+ << " restorable# " << (restorable ? "true" : "false")
+ << " status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " vdisksWithLastBlob# [";
+ for (auto it = vdisksWithLastBlob.begin(); it != vdisksWithLastBlob.end(); ++it) {
CTEST << (it != vdisksWithLastBlob.begin() ? " " : "")
- << it->ToString();
- }
+ << it->ToString();
+ }
CTEST << "] failedDisks# [";
- bool first = true;
- for (const auto& vdisk : Info->GetVDisks()) {
+ bool first = true;
+ for (const auto& vdisk : Info->GetVDisks()) {
auto vd = Info->GetVDiskId(vdisk.OrderNumber);
if (failedDisks & TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology(), vd)) {
CTEST << (first ? "" : " ") << vd;
- first = false;
- }
- }
+ first = false;
+ }
+ }
CTEST << "] num# " << num << Endl;
-
- NKikimrProto::EReplyStatus expected = recoverable && restorable
- ? NKikimrProto::OK
- : NKikimrProto::ERROR;
-
- UNIT_ASSERT_C(status == expected || status == NKikimrProto::ERROR,
- "status# " << NKikimrProto::EReplyStatus_Name(status)
- << " expected# " << NKikimrProto::EReplyStatus_Name(expected));
- }
+
+ NKikimrProto::EReplyStatus expected = recoverable && restorable
+ ? NKikimrProto::OK
+ : NKikimrProto::ERROR;
+
+ UNIT_ASSERT_C(status == expected || status == NKikimrProto::ERROR,
+ "status# " << NKikimrProto::EReplyStatus_Name(status)
+ << " expected# " << NKikimrProto::EReplyStatus_Name(expected));
+ }
SetFailedDisks(TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology()));
-
- // permute any combinations of faulty disks and check for blob recovery
- for (const auto& disks : FaultsFittingFailModel) {
- Delete(TLogoBlobID(0, 0, 0, 0, 0, 0), TLogoBlobID(Max<ui64>(), Max<ui32>(), Max<ui32>(),
- TLogoBlobID::MaxChannel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie),
- disks, false);
-
+
+ // permute any combinations of faulty disks and check for blob recovery
+ for (const auto& disks : FaultsFittingFailModel) {
+ Delete(TLogoBlobID(0, 0, 0, 0, 0, 0), TLogoBlobID(Max<ui64>(), Max<ui32>(), Max<ui32>(),
+ TLogoBlobID::MaxChannel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie),
+ disks, false);
+
SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvDiscover(tabletId, 0, true, true, TInstant::Max(), 0));
- auto response = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>();
-
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Status, NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.TabletID(), tabletId);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Generation(), numGenerations);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Step(), numStepsPerGeneration);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Channel(), 0);
-// UNIT_ASSERT_VALUES_EQUAL(response->Get()->BlockedGeneration, numGenerations - 1);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Buffer, Sprintf("%" PRIu32 "/%" PRIu32, numGenerations,
- numStepsPerGeneration));
- }
- }
-};
-
-} // NKikimr
+ auto response = WaitForSpecificEvent<TEvBlobStorage::TEvDiscoverResult>();
+
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Status, NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.TabletID(), tabletId);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Generation(), numGenerations);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Step(), numStepsPerGeneration);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Id.Channel(), 0);
+// UNIT_ASSERT_VALUES_EQUAL(response->Get()->BlockedGeneration, numGenerations - 1);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Buffer, Sprintf("%" PRIu32 "/%" PRIu32, numGenerations,
+ numStepsPerGeneration));
+ }
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get.h
index da1b719b036..e602f115e98 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get.h
@@ -1,73 +1,73 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_fault_tolerance_ut_base.h"
-
-namespace NKikimr {
-
-class TGetWithRecoverFaultToleranceTest : public TFaultToleranceTestBase<TGetWithRecoverFaultToleranceTest> {
-public:
- using TFaultToleranceTestBase::TFaultToleranceTestBase;
-
- void RunTestAction() {
- ui32 index = 1;
-
- for (const TEvBlobStorage::TEvPut::ETactic tactic : {TEvBlobStorage::TEvPut::TacticMinLatency,
- TEvBlobStorage::TEvPut::TacticMaxThroughput}) {
- TString data = "test";
- TLogoBlobID id(1, index++, 1, 1, data.size(), 0);
-
- // send put request
- Put(id, data, NKikimrProto::OK, tactic);
-
- // check for correctness
- CheckBlob(id, false, NKikimrProto::OK, data);
-
- // permute any combinations of faulty disks and check for blob recovery
- for (const auto& disks : FaultsFittingFailModel) {
- if (Info->GetQuorumChecker().CheckFailModelForGroup(disks)) {
- Delete(id, disks, false);
- CheckBlob(id, true, NKikimrProto::OK, data);
- }
- }
-
- // do the same, but for index restore on get query
- for (const auto& disks : FaultsFittingFailModel) {
- if (Info->GetQuorumChecker().CheckFailModelForGroup(disks)) {
- Delete(id, disks, false);
- CheckBlob(id, true, NKikimrProto::OK, TString());
- }
- }
-
- // check for correctness once again
- CheckBlob(id, false, NKikimrProto::OK, data);
-
- // now create bunch of blobs and check index restore get for them
- TVector<TLogoBlobID> ids;
- for (ui32 i = 0; i < 100000; ++i) {
- TLogoBlobID id(1, index++, 1, 1, data.size(), 0);
- Put(id, data, NKikimrProto::OK, tactic);
- ids.push_back(id);
- }
-
- TArrayHolder<TEvBlobStorage::TEvGet::TQuery> items(new TEvBlobStorage::TEvGet::TQuery[ids.size()]);
- for (ui32 i = 0; i < ids.size(); ++i) {
- items[i].Set(ids[i]);
- }
-
- SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvGet(items, ids.size(), TInstant::Max(),
- NKikimrBlobStorage::FastRead, true, true));
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>();
- TEvBlobStorage::TEvGetResult *msg = resp->Get();
- UNIT_ASSERT_VALUES_EQUAL(msg->Status, NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, ids.size());
- for (ui32 i = 0; i < ids.size(); ++i) {
- const TEvBlobStorage::TEvGetResult::TResponse& item = msg->Responses[i];
- UNIT_ASSERT_VALUES_EQUAL(item.Id, ids[i]);
- UNIT_ASSERT_VALUES_EQUAL(item.Status, NKikimrProto::OK);
- }
- }
- }
-};
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_fault_tolerance_ut_base.h"
+
+namespace NKikimr {
+
+class TGetWithRecoverFaultToleranceTest : public TFaultToleranceTestBase<TGetWithRecoverFaultToleranceTest> {
+public:
+ using TFaultToleranceTestBase::TFaultToleranceTestBase;
+
+ void RunTestAction() {
+ ui32 index = 1;
+
+ for (const TEvBlobStorage::TEvPut::ETactic tactic : {TEvBlobStorage::TEvPut::TacticMinLatency,
+ TEvBlobStorage::TEvPut::TacticMaxThroughput}) {
+ TString data = "test";
+ TLogoBlobID id(1, index++, 1, 1, data.size(), 0);
+
+ // send put request
+ Put(id, data, NKikimrProto::OK, tactic);
+
+ // check for correctness
+ CheckBlob(id, false, NKikimrProto::OK, data);
+
+ // permute any combinations of faulty disks and check for blob recovery
+ for (const auto& disks : FaultsFittingFailModel) {
+ if (Info->GetQuorumChecker().CheckFailModelForGroup(disks)) {
+ Delete(id, disks, false);
+ CheckBlob(id, true, NKikimrProto::OK, data);
+ }
+ }
+
+ // do the same, but for index restore on get query
+ for (const auto& disks : FaultsFittingFailModel) {
+ if (Info->GetQuorumChecker().CheckFailModelForGroup(disks)) {
+ Delete(id, disks, false);
+ CheckBlob(id, true, NKikimrProto::OK, TString());
+ }
+ }
+
+ // check for correctness once again
+ CheckBlob(id, false, NKikimrProto::OK, data);
+
+ // now create bunch of blobs and check index restore get for them
+ TVector<TLogoBlobID> ids;
+ for (ui32 i = 0; i < 100000; ++i) {
+ TLogoBlobID id(1, index++, 1, 1, data.size(), 0);
+ Put(id, data, NKikimrProto::OK, tactic);
+ ids.push_back(id);
+ }
+
+ TArrayHolder<TEvBlobStorage::TEvGet::TQuery> items(new TEvBlobStorage::TEvGet::TQuery[ids.size()]);
+ for (ui32 i = 0; i < ids.size(); ++i) {
+ items[i].Set(ids[i]);
+ }
+
+ SendToBSProxy(GetActorContext(), Info->GroupID, new TEvBlobStorage::TEvGet(items, ids.size(), TInstant::Max(),
+ NKikimrBlobStorage::FastRead, true, true));
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>();
+ TEvBlobStorage::TEvGetResult *msg = resp->Get();
+ UNIT_ASSERT_VALUES_EQUAL(msg->Status, NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, ids.size());
+ for (ui32 i = 0; i < ids.size(); ++i) {
+ const TEvBlobStorage::TEvGetResult::TResponse& item = msg->Responses[i];
+ UNIT_ASSERT_VALUES_EQUAL(item.Id, ids[i]);
+ UNIT_ASSERT_VALUES_EQUAL(item.Status, NKikimrProto::OK);
+ }
+ }
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get_hardened.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get_hardened.h
index 4c7bd5f1eef..be700d7a30f 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get_hardened.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_get_hardened.h
@@ -1,281 +1,281 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_fault_tolerance_ut_base.h"
-
-namespace NKikimr {
-
-class TGetHardenedFaultToleranceTest : public TFaultToleranceTestBase<TGetHardenedFaultToleranceTest> {
- ui32 Index = 1;
- TString Data = "hello, world!";
- struct TBlobInfo {
- TBlobStorageGroupInfo::TGroupVDisks DisksWrittenTo;
- TSubgroupPartLayout Layout;
- bool AlmostWritten;
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_fault_tolerance_ut_base.h"
+
+namespace NKikimr {
+
+class TGetHardenedFaultToleranceTest : public TFaultToleranceTestBase<TGetHardenedFaultToleranceTest> {
+ ui32 Index = 1;
+ TString Data = "hello, world!";
+ struct TBlobInfo {
+ TBlobStorageGroupInfo::TGroupVDisks DisksWrittenTo;
+ TSubgroupPartLayout Layout;
+ bool AlmostWritten;
bool Unwritten;
- };
- std::map<TLogoBlobID, TBlobInfo> BlobsWritten;
-
-public:
- using TFaultToleranceTestBase::TFaultToleranceTestBase;
-
- void RunTestAction() {
- WriteParts();
-
- enum EState {
- ST_OK,
- ST_ERR,
- ST_LOST,
- };
-
+ };
+ std::map<TLogoBlobID, TBlobInfo> BlobsWritten;
+
+public:
+ using TFaultToleranceTestBase::TFaultToleranceTestBase;
+
+ void RunTestAction() {
+ WriteParts();
+
+ enum EState {
+ ST_OK,
+ ST_ERR,
+ ST_LOST,
+ };
+
ui32 blobsWrittenFull = 0;
ui32 blobsWrittenAlmostFull = 0;
ui32 blobsUnwritten = 0;
- for (const auto& [id, blobInfo] : BlobsWritten) {
+ for (const auto& [id, blobInfo] : BlobsWritten) {
if (blobInfo.Unwritten) {
blobsUnwritten++;
} else {
++(blobInfo.AlmostWritten ? blobsWrittenAlmostFull : blobsWrittenFull);
}
- }
-
- const ui32 numDisks = Info->GetTotalVDisksNum();
- ui32 nIter = 0;
- for (const auto& [id, blobInfo] : BlobsWritten) {
+ }
+
+ const ui32 numDisks = Info->GetTotalVDisksNum();
+ ui32 nIter = 0;
+ for (const auto& [id, blobInfo] : BlobsWritten) {
if (nIter % TestPartCount != TestPartIdx) {
nIter++;
continue;
}
- Cerr << "iteration# " << nIter++ << " BlobsWritten# " << BlobsWritten.size()
- << " blobsWrittenFull# " << blobsWrittenFull << " blobsWrittenAlmostFull# " << blobsWrittenAlmostFull
+ Cerr << "iteration# " << nIter++ << " BlobsWritten# " << BlobsWritten.size()
+ << " blobsWrittenFull# " << blobsWrittenFull << " blobsWrittenAlmostFull# " << blobsWrittenAlmostFull
<< " blobsUnwritten# " << blobsUnwritten
- << Endl;
-
- std::vector<EState> states(numDisks, ST_OK);
- for (;;) {
- // send queries
- ui32 responsesPending = 0;
- for (ui32 i = 0; i < states.size(); ++i) {
- const EState state = states[i];
- Send(Info->GetActorId(i), TEvVMockCtlRequest::CreateErrorModeRequest(state == ST_ERR, state == ST_LOST));
- ++responsesPending;
- }
- while (responsesPending--) {
- WaitForSpecificEvent<TEvVMockCtlResponse>();
- }
-
- // check whether the group fits the fail model
- TBlobStorageGroupInfo::TGroupVDisks failedDisks(&Info->GetTopology());
- TBlobStorageGroupInfo::TGroupVDisks lostDisks(&Info->GetTopology());
+ << Endl;
+
+ std::vector<EState> states(numDisks, ST_OK);
+ for (;;) {
+ // send queries
+ ui32 responsesPending = 0;
+ for (ui32 i = 0; i < states.size(); ++i) {
+ const EState state = states[i];
+ Send(Info->GetActorId(i), TEvVMockCtlRequest::CreateErrorModeRequest(state == ST_ERR, state == ST_LOST));
+ ++responsesPending;
+ }
+ while (responsesPending--) {
+ WaitForSpecificEvent<TEvVMockCtlResponse>();
+ }
+
+ // check whether the group fits the fail model
+ TBlobStorageGroupInfo::TGroupVDisks failedDisks(&Info->GetTopology());
+ TBlobStorageGroupInfo::TGroupVDisks lostDisks(&Info->GetTopology());
bool isErrorDisksPresent = false;
- for (ui32 diskIdx = 0; diskIdx < states.size(); ++diskIdx) {
- if (states[diskIdx] != ST_OK) {
- failedDisks |= {&Info->GetTopology(), Info->GetVDiskId(diskIdx)};
+ for (ui32 diskIdx = 0; diskIdx < states.size(); ++diskIdx) {
+ if (states[diskIdx] != ST_OK) {
+ failedDisks |= {&Info->GetTopology(), Info->GetVDiskId(diskIdx)};
if (states[diskIdx] == ST_ERR) {
isErrorDisksPresent = true;
}
- }
- if (states[diskIdx] == ST_LOST) {
- lostDisks |= {&Info->GetTopology(), Info->GetVDiskId(diskIdx)};
- }
- }
- const bool fitsFailModel = Info->GetQuorumChecker().CheckFailModelForGroup(failedDisks);
-
- TString data;
+ }
+ if (states[diskIdx] == ST_LOST) {
+ lostDisks |= {&Info->GetTopology(), Info->GetVDiskId(diskIdx)};
+ }
+ }
+ const bool fitsFailModel = Info->GetQuorumChecker().CheckFailModelForGroup(failedDisks);
+
+ TString data;
const NKikimrProto::EReplyStatus status = GetBlob(id, false, &data,
blobInfo.AlmostWritten || blobInfo.Unwritten);
- bool failure = false;
- if (status == NKikimrProto::OK) {
+ bool failure = false;
+ if (status == NKikimrProto::OK) {
if (!blobInfo.AlmostWritten && !blobInfo.Unwritten) {
- UNIT_ASSERT_VALUES_EQUAL(data, Data);
- }
+ UNIT_ASSERT_VALUES_EQUAL(data, Data);
+ }
} else if (fitsFailModel && !blobInfo.AlmostWritten && !blobInfo.Unwritten) {
- failure = true;
- } else if (status == NKikimrProto::NODATA) {
- bool restorable = false;
- // see if there is any chance to restore this blob?
- TBlobStorageGroupInfo::TOrderNums orderNums;
- Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
- TSubgroupPartLayout layout(blobInfo.Layout);
- for (ui32 idxInSubgroup = 0; idxInSubgroup < Info->Type.BlobSubgroupSize(); ++idxInSubgroup) {
- if (states[orderNums[idxInSubgroup]] == ST_LOST) {
- for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
- layout.ClearItem(idxInSubgroup, partIdx, Info->Type);
- }
- }
- }
- switch (Info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- if (layout.GetDisksWithPart(0) || layout.GetDisksWithPart(1) || layout.GetDisksWithPart(2)) {
- restorable = true;
- }
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- if (layout.GetDisksWithPart(0) || layout.GetDisksWithPart(1)) {
- restorable = true;
- }
- break;
-
- default: {
- ui32 numDistinctParts = 0;
- for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
- if (layout.GetDisksWithPart(partIdx)) {
- ++numDistinctParts;
- }
- }
- if (numDistinctParts >= Info->Type.MinimalRestorablePartCount()) {
- restorable = true;
- }
- break;
- }
- }
+ failure = true;
+ } else if (status == NKikimrProto::NODATA) {
+ bool restorable = false;
+ // see if there is any chance to restore this blob?
+ TBlobStorageGroupInfo::TOrderNums orderNums;
+ Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
+ TSubgroupPartLayout layout(blobInfo.Layout);
+ for (ui32 idxInSubgroup = 0; idxInSubgroup < Info->Type.BlobSubgroupSize(); ++idxInSubgroup) {
+ if (states[orderNums[idxInSubgroup]] == ST_LOST) {
+ for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
+ layout.ClearItem(idxInSubgroup, partIdx, Info->Type);
+ }
+ }
+ }
+ switch (Info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ if (layout.GetDisksWithPart(0) || layout.GetDisksWithPart(1) || layout.GetDisksWithPart(2)) {
+ restorable = true;
+ }
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ if (layout.GetDisksWithPart(0) || layout.GetDisksWithPart(1)) {
+ restorable = true;
+ }
+ break;
+
+ default: {
+ ui32 numDistinctParts = 0;
+ for (ui32 partIdx = 0; partIdx < Info->Type.TotalPartCount(); ++partIdx) {
+ if (layout.GetDisksWithPart(partIdx)) {
+ ++numDistinctParts;
+ }
+ }
+ if (numDistinctParts >= Info->Type.MinimalRestorablePartCount()) {
+ restorable = true;
+ }
+ break;
+ }
+ }
if (!blobInfo.AlmostWritten && !blobInfo.Unwritten) {
- // it's okay if proxy returns DATA for fully written blob with excessive failures, but it
- // must reply with ERROR in phantom check mode
- if (Info->GetQuorumChecker().CheckFailModelForGroup(lostDisks)) {
- failure = true;
- UNIT_ASSERT(restorable);
- } else if (const NKikimrProto::EReplyStatus status = GetBlob(id, false, &data, true); status == NKikimrProto::NODATA) {
+ // it's okay if proxy returns DATA for fully written blob with excessive failures, but it
+ // must reply with ERROR in phantom check mode
+ if (Info->GetQuorumChecker().CheckFailModelForGroup(lostDisks)) {
+ failure = true;
+ UNIT_ASSERT(restorable);
+ } else if (const NKikimrProto::EReplyStatus status = GetBlob(id, false, &data, true); status == NKikimrProto::NODATA) {
// Cerr << "PhantomCheck mode status# " << NKikimrProto::EReplyStatus_Name(status) << Endl;
- failure = restorable;
- }
- } else {
- failure = restorable;
- }
- } else {
- UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::ERROR);
+ failure = restorable;
+ }
+ } else {
+ failure = restorable;
+ }
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::ERROR);
if (blobInfo.Unwritten && !isErrorDisksPresent) {
failure = true;
}
- }
- if (failure) {
- static char letters[] = {'O', 'E', 'L'};
-
- TStringBuilder state;
- for (ui32 i = 0; i < states.size(); ++i) {
- state << letters[states[states.size() - i - 1]];
- }
-
- TStringBuilder subgroupState;
- TBlobStorageGroupInfo::TOrderNums orderNums;
- Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
- for (ui32 i = 0; i < states.size(); ++i) {
- subgroupState << letters[states[orderNums[states.size() - i - 1]]];
- }
-
- TStringBuilder reducedLayout;
- reducedLayout << "{";
- for (ui32 diskIdx = 0; diskIdx < Info->Type.BlobSubgroupSize(); ++diskIdx) {
- if (diskIdx) {
- reducedLayout << " ";
- }
- for (ui32 partIdx = Info->Type.TotalPartCount(); partIdx--; ) {
- const ui32 orderNum = orderNums[diskIdx];
- const EState state = states[orderNum];
- const bool written = blobInfo.Layout.GetDisksWithPart(partIdx) >> diskIdx & 1;
- reducedLayout << (
- state == ST_OK ? (written ? "1" : "0") :
- state == ST_ERR ? (written ? "E" : "e") :
- state == ST_LOST ? (written ? "L" : "0") : "?"
- );
- }
- }
- reducedLayout << "}";
-
- Cerr << "state# " << state
- << " writtenTo# " << blobInfo.DisksWrittenTo.ToString()
- << " subgroupState# " << subgroupState
- << " subgroupLayout# " << blobInfo.Layout.ToString(Info->Type)
- << " reducedLayout# " << reducedLayout
- << " almostWritten# " << (blobInfo.AlmostWritten ? "Y" : "N")
+ }
+ if (failure) {
+ static char letters[] = {'O', 'E', 'L'};
+
+ TStringBuilder state;
+ for (ui32 i = 0; i < states.size(); ++i) {
+ state << letters[states[states.size() - i - 1]];
+ }
+
+ TStringBuilder subgroupState;
+ TBlobStorageGroupInfo::TOrderNums orderNums;
+ Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
+ for (ui32 i = 0; i < states.size(); ++i) {
+ subgroupState << letters[states[orderNums[states.size() - i - 1]]];
+ }
+
+ TStringBuilder reducedLayout;
+ reducedLayout << "{";
+ for (ui32 diskIdx = 0; diskIdx < Info->Type.BlobSubgroupSize(); ++diskIdx) {
+ if (diskIdx) {
+ reducedLayout << " ";
+ }
+ for (ui32 partIdx = Info->Type.TotalPartCount(); partIdx--; ) {
+ const ui32 orderNum = orderNums[diskIdx];
+ const EState state = states[orderNum];
+ const bool written = blobInfo.Layout.GetDisksWithPart(partIdx) >> diskIdx & 1;
+ reducedLayout << (
+ state == ST_OK ? (written ? "1" : "0") :
+ state == ST_ERR ? (written ? "E" : "e") :
+ state == ST_LOST ? (written ? "L" : "0") : "?"
+ );
+ }
+ }
+ reducedLayout << "}";
+
+ Cerr << "state# " << state
+ << " writtenTo# " << blobInfo.DisksWrittenTo.ToString()
+ << " subgroupState# " << subgroupState
+ << " subgroupLayout# " << blobInfo.Layout.ToString(Info->Type)
+ << " reducedLayout# " << reducedLayout
+ << " almostWritten# " << (blobInfo.AlmostWritten ? "Y" : "N")
<< " unritten# " << (blobInfo.Unwritten ? "Y" : "N")
- << " fitsFailModel# " << (fitsFailModel ? "Y" : "N")
- << " status# " << NKikimrProto::EReplyStatus_Name(status)
- << Endl;
- UNIT_ASSERT(false);
- }
-
- // advance to next option
- bool carry = true;
- for (ui32 i = 0; carry && i < numDisks; ++i) {
- switch (states[i]) {
- case ST_OK:
- states[i] = ST_ERR;
- break;
-
- case ST_ERR:
- states[i] = blobInfo.DisksWrittenTo[i] ? ST_LOST : ST_OK;
- break;
-
- case ST_LOST:
- states[i] = ST_OK;
- break;
- }
- carry = states[i] == ST_OK;
- }
- if (carry) {
- break;
- }
- }
- }
- }
-
- void GenerateBlob(TLogoBlobID *id, TDataPartSet *parts) {
- TString data = Data;
- *id = TLogoBlobID(1, 1, Index++, 0, data.size(), 0);
- char *buffer = data.Detach();
- Encrypt(buffer, buffer, 0, data.size(), *id, *Info);
- *parts = {};
- Info->Type.SplitData(TBlobStorageGroupType::CrcModeNone, data, *parts);
- }
-
- void WriteParts() {
- const TBlobStorageGroupType type = Info->Type;
- const TBlobStorageGroupInfo::TTopology *topology = &Info->GetTopology();
- const TBlobStorageGroupInfo::IQuorumChecker& checker = topology->GetQuorumChecker();
-
- TSubgroupPartLayout::GeneratePossibleLayouts(type, 1, [&](const TSubgroupPartLayout& layout) {
+ << " fitsFailModel# " << (fitsFailModel ? "Y" : "N")
+ << " status# " << NKikimrProto::EReplyStatus_Name(status)
+ << Endl;
+ UNIT_ASSERT(false);
+ }
+
+ // advance to next option
+ bool carry = true;
+ for (ui32 i = 0; carry && i < numDisks; ++i) {
+ switch (states[i]) {
+ case ST_OK:
+ states[i] = ST_ERR;
+ break;
+
+ case ST_ERR:
+ states[i] = blobInfo.DisksWrittenTo[i] ? ST_LOST : ST_OK;
+ break;
+
+ case ST_LOST:
+ states[i] = ST_OK;
+ break;
+ }
+ carry = states[i] == ST_OK;
+ }
+ if (carry) {
+ break;
+ }
+ }
+ }
+ }
+
+ void GenerateBlob(TLogoBlobID *id, TDataPartSet *parts) {
+ TString data = Data;
+ *id = TLogoBlobID(1, 1, Index++, 0, data.size(), 0);
+ char *buffer = data.Detach();
+ Encrypt(buffer, buffer, 0, data.size(), *id, *Info);
+ *parts = {};
+ Info->Type.SplitData(TBlobStorageGroupType::CrcModeNone, data, *parts);
+ }
+
+ void WriteParts() {
+ const TBlobStorageGroupType type = Info->Type;
+ const TBlobStorageGroupInfo::TTopology *topology = &Info->GetTopology();
+ const TBlobStorageGroupInfo::IQuorumChecker& checker = topology->GetQuorumChecker();
+
+ TSubgroupPartLayout::GeneratePossibleLayouts(type, 1, [&](const TSubgroupPartLayout& layout) {
bool almostWritten = false;
bool unwritten = false;
-
- if (checker.GetBlobState(layout, {topology}) == TBlobStorageGroupInfo::EBS_FULL) {
- almostWritten = false; // blob is fully written
- } else {
- // try to add one more part to make it fully written, if possible
- bool found = false;
- for (ui32 idxInSubgroup = 0; !found && idxInSubgroup < type.BlobSubgroupSize(); ++idxInSubgroup) {
- for (ui32 partIdx = 0; !found && partIdx < type.TotalPartCount(); ++partIdx) {
- if (layout.GetDisksWithPart(partIdx) & 1 << idxInSubgroup) {
- continue;
- }
- bool match = false;
- switch (type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- match = partIdx == idxInSubgroup % 3;
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- match = partIdx == (idxInSubgroup & 1) || partIdx == 2;
- break;
-
- default:
- match = idxInSubgroup < type.TotalPartCount()
- ? idxInSubgroup == partIdx // only specific part on main
- : true; // any part on handoff
- break;
- }
- if (match) {
- TSubgroupPartLayout temp(layout);
- temp.AddItem(idxInSubgroup, partIdx, type);
- if (checker.GetBlobState(temp, {topology}) == TBlobStorageGroupInfo::EBS_FULL) {
- found = true;
- }
- }
- }
- }
- if (found) {
- almostWritten = true;
+
+ if (checker.GetBlobState(layout, {topology}) == TBlobStorageGroupInfo::EBS_FULL) {
+ almostWritten = false; // blob is fully written
+ } else {
+ // try to add one more part to make it fully written, if possible
+ bool found = false;
+ for (ui32 idxInSubgroup = 0; !found && idxInSubgroup < type.BlobSubgroupSize(); ++idxInSubgroup) {
+ for (ui32 partIdx = 0; !found && partIdx < type.TotalPartCount(); ++partIdx) {
+ if (layout.GetDisksWithPart(partIdx) & 1 << idxInSubgroup) {
+ continue;
+ }
+ bool match = false;
+ switch (type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ match = partIdx == idxInSubgroup % 3;
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ match = partIdx == (idxInSubgroup & 1) || partIdx == 2;
+ break;
+
+ default:
+ match = idxInSubgroup < type.TotalPartCount()
+ ? idxInSubgroup == partIdx // only specific part on main
+ : true; // any part on handoff
+ break;
+ }
+ if (match) {
+ TSubgroupPartLayout temp(layout);
+ temp.AddItem(idxInSubgroup, partIdx, type);
+ if (checker.GetBlobState(temp, {topology}) == TBlobStorageGroupInfo::EBS_FULL) {
+ found = true;
+ }
+ }
+ }
+ }
+ if (found) {
+ almostWritten = true;
} else if (type.GetErasure() == TBlobStorageGroupType::Erasure4Plus2Block) {
i32 count = 0;
for (ui32 partIdx = 0; partIdx < type.TotalPartCount(); ++partIdx) {
@@ -288,31 +288,31 @@ public:
} else {
return;
}
- } else {
- return;
- }
- }
-
- TLogoBlobID id;
- TDataPartSet parts;
- GenerateBlob(&id, &parts);
-
- TBlobStorageGroupInfo::TOrderNums orderNums;
- Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
-
- TBlobStorageGroupInfo::TGroupVDisks disksWrittenTo(topology);
-
- layout.ForEachPartOfDisk(type, [&](ui32 partIdx, ui32 idxInSubgroup) {
- const TLogoBlobID partId(id, partIdx + 1);
- const NKikimrProto::EReplyStatus res = PutToVDisk(orderNums[idxInSubgroup], partId,
- parts.Parts[partIdx].OwnedString);
- UNIT_ASSERT_VALUES_EQUAL(res, NKikimrProto::OK);
- disksWrittenTo |= {topology, topology->GetVDiskId(idxInSubgroup)};
- });
-
+ } else {
+ return;
+ }
+ }
+
+ TLogoBlobID id;
+ TDataPartSet parts;
+ GenerateBlob(&id, &parts);
+
+ TBlobStorageGroupInfo::TOrderNums orderNums;
+ Info->GetTopology().PickSubgroup(id.Hash(), orderNums);
+
+ TBlobStorageGroupInfo::TGroupVDisks disksWrittenTo(topology);
+
+ layout.ForEachPartOfDisk(type, [&](ui32 partIdx, ui32 idxInSubgroup) {
+ const TLogoBlobID partId(id, partIdx + 1);
+ const NKikimrProto::EReplyStatus res = PutToVDisk(orderNums[idxInSubgroup], partId,
+ parts.Parts[partIdx].OwnedString);
+ UNIT_ASSERT_VALUES_EQUAL(res, NKikimrProto::OK);
+ disksWrittenTo |= {topology, topology->GetVDiskId(idxInSubgroup)};
+ });
+
BlobsWritten.emplace(id, TBlobInfo{.DisksWrittenTo = disksWrittenTo, .Layout = layout, .AlmostWritten = almostWritten, .Unwritten = unwritten});
- });
- }
-};
-
-} // NKikimr
+ });
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_put.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_put.h
index 72ac7de57f6..1d47ff4e7cd 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_put.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_put.h
@@ -1,78 +1,78 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_fault_tolerance_ut_base.h"
-
-namespace NKikimr {
-
-class TPutFaultToleranceTest : public TFaultToleranceTestBase<TPutFaultToleranceTest> {
-public:
- using TFaultToleranceTestBase::TFaultToleranceTestBase;
-
- void RunTestAction() {
- ui32 index = 1;
-
- for (const TEvBlobStorage::TEvPut::ETactic tactic : {TEvBlobStorage::TEvPut::TacticMinLatency,
- TEvBlobStorage::TEvPut::TacticMaxThroughput}) {
- auto makeBlob = [&index] {
- TString data = Sprintf("#%" PRIu32, index);
- while (data.size() < 4096) {
- data += data;
- }
- TLogoBlobID id(1, 1, index++, 0, data.size(), 0);
- return std::make_tuple(id, data);
- };
-
- THashMap<TLogoBlobID, TString> dataMap;
-
- auto tryOption = [&](const auto& faultyDisks, bool fitsFailModel) {
- if (IsVerbose) {
- TStringStream str;
- faultyDisks.Output(str << "faultyDisks# ");
- str << " fitsFailModel# " << (fitsFailModel ? "true" : "false");
- Cerr << str.Str() << Endl;
- }
-
- SetFailedDisks(faultyDisks);
- TLogoBlobID id;
- TString data;
- std::tie(id, data) = makeBlob();
- switch (const NKikimrProto::EReplyStatus status = PutWithResult(id, data, tactic)) {
- case NKikimrProto::OK:
- // whenever the PUT request finishes with success, the blob must be actually written and should
- // be restored in any case while fitting failure model
- dataMap[id] = data;
- break;
-
- case NKikimrProto::ERROR:
- // ERROR can only be generated if the failure model is exceeded
- Y_ASSERT(!fitsFailModel);
- break;
-
- default:
- Y_FAIL("unexpected status %s", NKikimrProto::EReplyStatus_Name(status).data());
- }
- };
-
- // now write blobs under normal conditions -- not exceeding failure model
- for (const auto& faultyDisks : FaultsFittingFailModel) {
- tryOption(faultyDisks, true);
- }
-
- // perform writes while exceeding the failure model
- for (const auto& faultyDisks : FaultsExceedingFailModel) {
- tryOption(faultyDisks, false);
- }
-
- // ensure we can read all the confirmed, thus successfully written blobs
- for (const auto& faultyDisks : FaultsFittingFailModel) {
- SetFailedDisks(faultyDisks);
- for (const auto& kv : dataMap) {
- CheckBlob(kv.first, false, NKikimrProto::OK, kv.second);
- }
- }
- }
- }
-};
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_fault_tolerance_ut_base.h"
+
+namespace NKikimr {
+
+class TPutFaultToleranceTest : public TFaultToleranceTestBase<TPutFaultToleranceTest> {
+public:
+ using TFaultToleranceTestBase::TFaultToleranceTestBase;
+
+ void RunTestAction() {
+ ui32 index = 1;
+
+ for (const TEvBlobStorage::TEvPut::ETactic tactic : {TEvBlobStorage::TEvPut::TacticMinLatency,
+ TEvBlobStorage::TEvPut::TacticMaxThroughput}) {
+ auto makeBlob = [&index] {
+ TString data = Sprintf("#%" PRIu32, index);
+ while (data.size() < 4096) {
+ data += data;
+ }
+ TLogoBlobID id(1, 1, index++, 0, data.size(), 0);
+ return std::make_tuple(id, data);
+ };
+
+ THashMap<TLogoBlobID, TString> dataMap;
+
+ auto tryOption = [&](const auto& faultyDisks, bool fitsFailModel) {
+ if (IsVerbose) {
+ TStringStream str;
+ faultyDisks.Output(str << "faultyDisks# ");
+ str << " fitsFailModel# " << (fitsFailModel ? "true" : "false");
+ Cerr << str.Str() << Endl;
+ }
+
+ SetFailedDisks(faultyDisks);
+ TLogoBlobID id;
+ TString data;
+ std::tie(id, data) = makeBlob();
+ switch (const NKikimrProto::EReplyStatus status = PutWithResult(id, data, tactic)) {
+ case NKikimrProto::OK:
+ // whenever the PUT request finishes with success, the blob must be actually written and should
+ // be restored in any case while fitting failure model
+ dataMap[id] = data;
+ break;
+
+ case NKikimrProto::ERROR:
+ // ERROR can only be generated if the failure model is exceeded
+ Y_ASSERT(!fitsFailModel);
+ break;
+
+ default:
+ Y_FAIL("unexpected status %s", NKikimrProto::EReplyStatus_Name(status).data());
+ }
+ };
+
+ // now write blobs under normal conditions -- not exceeding failure model
+ for (const auto& faultyDisks : FaultsFittingFailModel) {
+ tryOption(faultyDisks, true);
+ }
+
+ // perform writes while exceeding the failure model
+ for (const auto& faultyDisks : FaultsExceedingFailModel) {
+ tryOption(faultyDisks, false);
+ }
+
+ // ensure we can read all the confirmed, thus successfully written blobs
+ for (const auto& faultyDisks : FaultsFittingFailModel) {
+ SetFailedDisks(faultyDisks);
+ for (const auto& kv : dataMap) {
+ CheckBlob(kv.first, false, NKikimrProto::OK, kv.second);
+ }
+ }
+ }
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_range.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_range.h
index c055d68eabb..320f248d208 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_range.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_range.h
@@ -1,127 +1,127 @@
-#pragma once
-
-#include "defs.h"
-#include "dsproxy_fault_tolerance_ut_base.h"
-
+#pragma once
+
+#include "defs.h"
+#include "dsproxy_fault_tolerance_ut_base.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
-#include <util/random/fast.h>
-
-namespace NKikimr {
-
-class TRangeFaultToleranceTest : public TFaultToleranceTestBase<TRangeFaultToleranceTest> {
-public:
- using TFaultToleranceTestBase::TFaultToleranceTestBase;
-
+#include <util/random/fast.h>
+
+namespace NKikimr {
+
+class TRangeFaultToleranceTest : public TFaultToleranceTestBase<TRangeFaultToleranceTest> {
+public:
+ using TFaultToleranceTestBase::TFaultToleranceTestBase;
+
void Check(ui64 tabletId, const TBlobStorageGroupInfo::TGroupVDisks& disks,
NKikimrProto::EReplyStatus defaultExpectedStatus = NKikimrProto::OK) {
// Cerr << (TStringBuilder() << "]] " << disks.ToString() << Endl);
- for (ui32 generation = 1; generation <= 4; ++generation) {
+ for (ui32 generation = 1; generation <= 4; ++generation) {
NKikimrProto::EReplyStatus expectedStatus = defaultExpectedStatus;
TVector<TEvBlobStorage::TEvRangeResult::TResponse> expectedResponse;
-
- ui32 statusMap = generation - 1;
-
+
+ ui32 statusMap = generation - 1;
+
CTEST << "tabletId# " << tabletId << " generation# " << generation << " statusMap#";
-
- for (ui32 step = 1; step <= 2; ++step) {
+
+ for (ui32 step = 1; step <= 2; ++step) {
TString buffer = Sprintf("%256s/%" PRIu64 "/%" PRIu32 "/%" PRIu32, "kikimr", tabletId, generation, step);
TStringBuilder b;
for (int i = 0; i < 1024; ++i) {
b << 'a';
}
buffer += b;
- TLogoBlobID id(tabletId, generation, step, 0 /*channel*/, buffer.size(), 0);
+ TLogoBlobID id(tabletId, generation, step, 0 /*channel*/, buffer.size(), 0);
if (defaultExpectedStatus == NKikimrProto::OK) {
UNIT_ASSERT_VALUES_EQUAL(NKikimrProto::OK, PutWithResult(id, buffer, TEvBlobStorage::TEvPut::TacticMaxThroughput));
} else {
PutWithResult(id, buffer, TEvBlobStorage::TEvPut::TacticMaxThroughput);
}
-
- TBlobStorageGroupInfo::TVDiskIds vdisks;
- TBlobStorageGroupInfo::TServiceIds services;
- Info->PickSubgroup(id.Hash(), &vdisks, &services);
-
- enum {
- Lost,
- Unconfirmed,
- Max
- };
- const ui32 blobStatus = statusMap % Max;
- statusMap /= Max;
-
- switch (blobStatus) {
- case Lost:
+
+ TBlobStorageGroupInfo::TVDiskIds vdisks;
+ TBlobStorageGroupInfo::TServiceIds services;
+ Info->PickSubgroup(id.Hash(), &vdisks, &services);
+
+ enum {
+ Lost,
+ Unconfirmed,
+ Max
+ };
+ const ui32 blobStatus = statusMap % Max;
+ statusMap /= Max;
+
+ switch (blobStatus) {
+ case Lost:
CTEST << " Lost";
- // delete blobs from selected disks -- the data is missing, but the metadata is still here
- Delete(id, disks, false);
- break;
-
- case Unconfirmed:
+ // delete blobs from selected disks -- the data is missing, but the metadata is still here
+ Delete(id, disks, false);
+ break;
+
+ case Unconfirmed:
CTEST << " Unconfirmed";
- // wipe out blobs from selected disks, including any metadata
- Delete(id, disks, true);
- break;
-
- default:
- Y_FAIL();
- }
-
- // now collect information about actually written replicas
- ui32 writtenPartsMask = 0;
+ // wipe out blobs from selected disks, including any metadata
+ Delete(id, disks, true);
+ break;
+
+ default:
+ Y_FAIL();
+ }
+
+ // now collect information about actually written replicas
+ ui32 writtenPartsMask = 0;
TSubgroupPartLayout layout;
- for (ui32 i = 0; i < vdisks.size(); ++i) {
- auto event = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdisks[i], TInstant::Max(),
+ for (ui32 i = 0; i < vdisks.size(); ++i) {
+ auto event = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdisks[i], TInstant::Max(),
NKikimrBlobStorage::FastRead, TEvBlobStorage::TEvVGet::EFlags::None, {i}, {id});
- GetActorContext().Send(services[i], event.release());
- }
- for (ui32 i = 0; i < vdisks.size(); ++i) {
- auto event = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
+ GetActorContext().Send(services[i], event.release());
+ }
+ for (ui32 i = 0; i < vdisks.size(); ++i) {
+ auto event = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
// Cerr << (TStringBuilder() << "]] Get: " << event->Get()->ToString() << Endl);
- if (event->Get()->Record.GetStatus() == NKikimrProto::OK) {
- for (const auto& item : event->Get()->Record.GetResult()) {
- if (item.GetStatus() == NKikimrProto::OK) {
- TLogoBlobID partId(LogoBlobIDFromLogoBlobID(item.GetBlobID()));
- Y_VERIFY(partId.PartId() > 0);
- Y_VERIFY(partId.FullID() == id);
- writtenPartsMask |= 1 << (partId.PartId() - 1);
+ if (event->Get()->Record.GetStatus() == NKikimrProto::OK) {
+ for (const auto& item : event->Get()->Record.GetResult()) {
+ if (item.GetStatus() == NKikimrProto::OK) {
+ TLogoBlobID partId(LogoBlobIDFromLogoBlobID(item.GetBlobID()));
+ Y_VERIFY(partId.PartId() > 0);
+ Y_VERIFY(partId.FullID() == id);
+ writtenPartsMask |= 1 << (partId.PartId() - 1);
layout.AddItem(event->Get()->Record.GetCookie(), partId.PartId() - 1, Info->Type);
- }
- }
- }
- }
-
- // figure out if it is possible to restore this blob
- const bool restorable = Info->GetQuorumChecker().GetBlobState(layout, {&Info->GetTopology()}) &
- TBlobStorageGroupInfo::EBSF_RECOVERABLE;
- if (restorable) {
+ }
+ }
+ }
+ }
+
+ // figure out if it is possible to restore this blob
+ const bool restorable = Info->GetQuorumChecker().GetBlobState(layout, {&Info->GetTopology()}) &
+ TBlobStorageGroupInfo::EBSF_RECOVERABLE;
+ if (restorable) {
CTEST << "/Y";
- expectedResponse.emplace_back(id, buffer);
- } else {
+ expectedResponse.emplace_back(id, buffer);
+ } else {
CTEST << "/N(" << writtenPartsMask << ")";
- switch (blobStatus) {
- case Lost:
- // FIXME: uncomment when KIKIMR-2271 is done
-// expectedStatus = NKikimrProto::ERROR;
- break;
-
- case Unconfirmed:
- // this blob will not fit into result at all
- break;
- }
- }
- }
-
+ switch (blobStatus) {
+ case Lost:
+ // FIXME: uncomment when KIKIMR-2271 is done
+// expectedStatus = NKikimrProto::ERROR;
+ break;
+
+ case Unconfirmed:
+ // this blob will not fit into result at all
+ break;
+ }
+ }
+ }
+
CTEST << Endl;
-
- auto query = std::make_unique<TEvBlobStorage::TEvRange>(tabletId, TLogoBlobID(tabletId, generation, 0, 0, 0, 0),
- TLogoBlobID(tabletId, generation, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie),
- false, TInstant::Max());
- SendToBSProxy(GetActorContext(), Info->GroupID, query.release());
- auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvRangeResult>();
+
+ auto query = std::make_unique<TEvBlobStorage::TEvRange>(tabletId, TLogoBlobID(tabletId, generation, 0, 0, 0, 0),
+ TLogoBlobID(tabletId, generation, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie),
+ false, TInstant::Max());
+ SendToBSProxy(GetActorContext(), Info->GroupID, query.release());
+ auto resp = WaitForSpecificEvent<TEvBlobStorage::TEvRangeResult>();
CTEST << resp->Get()->ToString() << Endl;
- UNIT_ASSERT_VALUES_EQUAL(resp->Get()->Status, expectedStatus);
- if (expectedStatus == NKikimrProto::OK) {
+ UNIT_ASSERT_VALUES_EQUAL(resp->Get()->Status, expectedStatus);
+ if (expectedStatus == NKikimrProto::OK) {
auto it1 = resp->Get()->Responses.begin();
auto it2 = expectedResponse.begin();
@@ -134,29 +134,29 @@ public:
++it1;
++it2;
}
- }
+ }
UNIT_ASSERT(it2 == expectedResponse.end());
- }
- }
- }
-
- void RunTestAction() {
- ui64 tabletId = 100500;
- for (const auto& disks : FaultsFittingFailModel) {
- Check(tabletId++, disks);
- }
- for (const auto& disks : FaultsExceedingFailModel) {
- Check(tabletId++, disks);
- }
- for (const auto& disks : FaultsFittingFailModel) {
- SetFailedDisks(disks);
- Check(tabletId++, TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology()));
- }
+ }
+ }
+ }
+
+ void RunTestAction() {
+ ui64 tabletId = 100500;
+ for (const auto& disks : FaultsFittingFailModel) {
+ Check(tabletId++, disks);
+ }
+ for (const auto& disks : FaultsExceedingFailModel) {
+ Check(tabletId++, disks);
+ }
+ for (const auto& disks : FaultsFittingFailModel) {
+ SetFailedDisks(disks);
+ Check(tabletId++, TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology()));
+ }
for (const auto& disks : FaultsExceedingFailModel) {
SetFailedDisks(disks);
Check(tabletId++, TBlobStorageGroupInfo::TGroupVDisks(&Info->GetTopology()), NKikimrProto::ERROR);
}
- }
-};
-
-} // NKikimr
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
index bc33af4b86c..0c183425b3b 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_fault_tolerance_ut_runtime.h
@@ -1,7 +1,7 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/base/appdata.h>
#include <library/cpp/actors/core/executor_pool_basic.h>
#include <library/cpp/actors/core/executor_pool_io.h>
@@ -17,28 +17,28 @@
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h>
#include <util/system/sanitizers.h>
-
-namespace NKikimr {
-
-class TFaultToleranceTestRuntime {
-public:
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
+
+namespace NKikimr {
+
+class TFaultToleranceTestRuntime {
+public:
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
TVector<std::pair<TVDiskID, TActorId>> VDisks;
- std::unique_ptr<TAppData> AppData;
- std::unique_ptr<TActorSystem> ActorSystem;
+ std::unique_ptr<TAppData> AppData;
+ std::unique_ptr<TActorSystem> ActorSystem;
TProgramShouldContinue KikimrShouldContinue;
-
- void Setup(TBlobStorageGroupType groupType, ui32 numFailDomains, ui32 numVDisksPerFailDomain, ui32 numRealms) {
- Counters = new NMonitoring::TDynamicCounters;
-
+
+ void Setup(TBlobStorageGroupType groupType, ui32 numFailDomains, ui32 numVDisksPerFailDomain, ui32 numRealms) {
+ Counters = new NMonitoring::TDynamicCounters;
+
TIntrusivePtr<NScheme::TTypeRegistry> typeRegistry(new NScheme::TKikimrTypeRegistry());
auto functionRegistry = NKikimr::NMiniKQL::CreateFunctionRegistry(NKikimr::NMiniKQL::CreateBuiltinRegistry());
- AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(), functionRegistry.Get(), nullptr, &KikimrShouldContinue));
- AppData->Counters = Counters;
-
+ AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(), functionRegistry.Get(), nullptr, &KikimrShouldContinue));
+ AppData->Counters = Counters;
+
NActors::TActorId loggerActorId = TActorId(1, "logger");
- TIntrusivePtr<NLog::TSettings> logSettings = new NLog::TSettings(loggerActorId, NKikimrServices::LOGGER,
+ TIntrusivePtr<NLog::TSettings> logSettings = new NLog::TSettings(loggerActorId, NKikimrServices::LOGGER,
(IsVerbose ? NLog::PRI_NOTICE : NLog::PRI_CRIT),
NLog::PRI_DEBUG, 0);
logSettings->Append(
@@ -52,55 +52,55 @@ public:
NKikimrServices::EServiceKikimr_Name
);
// TString explanation;
-// logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_PROXY_GET, explanation);
-// logSettings->SetLevel(NLog::PRI_DEBUG, NActorsServices::TEST, explanation);
-
- GroupInfo.Reset(new TBlobStorageGroupInfo(groupType, numVDisksPerFailDomain, numFailDomains, numRealms));
-
- for (const auto& vdisk : GroupInfo->GetVDisks()) {
+// logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_PROXY_GET, explanation);
+// logSettings->SetLevel(NLog::PRI_DEBUG, NActorsServices::TEST, explanation);
+
+ GroupInfo.Reset(new TBlobStorageGroupInfo(groupType, numVDisksPerFailDomain, numFailDomains, numRealms));
+
+ for (const auto& vdisk : GroupInfo->GetVDisks()) {
auto vd = GroupInfo->GetVDiskId(vdisk.OrderNumber);
VDisks.emplace_back(vd, GroupInfo->GetActorId(vdisk.OrderNumber));
- }
-
- auto setup = MakeHolder<TActorSystemSetup>();
+ }
+
+ auto setup = MakeHolder<TActorSystemSetup>();
constexpr int maxSize = NSan::TSanIsOn() ? 1: 10;
- setup->NodeId = 1;
- setup->ExecutorsCount = 4;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[4]);
+ setup->NodeId = 1;
+ setup->ExecutorsCount = 4;
+ setup->Executors.Reset(new TAutoPtr<IExecutorPool>[4]);
setup->Executors[0].Reset(new TBasicExecutorPool(0, Min(8, maxSize), 20));
setup->Executors[1].Reset(new TBasicExecutorPool(1, 8, 20));
setup->Executors[2].Reset(new TIOExecutorPool(2, 10));
setup->Executors[3].Reset(new TBasicExecutorPool(3, 8, 20));
- setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 1000)));
-
- setup->LocalServices.emplace_back(loggerActorId, TActorSetupCmd(new TLoggerActor(logSettings,
- CreateStderrBackend(), Counters->GetSubgroup("logger", "counters")), TMailboxType::Simple, 0));
-
- auto shared = MakeIntrusive<TVDiskMockSharedState>(GroupInfo);
- for (const auto& pair : VDisks) {
+ setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 1000)));
+
+ setup->LocalServices.emplace_back(loggerActorId, TActorSetupCmd(new TLoggerActor(logSettings,
+ CreateStderrBackend(), Counters->GetSubgroup("logger", "counters")), TMailboxType::Simple, 0));
+
+ auto shared = MakeIntrusive<TVDiskMockSharedState>(GroupInfo);
+ for (const auto& pair : VDisks) {
setup->LocalServices.emplace_back(pair.second,
TActorSetupCmd(CreateVDiskMockActor(pair.first, shared, GroupInfo->PickTopology()),
- TMailboxType::Simple, 0));
- }
+ TMailboxType::Simple, 0));
+ }
TIntrusivePtr<TDsProxyNodeMon> nodeMon(new TDsProxyNodeMon(Counters, true));
TDsProxyPerPoolCounters perPoolCounters(Counters);
TIntrusivePtr<TStoragePoolCounters> storagePoolCounters = perPoolCounters.GetPoolCounters("pool_name");
TControlWrapper enablePutBatching(DefaultEnablePutBatching, false, true);
TControlWrapper enableVPatch(DefaultEnableVPatch, false, true);
- IActor *dsproxy = CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(GroupInfo), false, nodeMon,
- std::move(storagePoolCounters), enablePutBatching, enableVPatch);
+ IActor *dsproxy = CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(GroupInfo), false, nodeMon,
+ std::move(storagePoolCounters), enablePutBatching, enableVPatch);
setup->LocalServices.emplace_back(MakeBlobStorageProxyID(GroupInfo->GroupID),
TActorSetupCmd(dsproxy, TMailboxType::Simple, 0));
-
- ActorSystem.reset(new TActorSystem(setup, AppData.get(), logSettings));
- LOG_NOTICE(*ActorSystem, NActorsServices::TEST, "Actor system created");
- ActorSystem->Start();
- }
-
- void Finish() {
- ActorSystem->Stop();
- ActorSystem.reset();
- }
-};
-
-} // NKikimr
+
+ ActorSystem.reset(new TActorSystem(setup, AppData.get(), logSettings));
+ LOG_NOTICE(*ActorSystem, NActorsServices::TEST, "Actor system created");
+ ActorSystem->Start();
+ }
+
+ void Finish() {
+ ActorSystem->Stop();
+ ActorSystem.reset();
+ }
+};
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_get_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_get_ut.cpp
index 85e16c2aef3..b1b28231c81 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_get_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_get_ut.cpp
@@ -37,7 +37,7 @@ void TestIntervalsAndCrcAllOk(TErasureType::EErasureSpecies erasureSpecies, bool
const ui32 domainCount = groupType.BlobSubgroupSize();
TGroupMock group(groupId, erasureSpecies, domainCount, 1);
- TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
const ui64 maxQueryCount = 32;
@@ -71,11 +71,11 @@ void TestIntervalsAndCrcAllOk(TErasureType::EErasureSpecies erasureSpecies, bool
TEvBlobStorage::TEvGet ev(queriesA, queryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::FastRead, false, false);
ev.IsVerboseNoDataEnabled = isVerboseNoDataEnabled;
- TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
- logCtx.LogAcc.IsLogEnabled = false;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
+ logCtx.LogAcc.IsLogEnabled = false;
+ getImpl.GenerateInitialRequests(logCtx, vGets);
if (IsVerbose) {
for (ui32 i = 0; i < vGets.size(); ++i) {
@@ -92,8 +92,8 @@ void TestIntervalsAndCrcAllOk(TErasureType::EErasureSpecies erasureSpecies, bool
group.OnVGet(*vGets[vGetIdx], vGetResult);
// TODO: generate result
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
if (IsVerbose) {
for (ui32 i = 0; i < nextVGets.size(); ++i) {
@@ -190,7 +190,7 @@ public:
private:
TMaybe<TGroupMock> Group;
- TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
TMaybe<TBlobTestSet> BlobSet;
ui64 VPutRequests = 0;
@@ -259,7 +259,7 @@ public:
SendVPuts.clear();
Group.Clear();
Group.ConstructInPlace(GroupId, ErasureSpecies, DomainCount, 1);
- GroupQueues = Group->MakeGroupQueues();
+ GroupQueues = Group->MakeGroupQueues();
BlobSet.Clear();
BlobSet.ConstructInPlace();
if (Blobs) {
@@ -303,7 +303,7 @@ private:
}
void ProcessVPuts(TLogContext &logCtx, TGetImpl &getImpl,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &vPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &vPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &getResult) {
for (ui64 vPutIdx = 0; vPutIdx < vPuts.size(); ++vPutIdx) {
auto &putRequest = vPuts[vPutIdx]->Record;
@@ -313,18 +313,18 @@ private:
TBlobCookie cookie(putRequest.GetCookie());
SendVPuts.push_back({vdisk, blobId, cookie.GetBlobIdx()});
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
VPutResponses++;
RequestIndex += nextVGets.size();
VPutRequests += nextVPuts.size();
AssertCounters(getImpl);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -333,7 +333,7 @@ private:
}
void ProcessVPuts(TLogContext &logCtx, TGetImpl &getImpl,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &vPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> &vGets, TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &vPuts,
TAutoPtr<TEvBlobStorage::TEvGetResult> &getResult) {
for (ui64 vPutIdx = 0; vPutIdx < vPuts.size(); ++vPutIdx) {
auto &multiPutRequest = vPuts[vPutIdx]->Record;
@@ -353,10 +353,10 @@ private:
UNIT_ASSERT(sendBytes <= MaxBatchedPutSize);
TEvBlobStorage::TEvVMultiPutResult vMultiPutResult;
- vMultiPutResult.MakeError(NKikimrProto::OK, TString(), multiPutRequest);
+ vMultiPutResult.MakeError(NKikimrProto::OK, TString(), multiPutRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> nextVPuts;
getImpl.OnVPutResult(logCtx, vMultiPutResult,
nextVGets, nextVPuts, getResult);
VMultiPutResponses++;
@@ -364,8 +364,8 @@ private:
VMultiPutRequests += nextVPuts.size();
AssertCounters(getImpl);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -391,10 +391,10 @@ private:
TEvBlobStorage::TEvGet ev(queriesA, queryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::FastRead, IsRestore, false);
ev.IsVerboseNoDataEnabled = IsVerboseNoDataEnabled;
- TGetImpl getImpl(Group->GetInfo(), GroupQueues, &ev, nullptr);
+ TGetImpl getImpl(Group->GetInfo(), GroupQueues, &ev, nullptr);
ClearCounters();
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TVPutEvent>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TVPutEvent>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
getImpl.GenerateInitialRequests(logCtx, vGets);
@@ -412,8 +412,8 @@ private:
Group->OnVGet(*vGets[vGetIdx], vGetResult);
// TODO: generate result
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TVPutEvent>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TVPutEvent>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
ResponseIndex++;
RequestIndex += nextVGets.size();
@@ -424,9 +424,9 @@ private:
}
AssertCounters(getImpl);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
if (IsRestore) {
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
} else {
UNIT_ASSERT_VALUES_EQUAL(nextVPuts.size(), 0);
}
@@ -461,7 +461,7 @@ void TestIntervalsWipedAllOk(TErasureType::EErasureSpecies erasureSpecies, bool
const ui32 groupId = 0;
TBlobStorageGroupType groupType(erasureSpecies);
- const ui32 domainCount = groupType.BlobSubgroupSize();
+ const ui32 domainCount = groupType.BlobSubgroupSize();
TVector<ui64> queryCounts = {1, 2, 3, 13, 34};
@@ -493,7 +493,7 @@ void TestIntervalsWipedAllOkVMultiPut(TErasureType::EErasureSpecies erasureSpeci
const ui32 groupId = 0;
TBlobStorageGroupType groupType(erasureSpecies);
- const ui32 domainCount = groupType.BlobSubgroupSize();
+ const ui32 domainCount = groupType.BlobSubgroupSize();
TVector<ui64> queryCounts = {1, 2, 3, 13, 34, 55};
@@ -526,7 +526,7 @@ void TestIntervalsWipedAllOkComparisonVMultiPutAndVPut(TErasureType::EErasureSpe
const ui32 groupId = 0;
TBlobStorageGroupType groupType(erasureSpecies);
- const ui32 domainCount = groupType.BlobSubgroupSize();
+ const ui32 domainCount = groupType.BlobSubgroupSize();
const TVector<ui64> queryCounts = {1, 2};
@@ -577,15 +577,15 @@ void TestIntervalsWipedAllOkComparisonVMultiPutAndVPut(TErasureType::EErasureSpe
class TGetSimulator {
TGroupMock Group;
- TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
public:
TBlobTestSet BlobSet;
TGetSimulator(ui32 groupId, TErasureType::EErasureSpecies erasureSpecies, ui32 failDomains,
ui32 drivesPerFailDomain)
- : Group(groupId, erasureSpecies, failDomains, drivesPerFailDomain)
- , GroupQueues(Group.MakeGroupQueues())
- {}
+ : Group(groupId, erasureSpecies, failDomains, drivesPerFailDomain)
+ , GroupQueues(Group.MakeGroupQueues())
+ {}
void GenerateBlobSet(ui32 setIdx, ui32 count, ui32 forceSize = 0) {
BlobSet.GenerateSet(setIdx, count, forceSize);
@@ -605,19 +605,19 @@ public:
Group.SetPredictedDelayNs(domainIdx, predictedDelayNs);
}
- TIntrusivePtr<TGroupQueues> GetSessionsState() const {
- return GroupQueues;
+ TIntrusivePtr<TGroupQueues> GetSessionsState() const {
+ return GroupQueues;
}
TAutoPtr<TEvBlobStorage::TEvGetResult> Simulate(TEvBlobStorage::TEvGet *ev) {
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- TGetImpl getImpl(Group.GetInfo(), GroupQueues, ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TGetImpl getImpl(Group.GetInfo(), GroupQueues, ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ getImpl.GenerateInitialRequests(logCtx, vGets);
for (ui64 vGetIdx = 0; vGetIdx < vGets.size(); ++vGetIdx) {
@@ -628,12 +628,12 @@ public:
Group.OnVGet(*vGets[vGetIdx], vGetResult);
// TODO: generate result
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
if (ev->MustRestoreFirst) {
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
} else {
UNIT_ASSERT_VALUES_EQUAL(nextVPuts.size(), 0);
}
@@ -644,13 +644,13 @@ public:
auto &putRequest = vPuts[vPutIdx]->Record;
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
- getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -696,7 +696,7 @@ Y_UNIT_TEST(TestBlock42VGetCountWithErasure) {
const ui32 isRestore = 0;
TGroupMock group(groupId, erasureSpecies, domainCount, 1);
- TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
TBlobTestSet blobSet;
blobSet.AddBlobs(blobs);
group.PutBlobSet(blobSet);
@@ -726,16 +726,16 @@ Y_UNIT_TEST(TestBlock42VGetCountWithErasure) {
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
getImpl.GenerateInitialRequests(logCtx, vGets);
for (ui64 vGetIdx = 0; vGetIdx < vGets.size(); ++vGetIdx) {
if (vGetIdx == 3) {
- vGets.push_back(std::move(vGets[3]));
+ vGets.push_back(std::move(vGets[3]));
continue;
}
bool isLast = (vGetIdx == vGets.size() - 1);
@@ -746,14 +746,14 @@ Y_UNIT_TEST(TestBlock42VGetCountWithErasure) {
group.OnVGet(*vGets[vGetIdx], vGetResult);
// TODO: generate result
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
if (ev.MustRestoreFirst) {
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
} else {
UNIT_ASSERT_VALUES_EQUAL(nextVPuts.size(), 0);
}
@@ -764,13 +764,13 @@ Y_UNIT_TEST(TestBlock42VGetCountWithErasure) {
auto &putRequest = vPuts[vPutIdx]->Record;
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -839,7 +839,7 @@ Y_UNIT_TEST(TestBlock42WipedOneDiskAndErrorDurringGet) {
const ui32 isRestore = 0;
TGroupMock group(groupId, erasureSpecies, domainCount, 1);
- TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
TBlobTestSet blobSet;
blobSet.AddBlobs(blobs);
group.PutBlobSet(blobSet);
@@ -869,16 +869,16 @@ Y_UNIT_TEST(TestBlock42WipedOneDiskAndErrorDurringGet) {
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
getImpl.GenerateInitialRequests(logCtx, vGets);
for (ui64 vGetIdx = 0; vGetIdx < vGets.size(); ++vGetIdx) {
if (vGetIdx == 3) {
- vGets.push_back(std::move(vGets[3]));
+ vGets.push_back(std::move(vGets[3]));
continue;
}
if (vGetIdx == 5) {
@@ -892,14 +892,14 @@ Y_UNIT_TEST(TestBlock42WipedOneDiskAndErrorDurringGet) {
TEvBlobStorage::TEvVGetResult vGetResult;
group.OnVGet(*vGets[vGetIdx], vGetResult);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
if (ev.MustRestoreFirst) {
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
} else {
UNIT_ASSERT_VALUES_EQUAL(nextVPuts.size(), 0);
}
@@ -910,13 +910,13 @@ Y_UNIT_TEST(TestBlock42WipedOneDiskAndErrorDurringGet) {
auto &putRequest = vPuts[vPutIdx]->Record;
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -976,7 +976,7 @@ void TestIntervalsWipedError(TErasureType::EErasureSpecies erasureSpecies, bool
const ui32 groupId = 0;
TBlobStorageGroupType groupType(erasureSpecies);
- const ui32 domainCount = groupType.BlobSubgroupSize();
+ const ui32 domainCount = groupType.BlobSubgroupSize();
const ui64 maxQueryCount = 13;
const ui64 queryCounts[] = {1, 2, 3, 13};
@@ -1109,7 +1109,7 @@ void TestWipedErrorWithTwoBlobs(TErasureType::EErasureSpecies erasureSpecies, bo
for (ui64 it = 0; it < 100; ++it, ++seed) {
SetRandomSeed(seed);
TGroupMock group(groupId, erasureSpecies, domainCount, 1);
- TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
TBlobTestSet blobSet;
blobSet.AddBlobs(blobs);
group.PutBlobSet(blobSet);
@@ -1143,9 +1143,9 @@ void TestWipedErrorWithTwoBlobs(TErasureType::EErasureSpecies erasureSpecies, bo
TAutoPtr<TEvBlobStorage::TEvGetResult> getResult;
- TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TGetImpl getImpl(group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
getImpl.GenerateInitialRequests(logCtx, vGets);
@@ -1166,14 +1166,14 @@ void TestWipedErrorWithTwoBlobs(TErasureType::EErasureSpecies erasureSpecies, bo
group.OnVGet(*vGets[vGetIdx], vGetResult);
// TODO: generate result
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
if (ev.MustRestoreFirst) {
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
} else {
UNIT_ASSERT_VALUES_EQUAL(nextVPuts.size(), 0);
}
@@ -1184,13 +1184,13 @@ void TestWipedErrorWithTwoBlobs(TErasureType::EErasureSpecies erasureSpecies, bo
auto &putRequest = vPuts[vPutIdx]->Record;
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
- std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVGets.begin(), nextVGets.end(), std::back_inserter(vGets));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -1283,7 +1283,7 @@ void SpecificTest(ui32 badA, ui32 badB, ui32 blobSize, TMap<i64, i64> sizeForOff
const ui32 groupId = 0;
TBlobStorageGroupType groupType(erasureSpecies);
- const ui32 domainCount = groupType.BlobSubgroupSize();
+ const ui32 domainCount = groupType.BlobSubgroupSize();
TGetSimulator simulator(groupId, erasureSpecies, domainCount, 1);
simulator.GenerateBlobSet(0, 1, blobSize);
@@ -1386,15 +1386,15 @@ class TTestPossibleBlobLost {
queriesB[queryIdx] = q;
VERBOSE("query# " << queryIdx << " shift# " << q.Shift << " size# " << q.Size);
}
- TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
TEvBlobStorage::TEvGet ev(queriesA, MaxQueryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::Discover, true, false);
ev.IsVerboseNoDataEnabled = false;
- TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ getImpl.GenerateInitialRequests(logCtx, vGets);
return vGets.size();
}
@@ -1451,16 +1451,16 @@ public:
VERBOSE("query# " << queryIdx << " shift# " << q.Shift << " size# " << q.Size);
}
- TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
TEvBlobStorage::TEvGet ev(queriesA, MaxQueryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::Discover, true, false);
ev.IsVerboseNoDataEnabled = false;
- TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ getImpl.GenerateInitialRequests(logCtx, vGets);
for (ui32 i = 0; i < ErroneousVDisks.size(); ++i) {
if (ErroneousVDisks[i] == NKikimrProto::OK) {
Group.UnsetError(i);
@@ -1481,25 +1481,25 @@ public:
Group.OnVGet(*vGets[vGetIdx], vGetResult);
VERBOSE("vGetResult.ToString()# " << vGetResult.ToString());
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
for (ui64 i = 0; i < nextVPuts.size(); ++i) {
auto &vDiskID = nextVPuts[i]->Record.GetVDiskID();
VERBOSE("Additional TEvVPut to VDiskID# " << VDiskIDFromVDiskID(vDiskID));
- vPuts.push_back(std::move(nextVPuts[i]));
+ vPuts.push_back(std::move(nextVPuts[i]));
}
for (ui64 vPutIdx = 0; vPutIdx < vPuts.size(); ++vPutIdx) {
auto &putRequest = vPuts[vPutIdx]->Record;
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
- getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
UNIT_ASSERT_C(nextVGets.empty(), currentTestState.Str());
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
@@ -1507,7 +1507,7 @@ public:
for (ui64 i = 0; i < nextVGets.size(); ++i) {
auto &vDiskID = nextVGets[i]->Record.GetVDiskID();
VERBOSE("Additional TEvVGet to VDiskID# " << VDiskIDFromVDiskID(vDiskID));
- vGets.push_back(std::move(nextVGets[i]));
+ vGets.push_back(std::move(nextVGets[i]));
RequestsOrder.push_back(RequestsOrder.size());
}
if (getResult) {
@@ -1600,15 +1600,15 @@ protected:
queriesB[queryIdx] = q;
VERBOSE("query# " << queryIdx << " shift# " << q.Shift << " size# " << q.Size);
}
- TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
TEvBlobStorage::TEvGet ev(queriesA, MaxQueryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::Discover, true, false);
ev.IsVerboseNoDataEnabled = false;
- TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ getImpl.GenerateInitialRequests(logCtx, vGets);
return vGets.size();
}
@@ -1665,16 +1665,16 @@ public:
VERBOSE("query# " << queryIdx << " shift# " << q.Shift << " size# " << q.Size);
}
- TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = Group.MakeGroupQueues();
TLogContext logCtx(NKikimrServices::BS_PROXY_GET, false);
logCtx.LogAcc.IsLogEnabled = false;
TEvBlobStorage::TEvGet ev(queriesA, MaxQueryCount, TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::Discover, true, false);
ev.IsVerboseNoDataEnabled = false;
- TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
- getImpl.GenerateInitialRequests(logCtx, vGets);
+ TGetImpl getImpl(Group.GetInfo(), groupQueues, &ev, nullptr);
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> vGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ getImpl.GenerateInitialRequests(logCtx, vGets);
for (ui64 vDIdx = 0; vDIdx < requestOrder.size(); ++vDIdx) {
const ui64 domainIdx = requestOrder[vDIdx];
@@ -1693,19 +1693,19 @@ public:
Group.OnVGet(*vGets[vGetIdx], vGetResult);
VERBOSE("vGetResult.ToString()# " << vGetResult.ToString());
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
getImpl.OnVGetResult(logCtx, vGetResult, nextVGets, nextVPuts, getResult);
for (ui64 i = 0; i < nextVPuts.size(); ++i) {
auto &vDiskID = nextVPuts[i]->Record.GetVDiskID();
VERBOSE("Additional TEvVPut to VDiskID# " << VDiskIDFromVDiskID(vDiskID));
- vPuts.push_back(std::move(nextVPuts[i]));
+ vPuts.push_back(std::move(nextVPuts[i]));
}
for (ui64 i = 0; i < nextVGets.size(); ++i) {
auto &vDiskID = nextVGets[i]->Record.GetVDiskID();
VERBOSE("Additional TEvVGet to VDiskID# " << VDiskIDFromVDiskID(vDiskID));
- vGets.push_back(std::move(nextVGets[i]));
+ vGets.push_back(std::move(nextVGets[i]));
requestOrder.push_back(requestOrder.size());
}
if (getResult) {
@@ -1731,15 +1731,15 @@ public:
Y_VERIFY(putRequest.HasCookie());
TEvBlobStorage::TEvVPutResult vPutResult;
if (Mode == ReadAndWriteErrors && vPutIdx == 0) {
- vPutResult.MakeError(NKikimrProto::ERROR, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::ERROR, TString(), putRequest);
} else {
- vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
+ vPutResult.MakeError(NKikimrProto::OK, TString(), putRequest);
}
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
- getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVGet>> nextVGets;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ getImpl.OnVPutResult(logCtx, vPutResult, nextVGets, nextVPuts, getResult);
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
if (getResult) {
break;
}
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_patch_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_patch_ut.cpp
index 74bd0ed7ee8..a00b360069b 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_patch_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_patch_ut.cpp
@@ -270,8 +270,8 @@ NKikimrProto::EReplyStatus GetVMovedPatchResultStatus(EMovedPatchCase movedCase)
template <typename THandle, typename TEventHolder>
void SendByHandle(TTestBasicRuntime &runtime, const THandle &oldHandle, TEventHolder &&ev) {
- auto handle = std::make_unique<IEventHandle>(oldHandle->Sender, oldHandle->Recipient, ev.release(), oldHandle->Flags, oldHandle->Cookie);
- runtime.Send(handle.release());
+ auto handle = std::make_unique<IEventHandle>(oldHandle->Sender, oldHandle->Recipient, ev.release(), oldHandle->Flags, oldHandle->Cookie);
+ runtime.Send(handle.release());
}
void ReceivePatchResult(TTestBasicRuntime &runtime, const TTestArgs &args, NKikimrProto::EReplyStatus status) {
@@ -296,9 +296,9 @@ void ConductGet(TTestBasicRuntime &runtime, const TTestArgs &args, ENaivePatchCa
UNIT_ASSERT_VALUES_EQUAL(get->Queries[0].Id, args.OriginalId);
UNIT_ASSERT_VALUES_EQUAL(handle->Cookie, args.PatchedId.Hash());
- std::unique_ptr<TEvBlobStorage::TEvGetResult> getResult;
+ std::unique_ptr<TEvBlobStorage::TEvGetResult> getResult;
if (resultStatus == NKikimrProto::OK) {
- getResult = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, 1, args.CurrentGroupId);
+ getResult = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::OK, 1, args.CurrentGroupId);
if (naiveCase == ENaivePatchCase::ErrorOnGetItem) {
getResult->Responses[0].Id = args.OriginalId;
getResult->Responses[0].Status = NKikimrProto::ERROR;
@@ -308,7 +308,7 @@ void ConductGet(TTestBasicRuntime &runtime, const TTestArgs &args, ENaivePatchCa
getResult->Responses[0].Status = NKikimrProto::OK;
}
} else {
- getResult = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::ERROR, 0, args.CurrentGroupId);
+ getResult = std::make_unique<TEvBlobStorage::TEvGetResult>(NKikimrProto::ERROR, 0, args.CurrentGroupId);
}
SendByHandle(runtime, handle, std::move(getResult));
@@ -338,7 +338,7 @@ void ConductPut(TTestBasicRuntime &runtime, const TTestArgs &args, ENaivePatchCa
TString patchedBuffer = MakePatchedBuffer(args);
UNIT_ASSERT_VALUES_EQUAL(put->Buffer, patchedBuffer);
- std::unique_ptr<TEvBlobStorage::TEvPutResult> putResult = std::make_unique<TEvBlobStorage::TEvPutResult>(
+ std::unique_ptr<TEvBlobStorage::TEvPutResult> putResult = std::make_unique<TEvBlobStorage::TEvPutResult>(
resultStatus, args.PatchedId, args.StatusFlags, args.CurrentGroupId, args.ApproximateFreeSpaceShare);
SendByHandle(runtime, handle, std::move(putResult));
CTEST << "ConductPut: Finish\n";
@@ -369,7 +369,7 @@ void ConductVPatchStart(TTestBasicRuntime &runtime, const TDSProxyEnv &env, cons
TInstant now = runtime.GetCurrentTime();
UNIT_ASSERT(startRecord.HasCookie());
- std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts> foundParts = std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts> foundParts = std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(
status, args.OriginalId, args.PatchedId, vdisk, startRecord.GetCookie(), now, "", &startRecord,
nullptr, nullptr, nullptr, NWilson::TTraceId(), 0);
for (auto partId : parts) {
@@ -404,7 +404,7 @@ void ConductVPatchDiff(TTestBasicRuntime &runtime, const TDSProxyEnv &env, const
TInstant now = runtime.GetCurrentTime();
UNIT_ASSERT(diffRecord.HasCookie());
- std::unique_ptr<TEvBlobStorage::TEvVPatchResult> result = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchResult> result = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
resultStatus, args.OriginalId, args.PatchedId, vdisk, diffRecord.GetCookie(), now,
&diffRecord, nullptr, nullptr, nullptr,NWilson::TTraceId(), 0);
result->SetStatusFlagsAndFreeSpace(args.StatusFlags, args.ApproximateFreeSpaceShare);
@@ -447,7 +447,7 @@ void ConductVMovedPatch(TTestBasicRuntime &runtime, const TTestArgs &args, EMove
TVDiskID vDiskId = VDiskIDFromVDiskID(vPatchRecord.GetVDiskID());
TOutOfSpaceStatus oos(args.StatusFlags, args.ApproximateFreeSpaceShare);
- std::unique_ptr<TEvBlobStorage::TEvVMovedPatchResult> vPatchResult = std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVMovedPatchResult> vPatchResult = std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(
resultStatus, args.OriginalId, args.PatchedId, vDiskId, expectedCookie, oos,
TAppData::TimeProvider->Now(), 0, &vPatchRecord, nullptr, nullptr, nullptr, NWilson::TTraceId(), 0, TString());
@@ -517,11 +517,11 @@ TEvBlobStorage::TEvPatch::TPtr CreatePatch(TTestBasicRuntime &runtime, const TDS
diffs[diffIdx].Buffer = diff.Buffer;
}
TInstant deadline = runtime.GetCurrentTime() + TDuration::Seconds(5);
- std::unique_ptr<TEvBlobStorage::TEvPatch> patch = std::make_unique<TEvBlobStorage::TEvPatch>(
+ std::unique_ptr<TEvBlobStorage::TEvPatch> patch = std::make_unique<TEvBlobStorage::TEvPatch>(
args.OriginalGroupId, args.OriginalId, args.PatchedId, args.MaskForCookieBruteForcing, std::move(diffs),
args.Diffs.size(), deadline);
TEvBlobStorage::TEvPatch::TPtr ev(static_cast<TEventHandle<TEvBlobStorage::TEvPatch>*>(
- new IEventHandle(env.FakeProxyActorId, env.FakeProxyActorId, patch.release())));
+ new IEventHandle(env.FakeProxyActorId, env.FakeProxyActorId, patch.release())));
return ev;
}
@@ -529,8 +529,8 @@ void RunNaivePatchTest(TTestBasicRuntime &runtime, const TTestArgs &args, ENaive
TDSProxyEnv env;
env.Configure(runtime, args.GType, args.CurrentGroupId, 0);
TEvBlobStorage::TEvPatch::TPtr patch = CreatePatch(runtime, env, args);
- std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, false);
- runtime.Register(patchActor.release());
+ std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, false);
+ runtime.Register(patchActor.release());
ConductNaivePatch(runtime, args, naiveCase);
}
@@ -538,8 +538,8 @@ void RunMovedPatchTest(TTestBasicRuntime &runtime, const TTestArgs &args, EMoved
TDSProxyEnv env;
env.Configure(runtime, args.GType, args.CurrentGroupId, 0);
TEvBlobStorage::TEvPatch::TPtr patch = CreatePatch(runtime, env, args);
- std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
- runtime.Register(patchActor.release());
+ std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
+ runtime.Register(patchActor.release());
ConductMovedPatch(runtime, env, args, movedCase);
}
@@ -547,8 +547,8 @@ void RunVPatchTest(TTestBasicRuntime &runtime, const TTestArgs &args, EVPatchCas
TDSProxyEnv env;
env.Configure(runtime, args.GType, args.CurrentGroupId, 0);
TEvBlobStorage::TEvPatch::TPtr patch = CreatePatch(runtime, env, args);
- std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
- runtime.Register(patchActor.release());
+ std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
+ runtime.Register(patchActor.release());
ConductVPatch(runtime, env, args, vpatchCase);
}
@@ -741,8 +741,8 @@ void RunFaultToleranceBlock4Plus2(TTestBasicRuntime &runtime, const TTestArgs &a
TDSProxyEnv env;
env.Configure(runtime, args.GType, args.CurrentGroupId, 0);
TEvBlobStorage::TEvPatch::TPtr patch = CreatePatch(runtime, env, args);
- std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
- runtime.Register(patchActor.release());
+ std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
+ runtime.Register(patchActor.release());
ConductFaultTolerance(runtime, env, args, GetFaultToleranceCaseForBlock4Plus2(env, args));
}
@@ -750,8 +750,8 @@ void RunFaultToleranceMirror3dc(TTestBasicRuntime &runtime, const TTestArgs &arg
TDSProxyEnv env;
env.Configure(runtime, args.GType, args.CurrentGroupId, 0);
TEvBlobStorage::TEvPatch::TPtr patch = CreatePatch(runtime, env, args);
- std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
- runtime.Register(patchActor.release());
+ std::unique_ptr<IActor> patchActor = env.CreatePatchRequestActor(patch, true);
+ runtime.Register(patchActor.release());
ConductFaultTolerance(runtime, env, args, GetFaultToleranceCaseForMirror3dc(env, args));
}
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_put_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_put_ut.cpp
index d2d39a35504..be9bd525d2a 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_put_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_put_ut.cpp
@@ -36,7 +36,7 @@ void TestPutMaxPartCountOnHandoff(TErasureType::EErasureSpecies erasureSpecies)
const ui32 domainCount = groupType.BlobSubgroupSize();;
TGroupMock group(groupId, erasureSpecies, domainCount, 1);
- TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
+ TIntrusivePtr<TGroupQueues> groupQueues = group.MakeGroupQueues();
TIntrusivePtr<NMonitoring::TDynamicCounters> counters(new NMonitoring::TDynamicCounters());
TIntrusivePtr<TDsProxyNodeMon> nodeMon(new TDsProxyNodeMon(counters, true));
@@ -73,7 +73,7 @@ void TestPutMaxPartCountOnHandoff(TErasureType::EErasureSpecies erasureSpecies)
}
group.SetPredictedDelayNs(7, 10);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
putImpl.GenerateInitialRequests(logCtx, partSetSingleton, vPuts);
group.SetError(0, NKikimrProto::ERROR);
@@ -111,13 +111,13 @@ void TestPutMaxPartCountOnHandoff(TErasureType::EErasureSpecies erasureSpecies)
group.SetPredictedDelayNs(slowDiskSequence[vPutIdx], 10);
}
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> nextVPuts;
TEvBlobStorage::TEvVPut& vPut = *vPuts[vPutIdx];
TActorId sender;
TEvBlobStorage::TEvVPutResult vPutResult;
NKikimrProto::EReplyStatus status = group.OnVPut(vPut);
- vPutResult.MakeError(status, TString(), vPut.Record);
+ vPutResult.MakeError(status, TString(), vPut.Record);
putImpl.OnVPutEventResult(logCtx, sender, vPutResult, nextVPuts, putResults);
@@ -125,7 +125,7 @@ void TestPutMaxPartCountOnHandoff(TErasureType::EErasureSpecies erasureSpecies)
break;
}
- std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
+ std::move(nextVPuts.begin(), nextVPuts.end(), std::back_inserter(vPuts));
}
UNIT_ASSERT(putResults.size() == 1);
auto& [_, result] = putResults.front();
@@ -154,7 +154,7 @@ struct TTestPutAllOk {
TActorSystemStub ActorSystemStub;
TBlobStorageGroupType GroupType;
TGroupMock Group;
- TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
TBatchedVec<TLogoBlobID> BlobIds;
TString Data;
@@ -172,7 +172,7 @@ struct TTestPutAllOk {
TTestPutAllOk()
: GroupType(ErasureSpecies)
, Group(GroupId, ErasureSpecies, GroupType.BlobSubgroupSize(), 1)
- , GroupQueues(Group.MakeGroupQueues())
+ , GroupQueues(Group.MakeGroupQueues())
, BlobIds({TLogoBlobID(743284823, 10, 12345, 0, DataSize, 0), TLogoBlobID(743284823, 9, 12346, 0, DataSize, 0)})
, Data(AlphaData(DataSize))
, Counters(new NMonitoring::TDynamicCounters())
@@ -204,22 +204,22 @@ struct TTestPutAllOk {
}
}
- void InitVPutResults(TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &vPuts,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPutResult>> &vPutResults)
+ void InitVPutResults(TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> &vPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPutResult>> &vPutResults)
{
vPutResults.resize(vPuts.size());
for (ui32 vPutIdx = 0; vPutIdx < vPuts.size(); ++vPutIdx) {
TEvBlobStorage::TEvVPut &vPut = *vPuts[vPutIdx];
NKikimrProto::EReplyStatus status = Group.OnVPut(vPut);
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
- vPutResults[vPutIdx].reset(new TEvBlobStorage::TEvVPutResult());
+ vPutResults[vPutIdx].reset(new TEvBlobStorage::TEvVPutResult());
TEvBlobStorage::TEvVPutResult &vPutResult = *vPutResults[vPutIdx];
- vPutResult.MakeError(status, TString(), vPut.Record);
+ vPutResult.MakeError(status, TString(), vPut.Record);
}
}
- void InitVPutResults(TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &vMultiPuts,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult>> &vMultiPutResults)
+ void InitVPutResults(TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> &vMultiPuts,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult>> &vMultiPutResults)
{
vMultiPutResults.resize(vMultiPuts.size());
for (ui32 vMultiPutIdx = 0; vMultiPutIdx < vMultiPuts.size(); ++vMultiPutIdx) {
@@ -228,10 +228,10 @@ struct TTestPutAllOk {
for (auto status : statuses) {
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
}
- vMultiPutResults[vMultiPutIdx].reset(new TEvBlobStorage::TEvVMultiPutResult());
+ vMultiPutResults[vMultiPutIdx].reset(new TEvBlobStorage::TEvVMultiPutResult());
Y_VERIFY(vMultiPut.Record.ItemsSize() == statuses.size());
TEvBlobStorage::TEvVMultiPutResult &vMultiPutResult = *vMultiPutResults[vMultiPutIdx];
- vMultiPutResult.MakeError(NKikimrProto::OK, TString(), vMultiPut.Record);
+ vMultiPutResult.MakeError(NKikimrProto::OK, TString(), vMultiPut.Record);
for (ui64 itemIdx = 0; itemIdx < statuses.size(); ++itemIdx) {
NKikimrBlobStorage::TVMultiPutResultItem &item = *vMultiPutResult.Record.MutableItems(itemIdx);
NKikimrProto::EReplyStatus status = statuses[itemIdx];
@@ -242,7 +242,7 @@ struct TTestPutAllOk {
}
template <typename TVPutResultEvent>
- void PermutateVPutResults(ui64 resIdx, bool &isAborted, TDeque<std::unique_ptr<TVPutResultEvent>> &vPutResults) {
+ void PermutateVPutResults(ui64 resIdx, bool &isAborted, TDeque<std::unique_ptr<TVPutResultEvent>> &vPutResults) {
// select result in range [resIdx, vPutResults.size())
if (resIdx + 1 < CheckStack.size()) {
ui32 tgt = CheckStack[resIdx];
@@ -263,7 +263,7 @@ struct TTestPutAllOk {
}
bool Step(TPutImpl &putImpl,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPutResult>> &vPutResults,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPutResult>> &vPutResults,
TPutImpl::TPutResultVec &putResults)
{
bool isAborted = false;
@@ -274,7 +274,7 @@ struct TTestPutAllOk {
}
TActorId sender;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts2;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts2;
putImpl.OnVPutEventResult(LogCtx, sender, *vPutResults[resIdx], vPuts2, putResults);
if (putResults.size()) {
break;
@@ -286,7 +286,7 @@ struct TTestPutAllOk {
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
vPutResults.emplace_back(new TEvBlobStorage::TEvVPutResult());
TEvBlobStorage::TEvVPutResult &vPutResult = *vPutResults.back();
- vPutResult.MakeError(status, TString(), vPut.Record);
+ vPutResult.MakeError(status, TString(), vPut.Record);
}
}
@@ -294,7 +294,7 @@ struct TTestPutAllOk {
}
bool Step(TPutImpl &putImpl,
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult>> &vMultiPutResults,
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult>> &vMultiPutResults,
TPutImpl::TPutResultVec &putResults)
{
bool isAborted = false;
@@ -305,7 +305,7 @@ struct TTestPutAllOk {
}
TActorId sender;
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts2;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVMultiPut>> vMultiPuts2;
putImpl.OnVPutEventResult(LogCtx, sender, *vMultiPutResults[resIdx], vMultiPuts2, putResults);
if (putResults.size() == BlobIds.size()) {
break;
@@ -318,10 +318,10 @@ struct TTestPutAllOk {
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
}
- vMultiPutResults[vMultiPutIdx].reset(new TEvBlobStorage::TEvVMultiPutResult());
+ vMultiPutResults[vMultiPutIdx].reset(new TEvBlobStorage::TEvVMultiPutResult());
Y_VERIFY(vMultiPut.Record.ItemsSize() == statuses.size());
TEvBlobStorage::TEvVMultiPutResult &vMultiPutResult = *vMultiPutResults[vMultiPutIdx];
- vMultiPutResult.MakeError(NKikimrProto::OK, TString(), vMultiPut.Record);
+ vMultiPutResult.MakeError(NKikimrProto::OK, TString(), vMultiPut.Record);
for (ui64 itemIdx = 0; itemIdx < statuses.size(); ++itemIdx) {
auto &item = vMultiPut.Record.GetItems(itemIdx);
@@ -335,7 +335,7 @@ struct TTestPutAllOk {
cookie = &cookieValue;
}
- vMultiPutResult.AddVPutResult(status, TString(), blobId, cookie);
+ vMultiPutResult.AddVPutResult(status, TString(), blobId, cookie);
}
}
}
@@ -353,10 +353,10 @@ struct TTestPutAllOk {
Group.Wipe();
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> events;
for (auto &blobId : BlobIds) {
- std::unique_ptr<TEvBlobStorage::TEvPut> vPut(new TEvBlobStorage::TEvPut(blobId, Data, TInstant::Max(),
+ std::unique_ptr<TEvBlobStorage::TEvPut> vPut(new TEvBlobStorage::TEvPut(blobId, Data, TInstant::Max(),
NKikimrBlobStorage::TabletLog, TEvBlobStorage::TEvPut::TacticDefault));
events.emplace_back(static_cast<TEventHandle<TEvBlobStorage::TEvPut> *>(
- new IEventHandle(TActorId(), TActorId(), vPut.release())));
+ new IEventHandle(TActorId(), TActorId(), vPut.release())));
}
TMaybe<TPutImpl> putImpl;
@@ -364,14 +364,14 @@ struct TTestPutAllOk {
if constexpr (IsVPut) {
putImpl.ConstructInPlace(Group.GetInfo(), GroupQueues, events[0]->Get(), Mon, false);
} else {
- putImpl.ConstructInPlace(Group.GetInfo(), GroupQueues, events, Mon,
+ putImpl.ConstructInPlace(Group.GetInfo(), GroupQueues, events, Mon,
NKikimrBlobStorage::TabletLog, TEvBlobStorage::TEvPut::TacticDefault, false);
}
- TDeque<std::unique_ptr<TVPutEvent>> vPuts;
+ TDeque<std::unique_ptr<TVPutEvent>> vPuts;
putImpl->GenerateInitialRequests(LogCtx, PartSets, vPuts);
UNIT_ASSERT(vPuts.size() == 6 || !IsVPut);
- TDeque<std::unique_ptr<TVPutResultEvent>> vPutResults;
+ TDeque<std::unique_ptr<TVPutResultEvent>> vPutResults;
InitVPutResults(vPuts, vPutResults);
bool isAborted = Step(*putImpl, vPutResults, putResults);
@@ -412,7 +412,7 @@ Y_UNIT_TEST(TestMirror3dcWith3x3MinLatencyMod) {
TEvBlobStorage::TEvPut ev(blobId, data, TInstant::Max(), NKikimrBlobStorage::TabletLog,
TEvBlobStorage::TEvPut::TacticMinLatency);
TPutImpl putImpl(env.Info, env.GroupQueues, &ev, env.Mon, true);
- TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
+ TDeque<std::unique_ptr<TEvBlobStorage::TEvVPut>> vPuts;
TLogContext logCtx(NKikimrServices::BS_PROXY_PUT, false);
logCtx.LogAcc.IsLogEnabled = false;
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_quorum_tracker_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_quorum_tracker_ut.cpp
index dcdd375c18c..634f500a27e 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_quorum_tracker_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_quorum_tracker_ut.cpp
@@ -1,53 +1,53 @@
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/blobstorage/dsproxy/dsproxy_quorum_tracker.h>
-
-using namespace NKikimr;
-
-void RunCheckFailModel(TBlobStorageGroupType::EErasureSpecies erasure) {
- TBlobStorageGroupType gtype(erasure);
- const bool m3dc = erasure == TBlobStorageGroupType::ErasureMirror3dc;
- const ui32 numVDisksPerFailDomain = m3dc ? 1 : 2;
- const ui32 numFailDomainsPerFailRealm = m3dc ? 4 : gtype.BlobSubgroupSize() + 2;
- const ui32 numFailRealms = m3dc ? 3 : 1;
- TBlobStorageGroupInfo info(erasure, numVDisksPerFailDomain, numFailDomainsPerFailRealm, numFailRealms);
-
- const ui32 numDisks = info.GetTotalVDisksNum();
- for (ui64 failedMask = 0; failedMask != (ui64)1 << numDisks; ++failedMask) {
- TGroupQuorumTracker tracker(&info);
-
- NKikimrProto::EReplyStatus status = NKikimrProto::UNKNOWN;
- for (const auto& vdisk : info.GetVDisks()) {
- const TVDiskID& vdiskId = info.GetVDiskId(vdisk.OrderNumber);
- NKikimrProto::EReplyStatus diskStatus = (failedMask >> vdisk.OrderNumber) & 1
- ? NKikimrProto::ERROR : NKikimrProto::OK;
- status = tracker.ProcessReply(vdiskId, diskStatus);
- }
-
- NKikimrProto::EReplyStatus expectedStatus = info.GetQuorumChecker().CheckFailModelForGroup(
- TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&info.GetTopology(), failedMask))
- ? NKikimrProto::OK
- : NKikimrProto::ERROR;
-
- UNIT_ASSERT_VALUES_EQUAL(status, expectedStatus);
- }
-}
-
+
+using namespace NKikimr;
+
+void RunCheckFailModel(TBlobStorageGroupType::EErasureSpecies erasure) {
+ TBlobStorageGroupType gtype(erasure);
+ const bool m3dc = erasure == TBlobStorageGroupType::ErasureMirror3dc;
+ const ui32 numVDisksPerFailDomain = m3dc ? 1 : 2;
+ const ui32 numFailDomainsPerFailRealm = m3dc ? 4 : gtype.BlobSubgroupSize() + 2;
+ const ui32 numFailRealms = m3dc ? 3 : 1;
+ TBlobStorageGroupInfo info(erasure, numVDisksPerFailDomain, numFailDomainsPerFailRealm, numFailRealms);
+
+ const ui32 numDisks = info.GetTotalVDisksNum();
+ for (ui64 failedMask = 0; failedMask != (ui64)1 << numDisks; ++failedMask) {
+ TGroupQuorumTracker tracker(&info);
+
+ NKikimrProto::EReplyStatus status = NKikimrProto::UNKNOWN;
+ for (const auto& vdisk : info.GetVDisks()) {
+ const TVDiskID& vdiskId = info.GetVDiskId(vdisk.OrderNumber);
+ NKikimrProto::EReplyStatus diskStatus = (failedMask >> vdisk.OrderNumber) & 1
+ ? NKikimrProto::ERROR : NKikimrProto::OK;
+ status = tracker.ProcessReply(vdiskId, diskStatus);
+ }
+
+ NKikimrProto::EReplyStatus expectedStatus = info.GetQuorumChecker().CheckFailModelForGroup(
+ TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&info.GetTopology(), failedMask))
+ ? NKikimrProto::OK
+ : NKikimrProto::ERROR;
+
+ UNIT_ASSERT_VALUES_EQUAL(status, expectedStatus);
+ }
+}
+
Y_UNIT_TEST_SUITE(TDsProxyQuorumTracker) {
-
-#define UNIT_TEST_FOR_ERASURE(ERASURE) \
+
+#define UNIT_TEST_FOR_ERASURE(ERASURE) \
Y_UNIT_TEST(CheckFailModel##ERASURE) { \
- RunCheckFailModel(TBlobStorageGroupType::ERASURE); \
- }
-
- UNIT_TEST_FOR_ERASURE(ErasureNone)
- UNIT_TEST_FOR_ERASURE(ErasureMirror3)
- UNIT_TEST_FOR_ERASURE(Erasure3Plus1Block)
- UNIT_TEST_FOR_ERASURE(Erasure3Plus1Stripe)
- UNIT_TEST_FOR_ERASURE(Erasure4Plus2Block)
- UNIT_TEST_FOR_ERASURE(Erasure3Plus2Block)
- UNIT_TEST_FOR_ERASURE(Erasure4Plus2Stripe)
- UNIT_TEST_FOR_ERASURE(Erasure3Plus2Stripe)
- UNIT_TEST_FOR_ERASURE(ErasureMirror3Plus2)
- UNIT_TEST_FOR_ERASURE(ErasureMirror3dc)
-
-}
+ RunCheckFailModel(TBlobStorageGroupType::ERASURE); \
+ }
+
+ UNIT_TEST_FOR_ERASURE(ErasureNone)
+ UNIT_TEST_FOR_ERASURE(ErasureMirror3)
+ UNIT_TEST_FOR_ERASURE(Erasure3Plus1Block)
+ UNIT_TEST_FOR_ERASURE(Erasure3Plus1Stripe)
+ UNIT_TEST_FOR_ERASURE(Erasure4Plus2Block)
+ UNIT_TEST_FOR_ERASURE(Erasure3Plus2Block)
+ UNIT_TEST_FOR_ERASURE(Erasure4Plus2Stripe)
+ UNIT_TEST_FOR_ERASURE(Erasure3Plus2Stripe)
+ UNIT_TEST_FOR_ERASURE(ErasureMirror3Plus2)
+ UNIT_TEST_FOR_ERASURE(ErasureMirror3dc)
+
+}
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp b/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp
index fdd7a92ea30..6d312acf43f 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_sequence_ut.cpp
@@ -164,11 +164,11 @@ struct TVDiskState {
LastCookie = handle->Cookie;
InnerCookie = vput->Record.GetCookie();
Data = vput->Record.GetBuffer();
- if (!vput->Record.HasBuffer()) {
- const TRope& rope = vput->GetPayload(0);
- Data = TString::Uninitialized(rope.GetSize());
- rope.Begin().ExtractPlainDataAndAdvance(Data.Detach(), Data.size());
- }
+ if (!vput->Record.HasBuffer()) {
+ const TRope& rope = vput->GetPayload(0);
+ Data = TString::Uninitialized(rope.GetSize());
+ rope.Begin().ExtractPlainDataAndAdvance(Data.Detach(), Data.size());
+ }
MsgId = vput->Record.GetMsgQoS().GetMsgId().GetMsgId();
SequenceId = vput->Record.GetMsgQoS().GetMsgId().GetSequenceId();
IsValid = true;
@@ -244,10 +244,10 @@ void SetPredictedDelaysForAllQueues(const THashMap<TVDiskID, ui32> &latencies) {
void SendVGetResult(ui32 vDiskIdx, NKikimrProto::EReplyStatus status, ui32 partId,
TVector<TVDiskState> &subgroup, TTestActorRuntime &runtime) {
- TVDiskState *from = &subgroup[vDiskIdx];
+ TVDiskState *from = &subgroup[vDiskIdx];
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(NKikimrProto::OK, from->VDiskId,
- TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(NKikimrProto::OK, from->VDiskId,
+ TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
SetPredictedDelaysForAllQueues({});
ui64 queryCookie = from->QueryCookies.size() ? from->QueryCookies[0] : 0;
@@ -255,7 +255,7 @@ void SendVGetResult(ui32 vDiskIdx, NKikimrProto::EReplyStatus status, ui32 partI
result->Record.SetCookie(from->InnerCookie);
TVDiskState *part = nullptr;
Y_VERIFY(subgroup.size() > partId - 1);
- part = &subgroup[partId - 1];
+ part = &subgroup[partId - 1];
result->AddResult(status, part->LogoBlobId, 0, part->Data.data(), part->Data.size(),
&queryCookie);
@@ -269,15 +269,15 @@ void SendVGetResult(ui32 vDiskIdx, NKikimrProto::EReplyStatus status, ui32 partI
TLogoBlobID id(from->LogoBlobId, 0);
result->AddResult(status, id, &queryCookie);
}
- result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(subgroup[vDiskIdx].MsgId);
- result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(subgroup[vDiskIdx].SequenceId);
- runtime.Send(new IEventHandle(from->Sender, from->ActorId, result.release(), 0, from->LastCookie));
+ result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(subgroup[vDiskIdx].MsgId);
+ result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(subgroup[vDiskIdx].SequenceId);
+ runtime.Send(new IEventHandle(from->Sender, from->ActorId, result.release(), 0, from->LastCookie));
}
void SendVGetResult(ui32 blobIdx, ui32 vDiskIdx, NKikimrProto::EReplyStatus status,
TVector<TVector<TVDiskState>> &blobSubgroups,
TMap<TActorId, TGetRequest> &lastRequest, TTestActorRuntime &runtime) {
- TGetRequest &request = lastRequest[blobSubgroups[blobIdx][vDiskIdx].ActorId];
+ TGetRequest &request = lastRequest[blobSubgroups[blobIdx][vDiskIdx].ActorId];
if (!request.IsValid) {
return;
}
@@ -286,21 +286,21 @@ void SendVGetResult(ui32 blobIdx, ui32 vDiskIdx, NKikimrProto::EReplyStatus stat
if (status == NKikimrProto::ERROR || status == NKikimrProto::TRYLATER
|| status == NKikimrProto::TRYLATER_SIZE || status == NKikimrProto::TRYLATER_TIME
|| status == NKikimrProto::VDISK_ERROR_STATE) {
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- status, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr, nullptr,
- NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ status, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr, nullptr,
+ NWilson::TTraceId(), {}, 0U, 0U));
for (auto it = request.Queries.begin(); it != request.Queries.end(); ++it) {
result->AddResult(status, it->LogoBlobId, &it->QueryCookie);
}
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(request.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(request.SequenceId);
result->Record.SetCookie(request.RecordCookie);
- runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
+ runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
return;
} else if (status == NKikimrProto::NODATA) {
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
- nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ NKikimrProto::OK, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
+ nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
for (auto it = request.Queries.begin(); it != request.Queries.end(); ++it) {
result->AddResult(status, it->LogoBlobId, &it->QueryCookie);
TLogoBlobID id(it->LogoBlobId);
@@ -309,19 +309,19 @@ void SendVGetResult(ui32 blobIdx, ui32 vDiskIdx, NKikimrProto::EReplyStatus stat
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(request.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(request.SequenceId);
result->Record.SetCookie(request.RecordCookie);
- runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
+ runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
return;
} else if (status == NKikimrProto::OK) {
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
- nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ NKikimrProto::OK, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
+ nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
for (auto it = request.Queries.begin(); it != request.Queries.end(); ++it) {
TString data;
ui32 partIdx = 0;
- for (ui32 bIdx = 0; bIdx < blobSubgroups.size(); ++bIdx) {
- if (blobSubgroups[bIdx][0].LogoBlobId.IsSameBlob(it->LogoBlobId)) {
- for (ui32 vIdx = 0; vIdx < blobSubgroups[bIdx].size(); ++vIdx) {
- TVDiskState &state = blobSubgroups[bIdx][vIdx];
+ for (ui32 bIdx = 0; bIdx < blobSubgroups.size(); ++bIdx) {
+ if (blobSubgroups[bIdx][0].LogoBlobId.IsSameBlob(it->LogoBlobId)) {
+ for (ui32 vIdx = 0; vIdx < blobSubgroups[bIdx].size(); ++vIdx) {
+ TVDiskState &state = blobSubgroups[bIdx][vIdx];
if (state.ActorId == request.ActorId) {
partIdx = vIdx % 6;
ui32 size = state.Data.size() - it->Shift;
@@ -340,7 +340,7 @@ void SendVGetResult(ui32 blobIdx, ui32 vDiskIdx, NKikimrProto::EReplyStatus stat
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(request.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(request.SequenceId);
result->Record.SetCookie(request.RecordCookie);
- runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
+ runtime.Send(new IEventHandle(request.Sender, request.ActorId, result.release(), 0, request.Cookie));
return;
} else {
Y_FAIL();
@@ -363,14 +363,14 @@ void GrabVPutEvent(TTestActorRuntime &runtime, TVector<TVDiskState> &subgroup, u
void SendVPutResultEvent(TTestActorRuntime &runtime, TVDiskState &vdisk, NKikimrProto::EReplyStatus status) {
Y_VERIFY(vdisk.IsValid);
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> vPutResult(new TEvBlobStorage::TEvVPutResult(
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> vPutResult(new TEvBlobStorage::TEvVPutResult(
status, vdisk.LogoBlobId, vdisk.VDiskId,
&vdisk.InnerCookie, TOutOfSpaceStatus(0u, 0.0), TAppData::TimeProvider->Now(),
- 0, nullptr, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString()));
+ 0, nullptr, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString()));
vPutResult->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(vdisk.MsgId);
vPutResult->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(vdisk.SequenceId);
SetPredictedDelaysForAllQueues({});
- runtime.Send(new IEventHandle(vdisk.Sender, vdisk.ActorId, vPutResult.release(), 0, vdisk.LastCookie));
+ runtime.Send(new IEventHandle(vdisk.Sender, vdisk.ActorId, vPutResult.release(), 0, vdisk.LastCookie));
}
void PrepareBlobSubgroup(TLogoBlobID logoblobid, TString data, TVector<TVDiskState> &subgroup,
@@ -447,7 +447,7 @@ Y_UNIT_TEST(TestBlock42PutWithChangingSlowDisk) {
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> batched;
TEvBlobStorage::TEvPut::TPtr ev = testState.CreatePutRequest(blob, tactic, handleClass);
- std::unique_ptr<IActor> putActor = DSProxyEnv.CreatePutRequestActor(ev);
+ std::unique_ptr<IActor> putActor = DSProxyEnv.CreatePutRequestActor(ev);
TGroupMock &groupMock = testState.GetGroupMock();
groupMock.SetError(0, NKikimrProto::ERROR);
@@ -480,7 +480,7 @@ Y_UNIT_TEST(TestBlock42PutWithChangingSlowDisk) {
return true;
};
- runtime.Register(new TGeneralDecorator(THolder<IActor>(putActor.release()), action));
+ runtime.Register(new TGeneralDecorator(THolder<IActor>(putActor.release()), action));
for (ui64 idx = 0; idx < 8; ++idx) {
TEvBlobStorage::TEvVPut::TPtr ev = testState.GrabEventPtr<TEvBlobStorage::TEvVPut>();
@@ -525,7 +525,7 @@ void MakeTestMultiPutItemStatuses(TTestBasicRuntime &runtime, const TBlobStorage
TBatchedVec<TEvBlobStorage::TEvPut::TPtr> batched;
testState.CreatePutRequests(blobs, std::back_inserter(batched), tactic, handleClass);
- runtime.Register(DSProxyEnv.CreatePutRequestActor(batched, tactic, handleClass).release());
+ runtime.Register(DSProxyEnv.CreatePutRequestActor(batched, tactic, handleClass).release());
TMap<TPartLocation, NKikimrProto::EReplyStatus> specialStatuses;
for (ui64 idx = 0; idx < blobIds.size(); ++idx) {
@@ -552,7 +552,7 @@ Y_UNIT_TEST(TestGivenBlock42MultiPut2ItemsStatuses) {
TBlobStorageGroupType type = {TErasureType::Erasure4Plus2Block};
TTestBasicRuntime runtime(1, false);
Setup(runtime, type);
- constexpr ui64 statusCount = 3;
+ constexpr ui64 statusCount = 3;
NKikimrProto::EReplyStatus maybeStatuses[statusCount] = {
NKikimrProto::OK,
NKikimrProto::BLOCKED,
@@ -674,7 +674,7 @@ void MakeTestGivenBlock42GetRecoverMultiPutStatuses(NKikimrProto::EReplyStatus e
groupMock.Wipe(4);
TEvBlobStorage::TEvGet::TPtr ev = testState.CreateGetRequest(blobIds, true);
- runtime.Register(DSProxyEnv.CreateGetRequestActor(ev, NKikimrBlobStorage::TabletLog, true).release());
+ runtime.Register(DSProxyEnv.CreateGetRequestActor(ev, NKikimrBlobStorage::TabletLog, true).release());
testState.HandleVGetsWithMock(type.BlobSubgroupSize());
@@ -702,7 +702,7 @@ void MakeTestGivenBlock42GetRecoverMultiPutStatuses(NKikimrProto::EReplyStatus e
}
Y_UNIT_TEST(TestGivenBlock42GetRecoverMultiPutStatuses) {
- constexpr ui64 statusCount = 3;
+ constexpr ui64 statusCount = 3;
NKikimrProto::EReplyStatus maybeStatuses[statusCount] = {
NKikimrProto::OK,
NKikimrProto::BLOCKED,
@@ -715,7 +715,7 @@ Y_UNIT_TEST(TestGivenBlock42GetRecoverMultiPutStatuses) {
}
Y_UNIT_TEST(TestGivenBlock42GetRecoverMultiPut2ItemsStatuses) {
- constexpr ui64 statusCount = 3;
+ constexpr ui64 statusCount = 3;
NKikimrProto::EReplyStatus maybeStatuses[statusCount] = {
NKikimrProto::OK,
NKikimrProto::BLOCKED,
@@ -739,7 +739,7 @@ Y_UNIT_TEST(TestGivenMirror3DCGetWithFirstSlowDisk) {
TEvBlobStorage::TEvGet::TPtr ev = testState.CreateGetRequest({blobId}, false);
- TActorId getActorId = runtime.Register(DSProxyEnv.CreateGetRequestActor(ev, NKikimrBlobStorage::TabletLog, false).release());
+ TActorId getActorId = runtime.Register(DSProxyEnv.CreateGetRequestActor(ev, NKikimrBlobStorage::TabletLog, false).release());
runtime.EnableScheduleForActor(getActorId);
testState.GrabEventPtr<TEvBlobStorage::TEvVGet>();
@@ -766,21 +766,21 @@ Y_UNIT_TEST(TestGivenBlock42GetThenVGetResponseParts2523Nodata4ThenGetOk) {
TAutoPtr<IEventHandle> handle;
auto vget = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvVGet>(handle);
UNIT_ASSERT(vget);
- for (size_t idx = 0; idx < subgroup.size(); ++idx) {
- if (subgroup[idx].ActorId == handle->Recipient) {
- subgroup[idx].SetCookiesAndSenderFrom(handle.Get(), vget);
+ for (size_t idx = 0; idx < subgroup.size(); ++idx) {
+ if (subgroup[idx].ActorId == handle->Recipient) {
+ subgroup[idx].SetCookiesAndSenderFrom(handle.Get(), vget);
}
}
}
- SendVGetResult(6, NKikimrProto::OK, 2, subgroup, runtime);
- SendVGetResult(4, NKikimrProto::OK, 5, subgroup, runtime);
- SendVGetResult(1, NKikimrProto::OK, 2, subgroup, runtime);
- SendVGetResult(2, NKikimrProto::OK, 3, subgroup, runtime);
+ SendVGetResult(6, NKikimrProto::OK, 2, subgroup, runtime);
+ SendVGetResult(4, NKikimrProto::OK, 5, subgroup, runtime);
+ SendVGetResult(1, NKikimrProto::OK, 2, subgroup, runtime);
+ SendVGetResult(2, NKikimrProto::OK, 3, subgroup, runtime);
SendVGetResult(7, NKikimrProto::NODATA, 1, subgroup, runtime);
- SendVGetResult(3, NKikimrProto::OK, 4, subgroup, runtime);
- SendVGetResult(5, NKikimrProto::OK, 6, subgroup, runtime);
- SendVGetResult(0, NKikimrProto::OK, 1, subgroup, runtime);
+ SendVGetResult(3, NKikimrProto::OK, 4, subgroup, runtime);
+ SendVGetResult(5, NKikimrProto::OK, 6, subgroup, runtime);
+ SendVGetResult(0, NKikimrProto::OK, 1, subgroup, runtime);
TAutoPtr<IEventHandle> handle;
auto getResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvGetResult>(handle);
@@ -995,21 +995,21 @@ Y_UNIT_TEST(TestGivenStripe42GetThenVGetResponsePartsNodata263451ThenGetOk) {
TAutoPtr<IEventHandle> handle;
auto vget = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvVGet>(handle);
UNIT_ASSERT(vget);
- for (size_t idx = 0; idx < subgroup.size(); ++idx) {
- if (subgroup[idx].ActorId == handle->Recipient) {
- subgroup[idx].SetCookiesAndSenderFrom(handle.Get(), vget);
+ for (size_t idx = 0; idx < subgroup.size(); ++idx) {
+ if (subgroup[idx].ActorId == handle->Recipient) {
+ subgroup[idx].SetCookiesAndSenderFrom(handle.Get(), vget);
}
}
}
SendVGetResult(7, NKikimrProto::NODATA, 1, subgroup, runtime);
- SendVGetResult(1, NKikimrProto::OK, 2, subgroup, runtime);
- SendVGetResult(5, NKikimrProto::OK, 6, subgroup, runtime);
- SendVGetResult(2, NKikimrProto::OK, 3, subgroup, runtime);
- SendVGetResult(6, NKikimrProto::OK, 6, subgroup, runtime);
- SendVGetResult(3, NKikimrProto::OK, 4, subgroup, runtime);
- SendVGetResult(4, NKikimrProto::OK, 5, subgroup, runtime);
- SendVGetResult(0, NKikimrProto::OK, 1, subgroup, runtime);
+ SendVGetResult(1, NKikimrProto::OK, 2, subgroup, runtime);
+ SendVGetResult(5, NKikimrProto::OK, 6, subgroup, runtime);
+ SendVGetResult(2, NKikimrProto::OK, 3, subgroup, runtime);
+ SendVGetResult(6, NKikimrProto::OK, 6, subgroup, runtime);
+ SendVGetResult(3, NKikimrProto::OK, 4, subgroup, runtime);
+ SendVGetResult(4, NKikimrProto::OK, 5, subgroup, runtime);
+ SendVGetResult(0, NKikimrProto::OK, 1, subgroup, runtime);
TAutoPtr<IEventHandle> handle;
auto getResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvGetResult>(handle);
@@ -1043,7 +1043,7 @@ Y_UNIT_TEST(TestGivenStripe42WhenGet2PartsOfBlobThenGetOk) {
sizes.push_back(100);
TVector<TVector<TVDiskState>> blobSubgroups;
- blobSubgroups.resize(logoblobids.size());
+ blobSubgroups.resize(logoblobids.size());
TMap<TActorId, TGetRequest> lastRequest;
for (ui32 i = 0; i < logoblobids.size(); ++i) {
@@ -1071,7 +1071,7 @@ Y_UNIT_TEST(TestGivenStripe42WhenGet2PartsOfBlobThenGetOk) {
runtime.EnableScheduleForActor(lastRequest.begin()->second.Sender, true);
for (ui32 vDiskIdx = 0; vDiskIdx < 8; ++vDiskIdx) {
- SendVGetResult(0, vDiskIdx, NKikimrProto::OK, blobSubgroups, lastRequest, runtime);
+ SendVGetResult(0, vDiskIdx, NKikimrProto::OK, blobSubgroups, lastRequest, runtime);
}
TAutoPtr<IEventHandle> handle;
auto getResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvGetResult>(handle);
@@ -1104,7 +1104,7 @@ Y_UNIT_TEST(TestGivenBlock42IntersectingPutWhenNodataOkThenOk) {
sizes.push_back(200);
}
TVector<TVector<TVDiskState>> blobSubgroups;
- blobSubgroups.resize(logoblobids.size());
+ blobSubgroups.resize(logoblobids.size());
TMap<TActorId, TGetRequest> lastRequest;
for (ui32 i = 0; i < logoblobids.size(); ++i) {
@@ -1130,9 +1130,9 @@ Y_UNIT_TEST(TestGivenBlock42IntersectingPutWhenNodataOkThenOk) {
}
runtime.EnableScheduleForActor(lastRequest.begin()->second.Sender, true);
- SendVGetResult(0, 0, NKikimrProto::NODATA, blobSubgroups, lastRequest, runtime);
+ SendVGetResult(0, 0, NKikimrProto::NODATA, blobSubgroups, lastRequest, runtime);
for (ui32 vDiskIdx = 1; vDiskIdx < 8; ++vDiskIdx) {
- SendVGetResult(0, vDiskIdx, NKikimrProto::OK, blobSubgroups, lastRequest, runtime);
+ SendVGetResult(0, vDiskIdx, NKikimrProto::OK, blobSubgroups, lastRequest, runtime);
}
TAutoPtr<IEventHandle> handle;
auto getResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvGetResult>(handle);
@@ -1209,10 +1209,10 @@ Y_UNIT_TEST(TestGivenBlock42PutWhenPartialGetThenSingleDiskRequestOk) {
// Send VGetResult
TLogoBlobID id(query.LogoBlobId, query.LogoBlobId.PartId());
TString resultData = blobSubgroup[query.LogoBlobId.PartId() - 1].Data.substr(query.Shift, query.Size);
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(
new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, theRequest.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
- nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ NKikimrProto::OK, theRequest.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
+ nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
result->AddResult(
NKikimrProto::OK, id, query.Shift, resultData.data(),
resultData.size(), &query.QueryCookie);
@@ -1220,7 +1220,7 @@ Y_UNIT_TEST(TestGivenBlock42PutWhenPartialGetThenSingleDiskRequestOk) {
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(sequenceId);
result->Record.SetCookie(theRequest.RecordCookie);
runtime.Send(
- new IEventHandle(theRequest.Sender, theRequest.ActorId, result.release(), 0, theRequest.Cookie));
+ new IEventHandle(theRequest.Sender, theRequest.ActorId, result.release(), 0, theRequest.Cookie));
// Receive GetResult
auto getResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvGetResult>(handle);
@@ -1239,14 +1239,14 @@ Y_UNIT_TEST(TestGivenBlock42PutWhenPartialGetThenSingleDiskRequestOk) {
// Send responses in order for queues to progress
for (const auto &item: lastRequest) {
const auto &request = item.second;
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::RACE, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
- nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ NKikimrProto::RACE, request.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
+ nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(request.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(request.SequenceId);
result->Record.SetCookie(request.RecordCookie);
runtime.Send(new IEventHandle(
- request.Sender, request.ActorId, result.release(), 0, request.Cookie));
+ request.Sender, request.ActorId, result.release(), 0, request.Cookie));
}
}
@@ -1269,7 +1269,7 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) {
}
TLogoBlobID logoblobid(1, 2, 3, 4, (ui32)data.size(), 5);
TVector<TVector<TVDiskState>> blobSubgroups;
- blobSubgroups.resize(1);
+ blobSubgroups.resize(1);
PrepareBlobSubgroup(logoblobid, data, blobSubgroups[0], runtime, type);
@@ -1299,21 +1299,21 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) {
// Send 6 part VGetResult from the first handoff vDiskIdx# 6
TGetRequest &req = lastRequest[firstHandoffActorId];
TGetRangeQuery &query = req.RangeQueries[0];
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
- nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
+ nullptr, NWilson::TTraceId(), {}, 0U, 0U));
TIngress ingress;
for (ui32 partIdx = 0; partIdx < 6; ++partIdx) {
TLogoBlobID blobPartId(logoblobid, partIdx + 1);
TIngress partIngress(*TIngress::CreateIngressWithLocal(&DSProxyEnv.Info->GetTopology(), req.VDiskId, blobPartId));
ingress.Merge(partIngress);
}
- const ui64 ingressRaw = ingress.Raw();
+ const ui64 ingressRaw = ingress.Raw();
result->AddResult(NKikimrProto::OK, logoblobid, 0, nullptr, 0, &query.QueryCookie,
- &ingressRaw);
+ &ingressRaw);
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(req.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(req.SequenceId);
- runtime.Send(new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
+ runtime.Send(new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
}
for (auto iter = lastRequest.begin(); iter != lastRequest.end(); ++iter) {
@@ -1323,13 +1323,13 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) {
// Send Nodata VGetResult
TGetRequest &req = iter->second;
//TGetRangeQuery &query = req.RangeQueries[0];
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
- nullptr, NWilson::TTraceId(), {}, 0U, 0U));
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
+ nullptr, NWilson::TTraceId(), {}, 0U, 0U));
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(req.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(req.SequenceId);
runtime.Send(
- new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
+ new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
}
lastRequest.clear();
@@ -1350,9 +1350,9 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) {
// Send Nodata VGetResult
TGetRequest &req = iter->second;
TGetQuery &query = req.Queries[0];
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(
new TEvBlobStorage::TEvVGetResult(
- NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
+ NKikimrProto::OK, req.VDiskId, TAppData::TimeProvider->Now(), 0, nullptr, nullptr, nullptr,
nullptr, 0));
result->AddResult(
NKikimrProto::NODATA, query.LogoBlobId, 0, query.Shift, nullptr,
@@ -1360,7 +1360,7 @@ Y_UNIT_TEST(TestGivenBlock42Put6PartsOnOneVDiskWhenDiscoverThenRecoverFirst) {
result->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(req.MsgId);
result->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(req.SequenceId);
runtime.Send(
- new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
+ new IEventHandle(req.Sender, req.ActorId, result.release(), 0, req.Cookie));
}
*/
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_test_state_ut.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_test_state_ut.h
index bc805ac12b7..b91ecb40641 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_test_state_ut.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_test_state_ut.h
@@ -93,10 +93,10 @@ struct TTestState {
TEvBlobStorage::TEvPut::TPtr CreatePutRequest(const TBlobTestSet::TBlob &blob,
TEvBlobStorage::TEvPut::ETactic tactic, NKikimrBlobStorage::EPutHandleClass handleClass)
{
- std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(blob.Id, blob.Data, TInstant::Max(),
+ std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(blob.Id, blob.Data, TInstant::Max(),
handleClass, tactic);
return static_cast<TEventHandle<TEvBlobStorage::TEvPut>*>(
- new IEventHandle(EdgeActor, EdgeActor, put.release()));
+ new IEventHandle(EdgeActor, EdgeActor, put.release()));
}
template <typename TIter, typename TPutIter>
@@ -124,10 +124,10 @@ struct TTestState {
q.Shift = 0;
q.Size = q.Id.BlobSize();
}
- std::unique_ptr<TEvBlobStorage::TEvGet> get = std::make_unique<TEvBlobStorage::TEvGet>(queries, blobs.size(), TInstant::Max(),
+ std::unique_ptr<TEvBlobStorage::TEvGet> get = std::make_unique<TEvBlobStorage::TEvGet>(queries, blobs.size(), TInstant::Max(),
NKikimrBlobStorage::EGetHandleClass::FastRead, mustRestore, false);
return static_cast<TEventHandle<TEvBlobStorage::TEvGet>*>(
- new IEventHandle(EdgeActor, EdgeActor, get.release()));
+ new IEventHandle(EdgeActor, EdgeActor, get.release()));
}
////////////////////////////////////////////////////////////////////////////
@@ -140,8 +140,8 @@ struct TTestState {
}
template <typename TEvent>
- typename TEvent::TPtr CreateEventPtr(TActorId recipient, TActorId sender, std::unique_ptr<TEvent> &ev, ui64 cookie) {
- return CreateEventPtr(recipient, sender, ev.release(), cookie);
+ typename TEvent::TPtr CreateEventPtr(TActorId recipient, TActorId sender, std::unique_ptr<TEvent> &ev, ui64 cookie) {
+ return CreateEventPtr(recipient, sender, ev.release(), cookie);
}
template <typename TEvent>
@@ -163,26 +163,26 @@ struct TTestState {
return handle;
}
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> CreateEventResult(TEvBlobStorage::TEvVPut *ev,
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> CreateEventResult(TEvBlobStorage::TEvVPut *ev,
NKikimrProto::EReplyStatus status, TVDiskID vDiskId)
{
NKikimrBlobStorage::TEvVPut &record = ev->Record;
TLogoBlobID blobId = LogoBlobIDFromLogoBlobID(record.GetBlobID());
ui64 cookieValue = record.GetCookie();
ui64 *cookie = record.HasCookie() ? &cookieValue : nullptr;
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result(new TEvBlobStorage::TEvVPutResult(status, blobId, vDiskId,
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result(new TEvBlobStorage::TEvVPutResult(status, blobId, vDiskId,
cookie, TOutOfSpaceStatus(0u, 0.0), TAppData::TimeProvider->Now(),
0, nullptr, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString()));
return result;
}
- std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
+ std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
NKikimrProto::EReplyStatus status, TVDiskID vDiskId)
{
NKikimrBlobStorage::TEvVMultiPut &record = ev->Record;
ui64 cookieValue = record.GetCookie();
ui64 *cookie = record.HasCookie() ? &cookieValue : nullptr;
- std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> result(
new TEvBlobStorage::TEvVMultiPutResult(status, vDiskId, cookie, TAppData::TimeProvider->Now(), 0,
nullptr, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString()));
result->Record.SetStatusFlags(TOutOfSpaceStatus(0u, 0.0).Flags);
@@ -190,7 +190,7 @@ struct TTestState {
}
template <typename TIter>
- std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
+ std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
NKikimrProto::EReplyStatus status, TIter begin, TIter end, TVDiskID vDiskId)
{
NKikimrBlobStorage::TEvVMultiPut &record = ev->Record;
@@ -212,17 +212,17 @@ struct TTestState {
}
template <typename TCont>
- std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
+ std::unique_ptr<TEvBlobStorage::TEvVMultiPutResult> CreateEventResult(TEvBlobStorage::TEvVMultiPut *ev,
NKikimrProto::EReplyStatus status, const TCont &cont, TVDiskID vDiskId)
{
return CreateEventResult(ev, status, cont.cbegin(), cont.cend(), vDiskId);
}
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> CreateEventResult(TEvBlobStorage::TEvVGet *ev,
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> CreateEventResult(TEvBlobStorage::TEvVGet *ev,
NKikimrProto::EReplyStatus status = NKikimrProto::OK)
{
TVDiskID vDiskId = VDiskIDFromVDiskID(ev->Record.GetVDiskID());
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result(new TEvBlobStorage::TEvVGetResult(
status, vDiskId, TAppData::TimeProvider->Now(), 0, nullptr,
nullptr, nullptr, nullptr, NWilson::TTraceId(), {}, 0U, 0U));
return result;
@@ -286,4 +286,4 @@ struct TTestState {
}
};
-} // namespace NKikimr
+} // namespace NKikimr
diff --git a/ydb/core/blobstorage/dsproxy/ut/dsproxy_vdisk_mock_ut.h b/ydb/core/blobstorage/dsproxy/ut/dsproxy_vdisk_mock_ut.h
index 0a17c046e71..f30c2fa1215 100644
--- a/ydb/core/blobstorage/dsproxy/ut/dsproxy_vdisk_mock_ut.h
+++ b/ydb/core/blobstorage/dsproxy/ut/dsproxy_vdisk_mock_ut.h
@@ -101,7 +101,7 @@ public:
auto &request = vGet.Record;
Y_VERIFY(request.HasCookie());
if (IsError) {
- outVGetResult.MakeError(Status, TString(), request);
+ outVGetResult.MakeError(Status, TString(), request);
return;
}
//ui64 messageCookie = request->Record.GetCookie();
@@ -515,10 +515,10 @@ public:
}
}
- TIntrusivePtr<TGroupQueues> MakeGroupQueues() {
- TIntrusivePtr<TGroupQueues> groupQueues(new TGroupQueues(Info->GetTopology()));
- ui32 idx = 0;
- for (auto& domain : groupQueues->FailDomains) {
+ TIntrusivePtr<TGroupQueues> MakeGroupQueues() {
+ TIntrusivePtr<TGroupQueues> groupQueues(new TGroupQueues(Info->GetTopology()));
+ ui32 idx = 0;
+ for (auto& domain : groupQueues->FailDomains) {
for (auto& vDisk : domain.VDisks) {
vDisk.Queues.FlowRecordForQueueId(NKikimrBlobStorage::EVDiskQueueId::PutTabletLog).Reset(
VDisks[idx].FlowRecord);
@@ -532,10 +532,10 @@ public:
VDisks[idx].FlowRecord);
vDisk.Queues.FlowRecordForQueueId(NKikimrBlobStorage::EVDiskQueueId::GetDiscover).Reset(
VDisks[idx].FlowRecord);
- ++idx;
+ ++idx;
}
}
- return groupQueues;
+ return groupQueues;
}
};
diff --git a/ydb/core/blobstorage/dsproxy/ut/ya.make b/ydb/core/blobstorage/dsproxy/ut/ya.make
index 76825e572bb..b69f480f67c 100644
--- a/ydb/core/blobstorage/dsproxy/ut/ya.make
+++ b/ydb/core/blobstorage/dsproxy/ut/ya.make
@@ -1,15 +1,15 @@
-UNITTEST()
-
+UNITTEST()
+
FORK_SUBTESTS(MODULO)
SPLIT_FACTOR(20)
-
+
OWNER(
alexvru
cthulhu
g:kikimr
)
-
+
IF (SANITIZER_TYPE OR WITH_VALGRIND)
TIMEOUT(3600)
SIZE(LARGE)
@@ -19,7 +19,7 @@ ELSE()
SIZE(MEDIUM)
ENDIF()
-PEERDIR(
+PEERDIR(
library/cpp/actors/core
library/cpp/getopt
library/cpp/svnversion
@@ -33,18 +33,18 @@ PEERDIR(
ydb/core/testlib
ydb/core/testlib/actors
ydb/core/testlib/basics
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-SRCS(
+SRCS(
dsproxy_put_ut.cpp
- dsproxy_quorum_tracker_ut.cpp
+ dsproxy_quorum_tracker_ut.cpp
dsproxy_sequence_ut.cpp
dsproxy_patch_ut.cpp
dsproxy_counters_ut.cpp
-)
-
+)
+
IF (BUILD_TYPE == "RELEASE")
SRCS(
@@ -55,4 +55,4 @@ ELSE ()
MESSAGE(WARNING "It takes too much time to run test in DEBUG mode, some tests are skipped")
ENDIF ()
-END()
+END()
diff --git a/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp b/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp
index 13b1bec3563..acaa6082dfd 100644
--- a/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp
+++ b/ydb/core/blobstorage/dsproxy/ut_fat/dsproxy_ut.cpp
@@ -240,7 +240,7 @@ protected:
TActorId Sender;
TVDiskID VDiskId;
bool IsConnected;
- TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
TResponseData()
: Message(MessageNone)
@@ -275,7 +275,7 @@ protected:
ui32 ReadyQueueCount = 0;
ui32 QueueCount = 0;
- TIntrusivePtr<TGroupQueues> GroupQueues;
+ TIntrusivePtr<TGroupQueues> GroupQueues;
const TIntrusivePtr<TTestEnvironment> Env;
const TIntrusivePtr<ITestParametrs> Parametrs;
@@ -292,9 +292,9 @@ protected:
case 3:
UNIT_ASSERT(LastResponse.Message == TResponseData::MessageProxySessionsState);
- GroupQueues = std::move(LastResponse.GroupQueues);
- UNIT_ASSERT(GroupQueues);
- auto &failDomains = GroupQueues->FailDomains;
+ GroupQueues = std::move(LastResponse.GroupQueues);
+ UNIT_ASSERT(GroupQueues);
+ auto &failDomains = GroupQueues->FailDomains;
for (ui64 failDomainIdx = 0; failDomainIdx < failDomains.size(); ++failDomainIdx) {
auto &failDomain = failDomains[failDomainIdx];
for (ui64 vDiskIdx = 0; vDiskIdx < failDomain.VDisks.size(); ++vDiskIdx) {
@@ -358,7 +358,7 @@ protected:
}
}
if (isSendNeeded) {
- ui32 domains = BsInfo->GetTotalFailDomainsNum();
+ ui32 domains = BsInfo->GetTotalFailDomainsNum();
ui32 drives = Env->VDiskCount / domains;
ui32 domainIdx = InitVDiskIdx / drives;
ui32 driveIdx = InitVDiskIdx - domainIdx * drives;
@@ -366,18 +366,18 @@ protected:
TVDiskID vDiskId(0, 1, 0, domainIdx, driveIdx);
TLogoBlobID from(1, 0, 0, 0, 0, 0, 1);
TLogoBlobID to(1, 0, 0, 0, 0, 0, TLogoBlobID::MaxPartId);
- auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to);
+ auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to);
auto& msgId = *x->Record.MutableMsgQoS()->MutableMsgId();
msgId.SetMsgId(1);
msgId.SetSequenceId(1);
- GroupQueues->Send(*this, BsInfo->GetTopology(), std::move(x), 0, NWilson::TTraceId(), false);
+ GroupQueues->Send(*this, BsInfo->GetTopology(), std::move(x), 0, NWilson::TTraceId(), false);
break;
}
[[fallthrough]];
@@ -609,7 +609,7 @@ protected:
void HandleProxySessionsState(TEvProxySessionsState::TPtr &ev, const TActorContext &ctx) {
VERBOSE_COUT("HandleProxySessionsState");
LastResponse.Message = TResponseData::MessageProxySessionsState;
- LastResponse.GroupQueues = std::move(ev->Get()->GroupQueues);
+ LastResponse.GroupQueues = std::move(ev->Get()->GroupQueues);
LastResponse.Sender = ev->Sender;
ActTestFSM(ctx);
}
@@ -1055,10 +1055,10 @@ class TTestBlobStorageProxyPutInvalidSize : public TTestBlobStorageProxy {
VERBOSE_COUT(" Sending TEvPut");
TLogoBlobID logoblobid(1, 0, 0, 0, testData2.size(), 0);
- std::unique_ptr<TEvBlobStorage::TEvPut> put(new TEvBlobStorage::TEvPut(logoblobid, testData2, TInstant::Max()));
+ std::unique_ptr<TEvBlobStorage::TEvPut> put(new TEvBlobStorage::TEvPut(logoblobid, testData2, TInstant::Max()));
const_cast<TLogoBlobID&>(put->Id) = TLogoBlobID(1, 0, 0, 0, 1, 0);
- ctx.Send(Proxy, put.release());
+ ctx.Send(Proxy, put.release());
break;
}
case 10:
@@ -1406,13 +1406,13 @@ class TTestBlobStorageProxyVPutVGet : public TTestBlobStorageProxy {
VERBOSE_COUT(" Sending TEvVGet");
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
TLogoBlobID id(1, 0, 0, 0, testData2.size(), 0, 1);
- auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {id});
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {id});
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
break;
}
case 20:
@@ -1461,7 +1461,7 @@ class TTestBlobStorageProxyVPutVGetLimit : public TTestBlobStorageProxy {
const ui32 blobSubgroupSize = BsInfo->Type.BlobSubgroupSize();
TBlobStorageGroupInfo::TServiceIds vdisksSvc;
TBlobStorageGroupInfo::TVDiskIds vdisksId;
- BsInfo->PickSubgroup(logoblobid.Hash(), &vdisksId, &vdisksSvc);
+ BsInfo->PickSubgroup(logoblobid.Hash(), &vdisksId, &vdisksSvc);
ui32 partIdx = 0;
for (ui32 idx = 0; idx < blobSubgroupSize; ++idx) {
if (vdisksId[idx] == vDiskId) {
@@ -1505,15 +1505,15 @@ class TTestBlobStorageProxyVPutVGetLimit : public TTestBlobStorageProxy {
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
TLogoBlobID id1(1, 0, 0, 0, testData2.size(), 0, 1);
TLogoBlobID id2(1, 0, 10, 0, testData2.size(), 0, 1);
- auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- id1,
- id2,
- 5);
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ id1,
+ id2,
+ 5);
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
break;
}
case 20:
@@ -1671,13 +1671,13 @@ class TTestBlobStorageProxyVGet : public TTestBlobStorageProxy {
VERBOSE_COUT(" Sending TEvVGet");
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
- auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {id});
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {id});
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
break;
}
case 10:
@@ -1691,13 +1691,13 @@ class TTestBlobStorageProxyVGet : public TTestBlobStorageProxy {
TestStep -= 10;
TLogoBlobID id(1, 0, 0, 0, encryptedTestData2.size(), 0, partId);
- auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {id});
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {id});
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
break;
} else if (LastResponse.ItemStatus[0] == NKikimrProto::NODATA) {
isNoData = true;
@@ -1747,14 +1747,14 @@ class TTestBlobStorageProxyVGetFail : public TTestBlobStorageProxy {
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
TLogoBlobID from(1, 0, 0, 0, 0, 0, 1);
TLogoBlobID to(1, 0, 0, 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie, TLogoBlobID::MaxPartId);
- auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to);
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to);
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
break;
}
case 10:
@@ -1772,17 +1772,17 @@ class TTestBlobStorageProxyVGetFail : public TTestBlobStorageProxy {
// "Unexpected item status " << StatusToString(LastResponse.ItemStatus[0]));
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
- auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {LastResponse.ItemIds[0]});
+ auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {LastResponse.ItemIds[0]});
auto& msgId = *x->Record.MutableMsgQoS()->MutableMsgId();
msgId.SetMsgId(0);
msgId.SetSequenceId(1);
- ctx.Send(Env->VDisks[vDiskIdx], x.release());
+ ctx.Send(Env->VDisks[vDiskIdx], x.release());
} else {
VERBOSE_COUT("Done");
Env->DoneEvent.Signal();
@@ -1868,20 +1868,20 @@ class TTestBlobStorageProxyVBlockVPutVGet : public TTestBlobStorageProxy {
TEST_RESPONSE(MessageVPutResult, BLOCKED, 0, "");
VERBOSE_COUT(" Sending TEvVGet");
- TLogoBlobID id(1, 1, 1, 0, testData.size(), 3);
-
- auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {id});
-
+ TLogoBlobID id(1, 1, 1, 0, testData.size(), 3);
+
+ auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {id});
+
auto& msgId = *x->Record.MutableMsgQoS()->MutableMsgId();
msgId.SetMsgId(0);
msgId.SetSequenceId(1);
- ctx.Send(Env->VDisks[0], x.release());
+ ctx.Send(Env->VDisks[0], x.release());
break;
}
case 30:
@@ -1916,11 +1916,11 @@ class TTestBlobStorageProxyGarbageMark : public TTestBlobStorageProxy {
"Unexpected " << (int)LastResponse.Message);
VERBOSE_COUT(" Sending TEvCollectGarbage Keep");
- std::unique_ptr<TVector<TLogoBlobID>> Keep;
- Keep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> Keep;
+ Keep.reset(new TVector<TLogoBlobID>);
Keep->push_back(TLogoBlobID(1, 0, 0, 0, 104, 0));
VERBOSE_COUT(" keep logoblobid# " << (*Keep)[0].ToString());
- ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, false, 0, 0, Keep.release(), nullptr,
+ ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, false, 0, 0, Keep.release(), nullptr,
TInstant::Max()));
break;
}
@@ -1953,12 +1953,12 @@ class TTestBlobStorageProxyGarbageUnmark : public TTestBlobStorageProxy {
"Unexpected " << (int)LastResponse.Message);
VERBOSE_COUT(" Sending TEvCollectGarbage DoNotKeep");
- std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
- DoNotKeep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
+ DoNotKeep.reset(new TVector<TLogoBlobID>);
DoNotKeep->push_back(TLogoBlobID(1, 0, 0, 0, 104, 0));
VERBOSE_COUT(" donotkeep logoblobid# " << (*DoNotKeep)[0].ToString());
ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 2, 0, false, 0, 0, nullptr,
- DoNotKeep.release(), TInstant::Max()));
+ DoNotKeep.release(), TInstant::Max()));
break;
}
case 10:
@@ -2025,8 +2025,8 @@ class TTestBlobStorageProxyGarbageCollectHuge : public TTestBlobStorageProxy {
VERBOSE_COUT(" Sending TEvCollectGarbage collect");
ui64 keepCount = 12300;
ui64 doNotKeepCount = 45600;
- std::unique_ptr<TVector<TLogoBlobID>> keep(new TVector<TLogoBlobID>);
- std::unique_ptr<TVector<TLogoBlobID>> doNotKeep(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> keep(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> doNotKeep(new TVector<TLogoBlobID>);
keep->reserve(keepCount);
doNotKeep->reserve(doNotKeepCount);
for (ui64 idx = 0; idx < keepCount; ++idx) {
@@ -2035,10 +2035,10 @@ class TTestBlobStorageProxyGarbageCollectHuge : public TTestBlobStorageProxy {
for (ui64 idx = 0; idx < doNotKeepCount; ++idx) {
doNotKeep->emplace_back(123, 1, idx, 0, 100500, 1);
}
- std::unique_ptr<TEvBlobStorage::TEvCollectGarbage> ev(new TEvBlobStorage::TEvCollectGarbage(
- 123, 3, 0, true, 2, 0, keep.release(), doNotKeep.release(), TInstant::Max()));
+ std::unique_ptr<TEvBlobStorage::TEvCollectGarbage> ev(new TEvBlobStorage::TEvCollectGarbage(
+ 123, 3, 0, true, 2, 0, keep.release(), doNotKeep.release(), TInstant::Max()));
- ctx.Send(Proxy, ev.release());
+ ctx.Send(Proxy, ev.release());
break;
}
case 10:
@@ -2138,10 +2138,10 @@ class TTestBlobStorageProxyGarbageCollectComplex : public TTestBlobStorageProxy
TEST_RESPONSE(MessagePutResult, OK, 0, "");
VERBOSE_COUT(" Sending ");
- std::unique_ptr<TVector<TLogoBlobID>> Keep;
- Keep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> Keep;
+ Keep.reset(new TVector<TLogoBlobID>);
Keep->push_back(TLogoBlobID(1, 0, 0, 0, 5, 0));
- ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, true, 0, 1, Keep.release(),
+ ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, true, 0, 1, Keep.release(),
nullptr, TInstant::Max()));
break;
}
@@ -2183,11 +2183,11 @@ class TTestBlobStorageProxyGarbageCollectComplex : public TTestBlobStorageProxy
TEST_RESPONSE(MessageGetResult, OK, 1, "test2");
VERBOSE_COUT(" Sending TEvCollectGarbage");
- std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
- DoNotKeep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
+ DoNotKeep.reset(new TVector<TLogoBlobID>);
DoNotKeep->push_back(TLogoBlobID(1, 0, 0, 0, 5, 0));
ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, false, 0, 0, nullptr,
- DoNotKeep.release(), TInstant::Max()));
+ DoNotKeep.release(), TInstant::Max()));
break;
}
case 80:
@@ -2208,11 +2208,11 @@ class TTestBlobStorageProxyGarbageCollectComplex : public TTestBlobStorageProxy
TEST_RESPONSE_3(MessageGetResult, OK, 1);
VERBOSE_COUT(" Sending TEvCollectGarbage once again");
- std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
- DoNotKeep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> DoNotKeep;
+ DoNotKeep.reset(new TVector<TLogoBlobID>);
DoNotKeep->push_back(TLogoBlobID(1, 0, 0, 0, 5, 0));
ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, false, 0, 0, nullptr,
- DoNotKeep.release(), TInstant::Max()));
+ DoNotKeep.release(), TInstant::Max()));
break;
}
case 100:
@@ -2272,10 +2272,10 @@ class TTestBlobStorageProxyGarbageCollectAfterLargeData : public TTestBlobStorag
TEST_RESPONSE(MessagePutResult, ERROR, 0, "");
VERBOSE_COUT(" Sending ");
- std::unique_ptr<TVector<TLogoBlobID>> Keep;
- Keep.reset(new TVector<TLogoBlobID>);
+ std::unique_ptr<TVector<TLogoBlobID>> Keep;
+ Keep.reset(new TVector<TLogoBlobID>);
Keep->push_back(TLogoBlobID(1, 0, 0, 0, 5, 0));
- ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, true, 0, 1, Keep.release(),
+ ctx.Send(Proxy, new TEvBlobStorage::TEvCollectGarbage(1, 0, 0, true, 0, 1, Keep.release(),
nullptr, TInstant::Max()));
break;
}
@@ -2540,7 +2540,7 @@ class TTestBlobStorageProxyLongTailDiscoverPut : public TTestBlobStorageProxy {
TLogoBlobID blobId(id.TabletID(), id.Generation(), id.Step(), id.Channel(), id.BlobSize(), cookie);
TBlobStorageGroupInfo::TServiceIds vdisksSvc;
TBlobStorageGroupInfo::TVDiskIds vdisksId;
- BsInfo->PickSubgroup(blobId.Hash(), &vdisksId, &vdisksSvc);
+ BsInfo->PickSubgroup(blobId.Hash(), &vdisksId, &vdisksSvc);
for (ui32 idx = 0; idx < blobSubgroupSize; ++idx) {
if (vdisksId[idx] == vDiskId) {
*outPartIdx = idx;
@@ -3017,7 +3017,7 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy {
//ui32 idx = iteration - 1;
}
// Get 1 part
- ui32 domains = BsInfo->GetTotalFailDomainsNum();
+ ui32 domains = BsInfo->GetTotalFailDomainsNum();
ui32 drives = Env->VDiskCount / domains;
ui32 domainIdx = iteration / drives;
ui32 driveIdx = iteration - domainIdx * drives;
@@ -3026,15 +3026,15 @@ class TTestBlobStorageProxyBasic1 : public TTestBlobStorageProxy {
TLogoBlobID from(1, 3/*generation*/, 0, 0, 0, testData.size(), 1);
TLogoBlobID to(1, 3/*generation*/, 0, 0, 0, testData.size(), TLogoBlobID::MaxPartId);
- auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to);
+ auto x = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vDiskId,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to);
VERBOSE_COUT(" Sending TEvVGet");
- ctx.Send(Env->VDisks[iteration], x.release());
+ ctx.Send(Env->VDisks[iteration], x.release());
break;
}
case 200:
@@ -3224,7 +3224,7 @@ class TTestVDiskCompacted : public TTestBlobStorageProxy {
}
case 10:
{
- TEST_RESPONSE(MessageVCompactResult, OK, 0, "");
+ TEST_RESPONSE(MessageVCompactResult, OK, 0, "");
TVDiskID vDiskId(0, 1, 0, vDiskIdx , 0);
TAutoPtr<TEvBlobStorage::TEvVStatus> vStatus(new TEvBlobStorage::TEvVStatus(vDiskId));
VERBOSE_COUT("Sending EvVStatus to vDiskIdx: " << vDiskIdx);
@@ -3291,23 +3291,23 @@ class TTestBlobStorageProxyVPutVCollectVGetRace : public TTestBlobStorageProxy {
TLogoBlobID id(1, 1, 1, 0, testData.size(), 3);
- auto keep = std::make_unique<TVector<TLogoBlobID>>();
+ auto keep = std::make_unique<TVector<TLogoBlobID>>();
keep->push_back(id);
- auto collect = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(
+ auto collect = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(
1, 1, 1,
/* channel */ 0,
/* collect */ true,
/* collect gen */ 1,
/* collect step */ 1,
/* hard */ false,
- /* keep */ keep.get(),
+ /* keep */ keep.get(),
/* donotkeep */ nullptr,
vDiskId,
TInstant::Max());
collect->Record.MutableMsgQoS()->MutableMsgId()->SetMsgId(0);
collect->Record.MutableMsgQoS()->MutableMsgId()->SetSequenceId(1);
- ctx.Send(Env->VDisks[0], collect.release());
+ ctx.Send(Env->VDisks[0], collect.release());
auto x = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vDiskId,
TInstant::Max(),
@@ -3320,7 +3320,7 @@ class TTestBlobStorageProxyVPutVCollectVGetRace : public TTestBlobStorageProxy {
msgId.SetMsgId(0);
msgId.SetSequenceId(2);
- ctx.Send(Env->VDisks[0], x.release());
+ ctx.Send(Env->VDisks[0], x.release());
break;
}
case 20:
@@ -3403,7 +3403,7 @@ class TTestBlobStorageProxyBatchedPutRequestDoesNotContainAHugeBlob : public TTe
batched[1] = GetPut(blobIds[1], Data2);
TMaybe<TGroupStat::EKind> kind = PutHandleClassToGroupStatKind(HandleClass);
- IActor *reqActor = CreateBlobStorageGroupPutRequest(BsInfo, GroupQueues,
+ IActor *reqActor = CreateBlobStorageGroupPutRequest(BsInfo, GroupQueues,
Mon, batched, false, PerDiskStatsPtr, kind,TInstant::Now(),
StoragePoolCounters, HandleClass, Tactic, false);
@@ -3426,9 +3426,9 @@ class TTestBlobStorageProxyBatchedPutRequestDoesNotContainAHugeBlob : public TTe
}
TEvBlobStorage::TEvPut::TPtr GetPut(TLogoBlobID id, const TString &data) {
- std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(id, data,
+ std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(id, data,
TInstant::Max(), HandleClass, Tactic);
- return static_cast<TEventHandle<TEvBlobStorage::TEvPut>*>(new IEventHandle(SelfId(), SelfId(), put.release()));
+ return static_cast<TEventHandle<TEvBlobStorage::TEvPut>*>(new IEventHandle(SelfId(), SelfId(), put.release()));
}
TEvBlobStorage::TEvPut::ETactic Tactic = TEvBlobStorage::TEvPut::TacticDefault;
@@ -3840,7 +3840,7 @@ public:
return;
}
RemoveVDiskData(vDiskIdx, tempDir());
- //TestBlobStorage<TTestBlobStorageProxyVGetFail<vDiskIdx>>(0, erasureSpecies, tempDir().c_str());
+ //TestBlobStorage<TTestBlobStorageProxyVGetFail<vDiskIdx>>(0, erasureSpecies, tempDir().c_str());
TestBlobStorage<TTestBlobStorageProxyGet>(0, erasureSpecies, tempDir().c_str());
// Hands here
@@ -3881,7 +3881,7 @@ public:
}
void TestProxyRestoreOnGetMirror3Plus2() {
- TestProxyRestoreOnGet<2, 1>(TBlobStorageGroupType::ErasureMirror3Plus2);
+ TestProxyRestoreOnGet<2, 1>(TBlobStorageGroupType::ErasureMirror3Plus2);
}
void TestPartialGetBlock() {
@@ -4051,8 +4051,8 @@ public:
SectorMapByPath.clear();
}
- THolder<TActorSystemSetup> BuildActorSystemSetup(ui32 nodeId, NMonitoring::TDynamicCounters &counters,
- TIntrusivePtr<TTableNameserverSetup> &nameserverTable, TInterconnectMock &interconnectMock) {
+ THolder<TActorSystemSetup> BuildActorSystemSetup(ui32 nodeId, NMonitoring::TDynamicCounters &counters,
+ TIntrusivePtr<TTableNameserverSetup> &nameserverTable, TInterconnectMock &interconnectMock) {
auto setup = MakeHolder<TActorSystemSetup>();
setup->NodeId = nodeId;
setup->ExecutorsCount = 4;
@@ -4070,7 +4070,7 @@ public:
#endif
setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
- setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0));
+ setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0));
ui64 nodeCount = nameserverTable->StaticNodeTable.size() + 1;
setup->LocalServices.emplace_back(
@@ -4182,15 +4182,15 @@ public:
auto ioContext = std::make_shared<NKikimr::NPDisk::TIoContextFactoryOSS>();
appData.IoContextFactory = ioContext.get();
- THolder<TActorSystemSetup> setup1 = BuildActorSystemSetup(1, *counters, nameserverTable, interconnect);
- THolder<TActorSystemSetup> setup2 = BuildActorSystemSetup(2, *counters, nameserverTable, interconnect);
+ THolder<TActorSystemSetup> setup1 = BuildActorSystemSetup(1, *counters, nameserverTable, interconnect);
+ THolder<TActorSystemSetup> setup2 = BuildActorSystemSetup(2, *counters, nameserverTable, interconnect);
TIntrusivePtr<TDsProxyNodeMon> dsProxyNodeMon(new TDsProxyNodeMon(counters, true));
TDsProxyPerPoolCounters perPoolCounters(counters);
TIntrusivePtr<TStoragePoolCounters> storagePoolCounters = perPoolCounters.GetPoolCounters("pool_name");
- std::unique_ptr<IActor> proxyActor{CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(bsInfo), false,
- dsProxyNodeMon, TIntrusivePtr(storagePoolCounters), args.EnablePutBatching, DefaultEnableVPatch)};
- TActorSetupCmd bsproxySetup(proxyActor.release(), TMailboxType::Revolving, 3);
+ std::unique_ptr<IActor> proxyActor{CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(bsInfo), false,
+ dsProxyNodeMon, TIntrusivePtr(storagePoolCounters), args.EnablePutBatching, DefaultEnableVPatch)};
+ TActorSetupCmd bsproxySetup(proxyActor.release(), TMailboxType::Revolving, 3);
setup1->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(env->ProxyId, bsproxySetup));
TTempDir tempDir;
@@ -4268,11 +4268,11 @@ public:
TIntrusivePtr<NActors::NLog::TSettings> logSettings2 = AddLoggerActor(setup2, *counters);
//////////////////////////////////////////////////////////////////////////////
- std::unique_ptr<TActorSystem> actorSystem1;
- actorSystem1.reset(new TActorSystem(setup1, &appData, logSettings1));
+ std::unique_ptr<TActorSystem> actorSystem1;
+ actorSystem1.reset(new TActorSystem(setup1, &appData, logSettings1));
actorSystem1->Start();
- std::unique_ptr<TActorSystem> actorSystem2;
- actorSystem2.reset(new TActorSystem(setup2, &appData, logSettings2));
+ std::unique_ptr<TActorSystem> actorSystem2;
+ actorSystem2.reset(new TActorSystem(setup2, &appData, logSettings2));
actorSystem2->Start();
EnableActorCallstack();
try {
diff --git a/ydb/core/blobstorage/dsproxy/ya.make b/ydb/core/blobstorage/dsproxy/ya.make
index 6e165c7f5d1..8733814c321 100644
--- a/ydb/core/blobstorage/dsproxy/ya.make
+++ b/ydb/core/blobstorage/dsproxy/ya.make
@@ -1,26 +1,26 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
alexvru
cthulhu
g:kikimr
)
-
+
SRCS(
dsproxy.h
- dsproxy_impl.cpp
- dsproxy_impl.h
- dsproxy_encrypt.cpp
- dsproxy_request.cpp
- dsproxy_stat.cpp
- dsproxy_state.cpp
+ dsproxy_impl.cpp
+ dsproxy_impl.h
+ dsproxy_encrypt.cpp
+ dsproxy_request.cpp
+ dsproxy_stat.cpp
+ dsproxy_state.cpp
dsproxy_blackboard.h
dsproxy_blackboard.cpp
dsproxy_block.cpp
dsproxy_collect.cpp
dsproxy_discover.cpp
dsproxy_discover_m3dc.cpp
- dsproxy_discover_m3of4.cpp
+ dsproxy_discover_m3of4.cpp
dsproxy_get.cpp
dsproxy_get_impl.cpp
dsproxy_get_impl.h
@@ -44,25 +44,25 @@ SRCS(
dsproxy_responsiveness.h
dsproxy_status.cpp
dsproxy_strategy_accelerate_put.h
- dsproxy_strategy_accelerate_put_m3dc.h
+ dsproxy_strategy_accelerate_put_m3dc.h
dsproxy_strategy_base.cpp
dsproxy_strategy_base.h
dsproxy_strategy_get_bold.h
dsproxy_strategy_get_m3dc_basic.h
dsproxy_strategy_get_m3dc_restore.h
- dsproxy_strategy_get_m3of4.h
+ dsproxy_strategy_get_m3of4.h
dsproxy_strategy_get_min_iops_block.h
dsproxy_strategy_get_min_iops_mirror.h
- dsproxy_strategy_m3of4_base.h
- dsproxy_strategy_put_m3dc.h
- dsproxy_strategy_put_m3of4.h
+ dsproxy_strategy_m3of4_base.h
+ dsproxy_strategy_put_m3dc.h
+ dsproxy_strategy_put_m3of4.h
dsproxy_strategy_restore.h
- group_sessions.cpp
- group_sessions.h
- log_acc.h
+ group_sessions.cpp
+ group_sessions.h
+ log_acc.h
blobstorage_backoff.cpp
)
-
+
PEERDIR(
library/cpp/monlib/dynamic_counters/percentile
ydb/core/base
@@ -75,11 +75,11 @@ PEERDIR(
ydb/core/util
)
-END()
-
-RECURSE(
- mock
-)
+END()
+
+RECURSE(
+ mock
+)
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp
index 054d5be6653..37828f14eeb 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.cpp
@@ -1,314 +1,314 @@
#include "blobstorage_groupinfo.h"
-#include "blobstorage_groupinfo_blobmap.h"
-#include "blobstorage_groupinfo_iter.h"
-#include "blobstorage_groupinfo_sets.h"
-#include "blobstorage_groupinfo_partlayout.h"
+#include "blobstorage_groupinfo_blobmap.h"
+#include "blobstorage_groupinfo_iter.h"
+#include "blobstorage_groupinfo_sets.h"
+#include "blobstorage_groupinfo_partlayout.h"
#include <ydb/core/base/services/blobstorage_service_id.h>
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
#include <library/cpp/actors/core/interconnect.h>
-
+
#include <library/cpp/pop_count/popcount.h>
-
-#include <library/cpp/digest/crc32c/crc32c.h>
-
+
+#include <library/cpp/digest/crc32c/crc32c.h>
+
#include <util/string/printf.h>
-#include <util/string/escape.h>
+#include <util/string/escape.h>
#include <util/stream/input.h>
-#include <util/random/fast.h>
+#include <util/random/fast.h>
#include <util/system/unaligned_mem.h>
namespace NKikimr {
-class TQuorumCheckerBase : public TBlobStorageGroupInfo::IQuorumChecker {
-protected:
+class TQuorumCheckerBase : public TBlobStorageGroupInfo::IQuorumChecker {
+protected:
const TBlobStorageGroupInfo::TTopology *Top;
-
-public:
+
+public:
TQuorumCheckerBase(const TBlobStorageGroupInfo::TTopology *top)
: Top(top)
- {}
-
- bool CheckFailModelForGroup(const TBlobStorageGroupInfo::TGroupVDisks& failedGroupDisks) const override {
- return CheckFailModelForGroupDomains(TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(
- failedGroupDisks, TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY));
- }
-
- bool CheckQuorumForGroup(const TBlobStorageGroupInfo::TGroupVDisks& groupDisks) const override {
- return CheckQuorumForGroupDomains(TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(
- groupDisks, TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ALL));
- }
-};
-
-class TQuorumCheckerOrdinary : public TQuorumCheckerBase {
-public:
- using TQuorumCheckerBase::TQuorumCheckerBase;
-
- bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
+ {}
+
+ bool CheckFailModelForGroup(const TBlobStorageGroupInfo::TGroupVDisks& failedGroupDisks) const override {
+ return CheckFailModelForGroupDomains(TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(
+ failedGroupDisks, TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY));
+ }
+
+ bool CheckQuorumForGroup(const TBlobStorageGroupInfo::TGroupVDisks& groupDisks) const override {
+ return CheckQuorumForGroupDomains(TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(
+ groupDisks, TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ALL));
+ }
+};
+
+class TQuorumCheckerOrdinary : public TQuorumCheckerBase {
+public:
+ using TQuorumCheckerBase::TQuorumCheckerBase;
+
+ bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
return failedSubgroupDisks.GetNumSetItems() <= Top->GType.Handoff();
- }
-
- bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
+ }
+
+ bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
return failedDomains.GetNumSetItems() <= Top->GType.Handoff();
- }
-
- bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
- return CheckFailModelForSubgroup(~subgroupDisks);
- }
-
- bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
- return CheckFailModelForGroupDomains(~domains);
- }
-
- bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
- TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
- return domains.GetNumSetItems() == Top->GType.Handoff();
- }
-
- bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
- TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
- return domains.GetNumSetItems() + 1 >= Top->GType.Handoff();
- }
-
- TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
- const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
- if (!CheckFailModelForSubgroup(failedDisks)) {
- return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- } else {
+ }
+
+ bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
+ return CheckFailModelForSubgroup(~subgroupDisks);
+ }
+
+ bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
+ return CheckFailModelForGroupDomains(~domains);
+ }
+
+ bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
+ TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
+ return domains.GetNumSetItems() == Top->GType.Handoff();
+ }
+
+ bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
+ TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
+ return domains.GetNumSetItems() + 1 >= Top->GType.Handoff();
+ }
+
+ TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
+ const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
+ if (!CheckFailModelForSubgroup(failedDisks)) {
+ return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ } else {
ui32 effectiveReplicas = parts.CountEffectiveReplicas(Top->GType);
return Top->BlobState(effectiveReplicas, failedDisks.GetNumSetItems());
- }
- }
-
- ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
- const TBlobStorageGroupType type = Top->GType;
- const ui32 effectiveReplicas = parts.CountEffectiveReplicas(Top->GType);
- if (effectiveReplicas == type.TotalPartCount()) {
- return 0; // full quorum of records
- } else if (effectiveReplicas < type.MinimalRestorablePartCount()) {
- return 0; // no chance to restore this blob
- }
-
- // iterate over all possible parts and see if adding extra part increases effective replica count
- auto addsEffectiveReplicas = [&](ui32 part) {
- TSubgroupPartLayout temp(parts);
- temp.AddItem(idxInSubgroup, part, type);
- const ui32 newEffectiveReplicas = temp.CountEffectiveReplicas(type);
- Y_VERIFY(newEffectiveReplicas == effectiveReplicas || newEffectiveReplicas == effectiveReplicas + 1);
- return newEffectiveReplicas > effectiveReplicas;
- };
- if (idxInSubgroup < type.TotalPartCount()) {
- return addsEffectiveReplicas(idxInSubgroup) ? 1 << idxInSubgroup : 0;
- } else {
- for (ui32 part = 0; part < type.TotalPartCount(); ++part) {
- if (addsEffectiveReplicas(part)) {
- return 1 << part;
- }
- }
- return 0;
- }
- }
-};
-
-class TQuorumCheckerMirror3of4 : public TQuorumCheckerBase {
-public:
- using TQuorumCheckerBase::TQuorumCheckerBase;
-
- bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
- return failedSubgroupDisks.GetNumSetItems() <= 2;
- }
-
- bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
- return failedDomains.GetNumSetItems() <= 2;
- }
-
- bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
- return CheckFailModelForSubgroup(~subgroupDisks);
- }
-
- bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
- return CheckFailModelForGroupDomains(~domains);
- }
-
- bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
- TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
- return domains.GetNumSetItems() == 2;
- }
-
- bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
- TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
- return domains.GetNumSetItems() + 1 >= 2;
- }
-
- TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
- const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
- if (!CheckFailModelForSubgroup(failedDisks)) {
- return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- } else if (auto [data, any] = parts.GetMirror3of4State(); data >= 3 && any >= 5) {
- return TBlobStorageGroupInfo::EBS_FULL;
- } else if (data) {
- return TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY;
- } else {
- return TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY;
- }
- }
-
- ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
- auto [data, any] = parts.GetMirror3of4State();
- if (!data) {
- return 0; // nowhere to restore from
- } else if (data < 3) {
- // not enough data parts -- we must restore them first
- if ((parts.GetDisksWithPart(0) | parts.GetDisksWithPart(1)) & (1 << idxInSubgroup)) {
- return 0; // this disk already has data part and we can't help the group
- }
- return 1 << (idxInSubgroup & 1); // to fit this possible layout of parts over disks: 0 1 0 1 01 01 01 01
- } else if (any < 5) {
- // enough data parts, but not enough metadata ones
- if ((parts.GetDisksWithPart(0) | parts.GetDisksWithPart(1) | parts.GetDisksWithPart(2)) & (1 << idxInSubgroup)) {
- return 0; // this disk already contains one part
- }
- return 1 << 2;
- } else {
- // full quorum
- return 0;
- }
- }
-};
-
-class TQuorumCheckerMirror3dc : public TQuorumCheckerBase {
- static bool CheckFailModel(ui32 num1, ui32 num2) {
- return num1 <= 2 && num2 <= 1;
- }
-
- static void CountSubgroupRealmStat(const TBlobStorageGroupInfo::TSubgroupVDisks& set, ui32 *num1, ui32 *num2) {
- for (ui32 realm = 0; realm < 3; ++realm) {
- ui32 num = 0;
- for (ui32 domain = 0; domain < 3; ++domain) {
- const ui32 nodeId = realm + domain * 3; // nodeId for blob must be consistent with blob mapper
- num += set[nodeId];
- }
- *num1 += num >= 1;
- *num2 += num >= 2;
- }
- }
-
- bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
- ui32 num1 = 0; // number of realms with at least one fail domain set
- ui32 num2 = 0; // number of realms with at least two fail domains set
- CountSubgroupRealmStat(failedSubgroupDisks, &num1, &num2);
- return CheckFailModel(num1, num2);
- }
-
- bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
- ui32 num1 = 0; // number of realms with at least one fail domain set
- ui32 num2 = 0; // number of realms with at least two fail domains set
+ }
+ }
+
+ ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
+ const TBlobStorageGroupType type = Top->GType;
+ const ui32 effectiveReplicas = parts.CountEffectiveReplicas(Top->GType);
+ if (effectiveReplicas == type.TotalPartCount()) {
+ return 0; // full quorum of records
+ } else if (effectiveReplicas < type.MinimalRestorablePartCount()) {
+ return 0; // no chance to restore this blob
+ }
+
+ // iterate over all possible parts and see if adding extra part increases effective replica count
+ auto addsEffectiveReplicas = [&](ui32 part) {
+ TSubgroupPartLayout temp(parts);
+ temp.AddItem(idxInSubgroup, part, type);
+ const ui32 newEffectiveReplicas = temp.CountEffectiveReplicas(type);
+ Y_VERIFY(newEffectiveReplicas == effectiveReplicas || newEffectiveReplicas == effectiveReplicas + 1);
+ return newEffectiveReplicas > effectiveReplicas;
+ };
+ if (idxInSubgroup < type.TotalPartCount()) {
+ return addsEffectiveReplicas(idxInSubgroup) ? 1 << idxInSubgroup : 0;
+ } else {
+ for (ui32 part = 0; part < type.TotalPartCount(); ++part) {
+ if (addsEffectiveReplicas(part)) {
+ return 1 << part;
+ }
+ }
+ return 0;
+ }
+ }
+};
+
+class TQuorumCheckerMirror3of4 : public TQuorumCheckerBase {
+public:
+ using TQuorumCheckerBase::TQuorumCheckerBase;
+
+ bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
+ return failedSubgroupDisks.GetNumSetItems() <= 2;
+ }
+
+ bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
+ return failedDomains.GetNumSetItems() <= 2;
+ }
+
+ bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
+ return CheckFailModelForSubgroup(~subgroupDisks);
+ }
+
+ bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
+ return CheckFailModelForGroupDomains(~domains);
+ }
+
+ bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
+ TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
+ return domains.GetNumSetItems() == 2;
+ }
+
+ bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ const auto& domains = TBlobStorageGroupInfo::TGroupFailDomains::CreateFromGroupDiskSet(failedDisks,
+ TBlobStorageGroupInfo::TGroupFailDomains::EDiskCondition::ANY);
+ return domains.GetNumSetItems() + 1 >= 2;
+ }
+
+ TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
+ const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
+ if (!CheckFailModelForSubgroup(failedDisks)) {
+ return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ } else if (auto [data, any] = parts.GetMirror3of4State(); data >= 3 && any >= 5) {
+ return TBlobStorageGroupInfo::EBS_FULL;
+ } else if (data) {
+ return TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY;
+ } else {
+ return TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY;
+ }
+ }
+
+ ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
+ auto [data, any] = parts.GetMirror3of4State();
+ if (!data) {
+ return 0; // nowhere to restore from
+ } else if (data < 3) {
+ // not enough data parts -- we must restore them first
+ if ((parts.GetDisksWithPart(0) | parts.GetDisksWithPart(1)) & (1 << idxInSubgroup)) {
+ return 0; // this disk already has data part and we can't help the group
+ }
+ return 1 << (idxInSubgroup & 1); // to fit this possible layout of parts over disks: 0 1 0 1 01 01 01 01
+ } else if (any < 5) {
+ // enough data parts, but not enough metadata ones
+ if ((parts.GetDisksWithPart(0) | parts.GetDisksWithPart(1) | parts.GetDisksWithPart(2)) & (1 << idxInSubgroup)) {
+ return 0; // this disk already contains one part
+ }
+ return 1 << 2;
+ } else {
+ // full quorum
+ return 0;
+ }
+ }
+};
+
+class TQuorumCheckerMirror3dc : public TQuorumCheckerBase {
+ static bool CheckFailModel(ui32 num1, ui32 num2) {
+ return num1 <= 2 && num2 <= 1;
+ }
+
+ static void CountSubgroupRealmStat(const TBlobStorageGroupInfo::TSubgroupVDisks& set, ui32 *num1, ui32 *num2) {
+ for (ui32 realm = 0; realm < 3; ++realm) {
+ ui32 num = 0;
+ for (ui32 domain = 0; domain < 3; ++domain) {
+ const ui32 nodeId = realm + domain * 3; // nodeId for blob must be consistent with blob mapper
+ num += set[nodeId];
+ }
+ *num1 += num >= 1;
+ *num2 += num >= 2;
+ }
+ }
+
+ bool CheckFailModelForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& failedSubgroupDisks) const override {
+ ui32 num1 = 0; // number of realms with at least one fail domain set
+ ui32 num2 = 0; // number of realms with at least two fail domains set
+ CountSubgroupRealmStat(failedSubgroupDisks, &num1, &num2);
+ return CheckFailModel(num1, num2);
+ }
+
+ bool CheckFailModelForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& failedDomains) const override {
+ ui32 num1 = 0; // number of realms with at least one fail domain set
+ ui32 num2 = 0; // number of realms with at least two fail domains set
for (auto realmIt = Top->FailRealmsBegin(), realmEnd = Top->FailRealmsEnd(); realmIt != realmEnd; ++realmIt) {
- ui32 num = 0;
- for (const TBlobStorageGroupInfo::TFailDomain& domain : realmIt.GetFailRealmFailDomains()) {
- num += failedDomains[domain.FailDomainOrderNumber];
- }
- num1 += num >= 1;
- num2 += num >= 2;
- }
- return CheckFailModel(num1, num2);
- }
-
- bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
- ui32 num1 = 0; // number of realms with at least one fail domain set
- ui32 num2 = 0; // number of realms with at least two fail domains set
- CountSubgroupRealmStat(subgroupDisks, &num1, &num2);
- return num1 == 3 || num2 == 2;
- }
-
- bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
- // treat all unset domains as failed ones -- and check if the subset fits the failure model
- return CheckFailModelForGroupDomains(~domains);
- }
-
- bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- ui32 num1 = 0; // number of realms with at least one fail domain
- for (const auto& realm : Top->FailRealms) {
- for (const auto& domain : realm.FailDomains) {
- for (const auto& disk : domain.VDisks) {
- if (failedDisks[disk.OrderNumber]) {
- ++num1;
- goto quitIter;
- }
- }
- }
-quitIter: ;
- }
- return num1 == 2; // two realms have faulty disks
- }
-
- bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
- return failedDisks.GetNumSetItems();
- }
-
- TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
- const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
- if (!CheckFailModelForSubgroup(failedDisks)) {
- return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
- } else {
+ ui32 num = 0;
+ for (const TBlobStorageGroupInfo::TFailDomain& domain : realmIt.GetFailRealmFailDomains()) {
+ num += failedDomains[domain.FailDomainOrderNumber];
+ }
+ num1 += num >= 1;
+ num2 += num >= 2;
+ }
+ return CheckFailModel(num1, num2);
+ }
+
+ bool CheckQuorumForSubgroup(const TBlobStorageGroupInfo::TSubgroupVDisks& subgroupDisks) const override {
+ ui32 num1 = 0; // number of realms with at least one fail domain set
+ ui32 num2 = 0; // number of realms with at least two fail domains set
+ CountSubgroupRealmStat(subgroupDisks, &num1, &num2);
+ return num1 == 3 || num2 == 2;
+ }
+
+ bool CheckQuorumForGroupDomains(const TBlobStorageGroupInfo::TGroupFailDomains& domains) const override {
+ // treat all unset domains as failed ones -- and check if the subset fits the failure model
+ return CheckFailModelForGroupDomains(~domains);
+ }
+
+ bool IsDegraded(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ ui32 num1 = 0; // number of realms with at least one fail domain
+ for (const auto& realm : Top->FailRealms) {
+ for (const auto& domain : realm.FailDomains) {
+ for (const auto& disk : domain.VDisks) {
+ if (failedDisks[disk.OrderNumber]) {
+ ++num1;
+ goto quitIter;
+ }
+ }
+ }
+quitIter: ;
+ }
+ return num1 == 2; // two realms have faulty disks
+ }
+
+ bool OneStepFromDegradedOrWorse(const TBlobStorageGroupInfo::TGroupVDisks& failedDisks) const override {
+ return failedDisks.GetNumSetItems();
+ }
+
+ TBlobStorageGroupInfo::EBlobState GetBlobState(const TSubgroupPartLayout& parts,
+ const TBlobStorageGroupInfo::TSubgroupVDisks& failedDisks) const override {
+ if (!CheckFailModelForSubgroup(failedDisks)) {
+ return TBlobStorageGroupInfo::EBS_DISINTEGRATED;
+ } else {
const TBlobStorageGroupInfo::TSubgroupVDisks& disksWithReplica = parts.GetInvolvedDisks(Top);
-
- if (CheckQuorumForSubgroup(disksWithReplica)) {
- // we have all required replicas present in the parts set, so the blob is fully written
- return TBlobStorageGroupInfo::EBS_FULL;
- } else if (disksWithReplica) {
- // we have some disks with replicas, so data could be easily recovered if needed
- return TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY;
- } else {
- // we can't recover data
- return TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY;
- }
- }
- }
-
- ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
- const TBlobStorageGroupInfo::TSubgroupVDisks& disksWithReplica = parts.GetInvolvedDisks(Top);
- const ui32 myRing = idxInSubgroup % 3;
- const ui32 disksWithPart = parts.GetDisksWithPart(myRing);
- if (!disksWithReplica) {
- return 0; // nowhere to resurrect from
- } else if (CheckQuorumForSubgroup(disksWithReplica)) {
- return 0; // full quorum of writes
- } else if (parts.GetDisksWithPart(myRing) & (1 << idxInSubgroup)) {
- return 0; // we already have a part
- }
- // filter out only parts on their respective disks to filter out possibly incorrectly written parts
- const ui32 numDisksWithPartInMyRing = PopCount((disksWithPart >> myRing) & 0x49); // binary stencil 001001001
- // resurrect matching part if there are less than 2 parts in our datacenter
- return numDisksWithPartInMyRing < 2 ? 1 << myRing : 0;
- }
-
-public:
- using TQuorumCheckerBase::TQuorumCheckerBase;
-};
-
+
+ if (CheckQuorumForSubgroup(disksWithReplica)) {
+ // we have all required replicas present in the parts set, so the blob is fully written
+ return TBlobStorageGroupInfo::EBS_FULL;
+ } else if (disksWithReplica) {
+ // we have some disks with replicas, so data could be easily recovered if needed
+ return TBlobStorageGroupInfo::EBS_RECOVERABLE_FRAGMENTARY;
+ } else {
+ // we can't recover data
+ return TBlobStorageGroupInfo::EBS_UNRECOVERABLE_FRAGMENTARY;
+ }
+ }
+ }
+
+ ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const override {
+ const TBlobStorageGroupInfo::TSubgroupVDisks& disksWithReplica = parts.GetInvolvedDisks(Top);
+ const ui32 myRing = idxInSubgroup % 3;
+ const ui32 disksWithPart = parts.GetDisksWithPart(myRing);
+ if (!disksWithReplica) {
+ return 0; // nowhere to resurrect from
+ } else if (CheckQuorumForSubgroup(disksWithReplica)) {
+ return 0; // full quorum of writes
+ } else if (parts.GetDisksWithPart(myRing) & (1 << idxInSubgroup)) {
+ return 0; // we already have a part
+ }
+ // filter out only parts on their respective disks to filter out possibly incorrectly written parts
+ const ui32 numDisksWithPartInMyRing = PopCount((disksWithPart >> myRing) & 0x49); // binary stencil 001001001
+ // resurrect matching part if there are less than 2 parts in our datacenter
+ return numDisksWithPartInMyRing < 2 ? 1 << myRing : 0;
+ }
+
+public:
+ using TQuorumCheckerBase::TQuorumCheckerBase;
+};
+
////////////////////////////////////////////////////////////////////////////
// TBlobStorageGroupInfo::TTopology
////////////////////////////////////////////////////////////////////////////
-TBlobStorageGroupInfo::TTopology::TTopology(TBlobStorageGroupType gtype)
+TBlobStorageGroupInfo::TTopology::TTopology(TBlobStorageGroupType gtype)
: GType(gtype)
{}
-TBlobStorageGroupInfo::TTopology::TTopology(TBlobStorageGroupType gtype, ui32 numFailRealms,
- ui32 numFailDomainsPerFailRealm, ui32 numVDisksPerFailDomain)
- : GType(gtype)
-{
- FailRealms = {numFailRealms, {
- {numFailDomainsPerFailRealm, {
- {numVDisksPerFailDomain, TVDiskInfo{}}
- }}
- }};
-}
-
+TBlobStorageGroupInfo::TTopology::TTopology(TBlobStorageGroupType gtype, ui32 numFailRealms,
+ ui32 numFailDomainsPerFailRealm, ui32 numVDisksPerFailDomain)
+ : GType(gtype)
+{
+ FailRealms = {numFailRealms, {
+ {numFailDomainsPerFailRealm, {
+ {numVDisksPerFailDomain, TVDiskInfo{}}
+ }}
+ }};
+}
+
TBlobStorageGroupInfo::TTopology::~TTopology() = default;
bool TBlobStorageGroupInfo::TTopology::EqualityCheck(const TTopology &t) {
@@ -319,34 +319,34 @@ bool TBlobStorageGroupInfo::TTopology::EqualityCheck(const TTopology &t) {
void TBlobStorageGroupInfo::TTopology::FinalizeConstruction() {
// finish construction of topology structure
- ui32 failDomainOrderNumber = 0;
- ui32 vdiskOrderNumber = 0;
+ ui32 failDomainOrderNumber = 0;
+ ui32 vdiskOrderNumber = 0;
VDiskIdForOrderNumber.clear();
-
- for (auto realm = FailRealms.begin(); realm != FailRealms.end(); ++realm) {
- for (auto domain = realm->FailDomains.begin(); domain != realm->FailDomains.end(); ++domain) {
- domain->FailDomainOrderNumber = failDomainOrderNumber++;
- for (auto vdisk = domain->VDisks.begin(); vdisk != domain->VDisks.end(); ++vdisk) {
+
+ for (auto realm = FailRealms.begin(); realm != FailRealms.end(); ++realm) {
+ for (auto domain = realm->FailDomains.begin(); domain != realm->FailDomains.end(); ++domain) {
+ domain->FailDomainOrderNumber = failDomainOrderNumber++;
+ for (auto vdisk = domain->VDisks.begin(); vdisk != domain->VDisks.end(); ++vdisk) {
// calculate positions
- ui8 realmPos = realm - FailRealms.begin(); // it.GetFailRealmIdx()
- ui8 domainPos = domain - realm->FailDomains.begin(); // it.GetFailDomainIdx()
- ui8 vdiskPos = vdisk - domain->VDisks.begin(); // it.GetVDiskIdx());
+ ui8 realmPos = realm - FailRealms.begin(); // it.GetFailRealmIdx()
+ ui8 domainPos = domain - realm->FailDomains.begin(); // it.GetFailDomainIdx()
+ ui8 vdiskPos = vdisk - domain->VDisks.begin(); // it.GetVDiskIdx());
// fill in VDisk parameters
- vdisk->VDiskIdShort = TVDiskIdShort(realmPos, domainPos, vdiskPos);
- vdisk->OrderNumber = vdiskOrderNumber++;
- vdisk->FailDomainOrderNumber = domain->FailDomainOrderNumber;
+ vdisk->VDiskIdShort = TVDiskIdShort(realmPos, domainPos, vdiskPos);
+ vdisk->OrderNumber = vdiskOrderNumber++;
+ vdisk->FailDomainOrderNumber = domain->FailDomainOrderNumber;
// fill in VDiskIdForOrderNumber
- VDiskIdForOrderNumber.push_back(vdisk->VDiskIdShort);
+ VDiskIdForOrderNumber.push_back(vdisk->VDiskIdShort);
}
}
- }
-
- TotalFailDomains = failDomainOrderNumber;
+ }
+
+ TotalFailDomains = failDomainOrderNumber;
TotalVDisks = vdiskOrderNumber;
// create blob mapper
- BlobMapper.reset(CreateMapper(GType, this));
+ BlobMapper.reset(CreateMapper(GType, this));
// create quorum checker
- QuorumChecker.reset(CreateQuorumChecker(this));
+ QuorumChecker.reset(CreateQuorumChecker(this));
}
bool TBlobStorageGroupInfo::TTopology::IsValidId(const TVDiskID& vdisk) const {
@@ -378,7 +378,7 @@ bool TBlobStorageGroupInfo::TTopology::IsValidId(const TVDiskIdShort& vdisk) con
ui32 TBlobStorageGroupInfo::TTopology::GetFailDomainOrderNumber(const TVDiskIdShort& vdisk) const {
return FailRealms[vdisk.FailRealm].FailDomains[vdisk.FailDomain].VDisks[vdisk.VDisk].FailDomainOrderNumber;
}
-
+
TVDiskIdShort TBlobStorageGroupInfo::TTopology::GetVDiskId(ui32 orderNumber) const {
return VDiskIdForOrderNumber[orderNumber];
}
@@ -444,19 +444,19 @@ TBlobStorageGroupInfo::EBlobState TBlobStorageGroupInfo::TTopology::BlobState(ui
return EBS_RECOVERABLE_DOUBTED;
}
-IBlobToDiskMapper *TBlobStorageGroupInfo::TTopology::CreateMapper(TBlobStorageGroupType gtype,
+IBlobToDiskMapper *TBlobStorageGroupInfo::TTopology::CreateMapper(TBlobStorageGroupType gtype,
const TTopology *topology)
{
switch (gtype.GetErasure()) {
- case TBlobStorageGroupType::ErasureNone:
- case TBlobStorageGroupType::ErasureMirror3:
- case TBlobStorageGroupType::Erasure3Plus1Block:
- case TBlobStorageGroupType::Erasure3Plus1Stripe:
- case TBlobStorageGroupType::Erasure4Plus2Block:
- case TBlobStorageGroupType::Erasure3Plus2Block:
- case TBlobStorageGroupType::Erasure4Plus2Stripe:
- case TBlobStorageGroupType::Erasure3Plus2Stripe:
- case TBlobStorageGroupType::ErasureMirror3Plus2:
+ case TBlobStorageGroupType::ErasureNone:
+ case TBlobStorageGroupType::ErasureMirror3:
+ case TBlobStorageGroupType::Erasure3Plus1Block:
+ case TBlobStorageGroupType::Erasure3Plus1Stripe:
+ case TBlobStorageGroupType::Erasure4Plus2Block:
+ case TBlobStorageGroupType::Erasure3Plus2Block:
+ case TBlobStorageGroupType::Erasure4Plus2Stripe:
+ case TBlobStorageGroupType::Erasure3Plus2Stripe:
+ case TBlobStorageGroupType::ErasureMirror3Plus2:
case TBlobStorageGroupType::Erasure4Plus3Block:
case TBlobStorageGroupType::Erasure4Plus3Stripe:
case TBlobStorageGroupType::Erasure3Plus3Block:
@@ -465,19 +465,19 @@ IBlobToDiskMapper *TBlobStorageGroupInfo::TTopology::CreateMapper(TBlobStorageGr
case TBlobStorageGroupType::Erasure2Plus3Stripe:
case TBlobStorageGroupType::Erasure2Plus2Block:
case TBlobStorageGroupType::Erasure2Plus2Stripe:
- case TBlobStorageGroupType::ErasureMirror3of4:
+ case TBlobStorageGroupType::ErasureMirror3of4:
return IBlobToDiskMapper::CreateBasicMapper(topology);
-
- case TBlobStorageGroupType::ErasureMirror3dc:
+
+ case TBlobStorageGroupType::ErasureMirror3dc:
return IBlobToDiskMapper::CreateMirror3dcMapper(topology);
default:
Y_FAIL("unexpected erasure type 0x%08" PRIx32, static_cast<ui32>(gtype.GetErasure()));
- }
-
- Y_FAIL();
-}
-
+ }
+
+ Y_FAIL();
+}
+
TBlobStorageGroupInfo::IQuorumChecker *TBlobStorageGroupInfo::TTopology::CreateQuorumChecker(const TTopology *topology) {
switch (topology->GType.GetErasure()) {
case TBlobStorageGroupType::ErasureNone:
@@ -502,9 +502,9 @@ TBlobStorageGroupInfo::IQuorumChecker *TBlobStorageGroupInfo::TTopology::CreateQ
case TBlobStorageGroupType::ErasureMirror3dc:
return new TQuorumCheckerMirror3dc(topology);
- case TBlobStorageGroupType::ErasureMirror3of4:
- return new TQuorumCheckerMirror3of4(topology);
-
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ return new TQuorumCheckerMirror3of4(topology);
+
default:
Y_FAIL("unexpected erasure type 0x%08" PRIx32,
static_cast<ui32>(topology->GType.GetErasure()));
@@ -553,201 +553,201 @@ TBlobStorageGroupInfo::TDynamicInfo::TDynamicInfo(ui32 groupId, ui32 groupGen)
////////////////////////////////////////////////////////////////////////////
// TBlobStorageGroupInfo
////////////////////////////////////////////////////////////////////////////
-TBlobStorageGroupInfo::TBlobStorageGroupInfo(TBlobStorageGroupType gtype, ui32 numVDisksPerFailDomain,
+TBlobStorageGroupInfo::TBlobStorageGroupInfo(TBlobStorageGroupType gtype, ui32 numVDisksPerFailDomain,
ui32 numFailDomains, ui32 numFailRealms, const TVector<TActorId> *vdiskIds, EEncryptionMode encryptionMode,
ELifeCyclePhase lifeCyclePhase, TCypherKey key)
- : GroupID(0)
- , GroupGeneration(1)
- , Type(gtype)
- , Dynamic(GroupID, GroupGeneration)
+ : GroupID(0)
+ , GroupGeneration(1)
+ , Type(gtype)
+ , Dynamic(GroupID, GroupGeneration)
, EncryptionMode(encryptionMode)
, LifeCyclePhase(lifeCyclePhase)
, Key(key)
-{
- if (!numFailDomains) {
- numFailDomains = gtype.BlobSubgroupSize();
- }
-
- TTopology topology(gtype);
- topology.FailRealms.resize(numFailRealms);
- for (TFailRealm& realm : topology.FailRealms) {
- realm.FailDomains.resize(numFailDomains);
- for (TFailDomain& domain : realm.FailDomains) {
- domain.VDisks.resize(numVDisksPerFailDomain);
- }
- }
- Topology = std::make_shared<TTopology>(std::move(topology));
- Topology->FinalizeConstruction();
-
- for (ui32 i = 0, num = Topology->GetTotalVDisksNum(); i < num; ++i) {
- Dynamic.PushBackActorId(vdiskIds ? vdiskIds->at(i) : MakeBlobStorageVDiskID(1, i + 1, 0));
- }
-}
-
-TBlobStorageGroupInfo::TBlobStorageGroupInfo(std::shared_ptr<TTopology> topology, TDynamicInfo&& dyn, TString storagePoolName,
- TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType)
+{
+ if (!numFailDomains) {
+ numFailDomains = gtype.BlobSubgroupSize();
+ }
+
+ TTopology topology(gtype);
+ topology.FailRealms.resize(numFailRealms);
+ for (TFailRealm& realm : topology.FailRealms) {
+ realm.FailDomains.resize(numFailDomains);
+ for (TFailDomain& domain : realm.FailDomains) {
+ domain.VDisks.resize(numVDisksPerFailDomain);
+ }
+ }
+ Topology = std::make_shared<TTopology>(std::move(topology));
+ Topology->FinalizeConstruction();
+
+ for (ui32 i = 0, num = Topology->GetTotalVDisksNum(); i < num; ++i) {
+ Dynamic.PushBackActorId(vdiskIds ? vdiskIds->at(i) : MakeBlobStorageVDiskID(1, i + 1, 0));
+ }
+}
+
+TBlobStorageGroupInfo::TBlobStorageGroupInfo(std::shared_ptr<TTopology> topology, TDynamicInfo&& dyn, TString storagePoolName,
+ TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType)
: GroupID(dyn.GroupId)
, GroupGeneration(dyn.GroupGeneration)
- , Type(topology->GType)
- , Topology(std::move(topology))
+ , Type(topology->GType)
+ , Topology(std::move(topology))
, Dynamic(std::move(dyn))
- , AcceptedScope(acceptedScope)
- , StoragePoolName(std::move(storagePoolName))
+ , AcceptedScope(acceptedScope)
+ , StoragePoolName(std::move(storagePoolName))
, DeviceType(deviceType)
-{}
-
-TBlobStorageGroupInfo::TBlobStorageGroupInfo(TTopology&& topology, TDynamicInfo&& dyn, TString storagePoolName,
- TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType)
- : TBlobStorageGroupInfo(std::make_shared<TTopology>(std::move(topology)), std::move(dyn), std::move(storagePoolName),
- std::move(acceptedScope), deviceType)
+{}
+
+TBlobStorageGroupInfo::TBlobStorageGroupInfo(TTopology&& topology, TDynamicInfo&& dyn, TString storagePoolName,
+ TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType)
+ : TBlobStorageGroupInfo(std::make_shared<TTopology>(std::move(topology)), std::move(dyn), std::move(storagePoolName),
+ std::move(acceptedScope), deviceType)
{
Topology->FinalizeConstruction();
}
-TBlobStorageGroupInfo::TBlobStorageGroupInfo(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TVDiskID& vdiskId,
- const TActorId& actorId)
- : GroupID(vdiskId.GroupID)
- , GroupGeneration(vdiskId.GroupGeneration)
- , Type(info->Type)
- , Topology(info->Topology)
- , Dynamic(GroupID, GroupGeneration)
- , EncryptionMode(info->EncryptionMode)
- , LifeCyclePhase(info->LifeCyclePhase)
- , Key(info->Key)
- , AcceptedScope(info->AcceptedScope)
- , StoragePoolName(info->StoragePoolName)
- , DeviceType(info->DeviceType)
-{
- Dynamic.ServiceIdForOrderNumber.resize(Topology->GetTotalVDisksNum(), TActorId());
- Dynamic.ServiceIdForOrderNumber[GetOrderNumber(vdiskId)] = actorId;
-}
-
+TBlobStorageGroupInfo::TBlobStorageGroupInfo(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TVDiskID& vdiskId,
+ const TActorId& actorId)
+ : GroupID(vdiskId.GroupID)
+ , GroupGeneration(vdiskId.GroupGeneration)
+ , Type(info->Type)
+ , Topology(info->Topology)
+ , Dynamic(GroupID, GroupGeneration)
+ , EncryptionMode(info->EncryptionMode)
+ , LifeCyclePhase(info->LifeCyclePhase)
+ , Key(info->Key)
+ , AcceptedScope(info->AcceptedScope)
+ , StoragePoolName(info->StoragePoolName)
+ , DeviceType(info->DeviceType)
+{
+ Dynamic.ServiceIdForOrderNumber.resize(Topology->GetTotalVDisksNum(), TActorId());
+ Dynamic.ServiceIdForOrderNumber[GetOrderNumber(vdiskId)] = actorId;
+}
+
TBlobStorageGroupInfo::~TBlobStorageGroupInfo()
{}
-TIntrusivePtr<TBlobStorageGroupInfo> TBlobStorageGroupInfo::Parse(const NKikimrBlobStorage::TGroupInfo& group,
- const TEncryptionKey *key, IOutputStream *err) {
- auto erasure = (TBlobStorageGroupType::EErasureSpecies)group.GetErasureSpecies();
- TBlobStorageGroupType type(erasure);
- TBlobStorageGroupInfo::TTopology topology(type);
- TBlobStorageGroupInfo::TDynamicInfo dyn(group.GetGroupID(), group.GetGroupGeneration());
- topology.FailRealms.resize(group.RingsSize());
- for (ui32 ringIdx = 0; ringIdx < group.RingsSize(); ++ringIdx) {
- const auto& realm = group.GetRings(ringIdx);
- TBlobStorageGroupInfo::TFailRealm& bsFailRealm = topology.FailRealms[ringIdx];
- bsFailRealm.FailDomains.resize(realm.FailDomainsSize());
- for (ui32 domainIdx = 0; domainIdx < realm.FailDomainsSize(); ++domainIdx) {
- const auto& domain = realm.GetFailDomains(domainIdx);
- TBlobStorageGroupInfo::TFailDomain& bsDomain = bsFailRealm.FailDomains[domainIdx];
- bsDomain.VDisks.resize(domain.VDiskLocationsSize());
- for (ui32 vdiskIdx = 0; vdiskIdx < domain.VDiskLocationsSize(); ++vdiskIdx) {
- const auto& id = domain.GetVDiskLocations(vdiskIdx);
- TActorId vdiskActorId = MakeBlobStorageVDiskID(id.GetNodeID(), id.GetPDiskID(), id.GetVDiskSlotID());
- dyn.PushBackActorId(vdiskActorId);
- }
- }
- }
- TMaybe<TKikimrScopeId> acceptedScope;
- if (group.HasAcceptedScope()) {
- const auto& scope = group.GetAcceptedScope();
- acceptedScope.ConstructInPlace(scope.GetX1(), scope.GetX2());
- }
- TPDiskCategory::EDeviceType commonDeviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN;
- if (group.HasDeviceType()) {
- commonDeviceType = PDiskTypeToPDiskType(group.GetDeviceType());
- }
- auto res = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dyn), group.GetStoragePoolName(),
- acceptedScope, commonDeviceType);
-
- // process encryption parameters
- res->EncryptionMode = static_cast<EEncryptionMode>(group.GetEncryptionMode());
- if (res->EncryptionMode != EEM_NONE) {
- auto& lcp = res->LifeCyclePhase;
- lcp = static_cast<ELifeCyclePhase>(group.GetLifeCyclePhase());
- switch (lcp) {
- case ELCP_INITIAL:
- case ELCP_IN_TRANSITION:
- break;
-
- case ELCP_IN_USE: {
- const TString mainKeyId = group.GetMainKeyId();
- const ui64 mainKeyVersion = group.GetMainKeyVersion();
- const TString encryptedGroupKey = group.GetEncryptedGroupKey();
- const ui64 groupKeyNonce = group.GetGroupKeyNonce();
-
- if (!key || !*key) {
- lcp = ELCP_KEY_NOT_LOADED;
- } else if (mainKeyId != key->Id) {
- lcp = ELCP_KEY_ID_ERROR;
- } else if (mainKeyVersion != key->Version) {
- lcp = ELCP_KEY_VERSION_ERROR;
- } else if (!DecryptGroupKey(res->EncryptionMode, mainKeyId, encryptedGroupKey, groupKeyNonce, key->Key,
- &res->Key, group.GetGroupID())) {
- lcp = ELCP_KEY_CRC_ERROR;
- res->Key.Wipe();
- } else {
- break;
- }
- if (err) {
- *err << "LifeCyclePhase# " << lcp << " Key.Id# \"" << EscapeC(key->Id)
- << "\" Key.Version# " << key->Version << " MainKey.Id# \"" << EscapeC(mainKeyId)
- << "\" MainKey.Version# " << mainKeyVersion << " GroupKeyNonce# " << groupKeyNonce;
- }
- break;
- }
-
- default:
- Y_VERIFY_DEBUG_S(false, "unexpected LifeCyclePhase# " << lcp);
- if (err) {
- *err << "unexpected LifeCyclePhase# " << lcp;
- }
- break;
- }
- }
-
- // store original group protobuf it was parsed from
- res->Group.emplace(group);
- return res;
-}
-
-bool TBlobStorageGroupInfo::DecryptGroupKey(TBlobStorageGroupInfo::EEncryptionMode encryptionMode,
+TIntrusivePtr<TBlobStorageGroupInfo> TBlobStorageGroupInfo::Parse(const NKikimrBlobStorage::TGroupInfo& group,
+ const TEncryptionKey *key, IOutputStream *err) {
+ auto erasure = (TBlobStorageGroupType::EErasureSpecies)group.GetErasureSpecies();
+ TBlobStorageGroupType type(erasure);
+ TBlobStorageGroupInfo::TTopology topology(type);
+ TBlobStorageGroupInfo::TDynamicInfo dyn(group.GetGroupID(), group.GetGroupGeneration());
+ topology.FailRealms.resize(group.RingsSize());
+ for (ui32 ringIdx = 0; ringIdx < group.RingsSize(); ++ringIdx) {
+ const auto& realm = group.GetRings(ringIdx);
+ TBlobStorageGroupInfo::TFailRealm& bsFailRealm = topology.FailRealms[ringIdx];
+ bsFailRealm.FailDomains.resize(realm.FailDomainsSize());
+ for (ui32 domainIdx = 0; domainIdx < realm.FailDomainsSize(); ++domainIdx) {
+ const auto& domain = realm.GetFailDomains(domainIdx);
+ TBlobStorageGroupInfo::TFailDomain& bsDomain = bsFailRealm.FailDomains[domainIdx];
+ bsDomain.VDisks.resize(domain.VDiskLocationsSize());
+ for (ui32 vdiskIdx = 0; vdiskIdx < domain.VDiskLocationsSize(); ++vdiskIdx) {
+ const auto& id = domain.GetVDiskLocations(vdiskIdx);
+ TActorId vdiskActorId = MakeBlobStorageVDiskID(id.GetNodeID(), id.GetPDiskID(), id.GetVDiskSlotID());
+ dyn.PushBackActorId(vdiskActorId);
+ }
+ }
+ }
+ TMaybe<TKikimrScopeId> acceptedScope;
+ if (group.HasAcceptedScope()) {
+ const auto& scope = group.GetAcceptedScope();
+ acceptedScope.ConstructInPlace(scope.GetX1(), scope.GetX2());
+ }
+ TPDiskCategory::EDeviceType commonDeviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN;
+ if (group.HasDeviceType()) {
+ commonDeviceType = PDiskTypeToPDiskType(group.GetDeviceType());
+ }
+ auto res = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dyn), group.GetStoragePoolName(),
+ acceptedScope, commonDeviceType);
+
+ // process encryption parameters
+ res->EncryptionMode = static_cast<EEncryptionMode>(group.GetEncryptionMode());
+ if (res->EncryptionMode != EEM_NONE) {
+ auto& lcp = res->LifeCyclePhase;
+ lcp = static_cast<ELifeCyclePhase>(group.GetLifeCyclePhase());
+ switch (lcp) {
+ case ELCP_INITIAL:
+ case ELCP_IN_TRANSITION:
+ break;
+
+ case ELCP_IN_USE: {
+ const TString mainKeyId = group.GetMainKeyId();
+ const ui64 mainKeyVersion = group.GetMainKeyVersion();
+ const TString encryptedGroupKey = group.GetEncryptedGroupKey();
+ const ui64 groupKeyNonce = group.GetGroupKeyNonce();
+
+ if (!key || !*key) {
+ lcp = ELCP_KEY_NOT_LOADED;
+ } else if (mainKeyId != key->Id) {
+ lcp = ELCP_KEY_ID_ERROR;
+ } else if (mainKeyVersion != key->Version) {
+ lcp = ELCP_KEY_VERSION_ERROR;
+ } else if (!DecryptGroupKey(res->EncryptionMode, mainKeyId, encryptedGroupKey, groupKeyNonce, key->Key,
+ &res->Key, group.GetGroupID())) {
+ lcp = ELCP_KEY_CRC_ERROR;
+ res->Key.Wipe();
+ } else {
+ break;
+ }
+ if (err) {
+ *err << "LifeCyclePhase# " << lcp << " Key.Id# \"" << EscapeC(key->Id)
+ << "\" Key.Version# " << key->Version << " MainKey.Id# \"" << EscapeC(mainKeyId)
+ << "\" MainKey.Version# " << mainKeyVersion << " GroupKeyNonce# " << groupKeyNonce;
+ }
+ break;
+ }
+
+ default:
+ Y_VERIFY_DEBUG_S(false, "unexpected LifeCyclePhase# " << lcp);
+ if (err) {
+ *err << "unexpected LifeCyclePhase# " << lcp;
+ }
+ break;
+ }
+ }
+
+ // store original group protobuf it was parsed from
+ res->Group.emplace(group);
+ return res;
+}
+
+bool TBlobStorageGroupInfo::DecryptGroupKey(TBlobStorageGroupInfo::EEncryptionMode encryptionMode,
const TString& /*mainKeyId*/, const TString& encryptedGroupKey, ui64 groupKeyNonce, const TCypherKey& tenantKey,
- TCypherKey *outGroupKey, ui32 groupId) {
- switch (encryptionMode) {
- case TBlobStorageGroupInfo::EEM_NONE:
- return true;
- case TBlobStorageGroupInfo::EEM_ENC_V1:
- {
- // Decrypt the 'Group key' with the 'Tenant key'
- ui8* keyBytes = nullptr;
- ui32 keySize = 0;
- outGroupKey->MutableKeyBytes(&keyBytes, &keySize);
-
- TStreamCypher cypher;
- bool isKeySet = cypher.SetKey(tenantKey);
- Y_VERIFY(isKeySet);
- cypher.StartMessage(groupKeyNonce, 0);
-
- ui32 h = 0;
- Y_VERIFY(encryptedGroupKey.size() == keySize + sizeof(h),
- "Unexpected encryptedGroupKeySize# %" PRIu32 " keySize# %" PRIu32 " sizeof(h)# %" PRIu32
- " groupId# %" PRIu32 " encryptedGroupKey# \"%s\"",
- (ui32)encryptedGroupKey.size(), (ui32)keySize, (ui32)sizeof(h), (ui32)groupId,
- EscapeC(encryptedGroupKey).c_str());
- cypher.Encrypt(keyBytes, encryptedGroupKey.data(), keySize);
- cypher.Encrypt(&h, encryptedGroupKey.data() + keySize, sizeof(h));
-
- bool isHashGood = (h == Crc32c(keyBytes, keySize));
- return isHashGood;
- }
- }
- Y_FAIL("Unexpected Encryption Mode# %" PRIu64, (ui64)encryptionMode);
-}
-
-const TBlobStorageGroupInfo::IQuorumChecker& TBlobStorageGroupInfo::GetQuorumChecker() const {
+ TCypherKey *outGroupKey, ui32 groupId) {
+ switch (encryptionMode) {
+ case TBlobStorageGroupInfo::EEM_NONE:
+ return true;
+ case TBlobStorageGroupInfo::EEM_ENC_V1:
+ {
+ // Decrypt the 'Group key' with the 'Tenant key'
+ ui8* keyBytes = nullptr;
+ ui32 keySize = 0;
+ outGroupKey->MutableKeyBytes(&keyBytes, &keySize);
+
+ TStreamCypher cypher;
+ bool isKeySet = cypher.SetKey(tenantKey);
+ Y_VERIFY(isKeySet);
+ cypher.StartMessage(groupKeyNonce, 0);
+
+ ui32 h = 0;
+ Y_VERIFY(encryptedGroupKey.size() == keySize + sizeof(h),
+ "Unexpected encryptedGroupKeySize# %" PRIu32 " keySize# %" PRIu32 " sizeof(h)# %" PRIu32
+ " groupId# %" PRIu32 " encryptedGroupKey# \"%s\"",
+ (ui32)encryptedGroupKey.size(), (ui32)keySize, (ui32)sizeof(h), (ui32)groupId,
+ EscapeC(encryptedGroupKey).c_str());
+ cypher.Encrypt(keyBytes, encryptedGroupKey.data(), keySize);
+ cypher.Encrypt(&h, encryptedGroupKey.data() + keySize, sizeof(h));
+
+ bool isHashGood = (h == Crc32c(keyBytes, keySize));
+ return isHashGood;
+ }
+ }
+ Y_FAIL("Unexpected Encryption Mode# %" PRIu64, (ui64)encryptionMode);
+}
+
+const TBlobStorageGroupInfo::IQuorumChecker& TBlobStorageGroupInfo::GetQuorumChecker() const {
return Topology->GetQuorumChecker();
-}
-
+}
+
TVDiskID TBlobStorageGroupInfo::CreateVDiskID(const TVDiskIdShort &id) const {
return TVDiskID(GroupID, GroupGeneration, id.FailRealm, id.FailDomain, id.VDisk);
}
@@ -773,7 +773,7 @@ TBlobStorageGroupInfo::EBlobState TBlobStorageGroupInfo::BlobState(ui32 effectiv
return GetTopology().BlobState(effectiveReplicas, errorDomains);
}
-void TBlobStorageGroupInfo::PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServiceIds *outServiceIds) const {
+void TBlobStorageGroupInfo::PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServiceIds *outServiceIds) const {
TOrderNums orderNums;
Topology->PickSubgroup(hash, orderNums);
for (const auto x : orderNums) {
@@ -786,22 +786,22 @@ void TBlobStorageGroupInfo::PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServic
}
}
-bool TBlobStorageGroupInfo::BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const {
+bool TBlobStorageGroupInfo::BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const {
Y_VERIFY_DEBUG_S(vdisk.GroupID == GroupID, "Expected GroupID# " << GroupID << ", given GroupID# " << vdisk.GroupID);
Y_VERIFY_DEBUG_S(vdisk.GroupGeneration == GroupGeneration, "Expected GroupGeeration# " << GroupGeneration
<< ", given GroupGeneration# " << vdisk.GroupGeneration);
return Topology->BelongsToSubgroup(TVDiskIdShort(vdisk), hash);
}
-// Returns either vdisk idx in the blob subgroup, or BlobSubgroupSize if the vdisk is not in the blob subgroup
-ui32 TBlobStorageGroupInfo::GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const {
+// Returns either vdisk idx in the blob subgroup, or BlobSubgroupSize if the vdisk is not in the blob subgroup
+ui32 TBlobStorageGroupInfo::GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const {
Y_VERIFY_DEBUG_S(vdisk.GroupID == GroupID, "Expected GroupID# " << GroupID << ", given GroupID# " << vdisk.GroupID);
Y_VERIFY_DEBUG_S(vdisk.GroupGeneration == GroupGeneration, "Expected GroupGeeration# " << GroupGeneration
<< ", given GroupGeneration# " << vdisk.GroupGeneration);
return Topology->GetIdxInSubgroup(vdisk, hash);
}
-TVDiskID TBlobStorageGroupInfo::GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const {
+TVDiskID TBlobStorageGroupInfo::GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const {
auto shortId = Topology->GetVDiskInSubgroup(idxInSubgroup, hash);
return TVDiskID(GroupID, GroupGeneration, shortId);
}
@@ -811,7 +811,7 @@ ui32 TBlobStorageGroupInfo::GetOrderNumber(const TVDiskID &vdisk) const {
Y_VERIFY_S(vdisk.GroupGeneration == GroupGeneration, "Expected GroupGeeration# " << GroupGeneration
<< ", given GroupGeneration# " << vdisk.GroupGeneration);
return Topology->GetOrderNumber(vdisk);
-}
+}
ui32 TBlobStorageGroupInfo::GetOrderNumber(const TVDiskIdShort &vdisk) const {
return Topology->GetOrderNumber(vdisk);
@@ -825,15 +825,15 @@ bool TBlobStorageGroupInfo::IsValidId(const TVDiskIdShort &vdisk) const {
return Topology->IsValidId(vdisk);
}
-ui32 TBlobStorageGroupInfo::GetFailDomainOrderNumber(const TVDiskID& vdisk) const {
+ui32 TBlobStorageGroupInfo::GetFailDomainOrderNumber(const TVDiskID& vdisk) const {
return Topology->GetFailDomainOrderNumber(vdisk);
-}
-
+}
+
ui32 TBlobStorageGroupInfo::GetFailDomainOrderNumber(const TVDiskIdShort& vdisk) const {
return Topology->GetFailDomainOrderNumber(vdisk);
}
-TVDiskID TBlobStorageGroupInfo::GetVDiskId(ui32 orderNumber) const {
+TVDiskID TBlobStorageGroupInfo::GetVDiskId(ui32 orderNumber) const {
return TVDiskID(GroupID, GroupGeneration, Topology->GetVDiskId(orderNumber));
}
@@ -849,59 +849,59 @@ TActorId TBlobStorageGroupInfo::GetActorId(const TVDiskIdShort &vd) const {
return GetActorId(Topology->GetOrderNumber(vd));
}
-ui32 TBlobStorageGroupInfo::GetTotalVDisksNum() const {
+ui32 TBlobStorageGroupInfo::GetTotalVDisksNum() const {
return Topology->GetTotalVDisksNum();
}
-ui32 TBlobStorageGroupInfo::GetTotalFailDomainsNum() const {
+ui32 TBlobStorageGroupInfo::GetTotalFailDomainsNum() const {
return Topology->GetTotalFailDomainsNum();
-}
-
-ui32 TBlobStorageGroupInfo::GetNumVDisksPerFailDomain() const {
+}
+
+ui32 TBlobStorageGroupInfo::GetNumVDisksPerFailDomain() const {
return Topology->GetNumVDisksPerFailDomain();
}
-const TBlobStorageGroupInfo::TFailDomain& TBlobStorageGroupInfo::GetFailDomain(const TVDiskID& vdisk) const {
+const TBlobStorageGroupInfo::TFailDomain& TBlobStorageGroupInfo::GetFailDomain(const TVDiskID& vdisk) const {
return Topology->GetFailDomain(vdisk);
-}
-
-const TBlobStorageGroupInfo::TFailDomain& TBlobStorageGroupInfo::GetFailDomain(ui32 failDomainOrderNumber) const {
+}
+
+const TBlobStorageGroupInfo::TFailDomain& TBlobStorageGroupInfo::GetFailDomain(ui32 failDomainOrderNumber) const {
return Topology->GetFailDomain(failDomainOrderNumber);
}
TString TBlobStorageGroupInfo::ToString() const {
TStringStream str;
- str << "{GroupID# " << GroupID;
- str << " GroupGeneration# " << GroupGeneration;
- str << " Type# " << Type.ToString();
- str << " FailRealms# {";
+ str << "{GroupID# " << GroupID;
+ str << " GroupGeneration# " << GroupGeneration;
+ str << " Type# " << Type.ToString();
+ str << " FailRealms# {";
for (ui32 realmIdx = 0; realmIdx < Topology->FailRealms.size(); ++realmIdx) {
const TFailRealm& realm = Topology->FailRealms[realmIdx];
- str << (realmIdx ? " " : "") << "[" << realmIdx << "]# TFailRealm{ FailDomains# {";
- for (ui32 domainIdx = 0; domainIdx < realm.FailDomains.size(); ++domainIdx) {
- const TFailDomain& domain = realm.FailDomains[domainIdx];
- str << (domainIdx ? " " : "") << "[" << domainIdx << "]# TFailDomain{";
- str << "FailDomainOrderNumber# " << domain.FailDomainOrderNumber
- << " VDisks# {";
- for (ui32 vdiskIdx = 0; vdiskIdx < domain.VDisks.size(); ++vdiskIdx) {
- const TVDiskInfo& info = domain.VDisks[vdiskIdx];
- str << (vdiskIdx ? " " : "") << "[" << vdiskIdx << "]# TVDiskInfo{"
+ str << (realmIdx ? " " : "") << "[" << realmIdx << "]# TFailRealm{ FailDomains# {";
+ for (ui32 domainIdx = 0; domainIdx < realm.FailDomains.size(); ++domainIdx) {
+ const TFailDomain& domain = realm.FailDomains[domainIdx];
+ str << (domainIdx ? " " : "") << "[" << domainIdx << "]# TFailDomain{";
+ str << "FailDomainOrderNumber# " << domain.FailDomainOrderNumber
+ << " VDisks# {";
+ for (ui32 vdiskIdx = 0; vdiskIdx < domain.VDisks.size(); ++vdiskIdx) {
+ const TVDiskInfo& info = domain.VDisks[vdiskIdx];
+ str << (vdiskIdx ? " " : "") << "[" << vdiskIdx << "]# TVDiskInfo{"
<< "ActorId# " << GetActorId(info.OrderNumber)
<< " VDiskId# " << GetVDiskId(info.OrderNumber)
- << " OrderNumber# " << info.OrderNumber
- << " FailDomainOrderNumber# " << info.FailDomainOrderNumber
- << "}";
+ << " OrderNumber# " << info.OrderNumber
+ << " FailDomainOrderNumber# " << info.FailDomainOrderNumber
+ << "}";
}
str << "}";
}
- str << "}}";
+ str << "}}";
}
str << "}}";
return str.Str();
}
-
+
TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x) {
return TVDiskID(x.GetGroupID(), x.GetGroupGeneration(), x.GetRing(), x.GetDomain(), x.GetVDisk());
}
@@ -909,8 +909,8 @@ TVDiskID VDiskIDFromVDiskID(const NKikimrBlobStorage::TVDiskID &x) {
void VDiskIDFromVDiskID(const TVDiskID &id, NKikimrBlobStorage::TVDiskID *proto) {
proto->SetGroupID(id.GroupID);
proto->SetGroupGeneration(id.GroupGeneration);
- proto->SetRing(id.FailRealm);
- proto->SetDomain(id.FailDomain);
+ proto->SetRing(id.FailRealm);
+ proto->SetDomain(id.FailDomain);
proto->SetVDisk(id.VDisk);
}
@@ -1133,14 +1133,14 @@ TString TFailDomain::ToString() const {
return builder;
}
-TFailDomain TFailDomain::Slice(ui32 level) const {
- TFailDomain res;
- for (const auto& [key, value] : Levels) {
- if (key < level) {
- res.Levels.emplace_hint(res.Levels.end(), key, value);
- }
- }
- return res;
-}
-
-}
+TFailDomain TFailDomain::Slice(ui32 level) const {
+ TFailDomain res;
+ for (const auto& [key, value] : Levels) {
+ if (key < level) {
+ res.Levels.emplace_hint(res.Levels.end(), key, value);
+ }
+ }
+ return res;
+}
+
+}
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h
index e2d1445be4e..727f0e05a9c 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h
@@ -1,60 +1,60 @@
#pragma once
-
+
#include "defs.h"
#include <ydb/core/blobstorage/base/blobstorage_vdiskid.h>
#include <ydb/core/blobstorage/crypto/crypto.h>
-
+
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/base/event_filter.h>
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/util/log_priority_mute_checker.h>
-
+
#include <util/str_stl.h>
#include <util/digest/numeric.h>
-#include <util/generic/hash_set.h>
-
-namespace NActors {
- class TNodeLocation;
-} // NActors
+#include <util/generic/hash_set.h>
+namespace NActors {
+ class TNodeLocation;
+} // NActors
+
namespace NKikimr {
struct TDsProxyNodeMon;
-class TSubgroupPartLayout;
-
-namespace NBlobMapper {
- class TBasicMapper;
- class TMirror3dcMapper;
-} // NBlobMapper
-
-static constexpr ui8 MaxHandoffNodes = 6;
+class TSubgroupPartLayout;
+
+namespace NBlobMapper {
+ class TBasicMapper;
+ class TMirror3dcMapper;
+} // NBlobMapper
+
+static constexpr ui8 MaxHandoffNodes = 6;
static constexpr ui8 MaxNodesPerBlob = 10;
static constexpr ui8 MaxTotalPartCount = 7;
static constexpr ui8 MaxVDisksInGroup = 32;
-
-// mapper interface forward declaration
-struct IBlobToDiskMapper;
-
-// encryption key for the group
-struct TEncryptionKey {
- TCypherKey Key;
- ui64 Version = 0;
- TString Id;
-
- TString ToString() const {
- return TStringBuilder() << "{Id# '" << EscapeC(Id) << "' Version# " << Version << "}";
- }
-
- explicit operator bool() const { // returns true if the key is set
- return Key.GetIsKeySet();
- }
-
- explicit operator const TCypherKey&() const {
- return Key;
- }
-};
-
+
+// mapper interface forward declaration
+struct IBlobToDiskMapper;
+
+// encryption key for the group
+struct TEncryptionKey {
+ TCypherKey Key;
+ ui64 Version = 0;
+ TString Id;
+
+ TString ToString() const {
+ return TStringBuilder() << "{Id# '" << EscapeC(Id) << "' Version# " << Version << "}";
+ }
+
+ explicit operator bool() const { // returns true if the key is set
+ return Key.GetIsKeySet();
+ }
+
+ explicit operator const TCypherKey&() const {
+ return Key;
+ }
+};
+
// current state of storage group
class TBlobStorageGroupInfo : public TThrRefBase {
public:
@@ -75,7 +75,7 @@ public:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TYPES
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- using TVDiskIds = TStackVec<TVDiskID, 16>;
+ using TVDiskIds = TStackVec<TVDiskID, 16>;
using TServiceIds = TStackVec<TActorId, 16>;
using TOrderNums = TStackVec<ui32, 16>;
@@ -112,8 +112,8 @@ public:
ELCP_IN_USE = 3,
ELCP_KEY_CRC_ERROR = 700,
ELCP_KEY_VERSION_ERROR = 701,
- ELCP_KEY_ID_ERROR = 702,
- ELCP_KEY_NOT_LOADED = 703,
+ ELCP_KEY_ID_ERROR = 702,
+ ELCP_KEY_NOT_LOADED = 703,
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -136,14 +136,14 @@ public:
virtual bool CheckQuorumForSubgroup(const TSubgroupVDisks& subgroupDisks) const = 0;
virtual bool CheckQuorumForGroup(const TGroupVDisks& groupDisks) const = 0;
virtual bool CheckQuorumForGroupDomains(const TGroupFailDomains& domains) const = 0;
- virtual bool IsDegraded(const TGroupVDisks& failedDisks) const = 0;
- virtual bool OneStepFromDegradedOrWorse(const TGroupVDisks& failedDisks) const = 0;
+ virtual bool IsDegraded(const TGroupVDisks& failedDisks) const = 0;
+ virtual bool OneStepFromDegradedOrWorse(const TGroupVDisks& failedDisks) const = 0;
virtual EBlobState GetBlobState(const TSubgroupPartLayout& parts, const TSubgroupVDisks& failedDisks) const = 0;
-
- // check if we need to resurrect something; returns bit mask of parts needed for specified disk in group,
- // nth bit represents nth part; all returned parts are suitable for this particular disk
- virtual ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const = 0;
+
+ // check if we need to resurrect something; returns bit mask of parts needed for specified disk in group,
+ // nth bit represents nth part; all returned parts are suitable for this particular disk
+ virtual ui32 GetPartsToResurrect(const TSubgroupPartLayout& parts, ui32 idxInSubgroup) const = 0;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -152,46 +152,46 @@ public:
struct TVDiskInfo {
// short VDisk identifier
TVDiskIdShort VDiskIdShort;
-
- // order number inside this group; starting from 0 up to, but not including GetNumTotalVDisks()
+
+ // order number inside this group; starting from 0 up to, but not including GetNumTotalVDisks()
ui32 OrderNumber = 0;
-
- // order number of fail domain this VDisk resides in; fail domains are numbered continuously through all fail
- // realms
- ui32 FailDomainOrderNumber = 0;
+
+ // order number of fail domain this VDisk resides in; fail domains are numbered continuously through all fail
+ // realms
+ ui32 FailDomainOrderNumber = 0;
};
struct TFailDomain {
- // VDisks composing this fail domain
+ // VDisks composing this fail domain
TVector<TVDiskInfo> VDisks;
-
- // fail domain order number; domains are numbered continuously through all fail realms
- ui32 FailDomainOrderNumber = 0;
+
+ // fail domain order number; domains are numbered continuously through all fail realms
+ ui32 FailDomainOrderNumber = 0;
};
- struct TFailRealm {
- // fail domains contained in this fail realm
+ struct TFailRealm {
+ // fail domains contained in this fail realm
TVector<TFailDomain> FailDomains;
};
struct TTopology {
// group type (i.e. erasure)
const TBlobStorageGroupType GType;
- // fail realms in this group
+ // fail realms in this group
TVector<TFailRealm> FailRealms;
// total number of fail domains in this group
ui32 TotalFailDomains = 0;
// total number of vdisks
ui32 TotalVDisks = 0;
// maps blobs to disks in topology
- std::unique_ptr<IBlobToDiskMapper> BlobMapper;
+ std::unique_ptr<IBlobToDiskMapper> BlobMapper;
// quorum checker
- std::unique_ptr<IQuorumChecker> QuorumChecker;
+ std::unique_ptr<IQuorumChecker> QuorumChecker;
// map to quickly get (Short)VDisk id from its order number inside the group
TVector<TVDiskIdShort> VDiskIdForOrderNumber;
- TTopology(TBlobStorageGroupType gtype);
- TTopology(TBlobStorageGroupType gtype, ui32 numFailRealms, ui32 numFailDomainsPerFailRealm, ui32 numVDisksPerFailDomain);
+ TTopology(TBlobStorageGroupType gtype);
+ TTopology(TBlobStorageGroupType gtype, ui32 numFailRealms, ui32 numFailDomainsPerFailRealm, ui32 numVDisksPerFailDomain);
TTopology(const TTopology&) = delete;
TTopology &operator =(const TTopology&) = delete;
TTopology(TTopology&&) = default;
@@ -261,10 +261,10 @@ public:
TString ToString() const;
private:
- static IBlobToDiskMapper *CreateMapper(TBlobStorageGroupType gtype, const TTopology *topology);
+ static IBlobToDiskMapper *CreateMapper(TBlobStorageGroupType gtype, const TTopology *topology);
static IQuorumChecker *CreateQuorumChecker(const TTopology *topology);
- };
-
+ };
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DYNAMIC INFO
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -287,43 +287,43 @@ public:
}
};
- const IQuorumChecker& GetQuorumChecker() const;
+ const IQuorumChecker& GetQuorumChecker() const;
const TTopology &GetTopology() const { return *Topology; }
const TDynamicInfo &GetDynamicInfo() const { return Dynamic; }
EEncryptionMode GetEncryptionMode() const { return EncryptionMode; }
ELifeCyclePhase GetLifeCyclePhase() const { return LifeCyclePhase; }
ui64 GetGroupKeyNonce() const { return GroupKeyNonce; }
const TCypherKey* GetCypherKey() const { return &Key; }
- std::shared_ptr<TTopology> PickTopology() const { return Topology; }
-
- // for testing purposes; numFailDomains = 0 automatically selects possible minimum for provided erasure; groupId=0
- // and groupGen=1 for constructed group
- explicit TBlobStorageGroupInfo(TBlobStorageGroupType gtype, ui32 numVDisksPerFailDomain = 1,
+ std::shared_ptr<TTopology> PickTopology() const { return Topology; }
+
+ // for testing purposes; numFailDomains = 0 automatically selects possible minimum for provided erasure; groupId=0
+ // and groupGen=1 for constructed group
+ explicit TBlobStorageGroupInfo(TBlobStorageGroupType gtype, ui32 numVDisksPerFailDomain = 1,
ui32 numFailDomains = 0, ui32 numFailRealms = 1, const TVector<TActorId> *vdiskIds = nullptr,
- EEncryptionMode encryptionMode = EEM_ENC_V1, ELifeCyclePhase lifeCyclePhase = ELCP_IN_USE,
+ EEncryptionMode encryptionMode = EEM_ENC_V1, ELifeCyclePhase lifeCyclePhase = ELCP_IN_USE,
TCypherKey key = TCypherKey((const ui8*)"TestKey", 8));
-
- TBlobStorageGroupInfo(std::shared_ptr<TTopology> topology, TDynamicInfo&& rti, TString storagePoolName,
- TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType);
-
- TBlobStorageGroupInfo(TTopology&& topology, TDynamicInfo&& rti, TString storagePoolName,
- TMaybe<TKikimrScopeId> acceptedScope = {}, TPDiskCategory::EDeviceType deviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN);
-
- TBlobStorageGroupInfo(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TVDiskID& vdiskId, const TActorId& actorId);
-
- ~TBlobStorageGroupInfo();
-
- static TIntrusivePtr<TBlobStorageGroupInfo> Parse(const NKikimrBlobStorage::TGroupInfo& group,
- const TEncryptionKey *key, IOutputStream *err);
+
+ TBlobStorageGroupInfo(std::shared_ptr<TTopology> topology, TDynamicInfo&& rti, TString storagePoolName,
+ TMaybe<TKikimrScopeId> acceptedScope, TPDiskCategory::EDeviceType deviceType);
+
+ TBlobStorageGroupInfo(TTopology&& topology, TDynamicInfo&& rti, TString storagePoolName,
+ TMaybe<TKikimrScopeId> acceptedScope = {}, TPDiskCategory::EDeviceType deviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN);
+
+ TBlobStorageGroupInfo(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TVDiskID& vdiskId, const TActorId& actorId);
+
+ ~TBlobStorageGroupInfo();
+
+ static TIntrusivePtr<TBlobStorageGroupInfo> Parse(const NKikimrBlobStorage::TGroupInfo& group,
+ const TEncryptionKey *key, IOutputStream *err);
static bool DecryptGroupKey(TBlobStorageGroupInfo::EEncryptionMode encryptionMode, const TString& mainKeyId,
- const TString& encryptedGroupKey, ui64 groupKeyNonce, const TCypherKey& tenantKey, TCypherKey *outGroupKey,
- ui32 groupId);
-
- TString GetStoragePoolName() const {
- return StoragePoolName ? StoragePoolName : "static";
- }
-
+ const TString& encryptedGroupKey, ui64 groupKeyNonce, const TCypherKey& tenantKey, TCypherKey *outGroupKey,
+ ui32 groupId);
+
+ TString GetStoragePoolName() const {
+ return StoragePoolName ? StoragePoolName : "static";
+ }
+
TPDiskCategory::EDeviceType GetDeviceType() const {
return DeviceType;
}
@@ -332,77 +332,77 @@ public:
static TString BlobStateToString(EBlobState);
EBlobState BlobState(ui32 effectiveReplicas, ui32 errorDomains) const;
- void PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServiceIds *outServiceIds) const;
- bool BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const;
- ui32 GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const;
- TVDiskID GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const;
+ void PickSubgroup(ui32 hash, TVDiskIds *outVDisk, TServiceIds *outServiceIds) const;
+ bool BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const;
+ ui32 GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const;
+ TVDiskID GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const;
bool IsValidId(const TVDiskID &vdisk) const;
bool IsValidId(const TVDiskIdShort &vdisk) const;
ui32 GetOrderNumber(const TVDiskID &vdisk) const;
ui32 GetOrderNumber(const TVDiskIdShort &vdisk) const;
-
- // obtain logical fail domain index -- through number for mirror-3-dc and per-ring for other erasures
- ui32 GetFailDomainOrderNumber(const TVDiskID& vdisk) const;
+
+ // obtain logical fail domain index -- through number for mirror-3-dc and per-ring for other erasures
+ ui32 GetFailDomainOrderNumber(const TVDiskID& vdisk) const;
// obtain logical fail domain index -- through number for mirror-3-dc and per-ring for other erasures
ui32 GetFailDomainOrderNumber(const TVDiskIdShort& vdisk) const;
- // get VDisk by specified orderNumber (in range 0...TotalVDisks)
- TVDiskID GetVDiskId(ui32 orderNumber) const;
+ // get VDisk by specified orderNumber (in range 0...TotalVDisks)
+ TVDiskID GetVDiskId(ui32 orderNumber) const;
// obtain full vdisk id having just short vdisk id
TVDiskID GetVDiskId(const TVDiskIdShort &vd) const;
// get ActorID by specified orderNumber (in range 0...TotalVDisks)
TActorId GetActorId(ui32 orderNumber) const;
// get ActorID having just short vdisk id
TActorId GetActorId(const TVDiskIdShort &vdisk) const;
- // get the total number of VDisks in this group
- ui32 GetTotalVDisksNum() const;
- // get the total number of fail domains in this group
- ui32 GetTotalFailDomainsNum() const;
+ // get the total number of VDisks in this group
+ ui32 GetTotalVDisksNum() const;
+ // get the total number of fail domains in this group
+ ui32 GetTotalFailDomainsNum() const;
// get number of VDisks per fail domain
- ui32 GetNumVDisksPerFailDomain() const;
-
+ ui32 GetNumVDisksPerFailDomain() const;
+
TString ToString() const;
-
- TFailRealmIterator FailRealmsBegin() const;
- TFailRealmIterator FailRealmsEnd() const;
-
- TFailDomainIterator FailDomainsBegin() const;
- TFailDomainIterator FailDomainsEnd() const;
-
- TVDiskIterator VDisksBegin() const;
- TVDiskIterator VDisksEnd() const;
-
- // get all fail domains of this group info (or for specific ring)
- TFailDomainRange GetFailDomains() const;
- // get all VDisks of this group info (or for specific ring)
- TVDiskRange GetVDisks() const;
+
+ TFailRealmIterator FailRealmsBegin() const;
+ TFailRealmIterator FailRealmsEnd() const;
+
+ TFailDomainIterator FailDomainsBegin() const;
+ TFailDomainIterator FailDomainsEnd() const;
+
+ TVDiskIterator VDisksBegin() const;
+ TVDiskIterator VDisksEnd() const;
+
+ // get all fail domains of this group info (or for specific ring)
+ TFailDomainRange GetFailDomains() const;
+ // get all VDisks of this group info (or for specific ring)
+ TVDiskRange GetVDisks() const;
// obtain iterator for vdisk
- TVDiskIterator FindVDisk(const TVDiskID& vdisk) const;
-
- bool CheckScope(const TKikimrScopeId& scopeId, const TActorContext& ctx, bool allowLocalScope) const {
- if (allowLocalScope) {
- if (scopeId == AppData(ctx)->LocalScopeId || scopeId.GetInterconnectScopeId() == TScopeId::LocallyGenerated) {
- return true;
- }
- }
- return !AcceptedScope || *AcceptedScope == scopeId || scopeId == TKikimrScopeId::DynamicTenantScopeId;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // encryption parameters handling
-
-private:
- template<typename TBaseIter, typename TParentIter, typename TDerived>
- class TIteratorBase;
-
- class TRootIteratorBase;
-
-private:
- friend class NBlobMapper::TBasicMapper;
- friend class NBlobMapper::TMirror3dcMapper;
- const TFailDomain& GetFailDomain(const TVDiskID& vdisk) const;
- const TFailDomain& GetFailDomain(ui32 failDomainOrderNumber) const;
-
+ TVDiskIterator FindVDisk(const TVDiskID& vdisk) const;
+
+ bool CheckScope(const TKikimrScopeId& scopeId, const TActorContext& ctx, bool allowLocalScope) const {
+ if (allowLocalScope) {
+ if (scopeId == AppData(ctx)->LocalScopeId || scopeId.GetInterconnectScopeId() == TScopeId::LocallyGenerated) {
+ return true;
+ }
+ }
+ return !AcceptedScope || *AcceptedScope == scopeId || scopeId == TKikimrScopeId::DynamicTenantScopeId;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // encryption parameters handling
+
+private:
+ template<typename TBaseIter, typename TParentIter, typename TDerived>
+ class TIteratorBase;
+
+ class TRootIteratorBase;
+
+private:
+ friend class NBlobMapper::TBasicMapper;
+ friend class NBlobMapper::TMirror3dcMapper;
+ const TFailDomain& GetFailDomain(const TVDiskID& vdisk) const;
+ const TFailDomain& GetFailDomain(ui32 failDomainOrderNumber) const;
+
public:
// blobstorage group id
const ui32 GroupID;
@@ -410,14 +410,14 @@ public:
const ui32 GroupGeneration;
// erasure primarily
const TBlobStorageGroupType Type;
- // origin of the group info content
- std::optional<NKikimrBlobStorage::TGroupInfo> Group;
+ // origin of the group info content
+ std::optional<NKikimrBlobStorage::TGroupInfo> Group;
TAtomicLogPriorityMuteChecker<NLog::PRI_ERROR, NLog::PRI_DEBUG> PutErrorMuteChecker;
-
-private:
+
+private:
// group topology -- all disks inside this group
- std::shared_ptr<TTopology> Topology;
+ std::shared_ptr<TTopology> Topology;
// run type info about group (i.e. actor ids)
TDynamicInfo Dynamic;
// encryption mode
@@ -425,9 +425,9 @@ private:
ELifeCyclePhase LifeCyclePhase = ELCP_INITIAL;
ui64 GroupKeyNonce = 0;
TCypherKey Key;
- // access control
- TMaybe<TKikimrScopeId> AcceptedScope;
- TString StoragePoolName;
+ // access control
+ TMaybe<TKikimrScopeId> AcceptedScope;
+ TString StoragePoolName;
TPDiskCategory::EDeviceType DeviceType = TPDiskCategory::DEVICE_TYPE_UNKNOWN;
};
@@ -458,13 +458,13 @@ struct TFailDomain {
bool IsDifferentAt(const TLevelIds &id, const TFailDomain &other) const;
bool operator<(const TFailDomain &other) const;
TString ToString() const;
- TFailDomain Slice(ui32 level) const;
+ TFailDomain Slice(ui32 level) const;
};
} // NKikimr
-template<>
-inline void Out<NKikimr::TBlobStorageGroupInfo::EEncryptionMode>(IOutputStream& o, NKikimr::TBlobStorageGroupInfo::EEncryptionMode e) {
+template<>
+inline void Out<NKikimr::TBlobStorageGroupInfo::EEncryptionMode>(IOutputStream& o, NKikimr::TBlobStorageGroupInfo::EEncryptionMode e) {
using E = NKikimr::TBlobStorageGroupInfo::EEncryptionMode;
switch (e) {
case E::EEM_NONE:
@@ -476,8 +476,8 @@ inline void Out<NKikimr::TBlobStorageGroupInfo::EEncryptionMode>(IOutputStream&
}
}
-template<>
-inline void Out<NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase>(IOutputStream& o, NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase e) {
+template<>
+inline void Out<NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase>(IOutputStream& o, NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase e) {
using E = NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase;
switch (e) {
case E::ELCP_INITIAL:
@@ -501,8 +501,8 @@ inline void Out<NKikimr::TBlobStorageGroupInfo::ELifeCyclePhase>(IOutputStream&
case E::ELCP_KEY_ID_ERROR:
o << "KEY_ID_ERROR";
break;
- case E::ELCP_KEY_NOT_LOADED:
- o << "KEY_NOT_LOADED";
- break;
+ case E::ELCP_KEY_NOT_LOADED:
+ o << "KEY_NOT_LOADED";
+ break;
}
}
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.cpp
index 572c36fbaba..e3db808a2d4 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.cpp
@@ -1,28 +1,28 @@
-#include "blobstorage_groupinfo_blobmap.h"
-#include <util/random/fast.h>
-
-namespace NKikimr {
- namespace NBlobMapper {
-
- class TBasicMapper : public IBlobToDiskMapper {
+#include "blobstorage_groupinfo_blobmap.h"
+#include <util/random/fast.h>
+
+namespace NKikimr {
+ namespace NBlobMapper {
+
+ class TBasicMapper : public IBlobToDiskMapper {
const TBlobStorageGroupInfo::TTopology *Topology;
- const ui8 BlobSubgroupSize;
-
- private:
+ const ui8 BlobSubgroupSize;
+
+ private:
ui32 GetIdxInSubgroupImpl(const TVDiskIdShort& vdisk, ui32 hash) {
const ui32 failDomainOrderNumber = Topology->GetFailDomainOrderNumber(vdisk);
const ui32 numFailDomains = Topology->GetTotalFailDomainsNum();
- ui32 domainIdx = hash % numFailDomains;
-
- // get shift of this disk inside ring
+ ui32 domainIdx = hash % numFailDomains;
+
+ // get shift of this disk inside ring
ui32 shift = failDomainOrderNumber + numFailDomains - domainIdx;
if (shift >= numFailDomains) {
shift -= numFailDomains;
}
- if (shift >= BlobSubgroupSize) {
- return BlobSubgroupSize;
- }
-
+ if (shift >= BlobSubgroupSize) {
+ return BlobSubgroupSize;
+ }
+
const TBlobStorageGroupInfo::TFailDomain& domain = Topology->GetFailDomain(vdisk);
if (domain.VDisks.size() == 1) {
return shift;
@@ -33,21 +33,21 @@ namespace NKikimr {
}
return vdisk.VDisk == rng() % domain.VDisks.size() ? shift : BlobSubgroupSize;
- }
- }
-
- public:
+ }
+ }
+
+ public:
TBasicMapper(const TBlobStorageGroupInfo::TTopology *topology)
: Topology(topology)
, BlobSubgroupSize(Topology->GType.BlobSubgroupSize())
- {}
-
+ {}
+
void PickSubgroup(ui32 hash, TBlobStorageGroupInfo::TOrderNums &orderNums) override final {
Y_VERIFY(orderNums.empty());
-
+
const ui32 numFailDomains = Topology->GetTotalFailDomainsNum();
- ui32 domainIdx = hash % numFailDomains;
-
+ ui32 domainIdx = hash % numFailDomains;
+
if (Topology->GetNumVDisksPerFailDomain() == 1) {
for (ui32 i = 0; i < BlobSubgroupSize; ++i) {
const TBlobStorageGroupInfo::TFailDomain& domain = Topology->GetFailDomain(domainIdx);
@@ -57,7 +57,7 @@ namespace NKikimr {
Y_VERIFY_DEBUG(domain.VDisks.size() == 1);
const TBlobStorageGroupInfo::TVDiskInfo& vdisk = domain.VDisks[0];
orderNums.push_back(vdisk.OrderNumber);
- }
+ }
} else {
TReallyFastRng32 rng(hash);
@@ -70,22 +70,22 @@ namespace NKikimr {
const TBlobStorageGroupInfo::TVDiskInfo& vdisk = domain.VDisks[vdiskIdx];
orderNums.push_back(vdisk.OrderNumber);
}
- }
- }
-
+ }
+ }
+
bool BelongsToSubgroup(const TVDiskIdShort& vdisk, ui32 hash) override final {
- return GetIdxInSubgroupImpl(vdisk, hash) < BlobSubgroupSize;
- }
-
+ return GetIdxInSubgroupImpl(vdisk, hash) < BlobSubgroupSize;
+ }
+
ui32 GetIdxInSubgroup(const TVDiskIdShort& vdisk, ui32 hash) override final {
- return GetIdxInSubgroupImpl(vdisk, hash);
- }
-
+ return GetIdxInSubgroupImpl(vdisk, hash);
+ }
+
TVDiskIdShort GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) override final {
const ui32 numFailDomains = Topology->GetTotalFailDomainsNum();
ui32 domainIdx = (static_cast<ui64>(hash) + idxInSubgroup) % numFailDomains;
const TBlobStorageGroupInfo::TFailDomain& domain = Topology->GetFailDomain(domainIdx);
-
+
if (domain.VDisks.size() == 1) {
return domain.VDisks[0].VDiskIdShort;
} else {
@@ -96,131 +96,131 @@ namespace NKikimr {
const ui32 vdiskIdx = rng() % domain.VDisks.size();
return domain.VDisks[vdiskIdx].VDiskIdShort;
- }
- }
- };
-
- class TMirror3dcMapper : public IBlobToDiskMapper {
+ }
+ }
+ };
+
+ class TMirror3dcMapper : public IBlobToDiskMapper {
const TBlobStorageGroupInfo::TTopology *Topology;
- const ui32 NumFailRealms;
- const ui32 NumFailDomainsPerFailRealm;
- const ui32 NumVDisksPerFailDomain;
-
- // In mirror-3-dc blob mapper uses 9 disks to put blob on -- first three of them are main replicas and
- // other six are handoff replicas. Their positions in subgroup are as follows:
- //
- // <-DC->
- // 0 1 2 ^
- // 3 4 5 fail domain
- // 6 7 8 V
-
- const ui32 NumFailRealmsInSubgroup = 3;
- const ui32 NumFailDomainsPerFailRealmInSubgroup = 3;
- const ui32 BlobSubgroupSize = NumFailRealmsInSubgroup * NumFailDomainsPerFailRealmInSubgroup;
-
- private:
- void GetBaseCoordinates(ui32 hash, ui32 *baseRealm, ui32 *baseDomain, ui32 *baseVDisk) const {
- *baseRealm = hash % NumFailRealms;
- hash /= NumFailRealms;
- *baseDomain = hash % NumFailDomainsPerFailRealm;
- hash /= NumFailDomainsPerFailRealm;
- *baseVDisk = hash % NumVDisksPerFailDomain;
- }
-
- const TBlobStorageGroupInfo::TVDiskInfo& GetVDiskInfo(ui32 baseRealm, ui32 baseDomain, ui32 baseVDisk,
- ui32 row, ui32 col) const {
- const ui32 realm = (baseRealm + col) % NumFailRealms;
- const ui32 domain = (baseDomain + row) % NumFailDomainsPerFailRealm;
- const ui32 vdisk = baseVDisk;
+ const ui32 NumFailRealms;
+ const ui32 NumFailDomainsPerFailRealm;
+ const ui32 NumVDisksPerFailDomain;
+
+ // In mirror-3-dc blob mapper uses 9 disks to put blob on -- first three of them are main replicas and
+ // other six are handoff replicas. Their positions in subgroup are as follows:
+ //
+ // <-DC->
+ // 0 1 2 ^
+ // 3 4 5 fail domain
+ // 6 7 8 V
+
+ const ui32 NumFailRealmsInSubgroup = 3;
+ const ui32 NumFailDomainsPerFailRealmInSubgroup = 3;
+ const ui32 BlobSubgroupSize = NumFailRealmsInSubgroup * NumFailDomainsPerFailRealmInSubgroup;
+
+ private:
+ void GetBaseCoordinates(ui32 hash, ui32 *baseRealm, ui32 *baseDomain, ui32 *baseVDisk) const {
+ *baseRealm = hash % NumFailRealms;
+ hash /= NumFailRealms;
+ *baseDomain = hash % NumFailDomainsPerFailRealm;
+ hash /= NumFailDomainsPerFailRealm;
+ *baseVDisk = hash % NumVDisksPerFailDomain;
+ }
+
+ const TBlobStorageGroupInfo::TVDiskInfo& GetVDiskInfo(ui32 baseRealm, ui32 baseDomain, ui32 baseVDisk,
+ ui32 row, ui32 col) const {
+ const ui32 realm = (baseRealm + col) % NumFailRealms;
+ const ui32 domain = (baseDomain + row) % NumFailDomainsPerFailRealm;
+ const ui32 vdisk = baseVDisk;
return Topology->FailRealms[realm].FailDomains[domain].VDisks[vdisk];
- }
-
- void DecomposeIndex(ui32 idxInSubgroup, ui32 *row, ui32 *col) const {
- *row = idxInSubgroup / NumFailRealmsInSubgroup;
- *col = idxInSubgroup % NumFailRealmsInSubgroup;
- }
-
- ui32 ComposeIndex(ui32 row, ui32 col) const {
- return row * NumFailRealmsInSubgroup + col;
- }
-
+ }
+
+ void DecomposeIndex(ui32 idxInSubgroup, ui32 *row, ui32 *col) const {
+ *row = idxInSubgroup / NumFailRealmsInSubgroup;
+ *col = idxInSubgroup % NumFailRealmsInSubgroup;
+ }
+
+ ui32 ComposeIndex(ui32 row, ui32 col) const {
+ return row * NumFailRealmsInSubgroup + col;
+ }
+
ui32 GetIdxInSubgroupImpl(const TVDiskIdShort& vdisk, ui32 hash) const {
- ui32 baseRealm;
- ui32 baseDomain;
- ui32 baseVDisk;
- GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
-
- ui32 offsRealm = (vdisk.FailRealm + NumFailRealms - baseRealm) % NumFailRealms;
- ui32 offsDomain = (vdisk.FailDomain + NumFailDomainsPerFailRealm - baseDomain) % NumFailDomainsPerFailRealm;
- ui32 offsVDisk = (vdisk.VDisk + NumVDisksPerFailDomain - baseVDisk) % NumVDisksPerFailDomain;
-
- if (offsRealm >= NumFailRealmsInSubgroup || offsDomain >= NumFailDomainsPerFailRealmInSubgroup || offsVDisk) {
- return BlobSubgroupSize;
- }
-
- return ComposeIndex(offsDomain, offsRealm);
- }
-
- public:
+ ui32 baseRealm;
+ ui32 baseDomain;
+ ui32 baseVDisk;
+ GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
+
+ ui32 offsRealm = (vdisk.FailRealm + NumFailRealms - baseRealm) % NumFailRealms;
+ ui32 offsDomain = (vdisk.FailDomain + NumFailDomainsPerFailRealm - baseDomain) % NumFailDomainsPerFailRealm;
+ ui32 offsVDisk = (vdisk.VDisk + NumVDisksPerFailDomain - baseVDisk) % NumVDisksPerFailDomain;
+
+ if (offsRealm >= NumFailRealmsInSubgroup || offsDomain >= NumFailDomainsPerFailRealmInSubgroup || offsVDisk) {
+ return BlobSubgroupSize;
+ }
+
+ return ComposeIndex(offsDomain, offsRealm);
+ }
+
+ public:
TMirror3dcMapper(const TBlobStorageGroupInfo::TTopology *topology)
: Topology(topology)
, NumFailRealms(Topology->FailRealms.size())
, NumFailDomainsPerFailRealm(Topology->FailRealms[0].FailDomains.size())
, NumVDisksPerFailDomain(Topology->FailRealms[0].FailDomains[0].VDisks.size())
- {
- Y_VERIFY(NumFailRealms >= NumFailRealmsInSubgroup &&
- NumFailDomainsPerFailRealm >= NumFailDomainsPerFailRealmInSubgroup,
+ {
+ Y_VERIFY(NumFailRealms >= NumFailRealmsInSubgroup &&
+ NumFailDomainsPerFailRealm >= NumFailDomainsPerFailRealmInSubgroup,
"mirror-3-dc group tolopogy is invalid: %s", topology->ToString().data());
- }
-
+ }
+
void PickSubgroup(ui32 hash, TBlobStorageGroupInfo::TOrderNums &orderNums) override final {
Y_VERIFY(orderNums.empty());
-
- ui32 baseRealm;
- ui32 baseDomain;
- ui32 baseVDisk;
- GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
-
- // make output matrix; process in order of increasing index
- for (ui32 row = 0; row < NumFailDomainsPerFailRealmInSubgroup; ++row) {
- for (ui32 col = 0; col < NumFailRealmsInSubgroup; ++col) {
- const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo = GetVDiskInfo(baseRealm, baseDomain,
- baseVDisk, row, col);
+
+ ui32 baseRealm;
+ ui32 baseDomain;
+ ui32 baseVDisk;
+ GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
+
+ // make output matrix; process in order of increasing index
+ for (ui32 row = 0; row < NumFailDomainsPerFailRealmInSubgroup; ++row) {
+ for (ui32 col = 0; col < NumFailRealmsInSubgroup; ++col) {
+ const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo = GetVDiskInfo(baseRealm, baseDomain,
+ baseVDisk, row, col);
orderNums.push_back(vdiskInfo.OrderNumber);
- }
- }
- }
-
+ }
+ }
+ }
+
bool BelongsToSubgroup(const TVDiskIdShort& vdisk, ui32 hash) override final {
- return GetIdxInSubgroupImpl(vdisk, hash) < BlobSubgroupSize;
- }
-
+ return GetIdxInSubgroupImpl(vdisk, hash) < BlobSubgroupSize;
+ }
+
ui32 GetIdxInSubgroup(const TVDiskIdShort& vdisk, ui32 hash) override final {
- return GetIdxInSubgroupImpl(vdisk, hash);
- }
-
+ return GetIdxInSubgroupImpl(vdisk, hash);
+ }
+
TVDiskIdShort GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) override final {
- ui32 baseRealm;
- ui32 baseDomain;
- ui32 baseVDisk;
- GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
- ui32 row;
- ui32 col;
- DecomposeIndex(idxInSubgroup, &row, &col);
- const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo = GetVDiskInfo(baseRealm, baseDomain, baseVDisk,
- row, col);
+ ui32 baseRealm;
+ ui32 baseDomain;
+ ui32 baseVDisk;
+ GetBaseCoordinates(hash, &baseRealm, &baseDomain, &baseVDisk);
+ ui32 row;
+ ui32 col;
+ DecomposeIndex(idxInSubgroup, &row, &col);
+ const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo = GetVDiskInfo(baseRealm, baseDomain, baseVDisk,
+ row, col);
return vdiskInfo.VDiskIdShort;
- }
- };
-
- } // NBlobMapper
-
+ }
+ };
+
+ } // NBlobMapper
+
IBlobToDiskMapper *IBlobToDiskMapper::CreateBasicMapper(const TBlobStorageGroupInfo::TTopology *topology) {
return new NBlobMapper::TBasicMapper(topology);
- }
-
+ }
+
IBlobToDiskMapper *IBlobToDiskMapper::CreateMirror3dcMapper(const TBlobStorageGroupInfo::TTopology *topology) {
return new NBlobMapper::TMirror3dcMapper(topology);
- }
-
-} // NKikimr
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.h
index b7ff40aef55..448eba65d0b 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.h
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap.h
@@ -1,37 +1,37 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_groupinfo.h"
-
-namespace NKikimr {
-
- // disk to blob mapper -- a special class that controls distribution of blobs over VDisks in their group
- struct IBlobToDiskMapper {
- virtual ~IBlobToDiskMapper() = default;
-
- // function selects where to put disk blob; hash = TLogoBlobID::Hash() for a specific blob, fromRing is a ring
- // number of entity calling this function; vdisks and services array are filled (if not nullptr) with VDisk
- // identifier and service actor ids; output arrays must be empty on entry and they are filled with BlobSubgroupSize
- // items on exit
+#include "blobstorage_groupinfo.h"
+
+namespace NKikimr {
+
+ // disk to blob mapper -- a special class that controls distribution of blobs over VDisks in their group
+ struct IBlobToDiskMapper {
+ virtual ~IBlobToDiskMapper() = default;
+
+ // function selects where to put disk blob; hash = TLogoBlobID::Hash() for a specific blob, fromRing is a ring
+ // number of entity calling this function; vdisks and services array are filled (if not nullptr) with VDisk
+ // identifier and service actor ids; output arrays must be empty on entry and they are filled with BlobSubgroupSize
+ // items on exit
virtual void PickSubgroup(ui32 hash, TBlobStorageGroupInfo::TOrderNums &orderNums) = 0;
-
- // function checks if a blob with provided hash is a replica for specific vdisk
+
+ // function checks if a blob with provided hash is a replica for specific vdisk
virtual bool BelongsToSubgroup(const TVDiskIdShort& vdisk, ui32 hash) = 0;
-
- // function returns "vdisk" index into "vdisks" array of select replicas, i.e. it is equivalent to
- //
- // TVDiskIds ids;
- // PickSubgroup(hash, vdisk.Ring, &vdisks, nullptr);
- // return std::find(ids.begin(), ids.end(), vdisk) - ids.begin();
- //
- // It returns BlobSubgroupSize if this vdisk is not designated for provided blob
+
+ // function returns "vdisk" index into "vdisks" array of select replicas, i.e. it is equivalent to
+ //
+ // TVDiskIds ids;
+ // PickSubgroup(hash, vdisk.Ring, &vdisks, nullptr);
+ // return std::find(ids.begin(), ids.end(), vdisk) - ids.begin();
+ //
+ // It returns BlobSubgroupSize if this vdisk is not designated for provided blob
virtual ui32 GetIdxInSubgroup(const TVDiskIdShort& vdisk, ui32 hash) = 0;
-
- // function returns idxInSubgroup-th element of vdisks array from PickSubgroup
+
+ // function returns idxInSubgroup-th element of vdisks array from PickSubgroup
virtual TVDiskIdShort GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) = 0;
-
+
static IBlobToDiskMapper *CreateBasicMapper(const TBlobStorageGroupInfo::TTopology *topology);
static IBlobToDiskMapper *CreateMirror3dcMapper(const TBlobStorageGroupInfo::TTopology *topology);
- };
-
-} // NKikimr
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap_ut.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap_ut.cpp
index 9147c6a8715..dba97e47ed4 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap_ut.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_blobmap_ut.cpp
@@ -1,152 +1,152 @@
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/fast.h>
-#include "blobstorage_groupinfo_blobmap.h"
-#include "blobstorage_groupinfo_iter.h"
-
-using namespace NKikimr;
-
-namespace {
-
- struct TOriginalBlobStorageGroupInfo {
- ui32 BlobSubgroupSize;
+#include <util/random/fast.h>
+#include "blobstorage_groupinfo_blobmap.h"
+#include "blobstorage_groupinfo_iter.h"
+
+using namespace NKikimr;
+
+namespace {
+
+ struct TOriginalBlobStorageGroupInfo {
+ ui32 BlobSubgroupSize;
TVector<TBlobStorageGroupInfo::TFailRealm> Realms;
- const ui32 GroupID;
- const ui32 GroupGeneration;
+ const ui32 GroupID;
+ const ui32 GroupGeneration;
TBlobStorageGroupInfo::TDynamicInfo DynamicInfo;
-
- TOriginalBlobStorageGroupInfo(ui32 blobSubgroupSize, const TBlobStorageGroupInfo& groupInfo)
- : BlobSubgroupSize(blobSubgroupSize)
- , GroupID(groupInfo.GroupID)
- , GroupGeneration(groupInfo.GroupGeneration)
+
+ TOriginalBlobStorageGroupInfo(ui32 blobSubgroupSize, const TBlobStorageGroupInfo& groupInfo)
+ : BlobSubgroupSize(blobSubgroupSize)
+ , GroupID(groupInfo.GroupID)
+ , GroupGeneration(groupInfo.GroupGeneration)
, DynamicInfo(groupInfo.GetDynamicInfo())
- {
- for (auto it = groupInfo.FailRealmsBegin(); it != groupInfo.FailRealmsEnd(); ++it) {
- Realms.push_back(*it);
- }
- }
-
+ {
+ for (auto it = groupInfo.FailRealmsBegin(); it != groupInfo.FailRealmsEnd(); ++it) {
+ Realms.push_back(*it);
+ }
+ }
+
bool PickSubgroup(ui32 hash, ui32 vdiskSz, TVDiskID *outVDisk, TActorId *outServiceIds) const {
- const ui32 subgroupSz = BlobSubgroupSize;
- Y_VERIFY(vdiskSz == subgroupSz);
-
- const TBlobStorageGroupInfo::TFailRealm& realm = Realms[0];
- Y_VERIFY_DEBUG(realm.FailDomains.size() >= subgroupSz);
-
- ui32 domainIdx = hash % realm.FailDomains.size();
- TReallyFastRng32 rng(hash);
-
- for (ui32 i = 0; i < subgroupSz; ++i) {
- const ui32 dx = domainIdx % realm.FailDomains.size();
- const TBlobStorageGroupInfo::TFailDomain &domain = realm.FailDomains[dx];
- const ui32 vx = rng() % domain.VDisks.size();
-
- outVDisk[i] = TVDiskID(GroupID, GroupGeneration, 0, dx, vx);
+ const ui32 subgroupSz = BlobSubgroupSize;
+ Y_VERIFY(vdiskSz == subgroupSz);
+
+ const TBlobStorageGroupInfo::TFailRealm& realm = Realms[0];
+ Y_VERIFY_DEBUG(realm.FailDomains.size() >= subgroupSz);
+
+ ui32 domainIdx = hash % realm.FailDomains.size();
+ TReallyFastRng32 rng(hash);
+
+ for (ui32 i = 0; i < subgroupSz; ++i) {
+ const ui32 dx = domainIdx % realm.FailDomains.size();
+ const TBlobStorageGroupInfo::TFailDomain &domain = realm.FailDomains[dx];
+ const ui32 vx = rng() % domain.VDisks.size();
+
+ outVDisk[i] = TVDiskID(GroupID, GroupGeneration, 0, dx, vx);
auto orderNum = domain.VDisks[vx].OrderNumber;
outServiceIds[i] = DynamicInfo.ServiceIdForOrderNumber[orderNum];
-
- ++domainIdx;
- }
-
- return true;
- }
-
- bool BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const {
- bool isReplica = GetIdxInSubgroup(vdisk, hash) < BlobSubgroupSize;
- return isReplica;
- }
-
- // Returns either vdisk idx in the blob subgroup, or BlobSubgroupSize if the vdisk is not in the blob subgroup
- ui32 GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const {
- Y_VERIFY(vdisk.GroupID == GroupID && vdisk.GroupGeneration == GroupGeneration);
- Y_VERIFY(vdisk.FailRealm < Realms.size());
-
- const TBlobStorageGroupInfo::TFailRealm &realm = Realms[vdisk.FailRealm];
- ui32 idx = (vdisk.FailDomain + realm.FailDomains.size() - hash % realm.FailDomains.size()) % realm.FailDomains.size();
-
- if (idx < BlobSubgroupSize) {
- ui32 vdiskIdx;
- TReallyFastRng32 rng(hash);
- for (ui32 i = 0; i < idx; ++i)
- rng();
- vdiskIdx = rng() % realm.FailDomains[vdisk.FailDomain].VDisks.size();
- if (vdiskIdx == vdisk.VDisk) {
- return idx;
- }
- }
- return BlobSubgroupSize;
- }
-
- TVDiskID GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const {
- Y_VERIFY(idxInSubgroup < BlobSubgroupSize);
-
- const TBlobStorageGroupInfo::TFailRealm &xrealm = Realms[0];
- ui32 domainIdx = hash % xrealm.FailDomains.size() + idxInSubgroup;
- const ui32 dx = domainIdx % xrealm.FailDomains.size();
- const TBlobStorageGroupInfo::TFailDomain &domain = xrealm.FailDomains[dx];
- TReallyFastRng32 rng(hash);
- for (ui32 i = 0; i < idxInSubgroup; ++i) {
- rng();
- }
- const ui32 vx = rng() % domain.VDisks.size();
-
- return TVDiskID(GroupID, GroupGeneration, 0, dx, vx);
- }
- };
-
-} // anon
-
+
+ ++domainIdx;
+ }
+
+ return true;
+ }
+
+ bool BelongsToSubgroup(const TVDiskID &vdisk, ui32 hash) const {
+ bool isReplica = GetIdxInSubgroup(vdisk, hash) < BlobSubgroupSize;
+ return isReplica;
+ }
+
+ // Returns either vdisk idx in the blob subgroup, or BlobSubgroupSize if the vdisk is not in the blob subgroup
+ ui32 GetIdxInSubgroup(const TVDiskID &vdisk, ui32 hash) const {
+ Y_VERIFY(vdisk.GroupID == GroupID && vdisk.GroupGeneration == GroupGeneration);
+ Y_VERIFY(vdisk.FailRealm < Realms.size());
+
+ const TBlobStorageGroupInfo::TFailRealm &realm = Realms[vdisk.FailRealm];
+ ui32 idx = (vdisk.FailDomain + realm.FailDomains.size() - hash % realm.FailDomains.size()) % realm.FailDomains.size();
+
+ if (idx < BlobSubgroupSize) {
+ ui32 vdiskIdx;
+ TReallyFastRng32 rng(hash);
+ for (ui32 i = 0; i < idx; ++i)
+ rng();
+ vdiskIdx = rng() % realm.FailDomains[vdisk.FailDomain].VDisks.size();
+ if (vdiskIdx == vdisk.VDisk) {
+ return idx;
+ }
+ }
+ return BlobSubgroupSize;
+ }
+
+ TVDiskID GetVDiskInSubgroup(ui32 idxInSubgroup, ui32 hash) const {
+ Y_VERIFY(idxInSubgroup < BlobSubgroupSize);
+
+ const TBlobStorageGroupInfo::TFailRealm &xrealm = Realms[0];
+ ui32 domainIdx = hash % xrealm.FailDomains.size() + idxInSubgroup;
+ const ui32 dx = domainIdx % xrealm.FailDomains.size();
+ const TBlobStorageGroupInfo::TFailDomain &domain = xrealm.FailDomains[dx];
+ TReallyFastRng32 rng(hash);
+ for (ui32 i = 0; i < idxInSubgroup; ++i) {
+ rng();
+ }
+ const ui32 vx = rng() % domain.VDisks.size();
+
+ return TVDiskID(GroupID, GroupGeneration, 0, dx, vx);
+ }
+ };
+
+} // anon
+
Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoBlobMapTest) {
-
+
void MakeBelongsToSubgroupBenchmark(TBlobStorageGroupType::EErasureSpecies erasure, ui32 numFailDomains,
NUnitTest::TTestContext& ut_context) {
- auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(erasure, 1, numFailDomains, 1);
- const ui32 blobSubgroupSize = groupInfo->Type.BlobSubgroupSize();
- TOriginalBlobStorageGroupInfo orig(blobSubgroupSize, *groupInfo);
-
+ auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(erasure, 1, numFailDomains, 1);
+ const ui32 blobSubgroupSize = groupInfo->Type.BlobSubgroupSize();
+ TOriginalBlobStorageGroupInfo orig(blobSubgroupSize, *groupInfo);
+
TVector<TLogoBlobID> ids;
- for (ui32 i = 0; i < 10000; ++i) {
- for (ui32 j = 0; j < 1000; ++j) {
- ids.emplace_back(i, 1, j, 1, 1000, 1);
- }
- }
-
+ for (ui32 i = 0; i < 10000; ++i) {
+ for (ui32 j = 0; j < 1000; ++j) {
+ ids.emplace_back(i, 1, j, 1, 1000, 1);
+ }
+ }
+
constexpr ui64 blobCount = 10'000'000;
UNIT_ASSERT(blobCount == ids.size());
ui64 iterationCount = numFailDomains * blobCount;
- THPTimer timer;
- ui32 num = 0;
- for (const auto& vdisk : groupInfo->GetVDisks()) {
- for (const TLogoBlobID& id : ids) {
+ THPTimer timer;
+ ui32 num = 0;
+ for (const auto& vdisk : groupInfo->GetVDisks()) {
+ for (const TLogoBlobID& id : ids) {
auto vd = groupInfo->GetVDiskId(vdisk.OrderNumber);
num += groupInfo->BelongsToSubgroup(vd, id.Hash()) ? 1 : 0;
- }
- }
+ }
+ }
double newMetric = 1'000'000'000 * timer.PassedReset() / iterationCount;
TString newMetricsName = TStringBuilder() << TErasureType::ErasureSpeciesToStr(erasure)
<< " domains " << numFailDomains
<< " new (ns)";
ut_context.Metrics[newMetricsName] = newMetric;
Cerr << newMetricsName << ": " << newMetric<< Endl;
-
+
timer.Reset();
- ui32 num2 = 0;
- for (const auto& vdisk : groupInfo->GetVDisks()) {
- for (const TLogoBlobID& id : ids) {
+ ui32 num2 = 0;
+ for (const auto& vdisk : groupInfo->GetVDisks()) {
+ for (const TLogoBlobID& id : ids) {
auto vd = groupInfo->GetVDiskId(vdisk.OrderNumber);
num2 += orig.BelongsToSubgroup(vd, id.Hash()) ? 1 : 0;
- }
- }
+ }
+ }
double oldMetric = 1'000'000'000 * timer.PassedReset() / iterationCount;
TString oldMetricsName = TStringBuilder() << TErasureType::ErasureSpeciesToStr(erasure)
<< " domains " << numFailDomains
<< " old (ns)";
ut_context.Metrics[oldMetricsName] = oldMetric;
Cerr << oldMetricsName << ": " << oldMetric << Endl;
-
- UNIT_ASSERT_VALUES_EQUAL(num, num2);
- }
-
+
+ UNIT_ASSERT_VALUES_EQUAL(num, num2);
+ }
+
Y_UNIT_TEST(BelongsToSubgroupBenchmark) {
auto erasures = {TBlobStorageGroupType::ErasureNone,
TBlobStorageGroupType::ErasureMirror3,
@@ -160,7 +160,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoBlobMapTest) {
}
}
- void BasicCheck(const std::unique_ptr<TBlobStorageGroupInfo> &groupInfo, TOriginalBlobStorageGroupInfo &orig,
+ void BasicCheck(const std::unique_ptr<TBlobStorageGroupInfo> &groupInfo, TOriginalBlobStorageGroupInfo &orig,
TLogoBlobID id, ui32 blobSubgroupSize) {
std::array<TVDiskID, 8> vdisks;
std::array<TActorId, 8> services;
@@ -207,26 +207,26 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoBlobMapTest) {
}
Y_UNIT_TEST(BasicChecks) {
- for (auto erasure : {TBlobStorageGroupType::ErasureNone, TBlobStorageGroupType::ErasureMirror3,
- TBlobStorageGroupType::Erasure3Plus1Block, TBlobStorageGroupType::Erasure3Plus1Stripe,
- TBlobStorageGroupType::Erasure4Plus2Block, TBlobStorageGroupType::Erasure3Plus2Block,
- TBlobStorageGroupType::Erasure4Plus2Stripe, TBlobStorageGroupType::Erasure3Plus2Stripe,
- TBlobStorageGroupType::ErasureMirror3Plus2}) {
- auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(erasure, 3U, 8U, 1U);
- const ui32 blobSubgroupSize = groupInfo->Type.BlobSubgroupSize();
- TOriginalBlobStorageGroupInfo orig(blobSubgroupSize, *groupInfo);
-
- for (ui32 i = 0; i < 100; ++i) {
- for (ui32 j = 0; j < 10; ++j) {
- TLogoBlobID id(i, 1, j, 1, 1000, 1);
+ for (auto erasure : {TBlobStorageGroupType::ErasureNone, TBlobStorageGroupType::ErasureMirror3,
+ TBlobStorageGroupType::Erasure3Plus1Block, TBlobStorageGroupType::Erasure3Plus1Stripe,
+ TBlobStorageGroupType::Erasure4Plus2Block, TBlobStorageGroupType::Erasure3Plus2Block,
+ TBlobStorageGroupType::Erasure4Plus2Stripe, TBlobStorageGroupType::Erasure3Plus2Stripe,
+ TBlobStorageGroupType::ErasureMirror3Plus2}) {
+ auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(erasure, 3U, 8U, 1U);
+ const ui32 blobSubgroupSize = groupInfo->Type.BlobSubgroupSize();
+ TOriginalBlobStorageGroupInfo orig(blobSubgroupSize, *groupInfo);
+
+ for (ui32 i = 0; i < 100; ++i) {
+ for (ui32 j = 0; j < 10; ++j) {
+ TLogoBlobID id(i, 1, j, 1, 1000, 1);
BasicCheck(groupInfo, orig, id, blobSubgroupSize);
- }
- }
- }
- }
-
+ }
+ }
+ }
+ }
+
Y_UNIT_TEST(CheckCorrectBehaviourWithHashOverlow) {
- auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(TErasureType::ErasureMirror3, 1U, 5U, 1U);
+ auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(TErasureType::ErasureMirror3, 1U, 5U, 1U);
const ui32 blobSubgroupSize = groupInfo->Type.BlobSubgroupSize();
TOriginalBlobStorageGroupInfo orig(blobSubgroupSize, *groupInfo);
TLogoBlobID id(4550843067551373890, 2564314201, 2840555155, 59, 0, 2230444);
@@ -234,86 +234,86 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoBlobMapTest) {
}
Y_UNIT_TEST(Mirror3dcMapper) {
- auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(TBlobStorageGroupType::ErasureMirror3, 3U, 5U, 4U);
-
- std::unique_ptr<IBlobToDiskMapper> mapper{IBlobToDiskMapper::CreateMirror3dcMapper(&groupInfo->GetTopology())};
-
+ auto groupInfo = std::make_unique<TBlobStorageGroupInfo>(TBlobStorageGroupType::ErasureMirror3, 3U, 5U, 4U);
+
+ std::unique_ptr<IBlobToDiskMapper> mapper{IBlobToDiskMapper::CreateMirror3dcMapper(&groupInfo->GetTopology())};
+
THashMap<TVDiskID, TVector<ui32>> usageMap;
- for (const auto& vdisk : groupInfo->GetVDisks()) {
+ for (const auto& vdisk : groupInfo->GetVDisks()) {
auto vd = groupInfo->GetVDiskId(vdisk.OrderNumber);
usageMap.emplace(vd, TVector<ui32>(9));
- }
-
- TReallyFastRng32 rng(1);
- for (ui32 i = 0; i < 10000; ++i) {
- const ui32 hash = rng();
-
+ }
+
+ TReallyFastRng32 rng(1);
+ for (ui32 i = 0; i < 10000; ++i) {
+ const ui32 hash = rng();
+
TBlobStorageGroupInfo::TOrderNums orderNums;
- TBlobStorageGroupInfo::TVDiskIds vdisks;
+ TBlobStorageGroupInfo::TVDiskIds vdisks;
mapper->PickSubgroup(hash, orderNums);
for (const auto &x : orderNums) {
vdisks.push_back(groupInfo->GetVDiskId(x));
}
-
- for (ui32 i = 0; i < vdisks.size(); ++i) {
- ++usageMap[vdisks[i]][i];
- }
-
- for (ui32 i = 0; i < 3; ++i) {
- // ensure that cells within a column are in the same ring
- UNIT_ASSERT_VALUES_EQUAL(vdisks[i].FailRealm, vdisks[i + 3].FailRealm);
- UNIT_ASSERT_VALUES_EQUAL(vdisks[i].FailRealm, vdisks[i + 6].FailRealm);
- // and from different fail domains
- UNIT_ASSERT(vdisks[i].FailDomain != vdisks[i + 3].FailDomain);
- UNIT_ASSERT(vdisks[i].FailDomain != vdisks[i + 6].FailDomain);
- UNIT_ASSERT(vdisks[i + 3].FailDomain != vdisks[i + 6].FailDomain);
- }
- UNIT_ASSERT(vdisks[0].FailRealm != vdisks[1].FailRealm);
- UNIT_ASSERT(vdisks[0].FailRealm != vdisks[2].FailRealm);
- UNIT_ASSERT(vdisks[1].FailRealm != vdisks[2].FailRealm);
-
+
+ for (ui32 i = 0; i < vdisks.size(); ++i) {
+ ++usageMap[vdisks[i]][i];
+ }
+
+ for (ui32 i = 0; i < 3; ++i) {
+ // ensure that cells within a column are in the same ring
+ UNIT_ASSERT_VALUES_EQUAL(vdisks[i].FailRealm, vdisks[i + 3].FailRealm);
+ UNIT_ASSERT_VALUES_EQUAL(vdisks[i].FailRealm, vdisks[i + 6].FailRealm);
+ // and from different fail domains
+ UNIT_ASSERT(vdisks[i].FailDomain != vdisks[i + 3].FailDomain);
+ UNIT_ASSERT(vdisks[i].FailDomain != vdisks[i + 6].FailDomain);
+ UNIT_ASSERT(vdisks[i + 3].FailDomain != vdisks[i + 6].FailDomain);
+ }
+ UNIT_ASSERT(vdisks[0].FailRealm != vdisks[1].FailRealm);
+ UNIT_ASSERT(vdisks[0].FailRealm != vdisks[2].FailRealm);
+ UNIT_ASSERT(vdisks[1].FailRealm != vdisks[2].FailRealm);
+
THashMap<TVDiskID, ui32> disk2index;
- for (ui32 i = 0; i < vdisks.size(); ++i) {
- disk2index[vdisks[i]] = i;
- }
-
- for (const auto& vdisk : groupInfo->GetVDisks()) {
+ for (ui32 i = 0; i < vdisks.size(); ++i) {
+ disk2index[vdisks[i]] = i;
+ }
+
+ for (const auto& vdisk : groupInfo->GetVDisks()) {
auto vd = groupInfo->GetVDiskId(vdisk.OrderNumber);
auto it = disk2index.find(vd);
- bool isReplicaFor = it != disk2index.end();
+ bool isReplicaFor = it != disk2index.end();
UNIT_ASSERT_VALUES_EQUAL(mapper->GetIdxInSubgroup(vd, hash), isReplicaFor ? it->second : 9);
UNIT_ASSERT_VALUES_EQUAL(mapper->BelongsToSubgroup(vd, hash), isReplicaFor);
- }
-
- for (ui32 i = 0; i < vdisks.size(); ++i) {
- UNIT_ASSERT_EQUAL(mapper->GetVDiskInSubgroup(i, hash), vdisks[i]);
- }
- }
-
+ }
+
+ for (ui32 i = 0; i < vdisks.size(); ++i) {
+ UNIT_ASSERT_EQUAL(mapper->GetVDiskInSubgroup(i, hash), vdisks[i]);
+ }
+ }
+
TVector<double> xv;
- for (const auto& kv : usageMap) {
- Cerr << kv.first.ToString() << "#";
- for (ui32 i : kv.second) {
- xv.push_back(i);
- Cerr << " " << i;
- }
- Cerr << Endl;
- }
-
- double mean = 0;
- for (double x : xv) {
- mean += x;
- }
- mean /= xv.size();
-
- double dev = 0;
- for (double x : xv) {
- double d = x - mean;
- dev += d * d;
- }
- dev = sqrt(dev / xv.size());
-
- Cerr << "mean# " << mean << " dev# " << dev << Endl;
- }
-
-}
+ for (const auto& kv : usageMap) {
+ Cerr << kv.first.ToString() << "#";
+ for (ui32 i : kv.second) {
+ xv.push_back(i);
+ Cerr << " " << i;
+ }
+ Cerr << Endl;
+ }
+
+ double mean = 0;
+ for (double x : xv) {
+ mean += x;
+ }
+ mean /= xv.size();
+
+ double dev = 0;
+ for (double x : xv) {
+ double d = x - mean;
+ dev += d * d;
+ }
+ dev = sqrt(dev / xv.size());
+
+ Cerr << "mean# " << mean << " dev# " << dev << Endl;
+ }
+
+}
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h
index ecfdadffebd..ee95fc9bb58 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h
@@ -1,348 +1,348 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_groupinfo.h"
-
-namespace NKikimr {
-
- template<typename TBaseIter, typename TParentIter, typename TDerived>
- class TBlobStorageGroupInfo::TIteratorBase
- : public TParentIter
- {
+#include "blobstorage_groupinfo.h"
+
+namespace NKikimr {
+
+ template<typename TBaseIter, typename TParentIter, typename TDerived>
+ class TBlobStorageGroupInfo::TIteratorBase
+ : public TParentIter
+ {
using TValue = std::remove_reference_t<decltype(*std::declval<TBaseIter>())>;
-
- TBaseIter It; // iterator to current element
-
- public:
- TIteratorBase()
- {}
-
- template<typename... TArgs>
- TIteratorBase(const TBaseIter& it, TArgs&&... args)
- : TParentIter(std::forward<TArgs>(args)...)
- , It(it)
- {}
-
- TIteratorBase(const TIteratorBase& it)
- : TParentIter(it.GetParentIter())
- , It(it.It)
- {}
-
- const TValue& operator *() const {
- return *It;
- }
-
- const TValue *operator ->() const {
- return &*It;
- }
-
- TDerived& operator ++() {
- // if we have reached end of our range, we have to advance parent iterator and set up new ranges unless
- // it have reached the end too
- if (++It == TParentIter::NestedEnd()) {
- TParentIter::operator ++();
- if (!TParentIter::IsAtEnd()) {
- It = TParentIter::NestedBegin();
- }
- }
-
- return static_cast<TDerived&>(*this);
- }
-
- TDerived& operator --() {
- // check if we are at end; if so, we have nothing to do but to move parent iterator one item back; otherwise
- // see if we are at begin and have to move parent iterator too
- if (IsAtEnd() || It == TParentIter::NestedBegin()) {
- TParentIter::operator --();
- It = TParentIter::NestedEnd();
- }
- --It;
- return static_cast<TDerived&>(*this);
- }
-
- TDerived operator ++(int) {
- TDerived current(static_cast<TDerived&>(*this));
- ++*this;
- return current;
- }
-
- TDerived operator --(int) {
- TDerived current(static_cast<TDerived&>(*this));
- --*this;
- return current;
- }
-
- friend bool operator ==(const TIteratorBase& x, const TIteratorBase& y) {
- return x.It == y.It && static_cast<const TParentIter&>(x) == static_cast<const TParentIter&>(y);
- }
-
- friend bool operator !=(const TIteratorBase& x, const TIteratorBase& y) {
- return x.It != y.It || static_cast<const TParentIter&>(x) != static_cast<const TParentIter&>(y);
- }
-
- protected:
- bool IsAtEnd() const {
- return TParentIter::IsAtEnd() || It == TParentIter::NestedEnd();
- }
-
- ui32 IndexInParent() const {
- return It - TParentIter::NestedBegin();
- }
-
- const TParentIter& GetParentIter() const {
- return *this;
- }
- };
-
- class TBlobStorageGroupInfo::TRootIteratorBase {
+
+ TBaseIter It; // iterator to current element
+
+ public:
+ TIteratorBase()
+ {}
+
+ template<typename... TArgs>
+ TIteratorBase(const TBaseIter& it, TArgs&&... args)
+ : TParentIter(std::forward<TArgs>(args)...)
+ , It(it)
+ {}
+
+ TIteratorBase(const TIteratorBase& it)
+ : TParentIter(it.GetParentIter())
+ , It(it.It)
+ {}
+
+ const TValue& operator *() const {
+ return *It;
+ }
+
+ const TValue *operator ->() const {
+ return &*It;
+ }
+
+ TDerived& operator ++() {
+ // if we have reached end of our range, we have to advance parent iterator and set up new ranges unless
+ // it have reached the end too
+ if (++It == TParentIter::NestedEnd()) {
+ TParentIter::operator ++();
+ if (!TParentIter::IsAtEnd()) {
+ It = TParentIter::NestedBegin();
+ }
+ }
+
+ return static_cast<TDerived&>(*this);
+ }
+
+ TDerived& operator --() {
+ // check if we are at end; if so, we have nothing to do but to move parent iterator one item back; otherwise
+ // see if we are at begin and have to move parent iterator too
+ if (IsAtEnd() || It == TParentIter::NestedBegin()) {
+ TParentIter::operator --();
+ It = TParentIter::NestedEnd();
+ }
+ --It;
+ return static_cast<TDerived&>(*this);
+ }
+
+ TDerived operator ++(int) {
+ TDerived current(static_cast<TDerived&>(*this));
+ ++*this;
+ return current;
+ }
+
+ TDerived operator --(int) {
+ TDerived current(static_cast<TDerived&>(*this));
+ --*this;
+ return current;
+ }
+
+ friend bool operator ==(const TIteratorBase& x, const TIteratorBase& y) {
+ return x.It == y.It && static_cast<const TParentIter&>(x) == static_cast<const TParentIter&>(y);
+ }
+
+ friend bool operator !=(const TIteratorBase& x, const TIteratorBase& y) {
+ return x.It != y.It || static_cast<const TParentIter&>(x) != static_cast<const TParentIter&>(y);
+ }
+
+ protected:
+ bool IsAtEnd() const {
+ return TParentIter::IsAtEnd() || It == TParentIter::NestedEnd();
+ }
+
+ ui32 IndexInParent() const {
+ return It - TParentIter::NestedBegin();
+ }
+
+ const TParentIter& GetParentIter() const {
+ return *this;
+ }
+ };
+
+ class TBlobStorageGroupInfo::TRootIteratorBase {
const TBlobStorageGroupInfo::TTopology *Topology = nullptr;
- bool AtEnd = false;
-
- public:
- TRootIteratorBase()
- {}
-
+ bool AtEnd = false;
+
+ public:
+ TRootIteratorBase()
+ {}
+
TRootIteratorBase(const TBlobStorageGroupInfo::TTopology *topology, bool atEnd)
: Topology(topology)
- , AtEnd(atEnd)
- {}
-
- TRootIteratorBase& operator ++() {
- Y_VERIFY(!AtEnd);
- AtEnd = true;
- return *this;
- }
-
- TRootIteratorBase& operator --() {
- Y_VERIFY(AtEnd);
- AtEnd = false;
- return *this;
- }
-
- auto NestedBegin() const {
+ , AtEnd(atEnd)
+ {}
+
+ TRootIteratorBase& operator ++() {
+ Y_VERIFY(!AtEnd);
+ AtEnd = true;
+ return *this;
+ }
+
+ TRootIteratorBase& operator --() {
+ Y_VERIFY(AtEnd);
+ AtEnd = false;
+ return *this;
+ }
+
+ auto NestedBegin() const {
Y_VERIFY(!AtEnd && Topology);
return Topology->FailRealms.begin();
- }
-
- auto NestedEnd() const {
+ }
+
+ auto NestedEnd() const {
Y_VERIFY(!AtEnd && Topology);
return Topology->FailRealms.end();
- }
-
- bool IsAtEnd() const {
- return AtEnd;
- }
-
- friend bool operator ==(const TRootIteratorBase& x, const TRootIteratorBase& y) {
+ }
+
+ bool IsAtEnd() const {
+ return AtEnd;
+ }
+
+ friend bool operator ==(const TRootIteratorBase& x, const TRootIteratorBase& y) {
Y_VERIFY_DEBUG(x.Topology == y.Topology);
- return x.AtEnd == y.AtEnd;
- }
-
- friend bool operator !=(const TRootIteratorBase& x, const TRootIteratorBase& y) {
+ return x.AtEnd == y.AtEnd;
+ }
+
+ friend bool operator !=(const TRootIteratorBase& x, const TRootIteratorBase& y) {
Y_VERIFY_DEBUG(x.Topology == y.Topology);
- return x.AtEnd != y.AtEnd;
- }
- };
-
- class TBlobStorageGroupInfo::TFailRealmIterator
+ return x.AtEnd != y.AtEnd;
+ }
+ };
+
+ class TBlobStorageGroupInfo::TFailRealmIterator
: public TBlobStorageGroupInfo::TIteratorBase<TVector<TFailRealm>::const_iterator, TRootIteratorBase, TFailRealmIterator>
- , public std::iterator<std::bidirectional_iterator_tag, TFailRealm>
- {
- public:
- using TIteratorBase::TIteratorBase;
-
- ui32 GetFailRealmIdx() const {
- return TIteratorBase::IndexInParent();
- }
-
- ui32 GetNumFailDomainsPerFailRealm() const {
- const auto& failRealm = **this;
- return failRealm.FailDomains.size();
- }
-
- TFailDomainIterator FailRealmFailDomainsBegin() const;
- TFailDomainIterator FailRealmFailDomainsEnd() const;
- TFailDomainRange GetFailRealmFailDomains() const;
-
- TVDiskIterator FailRealmVDisksBegin() const;
- TVDiskIterator FailRealmVDisksEnd() const;
- TVDiskRange GetFailRealmVDisks() const;
-
- protected:
- auto NestedBegin() const {
- const TFailRealm& failRealm = **this;
- return failRealm.FailDomains.begin();
- }
-
- auto NestedEnd() const {
- const TFailRealm& failRealm = **this;
- return failRealm.FailDomains.end();
- }
- };
-
- class TBlobStorageGroupInfo::TFailDomainIterator
+ , public std::iterator<std::bidirectional_iterator_tag, TFailRealm>
+ {
+ public:
+ using TIteratorBase::TIteratorBase;
+
+ ui32 GetFailRealmIdx() const {
+ return TIteratorBase::IndexInParent();
+ }
+
+ ui32 GetNumFailDomainsPerFailRealm() const {
+ const auto& failRealm = **this;
+ return failRealm.FailDomains.size();
+ }
+
+ TFailDomainIterator FailRealmFailDomainsBegin() const;
+ TFailDomainIterator FailRealmFailDomainsEnd() const;
+ TFailDomainRange GetFailRealmFailDomains() const;
+
+ TVDiskIterator FailRealmVDisksBegin() const;
+ TVDiskIterator FailRealmVDisksEnd() const;
+ TVDiskRange GetFailRealmVDisks() const;
+
+ protected:
+ auto NestedBegin() const {
+ const TFailRealm& failRealm = **this;
+ return failRealm.FailDomains.begin();
+ }
+
+ auto NestedEnd() const {
+ const TFailRealm& failRealm = **this;
+ return failRealm.FailDomains.end();
+ }
+ };
+
+ class TBlobStorageGroupInfo::TFailDomainIterator
: public TBlobStorageGroupInfo::TIteratorBase<TVector<TFailDomain>::const_iterator, TFailRealmIterator, TFailDomainIterator>
- , public std::iterator<std::bidirectional_iterator_tag, TFailDomain>
- {
- public:
- using TIteratorBase::TIteratorBase;
-
- ui32 GetFailDomainIdx() const {
- return TIteratorBase::IndexInParent();
- }
-
- ui32 GetNumVDisksPerFailDomain() const {
- const TFailDomain& domain = **this;
- return domain.VDisks.size();
- }
-
- const TBlobStorageGroupInfo::TFailRealmIterator& GetFailRealmIt() const {
- return TIteratorBase::GetParentIter();
- }
-
- TVDiskIterator FailDomainVDisksBegin() const;
- TVDiskIterator FailDomainVDisksEnd() const;
- TVDiskRange GetFailDomainVDisks() const;
-
- protected:
- auto NestedBegin() const {
- const TFailDomain& domain = **this;
- return domain.VDisks.begin();
- }
-
- auto NestedEnd() const {
- const TFailDomain& domain = **this;
- return domain.VDisks.end();
- }
- };
-
- class TBlobStorageGroupInfo::TVDiskIterator
+ , public std::iterator<std::bidirectional_iterator_tag, TFailDomain>
+ {
+ public:
+ using TIteratorBase::TIteratorBase;
+
+ ui32 GetFailDomainIdx() const {
+ return TIteratorBase::IndexInParent();
+ }
+
+ ui32 GetNumVDisksPerFailDomain() const {
+ const TFailDomain& domain = **this;
+ return domain.VDisks.size();
+ }
+
+ const TBlobStorageGroupInfo::TFailRealmIterator& GetFailRealmIt() const {
+ return TIteratorBase::GetParentIter();
+ }
+
+ TVDiskIterator FailDomainVDisksBegin() const;
+ TVDiskIterator FailDomainVDisksEnd() const;
+ TVDiskRange GetFailDomainVDisks() const;
+
+ protected:
+ auto NestedBegin() const {
+ const TFailDomain& domain = **this;
+ return domain.VDisks.begin();
+ }
+
+ auto NestedEnd() const {
+ const TFailDomain& domain = **this;
+ return domain.VDisks.end();
+ }
+ };
+
+ class TBlobStorageGroupInfo::TVDiskIterator
: public TBlobStorageGroupInfo::TIteratorBase<TVector<TVDiskInfo>::const_iterator, TFailDomainIterator, TVDiskIterator>
- , public std::iterator<std::bidirectional_iterator_tag, TVDiskInfo>
- {
- public:
- using TIteratorBase::TIteratorBase;
-
- ui32 GetVDiskIdx() const {
- return TIteratorBase::IndexInParent();
- }
-
- const TBlobStorageGroupInfo::TFailDomainIterator& GetFailDomainIt() const {
- return TIteratorBase::GetParentIter();
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TBlobStorageGroupInfo implementation
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::FindVDisk(const TVDiskID& vdisk) const {
- Y_VERIFY(vdisk.GroupID == GroupID && vdisk.GroupGeneration == GroupGeneration);
+ , public std::iterator<std::bidirectional_iterator_tag, TVDiskInfo>
+ {
+ public:
+ using TIteratorBase::TIteratorBase;
+
+ ui32 GetVDiskIdx() const {
+ return TIteratorBase::IndexInParent();
+ }
+
+ const TBlobStorageGroupInfo::TFailDomainIterator& GetFailDomainIt() const {
+ return TIteratorBase::GetParentIter();
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TBlobStorageGroupInfo implementation
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::FindVDisk(const TVDiskID& vdisk) const {
+ Y_VERIFY(vdisk.GroupID == GroupID && vdisk.GroupGeneration == GroupGeneration);
const auto realmIt = Topology->FailRealms.begin() + vdisk.FailRealm;
- const auto domainIt = realmIt->FailDomains.begin() + vdisk.FailDomain;
- const auto vdiskIt = domainIt->VDisks.begin() + vdisk.VDisk;
- return TVDiskIterator(vdiskIt, domainIt, realmIt, Topology.get(), false);
- }
-
- template<typename TBaseIter>
- class TBlobStorageGroupInfo::TRangeBase {
- const TBaseIter Begin;
- const TBaseIter End;
-
- public:
- TRangeBase(const TBaseIter& begin, const TBaseIter& end)
- : Begin(begin)
- , End(end)
- {}
-
- const TBaseIter& begin() const {
- return Begin;
- }
-
- const TBaseIter& end() const {
- return End;
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TFailRealmIterator implementation
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmFailDomainsBegin() const {
- return TFailDomainIterator((*this)->FailDomains.begin(), *this);
- }
-
- inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmFailDomainsEnd() const {
- return ++TFailDomainIterator(std::prev((*this)->FailDomains.end()), *this);
- }
-
- inline TBlobStorageGroupInfo::TFailDomainRange TBlobStorageGroupInfo::TFailRealmIterator::GetFailRealmFailDomains() const {
- return TFailDomainRange(FailRealmFailDomainsBegin(), FailRealmFailDomainsEnd());
- }
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmVDisksBegin() const {
- return FailRealmFailDomainsBegin().FailDomainVDisksBegin();
- }
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmVDisksEnd() const {
- return (--FailRealmFailDomainsEnd()).FailDomainVDisksEnd();
- }
-
- inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::TFailRealmIterator::GetFailRealmVDisks() const {
- return TVDiskRange(FailRealmVDisksBegin(), FailRealmVDisksEnd());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TFailDomainIterator implementation
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailDomainIterator::FailDomainVDisksBegin() const {
- return TVDiskIterator((*this)->VDisks.begin(), *this);
- }
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailDomainIterator::FailDomainVDisksEnd() const {
- return ++TVDiskIterator(std::prev((*this)->VDisks.end()), *this);
- }
-
- inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::TFailDomainIterator::GetFailDomainVDisks() const {
- return TVDiskRange(FailDomainVDisksBegin(), FailDomainVDisksEnd());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ const auto domainIt = realmIt->FailDomains.begin() + vdisk.FailDomain;
+ const auto vdiskIt = domainIt->VDisks.begin() + vdisk.VDisk;
+ return TVDiskIterator(vdiskIt, domainIt, realmIt, Topology.get(), false);
+ }
+
+ template<typename TBaseIter>
+ class TBlobStorageGroupInfo::TRangeBase {
+ const TBaseIter Begin;
+ const TBaseIter End;
+
+ public:
+ TRangeBase(const TBaseIter& begin, const TBaseIter& end)
+ : Begin(begin)
+ , End(end)
+ {}
+
+ const TBaseIter& begin() const {
+ return Begin;
+ }
+
+ const TBaseIter& end() const {
+ return End;
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TFailRealmIterator implementation
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmFailDomainsBegin() const {
+ return TFailDomainIterator((*this)->FailDomains.begin(), *this);
+ }
+
+ inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmFailDomainsEnd() const {
+ return ++TFailDomainIterator(std::prev((*this)->FailDomains.end()), *this);
+ }
+
+ inline TBlobStorageGroupInfo::TFailDomainRange TBlobStorageGroupInfo::TFailRealmIterator::GetFailRealmFailDomains() const {
+ return TFailDomainRange(FailRealmFailDomainsBegin(), FailRealmFailDomainsEnd());
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmVDisksBegin() const {
+ return FailRealmFailDomainsBegin().FailDomainVDisksBegin();
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailRealmIterator::FailRealmVDisksEnd() const {
+ return (--FailRealmFailDomainsEnd()).FailDomainVDisksEnd();
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::TFailRealmIterator::GetFailRealmVDisks() const {
+ return TVDiskRange(FailRealmVDisksBegin(), FailRealmVDisksEnd());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TFailDomainIterator implementation
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailDomainIterator::FailDomainVDisksBegin() const {
+ return TVDiskIterator((*this)->VDisks.begin(), *this);
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::TFailDomainIterator::FailDomainVDisksEnd() const {
+ return ++TVDiskIterator(std::prev((*this)->VDisks.end()), *this);
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::TFailDomainIterator::GetFailDomainVDisks() const {
+ return TVDiskRange(FailDomainVDisksBegin(), FailDomainVDisksEnd());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TBlobStorageGroupInfo iterator builders
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- inline TBlobStorageGroupInfo::TFailRealmIterator TBlobStorageGroupInfo::FailRealmsBegin() const {
- return TFailRealmIterator(Topology->FailRealms.begin(), TRootIteratorBase(Topology.get(), false));
- }
-
- inline TBlobStorageGroupInfo::TFailRealmIterator TBlobStorageGroupInfo::FailRealmsEnd() const {
- return ++TFailRealmIterator(std::prev(Topology->FailRealms.end()), TRootIteratorBase(Topology.get(), false));
- }
-
- inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::FailDomainsBegin() const {
- return FailRealmsBegin().FailRealmFailDomainsBegin();
- }
-
- inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::FailDomainsEnd() const {
- return (--FailRealmsEnd()).FailRealmFailDomainsEnd();
- }
-
- inline TBlobStorageGroupInfo::TFailDomainRange TBlobStorageGroupInfo::GetFailDomains() const {
- return TFailDomainRange(FailDomainsBegin(), FailDomainsEnd());
- }
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::VDisksBegin() const {
- return FailRealmsBegin().FailRealmVDisksBegin();
- }
-
- inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::VDisksEnd() const {
- return (--FailRealmsEnd()).FailRealmVDisksEnd();
- }
-
- inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::GetVDisks() const {
- return TVDiskRange(VDisksBegin(), VDisksEnd());
- }
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ inline TBlobStorageGroupInfo::TFailRealmIterator TBlobStorageGroupInfo::FailRealmsBegin() const {
+ return TFailRealmIterator(Topology->FailRealms.begin(), TRootIteratorBase(Topology.get(), false));
+ }
+
+ inline TBlobStorageGroupInfo::TFailRealmIterator TBlobStorageGroupInfo::FailRealmsEnd() const {
+ return ++TFailRealmIterator(std::prev(Topology->FailRealms.end()), TRootIteratorBase(Topology.get(), false));
+ }
+
+ inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::FailDomainsBegin() const {
+ return FailRealmsBegin().FailRealmFailDomainsBegin();
+ }
+
+ inline TBlobStorageGroupInfo::TFailDomainIterator TBlobStorageGroupInfo::FailDomainsEnd() const {
+ return (--FailRealmsEnd()).FailRealmFailDomainsEnd();
+ }
+
+ inline TBlobStorageGroupInfo::TFailDomainRange TBlobStorageGroupInfo::GetFailDomains() const {
+ return TFailDomainRange(FailDomainsBegin(), FailDomainsEnd());
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::VDisksBegin() const {
+ return FailRealmsBegin().FailRealmVDisksBegin();
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskIterator TBlobStorageGroupInfo::VDisksEnd() const {
+ return (--FailRealmsEnd()).FailRealmVDisksEnd();
+ }
+
+ inline TBlobStorageGroupInfo::TVDiskRange TBlobStorageGroupInfo::GetVDisks() const {
+ return TVDiskRange(VDisksBegin(), VDisksEnd());
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -380,4 +380,4 @@ namespace NKikimr {
return TVDiskRange(VDisksBegin(), VDisksEnd());
}
-} // NKikimr
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter_ut.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter_ut.cpp
index 3810d6ef988..96bda829390 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter_ut.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter_ut.cpp
@@ -1,139 +1,139 @@
#include <library/cpp/testing/unittest/registar.h>
-#include "blobstorage_groupinfo_iter.h"
-
-using namespace NKikimr;
-
+#include "blobstorage_groupinfo_iter.h"
+
+using namespace NKikimr;
+
TIntrusivePtr<TBlobStorageGroupInfo> CreateTestGroupInfo(TVector<TVDiskID>& vdisks) {
- TIntrusivePtr<TBlobStorageGroupInfo> info = new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 5, 10, 5);
- for (const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo : info->GetVDisks()) {
- vdisks.push_back(info->GetVDiskId(vdiskInfo.OrderNumber));
- }
- return info;
-}
-
+ TIntrusivePtr<TBlobStorageGroupInfo> info = new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 5, 10, 5);
+ for (const TBlobStorageGroupInfo::TVDiskInfo& vdiskInfo : info->GetVDisks()) {
+ vdisks.push_back(info->GetVDiskId(vdiskInfo.OrderNumber));
+ }
+ return info;
+}
+
Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoIterTest) {
Y_UNIT_TEST(IteratorForward) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- ui32 pos = 0;
- for (auto it = info->VDisksBegin(), end = info->VDisksEnd(); it != end; ++it, ++pos) {
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ ui32 pos = 0;
+ for (auto it = info->VDisksBegin(), end = info->VDisksEnd(); it != end; ++it, ++pos) {
auto vd = info->GetVDiskId(it->OrderNumber);
UNIT_ASSERT_EQUAL(vd, vdisks[pos]);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(IteratorBackward) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- auto end = info->VDisksEnd();
- auto it = end;
- for (ui32 pos = vdisks.size(); pos--; ) {
- --it;
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ auto end = info->VDisksEnd();
+ auto it = end;
+ for (ui32 pos = vdisks.size(); pos--; ) {
+ --it;
auto vd = info->GetVDiskId(it->OrderNumber);
UNIT_ASSERT_EQUAL(vd, vdisks[pos]);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(IteratorForwardAndBackward) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- ui32 pos = 0;
- for (auto it = info->VDisksBegin(), end = info->VDisksEnd(); it != end; ++it, ++pos) {
- auto temp = it;
- for (ui32 i = 0; i <= pos; ++i) {
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ ui32 pos = 0;
+ for (auto it = info->VDisksBegin(), end = info->VDisksEnd(); it != end; ++it, ++pos) {
+ auto temp = it;
+ for (ui32 i = 0; i <= pos; ++i) {
UNIT_ASSERT_EQUAL(info->GetVDiskId(temp->OrderNumber), vdisks[pos - i]);
- if (i != pos) {
- --temp;
- } else {
- UNIT_ASSERT_EQUAL(temp, info->VDisksBegin());
- }
- }
- }
- UNIT_ASSERT_EQUAL(pos, vdisks.size());
- }
-
+ if (i != pos) {
+ --temp;
+ } else {
+ UNIT_ASSERT_EQUAL(temp, info->VDisksBegin());
+ }
+ }
+ }
+ UNIT_ASSERT_EQUAL(pos, vdisks.size());
+ }
+
Y_UNIT_TEST(PerRealmIterator) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- for (auto realmIt = info->FailRealmsBegin(); realmIt != info->FailRealmsEnd(); ++realmIt) {
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ for (auto realmIt = info->FailRealmsBegin(); realmIt != info->FailRealmsEnd(); ++realmIt) {
TVector<TVDiskID> vdisksInFailRealm;
- for (const TVDiskID& vdisk : vdisks) {
- if (vdisk.FailRealm == realmIt.GetFailRealmIdx()) {
- vdisksInFailRealm.push_back(vdisk);
- }
- }
-
- ui32 pos = 0;
- for (auto it = realmIt.FailRealmVDisksBegin(), end = realmIt.FailRealmVDisksEnd(); it != end; ++it, ++pos) {
- auto temp = it;
- for (ui32 i = 0; i <= pos; ++i) {
+ for (const TVDiskID& vdisk : vdisks) {
+ if (vdisk.FailRealm == realmIt.GetFailRealmIdx()) {
+ vdisksInFailRealm.push_back(vdisk);
+ }
+ }
+
+ ui32 pos = 0;
+ for (auto it = realmIt.FailRealmVDisksBegin(), end = realmIt.FailRealmVDisksEnd(); it != end; ++it, ++pos) {
+ auto temp = it;
+ for (ui32 i = 0; i <= pos; ++i) {
UNIT_ASSERT_EQUAL(info->GetVDiskId(temp->OrderNumber), vdisksInFailRealm[pos - i]);
- if (i != pos) {
- --temp;
- } else {
- UNIT_ASSERT_EQUAL(temp, realmIt.FailRealmVDisksBegin());
- }
- }
- }
- UNIT_ASSERT_EQUAL(pos, vdisksInFailRealm.size());
- }
- }
-
+ if (i != pos) {
+ --temp;
+ } else {
+ UNIT_ASSERT_EQUAL(temp, realmIt.FailRealmVDisksBegin());
+ }
+ }
+ }
+ UNIT_ASSERT_EQUAL(pos, vdisksInFailRealm.size());
+ }
+ }
+
Y_UNIT_TEST(PerFailDomainRange) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
- for (auto domIt = it.FailRealmFailDomainsBegin(); domIt != it.FailRealmFailDomainsEnd(); ++domIt) {
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
+ for (auto domIt = it.FailRealmFailDomainsBegin(); domIt != it.FailRealmFailDomainsEnd(); ++domIt) {
TVector<TVDiskID> vdisksInDomain;
- for (const TVDiskID& vdisk : vdisks) {
- if (vdisk.FailRealm == domIt.GetFailRealmIdx() && vdisk.FailDomain == domIt.GetFailDomainIdx()) {
- vdisksInDomain.push_back(vdisk);
- }
- }
-
- ui32 pos = 0;
- for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
+ for (const TVDiskID& vdisk : vdisks) {
+ if (vdisk.FailRealm == domIt.GetFailRealmIdx() && vdisk.FailDomain == domIt.GetFailDomainIdx()) {
+ vdisksInDomain.push_back(vdisk);
+ }
+ }
+
+ ui32 pos = 0;
+ for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
auto vd = info->GetVDiskId(vdisk.OrderNumber);
UNIT_ASSERT_EQUAL(vdisksInDomain[pos], vd);
- ++pos;
- }
- UNIT_ASSERT_EQUAL(pos, vdisksInDomain.size());
- }
- }
- }
-
+ ++pos;
+ }
+ UNIT_ASSERT_EQUAL(pos, vdisksInDomain.size());
+ }
+ }
+ }
+
Y_UNIT_TEST(Domains) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
TVector<std::pair<ui32, ui32>> x1, x2;
- for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
- for (auto domIt = it.FailRealmFailDomainsBegin(); domIt != it.FailRealmFailDomainsEnd(); ++domIt) {
- x1.emplace_back(it.GetFailRealmIdx(), domIt.GetFailDomainIdx());
- }
- }
- for (auto domIt = info->FailDomainsBegin(); domIt != info->FailDomainsEnd(); ++domIt) {
- x2.emplace_back(domIt.GetFailRealmIdx(), domIt.GetFailDomainIdx());
- }
- UNIT_ASSERT_VALUES_EQUAL(x1, x2);
- }
-
+ for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
+ for (auto domIt = it.FailRealmFailDomainsBegin(); domIt != it.FailRealmFailDomainsEnd(); ++domIt) {
+ x1.emplace_back(it.GetFailRealmIdx(), domIt.GetFailDomainIdx());
+ }
+ }
+ for (auto domIt = info->FailDomainsBegin(); domIt != info->FailDomainsEnd(); ++domIt) {
+ x2.emplace_back(domIt.GetFailRealmIdx(), domIt.GetFailDomainIdx());
+ }
+ UNIT_ASSERT_VALUES_EQUAL(x1, x2);
+ }
+
Y_UNIT_TEST(Indexes) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- for (auto it = info->VDisksBegin(); it != info->VDisksEnd(); ++it) {
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ for (auto it = info->VDisksBegin(); it != info->VDisksEnd(); ++it) {
UNIT_ASSERT_EQUAL(it->VDiskIdShort.FailRealm, it.GetFailRealmIdx());
UNIT_ASSERT_EQUAL(it->VDiskIdShort.FailDomain, it.GetFailDomainIdx());
UNIT_ASSERT_EQUAL(it->VDiskIdShort.VDisk, it.GetVDiskIdx());
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(WalkFailRealms) {
TVector<TVDiskID> vdisks;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
- ui32 num = 0;
- for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
- UNIT_ASSERT_EQUAL(num, it.GetFailRealmIdx());
- ++num;
- }
- }
-}
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroupInfo(vdisks);
+ ui32 num = 0;
+ for (auto it = info->FailRealmsBegin(); it != info->FailRealmsEnd(); ++it) {
+ UNIT_ASSERT_EQUAL(num, it.GetFailRealmIdx());
+ ++num;
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.cpp
index 37eec8059a2..413d2769008 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.cpp
@@ -1,115 +1,115 @@
-#include "blobstorage_groupinfo_partlayout.h"
-#include "blobstorage_groupinfo_sets.h"
+#include "blobstorage_groupinfo_partlayout.h"
+#include "blobstorage_groupinfo_sets.h"
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
-
-namespace NKikimr {
-
- template<typename Iterator>
- ui32 CountEffectiveReplicasGeneric(Iterator begin, Iterator end, ui32 usedDiskMask = 0) {
- if (begin == end) {
- return PopCount(usedDiskMask);
- }
- ui32 value = *begin++ & ~usedDiskMask;
- ui32 res = CountEffectiveReplicasGeneric(begin, end, usedDiskMask); // try skipping this disk
- while (value) {
- const ui32 leastDiskMask = 1 << CountTrailingZeroBits(value); // obtain the least set bit as a bitmask
- res = Max(res, CountEffectiveReplicasGeneric(begin, end, usedDiskMask | leastDiskMask)); // try this disk for current part
- value &= ~leastDiskMask;
- }
- return res;
- }
-
- ui32 TSubgroupPartLayout::CountEffectiveReplicas(const TBlobStorageGroupType &gtype) const {
- switch (gtype.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- case TBlobStorageGroupType::ErasureMirror3of4:
- Y_FAIL("inapplicable operation for erasure %s", TBlobStorageGroupType::ErasureSpeciesName(gtype.GetErasure()).data());
- default: {
- /*******************************************************************************************************
- * PerPartStatus is a matrix with bits indicating if the some part is present at specific disk; it looks
- * like:
- *
- * M 0 0 0 0 0 H1 H2
- * 0 M 0 0 0 0 H1 H2
- * 0 0 M 0 0 0 H1 H2
- * 0 0 0 M 0 0 H1 H2
- * 0 0 0 0 M 0 H1 H2
- * 0 0 0 0 0 M H1 H2
- *
- * where M is the main disk for each part idx and the H[i] is the i-th handoff disk
- */
- const ui32 totalPartCount = gtype.TotalPartCount();
- const ui32 mainMask = (1 << totalPartCount) - 1;
-
- // calculate mask of main parts in place
- ui32 total = 0;
- for (ui32 i = 0; i < totalPartCount; ++i) {
- total |= PerPartStatus[i];
- }
- total &= mainMask;
-
- // count them as effective replicas
- ui32 res = PopCount(total);
-
- if (total != mainMask) {
- // here we filter out handoff disks containing at least one of required parts (which are indicated
- // by bits in total); each row in 'handoffs' table contains bitmask of handoff disks containing
- // specific part
- TStackVec<ui32, MaxTotalPartCount> handoffDiskByPart;
- for (ui32 i = 0; i < totalPartCount; ++i) {
- const ui32 value = PerPartStatus[i] >> totalPartCount;
- if (~total & 1 << i && value) { // if there is no such part at main disk
- handoffDiskByPart.push_back(value);
- }
- }
- switch (handoffDiskByPart.size()) {
- case 0: // no handoff disks contain required parts
- break;
-
- case 1: // only one handoff disks contains at least one part -- we can use it
- ++res;
- break;
-
- case 2: { // two handoff disks contain parts
- const ui32 a = handoffDiskByPart[0], b = handoffDiskByPart[1];
- res += Min(2U, PopCount(a | b)); // if both disks contain the same part, we can use only one disk
- break;
- }
-
- default: // use generic algorithm
- res += CountEffectiveReplicasGeneric(handoffDiskByPart.begin(), handoffDiskByPart.end());
- break;
- }
- }
-
- return res;
- }
- }
- }
-
- ui32 TSubgroupPartLayout::CountEffectiveReplicas(TIngress ingress, TBlobStorageGroupType gtype) {
- return CreateFromIngress(ingress, gtype).CountEffectiveReplicas(gtype);
- }
-
+
+namespace NKikimr {
+
+ template<typename Iterator>
+ ui32 CountEffectiveReplicasGeneric(Iterator begin, Iterator end, ui32 usedDiskMask = 0) {
+ if (begin == end) {
+ return PopCount(usedDiskMask);
+ }
+ ui32 value = *begin++ & ~usedDiskMask;
+ ui32 res = CountEffectiveReplicasGeneric(begin, end, usedDiskMask); // try skipping this disk
+ while (value) {
+ const ui32 leastDiskMask = 1 << CountTrailingZeroBits(value); // obtain the least set bit as a bitmask
+ res = Max(res, CountEffectiveReplicasGeneric(begin, end, usedDiskMask | leastDiskMask)); // try this disk for current part
+ value &= ~leastDiskMask;
+ }
+ return res;
+ }
+
+ ui32 TSubgroupPartLayout::CountEffectiveReplicas(const TBlobStorageGroupType &gtype) const {
+ switch (gtype.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ Y_FAIL("inapplicable operation for erasure %s", TBlobStorageGroupType::ErasureSpeciesName(gtype.GetErasure()).data());
+ default: {
+ /*******************************************************************************************************
+ * PerPartStatus is a matrix with bits indicating if the some part is present at specific disk; it looks
+ * like:
+ *
+ * M 0 0 0 0 0 H1 H2
+ * 0 M 0 0 0 0 H1 H2
+ * 0 0 M 0 0 0 H1 H2
+ * 0 0 0 M 0 0 H1 H2
+ * 0 0 0 0 M 0 H1 H2
+ * 0 0 0 0 0 M H1 H2
+ *
+ * where M is the main disk for each part idx and the H[i] is the i-th handoff disk
+ */
+ const ui32 totalPartCount = gtype.TotalPartCount();
+ const ui32 mainMask = (1 << totalPartCount) - 1;
+
+ // calculate mask of main parts in place
+ ui32 total = 0;
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ total |= PerPartStatus[i];
+ }
+ total &= mainMask;
+
+ // count them as effective replicas
+ ui32 res = PopCount(total);
+
+ if (total != mainMask) {
+ // here we filter out handoff disks containing at least one of required parts (which are indicated
+ // by bits in total); each row in 'handoffs' table contains bitmask of handoff disks containing
+ // specific part
+ TStackVec<ui32, MaxTotalPartCount> handoffDiskByPart;
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ const ui32 value = PerPartStatus[i] >> totalPartCount;
+ if (~total & 1 << i && value) { // if there is no such part at main disk
+ handoffDiskByPart.push_back(value);
+ }
+ }
+ switch (handoffDiskByPart.size()) {
+ case 0: // no handoff disks contain required parts
+ break;
+
+ case 1: // only one handoff disks contains at least one part -- we can use it
+ ++res;
+ break;
+
+ case 2: { // two handoff disks contain parts
+ const ui32 a = handoffDiskByPart[0], b = handoffDiskByPart[1];
+ res += Min(2U, PopCount(a | b)); // if both disks contain the same part, we can use only one disk
+ break;
+ }
+
+ default: // use generic algorithm
+ res += CountEffectiveReplicasGeneric(handoffDiskByPart.begin(), handoffDiskByPart.end());
+ break;
+ }
+ }
+
+ return res;
+ }
+ }
+ }
+
+ ui32 TSubgroupPartLayout::CountEffectiveReplicas(TIngress ingress, TBlobStorageGroupType gtype) {
+ return CreateFromIngress(ingress, gtype).CountEffectiveReplicas(gtype);
+ }
+
TSubgroupPartLayout TSubgroupPartLayout::CreateFromIngress(TIngress ingress, const TBlobStorageGroupType &gtype) {
- TSubgroupPartLayout res;
- const ui8 subgroupSize = gtype.BlobSubgroupSize();
- for (ui8 i = 0; i < subgroupSize; ++i) {
- const NMatrix::TVectorType parts = ingress.KnownParts(gtype, i);
- for (ui8 j = parts.FirstPosition(); j != parts.GetSize(); j = parts.NextPosition(j)) {
- res.AddItem(i, j, gtype);
- }
- }
- return res;
- }
-
+ TSubgroupPartLayout res;
+ const ui8 subgroupSize = gtype.BlobSubgroupSize();
+ for (ui8 i = 0; i < subgroupSize; ++i) {
+ const NMatrix::TVectorType parts = ingress.KnownParts(gtype, i);
+ for (ui8 j = parts.FirstPosition(); j != parts.GetSize(); j = parts.NextPosition(j)) {
+ res.AddItem(i, j, gtype);
+ }
+ }
+ return res;
+ }
+
TBlobStorageGroupInfo::TSubgroupVDisks TSubgroupPartLayout::GetInvolvedDisks(const TBlobStorageGroupInfo::TTopology *top) const {
const ui32 totalPartCount = top->GType.TotalPartCount();
- ui32 mask = 0;
- for (ui32 i = 0; i < totalPartCount; ++i) {
- mask |= PerPartStatus[i];
- }
+ ui32 mask = 0;
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ mask |= PerPartStatus[i];
+ }
return TBlobStorageGroupInfo::TSubgroupVDisks::CreateFromMask(top, mask);
- }
-
-} // NKikimr
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h
index 77a6aa30e24..ca442b8a1a4 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h
@@ -1,165 +1,165 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_groupinfo.h"
-
-namespace NKikimr {
-
- class TIngress;
-
- // A special class that contains actual layout of some blob across its subgroup. It contains a number of rows
- // matching the number of parts for the specific erasure type, whereas each cell in a row contains a bit indicating
- // whether a specific part (identified by row number) is present on a subgroup's disk (identified by column number)
- class TSubgroupPartLayout {
- using TRowBitMask = ui16;
- static_assert(sizeof(TRowBitMask) * CHAR_BIT >= MaxNodesPerBlob, "incorrect size of row mask");
- using TTable = std::array<TRowBitMask, MaxTotalPartCount>;
-
- TTable PerPartStatus;
-
- public:
- TSubgroupPartLayout() {
- // clear all states to zero
- std::fill(PerPartStatus.begin(), PerPartStatus.end(), 0);
- }
-
+#include "blobstorage_groupinfo.h"
+
+namespace NKikimr {
+
+ class TIngress;
+
+ // A special class that contains actual layout of some blob across its subgroup. It contains a number of rows
+ // matching the number of parts for the specific erasure type, whereas each cell in a row contains a bit indicating
+ // whether a specific part (identified by row number) is present on a subgroup's disk (identified by column number)
+ class TSubgroupPartLayout {
+ using TRowBitMask = ui16;
+ static_assert(sizeof(TRowBitMask) * CHAR_BIT >= MaxNodesPerBlob, "incorrect size of row mask");
+ using TTable = std::array<TRowBitMask, MaxTotalPartCount>;
+
+ TTable PerPartStatus;
+
+ public:
+ TSubgroupPartLayout() {
+ // clear all states to zero
+ std::fill(PerPartStatus.begin(), PerPartStatus.end(), 0);
+ }
+
void AddItem(ui32 nodeId, ui32 partIdx, const TBlobStorageGroupType &gtype) {
Y_VERIFY(nodeId < gtype.BlobSubgroupSize() && partIdx < gtype.TotalPartCount());
- PerPartStatus[partIdx] |= TRowBitMask(1) << nodeId;
- }
-
- void ClearItem(ui32 nodeId, ui32 partIdx, const TBlobStorageGroupType& gtype) {
- Y_VERIFY(nodeId < gtype.BlobSubgroupSize() && partIdx < gtype.TotalPartCount());
- PerPartStatus[partIdx] &= ~(TRowBitMask(1) << nodeId);
- }
-
- void Merge(const TSubgroupPartLayout& other, const TBlobStorageGroupType& type) {
- for (ui32 partIdx = 0; partIdx < type.TotalPartCount(); ++partIdx) {
- PerPartStatus[partIdx] |= other.PerPartStatus[partIdx];
- }
- }
-
- // Count number of effective replicas (that is, the number of replicas written on distinct disks) using the
- // part-to-node mask; items in that mask are indexes by part index and contain bitmask of subgroup's disks
- // containing these parts
+ PerPartStatus[partIdx] |= TRowBitMask(1) << nodeId;
+ }
+
+ void ClearItem(ui32 nodeId, ui32 partIdx, const TBlobStorageGroupType& gtype) {
+ Y_VERIFY(nodeId < gtype.BlobSubgroupSize() && partIdx < gtype.TotalPartCount());
+ PerPartStatus[partIdx] &= ~(TRowBitMask(1) << nodeId);
+ }
+
+ void Merge(const TSubgroupPartLayout& other, const TBlobStorageGroupType& type) {
+ for (ui32 partIdx = 0; partIdx < type.TotalPartCount(); ++partIdx) {
+ PerPartStatus[partIdx] |= other.PerPartStatus[partIdx];
+ }
+ }
+
+ // Count number of effective replicas (that is, the number of replicas written on distinct disks) using the
+ // part-to-node mask; items in that mask are indexes by part index and contain bitmask of subgroup's disks
+ // containing these parts
ui32 CountEffectiveReplicas(const TBlobStorageGroupType &gtype) const;
-
- // Create part layout from ingress
+
+ // Create part layout from ingress
static TSubgroupPartLayout CreateFromIngress(TIngress ingress, const TBlobStorageGroupType &gtype);
-
- // Count effective replicas based on ingress.
- static ui32 CountEffectiveReplicas(TIngress ingress, TBlobStorageGroupType gtype);
-
- // Return a set of subgroup's disk contaning any replicas
+
+ // Count effective replicas based on ingress.
+ static ui32 CountEffectiveReplicas(TIngress ingress, TBlobStorageGroupType gtype);
+
+ // Return a set of subgroup's disk contaning any replicas
TBlobStorageGroupInfo::TSubgroupVDisks GetInvolvedDisks(const TBlobStorageGroupInfo::TTopology *top) const;
-
+
void Output(IOutputStream& str, const TBlobStorageGroupType &gtype) const {
const ui32 totalPartCount = gtype.TotalPartCount();
- str << "{";
- for (ui32 i = 0; i < totalPartCount; ++i) {
- if (i) {
- str << " ";
- }
- for (ui32 j = 0; j < gtype.BlobSubgroupSize(); ++j) {
- str << ((PerPartStatus[i] >> (gtype.BlobSubgroupSize() - j - 1)) & 1);
- }
- }
- str << "}";
- }
-
- TString ToString(const TBlobStorageGroupType& gtype) const {
- TStringStream s;
- Output(s, gtype);
- return s.Str();
- }
-
- ui32 GetDisksWithPart(ui32 partIdx) const {
- return PerPartStatus[partIdx];
- }
-
- std::pair<ui32, ui32> GetMirror3of4State() const {
- const ui32 data = PerPartStatus[0] | PerPartStatus[1];
- const ui32 meta = PerPartStatus[2];
- return std::make_tuple(PopCount(data), PopCount(data | meta));
- }
-
- template<typename F>
- void ForEachPartOfDisk(const TBlobStorageGroupType& gtype, F&& callback) const {
- for (ui32 partIdx = 0; partIdx < gtype.TotalPartCount(); ++partIdx) {
- ui32 mask = PerPartStatus[partIdx];
- while (mask) {
- const ui32 idxInSubgroup = CountTrailingZeroBits(mask);
- mask &= ~(1 << idxInSubgroup);
- callback(partIdx, idxInSubgroup);
- }
- }
- }
-
- template<typename F>
- static void GeneratePossibleLayouts(const TBlobStorageGroupType& gtype, ui32 maxHandoffBits, F&& callback) {
- std::vector<std::vector<ui32>> perDiskPartMasks(gtype.BlobSubgroupSize());
- for (ui32 idxInSubgroup = 0; idxInSubgroup < perDiskPartMasks.size(); ++idxInSubgroup) {
- auto& partMasks = perDiskPartMasks[idxInSubgroup];
- partMasks.push_back(0);
- switch (gtype.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- partMasks.push_back(1 << (idxInSubgroup % 3));
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- partMasks.push_back(1 << (idxInSubgroup & 1)); // data part only
- partMasks.push_back(1 << (idxInSubgroup & 1) | 1 << 2); // data part + metadata part
- partMasks.push_back(1 << 2); // metadata part only
- break;
-
- default:
- if (idxInSubgroup < gtype.TotalPartCount()) {
- partMasks.push_back(1 << idxInSubgroup);
- } else {
- for (ui32 j = 1; j < 1 << gtype.TotalPartCount(); ++j) {
- if (PopCount(j) <= maxHandoffBits) {
- partMasks.push_back(j);
- }
- }
- }
- break;
- }
- }
-
- std::vector<ui8> state(perDiskPartMasks.size(), 0);
- for (;;) {
- TSubgroupPartLayout layout;
-
- for (ui32 idxInSubgroup = 0; idxInSubgroup < state.size(); ++idxInSubgroup) {
- ui32 diskMask = perDiskPartMasks[idxInSubgroup][state[idxInSubgroup]];
- while (diskMask) {
- const ui32 partIdx = CountTrailingZeroBits(diskMask);
- diskMask &= ~(1 << partIdx);
- layout.AddItem(idxInSubgroup, partIdx, gtype);
- }
- }
-
- callback(layout);
-
- for (ui32 idxInSubgroup = 0; idxInSubgroup < state.size(); ++idxInSubgroup) {
- if (++state[idxInSubgroup] != perDiskPartMasks[idxInSubgroup].size()) {
- break;
- } else if (idxInSubgroup + 1 != state.size()) {
- state[idxInSubgroup] = 0;
- } else {
- return;
- }
- }
- }
- }
-
- friend bool operator ==(const TSubgroupPartLayout& x, const TSubgroupPartLayout& y) {
- return x.PerPartStatus == y.PerPartStatus;
- }
-
- friend bool operator !=(const TSubgroupPartLayout& x, const TSubgroupPartLayout& y) {
- return x.PerPartStatus != y.PerPartStatus;
- }
- };
-
-} // NKikimr
+ str << "{";
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ if (i) {
+ str << " ";
+ }
+ for (ui32 j = 0; j < gtype.BlobSubgroupSize(); ++j) {
+ str << ((PerPartStatus[i] >> (gtype.BlobSubgroupSize() - j - 1)) & 1);
+ }
+ }
+ str << "}";
+ }
+
+ TString ToString(const TBlobStorageGroupType& gtype) const {
+ TStringStream s;
+ Output(s, gtype);
+ return s.Str();
+ }
+
+ ui32 GetDisksWithPart(ui32 partIdx) const {
+ return PerPartStatus[partIdx];
+ }
+
+ std::pair<ui32, ui32> GetMirror3of4State() const {
+ const ui32 data = PerPartStatus[0] | PerPartStatus[1];
+ const ui32 meta = PerPartStatus[2];
+ return std::make_tuple(PopCount(data), PopCount(data | meta));
+ }
+
+ template<typename F>
+ void ForEachPartOfDisk(const TBlobStorageGroupType& gtype, F&& callback) const {
+ for (ui32 partIdx = 0; partIdx < gtype.TotalPartCount(); ++partIdx) {
+ ui32 mask = PerPartStatus[partIdx];
+ while (mask) {
+ const ui32 idxInSubgroup = CountTrailingZeroBits(mask);
+ mask &= ~(1 << idxInSubgroup);
+ callback(partIdx, idxInSubgroup);
+ }
+ }
+ }
+
+ template<typename F>
+ static void GeneratePossibleLayouts(const TBlobStorageGroupType& gtype, ui32 maxHandoffBits, F&& callback) {
+ std::vector<std::vector<ui32>> perDiskPartMasks(gtype.BlobSubgroupSize());
+ for (ui32 idxInSubgroup = 0; idxInSubgroup < perDiskPartMasks.size(); ++idxInSubgroup) {
+ auto& partMasks = perDiskPartMasks[idxInSubgroup];
+ partMasks.push_back(0);
+ switch (gtype.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ partMasks.push_back(1 << (idxInSubgroup % 3));
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ partMasks.push_back(1 << (idxInSubgroup & 1)); // data part only
+ partMasks.push_back(1 << (idxInSubgroup & 1) | 1 << 2); // data part + metadata part
+ partMasks.push_back(1 << 2); // metadata part only
+ break;
+
+ default:
+ if (idxInSubgroup < gtype.TotalPartCount()) {
+ partMasks.push_back(1 << idxInSubgroup);
+ } else {
+ for (ui32 j = 1; j < 1 << gtype.TotalPartCount(); ++j) {
+ if (PopCount(j) <= maxHandoffBits) {
+ partMasks.push_back(j);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ std::vector<ui8> state(perDiskPartMasks.size(), 0);
+ for (;;) {
+ TSubgroupPartLayout layout;
+
+ for (ui32 idxInSubgroup = 0; idxInSubgroup < state.size(); ++idxInSubgroup) {
+ ui32 diskMask = perDiskPartMasks[idxInSubgroup][state[idxInSubgroup]];
+ while (diskMask) {
+ const ui32 partIdx = CountTrailingZeroBits(diskMask);
+ diskMask &= ~(1 << partIdx);
+ layout.AddItem(idxInSubgroup, partIdx, gtype);
+ }
+ }
+
+ callback(layout);
+
+ for (ui32 idxInSubgroup = 0; idxInSubgroup < state.size(); ++idxInSubgroup) {
+ if (++state[idxInSubgroup] != perDiskPartMasks[idxInSubgroup].size()) {
+ break;
+ } else if (idxInSubgroup + 1 != state.size()) {
+ state[idxInSubgroup] = 0;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+
+ friend bool operator ==(const TSubgroupPartLayout& x, const TSubgroupPartLayout& y) {
+ return x.PerPartStatus == y.PerPartStatus;
+ }
+
+ friend bool operator !=(const TSubgroupPartLayout& x, const TSubgroupPartLayout& y) {
+ return x.PerPartStatus != y.PerPartStatus;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout_ut.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout_ut.cpp
index 900f40a0b7b..a58ed2e3da8 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout_ut.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout_ut.cpp
@@ -1,101 +1,101 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include "blobstorage_groupinfo_partlayout.h"
-#include <thread>
-#include <mutex>
-#include <condition_variable>
+#include <library/cpp/testing/unittest/registar.h>
+#include "blobstorage_groupinfo_partlayout.h"
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+
+using namespace NKikimr;
+
+ui32 CountEffectiveReplicas(const TSubgroupPartLayout& layout, ui32 numRows, ui32 numCols) {
+ // number of effective replicas is calculated as the maximum number of rows that can be mapped to unique columns in
+ // layout with bit at intersecting cell set to zero; here we state that numCols >= numRows
+ UNIT_ASSERT(numCols >= numRows);
+ std::vector<ui32> index(numCols);
+ for (size_t i = 0; i < index.size(); ++i) {
+ index[i] = i;
+ }
+ ui32 res = 0;
+ do {
+ ui32 value = 0;
+ for (ui32 row = 0; row < numRows; ++row) {
+ // extract the cell at row, col and count it if it is nonzero
+ value += layout.GetDisksWithPart(row) >> index[row] & 1;
+ }
+ if (value > res) {
+ res = value;
+ }
+ } while (std::next_permutation(index.begin(), index.end()));
+ return res;
+}
+
+class TCheckQueue {
+ std::mutex Mutex;
+ std::list<std::thread> Threads;
+ std::deque<TSubgroupPartLayout> Queue;
+ std::condition_variable Cvar, ReverseCvar;
+ volatile bool Done = false;
+ std::atomic_size_t CasesChecked = 0;
+ std::atomic_uint64_t Timing = 0;
+
+public:
+ TCheckQueue(TBlobStorageGroupType gtype) {
+ for (int n = std::thread::hardware_concurrency(); n; --n) {
+ Threads.emplace_back([=] {
+ for (;;) {
+ TSubgroupPartLayout layout;
+ {
+ std::unique_lock<std::mutex> lock(Mutex);
+ Cvar.wait(lock, [&] { return Done || !Queue.empty(); });
+ if (Queue.empty() && Done) {
+ return;
+ }
+ Y_VERIFY(!Queue.empty());
+ layout = std::move(Queue.front());
+ Queue.pop_front();
+ if (Queue.size() < 1024) {
+ ReverseCvar.notify_one();
+ }
+ }
-using namespace NKikimr;
-
-ui32 CountEffectiveReplicas(const TSubgroupPartLayout& layout, ui32 numRows, ui32 numCols) {
- // number of effective replicas is calculated as the maximum number of rows that can be mapped to unique columns in
- // layout with bit at intersecting cell set to zero; here we state that numCols >= numRows
- UNIT_ASSERT(numCols >= numRows);
- std::vector<ui32> index(numCols);
- for (size_t i = 0; i < index.size(); ++i) {
- index[i] = i;
- }
- ui32 res = 0;
- do {
- ui32 value = 0;
- for (ui32 row = 0; row < numRows; ++row) {
- // extract the cell at row, col and count it if it is nonzero
- value += layout.GetDisksWithPart(row) >> index[row] & 1;
- }
- if (value > res) {
- res = value;
- }
- } while (std::next_permutation(index.begin(), index.end()));
- return res;
-}
-
-class TCheckQueue {
- std::mutex Mutex;
- std::list<std::thread> Threads;
- std::deque<TSubgroupPartLayout> Queue;
- std::condition_variable Cvar, ReverseCvar;
- volatile bool Done = false;
- std::atomic_size_t CasesChecked = 0;
- std::atomic_uint64_t Timing = 0;
-
-public:
- TCheckQueue(TBlobStorageGroupType gtype) {
- for (int n = std::thread::hardware_concurrency(); n; --n) {
- Threads.emplace_back([=] {
- for (;;) {
- TSubgroupPartLayout layout;
- {
- std::unique_lock<std::mutex> lock(Mutex);
- Cvar.wait(lock, [&] { return Done || !Queue.empty(); });
- if (Queue.empty() && Done) {
- return;
- }
- Y_VERIFY(!Queue.empty());
- layout = std::move(Queue.front());
- Queue.pop_front();
- if (Queue.size() < 1024) {
- ReverseCvar.notify_one();
- }
- }
-
- // count effective replicas
- THPTimer timer;
- ui32 count = layout.CountEffectiveReplicas(gtype);
- Timing += 1e9 * timer.Passed();
-
- // compare it with generic value
- ui32 generic = CountEffectiveReplicas(layout, gtype.TotalPartCount(), gtype.BlobSubgroupSize());
-
- // verify the value
- Y_VERIFY(count == generic, "count# %" PRIu32 " generic# %" PRIu32 " layout# %s erasure# %s",
- count, generic, layout.ToString(gtype).data(),
- TBlobStorageGroupType::ErasureSpeciesName(gtype.GetErasure()).data());
-
- ++CasesChecked;
- }
- });
- }
- }
-
- ~TCheckQueue() {
+ // count effective replicas
+ THPTimer timer;
+ ui32 count = layout.CountEffectiveReplicas(gtype);
+ Timing += 1e9 * timer.Passed();
+
+ // compare it with generic value
+ ui32 generic = CountEffectiveReplicas(layout, gtype.TotalPartCount(), gtype.BlobSubgroupSize());
+
+ // verify the value
+ Y_VERIFY(count == generic, "count# %" PRIu32 " generic# %" PRIu32 " layout# %s erasure# %s",
+ count, generic, layout.ToString(gtype).data(),
+ TBlobStorageGroupType::ErasureSpeciesName(gtype.GetErasure()).data());
+
+ ++CasesChecked;
+ }
+ });
+ }
+ }
+
+ ~TCheckQueue() {
{
std::unique_lock<std::mutex> lock(Mutex);
Done = true;
}
- Cvar.notify_all();
- for (auto& thread : Threads) {
- thread.join();
- }
- Cerr << "Checked " << (size_t)CasesChecked << " cases, took " << (ui64)Timing / 1000 << " us" << Endl;
- }
-
- void operator ()(const TSubgroupPartLayout& layout) {
- std::unique_lock<std::mutex> lock(Mutex);
- ReverseCvar.wait(lock, [&] { return Queue.size() < 1024; });
- Queue.push_back(layout);
- Cvar.notify_one();
- }
-};
-
+ Cvar.notify_all();
+ for (auto& thread : Threads) {
+ thread.join();
+ }
+ Cerr << "Checked " << (size_t)CasesChecked << " cases, took " << (ui64)Timing / 1000 << " us" << Endl;
+ }
+
+ void operator ()(const TSubgroupPartLayout& layout) {
+ std::unique_lock<std::mutex> lock(Mutex);
+ ReverseCvar.wait(lock, [&] { return Queue.size() < 1024; });
+ Queue.push_back(layout);
+ Cvar.notify_one();
+ }
+};
+
void TestErasureSet(ui32 firstIdx, ui32 step) {
for (ui32 erasure = firstIdx; erasure < TBlobStorageGroupType::ErasureSpeciesCount; erasure += step) {
if (erasure == TBlobStorageGroupType::ErasureMirror3dc || erasure == TBlobStorageGroupType::ErasureMirror3of4) {
@@ -124,25 +124,25 @@ void TestErasureSet(ui32 firstIdx, ui32 step) {
for (ui32 i = 0; i < totalPartCount; ++i) {
if (handoffs[nodeId - totalPartCount] & 1 << i) {
layout.AddItem(nodeId, i, gtype);
- }
- }
- }
+ }
+ }
+ }
}
-
+
checker(layout);
-
+
// increment handoffs
ui32 carry = 1;
for (size_t i = 0; carry && i < handoffs.size(); ++i) {
carry = !(++handoffs[i] & (1 << totalPartCount) - 1);
- }
+ }
if (carry) {
break;
}
- }
- }
- }
-}
+ }
+ }
+ }
+}
Y_UNIT_TEST_SUITE(TSubgroupPartLayoutTest) {
Y_UNIT_TEST(CountEffectiveReplicas1of4) {
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h
index 132e0cce852..572d67f951d 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h
@@ -1,388 +1,388 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_groupinfo_iter.h"
-
+#include "blobstorage_groupinfo_iter.h"
+
#include <library/cpp/pop_count/popcount.h>
-
-namespace NKikimr {
-
- // There are basically three types of sets introduced in blob storage groups: a set of disks inside the whole group
- // (referred to as a TGroupVDisks), a set of disks inside a single blob's decomposition (subgroup, TSubgroupVDisks),
- // and a set of fail domains inside the group.
- //
- // Consider the following example group:
- //
- // +---------------+ +---------------+ +---------------+
- // | FAIL REALM 0 | | FAIL REALM 1 | | FAIL REALM 2 |
- // | | | | | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // | | DOMAIN 0 | | | | DOMAIN 0 | | | | DOMAIN 0 | |
- // | | #0 | | | | #3 | | | | #6 | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
- // | | | #0 | | | | | | #6 | | | | | | #12 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
- // | | | #1 | | | | | | #7 | | | | | | #13 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // | | | | | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // | | DOMAIN 1 | | | | DOMAIN 1 | | | | DOMAIN 1 | |
- // | | #1 | | | | #4 | | | | #7 | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
- // | | | #2 | | | | | | #8 | | | | | | #14 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
- // | | | #3 | | | | | | #9 | | | | | | #15 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // | | | | | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // | | DOMAIN 2 | | | | DOMAIN 2 | | | | DOMAIN 2 | |
- // | | #2 | | | | #5 | | | | #8 | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
- // | | | #4 | | | | | | #10 | | | | | | #16 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | | | | | | | | | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
- // | | | #5 | | | | | | #11 | | | | | | #17 | | |
- // | | +-------+ | | | | +-------+ | | | | +-------+ | |
- // | +-----------+ | | +-----------+ | | +-----------+ |
- // +---------------+ +---------------+ +---------------+
- //
- // In any BS group a single VDisk can be referred to as a tuple of (group id, group generation, fail realm, fail
- // domain, vdisk) -- provided by the TVDiskID structure, or by the order number of VDisk inside the continuously
- // numbered group. E.g. in the example group we have VDisk with order number #14 (inside the VDisk box) matching the
- // TVDiskID(id, gen, 2, 1, 0). This order number #14 can be obtained by Info->GetOrderNumber(vdisk) function.
- // Also, each fail domain inside the whole group has its own continuously numbered FailDomainOrderNumber. E.g.
- // fail domain 2 in fail realm 1 has the order number of 5.
- //
- // Internally each set contains information if the corresponding entity is in set or not. This is achieved by using
- // bitfields, in which indexes represent the order number of entities inside the group -- VDisk order numbers for
- // TGroupVDisks, fail domain order numbers for TGroupFailDomains, and IdxInSubgroup for subgroups.
- //
- // TGroupVDisks set is used in commands that span over the whole group; usually it is used to track erroneous replies
- // from VDisks in quorum tracker to determine whether the fail model was exceeded or not; also it is used in quorum
- // tracker to remember successful replies and to get quorum condition.
- //
- // TGroupFailDomains is used internally by TBlobStorageGroupInfo class to match fail model, because the fail model
- // mentions fail domains as basic entities and works solely with them. There is a simple way to create
- // TGroupFailDomains instance from TGroupVDisks class -- by using TGroupFailDomains::CreateFromGroupDiskSet method.
- // There are two ways of creating domain set from disk set. First of them uses ANY predicate and adds domain to set
- // in case if ANY disk inside that domain is in source disk set. Second one uses ALL predicate and adds only these
- // domains where all of VDisks are in source disk set. When working with failed disks set fail domain is considered
- // failed one if ANY disk inside that domain has failed.
- //
- // TSubgroupVDisks set is used to track status of disks comprising blob subgroup. These disks are returned by
+
+namespace NKikimr {
+
+ // There are basically three types of sets introduced in blob storage groups: a set of disks inside the whole group
+ // (referred to as a TGroupVDisks), a set of disks inside a single blob's decomposition (subgroup, TSubgroupVDisks),
+ // and a set of fail domains inside the group.
+ //
+ // Consider the following example group:
+ //
+ // +---------------+ +---------------+ +---------------+
+ // | FAIL REALM 0 | | FAIL REALM 1 | | FAIL REALM 2 |
+ // | | | | | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // | | DOMAIN 0 | | | | DOMAIN 0 | | | | DOMAIN 0 | |
+ // | | #0 | | | | #3 | | | | #6 | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
+ // | | | #0 | | | | | | #6 | | | | | | #12 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
+ // | | | #1 | | | | | | #7 | | | | | | #13 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // | | | | | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // | | DOMAIN 1 | | | | DOMAIN 1 | | | | DOMAIN 1 | |
+ // | | #1 | | | | #4 | | | | #7 | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
+ // | | | #2 | | | | | | #8 | | | | | | #14 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
+ // | | | #3 | | | | | | #9 | | | | | | #15 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // | | | | | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // | | DOMAIN 2 | | | | DOMAIN 2 | | | | DOMAIN 2 | |
+ // | | #2 | | | | #5 | | | | #8 | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 0| | | | | |VDISK 0| | | | | |VDISK 0| | |
+ // | | | #4 | | | | | | #10 | | | | | | #16 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | | | | | | | | | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | | |VDISK 1| | | | | |VDISK 1| | | | | |VDISK 1| | |
+ // | | | #5 | | | | | | #11 | | | | | | #17 | | |
+ // | | +-------+ | | | | +-------+ | | | | +-------+ | |
+ // | +-----------+ | | +-----------+ | | +-----------+ |
+ // +---------------+ +---------------+ +---------------+
+ //
+ // In any BS group a single VDisk can be referred to as a tuple of (group id, group generation, fail realm, fail
+ // domain, vdisk) -- provided by the TVDiskID structure, or by the order number of VDisk inside the continuously
+ // numbered group. E.g. in the example group we have VDisk with order number #14 (inside the VDisk box) matching the
+ // TVDiskID(id, gen, 2, 1, 0). This order number #14 can be obtained by Info->GetOrderNumber(vdisk) function.
+ // Also, each fail domain inside the whole group has its own continuously numbered FailDomainOrderNumber. E.g.
+ // fail domain 2 in fail realm 1 has the order number of 5.
+ //
+ // Internally each set contains information if the corresponding entity is in set or not. This is achieved by using
+ // bitfields, in which indexes represent the order number of entities inside the group -- VDisk order numbers for
+ // TGroupVDisks, fail domain order numbers for TGroupFailDomains, and IdxInSubgroup for subgroups.
+ //
+ // TGroupVDisks set is used in commands that span over the whole group; usually it is used to track erroneous replies
+ // from VDisks in quorum tracker to determine whether the fail model was exceeded or not; also it is used in quorum
+ // tracker to remember successful replies and to get quorum condition.
+ //
+ // TGroupFailDomains is used internally by TBlobStorageGroupInfo class to match fail model, because the fail model
+ // mentions fail domains as basic entities and works solely with them. There is a simple way to create
+ // TGroupFailDomains instance from TGroupVDisks class -- by using TGroupFailDomains::CreateFromGroupDiskSet method.
+ // There are two ways of creating domain set from disk set. First of them uses ANY predicate and adds domain to set
+ // in case if ANY disk inside that domain is in source disk set. Second one uses ALL predicate and adds only these
+ // domains where all of VDisks are in source disk set. When working with failed disks set fail domain is considered
+ // failed one if ANY disk inside that domain has failed.
+ //
+ // TSubgroupVDisks set is used to track status of disks comprising blob subgroup. These disks are returned by
// Top->PickSubgroup() methods and their ordinal indexes inside TVDiskIds array match their bit positions in set.
- //
- // The common methods of manipulating the sets are (Top is std::shared_ptr<TTopology>):
- //
- // 1. Construct empty set:
- // TGroupVDisks set(Top.get());
- //
- // 2. Add NEW disk to the set (function asserts if the vdisk is already in set):
- // set += TGroupVDisks(Top.get(), TVDiskID(vdisk));
- // set += TSubgroupVDisks(Top.get(), Top->GetIdxInSubgroup(id.Hash(), vdisk));
- //
- // 3. Check if disk is in set:
- // if (set & TGroupVDisks(Top.get(), vdisk)) { ... }
- //
- // 4. Check if disk is not in set:
- // if (~set & TGroupVDisks(Top.get(), vdisk)) { ... }
- //
- // 5. Calculate union of two sets:
- // TGroupVDisks res = set1 | set2;
- //
- // 6. Remove disks of one set from another one:
- // set1 -= set2; /* shortcut for set1 &= ~set2; */
- //
- // 7. Count number of disks in set:
- // ui32 num = set.GetNumSetItems();
- //
- // 8. Get the maximum possible number of disks in set:
- // ui32 num = set.GetNumBits();
- //
- // 9. Check if set is not empty
- // if (set) { ... }
- //
- // 10. Check if the group fail model allows failure of provided disks set:
+ //
+ // The common methods of manipulating the sets are (Top is std::shared_ptr<TTopology>):
+ //
+ // 1. Construct empty set:
+ // TGroupVDisks set(Top.get());
+ //
+ // 2. Add NEW disk to the set (function asserts if the vdisk is already in set):
+ // set += TGroupVDisks(Top.get(), TVDiskID(vdisk));
+ // set += TSubgroupVDisks(Top.get(), Top->GetIdxInSubgroup(id.Hash(), vdisk));
+ //
+ // 3. Check if disk is in set:
+ // if (set & TGroupVDisks(Top.get(), vdisk)) { ... }
+ //
+ // 4. Check if disk is not in set:
+ // if (~set & TGroupVDisks(Top.get(), vdisk)) { ... }
+ //
+ // 5. Calculate union of two sets:
+ // TGroupVDisks res = set1 | set2;
+ //
+ // 6. Remove disks of one set from another one:
+ // set1 -= set2; /* shortcut for set1 &= ~set2; */
+ //
+ // 7. Count number of disks in set:
+ // ui32 num = set.GetNumSetItems();
+ //
+ // 8. Get the maximum possible number of disks in set:
+ // ui32 num = set.GetNumBits();
+ //
+ // 9. Check if set is not empty
+ // if (set) { ... }
+ //
+ // 10. Check if the group fail model allows failure of provided disks set:
// if (Top->GetQuorumChecker().CheckFailModelForGroup(failedDisksSet)) { ... }
- //
- // 11. Check for quorum of disks in the group (providing set of successfully answered disks; quorum is obtained when
- // all disks answer except those who may fail):
+ //
+ // 11. Check for quorum of disks in the group (providing set of successfully answered disks; quorum is obtained when
+ // all disks answer except those who may fail):
// if (Top->GetQuorumChecker().CheckQuorumForGroup(successfulDisksSet)) { ... }
-
- template<typename TDerived>
- class TBlobStorageGroupInfo::TDomainSetBase {
- ui64 Mask;
-
- protected:
+
+ template<typename TDerived>
+ class TBlobStorageGroupInfo::TDomainSetBase {
+ ui64 Mask;
+
+ protected:
const TBlobStorageGroupInfo::TTopology *Top;
-
+
TDomainSetBase(const TBlobStorageGroupInfo::TTopology *top)
- : Mask(0)
+ : Mask(0)
, Top(top)
- {}
-
+ {}
+
TDomainSetBase(const TBlobStorageGroupInfo::TTopology *top, ui32 bitIndex)
- : Mask((ui64)1 << bitIndex)
+ : Mask((ui64)1 << bitIndex)
, Top(top)
- {}
-
+ {}
+
TDomainSetBase(const TBlobStorageGroupInfo::TTopology *top, const ui64 *mask)
- : Mask(*mask)
+ : Mask(*mask)
, Top(top)
- {}
-
- public:
- // combine this set with the other one and store the result inplace
- friend TDerived& operator |=(TDerived& x, const TDerived& y) {
+ {}
+
+ public:
+ // combine this set with the other one and store the result inplace
+ friend TDerived& operator |=(TDerived& x, const TDerived& y) {
Y_VERIFY(x.Top == y.Top);
- x.Mask |= y.Mask;
- return x;
- }
-
- // combine two sets and return the result
- friend TDerived operator |(const TDerived& x, const TDerived& y) {
- TDerived res(x);
+ x.Mask |= y.Mask;
+ return x;
+ }
+
+ // combine two sets and return the result
+ friend TDerived operator |(const TDerived& x, const TDerived& y) {
+ TDerived res(x);
return res |= y;
- }
-
- // union of two nonintersecting subsets
- friend TDerived& operator +=(TDerived& x, const TDerived& y) {
- Y_VERIFY(!(x & y));
- return x |= y;
- }
-
- // inplace union of two nonintersecting subsets
- friend TDerived operator +(const TDerived& x, const TDerived& y) {
- Y_VERIFY(!(x & y));
- return x | y;
- }
-
- // calculate intersection of two sets and store the result inplace
- friend TDerived& operator &=(TDerived& x, const TDerived& y) {
+ }
+
+ // union of two nonintersecting subsets
+ friend TDerived& operator +=(TDerived& x, const TDerived& y) {
+ Y_VERIFY(!(x & y));
+ return x |= y;
+ }
+
+ // inplace union of two nonintersecting subsets
+ friend TDerived operator +(const TDerived& x, const TDerived& y) {
+ Y_VERIFY(!(x & y));
+ return x | y;
+ }
+
+ // calculate intersection of two sets and store the result inplace
+ friend TDerived& operator &=(TDerived& x, const TDerived& y) {
Y_VERIFY(x.Top == y.Top);
- x.Mask &= y.Mask;
- return x;
- }
-
- // calculate intersection of two sets and return the result
- friend TDerived operator &(const TDerived& x, const TDerived& y) {
- TDerived res(x);
- return res &= y;
- }
-
- // calculate set difference of two sets -- return items contained in left set, but not in right one; store result
- // inplace
- friend TDerived& operator -=(TDerived& x, const TDerived& y) {
- return x &= ~y;
- }
-
- // calculate set difference for two sets and return the result
- friend TDerived operator -(const TDerived& x, const TDerived& y) {
- TDerived res(x);
- return res -= y;
- }
-
- // calculate the inverse set for the provided group
- friend TDerived operator ~(const TDerived& x) {
- const ui64 mask = ((ui64)1 << x.GetNumBits()) - 1;
- TDerived res(x);
- res.Mask = ~res.Mask & mask;
- return res;
- }
-
- // checks if the set is not empty
- explicit operator bool() const {
- return Mask != 0;
- }
-
- // check for specific bit
- bool operator [](ui32 index) const {
- Y_VERIFY(index < static_cast<const TDerived&>(*this).GetNumBits());
- return (Mask >> index) & 1;
- }
-
- // calculate number of set bits
- ui32 GetNumSetItems() const {
- return PopCount(Mask);
- }
-
+ x.Mask &= y.Mask;
+ return x;
+ }
+
+ // calculate intersection of two sets and return the result
+ friend TDerived operator &(const TDerived& x, const TDerived& y) {
+ TDerived res(x);
+ return res &= y;
+ }
+
+ // calculate set difference of two sets -- return items contained in left set, but not in right one; store result
+ // inplace
+ friend TDerived& operator -=(TDerived& x, const TDerived& y) {
+ return x &= ~y;
+ }
+
+ // calculate set difference for two sets and return the result
+ friend TDerived operator -(const TDerived& x, const TDerived& y) {
+ TDerived res(x);
+ return res -= y;
+ }
+
+ // calculate the inverse set for the provided group
+ friend TDerived operator ~(const TDerived& x) {
+ const ui64 mask = ((ui64)1 << x.GetNumBits()) - 1;
+ TDerived res(x);
+ res.Mask = ~res.Mask & mask;
+ return res;
+ }
+
+ // checks if the set is not empty
+ explicit operator bool() const {
+ return Mask != 0;
+ }
+
+ // check for specific bit
+ bool operator [](ui32 index) const {
+ Y_VERIFY(index < static_cast<const TDerived&>(*this).GetNumBits());
+ return (Mask >> index) & 1;
+ }
+
+ // calculate number of set bits
+ ui32 GetNumSetItems() const {
+ return PopCount(Mask);
+ }
+
const TBlobStorageGroupInfo::TTopology *GetTopology() const {
return Top;
- }
-
+ }
+
void Output(IOutputStream& str) const {
- const ui32 numBits = static_cast<const TDerived&>(*this).GetNumBits();
- for (ui32 i = 0; i < numBits; ++i) {
- str << ((Mask >> (numBits - i - 1)) & 1);
- }
- }
-
+ const ui32 numBits = static_cast<const TDerived&>(*this).GetNumBits();
+ for (ui32 i = 0; i < numBits; ++i) {
+ str << ((Mask >> (numBits - i - 1)) & 1);
+ }
+ }
+
TString ToString() const {
- TStringStream str;
- Output(str);
- return str.Str();
- }
-
- friend bool operator <(const TDerived& x, const TDerived& y) {
- return x.Mask < y.Mask;
- }
-
- friend bool operator ==(const TDerived& x, const TDerived& y) {
- return x.Mask == y.Mask;
- }
-
- friend bool operator !=(const TDerived& x, const TDerived& y) {
- return x.Mask != y.Mask;
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TSubgroupVDisks -- a class that defines subset of a subgroup for a specific blob; it contains bit mask of set
- // disks that can be used to figure out some properties, e.g. failure model fitness
-
- class TBlobStorageGroupInfo::TSubgroupVDisks
- : public TDomainSetBase<TSubgroupVDisks>
- {
- friend class TDomainSetBase<TSubgroupVDisks>;
-
+ TStringStream str;
+ Output(str);
+ return str.Str();
+ }
+
+ friend bool operator <(const TDerived& x, const TDerived& y) {
+ return x.Mask < y.Mask;
+ }
+
+ friend bool operator ==(const TDerived& x, const TDerived& y) {
+ return x.Mask == y.Mask;
+ }
+
+ friend bool operator !=(const TDerived& x, const TDerived& y) {
+ return x.Mask != y.Mask;
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TSubgroupVDisks -- a class that defines subset of a subgroup for a specific blob; it contains bit mask of set
+ // disks that can be used to figure out some properties, e.g. failure model fitness
+
+ class TBlobStorageGroupInfo::TSubgroupVDisks
+ : public TDomainSetBase<TSubgroupVDisks>
+ {
+ friend class TDomainSetBase<TSubgroupVDisks>;
+
TSubgroupVDisks(const TBlobStorageGroupInfo::TTopology *top, const ui64 *mask)
: TDomainSetBase(top, mask)
- {}
-
- public:
+ {}
+
+ public:
TSubgroupVDisks(const TBlobStorageGroupInfo::TTopology *top)
: TDomainSetBase(top)
- {}
-
- // create a set of subgroup disks containing single disk identified by its sequential number inside subgroup
- // decomposition for specific blob; this number is referred to as "nodeId" in Ingress
+ {}
+
+ // create a set of subgroup disks containing single disk identified by its sequential number inside subgroup
+ // decomposition for specific blob; this number is referred to as "nodeId" in Ingress
TSubgroupVDisks(const TBlobStorageGroupInfo::TTopology *top, ui32 nodeId)
: TDomainSetBase(top, nodeId)
- {}
-
+ {}
+
static TSubgroupVDisks CreateFromMask(const TBlobStorageGroupInfo::TTopology *top, ui64 mask) {
return TSubgroupVDisks(top, &mask);
- }
-
+ }
+
// Get the maximum possible number of disks in set
- ui32 GetNumBits() const {
+ ui32 GetNumBits() const {
return Top->GType.BlobSubgroupSize();
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TGroupVDisks -- a class that stored the set of disks inside the whole group; it's like TSubgroupVDisks, but for
- // the whole group
-
- class TBlobStorageGroupInfo::TGroupVDisks
- : public TDomainSetBase<TGroupVDisks>
- {
- friend class TDomainSetBase<TGroupVDisks>;
- friend class TGroupFailDomains;
-
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TGroupVDisks -- a class that stored the set of disks inside the whole group; it's like TSubgroupVDisks, but for
+ // the whole group
+
+ class TBlobStorageGroupInfo::TGroupVDisks
+ : public TDomainSetBase<TGroupVDisks>
+ {
+ friend class TDomainSetBase<TGroupVDisks>;
+ friend class TGroupFailDomains;
+
TGroupVDisks(const TBlobStorageGroupInfo::TTopology *top, const ui64 *mask)
: TDomainSetBase(top, mask)
- {}
-
- public:
+ {}
+
+ public:
TGroupVDisks(const TBlobStorageGroupInfo::TTopology *top)
: TDomainSetBase(top)
- {}
-
+ {}
+
TGroupVDisks(const TBlobStorageGroupInfo::TTopology *top, const TVDiskIdShort& vdiskId)
: TDomainSetBase(top, top->GetOrderNumber(vdiskId))
- {}
-
+ {}
+
static TGroupVDisks CreateFromMask(const TBlobStorageGroupInfo::TTopology *top, ui64 mask) {
return TGroupVDisks(top, &mask);
- }
-
+ }
+
// Get the maximum possible number of disks in set
- ui32 GetNumBits() const {
+ ui32 GetNumBits() const {
return Top->GetTotalVDisksNum();
- }
- };
-
- class TBlobStorageGroupInfo::TGroupFailDomains
- : public TDomainSetBase<TGroupFailDomains>
- {
- friend class TDomainSetBase<TGroupFailDomains>;
-
- public:
- enum class EDiskCondition {
- ALL, // the domain is selected when ALL disks of this domain are set
- ANY, // the domain is selected when ANY disk of this domain is set
- };
-
- private:
+ }
+ };
+
+ class TBlobStorageGroupInfo::TGroupFailDomains
+ : public TDomainSetBase<TGroupFailDomains>
+ {
+ friend class TDomainSetBase<TGroupFailDomains>;
+
+ public:
+ enum class EDiskCondition {
+ ALL, // the domain is selected when ALL disks of this domain are set
+ ANY, // the domain is selected when ANY disk of this domain is set
+ };
+
+ private:
TGroupFailDomains(const TBlobStorageGroupInfo::TTopology *top, ui32 domainOrderNumber)
: TDomainSetBase(top, domainOrderNumber)
- {}
-
- public:
+ {}
+
+ public:
TGroupFailDomains(const TBlobStorageGroupInfo::TTopology *top)
: TDomainSetBase(top)
- {}
-
- // create a group domain set containing single domain for provided VDisk
+ {}
+
+ // create a group domain set containing single domain for provided VDisk
TGroupFailDomains(const TBlobStorageGroupInfo::TTopology *top, const TVDiskIdShort& vdiskId)
: TDomainSetBase(top, top->GetFailDomainOrderNumber(vdiskId))
- {}
-
- // create a group domain set from the disk set; domain is selected in resulting group if the provided condition
- // triggers for disks of that domain
- static TGroupFailDomains CreateFromGroupDiskSet(const TGroupVDisks& disks, EDiskCondition condition) {
+ {}
+
+ // create a group domain set from the disk set; domain is selected in resulting group if the provided condition
+ // triggers for disks of that domain
+ static TGroupFailDomains CreateFromGroupDiskSet(const TGroupVDisks& disks, EDiskCondition condition) {
const TBlobStorageGroupInfo::TTopology *top = disks.GetTopology();
TGroupFailDomains res(top);
-
+
for (auto domIt = top->FailDomainsBegin(), domEnd = top->FailDomainsEnd(); domIt != domEnd; ++domIt) {
- bool someSet = false;
- bool someNotSet = false;
- for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
+ bool someSet = false;
+ bool someNotSet = false;
+ for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
if (disks & TGroupVDisks(top, top->GetVDiskId(vdisk.OrderNumber))) {
- someSet = true;
- } else {
- someNotSet = true;
- }
- }
- bool match = false;
- switch (condition) {
- case EDiskCondition::ANY:
- match = someSet;
- break;
-
- case EDiskCondition::ALL:
- match = !someNotSet;
- break;
- }
- if (match) {
+ someSet = true;
+ } else {
+ someNotSet = true;
+ }
+ }
+ bool match = false;
+ switch (condition) {
+ case EDiskCondition::ANY:
+ match = someSet;
+ break;
+
+ case EDiskCondition::ALL:
+ match = !someNotSet;
+ break;
+ }
+ if (match) {
res += TGroupFailDomains(top, domIt->FailDomainOrderNumber);
- }
- }
-
- return res;
- }
-
+ }
+ }
+
+ return res;
+ }
+
// Get the maximum possible number of fail domains in set
- ui32 GetNumBits() const {
+ ui32 GetNumBits() const {
return Top->GetTotalFailDomainsNum();
- }
- };
-
-} // NKikimr
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_ut.cpp b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_ut.cpp
index e93d36aaa2c..21aca09938d 100644
--- a/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_ut.cpp
+++ b/ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_ut.cpp
@@ -1,7 +1,7 @@
#include "blobstorage_groupinfo.h"
-#include "blobstorage_groupinfo_iter.h"
-#include "blobstorage_groupinfo_sets.h"
-#include "blobstorage_groupinfo_partlayout.h"
+#include "blobstorage_groupinfo_iter.h"
+#include "blobstorage_groupinfo_sets.h"
+#include "blobstorage_groupinfo_partlayout.h"
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
#include <library/cpp/testing/unittest/registar.h>
@@ -12,237 +12,237 @@ Y_UNIT_TEST_SUITE(TBlobStorageGroupInfoTest) {
Y_UNIT_TEST(TestBelongsToSubgroup) {
for (ui32 disks = 1; disks < 4; ++disks) {
for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
- if (species == TBlobStorageGroupType::ErasureMirror3dc) {
- continue;
- }
-
+ if (species == TBlobStorageGroupType::ErasureMirror3dc) {
+ continue;
+ }
+
const auto erasureType = TErasureType::EErasureSpecies(species);
const ui32 numFailDomains = TBlobStorageGroupType(erasureType).BlobSubgroupSize();
TBlobStorageGroupInfo info(erasureType, disks, numFailDomains);
for (ui32 hashIdx = 0; hashIdx < 1000; ++hashIdx) {
ui32 hash = 640480 + 13 * hashIdx;
- TBlobStorageGroupInfo::TVDiskIds vdiskIds;
+ TBlobStorageGroupInfo::TVDiskIds vdiskIds;
info.PickSubgroup(hash, &vdiskIds, nullptr);
TVector<bool> isMissingDomain;
- auto realm0 = info.FailRealmsBegin();
- isMissingDomain.resize(realm0.GetNumFailDomainsPerFailRealm());
- for (const auto& domain : realm0.GetFailRealmFailDomains()) {
- isMissingDomain[domain.FailDomainOrderNumber] = true;
+ auto realm0 = info.FailRealmsBegin();
+ isMissingDomain.resize(realm0.GetNumFailDomainsPerFailRealm());
+ for (const auto& domain : realm0.GetFailRealmFailDomains()) {
+ isMissingDomain[domain.FailDomainOrderNumber] = true;
}
for (ui32 i = 0; i < vdiskIds.size(); ++i) {
- isMissingDomain[vdiskIds[i].FailDomain] = false;
+ isMissingDomain[vdiskIds[i].FailDomain] = false;
}
- for (auto it = realm0.FailRealmFailDomainsBegin(); it != realm0.FailRealmFailDomainsEnd(); ++it) {
- if (isMissingDomain[it.GetFailDomainIdx()]) {
- ui32 vDisksSz = it.GetNumVDisksPerFailDomain();
+ for (auto it = realm0.FailRealmFailDomainsBegin(); it != realm0.FailRealmFailDomainsEnd(); ++it) {
+ if (isMissingDomain[it.GetFailDomainIdx()]) {
+ ui32 vDisksSz = it.GetNumVDisksPerFailDomain();
for (ui32 vdiskIdx = 0; vdiskIdx < vDisksSz; ++vdiskIdx) {
- TVDiskID id(0, 1, 0, it.GetFailDomainIdx(), vdiskIdx);
- bool isReplica = info.BelongsToSubgroup(id, hash);
+ TVDiskID id(0, 1, 0, it.GetFailDomainIdx(), vdiskIdx);
+ bool isReplica = info.BelongsToSubgroup(id, hash);
UNIT_ASSERT(!isReplica);
}
}
}
for (ui32 i = 0; i < vdiskIds.size(); ++i) {
- ui32 realmIdx = vdiskIds[i].FailRealm;
- ui32 domainIdx = vdiskIds[i].FailDomain;
- for (auto vdiskIt = realm0.FailRealmVDisksBegin(); vdiskIt != realm0.FailRealmVDisksEnd(); ++vdiskIt) {
- if (vdiskIt.GetFailDomainIdx() != domainIdx) {
- continue;
- }
- ui32 vdiskIdx = vdiskIt.GetVDiskIdx();
- TVDiskID id(0, 1, realmIdx, domainIdx, vdiskIdx);
- bool isReplica = info.BelongsToSubgroup(id, hash);
+ ui32 realmIdx = vdiskIds[i].FailRealm;
+ ui32 domainIdx = vdiskIds[i].FailDomain;
+ for (auto vdiskIt = realm0.FailRealmVDisksBegin(); vdiskIt != realm0.FailRealmVDisksEnd(); ++vdiskIt) {
+ if (vdiskIt.GetFailDomainIdx() != domainIdx) {
+ continue;
+ }
+ ui32 vdiskIdx = vdiskIt.GetVDiskIdx();
+ TVDiskID id(0, 1, realmIdx, domainIdx, vdiskIdx);
+ bool isReplica = info.BelongsToSubgroup(id, hash);
UNIT_ASSERT(isReplica == (vdiskIdx == vdiskIds[i].VDisk));
}
}
}
}
}
- }
+ }
Y_UNIT_TEST(SubgroupPartLayout) {
- TLogoBlobID id(1, 1, 1, 0, 100, 0);
-
- for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
- if (species == TBlobStorageGroupType::ErasureMirror3dc || species == TBlobStorageGroupType::ErasureMirror3of4) {
- continue;
- }
-
+ TLogoBlobID id(1, 1, 1, 0, 100, 0);
+
+ for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
+ if (species == TBlobStorageGroupType::ErasureMirror3dc || species == TBlobStorageGroupType::ErasureMirror3of4) {
+ continue;
+ }
+
const auto erasureType = TErasureType::EErasureSpecies(species);
const ui32 numFailDomains = TBlobStorageGroupType(erasureType).BlobSubgroupSize();
TBlobStorageGroupInfo info(erasureType, 1, numFailDomains);
-
- TBlobStorageGroupInfo::TVDiskIds ids;
- info.PickSubgroup(id.Hash(), &ids, nullptr);
-
- const ui32 totalPartCount = info.Type.TotalPartCount();
- const ui32 handoff = info.Type.Handoff();
- const ui32 numHandoff1 = handoff >= 1 ? totalPartCount : 0;
- const ui32 numHandoff2 = handoff >= 2 ? totalPartCount : 0;
-
- for (ui32 main = 0; main < (1U << totalPartCount); ++main) {
- for (ui32 handoff1 = 0; handoff1 < (1U << numHandoff1); ++handoff1) {
- for (ui32 handoff2 = 0; handoff2 < (1U << numHandoff2); ++handoff2) {
- TIngress ingress;
- for (ui32 i = 0; i < totalPartCount; ++i) {
- if (main & (1 << i)) {
+
+ TBlobStorageGroupInfo::TVDiskIds ids;
+ info.PickSubgroup(id.Hash(), &ids, nullptr);
+
+ const ui32 totalPartCount = info.Type.TotalPartCount();
+ const ui32 handoff = info.Type.Handoff();
+ const ui32 numHandoff1 = handoff >= 1 ? totalPartCount : 0;
+ const ui32 numHandoff2 = handoff >= 2 ? totalPartCount : 0;
+
+ for (ui32 main = 0; main < (1U << totalPartCount); ++main) {
+ for (ui32 handoff1 = 0; handoff1 < (1U << numHandoff1); ++handoff1) {
+ for (ui32 handoff2 = 0; handoff2 < (1U << numHandoff2); ++handoff2) {
+ TIngress ingress;
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ if (main & (1 << i)) {
auto iOpt = TIngress::CreateIngressWithLocal(&info.GetTopology(),
ids[i],
TLogoBlobID(id, i + 1));
ingress.Merge(*iOpt);
- }
- if (handoff1 & (1 << i)) {
+ }
+ if (handoff1 & (1 << i)) {
auto iOpt = TIngress::CreateIngressWithLocal(&info.GetTopology(),
ids[totalPartCount],
TLogoBlobID(id, i + 1));
ingress.Merge(*iOpt);
- }
- if (handoff2 & (1 << i)) {
+ }
+ if (handoff2 & (1 << i)) {
auto iOpt = TIngress::CreateIngressWithLocal(&info.GetTopology(),
ids[totalPartCount + 1],
TLogoBlobID(id, i + 1));
ingress.Merge(*iOpt);
- }
- }
- TSubgroupPartLayout layout;
- for (ui32 i = 0; i < totalPartCount; ++i) {
- if (main & (1 << i)) {
+ }
+ }
+ TSubgroupPartLayout layout;
+ for (ui32 i = 0; i < totalPartCount; ++i) {
+ if (main & (1 << i)) {
layout.AddItem(i, i, info.Type);
- }
- if (handoff1 & (1 << i)) {
+ }
+ if (handoff1 & (1 << i)) {
layout.AddItem(totalPartCount, i, info.Type);
- }
- if (handoff2 & (1 << i)) {
+ }
+ if (handoff2 & (1 << i)) {
layout.AddItem(totalPartCount + 1, i, info.Type);
- }
- }
-
+ }
+ }
+
UNIT_ASSERT_EQUAL(layout, TSubgroupPartLayout::CreateFromIngress(ingress, info.Type));
-
-// Cerr << "main# " << main << " hanoff1# " << handoff1 << " handoff2# " << handoff2 << " num# " << num << " num2# " << num2 << Endl;
- }
- }
- }
- }
+
+// Cerr << "main# " << main << " hanoff1# " << handoff1 << " handoff2# " << handoff2 << " num# " << num << " num2# " << num2 << Endl;
+ }
+ }
+ }
+ }
}
-
+
Y_UNIT_TEST(GroupQuorumCheckerOrdinary) {
- for (ui32 i = 0; i < TBlobStorageGroupType::ErasureSpeciesCount; ++i) {
- auto erasure = static_cast<TBlobStorageGroupType::EErasureSpecies>(i);
- if (erasure == TBlobStorageGroupType::ErasureMirror3dc || erasure == TBlobStorageGroupType::ErasureMirror3of4) {
- // separate test for mirror-3-dc
- continue;
- }
-
- const ui32 numFailDomains = 10;
- const ui32 numVDisks = 3;
- TBlobStorageGroupInfo info(erasure, numVDisks, numFailDomains);
-
- // calculate number of handoff disks
- const ui32 numHandoff = info.Type.Handoff();
- const ui32 numMasks = 1U << numFailDomains;
-
- // calculate sets of disks
+ for (ui32 i = 0; i < TBlobStorageGroupType::ErasureSpeciesCount; ++i) {
+ auto erasure = static_cast<TBlobStorageGroupType::EErasureSpecies>(i);
+ if (erasure == TBlobStorageGroupType::ErasureMirror3dc || erasure == TBlobStorageGroupType::ErasureMirror3of4) {
+ // separate test for mirror-3-dc
+ continue;
+ }
+
+ const ui32 numFailDomains = 10;
+ const ui32 numVDisks = 3;
+ TBlobStorageGroupInfo info(erasure, numVDisks, numFailDomains);
+
+ // calculate number of handoff disks
+ const ui32 numHandoff = info.Type.Handoff();
+ const ui32 numMasks = 1U << numFailDomains;
+
+ // calculate sets of disks
TVector<ui32> goodMask, badMask;
- for (ui32 mask = 0; mask < numMasks; ++mask) {
- (PopCount(mask) <= numHandoff ? goodMask : badMask).push_back(mask);
- }
-
- auto createGroupVDisks = [&](ui32 domainMask, ui32 vdiskMask) {
+ for (ui32 mask = 0; mask < numMasks; ++mask) {
+ (PopCount(mask) <= numHandoff ? goodMask : badMask).push_back(mask);
+ }
+
+ auto createGroupVDisks = [&](ui32 domainMask, ui32 vdiskMask) {
TBlobStorageGroupInfo::TGroupVDisks vdisks(&info.GetTopology());
- for (const auto& vdisk : info.GetVDisks()) {
+ for (const auto& vdisk : info.GetVDisks()) {
if (((domainMask >> vdisk.FailDomainOrderNumber) & 1) && ((vdiskMask >> vdisk.VDiskIdShort.VDisk) & 1)) {
auto vd = info.GetVDiskId(vdisk.OrderNumber);
vdisks += TBlobStorageGroupInfo::TGroupVDisks(&info.GetTopology(), vd);
- }
- }
- return vdisks;
- };
-
- const auto& checker = info.GetQuorumChecker();
- for (ui32 vdiskMask = 1; vdiskMask < (1U << numVDisks); ++vdiskMask) {
- for (ui32 domainMask : goodMask) {
- UNIT_ASSERT(checker.CheckQuorumForGroup(~createGroupVDisks(domainMask, vdiskMask)));
- }
- for (ui32 domainMask : badMask) {
- UNIT_ASSERT(!checker.CheckQuorumForGroup(~createGroupVDisks(domainMask, vdiskMask)));
- }
- }
- }
- }
-
+ }
+ }
+ return vdisks;
+ };
+
+ const auto& checker = info.GetQuorumChecker();
+ for (ui32 vdiskMask = 1; vdiskMask < (1U << numVDisks); ++vdiskMask) {
+ for (ui32 domainMask : goodMask) {
+ UNIT_ASSERT(checker.CheckQuorumForGroup(~createGroupVDisks(domainMask, vdiskMask)));
+ }
+ for (ui32 domainMask : badMask) {
+ UNIT_ASSERT(!checker.CheckQuorumForGroup(~createGroupVDisks(domainMask, vdiskMask)));
+ }
+ }
+ }
+ }
+
Y_UNIT_TEST(GroupQuorumCheckerMirror3dc) {
- const ui32 numFailRealms = 3;
- const ui32 numFailDomains = 4;
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 1, numFailDomains, numFailRealms);
-
- auto domainMask = [&](ui32 realm, ui32 domain) {
- return 1U << (realm * numFailDomains + domain);
- };
-
+ const ui32 numFailRealms = 3;
+ const ui32 numFailDomains = 4;
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 1, numFailDomains, numFailRealms);
+
+ auto domainMask = [&](ui32 realm, ui32 domain) {
+ return 1U << (realm * numFailDomains + domain);
+ };
+
TVector<ui32> goodMask;
-
- goodMask.push_back(0);
-
- for (ui32 realm = 0; realm < numFailRealms; ++realm) {
- for (ui32 mask = 1; mask < (1U << numFailDomains); ++mask) {
- // first, create failed domains mask for a single fail realm, iterating through all possible options
- // for failed fail domains
- ui32 domMask = 0;
- for (ui32 i = 0; i < numFailDomains; ++i) {
- if ((mask >> i) & 1) {
- domMask |= domainMask(realm, i);
- }
- }
-
- // push that mask to good ones
- goodMask.push_back(domMask);
-
- // now iterate through all other realms (not including current one) and add one more failed fail domain
- // to the common mask
- for (ui32 i = 0; i < numFailRealms; ++i) {
- if (i != realm) {
- for (ui32 j = 0; j < numFailDomains; ++j) {
- goodMask.push_back(domMask | domainMask(i, j));
- }
- }
- }
- }
- }
-
- // sort options
- std::sort(goodMask.begin(), goodMask.end());
-
- // create bad mask
+
+ goodMask.push_back(0);
+
+ for (ui32 realm = 0; realm < numFailRealms; ++realm) {
+ for (ui32 mask = 1; mask < (1U << numFailDomains); ++mask) {
+ // first, create failed domains mask for a single fail realm, iterating through all possible options
+ // for failed fail domains
+ ui32 domMask = 0;
+ for (ui32 i = 0; i < numFailDomains; ++i) {
+ if ((mask >> i) & 1) {
+ domMask |= domainMask(realm, i);
+ }
+ }
+
+ // push that mask to good ones
+ goodMask.push_back(domMask);
+
+ // now iterate through all other realms (not including current one) and add one more failed fail domain
+ // to the common mask
+ for (ui32 i = 0; i < numFailRealms; ++i) {
+ if (i != realm) {
+ for (ui32 j = 0; j < numFailDomains; ++j) {
+ goodMask.push_back(domMask | domainMask(i, j));
+ }
+ }
+ }
+ }
+ }
+
+ // sort options
+ std::sort(goodMask.begin(), goodMask.end());
+
+ // create bad mask
TVector<ui32> allMasks;
- for (ui32 i = 0; i < (1U << (numFailRealms * numFailDomains)); ++i) {
- allMasks.push_back(i);
- }
-
+ for (ui32 i = 0; i < (1U << (numFailRealms * numFailDomains)); ++i) {
+ allMasks.push_back(i);
+ }
+
TVector<ui32> badMask;
- std::set_difference(allMasks.begin(), allMasks.end(), goodMask.begin(), goodMask.end(), std::back_inserter(badMask));
-
- auto createGroupVDisks = [&](ui32 domainMask) {
+ std::set_difference(allMasks.begin(), allMasks.end(), goodMask.begin(), goodMask.end(), std::back_inserter(badMask));
+
+ auto createGroupVDisks = [&](ui32 domainMask) {
TBlobStorageGroupInfo::TGroupVDisks vdisks(&info.GetTopology());
- for (const auto& vdisk : info.GetVDisks()) {
- if ((domainMask >> vdisk.FailDomainOrderNumber) & 1) {
+ for (const auto& vdisk : info.GetVDisks()) {
+ if ((domainMask >> vdisk.FailDomainOrderNumber) & 1) {
auto vd = info.GetVDiskId(vdisk.OrderNumber);
vdisks += TBlobStorageGroupInfo::TGroupVDisks(&info.GetTopology(), vd);
- }
- }
- return vdisks;
- };
-
- const auto& checker = info.GetQuorumChecker();
- for (ui32 domainMask : goodMask) {
- UNIT_ASSERT(checker.CheckQuorumForGroup(~createGroupVDisks(domainMask)));
- }
- for (ui32 domainMask : badMask) {
- UNIT_ASSERT(!checker.CheckQuorumForGroup(~createGroupVDisks(domainMask)));
- }
- }
+ }
+ }
+ return vdisks;
+ };
+
+ const auto& checker = info.GetQuorumChecker();
+ for (ui32 domainMask : goodMask) {
+ UNIT_ASSERT(checker.CheckQuorumForGroup(~createGroupVDisks(domainMask)));
+ }
+ for (ui32 domainMask : badMask) {
+ UNIT_ASSERT(!checker.CheckQuorumForGroup(~createGroupVDisks(domainMask)));
+ }
+ }
}
} // namespace NKikimr
diff --git a/ydb/core/blobstorage/groupinfo/defs.h b/ydb/core/blobstorage/groupinfo/defs.h
index 27a0a205e50..2dad8cff0bf 100644
--- a/ydb/core/blobstorage/groupinfo/defs.h
+++ b/ydb/core/blobstorage/groupinfo/defs.h
@@ -1,5 +1,5 @@
#pragma once
// unique tag to fix pragma once gcc glueing: ./ydb/core/blobstorage/groupinfo/defs.h
#include <ydb/core/blobstorage/defs.h>
-#include <library/cpp/pop_count/popcount.h>
-#include <util/string/escape.h>
+#include <library/cpp/pop_count/popcount.h>
+#include <util/string/escape.h>
diff --git a/ydb/core/blobstorage/incrhuge/defs.h b/ydb/core/blobstorage/incrhuge/defs.h
index 9af83856597..6ab2f265c02 100644
--- a/ydb/core/blobstorage/incrhuge/defs.h
+++ b/ydb/core/blobstorage/incrhuge/defs.h
@@ -1,61 +1,61 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/defs.h>
-
-#define INCRHUGE_HARDENED 1
-
-namespace NKikimr {
- namespace NIncrHuge {
- using TIncrHugeBlobId = ui64;
-
+
+#define INCRHUGE_HARDENED 1
+
+namespace NKikimr {
+ namespace NIncrHuge {
+ using TIncrHugeBlobId = ui64;
+
#pragma pack(push,1)
- // Huge blob metadata -- universal nontransparent structure that is stored along with blob's data and returned
- // on read/init requests.
- union TBlobMetadata {
- ui8 Raw[32];
- ui64 RawU64[4];
- };
-
- class TChunkSerNum {
- ui64 Value;
-
- public:
- TChunkSerNum()
- : Value(-1)
- {}
-
- explicit TChunkSerNum(ui64 value)
- : Value(value)
- {}
-
- void Advance(ui64 shift) {
- Value += shift;
- }
-
- TChunkSerNum Add(ui64 shift) const {
- return TChunkSerNum(Value + shift);
- }
-
+ // Huge blob metadata -- universal nontransparent structure that is stored along with blob's data and returned
+ // on read/init requests.
+ union TBlobMetadata {
+ ui8 Raw[32];
+ ui64 RawU64[4];
+ };
+
+ class TChunkSerNum {
+ ui64 Value;
+
+ public:
+ TChunkSerNum()
+ : Value(-1)
+ {}
+
+ explicit TChunkSerNum(ui64 value)
+ : Value(value)
+ {}
+
+ void Advance(ui64 shift) {
+ Value += shift;
+ }
+
+ TChunkSerNum Add(ui64 shift) const {
+ return TChunkSerNum(Value + shift);
+ }
+
TString ToString() const {
- return Sprintf("%" PRIu64, Value);
- }
-
- explicit operator ui64() const {
- return Value;
- }
-
- friend bool operator ==(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value == y.Value; }
- friend bool operator !=(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value != y.Value; }
- friend bool operator <(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value < y.Value; }
- };
+ return Sprintf("%" PRIu64, Value);
+ }
+
+ explicit operator ui64() const {
+ return Value;
+ }
+
+ friend bool operator ==(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value == y.Value; }
+ friend bool operator !=(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value != y.Value; }
+ friend bool operator <(const TChunkSerNum& x, const TChunkSerNum& y) { return x.Value < y.Value; }
+ };
#pragma pack(pop)
- } // NIncrHuge
-} // NKikimr
-
-template<>
-struct THash<NKikimr::NIncrHuge::TChunkSerNum> : THash<ui64> {
- size_t operator ()(const NKikimr::NIncrHuge::TChunkSerNum& chunkSerNum) const noexcept {
- return THash<ui64>::operator ()(static_cast<ui64>(chunkSerNum));
- }
-};
+ } // NIncrHuge
+} // NKikimr
+
+template<>
+struct THash<NKikimr::NIncrHuge::TChunkSerNum> : THash<ui64> {
+ size_t operator ()(const NKikimr::NIncrHuge::TChunkSerNum& chunkSerNum) const noexcept {
+ return THash<ui64>::operator ()(static_cast<ui64>(chunkSerNum));
+ }
+};
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge.h b/ydb/core/blobstorage/incrhuge/incrhuge.h
index c2f5848e72e..f1c06d3222b 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge.h
@@ -1,201 +1,201 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+
#include <ydb/core/base/blobstorage.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDISK <-> INCREMENTAL HUGE BLOB KEEPER INTERFACE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // NOTICE: for every request message TEvX there is only single response TEvXResult, containing operation status;
- // one can rely on actual operation execution ONLY if returned status indicates success. To match requests with
- // responses user can use Cookie field in IEventHolder class -- it is copied from request to response for every
- // type of query incremental huge blob keeper provides.
-
- // TEvIncrHugeInit message is sent from VDisk to incremental huge blob keeper to obtain its personal identifier
- // (owner), which is used in further operations. This 'Owner' is different from the owner obtained from PDisk.
- struct TEvIncrHugeInit : public NActors::TEventLocal<TEvIncrHugeInit, TEvBlobStorage::EvIncrHugeInit> {
- TVDiskID VDiskId; // VDisk identifier that uniquely identifies VDisk on this keeper
- ui8 Owner; // owner id for this VDisk on underlying PDisk
- ui64 FirstLsn; // first LSN that is expected to appear in returned list of blobs
-
- TEvIncrHugeInit(const TVDiskID& vdiskId, ui8 owner, ui64 firstLsn)
- : VDiskId(vdiskId)
- , Owner(owner)
- , FirstLsn(firstLsn)
- {}
- };
-
- // TEvIncrHugeInitResult is sent in response to TEvIncrHugeInit message and contains status indicating whether
- // operation was carried out successfully, Owner to provide in following requests and a vector of blobs sorted
- // by LSN contaning metadata. This vector is used in recovery of VDisk as it doesn't log incremental huge blob
- // writes to its own log, but it needs to reproduce them at recovery to fill in fresh chunk and generate sync
- // log data.
- struct TEvIncrHugeInitResult : public NActors::TEventLocal<TEvIncrHugeInitResult, TEvBlobStorage::EvIncrHugeInitResult> {
- struct TItem {
- TIncrHugeBlobId Id; // blob identifier in space of incremental huge blob keeper
- ui64 Lsn; // LSN of this blob, provided by VDisk when writing this blob
- TBlobMetadata Meta; // no comments :)
- };
-
- NKikimrProto::EReplyStatus Status; // operation status
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDISK <-> INCREMENTAL HUGE BLOB KEEPER INTERFACE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // NOTICE: for every request message TEvX there is only single response TEvXResult, containing operation status;
+ // one can rely on actual operation execution ONLY if returned status indicates success. To match requests with
+ // responses user can use Cookie field in IEventHolder class -- it is copied from request to response for every
+ // type of query incremental huge blob keeper provides.
+
+ // TEvIncrHugeInit message is sent from VDisk to incremental huge blob keeper to obtain its personal identifier
+ // (owner), which is used in further operations. This 'Owner' is different from the owner obtained from PDisk.
+ struct TEvIncrHugeInit : public NActors::TEventLocal<TEvIncrHugeInit, TEvBlobStorage::EvIncrHugeInit> {
+ TVDiskID VDiskId; // VDisk identifier that uniquely identifies VDisk on this keeper
+ ui8 Owner; // owner id for this VDisk on underlying PDisk
+ ui64 FirstLsn; // first LSN that is expected to appear in returned list of blobs
+
+ TEvIncrHugeInit(const TVDiskID& vdiskId, ui8 owner, ui64 firstLsn)
+ : VDiskId(vdiskId)
+ , Owner(owner)
+ , FirstLsn(firstLsn)
+ {}
+ };
+
+ // TEvIncrHugeInitResult is sent in response to TEvIncrHugeInit message and contains status indicating whether
+ // operation was carried out successfully, Owner to provide in following requests and a vector of blobs sorted
+ // by LSN contaning metadata. This vector is used in recovery of VDisk as it doesn't log incremental huge blob
+ // writes to its own log, but it needs to reproduce them at recovery to fill in fresh chunk and generate sync
+ // log data.
+ struct TEvIncrHugeInitResult : public NActors::TEventLocal<TEvIncrHugeInitResult, TEvBlobStorage::EvIncrHugeInitResult> {
+ struct TItem {
+ TIncrHugeBlobId Id; // blob identifier in space of incremental huge blob keeper
+ ui64 Lsn; // LSN of this blob, provided by VDisk when writing this blob
+ TBlobMetadata Meta; // no comments :)
+ };
+
+ NKikimrProto::EReplyStatus Status; // operation status
TVector<TItem> Items; // a vector of items with matching LSN's
-
+
TEvIncrHugeInitResult(NKikimrProto::EReplyStatus status, TVector<TItem>&& items)
- : Status(status)
- , Items(std::move(items))
- {}
- };
-
- // TWritePayload structure contains user fields needed by VDisk when receiving write confirmation. It is
- // simply moved from request to response.
+ : Status(status)
+ , Items(std::move(items))
+ {}
+ };
+
+ // TWritePayload structure contains user fields needed by VDisk when receiving write confirmation. It is
+ // simply moved from request to response.
struct TWritePayload {
- virtual ~TWritePayload() = default;
- };
-
- using TWritePayloadPtr = std::unique_ptr<TWritePayload>;
-
- // TEvIncrHugeWrite -- write new blob. Incremental huge blob keeper allocates an identifier (TIncrHugeBlobId)
- // and writes provided data and metadata into storage. We have to mention that identifiers are reused if being
- // deleted, so, if there is a race between delete and write request, write may return identifier just deleted,
- // but with new content. Example: client sends write and gets identifier A. Then client sends delete A and write
- // other blob. If there is a race between write and delete inside keeper (which of them is executed first), then
- // keeper may return A for just written blob and then return success for deletion. It is normal situation. Also
- // this operation doesn't write to log and while huge blob keeper receives only writes (excluding reads and
- // deletes), it maintains strictly sequential disk write requests, this achieving maximum performance.
- struct TEvIncrHugeWrite : public NActors::TEventLocal<TEvIncrHugeWrite, TEvBlobStorage::EvIncrHugeWrite> {
- ui8 Owner; // the VDisk who writes the data
- ui64 Lsn; // non-transparent number from owner; compared to FirstLsn on init
- TBlobMetadata Meta; // non-transparent blob metadata
+ virtual ~TWritePayload() = default;
+ };
+
+ using TWritePayloadPtr = std::unique_ptr<TWritePayload>;
+
+ // TEvIncrHugeWrite -- write new blob. Incremental huge blob keeper allocates an identifier (TIncrHugeBlobId)
+ // and writes provided data and metadata into storage. We have to mention that identifiers are reused if being
+ // deleted, so, if there is a race between delete and write request, write may return identifier just deleted,
+ // but with new content. Example: client sends write and gets identifier A. Then client sends delete A and write
+ // other blob. If there is a race between write and delete inside keeper (which of them is executed first), then
+ // keeper may return A for just written blob and then return success for deletion. It is normal situation. Also
+ // this operation doesn't write to log and while huge blob keeper receives only writes (excluding reads and
+ // deletes), it maintains strictly sequential disk write requests, this achieving maximum performance.
+ struct TEvIncrHugeWrite : public NActors::TEventLocal<TEvIncrHugeWrite, TEvBlobStorage::EvIncrHugeWrite> {
+ ui8 Owner; // the VDisk who writes the data
+ ui64 Lsn; // non-transparent number from owner; compared to FirstLsn on init
+ TBlobMetadata Meta; // non-transparent blob metadata
TString Data; // buffer with payload; should not be less that minimal blob size
- TWritePayloadPtr Payload; // structure that is moved from request to response
-
+ TWritePayloadPtr Payload; // structure that is moved from request to response
+
TEvIncrHugeWrite(ui8 owner, ui64 lsn, const TBlobMetadata& meta, TString&& data, TWritePayloadPtr&& payload)
- : Owner(owner)
- , Lsn(lsn)
- , Meta(meta)
- , Data(std::move(data))
- , Payload(std::move(payload))
- {}
- };
-
- // TEvIncrHugeWriteResult is sent in response to successful (or unsuccessful) writing of blob. It contains
- // some metadata from request (including TWritePayload) and identifier of just written blob (in case of success).
- struct TEvIncrHugeWriteResult : public NActors::TEventLocal<TEvIncrHugeWriteResult,
- TEvBlobStorage::EvIncrHugeWriteResult> {
- NKikimrProto::EReplyStatus Status; // operation status
- TIncrHugeBlobId Id; // identifier of just written blob in case of success
- TWritePayloadPtr Payload; // field moved from request
-
- TEvIncrHugeWriteResult(NKikimrProto::EReplyStatus status, TIncrHugeBlobId id, TWritePayloadPtr&& payload)
- : Status(status)
- , Id(id)
- , Payload(std::move(payload))
- {}
- };
-
- // TEvIncrHugeRead request is sent from VDisk to read previously written blob. User should provide correct and
- // existing blob id, otherwise system will crash on Y_VERIFY (because VDisk's database became inconsistent).
- // If Size field is zero, then blob is read up to end starting at Offset.
- struct TEvIncrHugeRead : public NActors::TEventLocal<TEvIncrHugeRead, TEvBlobStorage::EvIncrHugeRead> {
- ui8 Owner; // the owner who wants to read the data
- TIncrHugeBlobId Id; // identifier of blob being read
- ui32 Offset; // offset inside blob in bytes
- ui32 Size; // size to read; if set to zero, then blob is read up to end (starting at offset)
-
- TEvIncrHugeRead(ui8 owner, TIncrHugeBlobId id, ui32 offset, ui32 size)
- : Owner(owner)
- , Id(id)
- , Offset(offset)
- , Size(size)
- {}
- };
-
- // TEvIncrHugeReadResult contains result of reading blob -- status and payload (in case of success). Payload
- // contains only requested part of blob.
- struct TEvIncrHugeReadResult : public NActors::TEventLocal<TEvIncrHugeReadResult, TEvBlobStorage::EvIncrHugeReadResult> {
- NKikimrProto::EReplyStatus Status; // operation status
+ : Owner(owner)
+ , Lsn(lsn)
+ , Meta(meta)
+ , Data(std::move(data))
+ , Payload(std::move(payload))
+ {}
+ };
+
+ // TEvIncrHugeWriteResult is sent in response to successful (or unsuccessful) writing of blob. It contains
+ // some metadata from request (including TWritePayload) and identifier of just written blob (in case of success).
+ struct TEvIncrHugeWriteResult : public NActors::TEventLocal<TEvIncrHugeWriteResult,
+ TEvBlobStorage::EvIncrHugeWriteResult> {
+ NKikimrProto::EReplyStatus Status; // operation status
+ TIncrHugeBlobId Id; // identifier of just written blob in case of success
+ TWritePayloadPtr Payload; // field moved from request
+
+ TEvIncrHugeWriteResult(NKikimrProto::EReplyStatus status, TIncrHugeBlobId id, TWritePayloadPtr&& payload)
+ : Status(status)
+ , Id(id)
+ , Payload(std::move(payload))
+ {}
+ };
+
+ // TEvIncrHugeRead request is sent from VDisk to read previously written blob. User should provide correct and
+ // existing blob id, otherwise system will crash on Y_VERIFY (because VDisk's database became inconsistent).
+ // If Size field is zero, then blob is read up to end starting at Offset.
+ struct TEvIncrHugeRead : public NActors::TEventLocal<TEvIncrHugeRead, TEvBlobStorage::EvIncrHugeRead> {
+ ui8 Owner; // the owner who wants to read the data
+ TIncrHugeBlobId Id; // identifier of blob being read
+ ui32 Offset; // offset inside blob in bytes
+ ui32 Size; // size to read; if set to zero, then blob is read up to end (starting at offset)
+
+ TEvIncrHugeRead(ui8 owner, TIncrHugeBlobId id, ui32 offset, ui32 size)
+ : Owner(owner)
+ , Id(id)
+ , Offset(offset)
+ , Size(size)
+ {}
+ };
+
+ // TEvIncrHugeReadResult contains result of reading blob -- status and payload (in case of success). Payload
+ // contains only requested part of blob.
+ struct TEvIncrHugeReadResult : public NActors::TEventLocal<TEvIncrHugeReadResult, TEvBlobStorage::EvIncrHugeReadResult> {
+ NKikimrProto::EReplyStatus Status; // operation status
TString Data; // requested blob data range
-
+
TEvIncrHugeReadResult(NKikimrProto::EReplyStatus status, TString&& data)
- : Status(status)
- , Data(std::move(data))
- {}
- };
-
- // TEvIncrHugeDelete is sent by VDisk to delete unused blob(s). Usually this happens while compacting, but there
- // is no general limit to use this operation. Upon receiving, it generates a log record containing some metadata
- // of deleted blobs, so then this operation is called frequently, it degrades performance of whole system as it
- // starts using log. There is a special identifier -- sequence number -- that is used to prevent repetition of
- // the same operation (e.g. when VDisk issues delete request, then fails and during log replay it issues the
- // same request). It is the responsibility of client to ensure that delete request completes successfully on
- // system failure and further recovery. For example, after compaction, when VDisk writes entrypoint with new
- // SST set and deleted blobs, it should not write next entrypoint of this type until deletion succeeds, nor
- // advance FirstLsnToKeep.
- struct TEvIncrHugeDelete : public NActors::TEventLocal<TEvIncrHugeDelete, TEvBlobStorage::EvIncrHugeDelete> {
- ui8 Owner; // owner who wants to delete the data
- ui64 SeqNo; // sequence number; should increase for each query from the same client
+ : Status(status)
+ , Data(std::move(data))
+ {}
+ };
+
+ // TEvIncrHugeDelete is sent by VDisk to delete unused blob(s). Usually this happens while compacting, but there
+ // is no general limit to use this operation. Upon receiving, it generates a log record containing some metadata
+ // of deleted blobs, so then this operation is called frequently, it degrades performance of whole system as it
+ // starts using log. There is a special identifier -- sequence number -- that is used to prevent repetition of
+ // the same operation (e.g. when VDisk issues delete request, then fails and during log replay it issues the
+ // same request). It is the responsibility of client to ensure that delete request completes successfully on
+ // system failure and further recovery. For example, after compaction, when VDisk writes entrypoint with new
+ // SST set and deleted blobs, it should not write next entrypoint of this type until deletion succeeds, nor
+ // advance FirstLsnToKeep.
+ struct TEvIncrHugeDelete : public NActors::TEventLocal<TEvIncrHugeDelete, TEvBlobStorage::EvIncrHugeDelete> {
+ ui8 Owner; // owner who wants to delete the data
+ ui64 SeqNo; // sequence number; should increase for each query from the same client
TVector<TIncrHugeBlobId> Ids; // a vector of blobs user wants to delete
-
+
TEvIncrHugeDelete(ui8 owner, ui64 seqNo, TVector<TIncrHugeBlobId>&& ids)
- : Owner(owner)
- , SeqNo(seqNo)
- , Ids(std::move(ids))
- {}
- };
-
- // TEvIncrHugeDeleteResult is sent in response to TEvIncrHugeDelete query. Contains just status.
- struct TEvIncrHugeDeleteResult : public NActors::TEventLocal<TEvIncrHugeDeleteResult, TEvBlobStorage::EvIncrHugeDeleteResult> {
- NKikimrProto::EReplyStatus Status; // operation status
-
- TEvIncrHugeDeleteResult(NKikimrProto::EReplyStatus status)
- : Status(status)
- {}
- };
-
- // TEvIncrHugeHarakiri is sent by client to indicate that is wants to destroy all its data inside this keeper
- // and cease functioning. FIXME: not implemented yet
- struct TEvIncrHugeHarakiri : public NActors::TEventLocal<TEvIncrHugeHarakiri, TEvBlobStorage::EvIncrHugeHarakiri> {
- ui8 Owner;
- };
-
- // TEvIncrHugeHarakiriResult is sent in response to TEvIncrHugeHarakiri.
- struct TEvIncrHugeHarakiriResult : public NActors::TEventLocal<TEvIncrHugeHarakiriResult, TEvBlobStorage::EvIncrHugeHarakiriResult> {
- NKikimrProto::EReplyStatus Status; // operation status
- };
-
- // TEvIncrHugeControlDefrag is used in tests and controls defragmenter threshold. FIXME: remove?
- struct TEvIncrHugeControlDefrag : public NActors::TEventLocal<TEvIncrHugeControlDefrag, TEvBlobStorage::EvIncrHugeControlDefrag> {
- double Threshold;
-
- TEvIncrHugeControlDefrag(double threshold)
- : Threshold(threshold)
- {}
- };
-
- // helper function used to construct incremental huge blob keeper's actod id on a local pdisk with specific
- // identifier
+ : Owner(owner)
+ , SeqNo(seqNo)
+ , Ids(std::move(ids))
+ {}
+ };
+
+ // TEvIncrHugeDeleteResult is sent in response to TEvIncrHugeDelete query. Contains just status.
+ struct TEvIncrHugeDeleteResult : public NActors::TEventLocal<TEvIncrHugeDeleteResult, TEvBlobStorage::EvIncrHugeDeleteResult> {
+ NKikimrProto::EReplyStatus Status; // operation status
+
+ TEvIncrHugeDeleteResult(NKikimrProto::EReplyStatus status)
+ : Status(status)
+ {}
+ };
+
+ // TEvIncrHugeHarakiri is sent by client to indicate that is wants to destroy all its data inside this keeper
+ // and cease functioning. FIXME: not implemented yet
+ struct TEvIncrHugeHarakiri : public NActors::TEventLocal<TEvIncrHugeHarakiri, TEvBlobStorage::EvIncrHugeHarakiri> {
+ ui8 Owner;
+ };
+
+ // TEvIncrHugeHarakiriResult is sent in response to TEvIncrHugeHarakiri.
+ struct TEvIncrHugeHarakiriResult : public NActors::TEventLocal<TEvIncrHugeHarakiriResult, TEvBlobStorage::EvIncrHugeHarakiriResult> {
+ NKikimrProto::EReplyStatus Status; // operation status
+ };
+
+ // TEvIncrHugeControlDefrag is used in tests and controls defragmenter threshold. FIXME: remove?
+ struct TEvIncrHugeControlDefrag : public NActors::TEventLocal<TEvIncrHugeControlDefrag, TEvBlobStorage::EvIncrHugeControlDefrag> {
+ double Threshold;
+
+ TEvIncrHugeControlDefrag(double threshold)
+ : Threshold(threshold)
+ {}
+ };
+
+ // helper function used to construct incremental huge blob keeper's actod id on a local pdisk with specific
+ // identifier
inline NActors::TActorId MakeIncrHugeKeeperId(ui32 pdiskId) {
- char x[12] = {'b', 's', 'I', 'n', 'c', 'r', 'H', 'K', 0, 0, 0, 0};
- x[8] = pdiskId;
- x[9] = pdiskId >> 8;
- x[10] = pdiskId >> 16;
- x[11] = pdiskId >> 24;
+ char x[12] = {'b', 's', 'I', 'n', 'c', 'r', 'H', 'K', 0, 0, 0, 0};
+ x[8] = pdiskId;
+ x[9] = pdiskId >> 8;
+ x[10] = pdiskId >> 16;
+ x[11] = pdiskId >> 24;
return NActors::TActorId(0, TStringBuf(x, 12));
- }
-
+ }
+
inline ui32 PDiskIdFromIncrHugeKeeperId(const TActorId& keeperId) {
- ui64 raw2 = keeperId.RawX2();
- Y_VERIFY(raw2 < (ui64(1) << 32));
- ui32 pdiskId = raw2;
- Y_VERIFY_DEBUG(keeperId == MakeIncrHugeKeeperId(pdiskId));
- return pdiskId;
- }
-
- } // NIncrHuge
-} // NKikimr
+ ui64 raw2 = keeperId.RawX2();
+ Y_VERIFY(raw2 < (ui64(1) << 32));
+ ui32 pdiskId = raw2;
+ Y_VERIFY_DEBUG(keeperId == MakeIncrHugeKeeperId(pdiskId));
+ return pdiskId;
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_data.h b/ydb/core/blobstorage/incrhuge/incrhuge_data.h
index d1a1318bce6..e449d5baefc 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_data.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_data.h
@@ -1,54 +1,54 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
-#pragma pack(push, 1)
- struct TBlobIndexRecord {
- ui64 Id; // raw TIncrHugeBlobId
- ui64 Lsn; // Owner's LSN
- TBlobMetadata Meta; // non-transparent owner metadata
- ui32 PayloadSize : 24; // size of payload in bytes
- ui32 Owner : 8; // blob owner
-
- friend bool operator ==(const TBlobIndexRecord& left, const TBlobIndexRecord& right) {
- return memcmp(&left, &right, sizeof(TBlobIndexRecord)) == 0;
- }
-
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+#pragma pack(push, 1)
+ struct TBlobIndexRecord {
+ ui64 Id; // raw TIncrHugeBlobId
+ ui64 Lsn; // Owner's LSN
+ TBlobMetadata Meta; // non-transparent owner metadata
+ ui32 PayloadSize : 24; // size of payload in bytes
+ ui32 Owner : 8; // blob owner
+
+ friend bool operator ==(const TBlobIndexRecord& left, const TBlobIndexRecord& right) {
+ return memcmp(&left, &right, sizeof(TBlobIndexRecord)) == 0;
+ }
+
TString ToString() const {
- return Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 " PayloadSize# %" PRIu32 " Owner# %" PRIu32 "}",
- Id, Lsn, PayloadSize, Owner);
- }
- };
-
- struct TBlobIndexHeader {
- ui32 Checksum; // checksum (CRC32C) of TBlobIndexHeader + data
- TChunkSerNum ChunkSerNum; // unique serial number of chunk this index header was written to
- ui32 NumItems; // number of records in Index[]
-
- const TBlobIndexRecord *InplaceIndexBegin() const {
- return reinterpret_cast<const TBlobIndexRecord *>(this + 1);
- }
-
- const TBlobIndexRecord *InplaceIndexEnd() const {
- return InplaceIndexBegin() + NumItems;
- }
- };
-
- struct TBlobHeader {
- ui32 Checksum; // checksum (CRC32C) of TBlobHeader + data, not including checksum
- TBlobIndexRecord IndexRecord; // index record for this blob
- TChunkSerNum ChunkSerNum; // unique serial number of chunk this blob was written to
-
+ return Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 " PayloadSize# %" PRIu32 " Owner# %" PRIu32 "}",
+ Id, Lsn, PayloadSize, Owner);
+ }
+ };
+
+ struct TBlobIndexHeader {
+ ui32 Checksum; // checksum (CRC32C) of TBlobIndexHeader + data
+ TChunkSerNum ChunkSerNum; // unique serial number of chunk this index header was written to
+ ui32 NumItems; // number of records in Index[]
+
+ const TBlobIndexRecord *InplaceIndexBegin() const {
+ return reinterpret_cast<const TBlobIndexRecord *>(this + 1);
+ }
+
+ const TBlobIndexRecord *InplaceIndexEnd() const {
+ return InplaceIndexBegin() + NumItems;
+ }
+ };
+
+ struct TBlobHeader {
+ ui32 Checksum; // checksum (CRC32C) of TBlobHeader + data, not including checksum
+ TBlobIndexRecord IndexRecord; // index record for this blob
+ TChunkSerNum ChunkSerNum; // unique serial number of chunk this blob was written to
+
TString ExtractInplacePayload() const {
- const char *begin = reinterpret_cast<const char *>(this + 1);
- const char *end = begin + IndexRecord.PayloadSize;
+ const char *begin = reinterpret_cast<const char *>(this + 1);
+ const char *end = begin + IndexRecord.PayloadSize;
return TString(begin, end);
- }
- };
-#pragma pack(pop)
-
- } // NIncrHuge
-} // NKikimr
+ }
+ };
+#pragma pack(pop)
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h b/ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h
index 270e210699b..d20e32e8c91 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h
@@ -1,264 +1,264 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/containers/intrusive_rb_tree/rb_tree.h>
-#include <util/generic/intrlist.h>
-#include <util/generic/bitmap.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- template<typename TValue, typename TPageSize, TPageSize PageSize>
- class TIdLookupTable {
- template<typename TPage>
- struct TComparePageId {
- static bool Compare(const TPage& left, const TPage& right) {
- return left.PageId < right.PageId;
- }
- static bool Compare(const TPage& left, ui64 right) {
- return left.PageId < right;
- }
- static bool Compare(ui64 left, const TPage& right) {
- return left < right.PageId;
- }
- };
-
- struct TPage
- : public TRbTreeItem<TPage, TComparePageId<TPage>>
- , public TIntrusiveListItem<TPage>
- {
- union TItem {
- TValue Value;
- TPageSize NextFreeItem;
- };
-
- TItem Items[PageSize];
- TBitMap<PageSize> UsedItemsMap;
- TPageSize FirstFreeItem;
- TPageSize NumUsedItems;
- ui64 PageId;
-
- TPage()
- : FirstFreeItem(0)
- , NumUsedItems(0)
- , PageId(0)
- {
- for (TPageSize i = 0; i < PageSize; ++i) {
- Items[i].NextFreeItem = i + 1;
- }
- }
- };
-
- TRbTree<TPage, TComparePageId<TPage>> Pages;
-
- // list of pages with free items; most used pages come first, that is list is ordered in descending
- // NumUsedItems order
- TIntrusiveList<TPage> PagesWithFreeItems;
-
- public:
- ~TIdLookupTable() {
- auto it = Pages.Begin();
- while (it != Pages.End()) {
- std::unique_ptr<TPage> page(&*it);
- Pages.Erase(it++);
- }
- }
-
- TIncrHugeBlobId Create(TValue&& value) {
- // get a page to write into
- TPage *page;
- if (PagesWithFreeItems) {
- // there is a page with free items, reuse it
- page = PagesWithFreeItems.Front();
- if (++page->NumUsedItems == PageSize) {
- // this page is filled up to maximum capacity, remove it from this list
- PagesWithFreeItems.PopFront();
- }
- } else {
- // all pages are filled up to maximum; allocate new page
- auto newPage = std::make_unique<TPage>();
-
- // create unique page id
- if (Pages) {
- auto lastPage = Pages.End();
- --lastPage;
- newPage->PageId = lastPage->PageId + 1;
- }
-
- // insert page into tree
- Pages.Insert(page = newPage.release());
-
- // and then into pages with free items list
- static_assert(PageSize != 1, "page size can't be 1");
- page->NumUsedItems = 1;
- PagesWithFreeItems.PushBack(page);
- }
-
- TPageSize index = page->FirstFreeItem;
- page->FirstFreeItem = page->Items[index].NextFreeItem;
- page->UsedItemsMap[index] = true;
- try {
- new(&page->Items[index].Value) TValue(std::move(value));
- } catch (...) {
- Y_FAIL("TValue ctor should not throw");
- }
-
- return ComposeId(page->PageId, index);
- }
-
- TValue *Insert(TIncrHugeBlobId id, TValue&& value, bool findDup = false) {
- ui64 pageId;
- TPageSize index;
- DecomposeId(id, &pageId, &index);
-
- // find page or create new one if this does not exist
- TPage *page = Pages.Find(pageId);
- if (!page) {
- auto newPage = std::make_unique<TPage>();
- newPage->PageId = pageId;
- Pages.Insert(page = newPage.release());
- PagesWithFreeItems.PushBack(page);
- }
-
- // if this item is used, return duplicate entry
- if (page->UsedItemsMap[index] && findDup) {
- return &page->Items[index].Value;
- }
-
- // ensure that this item isn't used and set up usage flag
- Y_VERIFY(!page->UsedItemsMap[index]);
- page->UsedItemsMap[index] = true;
-
- // find item referring to this one
- TPageSize *p;
- for (p = &page->FirstFreeItem; *p != index; p = &page->Items[*p].NextFreeItem) {
- Y_VERIFY(!page->UsedItemsMap[*p]);
- }
-
- // fill it with correct value
- *p = page->Items[index].NextFreeItem;
-
- // initialize item
- try {
- new(&page->Items[index].Value) TValue(std::move(value));
- } catch (...) {
- Y_FAIL("TValue ctor should not throw");
- }
-
- // adjust usage counter
- ++page->NumUsedItems;
- if (page->NumUsedItems == PageSize) {
- page->Unlink();
- } else if (page->NumUsedItems == PageSize - 1) {
- PagesWithFreeItems.PushFront(page);
- } else {
- typename TIntrusiveList<TPage>::TIterator iter(page);
- ++iter;
- while (iter != PagesWithFreeItems.End() && page->NumUsedItems < iter->NumUsedItems) {
- ++iter;
- }
- page->LinkBefore(iter.Item());
- }
-
- return nullptr;
- }
-
- TValue& Lookup(TIncrHugeBlobId id) {
- TPage *page;
- TPageSize index;
- bool status = FindExistingItem(id, &page, &index);
- Y_VERIFY(status, "not found TIncrHugeBlobId# %016" PRIx64, id);
-
- // return reference
- return page->Items[index].Value;
- }
-
- bool Delete(TIncrHugeBlobId id, TValue *value = nullptr) {
- TPage *page;
- TPageSize index;
- bool status = FindExistingItem(id, &page, &index);
- if (!status) {
- return false;
- }
-
- if (value) {
- *value = std::move(page->Items[index].Value);
- }
-
- page->Items[index].Value.~TValue();
- if (!--page->NumUsedItems) {
- delete page;
- page = nullptr;
- } else if (page->NumUsedItems == PageSize - 1) {
- PagesWithFreeItems.PushFront(page);
- } else {
- typename TIntrusiveList<TPage>::TIterator iter(page);
- ++iter;
- while (iter != PagesWithFreeItems.End() && page->NumUsedItems < iter->NumUsedItems) {
- ++iter;
- }
- page->LinkBefore(iter.Item());
- }
-
- if (page) {
- // page was not deleted, so we can set up some pointers
- page->Items[index].NextFreeItem = page->FirstFreeItem;
- page->FirstFreeItem = index;
- page->UsedItemsMap[index] = false;
- }
-
- return true;
- }
-
- void Replace(TIncrHugeBlobId id, TValue&& value) {
- TValue& existingValue = Lookup(id);
- existingValue = std::move(value);
- }
-
- template<typename Func>
- void Enumerate(Func&& callback) const {
- for (auto it = Pages.Begin(); it != Pages.End(); ++it) {
- for (TPageSize index = 0; index < PageSize; ++index) {
- if (it->UsedItemsMap[index]) {
- callback(ComposeId(it->PageId, index), it->Items[index].Value);
- }
- }
- }
- }
-
- size_t GetNumPagesUsed() const {
- size_t numItems = 0;
- for (auto it = Pages.Begin(); it != Pages.End(); ++it) {
- ++numItems;
- }
- return numItems;
- }
-
- private:
- bool FindExistingItem(TIncrHugeBlobId id, TPage **page, TPageSize *index) const {
- ui64 pageId;
- DecomposeId(id, &pageId, index);
-
- // find page containing this item
- *page = Pages.Find(pageId);
- if (!*page) {
- return false;
- }
-
- // check if item is used
- return (*page)->UsedItemsMap[*index];
- }
-
- static TIncrHugeBlobId ComposeId(ui64 pageId, TPageSize index) {
- return pageId * PageSize + index;
- }
-
- static void DecomposeId(TIncrHugeBlobId id, ui64 *pageId, TPageSize *index) {
- *pageId = id / PageSize;
- *index = id % PageSize;
- }
- };
-
- } // NIncrHuge
-} // NKikimr
+#include <util/generic/intrlist.h>
+#include <util/generic/bitmap.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ template<typename TValue, typename TPageSize, TPageSize PageSize>
+ class TIdLookupTable {
+ template<typename TPage>
+ struct TComparePageId {
+ static bool Compare(const TPage& left, const TPage& right) {
+ return left.PageId < right.PageId;
+ }
+ static bool Compare(const TPage& left, ui64 right) {
+ return left.PageId < right;
+ }
+ static bool Compare(ui64 left, const TPage& right) {
+ return left < right.PageId;
+ }
+ };
+
+ struct TPage
+ : public TRbTreeItem<TPage, TComparePageId<TPage>>
+ , public TIntrusiveListItem<TPage>
+ {
+ union TItem {
+ TValue Value;
+ TPageSize NextFreeItem;
+ };
+
+ TItem Items[PageSize];
+ TBitMap<PageSize> UsedItemsMap;
+ TPageSize FirstFreeItem;
+ TPageSize NumUsedItems;
+ ui64 PageId;
+
+ TPage()
+ : FirstFreeItem(0)
+ , NumUsedItems(0)
+ , PageId(0)
+ {
+ for (TPageSize i = 0; i < PageSize; ++i) {
+ Items[i].NextFreeItem = i + 1;
+ }
+ }
+ };
+
+ TRbTree<TPage, TComparePageId<TPage>> Pages;
+
+ // list of pages with free items; most used pages come first, that is list is ordered in descending
+ // NumUsedItems order
+ TIntrusiveList<TPage> PagesWithFreeItems;
+
+ public:
+ ~TIdLookupTable() {
+ auto it = Pages.Begin();
+ while (it != Pages.End()) {
+ std::unique_ptr<TPage> page(&*it);
+ Pages.Erase(it++);
+ }
+ }
+
+ TIncrHugeBlobId Create(TValue&& value) {
+ // get a page to write into
+ TPage *page;
+ if (PagesWithFreeItems) {
+ // there is a page with free items, reuse it
+ page = PagesWithFreeItems.Front();
+ if (++page->NumUsedItems == PageSize) {
+ // this page is filled up to maximum capacity, remove it from this list
+ PagesWithFreeItems.PopFront();
+ }
+ } else {
+ // all pages are filled up to maximum; allocate new page
+ auto newPage = std::make_unique<TPage>();
+
+ // create unique page id
+ if (Pages) {
+ auto lastPage = Pages.End();
+ --lastPage;
+ newPage->PageId = lastPage->PageId + 1;
+ }
+
+ // insert page into tree
+ Pages.Insert(page = newPage.release());
+
+ // and then into pages with free items list
+ static_assert(PageSize != 1, "page size can't be 1");
+ page->NumUsedItems = 1;
+ PagesWithFreeItems.PushBack(page);
+ }
+
+ TPageSize index = page->FirstFreeItem;
+ page->FirstFreeItem = page->Items[index].NextFreeItem;
+ page->UsedItemsMap[index] = true;
+ try {
+ new(&page->Items[index].Value) TValue(std::move(value));
+ } catch (...) {
+ Y_FAIL("TValue ctor should not throw");
+ }
+
+ return ComposeId(page->PageId, index);
+ }
+
+ TValue *Insert(TIncrHugeBlobId id, TValue&& value, bool findDup = false) {
+ ui64 pageId;
+ TPageSize index;
+ DecomposeId(id, &pageId, &index);
+
+ // find page or create new one if this does not exist
+ TPage *page = Pages.Find(pageId);
+ if (!page) {
+ auto newPage = std::make_unique<TPage>();
+ newPage->PageId = pageId;
+ Pages.Insert(page = newPage.release());
+ PagesWithFreeItems.PushBack(page);
+ }
+
+ // if this item is used, return duplicate entry
+ if (page->UsedItemsMap[index] && findDup) {
+ return &page->Items[index].Value;
+ }
+
+ // ensure that this item isn't used and set up usage flag
+ Y_VERIFY(!page->UsedItemsMap[index]);
+ page->UsedItemsMap[index] = true;
+
+ // find item referring to this one
+ TPageSize *p;
+ for (p = &page->FirstFreeItem; *p != index; p = &page->Items[*p].NextFreeItem) {
+ Y_VERIFY(!page->UsedItemsMap[*p]);
+ }
+
+ // fill it with correct value
+ *p = page->Items[index].NextFreeItem;
+
+ // initialize item
+ try {
+ new(&page->Items[index].Value) TValue(std::move(value));
+ } catch (...) {
+ Y_FAIL("TValue ctor should not throw");
+ }
+
+ // adjust usage counter
+ ++page->NumUsedItems;
+ if (page->NumUsedItems == PageSize) {
+ page->Unlink();
+ } else if (page->NumUsedItems == PageSize - 1) {
+ PagesWithFreeItems.PushFront(page);
+ } else {
+ typename TIntrusiveList<TPage>::TIterator iter(page);
+ ++iter;
+ while (iter != PagesWithFreeItems.End() && page->NumUsedItems < iter->NumUsedItems) {
+ ++iter;
+ }
+ page->LinkBefore(iter.Item());
+ }
+
+ return nullptr;
+ }
+
+ TValue& Lookup(TIncrHugeBlobId id) {
+ TPage *page;
+ TPageSize index;
+ bool status = FindExistingItem(id, &page, &index);
+ Y_VERIFY(status, "not found TIncrHugeBlobId# %016" PRIx64, id);
+
+ // return reference
+ return page->Items[index].Value;
+ }
+
+ bool Delete(TIncrHugeBlobId id, TValue *value = nullptr) {
+ TPage *page;
+ TPageSize index;
+ bool status = FindExistingItem(id, &page, &index);
+ if (!status) {
+ return false;
+ }
+
+ if (value) {
+ *value = std::move(page->Items[index].Value);
+ }
+
+ page->Items[index].Value.~TValue();
+ if (!--page->NumUsedItems) {
+ delete page;
+ page = nullptr;
+ } else if (page->NumUsedItems == PageSize - 1) {
+ PagesWithFreeItems.PushFront(page);
+ } else {
+ typename TIntrusiveList<TPage>::TIterator iter(page);
+ ++iter;
+ while (iter != PagesWithFreeItems.End() && page->NumUsedItems < iter->NumUsedItems) {
+ ++iter;
+ }
+ page->LinkBefore(iter.Item());
+ }
+
+ if (page) {
+ // page was not deleted, so we can set up some pointers
+ page->Items[index].NextFreeItem = page->FirstFreeItem;
+ page->FirstFreeItem = index;
+ page->UsedItemsMap[index] = false;
+ }
+
+ return true;
+ }
+
+ void Replace(TIncrHugeBlobId id, TValue&& value) {
+ TValue& existingValue = Lookup(id);
+ existingValue = std::move(value);
+ }
+
+ template<typename Func>
+ void Enumerate(Func&& callback) const {
+ for (auto it = Pages.Begin(); it != Pages.End(); ++it) {
+ for (TPageSize index = 0; index < PageSize; ++index) {
+ if (it->UsedItemsMap[index]) {
+ callback(ComposeId(it->PageId, index), it->Items[index].Value);
+ }
+ }
+ }
+ }
+
+ size_t GetNumPagesUsed() const {
+ size_t numItems = 0;
+ for (auto it = Pages.Begin(); it != Pages.End(); ++it) {
+ ++numItems;
+ }
+ return numItems;
+ }
+
+ private:
+ bool FindExistingItem(TIncrHugeBlobId id, TPage **page, TPageSize *index) const {
+ ui64 pageId;
+ DecomposeId(id, &pageId, index);
+
+ // find page containing this item
+ *page = Pages.Find(pageId);
+ if (!*page) {
+ return false;
+ }
+
+ // check if item is used
+ return (*page)->UsedItemsMap[*index];
+ }
+
+ static TIncrHugeBlobId ComposeId(ui64 pageId, TPageSize index) {
+ return pageId * PageSize + index;
+ }
+
+ static void DecomposeId(TIncrHugeBlobId id, ui64 *pageId, TPageSize *index) {
+ *pageId = id / PageSize;
+ *index = id % PageSize;
+ }
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper.cpp
index 05aafde94d1..c3401992738 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper.cpp
@@ -1,197 +1,197 @@
-#include "incrhuge_keeper.h"
-#include "incrhuge.h"
-#include "incrhuge_keeper_recovery_scan.h"
+#include "incrhuge_keeper.h"
+#include "incrhuge.h"
+#include "incrhuge_keeper_recovery_scan.h"
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
#include <library/cpp/digest/crc32c/crc32c.h>
#include <library/cpp/monlib/service/pages/templates.h>
-#include <util/generic/queue.h>
-#include <util/generic/bitmap.h>
-
-using namespace NActors;
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TKeeper::TKeeper(const TKeeperSettings& settings)
- : State(settings)
- , Allocator(*this)
- , Defragmenter(*this)
- , Deleter(*this)
- , Logger(*this)
- , Reader(*this)
- , Recovery(*this)
- , Writer(*this)
- {
- }
-
- void TKeeper::Bootstrap(const TActorContext& ctx) {
- // send yard init message
- TVDiskID myVDiskId(~0, ~0, 'H', 'I', 'K');
- ctx.Send(State.Settings.PDiskActorId, new NPDisk::TEvYardInit(State.Settings.InitOwnerRound, myVDiskId,
- State.Settings.PDiskGuid, ctx.SelfID));
- Become(&TKeeper::StateFunc);
- }
-
- void *TKeeper::RegisterYardCallback(std::unique_ptr<IEventCallback>&& callback) {
- void *id = reinterpret_cast<void *>(NextCallbackId++);
- CallbackMap.emplace(id, std::move(callback));
- return id;
- }
-
- void TKeeper::Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvYardInitResult *msg = ev->Get();
- State.PDiskParams = std::move(msg->PDiskParams);
-
- // calculate blocks size
- State.BlockSize = (State.Settings.UnalignedBlockSize + State.PDiskParams->AppendBlockSize - 1);
- State.BlockSize -= State.BlockSize % State.PDiskParams->AppendBlockSize;
-
- // calculate number of blocks in chunk
- State.BlocksInChunk = State.PDiskParams->ChunkSize / State.BlockSize;
-
- State.BlocksInMinBlob = (State.Settings.MinHugeBlobInBytes + State.BlockSize - 1) / State.BlockSize;
-
- State.MaxBlobsPerChunk = State.BlocksInChunk / State.BlocksInMinBlob;
-
- for (;;) {
- const ui32 indexSize = sizeof(TBlobIndexHeader) + State.MaxBlobsPerChunk * sizeof(TBlobIndexRecord);
- State.BlocksInIndexSection = (indexSize + State.BlockSize - 1) / State.BlockSize;
- State.BlocksInDataSection = State.BlocksInChunk - State.BlocksInIndexSection;
- if (State.BlocksInDataSection >= State.MaxBlobsPerChunk * State.BlocksInMinBlob) {
- break;
- } else {
- --State.MaxBlobsPerChunk;
- }
- }
-
- LOG_DEBUG(ctx, NKikimrServices::BS_INCRHUGE, "BlockSize# %" PRIu32 " BlocksInChunk# %" PRIu32
- " BlocksInMinBlob# %" PRIu32 " MaxBlobsPerChunk# %" PRIu32 " BlocksInDataSection# %" PRIu32
- " BlocksInIndexSection# %" PRIu32, State.BlockSize, State.BlocksInChunk, State.BlocksInMinBlob,
- State.MaxBlobsPerChunk, State.BlocksInDataSection, State.BlocksInIndexSection);
-
+#include <util/generic/queue.h>
+#include <util/generic/bitmap.h>
+
+using namespace NActors;
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TKeeper::TKeeper(const TKeeperSettings& settings)
+ : State(settings)
+ , Allocator(*this)
+ , Defragmenter(*this)
+ , Deleter(*this)
+ , Logger(*this)
+ , Reader(*this)
+ , Recovery(*this)
+ , Writer(*this)
+ {
+ }
+
+ void TKeeper::Bootstrap(const TActorContext& ctx) {
+ // send yard init message
+ TVDiskID myVDiskId(~0, ~0, 'H', 'I', 'K');
+ ctx.Send(State.Settings.PDiskActorId, new NPDisk::TEvYardInit(State.Settings.InitOwnerRound, myVDiskId,
+ State.Settings.PDiskGuid, ctx.SelfID));
+ Become(&TKeeper::StateFunc);
+ }
+
+ void *TKeeper::RegisterYardCallback(std::unique_ptr<IEventCallback>&& callback) {
+ void *id = reinterpret_cast<void *>(NextCallbackId++);
+ CallbackMap.emplace(id, std::move(callback));
+ return id;
+ }
+
+ void TKeeper::Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvYardInitResult *msg = ev->Get();
+ State.PDiskParams = std::move(msg->PDiskParams);
+
+ // calculate blocks size
+ State.BlockSize = (State.Settings.UnalignedBlockSize + State.PDiskParams->AppendBlockSize - 1);
+ State.BlockSize -= State.BlockSize % State.PDiskParams->AppendBlockSize;
+
+ // calculate number of blocks in chunk
+ State.BlocksInChunk = State.PDiskParams->ChunkSize / State.BlockSize;
+
+ State.BlocksInMinBlob = (State.Settings.MinHugeBlobInBytes + State.BlockSize - 1) / State.BlockSize;
+
+ State.MaxBlobsPerChunk = State.BlocksInChunk / State.BlocksInMinBlob;
+
+ for (;;) {
+ const ui32 indexSize = sizeof(TBlobIndexHeader) + State.MaxBlobsPerChunk * sizeof(TBlobIndexRecord);
+ State.BlocksInIndexSection = (indexSize + State.BlockSize - 1) / State.BlockSize;
+ State.BlocksInDataSection = State.BlocksInChunk - State.BlocksInIndexSection;
+ if (State.BlocksInDataSection >= State.MaxBlobsPerChunk * State.BlocksInMinBlob) {
+ break;
+ } else {
+ --State.MaxBlobsPerChunk;
+ }
+ }
+
+ LOG_DEBUG(ctx, NKikimrServices::BS_INCRHUGE, "BlockSize# %" PRIu32 " BlocksInChunk# %" PRIu32
+ " BlocksInMinBlob# %" PRIu32 " MaxBlobsPerChunk# %" PRIu32 " BlocksInDataSection# %" PRIu32
+ " BlocksInIndexSection# %" PRIu32, State.BlockSize, State.BlocksInChunk, State.BlocksInMinBlob,
+ State.MaxBlobsPerChunk, State.BlocksInDataSection, State.BlocksInIndexSection);
+
auto chunksIt = msg->StartingPoints.find(TLogSignature::SignatureIncrHugeChunks);
auto deletesIt = msg->StartingPoints.find(TLogSignature::SignatureIncrHugeDeletes);
- auto end = msg->StartingPoints.end();
- Recovery.ApplyYardInit(msg->Status, chunksIt != end ? &chunksIt->second : nullptr,
- deletesIt != end ? &deletesIt->second : nullptr, ctx);
- UpdateStatusFlags(msg->StatusFlags, ctx);
- }
-
- void TKeeper::Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvChunkReserveResult *msg = ev->Get();
- Allocator.ApplyAllocate(msg->Status, std::move(msg->ChunkIds), ctx);
- UpdateStatusFlags(msg->StatusFlags, ctx);
- }
-
- void TKeeper::Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvChunkWriteResult *msg = ev->Get();
- InvokeCallback(msg->Cookie, msg->Status, msg, ctx);
- UpdateStatusFlags(msg->StatusFlags, ctx);
- }
-
- void TKeeper::Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvChunkReadResult *msg = ev->Get();
- InvokeCallback(msg->Cookie, msg->Status, msg, ctx);
- UpdateStatusFlags(msg->StatusFlags, ctx);
- }
-
- void TKeeper::Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvLogResult *msg = ev->Get();
- for (const auto& item : msg->Results) {
- InvokeCallback(item.Cookie, msg->Status, msg, ctx);
- }
- UpdateStatusFlags(msg->StatusFlags, ctx);
- }
-
- void TKeeper::InvokeCallback(void *cookie, NKikimrProto::EReplyStatus status, IEventBase *msg,
- const TActorContext& ctx) {
- auto it = CallbackMap.find(cookie);
- Y_VERIFY(it != CallbackMap.end());
- it->second->Apply(status, msg, ctx);
- CallbackMap.erase(it);
- }
-
- void TKeeper::UpdateStatusFlags(NPDisk::TStatusFlags flags, const TActorContext& ctx) {
- const EDiskState newState =
- flags & NKikimrBlobStorage::StatusDiskSpaceRed ? EDiskState::SpaceRed :
- flags & NKikimrBlobStorage::StatusDiskSpaceOrange ? EDiskState::SpaceOrange :
+ auto end = msg->StartingPoints.end();
+ Recovery.ApplyYardInit(msg->Status, chunksIt != end ? &chunksIt->second : nullptr,
+ deletesIt != end ? &deletesIt->second : nullptr, ctx);
+ UpdateStatusFlags(msg->StatusFlags, ctx);
+ }
+
+ void TKeeper::Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvChunkReserveResult *msg = ev->Get();
+ Allocator.ApplyAllocate(msg->Status, std::move(msg->ChunkIds), ctx);
+ UpdateStatusFlags(msg->StatusFlags, ctx);
+ }
+
+ void TKeeper::Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvChunkWriteResult *msg = ev->Get();
+ InvokeCallback(msg->Cookie, msg->Status, msg, ctx);
+ UpdateStatusFlags(msg->StatusFlags, ctx);
+ }
+
+ void TKeeper::Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvChunkReadResult *msg = ev->Get();
+ InvokeCallback(msg->Cookie, msg->Status, msg, ctx);
+ UpdateStatusFlags(msg->StatusFlags, ctx);
+ }
+
+ void TKeeper::Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvLogResult *msg = ev->Get();
+ for (const auto& item : msg->Results) {
+ InvokeCallback(item.Cookie, msg->Status, msg, ctx);
+ }
+ UpdateStatusFlags(msg->StatusFlags, ctx);
+ }
+
+ void TKeeper::InvokeCallback(void *cookie, NKikimrProto::EReplyStatus status, IEventBase *msg,
+ const TActorContext& ctx) {
+ auto it = CallbackMap.find(cookie);
+ Y_VERIFY(it != CallbackMap.end());
+ it->second->Apply(status, msg, ctx);
+ CallbackMap.erase(it);
+ }
+
+ void TKeeper::UpdateStatusFlags(NPDisk::TStatusFlags flags, const TActorContext& ctx) {
+ const EDiskState newState =
+ flags & NKikimrBlobStorage::StatusDiskSpaceRed ? EDiskState::SpaceRed :
+ flags & NKikimrBlobStorage::StatusDiskSpaceOrange ? EDiskState::SpaceOrange :
flags & NKikimrBlobStorage::StatusDiskSpaceLightYellowMove ? EDiskState::SpaceYellow : EDiskState::SpaceGreen;
-
- if (newState != State.DiskState) {
- // kick defragmenter when it's going to be worse
- bool kickDefrag = newState < State.DiskState;
- State.DiskState = newState;
- if (kickDefrag) {
- for (const auto& pair : State.Chunks) {
- Defragmenter.UpdateChunkState(pair.first, ctx);
- }
- }
- }
- }
-
- void TKeeper::Handle(TEvIncrHugeCallback::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeCallback *msg = ev->Get();
- Y_VERIFY(msg->Callback);
- msg->Callback->Apply(NKikimrProto::OK, msg, ctx);
- }
-
- void TKeeper::Handle(TEvIncrHugeReadLogResult::TPtr& ev, const TActorContext& ctx) {
- Recovery.ApplyReadLog(ev->Sender, *ev->Get(), ctx);
- }
-
- void TKeeper::Handle(TEvIncrHugeScanResult::TPtr& ev, const TActorContext& ctx) {
- switch (EScanCookie(ev->Cookie)) {
- case EScanCookie::Recovery:
- Recovery.ApplyScan(ev->Sender, *ev->Get(), ctx);
- break;
-
- case EScanCookie::Defrag:
- Defragmenter.ApplyScan(ev->Sender, *ev->Get(), ctx);
- break;
-
- default:
- Y_FAIL("unexpected case");
- }
- }
-
- void TKeeper::HandlePoison(const TActorContext& ctx) {
+
+ if (newState != State.DiskState) {
+ // kick defragmenter when it's going to be worse
+ bool kickDefrag = newState < State.DiskState;
+ State.DiskState = newState;
+ if (kickDefrag) {
+ for (const auto& pair : State.Chunks) {
+ Defragmenter.UpdateChunkState(pair.first, ctx);
+ }
+ }
+ }
+ }
+
+ void TKeeper::Handle(TEvIncrHugeCallback::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeCallback *msg = ev->Get();
+ Y_VERIFY(msg->Callback);
+ msg->Callback->Apply(NKikimrProto::OK, msg, ctx);
+ }
+
+ void TKeeper::Handle(TEvIncrHugeReadLogResult::TPtr& ev, const TActorContext& ctx) {
+ Recovery.ApplyReadLog(ev->Sender, *ev->Get(), ctx);
+ }
+
+ void TKeeper::Handle(TEvIncrHugeScanResult::TPtr& ev, const TActorContext& ctx) {
+ switch (EScanCookie(ev->Cookie)) {
+ case EScanCookie::Recovery:
+ Recovery.ApplyScan(ev->Sender, *ev->Get(), ctx);
+ break;
+
+ case EScanCookie::Defrag:
+ Defragmenter.ApplyScan(ev->Sender, *ev->Get(), ctx);
+ break;
+
+ default:
+ Y_FAIL("unexpected case");
+ }
+ }
+
+ void TKeeper::HandlePoison(const TActorContext& ctx) {
for (const TActorId& actorId : State.ChildActors) {
- ctx.Send(actorId, new TEvents::TEvPoisonPill);
- }
- Die(ctx);
- }
-
- STRICT_STFUNC(TKeeper::StateFunc,
- // client <-> keeper interface
- HFunc(TEvIncrHugeInit, Recovery.HandleInit)
- HFunc(TEvIncrHugeWrite, Writer.HandleWrite)
- HFunc(TEvIncrHugeRead, Reader.HandleRead)
- HFunc(TEvIncrHugeDelete, Deleter.HandleDelete)
-// HFunc(TEvIncrHugeHarakiri, OwnerManager.HandleHarakiri)
- HFunc(TEvIncrHugeControlDefrag, Defragmenter.HandleControlDefrag)
-
-
- // keeper <-> yard interface
- HFunc(NPDisk::TEvYardInitResult, Handle)
- HFunc(NPDisk::TEvChunkReserveResult, Handle)
- HFunc(NPDisk::TEvChunkWriteResult, Handle)
- HFunc(NPDisk::TEvChunkReadResult, Handle)
- HFunc(NPDisk::TEvLogResult, Handle)
-
- // internal events
- HFunc(TEvIncrHugeCallback, Handle)
- HFunc(TEvIncrHugeReadLogResult, Handle)
- HFunc(TEvIncrHugeScanResult, Handle)
-
- // shutdown handling
- CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
- )
-
- IActor *CreateIncrHugeKeeper(const TKeeperSettings& settings) {
- return new TKeeper(settings);
- }
-
-
- } // NIncrHuge
-} // NKikimr
+ ctx.Send(actorId, new TEvents::TEvPoisonPill);
+ }
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(TKeeper::StateFunc,
+ // client <-> keeper interface
+ HFunc(TEvIncrHugeInit, Recovery.HandleInit)
+ HFunc(TEvIncrHugeWrite, Writer.HandleWrite)
+ HFunc(TEvIncrHugeRead, Reader.HandleRead)
+ HFunc(TEvIncrHugeDelete, Deleter.HandleDelete)
+// HFunc(TEvIncrHugeHarakiri, OwnerManager.HandleHarakiri)
+ HFunc(TEvIncrHugeControlDefrag, Defragmenter.HandleControlDefrag)
+
+
+ // keeper <-> yard interface
+ HFunc(NPDisk::TEvYardInitResult, Handle)
+ HFunc(NPDisk::TEvChunkReserveResult, Handle)
+ HFunc(NPDisk::TEvChunkWriteResult, Handle)
+ HFunc(NPDisk::TEvChunkReadResult, Handle)
+ HFunc(NPDisk::TEvLogResult, Handle)
+
+ // internal events
+ HFunc(TEvIncrHugeCallback, Handle)
+ HFunc(TEvIncrHugeReadLogResult, Handle)
+ HFunc(TEvIncrHugeScanResult, Handle)
+
+ // shutdown handling
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
+ )
+
+ IActor *CreateIncrHugeKeeper(const TKeeperSettings& settings) {
+ return new TKeeper(settings);
+ }
+
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper.h
index 3f45a0c0300..5cea6544604 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper.h
@@ -1,85 +1,85 @@
-#pragma once
-
-#include "defs.h"
-
-#include "incrhuge_keeper_alloc.h"
-#include "incrhuge_keeper_defrag.h"
-#include "incrhuge_keeper_delete.h"
-#include "incrhuge_keeper_log.h"
-#include "incrhuge_keeper_read.h"
-#include "incrhuge_keeper_recovery.h"
-#include "incrhuge_keeper_write.h"
-
+#pragma once
+
+#include "defs.h"
+
+#include "incrhuge_keeper_alloc.h"
+#include "incrhuge_keeper_defrag.h"
+#include "incrhuge_keeper_delete.h"
+#include "incrhuge_keeper_log.h"
+#include "incrhuge_keeper_read.h"
+#include "incrhuge_keeper_recovery.h"
+#include "incrhuge_keeper_write.h"
+
#include <library/cpp/actors/core/actor.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TKeeper
- : public NActors::TActorBootstrapped<TKeeper>
- {
- TKeeperCommonState State;
-
- friend class TKeeperComponentBase;
-
- friend class TAllocator;
- friend class TDefragmenter;
- friend class TDeleter;
- friend class TLogger;
- friend class TReader;
- friend class TRecovery;
- friend class TWriter;
-
- TAllocator Allocator;
- TDefragmenter Defragmenter;
- TDeleter Deleter;
- TLogger Logger;
- TReader Reader;
- TRecovery Recovery;
- TWriter Writer;
-
- THashMap<void *, std::unique_ptr<IEventCallback>> CallbackMap;
- ui64 NextCallbackId = 1;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER;
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TKeeper
+ : public NActors::TActorBootstrapped<TKeeper>
+ {
+ TKeeperCommonState State;
+
+ friend class TKeeperComponentBase;
+
+ friend class TAllocator;
+ friend class TDefragmenter;
+ friend class TDeleter;
+ friend class TLogger;
+ friend class TReader;
+ friend class TRecovery;
+ friend class TWriter;
+
+ TAllocator Allocator;
+ TDefragmenter Defragmenter;
+ TDeleter Deleter;
+ TLogger Logger;
+ TReader Reader;
+ TRecovery Recovery;
+ TWriter Writer;
+
+ THashMap<void *, std::unique_ptr<IEventCallback>> CallbackMap;
+ ui64 NextCallbackId = 1;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER;
}
- TKeeper(const TKeeperSettings& settings);
-
- void Bootstrap(const TActorContext& ctx);
-
- //////////////////////
- // Callback helpers //
- //////////////////////
-
- void *RegisterYardCallback(std::unique_ptr<IEventCallback>&& callback);
-
- private:
- STFUNC(StateFunc);
-
- /////////////////////////
- // Yard event handlers //
- /////////////////////////
-
- void Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx);
- void Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx);
- void Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx);
- void Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx);
- void Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvIncrHugeCallback::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvIncrHugeReadLogResult::TPtr& ev, const TActorContext& ctx);
- void Handle(TEvIncrHugeScanResult::TPtr& ev, const TActorContext& ctx);
-
- void HandlePoison(const TActorContext& ctx);
-
- void InvokeCallback(void *cookie, NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx);
-
- void UpdateStatusFlags(NPDisk::TStatusFlags flags, const TActorContext& ctx);
- };
-
- NActors::IActor *CreateIncrHugeKeeper(const TKeeperSettings& settings);
-
- } // NIncrHuge
-} // NKikimr
+ TKeeper(const TKeeperSettings& settings);
+
+ void Bootstrap(const TActorContext& ctx);
+
+ //////////////////////
+ // Callback helpers //
+ //////////////////////
+
+ void *RegisterYardCallback(std::unique_ptr<IEventCallback>&& callback);
+
+ private:
+ STFUNC(StateFunc);
+
+ /////////////////////////
+ // Yard event handlers //
+ /////////////////////////
+
+ void Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvIncrHugeCallback::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvIncrHugeReadLogResult::TPtr& ev, const TActorContext& ctx);
+ void Handle(TEvIncrHugeScanResult::TPtr& ev, const TActorContext& ctx);
+
+ void HandlePoison(const TActorContext& ctx);
+
+ void InvokeCallback(void *cookie, NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx);
+
+ void UpdateStatusFlags(NPDisk::TStatusFlags flags, const TActorContext& ctx);
+ };
+
+ NActors::IActor *CreateIncrHugeKeeper(const TKeeperSettings& settings);
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.cpp
index caaf0c7ca56..ad88a6b2061 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.cpp
@@ -1,90 +1,90 @@
-#include "incrhuge_keeper_alloc.h"
-#include "incrhuge_keeper.h"
-#include "incrhuge_keeper_write.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TAllocator::TAllocator(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Allocator")
- {}
-
- TAllocator::~TAllocator()
- {}
-
- void TAllocator::CheckForAllocationNeed(const TActorContext& ctx) {
- // if there is a query, we exit; we allow only one uncompleted query at a time
- if (ChunkReserveInFlight) {
- return;
- }
-
- // calculate number of chunks we currently have (the one being written to + write intent queue + uncommitted)
- ui32 numChunks = Keeper.State.WriteIntentQueue.size() + NumReservedUncommittedChunks;
- if (Keeper.State.CurrentChunk) {
- ++numChunks;
- }
-
- // see if we potentially need to allocate something
- if (numChunks < Keeper.State.Settings.MinCleanChunks) {
- // calculate number of chunks we have to reserve
- ui32 numToReserve = Keeper.State.Settings.MinCleanChunks - numChunks;
- // reserve only if we exceed specified allocation batch
- if (numToReserve >= Keeper.State.Settings.MinAllocationBatch) {
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkReserve(Keeper.State.PDiskParams->Owner,
- Keeper.State.PDiskParams->OwnerRound, numToReserve));
- ChunkReserveInFlight = true;
- }
- }
- }
-
+#include "incrhuge_keeper_alloc.h"
+#include "incrhuge_keeper.h"
+#include "incrhuge_keeper_write.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TAllocator::TAllocator(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Allocator")
+ {}
+
+ TAllocator::~TAllocator()
+ {}
+
+ void TAllocator::CheckForAllocationNeed(const TActorContext& ctx) {
+ // if there is a query, we exit; we allow only one uncompleted query at a time
+ if (ChunkReserveInFlight) {
+ return;
+ }
+
+ // calculate number of chunks we currently have (the one being written to + write intent queue + uncommitted)
+ ui32 numChunks = Keeper.State.WriteIntentQueue.size() + NumReservedUncommittedChunks;
+ if (Keeper.State.CurrentChunk) {
+ ++numChunks;
+ }
+
+ // see if we potentially need to allocate something
+ if (numChunks < Keeper.State.Settings.MinCleanChunks) {
+ // calculate number of chunks we have to reserve
+ ui32 numToReserve = Keeper.State.Settings.MinCleanChunks - numChunks;
+ // reserve only if we exceed specified allocation batch
+ if (numToReserve >= Keeper.State.Settings.MinAllocationBatch) {
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkReserve(Keeper.State.PDiskParams->Owner,
+ Keeper.State.PDiskParams->OwnerRound, numToReserve));
+ ChunkReserveInFlight = true;
+ }
+ }
+ }
+
void TAllocator::ApplyAllocate(NKikimrProto::EReplyStatus status, TVector<TChunkIdx>&& chunks,
- const TActorContext& ctx) {
- if (status == NKikimrProto::OK) {
- // count these chunks as reserved, but not yet committed
- NumReservedUncommittedChunks += chunks.size();
-
- // remember current id to store it in intent queue in case of success
- TChunkSerNum baseSerNum = Keeper.State.CurrentSerNum;
- Keeper.State.CurrentSerNum.Advance(chunks.size());
-
- // create callback which is invoked when allocation logging is finished; it captures a copy of
- // "chunks" vector to put it into write intent queue in case of success
- auto callback = [this, chunks, baseSerNum](NKikimrProto::EReplyStatus status,
- IEventBase* /*result*/, const TActorContext& ctx) {
- ChunkReserveInFlight = false;
- Y_VERIFY(NumReservedUncommittedChunks >= chunks.size());
- NumReservedUncommittedChunks -= chunks.size();
- if (status == NKikimrProto::OK) {
- // copy just allocated and confirmed chunks to write intent queue and kick writer (it may be
- // waiting for new chunks to arrive); we assign sequential identifiers to each allocated chunk
- // to enable strict ordering of write intent queue on recovery
+ const TActorContext& ctx) {
+ if (status == NKikimrProto::OK) {
+ // count these chunks as reserved, but not yet committed
+ NumReservedUncommittedChunks += chunks.size();
+
+ // remember current id to store it in intent queue in case of success
+ TChunkSerNum baseSerNum = Keeper.State.CurrentSerNum;
+ Keeper.State.CurrentSerNum.Advance(chunks.size());
+
+ // create callback which is invoked when allocation logging is finished; it captures a copy of
+ // "chunks" vector to put it into write intent queue in case of success
+ auto callback = [this, chunks, baseSerNum](NKikimrProto::EReplyStatus status,
+ IEventBase* /*result*/, const TActorContext& ctx) {
+ ChunkReserveInFlight = false;
+ Y_VERIFY(NumReservedUncommittedChunks >= chunks.size());
+ NumReservedUncommittedChunks -= chunks.size();
+ if (status == NKikimrProto::OK) {
+ // copy just allocated and confirmed chunks to write intent queue and kick writer (it may be
+ // waiting for new chunks to arrive); we assign sequential identifiers to each allocated chunk
+ // to enable strict ordering of write intent queue on recovery
for (size_t i = 0; i < chunks.size(); ++i) {
- TChunkSerNum chunkSerNum = baseSerNum.Add(i);
- const ui32 chunkIdx = chunks[i];
+ TChunkSerNum chunkSerNum = baseSerNum.Add(i);
+ const ui32 chunkIdx = chunks[i];
IHLOG_DEBUG(ctx, "ChunkIdx# %" PRIu32 " ChunkSerNum# %s", chunkIdx, chunkSerNum.ToString().data());
- Keeper.State.WriteIntentQueue.push(chunks[i]);
- Keeper.State.Chunks.emplace(chunks[i], TChunkInfo{
- EChunkState::WriteIntent, // State
- chunkSerNum, // ChunkSerNum
- 0, // NumUsedBlocks
- 0, // NumItems
- {}, // DeletedItems
- 0, // InFlightReq
- });
- }
- Keeper.Writer.ProcessWriteQueue(ctx);
- }
- CheckForAllocationNeed(ctx);
- };
-
- // log allocation which will record new chunk and new current id
- Keeper.Logger.LogChunkAllocation(std::move(chunks), baseSerNum, MakeCallback(std::move(callback)), ctx);
- } else {
- // try again, what else we can do?
- ChunkReserveInFlight = false;
- CheckForAllocationNeed(ctx);
- }
- }
-
- } // NIncrHuge
-} // NKikimr
+ Keeper.State.WriteIntentQueue.push(chunks[i]);
+ Keeper.State.Chunks.emplace(chunks[i], TChunkInfo{
+ EChunkState::WriteIntent, // State
+ chunkSerNum, // ChunkSerNum
+ 0, // NumUsedBlocks
+ 0, // NumItems
+ {}, // DeletedItems
+ 0, // InFlightReq
+ });
+ }
+ Keeper.Writer.ProcessWriteQueue(ctx);
+ }
+ CheckForAllocationNeed(ctx);
+ };
+
+ // log allocation which will record new chunk and new current id
+ Keeper.Logger.LogChunkAllocation(std::move(chunks), baseSerNum, MakeCallback(std::move(callback)), ctx);
+ } else {
+ // try again, what else we can do?
+ ChunkReserveInFlight = false;
+ CheckForAllocationNeed(ctx);
+ }
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.h
index ecef2a6c2ea..f91c24f1537 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_alloc.h
@@ -1,32 +1,32 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TAllocator
- : public TKeeperComponentBase
- {
- // is there a chunk reservation query in flight?
- bool ChunkReserveInFlight = false;
-
- // number of reserved, but uncommitted chunks
- ui32 NumReservedUncommittedChunks = 0;
-
- public:
- TAllocator(TKeeper& keeper);
- ~TAllocator();
-
- // this function is called whenever intent queue item is used; it checks if actor should allocate more chunks
- // for operation
- void CheckForAllocationNeed(const TActorContext& ctx);
-
- // callback function that is invoked on chunk reservation success/failure; this function is called by keeper
- // on TEvChunkWriteResult event reception
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TAllocator
+ : public TKeeperComponentBase
+ {
+ // is there a chunk reservation query in flight?
+ bool ChunkReserveInFlight = false;
+
+ // number of reserved, but uncommitted chunks
+ ui32 NumReservedUncommittedChunks = 0;
+
+ public:
+ TAllocator(TKeeper& keeper);
+ ~TAllocator();
+
+ // this function is called whenever intent queue item is used; it checks if actor should allocate more chunks
+ // for operation
+ void CheckForAllocationNeed(const TActorContext& ctx);
+
+ // callback function that is invoked on chunk reservation success/failure; this function is called by keeper
+ // on TEvChunkWriteResult event reception
void ApplyAllocate(NKikimrProto::EReplyStatus status, TVector<TChunkIdx>&& chunks, const TActorContext& ctx);
- };
-
- } // NIncrHuge
-} // NKikimr
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.cpp
index 759e1cc33e2..1c4188f1871 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.cpp
@@ -1,13 +1,13 @@
-#include "incrhuge_keeper_common.h"
-#include "incrhuge_keeper.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TKeeperComponentBase::TKeeperComponentBase(TKeeper& keeper, const char *name)
- : Keeper(keeper)
- , LogPrefix(Sprintf("[PDisk# %09" PRIu32 " %s] ", Keeper.State.Settings.PDiskId, name))
- {}
-
- } // NIncrHuge
-} // NKikimr
+#include "incrhuge_keeper_common.h"
+#include "incrhuge_keeper.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TKeeperComponentBase::TKeeperComponentBase(TKeeper& keeper, const char *name)
+ : Keeper(keeper)
+ , LogPrefix(Sprintf("[PDisk# %09" PRIu32 " %s] ", Keeper.State.Settings.PDiskId, name))
+ {}
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.h
index bc9f706f26b..7fe03baf2c4 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_common.h
@@ -1,309 +1,309 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_id_dict.h"
-#include "incrhuge_data.h"
-
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_id_dict.h"
+#include "incrhuge_data.h"
+
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
#include <ydb/core/protos/blobstorage_vdisk_internal.pb.h>
-
-#include <util/generic/queue.h>
-#include <util/generic/hash_set.h>
-
-#define IHLOG_DEBUG(CTX, ...) LOG_DEBUG_S((CTX), NKikimrServices::BS_INCRHUGE, LogPrefix << Sprintf(__VA_ARGS__))
-#define IHLOG_INFO(CTX, ...) LOG_INFO_S((CTX), NKikimrServices::BS_INCRHUGE, LogPrefix << Sprintf(__VA_ARGS__))
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TKeeper;
- struct TBlobIndexHeader;
- struct TBlobIndexRecord;
-
- // initial incremental huge keeper settings
- struct TKeeperSettings {
- ui32 PDiskId; // PDisk id
+
+#include <util/generic/queue.h>
+#include <util/generic/hash_set.h>
+
+#define IHLOG_DEBUG(CTX, ...) LOG_DEBUG_S((CTX), NKikimrServices::BS_INCRHUGE, LogPrefix << Sprintf(__VA_ARGS__))
+#define IHLOG_INFO(CTX, ...) LOG_INFO_S((CTX), NKikimrServices::BS_INCRHUGE, LogPrefix << Sprintf(__VA_ARGS__))
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TKeeper;
+ struct TBlobIndexHeader;
+ struct TBlobIndexRecord;
+
+ // initial incremental huge keeper settings
+ struct TKeeperSettings {
+ ui32 PDiskId; // PDisk id
TActorId PDiskActorId; // PDisk actor id
- ui64 PDiskGuid; // PDisk GUID
- ui32 MinHugeBlobInBytes; // minimal blob size we will receive
- ui32 MinCleanChunks; // minimal number of clean chunks we will hold
- ui32 MinAllocationBatch; // minimal number of chunks we will request for
- ui32 UnalignedBlockSize; // preferred block size; will rounded up to AppendBlockSize to get BlockSize
- ui32 MaxInFlightWrites; // maximal number of in flight blob writes
- NPDisk::TOwnerRound InitOwnerRound; // initial owner round
- };
-
- enum class EDiskState {
- SpaceRed, // we can't do anything
- SpaceOrange, // we don't accept new writes
- SpaceYellow, // we enforce defragmentation
- SpaceGreen, // we work as usual
- };
-
- enum class EChunkState {
- Complete, // chunk with data and index written
- Finalizing, // index write in progress, data written
- Current, // writing data
- WriteIntent, // going to write data in not so distant future
- Deleting, // chunk is going to be deleted
- Unknown, // going to determine real state
- };
-
- inline const char *ChunkStateToString(EChunkState state) {
- switch (state) {
- case EChunkState::Complete: return "Complete";
- case EChunkState::Finalizing: return "Finalizing";
- case EChunkState::Current: return "Current";
- case EChunkState::WriteIntent: return "WriteIntent";
- case EChunkState::Deleting: return "Deleting";
- case EChunkState::Unknown: return "Unknown";
- }
- Y_FAIL("unexpected case");
- }
-
- // per chunk information structure
- struct TChunkInfo {
- EChunkState State; // chunk state
- TChunkSerNum ChunkSerNum; // unique serial number of this chunk
- ui32 NumUsedBlocks; // number of used blocks
- ui32 NumItems; // index size of this chunk
- TDynBitMap DeletedItems; // bitmap of deleted items; size = MaxBlobsPerChunk
- ui32 InFlightReq; // number of in-flight requests to this chunk
- };
-
- // blob locator structure
- struct TBlobLocator {
- TChunkIdx ChunkIdx; // chunk index
- ui32 OffsetInBlocks; // offset inside chunk in blocks
- ui32 PayloadSize; // size of data payload in bytes
- ui32 IndexInsideChunk : 23; // ordinal number of blob inside containing chunk
- ui32 Owner : 8; // blob owner
- ui32 DeleteInProgress : 1; // this blob is being deleted
-
- std::tuple<TChunkIdx, ui32, ui32, ui32, ui8> AsTuple() const {
- return std::make_tuple(ChunkIdx, OffsetInBlocks, PayloadSize, IndexInsideChunk, Owner);
- }
-
- friend bool operator ==(const TBlobLocator& left, const TBlobLocator& right) {
- return left.AsTuple() == right.AsTuple();
- }
-
- friend bool operator <(const TBlobLocator& left, const TBlobLocator& right) {
- return left.AsTuple() < right.AsTuple();
- }
-
+ ui64 PDiskGuid; // PDisk GUID
+ ui32 MinHugeBlobInBytes; // minimal blob size we will receive
+ ui32 MinCleanChunks; // minimal number of clean chunks we will hold
+ ui32 MinAllocationBatch; // minimal number of chunks we will request for
+ ui32 UnalignedBlockSize; // preferred block size; will rounded up to AppendBlockSize to get BlockSize
+ ui32 MaxInFlightWrites; // maximal number of in flight blob writes
+ NPDisk::TOwnerRound InitOwnerRound; // initial owner round
+ };
+
+ enum class EDiskState {
+ SpaceRed, // we can't do anything
+ SpaceOrange, // we don't accept new writes
+ SpaceYellow, // we enforce defragmentation
+ SpaceGreen, // we work as usual
+ };
+
+ enum class EChunkState {
+ Complete, // chunk with data and index written
+ Finalizing, // index write in progress, data written
+ Current, // writing data
+ WriteIntent, // going to write data in not so distant future
+ Deleting, // chunk is going to be deleted
+ Unknown, // going to determine real state
+ };
+
+ inline const char *ChunkStateToString(EChunkState state) {
+ switch (state) {
+ case EChunkState::Complete: return "Complete";
+ case EChunkState::Finalizing: return "Finalizing";
+ case EChunkState::Current: return "Current";
+ case EChunkState::WriteIntent: return "WriteIntent";
+ case EChunkState::Deleting: return "Deleting";
+ case EChunkState::Unknown: return "Unknown";
+ }
+ Y_FAIL("unexpected case");
+ }
+
+ // per chunk information structure
+ struct TChunkInfo {
+ EChunkState State; // chunk state
+ TChunkSerNum ChunkSerNum; // unique serial number of this chunk
+ ui32 NumUsedBlocks; // number of used blocks
+ ui32 NumItems; // index size of this chunk
+ TDynBitMap DeletedItems; // bitmap of deleted items; size = MaxBlobsPerChunk
+ ui32 InFlightReq; // number of in-flight requests to this chunk
+ };
+
+ // blob locator structure
+ struct TBlobLocator {
+ TChunkIdx ChunkIdx; // chunk index
+ ui32 OffsetInBlocks; // offset inside chunk in blocks
+ ui32 PayloadSize; // size of data payload in bytes
+ ui32 IndexInsideChunk : 23; // ordinal number of blob inside containing chunk
+ ui32 Owner : 8; // blob owner
+ ui32 DeleteInProgress : 1; // this blob is being deleted
+
+ std::tuple<TChunkIdx, ui32, ui32, ui32, ui8> AsTuple() const {
+ return std::make_tuple(ChunkIdx, OffsetInBlocks, PayloadSize, IndexInsideChunk, Owner);
+ }
+
+ friend bool operator ==(const TBlobLocator& left, const TBlobLocator& right) {
+ return left.AsTuple() == right.AsTuple();
+ }
+
+ friend bool operator <(const TBlobLocator& left, const TBlobLocator& right) {
+ return left.AsTuple() < right.AsTuple();
+ }
+
TString ToString() const {
- return Sprintf("{ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32 " PayloadSize# %" PRIu32
- " IndexInsideChunk# %" PRIu32 " Owner# %" PRIu32 " DeleteInProgress# %" PRIu32 "}", ChunkIdx,
- OffsetInBlocks, PayloadSize, IndexInsideChunk, Owner, DeleteInProgress);
- }
- };
-
- // blob delete locator structure
- struct TBlobDeleteLocator {
- TChunkIdx ChunkIdx;
- TChunkSerNum ChunkSerNum;
- TIncrHugeBlobId Id;
- ui32 IndexInsideChunk;
- ui32 SizeInBlocks;
-
- std::tuple<TChunkIdx, TChunkSerNum, TIncrHugeBlobId, ui32, ui32> AsTuple() const {
- return std::make_tuple(ChunkIdx, ChunkSerNum, Id, IndexInsideChunk, SizeInBlocks);
- }
-
- friend bool operator ==(const TBlobDeleteLocator& left, const TBlobDeleteLocator& right) {
- return left.AsTuple() == right.AsTuple();
- }
-
- friend bool operator <(const TBlobDeleteLocator& left, const TBlobDeleteLocator& right) {
- return left.AsTuple() < right.AsTuple();
- }
-
+ return Sprintf("{ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32 " PayloadSize# %" PRIu32
+ " IndexInsideChunk# %" PRIu32 " Owner# %" PRIu32 " DeleteInProgress# %" PRIu32 "}", ChunkIdx,
+ OffsetInBlocks, PayloadSize, IndexInsideChunk, Owner, DeleteInProgress);
+ }
+ };
+
+ // blob delete locator structure
+ struct TBlobDeleteLocator {
+ TChunkIdx ChunkIdx;
+ TChunkSerNum ChunkSerNum;
+ TIncrHugeBlobId Id;
+ ui32 IndexInsideChunk;
+ ui32 SizeInBlocks;
+
+ std::tuple<TChunkIdx, TChunkSerNum, TIncrHugeBlobId, ui32, ui32> AsTuple() const {
+ return std::make_tuple(ChunkIdx, ChunkSerNum, Id, IndexInsideChunk, SizeInBlocks);
+ }
+
+ friend bool operator ==(const TBlobDeleteLocator& left, const TBlobDeleteLocator& right) {
+ return left.AsTuple() == right.AsTuple();
+ }
+
+ friend bool operator <(const TBlobDeleteLocator& left, const TBlobDeleteLocator& right) {
+ return left.AsTuple() < right.AsTuple();
+ }
+
TString ToString() const {
- return Sprintf("{ChunkIdx# %" PRIu32 " ChunkSerNum# %s Id# %016" PRIx64 " IndexInsideChunk# %"
+ return Sprintf("{ChunkIdx# %" PRIu32 " ChunkSerNum# %s Id# %016" PRIx64 " IndexInsideChunk# %"
PRIu32 " SizeInBlocks# %" PRIu32 "}", ChunkIdx, ChunkSerNum.ToString().data(), Id, IndexInsideChunk,
- SizeInBlocks);
- }
- };
-
- struct TKeeperCommonState : public TThrRefBase {
- // initial keeper settings
- const TKeeperSettings Settings;
-
- // pdisk parameters acquired after yard init
- TIntrusivePtr<TPDiskParams> PDiskParams;
-
- ////////////////////////////
- // Operational parameters //
- ////////////////////////////
-
- ui32 BlockSize = 0; // block size in bytes
- ui32 BlocksInChunk = 0; // chunk size in blocks
- ui32 MaxBlobsPerChunk = 0; // maximal number of blobs in one chunk
- ui32 BlocksInDataSection = 0; // data section size in blocks
- ui32 BlocksInIndexSection = 0; // index section size in blocks
- ui32 BlocksInMinBlob = 0; // number of blocks in minimal blob
-
- // current id of this state; recovered from the last chunk log records and incremented for each allocated
- // chunk
- TChunkSerNum CurrentSerNum{1000};
-
- // disk space state
- EDiskState DiskState = EDiskState::SpaceGreen;
-
- ///////////////////////
- // Blob location map //
- ///////////////////////
-
- TIdLookupTable<TBlobLocator, ui16, 4096> BlobLookup;
-
- ///////////////
- // Chunk map //
- ///////////////
-
- // list of all chunks (including current one)
+ SizeInBlocks);
+ }
+ };
+
+ struct TKeeperCommonState : public TThrRefBase {
+ // initial keeper settings
+ const TKeeperSettings Settings;
+
+ // pdisk parameters acquired after yard init
+ TIntrusivePtr<TPDiskParams> PDiskParams;
+
+ ////////////////////////////
+ // Operational parameters //
+ ////////////////////////////
+
+ ui32 BlockSize = 0; // block size in bytes
+ ui32 BlocksInChunk = 0; // chunk size in blocks
+ ui32 MaxBlobsPerChunk = 0; // maximal number of blobs in one chunk
+ ui32 BlocksInDataSection = 0; // data section size in blocks
+ ui32 BlocksInIndexSection = 0; // index section size in blocks
+ ui32 BlocksInMinBlob = 0; // number of blocks in minimal blob
+
+ // current id of this state; recovered from the last chunk log records and incremented for each allocated
+ // chunk
+ TChunkSerNum CurrentSerNum{1000};
+
+ // disk space state
+ EDiskState DiskState = EDiskState::SpaceGreen;
+
+ ///////////////////////
+ // Blob location map //
+ ///////////////////////
+
+ TIdLookupTable<TBlobLocator, ui16, 4096> BlobLookup;
+
+ ///////////////
+ // Chunk map //
+ ///////////////
+
+ // list of all chunks (including current one)
THashMap<TChunkIdx, TChunkInfo> Chunks;
-
- /////////////////////////
- // Writer shared state //
- /////////////////////////
-
- // the chunk index writer is currently writing to; if zero then there is no active chunk
- TChunkIdx CurrentChunk = 0;
-
- // write intent queue; contains a list of chunks we are going to fill in the near future; these all chunks
- // are confirmed, that is they have correspoding TCommitRecord successfully logged; each entry has
- // corresponding item in Chunks
+
+ /////////////////////////
+ // Writer shared state //
+ /////////////////////////
+
+ // the chunk index writer is currently writing to; if zero then there is no active chunk
+ TChunkIdx CurrentChunk = 0;
+
+ // write intent queue; contains a list of chunks we are going to fill in the near future; these all chunks
+ // are confirmed, that is they have correspoding TCommitRecord successfully logged; each entry has
+ // corresponding item in Chunks
TQueue<TChunkIdx> WriteIntentQueue;
-
- // is blob keeper ready?
- bool Ready = false;
-
- // number of in-flight writes
- ui32 InFlightWrites = 0;
-
- // set of defragmenter items being written right now
+
+ // is blob keeper ready?
+ bool Ready = false;
+
+ // number of in-flight writes
+ ui32 InFlightWrites = 0;
+
+ // set of defragmenter items being written right now
THashMap<TIncrHugeBlobId, bool> DefragWriteInProgress;
-
- // set of spawned children actors
+
+ // set of spawned children actors
THashSet<TActorId> ChildActors;
-
- TKeeperCommonState(const TKeeperSettings& settings)
- : Settings(settings)
- {}
-
- // calculate number of blocks occupied by a single blob
- ui32 GetBlobSizeInBlocks(ui32 payloadSize) const {
- return (sizeof(TBlobHeader) + payloadSize + BlockSize - 1) / BlockSize;
- }
- };
-
- // event callback base; it is a class that holds some data and has an apply function which is called when
- // log entry is written or write is failed or for other event; uses NALF incremental allocator, because it
- // is short-term object
+
+ TKeeperCommonState(const TKeeperSettings& settings)
+ : Settings(settings)
+ {}
+
+ // calculate number of blocks occupied by a single blob
+ ui32 GetBlobSizeInBlocks(ui32 payloadSize) const {
+ return (sizeof(TBlobHeader) + payloadSize + BlockSize - 1) / BlockSize;
+ }
+ };
+
+ // event callback base; it is a class that holds some data and has an apply function which is called when
+ // log entry is written or write is failed or for other event; uses NALF incremental allocator, because it
+ // is short-term object
class IEventCallback {
- public:
- virtual ~IEventCallback() = default;
- virtual void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) = 0;
- };
-
- // lambda callback wrapper, for convenience
- template<typename TFunctor>
- class TLambdaEventCallback : public IEventCallback {
- TFunctor Functor;
-
- public:
- TLambdaEventCallback(TFunctor&& functor)
- : Functor(std::move(functor))
- {}
-
- void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) override {
- Functor(status, result, ctx);
- }
- };
-
- // simple lambda callback wrapper -- for messages not using result
- template<typename TFunctor>
- class TSimpleLambdaEventCallback : public IEventCallback {
- TFunctor Functor;
-
- public:
- TSimpleLambdaEventCallback(TFunctor&& functor)
- : Functor(std::move(functor))
- {}
-
- void Apply(NKikimrProto::EReplyStatus status, IEventBase* /*result*/, const TActorContext& ctx) override {
- Functor(status, ctx);
- }
- };
-
- template<typename TFunctor>
- inline std::unique_ptr<IEventCallback> MakeCallback(TFunctor&& functor) {
- return std::make_unique<TLambdaEventCallback<TFunctor>>(std::move(functor));
- }
-
- template<typename TFunctor>
- inline std::unique_ptr<IEventCallback> MakeSimpleCallback(TFunctor&& functor) {
- return std::make_unique<TSimpleLambdaEventCallback<TFunctor>>(std::move(functor));
- }
-
- // callback demultiplexer
- class TMuxCallback : public IEventCallback {
- TVector<std::unique_ptr<IEventCallback>> Callbacks;
-
- public:
- TMuxCallback(TVector<std::unique_ptr<IEventCallback>>&& callbacks)
- : Callbacks(std::move(callbacks))
- {}
-
- void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) override {
- for (auto& callback : Callbacks) {
- callback->Apply(status, result, ctx);
- }
- }
- };
-
- class TKeeperComponentBase {
- protected:
- // keeper itself
- TKeeper& Keeper;
-
- // log prefix
+ public:
+ virtual ~IEventCallback() = default;
+ virtual void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) = 0;
+ };
+
+ // lambda callback wrapper, for convenience
+ template<typename TFunctor>
+ class TLambdaEventCallback : public IEventCallback {
+ TFunctor Functor;
+
+ public:
+ TLambdaEventCallback(TFunctor&& functor)
+ : Functor(std::move(functor))
+ {}
+
+ void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) override {
+ Functor(status, result, ctx);
+ }
+ };
+
+ // simple lambda callback wrapper -- for messages not using result
+ template<typename TFunctor>
+ class TSimpleLambdaEventCallback : public IEventCallback {
+ TFunctor Functor;
+
+ public:
+ TSimpleLambdaEventCallback(TFunctor&& functor)
+ : Functor(std::move(functor))
+ {}
+
+ void Apply(NKikimrProto::EReplyStatus status, IEventBase* /*result*/, const TActorContext& ctx) override {
+ Functor(status, ctx);
+ }
+ };
+
+ template<typename TFunctor>
+ inline std::unique_ptr<IEventCallback> MakeCallback(TFunctor&& functor) {
+ return std::make_unique<TLambdaEventCallback<TFunctor>>(std::move(functor));
+ }
+
+ template<typename TFunctor>
+ inline std::unique_ptr<IEventCallback> MakeSimpleCallback(TFunctor&& functor) {
+ return std::make_unique<TSimpleLambdaEventCallback<TFunctor>>(std::move(functor));
+ }
+
+ // callback demultiplexer
+ class TMuxCallback : public IEventCallback {
+ TVector<std::unique_ptr<IEventCallback>> Callbacks;
+
+ public:
+ TMuxCallback(TVector<std::unique_ptr<IEventCallback>>&& callbacks)
+ : Callbacks(std::move(callbacks))
+ {}
+
+ void Apply(NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) override {
+ for (auto& callback : Callbacks) {
+ callback->Apply(status, result, ctx);
+ }
+ }
+ };
+
+ class TKeeperComponentBase {
+ protected:
+ // keeper itself
+ TKeeper& Keeper;
+
+ // log prefix
TString LogPrefix;
-
- public:
- TKeeperComponentBase(TKeeper& keeper, const char *name);
- };
-
- // callback event; handled by keeper by invoking this callback :-)
- struct TEvIncrHugeCallback : public TEventLocal<TEvIncrHugeCallback, TEvBlobStorage::EvIncrHugeCallback> {
- std::unique_ptr<IEventCallback> Callback;
-
- TEvIncrHugeCallback(std::unique_ptr<IEventCallback>&& callback)
- : Callback(std::move(callback))
- {}
- };
-
- struct TEvIncrHugeReadLogResult
- : public TEventLocal<TEvIncrHugeReadLogResult, TEvBlobStorage::EvIncrHugeReadLogResult>
- {
- NKikimrProto::EReplyStatus Status;
- NKikimrVDiskData::TIncrHugeChunks Chunks;
- NKikimrVDiskData::TIncrHugeDelete Deletes;
- ui64 NextLsn;
- bool IssueInitialStartingPoints;
- };
-
- struct TEvIncrHugeScanResult
- : public TEventLocal<TEvIncrHugeScanResult, TEvBlobStorage::EvIncrHugeScanResult>
- {
- NKikimrProto::EReplyStatus Status;
+
+ public:
+ TKeeperComponentBase(TKeeper& keeper, const char *name);
+ };
+
+ // callback event; handled by keeper by invoking this callback :-)
+ struct TEvIncrHugeCallback : public TEventLocal<TEvIncrHugeCallback, TEvBlobStorage::EvIncrHugeCallback> {
+ std::unique_ptr<IEventCallback> Callback;
+
+ TEvIncrHugeCallback(std::unique_ptr<IEventCallback>&& callback)
+ : Callback(std::move(callback))
+ {}
+ };
+
+ struct TEvIncrHugeReadLogResult
+ : public TEventLocal<TEvIncrHugeReadLogResult, TEvBlobStorage::EvIncrHugeReadLogResult>
+ {
+ NKikimrProto::EReplyStatus Status;
+ NKikimrVDiskData::TIncrHugeChunks Chunks;
+ NKikimrVDiskData::TIncrHugeDelete Deletes;
+ ui64 NextLsn;
+ bool IssueInitialStartingPoints;
+ };
+
+ struct TEvIncrHugeScanResult
+ : public TEventLocal<TEvIncrHugeScanResult, TEvBlobStorage::EvIncrHugeScanResult>
+ {
+ NKikimrProto::EReplyStatus Status;
TVector<TBlobIndexRecord> Index;
- TChunkIdx ChunkIdx;
- bool IndexOnly;
- TChunkSerNum ChunkSerNum;
- bool IndexValid;
- };
-
- } // NIncrHuge
-} // NKikimr
+ TChunkIdx ChunkIdx;
+ bool IndexOnly;
+ TChunkSerNum ChunkSerNum;
+ bool IndexValid;
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.cpp
index 0cb43beb2ad..a52e5dfc257 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.cpp
@@ -1,297 +1,297 @@
-#include "incrhuge_keeper_defrag.h"
-#include "incrhuge_keeper.h"
-#include "incrhuge_keeper_recovery_scan.h"
+#include "incrhuge_keeper_defrag.h"
+#include "incrhuge_keeper.h"
+#include "incrhuge_keeper_recovery_scan.h"
#include <library/cpp/digest/crc32c/crc32c.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TDefragmenter::TDefragmenter(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Defragmenter")
- {
- Threshold = 0.8;
- }
-
- TDefragmenter::~TDefragmenter()
- {}
-
- void TDefragmenter::HandleControlDefrag(TEvIncrHugeControlDefrag::TPtr& ev, const TActorContext& ctx) {
- Threshold = ev->Get()->Threshold;
- for (const auto& pair : Keeper.State.Chunks) {
- UpdateChunkState(pair.first, ctx);
- }
- }
-
- void TDefragmenter::UpdateChunkState(TChunkIdx /*chunkIdx*/, const TActorContext& ctx) {
- ProcessPendingChunksQueue(ctx);
- }
-
- void TDefragmenter::InFlightWritesChanged(const TActorContext& ctx) {
- ProcessPendingChunksQueue(ctx);
- }
-
- void TDefragmenter::ProcessPendingChunksQueue(const TActorContext& ctx) {
- // do not process more than 1 chunk at once
- if (ChunkInProgress || InFlightReads || InFlightWrites || !Keeper.State.Ready || Keeper.State.InFlightWrites > 3) {
- return;
- }
-
- // calculate total efficiency
- ui64 numUsedBlocks = 0;
- for (const auto& pair : Keeper.State.Chunks) {
- const TChunkInfo& chunk = pair.second;
- numUsedBlocks += chunk.NumUsedBlocks;
- }
- double efficiency = (double)numUsedBlocks / (Keeper.State.Chunks.size() * Keeper.State.BlocksInDataSection);
- IHLOG_DEBUG(ctx, "overall efficiency %.3lf", efficiency);
- if (efficiency >= Threshold) {
- return;
- }
-
- // find worst chunk
- double worstEfficiency = 1.0;
- for (const auto& pair : Keeper.State.Chunks) {
- const TChunkIdx chunkIdx = pair.first;
- const TChunkInfo& chunk = pair.second;
-
- if (chunk.State != EChunkState::Complete) {
- // ignore other kinds of chunks, they're not ready for defragmentation yet
- continue;
- }
-
- // calculate efficiency and choose the worst one
- const double efficiency = (double)chunk.NumUsedBlocks / Keeper.State.BlocksInDataSection;
- if (efficiency < worstEfficiency || !ChunkInProgress) {
- ChunkInProgress = chunkIdx;
- ChunkInProgressSerNum = chunk.ChunkSerNum;
- worstEfficiency = efficiency;
- }
- }
-
- // if there were no chunk selected, exit
- if (!ChunkInProgress) {
- return;
- }
-
- // notify
- IHLOG_DEBUG(ctx, "starting ChunkInProgress# %" PRIu32 " efficiency# %.3lf", ChunkInProgress, worstEfficiency);
-
- // create chunk scanner to read index
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TDefragmenter::TDefragmenter(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Defragmenter")
+ {
+ Threshold = 0.8;
+ }
+
+ TDefragmenter::~TDefragmenter()
+ {}
+
+ void TDefragmenter::HandleControlDefrag(TEvIncrHugeControlDefrag::TPtr& ev, const TActorContext& ctx) {
+ Threshold = ev->Get()->Threshold;
+ for (const auto& pair : Keeper.State.Chunks) {
+ UpdateChunkState(pair.first, ctx);
+ }
+ }
+
+ void TDefragmenter::UpdateChunkState(TChunkIdx /*chunkIdx*/, const TActorContext& ctx) {
+ ProcessPendingChunksQueue(ctx);
+ }
+
+ void TDefragmenter::InFlightWritesChanged(const TActorContext& ctx) {
+ ProcessPendingChunksQueue(ctx);
+ }
+
+ void TDefragmenter::ProcessPendingChunksQueue(const TActorContext& ctx) {
+ // do not process more than 1 chunk at once
+ if (ChunkInProgress || InFlightReads || InFlightWrites || !Keeper.State.Ready || Keeper.State.InFlightWrites > 3) {
+ return;
+ }
+
+ // calculate total efficiency
+ ui64 numUsedBlocks = 0;
+ for (const auto& pair : Keeper.State.Chunks) {
+ const TChunkInfo& chunk = pair.second;
+ numUsedBlocks += chunk.NumUsedBlocks;
+ }
+ double efficiency = (double)numUsedBlocks / (Keeper.State.Chunks.size() * Keeper.State.BlocksInDataSection);
+ IHLOG_DEBUG(ctx, "overall efficiency %.3lf", efficiency);
+ if (efficiency >= Threshold) {
+ return;
+ }
+
+ // find worst chunk
+ double worstEfficiency = 1.0;
+ for (const auto& pair : Keeper.State.Chunks) {
+ const TChunkIdx chunkIdx = pair.first;
+ const TChunkInfo& chunk = pair.second;
+
+ if (chunk.State != EChunkState::Complete) {
+ // ignore other kinds of chunks, they're not ready for defragmentation yet
+ continue;
+ }
+
+ // calculate efficiency and choose the worst one
+ const double efficiency = (double)chunk.NumUsedBlocks / Keeper.State.BlocksInDataSection;
+ if (efficiency < worstEfficiency || !ChunkInProgress) {
+ ChunkInProgress = chunkIdx;
+ ChunkInProgressSerNum = chunk.ChunkSerNum;
+ worstEfficiency = efficiency;
+ }
+ }
+
+ // if there were no chunk selected, exit
+ if (!ChunkInProgress) {
+ return;
+ }
+
+ // notify
+ IHLOG_DEBUG(ctx, "starting ChunkInProgress# %" PRIu32 " efficiency# %.3lf", ChunkInProgress, worstEfficiency);
+
+ // create chunk scanner to read index
const TActorId actorId = ctx.Register(CreateRecoveryScanActor(ChunkInProgress, true, ChunkInProgressSerNum,
- static_cast<ui64>(EScanCookie::Defrag), Keeper.State), TMailboxType::HTSwap, AppData(ctx)->BatchPoolId);
- const bool inserted = Keeper.State.ChildActors.insert(actorId).second;
- Y_VERIFY(inserted);
- }
-
- TChunkInfo *TDefragmenter::CheckCurrentChunk(const TActorContext& ctx) {
- Y_VERIFY(ChunkInProgress);
- auto it = Keeper.State.Chunks.find(ChunkInProgress);
- if (it == Keeper.State.Chunks.end() || it->second.ChunkSerNum != ChunkInProgressSerNum ||
- it->second.State == EChunkState::Deleting) {
- // chunk is either not found nor has version mismatch -- this means that our original chunk we were
- // working with is gone now
- FinishChunkInProgress(ctx);
- return nullptr;
- } else {
- Y_VERIFY(it->second.State == EChunkState::Complete);
- return &it->second;
- }
- }
-
+ static_cast<ui64>(EScanCookie::Defrag), Keeper.State), TMailboxType::HTSwap, AppData(ctx)->BatchPoolId);
+ const bool inserted = Keeper.State.ChildActors.insert(actorId).second;
+ Y_VERIFY(inserted);
+ }
+
+ TChunkInfo *TDefragmenter::CheckCurrentChunk(const TActorContext& ctx) {
+ Y_VERIFY(ChunkInProgress);
+ auto it = Keeper.State.Chunks.find(ChunkInProgress);
+ if (it == Keeper.State.Chunks.end() || it->second.ChunkSerNum != ChunkInProgressSerNum ||
+ it->second.State == EChunkState::Deleting) {
+ // chunk is either not found nor has version mismatch -- this means that our original chunk we were
+ // working with is gone now
+ FinishChunkInProgress(ctx);
+ return nullptr;
+ } else {
+ Y_VERIFY(it->second.State == EChunkState::Complete);
+ return &it->second;
+ }
+ }
+
void TDefragmenter::ApplyScan(const TActorId& sender, TEvIncrHugeScanResult& msg, const TActorContext& ctx) {
- const size_t num = Keeper.State.ChildActors.erase(sender);
- Y_VERIFY(num == 1);
-
- IHLOG_DEBUG(ctx, "ApplyScan received");
-
- if (!CheckCurrentChunk(ctx)) {
- // if this chunk is finished, then we have nothing to do with this reply, simply ignore it
- return;
- }
-
- Y_VERIFY(msg.Status == NKikimrProto::OK);
-
- // generate some messages to read blobs
- Index = std::move(msg.Index);
- IndexPos = 0;
- OffsetInBlocks = 0;
- ProcessIndex(ctx);
- }
-
- void TDefragmenter::ProcessIndex(const TActorContext& ctx) {
- TChunkInfo *chunkPtr = CheckCurrentChunk(ctx);
- if (!chunkPtr) {
- return;
- }
- TChunkInfo& chunk = *chunkPtr;
-
- // process current index until there are records to process
+ const size_t num = Keeper.State.ChildActors.erase(sender);
+ Y_VERIFY(num == 1);
+
+ IHLOG_DEBUG(ctx, "ApplyScan received");
+
+ if (!CheckCurrentChunk(ctx)) {
+ // if this chunk is finished, then we have nothing to do with this reply, simply ignore it
+ return;
+ }
+
+ Y_VERIFY(msg.Status == NKikimrProto::OK);
+
+ // generate some messages to read blobs
+ Index = std::move(msg.Index);
+ IndexPos = 0;
+ OffsetInBlocks = 0;
+ ProcessIndex(ctx);
+ }
+
+ void TDefragmenter::ProcessIndex(const TActorContext& ctx) {
+ TChunkInfo *chunkPtr = CheckCurrentChunk(ctx);
+ if (!chunkPtr) {
+ return;
+ }
+ TChunkInfo& chunk = *chunkPtr;
+
+ // process current index until there are records to process
while (IndexPos < Index.size() && InFlightReads < MaxInFlightReads && InFlightReadBytes < MaxInFlightReadBytes
- && InFlightWrites < MaxInFlightWrites) {
- // get record header
- const TBlobIndexRecord& record = Index[IndexPos];
-
- // calculate number of blocks this blob occupies
- const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(record.PayloadSize);
-
- // check if this record is not deleted
- if (!chunk.DeletedItems.Get(IndexPos)) {
- // find locator for this blob and check if is still points here
- const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(record.Id);
- Y_VERIFY(locator.ChunkIdx == ChunkInProgress);
- Y_VERIFY(locator.OffsetInBlocks == OffsetInBlocks);
- Y_VERIFY(locator.PayloadSize == record.PayloadSize);
- Y_VERIFY(locator.IndexInsideChunk == IndexPos);
- Y_VERIFY(locator.Owner == record.Owner);
-
- // create read callback
- auto callback = [this, record, chunkIdx = ChunkInProgress, chunkSerNum = ChunkInProgressSerNum,
- offsetInBlocks = OffsetInBlocks, index = IndexPos]
- (NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
- ApplyRead(record, chunkIdx, chunkSerNum, offsetInBlocks, index, status,
- *static_cast<NPDisk::TEvChunkReadResult*>(msg), ctx);
- };
-
- // issue read
- const ui32 offset = OffsetInBlocks * Keeper.State.BlockSize;
- const ui32 size = sizeInBlocks * Keeper.State.BlockSize;
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(Keeper.State.PDiskParams->Owner,
- Keeper.State.PDiskParams->OwnerRound, ChunkInProgress, offset, size, NPriRead::HullComp,
- Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
-
- IHLOG_DEBUG(ctx, "sending TEvChunkRead ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32
- " sizeInBlocks# %" PRIu32, ChunkInProgress, OffsetInBlocks, sizeInBlocks);
-
- ++InFlightReads;
- InFlightReadBytes += size;
-
- ++chunk.InFlightReq;
- Y_VERIFY(chunk.State != EChunkState::Deleting);
- }
-
- // advance index and update offset in blocks
- ++IndexPos;
- OffsetInBlocks += sizeInBlocks;
- }
-
- // if current chunks ends and there are no more reads in flight, time to switch to another chunk
+ && InFlightWrites < MaxInFlightWrites) {
+ // get record header
+ const TBlobIndexRecord& record = Index[IndexPos];
+
+ // calculate number of blocks this blob occupies
+ const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(record.PayloadSize);
+
+ // check if this record is not deleted
+ if (!chunk.DeletedItems.Get(IndexPos)) {
+ // find locator for this blob and check if is still points here
+ const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(record.Id);
+ Y_VERIFY(locator.ChunkIdx == ChunkInProgress);
+ Y_VERIFY(locator.OffsetInBlocks == OffsetInBlocks);
+ Y_VERIFY(locator.PayloadSize == record.PayloadSize);
+ Y_VERIFY(locator.IndexInsideChunk == IndexPos);
+ Y_VERIFY(locator.Owner == record.Owner);
+
+ // create read callback
+ auto callback = [this, record, chunkIdx = ChunkInProgress, chunkSerNum = ChunkInProgressSerNum,
+ offsetInBlocks = OffsetInBlocks, index = IndexPos]
+ (NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
+ ApplyRead(record, chunkIdx, chunkSerNum, offsetInBlocks, index, status,
+ *static_cast<NPDisk::TEvChunkReadResult*>(msg), ctx);
+ };
+
+ // issue read
+ const ui32 offset = OffsetInBlocks * Keeper.State.BlockSize;
+ const ui32 size = sizeInBlocks * Keeper.State.BlockSize;
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(Keeper.State.PDiskParams->Owner,
+ Keeper.State.PDiskParams->OwnerRound, ChunkInProgress, offset, size, NPriRead::HullComp,
+ Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
+
+ IHLOG_DEBUG(ctx, "sending TEvChunkRead ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32
+ " sizeInBlocks# %" PRIu32, ChunkInProgress, OffsetInBlocks, sizeInBlocks);
+
+ ++InFlightReads;
+ InFlightReadBytes += size;
+
+ ++chunk.InFlightReq;
+ Y_VERIFY(chunk.State != EChunkState::Deleting);
+ }
+
+ // advance index and update offset in blocks
+ ++IndexPos;
+ OffsetInBlocks += sizeInBlocks;
+ }
+
+ // if current chunks ends and there are no more reads in flight, time to switch to another chunk
if (IndexPos == Index.size() && !InFlightReads && !InFlightWrites) {
- Y_VERIFY(chunk.State == EChunkState::Complete);
- FinishChunkInProgress(ctx);
- }
- }
-
- void TDefragmenter::ApplyRead(const TBlobIndexRecord& record, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
- ui32 offsetInBlocks, ui32 index, NKikimrProto::EReplyStatus status, NPDisk::TEvChunkReadResult& result,
- const TActorContext& ctx) {
- const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(record.PayloadSize);
- const ui32 totalSize = sizeof(TBlobHeader) + record.PayloadSize;
-
- IHLOG_DEBUG(ctx, "ApplyRead offsetInBlocks# %" PRIu32 " index# %" PRIu32 " Status# %s", offsetInBlocks,
+ Y_VERIFY(chunk.State == EChunkState::Complete);
+ FinishChunkInProgress(ctx);
+ }
+ }
+
+ void TDefragmenter::ApplyRead(const TBlobIndexRecord& record, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
+ ui32 offsetInBlocks, ui32 index, NKikimrProto::EReplyStatus status, NPDisk::TEvChunkReadResult& result,
+ const TActorContext& ctx) {
+ const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(record.PayloadSize);
+ const ui32 totalSize = sizeof(TBlobHeader) + record.PayloadSize;
+
+ IHLOG_DEBUG(ctx, "ApplyRead offsetInBlocks# %" PRIu32 " index# %" PRIu32 " Status# %s", offsetInBlocks,
index, NKikimrProto::EReplyStatus_Name(status).data());
-
- // adjust number of in-flight requests
- const ui32 bytes = sizeInBlocks * Keeper.State.BlockSize;
- Y_VERIFY(InFlightReads > 0 && InFlightReadBytes >= bytes);
- --InFlightReads;
- InFlightReadBytes -= bytes;
-
- // remove in-flight request; we may be blocking chunk deletion here (are there were read request to chunk
- // scheduled for deletion); if so and this was the last request, try to delete this chunk again
- auto it = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end() && it->second.ChunkSerNum == chunkSerNum);
- --it->second.InFlightReq;
- if (!it->second.InFlightReq && it->second.State == EChunkState::Deleting) {
- Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
- }
-
- // ignore this answer if this is not our current chunk
- if (chunkIdx != ChunkInProgress || chunkSerNum != ChunkInProgressSerNum) {
- return;
- }
-
- // check if current chunk still intact
- TChunkInfo *chunkPtr = CheckCurrentChunk(ctx);
- if (!chunkPtr) {
- return;
- }
-
- // get a refernce to our chunk
- TChunkInfo& chunk = *chunkPtr;
-
- // check if item wasn't deleted while read was executing
- if (status == NKikimrProto::OK && !chunk.DeletedItems.Get(index) && result.Data.IsReadable(0, sizeof(TBlobHeader))) {
- // lookup blob locator for this item
- const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(record.Id);
-
- // validate this locator
- Y_VERIFY(locator.ChunkIdx == ChunkInProgress && locator.OffsetInBlocks == offsetInBlocks
- && locator.PayloadSize == record.PayloadSize && locator.IndexInsideChunk == index
- && locator.Owner == record.Owner, "locator# %s offsetInBlocks# %" PRIu32 " index# %" PRIu32
+
+ // adjust number of in-flight requests
+ const ui32 bytes = sizeInBlocks * Keeper.State.BlockSize;
+ Y_VERIFY(InFlightReads > 0 && InFlightReadBytes >= bytes);
+ --InFlightReads;
+ InFlightReadBytes -= bytes;
+
+ // remove in-flight request; we may be blocking chunk deletion here (are there were read request to chunk
+ // scheduled for deletion); if so and this was the last request, try to delete this chunk again
+ auto it = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end() && it->second.ChunkSerNum == chunkSerNum);
+ --it->second.InFlightReq;
+ if (!it->second.InFlightReq && it->second.State == EChunkState::Deleting) {
+ Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
+ }
+
+ // ignore this answer if this is not our current chunk
+ if (chunkIdx != ChunkInProgress || chunkSerNum != ChunkInProgressSerNum) {
+ return;
+ }
+
+ // check if current chunk still intact
+ TChunkInfo *chunkPtr = CheckCurrentChunk(ctx);
+ if (!chunkPtr) {
+ return;
+ }
+
+ // get a refernce to our chunk
+ TChunkInfo& chunk = *chunkPtr;
+
+ // check if item wasn't deleted while read was executing
+ if (status == NKikimrProto::OK && !chunk.DeletedItems.Get(index) && result.Data.IsReadable(0, sizeof(TBlobHeader))) {
+ // lookup blob locator for this item
+ const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(record.Id);
+
+ // validate this locator
+ Y_VERIFY(locator.ChunkIdx == ChunkInProgress && locator.OffsetInBlocks == offsetInBlocks
+ && locator.PayloadSize == record.PayloadSize && locator.IndexInsideChunk == index
+ && locator.Owner == record.Owner, "locator# %s offsetInBlocks# %" PRIu32 " index# %" PRIu32
" record# %s", locator.ToString().data(), offsetInBlocks, index, record.ToString().data());
-
- const TBlobHeader& header = *result.Data.DataPtr<const TBlobHeader>(0);
- if (!locator.DeleteInProgress && result.Data.IsReadable(0, totalSize)) {
+
+ const TBlobHeader& header = *result.Data.DataPtr<const TBlobHeader>(0);
+ if (!locator.DeleteInProgress && result.Data.IsReadable(0, totalSize)) {
Y_VERIFY(Crc32c(&header.IndexRecord, totalSize - sizeof(ui32)) == header.Checksum);
- Y_VERIFY(header.IndexRecord == record);
- Y_VERIFY(header.ChunkSerNum == ChunkInProgressSerNum);
+ Y_VERIFY(header.IndexRecord == record);
+ Y_VERIFY(header.ChunkSerNum == ChunkInProgressSerNum);
TString data = header.ExtractInplacePayload();
-
- // fill in delete locator with provided values
- TBlobDeleteLocator deleteLocator{chunkIdx, chunkSerNum, {}, index, sizeInBlocks};
-
- // create callback which will be invoked when write is completed
- auto callback = [this, deleteLocator](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- ApplyWrite(deleteLocator, status, ctx);
- };
-
- // enqueue writer queue item; it should check if item was deleted when starting actual execution
- // of queue item and after writing it
- IHLOG_DEBUG(ctx, "EnqueueDefragWrite chunkIdx# %" PRIu32 " index# %" PRIu32 " Id# %016" PRIx64,
- chunkIdx, index, header.IndexRecord.Id);
- Keeper.Writer.EnqueueDefragWrite(header, chunkIdx, chunk.ChunkSerNum, index, std::move(data),
- MakeSimpleCallback(std::move(callback)), ctx);
- ++InFlightWrites;
- }
- }
-
- // generate some more read requests if it is possible
- ProcessIndex(ctx);
- }
-
- void TDefragmenter::ApplyWrite(const TBlobDeleteLocator& deleteLocator, NKikimrProto::EReplyStatus status,
- const TActorContext& ctx) {
- // RACE is returned when the original item was deleted while write was in waiting in queue or in progress
- if (status != NKikimrProto::RACE) {
- // ensure that write succeeds FIXME: error handling
- Y_VERIFY(status == NKikimrProto::OK);
+
+ // fill in delete locator with provided values
+ TBlobDeleteLocator deleteLocator{chunkIdx, chunkSerNum, {}, index, sizeInBlocks};
+
+ // create callback which will be invoked when write is completed
+ auto callback = [this, deleteLocator](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ ApplyWrite(deleteLocator, status, ctx);
+ };
+
+ // enqueue writer queue item; it should check if item was deleted when starting actual execution
+ // of queue item and after writing it
+ IHLOG_DEBUG(ctx, "EnqueueDefragWrite chunkIdx# %" PRIu32 " index# %" PRIu32 " Id# %016" PRIx64,
+ chunkIdx, index, header.IndexRecord.Id);
+ Keeper.Writer.EnqueueDefragWrite(header, chunkIdx, chunk.ChunkSerNum, index, std::move(data),
+ MakeSimpleCallback(std::move(callback)), ctx);
+ ++InFlightWrites;
+ }
+ }
+
+ // generate some more read requests if it is possible
+ ProcessIndex(ctx);
+ }
+
+ void TDefragmenter::ApplyWrite(const TBlobDeleteLocator& deleteLocator, NKikimrProto::EReplyStatus status,
+ const TActorContext& ctx) {
+ // RACE is returned when the original item was deleted while write was in waiting in queue or in progress
+ if (status != NKikimrProto::RACE) {
+ // ensure that write succeeds FIXME: error handling
+ Y_VERIFY(status == NKikimrProto::OK);
IHLOG_DEBUG(ctx, "generating virtual log record deleteLocator# %s", deleteLocator.ToString().data());
-
- // delete this locator right now; we do not log it, because on recovery it's easy to find
- // duplicate items by their id
- Keeper.Deleter.DeleteDefrag({deleteLocator}, ctx);
-
- auto it = Keeper.State.Chunks.find(deleteLocator.ChunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.DeletedItems.Get(deleteLocator.IndexInsideChunk));
- Y_VERIFY(chunk.ChunkSerNum == deleteLocator.ChunkSerNum);
- }
-
- --InFlightWrites;
- if (ChunkInProgress == deleteLocator.ChunkIdx && ChunkInProgressSerNum == deleteLocator.ChunkSerNum) {
- ProcessIndex(ctx);
- }
- }
-
- void TDefragmenter::FinishChunkInProgress(const TActorContext& ctx) {
- IHLOG_DEBUG(ctx, "finishing ChunkIdx# %" PRIu32 " ChunkSerNum# %s", ChunkInProgress,
+
+ // delete this locator right now; we do not log it, because on recovery it's easy to find
+ // duplicate items by their id
+ Keeper.Deleter.DeleteDefrag({deleteLocator}, ctx);
+
+ auto it = Keeper.State.Chunks.find(deleteLocator.ChunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.DeletedItems.Get(deleteLocator.IndexInsideChunk));
+ Y_VERIFY(chunk.ChunkSerNum == deleteLocator.ChunkSerNum);
+ }
+
+ --InFlightWrites;
+ if (ChunkInProgress == deleteLocator.ChunkIdx && ChunkInProgressSerNum == deleteLocator.ChunkSerNum) {
+ ProcessIndex(ctx);
+ }
+ }
+
+ void TDefragmenter::FinishChunkInProgress(const TActorContext& ctx) {
+ IHLOG_DEBUG(ctx, "finishing ChunkIdx# %" PRIu32 " ChunkSerNum# %s", ChunkInProgress,
ChunkInProgressSerNum.ToString().data());
- ChunkInProgress = 0;
- ChunkInProgressSerNum = {};
- Index.clear();
- ProcessPendingChunksQueue(ctx);
- }
-
- } // NIncrHuge
-} // NKikimr
+ ChunkInProgress = 0;
+ ChunkInProgressSerNum = {};
+ Index.clear();
+ ProcessPendingChunksQueue(ctx);
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.h
index e6bb8355a4f..edeffc65427 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_defrag.h
@@ -1,69 +1,69 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge.h"
-
-#include <util/generic/set.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TDefragmenter
- : public TKeeperComponentBase
- {
- // the current chunk we are defragmenting
- TChunkIdx ChunkInProgress = 0;
-
- // identifier of current chunk to check if it is gone
- TChunkSerNum ChunkInProgressSerNum;
-
- // index of current chunk
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge.h"
+
+#include <util/generic/set.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TDefragmenter
+ : public TKeeperComponentBase
+ {
+ // the current chunk we are defragmenting
+ TChunkIdx ChunkInProgress = 0;
+
+ // identifier of current chunk to check if it is gone
+ TChunkSerNum ChunkInProgressSerNum;
+
+ // index of current chunk
TVector<TBlobIndexRecord> Index;
- ui32 IndexPos = 0;
- ui32 OffsetInBlocks = 0;
-
- // number of in-flight reads
- ui32 InFlightReads = 0;
- const ui32 MaxInFlightReads = 3;
- ui32 InFlightReadBytes = 0;
- const ui32 MaxInFlightReadBytes = 32 << 20;
- ui32 InFlightWrites = 0;
- const ui32 MaxInFlightWrites = 3;
-
- // current threshold
- double Threshold = 0.0;
-
- public:
- TDefragmenter(TKeeper& keeper);
- ~TDefragmenter();
-
- void InFlightWritesChanged(const TActorContext& ctx);
-
- // called when chunk state (in terms of defragmentation) has changed -- chunk was partially/completely
- // cleaned
- void UpdateChunkState(TChunkIdx chunkIdx, const TActorContext& ctx);
-
+ ui32 IndexPos = 0;
+ ui32 OffsetInBlocks = 0;
+
+ // number of in-flight reads
+ ui32 InFlightReads = 0;
+ const ui32 MaxInFlightReads = 3;
+ ui32 InFlightReadBytes = 0;
+ const ui32 MaxInFlightReadBytes = 32 << 20;
+ ui32 InFlightWrites = 0;
+ const ui32 MaxInFlightWrites = 3;
+
+ // current threshold
+ double Threshold = 0.0;
+
+ public:
+ TDefragmenter(TKeeper& keeper);
+ ~TDefragmenter();
+
+ void InFlightWritesChanged(const TActorContext& ctx);
+
+ // called when chunk state (in terms of defragmentation) has changed -- chunk was partially/completely
+ // cleaned
+ void UpdateChunkState(TChunkIdx chunkIdx, const TActorContext& ctx);
+
void ApplyScan(const TActorId& sender, TEvIncrHugeScanResult& msg, const TActorContext& ctx);
-
- void HandleControlDefrag(TEvIncrHugeControlDefrag::TPtr& ev, const TActorContext& ctx);
-
- private:
- void ProcessPendingChunksQueue(const TActorContext& ctx);
-
- void ProcessIndex(const TActorContext& ctx);
-
- void ApplyRead(const TBlobIndexRecord& record, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
- ui32 offsetInBlocks, ui32 index, NKikimrProto::EReplyStatus status,
- NPDisk::TEvChunkReadResult& result, const TActorContext& ctx);
-
- void ApplyWrite(const TBlobDeleteLocator& deleteLocator, NKikimrProto::EReplyStatus status,
- const TActorContext& ctx);
-
- void FinishChunkInProgress(const TActorContext& ctx);
-
- TChunkInfo *CheckCurrentChunk(const TActorContext& ctx);
- };
-
- } // NIncrHuge
-} // NKikimr
+
+ void HandleControlDefrag(TEvIncrHugeControlDefrag::TPtr& ev, const TActorContext& ctx);
+
+ private:
+ void ProcessPendingChunksQueue(const TActorContext& ctx);
+
+ void ProcessIndex(const TActorContext& ctx);
+
+ void ApplyRead(const TBlobIndexRecord& record, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
+ ui32 offsetInBlocks, ui32 index, NKikimrProto::EReplyStatus status,
+ NPDisk::TEvChunkReadResult& result, const TActorContext& ctx);
+
+ void ApplyWrite(const TBlobDeleteLocator& deleteLocator, NKikimrProto::EReplyStatus status,
+ const TActorContext& ctx);
+
+ void FinishChunkInProgress(const TActorContext& ctx);
+
+ TChunkInfo *CheckCurrentChunk(const TActorContext& ctx);
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.cpp
index 141aa8f0b97..931a8dbbd8b 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.cpp
@@ -1,341 +1,341 @@
-#include "incrhuge_keeper_delete.h"
-#include "incrhuge_data.h"
-#include "incrhuge_keeper_log.h"
-#include "incrhuge_keeper.h"
+#include "incrhuge_keeper_delete.h"
+#include "incrhuge_data.h"
+#include "incrhuge_keeper_log.h"
+#include "incrhuge_keeper.h"
#include <ydb/core/protos/blobstorage_vdisk_internal.pb.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- enum class EItemState {
- WaitingForDefrag, // item is waiting for defragmenter to finish its job for involved items
- Ready, // item is ready to be sent to logger
- Processing, // item is waiting for logger to process request
- };
-
- struct TDeleter::TDeleteQueueItem {
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ enum class EItemState {
+ WaitingForDefrag, // item is waiting for defragmenter to finish its job for involved items
+ Ready, // item is ready to be sent to logger
+ Processing, // item is waiting for logger to process request
+ };
+
+ struct TDeleter::TDeleteQueueItem {
const TActorId Sender;
- const ui64 Cookie;
- const ui8 Owner;
- const ui64 SeqNo;
+ const ui64 Cookie;
+ const ui8 Owner;
+ const ui64 SeqNo;
const TVector<TIncrHugeBlobId> Ids;
-
- ui32 NumDefragItems; // number of items being defragmented right now
+
+ ui32 NumDefragItems; // number of items being defragmented right now
TVector<TBlobDeleteLocator> DeleteLocators;
- EItemState State;
- };
-
- TDeleter::TDeleter(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Deleter")
- {
- memset(OwnerToSeqNo.data(), 0, OwnerToSeqNo.size() * sizeof(ui64));
- }
-
- TDeleter::~TDeleter()
- {}
-
- void TDeleter::HandleDelete(TEvIncrHugeDelete::TPtr& ev, const TActorContext& ctx) {
- // get a message plain pointer
- TEvIncrHugeDelete *msg = ev->Get();
-
- // generate message into text log
- auto makeIdList = [&] {
- TStringStream s;
+ EItemState State;
+ };
+
+ TDeleter::TDeleter(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Deleter")
+ {
+ memset(OwnerToSeqNo.data(), 0, OwnerToSeqNo.size() * sizeof(ui64));
+ }
+
+ TDeleter::~TDeleter()
+ {}
+
+ void TDeleter::HandleDelete(TEvIncrHugeDelete::TPtr& ev, const TActorContext& ctx) {
+ // get a message plain pointer
+ TEvIncrHugeDelete *msg = ev->Get();
+
+ // generate message into text log
+ auto makeIdList = [&] {
+ TStringStream s;
for (size_t i = 0; i < msg->Ids.size(); ++i) {
- s << (i == 0 ? "" : " ") << Sprintf("%016" PRIx64, msg->Ids[i]);
- }
- return s.Str();
- };
- IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " HandleDelete Ids# [%s]", msg->Owner, msg->SeqNo,
+ s << (i == 0 ? "" : " ") << Sprintf("%016" PRIx64, msg->Ids[i]);
+ }
+ return s.Str();
+ };
+ IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " HandleDelete Ids# [%s]", msg->Owner, msg->SeqNo,
makeIdList().data());
-
- // verify sequence number -- it should exceed maximum value of stored number and all requests in-flight or
- // else this is duplicate query
- Y_VERIFY(msg->Owner < OwnerToSeqNo.size());
- ui64 ownerSeqNo = OwnerToSeqNo[msg->Owner];
- if (DeleteQueue) {
- const ui64 inFlightSeqNo = DeleteQueue.back().SeqNo;
- Y_VERIFY(inFlightSeqNo > ownerSeqNo, "inFlightSeqNo# %" PRIu64 " ownerSeqNo# %" PRIu64,
- inFlightSeqNo, ownerSeqNo);
- ownerSeqNo = inFlightSeqNo;
- }
- if (msg->SeqNo <= ownerSeqNo) {
- ctx.Send(ev->Sender, new TEvIncrHugeDeleteResult(NKikimrProto::ALREADY), 0, ev->Cookie);
- return;
- }
-
- // create delete queue item
- auto it = DeleteQueue.insert(DeleteQueue.end(), TDeleteQueueItem{
- ev->Sender, // Sender
- ev->Cookie, // Cookie
- msg->Owner, // Owner
- msg->SeqNo, // SeqNo
- std::move(msg->Ids), // Ids
- 0, // NumDefragItems
- {}, // DeleteLocators
- EItemState::Ready, // State
- });
- TDeleteQueueItem& item = *it;
-
- // create delete locators for specified items
- for (TIncrHugeBlobId id : item.Ids) {
- // find locator for item, it must exist
- TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
-
- // mark it as being deleted; ensure that there are no other deletion races
- Y_VERIFY(!locator.DeleteInProgress);
- locator.DeleteInProgress = true;
-
- // check if item is being defragmented right now; if so, we put it into wait queue; otherwise generate
- // delete locator
- auto defragIt = Keeper.State.DefragWriteInProgress.find(id);
- if (defragIt != Keeper.State.DefragWriteInProgress.end()) {
- Y_VERIFY(!defragIt->second);
- defragIt->second = true;
- ++item.NumDefragItems;
- Y_VERIFY(!WriteInProgress.count(id));
- WriteInProgress.emplace(id, it);
- item.State = EItemState::WaitingForDefrag;
- IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " Id# %016" PRIx64 " deferred delete",
- item.Owner, item.SeqNo, id);
- } else {
- // find matching chunk, check that it is not being deleted
- auto it = Keeper.State.Chunks.find(locator.ChunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.State != EChunkState::Deleting);
-
- // check that requested item is not deleted yet
- Y_VERIFY(!chunk.DeletedItems.Get(locator.IndexInsideChunk));
-
- // calculate number of blocks occupied by this blob
- const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(locator.PayloadSize);
-
- // create delete locator entry
- item.DeleteLocators.push_back(TBlobDeleteLocator{locator.ChunkIdx, chunk.ChunkSerNum, id,
- locator.IndexInsideChunk, sizeInBlocks});
- }
- }
-
- // try to process this item
- ProcessDeleteItem(it, ctx);
- }
-
- // this function is invoked as a notification for item that was moved when delete query for it was received
- void TDeleter::OnItemDefragWritten(TIncrHugeBlobId id, const TActorContext& ctx) {
- auto it = WriteInProgress.find(id);
- Y_VERIFY(it != WriteInProgress.end());
- TDeleteQueue::iterator itemIt = it->second;
- WriteInProgress.erase(it);
- TDeleteQueueItem& item = *itemIt;
-
- // obtain new locator for this item
- const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
-
- // get chunk
- auto chunkIt = Keeper.State.Chunks.find(locator.ChunkIdx);
- Y_VERIFY(chunkIt != Keeper.State.Chunks.end());
- TChunkInfo& chunk = chunkIt->second;
-
- // calculate size of this record in blocks
- const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(locator.PayloadSize);
-
- // create delete locator entry
- item.DeleteLocators.push_back(TBlobDeleteLocator{locator.ChunkIdx, chunk.ChunkSerNum, id,
- locator.IndexInsideChunk, sizeInBlocks});
-
- Y_VERIFY(item.NumDefragItems > 0);
- if (!--item.NumDefragItems) {
- IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " delete resumed", item.Owner, item.SeqNo);
- item.State = EItemState::Ready;
- ProcessDeleteItem(itemIt, ctx);
-
- // we have just started processing of one of the items; may be we can kick waiting items after that too?
- for (auto it = std::next(itemIt); it != DeleteQueue.end() && it->State == EItemState::Ready; ++it) {
- ProcessDeleteItem(it, ctx);
- }
- }
- }
-
- // this function is called for every item in delete queue, whether is was generated by user request; it may be
- // called lately after receiving request if one (or more) of items scheduled for deletion were being moved
- // right now; in this case deleter waits for all item moves to finish and actually executes user query
- void TDeleter::ProcessDeleteItem(TDeleteQueue::iterator it, const TActorContext& ctx) {
- TDeleteQueueItem& item = *it;
-
- // if previous item doesn't have 'Processing' state, then do not process this item too -- to keep ordering
- if (it != DeleteQueue.begin() && std::prev(it)->State != EItemState::Processing) {
- return;
- }
- switch (item.State) {
- case EItemState::WaitingForDefrag:
- // we can't process this item yet
- Y_VERIFY(item.NumDefragItems > 0);
- return;
-
- case EItemState::Ready:
- // switch to processing this item
- item.State = EItemState::Processing;
- break;
-
- case EItemState::Processing:
- Y_FAIL("unexpected case");
- }
-
- // ensure that we generated locator for each item
+
+ // verify sequence number -- it should exceed maximum value of stored number and all requests in-flight or
+ // else this is duplicate query
+ Y_VERIFY(msg->Owner < OwnerToSeqNo.size());
+ ui64 ownerSeqNo = OwnerToSeqNo[msg->Owner];
+ if (DeleteQueue) {
+ const ui64 inFlightSeqNo = DeleteQueue.back().SeqNo;
+ Y_VERIFY(inFlightSeqNo > ownerSeqNo, "inFlightSeqNo# %" PRIu64 " ownerSeqNo# %" PRIu64,
+ inFlightSeqNo, ownerSeqNo);
+ ownerSeqNo = inFlightSeqNo;
+ }
+ if (msg->SeqNo <= ownerSeqNo) {
+ ctx.Send(ev->Sender, new TEvIncrHugeDeleteResult(NKikimrProto::ALREADY), 0, ev->Cookie);
+ return;
+ }
+
+ // create delete queue item
+ auto it = DeleteQueue.insert(DeleteQueue.end(), TDeleteQueueItem{
+ ev->Sender, // Sender
+ ev->Cookie, // Cookie
+ msg->Owner, // Owner
+ msg->SeqNo, // SeqNo
+ std::move(msg->Ids), // Ids
+ 0, // NumDefragItems
+ {}, // DeleteLocators
+ EItemState::Ready, // State
+ });
+ TDeleteQueueItem& item = *it;
+
+ // create delete locators for specified items
+ for (TIncrHugeBlobId id : item.Ids) {
+ // find locator for item, it must exist
+ TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
+
+ // mark it as being deleted; ensure that there are no other deletion races
+ Y_VERIFY(!locator.DeleteInProgress);
+ locator.DeleteInProgress = true;
+
+ // check if item is being defragmented right now; if so, we put it into wait queue; otherwise generate
+ // delete locator
+ auto defragIt = Keeper.State.DefragWriteInProgress.find(id);
+ if (defragIt != Keeper.State.DefragWriteInProgress.end()) {
+ Y_VERIFY(!defragIt->second);
+ defragIt->second = true;
+ ++item.NumDefragItems;
+ Y_VERIFY(!WriteInProgress.count(id));
+ WriteInProgress.emplace(id, it);
+ item.State = EItemState::WaitingForDefrag;
+ IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " Id# %016" PRIx64 " deferred delete",
+ item.Owner, item.SeqNo, id);
+ } else {
+ // find matching chunk, check that it is not being deleted
+ auto it = Keeper.State.Chunks.find(locator.ChunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.State != EChunkState::Deleting);
+
+ // check that requested item is not deleted yet
+ Y_VERIFY(!chunk.DeletedItems.Get(locator.IndexInsideChunk));
+
+ // calculate number of blocks occupied by this blob
+ const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(locator.PayloadSize);
+
+ // create delete locator entry
+ item.DeleteLocators.push_back(TBlobDeleteLocator{locator.ChunkIdx, chunk.ChunkSerNum, id,
+ locator.IndexInsideChunk, sizeInBlocks});
+ }
+ }
+
+ // try to process this item
+ ProcessDeleteItem(it, ctx);
+ }
+
+ // this function is invoked as a notification for item that was moved when delete query for it was received
+ void TDeleter::OnItemDefragWritten(TIncrHugeBlobId id, const TActorContext& ctx) {
+ auto it = WriteInProgress.find(id);
+ Y_VERIFY(it != WriteInProgress.end());
+ TDeleteQueue::iterator itemIt = it->second;
+ WriteInProgress.erase(it);
+ TDeleteQueueItem& item = *itemIt;
+
+ // obtain new locator for this item
+ const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
+
+ // get chunk
+ auto chunkIt = Keeper.State.Chunks.find(locator.ChunkIdx);
+ Y_VERIFY(chunkIt != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = chunkIt->second;
+
+ // calculate size of this record in blocks
+ const ui32 sizeInBlocks = Keeper.State.GetBlobSizeInBlocks(locator.PayloadSize);
+
+ // create delete locator entry
+ item.DeleteLocators.push_back(TBlobDeleteLocator{locator.ChunkIdx, chunk.ChunkSerNum, id,
+ locator.IndexInsideChunk, sizeInBlocks});
+
+ Y_VERIFY(item.NumDefragItems > 0);
+ if (!--item.NumDefragItems) {
+ IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " delete resumed", item.Owner, item.SeqNo);
+ item.State = EItemState::Ready;
+ ProcessDeleteItem(itemIt, ctx);
+
+ // we have just started processing of one of the items; may be we can kick waiting items after that too?
+ for (auto it = std::next(itemIt); it != DeleteQueue.end() && it->State == EItemState::Ready; ++it) {
+ ProcessDeleteItem(it, ctx);
+ }
+ }
+ }
+
+ // this function is called for every item in delete queue, whether is was generated by user request; it may be
+ // called lately after receiving request if one (or more) of items scheduled for deletion were being moved
+ // right now; in this case deleter waits for all item moves to finish and actually executes user query
+ void TDeleter::ProcessDeleteItem(TDeleteQueue::iterator it, const TActorContext& ctx) {
+ TDeleteQueueItem& item = *it;
+
+ // if previous item doesn't have 'Processing' state, then do not process this item too -- to keep ordering
+ if (it != DeleteQueue.begin() && std::prev(it)->State != EItemState::Processing) {
+ return;
+ }
+ switch (item.State) {
+ case EItemState::WaitingForDefrag:
+ // we can't process this item yet
+ Y_VERIFY(item.NumDefragItems > 0);
+ return;
+
+ case EItemState::Ready:
+ // switch to processing this item
+ item.State = EItemState::Processing;
+ break;
+
+ case EItemState::Processing:
+ Y_FAIL("unexpected case");
+ }
+
+ // ensure that we generated locator for each item
Y_VERIFY(item.DeleteLocators.size() == item.Ids.size());
-
- // sort locators as needed
- std::sort(item.DeleteLocators.begin(), item.DeleteLocators.end());
-
- // create callback to be invoked upon successful (or unsuccessful) logging of delete record
- auto callback = [this, it](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- TDeleteQueueItem& item = *it;
-
- IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " finished Status# %s",
+
+ // sort locators as needed
+ std::sort(item.DeleteLocators.begin(), item.DeleteLocators.end());
+
+ // create callback to be invoked upon successful (or unsuccessful) logging of delete record
+ auto callback = [this, it](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ TDeleteQueueItem& item = *it;
+
+ IHLOG_DEBUG(ctx, "Owner# %d SeqNo# %" PRIu64 " finished Status# %s",
item.Owner, item.SeqNo, NKikimrProto::EReplyStatus_Name(status).data());
-
- if (status == NKikimrProto::OK) {
- // handle deleted locators; remove them from lookup also
- ProcessDeletedLocators(item.DeleteLocators, true, ctx);
- // update per-owner sequential number; we do this only in case of success
- Y_VERIFY(item.Owner < OwnerToSeqNo.size());
- ui64& ownerSeqNo = OwnerToSeqNo[item.Owner];
- Y_VERIFY(item.SeqNo > ownerSeqNo);
- ownerSeqNo = item.SeqNo;
- } else {
- // if delete fails, then reset deletion flag for scheduled items
- for (TIncrHugeBlobId id : item.Ids) {
- // find locator
- TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
- // ensure delete flag was set and reset it
- Y_VERIFY(locator.DeleteInProgress);
- locator.DeleteInProgress = false;
- }
- }
-
- // send reply to sender
- ctx.Send(item.Sender, new TEvIncrHugeDeleteResult(status), 0, item.Cookie);
-
- // delete queue item
- DeleteQueue.erase(it);
- };
-
- // send request to logger
+
+ if (status == NKikimrProto::OK) {
+ // handle deleted locators; remove them from lookup also
+ ProcessDeletedLocators(item.DeleteLocators, true, ctx);
+ // update per-owner sequential number; we do this only in case of success
+ Y_VERIFY(item.Owner < OwnerToSeqNo.size());
+ ui64& ownerSeqNo = OwnerToSeqNo[item.Owner];
+ Y_VERIFY(item.SeqNo > ownerSeqNo);
+ ownerSeqNo = item.SeqNo;
+ } else {
+ // if delete fails, then reset deletion flag for scheduled items
+ for (TIncrHugeBlobId id : item.Ids) {
+ // find locator
+ TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(id);
+ // ensure delete flag was set and reset it
+ Y_VERIFY(locator.DeleteInProgress);
+ locator.DeleteInProgress = false;
+ }
+ }
+
+ // send reply to sender
+ ctx.Send(item.Sender, new TEvIncrHugeDeleteResult(status), 0, item.Cookie);
+
+ // delete queue item
+ DeleteQueue.erase(it);
+ };
+
+ // send request to logger
Keeper.Logger.LogBlobDeletes(item.Owner, item.SeqNo, TVector<TBlobDeleteLocator>(item.DeleteLocators),
- MakeSimpleCallback(std::move(callback)), ctx);
- }
-
- // this function is called for items that were defragmented; a vector of delete locators contains metadata for
- // these items, but TIncrHugeBlobId's are zero to BadId as these items are not deleted from index -- they were
- // just moved
+ MakeSimpleCallback(std::move(callback)), ctx);
+ }
+
+ // this function is called for items that were defragmented; a vector of delete locators contains metadata for
+ // these items, but TIncrHugeBlobId's are zero to BadId as these items are not deleted from index -- they were
+ // just moved
void TDeleter::DeleteDefrag(TVector<TBlobDeleteLocator>&& deleteLocators, const TActorContext& ctx) {
- // sort items
- std::sort(deleteLocators.begin(), deleteLocators.end());
- // issue virtual log record to keep internal and log state consistent if delete chunk message is generated
+ // sort items
+ std::sort(deleteLocators.begin(), deleteLocators.end());
+ // issue virtual log record to keep internal and log state consistent if delete chunk message is generated
Keeper.Logger.LogVirtualBlobDeletes(TVector<TBlobDeleteLocator>(deleteLocators), ctx);
- // execute actual deletion; this must be called after logging virtual delete record, because this function
- // may issue chunk deletions and they must be consistent with deletions -- chunks may only be dropped after
- // _ALL_ their blobs are marked deleted
- ProcessDeletedLocators(deleteLocators, false, ctx);
- }
-
- // this function actually applies delete operations; it deletes items from index (if requested) and marks items
- // in chunks as deleted ones; this should be called only after successfully logging changes
+ // execute actual deletion; this must be called after logging virtual delete record, because this function
+ // may issue chunk deletions and they must be consistent with deletions -- chunks may only be dropped after
+ // _ALL_ their blobs are marked deleted
+ ProcessDeletedLocators(deleteLocators, false, ctx);
+ }
+
+ // this function actually applies delete operations; it deletes items from index (if requested) and marks items
+ // in chunks as deleted ones; this should be called only after successfully logging changes
void TDeleter::ProcessDeletedLocators(const TVector<TBlobDeleteLocator>& deleteLocators, bool deleteFromLookup,
- const TActorContext& ctx) {
- if (deleteFromLookup) {
- for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
- IHLOG_DEBUG(ctx, "deleting %016" PRIx64 " from lookup table", deleteLocator.Id);
- TBlobLocator locator;
- bool status = Keeper.State.BlobLookup.Delete(deleteLocator.Id, &locator);
- Y_VERIFY(status);
- }
- }
-
- // clear chunks
- for (auto it = deleteLocators.begin(); it != deleteLocators.end(); ) {
- // get reference to current chunk
- const TChunkIdx chunkIdx = it->ChunkIdx;
- auto chunkIt = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(chunkIt != Keeper.State.Chunks.end());
- TChunkInfo& chunk = chunkIt->second;
- Y_VERIFY(chunk.State != EChunkState::Deleting);
-
- // process items
- for (; it != deleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
- Y_VERIFY(chunk.ChunkSerNum == it->ChunkSerNum);
- Y_VERIFY(chunk.NumUsedBlocks >= it->SizeInBlocks);
- chunk.NumUsedBlocks -= it->SizeInBlocks;
- Y_VERIFY(!chunk.DeletedItems.Get(it->IndexInsideChunk));
- chunk.DeletedItems.Set(it->IndexInsideChunk);
- }
-
- // for complete chunks see if we can release this chunk; otherwise we mark deleted items there
- if (chunk.State == EChunkState::Complete && !chunk.NumUsedBlocks) {
- IssueLogChunkDelete(chunkIdx, ctx);
- }
-
- // notify defragmenter
- Keeper.Defragmenter.UpdateChunkState(chunkIdx, ctx);
- }
- }
-
- // this function is called for a chunk to transfer it to Deleting state and generate log entry with chunk
- // deletion; chunk is actually removed from index only when log operation succeeds; if log fails, then it is
- // retries infinitely until success; chunk is not deleted if there are requests in flight for this chunk, what
- // is indicated by non-zero value of chunk.InFlightReq; every time when this counter reaches zero as a result
- // of decrement and chunk is in 'Deleting' state, one should invoke this function
- void TDeleter::IssueLogChunkDelete(TChunkIdx chunkIdx, const TActorContext& ctx) {
- // update chunk state to deleting
- TChunkInfo& chunk = Keeper.State.Chunks.at(chunkIdx);
- chunk.State = EChunkState::Deleting;
-
- // if there are requests in flight, do nothing yet
- if (chunk.InFlightReq) {
- return;
- }
-
- // ensure that chunk is completely deleted, i.e. all of its items are marked deleted; mostly this is debug
- // feature
- Y_VERIFY(chunk.NumUsedBlocks == 0 && chunk.DeletedItems.Count() == chunk.NumItems);
- for (ui32 i = 0; i < chunk.NumItems; ++i) {
- Y_VERIFY(chunk.DeletedItems.Get(i));
- }
-
- // create callback that will actually delete this chunk from index when log is completed
- auto callback = [this, chunkIdx](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
- IHLOG_DEBUG(ctx, "finished chunk delete ChunkIdx# %" PRIu32 " Status# %s", chunkIdx,
+ const TActorContext& ctx) {
+ if (deleteFromLookup) {
+ for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
+ IHLOG_DEBUG(ctx, "deleting %016" PRIx64 " from lookup table", deleteLocator.Id);
+ TBlobLocator locator;
+ bool status = Keeper.State.BlobLookup.Delete(deleteLocator.Id, &locator);
+ Y_VERIFY(status);
+ }
+ }
+
+ // clear chunks
+ for (auto it = deleteLocators.begin(); it != deleteLocators.end(); ) {
+ // get reference to current chunk
+ const TChunkIdx chunkIdx = it->ChunkIdx;
+ auto chunkIt = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(chunkIt != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = chunkIt->second;
+ Y_VERIFY(chunk.State != EChunkState::Deleting);
+
+ // process items
+ for (; it != deleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
+ Y_VERIFY(chunk.ChunkSerNum == it->ChunkSerNum);
+ Y_VERIFY(chunk.NumUsedBlocks >= it->SizeInBlocks);
+ chunk.NumUsedBlocks -= it->SizeInBlocks;
+ Y_VERIFY(!chunk.DeletedItems.Get(it->IndexInsideChunk));
+ chunk.DeletedItems.Set(it->IndexInsideChunk);
+ }
+
+ // for complete chunks see if we can release this chunk; otherwise we mark deleted items there
+ if (chunk.State == EChunkState::Complete && !chunk.NumUsedBlocks) {
+ IssueLogChunkDelete(chunkIdx, ctx);
+ }
+
+ // notify defragmenter
+ Keeper.Defragmenter.UpdateChunkState(chunkIdx, ctx);
+ }
+ }
+
+ // this function is called for a chunk to transfer it to Deleting state and generate log entry with chunk
+ // deletion; chunk is actually removed from index only when log operation succeeds; if log fails, then it is
+ // retries infinitely until success; chunk is not deleted if there are requests in flight for this chunk, what
+ // is indicated by non-zero value of chunk.InFlightReq; every time when this counter reaches zero as a result
+ // of decrement and chunk is in 'Deleting' state, one should invoke this function
+ void TDeleter::IssueLogChunkDelete(TChunkIdx chunkIdx, const TActorContext& ctx) {
+ // update chunk state to deleting
+ TChunkInfo& chunk = Keeper.State.Chunks.at(chunkIdx);
+ chunk.State = EChunkState::Deleting;
+
+ // if there are requests in flight, do nothing yet
+ if (chunk.InFlightReq) {
+ return;
+ }
+
+ // ensure that chunk is completely deleted, i.e. all of its items are marked deleted; mostly this is debug
+ // feature
+ Y_VERIFY(chunk.NumUsedBlocks == 0 && chunk.DeletedItems.Count() == chunk.NumItems);
+ for (ui32 i = 0; i < chunk.NumItems; ++i) {
+ Y_VERIFY(chunk.DeletedItems.Get(i));
+ }
+
+ // create callback that will actually delete this chunk from index when log is completed
+ auto callback = [this, chunkIdx](NKikimrProto::EReplyStatus status, const TActorContext& ctx) {
+ IHLOG_DEBUG(ctx, "finished chunk delete ChunkIdx# %" PRIu32 " Status# %s", chunkIdx,
NKikimrProto::EReplyStatus_Name(status).data());
-
- // find chunk and ensure that it is in deleting state
- auto it = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.State == EChunkState::Deleting);
- Y_VERIFY(chunk.InFlightReq == 0);
-
- // on success just delete chunk from set; otherwise try again
- if (status == NKikimrProto::OK) {
- Keeper.State.Chunks.erase(it);
- } else {
- IssueLogChunkDelete(chunkIdx, ctx);
- }
- };
-
- IHLOG_DEBUG(ctx, "sending chunk delete ChunkIdx# %" PRIu32, chunkIdx);
-
- // log chunk deletion; generate "DeletedChunks" item for this record in order to remove this chunk from
- // chunks set on recovery
- Keeper.Logger.LogChunkDeletion(chunkIdx, chunk.ChunkSerNum, chunk.NumItems,
- MakeSimpleCallback(std::move(callback)), ctx);
- }
-
- // this function is called during recovery to set up initial positions of sequence number for each owner
- void TDeleter::InsertOwnerOnRecovery(ui8 owner, ui64 seqNo) {
- Y_VERIFY(owner < OwnerToSeqNo.size());
- OwnerToSeqNo[owner] = seqNo;
- }
-
- } // NIncrHuge
-} // NKikimr
+
+ // find chunk and ensure that it is in deleting state
+ auto it = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.State == EChunkState::Deleting);
+ Y_VERIFY(chunk.InFlightReq == 0);
+
+ // on success just delete chunk from set; otherwise try again
+ if (status == NKikimrProto::OK) {
+ Keeper.State.Chunks.erase(it);
+ } else {
+ IssueLogChunkDelete(chunkIdx, ctx);
+ }
+ };
+
+ IHLOG_DEBUG(ctx, "sending chunk delete ChunkIdx# %" PRIu32, chunkIdx);
+
+ // log chunk deletion; generate "DeletedChunks" item for this record in order to remove this chunk from
+ // chunks set on recovery
+ Keeper.Logger.LogChunkDeletion(chunkIdx, chunk.ChunkSerNum, chunk.NumItems,
+ MakeSimpleCallback(std::move(callback)), ctx);
+ }
+
+ // this function is called during recovery to set up initial positions of sequence number for each owner
+ void TDeleter::InsertOwnerOnRecovery(ui8 owner, ui64 seqNo) {
+ Y_VERIFY(owner < OwnerToSeqNo.size());
+ OwnerToSeqNo[owner] = seqNo;
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.h
index ecc415f4bcb..e124adcc939 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_delete.h
@@ -1,50 +1,50 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge.h"
-
-#include <util/generic/bitmap.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TDeleter
- : public TKeeperComponentBase
- {
- // vector of sequence numbers of deletion for each owner
- std::array<ui64, 256> OwnerToSeqNo;
-
- struct TDeleteQueueItem;
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge.h"
+
+#include <util/generic/bitmap.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TDeleter
+ : public TKeeperComponentBase
+ {
+ // vector of sequence numbers of deletion for each owner
+ std::array<ui64, 256> OwnerToSeqNo;
+
+ struct TDeleteQueueItem;
using TDeleteQueue = TList<TDeleteQueueItem>;
- TDeleteQueue DeleteQueue;
+ TDeleteQueue DeleteQueue;
THashMap<TIncrHugeBlobId, TDeleteQueue::iterator> WriteInProgress;
-
- public:
- TDeleter(TKeeper& keeper);
- ~TDeleter();
-
- // delete request handler
- void HandleDelete(TEvIncrHugeDelete::TPtr& ev, const TActorContext& ctx);
-
- // delete some locators generated while defragmenting
+
+ public:
+ TDeleter(TKeeper& keeper);
+ ~TDeleter();
+
+ // delete request handler
+ void HandleDelete(TEvIncrHugeDelete::TPtr& ev, const TActorContext& ctx);
+
+ // delete some locators generated while defragmenting
void DeleteDefrag(TVector<TBlobDeleteLocator>&& deleteLocators, const TActorContext& ctx);
-
- // issue chunk deletion request after it is completely freed
- void IssueLogChunkDelete(TChunkIdx chunkIdx, const TActorContext& ctx);
-
- // setup owner's position when doing recovery
- void InsertOwnerOnRecovery(ui8 owner, ui64 seqNo);
-
- void OnItemDefragWritten(TIncrHugeBlobId id, const TActorContext& ctx);
-
- private:
- void ProcessDeleteItem(TDeleteQueue::iterator it, const TActorContext& ctx);
-
- // post-log part of delete process (when log finished successfully)
+
+ // issue chunk deletion request after it is completely freed
+ void IssueLogChunkDelete(TChunkIdx chunkIdx, const TActorContext& ctx);
+
+ // setup owner's position when doing recovery
+ void InsertOwnerOnRecovery(ui8 owner, ui64 seqNo);
+
+ void OnItemDefragWritten(TIncrHugeBlobId id, const TActorContext& ctx);
+
+ private:
+ void ProcessDeleteItem(TDeleteQueue::iterator it, const TActorContext& ctx);
+
+ // post-log part of delete process (when log finished successfully)
void ProcessDeletedLocators(const TVector<TBlobDeleteLocator>& deleteLocators, bool deleteFromLookup,
- const TActorContext& ctx);
- };
-
- } // NIncrHuge
-} // NKikimr
+ const TActorContext& ctx);
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.cpp
index 62da8c0f7ef..aa34229b5b1 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.cpp
@@ -1,737 +1,737 @@
-#include "incrhuge_keeper_log.h"
-#include "incrhuge_keeper.h"
+#include "incrhuge_keeper_log.h"
+#include "incrhuge_keeper.h"
#include <ydb/core/protos/blobstorage_vdisk_internal.pb.h>
-
+
#include <google/protobuf/text_format.h>
#include <util/generic/variant.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CHUNK LOG RECORD MERGER
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TChunkRecordMerger::operator ()(const NKikimrVDiskData::TIncrHugeChunks& record) {
- for (const auto& c : record.GetChunks()) {
- Y_VERIFY(c.HasChunkIdx() && c.HasChunkSerNum() && c.HasState());
- const TChunkIdx chunkIdx = c.GetChunkIdx();
- const TChunkSerNum chunkSerNum(c.GetChunkSerNum());
- auto it = Chunks.find(chunkIdx);
- if (it != Chunks.end()) {
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.ChunkSerNum == chunkSerNum);
- chunk.State = c.GetState();
- } else {
- Chunks.emplace(chunkIdx, TChunkInfo{chunkSerNum, c.GetState()});
- }
- }
- for (TChunkIdx chunkIdx : record.GetDeletedChunks()) {
- auto it = Chunks.find(chunkIdx);
- Y_VERIFY(it != Chunks.end());
- Chunks.erase(it);
- }
- if (record.HasCurrentSerNum()) {
- CurrentSerNum = TChunkSerNum(record.GetCurrentSerNum());
- }
- }
-
- void TChunkRecordMerger::operator ()(const TChunkAllocation& record) {
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CHUNK LOG RECORD MERGER
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void TChunkRecordMerger::operator ()(const NKikimrVDiskData::TIncrHugeChunks& record) {
+ for (const auto& c : record.GetChunks()) {
+ Y_VERIFY(c.HasChunkIdx() && c.HasChunkSerNum() && c.HasState());
+ const TChunkIdx chunkIdx = c.GetChunkIdx();
+ const TChunkSerNum chunkSerNum(c.GetChunkSerNum());
+ auto it = Chunks.find(chunkIdx);
+ if (it != Chunks.end()) {
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.ChunkSerNum == chunkSerNum);
+ chunk.State = c.GetState();
+ } else {
+ Chunks.emplace(chunkIdx, TChunkInfo{chunkSerNum, c.GetState()});
+ }
+ }
+ for (TChunkIdx chunkIdx : record.GetDeletedChunks()) {
+ auto it = Chunks.find(chunkIdx);
+ Y_VERIFY(it != Chunks.end());
+ Chunks.erase(it);
+ }
+ if (record.HasCurrentSerNum()) {
+ CurrentSerNum = TChunkSerNum(record.GetCurrentSerNum());
+ }
+ }
+
+ void TChunkRecordMerger::operator ()(const TChunkAllocation& record) {
for (size_t i = 0; i < record.NewChunkIds.size(); ++i) {
- const TChunkIdx chunkIdx = record.NewChunkIds[i];
- Y_VERIFY(!Chunks.count(chunkIdx));
- Chunks[chunkIdx] = TChunkInfo{
- record.BaseSerNum.Add(i),
- NKikimrVDiskData::TIncrHugeChunks::WriteIntent
- };
- }
- CurrentSerNum = record.CurrentSerNum;
- }
-
- void TChunkRecordMerger::operator ()(const TChunkDeletion& record) {
- auto it = Chunks.find(record.ChunkIdx);
- Y_VERIFY(it != Chunks.end());
- Chunks.erase(it);
- }
-
- void TChunkRecordMerger::operator ()(const TCompleteChunk& record) {
- auto it = Chunks.find(record.ChunkIdx);
- Y_VERIFY(it != Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.ChunkSerNum == record.ChunkSerNum);
- Y_VERIFY(chunk.State == NKikimrVDiskData::TIncrHugeChunks::WriteIntent);
- chunk.State = NKikimrVDiskData::TIncrHugeChunks::Complete;
- }
-
- NKikimrVDiskData::TIncrHugeChunks TChunkRecordMerger::GetCurrentState() const {
- NKikimrVDiskData::TIncrHugeChunks record;
- for (const auto& pair : Chunks) {
- const TChunkIdx chunkIdx = pair.first;
- const TChunkInfo& chunk = pair.second;
- auto *c = record.AddChunks();
- c->SetChunkIdx(chunkIdx);
- c->SetChunkSerNum(static_cast<ui64>(chunk.ChunkSerNum));
- c->SetState(chunk.State);
- }
- if (CurrentSerNum) {
- record.SetCurrentSerNum(static_cast<ui64>(*CurrentSerNum));
- }
- return record;
- }
-
+ const TChunkIdx chunkIdx = record.NewChunkIds[i];
+ Y_VERIFY(!Chunks.count(chunkIdx));
+ Chunks[chunkIdx] = TChunkInfo{
+ record.BaseSerNum.Add(i),
+ NKikimrVDiskData::TIncrHugeChunks::WriteIntent
+ };
+ }
+ CurrentSerNum = record.CurrentSerNum;
+ }
+
+ void TChunkRecordMerger::operator ()(const TChunkDeletion& record) {
+ auto it = Chunks.find(record.ChunkIdx);
+ Y_VERIFY(it != Chunks.end());
+ Chunks.erase(it);
+ }
+
+ void TChunkRecordMerger::operator ()(const TCompleteChunk& record) {
+ auto it = Chunks.find(record.ChunkIdx);
+ Y_VERIFY(it != Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.ChunkSerNum == record.ChunkSerNum);
+ Y_VERIFY(chunk.State == NKikimrVDiskData::TIncrHugeChunks::WriteIntent);
+ chunk.State = NKikimrVDiskData::TIncrHugeChunks::Complete;
+ }
+
+ NKikimrVDiskData::TIncrHugeChunks TChunkRecordMerger::GetCurrentState() const {
+ NKikimrVDiskData::TIncrHugeChunks record;
+ for (const auto& pair : Chunks) {
+ const TChunkIdx chunkIdx = pair.first;
+ const TChunkInfo& chunk = pair.second;
+ auto *c = record.AddChunks();
+ c->SetChunkIdx(chunkIdx);
+ c->SetChunkSerNum(static_cast<ui64>(chunk.ChunkSerNum));
+ c->SetState(chunk.State);
+ }
+ if (CurrentSerNum) {
+ record.SetCurrentSerNum(static_cast<ui64>(*CurrentSerNum));
+ }
+ return record;
+ }
+
TString TChunkRecordMerger::Serialize(const NKikimrVDiskData::TIncrHugeChunks& record) {
TString data;
- bool status = record.SerializeToString(&data);
- Y_VERIFY(status);
- return data;
- }
-
+ bool status = record.SerializeToString(&data);
+ Y_VERIFY(status);
+ return data;
+ }
+
TString TChunkRecordMerger::Serialize(const TChunkAllocation& record) {
- NKikimrVDiskData::TIncrHugeChunks protobuf;
+ NKikimrVDiskData::TIncrHugeChunks protobuf;
for (size_t i = 0; i < record.NewChunkIds.size(); ++i) {
- auto *c = protobuf.AddChunks();
- c->SetChunkIdx(record.NewChunkIds[i]);
- c->SetChunkSerNum(static_cast<ui64>(record.BaseSerNum.Add(i)));
- c->SetState(NKikimrVDiskData::TIncrHugeChunks::WriteIntent);
- }
- protobuf.SetCurrentSerNum(static_cast<ui64>(record.CurrentSerNum));
- return Serialize(protobuf);
- }
-
+ auto *c = protobuf.AddChunks();
+ c->SetChunkIdx(record.NewChunkIds[i]);
+ c->SetChunkSerNum(static_cast<ui64>(record.BaseSerNum.Add(i)));
+ c->SetState(NKikimrVDiskData::TIncrHugeChunks::WriteIntent);
+ }
+ protobuf.SetCurrentSerNum(static_cast<ui64>(record.CurrentSerNum));
+ return Serialize(protobuf);
+ }
+
TString TChunkRecordMerger::Serialize(const TChunkDeletion& record) {
- NKikimrVDiskData::TIncrHugeChunks protobuf;
- protobuf.AddDeletedChunks(record.ChunkIdx);
- return Serialize(protobuf);
- }
-
+ NKikimrVDiskData::TIncrHugeChunks protobuf;
+ protobuf.AddDeletedChunks(record.ChunkIdx);
+ return Serialize(protobuf);
+ }
+
TString TChunkRecordMerger::Serialize(const TCompleteChunk& record) {
- NKikimrVDiskData::TIncrHugeChunks protobuf;
- auto *c = protobuf.AddChunks();
- c->SetChunkIdx(record.ChunkIdx);
- c->SetChunkSerNum(static_cast<ui64>(record.ChunkSerNum));
- c->SetState(NKikimrVDiskData::TIncrHugeChunks::Complete);
- return Serialize(protobuf);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // DELETE LOG RECORD MERGER
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // store deletion bitmap into log record item
- void SerializeDeletes(const TDynBitMap& deletedItems, NKikimrVDiskData::TIncrHugeDelete::TChunkInfo *chunk) {
- // serialize into item list
- auto& items = *chunk->MutableDeletedItems();
- size_t first = 0, count = 0;
- auto add = [&] {
- if (count == 1) {
- items.AddIndexes(first);
- } else if (count > 1) {
- auto *range = items.AddRanges();
- range->SetFirst(first);
- range->SetCount(count);
- }
- };
- Y_FOR_EACH_BIT(index, deletedItems) {
- if (index == first + count) {
- ++count;
- } else {
- add();
- first = index;
- count = 1;
- }
- }
- add();
-
- // second, serialize into string
- TStringStream stream;
- deletedItems.Save(&stream);
+ NKikimrVDiskData::TIncrHugeChunks protobuf;
+ auto *c = protobuf.AddChunks();
+ c->SetChunkIdx(record.ChunkIdx);
+ c->SetChunkSerNum(static_cast<ui64>(record.ChunkSerNum));
+ c->SetState(NKikimrVDiskData::TIncrHugeChunks::Complete);
+ return Serialize(protobuf);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DELETE LOG RECORD MERGER
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // store deletion bitmap into log record item
+ void SerializeDeletes(const TDynBitMap& deletedItems, NKikimrVDiskData::TIncrHugeDelete::TChunkInfo *chunk) {
+ // serialize into item list
+ auto& items = *chunk->MutableDeletedItems();
+ size_t first = 0, count = 0;
+ auto add = [&] {
+ if (count == 1) {
+ items.AddIndexes(first);
+ } else if (count > 1) {
+ auto *range = items.AddRanges();
+ range->SetFirst(first);
+ range->SetCount(count);
+ }
+ };
+ Y_FOR_EACH_BIT(index, deletedItems) {
+ if (index == first + count) {
+ ++count;
+ } else {
+ add();
+ first = index;
+ count = 1;
+ }
+ }
+ add();
+
+ // second, serialize into string
+ TStringStream stream;
+ deletedItems.Save(&stream);
TString bits = stream.Str();
-
- // choose the best
- if (bits.size() < (size_t)items.ByteSize()) {
- chunk->SetBits(bits);
- }
- }
-
- void DeserializeDeletes(TDynBitMap& deletedItems, const NKikimrVDiskData::TIncrHugeDelete::TChunkInfo& chunk) {
- switch (chunk.DeletedData_case()) {
- case NKikimrVDiskData::TIncrHugeDelete::TChunkInfo::kDeletedItems: {
- const auto& x = chunk.GetDeletedItems();
- for (ui32 index : x.GetIndexes()) {
- deletedItems.Set(index);
- }
- for (const auto& range : x.GetRanges()) {
- Y_VERIFY(range.HasFirst() && range.HasCount());
- const ui32 first = range.GetFirst();
- const ui32 count = range.GetCount();
- deletedItems.Set(first, first + count);
- }
- break;
- }
-
- case NKikimrVDiskData::TIncrHugeDelete::TChunkInfo::kBits: {
- TStringStream stream(chunk.GetBits());
- deletedItems.Load(&stream);
- break;
- }
-
- default:
- Y_FAIL("unexpected case");
- }
- }
-
- void TDeleteRecordMerger::operator ()(const NKikimrVDiskData::TIncrHugeDelete& record) {
- for (const auto& c : record.GetChunks()) {
- Y_VERIFY(c.HasChunkSerNum());
- const TChunkSerNum chunkSerNum(c.GetChunkSerNum());
-
- // find matching entry
- TDynBitMap& deletedItems = SerNumToChunk[chunkSerNum];
-
- // deserialize deletion bitmap
- TDynBitMap newDeletes;
- DeserializeDeletes(newDeletes, c);
-
- // ensure that there are no intersections
- Y_VERIFY((newDeletes & deletedItems).Count() == 0);
-
- // combine items
- deletedItems |= newDeletes;
- }
-
- // merge owner to seq no map
- for (const auto& o : record.GetOwners()) {
- Y_VERIFY(o.HasOwner() && o.HasSeqNo());
-
- // verify that owner's sequence numbers are logged in strictly increasing order
- auto it = OwnerToSeqNo.find(o.GetOwner());
- if (it != OwnerToSeqNo.end()) {
- Y_VERIFY(it->second < o.GetSeqNo(), "Delete record reordering OldSeqNo# %" PRIu64 " NewSeqNo# %"
- PRIu64, it->second, o.GetSeqNo());
- }
-
- // update seq no
- OwnerToSeqNo[o.GetOwner()] = o.GetSeqNo();
- }
- }
-
- void TDeleteRecordMerger::operator ()(const TBlobDeletes& record) {
- for (auto it = record.DeleteLocators.begin(); it != record.DeleteLocators.end(); ) {
- const TChunkIdx chunkIdx = it->ChunkIdx;
- TDynBitMap& deletedItems = SerNumToChunk[it->ChunkSerNum];
- for (; it != record.DeleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
- Y_VERIFY(!deletedItems.Get(it->IndexInsideChunk), "trying to delete already deleted item ChunkIdx# %"
- PRIu32 " ChunkSerNum# %s Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %"
+
+ // choose the best
+ if (bits.size() < (size_t)items.ByteSize()) {
+ chunk->SetBits(bits);
+ }
+ }
+
+ void DeserializeDeletes(TDynBitMap& deletedItems, const NKikimrVDiskData::TIncrHugeDelete::TChunkInfo& chunk) {
+ switch (chunk.DeletedData_case()) {
+ case NKikimrVDiskData::TIncrHugeDelete::TChunkInfo::kDeletedItems: {
+ const auto& x = chunk.GetDeletedItems();
+ for (ui32 index : x.GetIndexes()) {
+ deletedItems.Set(index);
+ }
+ for (const auto& range : x.GetRanges()) {
+ Y_VERIFY(range.HasFirst() && range.HasCount());
+ const ui32 first = range.GetFirst();
+ const ui32 count = range.GetCount();
+ deletedItems.Set(first, first + count);
+ }
+ break;
+ }
+
+ case NKikimrVDiskData::TIncrHugeDelete::TChunkInfo::kBits: {
+ TStringStream stream(chunk.GetBits());
+ deletedItems.Load(&stream);
+ break;
+ }
+
+ default:
+ Y_FAIL("unexpected case");
+ }
+ }
+
+ void TDeleteRecordMerger::operator ()(const NKikimrVDiskData::TIncrHugeDelete& record) {
+ for (const auto& c : record.GetChunks()) {
+ Y_VERIFY(c.HasChunkSerNum());
+ const TChunkSerNum chunkSerNum(c.GetChunkSerNum());
+
+ // find matching entry
+ TDynBitMap& deletedItems = SerNumToChunk[chunkSerNum];
+
+ // deserialize deletion bitmap
+ TDynBitMap newDeletes;
+ DeserializeDeletes(newDeletes, c);
+
+ // ensure that there are no intersections
+ Y_VERIFY((newDeletes & deletedItems).Count() == 0);
+
+ // combine items
+ deletedItems |= newDeletes;
+ }
+
+ // merge owner to seq no map
+ for (const auto& o : record.GetOwners()) {
+ Y_VERIFY(o.HasOwner() && o.HasSeqNo());
+
+ // verify that owner's sequence numbers are logged in strictly increasing order
+ auto it = OwnerToSeqNo.find(o.GetOwner());
+ if (it != OwnerToSeqNo.end()) {
+ Y_VERIFY(it->second < o.GetSeqNo(), "Delete record reordering OldSeqNo# %" PRIu64 " NewSeqNo# %"
+ PRIu64, it->second, o.GetSeqNo());
+ }
+
+ // update seq no
+ OwnerToSeqNo[o.GetOwner()] = o.GetSeqNo();
+ }
+ }
+
+ void TDeleteRecordMerger::operator ()(const TBlobDeletes& record) {
+ for (auto it = record.DeleteLocators.begin(); it != record.DeleteLocators.end(); ) {
+ const TChunkIdx chunkIdx = it->ChunkIdx;
+ TDynBitMap& deletedItems = SerNumToChunk[it->ChunkSerNum];
+ for (; it != record.DeleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
+ Y_VERIFY(!deletedItems.Get(it->IndexInsideChunk), "trying to delete already deleted item ChunkIdx# %"
+ PRIu32 " ChunkSerNum# %s Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %"
PRIu32, it->ChunkIdx, it->ChunkSerNum.ToString().data(), it->Id, it->IndexInsideChunk,
- it->SizeInBlocks);
- deletedItems.Set(it->IndexInsideChunk);
- }
- }
-
- if (record.Owner) {
- auto it = OwnerToSeqNo.find(record.Owner);
- if (it != OwnerToSeqNo.end()) {
- Y_VERIFY(it->second < record.SeqNo, "Delete record reordering OldSeqNo# %" PRIu64 " NewSeqNo# %"
- PRIu64, it->second, record.SeqNo);
- }
-
- OwnerToSeqNo[record.Owner] = record.SeqNo;
- }
- }
-
- void TDeleteRecordMerger::operator ()(const TDeleteChunk& record) {
- auto it = SerNumToChunk.find(record.ChunkSerNum);
- Y_VERIFY(it != SerNumToChunk.end());
- TDynBitMap& deletedItems = it->second;
- Y_VERIFY(record.NumItems == deletedItems.Count());
- for (ui32 i = 0; i < record.NumItems; ++i) {
- // ensure that there are no gaps in deleted items
- Y_VERIFY(deletedItems.Get(i));
- }
- SerNumToChunk.erase(it);
- }
-
- NKikimrVDiskData::TIncrHugeDelete TDeleteRecordMerger::GetCurrentState() const {
- NKikimrVDiskData::TIncrHugeDelete record;
-
- for (const auto& chunk : SerNumToChunk) {
- auto *c = record.AddChunks();
- c->SetChunkSerNum(static_cast<ui64>(chunk.first));
- SerializeDeletes(chunk.second, c);
- }
-
- for (const auto& owner : OwnerToSeqNo) {
- auto *o = record.AddOwners();
- o->SetOwner(owner.first);
- o->SetSeqNo(owner.second);
- }
-
- return record;
- }
-
+ it->SizeInBlocks);
+ deletedItems.Set(it->IndexInsideChunk);
+ }
+ }
+
+ if (record.Owner) {
+ auto it = OwnerToSeqNo.find(record.Owner);
+ if (it != OwnerToSeqNo.end()) {
+ Y_VERIFY(it->second < record.SeqNo, "Delete record reordering OldSeqNo# %" PRIu64 " NewSeqNo# %"
+ PRIu64, it->second, record.SeqNo);
+ }
+
+ OwnerToSeqNo[record.Owner] = record.SeqNo;
+ }
+ }
+
+ void TDeleteRecordMerger::operator ()(const TDeleteChunk& record) {
+ auto it = SerNumToChunk.find(record.ChunkSerNum);
+ Y_VERIFY(it != SerNumToChunk.end());
+ TDynBitMap& deletedItems = it->second;
+ Y_VERIFY(record.NumItems == deletedItems.Count());
+ for (ui32 i = 0; i < record.NumItems; ++i) {
+ // ensure that there are no gaps in deleted items
+ Y_VERIFY(deletedItems.Get(i));
+ }
+ SerNumToChunk.erase(it);
+ }
+
+ NKikimrVDiskData::TIncrHugeDelete TDeleteRecordMerger::GetCurrentState() const {
+ NKikimrVDiskData::TIncrHugeDelete record;
+
+ for (const auto& chunk : SerNumToChunk) {
+ auto *c = record.AddChunks();
+ c->SetChunkSerNum(static_cast<ui64>(chunk.first));
+ SerializeDeletes(chunk.second, c);
+ }
+
+ for (const auto& owner : OwnerToSeqNo) {
+ auto *o = record.AddOwners();
+ o->SetOwner(owner.first);
+ o->SetSeqNo(owner.second);
+ }
+
+ return record;
+ }
+
TString TDeleteRecordMerger::Serialize(const NKikimrVDiskData::TIncrHugeDelete& record) {
TString data;
- bool status = record.SerializeToString(&data);
- Y_VERIFY(status);
- return data;
- }
-
+ bool status = record.SerializeToString(&data);
+ Y_VERIFY(status);
+ return data;
+ }
+
TString TDeleteRecordMerger::Serialize(const TBlobDeletes& record) {
- NKikimrVDiskData::TIncrHugeDelete protobuf;
- if (record.Owner) {
- auto *owner = protobuf.AddOwners();
- owner->SetOwner(record.Owner);
- owner->SetSeqNo(record.SeqNo);
- }
- for (auto it = record.DeleteLocators.begin(); it != record.DeleteLocators.end(); ) {
- const TChunkIdx chunkIdx = it->ChunkIdx;
- const TChunkSerNum chunkSerNum = it->ChunkSerNum;
-
- // create bitmap of deleted items
- TDynBitMap deletedItems;
- for (; it != record.DeleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
- deletedItems.Set(it->IndexInsideChunk);
- }
-
- // serialize it into record
- auto *chunk = protobuf.AddChunks();
- chunk->SetChunkSerNum(static_cast<ui64>(chunkSerNum));
- SerializeDeletes(deletedItems, chunk);
- }
- return Serialize(protobuf);
- }
-
+ NKikimrVDiskData::TIncrHugeDelete protobuf;
+ if (record.Owner) {
+ auto *owner = protobuf.AddOwners();
+ owner->SetOwner(record.Owner);
+ owner->SetSeqNo(record.SeqNo);
+ }
+ for (auto it = record.DeleteLocators.begin(); it != record.DeleteLocators.end(); ) {
+ const TChunkIdx chunkIdx = it->ChunkIdx;
+ const TChunkSerNum chunkSerNum = it->ChunkSerNum;
+
+ // create bitmap of deleted items
+ TDynBitMap deletedItems;
+ for (; it != record.DeleteLocators.end() && it->ChunkIdx == chunkIdx; ++it) {
+ deletedItems.Set(it->IndexInsideChunk);
+ }
+
+ // serialize it into record
+ auto *chunk = protobuf.AddChunks();
+ chunk->SetChunkSerNum(static_cast<ui64>(chunkSerNum));
+ SerializeDeletes(deletedItems, chunk);
+ }
+ return Serialize(protobuf);
+ }
+
TString TDeleteRecordMerger::Serialize(const TDeleteChunk& /*record*/) {
- Y_FAIL("this function should never be called");
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TLogger CLASS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TLogger::TLogger(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Logger")
- {
- memset(LastSeqNo.data(), 0, LastSeqNo.size() * sizeof(ui64));
- }
-
- TLogger::~TLogger()
- {}
-
- void TLogger::SetLsnOnRecovery(ui64 lsn, bool issueInitialStartingPoints) {
- Lsn = lsn;
- IssueChunksStartingPoint = issueInitialStartingPoints;
- }
-
- struct TLogger::TChunkQueueItem {
- // log entry content
+ Y_FAIL("this function should never be called");
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TLogger CLASS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TLogger::TLogger(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Logger")
+ {
+ memset(LastSeqNo.data(), 0, LastSeqNo.size() * sizeof(ui64));
+ }
+
+ TLogger::~TLogger()
+ {}
+
+ void TLogger::SetLsnOnRecovery(ui64 lsn, bool issueInitialStartingPoints) {
+ Lsn = lsn;
+ IssueChunksStartingPoint = issueInitialStartingPoints;
+ }
+
+ struct TLogger::TChunkQueueItem {
+ // log entry content
std::variant<TChunkRecordMerger::TChunkAllocation, TChunkRecordMerger::TChunkDeletion,
- TChunkRecordMerger::TCompleteChunk, NKikimrVDiskData::TIncrHugeChunks> Content;
-
- // commit chunks
+ TChunkRecordMerger::TCompleteChunk, NKikimrVDiskData::TIncrHugeChunks> Content;
+
+ // commit chunks
TVector<TChunkIdx> CommitChunks;
-
- // delete chunks
+
+ // delete chunks
TVector<TChunkIdx> DeleteChunks;
-
- // callback to invoke upon completion
- std::unique_ptr<IEventCallback> Callback;
-
- // is it an entrypoint?
- bool Entrypoint;
-
- // lsn
- ui64 Lsn;
- };
-
- struct TLogger::TDeleteQueueItem {
- // actual record content depending on its type; for blob deletes it contains TBlobDeletes item, for
- // entrypoint -- full record that; this record will be simply merged into confirmed state upon success
+
+ // callback to invoke upon completion
+ std::unique_ptr<IEventCallback> Callback;
+
+ // is it an entrypoint?
+ bool Entrypoint;
+
+ // lsn
+ ui64 Lsn;
+ };
+
+ struct TLogger::TDeleteQueueItem {
+ // actual record content depending on its type; for blob deletes it contains TBlobDeletes item, for
+ // entrypoint -- full record that; this record will be simply merged into confirmed state upon success
std::variant<TDeleteRecordMerger::TBlobDeletes, TDeleteRecordMerger::TDeleteChunk,
- NKikimrVDiskData::TIncrHugeDelete> Content;
-
- // vector of callbacks that are invoked on success or failure of logging
- TVector<std::unique_ptr<IEventCallback>> Callbacks;
-
- // is this an entrypoint?
- bool Entrypoint;
-
- // LSN
- ui64 Lsn;
-
- // is this virtual entrypoint?
- bool Virtual;
-
- // failure expected? debug only; used to detect situations when PDisk logger for queries 1, 2, 3 responds
- // with success to 1 and 3, but fails 2 -- this should be incorrect behavior and can lead to data leak
- bool FailureExpected;
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CHUNKS HANDLING LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ NKikimrVDiskData::TIncrHugeDelete> Content;
+
+ // vector of callbacks that are invoked on success or failure of logging
+ TVector<std::unique_ptr<IEventCallback>> Callbacks;
+
+ // is this an entrypoint?
+ bool Entrypoint;
+
+ // LSN
+ ui64 Lsn;
+
+ // is this virtual entrypoint?
+ bool Virtual;
+
+ // failure expected? debug only; used to detect situations when PDisk logger for queries 1, 2, 3 responds
+ // with success to 1 and 3, but fails 2 -- this should be incorrect behavior and can lead to data leak
+ bool FailureExpected;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CHUNKS HANDLING LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
void TLogger::LogChunkAllocation(TVector<TChunkIdx>&& newChunkIds, TChunkSerNum baseSerNum,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
TVector<TChunkIdx> commitChunks(newChunkIds);
- ProcessChunkQueueItem(TChunkQueueItem{
- TChunkRecordMerger::TChunkAllocation{std::move(newChunkIds), baseSerNum, Keeper.State.CurrentSerNum},
- std::move(commitChunks),
- {},
- std::move(callback),
- IssueChunksStartingPoint,
- {},
- }, ctx);
- IssueChunksStartingPoint = false;
- }
-
- void TLogger::LogChunkDeletion(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, ui32 numItems,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
- ProcessChunkQueueItem(TChunkQueueItem{
- TChunkRecordMerger::TChunkDeletion{chunkIdx, chunkSerNum, numItems},
- {},
+ ProcessChunkQueueItem(TChunkQueueItem{
+ TChunkRecordMerger::TChunkAllocation{std::move(newChunkIds), baseSerNum, Keeper.State.CurrentSerNum},
+ std::move(commitChunks),
+ {},
+ std::move(callback),
+ IssueChunksStartingPoint,
+ {},
+ }, ctx);
+ IssueChunksStartingPoint = false;
+ }
+
+ void TLogger::LogChunkDeletion(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, ui32 numItems,
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
+ ProcessChunkQueueItem(TChunkQueueItem{
+ TChunkRecordMerger::TChunkDeletion{chunkIdx, chunkSerNum, numItems},
+ {},
TVector<TChunkIdx>{chunkIdx},
- std::move(callback),
- IssueChunksStartingPoint,
- {},
- }, ctx);
- IssueChunksStartingPoint = false;
- }
-
- void TLogger::LogCompleteChunk(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, const TActorContext& ctx) {
- ProcessChunkQueueItem(TChunkQueueItem{
- TChunkRecordMerger::TCompleteChunk{chunkIdx, chunkSerNum},
- {},
- {},
- {},
- IssueChunksStartingPoint,
- {},
- }, ctx);
- IssueChunksStartingPoint = false;
- }
-
- void TLogger::ProcessChunkQueueItem(TChunkQueueItem&& newItem, const TActorContext& ctx) {
- // if there is an entrypoint log pending, we do not accept new items, we put 'em into waiting queue
- if (LogChunksEntrypointPending) {
- PendingChunkQueue.push_back(std::move(newItem));
- return;
- }
-
- // insert new item into end of queue and get a reference to it
- ChunkQueue.push_back(std::move(newItem));
- TChunkQueueItem& item = ChunkQueue.back();
-
- // serialize it into string
+ std::move(callback),
+ IssueChunksStartingPoint,
+ {},
+ }, ctx);
+ IssueChunksStartingPoint = false;
+ }
+
+ void TLogger::LogCompleteChunk(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, const TActorContext& ctx) {
+ ProcessChunkQueueItem(TChunkQueueItem{
+ TChunkRecordMerger::TCompleteChunk{chunkIdx, chunkSerNum},
+ {},
+ {},
+ {},
+ IssueChunksStartingPoint,
+ {},
+ }, ctx);
+ IssueChunksStartingPoint = false;
+ }
+
+ void TLogger::ProcessChunkQueueItem(TChunkQueueItem&& newItem, const TActorContext& ctx) {
+ // if there is an entrypoint log pending, we do not accept new items, we put 'em into waiting queue
+ if (LogChunksEntrypointPending) {
+ PendingChunkQueue.push_back(std::move(newItem));
+ return;
+ }
+
+ // insert new item into end of queue and get a reference to it
+ ChunkQueue.push_back(std::move(newItem));
+ TChunkQueueItem& item = ChunkQueue.back();
+
+ // serialize it into string
TString data = std::visit([](const auto& content) { return TChunkRecordMerger::Serialize(content); }, item.Content);
-
- // generate LSN
- item.Lsn = Lsn++;
-
- // create callback which will be invoked by yard
- auto callback = [this, p = &item](NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
- ApplyLogChunkItem(*p, status, msg, ctx);
- };
-
- // create commit record
- NPDisk::TCommitRecord commit;
- commit.IsStartingPoint = item.Entrypoint;
- commit.CommitChunks = std::move(item.CommitChunks);
- commit.DeleteChunks = std::move(item.DeleteChunks);
- commit.FirstLsnToKeep = GetFirstLsnToKeep(item.Entrypoint ? EEntrypointType::Chunks : EEntrypointType::None);
-
- // issue log record
+
+ // generate LSN
+ item.Lsn = Lsn++;
+
+ // create callback which will be invoked by yard
+ auto callback = [this, p = &item](NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
+ ApplyLogChunkItem(*p, status, msg, ctx);
+ };
+
+ // create commit record
+ NPDisk::TCommitRecord commit;
+ commit.IsStartingPoint = item.Entrypoint;
+ commit.CommitChunks = std::move(item.CommitChunks);
+ commit.DeleteChunks = std::move(item.DeleteChunks);
+ commit.FirstLsnToKeep = GetFirstLsnToKeep(item.Entrypoint ? EEntrypointType::Chunks : EEntrypointType::None);
+
+ // issue log record
TLsnSeg seg(item.Lsn, item.Lsn);
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvLog(Keeper.State.PDiskParams->Owner,
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvLog(Keeper.State.PDiskParams->Owner,
Keeper.State.PDiskParams->OwnerRound, TLogSignature::SignatureIncrHugeChunks, commit, data,
seg, Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
-
- if (item.Entrypoint) {
- ProcessedChunksWithoutEntrypoint = 0;
- } else if (++ProcessedChunksWithoutEntrypoint >= 10) { // FIXME correct number
- LogChunksEntrypoint(ctx);
- }
- }
-
- void TLogger::ApplyLogChunkItem(TChunkQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
- const TActorContext& ctx) {
- Y_VERIFY(ChunkQueue && &item == &ChunkQueue.front());
-
- IHLOG_DEBUG(ctx, "ApplyLogChunkItem Lsn# %" PRIu64 " Status# %s",
+
+ if (item.Entrypoint) {
+ ProcessedChunksWithoutEntrypoint = 0;
+ } else if (++ProcessedChunksWithoutEntrypoint >= 10) { // FIXME correct number
+ LogChunksEntrypoint(ctx);
+ }
+ }
+
+ void TLogger::ApplyLogChunkItem(TChunkQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
+ const TActorContext& ctx) {
+ Y_VERIFY(ChunkQueue && &item == &ChunkQueue.front());
+
+ IHLOG_DEBUG(ctx, "ApplyLogChunkItem Lsn# %" PRIu64 " Status# %s",
item.Lsn, NKikimrProto::EReplyStatus_Name(status).data());
-
- if (status == NKikimrProto::OK) {
- // if this was an entrypoint, reset merger and update LSN
- if (item.Entrypoint) {
- Y_VERIFY(item.Lsn > ChunksEntrypointLsn);
- ChunksEntrypointLsn = item.Lsn;
- ConfirmedChunkMerger = TChunkRecordMerger();
- }
- // update confirmed state
+
+ if (status == NKikimrProto::OK) {
+ // if this was an entrypoint, reset merger and update LSN
+ if (item.Entrypoint) {
+ Y_VERIFY(item.Lsn > ChunksEntrypointLsn);
+ ChunksEntrypointLsn = item.Lsn;
+ ConfirmedChunkMerger = TChunkRecordMerger();
+ }
+ // update confirmed state
std::visit([this](const auto& content) { ConfirmedChunkMerger(content); }, item.Content);
- // if it was chunk deletion, propagate this information to deleter state
+ // if it was chunk deletion, propagate this information to deleter state
if (auto *record = std::get_if<TChunkRecordMerger::TChunkDeletion>(&item.Content)) {
- IHLOG_DEBUG(ctx, "DeleteChunk ChunkIdx# %" PRIu32 " ChunkSerNum# %s",
+ IHLOG_DEBUG(ctx, "DeleteChunk ChunkIdx# %" PRIu32 " ChunkSerNum# %s",
record->ChunkIdx, record->ChunkSerNum.ToString().data());
-
- TDeleteQueueItem deleteItem{
- TDeleteRecordMerger::TDeleteChunk{record->ChunkSerNum, record->NumItems}, // Content
- {}, // Callback
- false, // Entrypoint
- Lsn, // Lsn
- true, // Virtual
- false, // FailureExpected
- };
- DeleteQueue.push_back(std::move(deleteItem));
- ProcessDeleteQueueVirtualItems(ctx);
- }
- }
-
- // invoke callback
- if (std::unique_ptr<IEventCallback> callback = std::move(item.Callback)) {
- callback->Apply(status, msg, ctx);
- }
-
- // delete item
- ChunkQueue.pop_front();
-
- // if it was the last item and we have pending entrypoint set, then put it now
- if (!ChunkQueue && LogChunksEntrypointPending) {
- GenerateChunkEntrypoint(ctx);
- }
- }
-
- void TLogger::LogChunksEntrypoint(const TActorContext& ctx) {
- LogChunksEntrypointPending = true;
- if (!ChunkQueue) {
- GenerateChunkEntrypoint(ctx);
- }
- }
-
- void TLogger::GenerateChunkEntrypoint(const TActorContext& ctx) {
- Y_VERIFY(LogChunksEntrypointPending);
- LogChunksEntrypointPending = false;
-
- // create new queue of requests, starting from entrypoint and including all pending items
- TChunkQueue temp;
- temp.swap(PendingChunkQueue);
- temp.push_front(TChunkQueueItem{ConfirmedChunkMerger.GetCurrentState(), {}, {}, {}, true, {}});
-
- // process queue
- for (TChunkQueueItem& item : temp) {
- ProcessChunkQueueItem(std::move(item), ctx);
- }
- }
-
- void TLogger::SetInitialChunksState(const NKikimrVDiskData::TIncrHugeChunks& chunks) {
- ConfirmedChunkMerger(chunks);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // DELETE RECORDS PROCESSING LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
+ TDeleteQueueItem deleteItem{
+ TDeleteRecordMerger::TDeleteChunk{record->ChunkSerNum, record->NumItems}, // Content
+ {}, // Callback
+ false, // Entrypoint
+ Lsn, // Lsn
+ true, // Virtual
+ false, // FailureExpected
+ };
+ DeleteQueue.push_back(std::move(deleteItem));
+ ProcessDeleteQueueVirtualItems(ctx);
+ }
+ }
+
+ // invoke callback
+ if (std::unique_ptr<IEventCallback> callback = std::move(item.Callback)) {
+ callback->Apply(status, msg, ctx);
+ }
+
+ // delete item
+ ChunkQueue.pop_front();
+
+ // if it was the last item and we have pending entrypoint set, then put it now
+ if (!ChunkQueue && LogChunksEntrypointPending) {
+ GenerateChunkEntrypoint(ctx);
+ }
+ }
+
+ void TLogger::LogChunksEntrypoint(const TActorContext& ctx) {
+ LogChunksEntrypointPending = true;
+ if (!ChunkQueue) {
+ GenerateChunkEntrypoint(ctx);
+ }
+ }
+
+ void TLogger::GenerateChunkEntrypoint(const TActorContext& ctx) {
+ Y_VERIFY(LogChunksEntrypointPending);
+ LogChunksEntrypointPending = false;
+
+ // create new queue of requests, starting from entrypoint and including all pending items
+ TChunkQueue temp;
+ temp.swap(PendingChunkQueue);
+ temp.push_front(TChunkQueueItem{ConfirmedChunkMerger.GetCurrentState(), {}, {}, {}, true, {}});
+
+ // process queue
+ for (TChunkQueueItem& item : temp) {
+ ProcessChunkQueueItem(std::move(item), ctx);
+ }
+ }
+
+ void TLogger::SetInitialChunksState(const NKikimrVDiskData::TIncrHugeChunks& chunks) {
+ ConfirmedChunkMerger(chunks);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DELETE RECORDS PROCESSING LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
void TLogger::LogBlobDeletes(ui8 owner, ui64 seqNo, TVector<TBlobDeleteLocator>&& deleteLocators,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
- // check that locators are sorted and do not repeat
- Y_VERIFY(std::is_sorted(deleteLocators.begin(), deleteLocators.end()));
- Y_VERIFY(std::adjacent_find(deleteLocators.begin(), deleteLocators.end()) == deleteLocators.end());
-
- for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
- IHLOG_DEBUG(ctx, "LogBlobDeletes ChunkIdx# %" PRIu32 " ChunkSerNum# %s"
- " Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %" PRIu32 " Lsn# %" PRIu64
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
+ // check that locators are sorted and do not repeat
+ Y_VERIFY(std::is_sorted(deleteLocators.begin(), deleteLocators.end()));
+ Y_VERIFY(std::adjacent_find(deleteLocators.begin(), deleteLocators.end()) == deleteLocators.end());
+
+ for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
+ IHLOG_DEBUG(ctx, "LogBlobDeletes ChunkIdx# %" PRIu32 " ChunkSerNum# %s"
+ " Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %" PRIu32 " Lsn# %" PRIu64
" Owner# %d SeqNo# %" PRIu64, deleteLocator.ChunkIdx, deleteLocator.ChunkSerNum.ToString().data(),
- deleteLocator.Id, deleteLocator.IndexInsideChunk, deleteLocator.SizeInBlocks, Lsn, owner,
- seqNo);
- }
-
- // format blob deletes record
- TDeleteRecordMerger::TBlobDeletes record{owner, seqNo, std::move(deleteLocators)};
-
- // ensure that user has provided us a callback
- Y_VERIFY(callback);
- TVector<std::unique_ptr<IEventCallback>> callbacks;
- callbacks.push_back(std::move(callback));
-
- // create an item in the delete queue
- ProcessDeleteQueueItem(TDeleteQueueItem{
- std::move(record), // Content
- std::move(callbacks), // Callbacks
- false, // Entrypoint
- Lsn++, // Lsn
- false, // Virtual
- false, // FailureExpected
- }, ctx);
-
- // create entrypoint if needed
- if (++ProcessedDeletesWithoutEntrypoint == 100) { // FIXME: correct number
- LogDeletesEntrypoint(ctx);
- }
- }
-
+ deleteLocator.Id, deleteLocator.IndexInsideChunk, deleteLocator.SizeInBlocks, Lsn, owner,
+ seqNo);
+ }
+
+ // format blob deletes record
+ TDeleteRecordMerger::TBlobDeletes record{owner, seqNo, std::move(deleteLocators)};
+
+ // ensure that user has provided us a callback
+ Y_VERIFY(callback);
+ TVector<std::unique_ptr<IEventCallback>> callbacks;
+ callbacks.push_back(std::move(callback));
+
+ // create an item in the delete queue
+ ProcessDeleteQueueItem(TDeleteQueueItem{
+ std::move(record), // Content
+ std::move(callbacks), // Callbacks
+ false, // Entrypoint
+ Lsn++, // Lsn
+ false, // Virtual
+ false, // FailureExpected
+ }, ctx);
+
+ // create entrypoint if needed
+ if (++ProcessedDeletesWithoutEntrypoint == 100) { // FIXME: correct number
+ LogDeletesEntrypoint(ctx);
+ }
+ }
+
void TLogger::LogVirtualBlobDeletes(TVector<TBlobDeleteLocator>&& deleteLocators, const TActorContext& ctx) {
- // check that locators are sorted and do not repeat
- Y_VERIFY(std::is_sorted(deleteLocators.begin(), deleteLocators.end()));
- Y_VERIFY(std::adjacent_find(deleteLocators.begin(), deleteLocators.end()) == deleteLocators.end());
-
- for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
- IHLOG_DEBUG(ctx, "LogVirtualBlobDeletes ChunkIdx# %" PRIu32 " ChunkSerNum# %s"
- " Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %" PRIu32 " Lsn# %" PRIu64,
+ // check that locators are sorted and do not repeat
+ Y_VERIFY(std::is_sorted(deleteLocators.begin(), deleteLocators.end()));
+ Y_VERIFY(std::adjacent_find(deleteLocators.begin(), deleteLocators.end()) == deleteLocators.end());
+
+ for (const TBlobDeleteLocator& deleteLocator : deleteLocators) {
+ IHLOG_DEBUG(ctx, "LogVirtualBlobDeletes ChunkIdx# %" PRIu32 " ChunkSerNum# %s"
+ " Id# %016" PRIx64 " IndexInsideChunk# %" PRIu32 " SizeInBlocks# %" PRIu32 " Lsn# %" PRIu64,
deleteLocator.ChunkIdx, deleteLocator.ChunkSerNum.ToString().data(), deleteLocator.Id,
- deleteLocator.IndexInsideChunk, deleteLocator.SizeInBlocks, Lsn);
- }
-
- DeleteQueue.push_back(TDeleteQueueItem{
- TDeleteRecordMerger::TBlobDeletes{0, 0, std::move(deleteLocators)}, // Content
- {}, // Callbacks
- false, // Entrypoint
- Lsn, // Lsn
- true, // Virtual
- false, // FailureExpected
- });
-
- ProcessDeleteQueueVirtualItems(ctx);
- }
-
- void TLogger::SetInitialDeletesState(const NKikimrVDiskData::TIncrHugeDelete& record) {
- // just add this record to merger
- ConfirmedDeletesMerger(record);
- }
-
- void TLogger::LogDeletesEntrypoint(const TActorContext& ctx) {
- // combine all in-flight records with current confirmed state (or find last entrypoint and merge all other
- // items after it)
- TDeleteRecordMerger merger;
- auto it = DeleteQueue.end();
- while (it != DeleteQueue.begin()) {
- --it;
- if (it->Entrypoint) {
- break;
- }
- }
- if (it == DeleteQueue.end() || !it->Entrypoint) {
- merger = ConfirmedDeletesMerger;
- }
- for (; it != DeleteQueue.end(); ++it) {
+ deleteLocator.IndexInsideChunk, deleteLocator.SizeInBlocks, Lsn);
+ }
+
+ DeleteQueue.push_back(TDeleteQueueItem{
+ TDeleteRecordMerger::TBlobDeletes{0, 0, std::move(deleteLocators)}, // Content
+ {}, // Callbacks
+ false, // Entrypoint
+ Lsn, // Lsn
+ true, // Virtual
+ false, // FailureExpected
+ });
+
+ ProcessDeleteQueueVirtualItems(ctx);
+ }
+
+ void TLogger::SetInitialDeletesState(const NKikimrVDiskData::TIncrHugeDelete& record) {
+ // just add this record to merger
+ ConfirmedDeletesMerger(record);
+ }
+
+ void TLogger::LogDeletesEntrypoint(const TActorContext& ctx) {
+ // combine all in-flight records with current confirmed state (or find last entrypoint and merge all other
+ // items after it)
+ TDeleteRecordMerger merger;
+ auto it = DeleteQueue.end();
+ while (it != DeleteQueue.begin()) {
+ --it;
+ if (it->Entrypoint) {
+ break;
+ }
+ }
+ if (it == DeleteQueue.end() || !it->Entrypoint) {
+ merger = ConfirmedDeletesMerger;
+ }
+ for (; it != DeleteQueue.end(); ++it) {
std::visit([&merger](const auto& content) { merger(content); }, it->Content);
- }
-
- // create new log queue item
- ProcessDeleteQueueItem(TDeleteQueueItem{
- merger.GetCurrentState(), // Content
- {}, // Callbacks
- true, // Entrypoint
- Lsn++, // Lsn
- false, // Virtual
- false, // FailureExpected
- }, ctx);
-
- // clear number of processed deletes without entrypoint
- ProcessedDeletesWithoutEntrypoint = 0;
- }
-
- void TLogger::ProcessDeleteQueueItem(TDeleteQueueItem&& newItem, const TActorContext& ctx) {
- // insert this item into queue and get a reference
- DeleteQueue.emplace_back(std::move(newItem));
- TDeleteQueueItem& item = DeleteQueue.back();
-
- IHLOG_DEBUG(ctx, "ProcessDeleteQueueItem Lsn# %" PRIu64 " Entrypoint# %s"
- " Virtual# %s", item.Lsn, item.Entrypoint ? "true" : "false", item.Virtual ? "true" : "false");
-
- if (item.Virtual) {
- ProcessDeleteQueueVirtualItems(ctx);
- return;
- }
-
- // create callback that will be invoked upon completion of log
- auto callback = [this, p = &item](NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
- IHLOG_DEBUG(ctx, "ProcessDeleteQueueItem Lsn# %" PRIu64 " Status# %s",
+ }
+
+ // create new log queue item
+ ProcessDeleteQueueItem(TDeleteQueueItem{
+ merger.GetCurrentState(), // Content
+ {}, // Callbacks
+ true, // Entrypoint
+ Lsn++, // Lsn
+ false, // Virtual
+ false, // FailureExpected
+ }, ctx);
+
+ // clear number of processed deletes without entrypoint
+ ProcessedDeletesWithoutEntrypoint = 0;
+ }
+
+ void TLogger::ProcessDeleteQueueItem(TDeleteQueueItem&& newItem, const TActorContext& ctx) {
+ // insert this item into queue and get a reference
+ DeleteQueue.emplace_back(std::move(newItem));
+ TDeleteQueueItem& item = DeleteQueue.back();
+
+ IHLOG_DEBUG(ctx, "ProcessDeleteQueueItem Lsn# %" PRIu64 " Entrypoint# %s"
+ " Virtual# %s", item.Lsn, item.Entrypoint ? "true" : "false", item.Virtual ? "true" : "false");
+
+ if (item.Virtual) {
+ ProcessDeleteQueueVirtualItems(ctx);
+ return;
+ }
+
+ // create callback that will be invoked upon completion of log
+ auto callback = [this, p = &item](NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
+ IHLOG_DEBUG(ctx, "ProcessDeleteQueueItem Lsn# %" PRIu64 " Status# %s",
p->Lsn, NKikimrProto::EReplyStatus_Name(status).data());
- ApplyLogDeleteItem(*p, status, msg, ctx);
- };
-
- // serialize it into string, depending on its type
+ ApplyLogDeleteItem(*p, status, msg, ctx);
+ };
+
+ // serialize it into string, depending on its type
TString data = std::visit([](const auto& content) { return TDeleteRecordMerger::Serialize(content); }, item.Content);
-
- // format commit record
- NPDisk::TCommitRecord commit;
- commit.IsStartingPoint = item.Entrypoint;
- commit.FirstLsnToKeep = GetFirstLsnToKeep(item.Entrypoint ? EEntrypointType::Deletes : EEntrypointType::None);
-
- // send record to logger
+
+ // format commit record
+ NPDisk::TCommitRecord commit;
+ commit.IsStartingPoint = item.Entrypoint;
+ commit.FirstLsnToKeep = GetFirstLsnToKeep(item.Entrypoint ? EEntrypointType::Deletes : EEntrypointType::None);
+
+ // send record to logger
TLsnSeg seg(item.Lsn, item.Lsn);
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvLog(Keeper.State.PDiskParams->Owner,
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvLog(Keeper.State.PDiskParams->Owner,
Keeper.State.PDiskParams->OwnerRound, TLogSignature::SignatureIncrHugeDeletes, commit, data,
seg, Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
- }
-
- void TLogger::ApplyLogDeleteItem(TDeleteQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
- const TActorContext& ctx) {
- // ensure FIFO order of records processing
- Y_VERIFY(DeleteQueue && &item == &DeleteQueue.front());
-
- // check if this item was virtual
- bool v = item.Virtual;
-
- if (status == NKikimrProto::OK) {
- // ensure that failure is not expected for this item (if it is not virtual)
- Y_VERIFY(!item.FailureExpected || v);
- // if this was an entrypoint, reset merger, update LSN
- if (item.Entrypoint) {
- Y_VERIFY(item.Lsn > DeletesEntrypointLsn);
- DeletesEntrypointLsn = item.Lsn;
- ConfirmedDeletesMerger = TDeleteRecordMerger();
- }
- // update confirmed state
- IHLOG_DEBUG(ctx, "ApplyLogDeleteItem Entrypoint# %s Lsn# %" PRIu64
- " Virtual# %s", item.Entrypoint ? "true" : "false", item.Lsn, item.Virtual ? "true" : "false");
+ }
+
+ void TLogger::ApplyLogDeleteItem(TDeleteQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
+ const TActorContext& ctx) {
+ // ensure FIFO order of records processing
+ Y_VERIFY(DeleteQueue && &item == &DeleteQueue.front());
+
+ // check if this item was virtual
+ bool v = item.Virtual;
+
+ if (status == NKikimrProto::OK) {
+ // ensure that failure is not expected for this item (if it is not virtual)
+ Y_VERIFY(!item.FailureExpected || v);
+ // if this was an entrypoint, reset merger, update LSN
+ if (item.Entrypoint) {
+ Y_VERIFY(item.Lsn > DeletesEntrypointLsn);
+ DeletesEntrypointLsn = item.Lsn;
+ ConfirmedDeletesMerger = TDeleteRecordMerger();
+ }
+ // update confirmed state
+ IHLOG_DEBUG(ctx, "ApplyLogDeleteItem Entrypoint# %s Lsn# %" PRIu64
+ " Virtual# %s", item.Entrypoint ? "true" : "false", item.Lsn, item.Virtual ? "true" : "false");
std::visit([this](const auto& content) { ConfirmedDeletesMerger(content); }, item.Content);
- } else {
- // set failure expected flag for all pending items -- they are already in flight and should also fail
- for (TDeleteQueueItem& item : DeleteQueue) {
- item.FailureExpected = true;
- }
- }
-
- // invoke all pending callbacks; they must be non-null
- for (const auto& callback : item.Callbacks) {
- callback->Apply(status, msg, ctx);
- }
-
- // remove item from queue
- DeleteQueue.pop_front();
-
- // process virtual items if it was the real one
- if (!v) {
- ProcessDeleteQueueVirtualItems(ctx);
- }
- }
-
- void TLogger::ProcessDeleteQueueVirtualItems(const TActorContext& ctx) {
- while (DeleteQueue && DeleteQueue.front().Virtual) {
- TDeleteQueueItem& item = DeleteQueue.front();
- ApplyLogDeleteItem(item, NKikimrProto::OK, nullptr, ctx);
- }
- }
-
- ui64 TLogger::GetFirstLsnToKeep(EEntrypointType ep) const {
- ui64 lsn = Max<ui64>();
- if (ep != EEntrypointType::Chunks && ChunksEntrypointLsn < lsn) {
- lsn = ChunksEntrypointLsn;
- }
- if (ep != EEntrypointType::Deletes && DeletesEntrypointLsn < lsn) {
- lsn = DeletesEntrypointLsn;
- }
- return lsn;
- }
-
- void TLogger::HandleCutLog(NPDisk::TEvCutLog& msg, const TActorContext& ctx) {
- if (ChunksEntrypointLsn < msg.FreeUpToLsn) {
- LogChunksEntrypoint(ctx);
- }
- if (DeletesEntrypointLsn < msg.FreeUpToLsn) {
- LogDeletesEntrypoint(ctx);
- }
- }
-
- } // NIncrHuge
-} // NKikimr
+ } else {
+ // set failure expected flag for all pending items -- they are already in flight and should also fail
+ for (TDeleteQueueItem& item : DeleteQueue) {
+ item.FailureExpected = true;
+ }
+ }
+
+ // invoke all pending callbacks; they must be non-null
+ for (const auto& callback : item.Callbacks) {
+ callback->Apply(status, msg, ctx);
+ }
+
+ // remove item from queue
+ DeleteQueue.pop_front();
+
+ // process virtual items if it was the real one
+ if (!v) {
+ ProcessDeleteQueueVirtualItems(ctx);
+ }
+ }
+
+ void TLogger::ProcessDeleteQueueVirtualItems(const TActorContext& ctx) {
+ while (DeleteQueue && DeleteQueue.front().Virtual) {
+ TDeleteQueueItem& item = DeleteQueue.front();
+ ApplyLogDeleteItem(item, NKikimrProto::OK, nullptr, ctx);
+ }
+ }
+
+ ui64 TLogger::GetFirstLsnToKeep(EEntrypointType ep) const {
+ ui64 lsn = Max<ui64>();
+ if (ep != EEntrypointType::Chunks && ChunksEntrypointLsn < lsn) {
+ lsn = ChunksEntrypointLsn;
+ }
+ if (ep != EEntrypointType::Deletes && DeletesEntrypointLsn < lsn) {
+ lsn = DeletesEntrypointLsn;
+ }
+ return lsn;
+ }
+
+ void TLogger::HandleCutLog(NPDisk::TEvCutLog& msg, const TActorContext& ctx) {
+ if (ChunksEntrypointLsn < msg.FreeUpToLsn) {
+ LogChunksEntrypoint(ctx);
+ }
+ if (DeletesEntrypointLsn < msg.FreeUpToLsn) {
+ LogDeletesEntrypoint(ctx);
+ }
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h
index bbb566f634e..99698e185d0 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h
@@ -1,231 +1,231 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-
-#include <util/generic/hash_set.h>
-#include <util/generic/set.h>
-
-namespace NKikimrVDiskData {
- class TIncrHugeChunks;
-} // NKikimrVDiskData
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TChunkRecordMerger {
- struct TChunkInfo {
- TChunkSerNum ChunkSerNum;
- NKikimrVDiskData::TIncrHugeChunks::EChunkState State;
- };
-
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+
+#include <util/generic/hash_set.h>
+#include <util/generic/set.h>
+
+namespace NKikimrVDiskData {
+ class TIncrHugeChunks;
+} // NKikimrVDiskData
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TChunkRecordMerger {
+ struct TChunkInfo {
+ TChunkSerNum ChunkSerNum;
+ NKikimrVDiskData::TIncrHugeChunks::EChunkState State;
+ };
+
THashMap<TChunkIdx, TChunkInfo> Chunks;
- TMaybe<TChunkSerNum> CurrentSerNum;
-
- public:
- struct TChunkAllocation {
+ TMaybe<TChunkSerNum> CurrentSerNum;
+
+ public:
+ struct TChunkAllocation {
TVector<TChunkIdx> NewChunkIds;
- TChunkSerNum BaseSerNum;
- TChunkSerNum CurrentSerNum;
- };
-
- struct TChunkDeletion {
- TChunkIdx ChunkIdx;
- TChunkSerNum ChunkSerNum;
- ui32 NumItems;
- };
-
- struct TCompleteChunk {
- TChunkIdx ChunkIdx;
- TChunkSerNum ChunkSerNum;
- };
-
- public:
- void operator ()(const NKikimrVDiskData::TIncrHugeChunks& record);
- void operator ()(const TChunkAllocation& record);
- void operator ()(const TChunkDeletion& record);
- void operator ()(const TCompleteChunk& record);
- NKikimrVDiskData::TIncrHugeChunks GetCurrentState() const;
-
+ TChunkSerNum BaseSerNum;
+ TChunkSerNum CurrentSerNum;
+ };
+
+ struct TChunkDeletion {
+ TChunkIdx ChunkIdx;
+ TChunkSerNum ChunkSerNum;
+ ui32 NumItems;
+ };
+
+ struct TCompleteChunk {
+ TChunkIdx ChunkIdx;
+ TChunkSerNum ChunkSerNum;
+ };
+
+ public:
+ void operator ()(const NKikimrVDiskData::TIncrHugeChunks& record);
+ void operator ()(const TChunkAllocation& record);
+ void operator ()(const TChunkDeletion& record);
+ void operator ()(const TCompleteChunk& record);
+ NKikimrVDiskData::TIncrHugeChunks GetCurrentState() const;
+
static TString Serialize(const NKikimrVDiskData::TIncrHugeChunks& record);
static TString Serialize(const TChunkAllocation& record);
static TString Serialize(const TChunkDeletion& record);
static TString Serialize(const TCompleteChunk& record);
- };
-
- class TDeleteRecordMerger {
+ };
+
+ class TDeleteRecordMerger {
THashMap<ui8, ui64> OwnerToSeqNo;
THashMap<TChunkSerNum, TDynBitMap> SerNumToChunk;
-
- public:
- struct TBlobDeletes {
- ui8 Owner;
- ui64 SeqNo;
+
+ public:
+ struct TBlobDeletes {
+ ui8 Owner;
+ ui64 SeqNo;
TVector<TBlobDeleteLocator> DeleteLocators;
- };
-
- // delete chunk -- a pure virtual record that is never written to real log
- struct TDeleteChunk {
- TChunkSerNum ChunkSerNum;
- ui32 NumItems;
- };
-
- public:
- void operator ()(const NKikimrVDiskData::TIncrHugeDelete& record);
- void operator ()(const TBlobDeletes& record);
- void operator ()(const TDeleteChunk& record);
- NKikimrVDiskData::TIncrHugeDelete GetCurrentState() const;
-
+ };
+
+ // delete chunk -- a pure virtual record that is never written to real log
+ struct TDeleteChunk {
+ TChunkSerNum ChunkSerNum;
+ ui32 NumItems;
+ };
+
+ public:
+ void operator ()(const NKikimrVDiskData::TIncrHugeDelete& record);
+ void operator ()(const TBlobDeletes& record);
+ void operator ()(const TDeleteChunk& record);
+ NKikimrVDiskData::TIncrHugeDelete GetCurrentState() const;
+
static TString Serialize(const NKikimrVDiskData::TIncrHugeDelete& record);
static TString Serialize(const TBlobDeletes& record);
static TString Serialize(const TDeleteChunk& record);
- };
-
- class TLogger
- : public TKeeperComponentBase
- {
- // LSN of all chunks entrypoint
- ui64 ChunksEntrypointLsn = 0;
-
- // LSN of deletes entrypoint
- ui64 DeletesEntrypointLsn = 0;
-
- // LSN of next record
- ui64 Lsn = -1;
-
- // should we issue initial entrypoints?
- bool IssueChunksStartingPoint = false;
-
- // accumulated list of allocated chunks waiting for commit
+ };
+
+ class TLogger
+ : public TKeeperComponentBase
+ {
+ // LSN of all chunks entrypoint
+ ui64 ChunksEntrypointLsn = 0;
+
+ // LSN of deletes entrypoint
+ ui64 DeletesEntrypointLsn = 0;
+
+ // LSN of next record
+ ui64 Lsn = -1;
+
+ // should we issue initial entrypoints?
+ bool IssueChunksStartingPoint = false;
+
+ // accumulated list of allocated chunks waiting for commit
TVector<TChunkIdx> PendingCleanChunks;
-
- /////////////////////////////
- // Chunk record operations //
- /////////////////////////////
-
- struct TChunkQueueItem;
+
+ /////////////////////////////
+ // Chunk record operations //
+ /////////////////////////////
+
+ struct TChunkQueueItem;
using TChunkQueue = TList<TChunkQueueItem>;
- TChunkQueue ChunkQueue;
- TChunkQueue PendingChunkQueue;
-
- // confirmed state of chunk merger
- TChunkRecordMerger ConfirmedChunkMerger;
-
- bool LogChunksEntrypointPending = false;
-
- ui32 ProcessedChunksWithoutEntrypoint = 0;
-
- //////////////////////////////
- // Delete record operations //
- //////////////////////////////
-
- struct TDeleteQueueItem;
+ TChunkQueue ChunkQueue;
+ TChunkQueue PendingChunkQueue;
+
+ // confirmed state of chunk merger
+ TChunkRecordMerger ConfirmedChunkMerger;
+
+ bool LogChunksEntrypointPending = false;
+
+ ui32 ProcessedChunksWithoutEntrypoint = 0;
+
+ //////////////////////////////
+ // Delete record operations //
+ //////////////////////////////
+
+ struct TDeleteQueueItem;
using TDeleteQueue = TList<TDeleteQueueItem>;
- TDeleteQueue DeleteQueue;
-
- // this merger contains confirmed state of deletes -- that is it includes all successfully completed delete
- // log records
- TDeleteRecordMerger ConfirmedDeletesMerger;
-
- // number of process deletes
- ui32 ProcessedDeletesWithoutEntrypoint = 0;
-
-#if INCRHUGE_HARDENED
- // sequence number check logic
- std::array<ui64, 256> LastSeqNo;
-#endif
-
- ////////////////////////////////////
- // GetFirstLsnToKeep optimization //
- ////////////////////////////////////
-
- enum class EEntrypointType {
- None,
- Chunks,
- Deletes,
- };
-
- public:
- TLogger(TKeeper& keeper);
- ~TLogger();
-
- // update LSN with new state
- void SetLsnOnRecovery(ui64 lsn, bool issueInitialStartingPoints);
-
- ////////////
- // Chunks //
- ////////////
-
+ TDeleteQueue DeleteQueue;
+
+ // this merger contains confirmed state of deletes -- that is it includes all successfully completed delete
+ // log records
+ TDeleteRecordMerger ConfirmedDeletesMerger;
+
+ // number of process deletes
+ ui32 ProcessedDeletesWithoutEntrypoint = 0;
+
+#if INCRHUGE_HARDENED
+ // sequence number check logic
+ std::array<ui64, 256> LastSeqNo;
+#endif
+
+ ////////////////////////////////////
+ // GetFirstLsnToKeep optimization //
+ ////////////////////////////////////
+
+ enum class EEntrypointType {
+ None,
+ Chunks,
+ Deletes,
+ };
+
+ public:
+ TLogger(TKeeper& keeper);
+ ~TLogger();
+
+ // update LSN with new state
+ void SetLsnOnRecovery(ui64 lsn, bool issueInitialStartingPoints);
+
+ ////////////
+ // Chunks //
+ ////////////
+
void LogChunkAllocation(TVector<TChunkIdx>&& newChunkIds, TChunkSerNum baseSerNum,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
-
- // log deletion of chunk
- void LogChunkDeletion(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, ui32 numItems,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
-
- // log appearance of new filled chunk; this is auxiliary event and may be dropped under some conditions; if
- // it is not actually logged, then one on recovery should scan one more chunk instead of just reading index
- void LogCompleteChunk(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, const TActorContext& ctx);
-
- // log chunks entrypoint; this function should be called when there is need to update entrypoint -- by time,
- // by request of PDisk or by some other criterion; here we should mention that this function doesn't log
- // it immediately; instead of that is sets flag and that actual query is executed when all pending requests
- // are logged
- void LogChunksEntrypoint(const TActorContext& ctx);
-
-
- void SetInitialChunksState(const NKikimrVDiskData::TIncrHugeChunks& record);
-
- /////////////
- // Deletes //
- /////////////
-
- // log deletion of some blobs; requests are executed one by one in FIFO order; locators should come in
- // sorted order
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
+
+ // log deletion of chunk
+ void LogChunkDeletion(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, ui32 numItems,
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
+
+ // log appearance of new filled chunk; this is auxiliary event and may be dropped under some conditions; if
+ // it is not actually logged, then one on recovery should scan one more chunk instead of just reading index
+ void LogCompleteChunk(TChunkIdx chunkIdx, TChunkSerNum chunkSerNum, const TActorContext& ctx);
+
+ // log chunks entrypoint; this function should be called when there is need to update entrypoint -- by time,
+ // by request of PDisk or by some other criterion; here we should mention that this function doesn't log
+ // it immediately; instead of that is sets flag and that actual query is executed when all pending requests
+ // are logged
+ void LogChunksEntrypoint(const TActorContext& ctx);
+
+
+ void SetInitialChunksState(const NKikimrVDiskData::TIncrHugeChunks& record);
+
+ /////////////
+ // Deletes //
+ /////////////
+
+ // log deletion of some blobs; requests are executed one by one in FIFO order; locators should come in
+ // sorted order
void LogBlobDeletes(ui8 owner, ui64 seqNo, TVector<TBlobDeleteLocator>&& deleteLocators,
- std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
-
+ std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
+
void LogVirtualBlobDeletes(TVector<TBlobDeleteLocator>&& deleteLocators, const TActorContext& ctx);
-
- // set initial state
- void SetInitialDeletesState(const NKikimrVDiskData::TIncrHugeDelete& record);
-
- // generate deletes entrypoint
- void LogDeletesEntrypoint(const TActorContext& ctx);
-
- // calculate first LSN of actual log record
- ui64 GetFirstLsnToKeep(EEntrypointType ep) const;
-
- // handle cut log message from yard
- void HandleCutLog(NPDisk::TEvCutLog& msg, const TActorContext& ctx);
-
- private:
- /////////////////////////
- // Chunk queue helpers //
- /////////////////////////
-
- void ProcessChunkQueueItem(TChunkQueueItem&& newItem, const TActorContext& ctx);
-
- void ApplyLogChunkItem(TChunkQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
- const TActorContext& ctx);
-
- void GenerateChunkEntrypoint(const TActorContext& ctx);
-
- //////////////////////////
- // Delete queue helpers //
- //////////////////////////
-
- // process new delete queue item and put it into delete queue
- void ProcessDeleteQueueItem(TDeleteQueueItem&& newItem, const TActorContext& ctx);
-
- void ProcessDeleteQueueVirtualItems(const TActorContext& ctx);
-
- // applies log result
- void ApplyLogDeleteItem(TDeleteQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
- const TActorContext& ctx);
- };
-
- void DeserializeDeletes(TDynBitMap& deletedItems, const NKikimrVDiskData::TIncrHugeDelete::TChunkInfo& chunk);
-
- } // NIncrHuge
-} // NKikimr
+
+ // set initial state
+ void SetInitialDeletesState(const NKikimrVDiskData::TIncrHugeDelete& record);
+
+ // generate deletes entrypoint
+ void LogDeletesEntrypoint(const TActorContext& ctx);
+
+ // calculate first LSN of actual log record
+ ui64 GetFirstLsnToKeep(EEntrypointType ep) const;
+
+ // handle cut log message from yard
+ void HandleCutLog(NPDisk::TEvCutLog& msg, const TActorContext& ctx);
+
+ private:
+ /////////////////////////
+ // Chunk queue helpers //
+ /////////////////////////
+
+ void ProcessChunkQueueItem(TChunkQueueItem&& newItem, const TActorContext& ctx);
+
+ void ApplyLogChunkItem(TChunkQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
+ const TActorContext& ctx);
+
+ void GenerateChunkEntrypoint(const TActorContext& ctx);
+
+ //////////////////////////
+ // Delete queue helpers //
+ //////////////////////////
+
+ // process new delete queue item and put it into delete queue
+ void ProcessDeleteQueueItem(TDeleteQueueItem&& newItem, const TActorContext& ctx);
+
+ void ProcessDeleteQueueVirtualItems(const TActorContext& ctx);
+
+ // applies log result
+ void ApplyLogDeleteItem(TDeleteQueueItem& item, NKikimrProto::EReplyStatus status, IEventBase *msg,
+ const TActorContext& ctx);
+ };
+
+ void DeserializeDeletes(TDynBitMap& deletedItems, const NKikimrVDiskData::TIncrHugeDelete::TChunkInfo& chunk);
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.cpp
index 62927ca8fe8..d82f5111774 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.cpp
@@ -1,88 +1,88 @@
-#include "incrhuge_keeper_read.h"
-#include "incrhuge_keeper.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TReader::TReader(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Reader")
- {}
-
- TReader::~TReader()
- {}
-
- void TReader::HandleRead(TEvIncrHugeRead::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeRead *msg = ev->Get();
-
- // fill queue item
- TReadQueueItem item{msg->Owner, msg->Id, msg->Offset, msg->Size, ev->Sender, ev->Cookie};
-
- // try to process it unless queue already has items
- if (ReadQueue || !ProcessReadItem(item, ctx)) {
- ReadQueue.push(std::move(item));
- }
- }
-
- bool TReader::ProcessReadItem(TReadQueueItem& item, const TActorContext& ctx) {
- const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(item.Id);
-
- // verify owner
- Y_VERIFY(locator.Owner == item.Owner);
-
- // calculate size we want to read
- const ui32 maxSize = item.Offset < locator.PayloadSize ? locator.PayloadSize - item.Offset : 0;
- const ui32 size = Min(maxSize, item.Size ? item.Size : maxSize);
-
- // if there is no data, reply now
- if (!size) {
- ctx.Send(item.Sender, new TEvIncrHugeReadResult(NKikimrProto::OK, {}), 0, item.Cookie);
- return true;
- }
-
- // calculate offset inside chunk (in bytes)
- ui32 offsetInChunk = locator.OffsetInBlocks * Keeper.State.BlockSize + sizeof(TBlobHeader) + item.Offset;
-
- // callback
- auto callback = [this, chunkIdx = locator.ChunkIdx, sender = item.Sender, cookie = item.Cookie]
- (NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
- auto it = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- --chunk.InFlightReq;
- if (!chunk.InFlightReq && chunk.State == EChunkState::Deleting) {
- Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
- }
-
+#include "incrhuge_keeper_read.h"
+#include "incrhuge_keeper.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TReader::TReader(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Reader")
+ {}
+
+ TReader::~TReader()
+ {}
+
+ void TReader::HandleRead(TEvIncrHugeRead::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeRead *msg = ev->Get();
+
+ // fill queue item
+ TReadQueueItem item{msg->Owner, msg->Id, msg->Offset, msg->Size, ev->Sender, ev->Cookie};
+
+ // try to process it unless queue already has items
+ if (ReadQueue || !ProcessReadItem(item, ctx)) {
+ ReadQueue.push(std::move(item));
+ }
+ }
+
+ bool TReader::ProcessReadItem(TReadQueueItem& item, const TActorContext& ctx) {
+ const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(item.Id);
+
+ // verify owner
+ Y_VERIFY(locator.Owner == item.Owner);
+
+ // calculate size we want to read
+ const ui32 maxSize = item.Offset < locator.PayloadSize ? locator.PayloadSize - item.Offset : 0;
+ const ui32 size = Min(maxSize, item.Size ? item.Size : maxSize);
+
+ // if there is no data, reply now
+ if (!size) {
+ ctx.Send(item.Sender, new TEvIncrHugeReadResult(NKikimrProto::OK, {}), 0, item.Cookie);
+ return true;
+ }
+
+ // calculate offset inside chunk (in bytes)
+ ui32 offsetInChunk = locator.OffsetInBlocks * Keeper.State.BlockSize + sizeof(TBlobHeader) + item.Offset;
+
+ // callback
+ auto callback = [this, chunkIdx = locator.ChunkIdx, sender = item.Sender, cookie = item.Cookie]
+ (NKikimrProto::EReplyStatus status, IEventBase *msg, const TActorContext& ctx) {
+ auto it = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ --chunk.InFlightReq;
+ if (!chunk.InFlightReq && chunk.State == EChunkState::Deleting) {
+ Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
+ }
+
TString data;
- NPDisk::TEvChunkReadResult& result = *static_cast<NPDisk::TEvChunkReadResult*>(msg);
- if (result.Data.IsReadable()) {
- data = result.Data.ToString();
- } else {
- status = NKikimrProto::ERROR;
- }
- ctx.Send(sender, new TEvIncrHugeReadResult(status, std::move(data)), 0, cookie);
- };
-
- // send request to yard
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(Keeper.State.PDiskParams->Owner,
- Keeper.State.PDiskParams->OwnerRound, locator.ChunkIdx, offsetInChunk, size,
- NPriRead::HullOnlineOther, Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
-
- // find chunk and spin request counter
- auto it = Keeper.State.Chunks.find(locator.ChunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.State != EChunkState::Deleting);
- ++chunk.InFlightReq;
-
- return true;
- }
-
- void TReader::ProcessReadQueue(const TActorContext& ctx) {
- while (ReadQueue && ProcessReadItem(ReadQueue.front(), ctx)) {
- ReadQueue.pop();
- }
- }
-
- } // NIncrHuge
-} // NKikimr
+ NPDisk::TEvChunkReadResult& result = *static_cast<NPDisk::TEvChunkReadResult*>(msg);
+ if (result.Data.IsReadable()) {
+ data = result.Data.ToString();
+ } else {
+ status = NKikimrProto::ERROR;
+ }
+ ctx.Send(sender, new TEvIncrHugeReadResult(status, std::move(data)), 0, cookie);
+ };
+
+ // send request to yard
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(Keeper.State.PDiskParams->Owner,
+ Keeper.State.PDiskParams->OwnerRound, locator.ChunkIdx, offsetInChunk, size,
+ NPriRead::HullOnlineOther, Keeper.RegisterYardCallback(MakeCallback(std::move(callback)))));
+
+ // find chunk and spin request counter
+ auto it = Keeper.State.Chunks.find(locator.ChunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.State != EChunkState::Deleting);
+ ++chunk.InFlightReq;
+
+ return true;
+ }
+
+ void TReader::ProcessReadQueue(const TActorContext& ctx) {
+ while (ReadQueue && ProcessReadItem(ReadQueue.front(), ctx)) {
+ ReadQueue.pop();
+ }
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.h
index d6e104d7d79..d7e662f4096 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_read.h
@@ -1,43 +1,43 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge.h"
-
-#include <util/generic/queue.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TReader
- : public TKeeperComponentBase
- {
- struct TReadQueueItem {
- ui8 Owner;
- TIncrHugeBlobId Id;
- ui32 Offset;
- ui32 Size;
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge.h"
+
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TReader
+ : public TKeeperComponentBase
+ {
+ struct TReadQueueItem {
+ ui8 Owner;
+ TIncrHugeBlobId Id;
+ ui32 Offset;
+ ui32 Size;
TActorId Sender;
- ui64 Cookie;
- };
+ ui64 Cookie;
+ };
using TReadQueue = TQueue<TReadQueueItem>;
- TReadQueue ReadQueue;
-
- public:
- TReader(TKeeper& keeper);
- ~TReader();
-
- // register read request; it is executed immediately or placed in queue depending on settings of keeper
- void HandleRead(TEvIncrHugeRead::TPtr& ev, const TActorContext& ctx);
-
- private:
- // process read queue item; return true if item is processed and can be deleted from queues; otherwise it
- // returns false
- bool ProcessReadItem(TReadQueueItem& item, const TActorContext& ctx);
-
- // process read queue items if possible
- void ProcessReadQueue(const TActorContext& ctx);
- };
-
- } // NIncrHuge
-} // NKikimr
+ TReadQueue ReadQueue;
+
+ public:
+ TReader(TKeeper& keeper);
+ ~TReader();
+
+ // register read request; it is executed immediately or placed in queue depending on settings of keeper
+ void HandleRead(TEvIncrHugeRead::TPtr& ev, const TActorContext& ctx);
+
+ private:
+ // process read queue item; return true if item is processed and can be deleted from queues; otherwise it
+ // returns false
+ bool ProcessReadItem(TReadQueueItem& item, const TActorContext& ctx);
+
+ // process read queue items if possible
+ void ProcessReadQueue(const TActorContext& ctx);
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.cpp
index afdf92e80d7..a2699659866 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.cpp
@@ -1,520 +1,520 @@
-#include "incrhuge_keeper_recovery.h"
-#include "incrhuge_keeper_recovery_read_log.h"
-#include "incrhuge_keeper_recovery_scan.h"
-#include "incrhuge_keeper.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
-
- TRecovery::TRecovery(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Recovery")
- {}
-
-
- TRecovery::~TRecovery()
- {}
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDISK INIT LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TRecovery::HandleInit(TEvIncrHugeInit::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeInit *msg = ev->Get();
-
- // initialize init queue item
- TInitQueueItem item{
- msg->VDiskId, // VDiskId
- msg->Owner, // Owner
- msg->FirstLsn, // FirstLsn
- ev->Sender, // Sender
- ev->Cookie, // Cookie
- {}, // ScanQueue
- {}, // DeletedItemsMap
- {} // Items
- };
-
- // put it into the end of init queue and try to process it if we are ready
- InitQueue.push_back(std::move(item));
- if (Keeper.State.Ready) {
- ProcessInitItem(--InitQueue.end(), ctx);
- }
- }
-
- void TRecovery::ProcessInitItem(TInitQueue::iterator it, const TActorContext& ctx) {
- TInitQueueItem& item = *it;
-
- // make a snapshot of items being currently written
- item.Items = Keeper.Writer.EnumerateItems(item.Owner, item.FirstLsn);
-
- // make up a scan queue -- a queue consisting of complete chunks; all other chunks just have been enumerated
- for (auto& pair : Keeper.State.Chunks) {
- const TChunkIdx chunkIdx = pair.first;
- TChunkInfo& chunk = pair.second;
- if (chunk.State != EChunkState::Complete) {
- continue;
- }
-
- // do not allow to delete this chunk while it is not scanned
- ++chunk.InFlightReq;
-
- // add chunk to scan queue
- item.ScanQueue.emplace(chunkIdx, &chunk);
-
- // create a snapshot of deleted items map for this chunk
- item.DeletedItemsMap.emplace(chunkIdx, chunk.DeletedItems);
- }
-
- // process scan queue as far as possible
- ProcessInitItemScanQueue(it, ctx);
- }
-
- void TRecovery::ProcessInitItemScanQueue(TInitQueue::iterator it, const TActorContext& ctx) {
- TInitQueueItem& item = *it;
-
- while (item.ScanQueue && (!ScanBytesInFlight || ScanBytesInFlight < Keeper.State.PDiskParams->ChunkSize)) {
- // extract first queue item
- TChunkIdx chunkIdx;
- TChunkInfo *chunk;
- std::tie(chunkIdx, chunk) = item.ScanQueue.front();
- item.ScanQueue.pop();
-
- // issue scan request
+#include "incrhuge_keeper_recovery.h"
+#include "incrhuge_keeper_recovery_read_log.h"
+#include "incrhuge_keeper_recovery_scan.h"
+#include "incrhuge_keeper.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+
+ TRecovery::TRecovery(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Recovery")
+ {}
+
+
+ TRecovery::~TRecovery()
+ {}
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDISK INIT LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void TRecovery::HandleInit(TEvIncrHugeInit::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeInit *msg = ev->Get();
+
+ // initialize init queue item
+ TInitQueueItem item{
+ msg->VDiskId, // VDiskId
+ msg->Owner, // Owner
+ msg->FirstLsn, // FirstLsn
+ ev->Sender, // Sender
+ ev->Cookie, // Cookie
+ {}, // ScanQueue
+ {}, // DeletedItemsMap
+ {} // Items
+ };
+
+ // put it into the end of init queue and try to process it if we are ready
+ InitQueue.push_back(std::move(item));
+ if (Keeper.State.Ready) {
+ ProcessInitItem(--InitQueue.end(), ctx);
+ }
+ }
+
+ void TRecovery::ProcessInitItem(TInitQueue::iterator it, const TActorContext& ctx) {
+ TInitQueueItem& item = *it;
+
+ // make a snapshot of items being currently written
+ item.Items = Keeper.Writer.EnumerateItems(item.Owner, item.FirstLsn);
+
+ // make up a scan queue -- a queue consisting of complete chunks; all other chunks just have been enumerated
+ for (auto& pair : Keeper.State.Chunks) {
+ const TChunkIdx chunkIdx = pair.first;
+ TChunkInfo& chunk = pair.second;
+ if (chunk.State != EChunkState::Complete) {
+ continue;
+ }
+
+ // do not allow to delete this chunk while it is not scanned
+ ++chunk.InFlightReq;
+
+ // add chunk to scan queue
+ item.ScanQueue.emplace(chunkIdx, &chunk);
+
+ // create a snapshot of deleted items map for this chunk
+ item.DeletedItemsMap.emplace(chunkIdx, chunk.DeletedItems);
+ }
+
+ // process scan queue as far as possible
+ ProcessInitItemScanQueue(it, ctx);
+ }
+
+ void TRecovery::ProcessInitItemScanQueue(TInitQueue::iterator it, const TActorContext& ctx) {
+ TInitQueueItem& item = *it;
+
+ while (item.ScanQueue && (!ScanBytesInFlight || ScanBytesInFlight < Keeper.State.PDiskParams->ChunkSize)) {
+ // extract first queue item
+ TChunkIdx chunkIdx;
+ TChunkInfo *chunk;
+ std::tie(chunkIdx, chunk) = item.ScanQueue.front();
+ item.ScanQueue.pop();
+
+ // issue scan request
const TActorId actorId = ctx.Register(CreateRecoveryScanActor(chunkIdx, true, chunk->ChunkSerNum,
- static_cast<ui64>(EScanCookie::Recovery), Keeper.State));
- const bool added = Keeper.State.ChildActors.insert(actorId).second;
- Y_VERIFY(added);
-
- // remember this actor
- ScannerMap.emplace(actorId, TScanInfo{it, chunkIdx, *chunk});
-
- // adjust in-flight counter
- ScanBytesInFlight += Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize;
- }
-
- // check if we have finished all pending chunks
- if (!item.DeletedItemsMap) {
- SendInitResponse(it, NKikimrProto::OK, ctx);
- }
- }
-
- void TRecovery::ApplyInitItemScan(TInitQueue::iterator it, TChunkIdx chunkIdx, TChunkInfo& chunk,
- TEvIncrHugeScanResult& msg, const TActorContext& ctx) {
- TInitQueueItem& item = *it;
-
- // find deleted items snapshot for this chunk
- auto delIt = item.DeletedItemsMap.find(chunkIdx);
- Y_VERIFY(delIt != item.DeletedItemsMap.end());
- TDynBitMap& deletedItems = delIt->second;
-
- // traverse index and extract required items
+ static_cast<ui64>(EScanCookie::Recovery), Keeper.State));
+ const bool added = Keeper.State.ChildActors.insert(actorId).second;
+ Y_VERIFY(added);
+
+ // remember this actor
+ ScannerMap.emplace(actorId, TScanInfo{it, chunkIdx, *chunk});
+
+ // adjust in-flight counter
+ ScanBytesInFlight += Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize;
+ }
+
+ // check if we have finished all pending chunks
+ if (!item.DeletedItemsMap) {
+ SendInitResponse(it, NKikimrProto::OK, ctx);
+ }
+ }
+
+ void TRecovery::ApplyInitItemScan(TInitQueue::iterator it, TChunkIdx chunkIdx, TChunkInfo& chunk,
+ TEvIncrHugeScanResult& msg, const TActorContext& ctx) {
+ TInitQueueItem& item = *it;
+
+ // find deleted items snapshot for this chunk
+ auto delIt = item.DeletedItemsMap.find(chunkIdx);
+ Y_VERIFY(delIt != item.DeletedItemsMap.end());
+ TDynBitMap& deletedItems = delIt->second;
+
+ // traverse index and extract required items
for (ui32 i = 0; i < msg.Index.size(); ++i) {
- const TBlobIndexRecord& record = msg.Index[i];
- if (!deletedItems.Get(i) && record.Owner == item.Owner && record.Lsn >= item.FirstLsn) {
- item.Items.push_back(TEvIncrHugeInitResult::TItem{
- record.Id,
- record.Lsn,
- record.Meta
- });
- }
- }
-
- // remove unused item map
- item.DeletedItemsMap.erase(delIt);
-
- // dereference chunk
- if (!--chunk.InFlightReq && chunk.State == EChunkState::Deleting) {
- Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
- }
-
- // process more items
- ProcessInitItemScanQueue(it, ctx);
- }
-
- void TRecovery::SendInitResponse(TInitQueue::iterator it, NKikimrProto::EReplyStatus status,
- const TActorContext& ctx) {
- TInitQueueItem& item = *it;
- std::sort(item.Items.begin(), item.Items.end(), [](const auto& x, const auto& y) { return x.Lsn < y.Lsn; });
- ctx.Send(item.Sender, new TEvIncrHugeInitResult(status, std::move(item.Items)), 0, item.Cookie);
- InitQueue.erase(it);
- }
-
- void TRecovery::ApplyYardInit(NKikimrProto::EReplyStatus status, NPDisk::TLogRecord *chunks,
- NPDisk::TLogRecord *deletes, const TActorContext& ctx) {
- Y_VERIFY(status == NKikimrProto::OK);
-
- static const TMaybe<ui64> none;
+ const TBlobIndexRecord& record = msg.Index[i];
+ if (!deletedItems.Get(i) && record.Owner == item.Owner && record.Lsn >= item.FirstLsn) {
+ item.Items.push_back(TEvIncrHugeInitResult::TItem{
+ record.Id,
+ record.Lsn,
+ record.Meta
+ });
+ }
+ }
+
+ // remove unused item map
+ item.DeletedItemsMap.erase(delIt);
+
+ // dereference chunk
+ if (!--chunk.InFlightReq && chunk.State == EChunkState::Deleting) {
+ Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
+ }
+
+ // process more items
+ ProcessInitItemScanQueue(it, ctx);
+ }
+
+ void TRecovery::SendInitResponse(TInitQueue::iterator it, NKikimrProto::EReplyStatus status,
+ const TActorContext& ctx) {
+ TInitQueueItem& item = *it;
+ std::sort(item.Items.begin(), item.Items.end(), [](const auto& x, const auto& y) { return x.Lsn < y.Lsn; });
+ ctx.Send(item.Sender, new TEvIncrHugeInitResult(status, std::move(item.Items)), 0, item.Cookie);
+ InitQueue.erase(it);
+ }
+
+ void TRecovery::ApplyYardInit(NKikimrProto::EReplyStatus status, NPDisk::TLogRecord *chunks,
+ NPDisk::TLogRecord *deletes, const TActorContext& ctx) {
+ Y_VERIFY(status == NKikimrProto::OK);
+
+ static const TMaybe<ui64> none;
const TActorId actorId = ctx.Register(CreateRecoveryReadLogActor(Keeper.State.Settings.PDiskActorId,
- Keeper.State.PDiskParams->Owner, Keeper.State.PDiskParams->OwnerRound, chunks ? chunks->Lsn : none,
- deletes ? deletes->Lsn : none));
- const bool added = Keeper.State.ChildActors.insert(actorId).second;
- Y_VERIFY(added);
- IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] starting ReadLog", Keeper.State.Settings.PDiskId);
- }
-
+ Keeper.State.PDiskParams->Owner, Keeper.State.PDiskParams->OwnerRound, chunks ? chunks->Lsn : none,
+ deletes ? deletes->Lsn : none));
+ const bool added = Keeper.State.ChildActors.insert(actorId).second;
+ Y_VERIFY(added);
+ IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] starting ReadLog", Keeper.State.Settings.PDiskId);
+ }
+
void TRecovery::ApplyReadLog(const TActorId& sender, TEvIncrHugeReadLogResult& msg, const TActorContext& ctx) {
- const size_t num = Keeper.State.ChildActors.erase(sender);
- Y_VERIFY(num == 1);
-
- Y_VERIFY(msg.Status == NKikimrProto::OK);
-
- IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] finished ReadLog", Keeper.State.Settings.PDiskId);
-
- TStringStream str;
- str << "Chunks# [";
- bool first = true;
- for (const auto& chunk : msg.Chunks.GetChunks()) {
- str << (first ? first = false, "" : " ");
-
- const char *state = "<unknown>";
- switch (chunk.GetState()) {
- case NKikimrVDiskData::TIncrHugeChunks::Complete: state = "Complete"; break;
- case NKikimrVDiskData::TIncrHugeChunks::WriteIntent: state = "WriteIntent"; break;
- default: Y_FAIL("unexpected case");
- }
-
- TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
+ const size_t num = Keeper.State.ChildActors.erase(sender);
+ Y_VERIFY(num == 1);
+
+ Y_VERIFY(msg.Status == NKikimrProto::OK);
+
+ IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] finished ReadLog", Keeper.State.Settings.PDiskId);
+
+ TStringStream str;
+ str << "Chunks# [";
+ bool first = true;
+ for (const auto& chunk : msg.Chunks.GetChunks()) {
+ str << (first ? first = false, "" : " ");
+
+ const char *state = "<unknown>";
+ switch (chunk.GetState()) {
+ case NKikimrVDiskData::TIncrHugeChunks::Complete: state = "Complete"; break;
+ case NKikimrVDiskData::TIncrHugeChunks::WriteIntent: state = "WriteIntent"; break;
+ default: Y_FAIL("unexpected case");
+ }
+
+ TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
str << Sprintf("{Chunk# %" PRIu32 "@%s State# %s}", chunk.GetChunkIdx(), chunkSerNum.ToString().data(),
- state);
- }
- str << "] Deletes# [";
- first = true;
- for (const auto& chunk : msg.Deletes.GetChunks()) {
- str << (first ? first = false, "" : " ");
+ state);
+ }
+ str << "] Deletes# [";
+ first = true;
+ for (const auto& chunk : msg.Deletes.GetChunks()) {
+ str << (first ? first = false, "" : " ");
str << Sprintf("{ChunkSerNum# %s Items# [", TChunkSerNum(chunk.GetChunkSerNum()).ToString().data());
- bool itemFirst = true;
- TDynBitMap deletedItems;
- DeserializeDeletes(deletedItems, chunk);
- Y_FOR_EACH_BIT(index, deletedItems) {
- str << (itemFirst ? itemFirst = false, "" : " ") << index;
- }
- str << "]}";
- }
- str << "] Owners# {";
- first = true;
- for (const auto& owner : msg.Deletes.GetOwners()) {
- str << (first ? first = false, "" : " ") << owner.GetOwner() << ": " << owner.GetSeqNo();
- }
- str << Sprintf("} CurrentSerNum# %s NextLsn# %" PRIu64,
+ bool itemFirst = true;
+ TDynBitMap deletedItems;
+ DeserializeDeletes(deletedItems, chunk);
+ Y_FOR_EACH_BIT(index, deletedItems) {
+ str << (itemFirst ? itemFirst = false, "" : " ") << index;
+ }
+ str << "]}";
+ }
+ str << "] Owners# {";
+ first = true;
+ for (const auto& owner : msg.Deletes.GetOwners()) {
+ str << (first ? first = false, "" : " ") << owner.GetOwner() << ": " << owner.GetSeqNo();
+ }
+ str << Sprintf("} CurrentSerNum# %s NextLsn# %" PRIu64,
TChunkSerNum(msg.Chunks.GetCurrentSerNum()).ToString().data(), msg.NextLsn);
IHLOG_DEBUG(ctx, "ApplyReadLog %s", str.Str().data());
-
- // apply LSN and set starting points flag
- Keeper.Logger.SetLsnOnRecovery(msg.NextLsn, msg.IssueInitialStartingPoints);
-
- // if the record has actual id, store it; otherwise previously there were no time to span id and
- // it has default value
- if (msg.Chunks.HasCurrentSerNum()) {
- Keeper.State.CurrentSerNum = TChunkSerNum(msg.Chunks.GetCurrentSerNum());
- }
-
- // parse filled chunks list
+
+ // apply LSN and set starting points flag
+ Keeper.Logger.SetLsnOnRecovery(msg.NextLsn, msg.IssueInitialStartingPoints);
+
+ // if the record has actual id, store it; otherwise previously there were no time to span id and
+ // it has default value
+ if (msg.Chunks.HasCurrentSerNum()) {
+ Keeper.State.CurrentSerNum = TChunkSerNum(msg.Chunks.GetCurrentSerNum());
+ }
+
+ // parse filled chunks list
TMap<TChunkSerNum, TScanQueueItem> scanQueue;
THashMap<TChunkSerNum, TChunkInfo *> serNumToChunk;
- for (const auto& chunk : msg.Chunks.GetChunks()) {
- Y_VERIFY(chunk.HasChunkIdx() && chunk.HasChunkSerNum() && chunk.HasState());
-
- EChunkState newState;
- bool indexOnly;
-
- switch (chunk.GetState()) {
- case NKikimrVDiskData::TIncrHugeChunks::Complete:
- newState = EChunkState::Complete;
- indexOnly = true;
- break;
-
- case NKikimrVDiskData::TIncrHugeChunks::WriteIntent:
- newState = EChunkState::Unknown;
- indexOnly = false;
- break;
-
- default:
- Y_FAIL("unexpected case");
- }
-
- const TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
-
- TChunkInfo chunkInfo{
- newState, // State
- chunkSerNum, // ChunkSerNum
- 0, // NumUsedBlocks
- 0, // NumItems
- {}, // DeletedItems
- 0, // InFlightReq
- };
-
- auto chunkIt = Keeper.State.Chunks.emplace(chunk.GetChunkIdx(), std::move(chunkInfo)).first;
- serNumToChunk.emplace(chunkSerNum, &chunkIt->second);
-
- // enqueue scan; they are executed in order of increasing serial number, so we store them in sorted
- // map
- scanQueue.emplace(chunkSerNum, TScanQueueItem{chunk.GetChunkIdx(), indexOnly, chunkSerNum});
- }
-
- // start scans
- for (auto& pair : scanQueue) {
- EnqueueScan(std::move(pair.second), ctx);
- ChunkSerNumQueue.push(pair.first);
- }
- decltype(scanQueue)().swap(scanQueue);
-
- Keeper.Logger.SetInitialChunksState(msg.Chunks);
-
- // apply deletes
- for (const auto& chunk : msg.Deletes.GetChunks()) {
- // extract chunk's serial number
- Y_VERIFY(chunk.HasChunkSerNum());
- const TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
-
- // find chunk with such serial number
- auto it = serNumToChunk.find(chunkSerNum);
- if (it == serNumToChunk.end()) {
- // obsolete record -- ignoring it
- continue;
- }
-
- // deserialize deletes into found chunk
- DeserializeDeletes(it->second->DeletedItems, chunk);
- }
- Keeper.Logger.SetInitialDeletesState(msg.Deletes);
-
- // apply deletes' owners
- for (const auto& owner : msg.Deletes.GetOwners()) {
- Y_VERIFY(owner.HasOwner() && owner.HasSeqNo());
- Keeper.Deleter.InsertOwnerOnRecovery(owner.GetOwner(), owner.GetSeqNo());
- }
-
- ProcessScanQueue(ctx);
- }
-
+ for (const auto& chunk : msg.Chunks.GetChunks()) {
+ Y_VERIFY(chunk.HasChunkIdx() && chunk.HasChunkSerNum() && chunk.HasState());
+
+ EChunkState newState;
+ bool indexOnly;
+
+ switch (chunk.GetState()) {
+ case NKikimrVDiskData::TIncrHugeChunks::Complete:
+ newState = EChunkState::Complete;
+ indexOnly = true;
+ break;
+
+ case NKikimrVDiskData::TIncrHugeChunks::WriteIntent:
+ newState = EChunkState::Unknown;
+ indexOnly = false;
+ break;
+
+ default:
+ Y_FAIL("unexpected case");
+ }
+
+ const TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
+
+ TChunkInfo chunkInfo{
+ newState, // State
+ chunkSerNum, // ChunkSerNum
+ 0, // NumUsedBlocks
+ 0, // NumItems
+ {}, // DeletedItems
+ 0, // InFlightReq
+ };
+
+ auto chunkIt = Keeper.State.Chunks.emplace(chunk.GetChunkIdx(), std::move(chunkInfo)).first;
+ serNumToChunk.emplace(chunkSerNum, &chunkIt->second);
+
+ // enqueue scan; they are executed in order of increasing serial number, so we store them in sorted
+ // map
+ scanQueue.emplace(chunkSerNum, TScanQueueItem{chunk.GetChunkIdx(), indexOnly, chunkSerNum});
+ }
+
+ // start scans
+ for (auto& pair : scanQueue) {
+ EnqueueScan(std::move(pair.second), ctx);
+ ChunkSerNumQueue.push(pair.first);
+ }
+ decltype(scanQueue)().swap(scanQueue);
+
+ Keeper.Logger.SetInitialChunksState(msg.Chunks);
+
+ // apply deletes
+ for (const auto& chunk : msg.Deletes.GetChunks()) {
+ // extract chunk's serial number
+ Y_VERIFY(chunk.HasChunkSerNum());
+ const TChunkSerNum chunkSerNum(chunk.GetChunkSerNum());
+
+ // find chunk with such serial number
+ auto it = serNumToChunk.find(chunkSerNum);
+ if (it == serNumToChunk.end()) {
+ // obsolete record -- ignoring it
+ continue;
+ }
+
+ // deserialize deletes into found chunk
+ DeserializeDeletes(it->second->DeletedItems, chunk);
+ }
+ Keeper.Logger.SetInitialDeletesState(msg.Deletes);
+
+ // apply deletes' owners
+ for (const auto& owner : msg.Deletes.GetOwners()) {
+ Y_VERIFY(owner.HasOwner() && owner.HasSeqNo());
+ Keeper.Deleter.InsertOwnerOnRecovery(owner.GetOwner(), owner.GetSeqNo());
+ }
+
+ ProcessScanQueue(ctx);
+ }
+
void TRecovery::ApplyScan(const TActorId& sender, TEvIncrHugeScanResult& msg, const TActorContext& ctx) {
- const size_t num = Keeper.State.ChildActors.erase(sender);
- Y_VERIFY(num == 1);
-
- const ui32 bytes = msg.IndexOnly ? Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize :
- Keeper.State.PDiskParams->ChunkSize;
- Y_VERIFY(ScanBytesInFlight >= bytes);
- ScanBytesInFlight -= bytes;
-
- // try to find actor in scanner map
- auto it = ScannerMap.find(sender);
- if (it != ScannerMap.end()) {
- TScanInfo& scan = it->second;
- ApplyInitItemScan(scan.It, scan.ChunkIdx, scan.Chunk, msg, ctx);
- ScannerMap.erase(it);
- return;
- }
-
- // extract valuable information from message
- TScanResult scanResult{
- msg.Status,
- msg.ChunkIdx,
- msg.IndexOnly,
- msg.IndexValid,
- std::move(msg.Index)
- };
-
- // ensure that we still have chunk serial numbers to process; they are stored in ascending order, so we
- // process chunks starting from the oldest one
- Y_VERIFY(ChunkSerNumQueue);
-
- // if we can process this message right now, do it; otherwise store it for deferred execution
- if (msg.ChunkSerNum == ChunkSerNumQueue.front()) {
- ChunkSerNumQueue.pop();
- ProcessScanResult(scanResult, ctx);
-
- // we have advanced in current serial number, so check for deferred items queue -- we may have some
- // responses there
- decltype(PendingResults)::iterator it;
- while (ChunkSerNumQueue && (it = PendingResults.find(ChunkSerNumQueue.front())) != PendingResults.end()) {
- ChunkSerNumQueue.pop();
- ProcessScanResult(it->second, ctx);
- PendingResults.erase(it);
- }
-
- // issue more requests if possible
- ProcessScanQueue(ctx);
- } else {
- // just save the message for further processing
- PendingResults.emplace(msg.ChunkSerNum, std::move(scanResult));
- }
- }
-
- void TRecovery::ProcessScanResult(TScanResult& scanResult, const TActorContext& ctx) {
- // find matching chunk
- TChunkInfo& chunk = Keeper.State.Chunks.at(scanResult.ChunkIdx);
-
- IHLOG_DEBUG(ctx, "ProcessScanResult ChunkIdx# %" PRIu32 " ChunkSerNum# %s IndexOnly# %s IndexValid# %s",
+ const size_t num = Keeper.State.ChildActors.erase(sender);
+ Y_VERIFY(num == 1);
+
+ const ui32 bytes = msg.IndexOnly ? Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize :
+ Keeper.State.PDiskParams->ChunkSize;
+ Y_VERIFY(ScanBytesInFlight >= bytes);
+ ScanBytesInFlight -= bytes;
+
+ // try to find actor in scanner map
+ auto it = ScannerMap.find(sender);
+ if (it != ScannerMap.end()) {
+ TScanInfo& scan = it->second;
+ ApplyInitItemScan(scan.It, scan.ChunkIdx, scan.Chunk, msg, ctx);
+ ScannerMap.erase(it);
+ return;
+ }
+
+ // extract valuable information from message
+ TScanResult scanResult{
+ msg.Status,
+ msg.ChunkIdx,
+ msg.IndexOnly,
+ msg.IndexValid,
+ std::move(msg.Index)
+ };
+
+ // ensure that we still have chunk serial numbers to process; they are stored in ascending order, so we
+ // process chunks starting from the oldest one
+ Y_VERIFY(ChunkSerNumQueue);
+
+ // if we can process this message right now, do it; otherwise store it for deferred execution
+ if (msg.ChunkSerNum == ChunkSerNumQueue.front()) {
+ ChunkSerNumQueue.pop();
+ ProcessScanResult(scanResult, ctx);
+
+ // we have advanced in current serial number, so check for deferred items queue -- we may have some
+ // responses there
+ decltype(PendingResults)::iterator it;
+ while (ChunkSerNumQueue && (it = PendingResults.find(ChunkSerNumQueue.front())) != PendingResults.end()) {
+ ChunkSerNumQueue.pop();
+ ProcessScanResult(it->second, ctx);
+ PendingResults.erase(it);
+ }
+
+ // issue more requests if possible
+ ProcessScanQueue(ctx);
+ } else {
+ // just save the message for further processing
+ PendingResults.emplace(msg.ChunkSerNum, std::move(scanResult));
+ }
+ }
+
+ void TRecovery::ProcessScanResult(TScanResult& scanResult, const TActorContext& ctx) {
+ // find matching chunk
+ TChunkInfo& chunk = Keeper.State.Chunks.at(scanResult.ChunkIdx);
+
+ IHLOG_DEBUG(ctx, "ProcessScanResult ChunkIdx# %" PRIu32 " ChunkSerNum# %s IndexOnly# %s IndexValid# %s",
scanResult.ChunkIdx, chunk.ChunkSerNum.ToString().data(), scanResult.IndexOnly ? "true" : "false",
- scanResult.IndexValid ? "true" : "false");
-
- if (scanResult.Status == NKikimrProto::NODATA) {
- // this is really empty chunk, put it to write intent queue
- Y_VERIFY(!scanResult.IndexOnly);
- chunk.State = EChunkState::WriteIntent;
- Keeper.State.WriteIntentQueue.push(scanResult.ChunkIdx);
- } else if (scanResult.Status == NKikimrProto::OK) {
- // chunk with some data; calculate number of used blocks
- ui32 numUsedBlocks = 0;
- ui32 offsetInBlocks = 0;
+ scanResult.IndexValid ? "true" : "false");
+
+ if (scanResult.Status == NKikimrProto::NODATA) {
+ // this is really empty chunk, put it to write intent queue
+ Y_VERIFY(!scanResult.IndexOnly);
+ chunk.State = EChunkState::WriteIntent;
+ Keeper.State.WriteIntentQueue.push(scanResult.ChunkIdx);
+ } else if (scanResult.Status == NKikimrProto::OK) {
+ // chunk with some data; calculate number of used blocks
+ ui32 numUsedBlocks = 0;
+ ui32 offsetInBlocks = 0;
TVector<TBlobDeleteLocator> deleteLocators;
for (ui32 index = 0; index < scanResult.Index.size(); ++index) {
- const TBlobIndexRecord& record = scanResult.Index[index];
-
- // calculate item size in blocks
- const ui32 sizeInBlocks = (sizeof(TBlobHeader) + record.PayloadSize + Keeper.State.BlockSize - 1) /
- Keeper.State.BlockSize;
-
-// Cerr << Sprintf("ChunkSerNum# %s index# %" PRIu32 " record# %s deleted# %s\n",
-// ~chunk.ChunkSerNum.ToString(), index, ~record.ToString(),
-// chunk.DeletedItems.Get(index) ? "true" : "false");
-
- // count as used blocks unless this item is deleted
- TBlobLocator existing;
- if (!chunk.DeletedItems.Get(index)) {
- numUsedBlocks += sizeInBlocks;
-
- // create locator for new item
- TBlobLocator locator{scanResult.ChunkIdx, offsetInBlocks, record.PayloadSize, ui32(index),
- record.Owner, false};
-
- // try to insert new item; allow duplicates to be returned
- if (TBlobLocator *existing = Keeper.State.BlobLookup.Insert(record.Id, TBlobLocator(locator), true)) {
- // find existing chunk; it should exist just because we have created it recently during
- // recovery
- auto existingIt = Keeper.State.Chunks.find(existing->ChunkIdx);
- Y_VERIFY(existingIt != Keeper.State.Chunks.end());
- TChunkInfo& existingChunk = existingIt->second;
-
- // create delete locator for one of records (existing or new one)
- TBlobDeleteLocator deleteLocator;
-
- // sort by chunk ids; chunk ids are generated in ascending order, so newer chunks will have
- // greater id that the old ones; the only possible situation when duplicates occur is when
- // defragmented blob was not yet deleted from its previous location, so record with the most
- // id will win this race and will be marked as the real location of blob; the older record
- // will be marked as deleted
- if (existingChunk.ChunkSerNum < chunk.ChunkSerNum) {
- // existing record is older than the new one -- that it a duplicate and should be removed
- deleteLocator = {existing->ChunkIdx, existingChunk.ChunkSerNum, {},
- existing->IndexInsideChunk, sizeInBlocks};
- // replace existing record content with new one
- *existing = locator;
- } else if (chunk.ChunkSerNum < existingChunk.ChunkSerNum) {
- // fail as is breaks our order of processing -- old chunks first, then new chunks
- Y_FAIL("unexpected order of chunks");
- } else {
- // chunks are the same; this could happen if defragmenter was processing the current
- // chunk we were writing into, but this is completely incorrect behavior
- Y_FAIL("duplicate records; Old# %s New# %s ChunkSerNum# %s index# %" PRIu32,
+ const TBlobIndexRecord& record = scanResult.Index[index];
+
+ // calculate item size in blocks
+ const ui32 sizeInBlocks = (sizeof(TBlobHeader) + record.PayloadSize + Keeper.State.BlockSize - 1) /
+ Keeper.State.BlockSize;
+
+// Cerr << Sprintf("ChunkSerNum# %s index# %" PRIu32 " record# %s deleted# %s\n",
+// ~chunk.ChunkSerNum.ToString(), index, ~record.ToString(),
+// chunk.DeletedItems.Get(index) ? "true" : "false");
+
+ // count as used blocks unless this item is deleted
+ TBlobLocator existing;
+ if (!chunk.DeletedItems.Get(index)) {
+ numUsedBlocks += sizeInBlocks;
+
+ // create locator for new item
+ TBlobLocator locator{scanResult.ChunkIdx, offsetInBlocks, record.PayloadSize, ui32(index),
+ record.Owner, false};
+
+ // try to insert new item; allow duplicates to be returned
+ if (TBlobLocator *existing = Keeper.State.BlobLookup.Insert(record.Id, TBlobLocator(locator), true)) {
+ // find existing chunk; it should exist just because we have created it recently during
+ // recovery
+ auto existingIt = Keeper.State.Chunks.find(existing->ChunkIdx);
+ Y_VERIFY(existingIt != Keeper.State.Chunks.end());
+ TChunkInfo& existingChunk = existingIt->second;
+
+ // create delete locator for one of records (existing or new one)
+ TBlobDeleteLocator deleteLocator;
+
+ // sort by chunk ids; chunk ids are generated in ascending order, so newer chunks will have
+ // greater id that the old ones; the only possible situation when duplicates occur is when
+ // defragmented blob was not yet deleted from its previous location, so record with the most
+ // id will win this race and will be marked as the real location of blob; the older record
+ // will be marked as deleted
+ if (existingChunk.ChunkSerNum < chunk.ChunkSerNum) {
+ // existing record is older than the new one -- that it a duplicate and should be removed
+ deleteLocator = {existing->ChunkIdx, existingChunk.ChunkSerNum, {},
+ existing->IndexInsideChunk, sizeInBlocks};
+ // replace existing record content with new one
+ *existing = locator;
+ } else if (chunk.ChunkSerNum < existingChunk.ChunkSerNum) {
+ // fail as is breaks our order of processing -- old chunks first, then new chunks
+ Y_FAIL("unexpected order of chunks");
+ } else {
+ // chunks are the same; this could happen if defragmenter was processing the current
+ // chunk we were writing into, but this is completely incorrect behavior
+ Y_FAIL("duplicate records; Old# %s New# %s ChunkSerNum# %s index# %" PRIu32,
existing->ToString().data(), locator.ToString().data(),
existingChunk.ChunkSerNum.ToString().data(), index);
- }
-
- // schedule this record for deletion; do not delete it right now as it can be occasionally
- // deletes
- deleteLocators.push_back(std::move(deleteLocator));
- }
- } else if (Keeper.State.BlobLookup.Delete(record.Id, &existing)) {
- // we found existing locator, but newer record has delete flag set -- it means that this blob
- // was found in defragmented chunk and should be deleted
- auto it = Keeper.State.Chunks.find(existing.ChunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- deleteLocators.push_back(TBlobDeleteLocator{existing.ChunkIdx, chunk.ChunkSerNum, {},
- existing.IndexInsideChunk, sizeInBlocks});
- }
-
- // advance offset iterator
- offsetInBlocks += sizeInBlocks;
- }
-
- // update number of used blocks
- chunk.NumUsedBlocks = numUsedBlocks;
+ }
+
+ // schedule this record for deletion; do not delete it right now as it can be occasionally
+ // deletes
+ deleteLocators.push_back(std::move(deleteLocator));
+ }
+ } else if (Keeper.State.BlobLookup.Delete(record.Id, &existing)) {
+ // we found existing locator, but newer record has delete flag set -- it means that this blob
+ // was found in defragmented chunk and should be deleted
+ auto it = Keeper.State.Chunks.find(existing.ChunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ deleteLocators.push_back(TBlobDeleteLocator{existing.ChunkIdx, chunk.ChunkSerNum, {},
+ existing.IndexInsideChunk, sizeInBlocks});
+ }
+
+ // advance offset iterator
+ offsetInBlocks += sizeInBlocks;
+ }
+
+ // update number of used blocks
+ chunk.NumUsedBlocks = numUsedBlocks;
chunk.NumItems = scanResult.Index.size();
-
- // make actual deletes
- Keeper.Deleter.DeleteDefrag(std::move(deleteLocators), ctx);
-
- // check if index for this record is correct; if so, then put it into complete state
- if (scanResult.IndexValid) {
- chunk.State = EChunkState::Complete;
- } else {
- IncompleteChunks.emplace(chunk.ChunkSerNum, TIncompleteChunk{scanResult.ChunkIdx, offsetInBlocks,
- std::move(scanResult.Index)});
- }
- } else {
- Y_FAIL("can't recover");
- }
- }
-
- void TRecovery::EnqueueScan(TScanQueueItem&& item, const TActorContext& ctx) {
- if (ScanQueue || !ProcessScanItem(item, ctx)) {
- ScanQueue.push(std::move(item));
- }
- }
-
- bool TRecovery::ProcessScanItem(TScanQueueItem& item, const TActorContext& ctx) {
- const ui32 bytes = item.IndexOnly ? Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize :
- Keeper.State.PDiskParams->ChunkSize;
- if (ScanBytesInFlight && ScanBytesInFlight + bytes > Keeper.State.PDiskParams->ChunkSize) {
- return false;
- }
+
+ // make actual deletes
+ Keeper.Deleter.DeleteDefrag(std::move(deleteLocators), ctx);
+
+ // check if index for this record is correct; if so, then put it into complete state
+ if (scanResult.IndexValid) {
+ chunk.State = EChunkState::Complete;
+ } else {
+ IncompleteChunks.emplace(chunk.ChunkSerNum, TIncompleteChunk{scanResult.ChunkIdx, offsetInBlocks,
+ std::move(scanResult.Index)});
+ }
+ } else {
+ Y_FAIL("can't recover");
+ }
+ }
+
+ void TRecovery::EnqueueScan(TScanQueueItem&& item, const TActorContext& ctx) {
+ if (ScanQueue || !ProcessScanItem(item, ctx)) {
+ ScanQueue.push(std::move(item));
+ }
+ }
+
+ bool TRecovery::ProcessScanItem(TScanQueueItem& item, const TActorContext& ctx) {
+ const ui32 bytes = item.IndexOnly ? Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize :
+ Keeper.State.PDiskParams->ChunkSize;
+ if (ScanBytesInFlight && ScanBytesInFlight + bytes > Keeper.State.PDiskParams->ChunkSize) {
+ return false;
+ }
const TActorId actorId = ctx.Register(CreateRecoveryScanActor(item.ChunkIdx, item.IndexOnly,
- item.ChunkSerNum, static_cast<ui64>(EScanCookie::Recovery), Keeper.State));
- const bool added = Keeper.State.ChildActors.insert(actorId).second;
- Y_VERIFY(added);
- IHLOG_DEBUG(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] scan ChunkIdx# %" PRIu32
- " IndexOnly# %s", Keeper.State.Settings.PDiskId, item.ChunkIdx, item.IndexOnly ? "true" : "false");
- ScanBytesInFlight += bytes;
- return true;
- }
-
- void TRecovery::ProcessScanQueue(const TActorContext& ctx) {
- while (ScanQueue && ProcessScanItem(ScanQueue.front(), ctx)) {
- ScanQueue.pop();
- }
- if (!ScanQueue && !ScanBytesInFlight) {
- // check that we have actually processed all the scans and there are no hanging results
- Y_VERIFY(!ChunkSerNumQueue && !PendingResults);
-
- // apply incomplete chunks in order of write intent queue
- for (auto& pair : IncompleteChunks) {
- TIncompleteChunk& ic = pair.second;
-
- // check if there is a current chunk already set, then set up writer to write out index
- if (Keeper.State.CurrentChunk) {
- Keeper.Writer.FinishCurrentChunk(ctx);
- Y_VERIFY(!Keeper.State.CurrentChunk);
- }
-
- // set up new current chunk
- TChunkInfo& chunk = Keeper.State.Chunks.at(ic.ChunkIdx);
- chunk.State = EChunkState::Current;
- Keeper.State.CurrentChunk = ic.ChunkIdx;
- Keeper.Writer.SetUpCurrentChunk(ic.OffsetInBlocks, std::move(ic.Index));
- }
- IncompleteChunks.clear();
-
- // set ready flag and start processing all pending init queries
- Keeper.State.Ready = true;
- auto it = InitQueue.begin();
- while (it != InitQueue.end()) {
- auto next = std::next(it);
- ProcessInitItem(it, ctx);
- it = next;
- }
-
- // push all chunks to defragmenter as we are ready now
- for (const auto& pair : Keeper.State.Chunks) {
- Keeper.Defragmenter.UpdateChunkState(pair.first, ctx);
- }
-
- Keeper.Allocator.CheckForAllocationNeed(ctx);
-
- IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] ready", Keeper.State.Settings.PDiskId);
- }
- }
-
- } // NIncrHuge
-} // NKikimr
+ item.ChunkSerNum, static_cast<ui64>(EScanCookie::Recovery), Keeper.State));
+ const bool added = Keeper.State.ChildActors.insert(actorId).second;
+ Y_VERIFY(added);
+ IHLOG_DEBUG(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] scan ChunkIdx# %" PRIu32
+ " IndexOnly# %s", Keeper.State.Settings.PDiskId, item.ChunkIdx, item.IndexOnly ? "true" : "false");
+ ScanBytesInFlight += bytes;
+ return true;
+ }
+
+ void TRecovery::ProcessScanQueue(const TActorContext& ctx) {
+ while (ScanQueue && ProcessScanItem(ScanQueue.front(), ctx)) {
+ ScanQueue.pop();
+ }
+ if (!ScanQueue && !ScanBytesInFlight) {
+ // check that we have actually processed all the scans and there are no hanging results
+ Y_VERIFY(!ChunkSerNumQueue && !PendingResults);
+
+ // apply incomplete chunks in order of write intent queue
+ for (auto& pair : IncompleteChunks) {
+ TIncompleteChunk& ic = pair.second;
+
+ // check if there is a current chunk already set, then set up writer to write out index
+ if (Keeper.State.CurrentChunk) {
+ Keeper.Writer.FinishCurrentChunk(ctx);
+ Y_VERIFY(!Keeper.State.CurrentChunk);
+ }
+
+ // set up new current chunk
+ TChunkInfo& chunk = Keeper.State.Chunks.at(ic.ChunkIdx);
+ chunk.State = EChunkState::Current;
+ Keeper.State.CurrentChunk = ic.ChunkIdx;
+ Keeper.Writer.SetUpCurrentChunk(ic.OffsetInBlocks, std::move(ic.Index));
+ }
+ IncompleteChunks.clear();
+
+ // set ready flag and start processing all pending init queries
+ Keeper.State.Ready = true;
+ auto it = InitQueue.begin();
+ while (it != InitQueue.end()) {
+ auto next = std::next(it);
+ ProcessInitItem(it, ctx);
+ it = next;
+ }
+
+ // push all chunks to defragmenter as we are ready now
+ for (const auto& pair : Keeper.State.Chunks) {
+ Keeper.Defragmenter.UpdateChunkState(pair.first, ctx);
+ }
+
+ Keeper.Allocator.CheckForAllocationNeed(ctx);
+
+ IHLOG_INFO(ctx, "[IncrHugeKeeper PDisk# %09" PRIu32 "] ready", Keeper.State.Settings.PDiskId);
+ }
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.h
index 53463b80c90..20a77b03b4f 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery.h
@@ -1,97 +1,97 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge.h"
-
-#include <util/generic/queue.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TRecovery
- : public TKeeperComponentBase
- {
- struct TInitQueueItem {
- TVDiskID VDiskId;
- ui8 Owner;
- ui64 FirstLsn;
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge.h"
+
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TRecovery
+ : public TKeeperComponentBase
+ {
+ struct TInitQueueItem {
+ TVDiskID VDiskId;
+ ui8 Owner;
+ ui64 FirstLsn;
TActorId Sender;
- ui64 Cookie;
+ ui64 Cookie;
TQueue<std::pair<TChunkIdx, TChunkInfo *>> ScanQueue;
THashMap<TChunkIdx, TDynBitMap> DeletedItemsMap;
TVector<TEvIncrHugeInitResult::TItem> Items;
- };
+ };
using TInitQueue = TList<TInitQueueItem>;
- TInitQueue InitQueue;
-
- struct TScanQueueItem {
- TChunkIdx ChunkIdx;
- bool IndexOnly;
- TChunkSerNum ChunkSerNum;
-
- friend bool operator <(const TScanQueueItem& left, const TScanQueueItem& right) {
- return left.ChunkIdx < right.ChunkIdx;
- }
- };
+ TInitQueue InitQueue;
+
+ struct TScanQueueItem {
+ TChunkIdx ChunkIdx;
+ bool IndexOnly;
+ TChunkSerNum ChunkSerNum;
+
+ friend bool operator <(const TScanQueueItem& left, const TScanQueueItem& right) {
+ return left.ChunkIdx < right.ChunkIdx;
+ }
+ };
using TScanQueue = TQueue<TScanQueueItem>;
- TScanQueue ScanQueue;
- ui32 ScanBytesInFlight = 0;
+ TScanQueue ScanQueue;
+ ui32 ScanBytesInFlight = 0;
THashMap<TChunkIdx, TDynBitMap> IntentChunksDeletedItems;
-
- struct TScanResult {
- NKikimrProto::EReplyStatus Status;
- TChunkIdx ChunkIdx;
- bool IndexOnly;
- bool IndexValid;
+
+ struct TScanResult {
+ NKikimrProto::EReplyStatus Status;
+ TChunkIdx ChunkIdx;
+ bool IndexOnly;
+ bool IndexValid;
TVector<TBlobIndexRecord> Index;
- };
+ };
TQueue<TChunkSerNum> ChunkSerNumQueue;
THashMap<TChunkSerNum, TScanResult> PendingResults;
-
- struct TIncompleteChunk {
- TChunkIdx ChunkIdx;
- ui32 OffsetInBlocks;
+
+ struct TIncompleteChunk {
+ TChunkIdx ChunkIdx;
+ ui32 OffsetInBlocks;
TVector<TBlobIndexRecord> Index;
- };
+ };
TMap<TChunkSerNum, TIncompleteChunk> IncompleteChunks;
-
- struct TScanInfo {
- TInitQueue::iterator It;
- TChunkIdx ChunkIdx;
- TChunkInfo& Chunk;
- };
+
+ struct TScanInfo {
+ TInitQueue::iterator It;
+ TChunkIdx ChunkIdx;
+ TChunkInfo& Chunk;
+ };
THashMap<TActorId, TScanInfo> ScannerMap;
-
- public:
- TRecovery(TKeeper& keeper);
- ~TRecovery();
-
- // handle yard init message
- void ApplyYardInit(NKikimrProto::EReplyStatus status, NPDisk::TLogRecord *chunks, NPDisk::TLogRecord *deletes,
- const TActorContext& ctx);
-
- // handle read log result
+
+ public:
+ TRecovery(TKeeper& keeper);
+ ~TRecovery();
+
+ // handle yard init message
+ void ApplyYardInit(NKikimrProto::EReplyStatus status, NPDisk::TLogRecord *chunks, NPDisk::TLogRecord *deletes,
+ const TActorContext& ctx);
+
+ // handle read log result
void ApplyReadLog(const TActorId& sender, TEvIncrHugeReadLogResult& msg, const TActorContext& ctx);
-
- // handle scan result
+
+ // handle scan result
void ApplyScan(const TActorId& sender, TEvIncrHugeScanResult& msg, const TActorContext& ctx);
-
- // handle init message from client
- void HandleInit(TEvIncrHugeInit::TPtr& ev, const TActorContext& ctx);
-
- private:
- void EnqueueScan(TScanQueueItem&& item, const TActorContext& ctx);
- bool ProcessScanItem(TScanQueueItem& item, const TActorContext& ctx);
- void ProcessScanQueue(const TActorContext& ctx);
- void ProcessScanResult(TScanResult& scanResult, const TActorContext& ctx);
-
- void ProcessInitItem(TInitQueue::iterator it, const TActorContext& ctx);
- void SendInitResponse(TInitQueue::iterator it, NKikimrProto::EReplyStatus status, const TActorContext& ctx);
- void ProcessInitItemScanQueue(TInitQueue::iterator it, const TActorContext& ctx);
- void ApplyInitItemScan(TInitQueue::iterator it, TChunkIdx chunkIdx, TChunkInfo& chunk,
- TEvIncrHugeScanResult& msg, const TActorContext& ctx);
- };
-
- } // NIncrHuge
-} // NKikimr
+
+ // handle init message from client
+ void HandleInit(TEvIncrHugeInit::TPtr& ev, const TActorContext& ctx);
+
+ private:
+ void EnqueueScan(TScanQueueItem&& item, const TActorContext& ctx);
+ bool ProcessScanItem(TScanQueueItem& item, const TActorContext& ctx);
+ void ProcessScanQueue(const TActorContext& ctx);
+ void ProcessScanResult(TScanResult& scanResult, const TActorContext& ctx);
+
+ void ProcessInitItem(TInitQueue::iterator it, const TActorContext& ctx);
+ void SendInitResponse(TInitQueue::iterator it, NKikimrProto::EReplyStatus status, const TActorContext& ctx);
+ void ProcessInitItemScanQueue(TInitQueue::iterator it, const TActorContext& ctx);
+ void ApplyInitItemScan(TInitQueue::iterator it, TChunkIdx chunkIdx, TChunkInfo& chunk,
+ TEvIncrHugeScanResult& msg, const TActorContext& ctx);
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.cpp
index b5499213caf..bba5ed1057d 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.cpp
@@ -1,141 +1,141 @@
-#include "incrhuge_keeper_recovery_read_log.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge_keeper_log.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TReadLogActor : public TActor<TReadLogActor> {
+#include "incrhuge_keeper_recovery_read_log.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge_keeper_log.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TReadLogActor : public TActor<TReadLogActor> {
const TActorId PDiskActorId;
- const ui8 Owner;
- const NPDisk::TOwnerRound OwnerRound;
+ const ui8 Owner;
+ const NPDisk::TOwnerRound OwnerRound;
TActorId KeeperActorId;
- TMaybe<ui64> ChunksEntrypointLsn;
- TChunkRecordMerger ChunkMerger;
- TMaybe<ui64> DeletesEntrypointLsn;
- TDeleteRecordMerger DeleteMerger;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER_RECOVERY_READ_LOG;
+ TMaybe<ui64> ChunksEntrypointLsn;
+ TChunkRecordMerger ChunkMerger;
+ TMaybe<ui64> DeletesEntrypointLsn;
+ TDeleteRecordMerger DeleteMerger;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER_RECOVERY_READ_LOG;
}
TReadLogActor(const TActorId& pdiskActorId, ui8 owner, NPDisk::TOwnerRound ownerRound,
- TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn)
- : TActor<TReadLogActor>(&TReadLogActor::StateFunc)
- , PDiskActorId(pdiskActorId)
- , Owner(owner)
- , OwnerRound(ownerRound)
- , ChunksEntrypointLsn(chunksEntrypointLsn)
- , DeletesEntrypointLsn(deletesEntrypointLsn)
+ TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn)
+ : TActor<TReadLogActor>(&TReadLogActor::StateFunc)
+ , PDiskActorId(pdiskActorId)
+ , Owner(owner)
+ , OwnerRound(ownerRound)
+ , ChunksEntrypointLsn(chunksEntrypointLsn)
+ , DeletesEntrypointLsn(deletesEntrypointLsn)
{}
-
- private:
+
+ private:
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override {
- return new IEventHandle(self, parentId, new TEvents::TEvBootstrap);
- }
-
- void Handle(TEvents::TEvBootstrap::TPtr& ev, const TActorContext& ctx) {
- KeeperActorId = ev->Sender;
+ return new IEventHandle(self, parentId, new TEvents::TEvBootstrap);
+ }
+
+ void Handle(TEvents::TEvBootstrap::TPtr& ev, const TActorContext& ctx) {
+ KeeperActorId = ev->Sender;
ctx.Send(PDiskActorId, new NPDisk::TEvReadLog(Owner, OwnerRound));
- }
-
- void Handle(NPDisk::TEvReadLogResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvReadLogResult *msg = ev->Get();
- if (msg->Status != NKikimrProto::OK) {
- auto result = std::make_unique<TEvIncrHugeReadLogResult>();
- result->Status = msg->Status;
- ctx.Send(KeeperActorId, result.release());
- return Die(ctx);
- }
-
- // send next log read request if this is not the end
- if (!msg->IsEndOfLog) {
- ctx.Send(PDiskActorId, new NPDisk::TEvReadLog(Owner, OwnerRound, msg->NextPosition));
- }
-
- // parse log items
- TMaybe<ui64> maxLsn;
- for (const auto& item : msg->Results) {
- Y_VERIFY(!maxLsn || item.Lsn > *maxLsn);
- maxLsn = item.Lsn;
-
- switch (item.Signature) {
+ }
+
+ void Handle(NPDisk::TEvReadLogResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvReadLogResult *msg = ev->Get();
+ if (msg->Status != NKikimrProto::OK) {
+ auto result = std::make_unique<TEvIncrHugeReadLogResult>();
+ result->Status = msg->Status;
+ ctx.Send(KeeperActorId, result.release());
+ return Die(ctx);
+ }
+
+ // send next log read request if this is not the end
+ if (!msg->IsEndOfLog) {
+ ctx.Send(PDiskActorId, new NPDisk::TEvReadLog(Owner, OwnerRound, msg->NextPosition));
+ }
+
+ // parse log items
+ TMaybe<ui64> maxLsn;
+ for (const auto& item : msg->Results) {
+ Y_VERIFY(!maxLsn || item.Lsn > *maxLsn);
+ maxLsn = item.Lsn;
+
+ switch (item.Signature) {
case TLogSignature::SignatureIncrHugeChunks:
- if (!ChunksEntrypointLsn || item.Lsn >= *ChunksEntrypointLsn) {
- NKikimrVDiskData::TIncrHugeChunks record;
- bool status = record.ParseFromString(item.Data);
- Y_VERIFY(status);
- ChunkMerger(record);
- }
- break;
-
+ if (!ChunksEntrypointLsn || item.Lsn >= *ChunksEntrypointLsn) {
+ NKikimrVDiskData::TIncrHugeChunks record;
+ bool status = record.ParseFromString(item.Data);
+ Y_VERIFY(status);
+ ChunkMerger(record);
+ }
+ break;
+
case TLogSignature::SignatureIncrHugeDeletes:
- if (!DeletesEntrypointLsn || item.Lsn >= *DeletesEntrypointLsn) {
- NKikimrVDiskData::TIncrHugeDelete record;
- bool status = record.ParseFromString(item.Data);
- Y_VERIFY(status);
-
- TStringStream s;
- s << "Chunks# [";
- for (size_t i = 0; i < record.ChunksSize(); ++i) {
- const auto& chunk = record.GetChunks(i);
- s << (i ? " " : "");
- s << "Id# " << chunk.GetChunkSerNum() << " Items# [";
- TDynBitMap deletedItems;
- DeserializeDeletes(deletedItems, chunk);
- bool first = true;
- Y_FOR_EACH_BIT(j, deletedItems) {
- s << (first ? first = false, "" : " ") << j;
- }
- s << "]";
- }
- s << "] Owners# [";
- for (size_t i = 0; i < record.OwnersSize(); ++i) {
- const auto& o = record.GetOwners(i);
- s << (i ? " " : "") << o.GetOwner() << ": " << o.GetSeqNo();
- }
- s << "]";
- LOG_DEBUG(ctx, NKikimrServices::BS_INCRHUGE, "IncrHugeDelete# Lsn# %" PRIu64 " %s",
+ if (!DeletesEntrypointLsn || item.Lsn >= *DeletesEntrypointLsn) {
+ NKikimrVDiskData::TIncrHugeDelete record;
+ bool status = record.ParseFromString(item.Data);
+ Y_VERIFY(status);
+
+ TStringStream s;
+ s << "Chunks# [";
+ for (size_t i = 0; i < record.ChunksSize(); ++i) {
+ const auto& chunk = record.GetChunks(i);
+ s << (i ? " " : "");
+ s << "Id# " << chunk.GetChunkSerNum() << " Items# [";
+ TDynBitMap deletedItems;
+ DeserializeDeletes(deletedItems, chunk);
+ bool first = true;
+ Y_FOR_EACH_BIT(j, deletedItems) {
+ s << (first ? first = false, "" : " ") << j;
+ }
+ s << "]";
+ }
+ s << "] Owners# [";
+ for (size_t i = 0; i < record.OwnersSize(); ++i) {
+ const auto& o = record.GetOwners(i);
+ s << (i ? " " : "") << o.GetOwner() << ": " << o.GetSeqNo();
+ }
+ s << "]";
+ LOG_DEBUG(ctx, NKikimrServices::BS_INCRHUGE, "IncrHugeDelete# Lsn# %" PRIu64 " %s",
item.Lsn, s.Str().data());
-
- DeleteMerger(record);
- }
- break;
-
- default:
+
+ DeleteMerger(record);
+ }
+ break;
+
+ default:
Y_FAIL_S("unexpected log record " << item.Signature.ToString());
- }
- }
-
- // if this is the end, reply to parent and die
- if (msg->IsEndOfLog) {
- auto result = std::make_unique<TEvIncrHugeReadLogResult>();
- result->Status = NKikimrProto::OK;
- result->Chunks = ChunkMerger.GetCurrentState();
- result->Deletes = DeleteMerger.GetCurrentState();
- result->NextLsn = maxLsn.GetOrElse(0) + 1;
- result->IssueInitialStartingPoints = !maxLsn;
- ctx.Send(KeeperActorId, result.release());
- Die(ctx);
- }
- }
-
- void HandlePoison(const TActorContext& ctx) {
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvBootstrap, Handle)
- HFunc(NPDisk::TEvReadLogResult, Handle)
- CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
- )
- };
-
+ }
+ }
+
+ // if this is the end, reply to parent and die
+ if (msg->IsEndOfLog) {
+ auto result = std::make_unique<TEvIncrHugeReadLogResult>();
+ result->Status = NKikimrProto::OK;
+ result->Chunks = ChunkMerger.GetCurrentState();
+ result->Deletes = DeleteMerger.GetCurrentState();
+ result->NextLsn = maxLsn.GetOrElse(0) + 1;
+ result->IssueInitialStartingPoints = !maxLsn;
+ ctx.Send(KeeperActorId, result.release());
+ Die(ctx);
+ }
+ }
+
+ void HandlePoison(const TActorContext& ctx) {
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvBootstrap, Handle)
+ HFunc(NPDisk::TEvReadLogResult, Handle)
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
+ )
+ };
+
IActor *CreateRecoveryReadLogActor(const TActorId& pdiskActorId, ui8 owner, NPDisk::TOwnerRound ownerRound,
- TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn) {
- return new TReadLogActor(pdiskActorId, owner, ownerRound, chunksEntrypointLsn, deletesEntrypointLsn);
- }
-
- } // NIncrHuge
-} // NKikimr
+ TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn) {
+ return new TReadLogActor(pdiskActorId, owner, ownerRound, chunksEntrypointLsn, deletesEntrypointLsn);
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.h
index 551e8ad6412..b401cff40d0 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_read_log.h
@@ -1,18 +1,18 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/actors/core/actor.h>
-
+
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
-
-#include <util/generic/maybe.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
+
+#include <util/generic/maybe.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
NActors::IActor *CreateRecoveryReadLogActor(const NActors::TActorId& pdiskActorId, ui8 owner,
- NPDisk::TOwnerRound ownerRound, TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn);
-
- } // NIncrHuge
-} // NKikimr
+ NPDisk::TOwnerRound ownerRound, TMaybe<ui64> chunksEntrypointLsn, TMaybe<ui64> deletesEntrypointLsn);
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.cpp
index eb60105861b..ff5a8f24c44 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.cpp
@@ -1,174 +1,174 @@
-#include "incrhuge_keeper_recovery_scan.h"
+#include "incrhuge_keeper_recovery_scan.h"
#include <library/cpp/digest/crc32c/crc32c.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- class TScanActor : public TActor<TScanActor> {
- const TChunkIdx ChunkIdx;
- const bool IndexOnly;
- const TChunkSerNum ChunkSerNum;
- const ui64 Cookie;
- const TKeeperCommonState& State;
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ class TScanActor : public TActor<TScanActor> {
+ const TChunkIdx ChunkIdx;
+ const bool IndexOnly;
+ const TChunkSerNum ChunkSerNum;
+ const ui64 Cookie;
+ const TKeeperCommonState& State;
TActorId KeeperActorId;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER_RECOVERY_SCAN;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_INCR_HUGE_KEEPER_RECOVERY_SCAN;
}
- TScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
- const TKeeperCommonState& state)
- : TActor<TScanActor>(&TScanActor::StateFunc)
- , ChunkIdx(chunkIdx)
- , IndexOnly(indexOnly)
- , ChunkSerNum(chunkSerNum)
- , Cookie(cookie)
- , State(state)
+ TScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
+ const TKeeperCommonState& state)
+ : TActor<TScanActor>(&TScanActor::StateFunc)
+ , ChunkIdx(chunkIdx)
+ , IndexOnly(indexOnly)
+ , ChunkSerNum(chunkSerNum)
+ , Cookie(cookie)
+ , State(state)
{}
-
- private:
+
+ private:
TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override {
- return new IEventHandle(self, parentId, new TEvents::TEvBootstrap);
- }
-
- void Handle(TEvents::TEvBootstrap::TPtr& ev, const TActorContext& ctx) {
- KeeperActorId = ev->Sender;
-
- // in index-only mode read just index; otherwise read the full block
- ui32 offset = IndexOnly ? State.BlocksInDataSection * State.BlockSize : 0;
- ui32 size = IndexOnly ? State.BlocksInIndexSection * State.BlockSize : State.PDiskParams->ChunkSize;
- ctx.Send(State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(State.PDiskParams->Owner,
- State.PDiskParams->OwnerRound, ChunkIdx, offset, size, NPriRead::HullLoad, nullptr));
- }
-
+ return new IEventHandle(self, parentId, new TEvents::TEvBootstrap);
+ }
+
+ void Handle(TEvents::TEvBootstrap::TPtr& ev, const TActorContext& ctx) {
+ KeeperActorId = ev->Sender;
+
+ // in index-only mode read just index; otherwise read the full block
+ ui32 offset = IndexOnly ? State.BlocksInDataSection * State.BlockSize : 0;
+ ui32 size = IndexOnly ? State.BlocksInIndexSection * State.BlockSize : State.PDiskParams->ChunkSize;
+ ctx.Send(State.Settings.PDiskActorId, new NPDisk::TEvChunkRead(State.PDiskParams->Owner,
+ State.PDiskParams->OwnerRound, ChunkIdx, offset, size, NPriRead::HullLoad, nullptr));
+ }
+
void SendReplyAndDie(NKikimrProto::EReplyStatus status, TVector<TBlobIndexRecord>&& index, bool indexValid,
- const TActorContext& ctx) {
- auto result = std::make_unique<TEvIncrHugeScanResult>();
- result->Status = status;
- result->Index = std::move(index);
- result->ChunkIdx = ChunkIdx;
- result->IndexOnly = IndexOnly;
- result->ChunkSerNum = ChunkSerNum;
- result->IndexValid = indexValid;
- ctx.Send(KeeperActorId, result.release(), 0, Cookie);
- Die(ctx);
- }
-
- void Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx) {
- NPDisk::TEvChunkReadResult *msg = ev->Get();
- if (msg->Status != NKikimrProto::OK) {
- return SendReplyAndDie(msg->Status, {}, {}, ctx);
- }
- bool success = false;
- if (IndexOnly) {
- success = ParseIndex(*msg, ctx);
- } else {
- success = ParseWholeChunk(*msg, ctx);
- }
- if (!success) {
- return SendReplyAndDie(NKikimrProto::ERROR, {}, {}, ctx);
- }
- }
-
- bool ParseIndex(NPDisk::TEvChunkReadResult& msg, const TActorContext& ctx) {
- // try to get index
+ const TActorContext& ctx) {
+ auto result = std::make_unique<TEvIncrHugeScanResult>();
+ result->Status = status;
+ result->Index = std::move(index);
+ result->ChunkIdx = ChunkIdx;
+ result->IndexOnly = IndexOnly;
+ result->ChunkSerNum = ChunkSerNum;
+ result->IndexValid = indexValid;
+ ctx.Send(KeeperActorId, result.release(), 0, Cookie);
+ Die(ctx);
+ }
+
+ void Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx) {
+ NPDisk::TEvChunkReadResult *msg = ev->Get();
+ if (msg->Status != NKikimrProto::OK) {
+ return SendReplyAndDie(msg->Status, {}, {}, ctx);
+ }
+ bool success = false;
+ if (IndexOnly) {
+ success = ParseIndex(*msg, ctx);
+ } else {
+ success = ParseWholeChunk(*msg, ctx);
+ }
+ if (!success) {
+ return SendReplyAndDie(NKikimrProto::ERROR, {}, {}, ctx);
+ }
+ }
+
+ bool ParseIndex(NPDisk::TEvChunkReadResult& msg, const TActorContext& ctx) {
+ // try to get index
TVector<TBlobIndexRecord> index;
- if (!GetIndex(msg.Data, 0, index)) {
- return false;
- }
-
- // send reply & die
- SendReplyAndDie(NKikimrProto::OK, std::move(index), true, ctx);
- return true;
- }
-
+ if (!GetIndex(msg.Data, 0, index)) {
+ return false;
+ }
+
+ // send reply & die
+ SendReplyAndDie(NKikimrProto::OK, std::move(index), true, ctx);
+ return true;
+ }
+
bool GetIndex(TBufferWithGaps& data, ui32 offset, TVector<TBlobIndexRecord>& index) {
- // check that we can read header
- if (!data.IsReadable(offset, sizeof(TBlobIndexHeader))) {
- return false;
- }
-
- // get a reference to header and ensure we can read all declared records
- const TBlobIndexHeader& header = *data.DataPtr<const TBlobIndexHeader>(offset);
- const ui32 dataSize = header.NumItems * sizeof(TBlobIndexRecord);
- if (header.NumItems > State.MaxBlobsPerChunk || !data.IsReadable(offset + sizeof(TBlobIndexHeader), dataSize)) {
- return false;
- }
-
- // validate id; id mismatch means that consistency of this chunk is broken
- if (header.ChunkSerNum != ChunkSerNum) {
- return false;
- }
-
- // validate checksum
+ // check that we can read header
+ if (!data.IsReadable(offset, sizeof(TBlobIndexHeader))) {
+ return false;
+ }
+
+ // get a reference to header and ensure we can read all declared records
+ const TBlobIndexHeader& header = *data.DataPtr<const TBlobIndexHeader>(offset);
+ const ui32 dataSize = header.NumItems * sizeof(TBlobIndexRecord);
+ if (header.NumItems > State.MaxBlobsPerChunk || !data.IsReadable(offset + sizeof(TBlobIndexHeader), dataSize)) {
+ return false;
+ }
+
+ // validate id; id mismatch means that consistency of this chunk is broken
+ if (header.ChunkSerNum != ChunkSerNum) {
+ return false;
+ }
+
+ // validate checksum
const ui32 checksum = Crc32c(&header.ChunkSerNum, sizeof(TBlobIndexHeader) - sizeof(ui32) + dataSize);
- if (checksum != header.Checksum) {
- return false;
- }
-
- index.assign(header.InplaceIndexBegin(), header.InplaceIndexEnd());
- return true;
- }
-
- bool ParseWholeChunk(NPDisk::TEvChunkReadResult& msg, const TActorContext& ctx) {
+ if (checksum != header.Checksum) {
+ return false;
+ }
+
+ index.assign(header.InplaceIndexBegin(), header.InplaceIndexEnd());
+ return true;
+ }
+
+ bool ParseWholeChunk(NPDisk::TEvChunkReadResult& msg, const TActorContext& ctx) {
TVector<TBlobIndexRecord> index;
-
- for (ui32 block = 0; block < State.BlocksInDataSection; ) {
- ui32 offset = block * State.BlockSize;
-
- if (!msg.Data.IsReadable(offset, sizeof(TBlobHeader))) {
- break;
- }
-
- const TBlobHeader& header = *msg.Data.DataPtr<const TBlobHeader>(offset);
-
- const ui32 sizeInBlocks = (sizeof(TBlobHeader) + header.IndexRecord.PayloadSize + State.BlockSize -
- 1) / State.BlockSize;
- if (!msg.Data.IsReadable(offset, sizeInBlocks * State.BlockSize)) {
- break;
- }
-
+
+ for (ui32 block = 0; block < State.BlocksInDataSection; ) {
+ ui32 offset = block * State.BlockSize;
+
+ if (!msg.Data.IsReadable(offset, sizeof(TBlobHeader))) {
+ break;
+ }
+
+ const TBlobHeader& header = *msg.Data.DataPtr<const TBlobHeader>(offset);
+
+ const ui32 sizeInBlocks = (sizeof(TBlobHeader) + header.IndexRecord.PayloadSize + State.BlockSize -
+ 1) / State.BlockSize;
+ if (!msg.Data.IsReadable(offset, sizeInBlocks * State.BlockSize)) {
+ break;
+ }
+
const ui32 checksum = Crc32c(&header.IndexRecord, sizeof(TBlobHeader) - sizeof(ui32) +
- header.IndexRecord.PayloadSize);
- if (checksum != header.Checksum) {
- break;
- }
-
- // on id mismatch we stop, because the only reason is appearance of old data inside new chunk
- if (header.ChunkSerNum != ChunkSerNum) {
- break;
- }
-
- index.push_back(header.IndexRecord);
-
- block += sizeInBlocks;
- }
-
- // try to get stored index and check if it the same as computed one
+ header.IndexRecord.PayloadSize);
+ if (checksum != header.Checksum) {
+ break;
+ }
+
+ // on id mismatch we stop, because the only reason is appearance of old data inside new chunk
+ if (header.ChunkSerNum != ChunkSerNum) {
+ break;
+ }
+
+ index.push_back(header.IndexRecord);
+
+ block += sizeInBlocks;
+ }
+
+ // try to get stored index and check if it the same as computed one
TVector<TBlobIndexRecord> storedIndex;
- const bool indexValid = GetIndex(msg.Data, State.BlocksInDataSection * State.BlockSize, storedIndex) &&
- index == storedIndex;
-
- SendReplyAndDie(index ? NKikimrProto::OK : NKikimrProto::NODATA, std::move(index), indexValid, ctx);
- return true;
- }
-
- void HandlePoison(const TActorContext& ctx) {
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvBootstrap, Handle)
- HFunc(NPDisk::TEvChunkReadResult, Handle)
- CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
- )
- };
-
- IActor *CreateRecoveryScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
- const TKeeperCommonState& state) {
- return new TScanActor(chunkIdx, indexOnly, chunkSerNum, cookie, state);
- }
-
- } // NIncrHuge
-} // NKikimr
+ const bool indexValid = GetIndex(msg.Data, State.BlocksInDataSection * State.BlockSize, storedIndex) &&
+ index == storedIndex;
+
+ SendReplyAndDie(index ? NKikimrProto::OK : NKikimrProto::NODATA, std::move(index), indexValid, ctx);
+ return true;
+ }
+
+ void HandlePoison(const TActorContext& ctx) {
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvBootstrap, Handle)
+ HFunc(NPDisk::TEvChunkReadResult, Handle)
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
+ )
+ };
+
+ IActor *CreateRecoveryScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
+ const TKeeperCommonState& state) {
+ return new TScanActor(chunkIdx, indexOnly, chunkSerNum, cookie, state);
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.h
index 3f262ade9bf..506be9083bf 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_recovery_scan.h
@@ -1,18 +1,18 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- enum class EScanCookie : ui64 {
- Recovery = 1,
- Defrag = 2
- };
-
- IActor *CreateRecoveryScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
- const TKeeperCommonState& state);
-
- } // NIncrHuge
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ enum class EScanCookie : ui64 {
+ Recovery = 1,
+ Defrag = 2
+ };
+
+ IActor *CreateRecoveryScanActor(TChunkIdx chunkIdx, bool indexOnly, TChunkSerNum chunkSerNum, ui64 cookie,
+ const TKeeperCommonState& state);
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.cpp b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.cpp
index ca6cedf5d8f..58fb435fd80 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.cpp
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.cpp
@@ -1,621 +1,621 @@
-#include "incrhuge_keeper_write.h"
-#include "incrhuge_keeper.h"
+#include "incrhuge_keeper_write.h"
+#include "incrhuge_keeper.h"
#include <library/cpp/digest/crc32c/crc32c.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- TWriter::TWriter(TKeeper& keeper)
- : TKeeperComponentBase(keeper, "Writer")
- {}
-
- TWriter::~TWriter()
- {}
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // WRITE QUEUE LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TWriter::TWriteQueueItem {
- ////////////////////////
- // Request parameters //
- ////////////////////////
-
- // query unique id
- ui64 QueryId;
-
- // owner who sent this request
- ui8 Owner;
-
- // LSN in owner's space; just a number we don't examine here
- ui64 Lsn;
-
- // blob metadata with we also wouldn't examine
- TBlobMetadata Meta;
-
- // data to write
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ TWriter::TWriter(TKeeper& keeper)
+ : TKeeperComponentBase(keeper, "Writer")
+ {}
+
+ TWriter::~TWriter()
+ {}
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WRITE QUEUE LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TWriter::TWriteQueueItem {
+ ////////////////////////
+ // Request parameters //
+ ////////////////////////
+
+ // query unique id
+ ui64 QueryId;
+
+ // owner who sent this request
+ ui8 Owner;
+
+ // LSN in owner's space; just a number we don't examine here
+ ui64 Lsn;
+
+ // blob metadata with we also wouldn't examine
+ TBlobMetadata Meta;
+
+ // data to write
TString Data;
-
- // event payload which will be moved to response
- TWritePayloadPtr Payload;
-
- // the actor who sent this request
+
+ // event payload which will be moved to response
+ TWritePayloadPtr Payload;
+
+ // the actor who sent this request
TActorId Sender;
-
- // cookie of request; the same for response
- ui64 Cookie;
-
- // callback which will be invoked upon completion
- std::unique_ptr<IEventCallback> Callback;
-
- ////////////////////
- // Executor state //
- ////////////////////
-
- // are header and id fields valid?
- bool Defrag;
-
- // blob header -- we store it here until it is written becase there is a pointer to it in parts and we own
- // this data
- TBlobHeader Header;
-
- // list of parts we write into chunk; up to three parts -- mandatory both header and data, and optional
- // padding (if total size of data and header isn't multiple of block size)
- std::array<NPDisk::TEvChunkWrite::TPart, 3> Parts;
-
- // blob id
- TIncrHugeBlobId Id;
-
- // the chunk we store this blob into
- TChunkIdx ChunkIdx;
-
- // item's size in blocks
- ui32 SizeInBlocks;
-
- // item index inside chunk
- ui32 IndexInsideChunk;
-
- // item offset inside chunk
- ui32 OffsetInBlocks;
-
- // original item chunk index
- TChunkIdx OriginalChunkIdx;
-
- // original item chunk serial number
- TChunkSerNum OriginalChunkSerNum;
-
- // original item's index within its chunk
- ui32 OriginalIndexInsideChunk;
- };
-
- // write request handler; it does nothing but formatting new item into TWriteQueueItem and kicking queue processor
- void TWriter::HandleWrite(TEvIncrHugeWrite::TPtr& ev, const TActorContext& ctx) {
- // extract pointer to event
- TEvIncrHugeWrite *msg = ev->Get();
-
- // create an item to process
- TWriteQueueItem item{
- NextQueryId++, // QueryId
- msg->Owner, // Owner
- msg->Lsn, // Lsn
- msg->Meta, // Meta
- std::move(msg->Data), // Data
- std::move(msg->Payload), // Payload
- ev->Sender, // Sender
- ev->Cookie, // Cookie
- {}, // Callback (will be filled in later)
- false, // Defrag
- {}, // Header
- {}, // Parts
- {}, // Id
- {}, // ChunkIdx
- {}, // SizeInBlocks
- {}, // IndexInsideChunk
- {}, // OffsetInBlocks
- {}, // OriginalChunkIdx
- {}, // OriginalChunkSerNum
- {}}; // OriginalIndexInsideChunk
-
- // put item into queue
- auto it = WriteQueue.insert(WriteQueue.end(), std::move(item));
-
- // fill in callback
+
+ // cookie of request; the same for response
+ ui64 Cookie;
+
+ // callback which will be invoked upon completion
+ std::unique_ptr<IEventCallback> Callback;
+
+ ////////////////////
+ // Executor state //
+ ////////////////////
+
+ // are header and id fields valid?
+ bool Defrag;
+
+ // blob header -- we store it here until it is written becase there is a pointer to it in parts and we own
+ // this data
+ TBlobHeader Header;
+
+ // list of parts we write into chunk; up to three parts -- mandatory both header and data, and optional
+ // padding (if total size of data and header isn't multiple of block size)
+ std::array<NPDisk::TEvChunkWrite::TPart, 3> Parts;
+
+ // blob id
+ TIncrHugeBlobId Id;
+
+ // the chunk we store this blob into
+ TChunkIdx ChunkIdx;
+
+ // item's size in blocks
+ ui32 SizeInBlocks;
+
+ // item index inside chunk
+ ui32 IndexInsideChunk;
+
+ // item offset inside chunk
+ ui32 OffsetInBlocks;
+
+ // original item chunk index
+ TChunkIdx OriginalChunkIdx;
+
+ // original item chunk serial number
+ TChunkSerNum OriginalChunkSerNum;
+
+ // original item's index within its chunk
+ ui32 OriginalIndexInsideChunk;
+ };
+
+ // write request handler; it does nothing but formatting new item into TWriteQueueItem and kicking queue processor
+ void TWriter::HandleWrite(TEvIncrHugeWrite::TPtr& ev, const TActorContext& ctx) {
+ // extract pointer to event
+ TEvIncrHugeWrite *msg = ev->Get();
+
+ // create an item to process
+ TWriteQueueItem item{
+ NextQueryId++, // QueryId
+ msg->Owner, // Owner
+ msg->Lsn, // Lsn
+ msg->Meta, // Meta
+ std::move(msg->Data), // Data
+ std::move(msg->Payload), // Payload
+ ev->Sender, // Sender
+ ev->Cookie, // Cookie
+ {}, // Callback (will be filled in later)
+ false, // Defrag
+ {}, // Header
+ {}, // Parts
+ {}, // Id
+ {}, // ChunkIdx
+ {}, // SizeInBlocks
+ {}, // IndexInsideChunk
+ {}, // OffsetInBlocks
+ {}, // OriginalChunkIdx
+ {}, // OriginalChunkSerNum
+ {}}; // OriginalIndexInsideChunk
+
+ // put item into queue
+ auto it = WriteQueue.insert(WriteQueue.end(), std::move(item));
+
+ // fill in callback
auto callback = [it](NKikimrProto::EReplyStatus status, IEventBase* /*msg*/, const TActorContext& ctx) {
- ctx.Send(it->Sender, new TEvIncrHugeWriteResult(status, it->Id, std::move(it->Payload)), 0, it->Cookie);
- };
- it->Callback = MakeCallback(std::move(callback));
-
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " HandleWrite Lsn# %" PRIu64 " DataSize# %" PRIu32
+ ctx.Send(it->Sender, new TEvIncrHugeWriteResult(status, it->Id, std::move(it->Payload)), 0, it->Cookie);
+ };
+ it->Callback = MakeCallback(std::move(callback));
+
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " HandleWrite Lsn# %" PRIu64 " DataSize# %" PRIu32
" WriteQueueSize# %zu WriteInProgressItemsSize# %zu", it->QueryId, it->Lsn, ui32(it->Data.size()),
- WriteQueue.size(), WriteInProgressItems.size());
-
- // kick processor
- ProcessWriteQueue(ctx);
- }
-
- // defragmentation write handler; puts an item into write queue and kick executor
- void TWriter::EnqueueDefragWrite(const TBlobHeader& header, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
- ui32 indexInsideChunk, TString&& data, std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
- // create a queue item
- TWriteQueueItem item{
- NextQueryId++, // QueryId
- {}, // Owner
- {}, // Lsn
- {}, // Meta
- std::move(data), // Data
- {}, // Payload
- {}, // Sender
- {}, // Cookie
- std::move(callback), // Callback
- true, // Defrag
- header, // Header
- {}, // Parts
- header.IndexRecord.Id, // Id
- {}, // ChunkIdx
- {}, // SizeInBlocks
- {}, // IndexInsideChunk
- {}, // OffsetInBlocks
- chunkIdx, // OriginalChunkIdx
- chunkSerNum, // OriginalChunkSerNum
- indexInsideChunk}; // OriginalIndexInsideChunk
-
- // put it in queue
- WriteQueue.push_back(std::move(item));
-
- // kick processor
- ProcessWriteQueue(ctx);
- }
-
- // queue processor; this function tries to process as much items in WriteQueue in FIFO order as possible; it stops
- // when either queue ends, or there is not enough space to fit current blob in current chunk and there is no
- // other chunk in write intent queue, or in flight counter exceeded its maximum value
- void TWriter::ProcessWriteQueue(const TActorContext& ctx) {
- IHLOG_DEBUG(ctx, "WriteQueueSize# %zu WriteInProgressItemsSize# %zu",
- WriteQueue.size(), WriteInProgressItems.size());
- for (auto it = WriteQueue.begin(); it != WriteQueue.end() &&
- WriteInProgressItems.size() < Keeper.State.Settings.MaxInFlightWrites; ) {
- // iterator is postincremented because it may be invalidated inside this function
- if (!ProcessWriteItem(it++, ctx)) {
- break;
- }
- }
- }
-
- // queue item processor; it is called for WriteQueue items and, if possible, starts to write blob into chunk;
- // if there is not enough space in current blob, then current chunk is 'finalized' -- that is, the index is
- // formatted and written to chunk and next chunk is started; next chunk is always taken from the write intent
- // queue; writing consists of preparing data (like filling header fields and so on) and sending request to yard
- // to write to the chunk; if the request is sent, then item is moved from WriteQueue to WriteInProgressItems
- bool TWriter::ProcessWriteItem(TWriteQueue::iterator it, const TActorContext& ctx) {
- TWriteQueueItem& item = *it;
-
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem entry", item.QueryId);
-
- // for items coming from defragmenter we should first check if this item was deleted while it was in write
- // queue; for such items we return special condition
- if (item.Defrag && IsObsolete(item, ctx)) {
- item.Callback->Apply(NKikimrProto::RACE, nullptr, ctx);
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem defrag, obsolete", item.QueryId);
- WriteQueue.erase(it);
- return true;
- }
-
- // if this is item from user and there is not enough disk space to process query, abort this request
- if (!item.Defrag && Keeper.State.DiskState <= EDiskState::SpaceOrange) {
- item.Callback->Apply(NKikimrProto::OUT_OF_SPACE, nullptr, ctx);
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem disk space", item.QueryId);
- WriteQueue.erase(it);
- return true;
- }
-
- // calculate payload size in bytes and ensure it fits into required boundaries
+ WriteQueue.size(), WriteInProgressItems.size());
+
+ // kick processor
+ ProcessWriteQueue(ctx);
+ }
+
+ // defragmentation write handler; puts an item into write queue and kick executor
+ void TWriter::EnqueueDefragWrite(const TBlobHeader& header, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
+ ui32 indexInsideChunk, TString&& data, std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx) {
+ // create a queue item
+ TWriteQueueItem item{
+ NextQueryId++, // QueryId
+ {}, // Owner
+ {}, // Lsn
+ {}, // Meta
+ std::move(data), // Data
+ {}, // Payload
+ {}, // Sender
+ {}, // Cookie
+ std::move(callback), // Callback
+ true, // Defrag
+ header, // Header
+ {}, // Parts
+ header.IndexRecord.Id, // Id
+ {}, // ChunkIdx
+ {}, // SizeInBlocks
+ {}, // IndexInsideChunk
+ {}, // OffsetInBlocks
+ chunkIdx, // OriginalChunkIdx
+ chunkSerNum, // OriginalChunkSerNum
+ indexInsideChunk}; // OriginalIndexInsideChunk
+
+ // put it in queue
+ WriteQueue.push_back(std::move(item));
+
+ // kick processor
+ ProcessWriteQueue(ctx);
+ }
+
+ // queue processor; this function tries to process as much items in WriteQueue in FIFO order as possible; it stops
+ // when either queue ends, or there is not enough space to fit current blob in current chunk and there is no
+ // other chunk in write intent queue, or in flight counter exceeded its maximum value
+ void TWriter::ProcessWriteQueue(const TActorContext& ctx) {
+ IHLOG_DEBUG(ctx, "WriteQueueSize# %zu WriteInProgressItemsSize# %zu",
+ WriteQueue.size(), WriteInProgressItems.size());
+ for (auto it = WriteQueue.begin(); it != WriteQueue.end() &&
+ WriteInProgressItems.size() < Keeper.State.Settings.MaxInFlightWrites; ) {
+ // iterator is postincremented because it may be invalidated inside this function
+ if (!ProcessWriteItem(it++, ctx)) {
+ break;
+ }
+ }
+ }
+
+ // queue item processor; it is called for WriteQueue items and, if possible, starts to write blob into chunk;
+ // if there is not enough space in current blob, then current chunk is 'finalized' -- that is, the index is
+ // formatted and written to chunk and next chunk is started; next chunk is always taken from the write intent
+ // queue; writing consists of preparing data (like filling header fields and so on) and sending request to yard
+ // to write to the chunk; if the request is sent, then item is moved from WriteQueue to WriteInProgressItems
+ bool TWriter::ProcessWriteItem(TWriteQueue::iterator it, const TActorContext& ctx) {
+ TWriteQueueItem& item = *it;
+
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem entry", item.QueryId);
+
+ // for items coming from defragmenter we should first check if this item was deleted while it was in write
+ // queue; for such items we return special condition
+ if (item.Defrag && IsObsolete(item, ctx)) {
+ item.Callback->Apply(NKikimrProto::RACE, nullptr, ctx);
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem defrag, obsolete", item.QueryId);
+ WriteQueue.erase(it);
+ return true;
+ }
+
+ // if this is item from user and there is not enough disk space to process query, abort this request
+ if (!item.Defrag && Keeper.State.DiskState <= EDiskState::SpaceOrange) {
+ item.Callback->Apply(NKikimrProto::OUT_OF_SPACE, nullptr, ctx);
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem disk space", item.QueryId);
+ WriteQueue.erase(it);
+ return true;
+ }
+
+ // calculate payload size in bytes and ensure it fits into required boundaries
const ui32 payloadSize = item.Data.size();
- Y_VERIFY(payloadSize >= Keeper.State.Settings.MinHugeBlobInBytes && payloadSize < 0x1000000);
-
- // calculate full data record size in blocks; round total size of header and payload up to a block size
- const ui32 sizeInBlocks = (sizeof(TBlobHeader) + payloadSize + Keeper.State.BlockSize - 1) / Keeper.State.BlockSize;
-
- // if we have current chunk and there is no space to fit this item, we have to finish this chunk; inside
- // callee function current chunk state will be reset to 'no current chunk'
- if (Keeper.State.CurrentChunk && CurrentChunkOffsetInBlocks + sizeInBlocks > Keeper.State.BlocksInDataSection) {
- FinishCurrentChunk(ctx);
- Y_VERIFY_DEBUG(!Keeper.State.CurrentChunk);
- }
-
- // if we have no current chunk, then try to allocate one; this usually happens if we just have finished
- // our last chunk, but also may happen on start
- if (!Keeper.State.CurrentChunk && !TryToBeginNewChunk(ctx)) {
- // can't handle this now, no chunks to write into, because write intent queue is empty; this function
- // should be called once again when allocation occurs
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem no free chunks", item.QueryId);
- return false;
- }
-
- // ensure we have a chunk to write into
- Y_VERIFY(Keeper.State.CurrentChunk);
- TChunkInfo& chunk = Keeper.State.Chunks.at(Keeper.State.CurrentChunk);
- Y_VERIFY(chunk.State == EChunkState::Current);
-
- // store chunk we are writing to into queue item
- item.ChunkIdx = Keeper.State.CurrentChunk;
-
- // if this request came from user, we have to generate blob's id and fill in its header; for writes from
- // defragmenter these fields are already set
- TBlobHeader& header = item.Header;
- if (!item.Defrag) {
- // generate id, register it in blob lookup table
- item.Id = Keeper.State.BlobLookup.Create(TBlobLocator{Keeper.State.CurrentChunk,
- CurrentChunkOffsetInBlocks, payloadSize, chunk.NumItems, item.Owner, false});
-
- memset(&header, 0, sizeof(header));
-
- // fill in index record which is a part of blob header
- TBlobIndexRecord& indexRecord = header.IndexRecord;
- indexRecord.Id = item.Id;
- indexRecord.Lsn = item.Lsn;
- indexRecord.Meta = item.Meta;
- indexRecord.PayloadSize = payloadSize;
- indexRecord.Owner = item.Owner;
- }
-
- // fill in header; calculate checksum for header (excluding CRC) + data
- header.ChunkSerNum = chunk.ChunkSerNum;
+ Y_VERIFY(payloadSize >= Keeper.State.Settings.MinHugeBlobInBytes && payloadSize < 0x1000000);
+
+ // calculate full data record size in blocks; round total size of header and payload up to a block size
+ const ui32 sizeInBlocks = (sizeof(TBlobHeader) + payloadSize + Keeper.State.BlockSize - 1) / Keeper.State.BlockSize;
+
+ // if we have current chunk and there is no space to fit this item, we have to finish this chunk; inside
+ // callee function current chunk state will be reset to 'no current chunk'
+ if (Keeper.State.CurrentChunk && CurrentChunkOffsetInBlocks + sizeInBlocks > Keeper.State.BlocksInDataSection) {
+ FinishCurrentChunk(ctx);
+ Y_VERIFY_DEBUG(!Keeper.State.CurrentChunk);
+ }
+
+ // if we have no current chunk, then try to allocate one; this usually happens if we just have finished
+ // our last chunk, but also may happen on start
+ if (!Keeper.State.CurrentChunk && !TryToBeginNewChunk(ctx)) {
+ // can't handle this now, no chunks to write into, because write intent queue is empty; this function
+ // should be called once again when allocation occurs
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem no free chunks", item.QueryId);
+ return false;
+ }
+
+ // ensure we have a chunk to write into
+ Y_VERIFY(Keeper.State.CurrentChunk);
+ TChunkInfo& chunk = Keeper.State.Chunks.at(Keeper.State.CurrentChunk);
+ Y_VERIFY(chunk.State == EChunkState::Current);
+
+ // store chunk we are writing to into queue item
+ item.ChunkIdx = Keeper.State.CurrentChunk;
+
+ // if this request came from user, we have to generate blob's id and fill in its header; for writes from
+ // defragmenter these fields are already set
+ TBlobHeader& header = item.Header;
+ if (!item.Defrag) {
+ // generate id, register it in blob lookup table
+ item.Id = Keeper.State.BlobLookup.Create(TBlobLocator{Keeper.State.CurrentChunk,
+ CurrentChunkOffsetInBlocks, payloadSize, chunk.NumItems, item.Owner, false});
+
+ memset(&header, 0, sizeof(header));
+
+ // fill in index record which is a part of blob header
+ TBlobIndexRecord& indexRecord = header.IndexRecord;
+ indexRecord.Id = item.Id;
+ indexRecord.Lsn = item.Lsn;
+ indexRecord.Meta = item.Meta;
+ indexRecord.PayloadSize = payloadSize;
+ indexRecord.Owner = item.Owner;
+ }
+
+ // fill in header; calculate checksum for header (excluding CRC) + data
+ header.ChunkSerNum = chunk.ChunkSerNum;
header.Checksum = Crc32cExtend(Crc32c(&header.IndexRecord, sizeof(TBlobHeader) - sizeof(ui32)),
item.Data.data(), item.Data.size());
- static_assert(offsetof(TBlobHeader, Checksum) == 0 && sizeof(TBlobHeader::Checksum) == sizeof(ui32),
- "incorrect displacement of TBlobHeader::Checksum");
-
- item.SizeInBlocks = sizeInBlocks;
- item.IndexInsideChunk = chunk.NumItems;
- item.OffsetInBlocks = CurrentChunkOffsetInBlocks;
-
- // calculate padding required to get round request
- const ui32 padding = sizeInBlocks * Keeper.State.BlockSize - (sizeof(TBlobHeader) + payloadSize);
-
- // fill in parts array and create parts object to send it into yard; there are three parts -- blob header,
- // then blob data and padding to fill up to block size; if padding is zero, it is not added
- ui32 numParts = 0;
- item.Parts[numParts++] = {&item.Header, sizeof(TBlobHeader)};
+ static_assert(offsetof(TBlobHeader, Checksum) == 0 && sizeof(TBlobHeader::Checksum) == sizeof(ui32),
+ "incorrect displacement of TBlobHeader::Checksum");
+
+ item.SizeInBlocks = sizeInBlocks;
+ item.IndexInsideChunk = chunk.NumItems;
+ item.OffsetInBlocks = CurrentChunkOffsetInBlocks;
+
+ // calculate padding required to get round request
+ const ui32 padding = sizeInBlocks * Keeper.State.BlockSize - (sizeof(TBlobHeader) + payloadSize);
+
+ // fill in parts array and create parts object to send it into yard; there are three parts -- blob header,
+ // then blob data and padding to fill up to block size; if padding is zero, it is not added
+ ui32 numParts = 0;
+ item.Parts[numParts++] = {&item.Header, sizeof(TBlobHeader)};
item.Parts[numParts++] = {item.Data.data(), payloadSize};
- if (padding) {
- item.Parts[numParts++] = {nullptr, padding};
- }
-
- // calculate total size
- ui32 totalSize = 0;
- for (ui32 i = 0; i < numParts; ++i) {
- totalSize += item.Parts[i].Size;
- }
-
- // move this item into execution queue
- WriteInProgressItems.splice(WriteInProgressItems.end(), WriteQueue, it);
- ++Keeper.State.InFlightWrites;
-
- // create callback lambda that will be invoked upon write completion; this lambda invokes post-write handler
- // inside this class and then removes item from write-in-progress set and kicks queue processor to possibly
- // use just freed slot
- auto callback = [this, it](NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) {
- ApplyBlobWrite(status, *it, result, ctx);
- WriteInProgressItems.erase(it);
- --Keeper.State.InFlightWrites;
- ProcessWriteQueue(ctx);
- Keeper.Defragmenter.InFlightWritesChanged(ctx);
- };
-
- // prepare and send write message to yard
- const ui32 offset = CurrentChunkOffsetInBlocks * Keeper.State.BlockSize;
- auto writeMsg = std::make_unique<NPDisk::TEvChunkWrite>(Keeper.State.PDiskParams->Owner,
- Keeper.State.PDiskParams->OwnerRound, item.ChunkIdx, offset,
- new NPDisk::TEvChunkWrite::TNonOwningParts(item.Parts.data(), numParts), Keeper.RegisterYardCallback(
+ if (padding) {
+ item.Parts[numParts++] = {nullptr, padding};
+ }
+
+ // calculate total size
+ ui32 totalSize = 0;
+ for (ui32 i = 0; i < numParts; ++i) {
+ totalSize += item.Parts[i].Size;
+ }
+
+ // move this item into execution queue
+ WriteInProgressItems.splice(WriteInProgressItems.end(), WriteQueue, it);
+ ++Keeper.State.InFlightWrites;
+
+ // create callback lambda that will be invoked upon write completion; this lambda invokes post-write handler
+ // inside this class and then removes item from write-in-progress set and kicks queue processor to possibly
+ // use just freed slot
+ auto callback = [this, it](NKikimrProto::EReplyStatus status, IEventBase *result, const TActorContext& ctx) {
+ ApplyBlobWrite(status, *it, result, ctx);
+ WriteInProgressItems.erase(it);
+ --Keeper.State.InFlightWrites;
+ ProcessWriteQueue(ctx);
+ Keeper.Defragmenter.InFlightWritesChanged(ctx);
+ };
+
+ // prepare and send write message to yard
+ const ui32 offset = CurrentChunkOffsetInBlocks * Keeper.State.BlockSize;
+ auto writeMsg = std::make_unique<NPDisk::TEvChunkWrite>(Keeper.State.PDiskParams->Owner,
+ Keeper.State.PDiskParams->OwnerRound, item.ChunkIdx, offset,
+ new NPDisk::TEvChunkWrite::TNonOwningParts(item.Parts.data(), numParts), Keeper.RegisterYardCallback(
MakeCallback(std::move(callback))), true, NPriWrite::HullHugeUserData, true);
- ctx.Send(Keeper.State.Settings.PDiskActorId, writeMsg.release());
- ++CurrentChunkWritesInFlight;
-
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem OffsetInBlocks# %" PRIu32 " IndexInsideChunk# %"
- PRIu32 " SizeInBlocks# %" PRIu32 " SizeInBytes# %" PRIu32 " Offset# %" PRIu32 " Size# %" PRIu32
- " End# %" PRIu32 " Id# %016" PRIx64 " ChunkIdx# %" PRIu32 " ChunkSerNum# %s Defrag# %s",
- item.QueryId, CurrentChunkOffsetInBlocks, chunk.NumItems, sizeInBlocks, sizeInBlocks *
- Keeper.State.BlockSize, offset, totalSize, offset + totalSize, item.Id, item.ChunkIdx,
+ ctx.Send(Keeper.State.Settings.PDiskActorId, writeMsg.release());
+ ++CurrentChunkWritesInFlight;
+
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ProcessWriteItem OffsetInBlocks# %" PRIu32 " IndexInsideChunk# %"
+ PRIu32 " SizeInBlocks# %" PRIu32 " SizeInBytes# %" PRIu32 " Offset# %" PRIu32 " Size# %" PRIu32
+ " End# %" PRIu32 " Id# %016" PRIx64 " ChunkIdx# %" PRIu32 " ChunkSerNum# %s Defrag# %s",
+ item.QueryId, CurrentChunkOffsetInBlocks, chunk.NumItems, sizeInBlocks, sizeInBlocks *
+ Keeper.State.BlockSize, offset, totalSize, offset + totalSize, item.Id, item.ChunkIdx,
chunk.ChunkSerNum.ToString().data(), item.Defrag ? "true" : "false");
-
- // if this is defragmentation item, then put it into special hash map indicating that it is 'write in progress'
- // in this case, if delete request comes for such item, it should wait for defragmentation to finish
- if (item.Defrag) {
- Keeper.State.DefragWriteInProgress.emplace(item.Id, false);
- }
-
- // shift write pointers and update number of used blocks in current chunk; it may differ with offset
- // if blobs in current chunk were deleted while filling in the chunk
- CurrentChunkOffsetInBlocks += sizeInBlocks;
- chunk.NumUsedBlocks += sizeInBlocks;
- ++chunk.NumItems;
-
- // add index record
- CurrentChunkIndex.push_back(item.Header.IndexRecord);
-
- return true;
- }
-
- // blob write postprocessor code; it generates response to client and then checks if this chunk is in finalization
- // state
- void TWriter::ApplyBlobWrite(NKikimrProto::EReplyStatus status, TWriteQueueItem& item, IEventBase *result,
- const TActorContext& ctx) {
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ApplyBlobWrite Status# %s", item.QueryId,
+
+ // if this is defragmentation item, then put it into special hash map indicating that it is 'write in progress'
+ // in this case, if delete request comes for such item, it should wait for defragmentation to finish
+ if (item.Defrag) {
+ Keeper.State.DefragWriteInProgress.emplace(item.Id, false);
+ }
+
+ // shift write pointers and update number of used blocks in current chunk; it may differ with offset
+ // if blobs in current chunk were deleted while filling in the chunk
+ CurrentChunkOffsetInBlocks += sizeInBlocks;
+ chunk.NumUsedBlocks += sizeInBlocks;
+ ++chunk.NumItems;
+
+ // add index record
+ CurrentChunkIndex.push_back(item.Header.IndexRecord);
+
+ return true;
+ }
+
+ // blob write postprocessor code; it generates response to client and then checks if this chunk is in finalization
+ // state
+ void TWriter::ApplyBlobWrite(NKikimrProto::EReplyStatus status, TWriteQueueItem& item, IEventBase *result,
+ const TActorContext& ctx) {
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " ApplyBlobWrite Status# %s", item.QueryId,
NKikimrProto::EReplyStatus_Name(status).data());
-
- Y_VERIFY(status == NKikimrProto::OK, "don't know how to handle errors yet");
-
- // check if this item is from defragmenter
- if (item.Defrag) {
- // update item locator for a new place
- Keeper.State.BlobLookup.Replace(item.Id, TBlobLocator{item.ChunkIdx, item.OffsetInBlocks,
- item.Header.IndexRecord.PayloadSize, item.IndexInsideChunk, item.Header.IndexRecord.Owner,
- false});
-
- // remove item from set and kick deleter to resume operation for this item (if any)
- auto it = Keeper.State.DefragWriteInProgress.find(item.Id);
- Y_VERIFY(it != Keeper.State.DefragWriteInProgress.end());
- if (it->second) {
- Keeper.Deleter.OnItemDefragWritten(item.Id, ctx);
- }
- Keeper.State.DefragWriteInProgress.erase(it);
- }
-
- // invoke callback
- item.Callback->Apply(status, result, ctx);
-
- if (item.ChunkIdx == Keeper.State.CurrentChunk) {
- Y_VERIFY(CurrentChunkWritesInFlight > 0);
- --CurrentChunkWritesInFlight;
- } else {
- auto it = FinalizingChunks.find(item.ChunkIdx);
- Y_VERIFY(it != FinalizingChunks.end());
- TFinalizingChunk& fin = it->second;
- Y_VERIFY(fin.WritesInFlight > 0);
- --fin.WritesInFlight;
- if (CheckFinalizingChunk(item.ChunkIdx, fin, ctx)) {
- FinalizingChunks.erase(it);
- }
- }
- }
-
- bool TWriter::IsObsolete(const TWriteQueueItem& item, const TActorContext& ctx) {
- bool obsolete = true;
-
- // try to find chunk this item was in; if there is no such chunk, then item is obsolete
- auto it = Keeper.State.Chunks.find(item.OriginalChunkIdx);
- if (it != Keeper.State.Chunks.end()) {
- // ensure this chunk has the same version as recorded one
- TChunkInfo& chunk = it->second;
- if (chunk.ChunkSerNum == item.OriginalChunkSerNum) {
- // check for deletion
- obsolete = chunk.DeletedItems.Get(item.OriginalIndexInsideChunk);
- if (!obsolete) {
- // find locator
- const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(item.Header.IndexRecord.Id);
- Y_VERIFY(locator.ChunkIdx == item.OriginalChunkIdx);
- obsolete = locator.DeleteInProgress;
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " DeleteInProgress# %s", item.QueryId,
- obsolete ? "true" : "false");
- } else {
- IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " obsolete# true", item.QueryId);
- }
- }
- }
-
- return obsolete;
- }
-
+
+ Y_VERIFY(status == NKikimrProto::OK, "don't know how to handle errors yet");
+
+ // check if this item is from defragmenter
+ if (item.Defrag) {
+ // update item locator for a new place
+ Keeper.State.BlobLookup.Replace(item.Id, TBlobLocator{item.ChunkIdx, item.OffsetInBlocks,
+ item.Header.IndexRecord.PayloadSize, item.IndexInsideChunk, item.Header.IndexRecord.Owner,
+ false});
+
+ // remove item from set and kick deleter to resume operation for this item (if any)
+ auto it = Keeper.State.DefragWriteInProgress.find(item.Id);
+ Y_VERIFY(it != Keeper.State.DefragWriteInProgress.end());
+ if (it->second) {
+ Keeper.Deleter.OnItemDefragWritten(item.Id, ctx);
+ }
+ Keeper.State.DefragWriteInProgress.erase(it);
+ }
+
+ // invoke callback
+ item.Callback->Apply(status, result, ctx);
+
+ if (item.ChunkIdx == Keeper.State.CurrentChunk) {
+ Y_VERIFY(CurrentChunkWritesInFlight > 0);
+ --CurrentChunkWritesInFlight;
+ } else {
+ auto it = FinalizingChunks.find(item.ChunkIdx);
+ Y_VERIFY(it != FinalizingChunks.end());
+ TFinalizingChunk& fin = it->second;
+ Y_VERIFY(fin.WritesInFlight > 0);
+ --fin.WritesInFlight;
+ if (CheckFinalizingChunk(item.ChunkIdx, fin, ctx)) {
+ FinalizingChunks.erase(it);
+ }
+ }
+ }
+
+ bool TWriter::IsObsolete(const TWriteQueueItem& item, const TActorContext& ctx) {
+ bool obsolete = true;
+
+ // try to find chunk this item was in; if there is no such chunk, then item is obsolete
+ auto it = Keeper.State.Chunks.find(item.OriginalChunkIdx);
+ if (it != Keeper.State.Chunks.end()) {
+ // ensure this chunk has the same version as recorded one
+ TChunkInfo& chunk = it->second;
+ if (chunk.ChunkSerNum == item.OriginalChunkSerNum) {
+ // check for deletion
+ obsolete = chunk.DeletedItems.Get(item.OriginalIndexInsideChunk);
+ if (!obsolete) {
+ // find locator
+ const TBlobLocator& locator = Keeper.State.BlobLookup.Lookup(item.Header.IndexRecord.Id);
+ Y_VERIFY(locator.ChunkIdx == item.OriginalChunkIdx);
+ obsolete = locator.DeleteInProgress;
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " DeleteInProgress# %s", item.QueryId,
+ obsolete ? "true" : "false");
+ } else {
+ IHLOG_DEBUG(ctx, "QueryId# %" PRIu64 " obsolete# true", item.QueryId);
+ }
+ }
+ }
+
+ return obsolete;
+ }
+
void TWriter::SetUpCurrentChunk(ui32 offsetInBlocks, TVector<TBlobIndexRecord>&& index) {
- CurrentChunkOffsetInBlocks = offsetInBlocks;
- CurrentChunkIndex = std::move(index);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CHUNK ALLOCATION LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- bool TWriter::TryToBeginNewChunk(const TActorContext& ctx) {
- // see if we have some items in intent queue; if it is empty, return false meaning that we can't satisfy
- // this request right now
- if (Keeper.State.WriteIntentQueue.empty()) {
- return false;
- }
-
- // pop intent queue item
- TChunkIdx chunkIdx = Keeper.State.WriteIntentQueue.front();
- Keeper.State.WriteIntentQueue.pop();
-
- // find matching item in chunk set and set it as current
- auto it = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
- Y_VERIFY(chunk.State == EChunkState::WriteIntent);
- chunk.State = EChunkState::Current;
-
- // store current chunk index in common state
- Keeper.State.CurrentChunk = chunkIdx;
-
- // initialize local writer state
- CurrentChunkOffsetInBlocks = 0;
- CurrentChunkIndex.clear();
- CurrentChunkWritesInFlight = 0;
-
- // kick allocator because we have used one of write intent chunks; it may ask to allocate more of them
- Keeper.Allocator.CheckForAllocationNeed(ctx);
-
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CHUNK FINALIZATION LOGIC
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TWriter::TIndexWriteQueueItem {
- // the chunk we are finalizing
- TChunkIdx ChunkIdx;
- // index header
- TBlobIndexHeader Header;
- // list of parts to write; up to four: data padding, header, index, index padding
- std::array<NPDisk::TEvChunkWrite::TPart, 4> Parts;
- };
-
- void TWriter::FinishCurrentChunk(const TActorContext& ctx) {
- // create finalizing chunk record; store metadata here, it may be required in deletion and enumeration
- // this record lives longer that TIndexWriteQueueItem, so we store chunk index here
- Y_VERIFY_DEBUG(!FinalizingChunks.count(Keeper.State.CurrentChunk));
- TFinalizingChunk fin;
- fin.WritesInFlight = CurrentChunkWritesInFlight;
- fin.Index = std::move(CurrentChunkIndex);
- auto finIt = FinalizingChunks.emplace(Keeper.State.CurrentChunk, std::move(fin)).first;
-
- // create new index write queue item
- auto it = IndexWriteQueue.emplace(IndexWriteQueue.end());
- TIndexWriteQueueItem& item = *it;
-
- // ensure we have current chunk we are writing into and store it into item
- Y_VERIFY(Keeper.State.CurrentChunk);
- item.ChunkIdx = Keeper.State.CurrentChunk;
-
- // find current chunk and update its state
- TChunkInfo& chunk = Keeper.State.Chunks.at(Keeper.State.CurrentChunk);
- Y_VERIFY(chunk.State == EChunkState::Current);
- chunk.State = EChunkState::Finalizing;
-
- // calculate alignment up to data section end
- const ui32 dataPadding = (Keeper.State.BlocksInDataSection - CurrentChunkOffsetInBlocks) * Keeper.State.BlockSize;
-
- // generate index header
- TBlobIndexHeader& indexHeader = item.Header;
- memset(&indexHeader, 0, sizeof(indexHeader));
- indexHeader.ChunkSerNum = chunk.ChunkSerNum;
+ CurrentChunkOffsetInBlocks = offsetInBlocks;
+ CurrentChunkIndex = std::move(index);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CHUNK ALLOCATION LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ bool TWriter::TryToBeginNewChunk(const TActorContext& ctx) {
+ // see if we have some items in intent queue; if it is empty, return false meaning that we can't satisfy
+ // this request right now
+ if (Keeper.State.WriteIntentQueue.empty()) {
+ return false;
+ }
+
+ // pop intent queue item
+ TChunkIdx chunkIdx = Keeper.State.WriteIntentQueue.front();
+ Keeper.State.WriteIntentQueue.pop();
+
+ // find matching item in chunk set and set it as current
+ auto it = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
+ Y_VERIFY(chunk.State == EChunkState::WriteIntent);
+ chunk.State = EChunkState::Current;
+
+ // store current chunk index in common state
+ Keeper.State.CurrentChunk = chunkIdx;
+
+ // initialize local writer state
+ CurrentChunkOffsetInBlocks = 0;
+ CurrentChunkIndex.clear();
+ CurrentChunkWritesInFlight = 0;
+
+ // kick allocator because we have used one of write intent chunks; it may ask to allocate more of them
+ Keeper.Allocator.CheckForAllocationNeed(ctx);
+
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CHUNK FINALIZATION LOGIC
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TWriter::TIndexWriteQueueItem {
+ // the chunk we are finalizing
+ TChunkIdx ChunkIdx;
+ // index header
+ TBlobIndexHeader Header;
+ // list of parts to write; up to four: data padding, header, index, index padding
+ std::array<NPDisk::TEvChunkWrite::TPart, 4> Parts;
+ };
+
+ void TWriter::FinishCurrentChunk(const TActorContext& ctx) {
+ // create finalizing chunk record; store metadata here, it may be required in deletion and enumeration
+ // this record lives longer that TIndexWriteQueueItem, so we store chunk index here
+ Y_VERIFY_DEBUG(!FinalizingChunks.count(Keeper.State.CurrentChunk));
+ TFinalizingChunk fin;
+ fin.WritesInFlight = CurrentChunkWritesInFlight;
+ fin.Index = std::move(CurrentChunkIndex);
+ auto finIt = FinalizingChunks.emplace(Keeper.State.CurrentChunk, std::move(fin)).first;
+
+ // create new index write queue item
+ auto it = IndexWriteQueue.emplace(IndexWriteQueue.end());
+ TIndexWriteQueueItem& item = *it;
+
+ // ensure we have current chunk we are writing into and store it into item
+ Y_VERIFY(Keeper.State.CurrentChunk);
+ item.ChunkIdx = Keeper.State.CurrentChunk;
+
+ // find current chunk and update its state
+ TChunkInfo& chunk = Keeper.State.Chunks.at(Keeper.State.CurrentChunk);
+ Y_VERIFY(chunk.State == EChunkState::Current);
+ chunk.State = EChunkState::Finalizing;
+
+ // calculate alignment up to data section end
+ const ui32 dataPadding = (Keeper.State.BlocksInDataSection - CurrentChunkOffsetInBlocks) * Keeper.State.BlockSize;
+
+ // generate index header
+ TBlobIndexHeader& indexHeader = item.Header;
+ memset(&indexHeader, 0, sizeof(indexHeader));
+ indexHeader.ChunkSerNum = chunk.ChunkSerNum;
indexHeader.NumItems = finIt->second.Index.size();
indexHeader.Checksum = Crc32cExtend(Crc32c(&indexHeader.ChunkSerNum,
- sizeof(indexHeader) - sizeof(TBlobIndexHeader::Checksum)),
+ sizeof(indexHeader) - sizeof(TBlobIndexHeader::Checksum)),
finIt->second.Index.data(), indexHeader.NumItems * sizeof(TBlobIndexRecord));
- static_assert(offsetof(TBlobIndexHeader, Checksum) == 0 && sizeof(TBlobIndexHeader::Checksum) == sizeof(ui32),
- "incorrect displacement of TBlobIndexHeader::Checksum");
-
- // move index to queue item and calculate its size
- const ui32 indexSize = indexHeader.NumItems * sizeof(TBlobIndexRecord);
-
- // calculate index padding
- ui32 indexPadding = Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize - (sizeof(TBlobIndexHeader) +
- indexSize);
-
- // calculate parts we have to write
- ui32 numParts = 0;
- if (dataPadding) {
- item.Parts[numParts++] = {nullptr, dataPadding};
- }
- item.Parts[numParts++] = {&indexHeader, sizeof(TBlobIndexHeader)};
+ static_assert(offsetof(TBlobIndexHeader, Checksum) == 0 && sizeof(TBlobIndexHeader::Checksum) == sizeof(ui32),
+ "incorrect displacement of TBlobIndexHeader::Checksum");
+
+ // move index to queue item and calculate its size
+ const ui32 indexSize = indexHeader.NumItems * sizeof(TBlobIndexRecord);
+
+ // calculate index padding
+ ui32 indexPadding = Keeper.State.BlocksInIndexSection * Keeper.State.BlockSize - (sizeof(TBlobIndexHeader) +
+ indexSize);
+
+ // calculate parts we have to write
+ ui32 numParts = 0;
+ if (dataPadding) {
+ item.Parts[numParts++] = {nullptr, dataPadding};
+ }
+ item.Parts[numParts++] = {&indexHeader, sizeof(TBlobIndexHeader)};
item.Parts[numParts++] = {finIt->second.Index.data(), indexSize};
- if (indexPadding) {
- item.Parts[numParts++] = {nullptr, indexPadding};
- }
- ui32 totalSize = 0;
- for (ui32 i = 0; i < numParts; ++i) {
- totalSize += item.Parts[i].Size;
- }
- Y_VERIFY(totalSize % Keeper.State.PDiskParams->AppendBlockSize == 0, "totalSize# %" PRIu32
- " AppendBlockSize# %" PRIu32, totalSize, Keeper.State.PDiskParams->AppendBlockSize);
-
- // calculate and validate offset
- const ui32 offset = CurrentChunkOffsetInBlocks * Keeper.State.BlockSize;
- Y_VERIFY(offset + totalSize <= Keeper.State.PDiskParams->ChunkSize);
-
- // create callback object
- auto callback = [this, it](NKikimrProto::EReplyStatus status, IEventBase* /*result*/, const TActorContext& ctx) {
- ApplyIndexWrite(status, *it, ctx);
- IndexWriteQueue.erase(it);
- };
-
- IHLOG_DEBUG(ctx, "IndexWrite chunkIdx# %" PRIu32 " offset# %" PRIu32 " size# %"
- PRIu32 " end# %" PRIu32, item.ChunkIdx, offset, totalSize, offset + totalSize);
-
- // send write message to yard
- ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkWrite(Keeper.State.PDiskParams->Owner,
- Keeper.State.PDiskParams->OwnerRound, item.ChunkIdx, offset,
- new NPDisk::TEvChunkWrite::TNonOwningParts(item.Parts.data(), numParts),
+ if (indexPadding) {
+ item.Parts[numParts++] = {nullptr, indexPadding};
+ }
+ ui32 totalSize = 0;
+ for (ui32 i = 0; i < numParts; ++i) {
+ totalSize += item.Parts[i].Size;
+ }
+ Y_VERIFY(totalSize % Keeper.State.PDiskParams->AppendBlockSize == 0, "totalSize# %" PRIu32
+ " AppendBlockSize# %" PRIu32, totalSize, Keeper.State.PDiskParams->AppendBlockSize);
+
+ // calculate and validate offset
+ const ui32 offset = CurrentChunkOffsetInBlocks * Keeper.State.BlockSize;
+ Y_VERIFY(offset + totalSize <= Keeper.State.PDiskParams->ChunkSize);
+
+ // create callback object
+ auto callback = [this, it](NKikimrProto::EReplyStatus status, IEventBase* /*result*/, const TActorContext& ctx) {
+ ApplyIndexWrite(status, *it, ctx);
+ IndexWriteQueue.erase(it);
+ };
+
+ IHLOG_DEBUG(ctx, "IndexWrite chunkIdx# %" PRIu32 " offset# %" PRIu32 " size# %"
+ PRIu32 " end# %" PRIu32, item.ChunkIdx, offset, totalSize, offset + totalSize);
+
+ // send write message to yard
+ ctx.Send(Keeper.State.Settings.PDiskActorId, new NPDisk::TEvChunkWrite(Keeper.State.PDiskParams->Owner,
+ Keeper.State.PDiskParams->OwnerRound, item.ChunkIdx, offset,
+ new NPDisk::TEvChunkWrite::TNonOwningParts(item.Parts.data(), numParts),
Keeper.RegisterYardCallback(MakeCallback(std::move(callback))), true, NPriWrite::HullHugeUserData,
true));
-
- // clear current chunk state
- Keeper.State.CurrentChunk = 0;
- }
-
- void TWriter::ApplyIndexWrite(NKikimrProto::EReplyStatus status, TIndexWriteQueueItem& item, const TActorContext& ctx) {
- Y_VERIFY(status == NKikimrProto::OK, "don't know how to handle errors yet");
-
- auto it = FinalizingChunks.find(item.ChunkIdx);
- Y_VERIFY(it != FinalizingChunks.end());
- TFinalizingChunk& fin = it->second;
- Y_VERIFY(!fin.IndexWritten);
- fin.IndexWritten = true;
- if (CheckFinalizingChunk(item.ChunkIdx, fin, ctx)) {
- FinalizingChunks.erase(it);
- }
- }
-
- bool TWriter::CheckFinalizingChunk(ui32 chunkIdx, TFinalizingChunk& fin, const TActorContext& ctx) {
- if (fin.WritesInFlight == 0 && fin.IndexWritten) {
- TChunkInfo& chunk = Keeper.State.Chunks.at(chunkIdx);
- Y_VERIFY(chunk.State == EChunkState::Finalizing);
-
- // check if all chunk contents were deleted while finalizing; if so, this record should be deleted
- if (!chunk.NumUsedBlocks) {
- IHLOG_DEBUG(ctx, "deleting ChunkIdx# %" PRIu32, chunkIdx);
- Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
- return true;
- }
-
- // ensure the chunk is not empty
- Y_VERIFY(chunk.NumUsedBlocks > 0);
-
- // set state to complete
- chunk.State = EChunkState::Complete;
-
- // he have just filled in new chunk, so we may log it; we do not block until this request completes
- // because maximum side-effect of failure is a little recovery performance impact due to need of
- // extra chunk scan
- Keeper.Logger.LogCompleteChunk(chunkIdx, chunk.ChunkSerNum, ctx);
-
- // update defragmenter state for this chunk
- Keeper.Defragmenter.UpdateChunkState(chunkIdx, ctx);
-
- return true;
- }
-
- return false;
- }
-
+
+ // clear current chunk state
+ Keeper.State.CurrentChunk = 0;
+ }
+
+ void TWriter::ApplyIndexWrite(NKikimrProto::EReplyStatus status, TIndexWriteQueueItem& item, const TActorContext& ctx) {
+ Y_VERIFY(status == NKikimrProto::OK, "don't know how to handle errors yet");
+
+ auto it = FinalizingChunks.find(item.ChunkIdx);
+ Y_VERIFY(it != FinalizingChunks.end());
+ TFinalizingChunk& fin = it->second;
+ Y_VERIFY(!fin.IndexWritten);
+ fin.IndexWritten = true;
+ if (CheckFinalizingChunk(item.ChunkIdx, fin, ctx)) {
+ FinalizingChunks.erase(it);
+ }
+ }
+
+ bool TWriter::CheckFinalizingChunk(ui32 chunkIdx, TFinalizingChunk& fin, const TActorContext& ctx) {
+ if (fin.WritesInFlight == 0 && fin.IndexWritten) {
+ TChunkInfo& chunk = Keeper.State.Chunks.at(chunkIdx);
+ Y_VERIFY(chunk.State == EChunkState::Finalizing);
+
+ // check if all chunk contents were deleted while finalizing; if so, this record should be deleted
+ if (!chunk.NumUsedBlocks) {
+ IHLOG_DEBUG(ctx, "deleting ChunkIdx# %" PRIu32, chunkIdx);
+ Keeper.Deleter.IssueLogChunkDelete(chunkIdx, ctx);
+ return true;
+ }
+
+ // ensure the chunk is not empty
+ Y_VERIFY(chunk.NumUsedBlocks > 0);
+
+ // set state to complete
+ chunk.State = EChunkState::Complete;
+
+ // he have just filled in new chunk, so we may log it; we do not block until this request completes
+ // because maximum side-effect of failure is a little recovery performance impact due to need of
+ // extra chunk scan
+ Keeper.Logger.LogCompleteChunk(chunkIdx, chunk.ChunkSerNum, ctx);
+
+ // update defragmenter state for this chunk
+ Keeper.Defragmenter.UpdateChunkState(chunkIdx, ctx);
+
+ return true;
+ }
+
+ return false;
+ }
+
TVector<TEvIncrHugeInitResult::TItem> TWriter::EnumerateItems(ui8 owner, ui64 firstLsn) {
TVector<TEvIncrHugeInitResult::TItem> res;
auto scanChunk = [&](TChunkIdx chunkIdx, const TVector<TBlobIndexRecord>& index) {
- auto it = Keeper.State.Chunks.find(chunkIdx);
- Y_VERIFY(it != Keeper.State.Chunks.end());
- TChunkInfo& chunk = it->second;
+ auto it = Keeper.State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != Keeper.State.Chunks.end());
+ TChunkInfo& chunk = it->second;
for (ui32 i = 0; i < index.size(); ++i) {
- const TBlobIndexRecord& record = index[i];
- if (!chunk.DeletedItems.Get(i) && record.Owner == owner && record.Lsn >= firstLsn) {
- res.push_back(TEvIncrHugeInitResult::TItem{
- record.Id,
- record.Lsn,
- record.Meta
- });
- }
- }
- };
-
- if (const TChunkIdx chunkIdx = Keeper.State.CurrentChunk) {
- scanChunk(chunkIdx, CurrentChunkIndex);
- }
- for (const auto& pair : FinalizingChunks) {
- scanChunk(pair.first, pair.second.Index);
- }
-
- return res;
- }
-
- } // NIncrHuge
-} // NKikimr
+ const TBlobIndexRecord& record = index[i];
+ if (!chunk.DeletedItems.Get(i) && record.Owner == owner && record.Lsn >= firstLsn) {
+ res.push_back(TEvIncrHugeInitResult::TItem{
+ record.Id,
+ record.Lsn,
+ record.Meta
+ });
+ }
+ }
+ };
+
+ if (const TChunkIdx chunkIdx = Keeper.State.CurrentChunk) {
+ scanChunk(chunkIdx, CurrentChunkIndex);
+ }
+ for (const auto& pair : FinalizingChunks) {
+ scanChunk(pair.first, pair.second.Index);
+ }
+
+ return res;
+ }
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.h b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.h
index 4563da6d542..c0416691e11 100644
--- a/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.h
+++ b/ydb/core/blobstorage/incrhuge/incrhuge_keeper_write.h
@@ -1,123 +1,123 @@
-#pragma once
-
-#include "defs.h"
-#include "incrhuge_keeper_common.h"
-#include "incrhuge.h"
-#include "incrhuge_data.h"
-
-#include <util/generic/queue.h>
-
-namespace NKikimr {
- namespace NIncrHuge {
-
- // keeper forward reference
- class TKeeper;
-
- class TWriter
- : public TKeeperComponentBase
- {
- // offset (in blocks) inside current chunks
- ui32 CurrentChunkOffsetInBlocks = 0;
-
- // index of current chunk
+#pragma once
+
+#include "defs.h"
+#include "incrhuge_keeper_common.h"
+#include "incrhuge.h"
+#include "incrhuge_data.h"
+
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+ namespace NIncrHuge {
+
+ // keeper forward reference
+ class TKeeper;
+
+ class TWriter
+ : public TKeeperComponentBase
+ {
+ // offset (in blocks) inside current chunks
+ ui32 CurrentChunkOffsetInBlocks = 0;
+
+ // index of current chunk
TVector<TBlobIndexRecord> CurrentChunkIndex;
-
- // number of in-flight blob write requests to current chunk
- ui32 CurrentChunkWritesInFlight = 0;
-
- // write queue
- struct TWriteQueueItem;
+
+ // number of in-flight blob write requests to current chunk
+ ui32 CurrentChunkWritesInFlight = 0;
+
+ // write queue
+ struct TWriteQueueItem;
using TWriteQueue = TList<TWriteQueueItem>;
- TWriteQueue WriteQueue; // pending items
- TWriteQueue WriteInProgressItems; // items in work; they all are executed concurrently and may finish out-of-order
-
- // index write queue
- struct TIndexWriteQueueItem;
+ TWriteQueue WriteQueue; // pending items
+ TWriteQueue WriteInProgressItems; // items in work; they all are executed concurrently and may finish out-of-order
+
+ // index write queue
+ struct TIndexWriteQueueItem;
using TIndexWriteQueue = TList<TIndexWriteQueueItem>;
- TIndexWriteQueue IndexWriteQueue;
-
- // finalization chunk queue
- struct TFinalizingChunk {
- // number of writes in flight to this chunk
- ui32 WritesInFlight = 0;
-
- // index write finished?
- bool IndexWritten = false;
-
- // index of chunk being finalized
+ TIndexWriteQueue IndexWriteQueue;
+
+ // finalization chunk queue
+ struct TFinalizingChunk {
+ // number of writes in flight to this chunk
+ ui32 WritesInFlight = 0;
+
+ // index write finished?
+ bool IndexWritten = false;
+
+ // index of chunk being finalized
TVector<TBlobIndexRecord> Index;
- };
-
+ };
+
THashMap<TChunkIdx, TFinalizingChunk> FinalizingChunks;
-
- ui64 NextQueryId = 0;
-
- public:
- TWriter(TKeeper& keeper);
- ~TWriter();
-
- //////////////////////////
- // write queue handling //
- //////////////////////////
-
- // write request handler
- void HandleWrite(TEvIncrHugeWrite::TPtr& ev, const TActorContext& ctx);
-
- // defragmentation write handler
- void EnqueueDefragWrite(const TBlobHeader& header, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
- ui32 indexInsideChunk, TString&& data, std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
-
- // process queue items as much as possible; this function should be called when conditions to process queue
- // items successfully may occur; for example, chunk allocation occured or one of previous writes finished
- void ProcessWriteQueue(const TActorContext& ctx);
-
- // try to process item inside write queue; it may start processing if there is enough space, then item
- // will be marked as in progress; if item processing is started, returns true; otherwise false
- bool ProcessWriteItem(TWriteQueue::iterator it, const TActorContext& ctx);
-
- // blob writer callback; called when write operation finishes
- void ApplyBlobWrite(NKikimrProto::EReplyStatus status, TWriteQueueItem& item, IEventBase *result,
- const TActorContext& ctx);
-
- // reset writer to specified position (used in recovery)
+
+ ui64 NextQueryId = 0;
+
+ public:
+ TWriter(TKeeper& keeper);
+ ~TWriter();
+
+ //////////////////////////
+ // write queue handling //
+ //////////////////////////
+
+ // write request handler
+ void HandleWrite(TEvIncrHugeWrite::TPtr& ev, const TActorContext& ctx);
+
+ // defragmentation write handler
+ void EnqueueDefragWrite(const TBlobHeader& header, TChunkIdx chunkIdx, TChunkSerNum chunkSerNum,
+ ui32 indexInsideChunk, TString&& data, std::unique_ptr<IEventCallback>&& callback, const TActorContext& ctx);
+
+ // process queue items as much as possible; this function should be called when conditions to process queue
+ // items successfully may occur; for example, chunk allocation occured or one of previous writes finished
+ void ProcessWriteQueue(const TActorContext& ctx);
+
+ // try to process item inside write queue; it may start processing if there is enough space, then item
+ // will be marked as in progress; if item processing is started, returns true; otherwise false
+ bool ProcessWriteItem(TWriteQueue::iterator it, const TActorContext& ctx);
+
+ // blob writer callback; called when write operation finishes
+ void ApplyBlobWrite(NKikimrProto::EReplyStatus status, TWriteQueueItem& item, IEventBase *result,
+ const TActorContext& ctx);
+
+ // reset writer to specified position (used in recovery)
void SetUpCurrentChunk(ui32 offsetInBlocks, TVector<TBlobIndexRecord>&& index);
-
- // check if item is obsolete
- bool IsObsolete(const TWriteQueueItem& item, const TActorContext& ctx);
-
- //////////////////////
- // Chunk allocation //
- //////////////////////
-
- bool TryToBeginNewChunk(const TActorContext& ctx);
-
- ////////////////////////
- // Chunk finalization //
- ////////////////////////
-
- // this function generates index and issues write message to PDisk
- void FinishCurrentChunk(const TActorContext& ctx);
-
- // this callback is called when index write is finished
- void ApplyIndexWrite(NKikimrProto::EReplyStatus status, TIndexWriteQueueItem& item, const TActorContext& ctx);
-
- // check if chunk is completely finalized, that is index is written and there is no blob writes in flight,
- // and then put this chunk into filled chunks map; in this case function return true; otherwise it returns
- // false
- bool CheckFinalizingChunk(TChunkIdx chunkIdx, TFinalizingChunk& fin, const TActorContext& ctx);
-
- // get pointer to chunk in 'finalizing' state; this is needed by deleter to clean up items in such chunks
- TFinalizingChunk *GetFinalizingChunk(TChunkIdx chunkIdx);
-
- // put finalizing chunks to log record
- void PutFinalizingChunks(NKikimrVDiskData::TIncrHugeChunks *record) const;
-
- /////////////////
- // Client init //
- /////////////////
-
+
+ // check if item is obsolete
+ bool IsObsolete(const TWriteQueueItem& item, const TActorContext& ctx);
+
+ //////////////////////
+ // Chunk allocation //
+ //////////////////////
+
+ bool TryToBeginNewChunk(const TActorContext& ctx);
+
+ ////////////////////////
+ // Chunk finalization //
+ ////////////////////////
+
+ // this function generates index and issues write message to PDisk
+ void FinishCurrentChunk(const TActorContext& ctx);
+
+ // this callback is called when index write is finished
+ void ApplyIndexWrite(NKikimrProto::EReplyStatus status, TIndexWriteQueueItem& item, const TActorContext& ctx);
+
+ // check if chunk is completely finalized, that is index is written and there is no blob writes in flight,
+ // and then put this chunk into filled chunks map; in this case function return true; otherwise it returns
+ // false
+ bool CheckFinalizingChunk(TChunkIdx chunkIdx, TFinalizingChunk& fin, const TActorContext& ctx);
+
+ // get pointer to chunk in 'finalizing' state; this is needed by deleter to clean up items in such chunks
+ TFinalizingChunk *GetFinalizingChunk(TChunkIdx chunkIdx);
+
+ // put finalizing chunks to log record
+ void PutFinalizingChunks(NKikimrVDiskData::TIncrHugeChunks *record) const;
+
+ /////////////////
+ // Client init //
+ /////////////////
+
TVector<TEvIncrHugeInitResult::TItem> EnumerateItems(ui8 owner, ui64 firstLsn);
- };
-
- } // NIncrHuge
-} // NKikimr
+ };
+
+ } // NIncrHuge
+} // NKikimr
diff --git a/ydb/core/blobstorage/incrhuge/ut/faulty_pdisk.h b/ydb/core/blobstorage/incrhuge/ut/faulty_pdisk.h
index 73735697022..38c9b8bb261 100644
--- a/ydb/core/blobstorage/incrhuge/ut/faulty_pdisk.h
+++ b/ydb/core/blobstorage/incrhuge/ut/faulty_pdisk.h
@@ -1,24 +1,24 @@
-#pragma once
-
-class TFaultyPDiskActor : public TActor<TFaultyPDiskActor> {
+#pragma once
+
+class TFaultyPDiskActor : public TActor<TFaultyPDiskActor> {
TActorId PDiskId;
- ui32 Counter;
- TManualEvent *Event;
-
-public:
+ ui32 Counter;
+ TManualEvent *Event;
+
+public:
TFaultyPDiskActor(const TActorId& pdiskId, ui32 counter, TManualEvent *event)
- : TActor<TFaultyPDiskActor>(&TFaultyPDiskActor::StateFunc)
- , PDiskId(pdiskId)
- , Counter(counter)
- , Event(event)
- {}
-
- STFUNC(StateFunc) {
- if (!Counter--) {
- Event->Signal();
- Die(ctx);
- } else {
- ctx.ExecutorThread.Send(ev->Forward(PDiskId));
- }
- }
-};
+ : TActor<TFaultyPDiskActor>(&TFaultyPDiskActor::StateFunc)
+ , PDiskId(pdiskId)
+ , Counter(counter)
+ , Event(event)
+ {}
+
+ STFUNC(StateFunc) {
+ if (!Counter--) {
+ Event->Signal();
+ Die(ctx);
+ } else {
+ ctx.ExecutorThread.Send(ev->Forward(PDiskId));
+ }
+ }
+};
diff --git a/ydb/core/blobstorage/incrhuge/ut/incrhuge_basic_ut.cpp b/ydb/core/blobstorage/incrhuge/ut/incrhuge_basic_ut.cpp
index 59d3cb999cf..18dad237a8f 100644
--- a/ydb/core/blobstorage/incrhuge/ut/incrhuge_basic_ut.cpp
+++ b/ydb/core/blobstorage/incrhuge/ut/incrhuge_basic_ut.cpp
@@ -7,95 +7,95 @@
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_tools.h>
#include <library/cpp/actors/protos/services_common.pb.h>
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/fast.h>
-#include <util/folder/tempdir.h>
-#include <util/folder/path.h>
+#include <util/random/fast.h>
+#include <util/folder/tempdir.h>
+#include <util/folder/path.h>
#include <util/system/sanitizers.h>
#include <util/system/valgrind.h>
-
-using namespace NActors;
-using namespace NKikimr;
-using namespace NKikimr::NIncrHuge;
-
-#include "test_actor_concurrent.h"
-#include "test_actor_seq.h"
-#include "faulty_pdisk.h"
-
-class TTestEnv {
-public:
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters = new NMonitoring::TDynamicCounters;
+
+using namespace NActors;
+using namespace NKikimr;
+using namespace NKikimr::NIncrHuge;
+
+#include "test_actor_concurrent.h"
+#include "test_actor_seq.h"
+#include "faulty_pdisk.h"
+
+class TTestEnv {
+public:
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters = new NMonitoring::TDynamicCounters;
TString Path;
- ui32 ChunkSize;
- ui64 DiskSize;
- ui64 PDiskGuid;
- ui64 PDiskKey;
+ ui32 ChunkSize;
+ ui64 DiskSize;
+ ui64 PDiskGuid;
+ ui64 PDiskKey;
TActorId PDiskId;
TActorId KeeperId;
- std::unique_ptr<TActorSystem> ActorSystem;
- TTempDir TempDir;
- std::unique_ptr<TAppData> AppData;
+ std::unique_ptr<TActorSystem> ActorSystem;
+ TTempDir TempDir;
+ std::unique_ptr<TAppData> AppData;
std::shared_ptr<NPDisk::IIoContextFactory> IoContext;
-
- void Setup(bool format = true, ui32 counter = 0, TManualEvent *event = nullptr, ui32 numChunks = 1000,
- ui32 chunkSize = 16 << 20) {
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 3;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[3]);
- setup->Executors[0].Reset(new TBasicExecutorPool(0, 2, 20));
- setup->Executors[1].Reset(new TBasicExecutorPool(1, 2, 20));
- setup->Executors[2].Reset(new TIOExecutorPool(2, 10));
- setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PDisk
- if (format) {
+
+ void Setup(bool format = true, ui32 counter = 0, TManualEvent *event = nullptr, ui32 numChunks = 1000,
+ ui32 chunkSize = 16 << 20) {
+ auto setup = MakeHolder<TActorSystemSetup>();
+ setup->NodeId = 1;
+ setup->ExecutorsCount = 3;
+ setup->Executors.Reset(new TAutoPtr<IExecutorPool>[3]);
+ setup->Executors[0].Reset(new TBasicExecutorPool(0, 2, 20));
+ setup->Executors[1].Reset(new TBasicExecutorPool(1, 2, 20));
+ setup->Executors[2].Reset(new TIOExecutorPool(2, 10));
+ setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PDisk
+ if (format) {
TString dir = TempDir();
- Path = dir + "/incrhuge.bin";
- TFsPath(Path).DeleteIfExists();
- ChunkSize = chunkSize;
- DiskSize = (ui64)ChunkSize * numChunks;
- PDiskGuid = Now().GetValue();
- PDiskKey = 1;
- FormatPDisk(Path, DiskSize, 4096, ChunkSize, PDiskGuid, PDiskKey, PDiskKey, PDiskKey, PDiskKey, "incrhuge");
- }
-
- PDiskId = MakeBlobStoragePDiskID(1, 1);
- ui64 pDiskCategory = 0;
- TIntrusivePtr<TPDiskConfig> pDiskConfig = new TPDiskConfig(Path, PDiskGuid, 1, pDiskCategory);
- TActorSetupCmd pDiskSetup(CreatePDisk(pDiskConfig.Get(), PDiskKey, Counters), TMailboxType::Revolving, 0);
- setup->LocalServices.emplace_back(PDiskId, pDiskSetup);
-
+ Path = dir + "/incrhuge.bin";
+ TFsPath(Path).DeleteIfExists();
+ ChunkSize = chunkSize;
+ DiskSize = (ui64)ChunkSize * numChunks;
+ PDiskGuid = Now().GetValue();
+ PDiskKey = 1;
+ FormatPDisk(Path, DiskSize, 4096, ChunkSize, PDiskGuid, PDiskKey, PDiskKey, PDiskKey, PDiskKey, "incrhuge");
+ }
+
+ PDiskId = MakeBlobStoragePDiskID(1, 1);
+ ui64 pDiskCategory = 0;
+ TIntrusivePtr<TPDiskConfig> pDiskConfig = new TPDiskConfig(Path, PDiskGuid, 1, pDiskCategory);
+ TActorSetupCmd pDiskSetup(CreatePDisk(pDiskConfig.Get(), PDiskKey, Counters), TMailboxType::Revolving, 0);
+ setup->LocalServices.emplace_back(PDiskId, pDiskSetup);
+
TActorId pdiskActorId;
- if (counter) {
- char x[12] = {'f', 'a', 'u', 'l', 't', 'y', 'p', 'd', 'i', 's', 'k'};
+ if (counter) {
+ char x[12] = {'f', 'a', 'u', 'l', 't', 'y', 'p', 'd', 'i', 's', 'k'};
pdiskActorId = TActorId(0, x);
- setup->LocalServices.emplace_back(pdiskActorId, TActorSetupCmd(new TFaultyPDiskActor(PDiskId, counter, event),
- TMailboxType::Simple, 0));
- } else {
- pdiskActorId = PDiskId;
- }
-
- TKeeperSettings settings;
- settings.PDiskId = 1;
- settings.PDiskActorId = pdiskActorId;
- settings.PDiskGuid = PDiskGuid;
- settings.MinCleanChunks = 8;
- settings.MinAllocationBatch = 4;
- settings.UnalignedBlockSize = 4096;
- settings.MinHugeBlobInBytes = 512 << 10;
- settings.MaxInFlightWrites = 5;
+ setup->LocalServices.emplace_back(pdiskActorId, TActorSetupCmd(new TFaultyPDiskActor(PDiskId, counter, event),
+ TMailboxType::Simple, 0));
+ } else {
+ pdiskActorId = PDiskId;
+ }
+
+ TKeeperSettings settings;
+ settings.PDiskId = 1;
+ settings.PDiskActorId = pdiskActorId;
+ settings.PDiskGuid = PDiskGuid;
+ settings.MinCleanChunks = 8;
+ settings.MinAllocationBatch = 4;
+ settings.UnalignedBlockSize = 4096;
+ settings.MinHugeBlobInBytes = 512 << 10;
+ settings.MaxInFlightWrites = 5;
settings.InitOwnerRound = 2;
-
- KeeperId = MakeIncrHugeKeeperId(1);
- TActorSetupCmd keeperSetup(CreateIncrHugeKeeper(settings), TMailboxType::Revolving, 0);
- setup->LocalServices.emplace_back(KeeperId, keeperSetup);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // LOGGER
+
+ KeeperId = MakeIncrHugeKeeperId(1);
+ TActorSetupCmd keeperSetup(CreateIncrHugeKeeper(settings), TMailboxType::Revolving, 0);
+ setup->LocalServices.emplace_back(KeeperId, keeperSetup);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LOGGER
NActors::TActorId loggerActorId{1, "logger"};
- TIntrusivePtr<NActors::NLog::TSettings> logSettings{new NActors::NLog::TSettings{loggerActorId,
- NKikimrServices::LOGGER, NActors::NLog::PRI_ERROR, NActors::NLog::PRI_ERROR, 0}};
+ TIntrusivePtr<NActors::NLog::TSettings> logSettings{new NActors::NLog::TSettings{loggerActorId,
+ NKikimrServices::LOGGER, NActors::NLog::PRI_ERROR, NActors::NLog::PRI_ERROR, 0}};
logSettings->Append(
NActorsServices::EServiceCommon_MIN,
NActorsServices::EServiceCommon_MAX,
@@ -103,170 +103,170 @@ public:
);
logSettings->Append(
NKikimrServices::EServiceKikimr_MIN,
- NKikimrServices::EServiceKikimr_MAX,
+ NKikimrServices::EServiceKikimr_MAX,
NKikimrServices::EServiceKikimr_Name
);
TString explanation;
- logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_INCRHUGE, explanation);
- logSettings->SetLevel(NLog::PRI_DEBUG, NActorsServices::TEST, explanation);
-
- NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor{logSettings, NActors::CreateStderrBackend(),
- Counters};
- NActors::TActorSetupCmd loggerActorCmd{loggerActor, NActors::TMailboxType::Simple, 2};
- setup->LocalServices.emplace_back(loggerActorId, loggerActorCmd);
- AppData.reset(new TAppData(0, 1, 2, 1, TMap<TString, ui32>(), nullptr, nullptr, nullptr, nullptr));
+ logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_INCRHUGE, explanation);
+ logSettings->SetLevel(NLog::PRI_DEBUG, NActorsServices::TEST, explanation);
+
+ NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor{logSettings, NActors::CreateStderrBackend(),
+ Counters};
+ NActors::TActorSetupCmd loggerActorCmd{loggerActor, NActors::TMailboxType::Simple, 2};
+ setup->LocalServices.emplace_back(loggerActorId, loggerActorCmd);
+ AppData.reset(new TAppData(0, 1, 2, 1, TMap<TString, ui32>(), nullptr, nullptr, nullptr, nullptr));
IoContext = std::make_shared<NPDisk::TIoContextFactoryOSS>();
AppData->IoContextFactory = IoContext.get();
-
- ActorSystem.reset(new TActorSystem{setup, AppData.get(), logSettings});
- }
-
- void Start() {
- ActorSystem->Start();
- }
-
- void Stop() {
- ActorSystem->Stop();
- ActorSystem.reset();
- }
-};
-
+
+ ActorSystem.reset(new TActorSystem{setup, AppData.get(), logSettings});
+ }
+
+ void Start() {
+ ActorSystem->Start();
+ }
+
+ void Stop() {
+ ActorSystem->Stop();
+ ActorSystem.reset();
+ }
+};
+
Y_UNIT_TEST_SUITE(TIncrHugeBasicTest) {
Y_UNIT_TEST(WriteReadDeleteEnum) {
- return; /* TODO(alexvru): https://st.yandex-team.ru/KIKIMR-7588 */
-
- TTestEnv env;
- env.Setup();
- env.Start();
- TManualEvent event;
- TTestActorConcurrent::TTestActorState state;
+ return; /* TODO(alexvru): https://st.yandex-team.ru/KIKIMR-7588 */
+
+ TTestEnv env;
+ env.Setup();
+ env.Start();
+ TManualEvent event;
+ TTestActorConcurrent::TTestActorState state;
const ui32 numActions = NSan::PlainOrUnderSanitizer(
NValgrind::PlainOrUnderValgrind(10000, 100),
1000
);
TTestActorConcurrent *actor = new TTestActorConcurrent(env.KeeperId, &event, state, numActions, 1);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
- }
-
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+ }
+
Y_UNIT_TEST(WriteReadDeleteEnumRecover) {
- return; /* TODO(alexvru): https://st.yandex-team.ru/KIKIMR-7588 */
-
- TTestActorConcurrent::TTestActorState state;
- TManualEvent event;
- TTestActorConcurrent *actor;
- TTestEnv env;
-
- env.Setup();
- env.Start();
- actor = new TTestActorConcurrent(env.KeeperId, &event, state, 500, 1);
- env.ActorSystem->Register(actor);
- event.WaitI();
- usleep(150000);
- env.Stop();
-
- for (ui32 i = 0; i < 10; ++i) {
- event.Reset();
-
- env.Setup(false);
- env.Start();
+ return; /* TODO(alexvru): https://st.yandex-team.ru/KIKIMR-7588 */
+
+ TTestActorConcurrent::TTestActorState state;
+ TManualEvent event;
+ TTestActorConcurrent *actor;
+ TTestEnv env;
+
+ env.Setup();
+ env.Start();
+ actor = new TTestActorConcurrent(env.KeeperId, &event, state, 500, 1);
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ usleep(150000);
+ env.Stop();
+
+ for (ui32 i = 0; i < 10; ++i) {
+ event.Reset();
+
+ env.Setup(false);
+ env.Start();
const ui32 numActions = NSan::PlainOrUnderSanitizer(100, 10);
actor = new TTestActorConcurrent(env.KeeperId, &event, state, numActions, 2);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
- }
- }
-
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+ }
+ }
+
Y_UNIT_TEST(Defrag) {
- TTestEnv env;
- env.Setup(true, 0, nullptr, 1000);
- env.Start();
- TManualEvent event;
- TTestActorConcurrent::TTestActorState state;
+ TTestEnv env;
+ env.Setup(true, 0, nullptr, 1000);
+ env.Start();
+ TManualEvent event;
+ TTestActorConcurrent::TTestActorState state;
const ui32 initialNumActions = NSan::PlainOrUnderSanitizer(1000, 100);
TTestActorConcurrent *actor = new TTestActorConcurrent(env.KeeperId, &event, state, initialNumActions, 1,
- 100000 /* writeScore */, 80000 /* deleteScore */, 0 /* readScore */);
- env.ActorSystem->Register(actor);
-// usleep(1 * 1000 * 1000);
-// env.ActorSystem->Send(new IEventHandle(env.KeeperId, id, new TEvIncrHugeControlDefrag(0.8)));
- event.WaitI();
- usleep(50 * 1000 * 1000); // wait for defragment
- env.Stop();
-
- event.Reset();
-
- env.Setup(false);
- env.Start();
- LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "starting recovery");
+ 100000 /* writeScore */, 80000 /* deleteScore */, 0 /* readScore */);
+ env.ActorSystem->Register(actor);
+// usleep(1 * 1000 * 1000);
+// env.ActorSystem->Send(new IEventHandle(env.KeeperId, id, new TEvIncrHugeControlDefrag(0.8)));
+ event.WaitI();
+ usleep(50 * 1000 * 1000); // wait for defragment
+ env.Stop();
+
+ event.Reset();
+
+ env.Setup(false);
+ env.Start();
+ LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "starting recovery");
const ui32 numActions = NSan::PlainOrUnderSanitizer(5000, 1000);
actor = new TTestActorConcurrent(env.KeeperId, &event, state, numActions, 2);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
- }
-
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+ }
+
Y_UNIT_TEST(Recovery) {
return; // TODO https://st.yandex-team.ru/KIKIMR-3065
- TTestEnv env;
- env.Setup(true, 0, nullptr, 2000, 128 << 20);
- env.Start();
- TManualEvent event;
- TTestActorConcurrent::TTestActorState state;
+ TTestEnv env;
+ env.Setup(true, 0, nullptr, 2000, 128 << 20);
+ env.Start();
+ TManualEvent event;
+ TTestActorConcurrent::TTestActorState state;
const ui32 numActions = NSan::PlainOrUnderSanitizer(33333, 1000);
TTestActorConcurrent *actor = new TTestActorConcurrent(env.KeeperId, &event, state, numActions, 1,
- 100000 /* writeScore */, 1000 /* deleteScore */, 0 /* readScore */);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
-
- event.Reset();
-
- env.Setup(false);
- env.Start();
- LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "starting recovery");
- actor = new TTestActorConcurrent(env.KeeperId, &event, state, 0, 2);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
- }
-
+ 100000 /* writeScore */, 1000 /* deleteScore */, 0 /* readScore */);
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+
+ event.Reset();
+
+ env.Setup(false);
+ env.Start();
+ LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "starting recovery");
+ actor = new TTestActorConcurrent(env.KeeperId, &event, state, 0, 2);
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+ }
+
/* Y_UNIT_TEST(FaultyPDisk) {
- for (ui32 counter = 20; counter < 1000; ++counter) {
- TTestActorSeq::TTestActorState state;
- TTestActorSeq *actor;
- TTestEnv env;
- TManualEvent event;
-
- env.Setup(true, counter, &event);
- env.Start();
- LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== starting Counter# %" PRIu32, counter);
- actor = new TTestActorSeq(env.KeeperId, state, 1, nullptr);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
-
- event.Reset();
-
- env.Setup(false);
- env.Start();
- LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== restarting 1");
- actor = new TTestActorSeq(env.KeeperId, state, 1, &event);
- env.ActorSystem->Register(actor);
- usleep(5 * 1000 * 1000);
- env.Stop();
-
- event.Reset();
-
- env.Setup(false);
- env.Start();
- LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== restarting 2");
- actor = new TTestActorSeq(env.KeeperId, state, 1, &event);
- env.ActorSystem->Register(actor);
- event.WaitI();
- env.Stop();
- }
- }
-*/
-}
+ for (ui32 counter = 20; counter < 1000; ++counter) {
+ TTestActorSeq::TTestActorState state;
+ TTestActorSeq *actor;
+ TTestEnv env;
+ TManualEvent event;
+
+ env.Setup(true, counter, &event);
+ env.Start();
+ LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== starting Counter# %" PRIu32, counter);
+ actor = new TTestActorSeq(env.KeeperId, state, 1, nullptr);
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+
+ event.Reset();
+
+ env.Setup(false);
+ env.Start();
+ LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== restarting 1");
+ actor = new TTestActorSeq(env.KeeperId, state, 1, &event);
+ env.ActorSystem->Register(actor);
+ usleep(5 * 1000 * 1000);
+ env.Stop();
+
+ event.Reset();
+
+ env.Setup(false);
+ env.Start();
+ LOG_DEBUG(*env.ActorSystem, NActorsServices::TEST, "=== restarting 2");
+ actor = new TTestActorSeq(env.KeeperId, state, 1, &event);
+ env.ActorSystem->Register(actor);
+ event.WaitI();
+ env.Stop();
+ }
+ }
+*/
+}
diff --git a/ydb/core/blobstorage/incrhuge/ut/incrhuge_id_dict_ut.cpp b/ydb/core/blobstorage/incrhuge/ut/incrhuge_id_dict_ut.cpp
index 0d66d7f13a5..ab636ad36d4 100644
--- a/ydb/core/blobstorage/incrhuge/ut/incrhuge_id_dict_ut.cpp
+++ b/ydb/core/blobstorage/incrhuge/ut/incrhuge_id_dict_ut.cpp
@@ -1,39 +1,39 @@
#include <ydb/core/blobstorage/incrhuge/incrhuge_id_dict.h>
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NKikimr::NIncrHuge;
-
+
+using namespace NKikimr::NIncrHuge;
+
Y_UNIT_TEST_SUITE(TIncrHugeBlobIdDict) {
Y_UNIT_TEST(Basic) {
TVector<std::pair<TIncrHugeBlobId, ui8>> values;
- auto callback = [&](TIncrHugeBlobId id, ui8 value) {
- values.emplace_back(id, value);
- };
-
- TIdLookupTable<ui8, ui8, 2> dict;
- UNIT_ASSERT_VALUES_EQUAL(0, dict.GetNumPagesUsed());
- TIncrHugeBlobId id1 = dict.Create(1);
- UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
- TIncrHugeBlobId id2 = dict.Create(1);
- UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
- TIncrHugeBlobId id3 = dict.Create(1);
- UNIT_ASSERT_VALUES_EQUAL(2, dict.GetNumPagesUsed());
- UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id1));
- UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id2));
- UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id3));
- dict.Enumerate(callback);
- std::sort(values.begin(), values.end());
- UNIT_ASSERT_VALUES_EQUAL(values, (decltype(values){{id1, 1}, {id2, 1}, {id3, 1}}));
- values.clear();
- dict.Delete(id1);
- UNIT_ASSERT_VALUES_EQUAL(2, dict.GetNumPagesUsed());
- dict.Enumerate(callback);
- std::sort(values.begin(), values.end());
- UNIT_ASSERT_VALUES_EQUAL(values, (decltype(values){{id2, 1}, {id3, 1}}));
- values.clear();
- dict.Delete(id3);
- UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
- dict.Delete(id2);
- UNIT_ASSERT_VALUES_EQUAL(0, dict.GetNumPagesUsed());
- }
-}
+ auto callback = [&](TIncrHugeBlobId id, ui8 value) {
+ values.emplace_back(id, value);
+ };
+
+ TIdLookupTable<ui8, ui8, 2> dict;
+ UNIT_ASSERT_VALUES_EQUAL(0, dict.GetNumPagesUsed());
+ TIncrHugeBlobId id1 = dict.Create(1);
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
+ TIncrHugeBlobId id2 = dict.Create(1);
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
+ TIncrHugeBlobId id3 = dict.Create(1);
+ UNIT_ASSERT_VALUES_EQUAL(2, dict.GetNumPagesUsed());
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id1));
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id2));
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.Lookup(id3));
+ dict.Enumerate(callback);
+ std::sort(values.begin(), values.end());
+ UNIT_ASSERT_VALUES_EQUAL(values, (decltype(values){{id1, 1}, {id2, 1}, {id3, 1}}));
+ values.clear();
+ dict.Delete(id1);
+ UNIT_ASSERT_VALUES_EQUAL(2, dict.GetNumPagesUsed());
+ dict.Enumerate(callback);
+ std::sort(values.begin(), values.end());
+ UNIT_ASSERT_VALUES_EQUAL(values, (decltype(values){{id2, 1}, {id3, 1}}));
+ values.clear();
+ dict.Delete(id3);
+ UNIT_ASSERT_VALUES_EQUAL(1, dict.GetNumPagesUsed());
+ dict.Delete(id2);
+ UNIT_ASSERT_VALUES_EQUAL(0, dict.GetNumPagesUsed());
+ }
+}
diff --git a/ydb/core/blobstorage/incrhuge/ut/incrhuge_log_merger_ut.cpp b/ydb/core/blobstorage/incrhuge/ut/incrhuge_log_merger_ut.cpp
index 617f7f68a39..380dce01c5a 100644
--- a/ydb/core/blobstorage/incrhuge/ut/incrhuge_log_merger_ut.cpp
+++ b/ydb/core/blobstorage/incrhuge/ut/incrhuge_log_merger_ut.cpp
@@ -1,8 +1,8 @@
#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/blobstorage/incrhuge/incrhuge_keeper_log.h>
-
-using namespace NKikimr;
-using namespace NKikimr::NIncrHuge;
-
+
+using namespace NKikimr;
+using namespace NKikimr::NIncrHuge;
+
Y_UNIT_TEST_SUITE(TIncrHugeLogMerge) {
-}
+}
diff --git a/ydb/core/blobstorage/incrhuge/ut/test_actor_concurrent.h b/ydb/core/blobstorage/incrhuge/ut/test_actor_concurrent.h
index d7f370706fe..c0feeab6826 100644
--- a/ydb/core/blobstorage/incrhuge/ut/test_actor_concurrent.h
+++ b/ydb/core/blobstorage/incrhuge/ut/test_actor_concurrent.h
@@ -1,419 +1,419 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/digest/md5/md5.h>
-
-class TTestActorConcurrent : public TActorBootstrapped<TTestActorConcurrent> {
-public:
- struct TBlobInfo {
- unsigned char DataDigest[16];
- ui64 Lsn;
- TLogoBlobID LogoBlobId;
- };
-
- struct TWriteInfo {
- ui64 Lsn;
- TLogoBlobID LogoBlobId;
+
+class TTestActorConcurrent : public TActorBootstrapped<TTestActorConcurrent> {
+public:
+ struct TBlobInfo {
+ unsigned char DataDigest[16];
+ ui64 Lsn;
+ TLogoBlobID LogoBlobId;
+ };
+
+ struct TWriteInfo {
+ ui64 Lsn;
+ TLogoBlobID LogoBlobId;
TString Data;
-
- friend bool operator <(const TWriteInfo& left, const TWriteInfo& right) {
- return left.Lsn < right.Lsn || (left.Lsn == right.Lsn && left.LogoBlobId < right.LogoBlobId);
- }
- };
-
- struct TDeleteInfo {
- TIncrHugeBlobId Id;
-
- friend bool operator <(const TDeleteInfo& left, const TDeleteInfo& right) {
- return left.Id < right.Id;
- }
- };
-
- struct TTestActorState {
+
+ friend bool operator <(const TWriteInfo& left, const TWriteInfo& right) {
+ return left.Lsn < right.Lsn || (left.Lsn == right.Lsn && left.LogoBlobId < right.LogoBlobId);
+ }
+ };
+
+ struct TDeleteInfo {
+ TIncrHugeBlobId Id;
+
+ friend bool operator <(const TDeleteInfo& left, const TDeleteInfo& right) {
+ return left.Id < right.Id;
+ }
+ };
+
+ struct TTestActorState {
TMap<TIncrHugeBlobId, TBlobInfo> ConfirmedState;
TMap<std::pair<ui64, TLogoBlobID>, TBlobInfo> InFlightWrites;
TMap<TIncrHugeBlobId, TBlobInfo> InFlightDeletes;
THashMap<ui64, TBlobInfo> InFlightReads;
- ui64 Lsn = 0;
- ui64 BytesWritten = 0;
- TInstant StartTime = Now();
- };
-
- struct TPayload : public TWritePayload {
- ui64 Lsn;
- TLogoBlobID LogoBlobId;
-
- TPayload(ui64 lsn, const TLogoBlobID& logoBlobId)
- : Lsn(lsn)
- , LogoBlobId(logoBlobId)
- {}
- };
-
-private:
- TVDiskID VDiskId;
+ ui64 Lsn = 0;
+ ui64 BytesWritten = 0;
+ TInstant StartTime = Now();
+ };
+
+ struct TPayload : public TWritePayload {
+ ui64 Lsn;
+ TLogoBlobID LogoBlobId;
+
+ TPayload(ui64 lsn, const TLogoBlobID& logoBlobId)
+ : Lsn(lsn)
+ , LogoBlobId(logoBlobId)
+ {}
+ };
+
+private:
+ TVDiskID VDiskId;
TActorId KeeperId;
- TManualEvent *Event;
- ui8 Owner = 1;
- TTestActorState& State;
- const ui32 MinLen = 512 << 10;
- const ui32 MaxLen = 2048 << 10;
- TReallyFastRng32 Rng;
- ui32 ActionsTaken = 0;
- const ui32 NumActions;
- const ui32 Generation;
-
- const ui32 WriteScore;
- const ui32 DeleteScore;
- const ui32 ReadScore;
-
- struct TWriteRequestInfo {
- TBlobInfo BlobInfo;
- };
-
-public:
+ TManualEvent *Event;
+ ui8 Owner = 1;
+ TTestActorState& State;
+ const ui32 MinLen = 512 << 10;
+ const ui32 MaxLen = 2048 << 10;
+ TReallyFastRng32 Rng;
+ ui32 ActionsTaken = 0;
+ const ui32 NumActions;
+ const ui32 Generation;
+
+ const ui32 WriteScore;
+ const ui32 DeleteScore;
+ const ui32 ReadScore;
+
+ struct TWriteRequestInfo {
+ TBlobInfo BlobInfo;
+ };
+
+public:
TTestActorConcurrent(const TActorId& keeperId, TManualEvent *event, TTestActorState& state, ui32 numActions,
- ui32 generation, ui32 writeScore = 10, ui32 deleteScore = 10, ui32 readScore = 5)
- : KeeperId(keeperId)
- , Event(event)
- , State(state)
- , Rng(1)
- , NumActions(numActions)
- , Generation(generation)
- , WriteScore(writeScore)
- , DeleteScore(deleteScore)
- , ReadScore(readScore)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- ctx.Send(KeeperId, new TEvIncrHugeInit(VDiskId, Owner, 0));
-
- Become(&TTestActorConcurrent::StateFunc);
- }
-
- void Handle(TEvIncrHugeInitResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeInitResult *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
+ ui32 generation, ui32 writeScore = 10, ui32 deleteScore = 10, ui32 readScore = 5)
+ : KeeperId(keeperId)
+ , Event(event)
+ , State(state)
+ , Rng(1)
+ , NumActions(numActions)
+ , Generation(generation)
+ , WriteScore(writeScore)
+ , DeleteScore(deleteScore)
+ , ReadScore(readScore)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ ctx.Send(KeeperId, new TEvIncrHugeInit(VDiskId, Owner, 0));
+
+ Become(&TTestActorConcurrent::StateFunc);
+ }
+
+ void Handle(TEvIncrHugeInitResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeInitResult *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
TVector<TEvIncrHugeInitResult::TItem> referenceItems;
- for (const auto& pair : State.ConfirmedState) {
- TBlobMetadata meta;
- memset(&meta, 0, sizeof(meta));
- memcpy(meta.RawU64, pair.second.LogoBlobId.GetRaw(), 3 * sizeof(ui64));
- referenceItems.push_back(TEvIncrHugeInitResult::TItem{
- pair.first,
- pair.second.Lsn,
- meta
- });
- }
- std::sort(referenceItems.begin(), referenceItems.end(), [](const auto& left, const auto& right) {
- return left.Lsn < right.Lsn;
- });
-
- TStringStream str;
- str << "Reference# [";
- bool first = true;
- ui32 index = 0;
- for (const auto& ref : referenceItems) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- if (++index == 100) {
- str << "...";
- break;
- }
- str << Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 "}", ref.Id, ref.Lsn);
- }
- str << "] Enumerated# [";
- first = true;
- index = 0;
- for (const auto& item : msg->Items) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- if (++index == 100) {
- str << "...";
- break;
- }
- str << Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 "}", item.Id, item.Lsn);
- }
- str << "] InFlightDeletes# [";
- first = true;
- for (const auto& item : State.InFlightDeletes) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- str << Sprintf("%016" PRIx64, item.first);
- }
- str << "]";
+ for (const auto& pair : State.ConfirmedState) {
+ TBlobMetadata meta;
+ memset(&meta, 0, sizeof(meta));
+ memcpy(meta.RawU64, pair.second.LogoBlobId.GetRaw(), 3 * sizeof(ui64));
+ referenceItems.push_back(TEvIncrHugeInitResult::TItem{
+ pair.first,
+ pair.second.Lsn,
+ meta
+ });
+ }
+ std::sort(referenceItems.begin(), referenceItems.end(), [](const auto& left, const auto& right) {
+ return left.Lsn < right.Lsn;
+ });
+
+ TStringStream str;
+ str << "Reference# [";
+ bool first = true;
+ ui32 index = 0;
+ for (const auto& ref : referenceItems) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ if (++index == 100) {
+ str << "...";
+ break;
+ }
+ str << Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 "}", ref.Id, ref.Lsn);
+ }
+ str << "] Enumerated# [";
+ first = true;
+ index = 0;
+ for (const auto& item : msg->Items) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ if (++index == 100) {
+ str << "...";
+ break;
+ }
+ str << Sprintf("{Id# %016" PRIx64 " Lsn# %" PRIu64 "}", item.Id, item.Lsn);
+ }
+ str << "] InFlightDeletes# [";
+ first = true;
+ for (const auto& item : State.InFlightDeletes) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ str << Sprintf("%016" PRIx64, item.first);
+ }
+ str << "]";
LOG_DEBUG(ctx, NActorsServices::TEST, "finished Init %s", str.Str().data());
-
- auto refIt = referenceItems.begin();
- auto it = msg->Items.begin();
- while (refIt != referenceItems.end() || it != msg->Items.end()) {
- bool refEnd = refIt == referenceItems.end();
- bool itemsEnd = it == msg->Items.end();
-
- if ((!refEnd && !itemsEnd && refIt->Lsn < it->Lsn) || itemsEnd) {
- Y_FAIL("lost blob");
- } else if ((!refEnd && !itemsEnd && it->Lsn < refIt->Lsn) || refEnd) {
- // no matching reference item for returned one -- possibly write succeeded or delete hasn't completed yet
- auto& item = *it++;
-
- auto it = State.InFlightWrites.find(std::make_pair(item.Lsn, TLogoBlobID(item.Meta.RawU64)));
- if (it != State.InFlightWrites.end()) {
- State.ConfirmedState.emplace(item.Id, std::move(it->second));
- State.InFlightWrites.erase(it);
- } else {
- auto it = State.InFlightDeletes.find(item.Id);
- if (it != State.InFlightDeletes.end()) {
- // restore deleted blob
- State.ConfirmedState.emplace(it->first, std::move(it->second));
- } else {
- Y_FAIL("extra blob Lsn# %" PRIu64 " Id# %016" PRIx64, item.Lsn, item.Id);
- }
- }
- } else {
- // advance both iterators, it's okay
- Y_VERIFY(TLogoBlobID(refIt->Meta.RawU64) == TLogoBlobID(it->Meta.RawU64) &&
- refIt->Id == it->Id && refIt->Lsn == it->Lsn);
- ++refIt;
- ++it;
- }
- }
-
- State.InFlightWrites.clear();
- State.InFlightReads.clear();
- State.InFlightDeletes.clear();
-
- DoSomething(ctx);
- }
-
- ui32 GetNumRequestsInFlight() const {
- return State.InFlightWrites.size() + State.InFlightReads.size() + State.InFlightDeletes.size();
- }
-
- void DoSomething(const TActorContext& ctx) {
- ui32 writeScore = WriteScore;
- ui32 readScore = State.ConfirmedState.empty() ? 0 : ReadScore;
- ui32 deleteScore = State.ConfirmedState.empty() ? 0 : DeleteScore;
-
- ++ActionsTaken;
- const bool timeToDie = ActionsTaken >= NumActions;
- ui32 numRequests = timeToDie ? 50 : 8;
-
- LOG_DEBUG(ctx, NActorsServices::TEST, "ActionsTaken# %" PRIu32, ActionsTaken);
-
- while (GetNumRequestsInFlight() < numRequests) {
- LOG_DEBUG(ctx, NActorsServices::TEST, "GetNumRequestsInFlight# %" PRIu32 " InFlightWritesSize# %zu",
- GetNumRequestsInFlight(), State.InFlightWrites.size());
-
- // do not allow more than 2 reads at once or when its time to die
- if (State.InFlightReads.size() >= 2 || timeToDie) {
- readScore = 0;
- }
-
- bool exit = false;
- for (;;) {
- ui32 total = writeScore + readScore + deleteScore;
- if (!total) {
- exit = true;
- break;
- }
- ui32 option = Rng() % total;
- if (option < writeScore) {
- SendWriteRequest(ctx);
- break;
- } else {
- option -= writeScore;
- }
- if (option < readScore) {
- if (!SendReadRequest(ctx)) {
- readScore = 0;
- continue;
- } else {
- break;
- }
- } else {
- option -= readScore;
- }
- if (option < deleteScore) {
- if (!SendDeleteRequest(ctx)) {
- deleteScore = 0;
- continue;
- } else {
- break;
- }
- } else {
- option -= deleteScore;
- }
- Y_FAIL("this point should be unreachable");
- }
- if (exit) {
- break;
- }
- }
-
- if (timeToDie) {
- Event->Signal();
- Die(ctx);
- }
- }
-
- void SendWriteRequest(const TActorContext& ctx) {
- ui32 len = MinLen + Rng() % (MaxLen - MinLen + 1);
-
- char *temp = (char *)alloca(len);
- ui32 pos;
- const ui32 pattern = Rng();
- for (pos = 0; pos + 4 <= len; pos += 4) {
- *(ui32 *)(temp + pos) = pattern;
- }
- for (; pos < len; ++pos) {
- temp[pos] = Rng();
- }
-
+
+ auto refIt = referenceItems.begin();
+ auto it = msg->Items.begin();
+ while (refIt != referenceItems.end() || it != msg->Items.end()) {
+ bool refEnd = refIt == referenceItems.end();
+ bool itemsEnd = it == msg->Items.end();
+
+ if ((!refEnd && !itemsEnd && refIt->Lsn < it->Lsn) || itemsEnd) {
+ Y_FAIL("lost blob");
+ } else if ((!refEnd && !itemsEnd && it->Lsn < refIt->Lsn) || refEnd) {
+ // no matching reference item for returned one -- possibly write succeeded or delete hasn't completed yet
+ auto& item = *it++;
+
+ auto it = State.InFlightWrites.find(std::make_pair(item.Lsn, TLogoBlobID(item.Meta.RawU64)));
+ if (it != State.InFlightWrites.end()) {
+ State.ConfirmedState.emplace(item.Id, std::move(it->second));
+ State.InFlightWrites.erase(it);
+ } else {
+ auto it = State.InFlightDeletes.find(item.Id);
+ if (it != State.InFlightDeletes.end()) {
+ // restore deleted blob
+ State.ConfirmedState.emplace(it->first, std::move(it->second));
+ } else {
+ Y_FAIL("extra blob Lsn# %" PRIu64 " Id# %016" PRIx64, item.Lsn, item.Id);
+ }
+ }
+ } else {
+ // advance both iterators, it's okay
+ Y_VERIFY(TLogoBlobID(refIt->Meta.RawU64) == TLogoBlobID(it->Meta.RawU64) &&
+ refIt->Id == it->Id && refIt->Lsn == it->Lsn);
+ ++refIt;
+ ++it;
+ }
+ }
+
+ State.InFlightWrites.clear();
+ State.InFlightReads.clear();
+ State.InFlightDeletes.clear();
+
+ DoSomething(ctx);
+ }
+
+ ui32 GetNumRequestsInFlight() const {
+ return State.InFlightWrites.size() + State.InFlightReads.size() + State.InFlightDeletes.size();
+ }
+
+ void DoSomething(const TActorContext& ctx) {
+ ui32 writeScore = WriteScore;
+ ui32 readScore = State.ConfirmedState.empty() ? 0 : ReadScore;
+ ui32 deleteScore = State.ConfirmedState.empty() ? 0 : DeleteScore;
+
+ ++ActionsTaken;
+ const bool timeToDie = ActionsTaken >= NumActions;
+ ui32 numRequests = timeToDie ? 50 : 8;
+
+ LOG_DEBUG(ctx, NActorsServices::TEST, "ActionsTaken# %" PRIu32, ActionsTaken);
+
+ while (GetNumRequestsInFlight() < numRequests) {
+ LOG_DEBUG(ctx, NActorsServices::TEST, "GetNumRequestsInFlight# %" PRIu32 " InFlightWritesSize# %zu",
+ GetNumRequestsInFlight(), State.InFlightWrites.size());
+
+ // do not allow more than 2 reads at once or when its time to die
+ if (State.InFlightReads.size() >= 2 || timeToDie) {
+ readScore = 0;
+ }
+
+ bool exit = false;
+ for (;;) {
+ ui32 total = writeScore + readScore + deleteScore;
+ if (!total) {
+ exit = true;
+ break;
+ }
+ ui32 option = Rng() % total;
+ if (option < writeScore) {
+ SendWriteRequest(ctx);
+ break;
+ } else {
+ option -= writeScore;
+ }
+ if (option < readScore) {
+ if (!SendReadRequest(ctx)) {
+ readScore = 0;
+ continue;
+ } else {
+ break;
+ }
+ } else {
+ option -= readScore;
+ }
+ if (option < deleteScore) {
+ if (!SendDeleteRequest(ctx)) {
+ deleteScore = 0;
+ continue;
+ } else {
+ break;
+ }
+ } else {
+ option -= deleteScore;
+ }
+ Y_FAIL("this point should be unreachable");
+ }
+ if (exit) {
+ break;
+ }
+ }
+
+ if (timeToDie) {
+ Event->Signal();
+ Die(ctx);
+ }
+ }
+
+ void SendWriteRequest(const TActorContext& ctx) {
+ ui32 len = MinLen + Rng() % (MaxLen - MinLen + 1);
+
+ char *temp = (char *)alloca(len);
+ ui32 pos;
+ const ui32 pattern = Rng();
+ for (pos = 0; pos + 4 <= len; pos += 4) {
+ *(ui32 *)(temp + pos) = pattern;
+ }
+ for (; pos < len; ++pos) {
+ temp[pos] = Rng();
+ }
+
TString data(temp, len);
-
- // allocate LSN for new record
- ui64 lsn = State.Lsn++;
-
- // create LogoBlobId for new record
- TLogoBlobID logoBlobId(1, Generation, 1, 0, lsn, len);
- TBlobMetadata meta;
- memset(&meta, 0, sizeof(meta));
- memcpy(meta.RawU64, logoBlobId.GetRaw(), 3 * sizeof(ui64));
-
- // send request
- ctx.Send(KeeperId, new TEvIncrHugeWrite(Owner, lsn, meta, TString(data), std::make_unique<TPayload>(lsn, logoBlobId)));
-
- LOG_DEBUG(ctx, NActorsServices::TEST, "sent Write LogoBlobId# %s Lsn# %" PRIu64 " NumReq# %" PRIu32,
+
+ // allocate LSN for new record
+ ui64 lsn = State.Lsn++;
+
+ // create LogoBlobId for new record
+ TLogoBlobID logoBlobId(1, Generation, 1, 0, lsn, len);
+ TBlobMetadata meta;
+ memset(&meta, 0, sizeof(meta));
+ memcpy(meta.RawU64, logoBlobId.GetRaw(), 3 * sizeof(ui64));
+
+ // send request
+ ctx.Send(KeeperId, new TEvIncrHugeWrite(Owner, lsn, meta, TString(data), std::make_unique<TPayload>(lsn, logoBlobId)));
+
+ LOG_DEBUG(ctx, NActorsServices::TEST, "sent Write LogoBlobId# %s Lsn# %" PRIu64 " NumReq# %" PRIu32,
logoBlobId.ToString().data(), lsn, GetNumRequestsInFlight());
-
- // register in-flight write
- TBlobInfo blobInfo{{}, lsn, logoBlobId};
+
+ // register in-flight write
+ TBlobInfo blobInfo{{}, lsn, logoBlobId};
MD5().Update(data.data(), data.size()).Final(blobInfo.DataDigest);
- State.InFlightWrites.emplace(std::make_pair(lsn, logoBlobId), std::move(blobInfo));
- }
-
- void Handle(TEvIncrHugeWriteResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeWriteResult *msg = ev->Get();
- TPayload *payload = static_cast<TPayload *>(msg->Payload.get());
-
- LOG_DEBUG(ctx, NActorsServices::TEST, "finished Write Id# %016" PRIx64 " LogoBlobId# %s Lsn# %" PRIu64,
+ State.InFlightWrites.emplace(std::make_pair(lsn, logoBlobId), std::move(blobInfo));
+ }
+
+ void Handle(TEvIncrHugeWriteResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeWriteResult *msg = ev->Get();
+ TPayload *payload = static_cast<TPayload *>(msg->Payload.get());
+
+ LOG_DEBUG(ctx, NActorsServices::TEST, "finished Write Id# %016" PRIx64 " LogoBlobId# %s Lsn# %" PRIu64,
msg->Id, payload->LogoBlobId.ToString().data(), payload->Lsn);
-
+
Y_VERIFY(msg->Status == NKikimrProto::OK, "Status# %s", NKikimrProto::EReplyStatus_Name(msg->Status).data());
-
- // find matching in-flight request
- auto it = State.InFlightWrites.find(std::make_pair(payload->Lsn, payload->LogoBlobId));
- Y_VERIFY(it != State.InFlightWrites.end());
-
- State.BytesWritten += it->second.LogoBlobId.BlobSize();
- TDuration delta = Now() - State.StartTime;
- double speed = State.BytesWritten * 1000 * 1000 / delta.GetValue() / 1048576.0;
- LOG_INFO(ctx, NActorsServices::TEST, "BytesWritten# %" PRIu64 " MB ElapsedTime# %s Speed# %.2lf MB/s",
+
+ // find matching in-flight request
+ auto it = State.InFlightWrites.find(std::make_pair(payload->Lsn, payload->LogoBlobId));
+ Y_VERIFY(it != State.InFlightWrites.end());
+
+ State.BytesWritten += it->second.LogoBlobId.BlobSize();
+ TDuration delta = Now() - State.StartTime;
+ double speed = State.BytesWritten * 1000 * 1000 / delta.GetValue() / 1048576.0;
+ LOG_INFO(ctx, NActorsServices::TEST, "BytesWritten# %" PRIu64 " MB ElapsedTime# %s Speed# %.2lf MB/s",
(State.BytesWritten + 512 * 1024) / 1048576, delta.ToString().data(), speed);
-
- // insert new entry into confirmed state
- Y_VERIFY(!State.ConfirmedState.count(msg->Id));
- State.ConfirmedState.emplace(msg->Id, std::move(it->second));
-
- // delete in-flight request
- State.InFlightWrites.erase(it);
-
- DoSomething(ctx);
- }
-
- bool SendReadRequest(const TActorContext& ctx) {
- if (!State.ConfirmedState) {
- return false;
- }
-
- // choose random item to read
- auto it = State.ConfirmedState.begin();
- std::advance(it, Rng() % State.ConfirmedState.size());
-
- // send request
- ctx.Send(KeeperId, new TEvIncrHugeRead(Owner, it->first, 0, 0), 0, State.Lsn);
-
- // store request info
- State.InFlightReads.emplace(State.Lsn, it->second);
-
- LOG_DEBUG(ctx, NActorsServices::TEST, "sent Read Id# %016" PRIx64 " Lsn# %" PRIu64, it->first, State.Lsn);
- ++State.Lsn;
-
- return true;
- }
-
- void Handle(TEvIncrHugeReadResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeReadResult *msg = ev->Get();
- ui64 lsn = ev->Cookie;
- LOG_DEBUG(ctx, NActorsServices::TEST, "finished Read Status# %s Lsn# %" PRIu64,
+
+ // insert new entry into confirmed state
+ Y_VERIFY(!State.ConfirmedState.count(msg->Id));
+ State.ConfirmedState.emplace(msg->Id, std::move(it->second));
+
+ // delete in-flight request
+ State.InFlightWrites.erase(it);
+
+ DoSomething(ctx);
+ }
+
+ bool SendReadRequest(const TActorContext& ctx) {
+ if (!State.ConfirmedState) {
+ return false;
+ }
+
+ // choose random item to read
+ auto it = State.ConfirmedState.begin();
+ std::advance(it, Rng() % State.ConfirmedState.size());
+
+ // send request
+ ctx.Send(KeeperId, new TEvIncrHugeRead(Owner, it->first, 0, 0), 0, State.Lsn);
+
+ // store request info
+ State.InFlightReads.emplace(State.Lsn, it->second);
+
+ LOG_DEBUG(ctx, NActorsServices::TEST, "sent Read Id# %016" PRIx64 " Lsn# %" PRIu64, it->first, State.Lsn);
+ ++State.Lsn;
+
+ return true;
+ }
+
+ void Handle(TEvIncrHugeReadResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeReadResult *msg = ev->Get();
+ ui64 lsn = ev->Cookie;
+ LOG_DEBUG(ctx, NActorsServices::TEST, "finished Read Status# %s Lsn# %" PRIu64,
NKikimrProto::EReplyStatus_Name(msg->Status).data(), lsn);
-
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
- auto it = State.InFlightReads.find(lsn);
- Y_VERIFY(it != State.InFlightReads.end());
- Y_VERIFY(MD5::CalcRaw(msg->Data) == TStringBuf(reinterpret_cast<const char *>(it->second.DataDigest), 16));
- State.InFlightReads.erase(it);
-
- DoSomething(ctx);
- }
-
- bool SendDeleteRequest(const TActorContext& ctx) {
- if (!State.ConfirmedState) {
- return false;
- }
-
- // choose random item to delete
- auto it = State.ConfirmedState.begin();
- std::advance(it, Rng() % State.ConfirmedState.size());
-
- // send request to keeper
- ctx.Send(KeeperId, new TEvIncrHugeDelete(Owner, State.Lsn++, {it->first}), 0, it->first);
- LOG_DEBUG(ctx, NActorsServices::TEST, "sent Delete Id# %016" PRIx64 " NumReq# %" PRIu32, it->first,
- GetNumRequestsInFlight());
-
- // move item from confirmed state into in-flight delete
- Y_VERIFY(it != State.ConfirmedState.end());
- State.InFlightDeletes.emplace(it->first, std::move(it->second));
- State.ConfirmedState.erase(it);
-
- return true;
- }
-
- void Handle(TEvIncrHugeDeleteResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeDeleteResult *msg = ev->Get();
-
- TIncrHugeBlobId id = ev->Cookie;
-
- LOG_DEBUG(ctx, NActorsServices::TEST, "finished Delete Status# %s Id# %016" PRIx64,
+
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
+ auto it = State.InFlightReads.find(lsn);
+ Y_VERIFY(it != State.InFlightReads.end());
+ Y_VERIFY(MD5::CalcRaw(msg->Data) == TStringBuf(reinterpret_cast<const char *>(it->second.DataDigest), 16));
+ State.InFlightReads.erase(it);
+
+ DoSomething(ctx);
+ }
+
+ bool SendDeleteRequest(const TActorContext& ctx) {
+ if (!State.ConfirmedState) {
+ return false;
+ }
+
+ // choose random item to delete
+ auto it = State.ConfirmedState.begin();
+ std::advance(it, Rng() % State.ConfirmedState.size());
+
+ // send request to keeper
+ ctx.Send(KeeperId, new TEvIncrHugeDelete(Owner, State.Lsn++, {it->first}), 0, it->first);
+ LOG_DEBUG(ctx, NActorsServices::TEST, "sent Delete Id# %016" PRIx64 " NumReq# %" PRIu32, it->first,
+ GetNumRequestsInFlight());
+
+ // move item from confirmed state into in-flight delete
+ Y_VERIFY(it != State.ConfirmedState.end());
+ State.InFlightDeletes.emplace(it->first, std::move(it->second));
+ State.ConfirmedState.erase(it);
+
+ return true;
+ }
+
+ void Handle(TEvIncrHugeDeleteResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeDeleteResult *msg = ev->Get();
+
+ TIncrHugeBlobId id = ev->Cookie;
+
+ LOG_DEBUG(ctx, NActorsServices::TEST, "finished Delete Status# %s Id# %016" PRIx64,
NKikimrProto::EReplyStatus_Name(msg->Status).data(), id);
-
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
- // remove item from delete in-flight map
- auto deleteIt = State.InFlightDeletes.find(id);
- Y_VERIFY(deleteIt != State.InFlightDeletes.end());
- State.InFlightDeletes.erase(deleteIt);
-
- DoSomething(ctx);
- }
-
- STFUNC(StateFunc) {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- HFunc(TEvIncrHugeInitResult, Handle);
- HFunc(TEvIncrHugeWriteResult, Handle);
- HFunc(TEvIncrHugeReadResult, Handle);
- HFunc(TEvIncrHugeDeleteResult, Handle);
- default:
- Y_FAIL("unexpected message 0x%08" PRIx32, type);
- }
- }
-};
+
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
+ // remove item from delete in-flight map
+ auto deleteIt = State.InFlightDeletes.find(id);
+ Y_VERIFY(deleteIt != State.InFlightDeletes.end());
+ State.InFlightDeletes.erase(deleteIt);
+
+ DoSomething(ctx);
+ }
+
+ STFUNC(StateFunc) {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ HFunc(TEvIncrHugeInitResult, Handle);
+ HFunc(TEvIncrHugeWriteResult, Handle);
+ HFunc(TEvIncrHugeReadResult, Handle);
+ HFunc(TEvIncrHugeDeleteResult, Handle);
+ default:
+ Y_FAIL("unexpected message 0x%08" PRIx32, type);
+ }
+ }
+};
diff --git a/ydb/core/blobstorage/incrhuge/ut/test_actor_seq.h b/ydb/core/blobstorage/incrhuge/ut/test_actor_seq.h
index 9bf87cbd1b7..46d33bf1fb1 100644
--- a/ydb/core/blobstorage/incrhuge/ut/test_actor_seq.h
+++ b/ydb/core/blobstorage/incrhuge/ut/test_actor_seq.h
@@ -1,216 +1,216 @@
-#pragma once
-
-class TTestActorSeq : public TActorBootstrapped<TTestActorSeq> {
-public:
- struct TBlobInfo {
- TLogoBlobID LogoBlobId;
- ui64 Lsn;
+#pragma once
+
+class TTestActorSeq : public TActorBootstrapped<TTestActorSeq> {
+public:
+ struct TBlobInfo {
+ TLogoBlobID LogoBlobId;
+ ui64 Lsn;
TString Data;
- TIncrHugeBlobId Id;
- };
-
- struct TTestActorState {
- // a set of blobs that were written and confirmed
+ TIncrHugeBlobId Id;
+ };
+
+ struct TTestActorState {
+ // a set of blobs that were written and confirmed
TMap<ui64, TBlobInfo> ConfirmedState;
- TMaybe<TIncrHugeBlobId> DeleteRequest;
- TMaybe<TBlobInfo> WriteRequest;
- ui64 Lsn = 0;
- };
-
- struct TPayload : public TWritePayload {
- ui64 Lsn;
- TLogoBlobID LogoBlobId;
-
- TPayload(ui64 lsn, const TLogoBlobID& logoBlobId)
- : Lsn(lsn)
- , LogoBlobId(logoBlobId)
- {}
- };
-
-private:
+ TMaybe<TIncrHugeBlobId> DeleteRequest;
+ TMaybe<TBlobInfo> WriteRequest;
+ ui64 Lsn = 0;
+ };
+
+ struct TPayload : public TWritePayload {
+ ui64 Lsn;
+ TLogoBlobID LogoBlobId;
+
+ TPayload(ui64 lsn, const TLogoBlobID& logoBlobId)
+ : Lsn(lsn)
+ , LogoBlobId(logoBlobId)
+ {}
+ };
+
+private:
TActorId KeeperId;
- TTestActorState& State;
- ui8 Owner = 1;
- ui32 NumReadsPending = 0;
- TReallyFastRng32 Rng;
- const ui32 MinLen = 512 << 10;
- const ui32 MaxLen = 2048 << 10;
- const ui32 Generation;
- TManualEvent *Event;
-
-public:
+ TTestActorState& State;
+ ui8 Owner = 1;
+ ui32 NumReadsPending = 0;
+ TReallyFastRng32 Rng;
+ const ui32 MinLen = 512 << 10;
+ const ui32 MaxLen = 2048 << 10;
+ const ui32 Generation;
+ TManualEvent *Event;
+
+public:
TTestActorSeq(const TActorId& keeperId, TTestActorState& state, ui32 generation, TManualEvent *event)
- : KeeperId(keeperId)
- , State(state)
- , Rng(42)
- , Generation(generation)
- , Event(event)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- TVDiskID vdiskId(~0, ~0, 'H', 'I', 'K');
- ctx.Send(KeeperId, new TEvIncrHugeInit(vdiskId, Owner, 0));
- Become(&TTestActorSeq::StateFunc);
- }
-
- void Handle(TEvIncrHugeInitResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeInitResult *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
- for (const auto& item : msg->Items) {
- LOG_DEBUG(ctx, NActorsServices::TEST, "Item# {Id# %016" PRIx64 " Lsn# %" PRIu64 " LogoBlobId# %s}",
+ : KeeperId(keeperId)
+ , State(state)
+ , Rng(42)
+ , Generation(generation)
+ , Event(event)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ TVDiskID vdiskId(~0, ~0, 'H', 'I', 'K');
+ ctx.Send(KeeperId, new TEvIncrHugeInit(vdiskId, Owner, 0));
+ Become(&TTestActorSeq::StateFunc);
+ }
+
+ void Handle(TEvIncrHugeInitResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeInitResult *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
+ for (const auto& item : msg->Items) {
+ LOG_DEBUG(ctx, NActorsServices::TEST, "Item# {Id# %016" PRIx64 " Lsn# %" PRIu64 " LogoBlobId# %s}",
item.Id, item.Lsn, TLogoBlobID(item.Meta.RawU64).ToString().data());
- }
-
- auto itemIt = msg->Items.begin();
- auto stateIt = State.ConfirmedState.begin();
- while (itemIt != msg->Items.end() || stateIt != State.ConfirmedState.end()) {
- const bool itemValid = itemIt != msg->Items.end();
- const bool stateValid = stateIt != State.ConfirmedState.end();
- if (!itemValid || stateIt->second.Lsn < itemIt->Lsn) {
- // we have an entry in confirmed state that is not in msg->Items; this happens only if we had delete
- // request in flight that succeeded, but we haven't received reply
- LOG_DEBUG(ctx, NActorsServices::TEST, "deleted Id# %016" PRIx64, stateIt->second.Id);
- Y_VERIFY(State.DeleteRequest);
- Y_VERIFY(*State.DeleteRequest == stateIt->second.Lsn);
- stateIt = State.ConfirmedState.erase(stateIt);
- continue;
- } else if (!stateValid || itemIt->Lsn < stateIt->second.Lsn) {
- // here we have entry in msg->Items that is not in confirmed state -- this happens only if we had
- // in-flight write request, but haven't got reply
- LOG_DEBUG(ctx, NActorsServices::TEST, "added Id# %016" PRIx64, itemIt->Id);
- Y_VERIFY(State.WriteRequest);
- Y_VERIFY(itemIt->Lsn == State.WriteRequest->Lsn);
- Y_VERIFY(TLogoBlobID(itemIt->Meta.RawU64) == State.WriteRequest->LogoBlobId);
- State.WriteRequest->Id = itemIt->Id;
- stateIt = State.ConfirmedState.insert(stateIt, std::make_pair(itemIt->Lsn, *State.WriteRequest));
- }
-
- // LSNs are identical -- compare other values
- Y_VERIFY(itemIt->Lsn == stateIt->second.Lsn);
- Y_VERIFY(itemIt->Id == stateIt->second.Id);
- Y_VERIFY(TLogoBlobID(itemIt->Meta.RawU64) == stateIt->second.LogoBlobId);
-
- // issue read request to verify data
- if (!stateIt->second.Data) {
- ctx.Send(KeeperId, new TEvIncrHugeRead(Owner, stateIt->second.Id, 0, 0), 0, stateIt->first);
- ++NumReadsPending;
- }
-
- // advance
- ++itemIt;
- ++stateIt;
- }
-
- State.DeleteRequest.Clear();
- State.WriteRequest.Clear();
-
- if (!NumReadsPending) {
- DoSomething(ctx);
- }
- }
-
- void Handle(TEvIncrHugeReadResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeReadResult *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- auto it = State.ConfirmedState.find(ev->Cookie);
- Y_VERIFY(it != State.ConfirmedState.end());
- Y_VERIFY(it->second.Data == msg->Data);
- if (!--NumReadsPending) {
- DoSomething(ctx);
- }
- }
-
- void DoSomething(const TActorContext& ctx) {
- if (Event) {
- Event->Signal();
- }
-
- Y_VERIFY(!State.DeleteRequest && !State.WriteRequest);
-
- ui32 deleteScore = State.ConfirmedState ? 3 : 0;
- ui32 writeScore = 5;
- ui32 total = deleteScore + writeScore;
- ui32 option = Rng() % total;
- if (option < deleteScore) {
- size_t num = Rng() % State.ConfirmedState.size();
- auto it = State.ConfirmedState.begin();
- std::advance(it, num);
- State.DeleteRequest = it->second.Lsn;
- ui64 seqNo = State.Lsn++;
- ctx.Send(KeeperId, new TEvIncrHugeDelete(Owner, seqNo, {it->second.Id}), 0, it->first);
- LOG_DEBUG(ctx, NActorsServices::TEST, "sent Delete Id# %016" PRIx64 " SeqNo# %" PRIu64, it->second.Id, seqNo);
- return;
- } else {
- option -= deleteScore;
- }
- if (option < writeScore) {
- ui32 len = Rng() % (MaxLen - MinLen + 1) + MinLen;
+ }
+
+ auto itemIt = msg->Items.begin();
+ auto stateIt = State.ConfirmedState.begin();
+ while (itemIt != msg->Items.end() || stateIt != State.ConfirmedState.end()) {
+ const bool itemValid = itemIt != msg->Items.end();
+ const bool stateValid = stateIt != State.ConfirmedState.end();
+ if (!itemValid || stateIt->second.Lsn < itemIt->Lsn) {
+ // we have an entry in confirmed state that is not in msg->Items; this happens only if we had delete
+ // request in flight that succeeded, but we haven't received reply
+ LOG_DEBUG(ctx, NActorsServices::TEST, "deleted Id# %016" PRIx64, stateIt->second.Id);
+ Y_VERIFY(State.DeleteRequest);
+ Y_VERIFY(*State.DeleteRequest == stateIt->second.Lsn);
+ stateIt = State.ConfirmedState.erase(stateIt);
+ continue;
+ } else if (!stateValid || itemIt->Lsn < stateIt->second.Lsn) {
+ // here we have entry in msg->Items that is not in confirmed state -- this happens only if we had
+ // in-flight write request, but haven't got reply
+ LOG_DEBUG(ctx, NActorsServices::TEST, "added Id# %016" PRIx64, itemIt->Id);
+ Y_VERIFY(State.WriteRequest);
+ Y_VERIFY(itemIt->Lsn == State.WriteRequest->Lsn);
+ Y_VERIFY(TLogoBlobID(itemIt->Meta.RawU64) == State.WriteRequest->LogoBlobId);
+ State.WriteRequest->Id = itemIt->Id;
+ stateIt = State.ConfirmedState.insert(stateIt, std::make_pair(itemIt->Lsn, *State.WriteRequest));
+ }
+
+ // LSNs are identical -- compare other values
+ Y_VERIFY(itemIt->Lsn == stateIt->second.Lsn);
+ Y_VERIFY(itemIt->Id == stateIt->second.Id);
+ Y_VERIFY(TLogoBlobID(itemIt->Meta.RawU64) == stateIt->second.LogoBlobId);
+
+ // issue read request to verify data
+ if (!stateIt->second.Data) {
+ ctx.Send(KeeperId, new TEvIncrHugeRead(Owner, stateIt->second.Id, 0, 0), 0, stateIt->first);
+ ++NumReadsPending;
+ }
+
+ // advance
+ ++itemIt;
+ ++stateIt;
+ }
+
+ State.DeleteRequest.Clear();
+ State.WriteRequest.Clear();
+
+ if (!NumReadsPending) {
+ DoSomething(ctx);
+ }
+ }
+
+ void Handle(TEvIncrHugeReadResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeReadResult *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ auto it = State.ConfirmedState.find(ev->Cookie);
+ Y_VERIFY(it != State.ConfirmedState.end());
+ Y_VERIFY(it->second.Data == msg->Data);
+ if (!--NumReadsPending) {
+ DoSomething(ctx);
+ }
+ }
+
+ void DoSomething(const TActorContext& ctx) {
+ if (Event) {
+ Event->Signal();
+ }
+
+ Y_VERIFY(!State.DeleteRequest && !State.WriteRequest);
+
+ ui32 deleteScore = State.ConfirmedState ? 3 : 0;
+ ui32 writeScore = 5;
+ ui32 total = deleteScore + writeScore;
+ ui32 option = Rng() % total;
+ if (option < deleteScore) {
+ size_t num = Rng() % State.ConfirmedState.size();
+ auto it = State.ConfirmedState.begin();
+ std::advance(it, num);
+ State.DeleteRequest = it->second.Lsn;
+ ui64 seqNo = State.Lsn++;
+ ctx.Send(KeeperId, new TEvIncrHugeDelete(Owner, seqNo, {it->second.Id}), 0, it->first);
+ LOG_DEBUG(ctx, NActorsServices::TEST, "sent Delete Id# %016" PRIx64 " SeqNo# %" PRIu64, it->second.Id, seqNo);
+ return;
+ } else {
+ option -= deleteScore;
+ }
+ if (option < writeScore) {
+ ui32 len = Rng() % (MaxLen - MinLen + 1) + MinLen;
TString data;
- data.resize(len);
- ui32 pattern = Rng();
- ui32 i;
- for (i = 0; i + 4 <= len; i += 4) {
+ data.resize(len);
+ ui32 pattern = Rng();
+ ui32 i;
+ for (i = 0; i + 4 <= len; i += 4) {
*(ui32 *)(data.data() + i) = pattern;
- }
- while (i < len) {
+ }
+ while (i < len) {
*(ui8 *)(data.data() + i) = pattern;
- ++i;
- }
-
- TBlobInfo blob;
- blob.Lsn = State.Lsn++;
- blob.LogoBlobId = TLogoBlobID(12345678910UL, Generation, 1, 0, blob.Lsn, len);
- blob.Data = data;
-
- TBlobMetadata meta;
- memset(&meta, 0, sizeof(meta));
- memcpy(meta.RawU64, blob.LogoBlobId.GetRaw(), 3 * sizeof(ui64));
-
- ctx.Send(KeeperId, new TEvIncrHugeWrite(Owner, blob.Lsn, meta, std::move(data),
- std::make_unique<TPayload>(blob.Lsn, blob.LogoBlobId)));
- State.WriteRequest = blob;
- LOG_DEBUG(ctx, NActorsServices::TEST, "sent Write Lsn# %" PRIu64 " LogoBlobId# %s", blob.Lsn,
+ ++i;
+ }
+
+ TBlobInfo blob;
+ blob.Lsn = State.Lsn++;
+ blob.LogoBlobId = TLogoBlobID(12345678910UL, Generation, 1, 0, blob.Lsn, len);
+ blob.Data = data;
+
+ TBlobMetadata meta;
+ memset(&meta, 0, sizeof(meta));
+ memcpy(meta.RawU64, blob.LogoBlobId.GetRaw(), 3 * sizeof(ui64));
+
+ ctx.Send(KeeperId, new TEvIncrHugeWrite(Owner, blob.Lsn, meta, std::move(data),
+ std::make_unique<TPayload>(blob.Lsn, blob.LogoBlobId)));
+ State.WriteRequest = blob;
+ LOG_DEBUG(ctx, NActorsServices::TEST, "sent Write Lsn# %" PRIu64 " LogoBlobId# %s", blob.Lsn,
blob.LogoBlobId.ToString().data());
- return;
- } else {
- option -= writeScore;
- }
- Y_FAIL();
- }
-
- void Handle(TEvIncrHugeDeleteResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeDeleteResult *msg = ev->Get();
- LOG_DEBUG(ctx, NActorsServices::TEST, "finished Delete Status# %s Id# %016" PRIx64,
+ return;
+ } else {
+ option -= writeScore;
+ }
+ Y_FAIL();
+ }
+
+ void Handle(TEvIncrHugeDeleteResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeDeleteResult *msg = ev->Get();
+ LOG_DEBUG(ctx, NActorsServices::TEST, "finished Delete Status# %s Id# %016" PRIx64,
NKikimrProto::EReplyStatus_Name(msg->Status).data(), ev->Cookie);
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- Y_VERIFY(ev->Cookie == *State.DeleteRequest);
- State.DeleteRequest.Clear();
- State.ConfirmedState.erase(ev->Cookie);
- DoSomething(ctx);
- }
-
- void Handle(TEvIncrHugeWriteResult::TPtr& ev, const TActorContext& ctx) {
- TEvIncrHugeWriteResult *msg = ev->Get();
- TPayload *payload = static_cast<TPayload *>(msg->Payload.get());
- LOG_DEBUG(ctx, NActorsServices::TEST, "finished Write Status# %s Lsn# %" PRIu64 " LogoBlobId# %s Id# %016" PRIx64,
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ Y_VERIFY(ev->Cookie == *State.DeleteRequest);
+ State.DeleteRequest.Clear();
+ State.ConfirmedState.erase(ev->Cookie);
+ DoSomething(ctx);
+ }
+
+ void Handle(TEvIncrHugeWriteResult::TPtr& ev, const TActorContext& ctx) {
+ TEvIncrHugeWriteResult *msg = ev->Get();
+ TPayload *payload = static_cast<TPayload *>(msg->Payload.get());
+ LOG_DEBUG(ctx, NActorsServices::TEST, "finished Write Status# %s Lsn# %" PRIu64 " LogoBlobId# %s Id# %016" PRIx64,
NKikimrProto::EReplyStatus_Name(msg->Status).data(), payload->Lsn, payload->LogoBlobId.ToString().data(), msg->Id);
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- Y_VERIFY(State.WriteRequest);
- State.WriteRequest->Id = msg->Id;
- State.ConfirmedState.emplace(payload->Lsn, *State.WriteRequest);
- State.WriteRequest.Clear();
- DoSomething(ctx);
- }
-
- STFUNC(StateFunc) {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- HFunc(TEvIncrHugeInitResult, Handle);
- HFunc(TEvIncrHugeReadResult, Handle);
- HFunc(TEvIncrHugeDeleteResult, Handle);
- HFunc(TEvIncrHugeWriteResult, Handle);
- default:
- Y_FAIL("unexpected message 0x%08" PRIx32, type);
- }
- }
-};
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ Y_VERIFY(State.WriteRequest);
+ State.WriteRequest->Id = msg->Id;
+ State.ConfirmedState.emplace(payload->Lsn, *State.WriteRequest);
+ State.WriteRequest.Clear();
+ DoSomething(ctx);
+ }
+
+ STFUNC(StateFunc) {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ HFunc(TEvIncrHugeInitResult, Handle);
+ HFunc(TEvIncrHugeReadResult, Handle);
+ HFunc(TEvIncrHugeDeleteResult, Handle);
+ HFunc(TEvIncrHugeWriteResult, Handle);
+ default:
+ Y_FAIL("unexpected message 0x%08" PRIx32, type);
+ }
+ }
+};
diff --git a/ydb/core/blobstorage/incrhuge/ut/ya.make b/ydb/core/blobstorage/incrhuge/ut/ya.make
index 971a739c01a..0d558d16087 100644
--- a/ydb/core/blobstorage/incrhuge/ut/ya.make
+++ b/ydb/core/blobstorage/incrhuge/ut/ya.make
@@ -1,4 +1,4 @@
-UNITTEST()
+UNITTEST()
OWNER(
alexvru
@@ -31,4 +31,4 @@ SRCS(
REQUIREMENTS(ram:9)
-END()
+END()
diff --git a/ydb/core/blobstorage/incrhuge/ya.make b/ydb/core/blobstorage/incrhuge/ya.make
index aae316d055d..f5c69bd84f1 100644
--- a/ydb/core/blobstorage/incrhuge/ya.make
+++ b/ydb/core/blobstorage/incrhuge/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
OWNER(
alexvru
@@ -39,7 +39,7 @@ SRCS(
incrhuge_keeper_write.h
)
-END()
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.cpp b/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.cpp
index 0f6a440f57f..b2093be5a55 100644
--- a/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.cpp
+++ b/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.cpp
@@ -3,7 +3,7 @@
#include <ydb/core/base/blobstorage.h>
LWTRACE_DEFINE_PROVIDER(BLOBSTORAGE_PROVIDER);
-LWTRACE_DEFINE_PROVIDER(FAIL_INJECTION_PROVIDER);
+LWTRACE_DEFINE_PROVIDER(FAIL_INJECTION_PROVIDER);
namespace NKikimr { namespace NPDisk {
diff --git a/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h b/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h
index 7e20a7bd81a..e5d983d97c0 100644
--- a/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h
+++ b/ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h
@@ -263,11 +263,11 @@ struct TEventTypeField {
PROBE(VDiskStartProcessing, GROUPS("DSProxy"), TYPES(), NAMES()) \
PROBE(VDiskReply, GROUPS("DSProxy"), TYPES(), NAMES()) \
/**/
-LWTRACE_DECLARE_PROVIDER(BLOBSTORAGE_PROVIDER)
+LWTRACE_DECLARE_PROVIDER(BLOBSTORAGE_PROVIDER)
-#define FAIL_INJECTION_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
+#define FAIL_INJECTION_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
PROBE(PDiskFailInjection, GROUPS("PDisk"), TYPES(ui64), NAMES("cookie")) \
-/**/
-LWTRACE_DECLARE_PROVIDER(FAIL_INJECTION_PROVIDER)
-
+/**/
+LWTRACE_DECLARE_PROVIDER(FAIL_INJECTION_PROVIDER)
+
#define PDISK_FAIL_INJECTION(COOKIE) GLOBAL_LWPROBE(FAIL_INJECTION_PROVIDER, PDiskFailInjection, COOKIE)
diff --git a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
index e3c74cce7b4..298cb1dc365 100644
--- a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
+++ b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp
@@ -63,7 +63,7 @@ static bool IsVerbose = true;
static yexception LastException;
-constexpr ui32 DOMAIN_ID = 1;
+constexpr ui32 DOMAIN_ID = 1;
using namespace NActors;
@@ -207,8 +207,8 @@ void SetupServices(TTestActorRuntime &runtime, TString extraPath, TIntrusivePtr<
if (nodeIndex == 0) {
nodeWardenConfig->SectorMaps[extraPath] = extraSectorMap;
- ObtainTenantKey(&nodeWardenConfig->TenantKey, app.Keys[0]);
- ObtainStaticKey(&nodeWardenConfig->StaticKey);
+ ObtainTenantKey(&nodeWardenConfig->TenantKey, app.Keys[0]);
+ ObtainStaticKey(&nodeWardenConfig->StaticKey);
TString baseDir = runtime.GetTempDir();
@@ -282,22 +282,22 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
return bsController;
}
- ui32 CreatePDisk(TTestActorRuntime &runtime, ui32 nodeIdx, TString path, ui64 guid, ui32 pdiskId, ui64 pDiskCategory) {
- VERBOSE_COUT(" Creating pdisk");
-
+ ui32 CreatePDisk(TTestActorRuntime &runtime, ui32 nodeIdx, TString path, ui64 guid, ui32 pdiskId, ui64 pDiskCategory) {
+ VERBOSE_COUT(" Creating pdisk");
+
ui32 nodeId = runtime.GetNodeId(nodeIdx);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
- auto& record = ev->Record;
- auto *pdisk = record.MutableServiceSet()->AddPDisks();
- pdisk->SetNodeID(nodeId);
- pdisk->SetPDiskID(pdiskId);
- pdisk->SetPath(path);
- pdisk->SetPDiskGuid(guid);
- pdisk->SetPDiskCategory(pDiskCategory);
- pdisk->SetEntityStatus(NKikimrBlobStorage::CREATE);
- runtime.Send(new IEventHandle(MakeBlobStorageNodeWardenID(nodeId), TActorId(), ev.release()));
-
- return pdiskId;
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
+ auto& record = ev->Record;
+ auto *pdisk = record.MutableServiceSet()->AddPDisks();
+ pdisk->SetNodeID(nodeId);
+ pdisk->SetPDiskID(pdiskId);
+ pdisk->SetPath(path);
+ pdisk->SetPDiskGuid(guid);
+ pdisk->SetPDiskCategory(pDiskCategory);
+ pdisk->SetEntityStatus(NKikimrBlobStorage::CREATE);
+ runtime.Send(new IEventHandle(MakeBlobStorageNodeWardenID(nodeId), TActorId(), ev.release()));
+
+ return pdiskId;
}
void Put(TTestActorRuntime &runtime, TActorId &sender, ui32 groupId, TLogoBlobID logoBlobId, TString data, NKikimrProto::EReplyStatus expectAnsver = NKikimrProto::OK) {
@@ -323,7 +323,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
NKikimrBlobStorage::TDefineStoragePool storagePool = runtime.GetAppData().DomainsInfo->GetDomain(domainId).StoragePoolTypes.at(kind);
TActorId edge = runtime.AllocateEdgeActor();
- auto request = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
Y_VERIFY(storagePool.GetKind() == kind);
storagePool.ClearStoragePoolId();
storagePool.SetName(name);
@@ -333,7 +333,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
NTabletPipe::TClientConfig pipeConfig;
pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, request.release(), 0, pipeConfig);
+ runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, request.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetResponse().GetSuccess(), true);
@@ -343,19 +343,19 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
auto stateStorage = runtime.GetAppData().DomainsInfo->GetDefaultStateStorageGroup(domainId);
TActorId edge = runtime.AllocateEdgeActor();
- auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerSelectGroups>();
- auto *record = &selectGroups->Record;
- record->SetReturnAllMatchingGroups(true);
- auto* groupParams = record->AddGroupParameters();
- groupParams->MutableStoragePoolSpecifier()->SetName(poolName);
+ auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerSelectGroups>();
+ auto *record = &selectGroups->Record;
+ record->SetReturnAllMatchingGroups(true);
+ auto* groupParams = record->AddGroupParameters();
+ groupParams->MutableStoragePoolSpecifier()->SetName(poolName);
NTabletPipe::TClientConfig pipeConfig;
pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
+ runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
- auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerSelectGroupsResult>(edge);
- UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), NKikimrProto::OK);
- return reply->Get()->Record.GetMatchingGroups(0).GetGroups(0).GetGroupID();
+ auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerSelectGroupsResult>(edge);
+ UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetStatus(), NKikimrProto::OK);
+ return reply->Get()->Record.GetMatchingGroups(0).GetGroups(0).GetGroupID();
}
void SendToBsProxy(TTestBasicRuntime& runtime, TActorId sender, ui32 groupId, IEventBase *ev, ui64 cookie = 0) {
@@ -372,7 +372,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
auto stateStorage = runtime.GetAppData().DomainsInfo->GetDefaultStateStorageGroup(domainId);
TActorId edge = runtime.AllocateEdgeActor();
- auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
auto* request = selectGroups->Record.MutableRequest();
auto* readPool = request->AddCommand()->MutableReadStoragePool();
readPool->SetBoxId(1);
@@ -380,7 +380,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
NTabletPipe::TClientConfig pipeConfig;
pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
+ runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetResponse().GetSuccess(), true);
@@ -390,7 +390,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
void RemoveStoragePool(TTestBasicRuntime& runtime, ui32 domainId, const NKikimrBlobStorage::TDefineStoragePool& storagePool) {
auto stateStorage = runtime.GetAppData().DomainsInfo->GetDefaultStateStorageGroup(domainId);
TActorId edge = runtime.AllocateEdgeActor();
- auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto selectGroups = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
auto* request = selectGroups->Record.MutableRequest();
auto* deletePool = request->AddCommand()->MutableDeleteStoragePool();
deletePool->SetBoxId(1);
@@ -399,7 +399,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
NTabletPipe::TClientConfig pipeConfig;
pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
+ runtime.SendToPipe(MakeBSControllerID(stateStorage), edge, selectGroups.release(), 0, pipeConfig);
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(edge);
UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Record.GetResponse().GetSuccess(), true);
@@ -430,21 +430,21 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
void BlockGroup(TTestBasicRuntime& runtime, TActorId sender, ui64 tabletId, ui32 groupId, ui32 generation, bool isMonitored,
NKikimrProto::EReplyStatus expectAnsver = NKikimrProto::EReplyStatus::OK) {
- auto request = std::make_unique<TEvBlobStorage::TEvBlock>(tabletId, generation, TInstant::Max());
+ auto request = std::make_unique<TEvBlobStorage::TEvBlock>(tabletId, generation, TInstant::Max());
request->IsMonitored = isMonitored;
- SendToBsProxy(runtime, sender, groupId, request.release());
+ SendToBsProxy(runtime, sender, groupId, request.release());
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvBlockResult>(sender);
UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Status, expectAnsver);
}
void CollectGroup(TTestBasicRuntime& runtime, TActorId sender, ui64 tabletId, ui32 groupId, bool isMonitored,
NKikimrProto::EReplyStatus expectAnsver = NKikimrProto::EReplyStatus::OK) {
- auto request = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(tabletId, Max<ui32>(), Max<ui32>(), ui32(0),
+ auto request = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(tabletId, Max<ui32>(), Max<ui32>(), ui32(0),
true, Max<ui32>(), Max<ui32>(),
nullptr, nullptr, TInstant::Max(),
true, true);
request->IsMonitored = isMonitored;
- SendToBsProxy(runtime, sender, groupId, request.release());
+ SendToBsProxy(runtime, sender, groupId, request.release());
auto reply = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvCollectGarbageResult>(sender);
UNIT_ASSERT_VALUES_EQUAL(reply->Get()->Status, expectAnsver);
}
@@ -652,12 +652,12 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
VERBOSE_COUT(" Formatting pdisk");
FormatPDiskRandomKeys(tempDir() + "/new_pdisk.dat", sectorMap->DeviceSize, 32 << 20, 1, false, sectorMap);
- VERBOSE_COUT(" Creating PDisk");
+ VERBOSE_COUT(" Creating PDisk");
ui64 guid = 1;
ui64 pDiskCategory = 0;
EntropyPool().Read(&guid, sizeof(guid));
// TODO: look why doesn't sernder 1 work
- ui32 pDiskId = CreatePDisk(runtime, 0, tempDir() + "/new_pdisk.dat", guid, 1001, pDiskCategory);
+ ui32 pDiskId = CreatePDisk(runtime, 0, tempDir() + "/new_pdisk.dat", guid, 1001, pDiskCategory);
VERBOSE_COUT(" Verify that PDisk returns ERROR");
@@ -668,15 +668,15 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
}
ui32 nodeId = runtime.GetNodeId(0);
TActorId pDiskActorId = MakeBlobStoragePDiskID(nodeId, pDiskId);
- for (;;) {
- runtime.Send(new IEventHandle(pDiskActorId, sender0, new NPDisk::TEvYardInit(1, vDiskId, guid)), 0);
- TAutoPtr<IEventHandle> handle;
- if (auto initResult = runtime.GrabEdgeEventRethrow<NPDisk::TEvYardInitResult>(handle, TDuration::Seconds(1))) {
- UNIT_ASSERT(initResult);
+ for (;;) {
+ runtime.Send(new IEventHandle(pDiskActorId, sender0, new NPDisk::TEvYardInit(1, vDiskId, guid)), 0);
+ TAutoPtr<IEventHandle> handle;
+ if (auto initResult = runtime.GrabEdgeEventRethrow<NPDisk::TEvYardInitResult>(handle, TDuration::Seconds(1))) {
+ UNIT_ASSERT(initResult);
UNIT_ASSERT(initResult->Status == NKikimrProto::CORRUPTED);
- break;
- }
- }
+ break;
+ }
+ }
}
void TestHttpMonForPath(const TString& path) {
diff --git a/ydb/core/blobstorage/nodewarden/defs.h b/ydb/core/blobstorage/nodewarden/defs.h
index a3a658d27f5..c62366eb501 100644
--- a/ydb/core/blobstorage/nodewarden/defs.h
+++ b/ydb/core/blobstorage/nodewarden/defs.h
@@ -1,16 +1,16 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/defs.h>
-
+
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/hfunc.h>
#include <library/cpp/actors/core/mailbox_queue_revolving.h>
#include <library/cpp/actors/core/invoke.h>
-
+
#include <ydb/core/protos/services.pb.h>
#include <ydb/core/protos/config.pb.h>
-
+
#include <ydb/core/blobstorage/nodewarden/group_stat_aggregator.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/tablet_pipe.h>
@@ -32,27 +32,27 @@
#include <ydb/core/util/log_priority_mute_checker.h>
#include <ydb/core/util/stlog.h>
#include <ydb/library/pdisk_io/sector_map.h>
-
+
#include <library/cpp/lwtrace/mon/mon_lwtrace.h>
-
+
#include <google/protobuf/text_format.h>
-
+
#include <library/cpp/digest/crc32c/crc32c.h>
#include <library/cpp/actors/interconnect/interconnect.h>
-
-#include <util/folder/dirut.h>
-#include <util/folder/tempdir.h>
-#include <util/generic/algorithm.h>
-#include <util/generic/queue.h>
-#include <util/generic/set.h>
-#include <util/random/entropy.h>
-#include <util/stream/file.h>
-#include <util/stream/input.h>
-#include <util/string/escape.h>
-#include <util/string/printf.h>
-#include <util/system/backtrace.h>
-#include <util/system/condvar.h>
-#include <util/system/filemap.h>
-#include <util/system/file.h>
-#include <util/system/mutex.h>
-#include <util/system/thread.h>
+
+#include <util/folder/dirut.h>
+#include <util/folder/tempdir.h>
+#include <util/generic/algorithm.h>
+#include <util/generic/queue.h>
+#include <util/generic/set.h>
+#include <util/random/entropy.h>
+#include <util/stream/file.h>
+#include <util/stream/input.h>
+#include <util/string/escape.h>
+#include <util/string/printf.h>
+#include <util/system/backtrace.h>
+#include <util/system/condvar.h>
+#include <util/system/filemap.h>
+#include <util/system/file.h>
+#include <util/system/mutex.h>
+#include <util/system/thread.h>
diff --git a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp
index 9f63143b322..b40b788a782 100644
--- a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp
+++ b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.cpp
@@ -1,95 +1,95 @@
-#include "group_stat_aggregator.h"
+#include "group_stat_aggregator.h"
#include <ydb/core/base/group_stat.h>
-
-using namespace NKikimr;
-using namespace NActors;
-
-namespace {
-
- class TGroupStatAggregatorActor : public TActorBootstrapped<TGroupStatAggregatorActor> {
- static constexpr TDuration NodeStatKeepingTime = TDuration::Seconds(20);
-
- struct TNodeStat {
- TInstant Timestamp; // when the last stats was reported
- TGroupStat Stat; // the reported stat
- };
-
- const ui32 GroupId;
+
+using namespace NKikimr;
+using namespace NActors;
+
+namespace {
+
+ class TGroupStatAggregatorActor : public TActorBootstrapped<TGroupStatAggregatorActor> {
+ static constexpr TDuration NodeStatKeepingTime = TDuration::Seconds(20);
+
+ struct TNodeStat {
+ TInstant Timestamp; // when the last stats was reported
+ TGroupStat Stat; // the reported stat
+ };
+
+ const ui32 GroupId;
const TActorId VDiskServiceId;
- const TDuration ReportPeriod;
- TGroupStat Accum;
- THashMap<ui32, TNodeStat> PerNodeStat;
-
- public:
+ const TDuration ReportPeriod;
+ TGroupStat Accum;
+ THashMap<ui32, TNodeStat> PerNodeStat;
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::NODE_WARDEN_STATAGGR_ACTOR;
}
TGroupStatAggregatorActor(ui32 groupId, const TActorId& vdiskServiceId, TDuration reportPeriod = TDuration::Seconds(10))
- : GroupId(groupId)
- , VDiskServiceId(vdiskServiceId)
- , ReportPeriod(reportPeriod)
- {}
-
- void Bootstrap() {
- Become(&TThis::StateFunc, ReportPeriod, new TEvents::TEvWakeup);
- }
-
- void Handle(TEvGroupStatReport::TPtr& ev) {
- TEvGroupStatReport *msg = ev->Get();
- TGroupStat stat;
- if (msg->GetGroupId() == GroupId && msg->GetStat(stat)) {
+ : GroupId(groupId)
+ , VDiskServiceId(vdiskServiceId)
+ , ReportPeriod(reportPeriod)
+ {}
+
+ void Bootstrap() {
+ Become(&TThis::StateFunc, ReportPeriod, new TEvents::TEvWakeup);
+ }
+
+ void Handle(TEvGroupStatReport::TPtr& ev) {
+ TEvGroupStatReport *msg = ev->Get();
+ TGroupStat stat;
+ if (msg->GetGroupId() == GroupId && msg->GetStat(stat)) {
const TActorId& sender = ev->Sender;
- const ui32 nodeId = sender.NodeId();
- auto it = PerNodeStat.find(nodeId);
- if (it != PerNodeStat.end()) {
- TNodeStat& current = it->second;
- Accum.Replace(stat, current.Stat);
- current.Stat = stat;
- current.Timestamp = TActivationContext::Now();
- } else {
- Accum.Add(stat);
- TNodeStat current;
- current.Stat = stat;
- current.Timestamp = TActivationContext::Now();
- PerNodeStat.emplace(nodeId, std::move(current));
- }
- }
- }
-
- void CleanupExpiredPerNodeStat() {
- const TInstant now = TActivationContext::Now();
- for (auto it = PerNodeStat.begin(), next = it; it != PerNodeStat.end(); it = next) {
- next = std::next(it);
- const TNodeStat& stat = it->second;
- const TInstant expirationTimestamp = stat.Timestamp + NodeStatKeepingTime;
- if (now >= expirationTimestamp) {
- Accum.Subtract(stat.Stat);
- PerNodeStat.erase(it);
- }
- }
- }
-
- void HandleWakeup() {
- CleanupExpiredPerNodeStat();
- const TActorId nodeWardenId = MakeBlobStorageNodeWardenID(SelfId().NodeId());
- Send(nodeWardenId, new TEvGroupStatReport(VDiskServiceId, GroupId, Accum));
- Schedule(ReportPeriod, new TEvents::TEvWakeup);
- }
-
- STRICT_STFUNC(StateFunc, {
- hFunc(TEvGroupStatReport, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- cFunc(TEvents::TSystem::Poison, PassAway);
- })
- };
-
-} // anon
-
-namespace NKikimr {
-
+ const ui32 nodeId = sender.NodeId();
+ auto it = PerNodeStat.find(nodeId);
+ if (it != PerNodeStat.end()) {
+ TNodeStat& current = it->second;
+ Accum.Replace(stat, current.Stat);
+ current.Stat = stat;
+ current.Timestamp = TActivationContext::Now();
+ } else {
+ Accum.Add(stat);
+ TNodeStat current;
+ current.Stat = stat;
+ current.Timestamp = TActivationContext::Now();
+ PerNodeStat.emplace(nodeId, std::move(current));
+ }
+ }
+ }
+
+ void CleanupExpiredPerNodeStat() {
+ const TInstant now = TActivationContext::Now();
+ for (auto it = PerNodeStat.begin(), next = it; it != PerNodeStat.end(); it = next) {
+ next = std::next(it);
+ const TNodeStat& stat = it->second;
+ const TInstant expirationTimestamp = stat.Timestamp + NodeStatKeepingTime;
+ if (now >= expirationTimestamp) {
+ Accum.Subtract(stat.Stat);
+ PerNodeStat.erase(it);
+ }
+ }
+ }
+
+ void HandleWakeup() {
+ CleanupExpiredPerNodeStat();
+ const TActorId nodeWardenId = MakeBlobStorageNodeWardenID(SelfId().NodeId());
+ Send(nodeWardenId, new TEvGroupStatReport(VDiskServiceId, GroupId, Accum));
+ Schedule(ReportPeriod, new TEvents::TEvWakeup);
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ hFunc(TEvGroupStatReport, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ })
+ };
+
+} // anon
+
+namespace NKikimr {
+
IActor *CreateGroupStatAggregatorActor(ui32 groupId, const TActorId& vdiskServiceId) {
- return new TGroupStatAggregatorActor(groupId, vdiskServiceId);
- }
-
-} // NKikimr
+ return new TGroupStatAggregatorActor(groupId, vdiskServiceId);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.h b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.h
index 24c1f0a93e7..e224a3c2292 100644
--- a/ydb/core/blobstorage/nodewarden/group_stat_aggregator.h
+++ b/ydb/core/blobstorage/nodewarden/group_stat_aggregator.h
@@ -1,64 +1,64 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/base/group_stat.h>
#include <ydb/core/base/blobstorage.h>
-
+
#include <ydb/core/protos/blobstorage.pb.h>
-
+
#include <library/cpp/actors/core/actor.h>
#include <library/cpp/actors/core/event_local.h>
-
-namespace NKikimr {
-
- struct TEvGroupStatReport : TEventPB<TEvGroupStatReport, NKikimrBlobStorage::TEvGroupStatReport, TEvBlobStorage::EvGroupStatReport> {
- TEvGroupStatReport() = default;
-
+
+namespace NKikimr {
+
+ struct TEvGroupStatReport : TEventPB<TEvGroupStatReport, NKikimrBlobStorage::TEvGroupStatReport, TEvBlobStorage::EvGroupStatReport> {
+ TEvGroupStatReport() = default;
+
TEvGroupStatReport(const TActorId& vdiskServiceId, ui32 groupId, const TGroupStat& stat)
- {
- Record.SetGroupId(groupId);
+ {
+ Record.SetGroupId(groupId);
ActorIdToProto(vdiskServiceId, Record.MutableVDiskServiceId());
- stat.Serialize(&Record);
- }
-
- bool GetStat(TGroupStat& s) const {
- return s.Deserialize(Record);
- }
-
- ui32 GetGroupId() const {
- return Record.GetGroupId();
- }
-
+ stat.Serialize(&Record);
+ }
+
+ bool GetStat(TGroupStat& s) const {
+ return s.Deserialize(Record);
+ }
+
+ ui32 GetGroupId() const {
+ return Record.GetGroupId();
+ }
+
TActorId GetVDiskServiceId() const {
return ActorIdFromProto(Record.GetVDiskServiceId());
- }
- };
-
- inline TActorId MakeGroupStatAggregatorId(ui32 nodeId, ui32 pdiskId, ui32 vdiskSlotId) {
- char x[12] = {'b','s','g','s'};
- x[4] = (char)pdiskId;
- x[5] = (char)(pdiskId >> 8);
- x[6] = (char)(pdiskId >> 16);
- x[7] = (char)(pdiskId >> 24);
- x[8] = (char)vdiskSlotId;
- x[9] = (char)(vdiskSlotId >> 8);
- x[10] = (char)(vdiskSlotId >> 16);
- x[11] = (char)(vdiskSlotId >> 24);
- return TActorId(nodeId, TStringBuf(x, 12));
- }
-
- inline TActorId MakeGroupStatAggregatorId(const TActorId& vdiskServiceId) {
- Y_VERIFY(vdiskServiceId.IsService());
- char x[12];
- TStringBuf serviceId = vdiskServiceId.ServiceId();
- Y_VERIFY(serviceId[0] == 'b' && serviceId[1] == 's' && serviceId[2] == 'v' && serviceId[3] == 'd');
- memcpy(x, serviceId.data(), serviceId.size());
- x[0] = 'b';
- x[1] = 's';
- x[2] = 'g';
- x[3] = 's';
- return TActorId(vdiskServiceId.NodeId(), TStringBuf(x, 12));
- }
-
+ }
+ };
+
+ inline TActorId MakeGroupStatAggregatorId(ui32 nodeId, ui32 pdiskId, ui32 vdiskSlotId) {
+ char x[12] = {'b','s','g','s'};
+ x[4] = (char)pdiskId;
+ x[5] = (char)(pdiskId >> 8);
+ x[6] = (char)(pdiskId >> 16);
+ x[7] = (char)(pdiskId >> 24);
+ x[8] = (char)vdiskSlotId;
+ x[9] = (char)(vdiskSlotId >> 8);
+ x[10] = (char)(vdiskSlotId >> 16);
+ x[11] = (char)(vdiskSlotId >> 24);
+ return TActorId(nodeId, TStringBuf(x, 12));
+ }
+
+ inline TActorId MakeGroupStatAggregatorId(const TActorId& vdiskServiceId) {
+ Y_VERIFY(vdiskServiceId.IsService());
+ char x[12];
+ TStringBuf serviceId = vdiskServiceId.ServiceId();
+ Y_VERIFY(serviceId[0] == 'b' && serviceId[1] == 's' && serviceId[2] == 'v' && serviceId[3] == 'd');
+ memcpy(x, serviceId.data(), serviceId.size());
+ x[0] = 'b';
+ x[1] = 's';
+ x[2] = 'g';
+ x[3] = 's';
+ return TActorId(vdiskServiceId.NodeId(), TStringBuf(x, 12));
+ }
+
NActors::IActor *CreateGroupStatAggregatorActor(ui32 groupId, const TActorId& vdiskServiceId);
-
-} // NKikimr
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/nodewarden/node_warden.h b/ydb/core/blobstorage/nodewarden/node_warden.h
index 4d915508690..8a2dec19067 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden.h
+++ b/ydb/core/blobstorage/nodewarden/node_warden.h
@@ -7,15 +7,15 @@
#include <ydb/core/protos/config.pb.h>
#include <ydb/library/pdisk_io/sector_map.h>
-#include <util/folder/path.h>
+#include <util/folder/path.h>
namespace NKikimr {
- struct ICacheAccessor {
- virtual ~ICacheAccessor() = default;
- virtual TString Read() = 0;
- virtual void Update(std::function<TString(TString)> processor) = 0;
- };
-
+ struct ICacheAccessor {
+ virtual ~ICacheAccessor() = default;
+ virtual TString Read() = 0;
+ virtual void Update(std::function<TString(TString)> processor) = 0;
+ };
+
struct TNodeWardenConfig : public TThrRefBase {
NKikimrBlobStorage::TNodeWardenServiceSet ServiceSet;
TIntrusivePtr<IPDiskServiceFactory> PDiskServiceFactory;
@@ -23,19 +23,19 @@ namespace NKikimr {
TIntrusivePtr<NPDisk::TDriveModelDb> AllDriveModels;
NKikimrBlobStorage::TPDiskConfig PDiskConfigOverlay;
NKikimrConfig::TFeatureFlags FeatureFlags;
- NKikimrBlobStorage::TIncrHugeConfig IncrHugeConfig;
+ NKikimrBlobStorage::TIncrHugeConfig IncrHugeConfig;
THashMap<TString, TIntrusivePtr<NPDisk::TSectorMap>> SectorMaps;
- std::unique_ptr<ICacheAccessor> CacheAccessor;
- TEncryptionKey TenantKey;
- TEncryptionKey StaticKey;
+ std::unique_ptr<ICacheAccessor> CacheAccessor;
+ TEncryptionKey TenantKey;
+ TEncryptionKey StaticKey;
TEncryptionKey PDiskKey;
- bool CachePDisks = false;
- bool CacheVDisks = false;
- bool EnableVDiskCooldownTimeout = false;
-
- // debugging options
- bool VDiskReplPausedAtStart = false;
+ bool CachePDisks = false;
+ bool CacheVDisks = false;
+ bool EnableVDiskCooldownTimeout = false;
+ // debugging options
+ bool VDiskReplPausedAtStart = false;
+
TNodeWardenConfig(const TIntrusivePtr<IPDiskServiceFactory> &pDiskServiceFactory)
: PDiskServiceFactory(pDiskServiceFactory)
, AllVDiskKinds(new TAllVDiskKinds)
@@ -52,18 +52,18 @@ namespace NKikimr {
return NPDisk::YdbDefaultPDiskSequence;
}
}
-
- bool IsCacheEnabled() const {
- return static_cast<bool>(CacheAccessor);
- }
+
+ bool IsCacheEnabled() const {
+ return static_cast<bool>(CacheAccessor);
+ }
};
IActor* CreateBSNodeWarden(const TIntrusivePtr<TNodeWardenConfig> &cfg);
- bool ObtainTenantKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig);
- bool ObtainStaticKey(TEncryptionKey *key);
+ bool ObtainTenantKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig);
+ bool ObtainStaticKey(TEncryptionKey *key);
bool ObtainPDiskKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig);
-
- std::unique_ptr<ICacheAccessor> CreateFileCacheAccessor(const TFsPath& cacheFilePath);
-
+
+ std::unique_ptr<ICacheAccessor> CreateFileCacheAccessor(const TFsPath& cacheFilePath);
+
} // NKikimr
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_cache.cpp b/ydb/core/blobstorage/nodewarden/node_warden_cache.cpp
index ed9a1cd8f50..0ce4057b7c3 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_cache.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_cache.cpp
@@ -1,234 +1,234 @@
-#include "node_warden_impl.h"
-
-using namespace NKikimr;
-using namespace NStorage;
-
-void TNodeWarden::InvokeSyncOp(std::unique_ptr<IActor> actor) {
- Y_VERIFY(!SyncActorId);
- SyncActorId = Register(actor.release(), TMailboxType::Simple, AppData()->IOPoolId);
-}
-
-void TNodeWarden::Handle(TEvents::TEvInvokeResult::TPtr ev) {
- // reset actor
- Y_VERIFY(SyncActorId == ev->Sender);
- SyncActorId = {};
-
- // process message
- try {
- ev->Get()->Process(TActivationContext::ActorContextFor(SelfId()));
- } catch (const std::exception&) {
- Y_FAIL("Exception while executing sync callback: %s", CurrentExceptionMessage().data());
- }
-
- // issue other operation if pending (and if not already issued)
- if (!SyncActorId && !SyncOpQ.empty()) {
- InvokeSyncOp(std::move(SyncOpQ.front()));
- SyncOpQ.pop();
- }
-}
-
-void TNodeWarden::EnqueueSyncOp(std::function<std::function<void()>(const TActorContext&)> callback) {
- auto complete = [](auto&& resGetter, const TActorContext&) { resGetter()(); };
- auto actor = CreateInvokeActor<NKikimrServices::TActivity::NODE_WARDEN>(std::move(callback), std::move(complete));
- if (SyncActorId) {
- // there is other operation currently going on, we have to wait for a while
- SyncOpQ.push(std::move(actor));
- } else {
- // execute operation right now
- InvokeSyncOp(std::move(actor));
- }
-}
-
-std::function<std::function<void()>(const TActorContext&)> TNodeWarden::WrapCacheOp(TWrappedCacheOp operation) {
- return [cfg = Cfg, op = std::move(operation), instanceId = InstanceId, availDomainId = AvailDomainId](const TActorContext&) {
- std::function<void()> res;
- try {
- cfg->CacheAccessor->Update([&](TString data) {
- // TODO(alexvru): special handling needed when data is empty -- this means cache file was deleted due to
- // some error and needs to be rebuilt from scratch; unlikely case
-
- NKikimrBlobStorage::TNodeWardenCache proto;
- if (!google::protobuf::TextFormat::ParseFromString(data, &proto)) {
- proto.Clear();
- }
-
- // find matching availability domain in cache protobuf; create new, if not found
- if (!proto.HasAvailDomain() || proto.GetAvailDomain() != availDomainId ||
- !proto.HasInstanceId() || proto.GetInstanceId() != instanceId) {
- proto.Clear();
- proto.SetAvailDomain(availDomainId);
- proto.SetInstanceId(*instanceId);
- }
-
- // execute operation over the service set
- res = op(proto.MutableServiceSet());
-
- // format updated cache
- data.clear();
- google::protobuf::TextFormat::PrintToString(proto, &data);
- return data;
- });
- } catch (...) {
- STLOG(PRI_WARN, BS_NODE, NW06, "WrapCacheOp failed to update cache", (Error, CurrentExceptionMessage()));
- }
- if (!res) { // no processor was actually called due to error
- res = op(nullptr);
- }
- return res;
- };
-}
-
-TNodeWarden::TWrappedCacheOp TNodeWarden::UpdateGroupInCache(const NKikimrBlobStorage::TGroupInfo& group) {
- return [group](NKikimrBlobStorage::TNodeWardenServiceSet *services) -> std::function<void()> {
- if (services) {
- auto *protoGroups = services->MutableGroups();
- for (int i = 0; i < protoGroups->size(); ++i) {
- const NKikimrBlobStorage::TGroupInfo& pb = protoGroups->at(i);
- if (pb.GetGroupID() == group.GetGroupID()) {
- if (pb.GetGroupGeneration() <= group.GetGroupGeneration()) {
- protoGroups->Mutable(i)->CopyFrom(group);
- }
- return [] {};
- }
- }
- protoGroups->Add()->CopyFrom(group);
- }
- return [] {};
- };
-}
-
-TNodeWarden::TWrappedCacheOp TNodeWarden::UpdateServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& newServices,
- bool comprehensive, std::function<void()> tail) {
- return [newServices, comprehensive, tail = std::move(tail)](NKikimrBlobStorage::TNodeWardenServiceSet *services) {
- if (!services) {
- return tail;
- }
-
- auto applyDiff = [](auto *cache, auto& map) {
- using TMap = std::decay_t<decltype(map)>;
- using TItem = std::remove_cv_t<std::remove_pointer_t<typename TMap::mapped_type>>;
- static constexpr bool isGroupInfo = std::is_same_v<TItem, NKikimrBlobStorage::TGroupInfo>;
- static constexpr bool isVDisk = std::is_same_v<TItem, NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk>;
- auto extractKey = [](const auto& item) -> typename TMap::key_type {
- if constexpr (isGroupInfo) {
- return item.GetGroupID();
- } else if constexpr (isVDisk) {
- return TVSlotId(item.GetVDiskLocation());
- } else {
- return item;
- }
- };
- for (int i = 0; i < cache->size(); ++i) {
- const auto& item = cache->at(i);
- if (const auto it = map.find(extractKey(item)); it != map.end()) {
- if (it->second) {
- bool pred = true;
- if constexpr (isGroupInfo) {
- pred = item.GetGroupGeneration() <= it->second->GetGroupGeneration();
- }
- if (pred) {
- cache->Mutable(i)->CopyFrom(item);
- }
- } else {
- cache->DeleteSubrange(i--, 1);
- }
- map.erase(it);
- }
- }
- for (const auto& [key, value] : map) {
- if (value) {
- cache->Add()->CopyFrom(*value);
- }
- }
- };
-
- if (comprehensive) {
- // when we receive comprehensive configuration, we just overwrite corresponding values
- services->MutablePDisks()->CopyFrom(newServices.GetPDisks());
- services->MutableVDisks()->CopyFrom(newServices.GetVDisks());
- } else {
- // otherwise we have to calculate diffs and apply only changed entities
- std::set<TPDiskKey> pdisksToDestroy;
- std::map<TPDiskKey, const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk*> pdisks;
- for (const auto& x : newServices.GetPDisks()) {
- const auto *ptr = x.HasEntityStatus() && x.GetEntityStatus() == NKikimrBlobStorage::DESTROY ? nullptr : &x;
- pdisks.emplace(x, ptr);
- if (!ptr) {
- pdisksToDestroy.insert(x);
- }
- }
- applyDiff(services->MutablePDisks(), pdisks);
-
- // do the same thing for vdisks
- std::map<TVSlotId, const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk*> vdisks;
- for (const auto& x : newServices.GetVDisks()) {
- const TVSlotId key(x.GetVDiskLocation());
- Y_VERIFY(!pdisksToDestroy.count({key.NodeId, key.PDiskId}) || x.GetDoDestroy(), "inconsistent ServiceSet");
- vdisks.emplace(key, pdisksToDestroy.count({key.NodeId, key.PDiskId}) ? nullptr : &x);
- }
- applyDiff(services->MutableVDisks(), vdisks);
- }
-
- // update groups configuration
- std::unordered_map<ui32, const NKikimrBlobStorage::TGroupInfo*> groups;
- for (const auto& x : newServices.GetGroups()) {
- groups.emplace(x.GetGroupID(), x.HasEntityStatus() && x.GetEntityStatus() == NKikimrBlobStorage::DESTROY ? nullptr : &x);
- }
- applyDiff(services->MutableGroups(), groups);
-
- return tail;
- };
-}
-
-std::unique_ptr<ICacheAccessor> NKikimr::CreateFileCacheAccessor(const TFsPath& cacheFilePath) {
- class TAccessor : public ICacheAccessor {
- TFsPath Path;
-
- public:
- TAccessor(TFsPath path)
- : Path(std::move(path))
- {}
-
- TString Read() override {
- return TFileInput(Path).ReadAll();
- }
-
- void Update(std::function<TString(TString)> processor) override {
- try {
- TString data;
- std::optional<TFile> inFile;
- inFile.emplace(Path, OpenAlways | RdWr | Sync);
- inFile->Flock(LOCK_EX);
-
- // read the file unless it is way too big to fit into memory
- if (i64 len = inFile->GetLength(); len <= 32 * 1024 * 1024) {
- data = TString::Uninitialized(len);
- try {
- data.resize(inFile->Read(data.Detach(), len));
- } catch (const TFileError&) {
- data.clear(); // consider empty cache on read error
- }
- }
-
- data = processor(data);
-
- const TString suffix = Sprintf(".%08" PRIx32, RandomNumber<ui32>());
- TFsPath temp = Path.Parent() / (Path.GetName() + suffix);
- try {
- TFile outFile(temp, CreateNew | WrOnly);
- outFile.Write(data.data(), data.size());
- outFile.Close();
- temp.RenameTo(Path);
- } catch (...) {
- temp.DeleteIfExists();
- throw;
- }
- } catch (...) {
- Path.DeleteIfExists();
- throw;
- }
- }
- };
-
- return std::make_unique<TAccessor>(cacheFilePath);
-}
+#include "node_warden_impl.h"
+
+using namespace NKikimr;
+using namespace NStorage;
+
+void TNodeWarden::InvokeSyncOp(std::unique_ptr<IActor> actor) {
+ Y_VERIFY(!SyncActorId);
+ SyncActorId = Register(actor.release(), TMailboxType::Simple, AppData()->IOPoolId);
+}
+
+void TNodeWarden::Handle(TEvents::TEvInvokeResult::TPtr ev) {
+ // reset actor
+ Y_VERIFY(SyncActorId == ev->Sender);
+ SyncActorId = {};
+
+ // process message
+ try {
+ ev->Get()->Process(TActivationContext::ActorContextFor(SelfId()));
+ } catch (const std::exception&) {
+ Y_FAIL("Exception while executing sync callback: %s", CurrentExceptionMessage().data());
+ }
+
+ // issue other operation if pending (and if not already issued)
+ if (!SyncActorId && !SyncOpQ.empty()) {
+ InvokeSyncOp(std::move(SyncOpQ.front()));
+ SyncOpQ.pop();
+ }
+}
+
+void TNodeWarden::EnqueueSyncOp(std::function<std::function<void()>(const TActorContext&)> callback) {
+ auto complete = [](auto&& resGetter, const TActorContext&) { resGetter()(); };
+ auto actor = CreateInvokeActor<NKikimrServices::TActivity::NODE_WARDEN>(std::move(callback), std::move(complete));
+ if (SyncActorId) {
+ // there is other operation currently going on, we have to wait for a while
+ SyncOpQ.push(std::move(actor));
+ } else {
+ // execute operation right now
+ InvokeSyncOp(std::move(actor));
+ }
+}
+
+std::function<std::function<void()>(const TActorContext&)> TNodeWarden::WrapCacheOp(TWrappedCacheOp operation) {
+ return [cfg = Cfg, op = std::move(operation), instanceId = InstanceId, availDomainId = AvailDomainId](const TActorContext&) {
+ std::function<void()> res;
+ try {
+ cfg->CacheAccessor->Update([&](TString data) {
+ // TODO(alexvru): special handling needed when data is empty -- this means cache file was deleted due to
+ // some error and needs to be rebuilt from scratch; unlikely case
+
+ NKikimrBlobStorage::TNodeWardenCache proto;
+ if (!google::protobuf::TextFormat::ParseFromString(data, &proto)) {
+ proto.Clear();
+ }
+
+ // find matching availability domain in cache protobuf; create new, if not found
+ if (!proto.HasAvailDomain() || proto.GetAvailDomain() != availDomainId ||
+ !proto.HasInstanceId() || proto.GetInstanceId() != instanceId) {
+ proto.Clear();
+ proto.SetAvailDomain(availDomainId);
+ proto.SetInstanceId(*instanceId);
+ }
+
+ // execute operation over the service set
+ res = op(proto.MutableServiceSet());
+
+ // format updated cache
+ data.clear();
+ google::protobuf::TextFormat::PrintToString(proto, &data);
+ return data;
+ });
+ } catch (...) {
+ STLOG(PRI_WARN, BS_NODE, NW06, "WrapCacheOp failed to update cache", (Error, CurrentExceptionMessage()));
+ }
+ if (!res) { // no processor was actually called due to error
+ res = op(nullptr);
+ }
+ return res;
+ };
+}
+
+TNodeWarden::TWrappedCacheOp TNodeWarden::UpdateGroupInCache(const NKikimrBlobStorage::TGroupInfo& group) {
+ return [group](NKikimrBlobStorage::TNodeWardenServiceSet *services) -> std::function<void()> {
+ if (services) {
+ auto *protoGroups = services->MutableGroups();
+ for (int i = 0; i < protoGroups->size(); ++i) {
+ const NKikimrBlobStorage::TGroupInfo& pb = protoGroups->at(i);
+ if (pb.GetGroupID() == group.GetGroupID()) {
+ if (pb.GetGroupGeneration() <= group.GetGroupGeneration()) {
+ protoGroups->Mutable(i)->CopyFrom(group);
+ }
+ return [] {};
+ }
+ }
+ protoGroups->Add()->CopyFrom(group);
+ }
+ return [] {};
+ };
+}
+
+TNodeWarden::TWrappedCacheOp TNodeWarden::UpdateServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& newServices,
+ bool comprehensive, std::function<void()> tail) {
+ return [newServices, comprehensive, tail = std::move(tail)](NKikimrBlobStorage::TNodeWardenServiceSet *services) {
+ if (!services) {
+ return tail;
+ }
+
+ auto applyDiff = [](auto *cache, auto& map) {
+ using TMap = std::decay_t<decltype(map)>;
+ using TItem = std::remove_cv_t<std::remove_pointer_t<typename TMap::mapped_type>>;
+ static constexpr bool isGroupInfo = std::is_same_v<TItem, NKikimrBlobStorage::TGroupInfo>;
+ static constexpr bool isVDisk = std::is_same_v<TItem, NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk>;
+ auto extractKey = [](const auto& item) -> typename TMap::key_type {
+ if constexpr (isGroupInfo) {
+ return item.GetGroupID();
+ } else if constexpr (isVDisk) {
+ return TVSlotId(item.GetVDiskLocation());
+ } else {
+ return item;
+ }
+ };
+ for (int i = 0; i < cache->size(); ++i) {
+ const auto& item = cache->at(i);
+ if (const auto it = map.find(extractKey(item)); it != map.end()) {
+ if (it->second) {
+ bool pred = true;
+ if constexpr (isGroupInfo) {
+ pred = item.GetGroupGeneration() <= it->second->GetGroupGeneration();
+ }
+ if (pred) {
+ cache->Mutable(i)->CopyFrom(item);
+ }
+ } else {
+ cache->DeleteSubrange(i--, 1);
+ }
+ map.erase(it);
+ }
+ }
+ for (const auto& [key, value] : map) {
+ if (value) {
+ cache->Add()->CopyFrom(*value);
+ }
+ }
+ };
+
+ if (comprehensive) {
+ // when we receive comprehensive configuration, we just overwrite corresponding values
+ services->MutablePDisks()->CopyFrom(newServices.GetPDisks());
+ services->MutableVDisks()->CopyFrom(newServices.GetVDisks());
+ } else {
+ // otherwise we have to calculate diffs and apply only changed entities
+ std::set<TPDiskKey> pdisksToDestroy;
+ std::map<TPDiskKey, const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk*> pdisks;
+ for (const auto& x : newServices.GetPDisks()) {
+ const auto *ptr = x.HasEntityStatus() && x.GetEntityStatus() == NKikimrBlobStorage::DESTROY ? nullptr : &x;
+ pdisks.emplace(x, ptr);
+ if (!ptr) {
+ pdisksToDestroy.insert(x);
+ }
+ }
+ applyDiff(services->MutablePDisks(), pdisks);
+
+ // do the same thing for vdisks
+ std::map<TVSlotId, const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk*> vdisks;
+ for (const auto& x : newServices.GetVDisks()) {
+ const TVSlotId key(x.GetVDiskLocation());
+ Y_VERIFY(!pdisksToDestroy.count({key.NodeId, key.PDiskId}) || x.GetDoDestroy(), "inconsistent ServiceSet");
+ vdisks.emplace(key, pdisksToDestroy.count({key.NodeId, key.PDiskId}) ? nullptr : &x);
+ }
+ applyDiff(services->MutableVDisks(), vdisks);
+ }
+
+ // update groups configuration
+ std::unordered_map<ui32, const NKikimrBlobStorage::TGroupInfo*> groups;
+ for (const auto& x : newServices.GetGroups()) {
+ groups.emplace(x.GetGroupID(), x.HasEntityStatus() && x.GetEntityStatus() == NKikimrBlobStorage::DESTROY ? nullptr : &x);
+ }
+ applyDiff(services->MutableGroups(), groups);
+
+ return tail;
+ };
+}
+
+std::unique_ptr<ICacheAccessor> NKikimr::CreateFileCacheAccessor(const TFsPath& cacheFilePath) {
+ class TAccessor : public ICacheAccessor {
+ TFsPath Path;
+
+ public:
+ TAccessor(TFsPath path)
+ : Path(std::move(path))
+ {}
+
+ TString Read() override {
+ return TFileInput(Path).ReadAll();
+ }
+
+ void Update(std::function<TString(TString)> processor) override {
+ try {
+ TString data;
+ std::optional<TFile> inFile;
+ inFile.emplace(Path, OpenAlways | RdWr | Sync);
+ inFile->Flock(LOCK_EX);
+
+ // read the file unless it is way too big to fit into memory
+ if (i64 len = inFile->GetLength(); len <= 32 * 1024 * 1024) {
+ data = TString::Uninitialized(len);
+ try {
+ data.resize(inFile->Read(data.Detach(), len));
+ } catch (const TFileError&) {
+ data.clear(); // consider empty cache on read error
+ }
+ }
+
+ data = processor(data);
+
+ const TString suffix = Sprintf(".%08" PRIx32, RandomNumber<ui32>());
+ TFsPath temp = Path.Parent() / (Path.GetName() + suffix);
+ try {
+ TFile outFile(temp, CreateNew | WrOnly);
+ outFile.Write(data.data(), data.size());
+ outFile.Close();
+ temp.RenameTo(Path);
+ } catch (...) {
+ temp.DeleteIfExists();
+ throw;
+ }
+ } catch (...) {
+ Path.DeleteIfExists();
+ throw;
+ }
+ }
+ };
+
+ return std::make_unique<TAccessor>(cacheFilePath);
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_group.cpp b/ydb/core/blobstorage/nodewarden/node_warden_group.cpp
index 8db18cc8e81..99ee810bdfb 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_group.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_group.cpp
@@ -1,268 +1,268 @@
-#include "node_warden_impl.h"
-
-namespace NKikimr::NStorage {
-
- TIntrusivePtr<TBlobStorageGroupInfo> TNodeWarden::NeedGroupInfo(ui32 groupId) {
- if (EjectedGroups.count(groupId)) {
- return nullptr;
- }
-
- auto& group = Groups[groupId];
- if (const auto& info = group.Info; !info) {
- // we do not have relevant group configuration, request it; we can't return group now
- RequestGroupConfig(groupId, group);
- return nullptr;
- } else if (group.EncryptionParams.GetEncryptionMode() == TBlobStorageGroupInfo::EEM_NONE) {
- // no encryption required, group info relevant
- Y_VERIFY(group.EncryptionParams.HasEncryptionMode());
- return info;
- } else {
- // encryption required, check key's life cycle phase
- switch (info->GetLifeCyclePhase()) {
- case TBlobStorageGroupInfo::ELCP_INITIAL:
- // we have to request key here, if we haven't done this yet; if there is no main key set, then we
- // just return group without key and use it in limited mode
- if (const TEncryptionKey& mainKey = GetGroupMainKey(groupId)) {
- ProposeKey(groupId, mainKey, group.EncryptionParams);
- return nullptr;
- } else {
- Y_VERIFY(!info->GetCypherKey()->GetIsKeySet()); // ensure no key loaded
- return info;
- }
-
- case TBlobStorageGroupInfo::ELCP_IN_TRANSITION:
- // someone was proposing key and its transaction is in flight; we have to re-request the key after
- // some time, no key proposition needed; retry logic is implemented in application processor
- return nullptr;
-
- case TBlobStorageGroupInfo::ELCP_IN_USE:
- // key is in use and loaded, return the group
- Y_VERIFY(info->GetCypherKey()->GetIsKeySet());
- return info;
-
- case TBlobStorageGroupInfo::ELCP_PROPOSE:
- case TBlobStorageGroupInfo::ELCP_KEY_CRC_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_VERSION_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_ID_ERROR:
- case TBlobStorageGroupInfo::ELCP_KEY_NOT_LOADED:
- // run proxy in limited mode
- Y_VERIFY(!info->GetCypherKey()->GetIsKeySet()); // ensure no key loaded
- return info;
- }
- }
- }
-
- void TNodeWarden::ProposeKey(ui32 groupId, const TEncryptionKey& mainKey, const NKikimrBlobStorage::TGroupInfo& encryptionParams) {
- TCypherKey groupKey;
- ui8 *keyBytes = nullptr;
- ui32 keySizeBytes = 0;
- groupKey.MutableKeyBytes(&keyBytes, &keySizeBytes);
- EntropyPool().Read(keyBytes, keySizeBytes);
- TString encryptedGroupKey;
- ui32 h = Crc32c(keyBytes, keySizeBytes);
- encryptedGroupKey.resize(keySizeBytes + sizeof(ui32));
- char *destination = encryptedGroupKey.Detach();
-
- const ui64 groupKeyNonce = encryptionParams.GetGroupKeyNonce();
-
- TStreamCypher cypher;
- bool isKeySet = cypher.SetKey(static_cast<const TCypherKey&>(mainKey));
- Y_VERIFY(isKeySet);
- cypher.StartMessage(groupKeyNonce, 0);
- cypher.Encrypt(destination, keyBytes, keySizeBytes);
- destination += keySizeBytes;
- cypher.Encrypt(destination, &h, sizeof(h));
-
- Y_VERIFY(encryptedGroupKey.size() == groupKey.GetKeySizeBytes() + sizeof(ui32));
-
- // Send the request
- STLOG(PRI_DEBUG, BS_NODE, NW68, "ConfigureLocalProxy propose", (GroupId, groupId), (MainKey, mainKey));
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerProposeGroupKey>(LocalNodeId, groupId,
- TBlobStorageGroupInfo::ELCP_PROPOSE, mainKey.Id, encryptedGroupKey, mainKey.Version, groupKeyNonce));
- }
-
- TEncryptionKey& TNodeWarden::GetGroupMainKey(ui32 groupId) {
- return TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeStatic
- ? Cfg->StaticKey
- : Cfg->TenantKey;
- }
-
- void TNodeWarden::ApplyGroupInfo(ui32 groupId, ui32 generation, const NKikimrBlobStorage::TGroupInfo *newGroup,
- bool fromController, bool fromResolver) {
- // if the group is marked as 'ejected', this is a race
- if (EjectedGroups.count(groupId)) {
- return;
- }
-
- // some basic consistency checks
- Y_VERIFY(!newGroup || (newGroup->GetGroupID() == groupId && newGroup->GetGroupGeneration() == generation));
-
- // obtain group record
- const auto [it, _] = Groups.try_emplace(groupId);
- TGroupRecord& group = it->second;
- group.MaxKnownGeneration = Max(group.MaxKnownGeneration, generation);
-
- // forget pending queries
- if (fromController) {
- group.GetGroupRequestPending = false;
- group.ProposeRequestPending = false;
- } else if (fromResolver) {
- group.GetGroupRequestPending = false;
- }
-
- if (group.GroupResolver) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, group.GroupResolver, {}, nullptr, 0));
- group.GroupResolver = {};
- }
-
- // update group content and encryption stuff
- bool groupChanged = false; // did the 'Group' field change somehow?
- if (newGroup) {
- auto& currentGroup = group.Group;
-
- // generate serialized string to compare it to the one after changes
- TString before;
- if (currentGroup) {
- const bool success = currentGroup->SerializeToString(&before);
- Y_VERIFY(success);
- }
-
- // apply basic protobuf changes
- if (!currentGroup || currentGroup->GetGroupGeneration() < newGroup->GetGroupGeneration()) {
- currentGroup.emplace(*newGroup);
- }
-
- // apply encryption parameters from new protobuf
- auto& ep = group.EncryptionParams;
- Y_VERIFY_S(!ep.HasEncryptionMode() || ep.GetEncryptionMode() == newGroup->GetEncryptionMode(),
- "sudden EncryptionMode change from# " << static_cast<TBlobStorageGroupInfo::EEncryptionMode>(ep.GetEncryptionMode())
- << " to# " << static_cast<TBlobStorageGroupInfo::EEncryptionMode>(newGroup->GetEncryptionMode()) << " GroupId# " << groupId);
-
- if (!ep.HasEncryptionMode() || group.EncryptionParams.GetLifeCyclePhase() != TBlobStorageGroupInfo::ELCP_IN_USE) {
- // copy encryption mode and then copy other parameters if encryption is enabled
- ep.SetEncryptionMode(newGroup->GetEncryptionMode());
- if (ep.GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
- ep.SetLifeCyclePhase(newGroup->GetLifeCyclePhase());
- ep.SetMainKeyId(newGroup->GetMainKeyId());
- ep.SetEncryptedGroupKey(newGroup->GetEncryptedGroupKey());
- ep.SetGroupKeyNonce(newGroup->GetGroupKeyNonce());
- ep.SetMainKeyVersion(newGroup->GetMainKeyVersion());
-
- if (ep.GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
- // re-request group configuration for this group after some timeout
- TActivationContext::Schedule(TDuration::Seconds(1), new IEventHandle(TEvPrivate::EvGetGroup, 0,
- SelfId(), {}, nullptr, groupId));
- }
- }
- } else if (newGroup->GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_USE) {
- // validate encryption parameters -- they cannot change
- Y_VERIFY(ep.GetMainKeyId() == newGroup->GetMainKeyId());
- Y_VERIFY(ep.GetEncryptedGroupKey() == newGroup->GetEncryptedGroupKey());
- Y_VERIFY(ep.GetGroupKeyNonce() == newGroup->GetGroupKeyNonce());
- Y_VERIFY(ep.GetMainKeyVersion() == newGroup->GetMainKeyVersion());
- }
-
- // put encryption parameters overlay over the group proto
- currentGroup->MergeFrom(group.EncryptionParams);
-
- // check if group content has changed
- TString after;
- Y_VERIFY(currentGroup);
- const bool success = currentGroup->SerializeToString(&after);
- Y_VERIFY(success);
- groupChanged = before != after;
-
- if (groupChanged && Cfg->IsCacheEnabled() && TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeDynamic) {
- EnqueueSyncOp(WrapCacheOp(UpdateGroupInCache(*currentGroup)));
- }
- }
-
- if (const auto& currentGroup = group.Group; !currentGroup) {
- // we just do not have protobuf for the group, nothing else to do here
- } else if (currentGroup->GetGroupGeneration() != group.MaxKnownGeneration) {
- // we do not have relevant group configuration, but we know that there is one, so reset the configuration
- // for group/proxy and ask BSC for group info
- group.Info.Reset();
- RequestGroupConfig(groupId, group);
- if (group.ProxyRunning) {
- Send(MakeBlobStorageProxyID(groupId), new TEvBlobStorage::TEvConfigureProxy(nullptr));
- }
- } else if (groupChanged) {
- // group has changed; obtain main encryption key for this group and try to parse group info from the protobuf
- auto& mainKey = GetGroupMainKey(groupId);
- TStringStream err;
- group.Info = TBlobStorageGroupInfo::Parse(*currentGroup, &mainKey, &err);
- Y_VERIFY(group.EncryptionParams.HasEncryptionMode());
- if (const TString& s = err.Str()) {
- STLOG(PRI_ERROR, BS_NODE, NW19, "error while parsing group", (GroupId, groupId), (Err, s));
- }
-
- if (group.ProxyRunning) { // update configuration for running proxies
- auto info = NeedGroupInfo(groupId);
- auto counters = info
- ? DsProxyPerPoolCounters->GetPoolCounters(info->GetStoragePoolName(), info->GetDeviceType())
- : nullptr;
- Send(MakeBlobStorageProxyID(groupId), new TEvBlobStorage::TEvConfigureProxy(std::move(info),
- std::move(counters)));
- }
-
- if (const auto& info = group.Info) {
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate(info, info->GetStoragePoolName()));
- for (auto& vdisk : group.VDisksOfGroup) {
- UpdateGroupInfoForDisk(vdisk, info);
- }
- }
- }
- }
-
- void TNodeWarden::RequestGroupConfig(ui32 groupId, TGroupRecord& group) {
- STLOG(PRI_DEBUG, BS_NODE, NW98, "RequestGroupConfig", (GroupId, groupId));
- if (group.GetGroupRequestPending) {
- Y_VERIFY(group.GroupResolver);
- } else {
- Y_VERIFY(!group.GroupResolver);
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerGetGroup>(LocalNodeId, &groupId, &groupId + 1));
- group.GroupResolver = RegisterWithSameMailbox(CreateGroupResolverActor(groupId));
- group.GetGroupRequestPending = true;
- }
- }
-
- void TNodeWarden::ApplyGroupInfoFromServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
- for (const auto& group : serviceSet.GetGroups()) {
- const ui32 groupId = group.GetGroupID();
- if (group.GetEntityStatus() == NKikimrBlobStorage::DESTROY) {
- if (EjectedGroups.insert(groupId).second) {
- TGroupRecord& group = Groups[groupId];
- STLOG(PRI_DEBUG, BS_NODE, NW99, "destroying group", (GroupId, groupId), (ProxyRunning, group.ProxyRunning));
- if (group.ProxyRunning) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, MakeBlobStorageProxyID(groupId), {}, nullptr, 0));
- }
- Groups.erase(groupId);
-
- // report group deletion to whiteboard
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateDelete(groupId));
- }
- } else {
- ApplyGroupInfo(groupId, group.GetGroupGeneration(), &group, true, false);
- }
- }
- }
-
- void TNodeWarden::Handle(TEvBlobStorage::TEvUpdateGroupInfo::TPtr ev) {
- auto *msg = ev->Get();
- bool fromResolver = false;
- if (const auto it = Groups.find(msg->GroupId); it != Groups.end() && ev->Sender == it->second.GroupResolver) {
- it->second.GroupResolver = {};
- fromResolver = true;
- }
- ApplyGroupInfo(msg->GroupId, msg->GroupGeneration, msg->GroupInfo ? &*msg->GroupInfo : nullptr, false, fromResolver);
- }
-
- void TNodeWarden::HandleGetGroup(TAutoPtr<IEventHandle> ev) {
- if (const auto it = Groups.find(ev->Cookie); it != Groups.end() &&
- it->second.EncryptionParams.GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
- RequestGroupConfig(it->first, it->second);
- }
- }
-
-} // NKikimr::NStorage
+#include "node_warden_impl.h"
+
+namespace NKikimr::NStorage {
+
+ TIntrusivePtr<TBlobStorageGroupInfo> TNodeWarden::NeedGroupInfo(ui32 groupId) {
+ if (EjectedGroups.count(groupId)) {
+ return nullptr;
+ }
+
+ auto& group = Groups[groupId];
+ if (const auto& info = group.Info; !info) {
+ // we do not have relevant group configuration, request it; we can't return group now
+ RequestGroupConfig(groupId, group);
+ return nullptr;
+ } else if (group.EncryptionParams.GetEncryptionMode() == TBlobStorageGroupInfo::EEM_NONE) {
+ // no encryption required, group info relevant
+ Y_VERIFY(group.EncryptionParams.HasEncryptionMode());
+ return info;
+ } else {
+ // encryption required, check key's life cycle phase
+ switch (info->GetLifeCyclePhase()) {
+ case TBlobStorageGroupInfo::ELCP_INITIAL:
+ // we have to request key here, if we haven't done this yet; if there is no main key set, then we
+ // just return group without key and use it in limited mode
+ if (const TEncryptionKey& mainKey = GetGroupMainKey(groupId)) {
+ ProposeKey(groupId, mainKey, group.EncryptionParams);
+ return nullptr;
+ } else {
+ Y_VERIFY(!info->GetCypherKey()->GetIsKeySet()); // ensure no key loaded
+ return info;
+ }
+
+ case TBlobStorageGroupInfo::ELCP_IN_TRANSITION:
+ // someone was proposing key and its transaction is in flight; we have to re-request the key after
+ // some time, no key proposition needed; retry logic is implemented in application processor
+ return nullptr;
+
+ case TBlobStorageGroupInfo::ELCP_IN_USE:
+ // key is in use and loaded, return the group
+ Y_VERIFY(info->GetCypherKey()->GetIsKeySet());
+ return info;
+
+ case TBlobStorageGroupInfo::ELCP_PROPOSE:
+ case TBlobStorageGroupInfo::ELCP_KEY_CRC_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_VERSION_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_ID_ERROR:
+ case TBlobStorageGroupInfo::ELCP_KEY_NOT_LOADED:
+ // run proxy in limited mode
+ Y_VERIFY(!info->GetCypherKey()->GetIsKeySet()); // ensure no key loaded
+ return info;
+ }
+ }
+ }
+
+ void TNodeWarden::ProposeKey(ui32 groupId, const TEncryptionKey& mainKey, const NKikimrBlobStorage::TGroupInfo& encryptionParams) {
+ TCypherKey groupKey;
+ ui8 *keyBytes = nullptr;
+ ui32 keySizeBytes = 0;
+ groupKey.MutableKeyBytes(&keyBytes, &keySizeBytes);
+ EntropyPool().Read(keyBytes, keySizeBytes);
+ TString encryptedGroupKey;
+ ui32 h = Crc32c(keyBytes, keySizeBytes);
+ encryptedGroupKey.resize(keySizeBytes + sizeof(ui32));
+ char *destination = encryptedGroupKey.Detach();
+
+ const ui64 groupKeyNonce = encryptionParams.GetGroupKeyNonce();
+
+ TStreamCypher cypher;
+ bool isKeySet = cypher.SetKey(static_cast<const TCypherKey&>(mainKey));
+ Y_VERIFY(isKeySet);
+ cypher.StartMessage(groupKeyNonce, 0);
+ cypher.Encrypt(destination, keyBytes, keySizeBytes);
+ destination += keySizeBytes;
+ cypher.Encrypt(destination, &h, sizeof(h));
+
+ Y_VERIFY(encryptedGroupKey.size() == groupKey.GetKeySizeBytes() + sizeof(ui32));
+
+ // Send the request
+ STLOG(PRI_DEBUG, BS_NODE, NW68, "ConfigureLocalProxy propose", (GroupId, groupId), (MainKey, mainKey));
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerProposeGroupKey>(LocalNodeId, groupId,
+ TBlobStorageGroupInfo::ELCP_PROPOSE, mainKey.Id, encryptedGroupKey, mainKey.Version, groupKeyNonce));
+ }
+
+ TEncryptionKey& TNodeWarden::GetGroupMainKey(ui32 groupId) {
+ return TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeStatic
+ ? Cfg->StaticKey
+ : Cfg->TenantKey;
+ }
+
+ void TNodeWarden::ApplyGroupInfo(ui32 groupId, ui32 generation, const NKikimrBlobStorage::TGroupInfo *newGroup,
+ bool fromController, bool fromResolver) {
+ // if the group is marked as 'ejected', this is a race
+ if (EjectedGroups.count(groupId)) {
+ return;
+ }
+
+ // some basic consistency checks
+ Y_VERIFY(!newGroup || (newGroup->GetGroupID() == groupId && newGroup->GetGroupGeneration() == generation));
+
+ // obtain group record
+ const auto [it, _] = Groups.try_emplace(groupId);
+ TGroupRecord& group = it->second;
+ group.MaxKnownGeneration = Max(group.MaxKnownGeneration, generation);
+
+ // forget pending queries
+ if (fromController) {
+ group.GetGroupRequestPending = false;
+ group.ProposeRequestPending = false;
+ } else if (fromResolver) {
+ group.GetGroupRequestPending = false;
+ }
+
+ if (group.GroupResolver) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, group.GroupResolver, {}, nullptr, 0));
+ group.GroupResolver = {};
+ }
+
+ // update group content and encryption stuff
+ bool groupChanged = false; // did the 'Group' field change somehow?
+ if (newGroup) {
+ auto& currentGroup = group.Group;
+
+ // generate serialized string to compare it to the one after changes
+ TString before;
+ if (currentGroup) {
+ const bool success = currentGroup->SerializeToString(&before);
+ Y_VERIFY(success);
+ }
+
+ // apply basic protobuf changes
+ if (!currentGroup || currentGroup->GetGroupGeneration() < newGroup->GetGroupGeneration()) {
+ currentGroup.emplace(*newGroup);
+ }
+
+ // apply encryption parameters from new protobuf
+ auto& ep = group.EncryptionParams;
+ Y_VERIFY_S(!ep.HasEncryptionMode() || ep.GetEncryptionMode() == newGroup->GetEncryptionMode(),
+ "sudden EncryptionMode change from# " << static_cast<TBlobStorageGroupInfo::EEncryptionMode>(ep.GetEncryptionMode())
+ << " to# " << static_cast<TBlobStorageGroupInfo::EEncryptionMode>(newGroup->GetEncryptionMode()) << " GroupId# " << groupId);
+
+ if (!ep.HasEncryptionMode() || group.EncryptionParams.GetLifeCyclePhase() != TBlobStorageGroupInfo::ELCP_IN_USE) {
+ // copy encryption mode and then copy other parameters if encryption is enabled
+ ep.SetEncryptionMode(newGroup->GetEncryptionMode());
+ if (ep.GetEncryptionMode() != TBlobStorageGroupInfo::EEM_NONE) {
+ ep.SetLifeCyclePhase(newGroup->GetLifeCyclePhase());
+ ep.SetMainKeyId(newGroup->GetMainKeyId());
+ ep.SetEncryptedGroupKey(newGroup->GetEncryptedGroupKey());
+ ep.SetGroupKeyNonce(newGroup->GetGroupKeyNonce());
+ ep.SetMainKeyVersion(newGroup->GetMainKeyVersion());
+
+ if (ep.GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
+ // re-request group configuration for this group after some timeout
+ TActivationContext::Schedule(TDuration::Seconds(1), new IEventHandle(TEvPrivate::EvGetGroup, 0,
+ SelfId(), {}, nullptr, groupId));
+ }
+ }
+ } else if (newGroup->GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_USE) {
+ // validate encryption parameters -- they cannot change
+ Y_VERIFY(ep.GetMainKeyId() == newGroup->GetMainKeyId());
+ Y_VERIFY(ep.GetEncryptedGroupKey() == newGroup->GetEncryptedGroupKey());
+ Y_VERIFY(ep.GetGroupKeyNonce() == newGroup->GetGroupKeyNonce());
+ Y_VERIFY(ep.GetMainKeyVersion() == newGroup->GetMainKeyVersion());
+ }
+
+ // put encryption parameters overlay over the group proto
+ currentGroup->MergeFrom(group.EncryptionParams);
+
+ // check if group content has changed
+ TString after;
+ Y_VERIFY(currentGroup);
+ const bool success = currentGroup->SerializeToString(&after);
+ Y_VERIFY(success);
+ groupChanged = before != after;
+
+ if (groupChanged && Cfg->IsCacheEnabled() && TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeDynamic) {
+ EnqueueSyncOp(WrapCacheOp(UpdateGroupInCache(*currentGroup)));
+ }
+ }
+
+ if (const auto& currentGroup = group.Group; !currentGroup) {
+ // we just do not have protobuf for the group, nothing else to do here
+ } else if (currentGroup->GetGroupGeneration() != group.MaxKnownGeneration) {
+ // we do not have relevant group configuration, but we know that there is one, so reset the configuration
+ // for group/proxy and ask BSC for group info
+ group.Info.Reset();
+ RequestGroupConfig(groupId, group);
+ if (group.ProxyRunning) {
+ Send(MakeBlobStorageProxyID(groupId), new TEvBlobStorage::TEvConfigureProxy(nullptr));
+ }
+ } else if (groupChanged) {
+ // group has changed; obtain main encryption key for this group and try to parse group info from the protobuf
+ auto& mainKey = GetGroupMainKey(groupId);
+ TStringStream err;
+ group.Info = TBlobStorageGroupInfo::Parse(*currentGroup, &mainKey, &err);
+ Y_VERIFY(group.EncryptionParams.HasEncryptionMode());
+ if (const TString& s = err.Str()) {
+ STLOG(PRI_ERROR, BS_NODE, NW19, "error while parsing group", (GroupId, groupId), (Err, s));
+ }
+
+ if (group.ProxyRunning) { // update configuration for running proxies
+ auto info = NeedGroupInfo(groupId);
+ auto counters = info
+ ? DsProxyPerPoolCounters->GetPoolCounters(info->GetStoragePoolName(), info->GetDeviceType())
+ : nullptr;
+ Send(MakeBlobStorageProxyID(groupId), new TEvBlobStorage::TEvConfigureProxy(std::move(info),
+ std::move(counters)));
+ }
+
+ if (const auto& info = group.Info) {
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate(info, info->GetStoragePoolName()));
+ for (auto& vdisk : group.VDisksOfGroup) {
+ UpdateGroupInfoForDisk(vdisk, info);
+ }
+ }
+ }
+ }
+
+ void TNodeWarden::RequestGroupConfig(ui32 groupId, TGroupRecord& group) {
+ STLOG(PRI_DEBUG, BS_NODE, NW98, "RequestGroupConfig", (GroupId, groupId));
+ if (group.GetGroupRequestPending) {
+ Y_VERIFY(group.GroupResolver);
+ } else {
+ Y_VERIFY(!group.GroupResolver);
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerGetGroup>(LocalNodeId, &groupId, &groupId + 1));
+ group.GroupResolver = RegisterWithSameMailbox(CreateGroupResolverActor(groupId));
+ group.GetGroupRequestPending = true;
+ }
+ }
+
+ void TNodeWarden::ApplyGroupInfoFromServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
+ for (const auto& group : serviceSet.GetGroups()) {
+ const ui32 groupId = group.GetGroupID();
+ if (group.GetEntityStatus() == NKikimrBlobStorage::DESTROY) {
+ if (EjectedGroups.insert(groupId).second) {
+ TGroupRecord& group = Groups[groupId];
+ STLOG(PRI_DEBUG, BS_NODE, NW99, "destroying group", (GroupId, groupId), (ProxyRunning, group.ProxyRunning));
+ if (group.ProxyRunning) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, MakeBlobStorageProxyID(groupId), {}, nullptr, 0));
+ }
+ Groups.erase(groupId);
+
+ // report group deletion to whiteboard
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateDelete(groupId));
+ }
+ } else {
+ ApplyGroupInfo(groupId, group.GetGroupGeneration(), &group, true, false);
+ }
+ }
+ }
+
+ void TNodeWarden::Handle(TEvBlobStorage::TEvUpdateGroupInfo::TPtr ev) {
+ auto *msg = ev->Get();
+ bool fromResolver = false;
+ if (const auto it = Groups.find(msg->GroupId); it != Groups.end() && ev->Sender == it->second.GroupResolver) {
+ it->second.GroupResolver = {};
+ fromResolver = true;
+ }
+ ApplyGroupInfo(msg->GroupId, msg->GroupGeneration, msg->GroupInfo ? &*msg->GroupInfo : nullptr, false, fromResolver);
+ }
+
+ void TNodeWarden::HandleGetGroup(TAutoPtr<IEventHandle> ev) {
+ if (const auto it = Groups.find(ev->Cookie); it != Groups.end() &&
+ it->second.EncryptionParams.GetLifeCyclePhase() == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
+ RequestGroupConfig(it->first, it->second);
+ }
+ }
+
+} // NKikimr::NStorage
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_group_resolver.cpp b/ydb/core/blobstorage/nodewarden/node_warden_group_resolver.cpp
index 75c6eb26be9..02dba82dbb9 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_group_resolver.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_group_resolver.cpp
@@ -1,326 +1,326 @@
-#include "node_warden_impl.h"
-
-namespace NKikimr::NStorage {
-
- static constexpr TDuration GroupResolverStartTimeout = TDuration::Seconds(5); // time to wait before resolving
- static constexpr TDuration QueryTimeout = TDuration::Seconds(3); // timeout before considering unanswered
- static constexpr TDuration NodeTimeout = TDuration::Seconds(1); // timeout before next retry after receiving NodeDisconnected
- static constexpr ui32 MaxQueriesInFlight = 3;
-
- struct TNodeWarden::TGroupResolverContext::TImpl {
- std::unordered_set<ui32> NodeIds; // all static node ids of this cluster
- bool NodeIdsRequestPending = false;
- std::unordered_set<TActorId, THash<TActorId>> NodeIdsWaitQueue;
-
- struct TNodeInfo {
- std::vector<ui32> StartedGroupIds;
- };
- std::unordered_map<ui32, TNodeInfo> NodeInfo;
- std::set<std::pair<ui32, ui32>> StartedGroupIdToNodes;
- };
-
- TNodeWarden::TGroupResolverContext::TGroupResolverContext()
- : Impl(std::make_unique<TImpl>())
- {}
-
- TNodeWarden::TGroupResolverContext::~TGroupResolverContext()
- {}
-
- class TNodeWarden::TGroupResolverActor : public TActorBootstrapped<TGroupResolverActor> {
- struct TEvPrivate {
- enum {
- EvQueryTimeout = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvNodeTimeout,
- EvNodeIdsObtained,
- };
- struct TEvQueryTimeout : TEventLocal<TEvQueryTimeout, EvQueryTimeout> {};
- struct TEvNodeTimeout : TEventLocal<TEvNodeTimeout, EvNodeTimeout> {};
- };
-
- private:
- struct TQueryTimeout {
- TInstant Expires;
- ui32 NodeId;
- ui64 Cookie;
- };
-
- struct TNodeTimeout {
- TInstant Expires;
- ui32 NodeId;
- };
-
- private:
- const ui32 GroupId;
- const TIntrusivePtr<TGroupResolverContext> GroupResolverContext;
- TGroupResolverContext::TImpl& Ctx;
- std::unordered_set<ui32> NodeIdsUnprocessed;
- std::unordered_map<ui32, ui64> QueriesInFlight;
- std::unordered_set<ui32> SubscribedNodes;
- std::unordered_map<ui32, NKikimrBlobStorage::TGroupInfo> GroupInfoReceived;
- std::deque<TQueryTimeout> QueryTimeoutQ;
- std::deque<TNodeTimeout> NodeTimeoutQ;
- ui64 NextCookie = 1;
-
- public:
- TGroupResolverActor(ui32 groupId, TIntrusivePtr<TGroupResolverContext> groupResolverContext)
- : GroupId(groupId)
- , GroupResolverContext(std::move(groupResolverContext))
- , Ctx(*GroupResolverContext->Impl)
- {}
-
- void Bootstrap() {
- STLOG(PRI_INFO, BS_NODE, NW79, "TGroupResolverActor::Bootstrap", (GroupId, GroupId));
- Become(&TThis::StateWaitStart, GroupResolverStartTimeout, new TEvents::TEvWakeup);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void StartResolving() {
- STLOG(PRI_INFO, BS_NODE, NW85, "TGroupResolverActor::StartResolving", (GroupId, GroupId));
- Become(&TThis::StateFunc);
-
- if (!Ctx.NodeIds.empty()) { // we already have list of static nodes, so we can process immediately
- HandleNodeIdsObtained();
- } else if (Ctx.NodeIdsRequestPending) { // no nodes available and request is in flight, put us to queue
- Ctx.NodeIdsWaitQueue.emplace(SelfId());
- } else { // start new request
- Ctx.NodeIdsRequestPending = true;
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
- }
- }
-
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr ev) {
- const auto& dyn = AppData()->DynamicNameserviceConfig;
- ui32 maxStaticNodeId = dyn ? dyn->MaxStaticNodeId : Max<ui32>();
- for (const auto& node : ev->Get()->Nodes) {
- if (node.NodeId <= maxStaticNodeId) {
- Ctx.NodeIds.emplace(node.NodeId);
- }
- }
- for (TActorId actorId : std::exchange(Ctx.NodeIdsWaitQueue, {})) { // notify waiting actors
- TActivationContext::Send(new IEventHandle(TEvPrivate::EvNodeIdsObtained, 0, actorId, {}, {}, 0));
- }
- HandleNodeIdsObtained();
- }
-
- void HandleNodeIdsObtained() {
- NodeIdsUnprocessed = Ctx.NodeIds;
- IssueQueriesAndCheckIfDone();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void IssueQueriesAndCheckIfDone() {
- while (QueriesInFlight.size() < MaxQueriesInFlight && IssueQuery())
- {}
- if (QueriesInFlight.empty()) { // nothing more to do
- ProcessResultAndFinish();
- }
- }
-
- bool IssueQuery() {
- auto issueQueryToNode = [this](ui32 nodeId) {
- STLOG(PRI_DEBUG, BS_NODE, NW80, "TGroupResolverActor::IssueQuery", (GroupId, GroupId), (NodeId, nodeId));
-
- // issue message to target node
- Send(MakeBlobStorageNodeWardenID(nodeId), new TEvNodeWardenQueryGroupInfo(GroupId),
- IEventHandle::FlagSubscribeOnSession, nodeId);
-
- // mark this node as subscribed one
- SubscribedNodes.insert(nodeId);
-
- // register in flight request and push it into timeout queue
- const ui64 cookie = NextCookie++;
- QueriesInFlight.emplace(nodeId, cookie);
- QueryTimeoutQ.push_back(TQueryTimeout{TActivationContext::Now() + QueryTimeout, nodeId, cookie});
- if (QueryTimeoutQ.size() == 1) {
- Schedule(QueryTimeoutQ.front().Expires, new TEvPrivate::TEvQueryTimeout);
- }
-
- // remove this node from unprocessed node list
- NodeIdsUnprocessed.erase(nodeId);
- };
-
- // try to scan all nodes that are known to contains our group at a moment of time of near past
- auto& m = Ctx.StartedGroupIdToNodes;
- for (auto it = m.lower_bound(std::make_pair(GroupId, 0)); it != m.end() && it->first == GroupId; ++it) {
- const ui32 nodeId = it->second;
- if (NodeIdsUnprocessed.count(nodeId)) {
- issueQueryToNode(nodeId);
- return true;
- }
- }
-
- // check if we have the result and we have scanned all the nodes of the group
- if (const auto *result = GetResultingGroupInfo()) {
- std::unordered_set<ui32> needed;
- for (const auto& realm : result->GetRings()) {
- for (const auto& domain : realm.GetFailDomains()) {
- for (const auto& vdisk : domain.GetVDiskLocations()) {
- needed.insert(vdisk.GetNodeID());
- }
- }
- }
- for (auto it = m.lower_bound(std::make_pair(GroupId, 0)); it != m.end() && it->first == GroupId; ++it) {
- needed.erase(it->second);
- }
- if (needed.empty()) {
- return false; // information we have is quite conclusive, nothing more to scan
- }
- }
-
- // scan all nodes one-by-one
- for (ui32 nodeId : NodeIdsUnprocessed) {
- issueQueryToNode(nodeId);
- return true;
- }
-
- return false; // all nodes scanned, nothing more to do
- }
-
- void Handle(TEvNodeWardenGroupInfo::TPtr ev) {
- const ui32 nodeId = ev->Cookie;
- const auto& record = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_NODE, NW84, "TGroupResolverActor::TEvNodeWardenGroupInfo", (GroupId, GroupId),
- (NodeId, nodeId), (Msg, ev->Get()->ToString()));
- if (record.HasGroup()) { // remember group info
- GroupInfoReceived.emplace(nodeId, record.GetGroup());
- }
-
- // remove group<->node mapping for selected node and clear started groups vector
- auto& nodeInfo = Ctx.NodeInfo[nodeId];
- for (ui32 groupId : nodeInfo.StartedGroupIds) {
- const size_t num = Ctx.StartedGroupIdToNodes.erase(std::make_pair(groupId, nodeId));
- Y_VERIFY(num);
- }
- nodeInfo.StartedGroupIds.clear();
-
- // fill in new started groups vector and create appropriate map
- const auto& startedGroupIds = record.GetStartedGroupIds();
- nodeInfo.StartedGroupIds.insert(nodeInfo.StartedGroupIds.end(), startedGroupIds.begin(), startedGroupIds.end());
- for (ui32 groupId : nodeInfo.StartedGroupIds) {
- const bool inserted = Ctx.StartedGroupIdToNodes.emplace(groupId, nodeId).second;
- Y_VERIFY(inserted);
- }
-
- QueriesInFlight.erase(nodeId);
- IssueQueriesAndCheckIfDone();
- }
-
- void HandleQueryTimeout() {
- const TInstant now = TActivationContext::Now();
- std::deque<TQueryTimeout>::iterator it;
- for (it = QueryTimeoutQ.begin(); it != QueryTimeoutQ.end() && it->Expires <= now; ++it) {
- if (const auto inflightIt = QueriesInFlight.find(it->NodeId); inflightIt != QueriesInFlight.end() &&
- inflightIt->second == it->Cookie) {
- QueriesInFlight.erase(inflightIt);
- }
- }
- QueryTimeoutQ.erase(QueryTimeoutQ.begin(), it);
- if (!QueryTimeoutQ.empty()) {
- Schedule(QueryTimeoutQ.front().Expires, new TEvPrivate::TEvQueryTimeout);
- }
- IssueQueriesAndCheckIfDone();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const NKikimrBlobStorage::TGroupInfo *GetResultingGroupInfo() const {
- const NKikimrBlobStorage::TGroupInfo *result = nullptr;
- for (const auto& [nodeId, group] : GroupInfoReceived) {
- if (!result || result->GetGroupGeneration() < group.GetGroupGeneration()) {
- result = &group;
- }
- }
- return result;
- }
-
- void ProcessResultAndFinish() {
- if (auto *result = GetResultingGroupInfo()) {
- STLOG(PRI_INFO, BS_NODE, NW86, "TGroupResolverActor::ProcessResultAndFinish", (GroupId, GroupId),
- (Result, *result));
- Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvUpdateGroupInfo(GroupId,
- result->GetGroupGeneration(), *result));
- PassAway();
- } else { // restart from the beginning
- StartResolving();
- }
- }
-
- void PassAway() {
- STLOG(PRI_INFO, BS_NODE, NW81, "TGroupResolverActor::PassAway", (GroupId, GroupId));
- for (ui32 nodeId : SubscribedNodes) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
- }
- TActorBootstrapped::PassAway();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr ev) {
- STLOG(PRI_DEBUG, BS_NODE, NW82, "TGroupResolverActor::TEvNodeConnected", (GroupId, GroupId),
- (NodeId, ev->Get()->NodeId));
- }
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
- const ui32 nodeId = ev->Get()->NodeId;
- STLOG(PRI_DEBUG, BS_NODE, NW83, "TGroupResolverActor::TEvNodeDisconnected", (GroupId, GroupId),
- (NodeId, ev->Get()->NodeId));
- QueriesInFlight.erase(nodeId);
- NodeTimeoutQ.push_back(TNodeTimeout{TActivationContext::Now() + NodeTimeout, nodeId});
- if (NodeTimeoutQ.size() == 1) {
- Schedule(NodeTimeoutQ.front().Expires, new TEvPrivate::TEvNodeTimeout);
- }
- }
-
- void HandleNodeTimeout() {
- const TInstant now = TActivationContext::Now();
- std::deque<TNodeTimeout>::iterator it;
- for (it = NodeTimeoutQ.begin(); it != NodeTimeoutQ.end() && it->Expires <= now; ++it) {
- NodeIdsUnprocessed.insert(it->NodeId); // try processing for this node
- }
- NodeTimeoutQ.erase(NodeTimeoutQ.begin(), it);
- if (!NodeTimeoutQ.empty()) {
- Schedule(NodeTimeoutQ.front().Expires, new TEvPrivate::TEvNodeTimeout);
- }
- IssueQueriesAndCheckIfDone();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- STRICT_STFUNC(StateWaitStart,
- cFunc(TEvents::TSystem::Wakeup, StartResolving);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- cFunc(TEvPrivate::EvNodeIdsObtained, HandleNodeIdsObtained);
-
- hFunc(TEvNodeWardenGroupInfo, Handle);
- cFunc(TEvPrivate::EvQueryTimeout, HandleQueryTimeout);
- hFunc(TEvInterconnect::TEvNodeConnected, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
- cFunc(TEvPrivate::EvNodeTimeout, HandleNodeTimeout);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
- };
-
- IActor *TNodeWarden::CreateGroupResolverActor(ui32 groupId) {
- return new TGroupResolverActor(groupId, GroupResolverContext);
- }
-
- void TNodeWarden::Handle(TEvNodeWardenQueryGroupInfo::TPtr ev) {
- const auto& r = ev->Get()->Record;
- auto res = std::make_unique<TEvNodeWardenGroupInfo>();
- auto& record = res->Record;
- if (const auto it = Groups.find(r.GetGroupId()); it != Groups.end() && it->second.Group) {
- record.MutableGroup()->CopyFrom(*it->second.Group);
- }
- for (const auto& [groupId, group] : Groups) {
- record.AddStartedGroupIds(groupId);
- }
- Send(ev->Sender, res.release(), 0, ev->Cookie);
- }
-
-} // NKikimr
+#include "node_warden_impl.h"
+
+namespace NKikimr::NStorage {
+
+ static constexpr TDuration GroupResolverStartTimeout = TDuration::Seconds(5); // time to wait before resolving
+ static constexpr TDuration QueryTimeout = TDuration::Seconds(3); // timeout before considering unanswered
+ static constexpr TDuration NodeTimeout = TDuration::Seconds(1); // timeout before next retry after receiving NodeDisconnected
+ static constexpr ui32 MaxQueriesInFlight = 3;
+
+ struct TNodeWarden::TGroupResolverContext::TImpl {
+ std::unordered_set<ui32> NodeIds; // all static node ids of this cluster
+ bool NodeIdsRequestPending = false;
+ std::unordered_set<TActorId, THash<TActorId>> NodeIdsWaitQueue;
+
+ struct TNodeInfo {
+ std::vector<ui32> StartedGroupIds;
+ };
+ std::unordered_map<ui32, TNodeInfo> NodeInfo;
+ std::set<std::pair<ui32, ui32>> StartedGroupIdToNodes;
+ };
+
+ TNodeWarden::TGroupResolverContext::TGroupResolverContext()
+ : Impl(std::make_unique<TImpl>())
+ {}
+
+ TNodeWarden::TGroupResolverContext::~TGroupResolverContext()
+ {}
+
+ class TNodeWarden::TGroupResolverActor : public TActorBootstrapped<TGroupResolverActor> {
+ struct TEvPrivate {
+ enum {
+ EvQueryTimeout = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvNodeTimeout,
+ EvNodeIdsObtained,
+ };
+ struct TEvQueryTimeout : TEventLocal<TEvQueryTimeout, EvQueryTimeout> {};
+ struct TEvNodeTimeout : TEventLocal<TEvNodeTimeout, EvNodeTimeout> {};
+ };
+
+ private:
+ struct TQueryTimeout {
+ TInstant Expires;
+ ui32 NodeId;
+ ui64 Cookie;
+ };
+
+ struct TNodeTimeout {
+ TInstant Expires;
+ ui32 NodeId;
+ };
+
+ private:
+ const ui32 GroupId;
+ const TIntrusivePtr<TGroupResolverContext> GroupResolverContext;
+ TGroupResolverContext::TImpl& Ctx;
+ std::unordered_set<ui32> NodeIdsUnprocessed;
+ std::unordered_map<ui32, ui64> QueriesInFlight;
+ std::unordered_set<ui32> SubscribedNodes;
+ std::unordered_map<ui32, NKikimrBlobStorage::TGroupInfo> GroupInfoReceived;
+ std::deque<TQueryTimeout> QueryTimeoutQ;
+ std::deque<TNodeTimeout> NodeTimeoutQ;
+ ui64 NextCookie = 1;
+
+ public:
+ TGroupResolverActor(ui32 groupId, TIntrusivePtr<TGroupResolverContext> groupResolverContext)
+ : GroupId(groupId)
+ , GroupResolverContext(std::move(groupResolverContext))
+ , Ctx(*GroupResolverContext->Impl)
+ {}
+
+ void Bootstrap() {
+ STLOG(PRI_INFO, BS_NODE, NW79, "TGroupResolverActor::Bootstrap", (GroupId, GroupId));
+ Become(&TThis::StateWaitStart, GroupResolverStartTimeout, new TEvents::TEvWakeup);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void StartResolving() {
+ STLOG(PRI_INFO, BS_NODE, NW85, "TGroupResolverActor::StartResolving", (GroupId, GroupId));
+ Become(&TThis::StateFunc);
+
+ if (!Ctx.NodeIds.empty()) { // we already have list of static nodes, so we can process immediately
+ HandleNodeIdsObtained();
+ } else if (Ctx.NodeIdsRequestPending) { // no nodes available and request is in flight, put us to queue
+ Ctx.NodeIdsWaitQueue.emplace(SelfId());
+ } else { // start new request
+ Ctx.NodeIdsRequestPending = true;
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
+ }
+ }
+
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr ev) {
+ const auto& dyn = AppData()->DynamicNameserviceConfig;
+ ui32 maxStaticNodeId = dyn ? dyn->MaxStaticNodeId : Max<ui32>();
+ for (const auto& node : ev->Get()->Nodes) {
+ if (node.NodeId <= maxStaticNodeId) {
+ Ctx.NodeIds.emplace(node.NodeId);
+ }
+ }
+ for (TActorId actorId : std::exchange(Ctx.NodeIdsWaitQueue, {})) { // notify waiting actors
+ TActivationContext::Send(new IEventHandle(TEvPrivate::EvNodeIdsObtained, 0, actorId, {}, {}, 0));
+ }
+ HandleNodeIdsObtained();
+ }
+
+ void HandleNodeIdsObtained() {
+ NodeIdsUnprocessed = Ctx.NodeIds;
+ IssueQueriesAndCheckIfDone();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void IssueQueriesAndCheckIfDone() {
+ while (QueriesInFlight.size() < MaxQueriesInFlight && IssueQuery())
+ {}
+ if (QueriesInFlight.empty()) { // nothing more to do
+ ProcessResultAndFinish();
+ }
+ }
+
+ bool IssueQuery() {
+ auto issueQueryToNode = [this](ui32 nodeId) {
+ STLOG(PRI_DEBUG, BS_NODE, NW80, "TGroupResolverActor::IssueQuery", (GroupId, GroupId), (NodeId, nodeId));
+
+ // issue message to target node
+ Send(MakeBlobStorageNodeWardenID(nodeId), new TEvNodeWardenQueryGroupInfo(GroupId),
+ IEventHandle::FlagSubscribeOnSession, nodeId);
+
+ // mark this node as subscribed one
+ SubscribedNodes.insert(nodeId);
+
+ // register in flight request and push it into timeout queue
+ const ui64 cookie = NextCookie++;
+ QueriesInFlight.emplace(nodeId, cookie);
+ QueryTimeoutQ.push_back(TQueryTimeout{TActivationContext::Now() + QueryTimeout, nodeId, cookie});
+ if (QueryTimeoutQ.size() == 1) {
+ Schedule(QueryTimeoutQ.front().Expires, new TEvPrivate::TEvQueryTimeout);
+ }
+
+ // remove this node from unprocessed node list
+ NodeIdsUnprocessed.erase(nodeId);
+ };
+
+ // try to scan all nodes that are known to contains our group at a moment of time of near past
+ auto& m = Ctx.StartedGroupIdToNodes;
+ for (auto it = m.lower_bound(std::make_pair(GroupId, 0)); it != m.end() && it->first == GroupId; ++it) {
+ const ui32 nodeId = it->second;
+ if (NodeIdsUnprocessed.count(nodeId)) {
+ issueQueryToNode(nodeId);
+ return true;
+ }
+ }
+
+ // check if we have the result and we have scanned all the nodes of the group
+ if (const auto *result = GetResultingGroupInfo()) {
+ std::unordered_set<ui32> needed;
+ for (const auto& realm : result->GetRings()) {
+ for (const auto& domain : realm.GetFailDomains()) {
+ for (const auto& vdisk : domain.GetVDiskLocations()) {
+ needed.insert(vdisk.GetNodeID());
+ }
+ }
+ }
+ for (auto it = m.lower_bound(std::make_pair(GroupId, 0)); it != m.end() && it->first == GroupId; ++it) {
+ needed.erase(it->second);
+ }
+ if (needed.empty()) {
+ return false; // information we have is quite conclusive, nothing more to scan
+ }
+ }
+
+ // scan all nodes one-by-one
+ for (ui32 nodeId : NodeIdsUnprocessed) {
+ issueQueryToNode(nodeId);
+ return true;
+ }
+
+ return false; // all nodes scanned, nothing more to do
+ }
+
+ void Handle(TEvNodeWardenGroupInfo::TPtr ev) {
+ const ui32 nodeId = ev->Cookie;
+ const auto& record = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_NODE, NW84, "TGroupResolverActor::TEvNodeWardenGroupInfo", (GroupId, GroupId),
+ (NodeId, nodeId), (Msg, ev->Get()->ToString()));
+ if (record.HasGroup()) { // remember group info
+ GroupInfoReceived.emplace(nodeId, record.GetGroup());
+ }
+
+ // remove group<->node mapping for selected node and clear started groups vector
+ auto& nodeInfo = Ctx.NodeInfo[nodeId];
+ for (ui32 groupId : nodeInfo.StartedGroupIds) {
+ const size_t num = Ctx.StartedGroupIdToNodes.erase(std::make_pair(groupId, nodeId));
+ Y_VERIFY(num);
+ }
+ nodeInfo.StartedGroupIds.clear();
+
+ // fill in new started groups vector and create appropriate map
+ const auto& startedGroupIds = record.GetStartedGroupIds();
+ nodeInfo.StartedGroupIds.insert(nodeInfo.StartedGroupIds.end(), startedGroupIds.begin(), startedGroupIds.end());
+ for (ui32 groupId : nodeInfo.StartedGroupIds) {
+ const bool inserted = Ctx.StartedGroupIdToNodes.emplace(groupId, nodeId).second;
+ Y_VERIFY(inserted);
+ }
+
+ QueriesInFlight.erase(nodeId);
+ IssueQueriesAndCheckIfDone();
+ }
+
+ void HandleQueryTimeout() {
+ const TInstant now = TActivationContext::Now();
+ std::deque<TQueryTimeout>::iterator it;
+ for (it = QueryTimeoutQ.begin(); it != QueryTimeoutQ.end() && it->Expires <= now; ++it) {
+ if (const auto inflightIt = QueriesInFlight.find(it->NodeId); inflightIt != QueriesInFlight.end() &&
+ inflightIt->second == it->Cookie) {
+ QueriesInFlight.erase(inflightIt);
+ }
+ }
+ QueryTimeoutQ.erase(QueryTimeoutQ.begin(), it);
+ if (!QueryTimeoutQ.empty()) {
+ Schedule(QueryTimeoutQ.front().Expires, new TEvPrivate::TEvQueryTimeout);
+ }
+ IssueQueriesAndCheckIfDone();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ const NKikimrBlobStorage::TGroupInfo *GetResultingGroupInfo() const {
+ const NKikimrBlobStorage::TGroupInfo *result = nullptr;
+ for (const auto& [nodeId, group] : GroupInfoReceived) {
+ if (!result || result->GetGroupGeneration() < group.GetGroupGeneration()) {
+ result = &group;
+ }
+ }
+ return result;
+ }
+
+ void ProcessResultAndFinish() {
+ if (auto *result = GetResultingGroupInfo()) {
+ STLOG(PRI_INFO, BS_NODE, NW86, "TGroupResolverActor::ProcessResultAndFinish", (GroupId, GroupId),
+ (Result, *result));
+ Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvUpdateGroupInfo(GroupId,
+ result->GetGroupGeneration(), *result));
+ PassAway();
+ } else { // restart from the beginning
+ StartResolving();
+ }
+ }
+
+ void PassAway() {
+ STLOG(PRI_INFO, BS_NODE, NW81, "TGroupResolverActor::PassAway", (GroupId, GroupId));
+ for (ui32 nodeId : SubscribedNodes) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ }
+ TActorBootstrapped::PassAway();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr ev) {
+ STLOG(PRI_DEBUG, BS_NODE, NW82, "TGroupResolverActor::TEvNodeConnected", (GroupId, GroupId),
+ (NodeId, ev->Get()->NodeId));
+ }
+
+ void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
+ const ui32 nodeId = ev->Get()->NodeId;
+ STLOG(PRI_DEBUG, BS_NODE, NW83, "TGroupResolverActor::TEvNodeDisconnected", (GroupId, GroupId),
+ (NodeId, ev->Get()->NodeId));
+ QueriesInFlight.erase(nodeId);
+ NodeTimeoutQ.push_back(TNodeTimeout{TActivationContext::Now() + NodeTimeout, nodeId});
+ if (NodeTimeoutQ.size() == 1) {
+ Schedule(NodeTimeoutQ.front().Expires, new TEvPrivate::TEvNodeTimeout);
+ }
+ }
+
+ void HandleNodeTimeout() {
+ const TInstant now = TActivationContext::Now();
+ std::deque<TNodeTimeout>::iterator it;
+ for (it = NodeTimeoutQ.begin(); it != NodeTimeoutQ.end() && it->Expires <= now; ++it) {
+ NodeIdsUnprocessed.insert(it->NodeId); // try processing for this node
+ }
+ NodeTimeoutQ.erase(NodeTimeoutQ.begin(), it);
+ if (!NodeTimeoutQ.empty()) {
+ Schedule(NodeTimeoutQ.front().Expires, new TEvPrivate::TEvNodeTimeout);
+ }
+ IssueQueriesAndCheckIfDone();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ STRICT_STFUNC(StateWaitStart,
+ cFunc(TEvents::TSystem::Wakeup, StartResolving);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ cFunc(TEvPrivate::EvNodeIdsObtained, HandleNodeIdsObtained);
+
+ hFunc(TEvNodeWardenGroupInfo, Handle);
+ cFunc(TEvPrivate::EvQueryTimeout, HandleQueryTimeout);
+ hFunc(TEvInterconnect::TEvNodeConnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
+ cFunc(TEvPrivate::EvNodeTimeout, HandleNodeTimeout);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+ };
+
+ IActor *TNodeWarden::CreateGroupResolverActor(ui32 groupId) {
+ return new TGroupResolverActor(groupId, GroupResolverContext);
+ }
+
+ void TNodeWarden::Handle(TEvNodeWardenQueryGroupInfo::TPtr ev) {
+ const auto& r = ev->Get()->Record;
+ auto res = std::make_unique<TEvNodeWardenGroupInfo>();
+ auto& record = res->Record;
+ if (const auto it = Groups.find(r.GetGroupId()); it != Groups.end() && it->second.Group) {
+ record.MutableGroup()->CopyFrom(*it->second.Group);
+ }
+ for (const auto& [groupId, group] : Groups) {
+ record.AddStartedGroupIds(groupId);
+ }
+ Send(ev->Sender, res.release(), 0, ev->Cookie);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
index 47093a108da..1fc16a1caf2 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp
@@ -1,9 +1,9 @@
-#include "node_warden_impl.h"
+#include "node_warden_impl.h"
#include <ydb/library/pdisk_io/file_params.h>
-using namespace NKikimr;
-using namespace NStorage;
+using namespace NKikimr;
+using namespace NStorage;
TVector<NPDisk::TDriveData> TNodeWarden::ListLocalDrives() {
TVector<NPDisk::TDriveData> drives = ListDevicesWithPartlabel();
@@ -15,7 +15,7 @@ TVector<NPDisk::TDriveData> TNodeWarden::ListLocalDrives() {
drives.emplace_back(device);
}
} else {
- STLOG(PRI_WARN, BS_NODE, NW01, "Error parsing mock devices protobuf from file", (Path, MockDevicesPath));
+ STLOG(PRI_WARN, BS_NODE, NW01, "Error parsing mock devices protobuf from file", (Path, MockDevicesPath));
}
} catch (...) {
STLOG(PRI_INFO, BS_NODE, NW90, "Unable to find mock devices file", (Path, MockDevicesPath));
@@ -28,37 +28,37 @@ TVector<NPDisk::TDriveData> TNodeWarden::ListLocalDrives() {
return drives;
}
-void TNodeWarden::StartInvalidGroupProxy() {
- const ui32 groupId = Max<ui32>();
- STLOG(PRI_DEBUG, BS_NODE, NW11, "StartInvalidGroupProxy", (GroupId, groupId));
- TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(MakeBlobStorageProxyID(groupId), Register(
- CreateBlobStorageGroupEjectedProxy(groupId, DsProxyNodeMon), TMailboxType::ReadAsFilled, AppData()->SystemPoolId));
+void TNodeWarden::StartInvalidGroupProxy() {
+ const ui32 groupId = Max<ui32>();
+ STLOG(PRI_DEBUG, BS_NODE, NW11, "StartInvalidGroupProxy", (GroupId, groupId));
+ TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(MakeBlobStorageProxyID(groupId), Register(
+ CreateBlobStorageGroupEjectedProxy(groupId, DsProxyNodeMon), TMailboxType::ReadAsFilled, AppData()->SystemPoolId));
}
-void TNodeWarden::StopInvalidGroupProxy() {
+void TNodeWarden::StopInvalidGroupProxy() {
ui32 groupId = Max<ui32>();
- STLOG(PRI_DEBUG, BS_NODE, NW15, "StopInvalidGroupProxy", (GroupId, groupId));
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, MakeBlobStorageProxyID(groupId), {}, nullptr, 0));
+ STLOG(PRI_DEBUG, BS_NODE, NW15, "StopInvalidGroupProxy", (GroupId, groupId));
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, MakeBlobStorageProxyID(groupId), {}, nullptr, 0));
}
-void TNodeWarden::PassAway() {
- STLOG(PRI_DEBUG, BS_NODE, NW25, "PassAway");
- NTabletPipe::CloseClient(SelfId(), PipeClientId);
- StopInvalidGroupProxy();
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, DsProxyNodeMonActor, {}, nullptr, 0));
- return TActorBootstrapped::PassAway();
-}
-
-void TNodeWarden::Bootstrap() {
- STLOG(PRI_DEBUG, BS_NODE, NW26, "Bootstrap");
-
- LocalNodeId = SelfId().NodeId();
- WhiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(LocalNodeId);
-
- Become(&TThis::StateOnline, TDuration::Seconds(10), new TEvPrivate::TEvSendDiskMetrics());
+void TNodeWarden::PassAway() {
+ STLOG(PRI_DEBUG, BS_NODE, NW25, "PassAway");
+ NTabletPipe::CloseClient(SelfId(), PipeClientId);
+ StopInvalidGroupProxy();
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, DsProxyNodeMonActor, {}, nullptr, 0));
+ return TActorBootstrapped::PassAway();
+}
+
+void TNodeWarden::Bootstrap() {
+ STLOG(PRI_DEBUG, BS_NODE, NW26, "Bootstrap");
+
+ LocalNodeId = SelfId().NodeId();
+ WhiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(LocalNodeId);
+
+ Become(&TThis::StateOnline, TDuration::Seconds(10), new TEvPrivate::TEvSendDiskMetrics());
Schedule(TDuration::Seconds(10), new TEvPrivate::TEvUpdateNodeDrives());
- NLwTraceMonPage::ProbeRegistry().AddProbesList(LWTRACE_GET_PROBES(BLOBSTORAGE_PROVIDER));
+ NLwTraceMonPage::ProbeRegistry().AddProbesList(LWTRACE_GET_PROBES(BLOBSTORAGE_PROVIDER));
TActorSystem *actorSystem = TlsActivationContext->ExecutorThread.ActorSystem;
if (auto mon = AppData()->Mon) {
@@ -70,207 +70,207 @@ void TNodeWarden::Bootstrap() {
mon->RegisterActorPage(actorsMonPage, path, name, false, actorSystem, SelfId());
}
- DsProxyNodeMon = new TDsProxyNodeMon(AppData()->Counters, true);
- DsProxyNodeMonActor = Register(CreateDsProxyNodeMon(DsProxyNodeMon));
- DsProxyPerPoolCounters = new TDsProxyPerPoolCounters(AppData()->Counters);
-
+ DsProxyNodeMon = new TDsProxyNodeMon(AppData()->Counters, true);
+ DsProxyNodeMonActor = Register(CreateDsProxyNodeMon(DsProxyNodeMon));
+ DsProxyPerPoolCounters = new TDsProxyPerPoolCounters(AppData()->Counters);
+
if (actorSystem && actorSystem->AppData<TAppData>() && actorSystem->AppData<TAppData>()->Icb) {
actorSystem->AppData<TAppData>()->Icb->RegisterLocalControl(EnablePutBatching, "BlobStorage_EnablePutBatching");
actorSystem->AppData<TAppData>()->Icb->RegisterLocalControl(EnableVPatch, "BlobStorage_EnableVPatch");
}
- // start replication broker
- const auto& replBrokerConfig = Cfg->ServiceSet.GetReplBrokerConfig();
-
- ui64 requestBytesPerSecond = 500000000; // 500 MB/s by default
- if (replBrokerConfig.HasTotalRequestBytesPerSecond()) {
- requestBytesPerSecond = replBrokerConfig.GetTotalRequestBytesPerSecond();
- } else if (replBrokerConfig.HasRateBytesPerSecond()) { // compatibility option
- requestBytesPerSecond = replBrokerConfig.GetRateBytesPerSecond();
- }
- ReplNodeRequestQuoter = std::make_shared<TReplQuoter>(requestBytesPerSecond);
-
- ui64 responseBytesPerSecond = 500000000; // the same as for request
- if (replBrokerConfig.HasTotalResponseBytesPerSecond()) {
- responseBytesPerSecond = replBrokerConfig.GetTotalResponseBytesPerSecond();
- }
- ReplNodeResponseQuoter = std::make_shared<TReplQuoter>(responseBytesPerSecond);
-
- const ui64 maxBytes = replBrokerConfig.GetMaxInFlightReadBytes();
- actorSystem->RegisterLocalService(MakeBlobStorageReplBrokerID(), Register(CreateReplBrokerActor(maxBytes)));
-
- // determine if we are running in 'mock' mode
- EnableProxyMock = Cfg->ServiceSet.GetEnableProxyMock();
-
- // Start a statically configured set
- ApplyServiceSet(Cfg->ServiceSet, true, false, false);
- StartStaticProxies();
- EstablishPipe();
-
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(LocalNodeId));
-
- if (Cfg->IsCacheEnabled()) {
- TActivationContext::Schedule(TDuration::Seconds(5), new IEventHandle(TEvPrivate::EvReadCache, 0, SelfId(), {}, nullptr, 0));
- }
-
- StartInvalidGroupProxy();
-}
-
-void TNodeWarden::HandleReadCache() {
- if (IgnoreCache) {
- return;
- }
- EnqueueSyncOp([this, cfg = Cfg](const TActorContext&) {
- TString data;
- std::exception_ptr ex;
- try {
- data = cfg->CacheAccessor->Read();
- } catch (...) {
- ex = std::current_exception();
- }
-
- return [=] {
- NKikimrBlobStorage::TNodeWardenCache proto;
- try {
- if (IgnoreCache) {
- return;
- }
-
- if (ex) {
- std::rethrow_exception(ex);
- } else if (!google::protobuf::TextFormat::ParseFromString(data, &proto)) {
- throw yexception() << "failed to parse node warden cache protobuf";
- }
-
- STLOG(PRI_INFO, BS_NODE, NW07, "Bootstrap", (Cache, proto));
-
- if (!proto.HasInstanceId() && !proto.HasAvailDomain() && !proto.HasServiceSet()) {
- return;
- }
-
- Y_VERIFY(proto.HasInstanceId());
- Y_VERIFY(proto.HasAvailDomain() && proto.GetAvailDomain() == AvailDomainId);
- if (!InstanceId) {
- InstanceId.emplace(proto.GetInstanceId());
- }
-
- ApplyServiceSet(proto.GetServiceSet(), false, false, false);
- } catch (...) {
- STLOG(PRI_INFO, BS_NODE, NW16, "Bootstrap failed to fetch cache", (Error, CurrentExceptionMessage()));
- // ignore exception
- }
- };
- });
-}
-
-void TNodeWarden::Handle(TEvInterconnect::TEvNodeInfo::TPtr ev) {
- if (const auto& node = ev->Get()->Node) {
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(node->Location));
+ // start replication broker
+ const auto& replBrokerConfig = Cfg->ServiceSet.GetReplBrokerConfig();
+
+ ui64 requestBytesPerSecond = 500000000; // 500 MB/s by default
+ if (replBrokerConfig.HasTotalRequestBytesPerSecond()) {
+ requestBytesPerSecond = replBrokerConfig.GetTotalRequestBytesPerSecond();
+ } else if (replBrokerConfig.HasRateBytesPerSecond()) { // compatibility option
+ requestBytesPerSecond = replBrokerConfig.GetRateBytesPerSecond();
+ }
+ ReplNodeRequestQuoter = std::make_shared<TReplQuoter>(requestBytesPerSecond);
+
+ ui64 responseBytesPerSecond = 500000000; // the same as for request
+ if (replBrokerConfig.HasTotalResponseBytesPerSecond()) {
+ responseBytesPerSecond = replBrokerConfig.GetTotalResponseBytesPerSecond();
+ }
+ ReplNodeResponseQuoter = std::make_shared<TReplQuoter>(responseBytesPerSecond);
+
+ const ui64 maxBytes = replBrokerConfig.GetMaxInFlightReadBytes();
+ actorSystem->RegisterLocalService(MakeBlobStorageReplBrokerID(), Register(CreateReplBrokerActor(maxBytes)));
+
+ // determine if we are running in 'mock' mode
+ EnableProxyMock = Cfg->ServiceSet.GetEnableProxyMock();
+
+ // Start a statically configured set
+ ApplyServiceSet(Cfg->ServiceSet, true, false, false);
+ StartStaticProxies();
+ EstablishPipe();
+
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(LocalNodeId));
+
+ if (Cfg->IsCacheEnabled()) {
+ TActivationContext::Schedule(TDuration::Seconds(5), new IEventHandle(TEvPrivate::EvReadCache, 0, SelfId(), {}, nullptr, 0));
+ }
+
+ StartInvalidGroupProxy();
+}
+
+void TNodeWarden::HandleReadCache() {
+ if (IgnoreCache) {
+ return;
+ }
+ EnqueueSyncOp([this, cfg = Cfg](const TActorContext&) {
+ TString data;
+ std::exception_ptr ex;
+ try {
+ data = cfg->CacheAccessor->Read();
+ } catch (...) {
+ ex = std::current_exception();
+ }
+
+ return [=] {
+ NKikimrBlobStorage::TNodeWardenCache proto;
+ try {
+ if (IgnoreCache) {
+ return;
+ }
+
+ if (ex) {
+ std::rethrow_exception(ex);
+ } else if (!google::protobuf::TextFormat::ParseFromString(data, &proto)) {
+ throw yexception() << "failed to parse node warden cache protobuf";
+ }
+
+ STLOG(PRI_INFO, BS_NODE, NW07, "Bootstrap", (Cache, proto));
+
+ if (!proto.HasInstanceId() && !proto.HasAvailDomain() && !proto.HasServiceSet()) {
+ return;
+ }
+
+ Y_VERIFY(proto.HasInstanceId());
+ Y_VERIFY(proto.HasAvailDomain() && proto.GetAvailDomain() == AvailDomainId);
+ if (!InstanceId) {
+ InstanceId.emplace(proto.GetInstanceId());
+ }
+
+ ApplyServiceSet(proto.GetServiceSet(), false, false, false);
+ } catch (...) {
+ STLOG(PRI_INFO, BS_NODE, NW16, "Bootstrap failed to fetch cache", (Error, CurrentExceptionMessage()));
+ // ignore exception
+ }
+ };
+ });
+}
+
+void TNodeWarden::Handle(TEvInterconnect::TEvNodeInfo::TPtr ev) {
+ if (const auto& node = ev->Get()->Node) {
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateUpdate(node->Location));
}
-}
-
-void TNodeWarden::Handle(NPDisk::TEvSlayResult::TPtr ev) {
- const NPDisk::TEvSlayResult &msg = *ev->Get();
- const TVSlotId vslotId(LocalNodeId, msg.PDiskId, msg.VSlotId);
- STLOG(PRI_INFO, BS_NODE, NW28, "Handle(NPDisk::TEvSlayResult)", (Msg, msg.ToString()));
- switch (msg.Status) {
- case NKikimrProto::NOTREADY:
- TActivationContext::Schedule(TDuration::Seconds(1), new IEventHandle(MakeBlobStoragePDiskID(LocalNodeId,
- msg.PDiskId), SelfId(), new NPDisk::TEvSlay(msg.VDiskId, msg.SlayOwnerRound, msg.PDiskId, msg.VSlotId)));
- break;
-
- case NKikimrProto::OK:
- case NKikimrProto::ALREADY: {
- if (const auto vdiskIt = LocalVDisks.find(vslotId); vdiskIt == LocalVDisks.end()) {
- SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
- } else {
- SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::WIPED);
-
- TVDiskRecord& vdisk = vdiskIt->second;
- Y_VERIFY(vdisk.SlayInFlight);
- vdisk.SlayInFlight = false;
- StartLocalVDiskActor(vdisk, TDuration::Zero()); // restart actor after successful wiping
- SendDiskMetrics(false);
+}
+
+void TNodeWarden::Handle(NPDisk::TEvSlayResult::TPtr ev) {
+ const NPDisk::TEvSlayResult &msg = *ev->Get();
+ const TVSlotId vslotId(LocalNodeId, msg.PDiskId, msg.VSlotId);
+ STLOG(PRI_INFO, BS_NODE, NW28, "Handle(NPDisk::TEvSlayResult)", (Msg, msg.ToString()));
+ switch (msg.Status) {
+ case NKikimrProto::NOTREADY:
+ TActivationContext::Schedule(TDuration::Seconds(1), new IEventHandle(MakeBlobStoragePDiskID(LocalNodeId,
+ msg.PDiskId), SelfId(), new NPDisk::TEvSlay(msg.VDiskId, msg.SlayOwnerRound, msg.PDiskId, msg.VSlotId)));
+ break;
+
+ case NKikimrProto::OK:
+ case NKikimrProto::ALREADY: {
+ if (const auto vdiskIt = LocalVDisks.find(vslotId); vdiskIt == LocalVDisks.end()) {
+ SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
+ } else {
+ SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::WIPED);
+
+ TVDiskRecord& vdisk = vdiskIt->second;
+ Y_VERIFY(vdisk.SlayInFlight);
+ vdisk.SlayInFlight = false;
+ StartLocalVDiskActor(vdisk, TDuration::Zero()); // restart actor after successful wiping
+ SendDiskMetrics(false);
}
- break;
- }
-
- case NKikimrProto::CORRUPTED:
- case NKikimrProto::ERROR:
- STLOG(PRI_ERROR, BS_NODE, NW29, "Handle(NPDisk::TEvSlayResult) error", (Msg, msg.ToString()));
- SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::OPERATION_ERROR);
- break;
-
- case NKikimrProto::RACE:
- Y_FAIL("Unexpected# %s", msg.ToString().data());
- break;
-
- default:
- Y_FAIL("Unexpected status# %s", msg.ToString().data());
- break;
- };
-}
-
-void TNodeWarden::Handle(TEvRegisterPDiskLoadActor::TPtr ev) {
- Send(ev.Get()->Sender, new TEvRegisterPDiskLoadActorResult(NextLocalPDiskInitOwnerRound()));
-}
-
-void TNodeWarden::Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
- const auto& record = ev->Get()->Record;
-
- if (record.HasAvailDomain() && record.GetAvailDomain() != AvailDomainId) {
- // AvailDomain may arrive unset
- STLOG_DEBUG_FAIL(BS_NODE, NW02, "unexpected AvailDomain from BS_CONTROLLER", (Msg, record), (AvailDomainId, AvailDomainId));
- return;
- }
- if (record.HasInstanceId()) {
- if (record.GetInstanceId() != InstanceId.value_or(record.GetInstanceId())) {
- STLOG_DEBUG_FAIL(BS_NODE, NW14, "unexpected/unset InstanceId from BS_CONTROLLER", (Msg, record), (InstanceId, InstanceId));
- return;
+ break;
}
- InstanceId.emplace(record.GetInstanceId());
- }
-
- if (record.HasServiceSet()) {
- const bool comprehensive = record.GetComprehensive();
- IgnoreCache |= comprehensive;
- STLOG(PRI_DEBUG, BS_NODE, NW17, "Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate)", (Msg, record));
- ApplyServiceSet(record.GetServiceSet(), false, comprehensive, true);
- }
-}
-
-void TNodeWarden::SendDropDonorQuery(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId) {
- STLOG(PRI_NOTICE, BS_NODE, NW87, "SendDropDonorQuery", (NodeId, nodeId), (PDiskId, pdiskId), (VSlotId, vslotId),
- (VDiskId, vdiskId));
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
- auto& record = ev->Record;
- auto *request = record.MutableRequest();
- auto *cmd = request->AddCommand()->MutableDropDonorDisk();
- auto *p = cmd->MutableVSlotId();
- p->SetNodeId(nodeId);
- p->SetPDiskId(pdiskId);
- p->SetVSlotId(vslotId);
- VDiskIDFromVDiskID(vdiskId, cmd->MutableVDiskId());
- SendToController(std::move(ev));
-}
-
-void TNodeWarden::SendVDiskReport(TVSlotId vslotId, const TVDiskID &vDiskId, NKikimrBlobStorage::TEvControllerNodeReport::EVDiskPhase phase) {
- STLOG(PRI_DEBUG, BS_NODE, NW32, "SendVDiskReport", (VSlotId, vslotId), (Phase, phase));
-
- auto report = std::make_unique<TEvBlobStorage::TEvControllerNodeReport>(vslotId.NodeId);
- auto *vReport = report->Record.AddVDiskReports();
- auto *id = vReport->MutableVSlotId();
- id->SetNodeId(vslotId.NodeId);
- id->SetPDiskId(vslotId.PDiskId);
- id->SetVSlotId(vslotId.VDiskSlotId);
- VDiskIDFromVDiskID(vDiskId, vReport->MutableVDiskId());
- vReport->SetPhase(phase);
- SendToController(std::move(report));
-}
-
+
+ case NKikimrProto::CORRUPTED:
+ case NKikimrProto::ERROR:
+ STLOG(PRI_ERROR, BS_NODE, NW29, "Handle(NPDisk::TEvSlayResult) error", (Msg, msg.ToString()));
+ SendVDiskReport(vslotId, msg.VDiskId, NKikimrBlobStorage::TEvControllerNodeReport::OPERATION_ERROR);
+ break;
+
+ case NKikimrProto::RACE:
+ Y_FAIL("Unexpected# %s", msg.ToString().data());
+ break;
+
+ default:
+ Y_FAIL("Unexpected status# %s", msg.ToString().data());
+ break;
+ };
+}
+
+void TNodeWarden::Handle(TEvRegisterPDiskLoadActor::TPtr ev) {
+ Send(ev.Get()->Sender, new TEvRegisterPDiskLoadActorResult(NextLocalPDiskInitOwnerRound()));
+}
+
+void TNodeWarden::Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
+ const auto& record = ev->Get()->Record;
+
+ if (record.HasAvailDomain() && record.GetAvailDomain() != AvailDomainId) {
+ // AvailDomain may arrive unset
+ STLOG_DEBUG_FAIL(BS_NODE, NW02, "unexpected AvailDomain from BS_CONTROLLER", (Msg, record), (AvailDomainId, AvailDomainId));
+ return;
+ }
+ if (record.HasInstanceId()) {
+ if (record.GetInstanceId() != InstanceId.value_or(record.GetInstanceId())) {
+ STLOG_DEBUG_FAIL(BS_NODE, NW14, "unexpected/unset InstanceId from BS_CONTROLLER", (Msg, record), (InstanceId, InstanceId));
+ return;
+ }
+ InstanceId.emplace(record.GetInstanceId());
+ }
+
+ if (record.HasServiceSet()) {
+ const bool comprehensive = record.GetComprehensive();
+ IgnoreCache |= comprehensive;
+ STLOG(PRI_DEBUG, BS_NODE, NW17, "Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate)", (Msg, record));
+ ApplyServiceSet(record.GetServiceSet(), false, comprehensive, true);
+ }
+}
+
+void TNodeWarden::SendDropDonorQuery(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId) {
+ STLOG(PRI_NOTICE, BS_NODE, NW87, "SendDropDonorQuery", (NodeId, nodeId), (PDiskId, pdiskId), (VSlotId, vslotId),
+ (VDiskId, vdiskId));
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto& record = ev->Record;
+ auto *request = record.MutableRequest();
+ auto *cmd = request->AddCommand()->MutableDropDonorDisk();
+ auto *p = cmd->MutableVSlotId();
+ p->SetNodeId(nodeId);
+ p->SetPDiskId(pdiskId);
+ p->SetVSlotId(vslotId);
+ VDiskIDFromVDiskID(vdiskId, cmd->MutableVDiskId());
+ SendToController(std::move(ev));
+}
+
+void TNodeWarden::SendVDiskReport(TVSlotId vslotId, const TVDiskID &vDiskId, NKikimrBlobStorage::TEvControllerNodeReport::EVDiskPhase phase) {
+ STLOG(PRI_DEBUG, BS_NODE, NW32, "SendVDiskReport", (VSlotId, vslotId), (Phase, phase));
+
+ auto report = std::make_unique<TEvBlobStorage::TEvControllerNodeReport>(vslotId.NodeId);
+ auto *vReport = report->Record.AddVDiskReports();
+ auto *id = vReport->MutableVSlotId();
+ id->SetNodeId(vslotId.NodeId);
+ id->SetPDiskId(vslotId.PDiskId);
+ id->SetVSlotId(vslotId.VDiskSlotId);
+ VDiskIDFromVDiskID(vDiskId, vReport->MutableVDiskId());
+ vReport->SetPhase(phase);
+ SendToController(std::move(report));
+}
+
void TNodeWarden::Handle(TEvBlobStorage::TEvAskRestartPDisk::TPtr ev) {
const auto id = ev->Get()->PDiskId;
- if (auto it = LocalPDisks.find(TPDiskKey{LocalNodeId, id}); it != LocalPDisks.end()) {
+ if (auto it = LocalPDisks.find(TPDiskKey{LocalNodeId, id}); it != LocalPDisks.end()) {
RestartLocalPDiskStart(id, CreatePDiskConfig(it->second.Record));
}
}
@@ -279,73 +279,73 @@ void TNodeWarden::Handle(TEvBlobStorage::TEvRestartPDiskResult::TPtr ev) {
RestartLocalPDiskFinish(ev->Get()->PDiskId, ev->Get()->Status);
}
-void TNodeWarden::Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr ev) {
- STLOG(PRI_TRACE, BS_NODE, NW38, "Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus)");
-
- auto differs = [](const auto& updated, const auto& current) {
- TString xUpdated, xCurrent;
- bool success = updated.SerializeToString(&xUpdated);
- Y_VERIFY(success);
- success = current.SerializeToString(&xCurrent);
- Y_VERIFY(success);
- return xUpdated != xCurrent;
- };
-
- auto& record = ev->Get()->Record;
-
- for (const NKikimrBlobStorage::TVDiskMetrics& m : record.GetVDisksMetrics()) {
- Y_VERIFY(m.HasVSlotId());
- const TVSlotId vslotId(m.GetVSlotId());
- if (const auto it = LocalVDisks.find(vslotId); it != LocalVDisks.end()) {
- TVDiskRecord& vdisk = it->second;
- if (vdisk.VDiskMetrics) {
- auto& current = *vdisk.VDiskMetrics;
- NKikimrBlobStorage::TVDiskMetrics updated(current);
- updated.MergeFrom(m);
- if (differs(updated, current)) {
- current.Swap(&updated);
- VDisksWithUnreportedMetrics.PushBack(&vdisk);
- }
- } else {
- vdisk.VDiskMetrics.emplace(m);
- VDisksWithUnreportedMetrics.PushBack(&vdisk);
- }
+void TNodeWarden::Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr ev) {
+ STLOG(PRI_TRACE, BS_NODE, NW38, "Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus)");
+
+ auto differs = [](const auto& updated, const auto& current) {
+ TString xUpdated, xCurrent;
+ bool success = updated.SerializeToString(&xUpdated);
+ Y_VERIFY(success);
+ success = current.SerializeToString(&xCurrent);
+ Y_VERIFY(success);
+ return xUpdated != xCurrent;
+ };
+
+ auto& record = ev->Get()->Record;
+
+ for (const NKikimrBlobStorage::TVDiskMetrics& m : record.GetVDisksMetrics()) {
+ Y_VERIFY(m.HasVSlotId());
+ const TVSlotId vslotId(m.GetVSlotId());
+ if (const auto it = LocalVDisks.find(vslotId); it != LocalVDisks.end()) {
+ TVDiskRecord& vdisk = it->second;
+ if (vdisk.VDiskMetrics) {
+ auto& current = *vdisk.VDiskMetrics;
+ NKikimrBlobStorage::TVDiskMetrics updated(current);
+ updated.MergeFrom(m);
+ if (differs(updated, current)) {
+ current.Swap(&updated);
+ VDisksWithUnreportedMetrics.PushBack(&vdisk);
+ }
+ } else {
+ vdisk.VDiskMetrics.emplace(m);
+ VDisksWithUnreportedMetrics.PushBack(&vdisk);
+ }
}
}
-
- for (const NKikimrBlobStorage::TPDiskMetrics& m : record.GetPDisksMetrics()) {
- Y_VERIFY(m.HasPDiskId());
- if (const auto it = LocalPDisks.find({LocalNodeId, m.GetPDiskId()}); it != LocalPDisks.end()) {
- TPDiskRecord& pdisk = it->second;
- if (pdisk.PDiskMetrics) {
- auto& current = *pdisk.PDiskMetrics;
- if (differs(m, current)) {
- current.CopyFrom(m);
- PDisksWithUnreportedMetrics.PushBack(&pdisk);
- }
- } else {
- pdisk.PDiskMetrics.emplace(m);
- PDisksWithUnreportedMetrics.PushBack(&pdisk);
- }
+
+ for (const NKikimrBlobStorage::TPDiskMetrics& m : record.GetPDisksMetrics()) {
+ Y_VERIFY(m.HasPDiskId());
+ if (const auto it = LocalPDisks.find({LocalNodeId, m.GetPDiskId()}); it != LocalPDisks.end()) {
+ TPDiskRecord& pdisk = it->second;
+ if (pdisk.PDiskMetrics) {
+ auto& current = *pdisk.PDiskMetrics;
+ if (differs(m, current)) {
+ current.CopyFrom(m);
+ PDisksWithUnreportedMetrics.PushBack(&pdisk);
+ }
+ } else {
+ pdisk.PDiskMetrics.emplace(m);
+ PDisksWithUnreportedMetrics.PushBack(&pdisk);
+ }
}
}
-}
+}
-void TNodeWarden::Handle(TEvPrivate::TEvSendDiskMetrics::TPtr&) {
- STLOG(PRI_TRACE, BS_NODE, NW39, "Handle(TEvPrivate::TEvSendDiskMetrics)");
- SendDiskMetrics(true);
- ReportLatencies();
- Schedule(TDuration::Seconds(10), new TEvPrivate::TEvSendDiskMetrics());
-}
+void TNodeWarden::Handle(TEvPrivate::TEvSendDiskMetrics::TPtr&) {
+ STLOG(PRI_TRACE, BS_NODE, NW39, "Handle(TEvPrivate::TEvSendDiskMetrics)");
+ SendDiskMetrics(true);
+ ReportLatencies();
+ Schedule(TDuration::Seconds(10), new TEvPrivate::TEvSendDiskMetrics());
+}
void TNodeWarden::Handle(TEvPrivate::TEvUpdateNodeDrives::TPtr&) {
- STLOG(PRI_TRACE, BS_NODE, NW88, "Handle(TEvPrivate::UpdateNodeDrives)");
+ STLOG(PRI_TRACE, BS_NODE, NW88, "Handle(TEvPrivate::UpdateNodeDrives)");
EnqueueSyncOp([this] (const TActorContext&) {
auto drives = ListLocalDrives();
return [this, drives = std::move(drives)] () {
if (drives != WorkingLocalDrives) {
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerUpdateNodeDrives>(LocalNodeId, drives));
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerUpdateNodeDrives>(LocalNodeId, drives));
WorkingLocalDrives = std::move(drives);
}
};
@@ -354,58 +354,58 @@ void TNodeWarden::Handle(TEvPrivate::TEvUpdateNodeDrives::TPtr&) {
}
-void TNodeWarden::SendDiskMetrics(bool reportMetrics) {
- STLOG(PRI_TRACE, BS_NODE, NW45, "SendDiskMetrics", (ReportMetrics, reportMetrics));
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
- auto& record = ev->Record;
-
- if (reportMetrics) {
- for (auto& vdisk : std::exchange(VDisksWithUnreportedMetrics, {})) {
- Y_VERIFY(vdisk.VDiskMetrics);
- record.AddVDisksMetrics()->CopyFrom(*vdisk.VDiskMetrics);
- }
- for (auto& pdisk : std::exchange(PDisksWithUnreportedMetrics, {})) {
- Y_VERIFY(pdisk.PDiskMetrics);
- record.AddPDisksMetrics()->CopyFrom(*pdisk.PDiskMetrics);
+void TNodeWarden::SendDiskMetrics(bool reportMetrics) {
+ STLOG(PRI_TRACE, BS_NODE, NW45, "SendDiskMetrics", (ReportMetrics, reportMetrics));
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
+ auto& record = ev->Record;
+
+ if (reportMetrics) {
+ for (auto& vdisk : std::exchange(VDisksWithUnreportedMetrics, {})) {
+ Y_VERIFY(vdisk.VDiskMetrics);
+ record.AddVDisksMetrics()->CopyFrom(*vdisk.VDiskMetrics);
}
+ for (auto& pdisk : std::exchange(PDisksWithUnreportedMetrics, {})) {
+ Y_VERIFY(pdisk.PDiskMetrics);
+ record.AddPDisksMetrics()->CopyFrom(*pdisk.PDiskMetrics);
+ }
}
-
- FillInVDiskStatus(record.MutableVDiskStatus(), false);
-
- if (record.VDisksMetricsSize() || record.PDisksMetricsSize() || record.VDiskStatusSize()) { // anything to report?
- SendToController(std::move(ev));
- }
-}
-
-void TNodeWarden::Handle(TEvStatusUpdate::TPtr ev) {
- STLOG(PRI_DEBUG, BS_NODE, NW47, "Handle(TEvStatusUpdate)");
- auto *msg = ev->Get();
- const TVSlotId vslotId(msg->NodeId, msg->PDiskId, msg->VSlotId);
- if (const auto it = LocalVDisks.find(vslotId); it != LocalVDisks.end() && it->second.Status != msg->Status) {
- it->second.Status = msg->Status;
- SendDiskMetrics(false);
- }
-}
-
-void TNodeWarden::FillInVDiskStatus(google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus> *pb, bool initial) {
- for (auto& [vslotId, vdisk] : LocalVDisks) {
- const NKikimrBlobStorage::EVDiskStatus status = vdisk.RuntimeData
- ? vdisk.Status
- : NKikimrBlobStorage::EVDiskStatus::ERROR;
- if (initial || status != vdisk.ReportedVDiskStatus) {
- auto *item = pb->Add();
- VDiskIDFromVDiskID(vdisk.GetVDiskId(), item->MutableVDiskId());
- item->SetNodeId(vslotId.NodeId);
- item->SetPDiskId(vslotId.PDiskId);
- item->SetVSlotId(vslotId.VDiskSlotId);
- item->SetPDiskGuid(vdisk.Config.GetVDiskLocation().GetPDiskGuid());
- item->SetStatus(status);
- vdisk.ReportedVDiskStatus = status;
- }
- }
-}
-
+
+ FillInVDiskStatus(record.MutableVDiskStatus(), false);
+
+ if (record.VDisksMetricsSize() || record.PDisksMetricsSize() || record.VDiskStatusSize()) { // anything to report?
+ SendToController(std::move(ev));
+ }
+}
+
+void TNodeWarden::Handle(TEvStatusUpdate::TPtr ev) {
+ STLOG(PRI_DEBUG, BS_NODE, NW47, "Handle(TEvStatusUpdate)");
+ auto *msg = ev->Get();
+ const TVSlotId vslotId(msg->NodeId, msg->PDiskId, msg->VSlotId);
+ if (const auto it = LocalVDisks.find(vslotId); it != LocalVDisks.end() && it->second.Status != msg->Status) {
+ it->second.Status = msg->Status;
+ SendDiskMetrics(false);
+ }
+}
+
+void TNodeWarden::FillInVDiskStatus(google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus> *pb, bool initial) {
+ for (auto& [vslotId, vdisk] : LocalVDisks) {
+ const NKikimrBlobStorage::EVDiskStatus status = vdisk.RuntimeData
+ ? vdisk.Status
+ : NKikimrBlobStorage::EVDiskStatus::ERROR;
+ if (initial || status != vdisk.ReportedVDiskStatus) {
+ auto *item = pb->Add();
+ VDiskIDFromVDiskID(vdisk.GetVDiskId(), item->MutableVDiskId());
+ item->SetNodeId(vslotId.NodeId);
+ item->SetPDiskId(vslotId.PDiskId);
+ item->SetVSlotId(vslotId.VDiskSlotId);
+ item->SetPDiskGuid(vdisk.Config.GetVDiskLocation().GetPDiskGuid());
+ item->SetStatus(status);
+ vdisk.ReportedVDiskStatus = status;
+ }
+ }
+}
+
bool ObtainKey(TEncryptionKey *key, const NKikimrProto::TKeyRecord& record) {
TString containerPath = record.GetContainerPath();
TString pin = record.GetPin();
@@ -457,36 +457,36 @@ bool ObtainKey(TEncryptionKey *key, const NKikimrProto::TKeyRecord& record) {
return true;
}
-bool NKikimr::ObtainTenantKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig) {
- if (keyConfig.KeysSize()) {
- // TODO(cthulhu): process muliple keys here.
- auto &record = keyConfig.GetKeys(0);
+bool NKikimr::ObtainTenantKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig) {
+ if (keyConfig.KeysSize()) {
+ // TODO(cthulhu): process muliple keys here.
+ auto &record = keyConfig.GetKeys(0);
return ObtainKey(key, record);
} else {
Cerr << "No Keys in KeyConfig! Encrypted group DsProxies will not start" << Endl;
return false;
}
}
-
+
bool NKikimr::ObtainPDiskKey(TEncryptionKey *key, const NKikimrProto::TKeyConfig& keyConfig) {
if (keyConfig.KeysSize()) {
auto &record = keyConfig.GetKeys(0);
return ObtainKey(key, record);
- } else {
+ } else {
Cerr << "No Keys in PDiskKeyConfig! Encrypted pdisks will not start" << Endl;
- return false;
- }
-}
-
-
-bool NKikimr::ObtainStaticKey(TEncryptionKey *key) {
- // TODO(cthulhu): Replace this with real data
- key->Key.SetKey((ui8*)"TestStaticKey", 13);
- key->Version = 1;
- key->Id = "TestStaticKeyId";
- return true;
-}
-
-IActor* NKikimr::CreateBSNodeWarden(const TIntrusivePtr<TNodeWardenConfig> &cfg) {
+ return false;
+ }
+}
+
+
+bool NKikimr::ObtainStaticKey(TEncryptionKey *key) {
+ // TODO(cthulhu): Replace this with real data
+ key->Key.SetKey((ui8*)"TestStaticKey", 13);
+ key->Version = 1;
+ key->Id = "TestStaticKeyId";
+ return true;
+}
+
+IActor* NKikimr::CreateBSNodeWarden(const TIntrusivePtr<TNodeWardenConfig> &cfg) {
return new NStorage::TNodeWarden(cfg);
}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_impl.h b/ydb/core/blobstorage/nodewarden/node_warden_impl.h
index be67e5ef670..3cb82dde7c8 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_impl.h
+++ b/ydb/core/blobstorage/nodewarden/node_warden_impl.h
@@ -1,408 +1,408 @@
-#pragma once
-
-#include "defs.h"
-#include "node_warden.h"
-
+#pragma once
+
+#include "defs.h"
+#include "node_warden.h"
+
#include <ydb/core/blobstorage/dsproxy/group_sessions.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-namespace NKikimr::NStorage {
-
- constexpr ui32 ProxyConfigurationTimeoutMilliseconds = 200;
- constexpr TDuration BackoffMin = TDuration::MilliSeconds(20);
- constexpr TDuration BackoffMax = TDuration::Seconds(5);
+namespace NKikimr::NStorage {
+
+ constexpr ui32 ProxyConfigurationTimeoutMilliseconds = 200;
+ constexpr TDuration BackoffMin = TDuration::MilliSeconds(20);
+ constexpr TDuration BackoffMax = TDuration::Seconds(5);
constexpr const char *MockDevicesPath = "/Berkanavt/kikimr/testing/mock_devices.txt";
-
- template<typename T, typename TPred>
- T *FindOrCreateProtoItem(google::protobuf::RepeatedPtrField<T> *collection, TPred&& pred) {
- for (int i = 0; i < collection->size(); ++i) {
- if (pred(collection->Get(i))) {
- return collection->Mutable(i);
- }
- }
- return collection->Add();
- }
-
- struct TPDiskKey {
- ui32 NodeId;
- ui32 PDiskId;
-
- TPDiskKey(ui32 nodeId, ui32 pdiskId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- {}
-
- TPDiskKey(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk)
- : NodeId(pdisk.GetNodeID())
- , PDiskId(pdisk.GetPDiskID())
- {}
-
- friend bool operator <(const TPDiskKey& x, const TPDiskKey& y) {
- return std::make_tuple(x.NodeId, x.PDiskId) < std::make_tuple(y.NodeId, y.PDiskId);
- }
-
- friend bool operator ==(const TPDiskKey& x, const TPDiskKey& y) {
- return x.NodeId == y.NodeId && x.PDiskId == y.PDiskId;
- }
- };
-
- struct TUnreportedMetricTag {};
-
- struct TPDiskRecord
- : TIntrusiveListItem<TPDiskRecord, TUnreportedMetricTag>
- {
+
+ template<typename T, typename TPred>
+ T *FindOrCreateProtoItem(google::protobuf::RepeatedPtrField<T> *collection, TPred&& pred) {
+ for (int i = 0; i < collection->size(); ++i) {
+ if (pred(collection->Get(i))) {
+ return collection->Mutable(i);
+ }
+ }
+ return collection->Add();
+ }
+
+ struct TPDiskKey {
+ ui32 NodeId;
+ ui32 PDiskId;
+
+ TPDiskKey(ui32 nodeId, ui32 pdiskId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ {}
+
+ TPDiskKey(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk)
+ : NodeId(pdisk.GetNodeID())
+ , PDiskId(pdisk.GetPDiskID())
+ {}
+
+ friend bool operator <(const TPDiskKey& x, const TPDiskKey& y) {
+ return std::make_tuple(x.NodeId, x.PDiskId) < std::make_tuple(y.NodeId, y.PDiskId);
+ }
+
+ friend bool operator ==(const TPDiskKey& x, const TPDiskKey& y) {
+ return x.NodeId == y.NodeId && x.PDiskId == y.PDiskId;
+ }
+ };
+
+ struct TUnreportedMetricTag {};
+
+ struct TPDiskRecord
+ : TIntrusiveListItem<TPDiskRecord, TUnreportedMetricTag>
+ {
NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk Record;
- std::optional<NKikimrBlobStorage::TPDiskMetrics> PDiskMetrics;
-
- TReplQuoter::TPtr ReplPDiskReadQuoter;
- TReplQuoter::TPtr ReplPDiskWriteQuoter;
-
- TPDiskRecord(NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk record)
+ std::optional<NKikimrBlobStorage::TPDiskMetrics> PDiskMetrics;
+
+ TReplQuoter::TPtr ReplPDiskReadQuoter;
+ TReplQuoter::TPtr ReplPDiskWriteQuoter;
+
+ TPDiskRecord(NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk record)
: Record(std::move(record))
- {}
- };
-
- class TNodeWarden : public TActorBootstrapped<TNodeWarden> {
- TIntrusivePtr<TNodeWardenConfig> Cfg;
- TIntrusivePtr<TDsProxyNodeMon> DsProxyNodeMon;
+ {}
+ };
+
+ class TNodeWarden : public TActorBootstrapped<TNodeWarden> {
+ TIntrusivePtr<TNodeWardenConfig> Cfg;
+ TIntrusivePtr<TDsProxyNodeMon> DsProxyNodeMon;
TActorId DsProxyNodeMonActor;
- TIntrusivePtr<TDsProxyPerPoolCounters> DsProxyPerPoolCounters;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- ui32 LocalNodeId; // NodeId for local node
- TActorId WhiteboardId;
-
- std::map<TPDiskKey, TPDiskRecord> LocalPDisks;
- TIntrusiveList<TPDiskRecord, TUnreportedMetricTag> PDisksWithUnreportedMetrics;
+ TIntrusivePtr<TDsProxyPerPoolCounters> DsProxyPerPoolCounters;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ui32 LocalNodeId; // NodeId for local node
+ TActorId WhiteboardId;
+
+ std::map<TPDiskKey, TPDiskRecord> LocalPDisks;
+ TIntrusiveList<TPDiskRecord, TUnreportedMetricTag> PDisksWithUnreportedMetrics;
std::set<TPDiskKey> InFlightRestartedPDisks; // for sanity checks only
-
- ui64 LastScrubCookie = RandomNumber<ui64>();
-
- ui32 AvailDomainId;
- std::optional<TString> InstanceId; // instance ID of BS_CONTROLLER running this node
- TActorId PipeClientId;
-
+
+ ui64 LastScrubCookie = RandomNumber<ui64>();
+
+ ui32 AvailDomainId;
+ std::optional<TString> InstanceId; // instance ID of BS_CONTROLLER running this node
+ TActorId PipeClientId;
+
TVector<NPDisk::TDriveData> WorkingLocalDrives;
- NPDisk::TOwnerRound LocalPDiskInitOwnerRound = 1;
-
- bool IgnoreCache = false;
-
- bool EnableProxyMock = false;
+ NPDisk::TOwnerRound LocalPDiskInitOwnerRound = 1;
+
+ bool IgnoreCache = false;
+
+ bool EnableProxyMock = false;
NKikimrBlobStorage::TMockDevicesConfig MockDevicesConfig;
-
- struct TEvPrivate {
- enum EEv {
- EvSendDiskMetrics = EventSpaceBegin(TEvents::ES_PRIVATE),
+
+ struct TEvPrivate {
+ enum EEv {
+ EvSendDiskMetrics = EventSpaceBegin(TEvents::ES_PRIVATE),
EvUpdateNodeDrives,
- EvReadCache,
- EvGetGroup,
- };
-
- struct TEvSendDiskMetrics : TEventLocal<TEvSendDiskMetrics, EvSendDiskMetrics> {};
+ EvReadCache,
+ EvGetGroup,
+ };
+
+ struct TEvSendDiskMetrics : TEventLocal<TEvSendDiskMetrics, EvSendDiskMetrics> {};
struct TEvUpdateNodeDrives : TEventLocal<TEvUpdateNodeDrives, EvUpdateNodeDrives> {};
- };
-
+ };
+
TControlWrapper EnablePutBatching;
TControlWrapper EnableVPatch;
- TReplQuoter::TPtr ReplNodeRequestQuoter;
- TReplQuoter::TPtr ReplNodeResponseQuoter;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::NODE_WARDEN;
- }
-
- TNodeWarden(const TIntrusivePtr<TNodeWardenConfig> &cfg)
- : Cfg(cfg)
+ TReplQuoter::TPtr ReplNodeRequestQuoter;
+ TReplQuoter::TPtr ReplNodeResponseQuoter;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::NODE_WARDEN;
+ }
+
+ TNodeWarden(const TIntrusivePtr<TNodeWardenConfig> &cfg)
+ : Cfg(cfg)
, EnablePutBatching(Cfg->FeatureFlags.GetEnablePutBatchingForBlobStorage(), false, true)
, EnableVPatch(Cfg->FeatureFlags.GetEnableVPatch(), false, true)
- {
- Y_VERIFY(Cfg->ServiceSet.AvailabilityDomainsSize() <= 1);
- AvailDomainId = 1;
- for (const auto& domain : Cfg->ServiceSet.GetAvailabilityDomains()) {
- AvailDomainId = domain;
- }
- }
-
- NPDisk::TOwnerRound NextLocalPDiskInitOwnerRound() {
- LocalPDiskInitOwnerRound++;
- return LocalPDiskInitOwnerRound;
- }
-
+ {
+ Y_VERIFY(Cfg->ServiceSet.AvailabilityDomainsSize() <= 1);
+ AvailDomainId = 1;
+ for (const auto& domain : Cfg->ServiceSet.GetAvailabilityDomains()) {
+ AvailDomainId = domain;
+ }
+ }
+
+ NPDisk::TOwnerRound NextLocalPDiskInitOwnerRound() {
+ LocalPDiskInitOwnerRound++;
+ return LocalPDiskInitOwnerRound;
+ }
+
TIntrusivePtr<TPDiskConfig> CreatePDiskConfig(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk);
- void StartLocalPDisk(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk);
+ void StartLocalPDisk(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk);
void RestartLocalPDiskStart(ui32 pdiskId, TIntrusivePtr<TPDiskConfig> pdiskConfig);
void RestartLocalPDiskFinish(ui32 pdiskId, NKikimrProto::EReplyStatus status);
- void DestroyLocalPDisk(ui32 pdiskId);
-
- void ApplyServiceSetPDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDisks
-
- void ApplyServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet &serviceSet,
- bool isStatic, bool comprehensive, bool updateCache);
-
- void ConfigureLocalProxy(TIntrusivePtr<TBlobStorageGroupInfo> bsInfo);
- TActorId StartEjectedProxy(ui32 groupId);
- void StartInvalidGroupProxy();
- void StopInvalidGroupProxy();
- void StartLocalProxy(ui32 groupId);
- void StartStaticProxies();
-
+ void DestroyLocalPDisk(ui32 pdiskId);
+
+ void ApplyServiceSetPDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDisks
+
+ void ApplyServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet &serviceSet,
+ bool isStatic, bool comprehensive, bool updateCache);
+
+ void ConfigureLocalProxy(TIntrusivePtr<TBlobStorageGroupInfo> bsInfo);
+ TActorId StartEjectedProxy(ui32 groupId);
+ void StartInvalidGroupProxy();
+ void StopInvalidGroupProxy();
+ void StartLocalProxy(ui32 groupId);
+ void StartStaticProxies();
+
TVector<NPDisk::TDriveData> ListLocalDrives();
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Pipe management
-
- void SendToController(std::unique_ptr<IEventBase> ev, ui64 cookie = 0);
-
- void EstablishPipe();
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev);
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev);
- void OnPipeError();
-
- void SendRegisterNode();
- void SendInitialGroupRequests();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Actor methods
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void PassAway() override;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Group statistics reporting
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TAggregatorInfo {
- ui32 GroupId;
- TGroupStat Stat;
- };
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Pipe management
+
+ void SendToController(std::unique_ptr<IEventBase> ev, ui64 cookie = 0);
+
+ void EstablishPipe();
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev);
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev);
+ void OnPipeError();
+
+ void SendRegisterNode();
+ void SendInitialGroupRequests();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Actor methods
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void PassAway() override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Group statistics reporting
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TAggregatorInfo {
+ ui32 GroupId;
+ TGroupStat Stat;
+ };
+
TSet<TActorId> RunningVDiskServiceIds;
TMap<TActorId, TAggregatorInfo> PerAggregatorInfo;
-
- void ReportLatencies();
- void Handle(TEvGroupStatReport::TPtr ev);
- void StartAggregator(const TActorId& vdiskServiceId, ui32 groupId);
- void StopAggregator(const TActorId& vdiskServiceId);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDisk management code
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TVSlotId {
- const ui32 NodeId;
- const ui32 PDiskId;
- const ui32 VDiskSlotId;
-
- TVSlotId(ui32 nodeId, ui32 pdiskId, ui32 vdiskSlotId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- , VDiskSlotId(vdiskSlotId)
- {}
-
- TVSlotId(const NKikimrBlobStorage::TVDiskLocation& proto)
- : TVSlotId(proto.GetNodeID(), proto.GetPDiskID(), proto.GetVDiskSlotID())
- {}
-
- TVSlotId(const NKikimrBlobStorage::TVSlotId& proto)
- : TVSlotId(proto.GetNodeId(), proto.GetPDiskId(), proto.GetVSlotId())
- {}
-
- TActorId GetVDiskServiceId() const {
- return MakeBlobStorageVDiskID(NodeId, PDiskId, VDiskSlotId);
- }
-
- auto AsTuple() const { return std::make_tuple(NodeId, PDiskId, VDiskSlotId); }
- friend bool operator <(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() < y.AsTuple(); }
- friend bool operator <=(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() <= y.AsTuple(); }
- friend bool operator ==(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() == y.AsTuple(); }
- };
-
- struct TGroupRelationTag {};
-
- struct TVDiskRecord
- : TIntrusiveListItem<TVDiskRecord, TGroupRelationTag>
- , TIntrusiveListItem<TVDiskRecord, TUnreportedMetricTag>
- {
- // Configuration of VDisk never changes since VDisk is created. The only possible actions are:
- // 1. Wiping the disk.
- // 2. Incrementing generation.
- // 3. Becoming a donor.
- // 4. Deleting disk.
- NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk Config;
-
- // Runtime configuration of VDisk.
- struct TRuntimeData {
- TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
- ui32 OrderNumber;
- bool DonorMode;
- };
- std::optional<TRuntimeData> RuntimeData;
-
- // Last VDiskId reported to Node Whiteboard.
- std::optional<TVDiskID> WhiteboardVDiskId;
-
- bool SlayInFlight = false;
-
- NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
- std::optional<NKikimrBlobStorage::EVDiskStatus> ReportedVDiskStatus; // last reported to BSC
-
- enum EScrubState : ui32 {
- IDLE,
- QUERY_START_QUANTUM,
- IN_PROGRESS,
- QUANTUM_FINISHED,
- QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE,
- } ScrubState = EScrubState::IDLE;
-
- NKikimrBlobStorage::TEvControllerScrubQuantumFinished QuantumFinished; // message to be sent
- ui64 ScrubCookie = 0; // cookie used to match QueryStartQuantum requests with StartQuantum responses
- ui64 ScrubCookieForController = 0; // cookie used to communicate with BS_CONTROLLER
-
- std::optional<NKikimrBlobStorage::TVDiskMetrics> VDiskMetrics;
-
- // this flag is only used to cooperate between PDisk and VDisk code while processing service set update;
- // it should never escape the ApplyServiceSet() function
- bool UnderlyingPDiskDestroyed = false;
-
- ui32 GetGroupId() const {
- return Config.GetVDiskID().GetGroupID();
- }
-
- TVSlotId GetVSlotId() const {
- const auto& loc = Config.GetVDiskLocation();
- return {loc.GetNodeID(), loc.GetPDiskID(), loc.GetVDiskSlotID()};
- }
-
- TVDiskID GetVDiskId() const {
- const auto& vdiskId = VDiskIDFromVDiskID(Config.GetVDiskID());
- const ui32 generation = RuntimeData
- ? RuntimeData->GroupInfo->GroupGeneration
- : vdiskId.GroupGeneration;
- return TVDiskID(vdiskId.GroupID, generation, vdiskId);
- }
-
- TActorId GetVDiskServiceId() const {
- return GetVSlotId().GetVDiskServiceId();
- }
- };
-
- std::map<TVSlotId, TVDiskRecord> LocalVDisks;
- TIntrusiveList<TVDiskRecord, TUnreportedMetricTag> VDisksWithUnreportedMetrics;
-
- void DestroyLocalVDisk(TVDiskRecord& vdisk);
- void PoisonLocalVDisk(TVDiskRecord& vdisk);
- void StartLocalVDiskActor(TVDiskRecord& vdisk, TDuration yardInitDelay);
- void ApplyServiceSetVDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
-
- // process VDisk configuration
- void ApplyLocalVDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk);
-
- void Slay(TVDiskRecord& vdisk);
-
- void UpdateGroupInfoForDisk(TVDiskRecord& vdisk, const TIntrusivePtr<TBlobStorageGroupInfo>& newInfo);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Sync operation queue
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- std::queue<std::unique_ptr<IActor>> SyncOpQ;
+
+ void ReportLatencies();
+ void Handle(TEvGroupStatReport::TPtr ev);
+ void StartAggregator(const TActorId& vdiskServiceId, ui32 groupId);
+ void StopAggregator(const TActorId& vdiskServiceId);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDisk management code
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TVSlotId {
+ const ui32 NodeId;
+ const ui32 PDiskId;
+ const ui32 VDiskSlotId;
+
+ TVSlotId(ui32 nodeId, ui32 pdiskId, ui32 vdiskSlotId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VDiskSlotId(vdiskSlotId)
+ {}
+
+ TVSlotId(const NKikimrBlobStorage::TVDiskLocation& proto)
+ : TVSlotId(proto.GetNodeID(), proto.GetPDiskID(), proto.GetVDiskSlotID())
+ {}
+
+ TVSlotId(const NKikimrBlobStorage::TVSlotId& proto)
+ : TVSlotId(proto.GetNodeId(), proto.GetPDiskId(), proto.GetVSlotId())
+ {}
+
+ TActorId GetVDiskServiceId() const {
+ return MakeBlobStorageVDiskID(NodeId, PDiskId, VDiskSlotId);
+ }
+
+ auto AsTuple() const { return std::make_tuple(NodeId, PDiskId, VDiskSlotId); }
+ friend bool operator <(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() < y.AsTuple(); }
+ friend bool operator <=(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() <= y.AsTuple(); }
+ friend bool operator ==(const TVSlotId& x, const TVSlotId& y) { return x.AsTuple() == y.AsTuple(); }
+ };
+
+ struct TGroupRelationTag {};
+
+ struct TVDiskRecord
+ : TIntrusiveListItem<TVDiskRecord, TGroupRelationTag>
+ , TIntrusiveListItem<TVDiskRecord, TUnreportedMetricTag>
+ {
+ // Configuration of VDisk never changes since VDisk is created. The only possible actions are:
+ // 1. Wiping the disk.
+ // 2. Incrementing generation.
+ // 3. Becoming a donor.
+ // 4. Deleting disk.
+ NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk Config;
+
+ // Runtime configuration of VDisk.
+ struct TRuntimeData {
+ TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
+ ui32 OrderNumber;
+ bool DonorMode;
+ };
+ std::optional<TRuntimeData> RuntimeData;
+
+ // Last VDiskId reported to Node Whiteboard.
+ std::optional<TVDiskID> WhiteboardVDiskId;
+
+ bool SlayInFlight = false;
+
+ NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+ std::optional<NKikimrBlobStorage::EVDiskStatus> ReportedVDiskStatus; // last reported to BSC
+
+ enum EScrubState : ui32 {
+ IDLE,
+ QUERY_START_QUANTUM,
+ IN_PROGRESS,
+ QUANTUM_FINISHED,
+ QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE,
+ } ScrubState = EScrubState::IDLE;
+
+ NKikimrBlobStorage::TEvControllerScrubQuantumFinished QuantumFinished; // message to be sent
+ ui64 ScrubCookie = 0; // cookie used to match QueryStartQuantum requests with StartQuantum responses
+ ui64 ScrubCookieForController = 0; // cookie used to communicate with BS_CONTROLLER
+
+ std::optional<NKikimrBlobStorage::TVDiskMetrics> VDiskMetrics;
+
+ // this flag is only used to cooperate between PDisk and VDisk code while processing service set update;
+ // it should never escape the ApplyServiceSet() function
+ bool UnderlyingPDiskDestroyed = false;
+
+ ui32 GetGroupId() const {
+ return Config.GetVDiskID().GetGroupID();
+ }
+
+ TVSlotId GetVSlotId() const {
+ const auto& loc = Config.GetVDiskLocation();
+ return {loc.GetNodeID(), loc.GetPDiskID(), loc.GetVDiskSlotID()};
+ }
+
+ TVDiskID GetVDiskId() const {
+ const auto& vdiskId = VDiskIDFromVDiskID(Config.GetVDiskID());
+ const ui32 generation = RuntimeData
+ ? RuntimeData->GroupInfo->GroupGeneration
+ : vdiskId.GroupGeneration;
+ return TVDiskID(vdiskId.GroupID, generation, vdiskId);
+ }
+
+ TActorId GetVDiskServiceId() const {
+ return GetVSlotId().GetVDiskServiceId();
+ }
+ };
+
+ std::map<TVSlotId, TVDiskRecord> LocalVDisks;
+ TIntrusiveList<TVDiskRecord, TUnreportedMetricTag> VDisksWithUnreportedMetrics;
+
+ void DestroyLocalVDisk(TVDiskRecord& vdisk);
+ void PoisonLocalVDisk(TVDiskRecord& vdisk);
+ void StartLocalVDiskActor(TVDiskRecord& vdisk, TDuration yardInitDelay);
+ void ApplyServiceSetVDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
+
+ // process VDisk configuration
+ void ApplyLocalVDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk);
+
+ void Slay(TVDiskRecord& vdisk);
+
+ void UpdateGroupInfoForDisk(TVDiskRecord& vdisk, const TIntrusivePtr<TBlobStorageGroupInfo>& newInfo);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Sync operation queue
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ std::queue<std::unique_ptr<IActor>> SyncOpQ;
TActorId SyncActorId;
-
- void InvokeSyncOp(std::unique_ptr<IActor> actor);
- void Handle(TEvents::TEvInvokeResult::TPtr ev);
- void EnqueueSyncOp(std::function<std::function<void()>(const TActorContext&)> callback);
-
- using TWrappedCacheOp = std::function<std::function<void()>(NKikimrBlobStorage::TNodeWardenServiceSet*)>;
- std::function<std::function<void()>(const TActorContext&)> WrapCacheOp(TWrappedCacheOp operation);
-
- TWrappedCacheOp UpdateGroupInCache(const NKikimrBlobStorage::TGroupInfo& group);
- TWrappedCacheOp UpdateServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& newServices, bool comprehensive,
- std::function<void()> tail);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // NW group handling code
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- enum class EGroupInfoOrigin {
- BSC,
- GROUP_RESOLVER,
- DSPROXY,
- VDISK,
- };
-
- struct TGroupRecord {
- TIntrusivePtr<TBlobStorageGroupInfo> Info; // current group info
- ui32 MaxKnownGeneration = 0; // maximum seen generation
- std::optional<NKikimrBlobStorage::TGroupInfo> Group; // group info as a protobuf
- NKikimrBlobStorage::TGroupInfo EncryptionParams; // latest encryption parameters; set only when encryption enabled; overlay in respect to Group
- bool ProxyRunning = false;
- bool GetGroupRequestPending = false; // if true, then we are waiting for GetGroup response for this group
- bool ProposeRequestPending = false; // if true, then we have sent ProposeKey request and waiting for the group
- TActorId GroupResolver; // resolver actor id
- TIntrusiveList<TVDiskRecord, TGroupRelationTag> VDisksOfGroup;
- };
-
- std::unordered_map<ui32, TGroupRecord> Groups;
- std::unordered_set<ui32> EjectedGroups;
-
- // this function returns group info if possible, or otherwise starts requesting group info and/or proposing key
- // if needed
- TIntrusivePtr<TBlobStorageGroupInfo> NeedGroupInfo(ui32 groupId);
-
- // propose group key
- void ProposeKey(ui32 groupId, const TEncryptionKey& mainKey, const NKikimrBlobStorage::TGroupInfo& encryptionParams);
-
- // get encryption key for the group
- TEncryptionKey& GetGroupMainKey(ui32 groupId);
-
- // process group information structure
- void ApplyGroupInfo(ui32 groupId, ui32 generation, const NKikimrBlobStorage::TGroupInfo *newGroup, bool fromController,
- bool fromResolver);
-
- // issue GetGroup request to BSC/GroupResolver actor
- void RequestGroupConfig(ui32 groupId, TGroupRecord& group);
-
- // process group information from the configuration message
- void ApplyGroupInfoFromServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
-
- // process group information obtained by one of managed entities
- void Handle(TEvBlobStorage::TEvUpdateGroupInfo::TPtr ev);
-
- void HandleGetGroup(TAutoPtr<IEventHandle> ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
+ void InvokeSyncOp(std::unique_ptr<IActor> actor);
+ void Handle(TEvents::TEvInvokeResult::TPtr ev);
+ void EnqueueSyncOp(std::function<std::function<void()>(const TActorContext&)> callback);
+
+ using TWrappedCacheOp = std::function<std::function<void()>(NKikimrBlobStorage::TNodeWardenServiceSet*)>;
+ std::function<std::function<void()>(const TActorContext&)> WrapCacheOp(TWrappedCacheOp operation);
+
+ TWrappedCacheOp UpdateGroupInCache(const NKikimrBlobStorage::TGroupInfo& group);
+ TWrappedCacheOp UpdateServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& newServices, bool comprehensive,
+ std::function<void()> tail);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // NW group handling code
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ enum class EGroupInfoOrigin {
+ BSC,
+ GROUP_RESOLVER,
+ DSPROXY,
+ VDISK,
+ };
+
+ struct TGroupRecord {
+ TIntrusivePtr<TBlobStorageGroupInfo> Info; // current group info
+ ui32 MaxKnownGeneration = 0; // maximum seen generation
+ std::optional<NKikimrBlobStorage::TGroupInfo> Group; // group info as a protobuf
+ NKikimrBlobStorage::TGroupInfo EncryptionParams; // latest encryption parameters; set only when encryption enabled; overlay in respect to Group
+ bool ProxyRunning = false;
+ bool GetGroupRequestPending = false; // if true, then we are waiting for GetGroup response for this group
+ bool ProposeRequestPending = false; // if true, then we have sent ProposeKey request and waiting for the group
+ TActorId GroupResolver; // resolver actor id
+ TIntrusiveList<TVDiskRecord, TGroupRelationTag> VDisksOfGroup;
+ };
+
+ std::unordered_map<ui32, TGroupRecord> Groups;
+ std::unordered_set<ui32> EjectedGroups;
+
+ // this function returns group info if possible, or otherwise starts requesting group info and/or proposing key
+ // if needed
+ TIntrusivePtr<TBlobStorageGroupInfo> NeedGroupInfo(ui32 groupId);
+
+ // propose group key
+ void ProposeKey(ui32 groupId, const TEncryptionKey& mainKey, const NKikimrBlobStorage::TGroupInfo& encryptionParams);
+
+ // get encryption key for the group
+ TEncryptionKey& GetGroupMainKey(ui32 groupId);
+
+ // process group information structure
+ void ApplyGroupInfo(ui32 groupId, ui32 generation, const NKikimrBlobStorage::TGroupInfo *newGroup, bool fromController,
+ bool fromResolver);
+
+ // issue GetGroup request to BSC/GroupResolver actor
+ void RequestGroupConfig(ui32 groupId, TGroupRecord& group);
+
+ // process group information from the configuration message
+ void ApplyGroupInfoFromServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet);
+
+ // process group information obtained by one of managed entities
+ void Handle(TEvBlobStorage::TEvUpdateGroupInfo::TPtr ev);
+
+ void HandleGetGroup(TAutoPtr<IEventHandle> ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
std::map<TActorId, std::deque<std::unique_ptr<IEventHandle>>> PendingMessageQ;
-
+
void RegisterPendingActor(const TActorId& actorId);
- void EnqueuePendingMessage(TAutoPtr<IEventHandle> ev);
- void IssuePendingMessages(const TActorId& actorId);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Bootstrap();
- void HandleReadCache();
- void Handle(TEvInterconnect::TEvNodeInfo::TPtr ev);
- void Handle(NPDisk::TEvSlayResult::TPtr ev);
- void Handle(TEvRegisterPDiskLoadActor::TPtr ev);
- void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev);
-
- void SendDropDonorQuery(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId);
-
- void SendVDiskReport(TVSlotId vslotId, const TVDiskID& vdiskId,
- NKikimrBlobStorage::TEvControllerNodeReport::EVDiskPhase phase);
-
- void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr ev);
- void Handle(TEvPrivate::TEvSendDiskMetrics::TPtr&);
+ void EnqueuePendingMessage(TAutoPtr<IEventHandle> ev);
+ void IssuePendingMessages(const TActorId& actorId);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void Bootstrap();
+ void HandleReadCache();
+ void Handle(TEvInterconnect::TEvNodeInfo::TPtr ev);
+ void Handle(NPDisk::TEvSlayResult::TPtr ev);
+ void Handle(TEvRegisterPDiskLoadActor::TPtr ev);
+ void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev);
+
+ void SendDropDonorQuery(ui32 nodeId, ui32 pdiskId, ui32 vslotId, const TVDiskID& vdiskId);
+
+ void SendVDiskReport(TVSlotId vslotId, const TVDiskID& vdiskId,
+ NKikimrBlobStorage::TEvControllerNodeReport::EVDiskPhase phase);
+
+ void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr ev);
+ void Handle(TEvPrivate::TEvSendDiskMetrics::TPtr&);
void Handle(TEvPrivate::TEvUpdateNodeDrives ::TPtr&);
void Handle(NMon::TEvHttpInfo::TPtr&);
void RenderJsonGroupInfo(IOutputStream& out, const std::set<ui32>& groupIds);
@@ -410,106 +410,106 @@ namespace NKikimr::NStorage {
void RenderLocalDrives(IOutputStream&);
void RenderDSProxies(IOutputStream& out);
- void SendDiskMetrics(bool reportMetrics);
- void Handle(TEvStatusUpdate::TPtr ev);
-
- void Handle(TEvBlobStorage::TEvDropDonor::TPtr ev);
+ void SendDiskMetrics(bool reportMetrics);
+ void Handle(TEvStatusUpdate::TPtr ev);
+
+ void Handle(TEvBlobStorage::TEvDropDonor::TPtr ev);
void Handle(TEvBlobStorage::TEvAskRestartPDisk::TPtr ev);
void Handle(TEvBlobStorage::TEvRestartPDiskResult::TPtr ev);
-
- void FillInVDiskStatus(google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus> *pb, bool initial);
-
- void HandleForwarded(TAutoPtr<::NActors::IEventHandle> &ev);
- void HandleIncrHugeInit(NIncrHuge::TEvIncrHugeInit::TPtr ev);
-
- void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev); // from VDisk
- void Handle(TEvBlobStorage::TEvControllerScrubStartQuantum::TPtr ev); // from BSC
- void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev); // from VDisk
- void SendScrubRequests();
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TGroupResolverContext : TThrRefBase {
- struct TImpl;
- std::unique_ptr<TImpl> Impl;
- TGroupResolverContext();
- ~TGroupResolverContext();
- };
- TIntrusivePtr<TGroupResolverContext> GroupResolverContext = MakeIntrusive<TGroupResolverContext>();
-
- class TGroupResolverActor;
-
- IActor *CreateGroupResolverActor(ui32 groupId);
- void Handle(TEvNodeWardenQueryGroupInfo::TPtr ev);
-
- STATEFN(StateOnline) {
- switch (ev->GetTypeRewrite()) {
- fFunc(TEvBlobStorage::TEvPut::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvGet::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvBlock::EventType, HandleForwarded);
+
+ void FillInVDiskStatus(google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus> *pb, bool initial);
+
+ void HandleForwarded(TAutoPtr<::NActors::IEventHandle> &ev);
+ void HandleIncrHugeInit(NIncrHuge::TEvIncrHugeInit::TPtr ev);
+
+ void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev); // from VDisk
+ void Handle(TEvBlobStorage::TEvControllerScrubStartQuantum::TPtr ev); // from BSC
+ void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev); // from VDisk
+ void SendScrubRequests();
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TGroupResolverContext : TThrRefBase {
+ struct TImpl;
+ std::unique_ptr<TImpl> Impl;
+ TGroupResolverContext();
+ ~TGroupResolverContext();
+ };
+ TIntrusivePtr<TGroupResolverContext> GroupResolverContext = MakeIntrusive<TGroupResolverContext>();
+
+ class TGroupResolverActor;
+
+ IActor *CreateGroupResolverActor(ui32 groupId);
+ void Handle(TEvNodeWardenQueryGroupInfo::TPtr ev);
+
+ STATEFN(StateOnline) {
+ switch (ev->GetTypeRewrite()) {
+ fFunc(TEvBlobStorage::TEvPut::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvGet::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvBlock::EventType, HandleForwarded);
fFunc(TEvBlobStorage::TEvPatch::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvDiscover::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvRange::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvCollectGarbage::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvStatus::EventType, HandleForwarded);
- fFunc(TEvBlobStorage::TEvBunchOfEvents::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvDiscover::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvRange::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvCollectGarbage::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvStatus::EventType, HandleForwarded);
+ fFunc(TEvBlobStorage::TEvBunchOfEvents::EventType, HandleForwarded);
fFunc(TEvRequestProxySessionsState::EventType, HandleForwarded);
-
- hFunc(NIncrHuge::TEvIncrHugeInit, HandleIncrHugeInit);
-
- hFunc(TEvInterconnect::TEvNodeInfo, Handle);
-
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
-
- hFunc(NPDisk::TEvSlayResult, Handle);
-
- hFunc(TEvRegisterPDiskLoadActor, Handle);
-
- hFunc(TEvStatusUpdate, Handle);
- hFunc(TEvBlobStorage::TEvDropDonor, Handle);
+
+ hFunc(NIncrHuge::TEvIncrHugeInit, HandleIncrHugeInit);
+
+ hFunc(TEvInterconnect::TEvNodeInfo, Handle);
+
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+
+ hFunc(NPDisk::TEvSlayResult, Handle);
+
+ hFunc(TEvRegisterPDiskLoadActor, Handle);
+
+ hFunc(TEvStatusUpdate, Handle);
+ hFunc(TEvBlobStorage::TEvDropDonor, Handle);
hFunc(TEvBlobStorage::TEvAskRestartPDisk, Handle);
hFunc(TEvBlobStorage::TEvRestartPDiskResult, Handle);
-
- hFunc(TEvGroupStatReport, Handle);
-
- hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
- hFunc(TEvBlobStorage::TEvUpdateGroupInfo, Handle);
- hFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
- hFunc(TEvPrivate::TEvSendDiskMetrics, Handle);
+
+ hFunc(TEvGroupStatReport, Handle);
+
+ hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
+ hFunc(TEvBlobStorage::TEvUpdateGroupInfo, Handle);
+ hFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
+ hFunc(TEvPrivate::TEvSendDiskMetrics, Handle);
hFunc(TEvPrivate::TEvUpdateNodeDrives, Handle);
hFunc(NMon::TEvHttpInfo, Handle);
- cFunc(NActors::TEvents::TSystem::Poison, PassAway);
-
- hFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum, Handle);
- hFunc(TEvBlobStorage::TEvControllerScrubStartQuantum, Handle);
- hFunc(TEvBlobStorage::TEvControllerScrubQuantumFinished, Handle);
-
- hFunc(TEvents::TEvInvokeResult, Handle);
-
- hFunc(TEvNodeWardenQueryGroupInfo, Handle);
-
- // proxy requests for the NodeWhiteboard to prevent races
- hFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate, Handle);
-
- // ignore as it is used only in response to DropDonorDisk cmd
- IgnoreFunc(TEvBlobStorage::TEvControllerConfigResponse);
-
- cFunc(TEvPrivate::EvReadCache, HandleReadCache);
- fFunc(TEvPrivate::EvGetGroup, HandleGetGroup);
-
- default:
- EnqueuePendingMessage(ev);
- break;
- }
- }
- };
-
-}
-
-template<>
-inline void Out<NKikimr::NStorage::TNodeWarden::TVSlotId>(IOutputStream& o, const NKikimr::NStorage::TNodeWarden::TVSlotId& x) {
- o << x.NodeId << ":" << x.PDiskId << ":" << x.VDiskSlotId;
-}
+ cFunc(NActors::TEvents::TSystem::Poison, PassAway);
+
+ hFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum, Handle);
+ hFunc(TEvBlobStorage::TEvControllerScrubStartQuantum, Handle);
+ hFunc(TEvBlobStorage::TEvControllerScrubQuantumFinished, Handle);
+
+ hFunc(TEvents::TEvInvokeResult, Handle);
+
+ hFunc(TEvNodeWardenQueryGroupInfo, Handle);
+
+ // proxy requests for the NodeWhiteboard to prevent races
+ hFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate, Handle);
+
+ // ignore as it is used only in response to DropDonorDisk cmd
+ IgnoreFunc(TEvBlobStorage::TEvControllerConfigResponse);
+
+ cFunc(TEvPrivate::EvReadCache, HandleReadCache);
+ fFunc(TEvPrivate::EvGetGroup, HandleGetGroup);
+
+ default:
+ EnqueuePendingMessage(ev);
+ break;
+ }
+ }
+ };
+
+}
+
+template<>
+inline void Out<NKikimr::NStorage::TNodeWarden::TVSlotId>(IOutputStream& o, const NKikimr::NStorage::TNodeWarden::TVSlotId& x) {
+ o << x.NodeId << ":" << x.PDiskId << ":" << x.VDiskSlotId;
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_mon.cpp b/ydb/core/blobstorage/nodewarden/node_warden_mon.cpp
index 79568dbe87b..1a6186abc9b 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_mon.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_mon.cpp
@@ -42,8 +42,8 @@ void TNodeWarden::Handle(NMon::TEvHttpInfo::TPtr &ev) {
void TNodeWarden::RenderJsonGroupInfo(IOutputStream& out, const std::set<ui32>& groupIds) {
std::set<ui32> allGroups;
if (groupIds.empty()) {
- allGroups.insert(EjectedGroups.begin(), EjectedGroups.end());
- for (const auto& [groupId, _] : Groups) {
+ allGroups.insert(EjectedGroups.begin(), EjectedGroups.end());
+ for (const auto& [groupId, _] : Groups) {
allGroups.emplace(groupId);
}
}
@@ -51,27 +51,27 @@ void TNodeWarden::RenderJsonGroupInfo(IOutputStream& out, const std::set<ui32>&
NJson::TJsonArray array;
for (auto& groupId : (!groupIds.empty() ? groupIds : allGroups)) {
NJson::TJsonValue groupInfo;
+
+ groupInfo["GroupId"] = groupId;
+
+ if (EjectedGroups.count(groupId)) {
+ groupInfo["Status"] = "ejected";
+ } else {
+ TGroupRecord& group = Groups[groupId];
+ groupInfo["Status"] = group.ProxyRunning ? "started" : "stopped";
- groupInfo["GroupId"] = groupId;
+ if (const auto& info = group.Info) {
+ groupInfo["Generation"] = info->GroupGeneration;
+ groupInfo["ErasureType"] = info->Type.ToString();
+ groupInfo["EncryptionMode"] = TStringBuilder() << info->GetEncryptionMode();
+ groupInfo["LifeCyclePhase"] = TStringBuilder() << info->GetLifeCyclePhase();
- if (EjectedGroups.count(groupId)) {
- groupInfo["Status"] = "ejected";
- } else {
- TGroupRecord& group = Groups[groupId];
- groupInfo["Status"] = group.ProxyRunning ? "started" : "stopped";
-
- if (const auto& info = group.Info) {
- groupInfo["Generation"] = info->GroupGeneration;
- groupInfo["ErasureType"] = info->Type.ToString();
- groupInfo["EncryptionMode"] = TStringBuilder() << info->GetEncryptionMode();
- groupInfo["LifeCyclePhase"] = TStringBuilder() << info->GetLifeCyclePhase();
-
- NJson::TJsonArray vdisks;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- vdisks.AppendValue(info->GetVDiskId(i).ToString());
- }
- groupInfo["VDisks"] = std::move(vdisks);
- }
+ NJson::TJsonArray vdisks;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ vdisks.AppendValue(info->GetVDiskId(i).ToString());
+ }
+ groupInfo["VDisks"] = std::move(vdisks);
+ }
}
array.AppendValue(std::move(groupInfo));
@@ -89,7 +89,7 @@ void TNodeWarden::RenderWholePage(IOutputStream& out) {
</style>
)__";
- H2() { out << "NodeWarden on node " << LocalNodeId; }
+ H2() { out << "NodeWarden on node " << LocalNodeId; }
RenderLocalDrives(out);
H3() { out << "PDisks"; }
@@ -120,7 +120,7 @@ void TNodeWarden::RenderWholePage(IOutputStream& out) {
TABLER() {
TABLEH() { out << "Location (NodeId, PDiskId, VSlotId)"; }
TABLEH() { out << "VDiskId"; }
- TABLEH() { out << "Running"; }
+ TABLEH() { out << "Running"; }
TABLEH() { out << "StoragePoolName"; }
TABLEH() { out << "DonorMode"; }
TABLEH() { out << "CurrentStatus"; }
@@ -131,12 +131,12 @@ void TNodeWarden::RenderWholePage(IOutputStream& out) {
for (auto& [key, value] : LocalVDisks) {
TABLER() {
TABLED() { out << "(" << key.NodeId << "," << key.PDiskId << "," << key.VDiskSlotId << ")"; }
- TABLED() { out << value.GetVDiskId(); }
- TABLED() { out << (value.RuntimeData ? "true" : "false"); }
- TABLED() { out << value.Config.GetStoragePoolName(); }
- TABLED() { out << (value.Config.HasDonorMode() ? "true" : "false"); }
+ TABLED() { out << value.GetVDiskId(); }
+ TABLED() { out << (value.RuntimeData ? "true" : "false"); }
+ TABLED() { out << value.Config.GetStoragePoolName(); }
+ TABLED() { out << (value.Config.HasDonorMode() ? "true" : "false"); }
TABLED() {
- out << value.Status;
+ out << value.Status;
}
TABLED() {
if (value.ReportedVDiskStatus) {
@@ -218,16 +218,16 @@ void TNodeWarden::RenderDSProxies(IOutputStream& out) {
out << "</table>";
};
- ui32 numStarted = 0, numEjected = EjectedGroups.size();
- for (const auto& [groupId, group] : Groups) {
- numStarted += group.ProxyRunning;
- }
-
+ ui32 numStarted = 0, numEjected = EjectedGroups.size();
+ for (const auto& [groupId, group] : Groups) {
+ numStarted += group.ProxyRunning;
+ }
+
H3() { out << "Started DSProxies"; }
- createTable(out, "started", numStarted);
+ createTable(out, "started", numStarted);
H3() { out << "Ejected DSProxies"; }
- createTable(out, "ejected", numEjected);
+ createTable(out, "ejected", numEjected);
}
}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp b/ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp
index 07adc41be7a..238e8bd14b4 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_pdisk.cpp
@@ -1,220 +1,220 @@
-#include "node_warden_impl.h"
-
+#include "node_warden_impl.h"
+
#include <ydb/core/blobstorage/crypto/default.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_util_wcache.h>
#include <ydb/library/pdisk_io/file_params.h>
-
-#include <util/string/split.h>
-
-namespace NKikimr::NStorage {
-
- static const std::unordered_map<TPDiskCategory::EDeviceType, ui64> DefaultSpeedLimit{
- {TPDiskCategory::DEVICE_TYPE_ROT, 100000000},
- {TPDiskCategory::DEVICE_TYPE_SSD, 200000000},
- {TPDiskCategory::DEVICE_TYPE_NVME, 300000000},
- };
-
- TIntrusivePtr<TPDiskConfig> TNodeWarden::CreatePDiskConfig(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk) {
- const TString& path = pdisk.GetPath();
- const ui64 pdiskGuid = pdisk.GetPDiskGuid();
- const ui32 pdiskID = pdisk.GetPDiskID();
- const ui64 pdiskCategory = pdisk.GetPDiskCategory();
- const ui64 inMemoryForTestsBufferBytes = pdisk.GetInMemoryForTestsBufferBytes();
- Y_VERIFY_S(!inMemoryForTestsBufferBytes, "InMemory PDisk is deprecated, use SectorMap instead");
-
- TIntrusivePtr<TPDiskConfig> pdiskConfig = new TPDiskConfig(path, pdiskGuid, pdiskID, pdiskCategory);
- pdiskConfig->StartOwnerRound = NextLocalPDiskInitOwnerRound();
- pdiskConfig->FeatureFlags = Cfg->FeatureFlags;
- if (pdisk.HasManagementStage()) {
- pdiskConfig->SerialManagementStage = pdisk.GetManagementStage();
- }
- if (pdisk.HasSpaceColorBorder()) {
- pdiskConfig->SpaceColorBorder = pdisk.GetSpaceColorBorder();
- }
- if (pdisk.HasPDiskConfig()) {
- pdiskConfig->Apply(&pdisk.GetPDiskConfig());
- }
- pdiskConfig->Apply(&Cfg->PDiskConfigOverlay);
- if (pdisk.HasExpectedSerial()) {
- pdiskConfig->ExpectedSerial = pdisk.GetExpectedSerial();
- }
-
- // Path scheme: "SectorMap:unique_name[:3000]"
- // where '3000' is device size of in GiB.
- if (path.Contains(":")) {
- TVector<TString> splitted;
- size_t tokenCount = Split(path, ":", splitted);
-
- if (splitted[0] == "SectorMap") {
- Y_VERIFY(tokenCount >= 2);
- ui64 size = (ui64)100 << 30; // 100GB is default
- if (splitted.size() >= 3) {
- size = Max(size, FromStringWithDefault<ui64>(splitted[2], size) << 30);
- }
- auto& maps = Cfg->SectorMaps;
- if (auto it = maps.find(path); it == maps.end()) {
- maps[path] = new NPDisk::TSectorMap(size);
- maps[path]->ZeroInit(1000); // Format PDisk
- }
-
- const auto& map = maps[path];
- bool found = false;
- for (const auto& drive : MockDevicesConfig.GetDevices()) {
- if (drive.GetPath() == path) {
- map->Serial = drive.GetSerialNumber();
- found = true;
- break;
- }
- }
- if (!found) {
- auto *p = MockDevicesConfig.AddDevices();
- p->SetPath(path);
- p->SetSerialNumber(map->Serial);
- p->SetFirmwareRevision("rev.1");
- p->SetModelNumber("SectorMap");
- p->SetDeviceType(NKikimrBlobStorage::NVME);
- p->SetSize(map->DeviceSize);
- p->SetIsMock(true);
-
- TString data;
- google::protobuf::TextFormat::PrintToString(MockDevicesConfig, &data);
- try {
- TFile f(MockDevicesPath, CreateAlways | WrOnly);
- f.Write(data.Data(), data.Size());
- f.Flush();
- } catch (TFileError ex) {
- STLOG(PRI_WARN, BS_NODE, NW89, "Can't write new MockDevicesConfig to file", (Path, MockDevicesPath));
- }
- }
- } else if (splitted[0] == "Serial") {
- ;
- } else if (splitted[0] == "PCIe") {
- ;
- } else {
- STLOG(PRI_ERROR, BS_NODE, NW27, "unknown pdisk path scheme", (Path, path));
- }
- }
-
- // testlib uses SectorMap with fs-style path like "/place/vartmp/tmpAMjsJ0/pdisk_1.dat"
- if (auto it = Cfg->SectorMaps.find(path); it != Cfg->SectorMaps.end()) {
- pdiskConfig->SectorMap = it->second;
- pdiskConfig->EnableSectorEncryption = !pdiskConfig->SectorMap;
- }
-
- NPDisk::TKey pdiskKey = Cfg->CreatePDiskKey();
- THashCalculator hasher;
- TString keyPrintSalt = "@N2#_lW19)2-31!iifI@n1178349617";
- hasher.Hash(keyPrintSalt.Detach(), keyPrintSalt.Size());
- hasher.Hash(&pdiskKey, sizeof(pdiskKey));
- pdiskConfig->HashedMainKey = TStringBuilder() << Hex(hasher.GetHashResult(), HF_ADDX);
-
- pdiskConfig->Initialize();
-
- return pdiskConfig;
- }
-
- void TNodeWarden::StartLocalPDisk(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk) {
- const TPDiskKey key(pdisk.GetNodeID(), pdisk.GetPDiskID());
- auto [it, inserted] = LocalPDisks.try_emplace(key, pdisk);
- TPDiskRecord& record = it->second;
- if (!inserted) {
- Y_VERIFY(record.Record.GetPDiskGuid() == pdisk.GetPDiskGuid());
- return;
- }
-
- TPDiskCategory category(record.Record.GetPDiskCategory());
- std::optional<ui64> readBytesPerSecond, writeBytesPerSecond;
- for (const auto& item : Cfg->ServiceSet.GetReplBrokerConfig().GetMediaTypeQuota()) {
- if (PDiskTypeToPDiskType(item.GetType()) == category.Type()) {
- if (item.HasReadBytesPerSecond()) {
- readBytesPerSecond.emplace(item.GetReadBytesPerSecond());
- }
- if (item.HasWriteBytesPerSecond()) {
- writeBytesPerSecond.emplace(item.GetWriteBytesPerSecond());
- }
- }
- }
- std::optional<ui64> def;
- if (const auto it = DefaultSpeedLimit.find(category.Type()); it != DefaultSpeedLimit.end()) {
- def = it->second;
- }
- readBytesPerSecond = readBytesPerSecond ? readBytesPerSecond : def;
- writeBytesPerSecond = writeBytesPerSecond ? writeBytesPerSecond : def;
- if (readBytesPerSecond) {
- record.ReplPDiskReadQuoter = std::make_shared<TReplQuoter>(*readBytesPerSecond);
- }
- if (writeBytesPerSecond) {
- record.ReplPDiskWriteQuoter = std::make_shared<TReplQuoter>(*writeBytesPerSecond);
- }
-
- STLOG(PRI_DEBUG, BS_NODE, NW04, "StartLocalPDisk", (NodeId, key.NodeId), (PDiskId, key.PDiskId),
- (Path, TString(TStringBuilder() << '"' << pdisk.GetPath() << '"')),
- (PDiskCategory, TPDiskCategory(record.Record.GetPDiskCategory())));
-
- auto pdiskConfig = CreatePDiskConfig(pdisk);
-
- const ui32 pdiskID = pdisk.GetPDiskID();
- const TString& path = pdisk.GetPath();
- const ui64 pdiskGuid = pdisk.GetPDiskGuid();
- const ui64 pdiskCategory = pdisk.GetPDiskCategory();
- Cfg->PDiskServiceFactory->Create(TActivationContext::ActorContextFor(SelfId()), pdiskID, pdiskConfig,
- Cfg->CreatePDiskKey(), AppData()->SystemPoolId, LocalNodeId);
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateUpdate(pdiskID, path, pdiskGuid, pdiskCategory));
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddRole("Storage"));
- }
-
- void TNodeWarden::DestroyLocalPDisk(ui32 pdiskId) {
- STLOG(PRI_INFO, BS_NODE, NW36, "DestroyLocalPDisk", (PDiskId, pdiskId));
- if (auto it = LocalPDisks.find({LocalNodeId, pdiskId}); it != LocalPDisks.end()) {
- const TActorId actorId = MakeBlobStoragePDiskID(LocalNodeId, pdiskId);
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateDelete(pdiskId));
- LocalPDisks.erase(it);
-
- // mark vdisks still living over this PDisk as destroyed ones
- for (auto it = LocalVDisks.lower_bound({LocalNodeId, pdiskId, 0}); it != LocalVDisks.end() &&
- it->first.NodeId == LocalNodeId && it->first.PDiskId == pdiskId; ++it) {
- it->second.UnderlyingPDiskDestroyed = true;
- }
- }
- }
-
- void TNodeWarden::RestartLocalPDiskStart(ui32 pdiskId, TIntrusivePtr<TPDiskConfig> pdiskConfig) {
- auto it = LocalPDisks.find(TPDiskKey(LocalNodeId, pdiskId));
- if (it == LocalPDisks.end()) {
- STLOG(PRI_WARN, BS_NODE, NW66, "Cannot restart local pdisk since there is no such pdisk",
- (NodeId, LocalNodeId), (PDiskId, pdiskId));
- return;
- }
-
- bool inserted = InFlightRestartedPDisks.emplace(LocalNodeId, pdiskId).second;
- if (!inserted) {
- STLOG(PRI_WARN, BS_NODE, NW67, "Cannot restart local pdisk since it already in the process of restart",
- (NodeId, LocalNodeId), (PDiskId, pdiskId));
- return;
- }
-
- const TActorId actorId = MakeBlobStoragePDiskID(LocalNodeId, pdiskId);
- Send(actorId, new TEvBlobStorage::TEvRestartPDisk(pdiskId, Cfg->CreatePDiskKey(), pdiskConfig));
- STLOG(PRI_NOTICE, BS_NODE, NW69, "RestartLocalPDisk is started", (PDiskId, pdiskId));
- }
-
+
+#include <util/string/split.h>
+
+namespace NKikimr::NStorage {
+
+ static const std::unordered_map<TPDiskCategory::EDeviceType, ui64> DefaultSpeedLimit{
+ {TPDiskCategory::DEVICE_TYPE_ROT, 100000000},
+ {TPDiskCategory::DEVICE_TYPE_SSD, 200000000},
+ {TPDiskCategory::DEVICE_TYPE_NVME, 300000000},
+ };
+
+ TIntrusivePtr<TPDiskConfig> TNodeWarden::CreatePDiskConfig(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk) {
+ const TString& path = pdisk.GetPath();
+ const ui64 pdiskGuid = pdisk.GetPDiskGuid();
+ const ui32 pdiskID = pdisk.GetPDiskID();
+ const ui64 pdiskCategory = pdisk.GetPDiskCategory();
+ const ui64 inMemoryForTestsBufferBytes = pdisk.GetInMemoryForTestsBufferBytes();
+ Y_VERIFY_S(!inMemoryForTestsBufferBytes, "InMemory PDisk is deprecated, use SectorMap instead");
+
+ TIntrusivePtr<TPDiskConfig> pdiskConfig = new TPDiskConfig(path, pdiskGuid, pdiskID, pdiskCategory);
+ pdiskConfig->StartOwnerRound = NextLocalPDiskInitOwnerRound();
+ pdiskConfig->FeatureFlags = Cfg->FeatureFlags;
+ if (pdisk.HasManagementStage()) {
+ pdiskConfig->SerialManagementStage = pdisk.GetManagementStage();
+ }
+ if (pdisk.HasSpaceColorBorder()) {
+ pdiskConfig->SpaceColorBorder = pdisk.GetSpaceColorBorder();
+ }
+ if (pdisk.HasPDiskConfig()) {
+ pdiskConfig->Apply(&pdisk.GetPDiskConfig());
+ }
+ pdiskConfig->Apply(&Cfg->PDiskConfigOverlay);
+ if (pdisk.HasExpectedSerial()) {
+ pdiskConfig->ExpectedSerial = pdisk.GetExpectedSerial();
+ }
+
+ // Path scheme: "SectorMap:unique_name[:3000]"
+ // where '3000' is device size of in GiB.
+ if (path.Contains(":")) {
+ TVector<TString> splitted;
+ size_t tokenCount = Split(path, ":", splitted);
+
+ if (splitted[0] == "SectorMap") {
+ Y_VERIFY(tokenCount >= 2);
+ ui64 size = (ui64)100 << 30; // 100GB is default
+ if (splitted.size() >= 3) {
+ size = Max(size, FromStringWithDefault<ui64>(splitted[2], size) << 30);
+ }
+ auto& maps = Cfg->SectorMaps;
+ if (auto it = maps.find(path); it == maps.end()) {
+ maps[path] = new NPDisk::TSectorMap(size);
+ maps[path]->ZeroInit(1000); // Format PDisk
+ }
+
+ const auto& map = maps[path];
+ bool found = false;
+ for (const auto& drive : MockDevicesConfig.GetDevices()) {
+ if (drive.GetPath() == path) {
+ map->Serial = drive.GetSerialNumber();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ auto *p = MockDevicesConfig.AddDevices();
+ p->SetPath(path);
+ p->SetSerialNumber(map->Serial);
+ p->SetFirmwareRevision("rev.1");
+ p->SetModelNumber("SectorMap");
+ p->SetDeviceType(NKikimrBlobStorage::NVME);
+ p->SetSize(map->DeviceSize);
+ p->SetIsMock(true);
+
+ TString data;
+ google::protobuf::TextFormat::PrintToString(MockDevicesConfig, &data);
+ try {
+ TFile f(MockDevicesPath, CreateAlways | WrOnly);
+ f.Write(data.Data(), data.Size());
+ f.Flush();
+ } catch (TFileError ex) {
+ STLOG(PRI_WARN, BS_NODE, NW89, "Can't write new MockDevicesConfig to file", (Path, MockDevicesPath));
+ }
+ }
+ } else if (splitted[0] == "Serial") {
+ ;
+ } else if (splitted[0] == "PCIe") {
+ ;
+ } else {
+ STLOG(PRI_ERROR, BS_NODE, NW27, "unknown pdisk path scheme", (Path, path));
+ }
+ }
+
+ // testlib uses SectorMap with fs-style path like "/place/vartmp/tmpAMjsJ0/pdisk_1.dat"
+ if (auto it = Cfg->SectorMaps.find(path); it != Cfg->SectorMaps.end()) {
+ pdiskConfig->SectorMap = it->second;
+ pdiskConfig->EnableSectorEncryption = !pdiskConfig->SectorMap;
+ }
+
+ NPDisk::TKey pdiskKey = Cfg->CreatePDiskKey();
+ THashCalculator hasher;
+ TString keyPrintSalt = "@N2#_lW19)2-31!iifI@n1178349617";
+ hasher.Hash(keyPrintSalt.Detach(), keyPrintSalt.Size());
+ hasher.Hash(&pdiskKey, sizeof(pdiskKey));
+ pdiskConfig->HashedMainKey = TStringBuilder() << Hex(hasher.GetHashResult(), HF_ADDX);
+
+ pdiskConfig->Initialize();
+
+ return pdiskConfig;
+ }
+
+ void TNodeWarden::StartLocalPDisk(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk) {
+ const TPDiskKey key(pdisk.GetNodeID(), pdisk.GetPDiskID());
+ auto [it, inserted] = LocalPDisks.try_emplace(key, pdisk);
+ TPDiskRecord& record = it->second;
+ if (!inserted) {
+ Y_VERIFY(record.Record.GetPDiskGuid() == pdisk.GetPDiskGuid());
+ return;
+ }
+
+ TPDiskCategory category(record.Record.GetPDiskCategory());
+ std::optional<ui64> readBytesPerSecond, writeBytesPerSecond;
+ for (const auto& item : Cfg->ServiceSet.GetReplBrokerConfig().GetMediaTypeQuota()) {
+ if (PDiskTypeToPDiskType(item.GetType()) == category.Type()) {
+ if (item.HasReadBytesPerSecond()) {
+ readBytesPerSecond.emplace(item.GetReadBytesPerSecond());
+ }
+ if (item.HasWriteBytesPerSecond()) {
+ writeBytesPerSecond.emplace(item.GetWriteBytesPerSecond());
+ }
+ }
+ }
+ std::optional<ui64> def;
+ if (const auto it = DefaultSpeedLimit.find(category.Type()); it != DefaultSpeedLimit.end()) {
+ def = it->second;
+ }
+ readBytesPerSecond = readBytesPerSecond ? readBytesPerSecond : def;
+ writeBytesPerSecond = writeBytesPerSecond ? writeBytesPerSecond : def;
+ if (readBytesPerSecond) {
+ record.ReplPDiskReadQuoter = std::make_shared<TReplQuoter>(*readBytesPerSecond);
+ }
+ if (writeBytesPerSecond) {
+ record.ReplPDiskWriteQuoter = std::make_shared<TReplQuoter>(*writeBytesPerSecond);
+ }
+
+ STLOG(PRI_DEBUG, BS_NODE, NW04, "StartLocalPDisk", (NodeId, key.NodeId), (PDiskId, key.PDiskId),
+ (Path, TString(TStringBuilder() << '"' << pdisk.GetPath() << '"')),
+ (PDiskCategory, TPDiskCategory(record.Record.GetPDiskCategory())));
+
+ auto pdiskConfig = CreatePDiskConfig(pdisk);
+
+ const ui32 pdiskID = pdisk.GetPDiskID();
+ const TString& path = pdisk.GetPath();
+ const ui64 pdiskGuid = pdisk.GetPDiskGuid();
+ const ui64 pdiskCategory = pdisk.GetPDiskCategory();
+ Cfg->PDiskServiceFactory->Create(TActivationContext::ActorContextFor(SelfId()), pdiskID, pdiskConfig,
+ Cfg->CreatePDiskKey(), AppData()->SystemPoolId, LocalNodeId);
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateUpdate(pdiskID, path, pdiskGuid, pdiskCategory));
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddRole("Storage"));
+ }
+
+ void TNodeWarden::DestroyLocalPDisk(ui32 pdiskId) {
+ STLOG(PRI_INFO, BS_NODE, NW36, "DestroyLocalPDisk", (PDiskId, pdiskId));
+ if (auto it = LocalPDisks.find({LocalNodeId, pdiskId}); it != LocalPDisks.end()) {
+ const TActorId actorId = MakeBlobStoragePDiskID(LocalNodeId, pdiskId);
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0));
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateDelete(pdiskId));
+ LocalPDisks.erase(it);
+
+ // mark vdisks still living over this PDisk as destroyed ones
+ for (auto it = LocalVDisks.lower_bound({LocalNodeId, pdiskId, 0}); it != LocalVDisks.end() &&
+ it->first.NodeId == LocalNodeId && it->first.PDiskId == pdiskId; ++it) {
+ it->second.UnderlyingPDiskDestroyed = true;
+ }
+ }
+ }
+
+ void TNodeWarden::RestartLocalPDiskStart(ui32 pdiskId, TIntrusivePtr<TPDiskConfig> pdiskConfig) {
+ auto it = LocalPDisks.find(TPDiskKey(LocalNodeId, pdiskId));
+ if (it == LocalPDisks.end()) {
+ STLOG(PRI_WARN, BS_NODE, NW66, "Cannot restart local pdisk since there is no such pdisk",
+ (NodeId, LocalNodeId), (PDiskId, pdiskId));
+ return;
+ }
+
+ bool inserted = InFlightRestartedPDisks.emplace(LocalNodeId, pdiskId).second;
+ if (!inserted) {
+ STLOG(PRI_WARN, BS_NODE, NW67, "Cannot restart local pdisk since it already in the process of restart",
+ (NodeId, LocalNodeId), (PDiskId, pdiskId));
+ return;
+ }
+
+ const TActorId actorId = MakeBlobStoragePDiskID(LocalNodeId, pdiskId);
+ Send(actorId, new TEvBlobStorage::TEvRestartPDisk(pdiskId, Cfg->CreatePDiskKey(), pdiskConfig));
+ STLOG(PRI_NOTICE, BS_NODE, NW69, "RestartLocalPDisk is started", (PDiskId, pdiskId));
+ }
+
void TNodeWarden::RestartLocalPDiskFinish(ui32 pdiskId, NKikimrProto::EReplyStatus status) {
- const TPDiskKey pdiskKey(LocalNodeId, pdiskId);
-
- size_t erasedCount = InFlightRestartedPDisks.erase(pdiskKey);
- Y_VERIFY_S(erasedCount == 1, "PDiskId# " << pdiskId << " restarted, but wasn't in the process of removal");
-
- const TVSlotId from(pdiskKey.NodeId, pdiskKey.PDiskId, 0);
- const TVSlotId to(pdiskKey.NodeId, pdiskKey.PDiskId, Max<ui32>());
-
+ const TPDiskKey pdiskKey(LocalNodeId, pdiskId);
+
+ size_t erasedCount = InFlightRestartedPDisks.erase(pdiskKey);
+ Y_VERIFY_S(erasedCount == 1, "PDiskId# " << pdiskId << " restarted, but wasn't in the process of removal");
+
+ const TVSlotId from(pdiskKey.NodeId, pdiskKey.PDiskId, 0);
+ const TVSlotId to(pdiskKey.NodeId, pdiskKey.PDiskId, Max<ui32>());
+
if (status == NKikimrProto::EReplyStatus::OK) {
TStringStream vdisks;
bool first = true;
vdisks << "{";
- for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
+ for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
auto& [key, value] = *it;
-
+
PoisonLocalVDisk(value);
vdisks << (std::exchange(first, false) ? "" : ", ") << value.GetVDiskId().ToString();
if (value.SlayInFlight) {
@@ -223,51 +223,51 @@ namespace NKikimr::NStorage {
} else {
StartLocalVDiskActor(value, TDuration::Zero());
}
- }
+ }
SendDiskMetrics(false);
vdisks << "}";
STLOG(PRI_NOTICE, BS_NODE, NW74, "RestartLocalPDisk has finished",
(PDiskId, pdiskId), (VDiskIds, vdisks.Str()));
- } else {
- for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
- auto& [key, value] = *it;
- if (!value.RuntimeData && !value.SlayInFlight) {
- StartLocalVDiskActor(value, TDuration::Zero());
- }
- }
- }
- }
-
- void TNodeWarden::ApplyServiceSetPDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
- for (const auto& pdisk : serviceSet.GetPDisks()) {
- if (!pdisk.HasNodeID() || !pdisk.HasPDiskID() || !pdisk.HasPath() || !pdisk.HasPDiskGuid() ||
- pdisk.GetNodeID() != LocalNodeId) {
- continue;
- }
-
- auto entityStatus = pdisk.HasEntityStatus()
- ? pdisk.GetEntityStatus()
- : NKikimrBlobStorage::INITIAL;
-
- switch (entityStatus) {
- case NKikimrBlobStorage::INITIAL:
- case NKikimrBlobStorage::CREATE:
- StartLocalPDisk(pdisk);
- break;
-
- case NKikimrBlobStorage::DESTROY:
- DestroyLocalPDisk(pdisk.GetPDiskID());
- break;
-
- case NKikimrBlobStorage::RESTART:
- if (auto it = LocalPDisks.find({pdisk.GetNodeID(), pdisk.GetPDiskID()}); it != LocalPDisks.end()) {
- it->second.Record = pdisk;
- }
- RestartLocalPDiskStart(pdisk.GetPDiskID(), CreatePDiskConfig(pdisk));
- break;
- }
- }
- }
-
-} // NKikimr::NStorage
+ } else {
+ for (auto it = LocalVDisks.lower_bound(from); it != LocalVDisks.end() && it->first <= to; ++it) {
+ auto& [key, value] = *it;
+ if (!value.RuntimeData && !value.SlayInFlight) {
+ StartLocalVDiskActor(value, TDuration::Zero());
+ }
+ }
+ }
+ }
+
+ void TNodeWarden::ApplyServiceSetPDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
+ for (const auto& pdisk : serviceSet.GetPDisks()) {
+ if (!pdisk.HasNodeID() || !pdisk.HasPDiskID() || !pdisk.HasPath() || !pdisk.HasPDiskGuid() ||
+ pdisk.GetNodeID() != LocalNodeId) {
+ continue;
+ }
+
+ auto entityStatus = pdisk.HasEntityStatus()
+ ? pdisk.GetEntityStatus()
+ : NKikimrBlobStorage::INITIAL;
+
+ switch (entityStatus) {
+ case NKikimrBlobStorage::INITIAL:
+ case NKikimrBlobStorage::CREATE:
+ StartLocalPDisk(pdisk);
+ break;
+
+ case NKikimrBlobStorage::DESTROY:
+ DestroyLocalPDisk(pdisk.GetPDiskID());
+ break;
+
+ case NKikimrBlobStorage::RESTART:
+ if (auto it = LocalPDisks.find({pdisk.GetNodeID(), pdisk.GetPDiskID()}); it != LocalPDisks.end()) {
+ it->second.Record = pdisk;
+ }
+ RestartLocalPDiskStart(pdisk.GetPDiskID(), CreatePDiskConfig(pdisk));
+ break;
+ }
+ }
+ }
+
+} // NKikimr::NStorage
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_pipe.cpp b/ydb/core/blobstorage/nodewarden/node_warden_pipe.cpp
index f401ef1de0b..dc770d8b8da 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_pipe.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_pipe.cpp
@@ -1,91 +1,91 @@
-#include "node_warden_impl.h"
-
-using namespace NKikimr;
-using namespace NStorage;
-
-void TNodeWarden::SendToController(std::unique_ptr<IEventBase> ev, ui64 cookie) {
- NTabletPipe::SendData(SelfId(), PipeClientId, ev.release(), cookie);
-}
-
-void TNodeWarden::EstablishPipe() {
- Y_VERIFY(AppData() && AppData()->DomainsInfo);
-
- const ui64 stateStorageGroup = AppData()->DomainsInfo->GetDefaultStateStorageGroup(AvailDomainId);
- const ui64 controllerId = MakeBSControllerID(stateStorageGroup);
-
- PipeClientId = Register(NTabletPipe::CreateClient(SelfId(), controllerId, NTabletPipe::TClientRetryPolicy{
- .MaxRetryTime = TDuration::Seconds(5),
- .DoFirstRetryInstantly = false,
- }));
-
- STLOG(PRI_DEBUG, BS_NODE, NW21, "EstablishPipe", (AvailDomainId, AvailDomainId), (StateStorageGroup, stateStorageGroup),
- (PipeClientId, PipeClientId), (ControllerId, controllerId));
-
- SendRegisterNode();
- SendInitialGroupRequests();
- SendScrubRequests();
-}
-
-void TNodeWarden::Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
- TEvTabletPipe::TEvClientConnected *msg = ev->Get();
- if (msg->Status != NKikimrProto::OK) {
- STLOG(PRI_ERROR, BS_NODE, NW71, "TEvTabletPipe::TEvClientConnected", (Status, msg->Status),
- (ClientId, msg->ClientId), (ServerId, msg->ServerId), (TabletId, msg->TabletId),
- (PipeClientId, PipeClientId));
- OnPipeError();
- }
-}
-
-void TNodeWarden::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
- TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
- STLOG(PRI_ERROR, BS_NODE, NW42, "Handle(TEvTabletPipe::TEvClientDestroyed)", (ClientId, msg->ClientId),
- (ServerId, msg->ServerId), (TabletId, msg->TabletId), (PipeClientId, PipeClientId));
- OnPipeError();
-}
-
-void TNodeWarden::OnPipeError() {
- for (auto& [key, pdisk] : LocalPDisks) {
- if (pdisk.PDiskMetrics) {
- PDisksWithUnreportedMetrics.PushBack(&pdisk);
- }
- }
- for (auto& [key, vdisk] : LocalVDisks) {
- vdisk.ScrubCookieForController = 0; // invalidate all pending requests to BS_CONTROLLER
- if (vdisk.VDiskMetrics) {
- VDisksWithUnreportedMetrics.PushBack(&vdisk);
- }
- }
- EstablishPipe();
-}
-
-void TNodeWarden::SendRegisterNode() {
- STLOG(PRI_DEBUG, BS_NODE, NW20, "SendRegisterNode");
-
- TVector<ui32> startedDynamicGroups, generations;
- for (const auto& [groupId, group] : Groups) {
- if (group.ProxyRunning && TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeDynamic) {
- startedDynamicGroups.push_back(groupId);
- generations.push_back(group.Info ? group.Info->GroupGeneration : 0);
- }
- }
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(LocalNodeId, startedDynamicGroups, generations,
- WorkingLocalDrives);
- FillInVDiskStatus(ev->Record.MutableVDiskStatus(), true);
-
- SendToController(std::move(ev));
-}
-
-void TNodeWarden::SendInitialGroupRequests() {
- TStackVec<ui32, 32> groupIds;
- for (const auto& [groupId, group] : Groups) {
- if (group.GetGroupRequestPending) {
- groupIds.push_back(groupId);
- }
- }
- if (!groupIds.empty()) {
- STLOG(PRI_DEBUG, BS_NODE, NW22, "SendInitialGroupRequests", (GroupIds, FormatList(groupIds)));
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerGetGroup>(LocalNodeId,
- groupIds.begin(), groupIds.end()));
- }
-}
+#include "node_warden_impl.h"
+
+using namespace NKikimr;
+using namespace NStorage;
+
+void TNodeWarden::SendToController(std::unique_ptr<IEventBase> ev, ui64 cookie) {
+ NTabletPipe::SendData(SelfId(), PipeClientId, ev.release(), cookie);
+}
+
+void TNodeWarden::EstablishPipe() {
+ Y_VERIFY(AppData() && AppData()->DomainsInfo);
+
+ const ui64 stateStorageGroup = AppData()->DomainsInfo->GetDefaultStateStorageGroup(AvailDomainId);
+ const ui64 controllerId = MakeBSControllerID(stateStorageGroup);
+
+ PipeClientId = Register(NTabletPipe::CreateClient(SelfId(), controllerId, NTabletPipe::TClientRetryPolicy{
+ .MaxRetryTime = TDuration::Seconds(5),
+ .DoFirstRetryInstantly = false,
+ }));
+
+ STLOG(PRI_DEBUG, BS_NODE, NW21, "EstablishPipe", (AvailDomainId, AvailDomainId), (StateStorageGroup, stateStorageGroup),
+ (PipeClientId, PipeClientId), (ControllerId, controllerId));
+
+ SendRegisterNode();
+ SendInitialGroupRequests();
+ SendScrubRequests();
+}
+
+void TNodeWarden::Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
+ TEvTabletPipe::TEvClientConnected *msg = ev->Get();
+ if (msg->Status != NKikimrProto::OK) {
+ STLOG(PRI_ERROR, BS_NODE, NW71, "TEvTabletPipe::TEvClientConnected", (Status, msg->Status),
+ (ClientId, msg->ClientId), (ServerId, msg->ServerId), (TabletId, msg->TabletId),
+ (PipeClientId, PipeClientId));
+ OnPipeError();
+ }
+}
+
+void TNodeWarden::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
+ TEvTabletPipe::TEvClientDestroyed *msg = ev->Get();
+ STLOG(PRI_ERROR, BS_NODE, NW42, "Handle(TEvTabletPipe::TEvClientDestroyed)", (ClientId, msg->ClientId),
+ (ServerId, msg->ServerId), (TabletId, msg->TabletId), (PipeClientId, PipeClientId));
+ OnPipeError();
+}
+
+void TNodeWarden::OnPipeError() {
+ for (auto& [key, pdisk] : LocalPDisks) {
+ if (pdisk.PDiskMetrics) {
+ PDisksWithUnreportedMetrics.PushBack(&pdisk);
+ }
+ }
+ for (auto& [key, vdisk] : LocalVDisks) {
+ vdisk.ScrubCookieForController = 0; // invalidate all pending requests to BS_CONTROLLER
+ if (vdisk.VDiskMetrics) {
+ VDisksWithUnreportedMetrics.PushBack(&vdisk);
+ }
+ }
+ EstablishPipe();
+}
+
+void TNodeWarden::SendRegisterNode() {
+ STLOG(PRI_DEBUG, BS_NODE, NW20, "SendRegisterNode");
+
+ TVector<ui32> startedDynamicGroups, generations;
+ for (const auto& [groupId, group] : Groups) {
+ if (group.ProxyRunning && TGroupID(groupId).ConfigurationType() == GroupConfigurationTypeDynamic) {
+ startedDynamicGroups.push_back(groupId);
+ generations.push_back(group.Info ? group.Info->GroupGeneration : 0);
+ }
+ }
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(LocalNodeId, startedDynamicGroups, generations,
+ WorkingLocalDrives);
+ FillInVDiskStatus(ev->Record.MutableVDiskStatus(), true);
+
+ SendToController(std::move(ev));
+}
+
+void TNodeWarden::SendInitialGroupRequests() {
+ TStackVec<ui32, 32> groupIds;
+ for (const auto& [groupId, group] : Groups) {
+ if (group.GetGroupRequestPending) {
+ groupIds.push_back(groupId);
+ }
+ }
+ if (!groupIds.empty()) {
+ STLOG(PRI_DEBUG, BS_NODE, NW22, "SendInitialGroupRequests", (GroupIds, FormatList(groupIds)));
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerGetGroup>(LocalNodeId,
+ groupIds.begin(), groupIds.end()));
+ }
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_proxy.cpp b/ydb/core/blobstorage/nodewarden/node_warden_proxy.cpp
index 3e351ac554a..4961304e956 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_proxy.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_proxy.cpp
@@ -1,70 +1,70 @@
-#include "node_warden_impl.h"
-
-using namespace NKikimr;
-using namespace NStorage;
-
-TActorId TNodeWarden::StartEjectedProxy(ui32 groupId) {
- STLOG(PRI_DEBUG, BS_NODE, NW10, "StartErrorProxy", (GroupId, groupId));
- return Register(CreateBlobStorageGroupEjectedProxy(groupId, DsProxyNodeMon), TMailboxType::ReadAsFilled, AppData()->SystemPoolId);
-}
-
-void TNodeWarden::StartLocalProxy(ui32 groupId) {
- auto& group = Groups[groupId];
- Y_VERIFY(!group.ProxyRunning);
- group.ProxyRunning = true;
- STLOG(PRI_DEBUG, BS_NODE, NW12, "StartLocalProxy", (GroupId, groupId));
-
- std::unique_ptr<IActor> proxy;
-
- if (EnableProxyMock) {
- // create mock proxy
- proxy.reset(CreateBlobStorageGroupProxyMockActor());
- } else if (auto info = NeedGroupInfo(groupId)) {
- // create proxy with configuration
- auto counters = DsProxyPerPoolCounters->GetPoolCounters(info->GetStoragePoolName(), info->GetDeviceType());
- proxy.reset(CreateBlobStorageGroupProxyConfigured(std::move(info), false, DsProxyNodeMon, std::move(counters),
- EnablePutBatching, EnableVPatch));
- } else {
- // create proxy without configuration
- proxy.reset(CreateBlobStorageGroupProxyUnconfigured(groupId, DsProxyNodeMon, EnablePutBatching, EnableVPatch));
- }
-
- TActorSystem *as = TActivationContext::ActorSystem();
- as->RegisterLocalService(MakeBlobStorageProxyID(groupId), as->Register(proxy.release(), TMailboxType::ReadAsFilled,
- AppData()->SystemPoolId));
-}
-
-void TNodeWarden::StartStaticProxies() {
- for (const auto& group : Cfg->ServiceSet.GetGroups()) {
- StartLocalProxy(group.GetGroupID());
- }
-}
-
-void TNodeWarden::HandleForwarded(TAutoPtr<::NActors::IEventHandle> &ev) {
- const TGroupID groupId(GroupIDFromBlobStorageProxyID(ev->GetForwardOnNondeliveryRecipient()));
- const ui32 id = groupId.GetRaw();
-
- const bool noGroup = (groupId.ConfigurationType() == GroupConfigurationTypeStatic && !Groups.count(id)) || EjectedGroups.count(id);
- STLOG(PRI_DEBUG, BS_NODE, NW46, "HandleForwarded", (GroupId, id), (EnableProxyMock, EnableProxyMock), (NoGroup, noGroup));
-
- if (id == Max<ui32>()) {
- // invalid group; proxy for this group is created at start
- } else if (noGroup) {
- const TActorId errorProxy = StartEjectedProxy(id);
- TActivationContext::Send(ev->Forward(errorProxy));
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, errorProxy, {}, nullptr, 0));
- return;
- } else if (TGroupRecord& group = Groups[id]; !group.ProxyRunning) {
- StartLocalProxy(id);
- }
-
- TActivationContext::Send(ev->Forward(ev->GetForwardOnNondeliveryRecipient()));
-}
-
-void TNodeWarden::Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate::TPtr ev) {
- const auto& record = ev->Get()->Record;
- const ui32 groupId = record.GetGroupID();
- if (const auto it = Groups.find(groupId); it != Groups.end() && it->second.ProxyRunning) {
- TActivationContext::Send(ev->Forward(WhiteboardId));
- }
-}
+#include "node_warden_impl.h"
+
+using namespace NKikimr;
+using namespace NStorage;
+
+TActorId TNodeWarden::StartEjectedProxy(ui32 groupId) {
+ STLOG(PRI_DEBUG, BS_NODE, NW10, "StartErrorProxy", (GroupId, groupId));
+ return Register(CreateBlobStorageGroupEjectedProxy(groupId, DsProxyNodeMon), TMailboxType::ReadAsFilled, AppData()->SystemPoolId);
+}
+
+void TNodeWarden::StartLocalProxy(ui32 groupId) {
+ auto& group = Groups[groupId];
+ Y_VERIFY(!group.ProxyRunning);
+ group.ProxyRunning = true;
+ STLOG(PRI_DEBUG, BS_NODE, NW12, "StartLocalProxy", (GroupId, groupId));
+
+ std::unique_ptr<IActor> proxy;
+
+ if (EnableProxyMock) {
+ // create mock proxy
+ proxy.reset(CreateBlobStorageGroupProxyMockActor());
+ } else if (auto info = NeedGroupInfo(groupId)) {
+ // create proxy with configuration
+ auto counters = DsProxyPerPoolCounters->GetPoolCounters(info->GetStoragePoolName(), info->GetDeviceType());
+ proxy.reset(CreateBlobStorageGroupProxyConfigured(std::move(info), false, DsProxyNodeMon, std::move(counters),
+ EnablePutBatching, EnableVPatch));
+ } else {
+ // create proxy without configuration
+ proxy.reset(CreateBlobStorageGroupProxyUnconfigured(groupId, DsProxyNodeMon, EnablePutBatching, EnableVPatch));
+ }
+
+ TActorSystem *as = TActivationContext::ActorSystem();
+ as->RegisterLocalService(MakeBlobStorageProxyID(groupId), as->Register(proxy.release(), TMailboxType::ReadAsFilled,
+ AppData()->SystemPoolId));
+}
+
+void TNodeWarden::StartStaticProxies() {
+ for (const auto& group : Cfg->ServiceSet.GetGroups()) {
+ StartLocalProxy(group.GetGroupID());
+ }
+}
+
+void TNodeWarden::HandleForwarded(TAutoPtr<::NActors::IEventHandle> &ev) {
+ const TGroupID groupId(GroupIDFromBlobStorageProxyID(ev->GetForwardOnNondeliveryRecipient()));
+ const ui32 id = groupId.GetRaw();
+
+ const bool noGroup = (groupId.ConfigurationType() == GroupConfigurationTypeStatic && !Groups.count(id)) || EjectedGroups.count(id);
+ STLOG(PRI_DEBUG, BS_NODE, NW46, "HandleForwarded", (GroupId, id), (EnableProxyMock, EnableProxyMock), (NoGroup, noGroup));
+
+ if (id == Max<ui32>()) {
+ // invalid group; proxy for this group is created at start
+ } else if (noGroup) {
+ const TActorId errorProxy = StartEjectedProxy(id);
+ TActivationContext::Send(ev->Forward(errorProxy));
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, errorProxy, {}, nullptr, 0));
+ return;
+ } else if (TGroupRecord& group = Groups[id]; !group.ProxyRunning) {
+ StartLocalProxy(id);
+ }
+
+ TActivationContext::Send(ev->Forward(ev->GetForwardOnNondeliveryRecipient()));
+}
+
+void TNodeWarden::Handle(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate::TPtr ev) {
+ const auto& record = ev->Get()->Record;
+ const ui32 groupId = record.GetGroupID();
+ if (const auto it = Groups.find(groupId); it != Groups.end() && it->second.ProxyRunning) {
+ TActivationContext::Send(ev->Forward(WhiteboardId));
+ }
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_resource.cpp b/ydb/core/blobstorage/nodewarden/node_warden_resource.cpp
index d8179b7af81..02c690d8d4f 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_resource.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_resource.cpp
@@ -1,5 +1,5 @@
-#include "node_warden_impl.h"
-
+#include "node_warden_impl.h"
+
#include <ydb/core/blobstorage/crypto/default.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_util_wcache.h>
@@ -7,112 +7,112 @@
#include <util/string/split.h>
-using namespace NKikimr;
-using namespace NStorage;
-
+using namespace NKikimr;
+using namespace NStorage;
+
void TNodeWarden::RegisterPendingActor(const TActorId& actorId) {
- const bool inserted = PendingMessageQ.emplace(actorId, std::deque<std::unique_ptr<IEventHandle>>()).second;
- Y_VERIFY(inserted);
-}
-
-void TNodeWarden::EnqueuePendingMessage(TAutoPtr<IEventHandle> ev) {
- ev = ev->Forward(ev->GetForwardOnNondeliveryRecipient());
- const auto it = PendingMessageQ.find(ev->Recipient);
- if (it != PendingMessageQ.end()) {
- it->second.emplace_back(ev.Release());
- } else {
- TActivationContext::Send(ev);
- }
-}
-
-void TNodeWarden::IssuePendingMessages(const TActorId& actorId) {
- const auto it = PendingMessageQ.find(actorId);
- Y_VERIFY(it != PendingMessageQ.end());
- for (auto& ev : it->second) {
- TActivationContext::Send(ev.release());
- }
- PendingMessageQ.erase(it);
-}
-
-void TNodeWarden::ApplyServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet &serviceSet, bool isStatic, bool comprehensive, bool updateCache) {
- if (Cfg->IsCacheEnabled() && updateCache) {
- Y_VERIFY(!isStatic);
- return EnqueueSyncOp(WrapCacheOp(UpdateServiceSet(serviceSet, comprehensive, [=] {
- return ApplyServiceSet(serviceSet, false, comprehensive, false);
- })));
- }
-
- STLOG(PRI_DEBUG, BS_NODE, NW18, "ApplyServiceSet", (IsStatic, isStatic), (Comprehensive, comprehensive));
-
- // apply proxy information before we try to start VDisks/PDisks
- ApplyGroupInfoFromServiceSet(serviceSet);
-
- if (!EnableProxyMock) {
- // in mock mode we don't need PDisk/VDisk instances
- ApplyServiceSetPDisks(serviceSet);
- ApplyServiceSetVDisks(serviceSet);
- }
-
- // for comprehensive configuration -- stop created, but missing entities
- if (comprehensive) {
- std::set<TPDiskKey> pdiskQ;
- for (const auto& [pdiskId, _] : LocalPDisks) { // insert all running PDisk ids in the set
- pdiskQ.insert(pdiskId);
- }
- for (const auto& item : serviceSet.GetPDisks()) { // remove enumerated ids
- if (item.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::INITIAL ||
- item.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::CREATE) {
- pdiskQ.erase({item.GetNodeID(), item.GetPDiskID()});
- }
- }
- for (const auto& [vslotId, _] : LocalVDisks) { // remove ids for PDisks with active VSlots
- pdiskQ.erase({vslotId.NodeId, vslotId.PDiskId});
- }
- for (const TPDiskKey& pdiskId : pdiskQ) { // terminate excessive PDisks
- Y_VERIFY(pdiskId.NodeId == LocalNodeId);
- DestroyLocalPDisk(pdiskId.PDiskId);
- }
- }
-
- for (auto& [vslotId, vdisk] : LocalVDisks) {
- if (vdisk.UnderlyingPDiskDestroyed) {
- auto& tempVSlotId = vslotId;
- STLOG_DEBUG_FAIL(BS_NODE, NW37, "UnderlyingPDiskDestroyed escaped", (VSlotId, tempVSlotId));
- vdisk.UnderlyingPDiskDestroyed = false;
- }
- }
-}
-
-void TNodeWarden::HandleIncrHugeInit(NIncrHuge::TEvIncrHugeInit::TPtr ev) {
+ const bool inserted = PendingMessageQ.emplace(actorId, std::deque<std::unique_ptr<IEventHandle>>()).second;
+ Y_VERIFY(inserted);
+}
+
+void TNodeWarden::EnqueuePendingMessage(TAutoPtr<IEventHandle> ev) {
+ ev = ev->Forward(ev->GetForwardOnNondeliveryRecipient());
+ const auto it = PendingMessageQ.find(ev->Recipient);
+ if (it != PendingMessageQ.end()) {
+ it->second.emplace_back(ev.Release());
+ } else {
+ TActivationContext::Send(ev);
+ }
+}
+
+void TNodeWarden::IssuePendingMessages(const TActorId& actorId) {
+ const auto it = PendingMessageQ.find(actorId);
+ Y_VERIFY(it != PendingMessageQ.end());
+ for (auto& ev : it->second) {
+ TActivationContext::Send(ev.release());
+ }
+ PendingMessageQ.erase(it);
+}
+
+void TNodeWarden::ApplyServiceSet(const NKikimrBlobStorage::TNodeWardenServiceSet &serviceSet, bool isStatic, bool comprehensive, bool updateCache) {
+ if (Cfg->IsCacheEnabled() && updateCache) {
+ Y_VERIFY(!isStatic);
+ return EnqueueSyncOp(WrapCacheOp(UpdateServiceSet(serviceSet, comprehensive, [=] {
+ return ApplyServiceSet(serviceSet, false, comprehensive, false);
+ })));
+ }
+
+ STLOG(PRI_DEBUG, BS_NODE, NW18, "ApplyServiceSet", (IsStatic, isStatic), (Comprehensive, comprehensive));
+
+ // apply proxy information before we try to start VDisks/PDisks
+ ApplyGroupInfoFromServiceSet(serviceSet);
+
+ if (!EnableProxyMock) {
+ // in mock mode we don't need PDisk/VDisk instances
+ ApplyServiceSetPDisks(serviceSet);
+ ApplyServiceSetVDisks(serviceSet);
+ }
+
+ // for comprehensive configuration -- stop created, but missing entities
+ if (comprehensive) {
+ std::set<TPDiskKey> pdiskQ;
+ for (const auto& [pdiskId, _] : LocalPDisks) { // insert all running PDisk ids in the set
+ pdiskQ.insert(pdiskId);
+ }
+ for (const auto& item : serviceSet.GetPDisks()) { // remove enumerated ids
+ if (item.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::INITIAL ||
+ item.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::CREATE) {
+ pdiskQ.erase({item.GetNodeID(), item.GetPDiskID()});
+ }
+ }
+ for (const auto& [vslotId, _] : LocalVDisks) { // remove ids for PDisks with active VSlots
+ pdiskQ.erase({vslotId.NodeId, vslotId.PDiskId});
+ }
+ for (const TPDiskKey& pdiskId : pdiskQ) { // terminate excessive PDisks
+ Y_VERIFY(pdiskId.NodeId == LocalNodeId);
+ DestroyLocalPDisk(pdiskId.PDiskId);
+ }
+ }
+
+ for (auto& [vslotId, vdisk] : LocalVDisks) {
+ if (vdisk.UnderlyingPDiskDestroyed) {
+ auto& tempVSlotId = vslotId;
+ STLOG_DEBUG_FAIL(BS_NODE, NW37, "UnderlyingPDiskDestroyed escaped", (VSlotId, tempVSlotId));
+ vdisk.UnderlyingPDiskDestroyed = false;
+ }
+ }
+}
+
+void TNodeWarden::HandleIncrHugeInit(NIncrHuge::TEvIncrHugeInit::TPtr ev) {
const TActorId keeperId = ev->GetForwardOnNondeliveryRecipient();
- const ui32 pdiskId = NIncrHuge::PDiskIdFromIncrHugeKeeperId(keeperId);
-
- // find local pdisk config to extract GUID
- auto it = LocalPDisks.find(TPDiskKey(LocalNodeId, pdiskId));
- Y_VERIFY(it != LocalPDisks.end());
-
- // get config
- const NKikimrBlobStorage::TIncrHugeConfig& config = Cfg->IncrHugeConfig;
-
- // fill in settings record
- NIncrHuge::TKeeperSettings settings{
- it->first.PDiskId,
- MakeBlobStoragePDiskID(it->first.NodeId, it->first.PDiskId),
+ const ui32 pdiskId = NIncrHuge::PDiskIdFromIncrHugeKeeperId(keeperId);
+
+ // find local pdisk config to extract GUID
+ auto it = LocalPDisks.find(TPDiskKey(LocalNodeId, pdiskId));
+ Y_VERIFY(it != LocalPDisks.end());
+
+ // get config
+ const NKikimrBlobStorage::TIncrHugeConfig& config = Cfg->IncrHugeConfig;
+
+ // fill in settings record
+ NIncrHuge::TKeeperSettings settings{
+ it->first.PDiskId,
+ MakeBlobStoragePDiskID(it->first.NodeId, it->first.PDiskId),
it->second.Record.GetPDiskGuid(),
- config.GetMinHugeBlobInBytes(),
- config.GetMinCleanChunks(),
- config.GetMinAllocationBatch(),
- config.GetUnalignedBlockSize(),
- config.GetMaxInFlightWrites(),
- NextLocalPDiskInitOwnerRound()
- };
-
- // register new actor
- TActorId actorId = Register(CreateIncrHugeKeeper(settings), TMailboxType::HTSwap, AppData()->SystemPoolId);
-
- // bind it to service
- TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(keeperId, actorId);
-
- // forward to just created service
- TActivationContext::Send(ev->Forward(keeperId));
-}
+ config.GetMinHugeBlobInBytes(),
+ config.GetMinCleanChunks(),
+ config.GetMinAllocationBatch(),
+ config.GetUnalignedBlockSize(),
+ config.GetMaxInFlightWrites(),
+ NextLocalPDiskInitOwnerRound()
+ };
+
+ // register new actor
+ TActorId actorId = Register(CreateIncrHugeKeeper(settings), TMailboxType::HTSwap, AppData()->SystemPoolId);
+
+ // bind it to service
+ TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(keeperId, actorId);
+
+ // forward to just created service
+ TActivationContext::Send(ev->Forward(keeperId));
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_scrub.cpp b/ydb/core/blobstorage/nodewarden/node_warden_scrub.cpp
index 117b119d441..d54862a6c99 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_scrub.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_scrub.cpp
@@ -1,107 +1,107 @@
-#include "node_warden_impl.h"
-
-using namespace NKikimr;
-using namespace NStorage;
-
-void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev) {
- const auto& r = ev->Get()->Record;
- if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookie) {
- TVDiskRecord& vdisk = it->second;
- switch (vdisk.ScrubState) {
- case TVDiskRecord::EScrubState::IDLE:
- vdisk.ScrubState = TVDiskRecord::EScrubState::QUERY_START_QUANTUM;
- break;
-
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
- vdisk.ScrubState = TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE;
- break;
-
- case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
- case TVDiskRecord::EScrubState::IN_PROGRESS:
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
- Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
- }
- // issue request to BS_CONTROLLER
- const TVSlotId vslotId = it->first;
- vdisk.ScrubCookieForController = ++LastScrubCookie;
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
- vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId), vdisk.ScrubCookieForController);
- }
-}
-
-void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubStartQuantum::TPtr ev) {
- const auto& r = ev->Get()->Record;
- if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookieForController) {
- const TVSlotId vslotId = it->first;
- TVDiskRecord& vdisk = it->second;
- switch (vdisk.ScrubState) {
- case TVDiskRecord::EScrubState::IDLE:
- case TVDiskRecord::EScrubState::IN_PROGRESS:
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
- Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
-
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
- vdisk.QuantumFinished.Clear();
+#include "node_warden_impl.h"
+
+using namespace NKikimr;
+using namespace NStorage;
+
+void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev) {
+ const auto& r = ev->Get()->Record;
+ if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookie) {
+ TVDiskRecord& vdisk = it->second;
+ switch (vdisk.ScrubState) {
+ case TVDiskRecord::EScrubState::IDLE:
+ vdisk.ScrubState = TVDiskRecord::EScrubState::QUERY_START_QUANTUM;
+ break;
+
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
+ vdisk.ScrubState = TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE;
+ break;
+
+ case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
+ case TVDiskRecord::EScrubState::IN_PROGRESS:
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
+ Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
+ }
+ // issue request to BS_CONTROLLER
+ const TVSlotId vslotId = it->first;
+ vdisk.ScrubCookieForController = ++LastScrubCookie;
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
+ vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId), vdisk.ScrubCookieForController);
+ }
+}
+
+void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubStartQuantum::TPtr ev) {
+ const auto& r = ev->Get()->Record;
+ if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookieForController) {
+ const TVSlotId vslotId = it->first;
+ TVDiskRecord& vdisk = it->second;
+ switch (vdisk.ScrubState) {
+ case TVDiskRecord::EScrubState::IDLE:
+ case TVDiskRecord::EScrubState::IN_PROGRESS:
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
+ Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
+
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
+ vdisk.QuantumFinished.Clear();
[[fallthrough]];
- case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
- vdisk.ScrubState = TVDiskRecord::EScrubState::IN_PROGRESS;
- TActivationContext::Send(ev->Forward(MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId)));
- break;
- }
- }
-}
-
-void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev) {
- const auto& r = ev->Get()->Record;
- if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookie) {
- TVDiskRecord& vdisk = it->second;
- switch (vdisk.ScrubState) {
- case TVDiskRecord::EScrubState::IN_PROGRESS:
- vdisk.ScrubState = TVDiskRecord::EScrubState::QUANTUM_FINISHED;
- vdisk.QuantumFinished.CopyFrom(r);
- break;
-
- case TVDiskRecord::EScrubState::IDLE:
- case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
- Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
- }
- // forward request to BS_CONTROLLER
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(r));
- }
-}
-
-void TNodeWarden::SendScrubRequests() {
- for (auto& [key, vdisk] : LocalVDisks) {
- switch (vdisk.ScrubState) {
- case TVDiskRecord::EScrubState::IDLE:
- // VDisk didn't ask for any scrub activity yet, so just keep calm
- break;
-
- case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
- vdisk.ScrubCookieForController = ++LastScrubCookie;
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
- key.NodeId, key.PDiskId, key.VDiskSlotId), vdisk.ScrubCookieForController);
- break;
-
- case TVDiskRecord::EScrubState::IN_PROGRESS:
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubReportQuantumInProgress>(
- key.NodeId, key.PDiskId, key.VDiskSlotId));
- break;
-
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(
- vdisk.QuantumFinished));
- break;
-
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(
- vdisk.QuantumFinished));
- vdisk.ScrubCookieForController = ++LastScrubCookie;
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
- key.NodeId, key.PDiskId, key.VDiskSlotId), vdisk.ScrubCookieForController);
- break;
- }
- }
-}
+ case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
+ vdisk.ScrubState = TVDiskRecord::EScrubState::IN_PROGRESS;
+ TActivationContext::Send(ev->Forward(MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId)));
+ break;
+ }
+ }
+}
+
+void TNodeWarden::Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev) {
+ const auto& r = ev->Get()->Record;
+ if (const auto it = LocalVDisks.find(r.GetVSlotId()); it != LocalVDisks.end() && ev->Cookie == it->second.ScrubCookie) {
+ TVDiskRecord& vdisk = it->second;
+ switch (vdisk.ScrubState) {
+ case TVDiskRecord::EScrubState::IN_PROGRESS:
+ vdisk.ScrubState = TVDiskRecord::EScrubState::QUANTUM_FINISHED;
+ vdisk.QuantumFinished.CopyFrom(r);
+ break;
+
+ case TVDiskRecord::EScrubState::IDLE:
+ case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
+ Y_FAIL("inconsistent ScrubState# %" PRIu32, vdisk.ScrubState);
+ }
+ // forward request to BS_CONTROLLER
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(r));
+ }
+}
+
+void TNodeWarden::SendScrubRequests() {
+ for (auto& [key, vdisk] : LocalVDisks) {
+ switch (vdisk.ScrubState) {
+ case TVDiskRecord::EScrubState::IDLE:
+ // VDisk didn't ask for any scrub activity yet, so just keep calm
+ break;
+
+ case TVDiskRecord::EScrubState::QUERY_START_QUANTUM:
+ vdisk.ScrubCookieForController = ++LastScrubCookie;
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
+ key.NodeId, key.PDiskId, key.VDiskSlotId), vdisk.ScrubCookieForController);
+ break;
+
+ case TVDiskRecord::EScrubState::IN_PROGRESS:
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubReportQuantumInProgress>(
+ key.NodeId, key.PDiskId, key.VDiskSlotId));
+ break;
+
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED:
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(
+ vdisk.QuantumFinished));
+ break;
+
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE:
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(
+ vdisk.QuantumFinished));
+ vdisk.ScrubCookieForController = ++LastScrubCookie;
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQueryStartQuantum>(
+ key.NodeId, key.PDiskId, key.VDiskSlotId), vdisk.ScrubCookieForController);
+ break;
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_stat_aggr.cpp b/ydb/core/blobstorage/nodewarden/node_warden_stat_aggr.cpp
index 6a357489fc5..d166a693e29 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_stat_aggr.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_stat_aggr.cpp
@@ -1,55 +1,55 @@
-#include "node_warden_impl.h"
-
-using namespace NKikimr;
-using namespace NStorage;
-
-void TNodeWarden::ReportLatencies() {
- std::unique_ptr<TEvBlobStorage::TEvControllerUpdateGroupStat> ev;
-
- for (const auto& kv : PerAggregatorInfo) {
- const TAggregatorInfo& info = kv.second;
- const TGroupID groupId(info.GroupId);
- if (!ev) {
- ev.reset(new TEvBlobStorage::TEvControllerUpdateGroupStat);
- }
- auto& record = ev->Record;
- auto *pb = record.AddPerGroupReport();
- pb->SetGroupId(info.GroupId);
+#include "node_warden_impl.h"
+
+using namespace NKikimr;
+using namespace NStorage;
+
+void TNodeWarden::ReportLatencies() {
+ std::unique_ptr<TEvBlobStorage::TEvControllerUpdateGroupStat> ev;
+
+ for (const auto& kv : PerAggregatorInfo) {
+ const TAggregatorInfo& info = kv.second;
+ const TGroupID groupId(info.GroupId);
+ if (!ev) {
+ ev.reset(new TEvBlobStorage::TEvControllerUpdateGroupStat);
+ }
+ auto& record = ev->Record;
+ auto *pb = record.AddPerGroupReport();
+ pb->SetGroupId(info.GroupId);
ActorIdToProto(kv.first, pb->MutableVDiskServiceId());
- info.Stat.Serialize(pb);
- }
-
- if (ev) {
- SendToController(std::move(ev));
- }
-}
-
-void TNodeWarden::Handle(TEvGroupStatReport::TPtr ev) {
- TEvGroupStatReport *msg = ev->Get();
+ info.Stat.Serialize(pb);
+ }
+
+ if (ev) {
+ SendToController(std::move(ev));
+ }
+}
+
+void TNodeWarden::Handle(TEvGroupStatReport::TPtr ev) {
+ TEvGroupStatReport *msg = ev->Get();
TActorId vdiskServiceId = msg->GetVDiskServiceId();
-
- TGroupStat stat;
- if (RunningVDiskServiceIds.count(vdiskServiceId) && msg->GetStat(stat)) {
- PerAggregatorInfo[vdiskServiceId] = TAggregatorInfo{
- msg->GetGroupId(),
- std::move(stat)
- };
- }
-}
-
-void TNodeWarden::StartAggregator(const TActorId& vdiskServiceId, ui32 groupId) {
- if (RunningVDiskServiceIds.emplace(vdiskServiceId).second) {
+
+ TGroupStat stat;
+ if (RunningVDiskServiceIds.count(vdiskServiceId) && msg->GetStat(stat)) {
+ PerAggregatorInfo[vdiskServiceId] = TAggregatorInfo{
+ msg->GetGroupId(),
+ std::move(stat)
+ };
+ }
+}
+
+void TNodeWarden::StartAggregator(const TActorId& vdiskServiceId, ui32 groupId) {
+ if (RunningVDiskServiceIds.emplace(vdiskServiceId).second) {
const TActorId groupStatAggregatorId = MakeGroupStatAggregatorId(vdiskServiceId);
- const TActorId actorId = Register(CreateGroupStatAggregatorActor(groupId, vdiskServiceId),
- TMailboxType::Revolving, AppData()->SystemPoolId);
- TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(groupStatAggregatorId, actorId);
- }
-}
-
-void TNodeWarden::StopAggregator(const TActorId& vdiskServiceId) {
- if (RunningVDiskServiceIds.erase(vdiskServiceId)) {
+ const TActorId actorId = Register(CreateGroupStatAggregatorActor(groupId, vdiskServiceId),
+ TMailboxType::Revolving, AppData()->SystemPoolId);
+ TlsActivationContext->ExecutorThread.ActorSystem->RegisterLocalService(groupStatAggregatorId, actorId);
+ }
+}
+
+void TNodeWarden::StopAggregator(const TActorId& vdiskServiceId) {
+ if (RunningVDiskServiceIds.erase(vdiskServiceId)) {
const TActorId groupStatAggregatorId = MakeGroupStatAggregatorId(vdiskServiceId);
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, groupStatAggregatorId, {}, nullptr, 0));
- PerAggregatorInfo.erase(groupStatAggregatorId);
- }
-}
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, groupStatAggregatorId, {}, nullptr, 0));
+ PerAggregatorInfo.erase(groupStatAggregatorId);
+ }
+}
diff --git a/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp b/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp
index 096ac7ee90c..5f14737528a 100644
--- a/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp
+++ b/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp
@@ -1,305 +1,305 @@
-#include "node_warden_impl.h"
-
+#include "node_warden_impl.h"
+
#include <ydb/core/blobstorage/crypto/default.h>
-
-#include <util/string/split.h>
-
-namespace NKikimr::NStorage {
-
- void TNodeWarden::DestroyLocalVDisk(TVDiskRecord& vdisk) {
- STLOG(PRI_INFO, BS_NODE, NW35, "DestroyLocalVDisk", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()));
- Y_VERIFY(!vdisk.RuntimeData);
-
- const TVSlotId vslotId = vdisk.GetVSlotId();
- StopAggregator(MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId));
-
- if (vdisk.WhiteboardVDiskId) {
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateDelete(*vdisk.WhiteboardVDiskId));
- vdisk.WhiteboardVDiskId.reset();
- }
- }
-
- void TNodeWarden::PoisonLocalVDisk(TVDiskRecord& vdisk) {
- STLOG(PRI_INFO, BS_NODE, NW35, "PoisonLocalVDisk", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()),
- (RuntimeData, vdisk.RuntimeData.has_value()));
-
- if (vdisk.RuntimeData) {
- vdisk.TIntrusiveListItem<TVDiskRecord, TGroupRelationTag>::Unlink();
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, vdisk.GetVDiskServiceId(), {}, nullptr, 0));
- vdisk.RuntimeData.reset();
- }
-
- switch (vdisk.ScrubState) {
- case TVDiskRecord::EScrubState::IDLE: // no scrub in progress at all
- case TVDiskRecord::EScrubState::QUERY_START_QUANTUM: // VDisk was waiting for quantum and didn't get it
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED: // quantum finished, no work is in progress
- case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE: // like QUERY_START_QUANTUM
- break;
-
- case TVDiskRecord::EScrubState::IN_PROGRESS: { // scrub is in progress, report scrub stop to BS_CONTROLLER
- const TVSlotId vslotId = vdisk.GetVSlotId();
- SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(vslotId.NodeId,
- vslotId.PDiskId, vslotId.VDiskSlotId));
- break;
- }
- }
- vdisk.ScrubState = TVDiskRecord::EScrubState::IDLE;
- vdisk.QuantumFinished.Clear();
- vdisk.ScrubCookie = 0; // disable reception of Scrub messages from this disk
- vdisk.ScrubCookieForController = 0; // and from controller too
- vdisk.Status = NKikimrBlobStorage::EVDiskStatus::ERROR;
-
- SendDiskMetrics(false);
- }
-
- void TNodeWarden::StartLocalVDiskActor(TVDiskRecord& vdisk, TDuration yardInitDelay) {
- const TVSlotId vslotId = vdisk.GetVSlotId();
- const ui64 pdiskGuid = vdisk.Config.GetVDiskLocation().GetPDiskGuid();
- const bool restartInFlight = InFlightRestartedPDisks.count({vslotId.NodeId, vslotId.PDiskId});
- const bool donorMode = vdisk.Config.HasDonorMode();
-
- STLOG(PRI_DEBUG, BS_NODE, NW23, "StartLocalVDiskActor", (RestartInFlight, restartInFlight),
- (SlayInFlight, vdisk.SlayInFlight), (VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId),
- (PDiskGuid, pdiskGuid), (DonorMode, donorMode));
-
- if (restartInFlight || vdisk.SlayInFlight) {
- return;
- }
-
- // find underlying PDisk and determine its media type
- auto pdiskIt = LocalPDisks.find({vslotId.NodeId, vslotId.PDiskId});
- Y_VERIFY_S(pdiskIt != LocalPDisks.end(), "PDiskId# " << vslotId.NodeId << ":" << vslotId.PDiskId << " not found");
- auto& pdisk = pdiskIt->second;
- Y_VERIFY_S(pdisk.Record.GetPDiskGuid() == pdiskGuid, "PDiskId# " << vslotId.NodeId << ":" << vslotId.PDiskId << " PDiskGuid mismatch");
- const TPDiskCategory::EDeviceType deviceType = TPDiskCategory(pdisk.Record.GetPDiskCategory()).Type();
-
- const TActorId pdiskServiceId = MakeBlobStoragePDiskID(vslotId.NodeId, vslotId.PDiskId);
- const TActorId vdiskServiceId = MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId);
-
- // generate correct VDiskId (based on relevant generation of containing group) and groupInfo pointer
- Y_VERIFY(!vdisk.RuntimeData);
- TVDiskID vdiskId = vdisk.GetVDiskId();
- TIntrusivePtr<TBlobStorageGroupInfo> groupInfo;
-
- if (!donorMode) {
- // find group containing VDisk being started
- const auto it = Groups.find(vdisk.GetGroupId());
- if (it == Groups.end()) {
- STLOG_DEBUG_FAIL(BS_NODE, NW09, "group not found while starting VDisk actor",
- (GroupId, vdisk.GetGroupId()), (VDiskId, vdiskId), (Config, vdisk.Config));
- return;
- }
- auto& group = it->second;
-
- // ensure the group has correctly filled protobuf (in case when there is no relevant info pointer)
- if (!group.Group) {
- STLOG_DEBUG_FAIL(BS_NODE, NW13, "group configuration does not contain protobuf to start VDisk",
- (GroupId, it->first), (VDiskId, vdiskId), (Config, vdisk.Config));
- return;
- }
-
- // obtain group info pointer
- if (group.Info) {
- groupInfo = group.Info;
- } else {
- TStringStream err;
- groupInfo = TBlobStorageGroupInfo::Parse(*group.Group, nullptr, nullptr);
- }
-
- // check that VDisk belongs to active VDisks of the group
- const ui32 orderNumber = groupInfo->GetOrderNumber(TVDiskIdShort(vdiskId));
- if (groupInfo->GetActorId(orderNumber) != vdiskServiceId) {
- return;
- }
-
- // generate correct VDisk id
- vdiskId = TVDiskID(groupInfo->GroupID, groupInfo->GroupGeneration, vdiskId);
-
- // entangle VDisk with the group
- group.VDisksOfGroup.PushBack(&vdisk);
- } else {
- const auto& dm = vdisk.Config.GetDonorMode();
- TBlobStorageGroupType type(static_cast<TBlobStorageGroupType::EErasureSpecies>(dm.GetErasureSpecies()));
-
- // generate desired group topology
- TBlobStorageGroupInfo::TTopology topology(type, dm.GetNumFailRealms(), dm.GetNumFailDomainsPerFailRealm(),
- dm.GetNumVDisksPerFailDomain());
-
- // fill in dynamic info
- TBlobStorageGroupInfo::TDynamicInfo dyn(vdiskId.GroupID, vdiskId.GroupGeneration);
- for (ui32 i = dm.GetNumFailRealms() * dm.GetNumFailDomainsPerFailRealm() * dm.GetNumVDisksPerFailDomain(); i; --i) {
- dyn.PushBackActorId(TActorId());
- }
-
- // create fake group info
- groupInfo = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dyn),
- vdisk.Config.GetStoragePoolName(), Nothing(), deviceType);
- }
-
- const auto kind = vdisk.Config.HasVDiskKind() ? vdisk.Config.GetVDiskKind() : NKikimrBlobStorage::TVDiskKind::Default;
-
- // just some random number of indicate VDisk actor restart
- const ui64 whiteboardInstanceGuid = RandomNumber<ui64>();
-
- const ui64 scrubCookie = ++LastScrubCookie;
-
- std::vector<std::pair<TVDiskID, TActorId>> donorDiskIds;
- for (const auto& donor : vdisk.Config.GetDonors()) {
- const TVSlotId donorSlot(donor.GetVDiskLocation());
- donorDiskIds.emplace_back(VDiskIDFromVDiskID(donor.GetVDiskId()), donorSlot.GetVDiskServiceId());
- }
-
+
+#include <util/string/split.h>
+
+namespace NKikimr::NStorage {
+
+ void TNodeWarden::DestroyLocalVDisk(TVDiskRecord& vdisk) {
+ STLOG(PRI_INFO, BS_NODE, NW35, "DestroyLocalVDisk", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()));
+ Y_VERIFY(!vdisk.RuntimeData);
+
+ const TVSlotId vslotId = vdisk.GetVSlotId();
+ StopAggregator(MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId));
+
+ if (vdisk.WhiteboardVDiskId) {
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateDelete(*vdisk.WhiteboardVDiskId));
+ vdisk.WhiteboardVDiskId.reset();
+ }
+ }
+
+ void TNodeWarden::PoisonLocalVDisk(TVDiskRecord& vdisk) {
+ STLOG(PRI_INFO, BS_NODE, NW35, "PoisonLocalVDisk", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()),
+ (RuntimeData, vdisk.RuntimeData.has_value()));
+
+ if (vdisk.RuntimeData) {
+ vdisk.TIntrusiveListItem<TVDiskRecord, TGroupRelationTag>::Unlink();
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, vdisk.GetVDiskServiceId(), {}, nullptr, 0));
+ vdisk.RuntimeData.reset();
+ }
+
+ switch (vdisk.ScrubState) {
+ case TVDiskRecord::EScrubState::IDLE: // no scrub in progress at all
+ case TVDiskRecord::EScrubState::QUERY_START_QUANTUM: // VDisk was waiting for quantum and didn't get it
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED: // quantum finished, no work is in progress
+ case TVDiskRecord::EScrubState::QUANTUM_FINISHED_AND_WAITING_FOR_NEXT_ONE: // like QUERY_START_QUANTUM
+ break;
+
+ case TVDiskRecord::EScrubState::IN_PROGRESS: { // scrub is in progress, report scrub stop to BS_CONTROLLER
+ const TVSlotId vslotId = vdisk.GetVSlotId();
+ SendToController(std::make_unique<TEvBlobStorage::TEvControllerScrubQuantumFinished>(vslotId.NodeId,
+ vslotId.PDiskId, vslotId.VDiskSlotId));
+ break;
+ }
+ }
+ vdisk.ScrubState = TVDiskRecord::EScrubState::IDLE;
+ vdisk.QuantumFinished.Clear();
+ vdisk.ScrubCookie = 0; // disable reception of Scrub messages from this disk
+ vdisk.ScrubCookieForController = 0; // and from controller too
+ vdisk.Status = NKikimrBlobStorage::EVDiskStatus::ERROR;
+
+ SendDiskMetrics(false);
+ }
+
+ void TNodeWarden::StartLocalVDiskActor(TVDiskRecord& vdisk, TDuration yardInitDelay) {
+ const TVSlotId vslotId = vdisk.GetVSlotId();
+ const ui64 pdiskGuid = vdisk.Config.GetVDiskLocation().GetPDiskGuid();
+ const bool restartInFlight = InFlightRestartedPDisks.count({vslotId.NodeId, vslotId.PDiskId});
+ const bool donorMode = vdisk.Config.HasDonorMode();
+
+ STLOG(PRI_DEBUG, BS_NODE, NW23, "StartLocalVDiskActor", (RestartInFlight, restartInFlight),
+ (SlayInFlight, vdisk.SlayInFlight), (VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId),
+ (PDiskGuid, pdiskGuid), (DonorMode, donorMode));
+
+ if (restartInFlight || vdisk.SlayInFlight) {
+ return;
+ }
+
+ // find underlying PDisk and determine its media type
+ auto pdiskIt = LocalPDisks.find({vslotId.NodeId, vslotId.PDiskId});
+ Y_VERIFY_S(pdiskIt != LocalPDisks.end(), "PDiskId# " << vslotId.NodeId << ":" << vslotId.PDiskId << " not found");
+ auto& pdisk = pdiskIt->second;
+ Y_VERIFY_S(pdisk.Record.GetPDiskGuid() == pdiskGuid, "PDiskId# " << vslotId.NodeId << ":" << vslotId.PDiskId << " PDiskGuid mismatch");
+ const TPDiskCategory::EDeviceType deviceType = TPDiskCategory(pdisk.Record.GetPDiskCategory()).Type();
+
+ const TActorId pdiskServiceId = MakeBlobStoragePDiskID(vslotId.NodeId, vslotId.PDiskId);
+ const TActorId vdiskServiceId = MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VDiskSlotId);
+
+ // generate correct VDiskId (based on relevant generation of containing group) and groupInfo pointer
+ Y_VERIFY(!vdisk.RuntimeData);
+ TVDiskID vdiskId = vdisk.GetVDiskId();
+ TIntrusivePtr<TBlobStorageGroupInfo> groupInfo;
+
+ if (!donorMode) {
+ // find group containing VDisk being started
+ const auto it = Groups.find(vdisk.GetGroupId());
+ if (it == Groups.end()) {
+ STLOG_DEBUG_FAIL(BS_NODE, NW09, "group not found while starting VDisk actor",
+ (GroupId, vdisk.GetGroupId()), (VDiskId, vdiskId), (Config, vdisk.Config));
+ return;
+ }
+ auto& group = it->second;
+
+ // ensure the group has correctly filled protobuf (in case when there is no relevant info pointer)
+ if (!group.Group) {
+ STLOG_DEBUG_FAIL(BS_NODE, NW13, "group configuration does not contain protobuf to start VDisk",
+ (GroupId, it->first), (VDiskId, vdiskId), (Config, vdisk.Config));
+ return;
+ }
+
+ // obtain group info pointer
+ if (group.Info) {
+ groupInfo = group.Info;
+ } else {
+ TStringStream err;
+ groupInfo = TBlobStorageGroupInfo::Parse(*group.Group, nullptr, nullptr);
+ }
+
+ // check that VDisk belongs to active VDisks of the group
+ const ui32 orderNumber = groupInfo->GetOrderNumber(TVDiskIdShort(vdiskId));
+ if (groupInfo->GetActorId(orderNumber) != vdiskServiceId) {
+ return;
+ }
+
+ // generate correct VDisk id
+ vdiskId = TVDiskID(groupInfo->GroupID, groupInfo->GroupGeneration, vdiskId);
+
+ // entangle VDisk with the group
+ group.VDisksOfGroup.PushBack(&vdisk);
+ } else {
+ const auto& dm = vdisk.Config.GetDonorMode();
+ TBlobStorageGroupType type(static_cast<TBlobStorageGroupType::EErasureSpecies>(dm.GetErasureSpecies()));
+
+ // generate desired group topology
+ TBlobStorageGroupInfo::TTopology topology(type, dm.GetNumFailRealms(), dm.GetNumFailDomainsPerFailRealm(),
+ dm.GetNumVDisksPerFailDomain());
+
+ // fill in dynamic info
+ TBlobStorageGroupInfo::TDynamicInfo dyn(vdiskId.GroupID, vdiskId.GroupGeneration);
+ for (ui32 i = dm.GetNumFailRealms() * dm.GetNumFailDomainsPerFailRealm() * dm.GetNumVDisksPerFailDomain(); i; --i) {
+ dyn.PushBackActorId(TActorId());
+ }
+
+ // create fake group info
+ groupInfo = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dyn),
+ vdisk.Config.GetStoragePoolName(), Nothing(), deviceType);
+ }
+
+ const auto kind = vdisk.Config.HasVDiskKind() ? vdisk.Config.GetVDiskKind() : NKikimrBlobStorage::TVDiskKind::Default;
+
+ // just some random number of indicate VDisk actor restart
+ const ui64 whiteboardInstanceGuid = RandomNumber<ui64>();
+
+ const ui64 scrubCookie = ++LastScrubCookie;
+
+ std::vector<std::pair<TVDiskID, TActorId>> donorDiskIds;
+ for (const auto& donor : vdisk.Config.GetDonors()) {
+ const TVSlotId donorSlot(donor.GetVDiskLocation());
+ donorDiskIds.emplace_back(VDiskIDFromVDiskID(donor.GetVDiskId()), donorSlot.GetVDiskServiceId());
+ }
+
TVDiskConfig::TBaseInfo baseInfo(vdiskId, pdiskServiceId, pdiskGuid, vslotId.PDiskId, deviceType,
- vslotId.VDiskSlotId, kind, NextLocalPDiskInitOwnerRound(), groupInfo->GetStoragePoolName(), donorMode,
- donorDiskIds, scrubCookie, whiteboardInstanceGuid);
-
- baseInfo.ReplPDiskReadQuoter = pdiskIt->second.ReplPDiskReadQuoter;
- baseInfo.ReplPDiskWriteQuoter = pdiskIt->second.ReplPDiskWriteQuoter;
- baseInfo.ReplNodeRequestQuoter = ReplNodeRequestQuoter;
- baseInfo.ReplNodeResponseQuoter = ReplNodeResponseQuoter;
- baseInfo.YardInitDelay = yardInitDelay;
-
- TIntrusivePtr<TVDiskConfig> vdiskConfig = Cfg->AllVDiskKinds->MakeVDiskConfig(baseInfo);
- vdiskConfig->EnableVDiskCooldownTimeout = Cfg->EnableVDiskCooldownTimeout;
- vdiskConfig->ReplPausedAtStart = Cfg->VDiskReplPausedAtStart;
- vdiskConfig->EnableVPatch = EnableVPatch;
-
- // issue initial report to whiteboard before creating actor to avoid races
- Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(vdiskId, groupInfo->GetStoragePoolName(),
- vslotId.PDiskId, vslotId.VDiskSlotId, pdiskGuid, kind, donorMode, whiteboardInstanceGuid));
- vdisk.WhiteboardVDiskId.emplace(vdiskId);
-
- // create an actor
- auto *as = TActivationContext::ActorSystem();
- as->RegisterLocalService(vdiskServiceId, as->Register(CreateVDisk(vdiskConfig, groupInfo, AppData()->Counters),
- TMailboxType::Revolving, AppData()->SystemPoolId));
-
- STLOG(PRI_DEBUG, BS_NODE, NW24, "StartLocalVDiskActor done", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId),
- (PDiskGuid, pdiskGuid));
-
- // for dynamic groups -- start state aggregator
- if (TGroupID(groupInfo->GroupID).ConfigurationType() == GroupConfigurationTypeDynamic) {
- StartAggregator(vdiskServiceId, groupInfo->GroupID);
- }
-
- Y_VERIFY(vdisk.ScrubState == TVDiskRecord::EScrubState::IDLE);
- Y_VERIFY(!vdisk.QuantumFinished.ByteSizeLong());
- Y_VERIFY(!vdisk.ScrubCookie);
-
- vdisk.RuntimeData.emplace(TVDiskRecord::TRuntimeData{
- .GroupInfo = groupInfo,
- .OrderNumber = groupInfo->GetOrderNumber(TVDiskIdShort(vdiskId)),
- .DonorMode = donorMode
- });
-
- vdisk.Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
- vdisk.ReportedVDiskStatus.reset();
- vdisk.ScrubCookie = scrubCookie;
- }
-
- void TNodeWarden::ApplyServiceSetVDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
- for (const auto& vdisk : serviceSet.GetVDisks()) {
- ApplyLocalVDiskInfo(vdisk);
- }
- SendDiskMetrics(false);
- }
-
- void TNodeWarden::ApplyLocalVDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk) {
- // ApplyLocalVDiskInfo invocation may occur only in the following cases:
- //
- // 1. Starting and reading data from cache.
- // 2. Receiving RegisterNode response with comprehensive configuration.
- // 3. Processing GroupReconfigurationWipe command.
- // 4. Deleting VSlot during group reconfiguration or donor termination.
- // 5. Making VDisk a donor one.
- // 6. Updating VDisk generation when modifying group.
- //
- // The main idea of this command is when VDisk is created, it does not change its configuration. It may be
- // wiped out several times, it may become a donor and then it may be destroyed. That is a possible life cycle
- // of a VDisk in the occupied slot.
-
- if (!vdisk.HasVDiskID() || !vdisk.HasVDiskLocation()) {
- STLOG_DEBUG_FAIL(BS_NODE, NW30, "weird VDisk configuration", (Record, vdisk));
- return;
- }
-
- const auto& loc = vdisk.GetVDiskLocation();
- if (loc.GetNodeID() != LocalNodeId) {
- if (TGroupID(vdisk.GetVDiskID().GetGroupID()).ConfigurationType() != GroupConfigurationTypeStatic) {
- STLOG_DEBUG_FAIL(BS_NODE, NW31, "incorrect NodeId in VDisk configuration", (Record, vdisk), (NodeId, LocalNodeId));
- }
- return;
- }
-
- const TVSlotId vslotId(loc);
- const auto [it, inserted] = LocalVDisks.try_emplace(vslotId);
- auto& record = it->second;
- if (!inserted) {
- // -- check that configuration did not change
- }
- record.Config.CopyFrom(vdisk);
-
- if (vdisk.GetDoDestroy() || vdisk.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::DESTROY) {
- if (record.UnderlyingPDiskDestroyed) {
- PoisonLocalVDisk(record);
- SendVDiskReport(vslotId, record.GetVDiskId(), NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
- record.UnderlyingPDiskDestroyed = false;
- } else {
- Slay(record);
- }
- DestroyLocalVDisk(record);
- LocalVDisks.erase(it);
- } else if (vdisk.GetDoWipe()) {
- Slay(record);
- } else if (!record.RuntimeData) {
- StartLocalVDiskActor(record, TDuration::Zero());
- } else if (record.RuntimeData->DonorMode < record.Config.HasDonorMode()) {
- PoisonLocalVDisk(record);
- StartLocalVDiskActor(record, TDuration::Seconds(15) /* PDisk confidence delay */);
- }
- }
-
- void TNodeWarden::Slay(TVDiskRecord& vdisk) {
- STLOG(PRI_INFO, BS_NODE, NW33, "Slay", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()),
- (SlayInFlight, vdisk.SlayInFlight));
- if (!vdisk.SlayInFlight) {
- PoisonLocalVDisk(vdisk);
- const TVSlotId vslotId = vdisk.GetVSlotId();
- const TActorId pdiskServiceId = MakeBlobStoragePDiskID(vslotId.NodeId, vslotId.PDiskId);
- Send(pdiskServiceId, new NPDisk::TEvSlay(vdisk.GetVDiskId(), NextLocalPDiskInitOwnerRound(),
- vslotId.PDiskId, vslotId.VDiskSlotId));
- vdisk.SlayInFlight = true;
- }
- }
-
- void TNodeWarden::Handle(TEvBlobStorage::TEvDropDonor::TPtr ev) {
- auto *msg = ev->Get();
- STLOG(PRI_INFO, BS_NODE, NW34, "TEvDropDonor", (VSlotId, TVSlotId(msg->NodeId, msg->PDiskId, msg->VSlotId)),
- (VDiskId, msg->VDiskId));
- SendDropDonorQuery(msg->NodeId, msg->PDiskId, msg->VSlotId, msg->VDiskId);
- }
-
- void TNodeWarden::UpdateGroupInfoForDisk(TVDiskRecord& vdisk, const TIntrusivePtr<TBlobStorageGroupInfo>& newInfo) {
- if (!vdisk.RuntimeData) {
- return;
- }
-
- TIntrusivePtr<TBlobStorageGroupInfo>& currentInfo = vdisk.RuntimeData->GroupInfo;
- Y_VERIFY(newInfo->GroupID == currentInfo->GroupID);
-
- const ui32 orderNumber = vdisk.RuntimeData->OrderNumber;
- const TActorId vdiskServiceId = vdisk.GetVDiskServiceId();
-
- if (newInfo->GetActorId(orderNumber) != vdiskServiceId) {
- // this disk is in donor mode, we don't care about generation change; donor modes are operated by BSC solely
- return;
- }
-
- // update generation and send update message
- currentInfo = newInfo;
- const TVDiskID newVDiskId = currentInfo->GetVDiskId(orderNumber);
- vdisk.WhiteboardVDiskId.emplace(newVDiskId);
- Send(vdiskServiceId, new TEvVGenerationChange(newVDiskId, currentInfo));
- }
-
-} // NKikimr::NStorage
+ vslotId.VDiskSlotId, kind, NextLocalPDiskInitOwnerRound(), groupInfo->GetStoragePoolName(), donorMode,
+ donorDiskIds, scrubCookie, whiteboardInstanceGuid);
+
+ baseInfo.ReplPDiskReadQuoter = pdiskIt->second.ReplPDiskReadQuoter;
+ baseInfo.ReplPDiskWriteQuoter = pdiskIt->second.ReplPDiskWriteQuoter;
+ baseInfo.ReplNodeRequestQuoter = ReplNodeRequestQuoter;
+ baseInfo.ReplNodeResponseQuoter = ReplNodeResponseQuoter;
+ baseInfo.YardInitDelay = yardInitDelay;
+
+ TIntrusivePtr<TVDiskConfig> vdiskConfig = Cfg->AllVDiskKinds->MakeVDiskConfig(baseInfo);
+ vdiskConfig->EnableVDiskCooldownTimeout = Cfg->EnableVDiskCooldownTimeout;
+ vdiskConfig->ReplPausedAtStart = Cfg->VDiskReplPausedAtStart;
+ vdiskConfig->EnableVPatch = EnableVPatch;
+
+ // issue initial report to whiteboard before creating actor to avoid races
+ Send(WhiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(vdiskId, groupInfo->GetStoragePoolName(),
+ vslotId.PDiskId, vslotId.VDiskSlotId, pdiskGuid, kind, donorMode, whiteboardInstanceGuid));
+ vdisk.WhiteboardVDiskId.emplace(vdiskId);
+
+ // create an actor
+ auto *as = TActivationContext::ActorSystem();
+ as->RegisterLocalService(vdiskServiceId, as->Register(CreateVDisk(vdiskConfig, groupInfo, AppData()->Counters),
+ TMailboxType::Revolving, AppData()->SystemPoolId));
+
+ STLOG(PRI_DEBUG, BS_NODE, NW24, "StartLocalVDiskActor done", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vslotId),
+ (PDiskGuid, pdiskGuid));
+
+ // for dynamic groups -- start state aggregator
+ if (TGroupID(groupInfo->GroupID).ConfigurationType() == GroupConfigurationTypeDynamic) {
+ StartAggregator(vdiskServiceId, groupInfo->GroupID);
+ }
+
+ Y_VERIFY(vdisk.ScrubState == TVDiskRecord::EScrubState::IDLE);
+ Y_VERIFY(!vdisk.QuantumFinished.ByteSizeLong());
+ Y_VERIFY(!vdisk.ScrubCookie);
+
+ vdisk.RuntimeData.emplace(TVDiskRecord::TRuntimeData{
+ .GroupInfo = groupInfo,
+ .OrderNumber = groupInfo->GetOrderNumber(TVDiskIdShort(vdiskId)),
+ .DonorMode = donorMode
+ });
+
+ vdisk.Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+ vdisk.ReportedVDiskStatus.reset();
+ vdisk.ScrubCookie = scrubCookie;
+ }
+
+ void TNodeWarden::ApplyServiceSetVDisks(const NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet) {
+ for (const auto& vdisk : serviceSet.GetVDisks()) {
+ ApplyLocalVDiskInfo(vdisk);
+ }
+ SendDiskMetrics(false);
+ }
+
+ void TNodeWarden::ApplyLocalVDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk) {
+ // ApplyLocalVDiskInfo invocation may occur only in the following cases:
+ //
+ // 1. Starting and reading data from cache.
+ // 2. Receiving RegisterNode response with comprehensive configuration.
+ // 3. Processing GroupReconfigurationWipe command.
+ // 4. Deleting VSlot during group reconfiguration or donor termination.
+ // 5. Making VDisk a donor one.
+ // 6. Updating VDisk generation when modifying group.
+ //
+ // The main idea of this command is when VDisk is created, it does not change its configuration. It may be
+ // wiped out several times, it may become a donor and then it may be destroyed. That is a possible life cycle
+ // of a VDisk in the occupied slot.
+
+ if (!vdisk.HasVDiskID() || !vdisk.HasVDiskLocation()) {
+ STLOG_DEBUG_FAIL(BS_NODE, NW30, "weird VDisk configuration", (Record, vdisk));
+ return;
+ }
+
+ const auto& loc = vdisk.GetVDiskLocation();
+ if (loc.GetNodeID() != LocalNodeId) {
+ if (TGroupID(vdisk.GetVDiskID().GetGroupID()).ConfigurationType() != GroupConfigurationTypeStatic) {
+ STLOG_DEBUG_FAIL(BS_NODE, NW31, "incorrect NodeId in VDisk configuration", (Record, vdisk), (NodeId, LocalNodeId));
+ }
+ return;
+ }
+
+ const TVSlotId vslotId(loc);
+ const auto [it, inserted] = LocalVDisks.try_emplace(vslotId);
+ auto& record = it->second;
+ if (!inserted) {
+ // -- check that configuration did not change
+ }
+ record.Config.CopyFrom(vdisk);
+
+ if (vdisk.GetDoDestroy() || vdisk.GetEntityStatus() == NKikimrBlobStorage::EEntityStatus::DESTROY) {
+ if (record.UnderlyingPDiskDestroyed) {
+ PoisonLocalVDisk(record);
+ SendVDiskReport(vslotId, record.GetVDiskId(), NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
+ record.UnderlyingPDiskDestroyed = false;
+ } else {
+ Slay(record);
+ }
+ DestroyLocalVDisk(record);
+ LocalVDisks.erase(it);
+ } else if (vdisk.GetDoWipe()) {
+ Slay(record);
+ } else if (!record.RuntimeData) {
+ StartLocalVDiskActor(record, TDuration::Zero());
+ } else if (record.RuntimeData->DonorMode < record.Config.HasDonorMode()) {
+ PoisonLocalVDisk(record);
+ StartLocalVDiskActor(record, TDuration::Seconds(15) /* PDisk confidence delay */);
+ }
+ }
+
+ void TNodeWarden::Slay(TVDiskRecord& vdisk) {
+ STLOG(PRI_INFO, BS_NODE, NW33, "Slay", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId()),
+ (SlayInFlight, vdisk.SlayInFlight));
+ if (!vdisk.SlayInFlight) {
+ PoisonLocalVDisk(vdisk);
+ const TVSlotId vslotId = vdisk.GetVSlotId();
+ const TActorId pdiskServiceId = MakeBlobStoragePDiskID(vslotId.NodeId, vslotId.PDiskId);
+ Send(pdiskServiceId, new NPDisk::TEvSlay(vdisk.GetVDiskId(), NextLocalPDiskInitOwnerRound(),
+ vslotId.PDiskId, vslotId.VDiskSlotId));
+ vdisk.SlayInFlight = true;
+ }
+ }
+
+ void TNodeWarden::Handle(TEvBlobStorage::TEvDropDonor::TPtr ev) {
+ auto *msg = ev->Get();
+ STLOG(PRI_INFO, BS_NODE, NW34, "TEvDropDonor", (VSlotId, TVSlotId(msg->NodeId, msg->PDiskId, msg->VSlotId)),
+ (VDiskId, msg->VDiskId));
+ SendDropDonorQuery(msg->NodeId, msg->PDiskId, msg->VSlotId, msg->VDiskId);
+ }
+
+ void TNodeWarden::UpdateGroupInfoForDisk(TVDiskRecord& vdisk, const TIntrusivePtr<TBlobStorageGroupInfo>& newInfo) {
+ if (!vdisk.RuntimeData) {
+ return;
+ }
+
+ TIntrusivePtr<TBlobStorageGroupInfo>& currentInfo = vdisk.RuntimeData->GroupInfo;
+ Y_VERIFY(newInfo->GroupID == currentInfo->GroupID);
+
+ const ui32 orderNumber = vdisk.RuntimeData->OrderNumber;
+ const TActorId vdiskServiceId = vdisk.GetVDiskServiceId();
+
+ if (newInfo->GetActorId(orderNumber) != vdiskServiceId) {
+ // this disk is in donor mode, we don't care about generation change; donor modes are operated by BSC solely
+ return;
+ }
+
+ // update generation and send update message
+ currentInfo = newInfo;
+ const TVDiskID newVDiskId = currentInfo->GetVDiskId(orderNumber);
+ vdisk.WhiteboardVDiskId.emplace(newVDiskId);
+ Send(vdiskServiceId, new TEvVGenerationChange(newVDiskId, currentInfo));
+ }
+
+} // NKikimr::NStorage
diff --git a/ydb/core/blobstorage/nodewarden/ut/ya.make b/ydb/core/blobstorage/nodewarden/ut/ya.make
index a6aac874852..a21382f4f4a 100644
--- a/ydb/core/blobstorage/nodewarden/ut/ya.make
+++ b/ydb/core/blobstorage/nodewarden/ut/ya.make
@@ -1,12 +1,12 @@
UNITTEST_FOR(ydb/core/blobstorage/nodewarden)
-
+
FORK_SUBTESTS()
OWNER(
alexvru
g:kikimr
)
-
+
IF (SANITIZER_TYPE OR WITH_VALGRIND)
TIMEOUT(1200)
SIZE(LARGE)
@@ -16,16 +16,16 @@ ELSE()
SIZE(MEDIUM)
ENDIF()
-PEERDIR(
+PEERDIR(
ydb/core/testlib
-)
-
-SRCS(
- blobstorage_node_warden_ut.cpp
-)
-
+)
+
+SRCS(
+ blobstorage_node_warden_ut.cpp
+)
+
YQL_LAST_ABI_VERSION()
REQUIREMENTS(ram:14)
-END()
+END()
diff --git a/ydb/core/blobstorage/nodewarden/ut_sequence/dsproxy_config_retrieval.cpp b/ydb/core/blobstorage/nodewarden/ut_sequence/dsproxy_config_retrieval.cpp
index 040411e06c3..c660369cafe 100644
--- a/ydb/core/blobstorage/nodewarden/ut_sequence/dsproxy_config_retrieval.cpp
+++ b/ydb/core/blobstorage/nodewarden/ut_sequence/dsproxy_config_retrieval.cpp
@@ -7,193 +7,193 @@
#include <ydb/core/testlib/basics/helpers.h>
#include <ydb/core/testlib/tablet_helpers.h>
#include <ydb/core/mind/bscontroller/bsc.h>
-#include <util/system/compat.h>
-
-using namespace NKikimr;
-using namespace NActors;
-
-void SetupLogging(TTestBasicRuntime& runtime) {
- runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
- runtime.SetLogPriority(NKikimrServices::BS_NODE, NLog::PRI_DEBUG);
-}
-
-void SetupServices(TTestBasicRuntime& runtime) {
- TAppPrepare app;
-
- app.ClearDomainsAndHive();
- auto dom = TDomainsInfo::TDomain::ConstructEmptyDomain("dom-1", 0);
- app.AddDomain(dom.Release());
-
- TTempDir temp;
+#include <util/system/compat.h>
+
+using namespace NKikimr;
+using namespace NActors;
+
+void SetupLogging(TTestBasicRuntime& runtime) {
+ runtime.SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::BS_NODE, NLog::PRI_DEBUG);
+}
+
+void SetupServices(TTestBasicRuntime& runtime) {
+ TAppPrepare app;
+
+ app.ClearDomainsAndHive();
+ auto dom = TDomainsInfo::TDomain::ConstructEmptyDomain("dom-1", 0);
+ app.AddDomain(dom.Release());
+
+ TTempDir temp;
TString path = "SectorMap:" + temp() + "static.dat";
- ui64 pdiskSize = 32ULL << 30;
- ui64 chunkSize = 32ULL << 20;
- ui64 guid = RandomNumber<ui64>();
- auto sectorMap = MakeIntrusive<NPDisk::TSectorMap>(pdiskSize);
+ ui64 pdiskSize = 32ULL << 30;
+ ui64 chunkSize = 32ULL << 20;
+ ui64 guid = RandomNumber<ui64>();
+ auto sectorMap = MakeIntrusive<NPDisk::TSectorMap>(pdiskSize);
FormatPDisk(path, 0, 4096, chunkSize, guid, 0x1234567890 + 1, 0x4567890123 + 1, 0x7890123456 + 1,
NPDisk::YdbDefaultPDiskSequence, TString(), false, false, sectorMap);
-
- // per-node NodeWarden configurations; node 0 has the static group and the BS_CONTROLLER tablet
- THashMap<ui32, NKikimrBlobStorage::TNodeWardenServiceSet> configs;
- auto& st = configs[0];
- auto& pdisk = *st.AddPDisks();
- pdisk.SetNodeID(runtime.GetNodeId(0));
- pdisk.SetPDiskID(1);
- pdisk.SetPath(path);
- pdisk.SetPDiskGuid(guid);
- pdisk.SetPDiskCategory(0);
- pdisk.MutablePDiskConfig()->SetExpectedSlotCount(2);
- auto& vdisk = *st.AddVDisks();
- auto& id = *vdisk.MutableVDiskID();
- id.SetGroupID(0);
- id.SetGroupGeneration(1);
- id.SetRing(0);
- id.SetDomain(0);
- id.SetVDisk(0);
- auto& loc = *vdisk.MutableVDiskLocation();
- loc.SetNodeID(pdisk.GetNodeID());
- loc.SetPDiskID(pdisk.GetPDiskID());
- loc.SetVDiskSlotID(1);
- loc.SetPDiskGuid(pdisk.GetPDiskGuid());
- vdisk.SetVDiskKind(NKikimrBlobStorage::TVDiskKind::Default);
- auto& g = *st.AddGroups();
- g.SetGroupID(0);
- g.SetGroupGeneration(1);
- g.SetErasureSpecies(0);
- auto& r = *g.AddRings();
- auto& d = *r.AddFailDomains();
- auto& l = *d.AddVDiskLocations();
- l.CopyFrom(loc);
- st.AddAvailabilityDomains(0);
- app.BSConf = st;
-
- for (ui32 i = 0; i < runtime.GetNodeCount(); ++i) {
- SetupStateStorage(runtime, i);
- auto config = MakeIntrusive<TNodeWardenConfig>(new TStrandedPDiskServiceFactory(runtime));
- config->SectorMaps[path] = sectorMap;
- config->ServiceSet = configs[i];
- SetupBSNodeWarden(runtime, i, config);
- SetupTabletResolver(runtime, i);
- SetupNodeWhiteboard(runtime, i);
- }
-
- runtime.Initialize(app.Unwrap());
-
+
+ // per-node NodeWarden configurations; node 0 has the static group and the BS_CONTROLLER tablet
+ THashMap<ui32, NKikimrBlobStorage::TNodeWardenServiceSet> configs;
+ auto& st = configs[0];
+ auto& pdisk = *st.AddPDisks();
+ pdisk.SetNodeID(runtime.GetNodeId(0));
+ pdisk.SetPDiskID(1);
+ pdisk.SetPath(path);
+ pdisk.SetPDiskGuid(guid);
+ pdisk.SetPDiskCategory(0);
+ pdisk.MutablePDiskConfig()->SetExpectedSlotCount(2);
+ auto& vdisk = *st.AddVDisks();
+ auto& id = *vdisk.MutableVDiskID();
+ id.SetGroupID(0);
+ id.SetGroupGeneration(1);
+ id.SetRing(0);
+ id.SetDomain(0);
+ id.SetVDisk(0);
+ auto& loc = *vdisk.MutableVDiskLocation();
+ loc.SetNodeID(pdisk.GetNodeID());
+ loc.SetPDiskID(pdisk.GetPDiskID());
+ loc.SetVDiskSlotID(1);
+ loc.SetPDiskGuid(pdisk.GetPDiskGuid());
+ vdisk.SetVDiskKind(NKikimrBlobStorage::TVDiskKind::Default);
+ auto& g = *st.AddGroups();
+ g.SetGroupID(0);
+ g.SetGroupGeneration(1);
+ g.SetErasureSpecies(0);
+ auto& r = *g.AddRings();
+ auto& d = *r.AddFailDomains();
+ auto& l = *d.AddVDiskLocations();
+ l.CopyFrom(loc);
+ st.AddAvailabilityDomains(0);
+ app.BSConf = st;
+
+ for (ui32 i = 0; i < runtime.GetNodeCount(); ++i) {
+ SetupStateStorage(runtime, i);
+ auto config = MakeIntrusive<TNodeWardenConfig>(new TStrandedPDiskServiceFactory(runtime));
+ config->SectorMaps[path] = sectorMap;
+ config->ServiceSet = configs[i];
+ SetupBSNodeWarden(runtime, i, config);
+ SetupTabletResolver(runtime, i);
+ SetupNodeWhiteboard(runtime, i);
+ }
+
+ runtime.Initialize(app.Unwrap());
+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(MakeBSControllerID(0), TTabletTypes::FLAT_BS_CONTROLLER), &CreateFlatBsController);
-
- // setup box and storage pool for testing
- {
+
+ // setup box and storage pool for testing
+ {
TActorId edge = runtime.AllocateEdgeActor();
-
+
runtime.Send(new IEventHandle(GetNameserviceActorId(), edge, new TEvInterconnect::TEvListNodes));
- TAutoPtr<IEventHandle> handleNodesInfo;
- auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
-
- ui32 nodeId = runtime.GetNodeId(0);
- Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
- auto& nodeInfo = nodesInfo->Nodes[0];
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
- auto *r = ev->Record.MutableRequest();
- auto *hc = r->AddCommand()->MutableDefineHostConfig();
- hc->SetHostConfigId(1);
- auto *d = hc->AddDrive();
- d->SetPath(pdisk.GetPath());
- d->SetType(NKikimrBlobStorage::ROT);
- d->MutablePDiskConfig()->SetExpectedSlotCount(2);
- auto *db = r->AddCommand()->MutableDefineBox();
- db->SetBoxId(1);
- auto *h = db->AddHost();
- auto *hk = h->MutableKey();
- hk->SetFqdn(nodeInfo.Host);
- hk->SetIcPort(nodeInfo.Port);
- h->SetHostConfigId(hc->GetHostConfigId());
- auto *ds = r->AddCommand()->MutableDefineStoragePool();
- ds->SetBoxId(db->GetBoxId());
- ds->SetStoragePoolId(1);
- ds->SetErasureSpecies("none");
- ds->SetVDiskKind("Default");
- ds->SetNumGroups(1);
- ds->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
-
- runtime.SendToPipe(MakeBSControllerID(0), edge, ev.release());
- auto resp = runtime.GrabEdgeEvent<TEvBlobStorage::TEvControllerConfigResponse>(edge);
- const auto& record = resp->Get()->Record;
- UNIT_ASSERT(record.GetResponse().GetSuccess());
- }
-}
-
-void Setup(TTestBasicRuntime& runtime) {
- SetupLogging(runtime);
- SetupServices(runtime);
-}
-
-Y_UNIT_TEST_SUITE(NodeWardenDsProxyConfigRetrieval) {
-
- Y_UNIT_TEST(Disconnect) {
- TTestBasicRuntime runtime(1);
-
- const ui32 groupId = 0x80000000;
- const ui64 tabletId = MakeBSControllerID(0);
- bool allowConfiguring = false;
-
+ TAutoPtr<IEventHandle> handleNodesInfo;
+ auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
+
+ ui32 nodeId = runtime.GetNodeId(0);
+ Y_VERIFY(nodesInfo->Nodes[0].NodeId == nodeId);
+ auto& nodeInfo = nodesInfo->Nodes[0];
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto *r = ev->Record.MutableRequest();
+ auto *hc = r->AddCommand()->MutableDefineHostConfig();
+ hc->SetHostConfigId(1);
+ auto *d = hc->AddDrive();
+ d->SetPath(pdisk.GetPath());
+ d->SetType(NKikimrBlobStorage::ROT);
+ d->MutablePDiskConfig()->SetExpectedSlotCount(2);
+ auto *db = r->AddCommand()->MutableDefineBox();
+ db->SetBoxId(1);
+ auto *h = db->AddHost();
+ auto *hk = h->MutableKey();
+ hk->SetFqdn(nodeInfo.Host);
+ hk->SetIcPort(nodeInfo.Port);
+ h->SetHostConfigId(hc->GetHostConfigId());
+ auto *ds = r->AddCommand()->MutableDefineStoragePool();
+ ds->SetBoxId(db->GetBoxId());
+ ds->SetStoragePoolId(1);
+ ds->SetErasureSpecies("none");
+ ds->SetVDiskKind("Default");
+ ds->SetNumGroups(1);
+ ds->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
+
+ runtime.SendToPipe(MakeBSControllerID(0), edge, ev.release());
+ auto resp = runtime.GrabEdgeEvent<TEvBlobStorage::TEvControllerConfigResponse>(edge);
+ const auto& record = resp->Get()->Record;
+ UNIT_ASSERT(record.GetResponse().GetSuccess());
+ }
+}
+
+void Setup(TTestBasicRuntime& runtime) {
+ SetupLogging(runtime);
+ SetupServices(runtime);
+}
+
+Y_UNIT_TEST_SUITE(NodeWardenDsProxyConfigRetrieval) {
+
+ Y_UNIT_TEST(Disconnect) {
+ TTestBasicRuntime runtime(1);
+
+ const ui32 groupId = 0x80000000;
+ const ui64 tabletId = MakeBSControllerID(0);
+ bool allowConfiguring = false;
+
TActorId nodeWardenId;
- TTestActorRuntimeBase::TRegistrationObserver prevReg = runtime.SetRegistrationObserverFunc(
+ TTestActorRuntimeBase::TRegistrationObserver prevReg = runtime.SetRegistrationObserverFunc(
[&](TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) {
- if (IActor *actor = runtime.FindActor(actorId); dynamic_cast<NKikimr::NStorage::TNodeWarden*>(actor)) {
- UNIT_ASSERT(!nodeWardenId);
- nodeWardenId = actorId;
- runtime.EnableScheduleForActor(actorId);
- Cerr << "Caught NodeWarden registration actorId# " << actorId << Endl;
- }
- return prevReg(runtime, parentId, actorId);
- });
-
+ if (IActor *actor = runtime.FindActor(actorId); dynamic_cast<NKikimr::NStorage::TNodeWarden*>(actor)) {
+ UNIT_ASSERT(!nodeWardenId);
+ nodeWardenId = actorId;
+ runtime.EnableScheduleForActor(actorId);
+ Cerr << "Caught NodeWarden registration actorId# " << actorId << Endl;
+ }
+ return prevReg(runtime, parentId, actorId);
+ });
+
TActorId clientId;
- TTestActorRuntimeBase::TEventObserver prev = runtime.SetObserverFunc(
- [&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& ev) {
- if (auto *msg = ev->CastAsLocal<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>()) {
- for (const auto& group : msg->Record.GetServiceSet().GetGroups()) {
- if (group.GetGroupID() == groupId && !allowConfiguring) {
- return TTestActorRuntimeBase::EEventAction::DROP;
- }
- }
- } else if (auto *msg = ev->CastAsLocal<TEvTabletPipe::TEvClientConnected>()) {
- if (ev->Recipient == nodeWardenId && msg->TabletId == tabletId && msg->Status == NKikimrProto::OK) {
- Cerr << "Pipe connected clientId# " << msg->ClientId << Endl;
- UNIT_ASSERT(!clientId);
- clientId = msg->ClientId;
- }
- } else if (auto *msg = ev->CastAsLocal<TEvTabletPipe::TEvClientDestroyed>()) {
- if (ev->Recipient == nodeWardenId && msg->TabletId == tabletId) {
- Cerr << "Pipe disconnected clientId# " << msg->ClientId << Endl;
- UNIT_ASSERT_VALUES_EQUAL(clientId, msg->ClientId);
- clientId = {};
- }
- }
- return prev(runtime, ev);
- });
-
- Setup(runtime);
-
- // wait for pipe to establish
- TDispatchOptions opts;
- opts.CustomFinalCondition = [&] { return !!clientId; };
- Cerr << "=== Waiting for pipe to establish ===" << Endl;
- runtime.DispatchEvents(opts);
-
- // trigger event
+ TTestActorRuntimeBase::TEventObserver prev = runtime.SetObserverFunc(
+ [&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& ev) {
+ if (auto *msg = ev->CastAsLocal<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>()) {
+ for (const auto& group : msg->Record.GetServiceSet().GetGroups()) {
+ if (group.GetGroupID() == groupId && !allowConfiguring) {
+ return TTestActorRuntimeBase::EEventAction::DROP;
+ }
+ }
+ } else if (auto *msg = ev->CastAsLocal<TEvTabletPipe::TEvClientConnected>()) {
+ if (ev->Recipient == nodeWardenId && msg->TabletId == tabletId && msg->Status == NKikimrProto::OK) {
+ Cerr << "Pipe connected clientId# " << msg->ClientId << Endl;
+ UNIT_ASSERT(!clientId);
+ clientId = msg->ClientId;
+ }
+ } else if (auto *msg = ev->CastAsLocal<TEvTabletPipe::TEvClientDestroyed>()) {
+ if (ev->Recipient == nodeWardenId && msg->TabletId == tabletId) {
+ Cerr << "Pipe disconnected clientId# " << msg->ClientId << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(clientId, msg->ClientId);
+ clientId = {};
+ }
+ }
+ return prev(runtime, ev);
+ });
+
+ Setup(runtime);
+
+ // wait for pipe to establish
+ TDispatchOptions opts;
+ opts.CustomFinalCondition = [&] { return !!clientId; };
+ Cerr << "=== Waiting for pipe to establish ===" << Endl;
+ runtime.DispatchEvents(opts);
+
+ // trigger event
const TActorId recip = MakeBlobStorageProxyID(groupId);
const TActorId sender = runtime.AllocateEdgeActor(0);
const TActorId warden = MakeBlobStorageNodeWardenID(runtime.GetNodeId(0));
- Cerr << "=== Breaking pipe ===" << Endl;
+ Cerr << "=== Breaking pipe ===" << Endl;
runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, clientId, TActorId(), {}, 0));
- Cerr << "=== Sending put ===" << Endl;
- runtime.Send(new IEventHandle(recip, sender, new TEvBlobStorage::TEvPut(TLogoBlobID(1, 1, 1, 1, 1, 1), "1", TInstant::Max()),
- IEventHandle::FlagForwardOnNondelivery, 0, &warden), 0, true);
- allowConfiguring = true;
- auto res = runtime.GrabEdgeEvent<TEvBlobStorage::TEvPutResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
-}
+ Cerr << "=== Sending put ===" << Endl;
+ runtime.Send(new IEventHandle(recip, sender, new TEvBlobStorage::TEvPut(TLogoBlobID(1, 1, 1, 1, 1, 1), "1", TInstant::Max()),
+ IEventHandle::FlagForwardOnNondelivery, 0, &warden), 0, true);
+ allowConfiguring = true;
+ auto res = runtime.GrabEdgeEvent<TEvBlobStorage::TEvPutResult>(sender);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+}
diff --git a/ydb/core/blobstorage/nodewarden/ut_sequence/ya.make b/ydb/core/blobstorage/nodewarden/ut_sequence/ya.make
index 14e17be1045..9084ca3b9e9 100644
--- a/ydb/core/blobstorage/nodewarden/ut_sequence/ya.make
+++ b/ydb/core/blobstorage/nodewarden/ut_sequence/ya.make
@@ -1,5 +1,5 @@
-UNITTEST()
-
+UNITTEST()
+
OWNER(
alexvru
g:kikimr
@@ -8,19 +8,19 @@ OWNER(
SIZE(MEDIUM)
TIMEOUT(600)
-
-PEERDIR(
+
+PEERDIR(
ydb/core/blobstorage/base
ydb/core/blobstorage/crypto
ydb/core/blobstorage/nodewarden
ydb/core/blobstorage/pdisk
ydb/core/testlib
-)
-
-SRCS(
- dsproxy_config_retrieval.cpp
-)
-
+)
+
+SRCS(
+ dsproxy_config_retrieval.cpp
+)
+
YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/core/blobstorage/nodewarden/ya.make b/ydb/core/blobstorage/nodewarden/ya.make
index b43e61e02dd..cbb69222714 100644
--- a/ydb/core/blobstorage/nodewarden/ya.make
+++ b/ydb/core/blobstorage/nodewarden/ya.make
@@ -7,19 +7,19 @@ OWNER(
)
SRCS(
- group_stat_aggregator.cpp
- node_warden_cache.cpp
- node_warden_group.cpp
- node_warden_group_resolver.cpp
- node_warden_impl.cpp
+ group_stat_aggregator.cpp
+ node_warden_cache.cpp
+ node_warden_group.cpp
+ node_warden_group_resolver.cpp
+ node_warden_impl.cpp
node_warden_mon.cpp
- node_warden_pdisk.cpp
- node_warden_pipe.cpp
- node_warden_proxy.cpp
- node_warden_resource.cpp
- node_warden_scrub.cpp
- node_warden_stat_aggr.cpp
- node_warden_vdisk.cpp
+ node_warden_pdisk.cpp
+ node_warden_pipe.cpp
+ node_warden_proxy.cpp
+ node_warden_resource.cpp
+ node_warden_scrub.cpp
+ node_warden_stat_aggr.cpp
+ node_warden_vdisk.cpp
)
PEERDIR(
diff --git a/ydb/core/blobstorage/other/mon_blob_range_page.cpp b/ydb/core/blobstorage/other/mon_blob_range_page.cpp
index f4797d62e24..334abc7283c 100644
--- a/ydb/core/blobstorage/other/mon_blob_range_page.cpp
+++ b/ydb/core/blobstorage/other/mon_blob_range_page.cpp
@@ -1,216 +1,216 @@
-#include "mon_blob_range_page.h"
+#include "mon_blob_range_page.h"
#include <ydb/core/base/blobstorage.h>
#include <library/cpp/json/writer/json.h>
#include <library/cpp/json/writer/json_value.h>
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/threading/future/future.h>
-
-namespace NKikimr {
-
-namespace {
-
- class TMonBlobRangePage
- : public NMonitoring::IMonPage
- {
- class TRequestActor
- : public TActorBootstrapped<TRequestActor>
- {
- const ui32 GroupId;
- std::unique_ptr<TEvBlobStorage::TEvRange> Query;
- NThreading::TPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>> Promise;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GET_ACTOR;
- }
-
- TRequestActor(ui32 groupId, ui64 tabletId, const TLogoBlobID& from, const TLogoBlobID& to,
- NThreading::TPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>> promise)
- : GroupId(groupId)
- , Query(std::make_unique<TEvBlobStorage::TEvRange>(tabletId, from, to, false, TInstant::Max(), true))
- , Promise(std::move(promise))
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- SendToBSProxy(ctx, GroupId, Query.release());
- Become(&TThis::StateFunc);
- }
-
- void Handle(TEvBlobStorage::TEvRangeResult::TPtr& ev, const TActorContext& ctx) {
- Promise.SetValue(std::unique_ptr<TEvBlobStorage::TEvRangeResult>(ev->Release().Release()));
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvRangeResult, Handle)
- )
- };
-
- private:
- TActorSystem *ActorSystem;
-
- public:
- TMonBlobRangePage(const TString& path, TActorSystem *actorSystem)
- : IMonPage(path)
- , ActorSystem(actorSystem)
- {}
-
+
+namespace NKikimr {
+
+namespace {
+
+ class TMonBlobRangePage
+ : public NMonitoring::IMonPage
+ {
+ class TRequestActor
+ : public TActorBootstrapped<TRequestActor>
+ {
+ const ui32 GroupId;
+ std::unique_ptr<TEvBlobStorage::TEvRange> Query;
+ NThreading::TPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>> Promise;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GET_ACTOR;
+ }
+
+ TRequestActor(ui32 groupId, ui64 tabletId, const TLogoBlobID& from, const TLogoBlobID& to,
+ NThreading::TPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>> promise)
+ : GroupId(groupId)
+ , Query(std::make_unique<TEvBlobStorage::TEvRange>(tabletId, from, to, false, TInstant::Max(), true))
+ , Promise(std::move(promise))
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ SendToBSProxy(ctx, GroupId, Query.release());
+ Become(&TThis::StateFunc);
+ }
+
+ void Handle(TEvBlobStorage::TEvRangeResult::TPtr& ev, const TActorContext& ctx) {
+ Promise.SetValue(std::unique_ptr<TEvBlobStorage::TEvRangeResult>(ev->Release().Release()));
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvRangeResult, Handle)
+ )
+ };
+
+ private:
+ TActorSystem *ActorSystem;
+
+ public:
+ TMonBlobRangePage(const TString& path, TActorSystem *actorSystem)
+ : IMonPage(path)
+ , ActorSystem(actorSystem)
+ {}
+
void Output(NMonitoring::IMonHttpRequest& request) override {
IOutputStream& out = request.Output();
-
- // parse HTTP request
+
+ // parse HTTP request
const TCgiParameters& params = request.GetParams();
-
- auto generateError = [&](const TString& msg) {
- out << "HTTP/1.1 400 Bad Request\r\n"
- << "Content-Type: text/plain\r\n"
- << "Connection: close\r\n"
- << "\r\n"
- << msg << "\r\n";
- };
-
- ui32 groupId = 0;
- if (!params.Has("groupId")) {
- return generateError("Missing groupId parameter");
- } else if (!TryFromString(params.Get("groupId"), groupId)) {
- return generateError("Failed to parse groupId parameter -- must be an integer");
- }
-
- ui64 tabletId = 0;
- if (!params.Has("tabletId")) {
- return generateError("Missing tabletId parameter");
- } else if (!TryFromString(params.Get("tabletId"), tabletId)) {
- return generateError("Failed to parse tabletId parameter -- must be an integer");
- }
-
- ui32 json = 0;
- TLogoBlobID from, to;
- TString errorExplanation;
- if (!params.Has("from")) {
- return generateError("Missing from parameter");
- } else if (!TLogoBlobID::Parse(from, params.Get("from"), errorExplanation)) {
- return generateError("Failed to parse from parameter -- " + errorExplanation);
- } else if (from != from.FullID()) {
- return generateError("Desired blob must be full one");
- }
- if (!params.Has("to")) {
- return generateError("Missing to parameter");
- } else if (!TLogoBlobID::Parse(to, params.Get("to"), errorExplanation)) {
- return generateError("Failed to parse to parameter -- " + errorExplanation);
- } else if (to != to.FullID()) {
- return generateError("Desired blob must be full one");
- }
- if (params.Has("json")) {
- if (!TryFromString(params.Get("json"), json)) {
- return generateError("Failed to parse json parameter -- must be an integer");
- }
- }
-
- // create promise & future to obtain query result
- auto promise = NThreading::NewPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>>();
- auto future = promise.GetFuture();
-
- // register and start actor
- ActorSystem->Register(new TRequestActor(groupId, tabletId, from, to, std::move(promise)));
-
- // wait for query to complete
- future.Wait();
-
- // obtain result
- const std::unique_ptr<TEvBlobStorage::TEvRangeResult>& result = future.GetValue();
-
- if (json) {
- out << NMonitoring::HTTPOKJSON;
-
- NJson::TJsonValue root;
- root["Status"] = NKikimrProto::EReplyStatus_Name(result->Status);
- if (result->ErrorReason) {
- root["ErrorReason"] = result->ErrorReason;
- }
- NJson::TJsonValue blobs(NJson::JSON_ARRAY);
- for (const auto& blob : result->Responses) {
- blobs.AppendValue(blob.Id.ToString());
- }
- root["Blobs"] = blobs;
-
- NJsonWriter::TBuf buf;
- buf.WriteJsonValue(&root);
- out << buf.Str();
-
- return;
- }
-
- out << NMonitoring::HTTPOKHTML;
-
- HTML(out) {
- out << "<!DOCTYPE html>\n";
- HTML_TAG() {
- HEAD() {
- out << "<title>Blob Range Index Query</title>\n";
- out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
- out << "<style type=\"text/css\">\n";
- out << ".table-nonfluid { width: auto; }\n";
- out << ".narrow-line50 {line-height: 50%}\n";
- out << ".narrow-line60 {line-height: 60%}\n";
- out << ".narrow-line70 {line-height: 70%}\n";
- out << ".narrow-line80 {line-height: 80%}\n";
- out << ".narrow-line90 {line-height: 90%}\n";
- out << "</style>\n";
- }
- BODY() {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Blob Data";
- }
- DIV_CLASS("panel-body") {
- DIV() {
- out << "Status: ";
- STRONG() {
- out << NKikimrProto::EReplyStatus_Name(result->Status);
- }
- }
-
- if (result->ErrorReason) {
- DIV() {
- out << "ErrorReason: ";
- STRONG() {
- out << result->ErrorReason;
- }
- }
- }
-
- TABLE() {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- out << "LogoBlobId";
- }
- }
- }
- TABLEBODY() {
- for (const auto& blob : result->Responses) {
- TABLER() {
- TABLED() {
- out << blob.Id.ToString();
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- };
-
-} // anon
-
-NMonitoring::IMonPage *CreateMonBlobRangePage(const TString& path, TActorSystem *actorSystem) {
- return new TMonBlobRangePage(path, actorSystem);
-}
-
-} // NKikimr
+
+ auto generateError = [&](const TString& msg) {
+ out << "HTTP/1.1 400 Bad Request\r\n"
+ << "Content-Type: text/plain\r\n"
+ << "Connection: close\r\n"
+ << "\r\n"
+ << msg << "\r\n";
+ };
+
+ ui32 groupId = 0;
+ if (!params.Has("groupId")) {
+ return generateError("Missing groupId parameter");
+ } else if (!TryFromString(params.Get("groupId"), groupId)) {
+ return generateError("Failed to parse groupId parameter -- must be an integer");
+ }
+
+ ui64 tabletId = 0;
+ if (!params.Has("tabletId")) {
+ return generateError("Missing tabletId parameter");
+ } else if (!TryFromString(params.Get("tabletId"), tabletId)) {
+ return generateError("Failed to parse tabletId parameter -- must be an integer");
+ }
+
+ ui32 json = 0;
+ TLogoBlobID from, to;
+ TString errorExplanation;
+ if (!params.Has("from")) {
+ return generateError("Missing from parameter");
+ } else if (!TLogoBlobID::Parse(from, params.Get("from"), errorExplanation)) {
+ return generateError("Failed to parse from parameter -- " + errorExplanation);
+ } else if (from != from.FullID()) {
+ return generateError("Desired blob must be full one");
+ }
+ if (!params.Has("to")) {
+ return generateError("Missing to parameter");
+ } else if (!TLogoBlobID::Parse(to, params.Get("to"), errorExplanation)) {
+ return generateError("Failed to parse to parameter -- " + errorExplanation);
+ } else if (to != to.FullID()) {
+ return generateError("Desired blob must be full one");
+ }
+ if (params.Has("json")) {
+ if (!TryFromString(params.Get("json"), json)) {
+ return generateError("Failed to parse json parameter -- must be an integer");
+ }
+ }
+
+ // create promise & future to obtain query result
+ auto promise = NThreading::NewPromise<std::unique_ptr<TEvBlobStorage::TEvRangeResult>>();
+ auto future = promise.GetFuture();
+
+ // register and start actor
+ ActorSystem->Register(new TRequestActor(groupId, tabletId, from, to, std::move(promise)));
+
+ // wait for query to complete
+ future.Wait();
+
+ // obtain result
+ const std::unique_ptr<TEvBlobStorage::TEvRangeResult>& result = future.GetValue();
+
+ if (json) {
+ out << NMonitoring::HTTPOKJSON;
+
+ NJson::TJsonValue root;
+ root["Status"] = NKikimrProto::EReplyStatus_Name(result->Status);
+ if (result->ErrorReason) {
+ root["ErrorReason"] = result->ErrorReason;
+ }
+ NJson::TJsonValue blobs(NJson::JSON_ARRAY);
+ for (const auto& blob : result->Responses) {
+ blobs.AppendValue(blob.Id.ToString());
+ }
+ root["Blobs"] = blobs;
+
+ NJsonWriter::TBuf buf;
+ buf.WriteJsonValue(&root);
+ out << buf.Str();
+
+ return;
+ }
+
+ out << NMonitoring::HTTPOKHTML;
+
+ HTML(out) {
+ out << "<!DOCTYPE html>\n";
+ HTML_TAG() {
+ HEAD() {
+ out << "<title>Blob Range Index Query</title>\n";
+ out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
+ out << "<style type=\"text/css\">\n";
+ out << ".table-nonfluid { width: auto; }\n";
+ out << ".narrow-line50 {line-height: 50%}\n";
+ out << ".narrow-line60 {line-height: 60%}\n";
+ out << ".narrow-line70 {line-height: 70%}\n";
+ out << ".narrow-line80 {line-height: 80%}\n";
+ out << ".narrow-line90 {line-height: 90%}\n";
+ out << "</style>\n";
+ }
+ BODY() {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Blob Data";
+ }
+ DIV_CLASS("panel-body") {
+ DIV() {
+ out << "Status: ";
+ STRONG() {
+ out << NKikimrProto::EReplyStatus_Name(result->Status);
+ }
+ }
+
+ if (result->ErrorReason) {
+ DIV() {
+ out << "ErrorReason: ";
+ STRONG() {
+ out << result->ErrorReason;
+ }
+ }
+ }
+
+ TABLE() {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() {
+ out << "LogoBlobId";
+ }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& blob : result->Responses) {
+ TABLER() {
+ TABLED() {
+ out << blob.Id.ToString();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+
+} // anon
+
+NMonitoring::IMonPage *CreateMonBlobRangePage(const TString& path, TActorSystem *actorSystem) {
+ return new TMonBlobRangePage(path, actorSystem);
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/mon_blob_range_page.h b/ydb/core/blobstorage/other/mon_blob_range_page.h
index 06b0dc98ef4..af8687a5697 100644
--- a/ydb/core/blobstorage/other/mon_blob_range_page.h
+++ b/ydb/core/blobstorage/other/mon_blob_range_page.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/monlib/service/pages/mon_page.h>
-
-namespace NKikimr {
-
- NMonitoring::IMonPage *CreateMonBlobRangePage(const TString& path, TActorSystem *actorSystem);
-
-} // NKikimr
+
+namespace NKikimr {
+
+ NMonitoring::IMonPage *CreateMonBlobRangePage(const TString& path, TActorSystem *actorSystem);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/mon_get_blob_page.cpp b/ydb/core/blobstorage/other/mon_get_blob_page.cpp
index 95308879a33..116c64b4852 100644
--- a/ydb/core/blobstorage/other/mon_get_blob_page.cpp
+++ b/ydb/core/blobstorage/other/mon_get_blob_page.cpp
@@ -1,331 +1,331 @@
-#include "mon_get_blob_page.h"
+#include "mon_get_blob_page.h"
#include <ydb/core/base/blobstorage.h>
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/threading/future/future.h>
-
-namespace NKikimr {
-
-namespace {
-
- class TMonGetBlobPage
- : public NMonitoring::IMonPage
- {
- struct TRequestResult {
- TLogoBlobID LogoBlobId;
- NKikimrProto::EReplyStatus Status;
+
+namespace NKikimr {
+
+namespace {
+
+ class TMonGetBlobPage
+ : public NMonitoring::IMonPage
+ {
+ struct TRequestResult {
+ TLogoBlobID LogoBlobId;
+ NKikimrProto::EReplyStatus Status;
TString Buffer;
- TString DebugInfo;
- TVector<TEvBlobStorage::TEvGetResult::TPartMapItem> PartMap;
- };
-
- class TRequestActor
- : public TActorBootstrapped<TRequestActor>
- {
- const ui32 GroupId;
- const TLogoBlobID LogoBlobId;
- const bool CollectDebugInfo;
- NThreading::TPromise<TRequestResult> Promise;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GET_ACTOR;
- }
-
- TRequestActor(ui32 groupId, const TLogoBlobID& logoBlobId, bool collectDebugInfo,
- NThreading::TPromise<TRequestResult> promise)
- : GroupId(groupId)
- , LogoBlobId(logoBlobId)
- , CollectDebugInfo(collectDebugInfo)
- , Promise(promise)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- auto query = std::make_unique<TEvBlobStorage::TEvGet>(LogoBlobId, 0, 0, TInstant::Max(),
- NKikimrBlobStorage::AsyncRead);
- query->CollectDebugInfo = CollectDebugInfo;
- query->ReportDetailedPartMap = true;
- SendToBSProxy(ctx, GroupId, query.release());
- Become(&TRequestActor::StateFunc);
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev, const TActorContext& ctx) {
- TEvBlobStorage::TEvGetResult *msg = ev->Get();
-
- TRequestResult result;
- if (msg->Status != NKikimrProto::OK) {
- result.Status = msg->Status;
- } else if (msg->ResponseSz != 1) {
- result.Status = NKikimrProto::ERROR;
- } else {
- result.LogoBlobId = msg->Responses[0].Id;
- result.Status = msg->Responses[0].Status;
- result.Buffer = msg->Responses[0].Buffer;
- result.PartMap = std::move(msg->Responses[0].PartMap);
- }
- result.DebugInfo = std::move(msg->DebugInfo);
-
- Promise.SetValue(result);
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvGetResult, Handle)
- )
- };
-
- private:
- TActorSystem *ActorSystem;
-
- public:
+ TString DebugInfo;
+ TVector<TEvBlobStorage::TEvGetResult::TPartMapItem> PartMap;
+ };
+
+ class TRequestActor
+ : public TActorBootstrapped<TRequestActor>
+ {
+ const ui32 GroupId;
+ const TLogoBlobID LogoBlobId;
+ const bool CollectDebugInfo;
+ NThreading::TPromise<TRequestResult> Promise;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GET_ACTOR;
+ }
+
+ TRequestActor(ui32 groupId, const TLogoBlobID& logoBlobId, bool collectDebugInfo,
+ NThreading::TPromise<TRequestResult> promise)
+ : GroupId(groupId)
+ , LogoBlobId(logoBlobId)
+ , CollectDebugInfo(collectDebugInfo)
+ , Promise(promise)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ auto query = std::make_unique<TEvBlobStorage::TEvGet>(LogoBlobId, 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::AsyncRead);
+ query->CollectDebugInfo = CollectDebugInfo;
+ query->ReportDetailedPartMap = true;
+ SendToBSProxy(ctx, GroupId, query.release());
+ Become(&TRequestActor::StateFunc);
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev, const TActorContext& ctx) {
+ TEvBlobStorage::TEvGetResult *msg = ev->Get();
+
+ TRequestResult result;
+ if (msg->Status != NKikimrProto::OK) {
+ result.Status = msg->Status;
+ } else if (msg->ResponseSz != 1) {
+ result.Status = NKikimrProto::ERROR;
+ } else {
+ result.LogoBlobId = msg->Responses[0].Id;
+ result.Status = msg->Responses[0].Status;
+ result.Buffer = msg->Responses[0].Buffer;
+ result.PartMap = std::move(msg->Responses[0].PartMap);
+ }
+ result.DebugInfo = std::move(msg->DebugInfo);
+
+ Promise.SetValue(result);
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvGetResult, Handle)
+ )
+ };
+
+ private:
+ TActorSystem *ActorSystem;
+
+ public:
TMonGetBlobPage(const TString& path, TActorSystem *actorSystem)
- : IMonPage(path)
- , ActorSystem(actorSystem)
- {}
-
+ : IMonPage(path)
+ , ActorSystem(actorSystem)
+ {}
+
void Output(NMonitoring::IMonHttpRequest& request) override {
IOutputStream& out = request.Output();
-
- // parse HTTP request
+
+ // parse HTTP request
const TCgiParameters& params = request.GetParams();
-
+
auto generateError = [&](const TString& msg) {
- out << "HTTP/1.1 400 Bad Request\r\n"
- << "Content-Type: text/plain\r\n"
- << "Connection: close\r\n"
- << "\r\n"
- << msg << "\r\n";
- };
-
- ui32 groupId = 0;
- if (!params.Has("groupId")) {
- return generateError("Missing groupId parameter");
- } else if (!TryFromString(params.Get("groupId"), groupId)) {
- return generateError("Failed to parse groupId parameter -- must be an integer");
- }
-
- TLogoBlobID logoBlobId;
+ out << "HTTP/1.1 400 Bad Request\r\n"
+ << "Content-Type: text/plain\r\n"
+ << "Connection: close\r\n"
+ << "\r\n"
+ << msg << "\r\n";
+ };
+
+ ui32 groupId = 0;
+ if (!params.Has("groupId")) {
+ return generateError("Missing groupId parameter");
+ } else if (!TryFromString(params.Get("groupId"), groupId)) {
+ return generateError("Failed to parse groupId parameter -- must be an integer");
+ }
+
+ TLogoBlobID logoBlobId;
TString errorExplanation;
- if (!params.Has("blob")) {
- return generateError("Missing blob parameter");
- } else if (!TLogoBlobID::Parse(logoBlobId, params.Get("blob"), errorExplanation)) {
- return generateError("Failed to parse blob parameter -- " + errorExplanation);
- } else if (logoBlobId != logoBlobId.FullID()) {
- return generateError("Desired blob must be full one");
+ if (!params.Has("blob")) {
+ return generateError("Missing blob parameter");
+ } else if (!TLogoBlobID::Parse(logoBlobId, params.Get("blob"), errorExplanation)) {
+ return generateError("Failed to parse blob parameter -- " + errorExplanation);
+ } else if (logoBlobId != logoBlobId.FullID()) {
+ return generateError("Desired blob must be full one");
} else if (!logoBlobId || !logoBlobId.BlobSize()) {
- return generateError("Invalid blob id");
- }
-
- bool binary = false;
- if (params.Has("binary")) {
- int value;
- if (!TryFromString(params.Get("binary"), value) || !(value >= 0 && value <= 1)) {
- return generateError("Failed to parse binary parameter -- must be an integer in range [0, 1]");
- } else {
- binary = value != 0;
- }
- }
-
- bool collectDebugInfo = false;
- if (params.Has("debugInfo")) {
- int value;
- if (!TryFromString(params.Get("debugInfo"), value) || !(value >= 0 && value <= 1)) {
- return generateError("Failed to parse debugInfo parameter -- must be an integer in range [0, 1]");
- } else {
- collectDebugInfo = value != 0;
- }
-
- if (collectDebugInfo && binary) {
- return generateError("debugInfo and binary are mutually exclusive parameters");
- }
- }
-
- // create promise & future to obtain query result
- auto promise = NThreading::NewPromise<TRequestResult>();
- auto future = promise.GetFuture();
-
- // register and start actor
- ActorSystem->Register(new TRequestActor(groupId, logoBlobId, collectDebugInfo, promise));
-
- // wait for query to complete
- future.Wait();
-
- // obtain result
- const TRequestResult& result = future.GetValue();
-
- if (binary) {
- // generate data stream depending on result status
- if (result.Status == NKikimrProto::OK) {
- out << "HTTP/1.1 200 OK\r\n"
- << "Content-Type: application/octet-stream\r\n"
- << "Content-Disposition: attachment; filename=\"" << result.LogoBlobId.ToString() << "\"\r\n"
- << "Connection: close\r\n"
- << "\r\n";
- out.Write(result.Buffer);
- } else {
- if (result.Status == NKikimrProto::NODATA) {
- out << "HTTP/1.1 204 No Content\r\n";
- } else {
- out << "HTTP/1.1 500 Error\r\n";
- }
- out << "Content-Type: application/json\r\n"
- << "Connection: close\r\n"
- << "\r\n";
-
- out << "{\n"
- << " \"Status\": \"" << NKikimrProto::EReplyStatus_Name(result.Status) << "\"\n"
- << "}\n";
- }
- } else {
- out << NMonitoring::HTTPOKHTML;
-
- HTML(out) {
- out << "<!DOCTYPE html>\n";
- HTML_TAG() {
- HEAD() {
- out << "<title>Blob Query</title>\n";
- out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
- out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
- out << "<style type=\"text/css\">\n";
- out << ".table-nonfluid { width: auto; }\n";
- out << ".narrow-line50 {line-height: 50%}\n";
- out << ".narrow-line60 {line-height: 60%}\n";
- out << ".narrow-line70 {line-height: 70%}\n";
- out << ".narrow-line80 {line-height: 80%}\n";
- out << ".narrow-line90 {line-height: 90%}\n";
- out << "</style>\n";
- }
- BODY() {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Blob Data";
- }
- DIV_CLASS("panel-body") {
- DIV() {
- out << "LogoBlobId: ";
- STRONG() {
- out << logoBlobId.ToString();
- }
- }
-
- DIV() {
- out << "Status: ";
- STRONG() {
- out << NKikimrProto::EReplyStatus_Name(result.Status);
- }
- }
-
- if (collectDebugInfo) {
- DIV() {
- out << "Debug Info:";
- DIV() {
- out << "<pre><small>";
- out << result.DebugInfo;
- out << "</small></pre>";
- }
- }
- }
-
- DIV() {
- out << "Part Map:";
- DIV() {
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { out << "DiskOrderNumber"; }
- TABLEH() { out << "PartIdRequested"; }
- TABLEH() { out << "RequestIndex"; }
- TABLEH() { out << "ResponseIndex"; }
- TABLEH() { out << "PartId"; }
- TABLEH() { out << "Status"; }
- }
- }
- TABLEBODY() {
- for (const auto& item : result.PartMap) {
- auto prefix = [&] {
- TABLED() { out << item.DiskOrderNumber; }
- TABLED() { out << item.PartIdRequested; }
- TABLED() { out << item.RequestIndex; }
- TABLED() { out << item.ResponseIndex; }
- };
- if (item.Status) {
- for (const auto& x : item.Status) {
- TABLER() {
- prefix();
- TABLED() { out << x.first; }
- TABLED() { out << NKikimrProto::EReplyStatus_Name(x.second); }
- }
- }
- } else {
- TABLER() {
- prefix();
- TABLED() { out << "-"; }
- TABLED() { out << "-"; }
- }
- }
- }
- }
- }
- }
- }
-
- if (result.Status == NKikimrProto::OK) {
- DIV() {
- TCgiParameters params;
- params.InsertEscaped("blob", logoBlobId.ToString());
- params.InsertEscaped("groupId", ToString(groupId));
- params.InsertEscaped("binary", "1");
- out << "<a href=\"?" << params() << "\">Data</a>";
- DIV() {
- out << "<pre><small>";
- const TString& buffer = result.Buffer;
- const size_t rowSize = 64;
- for (size_t offset = 0; offset < buffer.size(); offset += rowSize) {
- out << Sprintf("0x%06zx | ", offset);
- size_t i;
- for (i = 0; i < rowSize && i + offset < buffer.size(); ++i) {
- out << Sprintf("%02x ", (ui8)buffer[i + offset]);
- }
- for (; i < rowSize; ++i) {
- out << " ";
- }
- out << "| ";
- bool gray = false;
- for (i = 0; i < rowSize && i + offset < buffer.size(); ++i) {
- ui8 ch = buffer[offset + i];
- if (isprint(ch)) {
- if (gray) {
- out << "</font>";
- gray = false;
- }
- out << ch;
- } else {
- if (!gray) {
- out << "<font color=\"gray\">";
- gray = true;
- }
- out << ".";
- }
- }
- out << "\n";
- }
- out << "</small></pre>";
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- };
-
-} // anon
-
+ return generateError("Invalid blob id");
+ }
+
+ bool binary = false;
+ if (params.Has("binary")) {
+ int value;
+ if (!TryFromString(params.Get("binary"), value) || !(value >= 0 && value <= 1)) {
+ return generateError("Failed to parse binary parameter -- must be an integer in range [0, 1]");
+ } else {
+ binary = value != 0;
+ }
+ }
+
+ bool collectDebugInfo = false;
+ if (params.Has("debugInfo")) {
+ int value;
+ if (!TryFromString(params.Get("debugInfo"), value) || !(value >= 0 && value <= 1)) {
+ return generateError("Failed to parse debugInfo parameter -- must be an integer in range [0, 1]");
+ } else {
+ collectDebugInfo = value != 0;
+ }
+
+ if (collectDebugInfo && binary) {
+ return generateError("debugInfo and binary are mutually exclusive parameters");
+ }
+ }
+
+ // create promise & future to obtain query result
+ auto promise = NThreading::NewPromise<TRequestResult>();
+ auto future = promise.GetFuture();
+
+ // register and start actor
+ ActorSystem->Register(new TRequestActor(groupId, logoBlobId, collectDebugInfo, promise));
+
+ // wait for query to complete
+ future.Wait();
+
+ // obtain result
+ const TRequestResult& result = future.GetValue();
+
+ if (binary) {
+ // generate data stream depending on result status
+ if (result.Status == NKikimrProto::OK) {
+ out << "HTTP/1.1 200 OK\r\n"
+ << "Content-Type: application/octet-stream\r\n"
+ << "Content-Disposition: attachment; filename=\"" << result.LogoBlobId.ToString() << "\"\r\n"
+ << "Connection: close\r\n"
+ << "\r\n";
+ out.Write(result.Buffer);
+ } else {
+ if (result.Status == NKikimrProto::NODATA) {
+ out << "HTTP/1.1 204 No Content\r\n";
+ } else {
+ out << "HTTP/1.1 500 Error\r\n";
+ }
+ out << "Content-Type: application/json\r\n"
+ << "Connection: close\r\n"
+ << "\r\n";
+
+ out << "{\n"
+ << " \"Status\": \"" << NKikimrProto::EReplyStatus_Name(result.Status) << "\"\n"
+ << "}\n";
+ }
+ } else {
+ out << NMonitoring::HTTPOKHTML;
+
+ HTML(out) {
+ out << "<!DOCTYPE html>\n";
+ HTML_TAG() {
+ HEAD() {
+ out << "<title>Blob Query</title>\n";
+ out << "<link rel='stylesheet' href='https://yastatic.net/bootstrap/3.3.1/css/bootstrap.min.css'>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/jquery/2.1.3/jquery.min.js'></script>\n";
+ out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n";
+ out << "<style type=\"text/css\">\n";
+ out << ".table-nonfluid { width: auto; }\n";
+ out << ".narrow-line50 {line-height: 50%}\n";
+ out << ".narrow-line60 {line-height: 60%}\n";
+ out << ".narrow-line70 {line-height: 70%}\n";
+ out << ".narrow-line80 {line-height: 80%}\n";
+ out << ".narrow-line90 {line-height: 90%}\n";
+ out << "</style>\n";
+ }
+ BODY() {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Blob Data";
+ }
+ DIV_CLASS("panel-body") {
+ DIV() {
+ out << "LogoBlobId: ";
+ STRONG() {
+ out << logoBlobId.ToString();
+ }
+ }
+
+ DIV() {
+ out << "Status: ";
+ STRONG() {
+ out << NKikimrProto::EReplyStatus_Name(result.Status);
+ }
+ }
+
+ if (collectDebugInfo) {
+ DIV() {
+ out << "Debug Info:";
+ DIV() {
+ out << "<pre><small>";
+ out << result.DebugInfo;
+ out << "</small></pre>";
+ }
+ }
+ }
+
+ DIV() {
+ out << "Part Map:";
+ DIV() {
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { out << "DiskOrderNumber"; }
+ TABLEH() { out << "PartIdRequested"; }
+ TABLEH() { out << "RequestIndex"; }
+ TABLEH() { out << "ResponseIndex"; }
+ TABLEH() { out << "PartId"; }
+ TABLEH() { out << "Status"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& item : result.PartMap) {
+ auto prefix = [&] {
+ TABLED() { out << item.DiskOrderNumber; }
+ TABLED() { out << item.PartIdRequested; }
+ TABLED() { out << item.RequestIndex; }
+ TABLED() { out << item.ResponseIndex; }
+ };
+ if (item.Status) {
+ for (const auto& x : item.Status) {
+ TABLER() {
+ prefix();
+ TABLED() { out << x.first; }
+ TABLED() { out << NKikimrProto::EReplyStatus_Name(x.second); }
+ }
+ }
+ } else {
+ TABLER() {
+ prefix();
+ TABLED() { out << "-"; }
+ TABLED() { out << "-"; }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (result.Status == NKikimrProto::OK) {
+ DIV() {
+ TCgiParameters params;
+ params.InsertEscaped("blob", logoBlobId.ToString());
+ params.InsertEscaped("groupId", ToString(groupId));
+ params.InsertEscaped("binary", "1");
+ out << "<a href=\"?" << params() << "\">Data</a>";
+ DIV() {
+ out << "<pre><small>";
+ const TString& buffer = result.Buffer;
+ const size_t rowSize = 64;
+ for (size_t offset = 0; offset < buffer.size(); offset += rowSize) {
+ out << Sprintf("0x%06zx | ", offset);
+ size_t i;
+ for (i = 0; i < rowSize && i + offset < buffer.size(); ++i) {
+ out << Sprintf("%02x ", (ui8)buffer[i + offset]);
+ }
+ for (; i < rowSize; ++i) {
+ out << " ";
+ }
+ out << "| ";
+ bool gray = false;
+ for (i = 0; i < rowSize && i + offset < buffer.size(); ++i) {
+ ui8 ch = buffer[offset + i];
+ if (isprint(ch)) {
+ if (gray) {
+ out << "</font>";
+ gray = false;
+ }
+ out << ch;
+ } else {
+ if (!gray) {
+ out << "<font color=\"gray\">";
+ gray = true;
+ }
+ out << ".";
+ }
+ }
+ out << "\n";
+ }
+ out << "</small></pre>";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+
+} // anon
+
NMonitoring::IMonPage *CreateMonGetBlobPage(const TString& path, TActorSystem *actorSystem) {
- return new TMonGetBlobPage(path, actorSystem);
-}
-
-} // NKikimr
+ return new TMonGetBlobPage(path, actorSystem);
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/mon_get_blob_page.h b/ydb/core/blobstorage/other/mon_get_blob_page.h
index d822023ab78..666ea02cc6b 100644
--- a/ydb/core/blobstorage/other/mon_get_blob_page.h
+++ b/ydb/core/blobstorage/other/mon_get_blob_page.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/monlib/service/pages/mon_page.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
NMonitoring::IMonPage *CreateMonGetBlobPage(const TString& path, TActorSystem *actorSystem);
-
-} // NKikimr
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/mon_vdisk_stream.cpp b/ydb/core/blobstorage/other/mon_vdisk_stream.cpp
index 90b95b4926e..a9aaa7e4e0d 100644
--- a/ydb/core/blobstorage/other/mon_vdisk_stream.cpp
+++ b/ydb/core/blobstorage/other/mon_vdisk_stream.cpp
@@ -1,123 +1,123 @@
-#include "mon_get_blob_page.h"
+#include "mon_get_blob_page.h"
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <library/cpp/monlib/service/pages/templates.h>
#include <library/cpp/threading/future/future.h>
-
-namespace NKikimr {
-
-namespace {
-
- class TMonVDiskPage
- : public NMonitoring::IMonPage
- {
- class TRequestActor
- : public TActorBootstrapped<TRequestActor>
- {
- const ui32 PDiskId;
- const ui32 VDiskSlotId;
- const TString SessionId;
- NThreading::TPromise<TString> Promise;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_GET_ACTOR;
- }
-
- TRequestActor(ui32 pdiskId, ui32 vdiskSlotId, TString sessionId, NThreading::TPromise<TString> promise)
- : PDiskId(pdiskId)
- , VDiskSlotId(vdiskSlotId)
- , SessionId(sessionId)
- , Promise(promise)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- ctx.Send(MakeBlobStorageVDiskID(ctx.SelfID.NodeId(), PDiskId, VDiskSlotId),
- new TEvBlobStorage::TEvMonStreamQuery(SessionId, {}, {}));
- Become(&TRequestActor::StateFunc);
- }
-
- void Handle(NMon::TEvHttpInfoRes::TPtr& ev, const TActorContext& ctx) {
- TStringStream s;
- ev->Get()->Output(s);
- Promise.SetValue(s.Str());
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(NMon::TEvHttpInfoRes, Handle)
- )
- };
-
- private:
- TActorSystem *ActorSystem;
-
- public:
- TMonVDiskPage(const TString& path, TActorSystem *actorSystem)
- : IMonPage(path)
- , ActorSystem(actorSystem)
- {}
-
- void Output(NMonitoring::IMonHttpRequest& request) override {
- IOutputStream& out = request.Output();
-
- // parse HTTP request
- const TCgiParameters& params = request.GetParams();
-
- auto generateError = [&](const TString& msg) {
- out << "HTTP/1.1 400 Bad Request\r\n"
- << "Content-Type: text/plain\r\n"
- << "Connection: close\r\n"
- << "\r\n"
- << msg << "\r\n";
- };
-
- ui32 pdiskId = 0;
- if (!params.Has("pdiskId")) {
- return generateError("Missing pdiskId parameter");
- } else if (!TryFromString(params.Get("pdiskId"), pdiskId)) {
- return generateError("Invalid pdiskId value");
- }
-
- ui32 vdiskSlotId = 0;
- if (!params.Has("vdiskSlotId")) {
- return generateError("Missing vdiskSlotId parameter");
- } else if (!TryFromString(params.Get("vdiskSlotId"), vdiskSlotId)) {
- return generateError("Invalid vdiskSlotId value");
- }
-
- TString sessionId;
- if (!params.Has("sessionId")) {
- return generateError("Missing sessionId parameter");
- } else {
- sessionId = params.Get("sessionId");
- }
-
- // create promise & future to obtain query result
- auto promise = NThreading::NewPromise<TString>();
- auto future = promise.GetFuture();
-
- // register and start actor
- ActorSystem->Register(new TRequestActor(pdiskId, vdiskSlotId, sessionId, promise));
-
- // wait for query to complete
- future.Wait();
-
- // obtain result
- const TString& result = future.GetValue();
-
- out << "HTTP/1.1 200 OK\r\n"
- << "Content-Type: application/octet-stream\r\n"
- << "Connection: close\r\n"
- << "\r\n"
- << result;
- }
- };
-
-} // anon
-
-NMonitoring::IMonPage *CreateMonVDiskStreamPage(const TString& path, TActorSystem *actorSystem) {
- return new TMonVDiskPage(path, actorSystem);
-}
-
-} // NKikimr
+
+namespace NKikimr {
+
+namespace {
+
+ class TMonVDiskPage
+ : public NMonitoring::IMonPage
+ {
+ class TRequestActor
+ : public TActorBootstrapped<TRequestActor>
+ {
+ const ui32 PDiskId;
+ const ui32 VDiskSlotId;
+ const TString SessionId;
+ NThreading::TPromise<TString> Promise;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_GET_ACTOR;
+ }
+
+ TRequestActor(ui32 pdiskId, ui32 vdiskSlotId, TString sessionId, NThreading::TPromise<TString> promise)
+ : PDiskId(pdiskId)
+ , VDiskSlotId(vdiskSlotId)
+ , SessionId(sessionId)
+ , Promise(promise)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ ctx.Send(MakeBlobStorageVDiskID(ctx.SelfID.NodeId(), PDiskId, VDiskSlotId),
+ new TEvBlobStorage::TEvMonStreamQuery(SessionId, {}, {}));
+ Become(&TRequestActor::StateFunc);
+ }
+
+ void Handle(NMon::TEvHttpInfoRes::TPtr& ev, const TActorContext& ctx) {
+ TStringStream s;
+ ev->Get()->Output(s);
+ Promise.SetValue(s.Str());
+ Die(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(NMon::TEvHttpInfoRes, Handle)
+ )
+ };
+
+ private:
+ TActorSystem *ActorSystem;
+
+ public:
+ TMonVDiskPage(const TString& path, TActorSystem *actorSystem)
+ : IMonPage(path)
+ , ActorSystem(actorSystem)
+ {}
+
+ void Output(NMonitoring::IMonHttpRequest& request) override {
+ IOutputStream& out = request.Output();
+
+ // parse HTTP request
+ const TCgiParameters& params = request.GetParams();
+
+ auto generateError = [&](const TString& msg) {
+ out << "HTTP/1.1 400 Bad Request\r\n"
+ << "Content-Type: text/plain\r\n"
+ << "Connection: close\r\n"
+ << "\r\n"
+ << msg << "\r\n";
+ };
+
+ ui32 pdiskId = 0;
+ if (!params.Has("pdiskId")) {
+ return generateError("Missing pdiskId parameter");
+ } else if (!TryFromString(params.Get("pdiskId"), pdiskId)) {
+ return generateError("Invalid pdiskId value");
+ }
+
+ ui32 vdiskSlotId = 0;
+ if (!params.Has("vdiskSlotId")) {
+ return generateError("Missing vdiskSlotId parameter");
+ } else if (!TryFromString(params.Get("vdiskSlotId"), vdiskSlotId)) {
+ return generateError("Invalid vdiskSlotId value");
+ }
+
+ TString sessionId;
+ if (!params.Has("sessionId")) {
+ return generateError("Missing sessionId parameter");
+ } else {
+ sessionId = params.Get("sessionId");
+ }
+
+ // create promise & future to obtain query result
+ auto promise = NThreading::NewPromise<TString>();
+ auto future = promise.GetFuture();
+
+ // register and start actor
+ ActorSystem->Register(new TRequestActor(pdiskId, vdiskSlotId, sessionId, promise));
+
+ // wait for query to complete
+ future.Wait();
+
+ // obtain result
+ const TString& result = future.GetValue();
+
+ out << "HTTP/1.1 200 OK\r\n"
+ << "Content-Type: application/octet-stream\r\n"
+ << "Connection: close\r\n"
+ << "\r\n"
+ << result;
+ }
+ };
+
+} // anon
+
+NMonitoring::IMonPage *CreateMonVDiskStreamPage(const TString& path, TActorSystem *actorSystem) {
+ return new TMonVDiskPage(path, actorSystem);
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/mon_vdisk_stream.h b/ydb/core/blobstorage/other/mon_vdisk_stream.h
index 3014fd48f5a..1f7df7c8db6 100644
--- a/ydb/core/blobstorage/other/mon_vdisk_stream.h
+++ b/ydb/core/blobstorage/other/mon_vdisk_stream.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/monlib/service/pages/mon_page.h>
-
-namespace NKikimr {
-
- NMonitoring::IMonPage *CreateMonVDiskStreamPage(const TString& path, TActorSystem *actorSystem);
-
-} // NKikimr
+
+namespace NKikimr {
+
+ NMonitoring::IMonPage *CreateMonVDiskStreamPage(const TString& path, TActorSystem *actorSystem);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/other/ya.make b/ydb/core/blobstorage/other/ya.make
index 650c118dade..6270e69ba3a 100644
--- a/ydb/core/blobstorage/other/ya.make
+++ b/ydb/core/blobstorage/other/ya.make
@@ -19,8 +19,8 @@ SRCS(
mon_blob_range_page.h
mon_get_blob_page.cpp
mon_get_blob_page.h
- mon_vdisk_stream.cpp
- mon_vdisk_stream.h
+ mon_vdisk_stream.cpp
+ mon_vdisk_stream.h
)
END()
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk.h
index 8e722ce42a0..b39334452f3 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk.h
@@ -135,18 +135,18 @@ struct TEvYardInit : public TEventLocal<TEvYardInit, TEvBlobStorage::EvYardInit>
TVDiskID VDisk;
ui64 PDiskGuid;
TActorId CutLogID; // ask this actor about log cut
- TActorId WhiteboardProxyId;
- ui32 SlotId;
-
+ TActorId WhiteboardProxyId;
+ ui32 SlotId;
+
TEvYardInit(TOwnerRound ownerRound, const TVDiskID &vdisk, ui64 pDiskGuid,
- const TActorId &cutLogID = TActorId(), const TActorId& whiteboardProxyId = {},
- ui32 slotId = Max<ui32>())
+ const TActorId &cutLogID = TActorId(), const TActorId& whiteboardProxyId = {},
+ ui32 slotId = Max<ui32>())
: OwnerRound(ownerRound)
, VDisk(vdisk)
, PDiskGuid(pDiskGuid)
, CutLogID(cutLogID)
- , WhiteboardProxyId(whiteboardProxyId)
- , SlotId(slotId)
+ , WhiteboardProxyId(whiteboardProxyId)
+ , SlotId(slotId)
{}
TString ToString() const {
@@ -159,7 +159,7 @@ struct TEvYardInit : public TEventLocal<TEvYardInit, TEvBlobStorage::EvYardInit>
str << " VDisk# " << record.VDisk.ToString();
str << " PDiskGuid# " << record.PDiskGuid;
str << " CutLogID# " << record.CutLogID;
- str << " WhiteboardProxyId# " << record.WhiteboardProxyId;
+ str << " WhiteboardProxyId# " << record.WhiteboardProxyId;
str << "}";
return str.Str();
}
@@ -248,7 +248,7 @@ struct TEvLog : public TEventLocal<TEvLog, TEvBlobStorage::EvLog> {
virtual void operator ()(TActorSystem *actorSystem, const TEvLogResult &ev) = 0;
};
- using TCallback = std::unique_ptr<ICallback>;
+ using TCallback = std::unique_ptr<ICallback>;
explicit TEvLog(TOwner owner, TOwnerRound ownerRound, TLogSignature signature,
const TString &data, TLsnSeg seg, void *cookie, TCallback &&cb = TCallback())
@@ -864,33 +864,33 @@ struct TEvChunkWrite : public TEventLocal<TEvChunkWrite, TEvBlobStorage::EvChunk
}
};
- ///////////////////// TAlignedParts //////////////////////////////
- class TRopeAlignedParts : public IParts {
- TRope Data; // we shall keep the rope here to prevent it from being freed
- TVector<TDataRef> Refs;
-
- public:
- TRopeAlignedParts(TRope&& data, size_t fullSize)
- : Data(std::move(data))
- {
- for (auto iter = Data.Begin(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
- Refs.emplace_back(iter.ContiguousData(), iter.ContiguousSize());
- }
- if (const size_t padding = fullSize - Data.GetSize()) {
- Refs.emplace_back(nullptr, padding);
- }
- }
-
- virtual ui32 Size() const override {
- return Refs.size();
- }
-
- virtual TDataRef operator [](ui32 index) const override {
- return Refs[index];
- }
- };
-
-
+ ///////////////////// TAlignedParts //////////////////////////////
+ class TRopeAlignedParts : public IParts {
+ TRope Data; // we shall keep the rope here to prevent it from being freed
+ TVector<TDataRef> Refs;
+
+ public:
+ TRopeAlignedParts(TRope&& data, size_t fullSize)
+ : Data(std::move(data))
+ {
+ for (auto iter = Data.Begin(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
+ Refs.emplace_back(iter.ContiguousData(), iter.ContiguousSize());
+ }
+ if (const size_t padding = fullSize - Data.GetSize()) {
+ Refs.emplace_back(nullptr, padding);
+ }
+ }
+
+ virtual ui32 Size() const override {
+ return Refs.size();
+ }
+
+ virtual TDataRef operator [](ui32 index) const override {
+ return Refs[index];
+ }
+ };
+
+
TEvChunkWrite(TOwner owner, TOwnerRound ownerRound, TChunkIdx chunkIdx, ui32 offset, TPartsPtr partsPtr,
void *cookie, bool doFlush, ui8 priorityClass, bool isSeqWrite = true)
: ChunkIdx(chunkIdx)
@@ -935,7 +935,7 @@ struct TEvChunkWrite : public TEventLocal<TEvChunkWrite, TEvBlobStorage::EvChunk
void Validate() const {
const ui32 count = PartsPtr ? PartsPtr->Size() : 0;
for (ui32 idx = 0; idx < count; ++idx) {
- Y_VERIFY((*PartsPtr)[idx].second);
+ Y_VERIFY((*PartsPtr)[idx].second);
if ((*PartsPtr)[idx].first) {
REQUEST_VALGRIND_CHECK_MEM_IS_DEFINED((*PartsPtr)[idx].first, (*PartsPtr)[idx].second);
}
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
index d92b19c6cca..9a8cfc1b0b6 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_actor.cpp
@@ -51,18 +51,18 @@ class TPDiskActor : public TActorBootstrapped<TPDiskActor> {
ui64 PDiskGuid;
TActorId Sender;
TActorId CutLogId;
- TActorId WhiteboardProxyId;
- ui32 SlotId;
+ TActorId WhiteboardProxyId;
+ ui32 SlotId;
- TInitQueueItem(TOwnerRound ownerRound, TVDiskID vDisk, ui64 pDiskGuid, TActorId sender, TActorId cutLogId,
- TActorId whiteboardProxyId, ui32 slotId)
+ TInitQueueItem(TOwnerRound ownerRound, TVDiskID vDisk, ui64 pDiskGuid, TActorId sender, TActorId cutLogId,
+ TActorId whiteboardProxyId, ui32 slotId)
: OwnerRound(ownerRound)
, VDisk(vDisk)
, PDiskGuid(pDiskGuid)
, Sender(sender)
, CutLogId(cutLogId)
- , WhiteboardProxyId(whiteboardProxyId)
- , SlotId(slotId)
+ , WhiteboardProxyId(whiteboardProxyId)
+ , SlotId(slotId)
{}
};
@@ -192,8 +192,8 @@ class TPDiskActor : public TActorBootstrapped<TPDiskActor> {
TWhiteboardFlag DeviceFlag;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PDISK_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PDISK_ACTOR;
}
TPDiskActor(const TIntrusivePtr<TPDiskConfig>& cfg, const NPDisk::TKey &mainKey,
@@ -313,7 +313,7 @@ public:
PDisk->Initialize(TlsActivationContext->ActorSystem(), SelfId());
Y_VERIFY(PDisk->PDiskThread.Running());
- *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
+ *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
*PDisk->Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorDiskCannotBeFormated;
@@ -373,7 +373,7 @@ public:
FormattingThread->Start();
} else {
SecureWipeBuffer((ui8*)&MainKey, sizeof(MainKey));
- *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
+ *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
*PDisk->Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorPDiskCannotBeInitialised;
if (!IsMagicAlreadyChecked) {
@@ -407,7 +407,7 @@ public:
<< " Successfully read format record# " << PDisk->Format.ToString());
TString info;
if (!PDisk->CheckGuid(&info)) {
- *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
+ *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
*PDisk->Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialFormatReadDueToGuid;
PDisk->ErrorStr = TStringBuilder() << "Can't start due to a guid error " << info;
@@ -416,7 +416,7 @@ public:
LOG_ERROR_S(*TlsActivationContext, NKikimrServices::BS_PDISK, str.Str());
InitError(str.Str());
} else if (!PDisk->CheckFormatComplete()) {
- *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
+ *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatReadError;
*PDisk->Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialFormatReadIncompleteFormat;
PDisk->ErrorStr = "Can't start due to incomplete format!";
@@ -428,7 +428,7 @@ public:
InitError(str.Str());
} else {
// PDisk GUID is OK and format is complete
- *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogRead;
+ *PDisk->Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogRead;
*PDisk->Mon.PDiskDetailedState = TPDiskMon::TPDisk::BootingSysLogRead;
PDisk->Format.InitMagic();
PDisk->ReadSysLog(SelfId());
@@ -458,8 +458,8 @@ public:
void InitSuccess() {
Become(&TThis::StateOnline);
for (TList<TInitQueueItem>::iterator it = InitQueue.begin(); it != InitQueue.end(); ++it) {
- NPDisk::TEvYardInit evInit(it->OwnerRound, it->VDisk, it->PDiskGuid, it->CutLogId, it->WhiteboardProxyId,
- it->SlotId);
+ NPDisk::TEvYardInit evInit(it->OwnerRound, it->VDisk, it->PDiskGuid, it->CutLogId, it->WhiteboardProxyId,
+ it->SlotId);
auto* request = PDisk->ReqCreator.CreateFromEv<TYardInit>(evInit, it->Sender);
PDisk->InputRequest(request);
}
@@ -471,8 +471,8 @@ public:
void InitHandle(NPDisk::TEvYardInit::TPtr &ev) {
const NPDisk::TEvYardInit &evYardInit = *ev->Get();
- InitQueue.emplace_back(evYardInit.OwnerRound, evYardInit.VDisk, evYardInit.PDiskGuid,
- ev->Sender, evYardInit.CutLogID, evYardInit.WhiteboardProxyId, evYardInit.SlotId);
+ InitQueue.emplace_back(evYardInit.OwnerRound, evYardInit.VDisk, evYardInit.PDiskGuid,
+ ev->Sender, evYardInit.CutLogID, evYardInit.WhiteboardProxyId, evYardInit.SlotId);
}
void InitHandle(NPDisk::TEvYardControl::TPtr &ev) {
@@ -828,7 +828,7 @@ public:
LOG_TRACE_S(*TlsActivationContext, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDisk->PDiskId
<< " handle TEvWhiteboardReportResult# " << result->ToString());
Send(NodeWhiteboardServiceId, result->PDiskState.Release());
- for (auto& p : result->VDiskStateVect) {
+ for (auto& p : result->VDiskStateVect) {
Send(std::get<0>(p),
new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(std::move(std::get<1>(p))));
}
@@ -1082,7 +1082,7 @@ IActor* CreatePDisk(const TIntrusivePtr<TPDiskConfig> &cfg, const NPDisk::TKey &
return new NPDisk::TPDiskActor(cfg, mainKey, counters);
}
-void TRealPDiskServiceFactory::Create(const TActorContext &ctx, ui32 pDiskID,
+void TRealPDiskServiceFactory::Create(const TActorContext &ctx, ui32 pDiskID,
const TIntrusivePtr<TPDiskConfig> &cfg, const NPDisk::TKey &mainKey, ui32 poolId, ui32 nodeId) {
TActorId actorId = ctx.ExecutorThread.RegisterActor(
CreatePDisk(cfg, mainKey, AppData(ctx)->Counters), TMailboxType::ReadAsFilled, poolId);
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice.h
index aa28b6297da..37258101278 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice.h
@@ -11,7 +11,7 @@
#include <ydb/library/pdisk_io/aio.h>
#include <ydb/library/pdisk_io/sector_map.h>
#include <ydb/library/wilson/wilson_event.h>
-
+
namespace NActors {
class TActorSystem;
}
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice_async.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice_async.cpp
index 34c20999b7b..142cf1dd9c5 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice_async.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_blockdevice_async.cpp
@@ -17,7 +17,7 @@
#include <ydb/core/util/yverify_stream.h>
#include <ydb/library/pdisk_io/aio.h>
#include <ydb/library/pdisk_io/spdk_state.h>
-
+
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/util/thread.h>
#include <library/cpp/containers/stack_vector/stack_vec.h>
@@ -804,7 +804,7 @@ protected:
<< " Warning# " << LastWarning);
}
if (IsFileOpened) {
- IoContext->SetActorSystem(ActorSystem);
+ IoContext->SetActorSystem(ActorSystem);
CompletionThread = MakeHolder<TCompletionThread>(*this, MaxQueuedCompletionActions);
TrimThread = MakeHolder<TTrimThread>(*this);
SharedCallback = MakeHolder<TSharedCallback>(*this);
@@ -943,9 +943,9 @@ protected:
REQUEST_VALGRIND_CHECK_MEM_IS_ADDRESSABLE(data, size);
}
- if (ActorSystem) {
- WILSON_TRACE(*ActorSystem, traceId, BlockPread, DiskOffset = offset, Size = size);
- }
+ if (ActorSystem) {
+ WILSON_TRACE(*ActorSystem, traceId, BlockPread, DiskOffset = offset, Size = size);
+ }
IAsyncIoOperation* op = IoContext->CreateAsyncIoOperation(completionAction, reqId, traceId);
IoContext->PreparePRead(op, data, size, offset);
Submit(op);
@@ -963,9 +963,9 @@ protected:
REQUEST_VALGRIND_CHECK_MEM_IS_DEFINED(data, size);
}
- if (ActorSystem) {
- WILSON_TRACE(*ActorSystem, traceId, BlockPwrite, DiskOffset = offset, Size = size);
- }
+ if (ActorSystem) {
+ WILSON_TRACE(*ActorSystem, traceId, BlockPwrite, DiskOffset = offset, Size = size);
+ }
IAsyncIoOperation* op = IoContext->CreateAsyncIoOperation(completionAction, reqId, traceId);
IoContext->PreparePWrite(op, const_cast<void*>(data), size, offset);
Submit(op);
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_color_limits.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_color_limits.h
index 217818f439c..623c72a17a4 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_color_limits.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_color_limits.h
@@ -23,10 +23,10 @@ struct TColorLimits {
i64 OrangeDivisor = 1;
i64 OrangeAddend = 0;
- i64 LightOrangeMultiplier = 0;
- i64 LightOrangeDivisor = 1;
- i64 LightOrangeAddend = 0;
-
+ i64 LightOrangeMultiplier = 0;
+ i64 LightOrangeDivisor = 1;
+ i64 LightOrangeAddend = 0;
+
i64 YellowMultiplier = 0;
i64 YellowDivisor = 1;
i64 YellowAddend = 0;
@@ -65,9 +65,9 @@ struct TColorLimits {
l.OrangeAddend = 4;
l.LightOrangeMultiplier = 65;
- l.LightOrangeDivisor = 1000;
+ l.LightOrangeDivisor = 1000;
l.LightOrangeAddend = 5;
-
+
l.YellowMultiplier = 80; // Stop serving user writes at 8% free space
l.YellowDivisor = 1000;
l.YellowAddend = 6;
@@ -76,7 +76,7 @@ struct TColorLimits {
l.LightYellowDivisor = 1000;
l.LightYellowAddend = 7;
- l.CyanMultiplier = 130; // 13% free space or less
+ l.CyanMultiplier = 130; // 13% free space or less
l.CyanDivisor = 1000;
l.CyanAddend = 8;
@@ -95,9 +95,9 @@ struct TColorLimits {
l.OrangeMultiplier = 500;
l.OrangeDivisor = 1000;
- l.LightOrangeMultiplier = 700;
- l.LightOrangeDivisor = 1000;
-
+ l.LightOrangeMultiplier = 700;
+ l.LightOrangeDivisor = 1000;
+
l.YellowMultiplier = 900;
l.YellowDivisor = 1000;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_drivemodel.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_drivemodel.h
index 2a0678dbd29..659cf89be1f 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_drivemodel.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_drivemodel.h
@@ -22,7 +22,7 @@ protected:
// Model data
ui64 SeekTimeNsec;
ui64 BulkReadBlockSizeBytes;
- ui64 BulkWriteBlockSizeBytes;
+ ui64 BulkWriteBlockSizeBytes;
ui64 TrimSpeedBps;
ui32 TotalChunksCount;
ui64 SpeedBps[OP_TYPE_COUNT];
@@ -200,14 +200,14 @@ public:
return Speed(chunkIdx, type) * durationNs / 1000000000ull;
}
- ui64 BulkWriteBlockSize() const {
- return BulkWriteBlockSizeBytes;
- }
-
- ui32 IOPS() const {
- return 1000000000ULL / SeekTimeNsec;
- }
-
+ ui64 BulkWriteBlockSize() const {
+ return BulkWriteBlockSizeBytes;
+ }
+
+ ui32 IOPS() const {
+ return 1000000000ULL / SeekTimeNsec;
+ }
+
TString ToString() const {
return ToString(false);
}
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_factory.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_factory.h
index 6d472eab412..b504a7d2637 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_factory.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_factory.h
@@ -12,13 +12,13 @@ namespace NKikimr {
class IPDiskServiceFactory : public TThrRefBase {
public:
- virtual void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
+ virtual void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
const NPDisk::TKey &mainKey, ui32 poolId, ui32 nodeId) = 0;
};
class TRealPDiskServiceFactory : public IPDiskServiceFactory {
public:
- void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
+ void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
const NPDisk::TKey &mainKey, ui32 poolId, ui32 nodeId) override;
};
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
index d00fc0f2203..2ee283f15ea 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp
@@ -68,7 +68,7 @@ TPDisk::TPDisk(const TIntrusivePtr<TPDiskConfig> cfg, const TIntrusivePtr<NMonit
ConfigureCbs(OwnerUnallocated, GateTrim, 16);
Format.Clear();
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::Initial;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::Initial;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Booting;
ErrorStr = "PDisk is initializing now";
@@ -643,7 +643,7 @@ void TPDisk::AskVDisksToCutLogs(TOwner ownerFilter, bool doForce) {
str << " OwnerId# " << (ui32)owner;
str << " { VDiskId# " << data.VDiskId.ToStringWOGeneration();
str << " CutLogId# " << data.CutLogId.ToString();
- str << " WhiteboardProxyId# " << data.WhiteboardProxyId;
+ str << " WhiteboardProxyId# " << data.WhiteboardProxyId;
str << " CurLsnToKeep# " << data.CurrentFirstLsnToKeep;
str << " FirstNonceToKeep# " << SysLogFirstNoncesToKeep.FirstNonceToKeep[owner];
str << " AskedToCutLogAt# " << data.AskedToCutLogAt;
@@ -973,7 +973,7 @@ TPDisk::EChunkReadPieceResult TPDisk::ChunkReadPiece(TIntrusivePtr<TChunkRead> &
ui64 readOffset = Format.Offset(read->ChunkIdx, read->FirstSector, currentSectorOffset);
// TODO: Get this from the drive
- WILSON_TRACE(*ActorSystem, &read->TraceId, AsyncReadScheduled, DiskOffset = readOffset, Size = bytesToRead);
+ WILSON_TRACE(*ActorSystem, &read->TraceId, AsyncReadScheduled, DiskOffset = readOffset, Size = bytesToRead);
THolder<TCompletionChunkReadPart> completion(new TCompletionChunkReadPart(this, read, bytesToRead,
payloadBytesToRead, payloadOffset, read->FinalCompletion, isTheLastPart, Cfg->UseT1ha0HashInFooter));
completion->CostNs = DriveModel.TimeForSizeNs(bytesToRead, read->ChunkIdx, TDriveModel::OP_TYPE_READ);
@@ -1204,24 +1204,24 @@ void TPDisk::WhiteboardReport(TWhiteboardReport &whiteboardReport) {
vdiskMetrics->SetAvailableSize(ownerFree);
vdiskMetrics->SetAllocatedSize(ownerAllocated);
vdiskMetrics->SetStatusFlags(Keeper.GetSpaceStatusFlags(owner));
- auto *vslotId = vdiskMetrics->MutableVSlotId();
- vslotId->SetNodeId(ActorSystem->NodeId);
- vslotId->SetPDiskId(PDiskId);
- vslotId->SetVSlotId(data.VDiskSlotId);
+ auto *vslotId = vdiskMetrics->MutableVSlotId();
+ vslotId->SetNodeId(ActorSystem->NodeId);
+ vslotId->SetPDiskId(PDiskId);
+ vslotId->SetVSlotId(data.VDiskSlotId);
}
NKikimrBlobStorage::TPDiskMetrics& pDiskMetrics = *reportResult->DiskMetrics->Record.AddPDisksMetrics();
pDiskMetrics.SetPDiskId(PDiskId);
pDiskMetrics.SetTotalSize(Format.DiskSize);
- pDiskMetrics.SetAvailableSize(availableSize);
- pDiskMetrics.SetMaxReadThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_READ));
- pDiskMetrics.SetMaxWriteThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_WRITE));
+ pDiskMetrics.SetAvailableSize(availableSize);
+ pDiskMetrics.SetMaxReadThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_READ));
+ pDiskMetrics.SetMaxWriteThroughput(DriveModel.Speed(TDriveModel::OP_TYPE_WRITE));
pDiskMetrics.SetNonRealTimeMs(AtomicGet(NonRealTimeMs));
pDiskMetrics.SetSlowDeviceMs(Max((ui64)AtomicGet(SlowDeviceMs), (ui64)*Mon.DeviceNonperformanceMs));
- pDiskMetrics.SetMaxIOPS(DriveModel.IOPS());
+ pDiskMetrics.SetMaxIOPS(DriveModel.IOPS());
if (minSlotSize != Max<i64>()) {
pDiskMetrics.SetEnforcedDynamicSlotSize(minSlotSize);
}
- pDiskMetrics.SetState(state);
+ pDiskMetrics.SetState(state);
}
ActorSystem->Send(whiteboardReport.Sender, reportResult);
@@ -1463,8 +1463,8 @@ bool TPDisk::YardInitForKnownVDisk(TYardInit &evYardInit, TOwner owner) {
GetStartingPoints(owner, result->StartingPoints);
ownerData.VDiskId = vDiskId;
ownerData.CutLogId = evYardInit.CutLogId;
- ownerData.WhiteboardProxyId = evYardInit.WhiteboardProxyId;
- ownerData.VDiskSlotId = evYardInit.SlotId;
+ ownerData.WhiteboardProxyId = evYardInit.WhiteboardProxyId;
+ ownerData.VDiskSlotId = evYardInit.SlotId;
ownerData.LogRecordsConsequentlyRead = 0;
ownerData.LastSeenLsn = 0;
ownerData.HasAlreadyLoggedThisIncarnation = false;
@@ -1570,8 +1570,8 @@ void TPDisk::YardInitFinish(TYardInit &evYardInit) {
Y_VERIFY(SysLogFirstNoncesToKeep.FirstNonceToKeep[owner] <= SysLogRecord.Nonces.Value[NonceLog]);
SysLogFirstNoncesToKeep.FirstNonceToKeep[owner] = SysLogRecord.Nonces.Value[NonceLog];
OwnerData[owner].CutLogId = evYardInit.CutLogId;
- OwnerData[owner].WhiteboardProxyId = evYardInit.WhiteboardProxyId;
- OwnerData[owner].VDiskSlotId = evYardInit.SlotId;
+ OwnerData[owner].WhiteboardProxyId = evYardInit.WhiteboardProxyId;
+ OwnerData[owner].VDiskSlotId = evYardInit.SlotId;
OwnerData[owner].OwnerRound = evYardInit.OwnerRound;
VDiskOwners[vDiskId] = owner;
OwnerData[owner].Status = TOwnerData::VDISK_STATUS_SENT_INIT;
@@ -2187,7 +2187,7 @@ bool TPDisk::Initialize(TActorSystem *actorSystem, const TActorId &pDiskActor) {
PDiskThread.Start();
if (!BlockDevice->IsGood()) {
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::OpenFileError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::OpenFileError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
TStringStream errStr;
errStr << "Can't open file " << Cfg->GetDevicePath().Quote() << ": ";
@@ -2226,7 +2226,7 @@ bool TPDisk::Initialize(TActorSystem *actorSystem, const TActorId &pDiskActor) {
}
ErrorStr = str.Str();
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::OpenFileError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::OpenFileError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorDeviceSerialMismatch;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_http.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_http.cpp
index 5565a0c829c..f097cf8a11a 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_http.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_http.cpp
@@ -197,7 +197,7 @@ void TPDisk::OutputHtmlOwners(TStringStream &str) {
TABLEH() { str << "VDiskId"; }
TABLEH() { str << "ChunksOwned"; }
TABLEH() { str << "CutLogId"; }
- TABLEH() { str << "WhiteboardProxyId"; }
+ TABLEH() { str << "WhiteboardProxyId"; }
TABLEH() { str << "CurLsnToKeep"; }
TABLEH() { str << "FirstNonceToKeep"; }
TABLEH() { str << "AskedToCutLogAt"; }
@@ -213,7 +213,7 @@ void TPDisk::OutputHtmlOwners(TStringStream &str) {
TABLED() { str << data.VDiskId.ToStringWOGeneration(); }
TABLED() { str << chunksOwned[owner]; }
TABLED() { str << data.CutLogId.ToString(); }
- TABLED() { str << data.WhiteboardProxyId; }
+ TABLED() { str << data.WhiteboardProxyId; }
TABLED() { str << data.CurrentFirstLsnToKeep; }
TABLED() { str << SysLogFirstNoncesToKeep.FirstNonceToKeep[owner]; }
TABLED() { str << data.AskedToCutLogAt; }
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp
index c9e09cc3a43..cce53e6fd90 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp
@@ -1122,7 +1122,7 @@ void TPDisk::InitiateReadSysLog(const TActorId &pDiskActor) {
ui8 *formatSectors = evReadFormatResult->FormatSectors.Get();
BlockDevice->PreadAsync(formatSectors, formatSectorsSize, 0,
new TCompletionEventSender(this, pDiskActor, evReadFormatResult.Release()), TReqId(TReqId::InitialFormatRead, 0), {});
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatRead;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialFormatRead;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::BootingFormatRead;
InitPhase = EInitPhase::ReadingSysLog;
}
@@ -1136,13 +1136,13 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
<< " Marker# BPD01");
switch (InitPhase) {
case EInitPhase::ReadingSysLog:
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogReadError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogReadError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialSysLogRead;
errStr << "Error in initial sys log read" << Endl;
break;
case EInitPhase::ReadingLog:
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialCommonLogRead;
errStr << "Error in initial common log read" << Endl;
@@ -1162,7 +1162,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
ProcessChunk0(evReadLogResult);
if (InitialSysLogWritePosition == 0) {
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogParseError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogParseError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialSysLogParse;
ActorSystem->Send(pDiskActor, new TEvLogInitResult(false,
@@ -1170,7 +1170,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
return;
}
// Parse the main log to obtain busy/free chunk lists
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogRead;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogRead;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::BootingCommonLogRead;
ReadAndParseMainLog(pDiskActor);
InitPhase = EInitPhase::ReadingLog;
@@ -1180,7 +1180,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
{
InitialLogPosition = evReadLogResult.NextPosition;
if (InitialLogPosition == TLogPosition{0, 0}) {
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialCommonLogParse;
ActorSystem->Send(pDiskActor, new TEvLogInitResult(false,
@@ -1255,7 +1255,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
bool isOk = Keeper.Reset(params, errorReason);
if (!isOk) {
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::ChunkQuotaError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::ChunkQuotaError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorCalculatingChunkQuotas;
ActorSystem->Send(pDiskActor, new TEvLogInitResult(false, errorReason));
@@ -1275,7 +1275,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
InitPhase = EInitPhase::Initialized;
if (!InitCommonLogger()) {
// TODO: report red zone
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::CommonLoggerInitError;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::CommonLoggerInitError;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::Error;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorCommonLoggerInit;
ActorSystem->Send(pDiskActor, new TEvLogInitResult(false, "Error in common logger init"));
@@ -1283,7 +1283,7 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul
}
// Now it's ok to write both logs and data.
- *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::Normal;
+ *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::Normal;
*Mon.PDiskBriefState = TPDiskMon::TPDisk::OK;
*Mon.PDiskDetailedState = TPDiskMon::TPDisk::EverythingIsOk;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
index 43b0c69ae9b..12a3cf86575 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_internal_interface.cpp
@@ -16,7 +16,7 @@ TString TEvWhiteboardReportResult::ToString(const TEvWhiteboardReportResult &rec
if (record.PDiskState) {
str << "PDiskState# " << record.PDiskState->Record;
}
- for (const auto& p : record.VDiskStateVect) {
+ for (const auto& p : record.VDiskStateVect) {
str << " VDiskState# " << std::get<1>(p);
}
if (record.DiskMetrics) {
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
index a514e261ab7..ccd8ab31937 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.cpp
@@ -175,7 +175,7 @@ TPDiskMon::TPDiskMon(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counter
BandwidthPSysLogRecordHeader = BandwidthGroup->GetCounter("Bandwidth/PDisk/SysLog/RecordHeader", true);
BandwidthPSysLogPadding = BandwidthGroup->GetCounter("Bandwidth/PDisk/SysLog/Padding", true);
BandwidthPSysLogErasure = BandwidthGroup->GetCounter("Bandwidth/PDisk/SysLog/Erasure", true);
-
+
BandwidthPChunkPayload = BandwidthGroup->GetCounter("Bandwidth/PDisk/Chunk/Payload", true);
BandwidthPChunkSectorFooter = BandwidthGroup->GetCounter("Bandwidth/PDisk/Chunk/SectorFooter", true);
BandwidthPChunkPadding = BandwidthGroup->GetCounter("Bandwidth/PDisk/Chunk/Padding", true);
@@ -402,15 +402,15 @@ void TPDiskMon::UpdateStats() {
}
TPDiskMon::TIoCounters *TPDiskMon::GetWriteCounter(ui8 priority) {
- switch (priority) {
- case NPriWrite::SyncLog: return &WriteSyncLog;
- case NPriWrite::HullFresh: return &WriteFresh;
+ switch (priority) {
+ case NPriWrite::SyncLog: return &WriteSyncLog;
+ case NPriWrite::HullFresh: return &WriteFresh;
case NPriWrite::HullHugeAsyncBlob: return &WriteHuge;
case NPriWrite::HullHugeUserData: return &WriteHuge;
- case NPriWrite::HullComp: return &WriteComp;
- }
+ case NPriWrite::HullComp: return &WriteComp;
+ }
return &Unknown;
-}
+}
TPDiskMon::TIoCounters *TPDiskMon::GetReadCounter(ui8 priority) {
switch (priority) {
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
index 38a0f73b7c8..3e65ae36086 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_mon.h
@@ -364,7 +364,7 @@ struct TPDiskMon {
};
static TString StateToStr(i64 val) {
- return NKikimrBlobStorage::TPDiskState::E_Name(static_cast<NKikimrBlobStorage::TPDiskState::E>(val));
+ return NKikimrBlobStorage::TPDiskState::E_Name(static_cast<NKikimrBlobStorage::TPDiskState::E>(val));
}
static const char *BriefStateToStr(i64 val) {
@@ -642,7 +642,7 @@ struct TPDiskMon {
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPSysLogRecordHeader;
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPSysLogPadding;
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPSysLogErasure;
-
+
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPChunkPayload;
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPChunkSectorFooter;
NMonitoring::TDynamicCounters::TCounterPtr BandwidthPChunkPadding;
@@ -660,27 +660,27 @@ struct TPDiskMon {
Requests = subgroup->GetCounter("Requests", true);
Bytes = subgroup->GetCounter("Bytes", true);
Results = subgroup->GetCounter("Results", true);
- }
-
- void CountRequest(ui32 size) {
+ }
+
+ void CountRequest(ui32 size) {
Requests->Inc();
*Bytes += size;
- }
-
+ }
+
void CountRequest() {
Requests->Inc();
}
- void CountResponse() {
+ void CountResponse() {
Results->Inc();
- }
+ }
void CountResponse(ui32 size) {
Results->Inc();
*Bytes += size;
}
- };
-
+ };
+
struct TReqCounters {
NMonitoring::TDynamicCounters::TCounterPtr Requests;
NMonitoring::TDynamicCounters::TCounterPtr Results;
@@ -715,7 +715,7 @@ struct TPDiskMon {
TIoCounters WriteHuge;
TIoCounters WriteComp;
TIoCounters Trim;
-
+
TIoCounters ReadSyncLog;
TIoCounters ReadComp;
TIoCounters ReadOnlineRt;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h
index ef728e32137..fead31b48c8 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h
@@ -11,25 +11,25 @@ namespace NPDisk {
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#define DISK_SPACE_COLORS(XX) \
- XX(Black) \
- XX(Red) \
- XX(Orange) \
- XX(LightOrange) \
- XX(Yellow) \
+#define DISK_SPACE_COLORS(XX) \
+ XX(Black) \
+ XX(Red) \
+ XX(Orange) \
+ XX(LightOrange) \
+ XX(Yellow) \
XX(LightYellow) \
- XX(Cyan) \
- //
-
+ XX(Cyan) \
+ //
+
class TQuotaRecord {
friend class TPerOwnerQuotaTracker;
TAtomic HardLimit = 0;
TAtomic Free = 0;
-#define DEFINE_DISK_SPACE_COLOR(NAME) TAtomic NAME = 0;
- DISK_SPACE_COLORS(DEFINE_DISK_SPACE_COLOR)
-#undef DEFINE_DISK_SPACE_COLOR
+#define DEFINE_DISK_SPACE_COLOR(NAME) TAtomic NAME = 0;
+ DISK_SPACE_COLORS(DEFINE_DISK_SPACE_COLOR)
+#undef DEFINE_DISK_SPACE_COLOR
TString Name;
std::optional<TVDiskID> VDiskId;
@@ -70,9 +70,9 @@ public:
str << " Free# " << Free;
str << " Used# " << GetUsed();
str << " CurrentColor# " << NKikimrBlobStorage::TPDiskSpaceColor::E_Name(EstimateSpaceColor(0)) << "\n";
-#define PRINT_DISK_SPACE_COLOR(NAME) str << " " #NAME "# " << NAME;
- DISK_SPACE_COLORS(PRINT_DISK_SPACE_COLOR)
-#undef PRINT_DISK_SPACE_COLOR
+#define PRINT_DISK_SPACE_COLOR(NAME) str << " " #NAME "# " << NAME;
+ DISK_SPACE_COLORS(PRINT_DISK_SPACE_COLOR)
+#undef PRINT_DISK_SPACE_COLOR
}
// Called only from the main trhead
@@ -83,13 +83,13 @@ public:
AtomicAdd(HardLimit, increment);
AtomicAdd(Free, increment);
- i64 value = 0;
-#define CALCULATE_COLOR(NAME) \
- value = Max(value, hardLimit * limits.NAME ## Multiplier / limits.NAME ## Divisor + limits.NAME ## Addend); \
- AtomicSet(NAME, value); \
- ++value;
- DISK_SPACE_COLORS(CALCULATE_COLOR)
-#undef CALCULATE_COLOR
+ i64 value = 0;
+#define CALCULATE_COLOR(NAME) \
+ value = Max(value, hardLimit * limits.NAME ## Multiplier / limits.NAME ## Divisor + limits.NAME ## Addend); \
+ AtomicSet(NAME, value); \
+ ++value;
+ DISK_SPACE_COLORS(CALCULATE_COLOR)
+#undef CALCULATE_COLOR
return -increment;
}
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_requestimpl.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_requestimpl.h
index 61c0996e081..81e33588731 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_requestimpl.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_requestimpl.h
@@ -54,7 +54,7 @@ public:
NHPTimer::STime ScheduleTime = 0;
// Tracing
- mutable NWilson::TTraceId TraceId;
+ mutable NWilson::TTraceId TraceId;
mutable NLWTrace::TOrbit Orbit;
public:
TRequestBase(const TActorId &sender, TReqId reqId, TOwner owner, TOwnerRound ownerRound, ui8 priorityClass,
@@ -66,7 +66,7 @@ public:
, PriorityClass(priorityClass)
, OwnerGroupType(EOwnerGroupType::Dynamic)
, CreationTime(HPNow())
- , TraceId(std::move(traceId))
+ , TraceId(std::move(traceId))
{}
void SetOwnerGroupType(bool isStaticGroupOwner) {
@@ -120,16 +120,16 @@ public:
TVDiskID VDisk;
ui64 PDiskGuid;
TActorId CutLogId;
- TActorId WhiteboardProxyId;
- ui32 SlotId;
+ TActorId WhiteboardProxyId;
+ ui32 SlotId;
TYardInit(const NPDisk::TEvYardInit &ev, const TActorId &sender, TAtomicBase reqIdx)
: TRequestBase(sender, TReqId(TReqId::YardInit, reqIdx), 0, ev.OwnerRound, NPriInternal::Other)
, VDisk(ev.VDisk)
, PDiskGuid(ev.PDiskGuid)
, CutLogId(ev.CutLogID)
- , WhiteboardProxyId(ev.WhiteboardProxyId)
- , SlotId(ev.SlotId)
+ , WhiteboardProxyId(ev.WhiteboardProxyId)
+ , SlotId(ev.SlotId)
{}
ERequestType GetType() const override {
@@ -251,7 +251,7 @@ class TLogWrite : public TRequestBase {
public:
TLogWrite *NextInBatch = nullptr;
TLogWrite *BatchTail; // Valid only for the head of the batch
- using TCallback = NPDisk::TEvLog::TCallback;
+ using TCallback = NPDisk::TEvLog::TCallback;
TLogSignature Signature;
ui32 EstimatedChunkIdx;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_signature.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_signature.h
index 6f8e8fb20b4..da2be2fe012 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_signature.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_signature.h
@@ -33,8 +33,8 @@ public:
SignatureIncrHugeDeletes = 19,
SignatureAnubisOsirisPut = 20,
SignatureAddBulkSst = 21,
- SignatureScrub = 22,
- Max = 23
+ SignatureScrub = 22,
+ Max = 23
};
TLogSignature(ui8 val = 0, bool hasCommit = false)
@@ -85,7 +85,7 @@ public:
case SignatureIncrHugeDeletes: return "IncrHugeDeletes";
case SignatureAnubisOsirisPut: return "SignatureAnubisOsirisPut";
case SignatureAddBulkSst: return "SignatureAddBulkSst";
- case SignatureScrub: return "SignatureScrub";
+ case SignatureScrub: return "SignatureScrub";
case Max: return "Max";
}
return TStringBuilder() << "Unknown(" << static_cast<ui32>(Signature) << "(";
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_state.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_state.h
index 3791397b91f..7835cc0f7d7 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_state.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_state.h
@@ -73,7 +73,7 @@ struct TOwnerData {
TLogPosition LogStartPosition{0, 0};
NMetrics::TDecayingAverageValue<ui64, NMetrics::DurationPerMinute, NMetrics::DurationPerSecond> ReadThroughput;
NMetrics::TDecayingAverageValue<ui64, NMetrics::DurationPerMinute, NMetrics::DurationPerSecond> WriteThroughput;
- ui32 VDiskSlotId = 0;
+ ui32 VDiskSlotId = 0;
TIntrusivePtr<TLogReaderBase> LogReader;
TIntrusivePtr<TOwnerInflight> InFlight;
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp
index b49b5bd206f..3e620bd3ae5 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp
@@ -24,20 +24,20 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
// Warning!
// Kikimr Admins use Integer values of EState in their scripts!
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::Initial == 0);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialFormatRead == 1);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialFormatReadError == 2);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogRead == 3);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogReadError == 4);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogParseError == 5);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogRead == 6);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError == 7);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError == 8);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::CommonLoggerInitError == 9);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::Normal == 10);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::OpenFileError == 11);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::ChunkQuotaError == 12);
- UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::DeviceIoError == 13);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::Initial == 0);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialFormatRead == 1);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialFormatReadError == 2);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogRead == 3);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogReadError == 4);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialSysLogParseError == 5);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogRead == 6);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError == 7);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError == 8);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::CommonLoggerInitError == 9);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::Normal == 10);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::OpenFileError == 11);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::ChunkQuotaError == 12);
+ UNIT_ASSERT(NKikimrBlobStorage::TPDiskState::DeviceIoError == 13);
}
struct TActorTestContext {
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.cpp
index 305cd7a8ea1..d99604f2b19 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.cpp
@@ -1191,7 +1191,7 @@ void TTestWhiteboard::ReceiveEvent() {
}
if (LastResponse.whiteboardDiskMetricsResult) {
ASSERT_YTHROW(LastResponse.whiteboardDiskMetricsResult->Type() ==
- TEvBlobStorage::EvControllerUpdateDiskStatus, "Unexpected message");
+ TEvBlobStorage::EvControllerUpdateDiskStatus, "Unexpected message");
IsDiskMetricsResultReceived = true;
VERBOSE_COUT("Received DiskMetricsResult");
}
@@ -2556,7 +2556,7 @@ void TTestRedZoneSurvivability::TestFSM(const TActorContext &ctx) {
| ui32(NKikimrBlobStorage::StatusDiskSpaceCyan)
| ui32(NKikimrBlobStorage::StatusDiskSpaceRed)
| ui32(NKikimrBlobStorage::StatusDiskSpaceOrange)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)
| ui32(NKikimrBlobStorage::StatusDiskSpaceYellowStop)
| ui32(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove));
ASSERT_YTHROW(ChunkIds.size() > 0, "Unexpected ChunkIds.size() == " << ChunkIds.size());
@@ -2572,7 +2572,7 @@ void TTestRedZoneSurvivability::TestFSM(const TActorContext &ctx) {
| ui32(NKikimrBlobStorage::StatusDiskSpaceCyan)
| ui32(NKikimrBlobStorage::StatusDiskSpaceRed)
| ui32(NKikimrBlobStorage::StatusDiskSpaceOrange)
- | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)
+ | ui32(NKikimrBlobStorage::StatusDiskSpaceLightOrange)
| ui32(NKikimrBlobStorage::StatusDiskSpaceYellowStop)
| ui32(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove));
VERBOSE_COUT(" Sending TEvLog to delete a chunk");
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_base_test.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_base_test.h
index e6c75e60003..e1230f95fa4 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_base_test.h
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_base_test.h
@@ -89,7 +89,7 @@ protected:
NMon::TEvHttpInfoRes *HttpResult;
NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateUpdate *whiteboardPDiskResult;
NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate *whiteboardVDiskResult;
- TEvBlobStorage::TEvControllerUpdateDiskStatus *whiteboardDiskMetricsResult;
+ TEvBlobStorage::TEvControllerUpdateDiskStatus *whiteboardDiskMetricsResult;
TResponseData() {
Clear();
@@ -338,7 +338,7 @@ protected:
VERBOSE_COUT("Got " << ev->Get()->ToString());
ActTestFSM(ctx);
}
- void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev, const TActorContext &ctx) {
+ void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev, const TActorContext &ctx) {
LastResponse.whiteboardDiskMetricsResult = ev->Get();
VERBOSE_COUT("Got " << ev->Get()->ToString());
ActTestFSM(ctx);
@@ -371,7 +371,7 @@ public:
HFunc(NMon::TEvHttpInfoRes, Handle);
HFunc(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateUpdate, Handle);
HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle);
- HFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
+ HFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
HFunc(TEvTablet::TEvBoot, HandleBoot);
}
}
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_writer.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_writer.cpp
index b638c55ed8d..1521fdfb192 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_writer.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_writer.cpp
@@ -12,7 +12,7 @@ namespace NPDisk {
void TBufferedWriter::WriteBufferWithFlush(TReqId reqId, NWilson::TTraceId *traceId,
TCompletionAction *flushAction, ui32 chunkIdx) {
- static NWilson::TTraceId noTrace;
+ static NWilson::TTraceId noTrace;
if (DirtyFrom != DirtyTo) {
ui8 *source = CurrentBuffer->Data() + DirtyFrom - StartOffset;
ui32 sizeToWrite = (ui32)(DirtyTo - DirtyFrom);
diff --git a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
index 1e84f5d8f69..1128036a129 100644
--- a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
+++ b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
@@ -1,673 +1,673 @@
-#include "pdisk_mock.h"
+#include "pdisk_mock.h"
#include <ydb/core/util/stlog.h>
#include <ydb/core/util/interval_set.h>
-
-namespace NKikimr {
-
-#ifdef _MSC_VER
-#define PDISK_MOCK_LOG(...)
-#else
-#define PDISK_MOCK_LOG(PRI, MARKER, ...) STLOG(NLog::PRI_##PRI, BS_PDISK, MARKER, Prefix << __VA_ARGS__)
-#endif
-
-struct TPDiskMockState::TImpl {
- struct TChunkData {
- std::unordered_map<ui32, const TString*> Blocks;
- };
- struct TOwner {
- TVDiskID VDiskId;
- ui32 SlotId;
- std::set<ui32> ReservedChunks, CommittedChunks;
- std::map<ui32, TChunkData> ChunkData;
- NPDisk::TOwnerRound OwnerRound = 0;
- TActorId CutLogId;
- std::deque<NPDisk::TLogRecord> Log;
+
+namespace NKikimr {
+
+#ifdef _MSC_VER
+#define PDISK_MOCK_LOG(...)
+#else
+#define PDISK_MOCK_LOG(PRI, MARKER, ...) STLOG(NLog::PRI_##PRI, BS_PDISK, MARKER, Prefix << __VA_ARGS__)
+#endif
+
+struct TPDiskMockState::TImpl {
+ struct TChunkData {
+ std::unordered_map<ui32, const TString*> Blocks;
+ };
+ struct TOwner {
+ TVDiskID VDiskId;
+ ui32 SlotId;
+ std::set<ui32> ReservedChunks, CommittedChunks;
+ std::map<ui32, TChunkData> ChunkData;
+ NPDisk::TOwnerRound OwnerRound = 0;
+ TActorId CutLogId;
+ std::deque<NPDisk::TLogRecord> Log;
TMap<TLogSignature, NPDisk::TLogRecord> StartingPoints;
- ui64 LogDataSize = 0;
- bool Slain = false;
- ui64 LastLsn = 0;
- };
-
- const ui32 NodeId;
- const ui32 PDiskId;
- const ui64 PDiskGuid;
- const ui64 Size;
- const ui32 ChunkSize;
- const ui32 TotalChunks;
- const ui32 AppendBlockSize;
- std::map<ui8, TOwner> Owners;
- std::set<ui32> FreeChunks;
- ui32 NextFreeChunk = 1;
- std::unordered_map<TString, ui32> Blocks;
- TIntervalSet<ui64> Corrupted;
-
- TImpl(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- , PDiskGuid(pdiskGuid)
- , Size(size)
- , ChunkSize(chunkSize)
- , TotalChunks(Size / ChunkSize)
- , AppendBlockSize(4096)
- , NextFreeChunk(1)
- {}
-
- TImpl(const TImpl&) = default;
-
- ui32 GetNumFreeChunks() const {
- return FreeChunks.size() + TotalChunks - NextFreeChunk;
- }
-
- void AdjustFreeChunks() {
- for (auto it = FreeChunks.end(); it != FreeChunks.begin() && *--it == NextFreeChunk - 1; it = FreeChunks.erase(it)) {
- --NextFreeChunk;
- }
- }
-
- ui32 AllocateChunk(TOwner& to) {
- ui32 chunkIdx = TotalChunks;
-
- if (FreeChunks.empty()) {
- chunkIdx = NextFreeChunk++;
- to.ReservedChunks.insert(chunkIdx);
- } else {
- auto it = FreeChunks.begin();
- chunkIdx = *it;
- to.ReservedChunks.insert(FreeChunks.extract(it));
- }
-
- Y_VERIFY(chunkIdx != TotalChunks);
- return chunkIdx;
- }
-
- void AdjustRefs() {
- for (auto& [ownerId, owner] : Owners) {
- for (auto& [chunkIdx, chunk] : owner.ChunkData) {
- for (auto& [blockIdx, ref] : chunk.Blocks) {
- const auto it = Blocks.find(*ref);
- Y_VERIFY(it != Blocks.end());
- ref = &it->first;
- }
- }
- }
- }
-
- template<typename TQuery, typename TResult>
- TOwner *FindOwner(TQuery *msg, std::unique_ptr<TResult>& res) {
- if (const auto it = Owners.find(msg->Owner); it == Owners.end()) {
- Y_FAIL("invalid Owner");
- } else if (it->second.Slain) {
- res->Status = NKikimrProto::INVALID_OWNER;
- res->ErrorReason = "VDisk is slain";
- } else if (msg->OwnerRound != it->second.OwnerRound) {
- res->Status = NKikimrProto::INVALID_ROUND;
- res->ErrorReason = "invalid OwnerRound";
- } else {
- return &it->second;
- }
- return nullptr;
- }
-
- std::tuple<ui8, TOwner*> FindOrCreateOwner(const TVDiskID& vdiskId, ui32 slotId, bool *created) {
- for (auto& [ownerId, owner] : Owners) {
- if (slotId == owner.SlotId) {
- Y_VERIFY(owner.VDiskId.SameExceptGeneration(vdiskId));
- *created = false;
- return std::make_tuple(ownerId, &owner);
- }
- }
- ui8 ownerId = 1;
- std::map<ui8, TOwner>::iterator it;
- for (it = Owners.begin(); it != Owners.end() && it->first == ownerId; ++it, ++ownerId)
- {}
- Y_VERIFY(ownerId);
- it = Owners.emplace_hint(it, ownerId, TOwner());
- it->second.VDiskId = vdiskId;
- it->second.SlotId = slotId;
- *created = true;
- return std::make_tuple(ownerId, &it->second);
- }
-
- void ResetOwnerReservedChunks(TOwner& owner) {
- for (const TChunkIdx chunkIdx : owner.ReservedChunks) {
- owner.ChunkData.erase(chunkIdx);
- }
- FreeChunks.merge(owner.ReservedChunks);
- AdjustFreeChunks();
- }
-
- void CommitChunk(TOwner& owner, TChunkIdx chunkIdx) {
- const ui32 num = owner.ReservedChunks.erase(chunkIdx) + owner.CommittedChunks.erase(chunkIdx);
- Y_VERIFY(num);
- const bool inserted = owner.CommittedChunks.insert(chunkIdx).second;
- Y_VERIFY(inserted);
- }
-
- void DeleteChunk(TOwner& owner, TChunkIdx chunkIdx) {
- const ui32 num = owner.ReservedChunks.erase(chunkIdx) + owner.CommittedChunks.erase(chunkIdx);
- Y_VERIFY(num);
- const bool inserted = FreeChunks.insert(chunkIdx).second;
- Y_VERIFY(inserted);
- AdjustFreeChunks();
- }
-
- void SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled) {
- const ui64 chunkBegin = ui64(chunkIdx) * ChunkSize;
- const ui64 diskBegin = chunkBegin + begin;
- const ui64 diskEnd = chunkBegin + end;
- if (enabled) {
- Corrupted |= {diskBegin, diskEnd};
- } else {
- Corrupted -= {diskBegin, diskEnd};
- }
- }
-
- std::set<ui32> GetChunks() {
- std::set<ui32> res;
- for (auto& [ownerId, owner] : Owners) {
- for (auto& [chunkIdx, data] : owner.ChunkData) {
- const bool inserted = res.insert(chunkIdx).second;
- Y_VERIFY(inserted);
- }
- }
- return res;
- }
-
- ui32 GetChunkSize() const {
- return ChunkSize;
- }
-
+ ui64 LogDataSize = 0;
+ bool Slain = false;
+ ui64 LastLsn = 0;
+ };
+
+ const ui32 NodeId;
+ const ui32 PDiskId;
+ const ui64 PDiskGuid;
+ const ui64 Size;
+ const ui32 ChunkSize;
+ const ui32 TotalChunks;
+ const ui32 AppendBlockSize;
+ std::map<ui8, TOwner> Owners;
+ std::set<ui32> FreeChunks;
+ ui32 NextFreeChunk = 1;
+ std::unordered_map<TString, ui32> Blocks;
+ TIntervalSet<ui64> Corrupted;
+
+ TImpl(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , PDiskGuid(pdiskGuid)
+ , Size(size)
+ , ChunkSize(chunkSize)
+ , TotalChunks(Size / ChunkSize)
+ , AppendBlockSize(4096)
+ , NextFreeChunk(1)
+ {}
+
+ TImpl(const TImpl&) = default;
+
+ ui32 GetNumFreeChunks() const {
+ return FreeChunks.size() + TotalChunks - NextFreeChunk;
+ }
+
+ void AdjustFreeChunks() {
+ for (auto it = FreeChunks.end(); it != FreeChunks.begin() && *--it == NextFreeChunk - 1; it = FreeChunks.erase(it)) {
+ --NextFreeChunk;
+ }
+ }
+
+ ui32 AllocateChunk(TOwner& to) {
+ ui32 chunkIdx = TotalChunks;
+
+ if (FreeChunks.empty()) {
+ chunkIdx = NextFreeChunk++;
+ to.ReservedChunks.insert(chunkIdx);
+ } else {
+ auto it = FreeChunks.begin();
+ chunkIdx = *it;
+ to.ReservedChunks.insert(FreeChunks.extract(it));
+ }
+
+ Y_VERIFY(chunkIdx != TotalChunks);
+ return chunkIdx;
+ }
+
+ void AdjustRefs() {
+ for (auto& [ownerId, owner] : Owners) {
+ for (auto& [chunkIdx, chunk] : owner.ChunkData) {
+ for (auto& [blockIdx, ref] : chunk.Blocks) {
+ const auto it = Blocks.find(*ref);
+ Y_VERIFY(it != Blocks.end());
+ ref = &it->first;
+ }
+ }
+ }
+ }
+
+ template<typename TQuery, typename TResult>
+ TOwner *FindOwner(TQuery *msg, std::unique_ptr<TResult>& res) {
+ if (const auto it = Owners.find(msg->Owner); it == Owners.end()) {
+ Y_FAIL("invalid Owner");
+ } else if (it->second.Slain) {
+ res->Status = NKikimrProto::INVALID_OWNER;
+ res->ErrorReason = "VDisk is slain";
+ } else if (msg->OwnerRound != it->second.OwnerRound) {
+ res->Status = NKikimrProto::INVALID_ROUND;
+ res->ErrorReason = "invalid OwnerRound";
+ } else {
+ return &it->second;
+ }
+ return nullptr;
+ }
+
+ std::tuple<ui8, TOwner*> FindOrCreateOwner(const TVDiskID& vdiskId, ui32 slotId, bool *created) {
+ for (auto& [ownerId, owner] : Owners) {
+ if (slotId == owner.SlotId) {
+ Y_VERIFY(owner.VDiskId.SameExceptGeneration(vdiskId));
+ *created = false;
+ return std::make_tuple(ownerId, &owner);
+ }
+ }
+ ui8 ownerId = 1;
+ std::map<ui8, TOwner>::iterator it;
+ for (it = Owners.begin(); it != Owners.end() && it->first == ownerId; ++it, ++ownerId)
+ {}
+ Y_VERIFY(ownerId);
+ it = Owners.emplace_hint(it, ownerId, TOwner());
+ it->second.VDiskId = vdiskId;
+ it->second.SlotId = slotId;
+ *created = true;
+ return std::make_tuple(ownerId, &it->second);
+ }
+
+ void ResetOwnerReservedChunks(TOwner& owner) {
+ for (const TChunkIdx chunkIdx : owner.ReservedChunks) {
+ owner.ChunkData.erase(chunkIdx);
+ }
+ FreeChunks.merge(owner.ReservedChunks);
+ AdjustFreeChunks();
+ }
+
+ void CommitChunk(TOwner& owner, TChunkIdx chunkIdx) {
+ const ui32 num = owner.ReservedChunks.erase(chunkIdx) + owner.CommittedChunks.erase(chunkIdx);
+ Y_VERIFY(num);
+ const bool inserted = owner.CommittedChunks.insert(chunkIdx).second;
+ Y_VERIFY(inserted);
+ }
+
+ void DeleteChunk(TOwner& owner, TChunkIdx chunkIdx) {
+ const ui32 num = owner.ReservedChunks.erase(chunkIdx) + owner.CommittedChunks.erase(chunkIdx);
+ Y_VERIFY(num);
+ const bool inserted = FreeChunks.insert(chunkIdx).second;
+ Y_VERIFY(inserted);
+ AdjustFreeChunks();
+ }
+
+ void SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled) {
+ const ui64 chunkBegin = ui64(chunkIdx) * ChunkSize;
+ const ui64 diskBegin = chunkBegin + begin;
+ const ui64 diskEnd = chunkBegin + end;
+ if (enabled) {
+ Corrupted |= {diskBegin, diskEnd};
+ } else {
+ Corrupted -= {diskBegin, diskEnd};
+ }
+ }
+
+ std::set<ui32> GetChunks() {
+ std::set<ui32> res;
+ for (auto& [ownerId, owner] : Owners) {
+ for (auto& [chunkIdx, data] : owner.ChunkData) {
+ const bool inserted = res.insert(chunkIdx).second;
+ Y_VERIFY(inserted);
+ }
+ }
+ return res;
+ }
+
+ ui32 GetChunkSize() const {
+ return ChunkSize;
+ }
+
TIntervalSet<i64> GetWrittenAreas(ui32 chunkIdx) const {
TIntervalSet<i64> res;
- for (auto& [ownerId, owner] : Owners) {
- if (const auto it = owner.ChunkData.find(chunkIdx); it != owner.ChunkData.end()) {
- for (const auto& [idx, data] : it->second.Blocks) {
- const ui32 offset = idx * AppendBlockSize;
- res |= TIntervalSet<i64>(offset, offset + AppendBlockSize);
- }
- break;
- }
- }
- return res;
- }
-
- void TrimQuery() {
- for (auto& [ownerId, owner] : Owners) {
- if (!owner.Log.empty()) {
- TActivationContext::Send(new IEventHandle(owner.CutLogId, {}, new NPDisk::TEvCutLog(ownerId,
- owner.OwnerRound, owner.Log.back().Lsn + 1, 0, 0, 0, 0)));
- }
- }
- }
-};
-
-TPDiskMockState::TPDiskMockState(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize)
- : TPDiskMockState(std::make_unique<TImpl>(nodeId, pdiskId, pdiskGuid, size, chunkSize))
-{}
-
-TPDiskMockState::TPDiskMockState(std::unique_ptr<TImpl>&& impl)
- : Impl(std::move(impl))
-{}
-
-TPDiskMockState::~TPDiskMockState()
-{}
-
-void TPDiskMockState::SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled) {
- Impl->SetCorruptedArea(chunkIdx, begin, end, enabled);
-}
-
-std::set<ui32> TPDiskMockState::GetChunks() {
- return Impl->GetChunks();
-}
-
-ui32 TPDiskMockState::GetChunkSize() const {
- return Impl->GetChunkSize();
-}
-
+ for (auto& [ownerId, owner] : Owners) {
+ if (const auto it = owner.ChunkData.find(chunkIdx); it != owner.ChunkData.end()) {
+ for (const auto& [idx, data] : it->second.Blocks) {
+ const ui32 offset = idx * AppendBlockSize;
+ res |= TIntervalSet<i64>(offset, offset + AppendBlockSize);
+ }
+ break;
+ }
+ }
+ return res;
+ }
+
+ void TrimQuery() {
+ for (auto& [ownerId, owner] : Owners) {
+ if (!owner.Log.empty()) {
+ TActivationContext::Send(new IEventHandle(owner.CutLogId, {}, new NPDisk::TEvCutLog(ownerId,
+ owner.OwnerRound, owner.Log.back().Lsn + 1, 0, 0, 0, 0)));
+ }
+ }
+ }
+};
+
+TPDiskMockState::TPDiskMockState(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize)
+ : TPDiskMockState(std::make_unique<TImpl>(nodeId, pdiskId, pdiskGuid, size, chunkSize))
+{}
+
+TPDiskMockState::TPDiskMockState(std::unique_ptr<TImpl>&& impl)
+ : Impl(std::move(impl))
+{}
+
+TPDiskMockState::~TPDiskMockState()
+{}
+
+void TPDiskMockState::SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled) {
+ Impl->SetCorruptedArea(chunkIdx, begin, end, enabled);
+}
+
+std::set<ui32> TPDiskMockState::GetChunks() {
+ return Impl->GetChunks();
+}
+
+ui32 TPDiskMockState::GetChunkSize() const {
+ return Impl->GetChunkSize();
+}
+
TIntervalSet<i64> TPDiskMockState::GetWrittenAreas(ui32 chunkIdx) const {
- return Impl->GetWrittenAreas(chunkIdx);
-}
-
-void TPDiskMockState::TrimQuery() {
- Impl->TrimQuery();
-}
-
-TPDiskMockState::TPtr TPDiskMockState::Snapshot() {
- auto res = MakeIntrusive<TPDiskMockState>(std::make_unique<TImpl>(*Impl));
- res->Impl->AdjustRefs();
- return res;
-}
-
-class TPDiskMockActor : public TActor<TPDiskMockActor> {
- enum {
- EvResume = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- using TImpl = TPDiskMockState::TImpl;
-
- TPDiskMockState::TPtr State;
- TImpl& Impl;
- const TString Prefix;
-
-public:
- TPDiskMockActor(TPDiskMockState::TPtr state)
- : TActor(&TThis::StateFunc)
- , State(std::move(state)) // to keep ownership
- , Impl(*State->Impl)
- , Prefix(TStringBuilder() << "PDiskMock[" << Impl.NodeId << ":" << Impl.PDiskId << "] ")
- {
- for (auto& [ownerId, owner] : Impl.Owners) { // reset runtime parameters to default values
- owner.OwnerRound = 0;
- owner.CutLogId = TActorId();
- Impl.ResetOwnerReservedChunks(owner); // return reserved, but not committed chunks to free pool
- }
- }
-
- void Handle(NPDisk::TEvYardInit::TPtr ev) {
- // report message and validate PDisk guid
- auto *msg = ev->Get();
- PDISK_MOCK_LOG(NOTICE, PDM01, "received TEvYardInit", (Msg, msg->ToString()));
- Y_VERIFY(msg->PDiskGuid == Impl.PDiskGuid, "PDiskGuid mismatch");
-
- // find matching owner or create a new one
- ui8 ownerId;
- TImpl::TOwner *owner;
- bool created;
- std::tie(ownerId, owner) = Impl.FindOrCreateOwner(msg->VDisk, msg->SlotId, &created);
- std::unique_ptr<NPDisk::TEvYardInitResult> res;
- if (ev->Get()->OwnerRound > owner->OwnerRound) {
- // fill in runtime owner parameters
- owner->OwnerRound = ev->Get()->OwnerRound;
- owner->CutLogId = ev->Get()->CutLogID;
- owner->Slain = false;
-
- // drop data from any reserved chunks and return them to free pool
- Impl.ResetOwnerReservedChunks(*owner);
-
- // fill in the response
- TVector<TChunkIdx> ownedChunks(owner->CommittedChunks.begin(), owner->CommittedChunks.end());
- const ui64 seekTimeUs = 100;
- const ui64 readSpeedBps = 100 * 1000 * 1000;
- const ui64 writeSpeedBps = 100 * 1000 * 1000;
- const ui64 readBlockSize = 65536;
- const ui64 writeBlockSize = 65536;
- const ui64 bulkWriteBlockSize = 65536;
- res = std::make_unique<NPDisk::TEvYardInitResult>(NKikimrProto::OK, seekTimeUs, readSpeedBps, writeSpeedBps,
- readBlockSize, writeBlockSize, bulkWriteBlockSize, Impl.ChunkSize, Impl.AppendBlockSize, ownerId,
- owner->OwnerRound, GetStatusFlags(), std::move(ownedChunks), TString());
- res->StartingPoints = owner->StartingPoints;
- } else {
- res = std::make_unique<NPDisk::TEvYardInitResult>(NKikimrProto::INVALID_ROUND, "invalid owner round");
- }
-
- PDISK_MOCK_LOG(INFO, PDM02, "sending TEvYardInitResult", (Msg, res->ToString()), (Created, created));
- Send(ev->Sender, res.release());
- }
-
- void Handle(NPDisk::TEvSlay::TPtr ev) {
- auto *msg = ev->Get();
- PDISK_MOCK_LOG(INFO, PDM17, "received TEvSlay", (Msg, msg->ToString()));
- auto res = std::make_unique<NPDisk::TEvSlayResult>(NKikimrProto::OK, GetStatusFlags(), msg->VDiskId,
- msg->SlayOwnerRound, msg->PDiskId, msg->VSlotId, TString());
- bool found = false;
- for (auto& [ownerId, owner] : Impl.Owners) {
- if (!owner.VDiskId.SameExceptGeneration(msg->VDiskId)) {
- // not our disk
- } else if (owner.Slain) {
- res->Status = NKikimrProto::ALREADY; // already slain or not found
- res->ErrorReason = "already slain or not found";
- found = true;
- break;
- } else if (msg->SlayOwnerRound <= owner.OwnerRound) {
- res->Status = NKikimrProto::RACE;
- res->ErrorReason = TStringBuilder() << "SlayOwnerRound# " << msg->SlayOwnerRound << " actual OwnerRound# "
- << owner.OwnerRound << " race detected";
- found = true;
- break;
- } else {
- owner.Slain = true;
- Impl.FreeChunks.merge(owner.ReservedChunks);
- Impl.FreeChunks.merge(owner.CommittedChunks);
- Impl.AdjustFreeChunks();
- owner.ChunkData.clear();
- owner.Log.clear();
- owner.LogDataSize = 0;
- owner.LastLsn = 0;
- owner.StartingPoints.clear();
- found = true;
- break;
- }
- }
- if (!found) {
- // a race is possible
- res->Status = NKikimrProto::ALREADY;
- res->ErrorReason = "not found";
- }
- Send(ev->Sender, res.release());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- std::deque<std::tuple<TActorId, THolder<NPDisk::TEvLog>>> LogQ;
-
- void Handle(NPDisk::TEvLog::TPtr ev) {
- if (LogQ.empty()) {
- TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), TActorId(), nullptr, 0));
- }
- LogQ.emplace_back(ev->Sender, ev->Release());
- }
-
- void Handle(NPDisk::TEvMultiLog::TPtr ev) {
- if (LogQ.empty()) {
- TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), TActorId(), nullptr, 0));
- }
- for (auto& msg : ev->Get()->Logs) {
- LogQ.emplace_back(ev->Sender, std::move(msg));
- }
- }
-
- void HandleLogQ() {
- std::deque<std::unique_ptr<IEventHandle>> results; // per sender actor
- std::deque<std::tuple<NPDisk::TEvLog::TCallback, NPDisk::TEvLogResult*>> callbacks; // just queue
- for (auto& item : std::exchange(LogQ, {})) {
- auto& recipient = std::get<0>(item);
- auto& msg = std::get<1>(item);
- NPDisk::TEvLogResult *res = nullptr;
- auto addRes = [&](NKikimrProto::EReplyStatus status, const TString& errorReason = TString()) {
- auto p = std::make_unique<NPDisk::TEvLogResult>(status, GetStatusFlags(), errorReason);
- res = p.get();
- results.emplace_back(new IEventHandle(recipient, SelfId(), p.release()));
- };
- if (const auto it = Impl.Owners.find(msg->Owner); it == Impl.Owners.end()) {
- Y_FAIL("invalid Owner");
- } else if (it->second.Slain) {
- addRes(NKikimrProto::INVALID_OWNER, "VDisk is slain");
- } else if (msg->OwnerRound != it->second.OwnerRound) {
- addRes(NKikimrProto::INVALID_ROUND, "invalid OwnerRound");
- } else {
- TImpl::TOwner& owner = it->second;
- PDISK_MOCK_LOG(DEBUG, PDM11, "received TEvLog", (Msg, msg->ToString()), (VDiskId, owner.VDiskId));
-
- Y_VERIFY(msg->Lsn > std::exchange(owner.LastLsn, msg->Lsn));
-
- // add successful result to the actor's result queue if there is no such last one
- if (!results.empty() && results.back()->Recipient == recipient) {
- res = results.back()->CastAsLocal<NPDisk::TEvLogResult>();
- if (res->Status != NKikimrProto::OK) {
- res = nullptr;
- }
- }
- if (!res) {
- addRes(NKikimrProto::OK);
- }
- res->Results.emplace_back(msg->Lsn, msg->Cookie);
-
- // process the log entry
- bool isStartingPoint = false;
+ return Impl->GetWrittenAreas(chunkIdx);
+}
+
+void TPDiskMockState::TrimQuery() {
+ Impl->TrimQuery();
+}
+
+TPDiskMockState::TPtr TPDiskMockState::Snapshot() {
+ auto res = MakeIntrusive<TPDiskMockState>(std::make_unique<TImpl>(*Impl));
+ res->Impl->AdjustRefs();
+ return res;
+}
+
+class TPDiskMockActor : public TActor<TPDiskMockActor> {
+ enum {
+ EvResume = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ using TImpl = TPDiskMockState::TImpl;
+
+ TPDiskMockState::TPtr State;
+ TImpl& Impl;
+ const TString Prefix;
+
+public:
+ TPDiskMockActor(TPDiskMockState::TPtr state)
+ : TActor(&TThis::StateFunc)
+ , State(std::move(state)) // to keep ownership
+ , Impl(*State->Impl)
+ , Prefix(TStringBuilder() << "PDiskMock[" << Impl.NodeId << ":" << Impl.PDiskId << "] ")
+ {
+ for (auto& [ownerId, owner] : Impl.Owners) { // reset runtime parameters to default values
+ owner.OwnerRound = 0;
+ owner.CutLogId = TActorId();
+ Impl.ResetOwnerReservedChunks(owner); // return reserved, but not committed chunks to free pool
+ }
+ }
+
+ void Handle(NPDisk::TEvYardInit::TPtr ev) {
+ // report message and validate PDisk guid
+ auto *msg = ev->Get();
+ PDISK_MOCK_LOG(NOTICE, PDM01, "received TEvYardInit", (Msg, msg->ToString()));
+ Y_VERIFY(msg->PDiskGuid == Impl.PDiskGuid, "PDiskGuid mismatch");
+
+ // find matching owner or create a new one
+ ui8 ownerId;
+ TImpl::TOwner *owner;
+ bool created;
+ std::tie(ownerId, owner) = Impl.FindOrCreateOwner(msg->VDisk, msg->SlotId, &created);
+ std::unique_ptr<NPDisk::TEvYardInitResult> res;
+ if (ev->Get()->OwnerRound > owner->OwnerRound) {
+ // fill in runtime owner parameters
+ owner->OwnerRound = ev->Get()->OwnerRound;
+ owner->CutLogId = ev->Get()->CutLogID;
+ owner->Slain = false;
+
+ // drop data from any reserved chunks and return them to free pool
+ Impl.ResetOwnerReservedChunks(*owner);
+
+ // fill in the response
+ TVector<TChunkIdx> ownedChunks(owner->CommittedChunks.begin(), owner->CommittedChunks.end());
+ const ui64 seekTimeUs = 100;
+ const ui64 readSpeedBps = 100 * 1000 * 1000;
+ const ui64 writeSpeedBps = 100 * 1000 * 1000;
+ const ui64 readBlockSize = 65536;
+ const ui64 writeBlockSize = 65536;
+ const ui64 bulkWriteBlockSize = 65536;
+ res = std::make_unique<NPDisk::TEvYardInitResult>(NKikimrProto::OK, seekTimeUs, readSpeedBps, writeSpeedBps,
+ readBlockSize, writeBlockSize, bulkWriteBlockSize, Impl.ChunkSize, Impl.AppendBlockSize, ownerId,
+ owner->OwnerRound, GetStatusFlags(), std::move(ownedChunks), TString());
+ res->StartingPoints = owner->StartingPoints;
+ } else {
+ res = std::make_unique<NPDisk::TEvYardInitResult>(NKikimrProto::INVALID_ROUND, "invalid owner round");
+ }
+
+ PDISK_MOCK_LOG(INFO, PDM02, "sending TEvYardInitResult", (Msg, res->ToString()), (Created, created));
+ Send(ev->Sender, res.release());
+ }
+
+ void Handle(NPDisk::TEvSlay::TPtr ev) {
+ auto *msg = ev->Get();
+ PDISK_MOCK_LOG(INFO, PDM17, "received TEvSlay", (Msg, msg->ToString()));
+ auto res = std::make_unique<NPDisk::TEvSlayResult>(NKikimrProto::OK, GetStatusFlags(), msg->VDiskId,
+ msg->SlayOwnerRound, msg->PDiskId, msg->VSlotId, TString());
+ bool found = false;
+ for (auto& [ownerId, owner] : Impl.Owners) {
+ if (!owner.VDiskId.SameExceptGeneration(msg->VDiskId)) {
+ // not our disk
+ } else if (owner.Slain) {
+ res->Status = NKikimrProto::ALREADY; // already slain or not found
+ res->ErrorReason = "already slain or not found";
+ found = true;
+ break;
+ } else if (msg->SlayOwnerRound <= owner.OwnerRound) {
+ res->Status = NKikimrProto::RACE;
+ res->ErrorReason = TStringBuilder() << "SlayOwnerRound# " << msg->SlayOwnerRound << " actual OwnerRound# "
+ << owner.OwnerRound << " race detected";
+ found = true;
+ break;
+ } else {
+ owner.Slain = true;
+ Impl.FreeChunks.merge(owner.ReservedChunks);
+ Impl.FreeChunks.merge(owner.CommittedChunks);
+ Impl.AdjustFreeChunks();
+ owner.ChunkData.clear();
+ owner.Log.clear();
+ owner.LogDataSize = 0;
+ owner.LastLsn = 0;
+ owner.StartingPoints.clear();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // a race is possible
+ res->Status = NKikimrProto::ALREADY;
+ res->ErrorReason = "not found";
+ }
+ Send(ev->Sender, res.release());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ std::deque<std::tuple<TActorId, THolder<NPDisk::TEvLog>>> LogQ;
+
+ void Handle(NPDisk::TEvLog::TPtr ev) {
+ if (LogQ.empty()) {
+ TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), TActorId(), nullptr, 0));
+ }
+ LogQ.emplace_back(ev->Sender, ev->Release());
+ }
+
+ void Handle(NPDisk::TEvMultiLog::TPtr ev) {
+ if (LogQ.empty()) {
+ TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), TActorId(), nullptr, 0));
+ }
+ for (auto& msg : ev->Get()->Logs) {
+ LogQ.emplace_back(ev->Sender, std::move(msg));
+ }
+ }
+
+ void HandleLogQ() {
+ std::deque<std::unique_ptr<IEventHandle>> results; // per sender actor
+ std::deque<std::tuple<NPDisk::TEvLog::TCallback, NPDisk::TEvLogResult*>> callbacks; // just queue
+ for (auto& item : std::exchange(LogQ, {})) {
+ auto& recipient = std::get<0>(item);
+ auto& msg = std::get<1>(item);
+ NPDisk::TEvLogResult *res = nullptr;
+ auto addRes = [&](NKikimrProto::EReplyStatus status, const TString& errorReason = TString()) {
+ auto p = std::make_unique<NPDisk::TEvLogResult>(status, GetStatusFlags(), errorReason);
+ res = p.get();
+ results.emplace_back(new IEventHandle(recipient, SelfId(), p.release()));
+ };
+ if (const auto it = Impl.Owners.find(msg->Owner); it == Impl.Owners.end()) {
+ Y_FAIL("invalid Owner");
+ } else if (it->second.Slain) {
+ addRes(NKikimrProto::INVALID_OWNER, "VDisk is slain");
+ } else if (msg->OwnerRound != it->second.OwnerRound) {
+ addRes(NKikimrProto::INVALID_ROUND, "invalid OwnerRound");
+ } else {
+ TImpl::TOwner& owner = it->second;
+ PDISK_MOCK_LOG(DEBUG, PDM11, "received TEvLog", (Msg, msg->ToString()), (VDiskId, owner.VDiskId));
+
+ Y_VERIFY(msg->Lsn > std::exchange(owner.LastLsn, msg->Lsn));
+
+ // add successful result to the actor's result queue if there is no such last one
+ if (!results.empty() && results.back()->Recipient == recipient) {
+ res = results.back()->CastAsLocal<NPDisk::TEvLogResult>();
+ if (res->Status != NKikimrProto::OK) {
+ res = nullptr;
+ }
+ }
+ if (!res) {
+ addRes(NKikimrProto::OK);
+ }
+ res->Results.emplace_back(msg->Lsn, msg->Cookie);
+
+ // process the log entry
+ bool isStartingPoint = false;
if (msg->Signature.HasCommitRecord()) {
- const auto& cr = msg->CommitRecord;
- if (cr.FirstLsnToKeep) { // trim log
- std::deque<NPDisk::TLogRecord>::iterator it;
- for (it = owner.Log.begin(); it != owner.Log.end() && it->Lsn < cr.FirstLsnToKeep; ++it)
- {}
- size_t num = std::distance(owner.Log.begin(), it);
- num = RandomNumber(num + 1);
- for (size_t i = 0; i < num; ++i) {
- owner.LogDataSize -= owner.Log.front().Data.size();
- owner.Log.pop_front();
- }
- }
- for (const TChunkIdx chunk : cr.CommitChunks) {
- Impl.CommitChunk(owner, chunk);
- }
- for (const TChunkIdx chunk : cr.DeleteChunks) {
- Impl.DeleteChunk(owner, chunk);
- }
- isStartingPoint = cr.IsStartingPoint;
- }
+ const auto& cr = msg->CommitRecord;
+ if (cr.FirstLsnToKeep) { // trim log
+ std::deque<NPDisk::TLogRecord>::iterator it;
+ for (it = owner.Log.begin(); it != owner.Log.end() && it->Lsn < cr.FirstLsnToKeep; ++it)
+ {}
+ size_t num = std::distance(owner.Log.begin(), it);
+ num = RandomNumber(num + 1);
+ for (size_t i = 0; i < num; ++i) {
+ owner.LogDataSize -= owner.Log.front().Data.size();
+ owner.Log.pop_front();
+ }
+ }
+ for (const TChunkIdx chunk : cr.CommitChunks) {
+ Impl.CommitChunk(owner, chunk);
+ }
+ for (const TChunkIdx chunk : cr.DeleteChunks) {
+ Impl.DeleteChunk(owner, chunk);
+ }
+ isStartingPoint = cr.IsStartingPoint;
+ }
owner.Log.emplace_back(msg->Signature.GetUnmasked(), msg->Data, msg->Lsn);
- owner.LogDataSize += msg->Data.size();
- if (isStartingPoint) {
+ owner.LogDataSize += msg->Data.size();
+ if (isStartingPoint) {
owner.StartingPoints[msg->Signature.GetUnmasked()] = owner.Log.back();
- }
- }
- Y_VERIFY(res);
- if (auto&& cb = std::move(msg->LogCallback)) { // register callback in the queue if there is one
- callbacks.emplace_back(std::move(cb), res);
- }
- }
- // invoke all accumulated callbacks with fully filled response messages
- for (auto& item : callbacks) {
- (*std::get<0>(item))(TlsActivationContext->ExecutorThread.ActorSystem, *std::get<1>(item));
- }
- // send the results
- for (auto& msg : results) {
- auto *ev = msg->CastAsLocal<NPDisk::TEvLogResult>();
- const TActorId& recipient = msg->Recipient;
- PDISK_MOCK_LOG(DEBUG, PDM12, "sending TEvLogResult", (Msg, ev->ToString()), (Recipient, recipient));
- TActivationContext::Send(msg.release());
- }
- // issue cut log events on log overflow
- for (auto& [ownerId, owner] : Impl.Owners) {
- const ui64 maxLogDataSize = 1048576;
- if (owner.LogDataSize >= maxLogDataSize) {
- ui64 temp = owner.LogDataSize;
- ui64 lsn = 0;
- for (auto it = owner.Log.begin(); it != owner.Log.end() && temp >= maxLogDataSize / 2; ++it) {
- temp -= it->Data.size();
- lsn = it->Lsn;
- }
- Send(owner.CutLogId, new NPDisk::TEvCutLog(ownerId, owner.OwnerRound, lsn, 0, 0, 0, 0));
- }
- }
- }
-
- void Handle(NPDisk::TEvReadLog::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvReadLogResult>(NKikimrProto::OK, msg->Position, msg->Position,
- true, GetStatusFlags(), TString(), msg->Owner);
- if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
- PDISK_MOCK_LOG(INFO, PDM05, "received TEvReadLog", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
- ui64 size = 0;
- Y_VERIFY(msg->Position.OffsetInChunk <= owner->Log.size());
- for (auto it = owner->Log.begin() + msg->Position.OffsetInChunk; it != owner->Log.end(); ++it) {
- res->Results.push_back(*it);
- res->IsEndOfLog = ++res->NextPosition.OffsetInChunk == owner->Log.size();
- size += it->Data.size();
- if (size >= msg->SizeLimit) {
- break;
- }
- }
- PDISK_MOCK_LOG(INFO, PDM06, "sending TEvReadLogResult", (Msg, res->ToString()));
- }
- Send(ev->Sender, res.release());
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Handle(NPDisk::TEvChunkReserve::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvChunkReserveResult>(NKikimrProto::OK, GetStatusFlags());
- if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
- if (Impl.GetNumFreeChunks() < msg->SizeChunks) {
- PDISK_MOCK_LOG(NOTICE, PDM09, "received TEvChunkReserve", (Msg, msg->ToString()), (Error, "no free chunks"));
- res->Status = NKikimrProto::OUT_OF_SPACE;
- res->ErrorReason = "no free chunks";
- } else {
- PDISK_MOCK_LOG(DEBUG, PDM07, "received TEvChunkReserve", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
- for (ui32 i = 0; i < msg->SizeChunks; ++i) {
- res->ChunkIds.push_back(Impl.AllocateChunk(*owner));
- }
- PDISK_MOCK_LOG(DEBUG, PDM10, "sending TEvChunkReserveResult", (Msg, res->ToString()));
- }
- }
- Send(ev->Sender, res.release());
- }
-
- void Handle(NPDisk::TEvChunkRead::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvChunkReadResult>(NKikimrProto::OK, msg->ChunkIdx, msg->Offset,
- msg->Cookie, GetStatusFlags(), TString());
- if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
- PDISK_MOCK_LOG(DEBUG, PDM13, "received TEvChunkRead", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
- Y_VERIFY_S(owner->ReservedChunks.count(msg->ChunkIdx) || owner->CommittedChunks.count(msg->ChunkIdx),
- "VDiskId# " << owner->VDiskId << " ChunkIdx# " << msg->ChunkIdx);
- ui32 offset = msg->Offset;
- ui32 size = msg->Size;
- Y_VERIFY(offset < Impl.ChunkSize && offset + size <= Impl.ChunkSize && size);
- TString data = TString::Uninitialized(size);
-
- const auto chunkIt = owner->ChunkData.find(msg->ChunkIdx);
- if (chunkIt == owner->ChunkData.end()) {
- res->Data.AddGap(0, size); // no data at all
- } else {
- TImpl::TChunkData& chunk = chunkIt->second;
- const ui64 chunkOffset = (ui64)msg->ChunkIdx * Impl.ChunkSize;
- if (Impl.Corrupted & TIntervalSet<ui64>(chunkOffset + offset, chunkOffset + offset + size)) {
- res->Status = NKikimrProto::CORRUPTED;
- } else {
- char *begin = data.Detach(), *ptr = begin;
- while (size) {
- const ui32 blockIdx = offset / Impl.AppendBlockSize;
- const ui32 offsetInBlock = offset % Impl.AppendBlockSize;
- const ui32 num = Min(size, Impl.AppendBlockSize - offsetInBlock);
- const auto it = chunk.Blocks.find(blockIdx);
- if (it == chunk.Blocks.end()) {
- const ui32 base = ptr - begin;
- res->Data.AddGap(base, base + num);
- } else {
- memcpy(ptr, it->second->data() + offsetInBlock, num);
- }
- ptr += num;
- offset += num;
- size -= num;
- }
- }
- }
-
- if (res->Status == NKikimrProto::OK) {
- res->Data.SetData(std::move(data));
- res->Data.Commit();
- }
- PDISK_MOCK_LOG(DEBUG, PDM14, "sending TEvChunkReadResult", (Msg, res->ToString()));
- }
- Send(ev->Sender, res.release());
- }
-
- void Handle(NPDisk::TEvChunkWrite::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvChunkWriteResult>(NKikimrProto::OK, msg->ChunkIdx, msg->Cookie,
- GetStatusFlags(), TString());
- if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
- PDISK_MOCK_LOG(DEBUG, PDM15, "received TEvChunkWrite", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
- if (!msg->ChunkIdx) { // allocate chunk
- if (!Impl.GetNumFreeChunks()) {
- res->Status = NKikimrProto::OUT_OF_SPACE;
- res->ErrorReason = "no free chunks";
- } else {
- msg->ChunkIdx = res->ChunkIdx = Impl.AllocateChunk(*owner);
- }
- }
- if (msg->ChunkIdx) {
- // allow reads only from owned chunks
- Y_VERIFY(owner->ReservedChunks.count(msg->ChunkIdx) || owner->CommittedChunks.count(msg->ChunkIdx));
- // ensure offset and write sizes are granular
- Y_VERIFY(msg->Offset % Impl.AppendBlockSize == 0);
- Y_VERIFY(msg->PartsPtr);
- Y_VERIFY(msg->PartsPtr->ByteSize() % Impl.AppendBlockSize == 0);
- Y_VERIFY(msg->Offset + msg->PartsPtr->ByteSize() <= Impl.ChunkSize);
- // issue write
- const ui32 offset = msg->Offset;
- TImpl::TChunkData& chunk = owner->ChunkData[msg->ChunkIdx];
- if (msg->PartsPtr && Impl.Corrupted) {
- const ui64 chunkOffset = (ui64)msg->ChunkIdx * Impl.ChunkSize;
- Impl.Corrupted -= {chunkOffset + offset, chunkOffset + offset + msg->PartsPtr->ByteSize()};
- }
- // create queue of blocks to write
- ui32 blockIdx = offset / Impl.AppendBlockSize;
- TString currentBlock;
- char *ptr, *end;
- auto push = [&](const auto& kv) {
- auto&& [data, len] = kv;
- ui32 offset = 0;
- while (offset != len) {
- if (!currentBlock) {
- currentBlock = TString::Uninitialized(Impl.AppendBlockSize);
- ptr = currentBlock.Detach();
- end = ptr + currentBlock.size();
- }
- const ui32 num = Min<ui32>(end - ptr, len - offset); // calculate number of bytes to move
- if (data) {
- memcpy(ptr, static_cast<const char*>(data) + offset, num);
- } else {
- memset(ptr, 0, num);
- }
- offset += num;
- ptr += num;
- if (ptr == end) { // commit full block
- auto&& [it, inserted] = Impl.Blocks.try_emplace(std::move(currentBlock), 0);
- ++it->second;
- if (const TString *prev = std::exchange(chunk.Blocks[blockIdx++], &it->first)) {
- const auto it = Impl.Blocks.find(*prev);
- Y_VERIFY(it != Impl.Blocks.end());
- if (!--it->second) {
- Impl.Blocks.erase(it);
- }
- }
- currentBlock = {};
- }
- }
- };
- for (ui32 i = 0; i < msg->PartsPtr->Size(); ++i) {
- push((*msg->PartsPtr)[i]);
- }
- }
- PDISK_MOCK_LOG(DEBUG, PDM16, "received TEvChunkWriteResult", (Msg, res->ToString()));
- }
- Send(ev->Sender, res.release());
- }
-
- void Handle(NPDisk::TEvHarakiri::TPtr /*ev*/) {
- Y_FAIL();
- }
-
- void Handle(NPDisk::TEvCheckSpace::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvCheckSpaceResult>(NKikimrProto::OK, GetStatusFlags(),
- Impl.GetNumFreeChunks(), Impl.TotalChunks, Impl.TotalChunks - Impl.GetNumFreeChunks(), TString());
- Impl.FindOwner(msg, res); // to ensure correct owner/round
- Send(ev->Sender, res.release());
- }
-
- void Handle(NPDisk::TEvConfigureScheduler::TPtr ev) {
- auto *msg = ev->Get();
- auto res = std::make_unique<NPDisk::TEvConfigureSchedulerResult>(NKikimrProto::OK, TString());
- Impl.FindOwner(msg, res); // to ensure correct owner/round
- Send(ev->Sender, res.release());
- }
-
- NPDisk::TStatusFlags GetStatusFlags() {
- return {};
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(NPDisk::TEvYardInit, Handle);
- hFunc(NPDisk::TEvLog, Handle);
- hFunc(NPDisk::TEvMultiLog, Handle);
- cFunc(EvResume, HandleLogQ);
- hFunc(NPDisk::TEvReadLog, Handle);
- hFunc(NPDisk::TEvChunkReserve, Handle);
- hFunc(NPDisk::TEvChunkRead, Handle);
- hFunc(NPDisk::TEvChunkWrite, Handle);
- hFunc(NPDisk::TEvCheckSpace, Handle);
- hFunc(NPDisk::TEvSlay, Handle);
- hFunc(NPDisk::TEvHarakiri, Handle);
- hFunc(NPDisk::TEvConfigureScheduler, Handle);
- )
-};
-
-IActor *CreatePDiskMockActor(TPDiskMockState::TPtr state) {
- return new TPDiskMockActor(std::move(state));
-}
-
-} // NKikimr
+ }
+ }
+ Y_VERIFY(res);
+ if (auto&& cb = std::move(msg->LogCallback)) { // register callback in the queue if there is one
+ callbacks.emplace_back(std::move(cb), res);
+ }
+ }
+ // invoke all accumulated callbacks with fully filled response messages
+ for (auto& item : callbacks) {
+ (*std::get<0>(item))(TlsActivationContext->ExecutorThread.ActorSystem, *std::get<1>(item));
+ }
+ // send the results
+ for (auto& msg : results) {
+ auto *ev = msg->CastAsLocal<NPDisk::TEvLogResult>();
+ const TActorId& recipient = msg->Recipient;
+ PDISK_MOCK_LOG(DEBUG, PDM12, "sending TEvLogResult", (Msg, ev->ToString()), (Recipient, recipient));
+ TActivationContext::Send(msg.release());
+ }
+ // issue cut log events on log overflow
+ for (auto& [ownerId, owner] : Impl.Owners) {
+ const ui64 maxLogDataSize = 1048576;
+ if (owner.LogDataSize >= maxLogDataSize) {
+ ui64 temp = owner.LogDataSize;
+ ui64 lsn = 0;
+ for (auto it = owner.Log.begin(); it != owner.Log.end() && temp >= maxLogDataSize / 2; ++it) {
+ temp -= it->Data.size();
+ lsn = it->Lsn;
+ }
+ Send(owner.CutLogId, new NPDisk::TEvCutLog(ownerId, owner.OwnerRound, lsn, 0, 0, 0, 0));
+ }
+ }
+ }
+
+ void Handle(NPDisk::TEvReadLog::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvReadLogResult>(NKikimrProto::OK, msg->Position, msg->Position,
+ true, GetStatusFlags(), TString(), msg->Owner);
+ if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
+ PDISK_MOCK_LOG(INFO, PDM05, "received TEvReadLog", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
+ ui64 size = 0;
+ Y_VERIFY(msg->Position.OffsetInChunk <= owner->Log.size());
+ for (auto it = owner->Log.begin() + msg->Position.OffsetInChunk; it != owner->Log.end(); ++it) {
+ res->Results.push_back(*it);
+ res->IsEndOfLog = ++res->NextPosition.OffsetInChunk == owner->Log.size();
+ size += it->Data.size();
+ if (size >= msg->SizeLimit) {
+ break;
+ }
+ }
+ PDISK_MOCK_LOG(INFO, PDM06, "sending TEvReadLogResult", (Msg, res->ToString()));
+ }
+ Send(ev->Sender, res.release());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void Handle(NPDisk::TEvChunkReserve::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvChunkReserveResult>(NKikimrProto::OK, GetStatusFlags());
+ if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
+ if (Impl.GetNumFreeChunks() < msg->SizeChunks) {
+ PDISK_MOCK_LOG(NOTICE, PDM09, "received TEvChunkReserve", (Msg, msg->ToString()), (Error, "no free chunks"));
+ res->Status = NKikimrProto::OUT_OF_SPACE;
+ res->ErrorReason = "no free chunks";
+ } else {
+ PDISK_MOCK_LOG(DEBUG, PDM07, "received TEvChunkReserve", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
+ for (ui32 i = 0; i < msg->SizeChunks; ++i) {
+ res->ChunkIds.push_back(Impl.AllocateChunk(*owner));
+ }
+ PDISK_MOCK_LOG(DEBUG, PDM10, "sending TEvChunkReserveResult", (Msg, res->ToString()));
+ }
+ }
+ Send(ev->Sender, res.release());
+ }
+
+ void Handle(NPDisk::TEvChunkRead::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvChunkReadResult>(NKikimrProto::OK, msg->ChunkIdx, msg->Offset,
+ msg->Cookie, GetStatusFlags(), TString());
+ if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
+ PDISK_MOCK_LOG(DEBUG, PDM13, "received TEvChunkRead", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
+ Y_VERIFY_S(owner->ReservedChunks.count(msg->ChunkIdx) || owner->CommittedChunks.count(msg->ChunkIdx),
+ "VDiskId# " << owner->VDiskId << " ChunkIdx# " << msg->ChunkIdx);
+ ui32 offset = msg->Offset;
+ ui32 size = msg->Size;
+ Y_VERIFY(offset < Impl.ChunkSize && offset + size <= Impl.ChunkSize && size);
+ TString data = TString::Uninitialized(size);
+
+ const auto chunkIt = owner->ChunkData.find(msg->ChunkIdx);
+ if (chunkIt == owner->ChunkData.end()) {
+ res->Data.AddGap(0, size); // no data at all
+ } else {
+ TImpl::TChunkData& chunk = chunkIt->second;
+ const ui64 chunkOffset = (ui64)msg->ChunkIdx * Impl.ChunkSize;
+ if (Impl.Corrupted & TIntervalSet<ui64>(chunkOffset + offset, chunkOffset + offset + size)) {
+ res->Status = NKikimrProto::CORRUPTED;
+ } else {
+ char *begin = data.Detach(), *ptr = begin;
+ while (size) {
+ const ui32 blockIdx = offset / Impl.AppendBlockSize;
+ const ui32 offsetInBlock = offset % Impl.AppendBlockSize;
+ const ui32 num = Min(size, Impl.AppendBlockSize - offsetInBlock);
+ const auto it = chunk.Blocks.find(blockIdx);
+ if (it == chunk.Blocks.end()) {
+ const ui32 base = ptr - begin;
+ res->Data.AddGap(base, base + num);
+ } else {
+ memcpy(ptr, it->second->data() + offsetInBlock, num);
+ }
+ ptr += num;
+ offset += num;
+ size -= num;
+ }
+ }
+ }
+
+ if (res->Status == NKikimrProto::OK) {
+ res->Data.SetData(std::move(data));
+ res->Data.Commit();
+ }
+ PDISK_MOCK_LOG(DEBUG, PDM14, "sending TEvChunkReadResult", (Msg, res->ToString()));
+ }
+ Send(ev->Sender, res.release());
+ }
+
+ void Handle(NPDisk::TEvChunkWrite::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvChunkWriteResult>(NKikimrProto::OK, msg->ChunkIdx, msg->Cookie,
+ GetStatusFlags(), TString());
+ if (TImpl::TOwner *owner = Impl.FindOwner(msg, res)) {
+ PDISK_MOCK_LOG(DEBUG, PDM15, "received TEvChunkWrite", (Msg, msg->ToString()), (VDiskId, owner->VDiskId));
+ if (!msg->ChunkIdx) { // allocate chunk
+ if (!Impl.GetNumFreeChunks()) {
+ res->Status = NKikimrProto::OUT_OF_SPACE;
+ res->ErrorReason = "no free chunks";
+ } else {
+ msg->ChunkIdx = res->ChunkIdx = Impl.AllocateChunk(*owner);
+ }
+ }
+ if (msg->ChunkIdx) {
+ // allow reads only from owned chunks
+ Y_VERIFY(owner->ReservedChunks.count(msg->ChunkIdx) || owner->CommittedChunks.count(msg->ChunkIdx));
+ // ensure offset and write sizes are granular
+ Y_VERIFY(msg->Offset % Impl.AppendBlockSize == 0);
+ Y_VERIFY(msg->PartsPtr);
+ Y_VERIFY(msg->PartsPtr->ByteSize() % Impl.AppendBlockSize == 0);
+ Y_VERIFY(msg->Offset + msg->PartsPtr->ByteSize() <= Impl.ChunkSize);
+ // issue write
+ const ui32 offset = msg->Offset;
+ TImpl::TChunkData& chunk = owner->ChunkData[msg->ChunkIdx];
+ if (msg->PartsPtr && Impl.Corrupted) {
+ const ui64 chunkOffset = (ui64)msg->ChunkIdx * Impl.ChunkSize;
+ Impl.Corrupted -= {chunkOffset + offset, chunkOffset + offset + msg->PartsPtr->ByteSize()};
+ }
+ // create queue of blocks to write
+ ui32 blockIdx = offset / Impl.AppendBlockSize;
+ TString currentBlock;
+ char *ptr, *end;
+ auto push = [&](const auto& kv) {
+ auto&& [data, len] = kv;
+ ui32 offset = 0;
+ while (offset != len) {
+ if (!currentBlock) {
+ currentBlock = TString::Uninitialized(Impl.AppendBlockSize);
+ ptr = currentBlock.Detach();
+ end = ptr + currentBlock.size();
+ }
+ const ui32 num = Min<ui32>(end - ptr, len - offset); // calculate number of bytes to move
+ if (data) {
+ memcpy(ptr, static_cast<const char*>(data) + offset, num);
+ } else {
+ memset(ptr, 0, num);
+ }
+ offset += num;
+ ptr += num;
+ if (ptr == end) { // commit full block
+ auto&& [it, inserted] = Impl.Blocks.try_emplace(std::move(currentBlock), 0);
+ ++it->second;
+ if (const TString *prev = std::exchange(chunk.Blocks[blockIdx++], &it->first)) {
+ const auto it = Impl.Blocks.find(*prev);
+ Y_VERIFY(it != Impl.Blocks.end());
+ if (!--it->second) {
+ Impl.Blocks.erase(it);
+ }
+ }
+ currentBlock = {};
+ }
+ }
+ };
+ for (ui32 i = 0; i < msg->PartsPtr->Size(); ++i) {
+ push((*msg->PartsPtr)[i]);
+ }
+ }
+ PDISK_MOCK_LOG(DEBUG, PDM16, "received TEvChunkWriteResult", (Msg, res->ToString()));
+ }
+ Send(ev->Sender, res.release());
+ }
+
+ void Handle(NPDisk::TEvHarakiri::TPtr /*ev*/) {
+ Y_FAIL();
+ }
+
+ void Handle(NPDisk::TEvCheckSpace::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvCheckSpaceResult>(NKikimrProto::OK, GetStatusFlags(),
+ Impl.GetNumFreeChunks(), Impl.TotalChunks, Impl.TotalChunks - Impl.GetNumFreeChunks(), TString());
+ Impl.FindOwner(msg, res); // to ensure correct owner/round
+ Send(ev->Sender, res.release());
+ }
+
+ void Handle(NPDisk::TEvConfigureScheduler::TPtr ev) {
+ auto *msg = ev->Get();
+ auto res = std::make_unique<NPDisk::TEvConfigureSchedulerResult>(NKikimrProto::OK, TString());
+ Impl.FindOwner(msg, res); // to ensure correct owner/round
+ Send(ev->Sender, res.release());
+ }
+
+ NPDisk::TStatusFlags GetStatusFlags() {
+ return {};
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(NPDisk::TEvYardInit, Handle);
+ hFunc(NPDisk::TEvLog, Handle);
+ hFunc(NPDisk::TEvMultiLog, Handle);
+ cFunc(EvResume, HandleLogQ);
+ hFunc(NPDisk::TEvReadLog, Handle);
+ hFunc(NPDisk::TEvChunkReserve, Handle);
+ hFunc(NPDisk::TEvChunkRead, Handle);
+ hFunc(NPDisk::TEvChunkWrite, Handle);
+ hFunc(NPDisk::TEvCheckSpace, Handle);
+ hFunc(NPDisk::TEvSlay, Handle);
+ hFunc(NPDisk::TEvHarakiri, Handle);
+ hFunc(NPDisk::TEvConfigureScheduler, Handle);
+ )
+};
+
+IActor *CreatePDiskMockActor(TPDiskMockState::TPtr state) {
+ return new TPDiskMockActor(std::move(state));
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h
index a09441f4ab5..cada0b5c776 100644
--- a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h
+++ b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h
@@ -1,34 +1,34 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
#include <ydb/core/util/interval_set.h>
-#include <library/cpp/actors/core/actor.h>
-#include <util/generic/ptr.h>
-
-namespace NKikimr {
-
- class TPDiskMockState : public TThrRefBase {
- struct TImpl;
- std::unique_ptr<TImpl> Impl;
- friend class TPDiskMockActor;
-
- public:
- using TPtr = TIntrusivePtr<TPDiskMockState>;
-
- public:
- TPDiskMockState(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize = 128 << 20);
- TPDiskMockState(std::unique_ptr<TImpl>&& impl);
- ~TPDiskMockState();
-
- void SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled);
- std::set<ui32> GetChunks();
- ui32 GetChunkSize() const;
+#include <library/cpp/actors/core/actor.h>
+#include <util/generic/ptr.h>
+
+namespace NKikimr {
+
+ class TPDiskMockState : public TThrRefBase {
+ struct TImpl;
+ std::unique_ptr<TImpl> Impl;
+ friend class TPDiskMockActor;
+
+ public:
+ using TPtr = TIntrusivePtr<TPDiskMockState>;
+
+ public:
+ TPDiskMockState(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize = 128 << 20);
+ TPDiskMockState(std::unique_ptr<TImpl>&& impl);
+ ~TPDiskMockState();
+
+ void SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled);
+ std::set<ui32> GetChunks();
+ ui32 GetChunkSize() const;
TIntervalSet<i64> GetWrittenAreas(ui32 chunkIdx) const;
- void TrimQuery();
-
- TPtr Snapshot(); // create a copy of PDisk whole state
- };
-
- IActor *CreatePDiskMockActor(TPDiskMockState::TPtr state);
-
-} // NKikimr
+ void TrimQuery();
+
+ TPtr Snapshot(); // create a copy of PDisk whole state
+ };
+
+ IActor *CreatePDiskMockActor(TPDiskMockState::TPtr state);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/pdisk/mock/ya.make b/ydb/core/blobstorage/pdisk/mock/ya.make
index 11637c4dc42..3cb6ba7b6c9 100644
--- a/ydb/core/blobstorage/pdisk/mock/ya.make
+++ b/ydb/core/blobstorage/pdisk/mock/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
OWNER(g:kikimr)
@@ -12,4 +12,4 @@ PEERDIR(
ydb/core/blobstorage/pdisk
)
-END()
+END()
diff --git a/ydb/core/blobstorage/testload/test_load_actor.cpp b/ydb/core/blobstorage/testload/test_load_actor.cpp
index c8788b13104..5fc08b69fe8 100644
--- a/ydb/core/blobstorage/testload/test_load_actor.cpp
+++ b/ydb/core/blobstorage/testload/test_load_actor.cpp
@@ -1,4 +1,4 @@
-#include "test_load_actor.h"
+#include "test_load_actor.h"
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/counters.h>
@@ -7,27 +7,27 @@
#include <google/protobuf/text_format.h>
#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NKikimr {
-
-using namespace NActors;
-
-class TLoadActor : public TActorBootstrapped<TLoadActor> {
- // per-actor HTTP info
- struct TActorInfo {
- ui64 Tag; // load tag
+
+namespace NKikimr {
+
+using namespace NActors;
+
+class TLoadActor : public TActorBootstrapped<TLoadActor> {
+ // per-actor HTTP info
+ struct TActorInfo {
+ ui64 Tag; // load tag
TString Data; // HTML response
- };
-
- // per-request info
- struct THttpInfoRequest {
+ };
+
+ // per-request info
+ struct THttpInfoRequest {
TActorId Origin; // who asked for status
- int SubRequestId; // origin subrequest id
+ int SubRequestId; // origin subrequest id
THashMap<TActorId, TActorInfo> ActorMap; // per-actor status
- ui32 HttpInfoResPending; // number of requests pending
- TString ErrorMessage;
- };
-
+ ui32 HttpInfoResPending; // number of requests pending
+ TString ErrorMessage;
+ };
+
struct TFinishedTestInfo {
ui64 Tag;
TString ErrorReason;
@@ -37,54 +37,54 @@ class TLoadActor : public TActorBootstrapped<TLoadActor> {
// info about finished actors
TVector<TFinishedTestInfo> FinishedTests;
- // currently running load actors
+ // currently running load actors
TMap<ui64, TActorId> LoadActors;
-
- // next HTTP request identifier
- ui32 NextRequestId;
-
- // HTTP info requests being currently executed
+
+ // next HTTP request identifier
+ ui32 NextRequestId;
+
+ // HTTP info requests being currently executed
THashMap<ui32, THttpInfoRequest> InfoRequests;
-
+
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LOAD_ACTOR;
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LOAD_ACTOR;
}
TLoadActor(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters)
- : NextRequestId(1)
+ : NextRequestId(1)
, Counters(counters)
{}
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- Become(&TLoadActor::StateFunc);
- }
-
- void Handle(TEvBlobStorage::TEvTestLoadRequest::TPtr& ev, const TActorContext& ctx) {
- ui32 status = NMsgBusProxy::MSTATUS_OK;
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ Become(&TLoadActor::StateFunc);
+ }
+
+ void Handle(TEvBlobStorage::TEvTestLoadRequest::TPtr& ev, const TActorContext& ctx) {
+ ui32 status = NMsgBusProxy::MSTATUS_OK;
TString error;
- const auto& record = ev->Get()->Record;
- try {
- ProcessCmd(record, ctx);
- } catch (const TLoadActorException& ex) {
+ const auto& record = ev->Get()->Record;
+ try {
+ ProcessCmd(record, ctx);
+ } catch (const TLoadActorException& ex) {
LOG_ERROR_S(ctx, NKikimrServices::BS_LOAD_TEST, "Exception while creating load actor, what# "
<< ex.what());
- status = NMsgBusProxy::MSTATUS_ERROR;
- error = ex.what();
- }
- auto response = std::make_unique<TEvBlobStorage::TEvTestLoadResponse>();
- response->Record.SetStatus(status);
- if (error) {
- response->Record.SetErrorReason(error);
- }
- if (record.HasCookie()) {
- response->Record.SetCookie(record.GetCookie());
- }
- ctx.Send(ev->Sender, response.release());
- }
-
+ status = NMsgBusProxy::MSTATUS_ERROR;
+ error = ex.what();
+ }
+ auto response = std::make_unique<TEvBlobStorage::TEvTestLoadResponse>();
+ response->Record.SetStatus(status);
+ if (error) {
+ response->Record.SetErrorReason(error);
+ }
+ if (record.HasCookie()) {
+ response->Record.SetCookie(record.GetCookie());
+ }
+ ctx.Send(ev->Sender, response.release());
+ }
+
template<typename T>
ui64 GetOrGenerateTag(const T& cmd) {
if (cmd.HasTag()) {
@@ -98,22 +98,22 @@ public:
}
}
- void ProcessCmd(const NKikimrBlobStorage::TEvTestLoadRequest& record, const TActorContext& ctx) {
- switch (record.Command_case()) {
- case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kLoadStart: {
- const auto& cmd = record.GetLoadStart();
+ void ProcessCmd(const NKikimrBlobStorage::TEvTestLoadRequest& record, const TActorContext& ctx) {
+ switch (record.Command_case()) {
+ case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kLoadStart: {
+ const auto& cmd = record.GetLoadStart();
const ui64 tag = GetOrGenerateTag(cmd);
if (LoadActors.count(tag) != 0) {
ythrow TLoadActorException() << Sprintf("duplicate load actor with Tag# %" PRIu64, tag);
- }
+ }
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Create new load actor with tag# " << tag);
LoadActors.emplace(tag, ctx.Register(CreateWriterTestLoad(cmd, ctx.SelfID,
GetServiceCounters(Counters, "load_actor"), tag)));
- break;
- }
-
- case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kLoadStop: {
- const auto& cmd = record.GetLoadStop();
+ break;
+ }
+
+ case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kLoadStop: {
+ const auto& cmd = record.GetLoadStop();
if (cmd.HasRemoveAllTags() && cmd.GetRemoveAllTags()) {
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Delete all running load actors");
for (auto& actorPair : LoadActors) {
@@ -130,22 +130,22 @@ public:
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Delete running load actor with tag# "
<< tag);
ctx.Send(iter->second, new TEvents::TEvPoisonPill);
- }
- break;
- }
-
- case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kPDiskLoadStart: {
- const auto& cmd = record.GetPDiskLoadStart();
+ }
+ break;
+ }
+
+ case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kPDiskLoadStart: {
+ const auto& cmd = record.GetPDiskLoadStart();
const ui64 tag = GetOrGenerateTag(cmd);
if (LoadActors.count(tag) != 0) {
ythrow TLoadActorException() << Sprintf("duplicate load actor with Tag# %" PRIu64, tag);
- }
+ }
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Create new load actor with tag# " << tag);
LoadActors.emplace(tag, ctx.Register(CreatePDiskWriterTestLoad(
cmd, ctx.SelfID, GetServiceCounters(Counters, "load_actor"), 0, tag)));
- break;
- }
-
+ break;
+ }
+
case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kPDiskReadLoadStart: {
const auto& cmd = record.GetPDiskReadLoadStart();
const ui64 tag = GetOrGenerateTag(cmd);
@@ -170,17 +170,17 @@ public:
break;
}
- case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kVDiskLoadStart: {
- const auto& cmd = record.GetVDiskLoadStart();
+ case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kVDiskLoadStart: {
+ const auto& cmd = record.GetVDiskLoadStart();
const ui64 tag = GetOrGenerateTag(cmd);
if (LoadActors.count(tag) != 0) {
ythrow TLoadActorException() << Sprintf("duplicate load actor with Tag# %" PRIu64, tag);
- }
+ }
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Create new load actor with tag# " << tag);
LoadActors.emplace(tag, ctx.Register(CreateVDiskWriterTestLoad(cmd, ctx.SelfID, tag)));
- break;
- }
-
+ break;
+ }
+
case NKikimrBlobStorage::TEvTestLoadRequest::CommandCase::kKeyValueLoadStart: {
const auto& cmd = record.GetKeyValueLoadStart();
const ui64 tag = GetOrGenerateTag(cmd);
@@ -228,131 +228,131 @@ public:
<< ui32(record.Command_case())
<< " protoTxt# " << protoTxt.Quote());
}
- }
- }
-
- void Handle(TEvTestLoadFinished::TPtr& ev, const TActorContext& ctx) {
- const auto& msg = ev->Get();
- auto iter = LoadActors.find(msg->Tag);
- Y_VERIFY(iter != LoadActors.end());
+ }
+ }
+
+ void Handle(TEvTestLoadFinished::TPtr& ev, const TActorContext& ctx) {
+ const auto& msg = ev->Get();
+ auto iter = LoadActors.find(msg->Tag);
+ Y_VERIFY(iter != LoadActors.end());
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Load actor with tag# " << msg->Tag << " finished");
- LoadActors.erase(iter);
-
+ LoadActors.erase(iter);
+
FinishedTests.push_back({msg->Tag, msg->ErrorReason, TAppData::TimeProvider->Now()});
- auto it = InfoRequests.begin();
- while (it != InfoRequests.end()) {
- auto next = std::next(it);
-
- THttpInfoRequest& info = it->second;
- auto actorIt = info.ActorMap.find(ev->Sender);
- if (actorIt != info.ActorMap.end()) {
- const bool empty = !actorIt->second.Data;
- info.ActorMap.erase(actorIt);
- if (empty && !--info.HttpInfoResPending) {
- GenerateHttpInfoRes(ctx, it->first);
- }
- }
-
- it = next;
- }
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- // calculate ID of this request
- ui32 id = NextRequestId++;
-
- // get reference to request information
- THttpInfoRequest& info = InfoRequests[id];
-
- // fill in sender parameters
- info.Origin = ev->Sender;
- info.SubRequestId = ev->Get()->SubRequestId;
-
- info.ErrorMessage.clear();
-
+ auto it = InfoRequests.begin();
+ while (it != InfoRequests.end()) {
+ auto next = std::next(it);
+
+ THttpInfoRequest& info = it->second;
+ auto actorIt = info.ActorMap.find(ev->Sender);
+ if (actorIt != info.ActorMap.end()) {
+ const bool empty = !actorIt->second.Data;
+ info.ActorMap.erase(actorIt);
+ if (empty && !--info.HttpInfoResPending) {
+ GenerateHttpInfoRes(ctx, it->first);
+ }
+ }
+
+ it = next;
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ // calculate ID of this request
+ ui32 id = NextRequestId++;
+
+ // get reference to request information
+ THttpInfoRequest& info = InfoRequests[id];
+
+ // fill in sender parameters
+ info.Origin = ev->Sender;
+ info.SubRequestId = ev->Get()->SubRequestId;
+
+ info.ErrorMessage.clear();
+
const auto& params = ev->Get()->Request.GetParams();
- if (params.Has("protobuf")) {
- NKikimrBlobStorage::TEvTestLoadRequest record;
- bool status = google::protobuf::TextFormat::ParseFromString(params.Get("protobuf"), &record);
- if (status) {
- try {
- ProcessCmd(record, ctx);
- } catch (const TLoadActorException& ex) {
- info.ErrorMessage = ex.what();
- }
- } else {
- info.ErrorMessage = "bad protobuf";
- }
-
- GenerateHttpInfoRes(ctx, id, true);
- return;
- }
-
- // send messages to subactors
- for (const auto& kv : LoadActors) {
- ctx.Send(kv.second, new NMon::TEvHttpInfo(ev->Get()->Request, id));
- info.ActorMap[kv.second].Tag = kv.first;
- }
-
- // record number of responses pending
- info.HttpInfoResPending = LoadActors.size();
-
- if (!info.HttpInfoResPending) {
- GenerateHttpInfoRes(ctx, id);
- }
- }
-
- void Handle(NMon::TEvHttpInfoRes::TPtr& ev, const TActorContext& ctx) {
- const auto& msg = ev->Get();
- ui32 id = static_cast<NMon::TEvHttpInfoRes *>(msg)->SubRequestId;
-
- auto it = InfoRequests.find(id);
- Y_VERIFY(it != InfoRequests.end());
- THttpInfoRequest& info = it->second;
-
- auto actorIt = info.ActorMap.find(ev->Sender);
- Y_VERIFY(actorIt != info.ActorMap.end());
- TActorInfo& perActorInfo = actorIt->second;
-
- TStringStream stream;
- msg->Output(stream);
- Y_VERIFY(!perActorInfo.Data);
- perActorInfo.Data = stream.Str();
-
- if (!--info.HttpInfoResPending) {
- GenerateHttpInfoRes(ctx, id);
- }
- }
-
- void GenerateHttpInfoRes(const TActorContext& ctx, ui32 id, bool nodata = false) {
- auto it = InfoRequests.find(id);
- Y_VERIFY(it != InfoRequests.end());
- THttpInfoRequest& info = it->second;
-
+ if (params.Has("protobuf")) {
+ NKikimrBlobStorage::TEvTestLoadRequest record;
+ bool status = google::protobuf::TextFormat::ParseFromString(params.Get("protobuf"), &record);
+ if (status) {
+ try {
+ ProcessCmd(record, ctx);
+ } catch (const TLoadActorException& ex) {
+ info.ErrorMessage = ex.what();
+ }
+ } else {
+ info.ErrorMessage = "bad protobuf";
+ }
+
+ GenerateHttpInfoRes(ctx, id, true);
+ return;
+ }
+
+ // send messages to subactors
+ for (const auto& kv : LoadActors) {
+ ctx.Send(kv.second, new NMon::TEvHttpInfo(ev->Get()->Request, id));
+ info.ActorMap[kv.second].Tag = kv.first;
+ }
+
+ // record number of responses pending
+ info.HttpInfoResPending = LoadActors.size();
+
+ if (!info.HttpInfoResPending) {
+ GenerateHttpInfoRes(ctx, id);
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfoRes::TPtr& ev, const TActorContext& ctx) {
+ const auto& msg = ev->Get();
+ ui32 id = static_cast<NMon::TEvHttpInfoRes *>(msg)->SubRequestId;
+
+ auto it = InfoRequests.find(id);
+ Y_VERIFY(it != InfoRequests.end());
+ THttpInfoRequest& info = it->second;
+
+ auto actorIt = info.ActorMap.find(ev->Sender);
+ Y_VERIFY(actorIt != info.ActorMap.end());
+ TActorInfo& perActorInfo = actorIt->second;
+
+ TStringStream stream;
+ msg->Output(stream);
+ Y_VERIFY(!perActorInfo.Data);
+ perActorInfo.Data = stream.Str();
+
+ if (!--info.HttpInfoResPending) {
+ GenerateHttpInfoRes(ctx, id);
+ }
+ }
+
+ void GenerateHttpInfoRes(const TActorContext& ctx, ui32 id, bool nodata = false) {
+ auto it = InfoRequests.find(id);
+ Y_VERIFY(it != InfoRequests.end());
+ THttpInfoRequest& info = it->second;
+
#define PROFILE(NAME) \
str << "<option value=\"" << ui32(NKikimrBlobStorage::TEvTestLoadRequest::NAME) << "\">" << #NAME << "</option>";
#define PUT_HANDLE_CLASS(NAME) \
str << "<option value=\"" << ui32(NKikimrBlobStorage::NAME) << "\">" << #NAME << "</option>";
- TStringStream str;
+ TStringStream str;
HTML(str) {
- if (info.ErrorMessage) {
+ if (info.ErrorMessage) {
DIV() {
- str << "<h1>" << info.ErrorMessage << "</h1>";
+ str << "<h1>" << info.ErrorMessage << "</h1>";
}
- }
-
- if (!nodata) {
- for (const auto& pair : info.ActorMap) {
- const TActorInfo& perActorInfo = pair.second;
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Tag# " << perActorInfo.Tag;
+ }
+
+ if (!nodata) {
+ for (const auto& pair : info.ActorMap) {
+ const TActorInfo& perActorInfo = pair.second;
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Tag# " << perActorInfo.Tag;
}
- DIV_CLASS("panel-body") {
- str << perActorInfo.Data;
+ DIV_CLASS("panel-body") {
+ str << perActorInfo.Data;
}
}
}
@@ -372,24 +372,24 @@ public:
}
}
}
- }
+ }
}
- ctx.Send(info.Origin, new NMon::TEvHttpInfoRes(str.Str(), info.SubRequestId));
-
- InfoRequests.erase(it);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvTestLoadRequest, Handle)
- HFunc(TEvTestLoadFinished, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(NMon::TEvHttpInfoRes, Handle)
- )
-};
-
+ ctx.Send(info.Origin, new NMon::TEvHttpInfoRes(str.Str(), info.SubRequestId));
+
+ InfoRequests.erase(it);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvTestLoadRequest, Handle)
+ HFunc(TEvTestLoadFinished, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(NMon::TEvHttpInfoRes, Handle)
+ )
+};
+
IActor *CreateTestLoadActor(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters) {
return new TLoadActor(counters);
-}
-
-} // NKikimr
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_actor.h b/ydb/core/blobstorage/testload/test_load_actor.h
index 38b7fb3d305..d0dba847351 100644
--- a/ydb/core/blobstorage/testload/test_load_actor.h
+++ b/ydb/core/blobstorage/testload/test_load_actor.h
@@ -1,17 +1,17 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/base/blobstorage.h>
#include <library/cpp/monlib/dynamic_counters/percentile/percentile_lg.h>
#include <cmath>
-
-namespace NKikimr {
+
+namespace NKikimr {
enum {
EvStopTest = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
EvUpdateQuantile,
EvUpdateMonitoring,
};
-
+
struct TEvStopTest : TEventLocal<TEvStopTest, EvStopTest>
{};
constexpr TDuration DelayBeforeMeasurements = TDuration::Seconds(15);
@@ -25,18 +25,18 @@ namespace NKikimr {
{};
- class TLoadActorException : public yexception {
- };
-
+ class TLoadActorException : public yexception {
+ };
+
NActors::IActor *CreateTestLoadActor(const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters);
-
- NActors::IActor *CreateWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TLoadStart& cmd,
+
+ NActors::IActor *CreateWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TLoadStart& cmd,
const NActors::TActorId& parent, TIntrusivePtr<NMonitoring::TDynamicCounters> counters, ui64 tag);
-
- NActors::IActor *CreatePDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLoadStart& cmd,
+
+ NActors::IActor *CreatePDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLoadStart& cmd,
const NActors::TActorId& parent, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
ui64 index, ui64 tag);
-
+
NActors::IActor *CreatePDiskLogWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLogLoadStart& cmd,
const NActors::TActorId& parent, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
ui64 index, ui64 tag);
@@ -45,9 +45,9 @@ namespace NKikimr {
const NActors::TActorId& parent, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
ui64 index, ui64 tag);
- NActors::IActor *CreateVDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
+ NActors::IActor *CreateVDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
const NActors::TActorId& parent, ui64 tag);
-
+
NActors::IActor *CreateKeyValueWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TKeyValueLoadStart& cmd,
const NActors::TActorId& parent, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
ui64 index, ui64 tag);
@@ -112,25 +112,25 @@ namespace NKikimr {
}
};
- struct TEvTestLoadFinished : public TEventLocal<TEvTestLoadFinished, TEvBlobStorage::EvTestLoadFinished> {
- ui64 Tag;
+ struct TEvTestLoadFinished : public TEventLocal<TEvTestLoadFinished, TEvBlobStorage::EvTestLoadFinished> {
+ ui64 Tag;
TIntrusivePtr<TLoadReport> Report; // nullptr indicates error
TString ErrorReason;
-
+
TEvTestLoadFinished(ui64 tag, TIntrusivePtr<TLoadReport> report, TString errorReason)
- : Tag(tag)
+ : Tag(tag)
, Report(report)
, ErrorReason(errorReason)
- {}
- };
-
-#define VERIFY_PARAM2(FIELD, NAME) \
- do { \
- if (!(FIELD).Has##NAME()) { \
- ythrow TLoadActorException() << "missing " << #NAME << " parameter"; \
- } \
- } while (false)
-
-#define VERIFY_PARAM(NAME) VERIFY_PARAM2(cmd, NAME)
-
-} // NKikimr
+ {}
+ };
+
+#define VERIFY_PARAM2(FIELD, NAME) \
+ do { \
+ if (!(FIELD).Has##NAME()) { \
+ ythrow TLoadActorException() << "missing " << #NAME << " parameter"; \
+ } \
+ } while (false)
+
+#define VERIFY_PARAM(NAME) VERIFY_PARAM2(cmd, NAME)
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_gen.h b/ydb/core/blobstorage/testload/test_load_gen.h
index 823ce9daf78..b19548ba75c 100644
--- a/ydb/core/blobstorage/testload/test_load_gen.h
+++ b/ydb/core/blobstorage/testload/test_load_gen.h
@@ -1,40 +1,40 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <ydb/core/base/appdata.h>
-
-namespace NKikimr {
-
- template<typename TItem>
- class TGenerator {
- // generation result type
- using TResult = decltype(std::declval<TItem>().Generate());
-
- // a sef of items; key is the accumulated weight for this item (including the one for the item itself)
+
+namespace NKikimr {
+
+ template<typename TItem>
+ class TGenerator {
+ // generation result type
+ using TResult = decltype(std::declval<TItem>().Generate());
+
+ // a sef of items; key is the accumulated weight for this item (including the one for the item itself)
TMap<double, TItem> Items;
-
- // accumulated weight
- double AccumWeight = 0;
-
- public:
- template<typename T>
- TGenerator(const google::protobuf::RepeatedPtrField<T>& setting) {
- for (const auto& item : setting) {
- Y_VERIFY(item.HasWeight());
- AccumWeight += item.GetWeight();
- Items.emplace(AccumWeight, item);
- }
- }
-
- TResult Generate() const {
+
+ // accumulated weight
+ double AccumWeight = 0;
+
+ public:
+ template<typename T>
+ TGenerator(const google::protobuf::RepeatedPtrField<T>& setting) {
+ for (const auto& item : setting) {
+ Y_VERIFY(item.HasWeight());
+ AccumWeight += item.GetWeight();
+ Items.emplace(AccumWeight, item);
+ }
+ }
+
+ TResult Generate() const {
const double x = AccumWeight * TAppData::RandomProvider->GenRandReal2();
- auto it = Items.lower_bound(x); // min Key >= x
- if (it == Items.end()) {
- return TResult(); // no items in distribution
- }
- const auto& generator = it->second;
- return generator.Generate();
- }
- };
-
-} // NKikimr
+ auto it = Items.lower_bound(x); // min Key >= x
+ if (it == Items.end()) {
+ return TResult(); // no items in distribution
+ }
+ const auto& generator = it->second;
+ return generator.Generate();
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_interval_gen.h b/ydb/core/blobstorage/testload/test_load_interval_gen.h
index 1d5c093db0a..102483371f1 100644
--- a/ydb/core/blobstorage/testload/test_load_interval_gen.h
+++ b/ydb/core/blobstorage/testload/test_load_interval_gen.h
@@ -1,83 +1,83 @@
-#pragma once
-
-#include "defs.h"
-#include "test_load_gen.h"
+#pragma once
+
+#include "defs.h"
+#include "test_load_gen.h"
#include <ydb/core/protos/blobstorage.pb.h>
-#include <util/generic/variant.h>
-
-namespace NKikimr {
- namespace NIntervalGenerator {
-
- // an item for uniform interval distribution
- struct TUniformItem {
- const TDuration Min;
- const TDuration Max;
-
- template<typename TProto>
- TUniformItem(const TProto& x)
- : Min(x.HasMinUs() ? TDuration::MicroSeconds(x.GetMinUs()) : TDuration::MilliSeconds(x.GetMinMs()))
- , Max(x.HasMaxUs() ? TDuration::MicroSeconds(x.GetMaxUs()) : TDuration::MilliSeconds(x.GetMaxMs()))
- {
- const bool a = x.HasMinUs(), b = x.HasMaxUs(), c = x.HasMinMs(), d = x.HasMaxMs();
- Y_VERIFY((a && b && !c && !d) || (!a && !b && c && d));
- }
-
- TDuration Generate() const {
- TDuration range = Max - Min;
+#include <util/generic/variant.h>
+
+namespace NKikimr {
+ namespace NIntervalGenerator {
+
+ // an item for uniform interval distribution
+ struct TUniformItem {
+ const TDuration Min;
+ const TDuration Max;
+
+ template<typename TProto>
+ TUniformItem(const TProto& x)
+ : Min(x.HasMinUs() ? TDuration::MicroSeconds(x.GetMinUs()) : TDuration::MilliSeconds(x.GetMinMs()))
+ , Max(x.HasMaxUs() ? TDuration::MicroSeconds(x.GetMaxUs()) : TDuration::MilliSeconds(x.GetMaxMs()))
+ {
+ const bool a = x.HasMinUs(), b = x.HasMaxUs(), c = x.HasMinMs(), d = x.HasMaxMs();
+ Y_VERIFY((a && b && !c && !d) || (!a && !b && c && d));
+ }
+
+ TDuration Generate() const {
+ TDuration range = Max - Min;
return Min + TDuration::MicroSeconds(TAppData::RandomProvider->GenRand64() % (range.GetValue() + 1));
- }
- };
-
- // an item for Poisson distrubution
- struct TPoissonItem {
- const double Frequency; // in Hz
- const double Xmin;
-
- template<typename TProto>
- TPoissonItem(const TProto& x)
- : Frequency(x.GetFrequency())
- , Xmin(exp(-Frequency * (x.GetMaxIntervalMs() * 1e-3)))
- {
- Y_VERIFY(x.HasFrequency() && x.HasMaxIntervalMs());
- }
-
- TDuration Generate() const {
+ }
+ };
+
+ // an item for Poisson distrubution
+ struct TPoissonItem {
+ const double Frequency; // in Hz
+ const double Xmin;
+
+ template<typename TProto>
+ TPoissonItem(const TProto& x)
+ : Frequency(x.GetFrequency())
+ , Xmin(exp(-Frequency * (x.GetMaxIntervalMs() * 1e-3)))
+ {
+ Y_VERIFY(x.HasFrequency() && x.HasMaxIntervalMs());
+ }
+
+ TDuration Generate() const {
const double x = Max(Xmin, TAppData::RandomProvider->GenRandReal2());
- return TDuration::Seconds(-log(x) / Frequency);
- }
- };
-
+ return TDuration::Seconds(-log(x) / Frequency);
+ }
+ };
+
struct TItem : public std::variant<TUniformItem, TPoissonItem> {
using TBase = std::variant<TUniformItem, TPoissonItem>;
-
- TItem(const NKikimrBlobStorage::TEvTestLoadRequest::TIntervalInfo& x)
+
+ TItem(const NKikimrBlobStorage::TEvTestLoadRequest::TIntervalInfo& x)
: TBase(CreateVariantFromProtobuf(x))
- {}
-
- template<typename TProto>
- static TBase CreateVariantFromProtobuf(const TProto& proto) {
- switch (proto.Distribution_case()) {
- case TProto::kUniform:
- return TUniformItem(proto.GetUniform());
-
- case TProto::kPoisson:
- return TPoissonItem(proto.GetPoisson());
-
- case TProto::DISTRIBUTION_NOT_SET:
- Y_FAIL("TIntervalInfo.Distribution not set");
- }
-
- Y_FAIL("unreachable code");
- }
-
- TDuration Generate() const {
- auto f = [](const auto& item) { return item.Generate(); };
+ {}
+
+ template<typename TProto>
+ static TBase CreateVariantFromProtobuf(const TProto& proto) {
+ switch (proto.Distribution_case()) {
+ case TProto::kUniform:
+ return TUniformItem(proto.GetUniform());
+
+ case TProto::kPoisson:
+ return TPoissonItem(proto.GetPoisson());
+
+ case TProto::DISTRIBUTION_NOT_SET:
+ Y_FAIL("TIntervalInfo.Distribution not set");
+ }
+
+ Y_FAIL("unreachable code");
+ }
+
+ TDuration Generate() const {
+ auto f = [](const auto& item) { return item.Generate(); };
return std::visit(f, *this);
- }
- };
-
- } // NIntervalGenerator
-
- using TIntervalGenerator = TGenerator<NIntervalGenerator::TItem>;
-
-} // NKikimr
+ }
+ };
+
+ } // NIntervalGenerator
+
+ using TIntervalGenerator = TGenerator<NIntervalGenerator::TItem>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_keyvalue_write.cpp b/ydb/core/blobstorage/testload/test_load_keyvalue_write.cpp
index 00e31ff18d2..0b0d8b85ae4 100644
--- a/ydb/core/blobstorage/testload/test_load_keyvalue_write.cpp
+++ b/ydb/core/blobstorage/testload/test_load_keyvalue_write.cpp
@@ -58,15 +58,15 @@ public:
LoopAtKeyCount = cmd.GetLoopAtKeyCount();
}
- std::unique_ptr<TEvKeyValue::TEvRequest> TrySend() {
+ std::unique_ptr<TEvKeyValue::TEvRequest> TrySend() {
if (IsDying) {
return {};
}
- std::unique_ptr<TEvKeyValue::TEvRequest> ev;
+ std::unique_ptr<TEvKeyValue::TEvRequest> ev;
if (ItemsInFlight < MaxInFlight) {
- ev = std::make_unique<TEvKeyValue::TEvRequest>();
+ ev = std::make_unique<TEvKeyValue::TEvRequest>();
auto write = ev->Record.AddCmdWrite();
write->SetKey(Sprintf("%s%08" PRIu64,
KeyPrefix.c_str(),
@@ -109,7 +109,7 @@ class TKeyValueWriterTestLoadActor : public TActorBootstrapped<TKeyValueWriterTe
ui64 Size;
};
- TVector<std::unique_ptr<TWorker>> Workers;
+ TVector<std::unique_ptr<TWorker>> Workers;
ui64 WrittenBytes = 0;
@@ -149,7 +149,7 @@ public:
ui32 idx = 0;
for (const auto& workerCmd : cmd.GetWorkers()) {
- Workers.push_back(std::make_unique<TWorker>(workerCmd, idx, &Rng));
+ Workers.push_back(std::make_unique<TWorker>(workerCmd, idx, &Rng));
++idx;
}
@@ -246,13 +246,13 @@ public:
ui64 sent = 0;
for (auto& worker : Workers) {
auto now = TAppData::TimeProvider->Now();
- while (std::unique_ptr<TEvKeyValue::TEvRequest> ev = worker->TrySend()) {
+ while (std::unique_ptr<TEvKeyValue::TEvRequest> ev = worker->TrySend()) {
ui64 size = ev->Record.GetCmdWrite(0).GetValue().size();
*KeyValueBytesWritten += size;
ev->Record.SetCookie(ReqIdx);
InFlightWrites.insert({ReqIdx, {worker->Idx, now, size}});
++ReqIdx;
- NTabletPipe::SendData(ctx, Pipe, ev.release());
+ NTabletPipe::SendData(ctx, Pipe, ev.release());
++sent;
}
}
diff --git a/ydb/core/blobstorage/testload/test_load_kqp.cpp b/ydb/core/blobstorage/testload/test_load_kqp.cpp
index fec4fd7b2c0..9c52ef77e58 100644
--- a/ydb/core/blobstorage/testload/test_load_kqp.cpp
+++ b/ydb/core/blobstorage/testload/test_load_kqp.cpp
@@ -170,9 +170,9 @@ public:
LOG_DEBUG_S(ctx, NKikimrServices::KQP_LOAD_TEST, "Tag# " << Tag
<< " TKqpWriterTestLoadActor StartDeathProcess called");
for(const auto& session : Sessions) {
- auto request = std::make_unique<NKqp::TEvKqp::TEvCloseSessionRequest>();
+ auto request = std::make_unique<NKqp::TEvKqp::TEvCloseSessionRequest>();
request->Record.MutableRequest()->SetSessionId(session);
- ctx.Send( new IEventHandle(NKqp::MakeKqpProxyID(1), SelfId(), request.release(),
+ ctx.Send( new IEventHandle(NKqp::MakeKqpProxyID(1), SelfId(), request.release(),
0, /* via actor system */ true));
}
diff --git a/ydb/core/blobstorage/testload/test_load_pdisk_log.cpp b/ydb/core/blobstorage/testload/test_load_pdisk_log.cpp
index 33fc363c935..d063f6c8614 100644
--- a/ydb/core/blobstorage/testload/test_load_pdisk_log.cpp
+++ b/ydb/core/blobstorage/testload/test_load_pdisk_log.cpp
@@ -104,12 +104,12 @@ public:
StorageDuration = cmd.GetStorageDuration();
}
- std::unique_ptr<NPDisk::TEvYardInit> GetYardInit(ui64 pDiskGuid) const {
- return std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, pDiskGuid);
+ std::unique_ptr<NPDisk::TEvYardInit> GetYardInit(ui64 pDiskGuid) const {
+ return std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, pDiskGuid);
}
- std::unique_ptr<NPDisk::TEvLog> TrySend(const ui64 globalWrittenBytes) {
+ std::unique_ptr<NPDisk::TEvLog> TrySend(const ui64 globalWrittenBytes) {
if (IsDying || IsHarakiriSent) {
return {};
}
@@ -119,7 +119,7 @@ public:
++BurstIdx;
}
- std::unique_ptr<NPDisk::TEvLog> ev;
+ std::unique_ptr<NPDisk::TEvLog> ev;
if (BurstWrittenBytes + BytesInFlight < BurstSize
&& BurstInterval * BurstIdx <= globalWrittenBytes
@@ -136,10 +136,10 @@ public:
CutLogLsn = *NextCutLogLsn;
CutLogBytesWritten = NextCutLogBytesWritten;
- ev = std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, OwnerRound, TLogSignature(),
+ ev = std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, OwnerRound, TLogSignature(),
record, DataBuffer, seg, nullptr);
} else {
- ev = std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, OwnerRound, TLogSignature(),
+ ev = std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, OwnerRound, TLogSignature(),
DataBuffer, seg, nullptr);
}
BytesInFlight += DataBuffer.Size();
@@ -178,17 +178,17 @@ public:
return false;
}
- std::unique_ptr<NPDisk::TEvHarakiri> GetHarakiri() {
+ std::unique_ptr<NPDisk::TEvHarakiri> GetHarakiri() {
Y_VERIFY(IsDying);
Y_VERIFY(LogReadPosition == NPDisk::TLogPosition::Invalid());
- return std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, OwnerRound);
+ return std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, OwnerRound);
}
- std::unique_ptr<NPDisk::TEvReadLog> GetLogRead() {
+ std::unique_ptr<NPDisk::TEvReadLog> GetLogRead() {
if (LogReadPosition == NPDisk::TLogPosition::Invalid()) {
return {};
} else {
- return std::make_unique<NPDisk::TEvReadLog>(PDiskParams->Owner, OwnerRound, LogReadPosition);
+ return std::make_unique<NPDisk::TEvReadLog>(PDiskParams->Owner, OwnerRound, LogReadPosition);
}
}
@@ -273,7 +273,7 @@ class TPDiskLogWriterTestLoadActor : public TActorBootstrapped<TPDiskLogWriterTe
ui64 Size;
};
- TVector<std::unique_ptr<TWorker>> Workers;
+ TVector<std::unique_ptr<TWorker>> Workers;
ui64 WrittenBytes = 0;
@@ -324,7 +324,7 @@ public:
ui32 idx = 0;
for (const auto& workerCmd : cmd.GetWorkers()) {
- Workers.push_back(std::make_unique<TWorker>(workerCmd, idx, &Rng));
+ Workers.push_back(std::make_unique<TWorker>(workerCmd, idx, &Rng));
if (IsWardenlessTest) {
Workers.back()->OwnerRound = 1000 + index + idx;
}
@@ -563,10 +563,10 @@ public:
<< " GetReallyWrittenBytes()# " << worker->GetReallyWrittenBytes()
<< " GetGlobalWrittenBytes()# " << worker->GetGlobalWrittenBytes());
}
- auto report = std::make_unique<TLoadReport>();
+ auto report = std::make_unique<TLoadReport>();
report->LoadType = TLoadReport::LOAD_LOG_WRITE;
report->Duration = TAppData::TimeProvider->Now() - TestStartTime;
- ctx.Send(Parent, new TEvTestLoadFinished(Tag, report.release(), "OK"));
+ ctx.Send(Parent, new TEvTestLoadFinished(Tag, report.release(), "OK"));
LOG_INFO_S(ctx, NKikimrServices::BS_LOAD_TEST, "Tag# " << Tag << " End of work, TEvTestLoadFinished is sent");
Die(ctx);
}
@@ -591,7 +591,7 @@ public:
LOG_TRACE_S(ctx, NKikimrServices::BS_LOAD_TEST, "Tag# " << Tag << " SendWriteRequests");
for (auto& worker : Workers) {
auto now = TAppData::TimeProvider->Now();
- while (std::unique_ptr<NPDisk::TEvLog> ev = worker->TrySend(WrittenBytes)) {
+ while (std::unique_ptr<NPDisk::TEvLog> ev = worker->TrySend(WrittenBytes)) {
*LogBytesWritten += ev->Data.size();
ev->Cookie = reinterpret_cast<void*>(ReqIdx);
InFlightLogWrites.insert({ReqIdx, {worker->Idx, now, ev->Data.size()}});
@@ -633,8 +633,8 @@ public:
}
template<typename TRequest>
- void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
- ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
+ void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
+ ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
}
void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
diff --git a/ydb/core/blobstorage/testload/test_load_pdisk_read.cpp b/ydb/core/blobstorage/testload/test_load_pdisk_read.cpp
index 3b446a74c2d..8fe63cede29 100644
--- a/ydb/core/blobstorage/testload/test_load_pdisk_read.cpp
+++ b/ydb/core/blobstorage/testload/test_load_pdisk_read.cpp
@@ -118,7 +118,7 @@ class TPDiskReaderTestLoadActor : public TActorBootstrapped<TPDiskReaderTestLoad
TString ErrorReason;
public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_LOAD_PDISK_READ;
+ return NKikimrServices::TActivity::BS_LOAD_PDISK_READ;
}
TPDiskReaderTestLoadActor(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskReadLoadStart& cmd, const TActorId& parent,
@@ -202,7 +202,7 @@ public:
AppData(ctx)->Icb->RegisterLocalControl(MaxInFlight, Sprintf("PDiskReadLoadActor_MaxInFlight_%4" PRIu64, Tag).c_str());
if (IsWardenlessTest) {
ErrorReason = "Still waiting for YardInitResult";
- SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
+ SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
} else {
Send(MakeBlobStorageNodeWardenID(ctx.SelfID.NodeId()), new TEvRegisterPDiskLoadActor());
}
@@ -211,7 +211,7 @@ public:
void Handle(TEvRegisterPDiskLoadActorResult::TPtr& ev, const TActorContext& ctx) {
OwnerRound = ev->Get()->OwnerRound;
ErrorReason = "Still waiting for YardInitResult";
- SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
+ SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
}
void Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx) {
@@ -221,7 +221,7 @@ public:
str << "yard init failed, Status# " << NKikimrProto::EReplyStatus_Name(msg->Status);
ErrorReason = str.Str();
LOG_INFO(ctx, NKikimrServices::BS_LOAD_TEST, "%s", str.Str().c_str());
- SendRequest(ctx, std::make_unique<TEvents::TEvPoisonPill>());
+ SendRequest(ctx, std::make_unique<TEvents::TEvPoisonPill>());
return;
}
ErrorReason = "OK";
@@ -242,7 +242,7 @@ public:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void StartAllReservations(const TActorContext& ctx) {
- SendRequest(ctx, std::make_unique<NPDisk::TEvChunkReserve>(PDiskParams->Owner,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvChunkReserve>(PDiskParams->Owner,
PDiskParams->OwnerRound, (ui32)Chunks.size()));
++ChunkReserve_RequestsSent;
}
@@ -262,7 +262,7 @@ public:
Chunks[i].Idx = chunkIdx;
ui64 requestIdx = NewTRequestInfo((ui32)DataBuffer.size(), chunkIdx, TAppData::TimeProvider->Now());
TString tmp = DataBuffer;
- SendRequest(ctx, std::make_unique<NPDisk::TEvChunkWrite>(PDiskParams->Owner, PDiskParams->OwnerRound,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvChunkWrite>(PDiskParams->Owner, PDiskParams->OwnerRound,
chunkIdx, 0u, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(tmp),
reinterpret_cast<void*>(requestIdx), true, NPriWrite::HullHugeAsyncBlob, Sequential));
++ChunkWrite_RequestsSent;
@@ -284,7 +284,7 @@ public:
<< NKikimrProto::EReplyStatus_Name(msg->Status);
ErrorReason = str.Str();
LOG_INFO(ctx, NKikimrServices::BS_LOAD_TEST, "%s", str.Str().c_str());
- SendRequest(ctx, std::make_unique<TEvents::TEvPoisonPill>());
+ SendRequest(ctx, std::make_unique<TEvents::TEvPoisonPill>());
}
if (ChunkWrite_OK == Chunks.size()) {
TestStartTime = TAppData::TimeProvider->Now();
@@ -317,7 +317,7 @@ public:
void CheckDie(const TActorContext& ctx) {
if (!MaxInFlight && !InFlight && !LogInFlight && !Harakiri) {
if (PDiskParams) {
- SendRequest(ctx, std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, PDiskParams->OwnerRound));
+ SendRequest(ctx, std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, PDiskParams->OwnerRound));
Harakiri = true;
} else {
ctx.Send(Parent, new TEvTestLoadFinished(Tag, nullptr, ErrorReason));
@@ -409,7 +409,7 @@ public:
Report->Size = size;
ui32 offset = SlotIndex * size;
ui64 requestIdx = NewTRequestInfo(size, chunkIdx, TAppData::TimeProvider->Now());
- SendRequest(ctx, std::make_unique<NPDisk::TEvChunkRead>(PDiskParams->Owner, PDiskParams->OwnerRound,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvChunkRead>(PDiskParams->Owner, PDiskParams->OwnerRound,
chunkIdx, offset, size, ui8(0), reinterpret_cast<void*>(requestIdx)));
++ChunkRead_RequestsSent;
@@ -440,7 +440,7 @@ public:
record.CommitChunks.push_back(chunkIdx);
TLsnSeg seg(Lsn, Lsn);
++Lsn;
- SendRequest(ctx, std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, PDiskParams->OwnerRound,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, PDiskParams->OwnerRound,
TLogSignature::SignatureHugeLogoBlob, record, logRecord, seg,
reinterpret_cast<void*>(requestIdx)));
++LogInFlight;
@@ -486,8 +486,8 @@ public:
}
template<typename TRequest>
- void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
- ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
+ void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
+ ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
}
void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
diff --git a/ydb/core/blobstorage/testload/test_load_pdisk_write.cpp b/ydb/core/blobstorage/testload/test_load_pdisk_write.cpp
index 8ea16e014cb..7cdbb449cd0 100644
--- a/ydb/core/blobstorage/testload/test_load_pdisk_write.cpp
+++ b/ydb/core/blobstorage/testload/test_load_pdisk_write.cpp
@@ -1,55 +1,55 @@
#include <util/random/shuffle.h>
-#include "test_load_actor.h"
+#include "test_load_actor.h"
#include <ydb/core/base/counters.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <library/cpp/monlib/service/pages/templates.h>
-#include <util/random/fast.h>
-#include <util/generic/queue.h>
-
-namespace NKikimr {
-
-class TPDiskWriterTestLoadActor : public TActorBootstrapped<TPDiskWriterTestLoadActor> {
- struct TChunkInfo {
+#include <util/random/fast.h>
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+
+class TPDiskWriterTestLoadActor : public TActorBootstrapped<TPDiskWriterTestLoadActor> {
+ struct TChunkInfo {
TDeque<std::pair<TChunkIdx, ui32>> WriteQueue;
- ui32 NumSlots;
- ui32 SlotSizeBlocks;
- ui32 Weight;
- ui64 AccumWeight;
-
- struct TFindByWeight {
- bool operator ()(ui64 left, const TChunkInfo& right) const {
- return left < right.AccumWeight;
- }
- };
- };
-
+ ui32 NumSlots;
+ ui32 SlotSizeBlocks;
+ ui32 Weight;
+ ui64 AccumWeight;
+
+ struct TFindByWeight {
+ bool operator ()(ui64 left, const TChunkInfo& right) const {
+ return left < right.AccumWeight;
+ }
+ };
+ };
+
struct TParts : public NPDisk::TEvChunkWrite::IParts {
- const void *Buffer;
- ui32 Len;
-
- TParts(const void *buffer, ui32 len)
- : Buffer(buffer)
- , Len(len)
- {}
-
- TDataRef operator [](ui32 index) const override {
- Y_VERIFY(index == 0);
- return std::make_pair(Buffer, Len);
- }
-
- ui32 Size() const override {
- return 1;
- }
- };
-
- struct TRequestInfo {
- ui32 Size;
- TChunkIdx ChunkIdx;
- TInstant StartTime;
+ const void *Buffer;
+ ui32 Len;
+
+ TParts(const void *buffer, ui32 len)
+ : Buffer(buffer)
+ , Len(len)
+ {}
+
+ TDataRef operator [](ui32 index) const override {
+ Y_VERIFY(index == 0);
+ return std::make_pair(Buffer, Len);
+ }
+
+ ui32 Size() const override {
+ return 1;
+ }
+ };
+
+ struct TRequestInfo {
+ ui32 Size;
+ TChunkIdx ChunkIdx;
+ TInstant StartTime;
TInstant LogStartTime;
- bool DataWritten;
- bool LogWritten;
+ bool DataWritten;
+ bool LogWritten;
TRequestInfo(ui32 size, TChunkIdx chunkIdx, TInstant startTime, TInstant logStartTime, bool dataWritten,
bool logWritten)
@@ -64,57 +64,57 @@ class TPDiskWriterTestLoadActor : public TActorBootstrapped<TPDiskWriterTestLoad
TRequestInfo(const TRequestInfo &) = default;
TRequestInfo() = default;
- };
-
- struct TRequestStat {
- ui64 BytesWrittenTotal;
- ui32 Size;
- TDuration Latency;
- };
-
+ };
+
+ struct TRequestStat {
+ ui64 BytesWrittenTotal;
+ ui32 Size;
+ TDuration Latency;
+ };
+
THashMap<ui64, TRequestInfo> RequestInfo;
ui64 NextRequestIdx = 0;
const TActorId Parent;
- ui64 Tag;
- ui32 DurationSeconds;
+ ui64 Tag;
+ ui32 DurationSeconds;
ui32 IntervalMsMin = 0;
ui32 IntervalMsMax = 0;
TControlWrapper MaxInFlight;
- ui32 InFlight = 0;
+ ui32 InFlight = 0;
ui32 LogInFlight = 0;
TInstant LastRequest;
ui32 IntervalMs = 0;
- ui32 PDiskId;
- TVDiskID VDiskId;
+ ui32 PDiskId;
+ TVDiskID VDiskId;
NPDisk::TOwnerRound OwnerRound;
- ui64 PDiskGuid;
- TIntrusivePtr<TPDiskParams> PDiskParams;
+ ui64 PDiskGuid;
+ TIntrusivePtr<TPDiskParams> PDiskParams;
TVector<TChunkInfo> Chunks;
- TReallyFastRng32 Rng;
- TBuffer DataBuffer;
- ui64 Lsn = 1;
- TChunkInfo *ReservePending = nullptr;
- NKikimrBlobStorage::TEvTestLoadRequest::ELogMode LogMode;
+ TReallyFastRng32 Rng;
+ TBuffer DataBuffer;
+ ui64 Lsn = 1;
+ TChunkInfo *ReservePending = nullptr;
+ NKikimrBlobStorage::TEvTestLoadRequest::ELogMode LogMode;
THashMap<TChunkIdx, ui32> ChunkUsageCount;
TQueue<TChunkIdx> AllocationQueue;
TMultiMap<TInstant, TRequestStat> TimeSeries;
TVector<TChunkIdx> DeleteChunks;
- bool Sequential;
- bool Reuse;
+ bool Sequential;
+ bool Reuse;
bool IsWardenlessTest;
- bool Harakiri = false;
-
+ bool Harakiri = false;
+
TInstant TestStartTime;
TInstant MeasurementStartTime;
- // statistics
- ui64 ChunkWrite_RequestsSent = 0;
- ui64 ChunkWrite_OK = 0;
- ui64 ChunkWrite_NonOK = 0;
- ui64 ChunkReserve_RequestsSent = 0;
- ui64 DeletedChunksCount = 0;
-
+ // statistics
+ ui64 ChunkWrite_RequestsSent = 0;
+ ui64 ChunkWrite_OK = 0;
+ ui64 ChunkWrite_NonOK = 0;
+ ui64 ChunkReserve_RequestsSent = 0;
+ ui64 DeletedChunksCount = 0;
+
// Monitoring
TIntrusivePtr<NMonitoring::TDynamicCounters> LoadCounters;
NMonitoring::TDynamicCounters::TCounterPtr BytesWritten;
@@ -126,62 +126,62 @@ class TPDiskWriterTestLoadActor : public TActorBootstrapped<TPDiskWriterTestLoad
TIntrusivePtr<NMonitoring::TCounterForPtr> PDiskBytesWritten;
TMap<double, TIntrusivePtr<NMonitoring::TCounterForPtr>> DevicePercentiles;
-public:
+public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_LOAD_PDISK_WRITE;
- }
-
+ return NKikimrServices::TActivity::BS_LOAD_PDISK_WRITE;
+ }
+
TPDiskWriterTestLoadActor(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLoadStart& cmd, const TActorId& parent,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, ui64 index, ui64 tag)
- : Parent(parent)
+ : Parent(parent)
, Tag(tag)
, MaxInFlight(4, 0, 65536)
, OwnerRound(1000 + index)
- , Rng(Now().GetValue())
+ , Rng(Now().GetValue())
, Report(new TLoadReport())
- {
-
- VERIFY_PARAM(DurationSeconds);
- DurationSeconds = cmd.GetDurationSeconds();
+ {
+
+ VERIFY_PARAM(DurationSeconds);
+ DurationSeconds = cmd.GetDurationSeconds();
Y_ASSERT(DurationSeconds > DelayBeforeMeasurements.Seconds());
Report->Duration = TDuration::Seconds(DurationSeconds);
-
+
IntervalMsMin = cmd.GetIntervalMsMin();
IntervalMsMax = cmd.GetIntervalMsMax();
- VERIFY_PARAM(InFlightWrites);
- MaxInFlight = cmd.GetInFlightWrites();
+ VERIFY_PARAM(InFlightWrites);
+ MaxInFlight = cmd.GetInFlightWrites();
Report->InFlight = MaxInFlight;
-
- VERIFY_PARAM(PDiskId);
- PDiskId = cmd.GetPDiskId();
-
- VERIFY_PARAM(PDiskGuid);
- PDiskGuid = cmd.GetPDiskGuid();
-
- VERIFY_PARAM(VDiskId);
- VDiskId = VDiskIDFromVDiskID(cmd.GetVDiskId());
-
- VERIFY_PARAM(LogMode);
- LogMode = cmd.GetLogMode();
-
- Sequential = cmd.GetSequential();
- Reuse = cmd.GetReuse();
+
+ VERIFY_PARAM(PDiskId);
+ PDiskId = cmd.GetPDiskId();
+
+ VERIFY_PARAM(PDiskGuid);
+ PDiskGuid = cmd.GetPDiskGuid();
+
+ VERIFY_PARAM(VDiskId);
+ VDiskId = VDiskIDFromVDiskID(cmd.GetVDiskId());
+
+ VERIFY_PARAM(LogMode);
+ LogMode = cmd.GetLogMode();
+
+ Sequential = cmd.GetSequential();
+ Reuse = cmd.GetReuse();
IsWardenlessTest = cmd.GetIsWardenlessTest();
-
- for (const auto& chunk : cmd.GetChunks()) {
- if (!chunk.HasSlots() || !chunk.HasWeight() || !chunk.GetSlots() || !chunk.GetWeight()) {
- ythrow TLoadActorException() << "chunk.Slots/Weight fields are either missing or zero";
- }
- Chunks.push_back(TChunkInfo{
- {},
- chunk.GetSlots(),
- 0,
- chunk.GetWeight(),
- 0,
- });
- }
-
+
+ for (const auto& chunk : cmd.GetChunks()) {
+ if (!chunk.HasSlots() || !chunk.HasWeight() || !chunk.GetSlots() || !chunk.GetWeight()) {
+ ythrow TLoadActorException() << "chunk.Slots/Weight fields are either missing or zero";
+ }
+ Chunks.push_back(TChunkInfo{
+ {},
+ chunk.GetSlots(),
+ 0,
+ chunk.GetWeight(),
+ 0,
+ });
+ }
+
// Monitoring initialization
LoadCounters = counters->GetSubgroup("tag", Sprintf("%" PRIu64, tag))->
GetSubgroup("pdisk", Sprintf("%09" PRIu32, PDiskId));
@@ -202,22 +202,22 @@ public:
}
- if (Chunks.empty()) {
- ythrow TLoadActorException() << "Chunks may not be empty";
- }
- }
-
+ if (Chunks.empty()) {
+ ythrow TLoadActorException() << "Chunks may not be empty";
+ }
+ }
+
~TPDiskWriterTestLoadActor() {
LoadCounters->ResetCounters();
}
- void Bootstrap(const TActorContext& ctx) {
- Become(&TPDiskWriterTestLoadActor::StateFunc);
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TPDiskWriterTestLoadActor::StateFunc);
ctx.Schedule(TDuration::Seconds(DurationSeconds), new TEvents::TEvPoisonPill);
ctx.Schedule(TDuration::MilliSeconds(MonitoringUpdateCycleMs), new TEvUpdateMonitoring);
AppData(ctx)->Icb->RegisterLocalControl(MaxInFlight, Sprintf("PDiskWriteLoadActor_MaxInFlight_%4" PRIu64, Tag).c_str());
if (IsWardenlessTest) {
- SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
+ SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
} else {
Send(MakeBlobStorageNodeWardenID(ctx.SelfID.NodeId()), new TEvRegisterPDiskLoadActor());
}
@@ -225,11 +225,11 @@ public:
void Handle(TEvRegisterPDiskLoadActorResult::TPtr& ev, const TActorContext& ctx) {
OwnerRound = ev->Get()->OwnerRound;
- SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
- }
-
+ SendRequest(ctx, std::make_unique<NPDisk::TEvYardInit>(OwnerRound, VDiskId, PDiskGuid));
+ }
+
void Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx) {
- auto msg = ev->Get();
+ auto msg = ev->Get();
if (msg->Status != NKikimrProto::OK) {
TStringStream str;
str << "yard init failed, Status# " << NKikimrProto::EReplyStatus_Name(msg->Status);
@@ -238,24 +238,24 @@ public:
Die(ctx);
return;
}
- PDiskParams = msg->PDiskParams;
- DataBuffer.Resize(PDiskParams->ChunkSize);
+ PDiskParams = msg->PDiskParams;
+ DataBuffer.Resize(PDiskParams->ChunkSize);
char *data = DataBuffer.data();
- for (ui32 i = 0; i < PDiskParams->ChunkSize; ++i) {
- data[i] = Rng();
- }
- for (TChunkInfo& chunk : Chunks) {
- chunk.SlotSizeBlocks = PDiskParams->ChunkSize / PDiskParams->AppendBlockSize / chunk.NumSlots;
- }
+ for (ui32 i = 0; i < PDiskParams->ChunkSize; ++i) {
+ data[i] = Rng();
+ }
+ for (TChunkInfo& chunk : Chunks) {
+ chunk.SlotSizeBlocks = PDiskParams->ChunkSize / PDiskParams->AppendBlockSize / chunk.NumSlots;
+ }
TestStartTime = TAppData::TimeProvider->Now();
MeasurementStartTime = TestStartTime + DelayBeforeMeasurements;
- CheckForReserve(ctx);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Chunk reservation
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ CheckForReserve(ctx);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Chunk reservation
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
ui64 NewTRequestInfo(ui32 size, TChunkIdx chunkIdx, TInstant startTime, TInstant logStartTime, bool dataWritten,
bool logWritten) {
ui64 requestIdx = NextRequestIdx;
@@ -264,53 +264,53 @@ public:
return requestIdx;
}
- void CheckForReserve(const TActorContext& ctx) {
- if (!ReservePending && MaxInFlight) {
- for (TChunkInfo& chunkInfo : Chunks) {
- if (chunkInfo.WriteQueue.size() <= chunkInfo.NumSlots * 2 / 3) {
- if (AllocationQueue) {
- TChunkIdx chunkIdx = AllocationQueue.front();
- AllocationQueue.pop();
- ApplyNewChunk(chunkIdx, chunkInfo);
- } else {
- SendRequest(ctx, std::make_unique<NPDisk::TEvChunkReserve>(PDiskParams->Owner,
+ void CheckForReserve(const TActorContext& ctx) {
+ if (!ReservePending && MaxInFlight) {
+ for (TChunkInfo& chunkInfo : Chunks) {
+ if (chunkInfo.WriteQueue.size() <= chunkInfo.NumSlots * 2 / 3) {
+ if (AllocationQueue) {
+ TChunkIdx chunkIdx = AllocationQueue.front();
+ AllocationQueue.pop();
+ ApplyNewChunk(chunkIdx, chunkInfo);
+ } else {
+ SendRequest(ctx, std::make_unique<NPDisk::TEvChunkReserve>(PDiskParams->Owner,
PDiskParams->OwnerRound, 1U));
- ReservePending = &chunkInfo;
- ++ChunkReserve_RequestsSent;
- }
- break;
- }
- }
- }
- }
-
+ ReservePending = &chunkInfo;
+ ++ChunkReserve_RequestsSent;
+ }
+ break;
+ }
+ }
+ }
+ }
+
void Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
- auto msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- TChunkInfo& chunkInfo = *ReservePending;
- ReservePending = nullptr;
- for (TChunkIdx chunkIdx : msg->ChunkIds) {
- ApplyNewChunk(chunkIdx, chunkInfo);
- }
- CheckForReserve(ctx);
- SendWriteRequests(ctx);
- }
-
- void ApplyNewChunk(TChunkIdx chunkIdx, TChunkInfo& chunkInfo) {
- std::vector<ui32> slots;
- for (ui32 i = 0; i < chunkInfo.NumSlots; ++i) {
- slots.push_back(i);
- }
- if (!Sequential) {
+ auto msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ TChunkInfo& chunkInfo = *ReservePending;
+ ReservePending = nullptr;
+ for (TChunkIdx chunkIdx : msg->ChunkIds) {
+ ApplyNewChunk(chunkIdx, chunkInfo);
+ }
+ CheckForReserve(ctx);
+ SendWriteRequests(ctx);
+ }
+
+ void ApplyNewChunk(TChunkIdx chunkIdx, TChunkInfo& chunkInfo) {
+ std::vector<ui32> slots;
+ for (ui32 i = 0; i < chunkInfo.NumSlots; ++i) {
+ slots.push_back(i);
+ }
+ if (!Sequential) {
Shuffle(slots.begin(), slots.end());
- }
- for (ui32 slot : slots) {
- chunkInfo.WriteQueue.emplace_back(chunkIdx, slot);
- }
- ChunkUsageCount[chunkIdx] = chunkInfo.NumSlots;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ }
+ for (ui32 slot : slots) {
+ chunkInfo.WriteQueue.emplace_back(chunkIdx, slot);
+ }
+ ChunkUsageCount[chunkIdx] = chunkInfo.NumSlots;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rate management
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -319,33 +319,33 @@ public:
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Death management
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ // Death management
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
void HandlePoisonPill(const TActorContext& ctx) {
Report->LoadType = TLoadReport::LOAD_WRITE;
- MaxInFlight = 0;
- CheckDie(ctx);
- }
-
- void CheckDie(const TActorContext& ctx) {
+ MaxInFlight = 0;
+ CheckDie(ctx);
+ }
+
+ void CheckDie(const TActorContext& ctx) {
if (!MaxInFlight && !InFlight && !LogInFlight && !Harakiri) {
if (PDiskParams) {
- SendRequest(ctx, std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, PDiskParams->OwnerRound));
+ SendRequest(ctx, std::make_unique<NPDisk::TEvHarakiri>(PDiskParams->Owner, PDiskParams->OwnerRound));
Harakiri = true;
} else {
ctx.Send(Parent, new TEvTestLoadFinished(Tag, Report, "OK, but can't send TEvHarakiri to PDisk"));
Die(ctx);
}
- }
- }
-
+ }
+ }
+
void Handle(NPDisk::TEvHarakiriResult::TPtr& /*ev*/, const TActorContext& ctx) {
ctx.Send(Parent, new TEvTestLoadFinished(Tag, Report, "OK"));
- Die(ctx);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ Die(ctx);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Monitoring
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -372,11 +372,11 @@ public:
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Chunk writing
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void SendWriteRequests(const TActorContext& ctx) {
- while (InFlight < MaxInFlight) {
+ // Chunk writing
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void SendWriteRequests(const TActorContext& ctx) {
+ while (InFlight < MaxInFlight) {
// Randomize interval (if required)
if (!IntervalMs && IntervalMsMax && IntervalMsMin) {
IntervalMs = IntervalMsMin;
@@ -399,117 +399,117 @@ public:
}
// Prepare to send request
- ui64 accumWeight = 0;
- for (TChunkInfo& chunkInfo : Chunks) {
- chunkInfo.AccumWeight = accumWeight;
- if (!chunkInfo.WriteQueue.empty()) {
- accumWeight += chunkInfo.Weight;
- }
- }
- if (!accumWeight) {
- break;
- }
-
- ui64 w = (ui64(Rng()) << 32 | Rng()) % accumWeight;
- auto it = std::prev(std::upper_bound(Chunks.begin(), Chunks.end(), w, TChunkInfo::TFindByWeight()));
- TChunkInfo& chunkInfo = *it;
-
- Y_VERIFY(!chunkInfo.WriteQueue.empty());
-
- auto& front = chunkInfo.WriteQueue.front();
- TChunkIdx chunkIdx = front.first;
- ui32 slotIndex = front.second;
- chunkInfo.WriteQueue.pop_front();
-
- ui32 size = chunkInfo.SlotSizeBlocks * PDiskParams->AppendBlockSize;
+ ui64 accumWeight = 0;
+ for (TChunkInfo& chunkInfo : Chunks) {
+ chunkInfo.AccumWeight = accumWeight;
+ if (!chunkInfo.WriteQueue.empty()) {
+ accumWeight += chunkInfo.Weight;
+ }
+ }
+ if (!accumWeight) {
+ break;
+ }
+
+ ui64 w = (ui64(Rng()) << 32 | Rng()) % accumWeight;
+ auto it = std::prev(std::upper_bound(Chunks.begin(), Chunks.end(), w, TChunkInfo::TFindByWeight()));
+ TChunkInfo& chunkInfo = *it;
+
+ Y_VERIFY(!chunkInfo.WriteQueue.empty());
+
+ auto& front = chunkInfo.WriteQueue.front();
+ TChunkIdx chunkIdx = front.first;
+ ui32 slotIndex = front.second;
+ chunkInfo.WriteQueue.pop_front();
+
+ ui32 size = chunkInfo.SlotSizeBlocks * PDiskParams->AppendBlockSize;
Report->Size = size;
- ui32 offset = slotIndex * size;
+ ui32 offset = slotIndex * size;
const TInstant now = TAppData::TimeProvider->Now();
// like the parallel mode, but log is treated already written
bool isLogWritten = (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_NONE);
ui64 requestIdx = NewTRequestInfo(size, chunkIdx, now, now, false, isLogWritten);
- SendRequest(ctx, std::make_unique<NPDisk::TEvChunkWrite>(PDiskParams->Owner, PDiskParams->OwnerRound,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvChunkWrite>(PDiskParams->Owner, PDiskParams->OwnerRound,
chunkIdx, offset,
new TParts{DataBuffer.data() + Rng() % (DataBuffer.size() - size), size},
reinterpret_cast<void*>(requestIdx), true, NPriWrite::HullHugeAsyncBlob, Sequential));
- ++ChunkWrite_RequestsSent;
-
- if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_PARALLEL) {
+ ++ChunkWrite_RequestsSent;
+
+ if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_PARALLEL) {
SendLogRequest(ctx, requestIdx, chunkIdx);
- }
-
- ++InFlight;
- }
-
- CheckForReserve(ctx);
- CheckDie(ctx);
- }
-
+ }
+
+ ++InFlight;
+ }
+
+ CheckForReserve(ctx);
+ CheckDie(ctx);
+ }
+
void Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx) {
- auto msg = ev->Get();
- if (msg->Status == NKikimrProto::OK) {
- ++ChunkWrite_OK;
- } else {
- ++ChunkWrite_NonOK;
- }
+ auto msg = ev->Get();
+ if (msg->Status == NKikimrProto::OK) {
+ ++ChunkWrite_OK;
+ } else {
+ ++ChunkWrite_NonOK;
+ }
ui64 requestIdx = reinterpret_cast<ui64>(msg->Cookie);
TRequestInfo *info = &RequestInfo[requestIdx];
- info->DataWritten = true;
+ info->DataWritten = true;
*BytesWritten += info->Size;
-
- if (info->LogWritten) {
- // both data and log are written, this could happen only in LOG_PARALLEL mode; this request is done
+
+ if (info->LogWritten) {
+ // both data and log are written, this could happen only in LOG_PARALLEL mode; this request is done
FinishRequest(ctx, requestIdx);
- } else if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_SEQUENTIAL) {
- // in sequential mode we send log request after completion of data write request
+ } else if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_SEQUENTIAL) {
+ // in sequential mode we send log request after completion of data write request
SendLogRequest(ctx, requestIdx, msg->ChunkIdx);
- } else if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_PARALLEL) {
- // this is parallel mode and log is not written yet, so request is not complete; we release it to avoid
- // being deleted
- }
-
- CheckDie(ctx);
- }
-
+ } else if (LogMode == NKikimrBlobStorage::TEvTestLoadRequest::LOG_PARALLEL) {
+ // this is parallel mode and log is not written yet, so request is not complete; we release it to avoid
+ // being deleted
+ }
+
+ CheckDie(ctx);
+ }
+
void SendLogRequest(const TActorContext& ctx, ui64 requestIdx, TChunkIdx chunkIdx) {
RequestInfo[requestIdx].LogStartTime = TAppData::TimeProvider->Now();
TString logRecord = "Hello, my dear log! I've just written a chunk!";
NPDisk::TCommitRecord record;
- record.CommitChunks.push_back(chunkIdx);
- record.DeleteChunks.swap(DeleteChunks);
- DeletedChunksCount += record.DeleteChunks.size();
+ record.CommitChunks.push_back(chunkIdx);
+ record.DeleteChunks.swap(DeleteChunks);
+ DeletedChunksCount += record.DeleteChunks.size();
TLsnSeg seg(Lsn, Lsn);
++Lsn;
- SendRequest(ctx, std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, PDiskParams->OwnerRound,
+ SendRequest(ctx, std::make_unique<NPDisk::TEvLog>(PDiskParams->Owner, PDiskParams->OwnerRound,
TLogSignature::SignatureHugeLogoBlob, record, logRecord, seg,
reinterpret_cast<void*>(requestIdx)));
++LogInFlight;
- }
-
+ }
+
void Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx) {
- auto msg = ev->Get();
+ auto msg = ev->Get();
TInstant now = TAppData::TimeProvider->Now();
- for (const auto& res : msg->Results) {
+ for (const auto& res : msg->Results) {
ui64 requestIdx = reinterpret_cast<ui64>(res.Cookie);
TRequestInfo *info = &RequestInfo[requestIdx];
- info->LogWritten = true;
+ info->LogWritten = true;
*LogEntriesWritten += 1;
LogResponseTimes.Increment((now - info->LogStartTime).MicroSeconds());
- if (info->DataWritten) {
- // both data and log are written, complete request and send another one if possible
+ if (info->DataWritten) {
+ // both data and log are written, complete request and send another one if possible
FinishRequest(ctx, requestIdx);
- } else {
- // log is written, but data is not; this is parallel mode and this request will be deleted in chunk write
- // completion handler
- }
+ } else {
+ // log is written, but data is not; this is parallel mode and this request will be deleted in chunk write
+ // completion handler
+ }
--LogInFlight;
- }
-
- CheckDie(ctx);
- }
-
+ }
+
+ CheckDie(ctx);
+ }
+
void FinishRequest(const TActorContext& ctx, ui64 requestIdx) {
- TInstant now = TAppData::TimeProvider->Now();
+ TInstant now = TAppData::TimeProvider->Now();
TRequestInfo *request = &RequestInfo[requestIdx];
if (now > MeasurementStartTime) {
@@ -519,48 +519,48 @@ public:
}
}
- TimeSeries.emplace(now, TRequestStat{
+ TimeSeries.emplace(now, TRequestStat{
static_cast<ui64>(*BytesWritten), // current state of bytes written counter
- request->Size,
- now - request->StartTime
- });
+ request->Size,
+ now - request->StartTime
+ });
ResponseTimes.Increment((now - request->StartTime).MicroSeconds());
- // cut time series to 60 seconds
- auto pos = TimeSeries.upper_bound(now - TDuration::Seconds(60));
- TimeSeries.erase(TimeSeries.begin(), pos);
- auto it = ChunkUsageCount.find(request->ChunkIdx);
- Y_VERIFY(it != ChunkUsageCount.end());
- if (!--it->second) {
- // chunk is completely written and can be destroyed
- if (Reuse) {
- AllocationQueue.push(it->first);
- } else {
- DeleteChunks.push_back(it->first);
- }
- ChunkUsageCount.erase(it);
- }
- --InFlight;
+ // cut time series to 60 seconds
+ auto pos = TimeSeries.upper_bound(now - TDuration::Seconds(60));
+ TimeSeries.erase(TimeSeries.begin(), pos);
+ auto it = ChunkUsageCount.find(request->ChunkIdx);
+ Y_VERIFY(it != ChunkUsageCount.end());
+ if (!--it->second) {
+ // chunk is completely written and can be destroyed
+ if (Reuse) {
+ AllocationQueue.push(it->first);
+ } else {
+ DeleteChunks.push_back(it->first);
+ }
+ ChunkUsageCount.erase(it);
+ }
+ --InFlight;
RequestInfo.erase(requestIdx);
- SendWriteRequests(ctx);
- }
-
- template<typename TRequest>
- void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
- ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- TStringStream str;
-#define PARAM(NAME, VALUE) \
+ SendWriteRequests(ctx);
+ }
+
+ template<typename TRequest>
+ void SendRequest(const TActorContext& ctx, std::unique_ptr<TRequest>&& request) {
+ ctx.Send(MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskId), request.release());
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ TStringStream str;
+#define PARAM(NAME, VALUE) \
TABLER() { \
TABLED() { str << NAME; } \
TABLED() { str << VALUE; } \
}
TMap<ui32, TVector<TDuration>> latmap;
- for (const auto& pair : TimeSeries) {
- const TRequestStat& stat = pair.second;
- latmap[stat.Size].push_back(stat.Latency);
- }
+ for (const auto& pair : TimeSeries) {
+ const TRequestStat& stat = pair.second;
+ latmap[stat.Size].push_back(stat.Latency);
+ }
HTML(str) {
TABLE() {
TABLEHEAD() {
@@ -573,44 +573,44 @@ public:
PARAM("Elapsed time / Duration", (TAppData::TimeProvider->Now() - TestStartTime).Seconds() << "s / "
<< DurationSeconds << "s");
- PARAM("TEvChunkWrite msgs sent", ChunkWrite_RequestsSent);
- PARAM("TEvChunkWriteResult msgs received, OK", ChunkWrite_OK);
- PARAM("TEvChunkWriteResult msgs received, not OK", ChunkWrite_NonOK);
- PARAM("TEvChunkReserve msgs sent", ChunkReserve_RequestsSent);
+ PARAM("TEvChunkWrite msgs sent", ChunkWrite_RequestsSent);
+ PARAM("TEvChunkWriteResult msgs received, OK", ChunkWrite_OK);
+ PARAM("TEvChunkWriteResult msgs received, not OK", ChunkWrite_NonOK);
+ PARAM("TEvChunkReserve msgs sent", ChunkReserve_RequestsSent);
PARAM("Bytes written", static_cast<ui64>(*BytesWritten));
- PARAM("Number of deleted chunks", DeletedChunksCount);
- if (PDiskParams) {
+ PARAM("Number of deleted chunks", DeletedChunksCount);
+ if (PDiskParams) {
PARAM("Owner", PDiskParams->Owner);
- PARAM("Chunk size", PDiskParams->ChunkSize);
- PARAM("Append block size", PDiskParams->AppendBlockSize);
- }
-
- for (ui32 dt : {5, 10, 15, 20, 60}) {
- TInstant now = TAppData::TimeProvider->Now();
- auto it = TimeSeries.upper_bound(now - TDuration::Seconds(dt));
- if (it != TimeSeries.begin()) {
- --it;
- }
- if (it != TimeSeries.end()) {
- auto end = std::prev(TimeSeries.end());
- if (end != it) {
- double seconds = (end->first - it->first).GetValue() * 1e-6;
- double speed = (end->second.BytesWrittenTotal - it->second.BytesWrittenTotal) / seconds;
+ PARAM("Chunk size", PDiskParams->ChunkSize);
+ PARAM("Append block size", PDiskParams->AppendBlockSize);
+ }
+
+ for (ui32 dt : {5, 10, 15, 20, 60}) {
+ TInstant now = TAppData::TimeProvider->Now();
+ auto it = TimeSeries.upper_bound(now - TDuration::Seconds(dt));
+ if (it != TimeSeries.begin()) {
+ --it;
+ }
+ if (it != TimeSeries.end()) {
+ auto end = std::prev(TimeSeries.end());
+ if (end != it) {
+ double seconds = (end->first - it->first).GetValue() * 1e-6;
+ double speed = (end->second.BytesWrittenTotal - it->second.BytesWrittenTotal) / seconds;
speed /= 1e6;
- PARAM("Average write speed at last " << dt << " seconds, MB/s", Sprintf("%.3f", speed));
- }
- }
- }
-
- for (auto& pair : latmap) {
- str << "<br/>";
+ PARAM("Average write speed at last " << dt << " seconds, MB/s", Sprintf("%.3f", speed));
+ }
+ }
+ }
+
+ for (auto& pair : latmap) {
+ str << "<br/>";
TVector<TDuration>& latencies = pair.second;
- std::sort(latencies.begin(), latencies.end());
- for (double percentile : {0.5, 0.9, 0.95, 0.99, 0.999, 1.0}) {
- TDuration value = latencies[size_t(percentile * (latencies.size() - 1))];
- PARAM(Sprintf("Size# %" PRIu32 " Percentile# %.3f", pair.first, percentile), value);
- }
- }
+ std::sort(latencies.begin(), latencies.end());
+ for (double percentile : {0.5, 0.9, 0.95, 0.99, 0.999, 1.0}) {
+ TDuration value = latencies[size_t(percentile * (latencies.size() - 1))];
+ PARAM(Sprintf("Size# %" PRIu32 " Percentile# %.3f", pair.first, percentile), value);
+ }
+ }
PARAM("Average speed since start, MB/s", Report->GetAverageSpeed() / 1e6);
PARAM("Speed standard deviation since start, MB/s", Report->GetSpeedDeviation() / 1e6);
for (double percentile : {0.5, 0.9, 0.95, 0.99, 0.999, 1.0}) {
@@ -621,26 +621,26 @@ public:
}
}
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
- }
-
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill)
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
+ }
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoisonPill)
HFunc(TEvRegisterPDiskLoadActorResult, Handle)
- HFunc(NPDisk::TEvYardInitResult, Handle)
- HFunc(NPDisk::TEvHarakiriResult, Handle)
+ HFunc(NPDisk::TEvYardInitResult, Handle)
+ HFunc(NPDisk::TEvHarakiriResult, Handle)
HFunc(TEvUpdateMonitoring, Handle)
- HFunc(NPDisk::TEvChunkWriteResult, Handle)
- HFunc(NPDisk::TEvChunkReserveResult, Handle)
- HFunc(NPDisk::TEvLogResult, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- )
-};
-
-IActor *CreatePDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLoadStart& cmd,
+ HFunc(NPDisk::TEvChunkWriteResult, Handle)
+ HFunc(NPDisk::TEvChunkReserveResult, Handle)
+ HFunc(NPDisk::TEvLogResult, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ )
+};
+
+IActor *CreatePDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TPDiskLoadStart& cmd,
const TActorId& parent, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters, ui64 index, ui64 tag) {
return new TPDiskWriterTestLoadActor(cmd, parent, counters, index, tag);
-}
-
-} // NKikimr
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_quantile.h b/ydb/core/blobstorage/testload/test_load_quantile.h
index 0d0f0207c6f..6fd521089b3 100644
--- a/ydb/core/blobstorage/testload/test_load_quantile.h
+++ b/ydb/core/blobstorage/testload/test_load_quantile.h
@@ -1,18 +1,18 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "test_load_time_series.h"
-
+#include "test_load_time_series.h"
+
#include <library/cpp/monlib/dynamic_counters/counters.h>
-namespace NKikimr {
-
- template<typename T>
- class TQuantileTracker : public TTimeSeries<T>
- {
- using TItem = typename TTimeSeries<T>::TItem;
- using TTimeSeries<T>::Items;
-
+namespace NKikimr {
+
+ template<typename T>
+ class TQuantileTracker : public TTimeSeries<T>
+ {
+ using TItem = typename TTimeSeries<T>::TItem;
+ using TTimeSeries<T>::Items;
+
using TPercentile = std::pair<float, NMonitoring::TDynamicCounters::TCounterPtr>;
using TPercentiles = TVector<TPercentile>;
@@ -20,15 +20,15 @@ namespace NKikimr {
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
NMonitoring::TDynamicCounters::TCounterPtr Samples;
- struct TCompareTimestamp {
- bool operator ()(const TItem& x, TInstant y) {
- return x.Timestamp < y;
- }
- };
-
- public:
- using TTimeSeries<T>::TTimeSeries;
-
+ struct TCompareTimestamp {
+ bool operator ()(const TItem& x, TInstant y) {
+ return x.Timestamp < y;
+ }
+ };
+
+ public:
+ using TTimeSeries<T>::TTimeSeries;
+
TQuantileTracker(TDuration lifetime, TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
const TString& metric, const TVector<float>& percentiles)
: TTimeSeries<T>(lifetime)
@@ -70,39 +70,39 @@ namespace NKikimr {
}
}
- bool CalculateQuantiles(size_t count, const size_t *numerators, size_t denominator, T *res,
- size_t *numSamples = nullptr, TDuration *interval = nullptr) const {
- if (numSamples) {
- *numSamples = Items.size();
- if (interval) {
- *interval = Items ? Items.back().Timestamp - Items.front().Timestamp : TDuration::Zero();
- }
- }
-
- // create a vector of values matching time criterion
+ bool CalculateQuantiles(size_t count, const size_t *numerators, size_t denominator, T *res,
+ size_t *numSamples = nullptr, TDuration *interval = nullptr) const {
+ if (numSamples) {
+ *numSamples = Items.size();
+ if (interval) {
+ *interval = Items ? Items.back().Timestamp - Items.front().Timestamp : TDuration::Zero();
+ }
+ }
+
+ // create a vector of values matching time criterion
TVector<T> values;
- values.reserve(Items.size());
- for (const TItem &item : Items) {
- values.push_back(item.Value);
- }
-
- // if there are no values, return false meaning we can't get adequate results
- if (values.empty()) {
- std::fill(res, res + count, T());
- return false;
- }
-
- // sort and calculate quantiles
- std::sort(values.begin(), values.end());
- size_t maxIndex = values.size() - 1;
- while (count--) {
- const size_t numerator = *numerators++;
- Y_VERIFY(numerator >= 0 && numerator <= denominator);
- const size_t index = maxIndex * numerator / denominator;
- *res++ = values[index];
- }
- return true;
- }
- };
-
-} // NKikimr
+ values.reserve(Items.size());
+ for (const TItem &item : Items) {
+ values.push_back(item.Value);
+ }
+
+ // if there are no values, return false meaning we can't get adequate results
+ if (values.empty()) {
+ std::fill(res, res + count, T());
+ return false;
+ }
+
+ // sort and calculate quantiles
+ std::sort(values.begin(), values.end());
+ size_t maxIndex = values.size() - 1;
+ while (count--) {
+ const size_t numerator = *numerators++;
+ Y_VERIFY(numerator >= 0 && numerator <= denominator);
+ const size_t index = maxIndex * numerator / denominator;
+ *res++ = values[index];
+ }
+ return true;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_size_gen.h b/ydb/core/blobstorage/testload/test_load_size_gen.h
index 5b4c296fa8d..be41eb2c6b0 100644
--- a/ydb/core/blobstorage/testload/test_load_size_gen.h
+++ b/ydb/core/blobstorage/testload/test_load_size_gen.h
@@ -1,28 +1,28 @@
-#pragma once
-
-#include "defs.h"
-#include "test_load_gen.h"
+#pragma once
+
+#include "defs.h"
+#include "test_load_gen.h"
#include <ydb/core/protos/blobstorage.pb.h>
-
-namespace NKikimr {
- namespace NSizeGenerator {
- struct TItem {
- ui32 Min;
- ui32 Max;
-
- TItem(const NKikimrBlobStorage::TEvTestLoadRequest::TSizeInfo& x)
- : Min(x.GetMin())
- , Max(x.GetMax())
- {
- Y_VERIFY(x.HasMin() && x.HasMax());
- }
-
- ui32 Generate() const {
- ui32 range = Max - Min + 1;
+
+namespace NKikimr {
+ namespace NSizeGenerator {
+ struct TItem {
+ ui32 Min;
+ ui32 Max;
+
+ TItem(const NKikimrBlobStorage::TEvTestLoadRequest::TSizeInfo& x)
+ : Min(x.GetMin())
+ , Max(x.GetMax())
+ {
+ Y_VERIFY(x.HasMin() && x.HasMax());
+ }
+
+ ui32 Generate() const {
+ ui32 range = Max - Min + 1;
return Min + TAppData::RandomProvider->GenRand64() % range;
- }
- };
- } // NSizeGenerator
-
- using TSizeGenerator = TGenerator<NSizeGenerator::TItem>;
-} // NKikimr
+ }
+ };
+ } // NSizeGenerator
+
+ using TSizeGenerator = TGenerator<NSizeGenerator::TItem>;
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_speed.h b/ydb/core/blobstorage/testload/test_load_speed.h
index edc6e8a8f62..d35ea99f194 100644
--- a/ydb/core/blobstorage/testload/test_load_speed.h
+++ b/ydb/core/blobstorage/testload/test_load_speed.h
@@ -1,35 +1,35 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "test_load_time_series.h"
-
-namespace NKikimr {
-
- template<typename T>
- class TSpeedTracker : public TTimeSeries<T>
- {
- using TItem = typename TTimeSeries<T>::TItem;
- using TTimeSeries<T>::Items;
-
- public:
- using TTimeSeries<T>::TTimeSeries;
-
- bool CalculateSpeed(T *res) const {
- if (Items.empty()) {
- *res = T();
- return false;
- }
-
- const TItem& front = Items.front();
- const TItem& back = Items.back();
- if (front.Timestamp != back.Timestamp) {
- *res = (back.Value - front.Value) * T(1000000) / (back.Timestamp - front.Timestamp).MicroSeconds();
- return true;
- } else {
- *res = T();
- return false;
- }
- }
- };
-
-} // NKikimr
+#include "test_load_time_series.h"
+
+namespace NKikimr {
+
+ template<typename T>
+ class TSpeedTracker : public TTimeSeries<T>
+ {
+ using TItem = typename TTimeSeries<T>::TItem;
+ using TTimeSeries<T>::Items;
+
+ public:
+ using TTimeSeries<T>::TTimeSeries;
+
+ bool CalculateSpeed(T *res) const {
+ if (Items.empty()) {
+ *res = T();
+ return false;
+ }
+
+ const TItem& front = Items.front();
+ const TItem& back = Items.back();
+ if (front.Timestamp != back.Timestamp) {
+ *res = (back.Value - front.Value) * T(1000000) / (back.Timestamp - front.Timestamp).MicroSeconds();
+ return true;
+ } else {
+ *res = T();
+ return false;
+ }
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_time_series.h b/ydb/core/blobstorage/testload/test_load_time_series.h
index b1ccfd037ad..e8bf2f721f1 100644
--- a/ydb/core/blobstorage/testload/test_load_time_series.h
+++ b/ydb/core/blobstorage/testload/test_load_time_series.h
@@ -1,45 +1,45 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-namespace NKikimr {
-
- template<typename T>
- class TTimeSeries {
- const TDuration MaxLifetime;
-
- protected:
- struct TItem {
- TInstant Timestamp;
- T Value;
-
- TItem(TInstant timestamp, T value)
- : Timestamp(timestamp)
- , Value(value)
- {}
- };
+namespace NKikimr {
+
+ template<typename T>
+ class TTimeSeries {
+ const TDuration MaxLifetime;
+
+ protected:
+ struct TItem {
+ TInstant Timestamp;
+ T Value;
+
+ TItem(TInstant timestamp, T value)
+ : Timestamp(timestamp)
+ , Value(value)
+ {}
+ };
TDeque<TItem> Items;
-
- public:
- using TValue = T;
-
- TTimeSeries(TDuration maxLifetime)
- : MaxLifetime(maxLifetime)
- {}
-
- void Add(TInstant timestamp, T value) {
- // ensure that timestamps are coming in nondecreasing order
- Y_VERIFY(!Items || Items.back().Timestamp <= timestamp);
-
- // drop old entries
- auto comp = [](const TItem &x, TInstant y) { return x.Timestamp < y; };
- auto it = std::lower_bound(Items.begin(), Items.end(), timestamp - MaxLifetime, comp);
- Items.erase(Items.begin(), it);
-
- // add new one
- Items.emplace_back(timestamp, std::move(value));
- }
- };
-
-
-} // NKikimr
+
+ public:
+ using TValue = T;
+
+ TTimeSeries(TDuration maxLifetime)
+ : MaxLifetime(maxLifetime)
+ {}
+
+ void Add(TInstant timestamp, T value) {
+ // ensure that timestamps are coming in nondecreasing order
+ Y_VERIFY(!Items || Items.back().Timestamp <= timestamp);
+
+ // drop old entries
+ auto comp = [](const TItem &x, TInstant y) { return x.Timestamp < y; };
+ auto it = std::lower_bound(Items.begin(), Items.end(), timestamp - MaxLifetime, comp);
+ Items.erase(Items.begin(), it);
+
+ // add new one
+ Items.emplace_back(timestamp, std::move(value));
+ }
+ };
+
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_vdisk_write.cpp b/ydb/core/blobstorage/testload/test_load_vdisk_write.cpp
index 39ecca9dbda..8f70e854198 100644
--- a/ydb/core/blobstorage/testload/test_load_vdisk_write.cpp
+++ b/ydb/core/blobstorage/testload/test_load_vdisk_write.cpp
@@ -1,271 +1,271 @@
-#include "test_load_actor.h"
-#include "test_load_interval_gen.h"
-#include "test_load_size_gen.h"
+#include "test_load_actor.h"
+#include "test_load_interval_gen.h"
+#include "test_load_size_gen.h"
#include <ydb/core/blobstorage/base/blobstorage_vdiskid.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/interconnect_channels.h>
#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NKikimr {
-
- namespace {
-
- class TVDiskLoadActor : public TActorBootstrapped<TVDiskLoadActor> {
- enum {
- EvTryToIssuePuts = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- EvTryToCollect,
- };
-
- struct TEvTryToIssuePuts : public TEventLocal<TEvTryToIssuePuts, EvTryToIssuePuts>
- {};
-
- struct TEvTryToCollect : public TEventLocal<TEvTryToCollect, EvTryToCollect>
- {};
-
+
+namespace NKikimr {
+
+ namespace {
+
+ class TVDiskLoadActor : public TActorBootstrapped<TVDiskLoadActor> {
+ enum {
+ EvTryToIssuePuts = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ EvTryToCollect,
+ };
+
+ struct TEvTryToIssuePuts : public TEventLocal<TEvTryToIssuePuts, EvTryToIssuePuts>
+ {};
+
+ struct TEvTryToCollect : public TEventLocal<TEvTryToCollect, EvTryToCollect>
+ {};
+
const TActorId ParentActorId;
const ui64 Tag;
-
- const TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TVDiskID VDiskId;
+
+ const TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TVDiskID VDiskId;
const TActorId VDiskActorId;
- const TBlobStorageGroupType GType;
+ const TBlobStorageGroupType GType;
TActorId QueueActorId;
-
- const ui64 TabletId;
- const ui32 Channel;
- const ui32 Generation;
-
+
+ const ui64 TabletId;
+ const ui32 Channel;
+ const ui32 Generation;
+
const ui64 DurationSeconds;
- const ui32 InFlightPutsMax;
- const ui64 InFlightPutBytesMax;
-
- const NKikimrBlobStorage::EPutHandleClass PutHandleClass;
- const ui32 StepDistance;
-
- TSizeGenerator PutSizeGenerator;
- TIntervalGenerator PutIntervalGenerator;
- TIntervalGenerator CollectIntervalGenerator;
-
+ const ui32 InFlightPutsMax;
+ const ui64 InFlightPutBytesMax;
+
+ const NKikimrBlobStorage::EPutHandleClass PutHandleClass;
+ const ui32 StepDistance;
+
+ TSizeGenerator PutSizeGenerator;
+ TIntervalGenerator PutIntervalGenerator;
+ TIntervalGenerator CollectIntervalGenerator;
+
TInstant StartTime;
- bool IsConnected = false;
-
- ui32 CollectStep = 0;
- ui32 CollectCounter = 1;
- TInstant NextCollectRequestTimestamp;
- bool EvTryToCollectScheduled = false;
-
- ui32 BlobStep = 1;
- ui32 BlobCookie = 0;
- TInstant NextWriteRequestTimestamp;
- ui32 InFlightPuts = 0;
+ bool IsConnected = false;
+
+ ui32 CollectStep = 0;
+ ui32 CollectCounter = 1;
+ TInstant NextCollectRequestTimestamp;
+ bool EvTryToCollectScheduled = false;
+
+ ui32 BlobStep = 1;
+ ui32 BlobCookie = 0;
+ TInstant NextWriteRequestTimestamp;
+ ui32 InFlightPuts = 0;
ui32 TEvVPutsSent = 0;
- ui64 InFlightPutBytes = 0;
+ ui64 InFlightPutBytes = 0;
ui64 BytesWritten = 0;
TMap<ui64, ui32> InFlightRequests;
- ui64 PutCookie = 1;
- bool EvTryToIssuePutsScheduled = false;
-
+ ui64 PutCookie = 1;
+ bool EvTryToIssuePutsScheduled = false;
+
TDeque<TLogoBlobID> WrittenBlobs;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LOAD_PDISK_WRITE;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LOAD_PDISK_WRITE;
}
- TVDiskLoadActor(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
+ TVDiskLoadActor(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
const NActors::TActorId& parent, ui64 tag)
- : ParentActorId(parent)
+ : ParentActorId(parent)
, Tag(tag)
- , Info(TBlobStorageGroupInfo::Parse(cmd.GetGroupInfo(), nullptr, nullptr))
- , VDiskId(VDiskIDFromVDiskID(cmd.GetVDiskId()))
- , VDiskActorId(Info->GetActorId(VDiskId))
- , GType(Info->Type)
- , TabletId(cmd.GetTabletId())
- , Channel(cmd.GetChannel())
- , Generation(cmd.GetGeneration())
+ , Info(TBlobStorageGroupInfo::Parse(cmd.GetGroupInfo(), nullptr, nullptr))
+ , VDiskId(VDiskIDFromVDiskID(cmd.GetVDiskId()))
+ , VDiskActorId(Info->GetActorId(VDiskId))
+ , GType(Info->Type)
+ , TabletId(cmd.GetTabletId())
+ , Channel(cmd.GetChannel())
+ , Generation(cmd.GetGeneration())
, DurationSeconds(cmd.GetDurationSeconds())
- , InFlightPutsMax(cmd.GetInFlightPutsMax())
- , InFlightPutBytesMax(cmd.GetInFlightPutBytesMax())
- , PutHandleClass(cmd.GetPutHandleClass())
- , StepDistance(cmd.GetStepDistance())
- , PutSizeGenerator(cmd.GetWriteSizes())
- , PutIntervalGenerator(cmd.GetWriteIntervals())
- , CollectIntervalGenerator(cmd.GetBarrierAdvanceIntervals())
- {
- }
-
- void Bootstrap(const TActorContext& ctx) {
+ , InFlightPutsMax(cmd.GetInFlightPutsMax())
+ , InFlightPutBytesMax(cmd.GetInFlightPutBytesMax())
+ , PutHandleClass(cmd.GetPutHandleClass())
+ , StepDistance(cmd.GetStepDistance())
+ , PutSizeGenerator(cmd.GetWriteSizes())
+ , PutIntervalGenerator(cmd.GetWriteIntervals())
+ , CollectIntervalGenerator(cmd.GetBarrierAdvanceIntervals())
+ {
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
LOG_INFO(ctx, NKikimrServices::BS_LOAD_TEST, "Load actor starter, erasure# %s",
GType.ToString().data());
- Become(&TVDiskLoadActor::StateFunc);
+ Become(&TVDiskLoadActor::StateFunc);
StartTime = TAppData::TimeProvider->Now();
ctx.Schedule(TDuration::Seconds(DurationSeconds), new TEvents::TEvPoisonPill);
- CreateQueueBackpressure(ctx);
- }
-
- void CreateQueueBackpressure(const TActorContext& ctx) {
- using namespace NBackpressure;
- auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
-
- NKikimrBlobStorage::EVDiskQueueId queueId = NKikimrBlobStorage::Unknown;
- switch (PutHandleClass) {
- case NKikimrBlobStorage::TabletLog:
- queueId = NKikimrBlobStorage::PutTabletLog;
- break;
- case NKikimrBlobStorage::AsyncBlob:
- queueId = NKikimrBlobStorage::PutAsyncBlob;
- break;
- case NKikimrBlobStorage::UserData:
- queueId = NKikimrBlobStorage::PutUserData;
- break;
- }
- Y_VERIFY(queueId != NKikimrBlobStorage::Unknown);
-
+ CreateQueueBackpressure(ctx);
+ }
+
+ void CreateQueueBackpressure(const TActorContext& ctx) {
+ using namespace NBackpressure;
+ auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
+
+ NKikimrBlobStorage::EVDiskQueueId queueId = NKikimrBlobStorage::Unknown;
+ switch (PutHandleClass) {
+ case NKikimrBlobStorage::TabletLog:
+ queueId = NKikimrBlobStorage::PutTabletLog;
+ break;
+ case NKikimrBlobStorage::AsyncBlob:
+ queueId = NKikimrBlobStorage::PutAsyncBlob;
+ break;
+ case NKikimrBlobStorage::UserData:
+ queueId = NKikimrBlobStorage::PutUserData;
+ break;
+ }
+ Y_VERIFY(queueId != NKikimrBlobStorage::Unknown);
+
TIntrusivePtr<TFlowRecord> flowRecord(new TFlowRecord);
- QueueActorId = ctx.Register(CreateVDiskBackpressureClient(
- Info,
- VDiskId,
- queueId,
- counters,
- MakeIntrusive<TBSProxyContext>(counters),
+ QueueActorId = ctx.Register(CreateVDiskBackpressureClient(
+ Info,
+ VDiskId,
+ queueId,
+ counters,
+ MakeIntrusive<TBSProxyContext>(counters),
TQueueClientId(EQueueClientType::VDiskLoad, TAppData::RandomProvider->GenRand64()),
- "",
- TInterconnectChannels::IC_BLOBSTORAGE,
- ctx.ExecutorThread.ActorSystem->NodeId == VDiskActorId.NodeId(),
+ "",
+ TInterconnectChannels::IC_BLOBSTORAGE,
+ ctx.ExecutorThread.ActorSystem->NodeId == VDiskActorId.NodeId(),
TDuration::Minutes(1),
flowRecord,
NMonitoring::TCountableBase::EVisibility::Public
- ));
- }
-
- void HandlePoison(const TActorContext& ctx) {
- ctx.Send(QueueActorId, new TEvents::TEvPoisonPill);
+ ));
+ }
+
+ void HandlePoison(const TActorContext& ctx) {
+ ctx.Send(QueueActorId, new TEvents::TEvPoisonPill);
ctx.Send(ParentActorId, new TEvTestLoadFinished(Tag, nullptr, "Poison pill"));
- Die(ctx);
- }
-
- void TryToIssuePuts(const TActorContext& ctx) {
+ Die(ctx);
+ }
+
+ void TryToIssuePuts(const TActorContext& ctx) {
const TInstant now = TAppData::TimeProvider->Now();
-
- while (IsConnected &&
- now >= NextWriteRequestTimestamp &&
- InFlightPuts < InFlightPutsMax &&
- InFlightPutBytes < InFlightPutBytesMax) {
- TLogoBlobID logoBlobId;
-
+
+ while (IsConnected &&
+ now >= NextWriteRequestTimestamp &&
+ InFlightPuts < InFlightPutsMax &&
+ InFlightPutBytes < InFlightPutBytesMax) {
+ TLogoBlobID logoBlobId;
+
if (WrittenBlobs && TAppData::RandomProvider->GenRandReal2() < 0.25) {
size_t index = TAppData::RandomProvider->GenRand64() % WrittenBlobs.size();
- logoBlobId = WrittenBlobs[index];
- } else {
- const ui32 size = PutSizeGenerator.Generate();
- logoBlobId = TLogoBlobID(TabletId, Generation, BlobStep, Channel, size, BlobCookie);
- ++BlobCookie;
- WrittenBlobs.push_back(logoBlobId);
- }
-
+ logoBlobId = WrittenBlobs[index];
+ } else {
+ const ui32 size = PutSizeGenerator.Generate();
+ logoBlobId = TLogoBlobID(TabletId, Generation, BlobStep, Channel, size, BlobCookie);
+ ++BlobCookie;
+ WrittenBlobs.push_back(logoBlobId);
+ }
+
logoBlobId = TLogoBlobID(logoBlobId, 1 + TAppData::RandomProvider->GenRand64() % GType.TotalPartCount());
-
- IssuePutRequest(logoBlobId, PutCookie, ctx);
- NextWriteRequestTimestamp = now + PutIntervalGenerator.Generate();
- ++InFlightPuts;
- InFlightPutBytes += logoBlobId.BlobSize();
- InFlightRequests.emplace(PutCookie, logoBlobId.BlobSize());
- ++PutCookie;
- }
-
- if (now < NextWriteRequestTimestamp && !EvTryToIssuePutsScheduled) {
- const TDuration remain = NextWriteRequestTimestamp - now;
- ctx.Schedule(remain, new TEvTryToIssuePuts);
- EvTryToIssuePutsScheduled = true;
- }
- }
-
- void IssuePutRequest(const TLogoBlobID& logoBlobId, ui64 cookie, const TActorContext& ctx) {
+
+ IssuePutRequest(logoBlobId, PutCookie, ctx);
+ NextWriteRequestTimestamp = now + PutIntervalGenerator.Generate();
+ ++InFlightPuts;
+ InFlightPutBytes += logoBlobId.BlobSize();
+ InFlightRequests.emplace(PutCookie, logoBlobId.BlobSize());
+ ++PutCookie;
+ }
+
+ if (now < NextWriteRequestTimestamp && !EvTryToIssuePutsScheduled) {
+ const TDuration remain = NextWriteRequestTimestamp - now;
+ ctx.Schedule(remain, new TEvTryToIssuePuts);
+ EvTryToIssuePutsScheduled = true;
+ }
+ }
+
+ void IssuePutRequest(const TLogoBlobID& logoBlobId, ui64 cookie, const TActorContext& ctx) {
TString whole(logoBlobId.BlobSize(), 'X');
- TDataPartSet parts;
+ TDataPartSet parts;
GType.SplitData((TErasureType::ECrcMode)logoBlobId.CrcMode(), whole, parts);
- auto ev = std::make_unique<TEvBlobStorage::TEvVPut>(logoBlobId,
+ auto ev = std::make_unique<TEvBlobStorage::TEvVPut>(logoBlobId,
parts.Parts[logoBlobId.PartId() - 1].OwnedString, VDiskId, true, &cookie, TInstant::Max(), PutHandleClass);
- ctx.Send(QueueActorId, ev.release());
+ ctx.Send(QueueActorId, ev.release());
++TEvVPutsSent;
- }
-
- void HandleTryToIssuePuts(const TActorContext& ctx) {
- Y_VERIFY(EvTryToIssuePutsScheduled);
- EvTryToIssuePutsScheduled = false;
- TryToIssuePuts(ctx);
- }
-
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr& ev, const TActorContext& ctx) {
- TEvBlobStorage::TEvVPutResult *msg = ev->Get();
- const auto& record = msg->Record;
-
- auto it = InFlightRequests.find(record.GetCookie());
- Y_VERIFY(it != InFlightRequests.end());
- const ui32 size = it->second;
- InFlightRequests.erase(it);
-
- --InFlightPuts;
- InFlightPutBytes -= size;
+ }
+
+ void HandleTryToIssuePuts(const TActorContext& ctx) {
+ Y_VERIFY(EvTryToIssuePutsScheduled);
+ EvTryToIssuePutsScheduled = false;
+ TryToIssuePuts(ctx);
+ }
+
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr& ev, const TActorContext& ctx) {
+ TEvBlobStorage::TEvVPutResult *msg = ev->Get();
+ const auto& record = msg->Record;
+
+ auto it = InFlightRequests.find(record.GetCookie());
+ Y_VERIFY(it != InFlightRequests.end());
+ const ui32 size = it->second;
+ InFlightRequests.erase(it);
+
+ --InFlightPuts;
+ InFlightPutBytes -= size;
if (record.GetStatus() == NKikimrProto::OK) {
BytesWritten += size;
}
-
- TryToIssuePuts(ctx);
- }
-
- void TryToCollect(const TActorContext& ctx) {
+
+ TryToIssuePuts(ctx);
+ }
+
+ void TryToCollect(const TActorContext& ctx) {
const TInstant now = TAppData::TimeProvider->Now();
- if (IsConnected && now >= NextCollectRequestTimestamp) {
- if (CollectStep < BlobStep + StepDistance) {
- const ui32 collectStep = CollectStep++;
- auto ev = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(TabletId, Generation, CollectCounter++,
- Channel, true, Generation, collectStep, false, nullptr, nullptr, VDiskId,
- TInstant::Max());
- ctx.Send(QueueActorId, ev.release());
- NextCollectRequestTimestamp = now + CollectIntervalGenerator.Generate();
-
- auto comp = [](ui32 step, const TLogoBlobID& logoBlobId) {
- return step < logoBlobId.Step();
- };
- auto pos = std::upper_bound(WrittenBlobs.begin(), WrittenBlobs.end(), collectStep, comp);
- WrittenBlobs.erase(WrittenBlobs.begin(), pos);
- }
- ++BlobStep;
- BlobCookie = 0;
- }
- if (!EvTryToCollectScheduled) {
- const TDuration remain = NextCollectRequestTimestamp - now;
- ctx.Schedule(remain, new TEvTryToCollect);
- EvTryToCollectScheduled = true;
- }
- }
-
- void HandleTryToCollect(const TActorContext& ctx) {
- Y_VERIFY(EvTryToCollectScheduled);
- TryToCollect(ctx);
- }
-
- void Handle(TEvBlobStorage::TEvVCollectGarbageResult::TPtr& /*ev*/, const TActorContext& ctx) {
- Y_VERIFY(EvTryToCollectScheduled);
- EvTryToCollectScheduled = false;
- TryToCollect(ctx);
- }
-
- void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& ctx) {
- IsConnected = ev->Get()->IsConnected;
- if (IsConnected) {
- TryToIssuePuts(ctx);
- TryToCollect(ctx);
- }
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- TStringStream str;
-
+ if (IsConnected && now >= NextCollectRequestTimestamp) {
+ if (CollectStep < BlobStep + StepDistance) {
+ const ui32 collectStep = CollectStep++;
+ auto ev = std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(TabletId, Generation, CollectCounter++,
+ Channel, true, Generation, collectStep, false, nullptr, nullptr, VDiskId,
+ TInstant::Max());
+ ctx.Send(QueueActorId, ev.release());
+ NextCollectRequestTimestamp = now + CollectIntervalGenerator.Generate();
+
+ auto comp = [](ui32 step, const TLogoBlobID& logoBlobId) {
+ return step < logoBlobId.Step();
+ };
+ auto pos = std::upper_bound(WrittenBlobs.begin(), WrittenBlobs.end(), collectStep, comp);
+ WrittenBlobs.erase(WrittenBlobs.begin(), pos);
+ }
+ ++BlobStep;
+ BlobCookie = 0;
+ }
+ if (!EvTryToCollectScheduled) {
+ const TDuration remain = NextCollectRequestTimestamp - now;
+ ctx.Schedule(remain, new TEvTryToCollect);
+ EvTryToCollectScheduled = true;
+ }
+ }
+
+ void HandleTryToCollect(const TActorContext& ctx) {
+ Y_VERIFY(EvTryToCollectScheduled);
+ TryToCollect(ctx);
+ }
+
+ void Handle(TEvBlobStorage::TEvVCollectGarbageResult::TPtr& /*ev*/, const TActorContext& ctx) {
+ Y_VERIFY(EvTryToCollectScheduled);
+ EvTryToCollectScheduled = false;
+ TryToCollect(ctx);
+ }
+
+ void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& ctx) {
+ IsConnected = ev->Get()->IsConnected;
+ if (IsConnected) {
+ TryToIssuePuts(ctx);
+ TryToCollect(ctx);
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ TStringStream str;
+
#define NAMED_PARAM(NAME, PARAM) \
TABLER() { \
TABLED() { \
@@ -285,36 +285,36 @@ namespace NKikimr {
str << NAME; \
} \
}
-
+
HTML(str) {
TABLE() {
TABLEHEAD() {
TABLER() {
TABLEH() {
- str << "Parameter";
+ str << "Parameter";
}
TABLEH() {
- str << "Value";
+ str << "Value";
}
}
}
TABLEBODY() {
NAMED_PARAM("Elapsed time / Duration", (TAppData::TimeProvider->Now() - StartTime).Seconds()
<< "s / " << DurationSeconds << "s");
- PARAM(TabletId)
- PARAM(Channel)
- PARAM(Generation)
- PARAM(NextCollectRequestTimestamp)
- PARAM(CollectStep)
- PARAM(NextWriteRequestTimestamp)
- PARAM(BlobStep)
- PARAM(BlobCookie)
- PARAM(InFlightPuts)
- PARAM(InFlightPutBytes)
- PARAM(PutCookie)
- PARAM(IsConnected)
- PARAM(VDiskId)
- PARAM(VDiskActorId)
+ PARAM(TabletId)
+ PARAM(Channel)
+ PARAM(Generation)
+ PARAM(NextCollectRequestTimestamp)
+ PARAM(CollectStep)
+ PARAM(NextWriteRequestTimestamp)
+ PARAM(BlobStep)
+ PARAM(BlobCookie)
+ PARAM(InFlightPuts)
+ PARAM(InFlightPutBytes)
+ PARAM(PutCookie)
+ PARAM(IsConnected)
+ PARAM(VDiskId)
+ PARAM(VDiskActorId)
PARAM(BytesWritten)
PARAM(TEvVPutsSent)
TString avgSpeed = Sprintf("%.3lf %s", (double) BytesWritten / (1 << 20) /
@@ -323,25 +323,25 @@ namespace NKikimr {
}
}
}
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
- }
-
- STRICT_STFUNC(StateFunc, {
- CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
- CFunc(EvTryToIssuePuts, HandleTryToIssuePuts);
- CFunc(EvTryToCollect, HandleTryToCollect);
- HFunc(TEvBlobStorage::TEvVPutResult, Handle);
- HFunc(TEvBlobStorage::TEvVCollectGarbageResult, Handle);
- HFunc(TEvProxyQueueState, Handle);
- HFunc(NMon::TEvHttpInfo, Handle);
- })
- };
-
- } // <anonymous>
-
- IActor *CreateVDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
+ CFunc(EvTryToIssuePuts, HandleTryToIssuePuts);
+ CFunc(EvTryToCollect, HandleTryToCollect);
+ HFunc(TEvBlobStorage::TEvVPutResult, Handle);
+ HFunc(TEvBlobStorage::TEvVCollectGarbageResult, Handle);
+ HFunc(TEvProxyQueueState, Handle);
+ HFunc(NMon::TEvHttpInfo, Handle);
+ })
+ };
+
+ } // <anonymous>
+
+ IActor *CreateVDiskWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TVDiskLoadStart& cmd,
const NActors::TActorId& parent, ui64 tag) {
return new TVDiskLoadActor(cmd, parent, tag);
- }
-
-} // NKikimr
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/testload/test_load_write.cpp b/ydb/core/blobstorage/testload/test_load_write.cpp
index 3169c1609ed..a37fc4b3f3b 100644
--- a/ydb/core/blobstorage/testload/test_load_write.cpp
+++ b/ydb/core/blobstorage/testload/test_load_write.cpp
@@ -1,8 +1,8 @@
-#include "test_load_actor.h"
-#include "test_load_size_gen.h"
-#include "test_load_interval_gen.h"
-#include "test_load_quantile.h"
-#include "test_load_speed.h"
+#include "test_load_actor.h"
+#include "test_load_size_gen.h"
+#include "test_load_interval_gen.h"
+#include "test_load_quantile.h"
+#include "test_load_speed.h"
#include <ydb/core/util/yverify_stream.h>
#include <ydb/core/util/lz4_data_generator.h>
@@ -11,74 +11,74 @@
#include <library/cpp/monlib/service/pages/templates.h>
-#include <util/datetime/cputimer.h>
-#include <util/generic/queue.h>
-#include <util/generic/set.h>
+#include <util/datetime/cputimer.h>
+#include <util/generic/queue.h>
+#include <util/generic/set.h>
#include <util/system/type_name.h>
-#include <util/random/fast.h>
-
-namespace NKikimr {
-
-class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActor> {
- class TWakeupQueue {
- using TCallback = std::function<void(const TActorContext&)>;
-
- struct TEvent {
- TInstant Timestamp;
- TCallback Callback;
-
- TEvent(TInstant timestamp, TCallback callback)
- : Timestamp(timestamp)
- , Callback(std::move(callback))
- {}
-
- friend bool operator <(const TEvent& x, const TEvent& y) {
- return y.Timestamp < x.Timestamp;
- }
- };
-
+#include <util/random/fast.h>
+
+namespace NKikimr {
+
+class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActor> {
+ class TWakeupQueue {
+ using TCallback = std::function<void(const TActorContext&)>;
+
+ struct TEvent {
+ TInstant Timestamp;
+ TCallback Callback;
+
+ TEvent(TInstant timestamp, TCallback callback)
+ : Timestamp(timestamp)
+ , Callback(std::move(callback))
+ {}
+
+ friend bool operator <(const TEvent& x, const TEvent& y) {
+ return y.Timestamp < x.Timestamp;
+ }
+ };
+
TPriorityQueue<TEvent> Events;
-
- public:
- void Wakeup(const TActorContext& ctx) {
+
+ public:
+ void Wakeup(const TActorContext& ctx) {
while (Events && TAppData::TimeProvider->Now() >= Events.top().Timestamp) {
- TCallback callback = std::move(Events.top().Callback);
- Events.pop();
- callback(ctx);
- }
- }
-
- TMaybe<TInstant> GetNextWakeupTime() const {
- return Events ? Events.top().Timestamp : TMaybe<TInstant>();
- }
-
- void Put(TInstant timestamp, TCallback callback, const TActorContext& /*ctx*/) {
- Events.emplace(timestamp, callback);
- }
- };
-
- class TQueryDispatcher {
- using TCallback = std::function<void(IEventBase*, const TActorContext&)>;
-
- ui64 NextCookie = 1;
+ TCallback callback = std::move(Events.top().Callback);
+ Events.pop();
+ callback(ctx);
+ }
+ }
+
+ TMaybe<TInstant> GetNextWakeupTime() const {
+ return Events ? Events.top().Timestamp : TMaybe<TInstant>();
+ }
+
+ void Put(TInstant timestamp, TCallback callback, const TActorContext& /*ctx*/) {
+ Events.emplace(timestamp, callback);
+ }
+ };
+
+ class TQueryDispatcher {
+ using TCallback = std::function<void(IEventBase*, const TActorContext&)>;
+
+ ui64 NextCookie = 1;
THashMap<ui64, TCallback> Callbacks;
-
- public:
- ui64 ObtainCookie(TCallback callback) {
- ui64 cookie = NextCookie++;
- Callbacks.emplace(cookie, std::move(callback));
- return cookie;
- }
-
- template<typename TEventPtr>
- void ProcessEvent(TEventPtr& ev, const TActorContext& ctx) {
- auto iter = Callbacks.find(ev->Cookie);
- Y_VERIFY(iter != Callbacks.end(), "Cookie# %" PRIu64 " Type# %s", ev->Cookie, TypeName<TEventPtr>().data());
- iter->second(ev->Get(), ctx);
- Callbacks.erase(iter);
- }
- };
-
+
+ public:
+ ui64 ObtainCookie(TCallback callback) {
+ ui64 cookie = NextCookie++;
+ Callbacks.emplace(cookie, std::move(callback));
+ return cookie;
+ }
+
+ template<typename TEventPtr>
+ void ProcessEvent(TEventPtr& ev, const TActorContext& ctx) {
+ auto iter = Callbacks.find(ev->Cookie);
+ Y_VERIFY(iter != Callbacks.end(), "Cookie# %" PRIu64 " Type# %s", ev->Cookie, TypeName<TEventPtr>().data());
+ iter->second(ev->Get(), ctx);
+ Callbacks.erase(iter);
+ }
+ };
+
struct TReqInfo {
TDuration SendTime;
TEvBlobStorage::EEv EvType;
@@ -86,71 +86,71 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
NKikimrBlobStorage::EPutHandleClass PutHandleClass;
};
- class TTabletWriter {
+ class TTabletWriter {
using TLatencyTrackerUs = NMonitoring::TPercentileTrackerLg<5, 5, 10>;
static_assert(TLatencyTrackerUs::TRACKER_LIMIT >= 100e6,
"TLatencyTrackerUs must have limit grater than 100 second");
-
+
const TVector<float> Percentiles{0.1, 0.15, 0.5, 0.9, 0.99, 0.999, 1.0};
const TDuration ExposePeriod = TDuration::Seconds(10);
TIntrusivePtr<NMonitoring::TDynamicCounters> TagCounters;
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TWakeupQueue& WakeupQueue;
- TQueryDispatcher& QueryDispatcher;
- const ui64 TabletId;
- const ui32 Channel;
- ui32 Generation;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TWakeupQueue& WakeupQueue;
+ TQueryDispatcher& QueryDispatcher;
+ const ui64 TabletId;
+ const ui32 Channel;
+ ui32 Generation;
ui32 GarbageCollectStep;
- ui32 WriteStep;
- ui32 Cookie;
+ ui32 WriteStep;
+ ui32 Cookie;
ui32 GroupBlockRetries;
- const ui32 GroupId;
- const NKikimrBlobStorage::EPutHandleClass PutHandleClass;
- TSizeGenerator WriteSizeGen;
- TIntervalGenerator WriteIntervalGen;
+ const ui32 GroupId;
+ const NKikimrBlobStorage::EPutHandleClass PutHandleClass;
+ TSizeGenerator WriteSizeGen;
+ TIntervalGenerator WriteIntervalGen;
TIntervalGenerator GarbageCollectIntervalGen;
- TInstant NextWriteTimestamp;
- ui32 WritesInFlight = 0;
- ui64 WriteBytesInFlight = 0;
- const ui32 MaxWritesInFlight;
- const ui64 MaxWriteBytesInFlight;
+ TInstant NextWriteTimestamp;
+ ui32 WritesInFlight = 0;
+ ui64 WriteBytesInFlight = 0;
+ const ui32 MaxWritesInFlight;
+ const ui64 MaxWriteBytesInFlight;
const ui64 MaxTotalBytesWritten;
- const bool Soft;
- ui64 TotalBytesWritten = 0;
- ui64 TotalBytesRead = 0;
- TSpeedTracker<ui64> MegabytesPerSecondST;
- TQuantileTracker<ui64> MegabytesPerSecondQT;
+ const bool Soft;
+ ui64 TotalBytesWritten = 0;
+ ui64 TotalBytesRead = 0;
+ TSpeedTracker<ui64> MegabytesPerSecondST;
+ TQuantileTracker<ui64> MegabytesPerSecondQT;
TLatencyTrackerUs ResponseQT;
- THashMap<ui64, ui64> SentTimestamp;
+ THashMap<ui64, ui64> SentTimestamp;
TDeque<std::pair<ui64, ui64>> WritesInFlightTimestamps;
TIntrusivePtr<NMonitoring::TCounterForPtr> MaxInFlightLatency;
- ui64 WriteQueryId = 0;
+ ui64 WriteQueryId = 0;
const NKikimrBlobStorage::EGetHandleClass GetHandleClass;
- TSizeGenerator ReadSizeGen;
- TIntervalGenerator ReadIntervalGen;
- const ui32 MaxReadsInFlight;
- const ui64 MaxReadBytesInFlight;
- ui32 ReadsInFlight = 0;
- ui64 ReadBytesInFlight = 0;
- TDeque<TLogoBlobID> ConfirmedBlobIds;
- TInstant NextReadTimestamp;
- ui64 ReadQueryId = 0;
- THashMap<ui64, ui64> ReadSentTimestamp;
- TSpeedTracker<ui64> ReadMegabytesPerSecondST;
- TQuantileTracker<ui64> ReadMegabytesPerSecondQT;
+ TSizeGenerator ReadSizeGen;
+ TIntervalGenerator ReadIntervalGen;
+ const ui32 MaxReadsInFlight;
+ const ui64 MaxReadBytesInFlight;
+ ui32 ReadsInFlight = 0;
+ ui64 ReadBytesInFlight = 0;
+ TDeque<TLogoBlobID> ConfirmedBlobIds;
+ TInstant NextReadTimestamp;
+ ui64 ReadQueryId = 0;
+ THashMap<ui64, ui64> ReadSentTimestamp;
+ TSpeedTracker<ui64> ReadMegabytesPerSecondST;
+ TQuantileTracker<ui64> ReadMegabytesPerSecondQT;
TLatencyTrackerUs ReadResponseQT;
- bool NextWriteInQueue = false;
- bool NextReadInQueue = false;
+ bool NextWriteInQueue = false;
+ bool NextReadInQueue = false;
bool IsWorkingNow = true;
-
- TQuantileTracker<ui32> WritesInFlightQT;
- TQuantileTracker<ui64> WriteBytesInFlightQT;
- TQuantileTracker<ui32> ReadsInFlightQT;
- TQuantileTracker<ui64> ReadBytesInFlightQT;
- TDeque<TInstant> IssuedWriteTimestamp;
-
+
+ TQuantileTracker<ui32> WritesInFlightQT;
+ TQuantileTracker<ui64> WriteBytesInFlightQT;
+ TQuantileTracker<ui32> ReadsInFlightQT;
+ TQuantileTracker<ui64> ReadBytesInFlightQT;
+ TDeque<TInstant> IssuedWriteTimestamp;
+
TInstant LastLatencyTrackerUpdate;
TInstant StartTimestamp;
@@ -161,11 +161,11 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
ui64 ScriptedRound;
TVector<TReqInfo> ScriptedRequests;
- public:
- TTabletWriter(ui64 tag, TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
- TWakeupQueue& wakeupQueue, TQueryDispatcher& queryDispatcher, ui64 tabletId, ui32 channel,
- TMaybe<ui32> generation, ui32 groupId, NKikimrBlobStorage::EPutHandleClass putHandleClass,
- const TSizeGenerator& writeSizeGen, const TIntervalGenerator& writeIntervalGen,
+ public:
+ TTabletWriter(ui64 tag, TIntrusivePtr<NMonitoring::TDynamicCounters> counters,
+ TWakeupQueue& wakeupQueue, TQueryDispatcher& queryDispatcher, ui64 tabletId, ui32 channel,
+ TMaybe<ui32> generation, ui32 groupId, NKikimrBlobStorage::EPutHandleClass putHandleClass,
+ const TSizeGenerator& writeSizeGen, const TIntervalGenerator& writeIntervalGen,
const TIntervalGenerator& garbageCollectIntervalGen, ui32 maxWritesInFlight, ui64 maxWriteBytesInFlight,
ui64 maxTotalBytesWritten, bool soft,
NKikimrBlobStorage::EGetHandleClass getHandleClass,
@@ -174,34 +174,34 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
TDuration scriptedRoundDuration, TVector<TReqInfo>&& scriptedRequests)
: TagCounters(counters->GetSubgroup("tag", Sprintf("%" PRIu64, tag)))
, Counters(TagCounters->GetSubgroup("channel", Sprintf("%" PRIu32, channel)))
- , WakeupQueue(wakeupQueue)
- , QueryDispatcher(queryDispatcher)
- , TabletId(tabletId)
- , Channel(channel)
- , Generation(generation ? *generation : 0)
+ , WakeupQueue(wakeupQueue)
+ , QueryDispatcher(queryDispatcher)
+ , TabletId(tabletId)
+ , Channel(channel)
+ , Generation(generation ? *generation : 0)
, GarbageCollectStep(1)
- , WriteStep(3)
- , Cookie(1)
+ , WriteStep(3)
+ , Cookie(1)
, GroupBlockRetries(3)
- , GroupId(groupId)
- , PutHandleClass(putHandleClass)
- , WriteSizeGen(writeSizeGen)
- , WriteIntervalGen(writeIntervalGen)
+ , GroupId(groupId)
+ , PutHandleClass(putHandleClass)
+ , WriteSizeGen(writeSizeGen)
+ , WriteIntervalGen(writeIntervalGen)
, GarbageCollectIntervalGen(garbageCollectIntervalGen)
- , MaxWritesInFlight(maxWritesInFlight)
- , MaxWriteBytesInFlight(maxWriteBytesInFlight)
+ , MaxWritesInFlight(maxWritesInFlight)
+ , MaxWriteBytesInFlight(maxWriteBytesInFlight)
, MaxTotalBytesWritten(maxTotalBytesWritten)
- , Soft(soft)
- , MegabytesPerSecondST(TDuration::Seconds(3)) // average speed at last 3 seconds
+ , Soft(soft)
+ , MegabytesPerSecondST(TDuration::Seconds(3)) // average speed at last 3 seconds
, MegabytesPerSecondQT(ExposePeriod, Counters->GetSubgroup("metric", "writeSpeed"),
"bytesPerSecond", Percentiles)
, ResponseQT()
, GetHandleClass(getHandleClass)
- , ReadSizeGen(readSizeGen)
- , ReadIntervalGen(readIntervalGen)
- , MaxReadsInFlight(maxReadsInFlight)
- , MaxReadBytesInFlight(maxReadBytesInFlight)
- , ReadMegabytesPerSecondST(TDuration::Seconds(3))
+ , ReadSizeGen(readSizeGen)
+ , ReadIntervalGen(readIntervalGen)
+ , MaxReadsInFlight(maxReadsInFlight)
+ , MaxReadBytesInFlight(maxReadBytesInFlight)
+ , ReadMegabytesPerSecondST(TDuration::Seconds(3))
, ReadMegabytesPerSecondQT(ExposePeriod, Counters->GetSubgroup("metric", "readSpeed"),
"bytesPerSecond", Percentiles)
, ReadResponseQT()
@@ -224,7 +224,7 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
ResponseQT.Initialize(percCounters->GetSubgroup("metric", "writeResponse"), Percentiles);
ReadResponseQT.Initialize(percCounters->GetSubgroup("metric", "readResponse"), Percentiles);
}
-
+
TString PrintMe() {
return TStringBuilder() << "TabletId# " << TabletId << " Generation# " << Generation;
}
@@ -235,7 +235,7 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
template<typename T>
bool CheckStatus(const TActorContext& ctx, T *ev, const TVector<NKikimrProto::EReplyStatus>& goodStatuses) {
- if (goodStatuses.empty() || Count(goodStatuses, ev->Status)) {
+ if (goodStatuses.empty() || Count(goodStatuses, ev->Status)) {
return true;
} else {
LOG_ERROR_S(ctx, NKikimrServices::BS_LOAD_TEST, PrintMe() << " recieved not OK, msg# "
@@ -247,9 +247,9 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
}
// Issue TEvDiscover
- void Bootstrap(const TActorContext& ctx) {
+ void Bootstrap(const TActorContext& ctx) {
NextWriteTimestamp = TAppData::TimeProvider->Now();
- auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, Generation, false, true, TInstant::Max(), 0);
+ auto ev = std::make_unique<TEvBlobStorage::TEvDiscover>(TabletId, Generation, false, true, TInstant::Max(), 0);
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, PrintMe() << " is bootstrapped, going to send "
<< ev->ToString());
auto callback = [this] (IEventBase *event, const TActorContext& ctx) {
@@ -262,11 +262,11 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
Generation = res->BlockedGeneration + 1;
IssueTEvBlock(ctx);
};
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
}
void IssueTEvBlock(const TActorContext& ctx) {
- auto ev = std::make_unique<TEvBlobStorage::TEvBlock>(TabletId, Generation, TInstant::Max());
+ auto ev = std::make_unique<TEvBlobStorage::TEvBlock>(TabletId, Generation, TInstant::Max());
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, PrintMe() << " going to send " << ev->ToString());
auto callback = [this] (IEventBase *event, const TActorContext& ctx) {
auto *res = dynamic_cast<TEvBlobStorage::TEvBlockResult *>(event);
@@ -284,7 +284,7 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
++Generation;
IssueLastBlob(ctx);
};
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
}
void IssueLastBlob(const TActorContext& ctx) {
@@ -292,7 +292,7 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
const ui32 lastStep = Max<ui32>();
const TLogoBlobID id(TabletId, Generation, lastStep, Channel, size, 0);
const TString buffer = GenerateBuffer(id);
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max(), PutHandleClass);
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max(), PutHandleClass);
auto callback = [this] (IEventBase *event, const TActorContext& ctx) {
auto *res = dynamic_cast<TEvBlobStorage::TEvPutResult *>(event);
@@ -304,7 +304,7 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
IssueTEvCollectGarbage(ctx);
};
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
}
void IssueTEvCollectGarbage(const TActorContext& ctx) {
@@ -328,11 +328,11 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
void StartWorking(const TActorContext& ctx) {
StartTimestamp = TAppData::TimeProvider->Now();
InitializeTrackers(StartTimestamp);
- IssueWriteIfPossible(ctx);
+ IssueWriteIfPossible(ctx);
ScheduleGarbageCollect(ctx);
- ExposeCounters(ctx);
- }
-
+ ExposeCounters(ctx);
+ }
+
void StopWorking(const TActorContext& ctx) {
auto ev = TEvBlobStorage::TEvCollectGarbage::CreateHardBarrier(TabletId, Generation, GarbageCollectStep,
Channel, Generation, Max<ui32>(), TInstant::Max());
@@ -368,20 +368,20 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
ReadBytesInFlightQT.Add(now, 0);
}
- void UpdateQuantile(TInstant now) {
- ui64 speed;
+ void UpdateQuantile(TInstant now) {
+ ui64 speed;
MegabytesPerSecondST.Add(now, TotalBytesWritten);
- if (MegabytesPerSecondST.CalculateSpeed(&speed)) {
- MegabytesPerSecondQT.Add(now, speed);
- }
+ if (MegabytesPerSecondST.CalculateSpeed(&speed)) {
+ MegabytesPerSecondQT.Add(now, speed);
+ }
ReadMegabytesPerSecondST.Add(now, TotalBytesRead);
- if (ReadMegabytesPerSecondST.CalculateSpeed(&speed)) {
- ReadMegabytesPerSecondQT.Add(now, speed);
- }
- WritesInFlightQT.Add(now, WritesInFlight);
- WriteBytesInFlightQT.Add(now, WriteBytesInFlight);
- ReadsInFlightQT.Add(now, ReadsInFlight);
- ReadBytesInFlightQT.Add(now, ReadBytesInFlight);
+ if (ReadMegabytesPerSecondST.CalculateSpeed(&speed)) {
+ ReadMegabytesPerSecondQT.Add(now, speed);
+ }
+ WritesInFlightQT.Add(now, WritesInFlight);
+ WriteBytesInFlightQT.Add(now, WriteBytesInFlight);
+ ReadsInFlightQT.Add(now, ReadsInFlight);
+ ReadBytesInFlightQT.Add(now, ReadBytesInFlight);
if (now > LastLatencyTrackerUpdate + TDuration::Seconds(1)) {
LastLatencyTrackerUpdate = now;
ResponseQT.Update();
@@ -391,13 +391,13 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
*MaxInFlightLatency = maxLatency.MicroSeconds();
}
}
- }
-
- static TString PercentileName(int value) {
- return Sprintf("%d.%04d", value / 10000, value % 10000);
- }
-
- void ExposeCounters(const TActorContext &ctx) {
+ }
+
+ static TString PercentileName(int value) {
+ return Sprintf("%d.%04d", value / 10000, value % 10000);
+ }
+
+ void ExposeCounters(const TActorContext &ctx) {
MegabytesPerSecondQT.CalculateQuantiles();
ReadMegabytesPerSecondQT.CalculateQuantiles();
@@ -405,89 +405,89 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
WriteBytesInFlightQT.CalculateQuantiles();
ReadsInFlightQT.CalculateQuantiles();
ReadBytesInFlightQT.CalculateQuantiles();
-
- using namespace std::placeholders;
+
+ using namespace std::placeholders;
WakeupQueue.Put(TAppData::TimeProvider->Now() + ExposePeriod,
std::bind(&TTabletWriter::ExposeCounters, this, _1), ctx);
- }
-
+ }
+
void DumpState(IOutputStream& str) {
-#define DUMP_PARAM(NAME) \
- TABLER() { \
- TABLED() { str << #NAME; } \
- TABLED() { str << NAME; } \
- }
- HTML(str) {
- TDuration EarliestTimestamp = TDuration::Zero();
+#define DUMP_PARAM(NAME) \
+ TABLER() { \
+ TABLED() { str << #NAME; } \
+ TABLED() { str << NAME; } \
+ }
+ HTML(str) {
+ TDuration EarliestTimestamp = TDuration::Zero();
const ui64 nowCycles = GetCycleCountFast();
- for (const auto& [writeId, issued] : WritesInFlightTimestamps) {
- EarliestTimestamp = Max(EarliestTimestamp, CyclesToDuration(nowCycles - issued));
- }
-
- DUMP_PARAM(TabletId)
- DUMP_PARAM(Channel)
- DUMP_PARAM(Generation)
+ for (const auto& [writeId, issued] : WritesInFlightTimestamps) {
+ EarliestTimestamp = Max(EarliestTimestamp, CyclesToDuration(nowCycles - issued));
+ }
+
+ DUMP_PARAM(TabletId)
+ DUMP_PARAM(Channel)
+ DUMP_PARAM(Generation)
DUMP_PARAM(GarbageCollectStep)
- DUMP_PARAM(WriteStep)
- DUMP_PARAM(Cookie)
- DUMP_PARAM(GroupId)
- DUMP_PARAM(PutHandleClass)
+ DUMP_PARAM(WriteStep)
+ DUMP_PARAM(Cookie)
+ DUMP_PARAM(GroupId)
+ DUMP_PARAM(PutHandleClass)
DUMP_PARAM(GetHandleClass)
- if (EarliestTimestamp != TDuration::Zero()) {
- DUMP_PARAM(EarliestTimestamp)
- }
- DUMP_PARAM(NextWriteTimestamp)
- DUMP_PARAM(WritesInFlight)
- DUMP_PARAM(WriteBytesInFlight)
- DUMP_PARAM(MaxWritesInFlight)
- DUMP_PARAM(MaxWriteBytesInFlight)
- DUMP_PARAM(TotalBytesWritten)
+ if (EarliestTimestamp != TDuration::Zero()) {
+ DUMP_PARAM(EarliestTimestamp)
+ }
+ DUMP_PARAM(NextWriteTimestamp)
+ DUMP_PARAM(WritesInFlight)
+ DUMP_PARAM(WriteBytesInFlight)
+ DUMP_PARAM(MaxWritesInFlight)
+ DUMP_PARAM(MaxWriteBytesInFlight)
+ DUMP_PARAM(TotalBytesWritten)
DUMP_PARAM(MaxTotalBytesWritten)
- DUMP_PARAM(TotalBytesRead)
- DUMP_PARAM(NextReadTimestamp)
- DUMP_PARAM(ReadsInFlight)
- DUMP_PARAM(ReadBytesInFlight)
- DUMP_PARAM(MaxReadsInFlight)
- DUMP_PARAM(MaxReadBytesInFlight)
- DUMP_PARAM(ConfirmedBlobIds.size())
-
- static constexpr size_t count = 5;
- std::array<size_t, count> nums{{9000, 9900, 9990, 9999, 10000}};
- std::array<ui64, count> qSpeed;
- MegabytesPerSecondQT.CalculateQuantiles(count, nums.data(), 10000, qSpeed.data());
-
- TABLER() {
- TABLED() { str << "Writes per second"; }
- if (IssuedWriteTimestamp.size() > 1) {
+ DUMP_PARAM(TotalBytesRead)
+ DUMP_PARAM(NextReadTimestamp)
+ DUMP_PARAM(ReadsInFlight)
+ DUMP_PARAM(ReadBytesInFlight)
+ DUMP_PARAM(MaxReadsInFlight)
+ DUMP_PARAM(MaxReadBytesInFlight)
+ DUMP_PARAM(ConfirmedBlobIds.size())
+
+ static constexpr size_t count = 5;
+ std::array<size_t, count> nums{{9000, 9900, 9990, 9999, 10000}};
+ std::array<ui64, count> qSpeed;
+ MegabytesPerSecondQT.CalculateQuantiles(count, nums.data(), 10000, qSpeed.data());
+
+ TABLER() {
+ TABLED() { str << "Writes per second"; }
+ if (IssuedWriteTimestamp.size() > 1) {
const double rps = IssuedWriteTimestamp.size() /
(IssuedWriteTimestamp.back() - IssuedWriteTimestamp.front()).SecondsFloat();
- TABLED() { str << Sprintf("%.2lf", rps); }
- } else {
- TABLED() { str << "no writes"; }
- }
- }
-
- for (size_t i = 0; i < count; ++i) {
- TABLER() {
- TABLED() { str << Sprintf("Speed@ %d.%02d%%", int(nums[i] / 100), int(nums[i] % 100)); }
- ui64 x = qSpeed[i] * 100 / 1048576;
- TABLED() { str << Sprintf("%" PRIu64 ".%02d MB/s", x / 100, int(x % 100)); }
- }
- }
-
- ReadMegabytesPerSecondQT.CalculateQuantiles(count, nums.data(), 10000, qSpeed.data());
-
- for (size_t i = 0; i < count; ++i) {
- TABLER() {
- TABLED() { str << Sprintf("ReadSpeed@ %d.%02d%%", int(nums[i] / 100), int(nums[i] % 100)); }
- ui64 x = qSpeed[i] * 100 / 1048576;
- TABLED() { str << Sprintf("%" PRIu64 ".%02d MB/s", x / 100, int(x % 100)); }
- }
- }
- }
- }
-
- private:
+ TABLED() { str << Sprintf("%.2lf", rps); }
+ } else {
+ TABLED() { str << "no writes"; }
+ }
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ TABLER() {
+ TABLED() { str << Sprintf("Speed@ %d.%02d%%", int(nums[i] / 100), int(nums[i] % 100)); }
+ ui64 x = qSpeed[i] * 100 / 1048576;
+ TABLED() { str << Sprintf("%" PRIu64 ".%02d MB/s", x / 100, int(x % 100)); }
+ }
+ }
+
+ ReadMegabytesPerSecondQT.CalculateQuantiles(count, nums.data(), 10000, qSpeed.data());
+
+ for (size_t i = 0; i < count; ++i) {
+ TABLER() {
+ TABLED() { str << Sprintf("ReadSpeed@ %d.%02d%%", int(nums[i] / 100), int(nums[i] % 100)); }
+ ui64 x = qSpeed[i] * 100 / 1048576;
+ TABLED() { str << Sprintf("%" PRIu64 ".%02d MB/s", x / 100, int(x % 100)); }
+ }
+ }
+ }
+ }
+
+ private:
void UpdateNextWakeups(const TActorContext& ctx, const TInstant& now) {
if (now < NextWriteTimestamp && !NextWriteInQueue) {
using namespace std::placeholders;
@@ -502,24 +502,24 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
}
}
- void IssueWriteIfPossible(const TActorContext& ctx) {
+ void IssueWriteIfPossible(const TActorContext& ctx) {
const TInstant now = TAppData::TimeProvider->Now();
-
- while ((WritesInFlight < MaxWritesInFlight || !MaxWritesInFlight) &&
- (WriteBytesInFlight < MaxWriteBytesInFlight || !MaxWriteBytesInFlight) &&
+
+ while ((WritesInFlight < MaxWritesInFlight || !MaxWritesInFlight) &&
+ (WriteBytesInFlight < MaxWriteBytesInFlight || !MaxWriteBytesInFlight) &&
(TotalBytesWritten + WriteBytesInFlight < MaxTotalBytesWritten || !MaxTotalBytesWritten) &&
now >= NextWriteTimestamp &&
(!ScriptedRequests || ScriptedRequests[ScriptedCounter].EvType == TEvBlobStorage::EvPut)) {
- IssueWriteRequest(ctx, now);
- }
-
+ IssueWriteRequest(ctx, now);
+ }
+
if (ScriptedRequests) {
UpdateNextTimestemps(false);
}
UpdateNextWakeups(ctx, now);
- }
-
- void IssueWriteRequest(const TActorContext& ctx, TInstant now) {
+ }
+
+ void IssueWriteRequest(const TActorContext& ctx, TInstant now) {
ui32 size;
NKikimrBlobStorage::EPutHandleClass putHandleClass;
if (ScriptedRequests) {
@@ -530,73 +530,73 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
size = WriteSizeGen.Generate();
putHandleClass = PutHandleClass;
}
- const TLogoBlobID id(TabletId, Generation, WriteStep, Channel, size, Cookie);
- const TString buffer = GenerateBuffer(id);
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max(), putHandleClass);
- const ui64 writeQueryId = ++WriteQueryId;
-
- auto writeCallback = [this, writeQueryId](IEventBase *event, const TActorContext& ctx) {
- auto *res = dynamic_cast<TEvBlobStorage::TEvPutResult *>(event);
- Y_VERIFY(res);
- if (!CheckStatus(ctx, res, {})) {
+ const TLogoBlobID id(TabletId, Generation, WriteStep, Channel, size, Cookie);
+ const TString buffer = GenerateBuffer(id);
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max(), putHandleClass);
+ const ui64 writeQueryId = ++WriteQueryId;
+
+ auto writeCallback = [this, writeQueryId](IEventBase *event, const TActorContext& ctx) {
+ auto *res = dynamic_cast<TEvBlobStorage::TEvPutResult *>(event);
+ Y_VERIFY(res);
+ if (!CheckStatus(ctx, res, {})) {
return;
}
-
- const TLogoBlobID& id = res->Id;
- const ui32 size = id.BlobSize();
-
- // this blob has been confirmed -- update set
- if (!ConfirmedBlobIds || id > ConfirmedBlobIds.back()) {
- ConfirmedBlobIds.push_back(id);
- } else {
- // most likely inserted somewhere near the end
- ConfirmedBlobIds.insert(std::lower_bound(ConfirmedBlobIds.begin(), ConfirmedBlobIds.end(), id), id);
- }
-
- Y_VERIFY(WritesInFlight >= 1 && WriteBytesInFlight >= size);
- --WritesInFlight;
- WriteBytesInFlight -= size;
-
- TotalBytesWritten += size;
-
- auto it = SentTimestamp.find(writeQueryId);
+
+ const TLogoBlobID& id = res->Id;
+ const ui32 size = id.BlobSize();
+
+ // this blob has been confirmed -- update set
+ if (!ConfirmedBlobIds || id > ConfirmedBlobIds.back()) {
+ ConfirmedBlobIds.push_back(id);
+ } else {
+ // most likely inserted somewhere near the end
+ ConfirmedBlobIds.insert(std::lower_bound(ConfirmedBlobIds.begin(), ConfirmedBlobIds.end(), id), id);
+ }
+
+ Y_VERIFY(WritesInFlight >= 1 && WriteBytesInFlight >= size);
+ --WritesInFlight;
+ WriteBytesInFlight -= size;
+
+ TotalBytesWritten += size;
+
+ auto it = SentTimestamp.find(writeQueryId);
const auto sendCycles = it->second;
- Y_VERIFY(it != SentTimestamp.end());
+ Y_VERIFY(it != SentTimestamp.end());
const TDuration response = CyclesToDuration(GetCycleCountFast() - sendCycles);
- SentTimestamp.erase(it);
-
+ SentTimestamp.erase(it);
+
// It's very likely that "writeQueryId" will be found at the start
auto itInFlight = Find(WritesInFlightTimestamps, std::make_pair(writeQueryId, sendCycles));
Y_VERIFY(itInFlight != WritesInFlightTimestamps.end());
WritesInFlightTimestamps.erase(itInFlight);
ResponseQT.Increment(response.MicroSeconds());
- IssueWriteIfPossible(ctx);
-
- if (ConfirmedBlobIds.size() == 1) {
- if (NextReadTimestamp == TInstant()) {
+ IssueWriteIfPossible(ctx);
+
+ if (ConfirmedBlobIds.size() == 1) {
+ if (NextReadTimestamp == TInstant()) {
NextReadTimestamp = TAppData::TimeProvider->Now();
- }
- IssueReadIfPossible(ctx);
- }
- };
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(writeCallback)));
+ }
+ IssueReadIfPossible(ctx);
+ }
+ };
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(writeCallback)));
const auto nowCycles = GetCycleCountFast();
WritesInFlightTimestamps.emplace_back(writeQueryId, nowCycles);
SentTimestamp.emplace(writeQueryId, nowCycles);
IssuedWriteTimestamp.push_back(TAppData::TimeProvider->Now());
- while (IssuedWriteTimestamp.size() > 10000 || IssuedWriteTimestamp.back() - IssuedWriteTimestamp.front() >= TDuration::Seconds(5)) {
- IssuedWriteTimestamp.pop_front();
- }
-
- ++Cookie;
-
- ++WritesInFlight;
- WriteBytesInFlight += size;
-
+ while (IssuedWriteTimestamp.size() > 10000 || IssuedWriteTimestamp.back() - IssuedWriteTimestamp.front() >= TDuration::Seconds(5)) {
+ IssuedWriteTimestamp.pop_front();
+ }
+
+ ++Cookie;
+
+ ++WritesInFlight;
+ WriteBytesInFlight += size;
+
if (ScriptedRequests) {
UpdateNextTimestemps(true);
- } else {
+ } else {
// calculate time of next write request
TDuration duration = WriteIntervalGen.Generate();
if (Soft) {
@@ -604,11 +604,11 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
} else {
NextWriteTimestamp = now + duration;
}
- }
-
- NextWriteInQueue = false;
- }
+ }
+ NextWriteInQueue = false;
+ }
+
void UpdateNextTimestemps(bool incrementCounter) {
Y_VERIFY(ScriptedRequests);
@@ -636,55 +636,55 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
void ScheduleGarbageCollect(const TActorContext& ctx) {
TDuration duration = GarbageCollectIntervalGen.Generate();
- if (duration != TDuration()) {
- using namespace std::placeholders;
+ if (duration != TDuration()) {
+ using namespace std::placeholders;
WakeupQueue.Put(TAppData::TimeProvider->Now() + duration,
std::bind(&TTabletWriter::IssueGarbageCollectRequest, this, _1), ctx);
- }
- }
-
+ }
+ }
+
void IssueGarbageCollectRequest(const TActorContext& ctx) {
- auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, Generation, GarbageCollectStep, Channel,
+ auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, Generation, GarbageCollectStep, Channel,
true, Generation, GarbageCollectStep, nullptr, nullptr, TInstant::Max(), false);
- auto callback = [](IEventBase *event, const TActorContext& /*ctx*/) {
- auto *res = dynamic_cast<TEvBlobStorage::TEvCollectGarbageResult *>(event);
- Y_VERIFY(res);
- };
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
-
- // just as we have sent this request, we have to trim all confirmed blobs which are going to be deleted
- const auto it = std::lower_bound(ConfirmedBlobIds.begin(), ConfirmedBlobIds.end(),
+ auto callback = [](IEventBase *event, const TActorContext& /*ctx*/) {
+ auto *res = dynamic_cast<TEvBlobStorage::TEvCollectGarbageResult *>(event);
+ Y_VERIFY(res);
+ };
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(callback)));
+
+ // just as we have sent this request, we have to trim all confirmed blobs which are going to be deleted
+ const auto it = std::lower_bound(ConfirmedBlobIds.begin(), ConfirmedBlobIds.end(),
TLogoBlobID(TabletId, Generation, GarbageCollectStep, Channel, TLogoBlobID::MaxBlobSize,
- TLogoBlobID::MaxCookie, TLogoBlobID::MaxPartId));
- ConfirmedBlobIds.erase(ConfirmedBlobIds.begin(), it);
-
+ TLogoBlobID::MaxCookie, TLogoBlobID::MaxPartId));
+ ConfirmedBlobIds.erase(ConfirmedBlobIds.begin(), it);
+
++GarbageCollectStep;
- ++WriteStep;
- Cookie = 1;
+ ++WriteStep;
+ Cookie = 1;
ScheduleGarbageCollect(ctx);
- }
-
- void IssueReadIfPossible(const TActorContext& ctx) {
+ }
+
+ void IssueReadIfPossible(const TActorContext& ctx) {
const TInstant now = TAppData::TimeProvider->Now();
-
+
while (ReadsInFlight < MaxReadsInFlight &&
(ReadBytesInFlight < MaxReadBytesInFlight || !MaxReadBytesInFlight) &&
now >= NextReadTimestamp &&
ConfirmedBlobIds &&
(!ScriptedRequests || ScriptedRequests[ScriptedCounter].EvType == TEvBlobStorage::EvGet)) {
- IssueReadRequest(ctx, now);
- }
-
+ IssueReadRequest(ctx, now);
+ }
+
if (ScriptedRequests) {
UpdateNextTimestemps(false);
}
UpdateNextWakeups(ctx, now);
- }
-
- void IssueReadRequest(const TActorContext& ctx, TInstant now) {
- auto iter = ConfirmedBlobIds.begin();
- std::advance(iter, RandomNumber(ConfirmedBlobIds.size()));
- const TLogoBlobID &id = *iter;
+ }
+
+ void IssueReadRequest(const TActorContext& ctx, TInstant now) {
+ auto iter = ConfirmedBlobIds.begin();
+ std::advance(iter, RandomNumber(ConfirmedBlobIds.size()));
+ const TLogoBlobID &id = *iter;
ui32 size;
if (ScriptedRequests) {
@@ -695,130 +695,130 @@ class TLogWriterTestLoadActor : public TActorBootstrapped<TLogWriterTestLoadActo
}
size = Min(size, id.BlobSize());
- const ui32 offset = RandomNumber<ui32>(id.BlobSize() - size + 1);
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(id, offset, size, TInstant::Max(),
+ const ui32 offset = RandomNumber<ui32>(id.BlobSize() - size + 1);
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(id, offset, size, TInstant::Max(),
GetHandleClass);
- const ui64 readQueryId = ++ReadQueryId;
-
- auto readCallback = [this, size, readQueryId](IEventBase *event, const TActorContext& ctx) {
- auto *res = dynamic_cast<TEvBlobStorage::TEvGetResult*>(event);
- Y_VERIFY(res);
+ const ui64 readQueryId = ++ReadQueryId;
+
+ auto readCallback = [this, size, readQueryId](IEventBase *event, const TActorContext& ctx) {
+ auto *res = dynamic_cast<TEvBlobStorage::TEvGetResult*>(event);
+ Y_VERIFY(res);
if (!CheckStatus(ctx, res, {NKikimrProto::EReplyStatus::OK})) {
return;
}
-
- Y_VERIFY(ReadsInFlight >= 1 && ReadBytesInFlight >= size);
- --ReadsInFlight;
- ReadBytesInFlight -= size;
+
+ Y_VERIFY(ReadsInFlight >= 1 && ReadBytesInFlight >= size);
+ --ReadsInFlight;
+ ReadBytesInFlight -= size;
TotalBytesRead += size;
-
- auto it = ReadSentTimestamp.find(readQueryId);
- Y_VERIFY(it != ReadSentTimestamp.end());
+
+ auto it = ReadSentTimestamp.find(readQueryId);
+ Y_VERIFY(it != ReadSentTimestamp.end());
const TDuration response = CyclesToDuration(GetCycleCountFast() - it->second);
- ReadSentTimestamp.erase(it);
-
+ ReadSentTimestamp.erase(it);
+
ReadResponseQT.Increment(response.MicroSeconds());
- IssueReadIfPossible(ctx);
- };
-
- SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(readCallback)));
+ IssueReadIfPossible(ctx);
+ };
+
+ SendToBSProxy(ctx, GroupId, ev.release(), QueryDispatcher.ObtainCookie(std::move(readCallback)));
ReadSentTimestamp.emplace(readQueryId, GetCycleCountFast());
-
- ++ReadsInFlight;
- ReadBytesInFlight += size;
-
- // calculate time of next write request
+
+ ++ReadsInFlight;
+ ReadBytesInFlight += size;
+
+ // calculate time of next write request
if (ScriptedRequests) {
UpdateNextTimestemps(true);
- } else {
+ } else {
TDuration duration = ReadIntervalGen.Generate();
if (Soft) {
NextReadTimestamp += duration;
} else {
NextReadTimestamp = now + duration;
}
- }
- NextReadInQueue = false;
- }
-
- static TString GenerateBuffer(const TLogoBlobID& id) {
+ }
+ NextReadInQueue = false;
+ }
+
+ static TString GenerateBuffer(const TLogoBlobID& id) {
return GenDataForLZ4(id.BlobSize());
- }
- };
-
+ }
+ };
+
TString ConfingString;
- const ui64 Tag;
+ const ui64 Tag;
const TActorId Parent;
-
- TMaybe<TDuration> TestDuration;
-
+
+ TMaybe<TDuration> TestDuration;
+
TVector<TTabletWriter> TabletWriters;
-
- TWakeupQueue WakeupQueue;
- TDeque<TInstant> WakeupScheduledAt;
- TDuration WakeupRounding = TDuration::MicroSeconds(50);
- TDuration WakeupScheduleThreshold = TDuration::Max();
-
- TQueryDispatcher QueryDispatcher;
-
- NMonitoring::TDynamicCounters::TCounterPtr ScheduleCounter;
-
+
+ TWakeupQueue WakeupQueue;
+ TDeque<TInstant> WakeupScheduledAt;
+ TDuration WakeupRounding = TDuration::MicroSeconds(50);
+ TDuration WakeupScheduleThreshold = TDuration::Max();
+
+ TQueryDispatcher QueryDispatcher;
+
+ NMonitoring::TDynamicCounters::TCounterPtr ScheduleCounter;
+
ui32 TestStoppedRecieved = 0;
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LOAD_ACTOR;
- }
-
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LOAD_ACTOR;
+ }
+
TLogWriterTestLoadActor(const NKikimrBlobStorage::TEvTestLoadRequest::TLoadStart& cmd, const TActorId& parent,
TIntrusivePtr<NMonitoring::TDynamicCounters> counters, ui64 tag)
: Tag(tag)
- , Parent(parent)
- , ScheduleCounter(counters->GetSubgroup("subsystem", "scheduler")->GetCounter("ScheduleCounter", true))
- {
+ , Parent(parent)
+ , ScheduleCounter(counters->GetSubgroup("subsystem", "scheduler")->GetCounter("ScheduleCounter", true))
+ {
google::protobuf::TextFormat::PrintToString(cmd, &ConfingString);
- if (cmd.HasDurationSeconds()) {
- TestDuration = TDuration::Seconds(cmd.GetDurationSeconds());
- }
- for (const auto& profile : cmd.GetTablets()) {
- if (!profile.TabletsSize()) {
- ythrow TLoadActorException() << "TPerTabletProfile.Tablets must have at least one item";
- }
- if (!profile.SizesSize()) {
- ythrow TLoadActorException() << "TPerTabletProfile.Sizes must have at least one item";
- }
- if (!profile.WriteIntervalsSize()) {
- ythrow TLoadActorException() << "TPerTabletProfile.WriteIntervals must have at least one item";
- }
-
- if (!profile.HasPutHandleClass()) {
- ythrow TLoadActorException() << "missing mandatory TPerTabletProfile.PutHandleClass";
- }
- NKikimrBlobStorage::EPutHandleClass putHandleClass = profile.GetPutHandleClass();
-
-
- TSizeGenerator writeSizeGen(profile.GetSizes());
- TIntervalGenerator writeIntervalGen(profile.GetWriteIntervals());
+ if (cmd.HasDurationSeconds()) {
+ TestDuration = TDuration::Seconds(cmd.GetDurationSeconds());
+ }
+ for (const auto& profile : cmd.GetTablets()) {
+ if (!profile.TabletsSize()) {
+ ythrow TLoadActorException() << "TPerTabletProfile.Tablets must have at least one item";
+ }
+ if (!profile.SizesSize()) {
+ ythrow TLoadActorException() << "TPerTabletProfile.Sizes must have at least one item";
+ }
+ if (!profile.WriteIntervalsSize()) {
+ ythrow TLoadActorException() << "TPerTabletProfile.WriteIntervals must have at least one item";
+ }
+
+ if (!profile.HasPutHandleClass()) {
+ ythrow TLoadActorException() << "missing mandatory TPerTabletProfile.PutHandleClass";
+ }
+ NKikimrBlobStorage::EPutHandleClass putHandleClass = profile.GetPutHandleClass();
+
+
+ TSizeGenerator writeSizeGen(profile.GetSizes());
+ TIntervalGenerator writeIntervalGen(profile.GetWriteIntervals());
TIntervalGenerator garbageCollectIntervalGen(profile.GetFlushIntervals());
-
- const ui32 maxWritesInFlight = profile.GetMaxInFlightRequests();
- const ui64 maxWriteBytesInFlight = profile.GetMaxInFlightBytes();
+
+ const ui32 maxWritesInFlight = profile.GetMaxInFlightRequests();
+ const ui64 maxWriteBytesInFlight = profile.GetMaxInFlightBytes();
ui64 maxTotalBytesWritten = 0;
if (profile.HasMaxTotalBytesWritten()) {
maxTotalBytesWritten = profile.GetMaxTotalBytesWritten();
}
- const bool soft = profile.GetSoft();
-
+ const bool soft = profile.GetSoft();
+
NKikimrBlobStorage::EGetHandleClass getHandleClass = NKikimrBlobStorage::EGetHandleClass::FastRead;
if (profile.HasGetHandleClass()) {
getHandleClass = profile.GetGetHandleClass();
}
- TSizeGenerator readSizeGen(profile.GetReadSizes());
- TIntervalGenerator readIntervalGen(profile.GetReadIntervals());
- const ui32 maxReadsInFlight = profile.GetMaxInFlightReadRequests();
- const ui64 maxReadBytesInFlight = profile.GetMaxInFlightReadBytes();
-
- for (const auto& tablet : profile.GetTablets()) {
+ TSizeGenerator readSizeGen(profile.GetReadSizes());
+ TIntervalGenerator readIntervalGen(profile.GetReadIntervals());
+ const ui32 maxReadsInFlight = profile.GetMaxInFlightReadRequests();
+ const ui64 maxReadBytesInFlight = profile.GetMaxInFlightReadBytes();
+
+ for (const auto& tablet : profile.GetTablets()) {
auto scriptedRoundDuration = TDuration::MicroSeconds(tablet.GetScriptedCycleDurationSec() * 1e6);
TVector<TReqInfo> scriptedRequests;
for (const auto& req : tablet.GetRequests()) {
@@ -830,37 +830,37 @@ public:
});
}
- if (!tablet.HasTabletId() || !tablet.HasChannel() || !tablet.HasGroupId()) {
- ythrow TLoadActorException() << "TTabletInfo.{TabletId,Channel,GroupId} fields are mandatory";
- }
- TabletWriters.emplace_back(Tag, counters, WakeupQueue, QueryDispatcher, tablet.GetTabletId(),
- tablet.GetChannel(), tablet.HasGeneration() ? TMaybe<ui32>(tablet.GetGeneration()) : TMaybe<ui32>(),
+ if (!tablet.HasTabletId() || !tablet.HasChannel() || !tablet.HasGroupId()) {
+ ythrow TLoadActorException() << "TTabletInfo.{TabletId,Channel,GroupId} fields are mandatory";
+ }
+ TabletWriters.emplace_back(Tag, counters, WakeupQueue, QueryDispatcher, tablet.GetTabletId(),
+ tablet.GetChannel(), tablet.HasGeneration() ? TMaybe<ui32>(tablet.GetGeneration()) : TMaybe<ui32>(),
tablet.GetGroupId(), putHandleClass, writeSizeGen, writeIntervalGen, garbageCollectIntervalGen,
maxWritesInFlight, maxWriteBytesInFlight, maxTotalBytesWritten, soft,
getHandleClass, readSizeGen, readIntervalGen,
maxReadsInFlight, maxReadBytesInFlight, scriptedRoundDuration, std::move(scriptedRequests));
- }
- }
- if (cmd.HasScheduleThresholdUs()) {
- WakeupScheduleThreshold = TDuration::MicroSeconds(cmd.GetScheduleThresholdUs());
- }
- if (cmd.HasScheduleRoundingUs()) {
- WakeupRounding = TDuration::MicroSeconds(cmd.GetScheduleRoundingUs());
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TLogWriterTestLoadActor::StateFunc);
- if (TestDuration) {
+ }
+ }
+ if (cmd.HasScheduleThresholdUs()) {
+ WakeupScheduleThreshold = TDuration::MicroSeconds(cmd.GetScheduleThresholdUs());
+ }
+ if (cmd.HasScheduleRoundingUs()) {
+ WakeupRounding = TDuration::MicroSeconds(cmd.GetScheduleRoundingUs());
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TLogWriterTestLoadActor::StateFunc);
+ if (TestDuration) {
ctx.Schedule(*TestDuration, new TEvents::TEvPoisonPill());
- }
+ }
for (auto& writer : TabletWriters) {
- writer.Bootstrap(ctx);
- }
- HandleWakeup(ctx);
- HandleUpdateQuantile(ctx);
- }
-
+ writer.Bootstrap(ctx);
+ }
+ HandleWakeup(ctx);
+ HandleUpdateQuantile(ctx);
+ }
+
void HandlePoison(const TActorContext& ctx) {
LOG_DEBUG_S(ctx, NKikimrServices::BS_LOAD_TEST, "Load tablet recieved PoisonPill, going to die");
for (auto& writer : TabletWriters) {
@@ -868,111 +868,111 @@ public:
}
}
- void HandleStopTest(const TActorContext& ctx) {
+ void HandleStopTest(const TActorContext& ctx) {
++TestStoppedRecieved;
if (TestStoppedRecieved == TabletWriters.size()) {
ctx.Send(Parent, new TEvTestLoadFinished(Tag, nullptr, "HandleStopTest"));
Die(ctx);
}
- }
-
- void HandleUpdateQuantile(const TActorContext& ctx) {
+ }
+
+ void HandleUpdateQuantile(const TActorContext& ctx) {
TInstant now = TAppData::TimeProvider->Now();
for (auto& writer : TabletWriters) {
- writer.UpdateQuantile(now);
- }
- ctx.Schedule(TDuration::MilliSeconds(5), new TEvUpdateQuantile);
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- // erase all scheduled items before this time point, including it
- WakeupScheduledAt.erase(WakeupScheduledAt.begin(), std::upper_bound(WakeupScheduledAt.begin(),
+ writer.UpdateQuantile(now);
+ }
+ ctx.Schedule(TDuration::MilliSeconds(5), new TEvUpdateQuantile);
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ // erase all scheduled items before this time point, including it
+ WakeupScheduledAt.erase(WakeupScheduledAt.begin(), std::upper_bound(WakeupScheduledAt.begin(),
WakeupScheduledAt.end(), TAppData::TimeProvider->Now()));
- WakeupQueue.Wakeup(ctx);
- ScheduleWakeup(ctx);
- }
-
- // schedule next wakeup event according to wakeup queue; should be called in any event handler that can potentially
- // touch wakeup queue
- void ScheduleWakeup(const TActorContext& ctx) {
- TMaybe<TInstant> nextWakeupTime = WakeupQueue.GetNextWakeupTime();
- // round up scheduler time to wakeup rounding time
- if (nextWakeupTime && WakeupRounding != TDuration::Zero()) {
- ui64 value = nextWakeupTime->GetValue();
- if (const ui64 delta = value % WakeupRounding.GetValue()) {
- value += WakeupRounding.GetValue() - delta;
- }
+ WakeupQueue.Wakeup(ctx);
+ ScheduleWakeup(ctx);
+ }
+
+ // schedule next wakeup event according to wakeup queue; should be called in any event handler that can potentially
+ // touch wakeup queue
+ void ScheduleWakeup(const TActorContext& ctx) {
+ TMaybe<TInstant> nextWakeupTime = WakeupQueue.GetNextWakeupTime();
+ // round up scheduler time to wakeup rounding time
+ if (nextWakeupTime && WakeupRounding != TDuration::Zero()) {
+ ui64 value = nextWakeupTime->GetValue();
+ if (const ui64 delta = value % WakeupRounding.GetValue()) {
+ value += WakeupRounding.GetValue() - delta;
+ }
nextWakeupTime = TInstant::MicroSeconds(value);
- }
- const TInstant scheduledWakeupTime = WakeupScheduledAt ? WakeupScheduledAt.front() : TInstant::Max();
- if (nextWakeupTime && *nextWakeupTime < scheduledWakeupTime) {
- WakeupScheduledAt.push_front(*nextWakeupTime);
+ }
+ const TInstant scheduledWakeupTime = WakeupScheduledAt ? WakeupScheduledAt.front() : TInstant::Max();
+ if (nextWakeupTime && *nextWakeupTime < scheduledWakeupTime) {
+ WakeupScheduledAt.push_front(*nextWakeupTime);
TDuration delta = *nextWakeupTime - TAppData::TimeProvider->Now();
- if (delta >= WakeupScheduleThreshold) {
- ctx.Schedule(delta, new TEvents::TEvWakeup);
- } else {
- ctx.Send(ctx.SelfID, new TEvents::TEvWakeup);
- }
- ++*ScheduleCounter;
- }
- }
-
- template<typename TPtr>
- void HandleDispatcher(TPtr& ev, const TActorContext& ctx) {
- QueryDispatcher.ProcessEvent(ev, ctx);
- HandleWakeup(ctx);
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- TStringStream str;
+ if (delta >= WakeupScheduleThreshold) {
+ ctx.Schedule(delta, new TEvents::TEvWakeup);
+ } else {
+ ctx.Send(ctx.SelfID, new TEvents::TEvWakeup);
+ }
+ ++*ScheduleCounter;
+ }
+ }
+
+ template<typename TPtr>
+ void HandleDispatcher(TPtr& ev, const TActorContext& ctx) {
+ QueryDispatcher.ProcessEvent(ev, ctx);
+ HandleWakeup(ctx);
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ TStringStream str;
HTML(str) {
- TABLE_CLASS("table table-condensed") {
+ TABLE_CLASS("table table-condensed") {
TABLEHEAD() {
TABLER() {
- TABLEH() {
- str << "Parameter";
- }
- TABLEH() {
- str << "Value";
- }
+ TABLEH() {
+ str << "Parameter";
+ }
+ TABLEH() {
+ str << "Value";
+ }
}
}
TABLEBODY() {
for (auto& writer : TabletWriters) {
- str << "<tr><td colspan=\"2\">" << "<b>Tablet</b>" << "</td></tr>";
- writer.DumpState(str);
- }
+ str << "<tr><td colspan=\"2\">" << "<b>Tablet</b>" << "</td></tr>";
+ writer.DumpState(str);
+ }
}
}
COLLAPSED_BUTTON_CONTENT(Sprintf("configProtobuf%" PRIu64, Tag), "Config") {
str << "<pre>" << ConfingString << "</pre>";
}
}
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& /*ctx*/) {
- Y_FAIL("TEvUndelivered# 0x%08" PRIx32 " ActorId# %s", ev->Get()->SourceType, ev->Sender.ToString().data());
- }
-
- STRICT_STFUNC(StateFunc,
- CFunc(EvStopTest, HandleStopTest);
- CFunc(EvUpdateQuantile, HandleUpdateQuantile);
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& /*ctx*/) {
+ Y_FAIL("TEvUndelivered# 0x%08" PRIx32 " ActorId# %s", ev->Get()->SourceType, ev->Sender.ToString().data());
+ }
+
+ STRICT_STFUNC(StateFunc,
+ CFunc(EvStopTest, HandleStopTest);
+ CFunc(EvUpdateQuantile, HandleUpdateQuantile);
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
CFunc(TEvents::TSystem::PoisonPill, HandlePoison);
HFunc(TEvBlobStorage::TEvDiscoverResult, HandleDispatcher);
HFunc(TEvBlobStorage::TEvBlockResult, HandleDispatcher);
- HFunc(TEvBlobStorage::TEvPutResult, HandleDispatcher);
- HFunc(TEvBlobStorage::TEvGetResult, HandleDispatcher);
- HFunc(TEvBlobStorage::TEvCollectGarbageResult, HandleDispatcher);
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvents::TEvUndelivered, Handle);
- )
-};
-
+ HFunc(TEvBlobStorage::TEvPutResult, HandleDispatcher);
+ HFunc(TEvBlobStorage::TEvGetResult, HandleDispatcher);
+ HFunc(TEvBlobStorage::TEvCollectGarbageResult, HandleDispatcher);
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvents::TEvUndelivered, Handle);
+ )
+};
+
IActor *CreateWriterTestLoad(const NKikimrBlobStorage::TEvTestLoadRequest::TLoadStart& cmd, const TActorId& parent,
TIntrusivePtr<NMonitoring::TDynamicCounters> counters, ui64 tag) {
return new TLogWriterTestLoadActor(cmd, parent, std::move(counters), tag);
-}
-
-} // NKikimr
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/ut_blobstorage/big_cluster.cpp b/ydb/core/blobstorage/ut_blobstorage/big_cluster.cpp
index 6262ee3e955..ffc1f9d0f96 100644
--- a/ydb/core/blobstorage/ut_blobstorage/big_cluster.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/big_cluster.cpp
@@ -1,20 +1,20 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(BigCluster) {
-
- Y_UNIT_TEST(Test) {
- for (ui32 num : {10, 100}) {
- THPTimer timer;
- {
- TEnvironmentSetup env(num, nullptr);
- env.CreateBoxAndPool(4, 4 * 8 * num);
- env.Cleanup();
- Cerr << "num# " << num << " restart" << Endl;
- env.Initialize();
- env.Sim(TDuration::Minutes(5));
- }
- Cerr << "num# " << num << " passed# " << TDuration::Seconds(timer.Passed()) << Endl;
- }
- }
-
-}
+
+Y_UNIT_TEST_SUITE(BigCluster) {
+
+ Y_UNIT_TEST(Test) {
+ for (ui32 num : {10, 100}) {
+ THPTimer timer;
+ {
+ TEnvironmentSetup env(num, nullptr);
+ env.CreateBoxAndPool(4, 4 * 8 * num);
+ env.Cleanup();
+ Cerr << "num# " << num << " restart" << Endl;
+ env.Initialize();
+ env.Sim(TDuration::Minutes(5));
+ }
+ Cerr << "num# " << num << " passed# " << TDuration::Seconds(timer.Passed()) << Endl;
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/block_race.cpp b/ydb/core/blobstorage/ut_blobstorage/block_race.cpp
index daa06c90872..fe85f3da555 100644
--- a/ydb/core/blobstorage/ut_blobstorage/block_race.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/block_race.cpp
@@ -1,49 +1,49 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
-
-Y_UNIT_TEST_SUITE(BlobStorageBlockRace) {
- Y_UNIT_TEST(Test) {
- TEnvironmentSetup env{{
- .NodeCount = 8,
- .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
- }};
- auto& runtime = env.Runtime;
-
- env.CreateBoxAndPool(1, 1);
- auto groups = env.GetGroups();
- UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
- const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
-
- auto sendBlock = [&](ui32 orderNum, ui64 tabletId, ui64 guid) {
- const TVDiskID vdiskId = info->GetVDiskId(orderNum);
-
- NKikimrProto::EReplyStatus status;
-
- env.WithQueueId(vdiskId, NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](const TActorId& queueId) {
- const TActorId edge = runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- runtime->Send(new IEventHandle(queueId, edge, new TEvBlobStorage::TEvVBlock(tabletId, 1, vdiskId,
- TInstant::Max(), guid)), edge.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVBlockResult>(edge);
- status = res->Get()->Record.GetStatus();
- });
-
- return status;
- };
-
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 1, 0), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 1, 0), NKikimrProto::ALREADY);
- env.Sim(TDuration::Seconds(10));
- for (ui32 orderNum = 1; orderNum < info->GetTotalVDisksNum(); ++orderNum) {
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 1, 0), NKikimrProto::ALREADY);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 2, 1), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 2, 1), NKikimrProto::OK);
- env.Sim(TDuration::Seconds(10));
- for (ui32 orderNum = 1; orderNum < info->GetTotalVDisksNum(); ++orderNum) {
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 0), NKikimrProto::ALREADY);
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 1), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 2), NKikimrProto::ALREADY);
- }
- }
-}
+
+Y_UNIT_TEST_SUITE(BlobStorageBlockRace) {
+ Y_UNIT_TEST(Test) {
+ TEnvironmentSetup env{{
+ .NodeCount = 8,
+ .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
+ }};
+ auto& runtime = env.Runtime;
+
+ env.CreateBoxAndPool(1, 1);
+ auto groups = env.GetGroups();
+ UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
+ const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
+
+ auto sendBlock = [&](ui32 orderNum, ui64 tabletId, ui64 guid) {
+ const TVDiskID vdiskId = info->GetVDiskId(orderNum);
+
+ NKikimrProto::EReplyStatus status;
+
+ env.WithQueueId(vdiskId, NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](const TActorId& queueId) {
+ const TActorId edge = runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
+ runtime->Send(new IEventHandle(queueId, edge, new TEvBlobStorage::TEvVBlock(tabletId, 1, vdiskId,
+ TInstant::Max(), guid)), edge.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVBlockResult>(edge);
+ status = res->Get()->Record.GetStatus();
+ });
+
+ return status;
+ };
+
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 1, 0), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 1, 0), NKikimrProto::ALREADY);
+ env.Sim(TDuration::Seconds(10));
+ for (ui32 orderNum = 1; orderNum < info->GetTotalVDisksNum(); ++orderNum) {
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 1, 0), NKikimrProto::ALREADY);
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 2, 1), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(0, 2, 1), NKikimrProto::OK);
+ env.Sim(TDuration::Seconds(10));
+ for (ui32 orderNum = 1; orderNum < info->GetTotalVDisksNum(); ++orderNum) {
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 0), NKikimrProto::ALREADY);
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 1), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(sendBlock(orderNum, 2, 2), NKikimrProto::ALREADY);
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/counting_events.cpp b/ydb/core/blobstorage/ut_blobstorage/counting_events.cpp
index 1f1b9e27be5..220b67a56e6 100644
--- a/ydb/core/blobstorage/ut_blobstorage/counting_events.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/counting_events.cpp
@@ -14,10 +14,10 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
void SendPut(const TTestInfo &test, const TLogoBlobID &blobId, const TString &data,
NKikimrProto::EReplyStatus status)
{
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPut>(blobId, data, TInstant::Max());
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPut>(blobId, data, TInstant::Max());
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
@@ -29,9 +29,9 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
void SendGet(const TTestInfo &test, const TLogoBlobID &blobId, const TString &data,
NKikimrProto::EReplyStatus status)
{
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvGet>(blobId, 0, 0, TInstant::Max(), NKikimrBlobStorage::AsyncRead);
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvGet>(blobId, 0, 0, TInstant::Max(), NKikimrBlobStorage::AsyncRead);
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvGetResult);
@@ -45,10 +45,10 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
void SendCollect(const TTestInfo &test, const TLogoBlobID &blobId,
NKikimrProto::EReplyStatus status)
{
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(blobId.TabletID(), blobId.Generation(),
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(blobId.TabletID(), blobId.Generation(),
blobId.Step(), blobId.Channel(), true, blobId.Generation(), blobId.Step(), nullptr, nullptr, TInstant::Max(), false);
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvCollectGarbageResult);
@@ -118,7 +118,7 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
NormalizePredictedDelays(queues);
SendPut(test, originalBlobId2, data, NKikimrProto::OK);
finishEventsCount = test.Runtime->GetEventsProcessed();
-
+
UNIT_ASSERT_VALUES_EQUAL(finishEventsCount - startEventsCount, eventsCount);
startEventsCount = test.Runtime->GetEventsProcessed();
@@ -164,15 +164,15 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
}
Y_UNIT_TEST(Put_Mirror3of4) {
- CountingEventsTest("put", 116, TBlobStorageGroupType::ErasureMirror3of4);
+ CountingEventsTest("put", 116, TBlobStorageGroupType::ErasureMirror3of4);
}
Y_UNIT_TEST(Put_Mirror3dc) {
- CountingEventsTest("put", 49, TBlobStorageGroupType::ErasureMirror3dc);
+ CountingEventsTest("put", 49, TBlobStorageGroupType::ErasureMirror3dc);
}
Y_UNIT_TEST(Put_Block42) {
- CountingEventsTest("put", 89, TBlobStorageGroupType::Erasure4Plus2Block);
+ CountingEventsTest("put", 89, TBlobStorageGroupType::Erasure4Plus2Block);
}
Y_UNIT_TEST(Put_None) {
@@ -180,7 +180,7 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
}
Y_UNIT_TEST(Get_Mirror3of4) {
- CountingEventsTest("get", 38, TBlobStorageGroupType::ErasureMirror3of4);
+ CountingEventsTest("get", 38, TBlobStorageGroupType::ErasureMirror3of4);
}
Y_UNIT_TEST(Get_Mirror3dc) {
@@ -188,7 +188,7 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
}
Y_UNIT_TEST(Get_Block42) {
- CountingEventsTest("get", 69, TBlobStorageGroupType::Erasure4Plus2Block);
+ CountingEventsTest("get", 69, TBlobStorageGroupType::Erasure4Plus2Block);
}
Y_UNIT_TEST(Get_None) {
@@ -196,15 +196,15 @@ Y_UNIT_TEST_SUITE(CountingEvents) {
}
Y_UNIT_TEST(Collect_Mirror3of4) {
- CountingEventsTest("collect", 113, TBlobStorageGroupType::ErasureMirror3of4);
+ CountingEventsTest("collect", 113, TBlobStorageGroupType::ErasureMirror3of4);
}
-
+
Y_UNIT_TEST(Collect_Mirror3dc) {
- CountingEventsTest("collect", 124, TBlobStorageGroupType::ErasureMirror3dc);
+ CountingEventsTest("collect", 124, TBlobStorageGroupType::ErasureMirror3dc);
}
Y_UNIT_TEST(Collect_Block42) {
- CountingEventsTest("collect", 112, TBlobStorageGroupType::Erasure4Plus2Block);
+ CountingEventsTest("collect", 112, TBlobStorageGroupType::Erasure4Plus2Block);
}
Y_UNIT_TEST(Collect_None) {
diff --git a/ydb/core/blobstorage/ut_blobstorage/defrag.cpp b/ydb/core/blobstorage/ut_blobstorage/defrag.cpp
index d84a4d65af8..c3f4577378c 100644
--- a/ydb/core/blobstorage/ut_blobstorage/defrag.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/defrag.cpp
@@ -1,145 +1,145 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
-
-Y_UNIT_TEST_SUITE(Defragmentation) {
- Y_UNIT_TEST(DoesItWork) {
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = 8,
- .Erasure = TBlobStorageGroupType::ErasureMirror3of4,
- });
-
- env.CreateBoxAndPool(1, 1);
- env.Sim(TDuration::Minutes(1));
- auto groups = env.GetGroups();
- UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
- const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
- env.Sim(TDuration::Minutes(5));
-
- const ui32 dataLen = 512 * 1024;
- const TString data(dataLen, 'x');
- ui32 index = 0;
-
- const ui32 orderNum = 0;
- const TVDiskID& vdiskId = info->GetVDiskId(orderNum);
- const TActorId& actorId = info->GetActorId(orderNum);
-
- const ui32 targetNumChunks = 10;
- std::map<ui32, std::vector<TLogoBlobID>> chunkToBlob;
-
- for (;;) {
- const TLogoBlobID id(1, 1, index /*step*/, 0, data.size(), 0);
- const ui32 hash = id.FullID().Hash();
- if (!info->GetTopology().BelongsToSubgroup(vdiskId, hash)) {
- continue;
- }
- const ui32 idxInSubgroup = info->GetTopology().GetIdxInSubgroup(vdiskId, hash);
- const ui32 partIdx = idxInSubgroup & 1; // 0 1 0 1 01 01 01 01 possible layouts; this fits them
- env.PutBlob(vdiskId, TLogoBlobID(id, partIdx + 1), data);
- ++index;
-
- env.Sim();
-
- auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
- chunkToBlob.clear();
- for (const auto& item : res->Layout) {
- using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
- if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
- chunkToBlob[item.Location.ChunkIdx].push_back(item.BlobId);
- }
- }
- if (chunkToBlob.size() == targetNumChunks) {
- break;
- }
- }
-
- TVector<TLogoBlobID> keep;
- std::set<TLogoBlobID> blobsToDelete;
- bool first = true;
- for (auto& [_, blobsOfChunk] : chunkToBlob) {
- blobsToDelete.insert(blobsOfChunk.begin(), blobsOfChunk.end());
- if (first && blobsOfChunk.size() > 1) {
- first = false;
- UNIT_ASSERT(blobsOfChunk.size() >= targetNumChunks);
-
- // keep all blobs but targetNumChunks - 1
- for (ui32 i = 0; i < blobsOfChunk.size() - (targetNumChunks - 1); ++i) {
- keep.push_back(blobsOfChunk[i]);
- }
- } else {
- // keep one blob
- keep.push_back(blobsOfChunk.front());
- }
- }
- for (const TLogoBlobID& id : keep) {
- blobsToDelete.erase(id);
- }
-
- // issue gc command
- {
- const TActorId& sender = env.Runtime->AllocateEdgeActor(1);
- env.Runtime->WrapInActorContext(sender, [&] {
- SendToBSProxy(sender, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(1, 1, 1, 0, true, 1, Max<ui32>(),
- new TVector<TLogoBlobID>(std::move(keep)), nullptr, TInstant::Max(), true));
- });
- const auto& res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
- // wait for sync
- env.Sim(TDuration::Seconds(3));
-
- for (;;) {
- // trigger compaction
- {
- const auto& sender = env.Runtime->AllocateEdgeActor(actorId.NodeId());
- auto ev = std::make_unique<IEventHandle>(actorId, sender, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
- ev->Rewrite(TEvBlobStorage::EvForwardToSkeleton, actorId);
- env.Runtime->Send(ev.release(), sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvCompactVDiskResult>(sender);
- }
-
- // check layout
- ui32 numUndeleted = 0;
- std::map<ui32, ui32> chunkToBlobs;
- auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
- for (const auto& item : res->Layout) {
- using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
- if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
- ++chunkToBlobs[item.Location.ChunkIdx];
- numUndeleted += blobsToDelete.count(item.BlobId);
- }
- }
- if (numUndeleted) {
- env.Sim(TDuration::Minutes(1));
- continue;
- }
- ui32 num1 = 0, numOther = 0;
- for (const auto& [_, numBlobs] : chunkToBlobs) {
- Cerr << "numBlobs# " << numBlobs << Endl;
- ++(numBlobs == 1 ? num1 : numOther);
- }
- UNIT_ASSERT_VALUES_EQUAL(numOther, 1);
- UNIT_ASSERT_VALUES_EQUAL(num1, targetNumChunks - 1);
- break;
- }
-
- // defrag
- {
- auto res = env.SyncQuery<TEvBlobStorage::TEvVDefragResult, TEvBlobStorage::TEvVDefrag>(actorId, vdiskId, true);
- UNIT_ASSERT_VALUES_EQUAL(res->Record.GetStatus(), NKikimrProto::OK);
- }
-
- // check layout again
- {
- std::map<ui32, ui32> chunkToBlobs;
- auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
- for (const auto& item : res->Layout) {
- using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
- if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
- ++chunkToBlobs[item.Location.ChunkIdx];
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(chunkToBlobs.size(), 1);
- }
- }
-}
+
+Y_UNIT_TEST_SUITE(Defragmentation) {
+ Y_UNIT_TEST(DoesItWork) {
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = 8,
+ .Erasure = TBlobStorageGroupType::ErasureMirror3of4,
+ });
+
+ env.CreateBoxAndPool(1, 1);
+ env.Sim(TDuration::Minutes(1));
+ auto groups = env.GetGroups();
+ UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
+ const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
+ env.Sim(TDuration::Minutes(5));
+
+ const ui32 dataLen = 512 * 1024;
+ const TString data(dataLen, 'x');
+ ui32 index = 0;
+
+ const ui32 orderNum = 0;
+ const TVDiskID& vdiskId = info->GetVDiskId(orderNum);
+ const TActorId& actorId = info->GetActorId(orderNum);
+
+ const ui32 targetNumChunks = 10;
+ std::map<ui32, std::vector<TLogoBlobID>> chunkToBlob;
+
+ for (;;) {
+ const TLogoBlobID id(1, 1, index /*step*/, 0, data.size(), 0);
+ const ui32 hash = id.FullID().Hash();
+ if (!info->GetTopology().BelongsToSubgroup(vdiskId, hash)) {
+ continue;
+ }
+ const ui32 idxInSubgroup = info->GetTopology().GetIdxInSubgroup(vdiskId, hash);
+ const ui32 partIdx = idxInSubgroup & 1; // 0 1 0 1 01 01 01 01 possible layouts; this fits them
+ env.PutBlob(vdiskId, TLogoBlobID(id, partIdx + 1), data);
+ ++index;
+
+ env.Sim();
+
+ auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
+ chunkToBlob.clear();
+ for (const auto& item : res->Layout) {
+ using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
+ if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
+ chunkToBlob[item.Location.ChunkIdx].push_back(item.BlobId);
+ }
+ }
+ if (chunkToBlob.size() == targetNumChunks) {
+ break;
+ }
+ }
+
+ TVector<TLogoBlobID> keep;
+ std::set<TLogoBlobID> blobsToDelete;
+ bool first = true;
+ for (auto& [_, blobsOfChunk] : chunkToBlob) {
+ blobsToDelete.insert(blobsOfChunk.begin(), blobsOfChunk.end());
+ if (first && blobsOfChunk.size() > 1) {
+ first = false;
+ UNIT_ASSERT(blobsOfChunk.size() >= targetNumChunks);
+
+ // keep all blobs but targetNumChunks - 1
+ for (ui32 i = 0; i < blobsOfChunk.size() - (targetNumChunks - 1); ++i) {
+ keep.push_back(blobsOfChunk[i]);
+ }
+ } else {
+ // keep one blob
+ keep.push_back(blobsOfChunk.front());
+ }
+ }
+ for (const TLogoBlobID& id : keep) {
+ blobsToDelete.erase(id);
+ }
+
+ // issue gc command
+ {
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(1);
+ env.Runtime->WrapInActorContext(sender, [&] {
+ SendToBSProxy(sender, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(1, 1, 1, 0, true, 1, Max<ui32>(),
+ new TVector<TLogoBlobID>(std::move(keep)), nullptr, TInstant::Max(), true));
+ });
+ const auto& res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(sender);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+ // wait for sync
+ env.Sim(TDuration::Seconds(3));
+
+ for (;;) {
+ // trigger compaction
+ {
+ const auto& sender = env.Runtime->AllocateEdgeActor(actorId.NodeId());
+ auto ev = std::make_unique<IEventHandle>(actorId, sender, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
+ ev->Rewrite(TEvBlobStorage::EvForwardToSkeleton, actorId);
+ env.Runtime->Send(ev.release(), sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvCompactVDiskResult>(sender);
+ }
+
+ // check layout
+ ui32 numUndeleted = 0;
+ std::map<ui32, ui32> chunkToBlobs;
+ auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
+ for (const auto& item : res->Layout) {
+ using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
+ if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
+ ++chunkToBlobs[item.Location.ChunkIdx];
+ numUndeleted += blobsToDelete.count(item.BlobId);
+ }
+ }
+ if (numUndeleted) {
+ env.Sim(TDuration::Minutes(1));
+ continue;
+ }
+ ui32 num1 = 0, numOther = 0;
+ for (const auto& [_, numBlobs] : chunkToBlobs) {
+ Cerr << "numBlobs# " << numBlobs << Endl;
+ ++(numBlobs == 1 ? num1 : numOther);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(numOther, 1);
+ UNIT_ASSERT_VALUES_EQUAL(num1, targetNumChunks - 1);
+ break;
+ }
+
+ // defrag
+ {
+ auto res = env.SyncQuery<TEvBlobStorage::TEvVDefragResult, TEvBlobStorage::TEvVDefrag>(actorId, vdiskId, true);
+ UNIT_ASSERT_VALUES_EQUAL(res->Record.GetStatus(), NKikimrProto::OK);
+ }
+
+ // check layout again
+ {
+ std::map<ui32, ui32> chunkToBlobs;
+ auto res = env.SyncQuery<TEvBlobStorage::TEvCaptureVDiskLayoutResult, TEvBlobStorage::TEvCaptureVDiskLayout>(actorId);
+ for (const auto& item : res->Layout) {
+ using T = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
+ if (item.Database == T::EDatabase::LogoBlobs && item.RecordType == T::ERecordType::HugeBlob) {
+ ++chunkToBlobs[item.Location.ChunkIdx];
+ }
+ }
+ UNIT_ASSERT_VALUES_EQUAL(chunkToBlobs.size(), 1);
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/donor.cpp b/ydb/core/blobstorage/ut_blobstorage/donor.cpp
index 4d0e2edb0f8..1dd96122177 100644
--- a/ydb/core/blobstorage/ut_blobstorage/donor.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/donor.cpp
@@ -1,86 +1,86 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(Donor) {
-
- Y_UNIT_TEST(SlayAfterWiping) {
- TEnvironmentSetup env{{
- .NodeCount = 8,
- .VDiskReplPausedAtStart = true,
- .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
- }};
- auto& runtime = env.Runtime;
-
- env.EnableDonorMode();
- env.CreateBoxAndPool(2, 1);
- env.CommenceReplication();
- env.Sim(TDuration::Seconds(30));
-
- const ui32 groupId = env.GetGroups().front();
-
- const TActorId edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
- for (ui32 i = 0; i < 100; ++i) {
- const TString buffer = TStringBuilder() << "blob number " << i;
- TLogoBlobID id(1, 1, 1, 0, buffer.size(), 0);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
- // wait for sync and stuff
- env.Sim(TDuration::Seconds(3));
-
- // move slot out from disk
- auto info = env.GetGroupInfo(groupId);
- const TVDiskID& vdiskId = info->GetVDiskId(0);
- const TActorId& vdiskActorId = info->GetActorId(0);
- env.SettlePDisk(vdiskActorId);
- env.Sim(TDuration::Seconds(30));
-
- // find our donor disk
- auto baseConfig = env.FetchBaseConfig();
- bool found = false;
- std::pair<ui32, ui32> donorPDiskId;
- std::tuple<ui32, ui32, ui32> acceptor;
- for (const auto& slot : baseConfig.GetVSlot()) {
- if (slot.DonorsSize()) {
- UNIT_ASSERT(!found);
- UNIT_ASSERT_VALUES_EQUAL(slot.DonorsSize(), 1);
- const auto& donor = slot.GetDonors(0);
- const auto& id = donor.GetVSlotId();
- UNIT_ASSERT_VALUES_EQUAL(vdiskActorId, MakeBlobStorageVDiskID(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()));
- UNIT_ASSERT_VALUES_EQUAL(VDiskIDFromVDiskID(donor.GetVDiskId()), vdiskId);
- donorPDiskId = {id.GetNodeId(), id.GetPDiskId()};
- const auto& acceptorId = slot.GetVSlotId();
- acceptor = {acceptorId.GetNodeId(), acceptorId.GetPDiskId(), acceptorId.GetVSlotId()};
- found = true;
- }
- }
- UNIT_ASSERT(found);
-
- // restart with formatting
- env.Cleanup();
- const size_t num = env.PDiskMockStates.erase(donorPDiskId);
- UNIT_ASSERT_VALUES_EQUAL(num, 1);
- env.Initialize();
-
- // wait for initialization
- env.Sim(TDuration::Seconds(30));
-
- // ensure it has vanished
- baseConfig = env.FetchBaseConfig();
- found = false;
- for (const auto& slot : baseConfig.GetVSlot()) {
- const auto& id = slot.GetVSlotId();
- if (std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()) == acceptor) {
- UNIT_ASSERT(!found);
- UNIT_ASSERT_VALUES_EQUAL(slot.DonorsSize(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot.GetStatus(), "REPLICATING");
- found = true;
- }
- }
- UNIT_ASSERT(found);
- }
-
-}
+
+Y_UNIT_TEST_SUITE(Donor) {
+
+ Y_UNIT_TEST(SlayAfterWiping) {
+ TEnvironmentSetup env{{
+ .NodeCount = 8,
+ .VDiskReplPausedAtStart = true,
+ .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
+ }};
+ auto& runtime = env.Runtime;
+
+ env.EnableDonorMode();
+ env.CreateBoxAndPool(2, 1);
+ env.CommenceReplication();
+ env.Sim(TDuration::Seconds(30));
+
+ const ui32 groupId = env.GetGroups().front();
+
+ const TActorId edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
+ for (ui32 i = 0; i < 100; ++i) {
+ const TString buffer = TStringBuilder() << "blob number " << i;
+ TLogoBlobID id(1, 1, 1, 0, buffer.size(), 0);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+ // wait for sync and stuff
+ env.Sim(TDuration::Seconds(3));
+
+ // move slot out from disk
+ auto info = env.GetGroupInfo(groupId);
+ const TVDiskID& vdiskId = info->GetVDiskId(0);
+ const TActorId& vdiskActorId = info->GetActorId(0);
+ env.SettlePDisk(vdiskActorId);
+ env.Sim(TDuration::Seconds(30));
+
+ // find our donor disk
+ auto baseConfig = env.FetchBaseConfig();
+ bool found = false;
+ std::pair<ui32, ui32> donorPDiskId;
+ std::tuple<ui32, ui32, ui32> acceptor;
+ for (const auto& slot : baseConfig.GetVSlot()) {
+ if (slot.DonorsSize()) {
+ UNIT_ASSERT(!found);
+ UNIT_ASSERT_VALUES_EQUAL(slot.DonorsSize(), 1);
+ const auto& donor = slot.GetDonors(0);
+ const auto& id = donor.GetVSlotId();
+ UNIT_ASSERT_VALUES_EQUAL(vdiskActorId, MakeBlobStorageVDiskID(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()));
+ UNIT_ASSERT_VALUES_EQUAL(VDiskIDFromVDiskID(donor.GetVDiskId()), vdiskId);
+ donorPDiskId = {id.GetNodeId(), id.GetPDiskId()};
+ const auto& acceptorId = slot.GetVSlotId();
+ acceptor = {acceptorId.GetNodeId(), acceptorId.GetPDiskId(), acceptorId.GetVSlotId()};
+ found = true;
+ }
+ }
+ UNIT_ASSERT(found);
+
+ // restart with formatting
+ env.Cleanup();
+ const size_t num = env.PDiskMockStates.erase(donorPDiskId);
+ UNIT_ASSERT_VALUES_EQUAL(num, 1);
+ env.Initialize();
+
+ // wait for initialization
+ env.Sim(TDuration::Seconds(30));
+
+ // ensure it has vanished
+ baseConfig = env.FetchBaseConfig();
+ found = false;
+ for (const auto& slot : baseConfig.GetVSlot()) {
+ const auto& id = slot.GetVSlotId();
+ if (std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()) == acceptor) {
+ UNIT_ASSERT(!found);
+ UNIT_ASSERT_VALUES_EQUAL(slot.DonorsSize(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(slot.GetStatus(), "REPLICATING");
+ found = true;
+ }
+ }
+ UNIT_ASSERT(found);
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/encryption.cpp b/ydb/core/blobstorage/ut_blobstorage/encryption.cpp
index 4297c53794a..2c0cb3243f4 100644
--- a/ydb/core/blobstorage/ut_blobstorage/encryption.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/encryption.cpp
@@ -1,58 +1,58 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(ProxyEncryption) {
- Y_UNIT_TEST(CorrectlyFailOnNoKeys) {
- const ui8 keyData[32] = "Hello, I'm your new key";
- const TEncryptionKey key{
- .Key = {keyData, sizeof(keyData)},
- .Version = 1,
- .Id = "tenant key"
- };
- auto preprocess = [&](ui32 nodeId, TNodeWardenConfig& config) {
- if (nodeId == 9 || nodeId == 10) {
- config.TenantKey = key;
- }
- };
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = 11,
- .Erasure = TBlobStorageGroupType::ErasureMirror3of4,
- .Encryption = true,
- .ConfigPreprocessor = preprocess
- });
- auto& runtime = env.Runtime;
- env.CreateBoxAndPool(1, 1);
- env.Sim(TDuration::Minutes(1));
-
- auto groups = env.GetGroups();
- UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
-
- TString data = "hello";
- TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
-
- // node with keys: write data
- {
- TActorId edge = runtime->AllocateEdgeActor(9);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groups[0], new TEvBlobStorage::TEvPut(id, data, TInstant::Max()));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
- auto tryToRead = [&](ui32 nodeId) {
- TActorId edge = runtime->AllocateEdgeActor(nodeId);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groups[0], new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(edge);
- auto *msg = res->Get();
- UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
- return msg->Responses[0].Status;
- };
-
- for (ui32 i = 1; i <= 11; ++i) {
- UNIT_ASSERT_VALUES_EQUAL(tryToRead(i), (i == 9 || i == 10) ? NKikimrProto::OK : NKikimrProto::ERROR);
- }
- }
-}
+
+Y_UNIT_TEST_SUITE(ProxyEncryption) {
+ Y_UNIT_TEST(CorrectlyFailOnNoKeys) {
+ const ui8 keyData[32] = "Hello, I'm your new key";
+ const TEncryptionKey key{
+ .Key = {keyData, sizeof(keyData)},
+ .Version = 1,
+ .Id = "tenant key"
+ };
+ auto preprocess = [&](ui32 nodeId, TNodeWardenConfig& config) {
+ if (nodeId == 9 || nodeId == 10) {
+ config.TenantKey = key;
+ }
+ };
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = 11,
+ .Erasure = TBlobStorageGroupType::ErasureMirror3of4,
+ .Encryption = true,
+ .ConfigPreprocessor = preprocess
+ });
+ auto& runtime = env.Runtime;
+ env.CreateBoxAndPool(1, 1);
+ env.Sim(TDuration::Minutes(1));
+
+ auto groups = env.GetGroups();
+ UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
+
+ TString data = "hello";
+ TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
+
+ // node with keys: write data
+ {
+ TActorId edge = runtime->AllocateEdgeActor(9);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groups[0], new TEvBlobStorage::TEvPut(id, data, TInstant::Max()));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+ auto tryToRead = [&](ui32 nodeId) {
+ TActorId edge = runtime->AllocateEdgeActor(nodeId);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groups[0], new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(edge);
+ auto *msg = res->Get();
+ UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
+ return msg->Responses[0].Status;
+ };
+
+ for (ui32 i = 1; i <= 11; ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(tryToRead(i), (i == 9 || i == 10) ? NKikimrProto::OK : NKikimrProto::ERROR);
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/gc_quorum_3dc.cpp b/ydb/core/blobstorage/ut_blobstorage/gc_quorum_3dc.cpp
index 6f48632a0a1..d0a43235230 100644
--- a/ydb/core/blobstorage/ut_blobstorage/gc_quorum_3dc.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/gc_quorum_3dc.cpp
@@ -1,181 +1,181 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-#include <random>
-
-Y_UNIT_TEST_SUITE(Mirror3dc) {
-
- Y_UNIT_TEST(GcQuorum) {
- // generate collect garbage disk ordering options
- std::vector<std::vector<ui32>> orders;
- {
- std::vector<ui32> order;
- for (ui32 i = 0; i < 9; ++i) {
- order.push_back(i);
- }
-
- for (ui32 i = 0; i < 18144; ++i) {
- orders.push_back(order);
- std::next_permutation(order.begin(), order.end());
- }
- }
-
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = 9,
- .Erasure = TBlobStorageGroupType::ErasureMirror3dc,
- });
- auto& runtime = env.Runtime;
-
- env.CreateBoxAndPool(1, 1);
- const ui32 groupId = env.GetGroups().front();
- auto info = env.GetGroupInfo(groupId);
- auto& topology = info->GetTopology();
- auto& checker = topology.GetQuorumChecker();
-
- std::unordered_map<ui32, TActorId> edgeActors;
- auto getEdgeActor = [&](ui32 nodeId) {
- TActorId& res = edgeActors[nodeId];
- if (!res) {
- res = runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
- }
- return res;
- };
-
- std::vector<TActorId> queueIds;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- queueIds.push_back(env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
- }
-
- // generate blob ids
- const TString buffer("x");
- std::vector<TLogoBlobID> ids;
- for (ui32 i = 1; i <= orders.size(); ++i) {
- const TLogoBlobID id(100500 + i, 1, 1, 0, buffer.size(), 0);
- ids.push_back(id);
- }
-
- // write out blobs
- {
- const TActorId edge = getEdgeActor(1);
- for (const TLogoBlobID& id : ids) {
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
- }
-
- Cerr << "BlobsWritten# " << ids.size() << Endl;
-
- // obtain part maps
- auto getPartMap = [&] {
- std::unordered_map<TLogoBlobID, std::map<ui32, ui32>, THash<TLogoBlobID>> partMap;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TVDiskID& vdiskId = info->GetVDiskId(i);
- TLogoBlobID from(Max<ui64>(), Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
- TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
- for (;;) {
- auto query = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, from, TLogoBlobID());
-
- const TActorId queueId = queueIds[i];
- const TActorId edge = getEdgeActor(queueId.NodeId());
- runtime->Send(new IEventHandle(queueId, edge, query.release()), edge.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
-
- const auto& record = res->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
- for (const auto& result : record.GetResult()) {
- UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NKikimrProto::OK);
- const auto& id = LogoBlobIDFromLogoBlobID(result.GetBlobID());
- if (result.PartsSize()) {
- auto& mask = partMap[id][i];
- for (const ui32 partId : result.GetParts()) {
- mask |= 1 << partId - 1;
- }
- }
- from = TLogoBlobID::PrevFull(id, TLogoBlobID::MaxBlobSize);
- }
-
- if (record.ResultSize() == 0) {
- break;
- }
- }
- }
- return partMap;
- };
-
- auto partMap = getPartMap();
- UNIT_ASSERT_VALUES_EQUAL(partMap.size(), ids.size());
-
- std::vector<TBlobStorageGroupInfo::TGroupVDisks> vdisks(ids.size(), {&topology});
-
- for (ui32 i = 0; i < 9; ++i) {
- Cerr << "step " << i << Endl;
-
- std::map<TActorId, ui32> waitQueue;
-
- for (ui32 j = 0; j < orders.size(); ++j) {
- const ui32 diskIdx = orders[j][i];
- const TVDiskID& vdiskId = info->GetVDiskId(diskIdx);
- const TActorId queueId = queueIds[diskIdx];
- const TActorId edge = getEdgeActor(queueId.NodeId());
- const TLogoBlobID& id = ids[j];
- runtime->Send(new IEventHandle(queueId, edge, new TEvBlobStorage::TEvVCollectGarbage(id.TabletID(),
- id.Generation(), 0, id.Channel(), true, id.Generation(), id.Step(), false, nullptr, nullptr, vdiskId,
- TInstant::Max())), edge.NodeId());
- ++waitQueue[edge];
- }
-
- Cerr << "waiting for replies" << Endl;
-
- while (!waitQueue.empty()) {
- std::set<TActorId> edges;
- for (const auto& [key, value] : waitQueue) {
- edges.insert(key);
- }
- auto res = runtime->WaitForEdgeActorEvent(edges);
- if (!--waitQueue[res->Recipient]) {
- waitQueue.erase(res->Recipient);
- }
- const auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVCollectGarbageResult>();
- UNIT_ASSERT(msg);
- UNIT_ASSERT_VALUES_EQUAL(msg->Record.GetStatus(), NKikimrProto::OK);
- }
-
- env.Sim(TDuration::Seconds(10)); // wait for sync
-
- Cerr << "scanning parts" << Endl;
-
- auto currentMap = getPartMap();
-
- for (ui32 j = 0; j < orders.size(); ++j) {
- const TLogoBlobID& id = ids[j];
- if (!partMap.count(id)) {
- continue; // this blob is already collected
- }
-
- // update collected state for current blob
- auto& collected = vdisks[j];
- auto prev = collected;
- collected |= {&topology, info->GetVDiskId(orders[j][i])};
-
- if (currentMap.count(id)) {
- UNIT_ASSERT_EQUAL(currentMap[id], partMap[id]); // blob is still inplace
- } else {
- UNIT_ASSERT(!checker.CheckQuorumForGroup(prev));
- UNIT_ASSERT(checker.CheckQuorumForGroup(collected));
- Cerr << "empty@ " << i << " " << j << Endl;
- }
- }
-
- partMap = std::move(currentMap);
-
- if (partMap.empty()) {
- break;
- }
- }
-
- UNIT_ASSERT(partMap.empty());
- }
-
-}
+#include <random>
+
+Y_UNIT_TEST_SUITE(Mirror3dc) {
+
+ Y_UNIT_TEST(GcQuorum) {
+ // generate collect garbage disk ordering options
+ std::vector<std::vector<ui32>> orders;
+ {
+ std::vector<ui32> order;
+ for (ui32 i = 0; i < 9; ++i) {
+ order.push_back(i);
+ }
+
+ for (ui32 i = 0; i < 18144; ++i) {
+ orders.push_back(order);
+ std::next_permutation(order.begin(), order.end());
+ }
+ }
+
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = 9,
+ .Erasure = TBlobStorageGroupType::ErasureMirror3dc,
+ });
+ auto& runtime = env.Runtime;
+
+ env.CreateBoxAndPool(1, 1);
+ const ui32 groupId = env.GetGroups().front();
+ auto info = env.GetGroupInfo(groupId);
+ auto& topology = info->GetTopology();
+ auto& checker = topology.GetQuorumChecker();
+
+ std::unordered_map<ui32, TActorId> edgeActors;
+ auto getEdgeActor = [&](ui32 nodeId) {
+ TActorId& res = edgeActors[nodeId];
+ if (!res) {
+ res = runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
+ }
+ return res;
+ };
+
+ std::vector<TActorId> queueIds;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ queueIds.push_back(env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
+ }
+
+ // generate blob ids
+ const TString buffer("x");
+ std::vector<TLogoBlobID> ids;
+ for (ui32 i = 1; i <= orders.size(); ++i) {
+ const TLogoBlobID id(100500 + i, 1, 1, 0, buffer.size(), 0);
+ ids.push_back(id);
+ }
+
+ // write out blobs
+ {
+ const TActorId edge = getEdgeActor(1);
+ for (const TLogoBlobID& id : ids) {
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+ }
+
+ Cerr << "BlobsWritten# " << ids.size() << Endl;
+
+ // obtain part maps
+ auto getPartMap = [&] {
+ std::unordered_map<TLogoBlobID, std::map<ui32, ui32>, THash<TLogoBlobID>> partMap;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TVDiskID& vdiskId = info->GetVDiskId(i);
+ TLogoBlobID from(Max<ui64>(), Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
+ TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
+ for (;;) {
+ auto query = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, from, TLogoBlobID());
+
+ const TActorId queueId = queueIds[i];
+ const TActorId edge = getEdgeActor(queueId.NodeId());
+ runtime->Send(new IEventHandle(queueId, edge, query.release()), edge.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
+
+ const auto& record = res->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
+ for (const auto& result : record.GetResult()) {
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), NKikimrProto::OK);
+ const auto& id = LogoBlobIDFromLogoBlobID(result.GetBlobID());
+ if (result.PartsSize()) {
+ auto& mask = partMap[id][i];
+ for (const ui32 partId : result.GetParts()) {
+ mask |= 1 << partId - 1;
+ }
+ }
+ from = TLogoBlobID::PrevFull(id, TLogoBlobID::MaxBlobSize);
+ }
+
+ if (record.ResultSize() == 0) {
+ break;
+ }
+ }
+ }
+ return partMap;
+ };
+
+ auto partMap = getPartMap();
+ UNIT_ASSERT_VALUES_EQUAL(partMap.size(), ids.size());
+
+ std::vector<TBlobStorageGroupInfo::TGroupVDisks> vdisks(ids.size(), {&topology});
+
+ for (ui32 i = 0; i < 9; ++i) {
+ Cerr << "step " << i << Endl;
+
+ std::map<TActorId, ui32> waitQueue;
+
+ for (ui32 j = 0; j < orders.size(); ++j) {
+ const ui32 diskIdx = orders[j][i];
+ const TVDiskID& vdiskId = info->GetVDiskId(diskIdx);
+ const TActorId queueId = queueIds[diskIdx];
+ const TActorId edge = getEdgeActor(queueId.NodeId());
+ const TLogoBlobID& id = ids[j];
+ runtime->Send(new IEventHandle(queueId, edge, new TEvBlobStorage::TEvVCollectGarbage(id.TabletID(),
+ id.Generation(), 0, id.Channel(), true, id.Generation(), id.Step(), false, nullptr, nullptr, vdiskId,
+ TInstant::Max())), edge.NodeId());
+ ++waitQueue[edge];
+ }
+
+ Cerr << "waiting for replies" << Endl;
+
+ while (!waitQueue.empty()) {
+ std::set<TActorId> edges;
+ for (const auto& [key, value] : waitQueue) {
+ edges.insert(key);
+ }
+ auto res = runtime->WaitForEdgeActorEvent(edges);
+ if (!--waitQueue[res->Recipient]) {
+ waitQueue.erase(res->Recipient);
+ }
+ const auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVCollectGarbageResult>();
+ UNIT_ASSERT(msg);
+ UNIT_ASSERT_VALUES_EQUAL(msg->Record.GetStatus(), NKikimrProto::OK);
+ }
+
+ env.Sim(TDuration::Seconds(10)); // wait for sync
+
+ Cerr << "scanning parts" << Endl;
+
+ auto currentMap = getPartMap();
+
+ for (ui32 j = 0; j < orders.size(); ++j) {
+ const TLogoBlobID& id = ids[j];
+ if (!partMap.count(id)) {
+ continue; // this blob is already collected
+ }
+
+ // update collected state for current blob
+ auto& collected = vdisks[j];
+ auto prev = collected;
+ collected |= {&topology, info->GetVDiskId(orders[j][i])};
+
+ if (currentMap.count(id)) {
+ UNIT_ASSERT_EQUAL(currentMap[id], partMap[id]); // blob is still inplace
+ } else {
+ UNIT_ASSERT(!checker.CheckQuorumForGroup(prev));
+ UNIT_ASSERT(checker.CheckQuorumForGroup(collected));
+ Cerr << "empty@ " << i << " " << j << Endl;
+ }
+ }
+
+ partMap = std::move(currentMap);
+
+ if (partMap.empty()) {
+ break;
+ }
+ }
+
+ UNIT_ASSERT(partMap.empty());
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/incorrect_queries.cpp b/ydb/core/blobstorage/ut_blobstorage/incorrect_queries.cpp
index 1e1bca2fe9c..f3aa98417d2 100644
--- a/ydb/core/blobstorage/ut_blobstorage/incorrect_queries.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/incorrect_queries.cpp
@@ -7,28 +7,28 @@
#include <ydb/core/protos/blobstorage.pb.h>
Y_UNIT_TEST_SUITE(IncorrectQueries) {
- const TVector<TString> erasureTypes = {"none", "block-4-2", "mirror-3", "mirror-3of4", "mirror-3-dc"};
+ const TVector<TString> erasureTypes = {"none", "block-4-2", "mirror-3", "mirror-3of4", "mirror-3-dc"};
- void SendPut(TEnvironmentSetup& env, TTestInfo& test,
+ void SendPut(TEnvironmentSetup& env, TTestInfo& test,
const TLogoBlobID& blobId, NKikimrProto::EReplyStatus status, ui32 blob_size, bool isEmptyObject = false, bool isEmptyMeta = false) {
const TString data(blob_size, 'a');
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvVPut>(blobId, data, test.Info->GetVDiskInSubgroup(0, blobId.Hash()),
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvVPut>(blobId, data, test.Info->GetVDiskInSubgroup(0, blobId.Hash()),
false, nullptr, TInstant::Max(), NKikimrBlobStorage::AsyncBlob);
if (isEmptyObject) {
if (isEmptyMeta) {
- ev = std::make_unique<TEvBlobStorage::TEvVPut>();
+ ev = std::make_unique<TEvBlobStorage::TEvVPut>();
} else {
NKikimrBlobStorage::TEvVPut protoQuery;
- static_cast<TEvBlobStorage::TEvVPut*>(ev.get())->Record = protoQuery;
+ static_cast<TEvBlobStorage::TEvVPut*>(ev.get())->Record = protoQuery;
}
} else if (isEmptyMeta) {
- static_cast<TEvBlobStorage::TEvVPut*>(ev.get())->StripPayload();
+ static_cast<TEvBlobStorage::TEvVPut*>(ev.get())->StripPayload();
}
-
+
env.WithQueueId(test.Info->GetVDiskInSubgroup(0, blobId.Hash()), NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
auto handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvVPutResult);
TEvBlobStorage::TEvVPutResult *putResult = handle->Get<TEvBlobStorage::TEvVPutResult>();
@@ -38,24 +38,24 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
void SendGet(TEnvironmentSetup& env, TTestInfo& test, const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& part,
NKikimrProto::EReplyStatus status = NKikimrProto::OK, bool isEmptyObject = false, bool isEmptyMeta = false) {
- std::unique_ptr<IEventBase> ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId,
+ std::unique_ptr<IEventBase> ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId,
TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
Nothing(), {{blobId, 0u, ui32(part.size())}});
if (isEmptyObject) {
if (isEmptyMeta) {
- ev = std::make_unique<TEvBlobStorage::TEvVGet>();
+ ev = std::make_unique<TEvBlobStorage::TEvVGet>();
} else {
NKikimrBlobStorage::TEvVGet protoQuery;
- static_cast<TEvBlobStorage::TEvVGet*>(ev.get())->Record = protoQuery;
+ static_cast<TEvBlobStorage::TEvVGet*>(ev.get())->Record = protoQuery;
}
} else if (isEmptyMeta) {
- static_cast<TEvBlobStorage::TEvVGet*>(ev.get())->StripPayload();
+ static_cast<TEvBlobStorage::TEvVGet*>(ev.get())->StripPayload();
}
-
+
env.WithQueueId(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
auto r = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(r->Type, TEvBlobStorage::EvVGetResult);
@@ -76,18 +76,18 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
void SendEmptyMultiPut(TEnvironmentSetup& env, TTestInfo& test, const std::vector<TBlobInfo>& blobs, NKikimrProto::EReplyStatus status,
NKikimrBlobStorage::TEvVMultiPut proto) {
- std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
- TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog, false, nullptr));
+ std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
+ TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog, false, nullptr));
for(auto [blob, data, status] : blobs) {
- static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->AddVPut(blob, data, 0);
+ static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->AddVPut(blob, data, 0);
}
- static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->Record = proto;
-
+ static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->Record = proto;
+
env.WithQueueId(test.Info->GetVDiskId(0), NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
auto handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvVMultiPutResult);
TEvBlobStorage::TEvVMultiPutResult *putResult = handle->Get<TEvBlobStorage::TEvVMultiPutResult>();
@@ -101,16 +101,16 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
}
void SendMultiPut(TEnvironmentSetup& env, TTestInfo& test, NKikimrProto::EReplyStatus status, const std::vector<TBlobInfo>& blobs) {
- std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskInSubgroup(0, blobs[0].BlobId.Hash()),
+ std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskInSubgroup(0, blobs[0].BlobId.Hash()),
TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog, false, nullptr));
for(auto [blob, data, status] : blobs) {
- static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->AddVPut(blob, data, 0);
+ static_cast<TEvBlobStorage::TEvVMultiPut*>(ev.get())->AddVPut(blob, data, 0);
}
-
+
env.WithQueueId(test.Info->GetVDiskInSubgroup(0, blobs[0].BlobId.Hash()), NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
auto handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvVMultiPutResult);
TEvBlobStorage::TEvVMultiPutResult *putResult = handle->Get<TEvBlobStorage::TEvVMultiPutResult>();
@@ -149,7 +149,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
TLogoBlobID blobId(1, 1, 0, 0, size, 0, 13);
SendPut(env, test, blobId, NKikimrProto::ERROR, size);
}
- }
+ }
Y_UNIT_TEST(VeryBigBlob) {
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
@@ -186,7 +186,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
SendPut(env, test, blobId, NKikimrProto::ERROR, size - 42, true, true);
SendPut(env, test, blobId, NKikimrProto::ERROR, size + 42, true, true);
SendPut(env, test, blobId, NKikimrProto::ERROR, 0, true, true);
- }
+ }
Y_UNIT_TEST(Proto) {
for(const auto& erasure : erasureTypes) {
@@ -208,13 +208,13 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
protoBlobId.clear_rawx1();
blobId = LogoBlobIDFromLogoBlobID(protoBlobId);
SendPut(env, test, blobId, NKikimrProto::ERROR, 42);
- }
+ }
}
Y_UNIT_TEST(BaseReadingTest) {
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
-
+
constexpr ui32 size = 10;
TLogoBlobID blobId(1, 1, 0, 0, size, 0, 1);
SendPut(env, test, blobId, NKikimrProto::OK, size);
@@ -227,7 +227,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
return;
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
-
+
constexpr ui32 size = 10;
TLogoBlobID blobId(1, 1, 0, 0, size, 0, 1);
SendPut(env, test, blobId, NKikimrProto::OK, size);
@@ -275,7 +275,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
auto vdiskId = test.Info->GetVDiskInSubgroup(0, blobId.Hash());
SendGet(env, test, vdiskId, blobId, "a");
}
-
+
Y_UNIT_TEST(ProtoQueryGet) {
return;
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
@@ -289,7 +289,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
SendGet(env, test, vdiskId, blobId, data, NKikimrProto::ERROR, true);
}
-
+
Y_UNIT_TEST(WrongPartId) {
TEnvironmentSetup env(true, GetErasureTypeByString("block-4-2"));
TTestInfo test = InitTest(env);
@@ -301,7 +301,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
auto vdiskId = test.Info->GetVDiskInSubgroup(0, blobId.Hash());
SendGet(env, test, vdiskId, blobId, "");
}
-
+
Y_UNIT_TEST(EmptyTest) {
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
@@ -334,7 +334,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
Y_UNIT_TEST(SameBlob) {
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
-
+
constexpr ui32 size = 10;
TLogoBlobID BlobId(1, 1, 0, 0, size, 0, 1);
TLogoBlobID BlobId2(1, 1, 0, 0, size+100, 0, 1);
@@ -358,7 +358,7 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
Y_UNIT_TEST(BasePutTest) {
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
-
+
constexpr ui32 size = 10;
TLogoBlobID blobId(1, 1, 0, 0, size, 0, 1);
SendPut(env, test, blobId, NKikimrProto::OK, size);
@@ -381,22 +381,22 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
NKikimrProto::TLogoBlobID pBlobId;
auto blobId = LogoBlobIDFromLogoBlobID(pBlobId);
-
+
std::vector<TBlobInfo> blobs;
blobs.push_back({blobId, "", NKikimrProto::ERROR});
-
+
SendMultiPut(env, test, NKikimrProto::OK, blobs);
pBlobId.set_rawx1(0);
pBlobId.set_rawx2(0);
pBlobId.set_rawx3((1ull << 30) + (1ull << 31) + 1);
- blobId = LogoBlobIDFromLogoBlobID(pBlobId);
+ blobId = LogoBlobIDFromLogoBlobID(pBlobId);
blobs.push_back({blobId, "", NKikimrProto::ERROR});
pBlobId.set_rawx3((1ull << 31) + 1);
- blobId = LogoBlobIDFromLogoBlobID(pBlobId);
+ blobId = LogoBlobIDFromLogoBlobID(pBlobId);
blobs.push_back({blobId, "", NKikimrProto::ERROR});
SendMultiPut(env, test, NKikimrProto::OK, blobs);
@@ -416,12 +416,12 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
return;
TEnvironmentSetup env(true, GetErasureTypeByString("none"));
TTestInfo test = InitTest(env);
- std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
+ std::unique_ptr<IEventBase> ev(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog, false, nullptr));
env.WithQueueId(test.Info->GetVDiskId(0), NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, ev.release()), queueId.NodeId());
auto handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvVMultiPutResult);
TEvBlobStorage::TEvVMultiPutResult *putResult = handle->Get<TEvBlobStorage::TEvVMultiPutResult>();
@@ -519,23 +519,23 @@ Y_UNIT_TEST_SUITE(IncorrectQueries) {
constexpr int eventsCount = 10000;
constexpr int blobSize = 100;
const TString data(blobSize, 'a');
- std::vector<std::unique_ptr<IEventBase>> events(eventsCount);
+ std::vector<std::unique_ptr<IEventBase>> events(eventsCount);
int goodCount = 0;
for(int i = 0; i < eventsCount; ++i) {
- events[i].reset(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
+ events[i].reset(new TEvBlobStorage::TEvVMultiPut(test.Info->GetVDiskId(0),
TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog, false, nullptr));
if (i % 19 != 18) {
++goodCount;
TLogoBlobID blob(i, 1, 0, 0, blobSize, 0, 1);
- static_cast<TEvBlobStorage::TEvVMultiPut*>(events[i].get())->AddVPut(blob, data, 0);
+ static_cast<TEvBlobStorage::TEvVMultiPut*>(events[i].get())->AddVPut(blob, data, 0);
}
}
env.WithQueueId(test.Info->GetVDiskId(0), NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
test.Edge = test.Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
for(int i = 0; i < eventsCount; ++i) {
- test.Runtime->Send(new IEventHandle(queueId, test.Edge, events[i].release()), queueId.NodeId());
+ test.Runtime->Send(new IEventHandle(queueId, test.Edge, events[i].release()), queueId.NodeId());
}
int okCount = 0;
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/activity.h b/ydb/core/blobstorage/ut_blobstorage/lib/activity.h
index 478a87b7077..41a9170b722 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/activity.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/activity.h
@@ -1,203 +1,203 @@
-#pragma once
-
-#include "defs.h"
-
-enum {
- EvFinished = EventSpaceBegin(TEvents::ES_PRIVATE),
-};
-
-class TActivityActor : public TActorBootstrapped<TActivityActor> {
- NUnitTest::TTestBase *Test = NUnitTest::NPrivate::GetCurrentTest();
- const ui64 TabletId;
- const ui32 GroupId;
- const TActorId Edge;
- const TString Prefix;
- ui32 Generation = 1;
- ui32 Step = 1;
- std::map<TLogoBlobID, TString> Committed;
- std::map<TLogoBlobID, TString> Inflight;
- ui32 ReadsInFlight = 0;
- ui32 NumWritesRemaining = 0;
- ui32 MaxWritesInFlight;
- TReplQuoter Quoter;
-
-public:
- TActivityActor(ui64 tabletId, ui32 groupId, const TActorId& edge)
- : TabletId(tabletId)
- , GroupId(groupId)
- , Edge(edge)
- , Prefix(TStringBuilder() << "[" << TabletId << "@" << GroupId << "] ")
- , Quoter(10)
- {}
-
- void SendToProxy(TDuration timeout, IEventBase *ev) {
- TActivationContext::Schedule(timeout, CreateEventForBSProxy(SelfId(), MakeBlobStorageProxyID(GroupId), ev, 0));
- }
-
- void Bootstrap() {
- IssueInitialCheck();
- Become(&TThis::StateFunc);
- }
-
- void IssueInitialCheck() {
- LOG_NOTICE_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "starting new cycle Generation# " << Generation);
- NumWritesRemaining = 15 + RandomNumber<size_t>(10);
- MaxWritesInFlight = 1 + RandomNumber<size_t>(5);
- SendToProxy(TDuration::MilliSeconds(100 + RandomNumber(100u)), new TEvBlobStorage::TEvStatus(TInstant::Max()));
- }
-
- void Handle(TEvBlobStorage::TEvStatusResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvStatusResult# " << ev->Get()->ToString());
- if (ev->Get()->Status != NKikimrProto::OK) {
- IssueInitialCheck();
- } else {
- IssueBlock();
- }
- }
-
- void IssueBlock() {
- if (Generation == 1) {
- IssueDiscover();
- } else {
- SendToProxy(TDuration::MilliSeconds(100), new TEvBlobStorage::TEvBlock(TabletId, Generation - 1, TInstant::Max()));
- }
- }
-
- void Handle(TEvBlobStorage::TEvBlockResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvBlockResult# " << ev->Get()->ToString());
- UNIT_ASSERT_C(ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY ||
- ev->Get()->Status == NKikimrProto::RACE, ev->Get()->Print(false));
- if (ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY) {
- IssueDiscover();
- } else {
- IssueBlock();
- }
- }
-
- void IssueDiscover() {
- SendToProxy(TDuration::MilliSeconds(100), new TEvBlobStorage::TEvDiscover(TabletId, 0, false, false, TInstant::Max(), 0));
- }
-
- void Handle(TEvBlobStorage::TEvDiscoverResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvDiscoverResult# " << ev->Get()->ToString());
- if (Generation == 1) {
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::NODATA, ev->Get()->Print(false));
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
- UNIT_ASSERT_VALUES_EQUAL(ev->Get()->Id, Committed.rbegin()->first);
- }
- IssueRangeRead();
- }
-
- void IssueRangeRead() {
- const TLogoBlobID from(TabletId, Generation - 1, 0, 0, 0, 0);
- const TLogoBlobID to(TabletId, Generation - 1, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
- auto msg = std::make_unique<TEvBlobStorage::TEvRange>(TabletId, from, to, true, TInstant::Max(), true);
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvRange# " << msg->ToString());
- SendToProxy(TDuration::MilliSeconds(100), msg.release());
- }
-
- void Handle(TEvBlobStorage::TEvRangeResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvRangeResult# " << ev->Get()->ToString());
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
- TDuration timeout = TDuration::MilliSeconds(100);
- for (const auto& item : ev->Get()->Responses) {
- SendToProxy(timeout, new TEvBlobStorage::TEvGet(item.Id, 0, 0, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, true));
- timeout += TDuration::MilliSeconds(10);
- ++ReadsInFlight;
- }
- if (!ReadsInFlight) {
- UNIT_ASSERT(Committed.empty());
- IssueCollectGarbage();
- }
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvGetResult# " << ev->Get()->ToString());
- auto *msg = ev->Get();
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
- UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
- auto& response = msg->Responses[0];
- UNIT_ASSERT_VALUES_EQUAL(response.Status, NKikimrProto::OK);
- UNIT_ASSERT_EQUAL(response.Status, NKikimrProto::OK);
- if (Committed.count(response.Id)) {
- UNIT_ASSERT_VALUES_EQUAL(Committed.at(response.Id), response.Buffer);
- Committed.erase(response.Id);
- }
- if (!--ReadsInFlight) {
- std::vector<TLogoBlobID> ids;
- for (const auto& [blobId, _] : Committed) {
- ids.push_back(blobId);
- }
- UNIT_ASSERT_C(Committed.empty(), FormatList(ids));
- IssueCollectGarbage();
- }
- }
-
- void IssueCollectGarbage() {
- if (Generation == 1) {
- IssueWrites();
- } else {
- auto msg = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, Generation, 1, 0, true,
- Generation - 1, Max<ui32>(), nullptr, nullptr, TInstant::Max(), false, false);
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvCollectGarbage# "
- << msg->ToString());
- SendToProxy(TDuration::MilliSeconds(100), msg.release());
- }
- }
-
- void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvCollectGarbageResult# " << ev->Get()->ToString());
- UNIT_ASSERT_C(ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY, ev->Get()->Print(false));
- IssueWrites();
- }
-
- TString GenerateBuffer() {
- size_t len = 10 + RandomNumber<size_t>(32);
- TString buffer = TString::Uninitialized(len);
- char *data = buffer.Detach();
- std::generate(data, data + len, TReallyFastRng32(TabletId ^ Step));
- return buffer;
- }
-
- void IssueWrites() {
- for (; Inflight.size() < MaxWritesInFlight && NumWritesRemaining; --NumWritesRemaining) {
- TString buffer = GenerateBuffer();
- const TLogoBlobID id(TabletId, Generation, Step++, 0, buffer.size(), 0);
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvPut Id# " << id);
- SendToProxy(Quoter.Take(TActivationContext::Now(), 1), new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
- Inflight.emplace(id, std::move(buffer));
- }
- if (!NumWritesRemaining && Inflight.empty()) {
- ++Generation;
- IssueInitialCheck();
- }
- }
-
- void Handle(TEvBlobStorage::TEvPutResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvPutResult# " << ev->Get()->ToString());
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
- auto it = Inflight.find(ev->Get()->Id);
- UNIT_ASSERT(it != Inflight.end());
- Committed.emplace(*it);
- Inflight.erase(it);
- IssueWrites();
- }
-
- void Handle(TEvents::TEvPoison::TPtr ev) {
- TActivationContext::Send(new IEventHandle(EvFinished, 0, ev->Sender, SelfId(), {}, 0));
- PassAway();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvStatusResult, Handle);
- hFunc(TEvBlobStorage::TEvBlockResult, Handle);
- hFunc(TEvBlobStorage::TEvDiscoverResult, Handle);
- hFunc(TEvBlobStorage::TEvRangeResult, Handle);
- hFunc(TEvBlobStorage::TEvGetResult, Handle);
- hFunc(TEvBlobStorage::TEvPutResult, Handle);
- hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
- hFunc(TEvents::TEvPoison, Handle);
- )
-};
+#pragma once
+
+#include "defs.h"
+
+enum {
+ EvFinished = EventSpaceBegin(TEvents::ES_PRIVATE),
+};
+
+class TActivityActor : public TActorBootstrapped<TActivityActor> {
+ NUnitTest::TTestBase *Test = NUnitTest::NPrivate::GetCurrentTest();
+ const ui64 TabletId;
+ const ui32 GroupId;
+ const TActorId Edge;
+ const TString Prefix;
+ ui32 Generation = 1;
+ ui32 Step = 1;
+ std::map<TLogoBlobID, TString> Committed;
+ std::map<TLogoBlobID, TString> Inflight;
+ ui32 ReadsInFlight = 0;
+ ui32 NumWritesRemaining = 0;
+ ui32 MaxWritesInFlight;
+ TReplQuoter Quoter;
+
+public:
+ TActivityActor(ui64 tabletId, ui32 groupId, const TActorId& edge)
+ : TabletId(tabletId)
+ , GroupId(groupId)
+ , Edge(edge)
+ , Prefix(TStringBuilder() << "[" << TabletId << "@" << GroupId << "] ")
+ , Quoter(10)
+ {}
+
+ void SendToProxy(TDuration timeout, IEventBase *ev) {
+ TActivationContext::Schedule(timeout, CreateEventForBSProxy(SelfId(), MakeBlobStorageProxyID(GroupId), ev, 0));
+ }
+
+ void Bootstrap() {
+ IssueInitialCheck();
+ Become(&TThis::StateFunc);
+ }
+
+ void IssueInitialCheck() {
+ LOG_NOTICE_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "starting new cycle Generation# " << Generation);
+ NumWritesRemaining = 15 + RandomNumber<size_t>(10);
+ MaxWritesInFlight = 1 + RandomNumber<size_t>(5);
+ SendToProxy(TDuration::MilliSeconds(100 + RandomNumber(100u)), new TEvBlobStorage::TEvStatus(TInstant::Max()));
+ }
+
+ void Handle(TEvBlobStorage::TEvStatusResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvStatusResult# " << ev->Get()->ToString());
+ if (ev->Get()->Status != NKikimrProto::OK) {
+ IssueInitialCheck();
+ } else {
+ IssueBlock();
+ }
+ }
+
+ void IssueBlock() {
+ if (Generation == 1) {
+ IssueDiscover();
+ } else {
+ SendToProxy(TDuration::MilliSeconds(100), new TEvBlobStorage::TEvBlock(TabletId, Generation - 1, TInstant::Max()));
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvBlockResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvBlockResult# " << ev->Get()->ToString());
+ UNIT_ASSERT_C(ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY ||
+ ev->Get()->Status == NKikimrProto::RACE, ev->Get()->Print(false));
+ if (ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY) {
+ IssueDiscover();
+ } else {
+ IssueBlock();
+ }
+ }
+
+ void IssueDiscover() {
+ SendToProxy(TDuration::MilliSeconds(100), new TEvBlobStorage::TEvDiscover(TabletId, 0, false, false, TInstant::Max(), 0));
+ }
+
+ void Handle(TEvBlobStorage::TEvDiscoverResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvDiscoverResult# " << ev->Get()->ToString());
+ if (Generation == 1) {
+ UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::NODATA, ev->Get()->Print(false));
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
+ UNIT_ASSERT_VALUES_EQUAL(ev->Get()->Id, Committed.rbegin()->first);
+ }
+ IssueRangeRead();
+ }
+
+ void IssueRangeRead() {
+ const TLogoBlobID from(TabletId, Generation - 1, 0, 0, 0, 0);
+ const TLogoBlobID to(TabletId, Generation - 1, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
+ auto msg = std::make_unique<TEvBlobStorage::TEvRange>(TabletId, from, to, true, TInstant::Max(), true);
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvRange# " << msg->ToString());
+ SendToProxy(TDuration::MilliSeconds(100), msg.release());
+ }
+
+ void Handle(TEvBlobStorage::TEvRangeResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvRangeResult# " << ev->Get()->ToString());
+ UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
+ TDuration timeout = TDuration::MilliSeconds(100);
+ for (const auto& item : ev->Get()->Responses) {
+ SendToProxy(timeout, new TEvBlobStorage::TEvGet(item.Id, 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, true));
+ timeout += TDuration::MilliSeconds(10);
+ ++ReadsInFlight;
+ }
+ if (!ReadsInFlight) {
+ UNIT_ASSERT(Committed.empty());
+ IssueCollectGarbage();
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvGetResult# " << ev->Get()->ToString());
+ auto *msg = ev->Get();
+ UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
+ UNIT_ASSERT_VALUES_EQUAL(msg->ResponseSz, 1);
+ auto& response = msg->Responses[0];
+ UNIT_ASSERT_VALUES_EQUAL(response.Status, NKikimrProto::OK);
+ UNIT_ASSERT_EQUAL(response.Status, NKikimrProto::OK);
+ if (Committed.count(response.Id)) {
+ UNIT_ASSERT_VALUES_EQUAL(Committed.at(response.Id), response.Buffer);
+ Committed.erase(response.Id);
+ }
+ if (!--ReadsInFlight) {
+ std::vector<TLogoBlobID> ids;
+ for (const auto& [blobId, _] : Committed) {
+ ids.push_back(blobId);
+ }
+ UNIT_ASSERT_C(Committed.empty(), FormatList(ids));
+ IssueCollectGarbage();
+ }
+ }
+
+ void IssueCollectGarbage() {
+ if (Generation == 1) {
+ IssueWrites();
+ } else {
+ auto msg = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(TabletId, Generation, 1, 0, true,
+ Generation - 1, Max<ui32>(), nullptr, nullptr, TInstant::Max(), false, false);
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvCollectGarbage# "
+ << msg->ToString());
+ SendToProxy(TDuration::MilliSeconds(100), msg.release());
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvCollectGarbageResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvCollectGarbageResult# " << ev->Get()->ToString());
+ UNIT_ASSERT_C(ev->Get()->Status == NKikimrProto::OK || ev->Get()->Status == NKikimrProto::ALREADY, ev->Get()->Print(false));
+ IssueWrites();
+ }
+
+ TString GenerateBuffer() {
+ size_t len = 10 + RandomNumber<size_t>(32);
+ TString buffer = TString::Uninitialized(len);
+ char *data = buffer.Detach();
+ std::generate(data, data + len, TReallyFastRng32(TabletId ^ Step));
+ return buffer;
+ }
+
+ void IssueWrites() {
+ for (; Inflight.size() < MaxWritesInFlight && NumWritesRemaining; --NumWritesRemaining) {
+ TString buffer = GenerateBuffer();
+ const TLogoBlobID id(TabletId, Generation, Step++, 0, buffer.size(), 0);
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "sending TEvPut Id# " << id);
+ SendToProxy(Quoter.Take(TActivationContext::Now(), 1), new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
+ Inflight.emplace(id, std::move(buffer));
+ }
+ if (!NumWritesRemaining && Inflight.empty()) {
+ ++Generation;
+ IssueInitialCheck();
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvPutResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NActorsServices::TEST, Prefix << "got TEvPutResult# " << ev->Get()->ToString());
+ UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, NKikimrProto::OK, ev->Get()->Print(false));
+ auto it = Inflight.find(ev->Get()->Id);
+ UNIT_ASSERT(it != Inflight.end());
+ Committed.emplace(*it);
+ Inflight.erase(it);
+ IssueWrites();
+ }
+
+ void Handle(TEvents::TEvPoison::TPtr ev) {
+ TActivationContext::Send(new IEventHandle(EvFinished, 0, ev->Sender, SelfId(), {}, 0));
+ PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvStatusResult, Handle);
+ hFunc(TEvBlobStorage::TEvBlockResult, Handle);
+ hFunc(TEvBlobStorage::TEvDiscoverResult, Handle);
+ hFunc(TEvBlobStorage::TEvRangeResult, Handle);
+ hFunc(TEvBlobStorage::TEvGetResult, Handle);
+ hFunc(TEvBlobStorage::TEvPutResult, Handle);
+ hFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
+ hFunc(TEvents::TEvPoison, Handle);
+ )
+};
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/defs.h b/ydb/core/blobstorage/ut_blobstorage/lib/defs.h
index 1385b8fca36..b74a5717119 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/defs.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/defs.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h>
#include <ydb/core/blobstorage/dsproxy/mock/model.h>
#include <ydb/core/blobstorage/pdisk/mock/pdisk_mock.h>
@@ -11,10 +11,10 @@
#include <ydb/core/mind/bscontroller/types.h>
#include <ydb/core/mind/dynamic_nameserver.h>
#include <ydb/core/util/testactorsys.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/system/rusage.h>
-#include <util/random/fast.h>
-
-using namespace NActors;
-using namespace NKikimr;
-using namespace NKikimr::NBsController;
+#include <library/cpp/testing/unittest/registar.h>
+#include <util/system/rusage.h>
+#include <util/random/fast.h>
+
+using namespace NActors;
+using namespace NKikimr;
+using namespace NKikimr::NBsController;
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/env.h b/ydb/core/blobstorage/ut_blobstorage/lib/env.h
index 1cc05f00bf0..2967e0e9f81 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/env.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/env.h
@@ -1,650 +1,650 @@
-#pragma once
-
-#include "defs.h"
-
-#include "node_warden_mock.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-struct TEnvironmentSetup {
- std::unique_ptr<TTestActorSystem> Runtime;
- static constexpr ui32 DrivesPerNode = 5;
- const ui32 DomainId = 1;
- const ui64 TabletId = MakeBSControllerID(DomainId);
- const ui32 GroupId = 0;
- const TString StoragePoolName = "test";
- const ui32 NumGroups = 1;
- TIntrusivePtr<NFake::TProxyDS> Group0 = MakeIntrusive<NFake::TProxyDS>();
- std::map<std::pair<ui32, ui32>, TIntrusivePtr<TPDiskMockState>> PDiskMockStates;
- std::set<TActorId> CommencedReplication;
- std::unordered_map<ui32, TString> Cache;
-
- struct TSettings {
- const ui32 NodeCount = 9;
- const bool VDiskReplPausedAtStart = false;
- const TBlobStorageGroupType Erasure = TBlobStorageGroupType::ErasureNone;
- const TNodeWardenMockActor::TSetup::TPtr NodeWardenMockSetup;
- const bool Encryption = false;
- const std::function<void(ui32, TNodeWardenConfig&)> ConfigPreprocessor;
- const std::function<void(TTestActorSystem&)> PrepareRuntime;
- const ui32 ControllerNodeId = 1;
- const bool Cache = false;
- };
-
- const TSettings Settings;
-
- class TMockPDiskServiceFactory : public IPDiskServiceFactory {
- TEnvironmentSetup& Env;
-
- public:
- TMockPDiskServiceFactory(TEnvironmentSetup& env)
- : Env(env)
- {}
-
- void Create(const TActorContext& ctx, ui32 pdiskId, const TIntrusivePtr<TPDiskConfig>& cfg,
+#pragma once
+
+#include "defs.h"
+
+#include "node_warden_mock.h"
+
+#include <library/cpp/testing/unittest/registar.h>
+
+struct TEnvironmentSetup {
+ std::unique_ptr<TTestActorSystem> Runtime;
+ static constexpr ui32 DrivesPerNode = 5;
+ const ui32 DomainId = 1;
+ const ui64 TabletId = MakeBSControllerID(DomainId);
+ const ui32 GroupId = 0;
+ const TString StoragePoolName = "test";
+ const ui32 NumGroups = 1;
+ TIntrusivePtr<NFake::TProxyDS> Group0 = MakeIntrusive<NFake::TProxyDS>();
+ std::map<std::pair<ui32, ui32>, TIntrusivePtr<TPDiskMockState>> PDiskMockStates;
+ std::set<TActorId> CommencedReplication;
+ std::unordered_map<ui32, TString> Cache;
+
+ struct TSettings {
+ const ui32 NodeCount = 9;
+ const bool VDiskReplPausedAtStart = false;
+ const TBlobStorageGroupType Erasure = TBlobStorageGroupType::ErasureNone;
+ const TNodeWardenMockActor::TSetup::TPtr NodeWardenMockSetup;
+ const bool Encryption = false;
+ const std::function<void(ui32, TNodeWardenConfig&)> ConfigPreprocessor;
+ const std::function<void(TTestActorSystem&)> PrepareRuntime;
+ const ui32 ControllerNodeId = 1;
+ const bool Cache = false;
+ };
+
+ const TSettings Settings;
+
+ class TMockPDiskServiceFactory : public IPDiskServiceFactory {
+ TEnvironmentSetup& Env;
+
+ public:
+ TMockPDiskServiceFactory(TEnvironmentSetup& env)
+ : Env(env)
+ {}
+
+ void Create(const TActorContext& ctx, ui32 pdiskId, const TIntrusivePtr<TPDiskConfig>& cfg,
const NPDisk::TKey& /*mainKey*/, ui32 poolId, ui32 nodeId) override {
- const auto key = std::make_pair(nodeId, pdiskId);
- TIntrusivePtr<TPDiskMockState>& state = Env.PDiskMockStates[key];
- if (!state) {
- state.Reset(new TPDiskMockState(nodeId, pdiskId, cfg->PDiskGuid, ui64(10) << 40, cfg->ChunkSize));
- }
- const TActorId& actorId = ctx.Register(CreatePDiskMockActor(state), TMailboxType::HTSwap, poolId);
- const TActorId& serviceId = MakeBlobStoragePDiskID(nodeId, pdiskId);
- ctx.ExecutorThread.ActorSystem->RegisterLocalService(serviceId, actorId);
- }
- };
-
- TEnvironmentSetup(bool vdiskReplPausedAtStart, TBlobStorageGroupType erasure = TBlobStorageGroupType::ErasureNone)
- : TEnvironmentSetup(TSettings{
- .VDiskReplPausedAtStart = vdiskReplPausedAtStart,
- .Erasure = erasure
- })
- {}
-
+ const auto key = std::make_pair(nodeId, pdiskId);
+ TIntrusivePtr<TPDiskMockState>& state = Env.PDiskMockStates[key];
+ if (!state) {
+ state.Reset(new TPDiskMockState(nodeId, pdiskId, cfg->PDiskGuid, ui64(10) << 40, cfg->ChunkSize));
+ }
+ const TActorId& actorId = ctx.Register(CreatePDiskMockActor(state), TMailboxType::HTSwap, poolId);
+ const TActorId& serviceId = MakeBlobStoragePDiskID(nodeId, pdiskId);
+ ctx.ExecutorThread.ActorSystem->RegisterLocalService(serviceId, actorId);
+ }
+ };
+
+ TEnvironmentSetup(bool vdiskReplPausedAtStart, TBlobStorageGroupType erasure = TBlobStorageGroupType::ErasureNone)
+ : TEnvironmentSetup(TSettings{
+ .VDiskReplPausedAtStart = vdiskReplPausedAtStart,
+ .Erasure = erasure
+ })
+ {}
+
TEnvironmentSetup(ui32 nodeCount, TNodeWardenMockActor::TSetup::TPtr nodeWardenMockSetup,
- TBlobStorageGroupType erasure = TBlobStorageGroupType::ErasureNone)
- : TEnvironmentSetup(TSettings{
- .NodeCount = nodeCount,
+ TBlobStorageGroupType erasure = TBlobStorageGroupType::ErasureNone)
+ : TEnvironmentSetup(TSettings{
+ .NodeCount = nodeCount,
.Erasure = erasure,
- .NodeWardenMockSetup = std::move(nodeWardenMockSetup),
- })
- {}
-
- TEnvironmentSetup(TSettings&& settings)
- : Settings(std::move(settings))
- {
- struct TSetupEnv { TSetupEnv() { TEnvironmentSetup::SetupEnv(); } };
- Singleton<TSetupEnv>();
- Initialize();
- }
-
- ~TEnvironmentSetup() {
- Cleanup();
- }
-
- static void SetupEnv() {
- TAppData::TimeProvider = TTestActorSystem::CreateTimeProvider();
- ui64 seed = RandomNumber<ui64>();
- if (const TString& s = GetEnv("SEED", "")) {
- seed = FromString<ui64>(s);
- }
- SetRandomSeed(seed);
- TAppData::RandomProvider = CreateDeterministicRandomProvider(RandomNumber<ui64>());
- Cerr << "RandomSeed# " << seed << Endl;
- }
-
- void Initialize() {
- Runtime = std::make_unique<TTestActorSystem>(Settings.NodeCount);
- if (Settings.PrepareRuntime) {
- Settings.PrepareRuntime(*Runtime);
- }
- SetupLogging();
- Runtime->Start();
- auto *appData = Runtime->GetAppData();
- appData->DomainsInfo->AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dom", DomainId).Release());
- Runtime->SetupTabletRuntime(Settings.Erasure.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc,
- Settings.ControllerNodeId);
- SetupStaticStorage();
- SetupTablet();
- SetupStorage();
- }
-
- void StopNode(ui32 nodeId) {
- Runtime->StopNode(nodeId);
- }
-
- void StartNode(ui32 nodeId) {
- Runtime->StartNode(nodeId);
- Runtime->SetupTabletRuntime(Settings.Erasure.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc,
- Settings.ControllerNodeId, nodeId);
- if (nodeId == Settings.ControllerNodeId) {
- SetupStaticStorage();
- SetupTablet();
- }
- SetupStorage(nodeId);
- }
-
- void RestartNode(ui32 nodeId) {
- StopNode(nodeId);
- StartNode(nodeId);
- }
-
- void Cleanup() {
- Runtime->Stop();
- Runtime.reset();
- }
-
- template<typename TEvent>
- TAutoPtr<TEventHandle<TEvent>> WaitForEdgeActorEvent(const TActorId& actorId, bool termOnCapture = true,
- TInstant deadline = TInstant::Max()) {
- std::set<TActorId> ids{actorId};
-
- TActorId wakeup;
- if (deadline != TInstant::Max()) {
- wakeup = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
- Runtime->Schedule(deadline, new IEventHandle(TEvents::TSystem::Wakeup, 0, wakeup, {}, nullptr, 0), nullptr,
- wakeup.NodeId());
- ids.insert(wakeup);
- }
-
- for (;;) {
- auto ev = Runtime->WaitForEdgeActorEvent(ids);
- if (ev->GetRecipientRewrite() == wakeup && ev->GetTypeRewrite() == TEvents::TSystem::Wakeup) {
- Runtime->DestroyActor(wakeup);
- return nullptr;
- } else if (ev->GetTypeRewrite() == TEvent::EventType) {
- TAutoPtr<TEventHandle<TEvent>> res = reinterpret_cast<TEventHandle<TEvent>*>(ev.release());
- if (termOnCapture) {
- Runtime->DestroyActor(actorId);
- }
- if (wakeup) {
- Runtime->DestroyActor(wakeup);
- }
- return res;
- }
- }
- }
-
- NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
- const TActorId self = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
- ev->Record.MutableRequest()->CopyFrom(request);
- Runtime->SendToPipe(TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerConfigResponse>(self);
- return response->Get()->Record.GetResponse();
- }
-
- void SetupLogging() {
- Runtime->SetLogPriority(NKikimrServices::BS_HULLCOMP, NLog::PRI_NOTICE);
- Runtime->SetLogPriority(NKikimrServices::BS_VDISK_SCRUB, NLog::PRI_NOTICE);
-
- auto prio = NLog::PRI_ERROR;
- Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
- Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
- Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
- Runtime->SetLogPriority(NKikimrServices::BS_NODE, prio);
-
- std::initializer_list<ui32> debug{
-// NKikimrServices::BS_CONTROLLER,
-// NKikimrServices::BS_SELFHEAL,
-// NKikimrServices::BS_PDISK,
-// NKikimrServices::BS_SKELETON,
-// NKikimrServices::BS_HULLCOMP,
-// NKikimrServices::BS_HULLRECS,
-// NKikimrServices::BS_HULLHUGE,
-// NKikimrServices::BS_REPL,
-// NKikimrServices::BS_SYNCER,
-// NKikimrServices::BS_SYNCLOG,
-// NKikimrServices::BS_SYNCJOB,
-// NKikimrServices::BS_QUEUE,
-// NKikimrServices::BS_VDISK_GET,
-// NKikimrServices::BS_VDISK_PATCH,
-// NKikimrServices::BS_VDISK_PUT,
-// NKikimrServices::BS_VDISK_OTHER,
-// NKikimrServices::BS_PROXY,
-// NKikimrServices::BS_PROXY_RANGE,
-// NKikimrServices::BS_PROXY_GET,
-// NKikimrServices::BS_PROXY_PUT,
-// NKikimrServices::BS_PROXY_INDEXRESTOREGET,
-// NKikimrServices::BS_PROXY_STATUS,
- NActorsServices::TEST,
-// NActorsServices::INTERCONNECT,
-// NActorsServices::INTERCONNECT_SESSION,
- };
- for (const auto& comp : debug) {
- Runtime->SetLogPriority(comp, NLog::PRI_DEBUG);
- }
- }
-
- void SetupStaticStorage() {
- const TActorId proxyId = MakeBlobStorageProxyID(GroupId);
- Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(Group0), Settings.ControllerNodeId));
- }
-
- void SetupStorage(ui32 targetNodeId = 0) {
- for (ui32 nodeId : Runtime->GetNodes()) {
- if (targetNodeId && nodeId != targetNodeId) {
- continue;
- }
-
- std::unique_ptr<IActor> warden;
-
- if (Settings.NodeWardenMockSetup) {
- warden.reset(new TNodeWardenMockActor(Settings.NodeWardenMockSetup));
- } else {
- auto config = MakeIntrusive<TNodeWardenConfig>(new TMockPDiskServiceFactory(*this));
- config->ServiceSet.AddAvailabilityDomains(DomainId);
- config->VDiskReplPausedAtStart = Settings.VDiskReplPausedAtStart;
- if (Settings.ConfigPreprocessor) {
- Settings.ConfigPreprocessor(nodeId, *config);
- }
- if (Settings.Cache) {
- class TAccessor : public ICacheAccessor {
- TString& Data;
-
- public:
- TAccessor(TString& data) : Data(data) {}
- TString Read() { return Data; }
- void Update(std::function<TString(TString)> processor) { Data = processor(Data); }
- };
- config->CacheAccessor = std::make_unique<TAccessor>(Cache[nodeId]);
- }
- warden.reset(CreateBSNodeWarden(config));
- }
-
- const TActorId wardenId = Runtime->Register(warden.release(), nodeId);
- Runtime->RegisterService(MakeBlobStorageNodeWardenID(nodeId), wardenId);
- }
- }
-
- void SetupTablet() {
+ .NodeWardenMockSetup = std::move(nodeWardenMockSetup),
+ })
+ {}
+
+ TEnvironmentSetup(TSettings&& settings)
+ : Settings(std::move(settings))
+ {
+ struct TSetupEnv { TSetupEnv() { TEnvironmentSetup::SetupEnv(); } };
+ Singleton<TSetupEnv>();
+ Initialize();
+ }
+
+ ~TEnvironmentSetup() {
+ Cleanup();
+ }
+
+ static void SetupEnv() {
+ TAppData::TimeProvider = TTestActorSystem::CreateTimeProvider();
+ ui64 seed = RandomNumber<ui64>();
+ if (const TString& s = GetEnv("SEED", "")) {
+ seed = FromString<ui64>(s);
+ }
+ SetRandomSeed(seed);
+ TAppData::RandomProvider = CreateDeterministicRandomProvider(RandomNumber<ui64>());
+ Cerr << "RandomSeed# " << seed << Endl;
+ }
+
+ void Initialize() {
+ Runtime = std::make_unique<TTestActorSystem>(Settings.NodeCount);
+ if (Settings.PrepareRuntime) {
+ Settings.PrepareRuntime(*Runtime);
+ }
+ SetupLogging();
+ Runtime->Start();
+ auto *appData = Runtime->GetAppData();
+ appData->DomainsInfo->AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dom", DomainId).Release());
+ Runtime->SetupTabletRuntime(Settings.Erasure.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc,
+ Settings.ControllerNodeId);
+ SetupStaticStorage();
+ SetupTablet();
+ SetupStorage();
+ }
+
+ void StopNode(ui32 nodeId) {
+ Runtime->StopNode(nodeId);
+ }
+
+ void StartNode(ui32 nodeId) {
+ Runtime->StartNode(nodeId);
+ Runtime->SetupTabletRuntime(Settings.Erasure.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc,
+ Settings.ControllerNodeId, nodeId);
+ if (nodeId == Settings.ControllerNodeId) {
+ SetupStaticStorage();
+ SetupTablet();
+ }
+ SetupStorage(nodeId);
+ }
+
+ void RestartNode(ui32 nodeId) {
+ StopNode(nodeId);
+ StartNode(nodeId);
+ }
+
+ void Cleanup() {
+ Runtime->Stop();
+ Runtime.reset();
+ }
+
+ template<typename TEvent>
+ TAutoPtr<TEventHandle<TEvent>> WaitForEdgeActorEvent(const TActorId& actorId, bool termOnCapture = true,
+ TInstant deadline = TInstant::Max()) {
+ std::set<TActorId> ids{actorId};
+
+ TActorId wakeup;
+ if (deadline != TInstant::Max()) {
+ wakeup = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
+ Runtime->Schedule(deadline, new IEventHandle(TEvents::TSystem::Wakeup, 0, wakeup, {}, nullptr, 0), nullptr,
+ wakeup.NodeId());
+ ids.insert(wakeup);
+ }
+
+ for (;;) {
+ auto ev = Runtime->WaitForEdgeActorEvent(ids);
+ if (ev->GetRecipientRewrite() == wakeup && ev->GetTypeRewrite() == TEvents::TSystem::Wakeup) {
+ Runtime->DestroyActor(wakeup);
+ return nullptr;
+ } else if (ev->GetTypeRewrite() == TEvent::EventType) {
+ TAutoPtr<TEventHandle<TEvent>> res = reinterpret_cast<TEventHandle<TEvent>*>(ev.release());
+ if (termOnCapture) {
+ Runtime->DestroyActor(actorId);
+ }
+ if (wakeup) {
+ Runtime->DestroyActor(wakeup);
+ }
+ return res;
+ }
+ }
+ }
+
+ NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
+ const TActorId self = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
+ ev->Record.MutableRequest()->CopyFrom(request);
+ Runtime->SendToPipe(TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerConfigResponse>(self);
+ return response->Get()->Record.GetResponse();
+ }
+
+ void SetupLogging() {
+ Runtime->SetLogPriority(NKikimrServices::BS_HULLCOMP, NLog::PRI_NOTICE);
+ Runtime->SetLogPriority(NKikimrServices::BS_VDISK_SCRUB, NLog::PRI_NOTICE);
+
+ auto prio = NLog::PRI_ERROR;
+ Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
+ Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
+ Runtime->SetLogPriority(NKikimrServices::BS_NODE, prio);
+
+ std::initializer_list<ui32> debug{
+// NKikimrServices::BS_CONTROLLER,
+// NKikimrServices::BS_SELFHEAL,
+// NKikimrServices::BS_PDISK,
+// NKikimrServices::BS_SKELETON,
+// NKikimrServices::BS_HULLCOMP,
+// NKikimrServices::BS_HULLRECS,
+// NKikimrServices::BS_HULLHUGE,
+// NKikimrServices::BS_REPL,
+// NKikimrServices::BS_SYNCER,
+// NKikimrServices::BS_SYNCLOG,
+// NKikimrServices::BS_SYNCJOB,
+// NKikimrServices::BS_QUEUE,
+// NKikimrServices::BS_VDISK_GET,
+// NKikimrServices::BS_VDISK_PATCH,
+// NKikimrServices::BS_VDISK_PUT,
+// NKikimrServices::BS_VDISK_OTHER,
+// NKikimrServices::BS_PROXY,
+// NKikimrServices::BS_PROXY_RANGE,
+// NKikimrServices::BS_PROXY_GET,
+// NKikimrServices::BS_PROXY_PUT,
+// NKikimrServices::BS_PROXY_INDEXRESTOREGET,
+// NKikimrServices::BS_PROXY_STATUS,
+ NActorsServices::TEST,
+// NActorsServices::INTERCONNECT,
+// NActorsServices::INTERCONNECT_SESSION,
+ };
+ for (const auto& comp : debug) {
+ Runtime->SetLogPriority(comp, NLog::PRI_DEBUG);
+ }
+ }
+
+ void SetupStaticStorage() {
+ const TActorId proxyId = MakeBlobStorageProxyID(GroupId);
+ Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(Group0), Settings.ControllerNodeId));
+ }
+
+ void SetupStorage(ui32 targetNodeId = 0) {
+ for (ui32 nodeId : Runtime->GetNodes()) {
+ if (targetNodeId && nodeId != targetNodeId) {
+ continue;
+ }
+
+ std::unique_ptr<IActor> warden;
+
+ if (Settings.NodeWardenMockSetup) {
+ warden.reset(new TNodeWardenMockActor(Settings.NodeWardenMockSetup));
+ } else {
+ auto config = MakeIntrusive<TNodeWardenConfig>(new TMockPDiskServiceFactory(*this));
+ config->ServiceSet.AddAvailabilityDomains(DomainId);
+ config->VDiskReplPausedAtStart = Settings.VDiskReplPausedAtStart;
+ if (Settings.ConfigPreprocessor) {
+ Settings.ConfigPreprocessor(nodeId, *config);
+ }
+ if (Settings.Cache) {
+ class TAccessor : public ICacheAccessor {
+ TString& Data;
+
+ public:
+ TAccessor(TString& data) : Data(data) {}
+ TString Read() { return Data; }
+ void Update(std::function<TString(TString)> processor) { Data = processor(Data); }
+ };
+ config->CacheAccessor = std::make_unique<TAccessor>(Cache[nodeId]);
+ }
+ warden.reset(CreateBSNodeWarden(config));
+ }
+
+ const TActorId wardenId = Runtime->Register(warden.release(), nodeId);
+ Runtime->RegisterService(MakeBlobStorageNodeWardenID(nodeId), wardenId);
+ }
+ }
+
+ void SetupTablet() {
Runtime->CreateTestBootstrapper(
TTestActorSystem::CreateTestTabletInfo(TabletId, TTabletTypes::FLAT_BS_CONTROLLER, Settings.Erasure.GetErasure(), GroupId),
- &CreateFlatBsController,
- Settings.ControllerNodeId);
-
- bool working = true;
- Runtime->Sim([&] { return working; }, [&](IEventHandle& event) { working = event.GetTypeRewrite() != TEvTablet::EvBoot; });
- }
-
- void CreateBoxAndPool(ui32 numDrivesPerNode = 0, ui32 numGroups = 0, ui32 numStorageNodes = 0) {
- NKikimrBlobStorage::TConfigRequest request;
-
- auto *cmd = request.AddCommand()->MutableDefineHostConfig();
- cmd->SetHostConfigId(1);
- for (ui32 j = 0; j < (numDrivesPerNode ? numDrivesPerNode : DrivesPerNode); ++j) {
- auto *drive = cmd->AddDrive();
- drive->SetPath(Sprintf("SectorMap:%" PRIu32 ":1000", j));
- drive->SetType(NKikimrBlobStorage::EPDiskType::ROT);
- }
-
- cmd = request.AddCommand()->MutableDefineHostConfig();
- cmd->SetHostConfigId(2);
-
- auto *cmd1 = request.AddCommand()->MutableDefineBox();
- cmd1->SetBoxId(1);
- ui32 index = 0;
- for (ui32 nodeId : Runtime->GetNodes()) {
- auto *host = cmd1->AddHost();
- host->MutableKey()->SetNodeId(nodeId);
- host->SetHostConfigId(numStorageNodes == 0 || index < numStorageNodes ? 1 : 2);
- ++index;
- }
-
- auto *cmd2 = request.AddCommand()->MutableDefineStoragePool();
- cmd2->SetBoxId(1);
- cmd2->SetStoragePoolId(1);
- cmd2->SetName(StoragePoolName);
- cmd2->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(Settings.Erasure.GetErasure()));
- cmd2->SetVDiskKind("Default");
- cmd2->SetNumGroups(numGroups ? numGroups : NumGroups);
- cmd2->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::EPDiskType::ROT);
- if (Settings.Encryption) {
- cmd2->SetEncryptionMode(TBlobStorageGroupInfo::EEncryptionMode::EEM_ENC_V1);
- }
-
- auto response = Invoke(request);
+ &CreateFlatBsController,
+ Settings.ControllerNodeId);
+
+ bool working = true;
+ Runtime->Sim([&] { return working; }, [&](IEventHandle& event) { working = event.GetTypeRewrite() != TEvTablet::EvBoot; });
+ }
+
+ void CreateBoxAndPool(ui32 numDrivesPerNode = 0, ui32 numGroups = 0, ui32 numStorageNodes = 0) {
+ NKikimrBlobStorage::TConfigRequest request;
+
+ auto *cmd = request.AddCommand()->MutableDefineHostConfig();
+ cmd->SetHostConfigId(1);
+ for (ui32 j = 0; j < (numDrivesPerNode ? numDrivesPerNode : DrivesPerNode); ++j) {
+ auto *drive = cmd->AddDrive();
+ drive->SetPath(Sprintf("SectorMap:%" PRIu32 ":1000", j));
+ drive->SetType(NKikimrBlobStorage::EPDiskType::ROT);
+ }
+
+ cmd = request.AddCommand()->MutableDefineHostConfig();
+ cmd->SetHostConfigId(2);
+
+ auto *cmd1 = request.AddCommand()->MutableDefineBox();
+ cmd1->SetBoxId(1);
+ ui32 index = 0;
+ for (ui32 nodeId : Runtime->GetNodes()) {
+ auto *host = cmd1->AddHost();
+ host->MutableKey()->SetNodeId(nodeId);
+ host->SetHostConfigId(numStorageNodes == 0 || index < numStorageNodes ? 1 : 2);
+ ++index;
+ }
+
+ auto *cmd2 = request.AddCommand()->MutableDefineStoragePool();
+ cmd2->SetBoxId(1);
+ cmd2->SetStoragePoolId(1);
+ cmd2->SetName(StoragePoolName);
+ cmd2->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(Settings.Erasure.GetErasure()));
+ cmd2->SetVDiskKind("Default");
+ cmd2->SetNumGroups(numGroups ? numGroups : NumGroups);
+ cmd2->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::EPDiskType::ROT);
+ if (Settings.Encryption) {
+ cmd2->SetEncryptionMode(TBlobStorageGroupInfo::EEncryptionMode::EEM_ENC_V1);
+ }
+
+ auto response = Invoke(request);
UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- }
-
- std::vector<ui32> GetGroups() {
- const TActorId& edge = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerSelectGroups>();
- auto& r = ev->Record;
- auto *params = r.AddGroupParameters();
- params->MutableStoragePoolSpecifier()->SetName(StoragePoolName);
- r.SetReturnAllMatchingGroups(true);
- Runtime->SendToPipe(TabletId, edge, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerSelectGroupsResult>(edge);
- auto& rr = response->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(rr.MatchingGroupsSize(), 1);
- const auto& mg = rr.GetMatchingGroups(0);
- std::vector<ui32> res;
- for (const auto& group : mg.GetGroups()) {
- res.push_back(group.GetGroupID());
- }
- return res;
- }
-
- NKikimrBlobStorage::TBaseConfig FetchBaseConfig() {
- NKikimrBlobStorage::TConfigRequest request;
- request.AddCommand()->MutableQueryBaseConfig();
- auto response = Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- UNIT_ASSERT_VALUES_EQUAL(response.StatusSize(), 1);
- return response.GetStatus(0).GetBaseConfig();
- }
-
- TIntrusivePtr<TBlobStorageGroupInfo> GetGroupInfo(ui32 groupId) {
- const auto& baseConfig = FetchBaseConfig();
- std::map<TActorId, TVDiskID> vslotToDiskMap;
- for (const auto& vslot : baseConfig.GetVSlot()) {
- const auto& l = vslot.GetVSlotId();
- vslotToDiskMap.emplace(MakeBlobStorageVDiskID(l.GetNodeId(), l.GetPDiskId(), l.GetVSlotId()),
- TVDiskID(vslot.GetGroupId(), vslot.GetGroupGeneration(), vslot.GetFailRealmIdx(),
- vslot.GetFailDomainIdx(), vslot.GetVDiskIdx()));
- }
- for (const auto& group : baseConfig.GetGroup()) {
- if (group.GetGroupId() == groupId) {
- std::map<TVDiskID, TActorId> vdisks;
- ui32 numFailRealms = 0;
- ui32 numFailDomainsPerFailRealm = 0;
- ui32 numVDisksPerFailDomain = 0;
- for (const auto& l : group.GetVSlotId()) {
- const auto it = vslotToDiskMap.find(MakeBlobStorageVDiskID(l.GetNodeId(), l.GetPDiskId(), l.GetVSlotId()));
- Y_VERIFY(it != vslotToDiskMap.end());
- const TVDiskID& vdiskId = it->second;
- Y_VERIFY(vdiskId.GroupID == groupId);
- Y_VERIFY(vdiskId.GroupGeneration == group.GetGroupGeneration());
- const bool inserted = vdisks.emplace(it->second, it->first).second;
- Y_VERIFY(inserted);
- numFailRealms = Max<ui32>(numFailRealms, vdiskId.FailRealm + 1);
- numFailDomainsPerFailRealm = Max<ui32>(numFailDomainsPerFailRealm, vdiskId.FailDomain + 1);
- numVDisksPerFailDomain = Max<ui32>(numVDisksPerFailDomain, vdiskId.VDisk + 1);
- }
- Y_VERIFY(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain == vdisks.size());
- TBlobStorageGroupInfo::TTopology topology(TBlobStorageGroupType(
- TBlobStorageGroupType::ErasureSpeciesByName(group.GetErasureSpecies())),
- numFailRealms, numFailDomainsPerFailRealm, numVDisksPerFailDomain);
- TBlobStorageGroupInfo::TDynamicInfo dyn(group.GetGroupId(), group.GetGroupGeneration());
- for (const auto& [vdiskId, vdiskActorId] : vdisks) {
- dyn.PushBackActorId(vdiskActorId);
- }
- return new TBlobStorageGroupInfo(std::move(topology), std::move(dyn), "storage_pool");
- }
- }
- return nullptr;
- }
-
- TActorId CreateQueueActor(const TVDiskID& vdiskId, NKikimrBlobStorage::EVDiskQueueId queueId, ui32 index) {
- TBSProxyContextPtr bspctx = MakeIntrusive<TBSProxyContext>(MakeIntrusive<NMonitoring::TDynamicCounters>());
- auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
- auto groupInfo = GetGroupInfo(vdiskId.GroupID);
- std::unique_ptr<IActor> actor(CreateVDiskBackpressureClient(groupInfo, vdiskId, queueId,
- MakeIntrusive<NMonitoring::TDynamicCounters>(), bspctx,
- NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, index), TStringBuilder()
- << "test# " << index, 0, false, TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
- const ui32 nodeId = Settings.ControllerNodeId;
- const TActorId edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
- const TActorId actorId = Runtime->Register(actor.release(), edge, {}, {}, nodeId);
- const TInstant deadline = Runtime->GetClock() + TDuration::Minutes(1);
- for (;;) {
- auto ev = WaitForEdgeActorEvent<TEvProxyQueueState>(edge, false, deadline);
- if (!ev || ev->Get()->IsConnected) {
- Runtime->DestroyActor(edge);
- break;
- }
- }
- return actorId;
- }
-
- void WaitForVDiskRepl(const TActorId& actorId, const TVDiskID& vdiskId) {
- const ui32 nodeId = actorId.NodeId();
- const TActorId& edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
- for (;;) {
- Runtime->Send(new IEventHandle(actorId, edge, new TEvBlobStorage::TEvVStatus(vdiskId),
- IEventHandle::FlagTrackDelivery), nodeId);
- auto r = Runtime->WaitForEdgeActorEvent({edge});
- if (auto *msg = r->CastAsLocal<TEvBlobStorage::TEvVStatusResult>(); msg && msg->Record.GetReplicated()) {
- Runtime->DestroyActor(edge);
- break;
- }
- Sim(TDuration::Seconds(5));
- }
- }
-
- void CompactVDisk(const TActorId& actorId, bool freshOnly = false) {
- const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId());
- for (;;) {
- Runtime->Send(new IEventHandle(actorId, edge, TEvCompactVDisk::Create(EHullDbType::LogoBlobs, freshOnly ?
- TEvCompactVDisk::EMode::FRESH_ONLY : TEvCompactVDisk::EMode::FULL)), actorId.NodeId());
- auto res = Runtime->WaitForEdgeActorEvent({edge});
- if (res->GetTypeRewrite() == TEvents::TSystem::Undelivered) {
- Sim(TDuration::Seconds(5));
- } else {
- Y_VERIFY(res->GetTypeRewrite() == TEvBlobStorage::EvCompactVDiskResult);
- Runtime->DestroyActor(edge);
- return;
- }
- }
- }
-
- void Sim(TDuration delta = TDuration::Zero()) {
- TInstant barrier = Runtime->GetClock() + delta;
- Runtime->Sim([&] { return Runtime->GetClock() <= barrier; });
- }
-
- TString Dump(const TActorId& vdiskActorId, const TVDiskID& vdiskId) {
- const TActorId& edge = Runtime->AllocateEdgeActor(vdiskActorId.NodeId(), __FILE__, __LINE__);
- Runtime->Send(new IEventHandle(vdiskActorId, edge, new TEvBlobStorage::TEvVDbStat(vdiskId,
- NKikimrBlobStorage::EDbStatAction::DumpDb, NKikimrBlobStorage::EDbStatType::StatLogoBlobs,
- true)), edge.NodeId());
- return WaitForEdgeActorEvent<TEvBlobStorage::TEvVDbStatResult>(edge)->Get()->Record.GetData();
- }
-
+ }
+
+ std::vector<ui32> GetGroups() {
+ const TActorId& edge = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerSelectGroups>();
+ auto& r = ev->Record;
+ auto *params = r.AddGroupParameters();
+ params->MutableStoragePoolSpecifier()->SetName(StoragePoolName);
+ r.SetReturnAllMatchingGroups(true);
+ Runtime->SendToPipe(TabletId, edge, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerSelectGroupsResult>(edge);
+ auto& rr = response->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(rr.MatchingGroupsSize(), 1);
+ const auto& mg = rr.GetMatchingGroups(0);
+ std::vector<ui32> res;
+ for (const auto& group : mg.GetGroups()) {
+ res.push_back(group.GetGroupID());
+ }
+ return res;
+ }
+
+ NKikimrBlobStorage::TBaseConfig FetchBaseConfig() {
+ NKikimrBlobStorage::TConfigRequest request;
+ request.AddCommand()->MutableQueryBaseConfig();
+ auto response = Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ UNIT_ASSERT_VALUES_EQUAL(response.StatusSize(), 1);
+ return response.GetStatus(0).GetBaseConfig();
+ }
+
+ TIntrusivePtr<TBlobStorageGroupInfo> GetGroupInfo(ui32 groupId) {
+ const auto& baseConfig = FetchBaseConfig();
+ std::map<TActorId, TVDiskID> vslotToDiskMap;
+ for (const auto& vslot : baseConfig.GetVSlot()) {
+ const auto& l = vslot.GetVSlotId();
+ vslotToDiskMap.emplace(MakeBlobStorageVDiskID(l.GetNodeId(), l.GetPDiskId(), l.GetVSlotId()),
+ TVDiskID(vslot.GetGroupId(), vslot.GetGroupGeneration(), vslot.GetFailRealmIdx(),
+ vslot.GetFailDomainIdx(), vslot.GetVDiskIdx()));
+ }
+ for (const auto& group : baseConfig.GetGroup()) {
+ if (group.GetGroupId() == groupId) {
+ std::map<TVDiskID, TActorId> vdisks;
+ ui32 numFailRealms = 0;
+ ui32 numFailDomainsPerFailRealm = 0;
+ ui32 numVDisksPerFailDomain = 0;
+ for (const auto& l : group.GetVSlotId()) {
+ const auto it = vslotToDiskMap.find(MakeBlobStorageVDiskID(l.GetNodeId(), l.GetPDiskId(), l.GetVSlotId()));
+ Y_VERIFY(it != vslotToDiskMap.end());
+ const TVDiskID& vdiskId = it->second;
+ Y_VERIFY(vdiskId.GroupID == groupId);
+ Y_VERIFY(vdiskId.GroupGeneration == group.GetGroupGeneration());
+ const bool inserted = vdisks.emplace(it->second, it->first).second;
+ Y_VERIFY(inserted);
+ numFailRealms = Max<ui32>(numFailRealms, vdiskId.FailRealm + 1);
+ numFailDomainsPerFailRealm = Max<ui32>(numFailDomainsPerFailRealm, vdiskId.FailDomain + 1);
+ numVDisksPerFailDomain = Max<ui32>(numVDisksPerFailDomain, vdiskId.VDisk + 1);
+ }
+ Y_VERIFY(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain == vdisks.size());
+ TBlobStorageGroupInfo::TTopology topology(TBlobStorageGroupType(
+ TBlobStorageGroupType::ErasureSpeciesByName(group.GetErasureSpecies())),
+ numFailRealms, numFailDomainsPerFailRealm, numVDisksPerFailDomain);
+ TBlobStorageGroupInfo::TDynamicInfo dyn(group.GetGroupId(), group.GetGroupGeneration());
+ for (const auto& [vdiskId, vdiskActorId] : vdisks) {
+ dyn.PushBackActorId(vdiskActorId);
+ }
+ return new TBlobStorageGroupInfo(std::move(topology), std::move(dyn), "storage_pool");
+ }
+ }
+ return nullptr;
+ }
+
+ TActorId CreateQueueActor(const TVDiskID& vdiskId, NKikimrBlobStorage::EVDiskQueueId queueId, ui32 index) {
+ TBSProxyContextPtr bspctx = MakeIntrusive<TBSProxyContext>(MakeIntrusive<NMonitoring::TDynamicCounters>());
+ auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
+ auto groupInfo = GetGroupInfo(vdiskId.GroupID);
+ std::unique_ptr<IActor> actor(CreateVDiskBackpressureClient(groupInfo, vdiskId, queueId,
+ MakeIntrusive<NMonitoring::TDynamicCounters>(), bspctx,
+ NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, index), TStringBuilder()
+ << "test# " << index, 0, false, TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
+ const ui32 nodeId = Settings.ControllerNodeId;
+ const TActorId edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
+ const TActorId actorId = Runtime->Register(actor.release(), edge, {}, {}, nodeId);
+ const TInstant deadline = Runtime->GetClock() + TDuration::Minutes(1);
+ for (;;) {
+ auto ev = WaitForEdgeActorEvent<TEvProxyQueueState>(edge, false, deadline);
+ if (!ev || ev->Get()->IsConnected) {
+ Runtime->DestroyActor(edge);
+ break;
+ }
+ }
+ return actorId;
+ }
+
+ void WaitForVDiskRepl(const TActorId& actorId, const TVDiskID& vdiskId) {
+ const ui32 nodeId = actorId.NodeId();
+ const TActorId& edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
+ for (;;) {
+ Runtime->Send(new IEventHandle(actorId, edge, new TEvBlobStorage::TEvVStatus(vdiskId),
+ IEventHandle::FlagTrackDelivery), nodeId);
+ auto r = Runtime->WaitForEdgeActorEvent({edge});
+ if (auto *msg = r->CastAsLocal<TEvBlobStorage::TEvVStatusResult>(); msg && msg->Record.GetReplicated()) {
+ Runtime->DestroyActor(edge);
+ break;
+ }
+ Sim(TDuration::Seconds(5));
+ }
+ }
+
+ void CompactVDisk(const TActorId& actorId, bool freshOnly = false) {
+ const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId());
+ for (;;) {
+ Runtime->Send(new IEventHandle(actorId, edge, TEvCompactVDisk::Create(EHullDbType::LogoBlobs, freshOnly ?
+ TEvCompactVDisk::EMode::FRESH_ONLY : TEvCompactVDisk::EMode::FULL)), actorId.NodeId());
+ auto res = Runtime->WaitForEdgeActorEvent({edge});
+ if (res->GetTypeRewrite() == TEvents::TSystem::Undelivered) {
+ Sim(TDuration::Seconds(5));
+ } else {
+ Y_VERIFY(res->GetTypeRewrite() == TEvBlobStorage::EvCompactVDiskResult);
+ Runtime->DestroyActor(edge);
+ return;
+ }
+ }
+ }
+
+ void Sim(TDuration delta = TDuration::Zero()) {
+ TInstant barrier = Runtime->GetClock() + delta;
+ Runtime->Sim([&] { return Runtime->GetClock() <= barrier; });
+ }
+
+ TString Dump(const TActorId& vdiskActorId, const TVDiskID& vdiskId) {
+ const TActorId& edge = Runtime->AllocateEdgeActor(vdiskActorId.NodeId(), __FILE__, __LINE__);
+ Runtime->Send(new IEventHandle(vdiskActorId, edge, new TEvBlobStorage::TEvVDbStat(vdiskId,
+ NKikimrBlobStorage::EDbStatAction::DumpDb, NKikimrBlobStorage::EDbStatType::StatLogoBlobs,
+ true)), edge.NodeId());
+ return WaitForEdgeActorEvent<TEvBlobStorage::TEvVDbStatResult>(edge)->Get()->Record.GetData();
+ }
+
void WithQueueId(const TVDiskID& vdiskId, NKikimrBlobStorage::EVDiskQueueId queue, std::function<void(TActorId)> action) {
const TActorId& queueId = CreateQueueActor(vdiskId, queue, 1000);
action(queueId);
Runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, queueId, {}, nullptr, 0), queueId.NodeId());
}
- void CheckBlob(const TActorId& vdiskActorId, const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& part,
- NKikimrProto::EReplyStatus status = NKikimrProto::OK) {
+ void CheckBlob(const TActorId& vdiskActorId, const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& part,
+ NKikimrProto::EReplyStatus status = NKikimrProto::OK) {
WithQueueId(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, [&](TActorId queueId) {
const TActorId& edge = Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
Runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId,
TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
- Nothing(), {{blobId, 1u, ui32(part.size() - 2)}}).release()), queueId.NodeId());
- auto r = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
- {
- auto& record = r->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
- const auto& res = record.GetResult(0);
- UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), status, Dump(vdiskActorId, vdiskId));
- if (status == NKikimrProto::OK) {
- UNIT_ASSERT_VALUES_EQUAL(res.GetBuffer(), part.substr(1, part.size() - 2));
- }
- }
-
- Runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(vdiskId,
- TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
- Nothing(), {{blobId.FullID(), 0, 0}}).release()), queueId.NodeId());
- r = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
- {
- auto& record = r->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
- const auto& res = record.GetResult(0);
- UNIT_ASSERT(!res.HasBuffer());
- UNIT_ASSERT_VALUES_EQUAL(LogoBlobIDFromLogoBlobID(res.GetBlobID()), blobId.FullID());
- UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), status);
+ Nothing(), {{blobId, 1u, ui32(part.size() - 2)}}).release()), queueId.NodeId());
+ auto r = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
+ {
+ auto& record = r->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
+ const auto& res = record.GetResult(0);
+ UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), status, Dump(vdiskActorId, vdiskId));
+ if (status == NKikimrProto::OK) {
+ UNIT_ASSERT_VALUES_EQUAL(res.GetBuffer(), part.substr(1, part.size() - 2));
+ }
+ }
+
+ Runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(vdiskId,
+ TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
+ Nothing(), {{blobId.FullID(), 0, 0}}).release()), queueId.NodeId());
+ r = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
+ {
+ auto& record = r->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
+ const auto& res = record.GetResult(0);
+ UNIT_ASSERT(!res.HasBuffer());
+ UNIT_ASSERT_VALUES_EQUAL(LogoBlobIDFromLogoBlobID(res.GetBlobID()), blobId.FullID());
+ UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), status);
}
});
- }
-
- void PutBlob(const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& part) {
+ }
+
+ void PutBlob(const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& part) {
WithQueueId(vdiskId, NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, [&](TActorId queueId) {
const TActorId& edge = Runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
Runtime->Send(new IEventHandle(queueId, edge, new TEvBlobStorage::TEvVPut(blobId, part, vdiskId, false, nullptr,
TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog)), queueId.NodeId());
auto r = WaitForEdgeActorEvent<TEvBlobStorage::TEvVPutResult>(edge);
-
+
auto& record = r->Get()->Record;
Cerr << "*** PUT BLOB " << blobId << " TO " << vdiskId << " FINISHED WITH "
<< NKikimrProto::EReplyStatus_Name(record.GetStatus()) << " ***" << Endl;
UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
});
- }
-
- void CommenceReplication() {
- for (ui32 groupId : GetGroups()) {
- auto info = GetGroupInfo(groupId);
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TActorId& serviceId = info->GetActorId(i);
- if (!CommencedReplication.insert(serviceId).second) {
- continue;
- }
- while (!Runtime->Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, serviceId, {}, nullptr, 0), serviceId.NodeId())) {
- Sim(TDuration::Seconds(1)); // VDisk may be not created yet
- }
- WaitForVDiskRepl(serviceId, info->GetVDiskId(i));
- }
- }
- }
-
- void WaitForSync(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TLogoBlobID& blobId) {
- std::map<TVDiskID, TActorId> queues;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TVDiskID& vdiskId = info->GetVDiskId(i);
- queues.emplace(vdiskId, CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
- }
- for (;;) {
- ui32 numDone = 0;
- for (const auto& [vdiskId, queueId] : queues) {
- const ui32 nodeId = queueId.NodeId();
- const TActorId& edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
- Runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(
- vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::ShowInternals, {}, {blobId.FullID()}).release()), nodeId);
- auto ev = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
- const auto& record = ev->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
- const auto& result = record.GetResult(0);
- numDone += result.HasIngress();
- }
- Cerr << "numDone# " << numDone << Endl;
- if (numDone >= info->Type.BlobSubgroupSize()) {
- break;
- }
- Sim(TDuration::Seconds(10));
- }
- for (const auto& [vdiskId, queueId] : queues) {
- Runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, queueId, {}, nullptr, 0), queueId.NodeId());
- }
- }
-
- void EnableDonorMode() {
- NKikimrBlobStorage::TConfigRequest request;
- request.AddCommand()->MutableEnableDonorMode()->SetEnable(true);
- auto response = Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- }
-
- void SetScrubPeriodicity(TDuration periodicity) {
- NKikimrBlobStorage::TConfigRequest request;
- request.AddCommand()->MutableSetScrubPeriodicity()->SetScrubPeriodicity(periodicity.Seconds());
- auto response = Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- }
-
- void SettlePDisk(const TActorId& vdiskActorId) {
- ui32 nodeId, pdiskId;
- std::tie(nodeId, pdiskId, std::ignore) = DecomposeVDiskServiceId(vdiskActorId);
- for (const auto& status : {NKikimrBlobStorage::EDriveStatus::BROKEN, NKikimrBlobStorage::EDriveStatus::ACTIVE}) {
- for (;;) {
- NKikimrBlobStorage::TConfigRequest request;
- auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
- cmd->MutableHostKey()->SetNodeId(nodeId);
- cmd->SetPDiskId(pdiskId);
- cmd->SetStatus(status);
- auto response = Invoke(request);
- if (response.GetSuccess()) {
- break;
- }
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- Sim(TDuration::Seconds(5));
- }
- }
- Sim(TDuration::Seconds(15));
- }
-
- void Wipe(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
- const TActorId self = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
- auto& record = ev->Record;
- auto *vslot = record.MutableVSlotId();
- vslot->SetNodeId(nodeId);
- vslot->SetPDiskId(pdiskId);
- vslot->SetVSlotId(vslotId);
- Runtime->SendToPipe(TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
- UNIT_ASSERT_VALUES_EQUAL(response->Get()->Record.GetStatus(), NKikimrProto::OK);
- }
-
- void WaitForVDiskToGetRunning(const TVDiskID& vdiskId, TActorId actorId) {
- for (;;) {
- const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
- auto ev = std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId);
- TString request = ev->ToString();
- Runtime->Send(new IEventHandle(actorId, edge, ev.release(), IEventHandle::FlagTrackDelivery), edge.NodeId());
- auto res = Runtime->WaitForEdgeActorEvent({edge});
- if (auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVStatusResult>()) {
- const auto& record = msg->Record;
- if (record.GetStatus() == NKikimrProto::OK && record.GetJoinedGroup() && record.GetReplicated()) {
- break;
- }
- } else if (auto *msg = res->CastAsLocal<TEvents::TEvUndelivered>()) {
- Y_VERIFY(msg->SourceType == TEvBlobStorage::EvVStatus);
- } else {
- Y_FAIL();
- }
-
- // sleep for a while
- {
- const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
- Runtime->Schedule(TDuration::Minutes(1), new IEventHandle(TEvents::TSystem::Wakeup, 0, edge, {}, nullptr, 0), nullptr, edge.NodeId());
- WaitForEdgeActorEvent<TEvents::TEvWakeup>(edge);
- }
- }
- }
-
- template<typename TResult, typename TFactory>
- std::unique_ptr<TResult> SyncQueryFactory(const TActorId& actorId, TFactory&& factory, bool checkUndelivered = true) {
- const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
- for (;;) {
- std::unique_ptr<typename std::invoke_result_t<TFactory>::element_type> ev(factory());
- Runtime->Send(new IEventHandle(actorId, edge, ev.release(), IEventHandle::FlagTrackDelivery), edge.NodeId());
- auto res = Runtime->WaitForEdgeActorEvent({edge});
- if (auto *msg = res->CastAsLocal<TEvents::TEvUndelivered>()) {
- UNIT_ASSERT(checkUndelivered);
- Sim(TDuration::Seconds(5));
- } else {
- UNIT_ASSERT_VALUES_EQUAL(res->Type, TResult::EventType);
- Runtime->DestroyActor(edge);
- return std::unique_ptr<TResult>(static_cast<TResult*>(res->ReleaseBase().Release()));
- }
- }
- }
-
- template<typename TResult, typename TQuery, typename... TArgs>
- std::unique_ptr<TResult> SyncQuery(const TActorId& actorId, TArgs&&... args) {
- return SyncQueryFactory<TResult>(actorId, [&] { return std::make_unique<TQuery>(args...); });
- }
-
-};
+ }
+
+ void CommenceReplication() {
+ for (ui32 groupId : GetGroups()) {
+ auto info = GetGroupInfo(groupId);
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TActorId& serviceId = info->GetActorId(i);
+ if (!CommencedReplication.insert(serviceId).second) {
+ continue;
+ }
+ while (!Runtime->Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, serviceId, {}, nullptr, 0), serviceId.NodeId())) {
+ Sim(TDuration::Seconds(1)); // VDisk may be not created yet
+ }
+ WaitForVDiskRepl(serviceId, info->GetVDiskId(i));
+ }
+ }
+ }
+
+ void WaitForSync(const TIntrusivePtr<TBlobStorageGroupInfo>& info, const TLogoBlobID& blobId) {
+ std::map<TVDiskID, TActorId> queues;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TVDiskID& vdiskId = info->GetVDiskId(i);
+ queues.emplace(vdiskId, CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
+ }
+ for (;;) {
+ ui32 numDone = 0;
+ for (const auto& [vdiskId, queueId] : queues) {
+ const ui32 nodeId = queueId.NodeId();
+ const TActorId& edge = Runtime->AllocateEdgeActor(nodeId, __FILE__, __LINE__);
+ Runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(
+ vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::ShowInternals, {}, {blobId.FullID()}).release()), nodeId);
+ auto ev = WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
+ const auto& record = ev->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(record.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(record.ResultSize(), 1);
+ const auto& result = record.GetResult(0);
+ numDone += result.HasIngress();
+ }
+ Cerr << "numDone# " << numDone << Endl;
+ if (numDone >= info->Type.BlobSubgroupSize()) {
+ break;
+ }
+ Sim(TDuration::Seconds(10));
+ }
+ for (const auto& [vdiskId, queueId] : queues) {
+ Runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, queueId, {}, nullptr, 0), queueId.NodeId());
+ }
+ }
+
+ void EnableDonorMode() {
+ NKikimrBlobStorage::TConfigRequest request;
+ request.AddCommand()->MutableEnableDonorMode()->SetEnable(true);
+ auto response = Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ }
+
+ void SetScrubPeriodicity(TDuration periodicity) {
+ NKikimrBlobStorage::TConfigRequest request;
+ request.AddCommand()->MutableSetScrubPeriodicity()->SetScrubPeriodicity(periodicity.Seconds());
+ auto response = Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ }
+
+ void SettlePDisk(const TActorId& vdiskActorId) {
+ ui32 nodeId, pdiskId;
+ std::tie(nodeId, pdiskId, std::ignore) = DecomposeVDiskServiceId(vdiskActorId);
+ for (const auto& status : {NKikimrBlobStorage::EDriveStatus::BROKEN, NKikimrBlobStorage::EDriveStatus::ACTIVE}) {
+ for (;;) {
+ NKikimrBlobStorage::TConfigRequest request;
+ auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
+ cmd->MutableHostKey()->SetNodeId(nodeId);
+ cmd->SetPDiskId(pdiskId);
+ cmd->SetStatus(status);
+ auto response = Invoke(request);
+ if (response.GetSuccess()) {
+ break;
+ }
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ Sim(TDuration::Seconds(5));
+ }
+ }
+ Sim(TDuration::Seconds(15));
+ }
+
+ void Wipe(ui32 nodeId, ui32 pdiskId, ui32 vslotId) {
+ const TActorId self = Runtime->AllocateEdgeActor(Settings.ControllerNodeId, __FILE__, __LINE__);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
+ auto& record = ev->Record;
+ auto *vslot = record.MutableVSlotId();
+ vslot->SetNodeId(nodeId);
+ vslot->SetPDiskId(pdiskId);
+ vslot->SetVSlotId(vslotId);
+ Runtime->SendToPipe(TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
+ UNIT_ASSERT_VALUES_EQUAL(response->Get()->Record.GetStatus(), NKikimrProto::OK);
+ }
+
+ void WaitForVDiskToGetRunning(const TVDiskID& vdiskId, TActorId actorId) {
+ for (;;) {
+ const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
+ auto ev = std::make_unique<TEvBlobStorage::TEvVStatus>(vdiskId);
+ TString request = ev->ToString();
+ Runtime->Send(new IEventHandle(actorId, edge, ev.release(), IEventHandle::FlagTrackDelivery), edge.NodeId());
+ auto res = Runtime->WaitForEdgeActorEvent({edge});
+ if (auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVStatusResult>()) {
+ const auto& record = msg->Record;
+ if (record.GetStatus() == NKikimrProto::OK && record.GetJoinedGroup() && record.GetReplicated()) {
+ break;
+ }
+ } else if (auto *msg = res->CastAsLocal<TEvents::TEvUndelivered>()) {
+ Y_VERIFY(msg->SourceType == TEvBlobStorage::EvVStatus);
+ } else {
+ Y_FAIL();
+ }
+
+ // sleep for a while
+ {
+ const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
+ Runtime->Schedule(TDuration::Minutes(1), new IEventHandle(TEvents::TSystem::Wakeup, 0, edge, {}, nullptr, 0), nullptr, edge.NodeId());
+ WaitForEdgeActorEvent<TEvents::TEvWakeup>(edge);
+ }
+ }
+ }
+
+ template<typename TResult, typename TFactory>
+ std::unique_ptr<TResult> SyncQueryFactory(const TActorId& actorId, TFactory&& factory, bool checkUndelivered = true) {
+ const TActorId& edge = Runtime->AllocateEdgeActor(actorId.NodeId(), __FILE__, __LINE__);
+ for (;;) {
+ std::unique_ptr<typename std::invoke_result_t<TFactory>::element_type> ev(factory());
+ Runtime->Send(new IEventHandle(actorId, edge, ev.release(), IEventHandle::FlagTrackDelivery), edge.NodeId());
+ auto res = Runtime->WaitForEdgeActorEvent({edge});
+ if (auto *msg = res->CastAsLocal<TEvents::TEvUndelivered>()) {
+ UNIT_ASSERT(checkUndelivered);
+ Sim(TDuration::Seconds(5));
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(res->Type, TResult::EventType);
+ Runtime->DestroyActor(edge);
+ return std::unique_ptr<TResult>(static_cast<TResult*>(res->ReleaseBase().Release()));
+ }
+ }
+ }
+
+ template<typename TResult, typename TQuery, typename... TArgs>
+ std::unique_ptr<TResult> SyncQuery(const TActorId& actorId, TArgs&&... args) {
+ return SyncQueryFactory<TResult>(actorId, [&] { return std::make_unique<TQuery>(args...); });
+ }
+
+};
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock.h b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock.h
index d311a90a76d..2c79bf2acac 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock.h
@@ -1,128 +1,128 @@
-#pragma once
-
-#include "defs.h"
-
-class TNodeWardenMockActor : public TActorBootstrapped<TNodeWardenMockActor> {
-public:
- struct TPDiskId {
- ui32 NodeId;
- ui32 PDiskId;
-
- TPDiskId(ui32 nodeId, ui32 pdiskId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- {}
-
- TString ToString() const {
- return TStringBuilder() << NodeId << ":" << PDiskId;
- }
-
- friend bool operator ==(const TPDiskId& x, const TPDiskId& y) {
- return x.NodeId == y.NodeId && x.PDiskId == y.PDiskId;
- }
-
- struct THash {
- size_t operator ()(const TPDiskId& x) const {
- return MultiHash(x.NodeId, x.PDiskId);
- }
- };
- };
-
- struct TVSlotId : TPDiskId {
- ui32 VSlotId;
-
- TVSlotId(ui32 nodeId, ui32 pdiskId, ui32 vslotId)
- : TPDiskId(nodeId, pdiskId)
- , VSlotId(vslotId)
- {}
-
- TString ToString() const {
- return TStringBuilder() << TPDiskId::ToString() << ":" << VSlotId;
- }
-
- friend bool operator ==(const TVSlotId& x, const TVSlotId& y) {
- return static_cast<const TPDiskId&>(x) == static_cast<const TPDiskId&>(y) && x.VSlotId == y.VSlotId;
- }
-
- struct THash {
- size_t operator ()(const TVSlotId& x) const {
- return MultiHash(TPDiskId::THash()(x), x.VSlotId);
- }
- };
- };
-
- struct TSetup : TThrRefBase {
- struct TPDiskInfo {
- ui64 Size; // total size of PDisk in bytes
- };
- struct TGroupInfo {
- ui64 SlotSize; // expected slot size of this group in bytes
- };
-
- ui64 TabletId;
- std::unordered_map<std::tuple<ui32, TString>, TPDiskInfo> PDisks;
- std::unordered_map<ui32, TGroupInfo> Groups;
-
- using TPtr = TIntrusivePtr<TSetup>;
- };
-
-private:
- class TVDiskMockActor;
-
-private:
- TSetup::TPtr Setup;
-
-public:
- TNodeWardenMockActor(TSetup::TPtr setup);
-
- void Bootstrap();
- void OnConnected();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // State code
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct TGroupState;
- struct TVDiskState;
- struct TPDiskState;
-
- std::unordered_map<TPDiskId, std::shared_ptr<TPDiskState>, TPDiskId::THash> PDisks;
- std::unordered_map<TVSlotId, std::shared_ptr<TVDiskState>, TVSlotId::THash> VDisks;
- std::unordered_map<ui32, std::shared_ptr<TGroupState>> Groups;
-
- TPDiskState *GetPDisk(TPDiskId pdiskId);
- TVDiskState *GetVDisk(TVSlotId vslotId);
- TGroupState *GetGroup(ui32 groupId);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // BSC interface code
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void SendRegisterNode();
- void SendUpdateDiskStatus();
- void SendUpdateVDiskStatus(TVDiskState *vdisk);
-
- void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Pipe management code
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TActorId PipeId; // actor id of the registered pipe client
- bool IsPipeConnected = false;
-
- void Connect();
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev);
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev);
- void ScheduleReconnect();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- cFunc(TEvents::TSystem::Wakeup, Connect);
- IgnoreFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate);
- )
-};
+#pragma once
+
+#include "defs.h"
+
+class TNodeWardenMockActor : public TActorBootstrapped<TNodeWardenMockActor> {
+public:
+ struct TPDiskId {
+ ui32 NodeId;
+ ui32 PDiskId;
+
+ TPDiskId(ui32 nodeId, ui32 pdiskId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ {}
+
+ TString ToString() const {
+ return TStringBuilder() << NodeId << ":" << PDiskId;
+ }
+
+ friend bool operator ==(const TPDiskId& x, const TPDiskId& y) {
+ return x.NodeId == y.NodeId && x.PDiskId == y.PDiskId;
+ }
+
+ struct THash {
+ size_t operator ()(const TPDiskId& x) const {
+ return MultiHash(x.NodeId, x.PDiskId);
+ }
+ };
+ };
+
+ struct TVSlotId : TPDiskId {
+ ui32 VSlotId;
+
+ TVSlotId(ui32 nodeId, ui32 pdiskId, ui32 vslotId)
+ : TPDiskId(nodeId, pdiskId)
+ , VSlotId(vslotId)
+ {}
+
+ TString ToString() const {
+ return TStringBuilder() << TPDiskId::ToString() << ":" << VSlotId;
+ }
+
+ friend bool operator ==(const TVSlotId& x, const TVSlotId& y) {
+ return static_cast<const TPDiskId&>(x) == static_cast<const TPDiskId&>(y) && x.VSlotId == y.VSlotId;
+ }
+
+ struct THash {
+ size_t operator ()(const TVSlotId& x) const {
+ return MultiHash(TPDiskId::THash()(x), x.VSlotId);
+ }
+ };
+ };
+
+ struct TSetup : TThrRefBase {
+ struct TPDiskInfo {
+ ui64 Size; // total size of PDisk in bytes
+ };
+ struct TGroupInfo {
+ ui64 SlotSize; // expected slot size of this group in bytes
+ };
+
+ ui64 TabletId;
+ std::unordered_map<std::tuple<ui32, TString>, TPDiskInfo> PDisks;
+ std::unordered_map<ui32, TGroupInfo> Groups;
+
+ using TPtr = TIntrusivePtr<TSetup>;
+ };
+
+private:
+ class TVDiskMockActor;
+
+private:
+ TSetup::TPtr Setup;
+
+public:
+ TNodeWardenMockActor(TSetup::TPtr setup);
+
+ void Bootstrap();
+ void OnConnected();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // State code
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct TGroupState;
+ struct TVDiskState;
+ struct TPDiskState;
+
+ std::unordered_map<TPDiskId, std::shared_ptr<TPDiskState>, TPDiskId::THash> PDisks;
+ std::unordered_map<TVSlotId, std::shared_ptr<TVDiskState>, TVSlotId::THash> VDisks;
+ std::unordered_map<ui32, std::shared_ptr<TGroupState>> Groups;
+
+ TPDiskState *GetPDisk(TPDiskId pdiskId);
+ TVDiskState *GetVDisk(TVSlotId vslotId);
+ TGroupState *GetGroup(ui32 groupId);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BSC interface code
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void SendRegisterNode();
+ void SendUpdateDiskStatus();
+ void SendUpdateVDiskStatus(TVDiskState *vdisk);
+
+ void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Pipe management code
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TActorId PipeId; // actor id of the registered pipe client
+ bool IsPipeConnected = false;
+
+ void Connect();
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev);
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev);
+ void ScheduleReconnect();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+ cFunc(TEvents::TSystem::Wakeup, Connect);
+ IgnoreFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate);
+ )
+};
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_bsc.cpp b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_bsc.cpp
index 16292d98e95..6b1cc2eb0b6 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_bsc.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_bsc.cpp
@@ -1,226 +1,226 @@
-#include "node_warden_mock.h"
-#include "node_warden_mock_state.h"
-#include "node_warden_mock_vdisk.h"
-
-void TNodeWardenMockActor::SendRegisterNode() {
- Y_VERIFY(PipeId);
-
- TVector<ui32> startedDynamicGroups, groupGenerations;
- for (const auto& [groupId, group] : Groups) {
- startedDynamicGroups.push_back(group->Info->GroupID);
- groupGenerations.push_back(group->Info->GroupGeneration);
- }
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(SelfId().NodeId(), startedDynamicGroups,
- groupGenerations, TVector<NPDisk::TDriveData>());
-
- auto& record = ev->Record;
- for (const auto& [vslotId, vdisk] : VDisks) {
- vdisk->FillInVDiskStatus(record.AddVDiskStatus());
- }
-
- NTabletPipe::SendData(SelfId(), PipeId, ev.release());
-}
-
-void TNodeWardenMockActor::SendUpdateDiskStatus() {
- Y_VERIFY(PipeId);
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
-
- auto& record = ev->Record;
- for (const auto& [vslotId, vdisk] : VDisks) {
- vdisk->FillInVDiskStatus(record.AddVDiskStatus());
- }
-
- for (const auto& [pdiskId, pdisk] : PDisks) {
- auto *m = record.AddPDisksMetrics();
- m->SetPDiskId(pdiskId.PDiskId);
- m->SetTotalSize(pdisk->Size);
- m->SetAvailableSize(pdisk->Size - pdisk->GetAllocatedSize());
- }
-
- for (const auto& [vslotId, vdisk] : VDisks) {
- auto *m = record.AddVDisksMetrics();
- VDiskIDFromVDiskID(vdisk->GetVDiskId(), m->MutableVDiskId());
- m->SetAllocatedSize(vdisk->AllocatedSize);
- m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
- }
-
- NTabletPipe::SendData(SelfId(), PipeId, ev.release());
-}
-
-void TNodeWardenMockActor::SendUpdateVDiskStatus(TVDiskState *vdisk) {
- if (IsPipeConnected) {
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
-
- auto& record = ev->Record;
- vdisk->FillInVDiskStatus(record.AddVDiskStatus());
-
- {
- auto *m = record.AddPDisksMetrics();
- m->SetPDiskId(vdisk->VSlotId.PDiskId);
- m->SetTotalSize(vdisk->PDisk->Size);
- m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
- }
-
- {
- auto *m = record.AddVDisksMetrics();
- VDiskIDFromVDiskID(vdisk->GetVDiskId(), m->MutableVDiskId());
- m->SetAllocatedSize(vdisk->AllocatedSize);
- m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
- }
-
- NTabletPipe::SendData(SelfId(), PipeId, ev.release());
- }
-}
-
-void TNodeWardenMockActor::Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
- auto& record = ev->Get()->Record;
-
- const auto& services = record.GetServiceSet();
-
- STLOG(PRI_INFO, BS_NODE, NWM10, "TEvControllerNodeServiceSetUpdate", (Record, record));
-
- for (const auto& group : services.GetGroups()) {
- auto info = TBlobStorageGroupInfo::Parse(group, nullptr, nullptr); // TODO(alexvru): group encryption?
- auto&& [it, inserted] = Groups.try_emplace(group.GetGroupID(), std::make_unique<TGroupState>(info));
- if (!inserted && it->second->Info->GroupGeneration < info->GroupGeneration) {
- it->second->UpdateGroup(info);
- }
- }
-
- std::unordered_set<TPDiskId, TPDiskId::THash> pdiskIds, pdiskIdsToRemove;
- for (const auto& [pdiskId, pdiskState] : PDisks) {
- pdiskIds.insert(pdiskId);
- }
- for (const auto& pdisk : services.GetPDisks()) {
- const TPDiskId pdiskId(pdisk.GetNodeID(), pdisk.GetPDiskID());
- pdiskIds.erase(pdiskId);
-
- STLOG(PRI_DEBUG, BS_NODE, NWM04, "PDisk", (Comprehensive, record.GetComprehensive()), (PDiskId, pdiskId),
- (EntityStatus, pdisk.GetEntityStatus()), (Path, pdisk.GetPath()), (PDiskGuid, pdisk.GetPDiskGuid()));
-
- switch (pdisk.GetEntityStatus()) {
- case NKikimrBlobStorage::EEntityStatus::INITIAL:
- case NKikimrBlobStorage::EEntityStatus::CREATE: {
- const auto setupIt = Setup->PDisks.find(std::make_tuple(pdiskId.NodeId, pdisk.GetPath()));
- Y_VERIFY(setupIt != Setup->PDisks.end());
- const TSetup::TPDiskInfo& info = setupIt->second;
-
- auto&& [it, inserted] = PDisks.try_emplace(pdiskId, std::make_unique<TPDiskState>(pdisk.GetPDiskGuid(),
- pdisk.GetPath(), info.Size));
- if (!inserted) {
- UNIT_ASSERT_EQUAL(it->second->PDiskGuid, pdisk.GetPDiskGuid());
- UNIT_ASSERT_EQUAL(it->second->Path, pdisk.GetPath());
- }
- break;
- }
-
- case NKikimrBlobStorage::EEntityStatus::DESTROY:
- pdiskIdsToRemove.insert(pdiskId);
- break;
+#include "node_warden_mock.h"
+#include "node_warden_mock_state.h"
+#include "node_warden_mock_vdisk.h"
+
+void TNodeWardenMockActor::SendRegisterNode() {
+ Y_VERIFY(PipeId);
+
+ TVector<ui32> startedDynamicGroups, groupGenerations;
+ for (const auto& [groupId, group] : Groups) {
+ startedDynamicGroups.push_back(group->Info->GroupID);
+ groupGenerations.push_back(group->Info->GroupGeneration);
+ }
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(SelfId().NodeId(), startedDynamicGroups,
+ groupGenerations, TVector<NPDisk::TDriveData>());
+
+ auto& record = ev->Record;
+ for (const auto& [vslotId, vdisk] : VDisks) {
+ vdisk->FillInVDiskStatus(record.AddVDiskStatus());
+ }
+
+ NTabletPipe::SendData(SelfId(), PipeId, ev.release());
+}
+
+void TNodeWardenMockActor::SendUpdateDiskStatus() {
+ Y_VERIFY(PipeId);
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
+
+ auto& record = ev->Record;
+ for (const auto& [vslotId, vdisk] : VDisks) {
+ vdisk->FillInVDiskStatus(record.AddVDiskStatus());
+ }
+
+ for (const auto& [pdiskId, pdisk] : PDisks) {
+ auto *m = record.AddPDisksMetrics();
+ m->SetPDiskId(pdiskId.PDiskId);
+ m->SetTotalSize(pdisk->Size);
+ m->SetAvailableSize(pdisk->Size - pdisk->GetAllocatedSize());
+ }
+
+ for (const auto& [vslotId, vdisk] : VDisks) {
+ auto *m = record.AddVDisksMetrics();
+ VDiskIDFromVDiskID(vdisk->GetVDiskId(), m->MutableVDiskId());
+ m->SetAllocatedSize(vdisk->AllocatedSize);
+ m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
+ }
+
+ NTabletPipe::SendData(SelfId(), PipeId, ev.release());
+}
+
+void TNodeWardenMockActor::SendUpdateVDiskStatus(TVDiskState *vdisk) {
+ if (IsPipeConnected) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
+
+ auto& record = ev->Record;
+ vdisk->FillInVDiskStatus(record.AddVDiskStatus());
+
+ {
+ auto *m = record.AddPDisksMetrics();
+ m->SetPDiskId(vdisk->VSlotId.PDiskId);
+ m->SetTotalSize(vdisk->PDisk->Size);
+ m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
+ }
+
+ {
+ auto *m = record.AddVDisksMetrics();
+ VDiskIDFromVDiskID(vdisk->GetVDiskId(), m->MutableVDiskId());
+ m->SetAllocatedSize(vdisk->AllocatedSize);
+ m->SetAvailableSize(vdisk->PDisk->Size - vdisk->PDisk->GetAllocatedSize());
+ }
+
+ NTabletPipe::SendData(SelfId(), PipeId, ev.release());
+ }
+}
+
+void TNodeWardenMockActor::Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
+ auto& record = ev->Get()->Record;
+
+ const auto& services = record.GetServiceSet();
+
+ STLOG(PRI_INFO, BS_NODE, NWM10, "TEvControllerNodeServiceSetUpdate", (Record, record));
+
+ for (const auto& group : services.GetGroups()) {
+ auto info = TBlobStorageGroupInfo::Parse(group, nullptr, nullptr); // TODO(alexvru): group encryption?
+ auto&& [it, inserted] = Groups.try_emplace(group.GetGroupID(), std::make_unique<TGroupState>(info));
+ if (!inserted && it->second->Info->GroupGeneration < info->GroupGeneration) {
+ it->second->UpdateGroup(info);
+ }
+ }
+
+ std::unordered_set<TPDiskId, TPDiskId::THash> pdiskIds, pdiskIdsToRemove;
+ for (const auto& [pdiskId, pdiskState] : PDisks) {
+ pdiskIds.insert(pdiskId);
+ }
+ for (const auto& pdisk : services.GetPDisks()) {
+ const TPDiskId pdiskId(pdisk.GetNodeID(), pdisk.GetPDiskID());
+ pdiskIds.erase(pdiskId);
+
+ STLOG(PRI_DEBUG, BS_NODE, NWM04, "PDisk", (Comprehensive, record.GetComprehensive()), (PDiskId, pdiskId),
+ (EntityStatus, pdisk.GetEntityStatus()), (Path, pdisk.GetPath()), (PDiskGuid, pdisk.GetPDiskGuid()));
+
+ switch (pdisk.GetEntityStatus()) {
+ case NKikimrBlobStorage::EEntityStatus::INITIAL:
+ case NKikimrBlobStorage::EEntityStatus::CREATE: {
+ const auto setupIt = Setup->PDisks.find(std::make_tuple(pdiskId.NodeId, pdisk.GetPath()));
+ Y_VERIFY(setupIt != Setup->PDisks.end());
+ const TSetup::TPDiskInfo& info = setupIt->second;
+
+ auto&& [it, inserted] = PDisks.try_emplace(pdiskId, std::make_unique<TPDiskState>(pdisk.GetPDiskGuid(),
+ pdisk.GetPath(), info.Size));
+ if (!inserted) {
+ UNIT_ASSERT_EQUAL(it->second->PDiskGuid, pdisk.GetPDiskGuid());
+ UNIT_ASSERT_EQUAL(it->second->Path, pdisk.GetPath());
+ }
+ break;
+ }
+
+ case NKikimrBlobStorage::EEntityStatus::DESTROY:
+ pdiskIdsToRemove.insert(pdiskId);
+ break;
case NKikimrBlobStorage::EEntityStatus::RESTART:
break;
- }
- }
-
- std::unordered_set<TVSlotId, TVSlotId::THash> vslotIds, vslotIdsToRemove;
- for (const auto& [vslotId, vdiskState] : VDisks) {
- vslotIds.insert(vslotId);
- }
- for (const auto& vdisk : services.GetVDisks()) {
- const auto& loc = vdisk.GetVDiskLocation();
- TVSlotId vslotId(loc.GetNodeID(), loc.GetPDiskID(), loc.GetVDiskSlotID());
- vslotIds.erase(vslotId);
-
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(vdisk.GetVDiskID());
-
- STLOG(PRI_DEBUG, BS_NODE, NWM05, "VDisk", (Comprehensive, record.GetComprehensive()), (VSlotId, vslotId),
- (EntityStatus, vdisk.GetEntityStatus()), (VDiskId, vdiskId), (DoDestroy, vdisk.GetDoDestroy()),
- (DoWipe, vdisk.GetDoWipe()), (DonorMode, vdisk.HasDonorMode()));
-
- TVDiskState *vdiskp = GetVDisk(vslotId);
-
- if (vdisk.HasDonorMode()) { // switch already operating disk to donor mode
- UNIT_ASSERT(vdiskp);
- vdiskp->DonorMode = true;
- } else if (!vdisk.GetDoDestroy() && vdiskp) {
- UNIT_ASSERT(!vdiskp->DonorMode); // do not allow donor mode reverts
- }
-
- TGroupState *group = GetGroup(vdiskId.GroupID);
- UNIT_ASSERT(group);
-
- TPDiskState *pdisk = GetPDisk(vslotId);
- UNIT_ASSERT(pdisk);
- UNIT_ASSERT_VALUES_EQUAL(loc.GetPDiskGuid(), pdisk->PDiskGuid);
-
- if (vdisk.GetDoDestroy() || vdisk.GetDoWipe()) {
- if (vdiskp) {
- UNIT_ASSERT(vdiskp->Actor);
- TAutoPtr<IEventHandle> ev = new IEventHandle(TEvents::TSystem::Poison, 0, {}, {}, nullptr, 0);
- InvokeOtherActor(*vdiskp->Actor, &IActor::Receive, ev, TActivationContext::ActorContextFor(vdiskp->Actor->SelfId()));
- UNIT_ASSERT(!vdiskp->Actor);
- }
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerNodeReport>(SelfId().NodeId());
- auto& record = ev->Record;
- auto *report = record.AddVDiskReports();
- report->MutableVSlotId()->SetNodeId(vslotId.NodeId);
- report->MutableVSlotId()->SetPDiskId(vslotId.PDiskId);
- report->MutableVSlotId()->SetVSlotId(vslotId.VSlotId);
- report->MutableVDiskId()->CopyFrom(vdisk.GetVDiskID());
- if (vdisk.GetDoDestroy()) {
- report->SetPhase(NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
- } else if (vdisk.GetDoWipe()) {
- report->SetPhase(NKikimrBlobStorage::TEvControllerNodeReport::WIPED);
- }
- UNIT_ASSERT(PipeId);
- NTabletPipe::SendData(SelfId(), PipeId, ev.release());
- }
-
- if (vdisk.GetDoDestroy()) {
- vslotIdsToRemove.insert(vslotId);
- } else if (vdisk.GetDoWipe() && vdiskp) {
- vdiskp->AllocatedSize = 0;
- vdiskp->Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
- } else if (!vdiskp) {
- const auto groupIt = Setup->Groups.find(vdiskId.GroupID);
- UNIT_ASSERT(groupIt != Setup->Groups.end());
- const TSetup::TGroupInfo& groupInfo = groupIt->second;
-
- auto&& [it, inserted] = VDisks.emplace(vslotId, std::make_unique<TVDiskState>(vdiskId, vslotId, group, pdisk,
- groupInfo.SlotSize));
- group->AddVDisk(it->second.get());
- pdisk->AddVSlot(it->second.get());
- auto *actorSystem = TActivationContext::ActorSystem();
- const TActorId serviceId = MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VSlotId);
- actorSystem->RegisterLocalService(serviceId, RegisterWithSameMailbox(new TVDiskMockActor(this, it->second)));
- }
- }
-
- if (record.GetComprehensive()) {
- pdiskIdsToRemove.merge(pdiskIds);
- vslotIdsToRemove.merge(vslotIds);
- }
-
- for (TVSlotId vslotId : vslotIdsToRemove) {
- if (TVDiskState *vdisk = GetVDisk(vslotId)) {
- vdisk->Group->EraseVDisk(vdisk);
- vdisk->PDisk->EraseVSlot(vdisk->VSlotId.VSlotId);
- VDisks.erase(vdisk->VSlotId);
- }
- }
-
- for (TPDiskId pdiskId : pdiskIdsToRemove) {
- if (const auto it = PDisks.find(pdiskId); it != PDisks.end()) {
- UNIT_ASSERT(it->second->VSlotsOnPDisk.empty());
- PDisks.erase(it);
- }
- }
-
- for (const auto& [vslotId, vdiskp] : VDisks) {
- UNIT_ASSERT(!vdiskp->RequireDonorMode || vdiskp->DonorMode);
- }
-
- SendUpdateDiskStatus();
-}
+ }
+ }
+
+ std::unordered_set<TVSlotId, TVSlotId::THash> vslotIds, vslotIdsToRemove;
+ for (const auto& [vslotId, vdiskState] : VDisks) {
+ vslotIds.insert(vslotId);
+ }
+ for (const auto& vdisk : services.GetVDisks()) {
+ const auto& loc = vdisk.GetVDiskLocation();
+ TVSlotId vslotId(loc.GetNodeID(), loc.GetPDiskID(), loc.GetVDiskSlotID());
+ vslotIds.erase(vslotId);
+
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(vdisk.GetVDiskID());
+
+ STLOG(PRI_DEBUG, BS_NODE, NWM05, "VDisk", (Comprehensive, record.GetComprehensive()), (VSlotId, vslotId),
+ (EntityStatus, vdisk.GetEntityStatus()), (VDiskId, vdiskId), (DoDestroy, vdisk.GetDoDestroy()),
+ (DoWipe, vdisk.GetDoWipe()), (DonorMode, vdisk.HasDonorMode()));
+
+ TVDiskState *vdiskp = GetVDisk(vslotId);
+
+ if (vdisk.HasDonorMode()) { // switch already operating disk to donor mode
+ UNIT_ASSERT(vdiskp);
+ vdiskp->DonorMode = true;
+ } else if (!vdisk.GetDoDestroy() && vdiskp) {
+ UNIT_ASSERT(!vdiskp->DonorMode); // do not allow donor mode reverts
+ }
+
+ TGroupState *group = GetGroup(vdiskId.GroupID);
+ UNIT_ASSERT(group);
+
+ TPDiskState *pdisk = GetPDisk(vslotId);
+ UNIT_ASSERT(pdisk);
+ UNIT_ASSERT_VALUES_EQUAL(loc.GetPDiskGuid(), pdisk->PDiskGuid);
+
+ if (vdisk.GetDoDestroy() || vdisk.GetDoWipe()) {
+ if (vdiskp) {
+ UNIT_ASSERT(vdiskp->Actor);
+ TAutoPtr<IEventHandle> ev = new IEventHandle(TEvents::TSystem::Poison, 0, {}, {}, nullptr, 0);
+ InvokeOtherActor(*vdiskp->Actor, &IActor::Receive, ev, TActivationContext::ActorContextFor(vdiskp->Actor->SelfId()));
+ UNIT_ASSERT(!vdiskp->Actor);
+ }
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerNodeReport>(SelfId().NodeId());
+ auto& record = ev->Record;
+ auto *report = record.AddVDiskReports();
+ report->MutableVSlotId()->SetNodeId(vslotId.NodeId);
+ report->MutableVSlotId()->SetPDiskId(vslotId.PDiskId);
+ report->MutableVSlotId()->SetVSlotId(vslotId.VSlotId);
+ report->MutableVDiskId()->CopyFrom(vdisk.GetVDiskID());
+ if (vdisk.GetDoDestroy()) {
+ report->SetPhase(NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED);
+ } else if (vdisk.GetDoWipe()) {
+ report->SetPhase(NKikimrBlobStorage::TEvControllerNodeReport::WIPED);
+ }
+ UNIT_ASSERT(PipeId);
+ NTabletPipe::SendData(SelfId(), PipeId, ev.release());
+ }
+
+ if (vdisk.GetDoDestroy()) {
+ vslotIdsToRemove.insert(vslotId);
+ } else if (vdisk.GetDoWipe() && vdiskp) {
+ vdiskp->AllocatedSize = 0;
+ vdiskp->Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+ } else if (!vdiskp) {
+ const auto groupIt = Setup->Groups.find(vdiskId.GroupID);
+ UNIT_ASSERT(groupIt != Setup->Groups.end());
+ const TSetup::TGroupInfo& groupInfo = groupIt->second;
+
+ auto&& [it, inserted] = VDisks.emplace(vslotId, std::make_unique<TVDiskState>(vdiskId, vslotId, group, pdisk,
+ groupInfo.SlotSize));
+ group->AddVDisk(it->second.get());
+ pdisk->AddVSlot(it->second.get());
+ auto *actorSystem = TActivationContext::ActorSystem();
+ const TActorId serviceId = MakeBlobStorageVDiskID(vslotId.NodeId, vslotId.PDiskId, vslotId.VSlotId);
+ actorSystem->RegisterLocalService(serviceId, RegisterWithSameMailbox(new TVDiskMockActor(this, it->second)));
+ }
+ }
+
+ if (record.GetComprehensive()) {
+ pdiskIdsToRemove.merge(pdiskIds);
+ vslotIdsToRemove.merge(vslotIds);
+ }
+
+ for (TVSlotId vslotId : vslotIdsToRemove) {
+ if (TVDiskState *vdisk = GetVDisk(vslotId)) {
+ vdisk->Group->EraseVDisk(vdisk);
+ vdisk->PDisk->EraseVSlot(vdisk->VSlotId.VSlotId);
+ VDisks.erase(vdisk->VSlotId);
+ }
+ }
+
+ for (TPDiskId pdiskId : pdiskIdsToRemove) {
+ if (const auto it = PDisks.find(pdiskId); it != PDisks.end()) {
+ UNIT_ASSERT(it->second->VSlotsOnPDisk.empty());
+ PDisks.erase(it);
+ }
+ }
+
+ for (const auto& [vslotId, vdiskp] : VDisks) {
+ UNIT_ASSERT(!vdiskp->RequireDonorMode || vdiskp->DonorMode);
+ }
+
+ SendUpdateDiskStatus();
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_pipe.cpp b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_pipe.cpp
index af3ab036088..ca32da601da 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_pipe.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_pipe.cpp
@@ -1,34 +1,34 @@
-#include "node_warden_mock.h"
-
-void TNodeWardenMockActor::Connect() {
- Y_VERIFY(!PipeId);
- PipeId = Register(NTabletPipe::CreateClient(SelfId(), Setup->TabletId, {}));
-}
-
-void TNodeWardenMockActor::Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
- STLOG(PRI_INFO, BS_NODE, NWM02, "pipe connected", (Sender, ev->Sender), (PipeId, PipeId), (Status, ev->Get()->Status));
- if (ev->Sender == PipeId) {
- Y_VERIFY(!IsPipeConnected);
- if (ev->Get()->Status == NKikimrProto::OK) {
- IsPipeConnected = true;
- OnConnected();
- } else {
- NTabletPipe::CloseAndForgetClient(SelfId(), PipeId);
- ScheduleReconnect();
- }
- }
-}
-
-void TNodeWardenMockActor::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
- STLOG(PRI_INFO, BS_NODE, NWM03, "pipe disconnected", (Sender, ev->Sender), (PipeId, PipeId));
- if (ev->Sender == PipeId) {
- IsPipeConnected = false;
- ScheduleReconnect();
- }
-}
-
-void TNodeWardenMockActor::ScheduleReconnect() {
- Y_VERIFY(!IsPipeConnected);
- PipeId = {};
- Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
-}
+#include "node_warden_mock.h"
+
+void TNodeWardenMockActor::Connect() {
+ Y_VERIFY(!PipeId);
+ PipeId = Register(NTabletPipe::CreateClient(SelfId(), Setup->TabletId, {}));
+}
+
+void TNodeWardenMockActor::Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
+ STLOG(PRI_INFO, BS_NODE, NWM02, "pipe connected", (Sender, ev->Sender), (PipeId, PipeId), (Status, ev->Get()->Status));
+ if (ev->Sender == PipeId) {
+ Y_VERIFY(!IsPipeConnected);
+ if (ev->Get()->Status == NKikimrProto::OK) {
+ IsPipeConnected = true;
+ OnConnected();
+ } else {
+ NTabletPipe::CloseAndForgetClient(SelfId(), PipeId);
+ ScheduleReconnect();
+ }
+ }
+}
+
+void TNodeWardenMockActor::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
+ STLOG(PRI_INFO, BS_NODE, NWM03, "pipe disconnected", (Sender, ev->Sender), (PipeId, PipeId));
+ if (ev->Sender == PipeId) {
+ IsPipeConnected = false;
+ ScheduleReconnect();
+ }
+}
+
+void TNodeWardenMockActor::ScheduleReconnect() {
+ Y_VERIFY(!IsPipeConnected);
+ PipeId = {};
+ Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.cpp b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.cpp
index 93a74e469e8..33d947f0de7 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.cpp
@@ -1,98 +1,98 @@
-#include "node_warden_mock.h"
-#include "node_warden_mock_state.h"
-
+#include "node_warden_mock.h"
+#include "node_warden_mock_state.h"
+
namespace NKikimr {
namespace NPDisk {
extern const ui64 YdbDefaultPDiskSequence = 0x7e5700007e570000;
}
}
-TNodeWardenMockActor::TNodeWardenMockActor(TSetup::TPtr setup)
- : Setup(std::move(setup))
-{}
-
-void TNodeWardenMockActor::Bootstrap() {
- Become(&TThis::StateFunc);
- STLOG(PRI_INFO, BS_NODE, NWM01, "starting");
- Connect();
-}
-
-void TNodeWardenMockActor::OnConnected() {
- SendRegisterNode();
-}
-
-TNodeWardenMockActor::TPDiskState *TNodeWardenMockActor::GetPDisk(TPDiskId pdiskId) {
- const auto it = PDisks.find(pdiskId);
- return it != PDisks.end() ? it->second.get() : nullptr;
-}
-
-TNodeWardenMockActor::TVDiskState *TNodeWardenMockActor::GetVDisk(TVSlotId vslotId) {
- const auto it = VDisks.find(vslotId);
- return it != VDisks.end() ? it->second.get() : nullptr;
-}
-
-TNodeWardenMockActor::TGroupState *TNodeWardenMockActor::GetGroup(ui32 groupId) {
- const auto it = Groups.find(groupId);
- return it != Groups.end() ? it->second.get() : nullptr;
-}
-
-void TNodeWardenMockActor::TGroupState::UpdateGroup(TIntrusivePtr<TBlobStorageGroupInfo> info) {
- for (TVDiskState *vdisk : VDisksOfGroup) {
- if (Info->GetActorId(vdisk->VDiskId) == info->GetActorId(vdisk->VDiskId)) {
- vdisk->Generation = info->GroupGeneration; // just update generation
- } else {
- STLOG(PRI_INFO, BS_NODE, NWM11, "UpdateGroup", (VDiskId, vdisk->VDiskId),
- (PrevActorId, Info->GetActorId(vdisk->VDiskId)),
- (CurActorId, info->GetActorId(vdisk->VDiskId)));
- vdisk->RequireDonorMode = true;
- }
- }
- Info = std::move(info);
-}
-
-void TNodeWardenMockActor::TGroupState::AddVDisk(TVDiskState *vdisk) {
- auto&& [it, inserted] = VDisksOfGroup.insert(vdisk);
- UNIT_ASSERT(inserted);
-}
-
-void TNodeWardenMockActor::TGroupState::EraseVDisk(TVDiskState *vdisk) {
- const size_t num = VDisksOfGroup.erase(vdisk);
- UNIT_ASSERT(num);
-}
-
-void TNodeWardenMockActor::TVDiskState::FillInVDiskStatus(NKikimrBlobStorage::TVDiskStatus *pb) {
- VDiskIDFromVDiskID(GetVDiskId(), pb->MutableVDiskId());
- pb->SetNodeId(VSlotId.NodeId);
- pb->SetPDiskId(VSlotId.PDiskId);
- pb->SetVSlotId(VSlotId.VSlotId);
- pb->SetPDiskGuid(PDisk->PDiskGuid);
- pb->SetStatus(Status);
-}
-
-void TNodeWardenMockActor::TPDiskState::AddVSlot(TVDiskState *vdisk) {
- auto&& [it, inserted] = VSlotsOnPDisk.emplace(vdisk->VSlotId.VSlotId, vdisk);
- UNIT_ASSERT(inserted);
-}
-
-void TNodeWardenMockActor::TPDiskState::EraseVSlot(ui32 vslotId) {
- const size_t num = VSlotsOnPDisk.erase(vslotId);
- UNIT_ASSERT(num);
-}
-
-ui64 TNodeWardenMockActor::TPDiskState::GetAllocatedSize() const {
- ui64 res = 0;
- for (const auto& [vslotId, vdisk] : VSlotsOnPDisk) {
- res += vdisk->AllocatedSize;
- }
- return res;
-}
-
-template<>
-void Out<TNodeWardenMockActor::TPDiskId>(IOutputStream& s, const TNodeWardenMockActor::TPDiskId& x) {
- s << x.ToString();
-}
-
-template<>
-void Out<TNodeWardenMockActor::TVSlotId>(IOutputStream& s, const TNodeWardenMockActor::TVSlotId& x) {
- s << x.ToString();
-}
+TNodeWardenMockActor::TNodeWardenMockActor(TSetup::TPtr setup)
+ : Setup(std::move(setup))
+{}
+
+void TNodeWardenMockActor::Bootstrap() {
+ Become(&TThis::StateFunc);
+ STLOG(PRI_INFO, BS_NODE, NWM01, "starting");
+ Connect();
+}
+
+void TNodeWardenMockActor::OnConnected() {
+ SendRegisterNode();
+}
+
+TNodeWardenMockActor::TPDiskState *TNodeWardenMockActor::GetPDisk(TPDiskId pdiskId) {
+ const auto it = PDisks.find(pdiskId);
+ return it != PDisks.end() ? it->second.get() : nullptr;
+}
+
+TNodeWardenMockActor::TVDiskState *TNodeWardenMockActor::GetVDisk(TVSlotId vslotId) {
+ const auto it = VDisks.find(vslotId);
+ return it != VDisks.end() ? it->second.get() : nullptr;
+}
+
+TNodeWardenMockActor::TGroupState *TNodeWardenMockActor::GetGroup(ui32 groupId) {
+ const auto it = Groups.find(groupId);
+ return it != Groups.end() ? it->second.get() : nullptr;
+}
+
+void TNodeWardenMockActor::TGroupState::UpdateGroup(TIntrusivePtr<TBlobStorageGroupInfo> info) {
+ for (TVDiskState *vdisk : VDisksOfGroup) {
+ if (Info->GetActorId(vdisk->VDiskId) == info->GetActorId(vdisk->VDiskId)) {
+ vdisk->Generation = info->GroupGeneration; // just update generation
+ } else {
+ STLOG(PRI_INFO, BS_NODE, NWM11, "UpdateGroup", (VDiskId, vdisk->VDiskId),
+ (PrevActorId, Info->GetActorId(vdisk->VDiskId)),
+ (CurActorId, info->GetActorId(vdisk->VDiskId)));
+ vdisk->RequireDonorMode = true;
+ }
+ }
+ Info = std::move(info);
+}
+
+void TNodeWardenMockActor::TGroupState::AddVDisk(TVDiskState *vdisk) {
+ auto&& [it, inserted] = VDisksOfGroup.insert(vdisk);
+ UNIT_ASSERT(inserted);
+}
+
+void TNodeWardenMockActor::TGroupState::EraseVDisk(TVDiskState *vdisk) {
+ const size_t num = VDisksOfGroup.erase(vdisk);
+ UNIT_ASSERT(num);
+}
+
+void TNodeWardenMockActor::TVDiskState::FillInVDiskStatus(NKikimrBlobStorage::TVDiskStatus *pb) {
+ VDiskIDFromVDiskID(GetVDiskId(), pb->MutableVDiskId());
+ pb->SetNodeId(VSlotId.NodeId);
+ pb->SetPDiskId(VSlotId.PDiskId);
+ pb->SetVSlotId(VSlotId.VSlotId);
+ pb->SetPDiskGuid(PDisk->PDiskGuid);
+ pb->SetStatus(Status);
+}
+
+void TNodeWardenMockActor::TPDiskState::AddVSlot(TVDiskState *vdisk) {
+ auto&& [it, inserted] = VSlotsOnPDisk.emplace(vdisk->VSlotId.VSlotId, vdisk);
+ UNIT_ASSERT(inserted);
+}
+
+void TNodeWardenMockActor::TPDiskState::EraseVSlot(ui32 vslotId) {
+ const size_t num = VSlotsOnPDisk.erase(vslotId);
+ UNIT_ASSERT(num);
+}
+
+ui64 TNodeWardenMockActor::TPDiskState::GetAllocatedSize() const {
+ ui64 res = 0;
+ for (const auto& [vslotId, vdisk] : VSlotsOnPDisk) {
+ res += vdisk->AllocatedSize;
+ }
+ return res;
+}
+
+template<>
+void Out<TNodeWardenMockActor::TPDiskId>(IOutputStream& s, const TNodeWardenMockActor::TPDiskId& x) {
+ s << x.ToString();
+}
+
+template<>
+void Out<TNodeWardenMockActor::TVSlotId>(IOutputStream& s, const TNodeWardenMockActor::TVSlotId& x) {
+ s << x.ToString();
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.h b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.h
index 3d4647758d0..4d6b37f6f22 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_state.h
@@ -1,62 +1,62 @@
-#pragma once
-
-#include "node_warden_mock.h"
-
-struct TNodeWardenMockActor::TGroupState {
- TIntrusivePtr<TBlobStorageGroupInfo> Info; // group info
- std::set<TVDiskState*> VDisksOfGroup; // vdisks of this group on this node
-
- TGroupState(TIntrusivePtr<TBlobStorageGroupInfo> info)
- : Info(std::move(info))
- {}
-
- void UpdateGroup(TIntrusivePtr<TBlobStorageGroupInfo> info);
- void AddVDisk(TVDiskState *vdisk);
- void EraseVDisk(TVDiskState *vdisk);
-};
-
-struct TNodeWardenMockActor::TVDiskState {
- const TVDiskID VDiskId; // VDiskId does not contain current generation!
- ui32 Generation = 0; // actual generation for this VDiskId
- const TVSlotId VSlotId; // location of the disk
- TGroupState* const Group; // group containing this VDisk
- TPDiskState* const PDisk; // PDisk containing this VDisk
- const ui64 TargetDataSize = 0;
- NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
- ui64 AllocatedSize = 0;
- bool DonorMode = false;
- bool RequireDonorMode = false;
- IActor *Actor = nullptr;
-
- TVDiskState(TVDiskID vdiskId, TVSlotId vslotId, TGroupState *group, TPDiskState *pdisk, ui64 targetDataSize)
- : VDiskId(vdiskId)
- , Generation(vdiskId.GroupGeneration)
- , VSlotId(vslotId)
- , Group(group)
- , PDisk(pdisk)
- , TargetDataSize(targetDataSize)
- {}
-
- TVDiskID GetVDiskId() const {
- return TVDiskID(VDiskId.GroupID, Generation, VDiskId);
- }
-
- void FillInVDiskStatus(NKikimrBlobStorage::TVDiskStatus *pb);
-};
-
-struct TNodeWardenMockActor::TPDiskState {
- const ui64 PDiskGuid;
- const TString Path;
- const ui64 Size;
- std::unordered_map<ui32, TVDiskState*> VSlotsOnPDisk;
-
- TPDiskState(ui64 pdiskGuid, TString path, ui64 size)
- : PDiskGuid(pdiskGuid)
- , Path(std::move(path))
- , Size(size)
- {}
-
- void AddVSlot(TVDiskState *vdisk);
- void EraseVSlot(ui32 vslotId);
- ui64 GetAllocatedSize() const;
-};
+#pragma once
+
+#include "node_warden_mock.h"
+
+struct TNodeWardenMockActor::TGroupState {
+ TIntrusivePtr<TBlobStorageGroupInfo> Info; // group info
+ std::set<TVDiskState*> VDisksOfGroup; // vdisks of this group on this node
+
+ TGroupState(TIntrusivePtr<TBlobStorageGroupInfo> info)
+ : Info(std::move(info))
+ {}
+
+ void UpdateGroup(TIntrusivePtr<TBlobStorageGroupInfo> info);
+ void AddVDisk(TVDiskState *vdisk);
+ void EraseVDisk(TVDiskState *vdisk);
+};
+
+struct TNodeWardenMockActor::TVDiskState {
+ const TVDiskID VDiskId; // VDiskId does not contain current generation!
+ ui32 Generation = 0; // actual generation for this VDiskId
+ const TVSlotId VSlotId; // location of the disk
+ TGroupState* const Group; // group containing this VDisk
+ TPDiskState* const PDisk; // PDisk containing this VDisk
+ const ui64 TargetDataSize = 0;
+ NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+ ui64 AllocatedSize = 0;
+ bool DonorMode = false;
+ bool RequireDonorMode = false;
+ IActor *Actor = nullptr;
+
+ TVDiskState(TVDiskID vdiskId, TVSlotId vslotId, TGroupState *group, TPDiskState *pdisk, ui64 targetDataSize)
+ : VDiskId(vdiskId)
+ , Generation(vdiskId.GroupGeneration)
+ , VSlotId(vslotId)
+ , Group(group)
+ , PDisk(pdisk)
+ , TargetDataSize(targetDataSize)
+ {}
+
+ TVDiskID GetVDiskId() const {
+ return TVDiskID(VDiskId.GroupID, Generation, VDiskId);
+ }
+
+ void FillInVDiskStatus(NKikimrBlobStorage::TVDiskStatus *pb);
+};
+
+struct TNodeWardenMockActor::TPDiskState {
+ const ui64 PDiskGuid;
+ const TString Path;
+ const ui64 Size;
+ std::unordered_map<ui32, TVDiskState*> VSlotsOnPDisk;
+
+ TPDiskState(ui64 pdiskGuid, TString path, ui64 size)
+ : PDiskGuid(pdiskGuid)
+ , Path(std::move(path))
+ , Size(size)
+ {}
+
+ void AddVSlot(TVDiskState *vdisk);
+ void EraseVSlot(ui32 vslotId);
+ ui64 GetAllocatedSize() const;
+};
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h
index 6b7325992ec..7e8aff9db9b 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/node_warden_mock_vdisk.h
@@ -1,144 +1,144 @@
-#pragma once
-
-#include "defs.h"
-#include "node_warden_mock.h"
-
-class TNodeWardenMockActor::TVDiskMockActor : public TActorBootstrapped<TVDiskMockActor> {
- TNodeWardenMockActor *NodeWardenMockActor;
- std::weak_ptr<TVDiskState> VDisk;
-
- enum class EState {
- INITIAL,
- READ_LOG,
- REPLICATION,
- READY,
- } State = EState::INITIAL;
-
-public:
- TVDiskMockActor(TNodeWardenMockActor *nodeWardenMockActor, std::shared_ptr<TVDiskState> vdisk)
- : NodeWardenMockActor(nodeWardenMockActor)
- , VDisk(vdisk)
- {
- vdisk->Actor = this;
- }
-
- void Bootstrap() {
- if (const auto& vdisk = VDisk.lock()) {
- STLOG(PRI_INFO, BS_NODE, NWM06, "VDisk starting", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
- if (vdisk->AllocatedSize) {
- StartReadLog();
- } else {
- StartInitial();
- }
- }
- Become(&TThis::StateFunc);
- }
-
- void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
- auto& record = ev->Get()->Record;
- if (const auto& vdisk = VDisk.lock()) {
- auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::ERROR, vdisk->GetVDiskId(),
- false, false, 0);
- auto& r = response->Record;
- if (VDiskIDFromVDiskID(record.GetVDiskID()) != vdisk->GetVDiskId()) { // RACE
- r.SetStatus(NKikimrProto::RACE);
- } else {
- r.SetStatus(NKikimrProto::OK);
- switch (State) {
- case EState::INITIAL:
- case EState::READ_LOG:
- r.SetStatus(NKikimrProto::NOTREADY);
- break;
-
- case EState::REPLICATION:
- r.SetJoinedGroup(true);
- break;
-
- case EState::READY:
- r.SetJoinedGroup(true);
- r.SetReplicated(true);
- break;
- }
- }
- Send(ev->Sender, response.release(), 0, ev->Cookie);
- } else {
- Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::ERROR, record.GetVDiskID()), 0, ev->Cookie);
- }
- }
-
- void StartInitial() {
- Schedule(TDuration::Seconds(15), new TEvents::TEvWakeup);
- State = EState::INITIAL;
- }
-
- void StartReadLog() {
- Schedule(TDuration::MilliSeconds(100 + RandomNumber<ui64>(4900)), new TEvents::TEvWakeup);
- State = EState::READ_LOG;
- }
-
- void StartReplication() {
- State = EState::REPLICATION;
- if (const auto& vdisk = VDisk.lock()) {
- STLOG(PRI_INFO, BS_NODE, NWM09, "VDisk REPLICATING", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
- vdisk->Status = NKikimrBlobStorage::EVDiskStatus::REPLICATING;
- InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
- }
- ResumeReplication();
- }
-
- void ResumeReplication() {
- if (const auto& vdisk = VDisk.lock()) {
- if (const ui64 quantum = Min(vdisk->TargetDataSize - vdisk->AllocatedSize, (400 << 20) + RandomNumber<ui64>(500 << 20))) {
- vdisk->AllocatedSize += quantum;
- UNIT_ASSERT(vdisk->PDisk->GetAllocatedSize() <= 85 * vdisk->PDisk->Size / 100);
- InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
- Schedule(TDuration::MilliSeconds(100 + RandomNumber<ui64>(100)), new TEvents::TEvWakeup);
- } else {
- BecomeReady();
- }
- }
- }
-
- void BecomeReady() {
- if (const auto& vdisk = VDisk.lock()) {
- STLOG(PRI_INFO, BS_NODE, NWM08, "VDisk READY", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
- vdisk->Status = NKikimrBlobStorage::EVDiskStatus::READY;
- InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
- State = EState::READY;
- }
- }
-
- void HandleWakeup() {
- switch (State) {
- case EState::INITIAL:
- StartReadLog();
- break;
-
- case EState::READ_LOG:
- StartReplication();
- break;
-
- case EState::REPLICATION:
- ResumeReplication();
- break;
-
- case EState::READY:
- Y_FAIL();
- }
- }
-
- void PassAway() override {
- if (const auto& vdisk = VDisk.lock()) {
- STLOG(PRI_INFO, BS_NODE, NWM07, "VDisk stopping", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
- UNIT_ASSERT_EQUAL(vdisk->Actor, this);
- vdisk->Actor = nullptr;
- }
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvVStatus, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-};
+#pragma once
+
+#include "defs.h"
+#include "node_warden_mock.h"
+
+class TNodeWardenMockActor::TVDiskMockActor : public TActorBootstrapped<TVDiskMockActor> {
+ TNodeWardenMockActor *NodeWardenMockActor;
+ std::weak_ptr<TVDiskState> VDisk;
+
+ enum class EState {
+ INITIAL,
+ READ_LOG,
+ REPLICATION,
+ READY,
+ } State = EState::INITIAL;
+
+public:
+ TVDiskMockActor(TNodeWardenMockActor *nodeWardenMockActor, std::shared_ptr<TVDiskState> vdisk)
+ : NodeWardenMockActor(nodeWardenMockActor)
+ , VDisk(vdisk)
+ {
+ vdisk->Actor = this;
+ }
+
+ void Bootstrap() {
+ if (const auto& vdisk = VDisk.lock()) {
+ STLOG(PRI_INFO, BS_NODE, NWM06, "VDisk starting", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
+ if (vdisk->AllocatedSize) {
+ StartReadLog();
+ } else {
+ StartInitial();
+ }
+ }
+ Become(&TThis::StateFunc);
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
+ auto& record = ev->Get()->Record;
+ if (const auto& vdisk = VDisk.lock()) {
+ auto response = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::ERROR, vdisk->GetVDiskId(),
+ false, false, 0);
+ auto& r = response->Record;
+ if (VDiskIDFromVDiskID(record.GetVDiskID()) != vdisk->GetVDiskId()) { // RACE
+ r.SetStatus(NKikimrProto::RACE);
+ } else {
+ r.SetStatus(NKikimrProto::OK);
+ switch (State) {
+ case EState::INITIAL:
+ case EState::READ_LOG:
+ r.SetStatus(NKikimrProto::NOTREADY);
+ break;
+
+ case EState::REPLICATION:
+ r.SetJoinedGroup(true);
+ break;
+
+ case EState::READY:
+ r.SetJoinedGroup(true);
+ r.SetReplicated(true);
+ break;
+ }
+ }
+ Send(ev->Sender, response.release(), 0, ev->Cookie);
+ } else {
+ Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::ERROR, record.GetVDiskID()), 0, ev->Cookie);
+ }
+ }
+
+ void StartInitial() {
+ Schedule(TDuration::Seconds(15), new TEvents::TEvWakeup);
+ State = EState::INITIAL;
+ }
+
+ void StartReadLog() {
+ Schedule(TDuration::MilliSeconds(100 + RandomNumber<ui64>(4900)), new TEvents::TEvWakeup);
+ State = EState::READ_LOG;
+ }
+
+ void StartReplication() {
+ State = EState::REPLICATION;
+ if (const auto& vdisk = VDisk.lock()) {
+ STLOG(PRI_INFO, BS_NODE, NWM09, "VDisk REPLICATING", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
+ vdisk->Status = NKikimrBlobStorage::EVDiskStatus::REPLICATING;
+ InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
+ }
+ ResumeReplication();
+ }
+
+ void ResumeReplication() {
+ if (const auto& vdisk = VDisk.lock()) {
+ if (const ui64 quantum = Min(vdisk->TargetDataSize - vdisk->AllocatedSize, (400 << 20) + RandomNumber<ui64>(500 << 20))) {
+ vdisk->AllocatedSize += quantum;
+ UNIT_ASSERT(vdisk->PDisk->GetAllocatedSize() <= 85 * vdisk->PDisk->Size / 100);
+ InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
+ Schedule(TDuration::MilliSeconds(100 + RandomNumber<ui64>(100)), new TEvents::TEvWakeup);
+ } else {
+ BecomeReady();
+ }
+ }
+ }
+
+ void BecomeReady() {
+ if (const auto& vdisk = VDisk.lock()) {
+ STLOG(PRI_INFO, BS_NODE, NWM08, "VDisk READY", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
+ vdisk->Status = NKikimrBlobStorage::EVDiskStatus::READY;
+ InvokeOtherActor(*NodeWardenMockActor, &TNodeWardenMockActor::SendUpdateVDiskStatus, vdisk.get());
+ State = EState::READY;
+ }
+ }
+
+ void HandleWakeup() {
+ switch (State) {
+ case EState::INITIAL:
+ StartReadLog();
+ break;
+
+ case EState::READ_LOG:
+ StartReplication();
+ break;
+
+ case EState::REPLICATION:
+ ResumeReplication();
+ break;
+
+ case EState::READY:
+ Y_FAIL();
+ }
+ }
+
+ void PassAway() override {
+ if (const auto& vdisk = VDisk.lock()) {
+ STLOG(PRI_INFO, BS_NODE, NWM07, "VDisk stopping", (VDiskId, vdisk->VDiskId), (VSlotId, vdisk->VSlotId));
+ UNIT_ASSERT_EQUAL(vdisk->Actor, this);
+ vdisk->Actor = nullptr;
+ }
+ TActorBootstrapped::PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvVStatus, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+};
diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/ya.make b/ydb/core/blobstorage/ut_blobstorage/lib/ya.make
index 69028ad727f..0f93145ef51 100644
--- a/ydb/core/blobstorage/ut_blobstorage/lib/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/lib/ya.make
@@ -1,4 +1,4 @@
-LIBRARY()
+LIBRARY()
OWNER(g:kikimr)
@@ -30,4 +30,4 @@ PEERDIR(
ydb/library/yql/public/udf/service/stub
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_blobstorage/main.cpp b/ydb/core/blobstorage/ut_blobstorage/main.cpp
index 1aa4999c8c8..3108e725301 100644
--- a/ydb/core/blobstorage/ut_blobstorage/main.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/main.cpp
@@ -1,107 +1,107 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(DonorMode) {
-
- Y_UNIT_TEST(BlobReplicationFromDonorDisk) {
- TEnvironmentSetup env(true, TBlobStorageGroupType::Erasure4Plus2Block);
- auto& runtime = env.Runtime;
-
- // enable donor mode
- env.EnableDonorMode();
-
- // create box and pool of groups
- env.CreateBoxAndPool();
-
- // commence replication for original groups and wait till it finishes
- env.CommenceReplication();
-
- auto groups = env.GetGroups();
-
- auto getBlobLocation = [&](const auto& info, const TLogoBlobID& blobId) {
- TBlobStorageGroupInfo::TVDiskIds vdiskIds;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- info->PickSubgroup(blobId.FullID().Hash(), &vdiskIds, &serviceIds);
- return std::make_pair(serviceIds[0], vdiskIds[0]); // always stored at the first disk of the subgroup
- };
-
- std::map<TLogoBlobID, TString> stored;
- std::vector<TActorId> donorVDiskIds;
-
- for (ui32 i = 0; i < 16; ++i) {
- Cerr << Endl << "*** ITERATION " << i << " ***" << Endl << Endl;
-
- // at some points allow replication to break the donor chain
- if (i == 3 || i == 7 || i == 15) {
- // commence replication for all disks of group
- env.CommenceReplication();
-
- // wait for the old disk to terminate
- auto donors = std::exchange(donorVDiskIds, {});
- for (ui32 i = 0; i < donors.size() - 1; ++i) {
- const TActorId& vdiskActorId = donors[i];
- const TActorId& edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
- runtime->Send(new IEventHandle(vdiskActorId, edge, new TEvBlobStorage::TEvVStatus(),
- IEventHandle::FlagTrackDelivery), 1);
- auto r = runtime->WaitForEdgeActorEvent({edge});
- runtime->DestroyActor(edge);
- if (r->GetTypeRewrite() == TEvents::TSystem::Undelivered) {
- break;
- } else {
- Y_VERIFY(r->GetTypeRewrite() == TEvBlobStorage::EvVStatusResult);
- }
- }
- }
-
- auto info = env.GetGroupInfo(groups[0]);
-
- // prepare new blob
- TString data = TStringBuilder() << "Hello, world! Iteration number " << i << " is on the run.";
- TDataPartSet partSet;
- info->Type.SplitData(TBlobStorageGroupType::CrcModeNone, data, partSet);
- TLogoBlobID blobId;
- for (ui32 step = 1;; ++step) {
- blobId = TLogoBlobID(1, 1 + i, step, 0, partSet.FullDataSize, 0, 1);
- const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
- if (TVDiskIdShort(vdiskId) == TVDiskIdShort(0, 0, 0)) {
- break;
- }
- }
- TString part = partSet.Parts[blobId.PartId() - 1].OwnedString;
-
- // scan through existing stored blobs and ensure they are intact
- for (const auto& [blobId, part] : stored) {
- const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
- env.CheckBlob(vdiskActorId, vdiskId, blobId, part);
- }
-
- // add it to stored set
- stored.emplace(blobId, part);
-
- // get the blob location for this group
- const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
-
- // first, check that there is no such blob in the disk
- env.CheckBlob(vdiskActorId, vdiskId, blobId, part, NKikimrProto::NODATA);
-
- // put the blob to the disk
- env.PutBlob(vdiskId, blobId, part);
-
- // check it appeared
- env.CheckBlob(vdiskActorId, vdiskId, blobId, part);
-
- // wait for sync
- env.WaitForSync(info, blobId);
-
- // settle pdisk under the VDisk
- env.SettlePDisk(vdiskActorId);
-
- // make it donor
- donorVDiskIds.push_back(vdiskActorId);
- }
- }
-
- Y_UNIT_TEST(BaseReadingTest) {
- TEnvironmentSetup env(true, TBlobStorageGroupType::ErasureNone);
- }
-
-}
+
+Y_UNIT_TEST_SUITE(DonorMode) {
+
+ Y_UNIT_TEST(BlobReplicationFromDonorDisk) {
+ TEnvironmentSetup env(true, TBlobStorageGroupType::Erasure4Plus2Block);
+ auto& runtime = env.Runtime;
+
+ // enable donor mode
+ env.EnableDonorMode();
+
+ // create box and pool of groups
+ env.CreateBoxAndPool();
+
+ // commence replication for original groups and wait till it finishes
+ env.CommenceReplication();
+
+ auto groups = env.GetGroups();
+
+ auto getBlobLocation = [&](const auto& info, const TLogoBlobID& blobId) {
+ TBlobStorageGroupInfo::TVDiskIds vdiskIds;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ info->PickSubgroup(blobId.FullID().Hash(), &vdiskIds, &serviceIds);
+ return std::make_pair(serviceIds[0], vdiskIds[0]); // always stored at the first disk of the subgroup
+ };
+
+ std::map<TLogoBlobID, TString> stored;
+ std::vector<TActorId> donorVDiskIds;
+
+ for (ui32 i = 0; i < 16; ++i) {
+ Cerr << Endl << "*** ITERATION " << i << " ***" << Endl << Endl;
+
+ // at some points allow replication to break the donor chain
+ if (i == 3 || i == 7 || i == 15) {
+ // commence replication for all disks of group
+ env.CommenceReplication();
+
+ // wait for the old disk to terminate
+ auto donors = std::exchange(donorVDiskIds, {});
+ for (ui32 i = 0; i < donors.size() - 1; ++i) {
+ const TActorId& vdiskActorId = donors[i];
+ const TActorId& edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
+ runtime->Send(new IEventHandle(vdiskActorId, edge, new TEvBlobStorage::TEvVStatus(),
+ IEventHandle::FlagTrackDelivery), 1);
+ auto r = runtime->WaitForEdgeActorEvent({edge});
+ runtime->DestroyActor(edge);
+ if (r->GetTypeRewrite() == TEvents::TSystem::Undelivered) {
+ break;
+ } else {
+ Y_VERIFY(r->GetTypeRewrite() == TEvBlobStorage::EvVStatusResult);
+ }
+ }
+ }
+
+ auto info = env.GetGroupInfo(groups[0]);
+
+ // prepare new blob
+ TString data = TStringBuilder() << "Hello, world! Iteration number " << i << " is on the run.";
+ TDataPartSet partSet;
+ info->Type.SplitData(TBlobStorageGroupType::CrcModeNone, data, partSet);
+ TLogoBlobID blobId;
+ for (ui32 step = 1;; ++step) {
+ blobId = TLogoBlobID(1, 1 + i, step, 0, partSet.FullDataSize, 0, 1);
+ const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
+ if (TVDiskIdShort(vdiskId) == TVDiskIdShort(0, 0, 0)) {
+ break;
+ }
+ }
+ TString part = partSet.Parts[blobId.PartId() - 1].OwnedString;
+
+ // scan through existing stored blobs and ensure they are intact
+ for (const auto& [blobId, part] : stored) {
+ const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
+ env.CheckBlob(vdiskActorId, vdiskId, blobId, part);
+ }
+
+ // add it to stored set
+ stored.emplace(blobId, part);
+
+ // get the blob location for this group
+ const auto& [vdiskActorId, vdiskId] = getBlobLocation(info, blobId);
+
+ // first, check that there is no such blob in the disk
+ env.CheckBlob(vdiskActorId, vdiskId, blobId, part, NKikimrProto::NODATA);
+
+ // put the blob to the disk
+ env.PutBlob(vdiskId, blobId, part);
+
+ // check it appeared
+ env.CheckBlob(vdiskActorId, vdiskId, blobId, part);
+
+ // wait for sync
+ env.WaitForSync(info, blobId);
+
+ // settle pdisk under the VDisk
+ env.SettlePDisk(vdiskActorId);
+
+ // make it donor
+ donorVDiskIds.push_back(vdiskActorId);
+ }
+ }
+
+ Y_UNIT_TEST(BaseReadingTest) {
+ TEnvironmentSetup env(true, TBlobStorageGroupType::ErasureNone);
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/mirror3of4.cpp b/ydb/core/blobstorage/ut_blobstorage/mirror3of4.cpp
index b9ffea9da2c..82807466d99 100644
--- a/ydb/core/blobstorage/ut_blobstorage/mirror3of4.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/mirror3of4.cpp
@@ -1,123 +1,123 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(Mirror3of4) {
-
- Y_UNIT_TEST(Compaction) {
- SetRandomSeed(1);
- TEnvironmentSetup env(false, TBlobStorageGroupType::ErasureMirror3of4);
- auto& runtime = env.Runtime;
+
+Y_UNIT_TEST_SUITE(Mirror3of4) {
+
+ Y_UNIT_TEST(Compaction) {
+ SetRandomSeed(1);
+ TEnvironmentSetup env(false, TBlobStorageGroupType::ErasureMirror3of4);
+ auto& runtime = env.Runtime;
env.CreateBoxAndPool();
- env.Sim(TDuration::Minutes(1));
-// runtime->SetLogPriority(NKikimrServices::BS_PROXY_PUT, NLog::PRI_DEBUG);
-// runtime->SetLogPriority(NKikimrServices::BS_VDISK_PUT, NLog::PRI_DEBUG);
-
- const auto& groups = env.GetGroups();
- const ui32 groupId = *groups.begin();
- Cerr << "operating on group " << groupId << Endl;
-
- TString blob = "hello, world";
- const ui64 tabletId = 1;
- const ui32 gen = 1;
- ui32 step = 1;
- const ui8 channel = 0;
- const TLogoBlobID id(tabletId, gen, step++, channel, blob.size(), 0);
-
- const TActorId& edge = runtime->AllocateEdgeActor(1);
- runtime->WrapInActorContext(edge, [&] {
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, blob, TInstant::Max(),
- NKikimrBlobStorage::EPutHandleClass::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput);
- SendToBSProxy(edge, groupId, ev.release());
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
-
- auto info = env.GetGroupInfo(groupId);
-
- for (ui32 i = 0; i < 10000; ++i) {
- Cerr << "iteration " << i << Endl;
- const ui32 size = 1048576;
- TString data = TString::Uninitialized(size);
- memset(data.Detach(), 1, size);
- const TLogoBlobID xid(tabletId, gen, step++, channel, size, 0);
- runtime->WrapInActorContext(edge, [&] {
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(xid, data, TInstant::Max(),
- NKikimrBlobStorage::EPutHandleClass::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput);
- SendToBSProxy(edge, groupId, ev.release());
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- if (i % 100 == 99) {
- Cerr << "compaction" << Endl;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- env.CompactVDisk(info->GetActorId(i));
- }
- }
- if (i % 200 == 199) {
- Cerr << "garbage collect" << Endl;
- TVector<TLogoBlobID> keep;
- if (i < 200) {
- keep.push_back(id);
- }
- auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(tabletId, gen, i, channel, true, gen,
- step - 1, keep ? new TVector<TLogoBlobID>(keep) : nullptr, nullptr, TInstant::Max(), true);
- runtime->WrapInActorContext(edge, [&] { SendToBSProxy(edge, groupId, ev.release()); });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
- if (i == 500) {
- const TActorId self = runtime->AllocateEdgeActor(1);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
- ev->Record.MutableVSlotId()->SetNodeId(2);
- ev->Record.MutableVSlotId()->SetPDiskId(1000);
- ev->Record.MutableVSlotId()->SetVSlotId(1000);
- runtime->SendToPipe(env.TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
- auto& r = response->Get()->Record;
- UNIT_ASSERT_EQUAL(r.GetStatus(), NKikimrProto::OK);
- }
- if (i == 600) {
- const TActorId self = runtime->AllocateEdgeActor(1);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
- ev->Record.MutableVSlotId()->SetNodeId(3);
- ev->Record.MutableVSlotId()->SetPDiskId(1000);
- ev->Record.MutableVSlotId()->SetVSlotId(1000);
- runtime->SendToPipe(env.TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
- auto& r = response->Get()->Record;
- UNIT_ASSERT_EQUAL(r.GetStatus(), NKikimrProto::OK);
- }
- }
-
- env.Sim(TDuration::Minutes(30));
-
- std::vector<TActorId> queues;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- queues.push_back(env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
- }
-
- ui32 numData = 0, numMetadata = 0;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(info->GetVDiskId(i), TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead);
- query->AddExtremeQuery(id, 0, 0);
- runtime->Send(new IEventHandle(queues[i], edge, query.release()), queues[i].NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
- Cerr << res->Get()->ToString() << Endl;
- auto& record = res->Get()->Record;
- UNIT_ASSERT_EQUAL(record.ResultSize(), 1);
- auto& r = record.GetResult(0);
- UNIT_ASSERT(r.GetStatus() == NKikimrProto::OK || r.GetStatus() == NKikimrProto::NODATA || r.GetStatus() == NKikimrProto::NOT_YET);
- if (r.GetStatus() == NKikimrProto::OK) {
- const auto& id = LogoBlobIDFromLogoBlobID(r.GetBlobID());
- UNIT_ASSERT(id.PartId() >= 1 && id.PartId() <= 3);
- if (id.PartId() == 3) {
- ++numMetadata;
- } else {
- ++numData;
- }
- }
- }
- UNIT_ASSERT(numData >= 3 && numData + numMetadata >= 5);
- }
-
-}
+ env.Sim(TDuration::Minutes(1));
+// runtime->SetLogPriority(NKikimrServices::BS_PROXY_PUT, NLog::PRI_DEBUG);
+// runtime->SetLogPriority(NKikimrServices::BS_VDISK_PUT, NLog::PRI_DEBUG);
+
+ const auto& groups = env.GetGroups();
+ const ui32 groupId = *groups.begin();
+ Cerr << "operating on group " << groupId << Endl;
+
+ TString blob = "hello, world";
+ const ui64 tabletId = 1;
+ const ui32 gen = 1;
+ ui32 step = 1;
+ const ui8 channel = 0;
+ const TLogoBlobID id(tabletId, gen, step++, channel, blob.size(), 0);
+
+ const TActorId& edge = runtime->AllocateEdgeActor(1);
+ runtime->WrapInActorContext(edge, [&] {
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, blob, TInstant::Max(),
+ NKikimrBlobStorage::EPutHandleClass::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput);
+ SendToBSProxy(edge, groupId, ev.release());
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+
+ auto info = env.GetGroupInfo(groupId);
+
+ for (ui32 i = 0; i < 10000; ++i) {
+ Cerr << "iteration " << i << Endl;
+ const ui32 size = 1048576;
+ TString data = TString::Uninitialized(size);
+ memset(data.Detach(), 1, size);
+ const TLogoBlobID xid(tabletId, gen, step++, channel, size, 0);
+ runtime->WrapInActorContext(edge, [&] {
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(xid, data, TInstant::Max(),
+ NKikimrBlobStorage::EPutHandleClass::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput);
+ SendToBSProxy(edge, groupId, ev.release());
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ if (i % 100 == 99) {
+ Cerr << "compaction" << Endl;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ env.CompactVDisk(info->GetActorId(i));
+ }
+ }
+ if (i % 200 == 199) {
+ Cerr << "garbage collect" << Endl;
+ TVector<TLogoBlobID> keep;
+ if (i < 200) {
+ keep.push_back(id);
+ }
+ auto ev = std::make_unique<TEvBlobStorage::TEvCollectGarbage>(tabletId, gen, i, channel, true, gen,
+ step - 1, keep ? new TVector<TLogoBlobID>(keep) : nullptr, nullptr, TInstant::Max(), true);
+ runtime->WrapInActorContext(edge, [&] { SendToBSProxy(edge, groupId, ev.release()); });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+ if (i == 500) {
+ const TActorId self = runtime->AllocateEdgeActor(1);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
+ ev->Record.MutableVSlotId()->SetNodeId(2);
+ ev->Record.MutableVSlotId()->SetPDiskId(1000);
+ ev->Record.MutableVSlotId()->SetVSlotId(1000);
+ runtime->SendToPipe(env.TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
+ auto& r = response->Get()->Record;
+ UNIT_ASSERT_EQUAL(r.GetStatus(), NKikimrProto::OK);
+ }
+ if (i == 600) {
+ const TActorId self = runtime->AllocateEdgeActor(1);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
+ ev->Record.MutableVSlotId()->SetNodeId(3);
+ ev->Record.MutableVSlotId()->SetPDiskId(1000);
+ ev->Record.MutableVSlotId()->SetVSlotId(1000);
+ runtime->SendToPipe(env.TabletId, self, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(self);
+ auto& r = response->Get()->Record;
+ UNIT_ASSERT_EQUAL(r.GetStatus(), NKikimrProto::OK);
+ }
+ }
+
+ env.Sim(TDuration::Minutes(30));
+
+ std::vector<TActorId> queues;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ queues.push_back(env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000));
+ }
+
+ ui32 numData = 0, numMetadata = 0;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(info->GetVDiskId(i), TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead);
+ query->AddExtremeQuery(id, 0, 0);
+ runtime->Send(new IEventHandle(queues[i], edge, query.release()), queues[i].NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
+ Cerr << res->Get()->ToString() << Endl;
+ auto& record = res->Get()->Record;
+ UNIT_ASSERT_EQUAL(record.ResultSize(), 1);
+ auto& r = record.GetResult(0);
+ UNIT_ASSERT(r.GetStatus() == NKikimrProto::OK || r.GetStatus() == NKikimrProto::NODATA || r.GetStatus() == NKikimrProto::NOT_YET);
+ if (r.GetStatus() == NKikimrProto::OK) {
+ const auto& id = LogoBlobIDFromLogoBlobID(r.GetBlobID());
+ UNIT_ASSERT(id.PartId() >= 1 && id.PartId() <= 3);
+ if (id.PartId() == 3) {
+ ++numMetadata;
+ } else {
+ ++numData;
+ }
+ }
+ }
+ UNIT_ASSERT(numData >= 3 && numData + numMetadata >= 5);
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/multiget.cpp b/ydb/core/blobstorage/ut_blobstorage/multiget.cpp
index 04127e8da70..d9f545cc348 100644
--- a/ydb/core/blobstorage/ut_blobstorage/multiget.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/multiget.cpp
@@ -1,62 +1,62 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(MultiGet) {
-
- Y_UNIT_TEST(SequentialGet) {
- TEnvironmentSetup env(false, TBlobStorageGroupType::Erasure4Plus2Block);
- auto& runtime = env.Runtime;
- env.CreateBoxAndPool();
- const ui32 groupId = env.GetGroups().front();
-
- const TActorId& edge = runtime->AllocateEdgeActor(1);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvStatus(TInstant::Max()));
- });
- {
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvStatusResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
- ui32 numInFlight = 0;
- auto wait = [&](ui32 max) {
- for (; numInFlight > max; --numInFlight) {
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
- };
-
- for (ui32 i = 1; i <= 1000000; ++i) {
- const TString buffer = "A SMALL BLOB 16b";
- const TLogoBlobID id(1, 1, i, 0, buffer.size(), 0);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
- });
- ++numInFlight;
- wait(16);
- if (i % 1000 == 0) {
- Cerr << i << "\r";
- }
- }
- wait(0);
-
- auto rusage = TRusage::Get();
- const ui64 rssOnBegin = rusage.MaxRss;
- Cerr << "rssOnBegin# " << rssOnBegin << Endl;
-
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvRange(1, TLogoBlobID(1, 0, 0, 0, 0, 0),
- TLogoBlobID(1, Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel, TLogoBlobID::MaxBlobSize,
- TLogoBlobID::MaxCookie), false, TInstant::Max()));
- });
- {
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvRangeResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- }
-
- rusage = TRusage::Get();
- const ui64 rssOnEnd = rusage.MaxRss;
-
- Cerr << rssOnBegin << " -> " << rssOnEnd << Endl;
- }
-
-}
+
+Y_UNIT_TEST_SUITE(MultiGet) {
+
+ Y_UNIT_TEST(SequentialGet) {
+ TEnvironmentSetup env(false, TBlobStorageGroupType::Erasure4Plus2Block);
+ auto& runtime = env.Runtime;
+ env.CreateBoxAndPool();
+ const ui32 groupId = env.GetGroups().front();
+
+ const TActorId& edge = runtime->AllocateEdgeActor(1);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvStatus(TInstant::Max()));
+ });
+ {
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvStatusResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+ ui32 numInFlight = 0;
+ auto wait = [&](ui32 max) {
+ for (; numInFlight > max; --numInFlight) {
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+ };
+
+ for (ui32 i = 1; i <= 1000000; ++i) {
+ const TString buffer = "A SMALL BLOB 16b";
+ const TLogoBlobID id(1, 1, i, 0, buffer.size(), 0);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
+ });
+ ++numInFlight;
+ wait(16);
+ if (i % 1000 == 0) {
+ Cerr << i << "\r";
+ }
+ }
+ wait(0);
+
+ auto rusage = TRusage::Get();
+ const ui64 rssOnBegin = rusage.MaxRss;
+ Cerr << "rssOnBegin# " << rssOnBegin << Endl;
+
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groupId, new TEvBlobStorage::TEvRange(1, TLogoBlobID(1, 0, 0, 0, 0, 0),
+ TLogoBlobID(1, Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel, TLogoBlobID::MaxBlobSize,
+ TLogoBlobID::MaxCookie), false, TInstant::Max()));
+ });
+ {
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvRangeResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ }
+
+ rusage = TRusage::Get();
+ const ui64 rssOnEnd = rusage.MaxRss;
+
+ Cerr << rssOnBegin << " -> " << rssOnEnd << Endl;
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/osiris.cpp b/ydb/core/blobstorage/ut_blobstorage/osiris.cpp
index 989452e3087..6ad384b1958 100644
--- a/ydb/core/blobstorage/ut_blobstorage/osiris.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/osiris.cpp
@@ -1,354 +1,354 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/dsproxy/dsproxy.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
-#include <util/system/condvar.h>
-#include <util/system/info.h>
-
-#define SINGLE_THREAD 0
-
-namespace {
-
-bool DoTestCase(TBlobStorageGroupType::EErasureSpecies erasure, const std::set<std::pair<ui32, ui32>>& orderNumToPart,
- bool doNotNeedToRestore, const TLogoBlobID& id, const TString& data, IOutputStream *stream) {
- const TBlobStorageGroupType type(erasure);
- const ui32 numDisks = type.BlobSubgroupSize();
-
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = numDisks,
- .Erasure = erasure,
- .PrepareRuntime = [&](TTestActorSystem& runtime) {
- runtime.LogStream = stream;
- },
- });
-
- env.CreateBoxAndPool(1, 1);
-
- const auto& groups = env.GetGroups();
- Y_VERIFY(groups.size() == 1);
- const auto& info = env.GetGroupInfo(groups.front());
-
- TBlobStorageGroupInfo::TOrderNums orderNums;
- info->GetTopology().PickSubgroup(id.Hash(), orderNums);
-
- TString temp = data;
- char *buffer = temp.Detach();
- Encrypt(buffer, buffer, 0, temp.size(), id, *info);
- TDataPartSet parts;
- info->Type.SplitData((TBlobStorageGroupType::ECrcMode)id.CrcMode(), temp, parts);
-
- TString error;
-
- // put parts to disks
- for (const auto& [orderNum, partIdx] : orderNumToPart) {
- const TActorId& queueId = env.CreateQueueActor(info->GetVDiskId(orderNum), NKikimrBlobStorage::PutTabletLog, 0);
- const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- const TLogoBlobID blobId(id, partIdx + 1);
- const TString& buffer = type.PartSize(blobId) ? parts.Parts[partIdx].OwnedString : TString();
- env.Runtime->Send(new IEventHandle(queueId, sender, new TEvBlobStorage::TEvVPut(blobId, buffer,
- info->GetVDiskId(orderNum), false, nullptr, TInstant::Max(), NKikimrBlobStorage::TabletLog)),
- sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVPutResult>(sender);
- Y_VERIFY(res->Get()->Record.GetStatus() == NKikimrProto::OK);
- }
-
- // sync
- env.Sim(TDuration::Seconds(10));
-
- // obtain config
- NKikimrBlobStorage::TConfigRequest request;
- request.AddCommand()->MutableQueryBaseConfig();
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- Y_VERIFY(response.GetSuccess());
- for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
- const TVDiskID vdiskId(vslot.GetGroupId(), vslot.GetGroupGeneration(), vslot.GetFailRealmIdx(),
- vslot.GetFailDomainIdx(), vslot.GetVDiskIdx());
-
- const TActorId sender = env.Runtime->AllocateEdgeActor(1);
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
- auto *slotId = ev->Record.MutableVSlotId();
- slotId->CopyFrom(vslot.GetVSlotId());
- env.Runtime->SendToPipe(env.TabletId, sender, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(sender);
- Y_VERIFY(response->Get()->Record.GetStatus() == NKikimrProto::OK);
-
- env.Sim(TDuration::Seconds(30));
- }
-
- // collect blob info from cluster
- TSubgroupPartLayout layout;
- std::vector<std::tuple<TVDiskID, TLogoBlobID, NKikimrProto::EReplyStatus>> v;
- for (ui32 i = 0; i < numDisks; ++i) {
- const TActorId& queueId = env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::GetFastRead, 0);
- const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(info->GetVDiskId(i), TInstant::Max(),
- NKikimrBlobStorage::FastRead);
- query->AddExtremeQuery(id, 0, 0);
- env.Runtime->Send(new IEventHandle(queueId, sender, query.release()), sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
- const auto& record = res->Get()->Record;
- Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- for (const auto& blob : record.GetResult()) {
- const auto& id = LogoBlobIDFromLogoBlobID(blob.GetBlobID());
- v.emplace_back(vdiskId, id, blob.GetStatus());
- if (blob.GetStatus() == NKikimrProto::OK || blob.GetStatus() == NKikimrProto::NOT_YET) {
- layout.AddItem(info->GetIdxInSubgroup(vdiskId, id.FullID().Hash()), id.PartId() - 1, info->Type);
- }
- }
- }
-
- std::sort(v.begin(), v.end());
- for (const auto& item : v) {
- const TVDiskID& vdiskId = std::get<0>(item);
- const TLogoBlobID& blobId = std::get<1>(item);
- const NKikimrProto::EReplyStatus status = std::get<2>(item);
- *stream << "VDiskId# " << vdiskId << " BlobId# " << blobId << " Status# " << NKikimrProto::EReplyStatus_Name(status) << Endl;
- if (doNotNeedToRestore && (status == NKikimrProto::OK || status == NKikimrProto::NOT_YET)) {
- const ui32 orderNum = info->GetOrderNumber(vdiskId);
- if (!orderNumToPart.count(std::make_pair(orderNum, blobId.PartId() - 1))) {
- error = "Excessive part written to disk";
- }
- }
- }
-
- if (error || doNotNeedToRestore) {
- // skip checking
- } else if (info->GetQuorumChecker().GetBlobState(layout, {&info->GetTopology()}) != TBlobStorageGroupInfo::EBS_FULL) {
- error = "Blob is not in EBS_FULL state";
- } else {
- switch (info->Type.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- case TBlobStorageGroupType::ErasureMirror3of4:
- break;
-
- default: {
- ui32 numDistinctParts = 0;
- for (ui32 i = 0; i < info->Type.TotalPartCount(); ++i) {
- if (layout.GetDisksWithPart(i)) {
- ++numDistinctParts;
- }
- }
- if (numDistinctParts != info->Type.TotalPartCount()) {
- error = "Not enough parts written";
- }
- break;
- }
- }
- }
-
- *stream << "[";
- bool first = true;
- for (const auto& [orderNum, part] : orderNumToPart) {
- const auto& vdiskId = info->GetVDiskId(orderNum);
- *stream << (std::exchange(first, false) ? "" : " ") << "[" << (int)vdiskId.FailRealm << ":"
- << (int)vdiskId.FailDomain << "]:" << part;
- }
- *stream << "] " << (error ? error : "Valid") << Endl;
-
- return !error;
-}
-
-template<typename F, typename G>
-void RunInThreads(size_t numTasks, F&& func, G&& postprocess) {
- using TResult = std::invoke_result_t<F, size_t>;
-
- std::deque<TResult> output;
- TMutex outputMutex;
- TCondVar outputCV;
- size_t numRunning = 0;
-
- size_t index = 0;
- TMutex indexMutex;
- auto threadFunc = [&] {
- for (;;) {
- size_t taskIndex;
- with_lock (indexMutex) {
- if (index == numTasks) {
- break;
- }
- taskIndex = index++;
- }
-
- TResult result = std::invoke(func, taskIndex);
-
- with_lock (outputMutex) {
- output.push_back(std::move(result));
- }
- outputCV.Signal();
- }
- with_lock (outputMutex) {
- if (!--numRunning) {
- outputCV.BroadCast();
- }
- }
- };
-
- std::list<TThread> threads;
- while (threads.size() < NSystemInfo::NumberOfCpus()) {
- threads.emplace_back(threadFunc);
- ++numRunning;
- }
- for (auto& thread : threads) {
- thread.Start();
- }
- for (;;) {
- std::deque<TResult> results;
- with_lock (outputMutex) {
- results.swap(output);
- if (results.empty()) {
- if (numRunning) {
- outputCV.Wait(outputMutex);
- continue;
- } else {
- break;
- }
- }
- }
- for (TResult& item : results) {
- std::invoke(postprocess, item);
- }
- }
- for (auto& thread : threads) {
- thread.Join();
- }
-}
-
-void DoTest(TBlobStorageGroupType::EErasureSpecies erasure) {
- const TBlobStorageGroupType type(erasure);
- const ui32 numDisks = type.BlobSubgroupSize();
-
- const ui32 numRealms = erasure == TBlobStorageGroupType::ErasureMirror3dc ? 3 : 1;
- const ui32 numDomains = erasure == TBlobStorageGroupType::ErasureMirror3dc ? 3 : type.BlobSubgroupSize();
- TBlobStorageGroupInfo tempInfo(type, 1, numDomains, numRealms); // group with the same layout as ours
- const auto& topology = tempInfo.GetTopology();
-
- TString data = "Hello, World!\n";
- TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
-
- TBlobStorageGroupInfo::TOrderNums orderNums;
- topology.PickSubgroup(id.Hash(), orderNums);
-
- std::vector<std::vector<ui32>> suitablePartsByOrderNum(numDisks);
- for (ui32 i = 0; i < type.BlobSubgroupSize(); ++i) {
- const ui32 orderNum = orderNums[i];
- auto& v = suitablePartsByOrderNum[orderNum];
- v.push_back(0); // no parts
- switch (erasure) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- v.push_back(1 << (i % 3)); // per-dc part indexing
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4:
- v.push_back(1 << 2); // meta
- v.push_back(1 << (i & 1)); // data
- break;
-
- default:
- if (i < type.TotalPartCount()) {
- v.push_back(1 << i); // main
- } else {
- for (ui32 j = 1; j < (1 << type.TotalPartCount()); ++j) {
- if (PopCount(j) <= 1) {
- v.push_back(j); // handoff
- }
- }
- }
- break;
- }
- }
-
- std::vector<std::tuple<std::set<std::pair<ui32, ui32>>, bool>> tasks;
-
- std::vector<size_t> indexes(numDisks, 0);
- for (;;) {
- TSubgroupPartLayout layout;
- std::set<std::pair<ui32, ui32>> orderNumToPart;
- for (ui32 i = 0; i < numDisks; ++i) {
- ui32 mask = suitablePartsByOrderNum[i][indexes[i]];
- while (mask) {
- const ui32 part = CountTrailingZeroBits(mask);
- orderNumToPart.emplace(i, part);
- layout.AddItem(topology.GetIdxInSubgroup(topology.GetVDiskId(i), id.Hash()), part, type);
- mask &= ~(1 << part);
- }
- }
- bool doNotNeedToRestore;
- switch (erasure) {
- case TBlobStorageGroupType::ErasureMirror3dc:
- doNotNeedToRestore = topology.GetQuorumChecker().CheckQuorumForSubgroup(layout.GetInvolvedDisks(&topology)) ||
- (!layout.GetDisksWithPart(0) && !layout.GetDisksWithPart(1) && !layout.GetDisksWithPart(2));
- break;
-
- case TBlobStorageGroupType::ErasureMirror3of4: {
- auto [data, any] = layout.GetMirror3of4State();
- doNotNeedToRestore = !data || (data >= 3 && any >= 5);
- break;
- }
-
- default: {
- ui32 numDistinctParts = 0;
- for (ui32 i = 0; i < type.TotalPartCount(); ++i) {
- if (layout.GetDisksWithPart(i)) {
- ++numDistinctParts;
- }
- }
- doNotNeedToRestore = numDistinctParts < type.MinimalRestorablePartCount() || (
- numDistinctParts == type.TotalPartCount() &&
- layout.GetInvolvedDisks(&topology).GetNumSetItems() >= type.DataParts() + type.ParityParts() &&
- layout.CountEffectiveReplicas(type) == numDistinctParts
- );
- break;
- }
- }
-
- tasks.emplace_back(std::move(orderNumToPart), doNotNeedToRestore);
-
- bool carry = true;
- for (ui32 i = 0; carry && i < numDisks; ++i) {
- carry = ++indexes[i] == suitablePartsByOrderNum[i].size();
- if (carry) {
- indexes[i] = 0;
- }
- }
- if (carry) {
- break;
- }
- }
-
- Cerr << "total# " << tasks.size() << Endl;
-
- ui32 badCases = 0;
-
-#if SINGLE_THREAD
- for (const auto& [orderNumToPart, doNotNeedToRestore] : tasks) {
- badCases += !DoTestCase(erasure, orderNumToPart, doNotNeedToRestore, id, data, &Cerr);
- }
-#else
- ui32 done = 0;
- auto func = [&](size_t index) {
- const auto& [orderNumToPart, doNotNeedToRestore] = tasks[index];
- TStringStream stream;
- const bool res = !DoTestCase(erasure, orderNumToPart, doNotNeedToRestore, id, data, &stream);
- return std::make_tuple(stream.Str(), res);
- };
- auto post = [&](const std::tuple<TString, bool>& value) {
- const auto& [log, res] = value;
- Cerr << log;
- badCases += res;
- Cerr << "done " << ++done << " of " << tasks.size() << Endl;
- };
- RunInThreads(tasks.size(), func, post);
-#endif
-
- UNIT_ASSERT_VALUES_EQUAL(badCases, 0);
-}
-
-}
-
-Y_UNIT_TEST_SUITE(Osiris) {
-
- Y_UNIT_TEST(mirror3dc) { DoTest(TBlobStorageGroupType::ErasureMirror3dc); }
- Y_UNIT_TEST(mirror3of4) { DoTest(TBlobStorageGroupType::ErasureMirror3of4); }
- Y_UNIT_TEST(block42) { DoTest(TBlobStorageGroupType::Erasure4Plus2Block); }
-
-}
+#include <util/system/condvar.h>
+#include <util/system/info.h>
+
+#define SINGLE_THREAD 0
+
+namespace {
+
+bool DoTestCase(TBlobStorageGroupType::EErasureSpecies erasure, const std::set<std::pair<ui32, ui32>>& orderNumToPart,
+ bool doNotNeedToRestore, const TLogoBlobID& id, const TString& data, IOutputStream *stream) {
+ const TBlobStorageGroupType type(erasure);
+ const ui32 numDisks = type.BlobSubgroupSize();
+
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = numDisks,
+ .Erasure = erasure,
+ .PrepareRuntime = [&](TTestActorSystem& runtime) {
+ runtime.LogStream = stream;
+ },
+ });
+
+ env.CreateBoxAndPool(1, 1);
+
+ const auto& groups = env.GetGroups();
+ Y_VERIFY(groups.size() == 1);
+ const auto& info = env.GetGroupInfo(groups.front());
+
+ TBlobStorageGroupInfo::TOrderNums orderNums;
+ info->GetTopology().PickSubgroup(id.Hash(), orderNums);
+
+ TString temp = data;
+ char *buffer = temp.Detach();
+ Encrypt(buffer, buffer, 0, temp.size(), id, *info);
+ TDataPartSet parts;
+ info->Type.SplitData((TBlobStorageGroupType::ECrcMode)id.CrcMode(), temp, parts);
+
+ TString error;
+
+ // put parts to disks
+ for (const auto& [orderNum, partIdx] : orderNumToPart) {
+ const TActorId& queueId = env.CreateQueueActor(info->GetVDiskId(orderNum), NKikimrBlobStorage::PutTabletLog, 0);
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ const TLogoBlobID blobId(id, partIdx + 1);
+ const TString& buffer = type.PartSize(blobId) ? parts.Parts[partIdx].OwnedString : TString();
+ env.Runtime->Send(new IEventHandle(queueId, sender, new TEvBlobStorage::TEvVPut(blobId, buffer,
+ info->GetVDiskId(orderNum), false, nullptr, TInstant::Max(), NKikimrBlobStorage::TabletLog)),
+ sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVPutResult>(sender);
+ Y_VERIFY(res->Get()->Record.GetStatus() == NKikimrProto::OK);
+ }
+
+ // sync
+ env.Sim(TDuration::Seconds(10));
+
+ // obtain config
+ NKikimrBlobStorage::TConfigRequest request;
+ request.AddCommand()->MutableQueryBaseConfig();
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ Y_VERIFY(response.GetSuccess());
+ for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
+ const TVDiskID vdiskId(vslot.GetGroupId(), vslot.GetGroupGeneration(), vslot.GetFailRealmIdx(),
+ vslot.GetFailDomainIdx(), vslot.GetVDiskIdx());
+
+ const TActorId sender = env.Runtime->AllocateEdgeActor(1);
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerGroupReconfigureWipe>();
+ auto *slotId = ev->Record.MutableVSlotId();
+ slotId->CopyFrom(vslot.GetVSlotId());
+ env.Runtime->SendToPipe(env.TabletId, sender, ev.release(), 0, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(sender);
+ Y_VERIFY(response->Get()->Record.GetStatus() == NKikimrProto::OK);
+
+ env.Sim(TDuration::Seconds(30));
+ }
+
+ // collect blob info from cluster
+ TSubgroupPartLayout layout;
+ std::vector<std::tuple<TVDiskID, TLogoBlobID, NKikimrProto::EReplyStatus>> v;
+ for (ui32 i = 0; i < numDisks; ++i) {
+ const TActorId& queueId = env.CreateQueueActor(info->GetVDiskId(i), NKikimrBlobStorage::GetFastRead, 0);
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(info->GetVDiskId(i), TInstant::Max(),
+ NKikimrBlobStorage::FastRead);
+ query->AddExtremeQuery(id, 0, 0);
+ env.Runtime->Send(new IEventHandle(queueId, sender, query.release()), sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
+ const auto& record = res->Get()->Record;
+ Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ for (const auto& blob : record.GetResult()) {
+ const auto& id = LogoBlobIDFromLogoBlobID(blob.GetBlobID());
+ v.emplace_back(vdiskId, id, blob.GetStatus());
+ if (blob.GetStatus() == NKikimrProto::OK || blob.GetStatus() == NKikimrProto::NOT_YET) {
+ layout.AddItem(info->GetIdxInSubgroup(vdiskId, id.FullID().Hash()), id.PartId() - 1, info->Type);
+ }
+ }
+ }
+
+ std::sort(v.begin(), v.end());
+ for (const auto& item : v) {
+ const TVDiskID& vdiskId = std::get<0>(item);
+ const TLogoBlobID& blobId = std::get<1>(item);
+ const NKikimrProto::EReplyStatus status = std::get<2>(item);
+ *stream << "VDiskId# " << vdiskId << " BlobId# " << blobId << " Status# " << NKikimrProto::EReplyStatus_Name(status) << Endl;
+ if (doNotNeedToRestore && (status == NKikimrProto::OK || status == NKikimrProto::NOT_YET)) {
+ const ui32 orderNum = info->GetOrderNumber(vdiskId);
+ if (!orderNumToPart.count(std::make_pair(orderNum, blobId.PartId() - 1))) {
+ error = "Excessive part written to disk";
+ }
+ }
+ }
+
+ if (error || doNotNeedToRestore) {
+ // skip checking
+ } else if (info->GetQuorumChecker().GetBlobState(layout, {&info->GetTopology()}) != TBlobStorageGroupInfo::EBS_FULL) {
+ error = "Blob is not in EBS_FULL state";
+ } else {
+ switch (info->Type.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ break;
+
+ default: {
+ ui32 numDistinctParts = 0;
+ for (ui32 i = 0; i < info->Type.TotalPartCount(); ++i) {
+ if (layout.GetDisksWithPart(i)) {
+ ++numDistinctParts;
+ }
+ }
+ if (numDistinctParts != info->Type.TotalPartCount()) {
+ error = "Not enough parts written";
+ }
+ break;
+ }
+ }
+ }
+
+ *stream << "[";
+ bool first = true;
+ for (const auto& [orderNum, part] : orderNumToPart) {
+ const auto& vdiskId = info->GetVDiskId(orderNum);
+ *stream << (std::exchange(first, false) ? "" : " ") << "[" << (int)vdiskId.FailRealm << ":"
+ << (int)vdiskId.FailDomain << "]:" << part;
+ }
+ *stream << "] " << (error ? error : "Valid") << Endl;
+
+ return !error;
+}
+
+template<typename F, typename G>
+void RunInThreads(size_t numTasks, F&& func, G&& postprocess) {
+ using TResult = std::invoke_result_t<F, size_t>;
+
+ std::deque<TResult> output;
+ TMutex outputMutex;
+ TCondVar outputCV;
+ size_t numRunning = 0;
+
+ size_t index = 0;
+ TMutex indexMutex;
+ auto threadFunc = [&] {
+ for (;;) {
+ size_t taskIndex;
+ with_lock (indexMutex) {
+ if (index == numTasks) {
+ break;
+ }
+ taskIndex = index++;
+ }
+
+ TResult result = std::invoke(func, taskIndex);
+
+ with_lock (outputMutex) {
+ output.push_back(std::move(result));
+ }
+ outputCV.Signal();
+ }
+ with_lock (outputMutex) {
+ if (!--numRunning) {
+ outputCV.BroadCast();
+ }
+ }
+ };
+
+ std::list<TThread> threads;
+ while (threads.size() < NSystemInfo::NumberOfCpus()) {
+ threads.emplace_back(threadFunc);
+ ++numRunning;
+ }
+ for (auto& thread : threads) {
+ thread.Start();
+ }
+ for (;;) {
+ std::deque<TResult> results;
+ with_lock (outputMutex) {
+ results.swap(output);
+ if (results.empty()) {
+ if (numRunning) {
+ outputCV.Wait(outputMutex);
+ continue;
+ } else {
+ break;
+ }
+ }
+ }
+ for (TResult& item : results) {
+ std::invoke(postprocess, item);
+ }
+ }
+ for (auto& thread : threads) {
+ thread.Join();
+ }
+}
+
+void DoTest(TBlobStorageGroupType::EErasureSpecies erasure) {
+ const TBlobStorageGroupType type(erasure);
+ const ui32 numDisks = type.BlobSubgroupSize();
+
+ const ui32 numRealms = erasure == TBlobStorageGroupType::ErasureMirror3dc ? 3 : 1;
+ const ui32 numDomains = erasure == TBlobStorageGroupType::ErasureMirror3dc ? 3 : type.BlobSubgroupSize();
+ TBlobStorageGroupInfo tempInfo(type, 1, numDomains, numRealms); // group with the same layout as ours
+ const auto& topology = tempInfo.GetTopology();
+
+ TString data = "Hello, World!\n";
+ TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
+
+ TBlobStorageGroupInfo::TOrderNums orderNums;
+ topology.PickSubgroup(id.Hash(), orderNums);
+
+ std::vector<std::vector<ui32>> suitablePartsByOrderNum(numDisks);
+ for (ui32 i = 0; i < type.BlobSubgroupSize(); ++i) {
+ const ui32 orderNum = orderNums[i];
+ auto& v = suitablePartsByOrderNum[orderNum];
+ v.push_back(0); // no parts
+ switch (erasure) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ v.push_back(1 << (i % 3)); // per-dc part indexing
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ v.push_back(1 << 2); // meta
+ v.push_back(1 << (i & 1)); // data
+ break;
+
+ default:
+ if (i < type.TotalPartCount()) {
+ v.push_back(1 << i); // main
+ } else {
+ for (ui32 j = 1; j < (1 << type.TotalPartCount()); ++j) {
+ if (PopCount(j) <= 1) {
+ v.push_back(j); // handoff
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ std::vector<std::tuple<std::set<std::pair<ui32, ui32>>, bool>> tasks;
+
+ std::vector<size_t> indexes(numDisks, 0);
+ for (;;) {
+ TSubgroupPartLayout layout;
+ std::set<std::pair<ui32, ui32>> orderNumToPart;
+ for (ui32 i = 0; i < numDisks; ++i) {
+ ui32 mask = suitablePartsByOrderNum[i][indexes[i]];
+ while (mask) {
+ const ui32 part = CountTrailingZeroBits(mask);
+ orderNumToPart.emplace(i, part);
+ layout.AddItem(topology.GetIdxInSubgroup(topology.GetVDiskId(i), id.Hash()), part, type);
+ mask &= ~(1 << part);
+ }
+ }
+ bool doNotNeedToRestore;
+ switch (erasure) {
+ case TBlobStorageGroupType::ErasureMirror3dc:
+ doNotNeedToRestore = topology.GetQuorumChecker().CheckQuorumForSubgroup(layout.GetInvolvedDisks(&topology)) ||
+ (!layout.GetDisksWithPart(0) && !layout.GetDisksWithPart(1) && !layout.GetDisksWithPart(2));
+ break;
+
+ case TBlobStorageGroupType::ErasureMirror3of4: {
+ auto [data, any] = layout.GetMirror3of4State();
+ doNotNeedToRestore = !data || (data >= 3 && any >= 5);
+ break;
+ }
+
+ default: {
+ ui32 numDistinctParts = 0;
+ for (ui32 i = 0; i < type.TotalPartCount(); ++i) {
+ if (layout.GetDisksWithPart(i)) {
+ ++numDistinctParts;
+ }
+ }
+ doNotNeedToRestore = numDistinctParts < type.MinimalRestorablePartCount() || (
+ numDistinctParts == type.TotalPartCount() &&
+ layout.GetInvolvedDisks(&topology).GetNumSetItems() >= type.DataParts() + type.ParityParts() &&
+ layout.CountEffectiveReplicas(type) == numDistinctParts
+ );
+ break;
+ }
+ }
+
+ tasks.emplace_back(std::move(orderNumToPart), doNotNeedToRestore);
+
+ bool carry = true;
+ for (ui32 i = 0; carry && i < numDisks; ++i) {
+ carry = ++indexes[i] == suitablePartsByOrderNum[i].size();
+ if (carry) {
+ indexes[i] = 0;
+ }
+ }
+ if (carry) {
+ break;
+ }
+ }
+
+ Cerr << "total# " << tasks.size() << Endl;
+
+ ui32 badCases = 0;
+
+#if SINGLE_THREAD
+ for (const auto& [orderNumToPart, doNotNeedToRestore] : tasks) {
+ badCases += !DoTestCase(erasure, orderNumToPart, doNotNeedToRestore, id, data, &Cerr);
+ }
+#else
+ ui32 done = 0;
+ auto func = [&](size_t index) {
+ const auto& [orderNumToPart, doNotNeedToRestore] = tasks[index];
+ TStringStream stream;
+ const bool res = !DoTestCase(erasure, orderNumToPart, doNotNeedToRestore, id, data, &stream);
+ return std::make_tuple(stream.Str(), res);
+ };
+ auto post = [&](const std::tuple<TString, bool>& value) {
+ const auto& [log, res] = value;
+ Cerr << log;
+ badCases += res;
+ Cerr << "done " << ++done << " of " << tasks.size() << Endl;
+ };
+ RunInThreads(tasks.size(), func, post);
+#endif
+
+ UNIT_ASSERT_VALUES_EQUAL(badCases, 0);
+}
+
+}
+
+Y_UNIT_TEST_SUITE(Osiris) {
+
+ Y_UNIT_TEST(mirror3dc) { DoTest(TBlobStorageGroupType::ErasureMirror3dc); }
+ Y_UNIT_TEST(mirror3of4) { DoTest(TBlobStorageGroupType::ErasureMirror3of4); }
+ Y_UNIT_TEST(block42) { DoTest(TBlobStorageGroupType::Erasure4Plus2Block); }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/patch.cpp b/ydb/core/blobstorage/ut_blobstorage/patch.cpp
index b68c05b80ef..f08087ff58c 100644
--- a/ydb/core/blobstorage/ut_blobstorage/patch.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/patch.cpp
@@ -1,15 +1,15 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/ut_blobstorage/lib/common.h>
-
-Y_UNIT_TEST_SUITE(BlobPatching) {
+
+Y_UNIT_TEST_SUITE(BlobPatching) {
void SendPut(const TTestInfo &test, const TLogoBlobID &blobId, const TString &data,
NKikimrProto::EReplyStatus status)
{
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPut>(blobId, data, TInstant::Max());
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPut>(blobId, data, TInstant::Max());
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
@@ -23,10 +23,10 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
{
TArrayHolder<TEvBlobStorage::TEvGet::TQuery> getQueries{new TEvBlobStorage::TEvGet::TQuery[1]};
getQueries[0].Id = blobId;
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvGet>(getQueries, 1, TInstant::Max(),
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvGet>(getQueries, 1, TInstant::Max(),
NKikimrBlobStorage::AsyncRead);
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvGetResult);
@@ -44,10 +44,10 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
for (ui32 idx = 0; idx < diffs.size(); ++idx) {
diffArr[idx] = diffs[idx];
}
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPatch>(test.Info->GroupID, originalBlobId, patchedBlobId,
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvBlobStorage::TEvPatch>(test.Info->GroupID, originalBlobId, patchedBlobId,
mask, std::move(diffArr), diffs.size(), TInstant::Max());
test.Runtime->WrapInActorContext(test.Edge, [&] {
- SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
+ SendToBSProxy(test.Edge, test.Info->GroupID, ev.release());
});
std::unique_ptr<IEventHandle> handle = test.Runtime->WaitForEdgeActorEvent({test.Edge});
UNIT_ASSERT_EQUAL(handle->Type, TEvBlobStorage::EvPatchResult);
@@ -64,48 +64,48 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
return result;
};
- void MakePatchingTest(TString erasure) {
+ void MakePatchingTest(TString erasure) {
TEnvironmentSetup env(true, GetErasureTypeByString(erasure));
TTestInfo test = InitTest(env);
-
- constexpr ui32 size = 100;
+
+ constexpr ui32 size = 100;
TString data(size, 'a');
- TLogoBlobID originalBlobId(1, 1, 0, 0, size, 0);
- std::unique_ptr<IEventHandle> handle;
-
+ TLogoBlobID originalBlobId(1, 1, 0, 0, size, 0);
+ std::unique_ptr<IEventHandle> handle;
+
SendPut(test, originalBlobId, data, NKikimrProto::OK);
SendGet(test, originalBlobId, data, NKikimrProto::OK);
-
- TVector<TEvBlobStorage::TEvPatch::TDiff> diffs1(1);
- diffs1[0].Set("b", 0);
+
+ TVector<TEvBlobStorage::TEvPatch::TDiff> diffs1(1);
+ diffs1[0].Set("b", 0);
TString patchedData1 = ApplyDiffs(data, diffs1);
- TLogoBlobID patchedBlobId1(1, 1, 1, 0, size, 0);
- TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &patchedBlobId1, 0,
+ TLogoBlobID patchedBlobId1(1, 1, 1, 0, size, 0);
+ TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &patchedBlobId1, 0,
test.Info->GroupID, test.Info->GroupID);
SendPatch(test, originalBlobId, patchedBlobId1, 0, diffs1, NKikimrProto::OK);
SendGet(test, patchedBlobId1, patchedData1, NKikimrProto::OK);
-
- TVector<TEvBlobStorage::TEvPatch::TDiff> diffs2(2);
- diffs2[0].Set("b", 0);
- diffs2[1].Set("b", 99);
+
+ TVector<TEvBlobStorage::TEvPatch::TDiff> diffs2(2);
+ diffs2[0].Set("b", 0);
+ diffs2[1].Set("b", 99);
TString patchedData2 = ApplyDiffs(data, diffs2);
- TLogoBlobID patchedBlobId2(1, 1, 2, 0, size, 0);
- TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &patchedBlobId2, 0,
+ TLogoBlobID patchedBlobId2(1, 1, 2, 0, size, 0);
+ TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &patchedBlobId2, 0,
test.Info->GroupID, test.Info->GroupID);
SendPatch(test, originalBlobId, patchedBlobId2, 0, diffs2, NKikimrProto::OK);
SendGet(test, patchedBlobId2, patchedData2, NKikimrProto::OK);
-
- TLogoBlobID patchedBlobId3(1, 1, 3, 0, size, 0);
- TLogoBlobID truePatchedBlobId3(1, 1, 3, 0, size, 0);
- TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &truePatchedBlobId3, TLogoBlobID::MaxCookie,
+
+ TLogoBlobID patchedBlobId3(1, 1, 3, 0, size, 0);
+ TLogoBlobID truePatchedBlobId3(1, 1, 3, 0, size, 0);
+ TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(originalBlobId, &truePatchedBlobId3, TLogoBlobID::MaxCookie,
test.Info->GroupID, test.Info->GroupID);
- UNIT_ASSERT(patchedBlobId3 != truePatchedBlobId3);
+ UNIT_ASSERT(patchedBlobId3 != truePatchedBlobId3);
NKikimrProto::EReplyStatus statusWhenNotMatchingCookie = (erasure == "block-4-2" ? NKikimrProto::ERROR : NKikimrProto::OK);
SendPatch(test, originalBlobId, patchedBlobId3, TLogoBlobID::MaxCookie, diffs2, statusWhenNotMatchingCookie);
SendPatch(test, originalBlobId, truePatchedBlobId3, TLogoBlobID::MaxCookie, diffs2, NKikimrProto::OK);
SendGet(test, truePatchedBlobId3, patchedData2, NKikimrProto::OK);
- }
-
+ }
+
void MakeStressPatchingTest(TString erasure) {
TEnvironmentSetup env(true, GetErasureTypeByString(erasure));
TTestInfo test = InitTest(env);
@@ -136,24 +136,24 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
Y_UNIT_TEST(Mirror3of4) {
- MakePatchingTest("mirror-3of4");
- }
-
+ MakePatchingTest("mirror-3of4");
+ }
+
Y_UNIT_TEST(Mirror3dc) {
MakePatchingTest("mirror-3-dc");
}
Y_UNIT_TEST(Mirror3) {
- MakePatchingTest("mirror-3");
- }
-
+ MakePatchingTest("mirror-3");
+ }
+
Y_UNIT_TEST(Block42) {
- MakePatchingTest("block-4-2");
- }
-
+ MakePatchingTest("block-4-2");
+ }
+
Y_UNIT_TEST(None) {
- MakePatchingTest("none");
- }
+ MakePatchingTest("none");
+ }
Y_UNIT_TEST(StressMirror3of4) {
@@ -175,7 +175,7 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
Y_UNIT_TEST(StressNone) {
MakeStressPatchingTest("none");
}
-
+
Y_UNIT_TEST(DiffsWithIncorectPatchedBlobPartId) {
TEnvironmentSetup env(true);
auto& runtime = env.Runtime;
@@ -185,15 +185,15 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
auto info = env.GetGroupInfo(groups[0]);
constexpr ui32 size = 100;
TLogoBlobID originalBlobId(1, 1, 0, 0, size, 0);
-
+
env.WithQueueId(info->GetVDiskId(0), NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob, [&](TActorId queueId) {
TActorId edge = runtime->AllocateEdgeActor(queueId.NodeId());
constexpr ui32 diffCount = 100;
for (ui32 diffIdx = 0; diffIdx < diffCount; ++diffIdx) {
TLogoBlobID patchedBlobId(1, 1, diffIdx + 1, 0, size, 0);
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> ev = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(
originalBlobId, patchedBlobId, info->GetVDiskId(0), 0, TInstant::Max(), 0);
- runtime->Send(new IEventHandle(queueId, edge, ev.release()), queueId.NodeId());
+ runtime->Send(new IEventHandle(queueId, edge, ev.release()), queueId.NodeId());
}
for (ui32 diffIdx = 0; diffIdx < diffCount; ++diffIdx) {
auto r = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVPatchResult>(edge, false);
@@ -201,5 +201,5 @@ Y_UNIT_TEST_SUITE(BlobPatching) {
}
});
}
-}
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/race.cpp b/ydb/core/blobstorage/ut_blobstorage/race.cpp
index 471b110f13a..b9ea7f026d6 100644
--- a/ydb/core/blobstorage/ut_blobstorage/race.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/race.cpp
@@ -1,238 +1,238 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/ut_blobstorage/lib/activity.h>
-
-std::vector<ui32> GetRestartableNodes(TEnvironmentSetup& env) {
- auto config = env.FetchBaseConfig();
- std::vector<ui32> res;
-
- std::map<std::tuple<ui32, ui32, ui32>, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slots;
- for (const auto& slot : config.GetVSlot()) {
- const auto& id = slot.GetVSlotId();
- slots.emplace(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()), &slot);
- }
-
- for (const ui32 nodeId : env.Runtime->GetNodes()) {
- bool badGroups = false;
- for (const auto& group : config.GetGroup()) {
- ui32 numFullyWorking = 0;
- for (const auto& id : group.GetVSlotId()) {
- auto *slot = slots.at({id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()});
- numFullyWorking += slot->GetReady() && nodeId != id.GetNodeId();
- }
- if (numFullyWorking < 6) {
- badGroups = true;
- break;
- }
- }
- if (!badGroups) {
- res.push_back(nodeId);
- }
- }
-
- return res;
-}
-
-bool IssueReassignQuery(TEnvironmentSetup& env) {
- auto config = env.FetchBaseConfig();
-
- std::map<std::tuple<ui32, ui32, ui32>, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slots;
- for (const auto& slot : config.GetVSlot()) {
- const auto& id = slot.GetVSlotId();
- slots.emplace(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()), &slot);
- }
-
- std::vector<const NKikimrBlobStorage::TBaseConfig::TVSlot*> options;
-
- for (const auto& group : config.GetGroup()) {
- ui32 numFullyWorking = 0;
- std::vector<const NKikimrBlobStorage::TBaseConfig::TVSlot*> all, notready;
- for (const auto& id : group.GetVSlotId()) {
- auto *slot = slots.at(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()));
- all.push_back(slot);
- if (slot->GetReady()) {
- ++numFullyWorking;
- } else {
- notready.push_back(slot);
- }
- }
- if (numFullyWorking > 6) {
- options.insert(options.end(), all.begin(), all.end());
- } else if (numFullyWorking == 6) {
- options.insert(options.end(), notready.begin(), notready.end());
- }
- }
-
- Cerr << "NumOptions# " << options.size() << Endl;
-
- if (options.empty()) {
- return false;
- }
-
- const NKikimrBlobStorage::TBaseConfig::TVSlot *slot = options[RandomNumber(options.size())];
- const auto& id = slot->GetVSlotId();
- const ui32 nodeId = id.GetNodeId();
- const ui32 pdiskId = id.GetPDiskId();
- std::vector<const NKikimrBlobStorage::TBaseConfig::TPDisk*> pdisks;
- std::map<std::tuple<ui32, ui32>, ui32> usageCount;
- for (const auto& pdisk : config.GetPDisk()) {
- if (pdisk.GetNodeId() == nodeId && pdisk.GetPDiskId() != pdiskId) {
- pdisks.push_back(&pdisk);
- usageCount[std::make_tuple(pdisk.GetNodeId(), pdisk.GetPDiskId())] = pdisk.GetNumStaticSlots();
- }
- }
- for (const auto& slot : config.GetVSlot()) {
- const auto& id = slot.GetVSlotId();
- if (id.GetNodeId() == nodeId && id.GetPDiskId() != pdiskId) {
- ++usageCount[std::make_tuple(id.GetNodeId(), id.GetPDiskId())];
- }
- }
- ui32 minUsage = Max<ui32>();
- for (const auto& [key, value] : usageCount) {
- minUsage = Min(minUsage, value);
- }
- auto pred = [&](const NKikimrBlobStorage::TBaseConfig::TPDisk *pdisk) {
- return usageCount[std::make_tuple(pdisk->GetNodeId(), pdisk->GetPDiskId())] > minUsage;
- };
- pdisks.erase(std::remove_if(pdisks.begin(), pdisks.end(), pred), pdisks.end());
- UNIT_ASSERT(!pdisks.empty());
- const NKikimrBlobStorage::TBaseConfig::TPDisk *target = pdisks[RandomNumber(pdisks.size())];
-
- NKikimrBlobStorage::TConfigRequest request;
- request.SetIgnoreGroupFailModelChecks(true);
-
- auto *reassign = request.AddCommand()->MutableReassignGroupDisk();
- reassign->SetGroupId(slot->GetGroupId());
- reassign->SetGroupGeneration(slot->GetGroupGeneration());
- reassign->SetFailRealmIdx(slot->GetFailRealmIdx());
- reassign->SetFailDomainIdx(slot->GetFailDomainIdx());
- reassign->SetVDiskIdx(slot->GetVDiskIdx());
- reassign->MutableTargetPDiskId()->SetNodeId(target->GetNodeId());
- reassign->MutableTargetPDiskId()->SetPDiskId(target->GetPDiskId());
-
- auto makeStatusString = [&] {
- std::map<TVDiskID, TString> status;
- for (const auto& x : config.GetVSlot()) {
- if (x.GetGroupId() == slot->GetGroupId()) {
- status.emplace(TVDiskID(x.GetGroupId(), x.GetGroupGeneration(), x.GetFailRealmIdx(),
- x.GetFailDomainIdx(), x.GetVDiskIdx()), x.GetStatus());
- }
- }
-
- TStringBuilder sb;
- for (const auto& [key, value] : status) {
- if (sb) {
- sb << " ";
- }
- sb << key << ":" << value;
- }
- return sb;
- };
-
- Cerr << "Reassign# " << SingleLineProto(request) << " Status# " << makeStatusString() << Endl;
-
- auto response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- return true;
-}
-
-void RunGroupReconfigurationRaceTest(TBlobStorageGroupType type) {
- const ui32 numStaticNodes = type.BlobSubgroupSize();
- const ui32 numDynamicNodes = RandomNumber(3u);
- const ui32 staticNodeSenderMask = RandomNumber(1u << numStaticNodes);
- const ui32 partitionedNode = RandomNumber(1 + numStaticNodes + numDynamicNodes);
- const bool cache = RandomNumber(2u);
- if (!numDynamicNodes && !staticNodeSenderMask) {
- return;
- }
-
- Cerr << "numStaticNodes# " << numStaticNodes << " numDynamicNodes# " << numDynamicNodes
- << " staticNodeSenderMask# " << staticNodeSenderMask << " partitionedNode# " << partitionedNode
- << " cache# " << (cache ? "true" : "false") << Endl;
-
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = numStaticNodes + numDynamicNodes,
- .Erasure = type,
- .Cache = cache,
- });
- auto& runtime = env.Runtime;
- runtime->SetLogPriority(NActorsServices::TEST, NLog::PRI_DEBUG);
-
- ui32 partCounter = 0;
- runtime->FilterFunction = [&](ui32 /*nodeId*/, IEventHandle& ev) {
- if (ev.Recipient == MakeBlobStorageNodeWardenID(partitionedNode) && partCounter++) {
- // keep the first message
- return false;
- }
- return true;
- };
-
- const ui32 numDrivesPerNode = 4;
- const ui32 numGroups = numDrivesPerNode * numStaticNodes;
- env.CreateBoxAndPool(numDrivesPerNode, numGroups, numStaticNodes);
-
- auto baseConfig = env.FetchBaseConfig();
- std::unordered_set<ui32> storageNodes;
- for (const auto& vslot : baseConfig.GetVSlot()) {
- storageNodes.insert(vslot.GetVSlotId().GetNodeId());
- }
-
- auto groups = env.GetGroups();
-
- std::vector<ui32> senderNodeIds;
- for (const ui32 nodeId : runtime->GetNodes()) {
- if (!storageNodes.count(nodeId) || staticNodeSenderMask & 1 << nodeId - 1) {
- senderNodeIds.push_back(nodeId);
- }
- }
-
- std::unordered_map<ui32, TActorId> nodeIdToEdge;
- auto getEdgeActor = [&](ui32 nodeId) -> TActorId {
- TActorId& edge = nodeIdToEdge[nodeId];
- if (!edge) {
- edge = runtime->AllocateEdgeActor(nodeId);
- }
- return edge;
- };
-
- const ui32 numWriters = groups.size(); // one per each group
- ui64 tabletId = 100500;
-
- std::unordered_set<TActorId, THash<TActorId>> actors;
- for (ui32 i = 0; i < numWriters; ++i) {
- const ui32 nodeId = senderNodeIds[i % senderNodeIds.size()];
- auto *actor = new TActivityActor(tabletId++, groups[i % groups.size()], getEdgeActor(nodeId));
- actors.insert(runtime->Register(actor, nodeId));
- }
-
- ui32 counter = 100;
- while (counter) {
- // restart node at random basis
- if (counter % 30 == 15) {
- auto nodes = GetRestartableNodes(env);
- if (!nodes.empty()) {
- auto it = nodes.begin();
- std::advance(it, RandomNumber(nodes.size()));
- Cerr << "RestartNode# " << *it << Endl;
- env.RestartNode(*it);
- env.Sim(TDuration::Seconds(30));
- --counter;
- continue;
- }
- } else if (IssueReassignQuery(env)) {
- const TDuration delay = TDuration::MilliSeconds(1 + RandomNumber<ui64>(200));
- env.Sim(delay);
- --counter;
- continue;
- }
- env.Sim(TDuration::Seconds(15));
- }
-}
-
-Y_UNIT_TEST_SUITE(GroupReconfigurationRace) {
- Y_UNIT_TEST(Test_block42) {
- for (ui32 i = 0; i < 100; ++i) {
- RunGroupReconfigurationRaceTest(TBlobStorageGroupType::Erasure4Plus2Block);
- }
- }
-}
+
+std::vector<ui32> GetRestartableNodes(TEnvironmentSetup& env) {
+ auto config = env.FetchBaseConfig();
+ std::vector<ui32> res;
+
+ std::map<std::tuple<ui32, ui32, ui32>, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slots;
+ for (const auto& slot : config.GetVSlot()) {
+ const auto& id = slot.GetVSlotId();
+ slots.emplace(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()), &slot);
+ }
+
+ for (const ui32 nodeId : env.Runtime->GetNodes()) {
+ bool badGroups = false;
+ for (const auto& group : config.GetGroup()) {
+ ui32 numFullyWorking = 0;
+ for (const auto& id : group.GetVSlotId()) {
+ auto *slot = slots.at({id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()});
+ numFullyWorking += slot->GetReady() && nodeId != id.GetNodeId();
+ }
+ if (numFullyWorking < 6) {
+ badGroups = true;
+ break;
+ }
+ }
+ if (!badGroups) {
+ res.push_back(nodeId);
+ }
+ }
+
+ return res;
+}
+
+bool IssueReassignQuery(TEnvironmentSetup& env) {
+ auto config = env.FetchBaseConfig();
+
+ std::map<std::tuple<ui32, ui32, ui32>, const NKikimrBlobStorage::TBaseConfig::TVSlot*> slots;
+ for (const auto& slot : config.GetVSlot()) {
+ const auto& id = slot.GetVSlotId();
+ slots.emplace(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()), &slot);
+ }
+
+ std::vector<const NKikimrBlobStorage::TBaseConfig::TVSlot*> options;
+
+ for (const auto& group : config.GetGroup()) {
+ ui32 numFullyWorking = 0;
+ std::vector<const NKikimrBlobStorage::TBaseConfig::TVSlot*> all, notready;
+ for (const auto& id : group.GetVSlotId()) {
+ auto *slot = slots.at(std::make_tuple(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId()));
+ all.push_back(slot);
+ if (slot->GetReady()) {
+ ++numFullyWorking;
+ } else {
+ notready.push_back(slot);
+ }
+ }
+ if (numFullyWorking > 6) {
+ options.insert(options.end(), all.begin(), all.end());
+ } else if (numFullyWorking == 6) {
+ options.insert(options.end(), notready.begin(), notready.end());
+ }
+ }
+
+ Cerr << "NumOptions# " << options.size() << Endl;
+
+ if (options.empty()) {
+ return false;
+ }
+
+ const NKikimrBlobStorage::TBaseConfig::TVSlot *slot = options[RandomNumber(options.size())];
+ const auto& id = slot->GetVSlotId();
+ const ui32 nodeId = id.GetNodeId();
+ const ui32 pdiskId = id.GetPDiskId();
+ std::vector<const NKikimrBlobStorage::TBaseConfig::TPDisk*> pdisks;
+ std::map<std::tuple<ui32, ui32>, ui32> usageCount;
+ for (const auto& pdisk : config.GetPDisk()) {
+ if (pdisk.GetNodeId() == nodeId && pdisk.GetPDiskId() != pdiskId) {
+ pdisks.push_back(&pdisk);
+ usageCount[std::make_tuple(pdisk.GetNodeId(), pdisk.GetPDiskId())] = pdisk.GetNumStaticSlots();
+ }
+ }
+ for (const auto& slot : config.GetVSlot()) {
+ const auto& id = slot.GetVSlotId();
+ if (id.GetNodeId() == nodeId && id.GetPDiskId() != pdiskId) {
+ ++usageCount[std::make_tuple(id.GetNodeId(), id.GetPDiskId())];
+ }
+ }
+ ui32 minUsage = Max<ui32>();
+ for (const auto& [key, value] : usageCount) {
+ minUsage = Min(minUsage, value);
+ }
+ auto pred = [&](const NKikimrBlobStorage::TBaseConfig::TPDisk *pdisk) {
+ return usageCount[std::make_tuple(pdisk->GetNodeId(), pdisk->GetPDiskId())] > minUsage;
+ };
+ pdisks.erase(std::remove_if(pdisks.begin(), pdisks.end(), pred), pdisks.end());
+ UNIT_ASSERT(!pdisks.empty());
+ const NKikimrBlobStorage::TBaseConfig::TPDisk *target = pdisks[RandomNumber(pdisks.size())];
+
+ NKikimrBlobStorage::TConfigRequest request;
+ request.SetIgnoreGroupFailModelChecks(true);
+
+ auto *reassign = request.AddCommand()->MutableReassignGroupDisk();
+ reassign->SetGroupId(slot->GetGroupId());
+ reassign->SetGroupGeneration(slot->GetGroupGeneration());
+ reassign->SetFailRealmIdx(slot->GetFailRealmIdx());
+ reassign->SetFailDomainIdx(slot->GetFailDomainIdx());
+ reassign->SetVDiskIdx(slot->GetVDiskIdx());
+ reassign->MutableTargetPDiskId()->SetNodeId(target->GetNodeId());
+ reassign->MutableTargetPDiskId()->SetPDiskId(target->GetPDiskId());
+
+ auto makeStatusString = [&] {
+ std::map<TVDiskID, TString> status;
+ for (const auto& x : config.GetVSlot()) {
+ if (x.GetGroupId() == slot->GetGroupId()) {
+ status.emplace(TVDiskID(x.GetGroupId(), x.GetGroupGeneration(), x.GetFailRealmIdx(),
+ x.GetFailDomainIdx(), x.GetVDiskIdx()), x.GetStatus());
+ }
+ }
+
+ TStringBuilder sb;
+ for (const auto& [key, value] : status) {
+ if (sb) {
+ sb << " ";
+ }
+ sb << key << ":" << value;
+ }
+ return sb;
+ };
+
+ Cerr << "Reassign# " << SingleLineProto(request) << " Status# " << makeStatusString() << Endl;
+
+ auto response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ return true;
+}
+
+void RunGroupReconfigurationRaceTest(TBlobStorageGroupType type) {
+ const ui32 numStaticNodes = type.BlobSubgroupSize();
+ const ui32 numDynamicNodes = RandomNumber(3u);
+ const ui32 staticNodeSenderMask = RandomNumber(1u << numStaticNodes);
+ const ui32 partitionedNode = RandomNumber(1 + numStaticNodes + numDynamicNodes);
+ const bool cache = RandomNumber(2u);
+ if (!numDynamicNodes && !staticNodeSenderMask) {
+ return;
+ }
+
+ Cerr << "numStaticNodes# " << numStaticNodes << " numDynamicNodes# " << numDynamicNodes
+ << " staticNodeSenderMask# " << staticNodeSenderMask << " partitionedNode# " << partitionedNode
+ << " cache# " << (cache ? "true" : "false") << Endl;
+
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = numStaticNodes + numDynamicNodes,
+ .Erasure = type,
+ .Cache = cache,
+ });
+ auto& runtime = env.Runtime;
+ runtime->SetLogPriority(NActorsServices::TEST, NLog::PRI_DEBUG);
+
+ ui32 partCounter = 0;
+ runtime->FilterFunction = [&](ui32 /*nodeId*/, IEventHandle& ev) {
+ if (ev.Recipient == MakeBlobStorageNodeWardenID(partitionedNode) && partCounter++) {
+ // keep the first message
+ return false;
+ }
+ return true;
+ };
+
+ const ui32 numDrivesPerNode = 4;
+ const ui32 numGroups = numDrivesPerNode * numStaticNodes;
+ env.CreateBoxAndPool(numDrivesPerNode, numGroups, numStaticNodes);
+
+ auto baseConfig = env.FetchBaseConfig();
+ std::unordered_set<ui32> storageNodes;
+ for (const auto& vslot : baseConfig.GetVSlot()) {
+ storageNodes.insert(vslot.GetVSlotId().GetNodeId());
+ }
+
+ auto groups = env.GetGroups();
+
+ std::vector<ui32> senderNodeIds;
+ for (const ui32 nodeId : runtime->GetNodes()) {
+ if (!storageNodes.count(nodeId) || staticNodeSenderMask & 1 << nodeId - 1) {
+ senderNodeIds.push_back(nodeId);
+ }
+ }
+
+ std::unordered_map<ui32, TActorId> nodeIdToEdge;
+ auto getEdgeActor = [&](ui32 nodeId) -> TActorId {
+ TActorId& edge = nodeIdToEdge[nodeId];
+ if (!edge) {
+ edge = runtime->AllocateEdgeActor(nodeId);
+ }
+ return edge;
+ };
+
+ const ui32 numWriters = groups.size(); // one per each group
+ ui64 tabletId = 100500;
+
+ std::unordered_set<TActorId, THash<TActorId>> actors;
+ for (ui32 i = 0; i < numWriters; ++i) {
+ const ui32 nodeId = senderNodeIds[i % senderNodeIds.size()];
+ auto *actor = new TActivityActor(tabletId++, groups[i % groups.size()], getEdgeActor(nodeId));
+ actors.insert(runtime->Register(actor, nodeId));
+ }
+
+ ui32 counter = 100;
+ while (counter) {
+ // restart node at random basis
+ if (counter % 30 == 15) {
+ auto nodes = GetRestartableNodes(env);
+ if (!nodes.empty()) {
+ auto it = nodes.begin();
+ std::advance(it, RandomNumber(nodes.size()));
+ Cerr << "RestartNode# " << *it << Endl;
+ env.RestartNode(*it);
+ env.Sim(TDuration::Seconds(30));
+ --counter;
+ continue;
+ }
+ } else if (IssueReassignQuery(env)) {
+ const TDuration delay = TDuration::MilliSeconds(1 + RandomNumber<ui64>(200));
+ env.Sim(delay);
+ --counter;
+ continue;
+ }
+ env.Sim(TDuration::Seconds(15));
+ }
+}
+
+Y_UNIT_TEST_SUITE(GroupReconfigurationRace) {
+ Y_UNIT_TEST(Test_block42) {
+ for (ui32 i = 0; i < 100; ++i) {
+ RunGroupReconfigurationRaceTest(TBlobStorageGroupType::Erasure4Plus2Block);
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/replication.cpp b/ydb/core/blobstorage/ut_blobstorage/replication.cpp
index 9542900d4b3..ec2bee00b0a 100644
--- a/ydb/core/blobstorage/ut_blobstorage/replication.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/replication.cpp
@@ -1,320 +1,320 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-#include <util/system/info.h>
-
-#define SINGLE_THREAD 1
-
-enum class EState {
- OK,
- FORMAT,
- OFFLINE,
-};
-
-TString DoTestCase(TBlobStorageGroupType::EErasureSpecies erasure, const std::vector<EState>& states) {
- TStringStream s;
- IOutputStream& log = SINGLE_THREAD ? Cerr : s;
-
- log << "*** SETUP: " << TBlobStorageGroupType::ErasureSpeciesName(erasure);
- for (EState state : states) {
- log << " ";
- switch (state) {
- case EState::OK: log << "OK"; break;
- case EState::FORMAT: log << "FORMAT"; break;
- case EState::OFFLINE: log << "OFFLINE"; break;
- }
- }
- log << Endl;
-
- std::function<bool(ui32, IEventHandle&)> filterFunction;
- auto prepareRuntime = [&](TTestActorSystem& runtime) {
- runtime.FilterFunction = filterFunction;
- runtime.LogStream = &log;
- };
-
- ui32 cleanNodeId;
- for (cleanNodeId = 1; cleanNodeId <= states.size(); ++cleanNodeId) {
- if (states[cleanNodeId - 1] != EState::OFFLINE) {
- break;
- }
- }
- TEnvironmentSetup env(TEnvironmentSetup::TSettings{
- .NodeCount = (ui32)states.size(),
- .Erasure = erasure,
- .PrepareRuntime = prepareRuntime,
- .ControllerNodeId = cleanNodeId,
- });
- env.CreateBoxAndPool(1, 1);
- env.Sim(TDuration::Minutes(1));
-
- auto groups = env.GetGroups();
- Y_VERIFY(groups.size() == 1);
-
- auto groupInfo = env.GetGroupInfo(groups.front());
- std::vector<TActorId> queues;
- for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
- queues.push_back(env.CreateQueueActor(groupInfo->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 0));
- }
-
- TString data = "hello";
- TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
-
- {
- TActorId edge = env.Runtime->AllocateEdgeActor(1);
- env.Runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvPut(id, data, TInstant::Max(),
- NKikimrBlobStorage::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge);
- Y_VERIFY(res->Get()->Status == NKikimrProto::OK);
- }
-
- ui32 numDisksWithBlob = 0;
- ui32 numDisksNotOk = 0;
-
- std::set<TActorId> edges;
- for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
- auto ev = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(groupInfo->GetVDiskId(i), TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
- groupInfo->GetActorId(i).NodeId());
- ev->AddExtremeQuery(id, 0, 0);
- const TActorId& queueId = queues[i];
- const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), queueId.NodeId());
- const bool inserted = edges.insert(edge).second;
- Y_VERIFY(inserted);
- }
- while (!edges.empty()) {
- auto res = env.Runtime->WaitForEdgeActorEvent(edges);
- const size_t numErased = edges.erase(res->Recipient);
- Y_VERIFY(numErased);
- env.Runtime->DestroyActor(res->Recipient);
- auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVGetResult>();
- Y_VERIFY(msg);
- const auto& record = msg->Record;
- Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
- Y_VERIFY(record.ResultSize() == 1);
- const auto& result = record.GetResult(0);
- const ui32 nodeId = record.GetCookie();
- Y_VERIFY(nodeId);
- Cerr << nodeId << " -> " << NKikimrProto::EReplyStatus_Name(result.GetStatus()) << Endl;
- if (result.GetStatus() == NKikimrProto::OK) {
- ++numDisksWithBlob;
- if (states[nodeId - 1] != EState::OK) {
- ++numDisksNotOk;
- }
- } else {
- Y_VERIFY(result.GetStatus() == NKikimrProto::NODATA);
- if (states[nodeId - 1] == EState::FORMAT) {
- log << "early abort -- formatted disk did not contain any parts" << Endl;
- return s.Str();
- }
- }
- }
-
- log << "numDisksWithBlob# " << numDisksWithBlob << " numDisksNotOk# " << numDisksNotOk << Endl;
-
- {
- TActorId edge = env.Runtime->AllocateEdgeActor(1);
- env.Runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), 1, 0, id.Channel(),
- true, id.Generation(), Max<ui32>(), new TVector<TLogoBlobID>(1, id), nullptr, TInstant::Max(), false));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge);
- Y_VERIFY(res->Get()->Status == NKikimrProto::OK);
- }
-
- auto checkBlob = [&] {
- TActorId edge = env.Runtime->AllocateEdgeActor(cleanNodeId);
- env.Runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(edge);
- auto *msg = res->Get();
- Y_VERIFY(msg->ResponseSz == 1);
- return msg->Responses[0].Status;
- };
-
- Y_VERIFY(checkBlob() == NKikimrProto::OK);
-
- // wait some time for sync data to spread
- TInstant syncStartWall = Now();
- TInstant syncStartClock = env.Runtime->GetClock();
- for (;;) {
- std::set<ui32> ingress;
- ui32 num = 0;
- std::set<TActorId> edges;
- for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
- const TActorId queueId = queues[i];
- auto query = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(groupInfo->GetVDiskId(i), TKeyBarrier::First(),
- TKeyBarrier::Inf(), nullptr, true);
- const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- env.Runtime->Send(new IEventHandle(queueId, edge, query.release()), edge.NodeId());
- const bool inserted = edges.insert(edge).second;
- Y_VERIFY(inserted);
- }
- while (!edges.empty()) {
- auto res = env.Runtime->WaitForEdgeActorEvent(edges);
- const size_t numErased = edges.erase(res->Recipient);
- Y_VERIFY(numErased);
- env.Runtime->DestroyActor(res->Recipient);
- auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVGetBarrierResult>();
- Y_VERIFY(msg);
-
- //log << "Result# " << msg->ToString() << Endl;
- const auto& record = msg->Record;
- Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
- if (record.KeysSize() == 0 && record.ValuesSize() == 0) {
- continue;
- }
- Y_VERIFY(record.KeysSize() == 1);
- Y_VERIFY(record.ValuesSize() == 1);
- auto& key = record.GetKeys(0);
- Y_VERIFY(key.GetTabletId() == id.TabletID());
- Y_VERIFY(key.GetChannel() == id.Channel());
- auto& value = record.GetValues(0);
- Y_VERIFY(value.GetCollectGen() == id.Generation());
- Y_VERIFY(value.GetCollectStep() == Max<ui32>());
- ingress.insert(value.GetIngress());
- ++num;
- }
- if (num == groupInfo->GetTotalVDisksNum() && ingress.size() == 1 && *ingress.begin()) {
- break;
- }
- env.Sim(TDuration::Seconds(5));
- }
- log << "syncTime wall# " << (Now() - syncStartWall) << " actor# " << (env.Runtime->GetClock() - syncStartClock) << Endl;
-
- env.Cleanup();
-
- TBlobStorageGroupInfo::TGroupVDisks err(&groupInfo->GetTopology());
- for (auto& [key, state] : env.PDiskMockStates) {
- switch (states[key.first - 1]) {
- case EState::FORMAT:
- log << "formatted pdisk " << key.first << ":" << key.second << Endl;
- state.Reset();
- [[fallthrough]];
- case EState::OFFLINE:
- for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
- if (groupInfo->GetActorId(i).NodeId() == key.first) {
- err |= {&groupInfo->GetTopology(), groupInfo->GetVDiskId(i)};
- }
- }
- break;
-
- case EState::OK:
- break;
- }
- }
-
- filterFunction = [&](ui32 nodeId, IEventHandle& ev) {
- if (ev.Type == TEvBlobStorage::EvVGet && states[ev.Recipient.NodeId() - 1] == EState::OFFLINE) {
- env.Runtime->Send(ev.ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected).Release(), nodeId);
- return false;
- }
- return true;
- };
-
- env.Initialize();
- env.Sim(TDuration::Seconds(150));
-
- const NKikimrProto::EReplyStatus status = checkBlob();
- log << "checkBlob status# " << NKikimrProto::EReplyStatus_Name(status) << Endl;
- if (groupInfo->GetQuorumChecker().CheckFailModelForGroup(err)) {
- Y_VERIFY(status == NKikimrProto::OK);
- } else {
- Y_VERIFY(status == NKikimrProto::ERROR || status == NKikimrProto::OK);
- }
-
- return s.Str();
-}
-
-void DoTest(TBlobStorageGroupType::EErasureSpecies erasure) {
- TMutex mutex, logMutex;
- std::vector<std::pair<TBlobStorageGroupType::EErasureSpecies, std::vector<EState>>> queue;
- size_t queueIndex = 0;
- std::deque<TString> logQueue;
- ui32 testCasesProcessed = 0, totalCases = 0;
-
- auto threadFunc = [&] {
- for (;;) {
- size_t index;
- with_lock (mutex) {
- if (queueIndex == queue.size()) {
- break;
- }
- index = queueIndex++;
- }
-
- // run test case
- TString log = DoTestCase(queue[index].first, queue[index].second);
-
- with_lock (logMutex) {
- ++testCasesProcessed;
- logQueue.push_back(TStringBuilder() << testCasesProcessed << "/" << totalCases << " test case(s) processed so far" << Endl << Endl << log << Endl);
- }
- }
- };
-
- const TBlobStorageGroupType type(erasure);
-// for (ui32 numFmt = 1; numFmt < type.BlobSubgroupSize(); ++numFmt) { // number of disks to format
-// for (ui32 numBad = 0; numBad + numFmt < type.BlobSubgroupSize(); ++numBad) { // number of partitioned nodes
- for (ui32 numFmt : {1}) {
- for (ui32 numBad : {2}) {
- std::vector<EState> states;
- for (ui32 i = 0; i < numFmt; ++i) {
- states.push_back(EState::FORMAT);
- }
- for (ui32 i = 0; i < numBad; ++i) {
- states.push_back(EState::OFFLINE);
- }
- while (states.size() < type.BlobSubgroupSize()) {
- states.push_back(EState::OK);
- }
- Y_VERIFY(states.size() == type.BlobSubgroupSize());
- std::sort(states.begin(), states.end());
- do {
-#if SINGLE_THREAD
- DoTestCase(erasure, states);
-#else
- queue.emplace_back(erasure, states);
-#endif
- ++totalCases;
- } while (std::next_permutation(states.begin(), states.end()));
- }
- }
-
- std::list<TThread> pool;
- for (ui32 i = 0; i < NSystemInfo::NumberOfCpus(); ++i) {
- pool.emplace_back(threadFunc);
- }
- for (auto& thread : pool) {
- thread.Start();
- }
- for (ui32 n = totalCases; !SINGLE_THREAD && n; ) {
- std::deque<TString> items;
- with_lock (logMutex) {
- items.swap(logQueue);
- }
- if (logQueue.empty()) {
- Sleep(TDuration::MilliSeconds(100));
- }
- for (; !items.empty(); items.pop_front()) {
- Cerr << items.front();
- --n;
- }
- }
- for (auto& thread : pool) {
- thread.Join();
- }
-}
-
-Y_UNIT_TEST_SUITE(Replication) {
-// Y_UNIT_TEST(Phantoms_mirror3dc) { DoTest(TBlobStorageGroupType::ErasureMirror3dc); }
-// Y_UNIT_TEST(Phantoms_block4_2) { DoTest(TBlobStorageGroupType::Erasure4Plus2Block); }
-// Y_UNIT_TEST(Phantoms_mirror3of4) { DoTest(TBlobStorageGroupType::ErasureMirror3of4); }
-
- using E = EState;
- Y_UNIT_TEST(Phantoms_mirror3dc_special) {
- DoTestCase(TBlobStorageGroupType::ErasureMirror3dc, {E::OK, E::FORMAT, E::OK, E::OK, E::OFFLINE, E::OK, E::OK, E::OFFLINE, E::OK});
- }
-}
+#include <util/system/info.h>
+
+#define SINGLE_THREAD 1
+
+enum class EState {
+ OK,
+ FORMAT,
+ OFFLINE,
+};
+
+TString DoTestCase(TBlobStorageGroupType::EErasureSpecies erasure, const std::vector<EState>& states) {
+ TStringStream s;
+ IOutputStream& log = SINGLE_THREAD ? Cerr : s;
+
+ log << "*** SETUP: " << TBlobStorageGroupType::ErasureSpeciesName(erasure);
+ for (EState state : states) {
+ log << " ";
+ switch (state) {
+ case EState::OK: log << "OK"; break;
+ case EState::FORMAT: log << "FORMAT"; break;
+ case EState::OFFLINE: log << "OFFLINE"; break;
+ }
+ }
+ log << Endl;
+
+ std::function<bool(ui32, IEventHandle&)> filterFunction;
+ auto prepareRuntime = [&](TTestActorSystem& runtime) {
+ runtime.FilterFunction = filterFunction;
+ runtime.LogStream = &log;
+ };
+
+ ui32 cleanNodeId;
+ for (cleanNodeId = 1; cleanNodeId <= states.size(); ++cleanNodeId) {
+ if (states[cleanNodeId - 1] != EState::OFFLINE) {
+ break;
+ }
+ }
+ TEnvironmentSetup env(TEnvironmentSetup::TSettings{
+ .NodeCount = (ui32)states.size(),
+ .Erasure = erasure,
+ .PrepareRuntime = prepareRuntime,
+ .ControllerNodeId = cleanNodeId,
+ });
+ env.CreateBoxAndPool(1, 1);
+ env.Sim(TDuration::Minutes(1));
+
+ auto groups = env.GetGroups();
+ Y_VERIFY(groups.size() == 1);
+
+ auto groupInfo = env.GetGroupInfo(groups.front());
+ std::vector<TActorId> queues;
+ for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
+ queues.push_back(env.CreateQueueActor(groupInfo->GetVDiskId(i), NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 0));
+ }
+
+ TString data = "hello";
+ TLogoBlobID id(1, 1, 1, 0, data.size(), 0);
+
+ {
+ TActorId edge = env.Runtime->AllocateEdgeActor(1);
+ env.Runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvPut(id, data, TInstant::Max(),
+ NKikimrBlobStorage::TabletLog, TEvBlobStorage::TEvPut::TacticMaxThroughput));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge);
+ Y_VERIFY(res->Get()->Status == NKikimrProto::OK);
+ }
+
+ ui32 numDisksWithBlob = 0;
+ ui32 numDisksNotOk = 0;
+
+ std::set<TActorId> edges;
+ for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
+ auto ev = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(groupInfo->GetVDiskId(i), TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None,
+ groupInfo->GetActorId(i).NodeId());
+ ev->AddExtremeQuery(id, 0, 0);
+ const TActorId& queueId = queues[i];
+ const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), queueId.NodeId());
+ const bool inserted = edges.insert(edge).second;
+ Y_VERIFY(inserted);
+ }
+ while (!edges.empty()) {
+ auto res = env.Runtime->WaitForEdgeActorEvent(edges);
+ const size_t numErased = edges.erase(res->Recipient);
+ Y_VERIFY(numErased);
+ env.Runtime->DestroyActor(res->Recipient);
+ auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVGetResult>();
+ Y_VERIFY(msg);
+ const auto& record = msg->Record;
+ Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
+ Y_VERIFY(record.ResultSize() == 1);
+ const auto& result = record.GetResult(0);
+ const ui32 nodeId = record.GetCookie();
+ Y_VERIFY(nodeId);
+ Cerr << nodeId << " -> " << NKikimrProto::EReplyStatus_Name(result.GetStatus()) << Endl;
+ if (result.GetStatus() == NKikimrProto::OK) {
+ ++numDisksWithBlob;
+ if (states[nodeId - 1] != EState::OK) {
+ ++numDisksNotOk;
+ }
+ } else {
+ Y_VERIFY(result.GetStatus() == NKikimrProto::NODATA);
+ if (states[nodeId - 1] == EState::FORMAT) {
+ log << "early abort -- formatted disk did not contain any parts" << Endl;
+ return s.Str();
+ }
+ }
+ }
+
+ log << "numDisksWithBlob# " << numDisksWithBlob << " numDisksNotOk# " << numDisksNotOk << Endl;
+
+ {
+ TActorId edge = env.Runtime->AllocateEdgeActor(1);
+ env.Runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), 1, 0, id.Channel(),
+ true, id.Generation(), Max<ui32>(), new TVector<TLogoBlobID>(1, id), nullptr, TInstant::Max(), false));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge);
+ Y_VERIFY(res->Get()->Status == NKikimrProto::OK);
+ }
+
+ auto checkBlob = [&] {
+ TActorId edge = env.Runtime->AllocateEdgeActor(cleanNodeId);
+ env.Runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, groups.front(), new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(edge);
+ auto *msg = res->Get();
+ Y_VERIFY(msg->ResponseSz == 1);
+ return msg->Responses[0].Status;
+ };
+
+ Y_VERIFY(checkBlob() == NKikimrProto::OK);
+
+ // wait some time for sync data to spread
+ TInstant syncStartWall = Now();
+ TInstant syncStartClock = env.Runtime->GetClock();
+ for (;;) {
+ std::set<ui32> ingress;
+ ui32 num = 0;
+ std::set<TActorId> edges;
+ for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
+ const TActorId queueId = queues[i];
+ auto query = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(groupInfo->GetVDiskId(i), TKeyBarrier::First(),
+ TKeyBarrier::Inf(), nullptr, true);
+ const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ env.Runtime->Send(new IEventHandle(queueId, edge, query.release()), edge.NodeId());
+ const bool inserted = edges.insert(edge).second;
+ Y_VERIFY(inserted);
+ }
+ while (!edges.empty()) {
+ auto res = env.Runtime->WaitForEdgeActorEvent(edges);
+ const size_t numErased = edges.erase(res->Recipient);
+ Y_VERIFY(numErased);
+ env.Runtime->DestroyActor(res->Recipient);
+ auto *msg = res->CastAsLocal<TEvBlobStorage::TEvVGetBarrierResult>();
+ Y_VERIFY(msg);
+
+ //log << "Result# " << msg->ToString() << Endl;
+ const auto& record = msg->Record;
+ Y_VERIFY(record.GetStatus() == NKikimrProto::OK);
+ if (record.KeysSize() == 0 && record.ValuesSize() == 0) {
+ continue;
+ }
+ Y_VERIFY(record.KeysSize() == 1);
+ Y_VERIFY(record.ValuesSize() == 1);
+ auto& key = record.GetKeys(0);
+ Y_VERIFY(key.GetTabletId() == id.TabletID());
+ Y_VERIFY(key.GetChannel() == id.Channel());
+ auto& value = record.GetValues(0);
+ Y_VERIFY(value.GetCollectGen() == id.Generation());
+ Y_VERIFY(value.GetCollectStep() == Max<ui32>());
+ ingress.insert(value.GetIngress());
+ ++num;
+ }
+ if (num == groupInfo->GetTotalVDisksNum() && ingress.size() == 1 && *ingress.begin()) {
+ break;
+ }
+ env.Sim(TDuration::Seconds(5));
+ }
+ log << "syncTime wall# " << (Now() - syncStartWall) << " actor# " << (env.Runtime->GetClock() - syncStartClock) << Endl;
+
+ env.Cleanup();
+
+ TBlobStorageGroupInfo::TGroupVDisks err(&groupInfo->GetTopology());
+ for (auto& [key, state] : env.PDiskMockStates) {
+ switch (states[key.first - 1]) {
+ case EState::FORMAT:
+ log << "formatted pdisk " << key.first << ":" << key.second << Endl;
+ state.Reset();
+ [[fallthrough]];
+ case EState::OFFLINE:
+ for (ui32 i = 0; i < groupInfo->GetTotalVDisksNum(); ++i) {
+ if (groupInfo->GetActorId(i).NodeId() == key.first) {
+ err |= {&groupInfo->GetTopology(), groupInfo->GetVDiskId(i)};
+ }
+ }
+ break;
+
+ case EState::OK:
+ break;
+ }
+ }
+
+ filterFunction = [&](ui32 nodeId, IEventHandle& ev) {
+ if (ev.Type == TEvBlobStorage::EvVGet && states[ev.Recipient.NodeId() - 1] == EState::OFFLINE) {
+ env.Runtime->Send(ev.ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected).Release(), nodeId);
+ return false;
+ }
+ return true;
+ };
+
+ env.Initialize();
+ env.Sim(TDuration::Seconds(150));
+
+ const NKikimrProto::EReplyStatus status = checkBlob();
+ log << "checkBlob status# " << NKikimrProto::EReplyStatus_Name(status) << Endl;
+ if (groupInfo->GetQuorumChecker().CheckFailModelForGroup(err)) {
+ Y_VERIFY(status == NKikimrProto::OK);
+ } else {
+ Y_VERIFY(status == NKikimrProto::ERROR || status == NKikimrProto::OK);
+ }
+
+ return s.Str();
+}
+
+void DoTest(TBlobStorageGroupType::EErasureSpecies erasure) {
+ TMutex mutex, logMutex;
+ std::vector<std::pair<TBlobStorageGroupType::EErasureSpecies, std::vector<EState>>> queue;
+ size_t queueIndex = 0;
+ std::deque<TString> logQueue;
+ ui32 testCasesProcessed = 0, totalCases = 0;
+
+ auto threadFunc = [&] {
+ for (;;) {
+ size_t index;
+ with_lock (mutex) {
+ if (queueIndex == queue.size()) {
+ break;
+ }
+ index = queueIndex++;
+ }
+
+ // run test case
+ TString log = DoTestCase(queue[index].first, queue[index].second);
+
+ with_lock (logMutex) {
+ ++testCasesProcessed;
+ logQueue.push_back(TStringBuilder() << testCasesProcessed << "/" << totalCases << " test case(s) processed so far" << Endl << Endl << log << Endl);
+ }
+ }
+ };
+
+ const TBlobStorageGroupType type(erasure);
+// for (ui32 numFmt = 1; numFmt < type.BlobSubgroupSize(); ++numFmt) { // number of disks to format
+// for (ui32 numBad = 0; numBad + numFmt < type.BlobSubgroupSize(); ++numBad) { // number of partitioned nodes
+ for (ui32 numFmt : {1}) {
+ for (ui32 numBad : {2}) {
+ std::vector<EState> states;
+ for (ui32 i = 0; i < numFmt; ++i) {
+ states.push_back(EState::FORMAT);
+ }
+ for (ui32 i = 0; i < numBad; ++i) {
+ states.push_back(EState::OFFLINE);
+ }
+ while (states.size() < type.BlobSubgroupSize()) {
+ states.push_back(EState::OK);
+ }
+ Y_VERIFY(states.size() == type.BlobSubgroupSize());
+ std::sort(states.begin(), states.end());
+ do {
+#if SINGLE_THREAD
+ DoTestCase(erasure, states);
+#else
+ queue.emplace_back(erasure, states);
+#endif
+ ++totalCases;
+ } while (std::next_permutation(states.begin(), states.end()));
+ }
+ }
+
+ std::list<TThread> pool;
+ for (ui32 i = 0; i < NSystemInfo::NumberOfCpus(); ++i) {
+ pool.emplace_back(threadFunc);
+ }
+ for (auto& thread : pool) {
+ thread.Start();
+ }
+ for (ui32 n = totalCases; !SINGLE_THREAD && n; ) {
+ std::deque<TString> items;
+ with_lock (logMutex) {
+ items.swap(logQueue);
+ }
+ if (logQueue.empty()) {
+ Sleep(TDuration::MilliSeconds(100));
+ }
+ for (; !items.empty(); items.pop_front()) {
+ Cerr << items.front();
+ --n;
+ }
+ }
+ for (auto& thread : pool) {
+ thread.Join();
+ }
+}
+
+Y_UNIT_TEST_SUITE(Replication) {
+// Y_UNIT_TEST(Phantoms_mirror3dc) { DoTest(TBlobStorageGroupType::ErasureMirror3dc); }
+// Y_UNIT_TEST(Phantoms_block4_2) { DoTest(TBlobStorageGroupType::Erasure4Plus2Block); }
+// Y_UNIT_TEST(Phantoms_mirror3of4) { DoTest(TBlobStorageGroupType::ErasureMirror3of4); }
+
+ using E = EState;
+ Y_UNIT_TEST(Phantoms_mirror3dc_special) {
+ DoTestCase(TBlobStorageGroupType::ErasureMirror3dc, {E::OK, E::FORMAT, E::OK, E::OK, E::OFFLINE, E::OK, E::OK, E::OFFLINE, E::OK});
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/scrub.cpp b/ydb/core/blobstorage/ut_blobstorage/scrub.cpp
index 8a355a5bd34..b43705e0357 100644
--- a/ydb/core/blobstorage/ut_blobstorage/scrub.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/scrub.cpp
@@ -1,402 +1,402 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/vdisk/scrub/scrub_actor.h>
-#include <library/cpp/digest/md5/md5.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-Y_UNIT_TEST_SUITE(BlobScrubbing) {
-
- ui32 QueueClientId = 0;
-
- using TLayout = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
-
- void Populate(TEnvironmentSetup& env, TVDiskID vdiskId, TActorId vdiskActorId, std::map<TLogoBlobID, TString>& data,
- std::unique_ptr<TLayout>& layout) {
- const TActorId& sender = env.Runtime->AllocateEdgeActor(vdiskActorId.NodeId());
-
- std::vector<TString> blobs;
- for (ui32 i = 0; i < 100; ++i) {
- const ui32 size = RandomNumber(10u) == 0 ? RandomNumber<ui32>(3 << 20) + 1048576 : (RandomNumber<ui32>(65536) + 1); // 1 byte - 4 MB
- TString data = TString::Uninitialized(size);
- memset(data.Detach(), RandomNumber<ui8>(), size);
- blobs.push_back(data);
- }
-
- for (ui32 i = 1;; ++i) {
- const TString& data = blobs[RandomNumber(blobs.size())];
- TLogoBlobID id(1, 1, i, 0, data.size(), 0);
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, data, TInstant::Max());
- env.Runtime->WrapInActorContext(sender, [&] {
- SendToBSProxy(sender, vdiskId.GroupID, ev.release());
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(sender, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
- Cerr << "res# " << res->Get()->ToString() << Endl;
-
- if (i % 500 == 0) {
- env.CompactVDisk(vdiskActorId, true /*freshOnly*/);
-
- bool done = false;
- for (;;) {
- env.Runtime->Send(new IEventHandle(vdiskActorId, sender, new TEvBlobStorage::TEvCaptureVDiskLayout),
- sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TLayout>(sender, false);
- layout.reset(res->Release().Release());
- ui32 num0 = 0, num1_16 = 0, num17 = 0, num18 = 0;
- for (const auto& item : layout->Layout) {
- if (item.Database == TLayout::EDatabase::LogoBlobs && item.RecordType == TLayout::ERecordType::IndexRecord) {
- if (item.Level == 0) {
- ++num0;
- } else if (item.Level < 17) {
- ++num1_16;
- } else if (item.Level == 17) {
- ++num17;
- } else if (item.Level == 18) {
- ++num18;
- } else {
- Y_FAIL("unexpected level");
- }
- }
- }
- Cerr << "num0# " << num0 << " num1..16# " << num1_16 << " num17# " << num17 << " num18# " << num18 << Endl;
- if (num0 > 3 && num1_16 && (num17 > 1 || num18 > 1)) {
- done = true;
- break;
- }
- if (num0 < 20) {
- break;
- }
- env.Sim(TDuration::Seconds(10));
- }
- if (done) {
- break;
- }
- }
- }
- env.Runtime->DestroyActor(sender);
-
- TActorId queueId = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000);
- TLogoBlobID fromId = TLogoBlobID(1, 0, 0, 0, 0, 0);
- TLogoBlobID toId = TLogoBlobID(1, Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
- TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
- for (;;) {
- const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- auto ev = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, fromId, toId, 1000);
- env.Runtime->Send(new IEventHandle(queueId, sender, ev.release()), sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
- auto& r = res->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
- for (const auto& item : r.GetResult()) {
- UNIT_ASSERT_VALUES_EQUAL(item.GetStatus(), NKikimrProto::OK);
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(item.GetBlobID());
- fromId = id;
- auto ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, {id});
- const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
- env.Runtime->Send(new IEventHandle(queueId, sender, ev.release()), sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
- auto& r = res->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
- for (const auto& item : r.GetResult()) {
- if (item.GetStatus() == NKikimrProto::OK) {
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(item.GetBlobID());
- const TString& buffer = item.GetBuffer();
- const TString& hash = MD5::Calc(buffer);
- data.emplace(id, hash);
- Cerr << "BlobId# " << id.ToString() << " hash# " << hash << " size# " << buffer.size() << Endl;
- }
- }
- }
- if (!r.GetIsRangeOverflow()) {
- break;
- }
- }
- }
-
- void Validate(TEnvironmentSetup& env, const TVDiskID& vdiskId, std::map<TLogoBlobID, TString>& data,
- TBlobStorageGroupType type, const std::set<TLogoBlobID>& blobIdsToValidate) {
- const TActorId& queueId = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, ++QueueClientId);
- const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
-
- std::unique_ptr<TEvBlobStorage::TEvVGet> ev;
- ui32 total = 0;
- ui32 numMsgs = 0;
- ui32 numBlobs = 0;
- for (const auto& key : blobIdsToValidate) {
- const ui32 partSize = type.PartSize(key);
- const ui32 size = partSize + BlobProtobufHeaderMaxSize;
- if (size + total > 60000000) {
- env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), edge.NodeId());
- total = 0;
- ++numMsgs;
- }
- if (!ev) {
- ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead);
- }
- ev->AddExtremeQuery(key, 0, 0);
- total += size;
- ++numBlobs;
- }
- if (ev) {
- env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), edge.NodeId());
- ++numMsgs;
- }
- while (numMsgs--) {
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
- auto& r = res->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
- for (const auto& result : r.GetResult()) {
- const TLogoBlobID& key = LogoBlobIDFromLogoBlobID(result.GetBlobID());
- UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), NKikimrProto::OK, "Id# " << key);
- UNIT_ASSERT_EQUAL(MD5::Calc(result.GetBuffer()), data.at(key));
- --numBlobs;
- }
- }
- UNIT_ASSERT(!numBlobs);
-
- env.Runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, queueId, edge, nullptr, 0), 1);
- env.Runtime->DestroyActor(edge);
- }
-
- void ScrubTest(TBlobStorageGroupType erasure) {
- SetRandomSeed(1);
+#include <library/cpp/digest/md5/md5.h>
+#include <library/cpp/testing/unittest/registar.h>
+
+Y_UNIT_TEST_SUITE(BlobScrubbing) {
+
+ ui32 QueueClientId = 0;
+
+ using TLayout = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
+
+ void Populate(TEnvironmentSetup& env, TVDiskID vdiskId, TActorId vdiskActorId, std::map<TLogoBlobID, TString>& data,
+ std::unique_ptr<TLayout>& layout) {
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(vdiskActorId.NodeId());
+
+ std::vector<TString> blobs;
+ for (ui32 i = 0; i < 100; ++i) {
+ const ui32 size = RandomNumber(10u) == 0 ? RandomNumber<ui32>(3 << 20) + 1048576 : (RandomNumber<ui32>(65536) + 1); // 1 byte - 4 MB
+ TString data = TString::Uninitialized(size);
+ memset(data.Detach(), RandomNumber<ui8>(), size);
+ blobs.push_back(data);
+ }
+
+ for (ui32 i = 1;; ++i) {
+ const TString& data = blobs[RandomNumber(blobs.size())];
+ TLogoBlobID id(1, 1, i, 0, data.size(), 0);
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, data, TInstant::Max());
+ env.Runtime->WrapInActorContext(sender, [&] {
+ SendToBSProxy(sender, vdiskId.GroupID, ev.release());
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(sender, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+ Cerr << "res# " << res->Get()->ToString() << Endl;
+
+ if (i % 500 == 0) {
+ env.CompactVDisk(vdiskActorId, true /*freshOnly*/);
+
+ bool done = false;
+ for (;;) {
+ env.Runtime->Send(new IEventHandle(vdiskActorId, sender, new TEvBlobStorage::TEvCaptureVDiskLayout),
+ sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TLayout>(sender, false);
+ layout.reset(res->Release().Release());
+ ui32 num0 = 0, num1_16 = 0, num17 = 0, num18 = 0;
+ for (const auto& item : layout->Layout) {
+ if (item.Database == TLayout::EDatabase::LogoBlobs && item.RecordType == TLayout::ERecordType::IndexRecord) {
+ if (item.Level == 0) {
+ ++num0;
+ } else if (item.Level < 17) {
+ ++num1_16;
+ } else if (item.Level == 17) {
+ ++num17;
+ } else if (item.Level == 18) {
+ ++num18;
+ } else {
+ Y_FAIL("unexpected level");
+ }
+ }
+ }
+ Cerr << "num0# " << num0 << " num1..16# " << num1_16 << " num17# " << num17 << " num18# " << num18 << Endl;
+ if (num0 > 3 && num1_16 && (num17 > 1 || num18 > 1)) {
+ done = true;
+ break;
+ }
+ if (num0 < 20) {
+ break;
+ }
+ env.Sim(TDuration::Seconds(10));
+ }
+ if (done) {
+ break;
+ }
+ }
+ }
+ env.Runtime->DestroyActor(sender);
+
+ TActorId queueId = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000);
+ TLogoBlobID fromId = TLogoBlobID(1, 0, 0, 0, 0, 0);
+ TLogoBlobID toId = TLogoBlobID(1, Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
+ TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
+ for (;;) {
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ auto ev = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, fromId, toId, 1000);
+ env.Runtime->Send(new IEventHandle(queueId, sender, ev.release()), sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
+ auto& r = res->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
+ for (const auto& item : r.GetResult()) {
+ UNIT_ASSERT_VALUES_EQUAL(item.GetStatus(), NKikimrProto::OK);
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(item.GetBlobID());
+ fromId = id;
+ auto ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, {}, {}, {id});
+ const TActorId& sender = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+ env.Runtime->Send(new IEventHandle(queueId, sender, ev.release()), sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(sender);
+ auto& r = res->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
+ for (const auto& item : r.GetResult()) {
+ if (item.GetStatus() == NKikimrProto::OK) {
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(item.GetBlobID());
+ const TString& buffer = item.GetBuffer();
+ const TString& hash = MD5::Calc(buffer);
+ data.emplace(id, hash);
+ Cerr << "BlobId# " << id.ToString() << " hash# " << hash << " size# " << buffer.size() << Endl;
+ }
+ }
+ }
+ if (!r.GetIsRangeOverflow()) {
+ break;
+ }
+ }
+ }
+
+ void Validate(TEnvironmentSetup& env, const TVDiskID& vdiskId, std::map<TLogoBlobID, TString>& data,
+ TBlobStorageGroupType type, const std::set<TLogoBlobID>& blobIdsToValidate) {
+ const TActorId& queueId = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, ++QueueClientId);
+ const TActorId& edge = env.Runtime->AllocateEdgeActor(queueId.NodeId());
+
+ std::unique_ptr<TEvBlobStorage::TEvVGet> ev;
+ ui32 total = 0;
+ ui32 numMsgs = 0;
+ ui32 numBlobs = 0;
+ for (const auto& key : blobIdsToValidate) {
+ const ui32 partSize = type.PartSize(key);
+ const ui32 size = partSize + BlobProtobufHeaderMaxSize;
+ if (size + total > 60000000) {
+ env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), edge.NodeId());
+ total = 0;
+ ++numMsgs;
+ }
+ if (!ev) {
+ ev = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead);
+ }
+ ev->AddExtremeQuery(key, 0, 0);
+ total += size;
+ ++numBlobs;
+ }
+ if (ev) {
+ env.Runtime->Send(new IEventHandle(queueId, edge, ev.release()), edge.NodeId());
+ ++numMsgs;
+ }
+ while (numMsgs--) {
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge, false);
+ auto& r = res->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(r.GetStatus(), NKikimrProto::OK);
+ for (const auto& result : r.GetResult()) {
+ const TLogoBlobID& key = LogoBlobIDFromLogoBlobID(result.GetBlobID());
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), NKikimrProto::OK, "Id# " << key);
+ UNIT_ASSERT_EQUAL(MD5::Calc(result.GetBuffer()), data.at(key));
+ --numBlobs;
+ }
+ }
+ UNIT_ASSERT(!numBlobs);
+
+ env.Runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, queueId, edge, nullptr, 0), 1);
+ env.Runtime->DestroyActor(edge);
+ }
+
+ void ScrubTest(TBlobStorageGroupType erasure) {
+ SetRandomSeed(1);
TEnvironmentSetup env(false, erasure);
- auto& runtime = env.Runtime;
+ auto& runtime = env.Runtime;
env.CreateBoxAndPool();
- env.Sim(TDuration::Minutes(1));
- auto groups = env.GetGroups();
- auto info = env.GetGroupInfo(groups[0]);
- const TVDiskID vdiskId = info->GetVDiskId(0);
- const TActorId vdiskActorId = info->GetActorId(0);
-
- std::map<TLogoBlobID, TString> data;
- std::unique_ptr<TLayout> layout;
- Populate(env, vdiskId, vdiskActorId, data, layout);
-
- env.SetScrubPeriodicity(TDuration::Seconds(60));
- env.Sim(TDuration::Seconds(60));
-
- ui32 nodeId, pdiskId;
- std::tie(nodeId, pdiskId, std::ignore) = DecomposeVDiskServiceId(vdiskActorId);
- auto it = env.PDiskMockStates.find(std::make_pair(nodeId, pdiskId));
- Y_VERIFY(it != env.PDiskMockStates.end());
- TPDiskMockState::TPtr snapshot = it->second->Snapshot();
-
- std::map<ui32, std::vector<const TLayout::TLayoutRecord*>> indexes;
- std::map<ui64, std::vector<const TLayout::TLayoutRecord*>> inplaceBlobs;
- std::map<ui64, std::vector<const TLayout::TLayoutRecord*>> hugeBlobs;
- std::map<ui32, std::vector<TLogoBlobID>> blobsPerChunk;
- std::map<TLogoBlobID, TDiskPart> locations;
- for (const auto& item : layout->Layout) {
- if (item.Database != TLayout::EDatabase::LogoBlobs) {
- continue;
- }
- switch (item.RecordType) {
- case TLayout::ERecordType::IndexRecord:
- if (item.Level == 0) {
- indexes[0].push_back(&item);
- } else if (item.Level < 17) {
- indexes[1].push_back(&item);
- } else {
- indexes[2].push_back(&item);
- }
- break;
-
- case TLayout::ERecordType::InplaceBlob:
- inplaceBlobs[item.SstId].push_back(&item);
- blobsPerChunk[item.Location.ChunkIdx].push_back(item.BlobId);
- locations.emplace(item.BlobId, item.Location);
- break;
-
- case TLayout::ERecordType::HugeBlob:
- hugeBlobs[item.SstId].push_back(&item);
- break;
- }
- }
-
- enum class ECheckpoint : ui32 {
- BROKEN_CHUNK_L0,
- BROKEN_INDEX_L0,
- BROKEN_CHUNK_L1_8,
- BROKEN_INDEX_L1_8,
- BROKEN_CHUNK_L17,
- BROKEN_INDEX_L17,
- BROKEN_INPLACE_BLOB,
- BROKEN_HUGE_BLOB,
- };
-
- std::map<ECheckpoint, std::pair<ui32, ui32>> checkpoints{
- {ECheckpoint::BROKEN_CHUNK_L0, {0, 5}},
- {ECheckpoint::BROKEN_INDEX_L0, {0, 5}},
- {ECheckpoint::BROKEN_CHUNK_L1_8, {0, 5}},
- {ECheckpoint::BROKEN_INDEX_L1_8, {0, 5}},
- {ECheckpoint::BROKEN_CHUNK_L17, {0, 5}},
- {ECheckpoint::BROKEN_INDEX_L17, {0, 5}},
- {ECheckpoint::BROKEN_INPLACE_BLOB, {0, 100}},
- {ECheckpoint::BROKEN_HUGE_BLOB, {0, 100}},
- };
-
- ui32 passedCheckpoints = 0; // from TEvScrubNotify
-
- for (ui32 iter = 0;; ++iter) {
- // wait for VDisks to start
- env.WaitForVDiskToGetRunning(vdiskId, vdiskActorId);
-
- Cerr << Endl;
-
- auto corrupt = [&](const TDiskPart& location, TString name) {
- Cerr << "*** iter# " << iter << " corrupting " << name << " location# " << location.ToString() << Endl;
- it->second->SetCorruptedArea(location.ChunkIdx, location.Offset, location.Offset + location.Size, true);
- };
-
- std::set<ui64> brokenSstIds;
-
- std::set<TLogoBlobID> blobIdsToValidate;
-
- auto pickIndexRecord = [&](ui32 i) {
- const std::vector<const TLayout::TLayoutRecord*>& recs = indexes[i];
- return recs[RandomNumber(recs.size())];
- };
-
- auto breakChunk = [&](ui32 i) {
- const auto& r = *pickIndexRecord(i);
- brokenSstIds.insert(r.SstId);
- const TDiskPart location(r.Location.ChunkIdx, 0, r.Location.Offset + r.Location.Size);
- corrupt(location, "chunk");
- for (const TLogoBlobID& id : blobsPerChunk[location.ChunkIdx]) {
- const auto& blobLocation = locations.at(id);
- if (location.Offset + location.Size > blobLocation.Offset && blobLocation.Offset + blobLocation.Size > location.Offset) {
- blobIdsToValidate.insert(id);
- }
- }
- };
-
- auto breakIndex = [&](ui32 i) {
- const auto& r = *pickIndexRecord(i);
- brokenSstIds.insert(r.SstId);
- corrupt(r.Location, "index");
- auto& v = blobsPerChunk[r.Location.ChunkIdx];
- blobIdsToValidate.insert(v.begin(), v.end());
- };
-
- auto pickBlob = [&](const auto& blobs) {
- std::vector<const TLayout::TLayoutRecord*> recs;
- for (ui64 sstId : brokenSstIds) {
- recs.insert(recs.end(), inplaceBlobs[sstId].begin(), inplaceBlobs[sstId].end());
- }
- if (recs.empty()) {
- for (const auto& [key, value] : blobs) {
- recs.insert(recs.end(), value.begin(), value.end());
- }
- }
- Y_VERIFY(!recs.empty());
- return recs[RandomNumber(recs.size())];
- };
-
- auto breakInplaceBlob = [&] {
- const auto& r = *pickBlob(inplaceBlobs);
- corrupt(r.Location, TStringBuilder() << "inplace blob# " << r.BlobId.ToString());
- blobIdsToValidate.insert(r.BlobId);
- };
-
- auto breakHugeBlob = [&] {
- const auto& r = *pickBlob(hugeBlobs);
- corrupt(r.Location, TStringBuilder() << "huge blob# " << r.BlobId.ToString());
- blobIdsToValidate.insert(r.BlobId);
- };
-
- std::vector<ECheckpoint> v;
- for (const auto& [key, value] : checkpoints) {
- for (ui32 i = 0; i < value.second - value.first; ++i) {
- v.push_back(key);
- }
- }
- for (ui32 i = 0; i < v.size(); ++i) {
- std::swap(v[i], v[i + RandomNumber(v.size() - i)]);
- }
- const ui32 num = 1 + RandomNumber(Min<ui32>(v.size(), 10));
- for (ui32 i = 0; i < num; ++i) {
- ++checkpoints[v[i]].first;
- switch (v[i]) {
- case ECheckpoint::BROKEN_CHUNK_L0: breakChunk(0); break;
- case ECheckpoint::BROKEN_INDEX_L0: breakIndex(0); break;
- case ECheckpoint::BROKEN_CHUNK_L1_8: breakChunk(1); break;
- case ECheckpoint::BROKEN_INDEX_L1_8: breakIndex(1); break;
- case ECheckpoint::BROKEN_CHUNK_L17: breakChunk(2); break;
- case ECheckpoint::BROKEN_INDEX_L17: breakIndex(2); break;
- case ECheckpoint::BROKEN_INPLACE_BLOB: breakInplaceBlob(); break;
- case ECheckpoint::BROKEN_HUGE_BLOB: breakHugeBlob(); break;
- }
- }
-
- Cerr << Endl;
-
- // wait for full scrub cycle to finish
- for (;;) {
- const ui32 nodeId = vdiskActorId.NodeId();
- const TActorId& edge = runtime->AllocateEdgeActor(nodeId);
- const ui64 cookie = RandomNumber<ui64>();
- runtime->Send(new IEventHandle(TEvBlobStorage::EvScrubAwait, 0, vdiskActorId, edge, nullptr, cookie), nodeId);
- auto ev = env.WaitForEdgeActorEvent<TEvScrubNotify>(edge);
- UNIT_ASSERT_VALUES_EQUAL(ev->Cookie, cookie);
- passedCheckpoints |= ev->Get()->Checkpoints;
- if (ev->Get()->Success) {
- break;
- }
- }
-
- // terminate peer disks
- for (ui32 i = 1; i < info->GetTotalVDisksNum(); ++i) {
- const TActorId& actorId = info->GetActorId(i);
- Cerr << "*** terminating peer disk# " << actorId.ToString() << Endl;
- runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0), actorId.NodeId());
- }
-
- Cerr << "*** blobIdsToValidate.size# " << blobIdsToValidate.size() << Endl;
-
- Validate(env, vdiskId, data, info->Type, blobIdsToValidate);
-
- env.Cleanup();
- env.Initialize();
-
- Validate(env, vdiskId, data, info->Type, blobIdsToValidate);
-
- Cerr << Endl;
- Cerr << "*** iter# " << iter << " checkpoints";
- for (const auto& [key, value] : checkpoints) {
- Cerr << " " << (ui32)key << ":" << value.first << "/" << value.second;
- }
- Cerr << Endl << Endl;
-
- bool done = passedCheckpoints == TEvScrubNotify::ALL;
- for (const auto& [key, value] : checkpoints) {
- const auto& [current, target] = value;
- if (current < target) {
- done = false;
- }
- }
- if (done) {
- break;
- }
-
- // restore PDisk snapshot and restart the system
- env.Cleanup();
- it->second = snapshot->Snapshot();
- env.Initialize();
- }
- }
-
- Y_UNIT_TEST(mirror3of4) {
- ScrubTest(TBlobStorageGroupType::ErasureMirror3of4);
- }
-
- Y_UNIT_TEST(mirror3dc) {
- ScrubTest(TBlobStorageGroupType::ErasureMirror3dc);
- }
-
- Y_UNIT_TEST(block42) {
- ScrubTest(TBlobStorageGroupType::Erasure4Plus2Block);
- }
-
-}
+ env.Sim(TDuration::Minutes(1));
+ auto groups = env.GetGroups();
+ auto info = env.GetGroupInfo(groups[0]);
+ const TVDiskID vdiskId = info->GetVDiskId(0);
+ const TActorId vdiskActorId = info->GetActorId(0);
+
+ std::map<TLogoBlobID, TString> data;
+ std::unique_ptr<TLayout> layout;
+ Populate(env, vdiskId, vdiskActorId, data, layout);
+
+ env.SetScrubPeriodicity(TDuration::Seconds(60));
+ env.Sim(TDuration::Seconds(60));
+
+ ui32 nodeId, pdiskId;
+ std::tie(nodeId, pdiskId, std::ignore) = DecomposeVDiskServiceId(vdiskActorId);
+ auto it = env.PDiskMockStates.find(std::make_pair(nodeId, pdiskId));
+ Y_VERIFY(it != env.PDiskMockStates.end());
+ TPDiskMockState::TPtr snapshot = it->second->Snapshot();
+
+ std::map<ui32, std::vector<const TLayout::TLayoutRecord*>> indexes;
+ std::map<ui64, std::vector<const TLayout::TLayoutRecord*>> inplaceBlobs;
+ std::map<ui64, std::vector<const TLayout::TLayoutRecord*>> hugeBlobs;
+ std::map<ui32, std::vector<TLogoBlobID>> blobsPerChunk;
+ std::map<TLogoBlobID, TDiskPart> locations;
+ for (const auto& item : layout->Layout) {
+ if (item.Database != TLayout::EDatabase::LogoBlobs) {
+ continue;
+ }
+ switch (item.RecordType) {
+ case TLayout::ERecordType::IndexRecord:
+ if (item.Level == 0) {
+ indexes[0].push_back(&item);
+ } else if (item.Level < 17) {
+ indexes[1].push_back(&item);
+ } else {
+ indexes[2].push_back(&item);
+ }
+ break;
+
+ case TLayout::ERecordType::InplaceBlob:
+ inplaceBlobs[item.SstId].push_back(&item);
+ blobsPerChunk[item.Location.ChunkIdx].push_back(item.BlobId);
+ locations.emplace(item.BlobId, item.Location);
+ break;
+
+ case TLayout::ERecordType::HugeBlob:
+ hugeBlobs[item.SstId].push_back(&item);
+ break;
+ }
+ }
+
+ enum class ECheckpoint : ui32 {
+ BROKEN_CHUNK_L0,
+ BROKEN_INDEX_L0,
+ BROKEN_CHUNK_L1_8,
+ BROKEN_INDEX_L1_8,
+ BROKEN_CHUNK_L17,
+ BROKEN_INDEX_L17,
+ BROKEN_INPLACE_BLOB,
+ BROKEN_HUGE_BLOB,
+ };
+
+ std::map<ECheckpoint, std::pair<ui32, ui32>> checkpoints{
+ {ECheckpoint::BROKEN_CHUNK_L0, {0, 5}},
+ {ECheckpoint::BROKEN_INDEX_L0, {0, 5}},
+ {ECheckpoint::BROKEN_CHUNK_L1_8, {0, 5}},
+ {ECheckpoint::BROKEN_INDEX_L1_8, {0, 5}},
+ {ECheckpoint::BROKEN_CHUNK_L17, {0, 5}},
+ {ECheckpoint::BROKEN_INDEX_L17, {0, 5}},
+ {ECheckpoint::BROKEN_INPLACE_BLOB, {0, 100}},
+ {ECheckpoint::BROKEN_HUGE_BLOB, {0, 100}},
+ };
+
+ ui32 passedCheckpoints = 0; // from TEvScrubNotify
+
+ for (ui32 iter = 0;; ++iter) {
+ // wait for VDisks to start
+ env.WaitForVDiskToGetRunning(vdiskId, vdiskActorId);
+
+ Cerr << Endl;
+
+ auto corrupt = [&](const TDiskPart& location, TString name) {
+ Cerr << "*** iter# " << iter << " corrupting " << name << " location# " << location.ToString() << Endl;
+ it->second->SetCorruptedArea(location.ChunkIdx, location.Offset, location.Offset + location.Size, true);
+ };
+
+ std::set<ui64> brokenSstIds;
+
+ std::set<TLogoBlobID> blobIdsToValidate;
+
+ auto pickIndexRecord = [&](ui32 i) {
+ const std::vector<const TLayout::TLayoutRecord*>& recs = indexes[i];
+ return recs[RandomNumber(recs.size())];
+ };
+
+ auto breakChunk = [&](ui32 i) {
+ const auto& r = *pickIndexRecord(i);
+ brokenSstIds.insert(r.SstId);
+ const TDiskPart location(r.Location.ChunkIdx, 0, r.Location.Offset + r.Location.Size);
+ corrupt(location, "chunk");
+ for (const TLogoBlobID& id : blobsPerChunk[location.ChunkIdx]) {
+ const auto& blobLocation = locations.at(id);
+ if (location.Offset + location.Size > blobLocation.Offset && blobLocation.Offset + blobLocation.Size > location.Offset) {
+ blobIdsToValidate.insert(id);
+ }
+ }
+ };
+
+ auto breakIndex = [&](ui32 i) {
+ const auto& r = *pickIndexRecord(i);
+ brokenSstIds.insert(r.SstId);
+ corrupt(r.Location, "index");
+ auto& v = blobsPerChunk[r.Location.ChunkIdx];
+ blobIdsToValidate.insert(v.begin(), v.end());
+ };
+
+ auto pickBlob = [&](const auto& blobs) {
+ std::vector<const TLayout::TLayoutRecord*> recs;
+ for (ui64 sstId : brokenSstIds) {
+ recs.insert(recs.end(), inplaceBlobs[sstId].begin(), inplaceBlobs[sstId].end());
+ }
+ if (recs.empty()) {
+ for (const auto& [key, value] : blobs) {
+ recs.insert(recs.end(), value.begin(), value.end());
+ }
+ }
+ Y_VERIFY(!recs.empty());
+ return recs[RandomNumber(recs.size())];
+ };
+
+ auto breakInplaceBlob = [&] {
+ const auto& r = *pickBlob(inplaceBlobs);
+ corrupt(r.Location, TStringBuilder() << "inplace blob# " << r.BlobId.ToString());
+ blobIdsToValidate.insert(r.BlobId);
+ };
+
+ auto breakHugeBlob = [&] {
+ const auto& r = *pickBlob(hugeBlobs);
+ corrupt(r.Location, TStringBuilder() << "huge blob# " << r.BlobId.ToString());
+ blobIdsToValidate.insert(r.BlobId);
+ };
+
+ std::vector<ECheckpoint> v;
+ for (const auto& [key, value] : checkpoints) {
+ for (ui32 i = 0; i < value.second - value.first; ++i) {
+ v.push_back(key);
+ }
+ }
+ for (ui32 i = 0; i < v.size(); ++i) {
+ std::swap(v[i], v[i + RandomNumber(v.size() - i)]);
+ }
+ const ui32 num = 1 + RandomNumber(Min<ui32>(v.size(), 10));
+ for (ui32 i = 0; i < num; ++i) {
+ ++checkpoints[v[i]].first;
+ switch (v[i]) {
+ case ECheckpoint::BROKEN_CHUNK_L0: breakChunk(0); break;
+ case ECheckpoint::BROKEN_INDEX_L0: breakIndex(0); break;
+ case ECheckpoint::BROKEN_CHUNK_L1_8: breakChunk(1); break;
+ case ECheckpoint::BROKEN_INDEX_L1_8: breakIndex(1); break;
+ case ECheckpoint::BROKEN_CHUNK_L17: breakChunk(2); break;
+ case ECheckpoint::BROKEN_INDEX_L17: breakIndex(2); break;
+ case ECheckpoint::BROKEN_INPLACE_BLOB: breakInplaceBlob(); break;
+ case ECheckpoint::BROKEN_HUGE_BLOB: breakHugeBlob(); break;
+ }
+ }
+
+ Cerr << Endl;
+
+ // wait for full scrub cycle to finish
+ for (;;) {
+ const ui32 nodeId = vdiskActorId.NodeId();
+ const TActorId& edge = runtime->AllocateEdgeActor(nodeId);
+ const ui64 cookie = RandomNumber<ui64>();
+ runtime->Send(new IEventHandle(TEvBlobStorage::EvScrubAwait, 0, vdiskActorId, edge, nullptr, cookie), nodeId);
+ auto ev = env.WaitForEdgeActorEvent<TEvScrubNotify>(edge);
+ UNIT_ASSERT_VALUES_EQUAL(ev->Cookie, cookie);
+ passedCheckpoints |= ev->Get()->Checkpoints;
+ if (ev->Get()->Success) {
+ break;
+ }
+ }
+
+ // terminate peer disks
+ for (ui32 i = 1; i < info->GetTotalVDisksNum(); ++i) {
+ const TActorId& actorId = info->GetActorId(i);
+ Cerr << "*** terminating peer disk# " << actorId.ToString() << Endl;
+ runtime->Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, {}, nullptr, 0), actorId.NodeId());
+ }
+
+ Cerr << "*** blobIdsToValidate.size# " << blobIdsToValidate.size() << Endl;
+
+ Validate(env, vdiskId, data, info->Type, blobIdsToValidate);
+
+ env.Cleanup();
+ env.Initialize();
+
+ Validate(env, vdiskId, data, info->Type, blobIdsToValidate);
+
+ Cerr << Endl;
+ Cerr << "*** iter# " << iter << " checkpoints";
+ for (const auto& [key, value] : checkpoints) {
+ Cerr << " " << (ui32)key << ":" << value.first << "/" << value.second;
+ }
+ Cerr << Endl << Endl;
+
+ bool done = passedCheckpoints == TEvScrubNotify::ALL;
+ for (const auto& [key, value] : checkpoints) {
+ const auto& [current, target] = value;
+ if (current < target) {
+ done = false;
+ }
+ }
+ if (done) {
+ break;
+ }
+
+ // restore PDisk snapshot and restart the system
+ env.Cleanup();
+ it->second = snapshot->Snapshot();
+ env.Initialize();
+ }
+ }
+
+ Y_UNIT_TEST(mirror3of4) {
+ ScrubTest(TBlobStorageGroupType::ErasureMirror3of4);
+ }
+
+ Y_UNIT_TEST(mirror3dc) {
+ ScrubTest(TBlobStorageGroupType::ErasureMirror3dc);
+ }
+
+ Y_UNIT_TEST(block42) {
+ ScrubTest(TBlobStorageGroupType::Erasure4Plus2Block);
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/space_check.cpp b/ydb/core/blobstorage/ut_blobstorage/space_check.cpp
index e40c65e9738..92dad5dad7b 100644
--- a/ydb/core/blobstorage/ut_blobstorage/space_check.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/space_check.cpp
@@ -1,203 +1,203 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
-
-Y_UNIT_TEST_SUITE(SpaceCheckForDiskReassign) {
-
- Y_UNIT_TEST(Basic) {
- using TPDiskId = TNodeWardenMockActor::TPDiskId;
- using TVSlotId = TNodeWardenMockActor::TVSlotId;
-
- TNodeWardenMockActor::TSetup::TPtr setup = MakeIntrusive<TNodeWardenMockActor::TSetup>();
- setup->TabletId = MakeBSControllerID(1);
-
- std::vector<std::vector<ui32>> driveSize = {
- // 8 nodes
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- {10, 10, 10, 10, 8, 8},
- // 8 nodes added
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- {10, 10, 6, 6, 8, 8},
- // some random stuff (8 nodes)
- {10, 10, 10, 6, 6},
- {10, 10, 10, 6, 6},
- {10, 10, 10, 8, 8},
- {10, 10, 10, 6},
- {10, 10, 10, 6},
- {10, 10, 10, 8},
- {10, 10, 10, 8},
- {10, 10, 10},
- };
-
- const ui32 numNodes = driveSize.size();
- ui32 numDrives = 0;
-
- ui64 totalSize = 0;
-
- NKikimrBlobStorage::TConfigRequest request;
- {
- std::map<std::vector<ui32>, ui64> configs;
- ui64 hostConfigId = 0;
-
- NKikimrBlobStorage::TDefineBox box;
- box.SetBoxId(1);
-
- ui32 nodeId = 1;
- for (const std::vector<ui32>& node : driveSize) {
- ui64& id = configs[node];
- NKikimrBlobStorage::TDefineHostConfig *cmd = nullptr;
- if (!id) {
- id = ++hostConfigId;
- cmd = request.AddCommand()->MutableDefineHostConfig();
- cmd->SetHostConfigId(id);
- }
- for (ui32 i = 0; i < node.size(); ++i) {
- TString path = TStringBuilder() << "/dev/disk/by-partlabel/testing_hdd_" << i;
- if (cmd) {
- auto *drive = cmd->AddDrive();
- drive->SetPath(path);
- drive->SetType(NKikimrBlobStorage::EPDiskType::ROT);
- drive->MutablePDiskConfig()->SetExpectedSlotCount(node[i]);
- }
- setup->PDisks.emplace(std::make_tuple(nodeId, path), TNodeWardenMockActor::TSetup::TPDiskInfo{
- node[i] * (ui64)1000000000000}); // TB
- totalSize += node[i];
- ++numDrives;
- }
- auto *host = box.AddHost();
- host->MutableKey()->SetNodeId(nodeId);
- host->SetHostConfigId(id);
- ++nodeId;
- }
-
- request.AddCommand()->MutableDefineBox()->CopyFrom(box);
- }
-
- TEnvironmentSetup env(numNodes, setup);
-
- // provide time for PDisks to report their metrics
- auto response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- env.Sim(TDuration::Minutes(1));
-
- const ui32 numGroups = numDrives * 6 / 8;
-
- request.Clear();
- auto *cmd2 = request.AddCommand()->MutableDefineStoragePool();
- cmd2->SetBoxId(1);
- cmd2->SetStoragePoolId(1);
- cmd2->SetName("storage-pool-1");
- cmd2->SetErasureSpecies("block-4-2");
- cmd2->SetVDiskKind("Default");
- cmd2->SetNumGroups(numGroups);
- cmd2->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::EPDiskType::ROT);
-
- const ui32 numSlots = numGroups * 8;
- totalSize *= (ui64)1000000000000;
-
- const ui64 maxSlotSize = totalSize / numSlots;
-
- for (ui32 i = 0, groupId = 0x82000000; i < numGroups; ++i, ++groupId) {
- const ui64 slotSize =
- i == 0 ? maxSlotSize * 2 :
- i % 6 < 3 ? maxSlotSize * 50 / 100 :
- i % 6 < 4 ? maxSlotSize * 75 / 100 :
- i % 6 < 5 ? maxSlotSize * 80 / 100 :
- maxSlotSize * 90 / 100;
-
- setup->Groups[groupId] = {slotSize};
- cmd2->AddExpectedGroupSlotSize(slotSize);
- }
-
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- request.Clear();
- request.AddCommand()->MutableEnableSelfHeal()->SetEnable(true);
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
-
- ui32 numIterations = 0;
- ui32 numCyclesWithoutProgress = 0;
- constexpr ui32 maxCyclesWithoutProgress = 1; // mins after full replication
-
- for (;;) {
- request.Clear();
- request.AddCommand()->MutableQueryBaseConfig();
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- std::unordered_set<TPDiskId, TPDiskId::THash> faultyPDiskIds;
- std::vector<TPDiskId> pdiskIds;
- for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
- const TPDiskId pdiskId(pdisk.GetNodeId(), pdisk.GetPDiskId());
- pdiskIds.push_back(pdiskId);
- if (pdisk.GetDriveStatus() == NKikimrBlobStorage::EDriveStatus::FAULTY) {
- faultyPDiskIds.insert(pdiskId);
- }
- }
- bool notReady = false;
- bool faultyVSlots = false;
- for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
- const auto& id = vslot.GetVSlotId();
- const TVSlotId vslotId(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId());
- if (faultyPDiskIds.count(vslotId)) {
- faultyVSlots = true;
- }
- if (vslot.GetStatus() != "READY") {
- notReady = true;
- }
- }
- if (notReady) {
- env.Sim(TDuration::Seconds(15));
- continue;
- }
- if (faultyVSlots && numCyclesWithoutProgress < maxCyclesWithoutProgress) {
- env.Sim(TDuration::Minutes(1));
- ++numCyclesWithoutProgress;
- continue;
- }
-
- request.Clear();
- auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
- if (faultyPDiskIds.size() >= 8 || numCyclesWithoutProgress >= maxCyclesWithoutProgress) {
- auto it = faultyPDiskIds.begin();
- std::advance(it, RandomNumber(faultyPDiskIds.size()));
- Cerr << "Making " << *it << " a normal one" << Endl;
- cmd->MutableHostKey()->SetNodeId(it->NodeId);
- cmd->SetPDiskId(it->PDiskId);
- cmd->SetStatus(NKikimrBlobStorage::EDriveStatus::ACTIVE);
- } else {
- size_t index = RandomNumber(pdiskIds.size());
- const auto& pdiskId = pdiskIds[index];
- Cerr << "Making " << pdiskId << " a faulty one" << Endl;
- cmd->MutableHostKey()->SetNodeId(pdiskId.NodeId);
- cmd->SetPDiskId(pdiskId.PDiskId);
- cmd->SetStatus(NKikimrBlobStorage::EDriveStatus::FAULTY);
- }
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- if (numCyclesWithoutProgress < maxCyclesWithoutProgress) {
- ++numIterations;
- }
- Cerr << "numIterations# " << numIterations << " numFaulty# " << faultyPDiskIds.size()
- << " numCyclesWithoutProgress# " << numCyclesWithoutProgress << Endl;
- numCyclesWithoutProgress = 0;
- if (numIterations == 2000) {
- break;
- }
- }
- }
-
-}
+
+Y_UNIT_TEST_SUITE(SpaceCheckForDiskReassign) {
+
+ Y_UNIT_TEST(Basic) {
+ using TPDiskId = TNodeWardenMockActor::TPDiskId;
+ using TVSlotId = TNodeWardenMockActor::TVSlotId;
+
+ TNodeWardenMockActor::TSetup::TPtr setup = MakeIntrusive<TNodeWardenMockActor::TSetup>();
+ setup->TabletId = MakeBSControllerID(1);
+
+ std::vector<std::vector<ui32>> driveSize = {
+ // 8 nodes
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ {10, 10, 10, 10, 8, 8},
+ // 8 nodes added
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ {10, 10, 6, 6, 8, 8},
+ // some random stuff (8 nodes)
+ {10, 10, 10, 6, 6},
+ {10, 10, 10, 6, 6},
+ {10, 10, 10, 8, 8},
+ {10, 10, 10, 6},
+ {10, 10, 10, 6},
+ {10, 10, 10, 8},
+ {10, 10, 10, 8},
+ {10, 10, 10},
+ };
+
+ const ui32 numNodes = driveSize.size();
+ ui32 numDrives = 0;
+
+ ui64 totalSize = 0;
+
+ NKikimrBlobStorage::TConfigRequest request;
+ {
+ std::map<std::vector<ui32>, ui64> configs;
+ ui64 hostConfigId = 0;
+
+ NKikimrBlobStorage::TDefineBox box;
+ box.SetBoxId(1);
+
+ ui32 nodeId = 1;
+ for (const std::vector<ui32>& node : driveSize) {
+ ui64& id = configs[node];
+ NKikimrBlobStorage::TDefineHostConfig *cmd = nullptr;
+ if (!id) {
+ id = ++hostConfigId;
+ cmd = request.AddCommand()->MutableDefineHostConfig();
+ cmd->SetHostConfigId(id);
+ }
+ for (ui32 i = 0; i < node.size(); ++i) {
+ TString path = TStringBuilder() << "/dev/disk/by-partlabel/testing_hdd_" << i;
+ if (cmd) {
+ auto *drive = cmd->AddDrive();
+ drive->SetPath(path);
+ drive->SetType(NKikimrBlobStorage::EPDiskType::ROT);
+ drive->MutablePDiskConfig()->SetExpectedSlotCount(node[i]);
+ }
+ setup->PDisks.emplace(std::make_tuple(nodeId, path), TNodeWardenMockActor::TSetup::TPDiskInfo{
+ node[i] * (ui64)1000000000000}); // TB
+ totalSize += node[i];
+ ++numDrives;
+ }
+ auto *host = box.AddHost();
+ host->MutableKey()->SetNodeId(nodeId);
+ host->SetHostConfigId(id);
+ ++nodeId;
+ }
+
+ request.AddCommand()->MutableDefineBox()->CopyFrom(box);
+ }
+
+ TEnvironmentSetup env(numNodes, setup);
+
+ // provide time for PDisks to report their metrics
+ auto response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ env.Sim(TDuration::Minutes(1));
+
+ const ui32 numGroups = numDrives * 6 / 8;
+
+ request.Clear();
+ auto *cmd2 = request.AddCommand()->MutableDefineStoragePool();
+ cmd2->SetBoxId(1);
+ cmd2->SetStoragePoolId(1);
+ cmd2->SetName("storage-pool-1");
+ cmd2->SetErasureSpecies("block-4-2");
+ cmd2->SetVDiskKind("Default");
+ cmd2->SetNumGroups(numGroups);
+ cmd2->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::EPDiskType::ROT);
+
+ const ui32 numSlots = numGroups * 8;
+ totalSize *= (ui64)1000000000000;
+
+ const ui64 maxSlotSize = totalSize / numSlots;
+
+ for (ui32 i = 0, groupId = 0x82000000; i < numGroups; ++i, ++groupId) {
+ const ui64 slotSize =
+ i == 0 ? maxSlotSize * 2 :
+ i % 6 < 3 ? maxSlotSize * 50 / 100 :
+ i % 6 < 4 ? maxSlotSize * 75 / 100 :
+ i % 6 < 5 ? maxSlotSize * 80 / 100 :
+ maxSlotSize * 90 / 100;
+
+ setup->Groups[groupId] = {slotSize};
+ cmd2->AddExpectedGroupSlotSize(slotSize);
+ }
+
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ request.Clear();
+ request.AddCommand()->MutableEnableSelfHeal()->SetEnable(true);
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+
+ ui32 numIterations = 0;
+ ui32 numCyclesWithoutProgress = 0;
+ constexpr ui32 maxCyclesWithoutProgress = 1; // mins after full replication
+
+ for (;;) {
+ request.Clear();
+ request.AddCommand()->MutableQueryBaseConfig();
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ std::unordered_set<TPDiskId, TPDiskId::THash> faultyPDiskIds;
+ std::vector<TPDiskId> pdiskIds;
+ for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
+ const TPDiskId pdiskId(pdisk.GetNodeId(), pdisk.GetPDiskId());
+ pdiskIds.push_back(pdiskId);
+ if (pdisk.GetDriveStatus() == NKikimrBlobStorage::EDriveStatus::FAULTY) {
+ faultyPDiskIds.insert(pdiskId);
+ }
+ }
+ bool notReady = false;
+ bool faultyVSlots = false;
+ for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
+ const auto& id = vslot.GetVSlotId();
+ const TVSlotId vslotId(id.GetNodeId(), id.GetPDiskId(), id.GetVSlotId());
+ if (faultyPDiskIds.count(vslotId)) {
+ faultyVSlots = true;
+ }
+ if (vslot.GetStatus() != "READY") {
+ notReady = true;
+ }
+ }
+ if (notReady) {
+ env.Sim(TDuration::Seconds(15));
+ continue;
+ }
+ if (faultyVSlots && numCyclesWithoutProgress < maxCyclesWithoutProgress) {
+ env.Sim(TDuration::Minutes(1));
+ ++numCyclesWithoutProgress;
+ continue;
+ }
+
+ request.Clear();
+ auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
+ if (faultyPDiskIds.size() >= 8 || numCyclesWithoutProgress >= maxCyclesWithoutProgress) {
+ auto it = faultyPDiskIds.begin();
+ std::advance(it, RandomNumber(faultyPDiskIds.size()));
+ Cerr << "Making " << *it << " a normal one" << Endl;
+ cmd->MutableHostKey()->SetNodeId(it->NodeId);
+ cmd->SetPDiskId(it->PDiskId);
+ cmd->SetStatus(NKikimrBlobStorage::EDriveStatus::ACTIVE);
+ } else {
+ size_t index = RandomNumber(pdiskIds.size());
+ const auto& pdiskId = pdiskIds[index];
+ Cerr << "Making " << pdiskId << " a faulty one" << Endl;
+ cmd->MutableHostKey()->SetNodeId(pdiskId.NodeId);
+ cmd->SetPDiskId(pdiskId.PDiskId);
+ cmd->SetStatus(NKikimrBlobStorage::EDriveStatus::FAULTY);
+ }
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ if (numCyclesWithoutProgress < maxCyclesWithoutProgress) {
+ ++numIterations;
+ }
+ Cerr << "numIterations# " << numIterations << " numFaulty# " << faultyPDiskIds.size()
+ << " numCyclesWithoutProgress# " << numCyclesWithoutProgress << Endl;
+ numCyclesWithoutProgress = 0;
+ if (numIterations == 2000) {
+ break;
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/sync.cpp b/ydb/core/blobstorage/ut_blobstorage/sync.cpp
index 1ec41aa1797..348495d9fd4 100644
--- a/ydb/core/blobstorage/ut_blobstorage/sync.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/sync.cpp
@@ -1,122 +1,122 @@
#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
-
-Y_UNIT_TEST_SUITE(BlobStorageSync) {
- Y_UNIT_TEST(SyncWhenDiskGetsDown) {
- TEnvironmentSetup env{{
- .NodeCount = 8,
- .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
- }};
- auto& runtime = env.Runtime;
-
- env.CreateBoxAndPool(1, 1);
- auto groups = env.GetGroups();
- UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
- const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
-
- const TActorId edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
- const TString buffer = "hello, world!";
- TLogoBlobID id(1, 1, 1, 0, buffer.size(), 0);
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
- });
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
-
- std::unordered_map<TVDiskID, TActorId, THash<TVDiskID>> queues;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TVDiskID vdiskId = info->GetVDiskId(i);
- queues[vdiskId] = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000);
- }
-
- struct TBlobInfo {
- TVDiskID VDiskId;
- TLogoBlobID BlobId;
- NKikimrProto::EReplyStatus Status;
- std::optional<TIngress> Ingress;
- };
- auto collectBlobInfo = [&] {
- std::vector<TBlobInfo> blobs;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TVDiskID vdiskId = info->GetVDiskId(i);
- const TActorId queueId = queues.at(vdiskId);
- const TActorId edge = runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
- runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(
- vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::ShowInternals, {}, {{id}}).release()), queueId.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
- auto& record = res->Get()->Record;
- UNIT_ASSERT(record.GetStatus() == NKikimrProto::OK || record.GetStatus() == NKikimrProto::NOTREADY);
- for (auto& result : record.GetResult()) {
- blobs.push_back({.VDiskId = vdiskId, .BlobId = LogoBlobIDFromLogoBlobID(result.GetBlobID()),
- .Status = result.GetStatus(), .Ingress = result.HasIngress() ? std::make_optional(
- TIngress(result.GetIngress())) : std::nullopt});
- }
- }
- return blobs;
- };
- auto dumpBlobs = [&](const char *name, const std::vector<TBlobInfo>& blobs) {
- Cerr << "Blobs(" << name <<"):" << Endl;
- for (const auto& item : blobs) {
- Cerr << item.VDiskId << " " << item.BlobId << " " << NKikimrProto::EReplyStatus_Name(item.Status)
- << " " << (item.Ingress ? item.Ingress->ToString(&info->GetTopology(), item.VDiskId, item.BlobId) :
- "none") << Endl;
- }
- };
-
- env.Sim(TDuration::Seconds(10)); // wait for blob to get synced across the group
-
- auto blobsInitial = collectBlobInfo();
-
- runtime->WrapInActorContext(edge, [&] {
- SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), id.Generation(),
- 0, id.Channel(), true, id.Generation(), id.Step(), new TVector<TLogoBlobID>(1, id), nullptr, TInstant::Max(),
- false));
- });
- auto res1 = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
-
- const ui32 suspendedNodeId = 2;
- env.StopNode(suspendedNodeId);
-
- runtime->WrapInActorContext(edge, [&] {
- // send the sole do not keep flag
- SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), 0, 0, 0, false, 0,
- 0, nullptr, new TVector<TLogoBlobID>(1, id), TInstant::Max(), false));
- });
- res1 = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
- UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
-
- // sync barriers and then compact them all
- env.Sim(TDuration::Seconds(10));
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- const TActorId actorId = info->GetActorId(i);
- if (actorId.NodeId() != suspendedNodeId) {
- const auto& sender = env.Runtime->AllocateEdgeActor(actorId.NodeId());
- auto ev = std::make_unique<IEventHandle>(actorId, sender, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
- ev->Rewrite(TEvBlobStorage::EvForwardToSkeleton, actorId);
- runtime->Send(ev.release(), sender.NodeId());
- auto res = env.WaitForEdgeActorEvent<TEvCompactVDiskResult>(sender);
- }
- }
- env.Sim(TDuration::Minutes(1));
- auto blobsIntermediate = collectBlobInfo();
-
- env.StartNode(suspendedNodeId);
- env.Sim(TDuration::Minutes(1));
-
- auto blobsFinal = collectBlobInfo();
-
- dumpBlobs("initial", blobsInitial);
- dumpBlobs("intermediate", blobsIntermediate);
- dumpBlobs("final", blobsFinal);
-
- for (auto& item : blobsIntermediate) {
- UNIT_ASSERT(!item.Ingress || item.Ingress->Raw() == 0);
- }
-
- for (auto& item : blobsFinal) {
- UNIT_ASSERT(!item.Ingress || item.Ingress->Raw() == 0);
- }
- }
-}
+
+Y_UNIT_TEST_SUITE(BlobStorageSync) {
+ Y_UNIT_TEST(SyncWhenDiskGetsDown) {
+ TEnvironmentSetup env{{
+ .NodeCount = 8,
+ .Erasure = TBlobStorageGroupType::Erasure4Plus2Block,
+ }};
+ auto& runtime = env.Runtime;
+
+ env.CreateBoxAndPool(1, 1);
+ auto groups = env.GetGroups();
+ UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1);
+ const TIntrusivePtr<TBlobStorageGroupInfo> info = env.GetGroupInfo(groups.front());
+
+ const TActorId edge = runtime->AllocateEdgeActor(1, __FILE__, __LINE__);
+ const TString buffer = "hello, world!";
+ TLogoBlobID id(1, 1, 1, 0, buffer.size(), 0);
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvPut(id, buffer, TInstant::Max()));
+ });
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+
+ std::unordered_map<TVDiskID, TActorId, THash<TVDiskID>> queues;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TVDiskID vdiskId = info->GetVDiskId(i);
+ queues[vdiskId] = env.CreateQueueActor(vdiskId, NKikimrBlobStorage::EVDiskQueueId::GetFastRead, 1000);
+ }
+
+ struct TBlobInfo {
+ TVDiskID VDiskId;
+ TLogoBlobID BlobId;
+ NKikimrProto::EReplyStatus Status;
+ std::optional<TIngress> Ingress;
+ };
+ auto collectBlobInfo = [&] {
+ std::vector<TBlobInfo> blobs;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TVDiskID vdiskId = info->GetVDiskId(i);
+ const TActorId queueId = queues.at(vdiskId);
+ const TActorId edge = runtime->AllocateEdgeActor(queueId.NodeId(), __FILE__, __LINE__);
+ runtime->Send(new IEventHandle(queueId, edge, TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(
+ vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::ShowInternals, {}, {{id}}).release()), queueId.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvVGetResult>(edge);
+ auto& record = res->Get()->Record;
+ UNIT_ASSERT(record.GetStatus() == NKikimrProto::OK || record.GetStatus() == NKikimrProto::NOTREADY);
+ for (auto& result : record.GetResult()) {
+ blobs.push_back({.VDiskId = vdiskId, .BlobId = LogoBlobIDFromLogoBlobID(result.GetBlobID()),
+ .Status = result.GetStatus(), .Ingress = result.HasIngress() ? std::make_optional(
+ TIngress(result.GetIngress())) : std::nullopt});
+ }
+ }
+ return blobs;
+ };
+ auto dumpBlobs = [&](const char *name, const std::vector<TBlobInfo>& blobs) {
+ Cerr << "Blobs(" << name <<"):" << Endl;
+ for (const auto& item : blobs) {
+ Cerr << item.VDiskId << " " << item.BlobId << " " << NKikimrProto::EReplyStatus_Name(item.Status)
+ << " " << (item.Ingress ? item.Ingress->ToString(&info->GetTopology(), item.VDiskId, item.BlobId) :
+ "none") << Endl;
+ }
+ };
+
+ env.Sim(TDuration::Seconds(10)); // wait for blob to get synced across the group
+
+ auto blobsInitial = collectBlobInfo();
+
+ runtime->WrapInActorContext(edge, [&] {
+ SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), id.Generation(),
+ 0, id.Channel(), true, id.Generation(), id.Step(), new TVector<TLogoBlobID>(1, id), nullptr, TInstant::Max(),
+ false));
+ });
+ auto res1 = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+
+ const ui32 suspendedNodeId = 2;
+ env.StopNode(suspendedNodeId);
+
+ runtime->WrapInActorContext(edge, [&] {
+ // send the sole do not keep flag
+ SendToBSProxy(edge, info->GroupID, new TEvBlobStorage::TEvCollectGarbage(id.TabletID(), 0, 0, 0, false, 0,
+ 0, nullptr, new TVector<TLogoBlobID>(1, id), TInstant::Max(), false));
+ });
+ res1 = env.WaitForEdgeActorEvent<TEvBlobStorage::TEvCollectGarbageResult>(edge, false);
+ UNIT_ASSERT_VALUES_EQUAL(res->Get()->Status, NKikimrProto::OK);
+
+ // sync barriers and then compact them all
+ env.Sim(TDuration::Seconds(10));
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ const TActorId actorId = info->GetActorId(i);
+ if (actorId.NodeId() != suspendedNodeId) {
+ const auto& sender = env.Runtime->AllocateEdgeActor(actorId.NodeId());
+ auto ev = std::make_unique<IEventHandle>(actorId, sender, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
+ ev->Rewrite(TEvBlobStorage::EvForwardToSkeleton, actorId);
+ runtime->Send(ev.release(), sender.NodeId());
+ auto res = env.WaitForEdgeActorEvent<TEvCompactVDiskResult>(sender);
+ }
+ }
+ env.Sim(TDuration::Minutes(1));
+ auto blobsIntermediate = collectBlobInfo();
+
+ env.StartNode(suspendedNodeId);
+ env.Sim(TDuration::Minutes(1));
+
+ auto blobsFinal = collectBlobInfo();
+
+ dumpBlobs("initial", blobsInitial);
+ dumpBlobs("intermediate", blobsIntermediate);
+ dumpBlobs("final", blobsFinal);
+
+ for (auto& item : blobsIntermediate) {
+ UNIT_ASSERT(!item.Ingress || item.Ingress->Raw() == 0);
+ }
+
+ for (auto& item : blobsFinal) {
+ UNIT_ASSERT(!item.Ingress || item.Ingress->Raw() == 0);
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_group_reconfiguration/ya.make b/ydb/core/blobstorage/ut_blobstorage/ut_group_reconfiguration/ya.make
index a244d2379b2..e74f51d8570 100644
--- a/ydb/core/blobstorage/ut_blobstorage/ut_group_reconfiguration/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/ut_group_reconfiguration/ya.make
@@ -1,19 +1,19 @@
UNITTEST_FOR(ydb/core/blobstorage/ut_blobstorage)
-
+
OWNER(g:kikimr)
-
+
FORK_SUBTESTS()
-
+
FORK_SUBTESTS()
-# SIZE(MEDIUM)
-# TIMEOUT(600)
+# SIZE(MEDIUM)
+# TIMEOUT(600)
SIZE(LARGE)
-
+
TIMEOUT(3600)
-
+
TAG(ya:fat)
-
+
SRCS(
race.cpp
)
@@ -27,4 +27,4 @@ REQUIREMENTS(
ram:32
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_osiris/ya.make b/ydb/core/blobstorage/ut_blobstorage/ut_osiris/ya.make
index f6d236317aa..046315e1496 100644
--- a/ydb/core/blobstorage/ut_blobstorage/ut_osiris/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/ut_osiris/ya.make
@@ -1,13 +1,13 @@
UNITTEST_FOR(ydb/core/blobstorage/ut_blobstorage)
-
+
OWNER(g:kikimr)
-
+
FORK_SUBTESTS()
-
+
SIZE(LARGE)
-
+
TIMEOUT(3600)
-
+
TAG(ya:fat)
SRCS(
@@ -23,4 +23,4 @@ REQUIREMENTS(
ram:32
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_replication/ya.make b/ydb/core/blobstorage/ut_blobstorage/ut_replication/ya.make
index e7f5ae6a86f..ae1da7375a3 100644
--- a/ydb/core/blobstorage/ut_blobstorage/ut_replication/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/ut_replication/ya.make
@@ -1,13 +1,13 @@
UNITTEST_FOR(ydb/core/blobstorage/ut_blobstorage)
-
+
OWNER(g:kikimr)
-
+
FORK_SUBTESTS()
-
+
SIZE(LARGE)
-
+
TIMEOUT(3600)
-
+
TAG(ya:fat)
SRCS(
@@ -23,4 +23,4 @@ REQUIREMENTS(
ram:32
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_scrub/ya.make b/ydb/core/blobstorage/ut_blobstorage/ut_scrub/ya.make
index 8d794d3d2e0..9ceca7d194b 100644
--- a/ydb/core/blobstorage/ut_blobstorage/ut_scrub/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/ut_scrub/ya.make
@@ -1,13 +1,13 @@
UNITTEST_FOR(ydb/core/blobstorage/ut_blobstorage)
-
+
OWNER(g:kikimr)
-
+
FORK_SUBTESTS()
-
+
SIZE(LARGE)
-
+
TIMEOUT(3600)
-
+
TAG(ya:fat)
SRCS(
@@ -23,4 +23,4 @@ REQUIREMENTS(
ram:32
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_blobstorage/ya.make b/ydb/core/blobstorage/ut_blobstorage/ya.make
index efe91d91cd9..e11e49a2e5f 100644
--- a/ydb/core/blobstorage/ut_blobstorage/ya.make
+++ b/ydb/core/blobstorage/ut_blobstorage/ya.make
@@ -1,13 +1,13 @@
-UNITTEST()
-
+UNITTEST()
+
OWNER(g:kikimr)
FORK_SUBTESTS()
-
+
SIZE(MEDIUM)
-
+
TIMEOUT(600)
-
+
SRCS(
block_race.cpp
counting_events.cpp
@@ -47,11 +47,11 @@ PEERDIR(
REQUIREMENTS(ram:32)
-END()
+END()
-RECURSE_FOR_TESTS(
- ut_group_reconfiguration
- ut_osiris
- ut_replication
- ut_scrub
-)
+RECURSE_FOR_TESTS(
+ ut_group_reconfiguration
+ ut_osiris
+ ut_replication
+ ut_scrub
+)
diff --git a/ydb/core/blobstorage/ut_group/main.cpp b/ydb/core/blobstorage/ut_group/main.cpp
index 538f46ae032..19b4cc6c975 100644
--- a/ydb/core/blobstorage/ut_group/main.cpp
+++ b/ydb/core/blobstorage/ut_group/main.cpp
@@ -1,5 +1,5 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/core/actor_coroutine.h>
+#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/actors/core/actor_coroutine.h>
#include <ydb/core/blobstorage/crypto/default.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
@@ -9,640 +9,640 @@
#include <ydb/core/blobstorage/dsproxy/dsproxy.h>
#include <ydb/core/node_whiteboard/node_whiteboard.h>
#include <ydb/core/util/testactorsys.h>
-#include <util/system/env.h>
-#include <random>
-
+#include <util/system/env.h>
+#include <random>
+
namespace NKikimr {
namespace NPDisk {
extern const ui64 YdbDefaultPDiskSequence = 0x7e5700007e570000;
}
}
-template<typename TTransformItem, typename TBaseContainer>
-class TFilteredContainer {
- TBaseContainer& Base;
- TTransformItem Callback;
-
- template<typename TBaseIterator>
- class TIterator : public TBaseIterator {
- const TTransformItem& Callback;
-
- public:
- template<typename... TArgs>
- TIterator(const TTransformItem& callback, TArgs&&... args)
- : TBaseIterator(std::forward<TArgs>(args)...)
- , Callback(callback)
- {}
-
- std::invoke_result_t<TTransformItem, decltype(*std::declval<TBaseIterator>())> operator *() {
- return std::invoke(Callback, *static_cast<TBaseIterator&>(*this));
- }
-
- std::invoke_result_t<TTransformItem, decltype(*std::declval<const TBaseIterator>())> operator *() const {
- return std::invoke(Callback, *static_cast<const TBaseIterator&>(*this));
- }
- };
-
-public:
- template<typename... TArgs>
- TFilteredContainer(TBaseContainer& base, TArgs&&... args)
- : Base(base)
- , Callback(std::forward<TArgs>(args)...)
- {}
-
- TIterator<decltype(std::declval<TBaseContainer>().begin())> begin() { return {Callback, Base.begin()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().begin())> begin() const { return {Callback, Base.begin()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().cbegin())> cbegin() const { return {Callback, Base.cbegin()}; }
-
- TIterator<decltype(std::declval<TBaseContainer>().rbegin())> rbegin() { return {Callback, Base.rbegin()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().rbegin())> rbegin() const { return {Callback, Base.rbegin()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().crbegin())> crbegin() const { return {Callback, Base.crbegin()}; }
-
- TIterator<decltype(std::declval<TBaseContainer>().end())> end() { return {Callback, Base.end()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().end())> end() const { return {Callback, Base.end()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().cend())> cend() const { return {Callback, Base.cend()}; }
-
- TIterator<decltype(std::declval<TBaseContainer>().rend())> rend() { return {Callback, Base.rend()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().rend())> rend() const { return {Callback, Base.rend()}; }
- TIterator<decltype(std::declval<const TBaseContainer>().crend())> crend() const { return {Callback, Base.crend()}; }
-};
-
-template<typename TTransformItem, typename TCont>
-TFilteredContainer<TTransformItem, TCont> FilterContainer(TCont& container, TTransformItem&& callback) {
- return {container, std::forward<TTransformItem>(callback)};
-}
-
-using namespace NKikimr;
-
-template<typename TEvent> struct TResultForImpl;
-template<> struct TResultForImpl<TEvBlobStorage::TEvPut> { using Type = TEvBlobStorage::TEvPutResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvGet> { using Type = TEvBlobStorage::TEvGetResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvBlock> { using Type = TEvBlobStorage::TEvBlockResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvDiscover> { using Type = TEvBlobStorage::TEvDiscoverResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvRange> { using Type = TEvBlobStorage::TEvRangeResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvCollectGarbage> { using Type = TEvBlobStorage::TEvCollectGarbageResult; };
-template<> struct TResultForImpl<TEvBlobStorage::TEvStatus> { using Type = TEvBlobStorage::TEvStatusResult; };
-template<typename TEvent> using TResultFor = typename TResultForImpl<TEvent>::Type;
-
-TString GenerateRandomBuffer(std::unordered_map<size_t, TString>& cache) {
- const size_t len = TAppData::RandomProvider->Uniform(100, 201);
- if (const auto it = cache.find(len); it != cache.end()) {
- return it->second;
- }
- TString buffer = TString::Uninitialized(len);
- std::mt19937 gen(TAppData::RandomProvider->GenRand64());
- char *p = buffer.Detach();
- char *end = p + len;
- for (; p != end; ++p) {
- *p = gen();
- }
- cache.emplace(len, buffer);
- return buffer;
-}
-
-class TNodeWardenMockActor : public TActor<TNodeWardenMockActor> {
- std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*>& StatusMap;
-
-public:
- TNodeWardenMockActor(std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*>& statusMap)
- : TActor(&TThis::StateFunc)
- , StatusMap(statusMap)
- {}
-
- void Ignore() {}
-
- void ForwardToProxy(TAutoPtr<IEventHandle> ev) {
- const TGroupID groupId(GroupIDFromBlobStorageProxyID(ev->GetForwardOnNondeliveryRecipient()));
- const ui32 id = groupId.GetRaw();
- TActivationContext::Send(ev->Forward(MakeBlobStorageProxyID(id)));
- }
-
- STRICT_STFUNC(StateFunc,
- cFunc(TEvBlobStorage::EvUpdateGroupInfo, Ignore);
- cFunc(TEvBlobStorage::EvControllerUpdateDiskStatus, Ignore);
- cFunc(TEvBlobStorage::EvDropDonor, Ignore);
- cFunc(TEvBlobStorage::EvGroupStatReport, Ignore);
- cFunc(TEvBlobStorage::EvNotifyVDiskGenerationChange, Ignore);
-
- fFunc(TEvBlobStorage::EvPut, ForwardToProxy);
- fFunc(TEvBlobStorage::EvGet, ForwardToProxy);
- fFunc(TEvBlobStorage::EvBlock, ForwardToProxy);
- fFunc(TEvBlobStorage::EvDiscover, ForwardToProxy);
- fFunc(TEvBlobStorage::EvRange, ForwardToProxy);
- fFunc(TEvBlobStorage::EvCollectGarbage, ForwardToProxy);
- fFunc(TEvBlobStorage::EvStatus, ForwardToProxy);
- fFunc(TEvBlobStorage::EvBunchOfEvents, ForwardToProxy);
-
- hFunc(TEvStatusUpdate, Handle);
-
- IgnoreFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum);
- IgnoreFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate);
- )
-
- void Handle(TEvStatusUpdate::TPtr ev) {
- auto *msg = ev->Get();
- if (const auto it = StatusMap.find({msg->NodeId, msg->PDiskId, msg->VSlotId}); it != StatusMap.end()) {
- *it->second = msg->Status;
- }
- }
-};
-
-class TTestEnv {
-public:
- struct TDiskRecord {
- TVDiskID VDiskId;
- TActorId PDiskActorId;
- TActorId VDiskActorId;
- ui32 NodeId;
- ui32 PDiskId;
- ui32 VDiskSlotId;
- ui64 PDiskGuid;
- NKikimrBlobStorage::EVDiskStatus Status;
- };
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+template<typename TTransformItem, typename TBaseContainer>
+class TFilteredContainer {
+ TBaseContainer& Base;
+ TTransformItem Callback;
+
+ template<typename TBaseIterator>
+ class TIterator : public TBaseIterator {
+ const TTransformItem& Callback;
+
+ public:
+ template<typename... TArgs>
+ TIterator(const TTransformItem& callback, TArgs&&... args)
+ : TBaseIterator(std::forward<TArgs>(args)...)
+ , Callback(callback)
+ {}
+
+ std::invoke_result_t<TTransformItem, decltype(*std::declval<TBaseIterator>())> operator *() {
+ return std::invoke(Callback, *static_cast<TBaseIterator&>(*this));
+ }
+
+ std::invoke_result_t<TTransformItem, decltype(*std::declval<const TBaseIterator>())> operator *() const {
+ return std::invoke(Callback, *static_cast<const TBaseIterator&>(*this));
+ }
+ };
+
+public:
+ template<typename... TArgs>
+ TFilteredContainer(TBaseContainer& base, TArgs&&... args)
+ : Base(base)
+ , Callback(std::forward<TArgs>(args)...)
+ {}
+
+ TIterator<decltype(std::declval<TBaseContainer>().begin())> begin() { return {Callback, Base.begin()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().begin())> begin() const { return {Callback, Base.begin()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().cbegin())> cbegin() const { return {Callback, Base.cbegin()}; }
+
+ TIterator<decltype(std::declval<TBaseContainer>().rbegin())> rbegin() { return {Callback, Base.rbegin()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().rbegin())> rbegin() const { return {Callback, Base.rbegin()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().crbegin())> crbegin() const { return {Callback, Base.crbegin()}; }
+
+ TIterator<decltype(std::declval<TBaseContainer>().end())> end() { return {Callback, Base.end()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().end())> end() const { return {Callback, Base.end()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().cend())> cend() const { return {Callback, Base.cend()}; }
+
+ TIterator<decltype(std::declval<TBaseContainer>().rend())> rend() { return {Callback, Base.rend()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().rend())> rend() const { return {Callback, Base.rend()}; }
+ TIterator<decltype(std::declval<const TBaseContainer>().crend())> crend() const { return {Callback, Base.crend()}; }
+};
+
+template<typename TTransformItem, typename TCont>
+TFilteredContainer<TTransformItem, TCont> FilterContainer(TCont& container, TTransformItem&& callback) {
+ return {container, std::forward<TTransformItem>(callback)};
+}
+
+using namespace NKikimr;
+
+template<typename TEvent> struct TResultForImpl;
+template<> struct TResultForImpl<TEvBlobStorage::TEvPut> { using Type = TEvBlobStorage::TEvPutResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvGet> { using Type = TEvBlobStorage::TEvGetResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvBlock> { using Type = TEvBlobStorage::TEvBlockResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvDiscover> { using Type = TEvBlobStorage::TEvDiscoverResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvRange> { using Type = TEvBlobStorage::TEvRangeResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvCollectGarbage> { using Type = TEvBlobStorage::TEvCollectGarbageResult; };
+template<> struct TResultForImpl<TEvBlobStorage::TEvStatus> { using Type = TEvBlobStorage::TEvStatusResult; };
+template<typename TEvent> using TResultFor = typename TResultForImpl<TEvent>::Type;
+
+TString GenerateRandomBuffer(std::unordered_map<size_t, TString>& cache) {
+ const size_t len = TAppData::RandomProvider->Uniform(100, 201);
+ if (const auto it = cache.find(len); it != cache.end()) {
+ return it->second;
+ }
+ TString buffer = TString::Uninitialized(len);
+ std::mt19937 gen(TAppData::RandomProvider->GenRand64());
+ char *p = buffer.Detach();
+ char *end = p + len;
+ for (; p != end; ++p) {
+ *p = gen();
+ }
+ cache.emplace(len, buffer);
+ return buffer;
+}
+
+class TNodeWardenMockActor : public TActor<TNodeWardenMockActor> {
+ std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*>& StatusMap;
+
+public:
+ TNodeWardenMockActor(std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*>& statusMap)
+ : TActor(&TThis::StateFunc)
+ , StatusMap(statusMap)
+ {}
+
+ void Ignore() {}
+
+ void ForwardToProxy(TAutoPtr<IEventHandle> ev) {
+ const TGroupID groupId(GroupIDFromBlobStorageProxyID(ev->GetForwardOnNondeliveryRecipient()));
+ const ui32 id = groupId.GetRaw();
+ TActivationContext::Send(ev->Forward(MakeBlobStorageProxyID(id)));
+ }
+
+ STRICT_STFUNC(StateFunc,
+ cFunc(TEvBlobStorage::EvUpdateGroupInfo, Ignore);
+ cFunc(TEvBlobStorage::EvControllerUpdateDiskStatus, Ignore);
+ cFunc(TEvBlobStorage::EvDropDonor, Ignore);
+ cFunc(TEvBlobStorage::EvGroupStatReport, Ignore);
+ cFunc(TEvBlobStorage::EvNotifyVDiskGenerationChange, Ignore);
+
+ fFunc(TEvBlobStorage::EvPut, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvGet, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvBlock, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvDiscover, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvRange, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvCollectGarbage, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvStatus, ForwardToProxy);
+ fFunc(TEvBlobStorage::EvBunchOfEvents, ForwardToProxy);
+
+ hFunc(TEvStatusUpdate, Handle);
+
+ IgnoreFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum);
+ IgnoreFunc(NNodeWhiteboard::TEvWhiteboard::TEvBSGroupStateUpdate);
+ )
+
+ void Handle(TEvStatusUpdate::TPtr ev) {
+ auto *msg = ev->Get();
+ if (const auto it = StatusMap.find({msg->NodeId, msg->PDiskId, msg->VSlotId}); it != StatusMap.end()) {
+ *it->second = msg->Status;
+ }
+ }
+};
+
+class TTestEnv {
+public:
+ struct TDiskRecord {
+ TVDiskID VDiskId;
+ TActorId PDiskActorId;
+ TActorId VDiskActorId;
+ ui32 NodeId;
+ ui32 PDiskId;
+ ui32 VDiskSlotId;
+ ui64 PDiskGuid;
+ NKikimrBlobStorage::EVDiskStatus Status;
+ };
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
const NPDisk::TKey MainKey = NPDisk::YdbDefaultPDiskSequence;
- const ui32 NodeCount;
- const ui32 GroupId = 0;
- std::vector<TDiskRecord> Disks;
- std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*> StatusMap;
- NPDisk::TOwnerRound Round = 1;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- std::map<std::tuple<ui32, ui32>, ui32> NextVDiskSlotId;
- std::multimap<ui32, std::tuple<ui32, ui32, ui64>> NodePDiskIds;
- std::unique_ptr<TAllVDiskKinds> AllVDiskKinds = std::make_unique<TAllVDiskKinds>();
- TIntrusivePtr<TStoragePoolCounters> StoragePoolCounters;
-
- TTestEnv(ui32 nodeCount)
- : Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
- , NodeCount(nodeCount)
- {}
-
- void Run(std::function<void(TTestActorSystem&)> fn) {
- TTestActorSystem runtime(NodeCount);
- SetupLogging(runtime);
- runtime.Start();
- SetupStorage(runtime);
- fn(runtime);
- runtime.Stop();
- }
-
- ui32 GetNumReadyDisks() {
- ui32 numReady = 0;
- for (const auto& disk : Disks) {
- numReady += disk.Status == NKikimrBlobStorage::EVDiskStatus::READY;
- }
- return numReady;
- }
-
- void WaitReady(TTestActorSystem& runtime) {
- while (GetNumReadyDisks() < Info->GetTotalVDisksNum()) {
- TInstant clock = runtime.GetClock();
- runtime.Sim([&] {
- return runtime.GetClock() < clock + TDuration::MilliSeconds(100);
- });
- }
- }
-
- bool DoObscenity(TTestActorSystem& runtime, ui32 *allowReformatCounter) {
- const auto *top = &Info->GetTopology();
- TBlobStorageGroupInfo::TGroupVDisks failedDisks(top);
- for (const auto& disk : Disks) {
- if (disk.Status != NKikimrBlobStorage::EVDiskStatus::READY) {
- failedDisks |= {top, disk.VDiskId};
- }
- }
- auto& checker = Info->GetQuorumChecker();
- std::vector<ui32> options;
- const bool reformat = *allowReformatCounter < 3;
- for (ui32 index = 0; index < Disks.size(); ++index) {
- auto item = TBlobStorageGroupInfo::TGroupVDisks(top, Disks[index].VDiskId);
- if ((reformat || !(failedDisks & item)) && checker.CheckFailModelForGroup(failedDisks | item)) {
- options.push_back(index);
- }
- }
- if (options.size()) {
- const size_t index = TAppData::RandomProvider->Uniform(options.size());
- const ui32 diskIdx = options[index];
- const ui32 decision = TAppData::RandomProvider->Uniform(100);
- TDiskRecord& disk = Disks[diskIdx];
- if (decision < 95) {
- RestartDisk(runtime, disk);
- } else if (decision < 98) {
- FormatDisk(runtime, disk);
- } else {
-// ReassignDisk(runtime, disk);
- }
- ++*allowReformatCounter;
- *allowReformatCounter %= 15;
- return true;
- }
- return false;
- }
-
- TString GetDiskStatusMap() const {
- TStringBuilder s;
- for (auto& disk : Disks) {
- switch (disk.Status) {
- case NKikimrBlobStorage::EVDiskStatus::ERROR: s << 'E'; break;
- case NKikimrBlobStorage::EVDiskStatus::INIT_PENDING: s << 'I'; break;
- case NKikimrBlobStorage::EVDiskStatus::REPLICATING: s << 'R'; break;
- case NKikimrBlobStorage::EVDiskStatus::READY: s << 'Y'; break;
- default: s << '?'; break;
- }
- }
- return s;
- }
-
- void RestartDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
- LOG_NOTICE_S(runtime, NActorsServices::TEST, "Restarting " << disk.VDiskId << " over NodeId# " << disk.NodeId
- << " PDiskId# " << disk.PDiskId);
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
- StartVDisk(runtime, disk);
- }
-
- void FormatDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
- LOG_NOTICE_S(runtime, NActorsServices::TEST, "Formatting " << disk.VDiskId << " over NodeId# " << disk.NodeId
- << " PDiskId# " << disk.PDiskId << " DiskStatus# " << GetDiskStatusMap());
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
- Slay(runtime, disk);
- StartVDisk(runtime, disk);
- }
-
- void ReassignDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
- // create set of nodes suitable as target ones
- std::set<ui32> nodes = runtime.GetNodes();
- for (const auto& actorId : Info->GetDynamicInfo().ServiceIdForOrderNumber) {
- const ui32 num = nodes.erase(actorId.NodeId());
- Y_VERIFY(num);
- }
- Y_VERIFY(nodes.size() == 1);
- const ui32 targetNode = *nodes.begin();
-
- // pick random target pdisk
- const auto range = NodePDiskIds.equal_range(targetNode);
- auto it = range.first;
- std::advance(it, TAppData::RandomProvider->Uniform(std::distance(range.first, range.second)));
- ui32 nodeId, pdiskId;
- ui64 pdiskGuid;
- std::tie(nodeId, pdiskId, pdiskGuid) = it->second;
-
- LOG_NOTICE_S(runtime, NActorsServices::TEST, "Reassigning " << disk.VDiskId
- << " from NodeId# " << disk.NodeId << " PDiskId# " << disk.PDiskId << " to NodeId# " << nodeId
- << " PDiskId# " << pdiskId << " PDiskGuid# " << pdiskGuid);
-
- // slay it over PDisk
- Slay(runtime, disk);
-
- // terminate running VDisk directly
- runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
-
- // fill in new VDisk params
- const ui32 vdiskSlotId = ++NextVDiskSlotId[std::make_tuple(nodeId, pdiskId)];
- disk.VDiskId = TVDiskID(Info->GroupID, Info->GroupGeneration + 1, disk.VDiskId);
- disk.PDiskActorId = MakeBlobStoragePDiskID(nodeId, pdiskId);
- disk.VDiskActorId = MakeBlobStorageVDiskID(nodeId, pdiskId, vdiskSlotId);
- disk.NodeId = nodeId;
- disk.PDiskId = pdiskId;
- disk.VDiskSlotId = vdiskSlotId;
- disk.PDiskGuid = pdiskGuid;
-
- // update group info
- TBlobStorageGroupInfo::TTopology topology(Info->Type);
- topology.FailRealms = Info->GetTopology().FailRealms;
- TBlobStorageGroupInfo::TDynamicInfo dynamic(Info->GroupID, Info->GroupGeneration + 1);
- dynamic.ServiceIdForOrderNumber = Info->GetDynamicInfo().ServiceIdForOrderNumber;
- dynamic.ServiceIdForOrderNumber[topology.GetOrderNumber(disk.VDiskId)] = disk.VDiskActorId;
- Info = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dynamic), TString(), Nothing(),
- TPDiskCategory::DEVICE_TYPE_SSD);
-
- StartVDisk(runtime, disk);
-
- // update group generation for other disks
- for (TDiskRecord& disk : Disks) {
- if (disk.VDiskId.GroupGeneration != Info->GroupGeneration) {
- disk.VDiskId = TVDiskID(Info->GroupID, Info->GroupGeneration, disk.VDiskId);
- runtime.Send(new IEventHandle(disk.VDiskActorId, {}, new TEvVGenerationChange(disk.VDiskId, Info)),
- disk.VDiskActorId.NodeId());
- }
- }
-
- // update group info for proxy
- runtime.Send(new IEventHandle(MakeBlobStorageProxyID(Info->GroupID), TActorId(),
- new TEvBlobStorage::TEvConfigureProxy(Info, StoragePoolCounters)), 1);
- }
-
- void Slay(TTestActorSystem& runtime, TDiskRecord& disk) {
- LOG_INFO_S(runtime, NActorsServices::TEST, "Slaying VDiskId# " << disk.VDiskId);
- const TActorId& edge = runtime.AllocateEdgeActor(disk.NodeId);
- auto slay = std::make_unique<NPDisk::TEvSlay>(disk.VDiskId, ++Round, disk.PDiskId, disk.VDiskSlotId);
- runtime.Send(new IEventHandle(disk.PDiskActorId, edge, slay.release()), disk.NodeId);
- auto res = runtime.WaitForEdgeActorEvent({edge});
- if (const auto *ev = res->CastAsLocal<NPDisk::TEvSlayResult>()) {
- Y_VERIFY_S(ev->Status == NKikimrProto::OK || ev->Status == NKikimrProto::ALREADY, "TEvSlayResult# " << ev->ToString());
- LOG_INFO_S(runtime, NActorsServices::TEST, "Slayed VDiskId# " << disk.VDiskId);
- } else {
- Y_FAIL("unexpected event to edge actor");
- }
- }
-
-private:
- void SetupLogging(TTestActorSystem& runtime) {
- runtime.SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_SKELETON, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_REPL, NLog::PRI_INFO);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_ERROR);
- runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_CRIT);
-// runtime.SetLogPriority(NKikimrServices::BS_PROXY, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_PROXY_PUT, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_QUEUE, NLog::PRI_DEBUG);
- runtime.SetLogPriority(NActorsServices::TEST, NLog::PRI_INFO);
- runtime.SetLogPriority(NActorsServices::TEST, NLog::PRI_DEBUG);
- }
-
- void SetupStorage(TTestActorSystem& runtime) {
- TVector<TActorId> vdiskActorIds;
-
- Disks.reserve(8 * NodeCount);
-
- for (ui32 nodeId = 1, i = 0; nodeId <= NodeCount; ++nodeId, ++i) {
- const ui32 pdiskId = 1;
- const ui64 pdiskGuid = TAppData::RandomProvider->GenRand64();
- const TPDiskCategory category(TPDiskCategory::DEVICE_TYPE_SSD, 0);
- const TActorId& actorId = runtime.Register(CreatePDiskMockActor(MakeIntrusive<TPDiskMockState>(nodeId,
- pdiskId, pdiskGuid, ui64(1000) << 30)), TActorId(), 0, std::nullopt, nodeId);
- const TActorId& serviceId = MakeBlobStoragePDiskID(nodeId, pdiskId);
- runtime.RegisterService(serviceId, actorId);
- NodePDiskIds.emplace(nodeId, std::make_tuple(nodeId, pdiskId, pdiskGuid));
- if (i < 8) {
- const ui32 vdiskSlotId = ++NextVDiskSlotId[std::make_tuple(nodeId, pdiskId)];
- const TActorId& vdiskActorId = MakeBlobStorageVDiskID(nodeId, pdiskId, vdiskSlotId);
- vdiskActorIds.push_back(vdiskActorId);
- const TVDiskID vdiskId(GroupId, 1, 0, i, 0);
- Disks.push_back(TDiskRecord{
- vdiskId,
- serviceId,
- vdiskActorId,
- nodeId,
- pdiskId,
- vdiskSlotId,
- pdiskGuid,
- NKikimrBlobStorage::EVDiskStatus::INIT_PENDING,
- });
- StatusMap.emplace(std::make_tuple(nodeId, pdiskId, vdiskSlotId), &Disks.back().Status);
- }
- runtime.RegisterService(MakeBlobStorageNodeWardenID(nodeId), runtime.Register(new TNodeWardenMockActor(StatusMap),
- TActorId(), 0, std::nullopt, nodeId));
- }
-
- Info = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block, 1u, 0u, 1u,
- &vdiskActorIds, TBlobStorageGroupInfo::EEM_NONE);
-
- for (TDiskRecord& disk : Disks) {
- StartVDisk(runtime, disk);
- }
-
- auto proxy = Counters->GetSubgroup("subsystem", "proxy");
- TIntrusivePtr<TDsProxyNodeMon> mon = MakeIntrusive<TDsProxyNodeMon>(proxy, true);
- StoragePoolCounters = MakeIntrusive<TStoragePoolCounters>(proxy, TString(), TPDiskCategory::DEVICE_TYPE_SSD);
- std::unique_ptr<IActor> proxyActor{CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(Info), false, mon,
- TIntrusivePtr(StoragePoolCounters), DefaultEnablePutBatching, DefaultEnableVPatch)};
- const TActorId& actorId = runtime.Register(proxyActor.release(), TActorId(), 0, std::nullopt, 1);
- runtime.RegisterService(MakeBlobStorageProxyID(GroupId), actorId);
- }
-
- void StartVDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
+ const ui32 NodeCount;
+ const ui32 GroupId = 0;
+ std::vector<TDiskRecord> Disks;
+ std::map<std::tuple<ui32, ui32, ui32>, NKikimrBlobStorage::EVDiskStatus*> StatusMap;
+ NPDisk::TOwnerRound Round = 1;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ std::map<std::tuple<ui32, ui32>, ui32> NextVDiskSlotId;
+ std::multimap<ui32, std::tuple<ui32, ui32, ui64>> NodePDiskIds;
+ std::unique_ptr<TAllVDiskKinds> AllVDiskKinds = std::make_unique<TAllVDiskKinds>();
+ TIntrusivePtr<TStoragePoolCounters> StoragePoolCounters;
+
+ TTestEnv(ui32 nodeCount)
+ : Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
+ , NodeCount(nodeCount)
+ {}
+
+ void Run(std::function<void(TTestActorSystem&)> fn) {
+ TTestActorSystem runtime(NodeCount);
+ SetupLogging(runtime);
+ runtime.Start();
+ SetupStorage(runtime);
+ fn(runtime);
+ runtime.Stop();
+ }
+
+ ui32 GetNumReadyDisks() {
+ ui32 numReady = 0;
+ for (const auto& disk : Disks) {
+ numReady += disk.Status == NKikimrBlobStorage::EVDiskStatus::READY;
+ }
+ return numReady;
+ }
+
+ void WaitReady(TTestActorSystem& runtime) {
+ while (GetNumReadyDisks() < Info->GetTotalVDisksNum()) {
+ TInstant clock = runtime.GetClock();
+ runtime.Sim([&] {
+ return runtime.GetClock() < clock + TDuration::MilliSeconds(100);
+ });
+ }
+ }
+
+ bool DoObscenity(TTestActorSystem& runtime, ui32 *allowReformatCounter) {
+ const auto *top = &Info->GetTopology();
+ TBlobStorageGroupInfo::TGroupVDisks failedDisks(top);
+ for (const auto& disk : Disks) {
+ if (disk.Status != NKikimrBlobStorage::EVDiskStatus::READY) {
+ failedDisks |= {top, disk.VDiskId};
+ }
+ }
+ auto& checker = Info->GetQuorumChecker();
+ std::vector<ui32> options;
+ const bool reformat = *allowReformatCounter < 3;
+ for (ui32 index = 0; index < Disks.size(); ++index) {
+ auto item = TBlobStorageGroupInfo::TGroupVDisks(top, Disks[index].VDiskId);
+ if ((reformat || !(failedDisks & item)) && checker.CheckFailModelForGroup(failedDisks | item)) {
+ options.push_back(index);
+ }
+ }
+ if (options.size()) {
+ const size_t index = TAppData::RandomProvider->Uniform(options.size());
+ const ui32 diskIdx = options[index];
+ const ui32 decision = TAppData::RandomProvider->Uniform(100);
+ TDiskRecord& disk = Disks[diskIdx];
+ if (decision < 95) {
+ RestartDisk(runtime, disk);
+ } else if (decision < 98) {
+ FormatDisk(runtime, disk);
+ } else {
+// ReassignDisk(runtime, disk);
+ }
+ ++*allowReformatCounter;
+ *allowReformatCounter %= 15;
+ return true;
+ }
+ return false;
+ }
+
+ TString GetDiskStatusMap() const {
+ TStringBuilder s;
+ for (auto& disk : Disks) {
+ switch (disk.Status) {
+ case NKikimrBlobStorage::EVDiskStatus::ERROR: s << 'E'; break;
+ case NKikimrBlobStorage::EVDiskStatus::INIT_PENDING: s << 'I'; break;
+ case NKikimrBlobStorage::EVDiskStatus::REPLICATING: s << 'R'; break;
+ case NKikimrBlobStorage::EVDiskStatus::READY: s << 'Y'; break;
+ default: s << '?'; break;
+ }
+ }
+ return s;
+ }
+
+ void RestartDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
+ LOG_NOTICE_S(runtime, NActorsServices::TEST, "Restarting " << disk.VDiskId << " over NodeId# " << disk.NodeId
+ << " PDiskId# " << disk.PDiskId);
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
+ StartVDisk(runtime, disk);
+ }
+
+ void FormatDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
+ LOG_NOTICE_S(runtime, NActorsServices::TEST, "Formatting " << disk.VDiskId << " over NodeId# " << disk.NodeId
+ << " PDiskId# " << disk.PDiskId << " DiskStatus# " << GetDiskStatusMap());
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
+ Slay(runtime, disk);
+ StartVDisk(runtime, disk);
+ }
+
+ void ReassignDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
+ // create set of nodes suitable as target ones
+ std::set<ui32> nodes = runtime.GetNodes();
+ for (const auto& actorId : Info->GetDynamicInfo().ServiceIdForOrderNumber) {
+ const ui32 num = nodes.erase(actorId.NodeId());
+ Y_VERIFY(num);
+ }
+ Y_VERIFY(nodes.size() == 1);
+ const ui32 targetNode = *nodes.begin();
+
+ // pick random target pdisk
+ const auto range = NodePDiskIds.equal_range(targetNode);
+ auto it = range.first;
+ std::advance(it, TAppData::RandomProvider->Uniform(std::distance(range.first, range.second)));
+ ui32 nodeId, pdiskId;
+ ui64 pdiskGuid;
+ std::tie(nodeId, pdiskId, pdiskGuid) = it->second;
+
+ LOG_NOTICE_S(runtime, NActorsServices::TEST, "Reassigning " << disk.VDiskId
+ << " from NodeId# " << disk.NodeId << " PDiskId# " << disk.PDiskId << " to NodeId# " << nodeId
+ << " PDiskId# " << pdiskId << " PDiskGuid# " << pdiskGuid);
+
+ // slay it over PDisk
+ Slay(runtime, disk);
+
+ // terminate running VDisk directly
+ runtime.Send(new IEventHandle(TEvents::TSystem::Poison, 0, disk.VDiskActorId, TActorId(), nullptr, 0), disk.NodeId);
+
+ // fill in new VDisk params
+ const ui32 vdiskSlotId = ++NextVDiskSlotId[std::make_tuple(nodeId, pdiskId)];
+ disk.VDiskId = TVDiskID(Info->GroupID, Info->GroupGeneration + 1, disk.VDiskId);
+ disk.PDiskActorId = MakeBlobStoragePDiskID(nodeId, pdiskId);
+ disk.VDiskActorId = MakeBlobStorageVDiskID(nodeId, pdiskId, vdiskSlotId);
+ disk.NodeId = nodeId;
+ disk.PDiskId = pdiskId;
+ disk.VDiskSlotId = vdiskSlotId;
+ disk.PDiskGuid = pdiskGuid;
+
+ // update group info
+ TBlobStorageGroupInfo::TTopology topology(Info->Type);
+ topology.FailRealms = Info->GetTopology().FailRealms;
+ TBlobStorageGroupInfo::TDynamicInfo dynamic(Info->GroupID, Info->GroupGeneration + 1);
+ dynamic.ServiceIdForOrderNumber = Info->GetDynamicInfo().ServiceIdForOrderNumber;
+ dynamic.ServiceIdForOrderNumber[topology.GetOrderNumber(disk.VDiskId)] = disk.VDiskActorId;
+ Info = MakeIntrusive<TBlobStorageGroupInfo>(std::move(topology), std::move(dynamic), TString(), Nothing(),
+ TPDiskCategory::DEVICE_TYPE_SSD);
+
+ StartVDisk(runtime, disk);
+
+ // update group generation for other disks
+ for (TDiskRecord& disk : Disks) {
+ if (disk.VDiskId.GroupGeneration != Info->GroupGeneration) {
+ disk.VDiskId = TVDiskID(Info->GroupID, Info->GroupGeneration, disk.VDiskId);
+ runtime.Send(new IEventHandle(disk.VDiskActorId, {}, new TEvVGenerationChange(disk.VDiskId, Info)),
+ disk.VDiskActorId.NodeId());
+ }
+ }
+
+ // update group info for proxy
+ runtime.Send(new IEventHandle(MakeBlobStorageProxyID(Info->GroupID), TActorId(),
+ new TEvBlobStorage::TEvConfigureProxy(Info, StoragePoolCounters)), 1);
+ }
+
+ void Slay(TTestActorSystem& runtime, TDiskRecord& disk) {
+ LOG_INFO_S(runtime, NActorsServices::TEST, "Slaying VDiskId# " << disk.VDiskId);
+ const TActorId& edge = runtime.AllocateEdgeActor(disk.NodeId);
+ auto slay = std::make_unique<NPDisk::TEvSlay>(disk.VDiskId, ++Round, disk.PDiskId, disk.VDiskSlotId);
+ runtime.Send(new IEventHandle(disk.PDiskActorId, edge, slay.release()), disk.NodeId);
+ auto res = runtime.WaitForEdgeActorEvent({edge});
+ if (const auto *ev = res->CastAsLocal<NPDisk::TEvSlayResult>()) {
+ Y_VERIFY_S(ev->Status == NKikimrProto::OK || ev->Status == NKikimrProto::ALREADY, "TEvSlayResult# " << ev->ToString());
+ LOG_INFO_S(runtime, NActorsServices::TEST, "Slayed VDiskId# " << disk.VDiskId);
+ } else {
+ Y_FAIL("unexpected event to edge actor");
+ }
+ }
+
+private:
+ void SetupLogging(TTestActorSystem& runtime) {
+ runtime.SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_SKELETON, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_REPL, NLog::PRI_INFO);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_ERROR);
+ runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_CRIT);
+// runtime.SetLogPriority(NKikimrServices::BS_PROXY, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_PROXY_PUT, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_QUEUE, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NActorsServices::TEST, NLog::PRI_INFO);
+ runtime.SetLogPriority(NActorsServices::TEST, NLog::PRI_DEBUG);
+ }
+
+ void SetupStorage(TTestActorSystem& runtime) {
+ TVector<TActorId> vdiskActorIds;
+
+ Disks.reserve(8 * NodeCount);
+
+ for (ui32 nodeId = 1, i = 0; nodeId <= NodeCount; ++nodeId, ++i) {
+ const ui32 pdiskId = 1;
+ const ui64 pdiskGuid = TAppData::RandomProvider->GenRand64();
+ const TPDiskCategory category(TPDiskCategory::DEVICE_TYPE_SSD, 0);
+ const TActorId& actorId = runtime.Register(CreatePDiskMockActor(MakeIntrusive<TPDiskMockState>(nodeId,
+ pdiskId, pdiskGuid, ui64(1000) << 30)), TActorId(), 0, std::nullopt, nodeId);
+ const TActorId& serviceId = MakeBlobStoragePDiskID(nodeId, pdiskId);
+ runtime.RegisterService(serviceId, actorId);
+ NodePDiskIds.emplace(nodeId, std::make_tuple(nodeId, pdiskId, pdiskGuid));
+ if (i < 8) {
+ const ui32 vdiskSlotId = ++NextVDiskSlotId[std::make_tuple(nodeId, pdiskId)];
+ const TActorId& vdiskActorId = MakeBlobStorageVDiskID(nodeId, pdiskId, vdiskSlotId);
+ vdiskActorIds.push_back(vdiskActorId);
+ const TVDiskID vdiskId(GroupId, 1, 0, i, 0);
+ Disks.push_back(TDiskRecord{
+ vdiskId,
+ serviceId,
+ vdiskActorId,
+ nodeId,
+ pdiskId,
+ vdiskSlotId,
+ pdiskGuid,
+ NKikimrBlobStorage::EVDiskStatus::INIT_PENDING,
+ });
+ StatusMap.emplace(std::make_tuple(nodeId, pdiskId, vdiskSlotId), &Disks.back().Status);
+ }
+ runtime.RegisterService(MakeBlobStorageNodeWardenID(nodeId), runtime.Register(new TNodeWardenMockActor(StatusMap),
+ TActorId(), 0, std::nullopt, nodeId));
+ }
+
+ Info = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block, 1u, 0u, 1u,
+ &vdiskActorIds, TBlobStorageGroupInfo::EEM_NONE);
+
+ for (TDiskRecord& disk : Disks) {
+ StartVDisk(runtime, disk);
+ }
+
+ auto proxy = Counters->GetSubgroup("subsystem", "proxy");
+ TIntrusivePtr<TDsProxyNodeMon> mon = MakeIntrusive<TDsProxyNodeMon>(proxy, true);
+ StoragePoolCounters = MakeIntrusive<TStoragePoolCounters>(proxy, TString(), TPDiskCategory::DEVICE_TYPE_SSD);
+ std::unique_ptr<IActor> proxyActor{CreateBlobStorageGroupProxyConfigured(TIntrusivePtr(Info), false, mon,
+ TIntrusivePtr(StoragePoolCounters), DefaultEnablePutBatching, DefaultEnableVPatch)};
+ const TActorId& actorId = runtime.Register(proxyActor.release(), TActorId(), 0, std::nullopt, 1);
+ runtime.RegisterService(MakeBlobStorageProxyID(GroupId), actorId);
+ }
+
+ void StartVDisk(TTestActorSystem& runtime, TDiskRecord& disk) {
TVDiskConfig::TBaseInfo baseInfo(disk.VDiskId, disk.PDiskActorId, disk.PDiskGuid, disk.PDiskId,
- TPDiskCategory::DEVICE_TYPE_SSD, disk.VDiskSlotId, NKikimrBlobStorage::TVDiskKind::Default, ++Round,
- TString());
- auto vdiskConfig = AllVDiskKinds->MakeVDiskConfig(baseInfo);
- vdiskConfig->EnableVDiskCooldownTimeout = true;
- auto counters = Counters->GetSubgroup("node", ToString(disk.NodeId))->GetSubgroup("vdisk", disk.VDiskId.ToString());
- const TActorId& actorId = runtime.Register(CreateVDisk(vdiskConfig, Info, counters), TActorId(), 0, std::nullopt, disk.NodeId);
- runtime.RegisterService(disk.VDiskActorId, actorId);
- disk.Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
- }
-};
-
-class TActivityActorImpl : public TActorCoroImpl {
- const ui64 TabletId;
- const ui32 GroupId;
- const ui32 MaxGen;
- TString Prefix;
- const TActorId ProxyId;
- ui32* const DoneCounter;
- ui32* const Counter;
- std::map<TLogoBlobID, TString> Committed;
- std::unordered_map<size_t, TString> Cache;
-
-public:
- TActivityActorImpl(ui64 tabletId, ui32 groupId, ui32 *doneCounter, ui32 *counter, ui32 maxGen)
- : TActorCoroImpl(65536)
- , TabletId(tabletId)
- , GroupId(groupId)
- , MaxGen(maxGen)
- , ProxyId(MakeBlobStorageProxyID(GroupId))
- , DoneCounter(doneCounter)
- , Counter(counter)
- {}
-
- void Run() override {
- for (ui32 generation = 1; generation <= MaxGen && generation; ++generation) {
- Prefix = TStringBuilder() << "[" << TabletId << ":" << generation << "@" << GroupId << "]";
- LOG_INFO_S(GetActorContext(), NActorsServices::TEST, Prefix << " running generation# " << generation);
- RunCycle(generation);
- }
- LOG_INFO_S(GetActorContext(), NActorsServices::TEST, Prefix << " done");
- ++*DoneCounter;
- }
-
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
- }
-
- template<typename TEvent, typename... TArgs>
- TAutoPtr<TEventHandle<TResultFor<TEvent>>> Query(TArgs&&... args) {
- auto q = std::make_unique<TEvent>(std::forward<TArgs>(args)...);
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending " << TypeName<TEvent>() << "# "
- << q->Print(false));
- GetActorSystem()->Schedule(TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100)),
- new IEventHandle(ProxyId, SelfActorId, q.release()));
- ++*Counter;
- auto ev = WaitForSpecificEvent<TResultFor<TEvent>>();
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received "
- << TypeName<TResultFor<TEvent>>() << "# " << ev->Get()->Print(false));
- return ev;
- }
-
- void RunCycle(ui32 generation) {
- // wait for disks to get ready
- while (auto ev = Query<TEvBlobStorage::TEvStatus>(TInstant::Max())) {
- if (ev->Get()->Status == NKikimrProto::OK) {
- break;
- }
- }
-
- // set a block for current generation
- if (auto ev = Query<TEvBlobStorage::TEvBlock>(TabletId, generation - 1, TInstant::Max())) {
- const auto& status = ev->Get()->Status;
- Y_VERIFY_S(status == NKikimrProto::OK || status == NKikimrProto::RACE,
- "TEvBlockResult# " << ev->Get()->Print(false));
- }
-
- // discover previously written data
- if (auto ev = Query<TEvBlobStorage::TEvDiscover>(TabletId, 0, true, false, TInstant::Max(), 0)) {
- Y_VERIFY(ev->Get()->Status == (Committed.empty() ? NKikimrProto::NODATA : NKikimrProto::OK));
- if (ev->Get()->Status == NKikimrProto::OK) {
- Y_VERIFY(ev->Get()->Buffer == Committed.rbegin()->second);
- }
- }
-
- // issue range read
- const TLogoBlobID from(TabletId, generation - 1, 0, 0, 0, 0);
- const TLogoBlobID to(TabletId, generation - 1, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
- std::deque<TLogoBlobID> readQueue;
- if (auto ev = Query<TEvBlobStorage::TEvRange>(TabletId, from, to, true, TInstant::Max(), true)) {
- Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
- for (const auto& response : ev->Get()->Responses) {
- readQueue.push_back(response.Id);
- }
- }
-
- // issue gets from the read queue
- ui32 readsInFlight = 0;
- const ui32 maxReadsInFlight = 3;
- TInstant nextSendTimestamp;
- while (readsInFlight || !readQueue.empty()) {
- const TInstant now = TActorCoroImpl::Now();
- if (readQueue.size() && now >= nextSendTimestamp && readsInFlight < maxReadsInFlight) {
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(readQueue.front(), 0, 0, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, true, false);
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending TEvGet# " << ev->Print(false));
- nextSendTimestamp = now + TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100));
- Send(ProxyId, ev.release());
- ++*Counter;
- readQueue.pop_front();
- ++readsInFlight;
- } else if (auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>(nextSendTimestamp)) {
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received TEvGetResult# " << ev->Get()->Print(false));
- Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
- for (ui32 i = 0; i < ev->Get()->ResponseSz; ++i) {
- const auto& response = ev->Get()->Responses[i];
- Y_VERIFY(response.Status == NKikimrProto::OK);
- const auto it = Committed.find(response.Id);
- Y_VERIFY(it != Committed.end());
- Y_VERIFY(it->second == response.Buffer);
- Committed.erase(it);
- }
- --readsInFlight;
- }
- }
- auto filter = [](const auto& item) { return item.first.ToString(); };
- Y_VERIFY_S(Committed.empty(), Prefix << " missing blobs# " << FormatList(FilterContainer(Committed, filter)));
-
- // set up a barrier
- if (generation != 1) {
- if (auto ev = Query<TEvBlobStorage::TEvCollectGarbage>(TabletId, generation, 0, 0, true, generation - 1,
- Max<ui32>(), nullptr, nullptr, TInstant::Max(), false)) {
- Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
- }
- }
-
- // begin putting
- std::map<TLogoBlobID, TString> writesInFlight;
- const ui32 maxWritesInFlight = 3;
- ui32 numWritesRemain = TAppData::RandomProvider->Uniform(100, 201);
- ui32 step = 1;
- while (writesInFlight.size() || numWritesRemain) {
- const TInstant now = TActorCoroImpl::Now();
- if (numWritesRemain && now >= nextSendTimestamp && writesInFlight.size() < maxWritesInFlight) {
- TString buffer = GenerateRandomBuffer(Cache);
- const TLogoBlobID id(TabletId, generation, step++, 0, buffer.size(), 0);
- auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max());
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending TEvPut# " << ev->Print(false));
- nextSendTimestamp = now + TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100));
- Send(ProxyId, ev.release());
- ++*Counter;
- writesInFlight.emplace(id, std::move(buffer));
- --numWritesRemain;
- } else if (auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvPutResult>(nextSendTimestamp)) {
- LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received TEvPutResult# " << ev->Get()->Print(false)
- << " writesInFlight.size# " << writesInFlight.size());
- Y_VERIFY_S(ev->Get()->Status == NKikimrProto::OK, "TEvPutResult# " << ev->Get()->Print(false));
- const auto it = writesInFlight.find(ev->Get()->Id);
- Y_VERIFY(it != writesInFlight.end());
- Committed.insert(writesInFlight.extract(it));
- }
- }
- }
-};
-
-Y_UNIT_TEST_SUITE(GroupStress) {
- Y_UNIT_TEST(Test) {
- TAppData::RandomProvider = CreateDeterministicRandomProvider(1);
- SetRandomSeed(1);
- TTestEnv env(9);
- env.Run([&](TTestActorSystem& runtime) {
- env.WaitReady(runtime); // wait for all disks to become ready
-
- const bool infinite = GetEnv("INFINITE", "no") == "yes";
-
- ui64 tabletId = 1;
- ui32 numTablets = 125;
- ui32 done = 0;
- ui32 counter = 0;
- for (ui32 i = 0; i < numTablets; ++i) {
- auto actor = MakeHolder<TActivityActorImpl>(tabletId++, env.GroupId, &done, &counter,
- infinite ? Max<ui32>() : 3);
- runtime.Register(new TActorCoro(std::move(actor)), TActorId(), 0, std::nullopt, 1);
- }
-
- ui32 obscenityCounter = 0;
- ui32 backoff = 128;
-
- using TCondition = std::function<bool()>;
- using TAction = std::function<void()>;
- std::deque<std::pair<TCondition, TAction>> map;
- bool exit = false;
- ui32 allowReformatCounter = 0;
- map.emplace_back([&] { return done == numTablets; }, [&] { exit = true; });
- map.emplace_back([&] { return counter > obscenityCounter + backoff; }, [&] {
- if (env.DoObscenity(runtime, &allowReformatCounter)) {
- backoff = 128;
- } else {
- backoff = Min<ui32>(1024, backoff * 2);
- }
- obscenityCounter = counter;
- });
-
- ui64 lastEventsProcessed = 0;
-
- auto dump = [&] {
- Cerr << Endl;
- Cerr << "Actor count @ EventsProcessed# " << runtime.GetEventsProcessed() << Endl;
- runtime.DumpActorCount(Cerr, " ", "\n");
- Cerr << Endl;
- };
-
- do {
- runtime.Sim([&] {
- for (auto& [condition, action] : map) {
- if (condition()) {
- return false;
- }
- }
- return true;
- });
- if (infinite && runtime.GetEventsProcessed() >= lastEventsProcessed + 100000) {
- lastEventsProcessed = runtime.GetEventsProcessed();
- dump();
- }
- for (auto& [condition, action] : map) {
- if (condition()) {
- action();
- }
- }
- } while (!exit);
- });
- }
-}
+ TPDiskCategory::DEVICE_TYPE_SSD, disk.VDiskSlotId, NKikimrBlobStorage::TVDiskKind::Default, ++Round,
+ TString());
+ auto vdiskConfig = AllVDiskKinds->MakeVDiskConfig(baseInfo);
+ vdiskConfig->EnableVDiskCooldownTimeout = true;
+ auto counters = Counters->GetSubgroup("node", ToString(disk.NodeId))->GetSubgroup("vdisk", disk.VDiskId.ToString());
+ const TActorId& actorId = runtime.Register(CreateVDisk(vdiskConfig, Info, counters), TActorId(), 0, std::nullopt, disk.NodeId);
+ runtime.RegisterService(disk.VDiskActorId, actorId);
+ disk.Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+ }
+};
+
+class TActivityActorImpl : public TActorCoroImpl {
+ const ui64 TabletId;
+ const ui32 GroupId;
+ const ui32 MaxGen;
+ TString Prefix;
+ const TActorId ProxyId;
+ ui32* const DoneCounter;
+ ui32* const Counter;
+ std::map<TLogoBlobID, TString> Committed;
+ std::unordered_map<size_t, TString> Cache;
+
+public:
+ TActivityActorImpl(ui64 tabletId, ui32 groupId, ui32 *doneCounter, ui32 *counter, ui32 maxGen)
+ : TActorCoroImpl(65536)
+ , TabletId(tabletId)
+ , GroupId(groupId)
+ , MaxGen(maxGen)
+ , ProxyId(MakeBlobStorageProxyID(GroupId))
+ , DoneCounter(doneCounter)
+ , Counter(counter)
+ {}
+
+ void Run() override {
+ for (ui32 generation = 1; generation <= MaxGen && generation; ++generation) {
+ Prefix = TStringBuilder() << "[" << TabletId << ":" << generation << "@" << GroupId << "]";
+ LOG_INFO_S(GetActorContext(), NActorsServices::TEST, Prefix << " running generation# " << generation);
+ RunCycle(generation);
+ }
+ LOG_INFO_S(GetActorContext(), NActorsServices::TEST, Prefix << " done");
+ ++*DoneCounter;
+ }
+
+ void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
+ }
+
+ template<typename TEvent, typename... TArgs>
+ TAutoPtr<TEventHandle<TResultFor<TEvent>>> Query(TArgs&&... args) {
+ auto q = std::make_unique<TEvent>(std::forward<TArgs>(args)...);
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending " << TypeName<TEvent>() << "# "
+ << q->Print(false));
+ GetActorSystem()->Schedule(TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100)),
+ new IEventHandle(ProxyId, SelfActorId, q.release()));
+ ++*Counter;
+ auto ev = WaitForSpecificEvent<TResultFor<TEvent>>();
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received "
+ << TypeName<TResultFor<TEvent>>() << "# " << ev->Get()->Print(false));
+ return ev;
+ }
+
+ void RunCycle(ui32 generation) {
+ // wait for disks to get ready
+ while (auto ev = Query<TEvBlobStorage::TEvStatus>(TInstant::Max())) {
+ if (ev->Get()->Status == NKikimrProto::OK) {
+ break;
+ }
+ }
+
+ // set a block for current generation
+ if (auto ev = Query<TEvBlobStorage::TEvBlock>(TabletId, generation - 1, TInstant::Max())) {
+ const auto& status = ev->Get()->Status;
+ Y_VERIFY_S(status == NKikimrProto::OK || status == NKikimrProto::RACE,
+ "TEvBlockResult# " << ev->Get()->Print(false));
+ }
+
+ // discover previously written data
+ if (auto ev = Query<TEvBlobStorage::TEvDiscover>(TabletId, 0, true, false, TInstant::Max(), 0)) {
+ Y_VERIFY(ev->Get()->Status == (Committed.empty() ? NKikimrProto::NODATA : NKikimrProto::OK));
+ if (ev->Get()->Status == NKikimrProto::OK) {
+ Y_VERIFY(ev->Get()->Buffer == Committed.rbegin()->second);
+ }
+ }
+
+ // issue range read
+ const TLogoBlobID from(TabletId, generation - 1, 0, 0, 0, 0);
+ const TLogoBlobID to(TabletId, generation - 1, Max<ui32>(), 0, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
+ std::deque<TLogoBlobID> readQueue;
+ if (auto ev = Query<TEvBlobStorage::TEvRange>(TabletId, from, to, true, TInstant::Max(), true)) {
+ Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
+ for (const auto& response : ev->Get()->Responses) {
+ readQueue.push_back(response.Id);
+ }
+ }
+
+ // issue gets from the read queue
+ ui32 readsInFlight = 0;
+ const ui32 maxReadsInFlight = 3;
+ TInstant nextSendTimestamp;
+ while (readsInFlight || !readQueue.empty()) {
+ const TInstant now = TActorCoroImpl::Now();
+ if (readQueue.size() && now >= nextSendTimestamp && readsInFlight < maxReadsInFlight) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(readQueue.front(), 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, true, false);
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending TEvGet# " << ev->Print(false));
+ nextSendTimestamp = now + TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100));
+ Send(ProxyId, ev.release());
+ ++*Counter;
+ readQueue.pop_front();
+ ++readsInFlight;
+ } else if (auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvGetResult>(nextSendTimestamp)) {
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received TEvGetResult# " << ev->Get()->Print(false));
+ Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
+ for (ui32 i = 0; i < ev->Get()->ResponseSz; ++i) {
+ const auto& response = ev->Get()->Responses[i];
+ Y_VERIFY(response.Status == NKikimrProto::OK);
+ const auto it = Committed.find(response.Id);
+ Y_VERIFY(it != Committed.end());
+ Y_VERIFY(it->second == response.Buffer);
+ Committed.erase(it);
+ }
+ --readsInFlight;
+ }
+ }
+ auto filter = [](const auto& item) { return item.first.ToString(); };
+ Y_VERIFY_S(Committed.empty(), Prefix << " missing blobs# " << FormatList(FilterContainer(Committed, filter)));
+
+ // set up a barrier
+ if (generation != 1) {
+ if (auto ev = Query<TEvBlobStorage::TEvCollectGarbage>(TabletId, generation, 0, 0, true, generation - 1,
+ Max<ui32>(), nullptr, nullptr, TInstant::Max(), false)) {
+ Y_VERIFY(ev->Get()->Status == NKikimrProto::OK);
+ }
+ }
+
+ // begin putting
+ std::map<TLogoBlobID, TString> writesInFlight;
+ const ui32 maxWritesInFlight = 3;
+ ui32 numWritesRemain = TAppData::RandomProvider->Uniform(100, 201);
+ ui32 step = 1;
+ while (writesInFlight.size() || numWritesRemain) {
+ const TInstant now = TActorCoroImpl::Now();
+ if (numWritesRemain && now >= nextSendTimestamp && writesInFlight.size() < maxWritesInFlight) {
+ TString buffer = GenerateRandomBuffer(Cache);
+ const TLogoBlobID id(TabletId, generation, step++, 0, buffer.size(), 0);
+ auto ev = std::make_unique<TEvBlobStorage::TEvPut>(id, buffer, TInstant::Max());
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " sending TEvPut# " << ev->Print(false));
+ nextSendTimestamp = now + TDuration::MicroSeconds(TAppData::RandomProvider->Uniform(10, 100));
+ Send(ProxyId, ev.release());
+ ++*Counter;
+ writesInFlight.emplace(id, std::move(buffer));
+ --numWritesRemain;
+ } else if (auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvPutResult>(nextSendTimestamp)) {
+ LOG_DEBUG_S(GetActorContext(), NActorsServices::TEST, Prefix << " received TEvPutResult# " << ev->Get()->Print(false)
+ << " writesInFlight.size# " << writesInFlight.size());
+ Y_VERIFY_S(ev->Get()->Status == NKikimrProto::OK, "TEvPutResult# " << ev->Get()->Print(false));
+ const auto it = writesInFlight.find(ev->Get()->Id);
+ Y_VERIFY(it != writesInFlight.end());
+ Committed.insert(writesInFlight.extract(it));
+ }
+ }
+ }
+};
+
+Y_UNIT_TEST_SUITE(GroupStress) {
+ Y_UNIT_TEST(Test) {
+ TAppData::RandomProvider = CreateDeterministicRandomProvider(1);
+ SetRandomSeed(1);
+ TTestEnv env(9);
+ env.Run([&](TTestActorSystem& runtime) {
+ env.WaitReady(runtime); // wait for all disks to become ready
+
+ const bool infinite = GetEnv("INFINITE", "no") == "yes";
+
+ ui64 tabletId = 1;
+ ui32 numTablets = 125;
+ ui32 done = 0;
+ ui32 counter = 0;
+ for (ui32 i = 0; i < numTablets; ++i) {
+ auto actor = MakeHolder<TActivityActorImpl>(tabletId++, env.GroupId, &done, &counter,
+ infinite ? Max<ui32>() : 3);
+ runtime.Register(new TActorCoro(std::move(actor)), TActorId(), 0, std::nullopt, 1);
+ }
+
+ ui32 obscenityCounter = 0;
+ ui32 backoff = 128;
+
+ using TCondition = std::function<bool()>;
+ using TAction = std::function<void()>;
+ std::deque<std::pair<TCondition, TAction>> map;
+ bool exit = false;
+ ui32 allowReformatCounter = 0;
+ map.emplace_back([&] { return done == numTablets; }, [&] { exit = true; });
+ map.emplace_back([&] { return counter > obscenityCounter + backoff; }, [&] {
+ if (env.DoObscenity(runtime, &allowReformatCounter)) {
+ backoff = 128;
+ } else {
+ backoff = Min<ui32>(1024, backoff * 2);
+ }
+ obscenityCounter = counter;
+ });
+
+ ui64 lastEventsProcessed = 0;
+
+ auto dump = [&] {
+ Cerr << Endl;
+ Cerr << "Actor count @ EventsProcessed# " << runtime.GetEventsProcessed() << Endl;
+ runtime.DumpActorCount(Cerr, " ", "\n");
+ Cerr << Endl;
+ };
+
+ do {
+ runtime.Sim([&] {
+ for (auto& [condition, action] : map) {
+ if (condition()) {
+ return false;
+ }
+ }
+ return true;
+ });
+ if (infinite && runtime.GetEventsProcessed() >= lastEventsProcessed + 100000) {
+ lastEventsProcessed = runtime.GetEventsProcessed();
+ dump();
+ }
+ for (auto& [condition, action] : map) {
+ if (condition()) {
+ action();
+ }
+ }
+ } while (!exit);
+ });
+ }
+}
diff --git a/ydb/core/blobstorage/ut_group/ya.make b/ydb/core/blobstorage/ut_group/ya.make
index 679d582ee1c..d3125dc661f 100644
--- a/ydb/core/blobstorage/ut_group/ya.make
+++ b/ydb/core/blobstorage/ut_group/ya.make
@@ -1,13 +1,13 @@
-UNITTEST()
-
+UNITTEST()
+
OWNER(g:kikimr)
-
+
IF (NOT WITH_VALGRIND)
SRCS(
main.cpp
- )
+ )
ENDIF()
-
+
IF (SANITIZER_TYPE)
TIMEOUT(3600)
SIZE(LARGE)
@@ -30,4 +30,4 @@ PEERDIR(
ydb/core/util
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_mirror3of4/main.cpp b/ydb/core/blobstorage/ut_mirror3of4/main.cpp
index 071a2852ddd..2cb413dcb90 100644
--- a/ydb/core/blobstorage/ut_mirror3of4/main.cpp
+++ b/ydb/core/blobstorage/ut_mirror3of4/main.cpp
@@ -1,5 +1,5 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/core/actor_coroutine.h>
+#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/actors/core/actor_coroutine.h>
#include <ydb/core/util/testactorsys.h>
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
@@ -8,395 +8,395 @@
#include <ydb/core/blobstorage/vdisk/common/vdisk_config.h>
#include <ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
-
-using namespace NActors;
-using namespace NKikimr;
-
-class TTestEnv {
-public:
- struct TPDisk {
- ui32 NodeId;
- ui32 PDiskId;
- ui64 PDiskGuid;
- TPDiskMockState::TPtr State;
- };
-
- const TBlobStorageGroupType GType;
- const ui32 NodeCount;
- std::vector<TPDisk> PDisks;
-
- TIntrusivePtr<TBlobStorageGroupInfo> CreateGroupInfo(const std::set<ui32>& nodeIds) const {
- UNIT_ASSERT_VALUES_EQUAL(nodeIds.size(), GType.BlobSubgroupSize());
- TVector<TActorId> vdiskIds;
- for (ui32 nodeId : nodeIds) {
- vdiskIds.push_back(MakeBlobStorageVDiskID(nodeId, 1, 0));
- }
- return MakeIntrusive<TBlobStorageGroupInfo>(GType, 1U, 0U, 1U, &vdiskIds);
- }
-
- void FormatDisk(ui32 index) {
- TPDisk& pdisk = PDisks[index];
- pdisk.State = MakeIntrusive<TPDiskMockState>(pdisk.NodeId, pdisk.PDiskId, pdisk.PDiskGuid, ui64(10) << 40);
- }
-
- TTestEnv(TBlobStorageGroupType gtype)
- : GType(gtype)
- , NodeCount(gtype.BlobSubgroupSize())
- , PDisks(NodeCount)
- , Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
- {
- for (ui32 i = 0; i < PDisks.size(); ++i) {
- PDisks[i] = {i + 1, 1, RandomNumber<ui64>(), nullptr};
- FormatDisk(i);
- }
- }
-
- class TCoro;
-
- enum {
- EvTestFinished = EventSpaceBegin(TEvents::ES_PRIVATE)
- };
- struct TEvTestFinished : TEventLocal<TEvTestFinished, EvTestFinished> {
- std::exception_ptr Exception;
-
- TEvTestFinished(std::exception_ptr exception)
- : Exception(std::move(exception))
- {}
- };
-
- void Run(std::function<void(TCoro*)> fn) {
- TTestActorSystem runtime(NodeCount);
- SetupLogging(runtime);
- runtime.Start();
- SetupStorage(runtime);
-
- const TActorId edge = runtime.AllocateEdgeActor(1);
- auto coro = MakeHolder<TCoro>(*this, std::move(fn), edge);
- UNIT_ASSERT(!CurrentCoro);
- CurrentCoro = coro.Get();
- runtime.Register(new TActorCoro(std::move(coro)), TActorId(), 0, std::nullopt, 1);
- auto ev = runtime.WaitForEdgeActorEvent({edge});
- CurrentCoro = nullptr;
-
- runtime.Stop();
-
- if (const auto& exception = ev->CastAsLocal<TEvTestFinished>()->Exception) {
- std::rethrow_exception(exception);
- }
- }
-
- class TCoro : public TActorCoroImpl {
- TTestEnv& Env;
- std::function<void(TCoro*)> Fn;
- const TActorId Edge;
- std::map<ui32, TActorId> Backpressure;
-
- public:
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
-
- public:
- TCoro(TTestEnv& env, std::function<void(TCoro*)>&& fn, const TActorId& edge)
- : TActorCoroImpl(65536)
- , Env(env)
- , Fn(std::move(fn))
- , Edge(edge)
- , Info(env.Info)
- {}
-
- void Run() override {
- std::exception_ptr exception;
- try {
- Fn(this);
- } catch (const TDtorException&) {
- return; // coroutine terminated from outside
- } catch (...) {
- exception = std::current_exception();
- }
- Send(Edge, new TEvTestFinished(exception));
- }
-
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> /*ev*/) override {
- UNIT_ASSERT(false);
- }
-
- TActorId GetBackpressureFor(ui32 diskOrderNum) {
- auto& res = Backpressure[diskOrderNum];
- if (res == TActorId()) {
- // create BS_QUEUE to this disk
- auto counters = Env.Counters->GetSubgroup("bsqueue", ToString(diskOrderNum));
- auto bspctx = MakeIntrusive<TBSProxyContext>(counters->GetSubgroup("subsystem", "memory"));
- auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
- res = Register(CreateVDiskBackpressureClient(Info, Info->GetVDiskId(diskOrderNum),
- NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, counters, bspctx,
- NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::VDiskLoad, 0), "queue", 0, false,
- TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
- }
- return res;
- }
-
- std::set<TVDiskID> GetVDiskSet() const {
- std::set<TVDiskID> vdisks;
- for (ui32 i = 0; i < Info->GetTotalVDisksNum(); ++i) {
- vdisks.insert(Info->GetVDiskId(i));
- }
- return vdisks;
- }
-
- void CreateQueuesAndWaitForReady() {
- for (ui32 i = 0; i < Info->GetTotalVDisksNum(); ++i) {
- GetBackpressureFor(i);
- }
- auto vdisks = GetVDiskSet();
- while (!vdisks.empty()) {
- auto ev = WaitForSpecificEvent<TEvProxyQueueState>();
- auto& msg = *ev->Get();
- UNIT_ASSERT(msg.IsConnected);
- const bool erased = vdisks.erase(msg.VDiskId);
- UNIT_ASSERT(erased);
- }
- }
-
- void WaitForRepl() {
- auto vdisks = GetVDiskSet();
- while (!vdisks.empty()) {
- for (const TVDiskID& vdiskId : vdisks) {
- Send(Info->GetActorId(Info->GetOrderNumber(vdiskId)), new TEvBlobStorage::TEvVStatus(vdiskId));
- }
- for (size_t num = vdisks.size(); num; --num) {
- auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVStatusResult>();
- auto& record = ev->Get()->Record;
- if (record.GetStatus() == NKikimrProto::OK && record.GetReplicated()) {
- const bool erased = vdisks.erase(VDiskIDFromVDiskID(record.GetVDiskID()));
- UNIT_ASSERT(erased);
- }
- }
- if (!vdisks.empty()) {
- Sleep(TDuration::Seconds(15));
- }
- }
- }
-
- void Sleep(TDuration timeout) {
- Schedule(timeout, new TEvents::TEvWakeup);
- WaitForSpecificEvent<TEvents::TEvWakeup>();
- }
-
- NKikimrProto::EReplyStatus Put(const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& data) {
- Send(GetBackpressureFor(Info->GetOrderNumber(vdiskId)), new TEvBlobStorage::TEvVPut(blobId, data, vdiskId,
- false, nullptr, TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog));
- auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVPutResult>();
- auto& record = ev->Get()->Record;
- UNIT_ASSERT_VALUES_EQUAL(vdiskId, VDiskIDFromVDiskID(record.GetVDiskID()));
- return record.GetStatus();
- }
-
- struct TGotItem {
- NKikimrProto::EReplyStatus Status;
- std::optional<TIngress> Ingress;
- std::optional<TString> Data;
-
- TGotItem(const NKikimrBlobStorage::TQueryResult& pb)
- : Status(pb.GetStatus())
- , Ingress(pb.HasIngress() ? std::make_optional(TIngress(pb.GetIngress())) : std::nullopt)
- , Data(pb.HasBuffer() ? std::make_optional(pb.GetBuffer()) : std::nullopt)
- {
- UNIT_ASSERT(pb.HasStatus());
- }
- };
- using TGetResult = std::map<TLogoBlobID, TGotItem>;
-
- TGetResult GetRange(const TVDiskID& vdiskId, const TLogoBlobID& from, const TLogoBlobID& to) {
- return Get(vdiskId, TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
- Nothing(), from, to));
- }
-
- TGetResult GetExtr(const TVDiskID& vdiskId, const TLogoBlobID& blobId) {
- return Get(vdiskId, TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
- Nothing(), {{blobId}}));
- }
-
- TGetResult Get(const TVDiskID& vdiskId, std::unique_ptr<TEvBlobStorage::TEvVGet>&& query) {
- Send(GetBackpressureFor(Info->GetOrderNumber(vdiskId)), query.release());
- auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
- auto& record = ev->Get()->Record;
- TGetResult res;
- for (const auto& item : record.GetResult()) {
- const bool inserted = res.emplace(LogoBlobIDFromLogoBlobID(item.GetBlobID()), TGotItem(item)).second;
- UNIT_ASSERT(inserted); // blob ids should not repeat
- }
- return res;
- }
- };
-
-public:
- TCoro *CurrentCoro = nullptr;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
-
-private:
- void SetupLogging(TTestActorSystem& runtime) {
- runtime.SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_DEBUG);
- runtime.SetLogPriority(NKikimrServices::BS_SKELETON, NLog::PRI_INFO);
- runtime.SetLogPriority(NKikimrServices::BS_LOCALRECOVERY, NLog::PRI_DEBUG);
- runtime.SetLogPriority(NKikimrServices::BS_VDISK_PUT, NLog::PRI_INFO);
- runtime.SetLogPriority(NKikimrServices::BS_VDISK_GET, NLog::PRI_DEBUG);
- runtime.SetLogPriority(NKikimrServices::BS_REPL, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_QUEUE, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_DEBUG);
-// runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_DEBUG);
- }
-
- void SetupStorage(TTestActorSystem& runtime) {
- Info = CreateGroupInfo(runtime.GetNodes());
- const TBlobStorageGroupInfo& info = *Info;
-
- for (ui32 i = 0; i < info.GetTotalVDisksNum(); ++i) {
- // create pdisk
- TPDisk& pdisk = PDisks[i];
- const TActorId pdiskActorId = MakeBlobStoragePDiskID(pdisk.NodeId, pdisk.PDiskId);
- runtime.RegisterService(pdiskActorId, runtime.Register(CreatePDiskMockActor(pdisk.State), TActorId(), 0,
- std::nullopt, pdisk.NodeId));
-
- // create vdisk
- TVDiskConfig::TBaseInfo baseInfo(
- info.GetVDiskId(i),
- pdiskActorId,
- pdisk.PDiskGuid,
- pdisk.PDiskId,
- TPDiskCategory::DEVICE_TYPE_SSD,
- 0,
- NKikimrBlobStorage::TVDiskKind::Default,
- 2, // InitOwnerRound
- ""
- );
- const auto vcfg = MakeIntrusive<TVDiskConfig>(baseInfo);
- auto vdiskCounters = Counters->GetSubgroup("vdisk", ToString(i));
- runtime.RegisterService(info.GetActorId(i), runtime.Register(CreateVDisk(vcfg, Info, vdiskCounters),
- TActorId(), 0, std::nullopt, pdisk.NodeId));
- }
- }
-
-private:
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
-};
-
-void ReplicationTest(const TString datum) {
- TTestEnv env(TBlobStorageGroupType::ErasureMirror3of4);
- const TLogoBlobID blobId(1, 1, 1, 0, datum.size(), 0);
- std::map<ui32, std::vector<ui8>> diskToParts = {{0, {1}}, {1, {2}}, {2, {1}}, {3, {3}}, {4, {3}}, {5, {2, 3}}};
- auto checkPartsInPlace = [&](auto *coro) {
- for (ui32 i = 0; i < coro->Info->GetTotalVDisksNum(); ++i) {
- auto res = coro->GetExtr(coro->Info->GetVDiskId(i), blobId);
- if (const auto it = diskToParts.find(i); it != diskToParts.end()) {
- const std::vector<ui8>& parts = it->second;
- std::set<ui8> m(parts.begin(), parts.end());
- for (const auto& [key, value] : res) {
- UNIT_ASSERT_VALUES_EQUAL(key.FullID(), blobId);
- UNIT_ASSERT(m.count(key.PartId()));
- m.erase(key.PartId());
- UNIT_ASSERT_VALUES_EQUAL(value.Status, NKikimrProto::OK);
- UNIT_ASSERT(value.Data);
- UNIT_ASSERT_VALUES_EQUAL(*value.Data, key.PartId() < 3 ? datum : TString());
- }
- UNIT_ASSERT(m.empty());
- } else {
- auto& [key, value] = *res.begin();
- UNIT_ASSERT_VALUES_EQUAL(res.size(), 1);
- UNIT_ASSERT_VALUES_EQUAL(key, blobId);
- UNIT_ASSERT_VALUES_EQUAL(value.Status, NKikimrProto::NODATA);
- }
- }
- };
- env.Run([&](auto *coro) {
- coro->CreateQueuesAndWaitForReady();
- for (const auto& [diskOrderNum, partIds] : diskToParts) {
- for (const ui8 partId : partIds) {
- UNIT_ASSERT_VALUES_EQUAL(coro->Put(coro->Info->GetVDiskId(diskOrderNum), TLogoBlobID(blobId, partId),
- partId < 3 ? datum : TString()), NKikimrProto::OK);
- }
- }
- TIngress required;
- for (const auto& [diskOrderNum, partIds] : diskToParts) {
- for (const ui8 partId : partIds) {
- const TVDiskID& vdiskId = coro->Info->GetVDiskId(diskOrderNum);
- const TLogoBlobID id(blobId, partId);
- required.Merge(*TIngress::CreateIngressWOLocal(&coro->Info->GetTopology(), vdiskId, id));
- }
- }
- for (;;) {
- bool done = true;
- TStringStream msgs;
- for (const auto& [diskOrderNum, partIds] : diskToParts) {
- for (const ui8 partId : partIds) {
- const TVDiskID& vdiskId = coro->Info->GetVDiskId(diskOrderNum);
- const TLogoBlobID id(blobId, partId);
- auto allres = coro->GetExtr(vdiskId, id);
- UNIT_ASSERT_VALUES_EQUAL(allres.size(), 1);
- const auto& res = allres.begin()->second;
- UNIT_ASSERT(res.Ingress);
- TIngress ingr(*res.Ingress);
- ingr = ingr.CopyWithoutLocal(coro->Info->Type);
- if (ingr.Raw() != required.Raw()) {
- done = false;
- }
- msgs << "*** " << vdiskId << " " << id << " "
- << ingr.ToString(&coro->Info->GetTopology(), vdiskId, id) << " <> "
- << required.ToString(&coro->Info->GetTopology(), vdiskId, id)
- << Endl;
- }
- }
- Cerr << Endl << msgs.Str() << Endl;
- if (done) {
- break;
- } else {
- coro->Sleep(TDuration::Seconds(10));
- }
- }
- checkPartsInPlace(coro);
- });
- Cerr << Endl << "*** rechecking data after restart" << Endl << Endl;
- env.Run([&](auto *coro) {
- coro->CreateQueuesAndWaitForReady();
- checkPartsInPlace(coro);
- });
- for (ui32 diskIdx = 0; diskIdx < env.GType.BlobSubgroupSize(); ++diskIdx) {
- Cerr << Endl << "*** formatting disk " << diskIdx << Endl << Endl;
- env.FormatDisk(diskIdx);
- env.Run([&](auto *coro) {
- coro->CreateQueuesAndWaitForReady();
- coro->WaitForRepl();
- checkPartsInPlace(coro);
- });
- }
- for (ui32 diskIdx = 0; diskIdx < env.GType.BlobSubgroupSize(); ++diskIdx) {
- for (ui32 diskIdx1 = 0; diskIdx1 < diskIdx; ++diskIdx1) {
- Cerr << Endl << "*** formatting disks " << diskIdx << ", " << diskIdx1 << Endl << Endl;
- env.FormatDisk(diskIdx);
- env.FormatDisk(diskIdx1);
- env.Run([&](auto *coro) {
- coro->CreateQueuesAndWaitForReady();
- coro->WaitForRepl();
- checkPartsInPlace(coro);
- });
- }
- }
-}
-
-Y_UNIT_TEST_SUITE(Mirror3of4) {
-
- Y_UNIT_TEST(ReplicationSmall) {
- ReplicationTest("hello, world!");
- }
-
- Y_UNIT_TEST(ReplicationHuge) {
- ui32 size = 1 << 20;
- TString datum = TString::Uninitialized(size);
- char *p = datum.Detach();
- for (ui32 i = 0; i < size; ++i) {
- p[i] = i;
- }
- ReplicationTest(datum);
- }
-
-}
+
+using namespace NActors;
+using namespace NKikimr;
+
+class TTestEnv {
+public:
+ struct TPDisk {
+ ui32 NodeId;
+ ui32 PDiskId;
+ ui64 PDiskGuid;
+ TPDiskMockState::TPtr State;
+ };
+
+ const TBlobStorageGroupType GType;
+ const ui32 NodeCount;
+ std::vector<TPDisk> PDisks;
+
+ TIntrusivePtr<TBlobStorageGroupInfo> CreateGroupInfo(const std::set<ui32>& nodeIds) const {
+ UNIT_ASSERT_VALUES_EQUAL(nodeIds.size(), GType.BlobSubgroupSize());
+ TVector<TActorId> vdiskIds;
+ for (ui32 nodeId : nodeIds) {
+ vdiskIds.push_back(MakeBlobStorageVDiskID(nodeId, 1, 0));
+ }
+ return MakeIntrusive<TBlobStorageGroupInfo>(GType, 1U, 0U, 1U, &vdiskIds);
+ }
+
+ void FormatDisk(ui32 index) {
+ TPDisk& pdisk = PDisks[index];
+ pdisk.State = MakeIntrusive<TPDiskMockState>(pdisk.NodeId, pdisk.PDiskId, pdisk.PDiskGuid, ui64(10) << 40);
+ }
+
+ TTestEnv(TBlobStorageGroupType gtype)
+ : GType(gtype)
+ , NodeCount(gtype.BlobSubgroupSize())
+ , PDisks(NodeCount)
+ , Counters(MakeIntrusive<NMonitoring::TDynamicCounters>())
+ {
+ for (ui32 i = 0; i < PDisks.size(); ++i) {
+ PDisks[i] = {i + 1, 1, RandomNumber<ui64>(), nullptr};
+ FormatDisk(i);
+ }
+ }
+
+ class TCoro;
+
+ enum {
+ EvTestFinished = EventSpaceBegin(TEvents::ES_PRIVATE)
+ };
+ struct TEvTestFinished : TEventLocal<TEvTestFinished, EvTestFinished> {
+ std::exception_ptr Exception;
+
+ TEvTestFinished(std::exception_ptr exception)
+ : Exception(std::move(exception))
+ {}
+ };
+
+ void Run(std::function<void(TCoro*)> fn) {
+ TTestActorSystem runtime(NodeCount);
+ SetupLogging(runtime);
+ runtime.Start();
+ SetupStorage(runtime);
+
+ const TActorId edge = runtime.AllocateEdgeActor(1);
+ auto coro = MakeHolder<TCoro>(*this, std::move(fn), edge);
+ UNIT_ASSERT(!CurrentCoro);
+ CurrentCoro = coro.Get();
+ runtime.Register(new TActorCoro(std::move(coro)), TActorId(), 0, std::nullopt, 1);
+ auto ev = runtime.WaitForEdgeActorEvent({edge});
+ CurrentCoro = nullptr;
+
+ runtime.Stop();
+
+ if (const auto& exception = ev->CastAsLocal<TEvTestFinished>()->Exception) {
+ std::rethrow_exception(exception);
+ }
+ }
+
+ class TCoro : public TActorCoroImpl {
+ TTestEnv& Env;
+ std::function<void(TCoro*)> Fn;
+ const TActorId Edge;
+ std::map<ui32, TActorId> Backpressure;
+
+ public:
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+
+ public:
+ TCoro(TTestEnv& env, std::function<void(TCoro*)>&& fn, const TActorId& edge)
+ : TActorCoroImpl(65536)
+ , Env(env)
+ , Fn(std::move(fn))
+ , Edge(edge)
+ , Info(env.Info)
+ {}
+
+ void Run() override {
+ std::exception_ptr exception;
+ try {
+ Fn(this);
+ } catch (const TDtorException&) {
+ return; // coroutine terminated from outside
+ } catch (...) {
+ exception = std::current_exception();
+ }
+ Send(Edge, new TEvTestFinished(exception));
+ }
+
+ void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> /*ev*/) override {
+ UNIT_ASSERT(false);
+ }
+
+ TActorId GetBackpressureFor(ui32 diskOrderNum) {
+ auto& res = Backpressure[diskOrderNum];
+ if (res == TActorId()) {
+ // create BS_QUEUE to this disk
+ auto counters = Env.Counters->GetSubgroup("bsqueue", ToString(diskOrderNum));
+ auto bspctx = MakeIntrusive<TBSProxyContext>(counters->GetSubgroup("subsystem", "memory"));
+ auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
+ res = Register(CreateVDiskBackpressureClient(Info, Info->GetVDiskId(diskOrderNum),
+ NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, counters, bspctx,
+ NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::VDiskLoad, 0), "queue", 0, false,
+ TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
+ }
+ return res;
+ }
+
+ std::set<TVDiskID> GetVDiskSet() const {
+ std::set<TVDiskID> vdisks;
+ for (ui32 i = 0; i < Info->GetTotalVDisksNum(); ++i) {
+ vdisks.insert(Info->GetVDiskId(i));
+ }
+ return vdisks;
+ }
+
+ void CreateQueuesAndWaitForReady() {
+ for (ui32 i = 0; i < Info->GetTotalVDisksNum(); ++i) {
+ GetBackpressureFor(i);
+ }
+ auto vdisks = GetVDiskSet();
+ while (!vdisks.empty()) {
+ auto ev = WaitForSpecificEvent<TEvProxyQueueState>();
+ auto& msg = *ev->Get();
+ UNIT_ASSERT(msg.IsConnected);
+ const bool erased = vdisks.erase(msg.VDiskId);
+ UNIT_ASSERT(erased);
+ }
+ }
+
+ void WaitForRepl() {
+ auto vdisks = GetVDiskSet();
+ while (!vdisks.empty()) {
+ for (const TVDiskID& vdiskId : vdisks) {
+ Send(Info->GetActorId(Info->GetOrderNumber(vdiskId)), new TEvBlobStorage::TEvVStatus(vdiskId));
+ }
+ for (size_t num = vdisks.size(); num; --num) {
+ auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVStatusResult>();
+ auto& record = ev->Get()->Record;
+ if (record.GetStatus() == NKikimrProto::OK && record.GetReplicated()) {
+ const bool erased = vdisks.erase(VDiskIDFromVDiskID(record.GetVDiskID()));
+ UNIT_ASSERT(erased);
+ }
+ }
+ if (!vdisks.empty()) {
+ Sleep(TDuration::Seconds(15));
+ }
+ }
+ }
+
+ void Sleep(TDuration timeout) {
+ Schedule(timeout, new TEvents::TEvWakeup);
+ WaitForSpecificEvent<TEvents::TEvWakeup>();
+ }
+
+ NKikimrProto::EReplyStatus Put(const TVDiskID& vdiskId, const TLogoBlobID& blobId, const TString& data) {
+ Send(GetBackpressureFor(Info->GetOrderNumber(vdiskId)), new TEvBlobStorage::TEvVPut(blobId, data, vdiskId,
+ false, nullptr, TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::TabletLog));
+ auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVPutResult>();
+ auto& record = ev->Get()->Record;
+ UNIT_ASSERT_VALUES_EQUAL(vdiskId, VDiskIDFromVDiskID(record.GetVDiskID()));
+ return record.GetStatus();
+ }
+
+ struct TGotItem {
+ NKikimrProto::EReplyStatus Status;
+ std::optional<TIngress> Ingress;
+ std::optional<TString> Data;
+
+ TGotItem(const NKikimrBlobStorage::TQueryResult& pb)
+ : Status(pb.GetStatus())
+ , Ingress(pb.HasIngress() ? std::make_optional(TIngress(pb.GetIngress())) : std::nullopt)
+ , Data(pb.HasBuffer() ? std::make_optional(pb.GetBuffer()) : std::nullopt)
+ {
+ UNIT_ASSERT(pb.HasStatus());
+ }
+ };
+ using TGetResult = std::map<TLogoBlobID, TGotItem>;
+
+ TGetResult GetRange(const TVDiskID& vdiskId, const TLogoBlobID& from, const TLogoBlobID& to) {
+ return Get(vdiskId, TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
+ Nothing(), from, to));
+ }
+
+ TGetResult GetExtr(const TVDiskID& vdiskId, const TLogoBlobID& blobId) {
+ return Get(vdiskId, TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
+ Nothing(), {{blobId}}));
+ }
+
+ TGetResult Get(const TVDiskID& vdiskId, std::unique_ptr<TEvBlobStorage::TEvVGet>&& query) {
+ Send(GetBackpressureFor(Info->GetOrderNumber(vdiskId)), query.release());
+ auto ev = WaitForSpecificEvent<TEvBlobStorage::TEvVGetResult>();
+ auto& record = ev->Get()->Record;
+ TGetResult res;
+ for (const auto& item : record.GetResult()) {
+ const bool inserted = res.emplace(LogoBlobIDFromLogoBlobID(item.GetBlobID()), TGotItem(item)).second;
+ UNIT_ASSERT(inserted); // blob ids should not repeat
+ }
+ return res;
+ }
+ };
+
+public:
+ TCoro *CurrentCoro = nullptr;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+
+private:
+ void SetupLogging(TTestActorSystem& runtime) {
+ runtime.SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::BS_SKELETON, NLog::PRI_INFO);
+ runtime.SetLogPriority(NKikimrServices::BS_LOCALRECOVERY, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::BS_VDISK_PUT, NLog::PRI_INFO);
+ runtime.SetLogPriority(NKikimrServices::BS_VDISK_GET, NLog::PRI_DEBUG);
+ runtime.SetLogPriority(NKikimrServices::BS_REPL, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_QUEUE, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_SYNCER, NLog::PRI_DEBUG);
+// runtime.SetLogPriority(NKikimrServices::BS_SYNCLOG, NLog::PRI_DEBUG);
+ }
+
+ void SetupStorage(TTestActorSystem& runtime) {
+ Info = CreateGroupInfo(runtime.GetNodes());
+ const TBlobStorageGroupInfo& info = *Info;
+
+ for (ui32 i = 0; i < info.GetTotalVDisksNum(); ++i) {
+ // create pdisk
+ TPDisk& pdisk = PDisks[i];
+ const TActorId pdiskActorId = MakeBlobStoragePDiskID(pdisk.NodeId, pdisk.PDiskId);
+ runtime.RegisterService(pdiskActorId, runtime.Register(CreatePDiskMockActor(pdisk.State), TActorId(), 0,
+ std::nullopt, pdisk.NodeId));
+
+ // create vdisk
+ TVDiskConfig::TBaseInfo baseInfo(
+ info.GetVDiskId(i),
+ pdiskActorId,
+ pdisk.PDiskGuid,
+ pdisk.PDiskId,
+ TPDiskCategory::DEVICE_TYPE_SSD,
+ 0,
+ NKikimrBlobStorage::TVDiskKind::Default,
+ 2, // InitOwnerRound
+ ""
+ );
+ const auto vcfg = MakeIntrusive<TVDiskConfig>(baseInfo);
+ auto vdiskCounters = Counters->GetSubgroup("vdisk", ToString(i));
+ runtime.RegisterService(info.GetActorId(i), runtime.Register(CreateVDisk(vcfg, Info, vdiskCounters),
+ TActorId(), 0, std::nullopt, pdisk.NodeId));
+ }
+ }
+
+private:
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+};
+
+void ReplicationTest(const TString datum) {
+ TTestEnv env(TBlobStorageGroupType::ErasureMirror3of4);
+ const TLogoBlobID blobId(1, 1, 1, 0, datum.size(), 0);
+ std::map<ui32, std::vector<ui8>> diskToParts = {{0, {1}}, {1, {2}}, {2, {1}}, {3, {3}}, {4, {3}}, {5, {2, 3}}};
+ auto checkPartsInPlace = [&](auto *coro) {
+ for (ui32 i = 0; i < coro->Info->GetTotalVDisksNum(); ++i) {
+ auto res = coro->GetExtr(coro->Info->GetVDiskId(i), blobId);
+ if (const auto it = diskToParts.find(i); it != diskToParts.end()) {
+ const std::vector<ui8>& parts = it->second;
+ std::set<ui8> m(parts.begin(), parts.end());
+ for (const auto& [key, value] : res) {
+ UNIT_ASSERT_VALUES_EQUAL(key.FullID(), blobId);
+ UNIT_ASSERT(m.count(key.PartId()));
+ m.erase(key.PartId());
+ UNIT_ASSERT_VALUES_EQUAL(value.Status, NKikimrProto::OK);
+ UNIT_ASSERT(value.Data);
+ UNIT_ASSERT_VALUES_EQUAL(*value.Data, key.PartId() < 3 ? datum : TString());
+ }
+ UNIT_ASSERT(m.empty());
+ } else {
+ auto& [key, value] = *res.begin();
+ UNIT_ASSERT_VALUES_EQUAL(res.size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(key, blobId);
+ UNIT_ASSERT_VALUES_EQUAL(value.Status, NKikimrProto::NODATA);
+ }
+ }
+ };
+ env.Run([&](auto *coro) {
+ coro->CreateQueuesAndWaitForReady();
+ for (const auto& [diskOrderNum, partIds] : diskToParts) {
+ for (const ui8 partId : partIds) {
+ UNIT_ASSERT_VALUES_EQUAL(coro->Put(coro->Info->GetVDiskId(diskOrderNum), TLogoBlobID(blobId, partId),
+ partId < 3 ? datum : TString()), NKikimrProto::OK);
+ }
+ }
+ TIngress required;
+ for (const auto& [diskOrderNum, partIds] : diskToParts) {
+ for (const ui8 partId : partIds) {
+ const TVDiskID& vdiskId = coro->Info->GetVDiskId(diskOrderNum);
+ const TLogoBlobID id(blobId, partId);
+ required.Merge(*TIngress::CreateIngressWOLocal(&coro->Info->GetTopology(), vdiskId, id));
+ }
+ }
+ for (;;) {
+ bool done = true;
+ TStringStream msgs;
+ for (const auto& [diskOrderNum, partIds] : diskToParts) {
+ for (const ui8 partId : partIds) {
+ const TVDiskID& vdiskId = coro->Info->GetVDiskId(diskOrderNum);
+ const TLogoBlobID id(blobId, partId);
+ auto allres = coro->GetExtr(vdiskId, id);
+ UNIT_ASSERT_VALUES_EQUAL(allres.size(), 1);
+ const auto& res = allres.begin()->second;
+ UNIT_ASSERT(res.Ingress);
+ TIngress ingr(*res.Ingress);
+ ingr = ingr.CopyWithoutLocal(coro->Info->Type);
+ if (ingr.Raw() != required.Raw()) {
+ done = false;
+ }
+ msgs << "*** " << vdiskId << " " << id << " "
+ << ingr.ToString(&coro->Info->GetTopology(), vdiskId, id) << " <> "
+ << required.ToString(&coro->Info->GetTopology(), vdiskId, id)
+ << Endl;
+ }
+ }
+ Cerr << Endl << msgs.Str() << Endl;
+ if (done) {
+ break;
+ } else {
+ coro->Sleep(TDuration::Seconds(10));
+ }
+ }
+ checkPartsInPlace(coro);
+ });
+ Cerr << Endl << "*** rechecking data after restart" << Endl << Endl;
+ env.Run([&](auto *coro) {
+ coro->CreateQueuesAndWaitForReady();
+ checkPartsInPlace(coro);
+ });
+ for (ui32 diskIdx = 0; diskIdx < env.GType.BlobSubgroupSize(); ++diskIdx) {
+ Cerr << Endl << "*** formatting disk " << diskIdx << Endl << Endl;
+ env.FormatDisk(diskIdx);
+ env.Run([&](auto *coro) {
+ coro->CreateQueuesAndWaitForReady();
+ coro->WaitForRepl();
+ checkPartsInPlace(coro);
+ });
+ }
+ for (ui32 diskIdx = 0; diskIdx < env.GType.BlobSubgroupSize(); ++diskIdx) {
+ for (ui32 diskIdx1 = 0; diskIdx1 < diskIdx; ++diskIdx1) {
+ Cerr << Endl << "*** formatting disks " << diskIdx << ", " << diskIdx1 << Endl << Endl;
+ env.FormatDisk(diskIdx);
+ env.FormatDisk(diskIdx1);
+ env.Run([&](auto *coro) {
+ coro->CreateQueuesAndWaitForReady();
+ coro->WaitForRepl();
+ checkPartsInPlace(coro);
+ });
+ }
+ }
+}
+
+Y_UNIT_TEST_SUITE(Mirror3of4) {
+
+ Y_UNIT_TEST(ReplicationSmall) {
+ ReplicationTest("hello, world!");
+ }
+
+ Y_UNIT_TEST(ReplicationHuge) {
+ ui32 size = 1 << 20;
+ TString datum = TString::Uninitialized(size);
+ char *p = datum.Detach();
+ for (ui32 i = 0; i < size; ++i) {
+ p[i] = i;
+ }
+ ReplicationTest(datum);
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_mirror3of4/ya.make b/ydb/core/blobstorage/ut_mirror3of4/ya.make
index 84bf0b51038..8fb0857de68 100644
--- a/ydb/core/blobstorage/ut_mirror3of4/ya.make
+++ b/ydb/core/blobstorage/ut_mirror3of4/ya.make
@@ -1,13 +1,13 @@
-UNITTEST()
-
+UNITTEST()
+
OWNER(g:kikimr)
-
+
SRCS(
main.cpp
)
-
+
SIZE(MEDIUM)
-
+
TIMEOUT(600)
PEERDIR(
@@ -25,4 +25,4 @@ PEERDIR(
ydb/core/util
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.cpp b/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.cpp
index 94eae0767aa..aaffc6a02f8 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.cpp
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.cpp
@@ -1,340 +1,340 @@
-#include "basic_test.h"
-#include "objectwithstate.h"
-#include "state_manager.h"
-#include <util/generic/set.h>
-#include <util/generic/bitmap.h>
+#include "basic_test.h"
+#include "objectwithstate.h"
+#include "state_manager.h"
+#include <util/generic/set.h>
+#include <util/generic/bitmap.h>
#include <util/system/unaligned_mem.h>
#include <library/cpp/digest/crc32c/crc32c.h>
-
-class TFakeVDisk
- : public TActor<TFakeVDisk>
- , public TObjectWithState
-{
- const TVDiskID VDiskId;
+
+class TFakeVDisk
+ : public TActor<TFakeVDisk>
+ , public TObjectWithState
+{
+ const TVDiskID VDiskId;
const TActorId PDiskServiceId;
- const ui64 PDiskGuid;
- TStateManager *StateManager;
- TIntrusivePtr<TPDiskParams> PDiskParams;
+ const ui64 PDiskGuid;
+ TStateManager *StateManager;
+ TIntrusivePtr<TPDiskParams> PDiskParams;
TFakeVDiskParams Params;
-
+
NKikimr::NPDisk::TLogPosition ReadLogPosition{0, 0};
-
- ui64 Lsn = 0;
-
- struct TLogRecord {
- ui64 Lsn;
+
+ ui64 Lsn = 0;
+
+ struct TLogRecord {
+ ui64 Lsn;
TLogSignature Signature;
- ui32 DataLen;
- ui32 Checksum;
+ ui32 DataLen;
+ ui32 Checksum;
TVector<TChunkIdx> CommitChunks;
TVector<TChunkIdx> DeleteChunks;
-
- friend bool operator <(const TLogRecord& x, const TLogRecord& y) {
- return x.Lsn < y.Lsn;
- }
- };
-
- struct TWriteRecord {
- TChunkIdx ChunkIdx;
- ui32 OffsetInBlocks;
- ui32 SizeInBlocks;
+
+ friend bool operator <(const TLogRecord& x, const TLogRecord& y) {
+ return x.Lsn < y.Lsn;
+ }
+ };
+
+ struct TWriteRecord {
+ TChunkIdx ChunkIdx;
+ ui32 OffsetInBlocks;
+ ui32 SizeInBlocks;
TVector<ui32> Checksums;
- void *Cookie;
- };
-
- enum class ECommitState {
- RESERVED,
- COMMIT_IN_PROGRESS,
- COMMITTED,
- DELETE_IN_PROGRESS,
- DELETED,
- };
-
- struct TState {
- class TChunkInfo {
- TDynBitMap UsedBlocks;
+ void *Cookie;
+ };
+
+ enum class ECommitState {
+ RESERVED,
+ COMMIT_IN_PROGRESS,
+ COMMITTED,
+ DELETE_IN_PROGRESS,
+ DELETED,
+ };
+
+ struct TState {
+ class TChunkInfo {
+ TDynBitMap UsedBlocks;
TVector<ui32> Checksums;
- ECommitState CommitState = ECommitState::RESERVED;
-
- public:
- TChunkInfo() = delete;
-
- TChunkInfo(const TChunkInfo& other) = default;
- TChunkInfo(TChunkInfo&& other) = default;
-
- TChunkInfo(ui32 numBlocks) {
- Y_VERIFY(numBlocks > 0);
- UsedBlocks.Reserve(numBlocks);
- UsedBlocks.Reset(0, numBlocks);
- Checksums.resize(numBlocks);
- }
-
- TChunkInfo(ui32 numBlocks, const NPDiskFIT::TFakeVDiskState::TChunk& pb)
- : TChunkInfo(numBlocks)
- {
- Y_VERIFY(pb.HasCommitState());
- for (const auto& block : pb.GetBlocks()) {
- Y_VERIFY(block.HasIndex());
- Y_VERIFY(block.HasChecksum());
- const ui32 index = block.GetIndex();
- Y_VERIFY(index < numBlocks);
- UsedBlocks.Set(index);
- Checksums[index] = block.GetChecksum();
- }
- CommitState = static_cast<ECommitState>(pb.GetCommitState());
- }
-
+ ECommitState CommitState = ECommitState::RESERVED;
+
+ public:
+ TChunkInfo() = delete;
+
+ TChunkInfo(const TChunkInfo& other) = default;
+ TChunkInfo(TChunkInfo&& other) = default;
+
+ TChunkInfo(ui32 numBlocks) {
+ Y_VERIFY(numBlocks > 0);
+ UsedBlocks.Reserve(numBlocks);
+ UsedBlocks.Reset(0, numBlocks);
+ Checksums.resize(numBlocks);
+ }
+
+ TChunkInfo(ui32 numBlocks, const NPDiskFIT::TFakeVDiskState::TChunk& pb)
+ : TChunkInfo(numBlocks)
+ {
+ Y_VERIFY(pb.HasCommitState());
+ for (const auto& block : pb.GetBlocks()) {
+ Y_VERIFY(block.HasIndex());
+ Y_VERIFY(block.HasChecksum());
+ const ui32 index = block.GetIndex();
+ Y_VERIFY(index < numBlocks);
+ UsedBlocks.Set(index);
+ Checksums[index] = block.GetChecksum();
+ }
+ CommitState = static_cast<ECommitState>(pb.GetCommitState());
+ }
+
void SetChecksums(ui32 index, const TVector<ui32>& checksums) {
const ui32 num = checksums.size();
Y_VERIFY(index + num <= Checksums.size() && index + num <= UsedBlocks.Size());
- UsedBlocks.Set(index, index + num);
- std::copy(checksums.begin(), checksums.end(), Checksums.begin() + index);
- }
-
- ui32 GetChecksum(ui32 index) const {
+ UsedBlocks.Set(index, index + num);
+ std::copy(checksums.begin(), checksums.end(), Checksums.begin() + index);
+ }
+
+ ui32 GetChecksum(ui32 index) const {
Y_VERIFY(index < Checksums.size());
- return Checksums[index];
- }
-
- bool VerifyChecksum(ui32 index, ui32 checksum) const {
+ return Checksums[index];
+ }
+
+ bool VerifyChecksum(ui32 index, ui32 checksum) const {
Y_VERIFY(index < Checksums.size());
- return UsedBlocks[index] && Checksums[index] == checksum;
- }
-
- bool IsUsed(ui32 index) const {
- return UsedBlocks[index];
- }
-
- void SerializeToProto(NPDiskFIT::TFakeVDiskState::TChunk& pb) const {
- Y_FOR_EACH_BIT(index, UsedBlocks) {
+ return UsedBlocks[index] && Checksums[index] == checksum;
+ }
+
+ bool IsUsed(ui32 index) const {
+ return UsedBlocks[index];
+ }
+
+ void SerializeToProto(NPDiskFIT::TFakeVDiskState::TChunk& pb) const {
+ Y_FOR_EACH_BIT(index, UsedBlocks) {
Y_VERIFY(index < Checksums.size(), "index# %zu +Checksums# %zu UsedBlocks# %zu", index, Checksums.size(),
- UsedBlocks.Size());
- auto& block = *pb.AddBlocks();
- block.SetIndex(index);
- block.SetChecksum(Checksums[index]);
- }
- pb.SetCommitState(static_cast<ui32>(CommitState));
- }
-
- ECommitState GetCommitState() const {
- return CommitState;
- }
-
- void SetCommitState(ECommitState x) {
- CommitState = x;
- }
- };
-
+ UsedBlocks.Size());
+ auto& block = *pb.AddBlocks();
+ block.SetIndex(index);
+ block.SetChecksum(Checksums[index]);
+ }
+ pb.SetCommitState(static_cast<ui32>(CommitState));
+ }
+
+ ECommitState GetCommitState() const {
+ return CommitState;
+ }
+
+ void SetCommitState(ECommitState x) {
+ CommitState = x;
+ }
+ };
+
TSet<TLogRecord> Confirmed;
TSet<TLogRecord> InFlight;
- ui64 FirstLsnToKeep = 0;
+ ui64 FirstLsnToKeep = 0;
TMap<TChunkIdx, TChunkInfo> Chunks;
TList<TWriteRecord> WritesInFlight;
- ui32 BlocksInChunk = 0;
-
+ ui32 BlocksInChunk = 0;
+
TString ToString() const {
- TStringStream str;
- str << "{Confirmed# [";
- bool first = true;
- for (const TLogRecord& x : Confirmed) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
+ TStringStream str;
+ str << "{Confirmed# [";
+ bool first = true;
+ for (const TLogRecord& x : Confirmed) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
str << x.Lsn << ":" << x.Signature.ToString() << ":" << x.DataLen;
- }
- str << "] InFlight# [";
- first = true;
- for (const TLogRecord& x : InFlight) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
+ }
+ str << "] InFlight# [";
+ first = true;
+ for (const TLogRecord& x : InFlight) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
str << x.Lsn << ":" << x.Signature.ToString() << ":" << x.DataLen;
- }
- str << "] FirstLsnToKeep# " << FirstLsnToKeep << "}";
- return str.Str();
- }
-
- TChunkInfo& GetChunk(TChunkIdx chunkIdx) {
- auto it = Chunks.find(chunkIdx);
- Y_VERIFY(it != Chunks.end());
- return it->second;
- }
-
- const TChunkInfo& GetChunk(TChunkIdx chunkIdx) const {
- auto it = Chunks.find(chunkIdx);
- Y_VERIFY(it != Chunks.end());
- return it->second;
- }
-
- void SerializeToProto(NPDiskFIT::TFakeVDiskState& pb) const {
- for (const auto& item : Confirmed) {
- Serialize(item, *pb.AddLogItems());
- }
- for (const auto& item : InFlight) {
- Serialize(item, *pb.AddInFlightItems());
- }
- pb.SetFirstLsnToKeep(FirstLsnToKeep);
- pb.SetBlocksInChunk(BlocksInChunk);
- for (const auto& pair : Chunks) {
- auto& chunk = *pb.AddChunks();
- chunk.SetChunkIdx(pair.first);
- pair.second.SerializeToProto(chunk);
- }
- for (const TWriteRecord& write : WritesInFlight) {
- auto& pbItem = *pb.AddWritesInFlight();
- pbItem.SetChunkIdx(write.ChunkIdx);
- pbItem.SetOffsetInBlocks(write.OffsetInBlocks);
- pbItem.SetSizeInBlocks(write.SizeInBlocks);
- for (ui32 checksum : write.Checksums) {
- pbItem.AddChecksums(checksum);
- }
- }
- }
-
- void DeserializeFromProto(const NPDiskFIT::TFakeVDiskState& pb) {
- for (const auto& pbItem : pb.GetLogItems()) {
- TLogRecord item;
- Deserialize(pbItem, item);
- Confirmed.insert(item);
- }
- for (const auto& pbItem : pb.GetInFlightItems()) {
- TLogRecord item;
- Deserialize(pbItem, item);
- InFlight.insert(item);
- }
- FirstLsnToKeep = pb.GetFirstLsnToKeep();
-
- // extract number of blocks per single chunk
- Y_VERIFY(pb.HasBlocksInChunk());
- BlocksInChunk = pb.GetBlocksInChunk();
-
- for (const auto& pbItem : pb.GetChunks()) {
- Y_VERIFY(pbItem.HasChunkIdx());
- const TChunkIdx chunkIdx = pbItem.GetChunkIdx();
- Chunks.emplace(chunkIdx, TChunkInfo(BlocksInChunk, pbItem));
- }
- for (const auto& pbItem : pb.GetWritesInFlight()) {
- Y_VERIFY(pbItem.HasChunkIdx());
- Y_VERIFY(pbItem.HasOffsetInBlocks());
- Y_VERIFY(pbItem.HasSizeInBlocks());
- Y_VERIFY(pbItem.ChecksumsSize() == pbItem.GetSizeInBlocks());
- TWriteRecord write;
- write.ChunkIdx = pbItem.GetChunkIdx();
- write.OffsetInBlocks = pbItem.GetOffsetInBlocks();
- write.SizeInBlocks = pbItem.GetSizeInBlocks();
- write.Checksums = {pbItem.GetChecksums().begin(), pbItem.GetChecksums().end()};
- WritesInFlight.push_back(std::move(write));
- }
- }
-
- private:
- static void Serialize(const TLogRecord& item, NPDiskFIT::TFakeVDiskState::TLogItem& pbItem) {
- pbItem.SetLsn(item.Lsn);
- pbItem.SetSignature(item.Signature);
- pbItem.SetDataLen(item.DataLen);
- pbItem.SetChecksum(item.Checksum);
- for (TChunkIdx chunk : item.CommitChunks) {
- pbItem.AddCommitChunks(chunk);
- }
- for (TChunkIdx chunk : item.DeleteChunks) {
- pbItem.AddDeleteChunks(chunk);
- }
- }
-
- static void Deserialize(const NPDiskFIT::TFakeVDiskState::TLogItem& pbItem, TLogRecord& item) {
- Y_VERIFY(pbItem.HasLsn());
- Y_VERIFY(pbItem.HasSignature());
- Y_VERIFY(pbItem.HasDataLen());
- Y_VERIFY(pbItem.HasChecksum());
- item.Lsn = pbItem.GetLsn();
- item.Signature = pbItem.GetSignature();
- item.DataLen = pbItem.GetDataLen();
- item.Checksum = pbItem.GetChecksum();
- item.CommitChunks = {pbItem.GetCommitChunks().begin(), pbItem.GetCommitChunks().end()};
- item.DeleteChunks = {pbItem.GetDeleteChunks().begin(), pbItem.GetDeleteChunks().end()};
- }
- };
-
- const TState Recovered;
-
- TState State;
-
- ui32 InFlightLog = 0;
-
+ }
+ str << "] FirstLsnToKeep# " << FirstLsnToKeep << "}";
+ return str.Str();
+ }
+
+ TChunkInfo& GetChunk(TChunkIdx chunkIdx) {
+ auto it = Chunks.find(chunkIdx);
+ Y_VERIFY(it != Chunks.end());
+ return it->second;
+ }
+
+ const TChunkInfo& GetChunk(TChunkIdx chunkIdx) const {
+ auto it = Chunks.find(chunkIdx);
+ Y_VERIFY(it != Chunks.end());
+ return it->second;
+ }
+
+ void SerializeToProto(NPDiskFIT::TFakeVDiskState& pb) const {
+ for (const auto& item : Confirmed) {
+ Serialize(item, *pb.AddLogItems());
+ }
+ for (const auto& item : InFlight) {
+ Serialize(item, *pb.AddInFlightItems());
+ }
+ pb.SetFirstLsnToKeep(FirstLsnToKeep);
+ pb.SetBlocksInChunk(BlocksInChunk);
+ for (const auto& pair : Chunks) {
+ auto& chunk = *pb.AddChunks();
+ chunk.SetChunkIdx(pair.first);
+ pair.second.SerializeToProto(chunk);
+ }
+ for (const TWriteRecord& write : WritesInFlight) {
+ auto& pbItem = *pb.AddWritesInFlight();
+ pbItem.SetChunkIdx(write.ChunkIdx);
+ pbItem.SetOffsetInBlocks(write.OffsetInBlocks);
+ pbItem.SetSizeInBlocks(write.SizeInBlocks);
+ for (ui32 checksum : write.Checksums) {
+ pbItem.AddChecksums(checksum);
+ }
+ }
+ }
+
+ void DeserializeFromProto(const NPDiskFIT::TFakeVDiskState& pb) {
+ for (const auto& pbItem : pb.GetLogItems()) {
+ TLogRecord item;
+ Deserialize(pbItem, item);
+ Confirmed.insert(item);
+ }
+ for (const auto& pbItem : pb.GetInFlightItems()) {
+ TLogRecord item;
+ Deserialize(pbItem, item);
+ InFlight.insert(item);
+ }
+ FirstLsnToKeep = pb.GetFirstLsnToKeep();
+
+ // extract number of blocks per single chunk
+ Y_VERIFY(pb.HasBlocksInChunk());
+ BlocksInChunk = pb.GetBlocksInChunk();
+
+ for (const auto& pbItem : pb.GetChunks()) {
+ Y_VERIFY(pbItem.HasChunkIdx());
+ const TChunkIdx chunkIdx = pbItem.GetChunkIdx();
+ Chunks.emplace(chunkIdx, TChunkInfo(BlocksInChunk, pbItem));
+ }
+ for (const auto& pbItem : pb.GetWritesInFlight()) {
+ Y_VERIFY(pbItem.HasChunkIdx());
+ Y_VERIFY(pbItem.HasOffsetInBlocks());
+ Y_VERIFY(pbItem.HasSizeInBlocks());
+ Y_VERIFY(pbItem.ChecksumsSize() == pbItem.GetSizeInBlocks());
+ TWriteRecord write;
+ write.ChunkIdx = pbItem.GetChunkIdx();
+ write.OffsetInBlocks = pbItem.GetOffsetInBlocks();
+ write.SizeInBlocks = pbItem.GetSizeInBlocks();
+ write.Checksums = {pbItem.GetChecksums().begin(), pbItem.GetChecksums().end()};
+ WritesInFlight.push_back(std::move(write));
+ }
+ }
+
+ private:
+ static void Serialize(const TLogRecord& item, NPDiskFIT::TFakeVDiskState::TLogItem& pbItem) {
+ pbItem.SetLsn(item.Lsn);
+ pbItem.SetSignature(item.Signature);
+ pbItem.SetDataLen(item.DataLen);
+ pbItem.SetChecksum(item.Checksum);
+ for (TChunkIdx chunk : item.CommitChunks) {
+ pbItem.AddCommitChunks(chunk);
+ }
+ for (TChunkIdx chunk : item.DeleteChunks) {
+ pbItem.AddDeleteChunks(chunk);
+ }
+ }
+
+ static void Deserialize(const NPDiskFIT::TFakeVDiskState::TLogItem& pbItem, TLogRecord& item) {
+ Y_VERIFY(pbItem.HasLsn());
+ Y_VERIFY(pbItem.HasSignature());
+ Y_VERIFY(pbItem.HasDataLen());
+ Y_VERIFY(pbItem.HasChecksum());
+ item.Lsn = pbItem.GetLsn();
+ item.Signature = pbItem.GetSignature();
+ item.DataLen = pbItem.GetDataLen();
+ item.Checksum = pbItem.GetChecksum();
+ item.CommitChunks = {pbItem.GetCommitChunks().begin(), pbItem.GetCommitChunks().end()};
+ item.DeleteChunks = {pbItem.GetDeleteChunks().begin(), pbItem.GetDeleteChunks().end()};
+ }
+ };
+
+ const TState Recovered;
+
+ TState State;
+
+ ui32 InFlightLog = 0;
+
ui32 LogsSent = 0;
- ui64 NextWriteCookie = 1;
-
- ui32 ReadMsgPending = 0;
-
- bool StateVerified = false;
-
-public:
+ ui64 NextWriteCookie = 1;
+
+ ui32 ReadMsgPending = 0;
+
+ bool StateVerified = false;
+
+public:
TFakeVDisk(const TVDiskID& vdiskId, const TActorId& pdiskServiceId, ui64 pdiskGuid, TStateManager *stateManager,
TFakeVDiskParams params)
- : TActor<TFakeVDisk>(&TFakeVDisk::StateFunc)
+ : TActor<TFakeVDisk>(&TFakeVDisk::StateFunc)
, TObjectWithState(Sprintf("vdisk[%s]", vdiskId.ToString().data()))
- , VDiskId(vdiskId)
- , PDiskServiceId(pdiskServiceId)
- , PDiskGuid(pdiskGuid)
- , StateManager(stateManager)
+ , VDiskId(vdiskId)
+ , PDiskServiceId(pdiskServiceId)
+ , PDiskGuid(pdiskGuid)
+ , StateManager(stateManager)
, Params(params)
- , Recovered(DeserializeRecoveredState())
- {
-// TStringStream str;
-// str << "VDiskId# " << vdiskId.ToString() << " Recovered# " << Recovered.ToString() << Endl;
-// Cerr << str.Str();
-
- // actually register this VDisk after all initialization procedures are finished
- TObjectWithState::Register();
- }
-
- ~TFakeVDisk() {
- }
-
- TState DeserializeRecoveredState() {
- TState recovered;
-
+ , Recovered(DeserializeRecoveredState())
+ {
+// TStringStream str;
+// str << "VDiskId# " << vdiskId.ToString() << " Recovered# " << Recovered.ToString() << Endl;
+// Cerr << str.Str();
+
+ // actually register this VDisk after all initialization procedures are finished
+ TObjectWithState::Register();
+ }
+
+ ~TFakeVDisk() {
+ }
+
+ TState DeserializeRecoveredState() {
+ TState recovered;
+
if (TString state = GetState()) {
- NPDiskFIT::TFakeVDiskState pb;
- bool status = pb.ParseFromString(state);
- Y_VERIFY(status);
- recovered.DeserializeFromProto(pb);
- }
-
- return recovered;
- }
-
- template<typename TFunc>
- void SendPDiskRequest(const TActorContext& ctx, IEventBase *msg, TFunc&& stateUpdate) {
- // we must execute this action consistently with state manager because if this action is executed after generating
- // failure condition, then state may become inconsistent, because PDisk may actually execute this request after
- // state collect
- StateManager->ExecuteConsistentAction([&] {
- ctx.Send(PDiskServiceId, msg);
- stateUpdate();
- });
- }
-
+ NPDiskFIT::TFakeVDiskState pb;
+ bool status = pb.ParseFromString(state);
+ Y_VERIFY(status);
+ recovered.DeserializeFromProto(pb);
+ }
+
+ return recovered;
+ }
+
+ template<typename TFunc>
+ void SendPDiskRequest(const TActorContext& ctx, IEventBase *msg, TFunc&& stateUpdate) {
+ // we must execute this action consistently with state manager because if this action is executed after generating
+ // failure condition, then state may become inconsistent, because PDisk may actually execute this request after
+ // state collect
+ StateManager->ExecuteConsistentAction([&] {
+ ctx.Send(PDiskServiceId, msg);
+ stateUpdate();
+ });
+ }
+
TString SelfInfo() const {
return TStringBuilder() << " VDiskId# " << VDiskId.ToStringWOGeneration() << " Owner# " << PDiskParams->Owner;
}
- void Bootstrap(const TActorContext& ctx) {
- Become(&TFakeVDisk::StateFunc);
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TFakeVDisk::StateFunc);
SendPDiskRequest(ctx, new NPDisk::TEvYardInit(2, VDiskId, PDiskGuid), [] {});
- }
-
+ }
+
void Handle(NPDisk::TEvYardInitResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- PDiskParams = msg->PDiskParams;
- State.BlocksInChunk = PDiskParams->ChunkSize / PDiskParams->AppendBlockSize;
-
+ auto *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ PDiskParams = msg->PDiskParams;
+ State.BlocksInChunk = PDiskParams->ChunkSize / PDiskParams->AppendBlockSize;
+
THashSet<TChunkIdx> owned(msg->OwnedChunks.begin(), msg->OwnedChunks.end());
for (const auto& [idx, info] : Recovered.Chunks) {
if (info.GetCommitState() == ECommitState::COMMITTED) {
@@ -353,216 +353,216 @@ public:
info.GetCommitState() == ECommitState::DELETE_IN_PROGRESS);
}
- TStringStream str;
+ TStringStream str;
str << SelfInfo() << " starting, owned chunks# " << FormatList(msg->OwnedChunks) << Endl;
- Cerr << str.Str();
-
- IssueReadLogRequest(ctx);
- }
-
- void IssueReadLogRequest(const TActorContext& ctx) {
+ Cerr << str.Str();
+
+ IssueReadLogRequest(ctx);
+ }
+
+ void IssueReadLogRequest(const TActorContext& ctx) {
SendPDiskRequest(ctx, new NPDisk::TEvReadLog(PDiskParams->Owner, PDiskParams->OwnerRound, ReadLogPosition), [] {});
- }
-
+ }
+
void Handle(NPDisk::TEvReadLogResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
- Y_VERIFY(msg->Position == ReadLogPosition);
-
- for (const auto& item : msg->Results) {
- Y_VERIFY(Lsn < item.Lsn);
- Lsn = item.Lsn;
-
- TStringStream str;
+ auto *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+ Y_VERIFY(msg->Position == ReadLogPosition);
+
+ for (const auto& item : msg->Results) {
+ Y_VERIFY(Lsn < item.Lsn);
+ Lsn = item.Lsn;
+
+ TStringStream str;
str << "TEvReadLogResult " << SelfInfo() << " Lsn# " << item.Lsn << " Len# " << item.Data.size()
<< " ChunkCommitSignature# " << (item.Signature.HasCommitRecord() ? "true" : "false")
<< Endl;
- Cerr << str.Str();
-
+ Cerr << str.Str();
+
State.Confirmed.insert(TLogRecord{item.Lsn, item.Signature, (ui32)item.Data.size(),
Crc32c(item.Data.data(), item.Data.size()), {}, {}});
- }
-
- if (msg->IsEndOfLog) {
- VerifyRecoveredLog(ctx);
- } else {
- ReadLogPosition = msg->NextPosition;
- IssueReadLogRequest(ctx);
- }
- }
-
- void ProcessItem(const TLogRecord *current, const TLogRecord *prev) {
- if (current && prev) {
- Y_VERIFY(current->Lsn == prev->Lsn);
- Y_VERIFY(current->Signature == prev->Signature);
- Y_VERIFY(current->DataLen == prev->DataLen);
- Y_VERIFY(current->Checksum == prev->Checksum);
- } else if (current) {
- // there is a record in current set (recovered from PDisk), but not in previous set (stored state); there
- // may be an item in flight?
- auto it = Recovered.InFlight.find(*current);
+ }
+
+ if (msg->IsEndOfLog) {
+ VerifyRecoveredLog(ctx);
+ } else {
+ ReadLogPosition = msg->NextPosition;
+ IssueReadLogRequest(ctx);
+ }
+ }
+
+ void ProcessItem(const TLogRecord *current, const TLogRecord *prev) {
+ if (current && prev) {
+ Y_VERIFY(current->Lsn == prev->Lsn);
+ Y_VERIFY(current->Signature == prev->Signature);
+ Y_VERIFY(current->DataLen == prev->DataLen);
+ Y_VERIFY(current->Checksum == prev->Checksum);
+ } else if (current) {
+ // there is a record in current set (recovered from PDisk), but not in previous set (stored state); there
+ // may be an item in flight?
+ auto it = Recovered.InFlight.find(*current);
Y_VERIFY_S(it != Recovered.InFlight.end(), "unexpected log record " << SelfInfo() << " Lsn# " << current->Lsn
<< " Signature# " << current->Signature.ToString());
Y_VERIFY_S(it->DataLen == current->DataLen && it->Checksum == current->Checksum &&
it->Signature == current->Signature, SelfInfo() << "Lsn# " << it->Lsn
<< " InFlightData# " << it->DataLen << " StoredData# " << current->DataLen);
- } else if (prev) {
- // lost item
- if (prev->Lsn >= Recovered.FirstLsnToKeep) {
+ } else if (prev) {
+ // lost item
+ if (prev->Lsn >= Recovered.FirstLsnToKeep) {
Y_FAIL_S("lost item Owner# " << PDiskParams->Owner << " Lsn# " << prev->Lsn);
- }
- }
- }
-
- void VerifyRecoveredLog(const TActorContext& ctx) {
-// TStringStream str;
-// str << "Owner# " << (int)PDiskParams->Owner << " Confirmed#";
-// for (const auto& item : Recovered.Confirmed) {
-// str << " [" << item.Lsn << " " << item.DataLen << "]";
-// }
-// str << " InFlight#";
-// for (const auto& item : Recovered.InFlight) {
-// str << " [" << item.Lsn << " " << item.DataLen << "]";
-// }
-// str << " State#";
-// for (const auto& item : State.Confirmed) {
-// str << " [" << item.Lsn << " " << item.DataLen << "]";
-// }
-// str << Endl;
-// Cerr << str.Str();
-
- auto curIt = State.Confirmed.begin();
- auto prevIt = Recovered.Confirmed.begin();
- for (;;) {
- const bool curEnd = curIt == State.Confirmed.end();
- const bool prevEnd = prevIt == Recovered.Confirmed.end();
- if (curEnd && prevEnd) {
- break;
- } else if (!curEnd && (prevEnd || *curIt < *prevIt)) {
- ProcessItem(&*curIt++, nullptr);
- } else if (!prevEnd && (curEnd || *prevIt < *curIt)) {
- ProcessItem(nullptr, &*prevIt++);
- } else {
- ProcessItem(&*curIt++, &*prevIt++);
- }
- }
-
- // advance LSN to point to next free index
- State.FirstLsnToKeep = Recovered.FirstLsnToKeep;
- ++Lsn;
-
- for (const auto& pair : Recovered.Chunks) {
+ }
+ }
+ }
+
+ void VerifyRecoveredLog(const TActorContext& ctx) {
+// TStringStream str;
+// str << "Owner# " << (int)PDiskParams->Owner << " Confirmed#";
+// for (const auto& item : Recovered.Confirmed) {
+// str << " [" << item.Lsn << " " << item.DataLen << "]";
+// }
+// str << " InFlight#";
+// for (const auto& item : Recovered.InFlight) {
+// str << " [" << item.Lsn << " " << item.DataLen << "]";
+// }
+// str << " State#";
+// for (const auto& item : State.Confirmed) {
+// str << " [" << item.Lsn << " " << item.DataLen << "]";
+// }
+// str << Endl;
+// Cerr << str.Str();
+
+ auto curIt = State.Confirmed.begin();
+ auto prevIt = Recovered.Confirmed.begin();
+ for (;;) {
+ const bool curEnd = curIt == State.Confirmed.end();
+ const bool prevEnd = prevIt == Recovered.Confirmed.end();
+ if (curEnd && prevEnd) {
+ break;
+ } else if (!curEnd && (prevEnd || *curIt < *prevIt)) {
+ ProcessItem(&*curIt++, nullptr);
+ } else if (!prevEnd && (curEnd || *prevIt < *curIt)) {
+ ProcessItem(nullptr, &*prevIt++);
+ } else {
+ ProcessItem(&*curIt++, &*prevIt++);
+ }
+ }
+
+ // advance LSN to point to next free index
+ State.FirstLsnToKeep = Recovered.FirstLsnToKeep;
+ ++Lsn;
+
+ for (const auto& pair : Recovered.Chunks) {
SendPDiskRequest(ctx, new NPDisk::TEvChunkRead(PDiskParams->Owner, PDiskParams->OwnerRound,
pair.first, 0, PDiskParams->ChunkSize, NPriRead::HullLoad, nullptr), [] {});
- ++ReadMsgPending;
- }
-
- CheckReadMsgPending(ctx);
- }
-
- void CheckReadMsgPending(const TActorContext& ctx) {
- if (!ReadMsgPending) {
- auto action = [this] {
- StateVerified = true;
- };
- StateManager->ExecuteConsistentAction(action);
- Activity(ctx);
- }
- }
-
- void Activity(const TActorContext& ctx) {
- while (InFlightLog < 10) {
- ui64 writeLogScore = 100;
+ ++ReadMsgPending;
+ }
+
+ CheckReadMsgPending(ctx);
+ }
+
+ void CheckReadMsgPending(const TActorContext& ctx) {
+ if (!ReadMsgPending) {
+ auto action = [this] {
+ StateVerified = true;
+ };
+ StateManager->ExecuteConsistentAction(action);
+ Activity(ctx);
+ }
+ }
+
+ void Activity(const TActorContext& ctx) {
+ while (InFlightLog < 10) {
+ ui64 writeLogScore = 100;
ui64 allocateScore = State.Chunks.size() < 20 ? 10 : 0;
- ui64 writeScore = State.Chunks.empty() ? 0 : 5;
-
- ui64 totalScore = writeLogScore + allocateScore + writeScore;
- if (!totalScore) {
- // nothing to do
- break;
- }
-
- ui64 option = RandomNumber<ui64>(totalScore);
+ ui64 writeScore = State.Chunks.empty() ? 0 : 5;
+
+ ui64 totalScore = writeLogScore + allocateScore + writeScore;
+ if (!totalScore) {
+ // nothing to do
+ break;
+ }
+
+ ui64 option = RandomNumber<ui64>(totalScore);
if (Params.LogsToBeSent && LogsSent >= Params.LogsToBeSent) {
break;
} else if (option < writeLogScore) {
IssueLogMessage(1, ctx);
- } else if ((option -= writeLogScore) < allocateScore) {
- IssueAllocateRequest(ctx);
- } else if ((option -= allocateScore) < writeScore) {
- IssueWriteRequest(ctx);
- } else {
- Y_FAIL("unexpected option");
- }
- }
- }
-
+ } else if ((option -= writeLogScore) < allocateScore) {
+ IssueAllocateRequest(ctx);
+ } else if ((option -= allocateScore) < writeScore) {
+ IssueWriteRequest(ctx);
+ } else {
+ Y_FAIL("unexpected option");
+ }
+ }
+ }
+
void IssueLogMessage(TLogSignature signature, const TActorContext& ctx) {
ui32 size = Params.SizeMin + RandomNumber<ui32>(Params.SizeMax - Params.SizeMin + 1);
TString data = GenerateRandomDataBuffer(size);
-
- auto *info = new TLogRecord;
- info->Signature = signature;
+
+ auto *info = new TLogRecord;
+ info->Signature = signature;
info->DataLen = data.size();
- info->Lsn = Lsn;
+ info->Lsn = Lsn;
info->Checksum = Crc32c(data.data(), data.size());
-
- // find out chunks we can commit or delete now
- for (auto& pair : State.Chunks) {
- TChunkIdx chunkIdx = pair.first;
- TState::TChunkInfo& chunk = pair.second;
- switch (chunk.GetCommitState()) {
- case ECommitState::RESERVED:
+
+ // find out chunks we can commit or delete now
+ for (auto& pair : State.Chunks) {
+ TChunkIdx chunkIdx = pair.first;
+ TState::TChunkInfo& chunk = pair.second;
+ switch (chunk.GetCommitState()) {
+ case ECommitState::RESERVED:
// reserved chunk is a subject for commit; 1% chance to commit chunk
if (RandomNumber<double>() < 0.01) {
- info->CommitChunks.push_back(chunkIdx);
- chunk.SetCommitState(ECommitState::COMMIT_IN_PROGRESS);
- }
- break;
-
- case ECommitState::COMMITTED:
+ info->CommitChunks.push_back(chunkIdx);
+ chunk.SetCommitState(ECommitState::COMMIT_IN_PROGRESS);
+ }
+ break;
+
+ case ECommitState::COMMITTED:
// committed chunk is a subject for deletion; 0.5% change to delete chunk
if (RandomNumber<double>() < 0.005) {
- bool hasWrites = false;
- for (const TWriteRecord& w : State.WritesInFlight) {
- if (w.ChunkIdx == chunkIdx) {
- hasWrites = true;
- break;
- }
- }
- if (hasWrites) {
- break;
- }
- info->DeleteChunks.push_back(chunkIdx);
- chunk.SetCommitState(ECommitState::DELETE_IN_PROGRESS);
- }
- break;
-
- default:
- break;
- }
- }
-
+ bool hasWrites = false;
+ for (const TWriteRecord& w : State.WritesInFlight) {
+ if (w.ChunkIdx == chunkIdx) {
+ hasWrites = true;
+ break;
+ }
+ }
+ if (hasWrites) {
+ break;
+ }
+ info->DeleteChunks.push_back(chunkIdx);
+ chunk.SetCommitState(ECommitState::DELETE_IN_PROGRESS);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
NPDisk::TCommitRecord cr;
-
- // advance LSN every 30000 items avg
+
+ // advance LSN every 30000 items avg
if (Lsn > Params.LsnToKeepCount && RandomNumber<double>() < Params.LogCutProbability) {
cr.FirstLsnToKeep = Lsn - Params.LsnToKeepCount;
- cr.IsStartingPoint = true; // make starting point if we cut log
- }
-
- // fill in commit/delete records
- cr.CommitChunks = info->CommitChunks;
- cr.DeleteChunks = info->DeleteChunks;
- cr.IsStartingPoint = cr.IsStartingPoint || cr.CommitChunks || cr.DeleteChunks;
-
- if (cr.FirstLsnToKeep) {
- TStringStream str;
+ cr.IsStartingPoint = true; // make starting point if we cut log
+ }
+
+ // fill in commit/delete records
+ cr.CommitChunks = info->CommitChunks;
+ cr.DeleteChunks = info->DeleteChunks;
+ cr.IsStartingPoint = cr.IsStartingPoint || cr.CommitChunks || cr.DeleteChunks;
+
+ if (cr.FirstLsnToKeep) {
+ TStringStream str;
str << SelfInfo() << " FirstLsnToKeep# " << cr.FirstLsnToKeep << Endl;
- Cerr << str.Str();
- }
-
- TStringStream msg;
+ Cerr << str.Str();
+ }
+
+ TStringStream msg;
msg << "TEvLog " << SelfInfo() << " Lsn# " << Lsn << " Size# " << info->DataLen;
auto printChunks = [] (TVector<TChunkIdx> chunks) {
bool first = true;
@@ -576,8 +576,8 @@ public:
<< " IsStartingPoint# " << (cr.IsStartingPoint ? "true" : "false") << Endl;
if (cr.IsStartingPoint || cr.CommitChunks || cr.DeleteChunks) {
Cerr << msg.Str();
- }
-
+ }
+
auto lsn = Lsn++;
SendPDiskRequest(ctx, new NPDisk::TEvLog(PDiskParams->Owner, PDiskParams->OwnerRound, signature, cr, data,
TLsnSeg(lsn, lsn), info), [&] {
@@ -587,323 +587,323 @@ public:
State.FirstLsnToKeep = cr.FirstLsnToKeep;
}
});
-
+
++LogsSent;
- ++InFlightLog;
- }
-
+ ++InFlightLog;
+ }
+
void Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
+ auto *msg = ev->Get();
Y_VERIFY(msg->Results, "No results in TEvLogResult, Owner# %" PRIu32 " Status# %s",
(ui32)PDiskParams->Owner, NKikimrProto::EReplyStatus_Name(msg->Status).c_str());
InFlightLog -= msg->Results.size();
- for (const auto& result : msg->Results) {
- std::unique_ptr<TLogRecord> info(static_cast<TLogRecord *>(result.Cookie));
- Y_VERIFY(info);
-
- StateManager->ExecuteConsistentAction([&] {
- auto it = State.InFlight.find(*info);
- Y_VERIFY(it != State.InFlight.end());
- State.InFlight.erase(it);
-
- const bool success = msg->Status == NKikimrProto::OK;
-
- if (success) {
- State.Confirmed.insert(*info);
- }
-
- // apply chunk commits
- for (TChunkIdx chunkIdx : info->CommitChunks) {
- TState::TChunkInfo& chunk = State.GetChunk(chunkIdx);
- chunk.SetCommitState(success ? ECommitState::COMMITTED : ECommitState::RESERVED);
- }
-
- // apply chunk deletes
- for (TChunkIdx chunkIdx : info->DeleteChunks) {
- auto it = State.Chunks.find(chunkIdx);
- Y_VERIFY(it != State.Chunks.end());
- TState::TChunkInfo& chunk = it->second;
- chunk.SetCommitState(success ? ECommitState::DELETED : ECommitState::COMMITTED);
- if (chunk.GetCommitState() == ECommitState::DELETED) {
- State.Chunks.erase(it);
- }
- }
- });
-
- TStringStream str;
+ for (const auto& result : msg->Results) {
+ std::unique_ptr<TLogRecord> info(static_cast<TLogRecord *>(result.Cookie));
+ Y_VERIFY(info);
+
+ StateManager->ExecuteConsistentAction([&] {
+ auto it = State.InFlight.find(*info);
+ Y_VERIFY(it != State.InFlight.end());
+ State.InFlight.erase(it);
+
+ const bool success = msg->Status == NKikimrProto::OK;
+
+ if (success) {
+ State.Confirmed.insert(*info);
+ }
+
+ // apply chunk commits
+ for (TChunkIdx chunkIdx : info->CommitChunks) {
+ TState::TChunkInfo& chunk = State.GetChunk(chunkIdx);
+ chunk.SetCommitState(success ? ECommitState::COMMITTED : ECommitState::RESERVED);
+ }
+
+ // apply chunk deletes
+ for (TChunkIdx chunkIdx : info->DeleteChunks) {
+ auto it = State.Chunks.find(chunkIdx);
+ Y_VERIFY(it != State.Chunks.end());
+ TState::TChunkInfo& chunk = it->second;
+ chunk.SetCommitState(success ? ECommitState::DELETED : ECommitState::COMMITTED);
+ if (chunk.GetCommitState() == ECommitState::DELETED) {
+ State.Chunks.erase(it);
+ }
+ }
+ });
+
+ TStringStream str;
str << "TEvLogResult " << SelfInfo() << " Lsn# " << result.Lsn <<
- " Status# " << NKikimrProto::EReplyStatus_Name(msg->Status) << Endl;
- Cerr << str.Str();
- }
-
- Activity(ctx);
- }
-
- void IssueAllocateRequest(const TActorContext& ctx) {
+ " Status# " << NKikimrProto::EReplyStatus_Name(msg->Status) << Endl;
+ Cerr << str.Str();
+ }
+
+ Activity(ctx);
+ }
+
+ void IssueAllocateRequest(const TActorContext& ctx) {
SendPDiskRequest(ctx, new NPDisk::TEvChunkReserve(PDiskParams->Owner, PDiskParams->OwnerRound, 1), [] {});
- }
-
+ }
+
void Handle(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
- StateManager->ExecuteConsistentAction([&] {
- for (TChunkIdx chunk : msg->ChunkIds) {
- Y_VERIFY(State.Chunks.count(chunk) == 0);
- State.Chunks.emplace(chunk, TState::TChunkInfo(State.BlocksInChunk));
- }
- });
-
- Activity(ctx);
- }
-
- void IssueWriteRequest(const TActorContext& ctx) {
- // generate list of possible ranges we can select
+ auto *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
+ StateManager->ExecuteConsistentAction([&] {
+ for (TChunkIdx chunk : msg->ChunkIds) {
+ Y_VERIFY(State.Chunks.count(chunk) == 0);
+ State.Chunks.emplace(chunk, TState::TChunkInfo(State.BlocksInChunk));
+ }
+ });
+
+ Activity(ctx);
+ }
+
+ void IssueWriteRequest(const TActorContext& ctx) {
+ // generate list of possible ranges we can select
TMap<TChunkIdx, TDynBitMap> maps;
- for (const auto& pair : State.Chunks) {
- if (pair.second.GetCommitState() != ECommitState::DELETE_IN_PROGRESS) {
- TDynBitMap bm;
- bm.Reserve(State.BlocksInChunk);
- bm.Set(0, State.BlocksInChunk);
- maps.emplace(pair.first, std::move(bm));
- }
- }
-
- // exclude any pending writes from that list
- for (const TWriteRecord& write : State.WritesInFlight) {
- auto it = maps.find(write.ChunkIdx);
- if (it == maps.end()) {
- continue;
- }
-
- TDynBitMap& bm = it->second;
- bm.Reset(write.OffsetInBlocks, write.OffsetInBlocks + write.SizeInBlocks);
- }
-
- // generate set of ranges suitable for writing
+ for (const auto& pair : State.Chunks) {
+ if (pair.second.GetCommitState() != ECommitState::DELETE_IN_PROGRESS) {
+ TDynBitMap bm;
+ bm.Reserve(State.BlocksInChunk);
+ bm.Set(0, State.BlocksInChunk);
+ maps.emplace(pair.first, std::move(bm));
+ }
+ }
+
+ // exclude any pending writes from that list
+ for (const TWriteRecord& write : State.WritesInFlight) {
+ auto it = maps.find(write.ChunkIdx);
+ if (it == maps.end()) {
+ continue;
+ }
+
+ TDynBitMap& bm = it->second;
+ bm.Reset(write.OffsetInBlocks, write.OffsetInBlocks + write.SizeInBlocks);
+ }
+
+ // generate set of ranges suitable for writing
TMultiMap<TChunkIdx, std::pair<ui32, ui32>> ranges;
- for (const auto& p : maps) {
- bool valid = false;
- for (ui32 i = 0, begin; i <= State.BlocksInChunk; ++i) {
- if (i != State.BlocksInChunk && p.second[i]) {
- // mark start of segment
- if (!valid) {
- valid = true;
- begin = i;
- }
- } else if (valid) {
- ranges.emplace(p.first, std::make_pair(begin, i));
- valid = false;
- }
- }
- }
-
- // if there are no valid sets, return
- if (!ranges) {
- return;
- }
-
- // select random range from that set
- auto it = ranges.begin();
- std::advance(it, RandomNumber(ranges.size()));
-
- // extract range offset and size
- const ui32 rangeOffset = it->second.first;
- const ui32 rangeSize = it->second.second - rangeOffset;
-
- // pick up number of blocks to write
- const ui32 numBlocks = 1 + RandomNumber(Min(rangeSize, 20U));
-
- // pick up block offset
- const ui32 offsetInBlocks = rangeOffset + RandomNumber(rangeSize - numBlocks + 1);
-
- // create data buffer
+ for (const auto& p : maps) {
+ bool valid = false;
+ for (ui32 i = 0, begin; i <= State.BlocksInChunk; ++i) {
+ if (i != State.BlocksInChunk && p.second[i]) {
+ // mark start of segment
+ if (!valid) {
+ valid = true;
+ begin = i;
+ }
+ } else if (valid) {
+ ranges.emplace(p.first, std::make_pair(begin, i));
+ valid = false;
+ }
+ }
+ }
+
+ // if there are no valid sets, return
+ if (!ranges) {
+ return;
+ }
+
+ // select random range from that set
+ auto it = ranges.begin();
+ std::advance(it, RandomNumber(ranges.size()));
+
+ // extract range offset and size
+ const ui32 rangeOffset = it->second.first;
+ const ui32 rangeSize = it->second.second - rangeOffset;
+
+ // pick up number of blocks to write
+ const ui32 numBlocks = 1 + RandomNumber(Min(rangeSize, 20U));
+
+ // pick up block offset
+ const ui32 offsetInBlocks = rangeOffset + RandomNumber(rangeSize - numBlocks + 1);
+
+ // create data buffer
TString data = GenerateRandomDataBuffer(numBlocks * PDiskParams->AppendBlockSize);
-
- // calculate checksums for written blocks
+
+ // calculate checksums for written blocks
TVector<ui32> checksums;
- for (ui32 i = 0; i < numBlocks; ++i) {
+ for (ui32 i = 0; i < numBlocks; ++i) {
const char *ptr = data.data() + i * PDiskParams->AppendBlockSize;
- checksums.push_back(Crc32c(ptr, PDiskParams->AppendBlockSize));
- }
-
- TStringStream str;
- str << "TEvChunkWrite ChunkIdx# " << it->first << " OffsetInBlocks# " << offsetInBlocks
- << " SizeInBlocks# " << numBlocks << " Checksums# [";
- bool first = true;
- for (ui32 checksum : checksums) {
- str << (first ? first = false, "" : " ") << Sprintf("%08" PRIx32, checksum);
- }
- str << "]" << Endl;
- Cerr << str.Str();
-
- void *cookie = reinterpret_cast<void *>(NextWriteCookie++);
-
+ checksums.push_back(Crc32c(ptr, PDiskParams->AppendBlockSize));
+ }
+
+ TStringStream str;
+ str << "TEvChunkWrite ChunkIdx# " << it->first << " OffsetInBlocks# " << offsetInBlocks
+ << " SizeInBlocks# " << numBlocks << " Checksums# [";
+ bool first = true;
+ for (ui32 checksum : checksums) {
+ str << (first ? first = false, "" : " ") << Sprintf("%08" PRIx32, checksum);
+ }
+ str << "]" << Endl;
+ Cerr << str.Str();
+
+ void *cookie = reinterpret_cast<void *>(NextWriteCookie++);
+
SendPDiskRequest(ctx, new NPDisk::TEvChunkWrite(PDiskParams->Owner, PDiskParams->OwnerRound, it->first,
offsetInBlocks * PDiskParams->AppendBlockSize, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data),
cookie, true, NPriWrite::HullHugeAsyncBlob), [&] {
- State.WritesInFlight.push_back(TWriteRecord{it->first, offsetInBlocks, numBlocks, std::move(checksums),
- cookie});
- });
- }
-
+ State.WritesInFlight.push_back(TWriteRecord{it->first, offsetInBlocks, numBlocks, std::move(checksums),
+ cookie});
+ });
+ }
+
void Handle(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- Y_VERIFY(msg->Status == NKikimrProto::OK);
-
- StateManager->ExecuteConsistentAction([&] {
- // find write in flight record
- decltype(State.WritesInFlight)::iterator it;
- for (it = State.WritesInFlight.begin(); it != State.WritesInFlight.end(); ++it) {
- if (msg->Cookie == it->Cookie) {
- break;
- }
- }
- Y_VERIFY(it != State.WritesInFlight.end());
- Y_VERIFY(it->ChunkIdx == msg->ChunkIdx);
+ auto *msg = ev->Get();
+ Y_VERIFY(msg->Status == NKikimrProto::OK);
+
+ StateManager->ExecuteConsistentAction([&] {
+ // find write in flight record
+ decltype(State.WritesInFlight)::iterator it;
+ for (it = State.WritesInFlight.begin(); it != State.WritesInFlight.end(); ++it) {
+ if (msg->Cookie == it->Cookie) {
+ break;
+ }
+ }
+ Y_VERIFY(it != State.WritesInFlight.end());
+ Y_VERIFY(it->ChunkIdx == msg->ChunkIdx);
Y_VERIFY(it->Checksums.size() == it->SizeInBlocks);
-
- TStringStream s;
- s << "TEvChunkWriteResult ChunkIdx# " << it->ChunkIdx << " OffsetInBlocks# " << it->OffsetInBlocks
- << " SizeInBlocks# " << it->SizeInBlocks << Endl;
- Cerr << s.Str();
-
- // move data into confirmed state -- set used blocks bits and fill in actual checksums
- TState::TChunkInfo& chunk = State.GetChunk(it->ChunkIdx);
- Y_VERIFY(it->OffsetInBlocks + it->SizeInBlocks <= State.BlocksInChunk);
- chunk.SetChecksums(it->OffsetInBlocks, it->Checksums);
-
- // drop write in flight record
- State.WritesInFlight.erase(it);
- });
-
- // more action!
- Activity(ctx);
- }
-
+
+ TStringStream s;
+ s << "TEvChunkWriteResult ChunkIdx# " << it->ChunkIdx << " OffsetInBlocks# " << it->OffsetInBlocks
+ << " SizeInBlocks# " << it->SizeInBlocks << Endl;
+ Cerr << s.Str();
+
+ // move data into confirmed state -- set used blocks bits and fill in actual checksums
+ TState::TChunkInfo& chunk = State.GetChunk(it->ChunkIdx);
+ Y_VERIFY(it->OffsetInBlocks + it->SizeInBlocks <= State.BlocksInChunk);
+ chunk.SetChecksums(it->OffsetInBlocks, it->Checksums);
+
+ // drop write in flight record
+ State.WritesInFlight.erase(it);
+ });
+
+ // more action!
+ Activity(ctx);
+ }
+
void Handle(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext& ctx) {
- auto *msg = ev->Get();
- TState::TChunkInfo chunk = Recovered.GetChunk(msg->ChunkIdx);
-
- TStringStream str;
- str << "TEvChunkReadResult ChunkIdx# " << msg->ChunkIdx << " Status# "
- << NKikimrProto::EReplyStatus_Name(msg->Status);
-// if (msg->Status == NKikimrProto::OK) {
-// for (ui32 i = 0; i < Recovered.BlocksInChunk; ++i) {
-// const ui32 offset = i * PDiskParams->AppendBlockSize;
-// const bool readable = msg->Data.IsReadable(offset, PDiskParams->AppendBlockSize);
-// const char *data = readable ? msg->Data.DataPtr<const char>(offset) : nullptr;
-// const ui32 checksum = data ? Crc32c(data, PDiskParams->AppendBlockSize) : 0;
-// str << " " << i << ":" << (data ? Sprintf("%08" PRIx32, checksum) : "XXXXXXXX");
-// }
-// }
- str << Endl;
- Cerr << str.Str();
-
- if (msg->Status != NKikimrProto::OK) {
- // this chunk can't be read at all; this means that we don't own it
- Y_VERIFY(chunk.GetCommitState() != ECommitState::COMMITTED);
- } else {
- // this chunk is readable, so it is committed somehow
- Y_VERIFY(chunk.GetCommitState() == ECommitState::COMMITTED
- || chunk.GetCommitState() == ECommitState::COMMIT_IN_PROGRESS
- || chunk.GetCommitState() == ECommitState::DELETE_IN_PROGRESS,
- "ChunkIdx# %" PRIu32 " CommitState# %" PRIu32, msg->ChunkIdx,
- static_cast<ui32>(chunk.GetCommitState()));
- chunk.SetCommitState(ECommitState::COMMITTED);
-
- ui32 offset = 0;
- for (ui32 i = 0; i < Recovered.BlocksInChunk; ++i, offset += PDiskParams->AppendBlockSize) {
- const bool readable = msg->Data.IsReadable(offset, PDiskParams->AppendBlockSize);
- const char *data = readable ? msg->Data.DataPtr<const char>(offset) : nullptr;
- const ui32 checksum = data ? Crc32c(data, PDiskParams->AppendBlockSize) : 0;
-
- if (readable) {
- TStringStream s;
- bool first = true;
- for (const auto& w : Recovered.WritesInFlight) {
- s << (first ? first = false, "" : " ") << "{ChunkIdx# " << w.ChunkIdx << " OffsetInBlocks# "
- << w.OffsetInBlocks << " SizeInBlocks# " << w.SizeInBlocks << " Checksums# [";
- bool firstChecksum = true;
- for (ui32 checksum : w.Checksums) {
- s << (firstChecksum ? firstChecksum = false, "" : " ") << Sprintf("%08" PRIx32, checksum);
- }
- s << "]}";
- }
-
- decltype(TState::WritesInFlight)::const_iterator it;
- for (it = Recovered.WritesInFlight.begin(); it != Recovered.WritesInFlight.end(); ++it) {
- if (it->ChunkIdx == msg->ChunkIdx && i >= it->OffsetInBlocks && i < it->OffsetInBlocks + it->SizeInBlocks &&
- it->Checksums[i - it->OffsetInBlocks] == checksum) {
- break;
- }
- }
- Y_VERIFY(it != Recovered.WritesInFlight.end() || chunk.VerifyChecksum(i, checksum),
- "inconsistent chunk data ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32 " Used# %s"
- " Checksum# %08" PRIx32 " StoredChecksum# %08" PRIx32 " WritesInFlight# %s", msg->ChunkIdx, i,
+ auto *msg = ev->Get();
+ TState::TChunkInfo chunk = Recovered.GetChunk(msg->ChunkIdx);
+
+ TStringStream str;
+ str << "TEvChunkReadResult ChunkIdx# " << msg->ChunkIdx << " Status# "
+ << NKikimrProto::EReplyStatus_Name(msg->Status);
+// if (msg->Status == NKikimrProto::OK) {
+// for (ui32 i = 0; i < Recovered.BlocksInChunk; ++i) {
+// const ui32 offset = i * PDiskParams->AppendBlockSize;
+// const bool readable = msg->Data.IsReadable(offset, PDiskParams->AppendBlockSize);
+// const char *data = readable ? msg->Data.DataPtr<const char>(offset) : nullptr;
+// const ui32 checksum = data ? Crc32c(data, PDiskParams->AppendBlockSize) : 0;
+// str << " " << i << ":" << (data ? Sprintf("%08" PRIx32, checksum) : "XXXXXXXX");
+// }
+// }
+ str << Endl;
+ Cerr << str.Str();
+
+ if (msg->Status != NKikimrProto::OK) {
+ // this chunk can't be read at all; this means that we don't own it
+ Y_VERIFY(chunk.GetCommitState() != ECommitState::COMMITTED);
+ } else {
+ // this chunk is readable, so it is committed somehow
+ Y_VERIFY(chunk.GetCommitState() == ECommitState::COMMITTED
+ || chunk.GetCommitState() == ECommitState::COMMIT_IN_PROGRESS
+ || chunk.GetCommitState() == ECommitState::DELETE_IN_PROGRESS,
+ "ChunkIdx# %" PRIu32 " CommitState# %" PRIu32, msg->ChunkIdx,
+ static_cast<ui32>(chunk.GetCommitState()));
+ chunk.SetCommitState(ECommitState::COMMITTED);
+
+ ui32 offset = 0;
+ for (ui32 i = 0; i < Recovered.BlocksInChunk; ++i, offset += PDiskParams->AppendBlockSize) {
+ const bool readable = msg->Data.IsReadable(offset, PDiskParams->AppendBlockSize);
+ const char *data = readable ? msg->Data.DataPtr<const char>(offset) : nullptr;
+ const ui32 checksum = data ? Crc32c(data, PDiskParams->AppendBlockSize) : 0;
+
+ if (readable) {
+ TStringStream s;
+ bool first = true;
+ for (const auto& w : Recovered.WritesInFlight) {
+ s << (first ? first = false, "" : " ") << "{ChunkIdx# " << w.ChunkIdx << " OffsetInBlocks# "
+ << w.OffsetInBlocks << " SizeInBlocks# " << w.SizeInBlocks << " Checksums# [";
+ bool firstChecksum = true;
+ for (ui32 checksum : w.Checksums) {
+ s << (firstChecksum ? firstChecksum = false, "" : " ") << Sprintf("%08" PRIx32, checksum);
+ }
+ s << "]}";
+ }
+
+ decltype(TState::WritesInFlight)::const_iterator it;
+ for (it = Recovered.WritesInFlight.begin(); it != Recovered.WritesInFlight.end(); ++it) {
+ if (it->ChunkIdx == msg->ChunkIdx && i >= it->OffsetInBlocks && i < it->OffsetInBlocks + it->SizeInBlocks &&
+ it->Checksums[i - it->OffsetInBlocks] == checksum) {
+ break;
+ }
+ }
+ Y_VERIFY(it != Recovered.WritesInFlight.end() || chunk.VerifyChecksum(i, checksum),
+ "inconsistent chunk data ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32 " Used# %s"
+ " Checksum# %08" PRIx32 " StoredChecksum# %08" PRIx32 " WritesInFlight# %s", msg->ChunkIdx, i,
chunk.IsUsed(i) ? "true" : "false", checksum, chunk.GetChecksum(i), s.Str().data());
- chunk.SetChecksums(i, {checksum});
- } else {
- Y_VERIFY(!chunk.IsUsed(i), "unexpected data ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32,
- msg->ChunkIdx, i);
- }
- }
-
- State.Chunks.emplace(msg->ChunkIdx, std::move(chunk));
- }
-
- --ReadMsgPending;
- CheckReadMsgPending(ctx);
- }
-
+ chunk.SetChecksums(i, {checksum});
+ } else {
+ Y_VERIFY(!chunk.IsUsed(i), "unexpected data ChunkIdx# %" PRIu32 " OffsetInBlocks# %" PRIu32,
+ msg->ChunkIdx, i);
+ }
+ }
+
+ State.Chunks.emplace(msg->ChunkIdx, std::move(chunk));
+ }
+
+ --ReadMsgPending;
+ CheckReadMsgPending(ctx);
+ }
+
TString SerializeState() override {
- NPDiskFIT::TFakeVDiskState pb;
-// TStringStream str;
-// str << "VDiskId# " << VDiskId.ToString() << " Owner# " << (PDiskParams ? (int)PDiskParams->Owner : 0)
-// << " StateVerified# " << (StateVerified ? "true" : "false") << Endl;
-// Cerr << str.Str();
- (StateVerified ? State : Recovered).SerializeToProto(pb);
+ NPDiskFIT::TFakeVDiskState pb;
+// TStringStream str;
+// str << "VDiskId# " << VDiskId.ToString() << " Owner# " << (PDiskParams ? (int)PDiskParams->Owner : 0)
+// << " StateVerified# " << (StateVerified ? "true" : "false") << Endl;
+// Cerr << str.Str();
+ (StateVerified ? State : Recovered).SerializeToProto(pb);
TString data;
- bool status = pb.SerializeToString(&data);
- Y_VERIFY(status);
- return data;
- }
-
+ bool status = pb.SerializeToString(&data);
+ Y_VERIFY(status);
+ return data;
+ }
+
TString GenerateRandomDataBuffer(size_t len) {
TString data(len, ' ');
char *mutableData = data.Detach();
- ui64 pattern = RandomNumber<ui64>();
- if (!pattern) {
- pattern = ~pattern;
- }
- size_t i;
- for (i = 0; i + 8 <= len; ++i) {
+ ui64 pattern = RandomNumber<ui64>();
+ if (!pattern) {
+ pattern = ~pattern;
+ }
+ size_t i;
+ for (i = 0; i + 8 <= len; ++i) {
WriteUnaligned<ui64>(mutableData + i, pattern);
- pattern = (pattern ^ pattern << 1 ^ pattern << 3 ^ pattern << 4) >> 63 | pattern << 1;
- }
- while (i < len) {
+ pattern = (pattern ^ pattern << 1 ^ pattern << 3 ^ pattern << 4) >> 63 | pattern << 1;
+ }
+ while (i < len) {
*(char *)(mutableData + i) = pattern;
- pattern >>= 8;
- ++i;
- }
- return data;
- }
-
- STFUNC(StateFunc) {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- CFunc(TEvents::TSystem::Bootstrap, Bootstrap);
+ pattern >>= 8;
+ ++i;
+ }
+ return data;
+ }
+
+ STFUNC(StateFunc) {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ CFunc(TEvents::TSystem::Bootstrap, Bootstrap);
HFunc(NPDisk::TEvYardInitResult, Handle);
HFunc(NPDisk::TEvReadLogResult, Handle);
HFunc(NPDisk::TEvLogResult, Handle);
HFunc(NPDisk::TEvChunkReserveResult, Handle);
HFunc(NPDisk::TEvChunkWriteResult, Handle);
HFunc(NPDisk::TEvChunkReadResult, Handle);
- default: Y_FAIL("unexpected message 0x%08" PRIx32, type);
- }
- }
-};
-
+ default: Y_FAIL("unexpected message 0x%08" PRIx32, type);
+ }
+ }
+};
+
IActor *CreateFakeVDisk(const TVDiskID& vdiskId, const TActorId& pdiskServiceId, ui64 pdiskGuid,
TStateManager *stateManager, TFakeVDiskParams params) {
return new TFakeVDisk(vdiskId, pdiskServiceId, pdiskGuid, stateManager, params);
-}
+}
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h b/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h
index 17a25ef9fbe..6223689105c 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h
@@ -1,18 +1,18 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
#include <ydb/core/protos/pdiskfit.pb.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
-#include <util/system/event.h>
-
-using namespace NActors;
-using namespace NKikimr;
-
-class TStateManager;
-
+#include <util/system/event.h>
+
+using namespace NActors;
+using namespace NKikimr;
+
+class TStateManager;
+
struct TFakeVDiskParams {
// 0 means no limit
ui32 LogsToBeSent = 0;
@@ -28,39 +28,39 @@ struct TFakeVDiskParams {
IActor *CreateFakeVDisk(const TVDiskID& vdiskId, const TActorId& pdiskServiceId, ui64 pdiskGuid,
TStateManager *stateManager, TFakeVDiskParams params);
-
-class TBasicTest : public TActorBootstrapped<TBasicTest> {
- TAutoEvent *StopEvent = nullptr;
- TStateManager *StateManager = nullptr;
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- TIntrusivePtr<TPDiskConfig> PDiskConfig;
+
+class TBasicTest : public TActorBootstrapped<TBasicTest> {
+ TAutoEvent *StopEvent = nullptr;
+ TStateManager *StateManager = nullptr;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+ TIntrusivePtr<TPDiskConfig> PDiskConfig;
TActorId PDiskServiceId;
- const ui32 NumVDisks;
+ const ui32 NumVDisks;
bool InduceLogSplicing;
-
-public:
+
+public:
TBasicTest(ui32 numVDisks, bool induceLogSplicing)
- : NumVDisks(numVDisks)
+ : NumVDisks(numVDisks)
, InduceLogSplicing(induceLogSplicing)
- {}
-
- template<typename TEnv>
- void Run(TEnv *env, TAutoEvent *stopEvent, TStateManager *stateManager) {
- StopEvent = stopEvent;
- StateManager = stateManager;
- Counters = env->Counters;
+ {}
+
+ template<typename TEnv>
+ void Run(TEnv *env, TAutoEvent *stopEvent, TStateManager *stateManager) {
+ StopEvent = stopEvent;
+ StateManager = stateManager;
+ Counters = env->Counters;
PDiskConfig = new TPDiskConfig(env->PDiskFilePath, env->PDiskGuid, 1,
TPDiskCategory(TPDiskCategory::DEVICE_TYPE_ROT, 0).GetRaw());
PDiskConfig->GetDriveDataSwitch = NKikimrBlobStorage::TPDiskConfig::DoNotTouch;
PDiskConfig->WriteCacheSwitch = NKikimrBlobStorage::TPDiskConfig::DoNotTouch;
- env->ActorSystem->Register(this);
- }
-
- void Bootstrap(const TActorContext& ctx) {
- CreatePDiskActor(ctx);
+ env->ActorSystem->Register(this);
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ CreatePDiskActor(ctx);
TVector<TActorId> actors;
- for (ui32 i = 0; i < NumVDisks; ++i) {
- TVDiskID vdiskId(i, 0, 0, 0, 0);
+ for (ui32 i = 0; i < NumVDisks; ++i) {
+ TVDiskID vdiskId(i, 0, 0, 0, 0);
TFakeVDiskParams params;
if (InduceLogSplicing) {
params.LogCutProbability = 1e-3;
@@ -72,37 +72,37 @@ public:
}
TActorId actorId = ctx.ExecutorThread.ActorSystem->Register(CreateFakeVDisk(vdiskId, PDiskServiceId,
PDiskConfig->PDiskGuid, StateManager, params));
- actors.push_back(actorId);
- }
+ actors.push_back(actorId);
+ }
for (const TActorId& actor : actors) {
- ctx.Send(actor, new TEvents::TEvBootstrap);
- }
- Become(&TBasicTest::StateFunc);
- }
-
- void CreatePDiskActor(const TActorContext& ctx) {
- Y_VERIFY(Counters);
- Y_VERIFY(ctx.ExecutorThread.ActorSystem);
- Y_VERIFY(PDiskConfig);
- Y_VERIFY(AppData(ctx));
- std::unique_ptr<IActor> pdiskActor(CreatePDisk(PDiskConfig, 1, Counters->GetSubgroup("subsystem", "pdisk")));
- const TActorId actorId = ctx.ExecutorThread.ActorSystem->Register(pdiskActor.release(), TMailboxType::Simple,
- AppData(ctx)->SystemPoolId);
- PDiskServiceId = MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskConfig->PDiskId);
- ctx.ExecutorThread.ActorSystem->RegisterLocalService(PDiskServiceId, actorId);
- }
-
- void Finish(const TActorContext& ctx) {
- LOG_NOTICE(ctx, NActorsServices::TEST, "TBasicTest::Finish called");
- Die(ctx);
- Y_VERIFY(StopEvent);
- StopEvent->Signal();
- }
-
- STFUNC(StateFunc) {
- Y_UNUSED(ctx);
- switch (const ui32 type = ev->GetTypeRewrite()) {
- default: Y_FAIL("unexpected message 0x%08" PRIx32, type);
- }
- }
-};
+ ctx.Send(actor, new TEvents::TEvBootstrap);
+ }
+ Become(&TBasicTest::StateFunc);
+ }
+
+ void CreatePDiskActor(const TActorContext& ctx) {
+ Y_VERIFY(Counters);
+ Y_VERIFY(ctx.ExecutorThread.ActorSystem);
+ Y_VERIFY(PDiskConfig);
+ Y_VERIFY(AppData(ctx));
+ std::unique_ptr<IActor> pdiskActor(CreatePDisk(PDiskConfig, 1, Counters->GetSubgroup("subsystem", "pdisk")));
+ const TActorId actorId = ctx.ExecutorThread.ActorSystem->Register(pdiskActor.release(), TMailboxType::Simple,
+ AppData(ctx)->SystemPoolId);
+ PDiskServiceId = MakeBlobStoragePDiskID(ctx.ExecutorThread.ActorSystem->NodeId, PDiskConfig->PDiskId);
+ ctx.ExecutorThread.ActorSystem->RegisterLocalService(PDiskServiceId, actorId);
+ }
+
+ void Finish(const TActorContext& ctx) {
+ LOG_NOTICE(ctx, NActorsServices::TEST, "TBasicTest::Finish called");
+ Die(ctx);
+ Y_VERIFY(StopEvent);
+ StopEvent->Signal();
+ }
+
+ STFUNC(StateFunc) {
+ Y_UNUSED(ctx);
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ default: Y_FAIL("unexpected message 0x%08" PRIx32, type);
+ }
+ }
+};
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h b/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h
index 7e0bfa05e06..03ad0f597e1 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h
@@ -1,8 +1,8 @@
-#pragma once
-
-#include "objectwithstate.h"
-#include "state_manager.h"
-
+#pragma once
+
+#include "objectwithstate.h"
+#include "state_manager.h"
+
#include <ydb/core/base/appdata.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_tools.h>
#include <ydb/library/pdisk_io/aio.h>
@@ -11,72 +11,72 @@
#include <library/cpp/actors/core/executor_pool_io.h>
#include <library/cpp/actors/core/scheduler_basic.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-
+
#include <library/cpp/lwtrace/all.h>
#include <library/cpp/monlib/dynamic_counters/counters.h>
#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/folder/tempdir.h>
-#include <util/system/atomic.h>
-#include <util/system/event.h>
-#include <util/random/fast.h>
-
-#include <sys/wait.h>
-
-class TFailInjector {
- TAtomic FailCounter = 0;
- TAutoEvent FailEvent;
-
-public:
- void SetFailCounter(ui32 failCounter) {
- AtomicSet(FailCounter, failCounter);
- }
-
- void Inject(ui64 /*cookie*/) {
- TAtomicBase result = AtomicDecrement(FailCounter);
- if (result < 0) {
- // overshoot, return one position back
- AtomicIncrement(FailCounter);
- } else if (result == 0) {
- // just came to zero, signal fail event
- FailEvent.Signal();
- }
-
- // block this thread indefinitely if fail has arrived
- if (result <= 0) {
- BlockThread();
- }
- }
-
- void WaitForFailure() {
- FailEvent.WaitI();
- }
-
-private:
- static void BlockThread() {
- // just sleep for one second, and then sleep again :-)
- for (;;) {
- NanoSleep(1000 * 1000 * 1000);
- }
- }
-};
-
-class TFailInjectionActionExecutor : public NLWTrace::TCustomActionExecutor {
- TFailInjector *Injector;
-
-public:
- TFailInjectionActionExecutor(NLWTrace::TProbe *probe, TFailInjector *injector)
- : NLWTrace::TCustomActionExecutor(probe, true /* destructive */)
- , Injector(injector)
- {}
-
-private:
+
+#include <util/folder/tempdir.h>
+#include <util/system/atomic.h>
+#include <util/system/event.h>
+#include <util/random/fast.h>
+
+#include <sys/wait.h>
+
+class TFailInjector {
+ TAtomic FailCounter = 0;
+ TAutoEvent FailEvent;
+
+public:
+ void SetFailCounter(ui32 failCounter) {
+ AtomicSet(FailCounter, failCounter);
+ }
+
+ void Inject(ui64 /*cookie*/) {
+ TAtomicBase result = AtomicDecrement(FailCounter);
+ if (result < 0) {
+ // overshoot, return one position back
+ AtomicIncrement(FailCounter);
+ } else if (result == 0) {
+ // just came to zero, signal fail event
+ FailEvent.Signal();
+ }
+
+ // block this thread indefinitely if fail has arrived
+ if (result <= 0) {
+ BlockThread();
+ }
+ }
+
+ void WaitForFailure() {
+ FailEvent.WaitI();
+ }
+
+private:
+ static void BlockThread() {
+ // just sleep for one second, and then sleep again :-)
+ for (;;) {
+ NanoSleep(1000 * 1000 * 1000);
+ }
+ }
+};
+
+class TFailInjectionActionExecutor : public NLWTrace::TCustomActionExecutor {
+ TFailInjector *Injector;
+
+public:
+ TFailInjectionActionExecutor(NLWTrace::TProbe *probe, TFailInjector *injector)
+ : NLWTrace::TCustomActionExecutor(probe, true /* destructive */)
+ , Injector(injector)
+ {}
+
+private:
bool DoExecute(NLWTrace::TOrbit&, const NLWTrace::TParams& params) override {
- Injector->Inject(params.Param[0].Get<ui64>());
- return true;
- }
-};
-
+ Injector->Inject(params.Param[0].Get<ui64>());
+ return true;
+ }
+};
+
class TFailCounterGenerator {
};
@@ -97,244 +97,244 @@ ui32 GenerateFailCounter(bool frequentFails) {
}
}
-struct TPDiskFailureInjectionTest {
- // default values for unit test
- ui32 NumIterations = 10; // 0 = unlimited
+struct TPDiskFailureInjectionTest {
+ // default values for unit test
+ ui32 NumIterations = 10; // 0 = unlimited
ui32 NumFailsInIteration = 1000; // 0 = unlimited
- TTempDir TempDir;
+ TTempDir TempDir;
TString PDiskFilePath;
ui64 DiskSize = 16ULL << 30; // 10 GB
- ui32 ChunkSize = 16 << 20; // 16 MB
- ui32 SectorSize = 4 << 10; // 4 KB
- ui64 PDiskGuid;
- bool ErasureEncode = false;
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
-
+ ui32 ChunkSize = 16 << 20; // 16 MB
+ ui32 SectorSize = 4 << 10; // 4 KB
+ ui64 PDiskGuid;
+ bool ErasureEncode = false;
+
+ TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
+
TProgramShouldContinue KikimrShouldContinue;
- std::unique_ptr<NKikimr::TAppData> AppData;
+ std::unique_ptr<NKikimr::TAppData> AppData;
std::shared_ptr<NKikimr::NPDisk::IIoContextFactory> IoContext;
- std::unique_ptr<NActors::TActorSystem> ActorSystem;
-
- TAutoEvent StopEvent;
-
+ std::unique_ptr<NActors::TActorSystem> ActorSystem;
+
+ TAutoEvent StopEvent;
+
NLWTrace::TManager TraceManager;
-
- TMaybe<TDuration> TestDuration;
-
- TPDiskFailureInjectionTest()
- : TraceManager(*Singleton<NLWTrace::TProbeRegistry>(), true)
- {}
-
- void Setup() {
- // generate temporary pdisk file name if not set
- if (!PDiskFilePath) {
- PDiskFilePath = TempDir() + "pdisk.bin";
- }
-
- // generate random guid
- PDiskGuid = Now().GetValue();
-
- // format pdisk
- NKikimr::FormatPDisk(PDiskFilePath, DiskSize, SectorSize, ChunkSize, PDiskGuid, 1, 1, 1, 1, "text message",
- ErasureEncode);
-
- Cerr << "created pdisk at " << PDiskFilePath << Endl;
- }
-
- void SetupLWTrace(TFailInjector *injector) {
- const char *name = "FailInjectionAction";
-
- NLWTrace::TQuery query;
- auto& block = *query.AddBlocks();
- auto& desc = *block.MutableProbeDesc();
+
+ TMaybe<TDuration> TestDuration;
+
+ TPDiskFailureInjectionTest()
+ : TraceManager(*Singleton<NLWTrace::TProbeRegistry>(), true)
+ {}
+
+ void Setup() {
+ // generate temporary pdisk file name if not set
+ if (!PDiskFilePath) {
+ PDiskFilePath = TempDir() + "pdisk.bin";
+ }
+
+ // generate random guid
+ PDiskGuid = Now().GetValue();
+
+ // format pdisk
+ NKikimr::FormatPDisk(PDiskFilePath, DiskSize, SectorSize, ChunkSize, PDiskGuid, 1, 1, 1, 1, "text message",
+ ErasureEncode);
+
+ Cerr << "created pdisk at " << PDiskFilePath << Endl;
+ }
+
+ void SetupLWTrace(TFailInjector *injector) {
+ const char *name = "FailInjectionAction";
+
+ NLWTrace::TQuery query;
+ auto& block = *query.AddBlocks();
+ auto& desc = *block.MutableProbeDesc();
desc.SetName("PDiskFailInjection");
- desc.SetProvider("FAIL_INJECTION_PROVIDER");
- auto& action = *block.AddAction();
- auto& custom = *action.MutableCustomAction();
- custom.SetName(name);
-
+ desc.SetProvider("FAIL_INJECTION_PROVIDER");
+ auto& action = *block.AddAction();
+ auto& custom = *action.MutableCustomAction();
+ custom.SetName(name);
+
auto factory = [=](NLWTrace::TProbe *probe, const NLWTrace::TCustomAction& /*action*/, NLWTrace::TSession* /*session*/) {
- return new TFailInjectionActionExecutor(probe, injector);
- };
-
- TraceManager.RegisterCustomAction(name, factory);
- TraceManager.New("env", query);
- }
-
- void InitActorSystem() {
- using namespace NActors;
-
- // create counters
- Counters = new NMonitoring::TDynamicCounters;
-
- // initialize app data with pool ids and registries
- AppData.reset(new NKikimr::TAppData(0u, 1u, 2u, 3u, {}, nullptr, nullptr, nullptr, &KikimrShouldContinue));
+ return new TFailInjectionActionExecutor(probe, injector);
+ };
+
+ TraceManager.RegisterCustomAction(name, factory);
+ TraceManager.New("env", query);
+ }
+
+ void InitActorSystem() {
+ using namespace NActors;
+
+ // create counters
+ Counters = new NMonitoring::TDynamicCounters;
+
+ // initialize app data with pool ids and registries
+ AppData.reset(new NKikimr::TAppData(0u, 1u, 2u, 3u, {}, nullptr, nullptr, nullptr, &KikimrShouldContinue));
IoContext = std::make_shared<NKikimr::NPDisk::TIoContextFactoryOSS>();
AppData->IoContextFactory = IoContext.get();
-
- // create actor system setup environment
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 4; // system, user, io, batch
+
+ // create actor system setup environment
+ auto setup = MakeHolder<TActorSystemSetup>();
+ setup->NodeId = 1;
+ setup->ExecutorsCount = 4; // system, user, io, batch
setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
- setup->Executors[0] = new TBasicExecutorPool(AppData->SystemPoolId, 8, 10);
- setup->Executors[1] = new TBasicExecutorPool(AppData->UserPoolId, 8, 10);
- setup->Executors[2] = new TIOExecutorPool(AppData->IOPoolId, 10);
- setup->Executors[3] = new TBasicExecutorPool(AppData->BatchPoolId, 8, 10);
- setup->Scheduler = new TBasicSchedulerThread(TSchedulerConfig(512, 100));
-
- // initialize logger settings
+ setup->Executors[0] = new TBasicExecutorPool(AppData->SystemPoolId, 8, 10);
+ setup->Executors[1] = new TBasicExecutorPool(AppData->UserPoolId, 8, 10);
+ setup->Executors[2] = new TIOExecutorPool(AppData->IOPoolId, 10);
+ setup->Executors[3] = new TBasicExecutorPool(AppData->BatchPoolId, 8, 10);
+ setup->Scheduler = new TBasicSchedulerThread(TSchedulerConfig(512, 100));
+
+ // initialize logger settings
const TActorId loggerId(setup->NodeId, "logger");
-
- TIntrusivePtr<NLog::TSettings> loggerSettings = new NLog::TSettings(loggerId, NKikimrServices::LOGGER,
- NActors::NLog::PRI_NOTICE, NActors::NLog::PRI_DEBUG, 0);
-
+
+ TIntrusivePtr<NLog::TSettings> loggerSettings = new NLog::TSettings(loggerId, NKikimrServices::LOGGER,
+ NActors::NLog::PRI_NOTICE, NActors::NLog::PRI_DEBUG, 0);
+
loggerSettings->Append(
NActorsServices::EServiceCommon_MIN,
NActorsServices::EServiceCommon_MAX,
NActorsServices::EServiceCommon_Name
);
-
+
loggerSettings->Append(
NKikimrServices::EServiceKikimr_MIN,
NKikimrServices::EServiceKikimr_MAX,
NKikimrServices::EServiceKikimr_Name
);
-
+
TString explanation;
loggerSettings->SetLevel(NActors::NLog::PRI_INFO, NKikimrServices::BS_PDISK, explanation);
loggerSettings->SetLevel(NActors::NLog::PRI_DEBUG, NKikimrServices::BS_PDISK_TEST, explanation);
- // create/register logger actor
- auto logger = std::make_unique<TLoggerActor>(loggerSettings, CreateStderrBackend(),
- Counters->GetSubgroup("logger", "counters"));
- setup->LocalServices.emplace_back(loggerId, TActorSetupCmd(logger.release(), TMailboxType::Simple, 0));
-
- // create and then initialize actor system
- ActorSystem = std::make_unique<TActorSystem>(setup, AppData.get(), loggerSettings);
- }
-
- template<typename TTest>
+ // create/register logger actor
+ auto logger = std::make_unique<TLoggerActor>(loggerSettings, CreateStderrBackend(),
+ Counters->GetSubgroup("logger", "counters"));
+ setup->LocalServices.emplace_back(loggerId, TActorSetupCmd(logger.release(), TMailboxType::Simple, 0));
+
+ // create and then initialize actor system
+ ActorSystem = std::make_unique<TActorSystem>(setup, AppData.get(), loggerSettings);
+ }
+
+ template<typename TTest>
void Run(TTest *test, TStateManager *stateManager, const TString& data = {}) {
- TObjectWithState::DeserializeCommonState(data);
- InitActorSystem();
- ActorSystem->Start();
- LOG_NOTICE(*ActorSystem, NActorsServices::TEST, "actor system started");
- test->Run(this, &StopEvent, stateManager);
- }
-
+ TObjectWithState::DeserializeCommonState(data);
+ InitActorSystem();
+ ActorSystem->Start();
+ LOG_NOTICE(*ActorSystem, NActorsServices::TEST, "actor system started");
+ test->Run(this, &StopEvent, stateManager);
+ }
+
//template<bool FREQUENT_FAILS, typename TTest, typename... TArgs>
- template<typename TTest, typename... TArgs>
+ template<typename TTest, typename... TArgs>
void RunCycle(bool frequentFails, TArgs&&... args) {
- TInstant startTime = TInstant::Now();
-
- for (ui32 iteration = 0; NumIterations == 0 || iteration < NumIterations; ++iteration) {
- Cerr << "iteration# " << iteration << Endl;
-
- // reset pdisk to initial state
- Setup();
-
- // stored common state
+ TInstant startTime = TInstant::Now();
+
+ for (ui32 iteration = 0; NumIterations == 0 || iteration < NumIterations; ++iteration) {
+ Cerr << "iteration# " << iteration << Endl;
+
+ // reset pdisk to initial state
+ Setup();
+
+ // stored common state
TString state;
-
- for (ui32 fail = 0; NumFailsInIteration == 0 || fail < NumFailsInIteration; ++fail) {
- if (TestDuration && TInstant::Now() >= startTime + *TestDuration) {
- return;
- }
-
- Cerr << "iteration# " << iteration << " fail# " << fail << " stateLen# " << state.size() << Endl;
-
- int fds[2];
- if (pipe(fds) != 0) {
- Y_FAIL("pipe failed");
- }
-
- pid_t pid = fork();
- if (pid == 0) {
- // close read end of pipe
- close(fds[0]);
-
- TFailInjector injector;
-
- TReallyFastRng32 rng(Now().GetValue());
-
+
+ for (ui32 fail = 0; NumFailsInIteration == 0 || fail < NumFailsInIteration; ++fail) {
+ if (TestDuration && TInstant::Now() >= startTime + *TestDuration) {
+ return;
+ }
+
+ Cerr << "iteration# " << iteration << " fail# " << fail << " stateLen# " << state.size() << Endl;
+
+ int fds[2];
+ if (pipe(fds) != 0) {
+ Y_FAIL("pipe failed");
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ // close read end of pipe
+ close(fds[0]);
+
+ TFailInjector injector;
+
+ TReallyFastRng32 rng(Now().GetValue());
+
ui32 failCounter = GenerateFailCounter(frequentFails);
- injector.SetFailCounter(failCounter);
- Cerr << "failCounter# " << failCounter << Endl;
-
- SetupLWTrace(&injector);
- TStateManager stateManager;
- Run(new TTest(TArgs(args)...), &stateManager, state);
- injector.WaitForFailure();
- stateManager.StopRunning();
-
- // store common state into variable...
- state = TObjectWithState::SerializeCommonState();
-
- // ...and move it through pipe
- size_t pos = 0;
+ injector.SetFailCounter(failCounter);
+ Cerr << "failCounter# " << failCounter << Endl;
+
+ SetupLWTrace(&injector);
+ TStateManager stateManager;
+ Run(new TTest(TArgs(args)...), &stateManager, state);
+ injector.WaitForFailure();
+ stateManager.StopRunning();
+
+ // store common state into variable...
+ state = TObjectWithState::SerializeCommonState();
+
+ // ...and move it through pipe
+ size_t pos = 0;
while (pos < state.size()) {
ssize_t written = write(fds[1], state.data() + pos, state.size() - pos);
- if (written == -1) {
- if (errno == EINTR) {
- continue;
- } else {
- perror("write to pipe failed");
- abort();
- }
- } else {
- pos += written;
- }
- }
-
- // close write end of pipe
- close(fds[1]);
-
- // terminate
- raise(SIGKILL);
- } else if (pid > 0) {
- Cerr << "pid# " << pid << Endl;
-
- // close write end of pipe
- close(fds[1]);
-
- // read buffer from pipe
- state.clear();
- for (;;) {
- char buffer[4096];
- ssize_t len = read(fds[0], buffer, sizeof(buffer));
- if (len == -1) {
- if (errno != EINTR) {
- Y_FAIL("unexpected error: %s", strerror(errno));
- }
- continue;
- } else if (!len) {
- break;
- } else {
- state.append(buffer, len);
- }
- }
-
- // close read end of pipe
- close(fds[0]);
-
- // wait for child to terminate
- int status = 0;
- if (waitpid(pid, &status, 0) != pid) {
- Y_FAIL("waitpid failed with error: %s", strerror(errno));
- }
-
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- if (sig != SIGKILL) {
- Y_FAIL("unexpected termination signal: %d pid# %d", sig, (int)pid);
- }
- }
- } else {
- perror("failed to fork");
- }
- }
- }
- }
-};
+ if (written == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ perror("write to pipe failed");
+ abort();
+ }
+ } else {
+ pos += written;
+ }
+ }
+
+ // close write end of pipe
+ close(fds[1]);
+
+ // terminate
+ raise(SIGKILL);
+ } else if (pid > 0) {
+ Cerr << "pid# " << pid << Endl;
+
+ // close write end of pipe
+ close(fds[1]);
+
+ // read buffer from pipe
+ state.clear();
+ for (;;) {
+ char buffer[4096];
+ ssize_t len = read(fds[0], buffer, sizeof(buffer));
+ if (len == -1) {
+ if (errno != EINTR) {
+ Y_FAIL("unexpected error: %s", strerror(errno));
+ }
+ continue;
+ } else if (!len) {
+ break;
+ } else {
+ state.append(buffer, len);
+ }
+ }
+
+ // close read end of pipe
+ close(fds[0]);
+
+ // wait for child to terminate
+ int status = 0;
+ if (waitpid(pid, &status, 0) != pid) {
+ Y_FAIL("waitpid failed with error: %s", strerror(errno));
+ }
+
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ if (sig != SIGKILL) {
+ Y_FAIL("unexpected termination signal: %d pid# %d", sig, (int)pid);
+ }
+ }
+ } else {
+ perror("failed to fork");
+ }
+ }
+ }
+ }
+};
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.cpp b/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.cpp
index e6759d60b29..1dc54bb5500 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.cpp
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.cpp
@@ -1,54 +1,54 @@
-#include "objectwithstate.h"
+#include "objectwithstate.h"
#include <ydb/core/protos/pdiskfit.pb.h>
-
-TMutex TObjectWithState::Mutex;
-TIntrusiveList<TObjectWithState> TObjectWithState::ObjectsWithState;
+
+TMutex TObjectWithState::Mutex;
+TIntrusiveList<TObjectWithState> TObjectWithState::ObjectsWithState;
THashMap<TString, TString> TObjectWithState::States;
-
+
TObjectWithState::TObjectWithState(TString name)
- : Name(std::move(name))
-{}
-
-TObjectWithState::~TObjectWithState() {
- TGuard<TMutex> lock(Mutex);
- TIntrusiveListItem<TObjectWithState>::Unlink();
-}
-
-void TObjectWithState::Register() {
- TGuard<TMutex> lock(Mutex);
- ObjectsWithState.PushBack(this);
-}
-
+ : Name(std::move(name))
+{}
+
+TObjectWithState::~TObjectWithState() {
+ TGuard<TMutex> lock(Mutex);
+ TIntrusiveListItem<TObjectWithState>::Unlink();
+}
+
+void TObjectWithState::Register() {
+ TGuard<TMutex> lock(Mutex);
+ ObjectsWithState.PushBack(this);
+}
+
TString TObjectWithState::SerializeCommonState() {
- TGuard<TMutex> lock(Mutex);
- for (TObjectWithState& object : ObjectsWithState) {
- States[object.Name] = object.SerializeState();
- }
- NPDiskFIT::TObjectWithStateDict dict;
- for (const auto& kv : States) {
- auto *item = dict.AddItems();
- item->SetKey(kv.first);
- item->SetValue(kv.second);
-
- }
+ TGuard<TMutex> lock(Mutex);
+ for (TObjectWithState& object : ObjectsWithState) {
+ States[object.Name] = object.SerializeState();
+ }
+ NPDiskFIT::TObjectWithStateDict dict;
+ for (const auto& kv : States) {
+ auto *item = dict.AddItems();
+ item->SetKey(kv.first);
+ item->SetValue(kv.second);
+
+ }
TString data;
- bool status = dict.SerializeToString(&data);
- Y_VERIFY(status);
- return data;
-}
-
+ bool status = dict.SerializeToString(&data);
+ Y_VERIFY(status);
+ return data;
+}
+
void TObjectWithState::DeserializeCommonState(const TString& data) {
- NPDiskFIT::TObjectWithStateDict dict;
- bool status = dict.ParseFromString(data);
- Y_VERIFY(status);
- for (const auto& item : dict.GetItems()) {
- Y_VERIFY(item.HasKey());
- Y_VERIFY(item.HasValue());
- States.emplace(item.GetKey(), item.GetValue());
- }
-}
-
+ NPDiskFIT::TObjectWithStateDict dict;
+ bool status = dict.ParseFromString(data);
+ Y_VERIFY(status);
+ for (const auto& item : dict.GetItems()) {
+ Y_VERIFY(item.HasKey());
+ Y_VERIFY(item.HasValue());
+ States.emplace(item.GetKey(), item.GetValue());
+ }
+}
+
TString TObjectWithState::GetState() {
- auto it = States.find(Name);
+ auto it = States.find(Name);
return it != States.end() ? it->second : TString();
-}
+}
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.h b/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.h
index 3ce790ce1e9..6955dcc73f0 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.h
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/objectwithstate.h
@@ -1,30 +1,30 @@
-#pragma once
-
-#include <util/generic/hash.h>
+#pragma once
+
+#include <util/generic/hash.h>
#include <util/generic/string.h>
-#include <util/system/mutex.h>
-#include <util/generic/intrlist.h>
-
-class TObjectWithState
- : public TIntrusiveListItem<TObjectWithState>
-{
+#include <util/system/mutex.h>
+#include <util/generic/intrlist.h>
+
+class TObjectWithState
+ : public TIntrusiveListItem<TObjectWithState>
+{
TString Name;
-
-public:
+
+public:
TObjectWithState(TString name);
- virtual ~TObjectWithState();
+ virtual ~TObjectWithState();
virtual TString SerializeState() = 0;
-
- // call register after full initialization of derived class
- void Register();
-
+
+ // call register after full initialization of derived class
+ void Register();
+
TString GetState();
-
+
static TString SerializeCommonState();
static void DeserializeCommonState(const TString& data);
-
-private:
- static TMutex Mutex;
- static TIntrusiveList<TObjectWithState> ObjectsWithState;
+
+private:
+ static TMutex Mutex;
+ static TIntrusiveList<TObjectWithState> ObjectsWithState;
static THashMap<TString, TString> States;
-};
+};
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/state_manager.h b/ydb/core/blobstorage/ut_pdiskfit/lib/state_manager.h
index bbb32fb8f48..de7b6777c8c 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/state_manager.h
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/state_manager.h
@@ -1,85 +1,85 @@
-#pragma once
-
-#include <util/system/datetime.h>
-#include <util/system/atomic.h>
-#include <util/system/event.h>
-
-class TStateManager {
- // "running" flag
- static constexpr TAtomicBase RunningFlag = TAtomicBase(1) << (CHAR_BIT * sizeof(TAtomicBase) - 1);
-
- // state consists of single 'running' flag indicating actions are allowed and a spin lock controlling parallel
- // execution of several actions
- TAtomic State = RunningFlag;
-
- TManualEvent Event;
-
-public:
- // executes consistent action -- that is, doesn't allow to return from "StopRunning" until action is carried out
- // or block indefinitely if stop already occured
- template<typename TFunc>
- void ExecuteConsistentAction(TFunc&& func) {
- for (;;) {
- // atomically obtain current value of state variable
- const TAtomicBase current = AtomicGet(State);
-
- // check if we are already not running
- if (~current & RunningFlag) {
- // there was no 'Running' flag set, so we can't execute this action and have to block this thread
- // for eternity; also we have to return spin lock value to previous state
- for (;;) {
- NanoSleep(1000 * 1000 * 1000);
- }
- }
-
- // calculate update value -- just increment it by one
- const TAtomicBase update = current + 1;
-
- // try atomic update; exit loop if succeeds
- if (AtomicCas(&State, update, current)) {
- break;
- }
- }
-
- // we have acquired lock and main thread can't pass StopRunning() point, if it occurs while we are executing
- // this action
- func();
-
- // release spin lock
- const TAtomicBase value = AtomicDecrement(State);
- if (!value) {
- // this happens when at acquisition of spin lock there was 'Running' flag set and now we have just released
- // last reference and 'Running' flag was cleared after we have acquired spin lock; so it means that main
- // thread is waiting for Event now (or going to wait for it later) and we have to set it to inform that
- // we have stopped
- Event.Signal();
- }
- }
-
- void StopRunning() {
- TAtomicBase write;
-
- for (;;) {
- TAtomicBase expected = AtomicGet(State);
- Y_VERIFY(expected & RunningFlag);
-
- // clear 'running' flag in the state
- write = expected & ~RunningFlag;
-
- // try to write new value
- if (AtomicCas(&State, write, expected)) {
- break;
- }
- }
-
- // we have just written new value 'write' without 'running' flag; if write is not zero, this means that some
- // thread was executing action at the moment 'write' was written :) and one of executors would signal Event
- // when it finishes
- if (write) {
- Event.WaitI();
- }
-
- // ensure that there were not writes left
- Y_VERIFY(AtomicGet(State) == 0);
- }
-};
+#pragma once
+
+#include <util/system/datetime.h>
+#include <util/system/atomic.h>
+#include <util/system/event.h>
+
+class TStateManager {
+ // "running" flag
+ static constexpr TAtomicBase RunningFlag = TAtomicBase(1) << (CHAR_BIT * sizeof(TAtomicBase) - 1);
+
+ // state consists of single 'running' flag indicating actions are allowed and a spin lock controlling parallel
+ // execution of several actions
+ TAtomic State = RunningFlag;
+
+ TManualEvent Event;
+
+public:
+ // executes consistent action -- that is, doesn't allow to return from "StopRunning" until action is carried out
+ // or block indefinitely if stop already occured
+ template<typename TFunc>
+ void ExecuteConsistentAction(TFunc&& func) {
+ for (;;) {
+ // atomically obtain current value of state variable
+ const TAtomicBase current = AtomicGet(State);
+
+ // check if we are already not running
+ if (~current & RunningFlag) {
+ // there was no 'Running' flag set, so we can't execute this action and have to block this thread
+ // for eternity; also we have to return spin lock value to previous state
+ for (;;) {
+ NanoSleep(1000 * 1000 * 1000);
+ }
+ }
+
+ // calculate update value -- just increment it by one
+ const TAtomicBase update = current + 1;
+
+ // try atomic update; exit loop if succeeds
+ if (AtomicCas(&State, update, current)) {
+ break;
+ }
+ }
+
+ // we have acquired lock and main thread can't pass StopRunning() point, if it occurs while we are executing
+ // this action
+ func();
+
+ // release spin lock
+ const TAtomicBase value = AtomicDecrement(State);
+ if (!value) {
+ // this happens when at acquisition of spin lock there was 'Running' flag set and now we have just released
+ // last reference and 'Running' flag was cleared after we have acquired spin lock; so it means that main
+ // thread is waiting for Event now (or going to wait for it later) and we have to set it to inform that
+ // we have stopped
+ Event.Signal();
+ }
+ }
+
+ void StopRunning() {
+ TAtomicBase write;
+
+ for (;;) {
+ TAtomicBase expected = AtomicGet(State);
+ Y_VERIFY(expected & RunningFlag);
+
+ // clear 'running' flag in the state
+ write = expected & ~RunningFlag;
+
+ // try to write new value
+ if (AtomicCas(&State, write, expected)) {
+ break;
+ }
+ }
+
+ // we have just written new value 'write' without 'running' flag; if write is not zero, this means that some
+ // thread was executing action at the moment 'write' was written :) and one of executors would signal Event
+ // when it finishes
+ if (write) {
+ Event.WaitI();
+ }
+
+ // ensure that there were not writes left
+ Y_VERIFY(AtomicGet(State) == 0);
+ }
+};
diff --git a/ydb/core/blobstorage/ut_pdiskfit/lib/ya.make b/ydb/core/blobstorage/ut_pdiskfit/lib/ya.make
index 7f9b9ba495c..9fd61462edc 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/lib/ya.make
+++ b/ydb/core/blobstorage/ut_pdiskfit/lib/ya.make
@@ -2,8 +2,8 @@ OWNER(
alexvru
g:kikimr
)
-
-LIBRARY()
+
+LIBRARY()
SRCS(
basic_test.cpp
@@ -17,4 +17,4 @@ PEERDIR(
ydb/library/pdisk_io
)
-END()
+END()
diff --git a/ydb/core/blobstorage/ut_pdiskfit/pdiskfit/pdiskfit.cpp b/ydb/core/blobstorage/ut_pdiskfit/pdiskfit/pdiskfit.cpp
index cb4ec086f9a..e7a6aa184b7 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/pdiskfit/pdiskfit.cpp
+++ b/ydb/core/blobstorage/ut_pdiskfit/pdiskfit/pdiskfit.cpp
@@ -2,96 +2,96 @@
#include <ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h>
#include <library/cpp/getopt/last_getopt.h>
#include <library/cpp/string_utils/parse_size/parse_size.h>
-
-using namespace NLastGetopt;
-
-int main(int argc, char *argv[]) {
+
+using namespace NLastGetopt;
+
+int main(int argc, char *argv[]) {
TString device;
- NSize::TSize size;
- ui32 numIterations = 100;
- ui32 numFailsPerIteration = 100;
- NSize::TSize chunkSize = 16 << 20;
- NSize::TSize sectorSize = 4 << 10;
- bool erasureEncode = false;
+ NSize::TSize size;
+ ui32 numIterations = 100;
+ ui32 numFailsPerIteration = 100;
+ NSize::TSize chunkSize = 16 << 20;
+ NSize::TSize sectorSize = 4 << 10;
+ bool erasureEncode = false;
TString test;
- ui32 numVDisks = 4;
-
- TOpts opts = TOpts::Default();
-
- opts.AddHelpOption();
-
- opts.AddLongOption("device")
- .StoreResult(&device)
- .Help("path to device/regular file to store PDisk in")
- .RequiredArgument("DEVICE")
- .Required();
-
- opts.AddLongOption("size")
- .StoreResult(&size)
- .Help("size of PDisk in case when DEVICE is a regular file")
- .RequiredArgument("SIZE")
- .Optional();
-
- opts.AddLongOption("num-iterations")
- .StoreResult(&numIterations)
- .Help("number of iterations to perform (0 = unlimited)")
- .RequiredArgument("NUM")
- .Optional();
-
- opts.AddLongOption("num-fails-per-iteration")
- .StoreResult(&numFailsPerIteration)
- .Help("number of fails per single iteration to simulate (0 = unlimited)")
- .RequiredArgument("NUM")
- .Optional();
-
- opts.AddLongOption("chunk-size")
- .StoreResult(&chunkSize)
- .Help("chunk size")
- .RequiredArgument("SIZE")
- .Optional();
-
- opts.AddLongOption("sector-size")
- .StoreResult(&sectorSize)
- .Help("sector size")
- .RequiredArgument("SIZE")
- .Optional();
-
- opts.AddLongOption("test")
- .StoreResult(&test)
- .Help("type of test to run")
- .RequiredArgument("TEST")
- .Optional()
- .DefaultValue("basic");
-
- opts.AddLongOption("num-vdisks")
- .StoreResult(&numVDisks)
- .Help("number of VDisk to spawn on PDisk")
- .RequiredArgument("NUM")
- .Optional();
-
- opts.AddLongOption("erasure-encode")
- .SetFlag(&erasureEncode)
- .Help("enable erasure encoding of pdisk");
-
- opts.SetFreeArgsMax(0);
-
- TOptsParseResult result(&opts, argc, argv);
-
- TPDiskFailureInjectionTest fit;
- fit.NumIterations = numIterations;
- fit.NumFailsInIteration = numFailsPerIteration;
- fit.PDiskFilePath = device;
- fit.DiskSize = size;
- fit.ChunkSize = chunkSize;
- fit.SectorSize = sectorSize;
- fit.ErasureEncode = erasureEncode;
-
- if (test == "basic") {
+ ui32 numVDisks = 4;
+
+ TOpts opts = TOpts::Default();
+
+ opts.AddHelpOption();
+
+ opts.AddLongOption("device")
+ .StoreResult(&device)
+ .Help("path to device/regular file to store PDisk in")
+ .RequiredArgument("DEVICE")
+ .Required();
+
+ opts.AddLongOption("size")
+ .StoreResult(&size)
+ .Help("size of PDisk in case when DEVICE is a regular file")
+ .RequiredArgument("SIZE")
+ .Optional();
+
+ opts.AddLongOption("num-iterations")
+ .StoreResult(&numIterations)
+ .Help("number of iterations to perform (0 = unlimited)")
+ .RequiredArgument("NUM")
+ .Optional();
+
+ opts.AddLongOption("num-fails-per-iteration")
+ .StoreResult(&numFailsPerIteration)
+ .Help("number of fails per single iteration to simulate (0 = unlimited)")
+ .RequiredArgument("NUM")
+ .Optional();
+
+ opts.AddLongOption("chunk-size")
+ .StoreResult(&chunkSize)
+ .Help("chunk size")
+ .RequiredArgument("SIZE")
+ .Optional();
+
+ opts.AddLongOption("sector-size")
+ .StoreResult(&sectorSize)
+ .Help("sector size")
+ .RequiredArgument("SIZE")
+ .Optional();
+
+ opts.AddLongOption("test")
+ .StoreResult(&test)
+ .Help("type of test to run")
+ .RequiredArgument("TEST")
+ .Optional()
+ .DefaultValue("basic");
+
+ opts.AddLongOption("num-vdisks")
+ .StoreResult(&numVDisks)
+ .Help("number of VDisk to spawn on PDisk")
+ .RequiredArgument("NUM")
+ .Optional();
+
+ opts.AddLongOption("erasure-encode")
+ .SetFlag(&erasureEncode)
+ .Help("enable erasure encoding of pdisk");
+
+ opts.SetFreeArgsMax(0);
+
+ TOptsParseResult result(&opts, argc, argv);
+
+ TPDiskFailureInjectionTest fit;
+ fit.NumIterations = numIterations;
+ fit.NumFailsInIteration = numFailsPerIteration;
+ fit.PDiskFilePath = device;
+ fit.DiskSize = size;
+ fit.ChunkSize = chunkSize;
+ fit.SectorSize = sectorSize;
+ fit.ErasureEncode = erasureEncode;
+
+ if (test == "basic") {
fit.RunCycle<TBasicTest>(false, numVDisks, false);
- } else {
- Cerr << "unknown test type " << test << Endl;
- return 1;
- }
-
- return 0;
-}
+ } else {
+ Cerr << "unknown test type " << test << Endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/ydb/core/blobstorage/ut_pdiskfit/ut/main.cpp b/ydb/core/blobstorage/ut_pdiskfit/ut/main.cpp
index 011d7cf8398..4ba48439de0 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/ut/main.cpp
+++ b/ydb/core/blobstorage/ut_pdiskfit/ut/main.cpp
@@ -1,43 +1,43 @@
#include <ydb/core/blobstorage/ut_pdiskfit/lib/fail_injection_test.h>
#include <ydb/core/blobstorage/ut_pdiskfit/lib/basic_test.h>
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/system/sanitizers.h>
class TWatchdogThread : public ISimpleThread {
- TMutex Mutex;
- TCondVar Stop;
+ TMutex Mutex;
+ TCondVar Stop;
TAtomic QuitFlag = 0;
-
-public:
- ~TWatchdogThread() {
+
+public:
+ ~TWatchdogThread() {
AtomicSet(QuitFlag, 1);
- with_lock (Mutex) {
- Stop.Signal();
- }
-
- Join();
- }
-
- void *ThreadProc() override {
- with_lock (Mutex) {
- do {
+ with_lock (Mutex) {
+ Stop.Signal();
+ }
+
+ Join();
+ }
+
+ void *ThreadProc() override {
+ with_lock (Mutex) {
+ do {
Cerr << Sprintf("Watchdog# %s\n", TInstant::Now().ToString().data());
} while (!AtomicGet(QuitFlag) && !Stop.WaitT(Mutex, TDuration::Seconds(5)));
- }
-
- return nullptr;
- }
-};
-
+ }
+
+ return nullptr;
+ }
+};
+
Y_UNIT_TEST_SUITE(TPDiskFIT) {
Y_UNIT_TEST(Basic) {
- TWatchdogThread watchdog;
- watchdog.Start();
- TPDiskFailureInjectionTest test;
+ TWatchdogThread watchdog;
+ watchdog.Start();
+ TPDiskFailureInjectionTest test;
test.TestDuration = NSan::PlainOrUnderSanitizer(TDuration::Minutes(4), TDuration::Minutes(3));
test.RunCycle<TBasicTest>(false, 8, false);
- }
+ }
Y_UNIT_TEST(FailTest) {
TWatchdogThread watchdog;
@@ -54,4 +54,4 @@ Y_UNIT_TEST_SUITE(TPDiskFIT) {
test.TestDuration = NSan::PlainOrUnderSanitizer(TDuration::Minutes(4), TDuration::Minutes(3));
test.RunCycle<TBasicTest>(true, 8, true);
}
-}
+}
diff --git a/ydb/core/blobstorage/ut_pdiskfit/ya.make b/ydb/core/blobstorage/ut_pdiskfit/ya.make
index 9198f894e79..9c5c43be5fc 100644
--- a/ydb/core/blobstorage/ut_pdiskfit/ya.make
+++ b/ydb/core/blobstorage/ut_pdiskfit/ya.make
@@ -2,7 +2,7 @@ OWNER(
alexvru
g:kikimr
)
-
+
RECURSE(
pdiskfit
lib
diff --git a/ydb/core/blobstorage/ut_vdisk/gen_restarts.cpp b/ydb/core/blobstorage/ut_vdisk/gen_restarts.cpp
index 3a09796dbae..18afc3c9b6a 100644
--- a/ydb/core/blobstorage/ut_vdisk/gen_restarts.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/gen_restarts.cpp
@@ -3,15 +3,15 @@
void WriteRestartRead(const TWriteRestartReadSettings &settings, TDuration testTimeout) {
TConfiguration Conf;
- Conf.Prepare(settings.WriteRunSetup.get());
- std::shared_ptr<TSet<ui32>> badSteps(new TSet<ui32>());
+ Conf.Prepare(settings.WriteRunSetup.get());
+ std::shared_ptr<TSet<ui32>> badSteps(new TSet<ui32>());
TManyPutsTest w(false, settings.MsgNum, settings.MsgSize, settings.Cls, badSteps);
bool success1 = Conf.Run<TManyPutsTest>(&w, testTimeout);
UNIT_ASSERT(success1);
Conf.Shutdown();
- Conf.Prepare(settings.ReadRunSetup.get(), false);
+ Conf.Prepare(settings.ReadRunSetup.get(), false);
TManyGetsTest r(false, settings.MsgNum, settings.MsgSize, settings.Cls, badSteps);
bool success2 = Conf.Run<TManyGetsTest>(&r, testTimeout);
UNIT_ASSERT(success2);
@@ -20,15 +20,15 @@ void WriteRestartRead(const TWriteRestartReadSettings &settings, TDuration testT
void MultiPutWriteRestartRead(const TMultiPutWriteRestartReadSettings &settings, TDuration testTimeout) {
TConfiguration Conf;
- Conf.Prepare(settings.WriteRunSetup.get());
- std::shared_ptr<TSet<ui32>> badSteps(new TSet<ui32>());
+ Conf.Prepare(settings.WriteRunSetup.get());
+ std::shared_ptr<TSet<ui32>> badSteps(new TSet<ui32>());
TManyMultiPutsTest w(false, settings.MsgNum, settings.MsgSize, settings.BatchSize, settings.Cls, badSteps);
bool success1 = Conf.Run<TManyMultiPutsTest>(&w, testTimeout);
UNIT_ASSERT(success1);
Conf.Shutdown();
- Conf.Prepare(settings.ReadRunSetup.get(), false);
+ Conf.Prepare(settings.ReadRunSetup.get(), false);
TManyGetsTest r(false, settings.MsgNum, settings.MsgSize, settings.Cls, badSteps);
bool success2 = Conf.Run<TManyGetsTest>(&r, testTimeout);
UNIT_ASSERT(success2);
@@ -37,9 +37,9 @@ void MultiPutWriteRestartRead(const TMultiPutWriteRestartReadSettings &settings,
void ChaoticWriteRestartWrite(const TChaoticWriteRestartWriteSettings &settings, TDuration testTimeout) {
TConfiguration Conf;
- Conf.Prepare(settings.WriteRunSetup.get());
+ Conf.Prepare(settings.WriteRunSetup.get());
- auto cls1 = std::make_shared<TPutHandleClassGenerator>(settings.Cls);
+ auto cls1 = std::make_shared<TPutHandleClassGenerator>(settings.Cls);
TChaoticManyPutsTest w(settings.Parallel, settings.MsgNum, settings.MsgSize, cls1, settings.WorkingTime,
settings.RequestTimeout);
bool success1 = Conf.Run<TChaoticManyPutsTest>(&w, testTimeout);
@@ -47,8 +47,8 @@ void ChaoticWriteRestartWrite(const TChaoticWriteRestartWriteSettings &settings,
UNIT_ASSERT(success1);
Conf.Shutdown();
- Conf.Prepare(settings.WriteRunSetup.get(), false);
- auto cls2 = std::make_shared<TPutHandleClassGenerator>(settings.Cls);
+ Conf.Prepare(settings.WriteRunSetup.get(), false);
+ auto cls2 = std::make_shared<TPutHandleClassGenerator>(settings.Cls);
TChaoticManyPutsTest x(settings.Parallel, 1, settings.MsgSize, cls2, settings.WorkingTime,
settings.RequestTimeout);
bool success2 = Conf.Run<TChaoticManyPutsTest>(&x, testTimeout);
diff --git a/ydb/core/blobstorage/ut_vdisk/gen_restarts.h b/ydb/core/blobstorage/ut_vdisk/gen_restarts.h
index 4f3e170c0de..fbacfad14f6 100644
--- a/ydb/core/blobstorage/ut_vdisk/gen_restarts.h
+++ b/ydb/core/blobstorage/ut_vdisk/gen_restarts.h
@@ -13,16 +13,16 @@ struct TWriteRestartReadSettings {
const ui32 MsgSize;
const EClass Cls;
// VDisk setup for write phase
- const std::shared_ptr<IVDiskSetup> WriteRunSetup;
+ const std::shared_ptr<IVDiskSetup> WriteRunSetup;
// VDisk setup for read phase
- const std::shared_ptr<IVDiskSetup> ReadRunSetup;
+ const std::shared_ptr<IVDiskSetup> ReadRunSetup;
TWriteRestartReadSettings(
ui32 msgNum,
ui32 msgSize,
EClass cls,
- std::shared_ptr<IVDiskSetup> writeRunSetup,
- std::shared_ptr<IVDiskSetup> readRunSetup)
+ std::shared_ptr<IVDiskSetup> writeRunSetup,
+ std::shared_ptr<IVDiskSetup> readRunSetup)
: MsgNum(msgNum)
, MsgSize(msgSize)
, Cls(cls)
@@ -34,7 +34,7 @@ struct TWriteRestartReadSettings {
ui32 msgNum,
ui32 msgSize,
EClass cls,
- std::shared_ptr<IVDiskSetup> setup) {
+ std::shared_ptr<IVDiskSetup> setup) {
return TWriteRestartReadSettings(msgNum, msgSize, cls, setup, setup);
}
};
@@ -49,17 +49,17 @@ struct TMultiPutWriteRestartReadSettings {
const ui32 MsgSize;
const EClass Cls;
// VDisk setup for write phase
- const std::shared_ptr<IVDiskSetup> WriteRunSetup;
+ const std::shared_ptr<IVDiskSetup> WriteRunSetup;
// VDisk setup for read phase
- const std::shared_ptr<IVDiskSetup> ReadRunSetup;
+ const std::shared_ptr<IVDiskSetup> ReadRunSetup;
TMultiPutWriteRestartReadSettings(
ui32 msgNum,
ui32 batchSize,
ui32 msgSize,
EClass cls,
- std::shared_ptr<IVDiskSetup> writeRunSetup,
- std::shared_ptr<IVDiskSetup> readRunSetup)
+ std::shared_ptr<IVDiskSetup> writeRunSetup,
+ std::shared_ptr<IVDiskSetup> readRunSetup)
: MsgNum(msgNum)
, BatchSize(batchSize)
, MsgSize(msgSize)
@@ -73,7 +73,7 @@ struct TMultiPutWriteRestartReadSettings {
ui32 batchSize,
ui32 msgSize,
EClass cls,
- std::shared_ptr<IVDiskSetup> setup) {
+ std::shared_ptr<IVDiskSetup> setup) {
return TMultiPutWriteRestartReadSettings(msgNum, batchSize, msgSize, cls, setup, setup);
}
};
diff --git a/ydb/core/blobstorage/ut_vdisk/huge_migration_ut.cpp b/ydb/core/blobstorage/ut_vdisk/huge_migration_ut.cpp
index db1731d569c..8248739ca2e 100644
--- a/ydb/core/blobstorage/ut_vdisk/huge_migration_ut.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/huge_migration_ut.cpp
@@ -22,9 +22,9 @@ Y_UNIT_TEST_SUITE(THugeMigration) {
}
void ExtendMap(ui32 msgSize) {
- auto vdiskWriteSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskWriteSetup = std::make_shared<TFastVDiskSetup>();
vdiskWriteSetup->AddConfigModifier(OldMap);
- auto vdiskReadSetup = std::make_shared <TFastVDiskSetup>();
+ auto vdiskReadSetup = std::make_shared <TFastVDiskSetup>();
vdiskReadSetup->AddConfigModifier(NewMap);
TWriteRestartReadSettings settings(100, msgSize, HUGEB, vdiskWriteSetup, vdiskReadSetup);
WriteRestartRead(settings, TIMEOUT);
@@ -48,9 +48,9 @@ Y_UNIT_TEST_SUITE(THugeMigration) {
// 1. New Map: we write huge blobs (both for new and old maps)
// 2. Rollback map and restart
// 3. We successfully read these blobs
- auto vdiskWriteSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskWriteSetup = std::make_shared<TFastVDiskSetup>();
vdiskWriteSetup->AddConfigModifier(NewMap);
- auto vdiskReadSetup = std::make_shared <TFastVDiskSetup>();
+ auto vdiskReadSetup = std::make_shared <TFastVDiskSetup>();
vdiskReadSetup->AddConfigModifier(OldMap);
TWriteRestartReadSettings settings(100, 66u << 10u, HUGEB, vdiskWriteSetup, vdiskReadSetup);
WriteRestartRead(settings, TIMEOUT);
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/astest.h b/ydb/core/blobstorage/ut_vdisk/lib/astest.h
index 2cf254eff2c..192433b1d39 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/astest.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/astest.h
@@ -33,10 +33,10 @@ public:
private:
TProgramShouldContinue KikimrShouldContinue;
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- std::unique_ptr<NActors::TMon> Monitoring;
- std::unique_ptr<NKikimr::TAppData> AppData;
+ std::unique_ptr<NActors::TMon> Monitoring;
+ std::unique_ptr<NKikimr::TAppData> AppData;
std::shared_ptr<NKikimr::NPDisk::IIoContextFactory> IoContext;
- std::unique_ptr<NActors::TActorSystem> ActorSystem1;
+ std::unique_ptr<NActors::TActorSystem> ActorSystem1;
TSystemEvent DoneEvent { TSystemEvent::rAuto };
public:
ui16 MonPort;
@@ -51,7 +51,7 @@ inline void TTestWithActorSystem::Run(NActors::IActor *testActor) {
nameserverTable->StaticNodeTable[1] = std::pair<TString, ui32>("127.0.0.1", pm.GetPort(12001));
nameserverTable->StaticNodeTable[2] = std::pair<TString, ui32>("127.0.0.1", pm.GetPort(12002));
- auto setup1 = MakeHolder<TActorSystemSetup>();
+ auto setup1 = MakeHolder<TActorSystemSetup>();
setup1->NodeId = 1;
setup1->ExecutorsCount = 4;
setup1->Executors.Reset(new TAutoPtr<IExecutorPool>[4]);
@@ -117,13 +117,13 @@ inline void TTestWithActorSystem::Run(NActors::IActor *testActor) {
loggerActor->Log(Now(), NKikimr::NLog::PRI_NOTICE, NActorsServices::TEST, "Monitoring settings set up");
//////////////////////////////////////////////////////////////////////////////
- AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(),
+ AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(),
nullptr, nullptr, &KikimrShouldContinue));
AppData->Counters = Counters;
- AppData->Mon = Monitoring.get();
+ AppData->Mon = Monitoring.get();
IoContext = std::make_shared<NKikimr::NPDisk::TIoContextFactoryOSS>();
AppData->IoContextFactory = IoContext.get();
- ActorSystem1.reset(new TActorSystem(setup1, AppData.get(), logSettings));
+ ActorSystem1.reset(new TActorSystem(setup1, AppData.get(), logSettings));
loggerActor->Log(Now(), NKikimr::NLog::PRI_NOTICE, NActorsServices::TEST, "Actor system created");
@@ -134,5 +134,5 @@ inline void TTestWithActorSystem::Run(NActors::IActor *testActor) {
DoneEvent.Wait();
ActorSystem1->Stop();
- ActorSystem1.reset();
+ ActorSystem1.reset();
}
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/dataset.cpp b/ydb/core/blobstorage/ut_vdisk/lib/dataset.cpp
index 89e383aea55..40c594290be 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/dataset.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/dataset.cpp
@@ -138,7 +138,7 @@ IDataGenerator* CreateBlobGenerator(ui64 maxCumSize, ui32 maxNumBlobs, ui32 minB
// generate pseudorandom data with step and size seed
TString data = GenerateData(size);
- ui32 numDisks = Info->Type.BlobSubgroupSize();
+ ui32 numDisks = Info->Type.BlobSubgroupSize();
ui32 handoff = Info->Type.Handoff();
// find matching LogoBlobID
@@ -149,13 +149,13 @@ IDataGenerator* CreateBlobGenerator(ui64 maxCumSize, ui32 maxNumBlobs, ui32 minB
id = TLogoBlobID(tabletId, 1, ++Step, 0, size, 0);
ui32 hash = id.Hash();
for (const TVDiskID& vDiskID : MatchingVDisks) {
- TBlobStorageGroupInfo::TVDiskIds vDisks;
- TBlobStorageGroupInfo::TServiceIds services;
- Info->PickSubgroup(hash, &vDisks, &services);
- for (ui32 i = 0; i < numDisks - handoff; ++i) {
- if (vDisks[i] == vDiskID) {
- goodId = true;
- break;
+ TBlobStorageGroupInfo::TVDiskIds vDisks;
+ TBlobStorageGroupInfo::TServiceIds services;
+ Info->PickSubgroup(hash, &vDisks, &services);
+ for (ui32 i = 0; i < numDisks - handoff; ++i) {
+ if (vDisks[i] == vDiskID) {
+ goodId = true;
+ break;
}
}
if (goodId)
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/helpers.cpp b/ydb/core/blobstorage/ut_vdisk/lib/helpers.cpp
index b73da3df8db..03e967be04e 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/helpers.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/helpers.cpp
@@ -112,17 +112,17 @@ class TRangeGet : public TActorBootstrapped<TRangeGet> {
LOG_NOTICE(ctx, NActorsServices::TEST,
" RANGE READ: from=%s to=%s\n", ReadFrom.ToString().data(), ReadTo.ToString().data());
-
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- ReadFrom,
- ReadTo,
- MaxResults);
-
- ctx.Send(VDiskInfo.ActorID, req.release());
+
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ ReadFrom,
+ ReadTo,
+ MaxResults);
+
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
void CheckOrder(const NKikimrBlobStorage::TEvVGetResult &rec,
@@ -167,19 +167,19 @@ class TRangeGet : public TActorBootstrapped<TRangeGet> {
public:
TRangeGet(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- const TLogoBlobID &readFrom, const TLogoBlobID &readTo, bool /*indexOnly*/, ui32 maxResults)
+ const TLogoBlobID &readFrom, const TLogoBlobID &readTo, bool /*indexOnly*/, ui32 maxResults)
: TActorBootstrapped<TRangeGet>()
, NotifyID(notifyID)
, VDiskInfo(vdiskInfo)
, ReadFrom(readFrom)
, ReadTo(readTo)
, MaxResults(maxResults)
- {}
+ {}
};
IActor *CreateRangeGet(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
const TLogoBlobID &readFrom, const TLogoBlobID &readTo, bool indexOnly, ui32 maxResults) {
- Y_VERIFY(indexOnly);
+ Y_VERIFY(indexOnly);
return new TRangeGet(notifyID, vdiskInfo, readFrom, readTo, indexOnly, maxResults);
}
@@ -194,19 +194,19 @@ class TManyPuts : public TActorBootstrapped<TManyPuts> {
TActorId NotifyID;
const TAllVDisks::TVDiskInstance VDiskInfo;
- std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
+ std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
ui32 MsgNum;
const ui64 TabletId;
const ui32 Channel;
const ui32 Gen;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
const TDuration RequestTimeout;
TVector<TPut> Puts;
ui32 PutIdx;
TActorId QueueActorId;
- bool Started = false;
+ bool Started = false;
// how many deadline statuses we got
ui64 RequestDeadlines = 0;
@@ -215,21 +215,21 @@ class TManyPuts : public TActorBootstrapped<TManyPuts> {
void Bootstrap(const TActorContext &ctx) {
Become(&TThis::StateWriteFunc);
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters = new NMonitoring::TDynamicCounters;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters = new NMonitoring::TDynamicCounters;
TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
- QueueActorId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
- NKikimrBlobStorage::PutTabletLog, counters, new TBSProxyContext{counters}, {}, "PutTabletLog", 0, false,
- TDuration::Minutes(10), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
- }
-
- void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& ctx) {
- if (ev->Get()->IsConnected && !Started) {
- // put logo blob
- SendPut(ctx);
- Started = true;
- }
- }
-
+ QueueActorId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
+ NKikimrBlobStorage::PutTabletLog, counters, new TBSProxyContext{counters}, {}, "PutTabletLog", 0, false,
+ TDuration::Minutes(10), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
+ }
+
+ void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& ctx) {
+ if (ev->Get()->IsConnected && !Started) {
+ // put logo blob
+ SendPut(ctx);
+ Started = true;
+ }
+ }
+
void Finish(const TActorContext &ctx) {
// Finished
const bool noTimeout = RequestTimeout == TDuration::Seconds(0);
@@ -260,7 +260,7 @@ class TManyPuts : public TActorBootstrapped<TManyPuts> {
if (mainVDiskId == VDiskInfo.VDiskID) {
const bool noTimeout = RequestTimeout == TDuration::Seconds(0);
const TInstant deadline = noTimeout ? TInstant::Max() : TInstant::Now() + RequestTimeout;
- ctx.Send(QueueActorId,
+ ctx.Send(QueueActorId,
new TEvBlobStorage::TEvVPut(logoBlobID, put.Data, VDiskInfo.VDiskID, false,
nullptr, deadline, HandleClassGen->GetHandleClass()));
return;
@@ -319,7 +319,7 @@ class TManyPuts : public TActorBootstrapped<TManyPuts> {
public:
TManyPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout)
: TActorBootstrapped<TManyPuts>()
, Conf(conf)
@@ -338,8 +338,8 @@ public:
}
TManyPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout)
: TActorBootstrapped<TManyPuts>()
, Conf(conf)
@@ -360,15 +360,15 @@ public:
IActor *CreateManyPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout) {
return new TManyPuts(conf, notifyID, vdiskInfo, msgDataSize, msgNum, tabletId, channel, gen, cls, badSteps,
requestTimeout);
}
IActor *CreateManyPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout) {
return new TManyPuts(conf, notifyID, vdiskInfo, msgPacks, tabletId, channel, gen, cls, badSteps, requestTimeout);
}
@@ -384,8 +384,8 @@ class TManyMultiPuts : public TActorBootstrapped<TManyMultiPuts> {
const ui64 TabletId;
const ui32 Channel;
const ui32 Gen;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
const TDuration RequestTimeout;
TVector<ui32> Steps;
ui32 Step;
@@ -404,9 +404,9 @@ class TManyMultiPuts : public TActorBootstrapped<TManyMultiPuts> {
TIntrusivePtr<NMonitoring::TDynamicCounters> counters = new NMonitoring::TDynamicCounters;
TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
- QueueActorId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
- NKikimrBlobStorage::PutTabletLog, counters, new TBSProxyContext{counters}, {}, "PutTabletLog", 0, false,
- TDuration::Minutes(10), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
+ QueueActorId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
+ NKikimrBlobStorage::PutTabletLog, counters, new TBSProxyContext{counters}, {}, "PutTabletLog", 0, false,
+ TDuration::Minutes(10), flowRecord, NMonitoring::TCountableBase::EVisibility::Public));
}
void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& ctx) {
@@ -437,7 +437,7 @@ class TManyMultiPuts : public TActorBootstrapped<TManyMultiPuts> {
const bool noTimeout = RequestTimeout == TDuration::Seconds(0);
const TInstant deadline = noTimeout ? TInstant::Max() : TInstant::Now() + RequestTimeout;
- std::unique_ptr<TEvBlobStorage::TEvVMultiPut> vMultiPut(
+ std::unique_ptr<TEvBlobStorage::TEvVMultiPut> vMultiPut(
new TEvBlobStorage::TEvVMultiPut(VDiskInfo.VDiskID, deadline, HandleClassGen->GetHandleClass(),
false, nullptr));
while (Step < MsgNum) {
@@ -463,7 +463,7 @@ class TManyMultiPuts : public TActorBootstrapped<TManyMultiPuts> {
}
if (putCount) {
- ctx.Send(QueueActorId, vMultiPut.release());
+ ctx.Send(QueueActorId, vMultiPut.release());
LastBatchSize = putCount;
return;
}
@@ -513,7 +513,7 @@ class TManyMultiPuts : public TActorBootstrapped<TManyMultiPuts> {
public:
TManyMultiPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui32 batchSize, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout)
: TActorBootstrapped<TManyMultiPuts>()
, Conf(conf)
@@ -544,7 +544,7 @@ public:
IActor *CreateManyMultiPuts(TConfiguration *conf, const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui32 batchSize, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout) {
return new TManyMultiPuts(conf, notifyID, vdiskInfo, msgDataSize, msgNum, batchSize, tabletId, channel, gen, cls,
badSteps, requestTimeout);
@@ -559,7 +559,7 @@ class TManyGets : public TActorBootstrapped<TManyGets> {
const ui64 TabletId;
const ui32 Channel;
const ui32 Gen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<TSet<ui32>> BadSteps;
ui32 Step;
TString MsgData;
@@ -577,13 +577,13 @@ class TManyGets : public TActorBootstrapped<TManyGets> {
if (Step % 100 == 0)
LOG_NOTICE(ctx, NActorsServices::TEST, "GET Step=%u", Step);
TLogoBlobID logoBlobID(TabletId, Gen, Step, Channel, MsgData.size(), 0, 1);
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {logoBlobID});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {logoBlobID});
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
void Check(const TActorContext &ctx, const NKikimrBlobStorage::TEvVGetResult &rec) {
@@ -625,7 +625,7 @@ class TManyGets : public TActorBootstrapped<TManyGets> {
public:
TManyGets(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo, ui32 msgDataSize, ui32 msgNum,
- ui64 tabletId, ui32 channel, ui32 gen, std::shared_ptr<TSet<ui32>> badSteps)
+ ui64 tabletId, ui32 channel, ui32 gen, std::shared_ptr<TSet<ui32>> badSteps)
: TActorBootstrapped<TManyGets>()
, NotifyID(notifyID)
, VDiskInfo(vdiskInfo)
@@ -645,7 +645,7 @@ public:
};
IActor *CreateManyGets(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo, ui32 msgDataSize,
- ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen, std::shared_ptr<TSet<ui32>> badSteps) {
+ ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen, std::shared_ptr<TSet<ui32>> badSteps) {
return new TManyGets(notifyID, vdiskInfo, msgDataSize, msgNum, tabletId, channel, gen, badSteps);
}
@@ -654,7 +654,7 @@ class TGet : public TActorBootstrapped<TGet> {
TActorId NotifyID;
const TAllVDisks::TVDiskInstance VDiskInfo;
ui32 MsgNum;
- std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
+ std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
const ui64 TabletId;
const ui32 Channel;
const ui32 Gen;
@@ -685,7 +685,7 @@ class TGet : public TActorBootstrapped<TGet> {
TLogoBlobID logoBlobID(TabletId, Gen, i, Channel, data.size(), 0, 1);
req->AddExtremeQuery(logoBlobID, Shift, data.size() - Shift, &i);
}
- ctx.Send(VDiskInfo.ActorID, req.release());
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
void Check(const TActorContext &ctx, const NKikimrBlobStorage::TEvVGetResult &rec) {
@@ -768,7 +768,7 @@ public:
}
TGet(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
ui64 tabletId, ui32 channel, ui32 gen, ui64 shift, bool withErrorResponse)
: TActorBootstrapped<TGet>()
, NotifyID(notifyID)
@@ -790,7 +790,7 @@ IActor *CreateGet(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vd
}
IActor *CreateGet(const TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen, ui64 shift,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen, ui64 shift,
bool withErrorResponse) {
return new TGet(notifyID, vdiskInfo, msgPacks, tabletId, channel, gen, shift, withErrorResponse);
}
@@ -815,7 +815,7 @@ class TPutGC : public TActorBootstrapped<TPutGC> {
TThis::Become(&TThis::StateFunc);
ctx.Send(VDiskInfo.ActorID,
new TEvBlobStorage::TEvVCollectGarbage(TabletID, RecGen, RecGenCounter, Channel, Collect, CollectGen,
- CollectStep, false, Keep.Get(), DoNotKeep.Get(), VDiskInfo.VDiskID,
+ CollectStep, false, Keep.Get(), DoNotKeep.Get(), VDiskInfo.VDiskID,
TInstant::Max()));
}
@@ -874,7 +874,7 @@ class TWaitForCompactionOneDisk : public TActorBootstrapped<TWaitForCompactionOn
}
void Handle(TEvBlobStorage::TEvVCompactResult::TPtr &ev, const TActorContext &ctx) {
- if (ev->Get()->Record.GetStatus() == NKikimrProto::OK) {
+ if (ev->Get()->Record.GetStatus() == NKikimrProto::OK) {
Become(&TThis::StateWait);
ctx.Send(VDiskInfo.ActorID, new TEvBlobStorage::TEvVStatus(VDiskInfo.VDiskID));
} else {
@@ -933,7 +933,7 @@ class TWaitForCompaction : public TActorBootstrapped<TWaitForCompaction> {
void Bootstrap(const TActorContext &ctx) {
Become(&TThis::StateFunc);
- ui32 total = Conf->GroupInfo->GetTotalVDisksNum();
+ ui32 total = Conf->GroupInfo->GetTotalVDisksNum();
for (ui32 i = 0; i < total; i++) {
TAllVDisks::TVDiskInstance &instance = Conf->VDisks->Get(i);
ctx.RegisterWithSameMailbox(CreateWaitForCompaction(ctx.SelfID, instance));
@@ -1316,7 +1316,7 @@ class TPutGCToCorrespondingVDisksActor : public TActorBootstrapped<TPutGCToCorre
void Bootstrap(const TActorContext &ctx) {
TThis::Become(&TThis::StateFunc);
- ui32 total = Conf->GroupInfo->GetTotalVDisksNum();
+ ui32 total = Conf->GroupInfo->GetTotalVDisksNum();
for (ui32 i = 0; i < total; i++) {
TAllVDisks::TVDiskInstance &instance = Conf->VDisks->Get(i);
if (instance.Initialized) {
@@ -1401,9 +1401,9 @@ ui32 PutLogoBlobToCorrespondingVDisks(const TActorContext &ctx, NKikimr::TBlobSt
const TLogoBlobID &id, const TString &data, NKikimrBlobStorage::EPutHandleClass cls) {
Y_ASSERT(id.PartId() == 0);
ui32 msgsSent = 0;
- TBlobStorageGroupInfo::TVDiskIds outVDisks;
- TBlobStorageGroupInfo::TServiceIds outServIds;
- info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
+ TBlobStorageGroupInfo::TVDiskIds outVDisks;
+ TBlobStorageGroupInfo::TServiceIds outServIds;
+ info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
ui8 n = info->Type.TotalPartCount();
for (ui8 i = 0; i < n; i++) {
TLogoBlobID aid(id, i + 1);
@@ -1417,20 +1417,20 @@ ui32 GetLogoBlobFromCorrespondingVDisks(const NActors::TActorContext &ctx, NKiki
const NKikimr::TLogoBlobID &id) {
Y_ASSERT(id.PartId() == 0);
ui32 msgsSent = 0;
- TBlobStorageGroupInfo::TVDiskIds outVDisks;
- TBlobStorageGroupInfo::TServiceIds outServIds;
- info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
+ TBlobStorageGroupInfo::TVDiskIds outVDisks;
+ TBlobStorageGroupInfo::TServiceIds outServIds;
+ info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
ui8 n = info->Type.TotalPartCount();
for (ui8 i = 0; i < n; i++) {
TLogoBlobID aid(id, i + 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Sending TEvGet: id=%s", aid.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(outVDisks[i],
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {aid});
- ctx.Send(outServIds[i], req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(outVDisks[i],
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {aid});
+ ctx.Send(outServIds[i], req.release());
msgsSent++;
}
return msgsSent;
@@ -1468,9 +1468,9 @@ void TDataSnapshot::PutExact(const TVDiskID &vdisk, const TActorId &service, con
void TDataSnapshot::PutCorresponding(const NKikimr::TLogoBlobID &id, const TString &data) {
Y_ASSERT(id.PartId() == 0);
- TBlobStorageGroupInfo::TVDiskIds outVDisks;
- TBlobStorageGroupInfo::TServiceIds outServIds;
- Info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
+ TBlobStorageGroupInfo::TVDiskIds outVDisks;
+ TBlobStorageGroupInfo::TServiceIds outServIds;
+ Info->PickSubgroup(id.Hash(), &outVDisks, &outServIds);
ui8 n = Info->Type.TotalPartCount();
for (ui8 i = 0; i < n; i++) {
TLogoBlobID aid(id, i + 1);
@@ -1600,13 +1600,13 @@ class TCheckDataSnapshotActor : public TActorBootstrapped<TCheckDataSnapshotActo
TThis::Die(ctx);
} else {
// send read
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(Cur->VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
- {},
- {TLogoBlobID(Cur->Id, 0)});
- ctx.Send(Cur->ServiceID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(Cur->VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::ShowInternals,
+ {},
+ {TLogoBlobID(Cur->Id, 0)});
+ ctx.Send(Cur->ServiceID, req.release());
}
}
@@ -1807,15 +1807,15 @@ struct TEvRunActor : public TEventLocal<TEvRunActor, TEvBlobStorage::EvRunActor>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TSyncRunActor : public TActor<TSyncRunActor> {
- std::shared_ptr<TSystemEvent> _Event;
- std::shared_ptr<TSyncRunner::TReturnValue> ReturnValue;
+ std::shared_ptr<TSystemEvent> _Event;
+ std::shared_ptr<TSyncRunner::TReturnValue> ReturnValue;
void Handle(TEvRunActor::TPtr &ev, const TActorContext &ctx) {
ctx.ExecutorThread.RegisterActor(ev->Get()->Actor.Release());
}
void HandleDone(TEvents::TEvCompleted::TPtr &ev, const TActorContext &ctx) {
- Y_UNUSED(ctx);
+ Y_UNUSED(ctx);
ReturnValue->Id = ev->Get()->Id;
ReturnValue->Status = ev->Get()->Status;
_Event->Signal();
@@ -1827,7 +1827,7 @@ class TSyncRunActor : public TActor<TSyncRunActor> {
)
public:
- TSyncRunActor(std::shared_ptr<TSystemEvent> event, std::shared_ptr<TSyncRunner::TReturnValue> returnValue)
+ TSyncRunActor(std::shared_ptr<TSystemEvent> event, std::shared_ptr<TSyncRunner::TReturnValue> returnValue)
: TActor<TSyncRunActor>(&TThis::StateFunc)
, _Event(event)
, ReturnValue(returnValue)
@@ -1841,12 +1841,12 @@ TSyncRunner::TReturnValue::TReturnValue(ui32 id, ui32 status)
, Status(status)
{}
-TSyncRunner::TSyncRunner(TActorSystem *system, TConfiguration *conf)
+TSyncRunner::TSyncRunner(TActorSystem *system, TConfiguration *conf)
: ActorSystem(system)
, WorkerID()
, _Event(new TSystemEvent(TSystemEvent::rAuto))
, ReturnValue (new TReturnValue {0, 0})
- , Conf(conf)
+ , Conf(conf)
{
WorkerID = ActorSystem->Register(new TSyncRunActor(_Event, ReturnValue));
}
@@ -1856,14 +1856,14 @@ TActorId TSyncRunner::NotifyID() const {
}
TSyncRunner::TReturnValue TSyncRunner::Run(const TActorContext &ctx, TAutoPtr<IActor> actor) {
- TConfiguration::TTimeoutCallbackId handle = Conf->RegisterTimeoutCallback([&] {
- _Event->Signal();
- });
+ TConfiguration::TTimeoutCallbackId handle = Conf->RegisterTimeoutCallback([&] {
+ _Event->Signal();
+ });
_Event->Reset();
*ReturnValue = TReturnValue {0, 0};
ctx.Send(WorkerID, new TEvRunActor(actor));
_Event->Wait();
- Conf->UnregisterTimeoutCallback(handle);
+ Conf->UnregisterTimeoutCallback(handle);
return *ReturnValue;
}
@@ -1877,7 +1877,7 @@ TSyncTestBase::TSyncTestBase(TConfiguration *conf)
{}
void TSyncTestBase::Bootstrap(const TActorContext &ctx) {
- SyncRunner.Reset(new TSyncRunner(ctx.ExecutorThread.ActorSystem, Conf));
+ SyncRunner.Reset(new TSyncRunner(ctx.ExecutorThread.ActorSystem, Conf));
Scenario(ctx);
AtomicIncrement(Conf->SuccessCount);
Conf->SignalDoneEvent();
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/helpers.h b/ydb/core/blobstorage/ut_vdisk/lib/helpers.h
index ed8792b838d..603233fd0f9 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/helpers.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/helpers.h
@@ -77,7 +77,7 @@ NActors::IActor *CreateRangeGet(const NActors::TActorId &notifyID, const TAllVDi
NActors::IActor *CreateManyPuts(TConfiguration *conf, const NActors::TActorId &notifyID,
const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout);
struct TMsgPackInfo {
@@ -97,27 +97,27 @@ struct TMsgPackInfo {
NActors::IActor *CreateManyPuts(TConfiguration *conf, const NActors::TActorId &notifyID,
const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
+ std::shared_ptr<IPutHandleClassGenerator> cls, std::shared_ptr<TSet<ui32>> badSteps,
TDuration requestTimeout);
NActors::IActor *CreateManyMultiPuts(TConfiguration *conf, const NActors::TActorId &notifyID,
const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui32 batchSize,
ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<IPutHandleClassGenerator> cls,
- std::shared_ptr<TSet<ui32>> badSteps, TDuration requestTimeout);
+ std::shared_ptr<IPutHandleClassGenerator> cls,
+ std::shared_ptr<TSet<ui32>> badSteps, TDuration requestTimeout);
NActors::IActor *CreateManyGets(const NActors::TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen,
- std::shared_ptr<TSet<ui32>> badSteps);
+ std::shared_ptr<TSet<ui32>> badSteps);
NActors::IActor *CreateGet(const NActors::TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
ui32 msgDataSize, ui32 msgNum, ui64 tabletId, ui32 channel, ui32 gen, ui64 shift,
bool withErrorResponse);
NActors::IActor *CreateGet(const NActors::TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks, ui64 tabletId, ui32 channel, ui32 gen,
ui64 shift, bool withErrorResponse);
NActors::IActor *CreatePutGC(const NActors::TActorId &notifyID, const TAllVDisks::TVDiskInstance &vdiskInfo,
@@ -291,7 +291,7 @@ public:
TReturnValue(ui32 id, ui32 status);
};
- TSyncRunner(NActors::TActorSystem *system, TConfiguration *conf);
+ TSyncRunner(NActors::TActorSystem *system, TConfiguration *conf);
NActors::TActorId NotifyID() const;
// returns pair<Id, Status>
TReturnValue Run(const NActors::TActorContext &ctx, TAutoPtr<NActors::IActor> actor);
@@ -299,9 +299,9 @@ public:
private:
NActors::TActorSystem *ActorSystem;
NActors::TActorId WorkerID;
- std::shared_ptr<TSystemEvent> _Event;
- std::shared_ptr<TReturnValue> ReturnValue;
- TConfiguration *Conf;
+ std::shared_ptr<TSystemEvent> _Event;
+ std::shared_ptr<TReturnValue> ReturnValue;
+ TConfiguration *Conf;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/http_client.cpp b/ydb/core/blobstorage/ut_vdisk/lib/http_client.cpp
index abde48cedfa..cb65a075f1a 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/http_client.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/http_client.cpp
@@ -89,17 +89,17 @@ void THttpClient::SendHttpRequest(const TStringBuf relativeUrl,
}
}
-std::unique_ptr<TNetworkAddress> THttpClient::Resolve() const {
+std::unique_ptr<TNetworkAddress> THttpClient::Resolve() const {
try {
- return std::make_unique<TNetworkAddress>(Host, Port);
+ return std::make_unique<TNetworkAddress>(Host, Port);
} catch (const yexception& e) {
ythrow THttpRequestException() << "Resolve of " << Host << ": " << e.what();
}
}
-std::unique_ptr<TSocket> THttpClient::Connect(TNetworkAddress& addr) const {
+std::unique_ptr<TSocket> THttpClient::Connect(TNetworkAddress& addr) const {
try {
- std::unique_ptr<TSocket> socket = std::make_unique<TSocket>(addr, ConnectTimeout);
+ std::unique_ptr<TSocket> socket = std::make_unique<TSocket>(addr, ConnectTimeout);
socket->SetSocketTimeout(SocketTimeout.Seconds());
return socket;
} catch (const yexception& e) {
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/http_client.h b/ydb/core/blobstorage/ut_vdisk/lib/http_client.h
index 3370f0eb00b..ebb43b4db60 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/http_client.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/http_client.h
@@ -44,8 +44,8 @@ public:
private:
void ReadAndTransferHttp(const TStringBuf relativeUrl, THttpInput& inp, IOutputStream* output) const;
- std::unique_ptr<TNetworkAddress> Resolve() const;
- std::unique_ptr<TSocket> Connect(TNetworkAddress& addr) const;
+ std::unique_ptr<TNetworkAddress> Resolve() const;
+ std::unique_ptr<TSocket> Connect(TNetworkAddress& addr) const;
void ProcessResponse(const TStringBuf relativeUrl, THttpInput& input, IOutputStream* output,
const unsigned statusCode) const;
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
index b2c020c3d21..3801387e882 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/prepare.cpp
@@ -14,7 +14,7 @@
#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/testing/unittest/tests_data.h>
-
+
#include <util/folder/dirut.h>
using namespace NKikimr;
@@ -105,7 +105,7 @@ TAllPDisks::TAllPDisks(const TAllPDisksConfiguration &cfg)
// using filesystem
TString entryDir;
if (cfg.Dir.empty()) {
- TempDir = std::make_shared<TTempDir>();
+ TempDir = std::make_shared<TTempDir>();
entryDir = (*TempDir)();
} else {
entryDir = cfg.Dir;
@@ -169,7 +169,7 @@ TOnePDisk &TAllPDisks::Get(ui32 pDiskID) {
void TAllPDisks::EraseDisk(ui32 diskNum, ui64 newGuid) {
TOnePDisk &inst = PDisks.at(diskNum);
- inst.PDiskGuid = newGuid;
+ inst.PDiskGuid = newGuid;
inst.FormatDisk(true);
}
@@ -238,8 +238,8 @@ TDefaultVDiskSetup::TDefaultVDiskSetup() {
bool TDefaultVDiskSetup::SetUp(TAllVDisks::TVDiskInstance &vdisk, TAllPDisks *pdisks, ui32 id, ui32 d, ui32 j,
ui32 pDiskID, ui32 slotId, bool runRepl, ui64 initOwnerRound) {
TOnePDisk &pdisk = pdisks->Get(pDiskID);
- vdisk.ActorID = MakeBlobStorageVDiskID(1, id + 1, 0);
- vdisk.VDiskID = TVDiskID(0, 1, 0, d, j);
+ vdisk.ActorID = MakeBlobStorageVDiskID(1, id + 1, 0);
+ vdisk.VDiskID = TVDiskID(0, 1, 0, d, j);
NKikimr::TVDiskConfig::TBaseInfo baseInfo(vdisk.VDiskID, pdisk.PDiskActorID, pdisk.PDiskGuid,
pdisk.PDiskID, NKikimr::TPDiskCategory::DEVICE_TYPE_ROT, slotId,
@@ -269,18 +269,18 @@ TConfiguration::TConfiguration(const TAllPDisksConfiguration &pcfg,
{}
TConfiguration::~TConfiguration() {
- if (ActorSystem1) {
- Shutdown();
- }
+ if (ActorSystem1) {
+ Shutdown();
+ }
}
static TProgramShouldContinue KikimrShouldContinue;
-void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRepl) { // FIXME: put newPDisks into configuration (see up)
+void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRepl) { // FIXME: put newPDisks into configuration (see up)
Counters = TIntrusivePtr<NMonitoring::TDynamicCounters>(new NMonitoring::TDynamicCounters());
TIntrusivePtr<TTableNameserverSetup> nameserverTable(new TTableNameserverSetup());
- TPortManager pm;
+ TPortManager pm;
nameserverTable->StaticNodeTable[1] = std::pair<TString, ui32>("127.0.0.1", pm.GetPort(12001));
nameserverTable->StaticNodeTable[2] = std::pair<TString, ui32>("127.0.0.1", pm.GetPort(12002));
@@ -301,16 +301,16 @@ void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRe
ui64 initOwnerRound = 1;
// setup pdisks
if (newPDisks) {
- PDisks.reset(new TAllPDisks(PCfg));
+ PDisks.reset(new TAllPDisks(PCfg));
}
PDisks->ActorSetupCmd(setup1.Get(), setup1->NodeId, Counters);
// setup GroupInfo
- GroupInfo = new TBlobStorageGroupInfo(Erasure, DisksInDomain, DomainsNum);
+ GroupInfo = new TBlobStorageGroupInfo(Erasure, DisksInDomain, DomainsNum);
// create vdisks
initOwnerRound += 100;
- VDisks.reset(new TAllVDisks(PDisks.get(), DomainsNum, DisksInDomain, vdiskSetup,
+ VDisks.reset(new TAllVDisks(PDisks.get(), DomainsNum, DisksInDomain, vdiskSetup,
(PCfg.PDisksNum == 1), runRepl, &initOwnerRound));
VDisks->ActorSetupCmd(setup1.Get(), GroupInfo.Get(), Counters);
@@ -330,10 +330,10 @@ void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRe
NKikimrServices::EServiceKikimr_Name
);
TString explanation;
- //logSettings->SetLevel(NLog::PRI_INFO, NKikimrServices::BS_SKELETON, explanation);
- //logSettings->SetLevel(NLog::PRI_INFO, NKikimrServices::BS_HULLCOMP, explanation);
+ //logSettings->SetLevel(NLog::PRI_INFO, NKikimrServices::BS_SKELETON, explanation);
+ //logSettings->SetLevel(NLog::PRI_INFO, NKikimrServices::BS_HULLCOMP, explanation);
//logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_HULLQUERY, explanation);
- //logSettings->SetLevel(NLog::PRI_ERROR, NKikimrServices::BS_SYNCLOG, explanation);
+ //logSettings->SetLevel(NLog::PRI_ERROR, NKikimrServices::BS_SYNCLOG, explanation);
//logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_SYNCJOB, explanation);
//logSettings->SetLevel(NLog::PRI_NOTICE, NKikimrServices::BS_SYNCER, explanation);
//logSettings->SetLevel(NLog::PRI_DEBUG, NKikimrServices::BS_REPL, explanation);
@@ -370,15 +370,15 @@ void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRe
//////////////////////////////////////////////////////////////////////////////
TIntrusivePtr<NScheme::TTypeRegistry> typeRegistry(new NScheme::TKikimrTypeRegistry());
- AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(),
+ AppData.reset(new NKikimr::TAppData(0, 1, 2, 3, TMap<TString, ui32>(), typeRegistry.Get(),
nullptr, nullptr, &KikimrShouldContinue));
- AppData->Counters = Counters;
- AppData->Mon = Monitoring.get();
+ AppData->Counters = Counters;
+ AppData->Mon = Monitoring.get();
IoContext = std::make_shared<NKikimr::NPDisk::TIoContextFactoryOSS>();
AppData->IoContextFactory = IoContext.get();
- ActorSystem1.reset(new TActorSystem(setup1, AppData.get(), logSettings));
- Monitoring->RegisterActorPage(actorsMonPage, "logger", "Logger", false, ActorSystem1.get(), loggerActorId);
+ ActorSystem1.reset(new TActorSystem(setup1, AppData.get(), logSettings));
+ Monitoring->RegisterActorPage(actorsMonPage, "logger", "Logger", false, ActorSystem1.get(), loggerActorId);
loggerActor->Log(Now(), NKikimr::NLog::PRI_NOTICE, NActorsServices::TEST, "Actor system created");
ActorSystem1->Start();
@@ -388,7 +388,7 @@ void TConfiguration::Prepare(IVDiskSetup *vdiskSetup, bool newPDisks, bool runRe
void TConfiguration::Shutdown() {
ActorSystem1->Stop();
- ActorSystem1.reset();
+ ActorSystem1.reset();
}
@@ -406,9 +406,9 @@ class TDbInitWaitActor : public TActorBootstrapped<TDbInitWaitActor> {
for (ui32 i = 0; i < Conf->VDisks->GetSize(); ++i) {
TAllVDisks::TVDiskInstance &vdisk = Conf->VDisks->Get(i);
if (vdisk.Initialized) {
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdisk.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::NotifyIfNotReady, {}, {id});
- ctx.Send(vdisk.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdisk.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::NotifyIfNotReady, {}, {id});
+ ctx.Send(vdisk.ActorID, req.release());
++Count;
}
}
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/prepare.h b/ydb/core/blobstorage/ut_vdisk/lib/prepare.h
index fc5da8d3421..2b623932ef9 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/prepare.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/prepare.h
@@ -5,7 +5,7 @@
#include <library/cpp/testing/unittest/registar.h>
#include <util/system/event.h>
-#include <util/system/condvar.h>
+#include <util/system/condvar.h>
#include <util/folder/tempdir.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_config.h>
#include <ydb/core/erasure/erasure.h>
@@ -76,7 +76,7 @@ public:
private:
TAllPDisksConfiguration Cfg;
TVector<TOnePDisk> PDisks;
- std::shared_ptr<TTempDir> TempDir;
+ std::shared_ptr<TTempDir> TempDir;
};
//////////////////////////////////////////////////////////////////////////////////////
@@ -154,12 +154,12 @@ struct TConfiguration {
TAllPDisksConfiguration PCfg;
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
- std::unique_ptr<NActors::TMon> Monitoring;
- std::unique_ptr<NKikimr::TAppData> AppData;
+ std::unique_ptr<NActors::TMon> Monitoring;
+ std::unique_ptr<NKikimr::TAppData> AppData;
std::shared_ptr<NKikimr::NPDisk::IIoContextFactory> IoContext;
- std::unique_ptr<NActors::TActorSystem> ActorSystem1;
- std::unique_ptr<TAllPDisks> PDisks;
- std::unique_ptr<TAllVDisks> VDisks;
+ std::unique_ptr<NActors::TActorSystem> ActorSystem1;
+ std::unique_ptr<TAllPDisks> PDisks;
+ std::unique_ptr<TAllVDisks> VDisks;
TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> GroupInfo;
TAtomic DoneCounter = 0;
@@ -167,11 +167,11 @@ struct TConfiguration {
TSystemEvent DbInitEvent { TSystemEvent::rAuto };
using TTimeoutCallbackList = TList<std::function<void ()>>;
- using TTimeoutCallbackId = TTimeoutCallbackList::iterator;
- TTimeoutCallbackList TimeoutCallbacks;
- TMutex TimeoutCallbacksLock;
- TCondVar TimeoutCallbacksCV;
-
+ using TTimeoutCallbackId = TTimeoutCallbackList::iterator;
+ TTimeoutCallbackList TimeoutCallbacks;
+ TMutex TimeoutCallbacksLock;
+ TCondVar TimeoutCallbacksCV;
+
TConfiguration(const TAllPDisksConfiguration &pcfg =
TAllPDisksConfiguration::MkOneTmp(512u << 10u, 16ull << 30ull, "ROT"),
ui32 domainsNum = 4u,
@@ -206,40 +206,40 @@ struct TConfiguration {
doneCount = AtomicGet(DoneCounter);
}
- for (;;) {
- TGuard<TMutex> lock(TimeoutCallbacksLock);
- if (TimeoutCallbacks.empty()) {
- break;
- }
- for (std::function<void ()>& callback : TimeoutCallbacks) {
- if (callback) {
- callback();
- callback = {};
- }
- }
- TimeoutCallbacksCV.WaitI(TimeoutCallbacksLock);
- }
-
+ for (;;) {
+ TGuard<TMutex> lock(TimeoutCallbacksLock);
+ if (TimeoutCallbacks.empty()) {
+ break;
+ }
+ for (std::function<void ()>& callback : TimeoutCallbacks) {
+ if (callback) {
+ callback();
+ callback = {};
+ }
+ }
+ TimeoutCallbacksCV.WaitI(TimeoutCallbacksLock);
+ }
+
UNIT_ASSERT_VALUES_EQUAL(doneCount, instances);
UNIT_ASSERT_VALUES_EQUAL(SuccessCount, instances);
return doneCount == instances && SuccessCount == instances;
}
- TTimeoutCallbackId RegisterTimeoutCallback(std::function<void ()> callback) {
- TGuard<TMutex> lock(TimeoutCallbacksLock);
- auto res = TimeoutCallbacks.insert(TimeoutCallbacks.end(), std::move(callback));
- TimeoutCallbacksCV.Signal();
- return res;
- }
-
- void UnregisterTimeoutCallback(TTimeoutCallbackId handle) {
- TGuard<TMutex> lock(TimeoutCallbacksLock);
- TimeoutCallbacks.erase(handle);
- TimeoutCallbacksCV.Signal();
- }
-
- void Prepare(IVDiskSetup *vdiskSetup, bool newPDisks = true, bool runRepl = true);
+ TTimeoutCallbackId RegisterTimeoutCallback(std::function<void ()> callback) {
+ TGuard<TMutex> lock(TimeoutCallbacksLock);
+ auto res = TimeoutCallbacks.insert(TimeoutCallbacks.end(), std::move(callback));
+ TimeoutCallbacksCV.Signal();
+ return res;
+ }
+
+ void UnregisterTimeoutCallback(TTimeoutCallbackId handle) {
+ TGuard<TMutex> lock(TimeoutCallbacksLock);
+ TimeoutCallbacks.erase(handle);
+ TimeoutCallbacksCV.Signal();
+ }
+
+ void Prepare(IVDiskSetup *vdiskSetup, bool newPDisks = true, bool runRepl = true);
void Shutdown();
void DbInitWait();
void PoisonVDisks();
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/setup.h b/ydb/core/blobstorage/ut_vdisk/lib/setup.h
index ae5a07e27c5..de34ee8ae99 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/setup.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/setup.h
@@ -48,7 +48,7 @@ struct TFastVDiskSetupSmallVDiskQueues : public TFastVDiskSetup {
}
};
-struct TFastVDiskSetupRepl : public TFastVDiskSetup {
+struct TFastVDiskSetupRepl : public TFastVDiskSetup {
TFastVDiskSetupRepl() {
auto modifier = [] (NKikimr::TVDiskConfig *cfg) {
cfg->HullCompSchedulingInterval = TDuration::Seconds(1);
@@ -59,9 +59,9 @@ struct TFastVDiskSetupRepl : public TFastVDiskSetup {
cfg->MilestoneHugeBlobInBytes = 512u << 10u;
};
AddConfigModifier(modifier);
- }
-};
-
+ }
+};
+
struct TFastVDiskSetupHndOff : public TFastVDiskSetup {
TFastVDiskSetupHndOff() {
auto modifier = [] (NKikimr::TVDiskConfig *cfg) {
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_brokendevice.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_brokendevice.cpp
index 74bfddbcab8..382b166947c 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_brokendevice.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_brokendevice.cpp
@@ -108,7 +108,7 @@ private:
CFunc(TEvents::TSystem::Wakeup, BrokenState_Timeout);
IgnoreFunc(TEvBlobStorage::TEvVWindowChange);
IgnoreFunc(NPDisk::TEvYardControlResult);
- IgnoreFunc(TEvents::TEvUndelivered);
+ IgnoreFunc(TEvents::TEvUndelivered);
)
public:
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_defrag.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_defrag.cpp
index e009de1c467..0d4059e1d2f 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_defrag.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_defrag.cpp
@@ -35,7 +35,7 @@ virtual void Scenario(const TActorContext &ctx) {
TPDiskPutStatusHandler hndl = PDiskPutStatusHandlerDefault;
// load huge and small blobs
- const ui32 maxBlobs = Max<ui32>();
+ const ui32 maxBlobs = Max<ui32>();
const ui64 hugeMaxDataSize = 20 << 20;
const ui32 hugeMinBlobSize = 64 << 10;
const ui32 hugeMaxBlobSize = 64 << 10;
@@ -92,13 +92,13 @@ virtual void Scenario(const TActorContext &ctx) {
SyncRunner->Run(ctx, defragCmd);
LOG_NOTICE(ctx, NActorsServices::TEST, " Defrag completed");
- // repeat
- defragCmd.Reset(CreateDefrag(SyncRunner->NotifyID(), instance, true, check));
- SyncRunner->Run(ctx, defragCmd);
- LOG_NOTICE(ctx, NActorsServices::TEST, " Defrag completed");
-
+ // repeat
+ defragCmd.Reset(CreateDefrag(SyncRunner->NotifyID(), instance, true, check));
+ SyncRunner->Run(ctx, defragCmd);
+ LOG_NOTICE(ctx, NActorsServices::TEST, " Defrag completed");
+
// check actually freed chunks
- UNIT_ASSERT_VALUES_EQUAL(freedChunks, 3);
+ UNIT_ASSERT_VALUES_EQUAL(freedChunks, 3);
}
SYNC_TEST_END(TDefrag50PercentGarbage, TSyncTestBase)
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_faketablet.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_faketablet.cpp
index b4d5cf9de33..73e132dfc5d 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_faketablet.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_faketablet.cpp
@@ -155,7 +155,7 @@ public:
, LogActor(new TFakeTabletLogChannelActor(conf, tabletId, minHugeBlobSize))
, HugeBlobActor(new TFakeTabletHugeBlobChannelActor(conf, tabletId, 1 /*channel*/, hugeBlobSize,
minHugeBlobSize, waitTime))
- {}
+ {}
};
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_gc.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_gc.cpp
index eb602a0b46f..513e3910978 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_gc.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_gc.cpp
@@ -30,13 +30,13 @@ virtual void Scenario(const TActorContext &ctx) {
// read command
TAutoPtr<IActor> readCmd;
auto sendFunc = [part0, &instance](const TActorContext &ctx) {
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- {part0});
- ctx.Send(instance.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ {part0});
+ ctx.Send(instance.ActorID, req.release());
};
auto checkFunc = [](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
CheckQueryResult(ev, ctx, EQR_OK_NODATA, nullptr);
@@ -84,20 +84,20 @@ virtual void Scenario(const TActorContext &ctx) {
TLogoBlobID from(0, 4294967295, 4294967295, 0, TLogoBlobID::MaxBlobSize, 0, TLogoBlobID::MaxPartId);
TLogoBlobID to (0, 0, 0, 0, 0, 0, 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to,
- 10);
- ctx.Send(instance.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to,
+ 10);
+ ctx.Send(instance.ActorID, req.release());
TString pppp("pppp");
TString qqqqq("qqqqq");
- ExpectedSet.Put(TLogoBlobID(0, 1, 471, 0, pppp.size(), 0), NKikimrProto::OK, {});
- ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
+ ExpectedSet.Put(TLogoBlobID(0, 1, 471, 0, pppp.size(), 0), NKikimrProto::OK, {});
+ ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
};
auto checkFunc = [this](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
CheckQueryResult(ev, ctx, EQR_OK_EXPECTED_SET, &ExpectedSet);
@@ -152,20 +152,20 @@ SYNC_TEST_BEGIN(TGCPutBarrier, TSyncTestWithSmallCommonDataset)
TLogoBlobID from(0, 4294967295, 4294967295, 0, TLogoBlobID::MaxBlobSize, 0, TLogoBlobID::MaxPartId);
TLogoBlobID to (0, 0, 0, 0, 0, 0, 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to,
- 10);
- ctx.Send(instance.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to,
+ 10);
+ ctx.Send(instance.ActorID, req.release());
TString pppp("pppp");
TString qqqqq("qqqqq");
- ExpectedSet.Put(TLogoBlobID(0, 1, 471, 0, pppp.size(), 0), NKikimrProto::OK, {});
- ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
+ ExpectedSet.Put(TLogoBlobID(0, 1, 471, 0, pppp.size(), 0), NKikimrProto::OK, {});
+ ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
};
auto checkFunc = [this](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
CheckQueryResult(ev, ctx, EQR_OK_EXPECTED_SET, &ExpectedSet);
@@ -222,17 +222,17 @@ virtual void Scenario(const TActorContext &ctx) {
TLogoBlobID from(0, 4294967295, 4294967295, 0, TLogoBlobID::MaxBlobSize, 0, TLogoBlobID::MaxPartId);
TLogoBlobID to (0, 0, 0, 0, 0, 0, 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to,
- 10);
- ctx.Send(instance.ActorID, req.release());
-
- ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to,
+ 10);
+ ctx.Send(instance.ActorID, req.release());
+
+ ExpectedSet.Put(TLogoBlobID(0, 1, 909, 0, qqqqq.size(), 0), NKikimrProto::OK, {});
};
auto checkFunc = [this](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
CheckQueryResult(ev, ctx, EQR_OK_EXPECTED_SET, &ExpectedSet);
@@ -283,15 +283,15 @@ virtual void Scenario(const TActorContext &ctx) {
TLogoBlobID from(0, 0, 0, 0, 0, 0, 1);
TLogoBlobID to (0, 4294967295, 4294967295, 0, TLogoBlobID::MaxBlobSize, 0, TLogoBlobID::MaxPartId);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to,
- 10);
- ctx.Send(instance.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to,
+ 10);
+ ctx.Send(instance.ActorID, req.release());
};
auto checkFunc = [&done](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
TEvBlobStorage::TEvVGetResult *msg = ev->Get();
@@ -349,15 +349,15 @@ virtual void Scenario(const TActorContext &ctx) {
TLogoBlobID from(0, 0, 0, 0, 0, 0, 1);
TLogoBlobID to (0, 4294967295, 4294967295, 0, TLogoBlobID::MaxBlobSize, 0, TLogoBlobID::MaxPartId);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::FastRead,
- TEvBlobStorage::TEvVGet::EFlags::None,
- {},
- from,
- to,
- 10);
- ctx.Send(instance.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(instance.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::FastRead,
+ TEvBlobStorage::TEvVGet::EFlags::None,
+ {},
+ from,
+ to,
+ 10);
+ ctx.Send(instance.ActorID, req.release());
};
auto checkFunc = [&done](TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
TEvBlobStorage::TEvVGetResult *msg = ev->Get();
@@ -431,7 +431,7 @@ virtual void Scenario(const TActorContext &ctx) {
TLogoBlobID to (0, 0, 0, 0, 0, TLogoBlobID::HashGeneric, 0, 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", ~from.ToString(), ~to.ToString());
req->AddRangeQuery(from, to, 10, nullptr);
- ctx.Send(instance.ActorID, req.release());
+ ctx.Send(instance.ActorID, req.release());
ExpectedSet.Put(TLogoBlobID(0, 1, 37, 0, 0, TLogoBlobID::HashGeneric, 0, 1), NKikimrProto::OK, "pppp");
ExpectedSet.Put(TLogoBlobID(0, 1, 40, 0, 0, TLogoBlobID::HashGeneric, 0, 1), NKikimrProto::OK, "qqqqq");
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_huge.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_huge.cpp
index 7364483b0c5..2c320104cb6 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_huge.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_huge.cpp
@@ -42,7 +42,7 @@ protected:
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class TSimpleScenary : public IScenary {
int State;
-
+
public:
TSimpleScenary(const TAllVDisks::TVDiskInstance &vDiskInstance)
: IScenary(vDiskInstance)
@@ -58,9 +58,9 @@ public:
const TLogoBlobID logoBlobId(0, 1, 10, 0, abcdefghkj.size(), 0, 1);
ctx.Send(HugeKeeperId,
new TEvHullWriteHugeBlob(TActorId(), 0, logoBlobId, TIngress(),
- TRope(abcdefghkj),
- false, NKikimrBlobStorage::EPutHandleClass::AsyncBlob,
- std::make_unique<TEvBlobStorage::TEvVPutResult>()));
+ TRope(abcdefghkj),
+ false, NKikimrBlobStorage::EPutHandleClass::AsyncBlob,
+ std::make_unique<TEvBlobStorage::TEvVPutResult>()));
State = 1;
return false;
}
@@ -80,7 +80,7 @@ public:
const auto *msg = ev->Get();
const bool slotIsUsed = true;
- const ui64 recLsn = 100500; // FIXME: write to log actually
+ const ui64 recLsn = 100500; // FIXME: write to log actually
ctx.Send(HugeKeeperId, new TEvHullHugeBlobLogged(msg->WriteId, msg->HugeBlob, recLsn, slotIsUsed));
State = 2;
}
@@ -115,16 +115,16 @@ struct THugeModuleContext {
class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryActor> {
using TStartingPoints = TMap<TLogSignature, NPDisk::TLogRecord>;
- std::shared_ptr<THugeModuleContext> HmCtx;
- ui64 Lsn = 0;
- std::shared_ptr<THullHugeKeeperPersState> RepairedHuge;
+ std::shared_ptr<THugeModuleContext> HmCtx;
+ ui64 Lsn = 0;
+ std::shared_ptr<THullHugeKeeperPersState> RepairedHuge;
friend class TActorBootstrapped<THugeModuleRecoveryActor>;
void Bootstrap(const TActorContext &ctx) {
auto &vDiskInstance = HmCtx->Conf->VDisks->Get(0);
HmCtx->Config = vDiskInstance.Cfg;
- HmCtx->VCtx.Reset(new TVDiskContext(ctx.SelfID, HmCtx->Conf->GroupInfo->PickTopology(), HmCtx->Counters,
+ HmCtx->VCtx.Reset(new TVDiskContext(ctx.SelfID, HmCtx->Conf->GroupInfo->PickTopology(), HmCtx->Counters,
vDiskInstance.VDiskID, ctx.ExecutorThread.ActorSystem, TPDiskCategory::DEVICE_TYPE_UNKNOWN));
TVDiskID selfVDiskID = HmCtx->Conf->GroupInfo->GetVDiskId(HmCtx->VCtx->ShortSelfVDisk);
@@ -144,7 +144,7 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
TStartingPoints::const_iterator it;
it = startingPoints.find(TLogSignature::SignatureHugeBlobEntryPoint);
if (it == startingPoints.end()) {
- RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
+ RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
HmCtx->VCtx,
HmCtx->PDiskCtx->Dsk->ChunkSize,
HmCtx->PDiskCtx->Dsk->AppendBlockSize,
@@ -154,7 +154,7 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
HmCtx->Config->HugeBlobOverhead,
HmCtx->Config->HugeBlobsFreeChunkReservation,
HmCtx->Config->HugeBlobOldMapCompatible,
- logFunc);
+ logFunc);
} else {
// read existing one
const ui64 lsn = it->second.Lsn;
@@ -163,7 +163,7 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
return false;
}
- RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
+ RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
HmCtx->VCtx,
HmCtx->PDiskCtx->Dsk->ChunkSize,
HmCtx->PDiskCtx->Dsk->AppendBlockSize,
@@ -173,14 +173,14 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
HmCtx->Config->HugeBlobOverhead,
HmCtx->Config->HugeBlobsFreeChunkReservation,
HmCtx->Config->HugeBlobOldMapCompatible,
- lsn, entryPoint, logFunc);
+ lsn, entryPoint, logFunc);
}
return true;
}
void Handle(NPDisk::TEvYardInitResult::TPtr &ev, const TActorContext &ctx) {
- const auto &m = ev->Get();
+ const auto &m = ev->Get();
NKikimrProto::EReplyStatus status = m->Status;
Y_VERIFY(status == NKikimrProto::OK, "Status# %s ErrorReason# %s",
NKikimrProto::EReplyStatus_Name(status).c_str(), m->ErrorReason.c_str());
@@ -194,24 +194,24 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
// start reading log
ctx.Send(HmCtx->PDiskCtx->PDiskId,
new NPDisk::TEvReadLog(HmCtx->PDiskCtx->Dsk->Owner, HmCtx->PDiskCtx->Dsk->OwnerRound));
- }
+ }
- void Handle(NPDisk::TEvReadLogResult::TPtr &ev, const TActorContext &ctx) {
+ void Handle(NPDisk::TEvReadLogResult::TPtr &ev, const TActorContext &ctx) {
const auto &m = ev->Get();
NKikimrProto::EReplyStatus status = m->Status;
Y_VERIFY(status == NKikimrProto::OK, "Status# %s ErrorReason# %s",
NKikimrProto::EReplyStatus_Name(status).c_str(), m->ErrorReason.c_str());
- if (m->Results) {
- const ui64 lsn = m->Results.back().Lsn;
- Y_VERIFY(lsn > Lsn);
- Lsn = lsn;
- }
+ if (m->Results) {
+ const ui64 lsn = m->Results.back().Lsn;
+ Y_VERIFY(lsn > Lsn);
+ Lsn = lsn;
+ }
- if (!m->IsEndOfLog) {
+ if (!m->IsEndOfLog) {
return (void)ctx.Send(HmCtx->PDiskCtx->PDiskId,
new NPDisk::TEvReadLog(HmCtx->PDiskCtx->Dsk->Owner, HmCtx->PDiskCtx->Dsk->OwnerRound,
m->NextPosition));
- }
+ }
Finish(ctx);
}
@@ -228,7 +228,7 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
TLogCutterCtx logCutterCtx = {HmCtx->VCtx, HmCtx->PDiskCtx, HmCtx->LsnMngr, HmCtx->Config, HmCtx->LoggerID};
HmCtx->LogCutterID = ctx.ExecutorThread.RegisterActor(CreateRecoveryLogCutter(std::move(logCutterCtx)));
RepairedHuge->FinishRecovery(ctx);
- auto hugeKeeperCtx = std::make_shared<THugeKeeperCtx>(HmCtx->VCtx, HmCtx->PDiskCtx, HmCtx->LsnMngr,
+ auto hugeKeeperCtx = std::make_shared<THugeKeeperCtx>(HmCtx->VCtx, HmCtx->PDiskCtx, HmCtx->LsnMngr,
HmCtx->MainID, HmCtx->LoggerID, HmCtx->LogCutterID, "{}");
TAutoPtr<IActor> hugeKeeperActor(CreateHullHugeBlobKeeper(hugeKeeperCtx, RepairedHuge));
HmCtx->HugeKeeperID = ctx.ExecutorThread.RegisterActor(hugeKeeperActor.Release());
@@ -244,7 +244,7 @@ class THugeModuleRecoveryActor : public TActorBootstrapped<THugeModuleRecoveryAc
)
public:
- THugeModuleRecoveryActor(std::shared_ptr<THugeModuleContext> hmCtx)
+ THugeModuleRecoveryActor(std::shared_ptr<THugeModuleContext> hmCtx)
: TActorBootstrapped<THugeModuleRecoveryActor>()
, HmCtx(hmCtx)
{}
@@ -254,7 +254,7 @@ public:
// THugeModuleTestActor
/////////////////////////////////////////////////////////////////////////////////////////////////////////
class THugeModuleTestActor : public TActorBootstrapped<THugeModuleTestActor> {
- std::shared_ptr<THugeModuleContext> HmCtx;
+ std::shared_ptr<THugeModuleContext> HmCtx;
TAutoPtr<IScenary> Scenary;
friend class TActorBootstrapped<THugeModuleTestActor>;
@@ -300,7 +300,7 @@ class THugeModuleTestActor : public TActorBootstrapped<THugeModuleTestActor> {
public:
THugeModuleTestActor(TConfiguration *conf, TAutoPtr<IScenary> scenary)
: TActorBootstrapped<THugeModuleTestActor>()
- , HmCtx(std::make_shared<THugeModuleContext>(conf))
+ , HmCtx(std::make_shared<THugeModuleContext>(conf))
, Scenary(scenary)
{}
};
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.cpp
index b65c601f86e..0600eef71a5 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.cpp
@@ -10,8 +10,8 @@ class TCheckDbIsEmptyManyPutGetActor : public TSyncTestBase {
const bool ExpectEmpty;
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
SyncRunner->Run(ctx, CreateCheckDbEmptyness(SyncRunner->NotifyID(), Conf->VDisks->Get(0), ExpectEmpty));
@@ -20,15 +20,15 @@ class TCheckDbIsEmptyManyPutGetActor : public TSyncTestBase {
}
public:
- TCheckDbIsEmptyManyPutGetActor(TConfiguration *conf, bool expectEmpty, bool /*waitForCompaction*/, ui32 msgNum,
+ TCheckDbIsEmptyManyPutGetActor(TConfiguration *conf, bool expectEmpty, bool /*waitForCompaction*/, ui32 msgNum,
ui32 msgSize, NKikimrBlobStorage::EPutHandleClass cls)
: TSyncTestBase(conf)
, ExpectEmpty(expectEmpty)
, MsgNum(msgNum)
, MsgSize(msgSize)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
- {}
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
+ {}
};
void TCheckDbIsEmptyManyPutGet::operator ()(TConfiguration *conf) {
@@ -42,8 +42,8 @@ void TCheckDbIsEmptyManyPutGet::operator ()(TConfiguration *conf) {
class TManyPutsActor : public TSyncTestBase {
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
ui64 tabletId = 0;
@@ -55,14 +55,14 @@ class TManyPutsActor : public TSyncTestBase {
}
public:
- TManyPutsActor(TConfiguration *conf, bool /*waitForCompaction*/, ui32 msgNum, ui32 msgSize,
- NKikimrBlobStorage::EPutHandleClass cls, std::shared_ptr<TSet<ui32>> badSteps)
+ TManyPutsActor(TConfiguration *conf, bool /*waitForCompaction*/, ui32 msgNum, ui32 msgSize,
+ NKikimrBlobStorage::EPutHandleClass cls, std::shared_ptr<TSet<ui32>> badSteps)
: TSyncTestBase(conf)
, MsgNum(msgNum)
, MsgSize(msgSize)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
, BadSteps(badSteps)
- {}
+ {}
};
@@ -74,7 +74,7 @@ void TManyPutsTest::operator ()(TConfiguration *conf) {
class TManyGetsActor : public TSyncTestBase {
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
ui64 tabletId = 0;
@@ -85,13 +85,13 @@ class TManyGetsActor : public TSyncTestBase {
}
public:
- TManyGetsActor(TConfiguration *conf, bool /*waitForCompaction*/, ui32 msgNum, ui32 msgSize,
- NKikimrBlobStorage::EPutHandleClass /*cls*/, std::shared_ptr<TSet<ui32>> badSteps)
+ TManyGetsActor(TConfiguration *conf, bool /*waitForCompaction*/, ui32 msgNum, ui32 msgSize,
+ NKikimrBlobStorage::EPutHandleClass /*cls*/, std::shared_ptr<TSet<ui32>> badSteps)
: TSyncTestBase(conf)
, MsgNum(msgNum)
, MsgSize(msgSize)
, BadSteps(badSteps)
- {}
+ {}
};
@@ -105,8 +105,8 @@ class TManyMultiPutsActor : public TSyncTestBase {
const ui32 MsgNum;
const ui32 BatchSize;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
ui64 tabletId = 0;
@@ -119,12 +119,12 @@ class TManyMultiPutsActor : public TSyncTestBase {
public:
TManyMultiPutsActor(TConfiguration *conf, bool /*waitForCompaction*/, ui32 msgNum, ui32 msgSize, ui32 batchSize,
- NKikimrBlobStorage::EPutHandleClass cls, std::shared_ptr<TSet<ui32>> badSteps)
+ NKikimrBlobStorage::EPutHandleClass cls, std::shared_ptr<TSet<ui32>> badSteps)
: TSyncTestBase(conf)
, MsgNum(msgNum)
, BatchSize(batchSize)
, MsgSize(msgSize)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
, BadSteps(badSteps)
{}
};
@@ -141,11 +141,11 @@ class TChaoticManyPutsActor : public NActors::TActorBootstrapped<TChaoticManyPut
const ui32 Parallel;
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
const TDuration WorkingTime;
const TDuration RequestTimeout;
ui32 Counter;
- TVector<std::shared_ptr<TSet<ui32>>> BadSteps;
+ TVector<std::shared_ptr<TSet<ui32>>> BadSteps;
friend class NActors::TActorBootstrapped<TChaoticManyPutsActor>;
void Bootstrap(const NActors::TActorContext &ctx) {
@@ -154,7 +154,7 @@ class TChaoticManyPutsActor : public NActors::TActorBootstrapped<TChaoticManyPut
ui64 tabletId = i + 1;
ui32 channel = 0;
ui32 gen = 1;
- auto badSteps = std::make_shared<TSet<ui32>>();
+ auto badSteps = std::make_shared<TSet<ui32>>();
ctx.ExecutorThread.RegisterActor(CreateManyPuts(Conf, ctx.SelfID, Conf->VDisks->Get(0),
MsgSize, MsgNum, tabletId, channel, gen,
HandleClassGen, badSteps, RequestTimeout));
@@ -185,7 +185,7 @@ class TChaoticManyPutsActor : public NActors::TActorBootstrapped<TChaoticManyPut
public:
TChaoticManyPutsActor(TConfiguration *conf, ui32 parallel, ui32 msgNum, ui32 msgSize,
- std::shared_ptr<IPutHandleClassGenerator> cls, TDuration workingTime,
+ std::shared_ptr<IPutHandleClassGenerator> cls, TDuration workingTime,
TDuration requestTimeout)
: TActorBootstrapped<TChaoticManyPutsActor>()
, Conf(conf)
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.h b/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.h
index 0f4a478de1d..050eddf83a4 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_localrecovery.h
@@ -33,11 +33,11 @@ struct TManyPutsTest {
const ui32 MsgNum;
const ui32 MsgSize;
const NKikimrBlobStorage::EPutHandleClass HandleClass;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<TSet<ui32>> BadSteps;
TManyPutsTest(bool waitForCompaction, ui32 msgNum, ui32 msgSize,
NKikimrBlobStorage::EPutHandleClass cls,
- std::shared_ptr<TSet<ui32>> badSteps)
+ std::shared_ptr<TSet<ui32>> badSteps)
: WaitForCompaction(waitForCompaction)
, MsgNum(msgNum)
, MsgSize(msgSize)
@@ -56,11 +56,11 @@ struct TManyMultiPutsTest {
const ui32 BatchSize;
const ui32 MsgSize;
const NKikimrBlobStorage::EPutHandleClass HandleClass;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<TSet<ui32>> BadSteps;
TManyMultiPutsTest(bool waitForCompaction, ui32 msgNum, ui32 batchSize, ui32 msgSize,
NKikimrBlobStorage::EPutHandleClass cls,
- std::shared_ptr<TSet<ui32>> badSteps)
+ std::shared_ptr<TSet<ui32>> badSteps)
: WaitForCompaction(waitForCompaction)
, MsgNum(msgNum)
, BatchSize(batchSize)
@@ -79,11 +79,11 @@ struct TManyGetsTest {
const ui32 MsgNum;
const ui32 MsgSize;
const NKikimrBlobStorage::EPutHandleClass HandleClass;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<TSet<ui32>> BadSteps;
TManyGetsTest(bool waitForCompaction, ui32 msgNum, ui32 msgSize,
NKikimrBlobStorage::EPutHandleClass cls,
- std::shared_ptr<TSet<ui32>> badSteps)
+ std::shared_ptr<TSet<ui32>> badSteps)
: WaitForCompaction(waitForCompaction)
, MsgNum(msgNum)
, MsgSize(msgSize)
@@ -99,12 +99,12 @@ struct TChaoticManyPutsTest {
const ui32 Parallel;
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
const TDuration WorkingTime;
const TDuration RequestTimeout; // zero means infinity
TChaoticManyPutsTest(ui32 parallel, ui32 msgNum, ui32 msgSize,
- std::shared_ptr<IPutHandleClassGenerator> cls,
+ std::shared_ptr<IPutHandleClassGenerator> cls,
TDuration workingTime, TDuration requestTimeout)
: Parallel(parallel)
, MsgNum(msgNum)
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_many.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_many.cpp
index d542dfc32a9..1dad2c35b1a 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_many.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_many.cpp
@@ -10,11 +10,11 @@ using namespace NKikimr;
class TManyPutOneGetActor : public TSyncTestBase {
protected:
const bool WaitForCompaction;
- std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
+ std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
const ui64 TabletId;
const ui64 Shift;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
const bool WithErrorResponse;
virtual void Scenario(const TActorContext &ctx) {
@@ -45,12 +45,12 @@ public:
, MsgPacks(new TVector<TMsgPackInfo>{TMsgPackInfo(msgSize, msgNum)})
, TabletId(tabletId)
, Shift(shift)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
, WithErrorResponse(withErrorResponse)
{}
- TManyPutOneGetActor(TConfiguration *conf, bool waitForCompaction, std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
+ TManyPutOneGetActor(TConfiguration *conf, bool waitForCompaction, std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
ui64 tabletId, ui64 shift, NKikimrBlobStorage::EPutHandleClass cls,
bool withErrorResponse)
: TSyncTestBase(conf)
@@ -58,8 +58,8 @@ public:
, MsgPacks(msgPacks)
, TabletId(tabletId)
, Shift(shift)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
, WithErrorResponse(withErrorResponse)
{}
};
@@ -76,8 +76,8 @@ protected:
const ui32 MsgNum;
const ui32 MsgSize;
const ui64 TabletId;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
// load data
@@ -106,8 +106,8 @@ public:
, MsgNum(msgNum)
, MsgSize(msgSize)
, TabletId(tabletId)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
{}
};
@@ -123,8 +123,8 @@ protected:
const ui32 MsgSize;
const ui32 BatchSize;
const ui64 TabletId;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
// load data
@@ -155,8 +155,8 @@ public:
, MsgSize(msgSize)
, BatchSize(batchSize)
, TabletId(tabletId)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
{}
};
@@ -172,8 +172,8 @@ protected:
const bool IndexOnly;
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
// load data
@@ -203,11 +203,11 @@ public:
, IndexOnly(indexOnly)
, MsgNum(msgNum)
, MsgSize(msgSize)
- , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
- {
- Y_VERIFY(indexOnly);
- }
+ , HandleClassGen(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
+ {
+ Y_VERIFY(indexOnly);
+ }
};
void TManyPutRangeGet::operator ()(TConfiguration *conf) {
@@ -223,9 +223,9 @@ protected:
const bool IndexOnly;
const ui32 MsgNum;
const ui32 MsgSize;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen1;
- std::shared_ptr<IPutHandleClassGenerator> HandleClassGen2;
- std::shared_ptr<TSet<ui32>> BadSteps;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen1;
+ std::shared_ptr<IPutHandleClassGenerator> HandleClassGen2;
+ std::shared_ptr<TSet<ui32>> BadSteps;
virtual void Scenario(const TActorContext &ctx) {
// load data 1
@@ -259,12 +259,12 @@ public:
, IndexOnly(indexOnly)
, MsgNum(msgNum)
, MsgSize(msgSize)
- , HandleClassGen1(std::make_shared<TPutHandleClassGenerator>(cls))
- , HandleClassGen2(std::make_shared<TPutHandleClassGenerator>(cls))
- , BadSteps(std::make_shared<TSet<ui32>>())
- {
- Y_VERIFY(indexOnly);
- }
+ , HandleClassGen1(std::make_shared<TPutHandleClassGenerator>(cls))
+ , HandleClassGen2(std::make_shared<TPutHandleClassGenerator>(cls))
+ , BadSteps(std::make_shared<TSet<ui32>>())
+ {
+ Y_VERIFY(indexOnly);
+ }
};
void TManyPutRangeGet2Channels::operator ()(TConfiguration *conf) {
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_many.h b/ydb/core/blobstorage/ut_vdisk/lib/test_many.h
index acfe4549df2..6660502741b 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_many.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_many.h
@@ -7,7 +7,7 @@
///////////////////////////////////////////////////////////////////////////
struct TManyPutOneGet {
const bool WaitForCompaction;
- std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
+ std::shared_ptr<TVector<TMsgPackInfo>> MsgPacks;
const NKikimrBlobStorage::EPutHandleClass HandleClass;
const ui64 TabletId;
const ui64 Shift;
@@ -23,7 +23,7 @@ struct TManyPutOneGet {
, WithErrorResponse(withErrorResponse)
{}
- TManyPutOneGet(bool waitForCompaction, std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
+ TManyPutOneGet(bool waitForCompaction, std::shared_ptr<TVector<TMsgPackInfo>> msgPacks,
NKikimrBlobStorage::EPutHandleClass cls, ui64 tabletId = 0, ui64 shift = 0,
bool withErrorResponse = false)
: WaitForCompaction(waitForCompaction)
@@ -93,9 +93,9 @@ struct TManyPutRangeGet {
, MsgNum(msgNum)
, MsgSize(msgSize)
, HandleClass(cls)
- {
- Y_VERIFY(indexOnly);
- }
+ {
+ Y_VERIFY(indexOnly);
+ }
void operator ()(TConfiguration *conf);
};
@@ -115,9 +115,9 @@ struct TManyPutRangeGet2Channels {
, MsgNum(msgNum)
, MsgSize(msgSize)
, HandleClass(cls)
- {
- Y_VERIFY(indexOnly);
- }
+ {
+ Y_VERIFY(indexOnly);
+ }
void operator ()(TConfiguration *conf);
};
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_repl.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_repl.cpp
index ae4288ab25b..2c8732aea2e 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_repl.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_repl.cpp
@@ -11,138 +11,138 @@ class TReadUntilSuccessActor : public TActorBootstrapped<TReadUntilSuccessActor>
TConfiguration *Conf;
const IDataSet *DataSet;
TAllVDisks::TVDiskInstance &VDisk;
- ui32 Counter;
+ ui32 Counter;
TDuration RepeatTimeout;
- bool Multipart;
+ bool Multipart;
struct TVal {
TString Data;
- ui32 PartMask;
-
+ ui32 PartMask;
+
TVal(const TString &data)
: Data(data)
- , PartMask(0)
+ , PartMask(0)
{}
-
- bool AddReply(const TLogoBlobID& id) {
- const ui8 partId = id.PartId();
- Y_VERIFY(partId > 0);
- const ui32 mask = 1 << (partId - 1);
- Y_VERIFY(!(PartMask & mask));
- PartMask |= mask;
- return PartMask == 7;
- }
+
+ bool AddReply(const TLogoBlobID& id) {
+ const ui8 partId = id.PartId();
+ Y_VERIFY(partId > 0);
+ const ui32 mask = 1 << (partId - 1);
+ Y_VERIFY(!(PartMask & mask));
+ PartMask |= mask;
+ return PartMask == 7;
+ }
};
typedef TMap<TLogoBlobID, TVal> TReadSet;
TReadSet ReadSet;
typedef TSet<TLogoBlobID> TPendingReads;
- TPendingReads PendingReads;
- bool HaveNoData;
+ TPendingReads PendingReads;
+ bool HaveNoData;
friend class TActorBootstrapped<TReadUntilSuccessActor>;
void SendAllMessages(const TActorContext &ctx) {
- std::unique_ptr<TEvBlobStorage::TEvVGet> req;
- ui32 numBlobs = 0;
-
- // send at most 10 packets of 64 requests
- for (auto it = PendingReads.begin(), e = PendingReads.end(); Counter < 10; ++it) {
- if (!req)
- req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDisk.VDiskID,
- TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead);
- if (it != e)
- req->AddExtremeQuery(*it, 0, 0);
- if (++numBlobs == 64 || it == e) {
- if (numBlobs != 0) {
- ctx.Send(VDisk.ActorID, req.release());
- ++Counter;
- }
- numBlobs = 0;
- if (it == e)
- break;
- }
+ std::unique_ptr<TEvBlobStorage::TEvVGet> req;
+ ui32 numBlobs = 0;
+
+ // send at most 10 packets of 64 requests
+ for (auto it = PendingReads.begin(), e = PendingReads.end(); Counter < 10; ++it) {
+ if (!req)
+ req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDisk.VDiskID,
+ TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead);
+ if (it != e)
+ req->AddExtremeQuery(*it, 0, 0);
+ if (++numBlobs == 64 || it == e) {
+ if (numBlobs != 0) {
+ ctx.Send(VDisk.ActorID, req.release());
+ ++Counter;
+ }
+ numBlobs = 0;
+ if (it == e)
+ break;
+ }
}
-
- HaveNoData = false;
+
+ HaveNoData = false;
}
void Bootstrap(const TActorContext &ctx) {
- ui32 numBlobs = 0;
- ui64 blobsSize = 0;
-
+ ui32 numBlobs = 0;
+ ui64 blobsSize = 0;
+
TAutoPtr<IDataSet::TIterator> it = DataSet->First();
Y_VERIFY(it->IsValid());
while (it->IsValid()) {
ReadSet.insert(std::pair<TLogoBlobID, TVal>(it->Get()->Id, TVal(it->Get()->Data)));
- PendingReads.insert(it->Get()->Id);
- ++numBlobs;
+ PendingReads.insert(it->Get()->Id);
+ ++numBlobs;
blobsSize += it->Get()->Data.size();
it->Next();
}
- LOG_INFO_S(ctx, NActorsServices::TEST, "numBlobs# " << numBlobs << " blobsSize# " << blobsSize);
-
+ LOG_INFO_S(ctx, NActorsServices::TEST, "numBlobs# " << numBlobs << " blobsSize# " << blobsSize);
+
Become(&TThis::StateFunc);
ctx.Schedule(RepeatTimeout, new TEvents::TEvWakeup());
SendAllMessages(ctx);
}
void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
- --Counter;
-
- LOG_DEBUG_S(ctx, NActorsServices::TEST, "received reply " << ev->Get()->ToString());
-
- ui32 ok = 0, notOk = 0, dataCorrupt = 0, miss = 0, noData = 0;
-
+ --Counter;
+
+ LOG_DEBUG_S(ctx, NActorsServices::TEST, "received reply " << ev->Get()->ToString());
+
+ ui32 ok = 0, notOk = 0, dataCorrupt = 0, miss = 0, noData = 0;
+
if (ev->Get()->Record.GetStatus() == NKikimrProto::OK) {
const NKikimrBlobStorage::TEvVGetResult &rec = ev->Get()->Record;
- for (const auto& q : rec.GetResult()) {
- if (q.GetStatus() == NKikimrProto::OK) {
- const TLogoBlobID id = TLogoBlobID(LogoBlobIDFromLogoBlobID(q.GetBlobID()), 0);
- const TReadSet::iterator it = ReadSet.find(id);
- if (it != ReadSet.end()) {
- if (it->second.Data == q.GetBuffer()) {
- if (!Multipart || it->second.AddReply(LogoBlobIDFromLogoBlobID(q.GetBlobID()))) {
- ReadSet.erase(it);
- }
- PendingReads.erase(id);
- ++ok;
- } else {
- ++dataCorrupt;
- }
- } else {
- ++miss;
+ for (const auto& q : rec.GetResult()) {
+ if (q.GetStatus() == NKikimrProto::OK) {
+ const TLogoBlobID id = TLogoBlobID(LogoBlobIDFromLogoBlobID(q.GetBlobID()), 0);
+ const TReadSet::iterator it = ReadSet.find(id);
+ if (it != ReadSet.end()) {
+ if (it->second.Data == q.GetBuffer()) {
+ if (!Multipart || it->second.AddReply(LogoBlobIDFromLogoBlobID(q.GetBlobID()))) {
+ ReadSet.erase(it);
+ }
+ PendingReads.erase(id);
+ ++ok;
+ } else {
+ ++dataCorrupt;
+ }
+ } else {
+ ++miss;
}
- } else if (q.GetStatus() == NKikimrProto::NODATA) {
- HaveNoData = true;
- ++noData;
- } else {
- HaveNoData = true;
- ++notOk;
+ } else if (q.GetStatus() == NKikimrProto::NODATA) {
+ HaveNoData = true;
+ ++noData;
+ } else {
+ HaveNoData = true;
+ ++notOk;
}
}
+ }
+
+ LOG_INFO_S(ctx, NActorsServices::TEST, "ok# " << ok << " notOk# " << notOk <<
+ " noData# " << noData << " dataCorrupt# " << dataCorrupt <<
+ " miss# " << miss << " remain# " << PendingReads.size());
+
+ if (!Counter && PendingReads.empty()) {
+ if (ReadSet.empty()) {
+ AtomicIncrement(Conf->SuccessCount);
+ }
+ Conf->SignalDoneEvent();
+ Die(ctx);
+ } else if (!Counter && !HaveNoData) {
+ SendAllMessages(ctx);
}
-
- LOG_INFO_S(ctx, NActorsServices::TEST, "ok# " << ok << " notOk# " << notOk <<
- " noData# " << noData << " dataCorrupt# " << dataCorrupt <<
- " miss# " << miss << " remain# " << PendingReads.size());
-
- if (!Counter && PendingReads.empty()) {
- if (ReadSet.empty()) {
- AtomicIncrement(Conf->SuccessCount);
- }
- Conf->SignalDoneEvent();
- Die(ctx);
- } else if (!Counter && !HaveNoData) {
- SendAllMessages(ctx);
- }
- }
+ }
void HandleWakeup(const TActorContext &ctx) {
- if (!Counter)
- SendAllMessages(ctx);
- ctx.Schedule(RepeatTimeout, new TEvents::TEvWakeup());
+ if (!Counter)
+ SendAllMessages(ctx);
+ ctx.Schedule(RepeatTimeout, new TEvents::TEvWakeup());
}
@@ -154,37 +154,37 @@ class TReadUntilSuccessActor : public TActorBootstrapped<TReadUntilSuccessActor>
public:
TReadUntilSuccessActor(TConfiguration *conf, const IDataSet *dataSet, ui32 vdiskNumber, const TDuration &repeatTimeout,
- bool multipart)
+ bool multipart)
: TActorBootstrapped<TReadUntilSuccessActor>()
, Conf(conf)
, DataSet(dataSet)
, VDisk(Conf->VDisks->Get(vdiskNumber))
- , Counter(0)
+ , Counter(0)
, RepeatTimeout(repeatTimeout)
- , Multipart(multipart)
+ , Multipart(multipart)
{}
};
void TReadUntilSuccess::operator ()(TConfiguration *conf) {
- conf->ActorSystem1->Register(new TReadUntilSuccessActor(conf, DataSet, VDiskNumber, RepeatTimeout, Multipart));
+ conf->ActorSystem1->Register(new TReadUntilSuccessActor(conf, DataSet, VDiskNumber, RepeatTimeout, Multipart));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
class TVDiskReplProxyReaderActor : public TActorBootstrapped<TVDiskReplProxyReaderActor> {
private:
const TActorId NotifyID;
const TAllVDisks::TVDiskInstance VDiskInfo;
TConfiguration *Conf;
TVDiskContextPtr VCtx;
- std::shared_ptr<TReplCtx> ReplCtx;
+ std::shared_ptr<TReplCtx> ReplCtx;
TVDiskProxyPtr Proxy;
IDataSet *DataSet;
TAutoPtr<TExpectedSet> ExpectedSetPtr;
TActorId QueueId;
- bool Running = false;
+ bool Running = false;
/*
void Put(const NKikimr::TLogoBlobID &id, NKikimrProto::EReplyStatus status, const TString &data);
void Check(const NKikimr::TLogoBlobID &id, NKikimrProto::EReplyStatus status, const TString &data);
@@ -196,32 +196,32 @@ private:
friend class TActorBootstrapped<TVDiskReplProxyReaderActor>;
void Bootstrap(const TActorContext &ctx) {
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters = new NMonitoring::TDynamicCounters;
+ TIntrusivePtr<NMonitoring::TDynamicCounters> counters = new NMonitoring::TDynamicCounters;
auto groupInfo = TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- VCtx.Reset(new TVDiskContext(ctx.SelfID, groupInfo.PickTopology(), counters, VDiskInfo.VDiskID,
+ VCtx.Reset(new TVDiskContext(ctx.SelfID, groupInfo.PickTopology(), counters, VDiskInfo.VDiskID,
ctx.ExecutorThread.ActorSystem, TPDiskCategory::DEVICE_TYPE_UNKNOWN));
- ReplCtx = std::make_shared<TReplCtx>(
+ ReplCtx = std::make_shared<TReplCtx>(
VCtx,
nullptr, // PDiskCtx
nullptr, // HugeBlobCtx
- nullptr,
- MakeIntrusive<TBlobStorageGroupInfo>(groupInfo),
+ nullptr,
+ MakeIntrusive<TBlobStorageGroupInfo>(groupInfo),
ctx.SelfID,
- VDiskInfo.Cfg,
- std::make_shared<std::atomic_uint64_t>());
+ VDiskInfo.Cfg,
+ std::make_shared<std::atomic_uint64_t>());
- TBSProxyContextPtr bspctx = new TBSProxyContext(counters);
+ TBSProxyContextPtr bspctx = new TBSProxyContext(counters);
TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
- QueueId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
- NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, counters, bspctx, NBackpressure::TQueueClientId(),
- "PutTabletLog", 0, false, TDuration::Minutes(10), flowRecord,
- NMonitoring::TCountableBase::EVisibility::Public));
+ QueueId = ctx.Register(CreateVDiskBackpressureClient(Conf->GroupInfo, VDiskInfo.VDiskID,
+ NKikimrBlobStorage::EVDiskQueueId::PutTabletLog, counters, bspctx, NBackpressure::TQueueClientId(),
+ "PutTabletLog", 0, false, TDuration::Minutes(10), flowRecord,
+ NMonitoring::TCountableBase::EVisibility::Public));
Proxy.Reset(new TVDiskProxy(ReplCtx, VDiskInfo.VDiskID, QueueId));
-
+
TAutoPtr<IDataSet::TIterator> it = DataSet->First();
while (it->IsValid()) {
- Proxy->Put(it->Get()->Id, 0);
+ Proxy->Put(it->Get()->Id, 0);
it->Next();
}
@@ -232,39 +232,39 @@ private:
Proxy->HandleNext(ev);
while (Proxy->Valid()) {
- TLogoBlobID id;
- NKikimrProto::EReplyStatus status;
+ TLogoBlobID id;
+ NKikimrProto::EReplyStatus status;
TTrackableString data(TMemoryConsumer(VCtx->Replication));
- Proxy->GetData(&id, &status, &data);
- if (status == NKikimrProto::OK) {
- ExpectedSetPtr->Check(id, status, data.GetBaseConstRef());
- }
+ Proxy->GetData(&id, &status, &data);
+ if (status == NKikimrProto::OK) {
+ ExpectedSetPtr->Check(id, status, data.GetBaseConstRef());
+ }
Proxy->Next();
}
- if (Proxy->IsEof()) {
- ExpectedSetPtr->Finish();
- ctx.Send(NotifyID, new TEvents::TEvCompleted());
- ctx.Send(QueueId, new TEvents::TEvPoisonPill);
- Die(ctx);
- } else {
- Proxy->SendNextRequest();
- }
- }
-
- void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& /*ctx*/) {
- if (ev->Get()->IsConnected && !Running) {
- Proxy->Run(SelfId());
- Running = true;
- }
+ if (Proxy->IsEof()) {
+ ExpectedSetPtr->Finish();
+ ctx.Send(NotifyID, new TEvents::TEvCompleted());
+ ctx.Send(QueueId, new TEvents::TEvPoisonPill);
+ Die(ctx);
+ } else {
+ Proxy->SendNextRequest();
+ }
}
+ void Handle(TEvProxyQueueState::TPtr& ev, const TActorContext& /*ctx*/) {
+ if (ev->Get()->IsConnected && !Running) {
+ Proxy->Run(SelfId());
+ Running = true;
+ }
+ }
+
STRICT_STFUNC(StateRead,
HFunc(TEvReplProxyNextResult, Handle);
HFunc(TEvProxyQueueState, Handle);
IgnoreFunc(TEvBlobStorage::TEvVWindowChange);
)
-
+
public:
TVDiskReplProxyReaderActor(TConfiguration *conf, const TActorId &notifyID,
const TAllVDisks::TVDiskInstance &vdiskInfo, TAutoPtr<TExpectedSet> expSetPtr,
@@ -274,7 +274,7 @@ public:
, VDiskInfo(vdiskInfo)
, Conf(conf)
, VCtx()
- , Proxy()
+ , Proxy()
, DataSet(dataSet)
, ExpectedSetPtr(expSetPtr)
{}
@@ -299,29 +299,29 @@ virtual void Scenario(const TActorContext &ctx) {
}
SYNC_TEST_WITH_DATASET_END(TTestReplDataWriteAndSync)
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SYNC_TEST_WITH_DATASET_BEGIN(TTestReplDataWriteAndSyncMultipart)
-virtual void Scenario(const TActorContext &ctx) {
- // load data
- SyncRunner->Run(ctx, ManyPutsToCorrespondingVDisks(SyncRunner->NotifyID(), Conf, DataSet));
- LOG_NOTICE(ctx, NActorsServices::TEST, " Data is loaded");
-
- // duplicate data to handoff
- for (ui8 part = 1; part <= 3; ++part) {
- SyncRunner->Run(ctx, ManyPutsToOneVDisk(SyncRunner->NotifyID(), Conf->VDisks->Get(3), DataSet, part,
- NKikimrBlobStorage::EPutHandleClass::TabletLog));
- }
- LOG_NOTICE(ctx, NActorsServices::TEST, " Data is duplicated");
-
- // wait for sync
- SyncRunner->Run(ctx, CreateWaitForSync(SyncRunner->NotifyID(), Conf));
- LOG_NOTICE(ctx, NActorsServices::TEST, " SYNC done");
-}
-SYNC_TEST_WITH_DATASET_END(TTestReplDataWriteAndSyncMultipart)
-
-
-
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+SYNC_TEST_WITH_DATASET_BEGIN(TTestReplDataWriteAndSyncMultipart)
+virtual void Scenario(const TActorContext &ctx) {
+ // load data
+ SyncRunner->Run(ctx, ManyPutsToCorrespondingVDisks(SyncRunner->NotifyID(), Conf, DataSet));
+ LOG_NOTICE(ctx, NActorsServices::TEST, " Data is loaded");
+
+ // duplicate data to handoff
+ for (ui8 part = 1; part <= 3; ++part) {
+ SyncRunner->Run(ctx, ManyPutsToOneVDisk(SyncRunner->NotifyID(), Conf->VDisks->Get(3), DataSet, part,
+ NKikimrBlobStorage::EPutHandleClass::TabletLog));
+ }
+ LOG_NOTICE(ctx, NActorsServices::TEST, " Data is duplicated");
+
+ // wait for sync
+ SyncRunner->Run(ctx, CreateWaitForSync(SyncRunner->NotifyID(), Conf));
+ LOG_NOTICE(ctx, NActorsServices::TEST, " SYNC done");
+}
+SYNC_TEST_WITH_DATASET_END(TTestReplDataWriteAndSyncMultipart)
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SYNC_TEST_BEGIN(TTestReplProxyData, TSyncTestWithSmallCommonDataset)
virtual void Scenario(const TActorContext &ctx) {
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_repl.h b/ydb/core/blobstorage/ut_vdisk/lib/test_repl.h
index 02edd4e30d9..bb59912318b 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_repl.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_repl.h
@@ -10,13 +10,13 @@ struct TReadUntilSuccess {
const IDataSet *DataSet;
ui32 VDiskNumber;
TDuration RepeatTimeout;
- bool Multipart;
+ bool Multipart;
TReadUntilSuccess(const IDataSet *dataSet, ui32 vdiskNumber, const TDuration &repeatTimeout, bool multipart = false)
: DataSet(dataSet)
, VDiskNumber(vdiskNumber)
, RepeatTimeout(repeatTimeout)
- , Multipart(multipart)
+ , Multipart(multipart)
{}
void operator ()(TConfiguration *conf);
@@ -33,18 +33,18 @@ struct TTestReplDataWriteAndSync {
void operator ()(TConfiguration *conf);
};
-///////////////////////////////////////////////////////////////////////////
-struct TTestReplDataWriteAndSyncMultipart {
+///////////////////////////////////////////////////////////////////////////
+struct TTestReplDataWriteAndSyncMultipart {
const IDataSet *DataSet;
TTestReplDataWriteAndSyncMultipart(const IDataSet *dataSet)
- : DataSet(dataSet)
- {}
-
- void operator ()(TConfiguration *conf);
-};
-
-
+ : DataSet(dataSet)
+ {}
+
+ void operator ()(TConfiguration *conf);
+};
+
+
#define SIMPLE_CLASS_DEF_NO_PARAMS(name) \
struct name { \
void operator ()(TConfiguration *conf); \
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.cpp
index 583b2beb1b1..81ea222d944 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.cpp
@@ -147,11 +147,11 @@ void SendReadRequests(const TActorContext &ctx) {
// read logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- for (ui32 i = 0; i < 3; ++i) {
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {ds.at(i).Id});
- ctx.Send(VDiskInfo.ActorID, req.release());
- }
+ for (ui32 i = 0; i < 3; ++i) {
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {ds.at(i).Id});
+ ctx.Send(VDiskInfo.ActorID, req.release());
+ }
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data);
ExpectedSet.Put(ds.at(1).Id, NKikimrProto::OK, ds.at(1).Data);
@@ -167,10 +167,10 @@ void SendReadRequests(const TActorContext &ctx) {
// read logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {ds.at(0).Id, ds.at(1).Id, ds.at(2).Id});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {ds.at(0).Id, ds.at(1).Id, ds.at(2).Id});
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data);
ExpectedSet.Put(ds.at(1).Id, NKikimrProto::OK, ds.at(1).Data);
@@ -186,10 +186,10 @@ void SendReadRequests(const TActorContext &ctx) {
// read logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {ds.at(0).Id, ds.at(2).Id});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {ds.at(0).Id, ds.at(2).Id});
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data);
ExpectedSet.Put(ds.at(2).Id, NKikimrProto::OK, ds.at(2).Data);
@@ -204,10 +204,10 @@ void SendReadRequests(const TActorContext &ctx) {
// use shift/size to read parts of logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {{ds.at(0).Id, 2, 5}, {ds.at(1).Id, 0, 3}, {ds.at(2).Id, 2, 1}});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {{ds.at(0).Id, 2, 5}, {ds.at(1).Id, 0, 3}, {ds.at(2).Id, 2, 1}});
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data.substr(2, 5));//"cdefg"
ExpectedSet.Put(ds.at(1).Id, NKikimrProto::OK, ds.at(1).Data.substr(0, 3));//"pqr"
@@ -225,10 +225,10 @@ void SendReadRequests(const TActorContext &ctx) {
// use shift/size to read parts of logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {{ds.at(0).Id, 65u << 10u, 5}, {ds.at(1).Id, 0, 65u << 10u}});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {{ds.at(0).Id, 65u << 10u, 5}, {ds.at(1).Id, 0, 65u << 10u}});
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::ERROR, "");
ExpectedSet.Put(ds.at(1).Id, NKikimrProto::ERROR, "");
@@ -237,42 +237,42 @@ void SendReadRequests(const TActorContext &ctx) {
}
SIMPLE_TEST_END(TSimple3Put1SeqSubsError, TBasePutAllFromDataSet)
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+SIMPLE_TEST_BEGIN(TSimple3Put1GetMissingKey, TBasePutAllFromDataSet)
+void SendReadRequests(const TActorContext &ctx) {
+ // use shift/size to read parts of logoblobs
+
+ TLogoBlobID key(10, 1, 1, 0, 10, 0, 1);
+
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {key});
+ ctx.Send(VDiskInfo.ActorID, req.release());
+
+ ExpectedSet.Put(key, NKikimrProto::NODATA, "");
+
+ Counter = 1;
+}
+SIMPLE_TEST_END(TSimple3Put1GetMissingKey, TBasePutAllFromDataSet)
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SIMPLE_TEST_BEGIN(TSimple3Put1GetMissingKey, TBasePutAllFromDataSet)
-void SendReadRequests(const TActorContext &ctx) {
- // use shift/size to read parts of logoblobs
-
- TLogoBlobID key(10, 1, 1, 0, 10, 0, 1);
-
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {key});
- ctx.Send(VDiskInfo.ActorID, req.release());
-
- ExpectedSet.Put(key, NKikimrProto::NODATA, "");
-
- Counter = 1;
-}
-SIMPLE_TEST_END(TSimple3Put1GetMissingKey, TBasePutAllFromDataSet)
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-SIMPLE_TEST_BEGIN(TSimple3Put1GetMissingPart, TBasePutAllFromDataSet)
-void SendReadRequests(const TActorContext &ctx) {
- // use shift/size to read parts of logoblobs
+SIMPLE_TEST_BEGIN(TSimple3Put1GetMissingPart, TBasePutAllFromDataSet)
+void SendReadRequests(const TActorContext &ctx) {
+ // use shift/size to read parts of logoblobs
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
-
- TLogoBlobID key(ds.at(0).Id, 2);
-
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {key});
- ctx.Send(VDiskInfo.ActorID, req.release());
-
- ExpectedSet.Put(key, NKikimrProto::NODATA, "");
-
- Counter = 1;
-}
-SIMPLE_TEST_END(TSimple3Put1GetMissingPart, TBasePutAllFromDataSet)
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ TLogoBlobID key(ds.at(0).Id, 2);
+
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {key});
+ ctx.Send(VDiskInfo.ActorID, req.release());
+
+ ExpectedSet.Put(key, NKikimrProto::NODATA, "");
+
+ Counter = 1;
+}
+SIMPLE_TEST_END(TSimple3Put1GetMissingPart, TBasePutAllFromDataSet)
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SIMPLE_TEST_BEGIN(TSimpleHnd6Put1SeqGet, TBasePutAllFromDataSet)
void SendReadRequests(const TActorContext &ctx) {
// read logoblobs
@@ -285,15 +285,15 @@ void SendReadRequests(const TActorContext &ctx) {
TLogoBlobID LogoBlobID1 = TLogoBlobID(ds.at(0).Id, 0); // LogoBlobID1Part1
TLogoBlobID LogoBlobID2Part3 = TLogoBlobID(ds.at(3).Id, 3); // LogoBlobID2Part2
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {{LogoBlobID1, 0, 0, &cookie1}, {LogoBlobID2Part3, 0, 0, &cookie2}, {ds.at(4).Id, 0, 0, &cookie3}});
-
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {{LogoBlobID1, 0, 0, &cookie1}, {LogoBlobID2Part3, 0, 0, &cookie2}, {ds.at(4).Id, 0, 0, &cookie3}});
+
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data); // LogoBlobID1Part1 "abcdefghkj"
ExpectedSet.Put(ds.at(1).Id, NKikimrProto::OK, ds.at(1).Data); // LogoBlobID1Part2 "abcdefghkj"
- ExpectedSet.Put(LogoBlobID2Part3, NKikimrProto::NODATA, "");
+ ExpectedSet.Put(LogoBlobID2Part3, NKikimrProto::NODATA, "");
ExpectedSet.Put(ds.at(4).Id, NKikimrProto::OK, ds.at(4).Data); // LogoBlobID3Part1 "xyz"
Counter = 1;
@@ -308,11 +308,11 @@ void SendReadRequests(const TActorContext &ctx) {
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
ui64 cookie = 386;
-
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- {{ds.at(0).Id, 0, 0, &cookie}});
- ctx.Send(VDiskInfo.ActorID, req.release());
+
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ {{ds.at(0).Id, 0, 0, &cookie}});
+ ctx.Send(VDiskInfo.ActorID, req.release());
ExpectedSet.Put(ds.at(0).Id, NKikimrProto::OK, ds.at(0).Data);
@@ -328,17 +328,17 @@ protected:
virtual void SendReadRequests(const TActorContext &ctx, const TLogoBlobID &from, const TLogoBlobID &to) {
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
- from, to, 10);
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {},
+ from, to, 10);
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
virtual void ExpectedSetAll() {
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- ExpectedSet.Put(ds.at(0).Id.FullID(), NKikimrProto::OK, {});
- ExpectedSet.Put(ds.at(1).Id.FullID(), NKikimrProto::OK, {});
- ExpectedSet.Put(ds.at(2).Id.FullID(), NKikimrProto::OK, {});
+ ExpectedSet.Put(ds.at(0).Id.FullID(), NKikimrProto::OK, {});
+ ExpectedSet.Put(ds.at(1).Id.FullID(), NKikimrProto::OK, {});
+ ExpectedSet.Put(ds.at(2).Id.FullID(), NKikimrProto::OK, {});
Counter = 1;
}
@@ -349,7 +349,7 @@ protected:
virtual void ExpectedSetMiddle() {
const TVector<TDataItem> &ds = DataSetPtr->ToVector();
- ExpectedSet.Put(ds.at(1).Id.FullID(), NKikimrProto::OK, {});
+ ExpectedSet.Put(ds.at(1).Id.FullID(), NKikimrProto::OK, {});
Counter = 1;
}
@@ -442,9 +442,9 @@ class TSimpleGetFromEmptyDBActor : public TActorBootstrapped<TSimpleGetFromEmpty
void Bootstrap(const TActorContext &ctx) {
Become(&TThis::StateFunc);
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {LogoBlobID1});
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, {LogoBlobID1});
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
@@ -487,9 +487,9 @@ class TRangeGetFromEmptyDBActor : public TActorBootstrapped<TRangeGetFromEmptyDB
TLogoBlobID from(0, 4294967295, 4294967295, 0, 0, 0, TLogoBlobID::MaxPartId);
TLogoBlobID to (0, 0, 0, 0, 0, 0, 1);
LOG_NOTICE(ctx, NActorsServices::TEST, " Test: from=%s to=%s\n", from.ToString().data(), to.ToString().data());
- auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, from, to, 10);
- ctx.Send(VDiskInfo.ActorID, req.release());
+ auto req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskInfo.VDiskID, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None, {}, from, to, 10);
+ ctx.Send(VDiskInfo.ActorID, req.release());
}
void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.h b/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.h
index da4c1509d6b..a53ff56aec2 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_simplebs.h
@@ -36,8 +36,8 @@ SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1SeqGetAll)
SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1SeqGet2)
SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1SeqSubsOk)
SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1SeqSubsError)
-SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1GetMissingKey)
-SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1GetMissingPart)
+SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1GetMissingKey)
+SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimple3Put1GetMissingPart)
// put/extreme_get from one HANDOFF vdisk
SIMPLE_CLASS_DEF_COMP_DISK_PARAMS(TSimpleHnd6Put1SeqGet)
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/test_synclog.cpp b/ydb/core/blobstorage/ut_vdisk/lib/test_synclog.cpp
index b5608c382d2..b085e04c4bc 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/test_synclog.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/test_synclog.cpp
@@ -34,7 +34,7 @@ public:
class TDataWriterActor : public TActorBootstrapped<TDataWriterActor> {
friend class TActorBootstrapped<TDataWriterActor>;
const TDuration Period = TDuration::MilliSeconds(100);
- std::shared_ptr<TTestContext> TestCtx;
+ std::shared_ptr<TTestContext> TestCtx;
TActorId ParentId;
ui32 Generation = 0;
ui32 Iterations = 10;
@@ -63,14 +63,14 @@ class TDataWriterActor : public TActorBootstrapped<TDataWriterActor> {
TLsnSeg seg = TestCtx->LsnMngr->AllocLsnForHullAndSyncLog();
++Generation;
TEvBlobStorage::TEvVBlock logCmd(tabletId, Generation, TestCtx->SelfVDiskId, TInstant::Max());
- TAllocChunkSerializer serializer;
+ TAllocChunkSerializer serializer;
logCmd.SerializeToArcadiaStream(&serializer);
- TIntrusivePtr<TEventSerializedData> buffers = serializer.Release(logCmd.IsExtendedFormat());
+ TIntrusivePtr<TEventSerializedData> buffers = serializer.Release(logCmd.IsExtendedFormat());
ctx.Send(TestCtx->LoggerId,
new NPDisk::TEvLog(TestCtx->PDiskCtx->Dsk->Owner, TestCtx->PDiskCtx->Dsk->OwnerRound,
TLogSignature::SignatureBlock, buffers->GetString(), seg, nullptr));
// FIXME: problems on reboot
- ctx.Send(TestCtx->SyncLogId, new NSyncLog::TEvSyncLogPut(seg.Point(), tabletId, Generation, 0));
+ ctx.Send(TestCtx->SyncLogId, new NSyncLog::TEvSyncLogPut(seg.Point(), tabletId, Generation, 0));
}
}
@@ -81,7 +81,7 @@ class TDataWriterActor : public TActorBootstrapped<TDataWriterActor> {
)
public:
- TDataWriterActor(std::shared_ptr<TTestContext> testCtxt, TActorId parentId)
+ TDataWriterActor(std::shared_ptr<TTestContext> testCtxt, TActorId parentId)
: TActorBootstrapped<TDataWriterActor>()
, TestCtx(testCtxt)
, ParentId(parentId)
@@ -94,7 +94,7 @@ public:
class TSyncerActor : public TActorBootstrapped<TSyncerActor> {
friend class TActorBootstrapped<TSyncerActor>;
const TDuration Period = TDuration::MilliSeconds(200);
- std::shared_ptr<TTestContext> TestCtx;
+ std::shared_ptr<TTestContext> TestCtx;
TSyncState SyncState;
TVDiskID SourceVDisk;
TVDiskID TargetVDisk;
@@ -137,7 +137,7 @@ class TSyncerActor : public TActorBootstrapped<TSyncerActor> {
)
public:
- TSyncerActor(std::shared_ptr<TTestContext> testCtx, const TVDiskID &sourceVDisk)
+ TSyncerActor(std::shared_ptr<TTestContext> testCtx, const TVDiskID &sourceVDisk)
: TActorBootstrapped<TSyncerActor>()
, TestCtx(std::move(testCtx))
, SourceVDisk(sourceVDisk)
@@ -150,7 +150,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////
class TSyncLogTestWriteActor : public TActorBootstrapped<TSyncLogTestWriteActor> {
TConfiguration *Conf;
- std::shared_ptr<TTestContext> TestCtx = std::make_shared<TTestContext>();
+ std::shared_ptr<TTestContext> TestCtx = std::make_shared<TTestContext>();
TVDiskContextPtr VCtx;
TIntrusivePtr<TVDiskConfig> VDiskConfig;
TActorId LogCutterId;
@@ -165,7 +165,7 @@ class TSyncLogTestWriteActor : public TActorBootstrapped<TSyncLogTestWriteActor>
TIntrusivePtr<NMonitoring::TDynamicCounters> counters(new NMonitoring::TDynamicCounters);
auto &vDiskInstance = Conf->VDisks->Get(0);
auto &groupInfo = Conf->GroupInfo;
- VCtx = MakeIntrusive<TVDiskContext>(ctx.SelfID, groupInfo->PickTopology(), counters, vDiskInstance.VDiskID,
+ VCtx = MakeIntrusive<TVDiskContext>(ctx.SelfID, groupInfo->PickTopology(), counters, vDiskInstance.VDiskID,
ctx.ExecutorThread.ActorSystem, TPDiskCategory::DEVICE_TYPE_UNKNOWN);
VDiskConfig = vDiskInstance.Cfg;
TestCtx->SelfVDiskId = groupInfo->GetVDiskId(VCtx->ShortSelfVDisk);
@@ -211,7 +211,7 @@ class TSyncLogTestWriteActor : public TActorBootstrapped<TSyncLogTestWriteActor>
VCtx->SyncLogCache
};
TString explanation;
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired =
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired =
NSyncLog::TSyncLogRepaired::Construct(std::move(params), TString(), 0, explanation);
Y_VERIFY(repaired);
@@ -227,7 +227,7 @@ class TSyncLogTestWriteActor : public TActorBootstrapped<TSyncLogTestWriteActor>
VDiskConfig->SyncLogMaxMemAmount,
VDiskConfig->MaxResponseSize,
Db->SyncLogFirstLsnToKeep);
- TestCtx->SyncLogId = ctx.Register(CreateSyncLogActor(slCtx, Conf->GroupInfo, TestCtx->SelfVDiskId, std::move(repaired)));
+ TestCtx->SyncLogId = ctx.Register(CreateSyncLogActor(slCtx, Conf->GroupInfo, TestCtx->SelfVDiskId, std::move(repaired)));
// Send Db birth lsn
ui64 dbBirthLsn = 0;
ctx.Send(TestCtx->SyncLogId, new NSyncLog::TEvSyncLogDbBirthLsn(dbBirthLsn));
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.cpp b/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.cpp
index 0d68629c647..05dcafa1637 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.cpp
@@ -1,127 +1,127 @@
-#include "vdisk_mock.h"
+#include "vdisk_mock.h"
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/protos/services_common.pb.h>
-#include <util/generic/hash_set.h>
-#include <util/system/guard.h>
-
-namespace NKikimr {
-
-using namespace NActors;
-
-class TVDiskMockActor : public TActorBootstrapped<TVDiskMockActor> {
- const TVDiskID VDiskId;
- const TIntrusivePtr<TVDiskMockSharedState> Shared;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+#include <util/generic/hash_set.h>
+#include <util/system/guard.h>
+
+namespace NKikimr {
+
+using namespace NActors;
+
+class TVDiskMockActor : public TActorBootstrapped<TVDiskMockActor> {
+ const TVDiskID VDiskId;
+ const TIntrusivePtr<TVDiskMockSharedState> Shared;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
TVDiskContextPtr VCtx;
- TMap<TLogoBlobID, std::optional<TString>> LogoBlobs;
+ TMap<TLogoBlobID, std::optional<TString>> LogoBlobs;
TMap<std::tuple<ui64, ui8, ui32, ui32, bool>, std::tuple<ui32, ui32>> Barriers;
TMap<ui64, ui32> Blocks;
- bool ErrorMode = false;
- bool LostMode = false;
-
-public:
+ bool ErrorMode = false;
+ bool LostMode = false;
+
+public:
TVDiskMockActor(const TVDiskID& vdiskId,
TIntrusivePtr<TVDiskMockSharedState> shared,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
- : VDiskId(vdiskId)
- , Shared(std::move(shared))
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
+ : VDiskId(vdiskId)
+ , Shared(std::move(shared))
, Top(std::move(top))
- {
- }
-
- template<typename T>
- static void FinalizeAndSend(std::unique_ptr<T> ptr, const TActorContext& ctx, const TActorId& recipient) {
- T* const p = ptr.get();
- p->FinalizeAndSend(ctx, std::make_unique<IEventHandle>(recipient, ctx.SelfID, ptr.release()));
- }
-
+ {
+ }
+
+ template<typename T>
+ static void FinalizeAndSend(std::unique_ptr<T> ptr, const TActorContext& ctx, const TActorId& recipient) {
+ T* const p = ptr.get();
+ p->FinalizeAndSend(ctx, std::make_unique<IEventHandle>(recipient, ctx.SelfID, ptr.release()));
+ }
+
void Bootstrap(const TActorContext& ctx) {
- VCtx.Reset(new TVDiskContext(ctx.SelfID, Top, new NMonitoring::TDynamicCounters, VDiskId,
+ VCtx.Reset(new TVDiskContext(ctx.SelfID, Top, new NMonitoring::TDynamicCounters, VDiskId,
ctx.ExecutorThread.ActorSystem, TPDiskCategory::DEVICE_TYPE_UNKNOWN));
- Become(&TVDiskMockActor::StateFunc);
- }
-
- bool IsBlocked(ui64 tabletId, ui32 generation) const {
- auto it = Blocks.find(tabletId);
- return it != Blocks.end() && generation <= it->second;
- }
-
- bool IsBlocked(const TLogoBlobID& id) const {
- return IsBlocked(id.TabletID(), id.Generation());
- }
-
- template<typename TMsg>
- void PutBlob(const TLogoBlobID& id, std::optional<TString> data, TMsg& msg, ui32 payloadIdx) {
- // get data
- if (!data) {
- const TRope& rope = msg.GetPayload(payloadIdx);
- data = TString::Uninitialized(rope.GetSize());
- rope.Begin().ExtractPlainDataAndAdvance(data->Detach(), data->size());
- }
-
- Y_VERIFY(data->size() == Shared->GroupInfo->Type.PartSize(id));
-
- // write record
- if (auto it = LogoBlobs.find(id); it != LogoBlobs.end()) {
- // ensure that new record is the same as the existing one with same blob id
- auto makeErrorString = [&] {
- TStringBuilder s;
- s << "id# " << id.ToString();
- if (it->second) {
- s << " " << it->second->size() << "b";
- } else {
- s << " NODATA";
- }
- s << " data# " << data->size() << "b";
- return s;
- };
- Y_VERIFY(!it->second || *it->second == *data, "%s", makeErrorString().data());
- }
- LogoBlobs[id] = std::move(data);
-
- // report this blob to shared state (emulate syncer)
- with_lock (Shared->Mutex) {
- TLogoBlobID fullId(id.FullID());
- TIngress ingress(*TIngress::CreateIngressWithLocal(&Shared->GroupInfo->GetTopology(), VDiskId, id));
- TIngress& sharedIngress = Shared->BlobToIngressMap[fullId];
- sharedIngress.Merge(ingress.CopyWithoutLocal(Shared->GroupInfo->Type));
- }
- }
-
- void Handle(TEvBlobStorage::TEvVPut::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId,
- "record.VDiskId# %s VDiskId# %s",
+ Become(&TVDiskMockActor::StateFunc);
+ }
+
+ bool IsBlocked(ui64 tabletId, ui32 generation) const {
+ auto it = Blocks.find(tabletId);
+ return it != Blocks.end() && generation <= it->second;
+ }
+
+ bool IsBlocked(const TLogoBlobID& id) const {
+ return IsBlocked(id.TabletID(), id.Generation());
+ }
+
+ template<typename TMsg>
+ void PutBlob(const TLogoBlobID& id, std::optional<TString> data, TMsg& msg, ui32 payloadIdx) {
+ // get data
+ if (!data) {
+ const TRope& rope = msg.GetPayload(payloadIdx);
+ data = TString::Uninitialized(rope.GetSize());
+ rope.Begin().ExtractPlainDataAndAdvance(data->Detach(), data->size());
+ }
+
+ Y_VERIFY(data->size() == Shared->GroupInfo->Type.PartSize(id));
+
+ // write record
+ if (auto it = LogoBlobs.find(id); it != LogoBlobs.end()) {
+ // ensure that new record is the same as the existing one with same blob id
+ auto makeErrorString = [&] {
+ TStringBuilder s;
+ s << "id# " << id.ToString();
+ if (it->second) {
+ s << " " << it->second->size() << "b";
+ } else {
+ s << " NODATA";
+ }
+ s << " data# " << data->size() << "b";
+ return s;
+ };
+ Y_VERIFY(!it->second || *it->second == *data, "%s", makeErrorString().data());
+ }
+ LogoBlobs[id] = std::move(data);
+
+ // report this blob to shared state (emulate syncer)
+ with_lock (Shared->Mutex) {
+ TLogoBlobID fullId(id.FullID());
+ TIngress ingress(*TIngress::CreateIngressWithLocal(&Shared->GroupInfo->GetTopology(), VDiskId, id));
+ TIngress& sharedIngress = Shared->BlobToIngressMap[fullId];
+ sharedIngress.Merge(ingress.CopyWithoutLocal(Shared->GroupInfo->Type));
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVPut::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId,
+ "record.VDiskId# %s VDiskId# %s",
VDiskIDFromVDiskID(record.GetVDiskID()).ToString().data(), VDiskId.ToString().data());
- TLogoBlobID id{LogoBlobIDFromLogoBlobID(record.GetBlobID())};
-
+ TLogoBlobID id{LogoBlobIDFromLogoBlobID(record.GetBlobID())};
+
LOG_DEBUG(ctx, NActorsServices::TEST, "TEvVPut# %s", ev->Get()->ToString().data());
-
- auto sendResponse = [&](NKikimrProto::EReplyStatus status, const TString& errorReason) {
- ui64 cookie = record.GetCookie();
- auto response = std::make_unique<TEvBlobStorage::TEvVPutResult>(status, id,
+
+ auto sendResponse = [&](NKikimrProto::EReplyStatus status, const TString& errorReason) {
+ ui64 cookie = record.GetCookie();
+ auto response = std::make_unique<TEvBlobStorage::TEvVPutResult>(status, id,
VDiskIDFromVDiskID(record.GetVDiskID()), record.HasCookie() ? &cookie : nullptr,
TOutOfSpaceStatus(0u, 0.0), TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, errorReason);
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- };
-
- if (ErrorMode) {
- return sendResponse(NKikimrProto::ERROR, "error mode");
- }
-
- // check for blocks
- if (!record.GetIgnoreBlock() && IsBlocked(id)) {
- return sendResponse(NKikimrProto::BLOCKED, "blocked");
- }
-
- // put the blob in place
- PutBlob(id, record.HasBuffer() ? std::make_optional(record.GetBuffer()) : std::nullopt, *ev->Get(), 0);
-
- // report success
- return sendResponse(NKikimrProto::OK, TString());
- }
-
+ &record, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, errorReason);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ };
+
+ if (ErrorMode) {
+ return sendResponse(NKikimrProto::ERROR, "error mode");
+ }
+
+ // check for blocks
+ if (!record.GetIgnoreBlock() && IsBlocked(id)) {
+ return sendResponse(NKikimrProto::BLOCKED, "blocked");
+ }
+
+ // put the blob in place
+ PutBlob(id, record.HasBuffer() ? std::make_optional(record.GetBuffer()) : std::nullopt, *ev->Get(), 0);
+
+ // report success
+ return sendResponse(NKikimrProto::OK, TString());
+ }
+
void Handle(TEvBlobStorage::TEvVMultiPut::TPtr& ev, const TActorContext& ctx) {
auto& record = ev->Get()->Record;
Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId,
@@ -131,15 +131,15 @@ public:
LOG_DEBUG(ctx, NActorsServices::TEST, "TEvVMultiPut# %s", ev->Get()->ToString().data());
ui64 cookie = record.GetCookie();
- auto response = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(NKikimrProto::OK,
+ auto response = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(NKikimrProto::OK,
VDiskIDFromVDiskID(record.GetVDiskID()), record.HasCookie() ? &cookie : nullptr,
TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString());
+ &record, nullptr, nullptr, nullptr, 0, NWilson::TTraceId(), 0, TString());
if (ErrorMode) {
- response->MakeError(NKikimrProto::ERROR, "error mode", record);
+ response->MakeError(NKikimrProto::ERROR, "error mode", record);
LOG_DEBUG(ctx, NActorsServices::TEST, "TEvVMultiPut %s -> %s", ev->Get()->ToString().data(),
response->ToString().data());
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
return;
}
@@ -148,334 +148,334 @@ public:
TLogoBlobID id{LogoBlobIDFromLogoBlobID(item.GetBlobID())};
// check for blocks
if (!record.GetIgnoreBlock() && IsBlocked(id)) {
- response->AddVPutResult(NKikimrProto::BLOCKED, "blocked", id, &i);
+ response->AddVPutResult(NKikimrProto::BLOCKED, "blocked", id, &i);
continue;
}
- // put the blob in place
- PutBlob(id, item.HasBuffer() ? std::make_optional(item.GetBuffer()) : std::nullopt, *ev->Get(), i);
+ // put the blob in place
+ PutBlob(id, item.HasBuffer() ? std::make_optional(item.GetBuffer()) : std::nullopt, *ev->Get(), i);
// report success
- response->AddVPutResult(NKikimrProto::OK, TString(), id, &i);
+ response->AddVPutResult(NKikimrProto::OK, TString(), id, &i);
}
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
}
- void Handle(TEvBlobStorage::TEvVGet::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- TMaybe<ui64> cookie;
- if (record.HasCookie()) {
- cookie = record.GetCookie();
- }
-
- auto response = std::make_unique<TEvBlobStorage::TEvVGetResult>(NKikimrProto::OK,
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), cookie, 0U, 0U);
-
- if (ErrorMode) {
- response->MakeError(NKikimrProto::ERROR, "error mode", record);
+ void Handle(TEvBlobStorage::TEvVGet::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ TMaybe<ui64> cookie;
+ if (record.HasCookie()) {
+ cookie = record.GetCookie();
+ }
+
+ auto response = std::make_unique<TEvBlobStorage::TEvVGetResult>(NKikimrProto::OK,
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
+ &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), cookie, 0U, 0U);
+
+ if (ErrorMode) {
+ response->MakeError(NKikimrProto::ERROR, "error mode", record);
LOG_DEBUG(ctx, NActorsServices::TEST, "TEvVGet# %s -> %s", ev->Get()->ToString().data(), response->ToString().data());
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- return;
- }
-
- TMaybe<TLogoBlobID> prevGenericId;
-
- auto addResult = [&](const TLogoBlobID& id, const std::optional<TString>& buffer, ui32 offset, ui32 size, const ui64 *cookie) {
- const TLogoBlobID fullId(id.FullID());
-
- if (record.GetIndexOnly()) {
- // do not allow duplicates when executing index-only query
- if (prevGenericId && fullId == *prevGenericId) {
- return;
- } else {
- prevGenericId = fullId;
- }
- }
-
- // get the ingress for this blob
- ui64 ingress = 0;
- const ui64 *pingr = nullptr;
-
- // find common ingress entry for this item
- TIngress ingr;
- with_lock (Shared->Mutex) {
- auto iter = Shared->BlobToIngressMap.find(fullId);
- Y_VERIFY(iter != Shared->BlobToIngressMap.end(), "fullId# %s", fullId.ToString().data());
- ingr = iter->second;
- }
-
- // find all local replicas for this blob and merge 'em into ingress
- for (auto iter = LogoBlobs.lower_bound(fullId); iter != LogoBlobs.end() && iter->first.FullID() == fullId; ++iter) {
- if (iter->second) {
- ingr.Merge(*TIngress::CreateIngressWithLocal(&Shared->GroupInfo->GetTopology(), VDiskId, iter->first));
- }
- }
-
- if (record.GetShowInternals()) {
- ingress = ingr.Raw();
- pingr = &ingress;
- }
-
- if (LostMode) {
- // answer like in VDisk query code
- if (record.GetIndexOnly()) {
- response->AddResult(NKikimrProto::NOT_YET, fullId, cookie, pingr);
- } else {
- response->AddResult(NKikimrProto::NOT_YET, id, offset, nullptr, size, cookie, pingr);
- }
- } else {
- // adjust offset and size
- if (buffer) {
- offset = Min<size_t>(offset, buffer->size());
- const ui32 maxSize = buffer->size() - offset;
- size = size ? Min(size, maxSize) : maxSize;
- }
-
- // check the status; we reply with OK on all index queries (we have found the blob); also we reply OK on
- // data queries where we have the data
- NKikimrProto::EReplyStatus status = record.GetIndexOnly() || buffer
- ? NKikimrProto::OK
- : NKikimrProto::NODATA;
-
- if (record.GetIndexOnly() || !buffer) {
- NMatrix::TVectorType local = ingr.LocalParts(Shared->GroupInfo->Type);
- response->AddResult(status, record.GetIndexOnly() ? fullId : id, cookie, pingr, &local);
- } else {
- response->AddResult(status, id, offset, buffer->data() + offset, size, cookie, pingr);
- }
- }
- };
-
- // process ranged queries
- if (record.HasRangeQuery()) {
- const auto& rangeQuery = record.GetRangeQuery();
- ui64 rangeCookie = rangeQuery.GetCookie();
-
- TLogoBlobID from{LogoBlobIDFromLogoBlobID(rangeQuery.GetFrom())};
- TLogoBlobID to{LogoBlobIDFromLogoBlobID(rangeQuery.GetTo())};
-
- const bool forward = from <= to;
- auto it = forward ? LogoBlobs.lower_bound(from) : LogoBlobs.upper_bound(from);
- ui32 numResults = 0;
- for (;;) {
- // move one step back when going down
- if (forward) {
- if (it == LogoBlobs.end()) {
- break;
- }
- } else {
- if (it == LogoBlobs.begin()) {
- break;
- }
- --it;
- if (it->first < to) {
- break;
- }
- }
-
- // check for results count
- if (rangeQuery.HasMaxResults() && numResults == rangeQuery.GetMaxResults()) {
- // FIXME: result?
- break;
- }
-
- addResult(it->first, it->second, 0, 0, record.HasCookie() ? &rangeCookie : nullptr);
- ++numResults;
-
- // move one step forward
- if (forward) {
- if (++it == LogoBlobs.end()) {
- break;
- }
- if (it->first > to) {
- break;
- }
- }
- }
- }
-
- // process extreme queries
- for (const auto& query : record.GetExtremeQueries()) {
- const TLogoBlobID id{LogoBlobIDFromLogoBlobID(query.GetId())};
- ui64 queryCookie = query.GetCookie();
- bool found = false;
- prevGenericId.Clear();
- for (auto it = LogoBlobs.lower_bound(id); it != LogoBlobs.end() && it->first.FullID() == id.FullID(); ++it) {
- if (id.PartId() && id.PartId() != it->first.PartId()) {
- break;
- }
- addResult(it->first, it->second, query.GetShift(), query.GetSize(), query.HasCookie() ? &queryCookie : nullptr);
- found = true;
- }
- if (!found) {
- response->AddResult(NKikimrProto::NODATA, id, query.HasCookie() ? &queryCookie : nullptr);
- }
- }
-
- // send final response
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ return;
+ }
+
+ TMaybe<TLogoBlobID> prevGenericId;
+
+ auto addResult = [&](const TLogoBlobID& id, const std::optional<TString>& buffer, ui32 offset, ui32 size, const ui64 *cookie) {
+ const TLogoBlobID fullId(id.FullID());
+
+ if (record.GetIndexOnly()) {
+ // do not allow duplicates when executing index-only query
+ if (prevGenericId && fullId == *prevGenericId) {
+ return;
+ } else {
+ prevGenericId = fullId;
+ }
+ }
+
+ // get the ingress for this blob
+ ui64 ingress = 0;
+ const ui64 *pingr = nullptr;
+
+ // find common ingress entry for this item
+ TIngress ingr;
+ with_lock (Shared->Mutex) {
+ auto iter = Shared->BlobToIngressMap.find(fullId);
+ Y_VERIFY(iter != Shared->BlobToIngressMap.end(), "fullId# %s", fullId.ToString().data());
+ ingr = iter->second;
+ }
+
+ // find all local replicas for this blob and merge 'em into ingress
+ for (auto iter = LogoBlobs.lower_bound(fullId); iter != LogoBlobs.end() && iter->first.FullID() == fullId; ++iter) {
+ if (iter->second) {
+ ingr.Merge(*TIngress::CreateIngressWithLocal(&Shared->GroupInfo->GetTopology(), VDiskId, iter->first));
+ }
+ }
+
+ if (record.GetShowInternals()) {
+ ingress = ingr.Raw();
+ pingr = &ingress;
+ }
+
+ if (LostMode) {
+ // answer like in VDisk query code
+ if (record.GetIndexOnly()) {
+ response->AddResult(NKikimrProto::NOT_YET, fullId, cookie, pingr);
+ } else {
+ response->AddResult(NKikimrProto::NOT_YET, id, offset, nullptr, size, cookie, pingr);
+ }
+ } else {
+ // adjust offset and size
+ if (buffer) {
+ offset = Min<size_t>(offset, buffer->size());
+ const ui32 maxSize = buffer->size() - offset;
+ size = size ? Min(size, maxSize) : maxSize;
+ }
+
+ // check the status; we reply with OK on all index queries (we have found the blob); also we reply OK on
+ // data queries where we have the data
+ NKikimrProto::EReplyStatus status = record.GetIndexOnly() || buffer
+ ? NKikimrProto::OK
+ : NKikimrProto::NODATA;
+
+ if (record.GetIndexOnly() || !buffer) {
+ NMatrix::TVectorType local = ingr.LocalParts(Shared->GroupInfo->Type);
+ response->AddResult(status, record.GetIndexOnly() ? fullId : id, cookie, pingr, &local);
+ } else {
+ response->AddResult(status, id, offset, buffer->data() + offset, size, cookie, pingr);
+ }
+ }
+ };
+
+ // process ranged queries
+ if (record.HasRangeQuery()) {
+ const auto& rangeQuery = record.GetRangeQuery();
+ ui64 rangeCookie = rangeQuery.GetCookie();
+
+ TLogoBlobID from{LogoBlobIDFromLogoBlobID(rangeQuery.GetFrom())};
+ TLogoBlobID to{LogoBlobIDFromLogoBlobID(rangeQuery.GetTo())};
+
+ const bool forward = from <= to;
+ auto it = forward ? LogoBlobs.lower_bound(from) : LogoBlobs.upper_bound(from);
+ ui32 numResults = 0;
+ for (;;) {
+ // move one step back when going down
+ if (forward) {
+ if (it == LogoBlobs.end()) {
+ break;
+ }
+ } else {
+ if (it == LogoBlobs.begin()) {
+ break;
+ }
+ --it;
+ if (it->first < to) {
+ break;
+ }
+ }
+
+ // check for results count
+ if (rangeQuery.HasMaxResults() && numResults == rangeQuery.GetMaxResults()) {
+ // FIXME: result?
+ break;
+ }
+
+ addResult(it->first, it->second, 0, 0, record.HasCookie() ? &rangeCookie : nullptr);
+ ++numResults;
+
+ // move one step forward
+ if (forward) {
+ if (++it == LogoBlobs.end()) {
+ break;
+ }
+ if (it->first > to) {
+ break;
+ }
+ }
+ }
+ }
+
+ // process extreme queries
+ for (const auto& query : record.GetExtremeQueries()) {
+ const TLogoBlobID id{LogoBlobIDFromLogoBlobID(query.GetId())};
+ ui64 queryCookie = query.GetCookie();
+ bool found = false;
+ prevGenericId.Clear();
+ for (auto it = LogoBlobs.lower_bound(id); it != LogoBlobs.end() && it->first.FullID() == id.FullID(); ++it) {
+ if (id.PartId() && id.PartId() != it->first.PartId()) {
+ break;
+ }
+ addResult(it->first, it->second, query.GetShift(), query.GetSize(), query.HasCookie() ? &queryCookie : nullptr);
+ found = true;
+ }
+ if (!found) {
+ response->AddResult(NKikimrProto::NODATA, id, query.HasCookie() ? &queryCookie : nullptr);
+ }
+ }
+
+ // send final response
LOG_DEBUG(ctx, NActorsServices::TEST, "TEvVGet# %s -> %s", ev->Get()->ToString().data(), response->ToString().data());
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- }
-
- void Handle(TEvBlobStorage::TEvVBlock::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- ui32& gen = Blocks[record.GetTabletId()];
- gen = Max(gen, record.GetGeneration());
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ }
+
+ void Handle(TEvBlobStorage::TEvVBlock::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ ui32& gen = Blocks[record.GetTabletId()];
+ gen = Max(gen, record.GetGeneration());
TEvBlobStorage::TEvVBlockResult::TTabletActGen actual(record.GetTabletId(), record.GetGeneration());
- auto response = std::make_unique<TEvBlobStorage::TEvVBlockResult>(NKikimrProto::OK, &actual,
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
- (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), 0);
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- }
-
- void Handle(TEvBlobStorage::TEvVGetBlock::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- std::unique_ptr<TEvBlobStorage::TEvVGetBlockResult> response;
- auto it = Blocks.find(record.GetTabletId());
- if (it != Blocks.end()) {
- response.reset(new TEvBlobStorage::TEvVGetBlockResult(NKikimrProto::OK, it->first, it->second,
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
- ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId()));
- } else {
- response.reset(new TEvBlobStorage::TEvVGetBlockResult(NKikimrProto::NODATA, record.GetTabletId(),
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
- ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId()));
- }
-
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- }
-
- void Handle(TEvBlobStorage::TEvVCollectGarbage::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- if (IsBlocked(record.GetTabletId(), record.GetRecordGeneration())) {
- auto response = std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(NKikimrProto::BLOCKED,
- record.GetTabletId(), record.GetRecordGeneration(), record.GetChannel(),
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
- (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), 0);
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- return;
- }
-
- auto key = std::make_tuple(record.GetTabletId(), record.GetChannel(), record.GetRecordGeneration(),
- record.GetPerGenerationCounter(), record.GetHard());
- auto value = std::make_tuple(record.GetCollectGeneration(), record.GetCollectStep());
-
- auto it = Barriers.find(key);
- if (it != Barriers.end()) {
- Y_VERIFY(it->second == value);
- } else {
- Barriers[key] = value;
- }
-
- // FIXME: collect garbage
-
- auto response = std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(NKikimrProto::OK, record.GetTabletId(),
- record.GetRecordGeneration(), record.GetChannel(), VDiskIDFromVDiskID(record.GetVDiskID()),
- TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr,
- NWilson::TTraceId(), 0);
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- }
-
- void Handle(TEvBlobStorage::TEvVGetBarrier::TPtr& ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
-
- const auto& from = record.GetFrom();
- auto first = std::make_tuple(from.GetTabletId(), from.GetChannel(), from.GetRecordGeneration(),
- from.GetPerGenerationCounter(), from.GetHard());
-
- const auto& to = record.GetTo();
- auto last = std::make_tuple(to.GetTabletId(), to.GetChannel(), to.GetRecordGeneration(),
- to.GetPerGenerationCounter(), to.GetHard());
-
- auto response = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(NKikimrProto::OK,
- VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
- &record, nullptr, nullptr, nullptr, NWilson::TTraceId());
-
- auto it = Barriers.lower_bound(first);
- while (it != Barriers.end() && it->first <= last) {
- const auto& key = it->first;
- const auto& value = it->second;
- response->AddResult({std::get<0>(key), std::get<1>(key), std::get<2>(key), std::get<3>(key), std::get<4>(key)},
- {std::get<0>(value), std::get<1>(value), {}}, false);
- ++it;
- }
-
- FinalizeAndSend(std::move(response), ctx, ev->Sender);
- }
-
- void Handle(TEvBlobStorage::TEvVCheckReadiness::TPtr& ev, const TActorContext& ctx) {
- ctx.Send(ev->Sender, new TEvBlobStorage::TEvVCheckReadinessResult(NKikimrProto::OK), 0, ev->Cookie);
- }
-
- void Handle(TEvVMockCtlRequest::TPtr& ev, const TActorContext& ctx) {
- auto msg = ev->Get();
- switch (msg->Action) {
- case TEvVMockCtlRequest::EAction::DeleteBlobs: {
- auto first = LogoBlobs.lower_bound(msg->First);
- auto last = LogoBlobs.upper_bound(msg->Last);
- for (auto it = first; it != last; ++it) {
- it->second.reset();
- }
- break;
- }
-
- // erase blobs as they have never been written to this disk
- case TEvVMockCtlRequest::EAction::WipeOutBlobs: {
- auto first = LogoBlobs.lower_bound(msg->First);
- auto last = LogoBlobs.upper_bound(msg->Last);
- with_lock (Shared->Mutex) {
- for (auto it = first; it != last; ++it) {
- const TLogoBlobID& id = it->first;
- TLogoBlobID fullId(id.FullID());
+ auto response = std::make_unique<TEvBlobStorage::TEvVBlockResult>(NKikimrProto::OK, &actual,
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
+ (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), 0);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetBlock::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ std::unique_ptr<TEvBlobStorage::TEvVGetBlockResult> response;
+ auto it = Blocks.find(record.GetTabletId());
+ if (it != Blocks.end()) {
+ response.reset(new TEvBlobStorage::TEvVGetBlockResult(NKikimrProto::OK, it->first, it->second,
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
+ ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId()));
+ } else {
+ response.reset(new TEvBlobStorage::TEvVGetBlockResult(NKikimrProto::NODATA, record.GetTabletId(),
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
+ ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId()));
+ }
+
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ }
+
+ void Handle(TEvBlobStorage::TEvVCollectGarbage::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ if (IsBlocked(record.GetTabletId(), record.GetRecordGeneration())) {
+ auto response = std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(NKikimrProto::BLOCKED,
+ record.GetTabletId(), record.GetRecordGeneration(), record.GetChannel(),
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(),
+ (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr, NWilson::TTraceId(), 0);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ return;
+ }
+
+ auto key = std::make_tuple(record.GetTabletId(), record.GetChannel(), record.GetRecordGeneration(),
+ record.GetPerGenerationCounter(), record.GetHard());
+ auto value = std::make_tuple(record.GetCollectGeneration(), record.GetCollectStep());
+
+ auto it = Barriers.find(key);
+ if (it != Barriers.end()) {
+ Y_VERIFY(it->second == value);
+ } else {
+ Barriers[key] = value;
+ }
+
+ // FIXME: collect garbage
+
+ auto response = std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(NKikimrProto::OK, record.GetTabletId(),
+ record.GetRecordGeneration(), record.GetChannel(), VDiskIDFromVDiskID(record.GetVDiskID()),
+ TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(), &record, nullptr, nullptr, nullptr,
+ NWilson::TTraceId(), 0);
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetBarrier::TPtr& ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ Y_VERIFY(VDiskIDFromVDiskID(record.GetVDiskID()) == VDiskId);
+
+ const auto& from = record.GetFrom();
+ auto first = std::make_tuple(from.GetTabletId(), from.GetChannel(), from.GetRecordGeneration(),
+ from.GetPerGenerationCounter(), from.GetHard());
+
+ const auto& to = record.GetTo();
+ auto last = std::make_tuple(to.GetTabletId(), to.GetChannel(), to.GetRecordGeneration(),
+ to.GetPerGenerationCounter(), to.GetHard());
+
+ auto response = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(NKikimrProto::OK,
+ VDiskIDFromVDiskID(record.GetVDiskID()), TAppData::TimeProvider->Now(), (ui32)ev->Get()->GetCachedByteSize(),
+ &record, nullptr, nullptr, nullptr, NWilson::TTraceId());
+
+ auto it = Barriers.lower_bound(first);
+ while (it != Barriers.end() && it->first <= last) {
+ const auto& key = it->first;
+ const auto& value = it->second;
+ response->AddResult({std::get<0>(key), std::get<1>(key), std::get<2>(key), std::get<3>(key), std::get<4>(key)},
+ {std::get<0>(value), std::get<1>(value), {}}, false);
+ ++it;
+ }
+
+ FinalizeAndSend(std::move(response), ctx, ev->Sender);
+ }
+
+ void Handle(TEvBlobStorage::TEvVCheckReadiness::TPtr& ev, const TActorContext& ctx) {
+ ctx.Send(ev->Sender, new TEvBlobStorage::TEvVCheckReadinessResult(NKikimrProto::OK), 0, ev->Cookie);
+ }
+
+ void Handle(TEvVMockCtlRequest::TPtr& ev, const TActorContext& ctx) {
+ auto msg = ev->Get();
+ switch (msg->Action) {
+ case TEvVMockCtlRequest::EAction::DeleteBlobs: {
+ auto first = LogoBlobs.lower_bound(msg->First);
+ auto last = LogoBlobs.upper_bound(msg->Last);
+ for (auto it = first; it != last; ++it) {
+ it->second.reset();
+ }
+ break;
+ }
+
+ // erase blobs as they have never been written to this disk
+ case TEvVMockCtlRequest::EAction::WipeOutBlobs: {
+ auto first = LogoBlobs.lower_bound(msg->First);
+ auto last = LogoBlobs.upper_bound(msg->Last);
+ with_lock (Shared->Mutex) {
+ for (auto it = first; it != last; ++it) {
+ const TLogoBlobID& id = it->first;
+ TLogoBlobID fullId(id.FullID());
TIngress ingress(*TIngress::CreateIngressWithLocal(&Shared->GroupInfo->GetTopology(), VDiskId, id));
- TIngress& sharedIngress = Shared->BlobToIngressMap[fullId];
- ui64 newSharedIngress = sharedIngress.Raw() & ~ingress.Raw();
- if (!newSharedIngress) {
- Shared->BlobToIngressMap.erase(fullId);
- } else {
- sharedIngress = TIngress(newSharedIngress);
- }
- }
- }
- LogoBlobs.erase(first, last);
- break;
- }
-
- case TEvVMockCtlRequest::EAction::SetErrorMode:
- ErrorMode = msg->ErrorMode;
- LostMode = msg->LostMode;
- break;
- }
- ctx.Send(ev->Sender, new TEvVMockCtlResponse);
- }
-
+ TIngress& sharedIngress = Shared->BlobToIngressMap[fullId];
+ ui64 newSharedIngress = sharedIngress.Raw() & ~ingress.Raw();
+ if (!newSharedIngress) {
+ Shared->BlobToIngressMap.erase(fullId);
+ } else {
+ sharedIngress = TIngress(newSharedIngress);
+ }
+ }
+ }
+ LogoBlobs.erase(first, last);
+ break;
+ }
+
+ case TEvVMockCtlRequest::EAction::SetErrorMode:
+ ErrorMode = msg->ErrorMode;
+ LostMode = msg->LostMode;
+ break;
+ }
+ ctx.Send(ev->Sender, new TEvVMockCtlResponse);
+ }
+
STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvVPut, Handle);
+ HFunc(TEvBlobStorage::TEvVPut, Handle);
HFunc(TEvBlobStorage::TEvVMultiPut, Handle);
- HFunc(TEvBlobStorage::TEvVGet, Handle);
- HFunc(TEvBlobStorage::TEvVBlock, Handle);
- HFunc(TEvBlobStorage::TEvVGetBlock, Handle);
- HFunc(TEvBlobStorage::TEvVCollectGarbage, Handle);
- HFunc(TEvBlobStorage::TEvVGetBarrier, Handle);
- HFunc(TEvBlobStorage::TEvVCheckReadiness, Handle);
- HFunc(TEvVMockCtlRequest, Handle);
+ HFunc(TEvBlobStorage::TEvVGet, Handle);
+ HFunc(TEvBlobStorage::TEvVBlock, Handle);
+ HFunc(TEvBlobStorage::TEvVGetBlock, Handle);
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, Handle);
+ HFunc(TEvBlobStorage::TEvVGetBarrier, Handle);
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, Handle);
+ HFunc(TEvVMockCtlRequest, Handle);
)
-};
-
+};
+
IActor *CreateVDiskMockActor(const TVDiskID& vdiskId,
TIntrusivePtr<TVDiskMockSharedState> shared,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top) {
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top) {
return new TVDiskMockActor(vdiskId, std::move(shared), std::move(top));
-}
-
-} // NKikimr
+}
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h b/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h
index 7330ae908ab..39aa9ca6620 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h
+++ b/ydb/core/blobstorage/ut_vdisk/lib/vdisk_mock.h
@@ -1,70 +1,70 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
-
-#include <util/system/mutex.h>
-
-namespace NKikimr {
-
-struct TEvVMockCtlRequest : public TEventLocal<TEvVMockCtlRequest, TEvBlobStorage::EvVMockCtlRequest> {
- enum class EAction {
- DeleteBlobs,
- SetErrorMode,
- WipeOutBlobs,
- };
-
- EAction Action;
- TLogoBlobID First; // starting blob id
- TLogoBlobID Last; // ending blob id, also included
- bool ErrorMode = false;
- bool LostMode = false;
-
- static TEvVMockCtlRequest *CreateDeleteBlobsRequest(const TLogoBlobID& first, const TLogoBlobID& last) {
- TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::DeleteBlobs);
- request->First = first;
- request->Last = last;
- return request;
- }
-
- static TEvVMockCtlRequest *CreateErrorModeRequest(bool errorMode, bool lostMode = false) {
- TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::SetErrorMode);
- request->ErrorMode = errorMode;
- request->LostMode = lostMode;
- return request;
- }
-
- static TEvVMockCtlRequest *CreateWipeOutBlobsRequest(const TLogoBlobID& first, const TLogoBlobID& last) {
- TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::WipeOutBlobs);
- request->First = first;
- request->Last = last;
- return request;
- }
-
-private:
- TEvVMockCtlRequest(EAction action)
- : Action(action)
- {}
-};
-
-struct TEvVMockCtlResponse : public TEventLocal<TEvVMockCtlResponse, TEvBlobStorage::EvVMockCtlResponse> {
-};
-
-struct TVDiskMockSharedState : public TThrRefBase {
- const TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
- TMutex Mutex;
+
+#include <util/system/mutex.h>
+
+namespace NKikimr {
+
+struct TEvVMockCtlRequest : public TEventLocal<TEvVMockCtlRequest, TEvBlobStorage::EvVMockCtlRequest> {
+ enum class EAction {
+ DeleteBlobs,
+ SetErrorMode,
+ WipeOutBlobs,
+ };
+
+ EAction Action;
+ TLogoBlobID First; // starting blob id
+ TLogoBlobID Last; // ending blob id, also included
+ bool ErrorMode = false;
+ bool LostMode = false;
+
+ static TEvVMockCtlRequest *CreateDeleteBlobsRequest(const TLogoBlobID& first, const TLogoBlobID& last) {
+ TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::DeleteBlobs);
+ request->First = first;
+ request->Last = last;
+ return request;
+ }
+
+ static TEvVMockCtlRequest *CreateErrorModeRequest(bool errorMode, bool lostMode = false) {
+ TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::SetErrorMode);
+ request->ErrorMode = errorMode;
+ request->LostMode = lostMode;
+ return request;
+ }
+
+ static TEvVMockCtlRequest *CreateWipeOutBlobsRequest(const TLogoBlobID& first, const TLogoBlobID& last) {
+ TEvVMockCtlRequest *request = new TEvVMockCtlRequest(EAction::WipeOutBlobs);
+ request->First = first;
+ request->Last = last;
+ return request;
+ }
+
+private:
+ TEvVMockCtlRequest(EAction action)
+ : Action(action)
+ {}
+};
+
+struct TEvVMockCtlResponse : public TEventLocal<TEvVMockCtlResponse, TEvBlobStorage::EvVMockCtlResponse> {
+};
+
+struct TVDiskMockSharedState : public TThrRefBase {
+ const TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
+ TMutex Mutex;
THashMap<TLogoBlobID, TIngress> BlobToIngressMap;
-
- TVDiskMockSharedState(TIntrusivePtr<TBlobStorageGroupInfo> groupInfo)
- : GroupInfo(std::move(groupInfo))
- {}
-
- TVDiskMockSharedState(const TVDiskMockSharedState& other) = delete;
-};
-
+
+ TVDiskMockSharedState(TIntrusivePtr<TBlobStorageGroupInfo> groupInfo)
+ : GroupInfo(std::move(groupInfo))
+ {}
+
+ TVDiskMockSharedState(const TVDiskMockSharedState& other) = delete;
+};
+
extern NActors::IActor *CreateVDiskMockActor(const TVDiskID& vdiskId,
TIntrusivePtr<TVDiskMockSharedState> shared,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top);
-
-} // NKikimr
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/ut_vdisk/lib/ya.make b/ydb/core/blobstorage/ut_vdisk/lib/ya.make
index c704427fd60..92ad00b49f7 100644
--- a/ydb/core/blobstorage/ut_vdisk/lib/ya.make
+++ b/ydb/core/blobstorage/ut_vdisk/lib/ya.make
@@ -44,8 +44,8 @@ SRCS(
test_simplebs.h
test_synclog.cpp
test_synclog.h
- vdisk_mock.cpp
- vdisk_mock.h
+ vdisk_mock.cpp
+ vdisk_mock.h
)
PEERDIR(
diff --git a/ydb/core/blobstorage/ut_vdisk/mon_reregister_ut.cpp b/ydb/core/blobstorage/ut_vdisk/mon_reregister_ut.cpp
index 36a2eca81f8..3337d4c4f05 100644
--- a/ydb/core/blobstorage/ut_vdisk/mon_reregister_ut.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/mon_reregister_ut.cpp
@@ -86,7 +86,7 @@ Y_UNIT_TEST_SUITE(TMonitoring) {
// TMyTest
////////////////////////////////////////////////////////////////////
class TMyTest : public TActorBootstrapped<TMyTest> {
- std::shared_ptr<TTestWithActorSystem> Env;
+ std::shared_ptr<TTestWithActorSystem> Env;
TActorId WorkerId;
friend class TActorBootstrapped<TMyTest>;
@@ -128,7 +128,7 @@ Y_UNIT_TEST_SUITE(TMonitoring) {
}
public:
- TMyTest(std::shared_ptr<TTestWithActorSystem> env)
+ TMyTest(std::shared_ptr<TTestWithActorSystem> env)
: TActorBootstrapped<TThis>()
, Env(env)
{}
@@ -138,7 +138,7 @@ Y_UNIT_TEST_SUITE(TMonitoring) {
// Unit test
////////////////////////////////////////////////////////////////////
Y_UNIT_TEST(ReregisterTest) {
- std::shared_ptr<TTestWithActorSystem> test(new TTestWithActorSystem(0));
+ std::shared_ptr<TTestWithActorSystem> test(new TTestWithActorSystem(0));
test->Run(new TMyTest(test));
}
}
diff --git a/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp b/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp
index 694828c9f8c..7e8ff81115e 100644
--- a/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp
+++ b/ydb/core/blobstorage/ut_vdisk/vdisk_test.cpp
@@ -106,7 +106,7 @@ Y_UNIT_TEST_SUITE(TBsVDiskExtreme) {
Y_UNIT_TEST_COMP_DISK(Simple3Put1GetMissingKeyFresh, TSimple3Put1GetMissingKey, TFastVDiskSetup, false, 0, DG_3PUT)
Y_UNIT_TEST_COMP_DISK(Simple3Put1GetMissingKeyCompaction, TSimple3Put1GetMissingKey, TFastVDiskSetupCompacted, true, 0, DG_3PUT)
-
+
Y_UNIT_TEST_COMP_DISK(Simple3Put1GetMissingPartFresh, TSimple3Put1GetMissingPart, TFastVDiskSetup, false, 0, DG_3PUT)
Y_UNIT_TEST_COMP_DISK(Simple3Put1GetMissingPartCompaction, TSimple3Put1GetMissingPart, TFastVDiskSetupCompacted, true, 0, DG_3PUT)
// TODO: Make range queries
@@ -258,17 +258,17 @@ Y_UNIT_TEST_SUITE(TBsVDiskRangeHuge) {
Y_UNIT_TEST_SUITE(TBsVDiskManyPutGetCheckSize) {
Y_UNIT_TEST(ManyPutGetCheckSize) {
- std::shared_ptr<TVector<TMsgPackInfo>> msgPacks(std::unique_ptr<TVector<TMsgPackInfo>>(new TVector<TMsgPackInfo>{
+ std::shared_ptr<TVector<TMsgPackInfo>> msgPacks(std::unique_ptr<TVector<TMsgPackInfo>>(new TVector<TMsgPackInfo>{
TMsgPackInfo(100'000, 672),
TMsgPackInfo(17'026, 1)
- }));
+ }));
TManyPutOneGet testOk(false, msgPacks, UNK, 0, 257, false);
TestRun<TManyPutOneGet, TFastVDiskSetupHndOff>(&testOk, TDuration::Minutes(100), DefChunkSize, DefDiskSize,
1, 1, NKikimr::TErasureType::ErasureNone);
- std::shared_ptr<TVector<TMsgPackInfo>> failMsgPacks(std::unique_ptr<TVector<TMsgPackInfo>>(new TVector<TMsgPackInfo>{
+ std::shared_ptr<TVector<TMsgPackInfo>> failMsgPacks(std::unique_ptr<TVector<TMsgPackInfo>>(new TVector<TMsgPackInfo>{
TMsgPackInfo(100'000, 672),
TMsgPackInfo(17'027, 1)
- }));
+ }));
TManyPutOneGet testError(false, failMsgPacks, UNK, 0, 257, true);
TestRun<TManyPutOneGet, TFastVDiskSetupHndOff>(&testError, TDuration::Minutes(100), DefChunkSize, DefDiskSize,
1, 1, NKikimr::TErasureType::ErasureNone);
@@ -469,25 +469,25 @@ Y_UNIT_TEST_SUITE(TBsLocalRecovery) {
}
Y_UNIT_TEST(WriteRestartRead) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
auto settings = TWriteRestartReadSettings::OneSetup(1000, 10, UNK, vdiskSetup);
WriteRestartRead(settings, TIMEOUT);
}
Y_UNIT_TEST(WriteRestartReadHuge) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
auto settings = TWriteRestartReadSettings::OneSetup(1000, 65u << 10u, HUGEB, vdiskSetup);
WriteRestartRead(settings, TIMEOUT);
}
Y_UNIT_TEST(MultiPutWriteRestartRead) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
auto settings = TMultiPutWriteRestartReadSettings::OneSetup(1000, 10, 10, UNK, vdiskSetup);
MultiPutWriteRestartRead(settings, TIMEOUT);
}
Y_UNIT_TEST(MultiPutWriteRestartReadHuge) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
auto settings = TMultiPutWriteRestartReadSettings::OneSetup(1000, 10, 65u << 10u, HUGEB, vdiskSetup);
MultiPutWriteRestartRead(settings, TIMEOUT);
}
@@ -519,15 +519,15 @@ Y_UNIT_TEST_SUITE(TBsLocalRecovery) {
};
Y_UNIT_TEST(SmallerHugeBlobs) {
- auto vdiskWriteSetup = std::make_shared<TWriteVDiskSetup>();
- auto vdiskReadSetup = std::make_shared <TReadVDiskSetup>();
+ auto vdiskWriteSetup = std::make_shared<TWriteVDiskSetup>();
+ auto vdiskReadSetup = std::make_shared <TReadVDiskSetup>();
TWriteRestartReadSettings settings(1000, 66u << 10u, HUGEB, vdiskWriteSetup, vdiskReadSetup);
WriteRestartRead(settings, TIMEOUT);
}
*/
Y_UNIT_TEST(ChaoticWriteRestart) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
TChaoticWriteRestartWriteSettings settings(
TWriteRestartReadSettings::OneSetup(100000, 10, UNK, vdiskSetup),
10,
@@ -538,7 +538,7 @@ Y_UNIT_TEST_SUITE(TBsLocalRecovery) {
Y_UNIT_TEST(ChaoticWriteRestartHuge) {
return; // https://st.yandex-team.ru/KIKIMR-5314
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
TChaoticWriteRestartWriteSettings settings(
TWriteRestartReadSettings::OneSetup(100000, 65u << 10u, HUGEB, vdiskSetup),
10,
@@ -548,7 +548,7 @@ Y_UNIT_TEST_SUITE(TBsLocalRecovery) {
}
Y_UNIT_TEST(ChaoticWriteRestartHugeXXX) {
- auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
+ auto vdiskSetup = std::make_shared<TFastVDiskSetup>();
TChaoticWriteRestartWriteSettings settings(
TWriteRestartReadSettings::OneSetup(300, 65u << 10u, HUGEB, vdiskSetup),
500,
@@ -564,7 +564,7 @@ Y_UNIT_TEST_SUITE(TBsLocalRecovery) {
Y_UNIT_TEST_SUITE(TBsOther1) {
Y_UNIT_TEST(PoisonPill) {
- TManyPutRangeGet2Channels test(false, true, LARGE_MSG_NUM, 100, UNK);
+ TManyPutRangeGet2Channels test(false, true, LARGE_MSG_NUM, 100, UNK);
TConfiguration Conf;
TFastVDiskSetup vdiskSetup;
Conf.Prepare(&vdiskSetup);
@@ -577,21 +577,21 @@ Y_UNIT_TEST_SUITE(TBsOther1) {
template <class TSetup>
void ChaoticParallelWriteGeneric(ui32 parallel, ui32 msgNum, ui32 msgSize,
- std::shared_ptr<IPutHandleClassGenerator> cls,
+ std::shared_ptr<IPutHandleClassGenerator> cls,
TDuration workingTime, TDuration requestTimeout) {
TConfiguration Conf;
TSetup vdiskSetup;
Conf.Prepare(&vdiskSetup);
TChaoticManyPutsTest w(parallel, msgNum, msgSize, cls, workingTime, requestTimeout);
- bool success1 = Conf.Run<TChaoticManyPutsTest>(&w, TDuration::Seconds(600));
+ bool success1 = Conf.Run<TChaoticManyPutsTest>(&w, TDuration::Seconds(600));
LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "Chaotic write done");
UNIT_ASSERT(success1);
Conf.Shutdown();
}
Y_UNIT_TEST(ChaoticParallelWrite) {
- auto cls = std::make_shared<TPutHandleClassGenerator>(UNK);
+ auto cls = std::make_shared<TPutHandleClassGenerator>(UNK);
NTestSuiteTBsOther1::ChaoticParallelWriteGeneric<TFastVDiskSetup>(
5000, 100, 10, cls, TDuration::Seconds(600), TDuration());
}
@@ -612,7 +612,7 @@ Y_UNIT_TEST_SUITE(TBsOther2) {
// and get them overflow
// vdisk must handle request in 0.1 sec or drop it, expect overload
const auto requestTimeout = TDuration::MilliSeconds(100);
- auto cls = std::make_shared<TRandomPutHandleClassGenerator>();
+ auto cls = std::make_shared<TRandomPutHandleClassGenerator>();
NTestSuiteTBsOther1::ChaoticParallelWriteGeneric<TFastVDiskSetupSmallVDiskQueues>(
5000, 100, 10, cls, TDuration::Seconds(600), requestTimeout);
}
@@ -623,7 +623,7 @@ Y_UNIT_TEST_SUITE(TBsOther2) {
///////////////////////////////////////////////////////////////////////////////////////////////////////
Y_UNIT_TEST_SUITE(TBsDbStat) {
Y_UNIT_TEST(ChaoticParallelWrite_DbStat) {
- auto cls = std::make_shared<TPutHandleClassGenerator>(UNK);
+ auto cls = std::make_shared<TPutHandleClassGenerator>(UNK);
const ui32 parallel = 50;
const ui32 msgNum = 10000;
const ui32 msgSize = 10;
@@ -711,26 +711,26 @@ Y_UNIT_TEST_SUITE(TBsVDiskRepl2) {
Y_UNIT_TEST_SUITE(TBsVDiskRepl3) {
Y_UNIT_TEST(ReplEraseDiskRestoreMultipart) {
- TSmallCommonDataSet dataSet;
- ui32 domainsNum = 4u;
- ui32 disksInDomain = 1u;
- ui32 pDisksNum = domainsNum * disksInDomain;
+ TSmallCommonDataSet dataSet;
+ ui32 domainsNum = 4u;
+ ui32 disksInDomain = 1u;
+ ui32 pDisksNum = domainsNum * disksInDomain;
TConfiguration Conf(TAllPDisksConfiguration::MkManyTmp(pDisksNum, 512u << 10u, 16ull << 30ull, "ROT"),
- domainsNum, disksInDomain);
- TFastVDiskSetup vdiskSetup;
- Conf.Prepare(&vdiskSetup);
- TTestReplDataWriteAndSyncMultipart testLoad(&dataSet);
- bool success1 = Conf.Run<TTestReplDataWriteAndSyncMultipart>(&testLoad, TIMEOUT);
- UNIT_ASSERT(success1);
- Conf.Shutdown();
- Conf.PDisks->EraseDisk(3, 678);
- Conf.Prepare(&vdiskSetup, false);
- TReadUntilSuccess testRead(&dataSet, 3, SMALL_TIMEOUT, true);
- bool success2 = Conf.Run<TReadUntilSuccess>(&testRead, TIMEOUT);
- Conf.Shutdown();
- UNIT_ASSERT(success2);
- }
-
+ domainsNum, disksInDomain);
+ TFastVDiskSetup vdiskSetup;
+ Conf.Prepare(&vdiskSetup);
+ TTestReplDataWriteAndSyncMultipart testLoad(&dataSet);
+ bool success1 = Conf.Run<TTestReplDataWriteAndSyncMultipart>(&testLoad, TIMEOUT);
+ UNIT_ASSERT(success1);
+ Conf.Shutdown();
+ Conf.PDisks->EraseDisk(3, 678);
+ Conf.Prepare(&vdiskSetup, false);
+ TReadUntilSuccess testRead(&dataSet, 3, SMALL_TIMEOUT, true);
+ bool success2 = Conf.Run<TReadUntilSuccess>(&testRead, TIMEOUT);
+ Conf.Shutdown();
+ UNIT_ASSERT(success2);
+ }
+
Y_UNIT_TEST(AnubisTest) {
// ignored
return;
@@ -789,62 +789,62 @@ Y_UNIT_TEST_SUITE(TBsVDiskRepl3) {
ui32 pDisksNum = domainsNum * disksInDomain;
TConfiguration Conf(TAllPDisksConfiguration::MkManyTmp(pDisksNum, 16u << 20u, 16ull << 30ull, "ROT"),
domainsNum, disksInDomain);
- TFastVDiskSetupRepl vdiskSetup;
- Conf.Prepare(&vdiskSetup);
-
- const ui32 erasedPDiskID = 4;
-
+ TFastVDiskSetupRepl vdiskSetup;
+ Conf.Prepare(&vdiskSetup);
+
+ const ui32 erasedPDiskID = 4;
+
TVector<NKikimr::TVDiskID> vdisks;
- for (ui32 i = 0; i < Conf.VDisks->GetSize(); ++i) {
- auto& vDisk = Conf.VDisks->Get(i);
+ for (ui32 i = 0; i < Conf.VDisks->GetSize(); ++i) {
+ auto& vDisk = Conf.VDisks->Get(i);
if (vDisk.Cfg->BaseInfo.PDiskId == erasedPDiskID) {
- vdisks.push_back(vDisk.VDiskID);
- }
- }
-
+ vdisks.push_back(vDisk.VDiskID);
+ }
+ }
+
LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "starting writer");
generator.Reset(CreateBlobGenerator(maxDataSize, maxBlobs, minBlobSize, maxBlobSize, 0, 1,
Conf.GroupInfo, vdisks));
dataSetPtr.Reset(new TGeneratedDataSet(generator));
TTestReplDataWriteAndSync testLoad(dataSetPtr.Get());
bool success1 = Conf.Run<TTestReplDataWriteAndSync>(&testLoad, TIMEOUT);
- UNIT_ASSERT(success1);
- LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "stopped writer");
- Conf.Shutdown();
-
- Conf.PDisks->EraseDisk(3, 678);
-
- Conf.Prepare(&vdiskSetup, false);
-
+ UNIT_ASSERT(success1);
+ LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "stopped writer");
+ Conf.Shutdown();
+
+ Conf.PDisks->EraseDisk(3, 678);
+
+ Conf.Prepare(&vdiskSetup, false);
+
generator.Reset(CreateBlobGenerator(maxDataSize, maxBlobs, minBlobSize, maxBlobSize, 0, 1,
Conf.GroupInfo, vdisks));
dataSetPtr.Reset(new TGeneratedDataSet(generator));
- LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "starting first read pass");
+ LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "starting first read pass");
TReadUntilSuccess testRead(dataSetPtr.Get(), 3, SMALL_TIMEOUT);
- TInstant begin = Now();
+ TInstant begin = Now();
bool success2 = Conf.Run<TReadUntilSuccess>(&testRead, TIMEOUT);
- TInstant end = Now();
- TDuration timedelta = end - begin;
- Conf.Shutdown();
- UNIT_ASSERT(success2);
-
- Conf.Prepare(&vdiskSetup, false, false); // do not run replication here, all data must already be in VDisk
-
+ TInstant end = Now();
+ TDuration timedelta = end - begin;
+ Conf.Shutdown();
+ UNIT_ASSERT(success2);
+
+ Conf.Prepare(&vdiskSetup, false, false); // do not run replication here, all data must already be in VDisk
+
generator.Reset(CreateBlobGenerator(maxDataSize, maxBlobs, minBlobSize, maxBlobSize, 0, 1,
Conf.GroupInfo, vdisks));
dataSetPtr.Reset(new TGeneratedDataSet(generator));
-
+
LOG_NOTICE_S(*Conf.ActorSystem1, NActorsServices::TEST, "first read pass w/repl took " << timedelta.ToString().data());
- LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "starting second read pass");
+ LOG_NOTICE(*Conf.ActorSystem1, NActorsServices::TEST, "starting second read pass");
TReadUntilSuccess verifyRead(dataSetPtr.Get(), 3, SMALL_TIMEOUT);
- begin = Now();
+ begin = Now();
bool success3 = Conf.Run<TReadUntilSuccess>(&verifyRead, TIMEOUT);
- end = Now();
- timedelta = end - begin;
- Conf.Shutdown();
- UNIT_ASSERT(success3);
- }
-
+ end = Now();
+ timedelta = end - begin;
+ Conf.Shutdown();
+ UNIT_ASSERT(success3);
+ }
+
Y_UNIT_TEST(SyncLogTest) {
TConfiguration Conf;
TNoVDiskSetup vdiskSetup;
diff --git a/ydb/core/blobstorage/ut_vdisk2/defs.h b/ydb/core/blobstorage/ut_vdisk2/defs.h
index 13e976d338c..6fafd87675d 100644
--- a/ydb/core/blobstorage/ut_vdisk2/defs.h
+++ b/ydb/core/blobstorage/ut_vdisk2/defs.h
@@ -1,9 +1,9 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/pdisk/mock/pdisk_mock.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_config.h>
#include <ydb/core/blobstorage/vdisk/vdisk_actor.h>
#include <ydb/core/util/testactorsys.h>
-#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/testing/unittest/registar.h>
diff --git a/ydb/core/blobstorage/ut_vdisk2/env.h b/ydb/core/blobstorage/ut_vdisk2/env.h
index 4d53effb997..40529095702 100644
--- a/ydb/core/blobstorage/ut_vdisk2/env.h
+++ b/ydb/core/blobstorage/ut_vdisk2/env.h
@@ -1,172 +1,172 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- class TTestEnv : TNonCopyable {
- std::unique_ptr<TTestActorSystem> Runtime;
- NMonitoring::TDynamicCounterPtr Counters;
- TIntrusivePtr<TVDiskConfig> VDiskConfig;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const ui32 GroupId = 0;
- const ui32 NodeId = 1;
- const ui32 PDiskId = 1;
- const ui32 VSlotId = 1;
- const ui64 PDiskGuid = 1;
- const TActorId PDiskServiceId = MakeBlobStoragePDiskID(NodeId, PDiskId);
- const TVDiskID VDiskId{GroupId, 1, 0, 0, 0};
- const TActorId VDiskServiceId = MakeBlobStorageVDiskID(NodeId, PDiskId, VSlotId);
- TIntrusivePtr<TAllVDiskKinds> AllVDiskKinds;
- TIntrusivePtr<TPDiskMockState> PDiskMockState;
- std::unordered_map<NKikimrBlobStorage::EVDiskQueueId, TActorId> QueueIds;
-
- public:
- TTestEnv(TIntrusivePtr<TPDiskMockState> state = nullptr)
- : Runtime(std::make_unique<TTestActorSystem>(1))
- , Counters(new NMonitoring::TDynamicCounters)
- , AllVDiskKinds(new TAllVDiskKinds)
- , PDiskMockState(state ? state : new TPDiskMockState(NodeId, PDiskId, PDiskGuid, (ui64)10 << 40))
- {
- SetupLogging();
- Runtime->Start();
- CreatePDisk();
- CreateVDisk();
- CreateQueues();
- }
-
- ~TTestEnv() {
- Runtime->Stop();
- }
-
- TTestActorSystem *GetRuntime() {
- return Runtime.get();
- }
-
- TIntrusivePtr<TPDiskMockState> GetPDiskMockState() {
- return PDiskMockState;
- }
-
- NKikimrBlobStorage::TEvVPutResult Put(const TLogoBlobID& id, TString buffer,
- NKikimrBlobStorage::EPutHandleClass prio = NKikimrBlobStorage::EPutHandleClass::TabletLog) {
- return ExecuteQuery<TEvBlobStorage::TEvVPutResult>(std::make_unique<TEvBlobStorage::TEvVPut>(id, buffer,
- VDiskId, false, nullptr, TInstant::Max(), prio), GetQueueId(prio));
- }
-
- NKikimrBlobStorage::TEvVGetResult Get(const TLogoBlobID& id,
- NKikimrBlobStorage::EGetHandleClass prio = NKikimrBlobStorage::EGetHandleClass::FastRead) {
- auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, TInstant::Max(), prio,
- TEvBlobStorage::TEvVGet::EFlags::None, Nothing(), {id});
- return ExecuteQuery<TEvBlobStorage::TEvVGetResult>(std::unique_ptr<IEventBase>(query.release()),
- GetQueueId(prio));
- }
-
- NKikimrBlobStorage::TEvVCollectGarbageResult Collect(ui64 tabletId, ui32 gen, ui32 counter,
- ui8 channel, std::optional<std::pair<ui32, ui32>> collect, bool hard, const TVector<TLogoBlobID>& keep,
- const TVector<TLogoBlobID>& doNotKeep) {
- return ExecuteQuery<TEvBlobStorage::TEvVCollectGarbageResult>(
- std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(tabletId, gen, counter, channel, !!collect,
- collect ? collect->first : 0, collect ? collect->second : 0, hard, keep ? &keep : nullptr,
- doNotKeep ? &doNotKeep : nullptr, VDiskId, TInstant::Max()),
- NKikimrBlobStorage::EVDiskQueueId::PutTabletLog);
- }
-
- private:
- template<typename TEvVResult>
- decltype(std::declval<TEvVResult>().Record) ExecuteQuery(std::unique_ptr<IEventBase> query,
- NKikimrBlobStorage::EVDiskQueueId queueId) {
- const TActorId& edge = Runtime->AllocateEdgeActor(NodeId);
- Runtime->Send(new IEventHandle(QueueIds.at(queueId), edge, query.release()), NodeId);
- auto ev = Runtime->WaitForEdgeActorEvent({edge});
- Runtime->DestroyActor(edge);
- auto *msg = ev->CastAsLocal<TEvVResult>();
- UNIT_ASSERT(msg);
- return msg->Record;
- }
-
- void SetupLogging() {
- Runtime->SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_ERROR);
- }
-
- void CreatePDisk() {
- Runtime->RegisterService(PDiskServiceId, Runtime->Register(CreatePDiskMockActor(PDiskMockState), NodeId));
- }
-
- void CreateVDisk() {
- // prepare group info (erasure=none, single disk)
- TVector<TActorId> vdiskIds(1, VDiskServiceId);
- Info.Reset(new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 1, 1, 1, &vdiskIds));
-
- // create vdisk config
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ class TTestEnv : TNonCopyable {
+ std::unique_ptr<TTestActorSystem> Runtime;
+ NMonitoring::TDynamicCounterPtr Counters;
+ TIntrusivePtr<TVDiskConfig> VDiskConfig;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const ui32 GroupId = 0;
+ const ui32 NodeId = 1;
+ const ui32 PDiskId = 1;
+ const ui32 VSlotId = 1;
+ const ui64 PDiskGuid = 1;
+ const TActorId PDiskServiceId = MakeBlobStoragePDiskID(NodeId, PDiskId);
+ const TVDiskID VDiskId{GroupId, 1, 0, 0, 0};
+ const TActorId VDiskServiceId = MakeBlobStorageVDiskID(NodeId, PDiskId, VSlotId);
+ TIntrusivePtr<TAllVDiskKinds> AllVDiskKinds;
+ TIntrusivePtr<TPDiskMockState> PDiskMockState;
+ std::unordered_map<NKikimrBlobStorage::EVDiskQueueId, TActorId> QueueIds;
+
+ public:
+ TTestEnv(TIntrusivePtr<TPDiskMockState> state = nullptr)
+ : Runtime(std::make_unique<TTestActorSystem>(1))
+ , Counters(new NMonitoring::TDynamicCounters)
+ , AllVDiskKinds(new TAllVDiskKinds)
+ , PDiskMockState(state ? state : new TPDiskMockState(NodeId, PDiskId, PDiskGuid, (ui64)10 << 40))
+ {
+ SetupLogging();
+ Runtime->Start();
+ CreatePDisk();
+ CreateVDisk();
+ CreateQueues();
+ }
+
+ ~TTestEnv() {
+ Runtime->Stop();
+ }
+
+ TTestActorSystem *GetRuntime() {
+ return Runtime.get();
+ }
+
+ TIntrusivePtr<TPDiskMockState> GetPDiskMockState() {
+ return PDiskMockState;
+ }
+
+ NKikimrBlobStorage::TEvVPutResult Put(const TLogoBlobID& id, TString buffer,
+ NKikimrBlobStorage::EPutHandleClass prio = NKikimrBlobStorage::EPutHandleClass::TabletLog) {
+ return ExecuteQuery<TEvBlobStorage::TEvVPutResult>(std::make_unique<TEvBlobStorage::TEvVPut>(id, buffer,
+ VDiskId, false, nullptr, TInstant::Max(), prio), GetQueueId(prio));
+ }
+
+ NKikimrBlobStorage::TEvVGetResult Get(const TLogoBlobID& id,
+ NKikimrBlobStorage::EGetHandleClass prio = NKikimrBlobStorage::EGetHandleClass::FastRead) {
+ auto query = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, TInstant::Max(), prio,
+ TEvBlobStorage::TEvVGet::EFlags::None, Nothing(), {id});
+ return ExecuteQuery<TEvBlobStorage::TEvVGetResult>(std::unique_ptr<IEventBase>(query.release()),
+ GetQueueId(prio));
+ }
+
+ NKikimrBlobStorage::TEvVCollectGarbageResult Collect(ui64 tabletId, ui32 gen, ui32 counter,
+ ui8 channel, std::optional<std::pair<ui32, ui32>> collect, bool hard, const TVector<TLogoBlobID>& keep,
+ const TVector<TLogoBlobID>& doNotKeep) {
+ return ExecuteQuery<TEvBlobStorage::TEvVCollectGarbageResult>(
+ std::make_unique<TEvBlobStorage::TEvVCollectGarbage>(tabletId, gen, counter, channel, !!collect,
+ collect ? collect->first : 0, collect ? collect->second : 0, hard, keep ? &keep : nullptr,
+ doNotKeep ? &doNotKeep : nullptr, VDiskId, TInstant::Max()),
+ NKikimrBlobStorage::EVDiskQueueId::PutTabletLog);
+ }
+
+ private:
+ template<typename TEvVResult>
+ decltype(std::declval<TEvVResult>().Record) ExecuteQuery(std::unique_ptr<IEventBase> query,
+ NKikimrBlobStorage::EVDiskQueueId queueId) {
+ const TActorId& edge = Runtime->AllocateEdgeActor(NodeId);
+ Runtime->Send(new IEventHandle(QueueIds.at(queueId), edge, query.release()), NodeId);
+ auto ev = Runtime->WaitForEdgeActorEvent({edge});
+ Runtime->DestroyActor(edge);
+ auto *msg = ev->CastAsLocal<TEvVResult>();
+ UNIT_ASSERT(msg);
+ return msg->Record;
+ }
+
+ void SetupLogging() {
+ Runtime->SetLogPriority(NKikimrServices::BS_PDISK, NLog::PRI_ERROR);
+ }
+
+ void CreatePDisk() {
+ Runtime->RegisterService(PDiskServiceId, Runtime->Register(CreatePDiskMockActor(PDiskMockState), NodeId));
+ }
+
+ void CreateVDisk() {
+ // prepare group info (erasure=none, single disk)
+ TVector<TActorId> vdiskIds(1, VDiskServiceId);
+ Info.Reset(new TBlobStorageGroupInfo(TBlobStorageGroupType::ErasureNone, 1, 1, 1, &vdiskIds));
+
+ // create vdisk config
TVDiskConfig::TBaseInfo baseInfo(VDiskId, PDiskServiceId, PDiskGuid, PDiskId,
- TPDiskCategory::DEVICE_TYPE_SSD, VSlotId, NKikimrBlobStorage::TVDiskKind::Default, 1,
- "static");
- VDiskConfig = AllVDiskKinds->MakeVDiskConfig(baseInfo);
-
- // create and register actor
- std::unique_ptr<IActor> vdisk(NKikimr::CreateVDisk(VDiskConfig, Info, Counters->GetSubgroup("subsystem", "vdisk")));
- Runtime->RegisterService(VDiskServiceId, Runtime->Register(vdisk.release(), NodeId));
- }
-
- void CreateQueues() {
- using E = NKikimrBlobStorage::EVDiskQueueId;
- for (const auto& queueId : {E::PutTabletLog, E::PutAsyncBlob, E::PutUserData, E::GetAsyncRead, E::GetFastRead,
- E::GetDiscover, E::GetLowRead}) {
- QueueIds.emplace(queueId, CreateQueue(queueId));
- }
- }
-
- static NKikimrBlobStorage::EVDiskQueueId GetQueueId(NKikimrBlobStorage::EPutHandleClass prio) {
- switch (prio) {
- case NKikimrBlobStorage::EPutHandleClass::TabletLog:
- return NKikimrBlobStorage::EVDiskQueueId::PutTabletLog;
-
- case NKikimrBlobStorage::EPutHandleClass::AsyncBlob:
- return NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob;
-
- case NKikimrBlobStorage::EPutHandleClass::UserData:
- return NKikimrBlobStorage::EVDiskQueueId::PutUserData;
- }
- }
-
- static NKikimrBlobStorage::EVDiskQueueId GetQueueId(NKikimrBlobStorage::EGetHandleClass prio) {
- switch (prio) {
- case NKikimrBlobStorage::EGetHandleClass::AsyncRead:
- return NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead;
-
- case NKikimrBlobStorage::EGetHandleClass::FastRead:
- return NKikimrBlobStorage::EVDiskQueueId::GetFastRead;
-
- case NKikimrBlobStorage::EGetHandleClass::Discover:
- return NKikimrBlobStorage::EVDiskQueueId::GetDiscover;
-
- case NKikimrBlobStorage::EGetHandleClass::LowRead:
- return NKikimrBlobStorage::EVDiskQueueId::GetLowRead;
- }
- }
-
- TActorId CreateQueue(NKikimrBlobStorage::EVDiskQueueId queueId) {
- const TString& name = NKikimrBlobStorage::EVDiskQueueId_Name(queueId);
- auto counters = Counters->GetSubgroup("queue", name);
- auto bspctx = MakeIntrusive<TBSProxyContext>(counters->GetSubgroup("subsystem", "bsp"));
- auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
- std::unique_ptr<IActor> actor(CreateVDiskBackpressureClient(Info, VDiskId, queueId,
- counters->GetSubgroup("subsystem", "queue"), bspctx,
- NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, NodeId), name, 0, false,
- TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
- const TActorId& edge = Runtime->AllocateEdgeActor(NodeId);
- const TActorId& actorId = Runtime->Register(actor.release(), edge, {}, {}, NodeId);
- for (;;) {
- auto ev = Runtime->WaitForEdgeActorEvent({edge});
- auto *msg = ev->CastAsLocal<TEvProxyQueueState>();
- UNIT_ASSERT(msg);
- if (msg->IsConnected) {
- Runtime->DestroyActor(edge);
- break;
- }
- }
- return actorId;
- }
- };
-
-} // NKikimr
+ TPDiskCategory::DEVICE_TYPE_SSD, VSlotId, NKikimrBlobStorage::TVDiskKind::Default, 1,
+ "static");
+ VDiskConfig = AllVDiskKinds->MakeVDiskConfig(baseInfo);
+
+ // create and register actor
+ std::unique_ptr<IActor> vdisk(NKikimr::CreateVDisk(VDiskConfig, Info, Counters->GetSubgroup("subsystem", "vdisk")));
+ Runtime->RegisterService(VDiskServiceId, Runtime->Register(vdisk.release(), NodeId));
+ }
+
+ void CreateQueues() {
+ using E = NKikimrBlobStorage::EVDiskQueueId;
+ for (const auto& queueId : {E::PutTabletLog, E::PutAsyncBlob, E::PutUserData, E::GetAsyncRead, E::GetFastRead,
+ E::GetDiscover, E::GetLowRead}) {
+ QueueIds.emplace(queueId, CreateQueue(queueId));
+ }
+ }
+
+ static NKikimrBlobStorage::EVDiskQueueId GetQueueId(NKikimrBlobStorage::EPutHandleClass prio) {
+ switch (prio) {
+ case NKikimrBlobStorage::EPutHandleClass::TabletLog:
+ return NKikimrBlobStorage::EVDiskQueueId::PutTabletLog;
+
+ case NKikimrBlobStorage::EPutHandleClass::AsyncBlob:
+ return NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob;
+
+ case NKikimrBlobStorage::EPutHandleClass::UserData:
+ return NKikimrBlobStorage::EVDiskQueueId::PutUserData;
+ }
+ }
+
+ static NKikimrBlobStorage::EVDiskQueueId GetQueueId(NKikimrBlobStorage::EGetHandleClass prio) {
+ switch (prio) {
+ case NKikimrBlobStorage::EGetHandleClass::AsyncRead:
+ return NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead;
+
+ case NKikimrBlobStorage::EGetHandleClass::FastRead:
+ return NKikimrBlobStorage::EVDiskQueueId::GetFastRead;
+
+ case NKikimrBlobStorage::EGetHandleClass::Discover:
+ return NKikimrBlobStorage::EVDiskQueueId::GetDiscover;
+
+ case NKikimrBlobStorage::EGetHandleClass::LowRead:
+ return NKikimrBlobStorage::EVDiskQueueId::GetLowRead;
+ }
+ }
+
+ TActorId CreateQueue(NKikimrBlobStorage::EVDiskQueueId queueId) {
+ const TString& name = NKikimrBlobStorage::EVDiskQueueId_Name(queueId);
+ auto counters = Counters->GetSubgroup("queue", name);
+ auto bspctx = MakeIntrusive<TBSProxyContext>(counters->GetSubgroup("subsystem", "bsp"));
+ auto flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
+ std::unique_ptr<IActor> actor(CreateVDiskBackpressureClient(Info, VDiskId, queueId,
+ counters->GetSubgroup("subsystem", "queue"), bspctx,
+ NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::DSProxy, NodeId), name, 0, false,
+ TDuration::Seconds(60), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
+ const TActorId& edge = Runtime->AllocateEdgeActor(NodeId);
+ const TActorId& actorId = Runtime->Register(actor.release(), edge, {}, {}, NodeId);
+ for (;;) {
+ auto ev = Runtime->WaitForEdgeActorEvent({edge});
+ auto *msg = ev->CastAsLocal<TEvProxyQueueState>();
+ UNIT_ASSERT(msg);
+ if (msg->IsConnected) {
+ Runtime->DestroyActor(edge);
+ break;
+ }
+ }
+ return actorId;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/ut_vdisk2/huge.cpp b/ydb/core/blobstorage/ut_vdisk2/huge.cpp
index f171301a0d1..ce3d47a39da 100644
--- a/ydb/core/blobstorage/ut_vdisk2/huge.cpp
+++ b/ydb/core/blobstorage/ut_vdisk2/huge.cpp
@@ -1,138 +1,138 @@
-#include "env.h"
-
-using namespace NKikimr;
-
-Y_UNIT_TEST_SUITE(VDiskTest) {
-
- Y_UNIT_TEST(HugeBlobWrite) {
- const TInstant started = TInstant::Now();
- const TInstant end = started + TDuration::Seconds(FromString<int>(GetEnv("TIMEOUT", "590")));
- const bool doValidate = FromString<int>(GetEnv("VALIDATE", "1"));
- SetRandomSeed(FromString<int>(GetEnv("SEED", "1")));
- std::optional<TTestEnv> env(std::in_place);
-
- char value = 1;
- std::vector<TString> blobValues;
- for (const ui32 size : {10, 1024, 576 * 1024, 1024 * 1024, 1536 * 1024}) {
- for (ui32 i = 0; i < 10; ++i) {
- TString data = TString::Uninitialized(size);
- memset(data.Detach(), value++, data.size());
- blobValues.push_back(data);
- }
- }
-
- std::map<TLogoBlobID, TString*> content;
-
- auto validate = [&] {
- for (const auto& [id, datap] : content) {
- auto res = env->Get(id);
- UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(res.ResultSize(), 1);
- const auto& value = res.GetResult(0);
- UNIT_ASSERT_VALUES_EQUAL(value.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(value.GetBuffer(), *datap);
- }
- };
-
- std::vector<ui64> tabletIds;
- for (ui32 i = 0; i < 100; ++i) {
- tabletIds.push_back(i + 1);
- }
-
- struct TTabletContext {
- std::pair<ui32, ui32> Barrier;
- std::pair<ui32, ui32> IssuedBarrier;
- TVector<TLogoBlobID> Keep;
- TVector<TLogoBlobID> DoNotKeep;
- ui32 GarbageCounter = 0;
- ui32 Gen = 1, Step = 1;
- };
- std::unordered_map<ui64, TTabletContext> tablets;
-
- ui64 maxTotalSize = (ui64)32 << 30;
- ui64 minTotalSize = (ui64)4 << 30;
- ui64 totalSize = 0;
- ui8 channel = 0;
-
- while (TInstant::Now() < end) {
- const ui64 tabletId = tabletIds[RandomNumber(tabletIds.size())];
- TTabletContext& tablet = tablets[tabletId];
-
- TString& data = blobValues[RandomNumber(blobValues.size())];
- TLogoBlobID id(tabletId, tablet.Gen, tablet.Step++, channel, data.size(), 0, 1);
-
- auto res = env->Put(id, data);
- UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
- Cerr << "Put id# " << id << " totalSize# " << totalSize << Endl;
-
- content.emplace(id, &data);
- totalSize += data.size();
-
- if (totalSize > maxTotalSize || (totalSize >= minTotalSize && RandomNumber(1000u) < 3)) {
- std::vector<TLogoBlobID> options;
- options.reserve(content.size());
- for (const auto& [id, datap] : content) {
- options.push_back(id);
- }
-
- const ui64 aim = RandomNumber(totalSize);
- while (totalSize > aim && !options.empty()) {
- size_t index = RandomNumber(options.size());
- TLogoBlobID& id = options[index];
- const auto& genstep = std::make_pair(id.Generation(), id.Step());
-
- content.erase(id);
- totalSize -= id.BlobSize();
-
- TTabletContext& tablet = tablets[id.TabletID()];
- tablet.Barrier = std::max(tablet.Barrier, genstep);
- if (genstep <= tablet.IssuedBarrier) {
- tablet.DoNotKeep.push_back(id.FullID());
- }
-
- std::swap(id, options.back());
- options.pop_back();
- }
- for (const auto& [id, datap] : content) {
- const auto& genstep = std::make_pair(id.Generation(), id.Step());
- TTabletContext& tablet = tablets[id.TabletID()];
- if (tablet.IssuedBarrier < genstep && genstep <= tablet.Barrier) {
- tablet.Keep.push_back(id.FullID());
- }
- }
-
- for (auto& [tabletId, tablet] : tablets) {
- if (tablet.Barrier != tablet.IssuedBarrier || !tablet.DoNotKeep.empty()) {
- auto res = env->Collect(tabletId, tablet.Gen, ++tablet.GarbageCounter, channel, tablet.Barrier,
- false, std::exchange(tablet.Keep, {}), std::exchange(tablet.DoNotKeep, {}));
- UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
- tablet.IssuedBarrier = tablet.Barrier;
- } else {
- UNIT_ASSERT(tablet.Keep.empty());
- }
- }
- Cerr << "CollectGarbage content.size# " << content.size() << " totalSize# " << totalSize << Endl;
- }
-
- if (RandomNumber(1000u) < 150) {
- Cerr << "Trim" << Endl;
- const TActorId& edge = env->GetRuntime()->AllocateEdgeActor(1);
- env->GetRuntime()->WrapInActorContext(edge, [&] {
- env->GetPDiskMockState()->TrimQuery();
- });
- env->GetRuntime()->DestroyActor(edge);
- }
-
- if (RandomNumber(1000u) < 50) {
- Cerr << "Restart" << Endl;
- ui32 numEventsToSim = RandomNumber(50u);
- env->GetRuntime()->Sim([&] { return numEventsToSim--; });
- env.emplace(env->GetPDiskMockState());
- if (doValidate) {
- validate();
- }
- }
- }
- }
-
-}
+#include "env.h"
+
+using namespace NKikimr;
+
+Y_UNIT_TEST_SUITE(VDiskTest) {
+
+ Y_UNIT_TEST(HugeBlobWrite) {
+ const TInstant started = TInstant::Now();
+ const TInstant end = started + TDuration::Seconds(FromString<int>(GetEnv("TIMEOUT", "590")));
+ const bool doValidate = FromString<int>(GetEnv("VALIDATE", "1"));
+ SetRandomSeed(FromString<int>(GetEnv("SEED", "1")));
+ std::optional<TTestEnv> env(std::in_place);
+
+ char value = 1;
+ std::vector<TString> blobValues;
+ for (const ui32 size : {10, 1024, 576 * 1024, 1024 * 1024, 1536 * 1024}) {
+ for (ui32 i = 0; i < 10; ++i) {
+ TString data = TString::Uninitialized(size);
+ memset(data.Detach(), value++, data.size());
+ blobValues.push_back(data);
+ }
+ }
+
+ std::map<TLogoBlobID, TString*> content;
+
+ auto validate = [&] {
+ for (const auto& [id, datap] : content) {
+ auto res = env->Get(id);
+ UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(res.ResultSize(), 1);
+ const auto& value = res.GetResult(0);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(value.GetBuffer(), *datap);
+ }
+ };
+
+ std::vector<ui64> tabletIds;
+ for (ui32 i = 0; i < 100; ++i) {
+ tabletIds.push_back(i + 1);
+ }
+
+ struct TTabletContext {
+ std::pair<ui32, ui32> Barrier;
+ std::pair<ui32, ui32> IssuedBarrier;
+ TVector<TLogoBlobID> Keep;
+ TVector<TLogoBlobID> DoNotKeep;
+ ui32 GarbageCounter = 0;
+ ui32 Gen = 1, Step = 1;
+ };
+ std::unordered_map<ui64, TTabletContext> tablets;
+
+ ui64 maxTotalSize = (ui64)32 << 30;
+ ui64 minTotalSize = (ui64)4 << 30;
+ ui64 totalSize = 0;
+ ui8 channel = 0;
+
+ while (TInstant::Now() < end) {
+ const ui64 tabletId = tabletIds[RandomNumber(tabletIds.size())];
+ TTabletContext& tablet = tablets[tabletId];
+
+ TString& data = blobValues[RandomNumber(blobValues.size())];
+ TLogoBlobID id(tabletId, tablet.Gen, tablet.Step++, channel, data.size(), 0, 1);
+
+ auto res = env->Put(id, data);
+ UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
+ Cerr << "Put id# " << id << " totalSize# " << totalSize << Endl;
+
+ content.emplace(id, &data);
+ totalSize += data.size();
+
+ if (totalSize > maxTotalSize || (totalSize >= minTotalSize && RandomNumber(1000u) < 3)) {
+ std::vector<TLogoBlobID> options;
+ options.reserve(content.size());
+ for (const auto& [id, datap] : content) {
+ options.push_back(id);
+ }
+
+ const ui64 aim = RandomNumber(totalSize);
+ while (totalSize > aim && !options.empty()) {
+ size_t index = RandomNumber(options.size());
+ TLogoBlobID& id = options[index];
+ const auto& genstep = std::make_pair(id.Generation(), id.Step());
+
+ content.erase(id);
+ totalSize -= id.BlobSize();
+
+ TTabletContext& tablet = tablets[id.TabletID()];
+ tablet.Barrier = std::max(tablet.Barrier, genstep);
+ if (genstep <= tablet.IssuedBarrier) {
+ tablet.DoNotKeep.push_back(id.FullID());
+ }
+
+ std::swap(id, options.back());
+ options.pop_back();
+ }
+ for (const auto& [id, datap] : content) {
+ const auto& genstep = std::make_pair(id.Generation(), id.Step());
+ TTabletContext& tablet = tablets[id.TabletID()];
+ if (tablet.IssuedBarrier < genstep && genstep <= tablet.Barrier) {
+ tablet.Keep.push_back(id.FullID());
+ }
+ }
+
+ for (auto& [tabletId, tablet] : tablets) {
+ if (tablet.Barrier != tablet.IssuedBarrier || !tablet.DoNotKeep.empty()) {
+ auto res = env->Collect(tabletId, tablet.Gen, ++tablet.GarbageCounter, channel, tablet.Barrier,
+ false, std::exchange(tablet.Keep, {}), std::exchange(tablet.DoNotKeep, {}));
+ UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
+ tablet.IssuedBarrier = tablet.Barrier;
+ } else {
+ UNIT_ASSERT(tablet.Keep.empty());
+ }
+ }
+ Cerr << "CollectGarbage content.size# " << content.size() << " totalSize# " << totalSize << Endl;
+ }
+
+ if (RandomNumber(1000u) < 150) {
+ Cerr << "Trim" << Endl;
+ const TActorId& edge = env->GetRuntime()->AllocateEdgeActor(1);
+ env->GetRuntime()->WrapInActorContext(edge, [&] {
+ env->GetPDiskMockState()->TrimQuery();
+ });
+ env->GetRuntime()->DestroyActor(edge);
+ }
+
+ if (RandomNumber(1000u) < 50) {
+ Cerr << "Restart" << Endl;
+ ui32 numEventsToSim = RandomNumber(50u);
+ env->GetRuntime()->Sim([&] { return numEventsToSim--; });
+ env.emplace(env->GetPDiskMockState());
+ if (doValidate) {
+ validate();
+ }
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/ut_vdisk2/ya.make b/ydb/core/blobstorage/ut_vdisk2/ya.make
index 58862986437..a9cf7525990 100644
--- a/ydb/core/blobstorage/ut_vdisk2/ya.make
+++ b/ydb/core/blobstorage/ut_vdisk2/ya.make
@@ -1,13 +1,13 @@
-UNITTEST()
-
+UNITTEST()
+
OWNER(alexvru)
-
+
FORK_SUBTESTS()
-
+
SIZE(MEDIUM)
-
+
TIMEOUT(600)
-
+
SRCS(
defs.h
env.h
@@ -25,4 +25,4 @@ PEERDIR(
ydb/library/yql/public/udf/service/stub
)
-END()
+END()
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis.cpp
index 2ea94df9a89..70533ad6d90 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis.cpp
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis.cpp
@@ -55,9 +55,9 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
void Bootstrap(const TActorContext &ctx) {
// prepare a list of candidates
- std::unique_ptr<IActor> finder(CreateAnubisCandidatesFinder(HullCtx, ctx.SelfID, Pos, std::move(LogoBlobsSnap),
+ std::unique_ptr<IActor> finder(CreateAnubisCandidatesFinder(HullCtx, ctx.SelfID, Pos, std::move(LogoBlobsSnap),
std::move(BarriersSnap)));
- TActorId aid = RunInBatchPool(ctx, finder.release());
+ TActorId aid = RunInBatchPool(ctx, finder.release());
ActiveActors.Insert(aid);
Become(&TThis::WaitForCandidatesStateFunc);
}
@@ -238,8 +238,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
TAnubisQuantumActor(const TIntrusivePtr<THullCtx> &hullCtx,
@@ -259,7 +259,7 @@ namespace NKikimr {
, LogoBlobsSnap(std::move(logoBlobsSnap))
, BarriersSnap(std::move(barriersSnap))
, MaxInFly(anubisOsirisMaxInFly)
- , BlobsStatusMngr(HullCtx->VCtx->Top.get())
+ , BlobsStatusMngr(HullCtx->VCtx->Top.get())
{}
};
@@ -285,10 +285,10 @@ namespace NKikimr {
friend class TActorBootstrapped<TAnubis>;
void CreateQueueActorMap(const TActorContext &ctx) {
- QueueActorMapPtr = std::make_shared<TQueueActorMap>();
+ QueueActorMapPtr = std::make_shared<TQueueActorMap>();
for (const auto &x : HullCtx->VCtx->Top->GetVDisks()) {
if (HullCtx->VCtx->ShortSelfVDisk != x.VDiskIdShort) {
- auto aid = ctx.Register(CreateAnubisProxy(HullCtx->VCtx, GInfo, x.VDiskIdShort, ReplInterconnectChannel));
+ auto aid = ctx.Register(CreateAnubisProxy(HullCtx->VCtx, GInfo, x.VDiskIdShort, ReplInterconnectChannel));
ActiveActors.Insert(aid);
(*QueueActorMapPtr)[x.VDiskIdShort] = aid;
}
@@ -304,9 +304,9 @@ namespace NKikimr {
void Handle(TEvTakeHullSnapshotResult::TPtr &ev, const TActorContext &ctx) {
Become(&TThis::QuantumStateFunc);
auto &snap = ev->Get()->Snap;
- auto a = std::make_unique<TAnubisQuantumActor>(HullCtx, QueueActorMapPtr, ctx.SelfID, SkeletonId, Pos,
+ auto a = std::make_unique<TAnubisQuantumActor>(HullCtx, QueueActorMapPtr, ctx.SelfID, SkeletonId, Pos,
std::move(snap.LogoBlobsSnap), std::move(snap.BarriersSnap), AnubisOsirisMaxInFly);
- auto aid = ctx.Register(a.release());
+ auto aid = ctx.Register(a.release());
ActiveActors.Insert(aid);
}
@@ -370,8 +370,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
TAnubis(const TIntrusivePtr<THullCtx> &hullCtx,
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis_osiris.h b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis_osiris.h
index 96eec4e4064..49e140d1de2 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis_osiris.h
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubis_osiris.h
@@ -59,7 +59,7 @@ namespace NKikimr {
if (IsAnubis()) {
Y_VERIFY(!LogoBlobId.PartId());
TIngress ingressDontKeep;
- ingressDontKeep.SetKeep(TIngress::IngressMode(top->GType), CollectModeDoNotKeep);
+ ingressDontKeep.SetKeep(TIngress::IngressMode(top->GType), CollectModeDoNotKeep);
return {LogoBlobId, ingressDontKeep};
} else {
Y_VERIFY(LogoBlobId.PartId());
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp
index a07206a22b2..cd79a76087f 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisfinder.cpp
@@ -147,8 +147,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
TAnubisCandidatesFinderActor(const TIntrusivePtr<THullCtx> &hullCtx,
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisproxy.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisproxy.cpp
index cdb854a099b..5a9d8a166b8 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisproxy.cpp
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisproxy.cpp
@@ -23,13 +23,13 @@ namespace NKikimr {
TVDiskID SelfVDiskId;
TActiveActors ActiveActors;
TActorId CliId; // backpressure client id
- std::unique_ptr<IActor> Actor; // backpressure client actor
+ std::unique_ptr<IActor> Actor; // backpressure client actor
TActorId RequestFrom;
friend class TActorBootstrapped<TAnubisProxyActor>;
void Bootstrap(const TActorContext &ctx) {
- CliId = ctx.Register(Actor.release());
+ CliId = ctx.Register(Actor.release());
ActiveActors.Insert(CliId);
Become(&TThis::StateFunc);
}
@@ -39,14 +39,14 @@ namespace NKikimr {
Y_VERIFY(RequestFrom == TActorId());
const auto eclass = NKikimrBlobStorage::EGetHandleClass::AsyncRead;
- auto msg = TEvVGet::CreateExtremeIndexQuery(TargetVDiskId, TInstant::Max(), eclass);
+ auto msg = TEvVGet::CreateExtremeIndexQuery(TargetVDiskId, TInstant::Max(), eclass);
msg->Record.SetSuppressBarrierCheck(true);
for (const auto &x : ev->Get()->Candidates) {
msg->AddExtremeQuery(x, 0, 0, nullptr);
}
- ctx.Send(CliId, msg.release());
+ ctx.Send(CliId, msg.release());
}
void Handle(TEvBlobStorage::TEvVGetResult::TPtr &ev, const TActorContext &ctx) {
@@ -58,9 +58,9 @@ namespace NKikimr {
if (status == NKikimrProto::OK && !SelfVDiskId.SameDisk(record.GetVDiskID())) {
record.SetStatus(NKikimrProto::RACE);
}
- if (status == NKikimrProto::NOTREADY) {
- record.SetStatus(NKikimrProto::ERROR);
- }
+ if (status == NKikimrProto::NOTREADY) {
+ record.SetStatus(NKikimrProto::ERROR);
+ }
// reply with result
ctx.Send(RequestFrom, new TEvAnubisVGetResult(TargetVDiskIdShort, ev));
@@ -80,8 +80,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
TAnubisProxyActor(const TIntrusivePtr<TVDiskContext> &vctx,
@@ -100,15 +100,15 @@ namespace NKikimr {
VCtx->Top->GetOrderNumber(VCtx->ShortSelfVDisk));
auto monGroup = VCtx->VDiskCounters->GetSubgroup("subsystem", "synceranubis");
TIntrusivePtr<TFlowRecord> flowRecord(new TFlowRecord);
- Actor.reset(CreateVDiskBackpressureClient(ginfo,
+ Actor.reset(CreateVDiskBackpressureClient(ginfo,
TargetVDiskIdShort,
- queueId,
+ queueId,
monGroup,
VCtx,
clientId,
"Get",
replInterconnectChannel,
- false,
+ false,
TDuration::Minutes(1),
flowRecord,
NMonitoring::TCountableBase::EVisibility::Private));
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.cpp
index f1bbfa34c64..83245eefc64 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.cpp
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.cpp
@@ -80,8 +80,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
TAnubisRunnerHttpInfoActor(
@@ -143,7 +143,7 @@ namespace NKikimr {
// 3. We retry Anubis if we got some errors from previous runs
////////////////////////////////////////////////////////////////////////////
class TAnubisRunner : public TActorBootstrapped<TAnubisRunner> {
- std::shared_ptr<TAnubisCtx> AnubisCtx;
+ std::shared_ptr<TAnubisCtx> AnubisCtx;
TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
TQuorumForAnubisTracker QuorumTracker;
TActiveActors ActiveActors;
@@ -258,29 +258,29 @@ namespace NKikimr {
// save current local state
TString s = QuorumTracker.ToString();
// create an actor to handle request
- auto actor = std::make_unique<TAnubisRunnerHttpInfoActor>(ev, ctx.SelfID, AnubisId, s);
- auto aid = ctx.Register(actor.release());
+ auto actor = std::make_unique<TAnubisRunnerHttpInfoActor>(ev, ctx.SelfID, AnubisId, s);
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_ANUBIS;
}
- TAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
+ TAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo)
: TActorBootstrapped<TAnubisRunner>()
, AnubisCtx(anubisCtx)
, GInfo(ginfo)
- , QuorumTracker(AnubisCtx->HullCtx->VCtx->Top.get())
+ , QuorumTracker(AnubisCtx->HullCtx->VCtx->Top.get())
{}
};
////////////////////////////////////////////////////////////////////////////
// ANUBIS RUNNER ACTOR CREATOR
////////////////////////////////////////////////////////////////////////////
- IActor* CreateAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
+ IActor* CreateAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo) {
return new TAnubisRunner(anubisCtx, ginfo);
}
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.h b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.h
index c2429164368..ec203ea4092 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.h
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_anubisrunner.h
@@ -62,7 +62,7 @@ namespace NKikimr {
, AnubisTimeout(anubisTimeout)
{}
};
- IActor* CreateAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
+ IActor* CreateAnubisRunner(const std::shared_ptr<TAnubisCtx> &anubisCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp
index 019c048d491..54845d0fbeb 100644
--- a/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp
+++ b/ydb/core/blobstorage/vdisk/anubis_osiris/blobstorage_osiris.cpp
@@ -43,7 +43,7 @@ namespace NKikimr {
TSaviour(const TIntrusivePtr<THullCtx> &hullCtx,
TLogoBlobsSnapshot &&snapshot,
- const std::shared_ptr<TFilter> &filter)
+ const std::shared_ptr<TFilter> &filter)
: HullCtx(hullCtx)
, Snapshot(std::move(snapshot))
, Filter(filter)
@@ -72,46 +72,46 @@ namespace NKikimr {
return CurKey;
}
- NMatrix::TVectorType GetPartsToResurrect() const {
- return PartsToResurrect;
+ NMatrix::TVectorType GetPartsToResurrect() const {
+ return PartsToResurrect;
}
private:
TIntrusivePtr<THullCtx> HullCtx;
TLogoBlobsSnapshot Snapshot;
- const std::shared_ptr<TFilter> Filter;
+ const std::shared_ptr<TFilter> Filter;
// As an iterator we position at some element, below are data extracted from this element
- TIndexForwardIterator CurIt; // current iterator we have
- TLogoBlobID CurKey; // current key we have
- TIngress CurIngress; // merged ingress we have
- NMatrix::TVectorType PartsToResurrect; // parts to resurrect we have
-
- bool ResurrectCur() {
- auto &self = HullCtx->VCtx->ShortSelfVDisk; // VDiskId we have
- const auto& topology = *HullCtx->VCtx->Top; // topology we have
- Y_VERIFY(topology.BelongsToSubgroup(self, CurKey.Hash())); // check that blob belongs to subgroup
-
- if (!Filter->Check(CurKey, CurIt.GetMemRec(), CurIt.GetMemRecsMerged(), HullCtx->AllowKeepFlags)) {
- // filter check returned false
- return false;
- }
-
- const TSubgroupPartLayout layout = TSubgroupPartLayout::CreateFromIngress(CurIngress, topology.GType);
- const ui32 idxInSubgroup = topology.GetIdxInSubgroup(self, CurKey.Hash());
- const ui32 partsMask = topology.GetQuorumChecker().GetPartsToResurrect(layout, idxInSubgroup);
- if (!partsMask) {
- return false;
- }
-
- PartsToResurrect = NMatrix::TVectorType(0, topology.GType.TotalPartCount());
- for (ui32 i = 0; i < PartsToResurrect.GetSize(); ++i) {
- if (partsMask & (1 << i)) {
- PartsToResurrect.Set(i);
- }
- }
-
- return true;
+ TIndexForwardIterator CurIt; // current iterator we have
+ TLogoBlobID CurKey; // current key we have
+ TIngress CurIngress; // merged ingress we have
+ NMatrix::TVectorType PartsToResurrect; // parts to resurrect we have
+
+ bool ResurrectCur() {
+ auto &self = HullCtx->VCtx->ShortSelfVDisk; // VDiskId we have
+ const auto& topology = *HullCtx->VCtx->Top; // topology we have
+ Y_VERIFY(topology.BelongsToSubgroup(self, CurKey.Hash())); // check that blob belongs to subgroup
+
+ if (!Filter->Check(CurKey, CurIt.GetMemRec(), CurIt.GetMemRecsMerged(), HullCtx->AllowKeepFlags)) {
+ // filter check returned false
+ return false;
+ }
+
+ const TSubgroupPartLayout layout = TSubgroupPartLayout::CreateFromIngress(CurIngress, topology.GType);
+ const ui32 idxInSubgroup = topology.GetIdxInSubgroup(self, CurKey.Hash());
+ const ui32 partsMask = topology.GetQuorumChecker().GetPartsToResurrect(layout, idxInSubgroup);
+ if (!partsMask) {
+ return false;
+ }
+
+ PartsToResurrect = NMatrix::TVectorType(0, topology.GType.TotalPartCount());
+ for (ui32 i = 0; i < PartsToResurrect.GetSize(); ++i) {
+ if (partsMask & (1 << i)) {
+ PartsToResurrect.Set(i);
+ }
+ }
+
+ return true;
}
void ScanUntilItemToResurrect() {
@@ -120,9 +120,9 @@ namespace NKikimr {
CurKey = CurIt.GetCurKey().LogoBlobID();
CurIngress = CurIt.GetMemRec().GetIngress();
- if (ResurrectCur()) {
+ if (ResurrectCur()) {
break;
- }
+ }
CurIt.Next();
}
@@ -140,7 +140,7 @@ namespace NKikimr {
const TActorId NotifyId;
const TActorId ParentId;
const TActorId SkeletonId;
- std::shared_ptr<TLogoBlobFilterForOsiris> LogoBlobFilter;
+ std::shared_ptr<TLogoBlobFilterForOsiris> LogoBlobFilter;
TSaviour<TLogoBlobFilterForOsiris> Saviour;
ui64 InFly = 0;
ui64 BlobsResurrected = 0;
@@ -169,7 +169,7 @@ namespace NKikimr {
while (Saviour.Valid() && InFly < MaxInFly) {
// find parts to resurrect
TLogoBlobID lb = Saviour.LogoBlobID();
- NMatrix::TVectorType v = Saviour.GetPartsToResurrect();
+ NMatrix::TVectorType v = Saviour.GetPartsToResurrect();
// for every part send a message to skeleton, we can send more than
// MaxInFly if we need to resurrect several parts
@@ -213,14 +213,14 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
+ STRICT_STFUNC(StateFunc,
HFunc(TEvAnubisOsirisPutResult, Handle)
- CFunc(TEvents::TSystem::PoisonPill, HandlePoison)
- )
+ CFunc(TEvents::TSystem::PoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_OSIRIS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_OSIRIS;
}
THullOsirisActor(
@@ -236,7 +236,7 @@ namespace NKikimr {
, NotifyId(notifyId)
, ParentId(parentId)
, SkeletonId(skeletonId)
- , LogoBlobFilter(std::make_shared<TLogoBlobFilterForOsiris>(HullCtx, std::move(fullSnap.BarriersSnap)))
+ , LogoBlobFilter(std::make_shared<TLogoBlobFilterForOsiris>(HullCtx, std::move(fullSnap.BarriersSnap)))
, Saviour(HullCtx, std::move(fullSnap.LogoBlobsSnap), LogoBlobFilter)
, MaxInFly(anubisOsirisMaxInFly)
{}
diff --git a/ydb/core/blobstorage/vdisk/common/align.h b/ydb/core/blobstorage/vdisk/common/align.h
index 4039e3c93ba..333d0cbbbc1 100644
--- a/ydb/core/blobstorage/vdisk/common/align.h
+++ b/ydb/core/blobstorage/vdisk/common/align.h
@@ -10,40 +10,40 @@ namespace NKikimr {
// Alignments
/////////////////////////////////////////////////////////////////////////////////////////
static inline ui32 AlignUpAppendBlockSize(ui32 val, ui32 appendBlockSize) {
- val += appendBlockSize - 1;
- return val - val % appendBlockSize;
+ val += appendBlockSize - 1;
+ return val - val % appendBlockSize;
}
- template <class T>
- static inline void AlignUpAppendBlockSize(T &buf, ui32 appendBlockSize) {
+ template <class T>
+ static inline void AlignUpAppendBlockSize(T &buf, ui32 appendBlockSize) {
ui32 bufSize = buf.Size();
ui32 expected = AlignUpAppendBlockSize(bufSize, appendBlockSize);
Y_VERIFY(expected >= bufSize);
ui32 padding = expected - bufSize;
- struct TZeroPadder {
- static void Append(TBuffer &buf, const char *zero, size_t len) {
- buf.Append(zero, len);
- }
-
- static void Append(TTrackableBuffer &buf, const char *zero, size_t len) {
- buf.Append(zero, len);
- }
-
+ struct TZeroPadder {
+ static void Append(TBuffer &buf, const char *zero, size_t len) {
+ buf.Append(zero, len);
+ }
+
+ static void Append(TTrackableBuffer &buf, const char *zero, size_t len) {
+ buf.Append(zero, len);
+ }
+
static void Append(TString &buf, const char *zero, size_t len) {
- buf.append(zero, len);
- }
-
- static void Append(TTrackableString &buf, const char *zero, size_t len) {
- buf.append(zero, len);
- }
- };
-
- static const char zero[256] = {0};
- while (size_t len = Min<size_t>(sizeof(zero), padding)) {
- TZeroPadder::Append(buf, zero, len);
- padding -= len;
- }
+ buf.append(zero, len);
+ }
+
+ static void Append(TTrackableString &buf, const char *zero, size_t len) {
+ buf.append(zero, len);
+ }
+ };
+
+ static const char zero[256] = {0};
+ while (size_t len = Min<size_t>(sizeof(zero), padding)) {
+ TZeroPadder::Append(buf, zero, len);
+ padding -= len;
+ }
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.cpp b/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.cpp
index 5f176b61b75..ee7c50f1cff 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.cpp
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.cpp
@@ -19,21 +19,21 @@ namespace NKikimr {
TLogCutterCtx LogCutterCtx;
bool WriteInProgress = false;
- ui64 HullLsnToKeep = 0;
- ui64 SyncLogLsnToKeep = 0;
- ui64 SyncerLsnToKeep = 0;
- ui64 HugeKeeperLsnToKeep = 0;
- ui64 ScrubLsnToKeep = 0;
+ ui64 HullLsnToKeep = 0;
+ ui64 SyncLogLsnToKeep = 0;
+ ui64 SyncerLsnToKeep = 0;
+ ui64 HugeKeeperLsnToKeep = 0;
+ ui64 ScrubLsnToKeep = 0;
TInstant HullLastTime;
TInstant SyncLogLastTime;
TInstant SyncerLastTime;
TInstant HugeKeeperLastTime;
- TInstant ScrubLastTime;
+ TInstant ScrubLastTime;
- TInstant LastCutTime;
+ TInstant LastCutTime;
TDeque<ui64> FreeUpToLsn;
- ui64 FreeUpToLsnLastWritten = 0;
-
+ ui64 FreeUpToLsnLastWritten = 0;
+
const TDuration FirstDuration;
const TDuration RegularDuration;
@@ -57,41 +57,41 @@ namespace NKikimr {
void Handle(TEvVDiskCutLog::TPtr &ev, const TActorContext &ctx) {
TEvVDiskCutLog *msg = ev->Get();
-
- auto update = [&](ui64 &target, TInstant &time, const char *name) {
- if (msg->LastKeepLsn < target) {
+
+ auto update = [&](ui64 &target, TInstant &time, const char *name) {
+ if (msg->LastKeepLsn < target) {
LOG_CRIT(ctx, NKikimrServices::BS_LOGCUTTER,
VDISKP(LogCutterCtx.VCtx->VDiskLogPrefix,
"Log rollback component# %s current# %" PRIu64
" new# %" PRIu64, name, target, msg->LastKeepLsn));
- } else {
- target = msg->LastKeepLsn;
- time = msg->GenerationTime;
+ } else {
+ target = msg->LastKeepLsn;
+ time = msg->GenerationTime;
LOG_DEBUG(ctx, NKikimrServices::BS_LOGCUTTER,
VDISKP(LogCutterCtx.VCtx->VDiskLogPrefix,
"UPDATED: Component# %s Hull# %" PRIu64 " SyncLog# %" PRIu64
" Syncer# %" PRIu64 " Huge# %" PRIu64 " Db# LogoBlobs Db# Barriers Db# Blocks",
name, HullLsnToKeep, SyncLogLsnToKeep, SyncerLsnToKeep, HugeKeeperLsnToKeep));
- }
- };
-
+ }
+ };
+
switch (msg->Component) {
case TEvVDiskCutLog::Hull:
- update(HullLsnToKeep, HullLastTime, "Hull");
+ update(HullLsnToKeep, HullLastTime, "Hull");
break;
case TEvVDiskCutLog::SyncLog:
- update(SyncLogLsnToKeep, SyncLogLastTime, "SyncLog");
+ update(SyncLogLsnToKeep, SyncLogLastTime, "SyncLog");
break;
case TEvVDiskCutLog::Syncer:
- update(SyncerLsnToKeep, SyncerLastTime, "Syncer");
+ update(SyncerLsnToKeep, SyncerLastTime, "Syncer");
break;
case TEvVDiskCutLog::HugeKeeper:
- update(HugeKeeperLsnToKeep, HugeKeeperLastTime, "HugeKeeper");
- break;
- case TEvVDiskCutLog::Scrub:
- update(ScrubLsnToKeep, ScrubLastTime, "Scrub");
+ update(HugeKeeperLsnToKeep, HugeKeeperLastTime, "HugeKeeper");
break;
+ case TEvVDiskCutLog::Scrub:
+ update(ScrubLsnToKeep, ScrubLastTime, "Scrub");
+ break;
default:
Y_FAIL("Unexpected case: %d", msg->Component);
}
@@ -99,11 +99,11 @@ namespace NKikimr {
Process(ctx);
}
- void Handle(NPDisk::TEvCutLog::TPtr &ev, const TActorContext &ctx) {
- FreeUpToLsn.push_back(ev->Get()->FreeUpToLsn);
- Process(ctx);
- }
-
+ void Handle(NPDisk::TEvCutLog::TPtr &ev, const TActorContext &ctx) {
+ FreeUpToLsn.push_back(ev->Get()->FreeUpToLsn);
+ Process(ctx);
+ }
+
void Timeout(const TActorContext &ctx) {
Process(ctx);
ScheduleActivity(ctx, RegularDuration);
@@ -113,21 +113,21 @@ namespace NKikimr {
if (WriteInProgress)
return;
- const ui64 curLsn = Min(HullLsnToKeep, SyncLogLsnToKeep, SyncerLsnToKeep, HugeKeeperLsnToKeep, ScrubLsnToKeep);
-
- // find the maximum of requested LSN's to free up to
- TMaybe<ui64> freeUpToLsn;
- while (FreeUpToLsn && curLsn >= FreeUpToLsn.front()) {
- freeUpToLsn = FreeUpToLsn.front();
- FreeUpToLsn.pop_front();
- }
-
- if (freeUpToLsn) {
+ const ui64 curLsn = Min(HullLsnToKeep, SyncLogLsnToKeep, SyncerLsnToKeep, HugeKeeperLsnToKeep, ScrubLsnToKeep);
+
+ // find the maximum of requested LSN's to free up to
+ TMaybe<ui64> freeUpToLsn;
+ while (FreeUpToLsn && curLsn >= FreeUpToLsn.front()) {
+ freeUpToLsn = FreeUpToLsn.front();
+ FreeUpToLsn.pop_front();
+ }
+
+ if (freeUpToLsn) {
LastCutTime = TAppData::TimeProvider->Now();
// generate clear log message
NPDisk::TCommitRecord commitRec;
- commitRec.FirstLsnToKeep = *freeUpToLsn;
+ commitRec.FirstLsnToKeep = *freeUpToLsn;
commitRec.IsStartingPoint = false;
TLsnSeg seg = LogCutterCtx.LsnMngr->AllocLsnForLocalUse();
ui8 signature = TLogSignature::SignatureHullCutLog;
@@ -135,7 +135,7 @@ namespace NKikimr {
new NPDisk::TEvLog(LogCutterCtx.PDiskCtx->Dsk->Owner,
LogCutterCtx.PDiskCtx->Dsk->OwnerRound, signature, commitRec, TString(), seg, nullptr));
WriteInProgress = true;
- FreeUpToLsnLastWritten = *freeUpToLsn;
+ FreeUpToLsnLastWritten = *freeUpToLsn;
LOG_DEBUG(ctx, NKikimrServices::BS_LOGCUTTER,
VDISKP(LogCutterCtx.VCtx->VDiskLogPrefix,
@@ -162,14 +162,14 @@ namespace NKikimr {
<< ", LastUpdate=" << ToStringLocalTimeUpToSeconds(SyncerLastTime) << "]<br>";
str << "HugeKeeper: [LsnToKeep=" << HugeKeeperLsnToKeep
<< ", LastUpdate=" << ToStringLocalTimeUpToSeconds(HugeKeeperLastTime) << "]<br>";
- str << "Scrub: [LsnToKeep=" << ScrubLsnToKeep
- << ", LastUpdate=" << ToStringLocalTimeUpToSeconds(ScrubLastTime) << "]<br>";
-
- str << "FreeUpToLsn: " << FormatList(FreeUpToLsn) << "<br>";
+ str << "Scrub: [LsnToKeep=" << ScrubLsnToKeep
+ << ", LastUpdate=" << ToStringLocalTimeUpToSeconds(ScrubLastTime) << "]<br>";
- str << "FreeUpToLsnLastWritten: [Lsn=" << FreeUpToLsnLastWritten
- << ", LastUpdate=" << ToStringLocalTimeUpToSeconds(LastCutTime) << "]<br>";
+ str << "FreeUpToLsn: " << FormatList(FreeUpToLsn) << "<br>";
+ str << "FreeUpToLsnLastWritten: [Lsn=" << FreeUpToLsnLastWritten
+ << ", LastUpdate=" << ToStringLocalTimeUpToSeconds(LastCutTime) << "]<br>";
+
str << "FirstDuration: " << FirstDuration << "<br>";
str << "RegularDuration: " << RegularDuration << "<br>";
}
@@ -185,20 +185,20 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvLogResult, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvLogResult, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
HFunc(TEvVDiskCutLog, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- CFunc(TEvents::TSystem::Wakeup, Timeout)
- )
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ CFunc(TEvents::TSystem::Wakeup, Timeout)
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_RECOVERY_LOG_CUTTER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_RECOVERY_LOG_CUTTER;
}
TRecoveryLogCutter(TLogCutterCtx &&logCutterCtx)
@@ -207,9 +207,9 @@ namespace NKikimr {
, FirstDuration(LogCutterCtx.Config->RecoveryLogCutterFirstDuration)
, RegularDuration(LogCutterCtx.Config->RecoveryLogCutterRegularDuration)
{
- if (!LogCutterCtx.Config->RunSyncer || LogCutterCtx.Config->BaseInfo.DonorMode) {
- SyncerLsnToKeep = Max<ui64>();
- }
+ if (!LogCutterCtx.Config->RunSyncer || LogCutterCtx.Config->BaseInfo.DonorMode) {
+ SyncerLsnToKeep = Max<ui64>();
+ }
}
};
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.h b/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.h
index b98c5061259..b026192afd1 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.h
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_dblogcutter.h
@@ -19,7 +19,7 @@ namespace NKikimr {
SyncLog,
Syncer,
HugeKeeper,
- Scrub,
+ Scrub,
Max
};
const EComp Component;
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.cpp b/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.cpp
index ee912aff02e..647fdb4212e 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.cpp
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.cpp
@@ -1,94 +1,94 @@
-#include "blobstorage_event_filter.h"
+#include "blobstorage_event_filter.h"
#include "vdisk_events.h"
-
-namespace NKikimr {
-
- void RegisterBlobStorageEventScopes(const std::shared_ptr<TEventFilter>& filter) {
- using E = ENodeClass;
-
- static const ui32 eventsFromPeerToSystem[] = {
- TEvBlobStorage::EvVPut,
- TEvBlobStorage::EvVGet,
- TEvBlobStorage::EvVBlock,
- TEvBlobStorage::EvVGetBlock,
- TEvBlobStorage::EvVCollectGarbage,
- TEvBlobStorage::EvVGetBarrier,
- TEvBlobStorage::EvVReadyNotify,
- TEvBlobStorage::EvVStatus,
- TEvBlobStorage::EvVCheckReadiness,
- TEvBlobStorage::EvVCompact,
-
- TEvBlobStorage::EvGroupStatReport,
-
- TEvBlobStorage::EvControllerProposeGroupKey,
- TEvBlobStorage::EvControllerRegisterNode,
- TEvBlobStorage::EvControllerGetGroup,
- };
-
- static const ui32 eventsFromSystemToPeer[] = {
- TEvBlobStorage::EvVPutResult,
- TEvBlobStorage::EvVGetResult,
- TEvBlobStorage::EvVBlockResult,
- TEvBlobStorage::EvVGetBlockResult,
- TEvBlobStorage::EvVCollectGarbageResult,
- TEvBlobStorage::EvVGetBarrierResult,
- TEvBlobStorage::EvVStatusResult,
- TEvBlobStorage::EvVWindowChange,
- TEvBlobStorage::EvVCheckReadinessResult,
- TEvBlobStorage::EvVCompactResult,
- TEvBlobStorage::EvControllerNodeServiceSetUpdate,
- };
-
- static const ui32 eventsIntraSystem[] = {
- TEvBlobStorage::EvVSync,
- TEvBlobStorage::EvVSyncFull,
- TEvBlobStorage::EvVSyncGuid,
- TEvBlobStorage::EvVSyncResult,
- TEvBlobStorage::EvVSyncFullResult,
- TEvBlobStorage::EvVSyncGuidResult,
- TEvBlobStorage::EvVBaldSyncLog,
- TEvBlobStorage::EvVBaldSyncLogResult,
-
- // BS_CONTROLLER
- TEvBlobStorage::EvControllerSelectGroups,
- TEvBlobStorage::EvControllerUpdateDiskStatus,
- TEvBlobStorage::EvControllerConfigRequest,
- TEvBlobStorage::EvControllerConfigResponse,
- TEvBlobStorage::EvControllerVDiskStatusSubscribeRequest,
- TEvBlobStorage::EvControllerVDiskStatusReport,
- TEvBlobStorage::EvControllerGroupStatusRequest,
- TEvBlobStorage::EvControllerGroupStatusResponse,
- TEvBlobStorage::EvControllerUpdateGroup,
- TEvBlobStorage::EvControllerUpdateFaultyDisks,
- TEvBlobStorage::EvControllerUpdateGroupStat,
-
- TEvBlobStorage::EvControllerSelectGroupsResult,
- TEvBlobStorage::EvRequestControllerInfo,
- TEvBlobStorage::EvResponseControllerInfo,
- TEvBlobStorage::EvControllerGroupReconfigureWipe,
- TEvBlobStorage::EvControllerGroupReconfigureWipeResult,
- TEvBlobStorage::EvControllerNodeReport,
- };
-
- for (ui32 event : eventsFromPeerToSystem) {
- filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
- {E::PEER_TENANT, E::SYSTEM},
- {E::SYSTEM, E::SYSTEM}
- }));
- }
-
- for (ui32 event : eventsFromSystemToPeer) {
- filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
- {E::SYSTEM, E::PEER_TENANT},
- {E::SYSTEM, E::SYSTEM}
- }));
- }
-
- for (ui32 event : eventsIntraSystem) {
- filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
- {E::SYSTEM, E::SYSTEM}
- }));
- }
- }
-
-} // NKikimr
+
+namespace NKikimr {
+
+ void RegisterBlobStorageEventScopes(const std::shared_ptr<TEventFilter>& filter) {
+ using E = ENodeClass;
+
+ static const ui32 eventsFromPeerToSystem[] = {
+ TEvBlobStorage::EvVPut,
+ TEvBlobStorage::EvVGet,
+ TEvBlobStorage::EvVBlock,
+ TEvBlobStorage::EvVGetBlock,
+ TEvBlobStorage::EvVCollectGarbage,
+ TEvBlobStorage::EvVGetBarrier,
+ TEvBlobStorage::EvVReadyNotify,
+ TEvBlobStorage::EvVStatus,
+ TEvBlobStorage::EvVCheckReadiness,
+ TEvBlobStorage::EvVCompact,
+
+ TEvBlobStorage::EvGroupStatReport,
+
+ TEvBlobStorage::EvControllerProposeGroupKey,
+ TEvBlobStorage::EvControllerRegisterNode,
+ TEvBlobStorage::EvControllerGetGroup,
+ };
+
+ static const ui32 eventsFromSystemToPeer[] = {
+ TEvBlobStorage::EvVPutResult,
+ TEvBlobStorage::EvVGetResult,
+ TEvBlobStorage::EvVBlockResult,
+ TEvBlobStorage::EvVGetBlockResult,
+ TEvBlobStorage::EvVCollectGarbageResult,
+ TEvBlobStorage::EvVGetBarrierResult,
+ TEvBlobStorage::EvVStatusResult,
+ TEvBlobStorage::EvVWindowChange,
+ TEvBlobStorage::EvVCheckReadinessResult,
+ TEvBlobStorage::EvVCompactResult,
+ TEvBlobStorage::EvControllerNodeServiceSetUpdate,
+ };
+
+ static const ui32 eventsIntraSystem[] = {
+ TEvBlobStorage::EvVSync,
+ TEvBlobStorage::EvVSyncFull,
+ TEvBlobStorage::EvVSyncGuid,
+ TEvBlobStorage::EvVSyncResult,
+ TEvBlobStorage::EvVSyncFullResult,
+ TEvBlobStorage::EvVSyncGuidResult,
+ TEvBlobStorage::EvVBaldSyncLog,
+ TEvBlobStorage::EvVBaldSyncLogResult,
+
+ // BS_CONTROLLER
+ TEvBlobStorage::EvControllerSelectGroups,
+ TEvBlobStorage::EvControllerUpdateDiskStatus,
+ TEvBlobStorage::EvControllerConfigRequest,
+ TEvBlobStorage::EvControllerConfigResponse,
+ TEvBlobStorage::EvControllerVDiskStatusSubscribeRequest,
+ TEvBlobStorage::EvControllerVDiskStatusReport,
+ TEvBlobStorage::EvControllerGroupStatusRequest,
+ TEvBlobStorage::EvControllerGroupStatusResponse,
+ TEvBlobStorage::EvControllerUpdateGroup,
+ TEvBlobStorage::EvControllerUpdateFaultyDisks,
+ TEvBlobStorage::EvControllerUpdateGroupStat,
+
+ TEvBlobStorage::EvControllerSelectGroupsResult,
+ TEvBlobStorage::EvRequestControllerInfo,
+ TEvBlobStorage::EvResponseControllerInfo,
+ TEvBlobStorage::EvControllerGroupReconfigureWipe,
+ TEvBlobStorage::EvControllerGroupReconfigureWipeResult,
+ TEvBlobStorage::EvControllerNodeReport,
+ };
+
+ for (ui32 event : eventsFromPeerToSystem) {
+ filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
+ {E::PEER_TENANT, E::SYSTEM},
+ {E::SYSTEM, E::SYSTEM}
+ }));
+ }
+
+ for (ui32 event : eventsFromSystemToPeer) {
+ filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
+ {E::SYSTEM, E::PEER_TENANT},
+ {E::SYSTEM, E::SYSTEM}
+ }));
+ }
+
+ for (ui32 event : eventsIntraSystem) {
+ filter->RegisterEvent(event, TEventFilter::MakeRouteMask({
+ {E::SYSTEM, E::SYSTEM}
+ }));
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h b/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h
index 8f7bfd89946..930ecadcda6 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/actors/interconnect/event_filter.h>
-
-namespace NKikimr {
-
- void RegisterBlobStorageEventScopes(const std::shared_ptr<NActors::TEventFilter>& filter);
-
-} // NKikimr
+
+namespace NKikimr {
+
+ void RegisterBlobStorageEventScopes(const std::shared_ptr<NActors::TEventFilter>& filter);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp b/ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp
index 4d770a40370..5cf716ea353 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_status.cpp
@@ -14,16 +14,16 @@ namespace NKikimr {
const TActorId SkeletonId;
const TActorId SyncerId;
const TActorId SyncLogId;
- std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
+ std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
const TVDiskID SelfVDiskId;
- const ui64 IncarnationGuid;
- const TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
+ const ui64 IncarnationGuid;
+ const TIntrusivePtr<TBlobStorageGroupInfo> GroupInfo;
TEvBlobStorage::TEvVStatus::TPtr Ev;
const TActorId NotifyId;
const TInstant Now;
- const bool ReplDone;
+ const bool ReplDone;
unsigned Counter;
- std::unique_ptr<TEvBlobStorage::TEvVStatusResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVStatusResult> Result;
friend class TActorBootstrapped<TStatusRequestHandler>;
@@ -31,18 +31,18 @@ namespace NKikimr {
// check request
const NKikimrBlobStorage::TEvVStatus &record = Ev->Get()->Record;
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::RACE, SelfVDiskId, false,
- false, IncarnationGuid);
- SetRacingGroupInfo(record, Result->Record, GroupInfo);
- LOG_DEBUG(ctx, BS_VDISK_OTHER, VDISKP(VCtx->VDiskLogPrefix, "TEvVStatusResult Request# {%s} Response# {%s}",
- SingleLineProto(record).data(), SingleLineProto(Result->Record).data()));
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie, Ev->GetChannel());
+ Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::RACE, SelfVDiskId, false,
+ false, IncarnationGuid);
+ SetRacingGroupInfo(record, Result->Record, GroupInfo);
+ LOG_DEBUG(ctx, BS_VDISK_OTHER, VDISKP(VCtx->VDiskLogPrefix, "TEvVStatusResult Request# {%s} Response# {%s}",
+ SingleLineProto(record).data(), SingleLineProto(Result->Record).data()));
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie, Ev->GetChannel());
Die(ctx);
return;
}
- Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::OK, SelfVDiskId, true, ReplDone,
- IncarnationGuid);
+ Result = std::make_unique<TEvBlobStorage::TEvVStatusResult>(NKikimrProto::OK, SelfVDiskId, true, ReplDone,
+ IncarnationGuid);
NPDisk::TStatusFlags statusFlags = VCtx->GetOutOfSpaceState().GetGlobalStatusFlags().Flags;
Result->Record.SetStatusFlags(statusFlags);
@@ -71,7 +71,7 @@ namespace NKikimr {
ctx.Send(NotifyId, new TEvents::TEvActorDied());
LOG_DEBUG(ctx, BS_VDISK_GET,
VDISKP(VCtx->VDiskLogPrefix, "TEvVStatusResult"));
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie, Ev->GetChannel());
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie, Ev->GetChannel());
Die(ctx);
}
}
@@ -81,14 +81,14 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvLocalStatusResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvLocalStatusResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_STATUS_REQUEST_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_STATUS_REQUEST_HANDLER;
}
TStatusRequestHandler(
@@ -96,10 +96,10 @@ namespace NKikimr {
const TActorId &skeletonId,
const TActorId &syncerId,
const TActorId &syncLogId,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
const TVDiskID selfVDiskId,
- const ui64 incarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
+ const ui64 incarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
TEvBlobStorage::TEvVStatus::TPtr &ev,
const TActorId &notifyId,
const TInstant &now,
@@ -111,12 +111,12 @@ namespace NKikimr {
, SyncLogId(syncLogId)
, IFaceMonGroup(ifaceMonGroup)
, SelfVDiskId(selfVDiskId)
- , IncarnationGuid(incarnationGuid)
- , GroupInfo(groupInfo)
+ , IncarnationGuid(incarnationGuid)
+ , GroupInfo(groupInfo)
, Ev(ev)
, NotifyId(notifyId)
, Now(now)
- , ReplDone(replDone)
+ , ReplDone(replDone)
, Counter(0)
{}
};
@@ -126,16 +126,16 @@ namespace NKikimr {
const TActorId &skeletonId,
const TActorId &syncerId,
const TActorId &syncLogId,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
const TVDiskID selfVDiskId,
- const ui64 incarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
+ const ui64 incarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
TEvBlobStorage::TEvVStatus::TPtr &ev,
const TActorId &notifyId,
const TInstant &now,
bool replDone) {
return new TStatusRequestHandler(vctx, skeletonId, syncerId, syncLogId, ifaceMonGroup, selfVDiskId,
- incarnationGuid, groupInfo, ev, notifyId, now, replDone);
+ incarnationGuid, groupInfo, ev, notifyId, now, replDone);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/blobstorage_status.h b/ydb/core/blobstorage/vdisk/common/blobstorage_status.h
index 413aab478ee..f528c55a308 100644
--- a/ydb/core/blobstorage/vdisk/common/blobstorage_status.h
+++ b/ydb/core/blobstorage/vdisk/common/blobstorage_status.h
@@ -22,10 +22,10 @@ namespace NKikimr {
const TActorId &skeletonId,
const TActorId &syncerId,
const TActorId &syncLogId,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
const TVDiskID selfVDiskId,
- const ui64 incarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
+ const ui64 incarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo,
TEvBlobStorage::TEvVStatus::TPtr &ev,
const TActorId &notifyId,
const TInstant &now,
diff --git a/ydb/core/blobstorage/vdisk/common/disk_part.h b/ydb/core/blobstorage/vdisk/common/disk_part.h
index f8916ba6ee8..4f3840dfc6c 100644
--- a/ydb/core/blobstorage/vdisk/common/disk_part.h
+++ b/ydb/core/blobstorage/vdisk/common/disk_part.h
@@ -12,7 +12,7 @@
// FIXME: only for TIngressCache (put it to vdisk/common)
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
#include <ydb/core/protos/blobstorage_vdisk_internal.pb.h>
-
+
namespace NKikimr {
///////////////////////////////////////////////////////////////////////////////////////
@@ -61,16 +61,16 @@ namespace NKikimr {
TDiskPart(const NKikimrVDiskData::TDiskPart& pb)
: TDiskPart(pb.GetChunkIdx(), pb.GetOffset(), pb.GetSize())
- {}
-
- explicit operator NKikimrVDiskData::TDiskPart() const {
- NKikimrVDiskData::TDiskPart proto;
- proto.SetChunkIdx(ChunkIdx);
- proto.SetOffset(Offset);
- proto.SetSize(Size);
- return proto;
- }
-
+ {}
+
+ explicit operator NKikimrVDiskData::TDiskPart() const {
+ NKikimrVDiskData::TDiskPart proto;
+ proto.SetChunkIdx(ChunkIdx);
+ proto.SetOffset(Offset);
+ proto.SetSize(Size);
+ return proto;
+ }
+
void SerializeToProto(NKikimrVDiskData::TDiskPart &pb) const {
pb.SetChunkIdx(ChunkIdx);
pb.SetOffset(Offset);
@@ -148,10 +148,10 @@ namespace NKikimr {
inline bool operator ==(const TDiskPart &x) const {
return ChunkIdx == x.ChunkIdx && Offset == x.Offset && Size == x.Size;
}
-
- inline bool operator !=(const TDiskPart &x) const {
- return ChunkIdx != x.ChunkIdx || Offset != x.Offset || Size != x.Size;
- }
+
+ inline bool operator !=(const TDiskPart &x) const {
+ return ChunkIdx != x.ChunkIdx || Offset != x.Offset || Size != x.Size;
+ }
};
#pragma pack(pop)
@@ -186,11 +186,11 @@ namespace NKikimr {
Vec.push_back(p);
}
- template<typename T>
- void Append(const T& other) {
- Vec.insert(Vec.end(), other.begin(), other.end());
- }
-
+ template<typename T>
+ void Append(const T& other) {
+ Vec.insert(Vec.end(), other.begin(), other.end());
+ }
+
void SerializeToProto(NKikimrVDiskData::TDiskPartVec &pb) const {
for (const auto &x : Vec) {
auto p = pb.AddDiskParts();
diff --git a/ydb/core/blobstorage/vdisk/common/memusage.h b/ydb/core/blobstorage/vdisk/common/memusage.h
index b045c1e3d50..14122c0f5b4 100644
--- a/ydb/core/blobstorage/vdisk/common/memusage.h
+++ b/ydb/core/blobstorage/vdisk/common/memusage.h
@@ -1,44 +1,44 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-#include <util/generic/buffer.h>
+
+#include <util/generic/buffer.h>
#include <util/generic/string.h>
-#include <util/generic/list.h>
-#include <util/generic/vector.h>
-
-namespace NKikimr {
-
- class TMemoryConsumer {
- NMonitoring::TDynamicCounters::TCounterPtr Counter;
-
- public:
- TMemoryConsumer(NMonitoring::TDynamicCounters::TCounterPtr counter)
- : Counter(std::move(counter))
- {}
-
- TMemoryConsumer(TMemoryConsumer&& other) = default;
- explicit TMemoryConsumer(const TMemoryConsumer& other) = default;
-
- void Add(size_t bytes) {
- Delta(bytes);
- }
-
- void Subtract(size_t bytes) {
- Delta(-static_cast<ssize_t>(bytes));
- }
-
- void Delta(ssize_t bytes) {
- *Counter += static_cast<i64>(bytes);
- }
+#include <util/generic/list.h>
+#include <util/generic/vector.h>
+
+namespace NKikimr {
+
+ class TMemoryConsumer {
+ NMonitoring::TDynamicCounters::TCounterPtr Counter;
+
+ public:
+ TMemoryConsumer(NMonitoring::TDynamicCounters::TCounterPtr counter)
+ : Counter(std::move(counter))
+ {}
+
+ TMemoryConsumer(TMemoryConsumer&& other) = default;
+ explicit TMemoryConsumer(const TMemoryConsumer& other) = default;
+
+ void Add(size_t bytes) {
+ Delta(bytes);
+ }
+
+ void Subtract(size_t bytes) {
+ Delta(-static_cast<ssize_t>(bytes));
+ }
+
+ void Delta(ssize_t bytes) {
+ *Counter += static_cast<i64>(bytes);
+ }
NMonitoring::TDynamicCounters::TCounterPtr GetCounter() const {
return Counter;
}
- };
-
+ };
+
class TMemoryConsumerWithDropOnDestroy : protected TMemoryConsumer {
public:
TMemoryConsumerWithDropOnDestroy(NMonitoring::TDynamicCounters::TCounterPtr counter)
@@ -75,477 +75,477 @@ namespace NKikimr {
};
template<typename TDerived>
- class TTrackableBase
- {
- TMemoryConsumer Consumer;
-#ifndef NDEBUG
- size_t LastCapacity;
-#endif
-
- size_t GetCapacity() const {
+ class TTrackableBase
+ {
+ TMemoryConsumer Consumer;
+#ifndef NDEBUG
+ size_t LastCapacity;
+#endif
+
+ size_t GetCapacity() const {
return static_cast<const TDerived&>(*this).GetCapacityImpl();
- }
-
- void CountInitialCapacity() {
- size_t capacity = GetCapacity();
-#ifndef NDEBUG
- LastCapacity = capacity;
-#endif
- Consumer.Add(capacity);
- }
-
- class TTracker
- {
- TTrackableBase& Base;
- size_t InitialCapacity;
-
- public:
- TTracker(TTrackableBase& base)
- : Base(base)
- , InitialCapacity(Base.GetCapacity())
- {
-#ifndef NDEBUG
+ }
+
+ void CountInitialCapacity() {
+ size_t capacity = GetCapacity();
+#ifndef NDEBUG
+ LastCapacity = capacity;
+#endif
+ Consumer.Add(capacity);
+ }
+
+ class TTracker
+ {
+ TTrackableBase& Base;
+ size_t InitialCapacity;
+
+ public:
+ TTracker(TTrackableBase& base)
+ : Base(base)
+ , InitialCapacity(Base.GetCapacity())
+ {
+#ifndef NDEBUG
Y_VERIFY(InitialCapacity == Base.LastCapacity, "InitialCapacity# %zu Base.LastCapacity# %zu",
- InitialCapacity, Base.LastCapacity);
-#endif
- }
-
- ~TTracker() {
- size_t capacity = Base.GetCapacity();
- ssize_t delta = capacity - InitialCapacity;
- Base.Consumer.Delta(delta);
-#ifndef NDEBUG
- Base.LastCapacity = capacity;
-#endif
- }
- };
-
- public:
- TTrackableBase(TMemoryConsumer&& consumer)
- : Consumer(std::move(consumer))
- {
- CountInitialCapacity();
- }
-
- TTrackableBase(const TTrackableBase& other)
- : Consumer(other.Consumer)
- {
- CountInitialCapacity();
- }
-
- ~TTrackableBase() {
- size_t capacity = GetCapacity();
-#ifndef NDEBUG
+ InitialCapacity, Base.LastCapacity);
+#endif
+ }
+
+ ~TTracker() {
+ size_t capacity = Base.GetCapacity();
+ ssize_t delta = capacity - InitialCapacity;
+ Base.Consumer.Delta(delta);
+#ifndef NDEBUG
+ Base.LastCapacity = capacity;
+#endif
+ }
+ };
+
+ public:
+ TTrackableBase(TMemoryConsumer&& consumer)
+ : Consumer(std::move(consumer))
+ {
+ CountInitialCapacity();
+ }
+
+ TTrackableBase(const TTrackableBase& other)
+ : Consumer(other.Consumer)
+ {
+ CountInitialCapacity();
+ }
+
+ ~TTrackableBase() {
+ size_t capacity = GetCapacity();
+#ifndef NDEBUG
Y_VERIFY(capacity == LastCapacity, "capacity# %zu LastCapacity# %zu", capacity, LastCapacity);
-#endif
- Consumer.Subtract(capacity);
- }
-
- TTrackableBase& operator =(const TTrackableBase& other) {
- Consumer = other.Consumer;
- CountInitialCapacity();
- return *this;
- }
-
- TTracker SpawnTracker() {
- return TTracker(*this);
- }
- };
-
- template<typename T>
- class THasCapitalSwapMethod {
- template<typename C>
- static std::true_type HasMethodImpl(decltype(&C::Swap)*);
- template<typename C>
- static std::false_type HasMethodImpl(...);
- public:
- static constexpr bool Value = decltype(HasMethodImpl<T>(nullptr))::value;
- };
-
- template<typename T>
- class THasSmallSwapMethod {
- template<typename C>
- static std::true_type HasMethodImpl(decltype(&C::swap)*);
- template<typename C>
- static std::false_type HasMethodImpl(...);
- public:
- static constexpr bool Value = decltype(HasMethodImpl<T>(nullptr))::value;
- };
-
-#define TRACKABLE_WRAP_METHOD(METHOD) \
- template<typename... TArgs> \
- decltype(std::declval<TBase>().METHOD(std::declval<TArgs>()...)) METHOD(TArgs&&... args) { \
+#endif
+ Consumer.Subtract(capacity);
+ }
+
+ TTrackableBase& operator =(const TTrackableBase& other) {
+ Consumer = other.Consumer;
+ CountInitialCapacity();
+ return *this;
+ }
+
+ TTracker SpawnTracker() {
+ return TTracker(*this);
+ }
+ };
+
+ template<typename T>
+ class THasCapitalSwapMethod {
+ template<typename C>
+ static std::true_type HasMethodImpl(decltype(&C::Swap)*);
+ template<typename C>
+ static std::false_type HasMethodImpl(...);
+ public:
+ static constexpr bool Value = decltype(HasMethodImpl<T>(nullptr))::value;
+ };
+
+ template<typename T>
+ class THasSmallSwapMethod {
+ template<typename C>
+ static std::true_type HasMethodImpl(decltype(&C::swap)*);
+ template<typename C>
+ static std::false_type HasMethodImpl(...);
+ public:
+ static constexpr bool Value = decltype(HasMethodImpl<T>(nullptr))::value;
+ };
+
+#define TRACKABLE_WRAP_METHOD(METHOD) \
+ template<typename... TArgs> \
+ decltype(std::declval<TBase>().METHOD(std::declval<TArgs>()...)) METHOD(TArgs&&... args) { \
auto tracker = static_cast<TDerived&>(*this).TTrackableBase<TDerived>::SpawnTracker(); \
- return TBase::METHOD(std::forward<TArgs>(args)...); \
- }
-
-#define WRAP_METHOD(METHOD, MODIFIERS) \
- template<typename... TArgs> \
- decltype(std::declval<MODIFIERS TBase>().METHOD(std::declval<TArgs>()...)) METHOD(TArgs&&... args) MODIFIERS { \
- return TBase::METHOD(std::forward<TArgs>(args)...); \
- }
-
-#define WRAP_METHOD_BOTH(METHOD) \
- WRAP_METHOD(METHOD,) \
- WRAP_METHOD(METHOD, const)
-
-#define WRAP_STL_ITERATORS() \
- WRAP_METHOD_BOTH(begin) \
- WRAP_METHOD(cbegin, const) \
- WRAP_METHOD_BOTH(end) \
- WRAP_METHOD(cend, const) \
- WRAP_METHOD_BOTH(rbegin) \
- WRAP_METHOD(crbegin, const) \
- WRAP_METHOD_BOTH(rend) \
- WRAP_METHOD(crend, const)
-
+ return TBase::METHOD(std::forward<TArgs>(args)...); \
+ }
+
+#define WRAP_METHOD(METHOD, MODIFIERS) \
+ template<typename... TArgs> \
+ decltype(std::declval<MODIFIERS TBase>().METHOD(std::declval<TArgs>()...)) METHOD(TArgs&&... args) MODIFIERS { \
+ return TBase::METHOD(std::forward<TArgs>(args)...); \
+ }
+
+#define WRAP_METHOD_BOTH(METHOD) \
+ WRAP_METHOD(METHOD,) \
+ WRAP_METHOD(METHOD, const)
+
+#define WRAP_STL_ITERATORS() \
+ WRAP_METHOD_BOTH(begin) \
+ WRAP_METHOD(cbegin, const) \
+ WRAP_METHOD_BOTH(end) \
+ WRAP_METHOD(cend, const) \
+ WRAP_METHOD_BOTH(rbegin) \
+ WRAP_METHOD(crbegin, const) \
+ WRAP_METHOD_BOTH(rend) \
+ WRAP_METHOD(crend, const)
+
template<typename TContainer, typename TDerived>
- struct TTrackerWrapperBase
- : protected TContainer
- {
- using TContainer::TContainer;
- };
-
+ struct TTrackerWrapperBase
+ : protected TContainer
+ {
+ using TContainer::TContainer;
+ };
+
template<typename TBase, typename TDerived>
- struct TTrackerWrapper;
-
- template<typename T, typename A, typename TDerived>
- struct TTrackerWrapper<TDeque<T, A>, TDerived>
- : protected TTrackerWrapperBase<TDeque<T, A>, TDerived>
- {
- using TBase = TDeque<T, A>;
- using TWrapperBase = TTrackerWrapperBase<TDeque<T, A>, TDerived>;
- using TWrapperBase::TWrapperBase;
-
- size_t GetCapacityImpl() const {
- return TBase::size() * sizeof(T);
- }
-
- // std::deque methods
- TRACKABLE_WRAP_METHOD(assign)
- TRACKABLE_WRAP_METHOD(clear)
- TRACKABLE_WRAP_METHOD(insert)
- TRACKABLE_WRAP_METHOD(emplace)
- TRACKABLE_WRAP_METHOD(erase)
- TRACKABLE_WRAP_METHOD(push_front)
- TRACKABLE_WRAP_METHOD(push_back)
- TRACKABLE_WRAP_METHOD(emplace_front)
- TRACKABLE_WRAP_METHOD(emplace_back)
- TRACKABLE_WRAP_METHOD(pop_front)
- TRACKABLE_WRAP_METHOD(pop_back)
-
- // non-modifying methods
- WRAP_METHOD(get_allocator, const)
- WRAP_METHOD_BOTH(at)
- WRAP_METHOD_BOTH(operator[])
- WRAP_METHOD_BOTH(front)
- WRAP_METHOD_BOTH(back)
- WRAP_STL_ITERATORS()
- WRAP_METHOD(empty, const)
- WRAP_METHOD(size, const)
- };
-
+ struct TTrackerWrapper;
+
template<typename T, typename A, typename TDerived>
+ struct TTrackerWrapper<TDeque<T, A>, TDerived>
+ : protected TTrackerWrapperBase<TDeque<T, A>, TDerived>
+ {
+ using TBase = TDeque<T, A>;
+ using TWrapperBase = TTrackerWrapperBase<TDeque<T, A>, TDerived>;
+ using TWrapperBase::TWrapperBase;
+
+ size_t GetCapacityImpl() const {
+ return TBase::size() * sizeof(T);
+ }
+
+ // std::deque methods
+ TRACKABLE_WRAP_METHOD(assign)
+ TRACKABLE_WRAP_METHOD(clear)
+ TRACKABLE_WRAP_METHOD(insert)
+ TRACKABLE_WRAP_METHOD(emplace)
+ TRACKABLE_WRAP_METHOD(erase)
+ TRACKABLE_WRAP_METHOD(push_front)
+ TRACKABLE_WRAP_METHOD(push_back)
+ TRACKABLE_WRAP_METHOD(emplace_front)
+ TRACKABLE_WRAP_METHOD(emplace_back)
+ TRACKABLE_WRAP_METHOD(pop_front)
+ TRACKABLE_WRAP_METHOD(pop_back)
+
+ // non-modifying methods
+ WRAP_METHOD(get_allocator, const)
+ WRAP_METHOD_BOTH(at)
+ WRAP_METHOD_BOTH(operator[])
+ WRAP_METHOD_BOTH(front)
+ WRAP_METHOD_BOTH(back)
+ WRAP_STL_ITERATORS()
+ WRAP_METHOD(empty, const)
+ WRAP_METHOD(size, const)
+ };
+
+ template<typename T, typename A, typename TDerived>
struct TTrackerWrapper<TVector<T, A>, TDerived>
: protected TTrackerWrapperBase<TVector<T, A>, TDerived>
- {
+ {
using TBase = TVector<T, A>;
using TWrapperBase = TTrackerWrapperBase<TVector<T, A>, TDerived>;
- using TWrapperBase::TWrapperBase;
-
- size_t GetCapacityImpl() const {
- return TBase::capacity() * sizeof(T);
- }
-
+ using TWrapperBase::TWrapperBase;
+
+ size_t GetCapacityImpl() const {
+ return TBase::capacity() * sizeof(T);
+ }
+
// ya-specific TVector methods
- TRACKABLE_WRAP_METHOD(crop)
-
- // std::vector methods
- TRACKABLE_WRAP_METHOD(assign)
- TRACKABLE_WRAP_METHOD(reserve)
- TRACKABLE_WRAP_METHOD(shrink_to_fit)
- TRACKABLE_WRAP_METHOD(clear)
- TRACKABLE_WRAP_METHOD(insert)
- TRACKABLE_WRAP_METHOD(emplace)
- TRACKABLE_WRAP_METHOD(erase)
- TRACKABLE_WRAP_METHOD(push_back)
- TRACKABLE_WRAP_METHOD(emplace_back)
- TRACKABLE_WRAP_METHOD(pop_back)
- TRACKABLE_WRAP_METHOD(resize)
-
- // non-modifying methods
- WRAP_METHOD(get_allocator, const)
- WRAP_METHOD_BOTH(at)
- WRAP_METHOD_BOTH(operator[])
- WRAP_METHOD_BOTH(front)
- WRAP_METHOD_BOTH(back)
- WRAP_METHOD_BOTH(data)
- WRAP_STL_ITERATORS()
- WRAP_METHOD(empty, const)
- WRAP_METHOD(size, const)
- WRAP_METHOD(max_size, const)
- WRAP_METHOD(capacity, const)
- };
-
+ TRACKABLE_WRAP_METHOD(crop)
+
+ // std::vector methods
+ TRACKABLE_WRAP_METHOD(assign)
+ TRACKABLE_WRAP_METHOD(reserve)
+ TRACKABLE_WRAP_METHOD(shrink_to_fit)
+ TRACKABLE_WRAP_METHOD(clear)
+ TRACKABLE_WRAP_METHOD(insert)
+ TRACKABLE_WRAP_METHOD(emplace)
+ TRACKABLE_WRAP_METHOD(erase)
+ TRACKABLE_WRAP_METHOD(push_back)
+ TRACKABLE_WRAP_METHOD(emplace_back)
+ TRACKABLE_WRAP_METHOD(pop_back)
+ TRACKABLE_WRAP_METHOD(resize)
+
+ // non-modifying methods
+ WRAP_METHOD(get_allocator, const)
+ WRAP_METHOD_BOTH(at)
+ WRAP_METHOD_BOTH(operator[])
+ WRAP_METHOD_BOTH(front)
+ WRAP_METHOD_BOTH(back)
+ WRAP_METHOD_BOTH(data)
+ WRAP_STL_ITERATORS()
+ WRAP_METHOD(empty, const)
+ WRAP_METHOD(size, const)
+ WRAP_METHOD(max_size, const)
+ WRAP_METHOD(capacity, const)
+ };
+
template<typename T, typename A, typename TDerived>
struct TTrackerWrapper<TList<T, A>, TDerived>
: protected TTrackerWrapperBase<TList<T, A>, TDerived>
- {
+ {
using TBase = TList<T, A>;
using TWrapperBase = TTrackerWrapperBase<TList<T, A>, TDerived>;
- using TWrapperBase::TWrapperBase;
-
- size_t GetCapacityImpl() const {
- size_t itemSize = sizeof(T) + 2 * sizeof(void *);
- itemSize = (itemSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
- return TBase::size() * itemSize;
- }
-
- TRACKABLE_WRAP_METHOD(assign)
- TRACKABLE_WRAP_METHOD(clear)
- TRACKABLE_WRAP_METHOD(insert)
- TRACKABLE_WRAP_METHOD(emplace)
- TRACKABLE_WRAP_METHOD(erase)
- TRACKABLE_WRAP_METHOD(push_back)
- TRACKABLE_WRAP_METHOD(emplace_back)
- TRACKABLE_WRAP_METHOD(pop_back)
- TRACKABLE_WRAP_METHOD(push_front)
- TRACKABLE_WRAP_METHOD(emplace_front)
- TRACKABLE_WRAP_METHOD(pop_front)
- TRACKABLE_WRAP_METHOD(resize)
- TRACKABLE_WRAP_METHOD(remove)
- TRACKABLE_WRAP_METHOD(remove_if)
- TRACKABLE_WRAP_METHOD(unique)
-
- template<typename... TArgs>
+ using TWrapperBase::TWrapperBase;
+
+ size_t GetCapacityImpl() const {
+ size_t itemSize = sizeof(T) + 2 * sizeof(void *);
+ itemSize = (itemSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+ return TBase::size() * itemSize;
+ }
+
+ TRACKABLE_WRAP_METHOD(assign)
+ TRACKABLE_WRAP_METHOD(clear)
+ TRACKABLE_WRAP_METHOD(insert)
+ TRACKABLE_WRAP_METHOD(emplace)
+ TRACKABLE_WRAP_METHOD(erase)
+ TRACKABLE_WRAP_METHOD(push_back)
+ TRACKABLE_WRAP_METHOD(emplace_back)
+ TRACKABLE_WRAP_METHOD(pop_back)
+ TRACKABLE_WRAP_METHOD(push_front)
+ TRACKABLE_WRAP_METHOD(emplace_front)
+ TRACKABLE_WRAP_METHOD(pop_front)
+ TRACKABLE_WRAP_METHOD(resize)
+ TRACKABLE_WRAP_METHOD(remove)
+ TRACKABLE_WRAP_METHOD(remove_if)
+ TRACKABLE_WRAP_METHOD(unique)
+
+ template<typename... TArgs>
void splice(typename TBase::const_iterator pos, TDerived& other, TArgs&&... args) {
auto tracker = static_cast<TDerived&>(*this).TTrackableBase<TDerived>::SpawnTracker();
auto otherTracker = other.TTrackableBase<TDerived>::SpawnTracker();
- TBase::splice(pos, other, std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
+ TBase::splice(pos, other, std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
void splice(typename TBase::const_iterator pos, TDerived&& other, TArgs&&... args) {
- splice(pos, other, std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
+ splice(pos, other, std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
void merge(TDerived& other, TArgs&&... args) {
auto tracker = static_cast<TDerived&>(*this).TTrackableBase<TDerived>::SpawnTracker();
auto otherTracker = other.TTrackableBase<TDerived>::SpawnTracker();
- TBase::merge(other, std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
+ TBase::merge(other, std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
void merge(TDerived&& other, TArgs&&... args) {
- merge(other, std::forward<TArgs>(args)...);
- }
-
- // non-size-modifying methods
- WRAP_METHOD(get_allocator, const)
- WRAP_METHOD_BOTH(front)
- WRAP_METHOD_BOTH(back)
- WRAP_STL_ITERATORS()
- WRAP_METHOD(empty, const)
- WRAP_METHOD(size, const)
- WRAP_METHOD(max_size, const)
- WRAP_METHOD(reverse,)
- WRAP_METHOD(sort,)
-
- using typename TBase::iterator;
- using typename TBase::reverse_iterator;
- using typename TBase::const_iterator;
- using typename TBase::const_reverse_iterator;
- };
-
+ merge(other, std::forward<TArgs>(args)...);
+ }
+
+ // non-size-modifying methods
+ WRAP_METHOD(get_allocator, const)
+ WRAP_METHOD_BOTH(front)
+ WRAP_METHOD_BOTH(back)
+ WRAP_STL_ITERATORS()
+ WRAP_METHOD(empty, const)
+ WRAP_METHOD(size, const)
+ WRAP_METHOD(max_size, const)
+ WRAP_METHOD(reverse,)
+ WRAP_METHOD(sort,)
+
+ using typename TBase::iterator;
+ using typename TBase::reverse_iterator;
+ using typename TBase::const_iterator;
+ using typename TBase::const_reverse_iterator;
+ };
+
template<typename TDerived>
struct TTrackerWrapper<TBuffer, TDerived>
: protected TTrackerWrapperBase<TBuffer, TDerived>
- {
- using TBase = TBuffer;
+ {
+ using TBase = TBuffer;
using TWrapperBase = TTrackerWrapperBase<TBuffer, TDerived>;
- using TWrapperBase::TWrapperBase;
-
- size_t GetCapacityImpl() const {
- return TBase::Capacity();
- }
-
- TRACKABLE_WRAP_METHOD(Assign)
- TRACKABLE_WRAP_METHOD(Append)
- TRACKABLE_WRAP_METHOD(ChopHead)
- TRACKABLE_WRAP_METHOD(Proceed)
- TRACKABLE_WRAP_METHOD(Advance)
- TRACKABLE_WRAP_METHOD(Reserve)
- TRACKABLE_WRAP_METHOD(ShrinkToFit)
- TRACKABLE_WRAP_METHOD(Resize)
- TRACKABLE_WRAP_METHOD(AlignUp)
-
- // non-capacity-modifying methods
- WRAP_METHOD(Clear,)
- WRAP_METHOD(EraseBack,)
- WRAP_METHOD_BOTH(Data)
- WRAP_METHOD_BOTH(Pos)
- WRAP_METHOD(Size, const)
- WRAP_METHOD(Empty, const)
- WRAP_METHOD(Avail, const)
- WRAP_METHOD(Capacity, const)
- WRAP_METHOD_BOTH(Begin)
- WRAP_METHOD_BOTH(End)
- };
-
+ using TWrapperBase::TWrapperBase;
+
+ size_t GetCapacityImpl() const {
+ return TBase::Capacity();
+ }
+
+ TRACKABLE_WRAP_METHOD(Assign)
+ TRACKABLE_WRAP_METHOD(Append)
+ TRACKABLE_WRAP_METHOD(ChopHead)
+ TRACKABLE_WRAP_METHOD(Proceed)
+ TRACKABLE_WRAP_METHOD(Advance)
+ TRACKABLE_WRAP_METHOD(Reserve)
+ TRACKABLE_WRAP_METHOD(ShrinkToFit)
+ TRACKABLE_WRAP_METHOD(Resize)
+ TRACKABLE_WRAP_METHOD(AlignUp)
+
+ // non-capacity-modifying methods
+ WRAP_METHOD(Clear,)
+ WRAP_METHOD(EraseBack,)
+ WRAP_METHOD_BOTH(Data)
+ WRAP_METHOD_BOTH(Pos)
+ WRAP_METHOD(Size, const)
+ WRAP_METHOD(Empty, const)
+ WRAP_METHOD(Avail, const)
+ WRAP_METHOD(Capacity, const)
+ WRAP_METHOD_BOTH(Begin)
+ WRAP_METHOD_BOTH(End)
+ };
+
template<typename TDerived>
struct TTrackerWrapper<TString, TDerived>
: protected TTrackerWrapperBase<TString, TDerived>
- {
+ {
using TBase = TString;
using TWrapperBase = TTrackerWrapperBase<TString, TDerived>;
- using TWrapperBase::TWrapperBase;
-
- size_t GetCapacityImpl() const {
- return TBase::capacity();
- }
-
- TRACKABLE_WRAP_METHOD(reserve)
- TRACKABLE_WRAP_METHOD(resize)
- TRACKABLE_WRAP_METHOD(clear)
- TRACKABLE_WRAP_METHOD(assign)
- TRACKABLE_WRAP_METHOD(AssignNoAlias)
- TRACKABLE_WRAP_METHOD(append)
- TRACKABLE_WRAP_METHOD(ReserveAndResize)
- TRACKABLE_WRAP_METHOD(push_back)
- TRACKABLE_WRAP_METHOD(prepend)
- TRACKABLE_WRAP_METHOD(insert)
- TRACKABLE_WRAP_METHOD(remove)
- TRACKABLE_WRAP_METHOD(erase)
- TRACKABLE_WRAP_METHOD(pop_back)
- TRACKABLE_WRAP_METHOD(operator +=)
- TRACKABLE_WRAP_METHOD(operator *=)
-
- // non-capacity-modifying methods
- WRAP_METHOD(off, const)
- WRAP_METHOD(IterOff, const)
- WRAP_METHOD(c_str, const)
- WRAP_METHOD(begin, const)
- WRAP_METHOD(cbegin, const)
- WRAP_METHOD(end, const)
- WRAP_METHOD(cend, const)
- WRAP_METHOD(back, const)
- WRAP_METHOD(size, const)
- WRAP_METHOD(capacity, const)
- WRAP_METHOD(is_null, const)
- WRAP_METHOD(empty, const)
+ using TWrapperBase::TWrapperBase;
+
+ size_t GetCapacityImpl() const {
+ return TBase::capacity();
+ }
+
+ TRACKABLE_WRAP_METHOD(reserve)
+ TRACKABLE_WRAP_METHOD(resize)
+ TRACKABLE_WRAP_METHOD(clear)
+ TRACKABLE_WRAP_METHOD(assign)
+ TRACKABLE_WRAP_METHOD(AssignNoAlias)
+ TRACKABLE_WRAP_METHOD(append)
+ TRACKABLE_WRAP_METHOD(ReserveAndResize)
+ TRACKABLE_WRAP_METHOD(push_back)
+ TRACKABLE_WRAP_METHOD(prepend)
+ TRACKABLE_WRAP_METHOD(insert)
+ TRACKABLE_WRAP_METHOD(remove)
+ TRACKABLE_WRAP_METHOD(erase)
+ TRACKABLE_WRAP_METHOD(pop_back)
+ TRACKABLE_WRAP_METHOD(operator +=)
+ TRACKABLE_WRAP_METHOD(operator *=)
+
+ // non-capacity-modifying methods
+ WRAP_METHOD(off, const)
+ WRAP_METHOD(IterOff, const)
+ WRAP_METHOD(c_str, const)
+ WRAP_METHOD(begin, const)
+ WRAP_METHOD(cbegin, const)
+ WRAP_METHOD(end, const)
+ WRAP_METHOD(cend, const)
+ WRAP_METHOD(back, const)
+ WRAP_METHOD(size, const)
+ WRAP_METHOD(capacity, const)
+ WRAP_METHOD(is_null, const)
+ WRAP_METHOD(empty, const)
WRAP_METHOD(data, const)
- WRAP_METHOD(compare, const)
- WRAP_METHOD(equal, const)
+ WRAP_METHOD(compare, const)
+ WRAP_METHOD(equal, const)
WRAP_METHOD(StartsWith, const)
WRAP_METHOD(EndsWith, const)
- WRAP_METHOD(at, const)
- WRAP_METHOD(operator[], const)
- WRAP_METHOD(find, const)
- WRAP_METHOD(rfind, const)
- WRAP_METHOD(Contains, const)
- WRAP_METHOD(find_first_of, const)
- WRAP_METHOD(find_first_not_of, const)
- WRAP_METHOD(find_last_of, const)
- WRAP_METHOD(copy, const)
- WRAP_METHOD(strcpy, const)
- WRAP_METHOD(substr, const)
-
+ WRAP_METHOD(at, const)
+ WRAP_METHOD(operator[], const)
+ WRAP_METHOD(find, const)
+ WRAP_METHOD(rfind, const)
+ WRAP_METHOD(Contains, const)
+ WRAP_METHOD(find_first_of, const)
+ WRAP_METHOD(find_first_not_of, const)
+ WRAP_METHOD(find_last_of, const)
+ WRAP_METHOD(copy, const)
+ WRAP_METHOD(strcpy, const)
+ WRAP_METHOD(substr, const)
+
decltype(std::declval<const TString>().data()) operator~() const {
return TBase::data();
- }
- };
-
- template<typename TBase>
- class TTrackable
- : public TTrackerWrapper<TBase, TTrackable<TBase>>
- , public TTrackableBase<TTrackable<TBase>>
- {
- public:
- template<typename... TArgs>
- TTrackable(TMemoryConsumer&& consumer, TArgs&&... args)
- : TTrackerWrapper<TBase, TTrackable<TBase>>(std::forward<TArgs>(args)...)
- , TTrackableBase<TTrackable<TBase>>(std::forward<TMemoryConsumer>(consumer))
- {}
-
- // copy constructor
- TTrackable(const TTrackable& other)
- : TTrackerWrapper<TBase, TTrackable<TBase>>(other)
- , TTrackableBase<TTrackable<TBase>>(other)
- {}
-
- // move constructor
- TTrackable(TTrackable&& other)
- : TTrackerWrapper<TBase, TTrackable<TBase>>()
- , TTrackableBase<TTrackable<TBase>>(other)
- {
- *this = std::move(other);
- }
-
- // copy assign
- TTrackable& operator =(const TTrackable& other) {
- auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- static_cast<TBase&>(*this) = other;
- return *this;
- }
-
- // move assign
- TTrackable& operator =(TTrackable&& other) {
- auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- static_cast<TBase&>(*this) = std::move(other);
- return *this;
- }
-
- // const cast operator
- const TBase& GetBaseConstRef() const {
- return *this;
- }
-
- // reset - completely free memory used by this object
- void Reset() {
- auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- TBase empty;
- DoSwap<TBase>(empty, *this);
- }
-
- void Swap(TTrackable& other) {
- auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- TBase::Swap(other);
- }
-
- void swap(TTrackable& other) {
- auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
- TBase::swap(other);
- }
- };
-
- template<typename T, typename A = typename TDeque<T>::allocator_type>
- using TTrackableDeque = TTrackable<TDeque<T, A>>;
+ }
+ };
+
+ template<typename TBase>
+ class TTrackable
+ : public TTrackerWrapper<TBase, TTrackable<TBase>>
+ , public TTrackableBase<TTrackable<TBase>>
+ {
+ public:
+ template<typename... TArgs>
+ TTrackable(TMemoryConsumer&& consumer, TArgs&&... args)
+ : TTrackerWrapper<TBase, TTrackable<TBase>>(std::forward<TArgs>(args)...)
+ , TTrackableBase<TTrackable<TBase>>(std::forward<TMemoryConsumer>(consumer))
+ {}
+
+ // copy constructor
+ TTrackable(const TTrackable& other)
+ : TTrackerWrapper<TBase, TTrackable<TBase>>(other)
+ , TTrackableBase<TTrackable<TBase>>(other)
+ {}
+
+ // move constructor
+ TTrackable(TTrackable&& other)
+ : TTrackerWrapper<TBase, TTrackable<TBase>>()
+ , TTrackableBase<TTrackable<TBase>>(other)
+ {
+ *this = std::move(other);
+ }
+
+ // copy assign
+ TTrackable& operator =(const TTrackable& other) {
+ auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ static_cast<TBase&>(*this) = other;
+ return *this;
+ }
+
+ // move assign
+ TTrackable& operator =(TTrackable&& other) {
+ auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ static_cast<TBase&>(*this) = std::move(other);
+ return *this;
+ }
+
+ // const cast operator
+ const TBase& GetBaseConstRef() const {
+ return *this;
+ }
+
+ // reset - completely free memory used by this object
+ void Reset() {
+ auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ TBase empty;
+ DoSwap<TBase>(empty, *this);
+ }
+
+ void Swap(TTrackable& other) {
+ auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ TBase::Swap(other);
+ }
+
+ void swap(TTrackable& other) {
+ auto tracker = TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ auto otherTracker = other.TTrackableBase<TTrackable<TBase>>::SpawnTracker();
+ TBase::swap(other);
+ }
+ };
+
+ template<typename T, typename A = typename TDeque<T>::allocator_type>
+ using TTrackableDeque = TTrackable<TDeque<T, A>>;
template<typename T, typename A = typename TVector<T>::allocator_type>
using TTrackableVector = TTrackable<TVector<T, A>>;
template<typename T, typename A = typename TList<T>::allocator_type>
using TTrackableList = TTrackable<TList<T, A>>;
- using TTrackableBuffer = TTrackable<TBuffer>;
- using TTrackableString = TTrackable<TString>;
-
-} // NKikimr
-
+ using TTrackableBuffer = TTrackable<TBuffer>;
+ using TTrackableString = TTrackable<TString>;
+
+} // NKikimr
+
template<typename TBase, std::enable_if_t<NKikimr::THasCapitalSwapMethod<TBase>::Value>* = nullptr>
-void DoSwap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
- first.Swap(second);
-}
-
+void DoSwap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
+ first.Swap(second);
+}
+
template<typename TBase, std::enable_if_t<NKikimr::THasSmallSwapMethod<TBase>::Value>* = nullptr>
-void DoSwap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
- first.swap(second);
-}
-
-namespace std {
- template<typename TBase>
- inline void swap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
- DoSwap(first, second);
- }
-} // std
+void DoSwap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
+ first.swap(second);
+}
+
+namespace std {
+ template<typename TBase>
+ inline void swap(NKikimr::TTrackable<TBase>& first, NKikimr::TTrackable<TBase>& second) {
+ DoSwap(first, second);
+ }
+} // std
diff --git a/ydb/core/blobstorage/vdisk/common/memusage_ut.cpp b/ydb/core/blobstorage/vdisk/common/memusage_ut.cpp
index 79022e4ab3d..9ba4dedaca4 100644
--- a/ydb/core/blobstorage/vdisk/common/memusage_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/common/memusage_ut.cpp
@@ -1,56 +1,56 @@
-#include "memusage.h"
+#include "memusage.h"
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NKikimr;
-
+
+using namespace NKikimr;
+
Y_UNIT_TEST_SUITE(TTrackable) {
Y_UNIT_TEST(TVector) {
- NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
- TMemoryConsumer cons(cntr);
- NMonitoring::TDynamicCounters::TCounterPtr cntr2(new NMonitoring::TCounterForPtr);
- TMemoryConsumer cons2(cntr2);
- {
- TTrackableVector<ui32> v{TMemoryConsumer(cons)};
- v.emplace_back(1);
- v.emplace_back(2);
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v.capacity());
- }
- {
- TTrackableVector<ui32> v1{TMemoryConsumer(cons), std::initializer_list<ui32>{1, 2, 3, 4, 5}};
- TTrackableVector<ui32> v2{TMemoryConsumer(cons2)};
- UNIT_ASSERT_VALUES_EQUAL(v1.size(), 5);
- UNIT_ASSERT_VALUES_EQUAL(v2.size(), 0);
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
- DoSwap(v1, v2);
- UNIT_ASSERT_VALUES_EQUAL(v1.size(), 0);
- UNIT_ASSERT_VALUES_EQUAL(v2.size(), 5);
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
- v1.swap(v2);
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
- UNIT_ASSERT_VALUES_EQUAL(v1.size(), 5);
- UNIT_ASSERT_VALUES_EQUAL(v2.size(), 0);
- }
- UNIT_ASSERT_EQUAL(*cntr, 0);
- }
-
+ NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
+ TMemoryConsumer cons(cntr);
+ NMonitoring::TDynamicCounters::TCounterPtr cntr2(new NMonitoring::TCounterForPtr);
+ TMemoryConsumer cons2(cntr2);
+ {
+ TTrackableVector<ui32> v{TMemoryConsumer(cons)};
+ v.emplace_back(1);
+ v.emplace_back(2);
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v.capacity());
+ }
+ {
+ TTrackableVector<ui32> v1{TMemoryConsumer(cons), std::initializer_list<ui32>{1, 2, 3, 4, 5}};
+ TTrackableVector<ui32> v2{TMemoryConsumer(cons2)};
+ UNIT_ASSERT_VALUES_EQUAL(v1.size(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(v2.size(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
+ DoSwap(v1, v2);
+ UNIT_ASSERT_VALUES_EQUAL(v1.size(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(v2.size(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
+ v1.swap(v2);
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), sizeof(ui32) * v1.capacity());
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr2), sizeof(ui32) * v2.capacity());
+ UNIT_ASSERT_VALUES_EQUAL(v1.size(), 5);
+ UNIT_ASSERT_VALUES_EQUAL(v2.size(), 0);
+ }
+ UNIT_ASSERT_EQUAL(*cntr, 0);
+ }
+
Y_UNIT_TEST(TList) {
- NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
- TMemoryConsumer cons(cntr);
- TTrackableList<ui32> list{TMemoryConsumer(cons)};
- list.push_back(1);
- UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), 3 * sizeof(void *));
- }
-
+ NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
+ TMemoryConsumer cons(cntr);
+ TTrackableList<ui32> list{TMemoryConsumer(cons)};
+ list.push_back(1);
+ UNIT_ASSERT_VALUES_EQUAL(static_cast<size_t>(*cntr), 3 * sizeof(void *));
+ }
+
Y_UNIT_TEST(TString) {
- NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
- TMemoryConsumer cons(cntr);
- }
-
+ NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
+ TMemoryConsumer cons(cntr);
+ }
+
Y_UNIT_TEST(TBuffer) {
- NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
- TMemoryConsumer cons(cntr);
- }
-}
+ NMonitoring::TDynamicCounters::TCounterPtr cntr(new NMonitoring::TCounterForPtr);
+ TMemoryConsumer cons(cntr);
+ }
+}
diff --git a/ydb/core/blobstorage/vdisk/common/sublog.h b/ydb/core/blobstorage/vdisk/common/sublog.h
index d9d5310682e..d9176caa7aa 100644
--- a/ydb/core/blobstorage/vdisk/common/sublog.h
+++ b/ydb/core/blobstorage/vdisk/common/sublog.h
@@ -1,11 +1,11 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/base/blobstorage.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
////////////////////////////////////////////////////////////////////////////
// TSublog
// We use TSublog for logging activities inside some class (actor).
@@ -26,7 +26,7 @@ namespace NKikimr {
IOutputStream &Log() const {
++Recs;
if (PrefixWithTime) {
- Out << TAppData::TimeProvider->Now().ToStringLocalUpToSeconds() << " ";
+ Out << TAppData::TimeProvider->Now().ToStringLocalUpToSeconds() << " ";
}
Out << Prefix;
return Out;
@@ -72,11 +72,11 @@ namespace NKikimr {
TSublogLineHolder(const TActorId &aid, const TActorContext &ctx)
: Aid(aid)
, Ctx(ctx)
- , Ev(std::make_unique<TEvSublogLine>())
+ , Ev(std::make_unique<TEvSublogLine>())
{}
~TSublogLineHolder() {
- Ctx.Send(Aid, Ev.release());
+ Ctx.Send(Aid, Ev.release());
}
IOutputStream &GetStream() {
@@ -85,10 +85,10 @@ namespace NKikimr {
private:
TActorId Aid;
const TActorContext &Ctx;
- std::unique_ptr<TEvSublogLine> Ev;
+ std::unique_ptr<TEvSublogLine> Ev;
};
-} // NKikimr
+} // NKikimr
// SUBLOGLINE is used for generating TEvSublogLine events
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
index 312fb3961ff..6cf1b5a4633 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_config.cpp
@@ -26,9 +26,9 @@ namespace NKikimr {
FreshCompaction = true;
GCOnlySynced = true;
AllowKeepFlags = true; // by default vdisk client can send keep/don'tkeep flags, for log can't
- CheckHugeBlobs = false;
+ CheckHugeBlobs = false;
// 128KB for SSD (because of PDisk crc?), 1MB for HDD (?)
- MaxLogoBlobDataSize = MaxVDiskBlobSize;
+ MaxLogoBlobDataSize = MaxVDiskBlobSize;
HullSstSizeInChunksFresh = 1;
HullSstSizeInChunksLevel = 1;
HugeBlobsFreeChunkReservation = 1;
@@ -39,17 +39,17 @@ namespace NKikimr {
HullCompSortedPartsNum = 8u;
HullCompLevelRateThreshold = 1.0;
HullCompFreeSpaceThreshold = 2.0;
- FreshCompMaxInFlightWrites = 10;
- HullCompMaxInFlightWrites = 10;
+ FreshCompMaxInFlightWrites = 10;
+ HullCompMaxInFlightWrites = 10;
HullCompMaxInFlightReads = 20;
- HullCompReadBatchEfficiencyThreshold = 0.5; // don't issue reads if there are more gaps than the useful data
+ HullCompReadBatchEfficiencyThreshold = 0.5; // don't issue reads if there are more gaps than the useful data
AnubisOsirisMaxInFly = 1000;
RecoveryLogCutterFirstDuration = TDuration::Seconds(10);
RecoveryLogCutterRegularDuration = TDuration::Seconds(30);
AdvanceEntryPointTimeout = TDuration::Seconds(10); // 10 seconds (FIXME: use feedback from PDisk)
SyncTimeInterval = TDuration::Seconds(3); // 3 seconds
- SyncJobTimeout = TDuration::Minutes(30); // 30 minutes
+ SyncJobTimeout = TDuration::Minutes(30); // 30 minutes
SyncerRLDRetryTimeout = TDuration::Seconds(1);
AnubisTimeout = TDuration::Minutes(60);
RunSyncer = true;
@@ -69,8 +69,8 @@ namespace NKikimr {
ReplRequestElements = 250;
ReplPrefetchElements = 2500;
ReplPrefetchDataSize = 32 << 20;
- ReplMaxResponseSize = 10 << 20;
- ReplInterconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_ASYNC_DATA;
+ ReplMaxResponseSize = 10 << 20;
+ ReplInterconnectChannel = TInterconnectChannels::IC_BLOBSTORAGE_ASYNC_DATA;
HandoffMaxWaitQueueSize = 10000;
HandoffMaxWaitQueueByteSize = 32u << 20u;
HandoffMaxInFlightSize = 1000;
@@ -80,20 +80,20 @@ namespace NKikimr {
RunHandoff = false;
SkeletonFrontGets_MaxInFlightCount = 24;
- SkeletonFrontGets_MaxInFlightCost = 200000000; // 200ms
- SkeletonFrontDiscover_MaxInFlightCount = 100;
- SkeletonFrontDiscover_MaxInFlightCost = 300000000; // 300ms
+ SkeletonFrontGets_MaxInFlightCost = 200000000; // 200ms
+ SkeletonFrontDiscover_MaxInFlightCount = 100;
+ SkeletonFrontDiscover_MaxInFlightCost = 300000000; // 300ms
SkeletonFrontLogPuts_MaxInFlightCount = 4000;
- SkeletonFrontLogPuts_MaxInFlightCost = 200000000; // 200ms
+ SkeletonFrontLogPuts_MaxInFlightCost = 200000000; // 200ms
SkeletonFrontHugePuts_MaxInFlightCount = 50;
- SkeletonFrontHugePuts_MaxInFlightCost = 700000000; // 700ms
-
- SkeletonFrontExtPutTabletLog_TotalCost = 300000000; // 300ms
- SkeletonFrontExtPutAsyncBlob_TotalCost = 700000000; // 700ms
- SkeletonFrontExtPutUserData_TotalCost = 300000000; // 300ms
- SkeletonFrontExtGetAsync_TotalCost = 300000000; // 300ms
- SkeletonFrontExtGetFast_TotalCost = 300000000; // 300ms
- SkeletonFrontExtGetDiscover_TotalCost = 300000000; // 300ms
+ SkeletonFrontHugePuts_MaxInFlightCost = 700000000; // 700ms
+
+ SkeletonFrontExtPutTabletLog_TotalCost = 300000000; // 300ms
+ SkeletonFrontExtPutAsyncBlob_TotalCost = 700000000; // 700ms
+ SkeletonFrontExtPutUserData_TotalCost = 300000000; // 300ms
+ SkeletonFrontExtGetAsync_TotalCost = 300000000; // 300ms
+ SkeletonFrontExtGetFast_TotalCost = 300000000; // 300ms
+ SkeletonFrontExtGetDiscover_TotalCost = 300000000; // 300ms
SkeletonFrontExtGetLow_TotalCost = 300000000; // 300ms
SkeletonFrontWakeupPeriod = TDuration::Seconds(1);
@@ -106,18 +106,18 @@ namespace NKikimr {
WindowPercentThreshold = 5; // 5%
WindowCostChangeUntilFrozenPercent = 20; // 20%
WindowCostChangeUntilDeathPercent = 33; // 33%
- WindowTimeout = TDuration::Minutes(60); // 1 hour
+ WindowTimeout = TDuration::Minutes(60); // 1 hour
MaxResponseSize = ui32(8) << ui32(20); // 8 MB
DskTrackerInterval = TDuration::Seconds(1);
WhiteboardUpdateInterval = TDuration::Seconds(1);
- EnableVDiskCooldownTimeout = false;
-
-#ifdef NDEBUG
- BarrierValidation = false;
-#else
- BarrierValidation = true; // switch by default on debug builds
-#endif
+ EnableVDiskCooldownTimeout = false;
+
+#ifdef NDEBUG
+ BarrierValidation = false;
+#else
+ BarrierValidation = true; // switch by default on debug builds
+#endif
}
void TVDiskConfig::SetupHugeBytes() {
@@ -155,7 +155,7 @@ namespace NKikimr {
UPDATE_MACRO(HullCompLevel0MaxSstsAtOnce);
UPDATE_MACRO(HullCompSortedPartsNum);
-
+
UPDATE_MACRO(ReplInterconnectChannel);
UPDATE_MACRO(BarrierValidation);
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_config.h b/ydb/core/blobstorage/vdisk/common/vdisk_config.h
index ff4bb4f0d61..6bba4b08007 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_config.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_config.h
@@ -27,18 +27,18 @@ namespace NKikimr {
EKind Kind = NKikimrBlobStorage::TVDiskKind::Default;
// name of the storage pool this VDisk belongs to
TString StoragePoolName;
- // is the donor mode enabled for this disk? (no communication with group, actually, no group -- only reads)
- const bool DonorMode = false;
- // a set of donor disks for this one
- std::vector<std::pair<TVDiskID, TActorId>> DonorDiskIds;
- // replication quoters
- TReplQuoter::TPtr ReplPDiskReadQuoter;
- TReplQuoter::TPtr ReplPDiskWriteQuoter;
- TReplQuoter::TPtr ReplNodeRequestQuoter;
- TReplQuoter::TPtr ReplNodeResponseQuoter;
- TDuration YardInitDelay = TDuration::Zero();
- const ui64 ScrubCookie = 0;
- const ui64 WhiteboardInstanceGuid = 0;
+ // is the donor mode enabled for this disk? (no communication with group, actually, no group -- only reads)
+ const bool DonorMode = false;
+ // a set of donor disks for this one
+ std::vector<std::pair<TVDiskID, TActorId>> DonorDiskIds;
+ // replication quoters
+ TReplQuoter::TPtr ReplPDiskReadQuoter;
+ TReplQuoter::TPtr ReplPDiskWriteQuoter;
+ TReplQuoter::TPtr ReplNodeRequestQuoter;
+ TReplQuoter::TPtr ReplNodeResponseQuoter;
+ TDuration YardInitDelay = TDuration::Zero();
+ const ui64 ScrubCookie = 0;
+ const ui64 WhiteboardInstanceGuid = 0;
TBaseInfo(
const TVDiskIdShort &vDiskIdShort,
@@ -50,10 +50,10 @@ namespace NKikimr {
EKind kind,
ui64 initOwnerRound,
TString storagePoolName,
- const bool donorMode = false,
- std::vector<std::pair<TVDiskID, TActorId>> donorDiskIds = {},
- ui64 scrubCookie = 0,
- ui64 whiteboardInstanceGuid = 0)
+ const bool donorMode = false,
+ std::vector<std::pair<TVDiskID, TActorId>> donorDiskIds = {},
+ ui64 scrubCookie = 0,
+ ui64 whiteboardInstanceGuid = 0)
: VDiskIdShort(vDiskIdShort)
, PDiskActorID(pDiskActorId)
, InitOwnerRound(initOwnerRound)
@@ -63,12 +63,12 @@ namespace NKikimr {
, VDiskSlotId(vdiskSlotId)
, Kind(kind)
, StoragePoolName(storagePoolName)
- , DonorMode(donorMode)
- , DonorDiskIds(std::move(donorDiskIds))
- , ScrubCookie(scrubCookie)
- , WhiteboardInstanceGuid(whiteboardInstanceGuid)
+ , DonorMode(donorMode)
+ , DonorDiskIds(std::move(donorDiskIds))
+ , ScrubCookie(scrubCookie)
+ , WhiteboardInstanceGuid(whiteboardInstanceGuid)
{}
-
+
TBaseInfo(const TBaseInfo &) = default;
TBaseInfo &operator=(const TBaseInfo &) = default;
@@ -117,10 +117,10 @@ namespace NKikimr {
ui32 HullCompSortedPartsNum;
double HullCompLevelRateThreshold;
double HullCompFreeSpaceThreshold;
- ui32 FreshCompMaxInFlightWrites;
- ui32 HullCompMaxInFlightWrites;
- ui32 HullCompMaxInFlightReads;
- double HullCompReadBatchEfficiencyThreshold;
+ ui32 FreshCompMaxInFlightWrites;
+ ui32 HullCompMaxInFlightWrites;
+ ui32 HullCompMaxInFlightReads;
+ double HullCompReadBatchEfficiencyThreshold;
ui64 AnubisOsirisMaxInFly;
//////////////// LOG CUTTER SETTINGS ////////////////
@@ -156,7 +156,7 @@ namespace NKikimr {
ui32 ReplPrefetchElements;
ui32 ReplPrefetchDataSize;
ui32 ReplMaxResponseSize;
- ui32 ReplInterconnectChannel;
+ ui32 ReplInterconnectChannel;
ui32 HandoffMaxWaitQueueSize;
ui32 HandoffMaxWaitQueueByteSize;
ui32 HandoffMaxInFlightSize;
@@ -164,13 +164,13 @@ namespace NKikimr {
TDuration HandoffTimeout;
bool RunRepl;
bool RunHandoff;
- bool ReplPausedAtStart = false;
+ bool ReplPausedAtStart = false;
///////////// SKELETON SETTINGS /////////////////////
ui64 SkeletonFrontGets_MaxInFlightCount;
ui64 SkeletonFrontGets_MaxInFlightCost;
- ui64 SkeletonFrontDiscover_MaxInFlightCount;
- ui64 SkeletonFrontDiscover_MaxInFlightCost;
+ ui64 SkeletonFrontDiscover_MaxInFlightCount;
+ ui64 SkeletonFrontDiscover_MaxInFlightCost;
ui64 SkeletonFrontLogPuts_MaxInFlightCount;
ui64 SkeletonFrontLogPuts_MaxInFlightCost;
ui64 SkeletonFrontHugePuts_MaxInFlightCount;
@@ -180,7 +180,7 @@ namespace NKikimr {
ui64 SkeletonFrontExtPutUserData_TotalCost;
ui64 SkeletonFrontExtGetAsync_TotalCost;
ui64 SkeletonFrontExtGetFast_TotalCost;
- ui64 SkeletonFrontExtGetDiscover_TotalCost;
+ ui64 SkeletonFrontExtGetDiscover_TotalCost;
ui64 SkeletonFrontExtGetLow_TotalCost;
TDuration SkeletonFrontWakeupPeriod;
TDuration SkeletonFrontRequestTimeout;
@@ -198,9 +198,9 @@ namespace NKikimr {
///////////// OTHER SETTINGS ////////////////////////
ui32 MaxResponseSize;
TDuration DskTrackerInterval;
- bool BarrierValidation;
+ bool BarrierValidation;
TDuration WhiteboardUpdateInterval;
- bool EnableVDiskCooldownTimeout;
+ bool EnableVDiskCooldownTimeout;
TControlWrapper EnableVPatch = true;
TVDiskConfig(const TBaseInfo &baseInfo);
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp
index 0635f0ec9e8..516f2284adf 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_context.cpp
@@ -21,26 +21,26 @@ namespace NKikimr {
TVDiskContext::TVDiskContext(
const TActorId &vdiskActorId,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& vdiskCounters,
const TVDiskID &selfVDisk,
TActorSystem *as, // as can be nullptr for tests
- TPDiskCategory::EDeviceType type,
- bool donorMode,
- TReplQuoter::TPtr replPDiskReadQuoter,
- TReplQuoter::TPtr replPDiskWriteQuoter,
- TReplQuoter::TPtr replNodeRequestQuoter,
- TReplQuoter::TPtr replNodeResponseQuoter)
+ TPDiskCategory::EDeviceType type,
+ bool donorMode,
+ TReplQuoter::TPtr replPDiskReadQuoter,
+ TReplQuoter::TPtr replPDiskWriteQuoter,
+ TReplQuoter::TPtr replNodeRequestQuoter,
+ TReplQuoter::TPtr replNodeResponseQuoter)
: TBSProxyContext(vdiskCounters->GetSubgroup("subsystem", "memhull"))
, VDiskActorId(vdiskActorId)
, Top(std::move(top))
, VDiskCounters(vdiskCounters)
, VDiskMemCounters(vdiskCounters->GetSubgroup("subsystem", "memhull"))
, Histograms(VDiskCounters, type)
- , IFaceMonGroup(std::make_shared<NMonGroup::TVDiskIFaceGroup>(VDiskCounters, "subsystem", "interface"))
+ , IFaceMonGroup(std::make_shared<NMonGroup::TVDiskIFaceGroup>(VDiskCounters, "subsystem", "interface"))
, GroupId(selfVDisk.GroupID)
, ShortSelfVDisk(selfVDisk)
- , VDiskLogPrefix(GenerateVDiskLogPrefix(selfVDisk, donorMode))
+ , VDiskLogPrefix(GenerateVDiskLogPrefix(selfVDisk, donorMode))
, NodeId(as ? as->NodeId : 0)
, FreshIndex(VDiskMemCounters->GetCounter("MemTotal:FreshIndex"))
, FreshData(VDiskMemCounters->GetCounter("MemTotal:FreshData"))
@@ -53,10 +53,10 @@ namespace NKikimr {
, Replication(VDiskMemCounters->GetCounter("MemTotal:Replication"))
, SyncLogCache(VDiskMemCounters->GetCounter("MemTotal:SyncLogCache"))
, ActorSystem(as)
- , ReplPDiskReadQuoter(std::move(replPDiskReadQuoter))
- , ReplPDiskWriteQuoter(std::move(replPDiskWriteQuoter))
- , ReplNodeRequestQuoter(std::move(replNodeRequestQuoter))
- , ReplNodeResponseQuoter(std::move(replNodeResponseQuoter))
+ , ReplPDiskReadQuoter(std::move(replPDiskReadQuoter))
+ , ReplPDiskWriteQuoter(std::move(replPDiskWriteQuoter))
+ , ReplNodeRequestQuoter(std::move(replNodeRequestQuoter))
+ , ReplNodeResponseQuoter(std::move(replNodeResponseQuoter))
, OutOfSpaceState(Top->GetTotalVDisksNum(), Top->GetOrderNumber(ShortSelfVDisk))
, Logger(as ? ActorSystemLogger(as) : DevNullLogger())
{
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_context.h b/ydb/core/blobstorage/vdisk/common/vdisk_context.h
index 7bb7dfd6704..85203859a06 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_context.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_context.h
@@ -32,12 +32,12 @@ namespace NKikimr {
public:
// ActorId of the main VDisk actor (currently ActorId of SkeletonFront)
const TActorId VDiskActorId;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
const TIntrusivePtr<NMonitoring::TDynamicCounters> VDiskCounters;
const TIntrusivePtr<NMonitoring::TDynamicCounters> VDiskMemCounters;
// latency histograms
NVDiskMon::THistograms Histograms;
- std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
+ std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
// Self VDisk related info
const ui32 GroupId;
const TVDiskIdShort ShortSelfVDisk;
@@ -55,10 +55,10 @@ namespace NKikimr {
TMemoryConsumer Replication;
TMemoryConsumer SyncLogCache;
TActorSystem *ActorSystem;
- TReplQuoter::TPtr ReplPDiskReadQuoter;
- TReplQuoter::TPtr ReplPDiskWriteQuoter;
- TReplQuoter::TPtr ReplNodeRequestQuoter;
- TReplQuoter::TPtr ReplNodeResponseQuoter;
+ TReplQuoter::TPtr ReplPDiskReadQuoter;
+ TReplQuoter::TPtr ReplPDiskWriteQuoter;
+ TReplQuoter::TPtr ReplNodeRequestQuoter;
+ TReplQuoter::TPtr ReplNodeResponseQuoter;
private:
// Managing disk space
@@ -79,16 +79,16 @@ namespace NKikimr {
public:
TVDiskContext(
const TActorId &vdiskActorId,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& vdiskCounters,
const TVDiskID &selfVDisk,
TActorSystem *as, // can be nullptr for tests
- TPDiskCategory::EDeviceType type,
- bool donorMode = false,
- TReplQuoter::TPtr replPDiskReadQuoter = nullptr,
- TReplQuoter::TPtr replPDiskWriteQuoter = nullptr,
- TReplQuoter::TPtr replNodeRequestQuoter = nullptr,
- TReplQuoter::TPtr replNodeResponseQuoter = nullptr);
+ TPDiskCategory::EDeviceType type,
+ bool donorMode = false,
+ TReplQuoter::TPtr replPDiskReadQuoter = nullptr,
+ TReplQuoter::TPtr replPDiskWriteQuoter = nullptr,
+ TReplQuoter::TPtr replNodeRequestQuoter = nullptr,
+ TReplQuoter::TPtr replNodeResponseQuoter = nullptr);
// The function checks response from PDisk. Normally, it's OK.
// Other alternatives are: 1) shutdown; 2) FAIL
@@ -99,10 +99,10 @@ namespace NKikimr {
// check status
switch (ev.Status) {
case NKikimrProto::OK:
- if constexpr (T::EventType != TEvBlobStorage::EvLogResult) {
- // we have different semantics for TEvLogResult StatusFlags
- OutOfSpaceState.UpdateLocal(ev.StatusFlags);
- }
+ if constexpr (T::EventType != TEvBlobStorage::EvLogResult) {
+ // we have different semantics for TEvLogResult StatusFlags
+ OutOfSpaceState.UpdateLocal(ev.StatusFlags);
+ }
return true;
case NKikimrProto::INVALID_OWNER:
case NKikimrProto::INVALID_ROUND:
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_events.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_events.cpp
index 25a0e24320d..22f81370b61 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_events.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_events.cpp
@@ -3,16 +3,16 @@
namespace NKikimr {
- TEvBlobStorage::TEvVPutResult::TEvVPutResult() = default;
+ TEvBlobStorage::TEvVPutResult::TEvVPutResult() = default;
TEvBlobStorage::TEvVPutResult::TEvVPutResult(const NKikimrProto::EReplyStatus status,
const TLogoBlobID &logoBlobId, const TVDiskID &vdisk, const ui64 *cookie, TOutOfSpaceStatus oosStatus,
const TInstant &now, ui32 recByteSize, NKikimrBlobStorage::TEvVPut *record,
const TActorIDPtr &skeletonFrontIDPtr, const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr,
const NVDiskMon::TLtcHistoPtr &histoPtr, const ui64 bufferSizeBytes, NWilson::TTraceId traceId,
- ui64 incarnationGuid, const TString& errorReason)
- : TEvVResultBaseWithQoSPB(now, counterPtr, histoPtr, std::move(traceId),
- TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG, recByteSize, record, skeletonFrontIDPtr)
+ ui64 incarnationGuid, const TString& errorReason)
+ : TEvVResultBaseWithQoSPB(now, counterPtr, histoPtr, std::move(traceId),
+ TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG, recByteSize, record, skeletonFrontIDPtr)
{
IncrementSize(bufferSizeBytes);
Record.SetStatus(status);
@@ -26,22 +26,22 @@ namespace NKikimr {
if (record && record->HasTimestamps()) {
Record.MutableTimestamps()->CopyFrom(record->GetTimestamps());
}
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
- if (errorReason && status != NKikimrProto::OK) {
- Record.SetErrorReason(errorReason);
- }
- }
-
- void TEvBlobStorage::TEvVPut::StorePayload(const TString& buffer) {
- if (KIKIMR_USE_PROTOBUF_WITH_PAYLOAD) {
- AddPayload(TRope(buffer));
- } else {
- Record.SetBuffer(buffer);
- }
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
+ if (errorReason && status != NKikimrProto::OK) {
+ Record.SetErrorReason(errorReason);
+ }
}
+ void TEvBlobStorage::TEvVPut::StorePayload(const TString& buffer) {
+ if (KIKIMR_USE_PROTOBUF_WITH_PAYLOAD) {
+ AddPayload(TRope(buffer));
+ } else {
+ Record.SetBuffer(buffer);
+ }
+ }
+
void TEvBlobStorage::TEvVPut::StorePayload(TRope&& buffer) {
Y_VERIFY(KIKIMR_USE_PROTOBUF_WITH_PAYLOAD);
AddPayload(std::move(buffer));
@@ -49,7 +49,7 @@ namespace NKikimr {
void TEvBlobStorage::TEvVMultiPut::StorePayload(NKikimrBlobStorage::TVMultiPutItem &item, const TString& buffer) {
if (KIKIMR_USE_PROTOBUF_WITH_PAYLOAD) {
- AddPayload(TRope(buffer));
+ AddPayload(TRope(buffer));
Y_VERIFY_DEBUG(Record.ItemsSize() == GetPayloadCount());
} else {
item.SetBuffer(buffer);
@@ -59,7 +59,7 @@ namespace NKikimr {
TRope TEvBlobStorage::TEvVMultiPut::GetItemBuffer(ui64 itemIdx) const {
auto &item = Record.GetItems(itemIdx);
if (item.HasBuffer()) {
- return TRope(item.GetBuffer());
+ return TRope(item.GetBuffer());
} else {
return GetPayload(itemIdx);
}
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_events.h b/ydb/core/blobstorage/vdisk/common/vdisk_events.h
index 47fbd959c96..206a1983704 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_events.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_events.h
@@ -14,286 +14,286 @@
#include <ydb/core/base/event_filter.h>
#include <ydb/core/base/interconnect_channels.h>
#include <ydb/core/protos/blobstorage_config.pb.h>
-
+
#include <ydb/core/util/pb.h>
-
+
#include <library/cpp/string_utils/base64/base64.h>
-#include <util/digest/multi.h>
-#include <util/generic/maybe.h>
+#include <util/digest/multi.h>
+#include <util/generic/maybe.h>
#include <util/stream/str.h>
-#include <util/string/escape.h>
+#include <util/string/escape.h>
-// FIXME: this check is obsolete; TEvVGet message generators check expected reply size by their own
-#ifndef BS_EVVGET_SIZE_VERIFY
+// FIXME: this check is obsolete; TEvVGet message generators check expected reply size by their own
+#ifndef BS_EVVGET_SIZE_VERIFY
#define BS_EVVGET_SIZE_VERIFY 0
-#endif
-
+#endif
+
namespace NKikimr {
- namespace NBackpressure {
-
- enum class EQueueClientType : ui32 {
- None,
- ReplJob,
- DSProxy,
- VDiskLoad,
+ namespace NBackpressure {
+
+ enum class EQueueClientType : ui32 {
+ None,
+ ReplJob,
+ DSProxy,
+ VDiskLoad,
VPatch,
- };
-
- inline const char *EQueueClientType2String(EQueueClientType t) {
- switch (t) {
- case EQueueClientType::None: return "None";
- case EQueueClientType::ReplJob: return "ReplJob";
- case EQueueClientType::DSProxy: return "DSProxy";
- case EQueueClientType::VDiskLoad: return "VDiskLoad";
+ };
+
+ inline const char *EQueueClientType2String(EQueueClientType t) {
+ switch (t) {
+ case EQueueClientType::None: return "None";
+ case EQueueClientType::ReplJob: return "ReplJob";
+ case EQueueClientType::DSProxy: return "DSProxy";
+ case EQueueClientType::VDiskLoad: return "VDiskLoad";
case EQueueClientType::VPatch: return "VPatch";
- }
-
- Y_FAIL("unexpected EQueueClientType");
- }
-
- // backpressure queue client identifier; ui32 means NodeId of DS Proxy actor, TVDiskID -- replication job identifier.
- class TQueueClientId {
- EQueueClientType Type;
- ui64 Identifier;
-
- public:
- TQueueClientId()
- : Type(EQueueClientType::None)
- , Identifier(0)
- {}
-
- TQueueClientId(EQueueClientType type, ui64 identifier)
- : Type(type)
- , Identifier(identifier)
- {}
-
- explicit TQueueClientId(const NKikimrBlobStorage::TMsgQoS& msgQoS)
- {
- switch (msgQoS.ClientId_case()) {
- case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kProxyNodeId:
- Type = EQueueClientType::DSProxy;
- Identifier = msgQoS.GetProxyNodeId();
- break;
-
- case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kReplVDiskId:
- Type = EQueueClientType::ReplJob;
- Identifier = msgQoS.GetReplVDiskId();
- break;
-
- case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kVDiskLoadId:
- Type = EQueueClientType::VDiskLoad;
- Identifier = msgQoS.GetVDiskLoadId();
- break;
-
+ }
+
+ Y_FAIL("unexpected EQueueClientType");
+ }
+
+ // backpressure queue client identifier; ui32 means NodeId of DS Proxy actor, TVDiskID -- replication job identifier.
+ class TQueueClientId {
+ EQueueClientType Type;
+ ui64 Identifier;
+
+ public:
+ TQueueClientId()
+ : Type(EQueueClientType::None)
+ , Identifier(0)
+ {}
+
+ TQueueClientId(EQueueClientType type, ui64 identifier)
+ : Type(type)
+ , Identifier(identifier)
+ {}
+
+ explicit TQueueClientId(const NKikimrBlobStorage::TMsgQoS& msgQoS)
+ {
+ switch (msgQoS.ClientId_case()) {
+ case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kProxyNodeId:
+ Type = EQueueClientType::DSProxy;
+ Identifier = msgQoS.GetProxyNodeId();
+ break;
+
+ case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kReplVDiskId:
+ Type = EQueueClientType::ReplJob;
+ Identifier = msgQoS.GetReplVDiskId();
+ break;
+
+ case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kVDiskLoadId:
+ Type = EQueueClientType::VDiskLoad;
+ Identifier = msgQoS.GetVDiskLoadId();
+ break;
+
case NKikimrBlobStorage::TMsgQoS::ClientIdCase::kVPatchVDiskId:
Type = EQueueClientType::VPatch;
Identifier = msgQoS.GetVPatchVDiskId();
break;
- case NKikimrBlobStorage::TMsgQoS::ClientIdCase::CLIENTID_NOT_SET:
- Type = EQueueClientType::None;
- Identifier = 0;
- break;
-
- default:
- Y_FAIL("unexpected case");
- }
- }
-
- void Serialize(NKikimrBlobStorage::TMsgQoS *msgQoS) const {
- switch (Type) {
- case EQueueClientType::None:
- break;
-
- case EQueueClientType::DSProxy:
- msgQoS->SetProxyNodeId(Identifier);
- break;
-
- case EQueueClientType::ReplJob:
- msgQoS->SetReplVDiskId(Identifier);
- break;
-
- case EQueueClientType::VDiskLoad:
- msgQoS->SetVDiskLoadId(Identifier);
- break;
+ case NKikimrBlobStorage::TMsgQoS::ClientIdCase::CLIENTID_NOT_SET:
+ Type = EQueueClientType::None;
+ Identifier = 0;
+ break;
+
+ default:
+ Y_FAIL("unexpected case");
+ }
+ }
+
+ void Serialize(NKikimrBlobStorage::TMsgQoS *msgQoS) const {
+ switch (Type) {
+ case EQueueClientType::None:
+ break;
+
+ case EQueueClientType::DSProxy:
+ msgQoS->SetProxyNodeId(Identifier);
+ break;
+
+ case EQueueClientType::ReplJob:
+ msgQoS->SetReplVDiskId(Identifier);
+ break;
+
+ case EQueueClientType::VDiskLoad:
+ msgQoS->SetVDiskLoadId(Identifier);
+ break;
case EQueueClientType::VPatch:
msgQoS->SetVPatchVDiskId(Identifier);
break;
- }
- }
-
- bool IsRepl() const {
- return Type == EQueueClientType::ReplJob;
- }
-
- size_t Hash() const {
- return MultiHash(Type, Identifier);
- }
-
- bool operator ==(const TQueueClientId& other) const {
- return Type == other.Type && Identifier == other.Identifier;
- }
-
- void Output(IOutputStream &str) const {
- str << "{Type# " << EQueueClientType2String(Type) << " Identifier# " << Identifier << "}";
- }
-
- TString ToString() const {
- TStringStream str;
- Output(str);
- return str.Str();
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // Status for window op/feedback
- ////////////////////////////////////////////////////////////////////////////
- using EStatus = NKikimrBlobStorage::TWindowFeedback::EStatus;
-
- inline bool Good(EStatus s) {
- return s == NKikimrBlobStorage::TWindowFeedback::Success ||
- s == NKikimrBlobStorage::TWindowFeedback::WindowUpdate ||
- s == NKikimrBlobStorage::TWindowFeedback::Processed;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // TMessageId -- Status for window op/feedback
- ////////////////////////////////////////////////////////////////////////////
- struct TMessageId {
- ui64 SequenceId; // id of sequence, incremented by client after failure of expected TMessageId
- ui64 MsgId; // message id in sequence, increments on each message
-
- TMessageId()
- : SequenceId(0)
- , MsgId(0)
- {}
-
- explicit TMessageId(ui64 sequenceId, ui64 msgId)
- : SequenceId(sequenceId)
- , MsgId(msgId)
- {}
-
- TMessageId(const NKikimrBlobStorage::TMessageId &from)
- : SequenceId(from.GetSequenceId())
- , MsgId(from.GetMsgId())
- {}
-
- void Serialize(NKikimrBlobStorage::TMessageId &to) const {
- to.SetSequenceId(SequenceId);
- to.SetMsgId(MsgId);
- }
-
- bool operator ==(const TMessageId &other) const {
- return SequenceId == other.SequenceId && MsgId == other.MsgId;
- }
-
- bool Empty() const {
- return SequenceId == 0 && MsgId == 0;
- }
-
- TString ToString() const {
- TStringStream str;
- Out(str);
- return str.Str();
- }
-
- void Out(IOutputStream &str) const {
- str << "[" << SequenceId << " " << MsgId << "]";
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // Current window status (after operation on window or layout change)
- ////////////////////////////////////////////////////////////////////////////
- template <class TClientId>
- struct TWindowStatus {
- TClientId ClientId;
+ }
+ }
+
+ bool IsRepl() const {
+ return Type == EQueueClientType::ReplJob;
+ }
+
+ size_t Hash() const {
+ return MultiHash(Type, Identifier);
+ }
+
+ bool operator ==(const TQueueClientId& other) const {
+ return Type == other.Type && Identifier == other.Identifier;
+ }
+
+ void Output(IOutputStream &str) const {
+ str << "{Type# " << EQueueClientType2String(Type) << " Identifier# " << Identifier << "}";
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ Output(str);
+ return str.Str();
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Status for window op/feedback
+ ////////////////////////////////////////////////////////////////////////////
+ using EStatus = NKikimrBlobStorage::TWindowFeedback::EStatus;
+
+ inline bool Good(EStatus s) {
+ return s == NKikimrBlobStorage::TWindowFeedback::Success ||
+ s == NKikimrBlobStorage::TWindowFeedback::WindowUpdate ||
+ s == NKikimrBlobStorage::TWindowFeedback::Processed;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // TMessageId -- Status for window op/feedback
+ ////////////////////////////////////////////////////////////////////////////
+ struct TMessageId {
+ ui64 SequenceId; // id of sequence, incremented by client after failure of expected TMessageId
+ ui64 MsgId; // message id in sequence, increments on each message
+
+ TMessageId()
+ : SequenceId(0)
+ , MsgId(0)
+ {}
+
+ explicit TMessageId(ui64 sequenceId, ui64 msgId)
+ : SequenceId(sequenceId)
+ , MsgId(msgId)
+ {}
+
+ TMessageId(const NKikimrBlobStorage::TMessageId &from)
+ : SequenceId(from.GetSequenceId())
+ , MsgId(from.GetMsgId())
+ {}
+
+ void Serialize(NKikimrBlobStorage::TMessageId &to) const {
+ to.SetSequenceId(SequenceId);
+ to.SetMsgId(MsgId);
+ }
+
+ bool operator ==(const TMessageId &other) const {
+ return SequenceId == other.SequenceId && MsgId == other.MsgId;
+ }
+
+ bool Empty() const {
+ return SequenceId == 0 && MsgId == 0;
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ Out(str);
+ return str.Str();
+ }
+
+ void Out(IOutputStream &str) const {
+ str << "[" << SequenceId << " " << MsgId << "]";
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Current window status (after operation on window or layout change)
+ ////////////////////////////////////////////////////////////////////////////
+ template <class TClientId>
+ struct TWindowStatus {
+ TClientId ClientId;
TActorId ActorId;
- EStatus Status;
- bool Notify;
- ui64 ActualWindowSize;
- ui64 MaxWindowSize;
- TMessageId ExpectedMsgId;
- TMessageId FailedMsgId;
-
- TWindowStatus()
- : ClientId()
- , ActorId()
- , Status(NKikimrBlobStorage::TWindowFeedback::Unknown)
- , Notify(false)
- , ActualWindowSize(0)
- , MaxWindowSize(0)
- , ExpectedMsgId()
- , FailedMsgId()
- {}
-
+ EStatus Status;
+ bool Notify;
+ ui64 ActualWindowSize;
+ ui64 MaxWindowSize;
+ TMessageId ExpectedMsgId;
+ TMessageId FailedMsgId;
+
+ TWindowStatus()
+ : ClientId()
+ , ActorId()
+ , Status(NKikimrBlobStorage::TWindowFeedback::Unknown)
+ , Notify(false)
+ , ActualWindowSize(0)
+ , MaxWindowSize(0)
+ , ExpectedMsgId()
+ , FailedMsgId()
+ {}
+
void Set(const TClientId &clientId, const TActorId& actorId, EStatus status, bool notify,
- ui64 actualWindowSize, ui64 maxWindowSize, const TMessageId &expectedMsgId,
- const TMessageId &failedMsgId) {
- ClientId = clientId;
- ActorId = actorId;
- Status = status;
- Notify = notify;
- ActualWindowSize = actualWindowSize;
- MaxWindowSize = maxWindowSize;
- ExpectedMsgId = expectedMsgId;
- FailedMsgId = failedMsgId;
- }
-
- void WindowUpdate(const TWindowStatus &s) {
- Y_VERIFY(ClientId == s.ClientId);
- // don't touch Status
- Notify = Notify || s.Notify;
- ActualWindowSize = s.ActualWindowSize;
- MaxWindowSize = s.MaxWindowSize;
- Y_VERIFY(ExpectedMsgId == s.ExpectedMsgId);
- // don't touch FailedMsgId
- }
-
- TString ToString() const {
- TStringStream str;
- str << "{Status# " << ui32(Status) << " Notify# " << Notify
- << " ActualWindowSize# " << ActualWindowSize << " MaxWindowSize# " << MaxWindowSize
- << " ExpectedMsgId# " << ExpectedMsgId.ToString() << " FailedMsgId# " << FailedMsgId.ToString()
- << "}";
- return str.Str();
- }
-
- void Serialize(NKikimrBlobStorage::TWindowFeedback &to) const {
- to.SetStatus(Status);
- to.SetActualWindowSize(ActualWindowSize);
- to.SetMaxWindowSize(MaxWindowSize);
- ExpectedMsgId.Serialize(*to.MutableExpectedMsgId());
- if (!FailedMsgId.Empty())
- FailedMsgId.Serialize(*to.MutableFailedMsgId());
- }
- };
-
- } // NBackpressure
-
+ ui64 actualWindowSize, ui64 maxWindowSize, const TMessageId &expectedMsgId,
+ const TMessageId &failedMsgId) {
+ ClientId = clientId;
+ ActorId = actorId;
+ Status = status;
+ Notify = notify;
+ ActualWindowSize = actualWindowSize;
+ MaxWindowSize = maxWindowSize;
+ ExpectedMsgId = expectedMsgId;
+ FailedMsgId = failedMsgId;
+ }
+
+ void WindowUpdate(const TWindowStatus &s) {
+ Y_VERIFY(ClientId == s.ClientId);
+ // don't touch Status
+ Notify = Notify || s.Notify;
+ ActualWindowSize = s.ActualWindowSize;
+ MaxWindowSize = s.MaxWindowSize;
+ Y_VERIFY(ExpectedMsgId == s.ExpectedMsgId);
+ // don't touch FailedMsgId
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ str << "{Status# " << ui32(Status) << " Notify# " << Notify
+ << " ActualWindowSize# " << ActualWindowSize << " MaxWindowSize# " << MaxWindowSize
+ << " ExpectedMsgId# " << ExpectedMsgId.ToString() << " FailedMsgId# " << FailedMsgId.ToString()
+ << "}";
+ return str.Str();
+ }
+
+ void Serialize(NKikimrBlobStorage::TWindowFeedback &to) const {
+ to.SetStatus(Status);
+ to.SetActualWindowSize(ActualWindowSize);
+ to.SetMaxWindowSize(MaxWindowSize);
+ ExpectedMsgId.Serialize(*to.MutableExpectedMsgId());
+ if (!FailedMsgId.Empty())
+ FailedMsgId.Serialize(*to.MutableFailedMsgId());
+ }
+ };
+
+ } // NBackpressure
+
struct TVMsgContext {
- const NBackpressure::TQueueClientId ClientId;
- const ui32 RecByteSize = 0;
- const NBackpressure::TMessageId MsgId;
- const ui64 Cost = 0;
- const NKikimrBlobStorage::EVDiskQueueId ExtQueueId = NKikimrBlobStorage::EVDiskQueueId::Unknown;
- const NKikimrBlobStorage::EVDiskInternalQueueId IntQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntUnknown;
- const TActorId ActorId;
-
- TVMsgContext() = default;
-
- TVMsgContext(ui32 recByteSize, const NKikimrBlobStorage::TMsgQoS& msgQoS)
- : ClientId(NBackpressure::TQueueClientId(msgQoS))
+ const NBackpressure::TQueueClientId ClientId;
+ const ui32 RecByteSize = 0;
+ const NBackpressure::TMessageId MsgId;
+ const ui64 Cost = 0;
+ const NKikimrBlobStorage::EVDiskQueueId ExtQueueId = NKikimrBlobStorage::EVDiskQueueId::Unknown;
+ const NKikimrBlobStorage::EVDiskInternalQueueId IntQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntUnknown;
+ const TActorId ActorId;
+
+ TVMsgContext() = default;
+
+ TVMsgContext(ui32 recByteSize, const NKikimrBlobStorage::TMsgQoS& msgQoS)
+ : ClientId(NBackpressure::TQueueClientId(msgQoS))
, RecByteSize(recByteSize)
- , MsgId(msgQoS.GetMsgId())
- , Cost(msgQoS.GetCost())
- , ExtQueueId(msgQoS.GetExtQueueId())
- , IntQueueId(msgQoS.GetIntQueueId())
- , ActorId(ActorIdFromProto(msgQoS.GetSenderActorId()))
- {}
+ , MsgId(msgQoS.GetMsgId())
+ , Cost(msgQoS.GetCost())
+ , ExtQueueId(msgQoS.GetExtQueueId())
+ , IntQueueId(msgQoS.GetIntQueueId())
+ , ActorId(ActorIdFromProto(msgQoS.GetSenderActorId()))
+ {}
void Output(IOutputStream &str) const {
str << "{ClientId# " << ClientId
@@ -315,18 +315,18 @@ namespace NKikimr {
struct TEvVDiskRequestCompleted
: public TEventLocal<TEvVDiskRequestCompleted, TEvBlobStorage::EvVDiskRequestCompleted> {
TVMsgContext Ctx;
- std::unique_ptr<IEventHandle> Event;
+ std::unique_ptr<IEventHandle> Event;
- TEvVDiskRequestCompleted(const TVMsgContext &ctx, std::unique_ptr<IEventHandle> event)
+ TEvVDiskRequestCompleted(const TVMsgContext &ctx, std::unique_ptr<IEventHandle> event)
: Ctx(ctx)
- , Event(std::move(event))
+ , Event(std::move(event))
{
Y_VERIFY_DEBUG(Ctx.ExtQueueId != NKikimrBlobStorage::EVDiskQueueId::Unknown);
Y_VERIFY_DEBUG(Ctx.IntQueueId != NKikimrBlobStorage::EVDiskInternalQueueId::IntUnknown);
}
};
- typedef std::shared_ptr<TActorId> TActorIDPtr;
+ typedef std::shared_ptr<TActorId> TActorIDPtr;
class TVDiskNonlocalResultBase {
ui32 Channel = 0;
@@ -348,11 +348,11 @@ namespace NKikimr {
}
};
- // Base class for all VDisk result events
+ // Base class for all VDisk result events
class TEvVResultBase : public TVDiskNonlocalResultBase {
public:
- TEvVResultBase() = default;
-
+ TEvVResultBase() = default;
+
TEvVResultBase(const TInstant &now, ui32 channel, const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr,
const NVDiskMon::TLtcHistoPtr &histoPtr, NWilson::TTraceId traceId)
: TVDiskNonlocalResultBase(channel)
@@ -360,28 +360,28 @@ namespace NKikimr {
, Size(0)
, CounterPtr(counterPtr)
, HistoPtr(histoPtr)
- , TraceId(std::move(traceId))
+ , TraceId(std::move(traceId))
{}
virtual ~TEvVResultBase() {
//Y_VERIFY(Finalized);
}
- virtual void FinalizeAndSend(const TActorContext& /*ctx*/, std::unique_ptr<IEventHandle> ev) {
+ virtual void FinalizeAndSend(const TActorContext& /*ctx*/, std::unique_ptr<IEventHandle> ev) {
Y_VERIFY(!Finalized); // call Finalize only once
- Finalized = true;
+ Finalized = true;
if (CounterPtr) {
- CounterPtr->Inc();
+ CounterPtr->Inc();
}
-
- if (HistoPtr) {
+
+ if (HistoPtr) {
HistoPtr->Collect(TAppData::TimeProvider->Now() - Start, Size);
- }
-
- TActivationContext::Send(ev.release());
- }
-
+ }
+
+ TActivationContext::Send(ev.release());
+ }
+
protected:
void IncrementSize(ui64 size) {
Size += size;
@@ -392,21 +392,21 @@ namespace NKikimr {
ui64 Size;
NMonitoring::TDynamicCounters::TCounterPtr CounterPtr;
NVDiskMon::TLtcHistoPtr HistoPtr;
- bool Finalized = false;
-
- public:
- NWilson::TTraceId TraceId;
- };
+ bool Finalized = false;
+
+ public:
+ NWilson::TTraceId TraceId;
+ };
template<typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType>
- class TEvVResultBasePB
- : public TEventPB<TEv, TRecord, TEventType>
- , public TEvVResultBase
- {
- using TEventPBBase = TEventPB<TEv, TRecord, TEventType>;
+ class TEvVResultBasePB
+ : public TEventPB<TEv, TRecord, TEventType>
+ , public TEvVResultBase
+ {
+ using TEventPBBase = TEventPB<TEv, TRecord, TEventType>;
public:
- TEvVResultBasePB() = default;
+ TEvVResultBasePB() = default;
TEvVResultBasePB(const TInstant &now, const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr,
const NVDiskMon::TLtcHistoPtr &histoPtr, NWilson::TTraceId traceId, ui32 channel)
@@ -414,18 +414,18 @@ namespace NKikimr {
{}
};
- template<typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType>
- class TEvVResultBaseWithQoSPB : public TEvVResultBasePB<TEv, TRecord, TEventType> {
- using TBase = TEvVResultBasePB<TEv, TRecord, TEventType>;
-
- TVMsgContext MsgCtx;
- TActorIDPtr SkeletonFrontIDPtr;
- THPTimer ExecutionTimer;
-
- public:
- TEvVResultBaseWithQoSPB() = default;
-
- template<typename TQueryRecord>
+ template<typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType>
+ class TEvVResultBaseWithQoSPB : public TEvVResultBasePB<TEv, TRecord, TEventType> {
+ using TBase = TEvVResultBasePB<TEv, TRecord, TEventType>;
+
+ TVMsgContext MsgCtx;
+ TActorIDPtr SkeletonFrontIDPtr;
+ THPTimer ExecutionTimer;
+
+ public:
+ TEvVResultBaseWithQoSPB() = default;
+
+ template<typename TQueryRecord>
static inline TInstant GetReceivedTimestamp(const TQueryRecord *queryRecord) {
return TInstant::MicroSeconds(queryRecord->GetMsgQoS().GetExecTimeStats().GetReceivedTimestamp());
}
@@ -436,61 +436,61 @@ namespace NKikimr {
ui32 recByteSize, TQueryRecord *queryRecord, const TActorIDPtr &skeletonFrontIDPtr)
: TBase(queryRecord ? GetReceivedTimestamp(queryRecord) : now,
counterPtr, histoPtr, std::move(traceId), channel)
- , MsgCtx(queryRecord ? TVMsgContext(recByteSize, queryRecord->GetMsgQoS()) : TVMsgContext())
+ , MsgCtx(queryRecord ? TVMsgContext(recByteSize, queryRecord->GetMsgQoS()) : TVMsgContext())
, SkeletonFrontIDPtr(skeletonFrontIDPtr)
- {
- if (queryRecord) {
- Y_VERIFY(queryRecord->HasMsgQoS());
+ {
+ if (queryRecord) {
+ Y_VERIFY(queryRecord->HasMsgQoS());
auto *resultQoS = TBase::Record.MutableMsgQoS();
resultQoS->Swap(queryRecord->MutableMsgQoS());
resultQoS->ClearDeadlineSeconds();
resultQoS->ClearSendMeCostSettings();
- } else {
- Y_VERIFY(!SkeletonFrontIDPtr);
- }
- }
-
- void MarkHugeWriteTime() {
- if (auto *stats = GetExecTimeStats()) {
- TDuration hugeWriteTime = TDuration::Seconds(ExecutionTimer.Passed());
- stats->SetHugeWriteTime(hugeWriteTime.GetValue());
- }
- }
-
- void FinalizeAndSend(const TActorContext &ctx, std::unique_ptr<IEventHandle> ev) override {
- TBase::FinalizeAndSend(ctx, nullptr);
-
- // update execution time stats
- if (auto *stats = GetExecTimeStats()) {
- TDuration execution = TDuration::Seconds(ExecutionTimer.Passed());
- stats->SetExecution(execution.GetValue());
- if (stats->HasReceivedTimestamp()) {
+ } else {
+ Y_VERIFY(!SkeletonFrontIDPtr);
+ }
+ }
+
+ void MarkHugeWriteTime() {
+ if (auto *stats = GetExecTimeStats()) {
+ TDuration hugeWriteTime = TDuration::Seconds(ExecutionTimer.Passed());
+ stats->SetHugeWriteTime(hugeWriteTime.GetValue());
+ }
+ }
+
+ void FinalizeAndSend(const TActorContext &ctx, std::unique_ptr<IEventHandle> ev) override {
+ TBase::FinalizeAndSend(ctx, nullptr);
+
+ // update execution time stats
+ if (auto *stats = GetExecTimeStats()) {
+ TDuration execution = TDuration::Seconds(ExecutionTimer.Passed());
+ stats->SetExecution(execution.GetValue());
+ if (stats->HasReceivedTimestamp()) {
TInstant started = TInstant::MicroSeconds(stats->GetReceivedTimestamp());
- TInstant now = TAppData::TimeProvider->Now();
- TDuration total = now - started;
- stats->SetTotal(total.GetValue());
- }
- }
-
- size_t byteSize = TBase::Record.ByteSize();
+ TInstant now = TAppData::TimeProvider->Now();
+ TDuration total = now - started;
+ stats->SetTotal(total.GetValue());
+ }
+ }
+
+ size_t byteSize = TBase::Record.ByteSize();
Y_VERIFY(byteSize <= NActors::EventMaxByteSize,
- "event suspiciously large: %zu\n%s",
+ "event suspiciously large: %zu\n%s",
byteSize, this->ToString().data());
-
- if (SkeletonFrontIDPtr && MsgCtx.IntQueueId != NKikimrBlobStorage::IntUnknown) {
- ctx.Send(*SkeletonFrontIDPtr, new TEvVDiskRequestCompleted(MsgCtx, std::move(ev)));
- } else {
- TActivationContext::Send(ev.release());
- }
- }
-
- private:
- NKikimrBlobStorage::TExecTimeStats *GetExecTimeStats() {
- auto *msgQoS = TBase::Record.MutableMsgQoS();
- return msgQoS->HasExecTimeStats() ? msgQoS->MutableExecTimeStats() : nullptr;
- }
- };
-
+
+ if (SkeletonFrontIDPtr && MsgCtx.IntQueueId != NKikimrBlobStorage::IntUnknown) {
+ ctx.Send(*SkeletonFrontIDPtr, new TEvVDiskRequestCompleted(MsgCtx, std::move(ev)));
+ } else {
+ TActivationContext::Send(ev.release());
+ }
+ }
+
+ private:
+ NKikimrBlobStorage::TExecTimeStats *GetExecTimeStats() {
+ auto *msgQoS = TBase::Record.MutableMsgQoS();
+ return msgQoS->HasExecTimeStats() ? msgQoS->MutableExecTimeStats() : nullptr;
+ }
+ };
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TEvVPut
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -506,7 +506,7 @@ namespace NKikimr {
TEvVPut(const TLogoBlobID &logoBlobId, const TString &buffer, const TVDiskID &vdisk,
const bool ignoreBlock, const ui64 *cookie, TInstant deadline,
- NKikimrBlobStorage::EPutHandleClass cls)
+ NKikimrBlobStorage::EPutHandleClass cls)
{
InitWithoutBuffer(logoBlobId, vdisk, ignoreBlock, cookie, deadline, cls);
REQUEST_VALGRIND_CHECK_MEM_IS_DEFINED(buffer.Data(), buffer.size());
@@ -555,8 +555,8 @@ namespace NKikimr {
return Record.HasBuffer() ? TRope(Record.GetBuffer()) : GetPayload(0);
}
- void StorePayload(const TString& buffer);
-
+ void StorePayload(const TString& buffer);
+
void StorePayload(TRope&& buffer);
ui64 GetBufferBytes() const {
@@ -700,13 +700,13 @@ namespace NKikimr {
mutable NLWTrace::TOrbit Orbit;
TEvVPutResult();
-
+
TEvVPutResult(const NKikimrProto::EReplyStatus status, const TLogoBlobID &logoBlobId, const TVDiskID &vdisk,
const ui64 *cookie, TOutOfSpaceStatus oosStatus, const TInstant &now, ui32 recByteSize,
NKikimrBlobStorage::TEvVPut *queryRecord, const TActorIDPtr &skeletonFrontIDPtr,
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr, const NVDiskMon::TLtcHistoPtr &histoPtr,
- const ui64 bufferSizeBytes, NWilson::TTraceId traceId, ui64 incarnationGuid,
- const TString& errorReason);
+ const ui64 bufferSizeBytes, NWilson::TTraceId traceId, ui64 incarnationGuid,
+ const TString& errorReason);
TString ToString() const override {
return ToString(Record);
@@ -720,9 +720,9 @@ namespace NKikimr {
TStringStream str;
TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetBlobID());
str << "{EvVPutResult Status# " << NKikimrProto::EReplyStatus_Name(record.GetStatus()).data();
- if (record.HasErrorReason()) {
- str << " ErrorReason# " << '"' << EscapeC(record.GetErrorReason()) << '"';
- }
+ if (record.HasErrorReason()) {
+ str << " ErrorReason# " << '"' << EscapeC(record.GetErrorReason()) << '"';
+ }
str << " ID# " << id.ToString();
if (record.HasCookie()) {
str << " Cookie# " << record.GetCookie();
@@ -736,12 +736,12 @@ namespace NKikimr {
return str.Str();
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& errorReason,
- const NKikimrBlobStorage::TEvVPut &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ const NKikimrBlobStorage::TEvVPut &request) {
Record.SetStatus(status);
- if (status != NKikimrProto::OK && errorReason) {
- Record.SetErrorReason(errorReason);
- }
+ if (status != NKikimrProto::OK && errorReason) {
+ Record.SetErrorReason(errorReason);
+ }
if (request.HasBlobID()) {
Record.MutableBlobID()->CopyFrom(request.GetBlobID());
}
@@ -905,11 +905,11 @@ namespace NKikimr {
TEvVMultiPutResult() = default;
- TEvVMultiPutResult(const NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const ui64 *cookie,
+ TEvVMultiPutResult(const NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const ui64 *cookie,
const TInstant &now, ui32 recByteSize, NKikimrBlobStorage::TEvVMultiPut *record,
const TActorIDPtr &skeletonFrontIDPtr, const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr,
const NVDiskMon::TLtcHistoPtr &histoPtr, const ui64 bufferSizeBytes, NWilson::TTraceId traceId,
- ui64 incarnationGuid, const TString& errorReason)
+ ui64 incarnationGuid, const TString& errorReason)
: TEvVResultBaseWithQoSPB(now, counterPtr, histoPtr, std::move(traceId),
TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG, recByteSize, record, skeletonFrontIDPtr)
{
@@ -922,22 +922,22 @@ namespace NKikimr {
if (record && record->HasTimestamps()) {
Record.MutableTimestamps()->CopyFrom(record->GetTimestamps());
}
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
- if (errorReason && status != NKikimrProto::OK) {
- Record.SetErrorReason(errorReason);
- }
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
+ if (errorReason && status != NKikimrProto::OK) {
+ Record.SetErrorReason(errorReason);
+ }
}
- void AddVPutResult(NKikimrProto::EReplyStatus status, const TString& errorReason, const TLogoBlobID &logoBlobId,
- ui64 *cookie, ui32 statusFlags = 0)
+ void AddVPutResult(NKikimrProto::EReplyStatus status, const TString& errorReason, const TLogoBlobID &logoBlobId,
+ ui64 *cookie, ui32 statusFlags = 0)
{
NKikimrBlobStorage::TVMultiPutResultItem *item = Record.AddItems();
item->SetStatus(status);
- if (errorReason && status != NKikimrProto::OK) {
- item->SetErrorReason(errorReason);
- }
+ if (errorReason && status != NKikimrProto::OK) {
+ item->SetErrorReason(errorReason);
+ }
LogoBlobIDFromLogoBlobID(logoBlobId, item->MutableBlobID());
if (cookie) {
item->SetCookie(*cookie);
@@ -945,15 +945,15 @@ namespace NKikimr {
item->SetStatusFlags(statusFlags);
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& errorReason,
- const NKikimrBlobStorage::TEvVMultiPut &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& errorReason,
+ const NKikimrBlobStorage::TEvVMultiPut &request) {
Record.SetStatus(status);
- if (errorReason && status != NKikimrProto::OK) {
- Record.SetErrorReason(errorReason);
- }
- if (status == NKikimrProto::NOTREADY) {
- status = NKikimrProto::ERROR; // treat BS_QUEUE internally generated NOTREADY as ERROR
- }
+ if (errorReason && status != NKikimrProto::OK) {
+ Record.SetErrorReason(errorReason);
+ }
+ if (status == NKikimrProto::NOTREADY) {
+ status = NKikimrProto::ERROR; // treat BS_QUEUE internally generated NOTREADY as ERROR
+ }
for (auto &item : request.GetItems()) {
Y_VERIFY(item.HasBlobID());
@@ -964,7 +964,7 @@ namespace NKikimr {
cookieValue = item.GetCookie();
cookie = &cookieValue;
}
- AddVPutResult(status, errorReason, logoBlobId, cookie);
+ AddVPutResult(status, errorReason, logoBlobId, cookie);
}
if (request.HasVDiskID()) {
@@ -985,17 +985,17 @@ namespace NKikimr {
static TString ToString(const NKikimrBlobStorage::TEvVMultiPutResult &record) {
TStringStream str;
str << "{EvVMultiPutResult Status# " << NKikimrProto::EReplyStatus_Name(record.GetStatus()).data();
- if (record.HasErrorReason()) {
- str << " ErrorReason# " << '"' << EscapeC(record.GetErrorReason()) << '"';
- }
+ if (record.HasErrorReason()) {
+ str << " ErrorReason# " << '"' << EscapeC(record.GetErrorReason()) << '"';
+ }
ui64 size = record.ItemsSize();
for (ui64 itemIdx = 0; itemIdx < size; ++itemIdx) {
const NKikimrBlobStorage::TVMultiPutResultItem &item = record.GetItems(itemIdx);
str << " Item# {VMultiPutResultItem";
str << " Status# " << NKikimrProto::EReplyStatus_Name(item.GetStatus()).data();
- if (item.HasErrorReason()) {
- str << " ErrorReason# " << '"' << EscapeC(item.GetErrorReason()) << '"';
- }
+ if (item.HasErrorReason()) {
+ str << " ErrorReason# " << '"' << EscapeC(item.GetErrorReason()) << '"';
+ }
TLogoBlobID id = LogoBlobIDFromLogoBlobID(item.GetBlobID());
str << " ID# " << id.ToString();
if (item.HasCookie()) {
@@ -1022,67 +1022,67 @@ namespace NKikimr {
struct TEvBlobStorage::TEvVGet
: public TEventPB<TEvBlobStorage::TEvVGet, NKikimrBlobStorage::TEvVGet, TEvBlobStorage::EvVGet>
{
- TEvVGet() = default;
-
- enum class EFlags : ui32 {
- None = 0,
- NotifyIfNotReady = 1,
- ShowInternals = 2,
- };
-
- struct TExtremeQuery : std::tuple<TLogoBlobID, ui32, ui32, const ui64*> {
- TExtremeQuery(const TLogoBlobID &logoBlobId, ui32 sh, ui32 sz, const ui64 *cookie = nullptr)
- : std::tuple<TLogoBlobID, ui32, ui32, const ui64*>(logoBlobId, sh, sz, cookie)
- {}
-
- TExtremeQuery(const TLogoBlobID &logoBlobId)
- : TExtremeQuery(logoBlobId, 0, 0)
- {}
- };
-
- static std::unique_ptr<TEvVGet> CreateExtremeIndexQuery(const TVDiskID &vdisk, TInstant deadline,
- NKikimrBlobStorage::EGetHandleClass cls, EFlags flags = EFlags::None, TMaybe<ui64> requestCookie = {},
+ TEvVGet() = default;
+
+ enum class EFlags : ui32 {
+ None = 0,
+ NotifyIfNotReady = 1,
+ ShowInternals = 2,
+ };
+
+ struct TExtremeQuery : std::tuple<TLogoBlobID, ui32, ui32, const ui64*> {
+ TExtremeQuery(const TLogoBlobID &logoBlobId, ui32 sh, ui32 sz, const ui64 *cookie = nullptr)
+ : std::tuple<TLogoBlobID, ui32, ui32, const ui64*>(logoBlobId, sh, sz, cookie)
+ {}
+
+ TExtremeQuery(const TLogoBlobID &logoBlobId)
+ : TExtremeQuery(logoBlobId, 0, 0)
+ {}
+ };
+
+ static std::unique_ptr<TEvVGet> CreateExtremeIndexQuery(const TVDiskID &vdisk, TInstant deadline,
+ NKikimrBlobStorage::EGetHandleClass cls, EFlags flags = EFlags::None, TMaybe<ui64> requestCookie = {},
std::initializer_list<TExtremeQuery> queries = {}, ui32 forceBlockedGeneration = 0) {
- std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
+ std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
bool(ui32(flags) & ui32(EFlags::ShowInternals)), requestCookie, true, true, forceBlockedGeneration));
- for (const auto &q : queries) {
- res->AddExtremeQuery(std::get<0>(q), std::get<1>(q), std::get<2>(q), std::get<3>(q));
- }
- return res;
- }
-
- static std::unique_ptr<TEvVGet> CreateExtremeDataQuery(const TVDiskID &vdisk, TInstant deadline,
- NKikimrBlobStorage::EGetHandleClass cls, EFlags flags = EFlags::None, TMaybe<ui64> requestCookie = {},
+ for (const auto &q : queries) {
+ res->AddExtremeQuery(std::get<0>(q), std::get<1>(q), std::get<2>(q), std::get<3>(q));
+ }
+ return res;
+ }
+
+ static std::unique_ptr<TEvVGet> CreateExtremeDataQuery(const TVDiskID &vdisk, TInstant deadline,
+ NKikimrBlobStorage::EGetHandleClass cls, EFlags flags = EFlags::None, TMaybe<ui64> requestCookie = {},
std::initializer_list<TExtremeQuery> queries = {}, ui32 forceBlockedGeneration = 0) {
- std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
+ std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
bool(ui32(flags) & ui32(EFlags::ShowInternals)), requestCookie, false, true, forceBlockedGeneration));
- for (const auto &q : queries) {
- res->AddExtremeQuery(std::get<0>(q), std::get<1>(q), std::get<2>(q), std::get<3>(q));
- }
- return res;
- }
-
- static std::unique_ptr<TEvVGet> CreateRangeIndexQuery(const TVDiskID &vdisk, TInstant deadline,
- NKikimrBlobStorage::EGetHandleClass cls, EFlags flags, TMaybe<ui64> requestCookie,
+ for (const auto &q : queries) {
+ res->AddExtremeQuery(std::get<0>(q), std::get<1>(q), std::get<2>(q), std::get<3>(q));
+ }
+ return res;
+ }
+
+ static std::unique_ptr<TEvVGet> CreateRangeIndexQuery(const TVDiskID &vdisk, TInstant deadline,
+ NKikimrBlobStorage::EGetHandleClass cls, EFlags flags, TMaybe<ui64> requestCookie,
const TLogoBlobID &fromId, const TLogoBlobID &toId, ui32 maxResults = 0, const ui64 *cookie = nullptr,
ui32 forceBlockedGeneration = 0) {
- std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
+ std::unique_ptr<TEvVGet> res(new TEvVGet(vdisk, deadline, cls, bool(ui32(flags) & ui32(EFlags::NotifyIfNotReady)),
bool(ui32(flags) & ui32(EFlags::ShowInternals)), requestCookie, true, false, forceBlockedGeneration));
- NKikimrBlobStorage::TRangeQuery *q = res->Record.MutableRangeQuery();
- LogoBlobIDFromLogoBlobID(fromId, q->MutableFrom());
- LogoBlobIDFromLogoBlobID(toId, q->MutableTo());
- if (maxResults) {
- q->SetMaxResults(maxResults);
+ NKikimrBlobStorage::TRangeQuery *q = res->Record.MutableRangeQuery();
+ LogoBlobIDFromLogoBlobID(fromId, q->MutableFrom());
+ LogoBlobIDFromLogoBlobID(toId, q->MutableTo());
+ if (maxResults) {
+ q->SetMaxResults(maxResults);
}
- if (cookie) {
- q->SetCookie(*cookie);
+ if (cookie) {
+ q->SetCookie(*cookie);
}
- return res;
+ return res;
}
void AddExtremeQuery(const TLogoBlobID &logoBlobId, ui32 sh, ui32 sz, const ui64 *cookie = nullptr) {
- Y_VERIFY(Extreme);
-
+ Y_VERIFY(Extreme);
+
NKikimrBlobStorage::TExtremeQuery *q = Record.AddExtremeQueries();
LogoBlobIDFromLogoBlobID(logoBlobId, q->MutableId());
if (sh != 0)
@@ -1091,7 +1091,7 @@ namespace NKikimr {
q->SetSize(sz);
if (cookie)
q->SetCookie(*cookie);
-#if BS_EVVGET_SIZE_VERIFY
+#if BS_EVVGET_SIZE_VERIFY
if (Record.HasIndexOnly() && Record.GetIndexOnly()) {
ExpectedReplySize += BlobProtobufHeaderMaxSize;
Y_VERIFY(TBlobStorageGroupType::GetMaxDataSizeWithErasureOverhead(ExpectedReplySize) <= MaxProtobufSize,
@@ -1103,7 +1103,7 @@ namespace NKikimr {
if (!blobSize) {
blobSize = MaxBlobSize;
}
-
+
ui32 payloadSize = sz ? sz : blobSize;
if (payloadSize + sh > blobSize) {
payloadSize = blobSize > sh ? blobSize - sh : 0;
@@ -1113,8 +1113,8 @@ namespace NKikimr {
"Possible protobuf overflow for get request. ExpectedReplySize# %" PRIu64
" MaxProtobufSize# %" PRIu64 " ExtremeQueries# %" PRIu64, (ui64)ExpectedReplySize,
(ui64)MaxProtobufSize, (ui64)Record.ExtremeQueriesSize());
- }
-#endif
+ }
+#endif
}
bool Validate(TString& errorReason) {
@@ -1180,57 +1180,57 @@ namespace NKikimr {
<< "}";
return str.Str();
}
-
- bool GetIsLocalMon() const {
- return IsLocalMon;
- }
-
- void SetIsLocalMon() {
- IsLocalMon = true;
- }
-
- private:
- bool IsLocalMon = false;
- const bool Extreme = false;
-
-#if BS_EVVGET_SIZE_VERIFY
- ui64 ExpectedReplySize = 0;
-#endif
-
- private:
- TEvVGet(const TVDiskID &vdisk,
- TInstant deadline,
- NKikimrBlobStorage::EGetHandleClass cls,
- bool notifyIfNotReady,
- bool showInternals,
- TMaybe<ui64> requestCookie,
- bool indexOnly,
+
+ bool GetIsLocalMon() const {
+ return IsLocalMon;
+ }
+
+ void SetIsLocalMon() {
+ IsLocalMon = true;
+ }
+
+ private:
+ bool IsLocalMon = false;
+ const bool Extreme = false;
+
+#if BS_EVVGET_SIZE_VERIFY
+ ui64 ExpectedReplySize = 0;
+#endif
+
+ private:
+ TEvVGet(const TVDiskID &vdisk,
+ TInstant deadline,
+ NKikimrBlobStorage::EGetHandleClass cls,
+ bool notifyIfNotReady,
+ bool showInternals,
+ TMaybe<ui64> requestCookie,
+ bool indexOnly,
bool extreme,
ui32 forceBlockedGeneration)
- : Extreme(extreme)
- {
- VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
- Record.SetHandleClass(cls);
- if (notifyIfNotReady) {
- Record.SetNotifyIfNotReady(true);
- }
- if (showInternals) {
- Record.SetShowInternals(true);
- }
- if (requestCookie) {
- Record.SetCookie(*requestCookie);
- }
- if (indexOnly) {
- Record.SetIndexOnly(true);
- }
- if (deadline != TInstant::Max()) {
- Record.MutableMsgQoS()->SetDeadlineSeconds((ui32)deadline.Seconds());
- }
+ : Extreme(extreme)
+ {
+ VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
+ Record.SetHandleClass(cls);
+ if (notifyIfNotReady) {
+ Record.SetNotifyIfNotReady(true);
+ }
+ if (showInternals) {
+ Record.SetShowInternals(true);
+ }
+ if (requestCookie) {
+ Record.SetCookie(*requestCookie);
+ }
+ if (indexOnly) {
+ Record.SetIndexOnly(true);
+ }
+ if (deadline != TInstant::Max()) {
+ Record.MutableMsgQoS()->SetDeadlineSeconds((ui32)deadline.Seconds());
+ }
if (forceBlockedGeneration) {
Record.SetForceBlockedGeneration(forceBlockedGeneration);
}
- Record.MutableMsgQoS()->SetExtQueueId(HandleClassToQueueId(cls));
- }
+ Record.MutableMsgQoS()->SetExtQueueId(HandleClassToQueueId(cls));
+ }
};
struct TEvBlobStorage::TEvVGetResult
@@ -1252,14 +1252,14 @@ namespace NKikimr {
if (queryRecord && queryRecord->HasTimestamps()) {
Record.MutableTimestamps()->CopyFrom(queryRecord->GetTimestamps());
}
-
- // copy cookie if it was set in initial query
- if (cookie)
- Record.SetCookie(*cookie);
-
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
+
+ // copy cookie if it was set in initial query
+ if (cookie)
+ Record.SetCookie(*cookie);
+
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
}
void MarkRangeOverflow() {
@@ -1275,10 +1275,10 @@ namespace NKikimr {
if (sh != 0) {
r->SetShift(sh);
}
- if (data) {
+ if (data) {
r->SetBuffer(data, size);
}
- r->SetSize(size);
+ r->SetSize(size);
r->SetFullDataSize(logoBlobId.BlobSize());
if (cookie) {
r->SetCookie(*cookie);
@@ -1288,7 +1288,7 @@ namespace NKikimr {
}
void AddResult(NKikimrProto::EReplyStatus status, const TLogoBlobID &logoBlobId, const ui64 *cookie = nullptr,
- const ui64 *ingress = nullptr, const NMatrix::TVectorType *local = nullptr) {
+ const ui64 *ingress = nullptr, const NMatrix::TVectorType *local = nullptr) {
NKikimrBlobStorage::TQueryResult *r = Record.AddResult();
r->SetStatus(status);
LogoBlobIDFromLogoBlobID(logoBlobId, r->MutableBlobID());
@@ -1296,31 +1296,31 @@ namespace NKikimr {
r->SetCookie(*cookie);
if (ingress)
r->SetIngress(*ingress);
- if (local) {
- for (ui8 i = local->FirstPosition(); i != local->GetSize(); i = local->NextPosition(i)) {
- r->AddParts(i + 1);
- }
- }
+ if (local) {
+ for (ui8 i = local->FirstPosition(); i != local->GetSize(); i = local->NextPosition(i)) {
+ r->AddParts(i + 1);
+ }
+ }
}
TString ToString() const override {
TStringStream str;
str << "{EvVGetResult QueryResult Status# " << NKikimrProto::EReplyStatus_Name(Record.GetStatus()).data();
- for (const auto& result : Record.GetResult()) {
- str << " {";
- str << (result.HasBlobID() ? LogoBlobIDFromLogoBlobID(result.GetBlobID()).ToString() : "?")
- << " " << (result.HasStatus() ? NKikimrProto::EReplyStatus_Name(result.GetStatus()) : "?");
- if (result.HasShift()) {
- str << " Shift# " << result.GetShift();
+ for (const auto& result : Record.GetResult()) {
+ str << " {";
+ str << (result.HasBlobID() ? LogoBlobIDFromLogoBlobID(result.GetBlobID()).ToString() : "?")
+ << " " << (result.HasStatus() ? NKikimrProto::EReplyStatus_Name(result.GetStatus()) : "?");
+ if (result.HasShift()) {
+ str << " Shift# " << result.GetShift();
}
- if (result.HasSize()) {
- str << " Size# " << result.GetSize();
+ if (result.HasSize()) {
+ str << " Size# " << result.GetSize();
}
- if (result.HasFullDataSize()) {
- str << " FullDataSize# " << result.GetFullDataSize();
+ if (result.HasFullDataSize()) {
+ str << " FullDataSize# " << result.GetFullDataSize();
}
- if (result.HasBuffer()) {
- const TString &data = result.GetBuffer();
+ if (result.HasBuffer()) {
+ const TString &data = result.GetBuffer();
str << " DataSize# " << data.size();
if (data.size() > 16) {
str << " Data# <too_large>";
@@ -1330,16 +1330,16 @@ namespace NKikimr {
str << " Data# " << encoded;
}
}
- if (result.HasCookie()) {
- str << " Cookie# " << result.GetCookie();
- }
- if (result.HasIngress()) {
- ui64 ingress = result.GetIngress();
- str << " Ingress# " << ingress;
+ if (result.HasCookie()) {
+ str << " Cookie# " << result.GetCookie();
}
- if (const auto& v = result.GetParts(); !v.empty()) {
- str << " Parts# " << FormatList(v);
+ if (result.HasIngress()) {
+ ui64 ingress = result.GetIngress();
+ str << " Ingress# " << ingress;
}
+ if (const auto& v = result.GetParts(); !v.empty()) {
+ str << " Parts# " << FormatList(v);
+ }
str << "}";
}
str << " BlockedGeneration# " << Record.GetBlockedGeneration();
@@ -1347,10 +1347,10 @@ namespace NKikimr {
return str.Str();
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const NKikimrBlobStorage::TEvVGet &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const NKikimrBlobStorage::TEvVGet &request) {
NKikimrProto::EReplyStatus messageStatus = status;
- NKikimrProto::EReplyStatus queryStatus = status != NKikimrProto::NOTREADY ? status : NKikimrProto::ERROR;
+ NKikimrProto::EReplyStatus queryStatus = status != NKikimrProto::NOTREADY ? status : NKikimrProto::ERROR;
Record.SetStatus(messageStatus);
// Ignore RangeQuery (pretend there are no results)
@@ -1679,13 +1679,13 @@ namespace NKikimr {
TEvVBlock()
{}
- TEvVBlock(ui64 tabletId, ui32 generation, const TVDiskID &vdisk, TInstant deadline, ui64 issuerGuid = 0)
+ TEvVBlock(ui64 tabletId, ui32 generation, const TVDiskID &vdisk, TInstant deadline, ui64 issuerGuid = 0)
{
Record.SetTabletId(tabletId);
Record.SetGeneration(generation);
- if (issuerGuid) {
- Record.SetIssuerGuid(issuerGuid);
- }
+ if (issuerGuid) {
+ Record.SetIssuerGuid(issuerGuid);
+ }
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
if (deadline != TInstant::Max()) {
Record.MutableMsgQoS()->SetDeadlineSeconds((ui32)deadline.Seconds());
@@ -1707,7 +1707,7 @@ namespace NKikimr {
, ActualGen(actualGen)
{}
};
- TEvVBlockResult() = default;
+ TEvVBlockResult() = default;
TEvVBlockResult(NKikimrProto::EReplyStatus status, const TTabletActGen *actual, const TVDiskID &vdisk,
const TInstant &now, ui32 recByteSize, NKikimrBlobStorage::TEvVBlock *queryRecord,
@@ -1722,9 +1722,9 @@ namespace NKikimr {
Record.SetGeneration(actual->ActualGen);
}
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
}
void UpdateStatus(NKikimrProto::EReplyStatus status, ui64 tabletId, ui32 actualGen) {
@@ -1749,8 +1749,8 @@ namespace NKikimr {
return str.Str();
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const NKikimrBlobStorage::TEvVBlock &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const NKikimrBlobStorage::TEvVBlock &request) {
Record.SetStatus(status);
Y_VERIFY(request.HasTabletId());
Record.SetTabletId(request.GetTabletId());
@@ -2081,7 +2081,7 @@ namespace NKikimr {
: public TEvVResultBaseWithQoSPB<TEvBlobStorage::TEvVGetBlockResult,
NKikimrBlobStorage::TEvVGetBlockResult,
TEvBlobStorage::EvVGetBlockResult> {
- TEvVGetBlockResult() = default;
+ TEvVGetBlockResult() = default;
TEvVGetBlockResult(NKikimrProto::EReplyStatus status, ui64 tabletId, const TVDiskID &vdisk,
const TInstant &now, ui32 recByteSize, NKikimrBlobStorage::TEvVGetBlock *queryRecord,
@@ -2124,8 +2124,8 @@ namespace NKikimr {
return str.Str();
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const NKikimrBlobStorage::TEvVGetBlock &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const NKikimrBlobStorage::TEvVGetBlock &request) {
Record.SetStatus(status);
Y_VERIFY(request.HasTabletId());
Record.SetTabletId(request.GetTabletId());
@@ -2146,7 +2146,7 @@ namespace NKikimr {
explicit
TEvVCollectGarbage(ui64 tabletId, ui32 recordGeneration, ui32 perGenerationCounter, ui32 channel, bool collect,
- ui32 collectGeneration, ui32 collectStep, bool hard,
+ ui32 collectGeneration, ui32 collectStep, bool hard,
const TVector<TLogoBlobID> *keep, const TVector<TLogoBlobID> *doNotKeep,
const TVDiskID &vdisk, TInstant deadline)
{
@@ -2157,7 +2157,7 @@ namespace NKikimr {
if (collect) {
Record.SetCollectGeneration(collectGeneration);
Record.SetCollectStep(collectStep);
- Record.SetHard(hard);
+ Record.SetHard(hard);
}
if (keep) {
for (ui64 i = 0; i < keep->size(); ++i) {
@@ -2200,12 +2200,12 @@ namespace NKikimr {
}
};
- struct TEvBlobStorage::TEvVCollectGarbageResult
- : public TEvVResultBaseWithQoSPB<TEvBlobStorage::TEvVCollectGarbageResult,
+ struct TEvBlobStorage::TEvVCollectGarbageResult
+ : public TEvVResultBaseWithQoSPB<TEvBlobStorage::TEvVCollectGarbageResult,
NKikimrBlobStorage::TEvVCollectGarbageResult,
TEvBlobStorage::EvVCollectGarbageResult>
- {
- TEvVCollectGarbageResult() = default;
+ {
+ TEvVCollectGarbageResult() = default;
TEvVCollectGarbageResult(NKikimrProto::EReplyStatus status, ui64 tabletId, ui32 recordGeneration, ui32 channel,
const TVDiskID &vdisk, const TInstant &now, ui32 recByteSize,
@@ -2220,9 +2220,9 @@ namespace NKikimr {
Record.SetRecordGeneration(recordGeneration);
Record.SetChannel(channel);
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
- if (status == NKikimrProto::OK) {
- Record.SetIncarnationGuid(incarnationGuid);
- }
+ if (status == NKikimrProto::OK) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
}
void UpdateStatus(NKikimrProto::EReplyStatus status) {
@@ -2248,8 +2248,8 @@ namespace NKikimr {
return str.Str();
}
- void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const NKikimrBlobStorage::TEvVCollectGarbage &request) {
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const NKikimrBlobStorage::TEvVCollectGarbage &request) {
Record.SetStatus(status);
Y_VERIFY(request.HasTabletId());
Record.SetTabletId(request.GetTabletId());
@@ -2301,7 +2301,7 @@ namespace NKikimr {
: public TEvVResultBaseWithQoSPB<TEvBlobStorage::TEvVGetBarrierResult,
NKikimrBlobStorage::TEvVGetBarrierResult,
TEvBlobStorage::EvVGetBarrierResult> {
- TEvVGetBarrierResult() = default;
+ TEvVGetBarrierResult() = default;
TEvVGetBarrierResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const TInstant &now,
ui32 recByteSize, NKikimrBlobStorage::TEvVGetBarrier *queryRecord,
@@ -2320,38 +2320,38 @@ namespace NKikimr {
auto v = Record.AddValues();
memRec.Serialize(*v, showInternals);
}
-
- void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const NKikimrBlobStorage::TEvVGetBarrier &request) {
- Record.SetStatus(status);
- Record.MutableVDiskID()->CopyFrom(request.GetVDiskID());
- }
+
+ void MakeError(NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const NKikimrBlobStorage::TEvVGetBarrier &request) {
+ Record.SetStatus(status);
+ Record.MutableVDiskID()->CopyFrom(request.GetVDiskID());
+ }
};
- struct TEvBlobStorage::TEvVCheckReadiness
+ struct TEvBlobStorage::TEvVCheckReadiness
: public TEventPB<TEvBlobStorage::TEvVCheckReadiness,
NKikimrBlobStorage::TEvVCheckReadiness,
TEvBlobStorage::EvVCheckReadiness>
- {
- TEvVCheckReadiness() = default;
-
- TEvVCheckReadiness(bool notifyIfNotReady) {
- Record.SetNotifyIfNotReady(notifyIfNotReady);
- }
- };
-
- struct TEvBlobStorage::TEvVCheckReadinessResult
+ {
+ TEvVCheckReadiness() = default;
+
+ TEvVCheckReadiness(bool notifyIfNotReady) {
+ Record.SetNotifyIfNotReady(notifyIfNotReady);
+ }
+ };
+
+ struct TEvBlobStorage::TEvVCheckReadinessResult
: public TEventPB<TEvBlobStorage::TEvVCheckReadinessResult,
NKikimrBlobStorage::TEvVCheckReadinessResult,
EvVCheckReadinessResult>
- {
- TEvVCheckReadinessResult() = default;
-
- TEvVCheckReadinessResult(NKikimrProto::EReplyStatus status) {
- Record.SetStatus(status);
- }
- };
-
+ {
+ TEvVCheckReadinessResult() = default;
+
+ TEvVCheckReadinessResult(NKikimrProto::EReplyStatus status) {
+ Record.SetStatus(status);
+ }
+ };
+
struct TEvBlobStorage::TEvVCompact
: public TEventPB<TEvBlobStorage::TEvVCompact, NKikimrBlobStorage::TEvVCompact, TEvBlobStorage::EvVCompact>
{
@@ -2473,13 +2473,13 @@ namespace NKikimr {
NKikimrBlobStorage::TEvVDbStatResult,
TEvBlobStorage::EvVDbStatResult>
{
- TEvVDbStatResult() = default;
+ TEvVDbStatResult() = default;
- TEvVDbStatResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const TInstant &now,
+ TEvVDbStatResult(NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const TInstant &now,
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr, const NVDiskMon::TLtcHistoPtr &histoPtr,
- NWilson::TTraceId traceId)
+ NWilson::TTraceId traceId)
: TEvVResultBasePB(now, counterPtr, histoPtr, std::move(traceId),
- TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG)
+ TInterconnectChannels::IC_BLOBSTORAGE_SMALL_MSG)
{
Record.SetStatus(status);
VDiskIDFromVDiskID(vdisk, Record.MutableVDiskID());
@@ -2539,7 +2539,7 @@ namespace NKikimr {
// from protobuf
using EState = NKikimrBlobStorage::TSyncGuidInfo::EState;
- TEvVSyncGuidResult() = default;
+ TEvVSyncGuidResult() = default;
// read response
TEvVSyncGuidResult(const NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const TInstant &now,
@@ -2598,7 +2598,7 @@ namespace NKikimr {
: public TEvVResultBasePB<TEvBlobStorage::TEvVSyncResult,
NKikimrBlobStorage::TEvVSyncResult,
TEvBlobStorage::EvVSyncResult> {
- TEvVSyncResult() = default;
+ TEvVSyncResult() = default;
TEvVSyncResult(const NKikimrProto::EReplyStatus status, const TVDiskID &vdisk,
const TSyncState &newSyncState, bool finished, NPDisk::TStatusFlags flags, const TInstant &now,
@@ -2665,7 +2665,7 @@ namespace NKikimr {
NKikimrBlobStorage::TEvVSyncFullResult,
TEvBlobStorage::EvVSyncFullResult>
{
- TEvVSyncFullResult() = default;
+ TEvVSyncFullResult() = default;
TEvVSyncFullResult(const NKikimrProto::EReplyStatus status, const TVDiskID &vdisk, const TSyncState &syncState,
ui64 cookie, const TInstant &now, const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr,
@@ -2706,25 +2706,25 @@ namespace NKikimr {
NKikimrBlobStorage::TEvVWindowChange,
TEvBlobStorage::EvVWindowChange>
{
- static constexpr struct TDropConnection {} DropConnection{};
-
+ static constexpr struct TDropConnection {} DropConnection{};
+
TEvVWindowChange()
{}
- template<typename TClientId>
- TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId queueId,
- const typename NBackpressure::TWindowStatus<TClientId> &wstatus) {
+ template<typename TClientId>
+ TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId queueId,
+ const typename NBackpressure::TWindowStatus<TClientId> &wstatus) {
Record.SetFrontQueueId(queueId);
wstatus.Serialize(*Record.MutableWindow());
}
- TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId queueId, TDropConnection) {
- Record.SetFrontQueueId(queueId);
- Record.SetDropConnection(true);
- }
-
+ TEvVWindowChange(NKikimrBlobStorage::EVDiskQueueId queueId, TDropConnection) {
+ Record.SetFrontQueueId(queueId);
+ Record.SetDropConnection(true);
+ }
+
TString ToString() const override {
- return SingleLineProto(Record);
+ return SingleLineProto(Record);
}
};
@@ -2732,18 +2732,18 @@ namespace NKikimr {
TVDiskID NewVDiskId;
TIntrusivePtr<TBlobStorageGroupInfo> NewInfo;
- TEvVGenerationChange(const TVDiskID &newVDiskId, const TIntrusivePtr<TBlobStorageGroupInfo> &newInfo)
- : NewVDiskId(newVDiskId)
+ TEvVGenerationChange(const TVDiskID &newVDiskId, const TIntrusivePtr<TBlobStorageGroupInfo> &newInfo)
+ : NewVDiskId(newVDiskId)
, NewInfo(newInfo)
{}
TEvVGenerationChange *Clone() {
- return new TEvVGenerationChange(NewVDiskId, NewInfo);
+ return new TEvVGenerationChange(NewVDiskId, NewInfo);
}
TString ToString() const override {
- return TStringBuilder() << "{TEvVGenerationChange NewVDiskId# " << NewVDiskId << " NewInfo# "
- << NewInfo->ToString() << "}" ;
+ return TStringBuilder() << "{TEvVGenerationChange NewVDiskId# " << NewVDiskId << " NewInfo# "
+ << NewInfo->ToString() << "}" ;
}
};
@@ -2753,9 +2753,9 @@ namespace NKikimr {
TIntrusivePtr<TBlobStorageGroupInfo> Info;
TIntrusivePtr<TStoragePoolCounters> StoragePoolCounters;
- TEvConfigureProxy(TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TStoragePoolCounters> storagePoolCounters = nullptr)
- : Info(std::move(info))
- , StoragePoolCounters(std::move(storagePoolCounters))
+ TEvConfigureProxy(TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TStoragePoolCounters> storagePoolCounters = nullptr)
+ : Info(std::move(info))
+ , StoragePoolCounters(std::move(storagePoolCounters))
{}
TString ToString() const override {
@@ -2777,54 +2777,54 @@ namespace NKikimr {
}
};
- struct TEvBlobStorage::TEvUpdateGroupInfo : TEventLocal<TEvUpdateGroupInfo, EvUpdateGroupInfo> {
- const ui32 GroupId;
- const ui32 GroupGeneration;
- std::optional<NKikimrBlobStorage::TGroupInfo> GroupInfo;
-
- TEvUpdateGroupInfo(ui32 groupId, ui32 groupGeneration, std::optional<NKikimrBlobStorage::TGroupInfo> groupInfo)
+ struct TEvBlobStorage::TEvUpdateGroupInfo : TEventLocal<TEvUpdateGroupInfo, EvUpdateGroupInfo> {
+ const ui32 GroupId;
+ const ui32 GroupGeneration;
+ std::optional<NKikimrBlobStorage::TGroupInfo> GroupInfo;
+
+ TEvUpdateGroupInfo(ui32 groupId, ui32 groupGeneration, std::optional<NKikimrBlobStorage::TGroupInfo> groupInfo)
: GroupId(groupId)
- , GroupGeneration(groupGeneration)
- , GroupInfo(std::move(groupInfo))
+ , GroupGeneration(groupGeneration)
+ , GroupInfo(std::move(groupInfo))
{}
};
- struct TEvBlobStorage::TEvEnrichNotYet : TEventLocal<TEvEnrichNotYet, EvEnrichNotYet> {
- TEvVGet::TPtr Query;
- std::unique_ptr<TEvVGetResult> Result;
-
- TEvEnrichNotYet(TEvVGet::TPtr query, std::unique_ptr<TEvVGetResult> result)
- : Query(std::move(query))
- , Result(std::move(result))
- {}
- };
-
- struct TEvBlobStorage::TEvCaptureVDiskLayout : TEventLocal<TEvCaptureVDiskLayout, EvCaptureVDiskLayout>
- {};
-
- struct TEvBlobStorage::TEvCaptureVDiskLayoutResult : TEventLocal<TEvCaptureVDiskLayoutResult, EvCaptureVDiskLayoutResult> {
- enum class EDatabase {
- LogoBlobs,
- Blocks,
- Barriers
- };
-
- enum class ERecordType {
- HugeBlob,
- InplaceBlob,
- IndexRecord,
- };
-
- struct TLayoutRecord {
- TDiskPart Location;
- EDatabase Database;
- ERecordType RecordType;
- TLogoBlobID BlobId; // for HugeBlob/InplaceBlob
- ui64 SstId; // for IndexRecord
- ui32 Level; // for IndexRecord
- };
-
- std::vector<TLayoutRecord> Layout;
- };
-
+ struct TEvBlobStorage::TEvEnrichNotYet : TEventLocal<TEvEnrichNotYet, EvEnrichNotYet> {
+ TEvVGet::TPtr Query;
+ std::unique_ptr<TEvVGetResult> Result;
+
+ TEvEnrichNotYet(TEvVGet::TPtr query, std::unique_ptr<TEvVGetResult> result)
+ : Query(std::move(query))
+ , Result(std::move(result))
+ {}
+ };
+
+ struct TEvBlobStorage::TEvCaptureVDiskLayout : TEventLocal<TEvCaptureVDiskLayout, EvCaptureVDiskLayout>
+ {};
+
+ struct TEvBlobStorage::TEvCaptureVDiskLayoutResult : TEventLocal<TEvCaptureVDiskLayoutResult, EvCaptureVDiskLayoutResult> {
+ enum class EDatabase {
+ LogoBlobs,
+ Blocks,
+ Barriers
+ };
+
+ enum class ERecordType {
+ HugeBlob,
+ InplaceBlob,
+ IndexRecord,
+ };
+
+ struct TLayoutRecord {
+ TDiskPart Location;
+ EDatabase Database;
+ ERecordType RecordType;
+ TLogoBlobID BlobId; // for HugeBlob/InplaceBlob
+ ui64 SstId; // for IndexRecord
+ ui32 Level; // for IndexRecord
+ };
+
+ std::vector<TLayoutRecord> Layout;
+ };
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_histogram_latency.h b/ydb/core/blobstorage/vdisk/common/vdisk_histogram_latency.h
index d0388fac73f..0701fe8197e 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_histogram_latency.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_histogram_latency.h
@@ -33,7 +33,7 @@ namespace NKikimr {
NMonitoring::TDynamicCounters::TCounterPtr ThroughputBytes;
};
- using TLtcHistoPtr = std::shared_ptr<TLtcHisto>;
+ using TLtcHistoPtr = std::shared_ptr<TLtcHisto>;
} // NVDiskMon
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.cpp
index 0407e91dbbe..9fc8c6c6594 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.cpp
@@ -42,8 +42,8 @@ namespace NKikimr {
}
// check whether this blob is huge one; userPartSize doesn't include any metadata stored along with blob
- bool THugeBlobCtx::IsHugeBlob(TBlobStorageGroupType gtype, const TLogoBlobID& fullId) const {
- return gtype.MaxPartSize(fullId) + TDiskBlob::HugeBlobOverhead >= MinREALHugeBlobInBytes;
+ bool THugeBlobCtx::IsHugeBlob(TBlobStorageGroupType gtype, const TLogoBlobID& fullId) const {
+ return gtype.MaxPartSize(fullId) + TDiskBlob::HugeBlobOverhead >= MinREALHugeBlobInBytes;
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h b/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h
index cb6c1233296..20c25373e97 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h
@@ -65,17 +65,17 @@ namespace NKikimr {
public:
// this value is multiply of AppendBlockSize and is calculated from Config->MinHugeBlobSize
const ui32 MinREALHugeBlobInBytes;
- const std::shared_ptr<const THugeSlotsMap> HugeSlotsMap;
+ const std::shared_ptr<const THugeSlotsMap> HugeSlotsMap;
// check whether this blob is huge one; userPartSize doesn't include any metadata stored along with blob
- bool IsHugeBlob(TBlobStorageGroupType gtype, const TLogoBlobID& fullId) const;
+ bool IsHugeBlob(TBlobStorageGroupType gtype, const TLogoBlobID& fullId) const;
- THugeBlobCtx(ui32 minREALHugeBlobInBytes, const std::shared_ptr<const THugeSlotsMap> &hugeSlotsMap)
+ THugeBlobCtx(ui32 minREALHugeBlobInBytes, const std::shared_ptr<const THugeSlotsMap> &hugeSlotsMap)
: MinREALHugeBlobInBytes(minREALHugeBlobInBytes)
, HugeSlotsMap(hugeSlotsMap)
{}
};
- using THugeBlobCtxPtr = std::shared_ptr<THugeBlobCtx>;
+ using THugeBlobCtxPtr = std::shared_ptr<THugeBlobCtx>;
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_log.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_log.cpp
index e7a3e8cc279..d3b1ef704fb 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_log.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_log.cpp
@@ -25,10 +25,10 @@ namespace NKikimr {
return prefix + formatted;
}
- TString GenerateVDiskLogPrefix(const TVDiskID &vdisk, bool donorMode) {
- return donorMode
- ? Sprintf("VDISK%s(DONOR): ", vdisk.ToString().data())
- : Sprintf("VDISK%s: ", vdisk.ToStringWOGeneration().data());
+ TString GenerateVDiskLogPrefix(const TVDiskID &vdisk, bool donorMode) {
+ return donorMode
+ ? Sprintf("VDISK%s(DONOR): ", vdisk.ToString().data())
+ : Sprintf("VDISK%s: ", vdisk.ToStringWOGeneration().data());
}
////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_log.h b/ydb/core/blobstorage/vdisk/common/vdisk_log.h
index c308e9a7a0d..86b3039e4c8 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_log.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_log.h
@@ -20,7 +20,7 @@ namespace NKikimr {
TString AppendVDiskLogPrefix(const TString &prefix, const char *c, ...);
struct TVDiskID;
- TString GenerateVDiskLogPrefix(const TVDiskID &vdisk, bool donorMode);
+ TString GenerateVDiskLogPrefix(const TVDiskID &vdisk, bool donorMode);
// logger
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h b/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h
index dde57d68b2e..349f572f667 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h
@@ -106,8 +106,8 @@ namespace NKikimr {
// AllocForSyncLog -- allocations to SyncLog
// Take into account that currently any allocation for SyncLog implies
// allocation for Hull. The opposite is wrong.
- std::unique_ptr<TLsnAllocTracker> AllocForHull;
- std::unique_ptr<TLsnAllocTracker> AllocForSyncLog;
+ std::unique_ptr<TLsnAllocTracker> AllocForHull;
+ std::unique_ptr<TLsnAllocTracker> AllocForSyncLog;
// basic lsn allocation
TLsnSeg AllocLsn(ui64 lsnAdvance = 1) {
@@ -142,8 +142,8 @@ namespace NKikimr {
CurrentLsnPtr = &CurrentLsn;
// Init trackers
- AllocForHull = std::make_unique<TLsnAllocTracker>(StartLsn);
- AllocForSyncLog = std::make_unique<TLsnAllocTracker>(lsnToSyncLogRecovered);
+ AllocForHull = std::make_unique<TLsnAllocTracker>(StartLsn);
+ AllocForSyncLog = std::make_unique<TLsnAllocTracker>(lsnToSyncLogRecovered);
}
TLsnMngr() = delete;
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr_ut.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr_ut.cpp
index b581b758bcb..c3e10fa50fc 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr_ut.cpp
@@ -88,9 +88,9 @@ namespace NKikimr {
TLsnMngr mngr(0, 0, false);
TParam p {&mngr, Its / threads};
auto start = Now();
- TVector<std::unique_ptr<TThread>> ts(threads);
+ TVector<std::unique_ptr<TThread>> ts(threads);
for (auto &t : ts) {
- t = std::make_unique<TThread>(&AllocLsnForLocalUseFunc, &p);
+ t = std::make_unique<TThread>(&AllocLsnForLocalUseFunc, &p);
}
for (auto &t : ts) {
t->Start();
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_mon.h b/ydb/core/blobstorage/vdisk/common/vdisk_mon.h
index ca1212b409b..c596ebdafd8 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_mon.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_mon.h
@@ -23,7 +23,7 @@ namespace NKikimr {
LocalRecovInfoId = 10,
AnubisRunnerId = 11,
DelayedHugeBlobDeleterId = 12,
- ScrubId = 13,
+ ScrubId = 13,
DbMainPageLogoBlobs = 14,
DbMainPageBlocks = 15,
DbMainPageBarriers = 16,
@@ -32,24 +32,24 @@ namespace NKikimr {
static const char *SubRequestIDToStr(int val) {
switch (val) {
- case SkeletonStateId: return "SkeletonStateId";
- case HullInfoId: return "HullInfoId";
- case SyncerInfoId: return "SyncerInfoId";
- case SyncLogId: return "SyncLogId";
- case ReplId: return "ReplId";
- case LogCutterId: return "LogCutterId";
- case HandoffMonId: return "HandoffMonId";
- case HugeKeeperId: return "HugeKeeperId";
- case DskSpaceTrackerId: return "DskSpaceTrackerId";
- case LocalRecovInfoId: return "LocalRecovInfoId";
- case DelayedHugeBlobDeleterId: return "DelayedHugeBlobDeleterId";
- case ScrubId: return "ScrubId";
+ case SkeletonStateId: return "SkeletonStateId";
+ case HullInfoId: return "HullInfoId";
+ case SyncerInfoId: return "SyncerInfoId";
+ case SyncLogId: return "SyncLogId";
+ case ReplId: return "ReplId";
+ case LogCutterId: return "LogCutterId";
+ case HandoffMonId: return "HandoffMonId";
+ case HugeKeeperId: return "HugeKeeperId";
+ case DskSpaceTrackerId: return "DskSpaceTrackerId";
+ case LocalRecovInfoId: return "LocalRecovInfoId";
+ case DelayedHugeBlobDeleterId: return "DelayedHugeBlobDeleterId";
+ case ScrubId: return "ScrubId";
case DbMainPageLogoBlobs: return "DbMainPageLogoBlobs";
case DbMainPageBlocks: return "DbMainPageBlocks";
case DbMainPageBarriers: return "DbMainPageBarriers";
case Defrag: return "Defrag";
}
- return "Unknown";
+ return "Unknown";
}
struct TDbLocalRecovery {
@@ -57,7 +57,7 @@ namespace NKikimr {
Initial,
YardInit,
LoadDb,
- LoadBulkFormedSegments,
+ LoadBulkFormedSegments,
ApplyLog,
Error,
Done
@@ -68,7 +68,7 @@ namespace NKikimr {
case Initial: return "Initial";
case YardInit: return "YardInit";
case LoadDb: return "LoadDb";
- case LoadBulkFormedSegments: return "LoadBulkFormedSegments";
+ case LoadBulkFormedSegments: return "LoadBulkFormedSegments";
case ApplyLog: return "ApplyLog";
case Error: return "Error";
case Done: return "Done";
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_mongroups.h b/ydb/core/blobstorage/vdisk/common/vdisk_mongroups.h
index aa1bff8f84e..7621c95ed12 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_mongroups.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_mongroups.h
@@ -209,10 +209,10 @@ public:
COUNTER_INIT(ReplUnreplicatedVDisks, false);
COUNTER_INIT(ReplUnreplicatedBlobs, false);
COUNTER_INIT(ReplVGetBytesReceived, true);
- COUNTER_INIT(ReplCurrentNumUnrecoveredPhantomBlobs, false);
- COUNTER_INIT(ReplCurrentNumUnrecoveredNonPhantomBlobs, false);
- COUNTER_INIT(ReplNumUnrecoveredPhantomBlobs, false);
- COUNTER_INIT(ReplNumUnrecoveredNonPhantomBlobs, false);
+ COUNTER_INIT(ReplCurrentNumUnrecoveredPhantomBlobs, false);
+ COUNTER_INIT(ReplCurrentNumUnrecoveredNonPhantomBlobs, false);
+ COUNTER_INIT(ReplNumUnrecoveredPhantomBlobs, false);
+ COUNTER_INIT(ReplNumUnrecoveredNonPhantomBlobs, false);
}
COUNTER_DEF(SyncerVSyncMessagesSent);
@@ -231,10 +231,10 @@ public:
COUNTER_DEF(ReplUnreplicatedVDisks);
COUNTER_DEF(ReplUnreplicatedBlobs);
COUNTER_DEF(ReplVGetBytesReceived);
- COUNTER_DEF(ReplCurrentNumUnrecoveredPhantomBlobs);
- COUNTER_DEF(ReplCurrentNumUnrecoveredNonPhantomBlobs);
- COUNTER_DEF(ReplNumUnrecoveredPhantomBlobs);
- COUNTER_DEF(ReplNumUnrecoveredNonPhantomBlobs);
+ COUNTER_DEF(ReplCurrentNumUnrecoveredPhantomBlobs);
+ COUNTER_DEF(ReplCurrentNumUnrecoveredNonPhantomBlobs);
+ COUNTER_DEF(ReplNumUnrecoveredPhantomBlobs);
+ COUNTER_DEF(ReplNumUnrecoveredNonPhantomBlobs);
};
///////////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_private_events.h b/ydb/core/blobstorage/vdisk/common/vdisk_private_events.h
index 7a1f8647832..1ea7f758803 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_private_events.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_private_events.h
@@ -76,31 +76,31 @@ namespace NKikimr {
// compaction has been finished.
////////////////////////////////////////////////////////////////////////////
struct TEvCompactVDisk : public TEventLocal<TEvCompactVDisk, TEvBlobStorage::EvCompactVDisk> {
- enum class EMode {
- FULL,
- FRESH_ONLY,
- };
-
+ enum class EMode {
+ FULL,
+ FRESH_ONLY,
+ };
+
// mask of databases to compact in terms of EHullDbType type (can compact several databases at once)
- const ui32 Mask;
- const EMode Mode;
+ const ui32 Mask;
+ const EMode Mode;
- TEvCompactVDisk(ui32 mask, EMode mode = EMode::FULL)
+ TEvCompactVDisk(ui32 mask, EMode mode = EMode::FULL)
: Mask(mask)
- , Mode(mode)
+ , Mode(mode)
{}
// create a message for compaction one database of type 'type'
- static TEvCompactVDisk *Create(EHullDbType type, EMode mode = EMode::FULL) {
- return new TEvCompactVDisk(::NKikimr::Mask(type), mode);
- }
-
- static const char *ModeToString(EMode mode) {
- switch (mode) {
- case EMode::FULL: return "FULL";
- case EMode::FRESH_ONLY: return "FRESH_ONLY";
- }
+ static TEvCompactVDisk *Create(EHullDbType type, EMode mode = EMode::FULL) {
+ return new TEvCompactVDisk(::NKikimr::Mask(type), mode);
}
+
+ static const char *ModeToString(EMode mode) {
+ switch (mode) {
+ case EMode::FULL: return "FULL";
+ case EMode::FRESH_ONLY: return "FRESH_ONLY";
+ }
+ }
};
////////////////////////////////////////////////////////////////////////////
@@ -117,20 +117,20 @@ namespace NKikimr {
// some database in local VDisk
////////////////////////////////////////////////////////////////////////////
struct TEvHullCompact : public TEventLocal<TEvHullCompact, TEvBlobStorage::EvHullCompact> {
- const EHullDbType Type;
- const ui64 RequestId;
- const TEvCompactVDisk::EMode Mode;
+ const EHullDbType Type;
+ const ui64 RequestId;
+ const TEvCompactVDisk::EMode Mode;
- TEvHullCompact(EHullDbType type, ui64 requestId, TEvCompactVDisk::EMode mode)
+ TEvHullCompact(EHullDbType type, ui64 requestId, TEvCompactVDisk::EMode mode)
: Type(type)
, RequestId(requestId)
- , Mode(mode)
+ , Mode(mode)
{}
- TString ToString() const {
- return TStringBuilder() << "{Type# " << EHullDbTypeToString(Type) << " RequestId# " << RequestId
- << " Mode# " << TEvCompactVDisk::ModeToString(Mode) << "}";
- }
+ TString ToString() const {
+ return TStringBuilder() << "{Type# " << EHullDbTypeToString(Type) << " RequestId# " << RequestId
+ << " Mode# " << TEvCompactVDisk::ModeToString(Mode) << "}";
+ }
};
////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_queues.h b/ydb/core/blobstorage/vdisk/common/vdisk_queues.h
index 9deed7fb435..4934c0fa25c 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_queues.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_queues.h
@@ -23,7 +23,7 @@ namespace NKikimr {
return gInfo->GetActorId(vdisk.VDiskIdShort);
}
- inline TActorId GetVDiskActorId(const std::pair<TVDiskID, TActorId> &p,
+ inline TActorId GetVDiskActorId(const std::pair<TVDiskID, TActorId> &p,
const TIntrusivePtr<NKikimr::TBlobStorageGroupInfo> &)
{
return p.second;
@@ -59,12 +59,12 @@ namespace NKikimr {
if (vdisk != vCtx->ShortSelfVDisk) {
TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord = MakeIntrusive<NBackpressure::TFlowRecord>();
TActorId vdiskActorId = GetVDiskActorId(vdiskInfo, gInfo);
- std::unique_ptr<IActor> queue;
- queue.reset(CreateVDiskBackpressureClient(gInfo, vdisk,
+ std::unique_ptr<IActor> queue;
+ queue.reset(CreateVDiskBackpressureClient(gInfo, vdisk,
vDiskQueueId, groupCounters, vCtx, queueClientId, queueName,
interconnectChannel, vdiskActorId.NodeId() == parent.NodeId(),
TDuration::Minutes(1), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
- TActorId serviceId = TActivationContext::Register(queue.release(), parent);
+ TActorId serviceId = TActivationContext::Register(queue.release(), parent);
EmplaceToContainer(cont, vdisk, wrapper.Wrap(std::move(serviceId)));
}
}
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_recoverylogwriter.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_recoverylogwriter.cpp
index f0ec9c15e40..456b70b4448 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_recoverylogwriter.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_recoverylogwriter.cpp
@@ -64,12 +64,12 @@ LWTRACE_USING(BLOBSTORAGE_PROVIDER);
// TQueueItem
////////////////////////////////////////////////////////////////////////////
struct TQueueItem {
- std::unique_ptr<IEventHandle> Ev;
+ std::unique_ptr<IEventHandle> Ev;
ui64 LsnSegmentStart;
ui64 Lsn;
- TQueueItem(std::unique_ptr<IEventHandle> ev, ui64 lsnSegmentStart, ui64 lsn)
- : Ev(std::move(ev))
+ TQueueItem(std::unique_ptr<IEventHandle> ev, ui64 lsnSegmentStart, ui64 lsn)
+ : Ev(std::move(ev))
, LsnSegmentStart(lsnSegmentStart)
, Lsn(lsn)
{
@@ -105,23 +105,23 @@ LWTRACE_USING(BLOBSTORAGE_PROVIDER);
const TQueueItem *item = nullptr;
while (!Queue.empty() && ((item = &Queue.top())->LsnSegmentStart == CurSentLsn + 1)) {
CurSentLsn = item->Lsn;
- std::unique_ptr<IEventHandle> ev = std::move(const_cast<TQueueItem*>(item)->Ev);
+ std::unique_ptr<IEventHandle> ev = std::move(const_cast<TQueueItem*>(item)->Ev);
ui32 type = ev->Type;
switch (type) {
- case TEvBlobStorage::EvLog:
- LWTRACK(VDiskRecoveryLogWriterVPutIsSent, ev->Get<NPDisk::TEvLog>()->Orbit, Owner, item->Lsn);
- break;
- case TEvBlobStorage::EvMultiLog:
- {
- NPDisk::TEvMultiLog *evLogs = ev->Get<NPDisk::TEvMultiLog>();
- for (auto &log : evLogs->Logs) {
- LWTRACK(VDiskRecoveryLogWriterVPutIsSent, log->Orbit, Owner, log->Lsn);
- }
- break;
+ case TEvBlobStorage::EvLog:
+ LWTRACK(VDiskRecoveryLogWriterVPutIsSent, ev->Get<NPDisk::TEvLog>()->Orbit, Owner, item->Lsn);
+ break;
+ case TEvBlobStorage::EvMultiLog:
+ {
+ NPDisk::TEvMultiLog *evLogs = ev->Get<NPDisk::TEvMultiLog>();
+ for (auto &log : evLogs->Logs) {
+ LWTRACK(VDiskRecoveryLogWriterVPutIsSent, log->Orbit, Owner, log->Lsn);
+ }
+ break;
}
}
Queue.pop();
- ctx.ExecutorThread.Send(ev.release());
+ ctx.ExecutorThread.Send(ev.release());
}
}
@@ -136,17 +136,17 @@ LWTRACE_USING(BLOBSTORAGE_PROVIDER);
*LsmLogBytesWritten += msgSize;
// update generic counters
Counters.Update(signature, msgSize);
- std::unique_ptr<IEventHandle> converted(ev->Forward(YardID).Release());
+ std::unique_ptr<IEventHandle> converted(ev->Forward(YardID).Release());
if (lsnSegmentStart == CurSentLsn + 1) {
// rewrite and send message;
LWTRACK(VDiskRecoveryLogWriterVPutIsSent, converted->Get<NPDisk::TEvLog>()->Orbit, Owner, lsn);
- ctx.ExecutorThread.Send(converted.release());
+ ctx.ExecutorThread.Send(converted.release());
CurSentLsn = lsn;
// proceed with elements waiting in the queue
ProcessQueue(ctx);
} else {
- Queue.push(TQueueItem(std::move(converted), lsnSegmentStart, lsn));
+ Queue.push(TQueueItem(std::move(converted), lsnSegmentStart, lsn));
}
}
@@ -170,16 +170,16 @@ LWTRACE_USING(BLOBSTORAGE_PROVIDER);
Counters.Update(signature, msgSize);
LWTRACK(VDiskRecoveryLogWriterVPutIsSent, log->Orbit, Owner, lsn);
}
- std::unique_ptr<IEventHandle> converted(ev->Forward(YardID).Release());
+ std::unique_ptr<IEventHandle> converted(ev->Forward(YardID).Release());
if (lsnSegmentStart == CurSentLsn + 1) {
// rewrite and send message;
- ctx.ExecutorThread.Send(converted.release());
+ ctx.ExecutorThread.Send(converted.release());
CurSentLsn = lsn;
// proceed with elements waiting in the queue
ProcessQueue(ctx);
} else {
- Queue.push(TQueueItem(std::move(converted), lsnSegmentStart, lsn));
+ Queue.push(TQueueItem(std::move(converted), lsnSegmentStart, lsn));
}
}
@@ -194,16 +194,16 @@ LWTRACE_USING(BLOBSTORAGE_PROVIDER);
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvLog, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvLog, Handle)
HFunc(NPDisk::TEvMultiLog, Handle)
- HFunc(TEvBlobStorage::TEvVCompact, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvBlobStorage::TEvVCompact, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_RECOVERY_LOG_WRITER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_RECOVERY_LOG_WRITER;
}
TRecoveryLogWriter(const TActorId &yardID, const TActorId &skeletonID,
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_response.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_response.cpp
index 384931d3051..a2eebf7adbd 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_response.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_response.cpp
@@ -6,43 +6,43 @@
namespace NKikimr {
-void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
- ui64 cookie) {
- ui32 channel = TInterconnectChannels::IC_BLOBSTORAGE;
- if (TEvVResultBase *base = dynamic_cast<TEvVResultBase *>(ev)) {
- channel = base->GetChannelToSend();
- }
- SendVDiskResponse(ctx, recipient, ev, actor, cookie, channel);
-}
-
-void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
- ui64 cookie, ui32 channel) {
- NWilson::TTraceId traceId;
-
- switch (const ui32 type = ev->Type()) {
-#define WILSON_HANDLE_EVENT(T, EV) \
- case TEvBlobStorage::T::EventType: { \
- TEvBlobStorage::T *event = static_cast<TEvBlobStorage::T *>(ev); \
- traceId = std::move(event->TraceId); \
- WILSON_TRACE_FROM_ACTOR(ctx, actor, &traceId, EV); \
+void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
+ ui64 cookie) {
+ ui32 channel = TInterconnectChannels::IC_BLOBSTORAGE;
+ if (TEvVResultBase *base = dynamic_cast<TEvVResultBase *>(ev)) {
+ channel = base->GetChannelToSend();
+ }
+ SendVDiskResponse(ctx, recipient, ev, actor, cookie, channel);
+}
+
+void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
+ ui64 cookie, ui32 channel) {
+ NWilson::TTraceId traceId;
+
+ switch (const ui32 type = ev->Type()) {
+#define WILSON_HANDLE_EVENT(T, EV) \
+ case TEvBlobStorage::T::EventType: { \
+ TEvBlobStorage::T *event = static_cast<TEvBlobStorage::T *>(ev); \
+ traceId = std::move(event->TraceId); \
+ WILSON_TRACE_FROM_ACTOR(ctx, actor, &traceId, EV); \
const double usPerCycle = 1000000.0 / NHPTimer::GetCyclesPerSecond(); \
event->Record.MutableTimestamps()->SetSentByVDiskUs(GetCycleCountFast() * usPerCycle); \
- break; \
- }
-
- WILSON_HANDLE_EVENT(TEvVPutResult, EvVPutResultSent)
+ break; \
+ }
+
+ WILSON_HANDLE_EVENT(TEvVPutResult, EvVPutResultSent)
WILSON_HANDLE_EVENT(TEvVMultiPutResult, EvVMultiPutResultSent)
- WILSON_HANDLE_EVENT(TEvVGetResult, EvVGetResultSent)
-
-#undef WILSON_HANDLE_EVENT
- }
-
- auto event = std::make_unique<IEventHandle>(recipient, ctx.SelfID, ev, IEventHandle::MakeFlags(channel, 0), cookie,
- nullptr, std::move(traceId));
+ WILSON_HANDLE_EVENT(TEvVGetResult, EvVGetResultSent)
+
+#undef WILSON_HANDLE_EVENT
+ }
+
+ auto event = std::make_unique<IEventHandle>(recipient, ctx.SelfID, ev, IEventHandle::MakeFlags(channel, 0), cookie,
+ nullptr, std::move(traceId));
if (TEvVResultBase *base = dynamic_cast<TEvVResultBase *>(ev)) {
- base->FinalizeAndSend(ctx, std::move(event));
- } else {
- TActivationContext::Send(event.release());
+ base->FinalizeAndSend(ctx, std::move(event));
+ } else {
+ TActivationContext::Send(event.release());
}
}
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_response.h b/ydb/core/blobstorage/vdisk/common/vdisk_response.h
index 1ac0452b8e5..3a9a88b7aaa 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_response.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_response.h
@@ -3,10 +3,10 @@
namespace NKikimr {
-void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
+void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
ui64 cookie);
-void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
+void SendVDiskResponse(const TActorContext &ctx, const TActorId &recipient, IEventBase *ev, const IActor& actor,
ui64 cookie, ui32 channel);
}//NKikimr
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors.h b/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors.h
index b014da97b04..d5c1a5f8a3a 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors.h
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors.h
@@ -6,7 +6,7 @@
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
#include <ydb/core/util/iterator.h>
-
+
#include <util/generic/vector.h>
#include <util/stream/str.h>
#include <library/cpp/monlib/service/pages/templates.h>
@@ -29,22 +29,22 @@ namespace NKikimr {
const bool MyFailDomain;
const bool Myself;
const ui32 OrderNumber;
- const ui32 DomainOrderNumber;
-
+ const ui32 DomainOrderNumber;
+
private:
T Payload;
public:
TVDiskInfo(const TVDiskIdShort &vdiskShort,
bool myFailDomain,
- bool myself,
+ bool myself,
const ui32 orderNumber,
- const ui32 domainOrderNumber)
+ const ui32 domainOrderNumber)
: VDiskIdShort(vdiskShort)
, MyFailDomain(myFailDomain)
, Myself(myself)
, OrderNumber(orderNumber)
- , DomainOrderNumber(domainOrderNumber)
+ , DomainOrderNumber(domainOrderNumber)
{}
TString ToString() const {
@@ -69,28 +69,28 @@ namespace NKikimr {
using TValue = TVDiskInfo<T>;
using TThis = TVDiskNeighbors<T>;
- // TNeighbors contains nested vectors of FailRealms, FailDomains and VDisks inside them; e.g.
- // [ FailRealm0:[ FailDomain0:[ VDisk_0_0_0 VDisk_0_0_1 ] FailDomain1:[ VDisk_0_1_0 ... ] ] ]
- // that is TNeighbors[vdisk.FailRealm][vdisk.FailDomain][vdisk.VDisk] contains per-VDisk metadata
+ // TNeighbors contains nested vectors of FailRealms, FailDomains and VDisks inside them; e.g.
+ // [ FailRealm0:[ FailDomain0:[ VDisk_0_0_0 VDisk_0_0_1 ] FailDomain1:[ VDisk_0_1_0 ... ] ] ]
+ // that is TNeighbors[vdisk.FailRealm][vdisk.FailDomain][vdisk.VDisk] contains per-VDisk metadata
using TNeighbors = TVector<TVector<TVector<TValue>>>;
-
+
template<bool Const>
class TFailDomainIteratorImpl;
-
+
TVDiskNeighbors(const TVDiskIdShort &self,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
- : Self(self)
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
+ : Self(self)
, Erasure(top->GType.GetErasure())
{
Setup(top);
}
TValue &operator [](const TVDiskIdShort &vdisk) {
- return Neighbors.at(vdisk.FailRealm).at(vdisk.FailDomain).at(vdisk.VDisk);
+ return Neighbors.at(vdisk.FailRealm).at(vdisk.FailDomain).at(vdisk.VDisk);
}
const TValue &operator [](const TVDiskIdShort &vdisk) const {
- return Neighbors.at(vdisk.FailRealm).at(vdisk.FailDomain).at(vdisk.VDisk);
+ return Neighbors.at(vdisk.FailRealm).at(vdisk.FailDomain).at(vdisk.VDisk);
}
ui32 GetTotalDisks() const {
@@ -104,7 +104,7 @@ namespace NKikimr {
template<bool Const>
bool IsMyFailDomain(const TFailDomainIteratorImpl<Const>& it) const {
- return it == GetMyFailDomainIter();
+ return it == GetMyFailDomainIter();
}
///////////////////////////////////////////////////////////////////////////
@@ -114,66 +114,66 @@ namespace NKikimr {
class TIteratorImpl
: public TIteratorFacade<TIteratorImpl<Const>,
typename std::conditional<Const,
- const TValue,
- TValue>::type>
+ const TValue,
+ TValue>::type>
{
using TNeighbors = typename std::conditional<Const,
- const typename TVDiskNeighbors::TNeighbors,
- typename TVDiskNeighbors::TNeighbors>::type;
-
+ const typename TVDiskNeighbors::TNeighbors,
+ typename TVDiskNeighbors::TNeighbors>::type;
+
using TValue = typename std::conditional<Const,
- const typename TVDiskNeighbors::TVDiskNeighbors::TValue,
- typename TVDiskNeighbors::TValue>::type;
-
- using TFailDomainIterator = TFailDomainIteratorImpl<Const>;
-
- TFailDomainIterator FailDomainIter;
- ui32 VDisk;
-
+ const typename TVDiskNeighbors::TVDiskNeighbors::TValue,
+ typename TVDiskNeighbors::TValue>::type;
+
+ using TFailDomainIterator = TFailDomainIteratorImpl<Const>;
+
+ TFailDomainIterator FailDomainIter;
+ ui32 VDisk;
+
public:
using value_type = TValue;
using reference = value_type&;
using pointer = value_type*;
using difference_type = std::size_t;
using iterator_category = std::forward_iterator_tag;
- TIteratorImpl(const TFailDomainIterator& failDomainIter, ui32 vdisk)
- : FailDomainIter(failDomainIter)
- , VDisk(vdisk)
+ TIteratorImpl(const TFailDomainIterator& failDomainIter, ui32 vdisk)
+ : FailDomainIter(failDomainIter)
+ , VDisk(vdisk)
{}
private:
friend struct TIteratorFacade<TIteratorImpl, TValue>;
-
+
TValue& Dereference() const {
- auto& vec = FailDomainIter.GetVDiskVector();
- return vec[VDisk];
+ auto& vec = FailDomainIter.GetVDiskVector();
+ return vec[VDisk];
}
-
+
void MoveNext() {
- const auto& vec = FailDomainIter.GetVDiskVector();
+ const auto& vec = FailDomainIter.GetVDiskVector();
if (++VDisk == vec.size()) {
- VDisk = 0;
- ++FailDomainIter;
+ VDisk = 0;
+ ++FailDomainIter;
}
}
template<bool OtherConst>
bool EqualTo(const TIteratorImpl<OtherConst>& other) const {
- return FailDomainIter == other.FailDomainIter && VDisk == other.VDisk;
+ return FailDomainIter == other.FailDomainIter && VDisk == other.VDisk;
}
size_t DistanceTo(const TIteratorImpl& other) const {
size_t rv = 0;
- ui32 offset = VDisk;
- TFailDomainIterator iter(FailDomainIter);
- while (iter != other.FailDomainIter) {
+ ui32 offset = VDisk;
+ TFailDomainIterator iter(FailDomainIter);
+ while (iter != other.FailDomainIter) {
rv += iter.GetVDiskVector().size() - offset;
- ++iter;
- offset = 0;
+ ++iter;
+ offset = 0;
}
- rv += other.VDisk - offset;
+ rv += other.VDisk - offset;
return rv;
- }
+ }
};
///////////////////////////////////////////////////////////////////////////
@@ -190,13 +190,13 @@ namespace NKikimr {
: public TIteratorFacade<TFailDomainIteratorImpl<Const>, TVDiskRangeImpl<Const>, TVDiskRangeImpl<Const>>
{
using TNeighbors = typename std::conditional<Const,
- const typename TVDiskNeighbors::TNeighbors,
- typename TVDiskNeighbors::TNeighbors>::type;
-
- using TValue = typename std::conditional<Const,
- const typename TVDiskNeighbors::TValue,
- typename TVDiskNeighbors::TValue>::type;
+ const typename TVDiskNeighbors::TNeighbors,
+ typename TVDiskNeighbors::TNeighbors>::type;
+ using TValue = typename std::conditional<Const,
+ const typename TVDiskNeighbors::TValue,
+ typename TVDiskNeighbors::TValue>::type;
+
// alias for VDisk range class
using TVDiskRange = TVDiskRangeImpl<Const>;
@@ -204,7 +204,7 @@ namespace NKikimr {
using TIterator = TIteratorImpl<Const>;
TNeighbors &Ref;
- ui32 FailRealm;
+ ui32 FailRealm;
ui32 FailDomain;
public:
@@ -213,55 +213,55 @@ namespace NKikimr {
using pointer = value_type*;
using difference_type = std::size_t;
using iterator_category = std::forward_iterator_tag;
- TFailDomainIteratorImpl(TNeighbors &ref, ui32 ring, ui32 failDomain)
+ TFailDomainIteratorImpl(TNeighbors &ref, ui32 ring, ui32 failDomain)
: Ref(ref)
- , FailRealm(ring)
+ , FailRealm(ring)
, FailDomain(failDomain)
{}
- private:
- friend class TVDiskNeighbors;
-
- ui32 GetFailRealmIndex() const {
- return FailRealm;
- }
-
- ui32 GetFailDomainIndex() const {
+ private:
+ friend class TVDiskNeighbors;
+
+ ui32 GetFailRealmIndex() const {
+ return FailRealm;
+ }
+
+ ui32 GetFailDomainIndex() const {
return FailDomain;
}
private:
- template<bool OtherConst>
- friend class TIteratorImpl;
-
- using TVDiskVector = typename std::conditional<Const,
- const typename TNeighbors::value_type::value_type,
- typename TNeighbors::value_type::value_type>::type;
-
- TVDiskVector& GetVDiskVector() const {
- return Ref[FailRealm][FailDomain];
- }
-
- private:
+ template<bool OtherConst>
+ friend class TIteratorImpl;
+
+ using TVDiskVector = typename std::conditional<Const,
+ const typename TNeighbors::value_type::value_type,
+ typename TNeighbors::value_type::value_type>::type;
+
+ TVDiskVector& GetVDiskVector() const {
+ return Ref[FailRealm][FailDomain];
+ }
+
+ private:
friend struct TIteratorFacade<TFailDomainIteratorImpl, TVDiskRangeImpl<Const>, TVDiskRangeImpl<Const>>;
TVDiskRange Dereference() const {
- TIterator begin(*this, 0);
- TIterator end(++TFailDomainIteratorImpl(*this), 0);
+ TIterator begin(*this, 0);
+ TIterator end(++TFailDomainIteratorImpl(*this), 0);
return TVDiskRange(begin, end);
}
void MoveNext() {
if (++FailDomain == Ref[FailRealm].size()) {
- FailDomain = 0;
- ++FailRealm;
- }
+ FailDomain = 0;
+ ++FailRealm;
+ }
}
template<bool OtherConst>
bool EqualTo(const TFailDomainIteratorImpl<OtherConst>& other) const {
Y_VERIFY(&Ref == &other.Ref);
- return FailRealm == other.FailRealm && FailDomain == other.FailDomain;
+ return FailRealm == other.FailRealm && FailDomain == other.FailDomain;
}
};
@@ -276,27 +276,27 @@ namespace NKikimr {
using TFailDomainIterator = TFailDomainIteratorImpl<false>;
using TConstFailDomainIterator = TFailDomainIteratorImpl<true>;
-
- TFailDomainIterator GetMyFailDomainIter() {
- return TFailDomainIterator(Neighbors, Self.FailRealm, Self.FailDomain);
- }
-
- TConstFailDomainIterator GetMyFailDomainIter() const {
- return TConstFailDomainIterator(Neighbors, Self.FailRealm, Self.FailDomain);
- }
-
+
+ TFailDomainIterator GetMyFailDomainIter() {
+ return TFailDomainIterator(Neighbors, Self.FailRealm, Self.FailDomain);
+ }
+
+ TConstFailDomainIterator GetMyFailDomainIter() const {
+ return TConstFailDomainIterator(Neighbors, Self.FailRealm, Self.FailDomain);
+ }
+
TFailDomainRangeImpl<true> GetFailDomains() const {
- return TFailDomainRangeImpl<true>(TConstFailDomainIterator(Neighbors, 0, 0),
+ return TFailDomainRangeImpl<true>(TConstFailDomainIterator(Neighbors, 0, 0),
TConstFailDomainIterator(Neighbors, Neighbors.size(), 0));
}
-
+
TFailDomainRangeImpl<false> GetFailDomains() {
- return TFailDomainRangeImpl<false>(TFailDomainIterator(Neighbors, 0, 0),
+ return TFailDomainRangeImpl<false>(TFailDomainIterator(Neighbors, 0, 0),
TFailDomainIterator(Neighbors, Neighbors.size(), 0));
}
-
+
TIterator Begin() {
- return TIterator(TFailDomainIterator(Neighbors, 0, 0), 0);
+ return TIterator(TFailDomainIterator(Neighbors, 0, 0), 0);
}
TIterator begin() {
@@ -304,7 +304,7 @@ namespace NKikimr {
}
TConstIterator Begin() const {
- return TConstIterator(TConstFailDomainIterator(Neighbors, 0, 0), 0);
+ return TConstIterator(TConstFailDomainIterator(Neighbors, 0, 0), 0);
}
TConstIterator begin() const {
@@ -379,30 +379,30 @@ namespace NKikimr {
public:
const TVDiskIdShort Self;
const TErasureType::EErasureSpecies Erasure;
-
+
protected:
TNeighbors Neighbors;
ui32 TotalDisks = 0;
ui32 DisksInDomain = 0;
- void Setup(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top) {
+ void Setup(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top) {
Neighbors.resize(top->GetTotalFailRealmsNum());
for (auto realmIt = top->FailRealmsBegin(), realmEnd = top->FailRealmsEnd(); realmIt != realmEnd; ++realmIt) {
- auto& realm = Neighbors[realmIt.GetFailRealmIdx()];
- realm.resize(realmIt.GetNumFailDomainsPerFailRealm());
- for (auto domIt = realmIt.FailRealmFailDomainsBegin(), domEnd = realmIt.FailRealmFailDomainsEnd();
- domIt != domEnd; ++domIt) {
- auto& domain = realm[domIt.GetFailDomainIdx()];
+ auto& realm = Neighbors[realmIt.GetFailRealmIdx()];
+ realm.resize(realmIt.GetNumFailDomainsPerFailRealm());
+ for (auto domIt = realmIt.FailRealmFailDomainsBegin(), domEnd = realmIt.FailRealmFailDomainsEnd();
+ domIt != domEnd; ++domIt) {
+ auto& domain = realm[domIt.GetFailDomainIdx()];
const bool myFailDomain = top->GetFailDomainOrderNumber(Self) == domIt->FailDomainOrderNumber;
- for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
+ for (const auto& vdisk : domIt.GetFailDomainVDisks()) {
const bool myself = Self == vdisk.VDiskIdShort;
domain.emplace_back(vdisk.VDiskIdShort, myFailDomain, myself,
vdisk.OrderNumber, vdisk.FailDomainOrderNumber);
- TotalDisks++;
- }
- }
+ TotalDisks++;
+ }
+ }
}
-
+
bool first = true;
for (const auto& vdisks : GetFailDomains()) {
const ui32 numDisks = vdisks.end() - vdisks.begin();
@@ -411,11 +411,11 @@ namespace NKikimr {
} else {
Y_VERIFY(DisksInDomain == numDisks);
}
- }
+ }
Y_VERIFY(top->GType.GetErasure() == TBlobStorageGroupType::ErasureNone || TotalDisks > 2);
- }
-
+ }
+
template <class TPrinter>
void OutputHtmlTableBody(IOutputStream &str, TPrinter &printer, TVector<TConstIterator> &its) const {
HTML(str) {
@@ -425,13 +425,13 @@ namespace NKikimr {
// column iterator -- one entry for each domain in "its"
typename TVector<TConstIterator>::iterator colIt = its.begin();
- for (const auto& vdisks : GetFailDomains()) {
+ for (const auto& vdisks : GetFailDomains()) {
TABLED() {
- TConstIterator& x = *colIt++;
- printer(str, x++);
- if (row + 1 == DisksInDomain) {
- Y_VERIFY(x == vdisks.end());
- }
+ TConstIterator& x = *colIt++;
+ printer(str, x++);
+ if (row + 1 == DisksInDomain) {
+ Y_VERIFY(x == vdisks.end());
+ }
}
}
}
@@ -456,7 +456,7 @@ namespace NKikimr {
TVDiskNeighborsSerializable(const TVDiskIdShort &self,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
: TBase(self, top)
{}
diff --git a/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors_ut.cpp b/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors_ut.cpp
index e03e6a461c8..64b24dabaed 100644
--- a/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/common/vdisk_syncneighbors_ut.cpp
@@ -1,37 +1,37 @@
#include <library/cpp/testing/unittest/registar.h>
#include "vdisk_syncneighbors.h"
-
-using namespace NKikimr;
-using namespace NSync;
-
-namespace {
- TIntrusivePtr<TBlobStorageGroupInfo> CreateTestGroup(ui32 numDomains, ui32 numFailRealms) {
- return new TBlobStorageGroupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 5, numDomains, numFailRealms);
- }
-
+
+using namespace NKikimr;
+using namespace NSync;
+
+namespace {
+ TIntrusivePtr<TBlobStorageGroupInfo> CreateTestGroup(ui32 numDomains, ui32 numFailRealms) {
+ return new TBlobStorageGroupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 5, numDomains, numFailRealms);
+ }
+
TVector<TVDiskID> GetVDisks(const TIntrusivePtr<TBlobStorageGroupInfo>& info) {
TVector<TVDiskID> ret;
- for (const auto& x : info->GetVDisks()) {
+ for (const auto& x : info->GetVDisks()) {
auto vd = info->GetVDiskId(x.OrderNumber);
ret.push_back(vd);
- }
- return ret;
- }
-
- struct TPayload {
- ui32 Value = 0;
-
- TPayload() = default;
-
- TPayload(ui32 value)
- : Value(value)
- {}
-
+ }
+ return ret;
+ }
+
+ struct TPayload {
+ ui32 Value = 0;
+
+ TPayload() = default;
+
+ TPayload(ui32 value)
+ : Value(value)
+ {}
+
bool operator ==(const TPayload& other) const {
return Value == other.Value;
- }
+ }
};
-
+
class TSer {
public:
TSer(IOutputStream &str)
@@ -56,7 +56,7 @@ namespace {
void operator() (TVDiskInfo<TPayload> &val) {
Load(&Str, val.Get().Value);
- }
+ }
void Finish() {
char c = '\0';
@@ -66,68 +66,68 @@ namespace {
private:
IInputStream &Str;
- };
-
-}
+ };
+}
+
Y_UNIT_TEST_SUITE(TBlobStorageSyncNeighborsTest) {
-
+
Y_UNIT_TEST(IterateOverAllDisks) {
- const ui32 numDomains = 8;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
+ const ui32 numDomains = 8;
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
TVector<TVDiskID> vdisks = GetVDisks(info);
- const TVDiskID& self = vdisks[0];
+ const TVDiskID& self = vdisks[0];
TVDiskNeighbors<TPayload> neighbors(self, info->PickTopology());
-
+
THashSet<TVDiskID> temp(vdisks.begin(), vdisks.end());
- for (const auto& item : neighbors) {
+ for (const auto& item : neighbors) {
const size_t count = temp.erase(TVDiskID(info->GroupID, info->GroupGeneration, item.VDiskIdShort));
- UNIT_ASSERT_VALUES_EQUAL(count, 1);
- }
- UNIT_ASSERT_VALUES_EQUAL(temp.size(), 0);
- }
-
+ UNIT_ASSERT_VALUES_EQUAL(count, 1);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(temp.size(), 0);
+ }
+
Y_UNIT_TEST(CheckRevLookup) {
- const ui32 numDomains = 8;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
+ const ui32 numDomains = 8;
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
TVector<TVDiskID> vdisks = GetVDisks(info);
- const TVDiskID& self = vdisks[0];
+ const TVDiskID& self = vdisks[0];
TVDiskNeighbors<TPayload> neighbors(self, info->PickTopology());
-
- for (const TVDiskID& vdisk : vdisks) {
+
+ for (const TVDiskID& vdisk : vdisks) {
UNIT_ASSERT_EQUAL(TVDiskIdShort(vdisk), neighbors[vdisk].VDiskIdShort);
- }
- }
-
+ }
+ }
+
Y_UNIT_TEST(CheckIsMyDomain) {
- const ui32 numDomains = 8;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
+ const ui32 numDomains = 8;
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
TVector<TVDiskID> vdisks = GetVDisks(info);
- const TVDiskID& self = vdisks[0];
+ const TVDiskID& self = vdisks[0];
TVDiskNeighbors<TPayload> neighbors(self, info->PickTopology());
-
- for (ui32 i = 0; i < numDomains; ++i) {
- auto domains = neighbors.GetFailDomains();
- auto it = domains.begin();
- for (ui32 k = 0; k < i; ++k) {
- ++it;
- }
- UNIT_ASSERT_VALUES_EQUAL(neighbors.IsMyFailDomain(it), i == self.FailDomain);
- }
- }
-
+
+ for (ui32 i = 0; i < numDomains; ++i) {
+ auto domains = neighbors.GetFailDomains();
+ auto it = domains.begin();
+ for (ui32 k = 0; k < i; ++k) {
+ ++it;
+ }
+ UNIT_ASSERT_VALUES_EQUAL(neighbors.IsMyFailDomain(it), i == self.FailDomain);
+ }
+ }
+
Y_UNIT_TEST(SerDes) {
- const ui32 numDomains = 8;
- TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
+ const ui32 numDomains = 8;
+ TIntrusivePtr<TBlobStorageGroupInfo> info = CreateTestGroup(numDomains, 2);
TVector<TVDiskID> vdisks = GetVDisks(info);
- const TVDiskID& self = vdisks[0];
+ const TVDiskID& self = vdisks[0];
TVDiskNeighborsSerializable<TPayload> neighbors(self, info->PickTopology());
-
- ui32 index = 0;
- for (const TVDiskID& vdisk : vdisks) {
- neighbors[vdisk].Get() = index++;
- }
-
+
+ ui32 index = 0;
+ for (const TVDiskID& vdisk : vdisks) {
+ neighbors[vdisk].Get() = index++;
+ }
+
// serialize
TStringStream outputStream;
TSer ser(outputStream);
@@ -137,68 +137,68 @@ Y_UNIT_TEST_SUITE(TBlobStorageSyncNeighborsTest) {
TStringInput inp(outputStream.Str());
TDes des(inp);
n2.GenericParse(des);
- for (const TVDiskID& vdisk : vdisks) {
- UNIT_ASSERT_EQUAL(neighbors[vdisk].Get(), n2[vdisk].Get());
- }
- }
-
+ for (const TVDiskID& vdisk : vdisks) {
+ UNIT_ASSERT_EQUAL(neighbors[vdisk].Get(), n2[vdisk].Get());
+ }
+ }
+
Y_UNIT_TEST(CheckVDiskIterators) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
- const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
- for (ui32 i = 0; i < topo.GetTotalVDisksNum(); ++i) {
- const TVDiskIdShort& self = topo.GetVDiskId(i);
- TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
-
- auto it1 = info.VDisksBegin();
- auto it2 = neighbors.Begin();
- while (it1 != info.VDisksEnd() && it2 != neighbors.End()) {
- UNIT_ASSERT_EQUAL(it1->VDiskIdShort, it2->VDiskIdShort);
- ++it1, ++it2;
- }
- UNIT_ASSERT_EQUAL(it1, info.VDisksEnd());
- UNIT_ASSERT_EQUAL(it2, neighbors.End());
- }
- }
-
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
+ const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
+ for (ui32 i = 0; i < topo.GetTotalVDisksNum(); ++i) {
+ const TVDiskIdShort& self = topo.GetVDiskId(i);
+ TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
+
+ auto it1 = info.VDisksBegin();
+ auto it2 = neighbors.Begin();
+ while (it1 != info.VDisksEnd() && it2 != neighbors.End()) {
+ UNIT_ASSERT_EQUAL(it1->VDiskIdShort, it2->VDiskIdShort);
+ ++it1, ++it2;
+ }
+ UNIT_ASSERT_EQUAL(it1, info.VDisksEnd());
+ UNIT_ASSERT_EQUAL(it2, neighbors.End());
+ }
+ }
+
Y_UNIT_TEST(CheckFailDomainsIterators) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
- const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
- for (ui32 i = 0; i < topo.GetTotalVDisksNum(); ++i) {
- const TVDiskIdShort& self = topo.GetVDiskId(i);
- TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
- const auto& range = neighbors.GetFailDomains();
- size_t index = 0;
- for (auto it = range.begin(); it != range.end(); ++it, ++index) {
- auto fd = info.FailDomainsBegin();
- for (size_t i = 0; i < index; ++i) {
- ++fd;
- }
-
- const auto& range = *it;
- auto it1 = fd.FailDomainVDisksBegin();
- auto it2 = range.begin();
- while (it1 != fd.FailDomainVDisksEnd() && it2 != range.end()) {
- UNIT_ASSERT_EQUAL(it1->VDiskIdShort, it2->VDiskIdShort);
- ++it1, ++it2;
- }
- UNIT_ASSERT_EQUAL(it1, fd.FailDomainVDisksEnd());
- UNIT_ASSERT_EQUAL(it2, range.end());
- }
- }
- }
-
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
+ const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
+ for (ui32 i = 0; i < topo.GetTotalVDisksNum(); ++i) {
+ const TVDiskIdShort& self = topo.GetVDiskId(i);
+ TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
+ const auto& range = neighbors.GetFailDomains();
+ size_t index = 0;
+ for (auto it = range.begin(); it != range.end(); ++it, ++index) {
+ auto fd = info.FailDomainsBegin();
+ for (size_t i = 0; i < index; ++i) {
+ ++fd;
+ }
+
+ const auto& range = *it;
+ auto it1 = fd.FailDomainVDisksBegin();
+ auto it2 = range.begin();
+ while (it1 != fd.FailDomainVDisksEnd() && it2 != range.end()) {
+ UNIT_ASSERT_EQUAL(it1->VDiskIdShort, it2->VDiskIdShort);
+ ++it1, ++it2;
+ }
+ UNIT_ASSERT_EQUAL(it1, fd.FailDomainVDisksEnd());
+ UNIT_ASSERT_EQUAL(it2, range.end());
+ }
+ }
+ }
+
Y_UNIT_TEST(CheckVDiskDistance) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
- const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
- const TVDiskIdShort& self = topo.GetVDiskId(0);
- TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
-
- for (auto it1 = neighbors.Begin(); it1 != neighbors.End(); ++it1) {
- size_t expectedDistance = 0;
- for (auto it2 = it1; it2 != neighbors.End(); ++it2, ++expectedDistance) {
- UNIT_ASSERT_VALUES_EQUAL(it2 - it1, expectedDistance);
- }
- }
- }
-
-}
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3dc, 2, 3, 3);
+ const TBlobStorageGroupInfo::TTopology& topo = info.GetTopology();
+ const TVDiskIdShort& self = topo.GetVDiskId(0);
+ TVDiskNeighbors<TPayload> neighbors(self, info.PickTopology());
+
+ for (auto it1 = neighbors.Begin(); it1 != neighbors.End(); ++it1) {
+ size_t expectedDistance = 0;
+ for (auto it2 = it1; it2 != neighbors.End(); ++it2, ++expectedDistance) {
+ UNIT_ASSERT_VALUES_EQUAL(it2 - it1, expectedDistance);
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_actor.cpp b/ydb/core/blobstorage/vdisk/defrag/defrag_actor.cpp
index 4916a059414..4a2e1595e3f 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_actor.cpp
@@ -1,12 +1,12 @@
#include "defrag_actor.h"
#include "defrag_quantum.h"
-#include "defrag_search.h"
+#include "defrag_search.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_context.h>
#include <ydb/core/blobstorage/vdisk/common/circlebufstream.h>
#include <ydb/core/blobstorage/vdisk/common/sublog.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_hugeblobctx.h>
#include <ydb/core/blobstorage/vdisk/skeleton/blobstorage_takedbsnap.h>
-#include <library/cpp/actors/core/invoke.h>
+#include <library/cpp/actors/core/invoke.h>
namespace NKikimr {
@@ -15,7 +15,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
TDefragCtx::TDefragCtx(
const TIntrusivePtr<TVDiskContext> &vctx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TPDiskCtxPtr &pdiskCtx,
const TActorId &skeletonId,
const TActorId &hugeKeeperId,
@@ -31,14 +31,14 @@ namespace NKikimr {
TDefragCtx::~TDefragCtx() = default;
- struct TEvDefragStartQuantum : TEventLocal<TEvDefragStartQuantum, TEvBlobStorage::EvDefragStartQuantum> {
- TChunksToDefrag ChunksToDefrag;
-
- TEvDefragStartQuantum(TChunksToDefrag chunksToDefrag)
- : ChunksToDefrag(std::move(chunksToDefrag))
- {}
- };
-
+ struct TEvDefragStartQuantum : TEventLocal<TEvDefragStartQuantum, TEvBlobStorage::EvDefragStartQuantum> {
+ TChunksToDefrag ChunksToDefrag;
+
+ TEvDefragStartQuantum(TChunksToDefrag chunksToDefrag)
+ : ChunksToDefrag(std::move(chunksToDefrag))
+ {}
+ };
+
////////////////////////////////////////////////////////////////////////////
// HugeHeapDefragmentationRequired
// We calculate allowd percent of garbage as a percent of chunks
@@ -71,114 +71,114 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TDefragLocalSheduler : public TActorBootstrapped<TDefragLocalSheduler> {
friend class TActorBootstrapped<TDefragLocalSheduler>;
- std::shared_ptr<TDefragCtx> DCtx;
- const TActorId DefragActorId;
- TActorId PlannerId;
- TDuration PauseMin = TDuration::Minutes(5);
- TDuration PauseMax = PauseMin + TDuration::Seconds(30);
-
- enum {
- EvResume = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- class TDefragPlannerActor : public TActorBootstrapped<TDefragPlannerActor> {
- std::shared_ptr<TDefragCtx> DCtx;
- TActorId ParentId;
- std::optional<TDefragCalcStat> CalcStat;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DEFRAG_PLANNER;
- }
-
- TDefragPlannerActor(std::shared_ptr<TDefragCtx> dctx)
- : DCtx(std::move(dctx))
- {}
-
- void Bootstrap(const TActorId parentId) {
- ParentId = parentId;
- Send(DCtx->SkeletonId, new TEvTakeHullSnapshot(false));
- Become(&TThis::StateFunc);
- }
-
- void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
- CalcStat.emplace(std::move(ev->Get()->Snap), DCtx->HugeBlobCtx);
- HandleResume();
- }
-
- void HandleResume() {
- if (CalcStat->Scan(TDuration::MilliSeconds(10))) {
- TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), {}, nullptr, 0));
- } else {
- const ui32 totalChunks = CalcStat->GetTotalChunks();
- const ui32 usefulChunks = CalcStat->GetUsefulChunks();
- Y_VERIFY(usefulChunks <= totalChunks);
- const ui32 canBeFreedChunks = totalChunks - usefulChunks;
- if (HugeHeapDefragmentationRequired(DCtx->VCtx->GetOutOfSpaceState(), canBeFreedChunks, totalChunks)) {
- TChunksToDefrag chunksToDefrag = CalcStat->GetChunksToDefrag(DCtx->MaxChunksToDefrag);
- Y_VERIFY(chunksToDefrag);
- Send(ParentId, new TEvDefragStartQuantum(std::move(chunksToDefrag)));
- } else {
- Send(ParentId, new TEvDefragStartQuantum(TChunksToDefrag()));
- }
- PassAway();
- }
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvTakeHullSnapshotResult, Handle);
- cFunc(EvResume, HandleResume);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
- };
-
- void RunDefragPlanner(const TActorContext &ctx) {
- Y_VERIFY(!PlannerId);
- PlannerId = RunInBatchPool(ctx, new TDefragPlannerActor(DCtx));
- }
-
- TDuration GeneratePause() const {
- const TDuration delta = PauseMax - PauseMin;
- return PauseMin + TDuration::FromValue(RandomNumber<ui64>(delta.GetValue() + 1));
- }
-
- void Handle(TEvDefragStartQuantum::TPtr ev, const TActorContext& ctx) {
- Y_VERIFY(ev->Sender == PlannerId);
- PlannerId = {};
- if (ev->Get()->ChunksToDefrag) {
- ctx.Send(ev->Forward(DefragActorId));
- } else {
- ctx.Schedule(GeneratePause(), new TEvents::TEvWakeup);
- }
+ std::shared_ptr<TDefragCtx> DCtx;
+ const TActorId DefragActorId;
+ TActorId PlannerId;
+ TDuration PauseMin = TDuration::Minutes(5);
+ TDuration PauseMax = PauseMin + TDuration::Seconds(30);
+
+ enum {
+ EvResume = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ class TDefragPlannerActor : public TActorBootstrapped<TDefragPlannerActor> {
+ std::shared_ptr<TDefragCtx> DCtx;
+ TActorId ParentId;
+ std::optional<TDefragCalcStat> CalcStat;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DEFRAG_PLANNER;
+ }
+
+ TDefragPlannerActor(std::shared_ptr<TDefragCtx> dctx)
+ : DCtx(std::move(dctx))
+ {}
+
+ void Bootstrap(const TActorId parentId) {
+ ParentId = parentId;
+ Send(DCtx->SkeletonId, new TEvTakeHullSnapshot(false));
+ Become(&TThis::StateFunc);
+ }
+
+ void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
+ CalcStat.emplace(std::move(ev->Get()->Snap), DCtx->HugeBlobCtx);
+ HandleResume();
+ }
+
+ void HandleResume() {
+ if (CalcStat->Scan(TDuration::MilliSeconds(10))) {
+ TActivationContext::Send(new IEventHandle(EvResume, 0, SelfId(), {}, nullptr, 0));
+ } else {
+ const ui32 totalChunks = CalcStat->GetTotalChunks();
+ const ui32 usefulChunks = CalcStat->GetUsefulChunks();
+ Y_VERIFY(usefulChunks <= totalChunks);
+ const ui32 canBeFreedChunks = totalChunks - usefulChunks;
+ if (HugeHeapDefragmentationRequired(DCtx->VCtx->GetOutOfSpaceState(), canBeFreedChunks, totalChunks)) {
+ TChunksToDefrag chunksToDefrag = CalcStat->GetChunksToDefrag(DCtx->MaxChunksToDefrag);
+ Y_VERIFY(chunksToDefrag);
+ Send(ParentId, new TEvDefragStartQuantum(std::move(chunksToDefrag)));
+ } else {
+ Send(ParentId, new TEvDefragStartQuantum(TChunksToDefrag()));
+ }
+ PassAway();
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvTakeHullSnapshotResult, Handle);
+ cFunc(EvResume, HandleResume);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+ };
+
+ void RunDefragPlanner(const TActorContext &ctx) {
+ Y_VERIFY(!PlannerId);
+ PlannerId = RunInBatchPool(ctx, new TDefragPlannerActor(DCtx));
}
+ TDuration GeneratePause() const {
+ const TDuration delta = PauseMax - PauseMin;
+ return PauseMin + TDuration::FromValue(RandomNumber<ui64>(delta.GetValue() + 1));
+ }
+
+ void Handle(TEvDefragStartQuantum::TPtr ev, const TActorContext& ctx) {
+ Y_VERIFY(ev->Sender == PlannerId);
+ PlannerId = {};
+ if (ev->Get()->ChunksToDefrag) {
+ ctx.Send(ev->Forward(DefragActorId));
+ } else {
+ ctx.Schedule(GeneratePause(), new TEvents::TEvWakeup);
+ }
+ }
+
void Bootstrap(const TActorContext &ctx) {
- Become(&TThis::StateFunc, ctx, TDuration::FromValue(RandomNumber<ui64>(PauseMin.GetValue() + 1)), new TEvents::TEvWakeup);
+ Become(&TThis::StateFunc, ctx, TDuration::FromValue(RandomNumber<ui64>(PauseMin.GetValue() + 1)), new TEvents::TEvWakeup);
}
- void Die(const TActorContext& ctx) override {
- if (PlannerId) {
- ctx.Send(new IEventHandle(TEvents::TSystem::Poison, 0, PlannerId, {}, nullptr, 0));
- }
- TActorBootstrapped::Die(ctx);
+ void Die(const TActorContext& ctx) override {
+ if (PlannerId) {
+ ctx.Send(new IEventHandle(TEvents::TSystem::Poison, 0, PlannerId, {}, nullptr, 0));
+ }
+ TActorBootstrapped::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::Poison, Die);
- CFunc(TEvents::TSystem::Wakeup, RunDefragPlanner);
- HFunc(TEvDefragStartQuantum, Handle);
- CFunc(TEvBlobStorage::EvVDefragResult, RunDefragPlanner);
- )
+ STRICT_STFUNC(StateFunc,
+ CFunc(TEvents::TSystem::Poison, Die);
+ CFunc(TEvents::TSystem::Wakeup, RunDefragPlanner);
+ HFunc(TEvDefragStartQuantum, Handle);
+ CFunc(TEvBlobStorage::EvVDefragResult, RunDefragPlanner);
+ )
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DEFRAG_SCHEDULER;
+ return NKikimrServices::TActivity::BS_DEFRAG_SCHEDULER;
}
- TDefragLocalSheduler(const std::shared_ptr<TDefragCtx> &dCtx, const TActorId &defragActorId)
+ TDefragLocalSheduler(const std::shared_ptr<TDefragCtx> &dCtx, const TActorId &defragActorId)
: TActorBootstrapped<TDefragLocalSheduler>()
, DCtx(dCtx)
- , DefragActorId(defragActorId)
+ , DefragActorId(defragActorId)
{}
};
@@ -188,25 +188,25 @@ namespace NKikimr {
class TDefragActor : public TActorBootstrapped<TDefragActor>
{
// defrag statistics
- using TStat = TEvDefragQuantumResult::TStat;
+ using TStat = TEvDefragQuantumResult::TStat;
// Task for database defrag
struct TTask {
TEvBlobStorage::TEvVDefrag::TPtr Req;
- TEvDefragStartQuantum::TPtr StartQuantumReq;
+ TEvDefragStartQuantum::TPtr StartQuantumReq;
TStat Stat;
- bool FirstQuantum = true; // true, if we run a first quantum with this task
-
- TTask(TEvDefragStartQuantum::TPtr req)
- : StartQuantumReq(req)
- {}
+ bool FirstQuantum = true; // true, if we run a first quantum with this task
+ TTask(TEvDefragStartQuantum::TPtr req)
+ : StartQuantumReq(req)
+ {}
+
TTask(TEvBlobStorage::TEvVDefrag::TPtr req)
: Req(req)
{}
};
- std::shared_ptr<TDefragCtx> DCtx;
+ std::shared_ptr<TDefragCtx> DCtx;
TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
ui64 TotalDefragRuns = 0;
bool InProgress = false;
@@ -234,9 +234,9 @@ namespace NKikimr {
Sublog.Log() << "Defrag quantum started\n";
++TotalDefragRuns;
InProgress = true;
- ActiveActors.Insert(RunInBatchPool(ctx, CreateDefragQuantumActor(DCtx,
- GInfo->GetVDiskId(DCtx->VCtx->ShortSelfVDisk),
- task.StartQuantumReq ? std::make_optional(std::move(task.StartQuantumReq->Get()->ChunksToDefrag)) : std::nullopt)));
+ ActiveActors.Insert(RunInBatchPool(ctx, CreateDefragQuantumActor(DCtx,
+ GInfo->GetVDiskId(DCtx->VCtx->ShortSelfVDisk),
+ task.StartQuantumReq ? std::make_optional(std::move(task.StartQuantumReq->Get()->ChunksToDefrag)) : std::nullopt)));
}
void Bootstrap(const TActorContext &ctx) {
@@ -255,30 +255,30 @@ namespace NKikimr {
Sublog.Log() << "Defrag quantum has been finished\n";
auto *msg = ev->Get();
- Y_VERIFY(msg->Stat.Eof || msg->Stat.FreedChunks.size() == DCtx->MaxChunksToDefrag);
-
+ Y_VERIFY(msg->Stat.Eof || msg->Stat.FreedChunks.size() == DCtx->MaxChunksToDefrag);
+
auto &task = WaitQueue.front();
-
+
// update stat
task.Stat.FoundChunksToDefrag += msg->Stat.FoundChunksToDefrag;
task.Stat.RewrittenRecs += msg->Stat.RewrittenRecs;
task.Stat.RewrittenBytes += msg->Stat.RewrittenBytes;
task.Stat.Eof = msg->Stat.Eof;
- task.Stat.FreedChunks.insert(task.Stat.FreedChunks.end(), msg->Stat.FreedChunks.begin(), msg->Stat.FreedChunks.end());
-
- if (msg->Stat.Eof || !task.Req || !task.Req->Get()->Record.GetFull()) {
- if (task.Req) {
- // response to caller
- auto vdisk = task.Req->Get()->Record.GetVDiskID();
- auto reply = std::make_unique<TEvBlobStorage::TEvVDefragResult>(NKikimrProto::OK, vdisk);
- reply->Record.SetFoundChunksToDefrag(task.Stat.FoundChunksToDefrag);
- reply->Record.SetRewrittenRecs(task.Stat.RewrittenRecs);
- reply->Record.SetRewrittenBytes(task.Stat.RewrittenBytes);
- reply->Record.SetEof(task.Stat.Eof);
- for (const auto &x : task.Stat.FreedChunks) {
- reply->Record.MutableFreedChunks()->Add(x.ChunkId);
- }
- ctx.Send(task.Req->Sender, reply.release());
+ task.Stat.FreedChunks.insert(task.Stat.FreedChunks.end(), msg->Stat.FreedChunks.begin(), msg->Stat.FreedChunks.end());
+
+ if (msg->Stat.Eof || !task.Req || !task.Req->Get()->Record.GetFull()) {
+ if (task.Req) {
+ // response to caller
+ auto vdisk = task.Req->Get()->Record.GetVDiskID();
+ auto reply = std::make_unique<TEvBlobStorage::TEvVDefragResult>(NKikimrProto::OK, vdisk);
+ reply->Record.SetFoundChunksToDefrag(task.Stat.FoundChunksToDefrag);
+ reply->Record.SetRewrittenRecs(task.Stat.RewrittenRecs);
+ reply->Record.SetRewrittenBytes(task.Stat.RewrittenBytes);
+ reply->Record.SetEof(task.Stat.Eof);
+ for (const auto &x : task.Stat.FreedChunks) {
+ reply->Record.MutableFreedChunks()->Add(x.ChunkId);
+ }
+ ctx.Send(task.Req->Sender, reply.release());
}
// and remove the task from active tasks
WaitQueue.pop_front();
@@ -288,9 +288,9 @@ namespace NKikimr {
RunDefragIfAny(ctx);
}
- void Die(const TActorContext& ctx) override {
+ void Die(const TActorContext& ctx) override {
ActiveActors.KillAndClear(ctx);
- TActorBootstrapped::Die(ctx);
+ TActorBootstrapped::Die(ctx);
}
void Handle(TEvVGenerationChange::TPtr &ev, const TActorContext &ctx) {
@@ -300,11 +300,11 @@ namespace NKikimr {
GInfo = msg->NewInfo;
}
- void Handle(TEvDefragStartQuantum::TPtr ev, const TActorContext& ctx) {
- WaitQueue.emplace_back(ev);
- RunDefragIfAny(ctx);
- }
-
+ void Handle(TEvDefragStartQuantum::TPtr ev, const TActorContext& ctx) {
+ WaitQueue.emplace_back(ev);
+ RunDefragIfAny(ctx);
+ }
+
void Handle(TEvBlobStorage::TEvVDefrag::TPtr &ev, const TActorContext &ctx) {
Sublog.Log() << "Defrag request\n";
WaitQueue.emplace_back(ev);
@@ -391,12 +391,12 @@ namespace NKikimr {
}
STRICT_STFUNC(StateFunc,
- CFunc(TEvents::TSystem::Poison, Die)
+ CFunc(TEvents::TSystem::Poison, Die)
HFunc(TEvVGenerationChange, Handle)
HFunc(TEvBlobStorage::TEvVDefrag, Handle)
HFunc(NMon::TEvHttpInfo, Handle)
HFunc(TEvSublogLine, Handle)
- HFunc(TEvDefragStartQuantum, Handle)
+ HFunc(TEvDefragStartQuantum, Handle)
HFunc(TEvDefragQuantumResult, Handle)
);
@@ -405,7 +405,7 @@ namespace NKikimr {
return NKikimrServices::TActivity::BS_DEFRAG;
}
- TDefragActor(const std::shared_ptr<TDefragCtx> &dCtx, const TIntrusivePtr<TBlobStorageGroupInfo> &info)
+ TDefragActor(const std::shared_ptr<TDefragCtx> &dCtx, const TIntrusivePtr<TBlobStorageGroupInfo> &info)
: TActorBootstrapped<TDefragActor>()
, DCtx(dCtx)
, GInfo(info)
@@ -417,7 +417,7 @@ namespace NKikimr {
// CreateDefragActor
////////////////////////////////////////////////////////////////////////////
IActor* CreateDefragActor(
- const std::shared_ptr<TDefragCtx> &dCtx,
+ const std::shared_ptr<TDefragCtx> &dCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &info) {
return new TDefragActor(dCtx, info);
}
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_actor.h b/ydb/core/blobstorage/vdisk/defrag/defrag_actor.h
index f59ecee374c..f1e14db3518 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_actor.h
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_actor.h
@@ -18,7 +18,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
struct TDefragCtx {
const TIntrusivePtr<TVDiskContext> VCtx;
- const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
const TPDiskCtxPtr PDiskCtx;
const TActorId SkeletonId;
const TActorId HugeKeeperId;
@@ -30,7 +30,7 @@ namespace NKikimr {
TDefragCtx(
const TIntrusivePtr<TVDiskContext> &vctx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TPDiskCtxPtr &pdiskCtx,
const TActorId &skeletonId,
const TActorId &hugeKeeperId,
@@ -55,7 +55,7 @@ namespace NKikimr {
// Can defrag manually by receiving TEvBlobStorage::TEvVDefrag message.
////////////////////////////////////////////////////////////////////////////
IActor* CreateDefragActor(
- const std::shared_ptr<TDefragCtx> &dCtx,
+ const std::shared_ptr<TDefragCtx> &dCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &info);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.cpp b/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.cpp
index e01dd3fca26..348cb6e1e0b 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.cpp
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.cpp
@@ -8,108 +8,108 @@
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
#include <ydb/core/blobstorage/vdisk/hulldb/hull_ds_all_snap.h>
#include <ydb/core/blobstorage/vdisk/skeleton/blobstorage_takedbsnap.h>
-#include <library/cpp/actors/core/actor_coroutine.h>
+#include <library/cpp/actors/core/actor_coroutine.h>
using namespace NKikimrServices;
namespace NKikimr {
- class TDefragQuantum : public TActorCoroImpl {
- std::shared_ptr<TDefragCtx> DCtx;
- const TVDiskID SelfVDiskId;
- std::optional<TChunksToDefrag> ChunksToDefrag;
-
- enum {
- EvResume = EventSpaceBegin(TEvents::ES_PRIVATE)
- };
-
- public:
- TDefragQuantum(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
- std::optional<TChunksToDefrag> chunksToDefrag)
- : TActorCoroImpl(65536, true, true)
- , DCtx(dctx)
- , SelfVDiskId(selfVDiskId)
- , ChunksToDefrag(std::move(chunksToDefrag))
+ class TDefragQuantum : public TActorCoroImpl {
+ std::shared_ptr<TDefragCtx> DCtx;
+ const TVDiskID SelfVDiskId;
+ std::optional<TChunksToDefrag> ChunksToDefrag;
+
+ enum {
+ EvResume = EventSpaceBegin(TEvents::ES_PRIVATE)
+ };
+
+ public:
+ TDefragQuantum(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
+ std::optional<TChunksToDefrag> chunksToDefrag)
+ : TActorCoroImpl(65536, true, true)
+ , DCtx(dctx)
+ , SelfVDiskId(selfVDiskId)
+ , ChunksToDefrag(std::move(chunksToDefrag))
{}
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
+ void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override {
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, ev->GetTypeRewrite());
}
- void Run() override {
- TEvDefragQuantumResult::TStat stat{.Eof = true};
-
- if (ChunksToDefrag) {
- Y_VERIFY(*ChunksToDefrag);
- } else {
- TDefragQuantumFindChunks findChunks(GetSnapshot(), DCtx->HugeBlobCtx);
- while (findChunks.Scan(TDuration::MilliSeconds(10))) {
- Yield();
- }
- ChunksToDefrag.emplace(findChunks.GetChunksToDefrag(DCtx->MaxChunksToDefrag));
- }
- if (*ChunksToDefrag) {
- stat.FoundChunksToDefrag = ChunksToDefrag->FoundChunksToDefrag;
- stat.FreedChunks = ChunksToDefrag->Chunks;
- stat.Eof = stat.FoundChunksToDefrag < DCtx->MaxChunksToDefrag;
-
- LockChunks(*ChunksToDefrag);
-
- TDefragQuantumFindRecords findRecords(GetSnapshot(), std::move(*ChunksToDefrag));
- findRecords.Scan(TDuration::MilliSeconds(10), std::bind(&TDefragQuantum::Yield, this));
-
- const TActorId rewriterActorId = Register(CreateDefragRewriter(DCtx, SelfVDiskId, SelfActorId,
- findRecords.RetrieveSnapshot(), findRecords.GetRecordsToRewrite()));
- THolder<TEvDefragRewritten::THandle> ev;
- try {
- ev = WaitForSpecificEvent<TEvDefragRewritten>();
- } catch (const TPoisonPillException& ex) {
- Send(new IEventHandle(TEvents::TSystem::Poison, 0, rewriterActorId, {}, nullptr, 0));
- throw;
- }
-
- stat.RewrittenRecs = ev->Get()->RewrittenRecs;
- stat.RewrittenBytes = ev->Get()->RewrittenBytes;
-
- Compact();
-
- auto hugeStat = GetHugeStat();
- Y_VERIFY(hugeStat.LockedChunks.size() < 100);
- }
-
- Send(ParentActorId, new TEvDefragQuantumResult(std::move(stat)));
+ void Run() override {
+ TEvDefragQuantumResult::TStat stat{.Eof = true};
+
+ if (ChunksToDefrag) {
+ Y_VERIFY(*ChunksToDefrag);
+ } else {
+ TDefragQuantumFindChunks findChunks(GetSnapshot(), DCtx->HugeBlobCtx);
+ while (findChunks.Scan(TDuration::MilliSeconds(10))) {
+ Yield();
+ }
+ ChunksToDefrag.emplace(findChunks.GetChunksToDefrag(DCtx->MaxChunksToDefrag));
+ }
+ if (*ChunksToDefrag) {
+ stat.FoundChunksToDefrag = ChunksToDefrag->FoundChunksToDefrag;
+ stat.FreedChunks = ChunksToDefrag->Chunks;
+ stat.Eof = stat.FoundChunksToDefrag < DCtx->MaxChunksToDefrag;
+
+ LockChunks(*ChunksToDefrag);
+
+ TDefragQuantumFindRecords findRecords(GetSnapshot(), std::move(*ChunksToDefrag));
+ findRecords.Scan(TDuration::MilliSeconds(10), std::bind(&TDefragQuantum::Yield, this));
+
+ const TActorId rewriterActorId = Register(CreateDefragRewriter(DCtx, SelfVDiskId, SelfActorId,
+ findRecords.RetrieveSnapshot(), findRecords.GetRecordsToRewrite()));
+ THolder<TEvDefragRewritten::THandle> ev;
+ try {
+ ev = WaitForSpecificEvent<TEvDefragRewritten>();
+ } catch (const TPoisonPillException& ex) {
+ Send(new IEventHandle(TEvents::TSystem::Poison, 0, rewriterActorId, {}, nullptr, 0));
+ throw;
+ }
+
+ stat.RewrittenRecs = ev->Get()->RewrittenRecs;
+ stat.RewrittenBytes = ev->Get()->RewrittenBytes;
+
+ Compact();
+
+ auto hugeStat = GetHugeStat();
+ Y_VERIFY(hugeStat.LockedChunks.size() < 100);
+ }
+
+ Send(ParentActorId, new TEvDefragQuantumResult(std::move(stat)));
}
- THullDsSnap GetSnapshot() {
- Send(DCtx->SkeletonId, new TEvTakeHullSnapshot(false));
- return std::move(WaitForSpecificEvent<TEvTakeHullSnapshotResult>()->Get()->Snap);
+ THullDsSnap GetSnapshot() {
+ Send(DCtx->SkeletonId, new TEvTakeHullSnapshot(false));
+ return std::move(WaitForSpecificEvent<TEvTakeHullSnapshotResult>()->Get()->Snap);
}
- void Yield() {
- Send(new IEventHandle(EvResume, 0, SelfActorId, {}, nullptr, 0));
- WaitForSpecificEvent([](IEventHandle& ev) { return ev.Type == EvResume; });
+ void Yield() {
+ Send(new IEventHandle(EvResume, 0, SelfActorId, {}, nullptr, 0));
+ WaitForSpecificEvent([](IEventHandle& ev) { return ev.Type == EvResume; });
}
- void LockChunks(const TChunksToDefrag& chunks) {
- Send(DCtx->HugeKeeperId, new TEvHugeLockChunks(chunks.Chunks));
- WaitForSpecificEvent<TEvHugeLockChunksResult>();
+ void LockChunks(const TChunksToDefrag& chunks) {
+ Send(DCtx->HugeKeeperId, new TEvHugeLockChunks(chunks.Chunks));
+ WaitForSpecificEvent<TEvHugeLockChunksResult>();
}
- void Compact() {
- Send(DCtx->SkeletonId, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
- WaitForSpecificEvent<TEvCompactVDiskResult>();
+ void Compact() {
+ Send(DCtx->SkeletonId, TEvCompactVDisk::Create(EHullDbType::LogoBlobs));
+ WaitForSpecificEvent<TEvCompactVDiskResult>();
}
- NHuge::THeapStat GetHugeStat() {
- Send(DCtx->HugeKeeperId, new TEvHugeStat());
- return std::move(WaitForSpecificEvent<TEvHugeStatResult>()->Get()->Stat);
+ NHuge::THeapStat GetHugeStat() {
+ Send(DCtx->HugeKeeperId, new TEvHugeStat());
+ return std::move(WaitForSpecificEvent<TEvHugeStatResult>()->Get()->Stat);
}
};
- IActor *CreateDefragQuantumActor(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
- std::optional<TChunksToDefrag> chunksToDefrag) {
- return new TActorCoro(MakeHolder<TDefragQuantum>(dctx, selfVDiskId, std::move(chunksToDefrag)),
- NKikimrServices::TActivity::BS_DEFRAG_QUANTUM);
+ IActor *CreateDefragQuantumActor(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
+ std::optional<TChunksToDefrag> chunksToDefrag) {
+ return new TActorCoro(MakeHolder<TDefragQuantum>(dctx, selfVDiskId, std::move(chunksToDefrag)),
+ NKikimrServices::TActivity::BS_DEFRAG_QUANTUM);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.h b/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.h
index bc07685b548..c67a651ed33 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.h
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_quantum.h
@@ -6,8 +6,8 @@
namespace NKikimr {
- class TDefragQuantumChunkFinder;
-
+ class TDefragQuantumChunkFinder;
+
struct TEvDefragQuantumResult :
public TEventLocal<TEvDefragQuantumResult, TEvBlobStorage::EvDefragQuantumResult>
{
@@ -32,10 +32,10 @@ namespace NKikimr {
{}
};
- struct TChunksToDefrag;
-
- IActor *CreateDefragQuantumActor(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
- std::optional<TChunksToDefrag> chunksToDefrag);
+ struct TChunksToDefrag;
+ IActor *CreateDefragQuantumActor(const std::shared_ptr<TDefragCtx>& dctx, const TVDiskID& selfVDiskId,
+ std::optional<TChunksToDefrag> chunksToDefrag);
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.cpp b/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.cpp
index 02945adaf0a..e57e1bd0ad1 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.cpp
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.cpp
@@ -9,7 +9,7 @@ namespace NKikimr {
{
friend class TActorBootstrapped<TDefragRewriter>;
- std::shared_ptr<TDefragCtx> DCtx;
+ std::shared_ptr<TDefragCtx> DCtx;
const TVDiskID SelfVDiskId;
const TActorId NotifyId;
// we can rewrite data while we are holding snapshot for data being read
@@ -28,13 +28,13 @@ namespace NKikimr {
if (RecToReadIdx < Recs.size()) {
const TDiskPart &p = Recs[RecToReadIdx].OldDiskPart;
auto msg = std::make_unique<NPDisk::TEvChunkRead>(DCtx->PDiskCtx->Dsk->Owner,
- DCtx->PDiskCtx->Dsk->OwnerRound, p.ChunkIdx, p.Offset, p.Size, NPriRead::HullComp, nullptr);
+ DCtx->PDiskCtx->Dsk->OwnerRound, p.ChunkIdx, p.Offset, p.Size, NPriRead::HullComp, nullptr);
ctx.Send(DCtx->PDiskCtx->PDiskId, msg.release());
DCtx->DefragMonGroup.DefragBytesRewritten() += p.Size;
RewrittenBytes += p.Size;
- } else if (RewrittenRecsCounter == Recs.size()) {
- ctx.Send(NotifyId, new TEvDefragRewritten(RewrittenRecsCounter, RewrittenBytes));
- Die(ctx);
+ } else if (RewrittenRecsCounter == Recs.size()) {
+ ctx.Send(NotifyId, new TEvDefragRewritten(RewrittenRecsCounter, RewrittenBytes));
+ Die(ctx);
}
}
@@ -43,27 +43,27 @@ namespace NKikimr {
CHECK_PDISK_RESPONSE(DCtx->VCtx, ev, ctx);
auto *msg = ev->Get();
- const TDefragRecord &rec = Recs[RecToReadIdx++];
+ const TDefragRecord &rec = Recs[RecToReadIdx++];
const auto &gtype = DCtx->VCtx->Top->GType;
ui8 partId = rec.LogoBlobId.PartId();
Y_VERIFY(partId);
- TString data = msg->Data.ToString();
- Y_VERIFY(data.size() == TDiskBlob::HeaderSize + gtype.PartSize(rec.LogoBlobId));
- const char *header = data.data();
-
- ui32 fullDataSize;
- memcpy(&fullDataSize, header, sizeof(fullDataSize));
- header += sizeof(fullDataSize);
- Y_VERIFY(fullDataSize == rec.LogoBlobId.BlobSize());
-
- Y_VERIFY(NMatrix::TVectorType::MakeOneHot(partId - 1, gtype.TotalPartCount()).Raw() == static_cast<ui8>(*header));
-
- TRope rope(data);
- rope.EraseFront(TDiskBlob::HeaderSize);
-
- auto writeEvent = std::make_unique<TEvBlobStorage::TEvVPut>(rec.LogoBlobId, std::move(rope),
+ TString data = msg->Data.ToString();
+ Y_VERIFY(data.size() == TDiskBlob::HeaderSize + gtype.PartSize(rec.LogoBlobId));
+ const char *header = data.data();
+
+ ui32 fullDataSize;
+ memcpy(&fullDataSize, header, sizeof(fullDataSize));
+ header += sizeof(fullDataSize);
+ Y_VERIFY(fullDataSize == rec.LogoBlobId.BlobSize());
+
+ Y_VERIFY(NMatrix::TVectorType::MakeOneHot(partId - 1, gtype.TotalPartCount()).Raw() == static_cast<ui8>(*header));
+
+ TRope rope(data);
+ rope.EraseFront(TDiskBlob::HeaderSize);
+
+ auto writeEvent = std::make_unique<TEvBlobStorage::TEvVPut>(rec.LogoBlobId, std::move(rope),
SelfVDiskId, true, nullptr, TInstant::Max(), NKikimrBlobStorage::EPutHandleClass::AsyncBlob);
Send(DCtx->SkeletonId, writeEvent.release());
}
@@ -73,7 +73,7 @@ namespace NKikimr {
// FIXME: Handle NotOK, in case of RACE just cancel the job
++RewrittenRecsCounter;
- SendNextRead(ctx);
+ SendNextRead(ctx);
}
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
@@ -91,11 +91,11 @@ namespace NKikimr {
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DEFRAG_REWRITER;
+ return NKikimrServices::TActivity::BS_DEFRAG_REWRITER;
}
TDefragRewriter(
- const std::shared_ptr<TDefragCtx> &dCtx,
+ const std::shared_ptr<TDefragCtx> &dCtx,
const TVDiskID &selfVDiskId,
const TActorId &notifyId,
THullDsSnap &&fullSnap,
@@ -116,7 +116,7 @@ namespace NKikimr {
// Rewrites selected huge blobs to free up some Huge Heap chunks
////////////////////////////////////////////////////////////////////////////
IActor* CreateDefragRewriter(
- const std::shared_ptr<TDefragCtx> &dCtx,
+ const std::shared_ptr<TDefragCtx> &dCtx,
const TVDiskID &selfVDiskId,
const TActorId &notifyId,
THullDsSnap &&fullSnap,
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.h b/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.h
index 2f9e2a79dbf..e6dbc8dd80b 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.h
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_rewriter.h
@@ -34,7 +34,7 @@ namespace NKikimr {
// Rewrites selected huge blobs to free up some Huge Heap chunks
////////////////////////////////////////////////////////////////////////////
IActor* CreateDefragRewriter(
- const std::shared_ptr<TDefragCtx> &dCtx,
+ const std::shared_ptr<TDefragCtx> &dCtx,
const TVDiskID &selfVDiskId,
const TActorId &notifyId,
THullDsSnap &&fullSnap,
diff --git a/ydb/core/blobstorage/vdisk/defrag/defrag_search.h b/ydb/core/blobstorage/vdisk/defrag/defrag_search.h
index 5578d0c240b..8ce74c126da 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defrag_search.h
+++ b/ydb/core/blobstorage/vdisk/defrag/defrag_search.h
@@ -8,21 +8,21 @@
namespace NKikimr {
- struct THugeBlobRecord {
- TDiskPart Part;
- TLogoBlobID Id;
- bool Useful;
-
- friend bool operator <(const THugeBlobRecord& x, const THugeBlobRecord& y) {
- return x.Part < y.Part;
- }
- };
-
+ struct THugeBlobRecord {
+ TDiskPart Part;
+ TLogoBlobID Id;
+ bool Useful;
+
+ friend bool operator <(const THugeBlobRecord& x, const THugeBlobRecord& y) {
+ return x.Part < y.Part;
+ }
+ };
+
struct TChunksToDefrag {
TDefragChunks Chunks;
- ui32 FoundChunksToDefrag = 0;
+ ui32 FoundChunksToDefrag = 0;
ui64 EstimatedSlotsCount = 0;
- std::vector<THugeBlobRecord> HugeBlobs;
+ std::vector<THugeBlobRecord> HugeBlobs;
void Output(IOutputStream &str) const {
str << "{Chunks# " << FormatList(Chunks);
@@ -34,10 +34,10 @@ namespace NKikimr {
Output(str);
return str.Str();
}
-
- explicit operator bool() const {
- return !Chunks.empty();
- }
+
+ explicit operator bool() const {
+ return !Chunks.empty();
+ }
};
struct TDefragRecord {
@@ -53,390 +53,390 @@ namespace NKikimr {
{}
};
- template<typename TDerived>
- class TDefragScanner {
- THullDsSnap FullSnap;
- const TBlobStorageGroupType GType;
- const TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> Barriers;
- const bool AllowKeepFlags;
- TLogoBlobsSnapshot::TForwardIterator Iter;
-
- TDataMerger Merger;
- TKeyLogoBlob Key;
- TMemRecLogoBlob MemRec;
- ui32 NumMemRecsMerged;
-
- public:
- TDefragScanner(THullDsSnap&& fullSnap)
- : FullSnap(std::move(fullSnap))
- , GType(FullSnap.HullCtx->VCtx->Top->GType)
- , Barriers(FullSnap.BarriersSnap.CreateEssence(FullSnap.HullCtx))
- , AllowKeepFlags(FullSnap.HullCtx->AllowKeepFlags)
- , Iter(FullSnap.HullCtx, &FullSnap.LogoBlobsSnap)
- {
- Iter.SeekToFirst();
- }
-
- bool Scan(TDuration maxTime) {
- ui64 endTime = GetCycleCountFast() + DurationToCycles(maxTime);
- ui32 count = 0;
- for (; Iter.Valid(); Iter.Next()) {
- if (++count % 1024 == 0 && GetCycleCountFast() >= endTime) {
- break;
- }
- Start(Iter.GetCurKey());
- Iter.PutToMerger(this);
- Finish();
- }
- return Iter.Valid();
- }
-
- void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope* /*data*/, const TKeyLogoBlob& key, ui64 lsn) {
- Update(memRec, nullptr, lsn);
- MemRec.Merge(memRec, key);
- ++NumMemRecsMerged;
- }
-
- void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key, ui64 circaLsn) {
- Update(memRec, outbound, circaLsn);
- MemRec.Merge(memRec, key);
- ++NumMemRecsMerged;
- }
-
- static constexpr bool HaveToMergeData() { return false; }
-
- private:
- void Start(const TKeyLogoBlob& key) {
- Key = key;
- MemRec = {};
- NumMemRecsMerged = 0;
- }
-
- void Finish() {
- if (!Merger.Empty()) {
- Y_VERIFY(!Merger.HasSmallBlobs());
- NGc::TKeepStatus status = Barriers->Keep(Key, MemRec, NumMemRecsMerged, AllowKeepFlags);
- const auto& hugeMerger = Merger.GetHugeBlobMerger();
- const auto& local = MemRec.GetIngress().LocalParts(GType);
- ui8 partIdx = local.FirstPosition();
- for (const TDiskPart& part : hugeMerger.SavedData()) {
- Y_VERIFY(partIdx != local.GetSize());
- if (part.ChunkIdx) {
- static_cast<TDerived&>(*this).Add(part, Key.LogoBlobID(), status.KeepData);
- }
- partIdx = local.NextPosition(partIdx);
- }
- for (const TDiskPart& part : hugeMerger.DeletedData()) {
- if (part.ChunkIdx) {
- static_cast<TDerived&>(*this).Add(part, Key.LogoBlobID(), false);
- }
- }
- Merger.Clear();
- }
- }
-
- void Update(const TMemRecLogoBlob &memRec, const TDiskPart *outbound, ui64 lsn) {
- TDiskDataExtractor extr;
- switch (memRec.GetType()) {
- case TBlobType::HugeBlob:
- case TBlobType::ManyHugeBlobs:
- memRec.GetDiskData(&extr, outbound);
- Merger.AddHugeBlob(extr.Begin, extr.End, memRec.GetIngress().LocalParts(GType), lsn);
- break;
-
- default:
- break;
- }
- }
- };
-
- class TDefragQuantumChunkFinder {
- private:
- // Info gathered per chunk
- struct TChunkInfo {
- ui32 UsefulSlots = 0;
- std::vector<THugeBlobRecord> Records;
- const ui32 SlotSize;
- const ui32 NumberOfSlotsInChunk;
-
- TChunkInfo(ui32 slotSize, ui32 numberOfSlotsInChunk)
- : SlotSize(slotSize)
- , NumberOfSlotsInChunk(numberOfSlotsInChunk)
- {}
-
- TString ToString() const {
- TStringStream str;
- str << "UsefulSlots# " << UsefulSlots << "/" << NumberOfSlotsInChunk;
- return str.Str();
- }
- };
-
- // Aggregated info gathered per slotSize
- struct TAggrSlotInfo {
- ui64 UsefulSlots = 0;
- ui32 UsedChunks = 0;
- std::unordered_map<ui32, const std::vector<THugeBlobRecord>*> RecordPtrs;
- const ui32 NumberOfSlotsInChunk;
-
- TAggrSlotInfo(ui32 numberOfSlotsInChunk)
- : NumberOfSlotsInChunk(numberOfSlotsInChunk)
- {}
- };
-
- class TChunksMap {
- private:
- using TPerChunkMap = THashMap<ui32, TChunkInfo>; // chunkIdx -> TChunkInfo
- using TAggrBySlotSize = THashMap<ui32, TAggrSlotInfo>; // slotSize -> TAggrSlotInfo
- const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
- TPerChunkMap PerChunkMap;
-
- private:
- TAggrBySlotSize AggregatePerSlotSize() const {
- TAggrBySlotSize aggrSlots;
- for (const auto& [chunkIdx, chunk] : PerChunkMap) {
- auto it = aggrSlots.try_emplace(chunk.SlotSize, chunk.NumberOfSlotsInChunk).first;
- TAggrSlotInfo& aggr = it->second;
- aggr.UsefulSlots += chunk.UsefulSlots;
- ++aggr.UsedChunks;
- aggr.RecordPtrs.emplace(chunkIdx, &chunk.Records);
- }
- return aggrSlots;
- }
-
- public:
- TChunksMap(const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx)
- : HugeBlobCtx(hugeBlobCtx)
- {}
-
- void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
- auto it = PerChunkMap.find(part.ChunkIdx);
- if (it == PerChunkMap.end()) {
- const THugeSlotsMap::TSlotInfo *slotInfo = HugeBlobCtx->HugeSlotsMap->GetSlotInfo(part.Size);
- Y_VERIFY(slotInfo, "size# %" PRIu32, part.Size);
- it = PerChunkMap.emplace(std::piecewise_construct, std::make_tuple(part.ChunkIdx),
- std::make_tuple(slotInfo->SlotSize, slotInfo->NumberOfSlotsInChunk)).first;
- }
- it->second.UsefulSlots += useful;
- it->second.Records.push_back(THugeBlobRecord{part, id, useful});
- }
-
- TChunksToDefrag GetChunksToDefrag(size_t maxChunksToDefrag) const {
- TAggrBySlotSize aggrSlots = AggregatePerSlotSize();
-
- std::vector<const TPerChunkMap::value_type*> chunks;
- chunks.reserve(PerChunkMap.size());
- for (const auto& kv : PerChunkMap) {
- chunks.push_back(&kv);
- }
- auto cmpByMoveSize = [](const auto *left, const auto *right) {
- return left->second.UsefulSlots < right->second.UsefulSlots;
- };
- std::sort(chunks.begin(), chunks.end(), cmpByMoveSize);
-
- TChunksToDefrag result;
- result.Chunks.reserve(maxChunksToDefrag);
-
- for (const auto *kv : chunks) {
- const auto& [chunkIdx, chunk] = *kv;
- auto it = aggrSlots.find(chunk.SlotSize);
- Y_VERIFY(it != aggrSlots.end());
- auto& a = it->second;
-
- // if we can put all current used slots into UsedChunks - 1, then defragment this chunk
- if (a.NumberOfSlotsInChunk * (a.UsedChunks - 1) >= a.UsefulSlots) {
- --a.UsedChunks;
- ++result.FoundChunksToDefrag;
- if (result.Chunks.size() < maxChunksToDefrag) {
- result.Chunks.emplace_back(chunkIdx, chunk.SlotSize);
- result.EstimatedSlotsCount += chunk.UsefulSlots;
- const auto& rp = a.RecordPtrs.at(chunkIdx);
- result.HugeBlobs.insert(result.HugeBlobs.end(), rp->begin(), rp->end());
- }
- }
- }
-
- return result;
- }
-
- void Output(IOutputStream &str) const {
- str << "{ChunksMap# [";
- bool first = true;
- for (auto& [chunkId, info] : PerChunkMap) {
- if (first) {
- first = false;
- } else {
- str << " ";
- }
- str << "{chunkId# " << chunkId << " " << info.ToString() << "}";
- }
- str << "]}";
- }
-
- TString ToString() const {
- TStringStream str;
- Output(str);
- return str.Str();
- }
- };
-
- TChunksMap ChunksMap;
-
- public:
- TDefragQuantumChunkFinder(const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx)
- : ChunksMap(hugeBlobCtx)
- {}
-
- TChunksToDefrag GetChunksToDefrag(size_t maxChunksToDefrag) {
- return ChunksMap.GetChunksToDefrag(maxChunksToDefrag);
- }
-
- void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
- ChunksMap.Add(part, id, useful);
- }
- };
-
- class TDefragQuantumFindChunks
- : public TDefragQuantumChunkFinder
- , public TDefragScanner<TDefragQuantumFindChunks>
- {
+ template<typename TDerived>
+ class TDefragScanner {
+ THullDsSnap FullSnap;
+ const TBlobStorageGroupType GType;
+ const TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> Barriers;
+ const bool AllowKeepFlags;
+ TLogoBlobsSnapshot::TForwardIterator Iter;
+
+ TDataMerger Merger;
+ TKeyLogoBlob Key;
+ TMemRecLogoBlob MemRec;
+ ui32 NumMemRecsMerged;
+
public:
- TDefragQuantumFindChunks(THullDsSnap&& snap, const std::shared_ptr<THugeBlobCtx>& hugeBlobCtx)
- : TDefragQuantumChunkFinder(hugeBlobCtx)
- , TDefragScanner(std::move(snap))
- {}
-
- using TDefragQuantumChunkFinder::Add;
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- class TDefragQuantumFindRecords {
- using TLevelSegment = ::NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelSstPtr = typename TLevelSegment::TLevelSstPtr;
-
- THullDsSnap FullSnap;
- TChunksToDefrag ChunksToDefrag;
- std::unordered_set<ui32> Chunks; // chunks to defrag (i.e. move all data from these chunks)
- std::vector<TDefragRecord> RecsToRewrite;
- TDuration MaxTime;
- std::function<void()> Yield;
- ui64 EndTime;
- ui32 Count;
-
- public:
- TDefragQuantumFindRecords(THullDsSnap&& fullSnap, TChunksToDefrag&& chunksToDefrag)
- : FullSnap(std::move(fullSnap))
- , ChunksToDefrag(std::move(chunksToDefrag))
- {
- for (const auto& chunk : ChunksToDefrag.Chunks) {
- Chunks.insert(chunk.ChunkId);
- }
- Y_VERIFY(Chunks.size() == ChunksToDefrag.Chunks.size()); // ensure there are no duplicate numbers
- std::sort(ChunksToDefrag.HugeBlobs.begin(), ChunksToDefrag.HugeBlobs.end());
- RecsToRewrite.reserve(ChunksToDefrag.EstimatedSlotsCount);
- }
-
- template<typename T>
- void Scan(TDuration maxTime, T&& yield) {
- MaxTime = maxTime;
- Yield = yield;
- EndTime = GetCycleCountFast() + DurationToCycles(MaxTime);
- Count = 0;
- TraverseDbWithoutMerge(FullSnap.HullCtx, this, FullSnap.LogoBlobsSnap);
- }
-
- void UpdateFresh(const char* /*segName*/, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
- Update(key, memRec, nullptr);
- }
-
- void UpdateLevel(const TLevelSstPtr& p, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
- Update(key, memRec, p.SstPtr->GetOutbound());
- }
-
- void Update(const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec, const TDiskPart *outbound) {
- TDiskDataExtractor extr;
- if (memRec.GetType() == TBlobType::HugeBlob || memRec.GetType() == TBlobType::ManyHugeBlobs) {
- memRec.GetDiskData(&extr, outbound);
- const NMatrix::TVectorType local = memRec.GetIngress().LocalParts(FullSnap.HullCtx->VCtx->Top->GType);
- ui8 partIdx = local.FirstPosition();
- for (const TDiskPart *p = extr.Begin; p != extr.End; ++p, partIdx = local.NextPosition(partIdx)) {
- Y_VERIFY(partIdx != local.GetSize());
- if (!p->ChunkIdx || !Chunks.count(p->ChunkIdx)) {
- continue; // not from chunks of our interest
- }
-
- const TLogoBlobID fullId = key.LogoBlobID();
- const auto it = std::lower_bound(ChunksToDefrag.HugeBlobs.begin(), ChunksToDefrag.HugeBlobs.end(),
- THugeBlobRecord{*p, fullId, true});
- if (it == ChunksToDefrag.HugeBlobs.end() || it->Part != *p || it->Id != fullId || it->Useful) {
- RecsToRewrite.emplace_back(TLogoBlobID(fullId, partIdx + 1), *p);
- }
- }
- }
- if (++Count % 1024 == 0 && GetCycleCountFast() >= EndTime) {
- Yield();
- EndTime = GetCycleCountFast() + DurationToCycles(MaxTime);
- }
- }
-
- void Finish() {}
-
- THullDsSnap RetrieveSnapshot() {
- return std::move(FullSnap);
- }
-
- std::vector<TDefragRecord> GetRecordsToRewrite() {
- return std::move(RecsToRewrite);
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- class TDefragCalcStat
- : public TDefragScanner<TDefragCalcStat>
- , public TDefragQuantumChunkFinder
- {
- struct TPerSlotSizeInfo {
- ui32 UsefulSlots = 0;
- const ui32 NumberOfSlotsInChunk;
-
- TPerSlotSizeInfo(ui32 numberOfSlotsInChunk)
- : NumberOfSlotsInChunk(numberOfSlotsInChunk)
- {}
- };
-
- std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
- std::unordered_set<ui32> Chunks;
- std::unordered_map<ui32, ui32> Map; // numberOfSlotsInChunk -> usefulSlots
-
- public:
- TDefragCalcStat(THullDsSnap&& fullSnap, const std::shared_ptr<THugeBlobCtx>& hugeBlobCtx)
- : TDefragScanner(std::move(fullSnap))
- , TDefragQuantumChunkFinder(hugeBlobCtx)
- , HugeBlobCtx(hugeBlobCtx)
- {}
-
- void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
- Chunks.insert(part.ChunkIdx);
- if (useful) {
- const THugeSlotsMap::TSlotInfo *slotInfo = HugeBlobCtx->HugeSlotsMap->GetSlotInfo(part.Size);
- Y_VERIFY(slotInfo, "size# %" PRIu32, part.Size);
- ++Map[slotInfo->NumberOfSlotsInChunk];
- }
- TDefragQuantumChunkFinder::Add(part, id, useful);
- }
-
- ui32 GetTotalChunks() {
- return Chunks.size();
- }
-
- ui32 GetUsefulChunks() {
- ui32 res = 0;
- for (const auto& [numberOfSlotsInChunk, usefulSlots] : Map) {
- res += (usefulSlots + numberOfSlotsInChunk - 1) / numberOfSlotsInChunk;
- }
- return res;
- }
- };
-
+ TDefragScanner(THullDsSnap&& fullSnap)
+ : FullSnap(std::move(fullSnap))
+ , GType(FullSnap.HullCtx->VCtx->Top->GType)
+ , Barriers(FullSnap.BarriersSnap.CreateEssence(FullSnap.HullCtx))
+ , AllowKeepFlags(FullSnap.HullCtx->AllowKeepFlags)
+ , Iter(FullSnap.HullCtx, &FullSnap.LogoBlobsSnap)
+ {
+ Iter.SeekToFirst();
+ }
+
+ bool Scan(TDuration maxTime) {
+ ui64 endTime = GetCycleCountFast() + DurationToCycles(maxTime);
+ ui32 count = 0;
+ for (; Iter.Valid(); Iter.Next()) {
+ if (++count % 1024 == 0 && GetCycleCountFast() >= endTime) {
+ break;
+ }
+ Start(Iter.GetCurKey());
+ Iter.PutToMerger(this);
+ Finish();
+ }
+ return Iter.Valid();
+ }
+
+ void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope* /*data*/, const TKeyLogoBlob& key, ui64 lsn) {
+ Update(memRec, nullptr, lsn);
+ MemRec.Merge(memRec, key);
+ ++NumMemRecsMerged;
+ }
+
+ void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key, ui64 circaLsn) {
+ Update(memRec, outbound, circaLsn);
+ MemRec.Merge(memRec, key);
+ ++NumMemRecsMerged;
+ }
+
+ static constexpr bool HaveToMergeData() { return false; }
+
+ private:
+ void Start(const TKeyLogoBlob& key) {
+ Key = key;
+ MemRec = {};
+ NumMemRecsMerged = 0;
+ }
+
+ void Finish() {
+ if (!Merger.Empty()) {
+ Y_VERIFY(!Merger.HasSmallBlobs());
+ NGc::TKeepStatus status = Barriers->Keep(Key, MemRec, NumMemRecsMerged, AllowKeepFlags);
+ const auto& hugeMerger = Merger.GetHugeBlobMerger();
+ const auto& local = MemRec.GetIngress().LocalParts(GType);
+ ui8 partIdx = local.FirstPosition();
+ for (const TDiskPart& part : hugeMerger.SavedData()) {
+ Y_VERIFY(partIdx != local.GetSize());
+ if (part.ChunkIdx) {
+ static_cast<TDerived&>(*this).Add(part, Key.LogoBlobID(), status.KeepData);
+ }
+ partIdx = local.NextPosition(partIdx);
+ }
+ for (const TDiskPart& part : hugeMerger.DeletedData()) {
+ if (part.ChunkIdx) {
+ static_cast<TDerived&>(*this).Add(part, Key.LogoBlobID(), false);
+ }
+ }
+ Merger.Clear();
+ }
+ }
+
+ void Update(const TMemRecLogoBlob &memRec, const TDiskPart *outbound, ui64 lsn) {
+ TDiskDataExtractor extr;
+ switch (memRec.GetType()) {
+ case TBlobType::HugeBlob:
+ case TBlobType::ManyHugeBlobs:
+ memRec.GetDiskData(&extr, outbound);
+ Merger.AddHugeBlob(extr.Begin, extr.End, memRec.GetIngress().LocalParts(GType), lsn);
+ break;
+
+ default:
+ break;
+ }
+ }
+ };
+
+ class TDefragQuantumChunkFinder {
+ private:
+ // Info gathered per chunk
+ struct TChunkInfo {
+ ui32 UsefulSlots = 0;
+ std::vector<THugeBlobRecord> Records;
+ const ui32 SlotSize;
+ const ui32 NumberOfSlotsInChunk;
+
+ TChunkInfo(ui32 slotSize, ui32 numberOfSlotsInChunk)
+ : SlotSize(slotSize)
+ , NumberOfSlotsInChunk(numberOfSlotsInChunk)
+ {}
+
+ TString ToString() const {
+ TStringStream str;
+ str << "UsefulSlots# " << UsefulSlots << "/" << NumberOfSlotsInChunk;
+ return str.Str();
+ }
+ };
+
+ // Aggregated info gathered per slotSize
+ struct TAggrSlotInfo {
+ ui64 UsefulSlots = 0;
+ ui32 UsedChunks = 0;
+ std::unordered_map<ui32, const std::vector<THugeBlobRecord>*> RecordPtrs;
+ const ui32 NumberOfSlotsInChunk;
+
+ TAggrSlotInfo(ui32 numberOfSlotsInChunk)
+ : NumberOfSlotsInChunk(numberOfSlotsInChunk)
+ {}
+ };
+
+ class TChunksMap {
+ private:
+ using TPerChunkMap = THashMap<ui32, TChunkInfo>; // chunkIdx -> TChunkInfo
+ using TAggrBySlotSize = THashMap<ui32, TAggrSlotInfo>; // slotSize -> TAggrSlotInfo
+ const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ TPerChunkMap PerChunkMap;
+
+ private:
+ TAggrBySlotSize AggregatePerSlotSize() const {
+ TAggrBySlotSize aggrSlots;
+ for (const auto& [chunkIdx, chunk] : PerChunkMap) {
+ auto it = aggrSlots.try_emplace(chunk.SlotSize, chunk.NumberOfSlotsInChunk).first;
+ TAggrSlotInfo& aggr = it->second;
+ aggr.UsefulSlots += chunk.UsefulSlots;
+ ++aggr.UsedChunks;
+ aggr.RecordPtrs.emplace(chunkIdx, &chunk.Records);
+ }
+ return aggrSlots;
+ }
+
+ public:
+ TChunksMap(const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx)
+ : HugeBlobCtx(hugeBlobCtx)
+ {}
+
+ void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
+ auto it = PerChunkMap.find(part.ChunkIdx);
+ if (it == PerChunkMap.end()) {
+ const THugeSlotsMap::TSlotInfo *slotInfo = HugeBlobCtx->HugeSlotsMap->GetSlotInfo(part.Size);
+ Y_VERIFY(slotInfo, "size# %" PRIu32, part.Size);
+ it = PerChunkMap.emplace(std::piecewise_construct, std::make_tuple(part.ChunkIdx),
+ std::make_tuple(slotInfo->SlotSize, slotInfo->NumberOfSlotsInChunk)).first;
+ }
+ it->second.UsefulSlots += useful;
+ it->second.Records.push_back(THugeBlobRecord{part, id, useful});
+ }
+
+ TChunksToDefrag GetChunksToDefrag(size_t maxChunksToDefrag) const {
+ TAggrBySlotSize aggrSlots = AggregatePerSlotSize();
+
+ std::vector<const TPerChunkMap::value_type*> chunks;
+ chunks.reserve(PerChunkMap.size());
+ for (const auto& kv : PerChunkMap) {
+ chunks.push_back(&kv);
+ }
+ auto cmpByMoveSize = [](const auto *left, const auto *right) {
+ return left->second.UsefulSlots < right->second.UsefulSlots;
+ };
+ std::sort(chunks.begin(), chunks.end(), cmpByMoveSize);
+
+ TChunksToDefrag result;
+ result.Chunks.reserve(maxChunksToDefrag);
+
+ for (const auto *kv : chunks) {
+ const auto& [chunkIdx, chunk] = *kv;
+ auto it = aggrSlots.find(chunk.SlotSize);
+ Y_VERIFY(it != aggrSlots.end());
+ auto& a = it->second;
+
+ // if we can put all current used slots into UsedChunks - 1, then defragment this chunk
+ if (a.NumberOfSlotsInChunk * (a.UsedChunks - 1) >= a.UsefulSlots) {
+ --a.UsedChunks;
+ ++result.FoundChunksToDefrag;
+ if (result.Chunks.size() < maxChunksToDefrag) {
+ result.Chunks.emplace_back(chunkIdx, chunk.SlotSize);
+ result.EstimatedSlotsCount += chunk.UsefulSlots;
+ const auto& rp = a.RecordPtrs.at(chunkIdx);
+ result.HugeBlobs.insert(result.HugeBlobs.end(), rp->begin(), rp->end());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ void Output(IOutputStream &str) const {
+ str << "{ChunksMap# [";
+ bool first = true;
+ for (auto& [chunkId, info] : PerChunkMap) {
+ if (first) {
+ first = false;
+ } else {
+ str << " ";
+ }
+ str << "{chunkId# " << chunkId << " " << info.ToString() << "}";
+ }
+ str << "]}";
+ }
+
+ TString ToString() const {
+ TStringStream str;
+ Output(str);
+ return str.Str();
+ }
+ };
+
+ TChunksMap ChunksMap;
+
+ public:
+ TDefragQuantumChunkFinder(const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx)
+ : ChunksMap(hugeBlobCtx)
+ {}
+
+ TChunksToDefrag GetChunksToDefrag(size_t maxChunksToDefrag) {
+ return ChunksMap.GetChunksToDefrag(maxChunksToDefrag);
+ }
+
+ void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
+ ChunksMap.Add(part, id, useful);
+ }
+ };
+
+ class TDefragQuantumFindChunks
+ : public TDefragQuantumChunkFinder
+ , public TDefragScanner<TDefragQuantumFindChunks>
+ {
+ public:
+ TDefragQuantumFindChunks(THullDsSnap&& snap, const std::shared_ptr<THugeBlobCtx>& hugeBlobCtx)
+ : TDefragQuantumChunkFinder(hugeBlobCtx)
+ , TDefragScanner(std::move(snap))
+ {}
+
+ using TDefragQuantumChunkFinder::Add;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class TDefragQuantumFindRecords {
+ using TLevelSegment = ::NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelSstPtr = typename TLevelSegment::TLevelSstPtr;
+
+ THullDsSnap FullSnap;
+ TChunksToDefrag ChunksToDefrag;
+ std::unordered_set<ui32> Chunks; // chunks to defrag (i.e. move all data from these chunks)
+ std::vector<TDefragRecord> RecsToRewrite;
+ TDuration MaxTime;
+ std::function<void()> Yield;
+ ui64 EndTime;
+ ui32 Count;
+
+ public:
+ TDefragQuantumFindRecords(THullDsSnap&& fullSnap, TChunksToDefrag&& chunksToDefrag)
+ : FullSnap(std::move(fullSnap))
+ , ChunksToDefrag(std::move(chunksToDefrag))
+ {
+ for (const auto& chunk : ChunksToDefrag.Chunks) {
+ Chunks.insert(chunk.ChunkId);
+ }
+ Y_VERIFY(Chunks.size() == ChunksToDefrag.Chunks.size()); // ensure there are no duplicate numbers
+ std::sort(ChunksToDefrag.HugeBlobs.begin(), ChunksToDefrag.HugeBlobs.end());
+ RecsToRewrite.reserve(ChunksToDefrag.EstimatedSlotsCount);
+ }
+
+ template<typename T>
+ void Scan(TDuration maxTime, T&& yield) {
+ MaxTime = maxTime;
+ Yield = yield;
+ EndTime = GetCycleCountFast() + DurationToCycles(MaxTime);
+ Count = 0;
+ TraverseDbWithoutMerge(FullSnap.HullCtx, this, FullSnap.LogoBlobsSnap);
+ }
+
+ void UpdateFresh(const char* /*segName*/, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
+ Update(key, memRec, nullptr);
+ }
+
+ void UpdateLevel(const TLevelSstPtr& p, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
+ Update(key, memRec, p.SstPtr->GetOutbound());
+ }
+
+ void Update(const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec, const TDiskPart *outbound) {
+ TDiskDataExtractor extr;
+ if (memRec.GetType() == TBlobType::HugeBlob || memRec.GetType() == TBlobType::ManyHugeBlobs) {
+ memRec.GetDiskData(&extr, outbound);
+ const NMatrix::TVectorType local = memRec.GetIngress().LocalParts(FullSnap.HullCtx->VCtx->Top->GType);
+ ui8 partIdx = local.FirstPosition();
+ for (const TDiskPart *p = extr.Begin; p != extr.End; ++p, partIdx = local.NextPosition(partIdx)) {
+ Y_VERIFY(partIdx != local.GetSize());
+ if (!p->ChunkIdx || !Chunks.count(p->ChunkIdx)) {
+ continue; // not from chunks of our interest
+ }
+
+ const TLogoBlobID fullId = key.LogoBlobID();
+ const auto it = std::lower_bound(ChunksToDefrag.HugeBlobs.begin(), ChunksToDefrag.HugeBlobs.end(),
+ THugeBlobRecord{*p, fullId, true});
+ if (it == ChunksToDefrag.HugeBlobs.end() || it->Part != *p || it->Id != fullId || it->Useful) {
+ RecsToRewrite.emplace_back(TLogoBlobID(fullId, partIdx + 1), *p);
+ }
+ }
+ }
+ if (++Count % 1024 == 0 && GetCycleCountFast() >= EndTime) {
+ Yield();
+ EndTime = GetCycleCountFast() + DurationToCycles(MaxTime);
+ }
+ }
+
+ void Finish() {}
+
+ THullDsSnap RetrieveSnapshot() {
+ return std::move(FullSnap);
+ }
+
+ std::vector<TDefragRecord> GetRecordsToRewrite() {
+ return std::move(RecsToRewrite);
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class TDefragCalcStat
+ : public TDefragScanner<TDefragCalcStat>
+ , public TDefragQuantumChunkFinder
+ {
+ struct TPerSlotSizeInfo {
+ ui32 UsefulSlots = 0;
+ const ui32 NumberOfSlotsInChunk;
+
+ TPerSlotSizeInfo(ui32 numberOfSlotsInChunk)
+ : NumberOfSlotsInChunk(numberOfSlotsInChunk)
+ {}
+ };
+
+ std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ std::unordered_set<ui32> Chunks;
+ std::unordered_map<ui32, ui32> Map; // numberOfSlotsInChunk -> usefulSlots
+
+ public:
+ TDefragCalcStat(THullDsSnap&& fullSnap, const std::shared_ptr<THugeBlobCtx>& hugeBlobCtx)
+ : TDefragScanner(std::move(fullSnap))
+ , TDefragQuantumChunkFinder(hugeBlobCtx)
+ , HugeBlobCtx(hugeBlobCtx)
+ {}
+
+ void Add(TDiskPart part, const TLogoBlobID& id, bool useful) {
+ Chunks.insert(part.ChunkIdx);
+ if (useful) {
+ const THugeSlotsMap::TSlotInfo *slotInfo = HugeBlobCtx->HugeSlotsMap->GetSlotInfo(part.Size);
+ Y_VERIFY(slotInfo, "size# %" PRIu32, part.Size);
+ ++Map[slotInfo->NumberOfSlotsInChunk];
+ }
+ TDefragQuantumChunkFinder::Add(part, id, useful);
+ }
+
+ ui32 GetTotalChunks() {
+ return Chunks.size();
+ }
+
+ ui32 GetUsefulChunks() {
+ ui32 res = 0;
+ for (const auto& [numberOfSlotsInChunk, usefulSlots] : Map) {
+ res += (usefulSlots + numberOfSlotsInChunk - 1) / numberOfSlotsInChunk;
+ }
+ return res;
+ }
+ };
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/defrag/defs.h b/ydb/core/blobstorage/vdisk/defrag/defs.h
index 24208cbbcd8..e038d88523e 100644
--- a/ydb/core/blobstorage/vdisk/defrag/defs.h
+++ b/ydb/core/blobstorage/vdisk/defrag/defs.h
@@ -1,4 +1,4 @@
#pragma once
-
+
// unique tag to fix pragma once gcc glueing: ./ydb/core/blobstorage/vdisk/defrag/defs.h
#include <ydb/core/blobstorage/vdisk/defs.h>
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_basic.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_basic.cpp
index da29a8822b2..ba19f629e6c 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_basic.cpp
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_basic.cpp
@@ -93,10 +93,10 @@ namespace NKikimr {
bool TProxyState::Restore(const TActorContext &ctx,
const TLogoBlobID &id,
ui64 fullDataSize,
- TRope&& data) {
+ TRope&& data) {
Y_VERIFY(Initialized, "Restore(%p): SelfVDiskID# %s TargetVDiskID# %s id# %s",
this, SelfVDiskID.ToString().data(), TargetVDiskID.ToString().data(), id.ToString().data());
- ui32 byteSize = TEvLocalHandoff::ByteSize(data.GetSize());
+ ui32 byteSize = TEvLocalHandoff::ByteSize(data.GetSize());
Y_VERIFY_DEBUG(byteSize < MaxBytes);
while (true) {
@@ -110,7 +110,7 @@ namespace NKikimr {
bool done = AtomicCas<ui64>((ui64 *)&Monitor, newMonitor, monitor);
if (done) {
// send message
- ctx.Send(ProxyID, new TEvLocalHandoff(id, fullDataSize, data.ConvertToString()));
+ ctx.Send(ProxyID, new TEvLocalHandoff(id, fullDataSize, data.ConvertToString()));
return true;
}
} else {
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_basic.h b/ydb/core/blobstorage/vdisk/handoff/handoff_basic.h
index 0a8380a8fcb..4dfc1d3e846 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_basic.h
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_basic.h
@@ -92,7 +92,7 @@ namespace NKikimr {
bool Restore(const TActorContext &ctx,
const TLogoBlobID &id,
ui64 fullDataSize,
- TRope&& data);
+ TRope&& data);
void FreeElement(ui32 byteSize);
TString ToString() const;
};
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.cpp
index f37aca976ac..b0952de3851 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.cpp
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.cpp
@@ -38,7 +38,7 @@ namespace NKikimr {
THandoffDelegate::THandoffDelegate(const TVDiskIdShort &self,
TIntrusivePtr<TBlobStorageGroupInfo> info,
const THandoffParams &params)
- : Fields(std::make_unique<TFields>(self, info, params))
+ : Fields(std::make_unique<TFields>(self, info, params))
{}
TActiveActors THandoffDelegate::RunProxies(const TActorContext &ctx) {
@@ -66,13 +66,13 @@ namespace NKikimr {
const TVDiskIdShort &vdisk,
const TLogoBlobID &id,
ui64 fullDataSize,
- TRope&& data) {
+ TRope&& data) {
TVDiskInfo &ref = (*Fields->ProxiesPtr)[vdisk];
Y_VERIFY_DEBUG(Fields->ProxiesStarted &&
vdisk == Fields->Info->GetVDiskId(ref.OrderNumber) &&
vdisk != Fields->SelfVDisk &&
vdisk == ref.Get().TargetVDiskID);
- return ref.Get().Restore(ctx, id, fullDataSize, std::move(data));
+ return ref.Get().Restore(ctx, id, fullDataSize, std::move(data));
}
TActorId THandoffDelegate::GetMonActorID() const {
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h b/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h
index eaedc8bb04b..b2c51e3eae5 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h
@@ -40,12 +40,12 @@ namespace NKikimr {
const TVDiskIdShort &vdisk,
const TLogoBlobID &id,
ui64 fullDataSize,
- TRope&& data);
+ TRope&& data);
TActorId GetMonActorID() const;
private:
struct TFields;
- std::unique_ptr<TFields> Fields;
+ std::unique_ptr<TFields> Fields;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_map.h b/ydb/core/blobstorage/vdisk/handoff/handoff_map.h
index 9e7480f60fe..9d3e1e345fa 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_map.h
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_map.h
@@ -118,7 +118,7 @@ namespace NKikimr {
private:
THullCtxPtr HullCtx;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
TIntrusivePtr<THandoffDelegate> HandoffDelegate;
const bool RunHandoff;
const TActorId SkeletonId;
@@ -220,9 +220,9 @@ namespace NKikimr {
if (memRec->GetType() == TBlobType::HugeBlob) {
Y_FAIL("Implement"); // FIXME
} else if (memRec->GetType() == TBlobType::DiskBlob) {
- const auto& merger = dataMerger->GetDiskBlobMerger();
- const TDiskBlob& blob = merger.GetDiskBlob();
- ui32 fullDataSize = blob.GetFullDataSize();
+ const auto& merger = dataMerger->GetDiskBlobMerger();
+ const TDiskBlob& blob = merger.GetDiskBlob();
+ ui32 fullDataSize = blob.GetFullDataSize();
// iterate via parts
for (TDiskBlob::TPartIterator it = blob.begin(), e = blob.end(); it != e; ++it) {
@@ -230,11 +230,11 @@ namespace NKikimr {
Y_VERIFY_DEBUG(partId > 0);
if (moveVec.Get(partId - 1)) {
TLogoBlobID id(key.LogoBlobID(), partId);
- TVDiskIdShort vdisk(memRec->GetIngress().GetMainReplica(Top.get(), id));
+ TVDiskIdShort vdisk(memRec->GetIngress().GetMainReplica(Top.get(), id));
// FIXME: for huge blobs we need to implement an actor which makes read, because we don't have
// this blob in memory
- TRope temp;
- bool res = HandoffDelegate->Restore(ctx, vdisk, id, fullDataSize, it.GetPart());
+ TRope temp;
+ bool res = HandoffDelegate->Restore(ctx, vdisk, id, fullDataSize, it.GetPart());
Stat.SuccessfulMoveSend += ui64(res);
Stat.FailedMoveSend += ui64(!res);
}
@@ -257,8 +257,8 @@ namespace NKikimr {
Y_FAIL("Implement"); // FIXME
} else if (memRec->GetType() == TBlobType::DiskBlob) {
TIngress ingress = memRec->GetIngress(); // ingress we are going to change
- const auto& merger = dataMerger->GetDiskBlobMerger();
- const TDiskBlob& blob = merger.GetDiskBlob();
+ const auto& merger = dataMerger->GetDiskBlobMerger();
+ const TDiskBlob& blob = merger.GetDiskBlob();
// a vector of local parts we have in ingress; we may have some of them missing in actual
// data merger as it contains only MemBlob items
@@ -269,16 +269,16 @@ namespace NKikimr {
if (delVec.Get(i)) {
const ui8 partId = i + 1;
TLogoBlobID id(key.LogoBlobID(), partId);
- ingress.DeleteHandoff(Top.get(), HullCtx->VCtx->ShortSelfVDisk, id);
+ ingress.DeleteHandoff(Top.get(), HullCtx->VCtx->ShortSelfVDisk, id);
localParts.Clear(i);
}
}
// create new blob from kept parts
TDataMerger dataMerger;
- for (auto it = blob.begin(); it != blob.end(); ++it) {
- if (localParts.Get(it.GetPartId() - 1)) {
- dataMerger.AddPart(blob, it);
+ for (auto it = blob.begin(); it != blob.end(); ++it) {
+ if (localParts.Get(it.GetPartId() - 1)) {
+ dataMerger.AddPart(blob, it);
}
}
// SetNewDisk can handle empty dataMerger correctly.
@@ -328,7 +328,7 @@ namespace NKikimr {
// check ingress
TLogoBlobID id(dbIt.GetCurKey().LogoBlobID());
TIngress levelIngress = dbMerger.GetMemRec().GetIngress();
- TIngress::TPairOfVectors moveDel = levelIngress.HandoffParts(Top.get(), HullCtx->VCtx->ShortSelfVDisk, id);
+ TIngress::TPairOfVectors moveDel = levelIngress.HandoffParts(Top.get(), HullCtx->VCtx->ShortSelfVDisk, id);
MoveMap.push_back(moveDel.first.Raw());
DelMap.push_back(moveDel.second.Raw());
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_mon.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_mon.cpp
index 5aa0e92348f..c5e8d4b346c 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_mon.cpp
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_mon.cpp
@@ -88,11 +88,11 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvHandoffProxyMonResult, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvHandoffProxyMonResult, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
// outputs state in HTML
struct TPrinter {
@@ -110,13 +110,13 @@ namespace NKikimr {
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HANDOFF_MON_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HANDOFF_MON_REQUEST;
}
THandoffMonRequestActor(const TActorId &parentId,
const TVDiskID &selfVDisk,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
TProxiesPtr proxiesPtr,
NMon::TEvHttpInfo::TPtr &ev)
: TActorBootstrapped<THandoffMonRequestActor>()
@@ -134,14 +134,14 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class THandoffMonActor : public TActor<THandoffMonActor> {
const TVDiskID SelfVDisk;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
TProxiesPtr ProxiesPtr;
TActiveActors ActiveActors;
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
Y_VERIFY_DEBUG(ev->Get()->SubRequestId == TDbMon::HandoffMonId);
- auto actor = std::make_unique<THandoffMonRequestActor>(ctx.SelfID, SelfVDisk, Top, ProxiesPtr, ev);
- auto aid = ctx.Register(actor.release());
+ auto actor = std::make_unique<THandoffMonRequestActor>(ctx.SelfID, SelfVDisk, Top, ProxiesPtr, ev);
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
}
@@ -156,19 +156,19 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvents::TEvActorDied, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HANDOFF_MON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HANDOFF_MON;
}
THandoffMonActor(const TVDiskID &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
TProxiesPtr proxiesPtr)
: TActor<THandoffMonActor>(&TThis::StateFunc)
, SelfVDisk(selfVDisk)
@@ -178,7 +178,7 @@ namespace NKikimr {
};
IActor *CreateHandoffMonActor(const TVDiskID &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
TProxiesPtr proxiesPtr) {
return new THandoffMonActor(selfVDisk, top, proxiesPtr);
}
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_mon.h b/ydb/core/blobstorage/vdisk/handoff/handoff_mon.h
index e785738f2da..aacc42b0056 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_mon.h
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_mon.h
@@ -6,7 +6,7 @@
namespace NKikimr {
IActor *CreateHandoffMonActor(const TVDiskID &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
NHandoff::TProxiesPtr proxiesPtr);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp
index 9a2d1676e0e..2a5a83973db 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_proxy.cpp
@@ -62,21 +62,21 @@ namespace NKikimr {
|| (State.InFlightQueueByteSize + size >= Params.MaxInFlightByteSize);
}
- void SendItem(const TActorContext &ctx, std::unique_ptr<TEvLocalHandoff> item) {
+ void SendItem(const TActorContext &ctx, std::unique_ptr<TEvLocalHandoff> item) {
auto vd = Info->GetVDiskId(VDiskInfoPtr->OrderNumber);
auto aid = Info->GetActorId(VDiskInfoPtr->OrderNumber);
- auto msg = std::make_unique<TEvBlobStorage::TEvVPut>(item->Id, item->Data, vd, true, &item->Cookie,
- TInstant::Max(), NKikimrBlobStorage::AsyncBlob);
+ auto msg = std::make_unique<TEvBlobStorage::TEvVPut>(item->Id, item->Data, vd, true, &item->Cookie,
+ TInstant::Max(), NKikimrBlobStorage::AsyncBlob);
State.InFlightQueueSize++;
State.InFlightQueueByteSize += item->ByteSize();
- InFlightQueue.PushBack(item.release());
+ InFlightQueue.PushBack(item.release());
State.LastSendTime = TAppData::TimeProvider->Now();
- ctx.Send(aid, msg.release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
+ ctx.Send(aid, msg.release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
}
void DisposeFrontItem() {
- std::unique_ptr<TEvLocalHandoff> item(InFlightQueue.PopFront());
+ std::unique_ptr<TEvLocalHandoff> item(InFlightQueue.PopFront());
ui32 byteSize = item->ByteSize();
State.InFlightQueueSize--;
State.InFlightQueueByteSize -= byteSize;
@@ -85,14 +85,14 @@ namespace NKikimr {
VDiskInfoPtr->Get().FreeElement(byteSize);
}
- void PutToWaitQueue(std::unique_ptr<TEvLocalHandoff> item) {
+ void PutToWaitQueue(std::unique_ptr<TEvLocalHandoff> item) {
State.WaitQueueSize++;
State.WaitQueueByteSize += item->ByteSize();
- WaitQueue.PushBack(item.release());
+ WaitQueue.PushBack(item.release());
}
- std::unique_ptr<TEvLocalHandoff> GetFromWaitQueue() {
- std::unique_ptr<TEvLocalHandoff> item(WaitQueue.PopFront());
+ std::unique_ptr<TEvLocalHandoff> GetFromWaitQueue() {
+ std::unique_ptr<TEvLocalHandoff> item(WaitQueue.PopFront());
State.WaitQueueSize--;
State.WaitQueueByteSize -= item->ByteSize();
return item;
@@ -103,7 +103,7 @@ namespace NKikimr {
ui32 maxCntr = State.BadnessState == TPrivateProxyState::GOOD ? Max<ui32>() : 1;
ui32 cntr = 0;
while (cntr < maxCntr && !WaitQueueIsEmpty() && !InFlightQueueIsFull(WaitQueue.Front()->ByteSize())) {
- SendItem(ctx, GetFromWaitQueue());
+ SendItem(ctx, GetFromWaitQueue());
cntr++;
}
}
@@ -118,7 +118,7 @@ namespace NKikimr {
"THandoffProxyActor(%s)::Handle(TEvLocalHandoff)",
VDiskInfoPtr->VDiskIdShort.ToString().data()));
- std::unique_ptr<TEvLocalHandoff> item(ev->Release().Release());
+ std::unique_ptr<TEvLocalHandoff> item(ev->Release().Release());
ui32 byteSize = item->ByteSize();
SendQueuedMessagesUntilAllowed(ctx);
@@ -126,11 +126,11 @@ namespace NKikimr {
if (!InFlightQueueIsFull(byteSize)) {
//Y_VERIFY_DEBUG(WaitQueueIsEmpty()); // FIXME: it seems that assert is invalid
item->Cookie = GenerateCookie();
- SendItem(ctx, std::move(item));
+ SendItem(ctx, std::move(item));
Counters.LocalHandoffSendRightAway++;
} else if (!WaitQueueIsFull(byteSize)) {
item->Cookie = GenerateCookie();
- PutToWaitQueue(std::move(item));
+ PutToWaitQueue(std::move(item));
Counters.LocalHandoffPostpone++;
} else {
Counters.LocalHandoffDiscard++;
@@ -150,12 +150,12 @@ namespace NKikimr {
// move all in flight messages to the wait queue for retrying
while (!InFlightQueueIsEmpty()) {
- std::unique_ptr<TEvLocalHandoff> item(InFlightQueue.PopBack());
+ std::unique_ptr<TEvLocalHandoff> item(InFlightQueue.PopBack());
ui32 byteSize = item->ByteSize();
State.InFlightQueueSize--;
State.InFlightQueueByteSize -= byteSize;
- WaitQueue.PushFront(item.release());
+ WaitQueue.PushFront(item.release());
State.WaitQueueSize++;
State.WaitQueueByteSize += byteSize;
}
@@ -292,19 +292,19 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvLocalHandoff, Handle)
- HFunc(TEvBlobStorage::TEvVPutResult, Handle)
- HFunc(TEvents::TEvUndelivered, Handle)
- HFunc(TEvHandoffProxyMon, Handle)
- HFunc(TEvBlobStorage::TEvVWindowChange, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvLocalHandoff, Handle)
+ HFunc(TEvBlobStorage::TEvVPutResult, Handle)
+ HFunc(TEvents::TEvUndelivered, Handle)
+ HFunc(TEvHandoffProxyMon, Handle)
+ HFunc(TEvBlobStorage::TEvVWindowChange, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HANDOFF_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HANDOFF_PROXY;
}
diff --git a/ydb/core/blobstorage/vdisk/handoff/handoff_synclogproxy.cpp b/ydb/core/blobstorage/vdisk/handoff/handoff_synclogproxy.cpp
index 4d4f55b88bf..6f12a58d4ae 100644
--- a/ydb/core/blobstorage/vdisk/handoff/handoff_synclogproxy.cpp
+++ b/ydb/core/blobstorage/vdisk/handoff/handoff_synclogproxy.cpp
@@ -56,15 +56,15 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvHandoffSyncLogDel, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvHandoffSyncLogDel, Handle)
HFunc(TEvDelLogoBlobDataSyncLogResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HANDOFF_SYNCLOG_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HANDOFF_SYNCLOG_PROXY;
}
THandoffSyncLogProxy(const TActorId &skeletonId,
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.cpp
index 30d2aeece40..4a98a75f67e 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.cpp
@@ -22,49 +22,49 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class THugeBlobLogLsnFifo {
public:
- ui64 Push(ui64 lsn) {
- Y_VERIFY_S(Fifo.empty() || Fifo.rbegin()->second <= lsn, ErrorReport(SeqWriteId, lsn));
- if (NodeCache.empty()) {
- Fifo.emplace_hint(Fifo.end(), SeqWriteId, lsn);
- } else {
- auto& nh = NodeCache.back();
- nh.key() = SeqWriteId;
- nh.mapped() = lsn;
- Fifo.insert(Fifo.end(), std::move(nh));
- NodeCache.pop_back();
- }
+ ui64 Push(ui64 lsn) {
+ Y_VERIFY_S(Fifo.empty() || Fifo.rbegin()->second <= lsn, ErrorReport(SeqWriteId, lsn));
+ if (NodeCache.empty()) {
+ Fifo.emplace_hint(Fifo.end(), SeqWriteId, lsn);
+ } else {
+ auto& nh = NodeCache.back();
+ nh.key() = SeqWriteId;
+ nh.mapped() = lsn;
+ Fifo.insert(Fifo.end(), std::move(nh));
+ NodeCache.pop_back();
+ }
return SeqWriteId++;
}
- void Pop(ui64 wId, ui64 lsn, bool logged) {
- Y_VERIFY_S(!Fifo.empty(), ErrorReport(wId, lsn));
- const auto it = Fifo.find(wId);
- Y_VERIFY(it != Fifo.end());
- Y_VERIFY_S(!logged || it->second <= lsn, ErrorReport(wId, lsn));
- if (NodeCache.size() < NodeCacheMaxSize) {
- NodeCache.push_back(Fifo.extract(it));
+ void Pop(ui64 wId, ui64 lsn, bool logged) {
+ Y_VERIFY_S(!Fifo.empty(), ErrorReport(wId, lsn));
+ const auto it = Fifo.find(wId);
+ Y_VERIFY(it != Fifo.end());
+ Y_VERIFY_S(!logged || it->second <= lsn, ErrorReport(wId, lsn));
+ if (NodeCache.size() < NodeCacheMaxSize) {
+ NodeCache.push_back(Fifo.extract(it));
} else {
- Fifo.erase(it);
+ Fifo.erase(it);
}
}
ui64 FirstLsnToKeep() const {
- return Fifo.empty() ? Max<ui64>() : Fifo.begin()->second;
+ return Fifo.empty() ? Max<ui64>() : Fifo.begin()->second;
}
TString FirstLsnToKeepDecomposed() const {
- const ui64 lsn = FirstLsnToKeep();
- return lsn != Max<ui64>() ? ToString(lsn) : "Max";
+ const ui64 lsn = FirstLsnToKeep();
+ return lsn != Max<ui64>() ? ToString(lsn) : "Max";
}
private:
- std::map<ui64, ui64> Fifo;
- TStackVec<std::map<ui64, ui64>::node_type, 8> NodeCache;
- static constexpr size_t NodeCacheMaxSize = 64;
- ui64 SeqWriteId = 0;
+ std::map<ui64, ui64> Fifo;
+ TStackVec<std::map<ui64, ui64>::node_type, 8> NodeCache;
+ static constexpr size_t NodeCacheMaxSize = 64;
+ ui64 SeqWriteId = 0;
TString ErrorReport(ui64 wId, ui64 lsn) const {
- return TStringBuilder() << "wId# " << wId << " lsn# " << lsn << " Fifo# " << FifoToString();
+ return TStringBuilder() << "wId# " << wId << " lsn# " << lsn << " Fifo# " << FifoToString();
}
TString FifoToString() const {
@@ -73,11 +73,11 @@ namespace NKikimr {
if (Fifo.empty())
str << "empty";
else {
- const auto& front = *Fifo.begin();
- str << "{front# {wId# " << front.first << " lsn# " << front.second << "}";
- const auto& back = *Fifo.rbegin();
- str << " back# {wId# " << back.first << " lsn# " << back.second << "}"
- << " size# " << Fifo.size() << "}";
+ const auto& front = *Fifo.begin();
+ str << "{front# {wId# " << front.first << " lsn# " << front.second << "}";
+ const auto& back = *Fifo.rbegin();
+ str << " back# {wId# " << back.first << " lsn# " << back.second << "}"
+ << " size# " << Fifo.size() << "}";
}
str << "}";
return str.Str();
@@ -91,13 +91,13 @@ namespace NKikimr {
public:
const ui32 ChunkId;
- explicit TEvHullHugeChunkAllocated(ui32 chunkId)
+ explicit TEvHullHugeChunkAllocated(ui32 chunkId)
: ChunkId(chunkId)
{}
TString ToString() const {
TStringStream str;
- str << "{ChunkId# " << ChunkId << "}";
+ str << "{ChunkId# " << ChunkId << "}";
return str.Str();
}
};
@@ -105,7 +105,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TEvHullHugeChunkFreed
////////////////////////////////////////////////////////////////////////////
- struct TEvHullHugeChunkFreed : TEventLocal<TEvHullHugeChunkFreed, TEvBlobStorage::EvHullHugeChunkFreed> {};
+ struct TEvHullHugeChunkFreed : TEventLocal<TEvHullHugeChunkFreed, TEvBlobStorage::EvHullHugeChunkFreed> {};
////////////////////////////////////////////////////////////////////////////
// TEvHullHugeCommitted
@@ -147,10 +147,10 @@ namespace NKikimr {
// THullHugeBlobWriter
////////////////////////////////////////////////////////////////////////////
class THullHugeBlobWriter : public TActorBootstrapped<THullHugeBlobWriter> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
const TActorId NotifyID;
const NHuge::THugeSlot HugeSlot;
- std::unique_ptr<TEvHullWriteHugeBlob> Item;
+ std::unique_ptr<TEvHullWriteHugeBlob> Item;
ui64 WriteId;
TDiskPart DiskAddr;
static void *Cookie;
@@ -173,11 +173,11 @@ namespace NKikimr {
const ui8 partId = Item->LogoBlobId.PartId();
Y_VERIFY(partId != 0);
- const ui32 storedBlobSize = Item->Data.GetSize();
- const ui32 writtenSize = AlignUpAppendBlockSize(storedBlobSize, HugeKeeperCtx->PDiskCtx->Dsk->AppendBlockSize);
+ const ui32 storedBlobSize = Item->Data.GetSize();
+ const ui32 writtenSize = AlignUpAppendBlockSize(storedBlobSize, HugeKeeperCtx->PDiskCtx->Dsk->AppendBlockSize);
Y_VERIFY(writtenSize <= HugeSlot.GetSize());
- NPDisk::TEvChunkWrite::TPartsPtr partsPtr(new NPDisk::TEvChunkWrite::TRopeAlignedParts(std::move(Item->Data), writtenSize));
+ NPDisk::TEvChunkWrite::TPartsPtr partsPtr(new NPDisk::TEvChunkWrite::TRopeAlignedParts(std::move(Item->Data), writtenSize));
ui32 chunkId = HugeSlot.GetChunkId();
ui32 offset = HugeSlot.GetOffset();
HugeKeeperCtx->LsmHullGroup.LsmHugeBytesWritten() += partsPtr->ByteSize();
@@ -201,7 +201,7 @@ namespace NKikimr {
ctx.Send(NotifyID, new TEvHullHugeWritten(HugeSlot));
ctx.Send(HugeKeeperCtx->SkeletonId,
new TEvHullLogHugeBlob(WriteId, Item->LogoBlobId, Item->Ingress, DiskAddr,
- Item->IgnoreBlock, Item->SenderId, Item->Cookie, std::move(Item->Result)));
+ Item->IgnoreBlock, Item->SenderId, Item->Cookie, std::move(Item->Result)));
LOG_DEBUG(ctx, BS_HULLHUGE,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"Writer: finish: id# %s diskAddr# %s",
@@ -209,30 +209,30 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvChunkWriteResult, Handle)
- CFunc(TEvents::TSystem::Poison, Die)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvChunkWriteResult, Handle)
+ CFunc(TEvents::TSystem::Poison, Die)
+ )
- void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
+ void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_WRITER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_WRITER;
}
THullHugeBlobWriter(
- std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
+ std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
const TActorId &notifyID,
const NHuge::THugeSlot &hugeSlot,
- std::unique_ptr<TEvHullWriteHugeBlob> item,
+ std::unique_ptr<TEvHullWriteHugeBlob> item,
ui64 wId)
: TActorBootstrapped<TThis>()
, HugeKeeperCtx(std::move(hugeKeeperCtx))
, NotifyID(notifyID)
, HugeSlot(hugeSlot)
- , Item(std::move(item))
+ , Item(std::move(item))
, WriteId(wId)
, DiskAddr()
{}
@@ -244,11 +244,11 @@ namespace NKikimr {
// THullHugeBlobChunkAllocator
////////////////////////////////////////////////////////////////////////////
class THullHugeBlobChunkAllocator : public TActorBootstrapped<THullHugeBlobChunkAllocator> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
const TActorId NotifyID;
- ui64 Lsn;
- std::shared_ptr<THullHugeKeeperPersState> Pers;
- ui32 ChunkId = 0;
+ ui64 Lsn;
+ std::shared_ptr<THullHugeKeeperPersState> Pers;
+ ui32 ChunkId = 0;
friend class TActorBootstrapped<THullHugeBlobChunkAllocator>;
@@ -259,17 +259,17 @@ namespace NKikimr {
ctx.Send(HugeKeeperCtx->PDiskCtx->PDiskId,
new NPDisk::TEvChunkReserve(HugeKeeperCtx->PDiskCtx->Dsk->Owner,
HugeKeeperCtx->PDiskCtx->Dsk->OwnerRound, 1));
- TThis::Become(&TThis::StateFunc);
+ TThis::Become(&TThis::StateFunc);
}
void Handle(NPDisk::TEvChunkReserveResult::TPtr &ev, const TActorContext &ctx) {
CHECK_PDISK_RESPONSE(HugeKeeperCtx->VCtx, ev, ctx);
Y_VERIFY(ev->Get()->ChunkIds.size() == 1);
ChunkId = ev->Get()->ChunkIds.front();
- Lsn = HugeKeeperCtx->LsnMngr->AllocLsnForLocalUse().Point();
+ Lsn = HugeKeeperCtx->LsnMngr->AllocLsnForLocalUse().Point();
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkAllocator: reserved:"
- " chunkId# %" PRIu32 " Lsn# %" PRIu64, ChunkId, Lsn));
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkAllocator: reserved:"
+ " chunkId# %" PRIu32 " Lsn# %" PRIu64, ChunkId, Lsn));
// prepare commit record, i.e. commit reserved chunk
NPDisk::TCommitRecord commitRecord;
@@ -287,47 +287,47 @@ namespace NKikimr {
LOG_DEBUG(ctx, NKikimrServices::BS_VDISK_CHUNKS,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"COMMIT: type# HugeChunkAllocator msg# %s", commitRecord.ToString().data()));
-
- ctx.Send(HugeKeeperCtx->LoggerId, new NPDisk::TEvLog(HugeKeeperCtx->PDiskCtx->Dsk->Owner,
+
+ ctx.Send(HugeKeeperCtx->LoggerId, new NPDisk::TEvLog(HugeKeeperCtx->PDiskCtx->Dsk->Owner,
HugeKeeperCtx->PDiskCtx->Dsk->OwnerRound, TLogSignature::SignatureHugeBlobAllocChunk,
- commitRecord, data, TLsnSeg(Lsn, Lsn), nullptr));
-
- // commit changes to the persistent state at once
- const ui64 prevLsn = std::exchange(Pers->LogPos.ChunkAllocationLsn, Lsn);
- Y_VERIFY(prevLsn < Lsn);
- Pers->Heap->AddChunk(ChunkId);
+ commitRecord, data, TLsnSeg(Lsn, Lsn), nullptr));
+
+ // commit changes to the persistent state at once
+ const ui64 prevLsn = std::exchange(Pers->LogPos.ChunkAllocationLsn, Lsn);
+ Y_VERIFY(prevLsn < Lsn);
+ Pers->Heap->AddChunk(ChunkId);
}
void Handle(NPDisk::TEvLogResult::TPtr &ev, const TActorContext &ctx) {
CHECK_PDISK_RESPONSE(HugeKeeperCtx->VCtx, ev, ctx);
- Y_VERIFY(ev->Get()->Results.size() == 1 && ev->Get()->Results.front().Lsn == Lsn);
+ Y_VERIFY(ev->Get()->Results.size() == 1 && ev->Get()->Results.front().Lsn == Lsn);
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkAllocator: committed:"
- " chunkId# %" PRIu32 " LsnSeg# %" PRIu64, ChunkId, Lsn));
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkAllocator: committed:"
+ " chunkId# %" PRIu32 " LsnSeg# %" PRIu64, ChunkId, Lsn));
- ctx.Send(NotifyID, new TEvHullHugeChunkAllocated(ChunkId));
+ ctx.Send(NotifyID, new TEvHullHugeChunkAllocated(ChunkId));
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvChunkReserveResult, Handle)
- HFunc(NPDisk::TEvLogResult, Handle)
- CFunc(TEvents::TSystem::Poison, Die)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvChunkReserveResult, Handle)
+ HFunc(NPDisk::TEvLogResult, Handle)
+ CFunc(TEvents::TSystem::Poison, Die)
+ )
- void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
+ void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_CHUNKALLOC;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_CHUNKALLOC;
}
- THullHugeBlobChunkAllocator(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
- std::shared_ptr<THullHugeKeeperPersState> pers)
- : HugeKeeperCtx(std::move(hugeKeeperCtx))
+ THullHugeBlobChunkAllocator(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
+ std::shared_ptr<THullHugeKeeperPersState> pers)
+ : HugeKeeperCtx(std::move(hugeKeeperCtx))
, NotifyID(notifyID)
- , Pers(std::move(pers))
+ , Pers(std::move(pers))
{}
};
@@ -335,10 +335,10 @@ namespace NKikimr {
// THullHugeBlobChunkDestroyer
////////////////////////////////////////////////////////////////////////////
class THullHugeBlobChunkDestroyer : public TActorBootstrapped<THullHugeBlobChunkDestroyer> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
const TActorId NotifyID;
TVector<ui32> ChunksToFree;
- const ui64 Lsn;
+ const ui64 Lsn;
friend class TActorBootstrapped<THullHugeBlobChunkDestroyer>;
@@ -348,8 +348,8 @@ namespace NKikimr {
NHuge::TFreeChunkRecoveryLogRec logRec(ChunksToFree);
TString data = logRec.Serialize();
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkDestroyer: bootstrap:"
- " chunks# %s Lsn# %" PRIu64, FormatList(ChunksToFree).data(), Lsn));
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkDestroyer: bootstrap:"
+ " chunks# %s Lsn# %" PRIu64, FormatList(ChunksToFree).data(), Lsn));
// prepare commit record, i.e. commit reserved chunk
NPDisk::TCommitRecord commitRecord;
@@ -364,44 +364,44 @@ namespace NKikimr {
LOG_DEBUG(ctx, NKikimrServices::BS_VDISK_CHUNKS,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"COMMIT: type# HugeChunkDestroyer msg# %s", commitRecord.ToString().data()));
-
+
// send log message
- ctx.Send(HugeKeeperCtx->LoggerId, new NPDisk::TEvLog(HugeKeeperCtx->PDiskCtx->Dsk->Owner,
+ ctx.Send(HugeKeeperCtx->LoggerId, new NPDisk::TEvLog(HugeKeeperCtx->PDiskCtx->Dsk->Owner,
HugeKeeperCtx->PDiskCtx->Dsk->OwnerRound, TLogSignature::SignatureHugeBlobFreeChunk,
- commitRecord, data, TLsnSeg(Lsn, Lsn), nullptr));
+ commitRecord, data, TLsnSeg(Lsn, Lsn), nullptr));
TThis::Become(&TThis::StateFunc);
}
void Handle(NPDisk::TEvLogResult::TPtr &ev, const TActorContext &ctx) {
CHECK_PDISK_RESPONSE(HugeKeeperCtx->VCtx, ev, ctx);
- Y_VERIFY(ev->Get()->Results.size() == 1 && ev->Get()->Results.front().Lsn == Lsn);
+ Y_VERIFY(ev->Get()->Results.size() == 1 && ev->Get()->Results.front().Lsn == Lsn);
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkDestroyer: committed:"
- " chunks# %s Lsn# %" PRIu64, FormatList(ChunksToFree).data(), Lsn));
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "ChunkDestroyer: committed:"
+ " chunks# %s Lsn# %" PRIu64, FormatList(ChunksToFree).data(), Lsn));
- ctx.Send(NotifyID, new TEvHullHugeChunkFreed);
+ ctx.Send(NotifyID, new TEvHullHugeChunkFreed);
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvLogResult, Handle)
- CFunc(TEvents::TSystem::Poison, Die)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvLogResult, Handle)
+ CFunc(TEvents::TSystem::Poison, Die)
+ )
- void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
+ void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_CHUNKDESTROY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_CHUNKDESTROY;
}
- THullHugeBlobChunkDestroyer(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
- TVector<ui32> &&chunksToFree, ui64 lsn)
- : HugeKeeperCtx(std::move(hugeKeeperCtx))
+ THullHugeBlobChunkDestroyer(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
+ TVector<ui32> &&chunksToFree, ui64 lsn)
+ : HugeKeeperCtx(std::move(hugeKeeperCtx))
, NotifyID(notifyID)
- , ChunksToFree(std::move(chunksToFree))
- , Lsn(lsn)
+ , ChunksToFree(std::move(chunksToFree))
+ , Lsn(lsn)
{}
};
@@ -409,7 +409,7 @@ namespace NKikimr {
// THullHugeBlobEntryPointSaver
////////////////////////////////////////////////////////////////////////////
class THullHugeBlobEntryPointSaver : public TActorBootstrapped<THullHugeBlobEntryPointSaver> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
const TActorId NotifyID;
const ui64 EntryPointLsn;
const TString Serialized;
@@ -446,22 +446,22 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvLogResult, Handle)
- CFunc(TEvents::TSystem::Poison, Die)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvLogResult, Handle)
+ CFunc(TEvents::TSystem::Poison, Die)
+ )
- void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
+ void HandlePoison(TEvents::TEvPoison::TPtr&, const TActorContext& ctx) { Die(ctx); }
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_ENTRYPOINTSAVER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_HUGE_BLOB_ENTRYPOINTSAVER;
}
- THullHugeBlobEntryPointSaver(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
- ui64 entryPointLsn, const TString &serialized)
- : HugeKeeperCtx(std::move(hugeKeeperCtx))
+ THullHugeBlobEntryPointSaver(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &notifyID,
+ ui64 entryPointLsn, const TString &serialized)
+ : HugeKeeperCtx(std::move(hugeKeeperCtx))
, NotifyID(notifyID)
, EntryPointLsn(entryPointLsn)
, Serialized(serialized)
@@ -472,7 +472,7 @@ namespace NKikimr {
// THullHugeStatGather
////////////////////////////////////////////////////////////////////////////
class THullHugeStatGather : public TActorBootstrapped<THullHugeStatGather> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
const TActorId ParentId;
// we update stat every RenewPeriod seconds
const TDuration RenewPeriod = TDuration::Seconds(15);
@@ -517,7 +517,7 @@ namespace NKikimr {
return NKikimrServices::TActivity::BS_HULL_HUGE_KEEPER;
}
- THullHugeStatGather(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &parentId)
+ THullHugeStatGather(std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx, const TActorId &parentId)
: HugeKeeperCtx(std::move(hugeKeeperCtx))
, ParentId(parentId)
{}
@@ -541,14 +541,14 @@ namespace NKikimr {
bool Committing = false;
ui64 FreeUpToLsn = 0; // last value we got from PDisk
- TMaybe<TInstant> LastCommitTime;
- std::shared_ptr<THullHugeKeeperPersState> Pers;
+ TMaybe<TInstant> LastCommitTime;
+ std::shared_ptr<THullHugeKeeperPersState> Pers;
THugeBlobLogLsnFifo LogLsnFifo;
ui64 LastReportedFirstLsnToKeep = 0;
- THullHugeKeeperState(std::shared_ptr<THullHugeKeeperPersState> &&pers)
+ THullHugeKeeperState(std::shared_ptr<THullHugeKeeperPersState> &&pers)
: Pers(std::move(pers))
- {}
+ {}
ui64 FirstLsnToKeep() const {
ui64 persLsn = Pers->FirstLsnToKeep();
@@ -563,15 +563,15 @@ namespace NKikimr {
<< " LogLsnFifo# " << LogLsnFifo.FirstLsnToKeepDecomposed()
<< "}";
return str.Str();
- }
-
+ }
+
void RenderHtml(IOutputStream &str) {
auto boolToString = [] (bool x) { return x ? "true" : "false"; };
str << "WaitQueueSize: " << WaitQueueSize << "<br>";
str << "WaitQueueByteSize: " << WaitQueueByteSize << "<br>";
str << "Committing: " << boolToString(Committing) << "<br>";
str << "FreeUpToLsn: " << FreeUpToLsn << "<br>";
- str << "LastCommitTime: " << (LastCommitTime ? ToStringLocalTimeUpToSeconds(*LastCommitTime) : "not yet") << "<br>";
+ str << "LastCommitTime: " << (LastCommitTime ? ToStringLocalTimeUpToSeconds(*LastCommitTime) : "not yet") << "<br>";
str << "FirstLsnToKeep: " << FirstLsnToKeep() << "<br>";
Pers->RenderHtml(str);
}
@@ -620,62 +620,62 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// THullHugeKeeper
////////////////////////////////////////////////////////////////////////////
- class THullHugeKeeper : public TActorBootstrapped<THullHugeKeeper> {
- std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
+ class THullHugeKeeper : public TActorBootstrapped<THullHugeKeeper> {
+ std::shared_ptr<THugeKeeperCtx> HugeKeeperCtx;
THullHugeKeeperState State;
TActiveActors ActiveActors;
- std::unordered_set<ui32> AllocatingChunkPerSlotSize;
+ std::unordered_set<ui32> AllocatingChunkPerSlotSize;
- void PutToWaitQueue(std::unique_ptr<TEvHullWriteHugeBlob> item) {
+ void PutToWaitQueue(std::unique_ptr<TEvHullWriteHugeBlob> item) {
State.WaitQueueSize++;
State.WaitQueueByteSize += item->ByteSize();
- State.WaitQueue.PushBack(item.release());
- }
-
- bool ProcessWrite(TEvHullWriteHugeBlob *ev, const TActorContext& ctx) {
- NHuge::THugeSlot hugeSlot;
- ui32 slotSize;
- if (State.Pers->Heap->Allocate(ev->Data.GetSize(), &hugeSlot, &slotSize)) {
- if (!ev->Empty()) { // remove item from the WaitQueue
- --State.WaitQueueSize;
- State.WaitQueueByteSize -= ev->ByteSize();
- ev->Unlink();
- }
-
- const bool inserted = State.Pers->AllocatedSlots.insert(hugeSlot).second;
- Y_VERIFY(inserted);
- const ui64 wId = State.LogLsnFifo.Push(HugeKeeperCtx->LsnMngr->GetLsn());
- auto aid = ctx.Register(new THullHugeBlobWriter(HugeKeeperCtx, ctx.SelfID, hugeSlot,
- std::unique_ptr<TEvHullWriteHugeBlob>(ev), wId));
- ActiveActors.Insert(aid);
- return true;
- } else if (AllocatingChunkPerSlotSize.insert(slotSize).second) {
- auto aid = ctx.RegisterWithSameMailbox(new THullHugeBlobChunkAllocator(HugeKeeperCtx, ctx.SelfID, State.Pers));
- ActiveActors.Insert(aid);
- }
- return false;
- }
-
- void ProcessQueue(const TActorContext &ctx) {
- State.WaitQueue.ForEach(std::bind(&TThis::ProcessWrite, this, std::placeholders::_1, std::cref(ctx)));
- }
-
- void FreeChunks(const TActorContext &ctx) {
- TVector<ui32> vec;
- while (ui32 chunkId = State.Pers->Heap->RemoveChunk()) {
- vec.push_back(chunkId);
- }
- if (!vec.empty()) {
- const ui64 lsn = HugeKeeperCtx->LsnMngr->AllocLsnForLocalUse().Point();
- auto aid = ctx.Register(new THullHugeBlobChunkDestroyer(HugeKeeperCtx, ctx.SelfID, std::move(vec), lsn));
- ActiveActors.Insert(aid);
- const ui64 prevLsn = std::exchange(State.Pers->LogPos.ChunkFreeingLsn, lsn);
- Y_VERIFY(prevLsn < lsn); // although it is useless :)
+ State.WaitQueue.PushBack(item.release());
+ }
+
+ bool ProcessWrite(TEvHullWriteHugeBlob *ev, const TActorContext& ctx) {
+ NHuge::THugeSlot hugeSlot;
+ ui32 slotSize;
+ if (State.Pers->Heap->Allocate(ev->Data.GetSize(), &hugeSlot, &slotSize)) {
+ if (!ev->Empty()) { // remove item from the WaitQueue
+ --State.WaitQueueSize;
+ State.WaitQueueByteSize -= ev->ByteSize();
+ ev->Unlink();
+ }
+
+ const bool inserted = State.Pers->AllocatedSlots.insert(hugeSlot).second;
+ Y_VERIFY(inserted);
+ const ui64 wId = State.LogLsnFifo.Push(HugeKeeperCtx->LsnMngr->GetLsn());
+ auto aid = ctx.Register(new THullHugeBlobWriter(HugeKeeperCtx, ctx.SelfID, hugeSlot,
+ std::unique_ptr<TEvHullWriteHugeBlob>(ev), wId));
+ ActiveActors.Insert(aid);
+ return true;
+ } else if (AllocatingChunkPerSlotSize.insert(slotSize).second) {
+ auto aid = ctx.RegisterWithSameMailbox(new THullHugeBlobChunkAllocator(HugeKeeperCtx, ctx.SelfID, State.Pers));
+ ActiveActors.Insert(aid);
+ }
+ return false;
+ }
+
+ void ProcessQueue(const TActorContext &ctx) {
+ State.WaitQueue.ForEach(std::bind(&TThis::ProcessWrite, this, std::placeholders::_1, std::cref(ctx)));
+ }
+
+ void FreeChunks(const TActorContext &ctx) {
+ TVector<ui32> vec;
+ while (ui32 chunkId = State.Pers->Heap->RemoveChunk()) {
+ vec.push_back(chunkId);
}
+ if (!vec.empty()) {
+ const ui64 lsn = HugeKeeperCtx->LsnMngr->AllocLsnForLocalUse().Point();
+ auto aid = ctx.Register(new THullHugeBlobChunkDestroyer(HugeKeeperCtx, ctx.SelfID, std::move(vec), lsn));
+ ActiveActors.Insert(aid);
+ const ui64 prevLsn = std::exchange(State.Pers->LogPos.ChunkFreeingLsn, lsn);
+ Y_VERIFY(prevLsn < lsn); // although it is useless :)
+ }
}
//////////// Cut Log Handler ///////////////////////////////////
- void TryToCutLog(const TActorContext &ctx) {
+ void TryToCutLog(const TActorContext &ctx) {
const ui64 firstLsnToKeep = State.FirstLsnToKeep();
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
@@ -683,28 +683,28 @@ namespace NKikimr {
" FirstLsnToKeepDecomposed# %s", State.ToString().data(), firstLsnToKeep,
State.FirstLsnToKeepDecomposed().data()));
- // notify log cutter if the FirstLsnToKeep has changed since last reporting
- if (firstLsnToKeep != State.LastReportedFirstLsnToKeep) {
+ // notify log cutter if the FirstLsnToKeep has changed since last reporting
+ if (firstLsnToKeep != State.LastReportedFirstLsnToKeep) {
Y_VERIFY_S(firstLsnToKeep > State.LastReportedFirstLsnToKeep, "huge keeper log rollback"
<< " firstLsnToKeep#" << firstLsnToKeep
<< " State.LastReportedFirstLsnToKeep# " << State.LastReportedFirstLsnToKeep);
ctx.Send(HugeKeeperCtx->LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::HugeKeeper, firstLsnToKeep));
- State.LastReportedFirstLsnToKeep = firstLsnToKeep;
-
+ State.LastReportedFirstLsnToKeep = firstLsnToKeep;
+
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TryToCutLog: send TEvVDiskCutLog; firstLsnToKeep# %" PRIu64,
firstLsnToKeep));
- }
-
+ }
+
// do nothing if commit is in progress
- if (State.Committing) {
+ if (State.Committing) {
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TryToCutLog: terminate 0; state# %s", State.ToString().data()));
- return;
- }
-
+ return;
+ }
+
// check what if we issue a new huge hull keeper entry point -- would it allow us to
// move the FirstLsnToKeep barrier forward? if so, try to issue an entry point, otherwise exit
const bool inFlightWrites = State.LogLsnFifo.FirstLsnToKeep() != Max<ui64>();
@@ -713,52 +713,52 @@ namespace NKikimr {
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TryToCutLog: terminate 1; state# %s", State.ToString().data()));
- return;
- }
-
+ return;
+ }
+
- // allocate LSN for the brand new entry point
+ // allocate LSN for the brand new entry point
ui64 lsn = HugeKeeperCtx->LsnMngr->AllocLsnForLocalUse().Point();
State.Pers->InitiateNewEntryPointCommit(lsn, inFlightWrites);
- State.Committing = true;
- // serialize log record into string
+ State.Committing = true;
+ // serialize log record into string
TString serialized = State.Pers->Serialize();
-
+
// run committer
LOG_DEBUG(ctx, BS_HULLHUGE,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper: Commit initiated"));
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper: TryToCutLog: run committer"));
-
- auto aid = ctx.Register(new THullHugeBlobEntryPointSaver(HugeKeeperCtx, ctx.SelfID, lsn, serialized));
- ActiveActors.Insert(aid);
- }
+
+ auto aid = ctx.Register(new THullHugeBlobEntryPointSaver(HugeKeeperCtx, ctx.SelfID, lsn, serialized));
+ ActiveActors.Insert(aid);
+ }
//////////// Cut Log Handler ///////////////////////////////////
//////////// Event Handlers ////////////////////////////////////
void Handle(TEvHullWriteHugeBlob::TPtr &ev, const TActorContext &ctx) {
- std::unique_ptr<TEvHullWriteHugeBlob> item(ev->Release().Release());
+ std::unique_ptr<TEvHullWriteHugeBlob> item(ev->Release().Release());
LOG_DEBUG(ctx, BS_HULLHUGE,
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TEvHullWriteHugeBlob: %s", item->ToString().data()));
- if (ProcessWrite(item.get(), ctx)) {
- (void)item.release();
- } else {
- PutToWaitQueue(std::move(item));
- }
+ if (ProcessWrite(item.get(), ctx)) {
+ (void)item.release();
+ } else {
+ PutToWaitQueue(std::move(item));
+ }
}
void Handle(TEvHullHugeChunkAllocated::TPtr &ev, const TActorContext &ctx) {
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper:"
- " TEvHullHugeChunkAllocated: %s", ev->Get()->ToString().data()));
- Y_VERIFY(!AllocatingChunkPerSlotSize.empty());
- // actually we don't care about exact slot size, we have this set being used only as a counter of distinct
- // slot sizes being currently requested
- AllocatingChunkPerSlotSize.erase(AllocatingChunkPerSlotSize.begin());
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper:"
+ " TEvHullHugeChunkAllocated: %s", ev->Get()->ToString().data()));
+ Y_VERIFY(!AllocatingChunkPerSlotSize.empty());
+ // actually we don't care about exact slot size, we have this set being used only as a counter of distinct
+ // slot sizes being currently requested
+ AllocatingChunkPerSlotSize.erase(AllocatingChunkPerSlotSize.begin());
ActiveActors.Erase(ev->Sender);
- ProcessQueue(ctx);
- TryToCutLog(ctx);
+ ProcessQueue(ctx);
+ TryToCutLog(ctx);
}
void Handle(TEvHullFreeHugeSlots::TPtr &ev, const TActorContext &ctx) {
@@ -797,13 +797,13 @@ namespace NKikimr {
default:
Y_FAIL("Impossible case");
}
- ProcessQueue(ctx);
- FreeChunks(ctx);
- TryToCutLog(ctx);
+ ProcessQueue(ctx);
+ FreeChunks(ctx);
+ TryToCutLog(ctx);
}
- void Handle(TEvHullHugeChunkFreed::TPtr& ev, const TActorContext &ctx) {
- LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper: TEvHullHugeChunkFreed"));
+ void Handle(TEvHullHugeChunkFreed::TPtr& ev, const TActorContext &ctx) {
+ LOG_DEBUG(ctx, BS_HULLHUGE, VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix, "THullHugeKeeper: TEvHullHugeChunkFreed"));
ActiveActors.Erase(ev->Sender);
}
@@ -816,9 +816,9 @@ namespace NKikimr {
ActiveActors.Erase(ev->Sender);
State.LastCommitTime = TAppData::TimeProvider->Now();
State.Pers->EntryPointCommitted(ev->Get()->EntryPointLsn);
-
- // try to cut the log again -- while we were writing the entry point, something may have changed
- TryToCutLog(ctx);
+
+ // try to cut the log again -- while we were writing the entry point, something may have changed
+ TryToCutLog(ctx);
}
void Handle(TEvHullHugeWritten::TPtr &ev, const TActorContext &ctx) {
@@ -834,7 +834,7 @@ namespace NKikimr {
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TEvHullHugeBlobLogged: %s", msg->ToString().data()));
// manage log requests in flight
- State.LogLsnFifo.Pop(msg->WriteId, msg->RecLsn, msg->SlotIsUsed);
+ State.LogLsnFifo.Pop(msg->WriteId, msg->RecLsn, msg->SlotIsUsed);
// manage allocated slots
const TDiskPart &hugeBlob = msg->HugeBlob;
NHuge::THugeSlot hugeSlot(State.Pers->Heap->ConvertDiskPartToHugeSlot(hugeBlob));
@@ -850,8 +850,8 @@ namespace NKikimr {
// ...free slot
State.Pers->Heap->Free(hugeBlob);
}
- // if we are not committing entrypoint right now, we can try to update it as the FirstLsnToKeep may have changed
- TryToCutLog(ctx);
+ // if we are not committing entrypoint right now, we can try to update it as the FirstLsnToKeep may have changed
+ TryToCutLog(ctx);
}
void Handle(TEvHugeLockChunks::TPtr &ev, const TActorContext &ctx) {
@@ -887,7 +887,7 @@ namespace NKikimr {
VDISKP(HugeKeeperCtx->VCtx->VDiskLogPrefix,
"THullHugeKeeper: TEvCutLog: %s", ev->Get()->ToString().data()));
State.FreeUpToLsn = ev->Get()->FreeUpToLsn;
- TryToCutLog(ctx);
+ TryToCutLog(ctx);
}
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
@@ -920,52 +920,52 @@ namespace NKikimr {
//////////// Event Handlers ////////////////////////////////////
- STRICT_STFUNC(StateFunc,
- HFunc(TEvHullWriteHugeBlob, Handle)
- HFunc(TEvHullHugeChunkAllocated, Handle)
- HFunc(TEvHullFreeHugeSlots, Handle)
- HFunc(TEvHullHugeChunkFreed, Handle)
- HFunc(TEvHullHugeCommitted, Handle)
- HFunc(TEvHullHugeWritten, Handle)
- HFunc(TEvHullHugeBlobLogged, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvHullWriteHugeBlob, Handle)
+ HFunc(TEvHullHugeChunkAllocated, Handle)
+ HFunc(TEvHullFreeHugeSlots, Handle)
+ HFunc(TEvHullHugeChunkFreed, Handle)
+ HFunc(TEvHullHugeCommitted, Handle)
+ HFunc(TEvHullHugeWritten, Handle)
+ HFunc(TEvHullHugeBlobLogged, Handle)
HFunc(TEvHugeLockChunks, Handle)
HFunc(TEvHugeStat, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvents::TEvPoisonPill, Handle)
- )
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvents::TEvPoisonPill, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_HUGE_KEEPER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_HUGE_KEEPER;
}
THullHugeKeeper(
- std::shared_ptr<THugeKeeperCtx> &&hugeKeeperCtx,
- std::shared_ptr<THullHugeKeeperPersState> &&persState)
+ std::shared_ptr<THugeKeeperCtx> &&hugeKeeperCtx,
+ std::shared_ptr<THullHugeKeeperPersState> &&persState)
: HugeKeeperCtx(std::move(hugeKeeperCtx))
, State(std::move(persState))
{
Y_VERIFY(State.Pers->Recovered &&
State.Pers->AllocatedSlots.empty());
}
-
- void Bootstrap(const TActorContext &ctx) {
+
+ void Bootstrap(const TActorContext &ctx) {
// update global fragmentation stat
UpdateGlobalFragmentationStat(State.Pers->Heap->GetStat());
// run actor that periodically gather huge stat
auto aid = ctx.Register(new THullHugeStatGather(HugeKeeperCtx, SelfId()));
ActiveActors.Insert(aid);
- // issue entrypoint just at the start
- TryToCutLog(ctx);
- Become(&TThis::StateFunc);
- }
+ // issue entrypoint just at the start
+ TryToCutLog(ctx);
+ Become(&TThis::StateFunc);
+ }
};
IActor *CreateHullHugeBlobKeeper(
- std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
- std::shared_ptr<THullHugeKeeperPersState> persState) {
+ std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
+ std::shared_ptr<THullHugeKeeperPersState> persState) {
return new THullHugeKeeper(std::move(hugeKeeperCtx), std::move(persState));
}
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.h b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.h
index 66f3c049594..8831fce904d 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.h
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge.h
@@ -14,34 +14,34 @@ namespace NKikimr {
class TEvHullWriteHugeBlob : public TEventLocal<TEvHullWriteHugeBlob, TEvBlobStorage::EvHullWriteHugeBlob>, public TIntrusiveListItem<TEvHullWriteHugeBlob> {
public:
const TActorId SenderId;
- const ui64 Cookie;
+ const ui64 Cookie;
const TLogoBlobID LogoBlobId;
const TIngress Ingress;
- TRope Data;
+ TRope Data;
const bool IgnoreBlock;
const NKikimrBlobStorage::EPutHandleClass HandleClass;
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
TEvHullWriteHugeBlob(const TActorId &senderId,
- ui64 cookie,
+ ui64 cookie,
const TLogoBlobID &logoBlobId,
const TIngress &ingress,
- TRope&& data,
+ TRope&& data,
bool ignoreBlock,
NKikimrBlobStorage::EPutHandleClass handleClass,
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result)
: SenderId(senderId)
- , Cookie(cookie)
+ , Cookie(cookie)
, LogoBlobId(logoBlobId)
, Ingress(ingress)
- , Data(std::move(data))
+ , Data(std::move(data))
, IgnoreBlock(ignoreBlock)
, HandleClass(handleClass)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
ui64 ByteSize() const {
- return Data.GetSize();
+ return Data.GetSize();
}
TString ToString() const {
@@ -62,8 +62,8 @@ namespace NKikimr {
const TDiskPart HugeBlob;
const bool IgnoreBlock;
const TActorId OrigClient;
- const ui64 OrigCookie;
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
+ const ui64 OrigCookie;
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
TEvHullLogHugeBlob(ui64 writeId,
const TLogoBlobID &logoBlobID,
@@ -71,16 +71,16 @@ namespace NKikimr {
const TDiskPart &hugeBlob,
bool ignoreBlock,
const TActorId &origClient,
- ui64 origCookie,
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result)
+ ui64 origCookie,
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result)
: WriteId(writeId)
, LogoBlobID(logoBlobID)
, Ingress(ingress)
, HugeBlob(hugeBlob)
, IgnoreBlock(ignoreBlock)
, OrigClient(origClient)
- , OrigCookie(origCookie)
- , Result(std::move(result))
+ , OrigCookie(origCookie)
+ , Result(std::move(result))
{}
};
@@ -131,7 +131,7 @@ namespace NKikimr {
TStringStream str;
str << "{" << Signature.ToString()
<< " DelLsn# " << DeletionLsn << " Slots# "
- << HugeBlobs.ToString() << "}";
+ << HugeBlobs.ToString() << "}";
return str.Str();
}
};
@@ -217,7 +217,7 @@ namespace NKikimr {
// CreateHullHugeBlobKeeper
////////////////////////////////////////////////////////////////////////////
IActor *CreateHullHugeBlobKeeper(
- std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
- std::shared_ptr<NHuge::THullHugeKeeperPersState> persState);
+ std::shared_ptr<THugeKeeperCtx> hugeKeeperCtx,
+ std::shared_ptr<NHuge::THullHugeKeeperPersState> persState);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge_ut.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge_ut.cpp
index ed64a07678e..17ad2b5df8b 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhuge_ut.cpp
@@ -27,9 +27,9 @@ namespace NKikimr {
auto logf = [] (const TString &state) { STR << state; };
auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
auto info = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block);
- auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
+ auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
nullptr, TPDiskCategory::DEVICE_TYPE_UNKNOWN);
- std::unique_ptr<THullHugeKeeperPersState> state(
+ std::unique_ptr<THullHugeKeeperPersState> state(
new THullHugeKeeperPersState(vctx, chunkSize, appendBlockSize,
minHugeBlobInBytes, milestoneHugeBlobInBytes, maxBlobInBytes,
overhead, freeChunksReservation, oldMapCompatible, logf));
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedefs.h b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedefs.h
index 9bb8e64c080..452df0dc915 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedefs.h
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedefs.h
@@ -212,7 +212,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TBlobMerger {
using TCircaLsns = TVector<ui64>;
-
+
public:
TBlobMerger() = default;
@@ -232,23 +232,23 @@ namespace NKikimr {
void Add(const TDiskPart *begin, const TDiskPart *end, const NMatrix::TVectorType &parts, ui64 circaLsn) {
if (DiskPtrs.empty()) {
Parts = parts;
- DiskPtrs = {begin, end};
+ DiskPtrs = {begin, end};
CircaLsns = TCircaLsns(end - begin, circaLsn);
- Y_VERIFY(DiskPtrs.size() == Parts.CountBits());
+ Y_VERIFY(DiskPtrs.size() == Parts.CountBits());
} else {
Merge(begin, end, parts, circaLsn);
}
}
- void AddMetadataParts(NMatrix::TVectorType parts) {
+ void AddMetadataParts(NMatrix::TVectorType parts) {
// this is special case for mirror3of4, where data can have empty TDiskPart
- std::array<TDiskPart, 8> zero;
- zero.fill(TDiskPart());
+ std::array<TDiskPart, 8> zero;
+ zero.fill(TDiskPart());
// empty TDiskPart at a position means that every circaLsn shoud work
const ui64 circaLsn = Max<ui64>();
Merge(zero.begin(), zero.begin() + parts.CountBits(), parts, circaLsn);
- }
-
+ }
+
bool Empty() const {
return Parts.Empty();
}
@@ -265,9 +265,9 @@ namespace NKikimr {
return DiskPtrs.size() == 1 ? TBlobType::HugeBlob : TBlobType::ManyHugeBlobs;
}
- ui32 GetNumParts() const {
- return DiskPtrs.size();
- }
+ ui32 GetNumParts() const {
+ return DiskPtrs.size();
+ }
void Output(IOutputStream &str) const {
if (Empty()) {
@@ -311,8 +311,8 @@ namespace NKikimr {
void Merge(const TDiskPart *begin, const TDiskPart *end, const NMatrix::TVectorType &parts, ui64 circaLsn)
{
- Y_VERIFY(end - begin == parts.CountBits());
- Y_VERIFY_DEBUG(Parts.GetSize() == parts.GetSize());
+ Y_VERIFY(end - begin == parts.CountBits());
+ Y_VERIFY_DEBUG(Parts.GetSize() == parts.GetSize());
const ui8 maxSize = parts.GetSize();
TDiskPtrs newDiskPtrs;
TCircaLsns newCircaLsns;
@@ -357,7 +357,7 @@ namespace NKikimr {
Parts |= parts;
DiskPtrs.swap(newDiskPtrs);
CircaLsns.swap(newCircaLsns);
- Y_VERIFY(DiskPtrs.size() == Parts.CountBits());
+ Y_VERIFY(DiskPtrs.size() == Parts.CountBits());
}
};
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.cpp
index 3c5e904a279..9dd3ba81613 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.cpp
@@ -1,44 +1,44 @@
-#include "blobstorage_hullhugedelete.h"
-
-namespace NKikimr {
-
- class TDelayedHugeBlobDeleterActor : public TActor<TDelayedHugeBlobDeleterActor> {
- // pointer to database general data; actually we need only HugeKeeperID from that data
+#include "blobstorage_hullhugedelete.h"
+
+namespace NKikimr {
+
+ class TDelayedHugeBlobDeleterActor : public TActor<TDelayedHugeBlobDeleterActor> {
+ // pointer to database general data; actually we need only HugeKeeperID from that data
const TActorId HugeKeeperId;
-
- // pointer to shared deleter state, it is primarily created in TLevelIndex
- const TIntrusivePtr<TDelayedHugeBlobDeleterInfo> Info;
-
- public:
+
+ // pointer to shared deleter state, it is primarily created in TLevelIndex
+ const TIntrusivePtr<TDelayedHugeBlobDeleterInfo> Info;
+
+ public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_DELAYED_HUGE_BLOB_DELETER;
- }
-
+ return NKikimrServices::TActivity::BS_DELAYED_HUGE_BLOB_DELETER;
+ }
+
TDelayedHugeBlobDeleterActor(const TActorId &hugeKeeperId,
- TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info)
- : TActor(&TDelayedHugeBlobDeleterActor::StateFunc)
+ TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info)
+ : TActor(&TDelayedHugeBlobDeleterActor::StateFunc)
, HugeKeeperId(hugeKeeperId)
- , Info(std::move(info))
- {}
-
- void Handle(TEvHullReleaseSnapshot::TPtr& ev, const TActorContext& ctx) {
+ , Info(std::move(info))
+ {}
+
+ void Handle(TEvHullReleaseSnapshot::TPtr& ev, const TActorContext& ctx) {
Info->ReleaseSnapshot(ev->Get()->Cookie, ctx, HugeKeeperId);
- }
-
+ }
+
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvHullReleaseSnapshot, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
- };
-
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvHullReleaseSnapshot, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
+ };
+
IActor *CreateDelayedHugeBlobDeleterActor(const TActorId &hugeKeeperId,
TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info) {
return new TDelayedHugeBlobDeleterActor(hugeKeeperId, std::move(info));
- }
-
-} // NKikimr
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.h b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.h
index f0f6ebc326e..608e6ef8b35 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.h
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugedelete.h
@@ -1,232 +1,232 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_hullhuge.h"
-
+#include "blobstorage_hullhuge.h"
+
#include <library/cpp/monlib/service/pages/templates.h>
#include <ydb/core/base/blobstorage.h>
-
-#include <util/generic/queue.h>
-
-// Delayed huge blob deletion mechanism is needed to prevent races between huge blob reads and compactions when compacted
-// items are being read at the moment of deletion. To ensure this we have LevelIndex shared state that holds actual
-// list of taken snapshots stored as a map of LSN (of a snapshot) pointing to counter that covers all snapshots that were
-// taken with this LSN:
-//
-// +--------------------------------------------------------------------+
-// | V
-// compact snap1 snap2 compact snap3 release_snap1
-// | | | | | |
-// -----------------------------------------------------------------------------------------------------------> LSN axis
-//
-// Each snapshot, when taken, contains data with actual index information. This means that we should hold all deletes
-// with "deletion LSN" > "LSN of the snapshot" until this snapshot is released. Also, there is no difference between
-// snapshots with different LSNs taken between the same two compactions, so we use LSN of the last compaction as the key
-// to store snapshots. This key is referred as 'cookie' below. Cookie is increased only when compaction is going to log
-// new index and this index contains at least one of removed huge blobs.
-
-namespace NKikimr {
-
- struct TEvHullReleaseSnapshot : public TEventLocal<TEvHullReleaseSnapshot, TEvBlobStorage::EvHullReleaseSnapshot> {
- const ui64 Cookie;
-
- TEvHullReleaseSnapshot(ui64 cookie)
- : Cookie(cookie)
- {}
- };
-
- // LevelIndex-wide state of taken snapshots; contains shared data between corresponding actor and LevelIndex; when
- // snapshot is taken, it is stored here; when it is released, a message is sent to deletion actor and the action is
- // taken
- class TDelayedHugeBlobDeleterInfo : public TThrRefBase {
- // map <LastDeletionLsn> -> <number of snapshots that were taken during the time LastDeletionLsn was equal
- // to key>; when snapshot counter reaches zero, the key is deleted from map
+
+#include <util/generic/queue.h>
+
+// Delayed huge blob deletion mechanism is needed to prevent races between huge blob reads and compactions when compacted
+// items are being read at the moment of deletion. To ensure this we have LevelIndex shared state that holds actual
+// list of taken snapshots stored as a map of LSN (of a snapshot) pointing to counter that covers all snapshots that were
+// taken with this LSN:
+//
+// +--------------------------------------------------------------------+
+// | V
+// compact snap1 snap2 compact snap3 release_snap1
+// | | | | | |
+// -----------------------------------------------------------------------------------------------------------> LSN axis
+//
+// Each snapshot, when taken, contains data with actual index information. This means that we should hold all deletes
+// with "deletion LSN" > "LSN of the snapshot" until this snapshot is released. Also, there is no difference between
+// snapshots with different LSNs taken between the same two compactions, so we use LSN of the last compaction as the key
+// to store snapshots. This key is referred as 'cookie' below. Cookie is increased only when compaction is going to log
+// new index and this index contains at least one of removed huge blobs.
+
+namespace NKikimr {
+
+ struct TEvHullReleaseSnapshot : public TEventLocal<TEvHullReleaseSnapshot, TEvBlobStorage::EvHullReleaseSnapshot> {
+ const ui64 Cookie;
+
+ TEvHullReleaseSnapshot(ui64 cookie)
+ : Cookie(cookie)
+ {}
+ };
+
+ // LevelIndex-wide state of taken snapshots; contains shared data between corresponding actor and LevelIndex; when
+ // snapshot is taken, it is stored here; when it is released, a message is sent to deletion actor and the action is
+ // taken
+ class TDelayedHugeBlobDeleterInfo : public TThrRefBase {
+ // map <LastDeletionLsn> -> <number of snapshots that were taken during the time LastDeletionLsn was equal
+ // to key>; when snapshot counter reaches zero, the key is deleted from map
TMap<ui64, ui32> CurrentSnapshots;
-
- // last deletion LSN is set every time to LSN of log record containing FreeHugeBlobs vector; it is used as key
- // to CurrentSnapshots map; every shapshot taken when LastDeletionLsn has the specific value must be freed before
- // further deletions (with their respective DeletionLsn > LastDeletionLsn when snapshot was taken); it is changed
- // stepwise no prevent unnecessary allocations in CurrentSnaphots
- ui64 LastDeletionLsn = 0;
-
- // delayed huge blob deleter actor id
+
+ // last deletion LSN is set every time to LSN of log record containing FreeHugeBlobs vector; it is used as key
+ // to CurrentSnapshots map; every shapshot taken when LastDeletionLsn has the specific value must be freed before
+ // further deletions (with their respective DeletionLsn > LastDeletionLsn when snapshot was taken); it is changed
+ // stepwise no prevent unnecessary allocations in CurrentSnaphots
+ ui64 LastDeletionLsn = 0;
+
+ // delayed huge blob deleter actor id
TActorId ActorId;
-
- // a queue of removed huge blobs per compaction
- struct TRemovedHugeBlobsQueueItem {
- ui64 RecordLsn;
- TDiskPartVec RemovedHugeBlobs;
+
+ // a queue of removed huge blobs per compaction
+ struct TRemovedHugeBlobsQueueItem {
+ ui64 RecordLsn;
+ TDiskPartVec RemovedHugeBlobs;
TLogSignature Signature;
-
+
TRemovedHugeBlobsQueueItem(ui64 recordLsn, TDiskPartVec&& removedHugeBlobs, TLogSignature signature)
- : RecordLsn(recordLsn)
- , RemovedHugeBlobs(std::move(removedHugeBlobs))
- , Signature(signature)
- {}
- };
+ : RecordLsn(recordLsn)
+ , RemovedHugeBlobs(std::move(removedHugeBlobs))
+ , Signature(signature)
+ {}
+ };
TDeque<TRemovedHugeBlobsQueueItem> RemovedHugeBlobsQueue;
-
- public:
+
+ public:
void SetActorId(const TActorId& actorId) {
- Y_VERIFY(!ActorId);
- ActorId = actorId;
- }
-
+ Y_VERIFY(!ActorId);
+ ActorId = actorId;
+ }
+
const TActorId& GetActorId() const {
- return ActorId;
- }
-
- // this function is called when snapshot is taken; it returns a cookie that needs to be passed in a Release
- // message to delayed huge blob deleter actor
- ui64 TakeSnapshot() {
- ++CurrentSnapshots[LastDeletionLsn];
- return LastDeletionLsn;
- }
-
- // this function is called every time when compaction is about to commit new entrypoint containing at least
- // one removed huge blob; recordLsn is allocated LSN of this entrypoint
- void Update(ui64 recordLsn, TDiskPartVec&& removedHugeBlobs, const TActorContext& ctx,
+ return ActorId;
+ }
+
+ // this function is called when snapshot is taken; it returns a cookie that needs to be passed in a Release
+ // message to delayed huge blob deleter actor
+ ui64 TakeSnapshot() {
+ ++CurrentSnapshots[LastDeletionLsn];
+ return LastDeletionLsn;
+ }
+
+ // this function is called every time when compaction is about to commit new entrypoint containing at least
+ // one removed huge blob; recordLsn is allocated LSN of this entrypoint
+ void Update(ui64 recordLsn, TDiskPartVec&& removedHugeBlobs, const TActorContext& ctx,
const TActorId& hugeKeeperId, TLogSignature signature) {
- Y_VERIFY(recordLsn > LastDeletionLsn);
- LastDeletionLsn = recordLsn;
- RemovedHugeBlobsQueue.emplace_back(recordLsn, std::move(removedHugeBlobs), signature);
- ProcessRemovedHugeBlobsQueue(ctx, hugeKeeperId);
- }
-
+ Y_VERIFY(recordLsn > LastDeletionLsn);
+ LastDeletionLsn = recordLsn;
+ RemovedHugeBlobsQueue.emplace_back(recordLsn, std::move(removedHugeBlobs), signature);
+ ProcessRemovedHugeBlobsQueue(ctx, hugeKeeperId);
+ }
+
void RenderState(IOutputStream &str) {
- HTML(str) {
- DIV_CLASS("panel panel-default") {
- DIV_CLASS("panel-heading") {
- str << "Delayed Huge Blob Deleter";
- }
- DIV_CLASS("panel-body") {
- DIV_CLASS("panel panel-default") {
- DIV_CLASS("panel-heading") {
- str << "CurrentSnapshots";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "LSN"; }
- TABLEH() { str << "Counter"; }
- }
- }
- TABLEBODY() {
- for (const auto &pair : CurrentSnapshots) {
- TABLER() {
- TABLED() { str << pair.first; }
- TABLED() { str << pair.second; }
- }
- }
- }
- }
- }
- }
-
- DIV_CLASS("panel panel-default") {
- DIV_CLASS("panel-heading") {
- str << "LastDeletionLsn";
- }
- DIV_CLASS("panel-body") {
- STRONG() {
- str << LastDeletionLsn;
- }
- }
- }
-
- ui32 index = 1;
- for (const auto &record : RemovedHugeBlobsQueue) {
+ HTML(str) {
+ DIV_CLASS("panel panel-default") {
+ DIV_CLASS("panel-heading") {
+ str << "Delayed Huge Blob Deleter";
+ }
+ DIV_CLASS("panel-body") {
+ DIV_CLASS("panel panel-default") {
+ DIV_CLASS("panel-heading") {
+ str << "CurrentSnapshots";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "LSN"; }
+ TABLEH() { str << "Counter"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto &pair : CurrentSnapshots) {
+ TABLER() {
+ TABLED() { str << pair.first; }
+ TABLED() { str << pair.second; }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ DIV_CLASS("panel panel-default") {
+ DIV_CLASS("panel-heading") {
+ str << "LastDeletionLsn";
+ }
+ DIV_CLASS("panel-body") {
+ STRONG() {
+ str << LastDeletionLsn;
+ }
+ }
+ }
+
+ ui32 index = 1;
+ for (const auto &record : RemovedHugeBlobsQueue) {
TMap<TChunkIdx, ui32> slots;
- for (const TDiskPart &part : record.RemovedHugeBlobs) {
- ++slots[part.ChunkIdx];
- }
-
- DIV_CLASS("panel panel-default") {
- DIV_CLASS("panel-heading") {
- str << "RemovedHugeBlobsQueue[" << index << "]";
- }
- DIV_CLASS("panel-body") {
- DIV() {
- STRONG() {
- str << "Lsn# " << record.RecordLsn;
- }
- }
-
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "Chunk"; }
- TABLEH() { str << "Number of freed slots"; }
- }
- }
- TABLEBODY() {
- for (const auto &pair : slots) {
- TABLER() {
- TABLED() { str << pair.first; }
- TABLED() { str << pair.second; }
- }
- }
- }
- }
- }
- }
-
- ++index;
- }
- }
- }
- }
- }
-
- private:
- friend class TDelayedHugeBlobDeleterActor;
-
+ for (const TDiskPart &part : record.RemovedHugeBlobs) {
+ ++slots[part.ChunkIdx];
+ }
+
+ DIV_CLASS("panel panel-default") {
+ DIV_CLASS("panel-heading") {
+ str << "RemovedHugeBlobsQueue[" << index << "]";
+ }
+ DIV_CLASS("panel-body") {
+ DIV() {
+ STRONG() {
+ str << "Lsn# " << record.RecordLsn;
+ }
+ }
+
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "Chunk"; }
+ TABLEH() { str << "Number of freed slots"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto &pair : slots) {
+ TABLER() {
+ TABLED() { str << pair.first; }
+ TABLED() { str << pair.second; }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ++index;
+ }
+ }
+ }
+ }
+ }
+
+ private:
+ friend class TDelayedHugeBlobDeleterActor;
+
void ReleaseSnapshot(ui64 cookie, const TActorContext& ctx, const TActorId& hugeKeeperId) {
- auto it = CurrentSnapshots.find(cookie);
- Y_VERIFY(it != CurrentSnapshots.end() && it->second > 0);
- if (!--it->second) {
- CurrentSnapshots.erase(it);
- ProcessRemovedHugeBlobsQueue(ctx, hugeKeeperId);
- }
- }
-
+ auto it = CurrentSnapshots.find(cookie);
+ Y_VERIFY(it != CurrentSnapshots.end() && it->second > 0);
+ if (!--it->second) {
+ CurrentSnapshots.erase(it);
+ ProcessRemovedHugeBlobsQueue(ctx, hugeKeeperId);
+ }
+ }
+
void ProcessRemovedHugeBlobsQueue(const TActorContext& ctx, const TActorId& hugeKeeperId) {
- // if we have no snapshots, we can safely process all messages; otherwise we can process only those messages
- // which do not have snapshots created before the point of compaction
- while (RemovedHugeBlobsQueue) {
- TRemovedHugeBlobsQueueItem& item = RemovedHugeBlobsQueue.front();
- if (CurrentSnapshots.empty() || (item.RecordLsn <= CurrentSnapshots.begin()->first)) {
- // matching record -- commit it to huge hull keeper and throw out of the queue
- ctx.Send(hugeKeeperId, new TEvHullFreeHugeSlots(std::move(item.RemovedHugeBlobs),
- item.RecordLsn, item.Signature));
- RemovedHugeBlobsQueue.pop_front();
- } else {
- // we have no matching record
- break;
- }
- }
- }
- };
-
- struct TDelayedHugeBlobDeleterNotifier : public TThrRefBase {
- TActorSystem* const ActorSystem;
- const TIntrusivePtr<TDelayedHugeBlobDeleterInfo> Info;
- const ui64 Cookie;
-
- TDelayedHugeBlobDeleterNotifier(TActorSystem *actorSystem, TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info)
- : ActorSystem(actorSystem)
- , Info(std::move(info))
- , Cookie(Info->TakeSnapshot())
- {}
-
- // implemented in blobstorage_hull.h
- ~TDelayedHugeBlobDeleterNotifier() {
+ // if we have no snapshots, we can safely process all messages; otherwise we can process only those messages
+ // which do not have snapshots created before the point of compaction
+ while (RemovedHugeBlobsQueue) {
+ TRemovedHugeBlobsQueueItem& item = RemovedHugeBlobsQueue.front();
+ if (CurrentSnapshots.empty() || (item.RecordLsn <= CurrentSnapshots.begin()->first)) {
+ // matching record -- commit it to huge hull keeper and throw out of the queue
+ ctx.Send(hugeKeeperId, new TEvHullFreeHugeSlots(std::move(item.RemovedHugeBlobs),
+ item.RecordLsn, item.Signature));
+ RemovedHugeBlobsQueue.pop_front();
+ } else {
+ // we have no matching record
+ break;
+ }
+ }
+ }
+ };
+
+ struct TDelayedHugeBlobDeleterNotifier : public TThrRefBase {
+ TActorSystem* const ActorSystem;
+ const TIntrusivePtr<TDelayedHugeBlobDeleterInfo> Info;
+ const ui64 Cookie;
+
+ TDelayedHugeBlobDeleterNotifier(TActorSystem *actorSystem, TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info)
+ : ActorSystem(actorSystem)
+ , Info(std::move(info))
+ , Cookie(Info->TakeSnapshot())
+ {}
+
+ // implemented in blobstorage_hull.h
+ ~TDelayedHugeBlobDeleterNotifier() {
ActorSystem->Send(new IEventHandle(Info->GetActorId(), TActorId(), new TEvHullReleaseSnapshot(Cookie)));
- }
- };
-
+ }
+ };
+
IActor *CreateDelayedHugeBlobDeleterActor(const TActorId &hugeKeeperId,
TIntrusivePtr<TDelayedHugeBlobDeleterInfo> info);
-
-} // NKikimr
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.cpp
index e60200de987..45d06072e92 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.cpp
@@ -120,7 +120,7 @@ namespace NKikimr {
void TChain::Allocate(NPrivate::TChunkSlot *id, TChunkID chunkId) {
Y_VERIFY_S(FreeSpace.empty(), VDiskLogPrefix << "Empty");
- FreeSpace.emplace(chunkId, ConstMask);
+ FreeSpace.emplace(chunkId, ConstMask);
FreeSlotsInFreeSpace += SlotsInChunk;
bool res = Allocate(id);
Y_VERIFY_S(res, VDiskLogPrefix << "TChain::Allocate2:"
@@ -165,16 +165,16 @@ namespace NKikimr {
mask.Set(slotId);
++FreeSlotsInFreeSpace;
- FreeSpace.emplace(chunkId, mask);
+ FreeSpace.emplace(chunkId, mask);
return TFreeRes(0, mask, SlotsInChunk); // no empty chunk
}
}
bool TChain::LockChunkForAllocation(TChunkID chunkId) {
- if (TFreeSpace::iterator it = FreeSpace.find(chunkId); it != FreeSpace.end()) {
- LockedChunks.insert(FreeSpace.extract(it));
- return true;
- } else {
+ if (TFreeSpace::iterator it = FreeSpace.find(chunkId); it != FreeSpace.end()) {
+ LockedChunks.insert(FreeSpace.extract(it));
+ return true;
+ } else {
// chunk is already freed
return false;
}
@@ -228,7 +228,7 @@ namespace NKikimr {
Y_VERIFY_S(id.GetChunkId() == chunkId && FreeSpace.find(chunkId) == FreeSpace.end(),
VDiskLogPrefix << " id# " << id.ToString() << " chunkId# " << chunkId << " State# " << ToString());
- FreeSpace.emplace(chunkId, ConstMask);
+ FreeSpace.emplace(chunkId, ConstMask);
FreeSlotsInFreeSpace += SlotsInChunk;
bool res = RecoveryModeAllocate(id);
@@ -239,13 +239,13 @@ namespace NKikimr {
void TChain::Save(IOutputStream *s) const {
::Save(s, SlotsInChunk);
::Save(s, AllocatedSlots);
- if (LockedChunks) {
- TFreeSpace temp(FreeSpace);
- temp.insert(LockedChunks.begin(), LockedChunks.end());
- ::Save(s, temp);
- } else {
- ::Save(s, FreeSpace);
- }
+ if (LockedChunks) {
+ TFreeSpace temp(FreeSpace);
+ temp.insert(LockedChunks.begin(), LockedChunks.end());
+ ::Save(s, temp);
+ } else {
+ ::Save(s, FreeSpace);
+ }
}
void TChain::Load(IInputStream *s) {
@@ -338,7 +338,7 @@ namespace NKikimr {
SlotsInChunk = blocksInChunk / slotSizeInBlocks;
SlotSize = slotSizeInBlocks * appendBlockSize;
- ChainPtr = MakeIntrusive<TChain>(vdiskLogPrefix, SlotsInChunk);
+ ChainPtr = MakeIntrusive<TChain>(vdiskLogPrefix, SlotsInChunk);
}
THugeSlot TChainDelegator::Convert(const NPrivate::TChunkSlot &id) const {
@@ -418,7 +418,7 @@ namespace NKikimr {
{
Y_VERIFY_S(MinHugeBlobInBytes != 0 &&
MinHugeBlobInBytes <= MilestoneBlobInBytes &&
- MilestoneBlobInBytes < MaxBlobInBytes, "INVALID CONFIGURATION! (SETTINGS ARE:"
+ MilestoneBlobInBytes < MaxBlobInBytes, "INVALID CONFIGURATION! (SETTINGS ARE:"
<< " MaxBlobInBytes# " << MaxBlobInBytes << " MinHugeBlobInBytes# " << MinHugeBlobInBytes
<< " MilestoneBlobInBytes# " << MilestoneBlobInBytes << " ChunkSize# " << ChunkSize
<< " AppendBlockSize# " << AppendBlockSize << ")");
@@ -603,7 +603,7 @@ namespace NKikimr {
return res;
}
- std::shared_ptr<THugeSlotsMap> TAllChains::BuildHugeSlotsMap() const {
+ std::shared_ptr<THugeSlotsMap> TAllChains::BuildHugeSlotsMap() const {
THugeSlotsMap::TAllSlotsInfo targetAllSlotsInfo;
THugeSlotsMap::TSearchTable targetSearchTable;
@@ -620,7 +620,7 @@ namespace NKikimr {
targetSearchTable.push_back(THugeSlotsMap::TIndex(targetAllSlotsInfo.size() - 1));
}
- return std::make_shared<THugeSlotsMap>(AppendBlockSize, std::move(targetAllSlotsInfo),
+ return std::make_shared<THugeSlotsMap>(AppendBlockSize, std::move(targetAllSlotsInfo),
std::move(targetSearchTable));
}
@@ -677,7 +677,7 @@ namespace NKikimr {
BuildSearchTable();
Y_VERIFY_S(GetMinREALHugeBlobInBytes() != 0, "INVALID CONFIGURATION: MinREALHugeBlobInBytes IS 0"
- << " (SETTINGS ARE: MaxBlobInBytes# " << MaxBlobInBytes
+ << " (SETTINGS ARE: MaxBlobInBytes# " << MaxBlobInBytes
<< " MinHugeBlobInBytes# " << MinHugeBlobInBytes
<< " ChunkSize# " << ChunkSize
<< " AppendBlockSize# " << AppendBlockSize << ')');
@@ -726,20 +726,20 @@ namespace NKikimr {
return THugeSlot(addr.ChunkIdx, addr.Offset, chainD->SlotSize);
}
- bool THeap::Allocate(ui32 size, THugeSlot *hugeSlot, ui32 *slotSize) {
+ bool THeap::Allocate(ui32 size, THugeSlot *hugeSlot, ui32 *slotSize) {
TChainDelegator *chainD = Chains.GetChain(size);
Y_VERIFY_S(chainD, VDiskLogPrefix << "size# " << size << " Heap# " << ToString());
- *slotSize = chainD->SlotSize;
+ *slotSize = chainD->SlotSize;
NPrivate::TChunkSlot id;
- if (!chainD->ChainPtr->Allocate(&id)) { // no available slot in free space of the chain
- if (FreeChunks.empty()) { // no free chunks left for reuse -- request a new chunk
+ if (!chainD->ChainPtr->Allocate(&id)) { // no available slot in free space of the chain
+ if (FreeChunks.empty()) { // no free chunks left for reuse -- request a new chunk
return false;
}
- chainD->ChainPtr->Allocate(&id, GetChunkIdFromFreeChunks()); // reuse free chunk for this chain
+ chainD->ChainPtr->Allocate(&id, GetChunkIdFromFreeChunks()); // reuse free chunk for this chain
}
- *hugeSlot = chainD->Convert(id);
- return true;
+ *hugeSlot = chainD->Convert(id);
+ return true;
}
TFreeRes THeap::Free(const TDiskPart &addr) {
@@ -796,7 +796,7 @@ namespace NKikimr {
} else {
ui32 chunkId = addr.ChunkIdx;
TFreeChunks::iterator it = FreeChunks.find(chunkId);
- Y_VERIFY_S(it != FreeChunks.end(), VDiskLogPrefix << "addr# " << addr.ToString() << " State# " << ToString());
+ Y_VERIFY_S(it != FreeChunks.end(), VDiskLogPrefix << "addr# " << addr.ToString() << " State# " << ToString());
FreeChunks.erase(it);
chainD->ChainPtr->RecoveryModeAllocate(id, chunkId);
}
@@ -809,7 +809,7 @@ namespace NKikimr {
void THeap::RecoveryModeRemoveChunks(const TVector<ui32> &chunkIds) {
for (ui32 x : chunkIds) {
TFreeChunks::iterator it = FreeChunks.find(x);
- Y_VERIFY_S(it != FreeChunks.end(), VDiskLogPrefix << "chunkId# " << x << " State# " << ToString());
+ Y_VERIFY_S(it != FreeChunks.end(), VDiskLogPrefix << "chunkId# " << x << " State# " << ToString());
FreeChunks.erase(it);
}
}
@@ -879,7 +879,7 @@ namespace NKikimr {
TStringStream str;
str << "FreeChunks: ";
str << FormatList(FreeChunks);
- str << " CHAINS: " << Chains.ToString();
+ str << " CHAINS: " << Chains.ToString();
return str.Str();
}
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.h b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.h
index 651117f2b94..4646d051059 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.h
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap.h
@@ -203,7 +203,7 @@ namespace NKikimr {
return std::pair<ui32, ui32>(ChainDelegators.size(), SearchTable.size());
}
// Builds a map of BlobSize -> THugeSlotsMap::TSlotInfo for THugeBlobCtx
- std::shared_ptr<THugeSlotsMap> BuildHugeSlotsMap() const;
+ std::shared_ptr<THugeSlotsMap> BuildHugeSlotsMap() const;
private:
struct TBuiltChainDelegators {
@@ -283,7 +283,7 @@ namespace NKikimr {
}
// Builds a map of BlobSize -> THugeSlotsMap::TSlotInfo for THugeBlobCtx
- std::shared_ptr<THugeSlotsMap> BuildHugeSlotsMap() const {
+ std::shared_ptr<THugeSlotsMap> BuildHugeSlotsMap() const {
return Chains.BuildHugeSlotsMap();
}
@@ -291,7 +291,7 @@ namespace NKikimr {
// Main functions
//////////////////////////////////////////////////////////////////////////////////////////
THugeSlot ConvertDiskPartToHugeSlot(const TDiskPart &addr) const;
- bool Allocate(ui32 size, THugeSlot *hugeSlot, ui32 *slotSize);
+ bool Allocate(ui32 size, THugeSlot *hugeSlot, ui32 *slotSize);
TFreeRes Free(const TDiskPart &addr);
void AddChunk(ui32 chunkId);
ui32 RemoveChunk();
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ctx_ut.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ctx_ut.cpp
index c6b0ff7a886..22bcecb892a 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ctx_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ctx_ut.cpp
@@ -18,11 +18,11 @@ namespace NKikimr {
constexpr ui32 ChunkSize = 135249920;
constexpr ui32 AppendBlockSize = 4064;
- std::shared_ptr<THugeBlobCtx> CreateHugeBlobCtx() {
+ std::shared_ptr<THugeBlobCtx> CreateHugeBlobCtx() {
TVDiskConfig cfg(TVDiskConfig::TBaseInfo::SampleForTests());
auto logFunc = [] (const TString &) {};
- auto repairedHuge = std::make_shared<NHuge::THullHugeKeeperPersState>(
+ auto repairedHuge = std::make_shared<NHuge::THullHugeKeeperPersState>(
Contexts.GetVCtx(),
ChunkSize,
AppendBlockSize,
@@ -34,7 +34,7 @@ namespace NKikimr {
cfg.HugeBlobOldMapCompatible,
logFunc);
- return std::make_shared<THugeBlobCtx>(
+ return std::make_shared<THugeBlobCtx>(
repairedHuge->GetMinREALHugeBlobInBytes(),
repairedHuge->Heap->BuildHugeSlotsMap());
}
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ut.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ut.cpp
index 638269fdfd2..ba74b178c23 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugeheap_ut.cpp
@@ -296,16 +296,16 @@ namespace NKikimr {
heap.AddChunk(3);
THugeSlot slot;
- ui32 slotSize;
+ ui32 slotSize;
bool res = false;
for (ui32 i = 0; i < heap.SlotNumberOfThisSize(hugeBlobSize); i++) {
- res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
+ res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
UNIT_ASSERT_EQUAL(res, true);
STR << "Allocated: " << slot.ToString() << "\n";
UNIT_ASSERT(slot.GetChunkId() == 3);
}
- res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
+ res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
UNIT_ASSERT_EQUAL(res, true);
UNIT_ASSERT(slot.GetChunkId() == 5);
STR << "Allocated: " << slot.ToString() << "\n";
@@ -322,16 +322,16 @@ namespace NKikimr {
heap.AddChunk(3);
THugeSlot slot;
- ui32 slotSize;
+ ui32 slotSize;
bool res = false;
for (ui32 i = 0; i < heap.SlotNumberOfThisSize(hugeBlobSize) * 2; i++) {
- res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
+ res = heap.Allocate(hugeBlobSize, &slot, &slotSize);
UNIT_ASSERT_EQUAL(res, true);
arr.push_back(slot);
STR << "Allocated: " << slot.ToString() << "\n";
}
STR << "Allocated all\n";
- UNIT_ASSERT_EQUAL(heap.Allocate(hugeBlobSize, &slot, &slotSize), false);
+ UNIT_ASSERT_EQUAL(heap.Allocate(hugeBlobSize, &slot, &slotSize), false);
}
void FreeScenary(THeap &heap, TVector<THugeSlot> &arr) {
@@ -416,19 +416,19 @@ namespace NKikimr {
ui32 chunkSize = 134274560u;
ui32 appendBlockSize = 56896u;
ui32 minHugeBlobInBytes = 512u << 10u;
- ui32 maxBlobInBytes = MaxVDiskBlobSize;
+ ui32 maxBlobInBytes = MaxVDiskBlobSize;
ui32 overhead = 8u;
ui32 freeChunksReservation = 1;
THeap heap("vdisk", chunkSize, appendBlockSize, minHugeBlobInBytes, minHugeBlobInBytes,
maxBlobInBytes, overhead, freeChunksReservation, false);
THugeSlot hugeSlot;
- ui32 slotSize;
+ ui32 slotSize;
ui32 minREALHugeBlobInBytes = heap.GetMinREALHugeBlobInBytes();
bool res = false;
- res = heap.Allocate(minREALHugeBlobInBytes, &hugeSlot, &slotSize);
+ res = heap.Allocate(minREALHugeBlobInBytes, &hugeSlot, &slotSize);
UNIT_ASSERT_EQUAL(res, false); // no chunks
- res = heap.Allocate(maxBlobInBytes, &hugeSlot, &slotSize);
+ res = heap.Allocate(maxBlobInBytes, &hugeSlot, &slotSize);
UNIT_ASSERT_EQUAL(res, false); // no chunks
}
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.cpp b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.cpp
index 77572ecfb6b..ad72d852d4e 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.cpp
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.cpp
@@ -32,8 +32,8 @@ namespace NKikimr {
<< " HugeBlobLoggedLsn# " << HugeBlobLoggedLsn
<< "}";
return str.Str();
- }
-
+ }
+
TString THullHugeRecoveryLogPos::ToString() const {
TStringStream str;
str << "{ChunkAllocationLsn# " << ChunkAllocationLsn
@@ -167,7 +167,7 @@ namespace NKikimr {
std::function<void(const TString&)> logFunc)
: VCtx(std::move(vctx))
, LogPos(THullHugeRecoveryLogPos::Default())
- , CommittedLogPos(LogPos)
+ , CommittedLogPos(LogPos)
, Heap(new NHuge::THeap(VCtx->VDiskLogPrefix, chunkSize, appendBlockSize,
minHugeBlobInBytes, milestoneHugeBlobInBytes,
maxBlobInBytes, overhead, freeChunksReservation,
@@ -194,7 +194,7 @@ namespace NKikimr {
std::function<void(const TString&)> logFunc)
: VCtx(std::move(vctx))
, LogPos(THullHugeRecoveryLogPos::Default())
- , CommittedLogPos(LogPos)
+ , CommittedLogPos(LogPos)
, Heap(new NHuge::THeap(VCtx->VDiskLogPrefix, chunkSize, appendBlockSize,
minHugeBlobInBytes, milestoneHugeBlobInBytes,
maxBlobInBytes, overhead, freeChunksReservation,
@@ -207,7 +207,7 @@ namespace NKikimr {
logFunc(VDISKP(VCtx->VDiskLogPrefix,
"Recovery started (guid# %" PRIu64 " entryLsn# %" PRIu64 "): State# %s",
Guid, entryPointLsn, ToString().data()));
- CommittedLogPos = LogPos;
+ CommittedLogPos = LogPos;
}
THullHugeKeeperPersState::~THullHugeKeeperPersState() {
@@ -229,9 +229,9 @@ namespace NKikimr {
str.Write(&heapSize, sizeof(ui32));
str.Write(serializedHeap.data(), heapSize);
- // chunks to free -- obsolete field
- const ui32 chunksSize = 0;
- Y_VERIFY(!chunksSize);
+ // chunks to free -- obsolete field
+ const ui32 chunksSize = 0;
+ Y_VERIFY(!chunksSize);
str.Write(&chunksSize, sizeof(ui32));
// allocated slots
@@ -265,7 +265,7 @@ namespace NKikimr {
// chunks to free
ui32 chunksSize = ReadUnaligned<ui32>(cur);
cur += sizeof(ui32); // chunks size
- Y_VERIFY(!chunksSize);
+ Y_VERIFY(!chunksSize);
// allocated slots
ui32 slotsSize = ReadUnaligned<ui32>(cur);
@@ -366,17 +366,17 @@ namespace NKikimr {
}
ui64 THullHugeKeeperPersState::FirstLsnToKeep() const {
- return Min(LogPos.FirstLsnToKeep(), LogTracker.FirstLsnToKeep(),
- // special case if these LSM tree entrypoints with deletions would be applied by the recovery code
- CommittedLogPos.LogoBlobsDbSlotDelLsn,
- CommittedLogPos.BlocksDbSlotDelLsn,
- CommittedLogPos.BarriersDbSlotDelLsn);
+ return Min(LogPos.FirstLsnToKeep(), LogTracker.FirstLsnToKeep(),
+ // special case if these LSM tree entrypoints with deletions would be applied by the recovery code
+ CommittedLogPos.LogoBlobsDbSlotDelLsn,
+ CommittedLogPos.BlocksDbSlotDelLsn,
+ CommittedLogPos.BarriersDbSlotDelLsn);
}
TString THullHugeKeeperPersState::FirstLsnToKeepDecomposed() const {
TStringStream str;
str << "{LogPos# " << LogPos.FirstLsnToKeepDecomposed()
- << " CommittedLogPos# " << CommittedLogPos.FirstLsnToKeepDecomposed()
+ << " CommittedLogPos# " << CommittedLogPos.FirstLsnToKeepDecomposed()
<< " LogTracker# " << LogTracker.FirstLsnToKeepDecomposed()
<< "}";
return str.Str();
@@ -401,7 +401,7 @@ namespace NKikimr {
pos.EntryPointLsn = LogPos.EntryPointLsn;
pos.HugeBlobLoggedLsn = LogPos.HugeBlobLoggedLsn;
LogTracker.InitiateNewEntryPointCommit(pos);
- CommittedLogPos = LogPos;
+ CommittedLogPos = LogPos;
}
// finish commit
@@ -444,13 +444,13 @@ namespace NKikimr {
{
if (lsn > LogPos.ChunkFreeingLsn) {
// apply
- LOG_DEBUG(ctx, BS_HULLHUGE,
- VDISKP(VCtx->VDiskLogPrefix,
- "Recovery(guid# %" PRIu64 " lsn# %" PRIu64 " entryLsn# %" PRIu64 "): "
- "FreeChunk apply(remove): %s",
- Guid, lsn, LogPos.EntryPointLsn, rec.ToString().data()));
- Heap->RecoveryModeRemoveChunks(rec.ChunkIds);
- LogPos.ChunkFreeingLsn = lsn;
+ LOG_DEBUG(ctx, BS_HULLHUGE,
+ VDISKP(VCtx->VDiskLogPrefix,
+ "Recovery(guid# %" PRIu64 " lsn# %" PRIu64 " entryLsn# %" PRIu64 "): "
+ "FreeChunk apply(remove): %s",
+ Guid, lsn, LogPos.EntryPointLsn, rec.ToString().data()));
+ Heap->RecoveryModeRemoveChunks(rec.ChunkIds);
+ LogPos.ChunkFreeingLsn = lsn;
return TRlas(true, false);
} else {
// skip
@@ -513,16 +513,16 @@ namespace NKikimr {
ui64 lsn,
const NHuge::TPutRecoveryLogRec &rec)
{
- if (rec.DiskAddr == TDiskPart()) {
- // this is metadata part, no actual slot exists here
- if (lsn > LogPos.HugeBlobLoggedLsn) {
- LogPos.HugeBlobLoggedLsn = lsn;
- return TRlas(true, false);
- } else {
- return TRlas(true, true);
- }
- }
-
+ if (rec.DiskAddr == TDiskPart()) {
+ // this is metadata part, no actual slot exists here
+ if (lsn > LogPos.HugeBlobLoggedLsn) {
+ LogPos.HugeBlobLoggedLsn = lsn;
+ return TRlas(true, false);
+ } else {
+ return TRlas(true, true);
+ }
+ }
+
NHuge::THugeSlot hugeSlot(Heap->ConvertDiskPartToHugeSlot(rec.DiskAddr));
if (lsn > LogPos.HugeBlobLoggedLsn) {
// apply
@@ -595,9 +595,9 @@ namespace NKikimr {
}
void THullHugeKeeperPersState::GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- Heap->GetOwnedChunks(chunks);
- }
-
+ Heap->GetOwnedChunks(chunks);
+ }
+
} // NHuge
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.h b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.h
index 7d6bbca7937..965da5bac19 100644
--- a/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.h
+++ b/ydb/core/blobstorage/vdisk/huge/blobstorage_hullhugerecovery.h
@@ -117,9 +117,9 @@ namespace NKikimr {
TIntrusivePtr<TVDiskContext> VCtx;
// current pos
THullHugeRecoveryLogPos LogPos;
- // last committed log pos
- THullHugeRecoveryLogPos CommittedLogPos;
- std::unique_ptr<NHuge::THeap> Heap;
+ // last committed log pos
+ THullHugeRecoveryLogPos CommittedLogPos;
+ std::unique_ptr<NHuge::THeap> Heap;
// slots that are already allocated, but not written to log
TAllocatedSlots AllocatedSlots;
// guard to avoid using structure before recovery has been completed
@@ -202,7 +202,7 @@ namespace NKikimr {
ui64 lsn,
const TString &data);
void FinishRecovery(const TActorContext &ctx);
-
+
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const;
};
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_chain.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_chain.cpp
index d9e62308e15..bb490222749 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_chain.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_chain.cpp
@@ -93,7 +93,7 @@ namespace NKikimr {
}
const bool noSync = !gcOnlySynced;
- if (val.Ingress.IsQuorum(ingrCache) || noSync || key.Hard) {
+ if (val.Ingress.IsQuorum(ingrCache) || noSync || key.Hard) {
if (CurrentBarrier.Empty() ||
std::make_tuple(CurrentBarrier->CollectGen, CurrentBarrier->CollectStep) <=
std::make_tuple(val.BarrierValue.CollectGen, val.BarrierValue.CollectStep)) {
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp
index c05fd1e05a4..83e4793e6cc 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.cpp
@@ -4,23 +4,23 @@
namespace NKikimr {
namespace NGcOpt {
- TBarriersEssence::TBarriersEssence(NBarriers::TMemViewSnap memViewSnap, TBlobStorageGroupType gtype)
+ TBarriersEssence::TBarriersEssence(NBarriers::TMemViewSnap memViewSnap, TBlobStorageGroupType gtype)
: MemViewSnap(std::move(memViewSnap))
- , BuildStat(std::make_unique<NGc::TBuildStat>())
- , IngressMode(TIngress::IngressMode(gtype))
+ , BuildStat(std::make_unique<NGc::TBuildStat>())
+ , IngressMode(TIngress::IngressMode(gtype))
{}
TIntrusivePtr<TBarriersEssence> TBarriersEssence::Create(const THullCtxPtr &hullCtx,
const NBarriers::TBarriersDsSnapshot &snapshot)
{
- return MakeIntrusive<TBarriersEssence>(snapshot.GetMemViewSnap(), hullCtx->VCtx->Top->GType);
+ return MakeIntrusive<TBarriersEssence>(snapshot.GetMemViewSnap(), hullCtx->VCtx->Top->GType);
}
TIntrusivePtr<TBarriersEssence> TBarriersEssence::Create(const THullCtxPtr &hullCtx,
const NBarriers::TBarriersDsSnapshot &snapshot,
- ui64 /*firstTabletId*/,
- ui64 /*lastTabletId*/,
- int /*debugLevel*/)
+ ui64 /*firstTabletId*/,
+ ui64 /*lastTabletId*/,
+ int /*debugLevel*/)
{
return Create(hullCtx, snapshot);
}
@@ -81,7 +81,7 @@ namespace NKikimr {
std::make_tuple(gen, step) > std::make_tuple(soft->CollectGen, soft->CollectStep);
// flags says us to keep the record?
- const bool keepByFlags = ingress.KeepUnconditionally(IngressMode);
+ const bool keepByFlags = ingress.KeepUnconditionally(IngressMode);
// is item is spread over multiple ssts?
const bool itemIsSpreadOverMultipleSsts = recsMerged > 1;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h
index 87e6fb7dffc..7b021d05da8 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_essence.h
@@ -18,9 +18,9 @@ namespace NGcOpt {
//////////////////////////////////////////////////////////////////////////////////////////
// TBarriersEssence
//////////////////////////////////////////////////////////////////////////////////////////
- class TBarriersEssence : public TThrRefBase, TNonCopyable {
+ class TBarriersEssence : public TThrRefBase, TNonCopyable {
public: // public for unit tests, actually private
- TBarriersEssence(NBarriers::TMemViewSnap memViewSnap, TBlobStorageGroupType gtype);
+ TBarriersEssence(NBarriers::TMemViewSnap memViewSnap, TBlobStorageGroupType gtype);
// Builds TBarriersEssence from TBarriersDsSnapshot,
// can work asynchronously
@@ -75,8 +75,8 @@ namespace NGcOpt {
TString ToString() const;
private:
NBarriers::TMemViewSnap MemViewSnap;
- std::unique_ptr<NGc::TBuildStat> BuildStat;
- const TIngress::EMode IngressMode;
+ std::unique_ptr<NGc::TBuildStat> BuildStat;
+ const TIngress::EMode IngressMode;
NGc::TKeepStatus KeepBarrier(const TKeyBarrier &key) const;
NGc::TKeepStatus KeepLogoBlob(const TLogoBlobID &id,
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.cpp
index fa2f9316dbe..b57ad1f94aa 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.cpp
@@ -26,11 +26,11 @@ namespace NKikimr {
/////////////////////////////////////////////////////////////////////////////////////////////
// TBarriersDs
/////////////////////////////////////////////////////////////////////////////////////////////
- TBarriersDs::TBarriersDs(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena)
- : TBase(settings, std::move(arena))
+ TBarriersDs::TBarriersDs(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena)
+ : TBase(settings, std::move(arena))
, VDiskLogPrefix(settings.HullCtx->VCtx->VDiskLogPrefix)
- , MemView(std::make_unique<TMemView>(
- TIngressCache::Create(settings.HullCtx->VCtx->Top, settings.HullCtx->VCtx->ShortSelfVDisk),
+ , MemView(std::make_unique<TMemView>(
+ TIngressCache::Create(settings.HullCtx->VCtx->Top, settings.HullCtx->VCtx->ShortSelfVDisk),
settings.HullCtx->VCtx->VDiskLogPrefix,
settings.HullCtx->GCOnlySynced))
{}
@@ -38,12 +38,12 @@ namespace NKikimr {
TBarriersDs::TBarriersDs(
const TLevelIndexSettings &settings,
const NKikimrVDiskData::TLevelIndex &pb,
- ui64 entryPointLsn,
- std::shared_ptr<TRopeArena> arena)
- : TBase(settings, pb, entryPointLsn, std::move(arena))
+ ui64 entryPointLsn,
+ std::shared_ptr<TRopeArena> arena)
+ : TBase(settings, pb, entryPointLsn, std::move(arena))
, VDiskLogPrefix(settings.HullCtx->VCtx->VDiskLogPrefix)
- , MemView(std::make_unique<TMemView>(
- TIngressCache::Create(settings.HullCtx->VCtx->Top, settings.HullCtx->VCtx->ShortSelfVDisk),
+ , MemView(std::make_unique<TMemView>(
+ TIngressCache::Create(settings.HullCtx->VCtx->Top, settings.HullCtx->VCtx->ShortSelfVDisk),
settings.HullCtx->VCtx->VDiskLogPrefix,
settings.HullCtx->GCOnlySynced))
{}
@@ -54,11 +54,11 @@ namespace NKikimr {
TBase::PutToFresh(lsn, key, memRec);
}
- void TBarriersDs::PutToFresh(std::shared_ptr<TBase::TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
+ void TBarriersDs::PutToFresh(std::shared_ptr<TBase::TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
Y_VERIFY_DEBUG(a);
// update barriers cache with newly inserted elements
- TFreshAppendix::TIterator it(Settings.HullCtx, a.get());
+ TFreshAppendix::TIterator it(Settings.HullCtx, a.get());
it.SeekToFirst();
while (it.Valid()) {
MemView->Update(it.GetCurKey(), it.GetMemRec());
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.h
index 42048969f1e..614f5e3b9e5 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_public.h
@@ -53,23 +53,23 @@ namespace NKikimr {
public:
using TBase = TLevelIndex<TKeyBarrier, TMemRecBarrier>;
- TBarriersDs(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena);
+ TBarriersDs(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena);
TBarriersDs(
const TLevelIndexSettings &settings,
const NKikimrVDiskData::TLevelIndex &pb,
- ui64 entryPointLsn,
- std::shared_ptr<TRopeArena> arena);
+ ui64 entryPointLsn,
+ std::shared_ptr<TRopeArena> arena);
void PutToFresh(ui64 lsn, const TKeyBarrier &key, const TMemRecBarrier &memRec);
- void PutToFresh(std::shared_ptr<TBase::TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn);
- void LoadCompleted() override;
+ void PutToFresh(std::shared_ptr<TBase::TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn);
+ void LoadCompleted() override;
TBarriersDsSnapshot GetSnapshot(TActorSystem *as);
TBarriersDsSnapshot GetIndexSnapshot();
private:
TString VDiskLogPrefix;
- std::unique_ptr<TMemView> MemView;
+ std::unique_ptr<TMemView> MemView;
void BuildMemView();
};
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.cpp
index 179c8c27432..684397f3789 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.cpp
@@ -66,13 +66,13 @@ namespace NKikimr {
const TKeyBarrier &key,
const TMemRecBarrier &memRec)
{
- LockWrite();
-
+ LockWrite();
+
TIndexKey indexKey(key.TabletId, key.Channel);
auto deadIt = Dead.find(indexKey);
if (deadIt != Dead.end()) {
// already dead table, ignore
- UnlockWrite();
+ UnlockWrite();
return;
}
@@ -92,8 +92,8 @@ namespace NKikimr {
Dead.insert(indexKey);
Index.erase(it);
}
-
- UnlockWrite();
+
+ UnlockWrite();
}
void TTree::GetBarrier(ui64 tabletId,
@@ -101,15 +101,15 @@ namespace NKikimr {
TMaybe<TCurrentBarrier> &soft,
TMaybe<TCurrentBarrier> &hard) const
{
- LockRead();
-
+ LockRead();
+
TIndexKey indexKey(tabletId, channel);
auto deadIt = Dead.find(indexKey);
if (deadIt != Dead.end()) {
// already dead table, ignore
soft = TCurrentBarrier(Max<ui32>(), Max<ui32>(), Max<ui32>(), Max<ui32>());
hard = TCurrentBarrier(Max<ui32>(), Max<ui32>(), Max<ui32>(), Max<ui32>());
- UnlockRead();
+ UnlockRead();
return;
}
@@ -121,8 +121,8 @@ namespace NKikimr {
soft = it->second.GetSoftBarrier();
hard = it->second.GetHardBarrier();
}
-
- UnlockRead();
+
+ UnlockRead();
}
void TTree::Output(IOutputStream &str) const {
@@ -143,7 +143,7 @@ namespace NKikimr {
// TMemView::TTreeWithLog
////////////////////////////////////////////////////////////////////////////////////////////
TMemView::TTreeWithLog::TTreeWithLog(TIntrusivePtr<TIngressCache> ingressCache, const TString &vdiskLogPrefix)
- : Tree(std::make_shared<TTree>(ingressCache, vdiskLogPrefix))
+ : Tree(std::make_shared<TTree>(ingressCache, vdiskLogPrefix))
{}
void TMemView::TTreeWithLog::RollUp(bool gcOnlySynced){
@@ -168,7 +168,7 @@ namespace NKikimr {
}
bool TMemView::TTreeWithLog::Shared() const {
- return Tree.use_count() > 1;
+ return Tree.use_count() > 1;
}
bool TMemView::TTreeWithLog::NeedRollUp() const {
@@ -184,22 +184,22 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////////////////////
TMemView::TMemView(TIntrusivePtr<TIngressCache> ingrCache, const TString &vdiskLogPrefix, bool gcOnlySynced)
: GCOnlySynced(gcOnlySynced)
- , Active(std::make_unique<TTreeWithLog>(ingrCache, vdiskLogPrefix))
- , Passive(std::make_unique<TTreeWithLog>(ingrCache, vdiskLogPrefix))
+ , Active(std::make_unique<TTreeWithLog>(ingrCache, vdiskLogPrefix))
+ , Passive(std::make_unique<TTreeWithLog>(ingrCache, vdiskLogPrefix))
{}
void TMemView::Update(const TKeyBarrier &key, const TMemRecBarrier &memRec) {
Active->Update(GCOnlySynced, key, memRec);
Passive->Update(GCOnlySynced, key, memRec);
- if (Active->Shared() && !Passive->Shared()) {
- Active.swap(Passive);
+ if (Active->Shared() && !Passive->Shared()) {
+ Active.swap(Passive);
}
}
TMemViewSnap TMemView::GetSnapshot() {
if (Active->NeedRollUp()) {
- if (Active->Shared() && !Passive->Shared()) {
- Active.swap(Passive);
+ if (Active->Shared() && !Passive->Shared()) {
+ Active.swap(Passive);
}
if (!Active->Shared()) {
Active->RollUp(GCOnlySynced);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.h
index e36fbf87eec..7030c10be40 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree.h
@@ -4,7 +4,7 @@
#include "barriers_chain.h"
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h>
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
-#include <util/system/sanitizers.h>
+#include <util/system/sanitizers.h>
namespace NKikimr {
namespace NBarriers {
@@ -91,37 +91,37 @@ namespace NKikimr {
TMaybe<TCurrentBarrier> &soft,
TMaybe<TCurrentBarrier> &hard) const;
void Output(IOutputStream &str) const;
-
- private:
- mutable std::atomic_intptr_t Lock{0};
-
- void LockWrite() {
- if constexpr (NSan::TSanIsOn()) {
- const intptr_t x = Lock.exchange(-1);
- Y_VERIFY(x == 0);
- }
- }
-
- void UnlockWrite() {
- if constexpr (NSan::TSanIsOn()) {
- const intptr_t x = Lock.exchange(0);
- Y_VERIFY(x == -1);
- }
- }
-
- void LockRead() const {
- if constexpr (NSan::TSanIsOn()) {
- const intptr_t x = Lock++;
- Y_VERIFY(x >= 0);
- }
- }
-
- void UnlockRead() const {
- if constexpr (NSan::TSanIsOn()) {
- const intptr_t x = --Lock;
- Y_VERIFY(x >= 0);
- }
- }
+
+ private:
+ mutable std::atomic_intptr_t Lock{0};
+
+ void LockWrite() {
+ if constexpr (NSan::TSanIsOn()) {
+ const intptr_t x = Lock.exchange(-1);
+ Y_VERIFY(x == 0);
+ }
+ }
+
+ void UnlockWrite() {
+ if constexpr (NSan::TSanIsOn()) {
+ const intptr_t x = Lock.exchange(0);
+ Y_VERIFY(x == -1);
+ }
+ }
+
+ void LockRead() const {
+ if constexpr (NSan::TSanIsOn()) {
+ const intptr_t x = Lock++;
+ Y_VERIFY(x >= 0);
+ }
+ }
+
+ void UnlockRead() const {
+ if constexpr (NSan::TSanIsOn()) {
+ const intptr_t x = --Lock;
+ Y_VERIFY(x >= 0);
+ }
+ }
};
////////////////////////////////////////////////////////////////////////////////////////////
@@ -129,10 +129,10 @@ namespace NKikimr {
// Barriers Database Memory View Snapshot
////////////////////////////////////////////////////////////////////////////////////////////
class TMemViewSnap {
- std::shared_ptr<TTree> Tree;
+ std::shared_ptr<TTree> Tree;
public:
- TMemViewSnap(std::shared_ptr<TTree> tree)
+ TMemViewSnap(std::shared_ptr<TTree> tree)
: Tree(std::move(tree))
{}
TMemViewSnap(const TMemViewSnap &) = default;
@@ -157,7 +157,7 @@ namespace NKikimr {
using TLogRec = std::pair<TKeyBarrier, TMemRecBarrier>;
using TLog = TDeque<TLogRec>;
- std::shared_ptr<TTree> Tree;
+ std::shared_ptr<TTree> Tree;
TLog Log;
TTreeWithLog(TIntrusivePtr<TIngressCache> ingressCache, const TString &vdiskLogPrefix);
@@ -172,8 +172,8 @@ namespace NKikimr {
};
const bool GCOnlySynced;
- std::unique_ptr<TTreeWithLog> Active;
- std::unique_ptr<TTreeWithLog> Passive;
+ std::unique_ptr<TTreeWithLog> Active;
+ std::unique_ptr<TTreeWithLog> Passive;
public:
TMemView(TIntrusivePtr<TIngressCache> ingrCache, const TString &vdiskLogPrefix, bool gcOnlySynced);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree_ut.cpp
index ab99707ac8f..7e94122f3e7 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/barriers_tree_ut.cpp
@@ -22,10 +22,10 @@ namespace NKikimr {
TVDiskID vdisk1(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
TVDiskID vdisk2(0, 1, 0, 2 /*domain*/, 0 /*vdisk*/);
TVDiskID vdisk3(0, 1, 0, 3 /*domain*/, 0 /*vdisk*/);
- Cache0 = TIngressCache::Create(Info.PickTopology(), vdisk0);
- Cache1 = TIngressCache::Create(Info.PickTopology(), vdisk1);
- Cache2 = TIngressCache::Create(Info.PickTopology(), vdisk2);
- Cache3 = TIngressCache::Create(Info.PickTopology(), vdisk3);
+ Cache0 = TIngressCache::Create(Info.PickTopology(), vdisk0);
+ Cache1 = TIngressCache::Create(Info.PickTopology(), vdisk1);
+ Cache2 = TIngressCache::Create(Info.PickTopology(), vdisk2);
+ Cache3 = TIngressCache::Create(Info.PickTopology(), vdisk3);
}
void Write(NBarriers::TTree &tree, const TKeyBarrier &key, ui32 collectGen, ui32 collectStep) {
@@ -57,7 +57,7 @@ namespace NKikimr {
Y_UNIT_TEST(Tree) {
TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 1, 4);
TVDiskID vdisk0(0, 1, 0, 0 /*domain*/, 0 /*vdisk*/);
- TIngressCachePtr cache0 = TIngressCache::Create(info.PickTopology(), vdisk0);
+ TIngressCachePtr cache0 = TIngressCache::Create(info.PickTopology(), vdisk0);
NBarriers::TTree tree(cache0, VDiskLogPrefix);
TWriter writer;
TMaybe<NBarriers::TCurrentBarrier> soft;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_cache_barrier.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_cache_barrier.h
index 7983b97a947..16328a34899 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_cache_barrier.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_cache_barrier.h
@@ -1,101 +1,101 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h>
-namespace NKikimr {
-
- class TBarrierCache {
- using TKey = std::pair<ui64, ui32>; // (tablet, channel)
-
- struct TCollectBarrier {
- ui32 Gen = 0;
- ui32 Step = 0;
-
- TCollectBarrier(ui32 gen, ui32 step)
- : Gen(gen)
- , Step(step)
- {}
-
- TCollectBarrier() = default;
- TCollectBarrier(const TCollectBarrier& other) = default;
-
- auto ConvertToTuple() const {
- return std::make_tuple(Gen, Step);
- }
-
+namespace NKikimr {
+
+ class TBarrierCache {
+ using TKey = std::pair<ui64, ui32>; // (tablet, channel)
+
+ struct TCollectBarrier {
+ ui32 Gen = 0;
+ ui32 Step = 0;
+
+ TCollectBarrier(ui32 gen, ui32 step)
+ : Gen(gen)
+ , Step(step)
+ {}
+
+ TCollectBarrier() = default;
+ TCollectBarrier(const TCollectBarrier& other) = default;
+
+ auto ConvertToTuple() const {
+ return std::make_tuple(Gen, Step);
+ }
+
TString ToString() const {
- TStringStream str;
- str << "{Gen# " << Gen << " Step# " << Step << "}";
- return str.Str();
- }
- };
-
- struct TValue {
- TMaybe<TCollectBarrier> Soft;
- TMaybe<TCollectBarrier> Hard;
-
+ TStringStream str;
+ str << "{Gen# " << Gen << " Step# " << Step << "}";
+ return str.Str();
+ }
+ };
+
+ struct TValue {
+ TMaybe<TCollectBarrier> Soft;
+ TMaybe<TCollectBarrier> Hard;
+
TString ToString() const {
- TStringStream str;
- str << "{Soft# " << (Soft ? Soft->ToString() : "<not set>")
- << " Hard# " << (Hard ? Hard->ToString() : "<not set>")
- << "}";
- return str.Str();
- }
- };
-
+ TStringStream str;
+ str << "{Soft# " << (Soft ? Soft->ToString() : "<not set>")
+ << " Hard# " << (Hard ? Hard->ToString() : "<not set>")
+ << "}";
+ return str.Str();
+ }
+ };
+
THashMap<TKey, TValue> Cache;
-
- public:
+
+ public:
void Build(const THullDs *hullDs) {
- // take a snapshot of all barriers; we don't care about LSN's here, because there should be no data in fresh
- // segment at this point of time
+ // take a snapshot of all barriers; we don't care about LSN's here, because there should be no data in fresh
+ // segment at this point of time
TBarriersSnapshot snapshot(hullDs->Barriers->GetIndexSnapshot());
-
- // create iterator and start traversing the whole barrier database
+
+ // create iterator and start traversing the whole barrier database
TBarriersSnapshot::TForwardIterator it(hullDs->HullCtx, &snapshot);
- it.SeekToFirst();
-
+ it.SeekToFirst();
+
TIndexRecordMerger<TKeyBarrier, TMemRecBarrier> merger(hullDs->HullCtx->VCtx->Top->GType);
- while (it.Valid()) {
- it.PutToMerger(&merger);
- merger.Finish();
-
- const TKeyBarrier& key = it.GetCurKey();
- const TMemRecBarrier& memRec = merger.GetMemRec();
- if (!hullDs->HullCtx->GCOnlySynced || memRec.Ingress.IsQuorum(hullDs->HullCtx->IngressCache.Get()) ||
- key.Hard) {
- Update(key.TabletId, key.Channel, key.Hard, memRec.CollectGen, memRec.CollectStep);
- }
-
- it.Next();
- merger.Clear();
- }
- }
-
- void Update(ui64 tabletId, ui32 channel, bool hard, ui32 collectGen, ui32 collectStep) {
- const TKey key(tabletId, channel);
- TValue& value = Cache[key];
- TMaybe<TCollectBarrier>& barrier = hard ? value.Hard : value.Soft;
- if (!barrier || std::make_tuple(collectGen, collectStep) > barrier->ConvertToTuple()) {
- barrier = TCollectBarrier(collectGen, collectStep);
- }
- }
-
+ while (it.Valid()) {
+ it.PutToMerger(&merger);
+ merger.Finish();
+
+ const TKeyBarrier& key = it.GetCurKey();
+ const TMemRecBarrier& memRec = merger.GetMemRec();
+ if (!hullDs->HullCtx->GCOnlySynced || memRec.Ingress.IsQuorum(hullDs->HullCtx->IngressCache.Get()) ||
+ key.Hard) {
+ Update(key.TabletId, key.Channel, key.Hard, memRec.CollectGen, memRec.CollectStep);
+ }
+
+ it.Next();
+ merger.Clear();
+ }
+ }
+
+ void Update(ui64 tabletId, ui32 channel, bool hard, ui32 collectGen, ui32 collectStep) {
+ const TKey key(tabletId, channel);
+ TValue& value = Cache[key];
+ TMaybe<TCollectBarrier>& barrier = hard ? value.Hard : value.Soft;
+ if (!barrier || std::make_tuple(collectGen, collectStep) > barrier->ConvertToTuple()) {
+ barrier = TCollectBarrier(collectGen, collectStep);
+ }
+ }
+
bool Keep(const TLogoBlobID& id, bool keepByIngress, TString *explanation = nullptr) const {
- const TKey key(id.TabletID(), id.Channel());
- auto it = Cache.find(key);
- if (it == Cache.end()) {
- return true;
- }
- const TValue& value = it->second;
- if (explanation) {
- *explanation = value.ToString();
- }
- auto position = std::make_tuple(id.Generation(), id.Step());
- return (!value.Hard || position > value.Hard->ConvertToTuple()) &&
- (keepByIngress || !value.Soft || position > value.Soft->ConvertToTuple());
- }
- };
-
-} // NKikimr
+ const TKey key(id.TabletID(), id.Channel());
+ auto it = Cache.find(key);
+ if (it == Cache.end()) {
+ return true;
+ }
+ const TValue& value = it->second;
+ if (explanation) {
+ *explanation = value.ToString();
+ }
+ auto position = std::make_tuple(id.Generation(), id.Step());
+ return (!value.Hard || position > value.Hard->ConvertToTuple()) &&
+ (keepByIngress || !value.Soft || position > value.Soft->ConvertToTuple());
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_gcessence_defs.h b/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_gcessence_defs.h
index 40132629ced..3af10375cb7 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_gcessence_defs.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/barriers/hullds_gcessence_defs.h
@@ -4,7 +4,7 @@
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h>
#include <library/cpp/actors/util/named_tuple.h>
-
+
namespace NKikimr {
namespace NGc {
@@ -55,113 +55,113 @@ namespace NKikimr {
}
};
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TBarrierKey -- structure that identifies entity for the garbage collector, that is tablet id and channel
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct TBarrierKey
- : public TNamedTupleBase<TBarrierKey>
- {
- ui64 TabletId = 0;
- ui32 Channel = 0;
-
- TBarrierKey() = default;
- TBarrierKey(const TBarrierKey& other) = default;
-
- TBarrierKey(ui64 tabletId, ui32 channel)
- : TabletId(tabletId)
- , Channel(channel)
- {}
-
- TBarrierKey(const TLogoBlobID& id)
- : TabletId(id.TabletID())
- , Channel(id.Channel())
- {}
-
- TBarrierKey(const TKeyBarrier& key)
- : TabletId(key.TabletId)
- , Channel(key.Channel)
- {}
-
- auto ConvertToTuple() const {
- return std::make_tuple(TabletId, Channel);
- }
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TBarrierKey -- structure that identifies entity for the garbage collector, that is tablet id and channel
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ struct TBarrierKey
+ : public TNamedTupleBase<TBarrierKey>
+ {
+ ui64 TabletId = 0;
+ ui32 Channel = 0;
+
+ TBarrierKey() = default;
+ TBarrierKey(const TBarrierKey& other) = default;
+
+ TBarrierKey(ui64 tabletId, ui32 channel)
+ : TabletId(tabletId)
+ , Channel(channel)
+ {}
+
+ TBarrierKey(const TLogoBlobID& id)
+ : TabletId(id.TabletID())
+ , Channel(id.Channel())
+ {}
+
+ TBarrierKey(const TKeyBarrier& key)
+ : TabletId(key.TabletId)
+ , Channel(key.Channel)
+ {}
+
+ auto ConvertToTuple() const {
+ return std::make_tuple(TabletId, Channel);
+ }
+
void Output(IOutputStream& str) const {
- str << TabletId << ":" << Channel;
- }
-
+ str << TabletId << ":" << Channel;
+ }
+
TString ToString() const {
- TStringStream str;
- Output(str);
- return str.Str();
- }
- };
-
- //////////////////////////////////////////////////////////////////////////////////////////
- // TBarrier
+ TStringStream str;
+ Output(str);
+ return str.Str();
+ }
+ };
+
//////////////////////////////////////////////////////////////////////////////////////////
- struct TBarrier
- : public TNamedTupleBase<TBarrier>
- {
- ui32 BarrierGen = 0; // generation of tablet that issued this barrier
- ui32 BarrierGenCounter = 0; // in-generation counter (step) of this entry
- ui32 CollectGen = 0; // generation
- ui32 CollectStep = 0; // step
-
- TBarrier() = default;
- TBarrier(const TBarrier& other) = default;
-
- TBarrier(ui32 barrierGen, ui32 barrierGenCounter, ui32 collectGen, ui32 collectStep)
- : BarrierGen(barrierGen)
- , BarrierGenCounter(barrierGenCounter)
- , CollectGen(collectGen)
- , CollectStep(collectStep)
- {}
-
- TBarrier(const TKeyBarrier& key, const TMemRecBarrier& memRec)
- : BarrierGen(key.Gen)
- , BarrierGenCounter(key.GenCounter)
- , CollectGen(memRec.CollectGen)
- , CollectStep(memRec.CollectStep)
- {}
-
- auto ConvertToTuple() const {
- return std::make_tuple(BarrierGen, BarrierGenCounter, CollectGen, CollectStep);
- }
-
- // checks whether the barrier is set; the default value is treated as empty
- operator bool() const {
- return *this != TBarrier();
- }
-
+ // TBarrier
+ //////////////////////////////////////////////////////////////////////////////////////////
+ struct TBarrier
+ : public TNamedTupleBase<TBarrier>
+ {
+ ui32 BarrierGen = 0; // generation of tablet that issued this barrier
+ ui32 BarrierGenCounter = 0; // in-generation counter (step) of this entry
+ ui32 CollectGen = 0; // generation
+ ui32 CollectStep = 0; // step
+
+ TBarrier() = default;
+ TBarrier(const TBarrier& other) = default;
+
+ TBarrier(ui32 barrierGen, ui32 barrierGenCounter, ui32 collectGen, ui32 collectStep)
+ : BarrierGen(barrierGen)
+ , BarrierGenCounter(barrierGenCounter)
+ , CollectGen(collectGen)
+ , CollectStep(collectStep)
+ {}
+
+ TBarrier(const TKeyBarrier& key, const TMemRecBarrier& memRec)
+ : BarrierGen(key.Gen)
+ , BarrierGenCounter(key.GenCounter)
+ , CollectGen(memRec.CollectGen)
+ , CollectStep(memRec.CollectStep)
+ {}
+
+ auto ConvertToTuple() const {
+ return std::make_tuple(BarrierGen, BarrierGenCounter, CollectGen, CollectStep);
+ }
+
+ // checks whether the barrier is set; the default value is treated as empty
+ operator bool() const {
+ return *this != TBarrier();
+ }
+
void Output(IOutputStream& str) const {
str << "Issued:[" << BarrierGen << ":" << BarrierGenCounter << "]" << " -> Collect:[" << CollectGen << ":" << CollectStep << "]";
- }
-
+ }
+
TString ToString() const {
- TStringStream str;
- Output(str);
- return str.Str();
- }
- };
-
- //////////////////////////////////////////////////////////////////////////////////////////
+ TStringStream str;
+ Output(str);
+ return str.Str();
+ }
+ };
+
+ //////////////////////////////////////////////////////////////////////////////////////////
// TFindResult
//////////////////////////////////////////////////////////////////////////////////////////
struct TFindResult {
- bool EntryFound;
- TBarrier SoftBarrier;
- TBarrier HardBarrier;
-
- TFindResult()
- : EntryFound(false)
- {}
-
- TFindResult(const TBarrier& soft, const TBarrier& hard)
- : EntryFound(true)
- , SoftBarrier(soft)
- , HardBarrier(hard)
- {}
+ bool EntryFound;
+ TBarrier SoftBarrier;
+ TBarrier HardBarrier;
+
+ TFindResult()
+ : EntryFound(false)
+ {}
+
+ TFindResult(const TBarrier& soft, const TBarrier& hard)
+ : EntryFound(true)
+ , SoftBarrier(soft)
+ , HardBarrier(hard)
+ {}
};
//////////////////////////////////////////////////////////////////////////////////////
@@ -173,11 +173,11 @@ namespace NKikimr {
ui64 NotSyncedNum = 0;
TStringStream DbgStream;
- void Init(const THullCtxPtr &hullCtx, int debugLevel) {
- if (debugLevel > 0) {
- DbgStream << hullCtx->VCtx->VDiskLogPrefix;
- }
- }
+ void Init(const THullCtxPtr &hullCtx, int debugLevel) {
+ if (debugLevel > 0) {
+ DbgStream << hullCtx->VCtx->VDiskLogPrefix;
+ }
+ }
};
//////////////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h
index 56fcf7a9e8c..03d8fbe7253 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h
@@ -4,7 +4,7 @@
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h>
#include <ydb/core/base/blobstorage_grouptype.h>
-
+
namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
@@ -27,150 +27,150 @@ namespace NKikimr {
// LocalParts=1b
//
class TDiskBlob {
- const TRope *Rope = nullptr; // the origin rope from which this blob comes; may be null for merger case
- NMatrix::TVectorType Parts; // a set of parts in this blob
- std::array<TRope, MaxTotalPartCount> PartData; // array of part data
- std::array<ui32, MaxTotalPartCount + 1> PartOffs; // array of part offsets
- ui32 FullDataSize = 0; // size of the whole blob
-
+ const TRope *Rope = nullptr; // the origin rope from which this blob comes; may be null for merger case
+ NMatrix::TVectorType Parts; // a set of parts in this blob
+ std::array<TRope, MaxTotalPartCount> PartData; // array of part data
+ std::array<ui32, MaxTotalPartCount + 1> PartOffs; // array of part offsets
+ ui32 FullDataSize = 0; // size of the whole blob
+
public:
static const size_t HeaderSize = sizeof(ui32) + sizeof(ui8);
static const size_t HugeBlobOverhead = HeaderSize;
- TDiskBlob() = default;
-
- TDiskBlob(const TRope *rope, NMatrix::TVectorType parts, TBlobStorageGroupType gtype, const TLogoBlobID& fullId)
- : Rope(rope)
- , Parts(parts)
- {
- // ensure the blob format is correct
- Y_VERIFY(Rope->GetSize() >= HeaderSize);
- Y_VERIFY(parts.GetSize() <= MaxTotalPartCount);
- //Y_VERIFY(parts.GetSize() == gtype.TotalPartCount()); // TODO(alexvru): fit UTs
-
- auto iter = Rope->Begin();
-
- // obtain full data size from the header
- iter.ExtractPlainDataAndAdvance(&FullDataSize, sizeof(FullDataSize));
-
- // then check the parts; we have `parts' argument to validate actual blob content
- ui8 partsMask;
- iter.ExtractPlainDataAndAdvance(&partsMask, sizeof(partsMask));
- Y_VERIFY(parts.Raw() == partsMask);
-
- // calculate part layout in the binary
- ui32 offset = HeaderSize;
- for (ui8 i = 0; i <= parts.GetSize(); ++i) {
- PartOffs[i] = offset;
- if (i != parts.GetSize()) {
- offset += parts.Get(i) ? gtype.PartSize(TLogoBlobID(fullId, i + 1)) : 0;
- }
- }
- Y_VERIFY(GetSize() == Rope->GetSize(), "%" PRIu32 " != %zu", GetSize(), Rope->GetSize());
- }
+ TDiskBlob() = default;
- bool Empty() const {
- return Parts.Empty();
- }
+ TDiskBlob(const TRope *rope, NMatrix::TVectorType parts, TBlobStorageGroupType gtype, const TLogoBlobID& fullId)
+ : Rope(rope)
+ , Parts(parts)
+ {
+ // ensure the blob format is correct
+ Y_VERIFY(Rope->GetSize() >= HeaderSize);
+ Y_VERIFY(parts.GetSize() <= MaxTotalPartCount);
+ //Y_VERIFY(parts.GetSize() == gtype.TotalPartCount()); // TODO(alexvru): fit UTs
- bool ContainsMetadataPartsOnly() const {
- for (ui8 i = Parts.FirstPosition(); i != Parts.GetSize(); i = Parts.NextPosition(i)) {
- if (GetPartSize(i)) {
- return false;
- }
- }
- return !Empty();
+ auto iter = Rope->Begin();
+
+ // obtain full data size from the header
+ iter.ExtractPlainDataAndAdvance(&FullDataSize, sizeof(FullDataSize));
+
+ // then check the parts; we have `parts' argument to validate actual blob content
+ ui8 partsMask;
+ iter.ExtractPlainDataAndAdvance(&partsMask, sizeof(partsMask));
+ Y_VERIFY(parts.Raw() == partsMask);
+
+ // calculate part layout in the binary
+ ui32 offset = HeaderSize;
+ for (ui8 i = 0; i <= parts.GetSize(); ++i) {
+ PartOffs[i] = offset;
+ if (i != parts.GetSize()) {
+ offset += parts.Get(i) ? gtype.PartSize(TLogoBlobID(fullId, i + 1)) : 0;
+ }
+ }
+ Y_VERIFY(GetSize() == Rope->GetSize(), "%" PRIu32 " != %zu", GetSize(), Rope->GetSize());
}
+ bool Empty() const {
+ return Parts.Empty();
+ }
+
+ bool ContainsMetadataPartsOnly() const {
+ for (ui8 i = Parts.FirstPosition(); i != Parts.GetSize(); i = Parts.NextPosition(i)) {
+ if (GetPartSize(i)) {
+ return false;
+ }
+ }
+ return !Empty();
+ }
+
ui64 GetFullDataSize() const {
return FullDataSize;
}
- // in some cases GetPart may return reference without actually copying the rope, so we provide holder in this case
- const TRope& GetPart(ui8 part, ui32 offset, ui32 size, TRope *holder) const {
- Y_VERIFY(Parts.Get(part));
- const ui32 partSize = GetPartSize(part);
- Y_VERIFY(offset <= partSize && offset + size <= partSize && part < PartData.size());
- if (Rope) {
- auto iter = Rope->Position(PartOffs[part] + offset);
- return *holder = TRope(iter, iter + size);
- } else {
- return PartData[part];
- }
+ // in some cases GetPart may return reference without actually copying the rope, so we provide holder in this case
+ const TRope& GetPart(ui8 part, ui32 offset, ui32 size, TRope *holder) const {
+ Y_VERIFY(Parts.Get(part));
+ const ui32 partSize = GetPartSize(part);
+ Y_VERIFY(offset <= partSize && offset + size <= partSize && part < PartData.size());
+ if (Rope) {
+ auto iter = Rope->Position(PartOffs[part] + offset);
+ return *holder = TRope(iter, iter + size);
+ } else {
+ return PartData[part];
+ }
}
- TRope GetPart(ui8 part, TRope *holder) const {
- return GetPart(part, 0, GetPartSize(part), holder);
+ TRope GetPart(ui8 part, TRope *holder) const {
+ return GetPart(part, 0, GetPartSize(part), holder);
}
- ui32 GetPartSize(ui8 part) const {
- Y_VERIFY(part < PartData.size());
- return PartOffs[part + 1] - PartOffs[part];
+ ui32 GetPartSize(ui8 part) const {
+ Y_VERIFY(part < PartData.size());
+ return PartOffs[part + 1] - PartOffs[part];
}
NMatrix::TVectorType GetParts() const {
return Parts;
}
- ui32 GetSize() const {
- return PartOffs[Parts.GetSize()];
- }
+ ui32 GetSize() const {
+ return PartOffs[Parts.GetSize()];
+ }
////////////////// Iterator via all parts ///////////////////////////////////////
class TPartIterator {
public:
- TPartIterator(const TDiskBlob *blob, ui8 part)
- : Blob(blob)
- , Part(part)
- {
- if (blob->Rope) {
- Iter = blob->Rope->Position(blob->PartOffs[part]);
- }
- }
+ TPartIterator(const TDiskBlob *blob, ui8 part)
+ : Blob(blob)
+ , Part(part)
+ {
+ if (blob->Rope) {
+ Iter = blob->Rope->Position(blob->PartOffs[part]);
+ }
+ }
inline TPartIterator& operator++() noexcept {
- if (Blob->Rope) {
- Iter += Blob->GetPartSize(Part);
- }
- Part = Blob->Parts.NextPosition(Part);
+ if (Blob->Rope) {
+ Iter += Blob->GetPartSize(Part);
+ }
+ Part = Blob->Parts.NextPosition(Part);
return *this;
}
inline TPartIterator operator++(int) noexcept {
- TPartIterator res(*this);
- ++*this;
- return res;
+ TPartIterator res(*this);
+ ++*this;
+ return res;
}
ui8 GetPartId() const {
- return Part + 1;
- }
-
- const TRope& GetPart(ui32 offset, ui32 size, TRope *holder) const {
- if (Blob->Rope) {
- return *holder = TRope(Iter + offset, Iter + (offset + size));
- } else if (offset == 0 && size == Blob->GetPartSize(Part)) {
- Y_VERIFY(Part < Blob->PartData.size());
- return Blob->PartData[Part];
- } else {
- Y_VERIFY(Part < Blob->PartData.size());
- const TRope& data = Blob->PartData[Part];
- return *holder = TRope(data.Position(offset), data.Position(offset + size));
- }
+ return Part + 1;
}
- TRope GetPart() const {
- if (Blob->Rope) {
- return TRope(Iter, Iter + Blob->GetPartSize(Part));
- } else {
- Y_VERIFY(Part < Blob->PartData.size());
- return Blob->PartData[Part];
- }
+ const TRope& GetPart(ui32 offset, ui32 size, TRope *holder) const {
+ if (Blob->Rope) {
+ return *holder = TRope(Iter + offset, Iter + (offset + size));
+ } else if (offset == 0 && size == Blob->GetPartSize(Part)) {
+ Y_VERIFY(Part < Blob->PartData.size());
+ return Blob->PartData[Part];
+ } else {
+ Y_VERIFY(Part < Blob->PartData.size());
+ const TRope& data = Blob->PartData[Part];
+ return *holder = TRope(data.Position(offset), data.Position(offset + size));
+ }
}
+ TRope GetPart() const {
+ if (Blob->Rope) {
+ return TRope(Iter, Iter + Blob->GetPartSize(Part));
+ } else {
+ Y_VERIFY(Part < Blob->PartData.size());
+ return Blob->PartData[Part];
+ }
+ }
+
bool operator == (const TPartIterator &i) {
- Y_VERIFY_DEBUG(Blob == i.Blob);
- return Part == i.Part;
+ Y_VERIFY_DEBUG(Blob == i.Blob);
+ return Part == i.Part;
}
bool operator != (const TPartIterator &i) {
@@ -178,115 +178,115 @@ namespace NKikimr {
}
private:
- const TDiskBlob *Blob; // the blob we are walking over
- ui8 Part; // part index, actually partId - 1
- TRope::TConstIterator Iter; // iterator to rope, if set
+ const TDiskBlob *Blob; // the blob we are walking over
+ ui8 Part; // part index, actually partId - 1
+ TRope::TConstIterator Iter; // iterator to rope, if set
};
TPartIterator begin() const {
- return {this, Parts.FirstPosition()};
+ return {this, Parts.FirstPosition()};
}
TPartIterator end() const {
- return {this, Parts.GetSize()};
+ return {this, Parts.GetSize()};
}
-
+
////////////////// Iterator via all parts ///////////////////////////////////////
- friend bool operator ==(const TDiskBlob& x, const TDiskBlob& y) {
- return x.FullDataSize == y.FullDataSize
- && x.Parts == y.Parts
- && ((x.Rope && y.Rope) ? *x.Rope == *y.Rope : x.Rope == y.Rope)
- && x.PartData == y.PartData
- && x.PartOffs == y.PartOffs;
- }
-
+ friend bool operator ==(const TDiskBlob& x, const TDiskBlob& y) {
+ return x.FullDataSize == y.FullDataSize
+ && x.Parts == y.Parts
+ && ((x.Rope && y.Rope) ? *x.Rope == *y.Rope : x.Rope == y.Rope)
+ && x.PartData == y.PartData
+ && x.PartOffs == y.PartOffs;
+ }
+
public:
- template<typename TPartIt>
- static TRope CreateFromDistinctParts(TPartIt first, TPartIt last, NMatrix::TVectorType parts, ui64 fullDataSize, TRopeArena& arena) {
- // ensure that we have correct number of set parts
- Y_VERIFY(parts.CountBits() == std::distance(first, last));
- Y_VERIFY(first != last);
-
- TRope rope;
-
- // fill in header
- char header[HeaderSize];
- Y_VERIFY(fullDataSize <= Max<ui32>());
- *reinterpret_cast<ui32*>(header) = fullDataSize;
- *reinterpret_cast<ui8*>(header + sizeof(ui32)) = parts.Raw();
- rope.Insert(rope.End(), arena.CreateRope(header, HeaderSize));
-
- // then copy parts' contents to the rope
- while (first != last) {
- rope.Insert(rope.End(), std::move(*first++));
- }
-
- return rope;
- }
-
- static inline TRope Create(ui64 fullDataSize, ui8 partId, ui8 total, TRope&& data, TRopeArena& arena) {
- Y_VERIFY(partId > 0 && partId <= 8);
- return CreateFromDistinctParts(&data, &data + 1, NMatrix::TVectorType::MakeOneHot(partId - 1, total),
- fullDataSize, arena);
- }
-
- static inline TRope Create(ui64 fullDataSize, NMatrix::TVectorType parts, TRope&& data, TRopeArena& arena) {
- return CreateFromDistinctParts(&data, &data + 1, parts, fullDataSize, arena);
- }
-
+ template<typename TPartIt>
+ static TRope CreateFromDistinctParts(TPartIt first, TPartIt last, NMatrix::TVectorType parts, ui64 fullDataSize, TRopeArena& arena) {
+ // ensure that we have correct number of set parts
+ Y_VERIFY(parts.CountBits() == std::distance(first, last));
+ Y_VERIFY(first != last);
+
+ TRope rope;
+
+ // fill in header
+ char header[HeaderSize];
+ Y_VERIFY(fullDataSize <= Max<ui32>());
+ *reinterpret_cast<ui32*>(header) = fullDataSize;
+ *reinterpret_cast<ui8*>(header + sizeof(ui32)) = parts.Raw();
+ rope.Insert(rope.End(), arena.CreateRope(header, HeaderSize));
+
+ // then copy parts' contents to the rope
+ while (first != last) {
+ rope.Insert(rope.End(), std::move(*first++));
+ }
+
+ return rope;
+ }
+
+ static inline TRope Create(ui64 fullDataSize, ui8 partId, ui8 total, TRope&& data, TRopeArena& arena) {
+ Y_VERIFY(partId > 0 && partId <= 8);
+ return CreateFromDistinctParts(&data, &data + 1, NMatrix::TVectorType::MakeOneHot(partId - 1, total),
+ fullDataSize, arena);
+ }
+
+ static inline TRope Create(ui64 fullDataSize, NMatrix::TVectorType parts, TRope&& data, TRopeArena& arena) {
+ return CreateFromDistinctParts(&data, &data + 1, parts, fullDataSize, arena);
+ }
+
// static function for calculating size of a blob being created ('Create' function creates blob of this size)
- static inline ui32 CalculateBlobSize(TBlobStorageGroupType gtype, const TLogoBlobID& fullId, NMatrix::TVectorType parts) {
- ui32 res = HeaderSize;
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- res += gtype.PartSize(TLogoBlobID(fullId, i + 1));
- }
- return res;
- }
-
- private:
- friend class TDiskBlobMerger;
-
- // used by blob merger
- void MergePart(const TDiskBlob& source, TPartIterator iter) {
- const ui8 part = iter.GetPartId() - 1;
- Y_VERIFY(!Rope); // ensure that this blob is used inside merger
- Y_VERIFY(FullDataSize == 0 || FullDataSize == source.FullDataSize, "FullDataSize# %" PRIu32 " source.FullDataSize# %" PRIu32,
- FullDataSize, source.FullDataSize);
-
- if (Parts.Empty()) {
- Parts = NMatrix::TVectorType(0, source.Parts.GetSize());
- PartOffs.fill(HeaderSize);
- } else {
- Y_VERIFY(Parts.GetSize() == source.Parts.GetSize());
- }
-
- if (!Parts.Get(part)) {
- Parts.Set(part);
- TRope partData = iter.GetPart();
- for (ui8 i = part + 1; i <= Parts.GetSize(); ++i) {
- PartOffs[i] += partData.GetSize();
- }
- Y_VERIFY(part < PartData.size());
- PartData[part] = std::move(partData);
- FullDataSize = source.FullDataSize;
+ static inline ui32 CalculateBlobSize(TBlobStorageGroupType gtype, const TLogoBlobID& fullId, NMatrix::TVectorType parts) {
+ ui32 res = HeaderSize;
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ res += gtype.PartSize(TLogoBlobID(fullId, i + 1));
+ }
+ return res;
+ }
+
+ private:
+ friend class TDiskBlobMerger;
+
+ // used by blob merger
+ void MergePart(const TDiskBlob& source, TPartIterator iter) {
+ const ui8 part = iter.GetPartId() - 1;
+ Y_VERIFY(!Rope); // ensure that this blob is used inside merger
+ Y_VERIFY(FullDataSize == 0 || FullDataSize == source.FullDataSize, "FullDataSize# %" PRIu32 " source.FullDataSize# %" PRIu32,
+ FullDataSize, source.FullDataSize);
+
+ if (Parts.Empty()) {
+ Parts = NMatrix::TVectorType(0, source.Parts.GetSize());
+ PartOffs.fill(HeaderSize);
+ } else {
+ Y_VERIFY(Parts.GetSize() == source.Parts.GetSize());
+ }
+
+ if (!Parts.Get(part)) {
+ Parts.Set(part);
+ TRope partData = iter.GetPart();
+ for (ui8 i = part + 1; i <= Parts.GetSize(); ++i) {
+ PartOffs[i] += partData.GetSize();
+ }
+ Y_VERIFY(part < PartData.size());
+ PartData[part] = std::move(partData);
+ FullDataSize = source.FullDataSize;
}
}
-
- TRope CreateDiskBlob(TRopeArena& arena) const {
- Y_VERIFY(!Empty());
-
- char header[HeaderSize];
- *reinterpret_cast<ui32*>(header) = FullDataSize;
- *reinterpret_cast<ui8*>(header + sizeof(ui32)) = Parts.Raw();
-
- TRope rope(arena.CreateRope(header, sizeof(header)));
- for (auto it = begin(); it != end(); ++it) {
- rope.Insert(rope.End(), it.GetPart());
- }
-
- return rope;
- }
+
+ TRope CreateDiskBlob(TRopeArena& arena) const {
+ Y_VERIFY(!Empty());
+
+ char header[HeaderSize];
+ *reinterpret_cast<ui32*>(header) = FullDataSize;
+ *reinterpret_cast<ui8*>(header + sizeof(ui32)) = Parts.Raw();
+
+ TRope rope(arena.CreateRope(header, sizeof(header)));
+ for (auto it = begin(); it != end(); ++it) {
+ rope.Insert(rope.End(), it.GetPart());
+ }
+
+ return rope;
+ }
};
@@ -295,110 +295,110 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TDiskBlobMerger {
public:
- TDiskBlobMerger()
- {}
+ TDiskBlobMerger()
+ {}
void Clear() {
- Blob = {};
+ Blob = {};
}
void Add(const TDiskBlob &addBlob) {
Y_VERIFY(!addBlob.GetParts().Empty());
- AddImpl(addBlob, addBlob.GetParts());
- }
-
- void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& it) {
- Blob.MergePart(source, it);
+ AddImpl(addBlob, addBlob.GetParts());
}
+ void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& it) {
+ Blob.MergePart(source, it);
+ }
+
bool Empty() const {
- return Blob.Empty();
+ return Blob.Empty();
}
- TRope CreateDiskBlob(TRopeArena& arena) const {
- return Blob.CreateDiskBlob(arena);
+ TRope CreateDiskBlob(TRopeArena& arena) const {
+ return Blob.CreateDiskBlob(arena);
}
- const TDiskBlob& GetDiskBlob() const {
+ const TDiskBlob& GetDiskBlob() const {
return Blob;
}
void Swap(TDiskBlobMerger &m) {
- std::swap(Blob, m.Blob);
+ std::swap(Blob, m.Blob);
}
TString ToString() const {
TStringStream str;
- str << "{FullDataSize# " << Blob.GetFullDataSize() << " Parts# " << Blob.GetParts().ToString() << "}";
+ str << "{FullDataSize# " << Blob.GetFullDataSize() << " Parts# " << Blob.GetParts().ToString() << "}";
return str.Str();
}
- friend bool operator ==(const TDiskBlobMerger& x, const TDiskBlobMerger& y) {
- return x.Blob == y.Blob;
- }
-
- protected:
+ friend bool operator ==(const TDiskBlobMerger& x, const TDiskBlobMerger& y) {
+ return x.Blob == y.Blob;
+ }
+
+ protected:
void AddImpl(const TDiskBlob &addBlob, NMatrix::TVectorType addParts) {
- for (auto it = addBlob.begin(); it != addBlob.end(); ++it) {
- const ui8 part = it.GetPartId() - 1;
- if (addParts.Get(part)) {
- AddPart(addBlob, it);
- }
- }
- }
-
+ for (auto it = addBlob.begin(); it != addBlob.end(); ++it) {
+ const ui8 part = it.GetPartId() - 1;
+ if (addParts.Get(part)) {
+ AddPart(addBlob, it);
+ }
+ }
+ }
+
private:
TDiskBlob Blob;
};
- class TDiskBlobMergerWithMask : public TDiskBlobMerger {
- public:
- TDiskBlobMergerWithMask() = default;
- TDiskBlobMergerWithMask(const TDiskBlobMergerWithMask&) = default;
- TDiskBlobMergerWithMask(TDiskBlobMergerWithMask&&) = default;
-
- TDiskBlobMergerWithMask(const TDiskBlobMerger& base, NMatrix::TVectorType mask)
- : AddFilterMask(mask)
- {
- // TODO(alexvru): check for saneness; maybe we shall not provide blobs not in mask?
- const TDiskBlob& blob = base.GetDiskBlob();
- for (auto it = blob.begin(); it != blob.end(); ++it) {
- AddPart(blob, it);
- }
- }
-
- void Clear() {
- TDiskBlobMerger::Clear();
- AddFilterMask.Clear();
- }
-
+ class TDiskBlobMergerWithMask : public TDiskBlobMerger {
+ public:
+ TDiskBlobMergerWithMask() = default;
+ TDiskBlobMergerWithMask(const TDiskBlobMergerWithMask&) = default;
+ TDiskBlobMergerWithMask(TDiskBlobMergerWithMask&&) = default;
+
+ TDiskBlobMergerWithMask(const TDiskBlobMerger& base, NMatrix::TVectorType mask)
+ : AddFilterMask(mask)
+ {
+ // TODO(alexvru): check for saneness; maybe we shall not provide blobs not in mask?
+ const TDiskBlob& blob = base.GetDiskBlob();
+ for (auto it = blob.begin(); it != blob.end(); ++it) {
+ AddPart(blob, it);
+ }
+ }
+
+ void Clear() {
+ TDiskBlobMerger::Clear();
+ AddFilterMask.Clear();
+ }
+
void SetFilterMask(NMatrix::TVectorType mask) {
- Y_VERIFY(!AddFilterMask);
- AddFilterMask = mask;
- }
-
- void Add(const TDiskBlob &addBlob) {
- Y_VERIFY(AddFilterMask);
+ Y_VERIFY(!AddFilterMask);
+ AddFilterMask = mask;
+ }
+
+ void Add(const TDiskBlob &addBlob) {
+ Y_VERIFY(AddFilterMask);
NMatrix::TVectorType addParts = addBlob.GetParts() & *AddFilterMask;
- if (!addParts.Empty()) {
- TDiskBlobMerger::AddImpl(addBlob, addParts);
- }
- }
-
- void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& it) {
- Y_VERIFY(AddFilterMask);
- if (AddFilterMask->Get(it.GetPartId() - 1)) {
- TDiskBlobMerger::AddPart(source, it);
- }
- }
-
- void Swap(TDiskBlobMergerWithMask& m) {
- TDiskBlobMerger::Swap(m);
- DoSwap(AddFilterMask, m.AddFilterMask);
- }
-
- private:
+ if (!addParts.Empty()) {
+ TDiskBlobMerger::AddImpl(addBlob, addParts);
+ }
+ }
+
+ void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& it) {
+ Y_VERIFY(AddFilterMask);
+ if (AddFilterMask->Get(it.GetPartId() - 1)) {
+ TDiskBlobMerger::AddPart(source, it);
+ }
+ }
+
+ void Swap(TDiskBlobMergerWithMask& m) {
+ TDiskBlobMerger::Swap(m);
+ DoSwap(AddFilterMask, m.AddFilterMask);
+ }
+
+ private:
TMaybe<NMatrix::TVectorType> AddFilterMask;
- };
-
+ };
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob_ut.cpp
index 5774a53a39d..a2ca7582c7a 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob_ut.cpp
@@ -3,67 +3,67 @@
namespace NKikimr {
- TIntrusivePtr<IRopeChunkBackend> AllocateArena() {
- return TRopeAlignedBuffer::Allocate(65536);
- }
-
- TRopeArena Arena(&AllocateArena);
-
- const TBlobStorageGroupType GType(TBlobStorageGroupType::ErasureNone);
-
+ TIntrusivePtr<IRopeChunkBackend> AllocateArena() {
+ return TRopeAlignedBuffer::Allocate(65536);
+ }
+
+ TRopeArena Arena(&AllocateArena);
+
+ const TBlobStorageGroupType GType(TBlobStorageGroupType::ErasureNone);
+
Y_UNIT_TEST_SUITE(TBlobStorageDiskBlob) {
Y_UNIT_TEST(CreateFromDistinctParts) {
- const ui8 totalParts = MaxTotalPartCount;
- const ui32 partSize = 6;
- const ui64 fullDataSize = partSize * totalParts / 2;
- const char *data[totalParts] = {
- "111111",
- "222222",
- "333333",
- "444444",
- "555555",
- "666666",
- "777777",
- };
-
- for (ui32 mask = 1; mask < (1 << totalParts); ++mask) {
- std::array<TRope, MaxTotalPartCount> partsData;
- ui32 numParts = 0;
+ const ui8 totalParts = MaxTotalPartCount;
+ const ui32 partSize = 6;
+ const ui64 fullDataSize = partSize * totalParts / 2;
+ const char *data[totalParts] = {
+ "111111",
+ "222222",
+ "333333",
+ "444444",
+ "555555",
+ "666666",
+ "777777",
+ };
+
+ for (ui32 mask = 1; mask < (1 << totalParts); ++mask) {
+ std::array<TRope, MaxTotalPartCount> partsData;
+ ui32 numParts = 0;
NMatrix::TVectorType parts(0, totalParts);
- for (ui8 i = 0; i < totalParts; ++i) {
- if (mask >> i & 1) {
- partsData[numParts++] = TRope(TString(data[i], partSize));
- parts.Set(i);
- }
- }
-
- TRope buffer = TDiskBlob::CreateFromDistinctParts(partsData.begin(), partsData.begin() + numParts, parts, fullDataSize, Arena);
-
- TDiskBlobMerger m;
- for (ui8 i = 0; i < totalParts; ++i) {
- if (mask >> i & 1) {
- const ui8 partId = i + 1;
- TRope blobBuffer = TDiskBlob::Create(fullDataSize, partId, totalParts, TRope(TString(data[i], partSize)), Arena);
- TDiskBlob blob(&blobBuffer, NMatrix::TVectorType::MakeOneHot(i, totalParts), GType, TLogoBlobID(0, 0, 0, 0, partSize, 0));
- m.Add(blob);
- }
- }
-
- UNIT_ASSERT_EQUAL(buffer, m.CreateDiskBlob(Arena));
- }
- }
-
+ for (ui8 i = 0; i < totalParts; ++i) {
+ if (mask >> i & 1) {
+ partsData[numParts++] = TRope(TString(data[i], partSize));
+ parts.Set(i);
+ }
+ }
+
+ TRope buffer = TDiskBlob::CreateFromDistinctParts(partsData.begin(), partsData.begin() + numParts, parts, fullDataSize, Arena);
+
+ TDiskBlobMerger m;
+ for (ui8 i = 0; i < totalParts; ++i) {
+ if (mask >> i & 1) {
+ const ui8 partId = i + 1;
+ TRope blobBuffer = TDiskBlob::Create(fullDataSize, partId, totalParts, TRope(TString(data[i], partSize)), Arena);
+ TDiskBlob blob(&blobBuffer, NMatrix::TVectorType::MakeOneHot(i, totalParts), GType, TLogoBlobID(0, 0, 0, 0, partSize, 0));
+ m.Add(blob);
+ }
+ }
+
+ UNIT_ASSERT_EQUAL(buffer, m.CreateDiskBlob(Arena));
+ }
+ }
+
Y_UNIT_TEST(CreateIterate) {
ui8 partId = 2;
TString data("abcdefgh");
- TRope buf = TDiskBlob::Create(16, partId, 3, TRope(data), Arena);
+ TRope buf = TDiskBlob::Create(16, partId, 3, TRope(data), Arena);
NMatrix::TVectorType localParts(0, 3);
localParts.Set(partId - 1);
- TDiskBlob blob(&buf, localParts, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
+ TDiskBlob blob(&buf, localParts, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
for (TDiskBlob::TPartIterator it = blob.begin(), e = blob.end(); it != e; ++it) {
UNIT_ASSERT(it.GetPartId() == partId);
- UNIT_ASSERT(it.GetPart().ConvertToString() == data);
+ UNIT_ASSERT(it.GetPart().ConvertToString() == data);
}
}
@@ -72,17 +72,17 @@ namespace NKikimr {
// blob1
ui8 partId1 = 1;
- TRope buf1 = TDiskBlob::Create(16, partId1, 8, TRope(data), Arena);
+ TRope buf1 = TDiskBlob::Create(16, partId1, 8, TRope(data), Arena);
NMatrix::TVectorType localParts1(0, 3);
localParts1.Set(partId1 - 1);
- TDiskBlob blob1(&buf1, localParts1, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
+ TDiskBlob blob1(&buf1, localParts1, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
// blob2
ui8 partId2 = 3;
- TRope buf2 = TDiskBlob::Create(16, partId2, 8, TRope(data), Arena);
+ TRope buf2 = TDiskBlob::Create(16, partId2, 8, TRope(data), Arena);
NMatrix::TVectorType localParts2(0, 3);
localParts2.Set(partId2 - 1);
- TDiskBlob blob2(&buf2, localParts2, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
+ TDiskBlob blob2(&buf2, localParts2, GType, TLogoBlobID(0, 0, 0, 0, data.size(), 0));
// merge vars
TDiskBlobMerger merger;
@@ -101,12 +101,12 @@ namespace NKikimr {
UNIT_ASSERT(!merger.Empty());
merger.Add(blob2);
UNIT_ASSERT(!merger.Empty());
- const TDiskBlob& blob = merger.GetDiskBlob();
+ const TDiskBlob& blob = merger.GetDiskBlob();
UNIT_ASSERT(resParts == blob.GetParts());
for (TDiskBlob::TPartIterator it = blob.begin(), e = blob.end(); it != e; ++it) {
ppp.push_back(it.GetPartId());
- UNIT_ASSERT_VALUES_EQUAL(blob.GetPartSize(it.GetPartId() - 1), data.size());
- UNIT_ASSERT(it.GetPart().ConvertToString() == data);
+ UNIT_ASSERT_VALUES_EQUAL(blob.GetPartSize(it.GetPartId() - 1), data.size());
+ UNIT_ASSERT(it.GetPart().ConvertToString() == data);
}
UNIT_ASSERT(ppp == resPpp);
}
@@ -122,57 +122,57 @@ namespace NKikimr {
UNIT_ASSERT(!merger.Empty());
merger.Add(blob1);
UNIT_ASSERT(!merger.Empty());
- const TDiskBlob& blob = merger.GetDiskBlob();
+ const TDiskBlob& blob = merger.GetDiskBlob();
UNIT_ASSERT(resParts == blob.GetParts());
for (TDiskBlob::TPartIterator it = blob.begin(), e = blob.end(); it != e; ++it) {
ppp.push_back(it.GetPartId());
- UNIT_ASSERT(blob.GetPartSize(it.GetPartId() - 1) == data.size());
- UNIT_ASSERT(it.GetPart().ConvertToString() == data);
+ UNIT_ASSERT(blob.GetPartSize(it.GetPartId() - 1) == data.size());
+ UNIT_ASSERT(it.GetPart().ConvertToString() == data);
}
UNIT_ASSERT(ppp == resPpp);
}
}
-
+
Y_UNIT_TEST(FilterMask) {
- const ui8 numParts = 6;
- for (ui32 mask1 = 1; mask1 < (1 << numParts); ++mask1) {
- for (ui32 mask2 = 1; mask2 < (1 << numParts); ++mask2) {
- if (!(mask1 & mask2)) {
- continue;
- }
-
+ const ui8 numParts = 6;
+ for (ui32 mask1 = 1; mask1 < (1 << numParts); ++mask1) {
+ for (ui32 mask2 = 1; mask2 < (1 << numParts); ++mask2) {
+ if (!(mask1 & mask2)) {
+ continue;
+ }
+
NMatrix::TVectorType partsToStore(0, numParts);
- for (ui8 i = 0; i < numParts; ++i) {
- if (mask2 >> i & 1) {
- partsToStore.Set(i);
- }
- }
-
- TDiskBlobMergerWithMask m;
- m.SetFilterMask(partsToStore);
- for (ui8 i = 0; i < numParts; ++i) {
- if (mask1 >> i & 1) {
+ for (ui8 i = 0; i < numParts; ++i) {
+ if (mask2 >> i & 1) {
+ partsToStore.Set(i);
+ }
+ }
+
+ TDiskBlobMergerWithMask m;
+ m.SetFilterMask(partsToStore);
+ for (ui8 i = 0; i < numParts; ++i) {
+ if (mask1 >> i & 1) {
NMatrix::TVectorType v(0, numParts);
- v.Set(i);
- TRope buffer = TDiskBlob::Create(100, i + 1, numParts, TRope(Sprintf("%08x", i)), Arena);
- m.Add(TDiskBlob(&buffer, v, GType, TLogoBlobID(0, 0, 0, 0, 8, 0)));
- }
- }
-
- TDiskBlobMerger m2;
- for (ui8 i = 0; i < numParts; ++i) {
- if ((mask1 & mask2) >> i & 1) {
+ v.Set(i);
+ TRope buffer = TDiskBlob::Create(100, i + 1, numParts, TRope(Sprintf("%08x", i)), Arena);
+ m.Add(TDiskBlob(&buffer, v, GType, TLogoBlobID(0, 0, 0, 0, 8, 0)));
+ }
+ }
+
+ TDiskBlobMerger m2;
+ for (ui8 i = 0; i < numParts; ++i) {
+ if ((mask1 & mask2) >> i & 1) {
NMatrix::TVectorType v(0, numParts);
- v.Set(i);
- TRope buffer = TDiskBlob::Create(100, i + 1, numParts, TRope(Sprintf("%08x", i)), Arena);
- m2.Add(TDiskBlob(&buffer, v, GType, TLogoBlobID(0, 0, 0, 0, 8, 0)));
- }
- }
-
- UNIT_ASSERT_EQUAL(m.CreateDiskBlob(Arena), m2.CreateDiskBlob(Arena));
- }
- }
- }
+ v.Set(i);
+ TRope buffer = TDiskBlob::Create(100, i + 1, numParts, TRope(Sprintf("%08x", i)), Arena);
+ m2.Add(TDiskBlob(&buffer, v, GType, TLogoBlobID(0, 0, 0, 0, 8, 0)));
+ }
+ }
+
+ UNIT_ASSERT_EQUAL(m.CreateDiskBlob(Arena), m2.CreateDiskBlob(Arena));
+ }
+ }
+ }
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hulldefs.h b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hulldefs.h
index 4719a39e728..c4f1e6a1a82 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hulldefs.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hulldefs.h
@@ -14,16 +14,16 @@
// FIXME: only for TIngressCache (put it to vdisk/common)
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
#include <ydb/core/protos/blobstorage_vdisk_internal.pb.h>
-
+
namespace NKikimr {
template <class TKey>
TLogSignature PDiskSignatureForHullDbKey();
///////////////////////////////////////////////////////////////////////////////////////
- // TDiskDataExtractor
+ // TDiskDataExtractor
///////////////////////////////////////////////////////////////////////////////////////
- struct TDiskDataExtractor {
+ struct TDiskDataExtractor {
TBlobType::EType BlobType = TBlobType::DiskBlob;
const TDiskPart *Begin = nullptr;
const TDiskPart *End = nullptr;
@@ -103,11 +103,11 @@ namespace NKikimr {
// TMemPart
///////////////////////////////////////////////////////////////////////////////////////
struct TMemPart {
- ui64 BufferId;
+ ui64 BufferId;
ui32 Size;
- TMemPart(ui64 bufferId, ui32 size)
- : BufferId(bufferId)
+ TMemPart(ui64 bufferId, ui32 size)
+ : BufferId(bufferId)
, Size(size)
{}
};
@@ -155,7 +155,7 @@ namespace NKikimr {
TDuration hullCompStorageRatioCalcPeriod,
TDuration hullCompStorageRatioMaxCalcDuration)
: VCtx(std::move(vctx))
- , IngressCache(TIngressCache::Create(VCtx->Top, VCtx->ShortSelfVDisk))
+ , IngressCache(TIngressCache::Create(VCtx->Top, VCtx->ShortSelfVDisk))
, ChunkSize(chunkSize)
, CompWorthReadSize(compWorthReadSize)
, FreshCompaction(freshCompaction)
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
index 74ed554356b..7daa6435a9d 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_hullsatisfactionrank.cpp
@@ -51,13 +51,13 @@ namespace NKikimr {
const bool prevVal = StopPuts();
FreshRank.ApplyUpdates();
LevelRank.ApplyUpdates();
- std::unique_ptr<NPDisk::TEvConfigureScheduler> msg;
+ std::unique_ptr<NPDisk::TEvConfigureScheduler> msg;
TLinearTrackBar::TStatus status;
// fresh
status = FreshWeight.Update(FreshRank.GetRank());
if (status.Changed) {
if (!msg) {
- msg = std::make_unique<NPDisk::TEvConfigureScheduler>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound);
+ msg = std::make_unique<NPDisk::TEvConfigureScheduler>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound);
}
msg->SchedulerCfg.FreshWeight = status.Weight;
}
@@ -65,13 +65,13 @@ namespace NKikimr {
status = LevelWeight.Update(LevelRank.GetRank());
if (status.Changed) {
if (!msg) {
- msg = std::make_unique<NPDisk::TEvConfigureScheduler>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound);
+ msg = std::make_unique<NPDisk::TEvConfigureScheduler>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound);
}
msg->SchedulerCfg.CompWeight = status.Weight;
}
// send msg if any
if (msg) {
- ctx.Send(PDiskCtx->PDiskId, msg.release());
+ ctx.Send(PDiskCtx->PDiskId, msg.release());
LOG_DEBUG(ctx, BS_VDISK_OTHER,
VDISKP(VCtx->VDiskLogPrefix, "TDynamicPDiskWeightsManager: "
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.cpp b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.cpp
index b88dc277c2b..46046edff6b 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.cpp
@@ -45,7 +45,7 @@ str = endptr + 1;
return false;
}
- out = TKeyBarrier(tabletID, channel, gen, genCounter, false);
+ out = TKeyBarrier(tabletID, channel, gen, genCounter, false);
return true;
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h
index 4afce21c055..fb40f5298b0 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h
@@ -7,7 +7,7 @@
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h>
#include <ydb/core/protos/blobstorage.pb.h>
#include <library/cpp/actors/util/named_tuple.h>
-
+
namespace NKikimr {
// Data types for barrier database
@@ -16,13 +16,13 @@ namespace NKikimr {
// TKeyBarrier
/////////////////////////////////////////////////////////////////////////
#pragma pack(push, 4)
- struct TKeyBarrier
- : public TNamedTupleBase<TKeyBarrier>
- {
+ struct TKeyBarrier
+ : public TNamedTupleBase<TKeyBarrier>
+ {
ui64 TabletId;
- ui32 Channel : 8;
- ui32 Reserved : 23;
- ui32 Hard : 1;
+ ui32 Channel : 8;
+ ui32 Reserved : 23;
+ ui32 Hard : 1;
ui32 Gen; // generation of tablet the command was issued
ui32 GenCounter; // sequential number of command during tablet lifetime
@@ -33,26 +33,26 @@ namespace NKikimr {
TKeyBarrier()
: TabletId(0)
, Channel(0)
- , Reserved(0)
- , Hard(0)
- , Gen(0)
- , GenCounter(0)
- {}
-
- TKeyBarrier(ui64 tabletId)
- : TabletId(tabletId)
- , Channel(0)
- , Reserved(0)
- , Hard(0)
+ , Reserved(0)
+ , Hard(0)
, Gen(0)
, GenCounter(0)
{}
- TKeyBarrier(ui64 tabletId, ui32 channel, ui32 gen, ui32 genCounter, bool hard)
+ TKeyBarrier(ui64 tabletId)
+ : TabletId(tabletId)
+ , Channel(0)
+ , Reserved(0)
+ , Hard(0)
+ , Gen(0)
+ , GenCounter(0)
+ {}
+
+ TKeyBarrier(ui64 tabletId, ui32 channel, ui32 gen, ui32 genCounter, bool hard)
: TabletId(tabletId)
, Channel(channel)
- , Reserved(0)
- , Hard(hard)
+ , Reserved(0)
+ , Hard(hard)
, Gen(gen)
, GenCounter(genCounter)
{}
@@ -60,51 +60,51 @@ namespace NKikimr {
TKeyBarrier(const NKikimrBlobStorage::TBarrierKey &proto)
: TabletId(proto.GetTabletId())
, Channel(proto.GetChannel())
- , Reserved(0)
- , Hard(proto.GetHard())
+ , Reserved(0)
+ , Hard(proto.GetHard())
, Gen(proto.GetRecordGeneration())
, GenCounter(proto.GetPerGenerationCounter())
{}
TString ToString() const {
- return Sprintf("[%16" PRIu64 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %s]",
- TabletId, Channel, Gen, GenCounter, Hard ? "hard" : "soft");
+ return Sprintf("[%16" PRIu64 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %s]",
+ TabletId, Channel, Gen, GenCounter, Hard ? "hard" : "soft");
}
TLogoBlobID LogoBlobID() const {
return TLogoBlobID();
- }
-
+ }
+
void Serialize(NKikimrBlobStorage::TBarrierKey &proto) const {
proto.SetTabletId(TabletId);
proto.SetChannel(Channel);
proto.SetRecordGeneration(Gen);
proto.SetPerGenerationCounter(GenCounter);
- proto.SetHard(Hard);
+ proto.SetHard(Hard);
}
static TKeyBarrier First() {
- return TKeyBarrier();
- }
-
- bool IsSameAs(const TKeyBarrier& other) const {
- return TabletId == other.TabletId
- && Channel == other.Channel
- && Gen == other.Gen
- && GenCounter == other.GenCounter
- && Hard == other.Hard;
+ return TKeyBarrier();
}
+ bool IsSameAs(const TKeyBarrier& other) const {
+ return TabletId == other.TabletId
+ && Channel == other.Channel
+ && Gen == other.Gen
+ && GenCounter == other.GenCounter
+ && Hard == other.Hard;
+ }
+
static TKeyBarrier Inf() {
- return TKeyBarrier(Max<ui64>(), Max<ui32>(), Max<ui32>(), Max<ui32>(), true);
+ return TKeyBarrier(Max<ui64>(), Max<ui32>(), Max<ui32>(), Max<ui32>(), true);
}
static bool Parse(TKeyBarrier &out, const TString &buf, TString &errorExplanation);
-
- auto ConvertToTuple() const {
- return std::make_tuple(TabletId, Channel, Hard, Gen, GenCounter);
- }
+
+ auto ConvertToTuple() const {
+ return std::make_tuple(TabletId, Channel, Hard, Gen, GenCounter);
+ }
};
#pragma pack(pop)
@@ -137,11 +137,11 @@ namespace NKikimr {
, Ingress(ingress)
{}
- void Merge(const TMemRecBarrier& rec, const TKeyBarrier& key) {
+ void Merge(const TMemRecBarrier& rec, const TKeyBarrier& key) {
Y_VERIFY(CollectGen == rec.CollectGen && CollectStep == rec.CollectStep,
"Barriers MUST be equal; CollectGen# %" PRIu32 " CollectStep# %" PRIu32
- " rec.CollectGen# %" PRIu32 " rec.CollectStep %" PRIu32
- " key# %s", CollectGen, CollectStep, rec.CollectGen, rec.CollectStep,
+ " rec.CollectGen# %" PRIu32 " rec.CollectStep %" PRIu32
+ " key# %s", CollectGen, CollectStep, rec.CollectGen, rec.CollectStep,
key.ToString().data());
TBarrierIngress::Merge(Ingress, rec.Ingress);
}
@@ -167,7 +167,7 @@ namespace NKikimr {
Y_FAIL("Must not be called");
}
- void SetMemBlob(ui64, ui32) {
+ void SetMemBlob(ui64, ui32) {
Y_FAIL("Must not be called");
}
@@ -179,7 +179,7 @@ namespace NKikimr {
Y_UNUSED(t);
}
- TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *) const {
+ TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *) const {
extr->Clear();
return extr;
}
@@ -188,13 +188,13 @@ namespace NKikimr {
Y_FAIL("Must not be called");
}
- NMatrix::TVectorType GetLocalParts(TBlobStorageGroupType) const {
+ NMatrix::TVectorType GetLocalParts(TBlobStorageGroupType) const {
return NMatrix::TVectorType();
}
- void ClearLocalParts(TBlobStorageGroupType)
- {}
-
+ void ClearLocalParts(TBlobStorageGroupType)
+ {}
+
TBlobType::EType GetType() const {
return TBlobType::DiskBlob;
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier_ut.cpp
index 644c9290a86..4461026a930 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier_ut.cpp
@@ -12,11 +12,11 @@ namespace NKikimr {
bool res = false;
res = TKeyBarrier::Parse(id, "[ 0:0:34:15]", explanation);
- expected = TKeyBarrier(0, 0, 34, 15, false);
+ expected = TKeyBarrier(0, 0, 34, 15, false);
UNIT_ASSERT(res && id == expected);
res = TKeyBarrier::Parse(id, "[ABC:0:34:15 ]", explanation);
- expected = TKeyBarrier(0xABC, 0, 34, 15, false);
+ expected = TKeyBarrier(0xABC, 0, 34, 15, false);
UNIT_ASSERT(res && id == expected);
res = TKeyBarrier::Parse(id, "[ABC:0:34:15 ", explanation);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h
index 72e38257f2a..01e772c743d 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h
@@ -36,15 +36,15 @@ namespace NKikimr {
TLogoBlobID LogoBlobID() const {
return TLogoBlobID();
- }
-
+ }
+
static TKeyBlock First() {
return TKeyBlock();
}
-
- bool IsSameAs(const TKeyBlock& other) const {
- return TabletId == other.TabletId;
- }
+
+ bool IsSameAs(const TKeyBlock& other) const {
+ return TabletId == other.TabletId;
+ }
};
#pragma pack(pop)
@@ -91,7 +91,7 @@ namespace NKikimr {
: BlockedGeneration(blockGen)
{}
- void Merge(const TMemRecBlock& rec, const TKeyBlock& /*key*/) {
+ void Merge(const TMemRecBlock& rec, const TKeyBlock& /*key*/) {
BlockedGeneration = Max(BlockedGeneration, rec.BlockedGeneration);
}
@@ -116,7 +116,7 @@ namespace NKikimr {
Y_FAIL("Must not be called");
}
- void SetMemBlob(ui64, ui32) {
+ void SetMemBlob(ui64, ui32) {
Y_FAIL("Must not be called");
}
@@ -128,7 +128,7 @@ namespace NKikimr {
Y_UNUSED(t);
}
- TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *) const {
+ TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *) const {
extr->Clear();
return extr;
}
@@ -137,13 +137,13 @@ namespace NKikimr {
Y_FAIL("Must not be called");
}
- NMatrix::TVectorType GetLocalParts(TBlobStorageGroupType) const {
+ NMatrix::TVectorType GetLocalParts(TBlobStorageGroupType) const {
return NMatrix::TVectorType();
}
- void ClearLocalParts(TBlobStorageGroupType)
- {}
-
+ void ClearLocalParts(TBlobStorageGroupType)
+ {}
+
TBlobType::EType GetType() const {
return TBlobType::DiskBlob;
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h
index 95d32d80f4c..28797390665 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h
@@ -44,16 +44,16 @@ namespace NKikimr {
static TKeyLogoBlob First() {
return TKeyLogoBlob();
}
-
- bool IsSameAs(const TKeyLogoBlob& other) const {
- TLogoBlobID x(LogoBlobID());
- TLogoBlobID y(other.LogoBlobID());
- return x.TabletID() == y.TabletID()
- && x.Channel() == y.Channel()
- && x.Generation() == y.Generation()
- && x.Step() == y.Step()
- && x.Cookie() == y.Cookie();
- }
+
+ bool IsSameAs(const TKeyLogoBlob& other) const {
+ TLogoBlobID x(LogoBlobID());
+ TLogoBlobID y(other.LogoBlobID());
+ return x.TabletID() == y.TabletID()
+ && x.Channel() == y.Channel()
+ && x.Generation() == y.Generation()
+ && x.Step() == y.Step()
+ && x.Cookie() == y.Cookie();
+ }
};
#pragma pack(pop)
@@ -69,10 +69,10 @@ namespace NKikimr {
return x.LogoBlobID() == y.LogoBlobID();
}
- inline bool operator !=(const TKeyLogoBlob &x, const TKeyLogoBlob &y) {
- return x.LogoBlobID() != y.LogoBlobID();
- }
-
+ inline bool operator !=(const TKeyLogoBlob &x, const TKeyLogoBlob &y) {
+ return x.LogoBlobID() != y.LogoBlobID();
+ }
+
inline bool operator <=(const TKeyLogoBlob &x, const TKeyLogoBlob &y) {
return x.LogoBlobID() <= y.LogoBlobID();
}
@@ -120,7 +120,7 @@ namespace NKikimr {
ClearData();
}
- void Merge(const TMemRecLogoBlob& rec, const TKeyLogoBlob& /*key*/) {
+ void Merge(const TMemRecLogoBlob& rec, const TKeyLogoBlob& /*key*/) {
TIngress::Merge(Ingress, rec.Ingress);
}
@@ -130,7 +130,7 @@ namespace NKikimr {
bool HasData() const {
TBlobType::EType t = GetType();
- return t == TBlobType::HugeBlob || t == TBlobType::ManyHugeBlobs || Size;
+ return t == TBlobType::HugeBlob || t == TBlobType::ManyHugeBlobs || Size;
}
void SetDiskBlob(const TDiskPart &dataAddr) {
@@ -147,18 +147,18 @@ namespace NKikimr {
Size = dataAddr.Size;
}
- void SetManyHugeBlobs(ui32 idx, ui32 num, ui32 size) {
- Type = TBlobType::ManyHugeBlobs;
+ void SetManyHugeBlobs(ui32 idx, ui32 num, ui32 size) {
+ Type = TBlobType::ManyHugeBlobs;
Id = idx;
Offset = num;
- Size = size;
+ Size = size;
}
- void SetMemBlob(ui64 id, ui32 size) {
+ void SetMemBlob(ui64 id, ui32 size) {
Type = TBlobType::MemBlob;
- Y_VERIFY(id < (ui64(1) << 62));
- Id = id >> 32;
- Offset = id;
+ Y_VERIFY(id < (ui64(1) << 62));
+ Id = id >> 32;
+ Offset = id;
Size = size;
}
@@ -171,7 +171,7 @@ namespace NKikimr {
Type = t;
}
- TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *outbound) const {
+ TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr, const TDiskPart *outbound) const {
TBlobType::EType t = GetType();
if (t == TBlobType::DiskBlob || t == TBlobType::HugeBlob) {
extr->Set(t, TDiskPart(Id, Offset, Size));
@@ -185,7 +185,7 @@ namespace NKikimr {
TMemPart GetMemData() const {
Y_VERIFY_DEBUG(GetType() == TBlobType::MemBlob);
- return TMemPart(ui64(Id) << 32 | Offset, Size);
+ return TMemPart(ui64(Id) << 32 | Offset, Size);
}
const TIngress &GetIngress() const {
@@ -202,18 +202,18 @@ namespace NKikimr {
void ClearLocalParts(const TBlobStorageGroupType &gtype) {
Ingress = Ingress.CopyWithoutLocal(gtype);
- }
-
+ }
+
TString ToString(const TIngressCache *cache, const TDiskPart *outbound) const {
Y_UNUSED(cache);
TStringStream str;
TBlobType::EType t = GetType();
- str << "{" << TBlobType::TypeToStr(t) << " " << CollectMode2String(Ingress.GetCollectMode(
- TIngress::IngressMode(cache->Topology->GType)));
+ str << "{" << TBlobType::TypeToStr(t) << " " << CollectMode2String(Ingress.GetCollectMode(
+ TIngress::IngressMode(cache->Topology->GType)));
if (t == TBlobType::MemBlob) {
// nothing
} else {
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
GetDiskData(&extr, outbound);
str << " " << extr.ToString();
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h
index 687e1a4ba00..4ae054bb957 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h
@@ -1,30 +1,30 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <library/cpp/actors/util/rope.h>
-
-#include <util/thread/lfstack.h>
-#include <util/system/filemap.h>
-
-namespace NKikimr {
-
- class TRopeArenaBackend : public IRopeChunkBackend {
- static constexpr size_t Capacity = 2 * 1024 * 1024 - 4096 /* lfalloc overhead */ - sizeof(IRopeChunkBackend);
- char Data[Capacity];
-
- public:
- TData GetData() const override {
- return {Data, Capacity};
- }
-
- size_t GetCapacity() const override {
- return Capacity;
- }
-
- static TIntrusivePtr<IRopeChunkBackend> Allocate() {
- return MakeIntrusive<TRopeArenaBackend>();
- }
- };
-
-}
+
+#include <util/thread/lfstack.h>
+#include <util/system/filemap.h>
+
+namespace NKikimr {
+
+ class TRopeArenaBackend : public IRopeChunkBackend {
+ static constexpr size_t Capacity = 2 * 1024 * 1024 - 4096 /* lfalloc overhead */ - sizeof(IRopeChunkBackend);
+ char Data[Capacity];
+
+ public:
+ TData GetData() const override {
+ return {Data, Capacity};
+ }
+
+ size_t GetCapacity() const override {
+ return Capacity;
+ }
+
+ static TIntrusivePtr<IRopeChunkBackend> Allocate() {
+ return MakeIntrusive<TRopeArenaBackend>();
+ }
+ };
+
+}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_generic_it.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_generic_it.h
index 204aaec7e7b..10fcebcf8ad 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_generic_it.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_generic_it.h
@@ -172,7 +172,7 @@ namespace NKikimr {
template <class TKey, class TIter, class TRecordMerger, class TPQueue>
void PutToMerger(TRecordMerger *merger, TPQueue &pqueue) {
- using TIterPtr = std::shared_ptr<TIter>;
+ using TIterPtr = std::shared_ptr<TIter>;
Y_VERIFY_DEBUG(!pqueue.empty());
TStackVec<TIterPtr, 32> tmp;
TIterPtr it = pqueue.top();
@@ -193,7 +193,7 @@ namespace NKikimr {
template <class TKey, class TIter, class TPQueue>
TString ToString(TPQueue &pqueue) {
- using TIterPtr = std::shared_ptr<TIter>;
+ using TIterPtr = std::shared_ptr<TIter>;
TStringStream str;
Y_VERIFY_DEBUG(!pqueue.empty());
TStackVec<TIterPtr, 32> tmp;
@@ -218,16 +218,16 @@ namespace NKikimr {
template <class TPQueue, class TIter>
void Copy(
- TVector<std::shared_ptr<TIter>> &dstIters,
+ TVector<std::shared_ptr<TIter>> &dstIters,
TPQueue &dstPQueue,
- const TVector<std::shared_ptr<TIter>> &srcIters)
+ const TVector<std::shared_ptr<TIter>> &srcIters)
{
// copy iterators
dstIters.clear();
dstPQueue.clear();
dstIters.reserve(srcIters.size());
for (const auto &x : srcIters) {
- dstIters.push_back(std::make_shared<TIter>(*x));
+ dstIters.push_back(std::make_shared<TIter>(*x));
}
// set up PQueue
for (auto &x : dstIters) {
@@ -259,7 +259,7 @@ namespace NKikimr {
Iters.reserve(elements.size());
for (const auto &x : elements) {
if (!x->Empty()) {
- Iters.push_back(std::make_shared<TIter>(hullCtx, x));
+ Iters.push_back(std::make_shared<TIter>(hullCtx, x));
}
}
}
@@ -322,7 +322,7 @@ namespace NKikimr {
}
protected:
- using TIterPtr = std::shared_ptr<TIter>;
+ using TIterPtr = std::shared_ptr<TIter>;
class TGreater {
public:
bool operator () (const TIterPtr &c1, const TIterPtr &c2) const {
@@ -355,7 +355,7 @@ namespace NKikimr {
Iters.reserve(elements.size());
for (const auto &x : elements) {
if (!x->Empty()) {
- Iters.push_back(std::make_shared<TIter>(hullCtx, x));
+ Iters.push_back(std::make_shared<TIter>(hullCtx, x));
}
}
}
@@ -419,7 +419,7 @@ namespace NKikimr {
}
protected:
- using TIterPtr = std::shared_ptr<TIter>;
+ using TIterPtr = std::shared_ptr<TIter>;
class TLess {
public:
bool operator () (const TIterPtr &c1, const TIterPtr &c2) const {
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_glue.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_glue.h
index 4328a9cca30..ce01dd2e66c 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_glue.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_glue.h
@@ -57,22 +57,22 @@ namespace NKikimr {
void Output(IOutputStream &str) const {
str << "[" << (IsCreatedByRepl() ? "REPL" : "COMP") << " CTime# "<< CTime << "]";
}
-
- friend bool operator ==(const TInfo& x, const TInfo& y) {
- return x.FirstLsn == y.FirstLsn &&
- x.LastLsn == y.LastLsn &&
- x.InplaceDataTotalSize == y.InplaceDataTotalSize &&
- x.HugeDataTotalSize == y.HugeDataTotalSize &&
- x.IdxTotalSize == y.IdxTotalSize &&
- x.Chunks == y.Chunks &&
- x.IndexParts == y.IndexParts &&
- x.Items == y.Items &&
- x.ItemsWithInplacedData == y.ItemsWithInplacedData &&
- x.ItemsWithHugeData == y.ItemsWithHugeData &&
- x.OutboundItems == y.OutboundItems &&
- x.Flags == y.Flags &&
- x.CTime == y.CTime;
- }
+
+ friend bool operator ==(const TInfo& x, const TInfo& y) {
+ return x.FirstLsn == y.FirstLsn &&
+ x.LastLsn == y.LastLsn &&
+ x.InplaceDataTotalSize == y.InplaceDataTotalSize &&
+ x.HugeDataTotalSize == y.HugeDataTotalSize &&
+ x.IdxTotalSize == y.IdxTotalSize &&
+ x.Chunks == y.Chunks &&
+ x.IndexParts == y.IndexParts &&
+ x.Items == y.Items &&
+ x.ItemsWithInplacedData == y.ItemsWithInplacedData &&
+ x.ItemsWithHugeData == y.ItemsWithHugeData &&
+ x.OutboundItems == y.OutboundItems &&
+ x.Flags == y.Flags &&
+ x.CTime == y.CTime;
+ }
};
ui32 MagicNumber;
@@ -88,13 +88,13 @@ namespace NKikimr {
{
Y_VERIFY_DEBUG(PrevPart.Empty());
}
-
- friend bool operator ==(const TIdxDiskPlaceHolder& x, const TIdxDiskPlaceHolder& y) {
- return x.MagicNumber == y.MagicNumber &&
- x.PrevPart == y.PrevPart &&
- x.SstId == y.SstId &&
- x.Info == y.Info;
- }
+
+ friend bool operator ==(const TIdxDiskPlaceHolder& x, const TIdxDiskPlaceHolder& y) {
+ return x.MagicNumber == y.MagicNumber &&
+ x.PrevPart == y.PrevPart &&
+ x.SstId == y.SstId &&
+ x.Info == y.Info;
+ }
};
/////////////////////////////////////////////////////////////////////////
@@ -110,10 +110,10 @@ namespace NKikimr {
TIdxDiskLinker(const TDiskPart &part)
: PrevPart(part)
{}
-
- friend bool operator ==(const TIdxDiskLinker& x, const TIdxDiskLinker& y) {
- return x.PrevPart == y.PrevPart;
- }
+
+ friend bool operator ==(const TIdxDiskLinker& x, const TIdxDiskLinker& y) {
+ return x.PrevPart == y.PrevPart;
+ }
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_ut.h b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_ut.h
index b0d875a060c..2b31439ec7f 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/base/hullds_ut.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/base/hullds_ut.h
@@ -12,7 +12,7 @@ namespace NKikimr {
: ChunkSize(chunkSize)
, CompWorthReadSize(compWorthReadSize)
, GroupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4)
- , VCtx(new TVDiskContext(TActorId(), GroupInfo.PickTopology(), new NMonitoring::TDynamicCounters(),
+ , VCtx(new TVDiskContext(TActorId(), GroupInfo.PickTopology(), new NMonitoring::TDynamicCounters(),
TVDiskID(), nullptr, TPDiskCategory::DEVICE_TYPE_UNKNOWN))
, HullCtx(
new THullCtx(
diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_defs.h b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_defs.h
index 8d5bd560293..6420b95e0ad 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_defs.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_defs.h
@@ -163,14 +163,14 @@ namespace NKikimr {
void FindHugeBlobsForRemoval(const TLevelSegment *seg) {
typename TLevelSegment::TMemIterator it(seg);
it.SeekToFirst();
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
while (it.Valid()) {
it.GetDiskData(&extr);
- if (extr.BlobType == TBlobType::HugeBlob || extr.BlobType == TBlobType::ManyHugeBlobs) {
+ if (extr.BlobType == TBlobType::HugeBlob || extr.BlobType == TBlobType::ManyHugeBlobs) {
for (const TDiskPart *part = extr.Begin; part < extr.End; ++part) {
- if (!part->Empty()) {
- HugeBlobsToDelete.PushBack(*part);
- }
+ if (!part->Empty()) {
+ HugeBlobsToDelete.PushBack(*part);
+ }
}
}
extr.Clear();
diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h
index fe2a48fc9ef..22da12b1211 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_ratio.h
@@ -46,7 +46,7 @@ namespace NKikimr {
(finishTime - startTime).ToString().data(), stat.ToString().data()));
}
- BarriersEssence.Reset();
+ BarriersEssence.Reset();
}
private:
@@ -122,8 +122,8 @@ namespace NKikimr {
break;
}
}
-
- BarriersEssence.Reset();
+
+ BarriersEssence.Reset();
}
TSstRatioPtr CalculateSstRatio(TLevelSegmentPtr sst, TInstant now) {
@@ -147,7 +147,7 @@ namespace NKikimr {
const TIndexRecordMerger &dbMerger) {
Y_UNUSED(subsIt);
Y_UNUSED(subsMerger);
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
subsIt.GetDiskData(&extr);
// calculate item's parameters
const ui64 indexItemByteSize = sizeof(TKey) + sizeof(TMemRec);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h
index f269d15b952..99425d38f9a 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/compstrat/hulldb_compstrat_selector.h
@@ -65,11 +65,11 @@ namespace NKikimr {
typedef ::NKikimr::NHullComp::TTask<TKey, TMemRec> TCompactionTask;
const NHullComp::EAction Action;
- std::unique_ptr<TCompactionTask> CompactionTask;
+ std::unique_ptr<TCompactionTask> CompactionTask;
- TSelected(NHullComp::EAction action, std::unique_ptr<TCompactionTask> compactionTask)
+ TSelected(NHullComp::EAction action, std::unique_ptr<TCompactionTask> compactionTask)
: Action(action)
- , CompactionTask(std::move(compactionTask))
+ , CompactionTask(std::move(compactionTask))
{}
};
@@ -94,15 +94,15 @@ namespace NKikimr {
TLevelIndexSnapshot LevelSnap;
TBarriersSnapshot BarriersSnap;
const TActorId RecipientID;
- std::unique_ptr<TCompactionTask> CompactionTask;
+ std::unique_ptr<TCompactionTask> CompactionTask;
void Bootstrap(const TActorContext &ctx) {
TInstant startTime(TAppData::TimeProvider->Now());
TStrategy strategy(HullCtx, Params, std::move(LevelSnap), std::move(BarriersSnap),
- CompactionTask.get());
+ CompactionTask.get());
NHullComp::EAction action = strategy.Select();
- ctx.Send(RecipientID, new TSelected(action, std::move(CompactionTask)));
+ ctx.Send(RecipientID, new TSelected(action, std::move(CompactionTask)));
TInstant finishTime(TAppData::TimeProvider->Now());
LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP,
@@ -114,8 +114,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULLCOMP_SELECTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULLCOMP_SELECTOR;
}
TSelectorActor(
@@ -124,14 +124,14 @@ namespace NKikimr {
TLevelIndexSnapshot &&levelSnap,
TBarriersSnapshot &&barriersSnap,
const TActorId &recipientID,
- std::unique_ptr<TCompactionTask> compactionTask)
+ std::unique_ptr<TCompactionTask> compactionTask)
: TActorBootstrapped<TThis>()
, HullCtx(hullCtx)
, Params(params)
, LevelSnap(std::move(levelSnap))
, BarriersSnap(std::move(barriersSnap))
, RecipientID(recipientID)
- , CompactionTask(std::move(compactionTask))
+ , CompactionTask(std::move(compactionTask))
{}
};
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.cpp
index d44ff95d7ea..d34ab198747 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.cpp
@@ -1,17 +1,17 @@
-#include "fresh_appendix.h"
-
-namespace NKikimr {
-
- template class TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshAppendix<TKeyBarrier, TMemRecBarrier>;
- template class TFreshAppendix<TKeyBlock, TMemRecBlock>;
-
- template class TFreshAppendixTreeSnap<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshAppendixTreeSnap<TKeyBarrier, TMemRecBarrier>;
- template class TFreshAppendixTreeSnap<TKeyBlock, TMemRecBlock>;
-
- template class TFreshAppendixTree<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshAppendixTree<TKeyBarrier, TMemRecBarrier>;
- template class TFreshAppendixTree<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "fresh_appendix.h"
+
+namespace NKikimr {
+
+ template class TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshAppendix<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshAppendix<TKeyBlock, TMemRecBlock>;
+
+ template class TFreshAppendixTreeSnap<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshAppendixTreeSnap<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshAppendixTreeSnap<TKeyBlock, TMemRecBlock>;
+
+ template class TFreshAppendixTree<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshAppendixTree<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshAppendixTree<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.h
index a4da075ad42..b512d8be5e9 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix.h
@@ -32,8 +32,8 @@ namespace NKikimr {
return Key < rec.Key;
}
- bool operator ==(const TRecord &rec) const {
- return Key == rec.Key;
+ bool operator ==(const TRecord &rec) const {
+ return Key == rec.Key;
}
TRecord(const TKey &key, const TMemRec &memRec)
@@ -87,9 +87,9 @@ namespace NKikimr {
return MemConsumed.GetCounter();
}
- static std::shared_ptr<TFreshAppendix> Merge(
+ static std::shared_ptr<TFreshAppendix> Merge(
const THullCtxPtr &hullCtx,
- const TVector<std::shared_ptr<TFreshAppendix>> &v);
+ const TVector<std::shared_ptr<TFreshAppendix>> &v);
class TIterator;
@@ -100,10 +100,10 @@ namespace NKikimr {
using TVecIterator = typename TVec::iterator;
};
- extern template class TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshAppendix<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshAppendix<TKeyBlock, TMemRecBlock>;
-
+ extern template class TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshAppendix<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshAppendix<TKeyBlock, TMemRecBlock>;
+
/////////////////////////////////////////////////////////////////////////////////////////
// TFreshAppendix::TIterator
/////////////////////////////////////////////////////////////////////////////////////////
@@ -170,9 +170,9 @@ namespace NKikimr {
// TFreshAppendix -- merge segments
/////////////////////////////////////////////////////////////////////////////////////////
template <class TKey, class TMemRec>
- std::shared_ptr<TFreshAppendix<TKey, TMemRec>> TFreshAppendix<TKey, TMemRec>::Merge(
+ std::shared_ptr<TFreshAppendix<TKey, TMemRec>> TFreshAppendix<TKey, TMemRec>::Merge(
const THullCtxPtr &hullCtx,
- const TVector<std::shared_ptr<TFreshAppendix<TKey, TMemRec>>> &v)
+ const TVector<std::shared_ptr<TFreshAppendix<TKey, TMemRec>>> &v)
{
using TFreshAppendix = ::NKikimr::TFreshAppendix<TKey, TMemRec>;
using TAppendixIterator = typename TFreshAppendix::TIterator;
@@ -182,7 +182,7 @@ namespace NKikimr {
input.reserve(v.size());
size_t reserve = 0;
for (auto &x : v) {
- input.push_back(x.get());
+ input.push_back(x.get());
reserve += x->GetSize();
}
typename TFreshAppendix::TVec vec;
@@ -200,7 +200,7 @@ namespace NKikimr {
merger.Clear();
}
- return std::make_shared<TFreshAppendix>(std::move(vec), TMemoryConsumer(input[0]->GetCounter()), true);
+ return std::make_shared<TFreshAppendix>(std::move(vec), TMemoryConsumer(input[0]->GetCounter()), true);
}
@@ -214,7 +214,7 @@ namespace NKikimr {
class TFreshAppendixTreeSnap {
private:
using TAppendix = ::NKikimr::TFreshAppendix<TKey, TMemRec>;
- using TAppendixPtr = std::shared_ptr<TAppendix>;
+ using TAppendixPtr = std::shared_ptr<TAppendix>;
using TTree = TSTree<TAppendix, THullCtxPtr>;
using TTreeSnap = TSTreeSnap<TAppendix, THullCtxPtr>;
friend class TFreshAppendixTree<TKey, TMemRec>;
@@ -250,10 +250,10 @@ namespace NKikimr {
};
};
- extern template class TFreshAppendixTreeSnap<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshAppendixTreeSnap<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshAppendixTreeSnap<TKeyBlock, TMemRecBlock>;
-
+ extern template class TFreshAppendixTreeSnap<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshAppendixTreeSnap<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshAppendixTreeSnap<TKeyBlock, TMemRecBlock>;
+
/////////////////////////////////////////////////////////////////////////////////////////
// TFreshAppendixTree -- several TFreshAppendix
/////////////////////////////////////////////////////////////////////////////////////////
@@ -261,7 +261,7 @@ namespace NKikimr {
class TFreshAppendixTree {
private:
using TAppendix = ::NKikimr::TFreshAppendix<TKey, TMemRec>;
- using TAppendixPtr = std::shared_ptr<TAppendix>;
+ using TAppendixPtr = std::shared_ptr<TAppendix>;
using TTree = TSTree<TAppendix, THullCtxPtr>;
using TTreeSnap = TSTreeSnap<TAppendix, THullCtxPtr>;
@@ -305,11 +305,11 @@ namespace NKikimr {
return TFreshAppendixTreeSnap<TKey, TMemRec>(Tree.GetSnapshot());
}
- std::shared_ptr<ISTreeCompaction> Compact() {
+ std::shared_ptr<ISTreeCompaction> Compact() {
return Tree.Compact();
}
- std::shared_ptr<ISTreeCompaction> ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
+ std::shared_ptr<ISTreeCompaction> ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
return Tree.ApplyCompactionResult(cjob);
}
@@ -348,10 +348,10 @@ namespace NKikimr {
}
};
- extern template class TFreshAppendixTree<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshAppendixTree<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshAppendixTree<TKeyBlock, TMemRecBlock>;
-
+ extern template class TFreshAppendixTree<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshAppendixTree<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshAppendixTree<TKeyBlock, TMemRecBlock>;
+
/////////////////////////////////////////////////////////////////////////////////////////
// TFreshAppendixTreeSnap::TPrivateIteratorBase
// Base class for TFreshAppendixTreeSnap iterators
@@ -379,7 +379,7 @@ namespace NKikimr {
typename TSnap::TTreeSnap::TIterator it(&snap->Snap);
it.SeekToFirst();
while (it.Valid()) {
- result.push_back(it.Get().get());
+ result.push_back(it.Get().get());
it.Next();
}
return result;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix_ut.cpp
index 144cc818c6c..651c0d0e5f6 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_appendix_ut.cpp
@@ -13,10 +13,10 @@ namespace NKikimr {
static NMonitoring::TDynamicCounters DynCounters;
- std::shared_ptr<TFreshAppendix<int, int>> CreateAppendix(const TVector<int> &v) {
+ std::shared_ptr<TFreshAppendix<int, int>> CreateAppendix(const TVector<int> &v) {
auto group = DynCounters.GetSubgroup("subsystem", "memhull");
TMemoryConsumer memConsumer(group->GetCounter("MemTotal:FreshIndex"));
- auto result = std::make_shared<TFreshAppendix<int, int>>(memConsumer);
+ auto result = std::make_shared<TFreshAppendix<int, int>>(memConsumer);
for (const auto &x : v) {
result->Add(x, 0);
}
@@ -25,8 +25,8 @@ namespace NKikimr {
// add appendix to the tree and track lsns
void AddAppendix(
- std::shared_ptr<TFreshAppendixTree<int, int>> c,
- std::shared_ptr<TFreshAppendix<int, int>> a,
+ std::shared_ptr<TFreshAppendixTree<int, int>> c,
+ std::shared_ptr<TFreshAppendix<int, int>> a,
ui64 &curLsn) {
ui64 firstLsn = curLsn;
ui64 lastLsn = curLsn + a->GetSize() - 1;
@@ -40,7 +40,7 @@ namespace NKikimr {
auto a3 = CreateAppendix(TVector{7, 80, 90, 98, 102, 600});
const size_t stagingCapacity = 4;
- auto c = std::make_shared<TFreshAppendixTree<int, int>>(nullptr, stagingCapacity);
+ auto c = std::make_shared<TFreshAppendixTree<int, int>>(nullptr, stagingCapacity);
ui64 lsn = 1;
AddAppendix(c, a1, lsn);
AddAppendix(c, a2, lsn);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.cpp
index e9c22ee893a..1a30daa82db 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.cpp
@@ -1,9 +1,9 @@
-#include "fresh_data.h"
-
-namespace NKikimr {
-
- template class TFreshData<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshData<TKeyBarrier, TMemRecBarrier>;
- template class TFreshData<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "fresh_data.h"
+
+namespace NKikimr {
+
+ template class TFreshData<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshData<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshData<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.h
index d751e63d1b5..2d692377908 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data.h
@@ -31,7 +31,7 @@ namespace NKikimr {
ui64 OldSegLastKeepLsn = ui64(-1);
bool WaitForCommit = false;
const bool UseDreg;
- std::shared_ptr<TRopeArena> Arena;
+ std::shared_ptr<TRopeArena> Arena;
static constexpr ui64 CalculateBufLowWatermark(ui32 chunkSize, bool useDreg) {
return ui64(chunkSize) * (2u + !!useDreg);
@@ -39,20 +39,20 @@ namespace NKikimr {
public:
TFreshData(const TLevelIndexSettings &s, const TIntrusivePtr<ITimeProvider> &tp,
- std::shared_ptr<TRopeArena> arena)
+ std::shared_ptr<TRopeArena> arena)
: HullCtx(s.HullCtx)
, TimeProvider(tp)
, CompThreshold(s.CompThreshold)
, Cur(new TFreshSegment(HullCtx, s.CompThreshold, tp->Now(), arena))
, UseDreg(s.FreshUseDreg)
- , Arena(std::move(arena))
+ , Arena(std::move(arena))
{}
// Puts
void Put(ui64 lsn, const TKey &key, const TMemRec &memRec);
void PutLogoBlobWithData(ui64 lsn, const TKey &key, ui8 partId, const TIngress &ingress, TRope buffer);
- void PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn);
-
+ void PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn);
+
// Compaction
bool NeedsCompaction(ui64 yardFreeUpToLsn) const;
TIntrusivePtr<TFreshSegment> FindSegmentForCompaction();
@@ -103,7 +103,7 @@ namespace NKikimr {
}
template <class TKey, class TMemRec>
- void TFreshData<TKey, TMemRec>::PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
+ void TFreshData<TKey, TMemRec>::PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
Y_VERIFY_DEBUG(lastLsn >= firstLsn);
Cur->PutAppendix(std::move(a), firstLsn, lastLsn);
SwapWithDregIfRequired();
@@ -132,7 +132,7 @@ namespace NKikimr {
}
OldSegLastKeepLsn = Old->GetFirstLsnToKeep();
- Cur = MakeIntrusive<TFreshSegment>(HullCtx, CompThreshold, TimeProvider->Now(), Arena);
+ Cur = MakeIntrusive<TFreshSegment>(HullCtx, CompThreshold, TimeProvider->Now(), Arena);
return Old;
}
@@ -225,13 +225,13 @@ namespace NKikimr {
const bool renewCur = UseDreg && !Dreg && Cur->NeedsCompactionBySize();
if (renewCur) {
Dreg.Swap(Cur);
- Cur = MakeIntrusive<TFreshSegment>(HullCtx, CompThreshold, TimeProvider->Now(), Arena);
+ Cur = MakeIntrusive<TFreshSegment>(HullCtx, CompThreshold, TimeProvider->Now(), Arena);
}
}
- extern template class TFreshData<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshData<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshData<TKeyBlock, TMemRecBlock>;
-
+ extern template class TFreshData<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshData<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshData<TKeyBlock, TMemRecBlock>;
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data_ut.cpp
index 061f2b71ed8..1a79e1f02c8 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_data_ut.cpp
@@ -12,15 +12,15 @@
namespace NKikimr {
- static std::shared_ptr<TRopeArena> Arena = std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate);
-
+ static std::shared_ptr<TRopeArena> Arena = std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate);
+
Y_UNIT_TEST_SUITE(TBlobStorageHullFresh) {
////////////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////////////
typedef TFreshData<TKeyLogoBlob, TMemRecLogoBlob> TFreshData;
- typedef std::shared_ptr<TFreshData> TFreshDataPtr;
+ typedef std::shared_ptr<TFreshData> TFreshDataPtr;
static const ui32 ChunkSize = 8u << 20u;
static const ui32 Level0MaxSstsAtOnce = 8u;
static const ui32 BufSize = 64u << 20u;
@@ -51,27 +51,27 @@ namespace NKikimr {
TMemRecLogoBlob MemRec3;
TFreshDataPtr Fresh;
- std::unique_ptr<TFreshData::TFreshDataSnapshot> Snap3;
- std::unique_ptr<TFreshData::TFreshDataSnapshot> Snap10;
+ std::unique_ptr<TFreshData::TFreshDataSnapshot> Snap3;
+ std::unique_ptr<TFreshData::TFreshDataSnapshot> Snap10;
TDatasetSimple() {
LogoBlob1 = TLogoBlobID(0, 1, 1, 0, sizeof(Data), 0, 1);
LogoBlob2 = TLogoBlobID(0, 1, 2, 0, sizeof(Data), 0, 1);
LogoBlob3 = TLogoBlobID(0, 2, 1, 0, sizeof(Data), 0, 1);
- Fresh = std::make_shared<TFreshData>(GetLevelIndexSetting(), CreateDefaultTimeProvider(), Arena);
+ Fresh = std::make_shared<TFreshData>(GetLevelIndexSetting(), CreateDefaultTimeProvider(), Arena);
// several puts
PutToFresh(1, LogoBlob1);
PutToFresh(2, LogoBlob2);
PutToFresh(3, LogoBlob3);
- Snap3 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
- Snap10 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
+ Snap3 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
+ Snap10 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
}
void PutToFresh(ui64 lsn, const TLogoBlobID &key) {
- TRope buffer(Data);
+ TRope buffer(Data);
Fresh->PutLogoBlobWithData(lsn, TKeyLogoBlob(key), key.PartId(), TIngress(), std::move(buffer));
}
};
@@ -86,7 +86,7 @@ namespace NKikimr {
PutToFresh(5, LogoBlob1);
PutToFresh(6, LogoBlob2);
PutToFresh(7, LogoBlob3);
- Snap10 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
+ Snap10 = std::make_unique<TFreshData::TFreshDataSnapshot>(Fresh->GetSnapshot());
}
};
@@ -190,7 +190,7 @@ namespace NKikimr {
Y_UNIT_TEST(SolomonStandCrash) {
TFreshDataPtr fresh(new TFreshData(GetLevelIndexSetting(),
- CreateDefaultTimeProvider(), Arena));
+ CreateDefaultTimeProvider(), Arena));
auto putFunc = [] (TFreshDataPtr fresh, ui64 tabletID, ui32 gen, ui32 step, ui64 lsn) {
TMemRecLogoBlob memRec;
@@ -243,7 +243,7 @@ namespace NKikimr {
{
TInstant delStart = TAppData::TimeProvider->Now();
- fresh.reset();
+ fresh.reset();
TInstant delStop = TAppData::TimeProvider->Now();
STR << "Data delete: " << (delStop - delStart).ToString() << "\n";
}
@@ -324,7 +324,7 @@ namespace NKikimr {
}
std::sort(vec.begin(), vec.end());
- auto result = std::make_shared<TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>>(ctx.MemConsumer);
+ auto result = std::make_shared<TFreshAppendix<TKeyLogoBlob, TMemRecLogoBlob>>(ctx.MemConsumer);
result->Reserve(elems);
for (const auto x : vec) {
result->Add(TKeyLogoBlob(x), ctx.MemRec);
@@ -352,7 +352,7 @@ namespace NKikimr {
// built fresh data
TFreshDataPtr FreshData;
// fresh data snapshot at nth percent
- std::unique_ptr<TFreshData::TFreshDataSnapshot> SnapPercent;
+ std::unique_ptr<TFreshData::TFreshDataSnapshot> SnapPercent;
};
TFreshBuilder(ui64 elems, ui64 appendixBatchSize, bool appendixCompaction, ui64 percentValidLsns)
@@ -388,11 +388,11 @@ namespace NKikimr {
// take snapshot
if (elems == SnapshotCutoffLsn) {
- result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
+ result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
}
}
if (!result.SnapPercent) {
- result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
+ result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
}
TInstant stopTime = TAppData::TimeProvider->Now();
STR << "Build Fresh from Appendix(compact="<< AppendixCompaction <<"): "
@@ -413,11 +413,11 @@ namespace NKikimr {
fresh->Put(lsn++, TKeyLogoBlob(dataGenerator.Next()), ctx.MemRec);
// take snapshot
if (elems == SnapshotCutoffLsn) {
- result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
+ result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
}
}
if (!result.SnapPercent) {
- result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
+ result.SnapPercent = std::make_unique<TFreshData::TFreshDataSnapshot>(fresh->GetSnapshot());
}
TInstant stopTime = TAppData::TimeProvider->Now();
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.cpp
index e03735a82a3..e5fa8c37684 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.cpp
@@ -1,9 +1,9 @@
-#include "fresh_datasnap.h"
-
-namespace NKikimr {
-
- template class TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshDataSnapshot<TKeyBarrier, TMemRecBarrier>;
- template class TFreshDataSnapshot<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "fresh_datasnap.h"
+
+namespace NKikimr {
+
+ template class TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshDataSnapshot<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshDataSnapshot<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.h
index fd9028f9368..868681ef886 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_datasnap.h
@@ -1,7 +1,7 @@
#pragma once
#include "defs.h"
-#include "fresh_segment.h"
+#include "fresh_segment.h"
#include <library/cpp/threading/skip_list/skiplist.h>
#include <util/system/align.h>
#include <util/generic/set.h>
@@ -34,7 +34,7 @@ namespace NKikimr {
, Cur(std::move(cur))
{}
- class TForwardOldDregSegsMerger; // forward iterator, merges Old and Dreg
+ class TForwardOldDregSegsMerger; // forward iterator, merges Old and Dreg
class TBackwardCurDregSegsMerger; // backward iterator, merges Cur and Dreg
public:
@@ -53,19 +53,19 @@ namespace NKikimr {
TFreshSegmentSnapshot Dreg;
TFreshSegmentSnapshot Cur;
- class TForwardIterator; // forward iterator, merges TForwardOldDregSegsMerger and Cur
+ class TForwardIterator; // forward iterator, merges TForwardOldDregSegsMerger and Cur
class TBackwardIterator; // backward iterator, merges TBackwardCurDregSegsMerger and Old
};
- extern template class TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshDataSnapshot<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshDataSnapshot<TKeyBlock, TMemRecBlock>;
-
+ extern template class TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshDataSnapshot<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshDataSnapshot<TKeyBlock, TMemRecBlock>;
+
/////////////////////////////////////////////////////////////////////////////////////////
- // TFreshDataSnapshot::TForwardOldDregSegsMerger
+ // TFreshDataSnapshot::TForwardOldDregSegsMerger
/////////////////////////////////////////////////////////////////////////////////////////
template <class TKey, class TMemRec>
- class TFreshDataSnapshot<TKey, TMemRec>::TForwardOldDregSegsMerger
+ class TFreshDataSnapshot<TKey, TMemRec>::TForwardOldDregSegsMerger
: public TGenericForwardIterator<TKey, TSegForwardIterator, TSegForwardIterator>
{
public:
@@ -73,8 +73,8 @@ namespace NKikimr {
typedef ::NKikimr::TFreshDataSnapshot<TKey, TMemRec> TFreshDataSnapshot;
typedef TFreshDataSnapshot TContType;
- TForwardOldDregSegsMerger(const THullCtxPtr &hullCtx, const TContType *freshData)
- : TBase(hullCtx, &freshData->Old, &freshData->Dreg)
+ TForwardOldDregSegsMerger(const THullCtxPtr &hullCtx, const TContType *freshData)
+ : TBase(hullCtx, &freshData->Old, &freshData->Dreg)
{}
using TBase::PutToMerger;
@@ -111,15 +111,15 @@ namespace NKikimr {
/////////////////////////////////////////////////////////////////////////////////////////
template <class TKey, class TMemRec>
class TFreshDataSnapshot<TKey, TMemRec>::TForwardIterator
- : public TGenericForwardIterator<TKey, TForwardOldDregSegsMerger, TSegForwardIterator>
+ : public TGenericForwardIterator<TKey, TForwardOldDregSegsMerger, TSegForwardIterator>
{
public:
- typedef ::NKikimr::TGenericForwardIterator<TKey, TForwardOldDregSegsMerger, TSegForwardIterator> TBase;
+ typedef ::NKikimr::TGenericForwardIterator<TKey, TForwardOldDregSegsMerger, TSegForwardIterator> TBase;
typedef ::NKikimr::TFreshDataSnapshot<TKey, TMemRec> TFreshDataSnapshot;
typedef TFreshDataSnapshot TContType;
TForwardIterator(const THullCtxPtr &hullCtx, const TContType *freshData)
- : TBase(hullCtx, freshData, &freshData->Cur)
+ : TBase(hullCtx, freshData, &freshData->Cur)
{}
using TBase::PutToMerger;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.cpp
index f755e78f4f2..7b565cda32c 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.cpp
@@ -1,21 +1,21 @@
-#include "fresh_segment.h"
-
-namespace NKikimr {
-
- template class TFreshIndexAndDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshIndexAndDataSnapshot<TKeyBarrier, TMemRecBarrier>;
- template class TFreshIndexAndDataSnapshot<TKeyBlock, TMemRecBlock>;
-
- template class TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshIndexAndData<TKeyBarrier, TMemRecBarrier>;
- template class TFreshIndexAndData<TKeyBlock, TMemRecBlock>;
-
- template class TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshSegmentSnapshot<TKeyBarrier, TMemRecBarrier>;
- template class TFreshSegmentSnapshot<TKeyBlock, TMemRecBlock>;
-
- template class TFreshSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TFreshSegment<TKeyBarrier, TMemRecBarrier>;
- template class TFreshSegment<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "fresh_segment.h"
+
+namespace NKikimr {
+
+ template class TFreshIndexAndDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshIndexAndDataSnapshot<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshIndexAndDataSnapshot<TKeyBlock, TMemRecBlock>;
+
+ template class TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshIndexAndData<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshIndexAndData<TKeyBlock, TMemRecBlock>;
+
+ template class TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshSegmentSnapshot<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshSegmentSnapshot<TKeyBlock, TMemRecBlock>;
+
+ template class TFreshSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TFreshSegment<TKeyBarrier, TMemRecBarrier>;
+ template class TFreshSegment<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.h
index 70f91fee69a..d346cf58fb6 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment.h
@@ -63,7 +63,7 @@ namespace NKikimr {
using TBase = TAtomicRefCountWithDeleterInBatchPool<TFreshIndexAndData<TKey, TMemRec>>;
using TFreshIndex = ::NKikimr::TFreshIndex<TKey, TMemRec>;
- TFreshIndexAndData(THullCtxPtr hullCtx, std::shared_ptr<TRopeArena> arena);
+ TFreshIndexAndData(THullCtxPtr hullCtx, std::shared_ptr<TRopeArena> arena);
ui64 InPlaceSizeApproximation() const {
ui64 index = (sizeof(TKey) + sizeof(TMemRec)) * Inserts + sizeof(TIdxDiskPlaceHolder);
@@ -81,9 +81,9 @@ namespace NKikimr {
ui64 GetMemDataSize() const { return MemDataSize; }
ui64 GetHugeDataSize() const { return HugeDataSize; }
- // put newly received item into fresh segment
+ // put newly received item into fresh segment
void PutLogoBlobWithData(ui64 lsn, const TKey &key, ui8 partId, const TIngress &ingress, TRope buffer);
- const TRope& GetLogoBlobData(const TMemPart& memPart) const;
+ const TRope& GetLogoBlobData(const TMemPart& memPart) const;
void Put(ui64 lsn, const TKey &key, const TMemRec &memRec);
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const;
void GetHugeBlobs(TSet<TDiskPart> &hugeBlobs) const;
@@ -106,19 +106,19 @@ namespace NKikimr {
private:
THullCtxPtr HullCtx;
- std::unique_ptr<TFreshIndex> Index;
-
- static constexpr size_t RopeExtentSize = 4096;
- using TRopeExtent = std::array<TRope, RopeExtentSize>;
-
+ std::unique_ptr<TFreshIndex> Index;
+
+ static constexpr size_t RopeExtentSize = 4096;
+ using TRopeExtent = std::array<TRope, RopeExtentSize>;
+
// Track FreshData memory consumption
TMemoryConsumerWithDropOnDestroy FreshDataMemConsumer;
- // arena for small-bounded data allocations
- std::shared_ptr<TRopeArena> Arena;
- // a list of extents; only the last one is being filled
- TList<TRopeExtent> RopeExtents;
- size_t LastRopeExtentSize = RopeExtentSize;
-
+ // arena for small-bounded data allocations
+ std::shared_ptr<TRopeArena> Arena;
+ // a list of extents; only the last one is being filled
+ TList<TRopeExtent> RopeExtents;
+ size_t LastRopeExtentSize = RopeExtentSize;
+
ui64 FirstLsn = ui64(-1);
ui64 LastLsn = 0;
ui64 MemDataSize = 0;
@@ -190,10 +190,10 @@ namespace NKikimr {
// Compact fresh appendix job
struct TCompactionJob {
TIntrusivePtr<TThis> FreshSegment;
- std::shared_ptr<ISTreeCompaction> Job;
+ std::shared_ptr<ISTreeCompaction> Job;
TCompactionJob() = default;
- TCompactionJob(TIntrusivePtr<TThis> &&seg, std::shared_ptr<ISTreeCompaction> &&job)
+ TCompactionJob(TIntrusivePtr<TThis> &&seg, std::shared_ptr<ISTreeCompaction> &&job)
: FreshSegment(std::move(seg))
, Job(std::move(job))
{}
@@ -203,16 +203,16 @@ namespace NKikimr {
TCompactionJob ApplyCompactionResult() {
TCompactionJob newJob = FreshSegment->ApplyCompactionResult(Job);
FreshSegment.Drop();
- Job.reset();
+ Job.reset();
return newJob;
}
};
- TFreshSegment(THullCtxPtr hullCtx, ui64 compThreshold, TInstant startTime, std::shared_ptr<TRopeArena> arena)
+ TFreshSegment(THullCtxPtr hullCtx, ui64 compThreshold, TInstant startTime, std::shared_ptr<TRopeArena> arena)
: CompThreshold(Max<ui64>(hullCtx->ChunkSize, compThreshold))
, ChunkSize(hullCtx->ChunkSize)
, StartTime(startTime)
- , IndexAndData(MakeIntrusive<TFreshIndexAndData>(hullCtx, std::move(arena)))
+ , IndexAndData(MakeIntrusive<TFreshIndexAndData>(hullCtx, std::move(arena)))
, AppendixTree(hullCtx, AppendixTreeStagingCapacity)
{}
@@ -246,7 +246,7 @@ namespace NKikimr {
}
const TRope& GetLogoBlobData(const TMemPart& memPart) const { return IndexAndData->GetLogoBlobData(memPart); }
void Put(ui64 lsn, const TKey &key, const TMemRec &memRec) { return IndexAndData->Put(lsn, key, memRec); }
- void PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
+ void PutAppendix(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
AppendixTree.AddAppendix(std::move(a), firstLsn, lastLsn);
}
void OutputHtml(const TString &which, IOutputStream &str) const;
@@ -254,7 +254,7 @@ namespace NKikimr {
void GetHugeBlobs(TSet<TDiskPart> &hugeBlobs) const { return IndexAndData->GetHugeBlobs(hugeBlobs); }
// Appendix Compact/ApplyCompactionResult
TCompactionJob Compact() { return MkCompactJob(AppendixTree.Compact()); }
- TCompactionJob ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
+ TCompactionJob ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
return MkCompactJob(AppendixTree.ApplyCompactionResult(cjob));
}
const TSTreeCompactionStat &GetCompactionStat() const { return AppendixTree.GetCompactionStat(); }
@@ -271,7 +271,7 @@ namespace NKikimr {
// FIXME: implement TIntrusivePtr with deletion in batch pool
TFreshAppendixTree<TKey, TMemRec> AppendixTree;
- TCompactionJob MkCompactJob(std::shared_ptr<ISTreeCompaction> &&job) {
+ TCompactionJob MkCompactJob(std::shared_ptr<ISTreeCompaction> &&job) {
if (job) {
return TCompactionJob(TIntrusivePtr<TThis>(this), std::move(job));
} else {
@@ -283,25 +283,25 @@ namespace NKikimr {
} // NKikimr
-#include "fresh_segment_impl.h"
-
-namespace NKikimr {
-
- extern template class TFreshIndexAndDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshIndexAndDataSnapshot<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshIndexAndDataSnapshot<TKeyBlock, TMemRecBlock>;
-
- extern template class TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshIndexAndData<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshIndexAndData<TKeyBlock, TMemRecBlock>;
-
- extern template class TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshSegmentSnapshot<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshSegmentSnapshot<TKeyBlock, TMemRecBlock>;
-
- extern template class TFreshSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TFreshSegment<TKeyBarrier, TMemRecBarrier>;
- extern template class TFreshSegment<TKeyBlock, TMemRecBlock>;
-
- } // NKikimr
-
+#include "fresh_segment_impl.h"
+
+namespace NKikimr {
+
+ extern template class TFreshIndexAndDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshIndexAndDataSnapshot<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshIndexAndDataSnapshot<TKeyBlock, TMemRecBlock>;
+
+ extern template class TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshIndexAndData<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshIndexAndData<TKeyBlock, TMemRecBlock>;
+
+ extern template class TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshSegmentSnapshot<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshSegmentSnapshot<TKeyBlock, TMemRecBlock>;
+
+ extern template class TFreshSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TFreshSegment<TKeyBarrier, TMemRecBarrier>;
+ extern template class TFreshSegment<TKeyBlock, TMemRecBlock>;
+
+ } // NKikimr
+
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_impl.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_impl.h
index 3ebf8e8bea3..036f5ebf2e3 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_impl.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_impl.h
@@ -170,12 +170,12 @@ namespace NKikimr {
template <class TKey, class TMemRec>
TFreshIndexAndData<TKey, TMemRec>::TFreshIndexAndData(
THullCtxPtr hullCtx,
- std::shared_ptr<TRopeArena> arena)
+ std::shared_ptr<TRopeArena> arena)
: TBase(TDeleteInBatchPool(hullCtx->VCtx->ActorSystem))
, HullCtx(hullCtx)
, Index(new TFreshIndex(hullCtx->VCtx))
, FreshDataMemConsumer(hullCtx->VCtx->FreshData)
- , Arena(std::move(arena))
+ , Arena(std::move(arena))
{}
template <class TKey, class TMemRec>
@@ -191,68 +191,68 @@ namespace NKikimr {
LastLsn = lsn;
}
- template <typename TKey, typename TMemRec>
- inline void TFreshIndexAndData<TKey, TMemRec>::PutLogoBlobWithData(ui64 /*lsn*/, const TKey& /*key*/, ui8 /*partId*/,
- const TIngress& /*ingress*/, TRope /*buffer*/) {
- static_assert(!std::is_same_v<TKey, TKeyLogoBlob>, "not implemented");
- }
-
- template <>
+ template <typename TKey, typename TMemRec>
+ inline void TFreshIndexAndData<TKey, TMemRec>::PutLogoBlobWithData(ui64 /*lsn*/, const TKey& /*key*/, ui8 /*partId*/,
+ const TIngress& /*ingress*/, TRope /*buffer*/) {
+ static_assert(!std::is_same_v<TKey, TKeyLogoBlob>, "not implemented");
+ }
+
+ template <>
inline void TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>::PutLogoBlobWithData(ui64 lsn,
const TKeyLogoBlob &key, ui8 partId, const TIngress &ingress, TRope buffer) {
- TMemRecLogoBlob memRec(ingress);
- const size_t before = Arena->GetSize();
- buffer = TRope::CopySpaceOptimized(std::move(buffer), 128, *Arena);
+ TMemRecLogoBlob memRec(ingress);
+ const size_t before = Arena->GetSize();
+ buffer = TRope::CopySpaceOptimized(std::move(buffer), 128, *Arena);
const ui64 fullDataSize = key.LogoBlobID().BlobSize();
- TRope blob = TDiskBlob::Create(fullDataSize, partId, HullCtx->VCtx->Top->GType.TotalPartCount(), std::move(buffer), *Arena);
- const size_t after = Arena->GetSize();
- const size_t delta = after - before;
+ TRope blob = TDiskBlob::Create(fullDataSize, partId, HullCtx->VCtx->Top->GType.TotalPartCount(), std::move(buffer), *Arena);
+ const size_t after = Arena->GetSize();
+ const size_t delta = after - before;
FreshDataMemConsumer.Add(delta);
- const ui32 blobSize = blob.GetSize();
-
- // create additional extent if existing one has exhausted
- if (LastRopeExtentSize == RopeExtentSize) {
- RopeExtents.emplace_back();
- LastRopeExtentSize = 0;
- }
-
- // get the last extent and put the rope to its end
- Y_VERIFY(RopeExtents);
- auto& extent = RopeExtents.back();
- TRope& rope = extent[LastRopeExtentSize++];
- rope = std::move(blob);
-
- // calculate buffer id from the rope address; the address is immutable during fresh segment lifetime, so we can
- // use it directly
- uintptr_t bufferId = reinterpret_cast<uintptr_t>(&rope);
- Y_VERIFY((bufferId & 0x7) == 0);
- bufferId >>= 3;
- Y_VERIFY(bufferId < (ui64(1) << 62));
- memRec.SetMemBlob(bufferId, blobSize);
-
- Put(lsn, key, memRec);
- }
-
- template <>
+ const ui32 blobSize = blob.GetSize();
+
+ // create additional extent if existing one has exhausted
+ if (LastRopeExtentSize == RopeExtentSize) {
+ RopeExtents.emplace_back();
+ LastRopeExtentSize = 0;
+ }
+
+ // get the last extent and put the rope to its end
+ Y_VERIFY(RopeExtents);
+ auto& extent = RopeExtents.back();
+ TRope& rope = extent[LastRopeExtentSize++];
+ rope = std::move(blob);
+
+ // calculate buffer id from the rope address; the address is immutable during fresh segment lifetime, so we can
+ // use it directly
+ uintptr_t bufferId = reinterpret_cast<uintptr_t>(&rope);
+ Y_VERIFY((bufferId & 0x7) == 0);
+ bufferId >>= 3;
+ Y_VERIFY(bufferId < (ui64(1) << 62));
+ memRec.SetMemBlob(bufferId, blobSize);
+
+ Put(lsn, key, memRec);
+ }
+
+ template <>
inline const TRope& TFreshIndexAndData<TKeyLogoBlob, TMemRecLogoBlob>::GetLogoBlobData(const TMemPart& memPart) const {
- const TRope& rope = *reinterpret_cast<const TRope*>(memPart.BufferId << 3);
- Y_VERIFY(rope.GetSize() == memPart.Size);
- return rope;
- }
-
+ const TRope& rope = *reinterpret_cast<const TRope*>(memPart.BufferId << 3);
+ Y_VERIFY(rope.GetSize() == memPart.Size);
+ return rope;
+ }
+
template <class TKey, class TMemRec>
inline const TRope& TFreshIndexAndData<TKey, TMemRec>::GetLogoBlobData(const TMemPart& /*memPart*/) const {
- Y_FAIL("invalid call");
- }
-
- template <class TKey, class TMemRec>
+ Y_FAIL("invalid call");
+ }
+
+ template <class TKey, class TMemRec>
void TFreshIndexAndData<TKey, TMemRec>::Put(ui64 lsn, const TKey &key, const TMemRec &memRec) {
auto type = memRec.GetType();
auto dataSize = memRec.DataSize();
switch (type) {
case TBlobType::MemBlob:
Y_VERIFY(dataSize);
- MemDataSize += AlignUp(dataSize, 8u);
+ MemDataSize += AlignUp(dataSize, 8u);
break;
case TBlobType::DiskBlob:
Y_VERIFY(!memRec.HasData());
@@ -270,17 +270,17 @@ namespace NKikimr {
template <class TKey, class TMemRec>
void TFreshIndexAndData<TKey, TMemRec>::GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
using TIterator = typename TFreshIndex::TIterator;
- TIterator it(Index.get());
+ TIterator it(Index.get());
it.SeekToFirst();
while (it.Valid()) {
const TMemRec &memRec = it.GetValue().MemRec;
if (memRec.GetType() == TBlobType::HugeBlob) {
TDiskDataExtractor extr;
const TDiskPart& part = memRec.GetDiskData(&extr, nullptr)->SwearOne();
- if (part.Size) {
- Y_VERIFY(part.ChunkIdx);
- chunks.insert(part.ChunkIdx);
- }
+ if (part.Size) {
+ Y_VERIFY(part.ChunkIdx);
+ chunks.insert(part.ChunkIdx);
+ }
}
it.Next();
}
@@ -289,7 +289,7 @@ namespace NKikimr {
template <class TKey, class TMemRec>
void TFreshIndexAndData<TKey, TMemRec>::GetHugeBlobs(TSet<TDiskPart> &hugeBlobs) const {
using TIterator = typename TFreshIndex::TIterator;
- TIterator it(Index.get());
+ TIterator it(Index.get());
it.SeekToFirst();
while (it.Valid()) {
const TMemRec &memRec = it.GetValue().MemRec;
@@ -329,7 +329,7 @@ namespace NKikimr {
while (cursor.Valid() && key == cursor.GetValue().Key) {
ui64 cursorLsn = cursor.GetValue().Lsn;
if (cursorLsn <= Lsn)
- PutToMerger(cursor.GetValue().MemRec, cursorLsn, merger);
+ PutToMerger(cursor.GetValue().MemRec, cursorLsn, merger);
cursor.Next();
}
}
@@ -351,7 +351,7 @@ namespace NKikimr {
// dump all data of the segment accessible by this iterator
void DumpAll(IOutputStream &str) const {
str << "=== Fresh (lsn=" << Lsn << ")===\n";
- TIterator it(Seg->Index.get());
+ TIterator it(Seg->Index.get());
it.SeekToFirst();
while (it.Valid()) {
const auto &item = it.GetValue();
@@ -378,15 +378,15 @@ namespace NKikimr {
}
template <class TRecordMerger>
- void PutToMerger(const TMemRec &memRec, ui64 lsn, TRecordMerger *merger) {
- TKey key = It.GetValue().Key;
- if (merger->HaveToMergeData() && memRec.HasData() && memRec.GetType() == TBlobType::MemBlob) {
- const TMemPart p = memRec.GetMemData();
- const TRope& rope = Seg->GetLogoBlobData(p);
- merger->AddFromFresh(memRec, &rope, key, lsn);
- } else {
- merger->AddFromFresh(memRec, nullptr, key, lsn);
- }
+ void PutToMerger(const TMemRec &memRec, ui64 lsn, TRecordMerger *merger) {
+ TKey key = It.GetValue().Key;
+ if (merger->HaveToMergeData() && memRec.HasData() && memRec.GetType() == TBlobType::MemBlob) {
+ const TMemPart p = memRec.GetMemData();
+ const TRope& rope = Seg->GetLogoBlobData(p);
+ merger->AddFromFresh(memRec, &rope, key, lsn);
+ } else {
+ merger->AddFromFresh(memRec, nullptr, key, lsn);
+ }
}
};
@@ -467,7 +467,7 @@ namespace NKikimr {
void SeekToFirst() {
if (Seg) {
- It = TIterator(Seg->Index.get());
+ It = TIterator(Seg->Index.get());
It.SeekToFirst();
if (!It.Valid())
return;
@@ -482,7 +482,7 @@ namespace NKikimr {
bool fromCache = SeekCache.Search(key, It);
if (!fromCache) {
typename TFreshIndex::TIdxKey idxKey(0, key, TMemRec());
- It = TIterator(Seg->Index.get());
+ It = TIterator(Seg->Index.get());
It.SeekTo(idxKey);
if (It.Valid() && !HasSatisfyingValues())
Next();
@@ -539,11 +539,11 @@ namespace NKikimr {
void Seek(const TKey &key) {
if (Seg) {
typename TFreshIndex::TIdxKey idxKey(0, key, TMemRec());
- It = TIterator(Seg->Index.get());
+ It = TIterator(Seg->Index.get());
It.SeekTo(idxKey);
if (!It.Valid()) {
// i.e. end
- It = TIterator(Seg->Index.get());
+ It = TIterator(Seg->Index.get());
It.SeekToLast();
if (It.Valid()) {
ToTheChainStart();
@@ -664,63 +664,63 @@ namespace NKikimr {
using TContType = TFreshSegmentSnapshot;
TIteratorWOMerge(const THullCtxPtr &hullCtx, const TContType *data)
- : It(hullCtx, data)
+ : It(hullCtx, data)
{}
TIteratorWOMerge(const TIteratorWOMerge &) = default;
TIteratorWOMerge &operator=(const TIteratorWOMerge &) = default;
bool Valid() const {
- return !Recs.empty();
+ return !Recs.empty();
}
void Next() {
- if (!Recs.empty()) {
- Recs.pop_back();
- if (!Recs.empty()) {
- return; // more records to go with the current key
- }
- }
-
- if (!It.Valid()) {
- return;
- }
-
- struct {
- std::vector<std::pair<TKey, TMemRec>>& Recs;
-
- void AddFromSegment(const TMemRec&, const TDiskPart*, const TKey&, ui64) {
- Y_VERIFY_DEBUG(false, "should not be called");
- }
-
- void AddFromFresh(const TMemRec& memRec, const TRope* /*data*/, const TKey& key, ui64 /*lsn*/) {
- Recs.emplace_back(key, memRec);
- }
-
- static constexpr bool HaveToMergeData() { return false; }
- } m{Recs};
-
- It.PutToMerger(&m);
- It.Next();
+ if (!Recs.empty()) {
+ Recs.pop_back();
+ if (!Recs.empty()) {
+ return; // more records to go with the current key
+ }
+ }
+
+ if (!It.Valid()) {
+ return;
+ }
+
+ struct {
+ std::vector<std::pair<TKey, TMemRec>>& Recs;
+
+ void AddFromSegment(const TMemRec&, const TDiskPart*, const TKey&, ui64) {
+ Y_VERIFY_DEBUG(false, "should not be called");
+ }
+
+ void AddFromFresh(const TMemRec& memRec, const TRope* /*data*/, const TKey& key, ui64 /*lsn*/) {
+ Recs.emplace_back(key, memRec);
+ }
+
+ static constexpr bool HaveToMergeData() { return false; }
+ } m{Recs};
+
+ It.PutToMerger(&m);
+ It.Next();
}
void SeekToFirst() {
- Recs.clear();
- It.SeekToFirst();
- Next();
+ Recs.clear();
+ It.SeekToFirst();
+ Next();
}
TKey GetUnmergedKey() const {
- return Recs.back().first;
+ return Recs.back().first;
}
TMemRec GetUnmergedMemRec() const {
- return Recs.back().second;
+ return Recs.back().second;
}
private:
- TForwardIterator It; // generic merging iterator
- std::vector<std::pair<TKey, TMemRec>> Recs;
+ TForwardIterator It; // generic merging iterator
+ std::vector<std::pair<TKey, TMemRec>> Recs;
};
template <class TKey, class TMemRec>
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_ut.cpp
index d634bfd7073..3d931808d14 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/fresh_segment_ut.cpp
@@ -12,7 +12,7 @@
namespace NKikimr {
- static std::shared_ptr<TRopeArena> Arena = std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate);
+ static std::shared_ptr<TRopeArena> Arena = std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate);
Y_UNIT_TEST_SUITE(TBlobStorageHullFreshSegment) {
@@ -94,7 +94,7 @@ namespace NKikimr {
void ReinitAps() {
for (Part = From; Part <= To; ++Part) {
- Aps[Part - From] = std::make_shared<TAppendix>(MemConsumer);
+ Aps[Part - From] = std::make_shared<TAppendix>(MemConsumer);
}
}
@@ -134,7 +134,7 @@ namespace NKikimr {
ui32 Part = 0;
ui32 Inserts = 0;
ui32 Compactions = 0;
- TVector<std::shared_ptr<TAppendix>> Aps;
+ TVector<std::shared_ptr<TAppendix>> Aps;
};
template <class TOtherVDisks>
@@ -186,49 +186,49 @@ namespace NKikimr {
Y_UNIT_TEST(PerfSkipList) {
Load<TOtherVDisksSkipList>();
}
-
- Y_UNIT_TEST(IteratorTest) {
- ui64 compThreshold = 128 << 20;
- auto hullCtx = GetLevelIndexSetting().HullCtx;
- auto seg = MakeIntrusive<TFreshSegment>(hullCtx, compThreshold, TAppData::TimeProvider->Now(), Arena);
-
- std::deque<TLogoBlobID> withMerge, withoutMerge;
-
- ui64 lsn = 1;
- const ui64 tabletId = 0x100100000010003ul;
- const ui32 gen = 5;
-
- TMemRecLogoBlob memRec;
- memRec.SetNoBlob();
-
- for (ui32 i = 1; i < 500000; i++) {
- const ui32 step = i;
-
- TLogoBlobID id(tabletId, gen, step, 0, 0, 0);
- seg->Put(lsn++, TKeyLogoBlob(id), memRec);
- withMerge.push_back(id);
- withoutMerge.push_back(id);
- if (RandomNumber<ui32>() % 2) {
- seg->Put(lsn++, TKeyLogoBlob(id), memRec);
- withoutMerge.push_back(id);
- }
- }
-
- auto snap = seg->GetSnapshot();
- using T = std::decay_t<decltype(snap)>;
-
- auto check = [&](auto iter, auto& queue, auto&& getKey) {
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- UNIT_ASSERT(!queue.empty());
- UNIT_ASSERT_VALUES_EQUAL(queue.front(), getKey(iter).LogoBlobID());
- queue.pop_front();
- }
- UNIT_ASSERT(queue.empty());
- };
-
- check(T::TForwardIterator(hullCtx, &snap), withMerge, [](auto& iter) { return iter.GetCurKey(); });
- check(T::TIteratorWOMerge(hullCtx, &snap), withoutMerge, [](auto& iter) { return iter.GetUnmergedKey(); });
- }
+
+ Y_UNIT_TEST(IteratorTest) {
+ ui64 compThreshold = 128 << 20;
+ auto hullCtx = GetLevelIndexSetting().HullCtx;
+ auto seg = MakeIntrusive<TFreshSegment>(hullCtx, compThreshold, TAppData::TimeProvider->Now(), Arena);
+
+ std::deque<TLogoBlobID> withMerge, withoutMerge;
+
+ ui64 lsn = 1;
+ const ui64 tabletId = 0x100100000010003ul;
+ const ui32 gen = 5;
+
+ TMemRecLogoBlob memRec;
+ memRec.SetNoBlob();
+
+ for (ui32 i = 1; i < 500000; i++) {
+ const ui32 step = i;
+
+ TLogoBlobID id(tabletId, gen, step, 0, 0, 0);
+ seg->Put(lsn++, TKeyLogoBlob(id), memRec);
+ withMerge.push_back(id);
+ withoutMerge.push_back(id);
+ if (RandomNumber<ui32>() % 2) {
+ seg->Put(lsn++, TKeyLogoBlob(id), memRec);
+ withoutMerge.push_back(id);
+ }
+ }
+
+ auto snap = seg->GetSnapshot();
+ using T = std::decay_t<decltype(snap)>;
+
+ auto check = [&](auto iter, auto& queue, auto&& getKey) {
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ UNIT_ASSERT(!queue.empty());
+ UNIT_ASSERT_VALUES_EQUAL(queue.front(), getKey(iter).LogoBlobID());
+ queue.pop_front();
+ }
+ UNIT_ASSERT(queue.empty());
+ };
+
+ check(T::TForwardIterator(hullCtx, &snap), withMerge, [](auto& iter) { return iter.GetCurKey(); });
+ check(T::TIteratorWOMerge(hullCtx, &snap), withoutMerge, [](auto& iter) { return iter.GetUnmergedKey(); });
+ }
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec.h b/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec.h
index 1d240ff7f70..03e2462e1df 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec.h
@@ -36,7 +36,7 @@ namespace NKikimr {
++Pos;
}
- const std::shared_ptr<T> &Get() const {
+ const std::shared_ptr<T> &Get() const {
Y_VERIFY_DEBUG(Valid());
return Snap->VecPtr->at(Pos);
}
@@ -63,16 +63,16 @@ namespace NKikimr {
TSVecSnap() = default;
void Destroy() {
- VecPtr.reset();
+ VecPtr.reset();
}
private:
- TSVecSnap(const std::shared_ptr<TVector<std::shared_ptr<T>>> &vecPtr) {
+ TSVecSnap(const std::shared_ptr<TVector<std::shared_ptr<T>>> &vecPtr) {
VecPtr = vecPtr;
NElements = vecPtr->size();
}
- std::shared_ptr<TVector<std::shared_ptr<T>>> VecPtr;
+ std::shared_ptr<TVector<std::shared_ptr<T>>> VecPtr;
size_t NElements = 0;
};
@@ -80,32 +80,32 @@ namespace NKikimr {
class TSVec {
public:
TSVec(size_t capacity)
- : VecPtr(std::make_shared<TVector<std::shared_ptr<T>>>())
+ : VecPtr(std::make_shared<TVector<std::shared_ptr<T>>>())
{
VecPtr->reserve(capacity);
}
- void Add(const std::shared_ptr<T> &t) {
+ void Add(const std::shared_ptr<T> &t) {
ResizeIfRequired();
SizeApprox += t->SizeApproximation();
VecPtr->push_back(t);
}
- void Add(std::shared_ptr<T> &&t) {
+ void Add(std::shared_ptr<T> &&t) {
ResizeIfRequired();
SizeApprox += t->SizeApproximation();
VecPtr->push_back(std::move(t));
}
void RemoveFirstElements(size_t n) {
- auto rebuildVecPtr = std::make_shared<TVector<std::shared_ptr<T>>>();
+ auto rebuildVecPtr = std::make_shared<TVector<std::shared_ptr<T>>>();
rebuildVecPtr->reserve(VecPtr->capacity());
ui64 sizeApprox = 0;
for (size_t i = n, size = VecPtr->size(); i < size; ++i) {
sizeApprox += VecPtr->at(i)->SizeApproximation();
rebuildVecPtr->push_back(VecPtr->at(i));
}
- VecPtr.swap(rebuildVecPtr);
+ VecPtr.swap(rebuildVecPtr);
SizeApprox = sizeApprox;
}
@@ -122,18 +122,18 @@ namespace NKikimr {
}
private:
- std::shared_ptr<TVector<std::shared_ptr<T>>> VecPtr;
+ std::shared_ptr<TVector<std::shared_ptr<T>>> VecPtr;
ui64 SizeApprox = 0;
void ResizeIfRequired() {
if (VecPtr->size() == VecPtr->capacity()) {
// rebuild vec with extended capacity
- auto rebuildVecPtr = std::make_shared<TVector<std::shared_ptr<T>>>();
+ auto rebuildVecPtr = std::make_shared<TVector<std::shared_ptr<T>>>();
rebuildVecPtr->reserve(VecPtr->capacity() * 2);
for (const auto &x : *VecPtr) {
rebuildVecPtr->push_back(x);
}
- VecPtr.swap(rebuildVecPtr);
+ VecPtr.swap(rebuildVecPtr);
}
}
};
@@ -149,10 +149,10 @@ namespace NKikimr {
template <class T, class TCtx>
class TSTreeSnap {
private:
- using TOneLevel = TVector<std::shared_ptr<T>>;
- using TOneLevelPtr = std::shared_ptr<TOneLevel>;
+ using TOneLevel = TVector<std::shared_ptr<T>>;
+ using TOneLevelPtr = std::shared_ptr<TOneLevel>;
using TLevels = TVector<TOneLevelPtr>;
- using TLevelsPtr = std::shared_ptr<TLevels>;
+ using TLevelsPtr = std::shared_ptr<TLevels>;
friend class TSTree<T, TCtx>;
TSTreeSnap(const TCtx &ctx, const TSVecSnap<T> &staging, const TLevelsPtr &levelsPtr)
@@ -161,7 +161,7 @@ namespace NKikimr {
, LevelsPtr(levelsPtr)
{}
- // TLevelsIterator -- iterates over levels (not staging), returns std::shared_ptr<T> on each iteration
+ // TLevelsIterator -- iterates over levels (not staging), returns std::shared_ptr<T> on each iteration
class TLevelsIterator {
public:
TLevelsIterator(TLevels *levels)
@@ -192,7 +192,7 @@ namespace NKikimr {
}
}
- const std::shared_ptr<T> &Get() const {
+ const std::shared_ptr<T> &Get() const {
Y_VERIFY_DEBUG(Valid());
return *IntraLevelIt;
}
@@ -208,7 +208,7 @@ namespace NKikimr {
void Position() {
while (ViaLevelsIt != Levels->end()) {
- if (ViaLevelsIt->get() && !(*ViaLevelsIt)->empty()) {
+ if (ViaLevelsIt->get() && !(*ViaLevelsIt)->empty()) {
IntraLevelIt = (*ViaLevelsIt)->begin();
break;
} else {
@@ -221,13 +221,13 @@ namespace NKikimr {
public:
TSTreeSnap() = default;
- // TIterator -- iterates over levels _and_ staging, returns std::shared_ptr<T> on each iteration
+ // TIterator -- iterates over levels _and_ staging, returns std::shared_ptr<T> on each iteration
class TIterator {
public:
TIterator(const TSTreeSnap *snap)
: Snap(snap)
, StagingIt(Snap ? &Snap->Staging : nullptr)
- , LevelsIt(Snap ? Snap->LevelsPtr.get() : nullptr)
+ , LevelsIt(Snap ? Snap->LevelsPtr.get() : nullptr)
{}
void SeekToFirst() {
@@ -248,7 +248,7 @@ namespace NKikimr {
}
}
- const std::shared_ptr<T> &Get() const {
+ const std::shared_ptr<T> &Get() const {
Y_VERIFY_DEBUG(Valid());
if (StagingIt.Valid()) {
return StagingIt.Get();
@@ -268,7 +268,7 @@ namespace NKikimr {
str << "Staging: ";
Staging.Output(str, printer);
str << "\n";
- TLevelsIterator it(LevelsPtr.get());
+ TLevelsIterator it(LevelsPtr.get());
it.SeekToFirst();
while (it.Valid()) {
str << "Level# " << it.GetLevel() << " Value# ";
@@ -280,7 +280,7 @@ namespace NKikimr {
void Destroy() {
Staging.Destroy();
- LevelsPtr.reset();
+ LevelsPtr.reset();
}
private:
@@ -332,10 +332,10 @@ namespace NKikimr {
, StagingCompactionThreshold(stagingCompThreshold)
, LevelCompactionThreshold(levelCompThreshold)
, Staging(stagingCapacity)
- , LevelsPtr(std::make_shared<TLevels>())
+ , LevelsPtr(std::make_shared<TLevels>())
{}
- void Add(const std::shared_ptr<T> &t) {
+ void Add(const std::shared_ptr<T> &t) {
Staging.Add(t);
}
@@ -347,17 +347,17 @@ namespace NKikimr {
return TSTreeSnap<T, TCtx>(Ctx, Staging.GetSnapshot(), LevelsPtr);
}
- std::shared_ptr<ISTreeCompaction> Compact() {
+ std::shared_ptr<ISTreeCompaction> Compact() {
if (Staging.GetVecSize() > StagingCompactionThreshold) {
- return std::make_shared<TCompactionJob>(Ctx, LevelCompactionThreshold,
+ return std::make_shared<TCompactionJob>(Ctx, LevelCompactionThreshold,
Staging.GetSnapshot(), LevelsPtr);
} else {
return nullptr;
}
}
- std::shared_ptr<ISTreeCompaction> ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
- auto *job = dynamic_cast<TCompactionJob*>(cjob.get());
+ std::shared_ptr<ISTreeCompaction> ApplyCompactionResult(std::shared_ptr<ISTreeCompaction> cjob) {
+ auto *job = dynamic_cast<TCompactionJob*>(cjob.get());
auto result = job->GetCompactionResult();
Staging.RemoveFirstElements(result.ClearFirstRecs);
LevelsPtr = result.LevelsPtrDst;
@@ -372,10 +372,10 @@ namespace NKikimr {
}
private:
- using TOneLevel = TVector<std::shared_ptr<T>>;
- using TOneLevelPtr = std::shared_ptr<TOneLevel>;
+ using TOneLevel = TVector<std::shared_ptr<T>>;
+ using TOneLevelPtr = std::shared_ptr<TOneLevel>;
using TLevels = TVector<TOneLevelPtr>;
- using TLevelsPtr = std::shared_ptr<TLevels>;
+ using TLevelsPtr = std::shared_ptr<TLevels>;
TCtx Ctx;
const size_t StagingCompactionThreshold;
@@ -416,20 +416,20 @@ namespace NKikimr {
}
virtual void Work() override {
- std::shared_ptr<T> s = CompactStaging();
+ std::shared_ptr<T> s = CompactStaging();
ui64 sizeApprox = 0;
bool toNextLine = true;
- CompactionResult.LevelsPtrDst = std::make_shared<TLevels>();
+ CompactionResult.LevelsPtrDst = std::make_shared<TLevels>();
CompactionResult.LevelsPtrDst->reserve(LevelsPtrSource->size() + 1);
size_t level = 0;
while (toNextLine) {
- auto newLevelPtr = std::make_shared<TOneLevel>();
+ auto newLevelPtr = std::make_shared<TOneLevel>();
if (level < LevelsPtrSource->size() && // handle no vec at level=level
LevelsPtrSource->at(level)->size() + 1 > LevelCompactionThreshold) {
// compact
- TVector<std::shared_ptr<T>> input;
+ TVector<std::shared_ptr<T>> input;
input = *LevelsPtrSource->at(level);
input.push_back(s);
// gather stat
@@ -485,8 +485,8 @@ namespace NKikimr {
const TLevelsPtr LevelsPtrSource;
TCompactionResult CompactionResult;
- std::shared_ptr<T> CompactStaging() {
- TVector<std::shared_ptr<T>> input;
+ std::shared_ptr<T> CompactStaging() {
+ TVector<std::shared_ptr<T>> input;
CompactionResult.ClearFirstRecs = StagingSource.GetSize();
input.reserve(CompactionResult.ClearFirstRecs);
typename TSVecSnap<T>::TIterator it(&StagingSource);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec_ut.cpp
index d4cac3ca5be..3ee3f51ad0c 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/snap_vec_ut.cpp
@@ -55,9 +55,9 @@ namespace NKikimr {
Y_UNIT_TEST(Basic) {
TSVec<TBundle> svec(4);
- svec.Add(std::make_shared<TBundle>(1));
- svec.Add(std::make_shared<TBundle>(2));
- svec.Add(std::make_shared<TBundle>(3));
+ svec.Add(std::make_shared<TBundle>(1));
+ svec.Add(std::make_shared<TBundle>(2));
+ svec.Add(std::make_shared<TBundle>(3));
auto snap1 = svec.GetSnapshot();
UNIT_ASSERT_EQUAL(snap1.GetSize(), 3);
@@ -65,10 +65,10 @@ namespace NKikimr {
UNIT_ASSERT_EQUAL(svec.SizeApproximation(), 3 * sizeof(int));
// rebuild happens
- svec.Add(std::make_shared<TBundle>(4));
- svec.Add(std::make_shared<TBundle>(5));
- svec.Add(std::make_shared<TBundle>(6));
- svec.Add(std::make_shared<TBundle>(7));
+ svec.Add(std::make_shared<TBundle>(4));
+ svec.Add(std::make_shared<TBundle>(5));
+ svec.Add(std::make_shared<TBundle>(6));
+ svec.Add(std::make_shared<TBundle>(7));
CheckSnap(snap1, TVector<int>({1, 2, 3}));
@@ -116,9 +116,9 @@ namespace NKikimr {
return sizeof(int) * Vec.size();
}
- static std::shared_ptr<TBundle> Merge(const TCtx &ctx, const TVector<std::shared_ptr<TBundle>> &v) {
+ static std::shared_ptr<TBundle> Merge(const TCtx &ctx, const TVector<std::shared_ptr<TBundle>> &v) {
Y_UNUSED(ctx);
- std::shared_ptr<TBundle> result = std::make_shared<TBundle>();
+ std::shared_ptr<TBundle> result = std::make_shared<TBundle>();
for (const auto &item : v) {
result->Append(*item);
}
@@ -128,7 +128,7 @@ namespace NKikimr {
TVector<int> Vec;
};
- static void SnapshotPrinter(IOutputStream &str, const std::shared_ptr<TBundle> &val) {
+ static void SnapshotPrinter(IOutputStream &str, const std::shared_ptr<TBundle> &val) {
val->Output(str);
}
@@ -166,7 +166,7 @@ namespace NKikimr {
Y_UNIT_TEST(Basic) {
TCtx ctx;
TSTree<TBundle, TCtx> stree(ctx, 4, 4, 4);
- std::unique_ptr<TSTreeSnap<TBundle, TCtx>> intermedSnap;
+ std::unique_ptr<TSTreeSnap<TBundle, TCtx>> intermedSnap;
TString intermedCanonized = "Staging: \n"
"Level# 0 Value# [50 51 52 53 54]\n"
@@ -183,8 +183,8 @@ namespace NKikimr {
"Level# 1 Value# [75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]\n";
for (int i = 0; i < 102; ++i) {
- stree.Add(std::make_shared<TBundle>(i));
- std::shared_ptr<ISTreeCompaction> cjob = stree.Compact();
+ stree.Add(std::make_shared<TBundle>(i));
+ std::shared_ptr<ISTreeCompaction> cjob = stree.Compact();
if (cjob) {
STR << "compaction\n";
cjob->Work();
@@ -192,7 +192,7 @@ namespace NKikimr {
}
UNIT_ASSERT_EQUAL(stree.SizeApproximation(), 4u * (i + 1));
if (i == 69) {
- intermedSnap = std::make_unique<TSTreeSnap<TBundle, TCtx>>(stree.GetSnapshot());
+ intermedSnap = std::make_unique<TSTreeSnap<TBundle, TCtx>>(stree.GetSnapshot());
UNIT_ASSERT_EQUAL(stree.SizeApproximation(), 4 * 5 * 4 + 25 * 4 + 25 * 4);
DebugPrint(*intermedSnap, "Intermed (at time of creation)");
CheckSnap(*intermedSnap, intermedCanonized);
diff --git a/ydb/core/blobstorage/vdisk/hulldb/fresh/ya.make b/ydb/core/blobstorage/vdisk/hulldb/fresh/ya.make
index 25939cb7cdc..aef0755cb34 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/fresh/ya.make
+++ b/ydb/core/blobstorage/vdisk/hulldb/fresh/ya.make
@@ -13,13 +13,13 @@ PEERDIR(
SRCS(
defs.h
- fresh_appendix.cpp
+ fresh_appendix.cpp
fresh_appendix.h
- fresh_data.cpp
+ fresh_data.cpp
fresh_data.h
- fresh_datasnap.cpp
+ fresh_datasnap.cpp
fresh_datasnap.h
- fresh_segment.cpp
+ fresh_segment.cpp
fresh_segment.h
fresh_segment_impl.h
snap_vec.h
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hulldatamerger.h b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hulldatamerger.h
index d079669cc3d..43d104946f0 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hulldatamerger.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hulldatamerger.h
@@ -48,25 +48,25 @@ namespace NKikimr {
ui32 GetInplacedSize() const {
Y_VERIFY_DEBUG(HugeBlobMerger.Empty() || DiskBlobMerger.Empty());
- return HugeBlobMerger.Empty() ? DiskBlobMerger.GetDiskBlob().GetSize() : 0;
+ return HugeBlobMerger.Empty() ? DiskBlobMerger.GetDiskBlob().GetSize() : 0;
}
void AddHugeBlob(const TDiskPart *begin, const TDiskPart *end, const NMatrix::TVectorType &parts,
ui64 circaLsn) {
- Y_VERIFY_DEBUG(DiskBlobMerger.Empty());
+ Y_VERIFY_DEBUG(DiskBlobMerger.Empty());
HugeBlobMerger.Add(begin, end, parts, circaLsn);
}
void AddBlob(const TDiskBlob &addBlob) {
- Y_VERIFY_DEBUG(HugeBlobMerger.Empty());
+ Y_VERIFY_DEBUG(HugeBlobMerger.Empty());
DiskBlobMerger.Add(addBlob);
}
- void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& iter) {
- Y_VERIFY_DEBUG(HugeBlobMerger.Empty());
- DiskBlobMerger.AddPart(source, iter);
- }
-
+ void AddPart(const TDiskBlob& source, const TDiskBlob::TPartIterator& iter) {
+ Y_VERIFY_DEBUG(HugeBlobMerger.Empty());
+ DiskBlobMerger.AddPart(source, iter);
+ }
+
void SetEmptyFromAnotherMerger(const TDataMerger *dataMerger) {
DiskBlobMerger.Clear();
HugeBlobMerger.SetEmptyFromAnotherMerger(&dataMerger->HugeBlobMerger);
@@ -78,7 +78,7 @@ namespace NKikimr {
ui32 GetDiskBlobRawSize() const {
Y_VERIFY_DEBUG(!DiskBlobMerger.Empty());
- return DiskBlobMerger.GetDiskBlob().GetSize();
+ return DiskBlobMerger.GetDiskBlob().GetSize();
}
const TDiskBlobMerger &GetDiskBlobMerger() const {
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullrecmerger.h b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullrecmerger.h
index 76654ea7aa9..7cd6cfc056d 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullrecmerger.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullrecmerger.h
@@ -47,12 +47,12 @@ namespace NKikimr {
Finished = false;
}
- void AddBasic(const TMemRec &memRec, const TKey &key) {
+ void AddBasic(const TMemRec &memRec, const TKey &key) {
if (MemRecsMerged == 0) {
MemRec = memRec;
MemRec.SetNoBlob();
} else {
- MemRec.Merge(memRec, key);
+ MemRec.Merge(memRec, key);
}
++MemRecsMerged;
}
@@ -88,7 +88,7 @@ namespace NKikimr {
AddBasic(memRec, key);
}
- void AddFromFresh(const TMemRec &memRec, const TRope* /*data*/, const TKey &key, ui64 /*lsn*/) {
+ void AddFromFresh(const TMemRec &memRec, const TRope* /*data*/, const TKey &key, ui64 /*lsn*/) {
AddBasic(memRec, key);
}
@@ -100,14 +100,14 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
- // TCompactRecordMergerBase
+ // TCompactRecordMergerBase
////////////////////////////////////////////////////////////////////////////
// Valid call sequence:
- // Clear(); Add(); ... Add(); Finish()
+ // Clear(); Add(); ... Add(); Finish()
// GetMemRec(); GetData();
template <class TKey, class TMemRec>
- class TCompactRecordMergerBase : public TRecordMergerBase<TKey, TMemRec> {
- protected:
+ class TCompactRecordMergerBase : public TRecordMergerBase<TKey, TMemRec> {
+ protected:
using TBase = TRecordMergerBase<TKey, TMemRec>;
using TBase::MemRec;
using TBase::GType;
@@ -126,14 +126,14 @@ namespace NKikimr {
TCompactRecordMergerBase(const TBlobStorageGroupType &gtype)
: TBase(gtype, true)
, MemRecs()
- , ProducingSmallBlob(false)
+ , ProducingSmallBlob(false)
, NeedToLoadData(ELoadData::NotSet)
{}
void Clear() {
TBase::Clear();
MemRecs.clear();
- ProducingSmallBlob = false;
+ ProducingSmallBlob = false;
NeedToLoadData = ELoadData::NotSet;
DataMerger.Clear();
}
@@ -152,13 +152,13 @@ namespace NKikimr {
case TBlobType::DiskBlob: {
if (memRec.HasData() && NeedToLoadData == ELoadData::LoadData) {
MemRecs.push_back(memRec);
- ProducingSmallBlob = true;
+ ProducingSmallBlob = true;
}
break;
}
case TBlobType::HugeBlob:
case TBlobType::ManyHugeBlobs: {
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
memRec.GetDiskData(&extr, outbound);
const NMatrix::TVectorType v = memRec.GetLocalParts(GType);
DataMerger.AddHugeBlob(extr.Begin, extr.End, v, circaLsn);
@@ -167,83 +167,83 @@ namespace NKikimr {
default:
Y_FAIL("Impossible case");
}
- VerifyConsistency(memRec, outbound);
+ VerifyConsistency(memRec, outbound);
}
- void AddFromFresh(const TMemRec &memRec, const TRope *data, const TKey &key, ui64 lsn) {
+ void AddFromFresh(const TMemRec &memRec, const TRope *data, const TKey &key, ui64 lsn) {
Y_VERIFY_DEBUG(NeedToLoadData != ELoadData::NotSet);
- AddBasic(memRec, key);
+ AddBasic(memRec, key);
if (memRec.HasData()) {
if (data) {
Y_VERIFY(memRec.GetType() == TBlobType::MemBlob || memRec.GetType() == TBlobType::DiskBlob);
if (NeedToLoadData == ELoadData::LoadData) {
- DataMerger.AddBlob(TDiskBlob(data, memRec.GetLocalParts(GType), GType, key.LogoBlobID()));
- ProducingSmallBlob = true;
+ DataMerger.AddBlob(TDiskBlob(data, memRec.GetLocalParts(GType), GType, key.LogoBlobID()));
+ ProducingSmallBlob = true;
} else {
// intentionally do nothing: don't add any data to DataMerger, because we don't need it
}
} else {
Y_VERIFY(memRec.GetType() == TBlobType::HugeBlob);
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
memRec.GetDiskData(&extr, nullptr);
const NMatrix::TVectorType v = memRec.GetLocalParts(GType);
DataMerger.AddHugeBlob(extr.Begin, extr.End, v, lsn);
}
}
- VerifyConsistency(memRec, nullptr);
- }
-
- void VerifyConsistency(const TMemRec& memRec, const TDiskPart *outbound) {
-#ifdef NDEBUG
- return;
-#endif
- if constexpr (std::is_same_v<TMemRec, TMemRecLogoBlob>) {
- if (const auto m = memRec.GetType(); m == TBlobType::HugeBlob || m == TBlobType::ManyHugeBlobs) {
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, outbound);
- Y_VERIFY(extr.End - extr.Begin == memRec.GetIngress().LocalParts(GType).CountBits());
- }
- switch (memRec.GetType()) {
- case TBlobType::DiskBlob:
- Y_VERIFY(!memRec.HasData() || DataMerger.GetHugeBlobMerger().Empty());
- break;
-
- case TBlobType::HugeBlob:
- case TBlobType::ManyHugeBlobs:
- Y_VERIFY(memRec.HasData() && DataMerger.GetDiskBlobMerger().Empty());
- break;
-
- case TBlobType::MemBlob:
- Y_VERIFY(memRec.HasData() && DataMerger.GetHugeBlobMerger().Empty());
- break;
- }
- VerifyConsistency();
- }
- }
-
- void VerifyConsistency() {
- if constexpr (std::is_same_v<TMemRec, TMemRecLogoBlob>) {
- Y_VERIFY_DEBUG(DataMerger.GetHugeBlobMerger().Empty() || MemRec.GetIngress().LocalParts(GType).CountBits() ==
- DataMerger.GetHugeBlobMerger().GetNumParts());
- }
+ VerifyConsistency(memRec, nullptr);
}
+ void VerifyConsistency(const TMemRec& memRec, const TDiskPart *outbound) {
+#ifdef NDEBUG
+ return;
+#endif
+ if constexpr (std::is_same_v<TMemRec, TMemRecLogoBlob>) {
+ if (const auto m = memRec.GetType(); m == TBlobType::HugeBlob || m == TBlobType::ManyHugeBlobs) {
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, outbound);
+ Y_VERIFY(extr.End - extr.Begin == memRec.GetIngress().LocalParts(GType).CountBits());
+ }
+ switch (memRec.GetType()) {
+ case TBlobType::DiskBlob:
+ Y_VERIFY(!memRec.HasData() || DataMerger.GetHugeBlobMerger().Empty());
+ break;
+
+ case TBlobType::HugeBlob:
+ case TBlobType::ManyHugeBlobs:
+ Y_VERIFY(memRec.HasData() && DataMerger.GetDiskBlobMerger().Empty());
+ break;
+
+ case TBlobType::MemBlob:
+ Y_VERIFY(memRec.HasData() && DataMerger.GetHugeBlobMerger().Empty());
+ break;
+ }
+ VerifyConsistency();
+ }
+ }
+
+ void VerifyConsistency() {
+ if constexpr (std::is_same_v<TMemRec, TMemRecLogoBlob>) {
+ Y_VERIFY_DEBUG(DataMerger.GetHugeBlobMerger().Empty() || MemRec.GetIngress().LocalParts(GType).CountBits() ==
+ DataMerger.GetHugeBlobMerger().GetNumParts());
+ }
+ }
+
void Finish() {
Y_VERIFY_DEBUG(!Empty());
- VerifyConsistency();
+ VerifyConsistency();
- // in case when we keep data and disk merger contains small blobs, we set up small blob record -- this logic
- // is used in replication and in fresh compaction
- if (NeedToLoadData == ELoadData::LoadData && DataMerger.HasSmallBlobs()) {
- TDiskPart addr(0, 0, DataMerger.GetDiskBlobRawSize());
- MemRec.SetDiskBlob(addr);
+ // in case when we keep data and disk merger contains small blobs, we set up small blob record -- this logic
+ // is used in replication and in fresh compaction
+ if (NeedToLoadData == ELoadData::LoadData && DataMerger.HasSmallBlobs()) {
+ TDiskPart addr(0, 0, DataMerger.GetDiskBlobRawSize());
+ MemRec.SetDiskBlob(addr);
}
-
- // clear local bits if we are not going to keep item's data
- if (NeedToLoadData == ELoadData::DontLoadData) {
+
+ // clear local bits if we are not going to keep item's data
+ if (NeedToLoadData == ELoadData::DontLoadData) {
MemRec.ClearLocalParts(GType);
- }
-
+ }
+
Finished = true;
MemRec.SetType(DataMerger.GetType());
}
@@ -253,9 +253,9 @@ namespace NKikimr {
return &DataMerger;
}
- protected:
+ protected:
TStackVec<TMemRec, 16> MemRecs;
- bool ProducingSmallBlob;
+ bool ProducingSmallBlob;
ELoadData NeedToLoadData;
TDataMerger DataMerger;
};
@@ -263,107 +263,107 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TCompactRecordMergerIndexPass
////////////////////////////////////////////////////////////////////////////
- template<typename TKey, typename TMemRec>
- class TCompactRecordMergerIndexPass : public TCompactRecordMergerBase<TKey, TMemRec> {
- using TBase = TCompactRecordMergerBase<TKey, TMemRec>;
+ template<typename TKey, typename TMemRec>
+ class TCompactRecordMergerIndexPass : public TCompactRecordMergerBase<TKey, TMemRec> {
+ using TBase = TCompactRecordMergerBase<TKey, TMemRec>;
- using ELoadData = typename TBase::ELoadData;
+ using ELoadData = typename TBase::ELoadData;
using TBase::MemRecs;
- using TBase::ProducingSmallBlob;
- using TBase::NeedToLoadData;
- using TBase::DataMerger;
- using TBase::MemRec;
-
- public:
+ using TBase::ProducingSmallBlob;
+ using TBase::NeedToLoadData;
+ using TBase::DataMerger;
+ using TBase::MemRec;
+
+ public:
TCompactRecordMergerIndexPass(const TBlobStorageGroupType &gtype)
: TBase(gtype)
- {}
-
- void Finish() {
- if (NeedToLoadData == ELoadData::DontLoadData) {
- Y_VERIFY(!DataMerger.HasSmallBlobs()); // we didn't put any small blob to the data merger
- // if we have huge blobs for the record, than we set TBlobType::HugeBlob or
- // TBlobType::ManyHugeBlobs a few lines below
- MemRec.SetNoBlob();
- }
-
- TBase::Finish();
- }
-
- template<typename TCallback>
- void ForEachSmallDiskBlob(TCallback&& callback) {
+ {}
+
+ void Finish() {
+ if (NeedToLoadData == ELoadData::DontLoadData) {
+ Y_VERIFY(!DataMerger.HasSmallBlobs()); // we didn't put any small blob to the data merger
+ // if we have huge blobs for the record, than we set TBlobType::HugeBlob or
+ // TBlobType::ManyHugeBlobs a few lines below
+ MemRec.SetNoBlob();
+ }
+
+ TBase::Finish();
+ }
+
+ template<typename TCallback>
+ void ForEachSmallDiskBlob(TCallback&& callback) {
for (const auto& memRec : MemRecs) {
callback(memRec);
- }
- }
- };
-
+ }
+ }
+ };
+
////////////////////////////////////////////////////////////////////////////
// TCompactRecordMergerDataPass
////////////////////////////////////////////////////////////////////////////
- template<typename TKey, typename TMemRec>
- class TCompactRecordMergerDataPass : public TCompactRecordMergerBase<TKey, TMemRec> {
- using TBase = TCompactRecordMergerBase<TKey, TMemRec>;
-
- using TBase::ProducingSmallBlob;
+ template<typename TKey, typename TMemRec>
+ class TCompactRecordMergerDataPass : public TCompactRecordMergerBase<TKey, TMemRec> {
+ using TBase = TCompactRecordMergerBase<TKey, TMemRec>;
+
+ using TBase::ProducingSmallBlob;
using TBase::MemRecs;
- using TBase::MemRec;
- using TBase::DataMerger;
+ using TBase::MemRec;
+ using TBase::DataMerger;
using TBase::GType;
- using TBase::SetLoadDataMode;
-
- public:
+ using TBase::SetLoadDataMode;
+
+ public:
TCompactRecordMergerDataPass(const TBlobStorageGroupType &gtype)
: TBase(gtype)
- {
- SetLoadDataMode(true);
- }
-
- void Clear() {
- TBase::Clear();
- ReadSmallBlobs.clear();
- SetLoadDataMode(true);
- }
-
- // add read small blob content; they should come in order as returned from GetSmallBlobDiskParts by index merger
+ {
+ SetLoadDataMode(true);
+ }
+
+ void Clear() {
+ TBase::Clear();
+ ReadSmallBlobs.clear();
+ SetLoadDataMode(true);
+ }
+
+ // add read small blob content; they should come in order as returned from GetSmallBlobDiskParts by index merger
void AddReadSmallBlob(TString data) {
- Y_VERIFY(ProducingSmallBlob);
- ReadSmallBlobs.push_back(std::move(data));
- }
-
- void Finish() {
- // ensure we are producing small blobs; otherwise this merger should never be created
- Y_VERIFY(ProducingSmallBlob);
-
- // add all read small blobs into blob merger
+ Y_VERIFY(ProducingSmallBlob);
+ ReadSmallBlobs.push_back(std::move(data));
+ }
+
+ void Finish() {
+ // ensure we are producing small blobs; otherwise this merger should never be created
+ Y_VERIFY(ProducingSmallBlob);
+
+ // add all read small blobs into blob merger
const size_t count = ReadSmallBlobs.size();
Y_VERIFY(count == +MemRecs, "count# %zu +MemRecs# %zu", count, +MemRecs);
- for (size_t i = 0; i < count; ++i) {
+ for (size_t i = 0; i < count; ++i) {
const TMemRec& memRec = MemRecs[i]->GetMemRec();
const TString& buffer = ReadSmallBlobs[i];
Y_VERIFY(buffer.size() == memRec.DataSize());
DataMerger.AddBlob(TDiskBlob(buffer.data(), buffer.size(), memRec.GetLocalParts(GType)));
- }
-
-
- // ensure that data merger has small blob
- Y_VERIFY(DataMerger.HasSmallBlobs());
-
- // finalize base class logic; it also generates blob record
- TBase::Finish();
-
- // ensure that we have generated correct DiskBlob with full set of declared parts
- const TDiskBlob& blob = DataMerger.GetDiskBlobMerger().GetDiskBlob();
+ }
+
+
+ // ensure that data merger has small blob
+ Y_VERIFY(DataMerger.HasSmallBlobs());
+
+ // finalize base class logic; it also generates blob record
+ TBase::Finish();
+
+ // ensure that we have generated correct DiskBlob with full set of declared parts
+ const TDiskBlob& blob = DataMerger.GetDiskBlobMerger().GetDiskBlob();
Y_VERIFY(blob.GetParts() == MemRec.GetLocalParts(GType));
- Y_VERIFY(MemRec.GetType() == TBlobType::DiskBlob);
- }
-
- private:
+ Y_VERIFY(MemRec.GetType() == TBlobType::DiskBlob);
+ }
+
+ private:
TVector<TString> ReadSmallBlobs;
- };
-
-
+ };
+
+
////////////////////////////////////////////////////////////////////////////
// TRecordMergerCallback
////////////////////////////////////////////////////////////////////////////
@@ -392,7 +392,7 @@ namespace NKikimr {
void AddFromSegment(const TMemRec &memRec, const TDiskPart *outbound, const TKey &key, ui64 circaLsn) {
AddBasic(memRec, key);
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
memRec.GetDiskData(&extr, outbound);
const NMatrix::TVectorType v = memRec.GetLocalParts(GType);
ui32 n = extr.End - extr.Begin;
@@ -433,8 +433,8 @@ namespace NKikimr {
}
}
- void AddFromFresh(const TMemRec &memRec, const TRope *data, const TKey &key, ui64 lsn) {
- AddBasic(memRec, key);
+ void AddFromFresh(const TMemRec &memRec, const TRope *data, const TKey &key, ui64 lsn) {
+ AddBasic(memRec, key);
if (memRec.HasData()) {
const NMatrix::TVectorType v = memRec.GetLocalParts(GType);
if (data) {
@@ -445,7 +445,7 @@ namespace NKikimr {
(*Callback)(TDiskBlob(data, v, GType, key.LogoBlobID()));
} else {
Y_VERIFY(memRec.GetType() == TBlobType::HugeBlob && v.CountBits() == 1u);
- TDiskDataExtractor extr;
+ TDiskDataExtractor extr;
memRec.GetDiskData(&extr, nullptr);
// deduplicate huge blob
LastWriteWinsMerger.Add(extr.SwearOne(), v, lsn);
@@ -464,36 +464,36 @@ namespace NKikimr {
public:
TLastWriteWins(ui8 vecSize)
: ResParts(0, vecSize)
- {}
+ {}
void Add(const TDiskPart &diskPart, NMatrix::TVectorType v, ui64 circaLsn) {
Y_VERIFY_DEBUG(v.CountBits() == 1u);
- const ui8 idx = v.FirstPosition();
- TResItem& item = Res[idx];
- if (item.CircaLsn < circaLsn) {
- item = {circaLsn, diskPart};
+ const ui8 idx = v.FirstPosition();
+ TResItem& item = Res[idx];
+ if (item.CircaLsn < circaLsn) {
+ item = {circaLsn, diskPart};
}
- ResParts.Set(idx);
+ ResParts.Set(idx);
}
void Finish(TCallback *callback) {
for (ui8 i = ResParts.FirstPosition(); i != ResParts.GetSize(); i = ResParts.NextPosition(i)) {
- (*callback)(Res[i].Part, NMatrix::TVectorType::MakeOneHot(i, ResParts.GetSize()));
+ (*callback)(Res[i].Part, NMatrix::TVectorType::MakeOneHot(i, ResParts.GetSize()));
}
}
void Clear() {
- Res.fill(TResItem());
+ Res.fill(TResItem());
ResParts.Clear();
}
private:
- struct TResItem {
+ struct TResItem {
ui64 CircaLsn = 0;
- TDiskPart Part;
- };
+ TDiskPart Part;
+ };
NMatrix::TVectorType ResParts;
- std::array<TResItem, 8> Res;
+ std::array<TResItem, 8> Res;
};
TCallback *Callback;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h
index 930fce08e65..15b25f9905a 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h
@@ -6,27 +6,27 @@
#include <ydb/core/blobstorage/vdisk/common/align.h>
#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk.h>
-#include <util/generic/queue.h>
-
+#include <util/generic/queue.h>
+
namespace NKikimr {
- class TBufferedChunkWriter;
-
- enum class EWriterDataType {
- Fresh,
- Comp,
- Replication
- };
-
- inline const TMemoryConsumer& WriterDataTypeToMemConsumer(const TVDiskContextPtr& vctx, EWriterDataType type, bool data) {
- switch (type) {
- case EWriterDataType::Fresh: return data ? vctx->CompDataFresh : vctx->CompIndexFresh;
- case EWriterDataType::Comp: return data ? vctx->CompData : vctx->CompIndex;
- case EWriterDataType::Replication: return vctx->Replication;
+ class TBufferedChunkWriter;
+
+ enum class EWriterDataType {
+ Fresh,
+ Comp,
+ Replication
+ };
+
+ inline const TMemoryConsumer& WriterDataTypeToMemConsumer(const TVDiskContextPtr& vctx, EWriterDataType type, bool data) {
+ switch (type) {
+ case EWriterDataType::Fresh: return data ? vctx->CompDataFresh : vctx->CompIndexFresh;
+ case EWriterDataType::Comp: return data ? vctx->CompData : vctx->CompIndex;
+ case EWriterDataType::Replication: return vctx->Replication;
default: Y_FAIL("incorrect EWriterDataType provided");
- }
- }
-
+ }
+ }
+
inline ui8 EWriterDataTypeToPriority(EWriterDataType t) {
switch (t) {
case EWriterDataType::Fresh: return NPriWrite::HullFresh;
@@ -36,116 +36,116 @@ namespace NKikimr {
}
}
- class TBufferedChunkWriter : public TThrRefBase {
- public:
+ class TBufferedChunkWriter : public TThrRefBase {
+ public:
TBufferedChunkWriter(TMemoryConsumer&& consumer, ui8 owner, ui64 ownerRound, ui8 priority, ui32 chunkSize,
- ui32 appendBlockSize, ui32 writeBlockSize, ui32 chunkIdx,
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue)
- : Consumer(std::move(consumer))
- , Owner(owner)
+ ui32 appendBlockSize, ui32 writeBlockSize, ui32 chunkIdx,
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue)
+ : Consumer(std::move(consumer))
+ , Owner(owner)
, OwnerRound(ownerRound)
, Priority(priority)
- , ChunkSize(chunkSize)
- , AppendBlockSize(appendBlockSize)
- , WriteBlockSize(writeBlockSize - writeBlockSize % appendBlockSize)
- , ChunkIdx(chunkIdx)
- , Offset(0)
- , Buffer(TMemoryConsumer(Consumer))
- , MsgQueue(msgQueue)
- , DiskPartOffset(0)
- , Finished(false)
- , HasBuffer(false)
- {
- Y_VERIFY(chunkIdx != 0);
- }
-
- void Push(const void *data, size_t len) {
+ , ChunkSize(chunkSize)
+ , AppendBlockSize(appendBlockSize)
+ , WriteBlockSize(writeBlockSize - writeBlockSize % appendBlockSize)
+ , ChunkIdx(chunkIdx)
+ , Offset(0)
+ , Buffer(TMemoryConsumer(Consumer))
+ , MsgQueue(msgQueue)
+ , DiskPartOffset(0)
+ , Finished(false)
+ , HasBuffer(false)
+ {
+ Y_VERIFY(chunkIdx != 0);
+ }
+
+ void Push(const void *data, size_t len) {
Y_VERIFY(Offset + len <= ChunkSize && !Finished);
-
- while (len) {
- if (!HasBuffer) {
- TTrackableBuffer newBuffer(TMemoryConsumer(Consumer), WriteBlockSize);
- Buffer.Swap(newBuffer);
- HasBuffer = true;
- }
-
- size_t bytes = Min(len, WriteBlockSize - Buffer.Size());
- const char *ptr = static_cast<const char *>(data);
- Buffer.Append(ptr, bytes);
- data = ptr + bytes;
- len -= bytes;
- Offset += bytes;
-
- if (Buffer.Size() == WriteBlockSize || Offset == ChunkSize) {
- CreateChunkWriteMsg();
- }
- }
- }
-
- void FinishChunk() {
+
+ while (len) {
+ if (!HasBuffer) {
+ TTrackableBuffer newBuffer(TMemoryConsumer(Consumer), WriteBlockSize);
+ Buffer.Swap(newBuffer);
+ HasBuffer = true;
+ }
+
+ size_t bytes = Min(len, WriteBlockSize - Buffer.Size());
+ const char *ptr = static_cast<const char *>(data);
+ Buffer.Append(ptr, bytes);
+ data = ptr + bytes;
+ len -= bytes;
+ Offset += bytes;
+
+ if (Buffer.Size() == WriteBlockSize || Offset == ChunkSize) {
+ CreateChunkWriteMsg();
+ }
+ }
+ }
+
+ void FinishChunk() {
Y_VERIFY(!Finished);
- Finished = true;
-
- if (Offset == ChunkSize)
- return;
-
- size_t sizeBeforeAlign = Buffer.Size();
- AlignUpAppendBlockSize(Buffer, AppendBlockSize);
- Offset += Buffer.Size() - sizeBeforeAlign;
-
- CreateChunkWriteMsg();
- }
-
- ui32 GetFreeSpace() const {
- return ChunkSize - Offset;
- }
-
- ui32 GetChunkIdx() const {
- return ChunkIdx;
- }
-
- void SetBookmark() {
- DiskPartOffset = Offset;
- }
-
- TDiskPart GetDiskPartForBookmark() const {
- return {ChunkIdx, DiskPartOffset, Offset - DiskPartOffset};
- }
-
- ui32 GetBlockSize() const {
- return WriteBlockSize;
- }
-
- private:
- void CreateChunkWriteMsg() {
- if (Buffer.Size()) {
- ui32 offsetInChunk = Offset - Buffer.Size();
- Y_VERIFY(offsetInChunk % AppendBlockSize == 0);
- Y_VERIFY(ChunkIdx);
+ Finished = true;
+
+ if (Offset == ChunkSize)
+ return;
+
+ size_t sizeBeforeAlign = Buffer.Size();
+ AlignUpAppendBlockSize(Buffer, AppendBlockSize);
+ Offset += Buffer.Size() - sizeBeforeAlign;
+
+ CreateChunkWriteMsg();
+ }
+
+ ui32 GetFreeSpace() const {
+ return ChunkSize - Offset;
+ }
+
+ ui32 GetChunkIdx() const {
+ return ChunkIdx;
+ }
+
+ void SetBookmark() {
+ DiskPartOffset = Offset;
+ }
+
+ TDiskPart GetDiskPartForBookmark() const {
+ return {ChunkIdx, DiskPartOffset, Offset - DiskPartOffset};
+ }
+
+ ui32 GetBlockSize() const {
+ return WriteBlockSize;
+ }
+
+ private:
+ void CreateChunkWriteMsg() {
+ if (Buffer.Size()) {
+ ui32 offsetInChunk = Offset - Buffer.Size();
+ Y_VERIFY(offsetInChunk % AppendBlockSize == 0);
+ Y_VERIFY(ChunkIdx);
NPDisk::TEvChunkWrite::TPartsPtr parts(new NPDisk::TEvChunkWrite::TBufBackedUpParts(std::move(Buffer)));
- auto ev = std::make_unique<NPDisk::TEvChunkWrite>(Owner, OwnerRound, ChunkIdx, offsetInChunk, parts, nullptr, true, Priority);
- MsgQueue.push(std::move(ev));
- HasBuffer = false;
- }
- }
-
- private:
- TMemoryConsumer Consumer;
- const ui8 Owner;
+ auto ev = std::make_unique<NPDisk::TEvChunkWrite>(Owner, OwnerRound, ChunkIdx, offsetInChunk, parts, nullptr, true, Priority);
+ MsgQueue.push(std::move(ev));
+ HasBuffer = false;
+ }
+ }
+
+ private:
+ TMemoryConsumer Consumer;
+ const ui8 Owner;
const ui64 OwnerRound;
const ui8 Priority;
- const ui32 ChunkSize;
- const ui32 AppendBlockSize;
- const ui32 WriteBlockSize;
- ui32 ChunkIdx;
- ui32 Offset;
- TTrackableBuffer Buffer;
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
- ui32 DiskPartOffset;
- bool Finished;
- bool HasBuffer;
- };
-
+ const ui32 ChunkSize;
+ const ui32 AppendBlockSize;
+ const ui32 WriteBlockSize;
+ ui32 ChunkIdx;
+ ui32 Offset;
+ TTrackableBuffer Buffer;
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
+ ui32 DiskPartOffset;
+ bool Finished;
+ bool HasBuffer;
+ };
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// TLevelSegment<TKey, TMemRec>::TBaseWriter
///////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -154,134 +154,134 @@ namespace NKikimr {
class TLevelSegment<TKey, TMemRec>::TBaseWriter {
public:
TBaseWriter(TMemoryConsumer&& consumer, ui8 owner, ui64 ownerRound, ui8 priority, ui32 chunkSize,
- ui32 appendBlockSize, ui32 writeBlockSize, TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue,
+ ui32 appendBlockSize, ui32 writeBlockSize, TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue,
TDeque<TChunkIdx>& rchunks)
- : Consumer(std::move(consumer))
+ : Consumer(std::move(consumer))
, Owner(owner)
, OwnerRound(ownerRound)
, Priority(priority)
, ChunkSize(chunkSize)
, AppendBlockSize(appendBlockSize)
- , WriteBlockSize(writeBlockSize)
- , MsgQueue(msgQueue)
- , RChunks(rchunks)
+ , WriteBlockSize(writeBlockSize)
+ , MsgQueue(msgQueue)
+ , RChunks(rchunks)
, UsedChunks()
{}
const TVector<ui32> &GetUsedChunks() const {
- return UsedChunks;
- }
-
- template<typename TChunkGenerator>
- TMaybe<TDiskPart> AppendAlignedImpl(TChunkGenerator&& generator, size_t len) {
- if (!ChunkWriter) {
- Y_VERIFY(!RChunks.empty());
- const TChunkIdx chunkIdx = RChunks.front();
- RChunks.pop_front();
-
- ChunkWriter = std::make_unique<TBufferedChunkWriter>(TMemoryConsumer(Consumer), Owner, OwnerRound,
- Priority, ChunkSize, AppendBlockSize, WriteBlockSize, chunkIdx, MsgQueue);
-
- UsedChunks.push_back(chunkIdx);
- }
-
- ui32 alignedLen = AlignUp<ui32>(len, 4);
- if (ChunkWriter->GetFreeSpace() < alignedLen)
- return TMaybe<TDiskPart>();
-
- ChunkWriter->SetBookmark();
- while (TMaybe<std::pair<const char*, size_t>> block = generator()) {
- ChunkWriter->Push(block->first, block->second);
- }
- TDiskPart result = ChunkWriter->GetDiskPartForBookmark();
- static const char padding[3] = {0, 0, 0};
+ return UsedChunks;
+ }
+
+ template<typename TChunkGenerator>
+ TMaybe<TDiskPart> AppendAlignedImpl(TChunkGenerator&& generator, size_t len) {
+ if (!ChunkWriter) {
+ Y_VERIFY(!RChunks.empty());
+ const TChunkIdx chunkIdx = RChunks.front();
+ RChunks.pop_front();
+
+ ChunkWriter = std::make_unique<TBufferedChunkWriter>(TMemoryConsumer(Consumer), Owner, OwnerRound,
+ Priority, ChunkSize, AppendBlockSize, WriteBlockSize, chunkIdx, MsgQueue);
+
+ UsedChunks.push_back(chunkIdx);
+ }
+
+ ui32 alignedLen = AlignUp<ui32>(len, 4);
+ if (ChunkWriter->GetFreeSpace() < alignedLen)
+ return TMaybe<TDiskPart>();
+
+ ChunkWriter->SetBookmark();
+ while (TMaybe<std::pair<const char*, size_t>> block = generator()) {
+ ChunkWriter->Push(block->first, block->second);
+ }
+ TDiskPart result = ChunkWriter->GetDiskPartForBookmark();
+ static const char padding[3] = {0, 0, 0};
Y_VERIFY_DEBUG(alignedLen - len <= 3);
- ChunkWriter->Push(padding, alignedLen - len);
-
- return result;
- }
-
- TMaybe<TDiskPart> AppendAligned(const char *buffer, size_t len) {
- struct TGenerator {
- const char *Buffer;
- size_t Len;
-
- TMaybe<std::pair<const char*, size_t>> operator ()() {
- if (Buffer) {
- auto res = std::make_pair(Buffer, Len);
- Buffer = nullptr;
- return res;
- } else {
- return {};
- }
- }
- } generator{buffer, len};
- return AppendAlignedImpl(generator, len);
- }
-
- TMaybe<TDiskPart> AppendAligned(const TRope& data) {
- struct TGenerator {
- TRope::TConstIterator Iter;
-
- TMaybe<std::pair<const char*, size_t>> operator ()() {
- if (Iter.Valid()) {
- auto res = std::make_pair(Iter.ContiguousData(), Iter.ContiguousSize());
- Iter.AdvanceToNextContiguousBlock();
- return res;
- } else {
- return {};
- }
- }
- } generator{data.Begin()};
- return AppendAlignedImpl(generator, data.GetSize());
- }
-
- ui32 ChunkOffset() const {
- return ChunkSize - (ChunkWriter ? ChunkWriter->GetFreeSpace() : 0);
- }
-
- void FinishChunk() {
- ChunkWriter->FinishChunk();
- ChunkWriter.reset();
- }
-
+ ChunkWriter->Push(padding, alignedLen - len);
+
+ return result;
+ }
+
+ TMaybe<TDiskPart> AppendAligned(const char *buffer, size_t len) {
+ struct TGenerator {
+ const char *Buffer;
+ size_t Len;
+
+ TMaybe<std::pair<const char*, size_t>> operator ()() {
+ if (Buffer) {
+ auto res = std::make_pair(Buffer, Len);
+ Buffer = nullptr;
+ return res;
+ } else {
+ return {};
+ }
+ }
+ } generator{buffer, len};
+ return AppendAlignedImpl(generator, len);
+ }
+
+ TMaybe<TDiskPart> AppendAligned(const TRope& data) {
+ struct TGenerator {
+ TRope::TConstIterator Iter;
+
+ TMaybe<std::pair<const char*, size_t>> operator ()() {
+ if (Iter.Valid()) {
+ auto res = std::make_pair(Iter.ContiguousData(), Iter.ContiguousSize());
+ Iter.AdvanceToNextContiguousBlock();
+ return res;
+ } else {
+ return {};
+ }
+ }
+ } generator{data.Begin()};
+ return AppendAlignedImpl(generator, data.GetSize());
+ }
+
+ ui32 ChunkOffset() const {
+ return ChunkSize - (ChunkWriter ? ChunkWriter->GetFreeSpace() : 0);
+ }
+
+ void FinishChunk() {
+ ChunkWriter->FinishChunk();
+ ChunkWriter.reset();
+ }
+
protected:
- TMemoryConsumer Consumer;
+ TMemoryConsumer Consumer;
const ui8 Owner;
const ui64 OwnerRound;
const ui8 Priority;
const ui32 ChunkSize;
const ui32 AppendBlockSize;
- const ui32 WriteBlockSize;
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
+ const ui32 WriteBlockSize;
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
TDeque<ui32>& RChunks;
TVector<ui32> UsedChunks;
- std::unique_ptr<TBufferedChunkWriter> ChunkWriter;
+ std::unique_ptr<TBufferedChunkWriter> ChunkWriter;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// TDataWriterConclusion
///////////////////////////////////////////////////////////////////////////////////////////////////////////
struct TDataWriterConclusion {
- std::unique_ptr<TBufferedChunkWriter> Writer;
+ std::unique_ptr<TBufferedChunkWriter> Writer;
TVector<ui32> UsedChunks;
- TDataWriterConclusion(std::unique_ptr<TBufferedChunkWriter>&& writer, TVector<ui32>&& usedChunks)
- : Writer(std::move(writer))
- , UsedChunks(std::move(usedChunks))
+ TDataWriterConclusion(std::unique_ptr<TBufferedChunkWriter>&& writer, TVector<ui32>&& usedChunks)
+ : Writer(std::move(writer))
+ , UsedChunks(std::move(usedChunks))
{}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// TIndexWriterConclusion
///////////////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename TKey, typename TMemRec>
+ template<typename TKey, typename TMemRec>
struct TIndexWriterConclusion {
TVector<ui32> UsedChunks;
TDiskPart Addr; // entry point
ui32 IndexParts = 0;
ui32 OutboundItems = 0;
- TIntrusivePtr<TLevelSegment<TKey, TMemRec>> LevelSegment;
+ TIntrusivePtr<TLevelSegment<TKey, TMemRec>> LevelSegment;
TString ToString() const {
TStringStream s;
@@ -313,7 +313,7 @@ namespace NKikimr {
public:
TDataWriter(TVDiskContextPtr vctx, EWriterDataType type, ui8 owner, ui64 ownerRound, ui32 chunkSize,
- ui32 appendBlockSize, ui32 writeBlockSize, TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue,
+ ui32 appendBlockSize, ui32 writeBlockSize, TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue,
TDeque<TChunkIdx>& rchunks)
: TBase(TMemoryConsumer(WriterDataTypeToMemConsumer(vctx, type, true)),
owner,
@@ -322,54 +322,54 @@ namespace NKikimr {
chunkSize,
appendBlockSize,
writeBlockSize,
- msgQueue,
- rchunks)
+ msgQueue,
+ rchunks)
, Finished(false)
- , RChunksIndex(0)
- , Offset(0)
+ , RChunksIndex(0)
+ , Offset(0)
{}
- TDiskPart Preallocate(ui32 size) {
- const ui32 alignedSize = AlignUp(size, 4U);
- if (Offset + alignedSize > ChunkSize) {
- Offset = 0;
- ++RChunksIndex;
- Y_VERIFY(RChunksIndex < UsedChunks.size() + RChunks.size());
- }
-
+ TDiskPart Preallocate(ui32 size) {
+ const ui32 alignedSize = AlignUp(size, 4U);
+ if (Offset + alignedSize > ChunkSize) {
+ Offset = 0;
+ ++RChunksIndex;
+ Y_VERIFY(RChunksIndex < UsedChunks.size() + RChunks.size());
+ }
+
const TChunkIdx chunkIdx = RChunksIndex < UsedChunks.size() ? UsedChunks[RChunksIndex]
: RChunks[RChunksIndex - UsedChunks.size()];
- TDiskPart location(chunkIdx, Offset, size);
- Offset += alignedSize;
- return location;
- }
-
+ TDiskPart location(chunkIdx, Offset, size);
+ Offset += alignedSize;
+ return location;
+ }
+
TDiskPart Push(const TRope& buffer) {
- Y_VERIFY_DEBUG(!Finished);
+ Y_VERIFY_DEBUG(!Finished);
TMaybe<TDiskPart> result = TBase::AppendAligned(buffer);
- if (!result) {
- // there is no space to fit in current chunk -- restart base writer with new chunk
- TBase::FinishChunk();
+ if (!result) {
+ // there is no space to fit in current chunk -- restart base writer with new chunk
+ TBase::FinishChunk();
result = TBase::AppendAligned(buffer);
Y_VERIFY(result);
- }
+ }
- return *result;
+ return *result;
}
- TDataWriterConclusion Finish() {
+ TDataWriterConclusion Finish() {
Y_VERIFY(!Finished);
- const ui32 alignedOffset = AlignUpAppendBlockSize(Offset, AppendBlockSize);
- if (const size_t num = alignedOffset - Offset) {
- char *buffer = (char*)alloca(num);
- memset(buffer, 0, num);
- const TMaybe<TDiskPart> part = TBase::AppendAligned(buffer, num);
- Y_VERIFY(part);
- Y_VERIFY((part->Offset + part->Size) % AppendBlockSize == 0);
- }
+ const ui32 alignedOffset = AlignUpAppendBlockSize(Offset, AppendBlockSize);
+ if (const size_t num = alignedOffset - Offset) {
+ char *buffer = (char*)alloca(num);
+ memset(buffer, 0, num);
+ const TMaybe<TDiskPart> part = TBase::AppendAligned(buffer, num);
+ Y_VERIFY(part);
+ Y_VERIFY((part->Offset + part->Size) % AppendBlockSize == 0);
+ }
Finished = true;
- return {std::move(TBase::ChunkWriter), std::move(UsedChunks)};
+ return {std::move(TBase::ChunkWriter), std::move(UsedChunks)};
}
bool IsFinished() const {
@@ -377,27 +377,27 @@ namespace NKikimr {
}
void GetUsageAfterPush(ui32 size, ui32 *chunks, ui32 *intermSize) const {
- *chunks = RChunksIndex + (Offset ? 1 : 0);
- *intermSize = Offset ? Offset : ChunkSize;
-
- if (const ui32 alignedSize = AlignUp(size, 4U)) {
- *intermSize += alignedSize;
- if (*intermSize > ChunkSize) {
- // if we'd start a new chunk
- ++*chunks;
- *intermSize = alignedSize;
- }
+ *chunks = RChunksIndex + (Offset ? 1 : 0);
+ *intermSize = Offset ? Offset : ChunkSize;
+
+ if (const ui32 alignedSize = AlignUp(size, 4U)) {
+ *intermSize += alignedSize;
+ if (*intermSize > ChunkSize) {
+ // if we'd start a new chunk
+ ++*chunks;
+ *intermSize = alignedSize;
+ }
}
-
- *intermSize = AlignUpAppendBlockSize(*intermSize, AppendBlockSize);
+
+ *intermSize = AlignUpAppendBlockSize(*intermSize, AppendBlockSize);
}
using TBase::GetUsedChunks;
private:
bool Finished;
- ui32 RChunksIndex;
- ui32 Offset;
+ ui32 RChunksIndex;
+ ui32 Offset;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -414,36 +414,36 @@ namespace NKikimr {
public:
TIndexBuilder(TVDiskContextPtr vctx, EWriterDataType type, ui8 owner, ui64 ownerRound, ui32 chunkSize,
- ui32 appendBlockSize, ui32 writeBlockSize, ui64 sstId, bool createdByRepl,
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue, TDeque<TChunkIdx>& rchunks)
- : Consumer(TMemoryConsumer(WriterDataTypeToMemConsumer(vctx, type, false)))
+ ui32 appendBlockSize, ui32 writeBlockSize, ui64 sstId, bool createdByRepl,
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& msgQueue, TDeque<TChunkIdx>& rchunks)
+ : Consumer(TMemoryConsumer(WriterDataTypeToMemConsumer(vctx, type, false)))
, Owner(owner)
, OwnerRound(ownerRound)
, Priority(EWriterDataTypeToPriority(type))
, ChunkSize(chunkSize)
, AppendBlockSize(appendBlockSize)
- , WriteBlockSize(writeBlockSize)
- , MsgQueue(msgQueue)
- , RChunks(rchunks)
+ , WriteBlockSize(writeBlockSize)
+ , MsgQueue(msgQueue)
+ , RChunks(rchunks)
, RecsPos(0)
, OutboundPos(0)
, InplaceDataTotalSize(0)
, HugeDataTotalSize(0)
- , Items(0)
+ , Items(0)
, ItemsWithInplacedData(0)
, ItemsWithHugeData(0)
- , Recs(TMemoryConsumer(Consumer))
- , Outbound(TMemoryConsumer(Consumer))
- , SstId(sstId)
+ , Recs(TMemoryConsumer(Consumer))
+ , Outbound(TMemoryConsumer(Consumer))
+ , SstId(sstId)
, FirstLsn(0)
, LastLsn(0)
, Conclusion()
- , Finished(false)
- , CreatedByRepl(createdByRepl)
- , PendingOp(EPendingOperation::NONE)
- , NumRecsPerChunk((ChunkSize - sizeof(TIdxDiskLinker)) / sizeof(TRec))
- , NumDiskPartsPerChunk((ChunkSize - sizeof(TIdxDiskLinker)) / sizeof(TDiskPart))
- , LevelSegment(new TLevelSegment(vctx))
+ , Finished(false)
+ , CreatedByRepl(createdByRepl)
+ , PendingOp(EPendingOperation::NONE)
+ , NumRecsPerChunk((ChunkSize - sizeof(TIdxDiskLinker)) / sizeof(TRec))
+ , NumDiskPartsPerChunk((ChunkSize - sizeof(TIdxDiskLinker)) / sizeof(TDiskPart))
+ , LevelSegment(new TLevelSegment(vctx))
{
Recs.reserve(ChunkSize / sizeof(TRec)); // reserve for one chunk
}
@@ -452,61 +452,61 @@ namespace NKikimr {
return !Items;
}
- ui32 GetUsageAfterPush(ui32 chunks, ui32 intermSize, ui32 numAddedOuts) const {
- ui32 items = Items + 1; // + 1 for the record being added
- ui32 outs = Outbound.size() + numAddedOuts;
-
- // if linker record doesn't fit in current chunk, we start a new one
- if (intermSize + sizeof(TIdxDiskLinker) > ChunkSize) {
- ++chunks;
- intermSize = 0;
- }
-
- if (intermSize) {
- const ui32 numItems = (ChunkSize - (sizeof(TIdxDiskLinker) + intermSize)) / sizeof(TRec);
- if (items <= numItems) {
- intermSize += items * sizeof(TRec);
- items = 0;
- } else {
- items -= numItems;
- ++chunks;
- intermSize = 0;
- }
- }
- if (items) {
- Y_VERIFY_DEBUG(!intermSize);
- chunks += items / NumRecsPerChunk;
- intermSize += (items % NumRecsPerChunk) * sizeof(TRec);
- }
-
- if (intermSize) {
- const ui32 numOuts = (ChunkSize - (sizeof(TIdxDiskLinker) + intermSize)) / sizeof(TDiskPart);
- if (outs <= numOuts) {
- intermSize += outs * sizeof(TDiskPart);
- outs = 0;
- } else {
- outs -= numOuts;
- ++chunks;
- intermSize = 0;
- }
- }
- if (outs) {
- Y_VERIFY_DEBUG(!intermSize);
- chunks += outs / NumDiskPartsPerChunk;
- intermSize += (outs % NumDiskPartsPerChunk) * sizeof(TDiskPart);
+ ui32 GetUsageAfterPush(ui32 chunks, ui32 intermSize, ui32 numAddedOuts) const {
+ ui32 items = Items + 1; // + 1 for the record being added
+ ui32 outs = Outbound.size() + numAddedOuts;
+
+ // if linker record doesn't fit in current chunk, we start a new one
+ if (intermSize + sizeof(TIdxDiskLinker) > ChunkSize) {
+ ++chunks;
+ intermSize = 0;
+ }
+
+ if (intermSize) {
+ const ui32 numItems = (ChunkSize - (sizeof(TIdxDiskLinker) + intermSize)) / sizeof(TRec);
+ if (items <= numItems) {
+ intermSize += items * sizeof(TRec);
+ items = 0;
+ } else {
+ items -= numItems;
+ ++chunks;
+ intermSize = 0;
+ }
+ }
+ if (items) {
+ Y_VERIFY_DEBUG(!intermSize);
+ chunks += items / NumRecsPerChunk;
+ intermSize += (items % NumRecsPerChunk) * sizeof(TRec);
+ }
+
+ if (intermSize) {
+ const ui32 numOuts = (ChunkSize - (sizeof(TIdxDiskLinker) + intermSize)) / sizeof(TDiskPart);
+ if (outs <= numOuts) {
+ intermSize += outs * sizeof(TDiskPart);
+ outs = 0;
+ } else {
+ outs -= numOuts;
+ ++chunks;
+ intermSize = 0;
+ }
}
-
- if (intermSize + sizeof(TIdxDiskPlaceHolder) > ChunkSize) {
- ++chunks;
- }
-
- return chunks;
+ if (outs) {
+ Y_VERIFY_DEBUG(!intermSize);
+ chunks += outs / NumDiskPartsPerChunk;
+ intermSize += (outs % NumDiskPartsPerChunk) * sizeof(TDiskPart);
+ }
+
+ if (intermSize + sizeof(TIdxDiskPlaceHolder) > ChunkSize) {
+ ++chunks;
+ }
+
+ return chunks;
}
void Push(const TKey &key, const TMemRec &memRec, const TDataMerger *dataMerger) {
- // check that keys are coming in strictly ascending order
- Y_VERIFY(Recs.empty() || Recs.back().Key < key);
-
+ // check that keys are coming in strictly ascending order
+ Y_VERIFY(Recs.empty() || Recs.back().Key < key);
+
switch (memRec.GetType()) {
case TBlobType::DiskBlob: {
InplaceDataTotalSize += memRec.DataSize();
@@ -533,15 +533,15 @@ namespace NKikimr {
TMemRec newMemRec(memRec);
ui32 idx = ui32(Outbound.size());
ui32 num = ui32(end - beg);
- ui32 size = 0;
- for (auto it = beg; it != end; ++it) {
- size += it->Size;
- }
- newMemRec.SetManyHugeBlobs(idx, num, size);
+ ui32 size = 0;
for (auto it = beg; it != end; ++it) {
+ size += it->Size;
+ }
+ newMemRec.SetManyHugeBlobs(idx, num, size);
+ for (auto it = beg; it != end; ++it) {
Outbound.push_back(*it);
}
- HugeDataTotalSize += size + sizeof(TDiskPart) * num;
+ HugeDataTotalSize += size + sizeof(TDiskPart) * num;
Recs.push_back(TRec(key, newMemRec));
ItemsWithHugeData++;
@@ -549,265 +549,265 @@ namespace NKikimr {
}
default: Y_FAIL("Impossible case");
}
-
- ++Items;
+
+ ++Items;
}
- void PrepareForFlush(ui64 firstLsn, ui64 lastLsn, TDataWriterConclusion&& conclusion) {
+ void PrepareForFlush(ui64 firstLsn, ui64 lastLsn, TDataWriterConclusion&& conclusion) {
FirstLsn = firstLsn;
LastLsn = lastLsn;
-
- Writer = std::move(conclusion.Writer);
- Conclusion.Addr = TDiskPart(0, 0, 0);
- Conclusion.UsedChunks = std::move(conclusion.UsedChunks);
- Conclusion.OutboundItems = Outbound.size();
- Conclusion.LevelSegment = LevelSegment;
-
- // finish current data chunk if there is no space for at least linker record
- if (Writer && sizeof(TIdxDiskLinker) > Writer->GetFreeSpace()) {
- Writer->FinishChunk();
- Writer.reset();
- }
-
- // if there is writer, then make bookmark here -- we start index data; otherwise start new chunk
- if (Writer) {
- Writer->SetBookmark();
- } else {
- StartIndexChunk();
- }
+
+ Writer = std::move(conclusion.Writer);
+ Conclusion.Addr = TDiskPart(0, 0, 0);
+ Conclusion.UsedChunks = std::move(conclusion.UsedChunks);
+ Conclusion.OutboundItems = Outbound.size();
+ Conclusion.LevelSegment = LevelSegment;
+
+ // finish current data chunk if there is no space for at least linker record
+ if (Writer && sizeof(TIdxDiskLinker) > Writer->GetFreeSpace()) {
+ Writer->FinishChunk();
+ Writer.reset();
+ }
+
+ // if there is writer, then make bookmark here -- we start index data; otherwise start new chunk
+ if (Writer) {
+ Writer->SetBookmark();
+ } else {
+ StartIndexChunk();
+ }
}
// returns true when done, false means 'continue calling me, I'have more chunks to write'
- bool FlushNext(ui32 maxMsgs) {
+ bool FlushNext(ui32 maxMsgs) {
if (Empty()) {
// no data at all
return true;
}
- return PackData(maxMsgs);
+ return PackData(maxMsgs);
}
- const TIndexWriterConclusion<TKey, TMemRec> &GetConclusion() const {
+ const TIndexWriterConclusion<TKey, TMemRec> &GetConclusion() const {
return Conclusion;
}
private:
- enum class EBlockStatus {
- IN_PROGRESS,
- NOT_ENOUGH_SPACE,
- FINISHED
- };
-
- enum class EPendingOperation {
- FINISH_PLACEHOLDER,
- FINISH_LINKER,
- NONE
- };
-
- private:
- TMemoryConsumer Consumer;
+ enum class EBlockStatus {
+ IN_PROGRESS,
+ NOT_ENOUGH_SPACE,
+ FINISHED
+ };
+
+ enum class EPendingOperation {
+ FINISH_PLACEHOLDER,
+ FINISH_LINKER,
+ NONE
+ };
+
+ private:
+ TMemoryConsumer Consumer;
const ui8 Owner;
const ui64 OwnerRound;
const ui8 Priority;
const ui32 ChunkSize;
const ui32 AppendBlockSize;
- const ui32 WriteBlockSize;
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
+ const ui32 WriteBlockSize;
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>>& MsgQueue;
TDeque<TChunkIdx>& RChunks;
ui32 RecsPos;
ui32 OutboundPos;
ui64 InplaceDataTotalSize;
ui64 HugeDataTotalSize;
- ui32 Items;
+ ui32 Items;
ui32 ItemsWithInplacedData;
ui32 ItemsWithHugeData;
- TTrackableVector<TRec> Recs;
- TTrackableVector<TDiskPart> Outbound;
+ TTrackableVector<TRec> Recs;
+ TTrackableVector<TDiskPart> Outbound;
const ui64 SstId;
ui64 FirstLsn;
ui64 LastLsn;
- TIndexWriterConclusion<TKey, TMemRec> Conclusion;
- std::unique_ptr<TBufferedChunkWriter> Writer;
- bool Finished; // just for VERIFY, i.e. internal consistency checking
- bool CreatedByRepl;
- EPendingOperation PendingOp;
-
- const ui32 NumRecsPerChunk;
- const ui32 NumDiskPartsPerChunk;
-
- // resulting LevelSegment as if it would be loaded
- TIntrusivePtr<TLevelSegment> LevelSegment;
-
- void PutLinker() {
- TIdxDiskLinker linker(Conclusion.Addr);
- Writer->Push(&linker, sizeof(linker));
- }
-
- void PutPlaceHolder() {
- // fill in LevelSegment information structure
- auto& info = LevelSegment->Info;
- info.FirstLsn = FirstLsn;
- info.LastLsn = LastLsn;
- info.InplaceDataTotalSize = InplaceDataTotalSize;
- info.HugeDataTotalSize = HugeDataTotalSize;
- info.IdxTotalSize = sizeof(TRec) * Items;
- info.Chunks = Conclusion.UsedChunks.size();
- info.IndexParts = Conclusion.IndexParts + 1;
- info.Items = Items;
- info.ItemsWithInplacedData = ItemsWithInplacedData;
- info.ItemsWithHugeData = ItemsWithHugeData;
- info.OutboundItems = Outbound.size();
- if (CreatedByRepl) {
- info.SetCreatedByRepl();
- }
- info.CTime = TAppData::TimeProvider->Now();
-
- // move Recs/Outbound into LevelSegment we are going to use
- Recs.shrink_to_fit();
- Outbound.shrink_to_fit();
- LevelSegment->LoadedIndex = std::move(Recs);
- LevelSegment->LoadedOutbound = std::move(Outbound);
-
- // fill in all chunks vector used in the sst
- LevelSegment->AllChunks = Conclusion.UsedChunks;
-
- // set up SST id
+ TIndexWriterConclusion<TKey, TMemRec> Conclusion;
+ std::unique_ptr<TBufferedChunkWriter> Writer;
+ bool Finished; // just for VERIFY, i.e. internal consistency checking
+ bool CreatedByRepl;
+ EPendingOperation PendingOp;
+
+ const ui32 NumRecsPerChunk;
+ const ui32 NumDiskPartsPerChunk;
+
+ // resulting LevelSegment as if it would be loaded
+ TIntrusivePtr<TLevelSegment> LevelSegment;
+
+ void PutLinker() {
+ TIdxDiskLinker linker(Conclusion.Addr);
+ Writer->Push(&linker, sizeof(linker));
+ }
+
+ void PutPlaceHolder() {
+ // fill in LevelSegment information structure
+ auto& info = LevelSegment->Info;
+ info.FirstLsn = FirstLsn;
+ info.LastLsn = LastLsn;
+ info.InplaceDataTotalSize = InplaceDataTotalSize;
+ info.HugeDataTotalSize = HugeDataTotalSize;
+ info.IdxTotalSize = sizeof(TRec) * Items;
+ info.Chunks = Conclusion.UsedChunks.size();
+ info.IndexParts = Conclusion.IndexParts + 1;
+ info.Items = Items;
+ info.ItemsWithInplacedData = ItemsWithInplacedData;
+ info.ItemsWithHugeData = ItemsWithHugeData;
+ info.OutboundItems = Outbound.size();
+ if (CreatedByRepl) {
+ info.SetCreatedByRepl();
+ }
+ info.CTime = TAppData::TimeProvider->Now();
+
+ // move Recs/Outbound into LevelSegment we are going to use
+ Recs.shrink_to_fit();
+ Outbound.shrink_to_fit();
+ LevelSegment->LoadedIndex = std::move(Recs);
+ LevelSegment->LoadedOutbound = std::move(Outbound);
+
+ // fill in all chunks vector used in the sst
+ LevelSegment->AllChunks = Conclusion.UsedChunks;
+
+ // set up SST id
LevelSegment->AssignedSstId = SstId;
-
- // fill in storage ratio
- auto ratio = MakeIntrusive<NHullComp::TSstRatio>();
- ratio->IndexItemsTotal = ratio->IndexItemsKeep = info.Items;
- ratio->IndexBytesTotal = ratio->IndexBytesKeep = info.IdxTotalSize;
- ratio->InplacedDataTotal = ratio->InplacedDataKeep = info.InplaceDataTotalSize;
- ratio->HugeDataTotal = ratio->HugeDataKeep = info.HugeDataTotalSize;
- LevelSegment->StorageRatio.Set(ratio);
-
- // write out place holder
- TIdxDiskPlaceHolder placeHolder(SstId);
- placeHolder.Info = info;
- placeHolder.PrevPart = Conclusion.Addr;
- Writer->Push(&placeHolder, sizeof(placeHolder));
- }
-
- EBlockStatus GenerateIndexBlockData(ui32 maxBlockSize) {
- Y_VERIFY(RecsPos <= Items && OutboundPos <= Outbound.size());
- if (ui32 recsLeft = Items - RecsPos) {
- if (ui32 numItems = Min<ui32>(recsLeft, maxBlockSize / sizeof(TRec))) {
- Writer->Push(&Recs[RecsPos], numItems * sizeof(TRec));
- RecsPos += numItems;
- return EBlockStatus::IN_PROGRESS;
- } else {
- return EBlockStatus::NOT_ENOUGH_SPACE;
+
+ // fill in storage ratio
+ auto ratio = MakeIntrusive<NHullComp::TSstRatio>();
+ ratio->IndexItemsTotal = ratio->IndexItemsKeep = info.Items;
+ ratio->IndexBytesTotal = ratio->IndexBytesKeep = info.IdxTotalSize;
+ ratio->InplacedDataTotal = ratio->InplacedDataKeep = info.InplaceDataTotalSize;
+ ratio->HugeDataTotal = ratio->HugeDataKeep = info.HugeDataTotalSize;
+ LevelSegment->StorageRatio.Set(ratio);
+
+ // write out place holder
+ TIdxDiskPlaceHolder placeHolder(SstId);
+ placeHolder.Info = info;
+ placeHolder.PrevPart = Conclusion.Addr;
+ Writer->Push(&placeHolder, sizeof(placeHolder));
+ }
+
+ EBlockStatus GenerateIndexBlockData(ui32 maxBlockSize) {
+ Y_VERIFY(RecsPos <= Items && OutboundPos <= Outbound.size());
+ if (ui32 recsLeft = Items - RecsPos) {
+ if (ui32 numItems = Min<ui32>(recsLeft, maxBlockSize / sizeof(TRec))) {
+ Writer->Push(&Recs[RecsPos], numItems * sizeof(TRec));
+ RecsPos += numItems;
+ return EBlockStatus::IN_PROGRESS;
+ } else {
+ return EBlockStatus::NOT_ENOUGH_SPACE;
}
- } else if (ui32 outboundLeft = Outbound.size() - OutboundPos) {
- if (ui32 numItems = Min<ui32>(outboundLeft, maxBlockSize / sizeof(TDiskPart))) {
- Writer->Push(&Outbound[OutboundPos], numItems * sizeof(TDiskPart));
- OutboundPos += numItems;
- return EBlockStatus::IN_PROGRESS;
- } else {
- return EBlockStatus::NOT_ENOUGH_SPACE;
+ } else if (ui32 outboundLeft = Outbound.size() - OutboundPos) {
+ if (ui32 numItems = Min<ui32>(outboundLeft, maxBlockSize / sizeof(TDiskPart))) {
+ Writer->Push(&Outbound[OutboundPos], numItems * sizeof(TDiskPart));
+ OutboundPos += numItems;
+ return EBlockStatus::IN_PROGRESS;
+ } else {
+ return EBlockStatus::NOT_ENOUGH_SPACE;
}
} else {
- return EBlockStatus::FINISHED;
- }
- }
+ return EBlockStatus::FINISHED;
+ }
+ }
- void StartIndexChunk() {
+ void StartIndexChunk() {
Y_VERIFY(!Writer);
+ Y_VERIFY(!Finished);
+
+ // obtain chunk index from reserved chunks list
+ Y_VERIFY(RChunks);
+ const TChunkIdx chunkIdx = RChunks.front();
+ RChunks.pop_front();
+
+ // create new writer
+ Writer = std::make_unique<TBufferedChunkWriter>(TMemoryConsumer(Consumer), Owner, OwnerRound, Priority,
+ ChunkSize, AppendBlockSize, WriteBlockSize, chunkIdx, MsgQueue);
+
+ // bookmark start of index data
+ Writer->SetBookmark();
+
+ // mark chunk as used
+ Conclusion.UsedChunks.push_back(chunkIdx);
+ }
+
+ void FinishIndexChunk() {
+ LevelSegment->LastPartAddr = Conclusion.Addr = Writer->GetDiskPartForBookmark();
+ LevelSegment->IndexParts.insert(LevelSegment->IndexParts.begin(), LevelSegment->LastPartAddr);
+ Writer->FinishChunk();
+ Writer.reset();
+ ++Conclusion.IndexParts;
+ }
+
+ bool PackData(ui32 maxMsgs) {
Y_VERIFY(!Finished);
- // obtain chunk index from reserved chunks list
- Y_VERIFY(RChunks);
- const TChunkIdx chunkIdx = RChunks.front();
- RChunks.pop_front();
-
- // create new writer
- Writer = std::make_unique<TBufferedChunkWriter>(TMemoryConsumer(Consumer), Owner, OwnerRound, Priority,
- ChunkSize, AppendBlockSize, WriteBlockSize, chunkIdx, MsgQueue);
-
- // bookmark start of index data
- Writer->SetBookmark();
-
- // mark chunk as used
- Conclusion.UsedChunks.push_back(chunkIdx);
- }
-
- void FinishIndexChunk() {
- LevelSegment->LastPartAddr = Conclusion.Addr = Writer->GetDiskPartForBookmark();
- LevelSegment->IndexParts.insert(LevelSegment->IndexParts.begin(), LevelSegment->LastPartAddr);
- Writer->FinishChunk();
- Writer.reset();
- ++Conclusion.IndexParts;
- }
-
- bool PackData(ui32 maxMsgs) {
- Y_VERIFY(!Finished);
-
- while (MsgQueue.size() < maxMsgs) {
- switch (PendingOp) {
- case EPendingOperation::FINISH_PLACEHOLDER:
- FinishIndexChunk();
- Finished = true;
- return true;
-
- case EPendingOperation::FINISH_LINKER:
- FinishIndexChunk();
- StartIndexChunk();
- PendingOp = EPendingOperation::NONE;
- continue;
-
- case EPendingOperation::NONE:
- break;
+ while (MsgQueue.size() < maxMsgs) {
+ switch (PendingOp) {
+ case EPendingOperation::FINISH_PLACEHOLDER:
+ FinishIndexChunk();
+ Finished = true;
+ return true;
+
+ case EPendingOperation::FINISH_LINKER:
+ FinishIndexChunk();
+ StartIndexChunk();
+ PendingOp = EPendingOperation::NONE;
+ continue;
+
+ case EPendingOperation::NONE:
+ break;
+ }
+
+ EBlockStatus status = EBlockStatus::NOT_ENOUGH_SPACE;
+
+ ui32 freeSpace = Writer->GetFreeSpace();
+ if (freeSpace > sizeof(TIdxDiskLinker)) {
+ ui32 maxBlockSize = Min<ui32>(freeSpace - sizeof(TIdxDiskLinker), Writer->GetBlockSize());
+ status = GenerateIndexBlockData(maxBlockSize);
+ Y_VERIFY(MsgQueue.size() <= maxMsgs);
+ if (MsgQueue.size() == maxMsgs) {
+ // we have now reached maxMsgs limit, but when we will be called next time, the same status
+ // will be returned, so there is no need to preserve it
+ break;
+ }
}
- EBlockStatus status = EBlockStatus::NOT_ENOUGH_SPACE;
-
- ui32 freeSpace = Writer->GetFreeSpace();
- if (freeSpace > sizeof(TIdxDiskLinker)) {
- ui32 maxBlockSize = Min<ui32>(freeSpace - sizeof(TIdxDiskLinker), Writer->GetBlockSize());
- status = GenerateIndexBlockData(maxBlockSize);
- Y_VERIFY(MsgQueue.size() <= maxMsgs);
- if (MsgQueue.size() == maxMsgs) {
- // we have now reached maxMsgs limit, but when we will be called next time, the same status
- // will be returned, so there is no need to preserve it
- break;
- }
- }
-
- switch (status) {
- case EBlockStatus::IN_PROGRESS:
- break;
-
- case EBlockStatus::FINISHED:
- if (Writer->GetFreeSpace() >= sizeof(TIdxDiskPlaceHolder)) {
- PutPlaceHolder();
- Y_VERIFY(MsgQueue.size() <= maxMsgs);
- if (MsgQueue.size() == maxMsgs) {
- PendingOp = EPendingOperation::FINISH_PLACEHOLDER;
- return false;
- }
- FinishIndexChunk();
- Finished = true;
- return true;
- }
+ switch (status) {
+ case EBlockStatus::IN_PROGRESS:
+ break;
+
+ case EBlockStatus::FINISHED:
+ if (Writer->GetFreeSpace() >= sizeof(TIdxDiskPlaceHolder)) {
+ PutPlaceHolder();
+ Y_VERIFY(MsgQueue.size() <= maxMsgs);
+ if (MsgQueue.size() == maxMsgs) {
+ PendingOp = EPendingOperation::FINISH_PLACEHOLDER;
+ return false;
+ }
+ FinishIndexChunk();
+ Finished = true;
+ return true;
+ }
[[fallthrough]];
- case EBlockStatus::NOT_ENOUGH_SPACE:
- PutLinker();
- Y_VERIFY(MsgQueue.size() <= maxMsgs);
- if (MsgQueue.size() == maxMsgs) {
- PendingOp = EPendingOperation::FINISH_LINKER;
- return false;
- }
- FinishIndexChunk();
- StartIndexChunk();
- break;
- }
+ case EBlockStatus::NOT_ENOUGH_SPACE:
+ PutLinker();
+ Y_VERIFY(MsgQueue.size() <= maxMsgs);
+ if (MsgQueue.size() == maxMsgs) {
+ PendingOp = EPendingOperation::FINISH_LINKER;
+ return false;
+ }
+ FinishIndexChunk();
+ StartIndexChunk();
+ break;
+ }
}
-
- // message queue is full, do not continue processing
- return false;
+
+ // message queue is full, do not continue processing
+ return false;
}
};
@@ -823,116 +823,116 @@ namespace NKikimr {
public:
TWriter(TVDiskContextPtr vctx, EWriterDataType type, ui32 chunksToUse, ui8 owner, ui64 ownerRound,
ui32 chunkSize, ui32 appendBlockSize, ui32 writeBlockSize, ui64 sstId, bool createdByRepl,
- TDeque<TChunkIdx>& rchunks, TRopeArena& arena)
+ TDeque<TChunkIdx>& rchunks, TRopeArena& arena)
: DataWriter(vctx, type, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize, MsgQueue, rchunks)
, IndexBuilder(vctx, type, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize, sstId,
createdByRepl, MsgQueue, rchunks)
, ChunksToUse(chunksToUse)
, ChunkSize(chunkSize)
- , Arena(arena)
+ , Arena(arena)
{}
bool Empty() const {
return IndexBuilder.Empty();
}
- bool CheckSpace(ui32 inplacedDataSize, ui32 numAddedOuts) {
- ui32 chunks = 0;
- ui32 intermSize = 0;
- DataWriter.GetUsageAfterPush(inplacedDataSize, &chunks, &intermSize);
- return IndexBuilder.GetUsageAfterPush(chunks, intermSize, numAddedOuts) <= ChunksToUse;
+ bool CheckSpace(ui32 inplacedDataSize, ui32 numAddedOuts) {
+ ui32 chunks = 0;
+ ui32 intermSize = 0;
+ DataWriter.GetUsageAfterPush(inplacedDataSize, &chunks, &intermSize);
+ return IndexBuilder.GetUsageAfterPush(chunks, intermSize, numAddedOuts) <= ChunksToUse;
}
- bool PushIndexOnly(const TKey& key, const TMemRec& memRec, const TDataMerger *dataMerger, ui32 inplacedDataSize,
- TDiskPart *location) {
- // inplacedDataSize must be nonzero for DiskBlob with data and zero in all other cases
+ bool PushIndexOnly(const TKey& key, const TMemRec& memRec, const TDataMerger *dataMerger, ui32 inplacedDataSize,
+ TDiskPart *location) {
+ // inplacedDataSize must be nonzero for DiskBlob with data and zero in all other cases
ui32 numAddedOuts = dataMerger->GetHugeBlobMerger().SavedData().size();
- if (!CheckSpace(inplacedDataSize, numAddedOuts)) {
- return false;
- }
-
- // generate TMemRec to perform actual insertion into index
- TMemRec memRecToAdd(memRec);
+ if (!CheckSpace(inplacedDataSize, numAddedOuts)) {
+ return false;
+ }
+
+ // generate TMemRec to perform actual insertion into index
+ TMemRec memRecToAdd(memRec);
switch (memRec.GetType()) {
case TBlobType::HugeBlob:
- Y_VERIFY_DEBUG(inplacedDataSize == 0);
- Y_VERIFY_DEBUG(numAddedOuts == 1);
- break;
-
- case TBlobType::ManyHugeBlobs:
- Y_VERIFY_DEBUG(inplacedDataSize == 0);
- Y_VERIFY_DEBUG(numAddedOuts > 1);
- break;
-
- case TBlobType::DiskBlob:
- Y_VERIFY_DEBUG(numAddedOuts == 0);
- if (inplacedDataSize) {
- *location = DataWriter.Preallocate(inplacedDataSize);
- memRecToAdd.SetDiskBlob(*location);
+ Y_VERIFY_DEBUG(inplacedDataSize == 0);
+ Y_VERIFY_DEBUG(numAddedOuts == 1);
+ break;
+
+ case TBlobType::ManyHugeBlobs:
+ Y_VERIFY_DEBUG(inplacedDataSize == 0);
+ Y_VERIFY_DEBUG(numAddedOuts > 1);
+ break;
+
+ case TBlobType::DiskBlob:
+ Y_VERIFY_DEBUG(numAddedOuts == 0);
+ if (inplacedDataSize) {
+ *location = DataWriter.Preallocate(inplacedDataSize);
+ memRecToAdd.SetDiskBlob(*location);
}
- break;
+ break;
default: Y_FAIL("Impossible case");
}
-
- IndexBuilder.Push(key, memRecToAdd, dataMerger);
-
- return true;
- }
-
- TDiskPart PushDataOnly(TRope&& buffer) {
- return DataWriter.Push(std::move(buffer));
- }
-
- // return false on no-more-space
- bool Push(const TKey &key, const TMemRec &memRec, const TDataMerger *dataMerger, ui32 inplacedDataSize = 0) {
- // if this is filled disk blob, then we extract data and calculate inplacedDataSize
- TRope data;
- const auto& diskBlobMerger = dataMerger->GetDiskBlobMerger();
- if (memRec.GetType() == TBlobType::DiskBlob && !diskBlobMerger.Empty()) {
- data = diskBlobMerger.CreateDiskBlob(Arena);
- Y_VERIFY_DEBUG(!inplacedDataSize);
- inplacedDataSize = data.GetSize();
- }
-
- TDiskPart preallocatedLocation;
- if (!PushIndexOnly(key, memRec, dataMerger, inplacedDataSize, &preallocatedLocation)) {
- return false;
- }
-
- // write inplace data if we have some
- if (data) {
- Y_VERIFY_DEBUG(data.GetSize() == inplacedDataSize);
- TDiskPart writtenLocation = DataWriter.Push(data);
- Y_VERIFY_DEBUG(writtenLocation == preallocatedLocation);
- }
-
- return true;
- }
-
+
+ IndexBuilder.Push(key, memRecToAdd, dataMerger);
+
+ return true;
+ }
+
+ TDiskPart PushDataOnly(TRope&& buffer) {
+ return DataWriter.Push(std::move(buffer));
+ }
+
+ // return false on no-more-space
+ bool Push(const TKey &key, const TMemRec &memRec, const TDataMerger *dataMerger, ui32 inplacedDataSize = 0) {
+ // if this is filled disk blob, then we extract data and calculate inplacedDataSize
+ TRope data;
+ const auto& diskBlobMerger = dataMerger->GetDiskBlobMerger();
+ if (memRec.GetType() == TBlobType::DiskBlob && !diskBlobMerger.Empty()) {
+ data = diskBlobMerger.CreateDiskBlob(Arena);
+ Y_VERIFY_DEBUG(!inplacedDataSize);
+ inplacedDataSize = data.GetSize();
+ }
+
+ TDiskPart preallocatedLocation;
+ if (!PushIndexOnly(key, memRec, dataMerger, inplacedDataSize, &preallocatedLocation)) {
+ return false;
+ }
+
+ // write inplace data if we have some
+ if (data) {
+ Y_VERIFY_DEBUG(data.GetSize() == inplacedDataSize);
+ TDiskPart writtenLocation = DataWriter.Push(data);
+ Y_VERIFY_DEBUG(writtenLocation == preallocatedLocation);
+ }
+
+ return true;
+ }
+
// returns true when done, false means 'continue calling me, I'have more chunks to write'
- bool FlushNext(ui64 firstLsn, ui64 lastLsn, ui32 maxMsgs) {
+ bool FlushNext(ui64 firstLsn, ui64 lastLsn, ui32 maxMsgs) {
if (!DataWriter.IsFinished()) {
- IndexBuilder.PrepareForFlush(firstLsn, lastLsn, DataWriter.Finish());
+ IndexBuilder.PrepareForFlush(firstLsn, lastLsn, DataWriter.Finish());
}
- return IndexBuilder.FlushNext(maxMsgs);
+ return IndexBuilder.FlushNext(maxMsgs);
}
- std::unique_ptr<NPDisk::TEvChunkWrite> GetPendingMessage() {
- if (!MsgQueue) {
- return nullptr; // no messages to send
- }
-
- std::unique_ptr<NPDisk::TEvChunkWrite> msg = std::move(MsgQueue.front());
- MsgQueue.pop();
- return msg;
+ std::unique_ptr<NPDisk::TEvChunkWrite> GetPendingMessage() {
+ if (!MsgQueue) {
+ return nullptr; // no messages to send
+ }
+
+ std::unique_ptr<NPDisk::TEvChunkWrite> msg = std::move(MsgQueue.front());
+ MsgQueue.pop();
+ return msg;
}
- const TIndexWriterConclusion<TKey, TMemRec> &GetConclusion() const {
- const auto &conclusion = IndexBuilder.GetConclusion();
- Y_VERIFY(std::find(conclusion.UsedChunks.begin(), conclusion.UsedChunks.end(), conclusion.Addr.ChunkIdx) !=
- conclusion.UsedChunks.end());
- return conclusion;
+ const TIndexWriterConclusion<TKey, TMemRec> &GetConclusion() const {
+ const auto &conclusion = IndexBuilder.GetConclusion();
+ Y_VERIFY(std::find(conclusion.UsedChunks.begin(), conclusion.UsedChunks.end(), conclusion.Addr.ChunkIdx) !=
+ conclusion.UsedChunks.end());
+ return conclusion;
}
private:
@@ -940,10 +940,10 @@ namespace NKikimr {
TIndexBuilder IndexBuilder;
const ui32 ChunksToUse;
const ui32 ChunkSize;
- TRopeArena& Arena;
-
- // pending messages
- TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>> MsgQueue;
+ TRopeArena& Arena;
+
+ // pending messages
+ TQueue<std::unique_ptr<NPDisk::TEvChunkWrite>> MsgQueue;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp
index 2bd6de3d43c..a5abe53cd37 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst_ut.cpp
@@ -19,11 +19,11 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////////////////
typedef TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob> TSstLogoBlob;
typedef TSstLogoBlob::TWriter TWriterLogoBlob;
- typedef TCompactRecordMergerIndexPass<TKeyLogoBlob, TMemRecLogoBlob> TTLogoBlobCompactRecordMerger;
+ typedef TCompactRecordMergerIndexPass<TKeyLogoBlob, TMemRecLogoBlob> TTLogoBlobCompactRecordMerger;
typedef TLevelSegment<TKeyBlock, TMemRecBlock> TSstBlock;
typedef TSstBlock::TWriter TWriterBlock;
- typedef TCompactRecordMergerIndexPass<TKeyBlock, TMemRecBlock> TBlockCompactRecordMerger;
+ typedef TCompactRecordMergerIndexPass<TKeyBlock, TMemRecBlock> TBlockCompactRecordMerger;
TTestContexts TestCtx;
@@ -34,9 +34,9 @@ namespace NKikimr {
class TTest {
public:
struct TSstStat {
- TIndexWriterConclusion<TKey, TMemRec> WriterConclusion;
+ TIndexWriterConclusion<TKey, TMemRec> WriterConclusion;
ui32 Step;
- TSstStat(const TIndexWriterConclusion<TKey, TMemRec> &writerStat, ui32 step)
+ TSstStat(const TIndexWriterConclusion<TKey, TMemRec> &writerStat, ui32 step)
: WriterConclusion(writerStat)
, Step(step)
{}
@@ -48,7 +48,7 @@ namespace NKikimr {
struct TAllStat {
TVector<TSstStat> Stat;
- void Push(const TIndexWriterConclusion<TKey, TMemRec> &writerStat, ui32 step) {
+ void Push(const TIndexWriterConclusion<TKey, TMemRec> &writerStat, ui32 step) {
Stat.push_back(TSstStat(writerStat, step));
}
@@ -72,13 +72,13 @@ namespace NKikimr {
, OwnerRound(ownerRound)
, ChunkSize(chunkSize)
, AppendBlockSize(appendBlockSize)
- , WriteBlockSize(writeBlockSize)
+ , WriteBlockSize(writeBlockSize)
, WriterPtr(new TWriter(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse, Owner, OwnerRound,
ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks))
, ReservedChunks()
, Stat()
{
- for (ui32 i = 1; i < 2000; i++)
+ for (ui32 i = 1; i < 2000; i++)
ReservedChunks.push_back(i);
}
@@ -104,56 +104,56 @@ namespace NKikimr {
const ui64 OwnerRound;
const ui32 ChunkSize;
const ui32 AppendBlockSize;
- const ui32 WriteBlockSize;
+ const ui32 WriteBlockSize;
- std::unique_ptr<TWriter> WriterPtr;
+ std::unique_ptr<TWriter> WriterPtr;
TDeque<ui32> ReservedChunks;
TAllStat Stat;
- THashMap<ui32, TMap<ui32, ui32>> WriteSpan;
+ THashMap<ui32, TMap<ui32, ui32>> WriteSpan;
- void Apply(std::unique_ptr<NPDisk::TEvChunkWrite> &msg) {
+ void Apply(std::unique_ptr<NPDisk::TEvChunkWrite> &msg) {
ui32 chunkIdx = msg->ChunkIdx;
- UNIT_ASSERT(msg->ChunkIdx != 0);
+ UNIT_ASSERT(msg->ChunkIdx != 0);
NPDisk::TEvChunkWrite::TPartsPtr partsPtr = msg->PartsPtr;
- const ui32 begin = msg->Offset;
- const ui32 end = begin + partsPtr->ByteSize();
- UNIT_ASSERT(!WriteSpan[msg->ChunkIdx].count(begin));
- WriteSpan[msg->ChunkIdx].emplace(begin, end);
+ const ui32 begin = msg->Offset;
+ const ui32 end = begin + partsPtr->ByteSize();
+ UNIT_ASSERT(!WriteSpan[msg->ChunkIdx].count(begin));
+ WriteSpan[msg->ChunkIdx].emplace(begin, end);
void *cookie = msg->Cookie;
- auto res = std::make_unique<NPDisk::TEvChunkWriteResult>(NKikimrProto::OK, chunkIdx, partsPtr, cookie, 0, TString());
+ auto res = std::make_unique<NPDisk::TEvChunkWriteResult>(NKikimrProto::OK, chunkIdx, partsPtr, cookie, 0, TString());
msg.Destroy();
}
void Finish(ui32 step) {
- std::unique_ptr<NPDisk::TEvChunkWrite> msg;
+ std::unique_ptr<NPDisk::TEvChunkWrite> msg;
bool done = false;
while (!done) {
- done = WriterPtr->FlushNext(0, 100500, 1);
- while (auto msg = WriterPtr->GetPendingMessage()) {
+ done = WriterPtr->FlushNext(0, 100500, 1);
+ while (auto msg = WriterPtr->GetPendingMessage()) {
Apply(msg);
}
}
Stat.Push(WriterPtr->GetConclusion(), step);
-
- ValidateWriteSpan();
- }
-
- void ValidateWriteSpan() {
- for (const auto& kv : WriteSpan) {
- ui32 expectedBegin = 0;
- for (auto it = kv.second.begin(); it != kv.second.end(); ++it) {
- UNIT_ASSERT_VALUES_EQUAL(expectedBegin, it->first);
- expectedBegin = it->second;
- }
- }
+
+ ValidateWriteSpan();
}
+
+ void ValidateWriteSpan() {
+ for (const auto& kv : WriteSpan) {
+ ui32 expectedBegin = 0;
+ for (auto it = kv.second.begin(); it != kv.second.end(); ++it) {
+ UNIT_ASSERT_VALUES_EQUAL(expectedBegin, it->first);
+ expectedBegin = it->second;
+ }
+ }
+ }
};
template <>
void TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob>::Test(ui32 maxStep, const TString &data) {
- TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
+ TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
for (ui32 step = 0; step < maxStep; step++) {
TLogoBlobID id(1, 1, step, 0, 0, 0);
@@ -171,16 +171,16 @@ namespace NKikimr {
merger.Add(memRec, blobBuf.data(), key);
merger.Finish();
- bool pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
+ bool pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
if (!pushRes) {
Finish(step);
- WriterPtr = std::make_unique<TWriterLogoBlob>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
- Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
- pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
+ WriterPtr = std::make_unique<TWriterLogoBlob>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
+ Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
+ pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
Y_VERIFY(pushRes);
}
- while (auto msg = WriterPtr->GetPendingMessage()) {
+ while (auto msg = WriterPtr->GetPendingMessage()) {
Apply(msg);
}
}
@@ -190,7 +190,7 @@ namespace NKikimr {
template <>
void TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob>::TestOutbound(ui32 maxStep) {
- TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
+ TTLogoBlobCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
for (ui32 step = 0; step < maxStep; step++) {
TLogoBlobID id(1, 1, step, 0, 0, 0);
@@ -209,20 +209,20 @@ namespace NKikimr {
merger.Clear();
merger.SetLoadDataMode(true);
- merger.Add(memRec1, nullptr, key);
- merger.Add(memRec2, nullptr, key);
+ merger.Add(memRec1, nullptr, key);
+ merger.Add(memRec2, nullptr, key);
merger.Finish();
- bool pushRes = WriterPtr->Push(key, merger.GetMemRec(), merger.GetDataMerger());
+ bool pushRes = WriterPtr->Push(key, merger.GetMemRec(), merger.GetDataMerger());
if (!pushRes) {
Finish(step);
- WriterPtr = std::make_unique<TWriterLogoBlob>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
- Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
- pushRes = WriterPtr->Push(key, merger.GetMemRec(), merger.GetDataMerger());
+ WriterPtr = std::make_unique<TWriterLogoBlob>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
+ Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
+ pushRes = WriterPtr->Push(key, merger.GetMemRec(), merger.GetDataMerger());
Y_VERIFY(pushRes);
}
- while (auto msg = WriterPtr->GetPendingMessage()) {
+ while (auto msg = WriterPtr->GetPendingMessage()) {
Apply(msg);
}
}
@@ -232,26 +232,26 @@ namespace NKikimr {
template <>
void TTest<TKeyBlock, TMemRecBlock, TWriterBlock>::Test(ui32 maxGen) {
- TBlockCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
+ TBlockCompactRecordMerger merger(TBlobStorageGroupType::ErasureMirror3);
for (ui32 gen = 0; gen < maxGen; gen++) {
- TKeyBlock key(34 + gen);
+ TKeyBlock key(34 + gen);
TMemRecBlock memRec(gen);
merger.Clear();
merger.SetLoadDataMode(true);
- merger.Add(memRec, nullptr, key);
+ merger.Add(memRec, nullptr, key);
merger.Finish();
- bool pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
+ bool pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
if (!pushRes) {
Finish(gen);
- WriterPtr = std::make_unique<TWriterBlock>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
- Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
- pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
+ WriterPtr = std::make_unique<TWriterBlock>(TestCtx.GetVCtx(), EWriterDataType::Fresh, ChunksToUse,
+ Owner, OwnerRound, ChunkSize, AppendBlockSize, WriteBlockSize, 0, false, ReservedChunks);
+ pushRes = WriterPtr->Push(key, memRec, merger.GetDataMerger());
Y_VERIFY(pushRes);
}
- while (auto msg = WriterPtr->GetPendingMessage()) {
+ while (auto msg = WriterPtr->GetPendingMessage()) {
Apply(msg);
}
}
@@ -270,64 +270,64 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TString data("Hello, world!");
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(10000, data);
TString res("{SST {Addr: {ChunkIdx: 1 Offset: 200000 Size: 440096} "
- "IndexParts: 1 {UsedChunks: 1}} step: 10000}");
- STR << res << "\n";
- STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
- }
-
- Y_UNIT_TEST(LogoBlobOneSstOneIndexWithSmallWriteBlocks) {
- ui32 chunksToUse = 4;
- ui8 owner = 1;
- ui64 ownerRound = 1;
- ui32 chunkSize = 1u << 20u;
- ui32 appendBlockSize = 1 << 10u;
- ui32 writeBlockSize = appendBlockSize;
-
- TString data("Hello, world!");
- while (data.size() < writeBlockSize * 2) {
- data += data;
- }
-
- ui32 numBlobs = chunkSize / 2 / data.size();
-
- TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
- test.Test(numBlobs, data);
-
- const ui32 offset = ((data.size() + 8) & ~3) * numBlobs; // 8 = 5 byte blob header + blob data + alignment up to 4 bytes
- const ui32 size = numBlobs * (sizeof(TKeyLogoBlob) + sizeof(TMemRecLogoBlob)) + sizeof(TIdxDiskPlaceHolder);
- const ui32 step = numBlobs;
-
- auto res = Sprintf("{SST {Addr: {ChunkIdx: 1 Offset: %u Size: %u} IndexParts: 1 {UsedChunks: 1}} step: %u}",
- offset, size, step);
-
+ "IndexParts: 1 {UsedChunks: 1}} step: 10000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
+ Y_UNIT_TEST(LogoBlobOneSstOneIndexWithSmallWriteBlocks) {
+ ui32 chunksToUse = 4;
+ ui8 owner = 1;
+ ui64 ownerRound = 1;
+ ui32 chunkSize = 1u << 20u;
+ ui32 appendBlockSize = 1 << 10u;
+ ui32 writeBlockSize = appendBlockSize;
+
+ TString data("Hello, world!");
+ while (data.size() < writeBlockSize * 2) {
+ data += data;
+ }
+
+ ui32 numBlobs = chunkSize / 2 / data.size();
+
+ TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
+ test.Test(numBlobs, data);
+
+ const ui32 offset = ((data.size() + 8) & ~3) * numBlobs; // 8 = 5 byte blob header + blob data + alignment up to 4 bytes
+ const ui32 size = numBlobs * (sizeof(TKeyLogoBlob) + sizeof(TMemRecLogoBlob)) + sizeof(TIdxDiskPlaceHolder);
+ const ui32 step = numBlobs;
+
+ auto res = Sprintf("{SST {Addr: {ChunkIdx: 1 Offset: %u Size: %u} IndexParts: 1 {UsedChunks: 1}} step: %u}",
+ offset, size, step);
+
+ STR << res << "\n";
+ STR << test.GetStat().ToString() << "\n";
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ }
+
Y_UNIT_TEST(LogoBlobOneSstMultiIndex) {
ui32 chunksToUse = 4;
ui8 owner = 1;
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TString data("X");
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(50000, data);
TString res("{SST {Addr: {ChunkIdx: 3 Offset: 0 Size: 502972} "
- "IndexParts: 3 {UsedChunks: 1 2 3}} step: 50000}");
+ "IndexParts: 3 {UsedChunks: 1 2 3}} step: 50000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
Y_UNIT_TEST(LogoBlobMultiSstOneIndex) {
@@ -336,19 +336,19 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TString data("Hello, world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(50000, data);
TString res("{SST {Addr: {ChunkIdx: 2 Offset: 125776 Size: 922776} "
- "IndexParts: 1 {UsedChunks: 1 2}} step: 20970} "
- "{SST {Addr: {ChunkIdx: 4 Offset: 125776 Size: 922776} "
- "IndexParts: 1 {UsedChunks: 3 4}} step: 41940} "
- "{SST {Addr: {ChunkIdx: 5 Offset: 451360 Size: 354736} "
- "IndexParts: 1 {UsedChunks: 5}} step: 50000}");
+ "IndexParts: 1 {UsedChunks: 1 2}} step: 20970} "
+ "{SST {Addr: {ChunkIdx: 4 Offset: 125776 Size: 922776} "
+ "IndexParts: 1 {UsedChunks: 3 4}} step: 41940} "
+ "{SST {Addr: {ChunkIdx: 5 Offset: 451360 Size: 354736} "
+ "IndexParts: 1 {UsedChunks: 5}} step: 50000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
Y_UNIT_TEST(LogoBlobMultiSstMultiIndex) {
@@ -357,39 +357,39 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TString data("X");
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(1000000, data);
TString res("{SST {Addr: {ChunkIdx: 4 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 1 2 3 4}} step: 80657} "
- "{SST {Addr: {ChunkIdx: 8 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 5 6 7 8}} step: 161314} "
- "{SST {Addr: {ChunkIdx: 12 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 9 10 11 12}} step: 241971} "
- "{SST {Addr: {ChunkIdx: 16 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 13 14 15 16}} step: 322628} "
- "{SST {Addr: {ChunkIdx: 20 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 17 18 19 20}} step: 403285} "
- "{SST {Addr: {ChunkIdx: 24 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 21 22 23 24}} step: 483942} "
- "{SST {Addr: {ChunkIdx: 28 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 25 26 27 28}} step: 564599} "
- "{SST {Addr: {ChunkIdx: 32 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 29 30 31 32}} step: 645256} "
- "{SST {Addr: {ChunkIdx: 36 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 33 34 35 36}} step: 725913} "
- "{SST {Addr: {ChunkIdx: 40 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 37 38 39 40}} step: 806570} "
- "{SST {Addr: {ChunkIdx: 44 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 41 42 43 44}} step: 887227} "
- "{SST {Addr: {ChunkIdx: 48 Offset: 0 Size: 1048572} "
- "IndexParts: 4 {UsedChunks: 45 46 47 48}} step: 967884} "
- "{SST {Addr: {ChunkIdx: 50 Offset: 0 Size: 621596} "
- "IndexParts: 2 {UsedChunks: 49 50}} step: 1000000}");
+ "IndexParts: 4 {UsedChunks: 1 2 3 4}} step: 80657} "
+ "{SST {Addr: {ChunkIdx: 8 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 5 6 7 8}} step: 161314} "
+ "{SST {Addr: {ChunkIdx: 12 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 9 10 11 12}} step: 241971} "
+ "{SST {Addr: {ChunkIdx: 16 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 13 14 15 16}} step: 322628} "
+ "{SST {Addr: {ChunkIdx: 20 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 17 18 19 20}} step: 403285} "
+ "{SST {Addr: {ChunkIdx: 24 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 21 22 23 24}} step: 483942} "
+ "{SST {Addr: {ChunkIdx: 28 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 25 26 27 28}} step: 564599} "
+ "{SST {Addr: {ChunkIdx: 32 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 29 30 31 32}} step: 645256} "
+ "{SST {Addr: {ChunkIdx: 36 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 33 34 35 36}} step: 725913} "
+ "{SST {Addr: {ChunkIdx: 40 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 37 38 39 40}} step: 806570} "
+ "{SST {Addr: {ChunkIdx: 44 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 41 42 43 44}} step: 887227} "
+ "{SST {Addr: {ChunkIdx: 48 Offset: 0 Size: 1048572} "
+ "IndexParts: 4 {UsedChunks: 45 46 47 48}} step: 967884} "
+ "{SST {Addr: {ChunkIdx: 50 Offset: 0 Size: 621596} "
+ "IndexParts: 2 {UsedChunks: 49 50}} step: 1000000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -401,15 +401,15 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.TestOutbound(10000);
TString res("{SST {Addr: {ChunkIdx: 1 Offset: 0 Size: 680096} "
- "IndexParts: 1 OutboundItems: 20000 {UsedChunks: 1}} step: 10000}");
+ "IndexParts: 1 OutboundItems: 20000 {UsedChunks: 1}} step: 10000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
Y_UNIT_TEST(LogoBlobOneSstMultiIndexPartOutbound) {
@@ -418,15 +418,15 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.TestOutbound(50000);
TString res("{SST {Addr: {ChunkIdx: 4 Offset: 0 Size: 254412} "
- "IndexParts: 4 OutboundItems: 100000 {UsedChunks: 1 2 3 4}} step: 50000}");
+ "IndexParts: 4 OutboundItems: 100000 {UsedChunks: 1 2 3 4}} step: 50000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
@@ -436,16 +436,16 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyLogoBlob, TMemRecLogoBlob, TWriterLogoBlob> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.TestOutbound(20000);
TString res("{SST {Addr: {ChunkIdx: 1 Offset: 0 Size: 1048520} "
- "IndexParts: 1 OutboundItems: 30836 {UsedChunks: 1}} step: 15418} "
- "{SST {Addr: {ChunkIdx: 2 Offset: 0 Size: 311672} "
- "IndexParts: 1 OutboundItems: 9164 {UsedChunks: 2}} step: 20000}");
+ "IndexParts: 1 OutboundItems: 30836 {UsedChunks: 1}} step: 15418} "
+ "{SST {Addr: {ChunkIdx: 2 Offset: 0 Size: 311672} "
+ "IndexParts: 1 OutboundItems: 9164 {UsedChunks: 2}} step: 20000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
@@ -458,15 +458,15 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyBlock, TMemRecBlock, TWriterBlock> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(5000);
TString res("{SST {Addr: {ChunkIdx: 1 Offset: 0 Size: 60096} "
- "IndexParts: 1 {UsedChunks: 1}} step: 5000}");
+ "IndexParts: 1 {UsedChunks: 1}} step: 5000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
Y_UNIT_TEST(BlockOneSstMultiIndex) {
@@ -475,15 +475,15 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyBlock, TMemRecBlock, TWriterBlock> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(150000);
TString res("{SST {Addr: {ChunkIdx: 2 Offset: 0 Size: 751536} "
- "IndexParts: 2 {UsedChunks: 1 2}} step: 150000}");
+ "IndexParts: 2 {UsedChunks: 1 2}} step: 150000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
Y_UNIT_TEST(BlockMultiSstOneIndex) {
@@ -492,17 +492,17 @@ namespace NKikimr {
ui64 ownerRound = 1;
ui32 chunkSize = 1u << 20u;
ui32 appendBlockSize = 4u << 10u;
- ui32 writeBlockSize = 16u << 10u;
+ ui32 writeBlockSize = 16u << 10u;
TTest<TKeyBlock, TMemRecBlock, TWriterBlock> test(chunksToUse, owner, ownerRound, chunkSize, appendBlockSize, writeBlockSize);
test.Test(150000);
TString res("{SST {Addr: {ChunkIdx: 1 Offset: 0 Size: 1048572} "
- "IndexParts: 1 {UsedChunks: 1}} step: 87373} "
- "{SST {Addr: {ChunkIdx: 2 Offset: 0 Size: 751620} "
- "IndexParts: 1 {UsedChunks: 2}} step: 150000}");
+ "IndexParts: 1 {UsedChunks: 1}} step: 87373} "
+ "{SST {Addr: {ChunkIdx: 2 Offset: 0 Size: 751620} "
+ "IndexParts: 1 {UsedChunks: 2}} step: 150000}");
STR << res << "\n";
STR << test.GetStat().ToString() << "\n";
- UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
+ UNIT_ASSERT_VALUES_EQUAL(test.GetStat().ToString(), res);
}
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.cpp
index d35b282732f..0ebb906ea49 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.cpp
@@ -2,7 +2,7 @@
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_block.h>
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_barrier.h>
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h>
-#include <library/cpp/monlib/service/pages/templates.h>
+#include <library/cpp/monlib/service/pages/templates.h>
namespace NKikimr {
@@ -40,7 +40,7 @@ namespace NKikimr {
bool TLevelIndexBase::CheckEntryPoint(const char *begin, const char *end, size_t keySizeOf, ui32 signature,
TString &explanation) {
// OLD Data Format
- // data ::= [signature=4b] [nextSstId=8b] deleted_chunks level0 otherLevels;
+ // data ::= [signature=4b] [nextSstId=8b] deleted_chunks level0 otherLevels;
// deleted_chunks ::= [size=4b] [chunkIdx=4b]*
// level0 ::= [size=4b] [TDiskPart=12b] * size
// otherLevels ::= levelX *
@@ -60,9 +60,9 @@ namespace NKikimr {
}
pos += sizeof(ui32);
- // skip next SST index
- pos += sizeof(ui64);
-
+ // skip next SST index
+ pos += sizeof(ui64);
+
// check deleted_chunks
if (size_t(end - pos) < sizeof(ui32)) {
explanation = "deleted chunks size";
@@ -132,7 +132,7 @@ namespace NKikimr {
ui32 chunks = *(const ui32*)pos;
pos += sizeof(ui32); // array size
for (ui32 i = 0; i < chunks; i++) {
- pb.AddDeletedChunks(*reinterpret_cast<const ui32 *>(pos));
+ pb.AddDeletedChunks(*reinterpret_cast<const ui32 *>(pos));
pos += sizeof(ui32);
}
@@ -167,58 +167,58 @@ namespace NKikimr {
}
- bool TLevelIndexBase::CheckBulkFormedSegments(const char *begin, const char *end) {
- // empty string is correct bulk-formed segment set
- if (begin == end)
- return true;
-
- TMemoryInput stream(begin, end - begin);
+ bool TLevelIndexBase::CheckBulkFormedSegments(const char *begin, const char *end) {
+ // empty string is correct bulk-formed segment set
+ if (begin == end)
+ return true;
+
+ TMemoryInput stream(begin, end - begin);
return NKikimrVDiskData::TBulkFormedSstInfoSet().ParseFromArcadiaStream(&stream);
- }
-
- template <class TKey, class TMemRec>
- void TLevelIndex<TKey, TMemRec>::OutputHtml(const TString &name, IOutputStream &str) const
- {
- HTML(str) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << name;
+ }
+
+ template <class TKey, class TMemRec>
+ void TLevelIndex<TKey, TMemRec>::OutputHtml(const TString &name, IOutputStream &str) const
+ {
+ HTML(str) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << name;
// output main db page
str << "<a class=\"btn btn-primary btn-xs navbar-right\""
<< " href=\"?type=dbmainpage&dbname=" << name << "\">Database Main Page</a>";
- // stat db
- str << "<a class=\"btn btn-primary btn-xs navbar-right\""
- << " href=\"?type=stat&dbname=" << name << "\">Database Stat</a>";
- // dump db
- str << "<a class=\"btn btn-primary btn-xs navbar-right\""
- << " href=\"?type=dump&dbname=" << name << "\">Dump Database</a>";
- OutputHugeStatButton(name, str);
- OutputQueryDbButton(name, str);
- }
- DIV_CLASS("panel-body") {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-1") {
- H5() { str << "Fresh"; }
- const char *comp = Fresh.CompactionInProgress() ? "Compaction In Progress" : "No Compaction";
- H6_CLASS ("text-info") {str << comp << " W:" << FreshCompWritesInFlight;}
- }
- DIV_CLASS("col-md-11") {Fresh.OutputHtml(str);}
- }
- DIV_CLASS("row") {
- DIV_CLASS("col-md-1") {
- H5() { str << "Levels"; }
- H6_CLASS ("text-info") {str << GetCompStateStr(HullCompReadsInFlight, HullCompWritesInFlight);}
- }
- DIV_CLASS("col-md-11") {CurSlice->OutputHtml(str);}
- }
+ // stat db
+ str << "<a class=\"btn btn-primary btn-xs navbar-right\""
+ << " href=\"?type=stat&dbname=" << name << "\">Database Stat</a>";
+ // dump db
+ str << "<a class=\"btn btn-primary btn-xs navbar-right\""
+ << " href=\"?type=dump&dbname=" << name << "\">Dump Database</a>";
+ OutputHugeStatButton(name, str);
+ OutputQueryDbButton(name, str);
+ }
+ DIV_CLASS("panel-body") {
+ DIV_CLASS("row") {
+ DIV_CLASS("col-md-1") {
+ H5() { str << "Fresh"; }
+ const char *comp = Fresh.CompactionInProgress() ? "Compaction In Progress" : "No Compaction";
+ H6_CLASS ("text-info") {str << comp << " W:" << FreshCompWritesInFlight;}
+ }
+ DIV_CLASS("col-md-11") {Fresh.OutputHtml(str);}
+ }
+ DIV_CLASS("row") {
+ DIV_CLASS("col-md-1") {
+ H5() { str << "Levels"; }
+ H6_CLASS ("text-info") {str << GetCompStateStr(HullCompReadsInFlight, HullCompWritesInFlight);}
+ }
+ DIV_CLASS("col-md-11") {CurSlice->OutputHtml(str);}
+ }
}
}
}
}
- template class TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TLevelIndex<TKeyBarrier, TMemRecBarrier>;
- template class TLevelIndex<TKeyBlock, TMemRecBlock>;
+ template class TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TLevelIndex<TKeyBarrier, TMemRecBarrier>;
+ template class TLevelIndex<TKeyBlock, TMemRecBlock>;
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.h
index b3b44759129..8b1184d458a 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idx.h
@@ -156,23 +156,23 @@ namespace NKikimr {
typedef NKikimr::TLevelSegment<TKey, TMemRec> TLevelSegment;
typedef NKikimr::TFreshAppendix<TKey, TMemRec> TFreshAppendix;
- static constexpr ui32 GetSignature() {
- if constexpr (std::is_same_v<TKey, TKeyLogoBlob>) {
- return 0x5567FEDC;
- } else if constexpr (std::is_same_v<TKey, TKeyBlock>) {
- return 0x5567FEDD;
- } else if constexpr (std::is_same_v<TKey, TKeyBarrier>) {
- return 0x5567FEDE;
- } else {
- static_assert(!std::is_same_v<TKey, TKey>, "invalid TKey");
- }
- }
-
- static constexpr ui32 Signature = GetSignature();
- static constexpr size_t KeySizeOf = sizeof(TKey);
-
+ static constexpr ui32 GetSignature() {
+ if constexpr (std::is_same_v<TKey, TKeyLogoBlob>) {
+ return 0x5567FEDC;
+ } else if constexpr (std::is_same_v<TKey, TKeyBlock>) {
+ return 0x5567FEDD;
+ } else if constexpr (std::is_same_v<TKey, TKeyBarrier>) {
+ return 0x5567FEDE;
+ } else {
+ static_assert(!std::is_same_v<TKey, TKey>, "invalid TKey");
+ }
+ }
+
+ static constexpr ui32 Signature = GetSignature();
+ static constexpr size_t KeySizeOf = sizeof(TKey);
+
private:
- std::shared_ptr<TLevelIndexCtx> Ctx;
+ std::shared_ptr<TLevelIndexCtx> Ctx;
TFreshData Fresh;
public:
@@ -188,7 +188,7 @@ namespace NKikimr {
TAtomic HullCompWritesInFlight = 0;
TIntrusivePtr<TDelayedHugeBlobDeleterInfo> DelayedHugeBlobDeleterInfo;
- std::shared_ptr<TLevelIndexActorCtx> ActorCtx;
+ std::shared_ptr<TLevelIndexActorCtx> ActorCtx;
private:
// it is used for allocation unique id to a new sst
@@ -225,27 +225,27 @@ namespace NKikimr {
// Constructors just create corresponding structures in memory from entryPoint record or from nothing;
// nothing is loaded into memory from disk, use TLevelIndexLoader for bringing index to memory
- TLevelIndex(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena)
+ TLevelIndex(const TLevelIndexSettings &settings, std::shared_ptr<TRopeArena> arena)
: TLevelIndexBase(settings)
- , Ctx(std::make_shared<TLevelIndexCtx>())
- , Fresh(settings, TAppData::TimeProvider, std::move(arena))
+ , Ctx(std::make_shared<TLevelIndexCtx>())
+ , Fresh(settings, TAppData::TimeProvider, std::move(arena))
, CurSlice(MakeIntrusive<TLevelSlice>(settings, Ctx))
, DelayedHugeBlobDeleterInfo(new TDelayedHugeBlobDeleterInfo)
- , ActorCtx(std::make_shared<TLevelIndexActorCtx>())
+ , ActorCtx(std::make_shared<TLevelIndexActorCtx>())
, CompactedLsn()
{}
TLevelIndex(const TLevelIndexSettings &settings,
const NKikimrVDiskData::TLevelIndex &pb,
- ui64 entryPointLsn,
- std::shared_ptr<TRopeArena> arena)
+ ui64 entryPointLsn,
+ std::shared_ptr<TRopeArena> arena)
: TLevelIndexBase(settings)
- , Ctx(std::make_shared<TLevelIndexCtx>())
- , Fresh(settings, TAppData::TimeProvider, std::move(arena))
+ , Ctx(std::make_shared<TLevelIndexCtx>())
+ , Fresh(settings, TAppData::TimeProvider, std::move(arena))
, CurSlice(MakeIntrusive<TLevelSlice>(settings, Ctx, pb))
, CurEntryPointLsn(entryPointLsn)
, DelayedHugeBlobDeleterInfo(new TDelayedHugeBlobDeleterInfo)
- , ActorCtx(std::make_shared<TLevelIndexActorCtx>())
+ , ActorCtx(std::make_shared<TLevelIndexActorCtx>())
, NextSstId(pb.GetNextSstId())
, CompactedLsn(pb)
{}
@@ -267,16 +267,16 @@ namespace NKikimr {
// Operations with Fresh
//////////////////////////////////////////////////////////////////////////////////////
void PutToFresh(ui64 lsn, const TKey &key, ui8 partId, const TIngress &ingress, TRope buffer) {
- Y_VERIFY_DEBUG(Loaded);
+ Y_VERIFY_DEBUG(Loaded);
Fresh.PutLogoBlobWithData(lsn, key, partId, ingress, std::move(buffer));
- }
-
+ }
+
void PutToFresh(ui64 lsn, const TKey &key, const TMemRec &memRec) {
Y_VERIFY_DEBUG(Loaded);
Fresh.Put(lsn, key, memRec);
}
- void PutToFresh(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
+ void PutToFresh(std::shared_ptr<TFreshAppendix> &&a, ui64 firstLsn, ui64 lastLsn) {
Y_VERIFY_DEBUG(Loaded);
Fresh.PutAppendix(std::move(a), firstLsn, lastLsn);
}
@@ -290,11 +290,11 @@ namespace NKikimr {
TIntrusivePtr<TFreshSegment> FindFreshSegmentForCompaction() {
return Fresh.FindSegmentForCompaction();
}
-
- bool FreshCompactionInProgress() const {
- return Fresh.CompactionInProgress();
- }
-
+
+ bool FreshCompactionInProgress() const {
+ return Fresh.CompactionInProgress();
+ }
+
void FreshCompactionFinished() {
Fresh.CompactionFinished();
}
@@ -313,7 +313,7 @@ namespace NKikimr {
return Min(Min(CurEntryPointLsn, PrevEntryPointLsn), Fresh.GetFirstLsnToKeep());
}
- virtual void LoadCompleted() {
+ virtual void LoadCompleted() {
Y_VERIFY_DEBUG(!Loaded);
Loaded = true;
@@ -427,159 +427,159 @@ namespace NKikimr {
void UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &stat);
};
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Custom implementation of GetSnapshot for every Hull Database (optimization applies)
- ///////////////////////////////////////////////////////////////////////////////////////////
- template <>
- inline TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob> TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::GetSnapshot(TActorSystem *as) {
- return PrivateGetSnapshot(as);
- }
-
- template <>
- inline TLevelIndexSnapshot<TKeyBlock, TMemRecBlock> TLevelIndex<TKeyBlock, TMemRecBlock>::GetSnapshot(TActorSystem *) {
- // we never want to take data snapshots for Blocks Database
- return PrivateGetSnapshot(nullptr);
- }
-
- template <>
- inline TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier> TLevelIndex<TKeyBarrier, TMemRecBarrier>::GetSnapshot(TActorSystem *) {
- // we never want to take data snapshots for Barriers Database
- return PrivateGetSnapshot(nullptr);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Custom implementation of UpdateLevelStat
- ///////////////////////////////////////////////////////////////////////////////////////////
- template <>
- inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &stat) {
- struct TLevelGroupInfo {
- ui64 SstNum = 0;
- ui64 NumItems = 0;
- ui64 NumItemsInplaced = 0;
- ui64 NumItemsHuge = 0;
- ui64 DataInplaced = 0;
- ui64 DataHuge = 0;
- };
-
- TLevelGroupInfo level0, level1to8, level9to16, level17, level18;
-
- auto process = [](TLevelGroupInfo *stat, TLevelSegment *seg) {
- stat->SstNum += 1;
- stat->NumItems += seg->Info.Items;
- stat->NumItemsInplaced += seg->Info.ItemsWithInplacedData;
- stat->NumItemsHuge += seg->Info.ItemsWithHugeData;
- stat->DataInplaced += seg->Info.InplaceDataTotalSize;
- stat->DataHuge += seg->Info.HugeDataTotalSize;
- };
-
- for (const auto& seg : CurSlice->Level0.Segs->Segments) {
- process(&level0, seg.Get());
- }
-
- ui32 levelIndex = 1;
- for (const auto& level : CurSlice->SortedLevels) {
- TLevelGroupInfo *info = nullptr;
- switch (levelIndex) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- info = &level1to8;
- break;
-
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- info = &level9to16;
- break;
-
- case 17:
- info = &level17;
- break;
-
- case 18:
- info = &level18;
- break;
- }
-
- if (info) {
- for (const auto& seg : level.Segs->Segments) {
- process(info, seg.Get());
- }
- }
-
- ++levelIndex;
- }
-
- for (const auto& p : {std::make_pair(&level0, &stat.Level0),
- std::make_pair(&level1to8, &stat.Level1to8),
- std::make_pair(&level9to16, &stat.Level9to16),
- std::make_pair(&level17, &stat.Level17),
- std::make_pair(&level18, &stat.Level18)}) {
- TLevelGroupInfo *from = p.first;
- NMonGroup::TLsmLevelGroup *to = p.second;
- to->SstNum() = from->SstNum;
- to->NumItems() = from->NumItems;
- to->NumItemsInplaced() = from->NumItemsInplaced;
- to->NumItemsHuge() = from->NumItemsHuge;
- to->DataInplaced() = from->DataInplaced;
- to->DataHuge() = from->DataHuge;
- }
- }
-
- template <>
- inline void TLevelIndex<TKeyBlock, TMemRecBlock>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &) {
- // intentionally empty
- }
-
- template <>
- inline void TLevelIndex<TKeyBarrier, TMemRecBarrier>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &) {
- // intentionally empty
- }
-
- template <class TKey, class TMemRec>
- inline void TLevelIndex<TKey, TMemRec>::OutputHugeStatButton(const TString& /*name*/, IOutputStream& /*str*/) const {
- // by default don't output HugeStat button
- }
-
- template <>
- inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::OutputHugeStatButton(const TString& /*name*/, IOutputStream &str) const
- {
- str << "<a class=\"btn btn-primary btn-xs navbar-right\""
- << " href=\"?type=hugestat\">Huge Stat</a>";
- }
-
- template <class TKey, class TMemRec>
- inline void TLevelIndex<TKey, TMemRec>::OutputQueryDbButton(const TString& /*name*/, IOutputStream& /*str*/) const {
- // by default don't output QueryDb button
- }
-
- template <>
- inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::OutputQueryDbButton(const TString &name, IOutputStream &str) const
- {
- str << "<a class=\"btn btn-primary btn-xs navbar-right\""
- << " href=\"?type=query&dbname=" << name << "&form=1\">Query Database</a>";
- }
-
- template <>
- inline void TLevelIndex<TKeyBarrier, TMemRecBarrier>::OutputQueryDbButton(const TString &name, IOutputStream &str) const
- {
- str << "<a class=\"btn btn-primary btn-xs navbar-right\""
- << " href=\"?type=query&dbname=" << name << "&form=1\">Query Database</a>";
- }
-
- extern template class TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TLevelIndex<TKeyBarrier, TMemRecBarrier>;
- extern template class TLevelIndex<TKeyBlock, TMemRecBlock>;
-
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Custom implementation of GetSnapshot for every Hull Database (optimization applies)
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ template <>
+ inline TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob> TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::GetSnapshot(TActorSystem *as) {
+ return PrivateGetSnapshot(as);
+ }
+
+ template <>
+ inline TLevelIndexSnapshot<TKeyBlock, TMemRecBlock> TLevelIndex<TKeyBlock, TMemRecBlock>::GetSnapshot(TActorSystem *) {
+ // we never want to take data snapshots for Blocks Database
+ return PrivateGetSnapshot(nullptr);
+ }
+
+ template <>
+ inline TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier> TLevelIndex<TKeyBarrier, TMemRecBarrier>::GetSnapshot(TActorSystem *) {
+ // we never want to take data snapshots for Barriers Database
+ return PrivateGetSnapshot(nullptr);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Custom implementation of UpdateLevelStat
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ template <>
+ inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &stat) {
+ struct TLevelGroupInfo {
+ ui64 SstNum = 0;
+ ui64 NumItems = 0;
+ ui64 NumItemsInplaced = 0;
+ ui64 NumItemsHuge = 0;
+ ui64 DataInplaced = 0;
+ ui64 DataHuge = 0;
+ };
+
+ TLevelGroupInfo level0, level1to8, level9to16, level17, level18;
+
+ auto process = [](TLevelGroupInfo *stat, TLevelSegment *seg) {
+ stat->SstNum += 1;
+ stat->NumItems += seg->Info.Items;
+ stat->NumItemsInplaced += seg->Info.ItemsWithInplacedData;
+ stat->NumItemsHuge += seg->Info.ItemsWithHugeData;
+ stat->DataInplaced += seg->Info.InplaceDataTotalSize;
+ stat->DataHuge += seg->Info.HugeDataTotalSize;
+ };
+
+ for (const auto& seg : CurSlice->Level0.Segs->Segments) {
+ process(&level0, seg.Get());
+ }
+
+ ui32 levelIndex = 1;
+ for (const auto& level : CurSlice->SortedLevels) {
+ TLevelGroupInfo *info = nullptr;
+ switch (levelIndex) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ info = &level1to8;
+ break;
+
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ info = &level9to16;
+ break;
+
+ case 17:
+ info = &level17;
+ break;
+
+ case 18:
+ info = &level18;
+ break;
+ }
+
+ if (info) {
+ for (const auto& seg : level.Segs->Segments) {
+ process(info, seg.Get());
+ }
+ }
+
+ ++levelIndex;
+ }
+
+ for (const auto& p : {std::make_pair(&level0, &stat.Level0),
+ std::make_pair(&level1to8, &stat.Level1to8),
+ std::make_pair(&level9to16, &stat.Level9to16),
+ std::make_pair(&level17, &stat.Level17),
+ std::make_pair(&level18, &stat.Level18)}) {
+ TLevelGroupInfo *from = p.first;
+ NMonGroup::TLsmLevelGroup *to = p.second;
+ to->SstNum() = from->SstNum;
+ to->NumItems() = from->NumItems;
+ to->NumItemsInplaced() = from->NumItemsInplaced;
+ to->NumItemsHuge() = from->NumItemsHuge;
+ to->DataInplaced() = from->DataInplaced;
+ to->DataHuge() = from->DataHuge;
+ }
+ }
+
+ template <>
+ inline void TLevelIndex<TKeyBlock, TMemRecBlock>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &) {
+ // intentionally empty
+ }
+
+ template <>
+ inline void TLevelIndex<TKeyBarrier, TMemRecBarrier>::UpdateLevelStat(NMonGroup::TLsmAllLevelsStat &) {
+ // intentionally empty
+ }
+
+ template <class TKey, class TMemRec>
+ inline void TLevelIndex<TKey, TMemRec>::OutputHugeStatButton(const TString& /*name*/, IOutputStream& /*str*/) const {
+ // by default don't output HugeStat button
+ }
+
+ template <>
+ inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::OutputHugeStatButton(const TString& /*name*/, IOutputStream &str) const
+ {
+ str << "<a class=\"btn btn-primary btn-xs navbar-right\""
+ << " href=\"?type=hugestat\">Huge Stat</a>";
+ }
+
+ template <class TKey, class TMemRec>
+ inline void TLevelIndex<TKey, TMemRec>::OutputQueryDbButton(const TString& /*name*/, IOutputStream& /*str*/) const {
+ // by default don't output QueryDb button
+ }
+
+ template <>
+ inline void TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>::OutputQueryDbButton(const TString &name, IOutputStream &str) const
+ {
+ str << "<a class=\"btn btn-primary btn-xs navbar-right\""
+ << " href=\"?type=query&dbname=" << name << "&form=1\">Query Database</a>";
+ }
+
+ template <>
+ inline void TLevelIndex<TKeyBarrier, TMemRecBarrier>::OutputQueryDbButton(const TString &name, IOutputStream &str) const
+ {
+ str << "<a class=\"btn btn-primary btn-xs navbar-right\""
+ << " href=\"?type=query&dbname=" << name << "&form=1\">Query Database</a>";
+ }
+
+ extern template class TLevelIndex<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TLevelIndex<TKeyBarrier, TMemRecBarrier>;
+ extern template class TLevelIndex<TKeyBlock, TMemRecBlock>;
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.cpp
index efd15163865..d26b96031de 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.cpp
@@ -1,9 +1,9 @@
-#include "hullds_idxsnap_it.h"
-
-namespace NKikimr {
-
- template class TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier>;
- template class TLevelIndexSnapshot<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "hullds_idxsnap_it.h"
+
+namespace NKikimr {
+
+ template class TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier>;
+ template class TLevelIndexSnapshot<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.h
index a32c54ae889..aa1c529227b 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_idxsnap.h
@@ -41,8 +41,8 @@ namespace NKikimr {
TLevelIndexSnapshot(TLevelIndexSnapshot &&) = default;
void Destroy() {
- SliceSnap.Destroy();
- FreshSnap.Destroy();
+ SliceSnap.Destroy();
+ FreshSnap.Destroy();
Notifier.Drop();
}
@@ -56,15 +56,15 @@ namespace NKikimr {
class TIndexForwardIterator;
class TIndexBackwardIterator;
- TLevelSliceSnapshot SliceSnap;
- TFreshDataSnapshot FreshSnap;
-
+ TLevelSliceSnapshot SliceSnap;
+ TFreshDataSnapshot FreshSnap;
+
private:
TIntrusivePtr<TDelayedHugeBlobDeleterNotifier> Notifier;
};
- extern template class TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier>;
- extern template class TLevelIndexSnapshot<TKeyBlock, TMemRecBlock>;
-
+ extern template class TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TLevelIndexSnapshot<TKeyBarrier, TMemRecBarrier>;
+ extern template class TLevelIndexSnapshot<TKeyBlock, TMemRecBlock>;
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_leveledssts.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_leveledssts.h
index b7de273a482..2f51a5762c0 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_leveledssts.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_leveledssts.h
@@ -75,8 +75,8 @@ namespace NKikimr {
, Pos(0)
{}
- TIterator(const TIterator&) = default;
- TIterator& operator =(const TIterator&) = default;
+ TIterator(const TIterator&) = default;
+ TIterator& operator =(const TIterator&) = default;
void SeekToFirst() {
Pos = 0;
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.cpp
index 71260dcffbe..afe0c43760c 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.cpp
@@ -1,34 +1,34 @@
-#include "hullds_sst.h"
-#include "hullds_sst_it.h"
+#include "hullds_sst.h"
+#include "hullds_sst_it.h"
#include <ydb/core/blobstorage/base/utility.h>
-#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NKikimr {
-
- template <class TKey, class TMemRec>
- void TLevelSegment<TKey, TMemRec>::OutputHtml(ui32 &index, ui32 level, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
- HTML(str) {
- if (IsLoaded()) {
- TABLER() {
- TABLED() {SMALL() {str << index;}}
- TABLED() {SMALL() {str << level;}}
- TABLED() {SMALL() {str << Info.FirstLsn << " / " << Info.LastLsn;}}
- TABLED() {SMALL() {str << Info.IdxTotalSize << " / " << Info.InplaceDataTotalSize << " / "
- << Info.HugeDataTotalSize;}}
- TABLED() {SMALL() {str << Info.Chunks << " / " << Info.IndexParts;}}
- TABLED() {SMALL() {str << Info.Items << " / " << Info.ItemsWithInplacedData << " / "
- << Info.ItemsWithHugeData;}}
- TABLED() {SMALL() {str << FirstKey().ToString() << "\n" << LastKey().ToString();}}
- TABLED() {SMALL() {str << StorageRatio.MonSummary();}}
- TABLED() {SMALL() {str << (Info.IsCreatedByRepl() ? "REPL" : "COMP");}}
- TABLED() {SMALL() {str << ToStringLocalTimeUpToSeconds(Info.CTime);}}
- ++index;
- }
- }
- }
- sum += Info;
- }
-
+#include <library/cpp/monlib/service/pages/templates.h>
+
+namespace NKikimr {
+
+ template <class TKey, class TMemRec>
+ void TLevelSegment<TKey, TMemRec>::OutputHtml(ui32 &index, ui32 level, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
+ HTML(str) {
+ if (IsLoaded()) {
+ TABLER() {
+ TABLED() {SMALL() {str << index;}}
+ TABLED() {SMALL() {str << level;}}
+ TABLED() {SMALL() {str << Info.FirstLsn << " / " << Info.LastLsn;}}
+ TABLED() {SMALL() {str << Info.IdxTotalSize << " / " << Info.InplaceDataTotalSize << " / "
+ << Info.HugeDataTotalSize;}}
+ TABLED() {SMALL() {str << Info.Chunks << " / " << Info.IndexParts;}}
+ TABLED() {SMALL() {str << Info.Items << " / " << Info.ItemsWithInplacedData << " / "
+ << Info.ItemsWithHugeData;}}
+ TABLED() {SMALL() {str << FirstKey().ToString() << "\n" << LastKey().ToString();}}
+ TABLED() {SMALL() {str << StorageRatio.MonSummary();}}
+ TABLED() {SMALL() {str << (Info.IsCreatedByRepl() ? "REPL" : "COMP");}}
+ TABLED() {SMALL() {str << ToStringLocalTimeUpToSeconds(Info.CTime);}}
+ ++index;
+ }
+ }
+ }
+ sum += Info;
+ }
+
template <class TKey, class TMemRec>
void TLevelSegment<TKey, TMemRec>::Output(IOutputStream &str) const {
str << "[" << FirstKey().ToString() << " " << LastKey().ToString() << " Info# ";
@@ -36,8 +36,8 @@ namespace NKikimr {
str << " Ratio# " << StorageRatio.MonSummary() << "]";
}
- template struct TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- template struct TLevelSegment<TKeyBarrier, TMemRecBarrier>;
- template struct TLevelSegment<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+ template struct TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ template struct TLevelSegment<TKeyBarrier, TMemRecBarrier>;
+ template struct TLevelSegment<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h
index bfe29070de9..b407828c373 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h
@@ -86,7 +86,7 @@ namespace NKikimr {
TTrackableVector<TDiskPart> LoadedOutbound;
TIdxDiskPlaceHolder::TInfo Info;
TVector<ui32> AllChunks; // all chunk ids that store index and data for this segment
- std::vector<TDiskPart> IndexParts; // index part locations; the first one is 'placeholder', stored as LastPartAddr
+ std::vector<TDiskPart> IndexParts; // index part locations; the first one is 'placeholder', stored as LastPartAddr
NHullComp::TSstRatioThreadSafeHolder StorageRatio;
// Every Sst has unique id
ui64 AssignedSstId = 0;
@@ -168,10 +168,10 @@ namespace NKikimr {
case TBlobType::ManyHugeBlobs:
it.GetDiskData(&extr);
for (const TDiskPart *part = extr.Begin; part != extr.End; ++part) {
- if (part->Size) {
- Y_VERIFY(part->ChunkIdx);
- chunks.insert(part->ChunkIdx);
- }
+ if (part->Size) {
+ Y_VERIFY(part->ChunkIdx);
+ chunks.insert(part->ChunkIdx);
+ }
}
extr.Clear();
break;
@@ -191,22 +191,22 @@ namespace NKikimr {
const TKey &FirstKey() const;
const TKey &LastKey() const;
// number of elements in the sst
- ui64 Elements() const {
- Y_VERIFY_DEBUG(IsLoaded());
- return LoadedIndex.size();
- }
+ ui64 Elements() const {
+ Y_VERIFY_DEBUG(IsLoaded());
+ return LoadedIndex.size();
+ }
// append cur seg chunk ids (index and data) to the vector
- void FillInChunkIds(TVector<ui32> &vec) const {
- // copy chunks ids
- for (auto idx : AllChunks)
- vec.push_back(idx);
- }
+ void FillInChunkIds(TVector<ui32> &vec) const {
+ // copy chunks ids
+ for (auto idx : AllChunks)
+ vec.push_back(idx);
+ }
void OutputHtml(ui32 &index, ui32 level, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const;
// dump all accessible data
- void DumpAll(IOutputStream &str) const {
- str << "=== SST ===\n";
- // We can add dump of SST here to be more verbose
- }
+ void DumpAll(IOutputStream &str) const {
+ str << "=== SST ===\n";
+ // We can add dump of SST here to be more verbose
+ }
void Output(IOutputStream &str) const;
class TBaseWriter;
@@ -215,9 +215,9 @@ namespace NKikimr {
class TWriter;
};
- extern template struct TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template struct TLevelSegment<TKeyBarrier, TMemRecBarrier>;
- extern template struct TLevelSegment<TKeyBlock, TMemRecBlock>;
-
+ extern template struct TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template struct TLevelSegment<TKeyBarrier, TMemRecBarrier>;
+ extern template struct TLevelSegment<TKeyBlock, TMemRecBlock>;
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it.h
index b4fe82f2d34..269700c2917 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it.h
@@ -26,19 +26,19 @@ namespace NKikimr {
const TRec *Begin() const {
- return Segment->LoadedIndex.data();
+ return Segment->LoadedIndex.data();
}
const TRec *End() const {
- return Segment->LoadedIndex.data() + Segment->LoadedIndex.size();
+ return Segment->LoadedIndex.data() + Segment->LoadedIndex.size();
}
TRec *Begin() {
- return const_cast<TLevelSegment *>(Segment)->LoadedIndex.data();
+ return const_cast<TLevelSegment *>(Segment)->LoadedIndex.data();
}
TRec *End() {
- return const_cast<TLevelSegment *>(Segment)->LoadedIndex.data() + Segment->LoadedIndex.size();
+ return const_cast<TLevelSegment *>(Segment)->LoadedIndex.data() + Segment->LoadedIndex.size();
}
public:
@@ -118,7 +118,7 @@ namespace NKikimr {
return !operator == (it);
}
- TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr) const {
+ TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr) const {
return Ptr->MemRec.GetDiskData(extr, Segment->GetOutbound());
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp
index f965e75f61f..498f716ed50 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst_it_all_ut.cpp
@@ -24,7 +24,7 @@ namespace NKikimr {
for (ui32 i = 0; i < recs; i++) {
TLogoBlobID id(tabletId, generation, step + i * plus, channel, 0, cookie);
TRec rec {TKeyLogoBlob(id), TMemRecLogoBlob()};
- ptr->LoadedIndex.push_back(rec);
+ ptr->LoadedIndex.push_back(rec);
}
return ptr;
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.cpp
index e4a2a0bf203..99d2ab12477 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.cpp
@@ -1,66 +1,66 @@
-#include "hullds_sstslice_it.h"
-#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NKikimr {
-
- template <class TKey, class TMemRec>
- void TLevelSlice<TKey, TMemRec>::OutputHtml(IOutputStream &str) const {
- TIdxDiskPlaceHolder::TInfo sum;
- HTML(str) {
- TABLE_CLASS ("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {str << "&#8470;";} // numero sign
- TABLEH() {str << "Level";}
- TABLEH() {str << "First / Last Lsn";}
- TABLEH() {str << "Idx / Inplaced / Huge Size";}
- TABLEH() {str << "Chunks / Index";}
- TABLEH() {str << "Items / WInplData / WHugeData";}
- TABLEH() {str << "First / Last Key";}
- TABLEH() {str << NHullComp::TSstRatio::MonHeader();}
- TABLEH() {str << "Origin";}
- TABLEH() {str << "CTime";}
- }
- }
- TABLEBODY() {
- ui32 index = 1;
-
- if (!Level0.Empty()) {
- Level0.OutputHtml(index, str, sum);
- }
-
- ui32 level = 1;
- for (const auto &x : SortedLevels) {
- if (!x.Empty()) {
- x.OutputHtml(index, level, str, sum);
- }
- ++level;
- }
- // total
- TABLER() {
- TABLED() {SMALL() {str << "index";}}
- TABLED() {SMALL() {str << "total";}}
- TABLED() {SMALL() {str << "lsns";}}
- TABLED() {SMALL() {str << sum.IdxTotalSize << " / " << sum.InplaceDataTotalSize << " / "
- << sum.HugeDataTotalSize;}}
- TABLED() {SMALL() {str << sum.Chunks << " / " << sum.IndexParts;}}
- TABLED() {SMALL() {str << sum.Items << " / " << sum.ItemsWithInplacedData << " / "
- << sum.ItemsWithHugeData;}}
- TABLED() {SMALL() {str << "keys";}}
- TABLED() {SMALL() {str << "ratio";}}
- TABLED() {SMALL() {str << "time";}}
- }
- }
- }
- }
- }
-
- template struct TLevelSlice<TKeyLogoBlob, TMemRecLogoBlob>;
- template struct TLevelSlice<TKeyBarrier, TMemRecBarrier>;
- template struct TLevelSlice<TKeyBlock, TMemRecBlock>;
-
- template class TLevelSliceSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- template class TLevelSliceSnapshot<TKeyBarrier, TMemRecBarrier>;
- template class TLevelSliceSnapshot<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "hullds_sstslice_it.h"
+#include <library/cpp/monlib/service/pages/templates.h>
+
+namespace NKikimr {
+
+ template <class TKey, class TMemRec>
+ void TLevelSlice<TKey, TMemRec>::OutputHtml(IOutputStream &str) const {
+ TIdxDiskPlaceHolder::TInfo sum;
+ HTML(str) {
+ TABLE_CLASS ("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() {str << "&#8470;";} // numero sign
+ TABLEH() {str << "Level";}
+ TABLEH() {str << "First / Last Lsn";}
+ TABLEH() {str << "Idx / Inplaced / Huge Size";}
+ TABLEH() {str << "Chunks / Index";}
+ TABLEH() {str << "Items / WInplData / WHugeData";}
+ TABLEH() {str << "First / Last Key";}
+ TABLEH() {str << NHullComp::TSstRatio::MonHeader();}
+ TABLEH() {str << "Origin";}
+ TABLEH() {str << "CTime";}
+ }
+ }
+ TABLEBODY() {
+ ui32 index = 1;
+
+ if (!Level0.Empty()) {
+ Level0.OutputHtml(index, str, sum);
+ }
+
+ ui32 level = 1;
+ for (const auto &x : SortedLevels) {
+ if (!x.Empty()) {
+ x.OutputHtml(index, level, str, sum);
+ }
+ ++level;
+ }
+ // total
+ TABLER() {
+ TABLED() {SMALL() {str << "index";}}
+ TABLED() {SMALL() {str << "total";}}
+ TABLED() {SMALL() {str << "lsns";}}
+ TABLED() {SMALL() {str << sum.IdxTotalSize << " / " << sum.InplaceDataTotalSize << " / "
+ << sum.HugeDataTotalSize;}}
+ TABLED() {SMALL() {str << sum.Chunks << " / " << sum.IndexParts;}}
+ TABLED() {SMALL() {str << sum.Items << " / " << sum.ItemsWithInplacedData << " / "
+ << sum.ItemsWithHugeData;}}
+ TABLED() {SMALL() {str << "keys";}}
+ TABLED() {SMALL() {str << "ratio";}}
+ TABLED() {SMALL() {str << "time";}}
+ }
+ }
+ }
+ }
+ }
+
+ template struct TLevelSlice<TKeyLogoBlob, TMemRecLogoBlob>;
+ template struct TLevelSlice<TKeyBarrier, TMemRecBarrier>;
+ template struct TLevelSlice<TKeyBlock, TMemRecBlock>;
+
+ template class TLevelSliceSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ template class TLevelSliceSnapshot<TKeyBarrier, TMemRecBarrier>;
+ template class TLevelSliceSnapshot<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.h
index 83d7253d3bf..31bb884a818 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstslice.h
@@ -41,18 +41,18 @@ namespace NKikimr {
// Max number of ssts at Level 0
const ui32 MaxSstsAtOnce;
// Context
- std::shared_ptr<TLevelIndexCtx> Ctx;
+ std::shared_ptr<TLevelIndexCtx> Ctx;
TUnorderedLevelSegmentsPtr Segs;
TLevel0(const TLevelIndexSettings &settings,
- const std::shared_ptr<TLevelIndexCtx> &ctx)
+ const std::shared_ptr<TLevelIndexCtx> &ctx)
: MaxSstsAtOnce(settings.GetMaxSstsAtLevel0AtOnce())
, Ctx(ctx)
, Segs(MakeIntrusive<TUnorderedLevelSegments>(settings.HullCtx->VCtx))
{}
TLevel0(const TLevelIndexSettings &settings,
- const std::shared_ptr<TLevelIndexCtx> &ctx,
+ const std::shared_ptr<TLevelIndexCtx> &ctx,
const NKikimrVDiskData::TLevel0 &pb)
: MaxSstsAtOnce(settings.GetMaxSstsAtLevel0AtOnce())
, Ctx(ctx)
@@ -91,7 +91,7 @@ namespace NKikimr {
}
void OutputHtml(ui32 &index, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
- Segs->OutputHtml(index, str, sum);
+ Segs->OutputHtml(index, str, sum);
}
typename TUnorderedLevelSegments::TSstIterator GetSstIterator(ui32 numLimit) const {
@@ -105,10 +105,10 @@ namespace NKikimr {
TSatisfactionRank GetSatisfactionRank() const {
return TSatisfactionRank::MkRatio(Segs->CurSstsNum(), MaxSstsAtOnce);
}
-
+
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- Segs->GetOwnedChunks(chunks);
- }
+ Segs->GetOwnedChunks(chunks);
+ }
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -160,11 +160,11 @@ namespace NKikimr {
}
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- Segs->GetOwnedChunks(chunks);
- }
-
+ Segs->GetOwnedChunks(chunks);
+ }
+
void OutputHtml(ui32 &index, ui32 level, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
- Segs->OutputHtml(index, level, str, sum);
+ Segs->OutputHtml(index, level, str, sum);
}
};
@@ -185,7 +185,7 @@ namespace NKikimr {
TLevel0 Level0;
TSortedLevels SortedLevels;
- std::shared_ptr<TLevelIndexCtx> Ctx;
+ std::shared_ptr<TLevelIndexCtx> Ctx;
// when slice is destroyed we notify CommitterId about this event (i.e. ChunksToDelete are not used anymore)
TActorSystem * /*const*/ ActorSystem;
@@ -193,14 +193,14 @@ namespace NKikimr {
// In ChunksToDelete we store chunks that are old and subject for deletion,
// but previous snapshot can still use them
TVector<ui32> ChunksToDelete;
- // Bulk-formed segments description; they contain only these bulk-formed SST references, which are required
- // to recover SyncLog in case of failure
- TBulkFormedSstInfoSet BulkFormedSegments;
- // last calculated total storage ratio for the whole level slice
- NHullComp::TSstRatio LastPublishedRatio;
+ // Bulk-formed segments description; they contain only these bulk-formed SST references, which are required
+ // to recover SyncLog in case of failure
+ TBulkFormedSstInfoSet BulkFormedSegments;
+ // last calculated total storage ratio for the whole level slice
+ NHullComp::TSstRatio LastPublishedRatio;
TLevelSlice(const TLevelIndexSettings &settings,
- const std::shared_ptr<TLevelIndexCtx> &ctx)
+ const std::shared_ptr<TLevelIndexCtx> &ctx)
: Level0(settings, ctx)
, SortedLevels()
, Ctx(ctx)
@@ -211,7 +211,7 @@ namespace NKikimr {
{}
TLevelSlice(const TLevelIndexSettings &settings,
- const std::shared_ptr<TLevelIndexCtx> &ctx,
+ const std::shared_ptr<TLevelIndexCtx> &ctx,
const NKikimrVDiskData::TLevelIndex &pb)
: Level0(settings, ctx, pb.GetLevel0())
, SortedLevels()
@@ -358,22 +358,22 @@ namespace NKikimr {
}
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- // we include deleted chunks
- for (TChunkIdx chunkIdx : ChunksToDelete) {
- const bool inserted = chunks.insert(chunkIdx).second;
- Y_VERIFY(inserted);
- }
-
- // include bulk formed segments
- BulkFormedSegments.GetOwnedChunks(chunks);
-
- // include levels
- Level0.GetOwnedChunks(chunks);
- for (const auto& level : SortedLevels) {
- level.GetOwnedChunks(chunks);
- }
- }
-
+ // we include deleted chunks
+ for (TChunkIdx chunkIdx : ChunksToDelete) {
+ const bool inserted = chunks.insert(chunkIdx).second;
+ Y_VERIFY(inserted);
+ }
+
+ // include bulk formed segments
+ BulkFormedSegments.GetOwnedChunks(chunks);
+
+ // include levels
+ Level0.GetOwnedChunks(chunks);
+ for (const auto& level : SortedLevels) {
+ level.GetOwnedChunks(chunks);
+ }
+ }
+
// iterator through sorted levels (doesn't include Level0)
class TSortedLevelsIter;
// iterator through ssts (all SortedLevels)
@@ -385,10 +385,10 @@ namespace NKikimr {
class TBackwardIterator;
};
- extern template struct TLevelSlice<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template struct TLevelSlice<TKeyBarrier, TMemRecBarrier>;
- extern template struct TLevelSlice<TKeyBlock, TMemRecBlock>;
-
+ extern template struct TLevelSlice<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template struct TLevelSlice<TKeyBarrier, TMemRecBarrier>;
+ extern template struct TLevelSlice<TKeyBlock, TMemRecBlock>;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TLevelSliceSnapshot
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -416,7 +416,7 @@ namespace NKikimr {
{}
TLevelSliceSnapshot(const TLevelSliceSnapshot &snap) = default;
- TLevelSliceSnapshot(TLevelSliceSnapshot &&snap) = default;
+ TLevelSliceSnapshot(TLevelSliceSnapshot &&snap) = default;
void Destroy() {
Slice.Drop();
@@ -479,10 +479,10 @@ namespace NKikimr {
class TBackwardIterator;
};
- extern template class TLevelSliceSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template class TLevelSliceSnapshot<TKeyBarrier, TMemRecBarrier>;
- extern template class TLevelSliceSnapshot<TKeyBlock, TMemRecBlock>;
-
+ extern template class TLevelSliceSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template class TLevelSliceSnapshot<TKeyBarrier, TMemRecBarrier>;
+ extern template class TLevelSliceSnapshot<TKeyBlock, TMemRecBlock>;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TLevelIndexActorCtx
// Some data that is used by LevelIndexActor
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.cpp b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.cpp
index ac20d81d041..753d7284440 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.cpp
@@ -1,13 +1,13 @@
-#include "hullds_sstvec_it.h"
-
-namespace NKikimr {
-
- template struct TOrderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
- template struct TOrderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
- template struct TOrderedLevelSegments<TKeyBlock, TMemRecBlock>;
-
- template struct TUnorderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
- template struct TUnorderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
- template struct TUnorderedLevelSegments<TKeyBlock, TMemRecBlock>;
-
-} // NKikimr
+#include "hullds_sstvec_it.h"
+
+namespace NKikimr {
+
+ template struct TOrderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
+ template struct TOrderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
+ template struct TOrderedLevelSegments<TKeyBlock, TMemRecBlock>;
+
+ template struct TUnorderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
+ template struct TUnorderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
+ template struct TUnorderedLevelSegments<TKeyBlock, TMemRecBlock>;
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.h
index 0a30c1e20b0..e348f718175 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec.h
@@ -78,17 +78,17 @@ namespace NKikimr {
}
// append cur seg chunk ids (index and data) to the vector
- void FillInChunkIds(TVector<ui32> &vec) const {
- for (const auto &x : Segments)
- x->FillInChunkIds(vec);
- }
+ void FillInChunkIds(TVector<ui32> &vec) const {
+ for (const auto &x : Segments)
+ x->FillInChunkIds(vec);
+ }
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- for (const TLevelSegmentPtr& seg : Segments) {
- seg->GetOwnedChunks(chunks);
- }
- }
-
+ for (const TLevelSegmentPtr& seg : Segments) {
+ seg->GetOwnedChunks(chunks);
+ }
+ }
+
void SerializeToProto(NKikimrVDiskData::TLevelX &pb) const {
for (const auto &x : Segments) {
auto sst = pb.AddSsts();
@@ -151,7 +151,7 @@ namespace NKikimr {
void OutputHtml(ui32 &index, ui32 level, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
for (typename TSegments::const_iterator it = Segments.begin(), e = Segments.end(); it != e; ++it) {
- (*it)->OutputHtml(index, level, str, sum);
+ (*it)->OutputHtml(index, level, str, sum);
}
}
@@ -165,9 +165,9 @@ namespace NKikimr {
class TSstIterator; // iterate via ssts
};
- extern template struct TOrderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template struct TOrderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
- extern template struct TOrderedLevelSegments<TKeyBlock, TMemRecBlock>;
+ extern template struct TOrderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template struct TOrderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
+ extern template struct TOrderedLevelSegments<TKeyBlock, TMemRecBlock>;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TUnorderedLevelSegments
@@ -252,22 +252,22 @@ namespace NKikimr {
void OutputHtml(ui32 &index, IOutputStream &str, TIdxDiskPlaceHolder::TInfo &sum) const {
for (const auto &x : Segments) {
if (x)
- x->OutputHtml(index, 0, str, sum);
+ x->OutputHtml(index, 0, str, sum);
}
}
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- for (const TLevelSegmentPtr& seg : Segments) {
- seg->GetOwnedChunks(chunks);
- }
- }
-
+ for (const TLevelSegmentPtr& seg : Segments) {
+ seg->GetOwnedChunks(chunks);
+ }
+ }
+
// iterator through ssts
class TSstIterator;
};
- extern template struct TUnorderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
- extern template struct TUnorderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
- extern template struct TUnorderedLevelSegments<TKeyBlock, TMemRecBlock>;
-
+ extern template struct TUnorderedLevelSegments<TKeyLogoBlob, TMemRecLogoBlob>;
+ extern template struct TUnorderedLevelSegments<TKeyBarrier, TMemRecBarrier>;
+ extern template struct TUnorderedLevelSegments<TKeyBlock, TMemRecBlock>;
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec_it.h b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec_it.h
index 702b0976d35..75df84737ef 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec_it.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sstvec_it.h
@@ -138,7 +138,7 @@ namespace NKikimr {
return !operator == (it);
}
- TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr) const {
+ TDiskDataExtractor *GetDiskData(TDiskDataExtractor *extr) const {
return CurSegIt.GetDiskData(extr);
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/generic/ya.make b/ydb/core/blobstorage/vdisk/hulldb/generic/ya.make
index 00d6b0f0f8e..1fbbdd404e8 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/generic/ya.make
+++ b/ydb/core/blobstorage/vdisk/hulldb/generic/ya.make
@@ -18,17 +18,17 @@ SRCS(
hulldb_events.h
hullds_idx.cpp
hullds_idx.h
- hullds_idxsnap.cpp
+ hullds_idxsnap.cpp
hullds_idxsnap.h
hullds_idxsnap_it.h
hullds_leveledssts.h
- hullds_sst.cpp
+ hullds_sst.cpp
hullds_sst.h
hullds_sst_it.h
- hullds_sstslice.cpp
+ hullds_sstslice.cpp
hullds_sstslice.h
hullds_sstslice_it.h
- hullds_sstvec.cpp
+ hullds_sstvec.cpp
hullds_sstvec.h
hullds_sstvec_it.h
)
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h b/ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h
index b2a22b83c3a..1cefdc1ced0 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h
@@ -39,15 +39,15 @@ namespace NKikimr {
using TFreshAppendixBarriers = TFreshAppendix<TKeyBarrier, TMemRecBarrier>;
struct TFreshBatch {
- std::shared_ptr<TFreshAppendixLogoBlobs> LogoBlobs;
- std::shared_ptr<TFreshAppendixBlocks> Blocks;
- std::shared_ptr<TFreshAppendixBarriers> Barriers;
+ std::shared_ptr<TFreshAppendixLogoBlobs> LogoBlobs;
+ std::shared_ptr<TFreshAppendixBlocks> Blocks;
+ std::shared_ptr<TFreshAppendixBarriers> Barriers;
bool IsReady() const { return LogoBlobs || Blocks || Barriers; }
void Clear() {
- LogoBlobs.reset();
- Blocks.reset();
- Barriers.reset();
+ LogoBlobs.reset();
+ Blocks.reset();
+ Barriers.reset();
}
ui64 GetRecords() const {
return (LogoBlobs ? LogoBlobs->GetSize() : 0)
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h
index dcf23836d63..ba444a3f7af 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h
@@ -68,20 +68,20 @@ namespace NKikimr {
BarriersAdditions = std::move(vec);
}
- ui32 GetLsnRange() const {
- ui32 res = 0;
- for (const auto& x : LogoBlobsAdditions) {
- res += x.RecsNum;
- }
- for (const auto& x : BlocksAdditions) {
- res += x.RecsNum;
- }
- for (const auto& x : BarriersAdditions) {
- res += x.RecsNum;
- }
- return res;
- }
-
+ ui32 GetLsnRange() const {
+ ui32 res = 0;
+ for (const auto& x : LogoBlobsAdditions) {
+ res += x.RecsNum;
+ }
+ for (const auto& x : BlocksAdditions) {
+ res += x.RecsNum;
+ }
+ for (const auto& x : BarriersAdditions) {
+ res += x.RecsNum;
+ }
+ return res;
+ }
+
private:
template <class TAddition>
static void SerializeToProto(TAddition &x, NKikimrVDiskData::TAddBulkSstRecoveryLogRec::TSstAndRecsNum *ad) {
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.cpp b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.cpp
index 3cc7d07a196..a2eee91c5d4 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.cpp
@@ -1,28 +1,28 @@
#include "hulldb_bulksstmngr.h"
#include "hulldb_bulksstloaded.h"
#include <ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h>
-
-namespace NKikimr {
-
- namespace NLoaderActor {
- using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
+
+namespace NKikimr {
+
+ namespace NLoaderActor {
+ using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
using THullSegLoaded = NKikimr::THullSegLoaded<TLevelSegment>;
-
- class TLoaderActor : public TActorBootstrapped<TLoaderActor> {
- struct TBulkSegmentLoadQueueItem {
- TLevelSegmentPtr Segment;
- ui64 FirstLsn;
- ui64 LastLsn;
-
- TBulkSegmentLoadQueueItem(TLevelSegmentPtr segment, ui64 firstLsn, ui64 lastLsn)
- : FirstLsn(firstLsn)
- , LastLsn(lastLsn)
- {
- Segment.Swap(segment);
- }
- };
-
+
+ class TLoaderActor : public TActorBootstrapped<TLoaderActor> {
+ struct TBulkSegmentLoadQueueItem {
+ TLevelSegmentPtr Segment;
+ ui64 FirstLsn;
+ ui64 LastLsn;
+
+ TBulkSegmentLoadQueueItem(TLevelSegmentPtr segment, ui64 firstLsn, ui64 lastLsn)
+ : FirstLsn(firstLsn)
+ , LastLsn(lastLsn)
+ {
+ Segment.Swap(segment);
+ }
+ };
+
TVDiskContextPtr VCtx;
TPDiskCtxPtr PDiskCtx;
const TActorId LocalRecoveryActorId;
@@ -30,178 +30,178 @@ namespace NKikimr {
THashMap<TActorId, TBulkSegmentLoadQueueItem> BulkSegmentLoadInFlight;
TVector<TLevelSegmentPtr> Segments;
TActiveActors ActiveActors;
-
- public:
+
+ public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_BULK_SST_LOADER;
- }
-
+ return NKikimrServices::TActivity::BS_BULK_SST_LOADER;
+ }
+
TLoaderActor(TVDiskContextPtr &&vctx, TPDiskCtxPtr &&pdiskCtx, const TActorId& localRecoveryActorId)
: VCtx(std::move(vctx))
, PDiskCtx(std::move(pdiskCtx))
- , LocalRecoveryActorId(localRecoveryActorId)
- {}
-
- void AddQueueItem(const TBulkFormedSstInfo& seg) {
+ , LocalRecoveryActorId(localRecoveryActorId)
+ {}
+
+ void AddQueueItem(const TBulkFormedSstInfo& seg) {
TLevelSegmentPtr segment = new TLevelSegment(VCtx, seg.EntryPoint);
- BulkSegmentLoadQueue.emplace(segment, seg.FirstBlobLsn, seg.LastBlobLsn);
- }
-
- private:
- friend class TActorBootstrapped<TLoaderActor>;
-
- void Bootstrap(const TActorContext& ctx) {
- IssueLoadRequestsOrFinish(ctx);
- Become(&TLoaderActor::StateFunc);
- }
-
- void IssueLoadRequestsOrFinish(const TActorContext& ctx) {
- while (!BulkSegmentLoadQueue.empty() && BulkSegmentLoadInFlight.size() < 3) {
- TBulkSegmentLoadQueueItem& item = BulkSegmentLoadQueue.front();
- auto loader = std::make_unique<TLevelSegmentLoader<TKeyLogoBlob, TMemRecLogoBlob>>(VCtx,
+ BulkSegmentLoadQueue.emplace(segment, seg.FirstBlobLsn, seg.LastBlobLsn);
+ }
+
+ private:
+ friend class TActorBootstrapped<TLoaderActor>;
+
+ void Bootstrap(const TActorContext& ctx) {
+ IssueLoadRequestsOrFinish(ctx);
+ Become(&TLoaderActor::StateFunc);
+ }
+
+ void IssueLoadRequestsOrFinish(const TActorContext& ctx) {
+ while (!BulkSegmentLoadQueue.empty() && BulkSegmentLoadInFlight.size() < 3) {
+ TBulkSegmentLoadQueueItem& item = BulkSegmentLoadQueue.front();
+ auto loader = std::make_unique<TLevelSegmentLoader<TKeyLogoBlob, TMemRecLogoBlob>>(VCtx,
PDiskCtx, item.Segment.Get(), ctx.SelfID, "BulkSegsLoader");
- TActorId loaderId = ctx.ExecutorThread.RegisterActor(loader.release());
+ TActorId loaderId = ctx.ExecutorThread.RegisterActor(loader.release());
ActiveActors.Insert(loaderId);
- BulkSegmentLoadInFlight.emplace(loaderId, std::move(item));
- BulkSegmentLoadQueue.pop();
- }
- if (BulkSegmentLoadQueue.empty() && BulkSegmentLoadInFlight.empty()) {
- Finish(ctx);
- }
- }
-
- void Handle(THullSegLoaded::TPtr& ev, const TActorContext& ctx) {
+ BulkSegmentLoadInFlight.emplace(loaderId, std::move(item));
+ BulkSegmentLoadQueue.pop();
+ }
+ if (BulkSegmentLoadQueue.empty() && BulkSegmentLoadInFlight.empty()) {
+ Finish(ctx);
+ }
+ }
+
+ void Handle(THullSegLoaded::TPtr& ev, const TActorContext& ctx) {
ActiveActors.Erase(ev->Sender);
- auto i = BulkSegmentLoadInFlight.find(ev->Sender);
- Y_VERIFY(i != BulkSegmentLoadInFlight.end());
- TBulkSegmentLoadQueueItem& item = i->second;
-
- // check that we have loaded correct segment :)
- Y_VERIFY(ev->Get()->LevelSegment == item.Segment.Get());
-
- // fill in loaded segment's LSN range
- TLevelSegment& seg = *item.Segment;
- seg.Info.FirstLsn = item.FirstLsn;
- seg.Info.LastLsn = item.LastLsn;
-
- // push segment into results
- Segments.push_back(std::move(item.Segment));
-
- // remove item from in flight set
- BulkSegmentLoadInFlight.erase(i);
-
- // send more requests
- IssueLoadRequestsOrFinish(ctx);
- }
-
- void Finish(const TActorContext& ctx) {
- ctx.Send(LocalRecoveryActorId, new TEvBulkSstsLoaded{std::move(Segments)});
- Die(ctx);
- }
-
+ auto i = BulkSegmentLoadInFlight.find(ev->Sender);
+ Y_VERIFY(i != BulkSegmentLoadInFlight.end());
+ TBulkSegmentLoadQueueItem& item = i->second;
+
+ // check that we have loaded correct segment :)
+ Y_VERIFY(ev->Get()->LevelSegment == item.Segment.Get());
+
+ // fill in loaded segment's LSN range
+ TLevelSegment& seg = *item.Segment;
+ seg.Info.FirstLsn = item.FirstLsn;
+ seg.Info.LastLsn = item.LastLsn;
+
+ // push segment into results
+ Segments.push_back(std::move(item.Segment));
+
+ // remove item from in flight set
+ BulkSegmentLoadInFlight.erase(i);
+
+ // send more requests
+ IssueLoadRequestsOrFinish(ctx);
+ }
+
+ void Finish(const TActorContext& ctx) {
+ ctx.Send(LocalRecoveryActorId, new TEvBulkSstsLoaded{std::move(Segments)});
+ Die(ctx);
+ }
+
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
ActiveActors.KillAndClear(ctx);
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(THullSegLoaded, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
- };
- } // NLoaderActor
-
- TBulkFormedSstInfoSet::TBulkFormedSstInfoSet(const NKikimrVDiskData::TBulkFormedSstInfoSet& pb) {
- const auto& segments = pb.GetSegments();
- BulkFormedSsts = {segments.begin(), segments.end()};
- std::sort(BulkFormedSsts.begin(), BulkFormedSsts.end());
- }
-
- void TBulkFormedSstInfoSet::RemoveSstFromIndex(const TDiskPart& entryPoint) {
- TBulkFormedSstInfo& bulk = FindIntactBulkFormedSst(entryPoint);
- Y_VERIFY(!bulk.RemovedFromIndex && bulk.ChunkIds.empty());
- bulk.RemovedFromIndex = true;
- }
-
- void TBulkFormedSstInfoSet::ApplyCompactionResult(TBulkFormedSstInfoSet& output, TVector<TChunkIdx>& deleteChunks) {
- Y_VERIFY(output.BulkFormedSsts.empty());
- for (TBulkFormedSstInfo& seg : std::exchange(BulkFormedSsts, {})) {
- if (!seg.RemovedFromIndex) {
- output.BulkFormedSsts.push_back(std::move(seg));
- } else if (seg.ChunkIds) {
- AppendToVector(deleteChunks, std::exchange(seg.ChunkIds, {}));
- }
- }
- }
-
- void TBulkFormedSstInfoSet::AddBulkFormedSst(ui64 firstLsn, ui64 lastLsn, const TDiskPart& entryPoint) {
+ STRICT_STFUNC(StateFunc,
+ HFunc(THullSegLoaded, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
+ };
+ } // NLoaderActor
+
+ TBulkFormedSstInfoSet::TBulkFormedSstInfoSet(const NKikimrVDiskData::TBulkFormedSstInfoSet& pb) {
+ const auto& segments = pb.GetSegments();
+ BulkFormedSsts = {segments.begin(), segments.end()};
+ std::sort(BulkFormedSsts.begin(), BulkFormedSsts.end());
+ }
+
+ void TBulkFormedSstInfoSet::RemoveSstFromIndex(const TDiskPart& entryPoint) {
+ TBulkFormedSstInfo& bulk = FindIntactBulkFormedSst(entryPoint);
+ Y_VERIFY(!bulk.RemovedFromIndex && bulk.ChunkIds.empty());
+ bulk.RemovedFromIndex = true;
+ }
+
+ void TBulkFormedSstInfoSet::ApplyCompactionResult(TBulkFormedSstInfoSet& output, TVector<TChunkIdx>& deleteChunks) {
+ Y_VERIFY(output.BulkFormedSsts.empty());
+ for (TBulkFormedSstInfo& seg : std::exchange(BulkFormedSsts, {})) {
+ if (!seg.RemovedFromIndex) {
+ output.BulkFormedSsts.push_back(std::move(seg));
+ } else if (seg.ChunkIds) {
+ AppendToVector(deleteChunks, std::exchange(seg.ChunkIds, {}));
+ }
+ }
+ }
+
+ void TBulkFormedSstInfoSet::AddBulkFormedSst(ui64 firstLsn, ui64 lastLsn, const TDiskPart& entryPoint) {
Y_VERIFY(firstLsn && lastLsn && !entryPoint.Empty(),
"firstLsn# %" PRIu64 " lastLsn# %" PRIu64 " entryPoint# %s",
firstLsn, lastLsn, entryPoint.ToString().data());
- // keep sorted order while inserting new item
- const auto it = std::lower_bound(BulkFormedSsts.begin(), BulkFormedSsts.end(), entryPoint);
- BulkFormedSsts.emplace(it, firstLsn, lastLsn, entryPoint);
- }
-
+ // keep sorted order while inserting new item
+ const auto it = std::lower_bound(BulkFormedSsts.begin(), BulkFormedSsts.end(), entryPoint);
+ BulkFormedSsts.emplace(it, firstLsn, lastLsn, entryPoint);
+ }
+
IActor *TBulkFormedSstInfoSet::CreateLoaderActor(TVDiskContextPtr vctx,
TPDiskCtxPtr pdiskCtx,
ui64 syncLogMaxLsnStored,
const TActorId& localRecoveryActorId) {
- auto loader = std::make_unique<NLoaderActor::TLoaderActor>(std::move(vctx), std::move(pdiskCtx),
+ auto loader = std::make_unique<NLoaderActor::TLoaderActor>(std::move(vctx), std::move(pdiskCtx),
localRecoveryActorId);
-
- for (const TBulkFormedSstInfo& seg : BulkFormedSsts) {
- // ignore segments which are not needed to recover SyncLog -- their LSNs are obsolete
- if (seg.LastBlobLsn <= syncLogMaxLsnStored) {
- continue;
- }
- // ignore segments that are not yet removed from index -- they were already loaded with index and
- // added to BulkFormedBlobSorter a few lines above
- if (!seg.RemovedFromIndex) {
- continue;
- }
- loader->AddQueueItem(seg);
- }
-
- return loader.release();
- }
-
- void TBulkFormedSstInfoSet::SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb) const {
- for (const auto &x : BulkFormedSsts) {
- auto p = pb.AddSegments();
- x.SerializeToProto(*p);
- }
- }
-
- bool TBulkFormedSstInfoSet::ConvertToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb,
- const char *begin, const char *end) {
- return pb.ParseFromArray(begin, end - begin);
- }
-
+
+ for (const TBulkFormedSstInfo& seg : BulkFormedSsts) {
+ // ignore segments which are not needed to recover SyncLog -- their LSNs are obsolete
+ if (seg.LastBlobLsn <= syncLogMaxLsnStored) {
+ continue;
+ }
+ // ignore segments that are not yet removed from index -- they were already loaded with index and
+ // added to BulkFormedBlobSorter a few lines above
+ if (!seg.RemovedFromIndex) {
+ continue;
+ }
+ loader->AddQueueItem(seg);
+ }
+
+ return loader.release();
+ }
+
+ void TBulkFormedSstInfoSet::SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb) const {
+ for (const auto &x : BulkFormedSsts) {
+ auto p = pb.AddSegments();
+ x.SerializeToProto(*p);
+ }
+ }
+
+ bool TBulkFormedSstInfoSet::ConvertToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb,
+ const char *begin, const char *end) {
+ return pb.ParseFromArray(begin, end - begin);
+ }
+
const TBulkFormedSstInfo& TBulkFormedSstInfoSet::FindIntactBulkFormedSst(const TDiskPart& entryPoint) const {
return FindIntactBulkFormedSstPrivate(entryPoint);
}
- TBulkFormedSstInfo& TBulkFormedSstInfoSet::FindIntactBulkFormedSst(const TDiskPart& entryPoint) {
+ TBulkFormedSstInfo& TBulkFormedSstInfoSet::FindIntactBulkFormedSst(const TDiskPart& entryPoint) {
return const_cast<TBulkFormedSstInfo&>(
static_cast<const TBulkFormedSstInfoSet&>(*this).FindIntactBulkFormedSstPrivate(entryPoint));
}
const TBulkFormedSstInfo& TBulkFormedSstInfoSet::FindIntactBulkFormedSstPrivate(const TDiskPart& entryPoint) const {
- for (auto it = std::lower_bound(BulkFormedSsts.begin(), BulkFormedSsts.end(), entryPoint);
- it != BulkFormedSsts.end() && it->EntryPoint == entryPoint; ++it) {
- if (!it->RemovedFromIndex) {
- return *it;
- }
- }
- Y_FAIL("bulk-formed SSTable not found");
- }
-
+ for (auto it = std::lower_bound(BulkFormedSsts.begin(), BulkFormedSsts.end(), entryPoint);
+ it != BulkFormedSsts.end() && it->EntryPoint == entryPoint; ++it) {
+ if (!it->RemovedFromIndex) {
+ return *it;
+ }
+ }
+ Y_FAIL("bulk-formed SSTable not found");
+ }
+
void TBulkFormedSstInfoSet::GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- for (const TBulkFormedSstInfo& seg : BulkFormedSsts) {
- seg.GetOwnedChunks(chunks);
- }
- }
-
-} // NKikimr
+ for (const TBulkFormedSstInfo& seg : BulkFormedSsts) {
+ seg.GetOwnedChunks(chunks);
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.h b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.h
index 22038ef95ca..50f953e6bd9 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksstmngr.h
@@ -1,153 +1,153 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <ydb/core/blobstorage/vdisk/common/disk_part.h>
#include <ydb/core/blobstorage/base/utility.h>
-
-#include <util/generic/set.h>
-
-namespace NKikimr {
-
+
+#include <util/generic/set.h>
+
+namespace NKikimr {
+
class TPDiskCtx;
using TPDiskCtxPtr = std::shared_ptr<TPDiskCtx>;
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TBulkFormedSstInfo
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- struct TBulkFormedSstInfo {
- // Bulk-formed SSTable info structure is created together with replicated SSTable and is used to store correct
- // LSN range of replicated blobs (as they are not known when SSTable is written) and to keep SSTable information
- // when it is deleted from index but still needed to recover SyncLog.
- //
- // Lifecycle:
- // 1. Replicated SSTable is created and added to index; matching bulk-formed segment is added to index too
- //
- // 2. First case: replicated SSTable is deleted from index during compaction, but SyncLog LSN is still less or
- // equal to LastLsn of replicated SSTable -- in this case we move ChunkIds to bulk-formed segment info and
- // it acquires ownership of these chunks. When SyncLog passes LastLsn point, during next compaction these
- // chunks are freed and SSTable is destroyed. Also bulk-formed segment is removed.
- //
- // 3. Second case: SyncLog passes LastLsn point before SSTable is compacted. In this case nothing happens :)
- // During compaction of replicated SSTable its chunk will be deleted as usual and matching bulk-formed segment
- // too.
- //
- // This lifecycle leads to these possible situations:
- // 1. RemovedFromIndex=false ChunkIds empty -- normal situation, just created SSTable.
- // 2. RemovedFromIndex=true ChunkIds not empty -- SSTable compacted and deleted from index, but still needed to
- // recover SyncLog correctly; ChunkIds are freed during next compaction when SyncLogFirstLsnToKeep > LastLsn.
- // *** this is an obsolete case and we don't handle SyncLog through bulk formed segments now ***
- // 3. RemovedFromIndex=true ChunkIds empty -- SSTable compated and deleted and is not needed to recover SyncLog.
- // In this case bulk-formed segment is marked obsolete and is collected during compaction.
-
- // LSN of first BLOB within this SSTable
- ui64 FirstBlobLsn;
-
- // LSN of last BLOB within this SSTable (used to determine whether this SSTable is needed by SyncLog)
- ui64 LastBlobLsn;
-
- // entry point to identify SSTable on disk (in order to read it on recovery)
- TDiskPart EntryPoint;
-
- // IDs of chunks composing this SSTable (stored only when SSTable is dropped from index, otherwise empty)
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TBulkFormedSstInfo
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ struct TBulkFormedSstInfo {
+ // Bulk-formed SSTable info structure is created together with replicated SSTable and is used to store correct
+ // LSN range of replicated blobs (as they are not known when SSTable is written) and to keep SSTable information
+ // when it is deleted from index but still needed to recover SyncLog.
+ //
+ // Lifecycle:
+ // 1. Replicated SSTable is created and added to index; matching bulk-formed segment is added to index too
+ //
+ // 2. First case: replicated SSTable is deleted from index during compaction, but SyncLog LSN is still less or
+ // equal to LastLsn of replicated SSTable -- in this case we move ChunkIds to bulk-formed segment info and
+ // it acquires ownership of these chunks. When SyncLog passes LastLsn point, during next compaction these
+ // chunks are freed and SSTable is destroyed. Also bulk-formed segment is removed.
+ //
+ // 3. Second case: SyncLog passes LastLsn point before SSTable is compacted. In this case nothing happens :)
+ // During compaction of replicated SSTable its chunk will be deleted as usual and matching bulk-formed segment
+ // too.
+ //
+ // This lifecycle leads to these possible situations:
+ // 1. RemovedFromIndex=false ChunkIds empty -- normal situation, just created SSTable.
+ // 2. RemovedFromIndex=true ChunkIds not empty -- SSTable compacted and deleted from index, but still needed to
+ // recover SyncLog correctly; ChunkIds are freed during next compaction when SyncLogFirstLsnToKeep > LastLsn.
+ // *** this is an obsolete case and we don't handle SyncLog through bulk formed segments now ***
+ // 3. RemovedFromIndex=true ChunkIds empty -- SSTable compated and deleted and is not needed to recover SyncLog.
+ // In this case bulk-formed segment is marked obsolete and is collected during compaction.
+
+ // LSN of first BLOB within this SSTable
+ ui64 FirstBlobLsn;
+
+ // LSN of last BLOB within this SSTable (used to determine whether this SSTable is needed by SyncLog)
+ ui64 LastBlobLsn;
+
+ // entry point to identify SSTable on disk (in order to read it on recovery)
+ TDiskPart EntryPoint;
+
+ // IDs of chunks composing this SSTable (stored only when SSTable is dropped from index, otherwise empty)
TVector<ui32> ChunkIds;
-
- // is this record removed from index?
- bool RemovedFromIndex;
-
- TBulkFormedSstInfo(ui64 firstBlobLsn, ui64 lastBlobLsn, const TDiskPart& entryPoint)
- : FirstBlobLsn(firstBlobLsn)
- , LastBlobLsn(lastBlobLsn)
- , EntryPoint(entryPoint)
- , RemovedFromIndex(false)
+
+ // is this record removed from index?
+ bool RemovedFromIndex;
+
+ TBulkFormedSstInfo(ui64 firstBlobLsn, ui64 lastBlobLsn, const TDiskPart& entryPoint)
+ : FirstBlobLsn(firstBlobLsn)
+ , LastBlobLsn(lastBlobLsn)
+ , EntryPoint(entryPoint)
+ , RemovedFromIndex(false)
{
Y_VERIFY(firstBlobLsn && lastBlobLsn && !entryPoint.Empty(),
"firstBlobLsn# %" PRIu64 " lastBlobLsn# %" PRIu64 " entryPoint# %s",
firstBlobLsn, lastBlobLsn, entryPoint.ToString().data());
}
-
- TBulkFormedSstInfo(const NKikimrVDiskData::TBulkFormedSstInfo& proto)
- : FirstBlobLsn(proto.GetFirstBlobLsn())
- , LastBlobLsn(proto.GetLastBlobLsn())
- , EntryPoint(proto.GetEntryPoint())
- , RemovedFromIndex(proto.GetRemovedFromIndex())
- {
+
+ TBulkFormedSstInfo(const NKikimrVDiskData::TBulkFormedSstInfo& proto)
+ : FirstBlobLsn(proto.GetFirstBlobLsn())
+ , LastBlobLsn(proto.GetLastBlobLsn())
+ , EntryPoint(proto.GetEntryPoint())
+ , RemovedFromIndex(proto.GetRemovedFromIndex())
+ {
Y_VERIFY(FirstBlobLsn && LastBlobLsn && !EntryPoint.Empty(),
"FirstBlobLsn# %" PRIu64 " LastBlobLsn# %" PRIu64 " EntryPoint# %s",
FirstBlobLsn, LastBlobLsn, EntryPoint.ToString().data());
- const auto& chunkIds = proto.GetChunkIds();
- ChunkIds.reserve(proto.ChunkIdsSize());
- ChunkIds.insert(ChunkIds.end(), chunkIds.begin(), chunkIds.end());
- }
-
- void SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfo &pb) const {
- // ensure we are in one of correct states -- either we are not removed from index and ChunkIds are empty
- // (because they are owned by matching SSTable), or we are removed from index, but ChunkIds are not empty
- // as we own them, because they are needed to recover SyncLog; in case when RemovedFromIndex=true and
- // ChunkIds are empty this bulk-formed segment must be collected and not written to index
- Y_VERIFY(RemovedFromIndex == !ChunkIds.empty());
-
- pb.SetFirstBlobLsn(FirstBlobLsn);
- pb.SetLastBlobLsn(LastBlobLsn);
- EntryPoint.SerializeToProto(*pb.MutableEntryPoint());
- for (ui32 chunkId : ChunkIds) {
- pb.AddChunkIds(chunkId);
- }
- if (RemovedFromIndex != pb.GetRemovedFromIndex()) {
- // set obsolete flag if it differs from its default value
- pb.SetRemovedFromIndex(RemovedFromIndex);
- }
- }
-
+ const auto& chunkIds = proto.GetChunkIds();
+ ChunkIds.reserve(proto.ChunkIdsSize());
+ ChunkIds.insert(ChunkIds.end(), chunkIds.begin(), chunkIds.end());
+ }
+
+ void SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfo &pb) const {
+ // ensure we are in one of correct states -- either we are not removed from index and ChunkIds are empty
+ // (because they are owned by matching SSTable), or we are removed from index, but ChunkIds are not empty
+ // as we own them, because they are needed to recover SyncLog; in case when RemovedFromIndex=true and
+ // ChunkIds are empty this bulk-formed segment must be collected and not written to index
+ Y_VERIFY(RemovedFromIndex == !ChunkIds.empty());
+
+ pb.SetFirstBlobLsn(FirstBlobLsn);
+ pb.SetLastBlobLsn(LastBlobLsn);
+ EntryPoint.SerializeToProto(*pb.MutableEntryPoint());
+ for (ui32 chunkId : ChunkIds) {
+ pb.AddChunkIds(chunkId);
+ }
+ if (RemovedFromIndex != pb.GetRemovedFromIndex()) {
+ // set obsolete flag if it differs from its default value
+ pb.SetRemovedFromIndex(RemovedFromIndex);
+ }
+ }
+
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- for (TChunkIdx chunkIdx : ChunkIds) {
- const bool inserted = chunks.insert(chunkIdx).second;
- Y_VERIFY(inserted);
- }
- }
-
- friend bool operator <(const TBulkFormedSstInfo& x, const TBulkFormedSstInfo& y) {
- return x.EntryPoint < y.EntryPoint;
- }
-
- friend bool operator <(const TBulkFormedSstInfo& x, const TDiskPart& y) {
- return x.EntryPoint < y;
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TBulkFormedSstInfoSet
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ for (TChunkIdx chunkIdx : ChunkIds) {
+ const bool inserted = chunks.insert(chunkIdx).second;
+ Y_VERIFY(inserted);
+ }
+ }
+
+ friend bool operator <(const TBulkFormedSstInfo& x, const TBulkFormedSstInfo& y) {
+ return x.EntryPoint < y.EntryPoint;
+ }
+
+ friend bool operator <(const TBulkFormedSstInfo& x, const TDiskPart& y) {
+ return x.EntryPoint < y;
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TBulkFormedSstInfoSet
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TBulkFormedSstInfoSet {
- public:
- TBulkFormedSstInfoSet() = default;
- TBulkFormedSstInfoSet(const NKikimrVDiskData::TBulkFormedSstInfoSet& pb);
-
- // mark specific SSTable (generated by replication job) as deleted when compaction is done and this SSTable
- // is not stored in index anymore
- void RemoveSstFromIndex(const TDiskPart& entryPoint);
-
- // generate compacted bulk-formed SSTable info set
- void ApplyCompactionResult(TBulkFormedSstInfoSet& output, TVector<TChunkIdx>& deleteChunks);
-
- void AddBulkFormedSst(ui64 firstLsn, ui64 lastLsn, const TDiskPart& entryPoint);
-
- // create actor which loads bulk-formed segments necessary for SyncLog recovery
+ public:
+ TBulkFormedSstInfoSet() = default;
+ TBulkFormedSstInfoSet(const NKikimrVDiskData::TBulkFormedSstInfoSet& pb);
+
+ // mark specific SSTable (generated by replication job) as deleted when compaction is done and this SSTable
+ // is not stored in index anymore
+ void RemoveSstFromIndex(const TDiskPart& entryPoint);
+
+ // generate compacted bulk-formed SSTable info set
+ void ApplyCompactionResult(TBulkFormedSstInfoSet& output, TVector<TChunkIdx>& deleteChunks);
+
+ void AddBulkFormedSst(ui64 firstLsn, ui64 lastLsn, const TDiskPart& entryPoint);
+
+ // create actor which loads bulk-formed segments necessary for SyncLog recovery
IActor *CreateLoaderActor(TVDiskContextPtr vctx, TPDiskCtxPtr pdiskCtx, ui64 syncLogMaxLsnStored,
const TActorId& localRecoveryActorId);
-
- void SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb) const;
- static bool ConvertToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb, const char *begin, const char *end);
-
- // finds bulk-formed segment that is still in index; it is identified by its entrypoint and it must exist
+
+ void SerializeToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb) const;
+ static bool ConvertToProto(NKikimrVDiskData::TBulkFormedSstInfoSet &pb, const char *begin, const char *end);
+
+ // finds bulk-formed segment that is still in index; it is identified by its entrypoint and it must exist
const TBulkFormedSstInfo& FindIntactBulkFormedSst(const TDiskPart& entryPoint) const;
- TBulkFormedSstInfo& FindIntactBulkFormedSst(const TDiskPart& entryPoint);
-
+ TBulkFormedSstInfo& FindIntactBulkFormedSst(const TDiskPart& entryPoint);
+
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const;
private:
TVector<TBulkFormedSstInfo> BulkFormedSsts;
const TBulkFormedSstInfo& FindIntactBulkFormedSstPrivate(const TDiskPart& entryPoint) const;
- };
-
-} // NKikimr
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.cpp b/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.cpp
index 365c729cd92..8c42656a5be 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.cpp
@@ -22,7 +22,7 @@ namespace NKikimr {
const TLogoBlobID &id,
ui8 partId,
const TIngress &ingress,
- TRope buffer,
+ TRope buffer,
ui64 lsn,
EOpMode mode)
{
@@ -101,7 +101,7 @@ namespace NKikimr {
const TActorContext &ctx,
ui64 tabletId,
ui32 gen,
- ui64 issuerGuid,
+ ui64 issuerGuid,
ui64 lsn,
EOpMode mode)
{
@@ -110,37 +110,37 @@ namespace NKikimr {
"Db# Blocks action# add mode# %s tabletId# %" PRIu64
" gen# %" PRIu32 " lsn# %" PRIu64, OpMode2Str(mode), tabletId, gen, lsn));
- UpdateBlocksCache(tabletId, gen, issuerGuid, lsn, mode);
+ UpdateBlocksCache(tabletId, gen, issuerGuid, lsn, mode);
HullDs->Blocks->PutToFresh(lsn, TKeyBlock(tabletId), TMemRecBlock(gen));
}
- void THullDbRecovery::UpdateBlocksCache(ui64 tabletId, ui32 gen, ui64 issuerGuid, ui64 lsn, EOpMode mode) {
+ void THullDbRecovery::UpdateBlocksCache(ui64 tabletId, ui32 gen, ui64 issuerGuid, ui64 lsn, EOpMode mode) {
switch (mode) {
case THullDbRecovery::NORMAL:
- BlocksCache.CommitInFlight(tabletId, {gen, issuerGuid}, lsn);
+ BlocksCache.CommitInFlight(tabletId, {gen, issuerGuid}, lsn);
break;
case THullDbRecovery::RECOVERY:
// Update cache of blocks; we update it even when we replay log as we preinitialize
// cache only with SST's
- BlocksCache.UpdatePersistent(tabletId, {gen, issuerGuid});
+ BlocksCache.UpdatePersistent(tabletId, {gen, issuerGuid});
break;
}
}
void THullDbRecovery::UpdateBlocksCache(
- const std::shared_ptr<TFreshAppendixBlocks> &blocks,
+ const std::shared_ptr<TFreshAppendixBlocks> &blocks,
TLsnSeg seg,
EOpMode mode)
{
Y_VERIFY_DEBUG(blocks);
// update blocks cache with newly inserted elements
- TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, blocks.get());
+ TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, blocks.get());
it.SeekToFirst();
ui64 lsnIt = seg.First;
while (it.Valid()) {
- // TODO(alexvru): correct handling of fresh appendix with blocks
- UpdateBlocksCache(it.GetCurKey().TabletId, it.GetMemRec().BlockedGeneration, 0, lsnIt++, mode);
+ // TODO(alexvru): correct handling of fresh appendix with blocks
+ UpdateBlocksCache(it.GetCurKey().TabletId, it.GetMemRec().BlockedGeneration, 0, lsnIt++, mode);
it.Next();
}
Y_VERIFY(seg.Last + 1 == lsnIt);
@@ -181,7 +181,7 @@ namespace NKikimr {
void THullDbRecovery::UpdateBarrierCache(const TKeyBarrier& key) {
// take a snapshot of the database including new record's LSN
TBarriersSnapshot snapshot(HullDs->Barriers->GetIndexSnapshot());
-
+
// create an iterator and seek to the just added key
TBarriersSnapshot::TForwardIterator it(HullDs->HullCtx, &snapshot);
it.Seek(key);
@@ -194,19 +194,19 @@ namespace NKikimr {
it.PutToMerger(&merger);
merger.Finish();
const TMemRecBarrier& memRec = merger.GetMemRec();
-
+
// check if the record has quorum
- if (!HullDs->HullCtx->GCOnlySynced || memRec.Ingress.IsQuorum(HullDs->HullCtx->IngressCache.Get()) || key.Hard) {
+ if (!HullDs->HullCtx->GCOnlySynced || memRec.Ingress.IsQuorum(HullDs->HullCtx->IngressCache.Get()) || key.Hard) {
// apply new record to the barrier cache
BarrierCache.Update(key.TabletId, key.Channel, key.Hard, memRec.CollectGen, memRec.CollectStep);
- }
+ }
}
-
- void THullDbRecovery::UpdateBarrierCache(const std::shared_ptr<TFreshAppendixBarriers>& barriers) {
+
+ void THullDbRecovery::UpdateBarrierCache(const std::shared_ptr<TFreshAppendixBarriers>& barriers) {
Y_VERIFY_DEBUG(barriers);
// update barriers cache with newly inserted elements
- TFreshAppendixBarriers::TIterator it(HullDs->HullCtx, barriers.get());
+ TFreshAppendixBarriers::TIterator it(HullDs->HullCtx, barriers.get());
it.SeekToFirst();
while (it.Valid()) {
UpdateBarrierCache(it.GetCurKey());
@@ -261,7 +261,7 @@ namespace NKikimr {
// check blocked
ui32 actualGen = 0;
- auto res = BlocksCache.IsBlocked(tabletID, {recordGeneration, 0}, &actualGen);
+ auto res = BlocksCache.IsBlocked(tabletID, {recordGeneration, 0}, &actualGen);
switch (res.Status) {
case TBlocksCache::EStatus::OK:
return res;
@@ -319,10 +319,10 @@ namespace NKikimr {
// we check at RECOVERY mode only, because incoming message is being checked early
Y_VERIFY(CheckGC(ctx, record)); // TODO: CheckGC consume resources just to be sure incoming message is good
}
-
+
// set up keep bits
TIngress ingressKeep;
- ingressKeep.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeKeep);
+ ingressKeep.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeKeep);
for (ui32 i = 0; i < record.KeepSize(); ++i) {
TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetKeep(i));
Y_VERIFY(id.PartId() == 0);
@@ -335,12 +335,12 @@ namespace NKikimr {
VDISKP(HullDs->HullCtx->VCtx->VDiskLogPrefix,
"Db# LogoBlobs action# set_keep mode# %s id# %s lsn# %" PRIu64,
OpMode2Str(mode), id.ToString().data(), lsn));
- }
- }
-
+ }
+ }
+
// set up do not keep bits
TIngress ingressDontKeep;
- ingressDontKeep.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeDoNotKeep);
+ ingressDontKeep.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeDoNotKeep);
for (ui32 i = 0; i < record.DoNotKeepSize(); ++i) {
TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetDoNotKeep(i));
Y_VERIFY(id.PartId() == 0);
@@ -352,13 +352,13 @@ namespace NKikimr {
VDISKP(HullDs->HullCtx->VCtx->VDiskLogPrefix,
"Db# LogoBlobs action# set_dont_keep mode# %s id# %s lsn# %" PRIu64,
OpMode2Str(mode), id.ToString().data(), lsn));
- }
+ }
}
}
void THullDbRecovery::ReplaySyncDataCmd_LogoBlobsBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
+ std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
TLsnSeg seg,
EOpMode mode)
{
@@ -371,7 +371,7 @@ namespace NKikimr {
void THullDbRecovery::ReplaySyncDataCmd_BlocksBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBlocks> &&blocks,
+ std::shared_ptr<TFreshAppendixBlocks> &&blocks,
TLsnSeg seg,
EOpMode mode)
{
@@ -385,7 +385,7 @@ namespace NKikimr {
void THullDbRecovery::ReplaySyncDataCmd_BarriersBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBarriers> &&barriers,
+ std::shared_ptr<TFreshAppendixBarriers> &&barriers,
TLsnSeg seg,
EOpMode mode)
{
@@ -405,14 +405,14 @@ namespace NKikimr {
HullDs->Blocks->GetOwnedChunks(chunks);
HullDs->Barriers->GetOwnedChunks(chunks);
}
-
+
void THullDbRecovery::BuildBarrierCache()
{
if (HullDs->HullCtx->BarrierValidation) {
BarrierCache.Build(HullDs.Get());
- }
+ }
}
-
+
void THullDbRecovery::BuildBlocksCache()
{
BlocksCache.Build(HullDs.Get());
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.h b/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.h
index 5b8ba535a4d..dd18ee7d8ee 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/hulldb_recovery.h
@@ -31,7 +31,7 @@ namespace NKikimr {
const TLogoBlobID &id,
ui8 partId,
const TIngress &ingress,
- TRope buffer,
+ TRope buffer,
ui64 lsn,
EOpMode mode);
@@ -62,7 +62,7 @@ namespace NKikimr {
const TActorContext &ctx,
ui64 tabletID,
ui32 gen,
- ui64 issuerGuid,
+ ui64 issuerGuid,
ui64 lsn,
EOpMode mode);
@@ -79,7 +79,7 @@ namespace NKikimr {
const TBarrierIngress &ingress,
ui64 lsn,
EOpMode mode);
-
+
void ReplayAddGCCmd(
const TActorContext &ctx,
const NKikimrBlobStorage::TEvVCollectGarbage &record,
@@ -98,22 +98,22 @@ namespace NKikimr {
const NKikimrBlobStorage::TEvVCollectGarbage &record,
ui64 lsn,
EOpMode mode);
-
+
void ReplaySyncDataCmd_LogoBlobsBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
+ std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
TLsnSeg seg,
EOpMode mode);
void ReplaySyncDataCmd_BlocksBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBlocks> &&blocks,
+ std::shared_ptr<TFreshAppendixBlocks> &&blocks,
TLsnSeg seg,
EOpMode mode);
void ReplaySyncDataCmd_BarriersBatch(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBarriers> &&barriers,
+ std::shared_ptr<TFreshAppendixBarriers> &&barriers,
TLsnSeg seg,
EOpMode mode);
@@ -123,7 +123,7 @@ namespace NKikimr {
TSatisfactionRank GetSatisfactionRank(EHullDbType t, ESatisfactionRankType s) const;
void OutputHtmlForDb(IOutputStream &str) const;
void OutputHtmlForHugeBlobDeleter(IOutputStream &str) const;
-
+
// FIXME: remove it when ready
TIntrusivePtr<THullDs> GetHullDs() const {
return HullDs;
@@ -138,7 +138,7 @@ namespace NKikimr {
TIntrusivePtr<THullDs> HullDs;
TLogoBlobFilter Filter;
TBlocksCache BlocksCache;
- TBarrierCache BarrierCache;
+ TBarrierCache BarrierCache;
// check on BLOCK incoming TEvVCollectGarbage message
TBlocksCache::TBlockRes IsBlocked(const NKikimrBlobStorage::TEvVCollectGarbage &record) const;
@@ -146,10 +146,10 @@ namespace NKikimr {
bool CheckGC(const TActorContext &ctx, const NKikimrBlobStorage::TEvVCollectGarbage &record);
private:
- void UpdateBlocksCache(ui64 tabletId, ui32 gen, ui64 issuerGuid, ui64 lsn, EOpMode mode);
- void UpdateBlocksCache(const std::shared_ptr<TFreshAppendixBlocks> &blocks, TLsnSeg seg, EOpMode mode);
+ void UpdateBlocksCache(ui64 tabletId, ui32 gen, ui64 issuerGuid, ui64 lsn, EOpMode mode);
+ void UpdateBlocksCache(const std::shared_ptr<TFreshAppendixBlocks> &blocks, TLsnSeg seg, EOpMode mode);
void UpdateBarrierCache(const TKeyBarrier& key);
- void UpdateBarrierCache(const std::shared_ptr<TFreshAppendixBarriers>& barriers);
+ void UpdateBarrierCache(const std::shared_ptr<TFreshAppendixBarriers>& barriers);
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.cpp b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.cpp
index 7f639cef5bf..9d76c5a5463 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.cpp
@@ -28,21 +28,21 @@ namespace NKikimr {
return str.Str();
}
- TBlocksCache::TBlockRes TBlocksCache::IsBlocked(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
+ TBlocksCache::TBlockRes TBlocksCache::IsBlocked(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
Y_VERIFY(Initialized);
- if (const auto& st = IsBlockedByPersistent(tabletId, gen, actualGen); st.Status != EStatus::OK) {
- return st;
- } else if (const auto& st = IsBlockedByInFlight(tabletId, gen, actualGen); st.Status != EStatus::OK) {
- return st;
- } else {
+ if (const auto& st = IsBlockedByPersistent(tabletId, gen, actualGen); st.Status != EStatus::OK) {
+ return st;
+ } else if (const auto& st = IsBlockedByInFlight(tabletId, gen, actualGen); st.Status != EStatus::OK) {
+ return st;
+ } else {
return {EStatus::OK, 0};
}
}
- bool TBlocksCache::IsBlockedLegacy(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
+ bool TBlocksCache::IsBlockedLegacy(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
Y_VERIFY(Initialized);
- auto persRes = IsBlockedByPersistent(tabletId, gen, actualGen);
- return persRes.Status != EStatus::OK;
+ auto persRes = IsBlockedByPersistent(tabletId, gen, actualGen);
+ return persRes.Status != EStatus::OK;
}
bool TBlocksCache::HasRecord(ui64 tabletId) const {
@@ -52,8 +52,8 @@ namespace NKikimr {
bool TBlocksCache::Find(ui64 tabletId, ui32 *outGen) const {
Y_VERIFY(Initialized);
- if (const auto it = PersistentBlocks.find(tabletId); it != PersistentBlocks.end()) {
- *outGen = it->second.Generation;
+ if (const auto it = PersistentBlocks.find(tabletId); it != PersistentBlocks.end()) {
+ *outGen = it->second.Generation;
return true;
} else {
return false;
@@ -82,64 +82,64 @@ namespace NKikimr {
merger.Finish();
TTabletId tabletId = it.GetCurKey().TabletId;
- ui32 blockedGen = merger.GetMemRec().BlockedGeneration;
- bool inserted = PersistentBlocks.emplace(tabletId, TBlockedGen(blockedGen, 0)).second;
+ ui32 blockedGen = merger.GetMemRec().BlockedGeneration;
+ bool inserted = PersistentBlocks.emplace(tabletId, TBlockedGen(blockedGen, 0)).second;
Y_VERIFY(inserted);
it.Next();
}
}
- TBlocksCache::TBlockRes TBlocksCache::IsBlockedByInFlight(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
- if (const auto it = InFlightBlocks.find(tabletId); it != InFlightBlocks.end() && it->second.MaxBlockedGen.IsBlocked(gen)) {
- if (actualGen) {
- *actualGen = it->second.MaxBlockedGen.Generation;
+ TBlocksCache::TBlockRes TBlocksCache::IsBlockedByInFlight(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
+ if (const auto it = InFlightBlocks.find(tabletId); it != InFlightBlocks.end() && it->second.MaxBlockedGen.IsBlocked(gen)) {
+ if (actualGen) {
+ *actualGen = it->second.MaxBlockedGen.Generation;
}
- return {EStatus::BLOCKED_INFLIGH, it->second.LsnForMaxBlockedGen};
+ return {EStatus::BLOCKED_INFLIGH, it->second.LsnForMaxBlockedGen};
}
return {EStatus::OK, 0};
}
- TBlocksCache::TBlockRes TBlocksCache::IsBlockedByPersistent(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
- if (const auto it = PersistentBlocks.find(tabletId); it != PersistentBlocks.end() && it->second.IsBlocked(gen)) {
- if (actualGen) {
- *actualGen = it->second.Generation;
+ TBlocksCache::TBlockRes TBlocksCache::IsBlockedByPersistent(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const {
+ if (const auto it = PersistentBlocks.find(tabletId); it != PersistentBlocks.end() && it->second.IsBlocked(gen)) {
+ if (actualGen) {
+ *actualGen = it->second.Generation;
}
- return {EStatus::BLOCKED_PERS, 0};
+ return {EStatus::BLOCKED_PERS, 0};
}
return {EStatus::OK, 0};
}
- void TBlocksCache::UpdatePersistent(ui64 tabletId, TBlockedGen gen) {
+ void TBlocksCache::UpdatePersistent(ui64 tabletId, TBlockedGen gen) {
Y_VERIFY(Initialized);
- auto& value = PersistentBlocks[tabletId];
- if (value.Generation <= gen.Generation) {
- value = gen;
+ auto& value = PersistentBlocks[tabletId];
+ if (value.Generation <= gen.Generation) {
+ value = gen;
}
}
- void TBlocksCache::UpdateInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn) {
+ void TBlocksCache::UpdateInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn) {
Y_VERIFY(Initialized);
- if (IsBlockedLegacy(tabletId, gen)) {
+ if (IsBlockedLegacy(tabletId, gen)) {
// already blocked and saved
return;
}
- auto& state = InFlightBlocks[tabletId];
- if (state.MaxBlockedGen.Generation < gen.Generation) {
+ auto& state = InFlightBlocks[tabletId];
+ if (state.MaxBlockedGen.Generation < gen.Generation) {
state.MaxBlockedGen = gen;
state.LsnForMaxBlockedGen = lsn;
}
// check that lsns increment in every queue
- Y_VERIFY(state.InFlightQueue.empty() || state.InFlightQueue.back().Lsn < lsn);
- Y_VERIFY(InFlightBlocksQueue.empty() || InFlightBlocksQueue.back().Lsn < lsn);
+ Y_VERIFY(state.InFlightQueue.empty() || state.InFlightQueue.back().Lsn < lsn);
+ Y_VERIFY(InFlightBlocksQueue.empty() || InFlightBlocksQueue.back().Lsn < lsn);
state.InFlightQueue.push_back({lsn, gen});
InFlightBlocksQueue.push_back({lsn, tabletId});
}
- void TBlocksCache::CommitInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn) {
+ void TBlocksCache::CommitInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn) {
Y_VERIFY(Initialized);
if (!InFlightBlocksQueue.empty()) {
Y_VERIFY(lsn <= InFlightBlocksQueue.front().Lsn);
@@ -147,11 +147,11 @@ namespace NKikimr {
Y_VERIFY(InFlightBlocksQueue.front().TabletId == tabletId);
InFlightBlocksQueue.pop_front();
- const auto it = InFlightBlocks.find(tabletId);
- Y_VERIFY(it != InFlightBlocks.end());
- auto& state = it->second;
- Y_VERIFY(!state.InFlightQueue.empty() && state.InFlightQueue.front().Lsn == lsn &&
- state.InFlightQueue.front().BlockedGen == gen);
+ const auto it = InFlightBlocks.find(tabletId);
+ Y_VERIFY(it != InFlightBlocks.end());
+ auto& state = it->second;
+ Y_VERIFY(!state.InFlightQueue.empty() && state.InFlightQueue.front().Lsn == lsn &&
+ state.InFlightQueue.front().BlockedGen == gen);
UpdatePersistent(tabletId, gen);
state.InFlightQueue.pop_front();
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.h b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.h
index baf4e40c4d0..4ca7d05337c 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.h
+++ b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block.h
@@ -27,28 +27,28 @@ namespace NKikimr {
TString ToString() const;
};
- struct TBlockedGen {
- ui32 Generation = 0;
- ui64 IssuerGuid = 0;
-
- TBlockedGen() = default;
- TBlockedGen(const TBlockedGen&) = default;
-
- TBlockedGen(ui32 generation, ui64 issuerGuid)
- : Generation(generation)
- , IssuerGuid(issuerGuid)
- {}
-
- bool IsBlocked(const TBlockedGen& gen) const {
- return gen.Generation < Generation || (gen.Generation == Generation && (!IssuerGuid || gen.IssuerGuid != IssuerGuid));
- }
-
- friend bool operator ==(const TBlockedGen& x, const TBlockedGen& y) {
- return x.Generation == y.Generation &&
- x.IssuerGuid == y.IssuerGuid;
- }
- };
-
+ struct TBlockedGen {
+ ui32 Generation = 0;
+ ui64 IssuerGuid = 0;
+
+ TBlockedGen() = default;
+ TBlockedGen(const TBlockedGen&) = default;
+
+ TBlockedGen(ui32 generation, ui64 issuerGuid)
+ : Generation(generation)
+ , IssuerGuid(issuerGuid)
+ {}
+
+ bool IsBlocked(const TBlockedGen& gen) const {
+ return gen.Generation < Generation || (gen.Generation == Generation && (!IssuerGuid || gen.IssuerGuid != IssuerGuid));
+ }
+
+ friend bool operator ==(const TBlockedGen& x, const TBlockedGen& y) {
+ return x.Generation == y.Generation &&
+ x.IssuerGuid == y.IssuerGuid;
+ }
+ };
+
TBlocksCache() = default;
~TBlocksCache() = default;
TBlocksCache(const TBlocksCache &) = delete;
@@ -56,17 +56,17 @@ namespace NKikimr {
TBlocksCache(TBlocksCache &&) = default;
TBlocksCache &operator=(TBlocksCache &&) = default;
- TBlockRes IsBlocked(ui64 tabletId, TBlockedGen gen, ui32 *actualGen = nullptr) const;
- bool IsBlockedLegacy(ui64 tabletId, TBlockedGen gen, ui32 *actualGen = nullptr) const;
+ TBlockRes IsBlocked(ui64 tabletId, TBlockedGen gen, ui32 *actualGen = nullptr) const;
+ bool IsBlockedLegacy(ui64 tabletId, TBlockedGen gen, ui32 *actualGen = nullptr) const;
bool HasRecord(ui64 tabletId) const;
bool Find(ui64 tabletId, ui32 *outGen) const;
bool IsInFlight() const { return !InFlightBlocks.empty() || !InFlightBlocksQueue.empty(); }
- void UpdateLegacy(ui64 tabletId, TBlockedGen gen) { UpdatePersistent(tabletId, gen); }
+ void UpdateLegacy(ui64 tabletId, TBlockedGen gen) { UpdatePersistent(tabletId, gen); }
// for log replay
- void UpdatePersistent(ui64 tabletId, TBlockedGen gen);
- void UpdateInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn);
- void CommitInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn);
+ void UpdatePersistent(ui64 tabletId, TBlockedGen gen);
+ void UpdateInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn);
+ void CommitInFlight(ui64 tabletId, TBlockedGen gen, ui64 lsn);
void Build(const THullDs *hullDs);
private:
@@ -109,8 +109,8 @@ namespace NKikimr {
TInFlightBlocksQueue InFlightBlocksQueue;
bool Initialized = false;
- TBlockRes IsBlockedByInFlight(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const;
- TBlockRes IsBlockedByPersistent(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const;
+ TBlockRes IsBlockedByInFlight(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const;
+ TBlockRes IsBlockedByPersistent(ui64 tabletId, TBlockedGen gen, ui32 *actualGen) const;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block_ut.cpp b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block_ut.cpp
index 1af113c2aab..6fe5100da1e 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/hullds_cache_block_ut.cpp
@@ -14,19 +14,19 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateLegacy(17, {1, 0});
- UNIT_ASSERT(!c.IsBlockedLegacy(17, {2, 0}));
- c.UpdateLegacy(17, {2, 0});
- UNIT_ASSERT(c.IsBlockedLegacy(17, {2, 0}));
+ c.UpdateLegacy(17, {1, 0});
+ UNIT_ASSERT(!c.IsBlockedLegacy(17, {2, 0}));
+ c.UpdateLegacy(17, {2, 0});
+ UNIT_ASSERT(c.IsBlockedLegacy(17, {2, 0}));
- c.UpdateInFlight(17, {3, 0}, 500);
- auto res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {3, 0}, 500);
+ auto res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 500);
- c.CommitInFlight(17, {3, 0}, 500);
- res = c.IsBlocked(17, {3, 0});
+ c.CommitInFlight(17, {3, 0}, 500);
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
}
@@ -34,38 +34,38 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateInFlight(17, {1, 0}, 400);
- c.CommitInFlight(17, {1, 0}, 400);
- auto res = c.IsBlocked(17, {1, 0});
+ c.UpdateInFlight(17, {1, 0}, 400);
+ c.CommitInFlight(17, {1, 0}, 400);
+ auto res = c.IsBlocked(17, {1, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {2, 0}, 500);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {2, 0}, 500);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 500);
- c.UpdateInFlight(17, {3, 0}, 600);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {3, 0}, 600);
+ res = c.IsBlocked(17, {2, 0});
// TODO could do better -- 500
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 600);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 600);
- res = c.IsBlocked(17, {4, 0});
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
- c.CommitInFlight(17, {2, 0}, 500);
- res = c.IsBlocked(17, {2, 0});
+ c.CommitInFlight(17, {2, 0}, 500);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 600);
- res = c.IsBlocked(17, {4, 0});
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
- c.CommitInFlight(17, {3, 0}, 600);
- res = c.IsBlocked(17, {2, 0});
+ c.CommitInFlight(17, {3, 0}, 600);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {4, 0});
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
}
@@ -73,33 +73,33 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateInFlight(17, {1, 0}, 400);
- c.CommitInFlight(17, {1, 0}, 400);
- auto res = c.IsBlocked(17, {1, 0});
+ c.UpdateInFlight(17, {1, 0}, 400);
+ c.CommitInFlight(17, {1, 0}, 400);
+ auto res = c.IsBlocked(17, {1, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {2, 0}, 500);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {2, 0}, 500);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 500);
- c.UpdateInFlight(17, {2, 0}, 501);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {2, 0}, 501);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 500);
- c.UpdateInFlight(17, {2, 0}, 502);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {2, 0}, 502);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 500);
- c.CommitInFlight(17, {2, 0}, 500);
- res = c.IsBlocked(17, {2, 0});
+ c.CommitInFlight(17, {2, 0}, 500);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.CommitInFlight(17, {2, 0}, 501);
- res = c.IsBlocked(17, {2, 0});
+ c.CommitInFlight(17, {2, 0}, 501);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.CommitInFlight(17, {2, 0}, 502);
- res = c.IsBlocked(17, {2, 0});
+ c.CommitInFlight(17, {2, 0}, 502);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
}
@@ -107,45 +107,45 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateInFlight(17, {2, 0}, 400);
- c.CommitInFlight(17, {2, 0}, 400);
- auto res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {2, 0}, 400);
+ c.CommitInFlight(17, {2, 0}, 400);
+ auto res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {1, 0}, 410);
- c.CommitInFlight(17, {1, 0}, 410);
- res = c.IsBlocked(17, {2, 0});
+ c.UpdateInFlight(17, {1, 0}, 410);
+ c.CommitInFlight(17, {1, 0}, 410);
+ res = c.IsBlocked(17, {2, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {2, 0}, 420);
- c.CommitInFlight(17, {2, 0}, 420);
- res = c.IsBlocked(17, {1, 0});
+ c.UpdateInFlight(17, {2, 0}, 420);
+ c.CommitInFlight(17, {2, 0}, 420);
+ res = c.IsBlocked(17, {1, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {4, 0}, 430);
- res = c.IsBlocked(17, {4, 0});
+ c.UpdateInFlight(17, {4, 0}, 430);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 430);
- res = c.IsBlocked(17, {5, 0});
+ res = c.IsBlocked(17, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
- c.UpdateInFlight(17, {3, 0}, 440);
- res = c.IsBlocked(17, {3, 0});
+ c.UpdateInFlight(17, {3, 0}, 440);
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 430);
- c.CommitInFlight(17, {4, 0}, 430);
- res = c.IsBlocked(17, {4, 0});
+ c.CommitInFlight(17, {4, 0}, 430);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {5, 0});
+ res = c.IsBlocked(17, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
UNIT_ASSERT(c.IsInFlight());
- c.CommitInFlight(17, {3, 0}, 440);
- res = c.IsBlocked(17, {4, 0});
+ c.CommitInFlight(17, {3, 0}, 440);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {3, 0});
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(17, {5, 0});
+ res = c.IsBlocked(17, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::OK);
UNIT_ASSERT(!c.IsInFlight());
}
@@ -154,25 +154,25 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateInFlight(17, {3, 0}, 400);
- c.CommitInFlight(17, {3, 0}, 400);
- auto res = c.IsBlocked(17, {3, 0});
+ c.UpdateInFlight(17, {3, 0}, 400);
+ c.CommitInFlight(17, {3, 0}, 400);
+ auto res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.UpdateInFlight(17, {4, 0}, 410);
- res = c.IsBlocked(17, {4, 0});
+ c.UpdateInFlight(17, {4, 0}, 410);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 410);
- c.UpdateInFlight(17, {2, 0}, 420);
- res = c.IsBlocked(17, {4, 0});
+ c.UpdateInFlight(17, {2, 0}, 420);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 410);
- c.CommitInFlight(17, {4, 0}, 410);
- res = c.IsBlocked(17, {4, 0});
+ c.CommitInFlight(17, {4, 0}, 410);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- c.CommitInFlight(17, {2, 0}, 420);
- res = c.IsBlocked(17, {4, 0});
+ c.CommitInFlight(17, {2, 0}, 420);
+ res = c.IsBlocked(17, {4, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
UNIT_ASSERT(!c.IsInFlight());
}
@@ -181,24 +181,24 @@ namespace NKikimr {
TBlocksCache c;
c.Build(nullptr);
- c.UpdateInFlight(17, {3, 0}, 400);
- c.UpdateInFlight(20, {5, 0}, 410);
+ c.UpdateInFlight(17, {3, 0}, 400);
+ c.UpdateInFlight(20, {5, 0}, 410);
- auto res = c.IsBlocked(17, {3, 0});
+ auto res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 400);
- res = c.IsBlocked(20, {5, 0});
+ res = c.IsBlocked(20, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 410);
- c.CommitInFlight(17, {3, 0}, 400);
- res = c.IsBlocked(17, {3, 0});
+ c.CommitInFlight(17, {3, 0}, 400);
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(20, {5, 0});
+ res = c.IsBlocked(20, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_INFLIGH && res.Lsn == 410);
- c.CommitInFlight(20, {5, 0}, 410);
- res = c.IsBlocked(17, {3, 0});
+ c.CommitInFlight(20, {5, 0}, 410);
+ res = c.IsBlocked(17, {3, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
- res = c.IsBlocked(20, {5, 0});
+ res = c.IsBlocked(20, {5, 0});
UNIT_ASSERT(res.Status == TBlocksCache::EStatus::BLOCKED_PERS);
UNIT_ASSERT(!c.IsInFlight());
}
diff --git a/ydb/core/blobstorage/vdisk/hulldb/test/testhull_index.cpp b/ydb/core/blobstorage/vdisk/hulldb/test/testhull_index.cpp
index 4a8cf90c2f7..94573cb0b76 100644
--- a/ydb/core/blobstorage/vdisk/hulldb/test/testhull_index.cpp
+++ b/ydb/core/blobstorage/vdisk/hulldb/test/testhull_index.cpp
@@ -9,7 +9,7 @@ namespace NTest {
//////////////////////////////////////////////////////////////////////////////////////////////
class TAllTabletMocks {
public:
- using TTabletMockAndWeight = std::pair<std::shared_ptr<ITabletMock>, ui64>;
+ using TTabletMockAndWeight = std::pair<std::shared_ptr<ITabletMock>, ui64>;
// initialize with a vector of pairs -- tablet mock pointer and tablet weight
TAllTabletMocks(TVector<TTabletMockAndWeight> &&allMocks)
@@ -32,7 +32,7 @@ namespace NTest {
private:
void GenerateSearchVector() {
size_t reserve = 0;
- auto reserveCountFunc = [&reserve] (const std::pair<std::shared_ptr<ITabletMock>, ui64> &elem) {
+ auto reserveCountFunc = [&reserve] (const std::pair<std::shared_ptr<ITabletMock>, ui64> &elem) {
reserve += elem.second;
};
std::for_each(AllMocks.begin(), AllMocks.end(), reserveCountFunc);
@@ -47,7 +47,7 @@ namespace NTest {
}
TVector<TTabletMockAndWeight> AllMocks;
- TVector<std::shared_ptr<ITabletMock>> SearchVector;
+ TVector<std::shared_ptr<ITabletMock>> SearchVector;
};
@@ -63,12 +63,12 @@ namespace NTest {
size_t SstsNum;
};
- TSstGenerator(std::shared_ptr<TTestContexts> testCtx, TAllTabletMocks &&allMocks)
+ TSstGenerator(std::shared_ptr<TTestContexts> testCtx, TAllTabletMocks &&allMocks)
: TestCtx(std::move(testCtx))
, AllMocks(std::move(allMocks))
{}
- TSstGenerator(std::shared_ptr<TTestContexts> testCtx, const TAllTabletMocks &allMocks)
+ TSstGenerator(std::shared_ptr<TTestContexts> testCtx, const TAllTabletMocks &allMocks)
: TestCtx(std::move(testCtx))
, AllMocks(allMocks)
{}
@@ -100,7 +100,7 @@ namespace NTest {
}
private:
- std::shared_ptr<TTestContexts> TestCtx;
+ std::shared_ptr<TTestContexts> TestCtx;
TAllTabletMocks AllMocks;
TVector<TLogoBlobsCmd> LogoBlobs;
TVector<TBarriersCmd> Barriers;
@@ -126,7 +126,7 @@ namespace NTest {
const ui64 requiredBytes = ChunkSize;
ui64 totalBytes = 0;
TIntrusivePtr<TSst> sst(new TSst(TestCtx->GetVCtx()));
- sst->Info.CTime = TAppData::TimeProvider->Now();
+ sst->Info.CTime = TAppData::TimeProvider->Now();
while (it != end && totalBytes < requiredBytes) {
sst->LoadedIndex.emplace_back(it->Key, it->MemRec);
@@ -165,7 +165,7 @@ namespace NTest {
{}
TIntrusivePtr<THullDs> GenerateHullDs() override {
- auto testCtx = std::make_shared<TTestContexts>(ChunkSize, CompWorthReadSize);
+ auto testCtx = std::make_shared<TTestContexts>(ChunkSize, CompWorthReadSize);
std::shared_ptr<TRopeArena> arena = std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate);
TSstGenerator gen(testCtx, std::move(AllMocks));
@@ -193,7 +193,7 @@ namespace NTest {
template <class TKey, class TMemRec, class TDs>
void Allocate17Levels(
- const std::shared_ptr<TTestContexts> &testCtx,
+ const std::shared_ptr<TTestContexts> &testCtx,
const std::shared_ptr<TRopeArena> &arena,
TIntrusivePtr<TDs> &ds)
{
@@ -220,7 +220,7 @@ namespace NTest {
//////////////////////////////////////////////////////////////////////////////////////////////
class TTabletMockLog : public ITabletMock {
public:
- TTabletMockLog(std::shared_ptr<TTestContexts> testCtx, ui64 tabletId, ui64 recsToKeep)
+ TTabletMockLog(std::shared_ptr<TTestContexts> testCtx, ui64 tabletId, ui64 recsToKeep)
: TabletId(tabletId)
, RecsToKeep(recsToKeep)
{
@@ -283,14 +283,14 @@ namespace NTest {
// GenerateDs_18Level_Logs
//////////////////////////////////////////////////////////////////////////////////////////////
TIntrusivePtr<THullDs> GenerateDs_17Level_Logs() {
- auto testCtx = std::make_shared<TTestContexts>();
+ auto testCtx = std::make_shared<TTestContexts>();
TVector<TAllTabletMocks::TTabletMockAndWeight> vec;
vec.reserve(10);
- vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 1ul, 10000ul), 64ul);
- vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 2ul, 10000ul), 64ul);
- vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 3ul, 10000ul), 64ul);
- vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 4ul, 10000ul), 64ul);
- vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 5ul, 10000ul), 4ul);
+ vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 1ul, 10000ul), 64ul);
+ vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 2ul, 10000ul), 64ul);
+ vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 3ul, 10000ul), 64ul);
+ vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 4ul, 10000ul), 64ul);
+ vec.emplace_back(std::make_shared<TTabletMockLog>(testCtx, 5ul, 10000ul), 4ul);
TAllTabletMocks allTabletMocks(std::move(vec));
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp
index 33a8e1153b5..ab1b5ab48e0 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.cpp
@@ -29,9 +29,9 @@ namespace NKikimr {
// THull::TFields
////////////////////////////////////////////////////////////////////////////
struct THull::TFields {
- std::shared_ptr<TLogoBlobsRunTimeCtx> LogoBlobsRunTimeCtx;
- std::shared_ptr<TBlocksRunTimeCtx> BlocksRunTimeCtx;
- std::shared_ptr<TBarriersRunTimeCtx> BarriersRunTimeCtx;
+ std::shared_ptr<TLogoBlobsRunTimeCtx> LogoBlobsRunTimeCtx;
+ std::shared_ptr<TBlocksRunTimeCtx> BlocksRunTimeCtx;
+ std::shared_ptr<TBarriersRunTimeCtx> BarriersRunTimeCtx;
TIntrusivePtr<TLsnMngr> LsnMngr;
TActorSystem *ActorSystem;
const bool BarrierValidation;
@@ -45,21 +45,21 @@ namespace NKikimr {
bool runHandoff,
TActorSystem *as,
bool barrierValidation)
- : LogoBlobsRunTimeCtx(std::make_shared<TLogoBlobsRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
+ : LogoBlobsRunTimeCtx(std::make_shared<TLogoBlobsRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
skeletonId, runHandoff, hullDs->LogoBlobs))
- , BlocksRunTimeCtx(std::make_shared<TBlocksRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
+ , BlocksRunTimeCtx(std::make_shared<TBlocksRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
skeletonId, runHandoff, hullDs->Blocks))
- , BarriersRunTimeCtx(std::make_shared<TBarriersRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
+ , BarriersRunTimeCtx(std::make_shared<TBarriersRunTimeCtx>(lsnMngr, pdiskCtx, handoffDelegate,
skeletonId, runHandoff, hullDs->Barriers))
, LsnMngr(std::move(lsnMngr))
, ActorSystem(as)
, BarrierValidation(barrierValidation)
{}
- void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
- LogoBlobsRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
- BlocksRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
- BarriersRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
+ void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
+ LogoBlobsRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
+ BlocksRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
+ BarriersRunTimeCtx->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
}
void SetLogNotifierActorId(const TActorId &aid) {
@@ -82,7 +82,7 @@ namespace NKikimr {
TActorSystem *as,
bool barrierValidation)
: THullDbRecovery(std::move(uncond))
- , Fields(std::make_unique<TFields>(HullDs, std::move(lsnMngr), std::move(pdiskCtx), std::move(handoffDelegate),
+ , Fields(std::make_unique<TFields>(HullDs, std::move(lsnMngr), std::move(pdiskCtx), std::move(handoffDelegate),
skeletonId, runHandoff, as, barrierValidation))
{}
@@ -106,8 +106,8 @@ namespace NKikimr {
TActiveActors THull::RunHullServices(
TIntrusivePtr<TVDiskConfig> config,
- std::shared_ptr<THullLogCtx> hullLogCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep,
TActorId loggerId,
TActorId logCutterId,
const TActorContext &ctx)
@@ -142,8 +142,8 @@ namespace NKikimr {
return activeActors;
}
- void THull::CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
- Fields->CutRecoveryLog(ctx, std::move(msg));
+ void THull::CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
+ Fields->CutRecoveryLog(ctx, std::move(msg));
}
void THull::PostponeReplyUntilCommitted(
@@ -165,14 +165,14 @@ namespace NKikimr {
{
// check blocked
if (!ignoreBlock) {
- auto res = BlocksCache.IsBlocked(id.TabletID(), {id.Generation(), 0});
+ auto res = BlocksCache.IsBlocked(id.TabletID(), {id.Generation(), 0});
switch (res.Status) {
case TBlocksCache::EStatus::OK:
break;
case TBlocksCache::EStatus::BLOCKED_PERS:
- return {NKikimrProto::BLOCKED, "blocked", 0, false};
+ return {NKikimrProto::BLOCKED, "blocked", 0, false};
case TBlocksCache::EStatus::BLOCKED_INFLIGH:
- return {NKikimrProto::BLOCKED, "blocked", res.Lsn, true};
+ return {NKikimrProto::BLOCKED, "blocked", res.Lsn, true};
}
}
@@ -185,7 +185,7 @@ namespace NKikimr {
const TLogoBlobID &id,
ui8 partId,
const TIngress &ingress,
- TRope buffer,
+ TRope buffer,
ui64 lsn)
{
ReplayAddLogoBlobCmd(ctx, id, partId, ingress, std::move(buffer), lsn, THullDbRecovery::NORMAL);
@@ -231,21 +231,21 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// Blocks
////////////////////////////////////////////////////////////////////////
- THullCheckStatus THull::CheckBlockCmdAndAllocLsn(ui64 tabletID, ui32 gen, ui64 issuerGuid, ui32 *actGen, TLsnSeg *seg)
+ THullCheckStatus THull::CheckBlockCmdAndAllocLsn(ui64 tabletID, ui32 gen, ui64 issuerGuid, ui32 *actGen, TLsnSeg *seg)
{
- const TBlocksCache::TBlockedGen g(gen, issuerGuid);
- auto res = BlocksCache.IsBlocked(tabletID, g, actGen);
+ const TBlocksCache::TBlockedGen g(gen, issuerGuid);
+ auto res = BlocksCache.IsBlocked(tabletID, g, actGen);
switch (res.Status) {
case TBlocksCache::EStatus::OK:
*actGen = gen;
// allocate lsn in case of success
*seg = Fields->LsnMngr->AllocLsnForHullAndSyncLog();
- BlocksCache.UpdateInFlight(tabletID, g, seg->Point());
+ BlocksCache.UpdateInFlight(tabletID, g, seg->Point());
return {NKikimrProto::OK, 0, false};
case TBlocksCache::EStatus::BLOCKED_PERS:
- return {NKikimrProto::ALREADY, "already got", 0, false};
+ return {NKikimrProto::ALREADY, "already got", 0, false};
case TBlocksCache::EStatus::BLOCKED_INFLIGH:
- return {NKikimrProto::ALREADY, "already got", res.Lsn, true};
+ return {NKikimrProto::ALREADY, "already got", res.Lsn, true};
}
}
@@ -253,12 +253,12 @@ namespace NKikimr {
const TActorContext &ctx,
ui64 tabletID,
ui32 gen,
- ui64 issuerGuid,
+ ui64 issuerGuid,
ui64 lsn,
const THull::TReplySender &replySender)
{
// unconditional replay
- ReplayAddBlockCmd(ctx, tabletID, gen, issuerGuid, lsn, THullDbRecovery::NORMAL);
+ ReplayAddBlockCmd(ctx, tabletID, gen, issuerGuid, lsn, THullDbRecovery::NORMAL);
Fields->DelayedResponses.ConfirmLsn(lsn, replySender);
// run compaction if required
@@ -290,7 +290,7 @@ namespace NKikimr {
ui32 perGenCounter,
ui32 collectGeneration,
ui32 collectStep,
- const TBarrierIngress& ingress,
+ const TBarrierIngress& ingress,
const TActorContext& ctx)
{
// check barrier against current state of Hull:
@@ -320,16 +320,16 @@ namespace NKikimr {
}
// we already have this key with the same value, so we issue ALREADY response
- const TBarrierIngress existingIngress(it.GetMemRec().Ingress);
- TBarrierIngress newIngress = existingIngress;
- TBarrierIngress::Merge(newIngress, ingress);
- return existingIngress.Raw() == newIngress.Raw()
- ? NKikimrProto::ALREADY // if this command is already seen by this disk
- : NKikimrProto::OK; // process command
- }
-
- // ensure that keys are coming in strictly ascending order
- if (IsFromSameSequence(newKey, it)) {
+ const TBarrierIngress existingIngress(it.GetMemRec().Ingress);
+ TBarrierIngress newIngress = existingIngress;
+ TBarrierIngress::Merge(newIngress, ingress);
+ return existingIngress.Raw() == newIngress.Raw()
+ ? NKikimrProto::ALREADY // if this command is already seen by this disk
+ : NKikimrProto::OK; // process command
+ }
+
+ // ensure that keys are coming in strictly ascending order
+ if (IsFromSameSequence(newKey, it)) {
// check that existing key is really greater that the new one -- this is internal consistency check
// so we can do it in Y_VERIFY
const TKeyBarrier& key = it.GetCurKey();
@@ -399,33 +399,33 @@ namespace NKikimr {
case TBlocksCache::EStatus::OK:
break;
case TBlocksCache::EStatus::BLOCKED_PERS:
- return {NKikimrProto::BLOCKED, "blocked", 0, false};
+ return {NKikimrProto::BLOCKED, "blocked", 0, false};
case TBlocksCache::EStatus::BLOCKED_INFLIGH:
- return {NKikimrProto::BLOCKED, "blocked", blockStatus.Lsn, true};
+ return {NKikimrProto::BLOCKED, "blocked", blockStatus.Lsn, true};
}
// check per generation counter
if (!record.HasPerGenerationCounter())
- return {NKikimrProto::ERROR, "missing per generation counter"}; // all commands must have per generation counter by contract
+ return {NKikimrProto::ERROR, "missing per generation counter"}; // all commands must have per generation counter by contract
if (completeDel) {
if (recordGeneration != Max<ui32>() || perGenCounter != Max<ui32>())
- return {NKikimrProto::ERROR, "incorrect complete deletion command"}; // complete del must obey format
+ return {NKikimrProto::ERROR, "incorrect complete deletion command"}; // complete del must obey format
}
// check keep/don't keep flags and if they are allowed
const bool hasFlagsButNotAllowed = !HullDs->HullCtx->AllowKeepFlags
&& (record.KeepSize() > 0 || record.DoNotKeepSize() > 0);
if (hasFlagsButNotAllowed)
- return {NKikimrProto::ERROR, "no keep flags allowed"};
+ return {NKikimrProto::ERROR, "no keep flags allowed"};
if (collect) {
const ui32 channel = record.GetChannel();
const bool hard = record.GetHard();
NKikimrProto::EReplyStatus status = ValidateGCCmd(tabletID, channel, hard, recordGeneration,
- perGenCounter, collectGeneration, collectStep, ingress, ctx);
+ perGenCounter, collectGeneration, collectStep, ingress, ctx);
if (status != NKikimrProto::OK) {
- return {status, "command invalid"};
+ return {status, "command invalid"};
}
}
@@ -436,7 +436,7 @@ namespace NKikimr {
ui64 lsnAdvance = !!collect + record.KeepSize() + record.DoNotKeepSize();
Y_VERIFY(lsnAdvance > 0);
*seg = Fields->LsnMngr->AllocLsnForHullAndSyncLog(lsnAdvance);
- return {NKikimrProto::OK, {}};
+ return {NKikimrProto::OK, {}};
}
void THull::AddGCCmd(
@@ -458,7 +458,7 @@ namespace NKikimr {
const TLsnSeg &seg)
{
TIngress ingress;
- ingress.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeDoNotKeep);
+ ingress.SetKeep(TIngress::IngressMode(HullDs->HullCtx->VCtx->Top->GType), CollectModeDoNotKeep);
ui64 idLsn = seg.First;
for (const TLogoBlobID& id : phantoms) {
HullDs->LogoBlobs->PutToFresh(idLsn, TKeyLogoBlob(id), TMemRecLogoBlob(ingress));
@@ -496,7 +496,7 @@ namespace NKikimr {
ui32 counter = 0;
auto count = [&counter] (const void *) { counter++; };
// do job - count all elements
- NSyncLog::TFragmentReader(data).ForEach(count, count, count, count);
+ NSyncLog::TFragmentReader(data).ForEach(count, count, count, count);
// allocate LsnSeg; we reserve a diapason of lsns since we put multiple records
ui64 lsnAdvance = counter;
@@ -506,16 +506,16 @@ namespace NKikimr {
// update blocks cache by blocks that are in flight
ui64 curLsn = seg.First;
auto blockHandler = [&] (const NSyncLog::TBlockRec *rec) {
- BlocksCache.UpdateInFlight(rec->TabletId, {rec->Generation, 0}, curLsn++);
- };
- auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
- BlocksCache.UpdateInFlight(rec->TabletId, {rec->Generation, rec->IssuerGuid}, curLsn++);
+ BlocksCache.UpdateInFlight(rec->TabletId, {rec->Generation, 0}, curLsn++);
};
+ auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
+ BlocksCache.UpdateInFlight(rec->TabletId, {rec->Generation, rec->IssuerGuid}, curLsn++);
+ };
auto otherHandler = [&] (const void *) {
curLsn++;
};
// do job - update blocks cache
- NSyncLog::TFragmentReader(data).ForEach(otherHandler, blockHandler, otherHandler, blockHandlerV2);
+ NSyncLog::TFragmentReader(data).ForEach(otherHandler, blockHandler, otherHandler, blockHandlerV2);
// check that all records are applied
Y_VERIFY_DEBUG(curLsn == seg.Last + 1);
@@ -534,10 +534,10 @@ namespace NKikimr {
if (freshBatch.Blocks) {
ui64 curLsn = seg.First + logoBlobsCount;
- TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, freshBatch.Blocks.get());
+ TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, freshBatch.Blocks.get());
it.SeekToFirst();
while (it.Valid()) {
- BlocksCache.UpdateInFlight(it.GetCurKey().TabletId, {it.GetMemRec().BlockedGeneration, 0}, curLsn++);
+ BlocksCache.UpdateInFlight(it.GetCurKey().TabletId, {it.GetMemRec().BlockedGeneration, 0}, curLsn++);
it.Next();
}
}
@@ -555,7 +555,7 @@ namespace NKikimr {
// record handlers
auto blobHandler = [&] (const NSyncLog::TLogoBlobRec *rec) {
- Y_VERIFY_DEBUG(TIngress::MustKnowAboutLogoBlob(HullDs->HullCtx->VCtx->Top.get(),
+ Y_VERIFY_DEBUG(TIngress::MustKnowAboutLogoBlob(HullDs->HullCtx->VCtx->Top.get(),
HullDs->HullCtx->VCtx->ShortSelfVDisk,
rec->LogoBlobID()),
"logoBlobID# %s ShortSelfVDisk# %s top# %s",
@@ -567,7 +567,7 @@ namespace NKikimr {
};
auto blockHandler = [&] (const NSyncLog::TBlockRec *rec) {
// replay uncondititionally
- ReplayAddBlockCmd(ctx, rec->TabletId, rec->Generation, 0, curLsn, THullDbRecovery::NORMAL);
+ ReplayAddBlockCmd(ctx, rec->TabletId, rec->Generation, 0, curLsn, THullDbRecovery::NORMAL);
Fields->DelayedResponses.ConfirmLsn(curLsn, replySender);
++curLsn;
};
@@ -575,15 +575,15 @@ namespace NKikimr {
ReplayAddBarrierCmd(ctx, rec->TabletId, rec->Channel, rec->Gen, rec->GenCounter, rec->CollectGeneration,
rec->CollectStep, rec->Hard, rec->Ingress, curLsn++, THullDbRecovery::NORMAL);
};
- auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
- ReplayAddBlockCmd(ctx, rec->TabletId, rec->Generation, rec->IssuerGuid, curLsn, THullDbRecovery::NORMAL);
- Fields->DelayedResponses.ConfirmLsn(curLsn, replySender);
- ++curLsn;
- };
+ auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
+ ReplayAddBlockCmd(ctx, rec->TabletId, rec->Generation, rec->IssuerGuid, curLsn, THullDbRecovery::NORMAL);
+ Fields->DelayedResponses.ConfirmLsn(curLsn, replySender);
+ ++curLsn;
+ };
// process synclog data
NSyncLog::TFragmentReader fragment(data);
- fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
+ fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
// check that all records are applied
Y_VERIFY_DEBUG(curLsn == seg.Last + 1);
@@ -598,7 +598,7 @@ namespace NKikimr {
void CompactFreshIfRequired(
const TActorContext &ctx,
TIntrusivePtr<THullDs> &hullDs,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
TLevelIndex<TKey, TMemRec> &levelIndex)
{
// try to start fresh compaction
@@ -635,7 +635,7 @@ namespace NKikimr {
TLsnSeg s(curLsn, curLsn + blocksCount - 1);
// confirm lsns
- TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, freshBatch.Blocks.get());
+ TFreshAppendixBlocks::TIterator it(HullDs->HullCtx, freshBatch.Blocks.get());
it.SeekToFirst();
while (it.Valid()) {
Fields->DelayedResponses.ConfirmLsn(curLsn++, replySender);
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h
index 309c3d52c2f..226ab0e4cc4 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hull.h
@@ -20,13 +20,13 @@ namespace NKikimr {
// reply until commit to the log. It is used for BLOCKED status;
struct THullCheckStatus {
NKikimrProto::EReplyStatus Status;
- TString ErrorReason;
+ TString ErrorReason;
ui64 Lsn;
bool Postponed;
- THullCheckStatus(NKikimrProto::EReplyStatus status, TString errorReason, ui64 lsn = 0, bool postponed = false)
+ THullCheckStatus(NKikimrProto::EReplyStatus status, TString errorReason, ui64 lsn = 0, bool postponed = false)
: Status(status)
- , ErrorReason(std::move(errorReason))
+ , ErrorReason(std::move(errorReason))
, Lsn(lsn)
, Postponed(postponed)
{}
@@ -38,7 +38,7 @@ namespace NKikimr {
class THull : public THullDbRecovery {
private:
struct TFields;
- std::unique_ptr<TFields> Fields;
+ std::unique_ptr<TFields> Fields;
void ValidateWriteQuery(const TActorContext &ctx, const TLogoBlobID &id);
@@ -53,7 +53,7 @@ namespace NKikimr {
ui32 perGenCounter,
ui32 collectGeneration,
ui32 collectStep,
- const TBarrierIngress& ingress,
+ const TBarrierIngress& ingress,
const TActorContext& ctx);
public:
@@ -75,14 +75,14 @@ namespace NKikimr {
// Run all required hull facilities, like actors that perform compactions, etc
TActiveActors RunHullServices(
TIntrusivePtr<TVDiskConfig> config,
- std::shared_ptr<THullLogCtx> hullLogCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep,
TActorId loggerId,
TActorId logCutterId,
const TActorContext &ctx);
// Request from PDisk to cut the recovery log
- void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg);
+ void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg);
void PostponeReplyUntilCommitted(IEventBase *msg, const TActorId &recipient, ui64 recipientCookie, ui64 lsn);
@@ -99,7 +99,7 @@ namespace NKikimr {
const TLogoBlobID &id,
ui8 partId,
const TIngress &ingress,
- TRope buffer,
+ TRope buffer,
ui64 lsn);
void AddHugeLogoBlob(
@@ -139,7 +139,7 @@ namespace NKikimr {
THullCheckStatus CheckBlockCmdAndAllocLsn(
ui64 tabletID,
ui32 gen,
- ui64 issuerGuid,
+ ui64 issuerGuid,
ui32 *actGen,
TLsnSeg *seg);
@@ -147,7 +147,7 @@ namespace NKikimr {
const TActorContext &ctx,
ui64 tabletID,
ui32 gen,
- ui64 issuerGuid,
+ ui64 issuerGuid,
ui64 lsn,
const TReplySender &replySender);
@@ -174,7 +174,7 @@ namespace NKikimr {
TLsnSeg AllocateLsnForPhantoms(const TDeque<TLogoBlobID>& phantoms);
void CollectPhantoms(const TActorContext& ctx, const TDeque<TLogoBlobID>& phantoms, const TLsnSeg &seg);
-
+
// fast check for LogoBlob
bool FastKeep(const TLogoBlobID& id, bool keepByIngress, TString *explanation = nullptr) const;
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp
index e0118b3acf6..c12ef6dd172 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.cpp
@@ -60,9 +60,9 @@ namespace NKikimr {
std::optional<NHullComp::TFullCompactionAttrs> GetFullCompactionAttrsForLevelCompactionSelector(
const TRTCtx &rtCtx)
{
- return Enabled() && rtCtx->LevelIndex->IsWrittenToSstBeforeLsn(FullCompactionAttrs->FullCompactionLsn)
- ? FullCompactionAttrs
- : std::nullopt;
+ return Enabled() && rtCtx->LevelIndex->IsWrittenToSstBeforeLsn(FullCompactionAttrs->FullCompactionLsn)
+ ? FullCompactionAttrs
+ : std::nullopt;
}
};
@@ -72,7 +72,7 @@ namespace NKikimr {
template <class TKey, class TMemRec>
void CompactFreshSegment(
TIntrusivePtr<THullDs> &hullDs,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
const TActorContext &ctx)
{
using TFreshSegment = ::NKikimr::TFreshSegment<TKey, TMemRec>;
@@ -93,14 +93,14 @@ namespace NKikimr {
auto levelSnap = rtCtx->LevelIndex->GetIndexSnapshot();
// prepare iterator and first/last lsns
- auto freshSegmentSnap = std::make_shared<TFreshSegmentSnapshot>(freshSegment->GetSnapshot());
- TIterator it(hullCtx, freshSegmentSnap.get());
+ auto freshSegmentSnap = std::make_shared<TFreshSegmentSnapshot>(freshSegment->GetSnapshot());
+ TIterator it(hullCtx, freshSegmentSnap.get());
it.SeekToFirst();
ui64 firstLsn = freshSegment->GetFirstLsn();
ui64 lastLsn = freshSegment->GetLastLsn();
- std::unique_ptr<TFreshCompaction> compaction(new TFreshCompaction(
+ std::unique_ptr<TFreshCompaction> compaction(new TFreshCompaction(
hullCtx, rtCtx, freshSegment, freshSegmentSnap, std::move(barriersSnap), std::move(levelSnap),
- mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Max(), {}));
+ mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Max(), {}));
LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP,
VDISKP(hullCtx->VCtx->VDiskLogPrefix,
@@ -110,7 +110,7 @@ namespace NKikimr {
"Last fresh lsn MUST be confirmed; lastLsn# %" PRIu64 " confirmed# %" PRIu64,
lastLsn, rtCtx->LsnMngr->GetConfirmedLsnForHull());
- auto actorId = RunInBatchPool(ctx, compaction.release());
+ auto actorId = RunInBatchPool(ctx, compaction.release());
rtCtx->LevelIndex->ActorCtx->ActiveActors.Insert(actorId);
}
@@ -153,18 +153,18 @@ namespace NKikimr {
TIntrusivePtr<TVDiskConfig> Config;
TIntrusivePtr<THullDs> HullDs;
- std::shared_ptr<THullLogCtx> HullLogCtx;
- std::shared_ptr<TRunTimeCtx> RTCtx;
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
+ std::shared_ptr<THullLogCtx> HullLogCtx;
+ std::shared_ptr<TRunTimeCtx> RTCtx;
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
NHullComp::TBoundariesConstPtr Boundaries;
THullDbCommitterCtxPtr HullDbCommitterCtx;
- std::unique_ptr<TCompactionTask> CompactionTask;
+ std::unique_ptr<TCompactionTask> CompactionTask;
bool AdvanceCommitInProgress = false;
TActiveActors &ActiveActors;
NMonGroup::TLsmAllLevelsStat LevelStat;
TFullCompactionState FullCompactionState;
- bool CompactionScheduled = false;
- TInstant NextCompactionWakeup;
+ bool CompactionScheduled = false;
+ TInstant NextCompactionWakeup;
friend class TActorBootstrapped<TThis>;
@@ -174,8 +174,8 @@ namespace NKikimr {
ScheduleCompaction(ctx);
}
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
// RunLevelCompactionSelector runs TSelectorActor which selects what to compact.
// returns true, if selector has been started, false otherwise
bool RunLevelCompactionSelector(const TActorContext &ctx) {
@@ -184,43 +184,43 @@ namespace NKikimr {
return false;
}
- //////////////////////// CHOOSE WHAT TO COMPACT ///////////////////////////////
+ //////////////////////// CHOOSE WHAT TO COMPACT ///////////////////////////////
RTCtx->LevelIndex->SetCompState(TLevelIndexBase::StateCompPolicyAtWork);
auto barriersSnap = HullDs->Barriers->GetIndexSnapshot();
auto levelSnap = RTCtx->LevelIndex->GetIndexSnapshot();
const double rateThreshold = Config->HullCompLevelRateThreshold;
auto fullCompactionAttrs = FullCompactionState.GetFullCompactionAttrsForLevelCompactionSelector(RTCtx);
NHullComp::TSelectorParams params = {Boundaries, rateThreshold, TInstant::Seconds(0), fullCompactionAttrs};
- auto selector = std::make_unique<TSelectorActor>(HullDs->HullCtx, params, std::move(levelSnap),
- std::move(barriersSnap), ctx.SelfID, std::move(CompactionTask));
- auto aid = RunInBatchPool(ctx, selector.release());
+ auto selector = std::make_unique<TSelectorActor>(HullDs->HullCtx, params, std::move(levelSnap),
+ std::move(barriersSnap), ctx.SelfID, std::move(CompactionTask));
+ auto aid = RunInBatchPool(ctx, selector.release());
ActiveActors.Insert(aid);
return true;
}
- void ScheduleCompactionWakeup(const TActorContext& ctx) {
- NextCompactionWakeup = ctx.Now() + Config->HullCompSchedulingInterval;
- if (!CompactionScheduled) {
- ctx.Schedule(NextCompactionWakeup, new TEvents::TEvWakeup);
- CompactionScheduled = true;
- }
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- Y_VERIFY(CompactionScheduled);
- CompactionScheduled = false;
- if (ctx.Now() >= NextCompactionWakeup) {
- ScheduleCompaction(ctx);
- } else {
- ScheduleCompactionWakeup(ctx);
- }
- }
-
+ void ScheduleCompactionWakeup(const TActorContext& ctx) {
+ NextCompactionWakeup = ctx.Now() + Config->HullCompSchedulingInterval;
+ if (!CompactionScheduled) {
+ ctx.Schedule(NextCompactionWakeup, new TEvents::TEvWakeup);
+ CompactionScheduled = true;
+ }
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ Y_VERIFY(CompactionScheduled);
+ CompactionScheduled = false;
+ if (ctx.Now() >= NextCompactionWakeup) {
+ ScheduleCompaction(ctx);
+ } else {
+ ScheduleCompactionWakeup(ctx);
+ }
+ }
+
void ScheduleCompaction(const TActorContext &ctx) {
// schedule fresh if required
CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx);
- if (!RunLevelCompactionSelector(ctx)) {
- ScheduleCompactionWakeup(ctx);
+ if (!RunLevelCompactionSelector(ctx)) {
+ ScheduleCompactionWakeup(ctx);
}
}
@@ -244,20 +244,20 @@ namespace NKikimr {
TLevelSliceForwardIterator it(HullDs->HullCtx, vec);
it.SeekToFirst();
- std::unique_ptr<TLevelCompaction> compaction(new TLevelCompaction(
+ std::unique_ptr<TLevelCompaction> compaction(new TLevelCompaction(
HullDs->HullCtx, RTCtx, nullptr, nullptr, std::move(barriersSnap), std::move(levelSnap),
- mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Minutes(2), {}));
- NActors::TActorId actorId = RunInBatchPool(ctx, compaction.release());
+ mergeElementsApproximation, it, firstLsn, lastLsn, TDuration::Minutes(2), {}));
+ NActors::TActorId actorId = RunInBatchPool(ctx, compaction.release());
ActiveActors.Insert(actorId);
}
void Handle(typename TSelected::TPtr &ev, const TActorContext &ctx) {
- ActiveActors.Erase(ev->Sender);
+ ActiveActors.Erase(ev->Sender);
Y_VERIFY(RTCtx->LevelIndex->GetCompState() == TLevelIndexBase::StateCompPolicyAtWork);
RTCtx->LevelIndex->SetCompState(TLevelIndexBase::StateNoComp);
NHullComp::EAction action = ev->Get()->Action;
- CompactionTask = std::move(ev->Get()->CompactionTask);
+ CompactionTask = std::move(ev->Get()->CompactionTask);
if (action != NHullComp::ActNothing) {
// log out decision
@@ -272,7 +272,7 @@ namespace NKikimr {
switch (action) {
case NHullComp::ActNothing: {
// nothing to merge, try later
- ScheduleCompactionWakeup(ctx);
+ ScheduleCompactionWakeup(ctx);
// for now, update storage ratio as it may have changed
UpdateStorageRatio(RTCtx->LevelIndex->CurSlice);
break;
@@ -378,11 +378,11 @@ namespace NKikimr {
// level and put to another
if (CompactionTask->CollectDeletedSsts()) {
TLeveledSstsIterator delIt(&CompactionTask->GetSstsToDelete());
- for (delIt.SeekToFirst(); delIt.Valid(); delIt.Next()) {
+ for (delIt.SeekToFirst(); delIt.Valid(); delIt.Next()) {
const TLevelSegment& seg = *delIt.Get().SstPtr;
- seg.FillInChunkIds(freedChunksSink);
- if (seg.Info.IsCreatedByRepl()) { // mark it out-of-index to schedule deletion from the bulk formed segments table
- prevSlice->BulkFormedSegments.RemoveSstFromIndex(seg.GetEntryPoint());
+ seg.FillInChunkIds(freedChunksSink);
+ if (seg.Info.IsCreatedByRepl()) { // mark it out-of-index to schedule deletion from the bulk formed segments table
+ prevSlice->BulkFormedSegments.RemoveSstFromIndex(seg.GetEntryPoint());
}
}
}
@@ -394,7 +394,7 @@ namespace NKikimr {
// apply compaction to bulk-formed SSTables; it produces a set of bulk-formed segments suitable for saving
// in new slice containing only needed entries
- prevSlice->BulkFormedSegments.ApplyCompactionResult(RTCtx->LevelIndex->CurSlice->BulkFormedSegments, freedChunksSink);
+ prevSlice->BulkFormedSegments.ApplyCompactionResult(RTCtx->LevelIndex->CurSlice->BulkFormedSegments, freedChunksSink);
// manage recovery log LSN to keep:
// we can't advance LsnToKeep until the prev snapshot dies,
@@ -403,10 +403,10 @@ namespace NKikimr {
// run level committer
TDiskPartVec removedHugeBlobs(CompactionTask->ExtractHugeBlobsToDelete());
- auto committer = std::make_unique<TAsyncLevelCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
+ auto committer = std::make_unique<TAsyncLevelCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
ctx.SelfID, std::move(chunksAdded), std::move(deleteChunks), std::move(removedHugeBlobs),
- prevSliceActive);
- TActorId committerID = ctx.RegisterWithSameMailbox(committer.release());
+ prevSliceActive);
+ TActorId committerID = ctx.RegisterWithSameMailbox(committer.release());
ActiveActors.Insert(committerID);
if (prevSliceActive) {
@@ -467,10 +467,10 @@ namespace NKikimr {
}
// run fresh committer
- auto committer = std::make_unique<TAsyncFreshCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
+ auto committer = std::make_unique<TAsyncFreshCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
ctx.SelfID, std::move(msg->CommitChunks), std::move(msg->ReservedChunks),
std::move(msg->FreedHugeBlobs), dbg.Str());
- auto aid = ctx.RegisterWithSameMailbox(committer.release());
+ auto aid = ctx.RegisterWithSameMailbox(committer.release());
ActiveActors.Insert(aid);
} else {
Y_VERIFY(RTCtx->LevelIndex->GetCompState() == TLevelIndexBase::StateCompInProgress);
@@ -478,16 +478,16 @@ namespace NKikimr {
CompactionTask->CompactSsts.CompactionFinished(std::move(msg->SegVec),
std::move(msg->FreedHugeBlobs), msg->Aborted);
- if (msg->Aborted) { // if the compaction was aborted, ensure there was no index change
+ if (msg->Aborted) { // if the compaction was aborted, ensure there was no index change
Y_VERIFY(CompactionTask->GetSstsToAdd().Empty());
Y_VERIFY(CompactionTask->GetSstsToDelete().Empty());
Y_VERIFY(CompactionTask->GetHugeBlobsToDelete().Empty());
- Y_VERIFY(!msg->CommitChunks);
- Y_VERIFY(!msg->FreshSegment);
+ Y_VERIFY(!msg->CommitChunks);
+ Y_VERIFY(!msg->FreshSegment);
} else {
Y_VERIFY(!CompactionTask->GetSstsToDelete().Empty());
- }
-
+ }
+
ApplyCompactionResult(ctx, std::move(msg->CommitChunks), std::move(msg->ReservedChunks));
}
@@ -509,10 +509,10 @@ namespace NKikimr {
Y_VERIFY(oneAddition.Sst->IsLoaded());
RTCtx->LevelIndex->UncommittedReplSegments.push_back(oneAddition.Sst);
- auto actor = std::make_unique<TAsyncReplSstCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
+ auto actor = std::make_unique<TAsyncReplSstCommitter>(HullLogCtx, HullDbCommitterCtx, RTCtx->LevelIndex,
ctx.SelfID, std::move(msg->ChunksToCommit), std::move(msg->ReservedChunks),
oneAddition.Sst, oneAddition.RecsNum, msg->NotifyId);
- auto aid = ctx.RegisterWithSameMailbox(actor.release());
+ auto aid = ctx.RegisterWithSameMailbox(actor.release());
ActiveActors.Insert(aid);
}
@@ -526,12 +526,12 @@ namespace NKikimr {
ScheduleCompaction(ctx);
break;
case THullCommitFinished::CommitFresh:
- ProcessFreshOnlyCompactQ(ctx);
+ ProcessFreshOnlyCompactQ(ctx);
// to avoid deadlock with emerg queue
if (FullCompactionState.Enabled()) {
- ScheduleCompaction(ctx);
- } else {
- CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx);
+ ScheduleCompaction(ctx);
+ } else {
+ CompactFreshSegmentIfRequired<TKey, TMemRec>(HullDs, RTCtx, ctx);
}
break;
case THullCommitFinished::CommitAdvanceLsn:
@@ -592,40 +592,40 @@ namespace NKikimr {
freeUpToLsn, RTCtx->LevelIndex->CurEntryPointLsn, RTCtx->LevelIndex->PrevEntryPointLsn));
}
- std::deque<std::pair<ui64, TEvHullCompact::TPtr>> FreshOnlyCompactQ;
-
+ std::deque<std::pair<ui64, TEvHullCompact::TPtr>> FreshOnlyCompactQ;
+
void Handle(TEvHullCompact::TPtr &ev, const TActorContext &ctx) {
- const ui64 confirmedLsn = RTCtx->LsnMngr->GetConfirmedLsnForHull();
- auto *msg = ev->Get();
- STLOG(PRI_INFO, BS_HULLCOMP, VDHC01, VDISKP(HullDs->HullCtx->VCtx, "TEvHullCompact"),
- (ConfirmedLsn, confirmedLsn), (Msg, *msg));
- Y_VERIFY(TKeyToEHullDbType<TKey>() == msg->Type);
-
- switch (msg->Mode) {
- using E = decltype(msg->Mode);
-
- case E::FULL:
- FullCompactionState.FullCompactionTask(confirmedLsn, ctx.Now(), msg->Type, msg->RequestId, ev->Sender);
- break;
-
- case E::FRESH_ONLY:
- Y_VERIFY(FreshOnlyCompactQ.empty() || FreshOnlyCompactQ.back().first <= confirmedLsn);
- FreshOnlyCompactQ.emplace_back(confirmedLsn, ev);
- break;
- }
-
- RTCtx->SetFreeUpToLsn(confirmedLsn);
- ScheduleCompaction(ctx);
- ProcessFreshOnlyCompactQ(ctx);
- }
-
- void ProcessFreshOnlyCompactQ(const TActorContext& ctx) {
- for (; !FreshOnlyCompactQ.empty(); FreshOnlyCompactQ.pop_front()) {
- if (auto& [lsn, ev] = FreshOnlyCompactQ.front(); RTCtx->LevelIndex->IsWrittenToSstBeforeLsn(lsn)) {
- ctx.Send(ev->Sender, new TEvHullCompactResult(ev->Get()->Type, ev->Get()->RequestId), 0, ev->Cookie);
- } else {
- break;
- }
+ const ui64 confirmedLsn = RTCtx->LsnMngr->GetConfirmedLsnForHull();
+ auto *msg = ev->Get();
+ STLOG(PRI_INFO, BS_HULLCOMP, VDHC01, VDISKP(HullDs->HullCtx->VCtx, "TEvHullCompact"),
+ (ConfirmedLsn, confirmedLsn), (Msg, *msg));
+ Y_VERIFY(TKeyToEHullDbType<TKey>() == msg->Type);
+
+ switch (msg->Mode) {
+ using E = decltype(msg->Mode);
+
+ case E::FULL:
+ FullCompactionState.FullCompactionTask(confirmedLsn, ctx.Now(), msg->Type, msg->RequestId, ev->Sender);
+ break;
+
+ case E::FRESH_ONLY:
+ Y_VERIFY(FreshOnlyCompactQ.empty() || FreshOnlyCompactQ.back().first <= confirmedLsn);
+ FreshOnlyCompactQ.emplace_back(confirmedLsn, ev);
+ break;
+ }
+
+ RTCtx->SetFreeUpToLsn(confirmedLsn);
+ ScheduleCompaction(ctx);
+ ProcessFreshOnlyCompactQ(ctx);
+ }
+
+ void ProcessFreshOnlyCompactQ(const TActorContext& ctx) {
+ for (; !FreshOnlyCompactQ.empty(); FreshOnlyCompactQ.pop_front()) {
+ if (auto& [lsn, ev] = FreshOnlyCompactQ.front(); RTCtx->LevelIndex->IsWrittenToSstBeforeLsn(lsn)) {
+ ctx.Send(ev->Sender, new TEvHullCompactResult(ev->Get()->Type, ev->Get()->RequestId), 0, ev->Cookie);
+ } else {
+ break;
+ }
}
}
@@ -639,7 +639,7 @@ namespace NKikimr {
HFunc(THullCommitFinished, Handle)
HFunc(NPDisk::TEvCutLog, Handle)
HFunc(TEvHullCompact, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
HTemplFunc(THullChange, Handle)
HTemplFunc(TFreshAppendixCompactionDone, Handle)
HTemplFunc(TEvAddBulkSst, Handle)
@@ -655,10 +655,10 @@ namespace NKikimr {
TLevelIndexActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TRunTimeCtx> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep)
+ std::shared_ptr<TRunTimeCtx> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep)
: TActorBootstrapped<TThis>()
, Config(std::move(config))
, HullDs(std::move(hullDs))
@@ -673,7 +673,7 @@ namespace NKikimr {
HullDs->HullCtx,
RTCtx->LsnMngr,
loggerId,
- HullLogCtx->HugeKeeperId))
+ HullLogCtx->HugeKeeperId))
, CompactionTask(new TCompactionTask)
, ActiveActors(RTCtx->LevelIndex->ActorCtx->ActiveActors)
, LevelStat(HullDs->HullCtx->VCtx->VDiskCounters)
@@ -683,10 +683,10 @@ namespace NKikimr {
NActors::IActor* CreateLogoBlobsActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyLogoBlob, TMemRecLogoBlob>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyLogoBlob, TMemRecLogoBlob>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
return new TLevelIndexActor<TKeyLogoBlob, TMemRecLogoBlob>(
config, hullDs, hullLogCtx, loggerId, rtCtx, syncLogFirstLsnToKeep);
@@ -695,10 +695,10 @@ namespace NKikimr {
NActors::IActor* CreateBlocksActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBlock, TMemRecBlock>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBlock, TMemRecBlock>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
return new TLevelIndexActor<TKeyBlock, TMemRecBlock>(
config, hullDs, hullLogCtx, loggerId, rtCtx, syncLogFirstLsnToKeep);
@@ -707,10 +707,10 @@ namespace NKikimr {
NActors::IActor* CreateBarriersActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBarrier, TMemRecBarrier>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBarrier, TMemRecBarrier>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep) {
return new TLevelIndexActor<TKeyBarrier, TMemRecBarrier>(
config, hullDs, hullLogCtx, loggerId, rtCtx, syncLogFirstLsnToKeep);
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h
index 5749a70ecd2..45123af4132 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullactor.h
@@ -1,5 +1,5 @@
#pragma once
-
+
#include "defs.h"
#include <ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h>
#include <ydb/core/blobstorage/vdisk/handoff/handoff_delegate.h>
@@ -46,9 +46,9 @@ namespace NKikimr {
Y_VERIFY(LsnMngr && PDiskCtx && LevelIndex);
}
- void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
+ void CutRecoveryLog(const TActorContext &ctx, std::unique_ptr<NPDisk::TEvCutLog> msg) {
if (LevelIndex)
- ctx.Send(LevelIndex->LIActor, msg.release());
+ ctx.Send(LevelIndex->LIActor, msg.release());
}
void SetFreeUpToLsn(ui64 freeUpToLsn) {
@@ -83,13 +83,13 @@ namespace NKikimr {
template <class TKey, class TMemRec>
void CompactFreshSegment(
TIntrusivePtr<THullDs> &hullDs,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
const TActorContext &ctx);
template <class TKey, class TMemRec>
bool CompactFreshSegmentIfRequired(
TIntrusivePtr<THullDs> &hullDs,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKey, TMemRec>> &rtCtx,
const TActorContext &ctx)
{
ui64 yardFreeUpToLsn = rtCtx->GetFreeUpToLsn();
@@ -106,25 +106,25 @@ namespace NKikimr {
NActors::IActor* CreateLogoBlobsActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyLogoBlob, TMemRecLogoBlob>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyLogoBlob, TMemRecLogoBlob>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
NActors::IActor* CreateBlocksActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBlock, TMemRecBlock>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBlock, TMemRecBlock>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
NActors::IActor* CreateBarriersActor(
TIntrusivePtr<TVDiskConfig> config,
TIntrusivePtr<THullDs> hullDs,
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
TActorId loggerId,
- std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBarrier, TMemRecBarrier>> rtCtx,
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
-
+ std::shared_ptr<TLevelIndexRunTimeCtx<TKeyBarrier, TMemRecBarrier>> rtCtx,
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep);
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcommit.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcommit.h
index 8b094e893bc..cff50b30124 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcommit.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcommit.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include "blobstorage_hulllog.h"
#include "hullop_entryserialize.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
@@ -8,12 +8,12 @@
#include <ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h>
#include <ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h>
-namespace NKikimr {
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // TBaseHullDbCommitter
- ////////////////////////////////////////////////////////////////////////////////
+namespace NKikimr {
+
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // TBaseHullDbCommitter
+ ////////////////////////////////////////////////////////////////////////////////
class THullDbCommitterCtx {
public:
TPDiskCtxPtr PDiskCtx;
@@ -27,7 +27,7 @@ namespace NKikimr {
THullCtxPtr hullCtx,
TIntrusivePtr<TLsnMngr> lsnMngr,
const TActorId &loggerId,
- const TActorId hugeKeeperId)
+ const TActorId hugeKeeperId)
: PDiskCtx(std::move(pdiskCtx))
, HullCtx(std::move(hullCtx))
, LsnMngr(std::move(lsnMngr))
@@ -38,177 +38,177 @@ namespace NKikimr {
}
};
- using THullDbCommitterCtxPtr = std::shared_ptr<THullDbCommitterCtx>;
+ using THullDbCommitterCtxPtr = std::shared_ptr<THullDbCommitterCtx>;
////////////////////////////////////////////////////////////////////////////////
// TBaseHullDbCommitter
////////////////////////////////////////////////////////////////////////////////
template<typename TKey, typename TMemRec, THullCommitFinished::EType NotifyType,
- NKikimrServices::TActivity::EType DerivedActivityType>
- class TBaseHullDbCommitter
+ NKikimrServices::TActivity::EType DerivedActivityType>
+ class TBaseHullDbCommitter
: public TActorBootstrapped<TBaseHullDbCommitter<TKey, TMemRec, NotifyType, DerivedActivityType>>
- {
- protected:
+ {
+ protected:
friend class TActorBootstrapped<TBaseHullDbCommitter<TKey, TMemRec, NotifyType, DerivedActivityType>>;
-
+
using TLevelIndex = NKikimr::TLevelIndex<TKey, TMemRec>;
- using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
- using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
+ using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
+ using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
using TThis = TBaseHullDbCommitter<TKey, TMemRec, NotifyType, DerivedActivityType>;
-
- struct THullCommitMeta {
+
+ struct THullCommitMeta {
TVector<ui32> CommitChunks; // chunks to commit within this log entry
TVector<ui32> DeleteChunks; // chunks to delete
- TDiskPartVec RemovedHugeBlobs; // freed huge blobs
- TLevelSegmentPtr ReplSst; // pointer to replicated SST
- ui32 NumRecoveredBlobs; // number of blobs in this SST (valid only for replicated tables)
-
+ TDiskPartVec RemovedHugeBlobs; // freed huge blobs
+ TLevelSegmentPtr ReplSst; // pointer to replicated SST
+ ui32 NumRecoveredBlobs; // number of blobs in this SST (valid only for replicated tables)
+
// constructor for ordinary committer (advance, fresh, level)
THullCommitMeta(TVector<ui32>&& chunksAdded,
TVector<ui32>&& chunksDeleted,
- TDiskPartVec&& removedHugeBlobs)
- : CommitChunks(std::move(chunksAdded))
- , DeleteChunks(std::move(chunksDeleted))
- , RemovedHugeBlobs(std::move(removedHugeBlobs))
- , NumRecoveredBlobs(0)
+ TDiskPartVec&& removedHugeBlobs)
+ : CommitChunks(std::move(chunksAdded))
+ , DeleteChunks(std::move(chunksDeleted))
+ , RemovedHugeBlobs(std::move(removedHugeBlobs))
+ , NumRecoveredBlobs(0)
{}
// constructor for repl sst committer
THullCommitMeta(TVector<ui32>&& chunksAdded,
TVector<ui32>&& chunksDeleted,
- TLevelSegmentPtr replSst,
- ui32 numRecoveredBlobs)
+ TLevelSegmentPtr replSst,
+ ui32 numRecoveredBlobs)
: CommitChunks(std::move(chunksAdded))
, DeleteChunks(std::move(chunksDeleted))
- , ReplSst(std::move(replSst))
- , NumRecoveredBlobs(numRecoveredBlobs)
- {}
- };
-
- std::shared_ptr<THullLogCtx> HullLogCtx;
+ , ReplSst(std::move(replSst))
+ , NumRecoveredBlobs(numRecoveredBlobs)
+ {}
+ };
+
+ std::shared_ptr<THullLogCtx> HullLogCtx;
THullDbCommitterCtxPtr Ctx;
TIntrusivePtr<TLevelIndex> LevelIndex;
TActorId NotifyID;
TActorId SecondNotifyID;
- THullCommitMeta Metadata;
- std::unique_ptr<NPDisk::TEvLog> CommitMsg;
+ THullCommitMeta Metadata;
+ std::unique_ptr<NPDisk::TEvLog> CommitMsg;
TLsnSeg LsnSeg;
- NPDisk::TCommitRecord CommitRecord;
+ NPDisk::TCommitRecord CommitRecord;
TStringStream DebugMessage;
TString CallerInfo;
-
- void Bootstrap(const TActorContext& ctx) {
- TThis::Become(&TThis::StateFunc);
+
+ void Bootstrap(const TActorContext& ctx) {
+ TThis::Become(&TThis::StateFunc);
LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP,
VDISKP(HullLogCtx->VCtx->VDiskLogPrefix, "sending %s lsn# %" PRIu64 " %s",
THullCommitFinished::TypeToString(NotifyType), CommitMsg->Lsn, CommitMsg->ToString().data()));
-
- if (CommitRecord.CommitChunks || CommitRecord.DeleteChunks) {
+
+ if (CommitRecord.CommitChunks || CommitRecord.DeleteChunks) {
LOG_INFO(ctx, NKikimrServices::BS_SKELETON,
VDISKP(HullLogCtx->VCtx->VDiskLogPrefix, "commit %s signature# %s CommitChunks# %s"
" DeleteChunks# %s", THullCommitFinished::TypeToString(NotifyType),
PDiskSignatureForHullDbKey<TKey>().ToString().data(),
FormatList(CommitRecord.CommitChunks).data(),
FormatList(CommitRecord.DeleteChunks).data()));
- }
-
+ }
+
LOG_DEBUG(ctx, NKikimrServices::BS_VDISK_CHUNKS,
VDISKP(HullLogCtx->VCtx->VDiskLogPrefix,"COMMIT: type# %s msg# %s",
THullCommitFinished::TypeToString(NotifyType), CommitMsg->CommitRecord.ToString().data()));
- ctx.Send(Ctx->LoggerId, CommitMsg.release());
- }
-
- virtual STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvLogResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
-
+ ctx.Send(Ctx->LoggerId, CommitMsg.release());
+ }
+
+ virtual STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvLogResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
+
PDISK_TERMINATE_STATE_FUNC_DEF;
void Handle(NPDisk::TEvLogResult::TPtr& ev, const TActorContext& ctx) {
CHECK_PDISK_RESPONSE(Ctx->HullCtx->VCtx, ev, ctx);
- // notify delayed deleter when log record is actually written; we MUST ensure that updates are coming in
- // order of increasing LSN's; this is achieved automatically as all actors reside on the same mailbox
+ // notify delayed deleter when log record is actually written; we MUST ensure that updates are coming in
+ // order of increasing LSN's; this is achieved automatically as all actors reside on the same mailbox
LevelIndex->DelayedHugeBlobDeleterInfo->Update(LsnSeg.Last, std::move(Metadata.RemovedHugeBlobs),
ctx, Ctx->HugeKeeperId, PDiskSignatureForHullDbKey<TKey>());
-
+
NPDisk::TEvLogResult* msg = ev->Get();
-
- // notify descendants about successful commit
- bool finished = OnLogResult(msg);
-
- // update current entry point for desired level index
- const auto& results = msg->Results;
+
+ // notify descendants about successful commit
+ bool finished = OnLogResult(msg);
+
+ // update current entry point for desired level index
+ const auto& results = msg->Results;
Y_VERIFY_DEBUG(results.size() == 1 && results.front().Lsn == LsnSeg.Last);
-
+
LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP,
VDISKP(HullLogCtx->VCtx->VDiskLogPrefix, "%s lsn# %s done",
THullCommitFinished::TypeToString(NotifyType), LsnSeg.ToString().data()));
-
+
LOG_INFO(ctx, NKikimrServices::BS_HULLRECS,
VDISKP(HullLogCtx->VCtx->VDiskLogPrefix, "%s", DebugMessage.Str().data()));
- // advance LSN
+ // advance LSN
LevelIndex->CurEntryPointLsn = LsnSeg.Last;
-
- if (finished)
- Finish(ctx);
- }
-
- void Finish(const TActorContext& ctx) {
- // if this was replicated SST, put it into hull -- now it is visible for users
- if (Metadata.ReplSst) {
- Ctx->LsnMngr->ConfirmLsnForHull(LsnSeg, false);
+
+ if (finished)
+ Finish(ctx);
+ }
+
+ void Finish(const TActorContext& ctx) {
+ // if this was replicated SST, put it into hull -- now it is visible for users
+ if (Metadata.ReplSst) {
+ Ctx->LsnMngr->ConfirmLsnForHull(LsnSeg, false);
LevelIndex->ApplyUncommittedReplSegment(std::move(Metadata.ReplSst), Ctx->HullCtx);
- }
-
- // notify sender & die
- ctx.Send(NotifyID, new THullCommitFinished(NotifyType));
- if (SecondNotifyID)
+ }
+
+ // notify sender & die
+ ctx.Send(NotifyID, new THullCommitFinished(NotifyType));
+ if (SecondNotifyID)
ctx.Send(SecondNotifyID, new TEvAddBulkSstResult);
- TThis::Die(ctx);
- }
-
- // validate commit record contents; this function may change order of CommitChunks/DeleteChunks inside commit
- // record, but this doesn't matter for PDisk
- void VerifyCommitRecord(NPDisk::TCommitRecord& commitRecord) {
- // sort set of chunks to quickly perform further checks
- std::sort(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end());
- std::sort(commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end());
-
- // verify that chunk ids do not repeat in both of arrays
- Y_VERIFY(std::adjacent_find(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end()) ==
- commitRecord.CommitChunks.end());
- Y_VERIFY(std::adjacent_find(commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end()) ==
- commitRecord.DeleteChunks.end());
-
- // ensure that there are no intersections between chunks being committed and deleted
+ TThis::Die(ctx);
+ }
+
+ // validate commit record contents; this function may change order of CommitChunks/DeleteChunks inside commit
+ // record, but this doesn't matter for PDisk
+ void VerifyCommitRecord(NPDisk::TCommitRecord& commitRecord) {
+ // sort set of chunks to quickly perform further checks
+ std::sort(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end());
+ std::sort(commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end());
+
+ // verify that chunk ids do not repeat in both of arrays
+ Y_VERIFY(std::adjacent_find(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end()) ==
+ commitRecord.CommitChunks.end());
+ Y_VERIFY(std::adjacent_find(commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end()) ==
+ commitRecord.DeleteChunks.end());
+
+ // ensure that there are no intersections between chunks being committed and deleted
TVector<TChunkIdx> isect;
- std::set_intersection(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end(),
- commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end(),
- std::back_inserter(isect));
- Y_VERIFY(isect.empty());
- }
-
- void VerifyRemovedHugeBlobs(TDiskPartVec& v) {
- auto comp = [](const TDiskPart& x, const TDiskPart& y) {
- return std::make_tuple(x.ChunkIdx, x.Offset, x.Size) < std::make_tuple(y.ChunkIdx, y.Offset, y.Size);
- };
- std::sort(v.Vec.begin(), v.Vec.end(), comp);
-
- auto pred = [](const TDiskPart& x, const TDiskPart& y) {
- return x.ChunkIdx == y.ChunkIdx && x.Offset == y.Offset;
- };
- auto it = std::adjacent_find(v.Vec.begin(), v.Vec.end(), pred);
- if (it != v.end()) {
- auto second = std::next(it);
+ std::set_intersection(commitRecord.CommitChunks.begin(), commitRecord.CommitChunks.end(),
+ commitRecord.DeleteChunks.begin(), commitRecord.DeleteChunks.end(),
+ std::back_inserter(isect));
+ Y_VERIFY(isect.empty());
+ }
+
+ void VerifyRemovedHugeBlobs(TDiskPartVec& v) {
+ auto comp = [](const TDiskPart& x, const TDiskPart& y) {
+ return std::make_tuple(x.ChunkIdx, x.Offset, x.Size) < std::make_tuple(y.ChunkIdx, y.Offset, y.Size);
+ };
+ std::sort(v.Vec.begin(), v.Vec.end(), comp);
+
+ auto pred = [](const TDiskPart& x, const TDiskPart& y) {
+ return x.ChunkIdx == y.ChunkIdx && x.Offset == y.Offset;
+ };
+ auto it = std::adjacent_find(v.Vec.begin(), v.Vec.end(), pred);
+ if (it != v.end()) {
+ auto second = std::next(it);
Y_FAIL("%s", VDISKP(HullLogCtx->VCtx->VDiskLogPrefix, "duplicate removed huge slots: x# %s y# %s",
it->ToString().data(), second->ToString().data()).data());
- }
- }
-
+ }
+ }
+
TString GenerateEntryPointData() const {
// prepare log record data
NKikimrVDiskData::THullDbEntryPoint pb;
@@ -217,31 +217,31 @@ namespace NKikimr {
return THullDbSignatureRoutines::Serialize(pb);
}
- void GenerateCommitMessage() {
- // prepare commit record
- CommitRecord.IsStartingPoint = true;
- CommitRecord.CommitChunks = std::move(Metadata.CommitChunks);
- CommitRecord.DeleteChunks = std::move(Metadata.DeleteChunks);
-
- // validate its contents
- VerifyCommitRecord(CommitRecord);
- VerifyRemovedHugeBlobs(Metadata.RemovedHugeBlobs);
-
+ void GenerateCommitMessage() {
+ // prepare commit record
+ CommitRecord.IsStartingPoint = true;
+ CommitRecord.CommitChunks = std::move(Metadata.CommitChunks);
+ CommitRecord.DeleteChunks = std::move(Metadata.DeleteChunks);
+
+ // validate its contents
+ VerifyCommitRecord(CommitRecord);
+ VerifyRemovedHugeBlobs(Metadata.RemovedHugeBlobs);
+
// create commit message
if (Metadata.ReplSst) {
// for replicated SST -- generate LSN range; do it now, because in serialization we need actual data
// generate range of LSN's covering newly generated blobs
const ui64 lsnAdvance = Metadata.NumRecoveredBlobs;
Y_VERIFY(lsnAdvance > 0);
- LsnSeg = Ctx->LsnMngr->AllocLsnForHull(lsnAdvance);
+ LsnSeg = Ctx->LsnMngr->AllocLsnForHull(lsnAdvance);
// store first/last LSN into level segment
Metadata.ReplSst->Info.FirstLsn = LsnSeg.First;
Metadata.ReplSst->Info.LastLsn = LsnSeg.Last;
// generate entry point data when LsgSeg is already allocated
TString data = GenerateEntryPointData();
- // create sync log message covering this segment; it will be issued when log entry is written
+ // create sync log message covering this segment; it will be issued when log entry is written
CommitMsg = CreateHullUpdate(HullLogCtx, PDiskSignatureForHullDbKey<TKey>(), CommitRecord,
- data, LsnSeg, nullptr, nullptr);
+ data, LsnSeg, nullptr, nullptr);
} else {
LsnSeg = Ctx->LsnMngr->AllocLsnForLocalUse();
DebugMessage << "Db# " << TKey::Name()
@@ -251,27 +251,27 @@ namespace NKikimr {
DebugMessage << " caller# " << CallerInfo;
}
TString data = GenerateEntryPointData();
- CommitMsg = std::make_unique<NPDisk::TEvLog>(Ctx->PDiskCtx->Dsk->Owner, Ctx->PDiskCtx->Dsk->OwnerRound,
- PDiskSignatureForHullDbKey<TKey>(), CommitRecord, data, LsnSeg, nullptr);
+ CommitMsg = std::make_unique<NPDisk::TEvLog>(Ctx->PDiskCtx->Dsk->Owner, Ctx->PDiskCtx->Dsk->OwnerRound,
+ PDiskSignatureForHullDbKey<TKey>(), CommitRecord, data, LsnSeg, nullptr);
}
- }
-
+ }
+
virtual bool OnLogResult(NPDisk::TEvLogResult* /*msg*/) {
- return true;
- }
-
+ return true;
+ }
+
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
TThis::Die(ctx);
}
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return DerivedActivityType;
}
TBaseHullDbCommitter(
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
THullDbCommitterCtxPtr ctx,
TIntrusivePtr<TLevelIndex> levelIndex,
const TActorId& notifyID,
@@ -281,28 +281,28 @@ namespace NKikimr {
: HullLogCtx(std::move(hullLogCtx))
, Ctx(std::move(ctx))
, LevelIndex(std::move(levelIndex))
- , NotifyID(notifyID)
+ , NotifyID(notifyID)
, SecondNotifyID(secondNotifyID)
- , Metadata(std::move(metadata))
+ , Metadata(std::move(metadata))
, CallerInfo(callerInfo)
- {
- // we create commit message in the constructor to avoid race condition
- GenerateCommitMessage();
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // TAsyncAdvanceLsnCommitter
- ////////////////////////////////////////////////////////////////////////////
+ {
+ // we create commit message in the constructor to avoid race condition
+ GenerateCommitMessage();
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // TAsyncAdvanceLsnCommitter
+ ////////////////////////////////////////////////////////////////////////////
template <class TKey, class TMemRec>
- class TAsyncAdvanceLsnCommitter
+ class TAsyncAdvanceLsnCommitter
: public TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitAdvanceLsn, NKikimrServices::TActivity::BS_ASYNC_LSN_COMMITTER>
- {
+ {
using TBase = TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitAdvanceLsn, NKikimrServices::TActivity::BS_ASYNC_LSN_COMMITTER>;
-
- public:
+
+ public:
TAsyncAdvanceLsnCommitter(
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
THullDbCommitterCtxPtr ctx,
TIntrusivePtr<typename TBase::TLevelIndex> levelIndex,
const TActorId &notifyID,
@@ -310,30 +310,30 @@ namespace NKikimr {
: TBase(std::move(hullLogCtx),
std::move(ctx),
std::move(levelIndex),
- notifyID,
+ notifyID,
TActorId(),
- typename TBase::THullCommitMeta(TVector<ui32>(), TVector<ui32>(), TDiskPartVec()),
+ typename TBase::THullCommitMeta(TVector<ui32>(), TVector<ui32>(), TDiskPartVec()),
callerInfo)
{}
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // TAsyncFreshCommitter
- ////////////////////////////////////////////////////////////////////////////
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // TAsyncFreshCommitter
+ ////////////////////////////////////////////////////////////////////////////
template <class TKey, class TMemRec>
- class TAsyncFreshCommitter :
+ class TAsyncFreshCommitter :
public TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitFresh, NKikimrServices::TActivity::BS_ASYNC_FRESH_COMMITTER>
- {
+ {
using TBase = TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitFresh, NKikimrServices::TActivity::BS_ASYNC_FRESH_COMMITTER>;
-
+
bool OnLogResult(NPDisk::TEvLogResult* /*msg*/) override {
TBase::LevelIndex->FreshCompactionFinished();
- return true;
- }
-
- public:
+ return true;
+ }
+
+ public:
TAsyncFreshCommitter(
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
THullDbCommitterCtxPtr ctx,
TIntrusivePtr<typename TBase::TLevelIndex> levelIndex,
const TActorId& notifyID,
@@ -344,60 +344,60 @@ namespace NKikimr {
: TBase(std::move(hullLogCtx),
std::move(ctx),
std::move(levelIndex),
- notifyID,
+ notifyID,
TActorId(),
- typename TBase::THullCommitMeta(std::move(chunksAdded),
- std::move(chunksDeleted),
- std::move(removedHugeBlobs)),
+ typename TBase::THullCommitMeta(std::move(chunksAdded),
+ std::move(chunksDeleted),
+ std::move(removedHugeBlobs)),
callerInfo)
{}
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // TAsyncLevelCommitter
- ////////////////////////////////////////////////////////////////////////////
-
- // this committer as well as committing log event and waiting for result
- // optionally waits for some slice to destroy, that is stopping using
- // ChunksToDelete from hull actor; it happens when we have active snapshot
- // while doing this commit, notification comes through THullFreeSlice
- // message
-
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // TAsyncLevelCommitter
+ ////////////////////////////////////////////////////////////////////////////
+
+ // this committer as well as committing log event and waiting for result
+ // optionally waits for some slice to destroy, that is stopping using
+ // ChunksToDelete from hull actor; it happens when we have active snapshot
+ // while doing this commit, notification comes through THullFreeSlice
+ // message
+
template <class TKey, class TMemRec>
- class TAsyncLevelCommitter
+ class TAsyncLevelCommitter
: public TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitLevel, NKikimrServices::TActivity::BS_ASYNC_LEVEL_COMMITTER>
- {
+ {
using TBase = TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitLevel, NKikimrServices::TActivity::BS_ASYNC_LEVEL_COMMITTER>;
-
- bool PrevSnapshotReleased;
- bool LogCommitted;
-
- bool Done() const {
- return PrevSnapshotReleased && LogCommitted;
- }
-
- void Handle(THullFreeSlice::TPtr& /*ev*/, const TActorContext& ctx) {
- PrevSnapshotReleased = true;
- if (Done())
- TBase::Finish(ctx);
- }
-
- STFUNC(StateFunc) override {
- switch (ev->GetTypeRewrite()) {
- HFunc(THullFreeSlice, Handle);
- default:
- return TBase::StateFunc(ev, ctx);
- }
- }
-
+
+ bool PrevSnapshotReleased;
+ bool LogCommitted;
+
+ bool Done() const {
+ return PrevSnapshotReleased && LogCommitted;
+ }
+
+ void Handle(THullFreeSlice::TPtr& /*ev*/, const TActorContext& ctx) {
+ PrevSnapshotReleased = true;
+ if (Done())
+ TBase::Finish(ctx);
+ }
+
+ STFUNC(StateFunc) override {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(THullFreeSlice, Handle);
+ default:
+ return TBase::StateFunc(ev, ctx);
+ }
+ }
+
bool OnLogResult(NPDisk::TEvLogResult* /*msg*/) override {
- LogCommitted = true;
- return Done();
- }
-
- public:
+ LogCommitted = true;
+ return Done();
+ }
+
+ public:
TAsyncLevelCommitter(
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
THullDbCommitterCtxPtr ctx,
TIntrusivePtr<typename TBase::TLevelIndex> levelIndex,
const TActorId& notifyID,
@@ -408,35 +408,35 @@ namespace NKikimr {
: TBase(std::move(hullLogCtx),
std::move(ctx),
std::move(levelIndex),
- notifyID,
+ notifyID,
TActorId(),
- typename TBase::THullCommitMeta(std::move(chunksAdded),
- std::move(chunksDeleted),
- std::move(removedHugeBlobs)),
+ typename TBase::THullCommitMeta(std::move(chunksAdded),
+ std::move(chunksDeleted),
+ std::move(removedHugeBlobs)),
TString())
- , PrevSnapshotReleased(!waitForHullFreeSlice)
- , LogCommitted(false)
+ , PrevSnapshotReleased(!waitForHullFreeSlice)
+ , LogCommitted(false)
{}
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // TAsyncReplSstCommitter
- ////////////////////////////////////////////////////////////////////////////////
-
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // TAsyncReplSstCommitter
+ ////////////////////////////////////////////////////////////////////////////////
+
template<typename TKey, typename TMemRec>
- class TAsyncReplSstCommitter
+ class TAsyncReplSstCommitter
: public TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitReplSst, NKikimrServices::TActivity::BS_ASYNC_REPLSST_COMMITTER>
- {
+ {
using TBase = TBaseHullDbCommitter<TKey, TMemRec, THullCommitFinished::CommitReplSst, NKikimrServices::TActivity::BS_ASYNC_REPLSST_COMMITTER>;
- using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
-
+ using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
+
bool OnLogResult(NPDisk::TEvLogResult* /*msg*/) override {
- return true;
- }
-
- public:
+ return true;
+ }
+
+ public:
TAsyncReplSstCommitter(
- std::shared_ptr<THullLogCtx> hullLogCtx,
+ std::shared_ptr<THullLogCtx> hullLogCtx,
THullDbCommitterCtxPtr ctx,
TIntrusivePtr<typename TBase::TLevelIndex> levelIndex,
const TActorId& notifyID,
@@ -448,12 +448,12 @@ namespace NKikimr {
: TBase(std::move(hullLogCtx),
std::move(ctx),
std::move(levelIndex),
- notifyID,
+ notifyID,
secondNotifyID,
- typename TBase::THullCommitMeta(std::move(chunksAdded), std::move(chunksDeleted), std::move(replSst),
- numRecoveredBlobs),
+ typename TBase::THullCommitMeta(std::move(chunksAdded), std::move(chunksDeleted), std::move(replSst),
+ numRecoveredBlobs),
TString())
{}
- };
-
-} // NKikimr
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h
index fca2f00daa9..5bcdbabbc33 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompact.h
@@ -29,8 +29,8 @@ namespace NKikimr {
TIntrusivePtr<TFreshSegment> FreshSegment;
// huge blobs to delete after compaction
TDiskPartVec FreedHugeBlobs;
- // was the compaction process aborted by some reason?
- bool Aborted = false;
+ // was the compaction process aborted by some reason?
+ bool Aborted = false;
THullChange() = default;
};
@@ -59,8 +59,8 @@ namespace NKikimr {
typedef ::NKikimr::TLevelIndexSnapshot<TKey, TMemRec> TLevelIndexSnapshot;
typedef ::NKikimr::TLevelIndexRunTimeCtx<TKey, TMemRec> TLevelIndexRunTimeCtx;
- using THullCompactionWorker = NKikimr::THullCompactionWorker<TKey, TMemRec, TIterator>;
-
+ using THullCompactionWorker = NKikimr::THullCompactionWorker<TKey, TMemRec, TIterator>;
+
friend class TActorBootstrapped<TThis>;
THullCtxPtr HullCtx;
@@ -68,27 +68,27 @@ namespace NKikimr {
const TActorId LIActor;
// FreshSegment to compact if any
TIntrusivePtr<TFreshSegment> FreshSegment;
- std::shared_ptr<TFreshSegmentSnapshot> FreshSegmentSnap;
+ std::shared_ptr<TFreshSegmentSnapshot> FreshSegmentSnap;
TBarriersSnapshot BarriersSnap;
TLevelIndexSnapshot LevelSnap;
TActiveActors ActiveActors;
-
+
THandoffMapPtr Hmp;
TGcMapPtr Gcmp;
TIterator It;
- THullCompactionWorker Worker;
+ THullCompactionWorker Worker;
const ui64 CompactionID;
TOrderedLevelSegmentsPtr Result;
- // messages we have to send to Yard
- TVector<std::unique_ptr<IEventBase>> MsgsForYard;
-
- TActorId SkeletonId;
-
- bool IsAborting = false;
- ui32 PendingResponses = 0;
-
+ // messages we have to send to Yard
+ TVector<std::unique_ptr<IEventBase>> MsgsForYard;
+
+ TActorId SkeletonId;
+
+ bool IsAborting = false;
+ ui32 PendingResponses = 0;
+
///////////////////////// BOOTSTRAP ////////////////////////////////////////////////
void Bootstrap(const TActorContext &ctx) {
Worker.Statistics.StartTime = TAppData::TimeProvider->Now();
@@ -113,7 +113,7 @@ namespace NKikimr {
// build barriers essence
auto brs = BarriersSnap.CreateEssence(HullCtx, 0, Max<ui64>(), brsDebugLevel);
-
+
// free barriers snapshot
BarriersSnap.Destroy();
@@ -125,120 +125,120 @@ namespace NKikimr {
// build gc map (use LevelSnap by ref)
Gcmp->BuildMap(ctx, brs, LevelSnap, It);
- TGcMapIterator gcmpIt = TGcMapIterator(Gcmp.Get());
+ TGcMapIterator gcmpIt = TGcMapIterator(Gcmp.Get());
// free level snapshot
LevelSnap.Destroy();
- // enter work state, prepare, and kick worker class
- TThis::Become(&TThis::WorkFunc);
+ // enter work state, prepare, and kick worker class
+ TThis::Become(&TThis::WorkFunc);
Worker.Prepare(Hmp, gcmpIt);
- MainCycle(ctx);
+ MainCycle(ctx);
}
- ///////////////////////// WORK: BEGIN ///////////////////////////////////////////////
- void MainCycle(const TActorContext& ctx) {
+ ///////////////////////// WORK: BEGIN ///////////////////////////////////////////////
+ void MainCycle(const TActorContext& ctx) {
// we invoke worker main cycle that possibly generates events for PDisk, they are stored in MsgsForYard; if
- // there are events, we send them to yard; worker internally controls all in flight limits and does not
- // generate more events than allowed; this function returns boolean status indicating whether compaction job
- // is finished or not
- const bool done = Worker.MainCycle(MsgsForYard, ctx);
- // check if there are messages we have for yard
- for (std::unique_ptr<IEventBase>& msg : MsgsForYard) {
- ctx.Send(PDiskCtx->PDiskId, msg.release());
- ++PendingResponses;
+ // there are events, we send them to yard; worker internally controls all in flight limits and does not
+ // generate more events than allowed; this function returns boolean status indicating whether compaction job
+ // is finished or not
+ const bool done = Worker.MainCycle(MsgsForYard, ctx);
+ // check if there are messages we have for yard
+ for (std::unique_ptr<IEventBase>& msg : MsgsForYard) {
+ ctx.Send(PDiskCtx->PDiskId, msg.release());
+ ++PendingResponses;
}
- MsgsForYard.clear();
- // when done, continue with other state
- if (done) {
- SwitchToWaitForHandoff(ctx);
- }
- }
-
- bool FinalizeIfAborting(const TActorContext& ctx) {
- if (IsAborting) {
- if (!PendingResponses) {
- Finalize(ctx);
- }
- return true;
- } else {
- return false;
- }
- }
-
- // the same logic for every yard response: apply response and restart main cycle
- void HandleYardResponse(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext &ctx) {
- --PendingResponses;
- if (ev->Get()->Status != NKikimrProto::CORRUPTED) {
- CHECK_PDISK_RESPONSE(HullCtx->VCtx, ev, ctx);
- }
- if (FinalizeIfAborting(ctx)) {
- return;
- }
- TEvRestoreCorruptedBlob *msg = Worker.Apply(ev->Get(), ctx.Now());
- MainCycle(ctx);
- if (msg) {
- ctx.Send(SkeletonId, msg);
- ++PendingResponses;
+ MsgsForYard.clear();
+ // when done, continue with other state
+ if (done) {
+ SwitchToWaitForHandoff(ctx);
}
}
- void Handle(TEvRestoreCorruptedBlobResult::TPtr& ev, const TActorContext& ctx) {
- --PendingResponses;
- if (FinalizeIfAborting(ctx)) {
- return;
- }
- TEvRestoreCorruptedBlob *msg = Worker.Apply(ev->Get(), &IsAborting, ctx.Now());
- if (FinalizeIfAborting(ctx)) {
- return;
- }
- MainCycle(ctx);
- if (msg) {
- ctx.Send(SkeletonId, msg);
- ++PendingResponses;
- }
- }
-
- void HandleYardResponse(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext &ctx) {
- --PendingResponses;
+ bool FinalizeIfAborting(const TActorContext& ctx) {
+ if (IsAborting) {
+ if (!PendingResponses) {
+ Finalize(ctx);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // the same logic for every yard response: apply response and restart main cycle
+ void HandleYardResponse(NPDisk::TEvChunkReadResult::TPtr& ev, const TActorContext &ctx) {
+ --PendingResponses;
+ if (ev->Get()->Status != NKikimrProto::CORRUPTED) {
+ CHECK_PDISK_RESPONSE(HullCtx->VCtx, ev, ctx);
+ }
+ if (FinalizeIfAborting(ctx)) {
+ return;
+ }
+ TEvRestoreCorruptedBlob *msg = Worker.Apply(ev->Get(), ctx.Now());
+ MainCycle(ctx);
+ if (msg) {
+ ctx.Send(SkeletonId, msg);
+ ++PendingResponses;
+ }
+ }
+
+ void Handle(TEvRestoreCorruptedBlobResult::TPtr& ev, const TActorContext& ctx) {
+ --PendingResponses;
+ if (FinalizeIfAborting(ctx)) {
+ return;
+ }
+ TEvRestoreCorruptedBlob *msg = Worker.Apply(ev->Get(), &IsAborting, ctx.Now());
+ if (FinalizeIfAborting(ctx)) {
+ return;
+ }
+ MainCycle(ctx);
+ if (msg) {
+ ctx.Send(SkeletonId, msg);
+ ++PendingResponses;
+ }
+ }
+
+ void HandleYardResponse(NPDisk::TEvChunkWriteResult::TPtr& ev, const TActorContext &ctx) {
+ --PendingResponses;
CHECK_PDISK_RESPONSE(HullCtx->VCtx, ev, ctx);
- if (FinalizeIfAborting(ctx)) {
- return;
- }
- Worker.Apply(ev->Get());
+ if (FinalizeIfAborting(ctx)) {
+ return;
+ }
+ Worker.Apply(ev->Get());
MainCycle(ctx);
}
- void HandleYardResponse(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
- --PendingResponses;
+ void HandleYardResponse(NPDisk::TEvChunkReserveResult::TPtr& ev, const TActorContext& ctx) {
+ --PendingResponses;
CHECK_PDISK_RESPONSE(HullCtx->VCtx, ev, ctx);
- if (FinalizeIfAborting(ctx)) {
- return;
- }
-
+ if (FinalizeIfAborting(ctx)) {
+ return;
+ }
+
LOG_INFO(ctx, NKikimrServices::BS_SKELETON,
VDISKP(HullCtx->VCtx->VDiskLogPrefix,
"comp reserve ChunkIds# %s", FormatList(ev->Get()->ChunkIds).data()));
-
- Worker.Apply(ev->Get());
- MainCycle(ctx);
- }
-
- STRICT_STFUNC(WorkFunc,
- HFunc(NPDisk::TEvChunkReserveResult, HandleYardResponse)
- HFunc(NPDisk::TEvChunkWriteResult, HandleYardResponse)
- HFunc(NPDisk::TEvChunkReadResult, HandleYardResponse)
- HFunc(TEvRestoreCorruptedBlobResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+
+ Worker.Apply(ev->Get());
+ MainCycle(ctx);
+ }
+
+ STRICT_STFUNC(WorkFunc,
+ HFunc(NPDisk::TEvChunkReserveResult, HandleYardResponse)
+ HFunc(NPDisk::TEvChunkWriteResult, HandleYardResponse)
+ HFunc(NPDisk::TEvChunkReadResult, HandleYardResponse)
+ HFunc(TEvRestoreCorruptedBlobResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
///////////////////////// WORK: END /////////////////////////////////////////////////
///////////////////////// WAITFORHANDOFF: BEGIN /////////////////////////////////////
- STRICT_STFUNC(WaitForHandoffFunc,
- HFunc(TEvHandoffSyncLogFinished, WaitForHandoffHandle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(WaitForHandoffFunc,
+ HFunc(TEvHandoffSyncLogFinished, WaitForHandoffHandle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
void SwitchToWaitForHandoff(const TActorContext &ctx) {
Hmp->Finish(ctx);
@@ -256,9 +256,9 @@ namespace NKikimr {
///////////////////////// FINALIZE: BEGIN ///////////////////////////////////////////
void Finalize(const TActorContext &ctx) {
- if (const auto& segs = Worker.GetLevelSegments(); segs && !IsAborting) {
- Result = MakeIntrusive<TOrderedLevelSegments>(segs.begin(), segs.end());
- Finish(ctx, false);
+ if (const auto& segs = Worker.GetLevelSegments(); segs && !IsAborting) {
+ Result = MakeIntrusive<TOrderedLevelSegments>(segs.begin(), segs.end());
+ Finish(ctx, false);
} else {
Finish(ctx, true);
}
@@ -269,38 +269,38 @@ namespace NKikimr {
///////////////////////// FINISH ACTIVITY: BEGIN ////////////////////////////////////
void Finish(const TActorContext &ctx, bool emptyWrite) {
// prepare commit message
- std::unique_ptr<THullChange> msg(new THullChange());
- const auto& reservedChunks = IsAborting ? Worker.GetAllocatedChunks() : Worker.GetReservedChunks();
- msg->ReservedChunks = {reservedChunks.begin(), reservedChunks.end()};
+ std::unique_ptr<THullChange> msg(new THullChange());
+ const auto& reservedChunks = IsAborting ? Worker.GetAllocatedChunks() : Worker.GetReservedChunks();
+ msg->ReservedChunks = {reservedChunks.begin(), reservedChunks.end()};
// huge blobs to free
- LOG_LOG(ctx, IsAborting ? NLog::PRI_ERROR : NLog::PRI_INFO, NKikimrServices::BS_HULLCOMP,
+ LOG_LOG(ctx, IsAborting ? NLog::PRI_ERROR : NLog::PRI_INFO, NKikimrServices::BS_HULLCOMP,
VDISKP(HullCtx->VCtx->VDiskLogPrefix,
"%s: Compaction job (%" PRIu64 ") finished (freedHugeBlobs): fresh# %s freedHugeBlobs# %s",
PDiskSignatureForHullDbKey<TKey>().ToString().data(), CompactionID,
(FreshSegment ? "true" : "false"), Worker.GetFreedHugeBlobs().ToString().data()));
- msg->FreedHugeBlobs = IsAborting ? TDiskPartVec() : Worker.GetFreedHugeBlobs();
-
+ msg->FreedHugeBlobs = IsAborting ? TDiskPartVec() : Worker.GetFreedHugeBlobs();
+
// chunks to commit
- msg->CommitChunks = IsAborting ? TVector<ui32>() : Worker.GetCommitChunks();
+ msg->CommitChunks = IsAborting ? TVector<ui32>() : Worker.GetCommitChunks();
Y_VERIFY(emptyWrite == msg->CommitChunks.empty()); // both empty or not
- msg->SegVec = IsAborting ? nullptr : std::move(Result);
- msg->FreshSegment = IsAborting ? nullptr : FreshSegment;
- msg->Aborted = IsAborting;
-
+ msg->SegVec = IsAborting ? nullptr : std::move(Result);
+ msg->FreshSegment = IsAborting ? nullptr : FreshSegment;
+ msg->Aborted = IsAborting;
+
Worker.Statistics.FinishTime = TAppData::TimeProvider->Now();
LOG_INFO(ctx, NKikimrServices::BS_HULLCOMP,
VDISKP(HullCtx->VCtx->VDiskLogPrefix,
"%s: Compaction job (%" PRIu64 ") finished: fresh# %s chunks# %" PRIu32 " stat# %s "
- "gcmpStat# %s IsAborting# %s",
+ "gcmpStat# %s IsAborting# %s",
PDiskSignatureForHullDbKey<TKey>().ToString().data(),
CompactionID, (FreshSegment ? "true" : "false"), ui32(msg->CommitChunks.size()),
- Worker.Statistics.ToString().data(), Gcmp->GetStat().ToString().data(),
- IsAborting ? "true" : "false"));
-
- ctx.Send(LIActor, msg.release());
+ Worker.Statistics.ToString().data(), Gcmp->GetStat().ToString().data(),
+ IsAborting ? "true" : "false"));
+
+ ctx.Send(LIActor, msg.release());
TThis::Die(ctx);
}
///////////////////////// FINISH ACTIVITY: END //////////////////////////////////////
@@ -314,21 +314,21 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VDISK_COMPACTION;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VDISK_COMPACTION;
}
THullCompaction(THullCtxPtr hullCtx,
- const std::shared_ptr<TLevelIndexRunTimeCtx> &rtCtx,
+ const std::shared_ptr<TLevelIndexRunTimeCtx> &rtCtx,
TIntrusivePtr<TFreshSegment> freshSegment,
- std::shared_ptr<TFreshSegmentSnapshot> freshSegmentSnap,
+ std::shared_ptr<TFreshSegmentSnapshot> freshSegmentSnap,
TBarriersSnapshot &&barriersSnap,
TLevelIndexSnapshot &&levelSnap,
ui64 mergeElementsApproximation,
const TIterator &it,
ui64 firstLsn,
- ui64 lastLsn,
- TDuration restoreDeadline,
+ ui64 lastLsn,
+ TDuration restoreDeadline,
std::optional<TKey> partitionKey)
: TActorBootstrapped<TThis>()
, HullCtx(std::move(hullCtx))
@@ -345,7 +345,7 @@ namespace NKikimr {
, Worker(HullCtx, PDiskCtx, rtCtx->LevelIndex, it, (bool)FreshSegment, firstLsn, lastLsn, restoreDeadline,
partitionKey)
, CompactionID(TAppData::RandomProvider->GenRand64())
- , SkeletonId(rtCtx->SkeletonId)
+ , SkeletonId(rtCtx->SkeletonId)
{}
};
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue.h
index bc28f0a3779..d7174a3d797 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue.h
@@ -1,98 +1,98 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/blobstorage/vdisk/common/disk_part.h>
#include <ydb/core/blobstorage/vdisk/hulldb/base/blobstorage_blob.h>
#include <ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h>
-
-#include <util/generic/queue.h>
-
-namespace NKikimr {
-
- template<typename TDerived>
- class TDeferredItemQueueBase {
- struct TItem {
- ui64 Id;
- ui32 NumReads;
- TDiskPart PreallocatedLocation;
- TDiskBlobMergerWithMask Merger;
+
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+
+ template<typename TDerived>
+ class TDeferredItemQueueBase {
+ struct TItem {
+ ui64 Id;
+ ui32 NumReads;
+ TDiskPart PreallocatedLocation;
+ TDiskBlobMergerWithMask Merger;
NMatrix::TVectorType PartsToStore;
- TLogoBlobID BlobId;
-
- TItem(ui64 id, ui32 numReads, const TDiskPart& preallocatedLocation, const TDiskBlobMerger& merger,
- NMatrix::TVectorType partsToStore, const TLogoBlobID& blobId)
- : Id(id)
- , NumReads(numReads)
- , PreallocatedLocation(preallocatedLocation)
- , Merger(merger, partsToStore)
- , PartsToStore(partsToStore)
- , BlobId(blobId)
- {}
- };
-
+ TLogoBlobID BlobId;
+
+ TItem(ui64 id, ui32 numReads, const TDiskPart& preallocatedLocation, const TDiskBlobMerger& merger,
+ NMatrix::TVectorType partsToStore, const TLogoBlobID& blobId)
+ : Id(id)
+ , NumReads(numReads)
+ , PreallocatedLocation(preallocatedLocation)
+ , Merger(merger, partsToStore)
+ , PartsToStore(partsToStore)
+ , BlobId(blobId)
+ {}
+ };
+
TQueue<TItem> ItemQueue;
- bool Started = false;
- TRopeArena& Arena;
- const TBlobStorageGroupType GType;
-
- public:
- TDeferredItemQueueBase(TRopeArena& arena, TBlobStorageGroupType gtype)
- : Arena(arena)
- , GType(gtype)
- {}
-
- template<typename... TArgs>
- void Put(TArgs&&... args) {
- Y_VERIFY(!Started);
- ItemQueue.emplace(std::forward<TArgs>(args)...);
- }
-
- template<typename... TArgs>
- void Start(TArgs&&... args) {
- Y_VERIFY(!Started);
- Started = true;
- static_cast<TDerived&>(*this).StartImpl(std::forward<TArgs>(args)...);
- ProcessItemQueue();
- }
-
- void AddReadDiskBlob(ui64 id, TRope&& buffer, NMatrix::TVectorType expectedParts) {
- Y_VERIFY(Started);
- Y_VERIFY(ItemQueue);
- TItem& item = ItemQueue.front();
- Y_VERIFY(item.Id == id);
- item.Merger.Add(TDiskBlob(&buffer, expectedParts, GType, item.BlobId));
- Y_VERIFY(item.NumReads > 0);
- if (!--item.NumReads) {
- ProcessItemQueue();
- }
- }
-
- bool AllProcessed() {
- return ItemQueue.empty();
- }
-
- void Finish() {
- Y_VERIFY(Started);
- Y_VERIFY(ItemQueue.empty());
- Started = false;
- static_cast<TDerived&>(*this).FinishImpl();
- }
-
- private:
- void ProcessItemQueue() {
- while (ItemQueue && !ItemQueue.front().NumReads) {
- ProcessItem(ItemQueue.front());
- ItemQueue.pop();
- }
- }
-
- void ProcessItem(TItem& item) {
- // ensure that we have all the parts we must have
- Y_VERIFY(item.Merger.GetDiskBlob().GetParts() == item.PartsToStore);
-
- // get newly generated blob raw content and put it into writer queue
- static_cast<TDerived&>(*this).ProcessItemImpl(item.PreallocatedLocation, item.Merger.CreateDiskBlob(Arena));
- }
- };
-
-} // NKikimr
+ bool Started = false;
+ TRopeArena& Arena;
+ const TBlobStorageGroupType GType;
+
+ public:
+ TDeferredItemQueueBase(TRopeArena& arena, TBlobStorageGroupType gtype)
+ : Arena(arena)
+ , GType(gtype)
+ {}
+
+ template<typename... TArgs>
+ void Put(TArgs&&... args) {
+ Y_VERIFY(!Started);
+ ItemQueue.emplace(std::forward<TArgs>(args)...);
+ }
+
+ template<typename... TArgs>
+ void Start(TArgs&&... args) {
+ Y_VERIFY(!Started);
+ Started = true;
+ static_cast<TDerived&>(*this).StartImpl(std::forward<TArgs>(args)...);
+ ProcessItemQueue();
+ }
+
+ void AddReadDiskBlob(ui64 id, TRope&& buffer, NMatrix::TVectorType expectedParts) {
+ Y_VERIFY(Started);
+ Y_VERIFY(ItemQueue);
+ TItem& item = ItemQueue.front();
+ Y_VERIFY(item.Id == id);
+ item.Merger.Add(TDiskBlob(&buffer, expectedParts, GType, item.BlobId));
+ Y_VERIFY(item.NumReads > 0);
+ if (!--item.NumReads) {
+ ProcessItemQueue();
+ }
+ }
+
+ bool AllProcessed() {
+ return ItemQueue.empty();
+ }
+
+ void Finish() {
+ Y_VERIFY(Started);
+ Y_VERIFY(ItemQueue.empty());
+ Started = false;
+ static_cast<TDerived&>(*this).FinishImpl();
+ }
+
+ private:
+ void ProcessItemQueue() {
+ while (ItemQueue && !ItemQueue.front().NumReads) {
+ ProcessItem(ItemQueue.front());
+ ItemQueue.pop();
+ }
+ }
+
+ void ProcessItem(TItem& item) {
+ // ensure that we have all the parts we must have
+ Y_VERIFY(item.Merger.GetDiskBlob().GetParts() == item.PartsToStore);
+
+ // get newly generated blob raw content and put it into writer queue
+ static_cast<TDerived&>(*this).ProcessItemImpl(item.PreallocatedLocation, item.Merger.CreateDiskBlob(Arena));
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue_ut.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue_ut.cpp
index 682e9f21c1c..7dd2479b300 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactdeferredqueue_ut.cpp
@@ -3,201 +3,201 @@
#include <util/random/shuffle.h>
#include <util/random/fast.h>
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/system/sanitizers.h>
-using namespace NKikimr;
-
-const TBlobStorageGroupType GType(TBlobStorageGroupType::ErasureNone);
-std::unordered_map<TString, size_t> StringToId;
-std::deque<TRope> IdToRope;
-
-size_t GetResMapId(TRope r) {
- TString s = r.ConvertToString();
- if (const auto it = StringToId.find(s); it != StringToId.end()) {
- return it->second;
- }
- const size_t id = StringToId.size();
- StringToId.emplace(std::move(s), id);
- IdToRope.push_back(std::move(r));
- return id;
-}
-
-class TTestDeferredQueue : public TDeferredItemQueueBase<TTestDeferredQueue> {
- friend class TDeferredItemQueueBase<TTestDeferredQueue>;
-
- void StartImpl() {
- }
-
- void ProcessItemImpl(const TDiskPart& /*preallocatedLocation*/, const TRope& buffer) {
- Results.push_back(GetResMapId(buffer));
- }
-
- void FinishImpl() {
- }
-
-public:
- TVector<size_t> Results;
-
- TTestDeferredQueue(TRopeArena& arena)
- : TDeferredItemQueueBase<TTestDeferredQueue>(arena, ::GType)
- {}
-};
-
+using namespace NKikimr;
+
+const TBlobStorageGroupType GType(TBlobStorageGroupType::ErasureNone);
+std::unordered_map<TString, size_t> StringToId;
+std::deque<TRope> IdToRope;
+
+size_t GetResMapId(TRope r) {
+ TString s = r.ConvertToString();
+ if (const auto it = StringToId.find(s); it != StringToId.end()) {
+ return it->second;
+ }
+ const size_t id = StringToId.size();
+ StringToId.emplace(std::move(s), id);
+ IdToRope.push_back(std::move(r));
+ return id;
+}
+
+class TTestDeferredQueue : public TDeferredItemQueueBase<TTestDeferredQueue> {
+ friend class TDeferredItemQueueBase<TTestDeferredQueue>;
+
+ void StartImpl() {
+ }
+
+ void ProcessItemImpl(const TDiskPart& /*preallocatedLocation*/, const TRope& buffer) {
+ Results.push_back(GetResMapId(buffer));
+ }
+
+ void FinishImpl() {
+ }
+
+public:
+ TVector<size_t> Results;
+
+ TTestDeferredQueue(TRopeArena& arena)
+ : TDeferredItemQueueBase<TTestDeferredQueue>(arena, ::GType)
+ {}
+};
+
Y_UNIT_TEST_SUITE(TBlobStorageHullCompactDeferredQueueTest) {
-
+
Y_UNIT_TEST(Basic) {
- TRope parts[6] = {
- TRope(TString("AAAAAA")),
- TRope(TString("BBBBBB")),
- TRope(TString("CCCCCC")),
- TRope(TString("DDDDDD")),
- TRope(TString("EEEEEE")),
- TRope(TString("FFFFFF")),
- };
-
- ui32 fullDataSize = 32;
-
- std::unordered_map<TString, size_t> resm;
-
- struct TItem {
- ssize_t BlobId;
- NMatrix::TVectorType BlobParts;
+ TRope parts[6] = {
+ TRope(TString("AAAAAA")),
+ TRope(TString("BBBBBB")),
+ TRope(TString("CCCCCC")),
+ TRope(TString("DDDDDD")),
+ TRope(TString("EEEEEE")),
+ TRope(TString("FFFFFF")),
+ };
+
+ ui32 fullDataSize = 32;
+
+ std::unordered_map<TString, size_t> resm;
+
+ struct TItem {
+ ssize_t BlobId;
+ NMatrix::TVectorType BlobParts;
NMatrix::TVectorType PartsToStore;
- TVector<std::pair<size_t, NMatrix::TVectorType>> DiskData;
- size_t Expected;
- };
+ TVector<std::pair<size_t, NMatrix::TVectorType>> DiskData;
+ size_t Expected;
+ };
TVector<TItem> items;
-
- TRopeArena arena(&TRopeArenaBackend::Allocate);
-
- auto process = [&](ui32 mem, ui32 masks0, ui32 masks1, ui32 numDiskParts) {
- ui32 masks[3] = {masks0, masks1, 0};
-
- TItem item;
- TDiskBlobMerger expm;
-
- // create initial memory merger
- for (ui8 i = 0; i < 6; ++i) {
- if (mem >> i & 1) {
- TRope buf = TDiskBlob::Create(fullDataSize, i + 1, 6, TRope(parts[i]), arena);
- TDiskBlob blob(&buf, NMatrix::TVectorType::MakeOneHot(i, 6), GType, TLogoBlobID(0, 0, 0, 0, parts[i].GetSize(), 0));
- expm.Add(blob);
- }
- }
-
- // extract blob merger data into item
- if (expm.Empty()) {
- item.BlobId = -1;
- } else {
- item.BlobId = GetResMapId(expm.CreateDiskBlob(arena));
- }
- item.BlobParts = expm.GetDiskBlob().GetParts();
-
- // generate disk parts
- ui64 wholeMask = mem;
- for (ui32 i = 0; i < numDiskParts; ++i) {
- const ui32 mask = masks[i];
-
- Y_VERIFY(mask);
-
- TDiskBlobMerger m;
- for (ui8 i = 0; i < 6; ++i) {
- if (mask >> i & 1) {
- TRope buf = TDiskBlob::Create(fullDataSize, i + 1, 6, TRope(parts[i]), arena);
- TDiskBlob blob(&buf, NMatrix::TVectorType::MakeOneHot(i, 6), GType, TLogoBlobID(0, 0, 0, 0, parts[i].GetSize(), 0));
- m.Add(blob);
- expm.Add(blob);
- }
- }
-
- TRope buf = m.CreateDiskBlob(arena);
- Y_VERIFY(buf);
- item.DiskData.emplace_back(GetResMapId(buf), m.GetDiskBlob().GetParts());
-
- wholeMask |= mask;
- }
-
- // generate parts to store vector and store item
- for (ui32 p = 1; p < 64; ++p) {
- if ((p & wholeMask) == p) {
- NMatrix::TVectorType v(0, 6);
- for (ui8 i = 0; i < 6; ++i) {
- if (p >> i & 1) {
- v.Set(i);
- }
- }
- item.PartsToStore = v;
-
- TDiskBlobMergerWithMask mx;
- mx.SetFilterMask(v);
- mx.Add(expm.GetDiskBlob());
- item.Expected = GetResMapId(mx.CreateDiskBlob(arena));
-
- items.push_back(item);
- }
- }
- };
-
- Cerr << "STEP 1" << Endl;
-
- TVector<ui32> maskopts;
- for (ui32 mask = 0; mask < 64; ++mask) {
- ui32 num = PopCount(mask);
- if (1 <= num && num <= 3) {
- maskopts.push_back(mask);
- }
- }
-
- for (ui32 mem = 0; mem < 64; ++mem) {
- process(mem, 0, 0, 0);
- for (ui32 x1 : maskopts) {
- process(mem, x1, 0, 1);
- for (ui32 x2 : maskopts) {
- process(mem, x1, x2, 2);
- }
- }
- }
-
- Cerr << "STEP 2 StringToId# " << StringToId.size() << " numItems# " << items.size() << Endl;
-
- // shuffle items
+
+ TRopeArena arena(&TRopeArenaBackend::Allocate);
+
+ auto process = [&](ui32 mem, ui32 masks0, ui32 masks1, ui32 numDiskParts) {
+ ui32 masks[3] = {masks0, masks1, 0};
+
+ TItem item;
+ TDiskBlobMerger expm;
+
+ // create initial memory merger
+ for (ui8 i = 0; i < 6; ++i) {
+ if (mem >> i & 1) {
+ TRope buf = TDiskBlob::Create(fullDataSize, i + 1, 6, TRope(parts[i]), arena);
+ TDiskBlob blob(&buf, NMatrix::TVectorType::MakeOneHot(i, 6), GType, TLogoBlobID(0, 0, 0, 0, parts[i].GetSize(), 0));
+ expm.Add(blob);
+ }
+ }
+
+ // extract blob merger data into item
+ if (expm.Empty()) {
+ item.BlobId = -1;
+ } else {
+ item.BlobId = GetResMapId(expm.CreateDiskBlob(arena));
+ }
+ item.BlobParts = expm.GetDiskBlob().GetParts();
+
+ // generate disk parts
+ ui64 wholeMask = mem;
+ for (ui32 i = 0; i < numDiskParts; ++i) {
+ const ui32 mask = masks[i];
+
+ Y_VERIFY(mask);
+
+ TDiskBlobMerger m;
+ for (ui8 i = 0; i < 6; ++i) {
+ if (mask >> i & 1) {
+ TRope buf = TDiskBlob::Create(fullDataSize, i + 1, 6, TRope(parts[i]), arena);
+ TDiskBlob blob(&buf, NMatrix::TVectorType::MakeOneHot(i, 6), GType, TLogoBlobID(0, 0, 0, 0, parts[i].GetSize(), 0));
+ m.Add(blob);
+ expm.Add(blob);
+ }
+ }
+
+ TRope buf = m.CreateDiskBlob(arena);
+ Y_VERIFY(buf);
+ item.DiskData.emplace_back(GetResMapId(buf), m.GetDiskBlob().GetParts());
+
+ wholeMask |= mask;
+ }
+
+ // generate parts to store vector and store item
+ for (ui32 p = 1; p < 64; ++p) {
+ if ((p & wholeMask) == p) {
+ NMatrix::TVectorType v(0, 6);
+ for (ui8 i = 0; i < 6; ++i) {
+ if (p >> i & 1) {
+ v.Set(i);
+ }
+ }
+ item.PartsToStore = v;
+
+ TDiskBlobMergerWithMask mx;
+ mx.SetFilterMask(v);
+ mx.Add(expm.GetDiskBlob());
+ item.Expected = GetResMapId(mx.CreateDiskBlob(arena));
+
+ items.push_back(item);
+ }
+ }
+ };
+
+ Cerr << "STEP 1" << Endl;
+
+ TVector<ui32> maskopts;
+ for (ui32 mask = 0; mask < 64; ++mask) {
+ ui32 num = PopCount(mask);
+ if (1 <= num && num <= 3) {
+ maskopts.push_back(mask);
+ }
+ }
+
+ for (ui32 mem = 0; mem < 64; ++mem) {
+ process(mem, 0, 0, 0);
+ for (ui32 x1 : maskopts) {
+ process(mem, x1, 0, 1);
+ for (ui32 x2 : maskopts) {
+ process(mem, x1, x2, 2);
+ }
+ }
+ }
+
+ Cerr << "STEP 2 StringToId# " << StringToId.size() << " numItems# " << items.size() << Endl;
+
+ // shuffle items
Shuffle(items.begin(), items.end());
-
- // generate read queue
- TTestDeferredQueue q(arena);
- TQueue<std::tuple<ui64, TRope, NMatrix::TVectorType>> itemQueue;
- TVector<size_t> referenceResults;
- ui64 id = 0;
- for (TItem& item : items) {
- // prepare item merger for this sample item
- TDiskBlobMerger merger;
- if (item.BlobId != -1) {
- merger.Add(TDiskBlob(&IdToRope[item.BlobId], item.BlobParts, GType, TLogoBlobID(0, 0, 0, 0, 6, 0)));
- }
-
- // put the item to queue
- q.Put(id, item.DiskData.size(), TDiskPart(0, 0, 0), std::move(merger), item.PartsToStore, TLogoBlobID(0, 0, 0, 0, 6, 0));
- for (auto& p : item.DiskData) {
- itemQueue.emplace(id, IdToRope[p.first], p.second);
- }
- referenceResults.push_back(item.Expected);
- ++id;
- }
-
- q.Start();
- while (itemQueue) {
- auto& front = itemQueue.front();
- q.AddReadDiskBlob(std::get<0>(front), std::move(std::get<1>(front)), std::get<2>(front));
- itemQueue.pop();
- UNIT_ASSERT_VALUES_EQUAL(q.AllProcessed(), itemQueue.empty());
- }
- q.Finish();
-
- UNIT_ASSERT_VALUES_EQUAL(referenceResults.size(), q.Results.size());
- for (ui32 i = 0; i < referenceResults.size(); ++i) {
- UNIT_ASSERT_EQUAL(referenceResults[i], q.Results[i]);
- }
- }
-
-}
+
+ // generate read queue
+ TTestDeferredQueue q(arena);
+ TQueue<std::tuple<ui64, TRope, NMatrix::TVectorType>> itemQueue;
+ TVector<size_t> referenceResults;
+ ui64 id = 0;
+ for (TItem& item : items) {
+ // prepare item merger for this sample item
+ TDiskBlobMerger merger;
+ if (item.BlobId != -1) {
+ merger.Add(TDiskBlob(&IdToRope[item.BlobId], item.BlobParts, GType, TLogoBlobID(0, 0, 0, 0, 6, 0)));
+ }
+
+ // put the item to queue
+ q.Put(id, item.DiskData.size(), TDiskPart(0, 0, 0), std::move(merger), item.PartsToStore, TLogoBlobID(0, 0, 0, 0, 6, 0));
+ for (auto& p : item.DiskData) {
+ itemQueue.emplace(id, IdToRope[p.first], p.second);
+ }
+ referenceResults.push_back(item.Expected);
+ ++id;
+ }
+
+ q.Start();
+ while (itemQueue) {
+ auto& front = itemQueue.front();
+ q.AddReadDiskBlob(std::get<0>(front), std::move(std::get<1>(front)), std::get<2>(front));
+ itemQueue.pop();
+ UNIT_ASSERT_VALUES_EQUAL(q.AllProcessed(), itemQueue.empty());
+ }
+ q.Finish();
+
+ UNIT_ASSERT_VALUES_EQUAL(referenceResults.size(), q.Results.size());
+ for (ui32 i = 0; i < referenceResults.size(); ++i) {
+ UNIT_ASSERT_EQUAL(referenceResults[i], q.Results[i]);
+ }
+ }
+
+}
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactworker.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactworker.h
index 7355d2c464b..5ebac9488a6 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactworker.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullcompactworker.h
@@ -1,5 +1,5 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include "blobstorage_readbatch.h"
#include "blobstorage_hullcompactdeferredqueue.h"
@@ -7,271 +7,271 @@
#include <ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h>
#include <ydb/core/blobstorage/vdisk/hulldb/blobstorage_hullgcmap.h>
#include <ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h>
-
-namespace NKikimr {
-
- template<typename TKey, typename TMemRec, typename TIterator>
- class THullCompactionWorker {
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // COMMON TYPE ALIASES
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // handoff map
- using THandoffMap = NKikimr::THandoffMap<TKey, TMemRec>;
- using TTransformedItem = typename THandoffMap::TTransformedItem;
- using THandoffMapPtr = TIntrusivePtr<THandoffMap>;
-
- // garbage collector map
- using TGcMap = NKikimr::TGcMap<TKey, TMemRec>;
- using TGcMapPtr = TIntrusivePtr<TGcMap>;
- using TGcMapIterator = typename TGcMap::TIterator;
-
- // compaction record merger
- using TCompactRecordMergerIndexPass = NKikimr::TCompactRecordMergerIndexPass<TKey, TMemRec>;
- using TCompactRecordMergerDataPass = NKikimr::TCompactRecordMergerDataPass<TKey, TMemRec>;
-
- // level segment
- using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
- using TWriter = typename TLevelSegment::TWriter;
-
- // level index
- using TLevelIndex = NKikimr::TLevelIndex<TKey, TMemRec>;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // DEFERRED ITEM QUEUE PROCESSOR
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- class TDeferredItemQueue : public TDeferredItemQueueBase<TDeferredItemQueue> {
- TWriter *Writer = nullptr;
-
- friend class TDeferredItemQueueBase<TDeferredItemQueue>;
-
- void StartImpl(TWriter *writer) {
- Y_VERIFY(!Writer);
- Writer = writer;
- Y_VERIFY(Writer);
- }
-
- void ProcessItemImpl(const TDiskPart& preallocatedLocation, TRope&& buffer) {
- TDiskPart writtenLocation = Writer->PushDataOnly(std::move(buffer));
-
- // ensure that item was written into preallocated position
- Y_VERIFY(writtenLocation == preallocatedLocation);
- }
-
- void FinishImpl() {
- Y_VERIFY(Writer);
- Writer = nullptr;
- }
-
- public:
- TDeferredItemQueue(TRopeArena& arena, TBlobStorageGroupType gtype)
- : TDeferredItemQueueBase<TDeferredItemQueue>(arena, gtype)
- {}
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // LOCAL TYPE DEFINITIONS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // state of compaction worker automaton
- enum class EState {
- Invalid, // invalid state; this state should never be reached
- GetNextItem, // going to extract next item for processing or finish if there are no more items
- TryProcessItem, // trying to write item into SST
- WaitingForDeferredItems,
- FlushingSST, // flushing SST to disk
- WaitForPendingRequests, // waiting for all pending requests to finish
- };
-
- // status of try
- enum class ETryProcessItemStatus {
- Success, // item was written to SST
- NeedMoreChunks, // we need more chunks to create new writer
- FinishSST, // we need to flush current SST to start a new one as this is full
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // MEMBER VARIABLES
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
+namespace NKikimr {
+
+ template<typename TKey, typename TMemRec, typename TIterator>
+ class THullCompactionWorker {
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // COMMON TYPE ALIASES
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // handoff map
+ using THandoffMap = NKikimr::THandoffMap<TKey, TMemRec>;
+ using TTransformedItem = typename THandoffMap::TTransformedItem;
+ using THandoffMapPtr = TIntrusivePtr<THandoffMap>;
+
+ // garbage collector map
+ using TGcMap = NKikimr::TGcMap<TKey, TMemRec>;
+ using TGcMapPtr = TIntrusivePtr<TGcMap>;
+ using TGcMapIterator = typename TGcMap::TIterator;
+
+ // compaction record merger
+ using TCompactRecordMergerIndexPass = NKikimr::TCompactRecordMergerIndexPass<TKey, TMemRec>;
+ using TCompactRecordMergerDataPass = NKikimr::TCompactRecordMergerDataPass<TKey, TMemRec>;
+
+ // level segment
+ using TLevelSegment = NKikimr::TLevelSegment<TKey, TMemRec>;
+ using TWriter = typename TLevelSegment::TWriter;
+
+ // level index
+ using TLevelIndex = NKikimr::TLevelIndex<TKey, TMemRec>;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DEFERRED ITEM QUEUE PROCESSOR
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ class TDeferredItemQueue : public TDeferredItemQueueBase<TDeferredItemQueue> {
+ TWriter *Writer = nullptr;
+
+ friend class TDeferredItemQueueBase<TDeferredItemQueue>;
+
+ void StartImpl(TWriter *writer) {
+ Y_VERIFY(!Writer);
+ Writer = writer;
+ Y_VERIFY(Writer);
+ }
+
+ void ProcessItemImpl(const TDiskPart& preallocatedLocation, TRope&& buffer) {
+ TDiskPart writtenLocation = Writer->PushDataOnly(std::move(buffer));
+
+ // ensure that item was written into preallocated position
+ Y_VERIFY(writtenLocation == preallocatedLocation);
+ }
+
+ void FinishImpl() {
+ Y_VERIFY(Writer);
+ Writer = nullptr;
+ }
+
+ public:
+ TDeferredItemQueue(TRopeArena& arena, TBlobStorageGroupType gtype)
+ : TDeferredItemQueueBase<TDeferredItemQueue>(arena, gtype)
+ {}
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LOCAL TYPE DEFINITIONS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // state of compaction worker automaton
+ enum class EState {
+ Invalid, // invalid state; this state should never be reached
+ GetNextItem, // going to extract next item for processing or finish if there are no more items
+ TryProcessItem, // trying to write item into SST
+ WaitingForDeferredItems,
+ FlushingSST, // flushing SST to disk
+ WaitForPendingRequests, // waiting for all pending requests to finish
+ };
+
+ // status of try
+ enum class ETryProcessItemStatus {
+ Success, // item was written to SST
+ NeedMoreChunks, // we need more chunks to create new writer
+ FinishSST, // we need to flush current SST to start a new one as this is full
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MEMBER VARIABLES
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
// basic contexts
THullCtxPtr HullCtx;
TPDiskCtxPtr PDiskCtx;
-
+
// Group Type
const TBlobStorageGroupType GType;
- // pointer to level index
+ // pointer to level index
const TIntrusivePtr<TLevelIndex> LevelIndex;
-
- // handoff map we use to transform items
- THandoffMapPtr Hmp;
-
- // garbage collector iterator
- TGcMapIterator GcmpIt;
-
- // LSN range
+
+ // handoff map we use to transform items
+ THandoffMapPtr Hmp;
+
+ // garbage collector iterator
+ TGcMapIterator GcmpIt;
+
+ // LSN range
const ui64 FirstLsn = 0;
const ui64 LastLsn = 0;
-
- // level DB iterator
- TIterator It;
-
- // true if fresh segment is being compacted
- const bool IsFresh;
-
- // maximum number of chunks we use per SST
+
+ // level DB iterator
+ TIterator It;
+
+ // true if fresh segment is being compacted
+ const bool IsFresh;
+
+ // maximum number of chunks we use per SST
ui32 ChunksToUse;
-
- // chunks currently reserved and not used
+
+ // chunks currently reserved and not used
TDeque<TChunkIdx> ReservedChunks;
-
- // all reserved chunks during the compaction
- TDeque<TChunkIdx> AllocatedChunks;
-
- // record merger for compaction
- TCompactRecordMergerIndexPass IndexMerger;
-
- // current handoff-transformed item
- const TTransformedItem *TransformedItem = nullptr;
-
- // SST writer
- std::unique_ptr<TWriter> WriterPtr;
-
- // number of chunks we have asked to reserve, but not yet confirmed
- ui32 ChunkReservePending = 0;
-
- // automaton state
- EState State = EState::Invalid;
-
- // number of currently unresponded write requests
- ui32 InFlightWrites = 0;
-
- // maximum number of such requests
+
+ // all reserved chunks during the compaction
+ TDeque<TChunkIdx> AllocatedChunks;
+
+ // record merger for compaction
+ TCompactRecordMergerIndexPass IndexMerger;
+
+ // current handoff-transformed item
+ const TTransformedItem *TransformedItem = nullptr;
+
+ // SST writer
+ std::unique_ptr<TWriter> WriterPtr;
+
+ // number of chunks we have asked to reserve, but not yet confirmed
+ ui32 ChunkReservePending = 0;
+
+ // automaton state
+ EState State = EState::Invalid;
+
+ // number of currently unresponded write requests
+ ui32 InFlightWrites = 0;
+
+ // maximum number of such requests
ui32 MaxInFlightWrites;
-
- // number of currently unresponded read requests
- ui32 InFlightReads = 0;
-
- // maximum number of such requests
+
+ // number of currently unresponded read requests
+ ui32 InFlightReads = 0;
+
+ // maximum number of such requests
ui32 MaxInFlightReads;
-
- // vector of freed huge blobs
- TDiskPartVec FreedHugeBlobs;
-
- // generated level segments
+
+ // vector of freed huge blobs
+ TDiskPartVec FreedHugeBlobs;
+
+ // generated level segments
TVector<TIntrusivePtr<TLevelSegment>> LevelSegments;
-
- // generated chunks
+
+ // generated chunks
TVector<TChunkIdx> CommitChunks;
-
- // pointer to an atomic variable contaning number of in flight reads
- TAtomic *ReadsInFlight;
-
- // pointer to an atomic variable contaning number of in flight writes
- TAtomic *WritesInFlight;
-
- struct TBatcherPayload {
- ui64 Id = 0;
+
+ // pointer to an atomic variable contaning number of in flight reads
+ TAtomic *ReadsInFlight;
+
+ // pointer to an atomic variable contaning number of in flight writes
+ TAtomic *WritesInFlight;
+
+ struct TBatcherPayload {
+ ui64 Id = 0;
NMatrix::TVectorType LocalParts; // a bit vector of local parts we are going to read from this disk blob
- TLogoBlobID BlobId;
- TDiskPart Location;
-
- TBatcherPayload() = default;
- TBatcherPayload(ui64 id, NMatrix::TVectorType localParts, TLogoBlobID blobId, TDiskPart location)
- : Id(id)
- , LocalParts(localParts)
- , BlobId(blobId)
- , Location(location)
- {}
- };
- TCompactReadBatcher<TBatcherPayload> ReadBatcher;
-
- // arena for different kinds of small-block allocations
- TRopeArena Arena;
-
- TDeferredItemQueue DeferredItems;
- ui64 NextDeferredItemId = 1;
-
- // previous key (in case of logoblobs)
- TKey PreviousKey;
-
- // is this the first key?
- bool IsFirstKey = true;
-
- public:
+ TLogoBlobID BlobId;
+ TDiskPart Location;
+
+ TBatcherPayload() = default;
+ TBatcherPayload(ui64 id, NMatrix::TVectorType localParts, TLogoBlobID blobId, TDiskPart location)
+ : Id(id)
+ , LocalParts(localParts)
+ , BlobId(blobId)
+ , Location(location)
+ {}
+ };
+ TCompactReadBatcher<TBatcherPayload> ReadBatcher;
+
+ // arena for different kinds of small-block allocations
+ TRopeArena Arena;
+
+ TDeferredItemQueue DeferredItems;
+ ui64 NextDeferredItemId = 1;
+
+ // previous key (in case of logoblobs)
+ TKey PreviousKey;
+
+ // is this the first key?
+ bool IsFirstKey = true;
+
+ public:
struct TStatistics {
THullCtxPtr HullCtx;
- // read/write stat
- ui64 BytesRead = 0;
- ui64 ReadIOPS = 0;
- ui64 BytesWritten = 0;
- ui64 WriteIOPS = 0;
- ui64 ItemsWritten = 0;
- // garbage collect stat
- ui64 KeepItemsWithData = 0;
- ui64 KeepItemsWOData = 0;
- ui64 DontKeepItems = 0;
- // time stat
- TInstant CreationTime;
- TInstant StartTime;
- TInstant FinishTime;
-
+ // read/write stat
+ ui64 BytesRead = 0;
+ ui64 ReadIOPS = 0;
+ ui64 BytesWritten = 0;
+ ui64 WriteIOPS = 0;
+ ui64 ItemsWritten = 0;
+ // garbage collect stat
+ ui64 KeepItemsWithData = 0;
+ ui64 KeepItemsWOData = 0;
+ ui64 DontKeepItems = 0;
+ // time stat
+ TInstant CreationTime;
+ TInstant StartTime;
+ TInstant FinishTime;
+
TStatistics(THullCtxPtr hullCtx)
: HullCtx(hullCtx)
- , CreationTime(TAppData::TimeProvider->Now())
- , StartTime()
- , FinishTime()
- {}
-
+ , CreationTime(TAppData::TimeProvider->Now())
+ , StartTime()
+ , FinishTime()
+ {}
+
TString ToString() const {
- TStringStream str;
- str << "{WaitTime# " << (StartTime - CreationTime).ToString()
- << " GetNextItemTime# " << (FinishTime - StartTime).ToString()
- << " BytesRead# " << BytesRead << " ReadIOPS# " << ReadIOPS
- << " BytesWritten# " << BytesWritten << " WriteIOPS# " << WriteIOPS
- << " ItemsWritten# " << ItemsWritten
- << " KeepItemsWithData# " << KeepItemsWithData
- << " KeepItemsWOData# " << KeepItemsWOData
- << " DontKeepItems# " << DontKeepItems << "}";
-
- return str.Str();
- }
-
- void ItemAdded() {
- ItemsWritten++;
- }
-
+ TStringStream str;
+ str << "{WaitTime# " << (StartTime - CreationTime).ToString()
+ << " GetNextItemTime# " << (FinishTime - StartTime).ToString()
+ << " BytesRead# " << BytesRead << " ReadIOPS# " << ReadIOPS
+ << " BytesWritten# " << BytesWritten << " WriteIOPS# " << WriteIOPS
+ << " ItemsWritten# " << ItemsWritten
+ << " KeepItemsWithData# " << KeepItemsWithData
+ << " KeepItemsWOData# " << KeepItemsWOData
+ << " DontKeepItems# " << DontKeepItems << "}";
+
+ return str.Str();
+ }
+
+ void ItemAdded() {
+ ItemsWritten++;
+ }
+
void Update(const NPDisk::TEvChunkRead *msg) {
- BytesRead += msg->Size;
- ReadIOPS++;
+ BytesRead += msg->Size;
+ ReadIOPS++;
HullCtx->LsmHullGroup.LsmCompactionBytesRead() += msg->Size;
- }
-
+ }
+
void Update(const NPDisk::TEvChunkWrite *msg) {
- ui32 bytes = msg->PartsPtr ? msg->PartsPtr->ByteSize() : 0;
- BytesWritten += bytes;
- WriteIOPS++;
+ ui32 bytes = msg->PartsPtr ? msg->PartsPtr->ByteSize() : 0;
+ BytesWritten += bytes;
+ WriteIOPS++;
HullCtx->LsmHullGroup.LsmCompactionBytesWritten() += bytes;
- }
- };
-
+ }
+ };
+
TStatistics Statistics;
- TDuration RestoreDeadline;
+ TDuration RestoreDeadline;
// Partition key is used for splitting resulting SSTs by the PartitionKey if present. Partition key
// is used for compaction policy implementation to limit number of intermediate chunks durint compaction.
std::optional<TKey> PartitionKey;
-
- public:
+
+ public:
THullCompactionWorker(THullCtxPtr hullCtx,
TPDiskCtxPtr pdiskCtx,
TIntrusivePtr<TLevelIndex> levelIndex,
const TIterator& it,
bool isFresh,
ui64 firstLsn,
- ui64 lastLsn,
- TDuration restoreDeadline,
+ ui64 lastLsn,
+ TDuration restoreDeadline,
std::optional<TKey> partitionKey)
: HullCtx(std::move(hullCtx))
, PDiskCtx(std::move(pdiskCtx))
@@ -279,16 +279,16 @@ namespace NKikimr {
, LevelIndex(std::move(levelIndex))
, FirstLsn(firstLsn)
, LastLsn(lastLsn)
- , It(it)
- , IsFresh(isFresh)
+ , It(it)
+ , IsFresh(isFresh)
, IndexMerger(GType)
, ReadBatcher(PDiskCtx->Dsk->ReadBlockSize,
PDiskCtx->Dsk->SeekTimeUs * PDiskCtx->Dsk->ReadSpeedBps / 1000000,
HullCtx->HullCompReadBatchEfficiencyThreshold)
- , Arena(&TRopeArenaBackend::Allocate)
- , DeferredItems(Arena, HullCtx->VCtx->Top->GType)
+ , Arena(&TRopeArenaBackend::Allocate)
+ , DeferredItems(Arena, HullCtx->VCtx->Top->GType)
, Statistics(HullCtx)
- , RestoreDeadline(restoreDeadline)
+ , RestoreDeadline(restoreDeadline)
, PartitionKey(partitionKey)
{
if (IsFresh) {
@@ -305,419 +305,419 @@ namespace NKikimr {
WritesInFlight = &LevelIndex->HullCompWritesInFlight;
}
}
-
+
void Prepare(THandoffMapPtr hmp, TGcMapIterator gcmpIt) {
- Hmp = std::move(hmp);
- GcmpIt = gcmpIt;
- State = EState::GetNextItem;
- }
-
- // main cycle function; return true if compaction is finished and compaction actor can proceed to index load;
- // when there is more work to do, return false; MUST NOT return true unless all pending requests are finished
- bool MainCycle(TVector<std::unique_ptr<IEventBase>>& msgsForYard, const TActorContext& ctx) {
- for (;;) {
- switch (State) {
- case EState::Invalid:
- Y_FAIL("unexpected state");
-
- case EState::GetNextItem:
- if (It.Valid()) {
- const TKey& key = It.GetCurKey();
- if (IsFirstKey) {
- IsFirstKey = false;
- } else {
- Y_VERIFY(!key.IsSameAs(PreviousKey), "duplicate keys: %s -> %s",
+ Hmp = std::move(hmp);
+ GcmpIt = gcmpIt;
+ State = EState::GetNextItem;
+ }
+
+ // main cycle function; return true if compaction is finished and compaction actor can proceed to index load;
+ // when there is more work to do, return false; MUST NOT return true unless all pending requests are finished
+ bool MainCycle(TVector<std::unique_ptr<IEventBase>>& msgsForYard, const TActorContext& ctx) {
+ for (;;) {
+ switch (State) {
+ case EState::Invalid:
+ Y_FAIL("unexpected state");
+
+ case EState::GetNextItem:
+ if (It.Valid()) {
+ const TKey& key = It.GetCurKey();
+ if (IsFirstKey) {
+ IsFirstKey = false;
+ } else {
+ Y_VERIFY(!key.IsSameAs(PreviousKey), "duplicate keys: %s -> %s",
PreviousKey.ToString().data(), key.ToString().data());
- }
- PreviousKey = key;
-
- // iterator is valid and we have one more item to process; instruct merger whether we want
- // data or not and proceed to TryProcessItem state
- Y_VERIFY(GcmpIt.Valid());
- IndexMerger.SetLoadDataMode(GcmpIt.KeepData());
- It.PutToMerger(&IndexMerger);
-
- const bool haveToProcessItem = PreprocessItem(ctx);
- if (haveToProcessItem) {
- State = EState::TryProcessItem;
- } else {
- FinishItem();
- }
- } else if (WriterPtr) {
- // start processing deferred items
- DeferredItems.Start(WriterPtr.get());
- // start batcher
- ReadBatcher.Start();
- // iterator is not valid and we have writer with items (because we don't create writer
- // unless there are actual items we want to write); proceed to WaitingForDeferredItems state
- State = EState::WaitingForDeferredItems;
- } else {
- // iterator is not valid and we have no writer -- so just proceed to WaitForPendingRequests
- // state and finish
- State = EState::WaitForPendingRequests;
- }
- break;
-
- case EState::TryProcessItem:
- // ensure we have transformed item
- Y_VERIFY(TransformedItem);
- // try to process it
- ETryProcessItemStatus status;
- status = TryProcessItem();
- switch (status) {
- case ETryProcessItemStatus::Success:
- // try to send some messages if this is the fresh segment
- if (IsFresh) {
- ProcessPendingMessages(msgsForYard);
- }
- // finalize item
- FinishItem();
- // continue with next item
- State = EState::GetNextItem;
- break;
-
- case ETryProcessItemStatus::NeedMoreChunks:
- // generate request for chunk reservation and try again
- if (auto msg = CheckForReservation()) {
- msgsForYard.push_back(std::move(msg));
- } else {
- Y_VERIFY(ChunkReservePending);
- }
- return false;
-
- case ETryProcessItemStatus::FinishSST:
- // start processing deferred items
- DeferredItems.Start(WriterPtr.get());
- // start batcher
- ReadBatcher.Start();
- // wait
- State = EState::WaitingForDeferredItems;
- break;
- }
- break;
-
- case EState::WaitingForDeferredItems:
- ProcessPendingMessages(msgsForYard);
- if (!DeferredItems.AllProcessed()) {
- return false;
- }
- DeferredItems.Finish();
- // we have finished will all of the deferred items, it's a good time to flush SST now
- State = EState::FlushingSST;
- ReadBatcher.Finish();
- break;
-
- case EState::FlushingSST:
- // do not continue processing if there are too many writes in flight
- if (InFlightWrites >= MaxInFlightWrites) {
- return false;
- }
- // try to flush SST
- if (FlushSST(msgsForYard)) {
- // we return to state from which finalization was invoked
- State = TransformedItem ? EState::TryProcessItem : EState::GetNextItem;
- }
- break;
-
- case EState::WaitForPendingRequests:
- // wait until all writes succeed
- if (InFlightWrites) {
- return false;
- }
-
- // wait until chunk reservation finishes (if any)
- if (ChunkReservePending) {
- return false;
- }
-
- // should never return to main cycle
- State = EState::Invalid;
-
- // return true indicating successful completion of this compaction job
- return true;
- }
- }
- }
-
- TEvRestoreCorruptedBlob *Apply(NPDisk::TEvChunkReadResult *msg, TInstant now) {
- AtomicDecrement(*ReadsInFlight);
- Y_VERIFY(InFlightReads > 0);
- --InFlightReads;
-
- // apply read result to batcher
- ReadBatcher.Apply(msg);
- return ProcessReadBatcher(now);
- }
-
- bool ExpectingBlobRestoration = false;
-
- TEvRestoreCorruptedBlob *Apply(TEvRestoreCorruptedBlobResult *msg, bool *isAborting, TInstant now) {
- Y_VERIFY(msg->Items.size() == 1);
- Y_VERIFY(ExpectingBlobRestoration);
- ExpectingBlobRestoration = false;
- auto& item = msg->Items.front();
- switch (item.Status) {
- case NKikimrProto::OK: {
- std::array<TRope, 8> parts;
- ui32 numParts = 0;
- for (ui32 i = item.Needed.FirstPosition(); i != item.Needed.GetSize(); i = item.Needed.NextPosition(i)) {
- parts[numParts++] = TRope(item.PartSet.Parts[i].OwnedString);
- }
- DeferredItems.AddReadDiskBlob(item.Cookie, TDiskBlob::CreateFromDistinctParts(&parts[0],
- &parts[numParts], item.Needed, item.BlobId.BlobSize(), Arena), item.Needed);
- return ProcessReadBatcher(now);
- }
-
- case NKikimrProto::DEADLINE:
- case NKikimrProto::ERROR:
- *isAborting = true;
- return nullptr;
-
- default:
- Y_FAIL();
- }
- }
-
- TEvRestoreCorruptedBlob *ProcessReadBatcher(TInstant now) {
- if (ExpectingBlobRestoration) {
- return nullptr;
- }
- // try to extract as much as possible items from read batcher
- ui64 serial;
- TBatcherPayload payload;
- NKikimrProto::EReplyStatus status;
+ }
+ PreviousKey = key;
+
+ // iterator is valid and we have one more item to process; instruct merger whether we want
+ // data or not and proceed to TryProcessItem state
+ Y_VERIFY(GcmpIt.Valid());
+ IndexMerger.SetLoadDataMode(GcmpIt.KeepData());
+ It.PutToMerger(&IndexMerger);
+
+ const bool haveToProcessItem = PreprocessItem(ctx);
+ if (haveToProcessItem) {
+ State = EState::TryProcessItem;
+ } else {
+ FinishItem();
+ }
+ } else if (WriterPtr) {
+ // start processing deferred items
+ DeferredItems.Start(WriterPtr.get());
+ // start batcher
+ ReadBatcher.Start();
+ // iterator is not valid and we have writer with items (because we don't create writer
+ // unless there are actual items we want to write); proceed to WaitingForDeferredItems state
+ State = EState::WaitingForDeferredItems;
+ } else {
+ // iterator is not valid and we have no writer -- so just proceed to WaitForPendingRequests
+ // state and finish
+ State = EState::WaitForPendingRequests;
+ }
+ break;
+
+ case EState::TryProcessItem:
+ // ensure we have transformed item
+ Y_VERIFY(TransformedItem);
+ // try to process it
+ ETryProcessItemStatus status;
+ status = TryProcessItem();
+ switch (status) {
+ case ETryProcessItemStatus::Success:
+ // try to send some messages if this is the fresh segment
+ if (IsFresh) {
+ ProcessPendingMessages(msgsForYard);
+ }
+ // finalize item
+ FinishItem();
+ // continue with next item
+ State = EState::GetNextItem;
+ break;
+
+ case ETryProcessItemStatus::NeedMoreChunks:
+ // generate request for chunk reservation and try again
+ if (auto msg = CheckForReservation()) {
+ msgsForYard.push_back(std::move(msg));
+ } else {
+ Y_VERIFY(ChunkReservePending);
+ }
+ return false;
+
+ case ETryProcessItemStatus::FinishSST:
+ // start processing deferred items
+ DeferredItems.Start(WriterPtr.get());
+ // start batcher
+ ReadBatcher.Start();
+ // wait
+ State = EState::WaitingForDeferredItems;
+ break;
+ }
+ break;
+
+ case EState::WaitingForDeferredItems:
+ ProcessPendingMessages(msgsForYard);
+ if (!DeferredItems.AllProcessed()) {
+ return false;
+ }
+ DeferredItems.Finish();
+ // we have finished will all of the deferred items, it's a good time to flush SST now
+ State = EState::FlushingSST;
+ ReadBatcher.Finish();
+ break;
+
+ case EState::FlushingSST:
+ // do not continue processing if there are too many writes in flight
+ if (InFlightWrites >= MaxInFlightWrites) {
+ return false;
+ }
+ // try to flush SST
+ if (FlushSST(msgsForYard)) {
+ // we return to state from which finalization was invoked
+ State = TransformedItem ? EState::TryProcessItem : EState::GetNextItem;
+ }
+ break;
+
+ case EState::WaitForPendingRequests:
+ // wait until all writes succeed
+ if (InFlightWrites) {
+ return false;
+ }
+
+ // wait until chunk reservation finishes (if any)
+ if (ChunkReservePending) {
+ return false;
+ }
+
+ // should never return to main cycle
+ State = EState::Invalid;
+
+ // return true indicating successful completion of this compaction job
+ return true;
+ }
+ }
+ }
+
+ TEvRestoreCorruptedBlob *Apply(NPDisk::TEvChunkReadResult *msg, TInstant now) {
+ AtomicDecrement(*ReadsInFlight);
+ Y_VERIFY(InFlightReads > 0);
+ --InFlightReads;
+
+ // apply read result to batcher
+ ReadBatcher.Apply(msg);
+ return ProcessReadBatcher(now);
+ }
+
+ bool ExpectingBlobRestoration = false;
+
+ TEvRestoreCorruptedBlob *Apply(TEvRestoreCorruptedBlobResult *msg, bool *isAborting, TInstant now) {
+ Y_VERIFY(msg->Items.size() == 1);
+ Y_VERIFY(ExpectingBlobRestoration);
+ ExpectingBlobRestoration = false;
+ auto& item = msg->Items.front();
+ switch (item.Status) {
+ case NKikimrProto::OK: {
+ std::array<TRope, 8> parts;
+ ui32 numParts = 0;
+ for (ui32 i = item.Needed.FirstPosition(); i != item.Needed.GetSize(); i = item.Needed.NextPosition(i)) {
+ parts[numParts++] = TRope(item.PartSet.Parts[i].OwnedString);
+ }
+ DeferredItems.AddReadDiskBlob(item.Cookie, TDiskBlob::CreateFromDistinctParts(&parts[0],
+ &parts[numParts], item.Needed, item.BlobId.BlobSize(), Arena), item.Needed);
+ return ProcessReadBatcher(now);
+ }
+
+ case NKikimrProto::DEADLINE:
+ case NKikimrProto::ERROR:
+ *isAborting = true;
+ return nullptr;
+
+ default:
+ Y_FAIL();
+ }
+ }
+
+ TEvRestoreCorruptedBlob *ProcessReadBatcher(TInstant now) {
+ if (ExpectingBlobRestoration) {
+ return nullptr;
+ }
+ // try to extract as much as possible items from read batcher
+ ui64 serial;
+ TBatcherPayload payload;
+ NKikimrProto::EReplyStatus status;
TString buffer;
- while (ReadBatcher.GetResultItem(&serial, &payload, &status, &buffer)) {
- if (status == NKikimrProto::CORRUPTED) {
- ExpectingBlobRestoration = true;
- TEvRestoreCorruptedBlob::TItem item(payload.BlobId, payload.LocalParts, GType, payload.Location, payload.Id);
- return new TEvRestoreCorruptedBlob(now + RestoreDeadline, {1u, item}, false, true);
- } else {
- Y_VERIFY(status == NKikimrProto::OK);
- DeferredItems.AddReadDiskBlob(payload.Id, TRope(buffer), payload.LocalParts);
- }
- }
- return nullptr;
- }
-
+ while (ReadBatcher.GetResultItem(&serial, &payload, &status, &buffer)) {
+ if (status == NKikimrProto::CORRUPTED) {
+ ExpectingBlobRestoration = true;
+ TEvRestoreCorruptedBlob::TItem item(payload.BlobId, payload.LocalParts, GType, payload.Location, payload.Id);
+ return new TEvRestoreCorruptedBlob(now + RestoreDeadline, {1u, item}, false, true);
+ } else {
+ Y_VERIFY(status == NKikimrProto::OK);
+ DeferredItems.AddReadDiskBlob(payload.Id, TRope(buffer), payload.LocalParts);
+ }
+ }
+ return nullptr;
+ }
+
void Apply(NPDisk::TEvChunkWriteResult * /*msg*/) {
- // adjust number of in flight messages
- Y_VERIFY(InFlightWrites > 0);
- --InFlightWrites;
- AtomicDecrement(*WritesInFlight);
- }
-
+ // adjust number of in flight messages
+ Y_VERIFY(InFlightWrites > 0);
+ --InFlightWrites;
+ AtomicDecrement(*WritesInFlight);
+ }
+
void Apply(NPDisk::TEvChunkReserveResult *msg) {
- // reset in flight allocation counter
- ChunkReservePending = 0;
-
- // add newly allocated chunks to reserved chunks set
- ReservedChunks.insert(ReservedChunks.end(), msg->ChunkIds.begin(), msg->ChunkIds.end());
- AllocatedChunks.insert(AllocatedChunks.end(), msg->ChunkIds.begin(), msg->ChunkIds.end());
- }
-
+ // reset in flight allocation counter
+ ChunkReservePending = 0;
+
+ // add newly allocated chunks to reserved chunks set
+ ReservedChunks.insert(ReservedChunks.end(), msg->ChunkIds.begin(), msg->ChunkIds.end());
+ AllocatedChunks.insert(AllocatedChunks.end(), msg->ChunkIds.begin(), msg->ChunkIds.end());
+ }
+
const TVector<TIntrusivePtr<TLevelSegment>>& GetLevelSegments() { return LevelSegments; }
const TVector<TChunkIdx>& GetCommitChunks() const { return CommitChunks; }
- const TDiskPartVec& GetFreedHugeBlobs() const { return FreedHugeBlobs; }
+ const TDiskPartVec& GetFreedHugeBlobs() const { return FreedHugeBlobs; }
const TDeque<TChunkIdx>& GetReservedChunks() const { return ReservedChunks; }
- const TDeque<TChunkIdx>& GetAllocatedChunks() const { return AllocatedChunks; }
-
- private:
+ const TDeque<TChunkIdx>& GetAllocatedChunks() const { return AllocatedChunks; }
+
+ private:
void CollectRemovedHugeBlobs(const TVector<TDiskPart> &hugeBlobs) {
- for (const TDiskPart& p : hugeBlobs) {
- if (!p.Empty()) {
- FreedHugeBlobs.PushBack(p);
- }
- }
- }
-
- // start item processing; this function transforms item using handoff map and adds collected huge blobs, if any
- // it returns true if we should keep this item; otherwise it returns false
- bool PreprocessItem(const TActorContext& ctx) {
- const TKey key = It.GetCurKey();
-
- // finish merging data for this item
- IndexMerger.Finish();
-
- // reset transformed item and try to create new one if we want to keep this item
- TransformedItem = nullptr;
- if (GcmpIt.KeepItem()) {
- const bool keepData = GcmpIt.KeepData();
+ for (const TDiskPart& p : hugeBlobs) {
+ if (!p.Empty()) {
+ FreedHugeBlobs.PushBack(p);
+ }
+ }
+ }
+
+ // start item processing; this function transforms item using handoff map and adds collected huge blobs, if any
+ // it returns true if we should keep this item; otherwise it returns false
+ bool PreprocessItem(const TActorContext& ctx) {
+ const TKey key = It.GetCurKey();
+
+ // finish merging data for this item
+ IndexMerger.Finish();
+
+ // reset transformed item and try to create new one if we want to keep this item
+ TransformedItem = nullptr;
+ if (GcmpIt.KeepItem()) {
+ const bool keepData = GcmpIt.KeepData();
++(keepData ? Statistics.KeepItemsWithData : Statistics.KeepItemsWOData);
- TransformedItem = Hmp->Transform(ctx, key, &IndexMerger.GetMemRec(), IndexMerger.GetDataMerger(), keepData);
- } else {
+ TransformedItem = Hmp->Transform(ctx, key, &IndexMerger.GetMemRec(), IndexMerger.GetDataMerger(), keepData);
+ } else {
++Statistics.DontKeepItems;
- }
-
- // collect huge blobs -- we unconditionally delete DeletedData and save SavedData only in case
- // when this blob is written -- that is, when TransformedItem is set.
- const TDataMerger *dataMerger = TransformedItem ? TransformedItem->DataMerger : IndexMerger.GetDataMerger();
- if (!TransformedItem) {
- CollectRemovedHugeBlobs(dataMerger->GetHugeBlobMerger().SavedData());
- }
- CollectRemovedHugeBlobs(dataMerger->GetHugeBlobMerger().DeletedData());
-
- return TransformedItem != nullptr;
- }
-
- ETryProcessItemStatus TryProcessItem() {
- // if there is no active writer, create one and start writing
- if (!WriterPtr) {
- // ensure we have enough reserved chunks to do operation; or else request for allocation and wait
+ }
+
+ // collect huge blobs -- we unconditionally delete DeletedData and save SavedData only in case
+ // when this blob is written -- that is, when TransformedItem is set.
+ const TDataMerger *dataMerger = TransformedItem ? TransformedItem->DataMerger : IndexMerger.GetDataMerger();
+ if (!TransformedItem) {
+ CollectRemovedHugeBlobs(dataMerger->GetHugeBlobMerger().SavedData());
+ }
+ CollectRemovedHugeBlobs(dataMerger->GetHugeBlobMerger().DeletedData());
+
+ return TransformedItem != nullptr;
+ }
+
+ ETryProcessItemStatus TryProcessItem() {
+ // if there is no active writer, create one and start writing
+ if (!WriterPtr) {
+ // ensure we have enough reserved chunks to do operation; or else request for allocation and wait
if (ReservedChunks.size() < ChunksToUse) {
- return ETryProcessItemStatus::NeedMoreChunks;
- }
-
- // create new instance of writer
- WriterPtr = std::make_unique<TWriter>(HullCtx->VCtx, IsFresh ? EWriterDataType::Fresh : EWriterDataType::Comp,
+ return ETryProcessItemStatus::NeedMoreChunks;
+ }
+
+ // create new instance of writer
+ WriterPtr = std::make_unique<TWriter>(HullCtx->VCtx, IsFresh ? EWriterDataType::Fresh : EWriterDataType::Comp,
ChunksToUse, PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound,
(ui32)PDiskCtx->Dsk->ChunkSize, PDiskCtx->Dsk->AppendBlockSize,
- (ui32)PDiskCtx->Dsk->BulkWriteBlockSize, LevelIndex->AllocSstId(), false, ReservedChunks, Arena);
- }
-
+ (ui32)PDiskCtx->Dsk->BulkWriteBlockSize, LevelIndex->AllocSstId(), false, ReservedChunks, Arena);
+ }
+
// if we have PartitionKey, check it is time to split partitions by PartitionKey
if (PartitionKey && !IsFirstKey && PreviousKey < *PartitionKey && TransformedItem->Key >= *PartitionKey &&
!WriterPtr->Empty()) {
return ETryProcessItemStatus::FinishSST;
}
- // special logic for fresh: we just put this item into data segment as usual, do not preallocate and then
- // write data
- if (IsFresh) {
- const bool itemWritten = WriterPtr->Push(TransformedItem->Key, *TransformedItem->MemRec,
- TransformedItem->DataMerger);
- if (itemWritten) {
- Statistics.ItemAdded();
- return ETryProcessItemStatus::Success;
- } else {
- return ETryProcessItemStatus::FinishSST;
- }
- }
-
- // calculate inplaced data size: extract TLogoBlobID from the key, calculate total blob size, then reduce
- // it to part size using layout information and finally calculate serialized blob size using number of local
- // parts stored in this record; if inplacedDataSize is zero, then we do not store any data inside SSTable,
- // otherwise we store DiskBlob and have to assemble it at data pass
- ui32 inplacedDataSize = 0;
+ // special logic for fresh: we just put this item into data segment as usual, do not preallocate and then
+ // write data
+ if (IsFresh) {
+ const bool itemWritten = WriterPtr->Push(TransformedItem->Key, *TransformedItem->MemRec,
+ TransformedItem->DataMerger);
+ if (itemWritten) {
+ Statistics.ItemAdded();
+ return ETryProcessItemStatus::Success;
+ } else {
+ return ETryProcessItemStatus::FinishSST;
+ }
+ }
+
+ // calculate inplaced data size: extract TLogoBlobID from the key, calculate total blob size, then reduce
+ // it to part size using layout information and finally calculate serialized blob size using number of local
+ // parts stored in this record; if inplacedDataSize is zero, then we do not store any data inside SSTable,
+ // otherwise we store DiskBlob and have to assemble it at data pass
+ ui32 inplacedDataSize = 0;
const NMatrix::TVectorType partsToStore = TransformedItem->MemRec->GetLocalParts(GType);
- if (TransformedItem->DataMerger->GetType() == TBlobType::DiskBlob && !partsToStore.Empty()) {
- inplacedDataSize = TDiskBlob::CalculateBlobSize(GType, TransformedItem->Key.LogoBlobID(), partsToStore);
- }
-
- // try to push item into SST; in case of failure there is not enough space to fit this item
- TDiskPart preallocatedLocation;
- if (WriterPtr->PushIndexOnly(TransformedItem->Key, *TransformedItem->MemRec, TransformedItem->DataMerger,
- inplacedDataSize, &preallocatedLocation)) {
- // count added item
+ if (TransformedItem->DataMerger->GetType() == TBlobType::DiskBlob && !partsToStore.Empty()) {
+ inplacedDataSize = TDiskBlob::CalculateBlobSize(GType, TransformedItem->Key.LogoBlobID(), partsToStore);
+ }
+
+ // try to push item into SST; in case of failure there is not enough space to fit this item
+ TDiskPart preallocatedLocation;
+ if (WriterPtr->PushIndexOnly(TransformedItem->Key, *TransformedItem->MemRec, TransformedItem->DataMerger,
+ inplacedDataSize, &preallocatedLocation)) {
+ // count added item
Statistics.ItemAdded();
-
- // if we do generate some small blob, we have to enqueue it in Deferred Items queue and then possibly
- // issue some reads
- if (inplacedDataSize != 0) {
- ui32 numReads = 0;
- auto lambda = [&](const TMemRec& memRec) {
- Y_VERIFY(memRec.GetType() == TBlobType::DiskBlob && memRec.HasData());
-
- // find out where our disk blob resides
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, nullptr);
- TDiskPart location = extr.SwearOne();
-
- // get its vector of local parts stored in that location
+
+ // if we do generate some small blob, we have to enqueue it in Deferred Items queue and then possibly
+ // issue some reads
+ if (inplacedDataSize != 0) {
+ ui32 numReads = 0;
+ auto lambda = [&](const TMemRec& memRec) {
+ Y_VERIFY(memRec.GetType() == TBlobType::DiskBlob && memRec.HasData());
+
+ // find out where our disk blob resides
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, nullptr);
+ TDiskPart location = extr.SwearOne();
+
+ // get its vector of local parts stored in that location
NMatrix::TVectorType parts = memRec.GetLocalParts(GType);
-
- // enqueue read
- ReadBatcher.AddReadItem(location.ChunkIdx, location.Offset, location.Size,
- TBatcherPayload(NextDeferredItemId, parts, It.GetCurKey().LogoBlobID(), location));
-
- ++numReads;
- };
- IndexMerger.ForEachSmallDiskBlob(std::move(lambda));
-
- // either we read something or it is already in memory
- const TDiskBlobMerger& diskBlobMerger = TransformedItem->DataMerger->GetDiskBlobMerger();
- Y_VERIFY(!diskBlobMerger.Empty() || numReads > 0, "Key# %s MemRec# %s LocalParts# %s KeepData# %s",
+
+ // enqueue read
+ ReadBatcher.AddReadItem(location.ChunkIdx, location.Offset, location.Size,
+ TBatcherPayload(NextDeferredItemId, parts, It.GetCurKey().LogoBlobID(), location));
+
+ ++numReads;
+ };
+ IndexMerger.ForEachSmallDiskBlob(std::move(lambda));
+
+ // either we read something or it is already in memory
+ const TDiskBlobMerger& diskBlobMerger = TransformedItem->DataMerger->GetDiskBlobMerger();
+ Y_VERIFY(!diskBlobMerger.Empty() || numReads > 0, "Key# %s MemRec# %s LocalParts# %s KeepData# %s",
It.GetCurKey().ToString().data(),
TransformedItem->MemRec->ToString(HullCtx->IngressCache.Get(), nullptr).data(),
TransformedItem->MemRec->GetLocalParts(GType).ToString().data(),
- GcmpIt.KeepData() ? "true" : "false");
-
- // TODO(alexvru): maybe we should get rid of copying DiskBlobMerger?
- DeferredItems.Put(NextDeferredItemId, numReads, preallocatedLocation, diskBlobMerger, partsToStore,
- It.GetCurKey().LogoBlobID());
-
- // advance deferred item identifier
- ++NextDeferredItemId;
- }
-
- // return success indicating that this item required no further processing
- return ETryProcessItemStatus::Success;
- } else {
- // return failure meaning this item should be restarted after flushing current SST
- return ETryProcessItemStatus::FinishSST;
- }
- }
-
- void FinishItem() {
- // clear merger and on-disk record list and advance both iterators synchronously
- IndexMerger.Clear();
- It.Next();
- GcmpIt.Next();
- TransformedItem = nullptr;
- }
-
- bool FlushSST(TVector<std::unique_ptr<IEventBase>>& msgsForYard) {
- // try to flush some more data; if the flush fails, it means that we have reached in flight write limit and
- // there is nothing to do here now, so we return
- const bool flushDone = WriterPtr->FlushNext(FirstLsn, LastLsn, MaxInFlightWrites - InFlightWrites);
- ProcessPendingMessages(msgsForYard);
- if (!flushDone) {
- return false;
- }
-
- // get writer conclusion and fill in entrypoint and used chunks vector
- const auto& conclusion = WriterPtr->GetConclusion();
- LevelSegments.push_back(conclusion.LevelSegment);
- CommitChunks.insert(CommitChunks.end(), conclusion.UsedChunks.begin(), conclusion.UsedChunks.end());
-
- // ensure that all writes were executed and drop writer
- Y_VERIFY(!WriterPtr->GetPendingMessage());
- WriterPtr.reset();
-
- return true;
- }
-
- void ProcessPendingMessages(TVector<std::unique_ptr<IEventBase>>& msgsForYard) {
- // ensure that we have writer
- Y_VERIFY(WriterPtr);
-
- // send new messages until we reach in flight limit
- std::unique_ptr<NPDisk::TEvChunkWrite> msg;
- while (InFlightWrites < MaxInFlightWrites && (msg = WriterPtr->GetPendingMessage())) {
- Statistics.Update(msg.get());
- msgsForYard.push_back(std::move(msg));
- ++InFlightWrites;
- AtomicIncrement(*WritesInFlight);
- }
-
- std::unique_ptr<NPDisk::TEvChunkRead> readMsg;
+ GcmpIt.KeepData() ? "true" : "false");
+
+ // TODO(alexvru): maybe we should get rid of copying DiskBlobMerger?
+ DeferredItems.Put(NextDeferredItemId, numReads, preallocatedLocation, diskBlobMerger, partsToStore,
+ It.GetCurKey().LogoBlobID());
+
+ // advance deferred item identifier
+ ++NextDeferredItemId;
+ }
+
+ // return success indicating that this item required no further processing
+ return ETryProcessItemStatus::Success;
+ } else {
+ // return failure meaning this item should be restarted after flushing current SST
+ return ETryProcessItemStatus::FinishSST;
+ }
+ }
+
+ void FinishItem() {
+ // clear merger and on-disk record list and advance both iterators synchronously
+ IndexMerger.Clear();
+ It.Next();
+ GcmpIt.Next();
+ TransformedItem = nullptr;
+ }
+
+ bool FlushSST(TVector<std::unique_ptr<IEventBase>>& msgsForYard) {
+ // try to flush some more data; if the flush fails, it means that we have reached in flight write limit and
+ // there is nothing to do here now, so we return
+ const bool flushDone = WriterPtr->FlushNext(FirstLsn, LastLsn, MaxInFlightWrites - InFlightWrites);
+ ProcessPendingMessages(msgsForYard);
+ if (!flushDone) {
+ return false;
+ }
+
+ // get writer conclusion and fill in entrypoint and used chunks vector
+ const auto& conclusion = WriterPtr->GetConclusion();
+ LevelSegments.push_back(conclusion.LevelSegment);
+ CommitChunks.insert(CommitChunks.end(), conclusion.UsedChunks.begin(), conclusion.UsedChunks.end());
+
+ // ensure that all writes were executed and drop writer
+ Y_VERIFY(!WriterPtr->GetPendingMessage());
+ WriterPtr.reset();
+
+ return true;
+ }
+
+ void ProcessPendingMessages(TVector<std::unique_ptr<IEventBase>>& msgsForYard) {
+ // ensure that we have writer
+ Y_VERIFY(WriterPtr);
+
+ // send new messages until we reach in flight limit
+ std::unique_ptr<NPDisk::TEvChunkWrite> msg;
+ while (InFlightWrites < MaxInFlightWrites && (msg = WriterPtr->GetPendingMessage())) {
+ Statistics.Update(msg.get());
+ msgsForYard.push_back(std::move(msg));
+ ++InFlightWrites;
+ AtomicIncrement(*WritesInFlight);
+ }
+
+ std::unique_ptr<NPDisk::TEvChunkRead> readMsg;
while (InFlightReads < MaxInFlightReads && (readMsg = ReadBatcher.GetPendingMessage(
PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound, NPriRead::HullComp))) {
- Statistics.Update(readMsg.get());
- msgsForYard.push_back(std::move(readMsg));
- ++InFlightReads;
- AtomicIncrement(*ReadsInFlight);
- }
- }
-
- std::unique_ptr<NPDisk::TEvChunkReserve> CheckForReservation() {
+ Statistics.Update(readMsg.get());
+ msgsForYard.push_back(std::move(readMsg));
+ ++InFlightReads;
+ AtomicIncrement(*ReadsInFlight);
+ }
+ }
+
+ std::unique_ptr<NPDisk::TEvChunkReserve> CheckForReservation() {
if (ReservedChunks.size() + ChunkReservePending >= ChunksToUse) {
- return nullptr;
- }
+ return nullptr;
+ }
const ui32 num = ChunksToUse - (ReservedChunks.size() + ChunkReservePending);
- ChunkReservePending += num;
- return std::make_unique<NPDisk::TEvChunkReserve>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound, num);
- }
- };
-
-} // NKikimr
+ ChunkReservePending += num;
+ return std::make_unique<NPDisk::TEvChunkReserve>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound, num);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h
index d08b3a04d77..1c239086f71 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hullload.h
@@ -9,30 +9,30 @@
namespace NKikimr {
- template<typename TMemRec>
- struct TSmallBlobChunkIdxExtractor {
- template<typename TIterator>
- TMaybe<TChunkIdx> ExtractChunkIdx(TIterator& /*it*/) {
- return {};
- }
- };
-
- template<>
- struct TSmallBlobChunkIdxExtractor<TMemRecLogoBlob> {
- template<typename TIterator>
- TMaybe<TChunkIdx> ExtractChunkIdx(TIterator& it) {
- if (it->MemRec.GetType() == TBlobType::DiskBlob) {
- TDiskDataExtractor extr;
- it.GetDiskData(&extr);
- const TDiskPart& part = extr.SwearOne();
- if (!part.Empty()) {
- return part.ChunkIdx;
- }
- }
- return {};
- }
- };
-
+ template<typename TMemRec>
+ struct TSmallBlobChunkIdxExtractor {
+ template<typename TIterator>
+ TMaybe<TChunkIdx> ExtractChunkIdx(TIterator& /*it*/) {
+ return {};
+ }
+ };
+
+ template<>
+ struct TSmallBlobChunkIdxExtractor<TMemRecLogoBlob> {
+ template<typename TIterator>
+ TMaybe<TChunkIdx> ExtractChunkIdx(TIterator& it) {
+ if (it->MemRec.GetType() == TBlobType::DiskBlob) {
+ TDiskDataExtractor extr;
+ it.GetDiskData(&extr);
+ const TDiskPart& part = extr.SwearOne();
+ if (!part.Empty()) {
+ return part.ChunkIdx;
+ }
+ }
+ return {};
+ }
+ };
+
////////////////////////////////////////////////////////////////////////////
// THullSegLoaded
////////////////////////////////////////////////////////////////////////////
@@ -162,25 +162,25 @@ namespace NKikimr {
// add data chunks to ChunksBuilder
typedef typename TLevelSegment::TMemIterator TMemIterator;
- TSmallBlobChunkIdxExtractor<TMemRec> chunkIdxExtr;
+ TSmallBlobChunkIdxExtractor<TMemRec> chunkIdxExtr;
TMemIterator it(LevelSegment);
it.SeekToFirst();
- bool first = true;
- TKey prevKey;
+ bool first = true;
+ TKey prevKey;
while (it.Valid()) {
- if (const TMaybe<TChunkIdx> chunkIdx = chunkIdxExtr.ExtractChunkIdx(it)) {
- Chunks.Add(*chunkIdx);
+ if (const TMaybe<TChunkIdx> chunkIdx = chunkIdxExtr.ExtractChunkIdx(it)) {
+ Chunks.Add(*chunkIdx);
}
-
- // ensure that keys are stored in strictly increasing order
- const TKey& key = it.GetCurKey();
- if (first) {
- first = false;
- } else {
- Y_VERIFY(prevKey < key && !prevKey.IsSameAs(key));
- }
- prevKey = key;
-
+
+ // ensure that keys are stored in strictly increasing order
+ const TKey& key = it.GetCurKey();
+ if (first) {
+ first = false;
+ } else {
+ Y_VERIFY(prevKey < key && !prevKey.IsSameAs(key));
+ }
+ prevKey = key;
+
it.Next();
}
Chunks.FillInVector(LevelSegment->AllChunks);
@@ -193,7 +193,7 @@ namespace NKikimr {
Y_VERIFY_DEBUG(data && size && RestToReadIndex >= size);
RestToReadIndex -= size;
- memcpy(reinterpret_cast<char *>(LevelSegment->LoadedIndex.data()) + RestToReadIndex, data, size);
+ memcpy(reinterpret_cast<char *>(LevelSegment->LoadedIndex.data()) + RestToReadIndex, data, size);
}
void AppendData(const char *data, size_t size) {
@@ -202,13 +202,13 @@ namespace NKikimr {
if (RestToReadOutbound) {
if (RestToReadOutbound >= size) {
RestToReadOutbound -= size;
- memcpy(reinterpret_cast<char *>(LevelSegment->LoadedOutbound.data()) + RestToReadOutbound, data, size);
+ memcpy(reinterpret_cast<char *>(LevelSegment->LoadedOutbound.data()) + RestToReadOutbound, data, size);
return;
} else {
size_t writeSize = RestToReadOutbound;
size_t restSize = size - writeSize;
- memcpy(reinterpret_cast<char *>(LevelSegment->LoadedOutbound.data()), data + restSize, writeSize);
+ memcpy(reinterpret_cast<char *>(LevelSegment->LoadedOutbound.data()), data + restSize, writeSize);
RestToReadOutbound = 0;
AppendIndexData(data, restSize);
@@ -219,62 +219,62 @@ namespace NKikimr {
}
void Handle(NPDisk::TEvChunkReadResult::TPtr &ev, const TActorContext &ctx) {
- auto *msg = ev->Get();
+ auto *msg = ev->Get();
TString message;
- if (msg->Status != NKikimrProto::OK) {
- TStringStream str;
- str << "{Origin# '" << Origin << "'}";
- message = str.Str();
- }
+ if (msg->Status != NKikimrProto::OK) {
+ TStringStream str;
+ str << "{Origin# '" << Origin << "'}";
+ message = str.Str();
+ }
CHECK_PDISK_RESPONSE_MSG(VCtx, ev, ctx, message);
- const TBufferWithGaps &data = msg->Data;
- LevelSegment->IndexParts.push_back({msg->ChunkIdx, msg->Offset, msg->Data.Size()});
-
+ const TBufferWithGaps &data = msg->Data;
+ LevelSegment->IndexParts.push_back({msg->ChunkIdx, msg->Offset, msg->Data.Size()});
+
if (FirstRead) {
FirstRead = false;
- // copy placeholder data, because otherwise we get unaligned access
- TIdxDiskPlaceHolder placeHolder(0);
- size_t partSize = data.Size() - sizeof(TIdxDiskPlaceHolder);
- memcpy(&placeHolder, data.DataPtr<const TIdxDiskPlaceHolder>(partSize), sizeof(TIdxDiskPlaceHolder));
-
- Y_VERIFY(placeHolder.MagicNumber == TIdxDiskPlaceHolder::Signature);
- RestToReadIndex = placeHolder.Info.IdxTotalSize;
- RestToReadOutbound = placeHolder.Info.OutboundItems * sizeof(TDiskPart);
- LevelSegment->LoadedIndex.resize(placeHolder.Info.Items);
- LevelSegment->LoadedOutbound.resize(placeHolder.Info.OutboundItems);
- LevelSegment->Info = placeHolder.Info;
- LevelSegment->AssignedSstId = placeHolder.SstId;
-
- AppendData(data.DataPtr<const char>(0, partSize), partSize);
-
- if (!placeHolder.PrevPart.Empty()) {
+ // copy placeholder data, because otherwise we get unaligned access
+ TIdxDiskPlaceHolder placeHolder(0);
+ size_t partSize = data.Size() - sizeof(TIdxDiskPlaceHolder);
+ memcpy(&placeHolder, data.DataPtr<const TIdxDiskPlaceHolder>(partSize), sizeof(TIdxDiskPlaceHolder));
+
+ Y_VERIFY(placeHolder.MagicNumber == TIdxDiskPlaceHolder::Signature);
+ RestToReadIndex = placeHolder.Info.IdxTotalSize;
+ RestToReadOutbound = placeHolder.Info.OutboundItems * sizeof(TDiskPart);
+ LevelSegment->LoadedIndex.resize(placeHolder.Info.Items);
+ LevelSegment->LoadedOutbound.resize(placeHolder.Info.OutboundItems);
+ LevelSegment->Info = placeHolder.Info;
+ LevelSegment->AssignedSstId = placeHolder.SstId;
+
+ AppendData(data.DataPtr<const char>(0, partSize), partSize);
+
+ if (!placeHolder.PrevPart.Empty()) {
ctx.Send(PDiskCtx->PDiskId, new NPDisk::TEvChunkRead(PDiskCtx->Dsk->Owner,
PDiskCtx->Dsk->OwnerRound,
- placeHolder.PrevPart.ChunkIdx,
- placeHolder.PrevPart.Offset,
- placeHolder.PrevPart.Size, NPriRead::HullLoad,
+ placeHolder.PrevPart.ChunkIdx,
+ placeHolder.PrevPart.Offset,
+ placeHolder.PrevPart.Size, NPriRead::HullLoad,
nullptr));
- Chunks.Add(placeHolder.PrevPart.ChunkIdx);
+ Chunks.Add(placeHolder.PrevPart.ChunkIdx);
} else {
Finish(ctx);
}
} else {
- TIdxDiskLinker linker;
- size_t partSize = data.Size() - sizeof(TIdxDiskLinker);
- memcpy(&linker, data.DataPtr<const TIdxDiskLinker>(partSize), sizeof(TIdxDiskLinker));
+ TIdxDiskLinker linker;
+ size_t partSize = data.Size() - sizeof(TIdxDiskLinker);
+ memcpy(&linker, data.DataPtr<const TIdxDiskLinker>(partSize), sizeof(TIdxDiskLinker));
- // TODO(alexvru, fomichev): this logic seems to work incorrectly -- data must be prepended
- AppendData(data.DataPtr<const char>(0, partSize), partSize);
+ // TODO(alexvru, fomichev): this logic seems to work incorrectly -- data must be prepended
+ AppendData(data.DataPtr<const char>(0, partSize), partSize);
- if (!linker.PrevPart.Empty()) {
+ if (!linker.PrevPart.Empty()) {
ctx.Send(PDiskCtx->PDiskId, new NPDisk::TEvChunkRead(PDiskCtx->Dsk->Owner,
PDiskCtx->Dsk->OwnerRound,
- linker.PrevPart.ChunkIdx,
- linker.PrevPart.Offset, linker.PrevPart.Size,
+ linker.PrevPart.ChunkIdx,
+ linker.PrevPart.Offset, linker.PrevPart.Size,
NPriRead::HullLoad, nullptr));
- Chunks.Add(linker.PrevPart.ChunkIdx);
+ Chunks.Add(linker.PrevPart.ChunkIdx);
} else {
Finish(ctx);
}
@@ -286,16 +286,16 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvChunkReadResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvChunkReadResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_SEGMENT_LOADER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_SEGMENT_LOADER;
}
TLevelSegmentLoader(
@@ -309,13 +309,13 @@ namespace NKikimr {
, PDiskCtx(pdiskCtx)
, LevelSegment(levelSegment)
, Recipient(recipient)
- , Origin(origin)
+ , Origin(origin)
, FirstRead(true)
, RestToReadIndex(0)
, RestToReadOutbound(0)
, Chunks()
{
- const TDiskPart& entry = levelSegment->GetEntryPoint();
+ const TDiskPart& entry = levelSegment->GetEntryPoint();
Y_VERIFY_DEBUG(!entry.Empty());
}
};
@@ -368,7 +368,7 @@ namespace NKikimr {
void Process(const TActorContext &ctx) {
if (Pos < Size) {
- std::unique_ptr<TLevelSegmentLoader> actor(new TLevelSegmentLoader(VCtx, PDiskCtx,
+ std::unique_ptr<TLevelSegmentLoader> actor(new TLevelSegmentLoader(VCtx, PDiskCtx,
Segs->Segments[Pos].Get(), ctx.SelfID, "OrderedLevelSegmentsLoader"));
NActors::TActorId aid = ctx.Register(actor.Release());
ActiveActors.Insert(aid);
@@ -396,14 +396,14 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HTemplFunc(THullSegLoaded, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HTemplFunc(THullSegLoaded, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_ORD_LEVEL_SEGMENT_LOADER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_ORD_LEVEL_SEGMENT_LOADER;
}
TOrderedLevelSegmentsLoader(
@@ -449,7 +449,7 @@ namespace NKikimr {
void Process(const TActorContext &ctx) {
if (Pos != End) {
- std::unique_ptr<TLevelSegmentLoader> actor(new TLevelSegmentLoader(VCtx, PDiskCtx, Pos->Get(), ctx.SelfID));
+ std::unique_ptr<TLevelSegmentLoader> actor(new TLevelSegmentLoader(VCtx, PDiskCtx, Pos->Get(), ctx.SelfID));
NActors::TActorId aid = ctx.Register(actor.Release());
ActiveActors.Insert(aid);
} else {
@@ -475,14 +475,14 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HTemplFunc(THullSegLoaded, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HTemplFunc(THullSegLoaded, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_UNORD_LEVEL_SEGMENT_LOADER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_UNORD_LEVEL_SEGMENT_LOADER;
}
TUnorderedLevelSegmentsLoader(
@@ -537,9 +537,9 @@ namespace NKikimr {
void Process(const TActorContext &ctx) {
if (It.Valid()) {
// Load next
- auto actor = std::make_unique<TLevelSegmentLoader>(VCtx, PDiskCtx, It.Get().SstPtr.Get(), ctx.SelfID,
- "LevelIndexLoader");
- NActors::TActorId aid = ctx.Register(actor.release());
+ auto actor = std::make_unique<TLevelSegmentLoader>(VCtx, PDiskCtx, It.Get().SstPtr.Get(), ctx.SelfID,
+ "LevelIndexLoader");
+ NActors::TActorId aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
It.Next();
} else {
@@ -567,14 +567,14 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HTemplFunc(THullSegLoaded, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HTemplFunc(THullSegLoaded, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_LOADER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_LOADER;
}
TLevelIndexLoader(
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.cpp
index bbdf962ce56..c463447d33a 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.cpp
@@ -3,79 +3,79 @@
namespace NKikimr {
- class THullCallback : public NPDisk::TEvLog::ICallback {
- const TLsnSeg Seg;
+ class THullCallback : public NPDisk::TEvLog::ICallback {
+ const TLsnSeg Seg;
TIntrusivePtr<TVDiskContext> VCtx;
const TActorId SkeletonId;
const TActorId SyncLogId;
const TActorId HugeKeeperId;
- std::unique_ptr<IEventBase> SyncLogMsg;
- std::unique_ptr<TEvHullHugeBlobLogged> HugeKeeperNotice;
+ std::unique_ptr<IEventBase> SyncLogMsg;
+ std::unique_ptr<TEvHullHugeBlobLogged> HugeKeeperNotice;
- public:
+ public:
THullCallback(TLsnSeg seg, const TIntrusivePtr<TVDiskContext> &vctx, TActorId skeletonId, TActorId syncLogId,
- TActorId hugeKeeperId, std::unique_ptr<IEventBase> syncLogMsg,
- std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice)
- : Seg(seg)
+ TActorId hugeKeeperId, std::unique_ptr<IEventBase> syncLogMsg,
+ std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice)
+ : Seg(seg)
, VCtx(vctx)
- , SkeletonId(skeletonId)
- , SyncLogId(syncLogId)
- , HugeKeeperId(hugeKeeperId)
- , SyncLogMsg(std::move(syncLogMsg))
- , HugeKeeperNotice(std::move(hugeKeeperNotice))
- {}
-
+ , SkeletonId(skeletonId)
+ , SyncLogId(syncLogId)
+ , HugeKeeperId(hugeKeeperId)
+ , SyncLogMsg(std::move(syncLogMsg))
+ , HugeKeeperNotice(std::move(hugeKeeperNotice))
+ {}
+
void operator ()(TActorSystem *actorSystem, const NPDisk::TEvLogResult &ev) override {
- // check if response is good; return on shutdown
+ // check if response is good; return on shutdown
if (!VCtx->CheckPDiskResponse(*actorSystem, ev))
- return;
-
- const bool syncLogAlso = static_cast<bool>(SyncLogMsg);
- if (syncLogAlso) {
- actorSystem->Send(SyncLogId, SyncLogMsg.release());
- }
+ return;
+
+ const bool syncLogAlso = static_cast<bool>(SyncLogMsg);
+ if (syncLogAlso) {
+ actorSystem->Send(SyncLogId, SyncLogMsg.release());
+ }
+
+ if (HugeKeeperNotice) {
+ Y_VERIFY(HugeKeeperId);
+ actorSystem->Send(HugeKeeperId, HugeKeeperNotice.release());
+ }
+ }
+ };
- if (HugeKeeperNotice) {
- Y_VERIFY(HugeKeeperId);
- actorSystem->Send(HugeKeeperId, HugeKeeperNotice.release());
- }
- }
- };
-
- std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
+ std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
TLogSignature signature,
const TString &data,
TLsnSeg seg,
void *cookie,
- std::unique_ptr<IEventBase> syncLogMsg,
- std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice)
+ std::unique_ptr<IEventBase> syncLogMsg,
+ std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice)
{
- auto callback = std::make_unique<THullCallback>(seg, hullLogCtx->VCtx, hullLogCtx->SkeletonId,
+ auto callback = std::make_unique<THullCallback>(seg, hullLogCtx->VCtx, hullLogCtx->SkeletonId,
hullLogCtx->SyncLogId, hullLogCtx->HugeKeeperId, std::move(syncLogMsg),
std::move(hugeKeeperNotice));
- return std::make_unique<NPDisk::TEvLog>(hullLogCtx->PDiskCtx->Dsk->Owner,
+ return std::make_unique<NPDisk::TEvLog>(hullLogCtx->PDiskCtx->Dsk->Owner,
hullLogCtx->PDiskCtx->Dsk->OwnerRound,
signature,
data,
seg,
cookie,
- std::move(callback));
+ std::move(callback));
}
- std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
+ std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
TLogSignature signature,
const NPDisk::TCommitRecord &commitRecord,
const TString &data,
TLsnSeg seg,
void *cookie,
- std::unique_ptr<IEventBase> syncLogMsg)
+ std::unique_ptr<IEventBase> syncLogMsg)
{
- auto callback = std::make_unique<THullCallback>(seg, hullLogCtx->VCtx, hullLogCtx->SkeletonId,
+ auto callback = std::make_unique<THullCallback>(seg, hullLogCtx->VCtx, hullLogCtx->SkeletonId,
hullLogCtx->SyncLogId, TActorId(), std::move(syncLogMsg), nullptr);
- return std::make_unique<NPDisk::TEvLog>(hullLogCtx->PDiskCtx->Dsk->Owner,
+ return std::make_unique<NPDisk::TEvLog>(hullLogCtx->PDiskCtx->Dsk->Owner,
hullLogCtx->PDiskCtx->Dsk->OwnerRound,
signature,
commitRecord,
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.h
index 6e6416b8309..b4222c7e3f6 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllog.h
@@ -4,7 +4,7 @@
namespace NKikimr {
- class TEvHullHugeBlobLogged;
+ class TEvHullHugeBlobLogged;
/////////////////////////////////////////////////////////////////////////////////////////
// These function are used for construction of NPDisk::TEvLog messages, that
@@ -12,20 +12,20 @@ namespace NKikimr {
// notifies SyncLog and Skeleton after successful commit of these records
// to recovery log
/////////////////////////////////////////////////////////////////////////////////////////
- std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
+ std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
TLogSignature signature,
const TString &data,
TLsnSeg seg,
void *cookie,
- std::unique_ptr<IEventBase> syncLogMsg,
- std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice);
+ std::unique_ptr<IEventBase> syncLogMsg,
+ std::unique_ptr<TEvHullHugeBlobLogged> hugeKeeperNotice);
- std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
+ std::unique_ptr<NPDisk::TEvLog> CreateHullUpdate(const std::shared_ptr<THullLogCtx> &hullLogCtx,
TLogSignature signature,
const NPDisk::TCommitRecord &commitRecord,
const TString &data,
TLsnSeg seg,
void *cookie,
- std::unique_ptr<IEventBase> syncLogMsg);
+ std::unique_ptr<IEventBase> syncLogMsg);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllogcutternotify.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllogcutternotify.cpp
index 4904c6b363a..a43e3c5c825 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllogcutternotify.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_hulllogcutternotify.cpp
@@ -29,13 +29,13 @@ namespace NKikimr {
"THullLogCutterNotifier: lsn# %" PRIu64 " PreviousCutLsn# %s",
lsn, PreviousCutLsnToString().data()));
- if (lsn != ui64(-1)) {
+ if (lsn != ui64(-1)) {
Y_VERIFY(!PreviousCutLsn || *PreviousCutLsn <= lsn);
if (!PreviousCutLsn || PreviousCutLsn < lsn) {
ctx.Send(LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::Hull, lsn));
PreviousCutLsn = lsn;
}
- }
+ }
}
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
@@ -43,14 +43,14 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
+ STRICT_STFUNC(StateFunc,
HFunc(TEvents::TEvCompleted, Handle);
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_LOG_CUTTER_NOTIFY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_LOG_CUTTER_NOTIFY;
}
THullLogCutterNotifier(
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch.h b/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch.h
index 50c2c1e0d42..9c7f8dc20ba 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch.h
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch.h
@@ -1,281 +1,281 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_pdiskctx.h>
-
-#include <util/generic/queue.h>
-
-namespace NKikimr {
-
- template<typename TValue>
- class TRangeSet {
- using TRange = std::pair<TValue, TValue>;
-
+
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+
+ template<typename TValue>
+ class TRangeSet {
+ using TRange = std::pair<TValue, TValue>;
+
TVector<TRange> Ranges;
- TValue Count = TValue();
-
- public:
- void Set(TValue first, TValue last) {
- Y_VERIFY_DEBUG(first <= last);
-
- auto begin = std::lower_bound(Ranges.begin(), Ranges.end(), first,
- [](const TRange& x, const TValue& y) { return x.second < y; });
-
- auto end = std::lower_bound(Ranges.begin(), Ranges.end(), last,
- [](const TRange& x, const TValue& y) { return x.second < y; });
-
- for (auto it = begin; it != end; ++it) {
- Count -= it->second - it->first;
- }
-
- if (begin != Ranges.end() && begin->first <= first) {
- Y_VERIFY_DEBUG(first <= begin->second);
- first = begin->first;
- begin->second = Max(begin->second, last);
- }
-
- if (end != Ranges.end() && end->first <= last) {
- Y_VERIFY_DEBUG(last <= end->second);
- Count -= end->second - end->first;
- end->first = Min(end->first, first);
- last = end->second;
- ++end;
- }
-
- Count += last - first;
- if (begin < end) {
- *begin++ = TRange(first, last);
- Ranges.erase(begin, end);
- } else {
- Ranges.emplace(end, first, last);
- }
- }
-
- TValue GetCount() const {
- return Count;
- }
-
- TRange GetEnclosingRange() const {
- return Ranges ? TRange(Ranges.front().first, Ranges.back().second) : TRange(0, 0);
- }
-
- template<typename TBitMap>
- void ToBitMap(TBitMap& bm) {
- TValue prev;
+ TValue Count = TValue();
+
+ public:
+ void Set(TValue first, TValue last) {
+ Y_VERIFY_DEBUG(first <= last);
+
+ auto begin = std::lower_bound(Ranges.begin(), Ranges.end(), first,
+ [](const TRange& x, const TValue& y) { return x.second < y; });
+
+ auto end = std::lower_bound(Ranges.begin(), Ranges.end(), last,
+ [](const TRange& x, const TValue& y) { return x.second < y; });
+
+ for (auto it = begin; it != end; ++it) {
+ Count -= it->second - it->first;
+ }
+
+ if (begin != Ranges.end() && begin->first <= first) {
+ Y_VERIFY_DEBUG(first <= begin->second);
+ first = begin->first;
+ begin->second = Max(begin->second, last);
+ }
+
+ if (end != Ranges.end() && end->first <= last) {
+ Y_VERIFY_DEBUG(last <= end->second);
+ Count -= end->second - end->first;
+ end->first = Min(end->first, first);
+ last = end->second;
+ ++end;
+ }
+
+ Count += last - first;
+ if (begin < end) {
+ *begin++ = TRange(first, last);
+ Ranges.erase(begin, end);
+ } else {
+ Ranges.emplace(end, first, last);
+ }
+ }
+
+ TValue GetCount() const {
+ return Count;
+ }
+
+ TRange GetEnclosingRange() const {
+ return Ranges ? TRange(Ranges.front().first, Ranges.back().second) : TRange(0, 0);
+ }
+
+ template<typename TBitMap>
+ void ToBitMap(TBitMap& bm) {
+ TValue prev;
for (size_t i = 0; i < Ranges.size(); ++i) {
- const TRange& r = Ranges[i];
- Y_VERIFY_DEBUG(i == 0 || prev < r.first);
- prev = r.second;
- bm.Set(r.first, r.second);
- }
- }
- };
-
- template<typename TPayload>
- class TCompactReadBatcher {
- struct TReadItem {
- TChunkIdx ChunkIdx;
- ui32 Offset;
- ui32 Size;
- TPayload Payload;
- ui64 Serial;
- NKikimrProto::EReplyStatus Status;
+ const TRange& r = Ranges[i];
+ Y_VERIFY_DEBUG(i == 0 || prev < r.first);
+ prev = r.second;
+ bm.Set(r.first, r.second);
+ }
+ }
+ };
+
+ template<typename TPayload>
+ class TCompactReadBatcher {
+ struct TReadItem {
+ TChunkIdx ChunkIdx;
+ ui32 Offset;
+ ui32 Size;
+ TPayload Payload;
+ ui64 Serial;
+ NKikimrProto::EReplyStatus Status;
TString Content;
- };
+ };
using TReadQueue = TDeque<TReadItem>;
- TReadQueue ReadQueue;
- ui64 NextSerial = 0;
-
- typename TReadQueue::iterator Iterator;
-
+ TReadQueue ReadQueue;
+ ui64 NextSerial = 0;
+
+ typename TReadQueue::iterator Iterator;
+
TMap<void *, std::pair<typename TReadQueue::iterator, typename TReadQueue::iterator>> ActiveRequests;
- ui64 NextRequestCookie = 1;
-
- struct TCompareReadItem {
- bool operator ()(const typename TReadQueue::iterator x, const typename TReadQueue::iterator y) const {
- return x->Serial > y->Serial;
- }
- };
+ ui64 NextRequestCookie = 1;
+
+ struct TCompareReadItem {
+ bool operator ()(const typename TReadQueue::iterator x, const typename TReadQueue::iterator y) const {
+ return x->Serial > y->Serial;
+ }
+ };
TPriorityQueue<typename TReadQueue::iterator, TVector<typename TReadQueue::iterator>, TCompareReadItem> ReadyItemQueue;
- ui64 NextReadySerial = 0;
-
- bool Started = false;
-
- const ui32 MaxReadBlockSize;
- const ui32 SeekCostInBytes;
- const double EfficiencyThreshold;
-
- public:
- TCompactReadBatcher(ui32 maxReadBlockSize, ui32 seekCostInBytes, double efficiencyThreshold)
- : MaxReadBlockSize(maxReadBlockSize)
- , SeekCostInBytes(seekCostInBytes)
- , EfficiencyThreshold(efficiencyThreshold)
- {}
-
- // enqueue read item -- a read from specific chunk at desired position and length; function returns serial
- // number of this request; all results are then reported sequently in ascending order of returned serial
- ui64 AddReadItem(TChunkIdx chunkIdx, ui32 offset, ui32 size, TPayload&& payload) {
- const ui64 serial = NextSerial++;
- ReadQueue.push_back(TReadItem{chunkIdx, offset, size, std::move(payload), serial, NKikimrProto::UNKNOWN, {}});
- return serial;
- }
-
- // start batcher operation; no AddReadItem requests allowed beyond this point
- void Start() {
- Y_VERIFY(!Started);
- Started = true;
- Iterator = ReadQueue.begin();
- }
-
- // generate new message to send to yard; batcher may generate as much messages as requested, it's job of caller
- // to control maximum number of in flight messages; return nullptr if there is nothing to read more
- std::unique_ptr<NPDisk::TEvChunkRead> GetPendingMessage(NPDisk::TOwner owner, NPDisk::TOwnerRound ownerRound,
+ ui64 NextReadySerial = 0;
+
+ bool Started = false;
+
+ const ui32 MaxReadBlockSize;
+ const ui32 SeekCostInBytes;
+ const double EfficiencyThreshold;
+
+ public:
+ TCompactReadBatcher(ui32 maxReadBlockSize, ui32 seekCostInBytes, double efficiencyThreshold)
+ : MaxReadBlockSize(maxReadBlockSize)
+ , SeekCostInBytes(seekCostInBytes)
+ , EfficiencyThreshold(efficiencyThreshold)
+ {}
+
+ // enqueue read item -- a read from specific chunk at desired position and length; function returns serial
+ // number of this request; all results are then reported sequently in ascending order of returned serial
+ ui64 AddReadItem(TChunkIdx chunkIdx, ui32 offset, ui32 size, TPayload&& payload) {
+ const ui64 serial = NextSerial++;
+ ReadQueue.push_back(TReadItem{chunkIdx, offset, size, std::move(payload), serial, NKikimrProto::UNKNOWN, {}});
+ return serial;
+ }
+
+ // start batcher operation; no AddReadItem requests allowed beyond this point
+ void Start() {
+ Y_VERIFY(!Started);
+ Started = true;
+ Iterator = ReadQueue.begin();
+ }
+
+ // generate new message to send to yard; batcher may generate as much messages as requested, it's job of caller
+ // to control maximum number of in flight messages; return nullptr if there is nothing to read more
+ std::unique_ptr<NPDisk::TEvChunkRead> GetPendingMessage(NPDisk::TOwner owner, NPDisk::TOwnerRound ownerRound,
ui8 priorityClass) {
- if (!Started || Iterator == ReadQueue.end()) {
- return nullptr;
- }
-
- // chunk for which we are batching reads
- const TChunkIdx chunkIdx = Iterator->ChunkIdx;
-
- // range set of chunk we are going to fetch
- TRangeSet<ui32> range;
-
- // vector of items we are _NOT_ going to read now
+ if (!Started || Iterator == ReadQueue.end()) {
+ return nullptr;
+ }
+
+ // chunk for which we are batching reads
+ const TChunkIdx chunkIdx = Iterator->ChunkIdx;
+
+ // range set of chunk we are going to fetch
+ TRangeSet<ui32> range;
+
+ // vector of items we are _NOT_ going to read now
TVector<TReadItem> otherItems;
-
- // iterator where we store enqueued items
- typename TReadQueue::iterator outIt = Iterator;
-
- // the range we are going to read
- std::pair<ui32, ui32> enclosingRange;
-
- // total number of bytes we are going to read
- ui32 totalBytes = 0;
-
- // current position
- typename TReadQueue::iterator it;
- for (it = Iterator; it != ReadQueue.end(); ++it) {
- if (it->ChunkIdx == chunkIdx) {
- // try to add this item to range and calculate parameters
- range.Set(it->Offset, it->Offset + it->Size);
- const std::pair<ui32, ui32> newEnclosingRange = range.GetEnclosingRange();
-
- // calculate new number of bytes we are going to read in single request; if this value exceeds
- // maximum block size, stop generating request (unless read queue is totally empty)
- const ui32 newTotalBytes = newEnclosingRange.second - newEnclosingRange.first;
- Y_VERIFY(newTotalBytes);
- if (newTotalBytes > MaxReadBlockSize && outIt != Iterator) {
- break;
- }
-
- // calculate number of effective bytes (bytes we are going to send to client) and calculate
- // request efficiency; compare with threshold and break if it is way too low
- const ui32 effectiveBytes = range.GetCount();
- double efficiency = (double)effectiveBytes / newTotalBytes;
- if (efficiency < EfficiencyThreshold) {
- // this can't be the first item -- as the efficiency for single item is 1.0
- Y_VERIFY(outIt != Iterator);
- break;
- }
-
- // calculate number of extra useless bytes we are going to read if we add this request and check
- // if it is better to seek than to read these extra bytes
- const i32 addedUselessBytes = newTotalBytes - (totalBytes + it->Size);
- if (addedUselessBytes > 0 && (ui32)addedUselessBytes > SeekCostInBytes) {
- // this can't be the first item too for the same reason as above
- Y_VERIFY(outIt != Iterator);
- break;
- }
-
- // move item in place
- *outIt++ = std::move(*it);
- enclosingRange = newEnclosingRange;
- totalBytes = newTotalBytes;
- } else {
- otherItems.push_back(std::move(*it));
- }
- }
-
- ActiveRequests.emplace(reinterpret_cast<void *>(NextRequestCookie), std::make_pair(Iterator, outIt));
-
- // create message
- const ui32 offset = enclosingRange.first;
- const ui32 size = enclosingRange.second - enclosingRange.first;
- auto msg = std::make_unique<NPDisk::TEvChunkRead>(owner, ownerRound, chunkIdx, offset, size, priorityClass,
- reinterpret_cast<void *>(NextRequestCookie));
- ++NextRequestCookie;
-
- // move stored items to their place and advance Iterator
+
+ // iterator where we store enqueued items
+ typename TReadQueue::iterator outIt = Iterator;
+
+ // the range we are going to read
+ std::pair<ui32, ui32> enclosingRange;
+
+ // total number of bytes we are going to read
+ ui32 totalBytes = 0;
+
+ // current position
+ typename TReadQueue::iterator it;
+ for (it = Iterator; it != ReadQueue.end(); ++it) {
+ if (it->ChunkIdx == chunkIdx) {
+ // try to add this item to range and calculate parameters
+ range.Set(it->Offset, it->Offset + it->Size);
+ const std::pair<ui32, ui32> newEnclosingRange = range.GetEnclosingRange();
+
+ // calculate new number of bytes we are going to read in single request; if this value exceeds
+ // maximum block size, stop generating request (unless read queue is totally empty)
+ const ui32 newTotalBytes = newEnclosingRange.second - newEnclosingRange.first;
+ Y_VERIFY(newTotalBytes);
+ if (newTotalBytes > MaxReadBlockSize && outIt != Iterator) {
+ break;
+ }
+
+ // calculate number of effective bytes (bytes we are going to send to client) and calculate
+ // request efficiency; compare with threshold and break if it is way too low
+ const ui32 effectiveBytes = range.GetCount();
+ double efficiency = (double)effectiveBytes / newTotalBytes;
+ if (efficiency < EfficiencyThreshold) {
+ // this can't be the first item -- as the efficiency for single item is 1.0
+ Y_VERIFY(outIt != Iterator);
+ break;
+ }
+
+ // calculate number of extra useless bytes we are going to read if we add this request and check
+ // if it is better to seek than to read these extra bytes
+ const i32 addedUselessBytes = newTotalBytes - (totalBytes + it->Size);
+ if (addedUselessBytes > 0 && (ui32)addedUselessBytes > SeekCostInBytes) {
+ // this can't be the first item too for the same reason as above
+ Y_VERIFY(outIt != Iterator);
+ break;
+ }
+
+ // move item in place
+ *outIt++ = std::move(*it);
+ enclosingRange = newEnclosingRange;
+ totalBytes = newTotalBytes;
+ } else {
+ otherItems.push_back(std::move(*it));
+ }
+ }
+
+ ActiveRequests.emplace(reinterpret_cast<void *>(NextRequestCookie), std::make_pair(Iterator, outIt));
+
+ // create message
+ const ui32 offset = enclosingRange.first;
+ const ui32 size = enclosingRange.second - enclosingRange.first;
+ auto msg = std::make_unique<NPDisk::TEvChunkRead>(owner, ownerRound, chunkIdx, offset, size, priorityClass,
+ reinterpret_cast<void *>(NextRequestCookie));
+ ++NextRequestCookie;
+
+ // move stored items to their place and advance Iterator
Y_VERIFY_DEBUG(it - outIt == static_cast<ssize_t>(otherItems.size()));
- Iterator = outIt;
- std::move(otherItems.begin(), otherItems.end(), Iterator);
-
- return msg;
- }
-
- // apply read result
+ Iterator = outIt;
+ std::move(otherItems.begin(), otherItems.end(), Iterator);
+
+ return msg;
+ }
+
+ // apply read result
void Apply(NPDisk::TEvChunkReadResult *msg) {
- auto& data = msg->Data;
-
- auto it = ActiveRequests.find(msg->Cookie);
- Y_VERIFY(it != ActiveRequests.end());
-
- for (auto reqIt = it->second.first; reqIt != it->second.second; ++reqIt) {
- TReadItem& item = *reqIt;
-
- item.Status = msg->Status;
- if (msg->Status == NKikimrProto::OK) {
- // ensure returned area covers this item
- Y_VERIFY(item.Offset >= msg->Offset && item.Offset + item.Size <= msg->Offset + data.Size());
-
- // calculate offset of item inside response
- const ui32 offset = item.Offset - msg->Offset;
-
- // if item is not readable at this point, we return ERROR
- if (!data.IsReadable(offset, item.Size)) {
- item.Status = NKikimrProto::ERROR;
- } else {
- item.Content = data.Substr(offset, item.Size);
- }
- }
-
- ReadyItemQueue.push(reqIt);
- }
-
- ActiveRequests.erase(it);
- }
-
- // try to get result item
+ auto& data = msg->Data;
+
+ auto it = ActiveRequests.find(msg->Cookie);
+ Y_VERIFY(it != ActiveRequests.end());
+
+ for (auto reqIt = it->second.first; reqIt != it->second.second; ++reqIt) {
+ TReadItem& item = *reqIt;
+
+ item.Status = msg->Status;
+ if (msg->Status == NKikimrProto::OK) {
+ // ensure returned area covers this item
+ Y_VERIFY(item.Offset >= msg->Offset && item.Offset + item.Size <= msg->Offset + data.Size());
+
+ // calculate offset of item inside response
+ const ui32 offset = item.Offset - msg->Offset;
+
+ // if item is not readable at this point, we return ERROR
+ if (!data.IsReadable(offset, item.Size)) {
+ item.Status = NKikimrProto::ERROR;
+ } else {
+ item.Content = data.Substr(offset, item.Size);
+ }
+ }
+
+ ReadyItemQueue.push(reqIt);
+ }
+
+ ActiveRequests.erase(it);
+ }
+
+ // try to get result item
bool GetResultItem(ui64 *serial, TPayload *payload, NKikimrProto::EReplyStatus *status, TString *content) {
- if (!ReadyItemQueue) {
- return false;
- }
-
- TReadItem& item = *ReadyItemQueue.top();
- if (item.Serial != NextReadySerial) {
- return false;
- }
- ++NextReadySerial;
-
- *serial = item.Serial;
- *payload = std::move(item.Payload);
- *status = item.Status;
- *content = std::move(item.Content);
-
- ReadyItemQueue.pop();
-
- while (ReadQueue && ReadQueue.front().Serial < NextReadySerial) {
- ReadQueue.pop_front();
- }
-
- return true;
- }
-
- void Finish() {
- Started = false;
- Y_VERIFY(NextSerial == NextReadySerial);
- }
- };
-
-} // NKikimr
+ if (!ReadyItemQueue) {
+ return false;
+ }
+
+ TReadItem& item = *ReadyItemQueue.top();
+ if (item.Serial != NextReadySerial) {
+ return false;
+ }
+ ++NextReadySerial;
+
+ *serial = item.Serial;
+ *payload = std::move(item.Payload);
+ *status = item.Status;
+ *content = std::move(item.Content);
+
+ ReadyItemQueue.pop();
+
+ while (ReadQueue && ReadQueue.front().Serial < NextReadySerial) {
+ ReadQueue.pop_front();
+ }
+
+ return true;
+ }
+
+ void Finish() {
+ Started = false;
+ Y_VERIFY(NextSerial == NextReadySerial);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch_ut.cpp b/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch_ut.cpp
index 2ec3c228f07..863952bf420 100644
--- a/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/blobstorage_readbatch_ut.cpp
@@ -1,106 +1,106 @@
-#include "blobstorage_readbatch.h"
+#include "blobstorage_readbatch.h"
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/fast.h>
-#include <util/generic/bitmap.h>
+#include <util/random/fast.h>
+#include <util/generic/bitmap.h>
#include <util/stream/null.h>
-
-using namespace NKikimr;
-
+
+using namespace NKikimr;
+
#define STR Cnull
Y_UNIT_TEST_SUITE(ReadBatcher) {
Y_UNIT_TEST(Range) {
TVector<std::pair<ui32, ui32>> ranges;
- const ui32 len = 8;
- for (ui32 start = 0; start <= len; ++start) {
- for (ui32 end = start; end <= len; ++end) {
- ranges.emplace_back(start, end);
- }
- }
+ const ui32 len = 8;
+ for (ui32 start = 0; start <= len; ++start) {
+ for (ui32 end = start; end <= len; ++end) {
+ ranges.emplace_back(start, end);
+ }
+ }
for (ui32 a = 0; a < ranges.size(); ++a) {
for (ui32 b = 0; b < ranges.size(); ++b) {
for (ui32 c = 0; c < ranges.size(); ++c) {
for (ui32 d = 0; d < ranges.size(); ++d) {
- TDynBitMap bm;
- TRangeSet<ui32> range;
- for (const auto& r : {ranges[a], ranges[b], ranges[c], ranges[d]}) {
- bm.Set(r.first, r.second);
- range.Set(r.first, r.second);
- }
- TDynBitMap ref;
- range.ToBitMap(ref);
- UNIT_ASSERT_EQUAL(ref, bm);
- UNIT_ASSERT_VALUES_EQUAL(range.GetCount(), bm.Count());
- }
- }
- }
- }
- }
-
+ TDynBitMap bm;
+ TRangeSet<ui32> range;
+ for (const auto& r : {ranges[a], ranges[b], ranges[c], ranges[d]}) {
+ bm.Set(r.first, r.second);
+ range.Set(r.first, r.second);
+ }
+ TDynBitMap ref;
+ range.ToBitMap(ref);
+ UNIT_ASSERT_EQUAL(ref, bm);
+ UNIT_ASSERT_VALUES_EQUAL(range.GetCount(), bm.Count());
+ }
+ }
+ }
+ }
+ }
+
Y_UNIT_TEST(ReadBatcher) {
- struct TPayload {
- TChunkIdx ChunkIdx;
- ui32 Offset;
- ui32 Size;
- };
-
- const ui32 chunkSize = 16 << 20;
+ struct TPayload {
+ TChunkIdx ChunkIdx;
+ ui32 Offset;
+ ui32 Size;
+ };
+
+ const ui32 chunkSize = 16 << 20;
TMap<TChunkIdx, TString> chunks;
- for (TChunkIdx chunkIdx = 1; chunkIdx <= 10; ++chunkIdx) {
+ for (TChunkIdx chunkIdx = 1; chunkIdx <= 10; ++chunkIdx) {
TString data(chunkSize, ' ');
- ui64 pattern = RandomNumber<ui64>();
- for (ui32 pos = 0; pos + sizeof(ui64) <= chunkSize; pos += sizeof(ui64)) {
+ ui64 pattern = RandomNumber<ui64>();
+ for (ui32 pos = 0; pos + sizeof(ui64) <= chunkSize; pos += sizeof(ui64)) {
*reinterpret_cast<ui64 *>(const_cast<char *>(data.data()) + pos) = pattern;
- }
- chunks.emplace(chunkIdx, data);
- }
-
- TReallyFastRng32 rng(100500);
- TCompactReadBatcher<TPayload> batcher(4 << 20, 4 << 20, 0.5);
-
- // generate requests
- const ui32 numRequests = 10000;
- for (ui32 i = 0; i < numRequests; ++i) {
- decltype(chunks)::iterator it = chunks.begin();
- std::advance(it, rng() % chunks.size());
- const ui32 offset = rng() % chunkSize;
- const ui32 len = 1 + rng() % Min<ui32>(100000, chunkSize + 1 - offset);
- TPayload payload{it->first, offset, len};
- batcher.AddReadItem(it->first, offset, len, std::move(payload));
- }
- batcher.Start();
-
- // start processing
- TVector<std::unique_ptr<NPDisk::TEvChunkRead>> pendingReads;
- ui32 expectedSerial = 0;
- for (;;) {
- ui32 action = rng() % 100;
- if (pendingReads && action < 20) {
+ }
+ chunks.emplace(chunkIdx, data);
+ }
+
+ TReallyFastRng32 rng(100500);
+ TCompactReadBatcher<TPayload> batcher(4 << 20, 4 << 20, 0.5);
+
+ // generate requests
+ const ui32 numRequests = 10000;
+ for (ui32 i = 0; i < numRequests; ++i) {
+ decltype(chunks)::iterator it = chunks.begin();
+ std::advance(it, rng() % chunks.size());
+ const ui32 offset = rng() % chunkSize;
+ const ui32 len = 1 + rng() % Min<ui32>(100000, chunkSize + 1 - offset);
+ TPayload payload{it->first, offset, len};
+ batcher.AddReadItem(it->first, offset, len, std::move(payload));
+ }
+ batcher.Start();
+
+ // start processing
+ TVector<std::unique_ptr<NPDisk::TEvChunkRead>> pendingReads;
+ ui32 expectedSerial = 0;
+ for (;;) {
+ ui32 action = rng() % 100;
+ if (pendingReads && action < 20) {
ui32 index = rng() % pendingReads.size();
- std::unique_ptr<NPDisk::TEvChunkRead> msg = std::move(pendingReads[index]);
- pendingReads.erase(pendingReads.begin() + index);
+ std::unique_ptr<NPDisk::TEvChunkRead> msg = std::move(pendingReads[index]);
+ pendingReads.erase(pendingReads.begin() + index);
NPDisk::TEvChunkReadResult result(NKikimrProto::OK, msg->ChunkIdx, msg->Offset, msg->Cookie, 0, "");
- UNIT_ASSERT(msg->Offset + msg->Size <= chunkSize);
- result.Data.SetData(chunks.at(msg->ChunkIdx).substr(msg->Offset, msg->Size));
- batcher.Apply(&result);
+ UNIT_ASSERT(msg->Offset + msg->Size <= chunkSize);
+ result.Data.SetData(chunks.at(msg->ChunkIdx).substr(msg->Offset, msg->Size));
+ batcher.Apply(&result);
} else if (auto msg = batcher.GetPendingMessage(0, 0, 0)) {
- pendingReads.push_back(std::move(msg));
- } else if (!pendingReads) {
- UNIT_ASSERT_VALUES_EQUAL(expectedSerial, numRequests);
- break;
- }
-
- ui64 serial;
- TPayload payload;
- NKikimrProto::EReplyStatus status;
+ pendingReads.push_back(std::move(msg));
+ } else if (!pendingReads) {
+ UNIT_ASSERT_VALUES_EQUAL(expectedSerial, numRequests);
+ break;
+ }
+
+ ui64 serial;
+ TPayload payload;
+ NKikimrProto::EReplyStatus status;
TString data;
- while (batcher.GetResultItem(&serial, &payload, &status, &data)) {
+ while (batcher.GetResultItem(&serial, &payload, &status, &data)) {
STR << serial << Endl;
- UNIT_ASSERT_VALUES_EQUAL(serial, expectedSerial);
- ++expectedSerial;
- UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
- UNIT_ASSERT_EQUAL(chunks.at(payload.ChunkIdx).substr(payload.Offset, payload.Size), data);
- }
- }
- }
-}
+ UNIT_ASSERT_VALUES_EQUAL(serial, expectedSerial);
+ ++expectedSerial;
+ UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::OK);
+ UNIT_ASSERT_EQUAL(chunks.at(payload.ChunkIdx).substr(payload.Offset, payload.Size), data);
+ }
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp.h b/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp.h
index 8d65c474c9b..db0e73530e6 100644
--- a/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp.h
+++ b/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp.h
@@ -14,14 +14,14 @@ namespace NKikimr {
using TAction = std::function<void (const TActorId &id, ui64 cookie, IEventBase *msg)>;
void Put(IEventBase *msg, const TActorId &recipient, ui64 recipientCookie, ui64 lsn) {
- Map.emplace(lsn, TValue {recipient, recipientCookie, std::unique_ptr<IEventBase>(msg)});
+ Map.emplace(lsn, TValue {recipient, recipientCookie, std::unique_ptr<IEventBase>(msg)});
}
void ConfirmLsn(ui64 lsn, const TAction &action) {
TMap::iterator it = Map.begin();
while (it != Map.end() && it->first <= lsn) {
TValue &v = it->second;
- action(v.Recipient, v.RecipientCookie, v.Msg.release());
+ action(v.Recipient, v.RecipientCookie, v.Msg.release());
++it;
}
// remove all traversed elements
@@ -32,7 +32,7 @@ namespace NKikimr {
struct TValue {
TActorId Recipient;
ui64 RecipientCookie;
- std::unique_ptr<IEventBase> Msg;
+ std::unique_ptr<IEventBase> Msg;
};
using TMap = std::multimap<ui64, TValue>;
diff --git a/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp_ut.cpp b/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp_ut.cpp
index f95ace015a2..fb2887df321 100644
--- a/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/hullop/hullop_delayedresp_ut.cpp
@@ -17,7 +17,7 @@ namespace NKikimr {
delete msg;
};
- auto dr = std::make_unique<TDelayedResponses>();
+ auto dr = std::make_unique<TDelayedResponses>();
dr->Put(nullptr, TActorId(), 1, 500);
dr->Put(nullptr, TActorId(), 2, 500);
dr->Put(nullptr, TActorId(), 3, 501);
diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.cpp b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.cpp
index 4e9f1f03c3a..8ad981e0a31 100644
--- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.cpp
+++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.cpp
@@ -15,7 +15,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TIngressCache -- precalculate some common parts to operate faster
////////////////////////////////////////////////////////////////////////////
- TIngressCachePtr TIngressCache::Create(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top, const TVDiskIdShort &vdisk) {
+ TIngressCachePtr TIngressCache::Create(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top, const TVDiskIdShort &vdisk) {
// vdiskOrderNum
ui32 vdiskOrderNum = top->GetOrderNumber(vdisk);
Y_VERIFY(vdiskOrderNum < MaxVDisksInGroup);
@@ -28,8 +28,8 @@ namespace NKikimr {
ui32 domainsNum = top->GetTotalFailDomainsNum();
ui32 disksInDomain = top->GetNumVDisksPerFailDomain();
- Y_VERIFY(domainsNum * disksInDomain == totalVDisks, "domainsNum# %" PRIu32 " disksInDomain# %" PRIu32
- " totalVDisks# %" PRIu32 " erasure# %s", domainsNum, disksInDomain, totalVDisks,
+ Y_VERIFY(domainsNum * disksInDomain == totalVDisks, "domainsNum# %" PRIu32 " disksInDomain# %" PRIu32
+ " totalVDisks# %" PRIu32 " erasure# %s", domainsNum, disksInDomain, totalVDisks,
TBlobStorageGroupType::ErasureName[top->GType.GetErasure()].data());
// handoff
@@ -43,12 +43,12 @@ namespace NKikimr {
ui32 barrierIngressDomainMask = (1ull << disksInDomain) - 1;
return new TIngressCache(vdiskOrderNum, totalVDisks, domainsNum, disksInDomain, handoff,
- barrierIngressValueMask, barrierIngressDomainMask, std::move(top));
+ barrierIngressValueMask, barrierIngressDomainMask, std::move(top));
}
TIngressCache::TIngressCache(ui32 vdiskOrderNum, ui32 totalVDisks, ui32 domainsNum,
ui32 disksInDomain, ui32 handoff, ui32 barrierIngressValueMask,
- ui32 barrierIngressDomainMask, std::shared_ptr<TBlobStorageGroupInfo::TTopology> topology)
+ ui32 barrierIngressDomainMask, std::shared_ptr<TBlobStorageGroupInfo::TTopology> topology)
: VDiskOrderNum(vdiskOrderNum)
, TotalVDisks(totalVDisks)
, DomainsNum(domainsNum)
@@ -56,7 +56,7 @@ namespace NKikimr {
, Handoff(handoff)
, BarrierIngressValueMask(barrierIngressValueMask)
, BarrierIngressDomainMask(barrierIngressDomainMask)
- , Topology(std::move(topology))
+ , Topology(std::move(topology))
{}
@@ -73,53 +73,53 @@ namespace NKikimr {
TShiftedMainBitVec local(dataPtr, start, (start + totalParts)); \
start += totalParts; \
ui32 handoffNum = (gtype).Handoff(); \
- Y_VERIFY_DEBUG(handoffNum <= MaxHandoffNodes); \
- const ui32 handoffVectorBits = totalParts * 2; \
- Y_VERIFY_DEBUG(start + handoffNum * handoffVectorBits <= sizeof(data) * NMatrix::BitsInByte); \
- TShiftedHandoffBitVec handoff[MaxHandoffNodes]; \
+ Y_VERIFY_DEBUG(handoffNum <= MaxHandoffNodes); \
+ const ui32 handoffVectorBits = totalParts * 2; \
+ Y_VERIFY_DEBUG(start + handoffNum * handoffVectorBits <= sizeof(data) * NMatrix::BitsInByte); \
+ TShiftedHandoffBitVec handoff[MaxHandoffNodes]; \
{ \
for (unsigned i = 0; i < handoffNum; i++) { \
handoff[i] = TShiftedHandoffBitVec(dataPtr, start, start + handoffVectorBits); \
- start += handoffVectorBits; \
- } \
- }
-
- TIngress::EMode TIngress::IngressMode(TBlobStorageGroupType gtype) {
- switch (gtype.GetErasure()) {
- case TBlobStorageGroupType::ErasureMirror3of4:
- return EMode::MIRROR3OF4;
- default:
- return EMode::GENERIC;
- }
- }
-
+ start += handoffVectorBits; \
+ } \
+ }
+
+ TIngress::EMode TIngress::IngressMode(TBlobStorageGroupType gtype) {
+ switch (gtype.GetErasure()) {
+ case TBlobStorageGroupType::ErasureMirror3of4:
+ return EMode::MIRROR3OF4;
+ default:
+ return EMode::GENERIC;
+ }
+ }
+
TIngress::TIngress(ui64 rawData) {
Data = rawData;
}
- bool TIngress::KeepUnconditionally(EMode ingressMode) const {
- return GetCollectMode(ingressMode) == CollectModeKeep;
+ bool TIngress::KeepUnconditionally(EMode ingressMode) const {
+ return GetCollectMode(ingressMode) == CollectModeKeep;
}
- void TIngress::SetKeep(EMode ingressMode, ECollectMode mode) {
- ui8& b = reinterpret_cast<ui8&>(Data);
- switch (ingressMode) {
- case EMode::GENERIC:
- Y_VERIFY_DEBUG((b >> 6) == 0);
- b |= ui8(mode) << 6;
- break;
- case EMode::MIRROR3OF4:
- Data |= static_cast<ui64>(mode) << 62;
- break;
- }
+ void TIngress::SetKeep(EMode ingressMode, ECollectMode mode) {
+ ui8& b = reinterpret_cast<ui8&>(Data);
+ switch (ingressMode) {
+ case EMode::GENERIC:
+ Y_VERIFY_DEBUG((b >> 6) == 0);
+ b |= ui8(mode) << 6;
+ break;
+ case EMode::MIRROR3OF4:
+ Data |= static_cast<ui64>(mode) << 62;
+ break;
+ }
}
- int TIngress::GetCollectMode(EMode ingressMode) const {
- switch (ingressMode) {
- case EMode::GENERIC:
- return reinterpret_cast<const ui8&>(Data) >> 6;
- case EMode::MIRROR3OF4:
- return Data >> 62;
+ int TIngress::GetCollectMode(EMode ingressMode) const {
+ switch (ingressMode) {
+ case EMode::GENERIC:
+ return reinterpret_cast<const ui8&>(Data) >> 6;
+ case EMode::MIRROR3OF4:
+ return Data >> 62;
}
}
@@ -143,81 +143,81 @@ namespace NKikimr {
return CreateIngressInternal(top->GType, nodeId, id, false); // w/o local bits
}
- TMaybe<TIngress> TIngress::CreateIngressInternal(TBlobStorageGroupType gtype,
+ TMaybe<TIngress> TIngress::CreateIngressInternal(TBlobStorageGroupType gtype,
const ui8 nodeId,
const TLogoBlobID &id,
const bool setUpLocalBits) {
- if (nodeId == gtype.BlobSubgroupSize()) {
- return Nothing();
- }
-
- switch (IngressMode(gtype)) {
- case EMode::GENERIC: {
- TIngress ingress;
- const ui8 subgroupSz = gtype.BlobSubgroupSize();
- Y_VERIFY_DEBUG(subgroupSz <= MaxNodesPerBlob);
- SETUP_VECTORS(ingress.Data, gtype);
- if (0 < id.PartId() && id.PartId() < totalParts + 1u) {
- // good
- ui8 part = id.PartId() - 1u;
-
- // setup local bits (i.e. 'we have data for this part')
- if (setUpLocalBits) {
- local.Set(part);
+ if (nodeId == gtype.BlobSubgroupSize()) {
+ return Nothing();
+ }
+
+ switch (IngressMode(gtype)) {
+ case EMode::GENERIC: {
+ TIngress ingress;
+ const ui8 subgroupSz = gtype.BlobSubgroupSize();
+ Y_VERIFY_DEBUG(subgroupSz <= MaxNodesPerBlob);
+ SETUP_VECTORS(ingress.Data, gtype);
+ if (0 < id.PartId() && id.PartId() < totalParts + 1u) {
+ // good
+ ui8 part = id.PartId() - 1u;
+
+ // setup local bits (i.e. 'we have data for this part')
+ if (setUpLocalBits) {
+ local.Set(part);
}
- // setup ingress bits (i.e. 'we know about this part')
- if (nodeId < totalParts) {
- if (nodeId != part) {
- return TMaybe<TIngress>();
- }
- main.Set(part);
- } else {
- handoff[nodeId - totalParts].Set(part);
- }
- return ingress;
+ // setup ingress bits (i.e. 'we know about this part')
+ if (nodeId < totalParts) {
+ if (nodeId != part) {
+ return TMaybe<TIngress>();
+ }
+ main.Set(part);
+ } else {
+ handoff[nodeId - totalParts].Set(part);
+ }
+ return ingress;
} else {
- // bad
- return Nothing();
+ // bad
+ return Nothing();
}
}
- case EMode::MIRROR3OF4: {
- if (id.PartId() == 0) {
- return Nothing(); // incorrect blob id
- }
- const ui8 partIdx = id.PartId() - 1;
- if (partIdx >= gtype.TotalPartCount()) {
- return Nothing(); // incorrect part id
- }
- const auto& v = NMatrix::TVectorType::MakeOneHot(partIdx, gtype.TotalPartCount());
- ui64 raw = 0;
- if (setUpLocalBits) {
- raw |= static_cast<ui64>(v.Raw()) << (62 - 8);
- }
- raw |= static_cast<ui64>(v.Raw()) << (62 - 8 - gtype.TotalPartCount() * (1 + nodeId));
- return TIngress(raw);
- }
+ case EMode::MIRROR3OF4: {
+ if (id.PartId() == 0) {
+ return Nothing(); // incorrect blob id
+ }
+ const ui8 partIdx = id.PartId() - 1;
+ if (partIdx >= gtype.TotalPartCount()) {
+ return Nothing(); // incorrect part id
+ }
+ const auto& v = NMatrix::TVectorType::MakeOneHot(partIdx, gtype.TotalPartCount());
+ ui64 raw = 0;
+ if (setUpLocalBits) {
+ raw |= static_cast<ui64>(v.Raw()) << (62 - 8);
+ }
+ raw |= static_cast<ui64>(v.Raw()) << (62 - 8 - gtype.TotalPartCount() * (1 + nodeId));
+ return TIngress(raw);
+ }
}
}
- TVectorType TIngress::PartsWeKnowAbout(TBlobStorageGroupType gtype) const {
- NMatrix::TVectorType res(0, gtype.TotalPartCount());
- for (ui8 i = 0; i < gtype.BlobSubgroupSize(); ++i) {
- res |= KnownParts(gtype, i);
+ TVectorType TIngress::PartsWeKnowAbout(TBlobStorageGroupType gtype) const {
+ NMatrix::TVectorType res(0, gtype.TotalPartCount());
+ for (ui8 i = 0; i < gtype.BlobSubgroupSize(); ++i) {
+ res |= KnownParts(gtype, i);
}
return res;
}
TVectorType TIngress::PartsWeMustHaveLocally(const TBlobStorageGroupInfo::TTopology *top,
- const TVDiskIdShort &vdisk,
- const TLogoBlobID &id) const {
- return KnownParts(top->GType, top->GetIdxInSubgroup(vdisk, id.Hash()));
+ const TVDiskIdShort &vdisk,
+ const TLogoBlobID &id) const {
+ return KnownParts(top->GType, top->GetIdxInSubgroup(vdisk, id.Hash()));
}
TIngress::TPairOfVectors TIngress::HandoffParts(const TBlobStorageGroupInfo::TTopology *top,
const TVDiskIdShort &vdisk,
const TLogoBlobID &id) const {
- Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
-
+ Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
+
// FIXME: think how we merge ingress (especially for handoff replicas) (when we delete parts)
Y_VERIFY_DEBUG(id.PartId() == 0);
SETUP_VECTORS(Data, top->GType);
@@ -238,39 +238,39 @@ namespace NKikimr {
}
}
- NMatrix::TVectorType TIngress::LocalParts(TBlobStorageGroupType gtype) const {
- switch (IngressMode(gtype)) {
- case EMode::GENERIC: {
- SETUP_VECTORS(Data, gtype);
- return local.ToVector();
- }
- case EMode::MIRROR3OF4:
- return NMatrix::TVectorType(Data >> (62 - 8), gtype.TotalPartCount());
- }
- }
-
- NMatrix::TVectorType TIngress::KnownParts(TBlobStorageGroupType gtype, ui8 nodeId) const {
- const ui8 numParts = gtype.TotalPartCount();
- Y_VERIFY_DEBUG(nodeId < gtype.BlobSubgroupSize());
- switch (IngressMode(gtype)) {
- case EMode::GENERIC: {
- SETUP_VECTORS(Data, gtype);
- if (nodeId < numParts) { // main disk
- return main.Get(nodeId)
- ? NMatrix::TVectorType::MakeOneHot(nodeId, numParts)
- : NMatrix::TVectorType(0, numParts);
- } else { // handoff disk
- return handoff[nodeId - numParts].ToVector();
- }
- }
- case EMode::MIRROR3OF4:
- // CollectMode[2] Local[numParts] Disk0[numParts] Disk1[numParts] ... Disk7[numParts]
- return NMatrix::TVectorType(Data >> (62 - 8 - numParts * (1 + nodeId)), numParts);
- }
- }
-
- TVDiskIdShort TIngress::GetMainReplica(const TBlobStorageGroupInfo::TTopology *top, const TLogoBlobID &id) {
- Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
+ NMatrix::TVectorType TIngress::LocalParts(TBlobStorageGroupType gtype) const {
+ switch (IngressMode(gtype)) {
+ case EMode::GENERIC: {
+ SETUP_VECTORS(Data, gtype);
+ return local.ToVector();
+ }
+ case EMode::MIRROR3OF4:
+ return NMatrix::TVectorType(Data >> (62 - 8), gtype.TotalPartCount());
+ }
+ }
+
+ NMatrix::TVectorType TIngress::KnownParts(TBlobStorageGroupType gtype, ui8 nodeId) const {
+ const ui8 numParts = gtype.TotalPartCount();
+ Y_VERIFY_DEBUG(nodeId < gtype.BlobSubgroupSize());
+ switch (IngressMode(gtype)) {
+ case EMode::GENERIC: {
+ SETUP_VECTORS(Data, gtype);
+ if (nodeId < numParts) { // main disk
+ return main.Get(nodeId)
+ ? NMatrix::TVectorType::MakeOneHot(nodeId, numParts)
+ : NMatrix::TVectorType(0, numParts);
+ } else { // handoff disk
+ return handoff[nodeId - numParts].ToVector();
+ }
+ }
+ case EMode::MIRROR3OF4:
+ // CollectMode[2] Local[numParts] Disk0[numParts] Disk1[numParts] ... Disk7[numParts]
+ return NMatrix::TVectorType(Data >> (62 - 8 - numParts * (1 + nodeId)), numParts);
+ }
+ }
+
+ TVDiskIdShort TIngress::GetMainReplica(const TBlobStorageGroupInfo::TTopology *top, const TLogoBlobID &id) {
+ Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
Y_VERIFY_DEBUG(id.PartId() != 0);
ui8 partId = id.PartId();
@@ -280,8 +280,8 @@ namespace NKikimr {
void TIngress::DeleteHandoff(const TBlobStorageGroupInfo::TTopology *top,
const TVDiskIdShort &vdisk,
const TLogoBlobID &id) {
- Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
-
+ Y_VERIFY(IngressMode(top->GType) == EMode::GENERIC);
+
Y_VERIFY_DEBUG(id.PartId() != 0);
SETUP_VECTORS(Data, top->GType);
@@ -298,97 +298,97 @@ namespace NKikimr {
}
// Make a copy of ingress w/o local bits
- TIngress TIngress::CopyWithoutLocal(TBlobStorageGroupType gtype) const {
- switch (IngressMode(gtype)) {
- case EMode::GENERIC: {
- TIngress res;
- res.Data = Data;
+ TIngress TIngress::CopyWithoutLocal(TBlobStorageGroupType gtype) const {
+ switch (IngressMode(gtype)) {
+ case EMode::GENERIC: {
+ TIngress res;
+ res.Data = Data;
- SETUP_VECTORS(res.Data, gtype);
- for (ui32 i = 0; i < totalParts; i++)
- local.Clear(i);
+ SETUP_VECTORS(res.Data, gtype);
+ for (ui32 i = 0; i < totalParts; i++)
+ local.Clear(i);
- return res;
- }
- case EMode::MIRROR3OF4: {
- const ui64 mask = ((static_cast<ui64>(1) << gtype.TotalPartCount()) - 1) << (62 - gtype.TotalPartCount());
- return TIngress(Data & ~mask);
- }
- }
+ return res;
+ }
+ case EMode::MIRROR3OF4: {
+ const ui64 mask = ((static_cast<ui64>(1) << gtype.TotalPartCount()) - 1) << (62 - gtype.TotalPartCount());
+ return TIngress(Data & ~mask);
+ }
+ }
}
TString TIngress::ToString(const TBlobStorageGroupInfo::TTopology *top,
const TVDiskIdShort &vdisk,
const TLogoBlobID &id) const {
- switch (IngressMode(top->GType)) {
- case EMode::GENERIC: {
- TStringStream str;
- SETUP_VECTORS(Data, top->GType);
- str << "{";
- // find nodeId, get list of vdisks/services
- ui8 nodeId = top->GetIdxInSubgroup(vdisk, id.Hash());
-
- str << "nodeId: " << ui32(nodeId);
-
- {
- str << " main: ";
- TVectorType vec = main.ToVector();
- for (ui8 i = 0; i < totalParts; i++) {
- if (i)
- str << " ";
- str << vec.Get(i);
- }
- }
- {
- for (ui8 hf = 0; hf < handoffNum; hf++) {
- str << " handoff" << ui32(hf) << ": ";
- for (ui8 i = 0; i < totalParts; i++) {
- if (i)
- str << " ";
- ui8 elem = handoff[hf].GetRaw(i);
- str << ((elem & 0x2) >> 1) << (elem & 0x1);
- }
- }
- }
- {
- str << " local: ";
- TVectorType vec = local.ToVector();
- for (ui8 i = 0; i < totalParts; i++) {
- if (i)
- str << " ";
- str << vec.Get(i);
- }
- }
- str << " " << CollectMode2String(GetCollectMode(TIngress::IngressMode(top->GType)));
- str << "}";
- return str.Str();
+ switch (IngressMode(top->GType)) {
+ case EMode::GENERIC: {
+ TStringStream str;
+ SETUP_VECTORS(Data, top->GType);
+ str << "{";
+ // find nodeId, get list of vdisks/services
+ ui8 nodeId = top->GetIdxInSubgroup(vdisk, id.Hash());
+
+ str << "nodeId: " << ui32(nodeId);
+
+ {
+ str << " main: ";
+ TVectorType vec = main.ToVector();
+ for (ui8 i = 0; i < totalParts; i++) {
+ if (i)
+ str << " ";
+ str << vec.Get(i);
+ }
+ }
+ {
+ for (ui8 hf = 0; hf < handoffNum; hf++) {
+ str << " handoff" << ui32(hf) << ": ";
+ for (ui8 i = 0; i < totalParts; i++) {
+ if (i)
+ str << " ";
+ ui8 elem = handoff[hf].GetRaw(i);
+ str << ((elem & 0x2) >> 1) << (elem & 0x1);
+ }
+ }
+ }
+ {
+ str << " local: ";
+ TVectorType vec = local.ToVector();
+ for (ui8 i = 0; i < totalParts; i++) {
+ if (i)
+ str << " ";
+ str << vec.Get(i);
+ }
+ }
+ str << " " << CollectMode2String(GetCollectMode(TIngress::IngressMode(top->GType)));
+ str << "}";
+ return str.Str();
}
- case EMode::MIRROR3OF4: {
- TStringBuilder s;
- s << "{nodeId: " << top->GetIdxInSubgroup(vdisk, id.Hash()) << " ";
- ui64 r = Data << 2;
- auto printGroup = [&](TString name) {
- s << name << ": ";
- for (unsigned i = 0; i < top->GType.TotalPartCount(); ++i, r <<= 1) {
- s << (r >> 63);
- }
- s << " ";
- };
- printGroup("local");
- for (unsigned i = 0; i < top->GType.BlobSubgroupSize(); ++i) {
- printGroup(Sprintf("node%u", i));
+ case EMode::MIRROR3OF4: {
+ TStringBuilder s;
+ s << "{nodeId: " << top->GetIdxInSubgroup(vdisk, id.Hash()) << " ";
+ ui64 r = Data << 2;
+ auto printGroup = [&](TString name) {
+ s << name << ": ";
+ for (unsigned i = 0; i < top->GType.TotalPartCount(); ++i, r <<= 1) {
+ s << (r >> 63);
+ }
+ s << " ";
+ };
+ printGroup("local");
+ for (unsigned i = 0; i < top->GType.BlobSubgroupSize(); ++i) {
+ printGroup(Sprintf("node%u", i));
}
- return s << CollectMode2String(GetCollectMode(EMode::MIRROR3OF4)) << "}";
+ return s << CollectMode2String(GetCollectMode(EMode::MIRROR3OF4)) << "}";
}
}
}
TString TIngress::PrintVDisksForLogoBlob(const TBlobStorageGroupInfo *info, const TLogoBlobID &id) {
Y_VERIFY_DEBUG(id.PartId() == 0);
- TBlobStorageGroupInfo::TVDiskIds outVDisks;
- info->PickSubgroup(id.Hash(), &outVDisks, nullptr);
+ TBlobStorageGroupInfo::TVDiskIds outVDisks;
+ info->PickSubgroup(id.Hash(), &outVDisks, nullptr);
TStringStream str;
- for (ui8 i = 0; i < outVDisks.size(); i++) {
+ for (ui8 i = 0; i < outVDisks.size(); i++) {
if (i)
str << " ";
str << outVDisks[i].ToString();
@@ -404,13 +404,13 @@ namespace NKikimr {
const TVDiskIdShort& vdisk,
const TLogoBlobID& id,
NMatrix::TVectorType recoveredParts) {
- TIngress res;
- Y_VERIFY(id.PartId() == 0);
- for (ui8 i = recoveredParts.FirstPosition(); i != recoveredParts.GetSize(); i = recoveredParts.NextPosition(i)) {
- res.Merge(*CreateIngressWithLocal(top, vdisk, TLogoBlobID(id, i + 1)));
- }
- return res;
- }
+ TIngress res;
+ Y_VERIFY(id.PartId() == 0);
+ for (ui8 i = recoveredParts.FirstPosition(); i != recoveredParts.GetSize(); i = recoveredParts.NextPosition(i)) {
+ res.Merge(*CreateIngressWithLocal(top, vdisk, TLogoBlobID(id, i + 1)));
+ }
+ return res;
+ }
////////////////////////////////////////////////////////////////////////////
// TBarrierIngress -- sync info for Barriers (garbage collection)
@@ -460,9 +460,9 @@ namespace NKikimr {
synced racks minus handoff parts.
*/
- auto& topology = *cache->Topology;
- auto synced = TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&topology, Data & cache->BarrierIngressValueMask);
- return topology.GetQuorumChecker().CheckQuorumForGroup(synced);
+ auto& topology = *cache->Topology;
+ auto synced = TBlobStorageGroupInfo::TGroupVDisks::CreateFromMask(&topology, Data & cache->BarrierIngressValueMask);
+ return topology.GetQuorumChecker().CheckQuorumForGroup(synced);
}
TString TBarrierIngress::ToString(const TIngressCache *cache) const {
@@ -515,7 +515,7 @@ namespace NKikimr {
}
void TBarrierIngress::CheckBlobStorageGroup(const TBlobStorageGroupInfo *info) {
- const ui32 num = info->GetTotalVDisksNum();
+ const ui32 num = info->GetTotalVDisksNum();
Y_VERIFY(num <= MaxVDisksInGroup, "Number of vdisks in group is too large; MaxVDisksInGroup# %" PRIu32
" actualNum# %" PRIu32, MaxVDisksInGroup, num);
}
diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h
index 05901ef275c..51a706d4be1 100644
--- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h
+++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress.h
@@ -41,9 +41,9 @@ namespace NKikimr {
const ui32 Handoff;
const ui32 BarrierIngressValueMask;
const ui32 BarrierIngressDomainMask;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
- static TIngressCachePtr Create(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ static TIngressCachePtr Create(std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TVDiskIdShort &vdisk);
private:
@@ -53,8 +53,8 @@ namespace NKikimr {
ui32 disksInDomain,
ui32 handoff,
ui32 barrierIngressValueMask,
- ui32 barrierIngressDomainMask,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> topology);
+ ui32 barrierIngressDomainMask,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> topology);
};
@@ -68,21 +68,21 @@ namespace NKikimr {
public:
typedef std::pair<NMatrix::TVectorType, NMatrix::TVectorType> TPairOfVectors;
- enum class EMode {
- GENERIC,
- MIRROR3OF4,
- };
- static EMode IngressMode(TBlobStorageGroupType gtype);
-
+ enum class EMode {
+ GENERIC,
+ MIRROR3OF4,
+ };
+ static EMode IngressMode(TBlobStorageGroupType gtype);
+
TIngress() = default;
// explicit constructor
explicit TIngress(ui64 rawData);
- bool KeepUnconditionally(EMode ingressMode) const;
- void SetKeep(EMode ingressMode, ECollectMode mode);
- int GetCollectMode(EMode ingressMode) const;
+ bool KeepUnconditionally(EMode ingressMode) const;
+ void SetKeep(EMode ingressMode, ECollectMode mode);
+ int GetCollectMode(EMode ingressMode) const;
// Returns vector of parts we have heard about, i.e. main_vec | handoff1 | ... | handoffN
- NMatrix::TVectorType PartsWeKnowAbout(TBlobStorageGroupType gtype) const;
+ NMatrix::TVectorType PartsWeKnowAbout(TBlobStorageGroupType gtype) const;
// Returns vector of parts we MUST have locally according to Ingress, i.e. parts we have
// written locally or recovered after crash
NMatrix::TVectorType PartsWeMustHaveLocally(const TBlobStorageGroupInfo::TTopology *top,
@@ -92,12 +92,12 @@ namespace NKikimr {
TPairOfVectors HandoffParts(const TBlobStorageGroupInfo::TTopology *top,
const TVDiskIdShort &vdisk,
const TLogoBlobID &id) const;
- NMatrix::TVectorType LocalParts(TBlobStorageGroupType gtype) const;
- NMatrix::TVectorType KnownParts(TBlobStorageGroupType gtype, ui8 nodeId) const;
+ NMatrix::TVectorType LocalParts(TBlobStorageGroupType gtype) const;
+ NMatrix::TVectorType KnownParts(TBlobStorageGroupType gtype, ui8 nodeId) const;
// Returns main replica for this LogoBlob with PartId != 0
static TVDiskIdShort GetMainReplica(const TBlobStorageGroupInfo::TTopology *top, const TLogoBlobID &id);
// Make a copy of ingress w/o local bits
- TIngress CopyWithoutLocal(TBlobStorageGroupType gtype) const;
+ TIngress CopyWithoutLocal(TBlobStorageGroupType gtype) const;
void DeleteHandoff(const TBlobStorageGroupInfo::TTopology *top,
const TVDiskIdShort &vdisk,
const TLogoBlobID &id);
@@ -139,10 +139,10 @@ namespace NKikimr {
const TVDiskIdShort &vdisk,
const TLogoBlobID &id);
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // mirror-3of4 support
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // mirror-3of4 support
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
private:
ui64 Data = 0;
// Data layout:
@@ -153,7 +153,7 @@ namespace NKikimr {
// create ingress from LogoBlobID id (fills in main or handoff ingress bits
// and local bits optionally)
static TMaybe<TIngress> CreateIngressInternal(
- TBlobStorageGroupType gtype,
+ TBlobStorageGroupType gtype,
const ui8 nodeId, // Ingress for _this_ node
const TLogoBlobID &id, // LogoBlobID
const bool setUpLocalBits); // Setup data also
@@ -203,7 +203,7 @@ namespace NKikimr {
// gc commands, etc.
////////////////////////////////////////////////////////////////////////////
struct TLogoBlobFilter {
- TLogoBlobFilter(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ TLogoBlobFilter(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
const TVDiskIdShort &vdisk)
: Top(top)
, VDisk(vdisk)
@@ -216,7 +216,7 @@ namespace NKikimr {
return Top->BelongsToSubgroup(VDisk, id.Hash());
}
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
const TVDiskIdShort VDisk;
};
@@ -225,10 +225,10 @@ namespace NKikimr {
bool Check(const T &) const {
return true;
}
- template <class T1, class T2>
- bool Check(const T1&, const T2&) const {
- return true;
- }
+ template <class T1, class T2>
+ bool Check(const T1&, const T2&) const {
+ return true;
+ }
template <class T1, class T2>
bool Check(const T1&, const T2&, bool) const {
return true;
diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h
index 29ef0150327..8d0f31de364 100644
--- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h
+++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_matrix.h
@@ -11,7 +11,7 @@ namespace NKikimr {
namespace NMatrix {
- static const ui32 BitsInByte = CHAR_BIT;
+ static const ui32 BitsInByte = CHAR_BIT;
/*
@@ -110,12 +110,12 @@ namespace NKikimr {
}
bool IsSupersetOf(NMatrix::TVectorType v) const {
- Y_VERIFY_DEBUG(Size == v.Size);
- return (Vec & v.Vec) == v.Vec;
- }
-
+ Y_VERIFY_DEBUG(Size == v.Size);
+ return (Vec & v.Vec) == v.Vec;
+ }
+
TVectorType &operator =(const TVectorType &v) {
- Y_VERIFY_DEBUG(Size == 0 || Size == v.Size || v.Size == 0);
+ Y_VERIFY_DEBUG(Size == 0 || Size == v.Size || v.Size == 0);
Size = v.Size;
Vec = v.Vec;
return *this;
@@ -128,11 +128,11 @@ namespace NKikimr {
}
TVectorType &operator &=(const TVectorType &v) {
- Y_VERIFY_DEBUG(Size == v.Size);
- Vec &= v.Vec;
- return *this;
- }
-
+ Y_VERIFY_DEBUG(Size == v.Size);
+ Vec &= v.Vec;
+ return *this;
+ }
+
TVectorType operator ~() const {
ui8 v = ~Vec;
return TVectorType(v, Size);
@@ -170,10 +170,10 @@ namespace NKikimr {
static TVectorType MakeOneHot(ui8 pos, ui8 size) {
TVectorType res(0, size);
- res.Set(pos);
- return res;
- }
-
+ res.Set(pos);
+ return res;
+ }
+
private:
ui8 Vec;
ui8 Size;
diff --git a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp
index 82cf659f5ac..70810bddcfe 100644
--- a/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/ingress/blobstorage_ingress_ut.cpp
@@ -13,24 +13,24 @@ namespace NKikimr {
Y_UNIT_TEST_SUITE(TBlobStorageIngress) {
Y_UNIT_TEST(Ingress) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- TVDiskID vdisk01 = TVDiskID(0, 1, 0, 0, 1);
- TVDiskID vdisk10 = TVDiskID(0, 1, 0, 1, 0);
- TVDiskID vdisk21 = TVDiskID(0, 1, 0, 2, 1);
- TVDiskID vdisk30 = TVDiskID(0, 1, 0, 3, 0);
+ TVDiskID vdisk01 = TVDiskID(0, 1, 0, 0, 1);
+ TVDiskID vdisk10 = TVDiskID(0, 1, 0, 1, 0);
+ TVDiskID vdisk21 = TVDiskID(0, 1, 0, 2, 1);
+ TVDiskID vdisk30 = TVDiskID(0, 1, 0, 3, 0);
TLogoBlobID lb1(0, 0, 0, 0, 0, 0);
// correspondings parts
- TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk10, TLogoBlobID(lb1, 1));
- TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk21, TLogoBlobID(lb1, 2));
- TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk30, TLogoBlobID(lb1, 3));
+ TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk10, TLogoBlobID(lb1, 1));
+ TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk21, TLogoBlobID(lb1, 2));
+ TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk30, TLogoBlobID(lb1, 3));
// merge
TIngress res;
TIngress::Merge(res, i1);
- TIngress::Merge(res, i2.CopyWithoutLocal(groupInfo.Type));
+ TIngress::Merge(res, i2.CopyWithoutLocal(groupInfo.Type));
TIngress::Merge(res, i3);
TVectorType vec = res.PartsWeKnowAbout(groupInfo.Type);
@@ -38,20 +38,20 @@ namespace NKikimr {
TVectorType parts(0, 3);
////
- parts = res.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk10, lb1) - res.LocalParts(groupInfo.Type);
+ parts = res.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk10, lb1) - res.LocalParts(groupInfo.Type);
UNIT_ASSERT(parts == TVectorType(0, 3));
////
- parts = res.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk21, lb1) - res.LocalParts(groupInfo.Type);
+ parts = res.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk21, lb1) - res.LocalParts(groupInfo.Type);
UNIT_ASSERT(parts == TVectorType(0x40, 3));
// hand off with data
- TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk01, TLogoBlobID(lb1, 2));
- parts = i4.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk01, lb1) - i4.LocalParts(groupInfo.Type);
+ TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk01, TLogoBlobID(lb1, 2));
+ parts = i4.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk01, lb1) - i4.LocalParts(groupInfo.Type);
UNIT_ASSERT(parts == TVectorType(0x0, 3));
// hand off without data
- TIngress i5(i4.CopyWithoutLocal(groupInfo.Type));
- parts = i5.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk01, lb1) - i5.LocalParts(groupInfo.Type);
+ TIngress i5(i4.CopyWithoutLocal(groupInfo.Type));
+ parts = i5.PartsWeMustHaveLocally(&groupInfo.GetTopology(), vdisk01, lb1) - i5.LocalParts(groupInfo.Type);
UNIT_ASSERT(parts == TVectorType(0x40, 3));
}
@@ -100,11 +100,11 @@ namespace NKikimr {
}
Y_UNIT_TEST(IngressLocalParts) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
TLogoBlobID lb1(0, 1, 0, 0, 0, 0);
- TBlobStorageGroupInfo::TVDiskIds vDisks;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
+ TBlobStorageGroupInfo::TVDiskIds vDisks;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
TVDiskID vdiskM1 = vDisks[0];
TVDiskID vdiskM2 = vDisks[1];
//TVDiskID vdiskM3 = vDisks[2];
@@ -116,7 +116,7 @@ namespace NKikimr {
// handoff
// for main disk 0
- TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM1, TLogoBlobID(lb1, 1));
+ TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM1, TLogoBlobID(lb1, 1));
{
TVectorType vec = i1.LocalParts(groupInfo.Type);
TVectorType canon(0, 3);
@@ -125,7 +125,7 @@ namespace NKikimr {
}
// for main disk 1
- TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM2, TLogoBlobID(lb1, 2));
+ TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM2, TLogoBlobID(lb1, 2));
{
TVectorType vec = i2.LocalParts(groupInfo.Type);
TVectorType canon(0, 3);
@@ -134,8 +134,8 @@ namespace NKikimr {
}
// for handoff disk
- TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 1));
- TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 3));
+ TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 1));
+ TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 3));
{
TIngress res;
TIngress::Merge(res, i3);
@@ -149,56 +149,56 @@ namespace NKikimr {
}
Y_UNIT_TEST(IngressCreateFromRepl) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8);
- TLogoBlobID id(0, 1, 0, 0, 10, 0);
- const ui8 subgroup = groupInfo.Type.BlobSubgroupSize();
- TBlobStorageGroupInfo::TVDiskIds vdisks;
- TBlobStorageGroupInfo::TServiceIds services;
- groupInfo.PickSubgroup(id.Hash(), &vdisks, &services);
- const ui8 totalParts = groupInfo.Type.TotalPartCount();
-
- for (ui32 vdisk = 0; vdisk < subgroup; ++vdisk) {
- for (ui32 mask = 1; mask < (1U << totalParts); ++mask) {
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8);
+ TLogoBlobID id(0, 1, 0, 0, 10, 0);
+ const ui8 subgroup = groupInfo.Type.BlobSubgroupSize();
+ TBlobStorageGroupInfo::TVDiskIds vdisks;
+ TBlobStorageGroupInfo::TServiceIds services;
+ groupInfo.PickSubgroup(id.Hash(), &vdisks, &services);
+ const ui8 totalParts = groupInfo.Type.TotalPartCount();
+
+ for (ui32 vdisk = 0; vdisk < subgroup; ++vdisk) {
+ for (ui32 mask = 1; mask < (1U << totalParts); ++mask) {
NMatrix::TVectorType parts(0, totalParts);
- for (ui8 i = 0; i < totalParts; ++i) {
- if (mask >> i & 1) {
- parts.Set(i);
- }
- }
-
- if (vdisk < totalParts) {
- if (parts.CountBits() > 1 || !parts.Get(vdisk)) {
- continue;
- }
- }
-
- TIngress ingress = TIngress::CreateFromRepl(&groupInfo.GetTopology(), vdisks[vdisk], id, parts);
-
- UNIT_ASSERT_EQUAL(ingress.LocalParts(groupInfo.Type), parts);
-
- if (vdisk < totalParts) {
- UNIT_ASSERT_EQUAL(ingress.KnownParts(groupInfo.Type, vdisk), parts & NMatrix::TVectorType(0x80 >> vdisk, totalParts));
- for (ui32 i = 0; i < groupInfo.Type.Handoff(); ++i) {
- UNIT_ASSERT(ingress.KnownParts(groupInfo.Type, totalParts + i).Empty());
- }
- } else {
- for (ui32 i = 0; i < totalParts; ++i) {
- UNIT_ASSERT(ingress.KnownParts(groupInfo.Type, i).Empty());
- }
- for (ui32 i = 0; i < groupInfo.Type.Handoff(); ++i) {
- UNIT_ASSERT_EQUAL(ingress.KnownParts(groupInfo.Type, totalParts + i), totalParts + i == vdisk ? parts : NMatrix::TVectorType(0, totalParts));
- }
- }
- }
- }
- }
-
+ for (ui8 i = 0; i < totalParts; ++i) {
+ if (mask >> i & 1) {
+ parts.Set(i);
+ }
+ }
+
+ if (vdisk < totalParts) {
+ if (parts.CountBits() > 1 || !parts.Get(vdisk)) {
+ continue;
+ }
+ }
+
+ TIngress ingress = TIngress::CreateFromRepl(&groupInfo.GetTopology(), vdisks[vdisk], id, parts);
+
+ UNIT_ASSERT_EQUAL(ingress.LocalParts(groupInfo.Type), parts);
+
+ if (vdisk < totalParts) {
+ UNIT_ASSERT_EQUAL(ingress.KnownParts(groupInfo.Type, vdisk), parts & NMatrix::TVectorType(0x80 >> vdisk, totalParts));
+ for (ui32 i = 0; i < groupInfo.Type.Handoff(); ++i) {
+ UNIT_ASSERT(ingress.KnownParts(groupInfo.Type, totalParts + i).Empty());
+ }
+ } else {
+ for (ui32 i = 0; i < totalParts; ++i) {
+ UNIT_ASSERT(ingress.KnownParts(groupInfo.Type, i).Empty());
+ }
+ for (ui32 i = 0; i < groupInfo.Type.Handoff(); ++i) {
+ UNIT_ASSERT_EQUAL(ingress.KnownParts(groupInfo.Type, totalParts + i), totalParts + i == vdisk ? parts : NMatrix::TVectorType(0, totalParts));
+ }
+ }
+ }
+ }
+ }
+
Y_UNIT_TEST(IngressGetMainReplica) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
TLogoBlobID lb1(0, 1, 0, 0, 0, 0);
- TBlobStorageGroupInfo::TVDiskIds vDisks;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
+ TBlobStorageGroupInfo::TVDiskIds vDisks;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
TVDiskID vdiskM1 = vDisks[0];
TVDiskID vdiskM2 = vDisks[1];
TVDiskID vdiskM3 = vDisks[2];
@@ -215,11 +215,11 @@ namespace NKikimr {
}
Y_UNIT_TEST(IngressHandoffPartsDelete) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
TLogoBlobID lb1(0, 1, 0, 0, 0, 0);
- TBlobStorageGroupInfo::TVDiskIds vDisks;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
+ TBlobStorageGroupInfo::TVDiskIds vDisks;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ groupInfo.PickSubgroup(lb1.Hash(), &vDisks, &serviceIds);
TVDiskID vdiskM1 = vDisks[0];
TVDiskID vdiskM2 = vDisks[1];
TVDiskID vdiskM3 = vDisks[2];
@@ -233,27 +233,27 @@ namespace NKikimr {
TVectorType emptyVec(0, 3);
// for main disk 0
- TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM1, TLogoBlobID(lb1, 1));
- TIngress::TPairOfVectors res1 = i1.HandoffParts(&groupInfo.GetTopology(), vdiskM1, lb1);
+ TIngress i1 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM1, TLogoBlobID(lb1, 1));
+ TIngress::TPairOfVectors res1 = i1.HandoffParts(&groupInfo.GetTopology(), vdiskM1, lb1);
UNIT_ASSERT(res1 == TIngress::TPairOfVectors(emptyVec, emptyVec));
- TIngress i1woLocal = i1.CopyWithoutLocal(groupInfo.Type);
+ TIngress i1woLocal = i1.CopyWithoutLocal(groupInfo.Type);
// for main disk 1
- TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM2, TLogoBlobID(lb1, 2));
- TIngress::TPairOfVectors res2 = i2.HandoffParts(&groupInfo.GetTopology(), vdiskM2, lb1);
+ TIngress i2 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM2, TLogoBlobID(lb1, 2));
+ TIngress::TPairOfVectors res2 = i2.HandoffParts(&groupInfo.GetTopology(), vdiskM2, lb1);
UNIT_ASSERT(res2 == TIngress::TPairOfVectors(emptyVec, emptyVec));
- TIngress i2woLocal = i2.CopyWithoutLocal(groupInfo.Type);
+ TIngress i2woLocal = i2.CopyWithoutLocal(groupInfo.Type);
// for handoff
- TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 2));
- TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 3));
+ TIngress i3 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 2));
+ TIngress i4 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 3));
TIngress i5;
i5.Merge(i1woLocal);
i5.Merge(i2woLocal);
i5.Merge(i3);
i5.Merge(i4);
- TIngress::TPairOfVectors res3 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
+ TIngress::TPairOfVectors res3 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
{
TVectorType moveVec(0, 3);
moveVec.Set(2);
@@ -262,8 +262,8 @@ namespace NKikimr {
UNIT_ASSERT(res3 == TIngress::TPairOfVectors(moveVec, delVec));
}
- i5.DeleteHandoff(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 2));
- TIngress::TPairOfVectors res4 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
+ i5.DeleteHandoff(&groupInfo.GetTopology(), vdisk00, TLogoBlobID(lb1, 2));
+ TIngress::TPairOfVectors res4 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
{
TVectorType moveVec(0, 3);
moveVec.Set(2);
@@ -272,11 +272,11 @@ namespace NKikimr {
}
// for main disk 2
- TIngress i6 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM3, TLogoBlobID(lb1, 3));
- TIngress i6woLocal = i6.CopyWithoutLocal(groupInfo.Type);
+ TIngress i6 = *TIngress::CreateIngressWithLocal(&groupInfo.GetTopology(), vdiskM3, TLogoBlobID(lb1, 3));
+ TIngress i6woLocal = i6.CopyWithoutLocal(groupInfo.Type);
i5.Merge(i6woLocal);
- TIngress::TPairOfVectors res5 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
+ TIngress::TPairOfVectors res5 = i5.HandoffParts(&groupInfo.GetTopology(), vdisk00, lb1);
{
TVectorType moveVec(0, 3);
TVectorType delVec(0, 3);
@@ -287,9 +287,9 @@ namespace NKikimr {
Y_UNIT_TEST(IngressCacheMirror3) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
- TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
+ TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
UNIT_ASSERT(cache->VDiskOrderNum == 2);
UNIT_ASSERT(cache->TotalVDisks == 8);
@@ -302,9 +302,9 @@ namespace NKikimr {
Y_UNIT_TEST(IngressCache4Plus2) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
- TVDiskID vdisk(0, 1, 0, 3 /*domain*/, 1 /*vdisk*/);
- TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
+ TVDiskID vdisk(0, 1, 0, 3 /*domain*/, 1 /*vdisk*/);
+ TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
UNIT_ASSERT(cache->VDiskOrderNum == 7);
UNIT_ASSERT(cache->TotalVDisks == 16);
@@ -316,9 +316,9 @@ namespace NKikimr {
}
Y_UNIT_TEST(BarrierIngressQuorumBasicMirror3_4_2) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
- TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
+ TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
TBarrierIngress i1(2);
TBarrierIngress i2(5);
@@ -355,9 +355,9 @@ namespace NKikimr {
Y_UNIT_TEST(BarrierIngressQuorumBasic4Plus2_8_1) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8);
- TVDiskID vdisk(0, 1, 0, 4 /*domain*/, 0 /*vdisk*/);
- TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8);
+ TVDiskID vdisk(0, 1, 0, 4 /*domain*/, 0 /*vdisk*/);
+ TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
TBarrierIngress i1(2);
TBarrierIngress i2(5);
@@ -398,36 +398,36 @@ namespace NKikimr {
Y_UNIT_TEST(BarrierIngressQuorumMirror3) {
- TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
- TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
-
- TVDiskID vdisk00 = TVDiskID(0, 1, 0, 0, 0);
- TVDiskID vdisk01 = TVDiskID(0, 1, 0, 0, 1);
- TVDiskID vdisk10 = TVDiskID(0, 1, 0, 1, 0);
- TVDiskID vdisk11 = TVDiskID(0, 1, 0, 1, 1);
- TVDiskID vdisk20 = TVDiskID(0, 1, 0, 2, 0);
- TVDiskID vdisk21 = TVDiskID(0, 1, 0, 2, 1);
- TVDiskID vdisk30 = TVDiskID(0, 1, 0, 3, 0);
- TVDiskID vdisk31 = TVDiskID(0, 1, 0, 3, 1);
-
- UNIT_ASSERT(info.GetOrderNumber(vdisk00) == 0);
- UNIT_ASSERT(info.GetOrderNumber(vdisk01) == 1);
- UNIT_ASSERT(info.GetOrderNumber(vdisk10) == 2);
- UNIT_ASSERT(info.GetOrderNumber(vdisk11) == 3);
- UNIT_ASSERT(info.GetOrderNumber(vdisk20) == 4);
- UNIT_ASSERT(info.GetOrderNumber(vdisk21) == 5);
- UNIT_ASSERT(info.GetOrderNumber(vdisk30) == 6);
- UNIT_ASSERT(info.GetOrderNumber(vdisk31) == 7);
-
- TBarrierIngress i0(info.GetOrderNumber(vdisk00));
- TBarrierIngress i1(info.GetOrderNumber(vdisk01));
- TBarrierIngress i2(info.GetOrderNumber(vdisk10));
- TBarrierIngress i3(info.GetOrderNumber(vdisk11));
- TBarrierIngress i4(info.GetOrderNumber(vdisk20));
- TBarrierIngress i5(info.GetOrderNumber(vdisk21));
- TBarrierIngress i6(info.GetOrderNumber(vdisk30));
- TBarrierIngress i7(info.GetOrderNumber(vdisk31));
+ TBlobStorageGroupInfo info(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TVDiskID vdisk(0, 1, 0, 1 /*domain*/, 0 /*vdisk*/);
+ TIngressCachePtr cache = TIngressCache::Create(info.PickTopology(), vdisk);
+
+ TVDiskID vdisk00 = TVDiskID(0, 1, 0, 0, 0);
+ TVDiskID vdisk01 = TVDiskID(0, 1, 0, 0, 1);
+ TVDiskID vdisk10 = TVDiskID(0, 1, 0, 1, 0);
+ TVDiskID vdisk11 = TVDiskID(0, 1, 0, 1, 1);
+ TVDiskID vdisk20 = TVDiskID(0, 1, 0, 2, 0);
+ TVDiskID vdisk21 = TVDiskID(0, 1, 0, 2, 1);
+ TVDiskID vdisk30 = TVDiskID(0, 1, 0, 3, 0);
+ TVDiskID vdisk31 = TVDiskID(0, 1, 0, 3, 1);
+
+ UNIT_ASSERT(info.GetOrderNumber(vdisk00) == 0);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk01) == 1);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk10) == 2);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk11) == 3);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk20) == 4);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk21) == 5);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk30) == 6);
+ UNIT_ASSERT(info.GetOrderNumber(vdisk31) == 7);
+
+ TBarrierIngress i0(info.GetOrderNumber(vdisk00));
+ TBarrierIngress i1(info.GetOrderNumber(vdisk01));
+ TBarrierIngress i2(info.GetOrderNumber(vdisk10));
+ TBarrierIngress i3(info.GetOrderNumber(vdisk11));
+ TBarrierIngress i4(info.GetOrderNumber(vdisk20));
+ TBarrierIngress i5(info.GetOrderNumber(vdisk21));
+ TBarrierIngress i6(info.GetOrderNumber(vdisk30));
+ TBarrierIngress i7(info.GetOrderNumber(vdisk31));
TBarrierIngress merged;
@@ -452,17 +452,17 @@ namespace NKikimr {
Y_UNIT_TEST(IngressPrintDistribution) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
for (ui32 i = 0; i < 3000; i++) {
TLogoBlobID lb(0, 1, i, 0, 0, 0);
- TBlobStorageGroupInfo::TVDiskIds vDisks;
- TBlobStorageGroupInfo::TServiceIds serviceIds;
- groupInfo.PickSubgroup(lb.Hash(), &vDisks, &serviceIds);
- if (vDisks[0].FailDomain == 0 && vDisks[0].VDisk == 0 &&
- vDisks[1].FailDomain == 1 && vDisks[1].VDisk == 1 &&
- vDisks[2].FailDomain == 2 && vDisks[2].VDisk == 0 &&
- vDisks[3].FailDomain == 3 && vDisks[3].VDisk == 1) {
+ TBlobStorageGroupInfo::TVDiskIds vDisks;
+ TBlobStorageGroupInfo::TServiceIds serviceIds;
+ groupInfo.PickSubgroup(lb.Hash(), &vDisks, &serviceIds);
+ if (vDisks[0].FailDomain == 0 && vDisks[0].VDisk == 0 &&
+ vDisks[1].FailDomain == 1 && vDisks[1].VDisk == 1 &&
+ vDisks[2].FailDomain == 2 && vDisks[2].VDisk == 0 &&
+ vDisks[3].FailDomain == 3 && vDisks[3].VDisk == 1) {
for (unsigned j = 0; j < 4; j++) {
auto f = [] (unsigned p) {
if (p < 3)
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_defs.h b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_defs.h
index 74149073478..37f65824c9f 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_defs.h
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_defs.h
@@ -90,7 +90,7 @@ namespace NKikimr {
ui64 LogRecPhantomBlob = 0;
ui64 LogRecAnubisOsirisPut = 0;
ui64 LogRecAddBulkSst = 0;
- ui64 LogRecScrub = 0;
+ ui64 LogRecScrub = 0;
// statistics for record dispatching
@@ -119,26 +119,26 @@ namespace NKikimr {
counter++; \
}
- DISPATCH_SIGNATURE_FUNC_GEN(LogoBlob, LogRecLogoBlob)
- DISPATCH_SIGNATURE_FUNC_GEN(Block, LogRecBlock)
- DISPATCH_SIGNATURE_FUNC_GEN(GC, LogRecGC)
- DISPATCH_SIGNATURE_FUNC_GEN(SyncLogIdx, LogRecSyncLogIdx)
- DISPATCH_SIGNATURE_FUNC_GEN(HullLogoBlobsDB, LogRecLogoBlobsDB)
- DISPATCH_SIGNATURE_FUNC_GEN(HullBlocksDB, LogRecBlocksDB)
- DISPATCH_SIGNATURE_FUNC_GEN(HullBarriersDB, LogRecBarriersDB)
- DISPATCH_SIGNATURE_FUNC_GEN(HullCutLog, LogRecCutLog)
- DISPATCH_SIGNATURE_FUNC_GEN(LocalSyncData, LogRecLocalSyncData)
- DISPATCH_SIGNATURE_FUNC_GEN(SyncerState, LogRecSyncerState)
- DISPATCH_SIGNATURE_FUNC_GEN(HandoffDelLogoBlob, LogRecHandoffDel)
- DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobAllocChunk, LogRecHugeBlobAllocChunk)
- DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobFreeChunk, LogRecHugeBlobFreeChunk)
- DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobEntryPoint, LogRecHugeBlobEntryPoint)
- DISPATCH_SIGNATURE_FUNC_GEN(HugeLogoBlob, LogRecHugeLogoBlob)
- DISPATCH_SIGNATURE_FUNC_GEN(LogoBlobOpt, LogRecLogoBlobOpt)
- DISPATCH_SIGNATURE_FUNC_GEN(PhantomBlobs, LogRecPhantomBlob)
- DISPATCH_SIGNATURE_FUNC_GEN(AnubisOsirisPut, LogRecAnubisOsirisPut)
- DISPATCH_SIGNATURE_FUNC_GEN(AddBulkSst, LogRecAddBulkSst)
- DISPATCH_SIGNATURE_FUNC_GEN(Scrub, LogRecScrub)
+ DISPATCH_SIGNATURE_FUNC_GEN(LogoBlob, LogRecLogoBlob)
+ DISPATCH_SIGNATURE_FUNC_GEN(Block, LogRecBlock)
+ DISPATCH_SIGNATURE_FUNC_GEN(GC, LogRecGC)
+ DISPATCH_SIGNATURE_FUNC_GEN(SyncLogIdx, LogRecSyncLogIdx)
+ DISPATCH_SIGNATURE_FUNC_GEN(HullLogoBlobsDB, LogRecLogoBlobsDB)
+ DISPATCH_SIGNATURE_FUNC_GEN(HullBlocksDB, LogRecBlocksDB)
+ DISPATCH_SIGNATURE_FUNC_GEN(HullBarriersDB, LogRecBarriersDB)
+ DISPATCH_SIGNATURE_FUNC_GEN(HullCutLog, LogRecCutLog)
+ DISPATCH_SIGNATURE_FUNC_GEN(LocalSyncData, LogRecLocalSyncData)
+ DISPATCH_SIGNATURE_FUNC_GEN(SyncerState, LogRecSyncerState)
+ DISPATCH_SIGNATURE_FUNC_GEN(HandoffDelLogoBlob, LogRecHandoffDel)
+ DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobAllocChunk, LogRecHugeBlobAllocChunk)
+ DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobFreeChunk, LogRecHugeBlobFreeChunk)
+ DISPATCH_SIGNATURE_FUNC_GEN(HugeBlobEntryPoint, LogRecHugeBlobEntryPoint)
+ DISPATCH_SIGNATURE_FUNC_GEN(HugeLogoBlob, LogRecHugeLogoBlob)
+ DISPATCH_SIGNATURE_FUNC_GEN(LogoBlobOpt, LogRecLogoBlobOpt)
+ DISPATCH_SIGNATURE_FUNC_GEN(PhantomBlobs, LogRecPhantomBlob)
+ DISPATCH_SIGNATURE_FUNC_GEN(AnubisOsirisPut, LogRecAnubisOsirisPut)
+ DISPATCH_SIGNATURE_FUNC_GEN(AddBulkSst, LogRecAddBulkSst)
+ DISPATCH_SIGNATURE_FUNC_GEN(Scrub, LogRecScrub)
///////////////////////////////////////////////////////////////////////////////
// Log Applied/Skipped items
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.cpp b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.cpp
index b9f9460b402..8723507f7dc 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.cpp
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.cpp
@@ -56,10 +56,10 @@ namespace NKikimr {
};
const TActorId ParentId;
- std::shared_ptr<TLocalRecoveryContext> LocRecCtx;
+ std::shared_ptr<TLocalRecoveryContext> LocRecCtx;
TActiveActors ActiveActors;
NPDisk::TLogPosition PrevLogPos = {0, 0};
- std::unique_ptr<TReadLogResultCtx> ReadLogCtx;
+ std::unique_ptr<TReadLogResultCtx> ReadLogCtx;
ui64 RecoveredLsn = 0;
ui64 SyncLogMaxLsnStored = 0;
@@ -101,11 +101,11 @@ namespace NKikimr {
void Finish(const TActorContext &ctx, NKikimrProto::EReplyStatus status, const TString &errorReason) {
ctx.Send(ParentId, new TEvRecoveryLogReplayDone(status, errorReason, RecoveredLsn));
- Die(ctx);
+ Die(ctx);
}
void Handle(NPDisk::TEvReadLogResult::TPtr &ev, const TActorContext &ctx) {
- ReadLogCtx = std::make_unique<TReadLogResultCtx>(ev);
+ ReadLogCtx = std::make_unique<TReadLogResultCtx>(ev);
if (ReadLogCtx->Msg->Status != NKikimrProto::OK) {
Finish(ctx, ReadLogCtx->Msg->Status, "Recovery log read failed");
@@ -140,10 +140,10 @@ namespace NKikimr {
// continue reading and applying log
SendReadLogRequest(ctx, ReadLogCtx->Msg->NextPosition);
// dispatching finished
- ReadLogCtx.reset();
+ ReadLogCtx.reset();
} else {
// dispatching finished
- ReadLogCtx.reset();
+ ReadLogCtx.reset();
// end
LocRecCtx->RecovInfo->FinishDispatching();
LocRecCtx->RepairedHuge->FinishRecovery(ctx);
@@ -248,7 +248,7 @@ namespace NKikimr {
}
}
- void PutBlockToHull(const TActorContext &ctx, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
+ void PutBlockToHull(const TActorContext &ctx, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
// skip records that already in index
if (LocRecCtx->HullDbRecovery->GetHullDs()->Blocks->SkipRecord(lsn)) {
LocRecCtx->RecovInfo->FreshSkipBlock();
@@ -262,13 +262,13 @@ namespace NKikimr {
VDISKP(LocRecCtx->VCtx->VDiskLogPrefix,
"RECORD (BLOCK) ADDED: lsn# %" PRIu64 " tabletId# %" PRIu64
" gen# %" PRIu32, lsn, tabletId, gen));
- LocRecCtx->HullDbRecovery->ReplayAddBlockCmd(ctx, tabletId, gen, issuerGuid, lsn, THullDbRecovery::RECOVERY);
+ LocRecCtx->HullDbRecovery->ReplayAddBlockCmd(ctx, tabletId, gen, issuerGuid, lsn, THullDbRecovery::RECOVERY);
}
}
- void PutBlockToHullAndSyncLog(const TActorContext &ctx, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
+ void PutBlockToHullAndSyncLog(const TActorContext &ctx, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
// put block to Hull Db
- PutBlockToHull(ctx, lsn, tabletId, gen, issuerGuid);
+ PutBlockToHull(ctx, lsn, tabletId, gen, issuerGuid);
// skip records that already in synclog
if (lsn <= SyncLogMaxLsnStored) {
@@ -383,7 +383,7 @@ namespace NKikimr {
const bool fromVPutCommand = true;
const TLogoBlobID id = LogoBlobIDFromLogoBlobID(PutMsg.GetBlobID());
const TString &buf = PutMsg.GetBuffer();
- TIngress ingress = *TIngress::CreateIngressWithLocal(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk, id);
+ TIngress ingress = *TIngress::CreateIngressWithLocal(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk, id);
PutLogoBlobToHullAndSyncLog(ctx, record.Lsn, id, ingress, buf, fromVPutCommand);
return EDispatchStatus::Success;
@@ -395,7 +395,7 @@ namespace NKikimr {
return EDispatchStatus::Error;
const bool fromVPutCommand = true;
- TIngress ingress = *TIngress::CreateIngressWithLocal(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk,
+ TIngress ingress = *TIngress::CreateIngressWithLocal(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk,
PutMsgOpt.Id);
PutLogoBlobToHullAndSyncLog(ctx, record.Lsn, PutMsgOpt.Id, ingress, PutMsgOpt.Data, fromVPutCommand);
@@ -409,7 +409,7 @@ namespace NKikimr {
const ui64 tabletId = BlockMsg.GetTabletId();
const ui32 gen = BlockMsg.GetGeneration();
- PutBlockToHullAndSyncLog(ctx, record.Lsn, tabletId, gen, BlockMsg.GetIssuerGuid());
+ PutBlockToHullAndSyncLog(ctx, record.Lsn, tabletId, gen, BlockMsg.GetIssuerGuid());
return EDispatchStatus::Success;
}
@@ -428,7 +428,7 @@ namespace NKikimr {
ui64 recsNum = 0;
auto count = [&recsNum] (const void *) { recsNum++; };
NSyncLog::TFragmentReader fragment(LocalSyncDataMsg.Data);
- fragment.ForEach(count, count, count, count);
+ fragment.ForEach(count, count, count, count);
// calculate lsn
Y_VERIFY_DEBUG(recordLsn >= recsNum, "recordLsn# %" PRIu64 " recsNum# %" PRIu64,
@@ -444,7 +444,7 @@ namespace NKikimr {
};
auto blockHandler = [&] (const NSyncLog::TBlockRec *rec) {
LocRecCtx->RecovInfo->SyncDataTryPutBlock();
- PutBlockToHull(ctx, lsn, rec->TabletId, rec->Generation, 0);
+ PutBlockToHull(ctx, lsn, rec->TabletId, rec->Generation, 0);
lsn++;
};
auto barrierHandler = [&] (const NSyncLog::TBarrierRec *rec) {
@@ -454,19 +454,19 @@ namespace NKikimr {
rec->CollectStep, rec->Hard, rec->Ingress);
lsn++;
};
- auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
- LocRecCtx->RecovInfo->SyncDataTryPutBlock();
- PutBlockToHull(ctx, lsn, rec->TabletId, rec->Generation, rec->IssuerGuid);
- lsn++;
- };
+ auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
+ LocRecCtx->RecovInfo->SyncDataTryPutBlock();
+ PutBlockToHull(ctx, lsn, rec->TabletId, rec->Generation, rec->IssuerGuid);
+ lsn++;
+ };
// apply local sync data
- fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
+ fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
}
void PutLogoBlobsBatchToHull(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
+ std::shared_ptr<TFreshAppendixLogoBlobs> &&logoBlobs,
TLsnSeg seg)
{
// skip records that already in index
@@ -486,7 +486,7 @@ namespace NKikimr {
void PutBlocksBatchToHull(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBlocks> &&blocks,
+ std::shared_ptr<TFreshAppendixBlocks> &&blocks,
TLsnSeg seg)
{
// skip records that already in index
@@ -506,7 +506,7 @@ namespace NKikimr {
void PutBarriersBatchToHull(
const TActorContext &ctx,
- std::shared_ptr<TFreshAppendixBarriers> &&barriers,
+ std::shared_ptr<TFreshAppendixBarriers> &&barriers,
TLsnSeg seg)
{
// skip records that already in index
@@ -735,7 +735,7 @@ namespace NKikimr {
ui64 lsn = record.Lsn - PhantomLogoBlobs.GetLogoBlobs().size() + 1;
TIngress ingress;
- ingress.SetKeep(TIngress::IngressMode(LocRecCtx->VCtx->Top->GType), CollectModeDoNotKeep);
+ ingress.SetKeep(TIngress::IngressMode(LocRecCtx->VCtx->Top->GType), CollectModeDoNotKeep);
for (const auto& id : PhantomLogoBlobs.GetLogoBlobs()) {
LocRecCtx->RecovInfo->PhantomTryPutLogoBlob();
const bool fromVPutCommand = false;
@@ -751,7 +751,7 @@ namespace NKikimr {
}
TEvAnubisOsirisPut put(AnubisOsirisPutMsg);
- TEvAnubisOsirisPut::THullDbInsert insert = put.PrepareInsert(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk);
+ TEvAnubisOsirisPut::THullDbInsert insert = put.PrepareInsert(LocRecCtx->VCtx->Top.get(), LocRecCtx->VCtx->ShortSelfVDisk);
const bool fromVPutCommand = false;
PutLogoBlobToHullAndSyncLog(ctx, record.Lsn, insert.Id, insert.Ingress, TString(), fromVPutCommand);
return EDispatchStatus::Success;
@@ -778,10 +778,10 @@ namespace NKikimr {
// skip record for all databases
return EDispatchStatus::Success;
}
- }
+ }
- EDispatchStatus HandleScrub(const TActorContext& /*ctx*/, const NPDisk::TLogRecord& /*record*/) {
- return EDispatchStatus::Success;
+ EDispatchStatus HandleScrub(const TActorContext& /*ctx*/, const NPDisk::TLogRecord& /*record*/) {
+ return EDispatchStatus::Success;
}
void Handle(TEvBulkSstEssenceLoaded::TPtr &ev, const TActorContext &ctx) {
@@ -866,9 +866,9 @@ namespace NKikimr {
case TLogSignature::SignatureAddBulkSst:
LocRecCtx->RecovInfo->DispatchSignatureAddBulkSst(record);
return HandleAddBulkSst(ctx, record);
- case TLogSignature::SignatureScrub:
- LocRecCtx->RecovInfo->DispatchSignatureScrub(record);
- return HandleScrub(ctx, record);
+ case TLogSignature::SignatureScrub:
+ LocRecCtx->RecovInfo->DispatchSignatureScrub(record);
+ return HandleScrub(ctx, record);
case TLogSignature::Max:
break;
}
@@ -876,18 +876,18 @@ namespace NKikimr {
}
void VerifyOwnedChunks(const TActorContext& ctx) {
- TSet<TChunkIdx> chunks;
-
+ TSet<TChunkIdx> chunks;
+
// create a set of used chunks as seen from our side
- LocRecCtx->HullDbRecovery->GetOwnedChunks(chunks);
- LocRecCtx->RepairedHuge->GetOwnedChunks(chunks);
- LocRecCtx->SyncLogRecovery->GetOwnedChunks(chunks);
+ LocRecCtx->HullDbRecovery->GetOwnedChunks(chunks);
+ LocRecCtx->RepairedHuge->GetOwnedChunks(chunks);
+ LocRecCtx->SyncLogRecovery->GetOwnedChunks(chunks);
// calculate leaked and unowned chunks
TVector<TChunkIdx> leaks, misowned;
std::set_difference(LocRecCtx->ReportedOwnedChunks.begin(), LocRecCtx->ReportedOwnedChunks.end(),
- chunks.begin(), chunks.end(), std::back_inserter(leaks));
- std::set_difference(chunks.begin(), chunks.end(),
+ chunks.begin(), chunks.end(), std::back_inserter(leaks));
+ std::set_difference(chunks.begin(), chunks.end(),
LocRecCtx->ReportedOwnedChunks.begin(), LocRecCtx->ReportedOwnedChunks.end(),
std::back_inserter(misowned));
@@ -916,11 +916,11 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
}
- TRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx)
+ TRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx)
: TActorBootstrapped<TRecoveryLogReplayer>()
, ParentId(parentId)
, LocRecCtx(std::move(locRecCtx))
@@ -936,7 +936,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// CreateRecoveryLogReplayer
////////////////////////////////////////////////////////////////////////////
- IActor* CreateRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx) {
+ IActor* CreateRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx) {
return new TRecoveryLogReplayer(parentId, std::move(locRecCtx));
}
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.h b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.h
index 7f86ae3332c..0432c348a63 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.h
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_logreplay.h
@@ -33,9 +33,9 @@ namespace NKikimr {
TIntrusivePtr<THullCtx> HullCtx;
TIntrusivePtr<TLocalRecoveryInfo> RecovInfo;
- std::shared_ptr<THullDbRecovery> HullDbRecovery; // for applying recovery log
+ std::shared_ptr<THullDbRecovery> HullDbRecovery; // for applying recovery log
TIntrusivePtr<NSyncLog::TSyncLogRecovery> SyncLogRecovery;
- std::shared_ptr<NHuge::THullHugeKeeperPersState> RepairedHuge;
+ std::shared_ptr<NHuge::THullHugeKeeperPersState> RepairedHuge;
TIntrusivePtr<TSyncerData> SyncerData;
// owned chunks as reported by PDisk
@@ -65,6 +65,6 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// CreateRecoveryLogReplayer
////////////////////////////////////////////////////////////////////////////
- IActor* CreateRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx);
+ IActor* CreateRecoveryLogReplayer(TActorId parentId, std::shared_ptr<TLocalRecoveryContext> locRecCtx);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.cpp b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.cpp
index b9bdafdbb13..07ef85f4373 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.cpp
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.cpp
@@ -21,21 +21,21 @@ namespace NKikimr {
TEvBlobStorage::TEvLocalRecoveryDone::TEvLocalRecoveryDone(
NKikimrProto::EReplyStatus status,
TIntrusivePtr<TLocalRecoveryInfo> recovInfo,
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog,
- std::shared_ptr<NHuge::THullHugeKeeperPersState> repairedHuge,
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog,
+ std::shared_ptr<NHuge::THullHugeKeeperPersState> repairedHuge,
TIntrusivePtr<TSyncerData> syncerData,
- std::shared_ptr<THullDbRecovery> &&reparedHullDb,
+ std::shared_ptr<THullDbRecovery> &&reparedHullDb,
const TPDiskCtxPtr &pdiskCtx,
TIntrusivePtr<THullCtx> &hullCtx,
- std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
TIntrusivePtr<TLocalRecoveryInfo> &localRecoveryInfo,
const TIntrusivePtr<TLsnMngr> &lsnMngr,
- TVDiskIncarnationGuid vdiskIncarnationGuid,
- NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn)
+ TVDiskIncarnationGuid vdiskIncarnationGuid,
+ NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn)
: Status(status)
, RecovInfo(recovInfo)
- , RepairedSyncLog(std::move(repairedSyncLog))
+ , RepairedSyncLog(std::move(repairedSyncLog))
, RepairedHuge(std::move(repairedHuge))
, SyncerData(syncerData)
, Uncond(std::move(reparedHullDb))
@@ -45,8 +45,8 @@ namespace NKikimr {
, LocalRecoveryInfo(localRecoveryInfo)
, LsnMngr(lsnMngr)
, VDiskIncarnationGuid(vdiskIncarnationGuid)
- , ScrubEntrypoint(std::move(scrubEntrypoint))
- , ScrubEntrypointLsn(scrubEntrypointLsn)
+ , ScrubEntrypoint(std::move(scrubEntrypoint))
+ , ScrubEntrypointLsn(scrubEntrypointLsn)
{}
TEvBlobStorage::TEvLocalRecoveryDone::~TEvLocalRecoveryDone() {
@@ -62,16 +62,16 @@ namespace NKikimr {
friend class TActorBootstrapped<TDatabaseLocalRecovery>;
using TStartingPoints = TMap<TLogSignature, NPDisk::TLogRecord>;
using THullSegLoadedLogoBlob = THullSegLoaded<TLogoBlobsSst>;
-
+
TIntrusivePtr<TVDiskConfig> Config;
// generation independent self VDiskId (it is required for Yard init only)
const TVDiskID SelfVDiskId;
const TActorId SkeletonId;
- const TActorId SkeletonFrontId;
- std::shared_ptr<TLocalRecoveryContext> LocRecCtx;
- std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ const TActorId SkeletonFrontId;
+ std::shared_ptr<TLocalRecoveryContext> LocRecCtx;
+ std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
TVDiskIncarnationGuid VDiskIncarnationGuid;
- std::shared_ptr<TRopeArena> Arena;
+ std::shared_ptr<TRopeArena> Arena;
NMonGroup::TVDiskStateGroup VDiskMonGroup;
bool HullLogoBlobsDBInitialized = false;
bool HullBlocksDBInitialized = false;
@@ -81,10 +81,10 @@ namespace NKikimr {
bool HugeKeeperInitialized = false;
ui64 RecoveredLsn = 0;
ui64 SyncLogMaxLsnStored = 0;
- bool CooldownTimerHit = false;
- bool DatabaseLoaded = false;
- NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
- ui64 ScrubEntrypointLsn = 0;
+ bool CooldownTimerHit = false;
+ bool DatabaseLoaded = false;
+ NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
+ ui64 ScrubEntrypointLsn = 0;
TActiveActors ActiveActors;
@@ -116,9 +116,9 @@ namespace NKikimr {
HugeBlobCtx,
LocRecCtx->RecovInfo,
nullptr,
- VDiskIncarnationGuid,
- {},
- 0));
+ VDiskIncarnationGuid,
+ {},
+ 0));
Die(ctx);
}
@@ -149,29 +149,29 @@ namespace NKikimr {
HugeBlobCtx,
LocRecCtx->RecovInfo,
lsnMngr,
- VDiskIncarnationGuid,
- std::move(ScrubEntrypoint),
- ScrubEntrypointLsn));
+ VDiskIncarnationGuid,
+ std::move(ScrubEntrypoint),
+ ScrubEntrypointLsn));
Die(ctx);
}
- void AdjustBulkFormedSegmentsLsnRange() {
- TIntrusivePtr<TLogoBlobsDs>& logoBlobs = LocRecCtx->HullDbRecovery->GetHullDs()->LogoBlobs;
+ void AdjustBulkFormedSegmentsLsnRange() {
+ TIntrusivePtr<TLogoBlobsDs>& logoBlobs = LocRecCtx->HullDbRecovery->GetHullDs()->LogoBlobs;
TLevelSlice<TKeyLogoBlob, TMemRecLogoBlob>::TSstIterator iter(logoBlobs->CurSlice.Get(),
- logoBlobs->CurSlice->Level0CurSstsNum());
-
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ logoBlobs->CurSlice->Level0CurSstsNum());
+
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
TLogoBlobsSstPtr segment = iter.Get().SstPtr;
- if (segment->Info.IsCreatedByRepl()) {
- Y_VERIFY(segment->Info.FirstLsn == 0 && segment->Info.LastLsn == 0);
- const auto& item = logoBlobs->CurSlice->BulkFormedSegments.FindIntactBulkFormedSst(segment->GetEntryPoint());
- segment->Info.FirstLsn = item.FirstBlobLsn;
- segment->Info.LastLsn = item.LastBlobLsn;
- }
- }
- }
-
- void AfterDatabaseLoaded(const TActorContext &ctx) {
+ if (segment->Info.IsCreatedByRepl()) {
+ Y_VERIFY(segment->Info.FirstLsn == 0 && segment->Info.LastLsn == 0);
+ const auto& item = logoBlobs->CurSlice->BulkFormedSegments.FindIntactBulkFormedSst(segment->GetEntryPoint());
+ segment->Info.FirstLsn = item.FirstBlobLsn;
+ segment->Info.LastLsn = item.LastBlobLsn;
+ }
+ }
+ }
+
+ void AfterDatabaseLoaded(const TActorContext &ctx) {
// store last indexed lsn (i.e. lsn of the last record that already in DiskRecLog)
SyncLogMaxLsnStored = LocRecCtx->SyncLogRecovery->GetLastLsnOfIndexRecord();
@@ -185,25 +185,25 @@ namespace NKikimr {
// set up blocks cache
LocRecCtx->HullDbRecovery->BuildBlocksCache();
- // set up barrier cache for validator
+ // set up barrier cache for validator
LocRecCtx->HullDbRecovery->BuildBarrierCache();
-
- Become(&TThis::StateLoadBulkFormedSegments);
+
+ Become(&TThis::StateLoadBulkFormedSegments);
VDiskMonGroup.VDiskLocalRecoveryState() = TDbMon::TDbLocalRecovery::LoadBulkFormedSegments;
-
- // start loading bulk-formed segments that are already not in index, but still required to recover SyncLog
+
+ // start loading bulk-formed segments that are already not in index, but still required to recover SyncLog
auto aid = ctx.Register(LocRecCtx->HullDbRecovery->GetHullDs()->LogoBlobs->CurSlice->BulkFormedSegments.CreateLoaderActor(
LocRecCtx->VCtx, LocRecCtx->PDiskCtx, SyncLogMaxLsnStored, ctx.SelfID));
ActiveActors.Insert(aid);
- }
-
- void Handle(TEvBulkSstsLoaded::TPtr& ev, const TActorContext& ctx) {
+ }
+
+ void Handle(TEvBulkSstsLoaded::TPtr& ev, const TActorContext& ctx) {
ActiveActors.Erase(ev->Sender);
- AdjustBulkFormedSegmentsLsnRange();
- BeginApplyingLog(ctx);
- }
-
- void BeginApplyingLog(const TActorContext& ctx) {
+ AdjustBulkFormedSegmentsLsnRange();
+ BeginApplyingLog(ctx);
+ }
+
+ void BeginApplyingLog(const TActorContext& ctx) {
auto replayerId = ctx.RegisterWithSameMailbox(CreateRecoveryLogReplayer(ctx.SelfID, LocRecCtx));
ActiveActors.Insert(replayerId);
Become(&TThis::StateApplyRecoveryLog);
@@ -214,9 +214,9 @@ namespace NKikimr {
ActiveActors.Erase(ev->Sender);
auto *msg = ev->Get();
RecoveredLsn = msg->RecoveredLsn;
- if (RecoveredLsn) {
- CooldownTimerHit = true; // we do not apply cooldown timer when there are entries in the log
- }
+ if (RecoveredLsn) {
+ CooldownTimerHit = true; // we do not apply cooldown timer when there are entries in the log
+ }
if (msg->Status == NKikimrProto::OK) {
PostReplayRecoveryLog(ctx);
} else {
@@ -408,7 +408,7 @@ namespace NKikimr {
if (it == startingPoints.end()) {
LocRecCtx->RecovInfo->EmptyHuge = true;
- LocRecCtx->RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
+ LocRecCtx->RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
LocRecCtx->VCtx,
LocRecCtx->PDiskCtx->Dsk->ChunkSize,
LocRecCtx->PDiskCtx->Dsk->AppendBlockSize,
@@ -418,7 +418,7 @@ namespace NKikimr {
Config->HugeBlobOverhead,
Config->HugeBlobsFreeChunkReservation,
Config->HugeBlobOldMapCompatible,
- logFunc);
+ logFunc);
} else {
// read existing one
LocRecCtx->RecovInfo->EmptyHuge = false;
@@ -430,7 +430,7 @@ namespace NKikimr {
return false;
}
- LocRecCtx->RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
+ LocRecCtx->RepairedHuge = std::make_shared<THullHugeKeeperPersState>(
LocRecCtx->VCtx,
LocRecCtx->PDiskCtx->Dsk->ChunkSize,
LocRecCtx->PDiskCtx->Dsk->AppendBlockSize,
@@ -440,25 +440,25 @@ namespace NKikimr {
Config->HugeBlobOverhead,
Config->HugeBlobsFreeChunkReservation,
Config->HugeBlobOldMapCompatible,
- lsn, entryPoint, logFunc);
+ lsn, entryPoint, logFunc);
}
- HugeBlobCtx = std::make_shared<THugeBlobCtx>(
+ HugeBlobCtx = std::make_shared<THugeBlobCtx>(
LocRecCtx->RepairedHuge->GetMinREALHugeBlobInBytes(),
LocRecCtx->RepairedHuge->Heap->BuildHugeSlotsMap());
HugeKeeperInitialized = true;
return true;
}
- bool InitScrub(const TStartingPoints& startingPoints, const TActorContext& ctx) {
- if (const auto it = startingPoints.find(TLogSignature::SignatureScrub); it != startingPoints.end()) {
- ScrubEntrypointLsn = it->second.Lsn;
- if (!ScrubEntrypoint.ParseFromString(it->second.Data)) {
- SignalErrorAndDie(ctx, NKikimrProto::ERROR, "Entry point for Scrub actor is incorrect");
- }
- }
- return true;
- }
-
+ bool InitScrub(const TStartingPoints& startingPoints, const TActorContext& ctx) {
+ if (const auto it = startingPoints.find(TLogSignature::SignatureScrub); it != startingPoints.end()) {
+ ScrubEntrypointLsn = it->second.Lsn;
+ if (!ScrubEntrypoint.ParseFromString(it->second.Data)) {
+ SignalErrorAndDie(ctx, NKikimrProto::ERROR, "Entry point for Scrub actor is incorrect");
+ }
+ }
+ return true;
+ }
+
void Handle(NPDisk::TEvYardInitResult::TPtr &ev, const TActorContext &ctx) {
NKikimrProto::EReplyStatus status = ev->Get()->Status;
@@ -492,12 +492,12 @@ namespace NKikimr {
Config->HullCompStorageRatioCalcPeriod,
Config->HullCompStorageRatioMaxCalcDuration);
// create THullDbRecovery, which creates THullDs
- LocRecCtx->HullDbRecovery = std::make_shared<THullDbRecovery>(hullCtx);
+ LocRecCtx->HullDbRecovery = std::make_shared<THullDbRecovery>(hullCtx);
LocRecCtx->HullCtx = hullCtx;
- // store reported owned chunks
+ // store reported owned chunks
LocRecCtx->ReportedOwnedChunks = std::move(m->OwnedChunks);
-
+
// prepare starting points
const TStartingPoints &startingPoints = ev->Get()->StartingPoints;
// save starting points into info
@@ -507,22 +507,22 @@ namespace NKikimr {
"STARTING POINT: signature# %" PRIu32 " record# %s",
ui32(x.first), x.second.ToString().data()));
LocRecCtx->RecovInfo->SetStartingPoint(x.first, x.second.Lsn);
- switch (x.first) {
+ switch (x.first) {
case TLogSignature::SignatureSyncLogIdx:
case TLogSignature::SignatureHullLogoBlobsDB:
case TLogSignature::SignatureHullBlocksDB:
case TLogSignature::SignatureHullBarriersDB:
case TLogSignature::SignatureSyncerState:
case TLogSignature::SignatureHugeBlobEntryPoint:
- case TLogSignature::SignatureScrub:
- break;
-
- default:
- LOG_CRIT(ctx, BS_LOCALRECOVERY, VDISKP(LocRecCtx->VCtx->VDiskLogPrefix,
- "Unknown starting point Signature# %" PRIu32 " record# %s",
- (ui32)x.first, x.second.ToString().data()));
- break;
- }
+ case TLogSignature::SignatureScrub:
+ break;
+
+ default:
+ LOG_CRIT(ctx, BS_LOCALRECOVERY, VDISKP(LocRecCtx->VCtx->VDiskLogPrefix,
+ "Unknown starting point Signature# %" PRIu32 " record# %s",
+ (ui32)x.first, x.second.ToString().data()));
+ break;
+ }
}
// hull DB async initialization
@@ -540,52 +540,52 @@ namespace NKikimr {
return;
if (!InitHugeBlobKeeper(startingPoints, ctx))
return;
- if (!InitScrub(startingPoints, ctx))
- return;
+ if (!InitScrub(startingPoints, ctx))
+ return;
Become(&TThis::StateLoadDatabase);
if (DatabaseStateLoaded())
- AfterDatabaseLoaded(ctx);
+ AfterDatabaseLoaded(ctx);
}
}
void PostReplayRecoveryLog(const TActorContext &ctx) {
- DatabaseLoaded = true;
- if (DatabaseLoaded && CooldownTimerHit) {
- SignalSuccessAndDie(ctx);
- }
- }
-
- void HandleWakeup(const TActorContext &ctx) {
- CooldownTimerHit = true;
- if (DatabaseLoaded && CooldownTimerHit) {
- SignalSuccessAndDie(ctx);
- }
- }
-
+ DatabaseLoaded = true;
+ if (DatabaseLoaded && CooldownTimerHit) {
+ SignalSuccessAndDie(ctx);
+ }
+ }
+
+ void HandleWakeup(const TActorContext &ctx) {
+ CooldownTimerHit = true;
+ if (DatabaseLoaded && CooldownTimerHit) {
+ SignalSuccessAndDie(ctx);
+ }
+ }
+
void Bootstrap(const TActorContext &ctx) {
LOG_NOTICE(ctx, BS_LOCALRECOVERY,
VDISKP(LocRecCtx->VCtx->VDiskLogPrefix, "LocalRecovery START"));
- auto ev = std::make_unique<NPDisk::TEvYardInit>(Config->BaseInfo.InitOwnerRound, SelfVDiskId,
- Config->BaseInfo.PDiskGuid, SkeletonId, SkeletonFrontId, Config->BaseInfo.VDiskSlotId);
+ auto ev = std::make_unique<NPDisk::TEvYardInit>(Config->BaseInfo.InitOwnerRound, SelfVDiskId,
+ Config->BaseInfo.PDiskGuid, SkeletonId, SkeletonFrontId, Config->BaseInfo.VDiskSlotId);
const TActorId nodeWardenId = MakeBlobStorageNodeWardenID(SelfId().NodeId());
- auto handle = std::make_unique<IEventHandle>(Config->BaseInfo.PDiskActorID, SelfId(), ev.release(),
- IEventHandle::FlagForwardOnNondelivery, 0, &nodeWardenId);
- if (const TDuration delay = Config->BaseInfo.YardInitDelay; delay != TDuration::Zero()) {
- TActivationContext::Schedule(delay, handle.release());
- } else {
- ctx.Send(handle.release());
- }
-
+ auto handle = std::make_unique<IEventHandle>(Config->BaseInfo.PDiskActorID, SelfId(), ev.release(),
+ IEventHandle::FlagForwardOnNondelivery, 0, &nodeWardenId);
+ if (const TDuration delay = Config->BaseInfo.YardInitDelay; delay != TDuration::Zero()) {
+ TActivationContext::Schedule(delay, handle.release());
+ } else {
+ ctx.Send(handle.release());
+ }
+
LOG_DEBUG(ctx, BS_LOGCUTTER,
VDISKP(LocRecCtx->VCtx->VDiskLogPrefix,
"Sending TEvYardInit: pdiskGuid# %" PRIu64 " skeletonid# %s selfid# %s",
ui64(Config->BaseInfo.PDiskGuid), SkeletonId.ToString().data(),
ctx.SelfID.ToString().data()));
- Become(&TThis::StateInitialize, ctx, VDiskCooldownTimeout, new TEvents::TEvWakeup);
+ Become(&TThis::StateInitialize, ctx, VDiskCooldownTimeout, new TEvents::TEvWakeup);
VDiskMonGroup.VDiskLocalRecoveryState() = TDbMon::TDbLocalRecovery::YardInit;
}
@@ -606,7 +606,7 @@ namespace NKikimr {
}
if (DatabaseStateLoaded())
- AfterDatabaseLoaded(ctx);
+ AfterDatabaseLoaded(ctx);
}
void HandlePoison(const TActorContext &ctx) {
@@ -622,37 +622,37 @@ namespace NKikimr {
}
- STRICT_STFUNC(StateInitialize,
- HFunc(NPDisk::TEvYardInitResult, Handle)
- CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-
- STRICT_STFUNC(StateLoadDatabase,
- HFunc(THullIndexLoaded, Handle)
- CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-
- STRICT_STFUNC(StateLoadBulkFormedSegments,
- HFunc(TEvBulkSstsLoaded, Handle)
- CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-
- STRICT_STFUNC(StateApplyRecoveryLog,
+ STRICT_STFUNC(StateInitialize,
+ HFunc(NPDisk::TEvYardInitResult, Handle)
+ CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+
+ STRICT_STFUNC(StateLoadDatabase,
+ HFunc(THullIndexLoaded, Handle)
+ CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+
+ STRICT_STFUNC(StateLoadBulkFormedSegments,
+ HFunc(TEvBulkSstsLoaded, Handle)
+ CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+
+ STRICT_STFUNC(StateApplyRecoveryLog,
HFunc(TEvRecoveryLogReplayDone, Handle)
- CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
+ CFunc(NActors::TEvents::TSystem::PoisonPill, HandlePoison)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
}
TDatabaseLocalRecovery(
@@ -660,21 +660,21 @@ namespace NKikimr {
const TIntrusivePtr<TVDiskConfig> &config,
const TVDiskID &selfVDiskId,
const TActorId &skeletonId,
- const TActorId skeletonFrontId,
- std::shared_ptr<TRopeArena> arena)
+ const TActorId skeletonFrontId,
+ std::shared_ptr<TRopeArena> arena)
: TActorBootstrapped<TDatabaseLocalRecovery>()
, Config(config)
, SelfVDiskId(selfVDiskId)
, SkeletonId(skeletonId)
- , SkeletonFrontId(skeletonFrontId)
- , LocRecCtx(std::make_shared<TLocalRecoveryContext>(vctx))
- , Arena(std::move(arena))
+ , SkeletonFrontId(skeletonFrontId)
+ , LocRecCtx(std::make_shared<TLocalRecoveryContext>(vctx))
+ , Arena(std::move(arena))
, VDiskMonGroup(vctx->VDiskCounters, "subsystem", "state")
- {
- if (!Config->EnableVDiskCooldownTimeout || LocRecCtx->VCtx->Top->GType.BlobSubgroupSize() == 1) {
- CooldownTimerHit = true;
- }
- }
+ {
+ if (!Config->EnableVDiskCooldownTimeout || LocRecCtx->VCtx->Top->GType.BlobSubgroupSize() == 1) {
+ CooldownTimerHit = true;
+ }
+ }
};
@@ -683,9 +683,9 @@ namespace NKikimr {
const TIntrusivePtr<TVDiskConfig> &config,
const TVDiskID &selfVDiskId,
const TActorId &skeletonId,
- const TActorId skeletonFrontId,
- std::shared_ptr<TRopeArena> arena) {
- return new TDatabaseLocalRecovery(vctx, config, selfVDiskId, skeletonId, skeletonFrontId, std::move(arena));
+ const TActorId skeletonFrontId,
+ std::shared_ptr<TRopeArena> arena) {
+ return new TDatabaseLocalRecovery(vctx, config, selfVDiskId, skeletonId, skeletonFrontId, std::move(arena));
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h
index adc87c73a86..066c5263ff2 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_public.h
@@ -39,33 +39,33 @@ namespace NKikimr {
{
NKikimrProto::EReplyStatus Status;
TIntrusivePtr<TLocalRecoveryInfo> RecovInfo;
- std::unique_ptr<NSyncLog::TSyncLogRepaired> RepairedSyncLog;
- std::shared_ptr<NHuge::THullHugeKeeperPersState> RepairedHuge;
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> RepairedSyncLog;
+ std::shared_ptr<NHuge::THullHugeKeeperPersState> RepairedHuge;
TIntrusivePtr<TSyncerData> SyncerData;
- std::shared_ptr<THullDbRecovery> Uncond;
+ std::shared_ptr<THullDbRecovery> Uncond;
std::shared_ptr<TPDiskCtx> PDiskCtx;
TIntrusivePtr<THullCtx> HullCtx;
- std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
TIntrusivePtr<TLocalRecoveryInfo> LocalRecoveryInfo;
TIntrusivePtr<TLsnMngr> LsnMngr;
TVDiskIncarnationGuid VDiskIncarnationGuid;
- NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
- ui64 ScrubEntrypointLsn;
+ NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
+ ui64 ScrubEntrypointLsn;
TEvLocalRecoveryDone(NKikimrProto::EReplyStatus status,
TIntrusivePtr<TLocalRecoveryInfo> recovInfo,
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog,
- std::shared_ptr<NHuge::THullHugeKeeperPersState> repairedHuge,
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog,
+ std::shared_ptr<NHuge::THullHugeKeeperPersState> repairedHuge,
TIntrusivePtr<TSyncerData> syncerData,
- std::shared_ptr<THullDbRecovery> &&reparedHullDb,
+ std::shared_ptr<THullDbRecovery> &&reparedHullDb,
const TPDiskCtxPtr &pdiskCtx,
TIntrusivePtr<THullCtx> &hullCtx,
- std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
TIntrusivePtr<TLocalRecoveryInfo> &localRecoveryInfo,
const TIntrusivePtr<TLsnMngr> &lsnMngr,
- TVDiskIncarnationGuid vdiskIncarnationGuid,
- NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn);
+ TVDiskIncarnationGuid vdiskIncarnationGuid,
+ NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn);
~TEvLocalRecoveryDone();
};
@@ -75,9 +75,9 @@ namespace NKikimr {
IActor* CreateDatabaseLocalRecoveryActor(
const TIntrusivePtr<TVDiskContext> &vctx,
const TIntrusivePtr<TVDiskConfig> &config,
- const TVDiskID &selfVDiskId,
+ const TVDiskID &selfVDiskId,
const TActorId &skeletonId,
- const TActorId skeletonFrontId,
- std::shared_ptr<TRopeArena> arena);
+ const TActorId skeletonFrontId,
+ std::shared_ptr<TRopeArena> arena);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_readbulksst.cpp b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_readbulksst.cpp
index f9c300960d9..8891f773a0a 100644
--- a/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_readbulksst.cpp
+++ b/ydb/core/blobstorage/vdisk/localrecovery/localrecovery_readbulksst.cpp
@@ -32,9 +32,9 @@ namespace NKikimr {
if (Index == Addition.size()) {
Finish(ctx);
} else {
- auto actor = std::make_unique<TLevelSegmentLoader>(VCtx, PDiskCtx, Addition[Index++].Sst.Get(),
+ auto actor = std::make_unique<TLevelSegmentLoader>(VCtx, PDiskCtx, Addition[Index++].Sst.Get(),
ctx.SelfID, Origin);
- auto aid = ctx.Register(actor.release());
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
}
}
@@ -46,9 +46,9 @@ namespace NKikimr {
void Finish(const TActorContext &ctx) {
Y_VERIFY(Index == Addition.size());
- auto msg = std::make_unique<TEvBulkSstEssenceLoaded>(RecoveryLogRecLsn);
+ auto msg = std::make_unique<TEvBulkSstEssenceLoaded>(RecoveryLogRecLsn);
msg->Essence.Replace(std::move(Addition));
- ctx.Send(Recipient, msg.release());
+ ctx.Send(Recipient, msg.release());
TThis::Die(ctx);
}
@@ -69,8 +69,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
}
TOneDbBulkSstLoader(
@@ -129,25 +129,25 @@ namespace NKikimr {
const TString origin = "BulkSstLoader";
if (Proto.LogoBlobsAdditionsSize() && LoadLogoBlobs) {
using TLoader = TOneDbBulkSstLoader<TLogoBlobsSst>;
- auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableLogoBlobsAdditions(),
+ auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableLogoBlobsAdditions(),
ctx.SelfID, RecoveryLogRecLsn, origin);
- auto aid = ctx.Register(actor.release());
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
++RunActors;
}
if (Proto.BlocksAdditionsSize() && LoadBlocks) {
using TLoader = TOneDbBulkSstLoader<TBlocksSst>;
- auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableBlocksAdditions(),
+ auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableBlocksAdditions(),
ctx.SelfID, RecoveryLogRecLsn, origin);
- auto aid = ctx.Register(actor.release());
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
++RunActors;
}
if (Proto.BarriersAdditionsSize() && LoadBarriers) {
using TLoader = TOneDbBulkSstLoader<TBarriersSst>;
- auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableBarriersAdditions(),
+ auto actor = std::make_unique<TLoader>(VCtx, PDiskCtx, *Proto.MutableBarriersAdditions(),
ctx.SelfID, RecoveryLogRecLsn, origin);
- auto aid = ctx.Register(actor.release());
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
++RunActors;
}
@@ -166,8 +166,8 @@ namespace NKikimr {
}
void Finish(const TActorContext &ctx) {
- auto msg = std::make_unique<TEvBulkSstEssenceLoaded>(std::move(Essence), RecoveryLogRecLsn);
- ctx.Send(Recipient, msg.release());
+ auto msg = std::make_unique<TEvBulkSstEssenceLoaded>(std::move(Essence), RecoveryLogRecLsn);
+ ctx.Send(Recipient, msg.release());
TThis::Die(ctx);
}
@@ -183,8 +183,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DB_LOCAL_RECOVERY;
}
TBulkSstLoader(
diff --git a/ydb/core/blobstorage/vdisk/query/query_barrier.cpp b/ydb/core/blobstorage/vdisk/query/query_barrier.cpp
index c469bb8f404..565f7c26fc3 100644
--- a/ydb/core/blobstorage/vdisk/query/query_barrier.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_barrier.cpp
@@ -19,7 +19,7 @@ namespace NKikimr {
TBarriersSnapshot BarriersSnap;
TEvBlobStorage::TEvVGetBarrier::TPtr Ev;
NKikimrBlobStorage::TEvVGetBarrier &Record;
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> Result;
friend class TActorBootstrapped<TLevelIndexBarrierQuery>;
@@ -33,7 +33,7 @@ namespace NKikimr {
LOG_DEBUG(ctx, BS_VDISK_GC,
VDISKP(HullCtx->VCtx->VDiskLogPrefix,
"TEvVGetBarrierResult: %s", Result->ToString().data()));
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
ctx.Send(ParentId, new TEvents::TEvActorDied);
Die(ctx);
}
@@ -54,8 +54,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_BARRIER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_BARRIER;
}
TLevelIndexBarrierQuery(
@@ -63,14 +63,14 @@ namespace NKikimr {
const TActorId &parentId,
TBarriersSnapshot &&barriersSnap,
TEvBlobStorage::TEvVGetBarrier::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result)
: TActorBootstrapped<TLevelIndexBarrierQuery>()
, HullCtx(hullCtx)
, ParentId(parentId)
, BarriersSnap(std::move(barriersSnap))
, Ev(ev)
, Record(Ev->Get()->Record)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
};
@@ -82,8 +82,8 @@ namespace NKikimr {
const TActorId &parentId,
TBarriersSnapshot &&barriersSnap,
TEvBlobStorage::TEvVGetBarrier::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result) {
- return new TLevelIndexBarrierQuery(hullCtx, parentId, std::move(barriersSnap), ev, std::move(result));
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result) {
+ return new TLevelIndexBarrierQuery(hullCtx, parentId, std::move(barriersSnap), ev, std::move(result));
}
diff --git a/ydb/core/blobstorage/vdisk/query/query_base.h b/ydb/core/blobstorage/vdisk/query/query_base.h
index 092b93964f2..a4eb547b486 100644
--- a/ydb/core/blobstorage/vdisk/query/query_base.h
+++ b/ydb/core/blobstorage/vdisk/query/query_base.h
@@ -14,25 +14,25 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TLevelIndexQueryBase {
protected:
- std::shared_ptr<TQueryCtx> QueryCtx;
+ std::shared_ptr<TQueryCtx> QueryCtx;
const TActorId ParentId;
TLogoBlobsSnapshot LogoBlobsSnapshot;
TBarriersSnapshot BarriersSnapshot;
TReadBatcherCtxPtr BatcherCtx;
const NKikimrBlobStorage::TEvVGet &Record;
const bool ShowInternals;
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> Result;
TQueryResultSizeTracker ResultSize;
- const TActorId ReplSchedulerId;
+ const TActorId ReplSchedulerId;
TLevelIndexQueryBase(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: QueryCtx(queryCtx)
, ParentId(parentId)
, LogoBlobsSnapshot(std::move(logoBlobsSnapshot))
@@ -40,10 +40,10 @@ namespace NKikimr {
, BatcherCtx(new TReadBatcherCtx(QueryCtx->HullCtx->VCtx, QueryCtx->PDiskCtx, ev))
, Record(BatcherCtx->OrigEv->Get()->Record)
, ShowInternals(Record.GetShowInternals())
- , Result(std::move(result))
- , ReplSchedulerId(replSchedulerId)
+ , Result(std::move(result))
+ , ReplSchedulerId(replSchedulerId)
{
- Y_VERIFY_DEBUG(Result);
+ Y_VERIFY_DEBUG(Result);
}
ui8 PDiskPriority() const {
@@ -66,16 +66,16 @@ namespace NKikimr {
return priority;
}
- bool IsRepl() const {
- return Result->Record.HasMsgQoS()
- ? NBackpressure::TQueueClientId(Result->Record.GetMsgQoS()).IsRepl()
- : false;
- }
-
+ bool IsRepl() const {
+ return Result->Record.HasMsgQoS()
+ ? NBackpressure::TQueueClientId(Result->Record.GetMsgQoS()).IsRepl()
+ : false;
+ }
+
template <class T>
void SendResponseAndDie(const TActorContext &ctx, T *self) {
- bool hasNotYet = false;
-
+ bool hasNotYet = false;
+
if (ResultSize.IsOverflow()) {
Result->Record.SetStatus(NKikimrProto::ERROR);
Result->Record.MutableResult()->Clear();
@@ -97,7 +97,7 @@ namespace NKikimr {
ui64 total = 0;
for (const auto& result : Result->Record.GetResult()) {
total += result.GetBuffer().size();
- hasNotYet = hasNotYet || result.GetStatus() == NKikimrProto::NOT_YET;
+ hasNotYet = hasNotYet || result.GetStatus() == NKikimrProto::NOT_YET;
}
QueryCtx->MonGroup.GetTotalBytes() += total;
LOG_DEBUG(ctx, NKikimrServices::BS_VDISK_GET,
@@ -105,14 +105,14 @@ namespace NKikimr {
"TEvVGetResult: %s", Result->ToString().data()));
}
- if (hasNotYet && ReplSchedulerId) {
- // send reply event to repl scheduler to possibly fix NOT_YET replies
- ctx.Send(ReplSchedulerId, new TEvBlobStorage::TEvEnrichNotYet(BatcherCtx->OrigEv, std::move(Result)));
- } else {
- // send reply event to sender
- SendVDiskResponse(ctx, BatcherCtx->OrigEv->Sender, Result.release(), *self, BatcherCtx->OrigEv->Cookie);
- }
-
+ if (hasNotYet && ReplSchedulerId) {
+ // send reply event to repl scheduler to possibly fix NOT_YET replies
+ ctx.Send(ReplSchedulerId, new TEvBlobStorage::TEvEnrichNotYet(BatcherCtx->OrigEv, std::move(Result)));
+ } else {
+ // send reply event to sender
+ SendVDiskResponse(ctx, BatcherCtx->OrigEv->Sender, Result.release(), *self, BatcherCtx->OrigEv->Cookie);
+ }
+
ctx.Send(ParentId, new TEvents::TEvActorDied);
self->Die(ctx);
}
diff --git a/ydb/core/blobstorage/vdisk/query/query_dumpdb.h b/ydb/core/blobstorage/vdisk/query/query_dumpdb.h
index bba8a7fbdcd..26c924d35d8 100644
--- a/ydb/core/blobstorage/vdisk/query/query_dumpdb.h
+++ b/ydb/core/blobstorage/vdisk/query/query_dumpdb.h
@@ -47,26 +47,26 @@ namespace NKikimr {
// send result
Result->SetResult(str.Str());
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
TThis::Die(ctx);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
}
TLevelIndexDumpActor(TIntrusivePtr<THullCtx> hullCtx,
const TActorId &parentId,
TLevelIndexSnapshot &&snapshot,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
: TActorBootstrapped<TThis>()
, HullCtx(std::move(hullCtx))
, ParentId(parentId)
, Snapshot(std::move(snapshot))
, Ev(ev)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
private:
@@ -74,7 +74,7 @@ namespace NKikimr {
const TActorId ParentId;
TLevelIndexSnapshot Snapshot;
TEvBlobStorage::TEvVDbStat::TPtr Ev;
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_extr.cpp b/ydb/core/blobstorage/vdisk/query/query_extr.cpp
index 196b6d2054a..f9d2ade94e6 100644
--- a/ydb/core/blobstorage/vdisk/query/query_extr.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_extr.cpp
@@ -28,15 +28,15 @@ namespace NKikimr {
{}
};
- std::unique_ptr<TLogoBlobsSnapshot::TForwardIterator> ForwardIt;
- TVector<TQuery> Queries;
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence;
- bool BlobInIndex = false;
+ std::unique_ptr<TLogoBlobsSnapshot::TForwardIterator> ForwardIt;
+ TVector<TQuery> Queries;
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence;
+ bool BlobInIndex = false;
- TQuery *FetchNextQuery() {
+ TQuery *FetchNextQuery() {
ui32 queryNum = Queries.size();
if (queryNum == Record.ExtremeQueriesSize()) {
- return nullptr;
+ return nullptr;
}
const NKikimrBlobStorage::TExtremeQuery *query = &Record.GetExtremeQueries(queryNum);
@@ -52,35 +52,35 @@ namespace NKikimr {
ForwardIt->Seek(q.LogoBlobID);
BlobInIndex = ForwardIt->Valid() && ForwardIt->GetCurKey().LogoBlobID() == q.LogoBlobID;
- return &Queries.back();
+ return &Queries.back();
}
- void Prepare() {
- Y_VERIFY(Record.ExtremeQueriesSize() > 0);
+ void Prepare() {
+ Y_VERIFY(Record.ExtremeQueriesSize() > 0);
// initialize ForwardIt with a delay to avoid work in constructor
- ForwardIt = std::make_unique<TLogoBlobsSnapshot::TForwardIterator>(QueryCtx->HullCtx, &LogoBlobsSnapshot);
- Queries.reserve(Record.ExtremeQueriesSize());
- BarriersEssence = BarriersSnapshot.CreateEssence(QueryCtx->HullCtx);
- BarriersSnapshot.Destroy();
- }
-
- template<typename TMerger>
- bool IsBlobDeleted(const TLogoBlobID &id, const TMerger &merger) {
- const auto &status = BarriersEssence->Keep(id, merger.GetMemRec(), merger.GetMemRecsMerged(),
+ ForwardIt = std::make_unique<TLogoBlobsSnapshot::TForwardIterator>(QueryCtx->HullCtx, &LogoBlobsSnapshot);
+ Queries.reserve(Record.ExtremeQueriesSize());
+ BarriersEssence = BarriersSnapshot.CreateEssence(QueryCtx->HullCtx);
+ BarriersSnapshot.Destroy();
+ }
+
+ template<typename TMerger>
+ bool IsBlobDeleted(const TLogoBlobID &id, const TMerger &merger) {
+ const auto &status = BarriersEssence->Keep(id, merger.GetMemRec(), merger.GetMemRecsMerged(),
QueryCtx->HullCtx->AllowKeepFlags);
- return !status.KeepData;
- }
-
+ return !status.KeepData;
+ }
+
TLevelIndexExtremeQueryViaBatcherBase(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: TLevelIndexQueryBase(queryCtx, parentId, std::move(logoBlobsSnapshot), std::move(barrierSnapshot),
- ev, std::move(result), replSchedulerId)
+ ev, std::move(result), replSchedulerId)
{}
};
@@ -99,36 +99,36 @@ namespace NKikimr {
friend class TLevelIndexExtremeQueryViaBatcherBase;
void Bootstrap(const TActorContext &ctx) {
- Prepare();
+ Prepare();
MainCycle(ctx);
}
void MainCycle(const TActorContext &ctx) {
TQuery *query = nullptr;
while ((query = FetchNextQuery()) && !ResultSize.IsOverflow()) {
- Y_VERIFY(query->PartId == 0); // only full blobs (w/o specifying a part) are allowed
- const ui64 *cookiePtr = query->HasCookie ? &query->CookieVal : nullptr;
+ Y_VERIFY(query->PartId == 0); // only full blobs (w/o specifying a part) are allowed
+ const ui64 *cookiePtr = query->HasCookie ? &query->CookieVal : nullptr;
ResultSize.AddLogoBlobIndex();
- if (!BlobInIndex) {
+ if (!BlobInIndex) {
// put NODATA
- Result->AddResult(NKikimrProto::NODATA, query->LogoBlobID, cookiePtr, nullptr);
+ Result->AddResult(NKikimrProto::NODATA, query->LogoBlobID, cookiePtr, nullptr);
} else {
// index record(s) are found
ForwardIt->PutToMerger(&Merger);
Merger.Finish();
TIngress ingress = Merger.GetMemRec().GetIngress();
// Find out if we have all parts locally that we must have according to ingress
- NMatrix::TVectorType mustHave = ingress.PartsWeMustHaveLocally(QueryCtx->HullCtx->VCtx->Top.get(),
+ NMatrix::TVectorType mustHave = ingress.PartsWeMustHaveLocally(QueryCtx->HullCtx->VCtx->Top.get(),
QueryCtx->HullCtx->VCtx->ShortSelfVDisk, query->LogoBlobID);
NMatrix::TVectorType actuallyHave = ingress.LocalParts(QueryCtx->HullCtx->VCtx->Top->GType);
NMatrix::TVectorType missingParts = mustHave - actuallyHave;
- // If we don't have something locally we return NOT_YET unless that blob is going to be collected
- auto status = IsBlobDeleted(query->LogoBlobID, Merger) ? NKikimrProto::NODATA :
- missingParts.Empty() ? NKikimrProto::OK : NKikimrProto::NOT_YET;
+ // If we don't have something locally we return NOT_YET unless that blob is going to be collected
+ auto status = IsBlobDeleted(query->LogoBlobID, Merger) ? NKikimrProto::NODATA :
+ missingParts.Empty() ? NKikimrProto::OK : NKikimrProto::NOT_YET;
// Add result
ui64 ingressRaw = ingress.Raw();
ui64 *pingr = (ShowInternals ? &ingressRaw : nullptr);
- Result->AddResult(status, query->LogoBlobID, cookiePtr, pingr);
+ Result->AddResult(status, query->LogoBlobID, cookiePtr, pingr);
Merger.Clear();
}
}
@@ -138,20 +138,20 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULLQUERY_EXTREME_INDEX_ONLY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULLQUERY_EXTREME_INDEX_ONLY;
}
TLevelIndexExtremeQueryViaBatcherIndexOnly(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: TLevelIndexExtremeQueryViaBatcherBase(queryCtx, parentId, std::move(logoBlobsSnapshot),
- std::move(barrierSnapshot), ev, std::move(result), replSchedulerId)
+ std::move(barrierSnapshot), ev, std::move(result), replSchedulerId)
, TActorBootstrapped<TLevelIndexExtremeQueryViaBatcherIndexOnly>()
, Merger(QueryCtx->HullCtx->VCtx->Top->GType)
{}
@@ -176,18 +176,18 @@ namespace NKikimr {
TActiveActors ActiveActors;
void Bootstrap(const TActorContext &ctx) {
- Prepare();
+ Prepare();
MainCycle(ctx);
}
void Finish(const TActorContext &ctx) {
- std::unordered_map<TLogoBlobID, NMatrix::TVectorType, THash<TLogoBlobID>> neededParts;
-
+ std::unordered_map<TLogoBlobID, NMatrix::TVectorType, THash<TLogoBlobID>> neededParts;
+
// build result
TReadBatcherResult::TIterator rit(&Batcher.GetResult());
for (rit.SeekToFirst(); rit.Valid(); rit.Next()) {
const NReadBatcher::TDataItem *it = rit.Get();
- const TQuery *query = static_cast<const TQuery*>(it->Cookie);
+ const TQuery *query = static_cast<const TQuery*>(it->Cookie);
Y_VERIFY_DEBUG(query->LogoBlobID.PartId() == 0);
const ui64 *cookiePtr = query->HasCookie ? &query->CookieVal : nullptr;
@@ -210,102 +210,102 @@ namespace NKikimr {
case NReadBatcher::TDataItem::ET_NOT_YET:
// put NOT_YET
Y_VERIFY(it->Id.PartId() > 0);
- Result->AddResult(NKikimrProto::NOT_YET, it->Id, query->Shift, nullptr, query->Size, cookiePtr, pingr);
+ Result->AddResult(NKikimrProto::NOT_YET, it->Id, query->Shift, nullptr, query->Size, cookiePtr, pingr);
break;
case NReadBatcher::TDataItem::ET_SETDISK:
case NReadBatcher::TDataItem::ET_SETMEM:
{
// GOOD
Y_VERIFY(it->Id.PartId() > 0);
- struct TProcessor {
- std::unique_ptr<TEvBlobStorage::TEvVGetResult>& Result;
- TLogoBlobID Id;
- ui64 Shift;
- ui64 Size;
- const ui64 *CookiePtr;
- const ui64 *IngrPtr;
- bool Success = true;
- void operator()(NReadBatcher::TReadError) {
- Result->AddResult(NKikimrProto::CORRUPTED, Id, Shift, nullptr, Size, CookiePtr, IngrPtr);
- Success = false;
- }
- void operator()(const char *data, size_t size) const {
- Result->AddResult(NKikimrProto::OK, Id, Shift, data, size, CookiePtr, IngrPtr);
- }
- void operator()(const TRope& data) const {
- const TString s = data.ConvertToString();
- (*this)(s.data(), s.size());
- }
- } processor{Result, it->Id, query->Shift, query->Size, cookiePtr, pingr};
- rit.GetData(processor);
- if (!processor.Success) {
- NMatrix::TVectorType& v = neededParts[it->Id.FullID()];
- if (!v.GetSize()) {
- v = NMatrix::TVectorType(0, GType.TotalPartCount());
- }
- v.Set(it->Id.PartId() - 1);
- }
+ struct TProcessor {
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult>& Result;
+ TLogoBlobID Id;
+ ui64 Shift;
+ ui64 Size;
+ const ui64 *CookiePtr;
+ const ui64 *IngrPtr;
+ bool Success = true;
+ void operator()(NReadBatcher::TReadError) {
+ Result->AddResult(NKikimrProto::CORRUPTED, Id, Shift, nullptr, Size, CookiePtr, IngrPtr);
+ Success = false;
+ }
+ void operator()(const char *data, size_t size) const {
+ Result->AddResult(NKikimrProto::OK, Id, Shift, data, size, CookiePtr, IngrPtr);
+ }
+ void operator()(const TRope& data) const {
+ const TString s = data.ConvertToString();
+ (*this)(s.data(), s.size());
+ }
+ } processor{Result, it->Id, query->Shift, query->Size, cookiePtr, pingr};
+ rit.GetData(processor);
+ if (!processor.Success) {
+ NMatrix::TVectorType& v = neededParts[it->Id.FullID()];
+ if (!v.GetSize()) {
+ v = NMatrix::TVectorType(0, GType.TotalPartCount());
+ }
+ v.Set(it->Id.PartId() - 1);
+ }
break;
}
}
}
// send response and die
- QueryCtx->PDiskReadBytes += Batcher.GetPDiskReadBytes();
-
- if (neededParts.empty()) {
- return Finish2(ctx);
- }
-
- std::vector<TEvRestoreCorruptedBlob::TItem> items;
- for (const auto& [id, needed] : neededParts) {
- items.emplace_back(id, needed, GType, TDiskPart());
- }
- ctx.Send(QueryCtx->SkeletonId, new TEvRestoreCorruptedBlob(ctx.Now() + TDuration::Minutes(2),
- std::move(items), true, true));
- }
-
- void Handle(TEvRestoreCorruptedBlobResult::TPtr ev, const TActorContext& ctx) {
- std::unordered_map<TLogoBlobID, TEvRestoreCorruptedBlobResult::TItem*, THash<TLogoBlobID>> map;
- for (auto& item : ev->Get()->Items) {
- map.emplace(item.BlobId, &item);
- }
- for (auto& res : *Result->Record.MutableResult()) {
- if (res.GetStatus() == NKikimrProto::CORRUPTED) {
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(res.GetBlobID());
- const auto it = map.find(id.FullID());
- Y_VERIFY(it != map.end());
- if (it->second->Status == NKikimrProto::OK) {
- const TString& buffer = it->second->GetPartData(id);
- res.SetBuffer(buffer.substr(res.GetShift(), res.GetSize() ? res.GetSize() : buffer.size() - res.GetShift()));
- res.SetStatus(NKikimrProto::OK);
- }
- }
- }
- Finish2(ctx);
- }
-
- void Finish2(const TActorContext& ctx) {
- TReplQuoter::TPtr quoter;
- if (IsRepl()) {
- quoter = QueryCtx->HullCtx->VCtx->ReplNodeResponseQuoter;
- }
- const TDuration duration = quoter
- ? quoter->Take(TActivationContext::Now(), Result->CalculateSerializedSizeCached())
- : TDuration::Zero();
- if (duration != TDuration::Zero()) {
- Schedule(duration, new TEvents::TEvWakeup);
- Become(&TThis::StateFunc);
- } else {
- SendResponse(ctx);
- }
- }
-
- void SendResponse(const TActorContext& ctx) {
+ QueryCtx->PDiskReadBytes += Batcher.GetPDiskReadBytes();
+
+ if (neededParts.empty()) {
+ return Finish2(ctx);
+ }
+
+ std::vector<TEvRestoreCorruptedBlob::TItem> items;
+ for (const auto& [id, needed] : neededParts) {
+ items.emplace_back(id, needed, GType, TDiskPart());
+ }
+ ctx.Send(QueryCtx->SkeletonId, new TEvRestoreCorruptedBlob(ctx.Now() + TDuration::Minutes(2),
+ std::move(items), true, true));
+ }
+
+ void Handle(TEvRestoreCorruptedBlobResult::TPtr ev, const TActorContext& ctx) {
+ std::unordered_map<TLogoBlobID, TEvRestoreCorruptedBlobResult::TItem*, THash<TLogoBlobID>> map;
+ for (auto& item : ev->Get()->Items) {
+ map.emplace(item.BlobId, &item);
+ }
+ for (auto& res : *Result->Record.MutableResult()) {
+ if (res.GetStatus() == NKikimrProto::CORRUPTED) {
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(res.GetBlobID());
+ const auto it = map.find(id.FullID());
+ Y_VERIFY(it != map.end());
+ if (it->second->Status == NKikimrProto::OK) {
+ const TString& buffer = it->second->GetPartData(id);
+ res.SetBuffer(buffer.substr(res.GetShift(), res.GetSize() ? res.GetSize() : buffer.size() - res.GetShift()));
+ res.SetStatus(NKikimrProto::OK);
+ }
+ }
+ }
+ Finish2(ctx);
+ }
+
+ void Finish2(const TActorContext& ctx) {
+ TReplQuoter::TPtr quoter;
+ if (IsRepl()) {
+ quoter = QueryCtx->HullCtx->VCtx->ReplNodeResponseQuoter;
+ }
+ const TDuration duration = quoter
+ ? quoter->Take(TActivationContext::Now(), Result->CalculateSerializedSizeCached())
+ : TDuration::Zero();
+ if (duration != TDuration::Zero()) {
+ Schedule(duration, new TEvents::TEvWakeup);
+ Become(&TThis::StateFunc);
+ } else {
+ SendResponse(ctx);
+ }
+ }
+
+ void SendResponse(const TActorContext& ctx) {
SendResponseAndDie(ctx, this);
}
- void HandleReadCompletion(TEvents::TEvCompleted::TPtr& ev, const TActorContext &ctx) {
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &Result->TraceId, ReadBatcherFinish, MergedNode = std::move(ev->TraceId));
+ void HandleReadCompletion(TEvents::TEvCompleted::TPtr& ev, const TActorContext &ctx) {
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &Result->TraceId, ReadBatcherFinish, MergedNode = std::move(ev->TraceId));
ActiveActors.Erase(ev->Sender);
Finish(ctx);
}
@@ -313,33 +313,33 @@ namespace NKikimr {
void MainCycle(const TActorContext &ctx) {
TQuery *query = nullptr;
while ((query = FetchNextQuery()) && !ResultSize.IsOverflow()) {
- const TLogoBlobID &fullId = query->LogoBlobID; // full blob id we are looking for
- const TLogoBlobID partId = TLogoBlobID(fullId, query->PartId);
- bool found = false;
- TMaybe<TIngress> ingress;
-
+ const TLogoBlobID &fullId = query->LogoBlobID; // full blob id we are looking for
+ const TLogoBlobID partId = TLogoBlobID(fullId, query->PartId);
+ bool found = false;
+ TMaybe<TIngress> ingress;
+
ResultSize.AddLogoBlobIndex();
- if (BlobInIndex) {
+ if (BlobInIndex) {
ResultSize.AddLogoBlobData(GType.PartSize(partId), query->Shift, query->Size);
- Batcher.StartTraverse(fullId, query, query->PartId, query->Shift, query->Size);
+ Batcher.StartTraverse(fullId, query, query->PartId, query->Shift, query->Size);
ForwardIt->PutToMerger(&Merger);
Merger.Finish();
- ingress = Merger.GetMemRec().GetIngress();
- if (IsBlobDeleted(fullId, Merger)) {
- // do nothing for this case -- this blob is scheduled for deletion and will not be reported
- Batcher.AbortTraverse();
- } else {
- // finish traversing and generate requests for reads
- Batcher.FinishTraverse(*ingress);
- found = true;
- }
+ ingress = Merger.GetMemRec().GetIngress();
+ if (IsBlobDeleted(fullId, Merger)) {
+ // do nothing for this case -- this blob is scheduled for deletion and will not be reported
+ Batcher.AbortTraverse();
+ } else {
+ // finish traversing and generate requests for reads
+ Batcher.FinishTraverse(*ingress);
+ found = true;
+ }
Merger.Clear();
}
- if (!found) {
- // report NODATA for requested part if it either was not found in index nor was scheduled for compaction
- Batcher.PutNoData(partId, ingress, query);
- }
+ if (!found) {
+ // report NODATA for requested part if it either was not found in index nor was scheduled for compaction
+ Batcher.PutNoData(partId, ingress, query);
+ }
}
if (ResultSize.IsOverflow()) {
@@ -347,10 +347,10 @@ namespace NKikimr {
} else {
ui8 priority = PDiskPriority();
WILSON_TRACE_FROM_ACTOR(ctx, *this, &Result->TraceId, ReadBatcherStart);
- std::unique_ptr<IActor> a(Batcher.CreateAsyncDataReader(ctx.SelfID, priority, Result->TraceId.SeparateBranch(),
- IsRepl()));
+ std::unique_ptr<IActor> a(Batcher.CreateAsyncDataReader(ctx.SelfID, priority, Result->TraceId.SeparateBranch(),
+ IsRepl()));
if (a) {
- auto aid = ctx.Register(a.release());
+ auto aid = ctx.Register(a.release());
ActiveActors.Insert(aid);
Become(&TThis::StateFunc);
// wait for reply
@@ -358,8 +358,8 @@ namespace NKikimr {
Finish(ctx);
}
}
-
- BarriersEssence.Reset();
+
+ BarriersEssence.Reset();
}
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
@@ -368,28 +368,28 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvCompleted, HandleReadCompletion)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- CFunc(TEvents::TSystem::Wakeup, SendResponse)
- HFunc(TEvRestoreCorruptedBlobResult, Handle)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvCompleted, HandleReadCompletion)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ CFunc(TEvents::TSystem::Wakeup, SendResponse)
+ HFunc(TEvRestoreCorruptedBlobResult, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULLQUERY_EXTREME_DATA;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULLQUERY_EXTREME_DATA;
}
TLevelIndexExtremeQueryViaBatcherMergeData(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: TLevelIndexExtremeQueryViaBatcherBase(queryCtx, parentId, std::move(logoBlobsSnapshot),
- std::move(barrierSnapshot), ev, std::move(result), replSchedulerId)
+ std::move(barrierSnapshot), ev, std::move(result), replSchedulerId)
, TActorBootstrapped<TLevelIndexExtremeQueryViaBatcherMergeData>()
, GType(QueryCtx->HullCtx->VCtx->Top->GType)
, Batcher(BatcherCtx)
@@ -402,20 +402,20 @@ namespace NKikimr {
// CreateLevelIndexExtremeQueryActor
////////////////////////////////////////////////////////////////////////////
IActor *CreateLevelIndexExtremeQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId) {
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId) {
const bool indexOnly = ev->Get()->Record.GetIndexOnly();
if (indexOnly)
return new TLevelIndexExtremeQueryViaBatcherIndexOnly(queryCtx, parentId,
- std::move(logoBlobsSnapshot), std::move(barrierSnapshot), ev, std::move(result), replSchedulerId);
+ std::move(logoBlobsSnapshot), std::move(barrierSnapshot), ev, std::move(result), replSchedulerId);
else
return new TLevelIndexExtremeQueryViaBatcherMergeData(queryCtx, parentId,
- std::move(logoBlobsSnapshot), std::move(barrierSnapshot), ev, std::move(result), replSchedulerId);
+ std::move(logoBlobsSnapshot), std::move(barrierSnapshot), ev, std::move(result), replSchedulerId);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_public.cpp b/ydb/core/blobstorage/vdisk/query/query_public.cpp
index 25761b685eb..775fb2914b1 100644
--- a/ydb/core/blobstorage/vdisk/query/query_public.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_public.cpp
@@ -3,7 +3,7 @@
#include "query_statdb.h"
#include "query_stathuge.h"
#include "query_stattablet.h"
-#include "query_stream.h"
+#include "query_stream.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_response.h>
using namespace NKikimrServices;
@@ -12,23 +12,23 @@ namespace NKikimr {
// Extreme Query Declaration
IActor *CreateLevelIndexExtremeQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId);
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId);
// Range Query Declaration
IActor *CreateLevelIndexRangeQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barrierSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId);
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId);
// NOTES
@@ -65,13 +65,13 @@ namespace NKikimr {
it.Seek(full);
if (it.Valid() && it.GetCurKey() == full) {
const TIngress& ingress = it.GetMemRec().GetIngress();
- const bool keep = ingress.KeepUnconditionally(TIngress::IngressMode(hullCtx->VCtx->Top->GType));
+ const bool keep = ingress.KeepUnconditionally(TIngress::IngressMode(hullCtx->VCtx->Top->GType));
TString explanation;
if (!suppressBarrierCheck && !keepChecker(full, keep, &explanation)) {
LOG_INFO(ctx, NKikimrServices::BS_HULLRECS,
VDISKP(hullCtx->VCtx->VDiskLogPrefix,
"Db# LogoBlobs getting blob beyond the barrier id# %s ingress# %s barrier# %s",
- id.ToString().data(), ingress.ToString(hullCtx->VCtx->Top.get(),
+ id.ToString().data(), ingress.ToString(hullCtx->VCtx->Top.get(),
hullCtx->VCtx->ShortSelfVDisk, id).data(), explanation.data()));
}
}
@@ -79,14 +79,14 @@ namespace NKikimr {
}
IActor *CreateLevelIndexQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
TReadQueryKeepChecker &&keepChecker,
const TActorContext &ctx,
THullDsSnap &&fullSnap,
const TActorId &parentId,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId) {
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId) {
const auto& record = ev->Get()->Record;
if (queryCtx->HullCtx->BarrierValidation) {
@@ -98,10 +98,10 @@ namespace NKikimr {
// we pass barriers snap to the query actor when we are doing range read -- we need barriers
// to ensure that no blobs that are subject to GC are reported to the request origin actor
return CreateLevelIndexRangeQueryActor(queryCtx, parentId,
- std::move(fullSnap.LogoBlobsSnap), std::move(fullSnap.BarriersSnap), ev, std::move(result), replSchedulerId);
+ std::move(fullSnap.LogoBlobsSnap), std::move(fullSnap.BarriersSnap), ev, std::move(result), replSchedulerId);
} else if (record.ExtremeQueriesSize() > 0) {
return CreateLevelIndexExtremeQueryActor(queryCtx, parentId,
- std::move(fullSnap.LogoBlobsSnap), std::move(fullSnap.BarriersSnap), ev, std::move(result), replSchedulerId);
+ std::move(fullSnap.LogoBlobsSnap), std::move(fullSnap.BarriersSnap), ev, std::move(result), replSchedulerId);
} else {
Y_FAIL("Impossible case");
}
@@ -152,14 +152,14 @@ namespace NKikimr {
const TVDiskContextPtr &vctx,
const TActorContext &ctx,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
const IActor& actor)
{
result->SetError();
LOG_DEBUG(ctx, NKikimrServices::BS_VDISK_OTHER,
VDISKP(vctx->VDiskLogPrefix,
"TEvVDbStatResult: %s", result->ToString().data()));
- SendVDiskResponse(ctx, ev->Sender, result.release(), actor, ev->Cookie);
+ SendVDiskResponse(ctx, ev->Sender, result.release(), actor, ev->Cookie);
}
template <class TKey, class TMemRec>
@@ -169,21 +169,21 @@ namespace NKikimr {
TLevelIndexSnapshot<TKey, TMemRec> &&levelSnap,
const TActorId &parentId,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
const IActor& actor)
{
const NKikimrBlobStorage::TEvVDbStat &record = ev->Get()->Record;
switch (record.GetAction()) {
case NKikimrBlobStorage::DumpDb: {
using TDumpActor = TLevelIndexDumpActor<TKey, TMemRec>;
- return new TDumpActor(hullCtx, parentId, std::move(levelSnap), ev, std::move(result));
+ return new TDumpActor(hullCtx, parentId, std::move(levelSnap), ev, std::move(result));
}
case NKikimrBlobStorage::StatDb: {
using TStatActor = TLevelIndexStatActor<TKey, TMemRec>;
- return new TStatActor(hullCtx, parentId, std::move(levelSnap), ev, std::move(result));
+ return new TStatActor(hullCtx, parentId, std::move(levelSnap), ev, std::move(result));
}
default: {
- DbStatError(hullCtx->VCtx, ctx, ev, std::move(result), actor);
+ DbStatError(hullCtx->VCtx, ctx, ev, std::move(result), actor);
return nullptr;
}
}
@@ -196,39 +196,39 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
IActor *CreateDbStatActor(
const TIntrusivePtr<THullCtx> &hullCtx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TActorContext &ctx,
THullDsSnap &&fullSnap,
const TActorId &parentId,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
const IActor& actor) {
const NKikimrBlobStorage::TEvVDbStat &record = ev->Get()->Record;
switch (record.GetType()) {
case NKikimrBlobStorage::StatLogoBlobs: {
- return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.LogoBlobsSnap), parentId, ev, std::move(result), actor);
+ return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.LogoBlobsSnap), parentId, ev, std::move(result), actor);
}
case NKikimrBlobStorage::StatBlocks: {
- return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.BlocksSnap), parentId, ev, std::move(result), actor);
+ return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.BlocksSnap), parentId, ev, std::move(result), actor);
}
case NKikimrBlobStorage::StatBarriers: {
- return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.BarriersSnap), parentId, ev, std::move(result), actor);
+ return RunDbStatAction(hullCtx, ctx, std::move(fullSnap.BarriersSnap), parentId, ev, std::move(result), actor);
}
case NKikimrBlobStorage::StatTabletType: {
- return CreateTabletStatActor(hullCtx, parentId, std::move(fullSnap), ev, std::move(result));
+ return CreateTabletStatActor(hullCtx, parentId, std::move(fullSnap), ev, std::move(result));
}
case NKikimrBlobStorage::StatHugeType: {
- return CreateHugeStatActor(hullCtx, hugeBlobCtx, parentId, std::move(fullSnap), ev, std::move(result));
+ return CreateHugeStatActor(hullCtx, hugeBlobCtx, parentId, std::move(fullSnap), ev, std::move(result));
}
default: {
- DbStatError(hullCtx->VCtx, ctx, ev, std::move(result), actor);
+ DbStatError(hullCtx->VCtx, ctx, ev, std::move(result), actor);
return nullptr;
}
}
}
- IActor *CreateMonStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev) {
- return new TLevelIndexStreamActor(std::move(fullSnap), ev);
- }
-
+ IActor *CreateMonStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev) {
+ return new TLevelIndexStreamActor(std::move(fullSnap), ev);
+ }
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_public.h b/ydb/core/blobstorage/vdisk/query/query_public.h
index 38e498ad718..e652bae64ac 100644
--- a/ydb/core/blobstorage/vdisk/query/query_public.h
+++ b/ydb/core/blobstorage/vdisk/query/query_public.h
@@ -17,15 +17,15 @@ namespace NKikimr {
TIntrusivePtr<THullCtx> HullCtx;
TPDiskCtxPtr PDiskCtx;
NMonGroup::TInterfaceGroup MonGroup;
- std::atomic<ui64> PDiskReadBytes;
- TActorId SkeletonId;
+ std::atomic<ui64> PDiskReadBytes;
+ TActorId SkeletonId;
TQueryCtx(TIntrusivePtr<THullCtx> hullCtx, TPDiskCtxPtr pdiskCtx, TActorId skeletonId)
: HullCtx(std::move(hullCtx))
, PDiskCtx(std::move(pdiskCtx))
, MonGroup(HullCtx->VCtx->VDiskCounters, "subsystem", "interface")
, PDiskReadBytes(0)
- , SkeletonId(skeletonId)
+ , SkeletonId(skeletonId)
{}
};
@@ -39,14 +39,14 @@ namespace NKikimr {
// Handle a TEvVGet query on Hull database snapshot
//////////////////////////////////////////////////////////////////////////////////////
IActor *CreateLevelIndexQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
TReadQueryKeepChecker &&keepChecker,
const TActorContext &ctx,
THullDsSnap &&fullSnap,
const TActorId &parentId,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId);
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId);
//////////////////////////////////////////////////////////////////////////////////////
// TEvVGet query check
@@ -63,7 +63,7 @@ namespace NKikimr {
const TActorId &parentId,
TBarriersSnapshot &&barriersSnap,
TEvBlobStorage::TEvVGetBarrier::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result);
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result);
////////////////////////////////////////////////////////////////////////////
// Check Barrier Query
@@ -78,14 +78,14 @@ namespace NKikimr {
class THugeBlobCtx;
IActor *CreateDbStatActor(
const TIntrusivePtr<THullCtx> &hullCtx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TActorContext &ctx,
THullDsSnap &&fullSnap,
const TActorId &parentId,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result,
const IActor& actor);
- IActor *CreateMonStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev);
-
+ IActor *CreateMonStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev);
+
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_range.cpp b/ydb/core/blobstorage/vdisk/query/query_range.cpp
index 4513187b550..f10290c70ae 100644
--- a/ydb/core/blobstorage/vdisk/query/query_range.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_range.cpp
@@ -43,23 +43,23 @@ namespace NKikimr {
DoSwap(FirstPartId, LastPartId);
BackwardIt.Seek(Last);
}
-
- const ui64 firstTabletId = Min(First.TabletID(), Last.TabletID());
- const ui64 lastTabletId = Max(First.TabletID(), Last.TabletID());
+
+ const ui64 firstTabletId = Min(First.TabletID(), Last.TabletID());
+ const ui64 lastTabletId = Max(First.TabletID(), Last.TabletID());
BarriersEssence = BarriersSnapshot.CreateEssence(QueryCtx->HullCtx, firstTabletId, lastTabletId, 0);
BarriersSnapshot.Destroy();
}
TLevelIndexRangeQueryViaBatcherBase(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barriersSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: TLevelIndexQueryBase(queryCtx, parentId, std::move(logoBlobsSnapshot), std::move(barriersSnapshot),
- ev, std::move(result), replSchedulerId)
+ ev, std::move(result), replSchedulerId)
, ForwardIt(QueryCtx->HullCtx, &LogoBlobsSnapshot)
, BackwardIt(QueryCtx->HullCtx, &LogoBlobsSnapshot)
, First()
@@ -98,7 +98,7 @@ namespace NKikimr {
while (Counter > 0 && !ResultSize.IsOverflow() && ForwardIt.Valid() && ForwardIt.GetCurKey() <= Last) {
ForwardIt.PutToMerger(&Merger);
Merger.Finish();
- AddIndexOnly(ForwardIt.GetCurKey().LogoBlobID(), Merger);
+ AddIndexOnly(ForwardIt.GetCurKey().LogoBlobID(), Merger);
Merger.Clear();
ForwardIt.Next();
}
@@ -107,7 +107,7 @@ namespace NKikimr {
while (Counter > 0 && !ResultSize.IsOverflow() && BackwardIt.Valid() && BackwardIt.GetCurKey() >= First) {
BackwardIt.PutToMerger(&Merger);
Merger.Finish();
- AddIndexOnly(BackwardIt.GetCurKey().LogoBlobID(), Merger);
+ AddIndexOnly(BackwardIt.GetCurKey().LogoBlobID(), Merger);
Merger.Clear();
BackwardIt.Prev();
}
@@ -120,37 +120,37 @@ namespace NKikimr {
SendResponseAndDie(ctx, this);
}
- template<typename TMerger>
- void AddIndexOnly(const TLogoBlobID &logoBlobId, const TMerger &merger) {
+ template<typename TMerger>
+ void AddIndexOnly(const TLogoBlobID &logoBlobId, const TMerger &merger) {
const auto &status = BarriersEssence->Keep(logoBlobId, merger.GetMemRec(), merger.GetMemRecsMerged(),
QueryCtx->HullCtx->AllowKeepFlags);
- if (status.KeepData) {
- const TIngress &ingress = merger.GetMemRec().GetIngress();
- ui64 ingr = ingress.Raw();
- ui64 *pingr = (ShowInternals ? &ingr : nullptr);
+ if (status.KeepData) {
+ const TIngress &ingress = merger.GetMemRec().GetIngress();
+ ui64 ingr = ingress.Raw();
+ ui64 *pingr = (ShowInternals ? &ingr : nullptr);
Y_VERIFY(logoBlobId.PartId() == 0); // Index-only response must contain a single record for the blob
- const NMatrix::TVectorType local = ingress.LocalParts(QueryCtx->HullCtx->VCtx->Top->GType);
- Result->AddResult(NKikimrProto::OK, logoBlobId, CookiePtr, pingr, &local);
+ const NMatrix::TVectorType local = ingress.LocalParts(QueryCtx->HullCtx->VCtx->Top->GType);
+ Result->AddResult(NKikimrProto::OK, logoBlobId, CookiePtr, pingr, &local);
--Counter;
ResultSize.AddLogoBlobIndex();
- }
+ }
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULLQUERY_RANGE_INDEX_ONLY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULLQUERY_RANGE_INDEX_ONLY;
}
TLevelIndexRangeQueryViaBatcherIndexOnly(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barriersSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId)
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId)
: TLevelIndexRangeQueryViaBatcherBase(queryCtx, parentId,
- std::move(logoBlobsSnapshot), std::move(barriersSnapshot), ev, std::move(result), replSchedulerId)
+ std::move(logoBlobsSnapshot), std::move(barriersSnapshot), ev, std::move(result), replSchedulerId)
, TActorBootstrapped<TLevelIndexRangeQueryViaBatcherIndexOnly>()
, Merger(QueryCtx->HullCtx->VCtx->Top->GType)
{
@@ -162,20 +162,20 @@ namespace NKikimr {
// CreateLevelIndexRangeQueryActor
////////////////////////////////////////////////////////////////////////////
IActor *CreateLevelIndexRangeQueryActor(
- std::shared_ptr<TQueryCtx> &queryCtx,
+ std::shared_ptr<TQueryCtx> &queryCtx,
const TActorId &parentId,
TLogoBlobsSnapshot &&logoBlobsSnapshot,
TBarriersSnapshot &&barriersSnapshot,
TEvBlobStorage::TEvVGet::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
- TActorId replSchedulerId) {
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> result,
+ TActorId replSchedulerId) {
bool indexOnly = ev->Get()->Record.GetIndexOnly();
- if (indexOnly) {
+ if (indexOnly) {
return new TLevelIndexRangeQueryViaBatcherIndexOnly(queryCtx, parentId,
- std::move(logoBlobsSnapshot), std::move(barriersSnapshot), ev, std::move(result), replSchedulerId);
- } else {
- return nullptr;
- }
+ std::move(logoBlobsSnapshot), std::move(barriersSnapshot), ev, std::move(result), replSchedulerId);
+ } else {
+ return nullptr;
+ }
}
diff --git a/ydb/core/blobstorage/vdisk/query/query_readactor.cpp b/ydb/core/blobstorage/vdisk/query/query_readactor.cpp
index dfe5cff3c0b..430f73a1e59 100644
--- a/ydb/core/blobstorage/vdisk/query/query_readactor.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_readactor.cpp
@@ -15,10 +15,10 @@ namespace NKikimr {
class TTReadBatcherActor : public TActorBootstrapped<TTReadBatcherActor> {
TReadBatcherCtxPtr Ctx;
const TActorId NotifyID;
- std::shared_ptr<TReadBatcherResult> Result;
+ std::shared_ptr<TReadBatcherResult> Result;
const ui8 Priority;
- NWilson::TTraceId TraceId;
- const bool IsRepl;
+ NWilson::TTraceId TraceId;
+ const bool IsRepl;
ui32 Counter = 0;
friend class TActorBootstrapped<TTReadBatcherActor>;
@@ -27,32 +27,32 @@ namespace NKikimr {
Become(&TThis::StateFunc);
Y_VERIFY_DEBUG(!Result->GlueReads.empty());
- TReplQuoter::TPtr quoter;
- if (IsRepl) {
- quoter = Ctx->VCtx->ReplPDiskReadQuoter;
- }
-
+ TReplQuoter::TPtr quoter;
+ if (IsRepl) {
+ quoter = Ctx->VCtx->ReplPDiskReadQuoter;
+ }
+
// make read requests
for (TGlueReads::iterator it = Result->GlueReads.begin(), e = Result->GlueReads.end(); it != e; ++it) {
- // cookie for this request
- void *cookie = &*it;
-
- // generate wilson event with query details
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &TraceId, EvChunkReadSent, ChunkIdx = it->Part.ChunkIdx,
- Offset = it->Part.Offset, Size = it->Part.Size, YardCookie = cookie);
-
- // create request
- std::unique_ptr<NPDisk::TEvChunkRead> msg(new NPDisk::TEvChunkRead(Ctx->PDiskCtx->Dsk->Owner,
+ // cookie for this request
+ void *cookie = &*it;
+
+ // generate wilson event with query details
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &TraceId, EvChunkReadSent, ChunkIdx = it->Part.ChunkIdx,
+ Offset = it->Part.Offset, Size = it->Part.Size, YardCookie = cookie);
+
+ // create request
+ std::unique_ptr<NPDisk::TEvChunkRead> msg(new NPDisk::TEvChunkRead(Ctx->PDiskCtx->Dsk->Owner,
Ctx->PDiskCtx->Dsk->OwnerRound, it->Part.ChunkIdx, it->Part.Offset, it->Part.Size,
Priority, cookie));
-
+
LOG_DEBUG(ctx, BS_VDISK_GET,
VDISKP(Ctx->VCtx->VDiskLogPrefix, "GLUEREAD(%p): %s", this, msg->ToString().data()));
-
- // send request
- TReplQuoter::QuoteMessage(quoter, std::make_unique<IEventHandle>(Ctx->PDiskCtx->PDiskId, SelfId(),
- msg.release(), 0, 0, nullptr, TraceId.SeparateBranch()), it->Part.Size);
-
+
+ // send request
+ TReplQuoter::QuoteMessage(quoter, std::make_unique<IEventHandle>(Ctx->PDiskCtx->PDiskId, SelfId(),
+ msg.release(), 0, 0, nullptr, TraceId.SeparateBranch()), it->Part.Size);
+
Counter++;
}
}
@@ -62,38 +62,38 @@ namespace NKikimr {
VDISKP(Ctx->VCtx->VDiskLogPrefix, "GLUEREAD FINISHED(%p): actualReadN# %" PRIu32
" origReadN# %" PRIu32, this, ui32(Result->GlueReads.size()),
ui32(Result->DiskDataItemPtrs.size())));
- ctx.Send(NotifyID, new TEvents::TEvCompleted(), 0, 0, std::move(TraceId));
+ ctx.Send(NotifyID, new TEvents::TEvCompleted(), 0, 0, std::move(TraceId));
Die(ctx);
}
void Handle(NPDisk::TEvChunkReadResult::TPtr &ev, const TActorContext &ctx) {
TString message;
- const NKikimrProto::EReplyStatus status = ev->Get()->Status;
- if (status != NKikimrProto::OK) {
- TStringStream str;
- str << "{TEvChunkReadResult# " << ev->Get()->ToString() << " GlueReads# [";
+ const NKikimrProto::EReplyStatus status = ev->Get()->Status;
+ if (status != NKikimrProto::OK) {
+ TStringStream str;
+ str << "{TEvChunkReadResult# " << ev->Get()->ToString() << " GlueReads# [";
for (auto it = Result->GlueReads.begin(); it != Result->GlueReads.end(); ++it) {
str << (it != Result->GlueReads.begin() ? " " : "") << it->Part.ToString();
- }
- str << "] OrigEv# " << Ctx->OrigEv->Get()->ToString() << " DataItems# [";
+ }
+ str << "] OrigEv# " << Ctx->OrigEv->Get()->ToString() << " DataItems# [";
for (auto it = Result->DataItems.begin(); it != Result->DataItems.end(); ++it) {
str << (it != Result->DataItems.begin() ? " " : "") << it->ToString();
- }
- str << "]}";
- message = str.Str();
- }
- if (status != NKikimrProto::CORRUPTED) {
- CHECK_PDISK_RESPONSE_MSG(Ctx->VCtx, ev, ctx, message);
- }
+ }
+ str << "]}";
+ message = str.Str();
+ }
+ if (status != NKikimrProto::CORRUPTED) {
+ CHECK_PDISK_RESPONSE_MSG(Ctx->VCtx, ev, ctx, message);
+ }
NPDisk::TEvChunkReadResult *msg = ev->Get();
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &TraceId, EvChunkReadResultReceived, YardCookie = msg->Cookie,
- MergedNode = std::move(ev->TraceId));
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &TraceId, EvChunkReadResultReceived, YardCookie = msg->Cookie,
+ MergedNode = std::move(ev->TraceId));
- TGlueRead *glueRead = static_cast<TGlueRead *>(msg->Cookie);
+ TGlueRead *glueRead = static_cast<TGlueRead *>(msg->Cookie);
glueRead->Data = std::move(msg->Data);
- glueRead->Success = status == NKikimrProto::OK;
-
+ glueRead->Success = status == NKikimrProto::OK;
+
Counter--;
if (Counter == 0)
Finish(ctx);
@@ -104,44 +104,44 @@ namespace NKikimr {
TThis::Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NPDisk::TEvChunkReadResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NPDisk::TEvChunkReadResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_READ_BATCHER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_READ_BATCHER;
}
TTReadBatcherActor(
TReadBatcherCtxPtr ctx,
const TActorId notifyID,
- std::shared_ptr<TReadBatcherResult> result,
+ std::shared_ptr<TReadBatcherResult> result,
ui8 priority,
- NWilson::TTraceId traceId,
- bool isRepl)
+ NWilson::TTraceId traceId,
+ bool isRepl)
: TActorBootstrapped<TTReadBatcherActor>()
, Ctx(ctx)
, NotifyID(notifyID)
, Result(std::move(result))
, Priority(priority)
- , TraceId(std::move(traceId))
- , IsRepl(isRepl)
+ , TraceId(std::move(traceId))
+ , IsRepl(isRepl)
{}
};
IActor *CreateReadBatcherActor(
TReadBatcherCtxPtr ctx,
const TActorId notifyID,
- std::shared_ptr<TReadBatcherResult> result,
+ std::shared_ptr<TReadBatcherResult> result,
ui8 priority,
- NWilson::TTraceId traceId,
- bool isRepl)
+ NWilson::TTraceId traceId,
+ bool isRepl)
{
- return new TTReadBatcherActor(ctx, notifyID, result, priority, std::move(traceId), isRepl);
+ return new TTReadBatcherActor(ctx, notifyID, result, priority, std::move(traceId), isRepl);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_readactor.h b/ydb/core/blobstorage/vdisk/query/query_readactor.h
index 614625ee8b3..4ce94c3a0af 100644
--- a/ydb/core/blobstorage/vdisk/query/query_readactor.h
+++ b/ydb/core/blobstorage/vdisk/query/query_readactor.h
@@ -8,10 +8,10 @@ namespace NKikimr {
IActor *CreateReadBatcherActor(
TReadBatcherCtxPtr ctx,
const TActorId notifyID,
- std::shared_ptr<TReadBatcherResult> result,
+ std::shared_ptr<TReadBatcherResult> result,
ui8 priority,
- NWilson::TTraceId traceId,
- bool isRepl);
+ NWilson::TTraceId traceId,
+ bool isRepl);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_readbatch.cpp b/ydb/core/blobstorage/vdisk/query/query_readbatch.cpp
index a883191f156..a00ba3a5902 100644
--- a/ydb/core/blobstorage/vdisk/query/query_readbatch.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_readbatch.cpp
@@ -31,89 +31,89 @@ namespace NKikimr {
QueryPartId = queryPartId;
QueryShift = queryShift;
QuerySize = querySize;
- FoundDiskItems.clear();
- FoundInMemItems.clear();
+ FoundDiskItems.clear();
+ FoundInMemItems.clear();
}
// We have data on disk
void TReadBatcher::operator () (const TDiskPart &data, NMatrix::TVectorType parts) {
Y_VERIFY_DEBUG(Traversing);
- FoundDiskItems.emplace_back(data, parts);
- }
-
- void TReadBatcher::ProcessFoundDiskItem(const TDiskPart &data, NMatrix::TVectorType parts) {
- if (QueryPartId && !parts.Get(QueryPartId - 1)) {
- return; // we have no requested part here
- }
- ui32 partOffs = data.Offset + TDiskBlob::HeaderSize; // current part offset in the data chunk
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- const TLogoBlobID partId(CurID, i + 1);
- const ui32 partSize = Ctx->VCtx->Top->GType.PartSize(partId);
- if (QueryPartId == 0 || QueryPartId == i + 1) {
- FoundAnything = true;
- auto& tmpItem = TmpItems[i];
- if ((QueryShift >= partSize && partSize) || QuerySize > partSize - QueryShift) {
- tmpItem.UpdateWithError(partId, Cookie);
- } else if (tmpItem.ShouldUpdateWithDisk()) {
- const ui32 size = QuerySize ? QuerySize : partSize - QueryShift;
- if (!size) { // for metadata reads
- tmpItem.UpdateWithMemItem(partId, Cookie, TRope());
+ FoundDiskItems.emplace_back(data, parts);
+ }
+
+ void TReadBatcher::ProcessFoundDiskItem(const TDiskPart &data, NMatrix::TVectorType parts) {
+ if (QueryPartId && !parts.Get(QueryPartId - 1)) {
+ return; // we have no requested part here
+ }
+ ui32 partOffs = data.Offset + TDiskBlob::HeaderSize; // current part offset in the data chunk
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ const TLogoBlobID partId(CurID, i + 1);
+ const ui32 partSize = Ctx->VCtx->Top->GType.PartSize(partId);
+ if (QueryPartId == 0 || QueryPartId == i + 1) {
+ FoundAnything = true;
+ auto& tmpItem = TmpItems[i];
+ if ((QueryShift >= partSize && partSize) || QuerySize > partSize - QueryShift) {
+ tmpItem.UpdateWithError(partId, Cookie);
+ } else if (tmpItem.ShouldUpdateWithDisk()) {
+ const ui32 size = QuerySize ? QuerySize : partSize - QueryShift;
+ if (!size) { // for metadata reads
+ tmpItem.UpdateWithMemItem(partId, Cookie, TRope());
} else {
- tmpItem.UpdateWithDiskItem(partId, Cookie, TDiskPart(data.ChunkIdx, partOffs + QueryShift, size));
+ tmpItem.UpdateWithDiskItem(partId, Cookie, TDiskPart(data.ChunkIdx, partOffs + QueryShift, size));
}
}
}
- partOffs += partSize;
+ partOffs += partSize;
}
}
// We have diskBlob in memory
void TReadBatcher::operator () (const TDiskBlob &diskBlob) {
Y_VERIFY_DEBUG(Traversing);
- FoundInMemItems.push_back(diskBlob);
- }
-
- void TReadBatcher::ProcessFoundInMemItem(const TDiskBlob &diskBlob) {
+ FoundInMemItems.push_back(diskBlob);
+ }
+
+ void TReadBatcher::ProcessFoundInMemItem(const TDiskBlob &diskBlob) {
if (QueryPartId == 0 || diskBlob.GetParts().Get(QueryPartId - 1)) {
// put data item iff we gather all parts OR we need a concrete part and parts contain it
for (TDiskBlob::TPartIterator it = diskBlob.begin(), e = diskBlob.end(); it != e; ++it) {
- const ui8 partId = it.GetPartId();
+ const ui8 partId = it.GetPartId();
Y_VERIFY(partId > 0);
- const TLogoBlobID blobId(CurID, partId);
- const ui32 partSize = diskBlob.GetPartSize(partId - 1);
- Y_VERIFY(partSize == Ctx->VCtx->Top->GType.PartSize(blobId));
- if (QueryPartId == 0 || QueryPartId == partId) {
+ const TLogoBlobID blobId(CurID, partId);
+ const ui32 partSize = diskBlob.GetPartSize(partId - 1);
+ Y_VERIFY(partSize == Ctx->VCtx->Top->GType.PartSize(blobId));
+ if (QueryPartId == 0 || QueryPartId == partId) {
FoundAnything = true;
- auto& item = TmpItems[partId - 1];
- if ((QueryShift >= partSize && partSize) || QuerySize > partSize - QueryShift) {
- item.UpdateWithError(blobId, Cookie);
- } else if (item.ShouldUpdateWithMem()) {
- const ui32 size = QuerySize ? QuerySize : partSize - QueryShift;
- TRope temp;
- item.UpdateWithMemItem(blobId, Cookie, it.GetPart(QueryShift, size, &temp));
+ auto& item = TmpItems[partId - 1];
+ if ((QueryShift >= partSize && partSize) || QuerySize > partSize - QueryShift) {
+ item.UpdateWithError(blobId, Cookie);
+ } else if (item.ShouldUpdateWithMem()) {
+ const ui32 size = QuerySize ? QuerySize : partSize - QueryShift;
+ TRope temp;
+ item.UpdateWithMemItem(blobId, Cookie, it.GetPart(QueryShift, size, &temp));
}
- }
- }
+ }
+ }
}
}
// Finish data traverse for a single key
- void TReadBatcher::FinishTraverse(const TIngress &ingress) {
+ void TReadBatcher::FinishTraverse(const TIngress &ingress) {
Y_VERIFY_DEBUG(Traversing);
Traversing = false;
- // process found items; first, we process disk items; then, we process in-mem items that may possibly
- // overwrite disk ones to prevent read IOPS
- for (const std::tuple<TDiskPart, NMatrix::TVectorType> &diskItem : FoundDiskItems) {
- ProcessFoundDiskItem(std::get<0>(diskItem), std::get<1>(diskItem));
- }
- for (const TDiskBlob &diskBlob : FoundInMemItems) {
- ProcessFoundInMemItem(diskBlob);
+ // process found items; first, we process disk items; then, we process in-mem items that may possibly
+ // overwrite disk ones to prevent read IOPS
+ for (const std::tuple<TDiskPart, NMatrix::TVectorType> &diskItem : FoundDiskItems) {
+ ProcessFoundDiskItem(std::get<0>(diskItem), std::get<1>(diskItem));
}
+ for (const TDiskBlob &diskBlob : FoundInMemItems) {
+ ProcessFoundInMemItem(diskBlob);
+ }
// NOTE: we may have parts that are not replicated yet;
- // we MUST NOT return NO_DATA for them; but when parts are missing due to finished GC, we report NODATA
- NMatrix::TVectorType mustHave = ingress.PartsWeMustHaveLocally(Ctx->VCtx->Top.get(),
+ // we MUST NOT return NO_DATA for them; but when parts are missing due to finished GC, we report NODATA
+ NMatrix::TVectorType mustHave = ingress.PartsWeMustHaveLocally(Ctx->VCtx->Top.get(),
Ctx->VCtx->ShortSelfVDisk, CurID);
NMatrix::TVectorType actuallyHave = ingress.LocalParts(Ctx->VCtx->Top->GType);
NMatrix::TVectorType missingParts = mustHave - actuallyHave;
@@ -127,7 +127,7 @@ namespace NKikimr {
}
// We don't have found any data at all, we even don't have unreplicated parts
- if (FoundAnything) {
+ if (FoundAnything) {
// setup DataItems and read requests finally
for (auto &x : TmpItems) {
if (!x.Empty()) {
@@ -138,16 +138,16 @@ namespace NKikimr {
}
}
}
- } else {
- PutNoData(TLogoBlobID(CurID, QueryPartId), ingress, Cookie);
+ } else {
+ PutNoData(TLogoBlobID(CurID, QueryPartId), ingress, Cookie);
}
}
- void TReadBatcher::AbortTraverse() {
- Y_VERIFY_DEBUG(Traversing);
- Traversing = false;
- }
-
+ void TReadBatcher::AbortTraverse() {
+ Y_VERIFY_DEBUG(Traversing);
+ Traversing = false;
+ }
+
TGlueRead *TReadBatcher::AddGlueRead(TDataItem *item) {
Result->GlueReads.push_back(TGlueRead(item->ActualRead));
item->SetGlueReqIdx(Result->GlueReads.size() - 1);
@@ -220,29 +220,29 @@ namespace NKikimr {
IActor *TReadBatcher::CreateAsyncDataReader(const TActorId &notifyID,
ui8 priority,
- NWilson::TTraceId traceId,
- bool isRepl) {
+ NWilson::TTraceId traceId,
+ bool isRepl) {
if (Result->DiskDataItemPtrs.empty())
return nullptr;
else {
// prepare read plan
PrepareReadPlan();
Y_VERIFY_DEBUG(!Result->GlueReads.empty());
- // evaluate total read size
- const ui32 blockSize = Ctx->PDiskCtx->Dsk->AppendBlockSize;
- for (const auto& item : Result->GlueReads) {
- const auto& part = item.Part;
- // adjust offset to append block size value
- ui32 size = part.Size;
- size += part.Offset % blockSize; // adjust read to the beginning of the block
- if (const ui32 rem = size % blockSize) {
- size += blockSize - rem; // adjust read to the end of the block
- }
- // count calculated size in blocks
- PDiskReadBytes += size;
- }
+ // evaluate total read size
+ const ui32 blockSize = Ctx->PDiskCtx->Dsk->AppendBlockSize;
+ for (const auto& item : Result->GlueReads) {
+ const auto& part = item.Part;
+ // adjust offset to append block size value
+ ui32 size = part.Size;
+ size += part.Offset % blockSize; // adjust read to the beginning of the block
+ if (const ui32 rem = size % blockSize) {
+ size += blockSize - rem; // adjust read to the end of the block
+ }
+ // count calculated size in blocks
+ PDiskReadBytes += size;
+ }
// start reader
- return CreateReadBatcherActor(Ctx, notifyID, Result, priority, std::move(traceId), isRepl);
+ return CreateReadBatcherActor(Ctx, notifyID, Result, priority, std::move(traceId), isRepl);
}
}
diff --git a/ydb/core/blobstorage/vdisk/query/query_readbatch.h b/ydb/core/blobstorage/vdisk/query/query_readbatch.h
index b0592a9a202..0bcb3b184a1 100644
--- a/ydb/core/blobstorage/vdisk/query/query_readbatch.h
+++ b/ydb/core/blobstorage/vdisk/query/query_readbatch.h
@@ -21,8 +21,8 @@ namespace NKikimr {
TDiskPart Part;
// data we get from disk
TBufferWithGaps Data;
- // was it read successfully?
- bool Success = false;
+ // was it read successfully?
+ bool Success = false;
TGlueRead(const TDiskPart &part)
: Part(part)
@@ -30,8 +30,8 @@ namespace NKikimr {
{}
};
- struct TReadError {};
-
+ struct TReadError {};
+
using TGlueReads = TDeque<TGlueRead>;
////////////////////////////////////////////////////////////////////////////////////
@@ -56,27 +56,27 @@ namespace NKikimr {
// disk
TDiskPart ActualRead; // actual read from disk for this item
// mem
- TRope MemData; // found data in memory
-
- // extra found disk items for the case when ActualRead fails by disk corruption
- std::vector<TDiskPart> ExtraDiskItems;
+ TRope MemData; // found data in memory
+ // extra found disk items for the case when ActualRead fails by disk corruption
+ std::vector<TDiskPart> ExtraDiskItems;
+
public:
TString ToString() const {
- TStringStream str;
- str << "{Type# ";
- switch (Type) {
- case ET_CLEAN: str << "ET_CLEAN"; break;
- case ET_SETDISK: str << "ET_SETDISK"; break;
- case ET_SETMEM: str << "ET_SETMEM"; break;
- case ET_NODATA: str << "ET_NODATA"; break;
- case ET_ERROR: str << "ET_ERROR"; break;
+ TStringStream str;
+ str << "{Type# ";
+ switch (Type) {
+ case ET_CLEAN: str << "ET_CLEAN"; break;
+ case ET_SETDISK: str << "ET_SETDISK"; break;
+ case ET_SETMEM: str << "ET_SETMEM"; break;
+ case ET_NODATA: str << "ET_NODATA"; break;
+ case ET_ERROR: str << "ET_ERROR"; break;
case ET_NOT_YET: str << "ET_NOT_YET"; break;
- }
- str << " Id# " << Id.ToString() << " ActualRead# " << ActualRead.ToString() << "}";
- return str.Str();
- }
-
+ }
+ str << " Id# " << Id.ToString() << " ActualRead# " << ActualRead.ToString() << "}";
+ return str.Str();
+ }
+
// def constructor
TDataItem()
{
@@ -91,8 +91,8 @@ namespace NKikimr {
Ingress = TIngress();
GlueReqIdx = (ui32(-1));
ActualRead.Clear();
- MemData = {};
- ExtraDiskItems.clear();
+ MemData = {};
+ ExtraDiskItems.clear();
}
// Set NO_DATA
@@ -118,10 +118,10 @@ namespace NKikimr {
// Update with disk data
void UpdateWithDiskItem(const TLogoBlobID &id, void *cookie, const TDiskPart &actualRead) {
- if (Type == ET_SETDISK) { // add backup copy of data for the case when main reads as CORRUPTED
- ExtraDiskItems.push_back(ActualRead);
- }
-
+ if (Type == ET_SETDISK) { // add backup copy of data for the case when main reads as CORRUPTED
+ ExtraDiskItems.push_back(ActualRead);
+ }
+
Type = ET_SETDISK;
Id = id;
Cookie = cookie;
@@ -130,15 +130,15 @@ namespace NKikimr {
}
// Update with mem data
- void UpdateWithMemItem(const TLogoBlobID &id, void *cookie, TRope data) {
+ void UpdateWithMemItem(const TLogoBlobID &id, void *cookie, TRope data) {
Type = ET_SETMEM;
Id = id;
Cookie = cookie;
////// clear disk
ActualRead.Clear();
- ExtraDiskItems.clear();
+ ExtraDiskItems.clear();
////// set mem
- MemData = std::move(data);
+ MemData = std::move(data);
}
void SetIngress(const TIngress &ingress) {
@@ -151,7 +151,7 @@ namespace NKikimr {
bool ShouldUpdateWithDisk() const {
Y_VERIFY_DEBUG(Type == ET_CLEAN || Type == ET_SETDISK || Type == ET_SETMEM);
- return Type == ET_CLEAN || Type == ET_SETDISK;
+ return Type == ET_CLEAN || Type == ET_SETDISK;
}
bool ShouldUpdateWithMem() const {
@@ -171,30 +171,30 @@ namespace NKikimr {
GlueReqIdx = idx;
}
- template<typename TProcessor>
- void GetData(const TGlueReads &glueReads, TProcessor&& processor) const {
- Y_VERIFY_DEBUG(Type == ET_SETDISK || Type == ET_SETMEM);
-
- if (Type == ET_SETMEM) {
- processor(MemData);
- } else {
- Y_VERIFY_DEBUG(GlueReqIdx != (ui32)-1);
- const TGlueRead &glue = glueReads[GlueReqIdx];
-
- Y_VERIFY_DEBUG(glue.Part.ChunkIdx == ActualRead.ChunkIdx &&
- glue.Part.Offset <= ActualRead.Offset &&
- (ActualRead.Offset + ActualRead.Size) <= (glue.Part.Offset + glue.Part.Size));
-
- if (glue.Success) {
- const char *ptr = glue.Data.DataPtr<const char>(ActualRead.Offset - glue.Part.Offset, ActualRead.Size);
- const size_t size = ActualRead.Size;
- processor(ptr, size);
- } else {
- processor(TReadError());
- }
- }
- }
-
+ template<typename TProcessor>
+ void GetData(const TGlueReads &glueReads, TProcessor&& processor) const {
+ Y_VERIFY_DEBUG(Type == ET_SETDISK || Type == ET_SETMEM);
+
+ if (Type == ET_SETMEM) {
+ processor(MemData);
+ } else {
+ Y_VERIFY_DEBUG(GlueReqIdx != (ui32)-1);
+ const TGlueRead &glue = glueReads[GlueReqIdx];
+
+ Y_VERIFY_DEBUG(glue.Part.ChunkIdx == ActualRead.ChunkIdx &&
+ glue.Part.Offset <= ActualRead.Offset &&
+ (ActualRead.Offset + ActualRead.Size) <= (glue.Part.Offset + glue.Part.Size));
+
+ if (glue.Success) {
+ const char *ptr = glue.Data.DataPtr<const char>(ActualRead.Offset - glue.Part.Offset, ActualRead.Size);
+ const size_t size = ActualRead.Size;
+ processor(ptr, size);
+ } else {
+ processor(TReadError());
+ }
+ }
+ }
+
static bool DiskPartLess(const TDataItem *x, const TDataItem *y) {
Y_VERIFY_DEBUG(x->ActualRead.Size && y->ActualRead.Size); // compare items with non-null Part only
return x->ActualRead < y->ActualRead;
@@ -252,9 +252,9 @@ namespace NKikimr {
}
// FIXME: refactor
- template<typename TProcessor>
- void GetData(TProcessor&& processor) const {
- Cur->GetData(Rbr->GlueReads, std::forward<TProcessor>(processor));
+ template<typename TProcessor>
+ void GetData(TProcessor&& processor) const {
+ Cur->GetData(Rbr->GlueReads, std::forward<TProcessor>(processor));
}
private:
@@ -290,7 +290,7 @@ namespace NKikimr {
public:
TReadBatcher(TReadBatcherCtxPtr ctx)
: Ctx(ctx)
- , Result(std::make_shared<TReadBatcherResult>())
+ , Result(std::make_shared<TReadBatcherResult>())
{
Y_VERIFY_DEBUG(Ctx->VCtx->Top->GType.TotalPartCount() <= MaxTotalPartCount);
TmpItems.resize(Ctx->VCtx->Top->GType.TotalPartCount());
@@ -308,31 +308,31 @@ namespace NKikimr {
// We have data on disk
void operator () (const TDiskPart &data, NMatrix::TVectorType parts);
- void ProcessFoundDiskItem(const TDiskPart &data, NMatrix::TVectorType parts);
+ void ProcessFoundDiskItem(const TDiskPart &data, NMatrix::TVectorType parts);
// We have diskBlob in memory
void operator () (const TDiskBlob &diskBlob);
- void ProcessFoundInMemItem(const TDiskBlob &diskBlob);
+ void ProcessFoundInMemItem(const TDiskBlob &diskBlob);
// Finish data traverse for a single key
- void FinishTraverse(const TIngress &ingress);
- // Abort traverse without giving out results
- void AbortTraverse();
-
+ void FinishTraverse(const TIngress &ingress);
+ // Abort traverse without giving out results
+ void AbortTraverse();
- void PutNoData(const TLogoBlobID &id, const TMaybe<TIngress> &ingress, void *cookie) {
+
+ void PutNoData(const TLogoBlobID &id, const TMaybe<TIngress> &ingress, void *cookie) {
NReadBatcher::TDataItem item;
item.UpdateWithNoData(id, cookie);
- if (ingress) {
- item.SetIngress(*ingress);
- }
+ if (ingress) {
+ item.SetIngress(*ingress);
+ }
Result->DataItems.push_back(item);
}
// creates an actor for efficient async data reads, returns nullptr
// if no read required
- IActor *CreateAsyncDataReader(const TActorId &notifyID, ui8 priority, NWilson::TTraceId traceId, bool isRepl);
+ IActor *CreateAsyncDataReader(const TActorId &notifyID, ui8 priority, NWilson::TTraceId traceId, bool isRepl);
const TReadBatcherResult &GetResult() const { return *Result; }
- ui64 GetPDiskReadBytes() const { return PDiskReadBytes; }
+ ui64 GetPDiskReadBytes() const { return PDiskReadBytes; }
private:
TReadBatcherCtxPtr Ctx;
@@ -347,12 +347,12 @@ namespace NKikimr {
ui32 QueryShift = 0;
ui32 QuerySize = 0;
// final result
- std::shared_ptr<TReadBatcherResult> Result;
- ui64 PDiskReadBytes = 0;
-
- TStackVec<std::tuple<TDiskPart, NMatrix::TVectorType>, MaxTotalPartCount> FoundDiskItems;
- TStackVec<TDiskBlob, MaxTotalPartCount> FoundInMemItems;
+ std::shared_ptr<TReadBatcherResult> Result;
+ ui64 PDiskReadBytes = 0;
+ TStackVec<std::tuple<TDiskPart, NMatrix::TVectorType>, MaxTotalPartCount> FoundDiskItems;
+ TStackVec<TDiskBlob, MaxTotalPartCount> FoundInMemItems;
+
NReadBatcher::TGlueRead *AddGlueRead(NReadBatcher::TDataItem *item);
void PrepareReadPlan();
TString DiskDataItemsToString() const;
diff --git a/ydb/core/blobstorage/vdisk/query/query_spacetracker.h b/ydb/core/blobstorage/vdisk/query/query_spacetracker.h
index 374107424c7..a0c290277b6 100644
--- a/ydb/core/blobstorage/vdisk/query/query_spacetracker.h
+++ b/ydb/core/blobstorage/vdisk/query/query_spacetracker.h
@@ -28,7 +28,7 @@ namespace NKikimr {
void AddAllPartsOfLogoBlob(const TBlobStorageGroupType &type, TLogoBlobID blobId) {
for (ui32 partIdx = 0; partIdx < type.TotalPartCount(); ++partIdx) {
AddLogoBlobIndex();
- AddLogoBlobData(type.PartSize(TLogoBlobID(blobId, partIdx + 1)), 0, 0);
+ AddLogoBlobData(type.PartSize(TLogoBlobID(blobId, partIdx + 1)), 0, 0);
}
}
diff --git a/ydb/core/blobstorage/vdisk/query/query_statalgo.h b/ydb/core/blobstorage/vdisk/query/query_statalgo.h
index e7c99e3fbdf..b92d4d93f13 100644
--- a/ydb/core/blobstorage/vdisk/query/query_statalgo.h
+++ b/ydb/core/blobstorage/vdisk/query/query_statalgo.h
@@ -128,11 +128,11 @@ namespace NKikimr {
CurKey = curKey;
}
- void AddFromFresh(const TMemRec& memRec, const TRope* /*data*/, const TKey& key, ui64 /*lsn*/) {
+ void AddFromFresh(const TMemRec& memRec, const TRope* /*data*/, const TKey& key, ui64 /*lsn*/) {
Y_VERIFY(key == CurKey);
if (!Constraint || Constraint->Check(CurKey)) {
auto mr = memRec.ToString(HullCtx->IngressCache.Get(), nullptr);
- auto ing = IngressToString(HullCtx->VCtx->Top.get(), HullCtx->VCtx->ShortSelfVDisk, CurKey, memRec);
+ auto ing = IngressToString(HullCtx->VCtx->Top.get(), HullCtx->VCtx->ShortSelfVDisk, CurKey, memRec);
Str << Prefix
<< Marker
<< " Key: " << CurKey.ToString()
@@ -155,58 +155,58 @@ namespace NKikimr {
void DumpFreshSegment(TCountingOutput &str,
TMaybe<typename TFreshSegmentSnapshot::TForwardIterator>& it,
- const char *marker) {
- if (!it) {
+ const char *marker) {
+ if (!it) {
return;
- }
+ }
TDumpRecordMerger merger(str, marker, HullCtx, Prefix, Constraint);
- while (it->Valid()) {
+ while (it->Valid()) {
// check limit
if (str.Counter() >= LimitInBytes) {
return;
}
- merger.SetCurKey(it->GetCurKey());
- it->PutToMerger(&merger);
+ merger.SetCurKey(it->GetCurKey());
+ it->PutToMerger(&merger);
merger.Finish();
merger.Clear();
- it->Next();
+ it->Next();
}
- it.Clear();
- }
-
- void DumpFresh(TCountingOutput &str) {
- DumpFreshSegment(str, FCurIt, "FCur");
- DumpFreshSegment(str, FDregIt, "FDreg");
- DumpFreshSegment(str, FOldIt, "FOld");
+ it.Clear();
}
- // move SstIt/MemIt to next valid item; on exit either SstIt and MemIt are valid, nor SstIt is not valid
- void AdjustMemIt() {
- while (SstIt->Valid()) {
- TLevelSstPtr p = SstIt->Get();
- MemIt = TMemIterator(p.SstPtr.Get());
- MemIt->SeekToFirst();
- if (MemIt->Valid()) {
- break;
- } else {
- SstIt->Next();
- }
- }
+ void DumpFresh(TCountingOutput &str) {
+ DumpFreshSegment(str, FCurIt, "FCur");
+ DumpFreshSegment(str, FDregIt, "FDreg");
+ DumpFreshSegment(str, FOldIt, "FOld");
}
- void DumpLevels(TCountingOutput &str) {
- while (SstIt->Valid()) {
- const auto& p = SstIt->Get();
- while (MemIt->Valid()) {
+ // move SstIt/MemIt to next valid item; on exit either SstIt and MemIt are valid, nor SstIt is not valid
+ void AdjustMemIt() {
+ while (SstIt->Valid()) {
+ TLevelSstPtr p = SstIt->Get();
+ MemIt = TMemIterator(p.SstPtr.Get());
+ MemIt->SeekToFirst();
+ if (MemIt->Valid()) {
+ break;
+ } else {
+ SstIt->Next();
+ }
+ }
+ }
+
+ void DumpLevels(TCountingOutput &str) {
+ while (SstIt->Valid()) {
+ const auto& p = SstIt->Get();
+ while (MemIt->Valid()) {
// check limit
if (str.Counter() >= LimitInBytes) {
return;
}
- const auto& c = *MemIt;
+ const auto& c = *MemIt;
if (!Constraint || Constraint->Check(c->Key)) {
auto mr = c->MemRec.ToString(HullCtx->IngressCache.Get(), c.GetSstPtr()->GetOutbound());
- auto ing = IngressToString(HullCtx->VCtx->Top.get(), HullCtx->VCtx->ShortSelfVDisk,
+ auto ing = IngressToString(HullCtx->VCtx->Top.get(), HullCtx->VCtx->ShortSelfVDisk,
c->Key, c->MemRec);
str << Prefix
<< "L: " << p.Level
@@ -216,10 +216,10 @@ namespace NKikimr {
<< " MemRec: " << mr
<< "\n";
}
- MemIt->Next();
+ MemIt->Next();
}
- SstIt->Next();
- AdjustMemIt();
+ SstIt->Next();
+ AdjustMemIt();
}
}
@@ -246,7 +246,7 @@ namespace NKikimr {
, LimitInBytes(limitInBytes)
, Prefix(prefix)
, Constraint(constraint)
- {
+ {
FCurIt.ConstructInPlace(HullCtx, &Snapshot.FreshSnap.Cur);
FCurIt->SeekToFirst();
FDregIt.ConstructInPlace(HullCtx, &Snapshot.FreshSnap.Dreg);
@@ -254,10 +254,10 @@ namespace NKikimr {
FOldIt.ConstructInPlace(HullCtx, &Snapshot.FreshSnap.Old);
FOldIt->SeekToFirst();
- SstIt.ConstructInPlace(&Snapshot.SliceSnap);
- SstIt->SeekToFirst();
- AdjustMemIt();
- }
+ SstIt.ConstructInPlace(&Snapshot.SliceSnap);
+ SstIt->SeekToFirst();
+ AdjustMemIt();
+ }
enum class EDumpRes {
OK = 0,
@@ -274,10 +274,10 @@ namespace NKikimr {
return (countedStr.Counter() >= LimitInBytes) ? EDumpRes::Limited : EDumpRes::OK;
}
- bool Done() const {
- return !FCurIt && !FDregIt && !FOldIt && !SstIt->Valid();
- }
-
+ bool Done() const {
+ return !FCurIt && !FDregIt && !FOldIt && !SstIt->Valid();
+ }
+
private:
TIntrusivePtr<THullCtx> HullCtx;
TLevelIndexSnapshot Snapshot;
@@ -287,11 +287,11 @@ namespace NKikimr {
const TString Prefix;
// We may dump using this constraint (only specific tabletId and channel)
const TMaybe<TConstraint> Constraint;
-
- // Reentrant state
+
+ // Reentrant state
TMaybe<typename TFreshSegmentSnapshot::TForwardIterator> FCurIt, FDregIt, FOldIt;
- TMaybe<TSstIterator> SstIt;
- TMaybe<TMemIterator> MemIt;
+ TMaybe<TSstIterator> SstIt;
+ TMaybe<TMemIterator> MemIt;
};
template <>
diff --git a/ydb/core/blobstorage/vdisk/query/query_statdb.cpp b/ydb/core/blobstorage/vdisk/query/query_statdb.cpp
index 65bded589f7..f7e5c3c4824 100644
--- a/ydb/core/blobstorage/vdisk/query/query_statdb.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_statdb.cpp
@@ -9,9 +9,9 @@ namespace NKikimr {
namespace {
- const char *ByteSuffix[] = {"B", "KiB", "MiB", "GiB", nullptr};
- const char *ItemSuffix[] = {"", "K", "M", "G", nullptr};
-
+ const char *ByteSuffix[] = {"B", "KiB", "MiB", "GiB", nullptr};
+ const char *ItemSuffix[] = {"", "K", "M", "G", nullptr};
+
///////////////////////////////////////////////////////////////////////////////
// TChannelInfo
///////////////////////////////////////////////////////////////////////////////
@@ -48,12 +48,12 @@ namespace NKikimr {
HTML(str) {
if (pretty) {
- TABLED_ATTRS({{"data-text", Sprintf("%" PRIu64, Num)}, {"align", "right"}}) { SMALL() {
- FormatHumanReadable(str, Num, 1000, 2, ItemSuffix);
- }}
- TABLED_ATTRS({{"data-text", Sprintf("%" PRIu64, DataSize)}, {"align", "right"}}) { SMALL() {
- FormatHumanReadable(str, DataSize, 1024, 2, ByteSuffix);
- }}
+ TABLED_ATTRS({{"data-text", Sprintf("%" PRIu64, Num)}, {"align", "right"}}) { SMALL() {
+ FormatHumanReadable(str, Num, 1000, 2, ItemSuffix);
+ }}
+ TABLED_ATTRS({{"data-text", Sprintf("%" PRIu64, DataSize)}, {"align", "right"}}) { SMALL() {
+ FormatHumanReadable(str, DataSize, 1024, 2, ByteSuffix);
+ }}
} else {
TABLED() {SMALL() {str << Num;}}
TABLED() {SMALL() {str << DataSize;}}
diff --git a/ydb/core/blobstorage/vdisk/query/query_statdb.h b/ydb/core/blobstorage/vdisk/query/query_statdb.h
index 67aa2aeec54..4396f5c2786 100644
--- a/ydb/core/blobstorage/vdisk/query/query_statdb.h
+++ b/ydb/core/blobstorage/vdisk/query/query_statdb.h
@@ -28,7 +28,7 @@ namespace NKikimr {
const bool prettyPrint = Ev->Get()->Record.GetPrettyPrint();
CalculateStat(str, prettyPrint);
Result->SetResult(str.Str());
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, Ev->Cookie);
ctx.Send(ParentId, new TEvents::TEvActorDied);
TThis::Die(ctx);
}
@@ -36,8 +36,8 @@ namespace NKikimr {
void CalculateStat(IOutputStream &str, bool pretty);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
}
TLevelIndexStatActor(
@@ -45,13 +45,13 @@ namespace NKikimr {
const TActorId &parentId,
TLevelIndexSnapshot &&snapshot,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
: TActorBootstrapped<TThis>()
, HullCtx(hullCtx)
, ParentId(parentId)
, Snapshot(std::move(snapshot))
, Ev(ev)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
private:
@@ -59,7 +59,7 @@ namespace NKikimr {
const TActorId ParentId;
TLevelIndexSnapshot Snapshot;
TEvBlobStorage::TEvVDbStat::TPtr Ev;
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_stathuge.cpp b/ydb/core/blobstorage/vdisk/query/query_stathuge.cpp
index e4f14dba802..6903b83a6b6 100644
--- a/ydb/core/blobstorage/vdisk/query/query_stathuge.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_stathuge.cpp
@@ -22,7 +22,7 @@ namespace NKikimr {
CalculateUsedHugeChunks(str, prettyPrint);
Result->SetResult(str.Str());
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, 0);
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, 0);
ctx.Send(ParentId, new TEvents::TEvActorDied);
TThis::Die(ctx);
}
@@ -36,18 +36,18 @@ namespace NKikimr {
THugeStatActor(
TIntrusivePtr<THullCtx> hullCtx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
: TActorBootstrapped<THugeStatActor>()
, HullCtx(std::move(hullCtx))
, HugeBlobCtx(hugeBlobCtx)
, ParentId(parentId)
, FullSnap(std::move(fullSnap))
, Ev(ev)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
private:
@@ -55,11 +55,11 @@ namespace NKikimr {
class TAggr;
TIntrusivePtr<THullCtx> HullCtx;
- std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
const TActorId ParentId;
THullDsSnap FullSnap;
TEvBlobStorage::TEvVDbStat::TPtr Ev;
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
};
////////////////////////////////////////////////////////////////////////////
@@ -111,7 +111,7 @@ namespace NKikimr {
// slotSize -> TAggrSlotInfo
using TAggrBySlotSize = TMap<ui32, TAggrSlotInfo>;
IOutputStream &Str;
- const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
const bool Pretty;
const ui32 ChunkSize;
TPerChunkMap Map;
@@ -310,7 +310,7 @@ namespace NKikimr {
public:
TChunksMap(
IOutputStream &str,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const bool pretty,
ui32 chunkSize)
: Str(str)
@@ -349,7 +349,7 @@ namespace NKikimr {
TChunksMap ChunksMap;
public:
- TAggr(IOutputStream &str, const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx, bool pretty, ui32 chunkSize)
+ TAggr(IOutputStream &str, const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx, bool pretty, ui32 chunkSize)
: ChunksMap(str, hugeBlobCtx, pretty, chunkSize)
{}
@@ -396,12 +396,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
IActor *CreateHugeStatActor(
TIntrusivePtr<THullCtx> hullCtx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result) {
- return new THugeStatActor(std::move(hullCtx), hugeBlobCtx, parentId, std::move(fullSnap), ev, std::move(result));
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result) {
+ return new THugeStatActor(std::move(hullCtx), hugeBlobCtx, parentId, std::move(fullSnap), ev, std::move(result));
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_stathuge.h b/ydb/core/blobstorage/vdisk/query/query_stathuge.h
index eb6985db648..24feb48ed2d 100644
--- a/ydb/core/blobstorage/vdisk/query/query_stathuge.h
+++ b/ydb/core/blobstorage/vdisk/query/query_stathuge.h
@@ -12,11 +12,11 @@ namespace NKikimr {
class THugeBlobCtx;
IActor *CreateHugeStatActor(
TIntrusivePtr<THullCtx> hullCtx,
- const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
+ const std::shared_ptr<THugeBlobCtx> &hugeBlobCtx,
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result);
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_stattablet.cpp b/ydb/core/blobstorage/vdisk/query/query_stattablet.cpp
index 16e25fb1a65..e3b0e58867d 100644
--- a/ydb/core/blobstorage/vdisk/query/query_stattablet.cpp
+++ b/ydb/core/blobstorage/vdisk/query/query_stattablet.cpp
@@ -24,7 +24,7 @@ namespace NKikimr {
ProcessLogoBlobs(str, tabletId, prettyPrint);
Result->SetResult(str.Str());
- SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, 0);
+ SendVDiskResponse(ctx, Ev->Sender, Result.release(), *this, 0);
ctx.Send(ParentId, new TEvents::TEvActorDied);
TThis::Die(ctx);
}
@@ -34,21 +34,21 @@ namespace NKikimr {
void ProcessLogoBlobs(IOutputStream &str, ui64 tabletId, bool pretty);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_LEVEL_INDEX_STAT_QUERY;
}
TTabletStatActor(TIntrusivePtr<THullCtx> hullCtx,
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result)
: TActorBootstrapped<TTabletStatActor>()
, HullCtx(std::move(hullCtx))
, ParentId(parentId)
, FullSnap(std::move(fullSnap))
, Ev(ev)
- , Result(std::move(result))
+ , Result(std::move(result))
{}
private:
@@ -59,7 +59,7 @@ namespace NKikimr {
const TActorId ParentId;
THullDsSnap FullSnap;
TEvBlobStorage::TEvVDbStat::TPtr Ev;
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> Result;
};
////////////////////////////////////////////////////////////////////////////
@@ -106,14 +106,14 @@ namespace NKikimr {
ui64 TabletId;
bool Pretty;
TMapType Map;
- const TIngress::EMode IngressMode;
+ const TIngress::EMode IngressMode;
public:
- TAggr(IOutputStream &str, ui64 tabletId, bool pretty, TIngress::EMode ingressMode)
+ TAggr(IOutputStream &str, ui64 tabletId, bool pretty, TIngress::EMode ingressMode)
: Str(str)
, TabletId(tabletId)
, Pretty(pretty)
- , IngressMode(ingressMode)
+ , IngressMode(ingressMode)
{}
void UpdateFresh(const char *segName,
@@ -142,7 +142,7 @@ namespace NKikimr {
}
// have some non default flags
- int flags = memRec.GetIngress().GetCollectMode(IngressMode);
+ int flags = memRec.GetIngress().GetCollectMode(IngressMode);
if (flags & ECollectMode::CollectModeDoNotKeep) {
val.RecordsWithDoNotKeepFlags++;
} else if (flags & ECollectMode::CollectModeKeep) {
@@ -354,7 +354,7 @@ namespace NKikimr {
// TTabletStatActor::ProcessLogoBlobs
////////////////////////////////////////////////////////////////////////////
void TTabletStatActor::ProcessLogoBlobs(IOutputStream &str, ui64 tabletId, bool pretty) {
- TAggr aggr(str, tabletId, pretty, TIngress::IngressMode(HullCtx->VCtx->Top->GType));
+ TAggr aggr(str, tabletId, pretty, TIngress::IngressMode(HullCtx->VCtx->Top->GType));
TraverseDbWithoutMerge(HullCtx, &aggr, FullSnap.LogoBlobsSnap);
}
@@ -365,8 +365,8 @@ namespace NKikimr {
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result) {
- return new TTabletStatActor(std::move(hullCtx), parentId, std::move(fullSnap), ev, std::move(result));
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result) {
+ return new TTabletStatActor(std::move(hullCtx), parentId, std::move(fullSnap), ev, std::move(result));
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_stattablet.h b/ydb/core/blobstorage/vdisk/query/query_stattablet.h
index 1d6ae9e22ae..0d74ead5c59 100644
--- a/ydb/core/blobstorage/vdisk/query/query_stattablet.h
+++ b/ydb/core/blobstorage/vdisk/query/query_stattablet.h
@@ -13,6 +13,6 @@ namespace NKikimr {
const TActorId &parentId,
THullDsSnap &&fullSnap,
TEvBlobStorage::TEvVDbStat::TPtr &ev,
- std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result);
+ std::unique_ptr<TEvBlobStorage::TEvVDbStatResult> result);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/query_stream.h b/ydb/core/blobstorage/vdisk/query/query_stream.h
index 1f5236284d0..e59234fa7a3 100644
--- a/ydb/core/blobstorage/vdisk/query/query_stream.h
+++ b/ydb/core/blobstorage/vdisk/query/query_stream.h
@@ -1,322 +1,322 @@
#pragma once
-#include "defs.h"
-#include "query_statalgo.h"
+#include "defs.h"
+#include "query_statalgo.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/vdisk/hulldb/hull_ds_all_snap.h>
#include <library/cpp/streams/bzip2/bzip2.h>
-
-namespace NKikimr {
-
- class TLevelIndexStreamActor : public TActorBootstrapped<TLevelIndexStreamActor> {
- static constexpr TDuration LifetimeAfterQuery = TDuration::Seconds(30);
- static constexpr size_t BlockSize = 4 << 20;
-
- TIntrusivePtr<THullCtx> HullCtx;
- std::optional<THullDsSnap> FullSnap;
+
+namespace NKikimr {
+
+ class TLevelIndexStreamActor : public TActorBootstrapped<TLevelIndexStreamActor> {
+ static constexpr TDuration LifetimeAfterQuery = TDuration::Seconds(30);
+ static constexpr size_t BlockSize = 4 << 20;
+
+ TIntrusivePtr<THullCtx> HullCtx;
+ std::optional<THullDsSnap> FullSnap;
TActorId SkeletonId;
- const TString StreamId;
- TInstant Deadline;
- ui64 SequenceId = 1;
-
- public:
- enum class EDatabase {
- LOGOBLOBS,
- BLOCKS,
- BARRIERS,
- };
-
- enum class ETableType : ui32 {
- FCUR,
- FDREG,
- FOLD,
- LEVEL,
- };
-
-#pragma pack(push, 1)
- struct TOutputLogoBlob {
- TKeyLogoBlob Key;
- ui64 Ingress;
- };
-
- struct TOutputBlock {
- TKeyBlock Key;
- TMemRecBlock MemRec;
- };
-
- struct TOutputBarrier {
- TKeyBarrier Key;
- TMemRecBarrier MemRec;
- };
-
- struct TOutputBlockHeader {
- ui32 NumRecs;
- ui32 Database : 2;
- ui32 TableType : 2;
- ui32 Level : 6;
- ui32 Reserved : 22;
- ui64 SstId;
- };
-#pragma pack(pop)
-
- private:
- static constexpr size_t GetRecLen(EDatabase database) {
- switch (database) {
- case EDatabase::LOGOBLOBS:
- return sizeof(TOutputLogoBlob);
-
- case EDatabase::BLOCKS:
- return sizeof(TOutputBlock);
-
- case EDatabase::BARRIERS:
- return sizeof(TOutputBarrier);
- }
- }
-
- class TDumpProcessor {
- class TTableId {
- ETableType Type;
- ui32 Level = 0;
- ui64 SstId = 0;
-
- public:
- TTableId(const char *segName) {
- Y_VERIFY_DEBUG(!strcmp(segName, "FCur") || !strcmp(segName, "FDreg") || !strcmp(segName, "FOld"));
- switch (segName[1]) {
- case 'C':
- Type = ETableType::FCUR;
- break;
-
- case 'D':
- Type = ETableType::FDREG;
- break;
-
- case 'O':
- Type = ETableType::FOLD;
- break;
-
- default:
- Y_FAIL();
- }
- }
-
- template<typename T>
- TTableId(const T& sst)
- : Type(ETableType::LEVEL)
- , Level(sst.Level)
- , SstId(sst.SstPtr->AssignedSstId)
- {}
-
- ui32 GetType() const { return static_cast<ui32>(Type); }
- ui32 GetLevel() const { return Level; }
- ui64 GetSstId() const { return SstId; }
-
- friend bool operator !=(const TTableId& x, const TTableId& y) {
- return x.Type != y.Type || x.Level != y.Level || x.SstId != y.SstId;
- }
- };
-
- private:
- struct TBlock {
- EDatabase Database;
- TTableId TableId;
- char Data[65536];
- size_t Len = 0;
-
- TBlock(EDatabase database, TTableId tableId)
- : Database(database)
- , TableId(tableId)
- {}
-
- void Append(const void *data, size_t len) {
- memcpy(Data + Len, data, len);
- Len += len;
- }
-
- size_t Capacity() const {
- return sizeof(Data) - Len;
- }
-
- const void *GetData() const {
- return Data;
- }
-
- size_t GetLen() const {
- return Len;
- }
- };
-
- private:
- std::deque<TBlock> Blocks;
-
- public:
- template<typename TKey, typename TMemRec>
- void UpdateFresh(const char *segName, const TKey& key, const TMemRec& memRec) {
- Update(TTableId(segName), key, memRec);
- }
-
- template<typename T, typename TKey, typename TMemRec>
- void UpdateLevel(const T& sst, const TKey& key, const TMemRec& memRec) {
- Update(TTableId(sst), key, memRec);
- }
-
- void Finish()
- {}
-
- void Update(TTableId tableId, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
- Update(EDatabase::LOGOBLOBS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
- }
-
- void Update(TTableId tableId, const TKeyBlock& key, const TMemRecBlock& memRec) {
- Update(EDatabase::BLOCKS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
- }
-
- void Update(TTableId tableId, const TKeyBarrier& key, const TMemRecBarrier& memRec) {
- Update(EDatabase::BARRIERS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
- }
-
- void Update(EDatabase database, TTableId tableId, const void *key, size_t keyLen, const void *memRec, size_t memRecLen) {
- if (Blocks.empty() || Blocks.back().Database != database || Blocks.back().TableId != tableId ||
- Blocks.back().Capacity() < keyLen + memRecLen) {
- Blocks.emplace_back(database, tableId);
- }
- Blocks.back().Append(key, keyLen);
- Blocks.back().Append(memRec, memRecLen);
- }
-
- ui64 GetNumBlocks() const {
- return Blocks.size();
- }
-
- TString ReadIntoString(size_t maxLen) {
- TString s = TString::Uninitialized(maxLen);
- char *begin = s.Detach();
- char *end = begin + s.size();
- char *p = begin;
-
- for (; !Blocks.empty(); Blocks.pop_front()) {
- TBlock& front = Blocks.front();
-
- const size_t outputRecLen = GetRecLen(front.Database);
-
- const size_t inputRecLen = front.Database == EDatabase::LOGOBLOBS
- ? sizeof(TKeyLogoBlob) + sizeof(TMemRecLogoBlob)
- : outputRecLen; // the same for other record types
-
- const ui32 numRecs = front.GetLen() / inputRecLen;
- Y_VERIFY_DEBUG(front.GetLen() % inputRecLen == 0);
-
- if (static_cast<size_t>(end - p) < sizeof(TOutputBlockHeader) + outputRecLen * numRecs) {
- break; // this block does not fit into the output, exit
- }
-
- const TOutputBlockHeader header{
- .NumRecs = numRecs,
- .Database = static_cast<ui32>(front.Database),
- .TableType = front.TableId.GetType(),
- .Level = front.TableId.GetLevel(),
- .Reserved = 0,
- .SstId = front.TableId.GetSstId(),
- };
- memcpy(p, &header, sizeof(header));
- p += sizeof(header);
-
- switch (front.Database) {
- case EDatabase::LOGOBLOBS: {
- const void *input = front.GetData();
- for (ui32 i = 0; i < numRecs; ++i) {
- auto *key = static_cast<const TKeyLogoBlob*>(input);
- auto *memRec = reinterpret_cast<const TMemRecLogoBlob*>(key + 1);
- input = memRec + 1;
-
- *reinterpret_cast<TOutputLogoBlob*>(p) = {
- .Key = *key,
- .Ingress = memRec->GetIngress().Raw(),
- };
- p += sizeof(TOutputLogoBlob);
- }
- Y_VERIFY_DEBUG(input == static_cast<const char*>(front.GetData()) + front.GetLen());
- break;
- }
-
- case EDatabase::BLOCKS:
- case EDatabase::BARRIERS:
- // no conversion
- memcpy(p, front.GetData(), front.GetLen());
- p += front.GetLen();
- break;
- }
- }
-
- s.resize(p - begin);
- return s;
- }
-
- bool Done() const {
- return Blocks.empty();
- }
- };
-
- TDumpProcessor Processor;
-
- public:
+ const TString StreamId;
+ TInstant Deadline;
+ ui64 SequenceId = 1;
+
+ public:
+ enum class EDatabase {
+ LOGOBLOBS,
+ BLOCKS,
+ BARRIERS,
+ };
+
+ enum class ETableType : ui32 {
+ FCUR,
+ FDREG,
+ FOLD,
+ LEVEL,
+ };
+
+#pragma pack(push, 1)
+ struct TOutputLogoBlob {
+ TKeyLogoBlob Key;
+ ui64 Ingress;
+ };
+
+ struct TOutputBlock {
+ TKeyBlock Key;
+ TMemRecBlock MemRec;
+ };
+
+ struct TOutputBarrier {
+ TKeyBarrier Key;
+ TMemRecBarrier MemRec;
+ };
+
+ struct TOutputBlockHeader {
+ ui32 NumRecs;
+ ui32 Database : 2;
+ ui32 TableType : 2;
+ ui32 Level : 6;
+ ui32 Reserved : 22;
+ ui64 SstId;
+ };
+#pragma pack(pop)
+
+ private:
+ static constexpr size_t GetRecLen(EDatabase database) {
+ switch (database) {
+ case EDatabase::LOGOBLOBS:
+ return sizeof(TOutputLogoBlob);
+
+ case EDatabase::BLOCKS:
+ return sizeof(TOutputBlock);
+
+ case EDatabase::BARRIERS:
+ return sizeof(TOutputBarrier);
+ }
+ }
+
+ class TDumpProcessor {
+ class TTableId {
+ ETableType Type;
+ ui32 Level = 0;
+ ui64 SstId = 0;
+
+ public:
+ TTableId(const char *segName) {
+ Y_VERIFY_DEBUG(!strcmp(segName, "FCur") || !strcmp(segName, "FDreg") || !strcmp(segName, "FOld"));
+ switch (segName[1]) {
+ case 'C':
+ Type = ETableType::FCUR;
+ break;
+
+ case 'D':
+ Type = ETableType::FDREG;
+ break;
+
+ case 'O':
+ Type = ETableType::FOLD;
+ break;
+
+ default:
+ Y_FAIL();
+ }
+ }
+
+ template<typename T>
+ TTableId(const T& sst)
+ : Type(ETableType::LEVEL)
+ , Level(sst.Level)
+ , SstId(sst.SstPtr->AssignedSstId)
+ {}
+
+ ui32 GetType() const { return static_cast<ui32>(Type); }
+ ui32 GetLevel() const { return Level; }
+ ui64 GetSstId() const { return SstId; }
+
+ friend bool operator !=(const TTableId& x, const TTableId& y) {
+ return x.Type != y.Type || x.Level != y.Level || x.SstId != y.SstId;
+ }
+ };
+
+ private:
+ struct TBlock {
+ EDatabase Database;
+ TTableId TableId;
+ char Data[65536];
+ size_t Len = 0;
+
+ TBlock(EDatabase database, TTableId tableId)
+ : Database(database)
+ , TableId(tableId)
+ {}
+
+ void Append(const void *data, size_t len) {
+ memcpy(Data + Len, data, len);
+ Len += len;
+ }
+
+ size_t Capacity() const {
+ return sizeof(Data) - Len;
+ }
+
+ const void *GetData() const {
+ return Data;
+ }
+
+ size_t GetLen() const {
+ return Len;
+ }
+ };
+
+ private:
+ std::deque<TBlock> Blocks;
+
+ public:
+ template<typename TKey, typename TMemRec>
+ void UpdateFresh(const char *segName, const TKey& key, const TMemRec& memRec) {
+ Update(TTableId(segName), key, memRec);
+ }
+
+ template<typename T, typename TKey, typename TMemRec>
+ void UpdateLevel(const T& sst, const TKey& key, const TMemRec& memRec) {
+ Update(TTableId(sst), key, memRec);
+ }
+
+ void Finish()
+ {}
+
+ void Update(TTableId tableId, const TKeyLogoBlob& key, const TMemRecLogoBlob& memRec) {
+ Update(EDatabase::LOGOBLOBS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
+ }
+
+ void Update(TTableId tableId, const TKeyBlock& key, const TMemRecBlock& memRec) {
+ Update(EDatabase::BLOCKS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
+ }
+
+ void Update(TTableId tableId, const TKeyBarrier& key, const TMemRecBarrier& memRec) {
+ Update(EDatabase::BARRIERS, tableId, &key, sizeof(key), &memRec, sizeof(memRec));
+ }
+
+ void Update(EDatabase database, TTableId tableId, const void *key, size_t keyLen, const void *memRec, size_t memRecLen) {
+ if (Blocks.empty() || Blocks.back().Database != database || Blocks.back().TableId != tableId ||
+ Blocks.back().Capacity() < keyLen + memRecLen) {
+ Blocks.emplace_back(database, tableId);
+ }
+ Blocks.back().Append(key, keyLen);
+ Blocks.back().Append(memRec, memRecLen);
+ }
+
+ ui64 GetNumBlocks() const {
+ return Blocks.size();
+ }
+
+ TString ReadIntoString(size_t maxLen) {
+ TString s = TString::Uninitialized(maxLen);
+ char *begin = s.Detach();
+ char *end = begin + s.size();
+ char *p = begin;
+
+ for (; !Blocks.empty(); Blocks.pop_front()) {
+ TBlock& front = Blocks.front();
+
+ const size_t outputRecLen = GetRecLen(front.Database);
+
+ const size_t inputRecLen = front.Database == EDatabase::LOGOBLOBS
+ ? sizeof(TKeyLogoBlob) + sizeof(TMemRecLogoBlob)
+ : outputRecLen; // the same for other record types
+
+ const ui32 numRecs = front.GetLen() / inputRecLen;
+ Y_VERIFY_DEBUG(front.GetLen() % inputRecLen == 0);
+
+ if (static_cast<size_t>(end - p) < sizeof(TOutputBlockHeader) + outputRecLen * numRecs) {
+ break; // this block does not fit into the output, exit
+ }
+
+ const TOutputBlockHeader header{
+ .NumRecs = numRecs,
+ .Database = static_cast<ui32>(front.Database),
+ .TableType = front.TableId.GetType(),
+ .Level = front.TableId.GetLevel(),
+ .Reserved = 0,
+ .SstId = front.TableId.GetSstId(),
+ };
+ memcpy(p, &header, sizeof(header));
+ p += sizeof(header);
+
+ switch (front.Database) {
+ case EDatabase::LOGOBLOBS: {
+ const void *input = front.GetData();
+ for (ui32 i = 0; i < numRecs; ++i) {
+ auto *key = static_cast<const TKeyLogoBlob*>(input);
+ auto *memRec = reinterpret_cast<const TMemRecLogoBlob*>(key + 1);
+ input = memRec + 1;
+
+ *reinterpret_cast<TOutputLogoBlob*>(p) = {
+ .Key = *key,
+ .Ingress = memRec->GetIngress().Raw(),
+ };
+ p += sizeof(TOutputLogoBlob);
+ }
+ Y_VERIFY_DEBUG(input == static_cast<const char*>(front.GetData()) + front.GetLen());
+ break;
+ }
+
+ case EDatabase::BLOCKS:
+ case EDatabase::BARRIERS:
+ // no conversion
+ memcpy(p, front.GetData(), front.GetLen());
+ p += front.GetLen();
+ break;
+ }
+ }
+
+ s.resize(p - begin);
+ return s;
+ }
+
+ bool Done() const {
+ return Blocks.empty();
+ }
+ };
+
+ TDumpProcessor Processor;
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::BS_MONSTREAM_ACTOR;
}
- TLevelIndexStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev)
- : FullSnap(std::move(fullSnap))
- , StreamId(std::move(ev->Get()->StreamId))
- {}
-
+ TLevelIndexStreamActor(THullDsSnap&& fullSnap, TEvBlobStorage::TEvMonStreamQuery::TPtr& ev)
+ : FullSnap(std::move(fullSnap))
+ , StreamId(std::move(ev->Get()->StreamId))
+ {}
+
void Bootstrap(const TActorId& parentId, const TActorContext& ctx) {
- Become(&TLevelIndexStreamActor::StateFunc);
-
- // record all snapped data into the processor and release snapshot
- TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->LogoBlobsSnap);
- TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->BlocksSnap);
- TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->BarriersSnap);
- FullSnap.reset();
-
- SkeletonId = parentId;
- Deadline = ctx.Now() + LifetimeAfterQuery;
- HandleWakeup(ctx);
- }
-
- STRICT_STFUNC(StateFunc, {
- HFunc(TEvBlobStorage::TEvMonStreamQuery, Handle);
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- CFunc(TEvents::TSystem::PoisonPill, Die);
- })
-
- void Handle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
- TStringStream s;
- if (!Processor.Done()) {
- TBZipCompress comp(&s, 6, 65536);
- Save(&comp, SelfId().RawX1());
- Save(&comp, SelfId().RawX2());
- Save(&comp, SequenceId++);
- Save(&comp, Processor.GetNumBlocks());
- comp << Processor.ReadIntoString(BlockSize);
- comp.Finish();
- }
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(s.Str()));
- Deadline = ctx.Now() + LifetimeAfterQuery;
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- const TInstant now = ctx.Now();
- if (now < Deadline) {
- ctx.Schedule(Deadline - now, new TEvents::TEvWakeup);
- } else {
- Die(ctx);
- }
- }
-
- void Die(const TActorContext& ctx) override {
- ctx.Send(SkeletonId, new TEvBlobStorage::TEvMonStreamActorDeathNote(std::move(StreamId)));
- TActorBootstrapped<TLevelIndexStreamActor>::Die(ctx);
- }
- };
-
-} // NKikimr
+ Become(&TLevelIndexStreamActor::StateFunc);
+
+ // record all snapped data into the processor and release snapshot
+ TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->LogoBlobsSnap);
+ TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->BlocksSnap);
+ TraverseDbWithoutMerge(FullSnap->HullCtx, &Processor, FullSnap->BarriersSnap);
+ FullSnap.reset();
+
+ SkeletonId = parentId;
+ Deadline = ctx.Now() + LifetimeAfterQuery;
+ HandleWakeup(ctx);
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, Handle);
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ CFunc(TEvents::TSystem::PoisonPill, Die);
+ })
+
+ void Handle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
+ TStringStream s;
+ if (!Processor.Done()) {
+ TBZipCompress comp(&s, 6, 65536);
+ Save(&comp, SelfId().RawX1());
+ Save(&comp, SelfId().RawX2());
+ Save(&comp, SequenceId++);
+ Save(&comp, Processor.GetNumBlocks());
+ comp << Processor.ReadIntoString(BlockSize);
+ comp.Finish();
+ }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(s.Str()));
+ Deadline = ctx.Now() + LifetimeAfterQuery;
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ const TInstant now = ctx.Now();
+ if (now < Deadline) {
+ ctx.Schedule(Deadline - now, new TEvents::TEvWakeup);
+ } else {
+ Die(ctx);
+ }
+ }
+
+ void Die(const TActorContext& ctx) override {
+ ctx.Send(SkeletonId, new TEvBlobStorage::TEvMonStreamActorDeathNote(std::move(StreamId)));
+ TActorBootstrapped<TLevelIndexStreamActor>::Die(ctx);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/query/ya.make b/ydb/core/blobstorage/vdisk/query/ya.make
index 4d638cf8037..e9a90000211 100644
--- a/ydb/core/blobstorage/vdisk/query/ya.make
+++ b/ydb/core/blobstorage/vdisk/query/ya.make
@@ -34,7 +34,7 @@ SRCS(
query_stathuge.h
query_stattablet.cpp
query_stattablet.h
- query_stream.h
+ query_stream.h
)
END()
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp
index 3a95c22022f..f9934c2d434 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.cpp
@@ -1,12 +1,12 @@
#include "defs.h"
#include "blobstorage_repl.h"
#include "blobstorage_replproxy.h"
-#include "blobstorage_replrecoverymachine.h"
+#include "blobstorage_replrecoverymachine.h"
#include <ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_private_events.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_partlayout.h>
#include <ydb/core/blobstorage/vdisk/skeleton/blobstorage_takedbsnap.h>
-#include <util/datetime/cputimer.h>
+#include <util/datetime/cputimer.h>
// FIXME: we need a process that asyncronously transfers handoff parts to their correct vdisk
// FIXME: when VDiskProxy reports error, we can get lot of errors during recovery, we want to distinguish them
@@ -17,806 +17,806 @@ namespace NKikimr {
using namespace NRepl;
- // a vector of proxies we are using to interoperate with other disks; index designates VDisk order number inside the
- // group; for those disks we don't use, the pointer is set to null
- using TVDiskProxySet = TStackVec<TVDiskProxyPtr, 32>;
-
- struct TEvReplPlanFinished : public TEventLocal<TEvReplPlanFinished, TEvBlobStorage::EvReplPlanFinished> {
- std::unique_ptr<TRecoveryMachine> RecoveryMachine;
- TLogoBlobID LastKey;
- bool Eof;
-
- TEvReplPlanFinished(std::unique_ptr<TRecoveryMachine>&& recoveryMachine, const TLogoBlobID& lastKey, bool eof)
- : RecoveryMachine(std::move(recoveryMachine))
- , LastKey(lastKey)
- , Eof(eof)
- {}
- };
-
+ // a vector of proxies we are using to interoperate with other disks; index designates VDisk order number inside the
+ // group; for those disks we don't use, the pointer is set to null
+ using TVDiskProxySet = TStackVec<TVDiskProxyPtr, 32>;
+
+ struct TEvReplPlanFinished : public TEventLocal<TEvReplPlanFinished, TEvBlobStorage::EvReplPlanFinished> {
+ std::unique_ptr<TRecoveryMachine> RecoveryMachine;
+ TLogoBlobID LastKey;
+ bool Eof;
+
+ TEvReplPlanFinished(std::unique_ptr<TRecoveryMachine>&& recoveryMachine, const TLogoBlobID& lastKey, bool eof)
+ : RecoveryMachine(std::move(recoveryMachine))
+ , LastKey(lastKey)
+ , Eof(eof)
+ {}
+ };
+
////////////////////////////////////////////////////////////////////////////
// THullReplPlannerActor
////////////////////////////////////////////////////////////////////////////
- class THullReplPlannerActor : public TActorBootstrapped<THullReplPlannerActor> {
- std::unique_ptr<TRecoveryMachine> RecoveryMachine;
- std::shared_ptr<TReplCtx> ReplCtx;
- TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
+ class THullReplPlannerActor : public TActorBootstrapped<THullReplPlannerActor> {
+ std::unique_ptr<TRecoveryMachine> RecoveryMachine;
+ std::shared_ptr<TReplCtx> ReplCtx;
+ TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
TActorId Recipient;
- TLogoBlobID StartKey;
+ TLogoBlobID StartKey;
TEvReplFinished::TInfoPtr ReplInfo;
- TBlobIdQueuePtr BlobsToReplicatePtr;
- TBlobIdQueuePtr UnreplicatedBlobsPtr;
- ui64 QuantumBytes = 0;
- ui32 QuantumParts = 0;
-
- public:
- void Bootstrap(const TActorId& parentId) {
- Recipient = parentId;
-
- // prepare the recovery machine
- RecoveryMachine = std::make_unique<TRecoveryMachine>(ReplCtx, ReplInfo, std::move(UnreplicatedBlobsPtr));
-
- // request for snapshot
- Send(ReplCtx->SkeletonId, new TEvTakeHullSnapshot(true));
-
- // switch state func
- Become(&TThis::StateFunc);
+ TBlobIdQueuePtr BlobsToReplicatePtr;
+ TBlobIdQueuePtr UnreplicatedBlobsPtr;
+ ui64 QuantumBytes = 0;
+ ui32 QuantumParts = 0;
+
+ public:
+ void Bootstrap(const TActorId& parentId) {
+ Recipient = parentId;
+
+ // prepare the recovery machine
+ RecoveryMachine = std::make_unique<TRecoveryMachine>(ReplCtx, ReplInfo, std::move(UnreplicatedBlobsPtr));
+
+ // request for snapshot
+ Send(ReplCtx->SkeletonId, new TEvTakeHullSnapshot(true));
+
+ // switch state func
+ Become(&TThis::StateFunc);
}
- void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
- auto& snap = ev->Get()->Snap;
- const bool allowKeepFlags = snap.HullCtx->AllowKeepFlags;
-
- // create barriers essence
- auto barriers = snap.BarriersSnap.CreateEssence(snap.HullCtx);
-
- // create iterator for the logoblobs metabase
- TLogoBlobsSnapshot::TIndexForwardIterator it(snap.HullCtx, &snap.LogoBlobsSnap);
- bool eof = false;
-
- const ui64 plannedEndTime = GetCycleCountFast() + DurationToCycles(ReplCtx->VDiskCfg->ReplPlanQuantum);
- auto going = [&, first = true]() mutable { // the predicate that determines the length of the quantum
- if (first) {
- first = false;
- return true;
- } else {
- return !RecoveryMachine->FullOfTasks() && QuantumBytes < ReplCtx->VDiskCfg->ReplMaxQuantumBytes &&
- GetCycleCountFast() <= plannedEndTime;
- }
- };
-
- if (BlobsToReplicatePtr) {
- // iterate over queue items and match them with iterator
- for (; !BlobsToReplicatePtr->empty() && going(); BlobsToReplicatePtr->pop()) {
- const TLogoBlobID& key = BlobsToReplicatePtr->front();
- it.Seek(key);
- if (it.Valid() && it.GetCurKey().LogoBlobID() == key) {
- ProcessItem(it, barriers, allowKeepFlags);
- }
- }
- eof = BlobsToReplicatePtr->empty();
- } else {
- // scan through the index until we have enough blobs to recover or the time is out
- for (it.Seek(StartKey); it.Valid() && going(); it.Next()) {
- ProcessItem(it, barriers, allowKeepFlags);
- }
- if (it.Valid()) {
- StartKey = it.GetCurKey().LogoBlobID(); // we gonna resume later starting from this key
- } else {
- eof = true;
- }
+ void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
+ auto& snap = ev->Get()->Snap;
+ const bool allowKeepFlags = snap.HullCtx->AllowKeepFlags;
+
+ // create barriers essence
+ auto barriers = snap.BarriersSnap.CreateEssence(snap.HullCtx);
+
+ // create iterator for the logoblobs metabase
+ TLogoBlobsSnapshot::TIndexForwardIterator it(snap.HullCtx, &snap.LogoBlobsSnap);
+ bool eof = false;
+
+ const ui64 plannedEndTime = GetCycleCountFast() + DurationToCycles(ReplCtx->VDiskCfg->ReplPlanQuantum);
+ auto going = [&, first = true]() mutable { // the predicate that determines the length of the quantum
+ if (first) {
+ first = false;
+ return true;
+ } else {
+ return !RecoveryMachine->FullOfTasks() && QuantumBytes < ReplCtx->VDiskCfg->ReplMaxQuantumBytes &&
+ GetCycleCountFast() <= plannedEndTime;
+ }
+ };
+
+ if (BlobsToReplicatePtr) {
+ // iterate over queue items and match them with iterator
+ for (; !BlobsToReplicatePtr->empty() && going(); BlobsToReplicatePtr->pop()) {
+ const TLogoBlobID& key = BlobsToReplicatePtr->front();
+ it.Seek(key);
+ if (it.Valid() && it.GetCurKey().LogoBlobID() == key) {
+ ProcessItem(it, barriers, allowKeepFlags);
+ }
+ }
+ eof = BlobsToReplicatePtr->empty();
+ } else {
+ // scan through the index until we have enough blobs to recover or the time is out
+ for (it.Seek(StartKey); it.Valid() && going(); it.Next()) {
+ ProcessItem(it, barriers, allowKeepFlags);
+ }
+ if (it.Valid()) {
+ StartKey = it.GetCurKey().LogoBlobID(); // we gonna resume later starting from this key
+ } else {
+ eof = true;
+ }
}
- if (eof || RecoveryMachine->FullOfTasks() || QuantumBytes >= ReplCtx->VDiskCfg->ReplMaxQuantumBytes) {
- // adjust counters
- ReplCtx->MonGroup.ReplCurrentUnreplicatedParts() += QuantumParts;
- ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes() += QuantumBytes;
-
- // the planning stage has finished, issue reply to the job actor
- Send(Recipient, new TEvReplPlanFinished(std::move(RecoveryMachine), StartKey, eof));
-
- // finish processing for this actor
- PassAway();
- } else {
- // resume processing a bit later with newer snapshot; this one gets released
- Send(ReplCtx->SkeletonId, new TEvTakeHullSnapshot(true));
- }
+ if (eof || RecoveryMachine->FullOfTasks() || QuantumBytes >= ReplCtx->VDiskCfg->ReplMaxQuantumBytes) {
+ // adjust counters
+ ReplCtx->MonGroup.ReplCurrentUnreplicatedParts() += QuantumParts;
+ ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes() += QuantumBytes;
+
+ // the planning stage has finished, issue reply to the job actor
+ Send(Recipient, new TEvReplPlanFinished(std::move(RecoveryMachine), StartKey, eof));
+
+ // finish processing for this actor
+ PassAway();
+ } else {
+ // resume processing a bit later with newer snapshot; this one gets released
+ Send(ReplCtx->SkeletonId, new TEvTakeHullSnapshot(true));
+ }
}
- void ProcessItem(const TLogoBlobsSnapshot::TIndexForwardIterator& it,
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> barriers, bool allowKeepFlags) {
- // aliases for convenient access
- const TBlobStorageGroupInfo::TTopology& topology = *ReplCtx->VCtx->Top;
- const TBlobStorageGroupType gtype = topology.GType;
- const TLogoBlobID& key = it.GetCurKey().LogoBlobID();
-
- NGc::TKeepStatus status = barriers->Keep(key, it.GetMemRec(), it.GetMemRecsMerged(), allowKeepFlags);
- if (status.KeepData) {
- const TMemRecLogoBlob &memRec = it.GetMemRec();
- const TIngress &ingress = memRec.GetIngress();
-
- // calculate set of parts to recover
- NMatrix::TVectorType parts = ingress.PartsWeMustHaveLocally(&topology, ReplCtx->VCtx->ShortSelfVDisk,
- key) - ingress.LocalParts(topology.GType);
-
- // scan for metadata parts
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- const TLogoBlobID id(key, i + 1);
- if (!gtype.PartSize(id)) {
- parts.Clear(i);
- RecoveryMachine->AddMetadataPart(id);
- }
- }
-
- if (!parts.Empty()) {
- const bool phantomLike = !status.KeepByBarrier && ReplInfo->DonorVDiskId == TVDiskID();
- RecoveryMachine->AddTask(key, parts, phantomLike, ingress);
-
- // calculate part size and total size to recover
- for (ui8 partIdx = parts.FirstPosition(); partIdx != parts.GetSize(); partIdx = parts.NextPosition(partIdx)) {
- QuantumBytes += gtype.PartSize(TLogoBlobID(key, partIdx + 1));
- ++QuantumParts;
- ++ReplInfo->PartsPlanned;
- }
-
- ReplInfo->RecoveryScheduled++;
- } else {
- ReplInfo->ReplicaOk++;
- }
- } else {
- ReplInfo->IgnoredDueToGC++;
- }
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvTakeHullSnapshotResult, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_REPL_PLANNER;
+ void ProcessItem(const TLogoBlobsSnapshot::TIndexForwardIterator& it,
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> barriers, bool allowKeepFlags) {
+ // aliases for convenient access
+ const TBlobStorageGroupInfo::TTopology& topology = *ReplCtx->VCtx->Top;
+ const TBlobStorageGroupType gtype = topology.GType;
+ const TLogoBlobID& key = it.GetCurKey().LogoBlobID();
+
+ NGc::TKeepStatus status = barriers->Keep(key, it.GetMemRec(), it.GetMemRecsMerged(), allowKeepFlags);
+ if (status.KeepData) {
+ const TMemRecLogoBlob &memRec = it.GetMemRec();
+ const TIngress &ingress = memRec.GetIngress();
+
+ // calculate set of parts to recover
+ NMatrix::TVectorType parts = ingress.PartsWeMustHaveLocally(&topology, ReplCtx->VCtx->ShortSelfVDisk,
+ key) - ingress.LocalParts(topology.GType);
+
+ // scan for metadata parts
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ const TLogoBlobID id(key, i + 1);
+ if (!gtype.PartSize(id)) {
+ parts.Clear(i);
+ RecoveryMachine->AddMetadataPart(id);
+ }
+ }
+
+ if (!parts.Empty()) {
+ const bool phantomLike = !status.KeepByBarrier && ReplInfo->DonorVDiskId == TVDiskID();
+ RecoveryMachine->AddTask(key, parts, phantomLike, ingress);
+
+ // calculate part size and total size to recover
+ for (ui8 partIdx = parts.FirstPosition(); partIdx != parts.GetSize(); partIdx = parts.NextPosition(partIdx)) {
+ QuantumBytes += gtype.PartSize(TLogoBlobID(key, partIdx + 1));
+ ++QuantumParts;
+ ++ReplInfo->PartsPlanned;
+ }
+
+ ReplInfo->RecoveryScheduled++;
+ } else {
+ ReplInfo->ReplicaOk++;
+ }
+ } else {
+ ReplInfo->IgnoredDueToGC++;
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvTakeHullSnapshotResult, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_REPL_PLANNER;
}
- THullReplPlannerActor(std::shared_ptr<TReplCtx> replCtx,
- TIntrusivePtr<TBlobStorageGroupInfo> ginfo,
+ THullReplPlannerActor(std::shared_ptr<TReplCtx> replCtx,
+ TIntrusivePtr<TBlobStorageGroupInfo> ginfo,
const TLogoBlobID &startKey,
TEvReplFinished::TInfoPtr replInfo,
TBlobIdQueuePtr&& blobsToReplicatePtr,
- TBlobIdQueuePtr&& unreplicatedBlobsPtr)
+ TBlobIdQueuePtr&& unreplicatedBlobsPtr)
: ReplCtx(std::move(replCtx))
- , GInfo(std::move(ginfo))
- , StartKey(startKey)
+ , GInfo(std::move(ginfo))
+ , StartKey(startKey)
, ReplInfo(replInfo)
- , BlobsToReplicatePtr(std::move(blobsToReplicatePtr))
- , UnreplicatedBlobsPtr(std::move(unreplicatedBlobsPtr))
- {}
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // THullReplJobActor
- ////////////////////////////////////////////////////////////////////////////
- class THullReplJobActor : public TActorBootstrapped<THullReplJobActor> {
- private:
- struct TLogoBlobInfo {
- TLogoBlobID Id;
- TIngress Ingress;
- };
-
- enum class EProcessQueueAction {
- Continue,
- Restart,
- Exit
- };
-
- std::shared_ptr<TReplCtx> ReplCtx;
- TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
+ , BlobsToReplicatePtr(std::move(blobsToReplicatePtr))
+ , UnreplicatedBlobsPtr(std::move(unreplicatedBlobsPtr))
+ {}
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // THullReplJobActor
+ ////////////////////////////////////////////////////////////////////////////
+ class THullReplJobActor : public TActorBootstrapped<THullReplJobActor> {
+ private:
+ struct TLogoBlobInfo {
+ TLogoBlobID Id;
+ TIngress Ingress;
+ };
+
+ enum class EProcessQueueAction {
+ Continue,
+ Restart,
+ Exit
+ };
+
+ std::shared_ptr<TReplCtx> ReplCtx;
+ TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
const TActorId ParentId;
- const TLogoBlobID StartKey;
+ const TLogoBlobID StartKey;
TVector<TVDiskProxyPtr> MergeHeap;
TEvReplFinished::TInfoPtr ReplInfo;
- TRecoveryMachine::TRecoveredBlobsQueue RecoveryQueue;
- TReplSstStreamWriter Writer;
- bool RecoveryMachineFinished, WriterFinished;
- TTimeAccount TimeAccount;
+ TRecoveryMachine::TRecoveredBlobsQueue RecoveryQueue;
+ TReplSstStreamWriter Writer;
+ bool RecoveryMachineFinished, WriterFinished;
+ TTimeAccount TimeAccount;
TActiveActors ActiveActors;
-
- // huge blob replication part
- ui32 HugeBlobsInFlight;
- const ui32 HugeBlobsInFlightMax;
-
+
+ // huge blob replication part
+ ui32 HugeBlobsInFlight;
+ const ui32 HugeBlobsInFlightMax;
+
TQueueActorMapPtr QueueActorMapPtr;
- TBlobIdQueuePtr BlobsToReplicatePtr;
- TBlobIdQueuePtr UnreplicatedBlobsPtr;
- std::optional<std::pair<TVDiskID, TActorId>> Donor;
-
- // parameters from planner
- std::unique_ptr<TRecoveryMachine> RecoveryMachine;
- TLogoBlobID LastKey;
- bool Eof = false;
- TVDiskProxySet DiskProxySet;
- ui32 NumRunningProxies = 0;
-
- bool PhantomCheckPending = false;
+ TBlobIdQueuePtr BlobsToReplicatePtr;
+ TBlobIdQueuePtr UnreplicatedBlobsPtr;
+ std::optional<std::pair<TVDiskID, TActorId>> Donor;
+
+ // parameters from planner
+ std::unique_ptr<TRecoveryMachine> RecoveryMachine;
+ TLogoBlobID LastKey;
+ bool Eof = false;
+ TVDiskProxySet DiskProxySet;
+ ui32 NumRunningProxies = 0;
+
+ bool PhantomCheckPending = false;
TDeque<TLogoBlobID> Phantoms;
-
+
THashSet<TChunkIdx> WrittenChunkIdxSet;
-
- friend class TActorBootstrapped<THullReplJobActor>;
-
- std::optional<TLogoBlobID> CurrentKey;
- std::optional<TRecoveryMachine::TPartSet> CurrentParts;
- TLogoBlobID LastProcessedKey;
-
- void Finish() {
- STLOG(PRI_DEBUG, BS_REPL, BSVR01, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished replication job"),
- (LastKey, LastKey), (Eof, Eof));
-
- if (!Phantoms.empty()) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR06, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "sending phantoms"),
- (NumPhantoms, Phantoms.size()));
- Send(ReplCtx->SkeletonId, new TEvDetectedPhantomBlob(std::move(Phantoms)));
- Phantoms.clear();
- }
-
- bool dropDonor = true;
- for (const auto& proxy : DiskProxySet) {
- dropDonor = dropDonor && proxy && proxy->NoTransientErrors();
- }
- ReplInfo->Finish(LastKey, Eof, Donor && dropDonor);
-
- TProxyStat stat;
- for (const TVDiskProxyPtr& p : DiskProxySet) {
- if (p) {
- stat += p->Stat;
- }
- }
- ReplInfo->ProxyStat = std::make_unique<TProxyStat>(stat);
-
- TimeAccount.SetState(ETimeState::COUNT);
+
+ friend class TActorBootstrapped<THullReplJobActor>;
+
+ std::optional<TLogoBlobID> CurrentKey;
+ std::optional<TRecoveryMachine::TPartSet> CurrentParts;
+ TLogoBlobID LastProcessedKey;
+
+ void Finish() {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR01, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished replication job"),
+ (LastKey, LastKey), (Eof, Eof));
+
+ if (!Phantoms.empty()) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR06, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "sending phantoms"),
+ (NumPhantoms, Phantoms.size()));
+ Send(ReplCtx->SkeletonId, new TEvDetectedPhantomBlob(std::move(Phantoms)));
+ Phantoms.clear();
+ }
+
+ bool dropDonor = true;
+ for (const auto& proxy : DiskProxySet) {
+ dropDonor = dropDonor && proxy && proxy->NoTransientErrors();
+ }
+ ReplInfo->Finish(LastKey, Eof, Donor && dropDonor);
+
+ TProxyStat stat;
+ for (const TVDiskProxyPtr& p : DiskProxySet) {
+ if (p) {
+ stat += p->Stat;
+ }
+ }
+ ReplInfo->ProxyStat = std::make_unique<TProxyStat>(stat);
+
+ TimeAccount.SetState(ETimeState::COUNT);
TimeAccount.UpdateInfo(*ReplInfo);
-
- Send(ParentId, new TEvReplFinished(ReplInfo));
- PassAway();
- }
-
- void Bootstrap() {
- STLOG(PRI_DEBUG, BS_REPL, BSVR02, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::Bootstrap"));
- TimeAccount.SetState(ETimeState::PREPARE_PLAN);
- auto actor = std::make_unique<THullReplPlannerActor>(ReplCtx, GInfo, StartKey, ReplInfo,
- std::move(BlobsToReplicatePtr), std::move(UnreplicatedBlobsPtr));
- auto aid = RunInBatchPool(TActivationContext::ActorContextFor(SelfId()), actor.release());
+
+ Send(ParentId, new TEvReplFinished(ReplInfo));
+ PassAway();
+ }
+
+ void Bootstrap() {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR02, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::Bootstrap"));
+ TimeAccount.SetState(ETimeState::PREPARE_PLAN);
+ auto actor = std::make_unique<THullReplPlannerActor>(ReplCtx, GInfo, StartKey, ReplInfo,
+ std::move(BlobsToReplicatePtr), std::move(UnreplicatedBlobsPtr));
+ auto aid = RunInBatchPool(TActivationContext::ActorContextFor(SelfId()), actor.release());
ActiveActors.Insert(aid);
- Become(&TThis::StatePreparePlan);
- }
-
- void Handle(TEvReplPlanFinished::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR03, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::Handle(TEvReplPlanFinished)"));
+ Become(&TThis::StatePreparePlan);
+ }
+
+ void Handle(TEvReplPlanFinished::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR03, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::Handle(TEvReplPlanFinished)"));
ActiveActors.Erase(ev->Sender);
- RecoveryMachine = std::move(ev->Get()->RecoveryMachine);
- LastKey = ev->Get()->LastKey;
- Eof = ev->Get()->Eof;
-
- if (RecoveryMachine->NoTasks()) {
- Finish();
- return;
- }
-
- // we will receive TEvReplResume from the Recipient a bit later
- Send(ParentId, new TEvReplStarted);
- TimeAccount.SetState(ETimeState::TOKEN_WAIT);
- Become(&TThis::StateToken);
- }
-
- void HandleResume() {
- STLOG(PRI_DEBUG, BS_REPL, BSVR04, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::HandleResume"));
- TimeAccount.SetState(ETimeState::PROXY_WAIT);
-
- // run proxies
- SetupDiskProxies();
- Y_VERIFY(!NumRunningProxies);
- for (const TVDiskProxyPtr& p : DiskProxySet) {
- if (p) {
- ActiveActors.Insert(p->Run(SelfId()));
- ++NumRunningProxies;
- }
- }
- if (NumRunningProxies) {
- Become(&TThis::StateInit);
- } else {
- Become(&TThis::StateMerge);
- Merge();
- }
- }
-
- void SetupDiskProxies() {
- DiskProxySet.clear();
- DiskProxySet.resize(Donor ? 1 : ReplCtx->VCtx->Top->GetTotalVDisksNum());
- if (Donor) {
- RecoveryMachine->ClearPossiblePhantom(); // no phantoms in donor mode
- }
-
- const TBlobStorageGroupInfo::TTopology& topology = *ReplCtx->VCtx->Top;
- const TBlobStorageGroupType gtype = topology.GType;
-
- if (Donor) {
- TVDiskProxyPtr& proxy = DiskProxySet[0];
- RecoveryMachine->ForEach([&](const TLogoBlobID& fullId, NMatrix::TVectorType parts, TIngress /*ingress*/) {
- if (!proxy) {
- proxy = MakeIntrusive<TVDiskProxy>(ReplCtx, Donor->first, Donor->second);
- }
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- const TLogoBlobID id(fullId, i + 1);
- proxy->Put(id, gtype.PartSize(id));
- }
- });
- } else {
- RecoveryMachine->ForEach([&](const TLogoBlobID& fullId, NMatrix::TVectorType /*parts*/, TIngress ingress) {
- // calculate subgroup layout for this blob
- TBlobStorageGroupInfo::TOrderNums vdiskOrderNums;
- topology.PickSubgroup(fullId.Hash(), vdiskOrderNums);
-
- // traverse through all of the disks and create proxies
- for (ui32 idx = 0; idx < vdiskOrderNums.size(); ++idx) {
- const ui32 orderNum = vdiskOrderNums[idx];
- const TVDiskID& vdisk = GInfo->GetVDiskId(orderNum);
- if (TVDiskIdShort(vdisk) == ReplCtx->VCtx->ShortSelfVDisk) {
- continue;
- }
-
- TVDiskProxyPtr &ptr = DiskProxySet.at(orderNum);
- if (!ptr) {
- auto queueIt = QueueActorMapPtr->find(vdisk);
- Y_VERIFY(queueIt != QueueActorMapPtr->end());
- ptr = MakeIntrusive<TVDiskProxy>(ReplCtx, vdisk, queueIt->second);
- }
-
- // count number of known parts on this disk according to ingress
- const NMatrix::TVectorType partsOnDisk = ingress.KnownParts(gtype, idx);
- ui32 expectedReplySize = 0;
- for (ui8 i = partsOnDisk.FirstPosition(); i != partsOnDisk.GetSize(); i = partsOnDisk.NextPosition(i)) {
- expectedReplySize += gtype.PartSize(TLogoBlobID(fullId, i + 1));
- }
-
- ptr->Put(fullId, expectedReplySize);
- }
- });
- }
-
- }
-
- void Merge() {
- while (MergeIteration())
- ;
- }
-
- bool MergeIteration() {
- for (;;) {
- const TReplSstStreamWriter::EState state = Writer.GetState();
- const bool noWorkForWriter = RecoveryQueue.empty() || RecoveryQueue.front().IsHugeBlob;
- if (state == TReplSstStreamWriter::EState::COLLECT) {
- Y_VERIFY(!WriterFinished);
- break;
- } else if (state == TReplSstStreamWriter::EState::STOPPED && noWorkForWriter) {
- break;
- }
-
- switch (state) {
- case TReplSstStreamWriter::EState::STOPPED:
- Y_VERIFY(RecoveryQueue && !RecoveryQueue.front().IsHugeBlob && !WriterFinished);
- Writer.Begin();
- break;
-
- case TReplSstStreamWriter::EState::PDISK_MESSAGE_PENDING: {
- // obtain pending message
- std::unique_ptr<IEventBase> msg = Writer.GetPendingPDiskMsg();
-
- // if this is chunk write, then check if we are writing new chunk; if so, count it
- if (msg->Type() == TEvBlobStorage::EvChunkWrite) {
- auto *write = static_cast<NPDisk::TEvChunkWrite*>(msg.get());
- // if we have seen new chunk index, then increase some counters
- if (WrittenChunkIdxSet.insert(write->ChunkIdx).second) {
- ++ReplInfo->ChunksWritten;
+ RecoveryMachine = std::move(ev->Get()->RecoveryMachine);
+ LastKey = ev->Get()->LastKey;
+ Eof = ev->Get()->Eof;
+
+ if (RecoveryMachine->NoTasks()) {
+ Finish();
+ return;
+ }
+
+ // we will receive TEvReplResume from the Recipient a bit later
+ Send(ParentId, new TEvReplStarted);
+ TimeAccount.SetState(ETimeState::TOKEN_WAIT);
+ Become(&TThis::StateToken);
+ }
+
+ void HandleResume() {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR04, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "THullReplJobActor::HandleResume"));
+ TimeAccount.SetState(ETimeState::PROXY_WAIT);
+
+ // run proxies
+ SetupDiskProxies();
+ Y_VERIFY(!NumRunningProxies);
+ for (const TVDiskProxyPtr& p : DiskProxySet) {
+ if (p) {
+ ActiveActors.Insert(p->Run(SelfId()));
+ ++NumRunningProxies;
+ }
+ }
+ if (NumRunningProxies) {
+ Become(&TThis::StateInit);
+ } else {
+ Become(&TThis::StateMerge);
+ Merge();
+ }
+ }
+
+ void SetupDiskProxies() {
+ DiskProxySet.clear();
+ DiskProxySet.resize(Donor ? 1 : ReplCtx->VCtx->Top->GetTotalVDisksNum());
+ if (Donor) {
+ RecoveryMachine->ClearPossiblePhantom(); // no phantoms in donor mode
+ }
+
+ const TBlobStorageGroupInfo::TTopology& topology = *ReplCtx->VCtx->Top;
+ const TBlobStorageGroupType gtype = topology.GType;
+
+ if (Donor) {
+ TVDiskProxyPtr& proxy = DiskProxySet[0];
+ RecoveryMachine->ForEach([&](const TLogoBlobID& fullId, NMatrix::TVectorType parts, TIngress /*ingress*/) {
+ if (!proxy) {
+ proxy = MakeIntrusive<TVDiskProxy>(ReplCtx, Donor->first, Donor->second);
+ }
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ const TLogoBlobID id(fullId, i + 1);
+ proxy->Put(id, gtype.PartSize(id));
+ }
+ });
+ } else {
+ RecoveryMachine->ForEach([&](const TLogoBlobID& fullId, NMatrix::TVectorType /*parts*/, TIngress ingress) {
+ // calculate subgroup layout for this blob
+ TBlobStorageGroupInfo::TOrderNums vdiskOrderNums;
+ topology.PickSubgroup(fullId.Hash(), vdiskOrderNums);
+
+ // traverse through all of the disks and create proxies
+ for (ui32 idx = 0; idx < vdiskOrderNums.size(); ++idx) {
+ const ui32 orderNum = vdiskOrderNums[idx];
+ const TVDiskID& vdisk = GInfo->GetVDiskId(orderNum);
+ if (TVDiskIdShort(vdisk) == ReplCtx->VCtx->ShortSelfVDisk) {
+ continue;
+ }
+
+ TVDiskProxyPtr &ptr = DiskProxySet.at(orderNum);
+ if (!ptr) {
+ auto queueIt = QueueActorMapPtr->find(vdisk);
+ Y_VERIFY(queueIt != QueueActorMapPtr->end());
+ ptr = MakeIntrusive<TVDiskProxy>(ReplCtx, vdisk, queueIt->second);
+ }
+
+ // count number of known parts on this disk according to ingress
+ const NMatrix::TVectorType partsOnDisk = ingress.KnownParts(gtype, idx);
+ ui32 expectedReplySize = 0;
+ for (ui8 i = partsOnDisk.FirstPosition(); i != partsOnDisk.GetSize(); i = partsOnDisk.NextPosition(i)) {
+ expectedReplySize += gtype.PartSize(TLogoBlobID(fullId, i + 1));
+ }
+
+ ptr->Put(fullId, expectedReplySize);
+ }
+ });
+ }
+
+ }
+
+ void Merge() {
+ while (MergeIteration())
+ ;
+ }
+
+ bool MergeIteration() {
+ for (;;) {
+ const TReplSstStreamWriter::EState state = Writer.GetState();
+ const bool noWorkForWriter = RecoveryQueue.empty() || RecoveryQueue.front().IsHugeBlob;
+ if (state == TReplSstStreamWriter::EState::COLLECT) {
+ Y_VERIFY(!WriterFinished);
+ break;
+ } else if (state == TReplSstStreamWriter::EState::STOPPED && noWorkForWriter) {
+ break;
+ }
+
+ switch (state) {
+ case TReplSstStreamWriter::EState::STOPPED:
+ Y_VERIFY(RecoveryQueue && !RecoveryQueue.front().IsHugeBlob && !WriterFinished);
+ Writer.Begin();
+ break;
+
+ case TReplSstStreamWriter::EState::PDISK_MESSAGE_PENDING: {
+ // obtain pending message
+ std::unique_ptr<IEventBase> msg = Writer.GetPendingPDiskMsg();
+
+ // if this is chunk write, then check if we are writing new chunk; if so, count it
+ if (msg->Type() == TEvBlobStorage::EvChunkWrite) {
+ auto *write = static_cast<NPDisk::TEvChunkWrite*>(msg.get());
+ // if we have seen new chunk index, then increase some counters
+ if (WrittenChunkIdxSet.insert(write->ChunkIdx).second) {
+ ++ReplInfo->ChunksWritten;
++ReplCtx->MonGroup.ReplChunksWritten();
- }
- const ui64 bytes = write->PartsPtr ? write->PartsPtr->ByteSize() : 0;
- ReplInfo->SstBytesWritten += bytes;
- // and check if we have to postpone it
- TReplQuoter::QuoteMessage(ReplCtx->VCtx->ReplPDiskWriteQuoter, std::make_unique<IEventHandle>(
- ReplCtx->PDiskCtx->PDiskId, SelfId(), msg.release()), bytes);
- } else {
- Send(ReplCtx->PDiskCtx->PDiskId, msg.release());
- }
- break;
- }
-
- case TReplSstStreamWriter::EState::NOT_READY:
- TimeAccount.SetState(ETimeState::PDISK_OP);
- return false; // we can't proceed right now
-
- case TReplSstStreamWriter::EState::COLLECT:
- Y_FAIL(); // should have exited a few lines above
-
- case TReplSstStreamWriter::EState::COMMIT_PENDING: {
- // acquire commit message from writer and send to the level index actor, writer state will
- // automatically switch to WAITING_FOR_COMMIT after this stage
- auto msg = Writer.GetPendingCommitMsg();
- msg->NotifyId = SelfId(); // receive notification after commit
- TimeAccount.SetState(ETimeState::COMMIT);
- Send(ReplCtx->HullDs->LogoBlobs->LIActor, msg.release());
- return false; // no further processing now
- }
-
- case TReplSstStreamWriter::EState::WAITING_FOR_COMMIT:
- return false; // just waiting for something to happen
-
- case TReplSstStreamWriter::EState::ERROR:
- Y_FAIL("replication failed"); // FIXME: do something sane
-
- default:
- Y_FAIL("unexpected state");
- }
- }
-
- // preprocess existing items, if any
- switch (ProcessQueue()) {
- case EProcessQueueAction::Continue:
- break;
- case EProcessQueueAction::Restart:
- return true;
- case EProcessQueueAction::Exit:
- return false;
- }
-
- // merge queue is not empty, but we are waiting for some events from proxies to come
- Y_VERIFY_DEBUG(MergeHeap.size() <= NumRunningProxies);
- if (MergeHeap.size() != NumRunningProxies) {
- return false;
- }
-
- if (PhantomCheckPending) {
- return false; // still waiting for proxy response about phantom validation
- }
-
- while (!MergeHeap.empty()) {
- TimeAccount.SetState(ETimeState::MERGE);
-
- // check that we have no missing proxies in merger queue (i.e. awaiting TEvReplProxyNextResult)
- Y_VERIFY_DEBUG(MergeHeap.size() == NumRunningProxies);
-
- // acquire current key; front item contains the least key
- if (!CurrentKey) {
- auto& front = MergeHeap.front();
- CurrentKey = front->GenLogoBlobId();
- CurrentParts.emplace(ReplCtx->VCtx->Top->GType);
- Y_VERIFY(LastProcessedKey < *CurrentKey);
- LastProcessedKey = *CurrentKey;
- }
-
- // find out which proxies carry items with the same key
+ }
+ const ui64 bytes = write->PartsPtr ? write->PartsPtr->ByteSize() : 0;
+ ReplInfo->SstBytesWritten += bytes;
+ // and check if we have to postpone it
+ TReplQuoter::QuoteMessage(ReplCtx->VCtx->ReplPDiskWriteQuoter, std::make_unique<IEventHandle>(
+ ReplCtx->PDiskCtx->PDiskId, SelfId(), msg.release()), bytes);
+ } else {
+ Send(ReplCtx->PDiskCtx->PDiskId, msg.release());
+ }
+ break;
+ }
+
+ case TReplSstStreamWriter::EState::NOT_READY:
+ TimeAccount.SetState(ETimeState::PDISK_OP);
+ return false; // we can't proceed right now
+
+ case TReplSstStreamWriter::EState::COLLECT:
+ Y_FAIL(); // should have exited a few lines above
+
+ case TReplSstStreamWriter::EState::COMMIT_PENDING: {
+ // acquire commit message from writer and send to the level index actor, writer state will
+ // automatically switch to WAITING_FOR_COMMIT after this stage
+ auto msg = Writer.GetPendingCommitMsg();
+ msg->NotifyId = SelfId(); // receive notification after commit
+ TimeAccount.SetState(ETimeState::COMMIT);
+ Send(ReplCtx->HullDs->LogoBlobs->LIActor, msg.release());
+ return false; // no further processing now
+ }
+
+ case TReplSstStreamWriter::EState::WAITING_FOR_COMMIT:
+ return false; // just waiting for something to happen
+
+ case TReplSstStreamWriter::EState::ERROR:
+ Y_FAIL("replication failed"); // FIXME: do something sane
+
+ default:
+ Y_FAIL("unexpected state");
+ }
+ }
+
+ // preprocess existing items, if any
+ switch (ProcessQueue()) {
+ case EProcessQueueAction::Continue:
+ break;
+ case EProcessQueueAction::Restart:
+ return true;
+ case EProcessQueueAction::Exit:
+ return false;
+ }
+
+ // merge queue is not empty, but we are waiting for some events from proxies to come
+ Y_VERIFY_DEBUG(MergeHeap.size() <= NumRunningProxies);
+ if (MergeHeap.size() != NumRunningProxies) {
+ return false;
+ }
+
+ if (PhantomCheckPending) {
+ return false; // still waiting for proxy response about phantom validation
+ }
+
+ while (!MergeHeap.empty()) {
+ TimeAccount.SetState(ETimeState::MERGE);
+
+ // check that we have no missing proxies in merger queue (i.e. awaiting TEvReplProxyNextResult)
+ Y_VERIFY_DEBUG(MergeHeap.size() == NumRunningProxies);
+
+ // acquire current key; front item contains the least key
+ if (!CurrentKey) {
+ auto& front = MergeHeap.front();
+ CurrentKey = front->GenLogoBlobId();
+ CurrentParts.emplace(ReplCtx->VCtx->Top->GType);
+ Y_VERIFY(LastProcessedKey < *CurrentKey);
+ LastProcessedKey = *CurrentKey;
+ }
+
+ // find out which proxies carry items with the same key
TVector<TVDiskProxyPtr>::iterator lastIter = MergeHeap.end();
- while (lastIter != MergeHeap.begin() && MergeHeap.front()->GenLogoBlobId() == *CurrentKey) {
- PopHeap(MergeHeap.begin(), lastIter, TVDiskProxy::TPtrGreater());
- --lastIter;
+ while (lastIter != MergeHeap.begin() && MergeHeap.front()->GenLogoBlobId() == *CurrentKey) {
+ PopHeap(MergeHeap.begin(), lastIter, TVDiskProxy::TPtrGreater());
+ --lastIter;
}
-
- // now proxies in range [ lastIter, MergeHeap.end() ) have the same current key; some of them may
- // contain runs of items with this key, so we should check it also; process those proxies and put
- // data to merger
- while (lastIter != MergeHeap.end()) {
- // process all items with specified current key
- TVDiskProxyPtr proxy = *lastIter;
- while (proxy->Valid() && proxy->GenLogoBlobId() == *CurrentKey) {
- TLogoBlobID id;
- NKikimrProto::EReplyStatus status;
+
+ // now proxies in range [ lastIter, MergeHeap.end() ) have the same current key; some of them may
+ // contain runs of items with this key, so we should check it also; process those proxies and put
+ // data to merger
+ while (lastIter != MergeHeap.end()) {
+ // process all items with specified current key
+ TVDiskProxyPtr proxy = *lastIter;
+ while (proxy->Valid() && proxy->GenLogoBlobId() == *CurrentKey) {
+ TLogoBlobID id;
+ NKikimrProto::EReplyStatus status;
TTrackableString data(TMemoryConsumer(ReplCtx->VCtx->Replication));
- proxy->GetData(&id, &status, &data);
- if (status != NKikimrProto::OK || data.size()) {
- CurrentParts->AddData(ReplCtx->VCtx->Top->GetOrderNumber(proxy->VDiskId), id, status, data.GetBaseConstRef());
- }
- proxy->Next();
- }
-
- // if proxy is not exhausted yet, then put it back into merge queue
- if (proxy->Valid()) {
- PushHeap(MergeHeap.begin(), ++lastIter, TVDiskProxy::TPtrGreater());
- } else {
- // there's no more data in proxy, we don't put it back to merger; moreover we remove this
- // proxy from merger queue and check if it is in EOF state or just needs some more requests
- // to VDisk
- DoSwap(*lastIter, MergeHeap.back());
- MergeHeap.pop_back();
- if (proxy->IsEof()) {
- // count this proxy as finished one
- STLOG(PRI_DEBUG, BS_REPL, BSVR05, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
- "proxy finished"), (VDiskId, proxy->VDiskId));
- --NumRunningProxies;
- } else {
- // put this proxy on wait queue
- proxy->SendNextRequest();
- }
- }
- }
-
- // if we're waiting for proxy data to arrive, then exit main cycle
- if (MergeHeap.size() != NumRunningProxies) {
- TimeAccount.SetState(ETimeState::PROXY_WAIT);
- return false;
- }
-
- // recover data
- TRecoveryMachine::EPhantomState phantom = TRecoveryMachine::EPhantomState::Unknown;
- RecoveryMachine->Recover(*CurrentKey, *CurrentParts, RecoveryQueue, phantom);
- if (phantom == TRecoveryMachine::EPhantomState::Check) {
- STLOG(PRI_INFO, BS_REPL, BSVR33, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "Sending phantom validation query"),
- (GroupId, GInfo->GroupID), (CurKey, *CurrentKey));
-
- auto ev = std::make_unique<TEvBlobStorage::TEvGet>(*CurrentKey, 0, 0, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead);
- ev->PhantomCheck = true;
- SendToBSProxy(SelfId(), GInfo->GroupID, ev.release());
-
- PhantomCheckPending = true;
-
- TimeAccount.SetState(ETimeState::PHANTOM);
- return false;
- }
- CurrentKey.reset();
- CurrentParts.reset();
-
- // process recovered items, if any; queueProcessed.first will be false when writer is not ready for new data
- EProcessQueueAction action = ProcessQueue();
-
- // if merger state has changed, then restart merge cycle; maybe writer wants to put some chunks to disks or make a commit
- if (action != EProcessQueueAction::Continue) {
- TimeAccount.SetState(ETimeState::OTHER);
- switch (action) {
- case EProcessQueueAction::Restart:
- return true;
- case EProcessQueueAction::Exit:
- return false;
- default:
+ proxy->GetData(&id, &status, &data);
+ if (status != NKikimrProto::OK || data.size()) {
+ CurrentParts->AddData(ReplCtx->VCtx->Top->GetOrderNumber(proxy->VDiskId), id, status, data.GetBaseConstRef());
+ }
+ proxy->Next();
+ }
+
+ // if proxy is not exhausted yet, then put it back into merge queue
+ if (proxy->Valid()) {
+ PushHeap(MergeHeap.begin(), ++lastIter, TVDiskProxy::TPtrGreater());
+ } else {
+ // there's no more data in proxy, we don't put it back to merger; moreover we remove this
+ // proxy from merger queue and check if it is in EOF state or just needs some more requests
+ // to VDisk
+ DoSwap(*lastIter, MergeHeap.back());
+ MergeHeap.pop_back();
+ if (proxy->IsEof()) {
+ // count this proxy as finished one
+ STLOG(PRI_DEBUG, BS_REPL, BSVR05, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
+ "proxy finished"), (VDiskId, proxy->VDiskId));
+ --NumRunningProxies;
+ } else {
+ // put this proxy on wait queue
+ proxy->SendNextRequest();
+ }
+ }
+ }
+
+ // if we're waiting for proxy data to arrive, then exit main cycle
+ if (MergeHeap.size() != NumRunningProxies) {
+ TimeAccount.SetState(ETimeState::PROXY_WAIT);
+ return false;
+ }
+
+ // recover data
+ TRecoveryMachine::EPhantomState phantom = TRecoveryMachine::EPhantomState::Unknown;
+ RecoveryMachine->Recover(*CurrentKey, *CurrentParts, RecoveryQueue, phantom);
+ if (phantom == TRecoveryMachine::EPhantomState::Check) {
+ STLOG(PRI_INFO, BS_REPL, BSVR33, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "Sending phantom validation query"),
+ (GroupId, GInfo->GroupID), (CurKey, *CurrentKey));
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvGet>(*CurrentKey, 0, 0, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead);
+ ev->PhantomCheck = true;
+ SendToBSProxy(SelfId(), GInfo->GroupID, ev.release());
+
+ PhantomCheckPending = true;
+
+ TimeAccount.SetState(ETimeState::PHANTOM);
+ return false;
+ }
+ CurrentKey.reset();
+ CurrentParts.reset();
+
+ // process recovered items, if any; queueProcessed.first will be false when writer is not ready for new data
+ EProcessQueueAction action = ProcessQueue();
+
+ // if merger state has changed, then restart merge cycle; maybe writer wants to put some chunks to disks or make a commit
+ if (action != EProcessQueueAction::Continue) {
+ TimeAccount.SetState(ETimeState::OTHER);
+ switch (action) {
+ case EProcessQueueAction::Restart:
+ return true;
+ case EProcessQueueAction::Exit:
+ return false;
+ default:
Y_FAIL("invalid EProcessQueueAction");
- }
- }
- }
-
- Y_VERIFY(!NumRunningProxies && MergeHeap.empty() && RecoveryQueue.empty());
- TimeAccount.SetState(ETimeState::OTHER);
-
- if (!RecoveryMachineFinished) {
- RecoveryMachine->Finish(RecoveryQueue);
- RecoveryMachineFinished = true;
- STLOG(PRI_DEBUG, BS_REPL, BSVR07, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished recovery machine"),
- (RecoveryQueueSize, RecoveryQueue.size()));
- return true;
- }
-
- if (!WriterFinished && Writer.GetState() != TReplSstStreamWriter::EState::STOPPED) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR08, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished writer"));
- Writer.Finish();
- WriterFinished = true;
- return true;
- }
-
- if (HugeBlobsInFlight != 0) {
- // do not finish until all in-flight requests are completed
- STLOG(PRI_DEBUG, BS_REPL, BSVR09, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "huge blobs unwritten"),
- (HugeBlobsInFlight, HugeBlobsInFlight));
- return false;
+ }
+ }
}
- if (Writer.GetState() == TReplSstStreamWriter::EState::STOPPED) {
+ Y_VERIFY(!NumRunningProxies && MergeHeap.empty() && RecoveryQueue.empty());
+ TimeAccount.SetState(ETimeState::OTHER);
+
+ if (!RecoveryMachineFinished) {
+ RecoveryMachine->Finish(RecoveryQueue);
+ RecoveryMachineFinished = true;
+ STLOG(PRI_DEBUG, BS_REPL, BSVR07, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished recovery machine"),
+ (RecoveryQueueSize, RecoveryQueue.size()));
+ return true;
+ }
+
+ if (!WriterFinished && Writer.GetState() != TReplSstStreamWriter::EState::STOPPED) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR08, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "finished writer"));
+ Writer.Finish();
+ WriterFinished = true;
+ return true;
+ }
+
+ if (HugeBlobsInFlight != 0) {
+ // do not finish until all in-flight requests are completed
+ STLOG(PRI_DEBUG, BS_REPL, BSVR09, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "huge blobs unwritten"),
+ (HugeBlobsInFlight, HugeBlobsInFlight));
+ return false;
+ }
+
+ if (Writer.GetState() == TReplSstStreamWriter::EState::STOPPED) {
Y_VERIFY(RecoveryQueue.empty());
- Finish();
- return false;
- }
-
+ Finish();
+ return false;
+ }
+
Y_FAIL("incorrect merger state State# %" PRIu32, ui32(Writer.GetState()));
}
- void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
- STLOG(PRI_INFO, BS_REPL, BSVR34, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "Received phantom validation reply"),
- (Msg, ev->Get()->ToString()));
- Y_VERIFY(PhantomCheckPending);
- Y_VERIFY(CurrentKey);
- Y_VERIFY(CurrentParts);
- TRecoveryMachine::EPhantomState phantom = TRecoveryMachine::EPhantomState::NonPhantom;
- auto *msg = ev->Get();
- if (msg->Status == NKikimrProto::OK) {
- Y_VERIFY(msg->ResponseSz == 1);
- auto& r = msg->Responses[0];
- Y_VERIFY(r.Id == *CurrentKey);
- if (r.Status == NKikimrProto::NODATA) {
- Phantoms.push_back(r.Id);
- phantom = TRecoveryMachine::EPhantomState::Phantom;
- }
- }
- RecoveryMachine->Recover(*CurrentKey, *CurrentParts, RecoveryQueue, phantom);
- PhantomCheckPending = false;
- CurrentKey.reset();
- CurrentParts.reset();
- Merge();
- }
-
- EProcessQueueAction ProcessQueue() {
- while (!RecoveryQueue.empty()) {
- auto& front = RecoveryQueue.front();
-
- // special handling of hugeblobs through Skeleton
- if (front.IsHugeBlob) {
- if (HugeBlobsInFlight == HugeBlobsInFlightMax) {
- // we are already at in flight limit, do not accept more messages
- return EProcessQueueAction::Exit;
- }
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr ev) {
+ STLOG(PRI_INFO, BS_REPL, BSVR34, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "Received phantom validation reply"),
+ (Msg, ev->Get()->ToString()));
+ Y_VERIFY(PhantomCheckPending);
+ Y_VERIFY(CurrentKey);
+ Y_VERIFY(CurrentParts);
+ TRecoveryMachine::EPhantomState phantom = TRecoveryMachine::EPhantomState::NonPhantom;
+ auto *msg = ev->Get();
+ if (msg->Status == NKikimrProto::OK) {
+ Y_VERIFY(msg->ResponseSz == 1);
+ auto& r = msg->Responses[0];
+ Y_VERIFY(r.Id == *CurrentKey);
+ if (r.Status == NKikimrProto::NODATA) {
+ Phantoms.push_back(r.Id);
+ phantom = TRecoveryMachine::EPhantomState::Phantom;
+ }
+ }
+ RecoveryMachine->Recover(*CurrentKey, *CurrentParts, RecoveryQueue, phantom);
+ PhantomCheckPending = false;
+ CurrentKey.reset();
+ CurrentParts.reset();
+ Merge();
+ }
+
+ EProcessQueueAction ProcessQueue() {
+ while (!RecoveryQueue.empty()) {
+ auto& front = RecoveryQueue.front();
+
+ // special handling of hugeblobs through Skeleton
+ if (front.IsHugeBlob) {
+ if (HugeBlobsInFlight == HugeBlobsInFlightMax) {
+ // we are already at in flight limit, do not accept more messages
+ return EProcessQueueAction::Exit;
+ }
Y_VERIFY(HugeBlobsInFlight < HugeBlobsInFlightMax);
- ++HugeBlobsInFlight;
-
+ ++HugeBlobsInFlight;
+
++ReplCtx->MonGroup.ReplHugeBlobsRecovered();
- ReplCtx->MonGroup.ReplHugeBlobBytesRecovered() += front.Data.GetSize();
-
- const ui64 bytes = front.Data.GetSize();
- TReplQuoter::QuoteMessage(ReplCtx->VCtx->ReplPDiskWriteQuoter, std::make_unique<IEventHandle>(
- ReplCtx->SkeletonId, SelfId(), new TEvRecoveredHugeBlob(front.Id, std::move(front.Data))),
- bytes);
-
- RecoveryQueue.pop();
- continue;
- }
-
- switch (Writer.GetState()) {
- case TReplSstStreamWriter::EState::STOPPED:
- return EProcessQueueAction::Restart;
- case TReplSstStreamWriter::EState::COLLECT:
- break;
- default:
+ ReplCtx->MonGroup.ReplHugeBlobBytesRecovered() += front.Data.GetSize();
+
+ const ui64 bytes = front.Data.GetSize();
+ TReplQuoter::QuoteMessage(ReplCtx->VCtx->ReplPDiskWriteQuoter, std::make_unique<IEventHandle>(
+ ReplCtx->SkeletonId, SelfId(), new TEvRecoveredHugeBlob(front.Id, std::move(front.Data))),
+ bytes);
+
+ RecoveryQueue.pop();
+ continue;
+ }
+
+ switch (Writer.GetState()) {
+ case TReplSstStreamWriter::EState::STOPPED:
+ return EProcessQueueAction::Restart;
+ case TReplSstStreamWriter::EState::COLLECT:
+ break;
+ default:
Y_FAIL("unexpected State# %" PRIu32, static_cast<ui32>(Writer.GetState()));
- }
-
- if (Writer.AddRecoveredBlob(front)) {
- if (front.LocalParts.CountBits() > 1) {
+ }
+
+ if (Writer.AddRecoveredBlob(front)) {
+ if (front.LocalParts.CountBits() > 1) {
++ReplInfo->MultipartBlobs;
- }
-
+ }
+
++ReplCtx->MonGroup.ReplBlobsRecovered();
- ReplCtx->MonGroup.ReplBlobBytesRecovered() += front.Data.GetSize();
- RecoveryQueue.pop();
- }
-
- // restart cycle if we have output data pending or something has changed
- if (Writer.GetState() != TReplSstStreamWriter::EState::COLLECT) {
- return EProcessQueueAction::Restart;
- }
- }
-
- return EProcessQueueAction::Continue;
- }
-
- void HandleYard(NPDisk::TEvChunkWriteResult::TPtr& ev) {
- CHECK_PDISK_RESPONSE(ReplCtx->VCtx, ev, TActivationContext::ActorContextFor(SelfId()));
- Writer.Apply(ev->Get());
- Merge();
- }
-
- void HandleYard(NPDisk::TEvChunkReserveResult::TPtr& ev) {
- CHECK_PDISK_RESPONSE(ReplCtx->VCtx, ev, TActivationContext::ActorContextFor(SelfId()));
- STLOG(PRI_INFO, BS_REPL, BSVR10, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "reserved chunks"),
- (ChunkIds, FormatList(ev->Get()->ChunkIds)));
- Writer.Apply(ev->Get());
- Merge();
- }
-
- void Handle(TEvReplProxyNextResult::TPtr &ev) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR11, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
- "THullReplJobActor::Handle(TEvReplProxyNextResult)"));
- TEvReplProxyNextResult *msg = ev->Get();
- TIntrusivePtr<TVDiskProxy> proxy = DiskProxySet.at(Donor ? 0 : ReplCtx->VCtx->Top->GetOrderNumber(msg->VDiskId));
- proxy->HandleNext(ev);
-
- if (proxy->IsEof()) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR12, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "proxy finished"),
- (VDiskId, msg->VDiskId.ToString()));
- --NumRunningProxies;
- } else {
+ ReplCtx->MonGroup.ReplBlobBytesRecovered() += front.Data.GetSize();
+ RecoveryQueue.pop();
+ }
+
+ // restart cycle if we have output data pending or something has changed
+ if (Writer.GetState() != TReplSstStreamWriter::EState::COLLECT) {
+ return EProcessQueueAction::Restart;
+ }
+ }
+
+ return EProcessQueueAction::Continue;
+ }
+
+ void HandleYard(NPDisk::TEvChunkWriteResult::TPtr& ev) {
+ CHECK_PDISK_RESPONSE(ReplCtx->VCtx, ev, TActivationContext::ActorContextFor(SelfId()));
+ Writer.Apply(ev->Get());
+ Merge();
+ }
+
+ void HandleYard(NPDisk::TEvChunkReserveResult::TPtr& ev) {
+ CHECK_PDISK_RESPONSE(ReplCtx->VCtx, ev, TActivationContext::ActorContextFor(SelfId()));
+ STLOG(PRI_INFO, BS_REPL, BSVR10, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "reserved chunks"),
+ (ChunkIds, FormatList(ev->Get()->ChunkIds)));
+ Writer.Apply(ev->Get());
+ Merge();
+ }
+
+ void Handle(TEvReplProxyNextResult::TPtr &ev) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR11, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
+ "THullReplJobActor::Handle(TEvReplProxyNextResult)"));
+ TEvReplProxyNextResult *msg = ev->Get();
+ TIntrusivePtr<TVDiskProxy> proxy = DiskProxySet.at(Donor ? 0 : ReplCtx->VCtx->Top->GetOrderNumber(msg->VDiskId));
+ proxy->HandleNext(ev);
+
+ if (proxy->IsEof()) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR12, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "proxy finished"),
+ (VDiskId, msg->VDiskId.ToString()));
+ --NumRunningProxies;
+ } else {
Y_VERIFY(proxy->Valid());
- MergeHeap.push_back(proxy);
- PushHeap(MergeHeap.begin(), MergeHeap.end(), TVDiskProxy::TPtrGreater());
- }
-
- STLOG(PRI_DEBUG, BS_REPL, BSVR13, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
- "THullReplJobActor::Handle(TEvReplProxyNextResult)"), (MergeHeapSize, MergeHeap.size()),
- (NumRunningProxies, NumRunningProxies));
-
- if (MergeHeap.size() == NumRunningProxies) {
+ MergeHeap.push_back(proxy);
+ PushHeap(MergeHeap.begin(), MergeHeap.end(), TVDiskProxy::TPtrGreater());
+ }
+
+ STLOG(PRI_DEBUG, BS_REPL, BSVR13, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
+ "THullReplJobActor::Handle(TEvReplProxyNextResult)"), (MergeHeapSize, MergeHeap.size()),
+ (NumRunningProxies, NumRunningProxies));
+
+ if (MergeHeap.size() == NumRunningProxies) {
Become(&TThis::StateMerge);
- Merge();
+ Merge();
}
}
- void Handle(TEvAddBulkSstResult::TPtr& ev) {
+ void Handle(TEvAddBulkSstResult::TPtr& ev) {
Y_UNUSED(ev);
- Writer.ApplyCommit();
- Merge();
- }
-
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr& /*ev*/) {
+ Writer.ApplyCommit();
+ Merge();
+ }
+
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr& /*ev*/) {
// FIXME: Handle NotOK
- // this message is received when huge blob is written by Skeleton
+ // this message is received when huge blob is written by Skeleton
Y_VERIFY(HugeBlobsInFlight != 0);
- --HugeBlobsInFlight;
- Merge();
+ --HugeBlobsInFlight;
+ Merge();
+ }
+
+ void PassAway() override {
+ ActiveActors.KillAndClear(TActivationContext::ActorContextFor(SelfId()));
+ TActorBootstrapped::PassAway();
}
- void PassAway() override {
- ActiveActors.KillAndClear(TActivationContext::ActorContextFor(SelfId()));
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StatePreparePlan,
- hFunc(TEvReplPlanFinished, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- )
-
- STRICT_STFUNC(StateMerge,
- hFunc(TEvReplProxyNextResult, Handle)
-
- // yard messages coming to Writer
- hFunc(NPDisk::TEvChunkWriteResult, HandleYard)
- hFunc(NPDisk::TEvChunkReserveResult, HandleYard)
- hFunc(TEvBlobStorage::TEvGetResult, Handle)
- hFunc(TEvAddBulkSstResult, Handle)
- hFunc(TEvBlobStorage::TEvVPutResult, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- )
-
- STRICT_STFUNC(StateInit,
- hFunc(TEvReplProxyNextResult, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- )
-
- STRICT_STFUNC(StateToken,
- cFunc(TEvBlobStorage::EvReplResume, HandleResume)
- cFunc(TEvents::TSystem::Poison, PassAway)
- )
-
- STATEFN(TerminateStateFunc) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvents::TSystem::Poison, PassAway)
- }
- }
+ STRICT_STFUNC(StatePreparePlan,
+ hFunc(TEvReplPlanFinished, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ )
+
+ STRICT_STFUNC(StateMerge,
+ hFunc(TEvReplProxyNextResult, Handle)
+
+ // yard messages coming to Writer
+ hFunc(NPDisk::TEvChunkWriteResult, HandleYard)
+ hFunc(NPDisk::TEvChunkReserveResult, HandleYard)
+ hFunc(TEvBlobStorage::TEvGetResult, Handle)
+ hFunc(TEvAddBulkSstResult, Handle)
+ hFunc(TEvBlobStorage::TEvVPutResult, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ )
+
+ STRICT_STFUNC(StateInit,
+ hFunc(TEvReplProxyNextResult, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ )
+
+ STRICT_STFUNC(StateToken,
+ cFunc(TEvBlobStorage::EvReplResume, HandleResume)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ )
+
+ STATEFN(TerminateStateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ }
+ }
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_REPL_JOB;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_REPL_JOB;
}
THullReplJobActor(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
const TActorId &parentId,
const TLogoBlobID &startKey,
TQueueActorMapPtr&& queueActorMapPtr,
TBlobIdQueuePtr&& blobsToReplicatePtr,
- TBlobIdQueuePtr&& unreplicatedBlobsPtr,
- const std::optional<std::pair<TVDiskID, TActorId>>& donor)
+ TBlobIdQueuePtr&& unreplicatedBlobsPtr,
+ const std::optional<std::pair<TVDiskID, TActorId>>& donor)
: TActorBootstrapped<THullReplJobActor>()
, ReplCtx(std::move(replCtx))
- , GInfo(ReplCtx->GInfo) // it is safe to take it here
+ , GInfo(ReplCtx->GInfo) // it is safe to take it here
, ParentId(parentId)
, StartKey(startKey)
, ReplInfo(new TEvReplFinished::TInfo())
- , Writer(ReplCtx, ReplCtx->HullDs)
- , RecoveryMachineFinished(false)
- , WriterFinished(false)
- , HugeBlobsInFlight(0)
- , HugeBlobsInFlightMax(3)
+ , Writer(ReplCtx, ReplCtx->HullDs)
+ , RecoveryMachineFinished(false)
+ , WriterFinished(false)
+ , HugeBlobsInFlight(0)
+ , HugeBlobsInFlightMax(3)
, QueueActorMapPtr(std::move(queueActorMapPtr))
- , BlobsToReplicatePtr(blobsToReplicatePtr)
- , UnreplicatedBlobsPtr(unreplicatedBlobsPtr)
- , Donor(donor)
- {
- if (Donor) {
- ReplInfo->DonorVDiskId = Donor->first;
- }
- }
+ , BlobsToReplicatePtr(blobsToReplicatePtr)
+ , UnreplicatedBlobsPtr(unreplicatedBlobsPtr)
+ , Donor(donor)
+ {
+ if (Donor) {
+ ReplInfo->DonorVDiskId = Donor->first;
+ }
+ }
};
@@ -824,16 +824,16 @@ namespace NKikimr {
// CreateReplJobActor
////////////////////////////////////////////////////////////////////////////
IActor *CreateReplJobActor(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
const TActorId &parentId,
const TLogoBlobID &startKey,
- TQueueActorMapPtr queueActorMapPtr,
- TBlobIdQueuePtr blobsToReplicatePtr,
- TBlobIdQueuePtr unreplicatedBlobsPtr,
- const std::optional<std::pair<TVDiskID, TActorId>>& donor)
+ TQueueActorMapPtr queueActorMapPtr,
+ TBlobIdQueuePtr blobsToReplicatePtr,
+ TBlobIdQueuePtr unreplicatedBlobsPtr,
+ const std::optional<std::pair<TVDiskID, TActorId>>& donor)
{
- return new THullReplJobActor(std::move(replCtx), parentId, startKey, std::move(queueActorMapPtr),
- std::move(blobsToReplicatePtr), std::move(unreplicatedBlobsPtr), donor);
+ return new THullReplJobActor(std::move(replCtx), parentId, startKey, std::move(queueActorMapPtr),
+ std::move(blobsToReplicatePtr), std::move(unreplicatedBlobsPtr), donor);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.h
index 8f7d43fb29a..83edb321253 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullrepljob.h
@@ -11,12 +11,12 @@ namespace NKikimr {
// CreateReplJobActor
////////////////////////////////////////////////////////////////////////////
IActor *CreateReplJobActor(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
const TActorId &parentId,
const TLogoBlobID &startKey,
- TQueueActorMapPtr queueActorMapPtr,
- TBlobIdQueuePtr blobsToReplicatePtr,
- TBlobIdQueuePtr unreplicatedBlobsPtr,
- const std::optional<std::pair<TVDiskID, TActorId>>& donor);
+ TQueueActorMapPtr queueActorMapPtr,
+ TBlobIdQueuePtr blobsToReplicatePtr,
+ TBlobIdQueuePtr unreplicatedBlobsPtr,
+ const std::optional<std::pair<TVDiskID, TActorId>>& donor);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h
index f4f0e49015f..11205249908 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h
@@ -1,288 +1,288 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_repl.h"
+#include "blobstorage_repl.h"
#include <ydb/core/blobstorage/vdisk/hulldb/hull_ds_all.h>
#include <ydb/core/blobstorage/vdisk/hulldb/generic/blobstorage_hullwritesst.h>
#include <ydb/core/blobstorage/vdisk/hulldb/hulldb_bulksst_add.h>
-
-namespace NKikimr {
-
- class TReplSstStreamWriter
- {
+
+namespace NKikimr {
+
+ class TReplSstStreamWriter
+ {
using TWriter = TLogoBlobsSst::TWriter;
-
- public:
- struct TRecoveredBlobInfo {
- TLogoBlobID Id;
- TRope Data;
- bool IsHugeBlob;
+
+ public:
+ struct TRecoveredBlobInfo {
+ TLogoBlobID Id;
+ TRope Data;
+ bool IsHugeBlob;
NMatrix::TVectorType LocalParts;
-
- TRecoveredBlobInfo(const TLogoBlobID& id, TRope&& data, bool isHugeBlob, NMatrix::TVectorType localParts)
- : Id(id)
- , Data(std::move(data))
- , IsHugeBlob(isHugeBlob)
- , LocalParts(localParts)
- {}
- };
-
- enum class EState {
- INVALID, // impossible state
- STOPPED, // doing nothing
- PDISK_MESSAGE_PENDING, // we have a message for PDisk
- NOT_READY, // we are waiting for some kind of external action (expecting response from PDisk)
- COLLECT, // ready for new blobs
- COMMIT_PENDING, // we have a commit message for Skeleton
- WAITING_FOR_COMMIT, // waiting for commit operation to finish
- ERROR, // something gone wrong, further operation impossible
- };
-
- enum class EOutputState {
- INVALID,
- INTERMEDIATE_CHUNK,
- FLUSH_CHUNK,
- FLUSH_LAST_CHUNK,
- };
-
- public:
+
+ TRecoveredBlobInfo(const TLogoBlobID& id, TRope&& data, bool isHugeBlob, NMatrix::TVectorType localParts)
+ : Id(id)
+ , Data(std::move(data))
+ , IsHugeBlob(isHugeBlob)
+ , LocalParts(localParts)
+ {}
+ };
+
+ enum class EState {
+ INVALID, // impossible state
+ STOPPED, // doing nothing
+ PDISK_MESSAGE_PENDING, // we have a message for PDisk
+ NOT_READY, // we are waiting for some kind of external action (expecting response from PDisk)
+ COLLECT, // ready for new blobs
+ COMMIT_PENDING, // we have a commit message for Skeleton
+ WAITING_FOR_COMMIT, // waiting for commit operation to finish
+ ERROR, // something gone wrong, further operation impossible
+ };
+
+ enum class EOutputState {
+ INVALID,
+ INTERMEDIATE_CHUNK,
+ FLUSH_CHUNK,
+ FLUSH_LAST_CHUNK,
+ };
+
+ public:
TReplSstStreamWriter(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
TIntrusivePtr<THullDs> hullDs)
: ReplCtx(std::move(replCtx))
, HullDs(std::move(hullDs))
- , State(EState::STOPPED)
- , MinReservedChunksCount(ReplCtx->VDiskCfg->HullSstSizeInChunksFresh)
- , Arena(&TRopeArenaBackend::Allocate)
- {}
-
- void Begin() {
+ , State(EState::STOPPED)
+ , MinReservedChunksCount(ReplCtx->VDiskCfg->HullSstSizeInChunksFresh)
+ , Arena(&TRopeArenaBackend::Allocate)
+ {}
+
+ void Begin() {
Y_VERIFY(State == EState::STOPPED);
-
- // ensure that we have no pending message and create new one to allocate some chunks for replicated SST
- Y_VERIFY(!PendingPDiskMsg);
- PendingPDiskMsg = std::make_unique<NPDisk::TEvChunkReserve>(ReplCtx->PDiskCtx->Dsk->Owner,
- ReplCtx->PDiskCtx->Dsk->OwnerRound, MinReservedChunksCount - ReservedChunks.size());
- State = EState::PDISK_MESSAGE_PENDING;
-
- // initialize state
- PrevID = TLogoBlobID();
- NumRecoveredBlobs = 0;
- OutputState = EOutputState::INVALID;
- FlushFinished = false;
- }
-
- std::unique_ptr<IEventBase> GetPendingPDiskMsg() {
- Y_VERIFY(State == EState::PDISK_MESSAGE_PENDING);
- std::unique_ptr<IEventBase> msg = std::move(PendingPDiskMsg);
-
- if (auto write = dynamic_cast<NPDisk::TEvChunkWrite*>(msg.get())) {
- if (write->PartsPtr) {
- *ReplCtx->PDiskWriteBytes += write->PartsPtr->ByteSize();
- }
-
- // we are issuing write message; we should count it as in flight one and take some actions according
- // to the current state
- ++WritesInFlight;
- if (WritesInFlight == MaxWritesInFlight) {
- // in any output state we shall wait for at least one message to finish
- State = EState::NOT_READY;
- } else {
- switch (OutputState) {
- case EOutputState::INTERMEDIATE_CHUNK:
- // we are ready to process further blobs, so return to COLLECT state
- State = EState::COLLECT;
- break;
-
- case EOutputState::FLUSH_CHUNK:
- // we are flushing index right now, so continue with this job; FlushNextPart() will internally
- // call IssueWriteCmd if needed, and it will fill in next PendingPDiskMsg and set the State
- // accordingly
- FlushNextPart();
- break;
-
- case EOutputState::FLUSH_LAST_CHUNK:
- // we were writing last chunk part now and shall wait for all pending operations to complete
- State = EState::NOT_READY;
- break;
-
- default:
- Y_FAIL("unexpected OutputState");
- }
- }
- } else if (dynamic_cast<NPDisk::TEvChunkReserve*>(msg.get())) {
- // we are issuing chunk allocation message and shall wait for it to finish
- State = EState::NOT_READY;
- } else {
- Y_FAIL("unexpected message type");
- }
-
- return msg;
- }
-
+
+ // ensure that we have no pending message and create new one to allocate some chunks for replicated SST
+ Y_VERIFY(!PendingPDiskMsg);
+ PendingPDiskMsg = std::make_unique<NPDisk::TEvChunkReserve>(ReplCtx->PDiskCtx->Dsk->Owner,
+ ReplCtx->PDiskCtx->Dsk->OwnerRound, MinReservedChunksCount - ReservedChunks.size());
+ State = EState::PDISK_MESSAGE_PENDING;
+
+ // initialize state
+ PrevID = TLogoBlobID();
+ NumRecoveredBlobs = 0;
+ OutputState = EOutputState::INVALID;
+ FlushFinished = false;
+ }
+
+ std::unique_ptr<IEventBase> GetPendingPDiskMsg() {
+ Y_VERIFY(State == EState::PDISK_MESSAGE_PENDING);
+ std::unique_ptr<IEventBase> msg = std::move(PendingPDiskMsg);
+
+ if (auto write = dynamic_cast<NPDisk::TEvChunkWrite*>(msg.get())) {
+ if (write->PartsPtr) {
+ *ReplCtx->PDiskWriteBytes += write->PartsPtr->ByteSize();
+ }
+
+ // we are issuing write message; we should count it as in flight one and take some actions according
+ // to the current state
+ ++WritesInFlight;
+ if (WritesInFlight == MaxWritesInFlight) {
+ // in any output state we shall wait for at least one message to finish
+ State = EState::NOT_READY;
+ } else {
+ switch (OutputState) {
+ case EOutputState::INTERMEDIATE_CHUNK:
+ // we are ready to process further blobs, so return to COLLECT state
+ State = EState::COLLECT;
+ break;
+
+ case EOutputState::FLUSH_CHUNK:
+ // we are flushing index right now, so continue with this job; FlushNextPart() will internally
+ // call IssueWriteCmd if needed, and it will fill in next PendingPDiskMsg and set the State
+ // accordingly
+ FlushNextPart();
+ break;
+
+ case EOutputState::FLUSH_LAST_CHUNK:
+ // we were writing last chunk part now and shall wait for all pending operations to complete
+ State = EState::NOT_READY;
+ break;
+
+ default:
+ Y_FAIL("unexpected OutputState");
+ }
+ }
+ } else if (dynamic_cast<NPDisk::TEvChunkReserve*>(msg.get())) {
+ // we are issuing chunk allocation message and shall wait for it to finish
+ State = EState::NOT_READY;
+ } else {
+ Y_FAIL("unexpected message type");
+ }
+
+ return msg;
+ }
+
void Apply(NPDisk::TEvChunkReserveResult* ev) {
- Y_VERIFY(State == EState::NOT_READY);
-
- if (ev->Status != NKikimrProto::OK) {
- State = EState::ERROR;
- return;
- }
-
- for (ui32 chunkId : ev->ChunkIds) {
- ReservedChunks.push_back(chunkId);
- }
-
- // create new writer
- Y_VERIFY(!Writer);
- Writer = std::make_unique<TWriter>(ReplCtx->VCtx, EWriterDataType::Replication, 1, ReplCtx->PDiskCtx->Dsk->Owner,
+ Y_VERIFY(State == EState::NOT_READY);
+
+ if (ev->Status != NKikimrProto::OK) {
+ State = EState::ERROR;
+ return;
+ }
+
+ for (ui32 chunkId : ev->ChunkIds) {
+ ReservedChunks.push_back(chunkId);
+ }
+
+ // create new writer
+ Y_VERIFY(!Writer);
+ Writer = std::make_unique<TWriter>(ReplCtx->VCtx, EWriterDataType::Replication, 1, ReplCtx->PDiskCtx->Dsk->Owner,
ReplCtx->PDiskCtx->Dsk->OwnerRound, ReplCtx->PDiskCtx->Dsk->ChunkSize,
ReplCtx->PDiskCtx->Dsk->AppendBlockSize, ReplCtx->PDiskCtx->Dsk->BulkWriteBlockSize,
- HullDs->LogoBlobs->AllocSstId(), true, ReservedChunks, Arena);
-
- // start collecting blobs
- State = EState::COLLECT;
- }
-
- bool AddRecoveredBlob(TRecoveredBlobInfo& record) {
+ HullDs->LogoBlobs->AllocSstId(), true, ReservedChunks, Arena);
+
+ // start collecting blobs
+ State = EState::COLLECT;
+ }
+
+ bool AddRecoveredBlob(TRecoveredBlobInfo& record) {
Y_VERIFY(State == EState::COLLECT);
Y_VERIFY(record.Id > PrevID);
- Y_VERIFY(!record.Id.PartId());
-
- // generate merged ingress for all locally recovered parts
- TIngress ingress = TIngress::CreateFromRepl(ReplCtx->VCtx->Top.get(), ReplCtx->VCtx->ShortSelfVDisk,
+ Y_VERIFY(!record.Id.PartId());
+
+ // generate merged ingress for all locally recovered parts
+ TIngress ingress = TIngress::CreateFromRepl(ReplCtx->VCtx->Top.get(), ReplCtx->VCtx->ShortSelfVDisk,
record.Id, record.LocalParts);
-
- // add disk blob to merger (in order to write it to SSTable)
- Merger.AddBlob(TDiskBlob(&record.Data, record.LocalParts, ReplCtx->VCtx->Top->GType, record.Id));
-
- // create memory record for disk blob with correct length
- TMemRecLogoBlob memRec(ingress);
- memRec.SetDiskBlob(TDiskPart(0, 0, Merger.GetDiskBlobRawSize()));
-
- const bool success = Writer->Push(record.Id, memRec, &Merger);
- if (success) {
- if (auto msg = Writer->GetPendingMessage()) {
- IssueWriteCmd(std::move(msg), EOutputState::INTERMEDIATE_CHUNK);
- }
- PrevID = record.Id;
- ++NumRecoveredBlobs;
- } else {
- // out of space in current chunks, have to start flushing; logoblob is not written
- FlushNextPart();
- }
-
- Merger.Clear();
-
- return success;
- }
-
+
+ // add disk blob to merger (in order to write it to SSTable)
+ Merger.AddBlob(TDiskBlob(&record.Data, record.LocalParts, ReplCtx->VCtx->Top->GType, record.Id));
+
+ // create memory record for disk blob with correct length
+ TMemRecLogoBlob memRec(ingress);
+ memRec.SetDiskBlob(TDiskPart(0, 0, Merger.GetDiskBlobRawSize()));
+
+ const bool success = Writer->Push(record.Id, memRec, &Merger);
+ if (success) {
+ if (auto msg = Writer->GetPendingMessage()) {
+ IssueWriteCmd(std::move(msg), EOutputState::INTERMEDIATE_CHUNK);
+ }
+ PrevID = record.Id;
+ ++NumRecoveredBlobs;
+ } else {
+ // out of space in current chunks, have to start flushing; logoblob is not written
+ FlushNextPart();
+ }
+
+ Merger.Clear();
+
+ return success;
+ }
+
void Apply(NPDisk::TEvChunkWriteResult* ev) {
- if (ev->Status != NKikimrProto::OK) {
- State = EState::ERROR;
- return;
- }
-
- Y_VERIFY(WritesInFlight > 0);
- --WritesInFlight;
-
- // if we were blocked for some reason when issuing last message, try to determine what to do next
- if (State == EState::NOT_READY) {
- switch (OutputState) {
- case EOutputState::INTERMEDIATE_CHUNK:
- State = EState::COLLECT; // continue collecting blobs
- break;
-
- case EOutputState::FLUSH_CHUNK:
- FlushNextPart(); // continue flushing data
- break;
-
- case EOutputState::FLUSH_LAST_CHUNK:
- if (!WritesInFlight) {
- OnFlushComplete();
- }
- break;
-
- default:
- Y_FAIL("incorrect output state");
- }
- }
- }
-
- void Finish() {
+ if (ev->Status != NKikimrProto::OK) {
+ State = EState::ERROR;
+ return;
+ }
+
+ Y_VERIFY(WritesInFlight > 0);
+ --WritesInFlight;
+
+ // if we were blocked for some reason when issuing last message, try to determine what to do next
+ if (State == EState::NOT_READY) {
+ switch (OutputState) {
+ case EOutputState::INTERMEDIATE_CHUNK:
+ State = EState::COLLECT; // continue collecting blobs
+ break;
+
+ case EOutputState::FLUSH_CHUNK:
+ FlushNextPart(); // continue flushing data
+ break;
+
+ case EOutputState::FLUSH_LAST_CHUNK:
+ if (!WritesInFlight) {
+ OnFlushComplete();
+ }
+ break;
+
+ default:
+ Y_FAIL("incorrect output state");
+ }
+ }
+ }
+
+ void Finish() {
Y_VERIFY(State == EState::COLLECT, "unexpected State# %" PRIu32, static_cast<ui32>(State));
- FlushNextPart();
- }
-
- std::unique_ptr<TEvAddBulkSst> GetPendingCommitMsg() {
+ FlushNextPart();
+ }
+
+ std::unique_ptr<TEvAddBulkSst> GetPendingCommitMsg() {
Y_VERIFY(State == EState::COMMIT_PENDING);
- std::unique_ptr<TEvAddBulkSst> msg;
- msg.swap(PendingCommitMsg);
+ std::unique_ptr<TEvAddBulkSst> msg;
+ msg.swap(PendingCommitMsg);
Y_VERIFY(msg);
- State = EState::WAITING_FOR_COMMIT;
- return msg;
- }
-
- void ApplyCommit() {
+ State = EState::WAITING_FOR_COMMIT;
+ return msg;
+ }
+
+ void ApplyCommit() {
Y_VERIFY(State == EState::WAITING_FOR_COMMIT);
- State = EState::STOPPED;
- }
-
- EState GetState() const {
- return State;
- }
-
- private:
- void IssueWriteCmd(std::unique_ptr<NPDisk::TEvChunkWrite>&& ev, EOutputState outputState) {
- State = EState::PDISK_MESSAGE_PENDING;
- PendingPDiskMsg = std::move(ev);
- Y_VERIFY(outputState >= OutputState);
- OutputState = outputState;
- }
-
- void FlushNextPart() {
- Y_VERIFY(!FlushFinished);
- FlushFinished = Writer->FlushNext(0, 0, 1);
- if (auto msg = Writer->GetPendingMessage()) {
- IssueWriteCmd(std::move(msg), FlushFinished ? EOutputState::FLUSH_LAST_CHUNK : EOutputState::FLUSH_CHUNK);
- } else if (WritesInFlight) {
- Y_VERIFY(FlushFinished);
- Y_VERIFY(OutputState == EOutputState::FLUSH_CHUNK);
- OutputState = EOutputState::FLUSH_LAST_CHUNK; // promote to final state
- State = EState::NOT_READY;
- } else {
- Y_VERIFY(FlushFinished);
- OnFlushComplete();
- }
- }
-
- void OnFlushComplete() {
- Y_VERIFY(!WritesInFlight);
- Y_VERIFY(FlushFinished);
- const auto& conclusion = Writer->GetConclusion();
+ State = EState::STOPPED;
+ }
+
+ EState GetState() const {
+ return State;
+ }
+
+ private:
+ void IssueWriteCmd(std::unique_ptr<NPDisk::TEvChunkWrite>&& ev, EOutputState outputState) {
+ State = EState::PDISK_MESSAGE_PENDING;
+ PendingPDiskMsg = std::move(ev);
+ Y_VERIFY(outputState >= OutputState);
+ OutputState = outputState;
+ }
+
+ void FlushNextPart() {
+ Y_VERIFY(!FlushFinished);
+ FlushFinished = Writer->FlushNext(0, 0, 1);
+ if (auto msg = Writer->GetPendingMessage()) {
+ IssueWriteCmd(std::move(msg), FlushFinished ? EOutputState::FLUSH_LAST_CHUNK : EOutputState::FLUSH_CHUNK);
+ } else if (WritesInFlight) {
+ Y_VERIFY(FlushFinished);
+ Y_VERIFY(OutputState == EOutputState::FLUSH_CHUNK);
+ OutputState = EOutputState::FLUSH_LAST_CHUNK; // promote to final state
+ State = EState::NOT_READY;
+ } else {
+ Y_VERIFY(FlushFinished);
+ OnFlushComplete();
+ }
+ }
+
+ void OnFlushComplete() {
+ Y_VERIFY(!WritesInFlight);
+ Y_VERIFY(FlushFinished);
+ const auto& conclusion = Writer->GetConclusion();
TVector<ui32> usedChunks = conclusion.UsedChunks;
- PendingCommitMsg = std::make_unique<TEvAddBulkSst>(TVector<ui32>(ReservedChunks.begin(), ReservedChunks.end()),
- std::move(usedChunks), TLogoBlobsSstPtr(conclusion.LevelSegment), NumRecoveredBlobs);
- Writer.reset();
- State = EState::COMMIT_PENDING;
- }
-
- private:
- std::shared_ptr<TReplCtx> ReplCtx;
+ PendingCommitMsg = std::make_unique<TEvAddBulkSst>(TVector<ui32>(ReservedChunks.begin(), ReservedChunks.end()),
+ std::move(usedChunks), TLogoBlobsSstPtr(conclusion.LevelSegment), NumRecoveredBlobs);
+ Writer.reset();
+ State = EState::COMMIT_PENDING;
+ }
+
+ private:
+ std::shared_ptr<TReplCtx> ReplCtx;
TIntrusivePtr<THullDs> HullDs;
- TLogoBlobID PrevID;
- EState State;
- EOutputState OutputState;
- std::unique_ptr<IEventBase> PendingPDiskMsg;
- std::unique_ptr<TEvAddBulkSst> PendingCommitMsg;
+ TLogoBlobID PrevID;
+ EState State;
+ EOutputState OutputState;
+ std::unique_ptr<IEventBase> PendingPDiskMsg;
+ std::unique_ptr<TEvAddBulkSst> PendingCommitMsg;
TDeque<ui32> ReservedChunks;
- ui32 MinReservedChunksCount;
- std::unique_ptr<TWriter> Writer;
- TDataMerger Merger;
- ui32 NumRecoveredBlobs = 0;
- ui32 WritesInFlight = 0;
- const ui32 MaxWritesInFlight = 5;
- TRopeArena Arena;
- bool FlushFinished = true;
- };
-
-} // NKikimr
+ ui32 MinReservedChunksCount;
+ std::unique_ptr<TWriter> Writer;
+ TDataMerger Merger;
+ ui32 NumRecoveredBlobs = 0;
+ ui32 WritesInFlight = 0;
+ const ui32 MaxWritesInFlight = 5;
+ TRopeArena Arena;
+ bool FlushFinished = true;
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst_ut.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst_ut.cpp
index cacb1405938..de266237bb5 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst_ut.cpp
@@ -1,206 +1,206 @@
-#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/blobstorage/vdisk/repl/blobstorage_hullreplwritesst.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
-
-using namespace NKikimr;
-
-std::shared_ptr<TReplCtx> CreateReplCtx(TVector<TVDiskID>& vdisks, const TIntrusivePtr<TBlobStorageGroupInfo>& info) {
- for (const auto& vdisk : info->GetVDisks()) {
- vdisks.push_back(info->GetVDiskId(vdisk.OrderNumber));
- }
- auto baseInfo = TVDiskConfig::TBaseInfo::SampleForTests();
- baseInfo.VDiskIdShort = TVDiskIdShort(vdisks[0]);
- auto vdiskCfg = MakeIntrusive<TVDiskConfig>(baseInfo);
- auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
- auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
+
+using namespace NKikimr;
+
+std::shared_ptr<TReplCtx> CreateReplCtx(TVector<TVDiskID>& vdisks, const TIntrusivePtr<TBlobStorageGroupInfo>& info) {
+ for (const auto& vdisk : info->GetVDisks()) {
+ vdisks.push_back(info->GetVDiskId(vdisk.OrderNumber));
+ }
+ auto baseInfo = TVDiskConfig::TBaseInfo::SampleForTests();
+ baseInfo.VDiskIdShort = TVDiskIdShort(vdisks[0]);
+ auto vdiskCfg = MakeIntrusive<TVDiskConfig>(baseInfo);
+ auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
+ auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
nullptr, TPDiskCategory::DEVICE_TYPE_UNKNOWN);
- auto hugeBlobCtx = std::make_shared<THugeBlobCtx>(512u << 10u, nullptr);
- auto dsk = MakeIntrusive<TPDiskParams>(ui8(1), 1u, 128u << 20, 4096u, 0u, 1000000000u, 1000000000u, 65536u, 65536u, 65536u);
+ auto hugeBlobCtx = std::make_shared<THugeBlobCtx>(512u << 10u, nullptr);
+ auto dsk = MakeIntrusive<TPDiskParams>(ui8(1), 1u, 128u << 20, 4096u, 0u, 1000000000u, 1000000000u, 65536u, 65536u, 65536u);
auto pdiskCtx = std::make_shared<TPDiskCtx>(dsk, TActorId());
- auto replCtx = std::make_shared<TReplCtx>(
- vctx,
- pdiskCtx,
- hugeBlobCtx,
- nullptr,
- info,
+ auto replCtx = std::make_shared<TReplCtx>(
+ vctx,
+ pdiskCtx,
+ hugeBlobCtx,
+ nullptr,
+ info,
TActorId(),
- vdiskCfg,
- std::make_shared<std::atomic_uint64_t>());
- return replCtx;
-}
-
-TVDiskContextPtr CreateVDiskContext(const TBlobStorageGroupInfo& info) {
- return MakeIntrusive<TVDiskContext>(TActorId(), info.PickTopology(), new NMonitoring::TDynamicCounters(), TVDiskID(),
+ vdiskCfg,
+ std::make_shared<std::atomic_uint64_t>());
+ return replCtx;
+}
+
+TVDiskContextPtr CreateVDiskContext(const TBlobStorageGroupInfo& info) {
+ return MakeIntrusive<TVDiskContext>(TActorId(), info.PickTopology(), new NMonitoring::TDynamicCounters(), TVDiskID(),
nullptr, TPDiskCategory::DEVICE_TYPE_UNKNOWN);
-}
-
-TIntrusivePtr<THullCtx> CreateHullCtx(const TBlobStorageGroupInfo& info, ui32 chunkSize, ui32 compWorthReadSize) {
- return MakeIntrusive<THullCtx>(CreateVDiskContext(info), chunkSize, compWorthReadSize, true, true, true, true, 1u,
- 1u, 2.0, 10u, 10u, 20u, 0.5, TDuration::Minutes(5), TDuration::Seconds(1));
-}
-
-TIntrusivePtr<THullDs> CreateHullDs(const TBlobStorageGroupInfo& info) {
- auto hullDs = MakeIntrusive<THullDs>(CreateHullCtx(info, 128 << 20, 256 * 1024));
- hullDs->LogoBlobs = MakeIntrusive<TLogoBlobsDs>(TLevelIndexSettings(hullDs->HullCtx, 0, 0, 0, TDuration::Zero(),
- 0, false, false), std::make_shared<TRopeArena>(TRopeArenaBackend::Allocate));
- return hullDs;
-}
-
-Y_UNIT_TEST_SUITE(HullReplWriteSst) {
- Y_UNIT_TEST(Basic) {
- TVector<TVDiskID> vdisks;
- auto groupInfo = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::ErasureMirror3);
- auto replCtx = CreateReplCtx(vdisks, groupInfo);
- auto hullDs = CreateHullDs(*groupInfo);
- TReplSstStreamWriter writer(replCtx, hullDs);
- ui64 index = 1;
- ui32 chunkIdx = 1;
- std::deque<TLogoBlobID> checkQ;
- std::map<ui32, TString> chunks;
- TRopeArena arena(TRopeArenaBackend::Allocate);
- std::deque<std::unique_ptr<NPDisk::TEvChunkWrite>> writeMsgs;
- auto handleWrite = [&](NPDisk::TEvChunkWrite& m) {
- TString& data = chunks[m.ChunkIdx];
- if (!data) {
- data = TString::Uninitialized(hullDs->HullCtx->ChunkSize);
- }
- ui32 offset = m.Offset;
- for (ui32 i = 0; i < m.PartsPtr->Size(); ++i) {
- const auto& [ptr, size] = (*m.PartsPtr)[i];
- Y_VERIFY(offset + size <= data.size());
- if (ptr) {
- memcpy(data.Detach() + offset, ptr, size);
- } else {
- memset(data.Detach() + offset, 0, size);
- }
- offset += size;
- }
- NPDisk::TEvChunkWriteResult res(NKikimrProto::OK, m.ChunkIdx, m.PartsPtr, m.Cookie, {}, {});
- writer.Apply(&res);
- };
- auto read = [&](const TDiskPart& p) {
- const auto it = chunks.find(p.ChunkIdx);
- Y_VERIFY(it != chunks.end());
- const TString& s = it->second;
- return s.substr(p.Offset, p.Size);
- };
- for (THPTimer timer; TDuration::Seconds(timer.Passed()) < TDuration::Minutes(5); ) {
- if (!writeMsgs.empty() && RandomNumber(1000u) == 999) {
- const size_t index = RandomNumber(writeMsgs.size());
- handleWrite(*writeMsgs[index]);
- writeMsgs.erase(writeMsgs.begin() + index);
- }
- switch (writer.GetState()) {
- case TReplSstStreamWriter::EState::STOPPED:
- writer.Begin();
- break;
-
- case TReplSstStreamWriter::EState::COLLECT: {
- // generate random size for this blob
- const ui32 size = 1 + RandomNumber(256u);
- TString data = TString::Uninitialized(size);
- memset(data.Detach(), '*', size);
-
- // generate blob id
- TLogoBlobID id(index++, 1, 1, 0, size, 0);
-
- // find possible local part for current vdisk
- TRope rope;
- NMatrix::TVectorType vec(0, groupInfo->GetTopology().GType.TotalPartCount());
- for (ui32 partIdx = 0; partIdx < vec.GetSize(); ++partIdx) {
- if (TIngress::CreateIngressWithLocal(&groupInfo->GetTopology(), replCtx->VCtx->ShortSelfVDisk,
- TLogoBlobID(id, partIdx + 1))) {
- vec.Set(partIdx);
- rope = TDiskBlob::Create(size, partIdx + 1, vec.GetSize(), TRope(std::move(data)), arena);
- break;
- }
- }
-
- // write it
- TReplSstStreamWriter::TRecoveredBlobInfo info(id, std::move(rope), false, vec);
- const bool success = writer.AddRecoveredBlob(info);
- if (success) {
- checkQ.push_back(info.Id);
- }
- break;
- }
-
- case TReplSstStreamWriter::EState::PDISK_MESSAGE_PENDING: {
- auto msg = writer.GetPendingPDiskMsg();
- Y_VERIFY(msg);
- if (auto *x = dynamic_cast<NPDisk::TEvChunkReserve*>(msg.get())) {
- NPDisk::TEvChunkReserveResult res(NKikimrProto::OK, {});
- for (ui32 i = 0; i < x->SizeChunks; ++i) {
- res.ChunkIds.push_back(chunkIdx++);
- }
- writer.Apply(&res);
- } else if (auto *x = dynamic_cast<NPDisk::TEvChunkWrite*>(msg.get())) {
- if (RandomNumber(100u) >= 95) {
- handleWrite(*x);
- } else {
- writeMsgs.emplace_back(static_cast<NPDisk::TEvChunkWrite*>(msg.release()));
- }
- } else {
- Y_FAIL();
- }
- break;
- }
-
- case TReplSstStreamWriter::EState::NOT_READY: {
- Y_VERIFY(!writeMsgs.empty());
- const size_t index = RandomNumber(writeMsgs.size());
- handleWrite(*writeMsgs[index]);
- writeMsgs.erase(writeMsgs.begin() + index);
- break;
- }
-
- case TReplSstStreamWriter::EState::COMMIT_PENDING: {
- auto msg = writer.GetPendingCommitMsg();
- Cerr << "commit" << Endl;
- for (const ui32 chunk : msg->ChunksToCommit) {
- Cerr << "chunk# " << chunk << Endl;
- }
- for (const auto& addition : msg->Essence.LogoBlobsAdditions) {
- Cerr << addition.Sst->LastPartAddr.ToString() << Endl;
- TString data = read(addition.Sst->LastPartAddr);
- TIdxDiskPlaceHolder ph = *(reinterpret_cast<const TIdxDiskPlaceHolder*>(data.data() + data.size()) - 1);
- UNIT_ASSERT_VALUES_EQUAL(ph.MagicNumber, ui32(TIdxDiskPlaceHolder::Signature));
- data.resize(data.size() - sizeof(ph));
- for (TDiskPart link = ph.PrevPart; link.ChunkIdx; ) {
- TString chain = read(link);
- auto *x = reinterpret_cast<const TIdxDiskLinker*>(chain.data() + chain.size()) - 1;
- link = x->PrevPart;
- data = chain + data;
- }
- const char *ptr = data.data();
- const char *end = ptr + data.size();
- ui32 numItems = 0;
- while (ptr < end) {
- auto *key = reinterpret_cast<const TKeyLogoBlob*>(ptr);
- auto *memrec = reinterpret_cast<const TMemRecLogoBlob*>(key + 1);
- ptr = reinterpret_cast<const char*>(memrec + 1);
- UNIT_ASSERT(ptr <= end);
- UNIT_ASSERT(!checkQ.empty());
- UNIT_ASSERT_VALUES_EQUAL(key->LogoBlobID(), checkQ.front());
- checkQ.pop_front();
- ++numItems;
- }
- Cerr << numItems << Endl;
- UNIT_ASSERT_VALUES_EQUAL(numItems, ph.Info.ItemsWithInplacedData);
- UNIT_ASSERT_VALUES_EQUAL(0, ph.Info.ItemsWithHugeData);
- }
- UNIT_ASSERT(checkQ.empty());
- for (const ui32 chunk : msg->ChunksToCommit) {
- const ui32 num = chunks.erase(chunk);
- UNIT_ASSERT_VALUES_EQUAL(num, 1);
- }
- writer.ApplyCommit();
- break;
- }
-
- default:
- Y_FAIL();
- }
- }
- }
-}
+}
+
+TIntrusivePtr<THullCtx> CreateHullCtx(const TBlobStorageGroupInfo& info, ui32 chunkSize, ui32 compWorthReadSize) {
+ return MakeIntrusive<THullCtx>(CreateVDiskContext(info), chunkSize, compWorthReadSize, true, true, true, true, 1u,
+ 1u, 2.0, 10u, 10u, 20u, 0.5, TDuration::Minutes(5), TDuration::Seconds(1));
+}
+
+TIntrusivePtr<THullDs> CreateHullDs(const TBlobStorageGroupInfo& info) {
+ auto hullDs = MakeIntrusive<THullDs>(CreateHullCtx(info, 128 << 20, 256 * 1024));
+ hullDs->LogoBlobs = MakeIntrusive<TLogoBlobsDs>(TLevelIndexSettings(hullDs->HullCtx, 0, 0, 0, TDuration::Zero(),
+ 0, false, false), std::make_shared<TRopeArena>(TRopeArenaBackend::Allocate));
+ return hullDs;
+}
+
+Y_UNIT_TEST_SUITE(HullReplWriteSst) {
+ Y_UNIT_TEST(Basic) {
+ TVector<TVDiskID> vdisks;
+ auto groupInfo = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::ErasureMirror3);
+ auto replCtx = CreateReplCtx(vdisks, groupInfo);
+ auto hullDs = CreateHullDs(*groupInfo);
+ TReplSstStreamWriter writer(replCtx, hullDs);
+ ui64 index = 1;
+ ui32 chunkIdx = 1;
+ std::deque<TLogoBlobID> checkQ;
+ std::map<ui32, TString> chunks;
+ TRopeArena arena(TRopeArenaBackend::Allocate);
+ std::deque<std::unique_ptr<NPDisk::TEvChunkWrite>> writeMsgs;
+ auto handleWrite = [&](NPDisk::TEvChunkWrite& m) {
+ TString& data = chunks[m.ChunkIdx];
+ if (!data) {
+ data = TString::Uninitialized(hullDs->HullCtx->ChunkSize);
+ }
+ ui32 offset = m.Offset;
+ for (ui32 i = 0; i < m.PartsPtr->Size(); ++i) {
+ const auto& [ptr, size] = (*m.PartsPtr)[i];
+ Y_VERIFY(offset + size <= data.size());
+ if (ptr) {
+ memcpy(data.Detach() + offset, ptr, size);
+ } else {
+ memset(data.Detach() + offset, 0, size);
+ }
+ offset += size;
+ }
+ NPDisk::TEvChunkWriteResult res(NKikimrProto::OK, m.ChunkIdx, m.PartsPtr, m.Cookie, {}, {});
+ writer.Apply(&res);
+ };
+ auto read = [&](const TDiskPart& p) {
+ const auto it = chunks.find(p.ChunkIdx);
+ Y_VERIFY(it != chunks.end());
+ const TString& s = it->second;
+ return s.substr(p.Offset, p.Size);
+ };
+ for (THPTimer timer; TDuration::Seconds(timer.Passed()) < TDuration::Minutes(5); ) {
+ if (!writeMsgs.empty() && RandomNumber(1000u) == 999) {
+ const size_t index = RandomNumber(writeMsgs.size());
+ handleWrite(*writeMsgs[index]);
+ writeMsgs.erase(writeMsgs.begin() + index);
+ }
+ switch (writer.GetState()) {
+ case TReplSstStreamWriter::EState::STOPPED:
+ writer.Begin();
+ break;
+
+ case TReplSstStreamWriter::EState::COLLECT: {
+ // generate random size for this blob
+ const ui32 size = 1 + RandomNumber(256u);
+ TString data = TString::Uninitialized(size);
+ memset(data.Detach(), '*', size);
+
+ // generate blob id
+ TLogoBlobID id(index++, 1, 1, 0, size, 0);
+
+ // find possible local part for current vdisk
+ TRope rope;
+ NMatrix::TVectorType vec(0, groupInfo->GetTopology().GType.TotalPartCount());
+ for (ui32 partIdx = 0; partIdx < vec.GetSize(); ++partIdx) {
+ if (TIngress::CreateIngressWithLocal(&groupInfo->GetTopology(), replCtx->VCtx->ShortSelfVDisk,
+ TLogoBlobID(id, partIdx + 1))) {
+ vec.Set(partIdx);
+ rope = TDiskBlob::Create(size, partIdx + 1, vec.GetSize(), TRope(std::move(data)), arena);
+ break;
+ }
+ }
+
+ // write it
+ TReplSstStreamWriter::TRecoveredBlobInfo info(id, std::move(rope), false, vec);
+ const bool success = writer.AddRecoveredBlob(info);
+ if (success) {
+ checkQ.push_back(info.Id);
+ }
+ break;
+ }
+
+ case TReplSstStreamWriter::EState::PDISK_MESSAGE_PENDING: {
+ auto msg = writer.GetPendingPDiskMsg();
+ Y_VERIFY(msg);
+ if (auto *x = dynamic_cast<NPDisk::TEvChunkReserve*>(msg.get())) {
+ NPDisk::TEvChunkReserveResult res(NKikimrProto::OK, {});
+ for (ui32 i = 0; i < x->SizeChunks; ++i) {
+ res.ChunkIds.push_back(chunkIdx++);
+ }
+ writer.Apply(&res);
+ } else if (auto *x = dynamic_cast<NPDisk::TEvChunkWrite*>(msg.get())) {
+ if (RandomNumber(100u) >= 95) {
+ handleWrite(*x);
+ } else {
+ writeMsgs.emplace_back(static_cast<NPDisk::TEvChunkWrite*>(msg.release()));
+ }
+ } else {
+ Y_FAIL();
+ }
+ break;
+ }
+
+ case TReplSstStreamWriter::EState::NOT_READY: {
+ Y_VERIFY(!writeMsgs.empty());
+ const size_t index = RandomNumber(writeMsgs.size());
+ handleWrite(*writeMsgs[index]);
+ writeMsgs.erase(writeMsgs.begin() + index);
+ break;
+ }
+
+ case TReplSstStreamWriter::EState::COMMIT_PENDING: {
+ auto msg = writer.GetPendingCommitMsg();
+ Cerr << "commit" << Endl;
+ for (const ui32 chunk : msg->ChunksToCommit) {
+ Cerr << "chunk# " << chunk << Endl;
+ }
+ for (const auto& addition : msg->Essence.LogoBlobsAdditions) {
+ Cerr << addition.Sst->LastPartAddr.ToString() << Endl;
+ TString data = read(addition.Sst->LastPartAddr);
+ TIdxDiskPlaceHolder ph = *(reinterpret_cast<const TIdxDiskPlaceHolder*>(data.data() + data.size()) - 1);
+ UNIT_ASSERT_VALUES_EQUAL(ph.MagicNumber, ui32(TIdxDiskPlaceHolder::Signature));
+ data.resize(data.size() - sizeof(ph));
+ for (TDiskPart link = ph.PrevPart; link.ChunkIdx; ) {
+ TString chain = read(link);
+ auto *x = reinterpret_cast<const TIdxDiskLinker*>(chain.data() + chain.size()) - 1;
+ link = x->PrevPart;
+ data = chain + data;
+ }
+ const char *ptr = data.data();
+ const char *end = ptr + data.size();
+ ui32 numItems = 0;
+ while (ptr < end) {
+ auto *key = reinterpret_cast<const TKeyLogoBlob*>(ptr);
+ auto *memrec = reinterpret_cast<const TMemRecLogoBlob*>(key + 1);
+ ptr = reinterpret_cast<const char*>(memrec + 1);
+ UNIT_ASSERT(ptr <= end);
+ UNIT_ASSERT(!checkQ.empty());
+ UNIT_ASSERT_VALUES_EQUAL(key->LogoBlobID(), checkQ.front());
+ checkQ.pop_front();
+ ++numItems;
+ }
+ Cerr << numItems << Endl;
+ UNIT_ASSERT_VALUES_EQUAL(numItems, ph.Info.ItemsWithInplacedData);
+ UNIT_ASSERT_VALUES_EQUAL(0, ph.Info.ItemsWithHugeData);
+ }
+ UNIT_ASSERT(checkQ.empty());
+ for (const ui32 chunk : msg->ChunksToCommit) {
+ const ui32 num = chunks.erase(chunk);
+ UNIT_ASSERT_VALUES_EQUAL(num, 1);
+ }
+ writer.ApplyCommit();
+ break;
+ }
+
+ default:
+ Y_FAIL();
+ }
+ }
+ }
+}
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.cpp
index 34be219abce..2b6be2ff5b4 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.cpp
@@ -1,8 +1,8 @@
#include "blobstorage_repl.h"
-#include "blobstorage_replproxy.h"
-#include "blobstorage_replbroker.h"
-#include "blobstorage_hullrepljob.h"
-#include "query_donor.h"
+#include "blobstorage_replproxy.h"
+#include "blobstorage_replbroker.h"
+#include "blobstorage_hullrepljob.h"
+#include "query_donor.h"
#include <ydb/core/blobstorage/base/utility.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
#include <ydb/core/blobstorage/vdisk/common/circlebuf.h>
@@ -21,23 +21,23 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// Internal Repl messages
////////////////////////////////////////////////////////////////////////////
- TEvReplFinished::TInfo::TInfo()
- : Start(TAppData::TimeProvider->Now())
- , End()
- , KeyPos()
- , Eof(false)
- {}
-
- TEvReplFinished::TInfo::~TInfo()
- {}
-
+ TEvReplFinished::TInfo::TInfo()
+ : Start(TAppData::TimeProvider->Now())
+ , End()
+ , KeyPos()
+ , Eof(false)
+ {}
+
+ TEvReplFinished::TInfo::~TInfo()
+ {}
+
////////////////////////////////////////////////////////////////////////////
// TEvReplFinished::TInfo
////////////////////////////////////////////////////////////////////////////
TString TEvReplFinished::TInfo::ToString() const {
- return Sprintf("{KeyPos: %s Eof: %s ReplicaOk: %" PRIu64 " RecoveryScheduled: %" PRIu64 " DataRecoverySuccess: %"
- PRIu64 " DataRecoveryFailure: %" PRIu64 "}", KeyPos.ToString().data(), (Eof ? "true" : "false"),
- ReplicaOk, RecoveryScheduled, DataRecoverySuccess, DataRecoveryFailure);
+ return Sprintf("{KeyPos: %s Eof: %s ReplicaOk: %" PRIu64 " RecoveryScheduled: %" PRIu64 " DataRecoverySuccess: %"
+ PRIu64 " DataRecoveryFailure: %" PRIu64 "}", KeyPos.ToString().data(), (Eof ? "true" : "false"),
+ ReplicaOk, RecoveryScheduled, DataRecoverySuccess, DataRecoveryFailure);
}
void TEvReplFinished::TInfo::OutputHtml(IOutputStream &str) const {
@@ -45,11 +45,11 @@ namespace NKikimr {
TABLED() { str << #NAME; } \
TABLED() { str << VALUE; } \
}
-
-#define PARAM_V(NAME) PARAM(NAME, NAME)
-
+
+#define PARAM_V(NAME) PARAM(NAME, NAME)
+
#define GROUP(NAME) TABLER() TABLED_ATTRS({{"colspan", "2"}}) COLLAPSED_BUTTON_CONTENT(CreateGuidAsString(), NAME) TABLE()
-
+
HTML(str) {
SMALL() {
TABLE() {
@@ -58,69 +58,69 @@ namespace NKikimr {
TABLEH() { str << "Value"; }
}
STRONG() {
- PARAM(Summary, DataRecoverySuccess << "/" << RecoveryScheduled << "/" << (ReplicaOk + RecoveryScheduled));
+ PARAM(Summary, DataRecoverySuccess << "/" << RecoveryScheduled << "/" << (ReplicaOk + RecoveryScheduled));
}
- PARAM(Start, ToStringLocalTimeUpToSeconds(Start));
- PARAM(End, ToStringLocalTimeUpToSeconds(End));
- PARAM(Duration, End - Start);
- PARAM_V(KeyPos);
- PARAM_V(Eof);
- PARAM_V(DonorVDiskId);
- PARAM_V(DropDonor);
+ PARAM(Start, ToStringLocalTimeUpToSeconds(Start));
+ PARAM(End, ToStringLocalTimeUpToSeconds(End));
+ PARAM(Duration, End - Start);
+ PARAM_V(KeyPos);
+ PARAM_V(Eof);
+ PARAM_V(DonorVDiskId);
+ PARAM_V(DropDonor);
GROUP("Plan Generation Stats") {
- PARAM_V(ReplicaOk);
- PARAM_V(RecoveryScheduled);
- PARAM_V(IgnoredDueToGC);
+ PARAM_V(ReplicaOk);
+ PARAM_V(RecoveryScheduled);
+ PARAM_V(IgnoredDueToGC);
}
GROUP("Plan Execution Stats") {
- PARAM_V(DataRecoverySuccess);
- PARAM_V(DataRecoveryFailure);
- PARAM_V(DataRecoveryNoParts);
- PARAM_V(DataRecoverySkip);
- PARAM_V(DataRecoveryPhantomCheck);
+ PARAM_V(DataRecoverySuccess);
+ PARAM_V(DataRecoveryFailure);
+ PARAM_V(DataRecoveryNoParts);
+ PARAM_V(DataRecoverySkip);
+ PARAM_V(DataRecoveryPhantomCheck);
}
GROUP("Detailed Stats") {
- PARAM_V(BytesRecovered);
- PARAM_V(LogoBlobsRecovered);
- PARAM_V(HugeLogoBlobsRecovered);
- PARAM_V(ChunksWritten);
- PARAM_V(SstBytesWritten);
- PARAM_V(MultipartBlobs);
- PARAM_V(MetadataBlobs);
- PARAM_V(PartsPlanned);
- PARAM_V(PartsExact);
- PARAM_V(PartsRestored);
- PARAM_V(PartsMissing);
+ PARAM_V(BytesRecovered);
+ PARAM_V(LogoBlobsRecovered);
+ PARAM_V(HugeLogoBlobsRecovered);
+ PARAM_V(ChunksWritten);
+ PARAM_V(SstBytesWritten);
+ PARAM_V(MultipartBlobs);
+ PARAM_V(MetadataBlobs);
+ PARAM_V(PartsPlanned);
+ PARAM_V(PartsExact);
+ PARAM_V(PartsRestored);
+ PARAM_V(PartsMissing);
}
GROUP("Durations") {
- PARAM_V(PreparePlanDuration);
- PARAM_V(TokenWaitDuration);
- PARAM_V(ProxyWaitDuration);
- PARAM_V(MergeDuration);
- PARAM_V(PDiskDuration);
- PARAM_V(CommitDuration);
- PARAM_V(OtherDuration);
- PARAM_V(PhantomDuration);
+ PARAM_V(PreparePlanDuration);
+ PARAM_V(TokenWaitDuration);
+ PARAM_V(ProxyWaitDuration);
+ PARAM_V(MergeDuration);
+ PARAM_V(PDiskDuration);
+ PARAM_V(CommitDuration);
+ PARAM_V(OtherDuration);
+ PARAM_V(PhantomDuration);
}
GROUP("VDisk Stats") {
- PARAM_V(ProxyStat->VDiskReqs);
- PARAM_V(ProxyStat->VDiskRespOK);
- PARAM_V(ProxyStat->VDiskRespRACE);
- PARAM_V(ProxyStat->VDiskRespERROR);
- PARAM_V(ProxyStat->VDiskRespDEADLINE);
- PARAM_V(ProxyStat->VDiskRespOther);
- PARAM_V(ProxyStat->LogoBlobGotIt);
- PARAM_V(ProxyStat->LogoBlobNoData);
- PARAM_V(ProxyStat->LogoBlobNotOK);
- PARAM_V(ProxyStat->LogoBlobDataSize);
- PARAM_V(ProxyStat->OverflowedMsgs);
+ PARAM_V(ProxyStat->VDiskReqs);
+ PARAM_V(ProxyStat->VDiskRespOK);
+ PARAM_V(ProxyStat->VDiskRespRACE);
+ PARAM_V(ProxyStat->VDiskRespERROR);
+ PARAM_V(ProxyStat->VDiskRespDEADLINE);
+ PARAM_V(ProxyStat->VDiskRespOther);
+ PARAM_V(ProxyStat->LogoBlobGotIt);
+ PARAM_V(ProxyStat->LogoBlobNoData);
+ PARAM_V(ProxyStat->LogoBlobNotOK);
+ PARAM_V(ProxyStat->LogoBlobDataSize);
+ PARAM_V(ProxyStat->OverflowedMsgs);
}
}
}
}
-#undef GROUP
-#undef PARAM_V
-#undef PARAM
+#undef GROUP
+#undef PARAM_V
+#undef PARAM
}
@@ -129,31 +129,31 @@ namespace NKikimr {
// TReplScheduler
////////////////////////////////////////////////////////////////////////////
class TReplScheduler : public TActorBootstrapped<TReplScheduler> {
- enum {
- EvResumeForce = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
- struct TEvResumeForce : TEventLocal<TEvResumeForce, EvResumeForce> {};
-
+ enum {
+ EvResumeForce = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+ struct TEvResumeForce : TEventLocal<TEvResumeForce, EvResumeForce> {};
+
typedef TCircleBuf<TEvReplFinished::TInfoPtr> THistory;
enum EState {
- Plan,
- AwaitToken,
- WaitQueues,
+ Plan,
+ AwaitToken,
+ WaitQueues,
Replication,
- Relaxation,
- Finished
+ Relaxation,
+ Finished
};
static const unsigned HistorySize = 12;
- struct TDonorQueueItem {
- TVDiskID VDiskId;
- TActorId QueueActorId;
- ui32 NodeId;
- ui32 PDiskId;
- ui32 VSlotId;
- };
-
- std::shared_ptr<TReplCtx> ReplCtx;
+ struct TDonorQueueItem {
+ TVDiskID VDiskId;
+ TActorId QueueActorId;
+ ui32 NodeId;
+ ui32 PDiskId;
+ ui32 VSlotId;
+ };
+
+ std::shared_ptr<TReplCtx> ReplCtx;
THistory History;
EState State;
TInstant LastReplStart;
@@ -161,39 +161,39 @@ namespace NKikimr {
TInstant LastReplQuantumStart;
TInstant LastReplQuantumEnd;
TQueueActorMapPtr QueueActorMapPtr;
- TBlobIdQueuePtr BlobsToReplicatePtr;
- TBlobIdQueuePtr UnreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
+ TBlobIdQueuePtr BlobsToReplicatePtr;
+ TBlobIdQueuePtr UnreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
TActorId ReplJobActorId;
- std::list<std::optional<TDonorQueueItem>> DonorQueue;
- std::deque<std::pair<TVDiskID, TActorId>> Donors;
- std::set<TVDiskID> ConnectedPeerDisks, ConnectedDonorDisks;
- TEvResumeForce *ResumeForceToken = nullptr;
+ std::list<std::optional<TDonorQueueItem>> DonorQueue;
+ std::deque<std::pair<TVDiskID, TActorId>> Donors;
+ std::set<TVDiskID> ConnectedPeerDisks, ConnectedDonorDisks;
+ TEvResumeForce *ResumeForceToken = nullptr;
friend class TActorBootstrapped<TReplScheduler>;
const char *StateToStr(EState state) {
switch (state) {
- case Plan: return "Plan";
- case AwaitToken: return "AwaitToken";
- case WaitQueues: return "WaitQueues";
+ case Plan: return "Plan";
+ case AwaitToken: return "AwaitToken";
+ case WaitQueues: return "WaitQueues";
case Replication: return "Replication";
case Relaxation: return "Relaxation";
- case Finished: return "Finished";
- default: return "Unknown";
+ case Finished: return "Finished";
+ default: return "Unknown";
}
}
- void Transition(EState current, EState next) {
- Y_VERIFY(State == current, "State# %s Expected# %s", StateToStr(State), StateToStr(current));
- State = next;
- }
-
- void Bootstrap() {
- QueueActorMapPtr = std::make_shared<TQueueActorMap>();
+ void Transition(EState current, EState next) {
+ Y_VERIFY(State == current, "State# %s Expected# %s", StateToStr(State), StateToStr(current));
+ State = next;
+ }
+
+ void Bootstrap() {
+ QueueActorMapPtr = std::make_shared<TQueueActorMap>();
auto replInterconnectChannel = static_cast<TInterconnectChannels::EInterconnectChannels>(
- ReplCtx->VDiskCfg->ReplInterconnectChannel);
+ ReplCtx->VDiskCfg->ReplInterconnectChannel);
- const TBlobStorageGroupInfo::TTopology& topology = ReplCtx->GInfo->GetTopology();
+ const TBlobStorageGroupInfo::TTopology& topology = ReplCtx->GInfo->GetTopology();
NBackpressure::TQueueClientId replQueueClientId(NBackpressure::EQueueClientType::ReplJob,
topology.GetOrderNumber(ReplCtx->VCtx->ShortSelfVDisk));
CreateQueuesForVDisks(*QueueActorMapPtr, SelfId(), ReplCtx->GInfo, ReplCtx->VCtx,
@@ -201,217 +201,217 @@ namespace NKikimr {
replQueueClientId, NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead,
"PeerRepl", replInterconnectChannel);
- for (const auto& [vdiskId, vdiskActorId] : ReplCtx->VDiskCfg->BaseInfo.DonorDiskIds) {
- TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
- auto info = MakeIntrusive<TBlobStorageGroupInfo>(ReplCtx->GInfo, vdiskId, vdiskActorId);
- const TActorId queueActorId = Register(CreateVDiskBackpressureClient(info, vdiskId,
- NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead, ReplCtx->MonGroup.GetGroup(), ReplCtx->VCtx,
- NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::ReplJob, 0), "Donor",
- ReplCtx->VDiskCfg->ReplInterconnectChannel, vdiskActorId.NodeId() == SelfId().NodeId(),
- TDuration::Minutes(1), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
- ui32 nodeId, pdiskId, vslotId;
- std::tie(nodeId, pdiskId, vslotId) = DecomposeVDiskServiceId(vdiskActorId);
- DonorQueue.emplace_back(TDonorQueueItem{
- .VDiskId = vdiskId,
- .QueueActorId = queueActorId,
- .NodeId = nodeId,
- .PDiskId = pdiskId,
- .VSlotId = vslotId
- });
- Donors.emplace_back(vdiskId, queueActorId);
- }
- DonorQueue.emplace_back(std::nullopt); // disks from group
-
- if (ReplCtx->PausedAtStart) {
- Become(&TThis::StateRelax);
- State = Relaxation;
- } else {
- StartReplication();
- }
+ for (const auto& [vdiskId, vdiskActorId] : ReplCtx->VDiskCfg->BaseInfo.DonorDiskIds) {
+ TIntrusivePtr<NBackpressure::TFlowRecord> flowRecord(new NBackpressure::TFlowRecord);
+ auto info = MakeIntrusive<TBlobStorageGroupInfo>(ReplCtx->GInfo, vdiskId, vdiskActorId);
+ const TActorId queueActorId = Register(CreateVDiskBackpressureClient(info, vdiskId,
+ NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead, ReplCtx->MonGroup.GetGroup(), ReplCtx->VCtx,
+ NBackpressure::TQueueClientId(NBackpressure::EQueueClientType::ReplJob, 0), "Donor",
+ ReplCtx->VDiskCfg->ReplInterconnectChannel, vdiskActorId.NodeId() == SelfId().NodeId(),
+ TDuration::Minutes(1), flowRecord, NMonitoring::TCountableBase::EVisibility::Private));
+ ui32 nodeId, pdiskId, vslotId;
+ std::tie(nodeId, pdiskId, vslotId) = DecomposeVDiskServiceId(vdiskActorId);
+ DonorQueue.emplace_back(TDonorQueueItem{
+ .VDiskId = vdiskId,
+ .QueueActorId = queueActorId,
+ .NodeId = nodeId,
+ .PDiskId = pdiskId,
+ .VSlotId = vslotId
+ });
+ Donors.emplace_back(vdiskId, queueActorId);
+ }
+ DonorQueue.emplace_back(std::nullopt); // disks from group
+
+ if (ReplCtx->PausedAtStart) {
+ Become(&TThis::StateRelax);
+ State = Relaxation;
+ } else {
+ StartReplication();
+ }
}
- void Handle(TEvProxyQueueState::TPtr ev) {
- const TVDiskID& vdiskId = ev->Get()->VDiskId;
- auto& set = vdiskId.GroupGeneration == ReplCtx->GInfo->GroupGeneration
- ? ConnectedPeerDisks
- : ConnectedDonorDisks;
- if (ev->Get()->IsConnected) {
- set.insert(vdiskId);
- } else {
- set.erase(vdiskId);
- }
- if (ResumeForceToken) { // if the process is blocked by number of available queues, try to kick it
- ResumeIfReady();
- }
- }
-
- void StartReplication() {
- STLOG(PRI_DEBUG, BS_REPL, BSVR14, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "REPL START"));
- STLOG(PRI_DEBUG, BS_REPL, BSVR15, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM START"));
-
- LastReplStart = TAppData::TimeProvider->Now();
+ void Handle(TEvProxyQueueState::TPtr ev) {
+ const TVDiskID& vdiskId = ev->Get()->VDiskId;
+ auto& set = vdiskId.GroupGeneration == ReplCtx->GInfo->GroupGeneration
+ ? ConnectedPeerDisks
+ : ConnectedDonorDisks;
+ if (ev->Get()->IsConnected) {
+ set.insert(vdiskId);
+ } else {
+ set.erase(vdiskId);
+ }
+ if (ResumeForceToken) { // if the process is blocked by number of available queues, try to kick it
+ ResumeIfReady();
+ }
+ }
+
+ void StartReplication() {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR14, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "REPL START"));
+ STLOG(PRI_DEBUG, BS_REPL, BSVR15, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM START"));
+
+ LastReplStart = TAppData::TimeProvider->Now();
ReplCtx->MonGroup.ReplCurrentUnreplicatedParts() = 0;
ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes() = 0;
ReplCtx->MonGroup.ReplCurrentPhantoms() = 0;
- ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs() = 0;
- ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs() = 0;
- ReplCtx->MonGroup.ReplUnreplicatedVDisks() = 1;
-
+ ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs() = 0;
+ ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs() = 0;
+ ReplCtx->MonGroup.ReplUnreplicatedVDisks() = 1;
+
Become(&TThis::StateRepl);
-
- // switch to planning state
- Transition(Relaxation, Plan);
-
- RunRepl(TLogoBlobID());
- }
-
- void Handle(TEvReplStarted::TPtr& ev) {
- Y_VERIFY(ReplJobActorId == ev->Sender);
-
- switch (State) {
- case Plan:
- // this is a first quantum of replication, so we have to register it in the broker
- State = AwaitToken;
- if (!Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplToken(ReplCtx->VDiskCfg->BaseInfo.PDiskId))) {
- HandleReplToken();
- }
- break;
-
- case Replication:
- // this is successive quantum, so we just continue as we have the token
- Send(ev->Sender, new TEvReplResume);
- break;
-
- default:
- Y_FAIL("unexpected State# %s", StateToStr(State));
- }
- }
-
- void HandleReplToken() {
- // switch to replication state
- Transition(AwaitToken, Replication);
- if (!ResumeIfReady()) {
- Transition(Replication, WaitQueues);
- Schedule(TDuration::Seconds(5), ResumeForceToken = new TEvResumeForce);
- }
- }
-
- bool ResumeIfReady() {
- const auto& donor = DonorQueue.front();
- const bool ready = donor
- ? ConnectedDonorDisks.count(donor->VDiskId)
- : ConnectedPeerDisks.size() >= ReplCtx->GInfo->Type.DataParts();
- if (ready) {
- if (State != Replication) {
- Transition(WaitQueues, Replication);
- }
- Send(ReplJobActorId, new TEvReplResume);
- ResumeForceToken = nullptr;
- }
- return ready;
- }
-
- void Handle(TEvResumeForce::TPtr ev) {
- if (ev->Get() == ResumeForceToken) {
- Transition(WaitQueues, Replication);
- Send(ReplJobActorId, new TEvReplResume);
- ResumeForceToken = nullptr;
- }
- }
-
- void DropDonor(const TDonorQueueItem& donor) {
- Donors.erase(std::find(Donors.begin(), Donors.end(), std::make_pair(donor.VDiskId, donor.QueueActorId)));
- Send(donor.QueueActorId, new TEvents::TEvPoison); // kill the queue actor
- Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvDropDonor(donor.NodeId,
- donor.PDiskId, donor.VSlotId, donor.VDiskId));
+
+ // switch to planning state
+ Transition(Relaxation, Plan);
+
+ RunRepl(TLogoBlobID());
+ }
+
+ void Handle(TEvReplStarted::TPtr& ev) {
+ Y_VERIFY(ReplJobActorId == ev->Sender);
+
+ switch (State) {
+ case Plan:
+ // this is a first quantum of replication, so we have to register it in the broker
+ State = AwaitToken;
+ if (!Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplToken(ReplCtx->VDiskCfg->BaseInfo.PDiskId))) {
+ HandleReplToken();
+ }
+ break;
+
+ case Replication:
+ // this is successive quantum, so we just continue as we have the token
+ Send(ev->Sender, new TEvReplResume);
+ break;
+
+ default:
+ Y_FAIL("unexpected State# %s", StateToStr(State));
+ }
+ }
+
+ void HandleReplToken() {
+ // switch to replication state
+ Transition(AwaitToken, Replication);
+ if (!ResumeIfReady()) {
+ Transition(Replication, WaitQueues);
+ Schedule(TDuration::Seconds(5), ResumeForceToken = new TEvResumeForce);
+ }
+ }
+
+ bool ResumeIfReady() {
+ const auto& donor = DonorQueue.front();
+ const bool ready = donor
+ ? ConnectedDonorDisks.count(donor->VDiskId)
+ : ConnectedPeerDisks.size() >= ReplCtx->GInfo->Type.DataParts();
+ if (ready) {
+ if (State != Replication) {
+ Transition(WaitQueues, Replication);
+ }
+ Send(ReplJobActorId, new TEvReplResume);
+ ResumeForceToken = nullptr;
+ }
+ return ready;
}
- void Handle(TEvReplFinished::TPtr &ev) {
- Y_VERIFY(ev->Sender == ReplJobActorId);
- ReplJobActorId = {};
-
- // replication can be finished only from the following states
- Y_VERIFY(State == Plan || State == Replication, "State# %s", StateToStr(State));
-
- TEvReplFinished *msg = ev->Get();
- TEvReplFinished::TInfoPtr info = msg->Info;
+ void Handle(TEvResumeForce::TPtr ev) {
+ if (ev->Get() == ResumeForceToken) {
+ Transition(WaitQueues, Replication);
+ Send(ReplJobActorId, new TEvReplResume);
+ ResumeForceToken = nullptr;
+ }
+ }
+
+ void DropDonor(const TDonorQueueItem& donor) {
+ Donors.erase(std::find(Donors.begin(), Donors.end(), std::make_pair(donor.VDiskId, donor.QueueActorId)));
+ Send(donor.QueueActorId, new TEvents::TEvPoison); // kill the queue actor
+ Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvDropDonor(donor.NodeId,
+ donor.PDiskId, donor.VSlotId, donor.VDiskId));
+ }
+
+ void Handle(TEvReplFinished::TPtr &ev) {
+ Y_VERIFY(ev->Sender == ReplJobActorId);
+ ReplJobActorId = {};
+
+ // replication can be finished only from the following states
+ Y_VERIFY(State == Plan || State == Replication, "State# %s", StateToStr(State));
+
+ TEvReplFinished *msg = ev->Get();
+ TEvReplFinished::TInfoPtr info = msg->Info;
TInstant now = TAppData::TimeProvider->Now();
- STLOG(PRI_DEBUG, BS_REPL, BSVR16, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM COMPLETED"), (Info, *info));
+ STLOG(PRI_DEBUG, BS_REPL, BSVR16, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM COMPLETED"), (Info, *info));
LastReplQuantumEnd = now;
- bool finished = false;
-
- if (info->Eof) { // when it is the last quantum for some donor, rotate the blob sets
- ReplCtx->MonGroup.ReplUnreplicatedBlobs() = UnreplicatedBlobsPtr->size();
- BlobsToReplicatePtr = std::move(UnreplicatedBlobsPtr);
- UnreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
- if (BlobsToReplicatePtr->empty()) {
- // no more blobs to replicate -- consider replication finished
- finished = true;
- for (const auto& donor : std::exchange(DonorQueue, {})) {
- if (donor) {
- DropDonor(*donor);
- }
- }
- }
- if (!finished) {
- if (info->DropDonor) {
- Y_VERIFY(!DonorQueue.empty() && DonorQueue.front());
- DropDonor(*DonorQueue.front());
- DonorQueue.pop_front();
- } else {
- finished = !DonorQueue.front();
- DonorQueue.splice(DonorQueue.end(), DonorQueue, DonorQueue.begin()); // move first item to the end
- }
- }
- }
-
+ bool finished = false;
+
+ if (info->Eof) { // when it is the last quantum for some donor, rotate the blob sets
+ ReplCtx->MonGroup.ReplUnreplicatedBlobs() = UnreplicatedBlobsPtr->size();
+ BlobsToReplicatePtr = std::move(UnreplicatedBlobsPtr);
+ UnreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
+ if (BlobsToReplicatePtr->empty()) {
+ // no more blobs to replicate -- consider replication finished
+ finished = true;
+ for (const auto& donor : std::exchange(DonorQueue, {})) {
+ if (donor) {
+ DropDonor(*donor);
+ }
+ }
+ }
+ if (!finished) {
+ if (info->DropDonor) {
+ Y_VERIFY(!DonorQueue.empty() && DonorQueue.front());
+ DropDonor(*DonorQueue.front());
+ DonorQueue.pop_front();
+ } else {
+ finished = !DonorQueue.front();
+ DonorQueue.splice(DonorQueue.end(), DonorQueue, DonorQueue.begin()); // move first item to the end
+ }
+ }
+ }
+
History.Push(info);
- if (finished) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR17, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "REPL COMPLETED"),
- (BlobsToReplicate, BlobsToReplicatePtr->size()));
+ if (finished) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR17, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "REPL COMPLETED"),
+ (BlobsToReplicate, BlobsToReplicatePtr->size()));
LastReplEnd = now;
ReplCtx->MonGroup.ReplUnreplicatedBytes() = ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes();
ReplCtx->MonGroup.ReplPhantoms() = ReplCtx->MonGroup.ReplCurrentPhantoms();
- ReplCtx->MonGroup.ReplNumUnrecoveredPhantomBlobs() = ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs();
- ReplCtx->MonGroup.ReplNumUnrecoveredNonPhantomBlobs() = ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs();
-
- if (State == WaitQueues || State == Replication) {
- // release token as we have finished replicating
- Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplToken);
- }
-
+ ReplCtx->MonGroup.ReplNumUnrecoveredPhantomBlobs() = ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs();
+ ReplCtx->MonGroup.ReplNumUnrecoveredNonPhantomBlobs() = ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs();
+
+ if (State == WaitQueues || State == Replication) {
+ // release token as we have finished replicating
+ Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplToken);
+ }
+
Become(&TThis::StateRelax);
- if (*BlobsToReplicatePtr) {
- // try again for unreplicated blobs in some future
- State = Relaxation;
- Schedule(ReplCtx->VDiskCfg->ReplTimeInterval, new TEvents::TEvWakeup);
- } else {
- // no more blobs to replicate; replication will not resume
- State = Finished;
- ReplCtx->MonGroup.ReplUnreplicatedVDisks() = 0;
- TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvReplDone, 0, ReplCtx->SkeletonId,
- SelfId(), nullptr, 0));
- }
+ if (*BlobsToReplicatePtr) {
+ // try again for unreplicated blobs in some future
+ State = Relaxation;
+ Schedule(ReplCtx->VDiskCfg->ReplTimeInterval, new TEvents::TEvWakeup);
+ } else {
+ // no more blobs to replicate; replication will not resume
+ State = Finished;
+ ReplCtx->MonGroup.ReplUnreplicatedVDisks() = 0;
+ TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvReplDone, 0, ReplCtx->SkeletonId,
+ SelfId(), nullptr, 0));
+ }
} else {
- STLOG(PRI_DEBUG, BS_REPL, BSVR18, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM START"));
- RunRepl(info->KeyPos);
+ STLOG(PRI_DEBUG, BS_REPL, BSVR18, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "QUANTUM START"));
+ RunRepl(info->KeyPos);
}
}
- void RunRepl(const TLogoBlobID& from) {
- LastReplQuantumStart = TAppData::TimeProvider->Now();
- Y_VERIFY(!ReplJobActorId);
- const auto& donor = DonorQueue.front();
- STLOG(PRI_DEBUG, BS_REPL, BSVR32, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TReplScheduler::RunRepl"),
- (From, from), (Donor, donor ? TString(TStringBuilder() << "{VDiskId# " << donor->VDiskId << " VSlotId# " <<
- donor->NodeId << ":" << donor->PDiskId << ":" << donor->VSlotId << "}") : "generic"));
- ReplJobActorId = Register(CreateReplJobActor(ReplCtx, SelfId(), from, QueueActorMapPtr,
- BlobsToReplicatePtr, UnreplicatedBlobsPtr, donor ? std::make_optional(std::make_pair(
- donor->VDiskId, donor->QueueActorId)) : std::nullopt));
- }
-
- template<typename Iter>
+ void RunRepl(const TLogoBlobID& from) {
+ LastReplQuantumStart = TAppData::TimeProvider->Now();
+ Y_VERIFY(!ReplJobActorId);
+ const auto& donor = DonorQueue.front();
+ STLOG(PRI_DEBUG, BS_REPL, BSVR32, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TReplScheduler::RunRepl"),
+ (From, from), (Donor, donor ? TString(TStringBuilder() << "{VDiskId# " << donor->VDiskId << " VSlotId# " <<
+ donor->NodeId << ":" << donor->PDiskId << ":" << donor->VSlotId << "}") : "generic"));
+ ReplJobActorId = Register(CreateReplJobActor(ReplCtx, SelfId(), from, QueueActorMapPtr,
+ BlobsToReplicatePtr, UnreplicatedBlobsPtr, donor ? std::make_optional(std::make_pair(
+ donor->VDiskId, donor->QueueActorId)) : std::nullopt));
+ }
+
+ template<typename Iter>
void OutputRow(IOutputStream &str, Iter &it, Iter &e) {
HTML(str) {
TABLER() {
@@ -422,28 +422,28 @@ namespace NKikimr {
}
}
- template<typename Iter>
+ template<typename Iter>
void OutputQuantums(IOutputStream& str, Iter it, Iter e) {
- if (it != e) {
- OutputRow(str, it, e);
- if (it != e) {
+ if (it != e) {
+ OutputRow(str, it, e);
+ if (it != e) {
HTML(str) {
TABLER() {
- str << "<td colspan=3>";
+ str << "<td colspan=3>";
TString id = CreateGuidAsString();
COLLAPSED_BUTTON_CONTENT(id, "More") {
TABLE() {
- OutputQuantums(str, it, e);
+ OutputQuantums(str, it, e);
}
}
- str << "</td>";
+ str << "</td>";
}
}
- }
- }
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr &ev) {
+ }
+ }
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr &ev) {
Y_VERIFY_DEBUG(ev->Get()->SubRequestId == TDbMon::ReplId);
TStringStream str;
@@ -453,33 +453,33 @@ namespace NKikimr {
DIV_CLASS("panel panel-success") {
DIV_CLASS("panel-heading") {str << "Repl";}
DIV_CLASS("panel-body") {
- auto makeConnectedDonorDisks = [&]() -> TString {
- TStringBuilder s;
- s << "[";
- for (auto it = ConnectedDonorDisks.begin(); it != ConnectedDonorDisks.end(); ++it) {
- if (it != ConnectedDonorDisks.begin()) {
- s << " ";
- }
- s << *it;
- }
- return s << "]";
- };
- str << "State: " << StateToStr(State) << "<br>"
- << "LastReplStart: " << ToStringLocalTimeUpToSeconds(LastReplStart) << "<br>"
- << "LastReplEnd: " << ToStringLocalTimeUpToSeconds(LastReplEnd) << "<br>"
- << "LastReplQuantumStart: " << ToStringLocalTimeUpToSeconds(LastReplQuantumStart) << "<br>"
- << "LastReplQuantumEnd: " << ToStringLocalTimeUpToSeconds(LastReplQuantumEnd) << "<br>"
- << "NumConnectedPeerDisks: " << ConnectedPeerDisks.size() << "<br>"
- << "ConnectedDonorDisks: " << makeConnectedDonorDisks() << "<br>";
+ auto makeConnectedDonorDisks = [&]() -> TString {
+ TStringBuilder s;
+ s << "[";
+ for (auto it = ConnectedDonorDisks.begin(); it != ConnectedDonorDisks.end(); ++it) {
+ if (it != ConnectedDonorDisks.begin()) {
+ s << " ";
+ }
+ s << *it;
+ }
+ return s << "]";
+ };
+ str << "State: " << StateToStr(State) << "<br>"
+ << "LastReplStart: " << ToStringLocalTimeUpToSeconds(LastReplStart) << "<br>"
+ << "LastReplEnd: " << ToStringLocalTimeUpToSeconds(LastReplEnd) << "<br>"
+ << "LastReplQuantumStart: " << ToStringLocalTimeUpToSeconds(LastReplQuantumStart) << "<br>"
+ << "LastReplQuantumEnd: " << ToStringLocalTimeUpToSeconds(LastReplQuantumEnd) << "<br>"
+ << "NumConnectedPeerDisks: " << ConnectedPeerDisks.size() << "<br>"
+ << "ConnectedDonorDisks: " << makeConnectedDonorDisks() << "<br>";
TABLE_CLASS ("table table-condensed") {
CAPTION() STRONG() {str << "Last " << historySize << " replication quantums"; }
TABLEBODY() {
TVector<TEvReplFinished::TInfoPtr> quantums;
- for (auto it = History.Begin(); it != History.End(); ++it) {
- quantums.push_back(*it);
- }
- OutputQuantums(str, quantums.rbegin(), quantums.rend());
+ for (auto it = History.Begin(); it != History.End(); ++it) {
+ quantums.push_back(*it);
+ }
+ OutputQuantums(str, quantums.rbegin(), quantums.rend());
}
}
}
@@ -487,103 +487,103 @@ namespace NKikimr {
}
str << "\n";
- Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), TDbMon::ReplId));
+ Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), TDbMon::ReplId));
}
- void HandleGenerationChange(TEvVGenerationChange::TPtr& ev) {
- // forward message to queue actors
- TEvVGenerationChange *msg = ev->Get();
+ void HandleGenerationChange(TEvVGenerationChange::TPtr& ev) {
+ // forward message to queue actors
+ TEvVGenerationChange *msg = ev->Get();
for (const auto& kv : *QueueActorMapPtr) {
- Send(kv.second, msg->Clone());
- }
- ReplCtx->GInfo = msg->NewInfo;
- }
-
- std::set<TActorId> DonorQueryActors;
-
- void Handle(TEvBlobStorage::TEvEnrichNotYet::TPtr ev) {
- DonorQueryActors.insert(Register(new TDonorQueryActor(*ev->Get(), Donors)));
- }
-
- void Handle(TEvents::TEvActorDied::TPtr ev) {
- const size_t num = DonorQueryActors.erase(ev->Sender);
- Y_VERIFY(num);
- }
-
- void Ignore()
- {}
-
- STRICT_STFUNC(StateRelax,
- cFunc(TEvents::TSystem::Wakeup, StartReplication)
- hFunc(NMon::TEvHttpInfo, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- hFunc(TEvProxyQueueState, Handle)
- hFunc(TEvVGenerationChange, HandleGenerationChange)
- hFunc(TEvResumeForce, Handle)
- hFunc(TEvBlobStorage::TEvEnrichNotYet, Handle)
- hFunc(TEvents::TEvActorDied, Handle)
- cFunc(TEvBlobStorage::EvCommenceRepl, StartReplication)
- )
-
- void PassAway() override {
- // forward poison pills to queue actors
+ Send(kv.second, msg->Clone());
+ }
+ ReplCtx->GInfo = msg->NewInfo;
+ }
+
+ std::set<TActorId> DonorQueryActors;
+
+ void Handle(TEvBlobStorage::TEvEnrichNotYet::TPtr ev) {
+ DonorQueryActors.insert(Register(new TDonorQueryActor(*ev->Get(), Donors)));
+ }
+
+ void Handle(TEvents::TEvActorDied::TPtr ev) {
+ const size_t num = DonorQueryActors.erase(ev->Sender);
+ Y_VERIFY(num);
+ }
+
+ void Ignore()
+ {}
+
+ STRICT_STFUNC(StateRelax,
+ cFunc(TEvents::TSystem::Wakeup, StartReplication)
+ hFunc(NMon::TEvHttpInfo, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ hFunc(TEvProxyQueueState, Handle)
+ hFunc(TEvVGenerationChange, HandleGenerationChange)
+ hFunc(TEvResumeForce, Handle)
+ hFunc(TEvBlobStorage::TEvEnrichNotYet, Handle)
+ hFunc(TEvents::TEvActorDied, Handle)
+ cFunc(TEvBlobStorage::EvCommenceRepl, StartReplication)
+ )
+
+ void PassAway() override {
+ // forward poison pills to queue actors
for (const auto& kv : *QueueActorMapPtr) {
- Send(kv.second, new TEvents::TEvPoison);
- }
- for (const auto& donor : DonorQueue) {
- if (donor) {
- Send(donor->QueueActorId, new TEvents::TEvPoison);
- }
- }
- for (const TActorId& actorId : DonorQueryActors) {
- Send(actorId, new TEvents::TEvPoison);
- }
-
- // return replication token if we have one
- if (State == AwaitToken || State == WaitQueues || State == Replication) {
- Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplToken);
- }
-
- if (ReplJobActorId) {
- Send(ReplJobActorId, new TEvents::TEvPoison);
- }
-
- TActorBootstrapped::PassAway();
+ Send(kv.second, new TEvents::TEvPoison);
+ }
+ for (const auto& donor : DonorQueue) {
+ if (donor) {
+ Send(donor->QueueActorId, new TEvents::TEvPoison);
+ }
+ }
+ for (const TActorId& actorId : DonorQueryActors) {
+ Send(actorId, new TEvents::TEvPoison);
+ }
+
+ // return replication token if we have one
+ if (State == AwaitToken || State == WaitQueues || State == Replication) {
+ Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplToken);
+ }
+
+ if (ReplJobActorId) {
+ Send(ReplJobActorId, new TEvents::TEvPoison);
+ }
+
+ TActorBootstrapped::PassAway();
}
- STRICT_STFUNC(StateRepl,
- cFunc(TEvReplToken::EventType, HandleReplToken)
- hFunc(TEvReplStarted, Handle)
- hFunc(TEvReplFinished, Handle)
- hFunc(NMon::TEvHttpInfo, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- hFunc(TEvProxyQueueState, Handle)
- hFunc(TEvVGenerationChange, HandleGenerationChange)
- hFunc(TEvResumeForce, Handle)
- hFunc(TEvBlobStorage::TEvEnrichNotYet, Handle)
- hFunc(TEvents::TEvActorDied, Handle)
- cFunc(TEvBlobStorage::EvCommenceRepl, Ignore)
- )
+ STRICT_STFUNC(StateRepl,
+ cFunc(TEvReplToken::EventType, HandleReplToken)
+ hFunc(TEvReplStarted, Handle)
+ hFunc(TEvReplFinished, Handle)
+ hFunc(NMon::TEvHttpInfo, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ hFunc(TEvProxyQueueState, Handle)
+ hFunc(TEvVGenerationChange, HandleGenerationChange)
+ hFunc(TEvResumeForce, Handle)
+ hFunc(TEvBlobStorage::TEvEnrichNotYet, Handle)
+ hFunc(TEvents::TEvActorDied, Handle)
+ cFunc(TEvBlobStorage::EvCommenceRepl, Ignore)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_REPL_SCHEDULER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_REPL_SCHEDULER;
}
- TReplScheduler(std::shared_ptr<TReplCtx> &replCtx)
+ TReplScheduler(std::shared_ptr<TReplCtx> &replCtx)
: TActorBootstrapped<TReplScheduler>()
, ReplCtx(replCtx)
, History(HistorySize)
, State(Relaxation)
- {}
+ {}
};
////////////////////////////////////////////////////////////////////////////
// REPL ACTOR CREATOR
////////////////////////////////////////////////////////////////////////////
- IActor* CreateReplActor(std::shared_ptr<TReplCtx> &replCtx) {
- return new TReplScheduler(replCtx);
+ IActor* CreateReplActor(std::shared_ptr<TReplCtx> &replCtx) {
+ return new TReplScheduler(replCtx);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.h
index 629d65bea97..0b0c28e6b98 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_repl.h
@@ -7,17 +7,17 @@
namespace NKikimr {
- namespace NRepl {
- struct TProxyStat;
- };
-
+ namespace NRepl {
+ struct TProxyStat;
+ };
+
using TBlobIdQueue = TQueue<TLogoBlobID>;
- using TBlobIdQueuePtr = std::shared_ptr<TBlobIdQueue>;
-
+ using TBlobIdQueuePtr = std::shared_ptr<TBlobIdQueue>;
+
////////////////////////////////////////////////////////////////////////////
// Internal Repl messages
////////////////////////////////////////////////////////////////////////////
- struct TEvReplStarted : TEventLocal<TEvReplStarted, TEvBlobStorage::EvReplStarted> {};
+ struct TEvReplStarted : TEventLocal<TEvReplStarted, TEvBlobStorage::EvReplStarted> {};
struct TEvReplFinished : public TEventLocal<TEvReplFinished, TEvBlobStorage::EvReplFinished> {
struct TInfo : public TThrRefBase {
@@ -26,58 +26,58 @@ namespace NKikimr {
TInstant End;
TLogoBlobID KeyPos;
bool Eof;
- TVDiskID DonorVDiskId;
- bool DropDonor = false;
+ TVDiskID DonorVDiskId;
+ bool DropDonor = false;
// generate plan stats
ui64 ReplicaOk = 0;
ui64 RecoveryScheduled = 0;
- ui64 IgnoredDueToGC = 0;
+ ui64 IgnoredDueToGC = 0;
// plan execution stats
ui64 DataRecoverySuccess = 0;
ui64 DataRecoveryFailure = 0;
- ui64 DataRecoveryNoParts = 0;
- ui64 DataRecoverySkip = 0;
- ui64 DataRecoveryPhantomCheck = 0;
-
- // detailed stats
- ui64 BytesRecovered = 0;
- ui64 LogoBlobsRecovered = 0;
- ui64 HugeLogoBlobsRecovered = 0;
- ui64 ChunksWritten = 0;
- ui64 SstBytesWritten = 0;
- ui64 MultipartBlobs = 0;
- ui64 MetadataBlobs = 0;
- ui64 PartsPlanned = 0;
- ui64 PartsExact = 0;
- ui64 PartsRestored = 0;
- ui64 PartsMissing = 0;
-
- // time durations
- TDuration PreparePlanDuration;
- TDuration TokenWaitDuration;
- TDuration ProxyWaitDuration;
- TDuration MergeDuration;
- TDuration PDiskDuration;
- TDuration CommitDuration;
- TDuration OtherDuration;
- TDuration PhantomDuration;
-
- std::unique_ptr<NRepl::TProxyStat> ProxyStat;
-
- void Finish(const TLogoBlobID &keyPos, bool eof, bool dropDonor) {
+ ui64 DataRecoveryNoParts = 0;
+ ui64 DataRecoverySkip = 0;
+ ui64 DataRecoveryPhantomCheck = 0;
+
+ // detailed stats
+ ui64 BytesRecovered = 0;
+ ui64 LogoBlobsRecovered = 0;
+ ui64 HugeLogoBlobsRecovered = 0;
+ ui64 ChunksWritten = 0;
+ ui64 SstBytesWritten = 0;
+ ui64 MultipartBlobs = 0;
+ ui64 MetadataBlobs = 0;
+ ui64 PartsPlanned = 0;
+ ui64 PartsExact = 0;
+ ui64 PartsRestored = 0;
+ ui64 PartsMissing = 0;
+
+ // time durations
+ TDuration PreparePlanDuration;
+ TDuration TokenWaitDuration;
+ TDuration ProxyWaitDuration;
+ TDuration MergeDuration;
+ TDuration PDiskDuration;
+ TDuration CommitDuration;
+ TDuration OtherDuration;
+ TDuration PhantomDuration;
+
+ std::unique_ptr<NRepl::TProxyStat> ProxyStat;
+
+ void Finish(const TLogoBlobID &keyPos, bool eof, bool dropDonor) {
End = TAppData::TimeProvider->Now();
KeyPos = keyPos;
Eof = eof;
- DropDonor = dropDonor;
+ DropDonor = dropDonor;
}
TString ToString() const;
void OutputHtml(IOutputStream &str) const;
- TInfo();
- ~TInfo();
+ TInfo();
+ ~TInfo();
};
typedef TIntrusivePtr<TInfo> TInfoPtr;
@@ -88,43 +88,43 @@ namespace NKikimr {
{}
};
- struct TEvReplResume : TEventLocal<TEvReplResume, TEvBlobStorage::EvReplResume> {};
-
+ struct TEvReplResume : TEventLocal<TEvReplResume, TEvBlobStorage::EvReplResume> {};
+
////////////////////////////////////////////////////////////////////////////
// Message for recovered data (to Skeleton)
////////////////////////////////////////////////////////////////////////////
- struct TEvRecoveredHugeBlob : public TEventLocal<TEvRecoveredHugeBlob, TEvBlobStorage::EvRecoveredHugeBlob> {
+ struct TEvRecoveredHugeBlob : public TEventLocal<TEvRecoveredHugeBlob, TEvBlobStorage::EvRecoveredHugeBlob> {
const TLogoBlobID Id;
- TRope Data;
+ TRope Data;
- TEvRecoveredHugeBlob(const TLogoBlobID &id, TRope&& data)
+ TEvRecoveredHugeBlob(const TLogoBlobID &id, TRope&& data)
: Id(id)
- , Data(std::move(data))
+ , Data(std::move(data))
{
Y_VERIFY_DEBUG(Id.PartId() != 0);
}
size_t ByteSize() const {
- return sizeof(TLogoBlobID) + Data.GetSize();
+ return sizeof(TLogoBlobID) + Data.GetSize();
}
};
- struct TEvDetectedPhantomBlob : public TEventLocal<TEvDetectedPhantomBlob, TEvBlobStorage::EvDetectedPhantomBlob> {
+ struct TEvDetectedPhantomBlob : public TEventLocal<TEvDetectedPhantomBlob, TEvBlobStorage::EvDetectedPhantomBlob> {
TDeque<TLogoBlobID> Phantoms;
TEvDetectedPhantomBlob(TDeque<TLogoBlobID>&& phantoms)
- : Phantoms(std::move(phantoms))
- {}
+ : Phantoms(std::move(phantoms))
+ {}
size_t ByteSize() const {
return sizeof(TLogoBlobID) * Phantoms.size();
}
- };
-
+ };
+
////////////////////////////////////////////////////////////////////////////
// REPL ACTOR CREATOR
////////////////////////////////////////////////////////////////////////////
- IActor* CreateReplActor(std::shared_ptr<TReplCtx> &replCtx);
+ IActor* CreateReplActor(std::shared_ptr<TReplCtx> &replCtx);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.cpp
index 543f0a537db..2be0e961295 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.cpp
@@ -1,174 +1,174 @@
-#include "blobstorage_replbroker.h"
+#include "blobstorage_replbroker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/queue.h>
-
-namespace NKikimr {
-
- class TReplBroker : public TActor<TReplBroker> {
- // queue of senders waiting for token per PDisk; the first one in queue always has a token
+#include <util/generic/hash_set.h>
+#include <util/generic/queue.h>
+
+namespace NKikimr {
+
+ class TReplBroker : public TActor<TReplBroker> {
+ // queue of senders waiting for token per PDisk; the first one in queue always has a token
THashMap<ui32, TDeque<TActorId>> VDiskQ;
THashMap<TActorId, ui32> SenderToPDisk;
-
- struct TMemQueueItem {
+
+ struct TMemQueueItem {
TActorId Sender;
- ui64 Cookie;
- ui64 Bytes;
-
+ ui64 Cookie;
+ ui64 Bytes;
+
TMemQueueItem(const TActorId& sender, ui64 cookie, ui64 bytes)
- : Sender(sender)
- , Cookie(cookie)
- , Bytes(bytes)
- {}
- };
+ : Sender(sender)
+ , Cookie(cookie)
+ , Bytes(bytes)
+ {}
+ };
TDeque<TMemQueueItem> MemQueue;
- i64 MemFree;
-
- struct TMemToken {
+ i64 MemFree;
+
+ struct TMemToken {
TActorId Sender;
- ui64 Bytes;
-
+ ui64 Bytes;
+
TMemToken(const TActorId& sender, ui64 bytes)
- : Sender(sender)
- , Bytes(bytes)
- {}
- };
+ : Sender(sender)
+ , Bytes(bytes)
+ {}
+ };
THashMap<TReplMemTokenId, TMemToken> MemTokens;
- TReplMemTokenId NextMemToken = 1;
-
- public:
+ TReplMemTokenId NextMemToken = 1;
+
+ public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_REPL_BROKER;
- }
-
- TReplBroker(ui64 maxMemBytes)
- : TActor(&TReplBroker::StateFunc)
- , MemFree(maxMemBytes)
- {}
-
- void Handle(TEvQueryReplToken::TPtr& ev) {
- const ui32 pdiskId = ev->Get()->PDiskId;
- const bool inserted = SenderToPDisk.emplace(ev->Sender, pdiskId).second;
- Y_VERIFY(inserted, "duplicate request for the replication token");
- auto& q = VDiskQ[pdiskId];
- q.push_back(ev->Sender);
- if (q.size() == 1) {
- Send(ev->Sender, new TEvReplToken);
- }
- }
-
- void Handle(TEvReleaseReplToken::TPtr& ev) {
- // first, find the queue for the requested PDisk; it MUST exist as the ReleaseToken operation is only possible
- // after issuing the QueryToken message
- auto it = SenderToPDisk.find(ev->Sender);
- Y_VERIFY(it != SenderToPDisk.end());
- const ui32 pdiskId = it->second;
- auto qIt = VDiskQ.find(pdiskId);
- Y_VERIFY(qIt != VDiskQ.end());
- auto& q = qIt->second;
- Y_VERIFY(q);
- SenderToPDisk.erase(it);
-
- if (q.front() == ev->Sender) {
- q.pop_front();
- if (q) {
- // we have next disk to grant replication to, so do it
- Send(q.front(), new TEvReplToken);
- } else {
- // replication queue for this PDisk got empty, remove it from the dictionary
- VDiskQ.erase(qIt);
- }
- } else {
- // just remove pending request from the queue; it has not been granted yet
- auto it = std::find(q.begin(), q.end(), ev->Sender);
- Y_VERIFY(it != q.end());
- q.erase(it);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // MEMORY MANAGEMENT
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ProcessMemQueue() {
- while (MemQueue && MemFree >= 0) {
- // check if we can allocate one more token -- if we have enough memory, or if we don't have tokens at all
- auto& item = MemQueue.front();
- if (item.Bytes > static_cast<ui64>(MemFree) && MemTokens) {
- break;
- }
-
- // allocate token
- const TReplMemTokenId token = NextMemToken++;
-
- // send response
- Send(item.Sender, new TEvReplMemToken(token), 0, item.Cookie);
-
- // register token
- MemTokens.emplace(token, TMemToken(item.Sender, item.Bytes));
-
- // adjust free mem size
- MemFree -= item.Bytes;
-
- // remove processed request
- MemQueue.pop_front();
- }
- }
-
- void Handle(TEvQueryReplMemToken::TPtr& ev) {
- MemQueue.emplace_back(ev->Sender, ev->Cookie, ev->Get()->Bytes);
- ProcessMemQueue();
- }
-
- void Handle(TEvUpdateReplMemToken::TPtr& ev) {
- TEvUpdateReplMemToken *msg = ev->Get();
- auto it = MemTokens.find(msg->Token);
- Y_VERIFY(it != MemTokens.end());
- TMemToken& token = it->second;
- MemFree += token.Bytes - msg->ActualBytes;
- token.Bytes = msg->ActualBytes;
- ProcessMemQueue();
- }
-
- void Handle(TEvReleaseReplMemToken::TPtr& ev) {
- auto it = MemTokens.find(ev->Get()->Token);
- Y_VERIFY(it != MemTokens.end());
- MemFree += it->second.Bytes;
- MemTokens.erase(it);
- ProcessMemQueue();
- }
-
- void Handle(TEvPruneQueue::TPtr& ev) {
- auto pred = [&](const auto& item) {
- return item.Sender == ev->Sender;
- };
- MemQueue.erase(std::remove_if(MemQueue.begin(), MemQueue.end(), pred), MemQueue.end());
-
- for (auto it = MemTokens.begin(); it != MemTokens.end(); ) {
- if (it->second.Sender == ev->Sender) {
- MemFree += it->second.Bytes;
- MemTokens.erase(it++);
- } else {
- ++it;
- }
- }
-
- ProcessMemQueue();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvQueryReplToken, Handle)
- hFunc(TEvReleaseReplToken, Handle)
- hFunc(TEvQueryReplMemToken, Handle)
- hFunc(TEvUpdateReplMemToken, Handle)
- hFunc(TEvReleaseReplMemToken, Handle)
- hFunc(TEvPruneQueue, Handle)
- )
- };
-
- IActor *CreateReplBrokerActor(ui64 maxMemBytes) {
- return new TReplBroker(maxMemBytes);
- }
-
-} // NKikimr
+ return NKikimrServices::TActivity::BS_REPL_BROKER;
+ }
+
+ TReplBroker(ui64 maxMemBytes)
+ : TActor(&TReplBroker::StateFunc)
+ , MemFree(maxMemBytes)
+ {}
+
+ void Handle(TEvQueryReplToken::TPtr& ev) {
+ const ui32 pdiskId = ev->Get()->PDiskId;
+ const bool inserted = SenderToPDisk.emplace(ev->Sender, pdiskId).second;
+ Y_VERIFY(inserted, "duplicate request for the replication token");
+ auto& q = VDiskQ[pdiskId];
+ q.push_back(ev->Sender);
+ if (q.size() == 1) {
+ Send(ev->Sender, new TEvReplToken);
+ }
+ }
+
+ void Handle(TEvReleaseReplToken::TPtr& ev) {
+ // first, find the queue for the requested PDisk; it MUST exist as the ReleaseToken operation is only possible
+ // after issuing the QueryToken message
+ auto it = SenderToPDisk.find(ev->Sender);
+ Y_VERIFY(it != SenderToPDisk.end());
+ const ui32 pdiskId = it->second;
+ auto qIt = VDiskQ.find(pdiskId);
+ Y_VERIFY(qIt != VDiskQ.end());
+ auto& q = qIt->second;
+ Y_VERIFY(q);
+ SenderToPDisk.erase(it);
+
+ if (q.front() == ev->Sender) {
+ q.pop_front();
+ if (q) {
+ // we have next disk to grant replication to, so do it
+ Send(q.front(), new TEvReplToken);
+ } else {
+ // replication queue for this PDisk got empty, remove it from the dictionary
+ VDiskQ.erase(qIt);
+ }
+ } else {
+ // just remove pending request from the queue; it has not been granted yet
+ auto it = std::find(q.begin(), q.end(), ev->Sender);
+ Y_VERIFY(it != q.end());
+ q.erase(it);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MEMORY MANAGEMENT
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ProcessMemQueue() {
+ while (MemQueue && MemFree >= 0) {
+ // check if we can allocate one more token -- if we have enough memory, or if we don't have tokens at all
+ auto& item = MemQueue.front();
+ if (item.Bytes > static_cast<ui64>(MemFree) && MemTokens) {
+ break;
+ }
+
+ // allocate token
+ const TReplMemTokenId token = NextMemToken++;
+
+ // send response
+ Send(item.Sender, new TEvReplMemToken(token), 0, item.Cookie);
+
+ // register token
+ MemTokens.emplace(token, TMemToken(item.Sender, item.Bytes));
+
+ // adjust free mem size
+ MemFree -= item.Bytes;
+
+ // remove processed request
+ MemQueue.pop_front();
+ }
+ }
+
+ void Handle(TEvQueryReplMemToken::TPtr& ev) {
+ MemQueue.emplace_back(ev->Sender, ev->Cookie, ev->Get()->Bytes);
+ ProcessMemQueue();
+ }
+
+ void Handle(TEvUpdateReplMemToken::TPtr& ev) {
+ TEvUpdateReplMemToken *msg = ev->Get();
+ auto it = MemTokens.find(msg->Token);
+ Y_VERIFY(it != MemTokens.end());
+ TMemToken& token = it->second;
+ MemFree += token.Bytes - msg->ActualBytes;
+ token.Bytes = msg->ActualBytes;
+ ProcessMemQueue();
+ }
+
+ void Handle(TEvReleaseReplMemToken::TPtr& ev) {
+ auto it = MemTokens.find(ev->Get()->Token);
+ Y_VERIFY(it != MemTokens.end());
+ MemFree += it->second.Bytes;
+ MemTokens.erase(it);
+ ProcessMemQueue();
+ }
+
+ void Handle(TEvPruneQueue::TPtr& ev) {
+ auto pred = [&](const auto& item) {
+ return item.Sender == ev->Sender;
+ };
+ MemQueue.erase(std::remove_if(MemQueue.begin(), MemQueue.end(), pred), MemQueue.end());
+
+ for (auto it = MemTokens.begin(); it != MemTokens.end(); ) {
+ if (it->second.Sender == ev->Sender) {
+ MemFree += it->second.Bytes;
+ MemTokens.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+
+ ProcessMemQueue();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvQueryReplToken, Handle)
+ hFunc(TEvReleaseReplToken, Handle)
+ hFunc(TEvQueryReplMemToken, Handle)
+ hFunc(TEvUpdateReplMemToken, Handle)
+ hFunc(TEvReleaseReplMemToken, Handle)
+ hFunc(TEvPruneQueue, Handle)
+ )
+ };
+
+ IActor *CreateReplBrokerActor(ui64 maxMemBytes) {
+ return new TReplBroker(maxMemBytes);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h
index 31d3359a55d..5391639c05c 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replbroker.h
@@ -1,71 +1,71 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include <ydb/core/base/blobstorage.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
-
-namespace NKikimr {
-
- // Replication token. Token is requested from replication broker using TEvQueryReplToken message. Token is granted
- // via TEvReplToken message, after reception of this message VDisk has to start its replication session. When session
- // is finished, granted token is returned via TEvReleaseReplToken message. Token is identified by the sender actor,
- // so the sender for Query and Release messages must be the same.
-
- struct TEvQueryReplToken : public TEventLocal<TEvQueryReplToken, TEvBlobStorage::EvQueryReplToken> {
- ui32 PDiskId; // PDisk it resides on
-
- TEvQueryReplToken(ui32 pdiskId)
- : PDiskId(pdiskId)
- {}
- };
-
- struct TEvReplToken : public TEventLocal<TEvReplToken, TEvBlobStorage::EvReplToken>
- {};
-
- struct TEvReleaseReplToken : public TEventLocal<TEvReleaseReplToken, TEvBlobStorage::EvReleaseReplToken>
- {};
-
- // Memory usage token. When replication proxy wants to keep N bytes in memory/in flight of interconnect queue, then
- // it sends TEvQueryReplMemToken request to replication broker. When granted via TEvReplMemToken, proxy issues
- // operation that consumes specified amount of memory. When amount changes, it can be corrected by sending
- // TEvUpdateReplMemToken message to broker. When memory is released, proxy sends TEvReleaseReplMemToken to broker.
-
- using TReplMemTokenId = ui64;
-
- struct TEvQueryReplMemToken : public TEventLocal<TEvQueryReplMemToken, TEvBlobStorage::EvQueryReplMemToken> {
- ui64 Bytes;
-
- TEvQueryReplMemToken(ui64 bytes)
- : Bytes(bytes)
- {}
- };
-
- struct TEvReplMemToken : public TEventLocal<TEvReplMemToken, TEvBlobStorage::EvReplMemToken> {
- TReplMemTokenId Token;
-
- TEvReplMemToken(TReplMemTokenId token)
- : Token(token)
- {}
- };
-
- struct TEvUpdateReplMemToken : public TEventLocal<TEvUpdateReplMemToken, TEvBlobStorage::EvUpdateReplMemToken> {
- TReplMemTokenId Token;
- ui64 ActualBytes;
-
- TEvUpdateReplMemToken(TReplMemTokenId token, ui64 actualBytes)
- : Token(token)
- , ActualBytes(actualBytes)
- {}
- };
-
- struct TEvReleaseReplMemToken : public TEventLocal<TEvReleaseReplMemToken, TEvBlobStorage::EvReleaseReplMemToken> {
- TReplMemTokenId Token;
-
- TEvReleaseReplMemToken(TReplMemTokenId token)
- : Token(token)
- {}
- };
-
- extern IActor *CreateReplBrokerActor(ui64 maxMemBytes);
-
-} // NKikimr
+
+namespace NKikimr {
+
+ // Replication token. Token is requested from replication broker using TEvQueryReplToken message. Token is granted
+ // via TEvReplToken message, after reception of this message VDisk has to start its replication session. When session
+ // is finished, granted token is returned via TEvReleaseReplToken message. Token is identified by the sender actor,
+ // so the sender for Query and Release messages must be the same.
+
+ struct TEvQueryReplToken : public TEventLocal<TEvQueryReplToken, TEvBlobStorage::EvQueryReplToken> {
+ ui32 PDiskId; // PDisk it resides on
+
+ TEvQueryReplToken(ui32 pdiskId)
+ : PDiskId(pdiskId)
+ {}
+ };
+
+ struct TEvReplToken : public TEventLocal<TEvReplToken, TEvBlobStorage::EvReplToken>
+ {};
+
+ struct TEvReleaseReplToken : public TEventLocal<TEvReleaseReplToken, TEvBlobStorage::EvReleaseReplToken>
+ {};
+
+ // Memory usage token. When replication proxy wants to keep N bytes in memory/in flight of interconnect queue, then
+ // it sends TEvQueryReplMemToken request to replication broker. When granted via TEvReplMemToken, proxy issues
+ // operation that consumes specified amount of memory. When amount changes, it can be corrected by sending
+ // TEvUpdateReplMemToken message to broker. When memory is released, proxy sends TEvReleaseReplMemToken to broker.
+
+ using TReplMemTokenId = ui64;
+
+ struct TEvQueryReplMemToken : public TEventLocal<TEvQueryReplMemToken, TEvBlobStorage::EvQueryReplMemToken> {
+ ui64 Bytes;
+
+ TEvQueryReplMemToken(ui64 bytes)
+ : Bytes(bytes)
+ {}
+ };
+
+ struct TEvReplMemToken : public TEventLocal<TEvReplMemToken, TEvBlobStorage::EvReplMemToken> {
+ TReplMemTokenId Token;
+
+ TEvReplMemToken(TReplMemTokenId token)
+ : Token(token)
+ {}
+ };
+
+ struct TEvUpdateReplMemToken : public TEventLocal<TEvUpdateReplMemToken, TEvBlobStorage::EvUpdateReplMemToken> {
+ TReplMemTokenId Token;
+ ui64 ActualBytes;
+
+ TEvUpdateReplMemToken(TReplMemTokenId token, ui64 actualBytes)
+ : Token(token)
+ , ActualBytes(actualBytes)
+ {}
+ };
+
+ struct TEvReleaseReplMemToken : public TEventLocal<TEvReleaseReplMemToken, TEvBlobStorage::EvReleaseReplMemToken> {
+ TReplMemTokenId Token;
+
+ TEvReleaseReplMemToken(TReplMemTokenId token)
+ : Token(token)
+ {}
+ };
+
+ extern IActor *CreateReplBrokerActor(ui64 maxMemBytes);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replctx.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_replctx.h
index 55406e76ec8..e6193791c36 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replctx.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replctx.h
@@ -13,37 +13,37 @@ namespace NKikimr {
public:
TIntrusivePtr<TVDiskContext> VCtx;
TPDiskCtxPtr PDiskCtx;
- std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
- TIntrusivePtr<THullDs> HullDs;
- TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
+ std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ TIntrusivePtr<THullDs> HullDs;
+ TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
TActorId SkeletonId;
NMonGroup::TReplGroup MonGroup;
// settings
- TIntrusivePtr<TVDiskConfig> VDiskCfg;
- std::shared_ptr<std::atomic_uint64_t> PDiskWriteBytes;
- const bool PausedAtStart;
+ TIntrusivePtr<TVDiskConfig> VDiskCfg;
+ std::shared_ptr<std::atomic_uint64_t> PDiskWriteBytes;
+ const bool PausedAtStart;
TReplCtx(
TIntrusivePtr<TVDiskContext> vctx,
TPDiskCtxPtr pdiskCtx,
- std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
- TIntrusivePtr<THullDs> hullDs,
- TIntrusivePtr<TBlobStorageGroupInfo> info,
+ std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
+ TIntrusivePtr<THullDs> hullDs,
+ TIntrusivePtr<TBlobStorageGroupInfo> info,
const TActorId &skeletonId,
- TIntrusivePtr<TVDiskConfig> vdiskCfg,
- std::shared_ptr<std::atomic_uint64_t> pdiskWriteBytes,
- bool pausedAtStart = false)
+ TIntrusivePtr<TVDiskConfig> vdiskCfg,
+ std::shared_ptr<std::atomic_uint64_t> pdiskWriteBytes,
+ bool pausedAtStart = false)
: VCtx(std::move(vctx))
, PDiskCtx(std::move(pdiskCtx))
, HugeBlobCtx(std::move(hugeBlobCtx))
- , HullDs(std::move(hullDs))
- , GInfo(std::move(info))
+ , HullDs(std::move(hullDs))
+ , GInfo(std::move(info))
, SkeletonId(skeletonId)
, MonGroup(VCtx->VDiskCounters, "subsystem", "repl")
- , VDiskCfg(std::move(vdiskCfg))
- , PDiskWriteBytes(std::move(pdiskWriteBytes))
- , PausedAtStart(pausedAtStart)
+ , VDiskCfg(std::move(vdiskCfg))
+ , PDiskWriteBytes(std::move(pdiskWriteBytes))
+ , PausedAtStart(pausedAtStart)
{}
};
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.cpp
index 1f82e552bac..e36a74e17b3 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.cpp
@@ -1,5 +1,5 @@
#include "blobstorage_replproxy.h"
-#include "blobstorage_replbroker.h"
+#include "blobstorage_replbroker.h"
#include <ydb/core/blobstorage/vdisk/common/vdisk_events.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_response.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
@@ -17,7 +17,7 @@ namespace NKikimr {
// forward declaration
IActor *CreateVDiskProxyActor(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
TTrackableVector<TVDiskProxy::TScheduledBlob>&& ids,
const TVDiskID& vdiskId,
const TActorId& serviceId);
@@ -25,36 +25,36 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TVDiskProxy
////////////////////////////////////////////////////////////////////////////
- TVDiskProxy::TVDiskProxy(std::shared_ptr<TReplCtx> replCtx, const TVDiskID& vdisk, const TActorId& serviceId)
+ TVDiskProxy::TVDiskProxy(std::shared_ptr<TReplCtx> replCtx, const TVDiskID& vdisk, const TActorId& serviceId)
: ReplCtx(std::move(replCtx))
- , VDiskId(vdisk)
- , ServiceId(serviceId)
+ , VDiskId(vdisk)
+ , ServiceId(serviceId)
, Ids(TMemoryConsumer(ReplCtx->VCtx->Replication))
, DataPortion(TMemoryConsumer(ReplCtx->VCtx->Replication))
{}
- TActorId TVDiskProxy::Run(const TActorId& parentId) {
+ TActorId TVDiskProxy::Run(const TActorId& parentId) {
Y_VERIFY_DEBUG(State == Initial);
State = RunProxy;
- STLOG(PRI_DEBUG, BS_REPL, BSVR19, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxy::Run"));
- ParentId = parentId;
- ProxyId = TActivationContext::Register(CreateVDiskProxyActor(ReplCtx, std::move(Ids), VDiskId, ServiceId), ParentId);
- return ProxyId;
+ STLOG(PRI_DEBUG, BS_REPL, BSVR19, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxy::Run"));
+ ParentId = parentId;
+ ProxyId = TActivationContext::Register(CreateVDiskProxyActor(ReplCtx, std::move(Ids), VDiskId, ServiceId), ParentId);
+ return ProxyId;
}
- void TVDiskProxy::SendNextRequest() {
- TActorIdentity(ParentId).Send(ProxyId, new TEvReplProxyNext);
+ void TVDiskProxy::SendNextRequest() {
+ TActorIdentity(ParentId).Send(ProxyId, new TEvReplProxyNext);
}
void TVDiskProxy::HandleNext(TEvReplProxyNextResult::TPtr &ev) {
- // transit to Ok state on first message
- if (State == RunProxy) {
- State = Ok;
- }
+ // transit to Ok state on first message
+ if (State == RunProxy) {
+ State = Ok;
+ }
Y_VERIFY(State == Ok);
HandlePortion(ev->Get()->Portion);
- Stat = ev->Get()->Stat;
- HasTransientErrors = HasTransientErrors || ev->Get()->HasTransientErrors;
+ Stat = ev->Get()->Stat;
+ HasTransientErrors = HasTransientErrors || ev->Get()->HasTransientErrors;
}
void TVDiskProxy::HandlePortion(TNextPortion &portion) {
@@ -74,7 +74,7 @@ namespace NKikimr {
}
Y_VERIFY(!DataPortion.Valid());
- DataPortion = std::move(portion.DataPortion);
+ DataPortion = std::move(portion.DataPortion);
}
@@ -89,388 +89,388 @@ namespace NKikimr {
//
////////////////////////////////////////////////////////////////////////////
class TVDiskProxyActor : public TActorBootstrapped<TVDiskProxyActor> {
- using TQueueItem = std::unique_ptr<TEvBlobStorage::TEvVGetResult>;
-
- struct TCompare {
- bool operator ()(const TQueueItem& left, const TQueueItem& right) const {
- return left->Record.GetCookie() > right->Record.GetCookie();
- }
- };
-
- enum {
- EvProcessDelayedEvent = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
- struct TEvProcessDelayedEvent : TEventLocal<TEvProcessDelayedEvent, EvProcessDelayedEvent> {
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> Event;
- TEvProcessDelayedEvent(std::unique_ptr<TEvBlobStorage::TEvVGetResult> event)
- : Event(std::move(event))
- {}
- };
-
+ using TQueueItem = std::unique_ptr<TEvBlobStorage::TEvVGetResult>;
+
+ struct TCompare {
+ bool operator ()(const TQueueItem& left, const TQueueItem& right) const {
+ return left->Record.GetCookie() > right->Record.GetCookie();
+ }
+ };
+
+ enum {
+ EvProcessDelayedEvent = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+ struct TEvProcessDelayedEvent : TEventLocal<TEvProcessDelayedEvent, EvProcessDelayedEvent> {
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> Event;
+ TEvProcessDelayedEvent(std::unique_ptr<TEvBlobStorage::TEvVGetResult> event)
+ : Event(std::move(event))
+ {}
+ };
+
using TResultQueue = TPriorityQueue<TQueueItem, TVector<TQueueItem>, TCompare>;
-
- std::shared_ptr<TReplCtx> ReplCtx;
+
+ std::shared_ptr<TReplCtx> ReplCtx;
const TBlobStorageGroupType GType;
- TActorId Recipient;
- TTrackableVector<TVDiskProxy::TScheduledBlob> Ids;
- TVDiskID VDiskId;
+ TActorId Recipient;
+ TTrackableVector<TVDiskProxy::TScheduledBlob> Ids;
+ TVDiskID VDiskId;
TActorId ServiceId;
TProxyStat Stat;
- ui32 SendIdx;
- ui32 CurPosIdx;
- ui32 RequestsInFlight;
- const ui32 MaxRequestsInFlight;
- TNextPortion Prefetch;
- ui32 PrefetchDataSize;
- bool RequestFromVDiskProxyPending;
- bool Finished;
- bool HasTransientErrors = false;
- ui64 NextSendCookie;
- ui64 NextReceiveCookie;
- TResultQueue ResultQueue;
-
- TQueue<std::unique_ptr<TEvBlobStorage::TEvVGet>> SchedulerRequestQ;
+ ui32 SendIdx;
+ ui32 CurPosIdx;
+ ui32 RequestsInFlight;
+ const ui32 MaxRequestsInFlight;
+ TNextPortion Prefetch;
+ ui32 PrefetchDataSize;
+ bool RequestFromVDiskProxyPending;
+ bool Finished;
+ bool HasTransientErrors = false;
+ ui64 NextSendCookie;
+ ui64 NextReceiveCookie;
+ TResultQueue ResultQueue;
+
+ TQueue<std::unique_ptr<TEvBlobStorage::TEvVGet>> SchedulerRequestQ;
THashMap<ui64, TReplMemTokenId> RequestTokens;
-
+
friend class TActorBootstrapped<TVDiskProxyActor>;
- void Bootstrap(const TActorId& parentId) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR20, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Bootstrap"));
-
- // remember parent actor id
- Recipient = parentId;
-
- // ensure we have LogoBlobs to fetch
+ void Bootstrap(const TActorId& parentId) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR20, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Bootstrap"));
+
+ // remember parent actor id
+ Recipient = parentId;
+
+ // ensure we have LogoBlobs to fetch
Y_VERIFY(!Ids.empty());
-
- // send initial request
+
+ // send initial request
Become(&TThis::StateFunc);
- ProcessPendingRequests();
+ ProcessPendingRequests();
}
- void SendRequest() {
- // query timestamp
- TInstant timestamp = TAppData::TimeProvider->Now();
-
- // create new VGet request and fill in basic parameters
- TInstant deadline = ReplCtx->VDiskCfg->ReplRequestTimeout.ToDeadLine(timestamp);
- const ui64 getCookie = NextSendCookie++;
- auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, deadline,
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None,
- getCookie);
-
- ui64 maxResponseSize = ReplCtx->VDiskCfg->ReplMaxResponseSize;
- if (const auto& quoter = ReplCtx->VCtx->ReplNodeRequestQuoter) {
- maxResponseSize = Min(maxResponseSize, quoter->GetMaxPacketSize());
- }
-
+ void SendRequest() {
+ // query timestamp
+ TInstant timestamp = TAppData::TimeProvider->Now();
+
+ // create new VGet request and fill in basic parameters
+ TInstant deadline = ReplCtx->VDiskCfg->ReplRequestTimeout.ToDeadLine(timestamp);
+ const ui64 getCookie = NextSendCookie++;
+ auto req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, deadline,
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, TEvBlobStorage::TEvVGet::EFlags::None,
+ getCookie);
+
+ ui64 maxResponseSize = ReplCtx->VDiskCfg->ReplMaxResponseSize;
+ if (const auto& quoter = ReplCtx->VCtx->ReplNodeRequestQuoter) {
+ maxResponseSize = Min(maxResponseSize, quoter->GetMaxPacketSize());
+ }
+
// prepare a set of extreme queries
Y_VERIFY(SendIdx < Ids.size());
- ui32 numIDsRemain = Min<size_t>(Ids.size() - SendIdx, ReplCtx->VDiskCfg->ReplRequestElements);
- ui32 responseSize = 0;
- ui64 bytes = 0;
- for (ui32 i = 0; i < numIDsRemain; ++i) {
- const TLogoBlobID& id = Ids[SendIdx].Id;
- // calculate worst case response data size for this kind of request
+ ui32 numIDsRemain = Min<size_t>(Ids.size() - SendIdx, ReplCtx->VDiskCfg->ReplRequestElements);
+ ui32 responseSize = 0;
+ ui64 bytes = 0;
+ for (ui32 i = 0; i < numIDsRemain; ++i) {
+ const TLogoBlobID& id = Ids[SendIdx].Id;
+ // calculate worst case response data size for this kind of request
responseSize += GType.GetExpectedVGetReplyProtobufSize(id);
- if (responseSize > maxResponseSize && i != 0) {
- // break only if we have sent at least one request
- break;
- }
-
- ui64 cookie = SendIdx;
- req->AddExtremeQuery(id, 0, 0, &cookie);
- bytes += Ids[SendIdx].ExpectedReplySize;
- ++SendIdx;
- }
-
- if (Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplMemToken(bytes), 0, getCookie)) {
- SchedulerRequestQ.push(std::move(req));
- } else {
- Send(ServiceId, req.release());
+ if (responseSize > maxResponseSize && i != 0) {
+ // break only if we have sent at least one request
+ break;
+ }
+
+ ui64 cookie = SendIdx;
+ req->AddExtremeQuery(id, 0, 0, &cookie);
+ bytes += Ids[SendIdx].ExpectedReplySize;
+ ++SendIdx;
}
- ++RequestsInFlight;
-
- // update stats
- Stat.VDiskReqs++;
-
- STLOG(PRI_DEBUG, BS_REPL, BSVR21, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::SendRequest"));
- }
-
- void Handle(TEvReplMemToken::TPtr& ev) {
- // send scheduled item and remember result token for this request
- Y_VERIFY(SchedulerRequestQ);
- auto& item = SchedulerRequestQ.front();
- Send(ServiceId, item.release());
- SchedulerRequestQ.pop();
- RequestTokens.emplace(ev->Cookie, ev->Get()->Token);
+
+ if (Send(MakeBlobStorageReplBrokerID(), new TEvQueryReplMemToken(bytes), 0, getCookie)) {
+ SchedulerRequestQ.push(std::move(req));
+ } else {
+ Send(ServiceId, req.release());
+ }
+ ++RequestsInFlight;
+
+ // update stats
+ Stat.VDiskReqs++;
+
+ STLOG(PRI_DEBUG, BS_REPL, BSVR21, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::SendRequest"));
}
- void Handle(TEvReplProxyNext::TPtr& /*ev*/) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR22, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Handle(TEvReplProxyNext)"));
-
- // increase number of unsatisfied TEvReplProxyNext requests by one more request
+ void Handle(TEvReplMemToken::TPtr& ev) {
+ // send scheduled item and remember result token for this request
+ Y_VERIFY(SchedulerRequestQ);
+ auto& item = SchedulerRequestQ.front();
+ Send(ServiceId, item.release());
+ SchedulerRequestQ.pop();
+ RequestTokens.emplace(ev->Cookie, ev->Get()->Token);
+ }
+
+ void Handle(TEvReplProxyNext::TPtr& /*ev*/) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR22, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Handle(TEvReplProxyNext)"));
+
+ // increase number of unsatisfied TEvReplProxyNext requests by one more request
Y_VERIFY(!RequestFromVDiskProxyPending);
- RequestFromVDiskProxyPending = true;
-
- // try to resolve this request via prefetch
- ProcessPendingRequests();
- }
-
- void ProcessPendingRequests() {
- // if there are unsatisfied requests, try to satisfy them as far as we have data in prefetch
- if (RequestFromVDiskProxyPending && Prefetch.Valid()) {
- Send(Recipient, new TEvReplProxyNextResult(VDiskId, std::move(Prefetch), Stat, HasTransientErrors));
- Prefetch.Reset();
- PrefetchDataSize = 0;
- RequestFromVDiskProxyPending = false;
- if (Finished) {
- Send(ServiceId, new TEvPruneQueue);
- Send(MakeBlobStorageReplBrokerID(), new TEvPruneQueue);
- RequestTokens.clear();
- return PassAway(); // TODO(alexvru): check correctness of invocations
- }
- }
- // send request(s) if prefetch queue is not full
- while (!Finished
- && Prefetch.DataPortion.GetNumItems() < ReplCtx->VDiskCfg->ReplPrefetchElements
- && PrefetchDataSize < ReplCtx->VDiskCfg->ReplPrefetchDataSize
- && SendIdx != Ids.size()
- && RequestsInFlight < MaxRequestsInFlight) {
- SendRequest();
- }
- }
-
- void PutResponseQueueItem(TNextPortion&& portion) {
- // we consider ourself finished when last status is either EOF or ERROR; such response must be ultimately last
+ RequestFromVDiskProxyPending = true;
+
+ // try to resolve this request via prefetch
+ ProcessPendingRequests();
+ }
+
+ void ProcessPendingRequests() {
+ // if there are unsatisfied requests, try to satisfy them as far as we have data in prefetch
+ if (RequestFromVDiskProxyPending && Prefetch.Valid()) {
+ Send(Recipient, new TEvReplProxyNextResult(VDiskId, std::move(Prefetch), Stat, HasTransientErrors));
+ Prefetch.Reset();
+ PrefetchDataSize = 0;
+ RequestFromVDiskProxyPending = false;
+ if (Finished) {
+ Send(ServiceId, new TEvPruneQueue);
+ Send(MakeBlobStorageReplBrokerID(), new TEvPruneQueue);
+ RequestTokens.clear();
+ return PassAway(); // TODO(alexvru): check correctness of invocations
+ }
+ }
+ // send request(s) if prefetch queue is not full
+ while (!Finished
+ && Prefetch.DataPortion.GetNumItems() < ReplCtx->VDiskCfg->ReplPrefetchElements
+ && PrefetchDataSize < ReplCtx->VDiskCfg->ReplPrefetchDataSize
+ && SendIdx != Ids.size()
+ && RequestsInFlight < MaxRequestsInFlight) {
+ SendRequest();
+ }
+ }
+
+ void PutResponseQueueItem(TNextPortion&& portion) {
+ // we consider ourself finished when last status is either EOF or ERROR; such response must be ultimately last
Y_VERIFY(!Finished);
- Finished = portion.Status != TNextPortion::Ok;
-
- // update prefetch cumulative data size
- PrefetchDataSize += portion.DataPortion.GetItemsDataTotalSize();
-
- // update status; the only possible situation is when we change OK status to EOF/ERROR
- Prefetch.Status = portion.Status;
-
- // put new data after existing one
- Prefetch.AppendDataPortion(std::move(portion.DataPortion));
-
- // reply to VDiskProxy and make additional requests to VDisk if required
- ProcessPendingRequests();
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR23, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Handle(TEvVGetResult)"),
- (Msg, ev->Get()->ToString()));
-
- // update actual memory usage
- const ui64 actualBytes = ev->Get()->GetCachedByteSize();
- const auto& record = ev->Get()->Record;
- if (const auto it = RequestTokens.find(record.GetCookie()); it != RequestTokens.end()) {
- Send(MakeBlobStorageReplBrokerID(), new TEvUpdateReplMemToken(it->second, actualBytes));
- }
-
- // limit bandwidth
- const auto& quoter = ReplCtx->VCtx->ReplNodeRequestQuoter;
- const TDuration duration = quoter
- ? quoter->Take(TActivationContext::Now(), actualBytes)
- : TDuration::Zero();
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> event(ev->Release().Release());
- if (duration != TDuration::Zero()) {
- Schedule(duration, new TEvProcessDelayedEvent(std::move(event)));
- } else {
- ProcessScheduledResult(event);
- }
- }
-
- void Handle(TEvProcessDelayedEvent::TPtr ev) {
- ProcessScheduledResult(ev->Get()->Event);
- }
-
- void ProcessScheduledResult(std::unique_ptr<TEvBlobStorage::TEvVGetResult>& ev) {
+ Finished = portion.Status != TNextPortion::Ok;
+
+ // update prefetch cumulative data size
+ PrefetchDataSize += portion.DataPortion.GetItemsDataTotalSize();
+
+ // update status; the only possible situation is when we change OK status to EOF/ERROR
+ Prefetch.Status = portion.Status;
+
+ // put new data after existing one
+ Prefetch.AppendDataPortion(std::move(portion.DataPortion));
+
+ // reply to VDiskProxy and make additional requests to VDisk if required
+ ProcessPendingRequests();
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR23, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TVDiskProxyActor::Handle(TEvVGetResult)"),
+ (Msg, ev->Get()->ToString()));
+
+ // update actual memory usage
+ const ui64 actualBytes = ev->Get()->GetCachedByteSize();
+ const auto& record = ev->Get()->Record;
+ if (const auto it = RequestTokens.find(record.GetCookie()); it != RequestTokens.end()) {
+ Send(MakeBlobStorageReplBrokerID(), new TEvUpdateReplMemToken(it->second, actualBytes));
+ }
+
+ // limit bandwidth
+ const auto& quoter = ReplCtx->VCtx->ReplNodeRequestQuoter;
+ const TDuration duration = quoter
+ ? quoter->Take(TActivationContext::Now(), actualBytes)
+ : TDuration::Zero();
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> event(ev->Release().Release());
+ if (duration != TDuration::Zero()) {
+ Schedule(duration, new TEvProcessDelayedEvent(std::move(event)));
+ } else {
+ ProcessScheduledResult(event);
+ }
+ }
+
+ void Handle(TEvProcessDelayedEvent::TPtr ev) {
+ ProcessScheduledResult(ev->Get()->Event);
+ }
+
+ void ProcessScheduledResult(std::unique_ptr<TEvBlobStorage::TEvVGetResult>& ev) {
ReplCtx->MonGroup.ReplVGetBytesReceived() += ev->GetCachedByteSize();
-
- // if result came out-of-order, then put it into result queue, otherwise process message and any
- // possible pending messages which came out-of-order before this one
- TEvBlobStorage::TEvVGetResult *msg = ev.get();
- if (msg->Record.GetCookie() == NextReceiveCookie) {
- ui64 cookie = NextReceiveCookie;
- ProcessResult(msg);
- ReleaseMemToken(cookie);
- while (!ResultQueue.empty()) {
- const TQueueItem& top = ResultQueue.top();
- if (top->Record.GetCookie() != NextReceiveCookie) {
- break;
- }
- ui64 cookie = NextReceiveCookie;
- ProcessResult(top.get());
- ReleaseMemToken(cookie);
- ResultQueue.pop();
- }
- } else {
- ResultQueue.push(std::move(ev));
- }
- }
-
- void ReleaseMemToken(ui64 cookie) {
- if (RequestTokens) {
- auto it = RequestTokens.find(cookie);
- Y_VERIFY(it != RequestTokens.end());
- Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplMemToken(it->second));
- RequestTokens.erase(it);
- }
- }
-
- void ProcessResult(TEvBlobStorage::TEvVGetResult *msg) {
- const ui64 cookie = msg->Record.GetCookie();
- Y_VERIFY(cookie == NextReceiveCookie);
- ++NextReceiveCookie;
-
+
+ // if result came out-of-order, then put it into result queue, otherwise process message and any
+ // possible pending messages which came out-of-order before this one
+ TEvBlobStorage::TEvVGetResult *msg = ev.get();
+ if (msg->Record.GetCookie() == NextReceiveCookie) {
+ ui64 cookie = NextReceiveCookie;
+ ProcessResult(msg);
+ ReleaseMemToken(cookie);
+ while (!ResultQueue.empty()) {
+ const TQueueItem& top = ResultQueue.top();
+ if (top->Record.GetCookie() != NextReceiveCookie) {
+ break;
+ }
+ ui64 cookie = NextReceiveCookie;
+ ProcessResult(top.get());
+ ReleaseMemToken(cookie);
+ ResultQueue.pop();
+ }
+ } else {
+ ResultQueue.push(std::move(ev));
+ }
+ }
+
+ void ReleaseMemToken(ui64 cookie) {
+ if (RequestTokens) {
+ auto it = RequestTokens.find(cookie);
+ Y_VERIFY(it != RequestTokens.end());
+ Send(MakeBlobStorageReplBrokerID(), new TEvReleaseReplMemToken(it->second));
+ RequestTokens.erase(it);
+ }
+ }
+
+ void ProcessResult(TEvBlobStorage::TEvVGetResult *msg) {
+ const ui64 cookie = msg->Record.GetCookie();
+ Y_VERIFY(cookie == NextReceiveCookie);
+ ++NextReceiveCookie;
+
Y_VERIFY(RequestsInFlight > 0);
- --RequestsInFlight;
-
- // ignore any further results if already finished
- if (Finished) {
- return;
- }
-
- // process VGetResult status
+ --RequestsInFlight;
+
+ // ignore any further results if already finished
+ if (Finished) {
+ return;
+ }
+
+ // process VGetResult status
TNextPortion portion(TNextPortion::Error, TMemoryConsumer(ReplCtx->VCtx->Replication));
- const NKikimrBlobStorage::TEvVGetResult &rec = msg->Record;
+ const NKikimrBlobStorage::TEvVGetResult &rec = msg->Record;
switch (rec.GetStatus()) {
case NKikimrProto::OK:
- portion.Status = TNextPortion::Ok;
- ++Stat.VDiskRespOK;
- break;
- case NKikimrProto::RACE:
- ++Stat.VDiskRespRACE;
- HasTransientErrors = true;
- break;
- case NKikimrProto::ERROR:
- case NKikimrProto::NOTREADY:
- ++Stat.VDiskRespERROR;
- HasTransientErrors = true;
- break;
- case NKikimrProto::DEADLINE:
- ++Stat.VDiskRespDEADLINE;
- break;
- case NKikimrProto::TRYLATER:
- case NKikimrProto::TRYLATER_TIME:
- case NKikimrProto::TRYLATER_SIZE:
+ portion.Status = TNextPortion::Ok;
+ ++Stat.VDiskRespOK;
+ break;
+ case NKikimrProto::RACE:
+ ++Stat.VDiskRespRACE;
+ HasTransientErrors = true;
+ break;
+ case NKikimrProto::ERROR:
+ case NKikimrProto::NOTREADY:
+ ++Stat.VDiskRespERROR;
+ HasTransientErrors = true;
+ break;
+ case NKikimrProto::DEADLINE:
+ ++Stat.VDiskRespDEADLINE;
+ break;
+ case NKikimrProto::TRYLATER:
+ case NKikimrProto::TRYLATER_TIME:
+ case NKikimrProto::TRYLATER_SIZE:
Y_FAIL("unexpected Status# %s from BS_QUEUE", EReplyStatus_Name(rec.GetStatus()).data());
default:
- ++Stat.VDiskRespOther;
- STLOG(PRI_DEBUG, BS_REPL, BSVR24, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
- "TVDiskProxyActor::Handle(TEvVGetResult)"), (Status, rec.GetStatus()));
- break;
+ ++Stat.VDiskRespOther;
+ STLOG(PRI_DEBUG, BS_REPL, BSVR24, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
+ "TVDiskProxyActor::Handle(TEvVGetResult)"), (Status, rec.GetStatus()));
+ break;
}
- if (portion.Status != TNextPortion::Ok) {
- STLOG(PRI_DEBUG, BS_REPL, BSVR25, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "EvVGet failed"),
- (Status, rec.GetStatus()));
- PutResponseQueueItem(std::move(portion));
- } else {
- // handle Ok status
- ui32 size = rec.GetResult().size();
- for (ui32 i = 0; i < size; i++) {
- const NKikimrBlobStorage::TQueryResult &q = rec.GetResult(i);
- ui64 cookie = q.GetCookie();
+ if (portion.Status != TNextPortion::Ok) {
+ STLOG(PRI_DEBUG, BS_REPL, BSVR25, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "EvVGet failed"),
+ (Status, rec.GetStatus()));
+ PutResponseQueueItem(std::move(portion));
+ } else {
+ // handle Ok status
+ ui32 size = rec.GetResult().size();
+ for (ui32 i = 0; i < size; i++) {
+ const NKikimrBlobStorage::TQueryResult &q = rec.GetResult(i);
+ ui64 cookie = q.GetCookie();
Y_VERIFY(cookie == CurPosIdx || (CurPosIdx && cookie == CurPosIdx - 1),
- "i# %" PRIu32 " cookie# %" PRIu64 " CurPosIdx %" PRIu32,
- i, cookie, CurPosIdx);
+ "i# %" PRIu32 " cookie# %" PRIu64 " CurPosIdx %" PRIu32,
+ i, cookie, CurPosIdx);
- // ensure we received correctly ordered LogoBlob ID
+ // ensure we received correctly ordered LogoBlob ID
const TLogoBlobID id = LogoBlobIDFromLogoBlobID(q.GetBlobID());
- const TLogoBlobID genId = Ids[cookie].Id.PartId() ? id : TLogoBlobID(id, 0);
- Y_VERIFY(genId == Ids[cookie].Id);
- if (CurPosIdx == cookie)
- ++CurPosIdx;
+ const TLogoBlobID genId = Ids[cookie].Id.PartId() ? id : TLogoBlobID(id, 0);
+ Y_VERIFY(genId == Ids[cookie].Id);
+ if (CurPosIdx == cookie)
+ ++CurPosIdx;
- if (q.GetStatus() == NKikimrProto::OK) {
+ if (q.GetStatus() == NKikimrProto::OK) {
TString buffer = q.GetBuffer();
- if (buffer.size() != GType.PartSize(id)) {
+ if (buffer.size() != GType.PartSize(id)) {
TString message = VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
"Received incorrect data BlobId# %s Buffer.size# %zu;"
" VDISK CAN NOT REPLICATE A BLOB BECAUSE HAS FOUND INCONSISTENCY IN BLOB SIZE",
- id.ToString().data(), buffer.size());
- STLOG(PRI_CRIT, BS_REPL, BSVR26, message, (BlobId, id), (BufferSize, buffer.size()));
+ id.ToString().data(), buffer.size());
+ STLOG(PRI_CRIT, BS_REPL, BSVR26, message, (BlobId, id), (BufferSize, buffer.size()));
Y_VERIFY_DEBUG(false, "%s", message.data());
-
- // count this blob as erroneous one
- portion.DataPortion.AddError(id, NKikimrProto::ERROR);
- } else {
- Stat.LogoBlobGotIt++;
- Stat.LogoBlobDataSize += buffer.size();
- portion.DataPortion.Add(id, std::move(buffer));
- }
+
+ // count this blob as erroneous one
+ portion.DataPortion.AddError(id, NKikimrProto::ERROR);
+ } else {
+ Stat.LogoBlobGotIt++;
+ Stat.LogoBlobDataSize += buffer.size();
+ portion.DataPortion.Add(id, std::move(buffer));
+ }
} else {
- portion.DataPortion.AddError(id, q.GetStatus());
- if (q.GetStatus() == NKikimrProto::OVERRUN) { // FIXME: implement overrun in query exec code
- Stat.OverflowedMsgs++;
- } else if (q.GetStatus() == NKikimrProto::NODATA) {
- Stat.LogoBlobNoData++;
- } else {
- Stat.LogoBlobNotOK++;
- }
+ portion.DataPortion.AddError(id, q.GetStatus());
+ if (q.GetStatus() == NKikimrProto::OVERRUN) { // FIXME: implement overrun in query exec code
+ Stat.OverflowedMsgs++;
+ } else if (q.GetStatus() == NKikimrProto::NODATA) {
+ Stat.LogoBlobNoData++;
+ } else {
+ Stat.LogoBlobNotOK++;
+ }
}
}
Y_VERIFY(CurPosIdx <= Ids.size());
- if (CurPosIdx == Ids.size())
- portion.Status = TNextPortion::Eof;
-
- // if we haven't received actual data items at all, then send next request
- if (!portion.DataPortion.Valid() && portion.Status == TNextPortion::Ok)
- ProcessPendingRequests();
- else
- PutResponseQueueItem(std::move(portion));
+ if (CurPosIdx == Ids.size())
+ portion.Status = TNextPortion::Eof;
+
+ // if we haven't received actual data items at all, then send next request
+ if (!portion.DataPortion.Valid() && portion.Status == TNextPortion::Ok)
+ ProcessPendingRequests();
+ else
+ PutResponseQueueItem(std::move(portion));
}
}
- STRICT_STFUNC(StateFunc,
- hFunc(TEvReplProxyNext, Handle)
- hFunc(TEvReplMemToken, Handle)
- hFunc(TEvBlobStorage::TEvVGetResult, Handle)
- cFunc(TEvents::TSystem::Poison, PassAway)
- hFunc(TEvProcessDelayedEvent, Handle)
- )
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvReplProxyNext, Handle)
+ hFunc(TEvReplMemToken, Handle)
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle)
+ cFunc(TEvents::TSystem::Poison, PassAway)
+ hFunc(TEvProcessDelayedEvent, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_VDISK_REPL_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_VDISK_REPL_PROXY;
}
TVDiskProxyActor(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
TTrackableVector<TVDiskProxy::TScheduledBlob>&& ids,
const TVDiskID& vdiskId,
const TActorId& serviceId)
: TActorBootstrapped<TVDiskProxyActor>()
, ReplCtx(std::move(replCtx))
, GType(ReplCtx->VCtx->Top->GType)
- , Ids(std::move(ids))
- , VDiskId(vdiskId)
- , ServiceId(serviceId)
+ , Ids(std::move(ids))
+ , VDiskId(vdiskId)
+ , ServiceId(serviceId)
, Stat()
- , SendIdx(0)
+ , SendIdx(0)
, CurPosIdx(0)
- , RequestsInFlight(0)
- , MaxRequestsInFlight(3)
+ , RequestsInFlight(0)
+ , MaxRequestsInFlight(3)
, Prefetch(TNextPortion::Unknown, TMemoryConsumer(ReplCtx->VCtx->Replication))
- , PrefetchDataSize(0)
- , RequestFromVDiskProxyPending(true)
- , Finished(false)
- , NextSendCookie(1)
- , NextReceiveCookie(1)
+ , PrefetchDataSize(0)
+ , RequestFromVDiskProxyPending(true)
+ , Finished(false)
+ , NextSendCookie(1)
+ , NextReceiveCookie(1)
{}
-
- ~TVDiskProxyActor() {}
+
+ ~TVDiskProxyActor() {}
};
- IActor *CreateVDiskProxyActor(std::shared_ptr<TReplCtx> replCtx,
+ IActor *CreateVDiskProxyActor(std::shared_ptr<TReplCtx> replCtx,
TTrackableVector<TVDiskProxy::TScheduledBlob>&& ids,
const TVDiskID& vdiskId,
const TActorId& serviceId) {
- return new TVDiskProxyActor(std::move(replCtx), std::move(ids), vdiskId, serviceId);
+ return new TVDiskProxyActor(std::move(replCtx), std::move(ids), vdiskId, serviceId);
}
} // NRepl
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.h
index e05f54cd079..a5a4c81b431 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replproxy.h
@@ -12,134 +12,134 @@ namespace NKikimr {
// TVDiskProxy -- forward declarations
////////////////////////////////////////////////////////////////////////////
class TVDiskProxy;
- typedef TIntrusivePtr<TVDiskProxy> TVDiskProxyPtr; // TODO(alexvru): maybe std::unique_ptr?
+ typedef TIntrusivePtr<TVDiskProxy> TVDiskProxyPtr; // TODO(alexvru): maybe std::unique_ptr?
////////////////////////////////////////////////////////////////////////////
// Data Structures
////////////////////////////////////////////////////////////////////////////
- // A portion of data elements
- class TDataPortion {
- // Data element received from a vdisk or rebuilt by ourselves
- struct TDataElement {
- TLogoBlobID LogoBlobId;
- NKikimrProto::EReplyStatus Status;
- TTrackableString Data;
-
- TDataElement(TMemoryConsumer&& consumer, const TLogoBlobID& logoBlobId, NKikimrProto::EReplyStatus status,
+ // A portion of data elements
+ class TDataPortion {
+ // Data element received from a vdisk or rebuilt by ourselves
+ struct TDataElement {
+ TLogoBlobID LogoBlobId;
+ NKikimrProto::EReplyStatus Status;
+ TTrackableString Data;
+
+ TDataElement(TMemoryConsumer&& consumer, const TLogoBlobID& logoBlobId, NKikimrProto::EReplyStatus status,
TString&& data)
- : LogoBlobId(logoBlobId)
- , Status(status)
- , Data(std::move(consumer), std::move(data))
- {}
-
- void Reset() {
- Data.clear();
- }
-
- size_t GetDataSize() const {
- return Data.capacity();
- }
- };
-
- public:
- TDataPortion(TMemoryConsumer&& consumer)
- : Consumer(std::move(consumer))
- , Items(TMemoryConsumer(Consumer))
- , FrontPos(0)
- {}
-
- TDataPortion(const TDataPortion& other) = delete;
+ : LogoBlobId(logoBlobId)
+ , Status(status)
+ , Data(std::move(consumer), std::move(data))
+ {}
+
+ void Reset() {
+ Data.clear();
+ }
+
+ size_t GetDataSize() const {
+ return Data.capacity();
+ }
+ };
+
+ public:
+ TDataPortion(TMemoryConsumer&& consumer)
+ : Consumer(std::move(consumer))
+ , Items(TMemoryConsumer(Consumer))
+ , FrontPos(0)
+ {}
+
+ TDataPortion(const TDataPortion& other) = delete;
TDataPortion& operator =(const TDataPortion& other) = delete;
-
- TDataPortion(TDataPortion&& other)
- : Consumer(other.Consumer)
- , Items(std::move(other.Items))
- , FrontPos(other.FrontPos)
- {}
-
- TDataPortion& operator =(TDataPortion&& other) {
- Items = std::move(other.Items);
- FrontPos = other.FrontPos;
- return *this;
- }
-
- void Reset() {
- Items.clear();
- Items.shrink_to_fit();
- FrontPos = 0;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // WRITE PART
- ////////////////////////////////////////////////////////////////////////////////
-
+
+ TDataPortion(TDataPortion&& other)
+ : Consumer(other.Consumer)
+ , Items(std::move(other.Items))
+ , FrontPos(other.FrontPos)
+ {}
+
+ TDataPortion& operator =(TDataPortion&& other) {
+ Items = std::move(other.Items);
+ FrontPos = other.FrontPos;
+ return *this;
+ }
+
+ void Reset() {
+ Items.clear();
+ Items.shrink_to_fit();
+ FrontPos = 0;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // WRITE PART
+ ////////////////////////////////////////////////////////////////////////////////
+
void Add(const TLogoBlobID& logoBlobId, TString&& data) {
Y_VERIFY_DEBUG(FrontPos == 0);
- Items.emplace_back(TMemoryConsumer(Consumer), logoBlobId, NKikimrProto::OK, std::move(data));
- }
-
- void AddError(const TLogoBlobID& logoBlobId, NKikimrProto::EReplyStatus status) {
+ Items.emplace_back(TMemoryConsumer(Consumer), logoBlobId, NKikimrProto::OK, std::move(data));
+ }
+
+ void AddError(const TLogoBlobID& logoBlobId, NKikimrProto::EReplyStatus status) {
Y_VERIFY_DEBUG(FrontPos == 0);
Items.emplace_back(TMemoryConsumer(Consumer), logoBlobId, status, TString());
- }
-
- void Append(TDataPortion&& from) {
+ }
+
+ void Append(TDataPortion&& from) {
Y_VERIFY_DEBUG(FrontPos == 0);
- if (Items.empty()) {
- Items = std::move(from.Items);
- } else {
- Items.insert(Items.end(), from.Items.begin(), from.Items.end());
- from.Items.clear();
- from.Items.shrink_to_fit();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // READ PART
- ////////////////////////////////////////////////////////////////////////////////
-
- size_t GetNumItems() const {
- return Items.size();
- }
-
- size_t GetItemsDataTotalSize() const {
- size_t bytes = 0;
- for (const TDataElement& item : Items) {
- bytes += item.GetDataSize();
- }
- return bytes;
- }
-
- void GetFrontItem(TLogoBlobID *logoBlobId, NKikimrProto::EReplyStatus *status, TTrackableString *data) const {
+ if (Items.empty()) {
+ Items = std::move(from.Items);
+ } else {
+ Items.insert(Items.end(), from.Items.begin(), from.Items.end());
+ from.Items.clear();
+ from.Items.shrink_to_fit();
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // READ PART
+ ////////////////////////////////////////////////////////////////////////////////
+
+ size_t GetNumItems() const {
+ return Items.size();
+ }
+
+ size_t GetItemsDataTotalSize() const {
+ size_t bytes = 0;
+ for (const TDataElement& item : Items) {
+ bytes += item.GetDataSize();
+ }
+ return bytes;
+ }
+
+ void GetFrontItem(TLogoBlobID *logoBlobId, NKikimrProto::EReplyStatus *status, TTrackableString *data) const {
Y_VERIFY_DEBUG(FrontPos < Items.size());
- const TDataElement& elem = Items[FrontPos];
- *logoBlobId = elem.LogoBlobId;
- *status = elem.Status;
- *data = elem.Data;
- }
-
- void GetFrontItem(TLogoBlobID *logoBlobId) const {
+ const TDataElement& elem = Items[FrontPos];
+ *logoBlobId = elem.LogoBlobId;
+ *status = elem.Status;
+ *data = elem.Data;
+ }
+
+ void GetFrontItem(TLogoBlobID *logoBlobId) const {
Y_VERIFY_DEBUG(FrontPos < Items.size());
- *logoBlobId = Items[FrontPos].LogoBlobId;
- }
-
- bool Valid() const {
+ *logoBlobId = Items[FrontPos].LogoBlobId;
+ }
+
+ bool Valid() const {
Y_VERIFY_DEBUG(FrontPos <= Items.size());
- return FrontPos != Items.size();
- }
-
- void Next() {
+ return FrontPos != Items.size();
+ }
+
+ void Next() {
Y_VERIFY_DEBUG(FrontPos < Items.size());
- Items[FrontPos].Reset();
- ++FrontPos;
- }
-
- private:
- TMemoryConsumer Consumer;
- TTrackableVector<TDataElement> Items;
- size_t FrontPos;
+ Items[FrontPos].Reset();
+ ++FrontPos;
+ }
+
+ private:
+ TMemoryConsumer Consumer;
+ TTrackableVector<TDataElement> Items;
+ size_t FrontPos;
};
// A portion of data from proxy
@@ -147,44 +147,44 @@ namespace NKikimr {
enum EStatus {
Ok = 0,
Eof = 1,
- Error = 2,
- Unknown = 3
+ Error = 2,
+ Unknown = 3
};
EStatus Status;
TDataPortion DataPortion;
- TNextPortion(EStatus status, TMemoryConsumer&& consumer)
+ TNextPortion(EStatus status, TMemoryConsumer&& consumer)
: Status(status)
- , DataPortion(std::move(consumer))
+ , DataPortion(std::move(consumer))
{}
-
- // AppendDataPortion(): add some data from another DataPortion to the end of this one
- void AppendDataPortion(TDataPortion&& from) {
- DataPortion.Append(std::move(from));
- }
-
- // Valid(): returns true if this next portion contains any sensitive data that can be
- // sent to VDiskProxy; this case includes ERROR/EOF replies or OK reply with non-empty
- // DataPortion
- bool Valid() const {
- return Status == Eof || Status == Error || (Status == Ok && DataPortion.Valid());
- }
-
- void Reset() {
- Status = Unknown;
- DataPortion.Reset();
- }
+
+ // AppendDataPortion(): add some data from another DataPortion to the end of this one
+ void AppendDataPortion(TDataPortion&& from) {
+ DataPortion.Append(std::move(from));
+ }
+
+ // Valid(): returns true if this next portion contains any sensitive data that can be
+ // sent to VDiskProxy; this case includes ERROR/EOF replies or OK reply with non-empty
+ // DataPortion
+ bool Valid() const {
+ return Status == Eof || Status == Error || (Status == Ok && DataPortion.Valid());
+ }
+
+ void Reset() {
+ Status = Unknown;
+ DataPortion.Reset();
+ }
};
// Per proxy statistics for VDisk, we can sum up it to obtain total statistics for all proxies
struct TProxyStat {
ui64 VDiskReqs = 0;
ui64 VDiskRespOK = 0;
- ui64 VDiskRespRACE = 0;
- ui64 VDiskRespERROR = 0;
- ui64 VDiskRespDEADLINE = 0;
- ui64 VDiskRespOther = 0;
+ ui64 VDiskRespRACE = 0;
+ ui64 VDiskRespERROR = 0;
+ ui64 VDiskRespDEADLINE = 0;
+ ui64 VDiskRespOther = 0;
ui64 LogoBlobGotIt = 0;
ui64 LogoBlobNoData = 0;
ui64 LogoBlobNotOK = 0;
@@ -194,10 +194,10 @@ namespace NKikimr {
TProxyStat &operator +=(const TProxyStat &stat) {
VDiskReqs += stat.VDiskReqs;
VDiskRespOK += stat.VDiskRespOK;
- VDiskRespRACE += stat.VDiskRespRACE;
- VDiskRespERROR += stat.VDiskRespERROR;
- VDiskRespDEADLINE += stat.VDiskRespDEADLINE;
- VDiskRespOther += stat.VDiskRespOther;
+ VDiskRespRACE += stat.VDiskRespRACE;
+ VDiskRespERROR += stat.VDiskRespERROR;
+ VDiskRespDEADLINE += stat.VDiskRespDEADLINE;
+ VDiskRespOther += stat.VDiskRespOther;
LogoBlobGotIt += stat.LogoBlobGotIt;
LogoBlobNoData += stat.LogoBlobNoData;
LogoBlobNotOK += stat.LogoBlobNotOK;
@@ -219,18 +219,18 @@ namespace NKikimr {
};
struct TEvReplProxyNextResult : public TEventLocal<TEvReplProxyNextResult, TEvBlobStorage::EvReplProxyNextResult> {
- TVDiskID VDiskId;
+ TVDiskID VDiskId;
NRepl::TNextPortion Portion;
NRepl::TProxyStat Stat;
- bool HasTransientErrors;
+ bool HasTransientErrors;
- TEvReplProxyNextResult(TVDiskID vdiskId, NRepl::TNextPortion&& portion, const NRepl::TProxyStat &stat,
- bool hasTransientErrors)
- : VDiskId(vdiskId)
- , Portion(std::move(portion))
+ TEvReplProxyNextResult(TVDiskID vdiskId, NRepl::TNextPortion&& portion, const NRepl::TProxyStat &stat,
+ bool hasTransientErrors)
+ : VDiskId(vdiskId)
+ , Portion(std::move(portion))
, Stat(stat)
- , HasTransientErrors(hasTransientErrors)
- {}
+ , HasTransientErrors(hasTransientErrors)
+ {}
};
namespace NRepl {
@@ -240,16 +240,16 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TVDiskProxy : public TThrRefBase {
public:
- struct TScheduledBlob {
- TLogoBlobID Id;
- ui32 ExpectedReplySize;
-
- TScheduledBlob(const TLogoBlobID& id, ui32 expectedReplySize)
- : Id(id)
- , ExpectedReplySize(expectedReplySize)
- {}
- };
-
+ struct TScheduledBlob {
+ TLogoBlobID Id;
+ ui32 ExpectedReplySize;
+
+ TScheduledBlob(const TLogoBlobID& id, ui32 expectedReplySize)
+ : Id(id)
+ , ExpectedReplySize(expectedReplySize)
+ {}
+ };
+
enum EState {
Initial = 0,
RunProxy = 1,
@@ -259,76 +259,76 @@ namespace NKikimr {
};
TVDiskProxy(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
const TVDiskID &vdisk,
const TActorId &serviceID);
-
- TActorId Run(const TActorId& parentId);
- void SendNextRequest();
+
+ TActorId Run(const TActorId& parentId);
+ void SendNextRequest();
void HandleNext(TEvReplProxyNextResult::TPtr &ev);
-
+
private:
void HandlePortion(TNextPortion &portion);
-
+
public:
- void Put(const TLogoBlobID &id, ui32 expectedReplySize) {
+ void Put(const TLogoBlobID &id, ui32 expectedReplySize) {
Y_VERIFY_DEBUG(State == Initial);
- Ids.emplace_back(id, expectedReplySize);
- }
-
- // Next(): advance to next data item
- // Precondition: Valid()
- void Next() {
- DataPortion.Next();
- }
-
- void GetData(TLogoBlobID *logoBlobId, NKikimrProto::EReplyStatus *status, TTrackableString *data) const {
- DataPortion.GetFrontItem(logoBlobId, status, data);
+ Ids.emplace_back(id, expectedReplySize);
}
- TLogoBlobID GenLogoBlobId() const {
- TLogoBlobID logoBlobId;
- DataPortion.GetFrontItem(&logoBlobId);
- return TLogoBlobID(logoBlobId, 0);
- }
-
- // IsEof(): returns true on EOF condition, i.e. when there is no more data exists in buffer and
- // no more data is expected in future
- bool IsEof() const {
+ // Next(): advance to next data item
+ // Precondition: Valid()
+ void Next() {
+ DataPortion.Next();
+ }
+
+ void GetData(TLogoBlobID *logoBlobId, NKikimrProto::EReplyStatus *status, TTrackableString *data) const {
+ DataPortion.GetFrontItem(logoBlobId, status, data);
+ }
+
+ TLogoBlobID GenLogoBlobId() const {
+ TLogoBlobID logoBlobId;
+ DataPortion.GetFrontItem(&logoBlobId);
+ return TLogoBlobID(logoBlobId, 0);
+ }
+
+ // IsEof(): returns true on EOF condition, i.e. when there is no more data exists in buffer and
+ // no more data is expected in future
+ bool IsEof() const {
Y_VERIFY_DEBUG(State == Ok || State == Eof || State == Error);
- return (State == Error || State == Eof) && !DataPortion.Valid();
- }
-
- // Valid(): returns true when there is data in buffer to read using LogoBlobID() / GetData()
- // methods and to advance using Next() method
- bool Valid() const {
- return DataPortion.Valid();
- }
-
- // returns true if there were no transient errors during query execution
- bool NoTransientErrors() const {
- return !HasTransientErrors;
- }
-
- std::shared_ptr<TReplCtx> ReplCtx;
- const TVDiskID VDiskId;
- const TActorId ServiceId;
- TProxyStat Stat;
+ return (State == Error || State == Eof) && !DataPortion.Valid();
+ }
+
+ // Valid(): returns true when there is data in buffer to read using LogoBlobID() / GetData()
+ // methods and to advance using Next() method
+ bool Valid() const {
+ return DataPortion.Valid();
+ }
+
+ // returns true if there were no transient errors during query execution
+ bool NoTransientErrors() const {
+ return !HasTransientErrors;
+ }
+
+ std::shared_ptr<TReplCtx> ReplCtx;
+ const TVDiskID VDiskId;
+ const TActorId ServiceId;
+ TProxyStat Stat;
private:
- TActorId ParentId;
- TActorId ProxyId;
- TTrackableVector<TScheduledBlob> Ids;
- EState State = Initial;
+ TActorId ParentId;
+ TActorId ProxyId;
+ TTrackableVector<TScheduledBlob> Ids;
+ EState State = Initial;
TDataPortion DataPortion;
- bool HasTransientErrors = false;
+ bool HasTransientErrors = false;
public:
struct TPtrGreater {
- bool operator() (const TVDiskProxyPtr &x, const TVDiskProxyPtr &y) const {
+ bool operator() (const TVDiskProxyPtr &x, const TVDiskProxyPtr &y) const {
Y_VERIFY_DEBUG(x->Valid() && y->Valid());
- return x->GenLogoBlobId() > y->GenLogoBlobId();
- }
+ return x->GenLogoBlobId() > y->GenLogoBlobId();
+ }
};
};
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine.h b/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine.h
index 9568165e383..fdbd4e4fadb 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine.h
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine.h
@@ -1,402 +1,402 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_hullreplwritesst.h"
-#include "blobstorage_repl.h"
-
-namespace NKikimr {
-
- namespace NRepl {
-
- enum class ETimeState : ui32 {
- PREPARE_PLAN,
- TOKEN_WAIT,
- PROXY_WAIT,
- MERGE,
- PDISK_OP,
- COMMIT,
- OTHER,
- PHANTOM,
- COUNT
- };
-
- struct TTimeAccount {
- TTimeAccount()
- : CurrentState(ETimeState::COUNT)
- {}
-
- void SetState(ETimeState state) {
- if (CurrentState != state) {
- TInstant timestamp = TAppData::TimeProvider->Now();
- if (CurrentState != ETimeState::COUNT)
- Durations[static_cast<ui32>(CurrentState)] += timestamp - PrevTimestamp;
- CurrentState = state;
- PrevTimestamp = timestamp;
- }
- }
-
+#include "blobstorage_hullreplwritesst.h"
+#include "blobstorage_repl.h"
+
+namespace NKikimr {
+
+ namespace NRepl {
+
+ enum class ETimeState : ui32 {
+ PREPARE_PLAN,
+ TOKEN_WAIT,
+ PROXY_WAIT,
+ MERGE,
+ PDISK_OP,
+ COMMIT,
+ OTHER,
+ PHANTOM,
+ COUNT
+ };
+
+ struct TTimeAccount {
+ TTimeAccount()
+ : CurrentState(ETimeState::COUNT)
+ {}
+
+ void SetState(ETimeState state) {
+ if (CurrentState != state) {
+ TInstant timestamp = TAppData::TimeProvider->Now();
+ if (CurrentState != ETimeState::COUNT)
+ Durations[static_cast<ui32>(CurrentState)] += timestamp - PrevTimestamp;
+ CurrentState = state;
+ PrevTimestamp = timestamp;
+ }
+ }
+
void UpdateInfo(TEvReplFinished::TInfo& replInfo) const {
replInfo.PreparePlanDuration = Durations[static_cast<ui32>(ETimeState::PREPARE_PLAN)];
- replInfo.TokenWaitDuration = Durations[static_cast<ui32>(ETimeState::TOKEN_WAIT)];
+ replInfo.TokenWaitDuration = Durations[static_cast<ui32>(ETimeState::TOKEN_WAIT)];
replInfo.ProxyWaitDuration = Durations[static_cast<ui32>(ETimeState::PROXY_WAIT)];
replInfo.MergeDuration = Durations[static_cast<ui32>(ETimeState::MERGE)];
- replInfo.PDiskDuration = Durations[static_cast<ui32>(ETimeState::PDISK_OP)];
+ replInfo.PDiskDuration = Durations[static_cast<ui32>(ETimeState::PDISK_OP)];
replInfo.CommitDuration = Durations[static_cast<ui32>(ETimeState::COMMIT)];
replInfo.OtherDuration = Durations[static_cast<ui32>(ETimeState::OTHER)];
- replInfo.PhantomDuration = Durations[static_cast<ui32>(ETimeState::PHANTOM)];
- }
-
- private:
- ETimeState CurrentState;
- TInstant PrevTimestamp;
- TDuration Durations[static_cast<ui32>(ETimeState::COUNT)];
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // TRecoveryMachine
- ////////////////////////////////////////////////////////////////////////////
- class TRecoveryMachine {
- public:
- using TRecoveredBlobInfo = TReplSstStreamWriter::TRecoveredBlobInfo;
+ replInfo.PhantomDuration = Durations[static_cast<ui32>(ETimeState::PHANTOM)];
+ }
+
+ private:
+ ETimeState CurrentState;
+ TInstant PrevTimestamp;
+ TDuration Durations[static_cast<ui32>(ETimeState::COUNT)];
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ // TRecoveryMachine
+ ////////////////////////////////////////////////////////////////////////////
+ class TRecoveryMachine {
+ public:
+ using TRecoveredBlobInfo = TReplSstStreamWriter::TRecoveredBlobInfo;
using TRecoveredBlobsQueue = TQueue<TRecoveredBlobInfo>;
-
- struct TPartSet {
- TDataPartSet PartSet;
- ui32 DisksRepliedOK = 0;
- ui32 DisksRepliedNODATA = 0;
- ui32 DisksRepliedNOT_YET = 0;
- ui32 DisksRepliedOther = 0;
-
- TPartSet(TBlobStorageGroupType gtype) {
- PartSet.Parts.resize(gtype.TotalPartCount());
- }
-
- void AddData(ui32 diskIdx, const TLogoBlobID& id, NKikimrProto::EReplyStatus status, TString data) {
- switch (status) {
- case NKikimrProto::OK: {
- const ui8 partIdx = id.PartId() - 1;
- Y_VERIFY(partIdx < PartSet.Parts.size());
- PartSet.FullDataSize = id.BlobSize();
- PartSet.PartsMask |= 1 << partIdx;
- PartSet.Parts[partIdx].ReferenceTo(data);
- DisksRepliedOK |= 1 << diskIdx;
- break;
- }
-
- case NKikimrProto::NODATA:
- DisksRepliedNODATA |= 1 << diskIdx;
- break;
-
- case NKikimrProto::NOT_YET:
- DisksRepliedNOT_YET |= 1 << diskIdx;
- break;
-
- default:
- DisksRepliedOther |= 1 << diskIdx;
- break;
- }
- }
-
- TString ToString() const {
- return TStringBuilder() << "{DisksRepliedOK# " << DisksRepliedOK
- << " DisksRepliedNODATA# " << DisksRepliedNODATA
- << " DisksRepliedNOT_YET# " << DisksRepliedNOT_YET
- << " DisksRepliedOther# " << DisksRepliedOther
- << "}";
- }
- };
-
- public:
+
+ struct TPartSet {
+ TDataPartSet PartSet;
+ ui32 DisksRepliedOK = 0;
+ ui32 DisksRepliedNODATA = 0;
+ ui32 DisksRepliedNOT_YET = 0;
+ ui32 DisksRepliedOther = 0;
+
+ TPartSet(TBlobStorageGroupType gtype) {
+ PartSet.Parts.resize(gtype.TotalPartCount());
+ }
+
+ void AddData(ui32 diskIdx, const TLogoBlobID& id, NKikimrProto::EReplyStatus status, TString data) {
+ switch (status) {
+ case NKikimrProto::OK: {
+ const ui8 partIdx = id.PartId() - 1;
+ Y_VERIFY(partIdx < PartSet.Parts.size());
+ PartSet.FullDataSize = id.BlobSize();
+ PartSet.PartsMask |= 1 << partIdx;
+ PartSet.Parts[partIdx].ReferenceTo(data);
+ DisksRepliedOK |= 1 << diskIdx;
+ break;
+ }
+
+ case NKikimrProto::NODATA:
+ DisksRepliedNODATA |= 1 << diskIdx;
+ break;
+
+ case NKikimrProto::NOT_YET:
+ DisksRepliedNOT_YET |= 1 << diskIdx;
+ break;
+
+ default:
+ DisksRepliedOther |= 1 << diskIdx;
+ break;
+ }
+ }
+
+ TString ToString() const {
+ return TStringBuilder() << "{DisksRepliedOK# " << DisksRepliedOK
+ << " DisksRepliedNODATA# " << DisksRepliedNODATA
+ << " DisksRepliedNOT_YET# " << DisksRepliedNOT_YET
+ << " DisksRepliedOther# " << DisksRepliedOther
+ << "}";
+ }
+ };
+
+ public:
TRecoveryMachine(
- std::shared_ptr<TReplCtx> replCtx,
+ std::shared_ptr<TReplCtx> replCtx,
TEvReplFinished::TInfoPtr replInfo,
TBlobIdQueuePtr unreplicatedBlobsPtr)
: ReplCtx(std::move(replCtx))
, ReplInfo(replInfo)
- , UnreplicatedBlobsPtr(std::move(unreplicatedBlobsPtr))
+ , UnreplicatedBlobsPtr(std::move(unreplicatedBlobsPtr))
, LostVec(TMemoryConsumer(ReplCtx->VCtx->Replication))
- , Arena(&TRopeArenaBackend::Allocate)
- {}
-
- enum class EPhantomState {
- Unknown,
- Check,
- Phantom,
- NonPhantom,
- };
-
- void Recover(const TLogoBlobID& id, TPartSet& partSet, TRecoveredBlobsQueue& rbq, EPhantomState& phantom) {
- Y_VERIFY(!id.PartId());
- Y_VERIFY(PhantomCheckPending ? *PhantomCheckPending == id : (!LastRecoveredId || *LastRecoveredId < id));
- LastRecoveredId = id;
-
- RecoverMetadata(id, rbq);
-
- while (!LostVec.empty() && LostVec.front().Id < id) {
- SkipItem(LostVec.front());
- LostVec.pop_front();
- }
-
- if (LostVec.empty() || LostVec.front().Id != id) {
- STLOG(PRI_ERROR, BS_REPL, BSVR27, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "blob not in LostVec"),
- (BlobId, id));
- return;
- }
-
- const TLost& lost = LostVec.front();
- Y_VERIFY(lost.Id == id);
-
- const TBlobStorageGroupType groupType = ReplCtx->VCtx->Top->GType;
-
- const NMatrix::TVectorType parts = lost.PartsToRecover;
-
- ui32 partsSize = 0;
- bool hasExactParts = false;
- bool needToRestore = false;
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- if (partSet.PartSet.PartsMask & (1 << i)) {
- hasExactParts = true;
- } else {
- needToRestore = true;
- }
- }
-
- bool countAsRecovered = false;
-
- Y_VERIFY_DEBUG((partSet.PartSet.PartsMask >> groupType.TotalPartCount()) == 0);
- const ui32 presentParts = PopCount(partSet.PartSet.PartsMask);
- bool canRestore = presentParts >= groupType.MinimalRestorablePartCount();
-
- if (phantom == EPhantomState::Unknown && lost.PossiblePhantom && needToRestore && !canRestore) {
- phantom = EPhantomState::Check;
- ++ReplInfo->DataRecoveryPhantomCheck;
- PhantomCheckPending = id;
- return; // reentry expected with the check result
- } else {
- PhantomCheckPending.reset();
- }
-
- // first of all, count present parts and recover only if there are enough of these parts
- if ((!canRestore && needToRestore && !hasExactParts) || phantom == EPhantomState::Phantom) {
+ , Arena(&TRopeArenaBackend::Allocate)
+ {}
+
+ enum class EPhantomState {
+ Unknown,
+ Check,
+ Phantom,
+ NonPhantom,
+ };
+
+ void Recover(const TLogoBlobID& id, TPartSet& partSet, TRecoveredBlobsQueue& rbq, EPhantomState& phantom) {
+ Y_VERIFY(!id.PartId());
+ Y_VERIFY(PhantomCheckPending ? *PhantomCheckPending == id : (!LastRecoveredId || *LastRecoveredId < id));
+ LastRecoveredId = id;
+
+ RecoverMetadata(id, rbq);
+
+ while (!LostVec.empty() && LostVec.front().Id < id) {
+ SkipItem(LostVec.front());
+ LostVec.pop_front();
+ }
+
+ if (LostVec.empty() || LostVec.front().Id != id) {
+ STLOG(PRI_ERROR, BS_REPL, BSVR27, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "blob not in LostVec"),
+ (BlobId, id));
+ return;
+ }
+
+ const TLost& lost = LostVec.front();
+ Y_VERIFY(lost.Id == id);
+
+ const TBlobStorageGroupType groupType = ReplCtx->VCtx->Top->GType;
+
+ const NMatrix::TVectorType parts = lost.PartsToRecover;
+
+ ui32 partsSize = 0;
+ bool hasExactParts = false;
+ bool needToRestore = false;
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ if (partSet.PartSet.PartsMask & (1 << i)) {
+ hasExactParts = true;
+ } else {
+ needToRestore = true;
+ }
+ }
+
+ bool countAsRecovered = false;
+
+ Y_VERIFY_DEBUG((partSet.PartSet.PartsMask >> groupType.TotalPartCount()) == 0);
+ const ui32 presentParts = PopCount(partSet.PartSet.PartsMask);
+ bool canRestore = presentParts >= groupType.MinimalRestorablePartCount();
+
+ if (phantom == EPhantomState::Unknown && lost.PossiblePhantom && needToRestore && !canRestore) {
+ phantom = EPhantomState::Check;
+ ++ReplInfo->DataRecoveryPhantomCheck;
+ PhantomCheckPending = id;
+ return; // reentry expected with the check result
+ } else {
+ PhantomCheckPending.reset();
+ }
+
+ // first of all, count present parts and recover only if there are enough of these parts
+ if ((!canRestore && needToRestore && !hasExactParts) || phantom == EPhantomState::Phantom) {
ReplInfo->DataRecoveryNoParts++;
- ReplInfo->PartsMissing += parts.CountBits();
- STLOG(PRI_INFO, BS_REPL, BSVR28, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "not enough data parts to recover"),
- (BlobId, id), (NumPresentParts, presentParts), (MinParts, groupType.DataParts()),
- (PartSet, partSet.ToString()), (IsPhantom, phantom == EPhantomState::Phantom),
- (IsNonPhantom, phantom == EPhantomState::NonPhantom), (PossiblePhantom, lost.PossiblePhantom),
- (Ingress, lost.Ingress.ToString(ReplCtx->VCtx->Top.get(), ReplCtx->VCtx->ShortSelfVDisk, id)));
- ++(phantom == EPhantomState::Phantom
- ? ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs()
- : ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs());
-
- if (phantom == EPhantomState::Phantom) {
+ ReplInfo->PartsMissing += parts.CountBits();
+ STLOG(PRI_INFO, BS_REPL, BSVR28, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "not enough data parts to recover"),
+ (BlobId, id), (NumPresentParts, presentParts), (MinParts, groupType.DataParts()),
+ (PartSet, partSet.ToString()), (IsPhantom, phantom == EPhantomState::Phantom),
+ (IsNonPhantom, phantom == EPhantomState::NonPhantom), (PossiblePhantom, lost.PossiblePhantom),
+ (Ingress, lost.Ingress.ToString(ReplCtx->VCtx->Top.get(), ReplCtx->VCtx->ShortSelfVDisk, id)));
+ ++(phantom == EPhantomState::Phantom
+ ? ReplCtx->MonGroup.ReplCurrentNumUnrecoveredPhantomBlobs()
+ : ReplCtx->MonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs());
+
+ if (phantom == EPhantomState::Phantom) {
++ReplCtx->MonGroup.ReplCurrentPhantoms();
-
- // count phantoms as replicated blobs
- countAsRecovered = true;
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- partsSize += groupType.PartSize(TLogoBlobID(id, i + 1));
- }
- } else {
- UnreplicatedBlobsPtr->push(id);
- }
- } else {
- // recover
- try {
- Y_VERIFY(partSet.PartSet.FullDataSize == id.BlobSize());
-
- // PartSet contains some data, other data will be restored and written in the same PartSet
+
+ // count phantoms as replicated blobs
+ countAsRecovered = true;
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ partsSize += groupType.PartSize(TLogoBlobID(id, i + 1));
+ }
+ } else {
+ UnreplicatedBlobsPtr->push(id);
+ }
+ } else {
+ // recover
+ try {
+ Y_VERIFY(partSet.PartSet.FullDataSize == id.BlobSize());
+
+ // PartSet contains some data, other data will be restored and written in the same PartSet
TString recoveredData;
- const ui32 incomingMask = partSet.PartSet.PartsMask;
- if (canRestore && needToRestore) {
- groupType.RestoreData((TErasureType::ECrcMode)id.CrcMode(), partSet.PartSet, recoveredData,
- true, false, true);
- partSet.PartSet.PartsMask = (1 << groupType.TotalPartCount()) - 1;
- }
-
- ui32 numSmallParts = 0, numMissingParts = 0, numHuge = 0;
- std::array<TRope, 8> partData; // part data for small blobs
- NMatrix::TVectorType small(0, parts.GetSize());
-
- for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
- if (~partSet.PartSet.PartsMask & (1 << i)) {
- ++numMissingParts; // ignore this missing part
- continue;
- }
- if (incomingMask & (1 << i)) {
- ++ReplInfo->PartsExact;
- } else {
- ++ReplInfo->PartsRestored;
- }
- const TLogoBlobID partId(id, i + 1);
- const ui32 partSize = groupType.PartSize(partId);
- Y_VERIFY(partSize); // no metadata here
- partsSize += partSize;
- TRope data(partSet.PartSet.Parts[i].OwnedString); // TODO(alexvru): employ rope in TDataPartSet
- Y_VERIFY(data.GetSize() == partSize);
- if (ReplCtx->HugeBlobCtx->IsHugeBlob(groupType, id)) {
- AddBlobToQueue(partId, TDiskBlob::Create(partSet.PartSet.FullDataSize, i + 1,
- groupType.TotalPartCount(), std::move(data), Arena), {}, true, rbq);
- ++numHuge;
- } else {
- partData[numSmallParts++] = std::move(data);
- small.Set(i);
- }
- }
-
- if (numMissingParts) {
- // this blob is not fully replicated yet
- UnreplicatedBlobsPtr->push(id);
- }
-
- if (numSmallParts) {
- // fill in disk blob buffer
- AddBlobToQueue(id, TDiskBlob::CreateFromDistinctParts(&partData[0], &partData[numSmallParts],
- small, partSet.PartSet.FullDataSize, Arena), small, false, rbq);
- }
-
- ReplInfo->LogoBlobsRecovered += numSmallParts;
- ReplInfo->HugeLogoBlobsRecovered += numHuge;
- ReplInfo->BytesRecovered += partsSize;
- ReplInfo->PartsMissing += numMissingParts;
-
- // count recovered parts
- countAsRecovered = true;
-
+ const ui32 incomingMask = partSet.PartSet.PartsMask;
+ if (canRestore && needToRestore) {
+ groupType.RestoreData((TErasureType::ECrcMode)id.CrcMode(), partSet.PartSet, recoveredData,
+ true, false, true);
+ partSet.PartSet.PartsMask = (1 << groupType.TotalPartCount()) - 1;
+ }
+
+ ui32 numSmallParts = 0, numMissingParts = 0, numHuge = 0;
+ std::array<TRope, 8> partData; // part data for small blobs
+ NMatrix::TVectorType small(0, parts.GetSize());
+
+ for (ui8 i = parts.FirstPosition(); i != parts.GetSize(); i = parts.NextPosition(i)) {
+ if (~partSet.PartSet.PartsMask & (1 << i)) {
+ ++numMissingParts; // ignore this missing part
+ continue;
+ }
+ if (incomingMask & (1 << i)) {
+ ++ReplInfo->PartsExact;
+ } else {
+ ++ReplInfo->PartsRestored;
+ }
+ const TLogoBlobID partId(id, i + 1);
+ const ui32 partSize = groupType.PartSize(partId);
+ Y_VERIFY(partSize); // no metadata here
+ partsSize += partSize;
+ TRope data(partSet.PartSet.Parts[i].OwnedString); // TODO(alexvru): employ rope in TDataPartSet
+ Y_VERIFY(data.GetSize() == partSize);
+ if (ReplCtx->HugeBlobCtx->IsHugeBlob(groupType, id)) {
+ AddBlobToQueue(partId, TDiskBlob::Create(partSet.PartSet.FullDataSize, i + 1,
+ groupType.TotalPartCount(), std::move(data), Arena), {}, true, rbq);
+ ++numHuge;
+ } else {
+ partData[numSmallParts++] = std::move(data);
+ small.Set(i);
+ }
+ }
+
+ if (numMissingParts) {
+ // this blob is not fully replicated yet
+ UnreplicatedBlobsPtr->push(id);
+ }
+
+ if (numSmallParts) {
+ // fill in disk blob buffer
+ AddBlobToQueue(id, TDiskBlob::CreateFromDistinctParts(&partData[0], &partData[numSmallParts],
+ small, partSet.PartSet.FullDataSize, Arena), small, false, rbq);
+ }
+
+ ReplInfo->LogoBlobsRecovered += numSmallParts;
+ ReplInfo->HugeLogoBlobsRecovered += numHuge;
+ ReplInfo->BytesRecovered += partsSize;
+ ReplInfo->PartsMissing += numMissingParts;
+
+ // count recovered parts
+ countAsRecovered = true;
+
ReplInfo->DataRecoverySuccess++;
- } catch (const std::exception& ex) {
+ } catch (const std::exception& ex) {
++ReplCtx->MonGroup.ReplRecoveryGroupTypeErrors();
- STLOG(PRI_ERROR, BS_REPL, BSVR29, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "recovery exception"),
- (BlobId, id), (Error, TString(ex.what())));
+ STLOG(PRI_ERROR, BS_REPL, BSVR29, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "recovery exception"),
+ (BlobId, id), (Error, TString(ex.what())));
ReplInfo->DataRecoveryFailure++;
- UnreplicatedBlobsPtr->push(id);
- }
- }
-
- if (countAsRecovered) {
- ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes() -= partsSize;
- ReplCtx->MonGroup.ReplCurrentUnreplicatedParts() -= parts.CountBits();
- }
-
- LostVec.pop_front();
- }
-
- // finish work
- void Finish(TRecoveredBlobsQueue& rbq) {
- RecoverMetadata(TLogoBlobID(Max<ui64>(), Max<ui64>(), Max<ui64>()), rbq);
- for (auto&& item : LostVec) {
- SkipItem(item);
- }
- LostVec.clear();
- }
-
- // add next task during preparation phase
+ UnreplicatedBlobsPtr->push(id);
+ }
+ }
+
+ if (countAsRecovered) {
+ ReplCtx->MonGroup.ReplCurrentUnreplicatedBytes() -= partsSize;
+ ReplCtx->MonGroup.ReplCurrentUnreplicatedParts() -= parts.CountBits();
+ }
+
+ LostVec.pop_front();
+ }
+
+ // finish work
+ void Finish(TRecoveredBlobsQueue& rbq) {
+ RecoverMetadata(TLogoBlobID(Max<ui64>(), Max<ui64>(), Max<ui64>()), rbq);
+ for (auto&& item : LostVec) {
+ SkipItem(item);
+ }
+ LostVec.clear();
+ }
+
+ // add next task during preparation phase
void AddTask(const TLogoBlobID &id, const NMatrix::TVectorType &partsToRecover, bool possiblePhantom,
- TIngress ingress) {
- Y_VERIFY(!id.PartId());
- Y_VERIFY(LostVec.empty() || LostVec.back().Id < id);
- LostVec.push_back(TLost(id, partsToRecover, possiblePhantom, ingress));
- }
-
- void AddMetadataPart(const TLogoBlobID& id) {
- MetadataParts.push_back(id);
- }
-
- bool FullOfTasks() const {
- return LostVec.size() >= ReplCtx->VDiskCfg->ReplMaxLostVecSize;
- }
-
- bool NoTasks() const {
- return LostVec.empty() && MetadataParts.empty();
- }
-
- void ClearPossiblePhantom() {
- for (TLost& item : LostVec) {
- item.PossiblePhantom = false;
- }
- }
-
- template<typename TCallback>
- void ForEach(TCallback&& callback) {
- for (const TLost& item : LostVec) {
- callback(item.Id, item.PartsToRecover, item.Ingress);
- }
- }
-
- private:
- // structure for a lost part
- struct TLost {
- const TLogoBlobID Id;
+ TIngress ingress) {
+ Y_VERIFY(!id.PartId());
+ Y_VERIFY(LostVec.empty() || LostVec.back().Id < id);
+ LostVec.push_back(TLost(id, partsToRecover, possiblePhantom, ingress));
+ }
+
+ void AddMetadataPart(const TLogoBlobID& id) {
+ MetadataParts.push_back(id);
+ }
+
+ bool FullOfTasks() const {
+ return LostVec.size() >= ReplCtx->VDiskCfg->ReplMaxLostVecSize;
+ }
+
+ bool NoTasks() const {
+ return LostVec.empty() && MetadataParts.empty();
+ }
+
+ void ClearPossiblePhantom() {
+ for (TLost& item : LostVec) {
+ item.PossiblePhantom = false;
+ }
+ }
+
+ template<typename TCallback>
+ void ForEach(TCallback&& callback) {
+ for (const TLost& item : LostVec) {
+ callback(item.Id, item.PartsToRecover, item.Ingress);
+ }
+ }
+
+ private:
+ // structure for a lost part
+ struct TLost {
+ const TLogoBlobID Id;
const NMatrix::TVectorType PartsToRecover;
- bool PossiblePhantom;
- const TIngress Ingress;
-
+ bool PossiblePhantom;
+ const TIngress Ingress;
+
TLost(const TLogoBlobID &id, const NMatrix::TVectorType &partsToRecover, const bool possiblePhantom,
- TIngress ingress)
- : Id(id)
- , PartsToRecover(partsToRecover)
- , PossiblePhantom(possiblePhantom)
- , Ingress(ingress)
- {}
- };
-
- // vector of lost parts, we are goind to recover them during this job
- typedef TTrackableDeque<TLost> TLostVec;
-
- std::shared_ptr<TReplCtx> ReplCtx;
+ TIngress ingress)
+ : Id(id)
+ , PartsToRecover(partsToRecover)
+ , PossiblePhantom(possiblePhantom)
+ , Ingress(ingress)
+ {}
+ };
+
+ // vector of lost parts, we are goind to recover them during this job
+ typedef TTrackableDeque<TLost> TLostVec;
+
+ std::shared_ptr<TReplCtx> ReplCtx;
TEvReplFinished::TInfoPtr ReplInfo;
- TBlobIdQueuePtr UnreplicatedBlobsPtr;
- TLostVec LostVec;
- TDeque<TLogoBlobID> MetadataParts;
- TRopeArena Arena;
- std::optional<TLogoBlobID> LastRecoveredId;
- std::optional<TLogoBlobID> PhantomCheckPending;
-
- void AddBlobToQueue(const TLogoBlobID& id, TRope blob, NMatrix::TVectorType parts, bool isHugeBlob,
- TRecoveredBlobsQueue& rbq) {
- if (!rbq.empty() && rbq.back().Id == id && !isHugeBlob) {
- auto& last = rbq.back();
- TDiskBlobMerger merger;
- merger.Add(TDiskBlob(&last.Data, last.LocalParts, ReplCtx->VCtx->Top->GType, id));
- merger.Add(TDiskBlob(&blob, parts, ReplCtx->VCtx->Top->GType, id));
- last.LocalParts = merger.GetDiskBlob().GetParts();
- last.Data = merger.CreateDiskBlob(Arena);
- } else {
- rbq.emplace(id, std::move(blob), isHugeBlob, parts);
- }
- }
-
- void RecoverMetadata(const TLogoBlobID& id, TRecoveredBlobsQueue& rbq) {
- while (!MetadataParts.empty() && MetadataParts.front().FullID() <= id) {
- const TLogoBlobID id = MetadataParts.front();
- const bool isHugeBlob = ReplCtx->HugeBlobCtx->IsHugeBlob(ReplCtx->VCtx->Top->GType, id.FullID());
- MetadataParts.pop_front();
- STLOG(PRI_DEBUG, BS_REPL, BSVR30, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
- "TRecoveryMachine::RecoverMetadata"), (BlobId, id));
- const TBlobStorageGroupType gtype = ReplCtx->VCtx->Top->GType;
- if (isHugeBlob) {
- // huge metadata blob contains ID with designated part id and no data at all (and no parts vector)
- AddBlobToQueue(id, TRope(), {}, true, rbq);
- } else {
- // small metadata blob contains only header without data, but its ID has PartId = 0 and parts
- // vector is filled accordingly
- const NMatrix::TVectorType parts = NMatrix::TVectorType::MakeOneHot(id.PartId() - 1,
- gtype.TotalPartCount());
- AddBlobToQueue(id.FullID(), TDiskBlob::Create(id.BlobSize(), parts, TRope(),
- Arena), parts, isHugeBlob, rbq);
- }
- ++ReplInfo->MetadataBlobs;
- }
- }
-
- void SkipItem(const TLost& item) {
- STLOG(PRI_INFO, BS_REPL, BSVR31, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TRecoveryMachine::SkipItem"),
- (BlobId, item.Id));
- ++ReplInfo->DataRecoverySkip;
- UnreplicatedBlobsPtr->push(item.Id);
- }
- };
-
- } // NRepl
-
-} // NKikimr
+ TBlobIdQueuePtr UnreplicatedBlobsPtr;
+ TLostVec LostVec;
+ TDeque<TLogoBlobID> MetadataParts;
+ TRopeArena Arena;
+ std::optional<TLogoBlobID> LastRecoveredId;
+ std::optional<TLogoBlobID> PhantomCheckPending;
+
+ void AddBlobToQueue(const TLogoBlobID& id, TRope blob, NMatrix::TVectorType parts, bool isHugeBlob,
+ TRecoveredBlobsQueue& rbq) {
+ if (!rbq.empty() && rbq.back().Id == id && !isHugeBlob) {
+ auto& last = rbq.back();
+ TDiskBlobMerger merger;
+ merger.Add(TDiskBlob(&last.Data, last.LocalParts, ReplCtx->VCtx->Top->GType, id));
+ merger.Add(TDiskBlob(&blob, parts, ReplCtx->VCtx->Top->GType, id));
+ last.LocalParts = merger.GetDiskBlob().GetParts();
+ last.Data = merger.CreateDiskBlob(Arena);
+ } else {
+ rbq.emplace(id, std::move(blob), isHugeBlob, parts);
+ }
+ }
+
+ void RecoverMetadata(const TLogoBlobID& id, TRecoveredBlobsQueue& rbq) {
+ while (!MetadataParts.empty() && MetadataParts.front().FullID() <= id) {
+ const TLogoBlobID id = MetadataParts.front();
+ const bool isHugeBlob = ReplCtx->HugeBlobCtx->IsHugeBlob(ReplCtx->VCtx->Top->GType, id.FullID());
+ MetadataParts.pop_front();
+ STLOG(PRI_DEBUG, BS_REPL, BSVR30, VDISKP(ReplCtx->VCtx->VDiskLogPrefix,
+ "TRecoveryMachine::RecoverMetadata"), (BlobId, id));
+ const TBlobStorageGroupType gtype = ReplCtx->VCtx->Top->GType;
+ if (isHugeBlob) {
+ // huge metadata blob contains ID with designated part id and no data at all (and no parts vector)
+ AddBlobToQueue(id, TRope(), {}, true, rbq);
+ } else {
+ // small metadata blob contains only header without data, but its ID has PartId = 0 and parts
+ // vector is filled accordingly
+ const NMatrix::TVectorType parts = NMatrix::TVectorType::MakeOneHot(id.PartId() - 1,
+ gtype.TotalPartCount());
+ AddBlobToQueue(id.FullID(), TDiskBlob::Create(id.BlobSize(), parts, TRope(),
+ Arena), parts, isHugeBlob, rbq);
+ }
+ ++ReplInfo->MetadataBlobs;
+ }
+ }
+
+ void SkipItem(const TLost& item) {
+ STLOG(PRI_INFO, BS_REPL, BSVR31, VDISKP(ReplCtx->VCtx->VDiskLogPrefix, "TRecoveryMachine::SkipItem"),
+ (BlobId, item.Id));
+ ++ReplInfo->DataRecoverySkip;
+ UnreplicatedBlobsPtr->push(item.Id);
+ }
+ };
+
+ } // NRepl
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine_ut.cpp b/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine_ut.cpp
index 3ff7efb53e2..c740a380d11 100644
--- a/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/repl/blobstorage_replrecoverymachine_ut.cpp
@@ -1,58 +1,58 @@
-#include "blobstorage_replrecoverymachine.h"
-
+#include "blobstorage_replrecoverymachine.h"
+
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/fast.h>
-
-namespace NKikimr {
-
+#include <util/random/fast.h>
+
+namespace NKikimr {
+
Y_UNIT_TEST_SUITE(TBlobStorageReplRecoveryMachine) {
-
+
TMap<TLogoBlobID, TVector<TString>> GenerateData(ui32 numBlobs,
ui32 maxLen,
const TIntrusivePtr<TBlobStorageGroupInfo> &info,
const TVector<TVDiskID>& vdisks) {
TMap<TLogoBlobID, TVector<TString>> rv;
- TReallyFastRng32 rng(1);
- ui32 step = 1;
-
- while (numBlobs--) {
- ui32 len = 1 + rng() % maxLen;
+ TReallyFastRng32 rng(1);
+ ui32 step = 1;
+
+ while (numBlobs--) {
+ ui32 len = 1 + rng() % maxLen;
TString data;
- data.reserve(len);
- for (ui32 i = 0; i < len; ++i) {
- data.push_back(rng());
- }
-
- TLogoBlobID id(1, 1, step, 0, len, 0);
- ++step;
-
- TBlobStorageGroupInfo::TVDiskIds varray;
- TBlobStorageGroupInfo::TServiceIds services;
+ data.reserve(len);
+ for (ui32 i = 0; i < len; ++i) {
+ data.push_back(rng());
+ }
+
+ TLogoBlobID id(1, 1, step, 0, len, 0);
+ ++step;
+
+ TBlobStorageGroupInfo::TVDiskIds varray;
+ TBlobStorageGroupInfo::TServiceIds services;
info->PickSubgroup(id.Hash(), &varray, &services);
-
- TDataPartSet parts;
+
+ TDataPartSet parts;
info->Type.SplitData((TErasureType::ECrcMode)id.CrcMode(), data, parts);
-
+
TVector<TString> diskvec(vdisks.size());
-
+
for (ui32 i = 0; i < info->Type.TotalPartCount(); ++i) {
- for (ui32 k = 0; k < vdisks.size(); ++k) {
- if (varray[i] == vdisks[k]) {
+ for (ui32 k = 0; k < vdisks.size(); ++k) {
+ if (varray[i] == vdisks[k]) {
diskvec[k] = parts.Parts[i].OwnedString;
- break;
- }
- }
- }
-
- rv.emplace(id, std::move(diskvec));
- }
-
- return rv;
- }
-
- std::shared_ptr<TReplCtx> CreateReplCtx(
+ break;
+ }
+ }
+ }
+
+ rv.emplace(id, std::move(diskvec));
+ }
+
+ return rv;
+ }
+
+ std::shared_ptr<TReplCtx> CreateReplCtx(
TVector<TVDiskID>& vdisks,
const TIntrusivePtr<TBlobStorageGroupInfo> &info)
{
@@ -64,111 +64,111 @@ namespace NKikimr {
baseInfo.VDiskIdShort = TVDiskIdShort(vdisks[0]);
auto vdiskCfg = MakeIntrusive<TVDiskConfig>(baseInfo);
auto counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
- auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
+ auto vctx = MakeIntrusive<TVDiskContext>(TActorId(), info->PickTopology(), counters, TVDiskID(0, 1, 0, 0, 0),
nullptr, TPDiskCategory::DEVICE_TYPE_UNKNOWN);
- auto hugeBlobCtx = std::make_shared<THugeBlobCtx>(512u << 10u, nullptr);
- auto replCtx = std::make_shared<TReplCtx>(
+ auto hugeBlobCtx = std::make_shared<THugeBlobCtx>(512u << 10u, nullptr);
+ auto replCtx = std::make_shared<TReplCtx>(
vctx,
nullptr, // PDiskCtx
hugeBlobCtx,
- nullptr,
- info,
+ nullptr,
+ info,
TActorId(),
- vdiskCfg,
- std::make_unique<std::atomic_uint64_t>());
+ vdiskCfg,
+ std::make_unique<std::atomic_uint64_t>());
return replCtx;
}
Y_UNIT_TEST(BasicFunctionality) {
- TRopeArena arena(&TRopeArenaBackend::Allocate);
+ TRopeArena arena(&TRopeArenaBackend::Allocate);
TVector<TVDiskID> vdisks;
auto groupInfo = MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block);
auto replCtx = CreateReplCtx(vdisks, groupInfo);
- auto info = MakeIntrusive<TEvReplFinished::TInfo>();
- TBlobIdQueuePtr unreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
+ auto info = MakeIntrusive<TEvReplFinished::TInfo>();
+ TBlobIdQueuePtr unreplicatedBlobsPtr = std::make_shared<TBlobIdQueue>();
NRepl::TRecoveryMachine m(replCtx, info, unreplicatedBlobsPtr);
TMap<TLogoBlobID, TVector<TString>> data = GenerateData(10000, 1024, groupInfo, vdisks);
- for (const auto& pair : data) {
- const TLogoBlobID& id = pair.first;
-
- // make ingress for every disk other than SelfVDisk
- TIngress ingress;
- TBlobStorageGroupInfo::TVDiskIds varray;
- TBlobStorageGroupInfo::TServiceIds services;
+ for (const auto& pair : data) {
+ const TLogoBlobID& id = pair.first;
+
+ // make ingress for every disk other than SelfVDisk
+ TIngress ingress;
+ TBlobStorageGroupInfo::TVDiskIds varray;
+ TBlobStorageGroupInfo::TServiceIds services;
groupInfo->PickSubgroup(id.Hash(), &varray, &services);
for (ui32 i = 0; i < groupInfo->Type.TotalPartCount(); ++i) {
TIngress otherDiskIngress(*TIngress::CreateIngressWithLocal(&groupInfo->GetTopology(),
varray[i],
TLogoBlobID(id, i + 1)));
- ingress.Merge(otherDiskIngress);
- }
+ ingress.Merge(otherDiskIngress);
+ }
ingress = ingress.CopyWithoutLocal(groupInfo->Type);
-
- ui8 partIndex = 0;
+
+ ui8 partIndex = 0;
for (partIndex = 0; partIndex < groupInfo->Type.BlobSubgroupSize(); ++partIndex) {
if (varray[partIndex] == groupInfo->GetVDiskId(replCtx->VCtx->ShortSelfVDisk)) {
- break;
- }
- }
+ break;
+ }
+ }
UNIT_ASSERT(partIndex != groupInfo->Type.BlobSubgroupSize());
if (partIndex >= groupInfo->Type.TotalPartCount()) {
- continue;
- }
-
- auto partsToRecover = ingress.PartsWeMustHaveLocally(&groupInfo->GetTopology(),
- replCtx->VCtx->ShortSelfVDisk, id) - ingress.LocalParts(groupInfo->Type);
- UNIT_ASSERT(!partsToRecover.Empty());
- UNIT_ASSERT(partsToRecover.Get(partIndex));
- m.AddTask(id, partsToRecover, false, ingress);
- }
- for (const auto& pair : data) {
- const TLogoBlobID& id = pair.first;
+ continue;
+ }
+
+ auto partsToRecover = ingress.PartsWeMustHaveLocally(&groupInfo->GetTopology(),
+ replCtx->VCtx->ShortSelfVDisk, id) - ingress.LocalParts(groupInfo->Type);
+ UNIT_ASSERT(!partsToRecover.Empty());
+ UNIT_ASSERT(partsToRecover.Get(partIndex));
+ m.AddTask(id, partsToRecover, false, ingress);
+ }
+ for (const auto& pair : data) {
+ const TLogoBlobID& id = pair.first;
const TVector<TString>& v = pair.second;
- if (v[0].empty()) {
- continue; // nothing to recover on this disk
- }
-
- TBlobStorageGroupInfo::TVDiskIds varray;
- TBlobStorageGroupInfo::TServiceIds services;
+ if (v[0].empty()) {
+ continue; // nothing to recover on this disk
+ }
+
+ TBlobStorageGroupInfo::TVDiskIds varray;
+ TBlobStorageGroupInfo::TServiceIds services;
groupInfo->PickSubgroup(id.Hash(), &varray, &services);
-
- NRepl::TRecoveryMachine::TPartSet p(groupInfo->Type);
- for (ui32 i = 1; i < v.size(); ++i) {
- if (v[i].empty()) {
- continue;
- }
- ui8 partIndex;
+
+ NRepl::TRecoveryMachine::TPartSet p(groupInfo->Type);
+ for (ui32 i = 1; i < v.size(); ++i) {
+ if (v[i].empty()) {
+ continue;
+ }
+ ui8 partIndex;
for (partIndex = 0; partIndex < groupInfo->Type.BlobSubgroupSize(); ++partIndex) {
- if (varray[partIndex] == vdisks[i]) {
- break;
- }
- }
+ if (varray[partIndex] == vdisks[i]) {
+ break;
+ }
+ }
UNIT_ASSERT(partIndex != groupInfo->Type.BlobSubgroupSize());
- p.AddData(0, TLogoBlobID(id, partIndex + 1), NKikimrProto::OK, v[i]);
- }
- NRepl::TRecoveryMachine::TRecoveredBlobsQueue rbq;
- NRepl::TRecoveryMachine::EPhantomState phantom = NRepl::TRecoveryMachine::EPhantomState::Unknown;
- m.Recover(id, p, rbq, phantom);
- Y_VERIFY(phantom == NRepl::TRecoveryMachine::EPhantomState::Unknown);
-
- ui8 partIndex;
+ p.AddData(0, TLogoBlobID(id, partIndex + 1), NKikimrProto::OK, v[i]);
+ }
+ NRepl::TRecoveryMachine::TRecoveredBlobsQueue rbq;
+ NRepl::TRecoveryMachine::EPhantomState phantom = NRepl::TRecoveryMachine::EPhantomState::Unknown;
+ m.Recover(id, p, rbq, phantom);
+ Y_VERIFY(phantom == NRepl::TRecoveryMachine::EPhantomState::Unknown);
+
+ ui8 partIndex;
for (partIndex = 0; partIndex < groupInfo->Type.BlobSubgroupSize(); ++partIndex) {
if (varray[partIndex] == groupInfo->GetVDiskId(replCtx->VCtx->ShortSelfVDisk)) {
- break;
- }
- }
+ break;
+ }
+ }
UNIT_ASSERT(partIndex != groupInfo->Type.BlobSubgroupSize());
-
- UNIT_ASSERT_EQUAL(rbq.size(), 1);
- auto& item = rbq.front();
- UNIT_ASSERT_EQUAL(item.Id, id);
-
- TRope buf = TDiskBlob::Create(id.BlobSize(), partIndex + 1, groupInfo->Type.TotalPartCount(), TRope(v[0]), arena);
-
- UNIT_ASSERT_EQUAL(item.Data, buf);
- }
- }
- }
-
-} // NKikimr
+
+ UNIT_ASSERT_EQUAL(rbq.size(), 1);
+ auto& item = rbq.front();
+ UNIT_ASSERT_EQUAL(item.Id, id);
+
+ TRope buf = TDiskBlob::Create(id.BlobSize(), partIndex + 1, groupInfo->Type.TotalPartCount(), TRope(v[0]), arena);
+
+ UNIT_ASSERT_EQUAL(item.Data, buf);
+ }
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/query_donor.h b/ydb/core/blobstorage/vdisk/repl/query_donor.h
index 7479d607c90..a2426442a23 100644
--- a/ydb/core/blobstorage/vdisk/repl/query_donor.h
+++ b/ydb/core/blobstorage/vdisk/repl/query_donor.h
@@ -1,104 +1,104 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/vdisk/common/vdisk_response.h>
-
-namespace NKikimr {
-
- class TDonorQueryActor : public TActorBootstrapped<TDonorQueryActor> {
- std::unique_ptr<TEvBlobStorage::TEvVGet> Query;
- const TActorId Sender;
- const ui64 Cookie;
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> Result;
- TActorId ParentId;
- std::deque<std::pair<TVDiskID, TActorId>> Donors;
-
- public:
- TDonorQueryActor(TEvBlobStorage::TEvEnrichNotYet& msg, std::deque<std::pair<TVDiskID, TActorId>> donors)
- : Query(msg.Query->Release().Release())
- , Sender(msg.Query->Sender)
- , Cookie(msg.Query->Cookie)
- , Result(std::move(msg.Result))
- , Donors(std::move(donors))
- {
- Y_VERIFY(!Query->Record.HasRangeQuery());
- }
-
- void Bootstrap(const TActorId& parentId) {
- ParentId = parentId;
- Become(&TThis::StateFunc);
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " starting Donor-mode query");
- Step();
- }
-
- void Step() {
- if (Donors.empty()) {
- return PassAway();
- }
-
- auto [vdiskId, actorId] = Donors.back();
- Donors.pop_back();
-
- // we use AsyncRead priority as we are going to use the replication queue for the VDisk; also this doesn't
- // matter too much as this is the only point of access to that disk
- const auto& record = Query->Record;
- const auto fun = record.GetIndexOnly()
- ? &TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery
- : &TEvBlobStorage::TEvVGet::CreateExtremeDataQuery;
- const auto flags = record.GetShowInternals()
- ? TEvBlobStorage::TEvVGet::EFlags::ShowInternals
- : TEvBlobStorage::TEvVGet::EFlags::None;
- auto query = fun(vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {}, 0);
-
- bool action = false;
-
- const auto& result = Result->Record;
- for (ui64 i = 0; i < result.ResultSize(); ++i) {
- const auto& r = result.GetResult(i);
- if (r.GetStatus() == NKikimrProto::NOT_YET) {
- query->AddExtremeQuery(LogoBlobIDFromLogoBlobID(r.GetBlobID()), r.GetShift(), r.GetSize(), &i);
- action = true;
- }
- }
-
- if (action) {
- const TActorId temp(actorId);
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " sending " << query->ToString()
- << " to " << temp);
- Send(actorId, query.release());
- } else {
- PassAway();
- }
- }
-
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " received " << ev->Get()->ToString());
- auto& result = Result->Record;
- for (const auto& item : ev->Get()->Record.GetResult()) {
- auto *res = result.MutableResult(item.GetCookie());
- if (item.GetStatus() == NKikimrProto::OK || (item.GetStatus() == NKikimrProto::ERROR && res->GetStatus() == NKikimrProto::NOT_YET)) {
- std::optional<ui64> cookie = res->HasCookie() ? std::make_optional(res->GetCookie()) : std::nullopt;
- res->CopyFrom(item);
- if (cookie) { // retain original cookie
- res->SetCookie(*cookie);
- } else {
- res->ClearCookie();
- }
- }
- }
- Step();
- }
-
- void PassAway() override {
- LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " finished query");
- Send(ParentId, new TEvents::TEvActorDied);
- SendVDiskResponse(TActivationContext::AsActorContext(), Sender, Result.release(), *this, Cookie);
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
- };
-
-} // NKikimr
+
+namespace NKikimr {
+
+ class TDonorQueryActor : public TActorBootstrapped<TDonorQueryActor> {
+ std::unique_ptr<TEvBlobStorage::TEvVGet> Query;
+ const TActorId Sender;
+ const ui64 Cookie;
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> Result;
+ TActorId ParentId;
+ std::deque<std::pair<TVDiskID, TActorId>> Donors;
+
+ public:
+ TDonorQueryActor(TEvBlobStorage::TEvEnrichNotYet& msg, std::deque<std::pair<TVDiskID, TActorId>> donors)
+ : Query(msg.Query->Release().Release())
+ , Sender(msg.Query->Sender)
+ , Cookie(msg.Query->Cookie)
+ , Result(std::move(msg.Result))
+ , Donors(std::move(donors))
+ {
+ Y_VERIFY(!Query->Record.HasRangeQuery());
+ }
+
+ void Bootstrap(const TActorId& parentId) {
+ ParentId = parentId;
+ Become(&TThis::StateFunc);
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " starting Donor-mode query");
+ Step();
+ }
+
+ void Step() {
+ if (Donors.empty()) {
+ return PassAway();
+ }
+
+ auto [vdiskId, actorId] = Donors.back();
+ Donors.pop_back();
+
+ // we use AsyncRead priority as we are going to use the replication queue for the VDisk; also this doesn't
+ // matter too much as this is the only point of access to that disk
+ const auto& record = Query->Record;
+ const auto fun = record.GetIndexOnly()
+ ? &TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery
+ : &TEvBlobStorage::TEvVGet::CreateExtremeDataQuery;
+ const auto flags = record.GetShowInternals()
+ ? TEvBlobStorage::TEvVGet::EFlags::ShowInternals
+ : TEvBlobStorage::TEvVGet::EFlags::None;
+ auto query = fun(vdiskId, TInstant::Max(), NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {}, 0);
+
+ bool action = false;
+
+ const auto& result = Result->Record;
+ for (ui64 i = 0; i < result.ResultSize(); ++i) {
+ const auto& r = result.GetResult(i);
+ if (r.GetStatus() == NKikimrProto::NOT_YET) {
+ query->AddExtremeQuery(LogoBlobIDFromLogoBlobID(r.GetBlobID()), r.GetShift(), r.GetSize(), &i);
+ action = true;
+ }
+ }
+
+ if (action) {
+ const TActorId temp(actorId);
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " sending " << query->ToString()
+ << " to " << temp);
+ Send(actorId, query.release());
+ } else {
+ PassAway();
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " received " << ev->Get()->ToString());
+ auto& result = Result->Record;
+ for (const auto& item : ev->Get()->Record.GetResult()) {
+ auto *res = result.MutableResult(item.GetCookie());
+ if (item.GetStatus() == NKikimrProto::OK || (item.GetStatus() == NKikimrProto::ERROR && res->GetStatus() == NKikimrProto::NOT_YET)) {
+ std::optional<ui64> cookie = res->HasCookie() ? std::make_optional(res->GetCookie()) : std::nullopt;
+ res->CopyFrom(item);
+ if (cookie) { // retain original cookie
+ res->SetCookie(*cookie);
+ } else {
+ res->ClearCookie();
+ }
+ }
+ }
+ Step();
+ }
+
+ void PassAway() override {
+ LOG_DEBUG_S(*TlsActivationContext, NKikimrServices::BS_VDISK_GET, SelfId() << " finished query");
+ Send(ParentId, new TEvents::TEvActorDied);
+ SendVDiskResponse(TActivationContext::AsActorContext(), Sender, Result.release(), *this, Cookie);
+ TActorBootstrapped::PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/repl_quoter.h b/ydb/core/blobstorage/vdisk/repl/repl_quoter.h
index 00a89547767..8d2b62814ee 100644
--- a/ydb/core/blobstorage/vdisk/repl/repl_quoter.h
+++ b/ydb/core/blobstorage/vdisk/repl/repl_quoter.h
@@ -1,57 +1,57 @@
-#pragma once
-
-namespace NKikimr {
-
- class TReplQuoter {
- public:
- using TPtr = std::shared_ptr<TReplQuoter>;
-
- private:
- using TAtomicInstant = std::atomic<TInstant>;
- static_assert(TAtomicInstant::is_always_lock_free);
-
- TAtomicInstant NextQueueItemTimestamp;
- const ui64 BytesPerSecond;
-
- public:
- TReplQuoter(ui64 bytesPerSecond)
- : BytesPerSecond(bytesPerSecond)
- {
- NextQueueItemTimestamp = TInstant::Zero();
- }
-
- TDuration Take(TInstant now, ui64 bytes) {
- TDuration duration = TDuration::MicroSeconds(bytes * 1000000 / BytesPerSecond);
- for (;;) {
- TInstant current = NextQueueItemTimestamp;
- const TInstant notBefore = now - GetCapacity();
- const TInstant base = Max(current, notBefore);
- const TDuration res = base - now; // time to wait until submitting desired query
- const TInstant next = base + duration;
- if (NextQueueItemTimestamp.compare_exchange_weak(current, next)) {
- return res;
- }
- }
- }
-
- static void QuoteMessage(const TPtr& quoter, std::unique_ptr<IEventHandle> ev, ui64 bytes) {
- const TDuration timeout = quoter
- ? quoter->Take(TActivationContext::Now(), bytes)
- : TDuration::Zero();
- if (timeout != TDuration::Zero()) {
- TActivationContext::Schedule(timeout, ev.release());
- } else {
- TActivationContext::Send(ev.release());
- }
- }
-
- ui64 GetMaxPacketSize() const {
- return BytesPerSecond * GetCapacity().MicroSeconds() / 1000000;
- }
-
- static constexpr TDuration GetCapacity() {
- return TDuration::MilliSeconds(100);
- }
- };
-
-} // NKikimr
+#pragma once
+
+namespace NKikimr {
+
+ class TReplQuoter {
+ public:
+ using TPtr = std::shared_ptr<TReplQuoter>;
+
+ private:
+ using TAtomicInstant = std::atomic<TInstant>;
+ static_assert(TAtomicInstant::is_always_lock_free);
+
+ TAtomicInstant NextQueueItemTimestamp;
+ const ui64 BytesPerSecond;
+
+ public:
+ TReplQuoter(ui64 bytesPerSecond)
+ : BytesPerSecond(bytesPerSecond)
+ {
+ NextQueueItemTimestamp = TInstant::Zero();
+ }
+
+ TDuration Take(TInstant now, ui64 bytes) {
+ TDuration duration = TDuration::MicroSeconds(bytes * 1000000 / BytesPerSecond);
+ for (;;) {
+ TInstant current = NextQueueItemTimestamp;
+ const TInstant notBefore = now - GetCapacity();
+ const TInstant base = Max(current, notBefore);
+ const TDuration res = base - now; // time to wait until submitting desired query
+ const TInstant next = base + duration;
+ if (NextQueueItemTimestamp.compare_exchange_weak(current, next)) {
+ return res;
+ }
+ }
+ }
+
+ static void QuoteMessage(const TPtr& quoter, std::unique_ptr<IEventHandle> ev, ui64 bytes) {
+ const TDuration timeout = quoter
+ ? quoter->Take(TActivationContext::Now(), bytes)
+ : TDuration::Zero();
+ if (timeout != TDuration::Zero()) {
+ TActivationContext::Schedule(timeout, ev.release());
+ } else {
+ TActivationContext::Send(ev.release());
+ }
+ }
+
+ ui64 GetMaxPacketSize() const {
+ return BytesPerSecond * GetCapacity().MicroSeconds() / 1000000;
+ }
+
+ static constexpr TDuration GetCapacity() {
+ return TDuration::MilliSeconds(100);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/repl/ut/ya.make b/ydb/core/blobstorage/vdisk/repl/ut/ya.make
index 186f4213dcb..ec60ecce8b3 100644
--- a/ydb/core/blobstorage/vdisk/repl/ut/ya.make
+++ b/ydb/core/blobstorage/vdisk/repl/ut/ya.make
@@ -17,7 +17,7 @@ PEERDIR(
)
SRCS(
- blobstorage_hullreplwritesst_ut.cpp
+ blobstorage_hullreplwritesst_ut.cpp
blobstorage_replrecoverymachine_ut.cpp
)
diff --git a/ydb/core/blobstorage/vdisk/repl/ya.make b/ydb/core/blobstorage/vdisk/repl/ya.make
index 8c237578909..34cc4ca9698 100644
--- a/ydb/core/blobstorage/vdisk/repl/ya.make
+++ b/ydb/core/blobstorage/vdisk/repl/ya.make
@@ -28,8 +28,8 @@ SRCS(
blobstorage_replproxy.h
blobstorage_replrecoverymachine.h
defs.h
- query_donor.h
- repl_quoter.h
+ query_donor.h
+ repl_quoter.h
)
END()
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery.cpp b/ydb/core/blobstorage/vdisk/scrub/blob_recovery.cpp
index b611d3c9cb5..026abd0c89c 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery.cpp
@@ -1,21 +1,21 @@
-#include "blob_recovery_impl.h"
-
-namespace NKikimr {
-
- void TBlobRecoveryActor::Bootstrap() {
- STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS27, VDISKP(LogPrefix, "bootstrapping blob recovery actor"), (SelfId, SelfId()));
- StartQueues();
- Become(&TThis::StateFunc);
- }
-
- void TBlobRecoveryActor::PassAway() {
- STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS30, VDISKP(LogPrefix, "blob recovery actor terminating"), (SelfId, SelfId()));
- StopQueues();
- }
-
- IActor *CreateBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
- NMonitoring::TDynamicCounterPtr counters) {
- return new TBlobRecoveryActor(std::move(vctx), std::move(info), std::move(counters));
- }
-
-} // NKikimr
+#include "blob_recovery_impl.h"
+
+namespace NKikimr {
+
+ void TBlobRecoveryActor::Bootstrap() {
+ STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS27, VDISKP(LogPrefix, "bootstrapping blob recovery actor"), (SelfId, SelfId()));
+ StartQueues();
+ Become(&TThis::StateFunc);
+ }
+
+ void TBlobRecoveryActor::PassAway() {
+ STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS30, VDISKP(LogPrefix, "blob recovery actor terminating"), (SelfId, SelfId()));
+ StopQueues();
+ }
+
+ IActor *CreateBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
+ NMonitoring::TDynamicCounterPtr counters) {
+ return new TBlobRecoveryActor(std::move(vctx), std::move(info), std::move(counters));
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery.h b/ydb/core/blobstorage/vdisk/scrub/blob_recovery.h
index 98c7fbab197..c8dd1397d9d 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery.h
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery.h
@@ -1,99 +1,99 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- struct TEvRecoverBlob : TEventLocal<TEvRecoverBlob, TEvBlobStorage::EvRecoverBlob> {
- struct TItem {
- TLogoBlobID BlobId;
- TDataPartSet PartSet; // available data
- NMatrix::TVectorType Needed; // needed parts
- TDiskPart CorruptedPart;
- ui64 Cookie;
-
- TItem(const TItem&) = default;
- TItem(TItem&&) = default;
-
- TItem(TLogoBlobID blobId, TDataPartSet&& partSet, NMatrix::TVectorType needed, TDiskPart corruptedPart, ui64 cookie = 0)
- : BlobId(blobId)
- , PartSet(std::move(partSet))
- , Needed(needed)
- , CorruptedPart(corruptedPart)
- , Cookie(cookie)
- {}
-
- TItem(TLogoBlobID blobId, NMatrix::TVectorType needed, const TBlobStorageGroupType& gtype, TDiskPart corruptedPart, ui64 cookie = 0)
- : BlobId(blobId)
- , PartSet{blobId.BlobSize(), 0, {gtype.TotalPartCount(), TPartFragment()}, TPartFragment(), 0u, false}
- , Needed(needed)
- , CorruptedPart(corruptedPart)
- , Cookie(cookie)
- {}
-
- void SetPartData(TLogoBlobID id, TString data) {
- Y_VERIFY(id.FullID() == BlobId);
- Y_VERIFY(id.PartId());
- const ui32 partIdx = id.PartId() - 1;
- if (PartSet.PartsMask & (1 << partIdx)) {
- Y_VERIFY(GetPartData(id) == data);
- } else {
- PartSet.PartsMask |= 1 << partIdx;
- PartSet.Parts[partIdx].ReferenceTo(data);
- }
- }
-
- TString GetPartData(TLogoBlobID id) const {
- Y_VERIFY(id.FullID() == BlobId);
- Y_VERIFY(id.PartId());
- const ui32 partIdx = id.PartId() - 1;
- Y_VERIFY(PartSet.PartsMask & (1 << partIdx));
- return PartSet.Parts[partIdx].OwnedString;
- }
-
- NMatrix::TVectorType GetAvailableParts() const {
- NMatrix::TVectorType res(0, Needed.GetSize());
- for (size_t i = 0; i < PartSet.Parts.size(); ++i) {
- if (PartSet.PartsMask & (1 << i)) {
- res.Set(i);
- }
- }
- return res;
- }
- };
- TInstant Deadline;
- std::deque<TItem> Items;
-
- TString ToString() const {
- TStringStream s;
- Output(s);
- return s.Str();
- }
-
- void Output(IOutputStream& s) const {
- s << "{Deadline# " << Deadline << " Items# [";
- bool first = true;
- for (const TItem& item : Items) {
- s << (std::exchange(first, false) ? "" : " ") << "{BlobId# " << item.BlobId.ToString() << " Needed# "
- << item.Needed.ToString() << " PartsMask# " << Sprintf("%02" PRIx32, item.PartSet.PartsMask) << "}";
- }
- s << "]}";
- }
- };
-
- struct TEvRecoverBlobResult : TEventLocal<TEvRecoverBlobResult, TEvBlobStorage::EvRecoverBlobResult> {
- struct TItem : TEvRecoverBlob::TItem {
- NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
-
- TItem(TEvRecoverBlob::TItem&& item)
- : TEvRecoverBlob::TItem(std::move(item))
- {}
- };
- TInstant Deadline;
- std::deque<TItem> Items;
- };
-
- IActor *CreateBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
- NMonitoring::TDynamicCounterPtr counters);
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ struct TEvRecoverBlob : TEventLocal<TEvRecoverBlob, TEvBlobStorage::EvRecoverBlob> {
+ struct TItem {
+ TLogoBlobID BlobId;
+ TDataPartSet PartSet; // available data
+ NMatrix::TVectorType Needed; // needed parts
+ TDiskPart CorruptedPart;
+ ui64 Cookie;
+
+ TItem(const TItem&) = default;
+ TItem(TItem&&) = default;
+
+ TItem(TLogoBlobID blobId, TDataPartSet&& partSet, NMatrix::TVectorType needed, TDiskPart corruptedPart, ui64 cookie = 0)
+ : BlobId(blobId)
+ , PartSet(std::move(partSet))
+ , Needed(needed)
+ , CorruptedPart(corruptedPart)
+ , Cookie(cookie)
+ {}
+
+ TItem(TLogoBlobID blobId, NMatrix::TVectorType needed, const TBlobStorageGroupType& gtype, TDiskPart corruptedPart, ui64 cookie = 0)
+ : BlobId(blobId)
+ , PartSet{blobId.BlobSize(), 0, {gtype.TotalPartCount(), TPartFragment()}, TPartFragment(), 0u, false}
+ , Needed(needed)
+ , CorruptedPart(corruptedPart)
+ , Cookie(cookie)
+ {}
+
+ void SetPartData(TLogoBlobID id, TString data) {
+ Y_VERIFY(id.FullID() == BlobId);
+ Y_VERIFY(id.PartId());
+ const ui32 partIdx = id.PartId() - 1;
+ if (PartSet.PartsMask & (1 << partIdx)) {
+ Y_VERIFY(GetPartData(id) == data);
+ } else {
+ PartSet.PartsMask |= 1 << partIdx;
+ PartSet.Parts[partIdx].ReferenceTo(data);
+ }
+ }
+
+ TString GetPartData(TLogoBlobID id) const {
+ Y_VERIFY(id.FullID() == BlobId);
+ Y_VERIFY(id.PartId());
+ const ui32 partIdx = id.PartId() - 1;
+ Y_VERIFY(PartSet.PartsMask & (1 << partIdx));
+ return PartSet.Parts[partIdx].OwnedString;
+ }
+
+ NMatrix::TVectorType GetAvailableParts() const {
+ NMatrix::TVectorType res(0, Needed.GetSize());
+ for (size_t i = 0; i < PartSet.Parts.size(); ++i) {
+ if (PartSet.PartsMask & (1 << i)) {
+ res.Set(i);
+ }
+ }
+ return res;
+ }
+ };
+ TInstant Deadline;
+ std::deque<TItem> Items;
+
+ TString ToString() const {
+ TStringStream s;
+ Output(s);
+ return s.Str();
+ }
+
+ void Output(IOutputStream& s) const {
+ s << "{Deadline# " << Deadline << " Items# [";
+ bool first = true;
+ for (const TItem& item : Items) {
+ s << (std::exchange(first, false) ? "" : " ") << "{BlobId# " << item.BlobId.ToString() << " Needed# "
+ << item.Needed.ToString() << " PartsMask# " << Sprintf("%02" PRIx32, item.PartSet.PartsMask) << "}";
+ }
+ s << "]}";
+ }
+ };
+
+ struct TEvRecoverBlobResult : TEventLocal<TEvRecoverBlobResult, TEvBlobStorage::EvRecoverBlobResult> {
+ struct TItem : TEvRecoverBlob::TItem {
+ NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
+
+ TItem(TEvRecoverBlob::TItem&& item)
+ : TEvRecoverBlob::TItem(std::move(item))
+ {}
+ };
+ TInstant Deadline;
+ std::deque<TItem> Items;
+ };
+
+ IActor *CreateBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
+ NMonitoring::TDynamicCounterPtr counters);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_impl.h b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_impl.h
index cca66554af1..51a37701e8c 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_impl.h
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_impl.h
@@ -1,117 +1,117 @@
-#pragma once
-
-#include "defs.h"
-#include "blob_recovery.h"
-
-namespace NKikimr {
-
- class TBlobRecoveryActor : public TActorBootstrapped<TBlobRecoveryActor> {
- const TIntrusivePtr<TVDiskContext> VCtx;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const NMonitoring::TDynamicCounterPtr Counters;
- const TString LogPrefix;
-
- public:
- TBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
- NMonitoring::TDynamicCounterPtr counters)
- : VCtx(std::move(vctx))
- , Info(std::move(info))
- , Counters(counters)
- , LogPrefix(VCtx->VDiskLogPrefix)
- {}
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_BLOB_RECOVERY_ACTOR;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // actor state function
-
- void Bootstrap();
- void PassAway() override;
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvVGenerationChange, Handle);
- hFunc(TEvProxyQueueState, Handle);
- hFunc(TEvRecoverBlob, Handle);
- hFunc(TEvBlobStorage::TEvVGetResult, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // BS_QUEUE management
-
- struct TQueueInfo {
- const TActorId QueueActorId;
- bool IsConnected = false;
- };
- std::unordered_map<TVDiskIdShort, TQueueInfo, THash<TVDiskIdShort>> Queues;
- bool IsConnected = false;
-
- void StartQueues();
- void StopQueues();
- void Handle(TEvVGenerationChange::TPtr ev);
- void Handle(TEvProxyQueueState::TPtr ev);
- void EvaluateConnectionQuorum();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // request processing
-
- struct TInFlightContext;
- using TInFlightContextPtr = std::shared_ptr<TInFlightContext>;
- using TInFlight = std::multimap<TInstant, TInFlightContextPtr>; // deadline -> context map
- struct TInFlightContext {
- TInFlight::iterator Iterator; // pointing to this record in InFlight map
- const ui64 RequestId; // identifier of a request (for debugging purposes)
- const TActorId Sender; // sender of an TEvRecoverBlob
- const ui64 Cookie; // cookie with the original request
- std::unique_ptr<TEvRecoverBlobResult> Result; // pending response message
- ui32 NumUnrespondedBlobs = 0; // number of blobs with UNKNOWN status
-
- TInFlightContext(ui64 requestId, TEventHandle<TEvRecoverBlob>& ev)
- : RequestId(requestId)
- , Sender(ev.Sender)
- , Cookie(ev.Cookie)
- , Result(std::make_unique<TEvRecoverBlobResult>())
- {}
-
- void SendResult(const TActorIdentity& self) {
- self.Send(Sender, Result.release(), 0, Cookie);
- }
- };
- TInFlight InFlight;
- ui64 NextRequestId = 1;
- bool WakeupScheduled = false;
-
- void Handle(TEvRecoverBlob::TPtr ev);
- void HandleWakeup();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDisk query processing
-
- struct TQuery {
- std::unique_ptr<TEvBlobStorage::TEvVGet> VGet; // currently filled in
- std::deque<std::unique_ptr<TEvBlobStorage::TEvVGet>> Pending; // already filled in and ready
- ui32 WorstReplySize = 0;
- };
- std::map<TVDiskID, TQuery> Queries;
-
- // a map to fill upon receiving VGet result
- struct TPerBlobInfo {
- const TInstant Deadline;
- std::weak_ptr<TInFlightContext> Context;
- TEvRecoverBlobResult::TItem *Item; // item to update
- ui32 BlobReplyCounter = 0; // number of unreplied queries for this blob
- };
- std::unordered_multimap<TLogoBlobID, TPerBlobInfo, THash<TLogoBlobID>> VGetResultMap;
-
- void AddBlobQuery(const TLogoBlobID& id, NMatrix::TVectorType needed, const std::shared_ptr<TInFlightContext>& context, TEvRecoverBlobResult::TItem *item);
- void AddExtremeQuery(const TVDiskID& vdiskId, const TLogoBlobID& id, TInstant deadline, ui32 worstReplySize);
- void SendPendingQueries();
- void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev);
- NKikimrProto::EReplyStatus ProcessItemData(TEvRecoverBlobResult::TItem& item);
- };
-
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+#include "blob_recovery.h"
+
+namespace NKikimr {
+
+ class TBlobRecoveryActor : public TActorBootstrapped<TBlobRecoveryActor> {
+ const TIntrusivePtr<TVDiskContext> VCtx;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const NMonitoring::TDynamicCounterPtr Counters;
+ const TString LogPrefix;
+
+ public:
+ TBlobRecoveryActor(TIntrusivePtr<TVDiskContext> vctx, TIntrusivePtr<TBlobStorageGroupInfo> info,
+ NMonitoring::TDynamicCounterPtr counters)
+ : VCtx(std::move(vctx))
+ , Info(std::move(info))
+ , Counters(counters)
+ , LogPrefix(VCtx->VDiskLogPrefix)
+ {}
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_BLOB_RECOVERY_ACTOR;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // actor state function
+
+ void Bootstrap();
+ void PassAway() override;
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvVGenerationChange, Handle);
+ hFunc(TEvProxyQueueState, Handle);
+ hFunc(TEvRecoverBlob, Handle);
+ hFunc(TEvBlobStorage::TEvVGetResult, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BS_QUEUE management
+
+ struct TQueueInfo {
+ const TActorId QueueActorId;
+ bool IsConnected = false;
+ };
+ std::unordered_map<TVDiskIdShort, TQueueInfo, THash<TVDiskIdShort>> Queues;
+ bool IsConnected = false;
+
+ void StartQueues();
+ void StopQueues();
+ void Handle(TEvVGenerationChange::TPtr ev);
+ void Handle(TEvProxyQueueState::TPtr ev);
+ void EvaluateConnectionQuorum();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // request processing
+
+ struct TInFlightContext;
+ using TInFlightContextPtr = std::shared_ptr<TInFlightContext>;
+ using TInFlight = std::multimap<TInstant, TInFlightContextPtr>; // deadline -> context map
+ struct TInFlightContext {
+ TInFlight::iterator Iterator; // pointing to this record in InFlight map
+ const ui64 RequestId; // identifier of a request (for debugging purposes)
+ const TActorId Sender; // sender of an TEvRecoverBlob
+ const ui64 Cookie; // cookie with the original request
+ std::unique_ptr<TEvRecoverBlobResult> Result; // pending response message
+ ui32 NumUnrespondedBlobs = 0; // number of blobs with UNKNOWN status
+
+ TInFlightContext(ui64 requestId, TEventHandle<TEvRecoverBlob>& ev)
+ : RequestId(requestId)
+ , Sender(ev.Sender)
+ , Cookie(ev.Cookie)
+ , Result(std::make_unique<TEvRecoverBlobResult>())
+ {}
+
+ void SendResult(const TActorIdentity& self) {
+ self.Send(Sender, Result.release(), 0, Cookie);
+ }
+ };
+ TInFlight InFlight;
+ ui64 NextRequestId = 1;
+ bool WakeupScheduled = false;
+
+ void Handle(TEvRecoverBlob::TPtr ev);
+ void HandleWakeup();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDisk query processing
+
+ struct TQuery {
+ std::unique_ptr<TEvBlobStorage::TEvVGet> VGet; // currently filled in
+ std::deque<std::unique_ptr<TEvBlobStorage::TEvVGet>> Pending; // already filled in and ready
+ ui32 WorstReplySize = 0;
+ };
+ std::map<TVDiskID, TQuery> Queries;
+
+ // a map to fill upon receiving VGet result
+ struct TPerBlobInfo {
+ const TInstant Deadline;
+ std::weak_ptr<TInFlightContext> Context;
+ TEvRecoverBlobResult::TItem *Item; // item to update
+ ui32 BlobReplyCounter = 0; // number of unreplied queries for this blob
+ };
+ std::unordered_multimap<TLogoBlobID, TPerBlobInfo, THash<TLogoBlobID>> VGetResultMap;
+
+ void AddBlobQuery(const TLogoBlobID& id, NMatrix::TVectorType needed, const std::shared_ptr<TInFlightContext>& context, TEvRecoverBlobResult::TItem *item);
+ void AddExtremeQuery(const TVDiskID& vdiskId, const TLogoBlobID& id, TInstant deadline, ui32 worstReplySize);
+ void SendPendingQueries();
+ void Handle(TEvBlobStorage::TEvVGetResult::TPtr ev);
+ NKikimrProto::EReplyStatus ProcessItemData(TEvRecoverBlobResult::TItem& item);
+ };
+
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_process.cpp b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_process.cpp
index 0348ada82de..3c7adf5904d 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_process.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_process.cpp
@@ -1,142 +1,142 @@
-#include "blob_recovery_impl.h"
-
-namespace NKikimr {
-
- void TBlobRecoveryActor::AddBlobQuery(const TLogoBlobID& id, NMatrix::TVectorType needed,
- const std::shared_ptr<TInFlightContext>& context, TEvRecoverBlobResult::TItem *item) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS32, VDISKP(LogPrefix, "AddBlobQuery"), (SelfId, SelfId()),
- (Id, id), (Needed, needed), (RequestId, context->RequestId));
- const TInstant deadline = context->Iterator->first;
- const TBlobStorageGroupType& gtype = Info->Type;
- TBlobStorageGroupInfo::TOrderNums nums;
- Info->GetTopology().PickSubgroup(id.Hash(), nums);
- ui32 blobReplyCounter = 0;
- for (ui32 i = 0; i < nums.size(); ++i) {
- const TVDiskID& vdiskId = Info->GetVDiskId(i); // obtain VDisk
- if (TVDiskIdShort(vdiskId) == VCtx->ShortSelfVDisk) {
- continue;
- }
- switch (TIngress::IngressMode(gtype)) {
- case TIngress::EMode::GENERIC:
- if (i < gtype.TotalPartCount() && needed.Get(i)) { // only main replica
- const TLogoBlobID partId(id, i + 1);
- AddExtremeQuery(vdiskId, partId, deadline, gtype.PartSize(partId));
- } else {
- ui32 maxSize = 0;
- for (ui32 i = 0; i < gtype.TotalPartCount(); ++i) {
- maxSize += gtype.PartSize(TLogoBlobID(id, i + 1));
- }
- AddExtremeQuery(vdiskId, id, deadline, maxSize);
- }
- break;
-
- case TIngress::EMode::MIRROR3OF4:
- AddExtremeQuery(vdiskId, id, deadline, gtype.PartSize(TLogoBlobID(id, 1)) +
- gtype.PartSize(TLogoBlobID(id, 2)));
- break;
- }
- ++blobReplyCounter;
- }
- VGetResultMap.emplace(id, TPerBlobInfo{context->Iterator->first, context, item, blobReplyCounter});
- }
-
- void TBlobRecoveryActor::AddExtremeQuery(const TVDiskID& vdiskId, const TLogoBlobID& id, TInstant deadline, ui32 worstReplySize) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS33, VDISKP(LogPrefix, "AddExtremeQuery"), (SelfId, SelfId()),
- (VDiskId, vdiskId), (Id, id), (WorstReplySize, worstReplySize));
-
- TQuery& query = Queries[vdiskId];
-
- const ui32 maxReplySize = 10000000; // FIXME
- if (query.VGet && query.WorstReplySize + worstReplySize > maxReplySize) { // send the request on overflow
- query.Pending.push_back(std::move(query.VGet));
- query.WorstReplySize = 0;
- }
-
- if (!query.VGet) {
- query.VGet = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, deadline,
- NKikimrBlobStorage::EGetHandleClass::AsyncRead);
- }
-
- query.VGet->AddExtremeQuery(id, 0, 0);
- query.WorstReplySize += worstReplySize;
- }
-
- void TBlobRecoveryActor::SendPendingQueries() {
- for (auto& [vdiskId, query] : std::exchange(Queries, {})) {
- Y_VERIFY(query.VGet);
- query.Pending.push_back(std::move(query.VGet));
- auto queueIt = Queues.find(vdiskId);
- Y_VERIFY(queueIt != Queues.end());
- for (auto& vget : query.Pending) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS34, VDISKP(LogPrefix, "sending TEvVGet"), (SelfId, SelfId()),
- (Msg, vget->ToString()));
- Send(queueIt->second.QueueActorId, vget.release());
- }
- }
- }
-
- void TBlobRecoveryActor::Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS35, VDISKP(LogPrefix, "received TEvVGetResult"), (SelfId, SelfId()),
- (Msg, ev->Get()->ToString()));
-
- const auto& record = ev->Get()->Record;
- for (const auto& res : record.GetResult()) {
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(res.GetBlobID());
- const TLogoBlobID& fullId = id.FullID(); // whole blob id
- auto r = VGetResultMap.equal_range(fullId);
- for (auto it = r.first; it != r.second; ) {
- TPerBlobInfo& info = it->second;
- if (auto context = info.Context.lock()) { // context acquired, request is still intact
- auto& item = *info.Item; // only here we can access item, after obtaining context pointer
- TString data = res.GetBuffer();
- bool update = false;
- if (res.GetStatus() == NKikimrProto::OK && data) {
- item.SetPartData(id, data);
- update = true;
- }
- const bool term = !--info.BlobReplyCounter;
- if (item.Status == NKikimrProto::UNKNOWN && (term || update)) {
- const NKikimrProto::EReplyStatus prevStatus = std::exchange(item.Status, ProcessItemData(item));
- if (item.Status == NKikimrProto::UNKNOWN && term) { // not enough parts to fulfill request
- item.Status = NKikimrProto::NODATA;
- }
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS36, VDISKP(LogPrefix, "processing item"),
- (SelfId, SelfId()), (RequestId, context->RequestId), (Id, id),
- (Status, res.GetStatus()), (Last, term), (DataUpdated, update),
- (EntryStatus, prevStatus), (ExitStatus, item.Status));
- }
- if (item.Status != NKikimrProto::UNKNOWN && !--context->NumUnrespondedBlobs) {
- context->SendResult(SelfId());
- InFlight.erase(context->Iterator);
- }
- ++it;
- } else { // request deadlined or canceled, we erase it from the map
- it = VGetResultMap.erase(it);
- }
- }
- }
- }
-
- NKikimrProto::EReplyStatus TBlobRecoveryActor::ProcessItemData(TEvRecoverBlobResult::TItem& item) {
- if (item.GetAvailableParts().IsSupersetOf(item.Needed)) {
- return NKikimrProto::OK;
- }
- const ui32 numParts = PopCount(item.PartSet.PartsMask);
- if (numParts >= Info->Type.MinimalRestorablePartCount()) {
- TString buffer;
- Info->Type.RestoreData((TErasureType::ECrcMode)item.BlobId.CrcMode(), item.PartSet, buffer, true,
- false, true);
- item.PartSet.PartsMask = (1u << item.PartSet.Parts.size()) - 1;
- // clear metadata parts in mirror erasures
- for (ui32 i = 0; i < item.PartSet.Parts.size(); ++i) {
- if (!Info->Type.PartSize(TLogoBlobID(item.BlobId, i + 1))) {
- item.PartSet.Parts[i].ReferenceTo(TString());
- }
- }
- return NKikimrProto::OK;
- } else {
- return NKikimrProto::UNKNOWN;
- }
- }
-
-} // NKikimr
+#include "blob_recovery_impl.h"
+
+namespace NKikimr {
+
+ void TBlobRecoveryActor::AddBlobQuery(const TLogoBlobID& id, NMatrix::TVectorType needed,
+ const std::shared_ptr<TInFlightContext>& context, TEvRecoverBlobResult::TItem *item) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS32, VDISKP(LogPrefix, "AddBlobQuery"), (SelfId, SelfId()),
+ (Id, id), (Needed, needed), (RequestId, context->RequestId));
+ const TInstant deadline = context->Iterator->first;
+ const TBlobStorageGroupType& gtype = Info->Type;
+ TBlobStorageGroupInfo::TOrderNums nums;
+ Info->GetTopology().PickSubgroup(id.Hash(), nums);
+ ui32 blobReplyCounter = 0;
+ for (ui32 i = 0; i < nums.size(); ++i) {
+ const TVDiskID& vdiskId = Info->GetVDiskId(i); // obtain VDisk
+ if (TVDiskIdShort(vdiskId) == VCtx->ShortSelfVDisk) {
+ continue;
+ }
+ switch (TIngress::IngressMode(gtype)) {
+ case TIngress::EMode::GENERIC:
+ if (i < gtype.TotalPartCount() && needed.Get(i)) { // only main replica
+ const TLogoBlobID partId(id, i + 1);
+ AddExtremeQuery(vdiskId, partId, deadline, gtype.PartSize(partId));
+ } else {
+ ui32 maxSize = 0;
+ for (ui32 i = 0; i < gtype.TotalPartCount(); ++i) {
+ maxSize += gtype.PartSize(TLogoBlobID(id, i + 1));
+ }
+ AddExtremeQuery(vdiskId, id, deadline, maxSize);
+ }
+ break;
+
+ case TIngress::EMode::MIRROR3OF4:
+ AddExtremeQuery(vdiskId, id, deadline, gtype.PartSize(TLogoBlobID(id, 1)) +
+ gtype.PartSize(TLogoBlobID(id, 2)));
+ break;
+ }
+ ++blobReplyCounter;
+ }
+ VGetResultMap.emplace(id, TPerBlobInfo{context->Iterator->first, context, item, blobReplyCounter});
+ }
+
+ void TBlobRecoveryActor::AddExtremeQuery(const TVDiskID& vdiskId, const TLogoBlobID& id, TInstant deadline, ui32 worstReplySize) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS33, VDISKP(LogPrefix, "AddExtremeQuery"), (SelfId, SelfId()),
+ (VDiskId, vdiskId), (Id, id), (WorstReplySize, worstReplySize));
+
+ TQuery& query = Queries[vdiskId];
+
+ const ui32 maxReplySize = 10000000; // FIXME
+ if (query.VGet && query.WorstReplySize + worstReplySize > maxReplySize) { // send the request on overflow
+ query.Pending.push_back(std::move(query.VGet));
+ query.WorstReplySize = 0;
+ }
+
+ if (!query.VGet) {
+ query.VGet = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(vdiskId, deadline,
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead);
+ }
+
+ query.VGet->AddExtremeQuery(id, 0, 0);
+ query.WorstReplySize += worstReplySize;
+ }
+
+ void TBlobRecoveryActor::SendPendingQueries() {
+ for (auto& [vdiskId, query] : std::exchange(Queries, {})) {
+ Y_VERIFY(query.VGet);
+ query.Pending.push_back(std::move(query.VGet));
+ auto queueIt = Queues.find(vdiskId);
+ Y_VERIFY(queueIt != Queues.end());
+ for (auto& vget : query.Pending) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS34, VDISKP(LogPrefix, "sending TEvVGet"), (SelfId, SelfId()),
+ (Msg, vget->ToString()));
+ Send(queueIt->second.QueueActorId, vget.release());
+ }
+ }
+ }
+
+ void TBlobRecoveryActor::Handle(TEvBlobStorage::TEvVGetResult::TPtr ev) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS35, VDISKP(LogPrefix, "received TEvVGetResult"), (SelfId, SelfId()),
+ (Msg, ev->Get()->ToString()));
+
+ const auto& record = ev->Get()->Record;
+ for (const auto& res : record.GetResult()) {
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(res.GetBlobID());
+ const TLogoBlobID& fullId = id.FullID(); // whole blob id
+ auto r = VGetResultMap.equal_range(fullId);
+ for (auto it = r.first; it != r.second; ) {
+ TPerBlobInfo& info = it->second;
+ if (auto context = info.Context.lock()) { // context acquired, request is still intact
+ auto& item = *info.Item; // only here we can access item, after obtaining context pointer
+ TString data = res.GetBuffer();
+ bool update = false;
+ if (res.GetStatus() == NKikimrProto::OK && data) {
+ item.SetPartData(id, data);
+ update = true;
+ }
+ const bool term = !--info.BlobReplyCounter;
+ if (item.Status == NKikimrProto::UNKNOWN && (term || update)) {
+ const NKikimrProto::EReplyStatus prevStatus = std::exchange(item.Status, ProcessItemData(item));
+ if (item.Status == NKikimrProto::UNKNOWN && term) { // not enough parts to fulfill request
+ item.Status = NKikimrProto::NODATA;
+ }
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS36, VDISKP(LogPrefix, "processing item"),
+ (SelfId, SelfId()), (RequestId, context->RequestId), (Id, id),
+ (Status, res.GetStatus()), (Last, term), (DataUpdated, update),
+ (EntryStatus, prevStatus), (ExitStatus, item.Status));
+ }
+ if (item.Status != NKikimrProto::UNKNOWN && !--context->NumUnrespondedBlobs) {
+ context->SendResult(SelfId());
+ InFlight.erase(context->Iterator);
+ }
+ ++it;
+ } else { // request deadlined or canceled, we erase it from the map
+ it = VGetResultMap.erase(it);
+ }
+ }
+ }
+ }
+
+ NKikimrProto::EReplyStatus TBlobRecoveryActor::ProcessItemData(TEvRecoverBlobResult::TItem& item) {
+ if (item.GetAvailableParts().IsSupersetOf(item.Needed)) {
+ return NKikimrProto::OK;
+ }
+ const ui32 numParts = PopCount(item.PartSet.PartsMask);
+ if (numParts >= Info->Type.MinimalRestorablePartCount()) {
+ TString buffer;
+ Info->Type.RestoreData((TErasureType::ECrcMode)item.BlobId.CrcMode(), item.PartSet, buffer, true,
+ false, true);
+ item.PartSet.PartsMask = (1u << item.PartSet.Parts.size()) - 1;
+ // clear metadata parts in mirror erasures
+ for (ui32 i = 0; i < item.PartSet.Parts.size(); ++i) {
+ if (!Info->Type.PartSize(TLogoBlobID(item.BlobId, i + 1))) {
+ item.PartSet.Parts[i].ReferenceTo(TString());
+ }
+ }
+ return NKikimrProto::OK;
+ } else {
+ return NKikimrProto::UNKNOWN;
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_queue.cpp b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_queue.cpp
index 6e4c2b66758..cdeebab8a4b 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_queue.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_queue.cpp
@@ -1,60 +1,60 @@
-#include "blob_recovery_impl.h"
-
+#include "blob_recovery_impl.h"
+
#include <ydb/core/blobstorage/vdisk/common/vdisk_queues.h>
-namespace NKikimr {
-
- void TBlobRecoveryActor::StartQueues() {
+namespace NKikimr {
+
+ void TBlobRecoveryActor::StartQueues() {
struct TQueueActorIdWrapper {
TQueueInfo Wrap(TActorId &&id) const {
return {std::move(id)};
}
};
- const NBackpressure::TQueueClientId clientId(NBackpressure::EQueueClientType::ReplJob,
- Info->GetTotalVDisksNum() + Info->GetOrderNumber(VCtx->ShortSelfVDisk)); // distinct queue client id
+ const NBackpressure::TQueueClientId clientId(NBackpressure::EQueueClientType::ReplJob,
+ Info->GetTotalVDisksNum() + Info->GetOrderNumber(VCtx->ShortSelfVDisk)); // distinct queue client id
CreateQueuesForVDisks(Queues, SelfId(), Info, VCtx, Info->GetVDisks(), Counters,
clientId, NKikimrBlobStorage::EVDiskQueueId::GetLowRead, "PeerScrub",
TInterconnectChannels::IC_BLOBSTORAGE_ASYNC_DATA, TQueueActorIdWrapper());
- }
-
- void TBlobRecoveryActor::StopQueues() {
- for (const auto& [vdiskId, queue] : Queues) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, queue.QueueActorId, {}, nullptr, 0));
- }
- }
-
- void TBlobRecoveryActor::Handle(TEvVGenerationChange::TPtr ev) {
- STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS28, VDISKP(LogPrefix, "received group generation change notification"),
- (SelfId, SelfId()), (Msg, ev->Get()->ToString()));
- for (const auto& [vdiskId, queue] : Queues) {
- Send(queue.QueueActorId, ev->Get()->Clone());
- }
- Info = ev->Get()->NewInfo;
- }
-
- void TBlobRecoveryActor::Handle(TEvProxyQueueState::TPtr ev) {
- const auto it = Queues.find(ev->Get()->VDiskId);
- Y_VERIFY(it != Queues.end());
- it->second.IsConnected = ev->Get()->IsConnected;
- STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS29, VDISKP(LogPrefix, "BS_QUEUE state update"), (SelfId, SelfId()),
- (VDiskId, it->first), (IsConnected, it->second.IsConnected));
- if (it->second.IsConnected) {
- EvaluateConnectionQuorum();
- }
- }
-
- void TBlobRecoveryActor::EvaluateConnectionQuorum() {
- TBlobStorageGroupInfo::TGroupVDisks connected(&Info->GetTopology());
- connected |= {&Info->GetTopology(), VCtx->ShortSelfVDisk}; // assume this disk as working one; doesn't work for replication
- for (const auto& [vdiskId, queue] : Queues) {
- if (queue.IsConnected) {
- connected |= {&Info->GetTopology(), vdiskId};
- }
- }
- IsConnected = Info->GetQuorumChecker().CheckFailModelForGroup(~connected);
- if (IsConnected) {
- SendPendingQueries();
- }
- }
-
-} // NKikimr
+ }
+
+ void TBlobRecoveryActor::StopQueues() {
+ for (const auto& [vdiskId, queue] : Queues) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, queue.QueueActorId, {}, nullptr, 0));
+ }
+ }
+
+ void TBlobRecoveryActor::Handle(TEvVGenerationChange::TPtr ev) {
+ STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS28, VDISKP(LogPrefix, "received group generation change notification"),
+ (SelfId, SelfId()), (Msg, ev->Get()->ToString()));
+ for (const auto& [vdiskId, queue] : Queues) {
+ Send(queue.QueueActorId, ev->Get()->Clone());
+ }
+ Info = ev->Get()->NewInfo;
+ }
+
+ void TBlobRecoveryActor::Handle(TEvProxyQueueState::TPtr ev) {
+ const auto it = Queues.find(ev->Get()->VDiskId);
+ Y_VERIFY(it != Queues.end());
+ it->second.IsConnected = ev->Get()->IsConnected;
+ STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS29, VDISKP(LogPrefix, "BS_QUEUE state update"), (SelfId, SelfId()),
+ (VDiskId, it->first), (IsConnected, it->second.IsConnected));
+ if (it->second.IsConnected) {
+ EvaluateConnectionQuorum();
+ }
+ }
+
+ void TBlobRecoveryActor::EvaluateConnectionQuorum() {
+ TBlobStorageGroupInfo::TGroupVDisks connected(&Info->GetTopology());
+ connected |= {&Info->GetTopology(), VCtx->ShortSelfVDisk}; // assume this disk as working one; doesn't work for replication
+ for (const auto& [vdiskId, queue] : Queues) {
+ if (queue.IsConnected) {
+ connected |= {&Info->GetTopology(), vdiskId};
+ }
+ }
+ IsConnected = Info->GetQuorumChecker().CheckFailModelForGroup(~connected);
+ if (IsConnected) {
+ SendPendingQueries();
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_request.cpp b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_request.cpp
index ec2e24ff440..5f8e394f171 100644
--- a/ydb/core/blobstorage/vdisk/scrub/blob_recovery_request.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/blob_recovery_request.cpp
@@ -1,66 +1,66 @@
-#include "blob_recovery_impl.h"
-
-namespace NKikimr {
-
- void TBlobRecoveryActor::Handle(TEvRecoverBlob::TPtr ev) {
- auto *msg = ev->Get();
- const ui64 requestId = NextRequestId++;
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS31, VDISKP(LogPrefix, "received TEvRecoverBlob"), (SelfId, SelfId()),
- (Msg, ev->Get()->ToString()), (IsConnected, IsConnected), (WakeupScheduled, WakeupScheduled),
- (RequestId, requestId));
-
- // create in flight context for this request and place it into in flight map
- auto context = std::make_shared<TInFlightContext>(requestId, *ev);
- context->Iterator = InFlight.emplace(msg->Deadline, context);
- context->Result->Deadline = msg->Deadline; // store original deadline in response
-
- // add origin items to result set
- auto& rItems = context->Result->Items;
- for (auto& item : msg->Items) {
- rItems.emplace_back(std::move(item));
+#include "blob_recovery_impl.h"
+
+namespace NKikimr {
+
+ void TBlobRecoveryActor::Handle(TEvRecoverBlob::TPtr ev) {
+ auto *msg = ev->Get();
+ const ui64 requestId = NextRequestId++;
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS31, VDISKP(LogPrefix, "received TEvRecoverBlob"), (SelfId, SelfId()),
+ (Msg, ev->Get()->ToString()), (IsConnected, IsConnected), (WakeupScheduled, WakeupScheduled),
+ (RequestId, requestId));
+
+ // create in flight context for this request and place it into in flight map
+ auto context = std::make_shared<TInFlightContext>(requestId, *ev);
+ context->Iterator = InFlight.emplace(msg->Deadline, context);
+ context->Result->Deadline = msg->Deadline; // store original deadline in response
+
+ // add origin items to result set
+ auto& rItems = context->Result->Items;
+ for (auto& item : msg->Items) {
+ rItems.emplace_back(std::move(item));
AddBlobQuery(rItems.back().BlobId, rItems.back().Needed, context, &rItems.back());
- ++context->NumUnrespondedBlobs;
- }
-
- // send queries to VDisks if necessary
- if (IsConnected) {
- SendPendingQueries();
- }
-
- // create timer to process deadlines if not yet created
- if (!WakeupScheduled) {
- const TInstant now = TActivationContext::Now();
- Schedule(msg->Deadline - now, new TEvents::TEvWakeup);
- WakeupScheduled = true;
- }
- }
-
- void TBlobRecoveryActor::HandleWakeup() {
- const TInstant now = TActivationContext::Now();
-
- // process the in flight request queue and obtain next deadline
- TInFlight::iterator it;
- for (it = InFlight.begin(); it != InFlight.end() && it->first <= now; ++it) {
- for (auto& item : it->second->Result->Items) {
- if (item.Status == NKikimrProto::UNKNOWN) {
- item.Status = NKikimrProto::DEADLINE;
- }
- it->second->SendResult(SelfId());
- }
- }
- InFlight.erase(InFlight.begin(), it);
-
- TInstant deadline = TInstant::Max(); // next deadline
- if (it != InFlight.end()) {
- deadline = it->first;
- }
-
- // reschedule timer
- if (deadline != TInstant::Max()) {
- Schedule(deadline - now, new TEvents::TEvWakeup);
- } else {
- WakeupScheduled = false;
- }
- }
-
-} // NKikimr
+ ++context->NumUnrespondedBlobs;
+ }
+
+ // send queries to VDisks if necessary
+ if (IsConnected) {
+ SendPendingQueries();
+ }
+
+ // create timer to process deadlines if not yet created
+ if (!WakeupScheduled) {
+ const TInstant now = TActivationContext::Now();
+ Schedule(msg->Deadline - now, new TEvents::TEvWakeup);
+ WakeupScheduled = true;
+ }
+ }
+
+ void TBlobRecoveryActor::HandleWakeup() {
+ const TInstant now = TActivationContext::Now();
+
+ // process the in flight request queue and obtain next deadline
+ TInFlight::iterator it;
+ for (it = InFlight.begin(); it != InFlight.end() && it->first <= now; ++it) {
+ for (auto& item : it->second->Result->Items) {
+ if (item.Status == NKikimrProto::UNKNOWN) {
+ item.Status = NKikimrProto::DEADLINE;
+ }
+ it->second->SendResult(SelfId());
+ }
+ }
+ InFlight.erase(InFlight.begin(), it);
+
+ TInstant deadline = TInstant::Max(); // next deadline
+ if (it != InFlight.end()) {
+ deadline = it->first;
+ }
+
+ // reschedule timer
+ if (deadline != TInstant::Max()) {
+ Schedule(deadline - now, new TEvents::TEvWakeup);
+ } else {
+ WakeupScheduled = false;
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/defs.h b/ydb/core/blobstorage/vdisk/scrub/defs.h
index dd2f3055cf3..88df88c690f 100644
--- a/ydb/core/blobstorage/vdisk/scrub/defs.h
+++ b/ydb/core/blobstorage/vdisk/scrub/defs.h
@@ -1,7 +1,7 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/blobstorage/vdisk/defs.h>
-
+
#include <ydb/core/blobstorage/vdisk/common/vdisk_context.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_pdiskctx.h>
#include <ydb/core/blobstorage/vdisk/common/vdisk_lsnmngr.h>
@@ -11,4 +11,4 @@
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_sets.h>
#include <ydb/core/blobstorage/backpressure/queue_backpressure_client.h>
#include <ydb/core/util/stlog.h>
-#include <library/cpp/actors/core/actor_coroutine.h>
+#include <library/cpp/actors/core/actor_coroutine.h>
diff --git a/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.cpp b/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.cpp
index 45af3970938..8759e6f4e6b 100644
--- a/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.cpp
@@ -1,339 +1,339 @@
-#include "restore_corrupted_blob_actor.h"
-
-namespace NKikimr {
-
- class TRestoreCorruptedBlobActor : public TActorBootstrapped<TRestoreCorruptedBlobActor> {
- const TActorId SkeletonId;
- const TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TIntrusivePtr<TVDiskContext> VCtx;
- const TString& LogPrefix;
+#include "restore_corrupted_blob_actor.h"
+
+namespace NKikimr {
+
+ class TRestoreCorruptedBlobActor : public TActorBootstrapped<TRestoreCorruptedBlobActor> {
+ const TActorId SkeletonId;
+ const TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TIntrusivePtr<TVDiskContext> VCtx;
+ const TString& LogPrefix;
const TPDiskCtxPtr PDiskCtx;
- const TInstant Deadline;
- std::vector<TEvRecoverBlobResult::TItem> Items;
- const bool WriteRestoredParts;
- const bool ReportNonrestoredParts;
- const TActorId Sender;
- const ui64 Cookie;
- bool AllQueriesDone = false;
- ui32 ReadsPending = 0;
- ui32 WritesPending = 0;
- std::optional<THullDsSnap> Snap;
-
- enum {
- EvIssueQuery = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
- struct TEvIssueQuery : TEventLocal<TEvIssueQuery, EvIssueQuery> {};
-
- struct TReadCmd {
- TDiskPart Location;
- TEvRestoreCorruptedBlobResult::TItem *Item;
- NMatrix::TVectorType Parts;
-
- TReadCmd(TDiskPart location, TEvRestoreCorruptedBlobResult::TItem *item, NMatrix::TVectorType parts)
- : Location(location)
- , Item(item)
- , Parts(parts)
- {}
- };
-
- std::vector<TReadCmd> ReadQ;
-
- struct TDataExtractorMerger {
- std::vector<TReadCmd>& ReadQ;
- const TBlobStorageGroupType GType;
- TEvRestoreCorruptedBlobResult::TItem *Item = nullptr;
-
- static constexpr bool HaveToMergeData() { return true; }
-
- void Begin(TEvRestoreCorruptedBlobResult::TItem *item) {
- Item = item;
- }
-
- void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& /*key*/,
+ const TInstant Deadline;
+ std::vector<TEvRecoverBlobResult::TItem> Items;
+ const bool WriteRestoredParts;
+ const bool ReportNonrestoredParts;
+ const TActorId Sender;
+ const ui64 Cookie;
+ bool AllQueriesDone = false;
+ ui32 ReadsPending = 0;
+ ui32 WritesPending = 0;
+ std::optional<THullDsSnap> Snap;
+
+ enum {
+ EvIssueQuery = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+ struct TEvIssueQuery : TEventLocal<TEvIssueQuery, EvIssueQuery> {};
+
+ struct TReadCmd {
+ TDiskPart Location;
+ TEvRestoreCorruptedBlobResult::TItem *Item;
+ NMatrix::TVectorType Parts;
+
+ TReadCmd(TDiskPart location, TEvRestoreCorruptedBlobResult::TItem *item, NMatrix::TVectorType parts)
+ : Location(location)
+ , Item(item)
+ , Parts(parts)
+ {}
+ };
+
+ std::vector<TReadCmd> ReadQ;
+
+ struct TDataExtractorMerger {
+ std::vector<TReadCmd>& ReadQ;
+ const TBlobStorageGroupType GType;
+ TEvRestoreCorruptedBlobResult::TItem *Item = nullptr;
+
+ static constexpr bool HaveToMergeData() { return true; }
+
+ void Begin(TEvRestoreCorruptedBlobResult::TItem *item) {
+ Item = item;
+ }
+
+ void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& /*key*/,
ui64 /*circaLsn*/) {
- const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
- if ((local & Item->Needed).Empty()) {
- return; // no useful parts here
- }
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, outbound);
- switch (extr.BlobType) {
- case TBlobType::DiskBlob:
- case TBlobType::HugeBlob:
- ReadQ.emplace_back(extr.SwearOne(), Item, local);
- break;
-
- case TBlobType::ManyHugeBlobs:
- for (ui32 i = local.FirstPosition(); i != local.GetSize(); i = local.NextPosition(i), ++extr.Begin) {
- if (Item->Needed.Get(i)) {
- ReadQ.emplace_back(*extr.Begin, Item, NMatrix::TVectorType::MakeOneHot(i, local.GetSize()));
- }
- }
- break;
-
- case TBlobType::MemBlob:
- Y_FAIL();
- }
- }
-
- void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key, ui64 /*lsn*/) {
- if (data) {
- const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
- TDiskBlob blob(data, local, GType, key.LogoBlobID());
- for (auto it = blob.begin(); it != blob.end(); ++it) {
- if (Item->Needed.Get(it.GetPartId() - 1)) {
- Item->SetPartData(TLogoBlobID(key.LogoBlobID(), it.GetPartId()), it.GetPart().ConvertToString());
- }
- }
- } else {
- // process possible on-disk huge blob stored in fresh segment
- AddFromSegment(memRec, nullptr, key, Max<ui64>());
- }
- }
- };
-
- public:
- TRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
+ const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
+ if ((local & Item->Needed).Empty()) {
+ return; // no useful parts here
+ }
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, outbound);
+ switch (extr.BlobType) {
+ case TBlobType::DiskBlob:
+ case TBlobType::HugeBlob:
+ ReadQ.emplace_back(extr.SwearOne(), Item, local);
+ break;
+
+ case TBlobType::ManyHugeBlobs:
+ for (ui32 i = local.FirstPosition(); i != local.GetSize(); i = local.NextPosition(i), ++extr.Begin) {
+ if (Item->Needed.Get(i)) {
+ ReadQ.emplace_back(*extr.Begin, Item, NMatrix::TVectorType::MakeOneHot(i, local.GetSize()));
+ }
+ }
+ break;
+
+ case TBlobType::MemBlob:
+ Y_FAIL();
+ }
+ }
+
+ void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key, ui64 /*lsn*/) {
+ if (data) {
+ const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
+ TDiskBlob blob(data, local, GType, key.LogoBlobID());
+ for (auto it = blob.begin(); it != blob.end(); ++it) {
+ if (Item->Needed.Get(it.GetPartId() - 1)) {
+ Item->SetPartData(TLogoBlobID(key.LogoBlobID(), it.GetPartId()), it.GetPart().ConvertToString());
+ }
+ }
+ } else {
+ // process possible on-disk huge blob stored in fresh segment
+ AddFromSegment(memRec, nullptr, key, Max<ui64>());
+ }
+ }
+ };
+
+ public:
+ TRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
TPDiskCtxPtr pdiskCtx)
- : SkeletonId(skeletonId)
- , Info(std::move(info))
- , VCtx(std::move(vctx))
- , LogPrefix(VCtx->VDiskLogPrefix)
- , PDiskCtx(std::move(pdiskCtx))
- , Deadline(ev->Get()->Deadline)
- , WriteRestoredParts(ev->Get()->WriteRestoredParts)
- , ReportNonrestoredParts(ev->Get()->ReportNonrestoredParts)
- , Sender(ev->Sender)
- , Cookie(ev->Cookie)
- {
- auto& items = ev->Get()->Items;
- Items.reserve(items.size());
- for (auto& item : items) {
- Items.push_back(std::move(item));
- }
- }
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_RESTORE_CORRUPTED_BLOB_ACTOR;
- }
-
- void Bootstrap() {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS09, VDISKP(LogPrefix, "bootstrapping TRestoreCorruptedBlobActor"),
- (SelfId, SelfId()));
- Send(SkeletonId, new TEvTakeHullSnapshot(false));
- Become(&TThis::StateFunc, Deadline, new TEvents::TEvWakeup);
- }
-
- void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
- Snap.emplace(std::move(ev->Get()->Snap));
- Snap->BlocksSnap.Destroy();
- Snap->BarriersSnap.Destroy();
- using TLevelIndexSnapshot = NKikimr::TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- TLevelIndexSnapshot::TForwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
- TDataExtractorMerger merger{ReadQ, Info->Type};
- for (auto& item : Items) {
- iter.Seek(item.BlobId);
- if (iter.Valid() && iter.GetCurKey() == item.BlobId) { // item found, process through merger to extract data parts
- merger.Begin(&item);
- iter.PutToMerger(&merger);
- } else { // item not found in local metabase -- report error for this one
- item.Status = NKikimrProto::ERROR;
- }
- }
-
- // filter out the read queue -- remove items that are already available or not needed
- auto remove = [](const TReadCmd& item) {
- const NMatrix::TVectorType missing = item.Item->Needed - item.Item->GetAvailableParts();
- return (missing & item.Parts).Empty() || item.Location == item.Item->CorruptedPart;
- };
- ReadQ.erase(std::remove_if(ReadQ.begin(), ReadQ.end(), remove), ReadQ.end());
-
- if (ReadQ.empty()) { // nothing to read, issue restore queries
- Snap.reset();
- IssueQuery();
- } else { // some data to read, generate reads
- for (auto& cmd : ReadQ) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS18, VDISKP(LogPrefix, "sending read to PDisk"),
- (SelfId, SelfId()), (Location, cmd.Location), (BlobId, cmd.Item->BlobId), (Parts, cmd.Parts));
- auto msg = std::make_unique<NPDisk::TEvChunkRead>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound,
- cmd.Location.ChunkIdx, cmd.Location.Offset, cmd.Location.Size, NPriRead::HullLow, &cmd);
- Send(PDiskCtx->PDiskId, msg.release());
- ++ReadsPending;
- }
- }
- }
-
- void Handle(NPDisk::TEvChunkReadResult::TPtr ev) {
- Y_VERIFY(ReadsPending);
- --ReadsPending;
-
- auto *msg = ev->Get();
- TReadCmd *cmd = static_cast<TReadCmd*>(msg->Cookie);
- if (msg->Status == NKikimrProto::OK) {
- auto& item = *cmd->Item;
- TRope rope(msg->Data.ToString());
- TDiskBlob blob(&rope, cmd->Parts, Info->Type, item.BlobId);
- for (auto it = blob.begin(); it != blob.end(); ++it) {
- if (item.Needed.Get(it.GetPartId() - 1)) {
- item.SetPartData(TLogoBlobID(item.BlobId, it.GetPartId()), it.GetPart().ConvertToString());
- }
- }
- const NMatrix::TVectorType& avail = item.GetAvailableParts();
- if (avail.IsSupersetOf(item.Needed)) {
- item.Status = NKikimrProto::OK; // item has been fully read from local sources
- }
- } else {
- STLOG(PRI_WARN, BS_VDISK_SCRUB, VDS26, VDISKP(LogPrefix, "failed to read data from PDisk"),
- (SelfId, SelfId()), (Location, cmd->Location), (BlobId, cmd->Item->BlobId), (Parts, cmd->Parts),
- (Status, msg->Status));
- }
-
- if (!ReadsPending) {
- Snap.reset();
- IssueQuery();
- }
- }
-
- void IssueQuery() {
- std::unique_ptr<TEvRecoverBlob> ev;
- for (size_t i = 0; i < Items.size(); ++i) {
- const auto& item = Items[i];
- if (item.Status == NKikimrProto::UNKNOWN) {
- if (!ev) {
- ev.reset(new TEvRecoverBlob);
- ev->Deadline = Deadline;
- }
- ev->Items.emplace_back(item.BlobId, TDataPartSet(item.PartSet), item.Needed, TDiskPart(), i);
- }
- }
- if (ev) {
- Send(SkeletonId, ev.release());
- } else {
- AllQueriesDone = true;
- TryToComplete();
- }
- }
-
- void TryToComplete() {
- if (AllQueriesDone && (!WriteRestoredParts || !WritesPending)) {
- PassAway();
- }
- }
-
- void Handle(TEvRecoverBlobResult::TPtr ev) {
- for (auto& item : ev->Get()->Items) {
- auto& myItem = Items[item.Cookie];
- Y_VERIFY(myItem.Status == NKikimrProto::UNKNOWN);
- myItem.PartSet = std::move(item.PartSet);
- if (item.Status != NKikimrProto::NODATA) { // we keep trying to fetch NODATA's till deadline
- myItem.Status = item.Status;
- if (myItem.Status == NKikimrProto::OK && WriteRestoredParts) {
- IssueWrite(myItem, item.Cookie);
- }
- }
- }
- for (const auto& item : Items) {
- if (item.Status == NKikimrProto::UNKNOWN) {
- return Schedule(TDuration::Seconds(1), new TEvIssueQuery);
- }
- }
- IssueQuery();
- }
-
- void IssueWrite(TEvRestoreCorruptedBlobResult::TItem& item, ui64 index) {
- const TVDiskID& vdiskId = Info->GetVDiskId(VCtx->ShortSelfVDisk);
- for (ui32 i = item.Needed.FirstPosition(); i != item.Needed.GetSize(); i = item.Needed.NextPosition(i)) {
- const TLogoBlobID blobId(item.BlobId, i + 1);
- const TString& buffer = item.GetPartData(blobId);
- Y_VERIFY(buffer.size() == Info->Type.PartSize(blobId));
- Y_VERIFY(WriteRestoredParts);
- auto ev = std::make_unique<TEvBlobStorage::TEvVPut>(blobId, buffer, vdiskId, true, &index, Deadline,
- NKikimrBlobStorage::EPutHandleClass::AsyncBlob);
- Send(SkeletonId, ev.release());
- ++WritesPending;
- }
- }
-
- void Handle(TEvBlobStorage::TEvVPutResult::TPtr ev) {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS37, VDISKP(LogPrefix, "received TEvVPutResult"), (SelfId, SelfId()),
- (Msg, ev->Get()->ToString()));
- Y_VERIFY(WritesPending);
- --WritesPending;
- const auto& record = ev->Get()->Record;
- auto& item = Items[record.GetCookie()];
- switch (record.GetStatus()) {
- case NKikimrProto::RACE:
- case NKikimrProto::ERROR:
- case NKikimrProto::OUT_OF_SPACE:
- case NKikimrProto::VDISK_ERROR_STATE:
- STLOG(PRI_ERROR, BS_VDISK_SCRUB, VDS10, VDISKP(LogPrefix, "failed to restore blob"),
- (SelfId, SelfId()), (Msg, ev->Get()->ToString()));
- if (item.Status == NKikimrProto::OK) {
- item.Status = NKikimrProto::ERROR;
- }
- break;
-
- case NKikimrProto::DEADLINE:
- item.Status = NKikimrProto::DEADLINE;
- break;
-
- case NKikimrProto::OK: // keep item status untouched
- break;
-
- default:
- Y_FAIL_S("unexpected TEvVPutResult status TEvVPutResult# " << ev->Get()->ToString());
- }
- TryToComplete();
- }
-
- void PassAway() override {
- STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS15, VDISKP(LogPrefix, "TRestoreCorruptedBlobActor terminating"),
- (SelfId, SelfId()));
- ReduceStatus(NKikimrProto::ERROR);
-
- if (ReportNonrestoredParts) {
- std::vector<TEvNonrestoredCorruptedBlobNotify::TItem> nonrestoredItems;
- for (const auto& item : Items) {
- if (item.Status != NKikimrProto::OK) {
- nonrestoredItems.emplace_back(item.BlobId, item.Needed, item.CorruptedPart);
- }
- }
- if (!nonrestoredItems.empty()) {
- Send(SkeletonId, new TEvNonrestoredCorruptedBlobNotify(std::move(nonrestoredItems)));
- }
- }
-
- Send(Sender, new TEvRestoreCorruptedBlobResult(std::move(Items)), 0, Cookie);
- TActorBootstrapped::PassAway();
- }
-
- void HandleWakeup() {
- ReduceStatus(NKikimrProto::DEADLINE);
- PassAway();
- }
-
- void ReduceStatus(NKikimrProto::EReplyStatus status) {
- for (auto& item : Items) {
- item.Status = item.Status != NKikimrProto::UNKNOWN ? item.Status : status;
- }
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvTakeHullSnapshotResult, Handle);
- hFunc(NPDisk::TEvChunkReadResult, Handle);
- hFunc(TEvRecoverBlobResult, Handle);
- cFunc(EvIssueQuery, IssueQuery);
- hFunc(TEvBlobStorage::TEvVPutResult, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
- };
-
- IActor *CreateRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
+ : SkeletonId(skeletonId)
+ , Info(std::move(info))
+ , VCtx(std::move(vctx))
+ , LogPrefix(VCtx->VDiskLogPrefix)
+ , PDiskCtx(std::move(pdiskCtx))
+ , Deadline(ev->Get()->Deadline)
+ , WriteRestoredParts(ev->Get()->WriteRestoredParts)
+ , ReportNonrestoredParts(ev->Get()->ReportNonrestoredParts)
+ , Sender(ev->Sender)
+ , Cookie(ev->Cookie)
+ {
+ auto& items = ev->Get()->Items;
+ Items.reserve(items.size());
+ for (auto& item : items) {
+ Items.push_back(std::move(item));
+ }
+ }
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_RESTORE_CORRUPTED_BLOB_ACTOR;
+ }
+
+ void Bootstrap() {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS09, VDISKP(LogPrefix, "bootstrapping TRestoreCorruptedBlobActor"),
+ (SelfId, SelfId()));
+ Send(SkeletonId, new TEvTakeHullSnapshot(false));
+ Become(&TThis::StateFunc, Deadline, new TEvents::TEvWakeup);
+ }
+
+ void Handle(TEvTakeHullSnapshotResult::TPtr ev) {
+ Snap.emplace(std::move(ev->Get()->Snap));
+ Snap->BlocksSnap.Destroy();
+ Snap->BarriersSnap.Destroy();
+ using TLevelIndexSnapshot = NKikimr::TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ TLevelIndexSnapshot::TForwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
+ TDataExtractorMerger merger{ReadQ, Info->Type};
+ for (auto& item : Items) {
+ iter.Seek(item.BlobId);
+ if (iter.Valid() && iter.GetCurKey() == item.BlobId) { // item found, process through merger to extract data parts
+ merger.Begin(&item);
+ iter.PutToMerger(&merger);
+ } else { // item not found in local metabase -- report error for this one
+ item.Status = NKikimrProto::ERROR;
+ }
+ }
+
+ // filter out the read queue -- remove items that are already available or not needed
+ auto remove = [](const TReadCmd& item) {
+ const NMatrix::TVectorType missing = item.Item->Needed - item.Item->GetAvailableParts();
+ return (missing & item.Parts).Empty() || item.Location == item.Item->CorruptedPart;
+ };
+ ReadQ.erase(std::remove_if(ReadQ.begin(), ReadQ.end(), remove), ReadQ.end());
+
+ if (ReadQ.empty()) { // nothing to read, issue restore queries
+ Snap.reset();
+ IssueQuery();
+ } else { // some data to read, generate reads
+ for (auto& cmd : ReadQ) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS18, VDISKP(LogPrefix, "sending read to PDisk"),
+ (SelfId, SelfId()), (Location, cmd.Location), (BlobId, cmd.Item->BlobId), (Parts, cmd.Parts));
+ auto msg = std::make_unique<NPDisk::TEvChunkRead>(PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound,
+ cmd.Location.ChunkIdx, cmd.Location.Offset, cmd.Location.Size, NPriRead::HullLow, &cmd);
+ Send(PDiskCtx->PDiskId, msg.release());
+ ++ReadsPending;
+ }
+ }
+ }
+
+ void Handle(NPDisk::TEvChunkReadResult::TPtr ev) {
+ Y_VERIFY(ReadsPending);
+ --ReadsPending;
+
+ auto *msg = ev->Get();
+ TReadCmd *cmd = static_cast<TReadCmd*>(msg->Cookie);
+ if (msg->Status == NKikimrProto::OK) {
+ auto& item = *cmd->Item;
+ TRope rope(msg->Data.ToString());
+ TDiskBlob blob(&rope, cmd->Parts, Info->Type, item.BlobId);
+ for (auto it = blob.begin(); it != blob.end(); ++it) {
+ if (item.Needed.Get(it.GetPartId() - 1)) {
+ item.SetPartData(TLogoBlobID(item.BlobId, it.GetPartId()), it.GetPart().ConvertToString());
+ }
+ }
+ const NMatrix::TVectorType& avail = item.GetAvailableParts();
+ if (avail.IsSupersetOf(item.Needed)) {
+ item.Status = NKikimrProto::OK; // item has been fully read from local sources
+ }
+ } else {
+ STLOG(PRI_WARN, BS_VDISK_SCRUB, VDS26, VDISKP(LogPrefix, "failed to read data from PDisk"),
+ (SelfId, SelfId()), (Location, cmd->Location), (BlobId, cmd->Item->BlobId), (Parts, cmd->Parts),
+ (Status, msg->Status));
+ }
+
+ if (!ReadsPending) {
+ Snap.reset();
+ IssueQuery();
+ }
+ }
+
+ void IssueQuery() {
+ std::unique_ptr<TEvRecoverBlob> ev;
+ for (size_t i = 0; i < Items.size(); ++i) {
+ const auto& item = Items[i];
+ if (item.Status == NKikimrProto::UNKNOWN) {
+ if (!ev) {
+ ev.reset(new TEvRecoverBlob);
+ ev->Deadline = Deadline;
+ }
+ ev->Items.emplace_back(item.BlobId, TDataPartSet(item.PartSet), item.Needed, TDiskPart(), i);
+ }
+ }
+ if (ev) {
+ Send(SkeletonId, ev.release());
+ } else {
+ AllQueriesDone = true;
+ TryToComplete();
+ }
+ }
+
+ void TryToComplete() {
+ if (AllQueriesDone && (!WriteRestoredParts || !WritesPending)) {
+ PassAway();
+ }
+ }
+
+ void Handle(TEvRecoverBlobResult::TPtr ev) {
+ for (auto& item : ev->Get()->Items) {
+ auto& myItem = Items[item.Cookie];
+ Y_VERIFY(myItem.Status == NKikimrProto::UNKNOWN);
+ myItem.PartSet = std::move(item.PartSet);
+ if (item.Status != NKikimrProto::NODATA) { // we keep trying to fetch NODATA's till deadline
+ myItem.Status = item.Status;
+ if (myItem.Status == NKikimrProto::OK && WriteRestoredParts) {
+ IssueWrite(myItem, item.Cookie);
+ }
+ }
+ }
+ for (const auto& item : Items) {
+ if (item.Status == NKikimrProto::UNKNOWN) {
+ return Schedule(TDuration::Seconds(1), new TEvIssueQuery);
+ }
+ }
+ IssueQuery();
+ }
+
+ void IssueWrite(TEvRestoreCorruptedBlobResult::TItem& item, ui64 index) {
+ const TVDiskID& vdiskId = Info->GetVDiskId(VCtx->ShortSelfVDisk);
+ for (ui32 i = item.Needed.FirstPosition(); i != item.Needed.GetSize(); i = item.Needed.NextPosition(i)) {
+ const TLogoBlobID blobId(item.BlobId, i + 1);
+ const TString& buffer = item.GetPartData(blobId);
+ Y_VERIFY(buffer.size() == Info->Type.PartSize(blobId));
+ Y_VERIFY(WriteRestoredParts);
+ auto ev = std::make_unique<TEvBlobStorage::TEvVPut>(blobId, buffer, vdiskId, true, &index, Deadline,
+ NKikimrBlobStorage::EPutHandleClass::AsyncBlob);
+ Send(SkeletonId, ev.release());
+ ++WritesPending;
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVPutResult::TPtr ev) {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS37, VDISKP(LogPrefix, "received TEvVPutResult"), (SelfId, SelfId()),
+ (Msg, ev->Get()->ToString()));
+ Y_VERIFY(WritesPending);
+ --WritesPending;
+ const auto& record = ev->Get()->Record;
+ auto& item = Items[record.GetCookie()];
+ switch (record.GetStatus()) {
+ case NKikimrProto::RACE:
+ case NKikimrProto::ERROR:
+ case NKikimrProto::OUT_OF_SPACE:
+ case NKikimrProto::VDISK_ERROR_STATE:
+ STLOG(PRI_ERROR, BS_VDISK_SCRUB, VDS10, VDISKP(LogPrefix, "failed to restore blob"),
+ (SelfId, SelfId()), (Msg, ev->Get()->ToString()));
+ if (item.Status == NKikimrProto::OK) {
+ item.Status = NKikimrProto::ERROR;
+ }
+ break;
+
+ case NKikimrProto::DEADLINE:
+ item.Status = NKikimrProto::DEADLINE;
+ break;
+
+ case NKikimrProto::OK: // keep item status untouched
+ break;
+
+ default:
+ Y_FAIL_S("unexpected TEvVPutResult status TEvVPutResult# " << ev->Get()->ToString());
+ }
+ TryToComplete();
+ }
+
+ void PassAway() override {
+ STLOG(PRI_DEBUG, BS_VDISK_SCRUB, VDS15, VDISKP(LogPrefix, "TRestoreCorruptedBlobActor terminating"),
+ (SelfId, SelfId()));
+ ReduceStatus(NKikimrProto::ERROR);
+
+ if (ReportNonrestoredParts) {
+ std::vector<TEvNonrestoredCorruptedBlobNotify::TItem> nonrestoredItems;
+ for (const auto& item : Items) {
+ if (item.Status != NKikimrProto::OK) {
+ nonrestoredItems.emplace_back(item.BlobId, item.Needed, item.CorruptedPart);
+ }
+ }
+ if (!nonrestoredItems.empty()) {
+ Send(SkeletonId, new TEvNonrestoredCorruptedBlobNotify(std::move(nonrestoredItems)));
+ }
+ }
+
+ Send(Sender, new TEvRestoreCorruptedBlobResult(std::move(Items)), 0, Cookie);
+ TActorBootstrapped::PassAway();
+ }
+
+ void HandleWakeup() {
+ ReduceStatus(NKikimrProto::DEADLINE);
+ PassAway();
+ }
+
+ void ReduceStatus(NKikimrProto::EReplyStatus status) {
+ for (auto& item : Items) {
+ item.Status = item.Status != NKikimrProto::UNKNOWN ? item.Status : status;
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvTakeHullSnapshotResult, Handle);
+ hFunc(NPDisk::TEvChunkReadResult, Handle);
+ hFunc(TEvRecoverBlobResult, Handle);
+ cFunc(EvIssueQuery, IssueQuery);
+ hFunc(TEvBlobStorage::TEvVPutResult, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+ };
+
+ IActor *CreateRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
TPDiskCtxPtr pdiskCtx) {
- return new TRestoreCorruptedBlobActor(skeletonId, ev, std::move(info), std::move(vctx), std::move(pdiskCtx));
- }
-
-} // NKikimr
+ return new TRestoreCorruptedBlobActor(skeletonId, ev, std::move(info), std::move(vctx), std::move(pdiskCtx));
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h b/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h
index cb8a48fc3ae..86923f3cac8 100644
--- a/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h
+++ b/ydb/core/blobstorage/vdisk/scrub/restore_corrupted_blob_actor.h
@@ -1,55 +1,55 @@
-#pragma once
-
-#include "defs.h"
-#include "blob_recovery.h"
-
-namespace NKikimr {
-
- struct TEvRestoreCorruptedBlob : TEventLocal<TEvRestoreCorruptedBlob, TEvBlobStorage::EvRestoreCorruptedBlob> {
- using TItem = TEvRecoverBlob::TItem;
- TInstant Deadline;
- std::vector<TItem> Items;
- bool WriteRestoredParts; // if true, then all restored parts are written back to VDisk
- bool ReportNonrestoredParts; // if true, nonrestored parts are reported to scrub actor for scrubbing
-
- TEvRestoreCorruptedBlob(TInstant deadline, std::vector<TItem>&& items, bool writeRestoredParts, bool reportNonrestoredParts)
- : Deadline(deadline)
- , Items(std::move(items))
- , WriteRestoredParts(writeRestoredParts)
- , ReportNonrestoredParts(reportNonrestoredParts)
- {}
- };
-
- struct TEvRestoreCorruptedBlobResult : TEventLocal<TEvRestoreCorruptedBlobResult, TEvBlobStorage::EvRestoreCorruptedBlobResult> {
- using TItem = TEvRecoverBlobResult::TItem;
- std::vector<TItem> Items; // status is either OK, ERROR, or DEADLINE
-
- TEvRestoreCorruptedBlobResult(std::vector<TItem>&& items)
- : Items(std::move(items))
- {}
- };
-
- struct TEvNonrestoredCorruptedBlobNotify : TEventLocal<TEvNonrestoredCorruptedBlobNotify, TEvBlobStorage::EvNonrestoredCorruptedBlobNotify> {
- struct TItem {
- TLogoBlobID BlobId;
- NMatrix::TVectorType UnreadableParts;
- TDiskPart CorruptedPart;
-
- TItem(const TLogoBlobID& blobId, NMatrix::TVectorType unreadableParts, TDiskPart corruptedPart)
- : BlobId(blobId)
- , UnreadableParts(unreadableParts)
- , CorruptedPart(corruptedPart)
- {}
- };
- std::vector<TItem> Items;
-
- TEvNonrestoredCorruptedBlobNotify(std::vector<TItem>&& items)
- : Items(std::move(items))
- {}
- };
-
- IActor *CreateRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
+#pragma once
+
+#include "defs.h"
+#include "blob_recovery.h"
+
+namespace NKikimr {
+
+ struct TEvRestoreCorruptedBlob : TEventLocal<TEvRestoreCorruptedBlob, TEvBlobStorage::EvRestoreCorruptedBlob> {
+ using TItem = TEvRecoverBlob::TItem;
+ TInstant Deadline;
+ std::vector<TItem> Items;
+ bool WriteRestoredParts; // if true, then all restored parts are written back to VDisk
+ bool ReportNonrestoredParts; // if true, nonrestored parts are reported to scrub actor for scrubbing
+
+ TEvRestoreCorruptedBlob(TInstant deadline, std::vector<TItem>&& items, bool writeRestoredParts, bool reportNonrestoredParts)
+ : Deadline(deadline)
+ , Items(std::move(items))
+ , WriteRestoredParts(writeRestoredParts)
+ , ReportNonrestoredParts(reportNonrestoredParts)
+ {}
+ };
+
+ struct TEvRestoreCorruptedBlobResult : TEventLocal<TEvRestoreCorruptedBlobResult, TEvBlobStorage::EvRestoreCorruptedBlobResult> {
+ using TItem = TEvRecoverBlobResult::TItem;
+ std::vector<TItem> Items; // status is either OK, ERROR, or DEADLINE
+
+ TEvRestoreCorruptedBlobResult(std::vector<TItem>&& items)
+ : Items(std::move(items))
+ {}
+ };
+
+ struct TEvNonrestoredCorruptedBlobNotify : TEventLocal<TEvNonrestoredCorruptedBlobNotify, TEvBlobStorage::EvNonrestoredCorruptedBlobNotify> {
+ struct TItem {
+ TLogoBlobID BlobId;
+ NMatrix::TVectorType UnreadableParts;
+ TDiskPart CorruptedPart;
+
+ TItem(const TLogoBlobID& blobId, NMatrix::TVectorType unreadableParts, TDiskPart corruptedPart)
+ : BlobId(blobId)
+ , UnreadableParts(unreadableParts)
+ , CorruptedPart(corruptedPart)
+ {}
+ };
+ std::vector<TItem> Items;
+
+ TEvNonrestoredCorruptedBlobNotify(std::vector<TItem>&& items)
+ : Items(std::move(items))
+ {}
+ };
+
+ IActor *CreateRestoreCorruptedBlobActor(TActorId skeletonId, TEvRestoreCorruptedBlob::TPtr& ev,
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TIntrusivePtr<TVDiskContext> vctx,
TPDiskCtxPtr pdiskCtx);
-
-} // NKikimr
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor.cpp
index e71b15c833a..4b446cf3492 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor.cpp
@@ -1,246 +1,246 @@
-#include "scrub_actor.h"
-#include "scrub_actor_impl.h"
-#include "blob_recovery.h"
-#include "restore_corrupted_blob_actor.h"
-
-namespace NKikimr {
-
- TScrubCoroImpl::TScrubCoroImpl(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn)
- : TActorCoroImpl(65536)
- , ScrubCtx(std::move(scrubCtx))
- , VCtx(ScrubCtx->VCtx)
- , Info(ScrubCtx->Info)
- , LogPrefix(VCtx->VDiskLogPrefix)
- , Counters(VCtx->VDiskCounters->GetSubgroup("subsystem", "scrub"))
- , SstProcessed(Counters->GetCounter("SstProcessed", true))
- , HugeBlobsRead(Counters->GetCounter("HugeBlobsRead", true))
- , HugeBlobBytesRead(Counters->GetCounter("HugeBlobBytesRead", true))
- , SmallBlobIntervalsRead(Counters->GetCounter("SmallBlobIntervalsRead", true))
- , SmallBlobIntervalBytesRead(Counters->GetCounter("SmallBlobIntervalBytesRead", true))
- , SmallBlobsRead(Counters->GetCounter("SmallBlobsRead", true))
- , SmallBlobBytesRead(Counters->GetCounter("SmallBlobBytesRead", true))
- , UnreadableBlobsFound(Counters->GetCounter("UnreadableBlobsFound", false))
- , BlobsFixed(Counters->GetCounter("BlobsFixed", false))
- , Arena(&TScrubCoroImpl::AllocateRopeArenaChunk)
- , ScrubEntrypoint(std::move(scrubEntrypoint))
- , ScrubEntrypointLsn(scrubEntrypointLsn)
- {}
-
- void TScrubCoroImpl::ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) {
- switch (const ui32 type = ev->GetTypeRewrite()) {
- hFunc(NMon::TEvHttpInfo, Handle);
- fFunc(TEvBlobStorage::EvScrubAwait, HandleScrubAwait);
- fFunc(TEvBlobStorage::EvVGenerationChange, ForwardToBlobRecoveryActor);
- fFunc(TEvBlobStorage::EvRecoverBlob, ForwardToBlobRecoveryActor);
- hFunc(TEvRestoreCorruptedBlobResult, Handle);
- hFunc(TEvNonrestoredCorruptedBlobNotify, Handle);
- cFunc(EvGenerateRestoreCorruptedBlobQuery, HandleGenerateRestoreCorruptedBlobQuery);
- hFunc(NPDisk::TEvLogResult, Handle);
- hFunc(NPDisk::TEvCutLog, Handle);
-
- default:
- Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
- }
- }
-
- void TScrubCoroImpl::HandleScrubAwait(TAutoPtr<IEventHandle> ev) {
- ScrubAwaitQueue.emplace(ScrubIterationCounter + 1, std::make_pair(ev->Sender, ev->Cookie));
- }
-
- void TScrubCoroImpl::ForwardToBlobRecoveryActor(TAutoPtr<IEventHandle> ev) {
- Send(ev->Forward(BlobRecoveryActorId));
- }
-
- void TScrubCoroImpl::Run() {
- // unpack entrypoint
- for (const auto& item : ScrubEntrypoint.GetUnreadableBlobs()) {
- UnreadableBlobs.emplace(LogoBlobIDFromLogoBlobID(item.GetBlobId()), TUnreadableBlobState(
- NMatrix::TVectorType(item.GetUnreadableParts(), Info->Type.TotalPartCount()),
- item.GetCorruptedPart()));
- }
-
- // update log cutter
- if (ScrubEntrypointLsn) {
- Send(ScrubCtx->LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::Scrub, ScrubEntrypointLsn));
- }
-
- BlobRecoveryActorId = Register(CreateBlobRecoveryActor(VCtx, Info, Counters));
- try {
- for (;;) {
- RequestState();
- const TInstant start = TActorCoroImpl::Now();
- const TInstant end = start + TDuration::Seconds(30);
- do {
- Quantum();
- Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(UnreadableBlobs.size()));
- } while (State && TActorCoroImpl::Now() < end);
- Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(UnreadableBlobs.size()));
- CommitStateUpdate();
- }
- } catch (const TExDie&) {
- STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS23, VDISKP(LogPrefix, "catched TExDie"));
- } catch (const TDtorException&) {
- return; // actor system is stopping, no actor activities allowed
- } catch (const TPoisonPillException&) { // poison pill from the skeleton
- STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS25, VDISKP(LogPrefix, "catched TPoisonPillException"));
- }
- Send(new IEventHandle(TEvents::TSystem::Poison, 0, std::exchange(BlobRecoveryActorId, {}), {}, nullptr, 0));
- }
-
- void TScrubCoroImpl::RequestState() {
- STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS01, VDISKP(LogPrefix, "requesting scrub state"));
- Send(MakeBlobStorageNodeWardenID(SelfActorId.NodeId()), new TEvBlobStorage::TEvControllerScrubQueryStartQuantum(
- ScrubCtx->NodeId, ScrubCtx->PDiskId, ScrubCtx->VSlotId), 0, ScrubCtx->ScrubCookie);
- CurrentState = TStringBuilder() << "in queue for scrub state";
- auto res = WaitForSpecificEvent<TEvBlobStorage::TEvControllerScrubStartQuantum>();
- const auto& r = res->Get()->Record;
- if (r.HasState()) {
- State.emplace();
- if (!State->ParseFromString(r.GetState())) {
- STLOGX(GetActorContext(), PRI_CRIT, BS_VDISK_SCRUB, VDS06, VDISKP(LogPrefix, "failed to parse scrub state protobuf"));
- State.reset();
- } else if (State->HasIncarnationGuid() && State->GetIncarnationGuid() != ScrubCtx->IncarnationGuid) {
- State.reset(); // restart scrub from the beginning
- }
- } else {
- State.reset();
- }
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS02, VDISKP(LogPrefix, "requested scrub state"), (State, State));
- }
-
- void TScrubCoroImpl::Quantum() {
- TakeSnapshot();
-
- // create an ordered set of available SSTs
- auto& slice = Snap->LogoBlobsSnap.SliceSnap;
- using T = std::decay_t<decltype(slice)>;
- T::TSstIterator iter(&slice);
- std::vector<TLevelSegmentPtr> segs;
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- segs.push_back(iter.Get().SstPtr);
- }
- auto comp = [](const TLevelSegmentPtr& x, const TLevelSegmentPtr& y) { return x->AssignedSstId < y->AssignedSstId; };
- std::sort(segs.begin(), segs.end(), comp);
-
- if (!State) { // we are starting a new cycle of scrubbing; it is started by scrubbing huge blobs of the VDisk
- ++ScrubIterationCounter;
- Checkpoints = 0;
- Success = true;
- } else {
- Success = State->GetSuccess();
- }
- if (!State || State->HasBlobId()) { // start or resume huge blob scrubbing
- if (!State) {
- State.emplace();
- }
- ScrubHugeBlobs();
- } else {
- const ui64 sstId = State->HasNextSstIdToScrub() ? State->GetNextSstIdToScrub() : Max<ui64>();
- auto comp = [](ui64 x, const TLevelSegmentPtr& y) { return x < y->AssignedSstId; };
- if (auto it = std::upper_bound(segs.begin(), segs.end(), sstId, comp); it != segs.begin()) {
- --it;
- if (it != segs.begin()) {
- State->SetNextSstIdToScrub((*std::prev(it))->AssignedSstId);
- } else {
- State.reset(); // we're done just after this SST
- }
- ScrubSst(*it);
- } else {
- State.reset(); // we're done
- }
- }
-
- ReleaseSnapshot();
-
- if (const ui64 cookie = GenerateRestoreCorruptedBlobQuery()) {
- while (LastReceivedRestoreCookie < cookie) {
- ProcessUnexpectedEvent(WaitForEvent());
- }
- }
-
- if (!State) { // full scrubbing cycle has finished
- ++ScrubIterationCounter;
- TScrubAwaitQueue::iterator it;
- for (it = ScrubAwaitQueue.begin(); it != ScrubAwaitQueue.end() && it->first < ScrubIterationCounter; ++it) {
- const auto& [actorId, cookie] = it->second;
- Send(actorId, new TEvScrubNotify(Checkpoints, Success && UnreadableBlobs.empty()), 0, cookie);
- }
- ScrubAwaitQueue.erase(ScrubAwaitQueue.begin(), it);
- }
-
- if (State) {
- State->SetSuccess(Success && UnreadableBlobs.empty());
- State->SetIncarnationGuid(ScrubCtx->IncarnationGuid);
- }
- }
-
- void TScrubCoroImpl::CommitStateUpdate() {
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS05, VDISKP(LogPrefix, "reporting scrub complete"), (State, State),
- (Success, Success), (UnreadableBlobsEmpty, UnreadableBlobs.empty()));
-
- auto finish = [&](auto&& result) {
- Send(MakeBlobStorageNodeWardenID(SelfActorId.NodeId()), new TEvBlobStorage::TEvControllerScrubQuantumFinished(
- ScrubCtx->NodeId, ScrubCtx->PDiskId, ScrubCtx->VSlotId, std::move(result)), 0, ScrubCtx->ScrubCookie);
- };
-
- if (State) {
- TString serialized;
- const bool success = State->SerializeToString(&serialized);
- Y_VERIFY(success);
- finish(serialized);
- ScrubEntrypoint.MutableScrubState()->CopyFrom(*State);
- } else {
- finish(Success && UnreadableBlobs.empty());
- ScrubEntrypoint.ClearScrubState();
- }
-
- IssueEntrypoint();
- }
-
- void TScrubCoroImpl::IssueEntrypoint() {
- // prepare entrypoint record
- ScrubEntrypoint.ClearUnreadableBlobs();
- for (const auto& [blobId, state] : UnreadableBlobs) {
- auto *pb = ScrubEntrypoint.AddUnreadableBlobs();
- LogoBlobIDFromLogoBlobID(blobId, pb->MutableBlobId());
- pb->SetUnreadableParts(state.UnreadableParts.Raw());
- state.CorruptedPart.SerializeToProto(*pb->MutableCorruptedPart());
- }
-
- TString data;
- const bool success = ScrubEntrypoint.SerializeToString(&data);
- Y_VERIFY(success);
-
- auto seg = ScrubCtx->LsnMngr->AllocLsnForLocalUse();
- ScrubEntrypointLsn = seg.Point();
- NPDisk::TCommitRecord cr;
- cr.IsStartingPoint = true;
- Send(ScrubCtx->LoggerId, new NPDisk::TEvLog(ScrubCtx->PDiskCtx->Dsk->Owner, ScrubCtx->PDiskCtx->Dsk->OwnerRound,
- TLogSignature::SignatureScrub, cr, data, seg, nullptr));
- }
-
- void TScrubCoroImpl::Handle(NPDisk::TEvLogResult::TPtr ev) {
- if (ev->Get()->Status == NKikimrProto::OK) {
- auto& lastItem = ev->Get()->Results.back();
- Send(ScrubCtx->LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::Scrub, lastItem.Lsn));
- }
- }
-
- void TScrubCoroImpl::Handle(NPDisk::TEvCutLog::TPtr ev) {
- if (ScrubEntrypointLsn < ev->Get()->FreeUpToLsn) {
- IssueEntrypoint();
- }
- }
-
- TIntrusivePtr<IRopeChunkBackend> TScrubCoroImpl::AllocateRopeArenaChunk() {
- return TRopeAlignedBuffer::Allocate(1 << 20); // 1 MB
- }
-
- IActor *CreateScrubActor(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn) {
- return new TActorCoro(MakeHolder<TScrubCoroImpl>(std::move(scrubCtx), std::move(scrubEntrypoint),
- scrubEntrypointLsn), NKikimrServices::TActivity::BS_SCRUB_ACTOR);
- }
-
-} // NKikimr
+#include "scrub_actor.h"
+#include "scrub_actor_impl.h"
+#include "blob_recovery.h"
+#include "restore_corrupted_blob_actor.h"
+
+namespace NKikimr {
+
+ TScrubCoroImpl::TScrubCoroImpl(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn)
+ : TActorCoroImpl(65536)
+ , ScrubCtx(std::move(scrubCtx))
+ , VCtx(ScrubCtx->VCtx)
+ , Info(ScrubCtx->Info)
+ , LogPrefix(VCtx->VDiskLogPrefix)
+ , Counters(VCtx->VDiskCounters->GetSubgroup("subsystem", "scrub"))
+ , SstProcessed(Counters->GetCounter("SstProcessed", true))
+ , HugeBlobsRead(Counters->GetCounter("HugeBlobsRead", true))
+ , HugeBlobBytesRead(Counters->GetCounter("HugeBlobBytesRead", true))
+ , SmallBlobIntervalsRead(Counters->GetCounter("SmallBlobIntervalsRead", true))
+ , SmallBlobIntervalBytesRead(Counters->GetCounter("SmallBlobIntervalBytesRead", true))
+ , SmallBlobsRead(Counters->GetCounter("SmallBlobsRead", true))
+ , SmallBlobBytesRead(Counters->GetCounter("SmallBlobBytesRead", true))
+ , UnreadableBlobsFound(Counters->GetCounter("UnreadableBlobsFound", false))
+ , BlobsFixed(Counters->GetCounter("BlobsFixed", false))
+ , Arena(&TScrubCoroImpl::AllocateRopeArenaChunk)
+ , ScrubEntrypoint(std::move(scrubEntrypoint))
+ , ScrubEntrypointLsn(scrubEntrypointLsn)
+ {}
+
+ void TScrubCoroImpl::ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) {
+ switch (const ui32 type = ev->GetTypeRewrite()) {
+ hFunc(NMon::TEvHttpInfo, Handle);
+ fFunc(TEvBlobStorage::EvScrubAwait, HandleScrubAwait);
+ fFunc(TEvBlobStorage::EvVGenerationChange, ForwardToBlobRecoveryActor);
+ fFunc(TEvBlobStorage::EvRecoverBlob, ForwardToBlobRecoveryActor);
+ hFunc(TEvRestoreCorruptedBlobResult, Handle);
+ hFunc(TEvNonrestoredCorruptedBlobNotify, Handle);
+ cFunc(EvGenerateRestoreCorruptedBlobQuery, HandleGenerateRestoreCorruptedBlobQuery);
+ hFunc(NPDisk::TEvLogResult, Handle);
+ hFunc(NPDisk::TEvCutLog, Handle);
+
+ default:
+ Y_FAIL("unexpected event Type# 0x%08" PRIx32, type);
+ }
+ }
+
+ void TScrubCoroImpl::HandleScrubAwait(TAutoPtr<IEventHandle> ev) {
+ ScrubAwaitQueue.emplace(ScrubIterationCounter + 1, std::make_pair(ev->Sender, ev->Cookie));
+ }
+
+ void TScrubCoroImpl::ForwardToBlobRecoveryActor(TAutoPtr<IEventHandle> ev) {
+ Send(ev->Forward(BlobRecoveryActorId));
+ }
+
+ void TScrubCoroImpl::Run() {
+ // unpack entrypoint
+ for (const auto& item : ScrubEntrypoint.GetUnreadableBlobs()) {
+ UnreadableBlobs.emplace(LogoBlobIDFromLogoBlobID(item.GetBlobId()), TUnreadableBlobState(
+ NMatrix::TVectorType(item.GetUnreadableParts(), Info->Type.TotalPartCount()),
+ item.GetCorruptedPart()));
+ }
+
+ // update log cutter
+ if (ScrubEntrypointLsn) {
+ Send(ScrubCtx->LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::Scrub, ScrubEntrypointLsn));
+ }
+
+ BlobRecoveryActorId = Register(CreateBlobRecoveryActor(VCtx, Info, Counters));
+ try {
+ for (;;) {
+ RequestState();
+ const TInstant start = TActorCoroImpl::Now();
+ const TInstant end = start + TDuration::Seconds(30);
+ do {
+ Quantum();
+ Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(UnreadableBlobs.size()));
+ } while (State && TActorCoroImpl::Now() < end);
+ Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(UnreadableBlobs.size()));
+ CommitStateUpdate();
+ }
+ } catch (const TExDie&) {
+ STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS23, VDISKP(LogPrefix, "catched TExDie"));
+ } catch (const TDtorException&) {
+ return; // actor system is stopping, no actor activities allowed
+ } catch (const TPoisonPillException&) { // poison pill from the skeleton
+ STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS25, VDISKP(LogPrefix, "catched TPoisonPillException"));
+ }
+ Send(new IEventHandle(TEvents::TSystem::Poison, 0, std::exchange(BlobRecoveryActorId, {}), {}, nullptr, 0));
+ }
+
+ void TScrubCoroImpl::RequestState() {
+ STLOGX(GetActorContext(), PRI_DEBUG, BS_VDISK_SCRUB, VDS01, VDISKP(LogPrefix, "requesting scrub state"));
+ Send(MakeBlobStorageNodeWardenID(SelfActorId.NodeId()), new TEvBlobStorage::TEvControllerScrubQueryStartQuantum(
+ ScrubCtx->NodeId, ScrubCtx->PDiskId, ScrubCtx->VSlotId), 0, ScrubCtx->ScrubCookie);
+ CurrentState = TStringBuilder() << "in queue for scrub state";
+ auto res = WaitForSpecificEvent<TEvBlobStorage::TEvControllerScrubStartQuantum>();
+ const auto& r = res->Get()->Record;
+ if (r.HasState()) {
+ State.emplace();
+ if (!State->ParseFromString(r.GetState())) {
+ STLOGX(GetActorContext(), PRI_CRIT, BS_VDISK_SCRUB, VDS06, VDISKP(LogPrefix, "failed to parse scrub state protobuf"));
+ State.reset();
+ } else if (State->HasIncarnationGuid() && State->GetIncarnationGuid() != ScrubCtx->IncarnationGuid) {
+ State.reset(); // restart scrub from the beginning
+ }
+ } else {
+ State.reset();
+ }
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS02, VDISKP(LogPrefix, "requested scrub state"), (State, State));
+ }
+
+ void TScrubCoroImpl::Quantum() {
+ TakeSnapshot();
+
+ // create an ordered set of available SSTs
+ auto& slice = Snap->LogoBlobsSnap.SliceSnap;
+ using T = std::decay_t<decltype(slice)>;
+ T::TSstIterator iter(&slice);
+ std::vector<TLevelSegmentPtr> segs;
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ segs.push_back(iter.Get().SstPtr);
+ }
+ auto comp = [](const TLevelSegmentPtr& x, const TLevelSegmentPtr& y) { return x->AssignedSstId < y->AssignedSstId; };
+ std::sort(segs.begin(), segs.end(), comp);
+
+ if (!State) { // we are starting a new cycle of scrubbing; it is started by scrubbing huge blobs of the VDisk
+ ++ScrubIterationCounter;
+ Checkpoints = 0;
+ Success = true;
+ } else {
+ Success = State->GetSuccess();
+ }
+ if (!State || State->HasBlobId()) { // start or resume huge blob scrubbing
+ if (!State) {
+ State.emplace();
+ }
+ ScrubHugeBlobs();
+ } else {
+ const ui64 sstId = State->HasNextSstIdToScrub() ? State->GetNextSstIdToScrub() : Max<ui64>();
+ auto comp = [](ui64 x, const TLevelSegmentPtr& y) { return x < y->AssignedSstId; };
+ if (auto it = std::upper_bound(segs.begin(), segs.end(), sstId, comp); it != segs.begin()) {
+ --it;
+ if (it != segs.begin()) {
+ State->SetNextSstIdToScrub((*std::prev(it))->AssignedSstId);
+ } else {
+ State.reset(); // we're done just after this SST
+ }
+ ScrubSst(*it);
+ } else {
+ State.reset(); // we're done
+ }
+ }
+
+ ReleaseSnapshot();
+
+ if (const ui64 cookie = GenerateRestoreCorruptedBlobQuery()) {
+ while (LastReceivedRestoreCookie < cookie) {
+ ProcessUnexpectedEvent(WaitForEvent());
+ }
+ }
+
+ if (!State) { // full scrubbing cycle has finished
+ ++ScrubIterationCounter;
+ TScrubAwaitQueue::iterator it;
+ for (it = ScrubAwaitQueue.begin(); it != ScrubAwaitQueue.end() && it->first < ScrubIterationCounter; ++it) {
+ const auto& [actorId, cookie] = it->second;
+ Send(actorId, new TEvScrubNotify(Checkpoints, Success && UnreadableBlobs.empty()), 0, cookie);
+ }
+ ScrubAwaitQueue.erase(ScrubAwaitQueue.begin(), it);
+ }
+
+ if (State) {
+ State->SetSuccess(Success && UnreadableBlobs.empty());
+ State->SetIncarnationGuid(ScrubCtx->IncarnationGuid);
+ }
+ }
+
+ void TScrubCoroImpl::CommitStateUpdate() {
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS05, VDISKP(LogPrefix, "reporting scrub complete"), (State, State),
+ (Success, Success), (UnreadableBlobsEmpty, UnreadableBlobs.empty()));
+
+ auto finish = [&](auto&& result) {
+ Send(MakeBlobStorageNodeWardenID(SelfActorId.NodeId()), new TEvBlobStorage::TEvControllerScrubQuantumFinished(
+ ScrubCtx->NodeId, ScrubCtx->PDiskId, ScrubCtx->VSlotId, std::move(result)), 0, ScrubCtx->ScrubCookie);
+ };
+
+ if (State) {
+ TString serialized;
+ const bool success = State->SerializeToString(&serialized);
+ Y_VERIFY(success);
+ finish(serialized);
+ ScrubEntrypoint.MutableScrubState()->CopyFrom(*State);
+ } else {
+ finish(Success && UnreadableBlobs.empty());
+ ScrubEntrypoint.ClearScrubState();
+ }
+
+ IssueEntrypoint();
+ }
+
+ void TScrubCoroImpl::IssueEntrypoint() {
+ // prepare entrypoint record
+ ScrubEntrypoint.ClearUnreadableBlobs();
+ for (const auto& [blobId, state] : UnreadableBlobs) {
+ auto *pb = ScrubEntrypoint.AddUnreadableBlobs();
+ LogoBlobIDFromLogoBlobID(blobId, pb->MutableBlobId());
+ pb->SetUnreadableParts(state.UnreadableParts.Raw());
+ state.CorruptedPart.SerializeToProto(*pb->MutableCorruptedPart());
+ }
+
+ TString data;
+ const bool success = ScrubEntrypoint.SerializeToString(&data);
+ Y_VERIFY(success);
+
+ auto seg = ScrubCtx->LsnMngr->AllocLsnForLocalUse();
+ ScrubEntrypointLsn = seg.Point();
+ NPDisk::TCommitRecord cr;
+ cr.IsStartingPoint = true;
+ Send(ScrubCtx->LoggerId, new NPDisk::TEvLog(ScrubCtx->PDiskCtx->Dsk->Owner, ScrubCtx->PDiskCtx->Dsk->OwnerRound,
+ TLogSignature::SignatureScrub, cr, data, seg, nullptr));
+ }
+
+ void TScrubCoroImpl::Handle(NPDisk::TEvLogResult::TPtr ev) {
+ if (ev->Get()->Status == NKikimrProto::OK) {
+ auto& lastItem = ev->Get()->Results.back();
+ Send(ScrubCtx->LogCutterId, new TEvVDiskCutLog(TEvVDiskCutLog::Scrub, lastItem.Lsn));
+ }
+ }
+
+ void TScrubCoroImpl::Handle(NPDisk::TEvCutLog::TPtr ev) {
+ if (ScrubEntrypointLsn < ev->Get()->FreeUpToLsn) {
+ IssueEntrypoint();
+ }
+ }
+
+ TIntrusivePtr<IRopeChunkBackend> TScrubCoroImpl::AllocateRopeArenaChunk() {
+ return TRopeAlignedBuffer::Allocate(1 << 20); // 1 MB
+ }
+
+ IActor *CreateScrubActor(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn) {
+ return new TActorCoro(MakeHolder<TScrubCoroImpl>(std::move(scrubCtx), std::move(scrubEntrypoint),
+ scrubEntrypointLsn), NKikimrServices::TActivity::BS_SCRUB_ACTOR);
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor.h b/ydb/core/blobstorage/vdisk/scrub/scrub_actor.h
index ddbfb93b555..978b84a6828 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor.h
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor.h
@@ -1,72 +1,72 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- struct TScrubContext : TThrRefBase {
- const TIntrusivePtr<TVDiskContext> VCtx;
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ struct TScrubContext : TThrRefBase {
+ const TIntrusivePtr<TVDiskContext> VCtx;
const TPDiskCtxPtr PDiskCtx;
- const TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TActorId SkeletonId;
- const TActorId LogoBlobsLevelIndexActorId;
- const ui32 NodeId;
- const ui32 PDiskId;
- const ui32 VSlotId;
- const ui64 ScrubCookie;
- const ui64 IncarnationGuid;
- const TIntrusivePtr<TLsnMngr> LsnMngr;
- const TActorId LoggerId;
- const TActorId LogCutterId;
-
+ const TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TActorId SkeletonId;
+ const TActorId LogoBlobsLevelIndexActorId;
+ const ui32 NodeId;
+ const ui32 PDiskId;
+ const ui32 VSlotId;
+ const ui64 ScrubCookie;
+ const ui64 IncarnationGuid;
+ const TIntrusivePtr<TLsnMngr> LsnMngr;
+ const TActorId LoggerId;
+ const TActorId LogCutterId;
+
TScrubContext(TIntrusivePtr<TVDiskContext> vctx, TPDiskCtxPtr pdiskCtx,
- TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId skeletonId, TActorId logoBlobsLevelIndexActorId,
- ui32 nodeId, ui32 pdiskId, ui32 vslotId, ui64 scrubCookie, ui64 incarnationGuid,
- const TIntrusivePtr<TLsnMngr> lsnMngr, TActorId loggerId, TActorId logCutterId)
- : VCtx(std::move(vctx))
- , PDiskCtx(std::move(pdiskCtx))
- , Info(std::move(info))
- , SkeletonId(skeletonId)
- , LogoBlobsLevelIndexActorId(logoBlobsLevelIndexActorId)
- , NodeId(nodeId)
- , PDiskId(pdiskId)
- , VSlotId(vslotId)
- , ScrubCookie(scrubCookie)
- , IncarnationGuid(incarnationGuid)
- , LsnMngr(std::move(lsnMngr))
- , LoggerId(loggerId)
- , LogCutterId(logCutterId)
- {}
-
- using TPtr = TIntrusivePtr<TScrubContext>;
- };
-
- struct TEvScrubNotify : TEventLocal<TEvScrubNotify, TEvBlobStorage::EvScrubNotify> {
- enum ECheckpoint : ui32 {
- HUGE_BLOB_SCRUBBED = 1,
- SMALL_BLOB_SCRUBBED = 2,
- INDEX_RESTORED = 4,
-
- ALL = HUGE_BLOB_SCRUBBED | SMALL_BLOB_SCRUBBED | INDEX_RESTORED
- };
- ui32 Checkpoints;
- bool Success;
-
- TEvScrubNotify(ui32 checkpoints, bool success)
- : Checkpoints(checkpoints)
- , Success(success)
- {}
- };
-
- struct TEvReportScrubStatus : TEventLocal<TEvReportScrubStatus, TEvBlobStorage::EvReportScrubStatus> {
- bool HasUnreadableBlobs;
-
- TEvReportScrubStatus(bool hasUnreadableBlobs)
- : HasUnreadableBlobs(hasUnreadableBlobs)
- {}
- };
-
- IActor *CreateScrubActor(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn);
-
-} // NKikimr
+ TIntrusivePtr<TBlobStorageGroupInfo> info, TActorId skeletonId, TActorId logoBlobsLevelIndexActorId,
+ ui32 nodeId, ui32 pdiskId, ui32 vslotId, ui64 scrubCookie, ui64 incarnationGuid,
+ const TIntrusivePtr<TLsnMngr> lsnMngr, TActorId loggerId, TActorId logCutterId)
+ : VCtx(std::move(vctx))
+ , PDiskCtx(std::move(pdiskCtx))
+ , Info(std::move(info))
+ , SkeletonId(skeletonId)
+ , LogoBlobsLevelIndexActorId(logoBlobsLevelIndexActorId)
+ , NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VSlotId(vslotId)
+ , ScrubCookie(scrubCookie)
+ , IncarnationGuid(incarnationGuid)
+ , LsnMngr(std::move(lsnMngr))
+ , LoggerId(loggerId)
+ , LogCutterId(logCutterId)
+ {}
+
+ using TPtr = TIntrusivePtr<TScrubContext>;
+ };
+
+ struct TEvScrubNotify : TEventLocal<TEvScrubNotify, TEvBlobStorage::EvScrubNotify> {
+ enum ECheckpoint : ui32 {
+ HUGE_BLOB_SCRUBBED = 1,
+ SMALL_BLOB_SCRUBBED = 2,
+ INDEX_RESTORED = 4,
+
+ ALL = HUGE_BLOB_SCRUBBED | SMALL_BLOB_SCRUBBED | INDEX_RESTORED
+ };
+ ui32 Checkpoints;
+ bool Success;
+
+ TEvScrubNotify(ui32 checkpoints, bool success)
+ : Checkpoints(checkpoints)
+ , Success(success)
+ {}
+ };
+
+ struct TEvReportScrubStatus : TEventLocal<TEvReportScrubStatus, TEvBlobStorage::EvReportScrubStatus> {
+ bool HasUnreadableBlobs;
+
+ TEvReportScrubStatus(bool hasUnreadableBlobs)
+ : HasUnreadableBlobs(hasUnreadableBlobs)
+ {}
+ };
+
+ IActor *CreateScrubActor(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn);
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp
index bdbb432708a..f192caebd85 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge.cpp
@@ -1,70 +1,70 @@
-#include "scrub_actor_impl.h"
-#include "scrub_actor_huge_blob_merger.h"
-
-namespace NKikimr {
-
- void TScrubCoroImpl::ScrubHugeBlobs() {
- TLevelIndexSnapshot::TBackwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
- if (State->HasBlobId()) {
- const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(State->GetBlobId());
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS19, VDISKP(LogPrefix, "resuming huge blob scrubbing"),
- (Id, id));
- iter.Seek(id);
- if (iter.Valid() && iter.GetCurKey() == id) {
- iter.Prev();
- }
- } else {
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS20, VDISKP(LogPrefix, "starting huge blob scrubbing"));
- // FIXME: check if this is correct logic?
- iter.Seek(TLogoBlobID(Max<ui64>(), Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
- TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie));
- }
-
- auto readHugeBlob = [&](const TDiskPart& location) {
- ++*HugeBlobsRead;
- *HugeBlobBytesRead += location.Size;
- return Read(location);
- };
-
- auto essence = GetBarriersEssence();
- THugeBlobMerger merger(LogPrefix, Info->Type, readHugeBlob, this);
- TIndexRecordMerger indexMerger(Info->Type); // for GC checking
-
- const TInstant startTime = TActorCoroImpl::Now();
- do {
- if (!iter.Valid()) {
- break;
- }
-
- iter.PutToMerger(&indexMerger);
- indexMerger.Finish();
- auto status = essence->Keep(iter.GetCurKey(), indexMerger.GetMemRec(), indexMerger.GetMemRecsMerged(),
- Snap->HullCtx->AllowKeepFlags);
- indexMerger.Clear();
-
- const TLogoBlobID& id = iter.GetCurKey().LogoBlobID();
-
- if (status.KeepData) {
- merger.Begin(id);
- iter.PutToMerger(&merger);
- const NMatrix::TVectorType needed = merger.GetPartsToRestore();
- UpdateUnreadableParts(id, needed, merger.GetCorruptedPart());
- if (!needed.Empty()) {
- Checkpoints |= TEvScrubNotify::HUGE_BLOB_SCRUBBED;
- }
- merger.Clear();
- } else {
- DropGarbageBlob(id);
- }
-
- iter.Prev();
- } while (TActorCoroImpl::Now() < startTime + TDuration::Seconds(5));
-
- if (iter.Valid()) {
- LogoBlobIDFromLogoBlobID(iter.GetCurKey().LogoBlobID(), State->MutableBlobId());
- } else {
- State->ClearBlobId();
- }
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+#include "scrub_actor_huge_blob_merger.h"
+
+namespace NKikimr {
+
+ void TScrubCoroImpl::ScrubHugeBlobs() {
+ TLevelIndexSnapshot::TBackwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
+ if (State->HasBlobId()) {
+ const TLogoBlobID& id = LogoBlobIDFromLogoBlobID(State->GetBlobId());
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS19, VDISKP(LogPrefix, "resuming huge blob scrubbing"),
+ (Id, id));
+ iter.Seek(id);
+ if (iter.Valid() && iter.GetCurKey() == id) {
+ iter.Prev();
+ }
+ } else {
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS20, VDISKP(LogPrefix, "starting huge blob scrubbing"));
+ // FIXME: check if this is correct logic?
+ iter.Seek(TLogoBlobID(Max<ui64>(), Max<ui32>(), Max<ui32>(), TLogoBlobID::MaxChannel,
+ TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie));
+ }
+
+ auto readHugeBlob = [&](const TDiskPart& location) {
+ ++*HugeBlobsRead;
+ *HugeBlobBytesRead += location.Size;
+ return Read(location);
+ };
+
+ auto essence = GetBarriersEssence();
+ THugeBlobMerger merger(LogPrefix, Info->Type, readHugeBlob, this);
+ TIndexRecordMerger indexMerger(Info->Type); // for GC checking
+
+ const TInstant startTime = TActorCoroImpl::Now();
+ do {
+ if (!iter.Valid()) {
+ break;
+ }
+
+ iter.PutToMerger(&indexMerger);
+ indexMerger.Finish();
+ auto status = essence->Keep(iter.GetCurKey(), indexMerger.GetMemRec(), indexMerger.GetMemRecsMerged(),
+ Snap->HullCtx->AllowKeepFlags);
+ indexMerger.Clear();
+
+ const TLogoBlobID& id = iter.GetCurKey().LogoBlobID();
+
+ if (status.KeepData) {
+ merger.Begin(id);
+ iter.PutToMerger(&merger);
+ const NMatrix::TVectorType needed = merger.GetPartsToRestore();
+ UpdateUnreadableParts(id, needed, merger.GetCorruptedPart());
+ if (!needed.Empty()) {
+ Checkpoints |= TEvScrubNotify::HUGE_BLOB_SCRUBBED;
+ }
+ merger.Clear();
+ } else {
+ DropGarbageBlob(id);
+ }
+
+ iter.Prev();
+ } while (TActorCoroImpl::Now() < startTime + TDuration::Seconds(5));
+
+ if (iter.Valid()) {
+ LogoBlobIDFromLogoBlobID(iter.GetCurKey().LogoBlobID(), State->MutableBlobId());
+ } else {
+ State->ClearBlobId();
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge_blob_merger.h b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge_blob_merger.h
index 2b04da97606..e5922bcf220 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge_blob_merger.h
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_huge_blob_merger.h
@@ -1,105 +1,105 @@
-#pragma once
-
-#include "defs.h"
-#include "scrub_actor_impl.h"
-
-namespace NKikimr {
-
- class TScrubCoroImpl::THugeBlobMerger {
- const TString& LogPrefix;
- NMatrix::TVectorType Local;
- NMatrix::TVectorType ReadableLocal;
- std::vector<TDiskPart> CorruptedParts;
- std::function<std::optional<TString>(const TDiskPart&)> Read;
- const TBlobStorageGroupType GType;
- TDataPartSet PartSet;
- TScrubCoroImpl *Impl;
-
- public:
- template<typename TRead>
- THugeBlobMerger(const TString& logPrefix, const TBlobStorageGroupType& gtype, TRead&& read, TScrubCoroImpl *impl)
- : LogPrefix(logPrefix)
- , Local(0, gtype.TotalPartCount())
- , ReadableLocal(0, gtype.TotalPartCount())
- , Read(std::move(read))
- , GType(gtype)
- , Impl(impl)
- {
- PartSet.FullDataSize = 0;
- PartSet.PartsMask = 0;
- PartSet.Parts.resize(gtype.TotalPartCount());
- }
-
- static bool HaveToMergeData() { return true; }
-
- void Begin(const TLogoBlobID& id) {
- PartSet.FullDataSize = id.BlobSize();
- }
-
- // process on-disk data
- void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key, ui64 /*sstId*/) {
- switch (memRec.GetType()) {
- // ignore non-huge blobs
- case TBlobType::MemBlob:
- case TBlobType::DiskBlob:
- break;
-
- case TBlobType::HugeBlob:
- case TBlobType::ManyHugeBlobs: {
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, outbound);
- const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
- Y_VERIFY(extr.End - extr.Begin == local.CountBits());
- const TDiskPart *part = extr.Begin;
- for (ui32 i = local.FirstPosition(); i != local.GetSize(); i = local.NextPosition(i), ++part) {
- if (part->ChunkIdx && part->Size) {
- std::optional<TString> data = Read(*part);
- STLOGX(Impl->GetActorContext(), data ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS21,
- VDISKP(LogPrefix, "huge blob read"), (Id, key.LogoBlobID()), (Local, local),
- (Location, *part), (IsReadable, data.has_value()));
- Local.Set(i);
- if (data) {
- ReadableLocal.Set(i);
- TRope rope(*data);
- TDiskBlob blob(&rope, NMatrix::TVectorType::MakeOneHot(i, local.GetSize()), GType,
- key.LogoBlobID());
- TRope holder;
- TRope part = blob.GetPart(i, &holder);
- PartSet.Parts[i].ReferenceTo(part.ConvertToString());
- } else {
- CorruptedParts.push_back(*part);
- }
- }
- }
- break;
- }
- }
- }
-
- void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope* /*data*/, const TKeyLogoBlob& key, ui64 /*lsn*/) {
- AddFromSegment(memRec, nullptr, key, Max<ui64>());
- }
-
- void Clear() {
- Local.Clear();
- ReadableLocal.Clear();
- CorruptedParts.clear();
- PartSet.FullDataSize = 0;
- PartSet.PartsMask = 0;
- std::fill(PartSet.Parts.begin(), PartSet.Parts.end(), TPartFragment());
- }
-
- NMatrix::TVectorType GetPartsToRestore() const {
- return Local & ~ReadableLocal;
- }
-
- TDiskPart GetCorruptedPart() const {
- return CorruptedParts.empty() ? TDiskPart() : CorruptedParts.front();
- }
-
- TDataPartSet GetPartSet() {
- return std::move(PartSet);
- }
- };
-
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+#include "scrub_actor_impl.h"
+
+namespace NKikimr {
+
+ class TScrubCoroImpl::THugeBlobMerger {
+ const TString& LogPrefix;
+ NMatrix::TVectorType Local;
+ NMatrix::TVectorType ReadableLocal;
+ std::vector<TDiskPart> CorruptedParts;
+ std::function<std::optional<TString>(const TDiskPart&)> Read;
+ const TBlobStorageGroupType GType;
+ TDataPartSet PartSet;
+ TScrubCoroImpl *Impl;
+
+ public:
+ template<typename TRead>
+ THugeBlobMerger(const TString& logPrefix, const TBlobStorageGroupType& gtype, TRead&& read, TScrubCoroImpl *impl)
+ : LogPrefix(logPrefix)
+ , Local(0, gtype.TotalPartCount())
+ , ReadableLocal(0, gtype.TotalPartCount())
+ , Read(std::move(read))
+ , GType(gtype)
+ , Impl(impl)
+ {
+ PartSet.FullDataSize = 0;
+ PartSet.PartsMask = 0;
+ PartSet.Parts.resize(gtype.TotalPartCount());
+ }
+
+ static bool HaveToMergeData() { return true; }
+
+ void Begin(const TLogoBlobID& id) {
+ PartSet.FullDataSize = id.BlobSize();
+ }
+
+ // process on-disk data
+ void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key, ui64 /*sstId*/) {
+ switch (memRec.GetType()) {
+ // ignore non-huge blobs
+ case TBlobType::MemBlob:
+ case TBlobType::DiskBlob:
+ break;
+
+ case TBlobType::HugeBlob:
+ case TBlobType::ManyHugeBlobs: {
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, outbound);
+ const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
+ Y_VERIFY(extr.End - extr.Begin == local.CountBits());
+ const TDiskPart *part = extr.Begin;
+ for (ui32 i = local.FirstPosition(); i != local.GetSize(); i = local.NextPosition(i), ++part) {
+ if (part->ChunkIdx && part->Size) {
+ std::optional<TString> data = Read(*part);
+ STLOGX(Impl->GetActorContext(), data ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS21,
+ VDISKP(LogPrefix, "huge blob read"), (Id, key.LogoBlobID()), (Local, local),
+ (Location, *part), (IsReadable, data.has_value()));
+ Local.Set(i);
+ if (data) {
+ ReadableLocal.Set(i);
+ TRope rope(*data);
+ TDiskBlob blob(&rope, NMatrix::TVectorType::MakeOneHot(i, local.GetSize()), GType,
+ key.LogoBlobID());
+ TRope holder;
+ TRope part = blob.GetPart(i, &holder);
+ PartSet.Parts[i].ReferenceTo(part.ConvertToString());
+ } else {
+ CorruptedParts.push_back(*part);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope* /*data*/, const TKeyLogoBlob& key, ui64 /*lsn*/) {
+ AddFromSegment(memRec, nullptr, key, Max<ui64>());
+ }
+
+ void Clear() {
+ Local.Clear();
+ ReadableLocal.Clear();
+ CorruptedParts.clear();
+ PartSet.FullDataSize = 0;
+ PartSet.PartsMask = 0;
+ std::fill(PartSet.Parts.begin(), PartSet.Parts.end(), TPartFragment());
+ }
+
+ NMatrix::TVectorType GetPartsToRestore() const {
+ return Local & ~ReadableLocal;
+ }
+
+ TDiskPart GetCorruptedPart() const {
+ return CorruptedParts.empty() ? TDiskPart() : CorruptedParts.front();
+ }
+
+ TDataPartSet GetPartSet() {
+ return std::move(PartSet);
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_impl.h b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_impl.h
index 7af6d264f68..aa653a204de 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_impl.h
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_impl.h
@@ -1,174 +1,174 @@
-#pragma once
-
-#include "defs.h"
-#include "scrub_actor.h"
-
-namespace NKikimr {
-
- struct TEvRestoreCorruptedBlobResult;
- struct TEvNonrestoredCorruptedBlobNotify;
-
- class TScrubCoroImpl : public TActorCoroImpl {
- using TFreshSegmentSnapshot = NKikimr::TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- using TIndexRecordMerger = NKikimr::TIndexRecordMerger<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelIndexSnapshot = NKikimr::TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
-
- TString CurrentState;
- const TScrubContext::TPtr ScrubCtx;
- const TIntrusivePtr<TVDiskContext> VCtx;
- TIntrusivePtr<TBlobStorageGroupInfo> Info;
- const TString LogPrefix;
-
- std::optional<NKikimrVDiskData::TScrubState> State;
-
- NMonitoring::TDynamicCounterPtr Counters;
- NMonitoring::TDynamicCounters::TCounterPtr SstProcessed;
- NMonitoring::TDynamicCounters::TCounterPtr HugeBlobsRead;
- NMonitoring::TDynamicCounters::TCounterPtr HugeBlobBytesRead;
- NMonitoring::TDynamicCounters::TCounterPtr SmallBlobIntervalsRead;
- NMonitoring::TDynamicCounters::TCounterPtr SmallBlobIntervalBytesRead;
- NMonitoring::TDynamicCounters::TCounterPtr SmallBlobsRead;
- NMonitoring::TDynamicCounters::TCounterPtr SmallBlobBytesRead;
- NMonitoring::TDynamicCounters::TCounterPtr UnreadableBlobsFound;
- NMonitoring::TDynamicCounters::TCounterPtr BlobsFixed;
-
- TRopeArena Arena;
-
- struct TExDie {};
-
- struct TBlobOnDisk {
- TLogoBlobID Id;
- NMatrix::TVectorType Local;
- TDiskPart Part;
- };
-
- TActorId BlobRecoveryActorId;
-
- std::optional<ui64> SstId;
- ui32 Checkpoints = 0;
-
- bool Success = false;
-
- enum {
- EvGenerateRestoreCorruptedBlobQuery = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- private:
- struct TUnreadableBlobState {
- NMatrix::TVectorType UnreadableParts; // parts we're going to recover from peer disks
- TDiskPart CorruptedPart;
- ui64 RecoveryInFlightCookie = 0; // 0 -- not being recovered
- TInstant RetryTimestamp;
-
- TUnreadableBlobState(NMatrix::TVectorType unreadableParts, TDiskPart corruptedPart)
- : UnreadableParts(unreadableParts)
- , CorruptedPart(corruptedPart)
- {}
- };
-
- using TUnreadableBlobStateMap = std::unordered_map<TLogoBlobID, TUnreadableBlobState, THash<TLogoBlobID>>;
- TUnreadableBlobStateMap UnreadableBlobs;
- ui64 LastRestoreCookie = 0;
- ui64 LastReceivedRestoreCookie = 0;
- bool GenerateRestoreCorruptedBlobQueryScheduled = false;
-
- void DropGarbageBlob(const TLogoBlobID& fullId);
- void AddUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart);
- void UpdateUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart);
- void UpdateReadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType readable);
-
- ui64 GenerateRestoreCorruptedBlobQuery();
- void Handle(TAutoPtr<TEventHandle<TEvRestoreCorruptedBlobResult>> ev);
- void Handle(TAutoPtr<TEventHandle<TEvNonrestoredCorruptedBlobNotify>> ev);
- void HandleGenerateRestoreCorruptedBlobQuery();
-
- public:
- TScrubCoroImpl(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
- ui64 scrubEntrypointLsn);
+#pragma once
+
+#include "defs.h"
+#include "scrub_actor.h"
+
+namespace NKikimr {
+
+ struct TEvRestoreCorruptedBlobResult;
+ struct TEvNonrestoredCorruptedBlobNotify;
+
+ class TScrubCoroImpl : public TActorCoroImpl {
+ using TFreshSegmentSnapshot = NKikimr::TFreshSegmentSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TIndexRecordMerger = NKikimr::TIndexRecordMerger<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelIndexSnapshot = NKikimr::TLevelIndexSnapshot<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
+
+ TString CurrentState;
+ const TScrubContext::TPtr ScrubCtx;
+ const TIntrusivePtr<TVDiskContext> VCtx;
+ TIntrusivePtr<TBlobStorageGroupInfo> Info;
+ const TString LogPrefix;
+
+ std::optional<NKikimrVDiskData::TScrubState> State;
+
+ NMonitoring::TDynamicCounterPtr Counters;
+ NMonitoring::TDynamicCounters::TCounterPtr SstProcessed;
+ NMonitoring::TDynamicCounters::TCounterPtr HugeBlobsRead;
+ NMonitoring::TDynamicCounters::TCounterPtr HugeBlobBytesRead;
+ NMonitoring::TDynamicCounters::TCounterPtr SmallBlobIntervalsRead;
+ NMonitoring::TDynamicCounters::TCounterPtr SmallBlobIntervalBytesRead;
+ NMonitoring::TDynamicCounters::TCounterPtr SmallBlobsRead;
+ NMonitoring::TDynamicCounters::TCounterPtr SmallBlobBytesRead;
+ NMonitoring::TDynamicCounters::TCounterPtr UnreadableBlobsFound;
+ NMonitoring::TDynamicCounters::TCounterPtr BlobsFixed;
+
+ TRopeArena Arena;
+
+ struct TExDie {};
+
+ struct TBlobOnDisk {
+ TLogoBlobID Id;
+ NMatrix::TVectorType Local;
+ TDiskPart Part;
+ };
+
+ TActorId BlobRecoveryActorId;
+
+ std::optional<ui64> SstId;
+ ui32 Checkpoints = 0;
+
+ bool Success = false;
+
+ enum {
+ EvGenerateRestoreCorruptedBlobQuery = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ private:
+ struct TUnreadableBlobState {
+ NMatrix::TVectorType UnreadableParts; // parts we're going to recover from peer disks
+ TDiskPart CorruptedPart;
+ ui64 RecoveryInFlightCookie = 0; // 0 -- not being recovered
+ TInstant RetryTimestamp;
+
+ TUnreadableBlobState(NMatrix::TVectorType unreadableParts, TDiskPart corruptedPart)
+ : UnreadableParts(unreadableParts)
+ , CorruptedPart(corruptedPart)
+ {}
+ };
+
+ using TUnreadableBlobStateMap = std::unordered_map<TLogoBlobID, TUnreadableBlobState, THash<TLogoBlobID>>;
+ TUnreadableBlobStateMap UnreadableBlobs;
+ ui64 LastRestoreCookie = 0;
+ ui64 LastReceivedRestoreCookie = 0;
+ bool GenerateRestoreCorruptedBlobQueryScheduled = false;
+
+ void DropGarbageBlob(const TLogoBlobID& fullId);
+ void AddUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart);
+ void UpdateUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart);
+ void UpdateReadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType readable);
+
+ ui64 GenerateRestoreCorruptedBlobQuery();
+ void Handle(TAutoPtr<TEventHandle<TEvRestoreCorruptedBlobResult>> ev);
+ void Handle(TAutoPtr<TEventHandle<TEvNonrestoredCorruptedBlobNotify>> ev);
+ void HandleGenerateRestoreCorruptedBlobQuery();
+
+ public:
+ TScrubCoroImpl(TScrubContext::TPtr scrubCtx, NKikimrVDiskData::TScrubEntrypoint scrubEntrypoint,
+ ui64 scrubEntrypointLsn);
void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) override;
- void Handle(NMon::TEvHttpInfo::TPtr ev);
- void ForwardToBlobRecoveryActor(TAutoPtr<IEventHandle> ev);
-
- TString RenderHtml(ui32 maxUnreadableBlobs) const;
-
- void Run() override;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // MAIN OPERATION CYCLE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
- ui64 ScrubEntrypointLsn = 0;
-
- void RequestState();
- void Quantum();
- void CommitStateUpdate();
- void IssueEntrypoint();
- void Handle(NPDisk::TEvLogResult::TPtr ev);
- void Handle(NPDisk::TEvCutLog::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // SNAPSHOT OPERATION
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- std::optional<THullDsSnap> Snap;
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence;
-
- void TakeSnapshot();
- void ReleaseSnapshot();
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> GetBarriersEssence();
-
- class THugeBlobMerger;
- class TSstBlobMerger;
- class TBlobLocationExtractorMerger;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PDISK INTERACTION
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- std::optional<TString> Read(const TDiskPart& part);
- bool IsReadable(const TDiskPart& part);
- void Write(const TDiskPart& part, TString data);
-
- template<typename T>
- typename T::TPtr WaitForPDiskEvent() {
- auto res = WaitForSpecificEvent<T>();
- if (res->Get()->Status == NKikimrProto::INVALID_ROUND) {
- throw TExDie(); // this VDisk is dead and racing with newly created one, so we terminate the disk
- }
- return res;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // HUGE BLOB SCRUBBING
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // Function does iteration of huge blob scrubbing; last scrubbed blob is taken from the state and written back
- // to the state unless the process is finished. In this case, BlobId is simply reset in the state.
- void ScrubHugeBlobs();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // SST SCRUBBING
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ScrubSst(TLevelSegmentPtr sst);
- void ReadOutAndResilverIndex(TLevelSegmentPtr sst);
- std::vector<TBlobOnDisk> MakeBlobList(TLevelSegmentPtr sst);
- void ReadOutSelectedBlobs(std::vector<TBlobOnDisk>&& blobsOnDisk);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // DEBUG
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- ui64 ScrubIterationCounter = 0;
- using TScrubAwaitQueue = std::multimap<ui64, std::pair<TActorId, ui64>>;
- TScrubAwaitQueue ScrubAwaitQueue;
- void HandleScrubAwait(TAutoPtr<IEventHandle> ev);
-
- private:
- static TIntrusivePtr<IRopeChunkBackend> AllocateRopeArenaChunk();
- };
-
-} // NKikimr
+ void Handle(NMon::TEvHttpInfo::TPtr ev);
+ void ForwardToBlobRecoveryActor(TAutoPtr<IEventHandle> ev);
+
+ TString RenderHtml(ui32 maxUnreadableBlobs) const;
+
+ void Run() override;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MAIN OPERATION CYCLE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ NKikimrVDiskData::TScrubEntrypoint ScrubEntrypoint;
+ ui64 ScrubEntrypointLsn = 0;
+
+ void RequestState();
+ void Quantum();
+ void CommitStateUpdate();
+ void IssueEntrypoint();
+ void Handle(NPDisk::TEvLogResult::TPtr ev);
+ void Handle(NPDisk::TEvCutLog::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SNAPSHOT OPERATION
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ std::optional<THullDsSnap> Snap;
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence;
+
+ void TakeSnapshot();
+ void ReleaseSnapshot();
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> GetBarriersEssence();
+
+ class THugeBlobMerger;
+ class TSstBlobMerger;
+ class TBlobLocationExtractorMerger;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PDISK INTERACTION
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ std::optional<TString> Read(const TDiskPart& part);
+ bool IsReadable(const TDiskPart& part);
+ void Write(const TDiskPart& part, TString data);
+
+ template<typename T>
+ typename T::TPtr WaitForPDiskEvent() {
+ auto res = WaitForSpecificEvent<T>();
+ if (res->Get()->Status == NKikimrProto::INVALID_ROUND) {
+ throw TExDie(); // this VDisk is dead and racing with newly created one, so we terminate the disk
+ }
+ return res;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HUGE BLOB SCRUBBING
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // Function does iteration of huge blob scrubbing; last scrubbed blob is taken from the state and written back
+ // to the state unless the process is finished. In this case, BlobId is simply reset in the state.
+ void ScrubHugeBlobs();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SST SCRUBBING
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ScrubSst(TLevelSegmentPtr sst);
+ void ReadOutAndResilverIndex(TLevelSegmentPtr sst);
+ std::vector<TBlobOnDisk> MakeBlobList(TLevelSegmentPtr sst);
+ void ReadOutSelectedBlobs(std::vector<TBlobOnDisk>&& blobsOnDisk);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DEBUG
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ ui64 ScrubIterationCounter = 0;
+ using TScrubAwaitQueue = std::multimap<ui64, std::pair<TActorId, ui64>>;
+ TScrubAwaitQueue ScrubAwaitQueue;
+ void HandleScrubAwait(TAutoPtr<IEventHandle> ev);
+
+ private:
+ static TIntrusivePtr<IRopeChunkBackend> AllocateRopeArenaChunk();
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_mon.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_mon.cpp
index 6948229b86d..1c3f31ff513 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_mon.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_mon.cpp
@@ -1,63 +1,63 @@
-#include "scrub_actor_impl.h"
-
-namespace NKikimr {
-
- void TScrubCoroImpl::Handle(NMon::TEvHttpInfo::TPtr ev) {
- const auto& cgi = ev->Get()->Request.GetParams();
- ui32 maxUnreadableBlobs = 100;
- if (cgi.Has("maxUnreadableBlobs")) {
- TryFromString<ui32>(cgi.Get("maxUnreadableBlobs"), maxUnreadableBlobs);
- }
- Send(ev->Sender, new NMon::TEvHttpInfoRes(RenderHtml(maxUnreadableBlobs), ev->Get()->SubRequestId));
- }
-
- TString TScrubCoroImpl::RenderHtml(ui32 maxUnreadableBlobs) const {
- TStringStream out;
- HTML(out) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Scrub";
- }
- DIV_CLASS("panel-body") {
- out << CurrentState;
- out << "<br>State: " << (State ? State->DebugString() : "<null>");
-
- out << "<br>UnreadableBlobs";
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { out << "BlobId"; }
- TABLEH() { out << "UnreadableParts"; }
- }
- }
- TABLEBODY() {
- std::vector<std::pair<TLogoBlobID, NMatrix::TVectorType>> blobs;
- blobs.reserve(UnreadableBlobs.size());
- for (const auto& [blobId, state] : UnreadableBlobs) {
- blobs.emplace_back(blobId, state.UnreadableParts);
- }
- auto comp = [](const auto& x, const auto& y) { return x.first < y.first; };
- std::sort(blobs.begin(), blobs.end(), comp);
- ui32 num = 0;
- for (const auto& [blobId, unreadableParts] : blobs) {
- TABLER() {
- TABLED() {
- out << blobId;
- }
- TABLED() {
- out << unreadableParts.ToString();
- }
- }
- if (++num == maxUnreadableBlobs) {
- break;
- }
- }
- }
- }
- }
- }
- }
- return out.Str();
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+
+namespace NKikimr {
+
+ void TScrubCoroImpl::Handle(NMon::TEvHttpInfo::TPtr ev) {
+ const auto& cgi = ev->Get()->Request.GetParams();
+ ui32 maxUnreadableBlobs = 100;
+ if (cgi.Has("maxUnreadableBlobs")) {
+ TryFromString<ui32>(cgi.Get("maxUnreadableBlobs"), maxUnreadableBlobs);
+ }
+ Send(ev->Sender, new NMon::TEvHttpInfoRes(RenderHtml(maxUnreadableBlobs), ev->Get()->SubRequestId));
+ }
+
+ TString TScrubCoroImpl::RenderHtml(ui32 maxUnreadableBlobs) const {
+ TStringStream out;
+ HTML(out) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Scrub";
+ }
+ DIV_CLASS("panel-body") {
+ out << CurrentState;
+ out << "<br>State: " << (State ? State->DebugString() : "<null>");
+
+ out << "<br>UnreadableBlobs";
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { out << "BlobId"; }
+ TABLEH() { out << "UnreadableParts"; }
+ }
+ }
+ TABLEBODY() {
+ std::vector<std::pair<TLogoBlobID, NMatrix::TVectorType>> blobs;
+ blobs.reserve(UnreadableBlobs.size());
+ for (const auto& [blobId, state] : UnreadableBlobs) {
+ blobs.emplace_back(blobId, state.UnreadableParts);
+ }
+ auto comp = [](const auto& x, const auto& y) { return x.first < y.first; };
+ std::sort(blobs.begin(), blobs.end(), comp);
+ ui32 num = 0;
+ for (const auto& [blobId, unreadableParts] : blobs) {
+ TABLER() {
+ TABLED() {
+ out << blobId;
+ }
+ TABLED() {
+ out << unreadableParts.ToString();
+ }
+ }
+ if (++num == maxUnreadableBlobs) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return out.Str();
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_pdisk.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_pdisk.cpp
index 19c54ac664d..5632fec5b65 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_pdisk.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_pdisk.cpp
@@ -1,45 +1,45 @@
-#include "scrub_actor_impl.h"
-
-namespace NKikimr {
-
- std::optional<TString> TScrubCoroImpl::Read(const TDiskPart& part) {
- Y_VERIFY(part.ChunkIdx);
- Y_VERIFY(part.Size);
- auto msg = std::make_unique<NPDisk::TEvChunkRead>(ScrubCtx->PDiskCtx->Dsk->Owner,
- ScrubCtx->PDiskCtx->Dsk->OwnerRound, part.ChunkIdx, part.Offset, part.Size, NPriRead::HullLow, nullptr);
- Send(ScrubCtx->PDiskCtx->PDiskId, msg.release());
- CurrentState = TStringBuilder() << "reading data from " << part.ToString();
- auto res = WaitForPDiskEvent<NPDisk::TEvChunkReadResult>();
- auto *m = res->Get();
- Y_VERIFY_S(m->Status == NKikimrProto::OK || m->Status == NKikimrProto::CORRUPTED,
- "Status# " << NKikimrProto::EReplyStatus_Name(m->Status));
- return m->Status == NKikimrProto::OK ? std::make_optional(m->Data.ToString()) : std::nullopt;
- }
-
- bool TScrubCoroImpl::IsReadable(const TDiskPart& part) {
- return Read(part).has_value();
- }
-
- void TScrubCoroImpl::Write(const TDiskPart& part, TString data) {
- Y_VERIFY(part.ChunkIdx);
- Y_VERIFY(part.Size);
- size_t alignedSize = data.size();
- if (const size_t offset = alignedSize % ScrubCtx->PDiskCtx->Dsk->AppendBlockSize) {
- alignedSize += ScrubCtx->PDiskCtx->Dsk->AppendBlockSize - offset;
- }
- auto msg = std::make_unique<NPDisk::TEvChunkWrite>(
- ScrubCtx->PDiskCtx->Dsk->Owner,
- ScrubCtx->PDiskCtx->Dsk->OwnerRound,
- part.ChunkIdx,
- part.Offset,
- MakeIntrusive<NPDisk::TEvChunkWrite::TAlignedParts>(std::move(data), alignedSize),
- nullptr,
- true,
- NPriWrite::HullComp);
- Send(ScrubCtx->PDiskCtx->PDiskId, msg.release());
- CurrentState = TStringBuilder() << "writing index to " << part.ToString();
- auto res = WaitForPDiskEvent<NPDisk::TEvChunkWriteResult>();
- Y_VERIFY(res->Get()->Status == NKikimrProto::OK); // FIXME: good logic
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+
+namespace NKikimr {
+
+ std::optional<TString> TScrubCoroImpl::Read(const TDiskPart& part) {
+ Y_VERIFY(part.ChunkIdx);
+ Y_VERIFY(part.Size);
+ auto msg = std::make_unique<NPDisk::TEvChunkRead>(ScrubCtx->PDiskCtx->Dsk->Owner,
+ ScrubCtx->PDiskCtx->Dsk->OwnerRound, part.ChunkIdx, part.Offset, part.Size, NPriRead::HullLow, nullptr);
+ Send(ScrubCtx->PDiskCtx->PDiskId, msg.release());
+ CurrentState = TStringBuilder() << "reading data from " << part.ToString();
+ auto res = WaitForPDiskEvent<NPDisk::TEvChunkReadResult>();
+ auto *m = res->Get();
+ Y_VERIFY_S(m->Status == NKikimrProto::OK || m->Status == NKikimrProto::CORRUPTED,
+ "Status# " << NKikimrProto::EReplyStatus_Name(m->Status));
+ return m->Status == NKikimrProto::OK ? std::make_optional(m->Data.ToString()) : std::nullopt;
+ }
+
+ bool TScrubCoroImpl::IsReadable(const TDiskPart& part) {
+ return Read(part).has_value();
+ }
+
+ void TScrubCoroImpl::Write(const TDiskPart& part, TString data) {
+ Y_VERIFY(part.ChunkIdx);
+ Y_VERIFY(part.Size);
+ size_t alignedSize = data.size();
+ if (const size_t offset = alignedSize % ScrubCtx->PDiskCtx->Dsk->AppendBlockSize) {
+ alignedSize += ScrubCtx->PDiskCtx->Dsk->AppendBlockSize - offset;
+ }
+ auto msg = std::make_unique<NPDisk::TEvChunkWrite>(
+ ScrubCtx->PDiskCtx->Dsk->Owner,
+ ScrubCtx->PDiskCtx->Dsk->OwnerRound,
+ part.ChunkIdx,
+ part.Offset,
+ MakeIntrusive<NPDisk::TEvChunkWrite::TAlignedParts>(std::move(data), alignedSize),
+ nullptr,
+ true,
+ NPriWrite::HullComp);
+ Send(ScrubCtx->PDiskCtx->PDiskId, msg.release());
+ CurrentState = TStringBuilder() << "writing index to " << part.ToString();
+ auto res = WaitForPDiskEvent<NPDisk::TEvChunkWriteResult>();
+ Y_VERIFY(res->Get()->Status == NKikimrProto::OK); // FIXME: good logic
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_snapshot.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_snapshot.cpp
index 14054d2bde3..98cac516fc0 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_snapshot.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_snapshot.cpp
@@ -1,26 +1,26 @@
-#include "scrub_actor_impl.h"
-
-namespace NKikimr {
-
- void TScrubCoroImpl::TakeSnapshot() {
- Send(ScrubCtx->SkeletonId, new TEvTakeHullSnapshot(false));
- CurrentState = TStringBuilder() << "waiting for Hull snapshot";
- auto res = WaitForSpecificEvent<TEvTakeHullSnapshotResult>();
- Snap.emplace(std::move(res->Get()->Snap));
- Snap->BarriersSnap.Destroy(); // barriers are not needed for operation
- }
-
- void TScrubCoroImpl::ReleaseSnapshot() {
- Snap.reset();
- BarriersEssence.Reset();
- }
-
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> TScrubCoroImpl::GetBarriersEssence() {
- if (!BarriersEssence) {
- BarriersEssence = Snap->BarriersSnap.CreateEssence(Snap->HullCtx);
- Snap->BarriersSnap.Destroy();
- }
- return BarriersEssence;
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+
+namespace NKikimr {
+
+ void TScrubCoroImpl::TakeSnapshot() {
+ Send(ScrubCtx->SkeletonId, new TEvTakeHullSnapshot(false));
+ CurrentState = TStringBuilder() << "waiting for Hull snapshot";
+ auto res = WaitForSpecificEvent<TEvTakeHullSnapshotResult>();
+ Snap.emplace(std::move(res->Get()->Snap));
+ Snap->BarriersSnap.Destroy(); // barriers are not needed for operation
+ }
+
+ void TScrubCoroImpl::ReleaseSnapshot() {
+ Snap.reset();
+ BarriersEssence.Reset();
+ }
+
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> TScrubCoroImpl::GetBarriersEssence() {
+ if (!BarriersEssence) {
+ BarriersEssence = Snap->BarriersSnap.CreateEssence(Snap->HullCtx);
+ Snap->BarriersSnap.Destroy();
+ }
+ return BarriersEssence;
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst.cpp
index 7da3cf9acb0..c9624fef514 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst.cpp
@@ -1,236 +1,236 @@
-#include "scrub_actor_impl.h"
-#include "scrub_actor_sst_blob_merger.h"
-
-namespace NKikimr {
-
- void TScrubCoroImpl::ScrubSst(TLevelSegmentPtr sst) {
- SstId = sst->AssignedSstId;
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS03, VDISKP(LogPrefix, "starting to scrub SST"), (SstId, SstId));
- auto blobsOnDisk = MakeBlobList(sst);
- ReadOutAndResilverIndex(sst);
- ReadOutSelectedBlobs(std::move(blobsOnDisk));
- SstId.reset();
- ++*SstProcessed;
- }
-
- std::vector<TScrubCoroImpl::TBlobOnDisk> TScrubCoroImpl::MakeBlobList(TLevelSegmentPtr sst) {
- std::vector<TScrubCoroImpl::TBlobOnDisk> res;
- TSstBlobMerger merger(*Snap, GetBarriersEssence());
- TLevelSegment::TMemIterator iter(sst.Get());
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- iter.PutToMerger(&merger);
- const TLogoBlobID& id = iter.GetCurKey().LogoBlobID();
- if (merger.Keep(id)) {
- res.insert(res.end(), merger.BlobsOnDisk.begin(), merger.BlobsOnDisk.end());
- } else {
- DropGarbageBlob(id);
- }
- merger.Clear();
- }
- return res;
- }
-
- void TScrubCoroImpl::ReadOutAndResilverIndex(TLevelSegmentPtr sst) {
- TDiskPart prevPart;
- bool first = true;
- ui32 remainOutboundSize = sst->LoadedOutbound.size() * sizeof(TDiskPart);
- ui32 remainIndexSize = sst->LoadedIndex.size() * sizeof(TLevelSegment::TRec);
- for (TDiskPart part : sst->IndexParts) {
- TString regen = TString::Uninitialized(part.Size);
- ui32 destLen = regen.size();
- char *dest = regen.Detach() + destLen;
- auto prepend = [&destLen, &dest](const void *data, ui32 len) {
- if (len) {
- Y_VERIFY(len <= destLen);
- destLen -= len;
- dest -= len;
- memcpy(dest, data, len);
- }
- };
-
- // first step: fill in the header
- if (first) {
- TIdxDiskPlaceHolder header(sst->AssignedSstId);
- header.PrevPart = prevPart;
- header.Info = sst->Info;
- if (sst->Info.IsCreatedByRepl()) {
- header.Info.FirstLsn = header.Info.LastLsn = 0;
- }
- prepend(&header, sizeof(header));
- } else {
- TIdxDiskLinker header;
- header.PrevPart = prevPart;
- prepend(&header, sizeof(header));
- }
-
- // second step: fill outbound (if some data remains)
- const ui32 osize = Min(remainOutboundSize, destLen);
- remainOutboundSize -= osize;
- prepend(reinterpret_cast<const char*>(sst->LoadedOutbound.data()) + remainOutboundSize, osize);
-
- // third step: the index
- const ui32 isize = Min(remainIndexSize, destLen);
- remainIndexSize -= isize;
- prepend(reinterpret_cast<const char*>(sst->LoadedIndex.data()) + remainIndexSize, isize);
-
- // fourth step: sanity check
- Y_VERIFY(!destLen);
-
- std::optional<TString> data = Read(part);
- if (!data) {
- STLOGX(GetActorContext(), PRI_WARN, BS_VDISK_SCRUB, VDS13, VDISKP(LogPrefix, "index is corrupt, restoring"),
- (SstId, sst->AssignedSstId), (Location, part));
-
- ui32 offset = part.Offset - part.Offset % ScrubCtx->PDiskCtx->Dsk->AppendBlockSize;
- if (const ui32 prefixLen = part.Offset - offset) {
- // restore prefixLen bytes of data before the index
- std::optional<TString> data = Read(TDiskPart(part.ChunkIdx, offset, prefixLen));
- if (data) {
- regen = *data + regen;
- part.Offset = offset;
- part.Size += prefixLen;
- } else {
- STLOGX(GetActorContext(), PRI_CRIT, BS_VDISK_SCRUB, VDS38, VDISKP(LogPrefix, "index is corrupt and can't be restored"),
- (SstId, sst->AssignedSstId));
- Success = false;
- return;
- }
- }
-
- if (regen) {
- Write(part, regen);
- Checkpoints |= TEvScrubNotify::INDEX_RESTORED;
- }
- } else {
- Y_VERIFY(regen.size() == data->size(), "index size differs from one stored in memory");
- const size_t headerLen = first ? sizeof(TIdxDiskPlaceHolder) : sizeof(TIdxDiskLinker);
- Y_VERIFY(memcmp(regen.data(), data->data(), part.Size - headerLen) == 0,
- "index data differs from one stored in memory"); // compare index data up to header
- auto compare = [&](auto a, auto b) {
- Y_VERIFY(sizeof(a) == headerLen && sizeof(b) == headerLen);
- memcpy(&a, regen.data() + regen.size() - headerLen, headerLen); // to prevent unaligned access
- memcpy(&b, data->data() + data->size() - headerLen, headerLen);
- Y_VERIFY(a == b, "index header differs from one stored in memory");
- };
- if (first) {
- compare(TIdxDiskPlaceHolder(0), TIdxDiskPlaceHolder(0));
- } else {
- compare(TIdxDiskLinker(), TIdxDiskLinker());
- }
- }
-
- prevPart = part;
- first = false;
- }
- Y_VERIFY(!remainOutboundSize && !remainIndexSize);
- }
-
- void TScrubCoroImpl::ReadOutSelectedBlobs(std::vector<TBlobOnDisk>&& blobsOnDisk) {
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS14, VDISKP(LogPrefix, "reading out SST"), (SstId, SstId),
- (NumBlobs, blobsOnDisk.size()));
-
- // scan all the blobs and sort them out -- huge blobs can be checked directly by reading them, small blobs
- // are split into chunks with intervals
- std::map<TChunkIdx, std::vector<TBlobOnDisk*>> chunks;
- for (TBlobOnDisk& blob : blobsOnDisk) {
- chunks[blob.Part.ChunkIdx].push_back(&blob);
- }
- for (auto& [chunkIdx, blobs] : chunks) {
- std::sort(blobs.begin(), blobs.end(), [](const auto *x, const auto *y) { return x->Part.Offset < y->Part.Offset; });
- }
-
- // scan small blob chunks
- struct TBlobToCheck {
- TLogoBlobID Id;
- NMatrix::TVectorType Needed;
- TDiskPart CorruptedPart;
- };
- std::vector<TBlobOnDisk*> pendingBlobs;
- std::vector<TBlobToCheck> blobsToCheck;
- for (const auto& [chunkIdx, blobs] : chunks) {
- const auto chunkIdx_{chunkIdx};
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS08, VDISKP(LogPrefix, "reading out chunk"), (SstId, SstId),
- (ChunkIdx, chunkIdx_));
- TDiskPart interval;
- auto doCheck = [&] {
- if (interval != TDiskPart()) {
- const bool intervalReadable = IsReadable(interval);
- STLOGX(GetActorContext(), intervalReadable ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS04,
- VDISKP(LogPrefix, "small blob interval checked"), (Interval, interval),
- (IsReadable, intervalReadable), (NumBlobsOfInterest, pendingBlobs.size()));
- ++*SmallBlobIntervalsRead;
- *SmallBlobIntervalBytesRead += interval.Size;
-
- for (TBlobOnDisk *blob : pendingBlobs) {
- const bool blobReadable = intervalReadable || IsReadable(blob->Part);
- if (!intervalReadable) {
- STLOGX(GetActorContext(), blobReadable ? PRI_INFO : PRI_ERROR, BS_VDISK_SCRUB, VDS12,
- VDISKP(LogPrefix, "small blob from unreadable interval checked"),
- (Key, blob->Id), (Location, blob->Part), (IsReadable, blobReadable));
- ++*SmallBlobsRead;
- *SmallBlobBytesRead += blob->Part.Size;
- }
- if (blobReadable) {
- UpdateReadableParts(blob->Id, blob->Local);
- } else {
- blobsToCheck.push_back({blob->Id, blob->Local, blob->Part});
- Checkpoints |= TEvScrubNotify::SMALL_BLOB_SCRUBBED;
- }
- }
- }
- pendingBlobs.clear();
- };
- for (TBlobOnDisk *blob : blobs) {
- const TDiskPart& part = blob->Part;
- const ui32 end = part.Offset + part.Size;
- Y_VERIFY(part.ChunkIdx == chunkIdx);
- if (interval == TDiskPart()) {
- interval = blob->Part;
- } else if (end - interval.Offset <= ScrubCtx->PDiskCtx->Dsk->ReadBlockSize) {
- interval.Size = end - interval.Offset;
- } else {
- doCheck();
- interval = blob->Part;
- }
- pendingBlobs.push_back(blob);
- }
- doCheck();
- }
-
- if (blobsToCheck.empty()) {
- return;
- }
-
- // find unreadable blobs which can't be read from other places
- TLevelIndexSnapshot::TForwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
- TBlobLocationExtractorMerger merger(Info->Type);
- for (const TBlobToCheck& blob : blobsToCheck) {
- iter.Seek(blob.Id);
- if (iter.Valid() && iter.GetCurKey() == blob.Id) {
- iter.PutToMerger(&merger);
-
- NMatrix::TVectorType needed = blob.Needed;
- Y_VERIFY(!needed.Empty());
-
- STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS11, VDISKP(LogPrefix, "reading out blob"), (SstId, SstId),
- (Id, blob.Id));
-
- for (const TBlobOnDisk& replica : merger.BlobsOnDisk) {
- if (!(replica.Local & needed).Empty()) {
- const bool blobReadable = IsReadable(replica.Part);
- STLOGX(GetActorContext(), blobReadable ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS16,
- VDISKP(LogPrefix, "read replica"), (SstId, SstId), (Id, blob.Id), (Location, replica.Part),
- (Local, replica.Local), (IsReadable, blobReadable));
- if (blobReadable) {
- needed &= ~replica.Local;
- }
- }
- }
-
- UpdateUnreadableParts(blob.Id, needed, blob.CorruptedPart);
- merger.Clear();
- }
- }
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+#include "scrub_actor_sst_blob_merger.h"
+
+namespace NKikimr {
+
+ void TScrubCoroImpl::ScrubSst(TLevelSegmentPtr sst) {
+ SstId = sst->AssignedSstId;
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS03, VDISKP(LogPrefix, "starting to scrub SST"), (SstId, SstId));
+ auto blobsOnDisk = MakeBlobList(sst);
+ ReadOutAndResilverIndex(sst);
+ ReadOutSelectedBlobs(std::move(blobsOnDisk));
+ SstId.reset();
+ ++*SstProcessed;
+ }
+
+ std::vector<TScrubCoroImpl::TBlobOnDisk> TScrubCoroImpl::MakeBlobList(TLevelSegmentPtr sst) {
+ std::vector<TScrubCoroImpl::TBlobOnDisk> res;
+ TSstBlobMerger merger(*Snap, GetBarriersEssence());
+ TLevelSegment::TMemIterator iter(sst.Get());
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ iter.PutToMerger(&merger);
+ const TLogoBlobID& id = iter.GetCurKey().LogoBlobID();
+ if (merger.Keep(id)) {
+ res.insert(res.end(), merger.BlobsOnDisk.begin(), merger.BlobsOnDisk.end());
+ } else {
+ DropGarbageBlob(id);
+ }
+ merger.Clear();
+ }
+ return res;
+ }
+
+ void TScrubCoroImpl::ReadOutAndResilverIndex(TLevelSegmentPtr sst) {
+ TDiskPart prevPart;
+ bool first = true;
+ ui32 remainOutboundSize = sst->LoadedOutbound.size() * sizeof(TDiskPart);
+ ui32 remainIndexSize = sst->LoadedIndex.size() * sizeof(TLevelSegment::TRec);
+ for (TDiskPart part : sst->IndexParts) {
+ TString regen = TString::Uninitialized(part.Size);
+ ui32 destLen = regen.size();
+ char *dest = regen.Detach() + destLen;
+ auto prepend = [&destLen, &dest](const void *data, ui32 len) {
+ if (len) {
+ Y_VERIFY(len <= destLen);
+ destLen -= len;
+ dest -= len;
+ memcpy(dest, data, len);
+ }
+ };
+
+ // first step: fill in the header
+ if (first) {
+ TIdxDiskPlaceHolder header(sst->AssignedSstId);
+ header.PrevPart = prevPart;
+ header.Info = sst->Info;
+ if (sst->Info.IsCreatedByRepl()) {
+ header.Info.FirstLsn = header.Info.LastLsn = 0;
+ }
+ prepend(&header, sizeof(header));
+ } else {
+ TIdxDiskLinker header;
+ header.PrevPart = prevPart;
+ prepend(&header, sizeof(header));
+ }
+
+ // second step: fill outbound (if some data remains)
+ const ui32 osize = Min(remainOutboundSize, destLen);
+ remainOutboundSize -= osize;
+ prepend(reinterpret_cast<const char*>(sst->LoadedOutbound.data()) + remainOutboundSize, osize);
+
+ // third step: the index
+ const ui32 isize = Min(remainIndexSize, destLen);
+ remainIndexSize -= isize;
+ prepend(reinterpret_cast<const char*>(sst->LoadedIndex.data()) + remainIndexSize, isize);
+
+ // fourth step: sanity check
+ Y_VERIFY(!destLen);
+
+ std::optional<TString> data = Read(part);
+ if (!data) {
+ STLOGX(GetActorContext(), PRI_WARN, BS_VDISK_SCRUB, VDS13, VDISKP(LogPrefix, "index is corrupt, restoring"),
+ (SstId, sst->AssignedSstId), (Location, part));
+
+ ui32 offset = part.Offset - part.Offset % ScrubCtx->PDiskCtx->Dsk->AppendBlockSize;
+ if (const ui32 prefixLen = part.Offset - offset) {
+ // restore prefixLen bytes of data before the index
+ std::optional<TString> data = Read(TDiskPart(part.ChunkIdx, offset, prefixLen));
+ if (data) {
+ regen = *data + regen;
+ part.Offset = offset;
+ part.Size += prefixLen;
+ } else {
+ STLOGX(GetActorContext(), PRI_CRIT, BS_VDISK_SCRUB, VDS38, VDISKP(LogPrefix, "index is corrupt and can't be restored"),
+ (SstId, sst->AssignedSstId));
+ Success = false;
+ return;
+ }
+ }
+
+ if (regen) {
+ Write(part, regen);
+ Checkpoints |= TEvScrubNotify::INDEX_RESTORED;
+ }
+ } else {
+ Y_VERIFY(regen.size() == data->size(), "index size differs from one stored in memory");
+ const size_t headerLen = first ? sizeof(TIdxDiskPlaceHolder) : sizeof(TIdxDiskLinker);
+ Y_VERIFY(memcmp(regen.data(), data->data(), part.Size - headerLen) == 0,
+ "index data differs from one stored in memory"); // compare index data up to header
+ auto compare = [&](auto a, auto b) {
+ Y_VERIFY(sizeof(a) == headerLen && sizeof(b) == headerLen);
+ memcpy(&a, regen.data() + regen.size() - headerLen, headerLen); // to prevent unaligned access
+ memcpy(&b, data->data() + data->size() - headerLen, headerLen);
+ Y_VERIFY(a == b, "index header differs from one stored in memory");
+ };
+ if (first) {
+ compare(TIdxDiskPlaceHolder(0), TIdxDiskPlaceHolder(0));
+ } else {
+ compare(TIdxDiskLinker(), TIdxDiskLinker());
+ }
+ }
+
+ prevPart = part;
+ first = false;
+ }
+ Y_VERIFY(!remainOutboundSize && !remainIndexSize);
+ }
+
+ void TScrubCoroImpl::ReadOutSelectedBlobs(std::vector<TBlobOnDisk>&& blobsOnDisk) {
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS14, VDISKP(LogPrefix, "reading out SST"), (SstId, SstId),
+ (NumBlobs, blobsOnDisk.size()));
+
+ // scan all the blobs and sort them out -- huge blobs can be checked directly by reading them, small blobs
+ // are split into chunks with intervals
+ std::map<TChunkIdx, std::vector<TBlobOnDisk*>> chunks;
+ for (TBlobOnDisk& blob : blobsOnDisk) {
+ chunks[blob.Part.ChunkIdx].push_back(&blob);
+ }
+ for (auto& [chunkIdx, blobs] : chunks) {
+ std::sort(blobs.begin(), blobs.end(), [](const auto *x, const auto *y) { return x->Part.Offset < y->Part.Offset; });
+ }
+
+ // scan small blob chunks
+ struct TBlobToCheck {
+ TLogoBlobID Id;
+ NMatrix::TVectorType Needed;
+ TDiskPart CorruptedPart;
+ };
+ std::vector<TBlobOnDisk*> pendingBlobs;
+ std::vector<TBlobToCheck> blobsToCheck;
+ for (const auto& [chunkIdx, blobs] : chunks) {
+ const auto chunkIdx_{chunkIdx};
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS08, VDISKP(LogPrefix, "reading out chunk"), (SstId, SstId),
+ (ChunkIdx, chunkIdx_));
+ TDiskPart interval;
+ auto doCheck = [&] {
+ if (interval != TDiskPart()) {
+ const bool intervalReadable = IsReadable(interval);
+ STLOGX(GetActorContext(), intervalReadable ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS04,
+ VDISKP(LogPrefix, "small blob interval checked"), (Interval, interval),
+ (IsReadable, intervalReadable), (NumBlobsOfInterest, pendingBlobs.size()));
+ ++*SmallBlobIntervalsRead;
+ *SmallBlobIntervalBytesRead += interval.Size;
+
+ for (TBlobOnDisk *blob : pendingBlobs) {
+ const bool blobReadable = intervalReadable || IsReadable(blob->Part);
+ if (!intervalReadable) {
+ STLOGX(GetActorContext(), blobReadable ? PRI_INFO : PRI_ERROR, BS_VDISK_SCRUB, VDS12,
+ VDISKP(LogPrefix, "small blob from unreadable interval checked"),
+ (Key, blob->Id), (Location, blob->Part), (IsReadable, blobReadable));
+ ++*SmallBlobsRead;
+ *SmallBlobBytesRead += blob->Part.Size;
+ }
+ if (blobReadable) {
+ UpdateReadableParts(blob->Id, blob->Local);
+ } else {
+ blobsToCheck.push_back({blob->Id, blob->Local, blob->Part});
+ Checkpoints |= TEvScrubNotify::SMALL_BLOB_SCRUBBED;
+ }
+ }
+ }
+ pendingBlobs.clear();
+ };
+ for (TBlobOnDisk *blob : blobs) {
+ const TDiskPart& part = blob->Part;
+ const ui32 end = part.Offset + part.Size;
+ Y_VERIFY(part.ChunkIdx == chunkIdx);
+ if (interval == TDiskPart()) {
+ interval = blob->Part;
+ } else if (end - interval.Offset <= ScrubCtx->PDiskCtx->Dsk->ReadBlockSize) {
+ interval.Size = end - interval.Offset;
+ } else {
+ doCheck();
+ interval = blob->Part;
+ }
+ pendingBlobs.push_back(blob);
+ }
+ doCheck();
+ }
+
+ if (blobsToCheck.empty()) {
+ return;
+ }
+
+ // find unreadable blobs which can't be read from other places
+ TLevelIndexSnapshot::TForwardIterator iter(Snap->HullCtx, &Snap->LogoBlobsSnap);
+ TBlobLocationExtractorMerger merger(Info->Type);
+ for (const TBlobToCheck& blob : blobsToCheck) {
+ iter.Seek(blob.Id);
+ if (iter.Valid() && iter.GetCurKey() == blob.Id) {
+ iter.PutToMerger(&merger);
+
+ NMatrix::TVectorType needed = blob.Needed;
+ Y_VERIFY(!needed.Empty());
+
+ STLOGX(GetActorContext(), PRI_INFO, BS_VDISK_SCRUB, VDS11, VDISKP(LogPrefix, "reading out blob"), (SstId, SstId),
+ (Id, blob.Id));
+
+ for (const TBlobOnDisk& replica : merger.BlobsOnDisk) {
+ if (!(replica.Local & needed).Empty()) {
+ const bool blobReadable = IsReadable(replica.Part);
+ STLOGX(GetActorContext(), blobReadable ? PRI_DEBUG : PRI_ERROR, BS_VDISK_SCRUB, VDS16,
+ VDISKP(LogPrefix, "read replica"), (SstId, SstId), (Id, blob.Id), (Location, replica.Part),
+ (Local, replica.Local), (IsReadable, blobReadable));
+ if (blobReadable) {
+ needed &= ~replica.Local;
+ }
+ }
+ }
+
+ UpdateUnreadableParts(blob.Id, needed, blob.CorruptedPart);
+ merger.Clear();
+ }
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h
index fb0a27df6ef..054b7fca030 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_sst_blob_merger.h
@@ -1,118 +1,118 @@
-#pragma once
-
-#include "defs.h"
-#include "scrub_actor_impl.h"
-
-namespace NKikimr {
-
- class TScrubCoroImpl::TBlobLocationExtractorMerger {
- protected:
- const TBlobStorageGroupType GType;
-
- public:
- std::vector<TBlobOnDisk> BlobsOnDisk;
-
- public:
- TBlobLocationExtractorMerger(const TBlobStorageGroupType& gtype)
- : GType(gtype)
- {}
-
- static bool HaveToMergeData() { return true; }
-
- // process on-disk data
+#pragma once
+
+#include "defs.h"
+#include "scrub_actor_impl.h"
+
+namespace NKikimr {
+
+ class TScrubCoroImpl::TBlobLocationExtractorMerger {
+ protected:
+ const TBlobStorageGroupType GType;
+
+ public:
+ std::vector<TBlobOnDisk> BlobsOnDisk;
+
+ public:
+ TBlobLocationExtractorMerger(const TBlobStorageGroupType& gtype)
+ : GType(gtype)
+ {}
+
+ static bool HaveToMergeData() { return true; }
+
+ // process on-disk data
void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key,
ui64 /*circaLsn*/) {
- if (memRec.GetType() != TBlobType::DiskBlob) {
- return;
- }
-
- // extract blob location
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, outbound);
- const TDiskPart& part = extr.SwearOne();
- if (part.ChunkIdx && part.Size) {
- const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
- BlobsOnDisk.push_back({key.LogoBlobID(), local, part});
- }
- }
-
- // just ignore in-memory data
- void AddFromFresh(const TMemRecLogoBlob& /*memRec*/, const TRope* /*data*/, const TKeyLogoBlob& /*key*/,
- ui64 /*lsn*/)
- {}
-
- void Clear() {
- BlobsOnDisk.clear();
- }
- };
-
- class TScrubCoroImpl::TSstBlobMerger : public TBlobLocationExtractorMerger {
- TLevelIndexSnapshot::TForwardIterator Iter; // whole database iterator to merge records for GC checking
- TIndexRecordMerger Merger; // merger for these records
- TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> Essence;
- const bool AllowKeepFlags;
- std::optional<bool> KeepData;
-
- public:
- TSstBlobMerger(const THullDsSnap& snap, TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> essence)
- : TBlobLocationExtractorMerger(snap.HullCtx->VCtx->Top->GType)
- , Iter(snap.HullCtx, &snap.LogoBlobsSnap)
- , Merger(GType)
- , Essence(std::move(essence))
- , AllowKeepFlags(snap.HullCtx->AllowKeepFlags)
- {
- Iter.SeekToFirst();
- }
-
- static bool HaveToMergeData() { return true; }
-
- // process on-disk data
+ if (memRec.GetType() != TBlobType::DiskBlob) {
+ return;
+ }
+
+ // extract blob location
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, outbound);
+ const TDiskPart& part = extr.SwearOne();
+ if (part.ChunkIdx && part.Size) {
+ const NMatrix::TVectorType local = memRec.GetLocalParts(GType);
+ BlobsOnDisk.push_back({key.LogoBlobID(), local, part});
+ }
+ }
+
+ // just ignore in-memory data
+ void AddFromFresh(const TMemRecLogoBlob& /*memRec*/, const TRope* /*data*/, const TKeyLogoBlob& /*key*/,
+ ui64 /*lsn*/)
+ {}
+
+ void Clear() {
+ BlobsOnDisk.clear();
+ }
+ };
+
+ class TScrubCoroImpl::TSstBlobMerger : public TBlobLocationExtractorMerger {
+ TLevelIndexSnapshot::TForwardIterator Iter; // whole database iterator to merge records for GC checking
+ TIndexRecordMerger Merger; // merger for these records
+ TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> Essence;
+ const bool AllowKeepFlags;
+ std::optional<bool> KeepData;
+
+ public:
+ TSstBlobMerger(const THullDsSnap& snap, TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> essence)
+ : TBlobLocationExtractorMerger(snap.HullCtx->VCtx->Top->GType)
+ , Iter(snap.HullCtx, &snap.LogoBlobsSnap)
+ , Merger(GType)
+ , Essence(std::move(essence))
+ , AllowKeepFlags(snap.HullCtx->AllowKeepFlags)
+ {
+ Iter.SeekToFirst();
+ }
+
+ static bool HaveToMergeData() { return true; }
+
+ // process on-disk data
void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key,
ui64 circaLsn) {
- if (memRec.GetType() == TBlobType::DiskBlob) {
+ if (memRec.GetType() == TBlobType::DiskBlob) {
TBlobLocationExtractorMerger::AddFromSegment(memRec, outbound, key, circaLsn);
- }
- }
-
- // just ignore in-memory data
- void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key, ui64 lsn) {
- TBlobLocationExtractorMerger::AddFromFresh(memRec, data, key, lsn);
- }
-
- void Clear() {
- KeepData.reset();
- TBlobLocationExtractorMerger::Clear();
- }
-
- bool Keep(const TLogoBlobID& id) {
- if (!KeepData) {
- // seek to the desired key; the key MUST exist in the whole database
- Y_VERIFY(Iter.Valid());
- Y_VERIFY(Iter.GetCurKey() <= id);
- if (Iter.GetCurKey() < id) {
- Iter.Next();
- Y_VERIFY(Iter.Valid());
- if (Iter.GetCurKey() < id) {
- Iter.Seek(id);
- }
- }
- Y_VERIFY(Iter.Valid() && Iter.GetCurKey() == id);
-
- // put iterator value to merger
- Iter.PutToMerger(&Merger);
- Merger.Finish();
-
- // obtain keep status
- NGc::TKeepStatus status = Essence->Keep(id, Merger.GetMemRec(), Merger.GetMemRecsMerged(), AllowKeepFlags);
-
- // clear merger for next operation
- Merger.Clear();
-
- // return true unless we need to discard this blob out of the list
- KeepData.emplace(status.KeepData);
- }
- return *KeepData;
- }
- };
-
-} // NKikimr
+ }
+ }
+
+ // just ignore in-memory data
+ void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key, ui64 lsn) {
+ TBlobLocationExtractorMerger::AddFromFresh(memRec, data, key, lsn);
+ }
+
+ void Clear() {
+ KeepData.reset();
+ TBlobLocationExtractorMerger::Clear();
+ }
+
+ bool Keep(const TLogoBlobID& id) {
+ if (!KeepData) {
+ // seek to the desired key; the key MUST exist in the whole database
+ Y_VERIFY(Iter.Valid());
+ Y_VERIFY(Iter.GetCurKey() <= id);
+ if (Iter.GetCurKey() < id) {
+ Iter.Next();
+ Y_VERIFY(Iter.Valid());
+ if (Iter.GetCurKey() < id) {
+ Iter.Seek(id);
+ }
+ }
+ Y_VERIFY(Iter.Valid() && Iter.GetCurKey() == id);
+
+ // put iterator value to merger
+ Iter.PutToMerger(&Merger);
+ Merger.Finish();
+
+ // obtain keep status
+ NGc::TKeepStatus status = Essence->Keep(id, Merger.GetMemRec(), Merger.GetMemRecsMerged(), AllowKeepFlags);
+
+ // clear merger for next operation
+ Merger.Clear();
+
+ // return true unless we need to discard this blob out of the list
+ KeepData.emplace(status.KeepData);
+ }
+ return *KeepData;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp
index 7d717019269..22839a1b27c 100644
--- a/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp
+++ b/ydb/core/blobstorage/vdisk/scrub/scrub_actor_unreadable.cpp
@@ -1,160 +1,160 @@
-#include "scrub_actor_impl.h"
-#include "restore_corrupted_blob_actor.h"
-
-namespace NKikimr {
-
- void TScrubCoroImpl::DropGarbageBlob(const TLogoBlobID& fullId) {
- Y_VERIFY(!fullId.PartId());
- if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
- STLOGX(GetActorContext(), PRI_NOTICE, BS_VDISK_SCRUB, VDS39, VDISKP(LogPrefix,
- "dropped garbage unreadable blob"), (BlobId, it->first), (UnreadableParts, it->second.UnreadableParts));
- *UnreadableBlobsFound -= it->second.UnreadableParts.CountBits();
- UnreadableBlobs.erase(it);
- }
- }
-
- void TScrubCoroImpl::AddUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart) {
- if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
- corrupted |= it->second.UnreadableParts;
- }
- UpdateUnreadableParts(fullId, corrupted, corruptedPart);
- }
-
- void TScrubCoroImpl::UpdateUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart) {
- Y_VERIFY(!fullId.PartId());
- const auto it = UnreadableBlobs.find(fullId);
-
- const NMatrix::TVectorType prevCorrupted = it != UnreadableBlobs.end()
- ? it->second.UnreadableParts
- : NMatrix::TVectorType(0, corrupted.GetSize());
-
- if (prevCorrupted != corrupted) {
- const NMatrix::TVectorType becameOk = prevCorrupted & ~corrupted;
- const NMatrix::TVectorType becameCorrupted = corrupted & ~prevCorrupted;
-
- STLOGX(GetActorContext(), becameCorrupted.Empty() ? PRI_NOTICE : PRI_ERROR, BS_VDISK_SCRUB, VDS41,
- VDISKP(LogPrefix, "huge blob corrupted state updated"), (BlobId, fullId),
- (UnreadablePartsBefore, prevCorrupted), (UnreadablePartsAfter, corrupted),
- (BecameOk, becameOk), (BecameCorrupted, becameCorrupted), (CorruptedPart, corruptedPart));
-
- if (corrupted.Empty()) {
- UnreadableBlobs.erase(it);
- } else if (it != UnreadableBlobs.end()) {
- it->second.UnreadableParts = corrupted;
- it->second.CorruptedPart = corruptedPart;
- if (!becameCorrupted.Empty()) { // retry recovery ASAP -- new unreadable parts found
- it->second.RecoveryInFlightCookie = 0;
- it->second.RetryTimestamp = TInstant::Zero();
- }
- } else {
- UnreadableBlobs.try_emplace(fullId, corrupted, corruptedPart);
- }
-
- *UnreadableBlobsFound += corrupted.CountBits() - prevCorrupted.CountBits();
- }
- }
-
- void TScrubCoroImpl::UpdateReadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType readable) {
- Y_VERIFY(!fullId.PartId());
- if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
- STLOGX(GetActorContext(), PRI_NOTICE, BS_VDISK_SCRUB, VDS42, VDISKP(LogPrefix,
- "read parts of previously unreadable blob"), (BlobId, it->first),
- (UnreadablePartsBefore, it->second.UnreadableParts), (ReadableParts, readable));
- *UnreadableBlobsFound -= (it->second.UnreadableParts & readable).CountBits();
- if ((it->second.UnreadableParts &= ~readable).Empty()) {
- UnreadableBlobs.erase(it);
- }
- }
- }
-
- ui64 TScrubCoroImpl::GenerateRestoreCorruptedBlobQuery() {
- const TInstant now = TActorCoroImpl::Now();
- std::vector<TEvRestoreCorruptedBlob::TItem> items;
-
- for (auto& [blobId, data] : UnreadableBlobs) {
- if (!data.RecoveryInFlightCookie && now >= data.RetryTimestamp) {
- data.RecoveryInFlightCookie = ++LastRestoreCookie;
- items.emplace_back(blobId, data.UnreadableParts, ScrubCtx->Info->Type, data.CorruptedPart,
- data.RecoveryInFlightCookie);
- const auto& p = data;
- const auto& q = blobId;
- STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS22, VDISKP(LogPrefix, "going to restore unreadable blob"),
- (Cookie, p.RecoveryInFlightCookie), (BlobId, q), (UnreadableParts, p.UnreadableParts),
- (CorruptedPart, p.CorruptedPart));
- }
- }
-
- if (!items.empty()) {
- const TInstant deadline = now + TDuration::Minutes(2);
- const ui64 cookie = ++LastRestoreCookie;
- Send(ScrubCtx->SkeletonId, new TEvRestoreCorruptedBlob(deadline, std::move(items), true, false), 0, cookie);
- return cookie;
- } else {
- return 0;
- }
- }
-
- void TScrubCoroImpl::Handle(TEvRestoreCorruptedBlobResult::TPtr ev) {
- const TInstant now = TActorCoroImpl::Now();
-
- for (const auto& item : ev->Get()->Items) {
- if (const auto it = UnreadableBlobs.find(item.BlobId); it != UnreadableBlobs.end()) {
- auto& data = it->second;
-
- if (!data.RecoveryInFlightCookie || data.RecoveryInFlightCookie != item.Cookie) {
- continue;
- }
- data.RecoveryInFlightCookie = 0;
- data.RetryTimestamp = now + TDuration::Minutes(1);
-
- if (item.Status == NKikimrProto::OK) {
- STLOG(PRI_NOTICE, BS_VDISK_SCRUB, VDS40, VDISKP(LogPrefix,
- "recovered parts of previously unreadable blob"), (BlobId, it->first),
- (UnreadablePartsBefore, data.UnreadableParts), (RecoveredParts, item.Needed));
-
- *UnreadableBlobsFound -= (data.UnreadableParts & item.Needed).CountBits();
- if ((data.UnreadableParts &= ~item.Needed).Empty()) {
- UnreadableBlobs.erase(it);
- }
-
- ++*BlobsFixed;
- } else {
- STLOG(PRI_WARN, BS_VDISK_SCRUB, VDS07, VDISKP(LogPrefix, "failed to restore corrupted blob"),
- (BlobId, item.BlobId), (Status, item.Status));
- }
- }
- }
-
- if (UnreadableBlobs.empty()) { // all blobs found so far are repaired
- Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(false));
- } else if (!GenerateRestoreCorruptedBlobQueryScheduled) { // retry in some time
- TInstant when = TInstant::Max();
- for (const auto& [blobId, data] : UnreadableBlobs) {
- if (!data.RecoveryInFlightCookie) {
- when = Min(when, data.RetryTimestamp);
- }
- }
- if (when != TInstant::Max()) {
- GetActorSystem()->Schedule(when, new IEventHandle(EvGenerateRestoreCorruptedBlobQuery, 0, SelfActorId,
- {}, nullptr, 0));
- GenerateRestoreCorruptedBlobQueryScheduled = true;
- }
- }
-
- LastReceivedRestoreCookie = Max(LastReceivedRestoreCookie, ev->Cookie);
- }
-
- void TScrubCoroImpl::Handle(TEvNonrestoredCorruptedBlobNotify::TPtr ev) {
- for (const auto& item : ev->Get()->Items) {
- AddUnreadableParts(item.BlobId, item.UnreadableParts, item.CorruptedPart);
- }
- GenerateRestoreCorruptedBlobQuery();
- }
-
- void TScrubCoroImpl::HandleGenerateRestoreCorruptedBlobQuery() {
- Y_VERIFY(GenerateRestoreCorruptedBlobQueryScheduled);
- GenerateRestoreCorruptedBlobQueryScheduled = false;
- GenerateRestoreCorruptedBlobQuery();
- }
-
-} // NKikimr
+#include "scrub_actor_impl.h"
+#include "restore_corrupted_blob_actor.h"
+
+namespace NKikimr {
+
+ void TScrubCoroImpl::DropGarbageBlob(const TLogoBlobID& fullId) {
+ Y_VERIFY(!fullId.PartId());
+ if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
+ STLOGX(GetActorContext(), PRI_NOTICE, BS_VDISK_SCRUB, VDS39, VDISKP(LogPrefix,
+ "dropped garbage unreadable blob"), (BlobId, it->first), (UnreadableParts, it->second.UnreadableParts));
+ *UnreadableBlobsFound -= it->second.UnreadableParts.CountBits();
+ UnreadableBlobs.erase(it);
+ }
+ }
+
+ void TScrubCoroImpl::AddUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart) {
+ if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
+ corrupted |= it->second.UnreadableParts;
+ }
+ UpdateUnreadableParts(fullId, corrupted, corruptedPart);
+ }
+
+ void TScrubCoroImpl::UpdateUnreadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType corrupted, TDiskPart corruptedPart) {
+ Y_VERIFY(!fullId.PartId());
+ const auto it = UnreadableBlobs.find(fullId);
+
+ const NMatrix::TVectorType prevCorrupted = it != UnreadableBlobs.end()
+ ? it->second.UnreadableParts
+ : NMatrix::TVectorType(0, corrupted.GetSize());
+
+ if (prevCorrupted != corrupted) {
+ const NMatrix::TVectorType becameOk = prevCorrupted & ~corrupted;
+ const NMatrix::TVectorType becameCorrupted = corrupted & ~prevCorrupted;
+
+ STLOGX(GetActorContext(), becameCorrupted.Empty() ? PRI_NOTICE : PRI_ERROR, BS_VDISK_SCRUB, VDS41,
+ VDISKP(LogPrefix, "huge blob corrupted state updated"), (BlobId, fullId),
+ (UnreadablePartsBefore, prevCorrupted), (UnreadablePartsAfter, corrupted),
+ (BecameOk, becameOk), (BecameCorrupted, becameCorrupted), (CorruptedPart, corruptedPart));
+
+ if (corrupted.Empty()) {
+ UnreadableBlobs.erase(it);
+ } else if (it != UnreadableBlobs.end()) {
+ it->second.UnreadableParts = corrupted;
+ it->second.CorruptedPart = corruptedPart;
+ if (!becameCorrupted.Empty()) { // retry recovery ASAP -- new unreadable parts found
+ it->second.RecoveryInFlightCookie = 0;
+ it->second.RetryTimestamp = TInstant::Zero();
+ }
+ } else {
+ UnreadableBlobs.try_emplace(fullId, corrupted, corruptedPart);
+ }
+
+ *UnreadableBlobsFound += corrupted.CountBits() - prevCorrupted.CountBits();
+ }
+ }
+
+ void TScrubCoroImpl::UpdateReadableParts(const TLogoBlobID& fullId, NMatrix::TVectorType readable) {
+ Y_VERIFY(!fullId.PartId());
+ if (const auto it = UnreadableBlobs.find(fullId); it != UnreadableBlobs.end()) {
+ STLOGX(GetActorContext(), PRI_NOTICE, BS_VDISK_SCRUB, VDS42, VDISKP(LogPrefix,
+ "read parts of previously unreadable blob"), (BlobId, it->first),
+ (UnreadablePartsBefore, it->second.UnreadableParts), (ReadableParts, readable));
+ *UnreadableBlobsFound -= (it->second.UnreadableParts & readable).CountBits();
+ if ((it->second.UnreadableParts &= ~readable).Empty()) {
+ UnreadableBlobs.erase(it);
+ }
+ }
+ }
+
+ ui64 TScrubCoroImpl::GenerateRestoreCorruptedBlobQuery() {
+ const TInstant now = TActorCoroImpl::Now();
+ std::vector<TEvRestoreCorruptedBlob::TItem> items;
+
+ for (auto& [blobId, data] : UnreadableBlobs) {
+ if (!data.RecoveryInFlightCookie && now >= data.RetryTimestamp) {
+ data.RecoveryInFlightCookie = ++LastRestoreCookie;
+ items.emplace_back(blobId, data.UnreadableParts, ScrubCtx->Info->Type, data.CorruptedPart,
+ data.RecoveryInFlightCookie);
+ const auto& p = data;
+ const auto& q = blobId;
+ STLOG(PRI_INFO, BS_VDISK_SCRUB, VDS22, VDISKP(LogPrefix, "going to restore unreadable blob"),
+ (Cookie, p.RecoveryInFlightCookie), (BlobId, q), (UnreadableParts, p.UnreadableParts),
+ (CorruptedPart, p.CorruptedPart));
+ }
+ }
+
+ if (!items.empty()) {
+ const TInstant deadline = now + TDuration::Minutes(2);
+ const ui64 cookie = ++LastRestoreCookie;
+ Send(ScrubCtx->SkeletonId, new TEvRestoreCorruptedBlob(deadline, std::move(items), true, false), 0, cookie);
+ return cookie;
+ } else {
+ return 0;
+ }
+ }
+
+ void TScrubCoroImpl::Handle(TEvRestoreCorruptedBlobResult::TPtr ev) {
+ const TInstant now = TActorCoroImpl::Now();
+
+ for (const auto& item : ev->Get()->Items) {
+ if (const auto it = UnreadableBlobs.find(item.BlobId); it != UnreadableBlobs.end()) {
+ auto& data = it->second;
+
+ if (!data.RecoveryInFlightCookie || data.RecoveryInFlightCookie != item.Cookie) {
+ continue;
+ }
+ data.RecoveryInFlightCookie = 0;
+ data.RetryTimestamp = now + TDuration::Minutes(1);
+
+ if (item.Status == NKikimrProto::OK) {
+ STLOG(PRI_NOTICE, BS_VDISK_SCRUB, VDS40, VDISKP(LogPrefix,
+ "recovered parts of previously unreadable blob"), (BlobId, it->first),
+ (UnreadablePartsBefore, data.UnreadableParts), (RecoveredParts, item.Needed));
+
+ *UnreadableBlobsFound -= (data.UnreadableParts & item.Needed).CountBits();
+ if ((data.UnreadableParts &= ~item.Needed).Empty()) {
+ UnreadableBlobs.erase(it);
+ }
+
+ ++*BlobsFixed;
+ } else {
+ STLOG(PRI_WARN, BS_VDISK_SCRUB, VDS07, VDISKP(LogPrefix, "failed to restore corrupted blob"),
+ (BlobId, item.BlobId), (Status, item.Status));
+ }
+ }
+ }
+
+ if (UnreadableBlobs.empty()) { // all blobs found so far are repaired
+ Send(ScrubCtx->SkeletonId, new TEvReportScrubStatus(false));
+ } else if (!GenerateRestoreCorruptedBlobQueryScheduled) { // retry in some time
+ TInstant when = TInstant::Max();
+ for (const auto& [blobId, data] : UnreadableBlobs) {
+ if (!data.RecoveryInFlightCookie) {
+ when = Min(when, data.RetryTimestamp);
+ }
+ }
+ if (when != TInstant::Max()) {
+ GetActorSystem()->Schedule(when, new IEventHandle(EvGenerateRestoreCorruptedBlobQuery, 0, SelfActorId,
+ {}, nullptr, 0));
+ GenerateRestoreCorruptedBlobQueryScheduled = true;
+ }
+ }
+
+ LastReceivedRestoreCookie = Max(LastReceivedRestoreCookie, ev->Cookie);
+ }
+
+ void TScrubCoroImpl::Handle(TEvNonrestoredCorruptedBlobNotify::TPtr ev) {
+ for (const auto& item : ev->Get()->Items) {
+ AddUnreadableParts(item.BlobId, item.UnreadableParts, item.CorruptedPart);
+ }
+ GenerateRestoreCorruptedBlobQuery();
+ }
+
+ void TScrubCoroImpl::HandleGenerateRestoreCorruptedBlobQuery() {
+ Y_VERIFY(GenerateRestoreCorruptedBlobQueryScheduled);
+ GenerateRestoreCorruptedBlobQueryScheduled = false;
+ GenerateRestoreCorruptedBlobQuery();
+ }
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/scrub/ya.make b/ydb/core/blobstorage/vdisk/scrub/ya.make
index 457effd72d1..1f977bf2507 100644
--- a/ydb/core/blobstorage/vdisk/scrub/ya.make
+++ b/ydb/core/blobstorage/vdisk/scrub/ya.make
@@ -1,7 +1,7 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(g:kikimr)
-
+
SRCS(
blob_recovery.cpp
blob_recovery.h
@@ -23,10 +23,10 @@ SRCS(
scrub_actor_sst_blob_merger.h
scrub_actor_unreadable.cpp
)
-
+
PEERDIR(
ydb/core/blobstorage/base
ydb/core/blobstorage/vdisk/common
)
-
-END()
+
+END()
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.cpp
index 0d8de3f200d..81740c89775 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.cpp
@@ -10,7 +10,7 @@ namespace NKikimr {
const TVDiskContextPtr &vctx)
: VDiskIncarnationGuid()
, VDiskIncarnationGuidSet(false)
- , SyncLogFirstLsnToKeep(std::make_shared<NSyncLog::TSyncLogFirstLsnToKeep>())
+ , SyncLogFirstLsnToKeep(std::make_shared<NSyncLog::TSyncLogFirstLsnToKeep>())
, Config(cfg)
, VCtx(vctx)
, GType(VCtx->Top->GType)
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.h
index 2bd127bbba3..22ad2340365 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_db.h
@@ -55,9 +55,9 @@ namespace NKikimr {
bool VDiskIncarnationGuidSet; // only for asserts
public:
- // SyncLog first item LSN that can't be deleted before unless synced
- std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
-
+ // SyncLog first item LSN that can't be deleted before unless synced
+ std::shared_ptr<NSyncLog::TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
+
// Settings
TIntrusivePtr<TVDiskConfig> Config;
TIntrusivePtr<TVDiskContext> VCtx;
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp
index 44b3c58c9c4..57bf58f7ba6 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp
@@ -27,8 +27,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_ERROR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_ERROR;
}
TMonErrorActor(const TActorId &notifyId,
@@ -62,8 +62,8 @@ namespace NKikimr {
TString DskSpaceTrackerInfo;
TString LocalRecovInfo;
TString AnubisRunnerInfo;
- TString DelayedHugeBlobDeleterInfo;
- TString ScrubInfo;
+ TString DelayedHugeBlobDeleterInfo;
+ TString ScrubInfo;
friend class TActorBootstrapped<TSkeletonMonMainPageActor>;
@@ -74,8 +74,8 @@ namespace NKikimr {
Counter++;
ctx.Send(Db->SkeletonID, new NMon::TEvHttpInfo(Ev->Get()->Request, TDbMon::HullInfoId));
Counter++;
- ctx.Send(Db->SkeletonID, new NMon::TEvHttpInfo(Ev->Get()->Request, TDbMon::DelayedHugeBlobDeleterId));
- Counter++;
+ ctx.Send(Db->SkeletonID, new NMon::TEvHttpInfo(Ev->Get()->Request, TDbMon::DelayedHugeBlobDeleterId));
+ Counter++;
}
if (bool(TActorId(Db->SyncerID))) {
@@ -123,9 +123,9 @@ namespace NKikimr {
Counter++;
}
- ctx.Send(Db->SkeletonID, new NMon::TEvHttpInfo(Ev->Get()->Request, TDbMon::ScrubId));
- Counter++;
-
+ ctx.Send(Db->SkeletonID, new NMon::TEvHttpInfo(Ev->Get()->Request, TDbMon::ScrubId));
+ Counter++;
+
if (Counter) {
// set up timeout, after which we reply
ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
@@ -154,8 +154,8 @@ namespace NKikimr {
DIV_CLASS("col-md-6") {Output(HugeKeeperInfo, str, "Huge Blob Keeper");}
DIV_CLASS("col-md-6") {Output(DskSpaceTrackerInfo, str, "Disk Space Tracker");}
DIV_CLASS("col-md-6") {Output(LocalRecovInfo, str, "Local Recovery Info");}
- DIV_CLASS("col-md-6") {Output(DelayedHugeBlobDeleterInfo, str, "Delayed Huge Blob Deleter Info");}
- DIV_CLASS("col-md-6") {Output(ScrubInfo, str, "Scrub Info");}
+ DIV_CLASS("col-md-6") {Output(DelayedHugeBlobDeleterInfo, str, "Delayed Huge Blob Deleter Info");}
+ DIV_CLASS("col-md-6") {Output(ScrubInfo, str, "Scrub Info");}
// uses column wrapping (sum is greater than 12)
}
Output(HullInfo, str, "Hull");
@@ -181,29 +181,29 @@ namespace NKikimr {
NMon::TEvHttpInfoRes *ptr = dynamic_cast<NMon::TEvHttpInfoRes*>(ev->Get());
Y_VERIFY_DEBUG(ptr);
- static const std::unordered_map<int, TString TThis::*> names{
- {TDbMon::SkeletonStateId, &TThis::SkeletonState},
- {TDbMon::HullInfoId, &TThis::HullInfo},
- {TDbMon::SyncerInfoId, &TThis::SyncerInfo},
- {TDbMon::SyncLogId, &TThis::SyncLogInfo},
- {TDbMon::ReplId, &TThis::ReplInfo},
- {TDbMon::LogCutterId, &TThis::LogCutterInfo},
- {TDbMon::HugeKeeperId, &TThis::HugeKeeperInfo},
- {TDbMon::HandoffMonId, &TThis::HandoffInfo},
- {TDbMon::DskSpaceTrackerId, &TThis::DskSpaceTrackerInfo},
- {TDbMon::LocalRecovInfoId, &TThis::LocalRecovInfo},
- {TDbMon::AnubisRunnerId, &TThis::AnubisRunnerInfo},
- {TDbMon::DelayedHugeBlobDeleterId, &TThis::DelayedHugeBlobDeleterInfo},
- {TDbMon::ScrubId, &TThis::ScrubInfo},
- };
-
- const auto it = names.find(ptr->SubRequestId);
- Y_VERIFY(it != names.end());
- this->*it->second = ptr->Answer;
+ static const std::unordered_map<int, TString TThis::*> names{
+ {TDbMon::SkeletonStateId, &TThis::SkeletonState},
+ {TDbMon::HullInfoId, &TThis::HullInfo},
+ {TDbMon::SyncerInfoId, &TThis::SyncerInfo},
+ {TDbMon::SyncLogId, &TThis::SyncLogInfo},
+ {TDbMon::ReplId, &TThis::ReplInfo},
+ {TDbMon::LogCutterId, &TThis::LogCutterInfo},
+ {TDbMon::HugeKeeperId, &TThis::HugeKeeperInfo},
+ {TDbMon::HandoffMonId, &TThis::HandoffInfo},
+ {TDbMon::DskSpaceTrackerId, &TThis::DskSpaceTrackerInfo},
+ {TDbMon::LocalRecovInfoId, &TThis::LocalRecovInfo},
+ {TDbMon::AnubisRunnerId, &TThis::AnubisRunnerInfo},
+ {TDbMon::DelayedHugeBlobDeleterId, &TThis::DelayedHugeBlobDeleterInfo},
+ {TDbMon::ScrubId, &TThis::ScrubInfo},
+ };
+
+ const auto it = names.find(ptr->SubRequestId);
+ Y_VERIFY(it != names.end());
+ this->*it->second = ptr->Answer;
--Counter;
- if (Counter == 0) {
+ if (Counter == 0) {
Finish(ctx);
- }
+ }
}
void HandlePoison(TEvents::TEvPoisonPill::TPtr &ev, const TActorContext &ctx) {
@@ -211,15 +211,15 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NMon::TEvHttpInfoRes, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NMon::TEvHttpInfoRes, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_MAIN_PAGE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_MAIN_PAGE;
}
TSkeletonMonMainPageActor(TIntrusivePtr<TDb> &db,
@@ -300,7 +300,7 @@ namespace NKikimr {
class TSkeletonFrontMonLogoBlobsQueryActor : public TActorBootstrapped<TSkeletonFrontMonLogoBlobsQueryActor>, public TMonQueryBaseActor {
const TVDiskID SelfVDiskId;
TIntrusivePtr<TVDiskConfig> Cfg;
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
const TActorId NotifyId;
const TActorId SkeletonFrontID;
NMon::TEvHttpInfo::TPtr Ev;
@@ -337,9 +337,9 @@ namespace NKikimr {
// FIXME: how to turn pages?
- std::unique_ptr<TEvBlobStorage::TEvVGet> req;
- const auto flags = ShowInternals ? TEvBlobStorage::TEvVGet::EFlags::ShowInternals : TEvBlobStorage::TEvVGet::EFlags::None;
-
+ std::unique_ptr<TEvBlobStorage::TEvVGet> req;
+ const auto flags = ShowInternals ? TEvBlobStorage::TEvVGet::EFlags::ShowInternals : TEvBlobStorage::TEvVGet::EFlags::None;
+
if (submitButton) {
// check that 'from' field is not empty
if (fromParam.empty()) {
@@ -358,13 +358,13 @@ namespace NKikimr {
if (toParam.empty()) {
// exact query
IsRangeQuery = false;
- if (IndexOnly) {
- req = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(SelfVDiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {From});
- } else {
- req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(SelfVDiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {From});
- }
+ if (IndexOnly) {
+ req = TEvBlobStorage::TEvVGet::CreateExtremeIndexQuery(SelfVDiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {From});
+ } else {
+ req = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(SelfVDiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, {From});
+ }
} else {
// range query
IsRangeQuery = true;
@@ -376,23 +376,23 @@ namespace NKikimr {
return;
}
- req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(SelfVDiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, From, To, 15);
+ req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(SelfVDiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, From, To, 15);
}
} else if (allButton) {
// browse database
IsRangeQuery = true;
From = TLogoBlobID(0, 4294967295, 4294967295, 0, 0, 0, TLogoBlobID::MaxPartId);
To = TLogoBlobID(0, 0, 0, 0, 0, 0, 1);
- req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(SelfVDiskId, TInstant::Max(),
- NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, From, To, 15);
+ req = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(SelfVDiskId, TInstant::Max(),
+ NKikimrBlobStorage::EGetHandleClass::AsyncRead, flags, {}, From, To, 15);
} else
Y_FAIL("Unknown button");
- if (req) {
- req->SetIsLocalMon();
- ctx.Send(SkeletonFrontID, req.release());
- }
+ if (req) {
+ req->SetIsLocalMon();
+ ctx.Send(SkeletonFrontID, req.release());
+ }
// set up timeout, after which we reply
ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
@@ -409,7 +409,7 @@ namespace NKikimr {
str << "Status: " << NKikimrProto::EReplyStatus_Name(q.GetStatus()) << "<br>";
str << "Id: " << id.ToString() << "<br>";
if (ShowInternals) {
- str << "Ingress: " << ingress.ToString(Top.get(), TVDiskIdShort(SelfVDiskId), id) << "<br>";
+ str << "Ingress: " << ingress.ToString(Top.get(), TVDiskIdShort(SelfVDiskId), id) << "<br>";
}
if (!IndexOnly) {
str << "FullDataSize: " << q.GetFullDataSize() << "<br>";
@@ -467,21 +467,21 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvVGetResult, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvVGetResult, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_SF_LOGOBLOBS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_SF_LOGOBLOBS;
}
TSkeletonFrontMonLogoBlobsQueryActor(const TVDiskID &selfVDiskId,
const TActorId &notifyId,
TIntrusivePtr<TVDiskConfig> cfg,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
const TActorId &skeletonFrontID,
NMon::TEvHttpInfo::TPtr &ev)
: TActorBootstrapped<TSkeletonFrontMonLogoBlobsQueryActor>()
@@ -506,7 +506,7 @@ namespace NKikimr {
class TSkeletonFrontMonBarriersQueryActor : public TActorBootstrapped<TSkeletonFrontMonBarriersQueryActor>, public TMonQueryBaseActor {
const TVDiskID SelfVDiskId;
TIntrusivePtr<TVDiskConfig> Cfg;
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
const TActorId NotifyId;
const TActorId SkeletonFrontID;
NMon::TEvHttpInfo::TPtr Ev;
@@ -539,7 +539,7 @@ namespace NKikimr {
}
ui32 maxResults = 15;
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrier> req;
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrier> req;
if (submitButton) {
// check that 'from' field is not empty
if (fromParam.empty()) {
@@ -558,8 +558,8 @@ namespace NKikimr {
if (toParam.empty()) {
// exact query
IsRangeQuery = false;
- req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, From, &maxResults, showInternals);
- ctx.Send(SkeletonFrontID, req.release());
+ req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, From, &maxResults, showInternals);
+ ctx.Send(SkeletonFrontID, req.release());
} else {
// range query
IsRangeQuery = true;
@@ -571,16 +571,16 @@ namespace NKikimr {
return;
}
- req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, To, &maxResults, showInternals);
- ctx.Send(SkeletonFrontID, req.release());
+ req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, To, &maxResults, showInternals);
+ ctx.Send(SkeletonFrontID, req.release());
}
} else if (allButton) {
// browse database
IsRangeQuery = true;
From = TKeyBarrier::First();
To = TKeyBarrier::Inf();
- req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, To, &maxResults, showInternals);
- ctx.Send(SkeletonFrontID, req.release());
+ req = std::make_unique<TEvBlobStorage::TEvVGetBarrier>(SelfVDiskId, From, To, &maxResults, showInternals);
+ ctx.Send(SkeletonFrontID, req.release());
}
// set up timeout, after which we reply
@@ -592,7 +592,7 @@ namespace NKikimr {
void OutputOneResult(IOutputStream &str, const NKikimrBlobStorage::TBarrierKey &k,
const NKikimrBlobStorage::TBarrierVal &v) {
- TIngressCachePtr ingressCache = TIngressCache::Create(Top, SelfVDiskId);
+ TIngressCachePtr ingressCache = TIngressCache::Create(Top, SelfVDiskId);
HTML(str) {
DIV_CLASS("well well-small") {
str << "TabletId: " << k.GetTabletId() << "<br>";
@@ -656,21 +656,21 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvVGetBarrierResult, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvVGetBarrierResult, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_SF_BARRIERS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_SF_BARRIERS;
}
TSkeletonFrontMonBarriersQueryActor(const TVDiskID &selfVDiskId,
const TActorId &notifyId,
TIntrusivePtr<TVDiskConfig> cfg,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
const TActorId &skeletonFrontID,
NMon::TEvHttpInfo::TPtr &ev)
: TActorBootstrapped<TSkeletonFrontMonBarriersQueryActor>()
@@ -737,7 +737,7 @@ namespace NKikimr {
struct TMessage {
bool Error; // was an error?
- std::unique_ptr<IEventBase> Msg; // in case of error contains reply, or a request to VDisk otherwise
+ std::unique_ptr<IEventBase> Msg; // in case of error contains reply, or a request to VDisk otherwise
};
TMessage CreateDumpDbMessageOK(NKikimrBlobStorage::EDbStatType dbStatType, bool pretty) {
@@ -745,18 +745,18 @@ namespace NKikimr {
auto channelParseRes = ParseChannel();
if (tabletIdParseRes.Status == NMonUtil::EParseRes::Error) {
auto s = Sprintf("Unsupported value '%s' for CGI parameter 'tabletid'", tabletIdParseRes.StrVal.data());
- return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
+ return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
}
if (channelParseRes.Status == NMonUtil::EParseRes::Error) {
auto s = Sprintf("Unsupported value '%s' for CGI parameter 'channel'", channelParseRes.StrVal.data());
- return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
+ return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
}
if (tabletIdParseRes.Status != channelParseRes.Status) {
auto s = Sprintf("CGI parameters 'tabletid' and 'channel' must be both OK or empty");
- return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
+ return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
}
- auto msg = std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, Action, dbStatType, pretty);
+ auto msg = std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, Action, dbStatType, pretty);
if (tabletIdParseRes.Status == NMonUtil::EParseRes::OK) {
// set up constraint
ui64 tabletId = tabletIdParseRes.Value;
@@ -768,14 +768,14 @@ namespace NKikimr {
}
TMessage CreateStatDbMessageOK(NKikimrBlobStorage::EDbStatType dbStatType, bool pretty) {
- return TMessage {false, std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, Action, dbStatType, pretty)};
+ return TMessage {false, std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, Action, dbStatType, pretty)};
}
TMessage CreateStatDumpDbMessage() {
auto r = NMonUtil::ParseDbName(Dbname);
if (r.Status == NMonUtil::EParseRes::Error || r.Status == NMonUtil::EParseRes::Empty) {
auto s = Sprintf("Unsupported value '%s' for CGI parameter 'dbname'", r.StrVal.data());
- return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
+ return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
} else {
// send db stat request
NKikimrBlobStorage::EDbStatType dbStatType = r.Value;
@@ -795,10 +795,10 @@ namespace NKikimr {
auto r = ParseTabletId();
if (r.Status == NMonUtil::EParseRes::OK) {
const bool pretty = PrettyPrint();
- return TMessage {false, std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, r.Value, pretty)};
+ return TMessage {false, std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, r.Value, pretty)};
} else {
auto s = Sprintf("Unsupported value '%s' for CGI parameter 'tabletid'", r.StrVal.data());
- return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
+ return TMessage {true, std::unique_ptr<IEventBase>(NMonUtil::PrepareError(s))};
}
}
@@ -806,8 +806,8 @@ namespace NKikimr {
const bool pretty = PrettyPrint();
return TMessage {
false,
- std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, NKikimrBlobStorage::StatHugeAction,
- NKikimrBlobStorage::StatHugeType, pretty)};
+ std::make_unique<TEvBlobStorage::TEvVDbStat>(SelfVDiskId, NKikimrBlobStorage::StatHugeAction,
+ NKikimrBlobStorage::StatHugeType, pretty)};
}
// creates a message
@@ -829,10 +829,10 @@ namespace NKikimr {
TMessage msg(CreateMessage());
if (msg.Error) {
// error creating a message, finish with error
- Finish(ctx, msg.Msg.release());
+ Finish(ctx, msg.Msg.release());
} else {
// send TEvDbStat message
- ctx.Send(SkeletonFrontID, msg.Msg.release());
+ ctx.Send(SkeletonFrontID, msg.Msg.release());
// set up timeout, after which we reply
ctx.Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup());
// switch state
@@ -862,15 +862,15 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvVDbStatResult, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvVDbStatResult, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_SF_LBSTAT;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_SF_LBSTAT;
}
TSkeletonFrontMonDbStatActor(const TVDiskID &selfVDiskId,
@@ -950,14 +950,14 @@ namespace NKikimr {
Finish(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(NMon::TEvHttpInfoRes, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(NMon::TEvHttpInfoRes, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_MON_SF_MAIN_PAGE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_MON_SF_MAIN_PAGE;
}
TSkeletonFrontMonMainPageActor(const TActorId &notifyId,
@@ -980,7 +980,7 @@ namespace NKikimr {
const TActorId &skeletonID,
const TActorId &skeletonFrontID,
TIntrusivePtr<TVDiskConfig> cfg,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
NMon::TEvHttpInfo::TPtr &ev,
const TString &frontHtml) {
const TCgiParameters& cgi = ev->Get()->Request.GetParams();
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h
index 95eacad7b58..31b2935167d 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h
@@ -17,7 +17,7 @@ namespace NKikimr {
const TActorId &skeletonID,
const TActorId &skeletonFrontID,
TIntrusivePtr<TVDiskConfig> cfg,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
NMon::TEvHttpInfo::TPtr &ev,
const TString &frontHtml);
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
index 96b813d3172..a18ec875a81 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeleton.cpp
@@ -13,7 +13,7 @@
#include "skeleton_oos_tracker.h"
#include "skeleton_overload_handler.h"
#include "skeleton_events.h"
-#include "skeleton_capturevdisklayout.h"
+#include "skeleton_capturevdisklayout.h"
#include "skeleton_compactionstate.h"
#include <ydb/core/blobstorage/base/wilson_events.h>
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
@@ -64,29 +64,29 @@ namespace NKikimr {
void UpdateWhiteboard(const TActorContext &ctx) {
// satisfaction rank
NKikimrWhiteboard::TVDiskSatisfactionRank satisfactionRank;
- TOverloadHandler::ToWhiteboard(OverloadHandler.get(), satisfactionRank);
+ TOverloadHandler::ToWhiteboard(OverloadHandler.get(), satisfactionRank);
// send a message to Whiteboard
- auto ev = std::make_unique<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate>(&satisfactionRank);
- const TInstant now = ctx.Now();
- const TInstant prev = std::exchange(WhiteboardUpdateTimestamp, now);
- const ui64 bytesRead = QueryCtx ? QueryCtx->PDiskReadBytes.exchange(0) : 0;
- const ui64 bytesWritten = PDiskWriteBytes->exchange(0);
- const TDuration delta = now - prev;
- if (delta != TDuration::Zero() && prev != TInstant::Zero()) {
- auto& record = ev->Record;
- record.SetReadThroughput(bytesRead * 1000000 / delta.MicroSeconds());
- record.SetWriteThroughput(bytesWritten * 1000000 / delta.MicroSeconds());
- }
- ctx.Send(*SkeletonFrontIDPtr, ev.release());
+ auto ev = std::make_unique<NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate>(&satisfactionRank);
+ const TInstant now = ctx.Now();
+ const TInstant prev = std::exchange(WhiteboardUpdateTimestamp, now);
+ const ui64 bytesRead = QueryCtx ? QueryCtx->PDiskReadBytes.exchange(0) : 0;
+ const ui64 bytesWritten = PDiskWriteBytes->exchange(0);
+ const TDuration delta = now - prev;
+ if (delta != TDuration::Zero() && prev != TInstant::Zero()) {
+ auto& record = ev->Record;
+ record.SetReadThroughput(bytesRead * 1000000 / delta.MicroSeconds());
+ record.SetWriteThroughput(bytesWritten * 1000000 / delta.MicroSeconds());
+ }
+ ctx.Send(*SkeletonFrontIDPtr, ev.release());
// send VDisk's metric to NodeWarden
if (OverloadHandler) {
ctx.Send(NodeWardenServiceId,
- new TEvBlobStorage::TEvControllerUpdateDiskStatus(
+ new TEvBlobStorage::TEvControllerUpdateDiskStatus(
SelfVDiskId,
- OverloadHandler->GetIntegralRankPercent(),
- SelfId().NodeId(),
- Config->BaseInfo.PDiskId,
- Config->BaseInfo.VDiskSlotId));
+ OverloadHandler->GetIntegralRankPercent(),
+ SelfId().NodeId(),
+ Config->BaseInfo.PDiskId,
+ Config->BaseInfo.VDiskSlotId));
}
// repeat later
ctx.Schedule(Config->WhiteboardUpdateInterval, new TEvTimeToUpdateWhiteboard());
@@ -137,9 +137,9 @@ namespace NKikimr {
// SEND REPLY
////////////////////////////////////////////////////////////////////////
template <class TOrigEv>
- void SendReply(const TActorContext &ctx, std::unique_ptr<IEventBase> result, TOrigEv &orig, EServiceKikimr logService) {
+ void SendReply(const TActorContext &ctx, std::unique_ptr<IEventBase> result, TOrigEv &orig, EServiceKikimr logService) {
Y_UNUSED(logService);
- SendVDiskResponse(ctx, orig->Sender, result.release(), *this, orig->Cookie);
+ SendVDiskResponse(ctx, orig->Sender, result.release(), *this, orig->Cookie);
}
////////////////////////////////////////////////////////////////////////
@@ -181,9 +181,9 @@ namespace NKikimr {
template <typename TEvPtr>
void ReplyVPatchError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvPtr &ev) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res = ErroneousResult(VCtx, status, errorReason, ev, TActivationContext::Now(),
+ std::unique_ptr<IEventBase> res = ErroneousResult(VCtx, status, errorReason, ev, TActivationContext::Now(),
SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo);
- SendReply(TActivationContext::AsActorContext(), std::move(res), ev, BS_VDISK_PATCH);
+ SendReply(TActivationContext::AsActorContext(), std::move(res), ev, BS_VDISK_PATCH);
}
void Handle(TEvBlobStorage::TEvVPatchStart::TPtr &ev, const TActorContext &ctx) {
@@ -211,10 +211,10 @@ namespace NKikimr {
<< " Event# " << ev->Get()->ToString());
IFaceMonGroup->PatchStartMsgs()++;
UpdateVPatchCtx();
- std::unique_ptr<IActor> actor{CreateSkeletonVPatchActor(SelfId(), GInfo->Type, ev, now, SkeletonFrontIDPtr,
+ std::unique_ptr<IActor> actor{CreateSkeletonVPatchActor(SelfId(), GInfo->Type, ev, now, SkeletonFrontIDPtr,
IFaceMonGroup->PatchFoundPartsMsgsPtr(), IFaceMonGroup->PatchResMsgsPtr(), VPatchCtx,
VCtx->VDiskLogPrefix, Db->GetVDiskIncarnationGuid())};
- TActorId vPatchActor = Register(actor.release());
+ TActorId vPatchActor = Register(actor.release());
VPatchActors.emplace(patchedBlobId, vPatchActor);
}
@@ -233,7 +233,7 @@ namespace NKikimr {
TLogoBlobID patchedBlobId = LogoBlobIDFromLogoBlobID(ev->Get()->Record.GetPatchedPartBlobId()).FullID();
auto it = VPatchActors.find(patchedBlobId);
if (it != VPatchActors.end()) {
- TActivationContext::Send(ev->Forward(it->second));
+ TActivationContext::Send(ev->Forward(it->second));
} else {
ReplyVPatchError(NKikimrProto::ERROR, "VPatchActor doesn't exist", ev);
}
@@ -250,20 +250,20 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// MULTIPUT SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
- const TActorContext &ctx, TInstant now) {
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
+ const TActorContext &ctx, TInstant now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
}
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
- const TActorContext &ctx, TInstant now, const TBatchedVec<NKikimrProto::EReplyStatus> &statuses) {
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
+ const TActorContext &ctx, TInstant now, const TBatchedVec<NKikimrProto::EReplyStatus> &statuses) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId, statuses,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId, statuses,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
}
void Handle(TEvBlobStorage::TEvVMultiPut::TPtr &ev, const TActorContext &ctx) {
@@ -289,29 +289,29 @@ namespace NKikimr {
};
void UpdatePDiskWriteBytes(size_t size) {
- *PDiskWriteBytes += size; // actual size for small blobs may be up to one block, but it may be
+ *PDiskWriteBytes += size; // actual size for small blobs may be up to one block, but it may be
// batched along with other VDisk log entries on the PDisk
}
TLoggedRecVPut* CreateLoggedRec(TLsnSeg seg, bool confirmSyncLogAlso, const TLogoBlobID &id,
- const TIngress &ingress, TRope &&buffer, std::unique_ptr<TEvBlobStorage::TEvVPutResult> res,
+ const TIngress &ingress, TRope &&buffer, std::unique_ptr<TEvBlobStorage::TEvVPutResult> res,
const TActorId &sender, ui64 cookie)
{
- return new TLoggedRecVPut(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(res), sender, cookie);
+ return new TLoggedRecVPut(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(res), sender, cookie);
}
TLoggedRecVMultiPutItem* CreateLoggedRec(TLsnSeg seg, bool confirmSyncLogAlso, const TLogoBlobID &id,
- const TIngress &ingress, TRope &&buffer, std::unique_ptr<TEvVMultiPutItemResult> res,
+ const TIngress &ingress, TRope &&buffer, std::unique_ptr<TEvVMultiPutItemResult> res,
const TActorId &sender, ui64 cookie)
{
- return new TLoggedRecVMultiPutItem(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(res),
+ return new TLoggedRecVMultiPutItem(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(res),
sender, cookie);
}
template <typename TEvResult>
- std::unique_ptr<NPDisk::TEvLog> CreatePutLogEvent(const TActorContext &ctx, TString evPrefix, NActors::TActorId sender,
+ std::unique_ptr<NPDisk::TEvLog> CreatePutLogEvent(const TActorContext &ctx, TString evPrefix, NActors::TActorId sender,
ui64 cookie, NLWTrace::TOrbit &&orbit, TVPutInfo &info,
- std::unique_ptr<TEvResult> result)
+ std::unique_ptr<TEvResult> result)
{
Y_VERIFY_DEBUG(info.HullStatus.Status == NKikimrProto::OK);
const TLogoBlobID &id = info.BlobId;
@@ -321,9 +321,9 @@ namespace NKikimr {
#ifdef OPTIMIZE_SYNC
// nothing to do, don't create synclog record
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg;
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg;
#else
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
new NSyncLog::TEvSyncLogPut(Db->GType, seg.Point(), TLogoBlobID(id, 0), info.Ingress));
#endif
@@ -338,28 +338,28 @@ namespace NKikimr {
bool confirmSyncLogAlso = static_cast<bool>(syncLogMsg);
intptr_t loggedRecId = LoggedRecsVault.Put(
- CreateLoggedRec(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(result), sender, cookie));
+ CreateLoggedRec(seg, confirmSyncLogAlso, id, ingress, std::move(buffer), std::move(result), sender, cookie));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureLogoBlobOpt, dataToWrite,
- seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
+ seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
logMsg->Orbit = std::move(orbit);
return logMsg;
}
- std::unique_ptr<TEvHullWriteHugeBlob> CreateHullWriteHugeBlob(const TActorContext &ctx, NActors::TActorId sender,
+ std::unique_ptr<TEvHullWriteHugeBlob> CreateHullWriteHugeBlob(const TActorContext &ctx, NActors::TActorId sender,
ui64 cookie, NWilson::TTraceId &traceId, bool ignoreBlock,
NKikimrBlobStorage::EPutHandleClass handleClass, TVPutInfo &info,
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> res)
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> res)
{
Y_VERIFY_DEBUG(info.HullStatus.Status == NKikimrProto::OK);
WILSON_TRACE_FROM_ACTOR(ctx, *this, &traceId, EvHullWriteHugeBlobSent);
- info.Buffer = TDiskBlob::Create(info.BlobId.BlobSize(), info.BlobId.PartId(), Db->GType.TotalPartCount(),
- std::move(info.Buffer), *Arena);
+ info.Buffer = TDiskBlob::Create(info.BlobId.BlobSize(), info.BlobId.PartId(), Db->GType.TotalPartCount(),
+ std::move(info.Buffer), *Arena);
UpdatePDiskWriteBytes(info.Buffer.GetSize());
- return std::make_unique<TEvHullWriteHugeBlob>(sender, cookie, info.BlobId, info.Ingress,
- std::move(info.Buffer), ignoreBlock, handleClass, std::move(res));
+ return std::make_unique<TEvHullWriteHugeBlob>(sender, cookie, info.BlobId, info.Ingress,
+ std::move(info.Buffer), ignoreBlock, handleClass, std::move(res));
}
THullCheckStatus ValidateVPut(const TActorContext &ctx, TString evPrefix,
@@ -374,13 +374,13 @@ namespace NKikimr {
}
if (bufSize != blobPartSize) {
- LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix
- << evPrefix << ": buffer size does not match with part size;"
- << " buffer size# " << bufSize
+ LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix
+ << evPrefix << ": buffer size does not match with part size;"
+ << " buffer size# " << bufSize
<< " PartSize# " << blobPartSize
<< " id# " << id
<< " Marker# BSVS01");
- return {NKikimrProto::ERROR, "buffer size mismatch"};
+ return {NKikimrProto::ERROR, "buffer size mismatch"};
}
if (bufSize > Config->MaxLogoBlobDataSize) {
@@ -389,7 +389,7 @@ namespace NKikimr {
<< " size# " << bufSize
<< " chunkSize# " << PDiskCtx->Dsk->ChunkSize
<< " Marker# BSVS02");
- return {NKikimrProto::ERROR, "buffer is too large"};
+ return {NKikimrProto::ERROR, "buffer is too large"};
}
auto status = Hull->CheckLogoBlob(ctx, id, ignoreBlock);
@@ -430,7 +430,7 @@ namespace NKikimr {
<< " event# " << ev->Get()->ToString()
<< " sender actorId# " << ev->Sender
<< " Marker# BSVS05");
- ReplyError(NKikimrProto::ERROR, "empty multiput", ev, ctx, now);
+ ReplyError(NKikimrProto::ERROR, "empty multiput", ev, ctx, now);
return;
}
@@ -440,14 +440,14 @@ namespace NKikimr {
firstBlobId.TabletID(), ev->Get()->GetSumBlobSize());
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
+ ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
return;
}
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvVMultiPut: race;"
<< " Marker# BSVS06");
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
return;
}
@@ -475,7 +475,7 @@ namespace NKikimr {
}
if (info.HullStatus.Status == NKikimrProto::OK) {
- auto ingressOpt = TIngress::CreateIngressWithLocal(VCtx->Top.get(), VCtx->ShortSelfVDisk, blobId);
+ auto ingressOpt = TIngress::CreateIngressWithLocal(VCtx->Top.get(), VCtx->ShortSelfVDisk, blobId);
if (!ingressOpt) {
LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvVMultiPut: ingress mismatch;"
<< " id# " << blobId
@@ -511,7 +511,7 @@ namespace NKikimr {
if (!hasHugeBlob && !lsnCount && !hasPostponed) {
LOG_INFO_S(ctx, BS_VDISK_PUT, Db->VCtx->VDiskLogPrefix << "TEvVMultiPut: all items have errors"
<< " Marker# BSVS09");
- ReplyError(NKikimrProto::OK, TString(), ev, ctx, now, statuses);
+ ReplyError(NKikimrProto::OK, TString(), ev, ctx, now, statuses);
return;
}
@@ -520,7 +520,7 @@ namespace NKikimr {
NKikimrBlobStorage::EPutHandleClass handleClass = ev->Get()->Record.GetHandleClass();
TVDiskID vdisk = VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID());
- std::unique_ptr<NPDisk::TEvMultiLog> evLogs = std::make_unique<NPDisk::TEvMultiLog>();
+ std::unique_ptr<NPDisk::TEvMultiLog> evLogs = std::make_unique<NPDisk::TEvMultiLog>();
ui64 cookie = ev->Cookie;
IActor* vMultiPutActor = CreateSkeletonVMultiPutActor(SelfId(), statuses, oosStatus, ev,
@@ -539,11 +539,11 @@ namespace NKikimr {
for (ui64 itemIdx = 0; itemIdx < record.ItemsSize(); ++itemIdx) {
TVPutInfo &info = putsInfo[itemIdx];
NKikimrProto::EReplyStatus status = info.HullStatus.Status;
- const TString& errorReason = info.HullStatus.ErrorReason;
+ const TString& errorReason = info.HullStatus.ErrorReason;
if (info.HullStatus.Postponed) {
- auto result = std::make_unique<TEvVMultiPutItemResult>(info.BlobId, itemIdx, status, errorReason);
- Hull->PostponeReplyUntilCommitted(result.release(), vMultiPutActorId, itemIdx, info.HullStatus.Lsn);
+ auto result = std::make_unique<TEvVMultiPutItemResult>(info.BlobId, itemIdx, status, errorReason);
+ Hull->PostponeReplyUntilCommitted(result.release(), vMultiPutActorId, itemIdx, info.HullStatus.Lsn);
continue;
}
@@ -559,29 +559,29 @@ namespace NKikimr {
TInstant::Max();
TEvBlobStorage::TEvVPut vPut(info.BlobId, TRope(), vdisk, ignoreBlock,
&itemIdx, deadline, handleClass);
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result(
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result(
new TEvBlobStorage::TEvVPutResult(status, info.BlobId, SelfVDiskId, &itemIdx, oosStatus, now,
vPut.GetCachedByteSize(), &vPut.Record, SkeletonFrontIDPtr, nullptr,
VCtx->Histograms.GetHistogram(handleClass), info.Buffer.GetSize(),
- NWilson::TTraceId(), Db->GetVDiskIncarnationGuid(), errorReason));
- if (info.Buffer) {
- auto hugeWrite = CreateHullWriteHugeBlob(ctx, vMultiPutActorId, cookie, traceId, ignoreBlock,
- handleClass, info, std::move(result));
- ctx.Send(Db->HugeKeeperID, hugeWrite.release());
- } else {
- ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, info.BlobId, info.Ingress, TDiskPart(),
- ignoreBlock, vMultiPutActorId, cookie, std::move(result)));
- }
+ NWilson::TTraceId(), Db->GetVDiskIncarnationGuid(), errorReason));
+ if (info.Buffer) {
+ auto hugeWrite = CreateHullWriteHugeBlob(ctx, vMultiPutActorId, cookie, traceId, ignoreBlock,
+ handleClass, info, std::move(result));
+ ctx.Send(Db->HugeKeeperID, hugeWrite.release());
+ } else {
+ ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, info.BlobId, info.Ingress, TDiskPart(),
+ ignoreBlock, vMultiPutActorId, cookie, std::move(result)));
+ }
} else {
Y_VERIFY(lsnBatch.First <= lsnBatch.Last);
info.Lsn = TLsnSeg(lsnBatch.First, lsnBatch.First);
lsnBatch.First++;
- std::unique_ptr<TEvVMultiPutItemResult> evItemResult(
- new TEvVMultiPutItemResult(info.BlobId, itemIdx, status, errorReason));
- auto logMsg = CreatePutLogEvent(ctx, "TEvVMultiPut", vMultiPutActorId, cookie, std::move(orbit),
- info, std::move(evItemResult));
- evLogs->AddLog(THolder<NPDisk::TEvLog>(logMsg.release()));
+ std::unique_ptr<TEvVMultiPutItemResult> evItemResult(
+ new TEvVMultiPutItemResult(info.BlobId, itemIdx, status, errorReason));
+ auto logMsg = CreatePutLogEvent(ctx, "TEvVMultiPut", vMultiPutActorId, cookie, std::move(orbit),
+ info, std::move(evItemResult));
+ evLogs->AddLog(THolder<NPDisk::TEvLog>(logMsg.release()));
}
}
@@ -589,7 +589,7 @@ namespace NKikimr {
OverloadHandler->ActualizeWeights(ctx, Mask(EHullDbType::LogoBlobs));
if (lsnCount) {
- ctx.Send(Db->LoggerID, evLogs.release());
+ ctx.Send(Db->LoggerID, evLogs.release());
}
}
@@ -599,12 +599,12 @@ namespace NKikimr {
void ReplyError(THullCheckStatus status, TEvBlobStorage::TEvVPut::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status.Status, status.ErrorReason, ev, now, SkeletonFrontIDPtr,
- SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo));
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status.Status, status.ErrorReason, ev, now, SkeletonFrontIDPtr,
+ SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo));
if (status.Postponed) {
- Hull->PostponeReplyUntilCommitted(res.release(), ev->Sender, ev->Cookie, status.Lsn);
+ Hull->PostponeReplyUntilCommitted(res.release(), ev->Sender, ev->Cookie, status.Lsn);
} else {
- SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
+ SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
}
}
@@ -616,13 +616,13 @@ namespace NKikimr {
}
void PrivateHandle(TEvBlobStorage::TEvVPut::TPtr &ev, const TActorContext &ctx) {
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvVPutReceived, VDiskId = SelfVDiskId,
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvVPutReceived, VDiskId = SelfVDiskId,
PDiskId = Config->BaseInfo.PDiskId, VDiskSlotId = Config->BaseInfo.VDiskSlotId);
-
+
IFaceMonGroup->PutMsgs()++;
IFaceMonGroup->PutTotalBytes() += ev->GetSize();
TInstant now = TAppData::TimeProvider->Now();
- NKikimrBlobStorage::TEvVPut &record = ev->Get()->Record;
+ NKikimrBlobStorage::TEvVPut &record = ev->Get()->Record;
const TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetBlobID());
LWTRACK(VDiskSkeletonVPutRecieved, ev->Get()->Orbit, VCtx->NodeId, VCtx->GroupId,
VCtx->Top->GetFailDomainOrderNumber(VCtx->ShortSelfVDisk), id.TabletID(), id.BlobSize());
@@ -641,14 +641,14 @@ namespace NKikimr {
const bool ignoreBlock = record.GetIgnoreBlock();
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError({NKikimrProto::OUT_OF_SPACE, "out of space", 0, false}, ev, ctx, now);
+ ReplyError({NKikimrProto::OUT_OF_SPACE, "out of space", 0, false}, ev, ctx, now);
return;
}
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvVPut: race; id# " << id
<< " Marker# BSVS10");
- ReplyError({NKikimrProto::RACE, "group generation mismatch", 0, false}, ev, ctx, now);
+ ReplyError({NKikimrProto::RACE, "group generation mismatch", 0, false}, ev, ctx, now);
return;
}
@@ -658,11 +658,11 @@ namespace NKikimr {
return;
}
- auto ingressOpt = TIngress::CreateIngressWithLocal(VCtx->Top.get(), VCtx->ShortSelfVDisk, id);
+ auto ingressOpt = TIngress::CreateIngressWithLocal(VCtx->Top.get(), VCtx->ShortSelfVDisk, id);
if (!ingressOpt) {
LOG_ERROR_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvVPut: ingress mismatch; id# " << id
<< " Marker# BSVS11");
- ReplyError({NKikimrProto::ERROR, "ingress mismatch", 0, false}, ev, ctx, now);
+ ReplyError({NKikimrProto::ERROR, "ingress mismatch", 0, false}, ev, ctx, now);
return;
}
info.Ingress = *ingressOpt;
@@ -678,27 +678,27 @@ namespace NKikimr {
info.Lsn = Db->LsnMngr->AllocLsnForHullAndSyncLog();
#endif
}
-
+
// no more errors (at least for for log writes)
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result = CreateResult(VCtx, NKikimrProto::OK, TString(), ev, now,
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result = CreateResult(VCtx, NKikimrProto::OK, TString(), ev, now,
SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid());
// Manage PDisk scheduler weights
OverloadHandler->ActualizeWeights(ctx, Mask(EHullDbType::LogoBlobs));
- if (!info.IsHugeBlob) {
- auto logMsg = CreatePutLogEvent(ctx, "TEvVPut", ev->Sender, ev->Cookie,
- std::move(ev->Get()->Orbit), info, std::move(result));
- ctx.Send(Db->LoggerID, logMsg.release());
- } else if (info.Buffer) {
+ if (!info.IsHugeBlob) {
+ auto logMsg = CreatePutLogEvent(ctx, "TEvVPut", ev->Sender, ev->Cookie,
+ std::move(ev->Get()->Orbit), info, std::move(result));
+ ctx.Send(Db->LoggerID, logMsg.release());
+ } else if (info.Buffer) {
// pass the work to huge blob writer
NKikimrBlobStorage::EPutHandleClass handleClass = record.GetHandleClass();
auto hugeWrite = CreateHullWriteHugeBlob(ctx, ev->Sender, ev->Cookie, ev->TraceId, ignoreBlock,
- handleClass, info, std::move(result));
- ctx.Send(Db->HugeKeeperID, hugeWrite.release());
+ handleClass, info, std::move(result));
+ ctx.Send(Db->HugeKeeperID, hugeWrite.release());
} else {
- ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, info.BlobId, info.Ingress, TDiskPart(),
- ignoreBlock, ev->Sender, ev->Cookie, std::move(result)));
+ ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, info.BlobId, info.Ingress, TDiskPart(),
+ ignoreBlock, ev->Sender, ev->Cookie, std::move(result)));
}
}
@@ -715,14 +715,14 @@ namespace NKikimr {
LOG_DEBUG_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix
<< "TEvVPut: realtime# false result# " << msg->Result->ToString()
<< " Marker# BSVS13");
- if (msg->HugeBlob != TDiskPart()) {
- ctx.Send(Db->HugeKeeperID, new TEvHullHugeBlobLogged(msg->WriteId, msg->HugeBlob, 0, false));
- }
+ if (msg->HugeBlob != TDiskPart()) {
+ ctx.Send(Db->HugeKeeperID, new TEvHullHugeBlobLogged(msg->WriteId, msg->HugeBlob, 0, false));
+ }
if (status.Postponed) {
- Hull->PostponeReplyUntilCommitted(msg->Result.release(), msg->OrigClient, msg->OrigCookie,
+ Hull->PostponeReplyUntilCommitted(msg->Result.release(), msg->OrigClient, msg->OrigCookie,
status.Lsn);
} else {
- SendVDiskResponse(ctx, msg->OrigClient, msg->Result.release(), *this, msg->OrigCookie);
+ SendVDiskResponse(ctx, msg->OrigClient, msg->Result.release(), *this, msg->OrigCookie);
}
return;
@@ -734,16 +734,16 @@ namespace NKikimr {
TLsnSeg seg = Db->LsnMngr->AllocLsnForHullAndSyncLog();
#endif
- LOG_DEBUG_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvHullHugeBlobLogged Id# " << msg->LogoBlobID
- << " HugeBlob# " << msg->HugeBlob.ToString() << " Lsn# " << seg);
-
+ LOG_DEBUG_S(ctx, BS_VDISK_PUT, VCtx->VDiskLogPrefix << "TEvHullHugeBlobLogged Id# " << msg->LogoBlobID
+ << " HugeBlob# " << msg->HugeBlob.ToString() << " Lsn# " << seg);
+
// prepare synclog msg in advance
#ifdef OPTIMIZE_SYNC
// nothing to do, don't create synclog record
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg;
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg;
#else
- auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.Point(), msg->LogoBlobID.FullID(),
- msg->Ingress);
+ auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.Point(), msg->LogoBlobID.FullID(),
+ msg->Ingress);
#endif
// prepare message to recovery
NHuge::TPutRecoveryLogRec logRec(msg->LogoBlobID, msg->Ingress, msg->HugeBlob);
@@ -756,9 +756,9 @@ namespace NKikimr {
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureHugeLogoBlob, dataToWrite, seg,
- loggedRecCookie, std::move(syncLogMsg), nullptr);
+ loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
////////////////////////////////////////////////////////////////////////
@@ -777,20 +777,20 @@ namespace NKikimr {
LogoBlobIDFromLogoBlobID(msg->Id, dump.MutableBlobID());
Y_PROTOBUF_SUPPRESS_NODISCARD dump.SerializeToString(&serializedLogRecord);
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
new NSyncLog::TEvSyncLogPut(Db->GType, seg.Point(), msg->Id, msg->Ingress));
- std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result(new TEvDelLogoBlobDataSyncLogResult(msg->OrderId, now,
+ std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result(new TEvDelLogoBlobDataSyncLogResult(msg->OrderId, now,
nullptr, nullptr, NWilson::TTraceId()));
bool confirmSyncLogAlso = static_cast<bool>(syncLogMsg);
intptr_t loggedRecId = LoggedRecsVault.Put(
- new TLoggedRecDelLogoBlobDataSyncLog(seg, confirmSyncLogAlso, std::move(result), ev->Sender, ev->Cookie));
+ new TLoggedRecDelLogoBlobDataSyncLog(seg, confirmSyncLogAlso, std::move(result), ev->Sender, ev->Cookie));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureHandoffDelLogoBlob,
- serializedLogRecord, seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
+ serializedLogRecord, seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
@@ -799,35 +799,35 @@ namespace NKikimr {
// Add already constructed ssts
////////////////////////////////////////////////////////////////////////
void Handle(TEvAddBulkSst::TPtr &ev, const TActorContext &ctx) {
- Y_FAIL("not implemented yet");
-
- const TLsnSeg seg = Db->LsnMngr->AllocLsnForHull(ev->Get()->Essence.GetLsnRange());
+ Y_FAIL("not implemented yet");
+
+ const TLsnSeg seg = Db->LsnMngr->AllocLsnForHull(ev->Get()->Essence.GetLsnRange());
NPDisk::TCommitRecord commitRecord;
TString data = ev->Get()->Serialize(commitRecord);
- intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecAddBulkSst(seg, false, ev));
- auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureAddBulkSst, commitRecord, data, seg,
- reinterpret_cast<void*>(loggedRecId), nullptr);
- ctx.Send(Db->LoggerID, logMsg.release());
+ intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecAddBulkSst(seg, false, ev));
+ auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureAddBulkSst, commitRecord, data, seg,
+ reinterpret_cast<void*>(loggedRecId), nullptr);
+ ctx.Send(Db->LoggerID, logMsg.release());
}
////////////////////////////////////////////////////////////////////////
// GET SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVGet::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVGet::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVGet::TPtr &ev, const TActorContext &ctx) {
- WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvVGetReceived);
-
+ WILSON_TRACE_FROM_ACTOR(ctx, *this, &ev->TraceId, EvVGetReceived);
+
IFaceMonGroup->GetMsgs()++;
TInstant now = TAppData::TimeProvider->Now();
- NKikimrBlobStorage::TEvVGet &record = ev->Get()->Record;
+ NKikimrBlobStorage::TEvVGet &record = ev->Get()->Record;
// FIXME: check PartId() is not null and is not too large
@@ -836,18 +836,18 @@ namespace NKikimr {
<< " Marker# BSVS14");
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
- } else if (!CheckVGetQuery(record)) {
- ReplyError(NKikimrProto::ERROR, "get query is invalid", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ } else if (!CheckVGetQuery(record)) {
+ ReplyError(NKikimrProto::ERROR, "get query is invalid", ev, ctx, now);
} else {
- TMaybe<ui64> cookie;
- if (record.HasCookie())
- cookie = record.GetCookie();
+ TMaybe<ui64> cookie;
+ if (record.HasCookie())
+ cookie = record.GetCookie();
auto handleClass = ev->Get()->Record.GetHandleClass();
- auto result = std::make_unique<TEvBlobStorage::TEvVGetResult>(NKikimrProto::OK, SelfVDiskId, now,
- ev->Get()->GetCachedByteSize(), &record, ev->Get()->GetIsLocalMon() ? nullptr : SkeletonFrontIDPtr,
- IFaceMonGroup->GetResMsgsPtr(), VCtx->Histograms.GetHistogram(handleClass), std::move(ev->TraceId),
- cookie, ev->GetChannel(), Db->GetVDiskIncarnationGuid());
+ auto result = std::make_unique<TEvBlobStorage::TEvVGetResult>(NKikimrProto::OK, SelfVDiskId, now,
+ ev->Get()->GetCachedByteSize(), &record, ev->Get()->GetIsLocalMon() ? nullptr : SkeletonFrontIDPtr,
+ IFaceMonGroup->GetResMsgsPtr(), VCtx->Histograms.GetHistogram(handleClass), std::move(ev->TraceId),
+ cookie, ev->GetChannel(), Db->GetVDiskIncarnationGuid());
if (record.GetAcquireBlockedGeneration()) {
ui64 tabletId = record.GetTabletId();
if (tabletId) {
@@ -864,15 +864,15 @@ namespace NKikimr {
// create a query actor and pass read-only snapshot to it
THullDsSnap fullSnap = Hull->GetSnapshot();
IActor *actor = CreateLevelIndexQueryActor(QueryCtx, std::move(keepChecker), ctx,
- std::move(fullSnap), ctx.SelfID, ev, std::move(result), Db->ReplID);
- if (actor) {
- auto aid = ctx.Register(actor);
- ActiveActors.Insert(aid);
- } else {
- auto res = std::make_unique<TEvBlobStorage::TEvVGetResult>();
- res->MakeError(NKikimrProto::ERROR, "incorrect query", record);
- ctx.Send(ev->Sender, res.release(), 0, ev->Cookie);
- }
+ std::move(fullSnap), ctx.SelfID, ev, std::move(result), Db->ReplID);
+ if (actor) {
+ auto aid = ctx.Register(actor);
+ ActiveActors.Insert(aid);
+ } else {
+ auto res = std::make_unique<TEvBlobStorage::TEvVGetResult>();
+ res->MakeError(NKikimrProto::ERROR, "incorrect query", record);
+ ctx.Send(ev->Sender, res.release(), 0, ev->Cookie);
+ }
// ReadQuery is responsible for sending result to the recipient
}
}
@@ -881,29 +881,29 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// BLOCK SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVBlock::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVBlock::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendReply(ctx, std::move(res), ev, BS_VDISK_BLOCK);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendReply(ctx, std::move(res), ev, BS_VDISK_BLOCK);
}
void Handle(TEvBlobStorage::TEvVBlock::TPtr &ev, const TActorContext &ctx) {
++IFaceMonGroup->BlockMsgs();
TInstant now = TAppData::TimeProvider->Now();
- NKikimrBlobStorage::TEvVBlock &record = ev->Get()->Record;
+ NKikimrBlobStorage::TEvVBlock &record = ev->Get()->Record;
const ui64 tabletId = record.GetTabletId();
const ui32 gen = record.GetGeneration();
- const ui64 issuerGuid = record.GetIssuerGuid();
+ const ui64 issuerGuid = record.GetIssuerGuid();
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
+ ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
return;
}
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
return;
}
@@ -913,21 +913,21 @@ namespace NKikimr {
TLsnSeg seg;
ui32 actGen = 0;
- auto checkStatus = Hull->CheckBlockCmdAndAllocLsn(tabletId, gen, issuerGuid, &actGen, &seg);
+ auto checkStatus = Hull->CheckBlockCmdAndAllocLsn(tabletId, gen, issuerGuid, &actGen, &seg);
NKikimrProto::EReplyStatus status = checkStatus.Status;
bool postponed = checkStatus.Postponed;
bool postponeUntilLsn = checkStatus.Lsn;
TEvBlobStorage::TEvVBlockResult::TTabletActGen act(tabletId, actGen);
- std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result(CreateResult(VCtx, status, checkStatus.ErrorReason, &act,
- ev, now, SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid()));
+ std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result(CreateResult(VCtx, status, checkStatus.ErrorReason, &act,
+ ev, now, SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid()));
if (status != NKikimrProto::OK) {
if (postponed) {
- Hull->PostponeReplyUntilCommitted(result.release(), ev->Sender, ev->Cookie, postponeUntilLsn);
+ Hull->PostponeReplyUntilCommitted(result.release(), ev->Sender, ev->Cookie, postponeUntilLsn);
} else {
LOG_DEBUG_S(ctx, BS_VDISK_BLOCK, VCtx->VDiskLogPrefix << "TEvVBlockResult: " << result->ToString()
<< " Marker# BSVS15");
- SendReply(ctx, std::move(result), ev, BS_VDISK_BLOCK);
+ SendReply(ctx, std::move(result), ev, BS_VDISK_BLOCK);
}
return;
@@ -935,18 +935,18 @@ namespace NKikimr {
OverloadHandler->ActualizeWeights(ctx, Mask(EHullDbType::Blocks));
// prepare synclog msg in advance
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(new NSyncLog::TEvSyncLogPut(seg.Point(), tabletId, gen,
- record.GetIssuerGuid()));
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(new NSyncLog::TEvSyncLogPut(seg.Point(), tabletId, gen,
+ record.GetIssuerGuid()));
bool confirmSyncLogAlso = static_cast<bool>(syncLogMsg);
- intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecVBlock(seg, confirmSyncLogAlso, tabletId, gen,
- issuerGuid, std::move(result), ev->Sender, ev->Cookie));
+ intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecVBlock(seg, confirmSyncLogAlso, tabletId, gen,
+ issuerGuid, std::move(result), ev->Sender, ev->Cookie));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureBlock,
- ev->GetChainBuffer()->GetString(), seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
+ ev->GetChainBuffer()->GetString(), seg, loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
////////////////////////////////////////////////////////////////////////
@@ -963,29 +963,29 @@ namespace NKikimr {
<< "TEvVGetBlock: tabletId# " << tabletId
<< " Marker# BSVS16");
- std::unique_ptr<TEvBlobStorage::TEvVGetBlockResult> result;
+ std::unique_ptr<TEvBlobStorage::TEvVGetBlockResult> result;
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::RACE, tabletId,
- SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
- IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
+ result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::RACE, tabletId,
+ SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
+ IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
} else {
ui32 blockedGen = 0;
bool isBlocked = Hull->GetBlocked(tabletId, &blockedGen);
if (isBlocked) {
- result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::OK, tabletId, blockedGen,
- SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
- IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
+ result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::OK, tabletId, blockedGen,
+ SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
+ IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
} else {
- result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::NODATA, tabletId,
- SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
- IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
+ result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(NKikimrProto::NODATA, tabletId,
+ SelfVDiskId, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, SkeletonFrontIDPtr,
+ IFaceMonGroup->GetBlockResMsgsPtr(), nullptr, std::move(ev->TraceId));
}
}
LOG_DEBUG_S(ctx, BS_VDISK_BLOCK, VCtx->VDiskLogPrefix
<< "TEvVGetBlockResult: " << result->ToString()
<< " Marker# BSVS17");
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
}
////////////////////////////////////////////////////////////////////////
@@ -994,27 +994,27 @@ namespace NKikimr {
void ReplyError(THullCheckStatus status, TEvBlobStorage::TEvVCollectGarbage::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status.Status, status.ErrorReason, ev, now,
- SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo));
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status.Status, status.ErrorReason, ev, now,
+ SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo));
if (status.Postponed) {
- Hull->PostponeReplyUntilCommitted(res.release(), ev->Sender, ev->Cookie, status.Lsn);
+ Hull->PostponeReplyUntilCommitted(res.release(), ev->Sender, ev->Cookie, status.Lsn);
} else {
- SendReply(ctx, std::move(res), ev, BS_VDISK_GC);
+ SendReply(ctx, std::move(res), ev, BS_VDISK_GC);
}
}
void Handle(TEvBlobStorage::TEvVCollectGarbage::TPtr &ev, const TActorContext &ctx) {
IFaceMonGroup->GCMsgs()++;
TInstant now = TAppData::TimeProvider->Now();
- NKikimrBlobStorage::TEvVCollectGarbage &record = ev->Get()->Record;
+ NKikimrBlobStorage::TEvVCollectGarbage &record = ev->Get()->Record;
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError({NKikimrProto::OUT_OF_SPACE, "out of space"}, ev, ctx, now);
+ ReplyError({NKikimrProto::OUT_OF_SPACE, "out of space"}, ev, ctx, now);
return;
}
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError({NKikimrProto::RACE, "group generation mismatch"}, ev, ctx, now);
+ ReplyError({NKikimrProto::RACE, "group generation mismatch"}, ev, ctx, now);
return;
}
@@ -1033,57 +1033,57 @@ namespace NKikimr {
OverloadHandler->ActualizeWeights(ctx,
Mask(EHullDbType::LogoBlobs) | Mask(EHullDbType::Barriers));
- std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result(CreateResult(VCtx, NKikimrProto::OK, TString(), ev,
- now, SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid()));
+ std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result(CreateResult(VCtx, NKikimrProto::OK, TString(), ev,
+ now, SkeletonFrontIDPtr, SelfVDiskId, Db->GetVDiskIncarnationGuid()));
// prepare synclog msg in advance
- std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
+ std::unique_ptr<NSyncLog::TEvSyncLogPut> syncLogMsg(
new NSyncLog::TEvSyncLogPut(Db->GType, seg.Last, record, ingress));
TString data = ev->GetChainBuffer()->GetString();
- intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecVCollectGarbage(seg, true, ingress, std::move(result), ev));
+ intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecVCollectGarbage(seg, true, ingress, std::move(result), ev));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureGC, data, seg, loggedRecCookie,
- std::move(syncLogMsg), nullptr);
+ std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
////////////////////////////////////////////////////////////////////////
// GET BARRIER SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVGetBarrier::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVGetBarrier::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVGetBarrier::TPtr &ev, const TActorContext &ctx) {
IFaceMonGroup->GetBarrierMsgs()++;
TInstant now = TAppData::TimeProvider->Now();
- NKikimrBlobStorage::TEvVGetBarrier &record = ev->Get()->Record;
+ NKikimrBlobStorage::TEvVGetBarrier &record = ev->Get()->Record;
LOG_DEBUG_S(ctx, BS_VDISK_GC, VCtx->VDiskLogPrefix
<< "TEvVGetBarrier: " << ev->Get()->ToString()
<< " Marker# BSVS19");
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
- } else if (!CheckVGetBarrierQuery(record)) {
- ReplyError(NKikimrProto::ERROR, "get barrier query invalid", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ } else if (!CheckVGetBarrierQuery(record)) {
+ ReplyError(NKikimrProto::ERROR, "get barrier query invalid", ev, ctx, now);
} else {
- std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result;
- result = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(NKikimrProto::OK, SelfVDiskId,
- now, ev->Get()->GetCachedByteSize(), &record, SkeletonFrontIDPtr,
- IFaceMonGroup->GetBarrierResMsgsPtr(), nullptr, std::move(ev->TraceId));
+ std::unique_ptr<TEvBlobStorage::TEvVGetBarrierResult> result;
+ result = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(NKikimrProto::OK, SelfVDiskId,
+ now, ev->Get()->GetCachedByteSize(), &record, SkeletonFrontIDPtr,
+ IFaceMonGroup->GetBarrierResMsgsPtr(), nullptr, std::move(ev->TraceId));
THullDsSnap fullSnap = Hull->GetIndexSnapshot();
fullSnap.LogoBlobsSnap.Destroy();
fullSnap.BlocksSnap.Destroy();
- IActor *actor = CreateLevelIndexBarrierQueryActor(HullCtx, ctx.SelfID, std::move(fullSnap.BarriersSnap),
- ev, std::move(result));
+ IActor *actor = CreateLevelIndexBarrierQueryActor(HullCtx, ctx.SelfID, std::move(fullSnap.BarriersSnap),
+ ev, std::move(result));
auto aid = ctx.Register(actor);
ActiveActors.Insert(aid);
// ReadBarrier is responsible for sending result to the recipient
@@ -1099,30 +1099,30 @@ namespace NKikimr {
LOG_DEBUG_S(ctx, BS_VDISK_OTHER, VCtx->VDiskLogPrefix << "TEvVStatus"
<< " Marker# BSVS20");
auto aid = ctx.Register(CreateStatusRequestHandler(VCtx, Db->SkeletonID, Db->SyncerID, Db->SyncLogID,
- IFaceMonGroup, SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo, ev, ctx.SelfID, now, ReplDone));
+ IFaceMonGroup, SelfVDiskId, Db->GetVDiskIncarnationGuid(), GInfo, ev, ctx.SelfID, now, ReplDone));
ActiveActors.Insert(aid);
}
void Handle(TEvLocalStatus::TPtr &ev, const TActorContext &ctx) {
- std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
+ std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
// hull status
- Hull->StatusRequest(ctx, result.get());
+ Hull->StatusRequest(ctx, result.get());
// local recovery status
NKikimrBlobStorage::TLocalRecoveryInfo *localRecoveryStatus = result->Record.MutableLocalRecoveryInfo();
LocalRecovInfo->FillIn(localRecoveryStatus);
// return result
- ctx.Send(ev->Sender, result.release());
+ ctx.Send(ev->Sender, result.release());
}
////////////////////////////////////////////////////////////////////////
// DBSTAT SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVDbStat::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVDbStat::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVDbStat::TPtr &ev, const TActorContext &ctx) {
@@ -1133,13 +1133,13 @@ namespace NKikimr {
<< " Marker# BSVS21");
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
} else {
- auto result = std::make_unique<TEvBlobStorage::TEvVDbStatResult>(NKikimrProto::OK, SelfVDiskId, now,
- IFaceMonGroup->DbStatResMsgsPtr(), nullptr, std::move(ev->TraceId));
+ auto result = std::make_unique<TEvBlobStorage::TEvVDbStatResult>(NKikimrProto::OK, SelfVDiskId, now,
+ IFaceMonGroup->DbStatResMsgsPtr(), nullptr, std::move(ev->TraceId));
THullDsSnap fullSnap = Hull->GetIndexSnapshot();
IActor *actor = CreateDbStatActor(HullCtx, HugeBlobCtx, ctx, std::move(fullSnap),
- ctx.SelfID, ev, std::move(result), *this);
+ ctx.SelfID, ev, std::move(result), *this);
if (actor) {
auto aid = ctx.Register(actor);
ActiveActors.Insert(aid);
@@ -1149,39 +1149,39 @@ namespace NKikimr {
}
////////////////////////////////////////////////////////////////////////
- // STREAM QUERIES
- ////////////////////////////////////////////////////////////////////////
-
+ // STREAM QUERIES
+ ////////////////////////////////////////////////////////////////////////
+
THashMap<TString, TActorId> MonStreamActors;
-
- void Handle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
+
+ void Handle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
TActorId& actorId = MonStreamActors[ev->Get()->StreamId];
if (actorId == TActorId()) {
- actorId = RunInBatchPool(ctx, CreateMonStreamActor(Hull->GetIndexSnapshot(), ev));
- ActiveActors.insert(actorId);
- }
- ctx.ExecutorThread.ActorSystem->Send(ev->Forward(actorId));
- }
-
- void Handle(TEvBlobStorage::TEvMonStreamActorDeathNote::TPtr& ev, const TActorContext& /*ctx*/) {
- auto it = MonStreamActors.find(ev->Get()->StreamId);
- Y_VERIFY(it != MonStreamActors.end());
- ActiveActors.erase(it->second);
- MonStreamActors.erase(it);
- }
-
- ////////////////////////////////////////////////////////////////////////
+ actorId = RunInBatchPool(ctx, CreateMonStreamActor(Hull->GetIndexSnapshot(), ev));
+ ActiveActors.insert(actorId);
+ }
+ ctx.ExecutorThread.ActorSystem->Send(ev->Forward(actorId));
+ }
+
+ void Handle(TEvBlobStorage::TEvMonStreamActorDeathNote::TPtr& ev, const TActorContext& /*ctx*/) {
+ auto it = MonStreamActors.find(ev->Get()->StreamId);
+ Y_VERIFY(it != MonStreamActors.end());
+ ActiveActors.erase(it->second);
+ MonStreamActors.erase(it);
+ }
+
+ ////////////////////////////////////////////////////////////////////////
// COMPACT SECTOR
////////////////////////////////////////////////////////////////////////
- void Reply(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TEvBlobStorage::TEvVCompact::TPtr &ev,
+ void Reply(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TEvBlobStorage::TEvVCompact::TPtr &ev,
const TActorContext &ctx, const TInstant &/*now*/) {
- auto result = std::make_unique<TEvBlobStorage::TEvVCompactResult>(status, SelfVDiskId);
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVCompactResult>(status, SelfVDiskId);
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
}
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVCompact::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVCompact::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
- Reply(status, errorReason, ev, ctx, now);
+ Reply(status, errorReason, ev, ctx, now);
}
void Handle(TEvBlobStorage::TEvVCompact::TPtr &ev, const TActorContext &ctx) {
@@ -1191,7 +1191,7 @@ namespace NKikimr {
<< " Marker# BSVS22");
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
} else if (!VDiskCompactionState) {
ReplyError(NKikimrProto::NOTREADY, "vdisk is not initialized", ev, ctx, now);
} else {
@@ -1225,7 +1225,7 @@ namespace NKikimr {
req.CompactLogoBlobs = bool(ev->Get()->Mask & Mask(EHullDbType::LogoBlobs));
req.CompactBlocks = bool(ev->Get()->Mask & Mask(EHullDbType::Blocks));
req.CompactBarriers = bool(ev->Get()->Mask & Mask(EHullDbType::Barriers));
- req.Mode = ev->Get()->Mode;
+ req.Mode = ev->Get()->Mode;
req.ClientId = ev->Sender;
req.ClientCookie = ev->Cookie;
req.Reply = std::make_unique<TEvCompactVDiskResult>();
@@ -1240,15 +1240,15 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// BALD SYNC LOG SECTOR
////////////////////////////////////////////////////////////////////////
- void Reply(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev, const TActorContext &ctx, const TInstant &/*now*/) {
- auto result = std::make_unique<TEvBlobStorage::TEvVBaldSyncLogResult>(status, SelfVDiskId);
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ void Reply(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev, const TActorContext &ctx, const TInstant &/*now*/) {
+ auto result = std::make_unique<TEvBlobStorage::TEvVBaldSyncLogResult>(status, SelfVDiskId);
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
}
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
- Reply(status, errorReason, ev, ctx, now);
+ Reply(status, errorReason, ev, ctx, now);
}
void Handle(TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev, const TActorContext &ctx) {
@@ -1258,13 +1258,13 @@ namespace NKikimr {
<< " Marker# BSVS23");
if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
} else {
Y_VERIFY(Db->SyncLogID);
// forward this message to SyncLog
ctx.Send(ev->Forward(Db->SyncLogID));
// reply back
- Reply(NKikimrProto::OK, TString(), ev, ctx, now);
+ Reply(NKikimrProto::OK, TString(), ev, ctx, now);
}
}
@@ -1272,12 +1272,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// SYNC SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSync::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSync::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVSync::TPtr &ev, const TActorContext &ctx) {
@@ -1287,12 +1287,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// SYNC GUID SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSyncGuid::TPtr &ev,
+ void ReplyError(NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSyncGuid::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
// FIXME: check for RACE in other handlers!!!
@@ -1306,7 +1306,7 @@ namespace NKikimr {
<< "TSkeleton::Handle(TEvBlobStorage::TEvVSyncGuid): Source:"
<< " Self# " << SelfVDiskId << " Source# " << protoVDisk
<< " Marker# BSVS24");
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
}
if (!SelfVDiskId.SameDisk(record.GetTargetVDiskID())) {
auto protoVDisk = VDiskIDFromVDiskID(record.GetTargetVDiskID());
@@ -1314,7 +1314,7 @@ namespace NKikimr {
<< "TSkeleton::Handle(TEvBlobStorage::TEvVSyncGuid): Target:"
<< " Self# " << SelfVDiskId << " Source# " << protoVDisk
<< " Marker# BSVS25");
- ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
+ ReplyError(NKikimrProto::RACE, "group generation mismatch", ev, ctx, now);
}
ctx.Send(ev->Forward(Db->SyncerID));
@@ -1323,11 +1323,11 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// LOCAL SYNC DATA SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TEvLocalSyncData::TPtr &ev,
+ void ReplyError(const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TEvLocalSyncData::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
- auto result = std::make_unique<TEvLocalSyncDataResult>(status, now, SyncLogIFaceGroup.LocalSyncResMsgsPtr(),
- nullptr, NWilson::TTraceId());
- SendReply(ctx, std::move(result), ev, BS_VDISK_OTHER);
+ auto result = std::make_unique<TEvLocalSyncDataResult>(status, now, SyncLogIFaceGroup.LocalSyncResMsgsPtr(),
+ nullptr, NWilson::TTraceId());
+ SendReply(ctx, std::move(result), ev, BS_VDISK_OTHER);
}
void Handle(TEvLocalSyncData::TPtr &ev, const TActorContext &ctx) {
@@ -1342,7 +1342,7 @@ namespace NKikimr {
SyncLogIFaceGroup.LocalSyncMsgs()++;
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
+ ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
return;
}
@@ -1352,20 +1352,20 @@ namespace NKikimr {
#else
TLsnSeg seg = Hull->AllocateLsnForSyncDataCmd(ev->Get()->Data);
#endif
- std::unique_ptr<TEvLocalSyncDataResult> result(
+ std::unique_ptr<TEvLocalSyncDataResult> result(
new TEvLocalSyncDataResult(NKikimrProto::OK, now, SyncLogIFaceGroup.LocalSyncResMsgsPtr(),
nullptr, NWilson::TTraceId()));
OverloadHandler->ActualizeWeights(ctx, AllEHullDbTypes);
TString data = ev->Get()->Serialize();
- intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecLocalSyncData(seg, false, std::move(result), ev));
+ intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecLocalSyncData(seg, false, std::move(result), ev));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureLocalSyncData, data, seg,
loggedRecCookie, nullptr, nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
////////////////////////////////////////////////////////////////////////
@@ -1393,13 +1393,13 @@ namespace NKikimr {
}
void ReplyError(const NKikimrProto::EReplyStatus status,
- const TString& /*errorReason*/,
+ const TString& /*errorReason*/,
TEvAnubisOsirisPut::TPtr &ev,
const TActorContext &ctx,
const TInstant &now) {
- std::unique_ptr<IEventBase> res(new TEvAnubisOsirisPutResult(status, now, IFaceMonGroup->PutResMsgsPtr(),
+ std::unique_ptr<IEventBase> res(new TEvAnubisOsirisPutResult(status, now, IFaceMonGroup->PutResMsgsPtr(),
nullptr, NWilson::TTraceId()));
- SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
+ SendReply(ctx, std::move(res), ev, BS_VDISK_PUT);
}
void PrivateHandle(TEvAnubisOsirisPut::TPtr &ev, const TActorContext &ctx) {
@@ -1410,17 +1410,17 @@ namespace NKikimr {
(msg->IsAnubis() ? IFaceMonGroup->AnubisPutMsgs() : IFaceMonGroup->OsirisPutMsgs())++;
if (!OutOfSpaceLogic->Allow(ctx, ev)) {
- ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
+ ReplyError(NKikimrProto::OUT_OF_SPACE, "out of space", ev, ctx, now);
return;
}
- TEvAnubisOsirisPut::THullDbInsert insert = msg->PrepareInsert(VCtx->Top.get(), VCtx->ShortSelfVDisk);
+ TEvAnubisOsirisPut::THullDbInsert insert = msg->PrepareInsert(VCtx->Top.get(), VCtx->ShortSelfVDisk);
TLsnSeg seg = Db->LsnMngr->AllocLsnForHullAndSyncLog();
// Manage PDisk scheduler weights
OverloadHandler->ActualizeWeights(ctx, Mask(EHullDbType::LogoBlobs));
- std::unique_ptr<TEvAnubisOsirisPutResult> result(new TEvAnubisOsirisPutResult(NKikimrProto::OK, now,
+ std::unique_ptr<TEvAnubisOsirisPutResult> result(new TEvAnubisOsirisPutResult(NKikimrProto::OK, now,
(msg->IsAnubis() ? IFaceMonGroup->AnubisPutResMsgsPtr() : IFaceMonGroup->OsirisPutResMsgsPtr()),
nullptr, NWilson::TTraceId()));
// log data
@@ -1428,15 +1428,15 @@ namespace NKikimr {
TString data = logRec.Serialize();
// prepare synclog msg in advance
- auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.Point(), insert.Id, insert.Ingress);
+ auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.Point(), insert.Id, insert.Ingress);
- intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecAnubisOsirisPut(seg, true, insert, std::move(result), ev));
+ intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecAnubisOsirisPut(seg, true, insert, std::move(result), ev));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignatureAnubisOsirisPut, data, seg,
- loggedRecCookie, std::move(syncLogMsg), nullptr);
+ loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
+ ctx.Send(Db->LoggerID, logMsg.release());
}
@@ -1451,12 +1451,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// SYNC FULL SECTOR
////////////////////////////////////////////////////////////////////////
- void ReplyError(const NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSyncFull::TPtr &ev,
+ void ReplyError(const NKikimrProto::EReplyStatus status, const TString& errorReason, TEvBlobStorage::TEvVSyncFull::TPtr &ev,
const TActorContext &ctx, const TInstant &now) {
using namespace NErrBuilder;
- std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
- Db->GetVDiskIncarnationGuid(), GInfo));
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ std::unique_ptr<IEventBase> res(ErroneousResult(VCtx, status, errorReason, ev, now, SkeletonFrontIDPtr, SelfVDiskId,
+ Db->GetVDiskIncarnationGuid(), GInfo));
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVSyncFull::TPtr &ev, const TActorContext &ctx) {
@@ -1466,8 +1466,8 @@ namespace NKikimr {
ui64 dbBirthLsn = 0;
const ui64 confirmedLsn = Db->LsnMngr->GetConfirmedLsnForHull();
dbBirthLsn = *DbBirthLsn;
- auto aid = ctx.RegisterWithSameMailbox(CreateHullSyncFullHandler(Db, HullCtx, SelfVDiskId, ctx.SelfID, Hull,
- IFaceMonGroup, ev, now, dbBirthLsn, confirmedLsn));
+ auto aid = ctx.RegisterWithSameMailbox(CreateHullSyncFullHandler(Db, HullCtx, SelfVDiskId, ctx.SelfID, Hull,
+ IFaceMonGroup, ev, now, dbBirthLsn, confirmedLsn));
ActiveActors.Insert(aid);
}
@@ -1481,7 +1481,7 @@ namespace NKikimr {
intptr_t loggedRecId = reinterpret_cast<intptr_t>(elem.Cookie);
LWTRACK(VDiskSkeletonRecordLogged, elem.Orbit, elem.Lsn);
- std::unique_ptr<ILoggedRec> loggedRec(LoggedRecsVault.Extract(loggedRecId));
+ std::unique_ptr<ILoggedRec> loggedRec(LoggedRecsVault.Extract(loggedRecId));
Db->LsnMngr->ConfirmLsnForHull(loggedRec->Seg, loggedRec->ConfirmSyncLogAlso);
loggedRec->Replay(*Hull, ctx, *this);
}
@@ -1493,68 +1493,68 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// REPL SECTOR
////////////////////////////////////////////////////////////////////////
- void Handle(TEvRecoveredHugeBlob::TPtr &ev, const TActorContext &ctx) {
+ void Handle(TEvRecoveredHugeBlob::TPtr &ev, const TActorContext &ctx) {
TInstant now = TAppData::TimeProvider->Now();
IFaceMonGroup->RecoveredHugeBlobMsgs()++;
- const TEvRecoveredHugeBlob *msg = ev->Get();
- const TLogoBlobID& id = msg->Id;
+ const TEvRecoveredHugeBlob *msg = ev->Get();
+ const TLogoBlobID& id = msg->Id;
LOG_DEBUG_S(ctx, BS_REPL, VCtx->VDiskLogPrefix << "TSkeleton::Handle(TEvRecoveredHugeBlob): id# " << id
<< " Marker# BSVS26");
- TRope buf = std::move(msg->Data);
+ TRope buf = std::move(msg->Data);
const ui64 bufSize = buf.GetSize();
- Y_VERIFY(bufSize <= Config->MaxLogoBlobDataSize && HugeBlobCtx->IsHugeBlob(VCtx->Top->GType, id.FullID()),
+ Y_VERIFY(bufSize <= Config->MaxLogoBlobDataSize && HugeBlobCtx->IsHugeBlob(VCtx->Top->GType, id.FullID()),
"TEvRecoveredHugeBlob: blob is too small/huge bufSize# %zu", bufSize);
- UpdatePDiskWriteBytes(bufSize);
-
+ UpdatePDiskWriteBytes(bufSize);
+
auto oosStatus = VCtx->GetOutOfSpaceState().GetGlobalStatusFlags();
- auto result = std::make_unique<TEvBlobStorage::TEvVPutResult>(NKikimrProto::OK, id, SelfVDiskId, nullptr,
- oosStatus, now, 0, nullptr, nullptr, IFaceMonGroup->RecoveredHugeBlobResMsgsPtr(), nullptr, bufSize,
- std::move(ev->TraceId), 0, TString());
-
- // pass the work to huge blob writer
- TIngress ingress = *TIngress::CreateIngressWithLocal(VCtx->Top.get(), SelfVDiskId, id);
- if (buf) {
- ctx.Send(Db->HugeKeeperID, new TEvHullWriteHugeBlob(ev->Sender, ev->Cookie, id, ingress, std::move(buf),
- true, NKikimrBlobStorage::EPutHandleClass::AsyncBlob, std::move(result)));
- } else {
- ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, id, ingress, TDiskPart(), true, ev->Sender, ev->Cookie, std::move(result)));
- }
- }
-
- void Handle(TEvDetectedPhantomBlob::TPtr& ev, const TActorContext& ctx) {
- TEvDetectedPhantomBlob *msg = ev->Get();
-
- for (const TLogoBlobID& logoBlobId : msg->Phantoms) {
+ auto result = std::make_unique<TEvBlobStorage::TEvVPutResult>(NKikimrProto::OK, id, SelfVDiskId, nullptr,
+ oosStatus, now, 0, nullptr, nullptr, IFaceMonGroup->RecoveredHugeBlobResMsgsPtr(), nullptr, bufSize,
+ std::move(ev->TraceId), 0, TString());
+
+ // pass the work to huge blob writer
+ TIngress ingress = *TIngress::CreateIngressWithLocal(VCtx->Top.get(), SelfVDiskId, id);
+ if (buf) {
+ ctx.Send(Db->HugeKeeperID, new TEvHullWriteHugeBlob(ev->Sender, ev->Cookie, id, ingress, std::move(buf),
+ true, NKikimrBlobStorage::EPutHandleClass::AsyncBlob, std::move(result)));
+ } else {
+ ctx.Send(SelfId(), new TEvHullLogHugeBlob(0, id, ingress, TDiskPart(), true, ev->Sender, ev->Cookie, std::move(result)));
+ }
+ }
+
+ void Handle(TEvDetectedPhantomBlob::TPtr& ev, const TActorContext& ctx) {
+ TEvDetectedPhantomBlob *msg = ev->Get();
+
+ for (const TLogoBlobID& logoBlobId : msg->Phantoms) {
LOG_ERROR_S(ctx, NKikimrServices::BS_SKELETON, VCtx->VDiskLogPrefix
<< "adding DoNotKeep to phantom LogoBlobId# " << logoBlobId
<< " Marker# BSVS27");
- }
-
+ }
+
TLsnSeg seg = Hull->AllocateLsnForPhantoms(msg->Phantoms);
-
- // generate sync log message with collected blobs
- auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.First, msg->Phantoms);
-
- // serialize message to pass it to log
- NKikimrVDiskData::TPhantomLogoBlobs record;
- for (const TLogoBlobID& id : msg->Phantoms) {
- LogoBlobIDFromLogoBlobID(id, record.AddLogoBlobs());
- }
+
+ // generate sync log message with collected blobs
+ auto syncLogMsg = std::make_unique<NSyncLog::TEvSyncLogPut>(Db->GType, seg.First, msg->Phantoms);
+
+ // serialize message to pass it to log
+ NKikimrVDiskData::TPhantomLogoBlobs record;
+ for (const TLogoBlobID& id : msg->Phantoms) {
+ LogoBlobIDFromLogoBlobID(id, record.AddLogoBlobs());
+ }
TString data;
- bool res = record.SerializeToString(&data);
+ bool res = record.SerializeToString(&data);
Y_VERIFY(res);
-
+
intptr_t loggedRecId = LoggedRecsVault.Put(new TLoggedRecPhantoms(seg, true, ev));
void *loggedRecCookie = reinterpret_cast<void *>(loggedRecId);
// create log msg
auto logMsg = CreateHullUpdate(HullLogCtx, TLogSignature::SignaturePhantomBlobs, data, seg,
- loggedRecCookie, std::move(syncLogMsg), nullptr);
+ loggedRecCookie, std::move(syncLogMsg), nullptr);
// send prepared message to recovery log
- ctx.Send(Db->LoggerID, logMsg.release());
- }
-
+ ctx.Send(Db->LoggerID, logMsg.release());
+ }
+
////////////////////////////////////////////////////////////////////////
// RECOVERY SECTOR
////////////////////////////////////////////////////////////////////////
@@ -1580,23 +1580,23 @@ namespace NKikimr {
resultStream << str.Str();
}
- void SkeletonIsUpAndRunning(const TActorContext &ctx, bool runRepl = false) {
+ void SkeletonIsUpAndRunning(const TActorContext &ctx, bool runRepl = false) {
Become(&TThis::StateNormal);
VDiskMonGroup.VDiskState(NKikimrWhiteboard::EVDiskState::OK);
LOG_INFO_S(ctx, BS_SKELETON, VCtx->VDiskLogPrefix << "SKELETON IS UP AND RUNNING"
<< " Marker# BSVS28");
// notify SkeletonFront
- auto msg = std::make_unique<TEvFrontRecoveryStatus>(TEvFrontRecoveryStatus::SyncGuidRecoveryDone,
+ auto msg = std::make_unique<TEvFrontRecoveryStatus>(TEvFrontRecoveryStatus::SyncGuidRecoveryDone,
NKikimrProto::OK,
(PDiskCtx ? PDiskCtx->Dsk : nullptr),
HugeBlobCtx,
Db->GetVDiskIncarnationGuid());
- ctx.Send(*SkeletonFrontIDPtr, msg.release());
- // propagate status to Node Warden unless replication is on -- in that case it sets the status itself
- if (!runRepl) {
- ReplDone = true;
- }
- UpdateReplState(ctx);
+ ctx.Send(*SkeletonFrontIDPtr, msg.release());
+ // propagate status to Node Warden unless replication is on -- in that case it sets the status itself
+ if (!runRepl) {
+ ReplDone = true;
+ }
+ UpdateReplState(ctx);
}
void SkeletonErrorState(const TActorContext &ctx,
@@ -1606,14 +1606,14 @@ namespace NKikimr {
Become(&TThis::StateDatabaseError);
VDiskMonGroup.VDiskState(state);
// notify SkeletonFront
- auto msg = std::make_unique<TEvFrontRecoveryStatus>(phase,
+ auto msg = std::make_unique<TEvFrontRecoveryStatus>(phase,
NKikimrProto::ERROR,
(PDiskCtx ? PDiskCtx->Dsk : nullptr),
HugeBlobCtx,
Db->GetVDiskIncarnationGuid());
- ctx.Send(*SkeletonFrontIDPtr, msg.release());
- // push the status
- UpdateVDiskStatus(NKikimrBlobStorage::ERROR, ctx);
+ ctx.Send(*SkeletonFrontIDPtr, msg.release());
+ // push the status
+ UpdateVDiskStatus(NKikimrBlobStorage::ERROR, ctx);
}
void Handle(TEvBlobStorage::TEvLocalRecoveryDone::TPtr &ev, const TActorContext &ctx) {
@@ -1630,69 +1630,69 @@ namespace NKikimr {
// check status
if (ev->Get()->Status == NKikimrProto::OK) {
- // handle special case when donor disk starts and finds out that it has been wiped out
- if (ev->Get()->LsnMngr->GetOriginallyRecoveredLsn() == 0 && Config->BaseInfo.DonorMode) {
- // send drop donor cmd to NodeWarden
- const TVDiskID vdiskId(GInfo->GroupID, GInfo->GroupGeneration, VCtx->ShortSelfVDisk);
- Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvDropDonor(SelfId().NodeId(),
- Config->BaseInfo.PDiskId, Config->BaseInfo.VDiskSlotId, vdiskId));
-
- // transit to error state and await deletion
- return SkeletonErrorState(ctx, TEvFrontRecoveryStatus::LocalRecoveryDone,
- NKikimrWhiteboard::EVDiskState::LocalRecoveryError);
- }
-
+ // handle special case when donor disk starts and finds out that it has been wiped out
+ if (ev->Get()->LsnMngr->GetOriginallyRecoveredLsn() == 0 && Config->BaseInfo.DonorMode) {
+ // send drop donor cmd to NodeWarden
+ const TVDiskID vdiskId(GInfo->GroupID, GInfo->GroupGeneration, VCtx->ShortSelfVDisk);
+ Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), new TEvBlobStorage::TEvDropDonor(SelfId().NodeId(),
+ Config->BaseInfo.PDiskId, Config->BaseInfo.VDiskSlotId, vdiskId));
+
+ // transit to error state and await deletion
+ return SkeletonErrorState(ctx, TEvFrontRecoveryStatus::LocalRecoveryDone,
+ NKikimrWhiteboard::EVDiskState::LocalRecoveryError);
+ }
+
// notify skeketon front about recovery status
- auto msg = std::make_unique<TEvFrontRecoveryStatus>(TEvFrontRecoveryStatus::LocalRecoveryDone,
+ auto msg = std::make_unique<TEvFrontRecoveryStatus>(TEvFrontRecoveryStatus::LocalRecoveryDone,
NKikimrProto::OK,
PDiskCtx->Dsk,
HugeBlobCtx,
Db->GetVDiskIncarnationGuid());
- ctx.Send(*SkeletonFrontIDPtr, msg.release());
-
- // place new incarnation guid on whiteboard
- using TEv = NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate;
- ctx.Send(*SkeletonFrontIDPtr, new TEv(TEv::UpdateIncarnationGuid, Db->GetVDiskIncarnationGuid()));
-
+ ctx.Send(*SkeletonFrontIDPtr, msg.release());
+
+ // place new incarnation guid on whiteboard
+ using TEv = NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate;
+ ctx.Send(*SkeletonFrontIDPtr, new TEv(TEv::UpdateIncarnationGuid, Db->GetVDiskIncarnationGuid()));
+
// we got a recovered local DB here
LOG_INFO_S(ctx, BS_SKELETON, VCtx->VDiskLogPrefix << "SKELETON LOCAL RECOVERY SUCCEEDED"
<< " Marker# BSVS29");
-
+
// run logger forwarder
auto logWriter = CreateRecoveryLogWriter(PDiskCtx->PDiskId, Db->SkeletonID,
PDiskCtx->Dsk->Owner, PDiskCtx->Dsk->OwnerRound, Db->LsnMngr->GetStartLsn(),
VCtx->VDiskCounters);
Db->LoggerID.Set(ctx.Register(logWriter));
ActiveActors.Insert(Db->LoggerID); // keep forever
-
+
// run out of disk space tracker
Db->DskSpaceTrackerID.Set(ctx.Register(CreateDskSpaceTracker(VCtx, PDiskCtx,
Config->DskTrackerInterval)));
ActiveActors.Insert(Db->DskSpaceTrackerID); // keep forever
-
+
// start handoff proxies right now, because they are required for Hull compactions
- if (Config->RunHandoff && !Config->BaseInfo.DonorMode) {
+ if (Config->RunHandoff && !Config->BaseInfo.DonorMode) {
auto moreActors = Db->Handoff->RunProxies(ctx);
ActiveActors.Insert(moreActors);
}
-
+
// run LogCutter in the same mailbox
TLogCutterCtx logCutterCtx = {VCtx, PDiskCtx, Db->LsnMngr, Config,
(TActorId)(Db->LoggerID)};
Db->LogCutterID.Set(ctx.RegisterWithSameMailbox(CreateRecoveryLogCutter(std::move(logCutterCtx))));
ActiveActors.Insert(Db->LogCutterID); // keep forever
-
+
// run HugeBlobKeeper
TString localRecovInfoStr = Db->LocalRecoveryInfo ? Db->LocalRecoveryInfo->ToString() : TString("{}");
- auto hugeKeeperCtx = std::make_shared<THugeKeeperCtx>(VCtx, PDiskCtx, Db->LsnMngr,
+ auto hugeKeeperCtx = std::make_shared<THugeKeeperCtx>(VCtx, PDiskCtx, Db->LsnMngr,
ctx.SelfID, (TActorId)(Db->LoggerID), (TActorId)(Db->LogCutterID),
localRecovInfoStr);
auto hugeKeeper = CreateHullHugeBlobKeeper(hugeKeeperCtx, ev->Get()->RepairedHuge);
Db->HugeKeeperID.Set(ctx.Register(hugeKeeper));
ActiveActors.Insert(Db->HugeKeeperID); // keep forever
-
+
// run SyncLogActor
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog = std::move(ev->Get()->RepairedSyncLog);
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repairedSyncLog = std::move(ev->Get()->RepairedSyncLog);
Y_VERIFY(SelfVDiskId == GInfo->GetVDiskId(VCtx->ShortSelfVDisk));
auto slCtx = MakeIntrusive<NSyncLog::TSyncLogCtx>(
VCtx,
@@ -1705,31 +1705,31 @@ namespace NKikimr {
Config->SyncLogMaxMemAmount,
Config->MaxResponseSize,
Db->SyncLogFirstLsnToKeep);
- Db->SyncLogID.Set(ctx.Register(CreateSyncLogActor(slCtx, GInfo, SelfVDiskId, std::move(repairedSyncLog))));
+ Db->SyncLogID.Set(ctx.Register(CreateSyncLogActor(slCtx, GInfo, SelfVDiskId, std::move(repairedSyncLog))));
ActiveActors.Insert(Db->SyncLogID); // keep forever
-
+
// create HullLogCtx
- HullLogCtx = std::make_shared<THullLogCtx>(VCtx, PDiskCtx, Db->SkeletonID, Db->SyncLogID,
+ HullLogCtx = std::make_shared<THullLogCtx>(VCtx, PDiskCtx, Db->SkeletonID, Db->SyncLogID,
Db->HugeKeeperID);
-
+
// create Hull
- Hull = std::make_shared<THull>(Db->LsnMngr, PDiskCtx, Db->Handoff, Db->SkeletonID,
+ Hull = std::make_shared<THull>(Db->LsnMngr, PDiskCtx, Db->Handoff, Db->SkeletonID,
Config->RunHandoff, std::move(*ev->Get()->Uncond),
ctx.ExecutorThread.ActorSystem, Config->BarrierValidation);
auto moreActors = Hull->RunHullServices(Config, HullLogCtx, Db->SyncLogFirstLsnToKeep,
Db->LoggerID, Db->LogCutterID, ctx);
ActiveActors.Insert(moreActors);
-
+
// create VDiskCompactionState
VDiskCompactionState = std::make_unique<TVDiskCompactionState>(Hull->GetHullDs()->LogoBlobs->LIActor,
Hull->GetHullDs()->Blocks->LIActor, Hull->GetHullDs()->Barriers->LIActor);
// initialize Out Of Space Logic
- OutOfSpaceLogic = std::make_shared<TOutOfSpaceLogic>(VCtx, Hull);
-
+ OutOfSpaceLogic = std::make_shared<TOutOfSpaceLogic>(VCtx, Hull);
+
// initialize QueryCtx
- QueryCtx = std::make_shared<TQueryCtx>(HullCtx, PDiskCtx, SelfId());
-
+ QueryCtx = std::make_shared<TQueryCtx>(HullCtx, PDiskCtx, SelfId());
+
// create overload handler
auto vMovedPatch = [this] (const TActorContext &ctx, TEvBlobStorage::TEvVMovedPatch::TPtr ev) {
this->PrivateHandle(ev, ctx);
@@ -1750,48 +1750,48 @@ namespace NKikimr {
this->PrivateHandle(ev, ctx);
};
NMonGroup::TSkeletonOverloadGroup overloadMonGroup(VCtx->VDiskCounters, "subsystem", "emergency");
- OverloadHandler = std::make_unique<TOverloadHandler>(VCtx, PDiskCtx, Hull,
+ OverloadHandler = std::make_unique<TOverloadHandler>(VCtx, PDiskCtx, Hull,
std::move(overloadMonGroup), std::move(vMovedPatch), std::move(vPatchStart), std::move(vput),
std::move(vMultiPutHandler), std::move(loc), std::move(aoput));
ScheduleWakeupEmergencyPutQueue(ctx);
-
+
// actualize weights before we start
OverloadHandler->ActualizeWeights(ctx, AllEHullDbTypes, true);
// run Anubis
- if (Config->RunAnubis && !Config->BaseInfo.DonorMode) {
- auto anubisCtx = std::make_shared<TAnubisCtx>(HullCtx, ctx.SelfID,
+ if (Config->RunAnubis && !Config->BaseInfo.DonorMode) {
+ auto anubisCtx = std::make_shared<TAnubisCtx>(HullCtx, ctx.SelfID,
Config->ReplInterconnectChannel, Config->AnubisOsirisMaxInFly, Config->AnubisTimeout);
Db->AnubisRunnerID.Set(ctx.Register(CreateAnubisRunner(anubisCtx, GInfo)));
}
if (Config->RunDefrag) {
- auto defragCtx = std::make_shared<TDefragCtx>(VCtx, HugeBlobCtx, PDiskCtx, ctx.SelfID,
+ auto defragCtx = std::make_shared<TDefragCtx>(VCtx, HugeBlobCtx, PDiskCtx, ctx.SelfID,
Db->HugeKeeperID, true);
DefragId = ctx.Register(CreateDefragActor(defragCtx, GInfo));
ActiveActors.Insert(DefragId); // keep forever
}
- // create scrubber actor
- auto scrubCtx = MakeIntrusive<TScrubContext>(
- VCtx,
- PDiskCtx,
- GInfo,
- SelfId(),
- Hull->GetHullDs()->LogoBlobs->LIActor,
- SelfId().NodeId(),
- Config->BaseInfo.PDiskId,
- Config->BaseInfo.VDiskSlotId,
- Config->BaseInfo.ScrubCookie,
- Db->GetVDiskIncarnationGuid(),
- Db->LsnMngr,
- Db->LoggerID,
- Db->LogCutterID);
- ScrubId = ctx.Register(CreateScrubActor(std::move(scrubCtx), std::move(ev->Get()->ScrubEntrypoint),
- ev->Get()->ScrubEntrypointLsn));
- ActiveActors.Insert(ScrubId);
-
- if (Config->RunSyncer && !Config->BaseInfo.DonorMode) {
+ // create scrubber actor
+ auto scrubCtx = MakeIntrusive<TScrubContext>(
+ VCtx,
+ PDiskCtx,
+ GInfo,
+ SelfId(),
+ Hull->GetHullDs()->LogoBlobs->LIActor,
+ SelfId().NodeId(),
+ Config->BaseInfo.PDiskId,
+ Config->BaseInfo.VDiskSlotId,
+ Config->BaseInfo.ScrubCookie,
+ Db->GetVDiskIncarnationGuid(),
+ Db->LsnMngr,
+ Db->LoggerID,
+ Db->LogCutterID);
+ ScrubId = ctx.Register(CreateScrubActor(std::move(scrubCtx), std::move(ev->Get()->ScrubEntrypoint),
+ ev->Get()->ScrubEntrypointLsn));
+ ActiveActors.Insert(ScrubId);
+
+ if (Config->RunSyncer && !Config->BaseInfo.DonorMode) {
// switch to syncronization step
Become(&TThis::StateSyncGuidRecovery);
VDiskMonGroup.VDiskState(NKikimrWhiteboard::EVDiskState::SyncGuidRecovery);
@@ -1804,7 +1804,7 @@ namespace NKikimr {
Db->LoggerID,
Db->LogCutterID,
Db->SyncLogID,
- Config);
+ Config);
// syncer performes sync recovery
Db->SyncerID.Set(ctx.Register(CreateSyncerActor(sc, GInfo, ev->Get()->SyncerData)));
ActiveActors.Insert(Db->SyncerID); // keep forever
@@ -1829,16 +1829,16 @@ namespace NKikimr {
LOG_INFO_S(ctx, BS_SKELETON, VCtx->VDiskLogPrefix << "SKELETON SYNC GUID RECOVERY SUCCEEDED"
<< " Marker# BSVS31");
DbBirthLsn = ev->Get()->DbBirthLsn;
- SkeletonIsUpAndRunning(ctx, Config->RunRepl);
+ SkeletonIsUpAndRunning(ctx, Config->RunRepl);
if (Config->RunRepl) {
- auto replCtx = std::make_shared<TReplCtx>(VCtx, PDiskCtx, HugeBlobCtx, Hull->GetHullDs(), GInfo,
- SelfId(), Config, PDiskWriteBytes, Config->ReplPausedAtStart);
- Db->ReplID.Set(ctx.Register(CreateReplActor(replCtx)));
+ auto replCtx = std::make_shared<TReplCtx>(VCtx, PDiskCtx, HugeBlobCtx, Hull->GetHullDs(), GInfo,
+ SelfId(), Config, PDiskWriteBytes, Config->ReplPausedAtStart);
+ Db->ReplID.Set(ctx.Register(CreateReplActor(replCtx)));
ActiveActors.Insert(Db->ReplID); // keep forever
- if (CommenceRepl) {
- TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, Db->ReplID, SelfId(),
- nullptr, 0));
- }
+ if (CommenceRepl) {
+ TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, Db->ReplID, SelfId(),
+ nullptr, 0));
+ }
}
} else {
LOG_INFO_S(ctx, BS_SKELETON, VCtx->VDiskLogPrefix << "SKELETON SYNC GUID RECOVERY FAILED"
@@ -1853,7 +1853,7 @@ namespace NKikimr {
// MONITORING SECTOR
////////////////////////////////////////////////////////////////////////
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
- switch (auto subrequest = ev->Get()->SubRequestId) {
+ switch (auto subrequest = ev->Get()->SubRequestId) {
case 0: {
// calculate id for the actor who'll tell us about local recovery
TActorId locRecovActor = LocalDbRecoveryID ? LocalDbRecoveryID : ctx.SelfID;
@@ -1880,23 +1880,23 @@ namespace NKikimr {
if (LocalRecovInfo)
LocalRecovInfo->OutputHtml(str);
ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), TDbMon::LocalRecovInfoId));
- break;
+ break;
}
- case TDbMon::DelayedHugeBlobDeleterId: {
- TStringStream str;
+ case TDbMon::DelayedHugeBlobDeleterId: {
+ TStringStream str;
if (Hull) {
Hull->OutputHtmlForHugeBlobDeleter(str);
- }
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), subrequest));
- break;
- }
- case TDbMon::ScrubId:
- if (ScrubId) {
- ctx.Send(ev->Forward(ScrubId));
- } else {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("scrub actor is not started", subrequest));
- }
- break;
+ }
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), subrequest));
+ break;
+ }
+ case TDbMon::ScrubId:
+ if (ScrubId) {
+ ctx.Send(ev->Forward(ScrubId));
+ } else {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("scrub actor is not started", subrequest));
+ }
+ break;
case TDbMon::DbMainPageLogoBlobs:
case TDbMon::DbMainPageBlocks:
case TDbMon::DbMainPageBarriers: {
@@ -2011,10 +2011,10 @@ namespace NKikimr {
TABLED() {str << "BlobStorage GroupId (decimal)";}
TABLED() {str << GInfo->GroupID;}
}
- TABLER() {
- TABLED() {str << "VDiskIncarnationGuid";}
- TABLED() {str << Db->GetVDiskIncarnationGuid();}
- }
+ TABLER() {
+ TABLED() {str << "VDiskIncarnationGuid";}
+ TABLED() {str << Db->GetVDiskIncarnationGuid();}
+ }
}
}
@@ -2037,7 +2037,7 @@ namespace NKikimr {
// CUT LOG FORWARDER SECTOR
////////////////////////////////////////////////////////////////////////
void Handle(NPDisk::TEvCutLog::TPtr &ev, const TActorContext &ctx) {
- std::unique_ptr<NPDisk::TEvCutLog> msg(ev->Release().Release());
+ std::unique_ptr<NPDisk::TEvCutLog> msg(ev->Release().Release());
if (LocalDbInitialized) {
Y_VERIFY_DEBUG(msg->Owner == PDiskCtx->Dsk->Owner);
@@ -2046,23 +2046,23 @@ namespace NKikimr {
<< "Handle " << msg->ToString()
<< " actorid# " << ctx.SelfID.ToString()
<< " Marker# BSVS33");
- SpreadCutLog(std::move(msg), ctx);
+ SpreadCutLog(std::move(msg), ctx);
} else {
LOG_DEBUG_S(ctx, BS_LOGCUTTER, VCtx->VDiskLogPrefix
<< "Handle " << msg->ToString()
<< " DELAYED actorid# " << ctx.SelfID.ToString()
<< " Marker# BSVS34");
- CutLogDelayedMsg = std::move(msg);
+ CutLogDelayedMsg = std::move(msg);
}
}
- void SpreadCutLog(std::unique_ptr<NPDisk::TEvCutLog> msg, const TActorContext &ctx) {
+ void SpreadCutLog(std::unique_ptr<NPDisk::TEvCutLog> msg, const TActorContext &ctx) {
Y_VERIFY_DEBUG(msg->Owner == PDiskCtx->Dsk->Owner);
ui32 counter = 0;
// setup FreeUpToLsn for Hull Database
if (Hull) {
- Hull->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
+ Hull->CutRecoveryLog(ctx, std::unique_ptr<NPDisk::TEvCutLog>(msg->Clone()));
++counter;
}
// setup FreeUpToLsn for Syncer
@@ -2083,10 +2083,10 @@ namespace NKikimr {
ctx.Send(Db->LogCutterID, msg->Clone());
++counter;
}
- if (ScrubId) {
- ctx.Send(ScrubId, msg->Clone());
- ++counter;
- }
+ if (ScrubId) {
+ ctx.Send(ScrubId, msg->Clone());
+ ++counter;
+ }
LOG_DEBUG_S(ctx, BS_LOGCUTTER, VCtx->VDiskLogPrefix
<< "SpreadCutLog: Handle " << msg->ToString()
@@ -2107,7 +2107,7 @@ namespace NKikimr {
LocalDbInitialized = true;
if (CutLogDelayedMsg) {
Y_VERIFY_DEBUG(CutLogDelayedMsg->Owner == PDiskCtx->Dsk->Owner);
- SpreadCutLog(std::exchange(CutLogDelayedMsg, nullptr), ctx);
+ SpreadCutLog(std::exchange(CutLogDelayedMsg, nullptr), ctx);
Y_VERIFY(!CutLogDelayedMsg);
}
}
@@ -2120,7 +2120,7 @@ namespace NKikimr {
// Save locally
GInfo = msg->NewInfo;
- SelfVDiskId = msg->NewVDiskId;
+ SelfVDiskId = msg->NewVDiskId;
// clear VPatchCtx
VPatchCtx = nullptr;
@@ -2133,8 +2133,8 @@ namespace NKikimr {
ctx.Send(Db->ReplID, ev->Get()->Clone());
// send command to AnubisRunner
ctx.Send(Db->AnubisRunnerID, ev->Get()->Clone());
- // send command to scrub actor
- ctx.Send(ScrubId, ev->Get()->Clone());
+ // send command to scrub actor
+ ctx.Send(ScrubId, ev->Get()->Clone());
// send command to defrag actor
if (DefragId) {
ctx.Send(DefragId, ev->Get()->Clone());
@@ -2143,19 +2143,19 @@ namespace NKikimr {
// FIXME: reconfigure handoff
}
- void HandleReplDone(const TActorContext& ctx) {
- ReplDone = true;
- UpdateReplState(ctx);
- }
-
- void Ignore(const TActorContext&)
- {}
-
- void UpdateVDiskStatus(NKikimrBlobStorage::EVDiskStatus status, const TActorContext& ctx) {
- const auto& base = Db->Config->BaseInfo;
- Send(NodeWardenServiceId, new TEvStatusUpdate(ctx.SelfID.NodeId(), base.PDiskId, base.VDiskSlotId, status));
- }
+ void HandleReplDone(const TActorContext& ctx) {
+ ReplDone = true;
+ UpdateReplState(ctx);
+ }
+ void Ignore(const TActorContext&)
+ {}
+
+ void UpdateVDiskStatus(NKikimrBlobStorage::EVDiskStatus status, const TActorContext& ctx) {
+ const auto& base = Db->Config->BaseInfo;
+ Send(NodeWardenServiceId, new TEvStatusUpdate(ctx.SelfID.NodeId(), base.PDiskId, base.VDiskSlotId, status));
+ }
+
////////////////////////////////////////////////////////////////////////
// STATES SECTOR
////////////////////////////////////////////////////////////////////////
@@ -2169,8 +2169,8 @@ namespace NKikimr {
// generation independent self VDisk Id
auto genIndSelfVDiskId = SelfVDiskId;
genIndSelfVDiskId.GroupGeneration = -1;
- LocalDbRecoveryID = ctx.Register(CreateDatabaseLocalRecoveryActor(VCtx, Config, genIndSelfVDiskId, SelfId(),
- *SkeletonFrontIDPtr, Arena));
+ LocalDbRecoveryID = ctx.Register(CreateDatabaseLocalRecoveryActor(VCtx, Config, genIndSelfVDiskId, SelfId(),
+ *SkeletonFrontIDPtr, Arena));
ActiveActors.Insert(LocalDbRecoveryID);
UpdateWhiteboard(ctx);
}
@@ -2186,44 +2186,44 @@ namespace NKikimr {
Die(ctx);
}
- void HandleCommenceRepl(const TActorContext& /*ctx*/) {
- CommenceRepl = true;
- if (Db->ReplID) {
- TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, Db->ReplID, SelfId(), nullptr, 0));
- }
- }
-
- void ForwardToScrubActor(STFUNC_SIG) {
- ctx.Send(ev->Forward(ScrubId));
- }
-
+ void HandleCommenceRepl(const TActorContext& /*ctx*/) {
+ CommenceRepl = true;
+ if (Db->ReplID) {
+ TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, Db->ReplID, SelfId(), nullptr, 0));
+ }
+ }
+
+ void ForwardToScrubActor(STFUNC_SIG) {
+ ctx.Send(ev->Forward(ScrubId));
+ }
+
void ForwardToDefragActor(STFUNC_SIG) {
ctx.Send(ev->Forward(DefragId));
}
- void Handle(TEvReportScrubStatus::TPtr ev, const TActorContext& ctx) {
- HasUnreadableBlobs = ev->Get()->HasUnreadableBlobs;
- UpdateReplState(ctx);
- ctx.Send(ev->Forward(*SkeletonFrontIDPtr));
- }
-
- void UpdateReplState(const TActorContext& ctx) {
- const bool ready = ReplDone && !HasUnreadableBlobs;
- UpdateVDiskStatus(ready ? NKikimrBlobStorage::READY : NKikimrBlobStorage::REPLICATING, ctx);
- }
-
- void Handle(TEvRestoreCorruptedBlob::TPtr ev, const TActorContext& ctx) {
- ctx.Register(CreateRestoreCorruptedBlobActor(SelfId(), ev, GInfo, VCtx, PDiskCtx));
- }
-
- void Handle(TEvBlobStorage::TEvCaptureVDiskLayout::TPtr ev, const TActorContext& ctx) {
- ctx.Register(new TCaptureVDiskLayoutActor(ev, Hull->GetSnapshot()));
- }
-
- void ForwardToLogoBlobsLevelIndexActor(STFUNC_SIG) {
- ctx.Send(ev->Forward(Hull->GetHullDs()->LogoBlobs->LIActor));
- }
-
+ void Handle(TEvReportScrubStatus::TPtr ev, const TActorContext& ctx) {
+ HasUnreadableBlobs = ev->Get()->HasUnreadableBlobs;
+ UpdateReplState(ctx);
+ ctx.Send(ev->Forward(*SkeletonFrontIDPtr));
+ }
+
+ void UpdateReplState(const TActorContext& ctx) {
+ const bool ready = ReplDone && !HasUnreadableBlobs;
+ UpdateVDiskStatus(ready ? NKikimrBlobStorage::READY : NKikimrBlobStorage::REPLICATING, ctx);
+ }
+
+ void Handle(TEvRestoreCorruptedBlob::TPtr ev, const TActorContext& ctx) {
+ ctx.Register(CreateRestoreCorruptedBlobActor(SelfId(), ev, GInfo, VCtx, PDiskCtx));
+ }
+
+ void Handle(TEvBlobStorage::TEvCaptureVDiskLayout::TPtr ev, const TActorContext& ctx) {
+ ctx.Register(new TCaptureVDiskLayoutActor(ev, Hull->GetSnapshot()));
+ }
+
+ void ForwardToLogoBlobsLevelIndexActor(STFUNC_SIG) {
+ ctx.Send(ev->Forward(Hull->GetHullDs()->LogoBlobs->LIActor));
+ }
+
// NOTES: we have 4 state functions, one of which is an error state (StateDatabaseError) and
// others are good: StateLocalRecovery, StateSyncGuidRecovery, StateNormal
// We switch between states in the following manner:
@@ -2238,178 +2238,178 @@ namespace NKikimr {
// state. We don't care about sync quorum anymore, it's responsibility of blobstorage
// proxy to perform some action if too many vdisks become unavailable.
- STRICT_STFUNC(StateLocalRecovery,
- // We should not get these requests while performing LocalRecovery
- // TEvBlobStorage::TEvVPut
+ STRICT_STFUNC(StateLocalRecovery,
+ // We should not get these requests while performing LocalRecovery
+ // TEvBlobStorage::TEvVPut
// TEvDelLogoBlobDataSyncLog
// TEvAddBulkSst
- // TEvBlobStorage::TEvVGet
- // TEvBlobStorage::TEvVBlock
- // TEvBlobStorage::TEvVGetBlock
- // TEvBlobStorage::TEvVCollectGarbage
- // TEvBlobStorage::TEvVGetBarrier
- // TEvBlobStorage::TEvVSync
- // TEvBlobStorage::TEvVSyncFull
- // TEvCallOsiris
+ // TEvBlobStorage::TEvVGet
+ // TEvBlobStorage::TEvVBlock
+ // TEvBlobStorage::TEvVGetBlock
+ // TEvBlobStorage::TEvVCollectGarbage
+ // TEvBlobStorage::TEvVGetBarrier
+ // TEvBlobStorage::TEvVSync
+ // TEvBlobStorage::TEvVSyncFull
+ // TEvCallOsiris
// TEvAnubisOsirisPut
- // TEvBlobStorage::TEvVSyncGuid
- // TEvSyncGuidRecoveryDone -- can't get in this state
- // TEvBlobStorage::TEvVStatus
- // TEvBlobStorage::TEvVDbStat
- // TEvBlobStorage::TEvVCompact
+ // TEvBlobStorage::TEvVSyncGuid
+ // TEvSyncGuidRecoveryDone -- can't get in this state
+ // TEvBlobStorage::TEvVStatus
+ // TEvBlobStorage::TEvVDbStat
+ // TEvBlobStorage::TEvVCompact
IgnoreFunc(TEvBlobStorage::TEvVDefrag);
// TEvHullCompactResult
// TEvCompactVDisk
// TEvBlobStorage::TEvVBaldSyncLog
- HFunc(TEvBlobStorage::TEvLocalRecoveryDone, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
+ HFunc(TEvBlobStorage::TEvLocalRecoveryDone, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
HFunc(TEvProxyQueueState, Handle)
- )
+ )
- STRICT_STFUNC(StateSyncGuidRecovery,
- // We should not get these requests while performing SyncGuidRecovery
- // TEvBlobStorage::TEvVPut
+ STRICT_STFUNC(StateSyncGuidRecovery,
+ // We should not get these requests while performing SyncGuidRecovery
+ // TEvBlobStorage::TEvVPut
HFunc(TEvDelLogoBlobDataSyncLog, Handle)
HFunc(TEvAddBulkSst, Handle)
- // TEvBlobStorage::TEvVGet
- // TEvBlobStorage::TEvVBlock
- // TEvBlobStorage::TEvVGetBlock
- // TEvBlobStorage::TEvVCollectGarbage
- // TEvBlobStorage::TEvVGetBarrier
- // TEvBlobStorage::TEvVSync
- // TEvBlobStorage::TEvVSyncFull
- HFunc(TEvCallOsiris, Handle)
+ // TEvBlobStorage::TEvVGet
+ // TEvBlobStorage::TEvVBlock
+ // TEvBlobStorage::TEvVGetBlock
+ // TEvBlobStorage::TEvVCollectGarbage
+ // TEvBlobStorage::TEvVGetBarrier
+ // TEvBlobStorage::TEvVSync
+ // TEvBlobStorage::TEvVSyncFull
+ HFunc(TEvCallOsiris, Handle)
HFunc(TEvAnubisOsirisPut, Handle)
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- HFunc(TEvSyncGuidRecoveryDone, Handle)
- HFunc(TEvLocalSyncData, Handle)
- // TEvBlobStorage::TEvVStatus
- // TEvBlobStorage::TEvVDbStat
- HFunc(TEvBlobStorage::TEvVCompact, Handle)
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ HFunc(TEvSyncGuidRecoveryDone, Handle)
+ HFunc(TEvLocalSyncData, Handle)
+ // TEvBlobStorage::TEvVStatus
+ // TEvBlobStorage::TEvVDbStat
+ HFunc(TEvBlobStorage::TEvVCompact, Handle)
FFunc(TEvBlobStorage::EvVDefrag, ForwardToDefragActor)
HFunc(TEvCompactVDisk, Handle)
HFunc(TEvHullCompactResult, Handle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, Handle)
HFunc(NPDisk::TEvLogResult, Handle)
- CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
- CFunc(TEvBlobStorage::EvKickEmergencyPutQueue, KickEmergencyPutQueue)
- CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
+ CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
+ CFunc(TEvBlobStorage::EvKickEmergencyPutQueue, KickEmergencyPutQueue)
+ CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
HFunc(TEvTakeHullSnapshot, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(NPDisk::TEvConfigureSchedulerResult, Handle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(NPDisk::TEvConfigureSchedulerResult, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
- HFunc(TEvReportScrubStatus, Handle)
- HFunc(TEvRestoreCorruptedBlob, Handle)
- HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
+ HFunc(TEvReportScrubStatus, Handle)
+ HFunc(TEvRestoreCorruptedBlob, Handle)
+ HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
HFunc(TEvProxyQueueState, Handle)
- )
+ )
- STRICT_STFUNC(StateNormal,
+ STRICT_STFUNC(StateNormal,
HFunc(TEvBlobStorage::TEvVMovedPatch, Handle)
HFunc(TEvBlobStorage::TEvVPatchStart, Handle)
HFunc(TEvBlobStorage::TEvVPatchDiff, HandleVPatchDiffResending)
HFunc(TEvBlobStorage::TEvVPatchXorDiff, HandleVPatchDiffResending)
hFunc(TEvVPatchDyingRequest, Handle)
- HFunc(TEvBlobStorage::TEvVPut, Handle)
+ HFunc(TEvBlobStorage::TEvVPut, Handle)
HFunc(TEvBlobStorage::TEvVMultiPut, Handle)
- HFunc(TEvHullLogHugeBlob, Handle)
+ HFunc(TEvHullLogHugeBlob, Handle)
HFunc(TEvDelLogoBlobDataSyncLog, Handle)
HFunc(TEvAddBulkSst, Handle)
- HFunc(TEvBlobStorage::TEvVGet, Handle)
- HFunc(TEvBlobStorage::TEvVBlock, Handle)
- HFunc(TEvBlobStorage::TEvVGetBlock, Handle)
- HFunc(TEvBlobStorage::TEvVCollectGarbage, Handle)
- HFunc(TEvBlobStorage::TEvVGetBarrier, Handle)
- HFunc(TEvBlobStorage::TEvVSync, Handle)
- HFunc(TEvBlobStorage::TEvVSyncFull, Handle)
- // TEvCallOsiris
+ HFunc(TEvBlobStorage::TEvVGet, Handle)
+ HFunc(TEvBlobStorage::TEvVBlock, Handle)
+ HFunc(TEvBlobStorage::TEvVGetBlock, Handle)
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, Handle)
+ HFunc(TEvBlobStorage::TEvVGetBarrier, Handle)
+ HFunc(TEvBlobStorage::TEvVSync, Handle)
+ HFunc(TEvBlobStorage::TEvVSyncFull, Handle)
+ // TEvCallOsiris
// TEvAnubisOsirisPut
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- // TEvSyncGuidRecoveryDone
- HFunc(TEvLocalSyncData, Handle)
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ // TEvSyncGuidRecoveryDone
+ HFunc(TEvLocalSyncData, Handle)
HFunc(NPDisk::TEvLogResult, Handle)
- CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
- CFunc(TEvBlobStorage::EvKickEmergencyPutQueue, KickEmergencyPutQueue)
- CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
- HFunc(TEvRecoveredHugeBlob, Handle)
- HFunc(TEvDetectedPhantomBlob, Handle)
- HFunc(TEvBlobStorage::TEvVStatus, Handle)
- HFunc(TEvBlobStorage::TEvVDbStat, Handle)
- HFunc(TEvBlobStorage::TEvMonStreamQuery, Handle)
- HFunc(TEvBlobStorage::TEvMonStreamActorDeathNote, Handle)
- HFunc(TEvBlobStorage::TEvVCompact, Handle)
+ CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
+ CFunc(TEvBlobStorage::EvKickEmergencyPutQueue, KickEmergencyPutQueue)
+ CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
+ HFunc(TEvRecoveredHugeBlob, Handle)
+ HFunc(TEvDetectedPhantomBlob, Handle)
+ HFunc(TEvBlobStorage::TEvVStatus, Handle)
+ HFunc(TEvBlobStorage::TEvVDbStat, Handle)
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, Handle)
+ HFunc(TEvBlobStorage::TEvMonStreamActorDeathNote, Handle)
+ HFunc(TEvBlobStorage::TEvVCompact, Handle)
FFunc(TEvBlobStorage::EvVDefrag, ForwardToDefragActor)
HFunc(TEvCompactVDisk, Handle)
HFunc(TEvHullCompactResult, Handle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, Handle)
HFunc(TEvTakeHullSnapshot, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(NPDisk::TEvConfigureSchedulerResult, Handle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(NPDisk::TEvConfigureSchedulerResult, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvReplDone, HandleReplDone)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
- HFunc(TEvReportScrubStatus, Handle)
- HFunc(TEvRestoreCorruptedBlob, Handle)
- HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvReplDone, HandleReplDone)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
+ HFunc(TEvReportScrubStatus, Handle)
+ HFunc(TEvRestoreCorruptedBlob, Handle)
+ HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
HFunc(TEvProxyQueueState, Handle)
- )
-
- STRICT_STFUNC(StateDatabaseError,
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
- CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
- HFunc(NMon::TEvHttpInfo, Handle)
- CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
+ )
+
+ STRICT_STFUNC(StateDatabaseError,
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ CFunc(TEvBlobStorage::EvCompactionFinished, LevelIndexCompactionFinished)
+ CFunc(TEvBlobStorage::EvWakeupEmergencyPutQueue, WakeupEmergencyPutQueue)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvVGenerationChange, Handle)
- CFunc(TEvBlobStorage::EvReplDone, Ignore)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
- FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
+ HFunc(TEvents::TEvActorDied, Handle)
+ HFunc(TEvVGenerationChange, Handle)
+ CFunc(TEvBlobStorage::EvReplDone, Ignore)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvRecoverBlob, ForwardToScrubActor)
+ FFunc(TEvBlobStorage::EvNonrestoredCorruptedBlobNotify, ForwardToScrubActor)
IgnoreFunc(TEvBlobStorage::TEvVDefrag);
- HFunc(TEvReportScrubStatus, Handle)
- HFunc(TEvRestoreCorruptedBlob, Handle)
- HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
+ HFunc(TEvReportScrubStatus, Handle)
+ HFunc(TEvRestoreCorruptedBlob, Handle)
+ HFunc(TEvBlobStorage::TEvCaptureVDiskLayout, Handle)
HFunc(TEvProxyQueueState, Handle)
hFunc(TEvVPatchDyingRequest, Handle)
- )
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VDISK_SKELETON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VDISK_SKELETON;
}
TSkeleton(TIntrusivePtr<TVDiskConfig> cfg,
@@ -2427,10 +2427,10 @@ namespace NKikimr {
, LocalDbRecoveryID()
, NodeWardenServiceId(MakeBlobStorageNodeWardenID(vctx->NodeId))
, SelfVDiskId(GInfo->GetVDiskId(VCtx->ShortSelfVDisk))
- , Arena(std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate))
+ , Arena(std::make_shared<TRopeArena>(&TRopeArenaBackend::Allocate))
, VDiskMonGroup(VCtx->VDiskCounters, "subsystem", "state")
, SyncLogIFaceGroup(VCtx->VDiskCounters, "subsystem", "synclog")
- , IFaceMonGroup(std::make_shared<NMonGroup::TVDiskIFaceGroup>(
+ , IFaceMonGroup(std::make_shared<NMonGroup::TVDiskIFaceGroup>(
VCtx->VDiskCounters, "subsystem", "interface"))
, EnableVPatch(cfg->EnableVPatch)
{}
@@ -2446,13 +2446,13 @@ namespace NKikimr {
TPDiskCtxPtr PDiskCtx;
THullCtxPtr HullCtx;
THugeBlobCtxPtr HugeBlobCtx;
- std::shared_ptr<THullLogCtx> HullLogCtx;
- std::shared_ptr<THull> Hull; // run it after local recovery
- std::shared_ptr<TOutOfSpaceLogic> OutOfSpaceLogic;
- std::shared_ptr<TQueryCtx> QueryCtx;
+ std::shared_ptr<THullLogCtx> HullLogCtx;
+ std::shared_ptr<THull> Hull; // run it after local recovery
+ std::shared_ptr<TOutOfSpaceLogic> OutOfSpaceLogic;
+ std::shared_ptr<TQueryCtx> QueryCtx;
TIntrusivePtr<TVPatchCtx> VPatchCtx;
TIntrusivePtr<TLocalRecoveryInfo> LocalRecovInfo; // just info we got after local recovery
- std::unique_ptr<TOverloadHandler> OverloadHandler;
+ std::unique_ptr<TOverloadHandler> OverloadHandler;
TActorIDPtr SkeletonFrontIDPtr;
TActorId LocalDbRecoveryID;
const TActorId NodeWardenServiceId;
@@ -2460,20 +2460,20 @@ namespace NKikimr {
TMaybe<ui64> DbBirthLsn;
TActiveActors ActiveActors;
// fields for handling NPDisk::TEvCutLog
- std::unique_ptr<NPDisk::TEvCutLog> CutLogDelayedMsg;
+ std::unique_ptr<NPDisk::TEvCutLog> CutLogDelayedMsg;
bool LocalDbInitialized = false;
- std::shared_ptr<TRopeArena> Arena;
+ std::shared_ptr<TRopeArena> Arena;
NMonGroup::TVDiskStateGroup VDiskMonGroup;
NMonGroup::TSyncLogIFaceGroup SyncLogIFaceGroup;
- std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
- bool ReplDone = false;
- TInstant WhiteboardUpdateTimestamp = TInstant::Zero();
- std::shared_ptr<std::atomic_uint64_t> PDiskWriteBytes = std::make_shared<std::atomic_uint64_t>();
+ std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
+ bool ReplDone = false;
+ TInstant WhiteboardUpdateTimestamp = TInstant::Zero();
+ std::shared_ptr<std::atomic_uint64_t> PDiskWriteBytes = std::make_shared<std::atomic_uint64_t>();
TLoggedRecsVault LoggedRecsVault;
- bool CommenceRepl = false;
- TActorId ScrubId;
+ bool CommenceRepl = false;
+ TActorId ScrubId;
TActorId DefragId;
- bool HasUnreadableBlobs = false;
+ bool HasUnreadableBlobs = false;
std::unique_ptr<TVDiskCompactionState> VDiskCompactionState;
TMemorizableControlWrapper EnableVPatch;
THashMap<TLogoBlobID, TActorId> VPatchActors;
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonerr.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonerr.h
index 7e899b32368..df0e4213723 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonerr.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonerr.h
@@ -76,147 +76,147 @@ namespace NKikimr {
return vctx->IFaceMonGroup->PatchResMsgsPtr();
}
- template<typename TRequest, typename TResponse>
- inline void SetRacingGroupInfo(const TRequest& request, TResponse& response,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo) {
- if (response.GetStatus() == NKikimrProto::RACE && groupInfo->Group) {
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(request.GetVDiskID());
- if (vdiskId.GroupID == groupInfo->GroupID && vdiskId.GroupGeneration < groupInfo->GroupGeneration) {
- response.MutableRecentGroup()->CopyFrom(*groupInfo->Group);
- }
- }
- }
-
+ template<typename TRequest, typename TResponse>
+ inline void SetRacingGroupInfo(const TRequest& request, TResponse& response,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo) {
+ if (response.GetStatus() == NKikimrProto::RACE && groupInfo->Group) {
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(request.GetVDiskID());
+ if (vdiskId.GroupID == groupInfo->GroupID && vdiskId.GroupGeneration < groupInfo->GroupGeneration) {
+ response.MutableRecentGroup()->CopyFrom(*groupInfo->Group);
+ }
+ }
+ }
+
inline void SetRacingGroupInfo(const NKikimrBlobStorage::TEvVPatchXorDiff&,
NKikimrBlobStorage::TEvVPatchXorDiffResult&, const TIntrusivePtr<TBlobStorageGroupInfo>&)
{}
-
+
////////////////////////////////////////////////////////////////////////////////////////////
// CreateResult -- create result from original message and status
////////////////////////////////////////////////////////////////////////////////////////////
- static inline std::unique_ptr<TEvBlobStorage::TEvVMovedPatchResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
- TEvBlobStorage::TEvVMovedPatch::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
- NKikimrBlobStorage::TEvVMovedPatch &record = ev->Get()->Record;
- TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalBlobId());
- TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
- TMaybe<ui64> cookie;
- if (record.HasCookie()) {
- cookie = record.GetCookie();
+ static inline std::unique_ptr<TEvBlobStorage::TEvVMovedPatchResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TEvBlobStorage::TEvVMovedPatch::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
+ NKikimrBlobStorage::TEvVMovedPatch &record = ev->Get()->Record;
+ TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalBlobId());
+ TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
+ TMaybe<ui64> cookie;
+ if (record.HasCookie()) {
+ cookie = record.GetCookie();
+ }
+ const auto oosStatus = vctx->GetOutOfSpaceState().GetGlobalStatusFlags();
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+
+ return std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(status, originalId, patchedId, vdiskID, cookie,
+ oosStatus, now, ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, nullptr,
+ std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TEvBlobStorage::TEvVPatchStart::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
+ NKikimrBlobStorage::TEvVPatchStart &record = ev->Get()->Record;
+ TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalBlobId());
+ TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
+ TMaybe<ui64> cookie;
+ if (record.HasCookie()) {
+ cookie = record.GetCookie();
}
- const auto oosStatus = vctx->GetOutOfSpaceState().GetGlobalStatusFlags();
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
-
- return std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(status, originalId, patchedId, vdiskID, cookie,
- oosStatus, now, ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, nullptr,
- std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
- TEvBlobStorage::TEvVPatchStart::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
- NKikimrBlobStorage::TEvVPatchStart &record = ev->Get()->Record;
- TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalBlobId());
- TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
- TMaybe<ui64> cookie;
- if (record.HasCookie()) {
- cookie = record.GetCookie();
- }
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
-
- return std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(status, originalId, patchedId, vdiskID, cookie, now,
- errorReason, &record, skeletonFrontIDPtr, counterPtr, nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVPatchResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
- TEvBlobStorage::TEvVPatchDiff::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
-
- auto &record = ev->Get()->Record;
- TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalPartBlobId());
- TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedPartBlobId());
- TMaybe<ui64> cookie;
- if (record.HasCookie()) {
- cookie = record.GetCookie();
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+
+ return std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(status, originalId, patchedId, vdiskID, cookie, now,
+ errorReason, &record, skeletonFrontIDPtr, counterPtr, nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVPatchResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TEvBlobStorage::TEvVPatchDiff::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
+
+ auto &record = ev->Get()->Record;
+ TLogoBlobID originalId = LogoBlobIDFromLogoBlobID(record.GetOriginalPartBlobId());
+ TLogoBlobID patchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedPartBlobId());
+ TMaybe<ui64> cookie;
+ if (record.HasCookie()) {
+ cookie = record.GetCookie();
}
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
-
- auto res = std::make_unique<TEvBlobStorage::TEvVPatchResult>(status, originalId, patchedId, vdiskID, cookie,
- now, &record, skeletonFrontIDPtr, counterPtr, nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
- res->SetStatus(status, errorReason);
- return res;
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
- TEvBlobStorage::TEvVPatchXorDiff::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
-
- Y_UNUSED(errorReason, vdiskID, vdiskIncarnationGuid);
- auto &record = ev->Get()->Record;
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- return std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(status, now, &record, skeletonFrontIDPtr,
- counterPtr, nullptr, std::move(ev->TraceId));
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVPutResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
- TEvBlobStorage::TEvVPut::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
-
- NKikimrBlobStorage::TEvVPut &record = ev->Get()->Record;
- const TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetBlobID());
- const ui64 bufferSizeBytes = ev->Get()->GetBufferBytes();
- const ui64 vcookie = record.GetCookie();
- const ui64 *cookie = record.HasCookie() ? &vcookie : nullptr;
- const auto oosStatus = vctx->GetOutOfSpaceState().GetGlobalStatusFlags();
- const auto handleClass = record.GetHandleClass();
- const NVDiskMon::TLtcHistoPtr &histoPtr = vctx->Histograms.GetHistogram(handleClass);
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
-
- return std::make_unique<TEvBlobStorage::TEvVPutResult>(status, id, vdiskID, cookie, oosStatus, now,
- ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr,
- bufferSizeBytes, std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVBlockResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- const TEvBlobStorage::TEvVBlockResult::TTabletActGen *actual,
- TEvBlobStorage::TEvVBlock::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid)
- {
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- return std::make_unique<TEvBlobStorage::TEvVBlockResult>(status, actual, vdiskID, now,
- ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr,
- nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
- }
-
- static inline std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult>
- CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- TEvBlobStorage::TEvVCollectGarbage::TPtr &ev, const TInstant &now,
- const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid)
- {
- NKikimrBlobStorage::TEvVCollectGarbage &record = ev->Get()->Record;
- const auto tabletId = record.GetTabletId();
- const auto gen = record.GetRecordGeneration();
- const auto channel = record.GetChannel();
- const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- return std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(status, tabletId, gen, channel, vdiskID, now,
- ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, nullptr,
- std::move(ev->TraceId), vdiskIncarnationGuid);
- }
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+
+ auto res = std::make_unique<TEvBlobStorage::TEvVPatchResult>(status, originalId, patchedId, vdiskID, cookie,
+ now, &record, skeletonFrontIDPtr, counterPtr, nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
+ res->SetStatus(status, errorReason);
+ return res;
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TEvBlobStorage::TEvVPatchXorDiff::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
+
+ Y_UNUSED(errorReason, vdiskID, vdiskIncarnationGuid);
+ auto &record = ev->Get()->Record;
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+ return std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(status, now, &record, skeletonFrontIDPtr,
+ counterPtr, nullptr, std::move(ev->TraceId));
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVPutResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TEvBlobStorage::TEvVPut::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid) {
+
+ NKikimrBlobStorage::TEvVPut &record = ev->Get()->Record;
+ const TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetBlobID());
+ const ui64 bufferSizeBytes = ev->Get()->GetBufferBytes();
+ const ui64 vcookie = record.GetCookie();
+ const ui64 *cookie = record.HasCookie() ? &vcookie : nullptr;
+ const auto oosStatus = vctx->GetOutOfSpaceState().GetGlobalStatusFlags();
+ const auto handleClass = record.GetHandleClass();
+ const NVDiskMon::TLtcHistoPtr &histoPtr = vctx->Histograms.GetHistogram(handleClass);
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+
+ return std::make_unique<TEvBlobStorage::TEvVPutResult>(status, id, vdiskID, cookie, oosStatus, now,
+ ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr,
+ bufferSizeBytes, std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVBlockResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ const TEvBlobStorage::TEvVBlockResult::TTabletActGen *actual,
+ TEvBlobStorage::TEvVBlock::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid)
+ {
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+ return std::make_unique<TEvBlobStorage::TEvVBlockResult>(status, actual, vdiskID, now,
+ ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr,
+ nullptr, std::move(ev->TraceId), vdiskIncarnationGuid);
+ }
+
+ static inline std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult>
+ CreateResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ TEvBlobStorage::TEvVCollectGarbage::TPtr &ev, const TInstant &now,
+ const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid)
+ {
+ NKikimrBlobStorage::TEvVCollectGarbage &record = ev->Get()->Record;
+ const auto tabletId = record.GetTabletId();
+ const auto gen = record.GetRecordGeneration();
+ const auto channel = record.GetChannel();
+ const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
+ return std::make_unique<TEvBlobStorage::TEvVCollectGarbageResult>(status, tabletId, gen, channel, vdiskID, now,
+ ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, nullptr,
+ std::move(ev->TraceId), vdiskIncarnationGuid);
+ }
////////////////////////////////////////////////////////////////////////////
// NErrBuilder -- routines for error results
////////////////////////////////////////////////////////////////////////////
namespace NErrBuilder {
template <typename TEvPtr>
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
TEvPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
@@ -247,18 +247,18 @@ namespace NKikimr {
vctx->Top->GetFailDomainOrderNumber(vctx->ShortSelfVDisk), id.TabletID(), id.BlobSize());
}
- auto result = CreateResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID,
- vdiskIncarnationGuid);
+ auto result = CreateResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID,
+ vdiskIncarnationGuid);
SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ return result;
}
- static inline std::unique_ptr<IEventBase>
+ static inline std::unique_ptr<IEventBase>
ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
TEvBlobStorage::TEvVMultiPut::TPtr &ev, const TInstant &now,
const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID,
- const TBatchedVec<NKikimrProto::EReplyStatus> &statuses, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TBatchedVec<NKikimrProto::EReplyStatus> &statuses, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
NKikimrBlobStorage::TEvVMultiPut &record = ev->Get()->Record;
LWTRACK(VDiskSkeletonFrontVMultiPutRecieved, ev->Get()->Orbit, vctx->NodeId, vctx->GroupId,
@@ -270,9 +270,9 @@ namespace NKikimr {
const auto handleClass = record.GetHandleClass();
const NVDiskMon::TLtcHistoPtr &histoPtr = vctx->Histograms.GetHistogram(handleClass);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- auto result = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(status, vdiskID, cookie, now,
- ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr, bufferSizeBytes,
- std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
+ auto result = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(status, vdiskID, cookie, now,
+ ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr, bufferSizeBytes,
+ std::move(ev->TraceId), vdiskIncarnationGuid, errorReason);
Y_VERIFY(record.ItemsSize() == statuses.size());
for (ui64 itemIdx = 0; itemIdx < record.ItemsSize(); ++itemIdx) {
auto &item = record.GetItems(itemIdx);
@@ -283,41 +283,41 @@ namespace NKikimr {
cookiePtr = &cookieValue;
}
TLogoBlobID blobId = LogoBlobIDFromLogoBlobID(item.GetBlobID());
- result->AddVPutResult(statuses[itemIdx], errorReason, blobId, cookiePtr);
+ result->AddVPutResult(statuses[itemIdx], errorReason, blobId, cookiePtr);
}
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
TEvBlobStorage::TEvVMultiPut::TPtr &ev, const TInstant &now,
const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
NKikimrBlobStorage::TEvVMultiPut &record = ev->Get()->Record;
TBatchedVec<NKikimrProto::EReplyStatus> statuses(record.ItemsSize(), status);
- return ErroneousResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID, statuses,
- vdiskIncarnationGuid, groupInfo);
+ return ErroneousResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID, statuses,
+ vdiskIncarnationGuid, groupInfo);
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
TEvBlobStorage::TEvVGet::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
- NKikimrBlobStorage::TEvVGet &record = ev->Get()->Record;
- TMaybe<ui64> cookie;
- if (record.HasCookie())
- cookie = record.GetCookie();
+ NKikimrBlobStorage::TEvVGet &record = ev->Get()->Record;
+ TMaybe<ui64> cookie;
+ if (record.HasCookie())
+ cookie = record.GetCookie();
const auto handleClass = record.GetHandleClass();
const NVDiskMon::TLtcHistoPtr &histoPtr = vctx->Histograms.GetHistogram(handleClass);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- auto result = std::make_unique<TEvBlobStorage::TEvVGetResult>(status, vdiskID, now,
- ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr,
- std::move(ev->TraceId), cookie, ev->GetChannel(), vdiskIncarnationGuid);
+ auto result = std::make_unique<TEvBlobStorage::TEvVGetResult>(status, vdiskID, now,
+ ev->Get()->GetCachedByteSize(), &record, skeletonFrontIDPtr, counterPtr, histoPtr,
+ std::move(ev->TraceId), cookie, ev->GetChannel(), vdiskIncarnationGuid);
// range query
if (record.HasRangeQuery()) {
const NKikimrBlobStorage::TRangeQuery *q = &record.GetRangeQuery();
@@ -334,112 +334,112 @@ namespace NKikimr {
const ui64 *cookie = q->HasCookie() ? &vcookie : nullptr;
result->AddResult(status, first, cookie);
}
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
TEvBlobStorage::TEvVBlock::TPtr &ev, const TInstant &now, const TActorIDPtr &skeletonFrontIDPtr,
- const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
- auto result = CreateResult(vctx, status, errorReason, nullptr, ev, now, skeletonFrontIDPtr, vdiskID,
- vdiskIncarnationGuid);
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ auto result = CreateResult(vctx, status, errorReason, nullptr, ev, now, skeletonFrontIDPtr, vdiskID,
+ vdiskIncarnationGuid);
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
TEvBlobStorage::TEvVGetBlock::TPtr &ev, const TInstant &now,
- const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- auto result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(status, ev->Get()->Record.GetTabletId(),
- vdiskID, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr,
- nullptr, std::move(ev->TraceId));
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ auto result = std::make_unique<TEvBlobStorage::TEvVGetBlockResult>(status, ev->Get()->Record.GetTabletId(),
+ vdiskID, now, ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr,
+ nullptr, std::move(ev->TraceId));
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& errorReason,
TEvBlobStorage::TEvVCollectGarbage::TPtr &ev, const TInstant &now,
- const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
- auto result = CreateResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID,
- vdiskIncarnationGuid);
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ auto result = CreateResult(vctx, status, errorReason, ev, now, skeletonFrontIDPtr, vdiskID,
+ vdiskIncarnationGuid);
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
TEvBlobStorage::TEvVGetBarrier::TPtr &ev, const TInstant &now,
- const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
+ const TActorIDPtr &skeletonFrontIDPtr, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- auto result = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(status,vdiskID, now,
- ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr, nullptr,
- std::move(ev->TraceId));
- SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
- return result;
+ auto result = std::make_unique<TEvBlobStorage::TEvVGetBarrierResult>(status,vdiskID, now,
+ ev->Get()->GetCachedByteSize(), &ev->Get()->Record, skeletonFrontIDPtr, counterPtr, nullptr,
+ std::move(ev->TraceId));
+ SetRacingGroupInfo(ev->Get()->Record, result->Record, groupInfo);
+ return result;
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- TEvBlobStorage::TEvVDbStat::TPtr & ev, const TInstant &now,
- const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ TEvBlobStorage::TEvVDbStat::TPtr & ev, const TInstant &now,
+ const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- return std::make_unique<TEvBlobStorage::TEvVDbStatResult>(status, vdiskID, now, counterPtr, nullptr,
- std::move(ev->TraceId));
+ return std::make_unique<TEvBlobStorage::TEvVDbStatResult>(status, vdiskID, now, counterPtr, nullptr,
+ std::move(ev->TraceId));
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
- TEvBlobStorage::TEvVSync::TPtr & ev, const TInstant &now,
- const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ TEvBlobStorage::TEvVSync::TPtr & ev, const TInstant &now,
+ const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
auto flags = vctx->GetOutOfSpaceState().GetLocalStatusFlags();
- return std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, vdiskID, flags, now, counterPtr, nullptr,
- std::move(ev->TraceId), ev->GetChannel());
+ return std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, vdiskID, flags, now, counterPtr, nullptr,
+ std::move(ev->TraceId), ev->GetChannel());
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
TEvBlobStorage::TEvVSyncFull::TPtr &ev, const TInstant &now,
- const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
+ const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
ui64 cookie = ev->Get()->Record.GetCookie();
- return std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(status, vdiskID, cookie, now, counterPtr, nullptr,
- std::move(ev->TraceId), ev->GetChannel());
+ return std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(status, vdiskID, cookie, now, counterPtr, nullptr,
+ std::move(ev->TraceId), ev->GetChannel());
}
- static inline std::unique_ptr<IEventBase>
- ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
+ static inline std::unique_ptr<IEventBase>
+ ErroneousResult(const TVDiskContextPtr &vctx, const NKikimrProto::EReplyStatus status, const TString& /*errorReason*/,
TEvBlobStorage::TEvVSyncGuid::TPtr & ev, const TInstant &now,
- const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
- const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
+ const TActorIDPtr &/*skeletonFrontIDPtr*/, const TVDiskID &vdiskID, ui64 vdiskIncarnationGuid,
+ const TIntrusivePtr<TBlobStorageGroupInfo>& /*groupInfo*/)
{
Y_UNUSED(vdiskIncarnationGuid);
const NMonitoring::TDynamicCounters::TCounterPtr &counterPtr = ResultingCounterForEvent(vctx, ev);
- return std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(status, vdiskID, now, counterPtr, nullptr,
- std::move(ev->TraceId), ev->GetChannel());
+ return std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(status, vdiskID, now, counterPtr, nullptr,
+ std::move(ev->TraceId), ev->GetChannel());
}
} // NErrBuilder
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp
index 08c32a8921e..cecbcf06de4 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp
@@ -37,7 +37,7 @@ namespace NKikimr {
TEvFrontRecoveryStatus::TEvFrontRecoveryStatus(EPhase phase,
NKikimrProto::EReplyStatus status,
const TIntrusivePtr<TPDiskParams> &dsk,
- std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
+ std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
TVDiskIncarnationGuid vdiskIncarnationGuid)
: Phase(phase)
, Status(status)
@@ -50,55 +50,55 @@ namespace NKikimr {
namespace {
- // Helper function to extract protobuf's Record from event and push it to callback
- template<typename Func>
- void ApplyToRecord(IEventHandle& event, Func&& callback) {
- switch (event.GetTypeRewrite()) {
-#define EVENT_TYPE(EVENT) case TEvBlobStorage::EVENT::EventType: callback(static_cast<TEvBlobStorage::EVENT&>(*event.GetBase()).Record); return;
+ // Helper function to extract protobuf's Record from event and push it to callback
+ template<typename Func>
+ void ApplyToRecord(IEventHandle& event, Func&& callback) {
+ switch (event.GetTypeRewrite()) {
+#define EVENT_TYPE(EVENT) case TEvBlobStorage::EVENT::EventType: callback(static_cast<TEvBlobStorage::EVENT&>(*event.GetBase()).Record); return;
EVENT_TYPE(TEvVMovedPatch)
EVENT_TYPE(TEvVPatchStart)
EVENT_TYPE(TEvVPatchDiff)
EVENT_TYPE(TEvVPatchXorDiff)
- EVENT_TYPE(TEvVPut)
+ EVENT_TYPE(TEvVPut)
EVENT_TYPE(TEvVMultiPut)
- EVENT_TYPE(TEvVGet)
- EVENT_TYPE(TEvVBlock)
- EVENT_TYPE(TEvVGetBlock)
- EVENT_TYPE(TEvVCollectGarbage)
- EVENT_TYPE(TEvVGetBarrier)
-#undef EVENT_TYPE
- }
- Y_FAIL("unsupported event type");
- }
-
- struct TUpdateInQueueTime {
- TDuration InQueue;
-
- TUpdateInQueueTime(TDuration inQueue)
- : InQueue(inQueue)
- {}
-
- template<typename TRecord>
- void operator ()(TRecord& record) const {
- auto& msgQoS = *record.MutableMsgQoS();
- auto& execTimeStats = *msgQoS.MutableExecTimeStats();
- execTimeStats.SetInQueue(InQueue.GetValue());
- }
- };
-
+ EVENT_TYPE(TEvVGet)
+ EVENT_TYPE(TEvVBlock)
+ EVENT_TYPE(TEvVGetBlock)
+ EVENT_TYPE(TEvVCollectGarbage)
+ EVENT_TYPE(TEvVGetBarrier)
+#undef EVENT_TYPE
+ }
+ Y_FAIL("unsupported event type");
+ }
+
+ struct TUpdateInQueueTime {
+ TDuration InQueue;
+
+ TUpdateInQueueTime(TDuration inQueue)
+ : InQueue(inQueue)
+ {}
+
+ template<typename TRecord>
+ void operator ()(TRecord& record) const {
+ auto& msgQoS = *record.MutableMsgQoS();
+ auto& execTimeStats = *msgQoS.MutableExecTimeStats();
+ execTimeStats.SetInQueue(InQueue.GetValue());
+ }
+ };
+
////////////////////////////////////////////////////////////////////////////
// TRecord for delayed queue
////////////////////////////////////////////////////////////////////////////
struct TRecord {
- std::unique_ptr<IEventHandle> Ev;
+ std::unique_ptr<IEventHandle> Ev;
TInstant ReceivedTime;
TInstant Deadline; // after this deadline we will not process this request
ui32 ByteSize;
NBackpressure::TMessageId MsgId;
ui64 Cost;
NKikimrBlobStorage::EVDiskQueueId ExtQueueId;
- NBackpressure::TQueueClientId ClientId;
- TActorId ActorId;
+ NBackpressure::TQueueClientId ClientId;
+ TActorId ActorId;
TRecord()
: Ev()
@@ -108,31 +108,31 @@ namespace NKikimr {
, MsgId()
, Cost(0)
, ExtQueueId(NKikimrBlobStorage::EVDiskQueueId::Unknown)
- , ClientId()
+ , ClientId()
{}
- TRecord(std::unique_ptr<IEventHandle> ev, TInstant now, ui32 recByteSize, const NBackpressure::TMessageId &msgId,
- ui64 cost, TInstant deadline, NKikimrBlobStorage::EVDiskQueueId extQueueId,
- const NBackpressure::TQueueClientId& clientId)
- : Ev(std::move(ev))
+ TRecord(std::unique_ptr<IEventHandle> ev, TInstant now, ui32 recByteSize, const NBackpressure::TMessageId &msgId,
+ ui64 cost, TInstant deadline, NKikimrBlobStorage::EVDiskQueueId extQueueId,
+ const NBackpressure::TQueueClientId& clientId)
+ : Ev(std::move(ev))
, ReceivedTime(now)
, Deadline(deadline)
, ByteSize(recByteSize)
, MsgId(msgId)
, Cost(cost)
, ExtQueueId(extQueueId)
- , ClientId(clientId)
- , ActorId(Ev->Sender)
+ , ClientId(clientId)
+ , ActorId(Ev->Sender)
{}
};
- using TMyQueueBackpressure = NBackpressure::TQueueBackpressure<NBackpressure::TQueueClientId>;
+ using TMyQueueBackpressure = NBackpressure::TQueueBackpressure<NBackpressure::TQueueClientId>;
using TWindowStatus = TMyQueueBackpressure::TWindowStatus;
using TWindowStatusOpt = TMaybe<TWindowStatus>;
using TFeedback = TMyQueueBackpressure::TFeedback;
- void SendWindowChange(const TActorContext &ctx, const TWindowStatus &wstatus, NKikimrBlobStorage::EVDiskQueueId queueId) {
- ctx.Send(wstatus.ActorId, new TEvBlobStorage::TEvVWindowChange(queueId, wstatus));
+ void SendWindowChange(const TActorContext &ctx, const TWindowStatus &wstatus, NKikimrBlobStorage::EVDiskQueueId queueId) {
+ ctx.Send(wstatus.ActorId, new TEvBlobStorage::TEvVWindowChange(queueId, wstatus));
}
////////////////////////////////////////////////////////////////////////////
@@ -142,7 +142,7 @@ namespace NKikimr {
using TQueueType = TQueueInplace<TRecord, 4096>;
private:
- std::unique_ptr<TQueueType, TQueueType::TCleanDestructor> Queue;
+ std::unique_ptr<TQueueType, TQueueType::TCleanDestructor> Queue;
ui64 InFlightCount;
ui64 InFlightCost;
ui64 InFlightBytes;
@@ -161,7 +161,7 @@ namespace NKikimr {
NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontInFlightBytes;
NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontDelayedCount;
NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontDelayedBytes;
- NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontCostProcessed;
+ NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontCostProcessed;
bool CanSendToSkeleton(ui64 cost) const {
bool inFlightCond = InFlightCount < MaxInFlightCount;
@@ -193,22 +193,22 @@ namespace NKikimr {
, SkeletonFrontInFlightBytes(skeletonFrontGroup->GetCounter("SkeletonFront/" + Name + "/InFlightBytes", false))
, SkeletonFrontDelayedCount(skeletonFrontGroup->GetCounter("SkeletonFront/" + Name + "/DelayedCount", false))
, SkeletonFrontDelayedBytes(skeletonFrontGroup->GetCounter("SkeletonFront/" + Name + "/DelayedBytes", false))
- , SkeletonFrontCostProcessed(skeletonFrontGroup->GetCounter("SkeletonFront/" + Name + "/CostProcessed", true))
+ , SkeletonFrontCostProcessed(skeletonFrontGroup->GetCounter("SkeletonFront/" + Name + "/CostProcessed", true))
{}
ui64 GetSize() const {
return Queue->GetSize();
}
- template<typename TFront>
- void Enqueue(const TActorContext &ctx, ui32 recByteSize, std::unique_ptr<IEventHandle> converted,
+ template<typename TFront>
+ void Enqueue(const TActorContext &ctx, ui32 recByteSize, std::unique_ptr<IEventHandle> converted,
const NBackpressure::TMessageId &msgId, ui64 cost, const TInstant &deadline,
- NKikimrBlobStorage::EVDiskQueueId extQueueId, TFront& front,
- const NBackpressure::TQueueClientId& clientId) {
+ NKikimrBlobStorage::EVDiskQueueId extQueueId, TFront& front,
+ const NBackpressure::TQueueClientId& clientId) {
Y_UNUSED(front);
- if (!Queue->Head() && CanSendToSkeleton(cost)) {
+ if (!Queue->Head() && CanSendToSkeleton(cost)) {
// send to Skeleton for further processing
- ctx.ExecutorThread.Send(converted.release());
+ ctx.ExecutorThread.Send(converted.release());
++InFlightCount;
InFlightCost += cost;
InFlightBytes += recByteSize;
@@ -224,25 +224,25 @@ namespace NKikimr {
++*SkeletonFrontDelayedCount;
*SkeletonFrontDelayedBytes += recByteSize;
- WILSON_TRACE_FROM_ACTOR(ctx, front, &converted->TraceId, EvSkeletonFrontEnqueue);
-
+ WILSON_TRACE_FROM_ACTOR(ctx, front, &converted->TraceId, EvSkeletonFrontEnqueue);
+
TInstant now = TAppData::TimeProvider->Now();
- Queue->Push(TRecord(std::move(converted), now, recByteSize, msgId, cost, deadline, extQueueId, clientId));
+ Queue->Push(TRecord(std::move(converted), now, recByteSize, msgId, cost, deadline, extQueueId, clientId));
}
}
- template<typename TFront>
- void DropWithError(const TActorContext& ctx, TFront& front) {
- ProcessNext(ctx, front, true);
- }
-
+ template<typename TFront>
+ void DropWithError(const TActorContext& ctx, TFront& front) {
+ ProcessNext(ctx, front, true);
+ }
+
private:
template <class TFront>
- void ProcessNext(const TActorContext &ctx, TFront &front, bool forceError) {
+ void ProcessNext(const TActorContext &ctx, TFront &front, bool forceError) {
// we can send next element to Skeleton if any
while (TRecord *rec = Queue->Head()) {
const ui64 cost = rec->Cost;
- if (CanSendToSkeleton(cost) || forceError) {
+ if (CanSendToSkeleton(cost) || forceError) {
ui32 recByteSize = rec->ByteSize;
Y_VERIFY_DEBUG(DelayedCount > 0 && DelayedBytes >= recByteSize);
@@ -251,19 +251,19 @@ namespace NKikimr {
--*SkeletonFrontDelayedCount;
*SkeletonFrontDelayedBytes -= recByteSize;
- // update in-queue duration for this query
+ // update in-queue duration for this query
TInstant now = TAppData::TimeProvider->Now();
- TDuration inQueue = now - rec->ReceivedTime;
- ApplyToRecord(*rec->Ev, TUpdateInQueueTime(inQueue));
-
- if (forceError) {
- front.GetExtQueue(rec->ExtQueueId).DroppedWithError(ctx, rec, now, front);
- } else if (now >= rec->Deadline) {
+ TDuration inQueue = now - rec->ReceivedTime;
+ ApplyToRecord(*rec->Ev, TUpdateInQueueTime(inQueue));
+
+ if (forceError) {
+ front.GetExtQueue(rec->ExtQueueId).DroppedWithError(ctx, rec, now, front);
+ } else if (now >= rec->Deadline) {
++Deadlines;
front.GetExtQueue(rec->ExtQueueId).DeadlineHappened(ctx, rec, now, front);
} else {
- WILSON_TRACE_FROM_ACTOR(ctx, front, &rec->Ev->TraceId, EvSkeletonFrontProceed);
- ctx.ExecutorThread.Send(rec->Ev.release());
+ WILSON_TRACE_FROM_ACTOR(ctx, front, &rec->Ev->TraceId, EvSkeletonFrontProceed);
+ ctx.ExecutorThread.Send(rec->Ev.release());
++InFlightCount;
InFlightCost += cost;
@@ -296,9 +296,9 @@ namespace NKikimr {
--*SkeletonFrontInFlightCount;
*SkeletonFrontInFlightCost -= msgCtx.Cost;
*SkeletonFrontInFlightBytes -= msgCtx.RecByteSize;
- *SkeletonFrontCostProcessed += msgCtx.Cost;
+ *SkeletonFrontCostProcessed += msgCtx.Cost;
- ProcessNext(ctx, front, false);
+ ProcessNext(ctx, front, false);
}
// enumeration of parameters we take into account to diagnose overloading
@@ -401,12 +401,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TExtQueueClass {
private:
- std::unique_ptr<TMyQueueBackpressure> QueueBackpressure;
+ std::unique_ptr<TMyQueueBackpressure> QueueBackpressure;
NKikimrBlobStorage::EVDiskQueueId ExtQueueId;
TString Name;
NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontDeadline;
NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontOverflow;
- NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontIncorrectMsgId;
+ NMonitoring::TDynamicCounters::TCounterPtr SkeletonFrontIncorrectMsgId;
void NotifyOtherClients(const TActorContext &ctx, const TFeedback &feedback) {
@@ -420,65 +420,65 @@ namespace NKikimr {
ss << "Feedback: ";
feedback.Output(ss);
ss << "\nQueueBackpressureState: ";
- TInstant now = TAppData::TimeProvider->Now();
- QueueBackpressure->Output(ss, now);
+ TInstant now = TAppData::TimeProvider->Now();
+ QueueBackpressure->Output(ss, now);
Cerr << "\n\n" << ss.Str() << "\n\n";
}
public:
TExtQueueClass(NKikimrBlobStorage::EVDiskQueueId extQueueId, const TString &name, ui64 totalCost,
- bool checkMsgId, TIntrusivePtr<NMonitoring::TDynamicCounters> skeletonFrontGroup,
- const TIntrusivePtr<TVDiskConfig>& config)
+ bool checkMsgId, TIntrusivePtr<NMonitoring::TDynamicCounters> skeletonFrontGroup,
+ const TIntrusivePtr<TVDiskConfig>& config)
: QueueBackpressure()
, ExtQueueId(extQueueId)
, Name(name)
, SkeletonFrontDeadline(skeletonFrontGroup->GetCounter("SkeletonFront/" + name + "/Deadline", true))
, SkeletonFrontOverflow(skeletonFrontGroup->GetCounter("SkeletonFront/" + name + "/Overflow", true))
- , SkeletonFrontIncorrectMsgId(skeletonFrontGroup->GetCounter("SkeletonFront/" + name + "/IncorrectMsgId", true))
+ , SkeletonFrontIncorrectMsgId(skeletonFrontGroup->GetCounter("SkeletonFront/" + name + "/IncorrectMsgId", true))
{
- // recalculate window percents to cost
- ui64 costChangeToRecalculate = totalCost * config->WindowCostChangeToRecalculatePercent / 100;
- ui64 minLowWatermark = totalCost * config->WindowMinLowWatermarkPercent / 100;
- ui64 maxLowWatermark = totalCost * config->WindowMaxLowWatermarkPercent / 100;
- ui64 costChangeUntilFrozen = totalCost * config->WindowCostChangeUntilFrozenPercent / 100;
- ui64 costChangeUntilDeath = totalCost * config->WindowCostChangeUntilDeathPercent / 100;
-
- ui64 percentThreshold = config->WindowPercentThreshold;
-
- QueueBackpressure = std::make_unique<TMyQueueBackpressure>(checkMsgId, totalCost, costChangeToRecalculate,
- minLowWatermark, maxLowWatermark, percentThreshold, costChangeUntilFrozen, costChangeUntilDeath,
- config->WindowTimeout);
- }
-
- std::optional<NBackpressure::TMessageId> GetExpectedMsgId(const TActorId& actorId) const {
- return QueueBackpressure->GetExpectedMsgId(actorId);
+ // recalculate window percents to cost
+ ui64 costChangeToRecalculate = totalCost * config->WindowCostChangeToRecalculatePercent / 100;
+ ui64 minLowWatermark = totalCost * config->WindowMinLowWatermarkPercent / 100;
+ ui64 maxLowWatermark = totalCost * config->WindowMaxLowWatermarkPercent / 100;
+ ui64 costChangeUntilFrozen = totalCost * config->WindowCostChangeUntilFrozenPercent / 100;
+ ui64 costChangeUntilDeath = totalCost * config->WindowCostChangeUntilDeathPercent / 100;
+
+ ui64 percentThreshold = config->WindowPercentThreshold;
+
+ QueueBackpressure = std::make_unique<TMyQueueBackpressure>(checkMsgId, totalCost, costChangeToRecalculate,
+ minLowWatermark, maxLowWatermark, percentThreshold, costChangeUntilFrozen, costChangeUntilDeath,
+ config->WindowTimeout);
}
+ std::optional<NBackpressure::TMessageId> GetExpectedMsgId(const TActorId& actorId) const {
+ return QueueBackpressure->GetExpectedMsgId(actorId);
+ }
+
// return true if enqueed, false otherwise
template <class TFront>
- std::unique_ptr<IEventHandle> Enqueue(const TActorContext &ctx, std::unique_ptr<IEventHandle> converted,
- const NBackpressure::TMessageId &msgId, ui64 cost, TFront &front,
- const NBackpressure::TQueueClientId& clientId) {
- TInstant now = TAppData::TimeProvider->Now();
- auto feedback = QueueBackpressure->Push(clientId, converted->Sender, msgId, cost, now);
+ std::unique_ptr<IEventHandle> Enqueue(const TActorContext &ctx, std::unique_ptr<IEventHandle> converted,
+ const NBackpressure::TMessageId &msgId, ui64 cost, TFront &front,
+ const NBackpressure::TQueueClientId& clientId) {
+ TInstant now = TAppData::TimeProvider->Now();
+ auto feedback = QueueBackpressure->Push(clientId, converted->Sender, msgId, cost, now);
NotifyOtherClients(ctx, feedback);
if (!feedback.Good()) {
#ifdef VERBOSE
OutputBadFeedback(feedback);
#endif
- TString errorReason;
- NKikimrProto::EReplyStatus status = NKikimrProto::TRYLATER_SIZE;
- if (feedback.first.Status == NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId) {
- // special status to distinguish between incorrect message id and queue overflow
- status = NKikimrProto::TRYLATER;
- errorReason = "incorrect message id";
- ++*SkeletonFrontIncorrectMsgId;
- } else {
- // overflow
- errorReason = "queue overflow";
- ++*SkeletonFrontOverflow;
- }
- front.ReplyFunc(std::move(converted), ctx, status, errorReason, now, feedback.first);
+ TString errorReason;
+ NKikimrProto::EReplyStatus status = NKikimrProto::TRYLATER_SIZE;
+ if (feedback.first.Status == NKikimrBlobStorage::TWindowFeedback::IncorrectMsgId) {
+ // special status to distinguish between incorrect message id and queue overflow
+ status = NKikimrProto::TRYLATER;
+ errorReason = "incorrect message id";
+ ++*SkeletonFrontIncorrectMsgId;
+ } else {
+ // overflow
+ errorReason = "queue overflow";
+ ++*SkeletonFrontOverflow;
+ }
+ front.ReplyFunc(std::move(converted), ctx, status, errorReason, now, feedback.first);
}
return converted;
}
@@ -486,52 +486,52 @@ namespace NKikimr {
template <class TFront>
void DeadlineHappened(const TActorContext &ctx, TRecord *rec, TInstant now, TFront &front) {
++*SkeletonFrontDeadline;
- auto feedback = QueueBackpressure->Processed(rec->ActorId, rec->MsgId, rec->Cost, now);
- front.ReplyFunc(std::move(rec->Ev), ctx, NKikimrProto::DEADLINE, "deadline exceeded", now, feedback.first);
+ auto feedback = QueueBackpressure->Processed(rec->ActorId, rec->MsgId, rec->Cost, now);
+ front.ReplyFunc(std::move(rec->Ev), ctx, NKikimrProto::DEADLINE, "deadline exceeded", now, feedback.first);
NotifyOtherClients(ctx, feedback);
}
- template <class TFront>
- void DroppedWithError(const TActorContext &ctx, TRecord *rec, TInstant now, TFront &front) {
- auto feedback = QueueBackpressure->Processed(rec->ActorId, rec->MsgId, rec->Cost, now);
- front.ReplyFunc(std::move(rec->Ev), ctx, NKikimrProto::ERROR, "error state", now, feedback.first);
- }
-
- void DisconnectClients(const TActorContext& ctx, const TActorId& serviceId) {
- auto callback = [&](const auto& winp) {
- ctx.Send(winp->ActorId, new TEvBlobStorage::TEvVWindowChange(ExtQueueId,
- TEvBlobStorage::TEvVWindowChange::DropConnection));
-
- // small hack for older versions of BS_QUEUE that do not support DropConnection flag
- ctx.Send(new IEventHandle(winp->ActorId, serviceId, new TEvents::TEvUndelivered(0,
- TEvents::TEvUndelivered::ReasonActorUnknown)));
- };
- QueueBackpressure->ForEachWindow(callback);
- }
-
- void Completed(const TActorContext &ctx, const TVMsgContext &msgCtx, IEventBase *ev) {
- TInstant now = TAppData::TimeProvider->Now();
- Y_VERIFY(msgCtx.ActorId);
- auto feedback = QueueBackpressure->Processed(msgCtx.ActorId, msgCtx.MsgId, msgCtx.Cost, now);
- NKikimrBlobStorage::TMsgQoS *msgQoS = nullptr;
- switch (ev->Type()) {
-#define UPDATE_WINDOW_STATUS(TYPE) case TYPE::EventType: msgQoS = static_cast<TYPE&>(*ev).Record.MutableMsgQoS(); break;
- // all message types that have MsgQoS structure
+ template <class TFront>
+ void DroppedWithError(const TActorContext &ctx, TRecord *rec, TInstant now, TFront &front) {
+ auto feedback = QueueBackpressure->Processed(rec->ActorId, rec->MsgId, rec->Cost, now);
+ front.ReplyFunc(std::move(rec->Ev), ctx, NKikimrProto::ERROR, "error state", now, feedback.first);
+ }
+
+ void DisconnectClients(const TActorContext& ctx, const TActorId& serviceId) {
+ auto callback = [&](const auto& winp) {
+ ctx.Send(winp->ActorId, new TEvBlobStorage::TEvVWindowChange(ExtQueueId,
+ TEvBlobStorage::TEvVWindowChange::DropConnection));
+
+ // small hack for older versions of BS_QUEUE that do not support DropConnection flag
+ ctx.Send(new IEventHandle(winp->ActorId, serviceId, new TEvents::TEvUndelivered(0,
+ TEvents::TEvUndelivered::ReasonActorUnknown)));
+ };
+ QueueBackpressure->ForEachWindow(callback);
+ }
+
+ void Completed(const TActorContext &ctx, const TVMsgContext &msgCtx, IEventBase *ev) {
+ TInstant now = TAppData::TimeProvider->Now();
+ Y_VERIFY(msgCtx.ActorId);
+ auto feedback = QueueBackpressure->Processed(msgCtx.ActorId, msgCtx.MsgId, msgCtx.Cost, now);
+ NKikimrBlobStorage::TMsgQoS *msgQoS = nullptr;
+ switch (ev->Type()) {
+#define UPDATE_WINDOW_STATUS(TYPE) case TYPE::EventType: msgQoS = static_cast<TYPE&>(*ev).Record.MutableMsgQoS(); break;
+ // all message types that have MsgQoS structure
UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVMovedPatchResult)
UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVPatchFoundParts)
UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVPatchXorDiffResult)
UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVPatchResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVPutResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVMultiPutResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVBlockResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetBlockResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVCollectGarbageResult)
- UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetBarrierResult)
-#undef UPDATE_WINDOW_STATUS
- }
- Y_VERIFY(msgQoS);
- feedback.first.Serialize(*msgQoS->MutableWindow());
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVPutResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVMultiPutResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVBlockResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetBlockResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVCollectGarbageResult)
+ UPDATE_WINDOW_STATUS(TEvBlobStorage::TEvVGetBarrierResult)
+#undef UPDATE_WINDOW_STATUS
+ }
+ Y_VERIFY(msgQoS);
+ feedback.first.Serialize(*msgQoS->MutableWindow());
NotifyOtherClients(ctx, feedback);
}
@@ -579,44 +579,44 @@ namespace NKikimr {
UserData ----------> | | | | ----------> IntPutHugeForeground
GetAsync ----------> | | | | ----------> IntGetAsync
GetFast ----------> | | | | ----------> IntGetFast
- GetDiscover ----------> | | | | ----------> IntGetDiscover
+ GetDiscover ----------> | | | | ----------> IntGetDiscover
GetLow ----------> | | | | ----------> IntLowRead
+--+ +--+
*/
class TSkeletonFront : public TActorBootstrapped<TSkeletonFront> {
friend class TActorBootstrapped<TSkeletonFront>;
- friend class TIntQueueClass;
+ friend class TIntQueueClass;
TVDiskContextPtr VCtx;
TIntrusivePtr<TVDiskConfig> Config;
TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
TVDiskID SelfVDiskId;
TActorId SkeletonId;
TIntrusivePtr<NMonitoring::TDynamicCounters> VDiskCounters;
TIntrusivePtr<NMonitoring::TDynamicCounters> SkeletonFrontGroup;
- NMonitoring::TDynamicCounters::TCounterPtr AccessDeniedMessages;
- std::unique_ptr<TIntQueueClass> IntQueueAsyncGets;
- std::unique_ptr<TIntQueueClass> IntQueueFastGets;
- std::unique_ptr<TIntQueueClass> IntQueueDiscover;
- std::unique_ptr<TIntQueueClass> IntQueueLowGets;
- std::unique_ptr<TIntQueueClass> IntQueueLogPuts;
- std::unique_ptr<TIntQueueClass> IntQueueHugePutsForeground;
- std::unique_ptr<TIntQueueClass> IntQueueHugePutsBackground;
+ NMonitoring::TDynamicCounters::TCounterPtr AccessDeniedMessages;
+ std::unique_ptr<TIntQueueClass> IntQueueAsyncGets;
+ std::unique_ptr<TIntQueueClass> IntQueueFastGets;
+ std::unique_ptr<TIntQueueClass> IntQueueDiscover;
+ std::unique_ptr<TIntQueueClass> IntQueueLowGets;
+ std::unique_ptr<TIntQueueClass> IntQueueLogPuts;
+ std::unique_ptr<TIntQueueClass> IntQueueHugePutsForeground;
+ std::unique_ptr<TIntQueueClass> IntQueueHugePutsBackground;
TExtQueueClass ExtQueueAsyncGets;
TExtQueueClass ExtQueueFastGets;
- TExtQueueClass ExtQueueDiscoverGets;
+ TExtQueueClass ExtQueueDiscoverGets;
TExtQueueClass ExtQueueLowGets;
TExtQueueClass ExtQueueTabletLogPuts;
TExtQueueClass ExtQueueAsyncBlobPuts;
TExtQueueClass ExtQueueUserDataPuts;
- std::unique_ptr<TCostModel> CostModel;
+ std::unique_ptr<TCostModel> CostModel;
TActiveActors ActiveActors;
NMonGroup::TReplGroup ReplMonGroup;
NMonGroup::TSyncerGroup SyncerMonGroup;
NMonGroup::TVDiskStateGroup VDiskMonGroup;
TVDiskIncarnationGuid VDiskIncarnationGuid;
- bool HasUnreadableBlobs = false;
+ bool HasUnreadableBlobs = false;
////////////////////////////////////////////////////////////////////////
// NOTIFICATIONS
@@ -655,50 +655,50 @@ namespace NKikimr {
}
void Bootstrap(const TActorContext &ctx) {
- const auto& baseInfo = Config->BaseInfo;
- VCtx = MakeIntrusive<TVDiskContext>(ctx.SelfID, GInfo->PickTopology(), VDiskCounters, SelfVDiskId,
+ const auto& baseInfo = Config->BaseInfo;
+ VCtx = MakeIntrusive<TVDiskContext>(ctx.SelfID, GInfo->PickTopology(), VDiskCounters, SelfVDiskId,
ctx.ExecutorThread.ActorSystem, baseInfo.DeviceType, baseInfo.DonorMode,
baseInfo.ReplPDiskReadQuoter, baseInfo.ReplPDiskWriteQuoter, baseInfo.ReplNodeRequestQuoter,
- baseInfo.ReplNodeResponseQuoter);
+ baseInfo.ReplNodeResponseQuoter);
// create IntQueues
- IntQueueAsyncGets = std::make_unique<TIntQueueClass>(
+ IntQueueAsyncGets = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntGetAsync,
"AsyncGets",
Config->SkeletonFrontGets_MaxInFlightCount,
Config->SkeletonFrontGets_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueFastGets = std::make_unique<TIntQueueClass>(
+ IntQueueFastGets = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntGetFast,
"FastGets",
Config->SkeletonFrontGets_MaxInFlightCount,
Config->SkeletonFrontGets_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueDiscover = std::make_unique<TIntQueueClass>(
+ IntQueueDiscover = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntGetDiscover,
"DiscoverGets",
Config->SkeletonFrontDiscover_MaxInFlightCount,
Config->SkeletonFrontDiscover_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueLowGets = std::make_unique<TIntQueueClass>(
+ IntQueueLowGets = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntLowRead,
"FastGets",
Config->SkeletonFrontGets_MaxInFlightCount,
Config->SkeletonFrontGets_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueLogPuts = std::make_unique<TIntQueueClass>(
+ IntQueueLogPuts = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntPutLog,
"LogPuts",
Config->SkeletonFrontLogPuts_MaxInFlightCount,
Config->SkeletonFrontLogPuts_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueHugePutsForeground = std::make_unique<TIntQueueClass>(
+ IntQueueHugePutsForeground = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntPutHugeForeground,
"HugePutsForeground",
Config->SkeletonFrontHugePuts_MaxInFlightCount,
Config->SkeletonFrontHugePuts_MaxInFlightCost,
SkeletonFrontGroup);
- IntQueueHugePutsBackground = std::make_unique<TIntQueueClass>(
+ IntQueueHugePutsBackground = std::make_unique<TIntQueueClass>(
NKikimrBlobStorage::EVDiskInternalQueueId::IntPutHugeBackground,
"HugePutsBackground",
Config->SkeletonFrontHugePuts_MaxInFlightCount,
@@ -708,7 +708,7 @@ namespace NKikimr {
UpdateWhiteboard(ctx);
// create and run skeleton
- SkeletonId = ctx.Register(CreateVDiskSkeleton(Config, GInfo, ctx.SelfID, VCtx));
+ SkeletonId = ctx.Register(CreateVDiskSkeleton(Config, GInfo, ctx.SelfID, VCtx));
ActiveActors.Insert(SkeletonId);
SetupMonitoring(ctx);
@@ -727,9 +727,9 @@ namespace NKikimr {
{
Become(&TThis::StateSyncGuidRecoveryInProgress);
TBlobStorageGroupType type = (GInfo ? GInfo->Type : TErasureType::ErasureNone);
- CostModel = std::make_unique<TCostModel>(msg->Dsk->SeekTimeUs, msg->Dsk->ReadSpeedBps,
- msg->Dsk->WriteSpeedBps, msg->Dsk->ReadBlockSize, msg->Dsk->WriteBlockSize,
- msg->HugeBlobCtx->MinREALHugeBlobInBytes, type);
+ CostModel = std::make_unique<TCostModel>(msg->Dsk->SeekTimeUs, msg->Dsk->ReadSpeedBps,
+ msg->Dsk->WriteSpeedBps, msg->Dsk->ReadBlockSize, msg->Dsk->WriteBlockSize,
+ msg->HugeBlobCtx->MinREALHugeBlobInBytes, type);
break;
}
case TEvFrontRecoveryStatus::SyncGuidRecoveryDone:
@@ -898,13 +898,13 @@ namespace NKikimr {
// WHITEBOARD SECTOR
// Update Whiteboard with the current status
////////////////////////////////////////////////////////////////////////
- void UpdateWhiteboard(const TActorContext &ctx, bool schedule = true) {
+ void UpdateWhiteboard(const TActorContext &ctx, bool schedule = true) {
// out of space
const auto outOfSpaceFlags = VCtx->GetOutOfSpaceState().LocalWhiteboardFlag();
// skeleton state
const auto state = VDiskMonGroup.VDiskState();
// replicated?
- bool replicated = !ReplMonGroup.ReplUnreplicatedVDisks() && !HasUnreadableBlobs;
+ bool replicated = !ReplMonGroup.ReplUnreplicatedVDisks() && !HasUnreadableBlobs;
bool unreplicatedPhantoms = ReplMonGroup.ReplCurrentNumUnrecoveredPhantomBlobs() +
ReplMonGroup.ReplNumUnrecoveredPhantomBlobs();
bool unreplicatedNonPhantoms = ReplMonGroup.ReplCurrentNumUnrecoveredNonPhantomBlobs() +
@@ -913,70 +913,70 @@ namespace NKikimr {
ui64 unsyncedVDisks = SyncerMonGroup.SyncerUnsyncedDisks();
// calculate cumulative status of Skeleton Front overload
auto light = NKikimrWhiteboard::EFlag::Green;
- for (auto queue : {IntQueueAsyncGets.get(), IntQueueFastGets.get(), IntQueueDiscover.get(),
- IntQueueLowGets.get(), IntQueueLogPuts.get(), IntQueueHugePutsForeground.get(),
- IntQueueHugePutsBackground.get()}) {
+ for (auto queue : {IntQueueAsyncGets.get(), IntQueueFastGets.get(), IntQueueDiscover.get(),
+ IntQueueLowGets.get(), IntQueueLogPuts.get(), IntQueueHugePutsForeground.get(),
+ IntQueueHugePutsBackground.get()}) {
light = Max(light, queue->GetCumulativeLight());
}
// send a message to Whiteboard
- ctx.Send(SelfId(), new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(state, outOfSpaceFlags,
- replicated, unreplicatedPhantoms, unreplicatedNonPhantoms, unsyncedVDisks, light, HasUnreadableBlobs));
+ ctx.Send(SelfId(), new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate(state, outOfSpaceFlags,
+ replicated, unreplicatedPhantoms, unreplicatedNonPhantoms, unsyncedVDisks, light, HasUnreadableBlobs));
// repeat later
- if (schedule) {
- ctx.Schedule(Config->WhiteboardUpdateInterval, new TEvTimeToUpdateWhiteboard);
- }
+ if (schedule) {
+ ctx.Schedule(Config->WhiteboardUpdateInterval, new TEvTimeToUpdateWhiteboard);
+ }
}
template <class TEventPtr>
inline void CheckEvent(TEventPtr &ev, const char *msgName) {
Y_VERIFY_DEBUG(CostModel);
- Y_VERIFY(ev->Get(), "Incoming message of type %s is null at the VDisk border. This MUST never happens, "
- "check VDisk clients: bufSize# %u", msgName, unsigned(ev->GetSize()));
+ Y_VERIFY(ev->Get(), "Incoming message of type %s is null at the VDisk border. This MUST never happens, "
+ "check VDisk clients: bufSize# %u", msgName, unsigned(ev->GetSize()));
}
template <class TEventPtr>
- void DatabaseAccessDeniedHandle(TEventPtr &ev, const TActorContext &ctx) {
+ void DatabaseAccessDeniedHandle(TEventPtr &ev, const TActorContext &ctx) {
LOG_ERROR_S(ctx, NKikimrServices::BS_SKELETON, VCtx->VDiskLogPrefix
<< "Access denied Type# " << Sprintf("0x%08" PRIx32, ev->GetTypeRewrite())
<< " Sender# " << ev->Sender.ToString()
<< " OriginScopeId# " << ScopeIdToString(ev->OriginScopeId)
<< " LocalScopeId# " << ScopeIdToString(AppData(ctx)->LocalScopeId.GetInterconnectScopeId())
<< " Marker# BSVSF01");
- ++*AccessDeniedMessages;
+ ++*AccessDeniedMessages;
TInstant now = TAppData::TimeProvider->Now();
FillInCostSettingsAndTimestampIfApplicable(ev->Get()->Record, now);
- Reply(ev, ctx, NKikimrProto::ERROR, "access denied", now);
- }
-
- template <class TEventPtr>
+ Reply(ev, ctx, NKikimrProto::ERROR, "access denied", now);
+ }
+
+ template <class TEventPtr>
void DatabaseErrorHandle(TEventPtr &ev, const TActorContext &ctx) {
- SetReceivedTime(ev);
+ SetReceivedTime(ev);
TInstant now = TAppData::TimeProvider->Now();
FillInCostSettingsAndTimestampIfApplicable(ev->Get()->Record, now);
- Reply(ev, ctx, NKikimrProto::VDISK_ERROR_STATE, "VDisk is in error state", now);
+ Reply(ev, ctx, NKikimrProto::VDISK_ERROR_STATE, "VDisk is in error state", now);
// NOTE: VDisk is in StateDatabaseError state, it means recovery failed.
// VDisk returns VDISK_ERROR_STATE status to all requests (outside).
}
template <class TEventPtr>
void DatabaseNotReadyHandle(TEventPtr &ev, const TActorContext &ctx) {
- SetReceivedTime(ev);
+ SetReceivedTime(ev);
TInstant now = TAppData::TimeProvider->Now();
NotifyIfNotReady(ev, ctx);
FillInCostSettingsAndTimestampIfApplicable(ev->Get()->Record, now);
- Reply(ev, ctx, NKikimrProto::NOTREADY, "VDisk is not ready", now);
+ Reply(ev, ctx, NKikimrProto::NOTREADY, "VDisk is not ready", now);
// NOTE: when database is not ready, we reply with NOTREADY and we do not
// pass this message to the Backpressure management subsystem
}
- void DatabaseErrorHandle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("ERROR"));
- }
-
- void DatabaseNotReadyHandle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("NOT_READY"));
- }
+ void DatabaseErrorHandle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("ERROR"));
+ }
+ void DatabaseNotReadyHandle(TEvBlobStorage::TEvMonStreamQuery::TPtr& ev, const TActorContext& ctx) {
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes("NOT_READY"));
+ }
+
////////////////////////////////////////////////////////////////////////////
// HANDLE SECTOR
////////////////////////////////////////////////////////////////////////////
@@ -988,7 +988,7 @@ namespace NKikimr {
struct THasMsgQoS {
static constexpr bool value = false;
};
-
+
template <typename TRecord>
struct THasMsgQoS<TRecord, TRecord> {
static constexpr bool value = true;
@@ -997,15 +997,15 @@ namespace NKikimr {
return r.MutableMsgQoS();
}
};
-
+
template<typename TRecord>
void FillInCostSettingsAndTimestampIfApplicable(TRecord& record, TInstant now) const
{
if constexpr (THasMsgQoS<TRecord>::value) {
FillInCostSettingsAndTimestampIfRequired(record.MutableMsgQoS(), now);
}
- }
-
+ }
+
void FillInCostSettingsAndTimestampIfRequired(NKikimrBlobStorage::TMsgQoS *qos, TInstant now) const {
qos->MutableExecTimeStats()->SetReceivedTimestamp(now.GetValue());
if (qos->GetSendMeCostSettings() && CostModel) {
@@ -1014,23 +1014,23 @@ namespace NKikimr {
}
template <class TEventPtr>
- void HandleRequestWithQoS(const TActorContext &ctx, TEventPtr &ev, const char *msgName, ui64 cost,
+ void HandleRequestWithQoS(const TActorContext &ctx, TEventPtr &ev, const char *msgName, ui64 cost,
TIntQueueClass &intQueue) {
CheckEvent(ev, msgName);
const ui32 recByteSize = ev->Get()->GetCachedByteSize();
auto &record = ev->Get()->Record;
auto &msgQoS = *record.MutableMsgQoS();
-
- // set up reception time
- TInstant now = TAppData::TimeProvider->Now();
-
- const NBackpressure::TMessageId msgId(msgQoS.GetMsgId());
- const TInstant deadline = CalcDeadline(msgQoS.GetDeadlineSeconds());
- auto extQueueId = msgQoS.GetExtQueueId();
+
+ // set up reception time
+ TInstant now = TAppData::TimeProvider->Now();
+
+ const NBackpressure::TMessageId msgId(msgQoS.GetMsgId());
+ const TInstant deadline = CalcDeadline(msgQoS.GetDeadlineSeconds());
+ auto extQueueId = msgQoS.GetExtQueueId();
auto intQueueId = intQueue.IntQueueId;
- msgQoS.SetCost(cost);
- msgQoS.SetIntQueueId(intQueueId);
- ActorIdToProto(ev->Sender, msgQoS.MutableSenderActorId());
+ msgQoS.SetCost(cost);
+ msgQoS.SetIntQueueId(intQueueId);
+ ActorIdToProto(ev->Sender, msgQoS.MutableSenderActorId());
FillInCostSettingsAndTimestampIfRequired(&msgQoS, now);
// check queue compatibility: it's a contract between BlobStorage Proxy and VDisk,
@@ -1042,12 +1042,12 @@ namespace NKikimr {
NKikimrBlobStorage::EVDiskQueueId_Name(extQueueId).data());
TExtQueueClass &extQueue = GetExtQueue(extQueueId);
- NBackpressure::TQueueClientId clientId(msgQoS);
- std::unique_ptr<IEventHandle> event = extQueue.Enqueue(ctx, std::unique_ptr<IEventHandle>(
- ev->Forward(SkeletonId).Release()), msgId, cost, *this, clientId);
+ NBackpressure::TQueueClientId clientId(msgQoS);
+ std::unique_ptr<IEventHandle> event = extQueue.Enqueue(ctx, std::unique_ptr<IEventHandle>(
+ ev->Forward(SkeletonId).Release()), msgId, cost, *this, clientId);
if (event) {
// good, enqueue it in intQueue
- intQueue.Enqueue(ctx, recByteSize, std::move(event), msgId, cost, deadline, extQueueId, *this, clientId);
+ intQueue.Enqueue(ctx, recByteSize, std::move(event), msgId, cost, deadline, extQueueId, *this, clientId);
}
}
@@ -1059,7 +1059,7 @@ namespace NKikimr {
// IPL = IntPutLog
// IPHF = IntPutHugeForeground
// IPHB = IntPutHugeBackground
- // ID = IntDiscover
+ // ID = IntDiscover
// IL = IntLowRead
static bool compatibilityMatrix[8][8] = {
// IU IAG IFG IPL IPHF IPHB ID IL
@@ -1096,7 +1096,7 @@ namespace NKikimr {
}
const char* name = "Unknown";
- TIntQueueClass *queue = IntQueueHugePutsBackground.get();
+ TIntQueueClass *queue = IntQueueHugePutsBackground.get();
if constexpr (std::is_same_v<TEvPtr, TEvBlobStorage::TEvVMovedPatch::TPtr>) {
LWTRACK(VDiskSkeletonFrontVMovedPatchRecieved, ev->Get()->Orbit, VCtx->NodeId, VCtx->GroupId,
VCtx->Top->GetFailDomainOrderNumber(VCtx->ShortSelfVDisk), blob.TabletID(), blob.BlobSize());
@@ -1104,7 +1104,7 @@ namespace NKikimr {
} else if constexpr (std::is_same_v<TEvPtr, TEvBlobStorage::TEvVPatchStart::TPtr>) {
LWTRACK(VDiskSkeletonFrontVPatchStartRecieved, ev->Get()->Orbit, VCtx->NodeId, VCtx->GroupId,
VCtx->Top->GetFailDomainOrderNumber(VCtx->ShortSelfVDisk), blob.TabletID(), blob.BlobSize());
- queue = IntQueueFastGets.get();
+ queue = IntQueueFastGets.get();
name = "TEvVPatchStart";
} else if constexpr (std::is_same_v<TEvPtr, TEvBlobStorage::TEvVPatchDiff::TPtr>) {
LWTRACK(VDiskSkeletonFrontVPatchDiffRecieved, ev->Get()->Orbit, VCtx->NodeId, VCtx->GroupId,
@@ -1188,9 +1188,9 @@ namespace NKikimr {
case NKikimrBlobStorage::EGetHandleClass::FastRead:
intQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntGetFast;
break;
- case NKikimrBlobStorage::EGetHandleClass::Discover:
- intQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntGetDiscover;
- break;
+ case NKikimrBlobStorage::EGetHandleClass::Discover:
+ intQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntGetDiscover;
+ break;
case NKikimrBlobStorage::EGetHandleClass::LowRead:
intQueueId = NKikimrBlobStorage::EVDiskInternalQueueId::IntLowRead;
break;
@@ -1221,48 +1221,48 @@ namespace NKikimr {
HandleRequestWithQoS(ctx, ev, "TEvVGetBarrier", cost, *IntQueueFastGets);
}
- template<typename TEventPtr>
- void HandleRequestWithoutQoS(TEventPtr& ev, const TActorContext& ctx) {
- // we just forward this message to skeleton
+ template<typename TEventPtr>
+ void HandleRequestWithoutQoS(TEventPtr& ev, const TActorContext& ctx) {
+ // we just forward this message to skeleton
ctx.Send(ev->Forward(SkeletonId));
}
- void HandleCheckReadiness(TEvBlobStorage::TEvVCheckReadiness::TPtr& ev, const TActorContext& ctx) {
- if (GInfo->CheckScope(TKikimrScopeId(ev->OriginScopeId), ctx, true)) {
- const auto& record = ev->Get()->Record;
- if (record.HasVDiskID()) {
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
- Y_VERIFY(vdiskId.GroupID == SelfVDiskId.GroupID);
- Y_VERIFY(TVDiskIdShort(vdiskId) == TVDiskIdShort(SelfVDiskId));
- if (vdiskId != SelfVDiskId) {
- if (SelfVDiskId.GroupGeneration < vdiskId.GroupGeneration && record.HasRecentGroup()) {
- auto newInfo = TBlobStorageGroupInfo::Parse(record.GetRecentGroup(), nullptr, nullptr);
- ChangeGeneration(vdiskId, newInfo, ctx);
- Y_VERIFY(vdiskId == SelfVDiskId);
- const ui32 groupId = newInfo->GroupID;
- const ui32 generation = newInfo->GroupGeneration;
- auto ev = std::make_unique<TEvBlobStorage::TEvUpdateGroupInfo>(groupId, generation, *newInfo->Group);
- Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), ev.release());
- } else {
- return Reply(ev, ctx, NKikimrProto::RACE, "group generation mismatch", TAppData::TimeProvider->Now());
- }
- }
- }
- std::optional<NBackpressure::TMessageId> expectedMsgId;
- if (record.HasQoS()) {
- const auto& qos = record.GetQoS();
- Y_VERIFY_DEBUG(qos.HasExtQueueId());
- if (qos.HasExtQueueId()) {
- auto& queue = GetExtQueue(qos.GetExtQueueId());
- expectedMsgId = queue.GetExpectedMsgId(ev->Sender);
- }
- }
- Reply(ev, ctx, NKikimrProto::OK, TString(), TAppData::TimeProvider->Now(), expectedMsgId);
- } else {
- Reply(ev, ctx, NKikimrProto::ERROR, "access denied", TAppData::TimeProvider->Now());
- }
- }
-
+ void HandleCheckReadiness(TEvBlobStorage::TEvVCheckReadiness::TPtr& ev, const TActorContext& ctx) {
+ if (GInfo->CheckScope(TKikimrScopeId(ev->OriginScopeId), ctx, true)) {
+ const auto& record = ev->Get()->Record;
+ if (record.HasVDiskID()) {
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(record.GetVDiskID());
+ Y_VERIFY(vdiskId.GroupID == SelfVDiskId.GroupID);
+ Y_VERIFY(TVDiskIdShort(vdiskId) == TVDiskIdShort(SelfVDiskId));
+ if (vdiskId != SelfVDiskId) {
+ if (SelfVDiskId.GroupGeneration < vdiskId.GroupGeneration && record.HasRecentGroup()) {
+ auto newInfo = TBlobStorageGroupInfo::Parse(record.GetRecentGroup(), nullptr, nullptr);
+ ChangeGeneration(vdiskId, newInfo, ctx);
+ Y_VERIFY(vdiskId == SelfVDiskId);
+ const ui32 groupId = newInfo->GroupID;
+ const ui32 generation = newInfo->GroupGeneration;
+ auto ev = std::make_unique<TEvBlobStorage::TEvUpdateGroupInfo>(groupId, generation, *newInfo->Group);
+ Send(MakeBlobStorageNodeWardenID(SelfId().NodeId()), ev.release());
+ } else {
+ return Reply(ev, ctx, NKikimrProto::RACE, "group generation mismatch", TAppData::TimeProvider->Now());
+ }
+ }
+ }
+ std::optional<NBackpressure::TMessageId> expectedMsgId;
+ if (record.HasQoS()) {
+ const auto& qos = record.GetQoS();
+ Y_VERIFY_DEBUG(qos.HasExtQueueId());
+ if (qos.HasExtQueueId()) {
+ auto& queue = GetExtQueue(qos.GetExtQueueId());
+ expectedMsgId = queue.GetExpectedMsgId(ev->Sender);
+ }
+ }
+ Reply(ev, ctx, NKikimrProto::OK, TString(), TAppData::TimeProvider->Now(), expectedMsgId);
+ } else {
+ Reply(ev, ctx, NKikimrProto::ERROR, "access denied", TAppData::TimeProvider->Now());
+ }
+ }
+
////////////////////////////////////////////////////////////////////////////
// Set receiving time
@@ -1286,39 +1286,39 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// REPLY SECTOR
////////////////////////////////////////////////////////////////////////////
- template<typename TPtr>
- void Reply(TPtr& ev, const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
- TInstant now, const TWindowStatus& wstatus) {
- wstatus.Serialize(*ev->Get()->Record.MutableMsgQoS()->MutableWindow());
- Reply(ev, ctx, status, errorReason, now);
- }
-
- template<typename TPtr>
- void Reply(TPtr& ev, const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
- TInstant now) {
- using namespace NErrBuilder;
- auto res = ErroneousResult(VCtx, status, errorReason, ev, now, nullptr, SelfVDiskId, VDiskIncarnationGuid, GInfo);
- SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ template<typename TPtr>
+ void Reply(TPtr& ev, const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TInstant now, const TWindowStatus& wstatus) {
+ wstatus.Serialize(*ev->Get()->Record.MutableMsgQoS()->MutableWindow());
+ Reply(ev, ctx, status, errorReason, now);
}
+ template<typename TPtr>
+ void Reply(TPtr& ev, const TActorContext& ctx, NKikimrProto::EReplyStatus status, const TString& errorReason,
+ TInstant now) {
+ using namespace NErrBuilder;
+ auto res = ErroneousResult(VCtx, status, errorReason, ev, now, nullptr, SelfVDiskId, VDiskIncarnationGuid, GInfo);
+ SendVDiskResponse(ctx, ev->Sender, res.release(), *this, ev->Cookie);
+ }
+
void Reply(TEvBlobStorage::TEvVCheckReadiness::TPtr &ev, const TActorContext &ctx,
- NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/,
- const std::optional<NBackpressure::TMessageId>& expectedMsgId = std::nullopt) {
- const ui32 flags = IEventHandle::MakeFlags(ev->GetChannel(), 0);
- auto res = std::make_unique<TEvBlobStorage::TEvVCheckReadinessResult>(status);
- auto& record = res->Record;
- SetRacingGroupInfo(ev->Get()->Record, record, GInfo);
- if (expectedMsgId) {
- expectedMsgId->Serialize(*record.MutableExpectedMsgId());
- }
- if (CostModel && status == NKikimrProto::OK) {
- CostModel->FillInSettings(*record.MutableCostSettings());
- }
- ctx.Send(ev->Sender, res.release(), flags, ev->Cookie);
- }
-
+ NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/,
+ const std::optional<NBackpressure::TMessageId>& expectedMsgId = std::nullopt) {
+ const ui32 flags = IEventHandle::MakeFlags(ev->GetChannel(), 0);
+ auto res = std::make_unique<TEvBlobStorage::TEvVCheckReadinessResult>(status);
+ auto& record = res->Record;
+ SetRacingGroupInfo(ev->Get()->Record, record, GInfo);
+ if (expectedMsgId) {
+ expectedMsgId->Serialize(*record.MutableExpectedMsgId());
+ }
+ if (CostModel && status == NKikimrProto::OK) {
+ CostModel->FillInSettings(*record.MutableCostSettings());
+ }
+ ctx.Send(ev->Sender, res.release(), flags, ev->Cookie);
+ }
+
void Reply(TEvBlobStorage::TEvVCompact::TPtr &ev, const TActorContext &ctx,
- NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
+ NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
const ui32 flags = IEventHandle::MakeFlags(ev->GetChannel(), 0);
ctx.Send(ev->Sender, new TEvBlobStorage::TEvVCompactResult(status, ev->Get()->Record.GetVDiskID()),
flags, ev->Cookie);
@@ -1332,14 +1332,14 @@ namespace NKikimr {
}
void Reply(TEvBlobStorage::TEvVBaldSyncLog::TPtr &ev, const TActorContext &ctx,
- NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
+ NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
const ui32 flags = IEventHandle::MakeFlags(ev->GetChannel(), 0);
ctx.Send(ev->Sender, new TEvBlobStorage::TEvVBaldSyncLogResult(status, ev->Get()->Record.GetVDiskID()),
flags, ev->Cookie);
}
void Reply(TEvBlobStorage::TEvVStatus::TPtr &ev, const TActorContext &ctx,
- NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
+ NKikimrProto::EReplyStatus status, const TString& /*errorReason*/, TInstant /*now*/) {
const ui32 flags = IEventHandle::MakeFlags(ev->GetChannel(), 0);
ctx.Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(status, ev->Get()->Record.GetVDiskID()),
flags, ev->Cookie);
@@ -1355,64 +1355,64 @@ namespace NKikimr {
const TCgiParameters& cgi = ev->Get()->Request.GetParams();
const TString& type = cgi.Get("type");
TString html = (type == TString()) ? GenerateHtmlState(ctx) : TString();
- auto aid = ctx.Register(CreateFrontSkeletonMonRequestHandler(SelfVDiskId, ctx.SelfID, SkeletonId,
- ctx.SelfID, Config, Top, ev, html));
+ auto aid = ctx.Register(CreateFrontSkeletonMonRequestHandler(SelfVDiskId, ctx.SelfID, SkeletonId,
+ ctx.SelfID, Config, Top, ev, html));
ActiveActors.Insert(aid);
}
void Handle(TEvVDiskRequestCompleted::TPtr &ev, const TActorContext &ctx) {
const TVMsgContext &msgCtx = ev->Get()->Ctx;
- std::unique_ptr<IEventHandle> event = std::move(ev->Get()->Event);
+ std::unique_ptr<IEventHandle> event = std::move(ev->Get()->Event);
TExtQueueClass &extQueue = GetExtQueue(msgCtx.ExtQueueId);
- extQueue.Completed(ctx, msgCtx, event->GetBase());
+ extQueue.Completed(ctx, msgCtx, event->GetBase());
TIntQueueClass &intQueue = GetIntQueue(msgCtx.IntQueueId);
intQueue.Completed(ctx, msgCtx, *this);
- TActivationContext::Send(event.release());
+ TActivationContext::Send(event.release());
}
- void ChangeGeneration(const TVDiskID& vdiskId, const TIntrusivePtr<TBlobStorageGroupInfo>& info,
- const TActorContext& ctx) {
- // check group id
- Y_VERIFY(info->GroupID == GInfo->GroupID, "GroupId# %" PRIu32 " new GroupId# %" PRIu32,
- GInfo->GroupID, info->GroupID);
-
- // check target disk id
- Y_VERIFY(TVDiskIdShort(SelfVDiskId) == TVDiskIdShort(vdiskId), "Incorrect target VDiskId"
- " SelfVDiskId# %s new VDiskId# %s", SelfVDiskId.ToString().data(), vdiskId.ToString().data());
-
- // check the disk location inside group
- Y_VERIFY(info->GetVDiskId(TVDiskIdShort(vdiskId)) == vdiskId);
-
- // check that NewInfo has the same topology as the one VDisk started with
- Y_VERIFY(VCtx->Top->EqualityCheck(info->GetTopology()));
-
- // check generation for possible race
- if (info->GroupGeneration <= GInfo->GroupGeneration) {
- // its just a race -- we already have newer group generation
- return;
- }
-
- // all checks passed
+ void ChangeGeneration(const TVDiskID& vdiskId, const TIntrusivePtr<TBlobStorageGroupInfo>& info,
+ const TActorContext& ctx) {
+ // check group id
+ Y_VERIFY(info->GroupID == GInfo->GroupID, "GroupId# %" PRIu32 " new GroupId# %" PRIu32,
+ GInfo->GroupID, info->GroupID);
+
+ // check target disk id
+ Y_VERIFY(TVDiskIdShort(SelfVDiskId) == TVDiskIdShort(vdiskId), "Incorrect target VDiskId"
+ " SelfVDiskId# %s new VDiskId# %s", SelfVDiskId.ToString().data(), vdiskId.ToString().data());
+
+ // check the disk location inside group
+ Y_VERIFY(info->GetVDiskId(TVDiskIdShort(vdiskId)) == vdiskId);
+
+ // check that NewInfo has the same topology as the one VDisk started with
+ Y_VERIFY(VCtx->Top->EqualityCheck(info->GetTopology()));
+
+ // check generation for possible race
+ if (info->GroupGeneration <= GInfo->GroupGeneration) {
+ // its just a race -- we already have newer group generation
+ return;
+ }
+
+ // all checks passed
LOG_INFO_S(ctx, BS_SKELETON, VCtx->VDiskLogPrefix << "VDisk Generation Change success;"
<< " new VDiskId# " << vdiskId
<< " Marker# BSVSF02");
-
- // update GroupInfo-related fields
- GInfo = info;
- const auto& prevVDiskId = std::exchange(SelfVDiskId, vdiskId);
-
- // forward message to Skeleton
- ctx.Send(SkeletonId, new TEvVGenerationChange(vdiskId, info));
-
- // notify whiteboard
- Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()),
- new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateGenerationChange(prevVDiskId,
- SelfVDiskId.GroupGeneration, Config->BaseInfo.WhiteboardInstanceGuid));
- }
-
+
+ // update GroupInfo-related fields
+ GInfo = info;
+ const auto& prevVDiskId = std::exchange(SelfVDiskId, vdiskId);
+
+ // forward message to Skeleton
+ ctx.Send(SkeletonId, new TEvVGenerationChange(vdiskId, info));
+
+ // notify whiteboard
+ Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId()),
+ new NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateGenerationChange(prevVDiskId,
+ SelfVDiskId.GroupGeneration, Config->BaseInfo.WhiteboardInstanceGuid));
+ }
+
void Handle(TEvVGenerationChange::TPtr &ev, const TActorContext &ctx) {
auto *msg = ev->Get();
- ChangeGeneration(msg->NewVDiskId, msg->NewInfo, ctx);
+ ChangeGeneration(msg->NewVDiskId, msg->NewInfo, ctx);
}
void Handle(TEvPDiskErrorStateChange::TPtr &ev, const TActorContext &ctx) {
@@ -1430,27 +1430,27 @@ namespace NKikimr {
SkeletonId = {};
// go to error state
Become(&TThis::StateDatabaseError);
- // update status in NodeWarden
- const TActorId& warden = MakeBlobStorageNodeWardenID(SelfId().NodeId());
- const auto& base = Config->BaseInfo;
- ctx.Send(warden, new TEvStatusUpdate(ctx.SelfID.NodeId(), base.PDiskId, base.VDiskSlotId, NKikimrBlobStorage::EVDiskStatus::ERROR));
- // drop messages in internal queues
- for (auto *q : {&IntQueueAsyncGets, &IntQueueFastGets, &IntQueueDiscover, &IntQueueLowGets, &IntQueueLogPuts,
- &IntQueueHugePutsForeground, &IntQueueHugePutsBackground}) {
- (*q)->DropWithError(ctx, *this);
+ // update status in NodeWarden
+ const TActorId& warden = MakeBlobStorageNodeWardenID(SelfId().NodeId());
+ const auto& base = Config->BaseInfo;
+ ctx.Send(warden, new TEvStatusUpdate(ctx.SelfID.NodeId(), base.PDiskId, base.VDiskSlotId, NKikimrBlobStorage::EVDiskStatus::ERROR));
+ // drop messages in internal queues
+ for (auto *q : {&IntQueueAsyncGets, &IntQueueFastGets, &IntQueueDiscover, &IntQueueLowGets, &IntQueueLogPuts,
+ &IntQueueHugePutsForeground, &IntQueueHugePutsBackground}) {
+ (*q)->DropWithError(ctx, *this);
}
- // drop external queues
- DisconnectClients(ctx);
+ // drop external queues
+ DisconnectClients(ctx);
}
- void DisconnectClients(const TActorContext& ctx) {
- const auto& base = Config->BaseInfo;
- const TActorId& serviceId = MakeBlobStorageVDiskID(SelfId().NodeId(), base.PDiskId, base.VDiskSlotId);
- for (auto *q : {&ExtQueueAsyncGets, &ExtQueueFastGets, &ExtQueueDiscoverGets, &ExtQueueLowGets,
- &ExtQueueTabletLogPuts, &ExtQueueAsyncBlobPuts, &ExtQueueUserDataPuts}) {
- q->DisconnectClients(ctx, serviceId);
- }
- }
+ void DisconnectClients(const TActorContext& ctx) {
+ const auto& base = Config->BaseInfo;
+ const TActorId& serviceId = MakeBlobStorageVDiskID(SelfId().NodeId(), base.PDiskId, base.VDiskSlotId);
+ for (auto *q : {&ExtQueueAsyncGets, &ExtQueueFastGets, &ExtQueueDiscoverGets, &ExtQueueLowGets,
+ &ExtQueueTabletLogPuts, &ExtQueueAsyncBlobPuts, &ExtQueueUserDataPuts}) {
+ q->DisconnectClients(ctx, serviceId);
+ }
+ }
public:
TExtQueueClass &GetExtQueue(NKikimrBlobStorage::EVDiskQueueId extQueueId) {
@@ -1471,13 +1471,13 @@ namespace NKikimr {
case NKikimrBlobStorage::EVDiskQueueId::GetFastRead:
extQueue = &ExtQueueFastGets;
break;
- case NKikimrBlobStorage::EVDiskQueueId::GetDiscover:
- extQueue = &ExtQueueDiscoverGets;
- break;
+ case NKikimrBlobStorage::EVDiskQueueId::GetDiscover:
+ extQueue = &ExtQueueDiscoverGets;
+ break;
case NKikimrBlobStorage::EVDiskQueueId::GetLowRead:
extQueue = &ExtQueueLowGets;
break;
- default: Y_FAIL("Unexpected case extQueueId# %" PRIu32, static_cast<ui32>(extQueueId));
+ default: Y_FAIL("Unexpected case extQueueId# %" PRIu32, static_cast<ui32>(extQueueId));
}
return *extQueue;
}
@@ -1486,25 +1486,25 @@ namespace NKikimr {
TIntQueueClass *intQueue = nullptr;
switch (intQueueId) {
case NKikimrBlobStorage::EVDiskInternalQueueId::IntGetAsync:
- intQueue = IntQueueAsyncGets.get();
+ intQueue = IntQueueAsyncGets.get();
break;
case NKikimrBlobStorage::EVDiskInternalQueueId::IntGetFast:
- intQueue = IntQueueFastGets.get();
- break;
- case NKikimrBlobStorage::EVDiskInternalQueueId::IntGetDiscover:
- intQueue = IntQueueDiscover.get();
+ intQueue = IntQueueFastGets.get();
break;
+ case NKikimrBlobStorage::EVDiskInternalQueueId::IntGetDiscover:
+ intQueue = IntQueueDiscover.get();
+ break;
case NKikimrBlobStorage::EVDiskInternalQueueId::IntLowRead:
- intQueue = IntQueueLowGets.get();
+ intQueue = IntQueueLowGets.get();
break;
case NKikimrBlobStorage::EVDiskInternalQueueId::IntPutLog:
- intQueue = IntQueueLogPuts.get();
+ intQueue = IntQueueLogPuts.get();
break;
case NKikimrBlobStorage::EVDiskInternalQueueId::IntPutHugeForeground:
- intQueue = IntQueueHugePutsForeground.get();
+ intQueue = IntQueueHugePutsForeground.get();
break;
case NKikimrBlobStorage::EVDiskInternalQueueId::IntPutHugeBackground:
- intQueue = IntQueueHugePutsBackground.get();
+ intQueue = IntQueueHugePutsBackground.get();
break;
default: Y_FAIL("Unexpected case");
}
@@ -1512,9 +1512,9 @@ namespace NKikimr {
}
private:
- void Die(const TActorContext &ctx) override {
+ void Die(const TActorContext &ctx) override {
ActiveActors.KillAndClear(ctx);
- TActorBootstrapped::Die(ctx);
+ TActorBootstrapped::Die(ctx);
}
void Handle(TEvents::TEvActorDied::TPtr &ev, const TActorContext &ctx) {
@@ -1522,160 +1522,160 @@ namespace NKikimr {
ActiveActors.Erase(ev->Sender);
}
- void HandleCommenceRepl(const TActorContext& /*ctx*/) {
- TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, SkeletonId, SelfId(), nullptr, 0));
- }
-
- void Handle(TEvReportScrubStatus::TPtr ev, const TActorContext& ctx) {
- HasUnreadableBlobs = ev->Get()->HasUnreadableBlobs;
- UpdateWhiteboard(ctx, false);
- }
-
- void Handle(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate::TPtr ev, const TActorContext& ctx) {
- auto& record = ev->Get()->Record;
- VDiskIDFromVDiskID(SelfVDiskId, record.MutableVDiskId());
- record.SetInstanceGuid(Config->BaseInfo.WhiteboardInstanceGuid);
- ctx.Send(ev->Forward(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId())));
- }
-
+ void HandleCommenceRepl(const TActorContext& /*ctx*/) {
+ TActivationContext::Send(new IEventHandle(TEvBlobStorage::EvCommenceRepl, 0, SkeletonId, SelfId(), nullptr, 0));
+ }
+
+ void Handle(TEvReportScrubStatus::TPtr ev, const TActorContext& ctx) {
+ HasUnreadableBlobs = ev->Get()->HasUnreadableBlobs;
+ UpdateWhiteboard(ctx, false);
+ }
+
+ void Handle(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate::TPtr ev, const TActorContext& ctx) {
+ auto& record = ev->Get()->Record;
+ VDiskIDFromVDiskID(SelfVDiskId, record.MutableVDiskId());
+ record.SetInstanceGuid(Config->BaseInfo.WhiteboardInstanceGuid);
+ ctx.Send(ev->Forward(NNodeWhiteboard::MakeNodeWhiteboardServiceId(SelfId().NodeId())));
+ }
+
// while local db recovery is in progress, we use this state function to handle requests
- STRICT_STFUNC(StateLocalRecoveryInProgress,
+ STRICT_STFUNC(StateLocalRecoveryInProgress,
HFunc(TEvBlobStorage::TEvVMovedPatch, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchStart, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchDiff, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchXorDiff, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVPut, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVPut, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVMultiPut, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGet, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVBlock, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVStatus, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVDbStat, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVSync, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVSyncGuid, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGet, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVBlock, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVStatus, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVDbStat, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVSync, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVSyncGuid, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVDefrag, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, DatabaseNotReadyHandle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvPDiskErrorStateChange, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvFrontRecoveryStatus, Handle)
- HFunc(TEvVDiskRequestCompleted, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvFrontRecoveryStatus, Handle)
+ HFunc(TEvVDiskRequestCompleted, Handle)
CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
- HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
- FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
- )
+ CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
+ HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
+ FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
+ )
// while recovering sync guid we use this state function to handle requests
- STRICT_STFUNC(StateSyncGuidRecoveryInProgress,
+ STRICT_STFUNC(StateSyncGuidRecoveryInProgress,
HFunc(TEvBlobStorage::TEvVMovedPatch, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchStart, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchDiff, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVPatchXorDiff, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVPut, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVPut, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVMultiPut, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGet, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVBlock, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVStatus, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVDbStat, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVSync, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseNotReadyHandle)
- // NOTE: Below is the only diff from StateLocalRecoveryInProgress --
- // we handle TEvBlobStorage::TEvVSyncGuid
- HFunc(TEvBlobStorage::TEvVSyncGuid, HandleRequestWithoutQoS)
- HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseNotReadyHandle)
- HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGet, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVBlock, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVStatus, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVDbStat, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVSync, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseNotReadyHandle)
+ // NOTE: Below is the only diff from StateLocalRecoveryInProgress --
+ // we handle TEvBlobStorage::TEvVSyncGuid
+ HFunc(TEvBlobStorage::TEvVSyncGuid, HandleRequestWithoutQoS)
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVDefrag, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, DatabaseNotReadyHandle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvPDiskErrorStateChange, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvFrontRecoveryStatus, Handle)
- HFunc(TEvVDiskRequestCompleted, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvFrontRecoveryStatus, Handle)
+ HFunc(TEvVDiskRequestCompleted, Handle)
CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
- HFunc(TEvReportScrubStatus, Handle)
- HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
- FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
- )
-
- STRICT_STFUNC(StateDatabaseError,
+ CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
+ HFunc(TEvReportScrubStatus, Handle)
+ HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
+ FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
+ )
+
+ STRICT_STFUNC(StateDatabaseError,
HFunc(TEvBlobStorage::TEvVMovedPatch, DatabaseErrorHandle)
HFunc(TEvBlobStorage::TEvVPatchStart, DatabaseErrorHandle)
HFunc(TEvBlobStorage::TEvVPatchDiff, DatabaseErrorHandle)
HFunc(TEvBlobStorage::TEvVPatchXorDiff, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVPut, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVPut, DatabaseErrorHandle)
HFunc(TEvBlobStorage::TEvVMultiPut, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVGet, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVBlock, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVStatus, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVDbStat, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVSync, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVSyncGuid, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseErrorHandle)
- HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
+ HFunc(TEvBlobStorage::TEvVGet, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVBlock, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVGetBlock, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVGetBarrier, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVStatus, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVDbStat, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVSync, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVSyncFull, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVSyncGuid, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, DatabaseErrorHandle)
+ HFunc(TEvBlobStorage::TEvVCompact, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVDefrag, DatabaseNotReadyHandle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, DatabaseNotReadyHandle)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvPDiskErrorStateChange, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
- HFunc(TEvReportScrubStatus, Handle)
- IgnoreFunc(TEvVDiskRequestCompleted)
- HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
- FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
- )
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Events checking: RACE and access control
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+ CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
+ HFunc(TEvReportScrubStatus, Handle)
+ IgnoreFunc(TEvVDiskRequestCompleted)
+ HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
+ FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
+ )
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Events checking: RACE and access control
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
template <typename TEv>
static constexpr bool IsPatchEvent = std::is_same_v<TEv, TEvBlobStorage::TEvVMovedPatch>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVPatchStart>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVPatchDiff>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVPatchXorDiff>;
-
+
template <typename TEv>
static constexpr bool IsWithoutQoS = std::is_same_v<TEv, TEvBlobStorage::TEvVStatus>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVDbStat>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVCompact>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVDefrag>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVBaldSyncLog>;
-
+
template <typename TEv>
static constexpr bool IsValidatable = std::is_same_v<TEv, TEvBlobStorage::TEvVMultiPut>
|| std::is_same_v<TEv, TEvBlobStorage::TEvVGet>
@@ -1690,8 +1690,8 @@ namespace NKikimr {
} else {
Handle(ev, ctx);
}
- }
-
+ }
+
template <typename TEv>
bool Validate(TEv* ev, TString& errorReason) const {
if constexpr (IsValidatable<TEv>) {
@@ -1699,20 +1699,20 @@ namespace NKikimr {
}
return true;
}
-
+
template <typename TEventType>
void Check(TAutoPtr<TEventHandle<TEventType>>& ev, const TActorContext& ctx) {
- const auto& record = ev->Get()->Record;
- if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
- return Reply(ev, ctx, NKikimrProto::RACE, "group generation mismatch", TAppData::TimeProvider->Now());
- } else if (!GInfo->CheckScope(TKikimrScopeId(ev->OriginScopeId), ctx, true)) {
- DatabaseAccessDeniedHandle(ev, ctx);
- } else {
- SetReceivedTime(ev);
- CheckExecute(ev, ctx);
- }
- }
-
+ const auto& record = ev->Get()->Record;
+ if (!SelfVDiskId.SameDisk(record.GetVDiskID())) {
+ return Reply(ev, ctx, NKikimrProto::RACE, "group generation mismatch", TAppData::TimeProvider->Now());
+ } else if (!GInfo->CheckScope(TKikimrScopeId(ev->OriginScopeId), ctx, true)) {
+ DatabaseAccessDeniedHandle(ev, ctx);
+ } else {
+ SetReceivedTime(ev);
+ CheckExecute(ev, ctx);
+ }
+ }
+
template<typename TEv>
void ValidateEvent(TAutoPtr<TEventHandle<TEv>>& ev, const TActorContext& ctx) {
TString errorReason;
@@ -1724,16 +1724,16 @@ namespace NKikimr {
Check(ev, ctx);
};
- void ForwardToSkeleton(STFUNC_SIG) {
- ctx.Send(ev->Forward(SkeletonId));
- }
-
- void HandleForwardToSkeleton(STFUNC_SIG) {
- ev->Rewrite(ev->Type, SkeletonId);
- ctx.Send(ev);
- }
-
- STRICT_STFUNC(StateFunc,
+ void ForwardToSkeleton(STFUNC_SIG) {
+ ctx.Send(ev->Forward(SkeletonId));
+ }
+
+ void HandleForwardToSkeleton(STFUNC_SIG) {
+ ev->Rewrite(ev->Type, SkeletonId);
+ ctx.Send(ev);
+ }
+
+ STRICT_STFUNC(StateFunc,
HFunc(TEvBlobStorage::TEvVMovedPatch, Check)
HFunc(TEvBlobStorage::TEvVPatchStart, Check)
HFunc(TEvBlobStorage::TEvVPatchDiff, Check)
@@ -1741,69 +1741,69 @@ namespace NKikimr {
HFunc(TEvBlobStorage::TEvVPut, ValidateEvent)
HFunc(TEvBlobStorage::TEvVMultiPut, ValidateEvent)
HFunc(TEvBlobStorage::TEvVGet, ValidateEvent)
- HFunc(TEvBlobStorage::TEvVBlock, Check)
- HFunc(TEvBlobStorage::TEvVGetBlock, Check)
- HFunc(TEvBlobStorage::TEvVCollectGarbage, Check)
- HFunc(TEvBlobStorage::TEvVGetBarrier, Check)
- HFunc(TEvBlobStorage::TEvVStatus, Check)
- HFunc(TEvBlobStorage::TEvVDbStat, Check)
- HFunc(TEvBlobStorage::TEvMonStreamQuery, HandleRequestWithoutQoS)
- HFunc(TEvBlobStorage::TEvVSync, HandleRequestWithoutQoS)
- HFunc(TEvBlobStorage::TEvVSyncFull, HandleRequestWithoutQoS)
- HFunc(TEvBlobStorage::TEvVSyncGuid, HandleRequestWithoutQoS)
- HFunc(TEvBlobStorage::TEvVCheckReadiness, HandleCheckReadiness)
- HFunc(TEvBlobStorage::TEvVCompact, Check)
+ HFunc(TEvBlobStorage::TEvVBlock, Check)
+ HFunc(TEvBlobStorage::TEvVGetBlock, Check)
+ HFunc(TEvBlobStorage::TEvVCollectGarbage, Check)
+ HFunc(TEvBlobStorage::TEvVGetBarrier, Check)
+ HFunc(TEvBlobStorage::TEvVStatus, Check)
+ HFunc(TEvBlobStorage::TEvVDbStat, Check)
+ HFunc(TEvBlobStorage::TEvMonStreamQuery, HandleRequestWithoutQoS)
+ HFunc(TEvBlobStorage::TEvVSync, HandleRequestWithoutQoS)
+ HFunc(TEvBlobStorage::TEvVSyncFull, HandleRequestWithoutQoS)
+ HFunc(TEvBlobStorage::TEvVSyncGuid, HandleRequestWithoutQoS)
+ HFunc(TEvBlobStorage::TEvVCheckReadiness, HandleCheckReadiness)
+ HFunc(TEvBlobStorage::TEvVCompact, Check)
HFunc(TEvBlobStorage::TEvVDefrag, Check)
- HFunc(TEvBlobStorage::TEvVBaldSyncLog, Check)
- HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvBlobStorage::TEvVBaldSyncLog, Check)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvPDiskErrorStateChange, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- // TEvFrontRecoveryStatus
- HFunc(TEvVDiskRequestCompleted, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ // TEvFrontRecoveryStatus
+ HFunc(TEvVDiskRequestCompleted, Handle)
CFunc(TEvBlobStorage::EvTimeToUpdateWhiteboard, UpdateWhiteboard)
- CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
- HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
- FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
- FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
- HFunc(TEvReportScrubStatus, Handle)
- HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
- FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
- )
-
-#define HFuncStatus(TEvType, status, errorReason, now, wstatus) \
+ CFunc(NActors::TEvents::TSystem::PoisonPill, Die)
+ HFunc(TEvents::TEvActorDied, Handle)
+ CFunc(TEvBlobStorage::EvCommenceRepl, HandleCommenceRepl)
+ FFunc(TEvBlobStorage::EvControllerScrubStartQuantum, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvScrubAwait, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCaptureVDiskLayout, ForwardToSkeleton)
+ FFunc(TEvBlobStorage::EvCompactVDisk, ForwardToSkeleton)
+ HFunc(TEvReportScrubStatus, Handle)
+ HFunc(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateUpdate, Handle)
+ FFunc(TEvBlobStorage::EvForwardToSkeleton, HandleForwardToSkeleton)
+ )
+
+#define HFuncStatus(TEvType, status, errorReason, now, wstatus) \
case TEvType::EventType: \
{ \
- TEvType::TPtr x(static_cast<TEventHandle<TEvType>*>(ev.release())); \
- Reply(x, ctx, status, errorReason, now, wstatus); \
+ TEvType::TPtr x(static_cast<TEventHandle<TEvType>*>(ev.release())); \
+ Reply(x, ctx, status, errorReason, now, wstatus); \
break; \
}
public:
- void ReplyFunc(std::unique_ptr<IEventHandle> ev, const ::NActors::TActorContext &ctx,
- NKikimrProto::EReplyStatus status, const TString& errorReason, TInstant now,
- const TWindowStatus &wstatus) {
+ void ReplyFunc(std::unique_ptr<IEventHandle> ev, const ::NActors::TActorContext &ctx,
+ NKikimrProto::EReplyStatus status, const TString& errorReason, TInstant now,
+ const TWindowStatus &wstatus) {
switch (ev->GetTypeRewrite()) {
HFuncStatus(TEvBlobStorage::TEvVMovedPatch, status, errorReason, now, wstatus);
HFuncStatus(TEvBlobStorage::TEvVPatchStart, status, errorReason, now, wstatus);
HFuncStatus(TEvBlobStorage::TEvVPatchDiff, status, errorReason, now, wstatus);
HFuncStatus(TEvBlobStorage::TEvVPatchXorDiff, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVPut, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVMultiPut, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVGet, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVBlock, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVGetBlock, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVCollectGarbage, status, errorReason, now, wstatus);
- HFuncStatus(TEvBlobStorage::TEvVGetBarrier, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVPut, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVMultiPut, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVGet, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVBlock, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVGetBlock, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVCollectGarbage, status, errorReason, now, wstatus);
+ HFuncStatus(TEvBlobStorage::TEvVGetBarrier, status, errorReason, now, wstatus);
default: Y_VERIFY_DEBUG(false, "Unsupported message %d", ev->GetTypeRewrite());
}
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SKELETON_FRONT;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SKELETON_FRONT;
}
static TIntrusivePtr<NMonitoring::TDynamicCounters> CreateVDiskCounters(
@@ -1834,8 +1834,8 @@ namespace NKikimr {
vdiskCounters = vdiskCounters->GetSubgroup("media", to_lower(TPDiskCategory::DeviceTypeStr(media, true)));
return vdiskCounters;
- }
-
+ }
+
TSkeletonFront(TIntrusivePtr<TVDiskConfig> cfg, TIntrusivePtr<TBlobStorageGroupInfo> info,
const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters)
: TActorBootstrapped<TSkeletonFront>()
@@ -1847,7 +1847,7 @@ namespace NKikimr {
, SkeletonId()
, VDiskCounters(CreateVDiskCounters(cfg, info, counters))
, SkeletonFrontGroup(VDiskCounters->GetSubgroup("subsystem", "skeletonfront"))
- , AccessDeniedMessages(SkeletonFrontGroup->GetCounter("AccessDeniedMessages", true))
+ , AccessDeniedMessages(SkeletonFrontGroup->GetCounter("AccessDeniedMessages", true))
, ExtQueueAsyncGets(NKikimrBlobStorage::EVDiskQueueId::GetAsyncRead,
"AsyncGet",
@@ -1861,12 +1861,12 @@ namespace NKikimr {
Config->SkeletonFrontQueueBackpressureCheckMsgId,
SkeletonFrontGroup,
cfg)
- , ExtQueueDiscoverGets(NKikimrBlobStorage::EVDiskQueueId::GetDiscover,
+ , ExtQueueDiscoverGets(NKikimrBlobStorage::EVDiskQueueId::GetDiscover,
"DiscoverGet",
Config->SkeletonFrontExtGetDiscover_TotalCost,
Config->SkeletonFrontQueueBackpressureCheckMsgId,
- SkeletonFrontGroup,
- cfg)
+ SkeletonFrontGroup,
+ cfg)
, ExtQueueLowGets(NKikimrBlobStorage::EVDiskQueueId::GetLowRead,
"LowGet",
Config->SkeletonFrontExtGetLow_TotalCost,
@@ -1877,20 +1877,20 @@ namespace NKikimr {
"PutTabletLog",
Config->SkeletonFrontExtPutTabletLog_TotalCost,
Config->SkeletonFrontQueueBackpressureCheckMsgId,
- SkeletonFrontGroup,
- cfg)
+ SkeletonFrontGroup,
+ cfg)
, ExtQueueAsyncBlobPuts(NKikimrBlobStorage::EVDiskQueueId::PutAsyncBlob,
"PutAsyncBlob",
Config->SkeletonFrontExtPutAsyncBlob_TotalCost,
Config->SkeletonFrontQueueBackpressureCheckMsgId,
- SkeletonFrontGroup,
- cfg)
+ SkeletonFrontGroup,
+ cfg)
, ExtQueueUserDataPuts(NKikimrBlobStorage::EVDiskQueueId::PutUserData,
"PutUserData",
Config->SkeletonFrontExtPutUserData_TotalCost,
Config->SkeletonFrontQueueBackpressureCheckMsgId,
- SkeletonFrontGroup,
- cfg)
+ SkeletonFrontGroup,
+ cfg)
, CostModel()
, ReplMonGroup(VDiskCounters, "subsystem", "repl")
, SyncerMonGroup(VDiskCounters, "subsystem", "syncer")
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.h
index 9044230ab1e..2f873865c73 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.h
@@ -25,13 +25,13 @@ namespace NKikimr {
const EPhase Phase;
const NKikimrProto::EReplyStatus Status;
const TIntrusivePtr<TPDiskParams> Dsk;
- const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
+ const std::shared_ptr<THugeBlobCtx> HugeBlobCtx;
const TVDiskIncarnationGuid VDiskIncarnationGuid;
TEvFrontRecoveryStatus(EPhase phase,
NKikimrProto::EReplyStatus status,
const TIntrusivePtr<TPDiskParams> &dsk,
- std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
+ std::shared_ptr<THugeBlobCtx> hugeBlobCtx,
TVDiskIncarnationGuid vdiskIncarnationGuid);
~TEvFrontRecoveryStatus();
};
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp
index 5881368772c..5f93fb9a0b3 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp
@@ -24,8 +24,8 @@ namespace NKikimr {
bool allowKeepFlags) const {
return TLogoBlobFilter::Check(key.LogoBlobID()) &&
BarriersEssence->Keep(key, memRec, recsMerged, allowKeepFlags).KeepData;
- }
-
+ }
+
TIntrusivePtr<THullCtx> HullCtx;
TIntrusivePtr<TBarriersSnapshot::TBarriersEssence> BarriersEssence;
};
@@ -45,7 +45,7 @@ namespace NKikimr {
TKeyBlock KeyBlock;
TKeyBarrier KeyBarrier;
NKikimrBlobStorage::ESyncFullStage Stage;
- std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> Result;
TFakeFilter FakeFilter;
TLogoBlobFilterForHull LogoBlobFilter;
TVDiskID SourceVDisk;
@@ -70,7 +70,7 @@ namespace NKikimr {
Y_UNUSED(ctx);
char tmpBuf[NSyncLog::MaxRecFullSize];
auto s = NSyncLog::TSerializeRoutines::SetBlock;
- ui32 size = s(tmpBuf, 0, key.TabletId, memRec.BlockedGeneration, 0);
+ ui32 size = s(tmpBuf, 0, key.TabletId, memRec.BlockedGeneration, 0);
buf->append(tmpBuf, size);
}
@@ -83,7 +83,7 @@ namespace NKikimr {
auto s = NSyncLog::TSerializeRoutines::SetBarrier;
ui32 size = s(tmpBuf, 0, key.TabletId, key.Channel, key.Gen,
key.GenCounter, memRec.CollectGen,
- memRec.CollectStep, key.Hard, memRec.Ingress);
+ memRec.CollectStep, key.Hard, memRec.Ingress);
buf->append(tmpBuf, size);
}
@@ -92,7 +92,7 @@ namespace NKikimr {
void Bootstrap(const TActorContext &ctx) {
LogoBlobFilter.BuildBarriersEssence(FullSnap.BarriersSnap);
-
+
ui32 pres = 0;
switch (Stage) {
case NKikimrBlobStorage::LogoBlobs:
@@ -125,7 +125,7 @@ namespace NKikimr {
Result->Record.SetBlockTabletFrom(KeyBlock.TabletId);
KeyBarrier.Serialize(*Result->Record.MutableBarrierFrom());
// send reply
- SendVDiskResponse(ctx, Recipient, Result.release(), *this, 0);
+ SendVDiskResponse(ctx, Recipient, Result.release(), *this, 0);
// notify parent about death
ctx.Send(ParentId, new TEvents::TEvActorDied);
Die(ctx);
@@ -148,7 +148,7 @@ namespace NKikimr {
TIndexForwardIterator it(HullCtx, &snapshot);
it.Seek(key);
// copy data until we have some space
- while (it.Valid() && (data->size() + NSyncLog::MaxRecFullSize <= data->capacity())) {
+ while (it.Valid() && (data->size() + NSyncLog::MaxRecFullSize <= data->capacity())) {
key = it.GetCurKey();
if (filter.Check(key, it.GetMemRec(), it.GetMemRecsMerged(), HullCtx->AllowKeepFlags))
Serialize(ctx, data, key, it.GetMemRec());
@@ -159,14 +159,14 @@ namespace NKikimr {
ui32 result = 0;
if (!it.Valid())
result |= EmptyFlag;
- if (data->size() + NSyncLog::MaxRecFullSize > data->capacity())
+ if (data->size() + NSyncLog::MaxRecFullSize > data->capacity())
result |= MsgFullFlag;
return result;
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_HULL_SYNC_FULL;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_HULL_SYNC_FULL;
}
THullSyncFullActor(
@@ -180,7 +180,7 @@ namespace NKikimr {
const TKeyBlock &keyBlock,
const TKeyBarrier &keyBarrier,
NKikimrBlobStorage::ESyncFullStage stage,
- std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result)
+ std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result)
: TActorBootstrapped<THullSyncFullActor>()
, Config(config)
, HullCtx(hullCtx)
@@ -191,7 +191,7 @@ namespace NKikimr {
, KeyBlock(keyBlock)
, KeyBarrier(keyBarrier)
, Stage(stage)
- , Result(std::move(result))
+ , Result(std::move(result))
, FakeFilter()
, LogoBlobFilter(HullCtx, sourceVDisk)
, SourceVDisk(sourceVDisk)
@@ -212,9 +212,9 @@ namespace NKikimr {
const TKeyBlock &keyBlock,
const TKeyBarrier &keyBarrier,
NKikimrBlobStorage::ESyncFullStage stage,
- std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result) {
+ std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result) {
return new THullSyncFullActor(config, hullCtx, parentId, sourceVDisk, recipient, std::move(fullSnap),
- keyLogoBlob, keyBlock, keyBarrier, stage, std::move(result));
+ keyLogoBlob, keyBlock, keyBarrier, stage, std::move(result));
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.h
index 50d8ea5acce..0fa7bf6e158 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.h
@@ -17,6 +17,6 @@ namespace NKikimr {
const TKeyBlock &keyBlock,
const TKeyBarrier &keyBarrier,
NKikimrBlobStorage::ESyncFullStage stage,
- std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result);
+ std::unique_ptr<TEvBlobStorage::TEvVSyncFullResult> result);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp
index 11f708e717d..1672692c24e 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.cpp
@@ -18,8 +18,8 @@ namespace NKikimr {
TIntrusivePtr<THullCtx> HullCtx;
const TVDiskID SelfVDiskId;
const TActorId ParentId;
- std::shared_ptr<THull> Hull;
- std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
+ std::shared_ptr<THull> Hull;
+ std::shared_ptr<NMonGroup::TVDiskIFaceGroup> IFaceMonGroup;
TEvBlobStorage::TEvVSyncFull::TPtr Ev;
const NKikimrBlobStorage::TEvVSyncFull &Record;
const TVDiskID SourceVDisk;
@@ -43,7 +43,7 @@ namespace NKikimr {
IFaceMonGroup->SyncFullMsgs()++;
TActorId recipient = Ev->Sender;
- const ui64 cookie = Ev->Cookie;
+ const ui64 cookie = Ev->Cookie;
TSyncState clientSyncState(SyncStateFromSyncState(Record.GetSyncState()));
LOG_DEBUG_S(ctx, BS_SYNCJOB, Db->VCtx->VDiskLogPrefix
@@ -56,10 +56,10 @@ namespace NKikimr {
// check that the disk is from this group
if (!SelfVDiskId.SameGroupAndGeneration(SourceVDisk) ||
!SelfVDiskId.SameDisk(TargetVDisk)) {
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::ERROR, SelfVDiskId,
- Record.GetCookie(), Now, IFaceMonGroup->SyncFullResMsgsPtr(), nullptr, std::move(Ev->TraceId),
- Ev->GetChannel());
- SendVDiskResponse(ctx, recipient, result.release(), *this, cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::ERROR, SelfVDiskId,
+ Record.GetCookie(), Now, IFaceMonGroup->SyncFullResMsgsPtr(), nullptr, std::move(Ev->TraceId),
+ Ev->GetChannel());
+ SendVDiskResponse(ctx, recipient, result.release(), *this, cookie);
Die(ctx);
return;
}
@@ -71,10 +71,10 @@ namespace NKikimr {
<< " SourceVDisk# " << SourceVDisk
<< " DbBirthLsn# " << DbBirthLsn
<< " Marker# BSVSFH02");
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::NODATA, SelfVDiskId,
- TSyncState(Db->GetVDiskIncarnationGuid(), DbBirthLsn), Record.GetCookie(), Now,
- IFaceMonGroup->SyncFullResMsgsPtr(), nullptr, std::move(Ev->TraceId), Ev->GetChannel());
- SendVDiskResponse(ctx, recipient, result.release(), *this, cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::NODATA, SelfVDiskId,
+ TSyncState(Db->GetVDiskIncarnationGuid(), DbBirthLsn), Record.GetCookie(), Now,
+ IFaceMonGroup->SyncFullResMsgsPtr(), nullptr, std::move(Ev->TraceId), Ev->GetChannel());
+ SendVDiskResponse(ctx, recipient, result.release(), *this, cookie);
Die(ctx);
return;
}
@@ -104,9 +104,9 @@ namespace NKikimr {
const TKeyBarrier barrierFrom(Record.GetBarrierFrom());
TSyncState newSyncState(Db->GetVDiskIncarnationGuid(), syncedLsn);
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::OK, SelfVDiskId,
- newSyncState, Record.GetCookie(), Now, IFaceMonGroup->SyncFullResMsgsPtr(), nullptr,
- std::move(Ev->TraceId), Ev->GetChannel());
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncFullResult>(NKikimrProto::OK, SelfVDiskId,
+ newSyncState, Record.GetCookie(), Now, IFaceMonGroup->SyncFullResMsgsPtr(), nullptr,
+ std::move(Ev->TraceId), Ev->GetChannel());
// snapshotLsn is _always_ the last confirmed lsn
THullDsSnap fullSnap = Hull->GetIndexSnapshot();
@@ -127,7 +127,7 @@ namespace NKikimr {
TKeyBlock(blockTabletFrom),
barrierFrom,
stage,
- std::move(result));
+ std::move(result));
auto aid = ctx.Register(actor);
ActiveActors.Insert(aid);
Become(&TThis::StateFunc);
@@ -145,22 +145,22 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvActorDied, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNC_FULL_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNC_FULL_HANDLER;
}
TVSyncFullHandler(const TIntrusivePtr<TDb> &db,
const TIntrusivePtr<THullCtx> &hullCtx,
const TVDiskID &selfVDiskId,
const TActorId &parentId,
- const std::shared_ptr<THull> &hull,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<THull> &hull,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
TEvBlobStorage::TEvVSyncFull::TPtr &ev,
const TInstant &now,
ui64 dbBirthLsn,
@@ -191,8 +191,8 @@ namespace NKikimr {
const TIntrusivePtr<THullCtx> &hullCtx,
const TVDiskID &selfVDiskId,
const TActorId &parentId,
- const std::shared_ptr<THull> &hull,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<THull> &hull,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
TEvBlobStorage::TEvVSyncFull::TPtr &ev,
const TInstant &now,
ui64 dbBirthLsn,
diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.h
index 7d4c29253aa..bbd108f90d9 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfullhandler.h
@@ -16,8 +16,8 @@ namespace NKikimr {
const TIntrusivePtr<THullCtx> &hullCtx,
const TVDiskID &selfVDiskId,
const TActorId &parentId,
- const std::shared_ptr<THull> &hull,
- const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
+ const std::shared_ptr<THull> &hull,
+ const std::shared_ptr<NMonGroup::TVDiskIFaceGroup> &ifaceMonGroup,
TEvBlobStorage::TEvVSyncFull::TPtr &ev,
const TInstant &now,
ui64 dbBirthLsn,
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_capturevdisklayout.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_capturevdisklayout.h
index aca411bafc1..8e3166b1840 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_capturevdisklayout.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_capturevdisklayout.h
@@ -1,89 +1,89 @@
-#pragma once
-
-namespace NKikimr {
-
- class TCaptureVDiskLayoutActor : public TActorBootstrapped<TCaptureVDiskLayoutActor> {
+#pragma once
+
+namespace NKikimr {
+
+ class TCaptureVDiskLayoutActor : public TActorBootstrapped<TCaptureVDiskLayoutActor> {
using TRes = TEvBlobStorage::TEvCaptureVDiskLayoutResult;
- TEvBlobStorage::TEvCaptureVDiskLayout::TPtr Ev;
- THullDsSnap Snap;
-
- public:
- TCaptureVDiskLayoutActor(TEvBlobStorage::TEvCaptureVDiskLayout::TPtr ev, THullDsSnap snap)
- : Ev(ev)
- , Snap(std::move(snap))
- {}
-
- void Bootstrap() {
- auto res = std::make_unique<TRes>();
-
- auto traverse = [&](const auto& slice, auto&& callback, TRes::EDatabase type) {
- using T = std::decay_t<decltype(slice)>;
- typename T::TSstIterator iter(&slice);
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- const auto& item = iter.Get();
- const auto& sst = item.SstPtr;
- for (const TDiskPart& part : sst->IndexParts) {
- res->Layout.push_back({part, type, TRes::ERecordType::IndexRecord, {}, sst->AssignedSstId,
- item.Level});
- }
- callback(sst, item.Level);
- }
- };
-
- // then, scan all the blobs
- struct TMerger {
- TRes& Res;
- ui32 Level;
-
- static constexpr bool HaveToMergeData() { return true; }
-
- void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key,
- ui64 circaLsn) {
- TDiskDataExtractor extr;
- memRec.GetDiskData(&extr, outbound);
- const TRes::ERecordType recordType = extr.BlobType == TBlobType::DiskBlob
- ? TRes::ERecordType::InplaceBlob
- : TRes::ERecordType::HugeBlob;
- for (const TDiskPart *location = extr.Begin; location != extr.End; ++location) {
- if (location->ChunkIdx && location->Size) {
- Res.Layout.push_back({*location, TRes::EDatabase::LogoBlobs, recordType, key.LogoBlobID(),
- circaLsn, Level});
- }
- }
- }
-
- void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key,
- ui64 circaLsn) {
- if (!data) {
- AddFromSegment(memRec, nullptr, key, circaLsn);
- }
- }
- };
-
- auto logoBlobsCallback = [&](const auto& sst, ui32 level) {
- TMerger merger{*res, level};
- TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>::TMemIterator iter(sst.Get());
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- iter.PutToMerger(&merger);
- }
- };
-
- auto ignoreCallback = [](const auto& /*sst*/, ui32 /*level*/) {};
-
- traverse(Snap.LogoBlobsSnap.SliceSnap, logoBlobsCallback, TRes::EDatabase::LogoBlobs);
- traverse(Snap.BlocksSnap.SliceSnap, ignoreCallback, TRes::EDatabase::Blocks);
- traverse(Snap.BarriersSnap.SliceSnap, ignoreCallback, TRes::EDatabase::Barriers);
-
- TMerger merger{*res, Max<ui32>()};
- TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>::TForwardIterator iter(Snap.HullCtx, &Snap.LogoBlobsSnap.FreshSnap);
- for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
- iter.PutToMerger(&merger);
- }
-
- Send(Ev->Sender, res.release(), 0, Ev->Cookie);
- PassAway();
- }
- };
-
-} // NKikimr
+ TEvBlobStorage::TEvCaptureVDiskLayout::TPtr Ev;
+ THullDsSnap Snap;
+
+ public:
+ TCaptureVDiskLayoutActor(TEvBlobStorage::TEvCaptureVDiskLayout::TPtr ev, THullDsSnap snap)
+ : Ev(ev)
+ , Snap(std::move(snap))
+ {}
+
+ void Bootstrap() {
+ auto res = std::make_unique<TRes>();
+
+ auto traverse = [&](const auto& slice, auto&& callback, TRes::EDatabase type) {
+ using T = std::decay_t<decltype(slice)>;
+ typename T::TSstIterator iter(&slice);
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ const auto& item = iter.Get();
+ const auto& sst = item.SstPtr;
+ for (const TDiskPart& part : sst->IndexParts) {
+ res->Layout.push_back({part, type, TRes::ERecordType::IndexRecord, {}, sst->AssignedSstId,
+ item.Level});
+ }
+ callback(sst, item.Level);
+ }
+ };
+
+ // then, scan all the blobs
+ struct TMerger {
+ TRes& Res;
+ ui32 Level;
+
+ static constexpr bool HaveToMergeData() { return true; }
+
+ void AddFromSegment(const TMemRecLogoBlob& memRec, const TDiskPart *outbound, const TKeyLogoBlob& key,
+ ui64 circaLsn) {
+ TDiskDataExtractor extr;
+ memRec.GetDiskData(&extr, outbound);
+ const TRes::ERecordType recordType = extr.BlobType == TBlobType::DiskBlob
+ ? TRes::ERecordType::InplaceBlob
+ : TRes::ERecordType::HugeBlob;
+ for (const TDiskPart *location = extr.Begin; location != extr.End; ++location) {
+ if (location->ChunkIdx && location->Size) {
+ Res.Layout.push_back({*location, TRes::EDatabase::LogoBlobs, recordType, key.LogoBlobID(),
+ circaLsn, Level});
+ }
+ }
+ }
+
+ void AddFromFresh(const TMemRecLogoBlob& memRec, const TRope *data, const TKeyLogoBlob& key,
+ ui64 circaLsn) {
+ if (!data) {
+ AddFromSegment(memRec, nullptr, key, circaLsn);
+ }
+ }
+ };
+
+ auto logoBlobsCallback = [&](const auto& sst, ui32 level) {
+ TMerger merger{*res, level};
+ TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>::TMemIterator iter(sst.Get());
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ iter.PutToMerger(&merger);
+ }
+ };
+
+ auto ignoreCallback = [](const auto& /*sst*/, ui32 /*level*/) {};
+
+ traverse(Snap.LogoBlobsSnap.SliceSnap, logoBlobsCallback, TRes::EDatabase::LogoBlobs);
+ traverse(Snap.BlocksSnap.SliceSnap, ignoreCallback, TRes::EDatabase::Blocks);
+ traverse(Snap.BarriersSnap.SliceSnap, ignoreCallback, TRes::EDatabase::Barriers);
+
+ TMerger merger{*res, Max<ui32>()};
+ TFreshDataSnapshot<TKeyLogoBlob, TMemRecLogoBlob>::TForwardIterator iter(Snap.HullCtx, &Snap.LogoBlobsSnap.FreshSnap);
+ for (iter.SeekToFirst(); iter.Valid(); iter.Next()) {
+ iter.PutToMerger(&merger);
+ }
+
+ Send(Ev->Sender, res.release(), 0, Ev->Cookie);
+ PassAway();
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp
index daaa498926b..814ae4ce506 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.cpp
@@ -18,19 +18,19 @@ namespace NKikimr {
void TVDiskCompactionState::SendLocalCompactCmd(const TActorContext &ctx, TCompactionReq cReq) {
ui64 requestId = ++RequestIdCounter;
- const auto mode = cReq.Mode;
+ const auto mode = cReq.Mode;
auto insRes = Requests.insert({requestId, std::move(cReq)});
Y_VERIFY(insRes.second);
auto &req = insRes.first->second;
if (req.CompactLogoBlobs) {
- ctx.Send(LogoBlobsActorId, new TEvHullCompact(EHullDbType::LogoBlobs, requestId, mode));
+ ctx.Send(LogoBlobsActorId, new TEvHullCompact(EHullDbType::LogoBlobs, requestId, mode));
}
if (req.CompactBlocks) {
- ctx.Send(BlocksActorId, new TEvHullCompact(EHullDbType::Blocks, requestId, mode));
+ ctx.Send(BlocksActorId, new TEvHullCompact(EHullDbType::Blocks, requestId, mode));
}
if (req.CompactBarriers) {
- ctx.Send(BarriersActorId, new TEvHullCompact(EHullDbType::Barriers, requestId, mode));
+ ctx.Send(BarriersActorId, new TEvHullCompact(EHullDbType::Barriers, requestId, mode));
}
}
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.h
index 1a0a39677b5..6bdad89fa71 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_compactionstate.h
@@ -12,7 +12,7 @@ namespace NKikimr {
bool CompactLogoBlobs = false;
bool CompactBlocks = false;
bool CompactBarriers = false;
- TEvCompactVDisk::EMode Mode;
+ TEvCompactVDisk::EMode Mode;
TActorId ClientId;
ui64 ClientCookie = 0;
std::unique_ptr<TEvCompactVDiskResult> Reply;
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp
index ce4615fb5d4..41db3b86dce 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.cpp
@@ -23,14 +23,14 @@ namespace NKikimr {
const TLogoBlobID &id,
const TIngress &ingress,
TRope &&buffer,
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> result,
const TActorId &recipient,
ui64 recipientCookie)
: ILoggedRec(seg, confirmSyncLogAlso)
, Id(id)
, Ingress(ingress)
, Buffer(std::move(buffer))
- , Result(std::move(result))
+ , Result(std::move(result))
, Recipient(recipient)
, RecipientCookie(recipientCookie)
{}
@@ -44,7 +44,7 @@ namespace NKikimr {
<< " msg# " << Result->ToString()
<< " Marker# BSVSLR01");
- SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
+ SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -56,14 +56,14 @@ namespace NKikimr {
const TLogoBlobID &id,
const TIngress &ingress,
TRope &&buffer,
- std::unique_ptr<TEvVMultiPutItemResult> result,
+ std::unique_ptr<TEvVMultiPutItemResult> result,
const TActorId &recipient,
ui64 recipientCookie)
: ILoggedRec(seg, confirmSyncLogAlso)
, Id(id)
, Ingress(ingress)
, Buffer(std::move(buffer))
- , Result(std::move(result))
+ , Result(std::move(result))
, Recipient(recipient)
, RecipientCookie(recipientCookie)
{}
@@ -79,7 +79,7 @@ namespace NKikimr {
<< " msg# " << Result->ToString()
<< " Marker# BSVSLR02");
- ctx.Send(Recipient, Result.release(), RecipientCookie);
+ ctx.Send(Recipient, Result.release(), RecipientCookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -101,14 +101,14 @@ namespace NKikimr {
TLogoBlobID genId(msg->LogoBlobID, 0);
hull.AddHugeLogoBlob(ctx, genId, msg->Ingress, msg->HugeBlob, Seg.Point());
// notify huge keeper
- if (msg->HugeBlob != TDiskPart()) {
- ctx.Send(HugeKeeperId, new TEvHullHugeBlobLogged(msg->WriteId, msg->HugeBlob, Seg.Point(), true));
- }
+ if (msg->HugeBlob != TDiskPart()) {
+ ctx.Send(HugeKeeperId, new TEvHullHugeBlobLogged(msg->WriteId, msg->HugeBlob, Seg.Point(), true));
+ }
LOG_DEBUG_S(ctx, NKikimrServices::BS_VDISK_PUT, hull.GetHullCtx()->VCtx->VDiskLogPrefix
<< "TEvVPut: realtime# false result# " << msg->Result->ToString()
<< " Marker# BSVSLR03");
- SendVDiskResponse(ctx, msg->OrigClient, msg->Result.release(), actor, msg->OrigCookie);
+ SendVDiskResponse(ctx, msg->OrigClient, msg->Result.release(), actor, msg->OrigCookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -119,15 +119,15 @@ namespace NKikimr {
bool confirmSyncLogAlso,
ui64 tabletId,
ui32 gen,
- ui64 issuerGuid,
- std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result,
+ ui64 issuerGuid,
+ std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result,
const TActorId &recipient,
ui64 recipientCookie)
: ILoggedRec(seg, confirmSyncLogAlso)
, TabletId(tabletId)
, Gen(gen)
- , IssuerGuid(issuerGuid)
- , Result(std::move(result))
+ , IssuerGuid(issuerGuid)
+ , Result(std::move(result))
, Recipient(recipient)
, RecipientCookie(recipientCookie)
{}
@@ -137,12 +137,12 @@ namespace NKikimr {
SendVDiskResponse(ctx, id, msg, actor, cookie);
};
- hull.AddBlockCmd(ctx, TabletId, Gen, IssuerGuid, Seg.Point(), replySender);
+ hull.AddBlockCmd(ctx, TabletId, Gen, IssuerGuid, Seg.Point(), replySender);
LOG_DEBUG_S(ctx, NKikimrServices::BS_VDISK_BLOCK, hull.GetHullCtx()->VCtx->VDiskLogPrefix
<< "TEvVBlock: result# " << Result->ToString()
<< " Marker# BSVSLR04");
- SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
+ SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -152,11 +152,11 @@ namespace NKikimr {
TLsnSeg seg,
bool confirmSyncLogAlso,
TBarrierIngress ingress,
- std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result,
TEvBlobStorage::TEvVCollectGarbage::TPtr origEv)
: ILoggedRec(seg, confirmSyncLogAlso)
, Ingress(ingress)
- , Result(std::move(result))
+ , Result(std::move(result))
, OrigEv(origEv)
{}
@@ -167,7 +167,7 @@ namespace NKikimr {
LOG_DEBUG_S(ctx, NKikimrServices::BS_VDISK_GC, hull.GetHullCtx()->VCtx->VDiskLogPrefix
<< "TEvVCollectGarbage: result# " << Result->ToString()
<< " Marker# BSVSLR05");
- SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
+ SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -176,10 +176,10 @@ namespace NKikimr {
TLoggedRecLocalSyncData::TLoggedRecLocalSyncData(
TLsnSeg seg,
bool confirmSyncLogAlso,
- std::unique_ptr<TEvLocalSyncDataResult> result,
+ std::unique_ptr<TEvLocalSyncDataResult> result,
TEvLocalSyncData::TPtr origEv)
: ILoggedRec(seg, confirmSyncLogAlso)
- , Result(std::move(result))
+ , Result(std::move(result))
, OrigEv(origEv)
{}
@@ -193,7 +193,7 @@ namespace NKikimr {
#else
hull.AddSyncDataCmd(ctx, OrigEv->Get()->Data, Seg, replySender);
#endif
- SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
+ SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -203,17 +203,17 @@ namespace NKikimr {
TLsnSeg seg,
bool confirmSyncLogAlso,
const TEvAnubisOsirisPut::THullDbInsert &insert,
- std::unique_ptr<TEvAnubisOsirisPutResult> result,
+ std::unique_ptr<TEvAnubisOsirisPutResult> result,
TEvAnubisOsirisPut::TPtr origEv)
: ILoggedRec(seg, confirmSyncLogAlso)
, Insert(insert)
- , Result(std::move(result))
+ , Result(std::move(result))
, OrigEv(origEv)
{}
void TLoggedRecAnubisOsirisPut::Replay(THull &hull, const TActorContext &ctx, const IActor& actor) {
hull.AddAnubisOsirisLogoBlob(ctx, Insert.Id, Insert.Ingress, Seg);
- SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
+ SendVDiskResponse(ctx, OrigEv->Sender, Result.release(), actor, OrigEv->Cookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -239,18 +239,18 @@ namespace NKikimr {
TLoggedRecDelLogoBlobDataSyncLog::TLoggedRecDelLogoBlobDataSyncLog(
TLsnSeg seg,
bool confirmSyncLogAlso,
- std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result,
+ std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result,
const TActorId &recipient,
ui64 recipientCookie)
: ILoggedRec(seg, confirmSyncLogAlso)
- , Result(std::move(result))
+ , Result(std::move(result))
, Recipient(recipient)
, RecipientCookie(recipientCookie)
{}
void TLoggedRecDelLogoBlobDataSyncLog::Replay(THull &hull, const TActorContext &ctx, const IActor& actor) {
Y_UNUSED(hull);
- SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
+ SendVDiskResponse(ctx, Recipient, Result.release(), actor, RecipientCookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -266,7 +266,7 @@ namespace NKikimr {
void TLoggedRecAddBulkSst::Replay(THull &hull, const TActorContext &ctx, const IActor& actor) {
hull.AddBulkSst(ctx, OrigEv->Get()->Essence, Seg);
- SendVDiskResponse(ctx, OrigEv->Sender, new TEvAddBulkSstResult, actor, OrigEv->Cookie);
+ SendVDiskResponse(ctx, OrigEv->Sender, new TEvAddBulkSstResult, actor, OrigEv->Cookie);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.h
index 50a7a06d2af..f68ebf84bef 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_loggedrec.h
@@ -48,7 +48,7 @@ namespace NKikimr {
class TLoggedRecVPut : public ILoggedRec {
public:
TLoggedRecVPut(TLsnSeg seg, bool confirmSyncLogAlso, const TLogoBlobID &id, const TIngress &ingress,
- TRope &&buffer, std::unique_ptr<TEvBlobStorage::TEvVPutResult> result, const TActorId &recipient,
+ TRope &&buffer, std::unique_ptr<TEvBlobStorage::TEvVPutResult> result, const TActorId &recipient,
ui64 recipientCookie);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
@@ -56,7 +56,7 @@ namespace NKikimr {
TLogoBlobID Id;
TIngress Ingress;
TRope Buffer;
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> Result;
TActorId Recipient;
ui64 RecipientCookie;
};
@@ -67,7 +67,7 @@ namespace NKikimr {
class TLoggedRecVMultiPutItem : public ILoggedRec {
public:
TLoggedRecVMultiPutItem(TLsnSeg seg, bool confirmSyncLogAlso, const TLogoBlobID &id, const TIngress &ingress,
- TRope &&buffer, std::unique_ptr<TEvVMultiPutItemResult> result, const TActorId &recipient,
+ TRope &&buffer, std::unique_ptr<TEvVMultiPutItemResult> result, const TActorId &recipient,
ui64 recipientCookie);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
@@ -75,7 +75,7 @@ namespace NKikimr {
TLogoBlobID Id;
TIngress Ingress;
TRope Buffer;
- std::unique_ptr<TEvVMultiPutItemResult> Result;
+ std::unique_ptr<TEvVMultiPutItemResult> Result;
TActorId Recipient;
ui64 RecipientCookie;
};
@@ -99,15 +99,15 @@ namespace NKikimr {
///////////////////////////////////////////////////////////////////////////////////////////////////////
class TLoggedRecVBlock : public ILoggedRec {
public:
- TLoggedRecVBlock(TLsnSeg seg, bool confirmSyncLogAlso, ui64 tabletId, ui32 gen, ui64 issuerGuid,
- std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result, const TActorId &recipient, ui64 recipientCookie);
+ TLoggedRecVBlock(TLsnSeg seg, bool confirmSyncLogAlso, ui64 tabletId, ui32 gen, ui64 issuerGuid,
+ std::unique_ptr<TEvBlobStorage::TEvVBlockResult> result, const TActorId &recipient, ui64 recipientCookie);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
private:
ui64 TabletId;
ui32 Gen;
- ui64 IssuerGuid;
- std::unique_ptr<TEvBlobStorage::TEvVBlockResult> Result;
+ ui64 IssuerGuid;
+ std::unique_ptr<TEvBlobStorage::TEvVBlockResult> Result;
TActorId Recipient;
ui64 RecipientCookie;
};
@@ -118,13 +118,13 @@ namespace NKikimr {
class TLoggedRecVCollectGarbage : public ILoggedRec {
public:
TLoggedRecVCollectGarbage(TLsnSeg seg, bool confirmSyncLogAlso, TBarrierIngress ingress,
- std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result,
+ std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> result,
TEvBlobStorage::TEvVCollectGarbage::TPtr origEv);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
private:
TBarrierIngress Ingress;
- std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> Result;
+ std::unique_ptr<TEvBlobStorage::TEvVCollectGarbageResult> Result;
TEvBlobStorage::TEvVCollectGarbage::TPtr OrigEv;
};
@@ -133,12 +133,12 @@ namespace NKikimr {
///////////////////////////////////////////////////////////////////////////////////////////////////////
class TLoggedRecLocalSyncData : public ILoggedRec {
public:
- TLoggedRecLocalSyncData(TLsnSeg seg, bool confirmSyncLogAlso, std::unique_ptr<TEvLocalSyncDataResult> result,
+ TLoggedRecLocalSyncData(TLsnSeg seg, bool confirmSyncLogAlso, std::unique_ptr<TEvLocalSyncDataResult> result,
TEvLocalSyncData::TPtr origEv);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
private:
- std::unique_ptr<TEvLocalSyncDataResult> Result;
+ std::unique_ptr<TEvLocalSyncDataResult> Result;
TEvLocalSyncData::TPtr OrigEv;
};
@@ -148,13 +148,13 @@ namespace NKikimr {
class TLoggedRecAnubisOsirisPut : public ILoggedRec {
public:
TLoggedRecAnubisOsirisPut(TLsnSeg seg, bool confirmSyncLogAlso,
- const TEvAnubisOsirisPut::THullDbInsert &insert, std::unique_ptr<TEvAnubisOsirisPutResult> result,
+ const TEvAnubisOsirisPut::THullDbInsert &insert, std::unique_ptr<TEvAnubisOsirisPutResult> result,
TEvAnubisOsirisPut::TPtr origEv);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
private:
TEvAnubisOsirisPut::THullDbInsert Insert;
- std::unique_ptr<TEvAnubisOsirisPutResult> Result;
+ std::unique_ptr<TEvAnubisOsirisPutResult> Result;
TEvAnubisOsirisPut::TPtr OrigEv;
};
@@ -176,12 +176,12 @@ namespace NKikimr {
class TLoggedRecDelLogoBlobDataSyncLog : public ILoggedRec {
public:
TLoggedRecDelLogoBlobDataSyncLog(TLsnSeg seg, bool confirmSyncLogAlso,
- std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result, const TActorId &recipient,
+ std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> result, const TActorId &recipient,
ui64 recipientCookie);
void Replay(THull &hull, const TActorContext &ctx, const IActor& actor) override;
private:
- std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> Result;
+ std::unique_ptr<TEvDelLogoBlobDataSyncLogResult> Result;
TActorId Recipient;
ui64 RecipientCookie;
};
@@ -214,7 +214,7 @@ namespace NKikimr {
private:
class TImpl;
- std::unique_ptr<TImpl> Impl;
+ std::unique_ptr<TImpl> Impl;
};
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.cpp
index 5592abd5c08..e3798a01b3d 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.cpp
@@ -124,7 +124,7 @@ namespace NKikimr {
*/
- TOutOfSpaceLogic::TOutOfSpaceLogic(TIntrusivePtr<TVDiskContext> vctx, std::shared_ptr<THull> hull)
+ TOutOfSpaceLogic::TOutOfSpaceLogic(TIntrusivePtr<TVDiskContext> vctx, std::shared_ptr<THull> hull)
: VCtx(std::move(vctx))
, Hull(std::move(hull))
, Stat(new TStat)
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.h
index 8def77caa1f..839926bee21 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_logic.h
@@ -16,7 +16,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TOutOfSpaceLogic {
public:
- TOutOfSpaceLogic(TIntrusivePtr<TVDiskContext> vctx, std::shared_ptr<THull> hull);
+ TOutOfSpaceLogic(TIntrusivePtr<TVDiskContext> vctx, std::shared_ptr<THull> hull);
~TOutOfSpaceLogic();
// Check if we allow this write
@@ -33,9 +33,9 @@ namespace NKikimr {
private:
TIntrusivePtr<TVDiskContext> VCtx;
- std::shared_ptr<THull> Hull;
+ std::shared_ptr<THull> Hull;
class TStat;
- mutable std::unique_ptr<TStat> Stat;
+ mutable std::unique_ptr<TStat> Stat;
bool DefaultAllow(ESpaceColor color) const;
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_tracker.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_tracker.cpp
index 8af5bd8dc22..9819a5e0fa6 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_tracker.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_oos_tracker.cpp
@@ -187,8 +187,8 @@ namespace NKikimr {
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_DISK_SPACE_TRACKER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_DISK_SPACE_TRACKER;
}
TDskSpaceTrackerActor(
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.cpp
index 45968b8d54f..f860a5b0c6b 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.cpp
@@ -12,13 +12,13 @@ namespace NKikimr {
//////////////////////////////////////////////////////////////////////////
class TEmergencyQueue {
struct TItem {
- std::unique_ptr<IEventHandle> Ev;
+ std::unique_ptr<IEventHandle> Ev;
TItem() = default;
-
- template<typename T>
- TItem(TAutoPtr<TEventHandle<T>> ev)
- : Ev(ev.Release())
+
+ template<typename T>
+ TItem(TAutoPtr<TEventHandle<T>> ev)
+ : Ev(ev.Release())
{}
};
@@ -95,7 +95,7 @@ namespace NKikimr {
void Process(const TActorContext &ctx) {
auto item = Queue.Head();
Y_VERIFY(item);
- TAutoPtr<IEventHandle> ev = item->Ev.release();
+ TAutoPtr<IEventHandle> ev = item->Ev.release();
Queue.Pop();
switch (ev->GetTypeRewrite()) {
case TEvBlobStorage::EvVMovedPatch: {
@@ -152,7 +152,7 @@ namespace NKikimr {
TOverloadHandler::TOverloadHandler(
const TIntrusivePtr<TVDiskContext> &vctx,
const TPDiskCtxPtr &pdiskCtx,
- std::shared_ptr<THull> hull,
+ std::shared_ptr<THull> hull,
NMonGroup::TSkeletonOverloadGroup &&mon,
TVMovedPatchHandler &&vMovedPatch,
TVPatchStartHandler &&vPatchStart,
@@ -164,7 +164,7 @@ namespace NKikimr {
, Mon(std::move(mon))
, EmergencyQueue(new TEmergencyQueue(Mon, std::move(vMovedPatch), std::move(vPatchStart), std::move(vput),
std::move(vMultiPut), std::move(loc), std::move(aoput)))
- , DynamicPDiskWeightsManager(std::make_shared<TDynamicPDiskWeightsManager>(vctx, pdiskCtx))
+ , DynamicPDiskWeightsManager(std::make_shared<TDynamicPDiskWeightsManager>(vctx, pdiskCtx))
{}
TOverloadHandler::~TOverloadHandler() {}
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.h
index 00707bb803c..39389c4bbd2 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_overload_handler.h
@@ -61,7 +61,7 @@ namespace NKikimr {
TOverloadHandler(
const TIntrusivePtr<TVDiskContext> &vctx,
const TPDiskCtxPtr &pdiskCtx,
- std::shared_ptr<THull> hull,
+ std::shared_ptr<THull> hull,
NMonGroup::TSkeletonOverloadGroup &&mon,
TVMovedPatchHandler &&vMovedPatch,
TVPatchStartHandler &&vPatchStart,
@@ -91,10 +91,10 @@ namespace NKikimr {
void RenderHtml(IOutputStream &str);
private:
- std::shared_ptr<THull> Hull;
+ std::shared_ptr<THull> Hull;
NMonGroup::TSkeletonOverloadGroup Mon;
- std::unique_ptr<TEmergencyQueue> EmergencyQueue;
- std::shared_ptr<TDynamicPDiskWeightsManager> DynamicPDiskWeightsManager;
+ std::unique_ptr<TEmergencyQueue> EmergencyQueue;
+ std::shared_ptr<TDynamicPDiskWeightsManager> DynamicPDiskWeightsManager;
template <class TEv>
bool PostponeEventPrivate(TEv &ev, const TActorContext &ctx, IActor *skeleton);
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
index cc24115b3f0..385da474786 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
@@ -20,7 +20,7 @@ namespace NKikimr {
TString ErrorReason;
ui32 DiffCount = 0;
- std::unique_ptr<TEvBlobStorage::TEvPatch::TDiff[]> Diffs;
+ std::unique_ptr<TEvBlobStorage::TEvPatch::TDiff[]> Diffs;
TActorIDPtr SkeletonFrontIDPtr;
NMonitoring::TDynamicCounters::TCounterPtr MovedPatchResMsgsPtr;
@@ -61,7 +61,7 @@ namespace NKikimr {
PatchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
DiffCount = record.DiffsSize();
- Diffs.reset(new TEvBlobStorage::TEvPatch::TDiff[DiffCount]);
+ Diffs.reset(new TEvBlobStorage::TEvPatch::TDiff[DiffCount]);
for (ui32 idx = 0; idx < DiffCount; ++idx) {
const NKikimrBlobStorage::TDiffBlock &diff = record.GetDiffs(idx);
Y_VERIFY(diff.HasOffset());
@@ -84,7 +84,7 @@ namespace NKikimr {
}
TInstant now = TAppData::TimeProvider->Now();
- auto vMovedPatchResult = std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(status, OriginalId,
+ auto vMovedPatchResult = std::make_unique<TEvBlobStorage::TEvVMovedPatchResult>(status, OriginalId,
PatchedId, vdisk, cookie, OOSStatus, now, Event->Get()->GetCachedByteSize(), &record,
SkeletonFrontIDPtr, MovedPatchResMsgsPtr, nullptr, std::move(TraceId), IncarnationGuid,
ErrorReason);
@@ -98,7 +98,7 @@ namespace NKikimr {
<< " ErrorReason# " << ErrorReason
<< " Marker# BSVSP01");
}
- SendVDiskResponse(ctx, Event->Sender, vMovedPatchResult.release(), *this, Event->Cookie);
+ SendVDiskResponse(ctx, Event->Sender, vMovedPatchResult.release(), *this, Event->Cookie);
PassAway();
}
@@ -146,11 +146,11 @@ namespace NKikimr {
// We have chosen UserData as PutHandleClass on purpose.
// If VMovedPatch and Put were AsyncWrite, it would become a deadlock
// because the put subrequest may not send and the moved patch request will end by timeout.
- std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(PatchedId, Buffer, deadline,
+ std::unique_ptr<TEvBlobStorage::TEvPut> put = std::make_unique<TEvBlobStorage::TEvPut>(PatchedId, Buffer, deadline,
NKikimrBlobStorage::UserData, TEvBlobStorage::TEvPut::TacticDefault);
put->Orbit = std::move(Orbit);
- SendToBSProxy(SelfId(), PatchedGroupId, put.release(), OriginalId.Hash(), std::move(Event->TraceId));
+ SendToBSProxy(SelfId(), PatchedGroupId, put.release(), OriginalId.Hash(), std::move(Event->TraceId));
}
void Handle(TEvBlobStorage::TEvPutResult::TPtr &ev, const TActorContext &ctx) {
@@ -178,11 +178,11 @@ namespace NKikimr {
void Bootstrap() {
TInstant deadline = TActivationContext::Now() + TDuration::MilliSeconds(SubRequestDurationMs);
- std::unique_ptr<TEvBlobStorage::TEvGet> get = std::make_unique<TEvBlobStorage::TEvGet>(OriginalId, 0,
+ std::unique_ptr<TEvBlobStorage::TEvGet> get = std::make_unique<TEvBlobStorage::TEvGet>(OriginalId, 0,
OriginalId.BlobSize(), deadline, NKikimrBlobStorage::AsyncRead);
get->Orbit = std::move(Event->Get()->Orbit);
- SendToBSProxy(SelfId(), OriginalGroupId, get.release(), PatchedId.Hash(), std::move(Event->TraceId));
+ SendToBSProxy(SelfId(), OriginalGroupId, get.release(), PatchedId.Hash(), std::move(Event->TraceId));
Become(&TThis::StateWait);
}
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.cpp
index ac7dcd7d58a..60f6ae33854 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.cpp
@@ -11,7 +11,7 @@ namespace NKikimr {
struct TItem {
NKikimrProto::EReplyStatus Status = NKikimrProto::UNKNOWN;
- TString ErrorReason;
+ TString ErrorReason;
TLogoBlobID BlobId;
ui64 Cookie = 0;
ui32 StatusFlags = 0;
@@ -22,7 +22,7 @@ namespace NKikimr {
return TStringBuilder()
<< "{"
<< " Status# " << NKikimrProto::EReplyStatus_Name(Status)
- << " ErrorReason# " << '"' << EscapeC(ErrorReason) << '"'
+ << " ErrorReason# " << '"' << EscapeC(ErrorReason) << '"'
<< " BlobId# " << BlobId.ToString()
<< " HasCookie# " << HasCookie
<< " Cookie# " << Cookie
@@ -41,13 +41,13 @@ namespace NKikimr {
TActorId LeaderId;
TOutOfSpaceStatus OOSStatus;
- const ui64 IncarnationGuid;
-
+ const ui64 IncarnationGuid;
+
public:
TBufferVMultiPutActor(TActorId leaderId, const TBatchedVec<NKikimrProto::EReplyStatus> &statuses,
TOutOfSpaceStatus oosStatus, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
TActorIDPtr skeletonFrontIDPtr, NMonitoring::TDynamicCounters::TCounterPtr multiPutResMsgsPtr,
- ui64 incarnationGuid)
+ ui64 incarnationGuid)
: TActorBootstrapped()
, Items(ev->Get()->Record.ItemsSize())
, ReceivedResults(0)
@@ -56,7 +56,7 @@ namespace NKikimr {
, Event(ev)
, LeaderId(leaderId)
, OOSStatus(oosStatus)
- , IncarnationGuid(incarnationGuid)
+ , IncarnationGuid(incarnationGuid)
{
Y_VERIFY(statuses.size() == Items.size());
for (ui64 idx = 0; idx < Items.size(); ++idx) {
@@ -78,19 +78,19 @@ namespace NKikimr {
TInstant now = TAppData::TimeProvider->Now();
const ui64 bufferSizeBytes = Event->Get()->GetBufferBytes();
- auto vMultiPutResult = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(NKikimrProto::OK, vdisk, cookie,
- now, Event->Get()->GetCachedByteSize(), &vMultiPutRecord, SkeletonFrontIDPtr, MultiPutResMsgsPtr,
- nullptr, bufferSizeBytes, std::move(Event->TraceId), IncarnationGuid, TString());
+ auto vMultiPutResult = std::make_unique<TEvBlobStorage::TEvVMultiPutResult>(NKikimrProto::OK, vdisk, cookie,
+ now, Event->Get()->GetCachedByteSize(), &vMultiPutRecord, SkeletonFrontIDPtr, MultiPutResMsgsPtr,
+ nullptr, bufferSizeBytes, std::move(Event->TraceId), IncarnationGuid, TString());
for (ui64 idx = 0; idx < Items.size(); ++idx) {
TItem &result = Items[idx];
- vMultiPutResult->AddVPutResult(result.Status, result.ErrorReason, result.BlobId,
- result.HasCookie ? &result.Cookie : nullptr, result.StatusFlags);
+ vMultiPutResult->AddVPutResult(result.Status, result.ErrorReason, result.BlobId,
+ result.HasCookie ? &result.Cookie : nullptr, result.StatusFlags);
}
vMultiPutResult->Record.SetStatusFlags(OOSStatus.Flags);
- SendVDiskResponse(ctx, Event->Sender, vMultiPutResult.release(), *this, Event->Cookie);
+ SendVDiskResponse(ctx, Event->Sender, vMultiPutResult.release(), *this, Event->Cookie);
PassAway();
}
@@ -104,7 +104,7 @@ namespace NKikimr {
Y_VERIFY(!item.Received, "itemIdx# %" PRIu64 " item# %s", idx, item.ToString().data());
item.Received = true;
item.Status = ev->Get()->Status;
- item.ErrorReason = ev->Get()->ErrorReason;
+ item.ErrorReason = ev->Get()->ErrorReason;
ReceivedResults++;
@@ -127,7 +127,7 @@ namespace NKikimr {
item.Received = true;
Y_VERIFY(record.HasStatus());
item.Status = record.GetStatus();
- item.ErrorReason = record.GetErrorReason();
+ item.ErrorReason = record.GetErrorReason();
ReceivedResults++;
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.h b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.h
index 1eebe004567..13ac2abbaf4 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.h
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmultiput_actor.h
@@ -8,24 +8,24 @@
namespace NKikimr {
-struct TEvVMultiPutItemResult : TEventLocal<TEvVMultiPutItemResult, TEvBlobStorage::EvVMultiPutItemResult> {
+struct TEvVMultiPutItemResult : TEventLocal<TEvVMultiPutItemResult, TEvBlobStorage::EvVMultiPutItemResult> {
TLogoBlobID BlobId;
ui64 ItemIdx;
NKikimrProto::EReplyStatus Status;
- TString ErrorReason;
+ TString ErrorReason;
- TEvVMultiPutItemResult(TLogoBlobID id, ui64 itemIdx, NKikimrProto::EReplyStatus status, TString errorReason)
+ TEvVMultiPutItemResult(TLogoBlobID id, ui64 itemIdx, NKikimrProto::EReplyStatus status, TString errorReason)
: TEventLocal()
, BlobId(id)
, ItemIdx(itemIdx)
, Status(status)
- , ErrorReason(std::move(errorReason))
+ , ErrorReason(std::move(errorReason))
{}
};
IActor* CreateSkeletonVMultiPutActor(TActorId leaderId, const TBatchedVec<NKikimrProto::EReplyStatus> &statuses,
TOutOfSpaceStatus oosStatus, TEvBlobStorage::TEvVMultiPut::TPtr &ev,
TActorIDPtr skeletonFrontIDPtr, NMonitoring::TDynamicCounters::TCounterPtr multiPutResMsgsPtr,
- ui64 incarnationGuid);
+ ui64 incarnationGuid);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor.cpp
index b04e8d6d8fe..1505a098fb1 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor.cpp
@@ -58,12 +58,12 @@ namespace NKikimr::NPrivate {
struct TXorDiffs {
TVector<TDiff> Diffs;
ui8 PartId;
- std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> ResultEvent;
+ std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> ResultEvent;
TActorId Sender;
ui64 Cookie;
- TXorDiffs(TVector<TDiff> &&diffs, ui8 partId, std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> &&result,
+ TXorDiffs(TVector<TDiff> &&diffs, ui8 partId, std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> &&result,
const TActorId &sender, ui64 cookie)
: Diffs(std::move(diffs))
, PartId(partId)
@@ -108,8 +108,8 @@ namespace NKikimr::NPrivate {
TString ErrorReason;
- std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts> FoundPartsEvent;
- std::unique_ptr<TEvBlobStorage::TEvVPatchResult> ResultEvent;
+ std::unique_ptr<TEvBlobStorage::TEvVPatchFoundParts> FoundPartsEvent;
+ std::unique_ptr<TEvBlobStorage::TEvVPatchResult> ResultEvent;
TBlobStorageGroupType GType;
@@ -149,7 +149,7 @@ namespace NKikimr::NPrivate {
Y_VERIFY(record.HasVDiskID());
VDiskId = VDiskIDFromVDiskID(record.GetVDiskID());
Y_VERIFY(record.HasCookie());
- FoundPartsEvent = std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(
+ FoundPartsEvent = std::make_unique<TEvBlobStorage::TEvVPatchFoundParts>(
NKikimrProto::OK, OriginalBlobId, PatchedBlobId, VDiskId, record.GetCookie(), now, ErrorReason, &record,
SkeletonFrontIDPtr, VPatchFoundPartsMsgsPtr, nullptr,
std::move(ev->TraceId), IncarnationGuid);
@@ -161,11 +161,11 @@ namespace NKikimr::NPrivate {
(OriginalBlobId, OriginalBlobId),
(Deadline, Deadline));
ui32 cookie = 0;
- std::unique_ptr<TEvBlobStorage::TEvVGet> msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskId, Deadline,
+ std::unique_ptr<TEvBlobStorage::TEvVGet> msg = TEvBlobStorage::TEvVGet::CreateRangeIndexQuery(VDiskId, Deadline,
NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None, cookie,
OriginalBlobId, TLogoBlobID(OriginalBlobId, TLogoBlobID::MaxPartId),
TLogoBlobID::MaxPartId, nullptr, false);
- Send(LeaderId, msg.release());
+ Send(LeaderId, msg.release());
Become(&TThis::StartState);
@@ -184,7 +184,7 @@ namespace NKikimr::NPrivate {
FoundPartsEvent->AddPart(part);
}
FoundPartsEvent->SetStatus(status);
- SendVDiskResponse(TActivationContext::AsActorContext(), Sender, FoundPartsEvent.release(), *this, Cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), Sender, FoundPartsEvent.release(), *this, Cookie);
}
void PullOriginalPart(ui64 pullingPart) {
@@ -193,12 +193,12 @@ namespace NKikimr::NPrivate {
(OriginalBlobId, OriginalBlobId),
(PullingPart, pullingPart));
ui32 cookie = 0;
- std::unique_ptr<TEvBlobStorage::TEvVGet> msg = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, Deadline,
+ std::unique_ptr<TEvBlobStorage::TEvVGet> msg = TEvBlobStorage::TEvVGet::CreateExtremeDataQuery(VDiskId, Deadline,
NKikimrBlobStorage::EGetHandleClass::FastRead, TEvBlobStorage::TEvVGet::EFlags::None, cookie,
{}, false);
TLogoBlobID id(OriginalBlobId, pullingPart);
msg->AddExtremeQuery(id, 0, 0, &pullingPart);
- Send(LeaderId, msg.release());
+ Send(LeaderId, msg.release());
}
void HandleVGetRangeResult(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
@@ -254,7 +254,7 @@ namespace NKikimr::NPrivate {
(ErrorReason, ErrorReason));
Y_VERIFY(ResultEvent);
ResultEvent->SetStatus(status, ErrorReason);
- SendVDiskResponse(TActivationContext::AsActorContext(), Sender, ResultEvent.release(), *this, Cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), Sender, ResultEvent.release(), *this, Cookie);
}
void HandleVGetResult(TEvBlobStorage::TEvVGetResult::TPtr &ev) {
@@ -316,7 +316,7 @@ namespace NKikimr::NPrivate {
for (ui32 idx = ReceivedXorDiffs.size(); idx != 0; --idx) {
auto &[diffs, partId, result, sender, cookie] = ReceivedXorDiffs.back();
GType.ApplyXorDiff(TErasureType::CrcModeNone, dataSize, buffer, diffs, partId - 1, toPart - 1);
- SendVDiskResponse(TActivationContext::AsActorContext(), sender, result.release(), *this, cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), sender, result.release(), *this, cookie);
ReceivedXorDiffs.pop_back();
}
@@ -381,7 +381,7 @@ namespace NKikimr::NPrivate {
GType.MakeXorDiff(TErasureType::CrcModeNone, OriginalBlobId.BlobSize(), buffer, Diffs, &xorDiffs);
for (TXorReceiver &xorReceiver : XorReceivers) {
- std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiff> xorDiff = std::make_unique<TEvBlobStorage::TEvVPatchXorDiff>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiff> xorDiff = std::make_unique<TEvBlobStorage::TEvVPatchXorDiff>(
TLogoBlobID(OriginalBlobId, xorReceiver.PartId),
TLogoBlobID(PatchedBlobId, xorReceiver.PartId),
xorReceiver.VDiskId, OriginalPartId, Deadline, 0);
@@ -402,7 +402,7 @@ namespace NKikimr::NPrivate {
NKikimrBlobStorage::TExecTimeStats &execTimeStats = *msgQoS.MutableExecTimeStats();
execTimeStats.SetSubmitTimestamp(now.GetValue());
- Send(it->second, xorDiff.release());
+ Send(it->second, xorDiff.release());
}
}
@@ -414,15 +414,15 @@ namespace NKikimr::NPrivate {
(OriginalPartId, (ui32)OriginalPartId),
(PatchedPartId, (ui32)PatchedPartId));
ui64 cookie = OriginalBlobId.Hash();
- std::unique_ptr<IEventBase> put = std::make_unique<TEvBlobStorage::TEvVPut>(TLogoBlobID(PatchedBlobId, PatchedPartId),
+ std::unique_ptr<IEventBase> put = std::make_unique<TEvBlobStorage::TEvVPut>(TLogoBlobID(PatchedBlobId, PatchedPartId),
Buffer, VDiskId, false, &cookie, Deadline, NKikimrBlobStorage::AsyncBlob);
- Send(LeaderId, put.release());
+ Send(LeaderId, put.release());
}
void HandleError(TEvBlobStorage::TEvVPatchDiff::TPtr &ev) {
NKikimrBlobStorage::TEvVPatchDiff &record = ev->Get()->Record;
TInstant now = TActivationContext::Now();
- ResultEvent = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
+ ResultEvent = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
NKikimrProto::OK, TLogoBlobID(OriginalBlobId, OriginalPartId),
TLogoBlobID(PatchedBlobId, PatchedPartId), VDiskId, record.GetCookie(), now,
&record, SkeletonFrontIDPtr, VPatchResMsgsPtr, nullptr,
@@ -465,7 +465,7 @@ namespace NKikimr::NPrivate {
Y_VERIFY(!ResultEvent);
TInstant now = TActivationContext::Now();
- ResultEvent = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
+ ResultEvent = std::make_unique<TEvBlobStorage::TEvVPatchResult>(
NKikimrProto::OK, originalPartBlobId, patchedPartBlobId, VDiskId, record.GetCookie(), now,
&record, SkeletonFrontIDPtr, VPatchResMsgsPtr, nullptr,
std::move(ev->TraceId), IncarnationGuid);
@@ -525,10 +525,10 @@ namespace NKikimr::NPrivate {
void HandleError(TEvBlobStorage::TEvVPatchXorDiff::TPtr &ev) {
NKikimrBlobStorage::TEvVPatchXorDiff &record = ev->Get()->Record;
TInstant now = TActivationContext::Now();
- auto resultEvent = std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(
+ auto resultEvent = std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(
NKikimrProto::ERROR, now, &record, SkeletonFrontIDPtr, VPatchResMsgsPtr, nullptr,
std::move(ev->TraceId));
- SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
}
void Handle(TEvBlobStorage::TEvVPatchXorDiff::TPtr &ev) {
@@ -549,14 +549,14 @@ namespace NKikimr::NPrivate {
(ReceivedXorDiffCount, TStringBuilder() << ReceivedXorDiffCount << '/' << WaitedXorDiffCount));
TInstant now = TActivationContext::Now();
- std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> resultEvent = std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiffResult> resultEvent = std::make_unique<TEvBlobStorage::TEvVPatchXorDiffResult>(
NKikimrProto::OK, now, &record, SkeletonFrontIDPtr, VPatchResMsgsPtr, nullptr, std::move(ev->TraceId));
if (!CheckDiff(xorDiffs, "XorDiff from datapart")) {
for (auto &[diffs, partId, result, sender, cookie] : ReceivedXorDiffs) {
- SendVDiskResponse(TActivationContext::AsActorContext(), sender, result.release(), *this, cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), sender, result.release(), *this, cookie);
}
- SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
if (ResultEvent) {
SendVPatchResult(NKikimrProto::ERROR);
@@ -577,7 +577,7 @@ namespace NKikimr::NPrivate {
}
xorDiffs.clear();
- SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
+ SendVDiskResponse(TActivationContext::AsActorContext(), ev->Sender, resultEvent.release(), *this, ev->Cookie);
} else {
ReceivedXorDiffs.emplace_back(std::move(xorDiffs), fromPart, std::move(resultEvent),
ev->Sender, ev->Cookie);
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor_ut.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor_ut.cpp
index ca54eeec88c..934d0213dbc 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vpatch_actor_ut.cpp
@@ -50,9 +50,9 @@ namespace NKikimr {
virtual ~TVPatchDecorator() {
if (NActors::TlsActivationContext) {
- std::unique_ptr<IEventBase> ev = std::make_unique<TEvRequestEnd>();
- std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(EdgeActor, EdgeActor, ev.release());
- TActivationContext::Send(handle.release());
+ std::unique_ptr<IEventBase> ev = std::make_unique<TEvRequestEnd>();
+ std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(EdgeActor, EdgeActor, ev.release());
+ TActivationContext::Send(handle.release());
}
}
@@ -147,14 +147,14 @@ namespace NKikimr {
Runtime.SetLogPriority(NActorsServices::TEST, NLog::PRI_DEBUG);
}
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> CreateVPatchStart(TMaybe<ui64> cookie, ui32 nodeId = 0) const {
- return std::make_unique<TEvBlobStorage::TEvVPatchStart>(OriginalBlobId, PatchedBlobId, VDiskIds[nodeId], Deadline,
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> CreateVPatchStart(TMaybe<ui64> cookie, ui32 nodeId = 0) const {
+ return std::make_unique<TEvBlobStorage::TEvVPatchStart>(OriginalBlobId, PatchedBlobId, VDiskIds[nodeId], Deadline,
cookie, false);
}
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> CreateVPatchDiff(ui8 partId, ui8 waitedXorDiffs,
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> CreateVPatchDiff(ui8 partId, ui8 waitedXorDiffs,
const TVector<TDiff> &diffs, TMaybe<ui64> cookie, ui8 nodeId = 0) const {
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(TLogoBlobID(OriginalBlobId, partId),
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(TLogoBlobID(OriginalBlobId, partId),
TLogoBlobID(PatchedBlobId, partId), VDiskIds[nodeId], waitedXorDiffs, Deadline, cookie);
for (auto &diffBlock : diffs) {
diff->AddDiff(diffBlock.Offset, diffBlock.Buffer);
@@ -162,8 +162,8 @@ namespace NKikimr {
return std::move(diff);
}
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> CreateForceEndVPatchDiff(ui8 partId, TMaybe<ui64> cookie) const {
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(TLogoBlobID(OriginalBlobId, partId),
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> CreateForceEndVPatchDiff(ui8 partId, TMaybe<ui64> cookie) const {
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = std::make_unique<TEvBlobStorage::TEvVPatchDiff>(TLogoBlobID(OriginalBlobId, partId),
TLogoBlobID(PatchedBlobId, partId), VDiskIds[partId - 1], false, Deadline, cookie);
diff->SetForceEnd();
return std::move(diff);
@@ -197,12 +197,12 @@ namespace NKikimr {
}
void ForceEndTest() {
- std::unique_ptr<IEventHandle> handle;
+ std::unique_ptr<IEventHandle> handle;
ui32 nodeCount = Runtime.GetNodeCount();
for (ui32 nodeId = 0; nodeId < nodeCount; ++nodeId) {
- handle = std::make_unique<IEventHandle>(VPatchActorIds[nodeId], EdgeActors[nodeId],
+ handle = std::make_unique<IEventHandle>(VPatchActorIds[nodeId], EdgeActors[nodeId],
new NActors::TEvents::TEvPoisonPill);
- Runtime.Send(handle.release());
+ Runtime.Send(handle.release());
}
WaitEndTest();
}
@@ -210,9 +210,9 @@ namespace NKikimr {
template<typename EventType>
typename EventType::TPtr CreateEventHandle(const TActorId &recipient, const TActorId &sender,
- std::unique_ptr<EventType> &&ev)
+ std::unique_ptr<EventType> &&ev)
{
- return static_cast<TEventHandle<EventType>*>(new IEventHandle(recipient, sender, ev.release()));
+ return static_cast<TEventHandle<EventType>*>(new IEventHandle(recipient, sender, ev.release()));
}
@@ -251,7 +251,7 @@ namespace NKikimr {
UNIT_ASSERT(evVGetRange->Record.HasCookie());
UNIT_ASSERT(evVGetRange->Record.HasIndexOnly() && evVGetRange->Record.GetIndexOnly());
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> evVGetRangeResult = std::make_unique<TEvBlobStorage::TEvVGetResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> evVGetRangeResult = std::make_unique<TEvBlobStorage::TEvVGetResult>(
vGetStatus, testData.VDiskIds[nodeId], testData.Now, evVGetRange->GetCachedByteSize(), &evVGetRange->Record,
nullptr, nullptr, nullptr, std::move(handle->TraceId), evVGetRange->Record.GetCookie(),
handle->GetChannel(), 0);
@@ -260,7 +260,7 @@ namespace NKikimr {
for (ui8 partId : foundParts) {
evVGetRangeResult->Record.MutableResult(0)->AddParts(partId);
}
- handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, evVGetRangeResult.release());
+ handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, evVGetRangeResult.release());
runtime.Send(handle.Release());
auto evVPatchFoundParts = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvVPatchFoundParts>(handle);
@@ -296,15 +296,15 @@ namespace NKikimr {
testData.SequenceOfReceivingEvents = std::move(receivingEvents);
testData.SequenceOfSendingEvents = std::move(sendingEvents);
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
TEvBlobStorage::TEvVPatchStart::TPtr ev = CreateEventHandle(edgeActor, edgeActor, std::move(start));
TActorId vPatchActorId = testData.CreateTVPatchActor<TVPatchDecorator>(std::move(ev));
bool isKilled = PassFindingParts(testData, vGetStatus, foundParts);
TAutoPtr<IEventHandle> handle;
if (!isKilled) {
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateForceEndVPatchDiff(1, 0);
- handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, diff.release());
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateForceEndVPatchDiff(1, 0);
+ handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, diff.release());
testData.Runtime.Send(handle.Release());
auto result = testData.Runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvVPatchResult>(handle);
@@ -376,7 +376,7 @@ namespace NKikimr {
TEvBlobStorage::EvVPatchFoundParts,
TEvBlobStorage::EvVPatchDyingRequest};
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
TEvBlobStorage::TEvVPatchStart::TPtr ev = CreateEventHandle(edgeActor, edgeActor, std::move(start));
TActorId actorId = testData.CreateTVPatchActor<TVPatchDecorator>(std::move(ev));
@@ -405,14 +405,14 @@ namespace NKikimr {
UNIT_ASSERT(evVGet->Record.HasCookie());
UNIT_ASSERT(!evVGet->Record.HasIndexOnly() || !evVGet->Record.GetIndexOnly());
- std::unique_ptr<TEvBlobStorage::TEvVGetResult> evVGetResult = std::make_unique<TEvBlobStorage::TEvVGetResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVGetResult> evVGetResult = std::make_unique<TEvBlobStorage::TEvVGetResult>(
vGetStatus, testData.VDiskIds[nodeId], testData.Now, evVGet->GetCachedByteSize(), &evVGet->Record,
nullptr, nullptr, nullptr, std::move(vGetHandle->TraceId), evVGet->Record.GetCookie(),
vGetHandle->GetChannel(), 0);
evVGetResult->AddResult(NKikimrProto::OK, blob.BlobId, 0, blob.Buffer.data(), blob.Buffer.size());
- std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, evVGetResult.release());
- runtime.Send(handle.release());
+ std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, evVGetResult.release());
+ runtime.Send(handle.release());
return vGetStatus != NKikimrProto::OK;
}
@@ -435,12 +435,12 @@ namespace NKikimr {
UNIT_ASSERT_C(vPut->GetBuffer() == blob.Buffer, "NodeId# " << nodeId);
TOutOfSpaceStatus oos = TOutOfSpaceStatus(testData.StatusFlags, testData.ApproximateFreeSpaceShare);
- std::unique_ptr<TEvBlobStorage::TEvVPutResult> vPutResult = std::make_unique<TEvBlobStorage::TEvVPutResult>(
+ std::unique_ptr<TEvBlobStorage::TEvVPutResult> vPutResult = std::make_unique<TEvBlobStorage::TEvVPutResult>(
vPutStatus, blobId, testData.VDiskIds[nodeId], &cookie, oos, testData.Now,
0, &record, nullptr, nullptr, nullptr, vPut->GetBufferBytes(), std::move(handle->TraceId),
0, "");
- handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, vPutResult.release());
+ handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, vPutResult.release());
runtime.Send(handle.Release());
return true;
}
@@ -459,7 +459,7 @@ namespace NKikimr {
testData.SequenceOfReceivingEvents = std::move(receivingEvents);
testData.SequenceOfSendingEvents = std::move(sendingEvents);
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
TEvBlobStorage::TEvVPatchStart::TPtr ev = CreateEventHandle(edgeActor, edgeActor, std::move(start));
TActorId vPatchActorId = testData.CreateTVPatchActor<TVPatchDecorator>(std::move(ev));
@@ -468,10 +468,10 @@ namespace NKikimr {
isKilled = PassFindingParts(testData, NKikimrProto::OK, foundPartIds);
UNIT_ASSERT(!isKilled);
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(pullingPart, false, {}, 0);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(pullingPart, false, {}, 0);
TAutoPtr<IEventHandle> handle;
- handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, diff.release());
+ handle = MakeHolder<IEventHandle>(vPatchActorId, edgeActor, diff.release());
runtime.Send(handle.Release());
TBlob pullingBlob(testData.OriginalBlobId, pullingPart, partSize);
@@ -557,7 +557,7 @@ namespace NKikimr {
TActorId vPatchActorId = testData.VPatchActorIds[nodeId];
TVDiskID vDiskId = testData.VDiskIds[nodeId];
- std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiff> xorDiff = std::make_unique<TEvBlobStorage::TEvVPatchXorDiff>(
+ std::unique_ptr<TEvBlobStorage::TEvVPatchXorDiff> xorDiff = std::make_unique<TEvBlobStorage::TEvVPatchXorDiff>(
TLogoBlobID(testData.OriginalBlobId, toPart),
TLogoBlobID(testData.PatchedBlobId, toPart),
vDiskId, toPart, testData.Deadline, 0);
@@ -565,8 +565,8 @@ namespace NKikimr {
xorDiff->AddDiff(diff.Offset, diff.Buffer);
}
- std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, xorDiff.release());
- runtime.Send(handle.release());
+ std::unique_ptr<IEventHandle> handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, xorDiff.release());
+ runtime.Send(handle.release());
}
void ReceiveVPatchResult(TVPatchTestGeneralData &testData, NKikimrProto::EReplyStatus status) {
@@ -587,7 +587,7 @@ namespace NKikimr {
testData.SequenceOfReceivingEvents = std::move(receivingEvents);
testData.SequenceOfSendingEvents = std::move(sendingEvents);
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(0);
TEvBlobStorage::TEvVPatchStart::TPtr ev = CreateEventHandle(edgeActor, edgeActor, std::move(start));
TActorId vPatchActorId = testData.CreateTVPatchActor<TVPatchDecorator>(std::move(ev));
@@ -597,11 +597,11 @@ namespace NKikimr {
UNIT_ASSERT(!isKilled);
SendXorDiff(testData, diffs, type.DataParts());
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, 1, {}, 0);
- std::unique_ptr<IEventHandle> handle;
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, 1, {}, 0);
+ std::unique_ptr<IEventHandle> handle;
- handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, diff.release());
- runtime.Send(handle.release());
+ handle = std::make_unique<IEventHandle>(vPatchActorId, edgeActor, diff.release());
+ runtime.Send(handle.release());
if (status != NKikimrProto::OK) {
TAutoPtr<IEventHandle> handle;
@@ -680,7 +680,7 @@ namespace NKikimr {
TVPatchTestGeneralData testData(type, data.Size(), nodeCount);
for (ui32 nodeIdx = 0; nodeIdx < nodeCount; ++nodeIdx) {
- std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(nodeIdx, nodeIdx);
+ std::unique_ptr<TEvBlobStorage::TEvVPatchStart> start = testData.CreateVPatchStart(nodeIdx, nodeIdx);
TActorId edgeActor = testData.EdgeActors[nodeIdx];
TEvBlobStorage::TEvVPatchStart::TPtr ev = CreateEventHandle(edgeActor, edgeActor, std::move(start));
testData.CreateTVPatchActor<TVPatchDecorator>(std::move(ev), nodeIdx);
@@ -714,17 +714,17 @@ namespace NKikimr {
ui32 dataDiffCount = 0;
for (ui32 partIdx = 0; partIdx < dataPartCount; ++partIdx) {
ui32 partId = partIdx + 1;
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, 0,
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, 0,
diffSet.PartDiffs[partIdx].Diffs, 0, partIdx);
for (ui32 parityPartIdx = dataPartCount; parityPartIdx < totalPartCount; ++parityPartIdx) {
diff->AddXorReceiver(testData.VDiskIds[parityPartIdx], parityPartIdx + 1);
}
- std::unique_ptr<IEventHandle> handle;
- handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
- diff.release());
- testData.Runtime.Send(handle.release());
+ std::unique_ptr<IEventHandle> handle;
+ handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
+ diff.release());
+ testData.Runtime.Send(handle.release());
dataDiffCount++;
}
@@ -737,12 +737,12 @@ namespace NKikimr {
if (!quickXorDiffs) {
for (ui32 partIdx = dataPartCount; partIdx < totalPartCount; ++partIdx) {
ui32 partId = partIdx + 1;
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, dataDiffCount,
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, dataDiffCount,
{}, 0, partIdx);
- std::unique_ptr<IEventHandle> handle;
- handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
- diff.release());
- testData.Runtime.Send(handle.release());
+ std::unique_ptr<IEventHandle> handle;
+ handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
+ diff.release());
+ testData.Runtime.Send(handle.release());
}
for (ui32 partIdx = dataPartCount; partIdx < totalPartCount; ++partIdx) {
@@ -772,9 +772,9 @@ namespace NKikimr {
}
TActorId patchActor = testData.VPatchActorIds[patchedPartId - 1];
- auto handle2 = std::make_unique<IEventHandle>(patchActor, edgeActor, handle->Release().Release(), handle->Flags,
+ auto handle2 = std::make_unique<IEventHandle>(patchActor, edgeActor, handle->Release().Release(), handle->Flags,
handle->Cookie, nullptr, std::move(handle->TraceId));
- testData.Runtime.Send(handle2.release());
+ testData.Runtime.Send(handle2.release());
}
}
@@ -785,12 +785,12 @@ namespace NKikimr {
if (quickXorDiffs) {
for (ui32 partIdx = dataPartCount; partIdx < totalPartCount; ++partIdx) {
ui32 partId = partIdx + 1;
- std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, dataDiffCount,
+ std::unique_ptr<TEvBlobStorage::TEvVPatchDiff> diff = testData.CreateVPatchDiff(partId, dataDiffCount,
{}, 0, partIdx);
- std::unique_ptr<IEventHandle> handle;
- handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
- diff.release());
- testData.Runtime.Send(handle.release());
+ std::unique_ptr<IEventHandle> handle;
+ handle = std::make_unique<IEventHandle>(testData.VPatchActorIds[partIdx], testData.EdgeActors[partIdx],
+ diff.release());
+ testData.Runtime.Send(handle.release());
}
for (ui32 partIdx = dataPartCount; partIdx < totalPartCount; ++partIdx) {
diff --git a/ydb/core/blobstorage/vdisk/skeleton/ya.make b/ydb/core/blobstorage/vdisk/skeleton/ya.make
index 892b79e6e12..0524fd8ebe1 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/ya.make
+++ b/ydb/core/blobstorage/vdisk/skeleton/ya.make
@@ -24,7 +24,7 @@ SRCS(
blobstorage_syncfullhandler.cpp
blobstorage_syncfullhandler.h
blobstorage_takedbsnap.h
- skeleton_capturevdisklayout.h
+ skeleton_capturevdisklayout.h
skeleton_compactionstate.cpp
skeleton_compactionstate.h
skeleton_events.h
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer.cpp
index bf0179b4ed9..be4275e10ad 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer.cpp
@@ -28,15 +28,15 @@ namespace NKikimr {
using TItem = TEvBlobStorage::TEvVSyncGuidResult;
public:
- ui64 WriteRequest(const TActorId &id, std::unique_ptr<TItem> &&r) {
+ ui64 WriteRequest(const TActorId &id, std::unique_ptr<TItem> &&r) {
ui64 seqNum = ++InFlySeqNum;
Queue.emplace_back(id, std::move(r), seqNum);
return seqNum;
}
- void ReadRequest(const TActorContext &ctx, const TActorId &id, std::unique_ptr<TItem> &&r) {
+ void ReadRequest(const TActorContext &ctx, const TActorId &id, std::unique_ptr<TItem> &&r) {
if (CommittedSeqNum == InFlySeqNum) {
- ctx.Send(id, r.release());
+ ctx.Send(id, r.release());
} else {
Queue.emplace_back(id, std::move(r), InFlySeqNum);
}
@@ -48,7 +48,7 @@ namespace NKikimr {
while (!Queue.empty() && Queue.front().SeqNum <= CommittedSeqNum) {
auto &elem = Queue.front();
- ctx.Send(elem.ActorId, elem.Item.release());
+ ctx.Send(elem.ActorId, elem.Item.release());
Queue.pop_front();
}
}
@@ -56,10 +56,10 @@ namespace NKikimr {
private:
struct TItemAndSeq {
TActorId ActorId;
- std::unique_ptr<TItem> Item;
+ std::unique_ptr<TItem> Item;
ui64 SeqNum;
- TItemAndSeq(const TActorId &id, std::unique_ptr<TItem> &&r, ui64 seqNum)
+ TItemAndSeq(const TActorId &id, std::unique_ptr<TItem> &&r, ui64 seqNum)
: ActorId(id)
, Item(std::move(r))
, SeqNum(seqNum)
@@ -125,14 +125,14 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
+ STRICT_STFUNC(StateFunc,
HFunc(NMon::TEvHttpInfoRes, Handle)
HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_HTTPREQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_HTTPREQ;
}
TSyncerHttpInfoActor(TIntrusivePtr<TSyncerContext> &sc,
@@ -176,7 +176,7 @@ namespace NKikimr {
TVector<TActorId> PropagatorIds;
EPhase Phase = TPhaseVal::PhaseNone;
TActiveActors ActiveActors;
- std::unique_ptr<NSyncer::TOutcome> GuidRecovOutcome;
+ std::unique_ptr<NSyncer::TOutcome> GuidRecovOutcome;
TDelayedQueue DelayedQueue;
TSublog<> Sublog;
@@ -220,8 +220,8 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
void SyncGuid(const TActorContext &ctx) {
Become(&TThis::SyncGuidStateFunc);
- GuidRecoveryId = ctx.Register(CreateVDiskGuidRecoveryActor(SyncerCtx->VCtx, GInfo, CommitterId, SelfId(),
- LocalSyncerState));
+ GuidRecoveryId = ctx.Register(CreateVDiskGuidRecoveryActor(SyncerCtx->VCtx, GInfo, CommitterId, SelfId(),
+ LocalSyncerState));
ActiveActors.Insert(GuidRecoveryId);
Phase = TPhaseVal::PhaseSyncGuid;
}
@@ -229,7 +229,7 @@ namespace NKikimr {
void Handle(TEvVDiskGuidRecovered::TPtr &ev, const TActorContext &ctx) {
ActiveActors.Erase(ev->Sender);
GuidRecoveryId = TActorId();
- GuidRecovOutcome = std::make_unique<NSyncer::TOutcome>(std::move(ev->Get()->Outcome));
+ GuidRecovOutcome = std::make_unique<NSyncer::TOutcome>(std::move(ev->Get()->Outcome));
switch (GuidRecovOutcome->Decision) {
case EDecision::FirstRun:
@@ -247,18 +247,18 @@ namespace NKikimr {
}
}
- STRICT_STFUNC(SyncGuidStateFunc,
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(TEvVDiskGuidRecovered, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
+ STRICT_STFUNC(SyncGuidStateFunc,
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(TEvVDiskGuidRecovered, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, SyncGuidModeHandle)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, SyncGuidModeHandle)
+ )
////////////////////////////////////////////////////////////////////////
// Inconsistent State
@@ -270,17 +270,17 @@ namespace NKikimr {
ctx.Send(SyncerData->NotifyId, new TEvSyncGuidRecoveryDone(NKikimrProto::ERROR, 0));
}
- STRICT_STFUNC(InconsistentancyStateFunc,
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
+ STRICT_STFUNC(InconsistentancyStateFunc,
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, InconsistencyModeHandle)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, InconsistencyModeHandle)
+ )
////////////////////////////////////////////////////////////////////////
// Recover Lost Data
@@ -288,7 +288,7 @@ namespace NKikimr {
void RecoverLostData(const TActorContext &ctx) {
Become(&TThis::RecoverLostDataStateFunc);
const TVDiskEternalGuid guid = GuidRecovOutcome->Guid;
- RecoverLostDataId = ctx.Register(CreateSyncerRecoverLostDataActor(SyncerCtx, GInfo, CommitterId, ctx.SelfID, guid));
+ RecoverLostDataId = ctx.Register(CreateSyncerRecoverLostDataActor(SyncerCtx, GInfo, CommitterId, ctx.SelfID, guid));
ActiveActors.Insert(RecoverLostDataId);
Phase = TPhaseVal::PhaseRecoverLostData;
}
@@ -300,26 +300,26 @@ namespace NKikimr {
StandardMode(ctx);
}
- STRICT_STFUNC(RecoverLostDataStateFunc,
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(TEvSyncerLostDataRecovered, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
+ STRICT_STFUNC(RecoverLostDataStateFunc,
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(TEvSyncerLostDataRecovered, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, RecoverLostDataModeHandle)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, RecoverLostDataModeHandle)
+ )
////////////////////////////////////////////////////////////////////////
// Standard Mode
////////////////////////////////////////////////////////////////////////
void StandardMode(const TActorContext &ctx) {
// notify synclog that it can start serving requests, tell him the DbBirthLsn
- auto msg = std::make_unique<NSyncLog::TEvSyncLogDbBirthLsn>(LocalSyncerState.DbBirthLsn);
- ctx.Send(SyncerCtx->SyncLogId, msg.release());
+ auto msg = std::make_unique<NSyncLog::TEvSyncLogDbBirthLsn>(LocalSyncerState.DbBirthLsn);
+ ctx.Send(SyncerCtx->SyncLogId, msg.release());
RunPropagators(ctx);
// notify Skeleton about SyncGuid recovery state
@@ -327,22 +327,22 @@ namespace NKikimr {
new TEvSyncGuidRecoveryDone(NKikimrProto::OK, LocalSyncerState.DbBirthLsn));
SyncerData->Neighbors->DbBirthLsn = LocalSyncerState.DbBirthLsn;
Become(&TThis::StandardModeStateFunc);
- SchedulerId = ctx.Register(CreateSyncerSchedulerActor(SyncerCtx, GInfo, SyncerData, CommitterId));
- ActiveActors.Insert(SchedulerId);
+ SchedulerId = ctx.Register(CreateSyncerSchedulerActor(SyncerCtx, GInfo, SyncerData, CommitterId));
+ ActiveActors.Insert(SchedulerId);
Phase = TPhaseVal::PhaseStandardMode;
}
- STRICT_STFUNC(StandardModeStateFunc,
- HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
+ STRICT_STFUNC(StandardModeStateFunc,
+ HFunc(TEvBlobStorage::TEvVSyncGuid, Handle)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, ReadyModeHandle)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, ReadyModeHandle)
+ )
////////////////////////////////////////////////////////////////////////
// Handle EvVSyncGuid
@@ -363,23 +363,23 @@ namespace NKikimr {
auto &data = (*SyncerData->Neighbors)[vdisk].Get().PeerGuidInfo;
data.Info = info;
// create reply
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(NKikimrProto::OK, selfVDisk,
- TAppData::TimeProvider->Now(), nullptr, nullptr, std::move(ev->TraceId), ev->GetChannel());
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(NKikimrProto::OK, selfVDisk,
+ TAppData::TimeProvider->Now(), nullptr, nullptr, std::move(ev->TraceId), ev->GetChannel());
// put reply into the queue and wait until it would be committed
ui64 seqNum = DelayedQueue.WriteRequest(ev->Sender, std::move(result));
// commit
void *cookie = reinterpret_cast<void*>(intptr_t(seqNum));
auto msg = TEvSyncerCommit::Remote(vdisk, state, guid, cookie);
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
} else {
// handle READ request
auto &data = (*SyncerData->Neighbors)[vdisk].Get().PeerGuidInfo.Info;
auto state = data.GetState();
auto guid = data.GetGuid();
// create reply
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(NKikimrProto::OK, selfVDisk,
- TAppData::TimeProvider->Now(), guid, state, nullptr, nullptr, std::move(ev->TraceId),
- ev->GetChannel());
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncGuidResult>(NKikimrProto::OK, selfVDisk,
+ TAppData::TimeProvider->Now(), guid, state, nullptr, nullptr, std::move(ev->TraceId),
+ ev->GetChannel());
// put reply into the queue and wait until all required writes are committed
DelayedQueue.ReadRequest(ctx, ev->Sender, std::move(result));
}
@@ -449,8 +449,8 @@ namespace NKikimr {
TStringStream str;
LogAndPhaseToHtml(str);
// create an actor to handle request
- auto actor = std::make_unique<TSyncerHttpInfoActor>(SyncerCtx, ev, ctx.SelfID, schId, str.Str());
- auto aid = ctx.Register(actor.release());
+ auto actor = std::make_unique<TSyncerHttpInfoActor>(SyncerCtx, ev, ctx.SelfID, schId, str.Str());
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
}
@@ -466,10 +466,10 @@ namespace NKikimr {
if (Phase == TPhaseVal::PhaseStandardMode) {
ctx.Send(ev->Forward(SchedulerId));
} else {
- auto result = std::make_unique<TEvLocalStatusResult>();
+ auto result = std::make_unique<TEvLocalStatusResult>();
NKikimrBlobStorage::TSyncerStatus *rec = result->Record.MutableSyncerStatus();
rec->SetPhase(Phase);
- ctx.Send(ev->Sender, result.release());
+ ctx.Send(ev->Sender, result.release());
}
}
@@ -543,8 +543,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_MAIN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_MAIN;
}
TSyncer(const TIntrusivePtr<TSyncerContext> &sc,
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.cpp
index 0c394f24443..1e8adb80866 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.cpp
@@ -11,16 +11,16 @@ namespace NKikimr {
: Modif(ENone)
{}
- std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Local(ELocalState state, TVDiskEternalGuid guid) {
- auto msg = std::make_unique<TEvSyncerCommit>();
+ std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Local(ELocalState state, TVDiskEternalGuid guid) {
+ auto msg = std::make_unique<TEvSyncerCommit>();
msg->Modif = ELocalGuid;
msg->LocalGuidInfo.SetState(state);
msg->LocalGuidInfo.SetGuid(guid);
return msg;
}
- std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::LocalFinal(TVDiskEternalGuid guid, ui64 dbBirthLsn) {
- auto msg = std::make_unique<TEvSyncerCommit>();
+ std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::LocalFinal(TVDiskEternalGuid guid, ui64 dbBirthLsn) {
+ auto msg = std::make_unique<TEvSyncerCommit>();
msg->Modif = ELocalGuid;
msg->LocalGuidInfo.SetState(TLocalVal::Final);
msg->LocalGuidInfo.SetGuid(guid);
@@ -28,20 +28,20 @@ namespace NKikimr {
return msg;
}
- std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Remote(const TVDiskID &vdisk,
+ std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Remote(const TVDiskID &vdisk,
const NSyncer::TPeerSyncState &p) {
- auto msg = std::make_unique<TEvSyncerCommit>();
+ auto msg = std::make_unique<TEvSyncerCommit>();
msg->Modif = EVDiskEntry;
msg->VDiskId = vdisk;
p.Serialize(msg->VDiskEntry);
return msg;
}
- std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Remote(const TVDiskID &vdisk,
+ std::unique_ptr<TEvSyncerCommit> TEvSyncerCommit::Remote(const TVDiskID &vdisk,
ESyncState state,
TVDiskEternalGuid guid,
void *cookie) {
- auto msg = std::make_unique<TEvSyncerCommit>();
+ auto msg = std::make_unique<TEvSyncerCommit>();
msg->Modif = EVDiskEntry;
msg->VDiskId = vdisk;
msg->Cookie = cookie;
@@ -60,7 +60,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TProtoState {
public:
- TProtoState(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ TProtoState(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
TSyncerDataSerializer &&sds)
: Top(top)
, Sds(std::move(sds))
@@ -89,7 +89,7 @@ namespace NKikimr {
}
private:
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
TSyncerDataSerializer Sds;
};
@@ -137,12 +137,12 @@ namespace NKikimr {
TString data = State.Serialize();
size_t dataSize = data.size();
TLsnSeg seg = SyncerCtx->LsnMngr->AllocLsnForLocalUse();
- auto msg = std::make_unique<NPDisk::TEvLog>(SyncerCtx->PDiskCtx->Dsk->Owner,
- SyncerCtx->PDiskCtx->Dsk->OwnerRound, TLogSignature::SignatureSyncerState,
- commitRec, data, seg, nullptr);
+ auto msg = std::make_unique<NPDisk::TEvLog>(SyncerCtx->PDiskCtx->Dsk->Owner,
+ SyncerCtx->PDiskCtx->Dsk->OwnerRound, TLogSignature::SignatureSyncerState,
+ commitRec, data, seg, nullptr);
SyncerCtx->MonGroup.SyncerLoggedBytes() += dataSize;
++SyncerCtx->MonGroup.SyncerLoggerRecords();
- ctx.Send(SyncerCtx->LoggerId, msg.release());
+ ctx.Send(SyncerCtx->LoggerId, msg.release());
}
void Handle(TEvSyncerCommit::TPtr &ev, const TActorContext &ctx) {
@@ -232,27 +232,27 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncerCommit, Handle)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(NPDisk::TEvLogResult, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncerCommit, Handle)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(NPDisk::TEvLogResult, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_COMMITTER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_COMMITTER;
}
TSyncerCommitter(const TIntrusivePtr<TSyncerContext> &sc,
TSyncerDataSerializer &&sds)
: TActorBootstrapped<TSyncerCommitter>()
, SyncerCtx(sc)
- , AdvanceEntryPointTimeout(SyncerCtx->Config->AdvanceEntryPointTimeout)
+ , AdvanceEntryPointTimeout(SyncerCtx->Config->AdvanceEntryPointTimeout)
, State(SyncerCtx->VCtx->Top, std::move(sds))
{}
};
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.h b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.h
index e865bc51172..f83f67c789e 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.h
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_committer.h
@@ -49,14 +49,14 @@ namespace NKikimr {
TEvSyncerCommit();
// create commit msg for local state (not Final)
- static std::unique_ptr<TEvSyncerCommit> Local(ELocalState state, TVDiskEternalGuid guid);
+ static std::unique_ptr<TEvSyncerCommit> Local(ELocalState state, TVDiskEternalGuid guid);
// create commit msg for local state (Final)
- static std::unique_ptr<TEvSyncerCommit> LocalFinal(TVDiskEternalGuid guid, ui64 dbBirthLsn);
+ static std::unique_ptr<TEvSyncerCommit> LocalFinal(TVDiskEternalGuid guid, ui64 dbBirthLsn);
// create commit msg for remote vdisk (save sync status, initiated locally)
- static std::unique_ptr<TEvSyncerCommit> Remote(const TVDiskID &vdisk,
+ static std::unique_ptr<TEvSyncerCommit> Remote(const TVDiskID &vdisk,
const NSyncer::TPeerSyncState &p);
// create commit msg for remote vdisk (save eternal guid, initiated by remote VDisk)
- static std::unique_ptr<TEvSyncerCommit> Remote(const TVDiskID &vdisk,
+ static std::unique_ptr<TEvSyncerCommit> Remote(const TVDiskID &vdisk,
ESyncState state,
TVDiskEternalGuid guid,
void *cookie);
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.cpp
index 4de7b60fbe8..c4e7cab9f72 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.cpp
@@ -164,7 +164,7 @@ namespace NKikimr {
TSyncNeighbors::TSyncNeighbors(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &self,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top)
: LogPrefix(logPrefix)
, NotifyId(notifyId)
, Neighbors(self, top)
@@ -290,7 +290,7 @@ namespace NKikimr {
TSyncerData::TSyncerData(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint)
: Neighbors(MakeIntrusive<TSyncNeighbors>(logPrefix,
notifyId,
@@ -306,7 +306,7 @@ namespace NKikimr {
bool TSyncerData::CheckEntryPoint(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint) {
try {
TSyncerData n(logPrefix, notifyId, selfVDisk, top);
@@ -321,7 +321,7 @@ namespace NKikimr {
// Convert from old entry point format to protobuf format
// TODO: we can remove this function after migrating to the protobuf format
TString TSyncerData::Convert(const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint) {
if (entryPoint.empty()) {
return entryPoint;
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.h b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.h
index c623859a60c..00abd104b0f 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.h
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data.h
@@ -124,7 +124,7 @@ namespace NKikimr {
TSyncNeighbors(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &self,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top);
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top);
TConstIterator begin() const { return Neighbors.Begin(); }
TConstIterator end() const { return Neighbors.End(); }
@@ -193,7 +193,7 @@ namespace NKikimr {
TSyncerData(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint = TString());
// we call this func during local recovery to apply last changes from recovery log
@@ -207,12 +207,12 @@ namespace NKikimr {
static bool CheckEntryPoint(const TString &logPrefix,
const TActorId &notifyId,
const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint);
// Convert from old entry point format to protobuf format
// TODO: we can remove this function after migrating to the protobuf format
static TString Convert(const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &entryPoint);
private:
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data_ut.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data_ut.cpp
index 0da0c427ee3..7430597c727 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_data_ut.cpp
@@ -8,9 +8,9 @@ using namespace NSync;
Y_UNIT_TEST_SUITE(TSyncNeighborsTests) {
- template<typename... TArgs>
- void SerDes(TArgs&&... args) {
- auto info = MakeIntrusive<TBlobStorageGroupInfo>(std::forward<TArgs>(args)...);
+ template<typename... TArgs>
+ void SerDes(TArgs&&... args) {
+ auto info = MakeIntrusive<TBlobStorageGroupInfo>(std::forward<TArgs>(args)...);
auto it = info->VDisksBegin();
++it;
auto vd = info->GetVDiskId(it->OrderNumber);
@@ -49,14 +49,14 @@ Y_UNIT_TEST_SUITE(TSyncNeighborsTests) {
}
Y_UNIT_TEST(SerDes1) {
- SerDes(TBlobStorageGroupType::ErasureMirror3, 2U, 4U);
+ SerDes(TBlobStorageGroupType::ErasureMirror3, 2U, 4U);
}
Y_UNIT_TEST(SerDes2) {
- SerDes(TBlobStorageGroupType::Erasure4Plus2Block, 1U, 8U);
+ SerDes(TBlobStorageGroupType::Erasure4Plus2Block, 1U, 8U);
}
Y_UNIT_TEST(SerDes3) {
- SerDes(TBlobStorageGroupType::Erasure4Plus2Block, 2U, 8U);
+ SerDes(TBlobStorageGroupType::Erasure4Plus2Block, 2U, 8U);
}
}
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.cpp
index b7ade7f8314..bf8986feacb 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.cpp
@@ -96,7 +96,7 @@ namespace NKikimr {
// record handlers
auto blobHandler = [&] (const NSyncLog::TLogoBlobRec *rec) {
- Y_VERIFY_DEBUG(TIngress::MustKnowAboutLogoBlob(vctx->Top.get(), vctx->ShortSelfVDisk, rec->LogoBlobID()),
+ Y_VERIFY_DEBUG(TIngress::MustKnowAboutLogoBlob(vctx->Top.get(), vctx->ShortSelfVDisk, rec->LogoBlobID()),
"logoBlobID# %s ShortSelfVDisk# %s top# %s", rec->LogoBlobID().ToString().data(),
vctx->ShortSelfVDisk.ToString().data(), vctx->Top->ToString().data());
@@ -111,29 +111,29 @@ namespace NKikimr {
TMemRecBarrier memRecBarrier(rec->CollectGeneration, rec->CollectStep, rec->Ingress);
barriers.emplace_back(keyBarrier, memRecBarrier);
};
- auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
- blocks.emplace_back(TKeyBlock(rec->TabletId), TMemRecBlock(rec->Generation));
- };
+ auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
+ blocks.emplace_back(TKeyBlock(rec->TabletId), TMemRecBlock(rec->Generation));
+ };
// process synclog data
NSyncLog::TFragmentReader fragment(Data);
- fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
+ fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
if (logoBlobs) {
Squeeze(logoBlobs);
Extracted.LogoBlobs =
- std::make_shared<TFreshAppendixLogoBlobs>(std::move(logoBlobs), vctx->FreshIndex, true);
+ std::make_shared<TFreshAppendixLogoBlobs>(std::move(logoBlobs), vctx->FreshIndex, true);
}
if (blocks) {
Squeeze(blocks);
// blocks are already sorted
Extracted.Blocks =
- std::make_shared<TFreshAppendixBlocks>(std::move(blocks), vctx->FreshIndex, true);
+ std::make_shared<TFreshAppendixBlocks>(std::move(blocks), vctx->FreshIndex, true);
}
if (barriers) {
Squeeze(barriers);
Extracted.Barriers =
- std::make_shared<TFreshAppendixBarriers>(std::move(barriers), vctx->FreshIndex, true);
+ std::make_shared<TFreshAppendixBarriers>(std::move(barriers), vctx->FreshIndex, true);
}
Y_VERIFY(Extracted.IsReady());
}
@@ -149,7 +149,7 @@ namespace NKikimr {
TIntrusivePtr<TVDiskContext> VCtx;
TActorId SkeletonId;
TActorId ParentId;
- std::unique_ptr<TEvLocalSyncData> Ev;
+ std::unique_ptr<TEvLocalSyncData> Ev;
void Bootstrap(const TActorContext &ctx) {
auto startTime = TAppData::TimeProvider->Now();
@@ -160,7 +160,7 @@ namespace NKikimr {
<< " dataSize# " << Ev->Data.size()
<< " duration# %s" << (finishTime - startTime));
- ctx.Send(new IEventHandle(SkeletonId, ParentId, Ev.release()));
+ ctx.Send(new IEventHandle(SkeletonId, ParentId, Ev.release()));
PassAway();
}
@@ -173,7 +173,7 @@ namespace NKikimr {
const TIntrusivePtr<TVDiskContext> &vctx,
const TActorId &skeletonId,
const TActorId &parentId,
- std::unique_ptr<TEvLocalSyncData> ev)
+ std::unique_ptr<TEvLocalSyncData> ev)
: VCtx(vctx)
, SkeletonId(skeletonId)
, ParentId(parentId)
@@ -182,7 +182,7 @@ namespace NKikimr {
};
IActor *CreateLocalSyncDataExtractor(const TIntrusivePtr<TVDiskContext> &vctx, const TActorId &skeletonId,
- const TActorId &parentId, std::unique_ptr<TEvLocalSyncData> ev) {
+ const TActorId &parentId, std::unique_ptr<TEvLocalSyncData> ev) {
return new TLocalSyncDataExtractorActor(vctx, skeletonId, parentId, std::move(ev));
}
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.h b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.h
index 701dec57bdd..1c41d4b0c38 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.h
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_localwriter.h
@@ -68,6 +68,6 @@ namespace NKikimr {
// CreateLocalSyncDataExtractor
///////////////////////////////////////////////////////////////////////////////////////////////
IActor *CreateLocalSyncDataExtractor(const TIntrusivePtr<TVDiskContext> &vctx, const TActorId &skeletonId,
- const TActorId &parentId, std::unique_ptr<TEvLocalSyncData> ev);
+ const TActorId &parentId, std::unique_ptr<TEvLocalSyncData> ev);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata.cpp
index 1b3286397de..00fd35ee5ca 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata.cpp
@@ -43,7 +43,7 @@ namespace NKikimr {
class TSyncFullRecoverState {
public:
TSyncFullRecoverState(const TVDiskIdShort &self,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top)
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top)
: Neighbors(self, top)
, QuorumTracker(self, top, false)
, Sublog(false, self.ToString() + ": ")
@@ -104,7 +104,7 @@ namespace NKikimr {
const TActorId NotifyId;
const TVDiskEternalGuid Guid;
ui64 DbBirthLsn = 0;
- std::shared_ptr<TSjCtx> JobCtx;
+ std::shared_ptr<TSjCtx> JobCtx;
void Bootstrap(const TActorContext &ctx) {
// FIXME: RecoverLostData actor MUST remove artefacts of the previous recover try
@@ -160,11 +160,11 @@ namespace NKikimr {
}
}
- STRICT_STFUNC(FullSyncStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerFullSyncedWithPeer, Handle)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(FullSyncStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerFullSyncedWithPeer, Handle)
+ HFunc(TEvVGenerationChange, Handle)
+ )
////////////////////////////////////////////////////////////////////////
// CALL OSIRIS
@@ -189,12 +189,12 @@ namespace NKikimr {
WriteFinalLocally(ctx);
}
- STRICT_STFUNC(WaitOsirisStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvOsirisDone, Handle)
- IgnoreFunc(TEvSyncerFullSyncedWithPeer)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(WaitOsirisStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvOsirisDone, Handle)
+ IgnoreFunc(TEvSyncerFullSyncedWithPeer)
+ HFunc(TEvVGenerationChange, Handle)
+ )
////////////////////////////////////////////////////////////////////////
// WRITE FINAL GUID LOCALLY
@@ -204,7 +204,7 @@ namespace NKikimr {
VDISKP(SyncerCtx->VCtx->VDiskLogPrefix,
"TSyncerRecoverLostDataActor: WriteFinalLocally"));
auto msg = TEvSyncerCommit::LocalFinal(Guid, DbBirthLsn);
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
Become(&TThis::WriteFinalLocallyStateFunc);
}
@@ -216,12 +216,12 @@ namespace NKikimr {
Finish(ctx);
}
- STRICT_STFUNC(WriteFinalLocallyStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerCommitDone, HandleFinalLocally)
- HFunc(TEvVGenerationChange, Handle)
+ STRICT_STFUNC(WriteFinalLocallyStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerCommitDone, HandleFinalLocally)
+ HFunc(TEvVGenerationChange, Handle)
IgnoreFunc(TEvSyncerFullSyncedWithPeer)
- )
+ )
////////////////////////////////////////////////////////////////////////
// WRITE FINAL GUID LOCALLY
@@ -263,8 +263,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_RECOVER_LOST_DATA;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_RECOVER_LOST_DATA;
}
TSyncerRecoverLostDataActor(const TIntrusivePtr<TSyncerContext> &sc,
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.cpp
index 2d0e205c7b5..63c86fff2db 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.cpp
@@ -21,10 +21,10 @@ namespace NKikimr {
: public TEventLocal<TEvSyncerRLDWakeup, TEvBlobStorage::EvSyncerRLDWakeup>
{
// Our task we working on
- std::unique_ptr<TSyncerJobTask> Task;
+ std::unique_ptr<TSyncerJobTask> Task;
- TEvSyncerRLDWakeup(std::unique_ptr<TSyncerJobTask> task)
- : Task(std::move(task))
+ TEvSyncerRLDWakeup(std::unique_ptr<TSyncerJobTask> task)
+ : Task(std::move(task))
{}
};
@@ -40,17 +40,17 @@ namespace NKikimr {
const TActorId CommitterId;
const TActorId NotifyId;
TActiveActors ActiveActors;
- std::shared_ptr<TSjCtx> JobCtx;
+ std::shared_ptr<TSjCtx> JobCtx;
// Target VDiskId and ActorId are reconfigurable
TVDiskID TargetVDiskId;
TActorId TargetActorId;
void CreateAndRunTask(const TActorContext &ctx) {
// create task
- auto task = std::make_unique<TSyncerJobTask>(TSyncerJobTask::EFullRecover, TargetVDiskId, TargetActorId,
- PeerSyncState, JobCtx);
+ auto task = std::make_unique<TSyncerJobTask>(TSyncerJobTask::EFullRecover, TargetVDiskId, TargetActorId,
+ PeerSyncState, JobCtx);
// run task
- const TActorId aid = ctx.Register(CreateSyncerJob(SyncerCtx, std::move(task), ctx.SelfID));
+ const TActorId aid = ctx.Register(CreateSyncerJob(SyncerCtx, std::move(task), ctx.SelfID));
ActiveActors.Insert(aid);
// state func
Become(&TThis::WaitForSyncStateFunc);
@@ -72,20 +72,20 @@ namespace NKikimr {
"TSyncerRLDFullSyncProxyActor(%s): TEvSyncerJobDone; Task# %s",
TargetVDiskId.ToString().data(), ev->Get()->Task->ToString().data()));
ActiveActors.Erase(ev->Sender);
- std::unique_ptr<TSyncerJobTask> task = std::move(ev->Get()->Task);
+ std::unique_ptr<TSyncerJobTask> task = std::move(ev->Get()->Task);
auto syncStatus = task->GetCurrent().LastSyncStatus;
if (!TPeerSyncState::Good(syncStatus)) {
RerunTaskAfterTimeout(ctx);
} else {
- Commit(ctx, std::move(task));
+ Commit(ctx, std::move(task));
}
}
- STRICT_STFUNC(WaitForSyncStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerJobDone, Handle)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(WaitForSyncStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerJobDone, Handle)
+ HFunc(TEvVGenerationChange, Handle)
+ )
////////////////////////////////////////////////////////////////////////
// WAIT FOR TIMEOUT
@@ -95,7 +95,7 @@ namespace NKikimr {
VDISKP(SyncerCtx->VCtx->VDiskLogPrefix,
"TSyncerRLDFullSyncProxyActor(%s): RerunTaskAfterTimeout",
TargetVDiskId.ToString().data()));
- auto timeout = SyncerCtx->Config->SyncerRLDRetryTimeout;
+ auto timeout = SyncerCtx->Config->SyncerRLDRetryTimeout;
ctx.Schedule(timeout, new TEvSyncerRLDWakeup(nullptr));
// state func
Become(&TThis::WaitForTimeoutStateFunc);
@@ -107,23 +107,23 @@ namespace NKikimr {
CreateAndRunTask(ctx);
}
- STRICT_STFUNC(WaitForTimeoutStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerRLDWakeup, Handle)
- IgnoreFunc(TEvSyncerJobDone)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(WaitForTimeoutStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerRLDWakeup, Handle)
+ IgnoreFunc(TEvSyncerJobDone)
+ HFunc(TEvVGenerationChange, Handle)
+ )
////////////////////////////////////////////////////////////////////////
// COMMIT
////////////////////////////////////////////////////////////////////////
- void Commit(const TActorContext &ctx, std::unique_ptr<TSyncerJobTask> task) {
+ void Commit(const TActorContext &ctx, std::unique_ptr<TSyncerJobTask> task) {
LOG_DEBUG(ctx, BS_SYNCER,
VDISKP(SyncerCtx->VCtx->VDiskLogPrefix,
"TSyncerRLDFullSyncProxyActor(%s): Commit",
TargetVDiskId.ToString().data()));
auto msg = TEvSyncerCommit::Remote(task->VDiskId, task->GetCurrent());
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
Become(&TThis::WaitForCommitStateFunc);
}
@@ -137,11 +137,11 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(WaitForCommitStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerCommitDone, Handle)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(WaitForCommitStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerCommitDone, Handle)
+ HFunc(TEvVGenerationChange, Handle)
+ )
////////////////////////////////////////////////////////////////////////
// HandlePoison
@@ -169,15 +169,15 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_RECOVER_LOST_DATA;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_RECOVER_LOST_DATA;
}
TSyncerRLDFullSyncProxyActor(const TIntrusivePtr<TSyncerContext> &sc,
const TPeerSyncState& peerSyncState,
const TActorId &committerId,
const TActorId &notifyId,
- const std::shared_ptr<TSjCtx> &jobCtx,
+ const std::shared_ptr<TSjCtx> &jobCtx,
const TVDiskID &targetVDiskId,
const TActorId &targetActorId)
: TActorBootstrapped<TSyncerRLDFullSyncProxyActor>()
@@ -199,7 +199,7 @@ namespace NKikimr {
const TPeerSyncState& peerSyncState,
const TActorId &committerId,
const TActorId &notifyId,
- const std::shared_ptr<TSjCtx> &jobCtx,
+ const std::shared_ptr<TSjCtx> &jobCtx,
const TVDiskID &targetVDiskId,
const TActorId &targetActorId) {
return new TSyncerRLDFullSyncProxyActor(sc, peerSyncState, committerId, notifyId,
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.h b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.h
index eb5605a4708..4b73ce910a3 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.h
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_recoverlostdata_proxy.h
@@ -37,7 +37,7 @@ namespace NKikimr {
const NSyncer::TPeerSyncState& peerSyncState,
const TActorId &committerId,
const TActorId &notifyId,
- const std::shared_ptr<NSyncer::TSjCtx> &jobCtx,
+ const std::shared_ptr<NSyncer::TSjCtx> &jobCtx,
const TVDiskID &targetVDiskId,
const TActorId &targetActorId);
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_scheduler.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_scheduler.cpp
index 92ae94e89f7..3ea3b2d1bd2 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_scheduler.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncer_scheduler.cpp
@@ -96,8 +96,8 @@ namespace NKikimr {
)
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_HTTPREQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_HTTPREQ;
}
TSyncerSchedulerHttpActor(const TIntrusivePtr<TSyncerContext> &sc,
@@ -123,10 +123,10 @@ namespace NKikimr {
struct TEvSyncerCommitProxyDone :
public TEventLocal<TEvSyncerCommitProxyDone, TEvBlobStorage::EvSyncerCommitProxyDone>
{
- std::unique_ptr<TSyncerJobTask> Task;
+ std::unique_ptr<TSyncerJobTask> Task;
- TEvSyncerCommitProxyDone(std::unique_ptr<TSyncerJobTask> task)
- : Task(std::move(task))
+ TEvSyncerCommitProxyDone(std::unique_ptr<TSyncerJobTask> task)
+ : Task(std::move(task))
{}
};
@@ -138,17 +138,17 @@ namespace NKikimr {
const TActorId NotifyId;
const TActorId CommitterId;
- std::unique_ptr<TSyncerJobTask> Task;
+ std::unique_ptr<TSyncerJobTask> Task;
void Bootstrap(const TActorContext &ctx) {
auto msg = TEvSyncerCommit::Remote(Task->VDiskId, Task->GetCurrent());
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
TThis::Become(&TThis::StateFunc);
}
void Handle(TEvSyncerCommitDone::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
- ctx.Send(NotifyId, new TEvSyncerCommitProxyDone(std::move(Task)));
+ ctx.Send(NotifyId, new TEvSyncerCommitProxyDone(std::move(Task)));
Die(ctx);
}
@@ -157,23 +157,23 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncerCommitDone, Handle);
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncerCommitDone, Handle);
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_COMMITTER_PROXY;
- }
-
+ return NKikimrServices::TActivity::BS_SYNCER_COMMITTER_PROXY;
+ }
+
TSyncerCommitterProxy(const TActorId &notifyId,
const TActorId &committerId,
- std::unique_ptr<TSyncerJobTask> task)
+ std::unique_ptr<TSyncerJobTask> task)
: TActorBootstrapped<TSyncerCommitterProxy>()
, NotifyId(notifyId)
, CommitterId(committerId)
- , Task(std::move(task))
+ , Task(std::move(task))
{}
};
@@ -206,7 +206,7 @@ namespace NKikimr {
const TDuration SyncTimeInterval;
TActorId CommitterId;
bool Scheduled;
- std::shared_ptr<TSjCtx> JobCtx;
+ std::shared_ptr<TSjCtx> JobCtx;
friend class TActorBootstrapped<TSyncerScheduler>;
@@ -233,13 +233,13 @@ namespace NKikimr {
}
}
- // if we haven't found any neighbors to sync with, notify skeleton
- if (SchedulerQueue.empty()) {
- Become(&TThis::NothingToDo);
- } else {
- // start sync immediately
- Schedule(ctx);
- }
+ // if we haven't found any neighbors to sync with, notify skeleton
+ if (SchedulerQueue.empty()) {
+ Become(&TThis::NothingToDo);
+ } else {
+ // start sync immediately
+ Schedule(ctx);
+ }
}
void HandleWakeup(const TActorContext &ctx) {
@@ -247,10 +247,10 @@ namespace NKikimr {
Schedule(ctx);
}
- void ApplyChanges(const TActorContext &ctx, TSyncerJobTask& task) {
- SyncerData->Neighbors->ApplyChanges(ctx, &task, SyncerContext->Config->SyncTimeInterval);
+ void ApplyChanges(const TActorContext &ctx, TSyncerJobTask& task) {
+ SyncerData->Neighbors->ApplyChanges(ctx, &task, SyncerContext->Config->SyncTimeInterval);
ActualizeUnsyncedDisksNum();
- SchedulerQueue.push(&(*SyncerData->Neighbors)[task.VDiskId]);
+ SchedulerQueue.push(&(*SyncerData->Neighbors)[task.VDiskId]);
Schedule(ctx);
}
@@ -259,23 +259,23 @@ namespace NKikimr {
TEvSyncerJobDone *msg = ev->Get();
if (msg->Task->NeedCommit()) {
- auto proxy = std::make_unique<TSyncerCommitterProxy>(ctx.SelfID, CommitterId, std::move(msg->Task));
- const TActorId aid = ctx.Register(proxy.release());
+ auto proxy = std::make_unique<TSyncerCommitterProxy>(ctx.SelfID, CommitterId, std::move(msg->Task));
+ const TActorId aid = ctx.Register(proxy.release());
ActiveActors.Insert(aid);
} else {
- ApplyChanges(ctx, *msg->Task);
+ ApplyChanges(ctx, *msg->Task);
}
}
void Handle(TEvSyncerCommitProxyDone::TPtr &ev, const TActorContext &ctx) {
ActiveActors.Erase(ev->Sender);
TEvSyncerCommitProxyDone *msg = ev->Get();
- ApplyChanges(ctx, *msg->Task);
+ ApplyChanges(ctx, *msg->Task);
}
void Schedule(const TActorContext &ctx) {
- Become(&TThis::StateFunc);
-
+ Become(&TThis::StateFunc);
+
TInstant now = TAppData::TimeProvider->Now();
// NOTE: After full recovery we run sync op immediately. We achieve this by setting
// SchTime to 'now' in ApplyChanges and running sync op below
@@ -285,9 +285,9 @@ namespace NKikimr {
TVDiskInfoPtr tmp = SchedulerQueue.top();
SchedulerQueue.pop();
Y_VERIFY_DEBUG(tmp->Get().PeerSyncState.LastSyncStatus != TSyncStatusVal::Running);
- auto task = std::make_unique<TSyncerJobTask>(TSyncerJobTask::EJustSync, GInfo->GetVDiskId(tmp->OrderNumber),
- GInfo->GetActorId(tmp->OrderNumber), tmp->Get().PeerSyncState, JobCtx);
- const TActorId aid = ctx.Register(CreateSyncerJob(SyncerContext, std::move(task), ctx.SelfID));
+ auto task = std::make_unique<TSyncerJobTask>(TSyncerJobTask::EJustSync, GInfo->GetVDiskId(tmp->OrderNumber),
+ GInfo->GetActorId(tmp->OrderNumber), tmp->Get().PeerSyncState, JobCtx);
+ const TActorId aid = ctx.Register(CreateSyncerJob(SyncerContext, std::move(task), ctx.SelfID));
ActiveActors.Insert(aid);
}
@@ -301,20 +301,20 @@ namespace NKikimr {
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
Y_VERIFY_DEBUG(ev->Get()->SubRequestId == TDbMon::SyncerInfoId);
// create an actor to handle request
- auto actor = std::make_unique<TSyncerSchedulerHttpActor>(SyncerContext, GInfo, SyncerData, ev, ctx.SelfID);
- auto aid = ctx.RegisterWithSameMailbox(actor.release());
+ auto actor = std::make_unique<TSyncerSchedulerHttpActor>(SyncerContext, GInfo, SyncerData, ev, ctx.SelfID);
+ auto aid = ctx.RegisterWithSameMailbox(actor.release());
ActiveActors.Insert(aid);
}
void Handle(TEvLocalStatus::TPtr &ev, const TActorContext &ctx) {
- std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
+ std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
NKikimrBlobStorage::TSyncerStatus *rec = result->Record.MutableSyncerStatus();
rec->SetPhase(NKikimrBlobStorage::TSyncerStatus::PhaseStandardMode);
for (const auto &x: *SyncerData->Neighbors) {
NKikimrBlobStorage::TSyncState *st = rec->AddSyncState();
SyncStateFromSyncState(x.Get().PeerSyncState.SyncState, st);
}
- ctx.Send(ev->Sender, result.release());
+ ctx.Send(ev->Sender, result.release());
}
void Handle(NPDisk::TEvCutLog::TPtr &ev, const TActorContext &ctx) {
@@ -340,30 +340,30 @@ namespace NKikimr {
ActiveActors.Erase(ev->Sender);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncerJobDone, Handle)
- HFunc(TEvSyncerCommitProxyDone, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvVGenerationChange, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncerJobDone, Handle)
+ HFunc(TEvSyncerCommitProxyDone, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- )
-
- STRICT_STFUNC(NothingToDo,
- HFunc(NMon::TEvHttpInfo, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvVGenerationChange, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ )
+
+ STRICT_STFUNC(NothingToDo,
+ HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(TEvVGenerationChange, Handle)
HFunc(TEvents::TEvActorDied, Handle)
- )
-
+ )
+
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_SCHEDULER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_SCHEDULER;
}
TSyncerScheduler(const TIntrusivePtr<TSyncerContext> &sc,
@@ -376,7 +376,7 @@ namespace NKikimr {
, SyncerData(syncerData)
, SchedulerQueue()
, ActiveActors()
- , SyncTimeInterval(SyncerContext->Config->SyncTimeInterval)
+ , SyncTimeInterval(SyncerContext->Config->SyncTimeInterval)
, CommitterId(committerId)
, Scheduled(false)
, JobCtx(TSjCtx::Create(SyncerContext, GInfo))
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum.h b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum.h
index 5d53a289ce0..8a36a4b0ba9 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum.h
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum.h
@@ -34,15 +34,15 @@ namespace NKikimr {
// TQuorumTracker
// The class tracks responses from other vdisks in group to obtain quorum
///////////////////////////////////////////////////////////////////////////
- class TQuorumTracker {
+ class TQuorumTracker {
public:
TQuorumTracker(const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
bool includeMyFailDomain)
: Top(std::move(top))
, MyFailDomainOrderNumber(Top->GetFailDomainOrderNumber(selfVDisk))
, IncludeMyFailDomain(includeMyFailDomain)
- , SyncedDisks(Top.get())
+ , SyncedDisks(Top.get())
, Erasure(Top->GType.GetErasure())
{
}
@@ -50,22 +50,22 @@ namespace NKikimr {
void Update(const TVDiskIdShort &vdisk) {
Debug.Update(vdisk);
if (IncludeMyFailDomain || Top->GetFailDomainOrderNumber(vdisk) != MyFailDomainOrderNumber) {
- SyncedDisks |= TBlobStorageGroupInfo::TGroupVDisks(Top.get(), vdisk);
+ SyncedDisks |= TBlobStorageGroupInfo::TGroupVDisks(Top.get(), vdisk);
}
}
bool HasQuorum() const {
const auto& checker = Top->GetQuorumChecker();
- return checker.CheckQuorumForGroup(SyncedDisks);
+ return checker.CheckQuorumForGroup(SyncedDisks);
}
void Clear() {
Debug.Clear();
- SyncedDisks = TBlobStorageGroupInfo::TGroupVDisks(Top.get());
+ SyncedDisks = TBlobStorageGroupInfo::TGroupVDisks(Top.get());
}
void Output(IOutputStream &str) const {
- str << "{Debug# " << Debug.ToString() << "}";
+ str << "{Debug# " << Debug.ToString() << "}";
}
TString ToString() const {
@@ -75,14 +75,14 @@ namespace NKikimr {
}
private:
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
- const ui32 MyFailDomainOrderNumber;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ const ui32 MyFailDomainOrderNumber;
const bool IncludeMyFailDomain;
TQuorumTrackerDebug Debug;
- TBlobStorageGroupInfo::TGroupVDisks SyncedDisks;
-
- public:
- const TBlobStorageGroupType::EErasureSpecies Erasure;
+ TBlobStorageGroupInfo::TGroupVDisks SyncedDisks;
+
+ public:
+ const TBlobStorageGroupType::EErasureSpecies Erasure;
};
} // NSync
diff --git a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum_ut.cpp b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum_ut.cpp
index 78e25633ab3..e472fc58978 100644
--- a/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/blobstorage_syncquorum_ut.cpp
@@ -34,13 +34,13 @@ namespace NKikimr {
}
Y_UNIT_TEST(ErasureNoneNeverHasQuorum_4_1) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureNone, 1, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureNone, 1, 4);
- auto vdisks = GetDisks(&groupInfo);
+ auto vdisks = GetDisks(&groupInfo);
Shuffle(vdisks.begin(), vdisks.end());
auto self = vdisks[0];
- TQuorumTracker tracker(self, groupInfo.PickTopology(), false);
+ TQuorumTracker tracker(self, groupInfo.PickTopology(), false);
for (unsigned i = 1; i < vdisks.size(); i++) {
tracker.Update(vdisks[i]);
UNIT_ASSERT(!tracker.HasQuorum());
@@ -48,57 +48,57 @@ namespace NKikimr {
}
UNIT_ASSERT(!tracker.HasQuorum());
}
-
+
Y_UNIT_TEST(Erasure4Plus2BlockIncludingMyFailDomain_8_2) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
-
- auto vdisks = GetDisks(&groupInfo);
- const TVDiskID& self = vdisks[0];
-
- TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
- for (unsigned i = 0; i < vdisks.size(); i++) {
- tracker.Update(vdisks[i]);
- if (i + 1 >= 2 * 6) {
- UNIT_ASSERT(tracker.HasQuorum());
- } else {
- UNIT_ASSERT(!tracker.HasQuorum());
- }
- }
- }
-
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
+
+ auto vdisks = GetDisks(&groupInfo);
+ const TVDiskID& self = vdisks[0];
+
+ TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
+ for (unsigned i = 0; i < vdisks.size(); i++) {
+ tracker.Update(vdisks[i]);
+ if (i + 1 >= 2 * 6) {
+ UNIT_ASSERT(tracker.HasQuorum());
+ } else {
+ UNIT_ASSERT(!tracker.HasQuorum());
+ }
+ }
+ }
+
Y_UNIT_TEST(Erasure4Plus2BlockNotIncludingMyFailDomain_8_2) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
-
- auto vdisks = GetDisks(&groupInfo);
- const TVDiskID& self = vdisks[0];
-
- TQuorumTracker tracker(self, groupInfo.PickTopology(), false);
- for (unsigned i = 0; i < vdisks.size(); i++) {
- tracker.Update(vdisks[i]);
- if (i + 1 >= 2 * (6 + 1)) {
- UNIT_ASSERT(tracker.HasQuorum());
- } else {
- UNIT_ASSERT(!tracker.HasQuorum());
- }
- }
- }
-
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::Erasure4Plus2Block, 2, 8);
+
+ auto vdisks = GetDisks(&groupInfo);
+ const TVDiskID& self = vdisks[0];
+
+ TQuorumTracker tracker(self, groupInfo.PickTopology(), false);
+ for (unsigned i = 0; i < vdisks.size(); i++) {
+ tracker.Update(vdisks[i]);
+ if (i + 1 >= 2 * (6 + 1)) {
+ UNIT_ASSERT(tracker.HasQuorum());
+ } else {
+ UNIT_ASSERT(!tracker.HasQuorum());
+ }
+ }
+ }
+
Y_UNIT_TEST(ErasureMirror3IncludingMyFailDomain_4_2) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
- auto vdisks = GetDisks(&groupInfo);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ auto vdisks = GetDisks(&groupInfo);
const TVDiskID& self = vdisks[0];
- TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
+ TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
TVector<int> notYetQuorum = {0, 1, 2, 3, 4, 7};
Check(tracker, vdisks, notYetQuorum, 6);
}
Y_UNIT_TEST(ErasureMirror3IncludingMyFailDomain_5_2) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 5);
- auto vdisks = GetDisks(&groupInfo);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 5);
+ auto vdisks = GetDisks(&groupInfo);
const TVDiskID& self = vdisks[0];
- TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
+ TQuorumTracker tracker(self, groupInfo.PickTopology(), true);
TVector<int> notYetQuorum = {0, 1, 3, 4, 5, 6, 8, 9};
Check(tracker, vdisks, notYetQuorum, 2);
}
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_firstrun.cpp b/ydb/core/blobstorage/vdisk/syncer/guid_firstrun.cpp
index 79a4df2abe3..6d04e20e9f9 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_firstrun.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_firstrun.cpp
@@ -103,7 +103,7 @@ namespace NKikimr {
public:
TVDiskGuidFirstRunState(const TVDiskIdShort &self,
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
EFirstRunStep step,
TVDiskEternalGuid guid)
: Neighbors(self, top)
@@ -364,11 +364,11 @@ namespace NKikimr {
}
}
- STRICT_STFUNC(WriteGuidInProgressStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvVDiskGuidWritten, HandleInProgressWritten)
- HFunc(TEvVGenerationChange, HandleWhileProxiesRunning)
- )
+ STRICT_STFUNC(WriteGuidInProgressStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvVDiskGuidWritten, HandleInProgressWritten)
+ HFunc(TEvVGenerationChange, HandleWhileProxiesRunning)
+ )
////////////////////////////////////////////////////////////////////////
// WRITE SELECTED GUID LOCALLY
@@ -381,7 +381,7 @@ namespace NKikimr {
FirstRunState.RunWriteSelectedLocally();
auto guid = FirstRunState.GetGuid();
auto msg = TEvSyncerCommit::Local(TLocalVal::Selected, guid);
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
Become(&TThis::WriteSelectedLocallyStateFunc);
WaitFor = WaitForCommitter;
}
@@ -392,14 +392,14 @@ namespace NKikimr {
WriteFinalGuidToQuorum(ctx);
}
- STRICT_STFUNC(WriteSelectedLocallyStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerCommitDone, HandleSelectedLocally)
- // NOTE: In WaitForCommitter state we can still receive TEvVDiskGuidWritten
- // messages (i.e. replies from the previous phase). Ignore them.
- IgnoreFunc(TEvVDiskGuidWritten)
- HFunc(TEvVGenerationChange, HandleNoProxies)
- )
+ STRICT_STFUNC(WriteSelectedLocallyStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerCommitDone, HandleSelectedLocally)
+ // NOTE: In WaitForCommitter state we can still receive TEvVDiskGuidWritten
+ // messages (i.e. replies from the previous phase). Ignore them.
+ IgnoreFunc(TEvVDiskGuidWritten)
+ HFunc(TEvVGenerationChange, HandleNoProxies)
+ )
////////////////////////////////////////////////////////////////////////
// WRITE FINAL GUID TO QUORUM
@@ -447,11 +447,11 @@ namespace NKikimr {
}
}
- STRICT_STFUNC(WriteFinalGuidStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvVDiskGuidWritten, HandleFinalWritten)
- HFunc(TEvVGenerationChange, HandleWhileProxiesRunning)
- )
+ STRICT_STFUNC(WriteFinalGuidStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvVDiskGuidWritten, HandleFinalWritten)
+ HFunc(TEvVGenerationChange, HandleWhileProxiesRunning)
+ )
////////////////////////////////////////////////////////////////////////
// WRITE FINAL GUID LOCALLY
@@ -466,7 +466,7 @@ namespace NKikimr {
Y_VERIFY(guid);
ui64 dbBirthLsn = 0;
auto msg = TEvSyncerCommit::LocalFinal(guid, dbBirthLsn);
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
Become(&TThis::WriteFinalLocallyStateFunc);
WaitFor = WaitForCommitter;
}
@@ -477,14 +477,14 @@ namespace NKikimr {
Finish(ctx);
}
- STRICT_STFUNC(WriteFinalLocallyStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerCommitDone, HandleFinalLocally)
- // NOTE: In WaitForCommitter state we can still receive TEvVDiskGuidWritten
- // messages (i.e. replies from the previous phase). Ignore them.
- IgnoreFunc(TEvVDiskGuidWritten)
- HFunc(TEvVGenerationChange, HandleNoProxies)
- )
+ STRICT_STFUNC(WriteFinalLocallyStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerCommitDone, HandleFinalLocally)
+ // NOTE: In WaitForCommitter state we can still receive TEvVDiskGuidWritten
+ // messages (i.e. replies from the previous phase). Ignore them.
+ IgnoreFunc(TEvVDiskGuidWritten)
+ HFunc(TEvVGenerationChange, HandleNoProxies)
+ )
////////////////////////////////////////////////////////////////////////
// FINISH
@@ -544,8 +544,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNC_VDISK_GUID_FIRST_RUN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNC_VDISK_GUID_FIRST_RUN;
}
TVDiskGuidFirstRunActor(TIntrusivePtr<TVDiskContext> vctx,
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_propagator.cpp b/ydb/core/blobstorage/vdisk/syncer/guid_propagator.cpp
index 75be9753075..56a19da37b6 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_propagator.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_propagator.cpp
@@ -99,21 +99,21 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////
// State Functions
////////////////////////////////////////////////////////////////////////
- STRICT_STFUNC(StateFuncWrite,
- HFunc(TEvVDiskGuidWritten, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvVGenerationChange, Handle)
- )
-
- STRICT_STFUNC(StateFuncWait,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(StateFuncWrite,
+ HFunc(TEvVDiskGuidWritten, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvVGenerationChange, Handle)
+ )
+
+ STRICT_STFUNC(StateFuncWait,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvVGenerationChange, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_GUID_PROPAGATOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_GUID_PROPAGATOR;
}
TSyncerGuidPropagator(TIntrusivePtr<TVDiskContext> vctx,
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h b/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h
index ffdd4b26c7e..19707afc6a7 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_proxybase.h
@@ -25,7 +25,7 @@ namespace NKikimr {
// override these functions to get required functionality
- virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() = 0;
+ virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() = 0;
virtual void HandleReply(const TActorContext &ctx,
const NKikimrBlobStorage::TEvVSyncGuidResult &record) = 0;
@@ -42,7 +42,7 @@ namespace NKikimr {
// we don't use cookie, because in general any response is OK
// track delivery and subscribe on session
- ctx.Send(TargetServiceId, GenerateRequest().release(),
+ ctx.Send(TargetServiceId, GenerateRequest().release(),
IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
Become(&TThis::StateFunc);
@@ -139,28 +139,28 @@ namespace NKikimr {
TargetServiceId = info->GetActorId(shortTarget);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
- HFunc(TEvents::TEvUndelivered, Handle)
- HFunc(TEvBlobStorage::TEvVSyncGuidResult, Handle)
- IgnoreFunc(TEvInterconnect::TEvNodeConnected)
- HFunc(TEvVGenerationChange, Handle)
- )
-
- STRICT_STFUNC(StateSleep,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- IgnoreFunc(TEvInterconnect::TEvNodeDisconnected)
- IgnoreFunc(TEvents::TEvUndelivered)
- IgnoreFunc(TEvBlobStorage::TEvVSyncGuidResult)
- CFunc(TEvents::TEvWakeup::EventType, HandleWakeup)
- IgnoreFunc(TEvInterconnect::TEvNodeConnected)
- HFunc(TEvVGenerationChange, Handle)
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
+ HFunc(TEvents::TEvUndelivered, Handle)
+ HFunc(TEvBlobStorage::TEvVSyncGuidResult, Handle)
+ IgnoreFunc(TEvInterconnect::TEvNodeConnected)
+ HFunc(TEvVGenerationChange, Handle)
+ )
+
+ STRICT_STFUNC(StateSleep,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ IgnoreFunc(TEvInterconnect::TEvNodeDisconnected)
+ IgnoreFunc(TEvents::TEvUndelivered)
+ IgnoreFunc(TEvBlobStorage::TEvVSyncGuidResult)
+ CFunc(TEvents::TEvWakeup::EventType, HandleWakeup)
+ IgnoreFunc(TEvInterconnect::TEvNodeConnected)
+ HFunc(TEvVGenerationChange, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNC_WRITE_VDISK_GUID_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNC_WRITE_VDISK_GUID_PROXY;
}
TVDiskGuidProxyBase(TIntrusivePtr<TVDiskContext> vctx,
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_proxyobtain.cpp b/ydb/core/blobstorage/vdisk/syncer/guid_proxyobtain.cpp
index 29f2e3bfbc0..b03801a9cf8 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_proxyobtain.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_proxyobtain.cpp
@@ -12,8 +12,8 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TObtainVDiskGuidProxy : public TVDiskGuidProxyBase {
protected:
- virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() override {
- return std::make_unique<TEvBlobStorage::TEvVSyncGuid>(SelfVDiskId, TargetVDiskId);
+ virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() override {
+ return std::make_unique<TEvBlobStorage::TEvVSyncGuid>(SelfVDiskId, TargetVDiskId);
}
virtual void HandleReply(const TActorContext &ctx,
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_proxywrite.cpp b/ydb/core/blobstorage/vdisk/syncer/guid_proxywrite.cpp
index 8b2d29b0616..0c53017eddf 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_proxywrite.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_proxywrite.cpp
@@ -15,9 +15,9 @@ namespace NKikimr {
const NKikimrBlobStorage::TSyncGuidInfo::EState State;
const TVDiskEternalGuid Guid;
- virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() override {
+ virtual std::unique_ptr<TEvBlobStorage::TEvVSyncGuid> GenerateRequest() override {
// write request
- return std::make_unique<TEvBlobStorage::TEvVSyncGuid>(SelfVDiskId,
+ return std::make_unique<TEvBlobStorage::TEvVSyncGuid>(SelfVDiskId,
TargetVDiskId,
Guid,
State);
diff --git a/ydb/core/blobstorage/vdisk/syncer/guid_recovery.cpp b/ydb/core/blobstorage/vdisk/syncer/guid_recovery.cpp
index d4dc97f9aba..8513936c06a 100644
--- a/ydb/core/blobstorage/vdisk/syncer/guid_recovery.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/guid_recovery.cpp
@@ -310,7 +310,7 @@ namespace NKikimr {
using TLocalVal = NKikimrBlobStorage::TLocalGuidInfo;
TDecisionMaker(const TVDiskIdShort &self,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TLocalSyncerState &locallyRecoveredState)
: Self(self)
, Top(top)
@@ -384,7 +384,7 @@ namespace NKikimr {
private:
const TVDiskIdShort Self;
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Top;
const TLocalSyncerState LocallyRecoveredState;
NSync::TVDiskNeighbors<TNeighborVDiskState> Neighbors;
NSync::TQuorumTracker QuorumTracker;
@@ -635,7 +635,7 @@ namespace NKikimr {
const TActorId CommitterId;
const TActorId NotifyId;
TDecisionMaker DecisionMaker;
- std::unique_ptr<TDecision> Decision;
+ std::unique_ptr<TDecision> Decision;
EPhase Phase = PhaseNotSet;
TActorId FirstRunActorId;
@@ -669,25 +669,25 @@ namespace NKikimr {
GInfo = ev->Get()->NewInfo;
// reconfigure every proxy that hasn't returned a value yet
- auto reconfigureProxy = [&ctx] (std::unique_ptr<TEvVGenerationChange> &&msg,
+ auto reconfigureProxy = [&ctx] (std::unique_ptr<TEvVGenerationChange> &&msg,
TVDiskInfo<TNeighborVDiskState>& x) {
Y_VERIFY(!x.Get().Obtained);
- ctx.Send(x.Get().ProxyId, msg.release());
+ ctx.Send(x.Get().ProxyId, msg.release());
};
using namespace std::placeholders;
- auto call = [&reconfigureProxy, msg = ev->Get()] (TVDiskInfo<TNeighborVDiskState>& x) {
- reconfigureProxy(std::unique_ptr<TEvVGenerationChange>(msg->Clone()), x);
+ auto call = [&reconfigureProxy, msg = ev->Get()] (TVDiskInfo<TNeighborVDiskState>& x) {
+ reconfigureProxy(std::unique_ptr<TEvVGenerationChange>(msg->Clone()), x);
};
DecisionMaker.ReconfigureAllWorkingProxies(call);
}
- STRICT_STFUNC(ObtainGuidQuorumFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvVDiskGuidObtained, Handle)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, HandleObtainGuidQuorumMode)
- )
+ STRICT_STFUNC(ObtainGuidQuorumFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvVDiskGuidObtained, Handle)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, HandleObtainGuidQuorumMode)
+ )
////////////////////////////////////////////////////////////////////////
// Gather Quorum
@@ -703,7 +703,7 @@ namespace NKikimr {
// kill actors that didn't respond
DecisionMaker.AbandomOngoingRequests(ctx);
// reach a verdict and save it
- Decision = std::make_unique<TDecision>(DecisionMaker.ReachAVerdict());
+ Decision = std::make_unique<TDecision>(DecisionMaker.ReachAVerdict());
// log result of guid recovery
auto pri = NActors::NLog::PRI_INFO;
@@ -779,7 +779,7 @@ namespace NKikimr {
void FirstRunPhase(const TActorContext &ctx, EFirstRunStep f) {
auto guid = Decision->GetGuid();
Become(&TThis::WaitForFirstRunStateFunc);
- FirstRunActorId = ctx.Register(CreateVDiskGuidFirstRunActor(VCtx, GInfo, CommitterId, ctx.SelfID, f, guid));
+ FirstRunActorId = ctx.Register(CreateVDiskGuidFirstRunActor(VCtx, GInfo, CommitterId, ctx.SelfID, f, guid));
Phase = PhaseFirstRun;
}
@@ -812,15 +812,15 @@ namespace NKikimr {
ctx.Send(FirstRunActorId, ev->Get()->Clone());
}
- STRICT_STFUNC(WaitForFirstRunStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerGuidFirstRunDone, HandleFirstRunCompleted)
- // NOTE: In PhaseFirstRun phase we can still receive TEvVDiskGuidObtained
- // messages (i.e. replies from the previous phase). Ignore them.
- IgnoreFunc(TEvVDiskGuidObtained)
- HFunc(TEvSublogLine, Handle)
- HFunc(TEvVGenerationChange, HandleFirstRunMode)
- )
+ STRICT_STFUNC(WaitForFirstRunStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerGuidFirstRunDone, HandleFirstRunCompleted)
+ // NOTE: In PhaseFirstRun phase we can still receive TEvVDiskGuidObtained
+ // messages (i.e. replies from the previous phase). Ignore them.
+ IgnoreFunc(TEvVDiskGuidObtained)
+ HFunc(TEvSublogLine, Handle)
+ HFunc(TEvVGenerationChange, HandleFirstRunMode)
+ )
////////////////////////////////////////////////////////////////////////
// Data Loss Phase
@@ -829,7 +829,7 @@ namespace NKikimr {
auto guid = Decision->GetGuid();
Become(&TThis::WaitForSettlingDataLossStateFunc);
auto msg = TEvSyncerCommit::Local(TLocalVal::Lost, guid);
- ctx.Send(CommitterId, msg.release());
+ ctx.Send(CommitterId, msg.release());
Phase = PhaseSettleDataLoss;
}
@@ -839,16 +839,16 @@ namespace NKikimr {
Finish(ctx, TOutcome(*Decision));
}
- STRICT_STFUNC(WaitForSettlingDataLossStateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(TEvSyncerCommitDone, HandleDataLossCompleted)
- // NOTE: In PhaseFirstRun phase we can still receive TEvVDiskGuidObtained
- // messages (i.e. replies from the previous phase). Ignore them.
- IgnoreFunc(TEvVDiskGuidObtained)
- HFunc(TEvSublogLine, Handle)
- // no more communication with other VDisks, can ignore generation change
- IgnoreFunc(TEvVGenerationChange)
- )
+ STRICT_STFUNC(WaitForSettlingDataLossStateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(TEvSyncerCommitDone, HandleDataLossCompleted)
+ // NOTE: In PhaseFirstRun phase we can still receive TEvVDiskGuidObtained
+ // messages (i.e. replies from the previous phase). Ignore them.
+ IgnoreFunc(TEvVDiskGuidObtained)
+ HFunc(TEvSublogLine, Handle)
+ // no more communication with other VDisks, can ignore generation change
+ IgnoreFunc(TEvVGenerationChange)
+ )
////////////////////////////////////////////////////////////////////////
// Handle Poison
@@ -878,8 +878,8 @@ namespace NKikimr {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNC_VDISK_GUID_RECOVERY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNC_VDISK_GUID_RECOVERY;
}
TVDiskGuidRecoveryActor(TIntrusivePtr<TVDiskContext> vctx,
diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_context.h b/ydb/core/blobstorage/vdisk/syncer/syncer_context.h
index ba825dc2f61..a3e21e3ebd0 100644
--- a/ydb/core/blobstorage/vdisk/syncer/syncer_context.h
+++ b/ydb/core/blobstorage/vdisk/syncer/syncer_context.h
@@ -18,7 +18,7 @@ namespace NKikimr {
const TActorId LoggerId;
const TActorId LogCutterId;
const TActorId SyncLogId;
- const TIntrusivePtr<TVDiskConfig> Config;
+ const TIntrusivePtr<TVDiskConfig> Config;
NMonGroup::TSyncerGroup MonGroup;
TSyncerContext(TIntrusivePtr<TVDiskContext> vctx,
@@ -29,7 +29,7 @@ namespace NKikimr {
const TActorId &loggerId,
const TActorId &logCutterId,
const TActorId &syncLogId,
- TIntrusivePtr<TVDiskConfig> config)
+ TIntrusivePtr<TVDiskConfig> config)
: VCtx(std::move(vctx))
, LsnMngr(std::move(lsnMngr))
, PDiskCtx(std::move(pdiskCtx))
@@ -38,7 +38,7 @@ namespace NKikimr {
, LoggerId(loggerId)
, LogCutterId(logCutterId)
, SyncLogId(syncLogId)
- , Config(std::move(config))
+ , Config(std::move(config))
, MonGroup(VCtx->VDiskCounters, "subsystem", "syncer")
{
Y_VERIFY(VCtx && LsnMngr && PDiskCtx);
diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp
index c1a1629bf11..417b5f2d2f4 100644
--- a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.cpp
@@ -7,7 +7,7 @@
#include <ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h>
#include <ydb/core/base/interconnect_channels.h>
#include <library/cpp/actors/core/interconnect.h>
-
+
using namespace NKikimrServices;
using namespace NKikimr::NSyncer;
@@ -24,7 +24,7 @@ namespace NKikimr {
using TBase = TActorBootstrapped<TSyncerJob>;
TIntrusivePtr<TSyncerContext> SyncerCtx;
- std::unique_ptr<TSyncerJobTask> Task;
+ std::unique_ptr<TSyncerJobTask> Task;
const ui32 NodeId;
const TActorId NotifyId;
const ui64 JobId; // just unique job id for log readability
@@ -39,9 +39,9 @@ namespace NKikimr {
if (outcome.ActorActivity) {
if (outcome.RunInBatchPool) {
- RunInBatchPool(ctx, outcome.ActorActivity.release());
+ RunInBatchPool(ctx, outcome.ActorActivity.release());
} else {
- ctx.Register(outcome.ActorActivity.release());
+ ctx.Register(outcome.ActorActivity.release());
}
}
@@ -51,20 +51,20 @@ namespace NKikimr {
TVDiskIdShort vd = Task->VDiskId;
ctx.Send(SyncerCtx->AnubisRunnerId, new TEvFullSyncedWith(vd));
}
- ctx.Send(NotifyId, new TEvSyncerJobDone(std::move(Task)));
+ ctx.Send(NotifyId, new TEvSyncerJobDone(std::move(Task)));
Die(ctx);
}
}
// function for sending a message
- void SendOutcomeMsg(std::unique_ptr<IEventBase> &&ev, TActorId &&to, const TActorContext &ctx) {
+ void SendOutcomeMsg(std::unique_ptr<IEventBase> &&ev, TActorId &&to, const TActorContext &ctx) {
Y_VERIFY(ev && to != TActorId());
// subscribe on Interconnect Session/Message tracking
ui32 flags = IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession;
const auto channel = TInterconnectChannels::IC_BLOBSTORAGE_SYNCER;
flags = IEventHandle::MakeFlags(channel, flags);
- ctx.Send(to, ev.release(), flags);
+ ctx.Send(to, ev.release(), flags);
}
// overridden Die (unsubsribe from Message/Session tracking)
@@ -125,7 +125,7 @@ namespace NKikimr {
void Bootstrap(const TActorContext &ctx) {
// don't run sync job for too long
- ctx.Schedule(SyncerCtx->Config->SyncJobTimeout, new TEvents::TEvWakeup());
+ ctx.Schedule(SyncerCtx->Config->SyncJobTimeout, new TEvents::TEvWakeup());
// initiate requests
TSjOutcome outcome = Task->NextRequest();
@@ -146,7 +146,7 @@ namespace NKikimr {
" id# %s ignress# %s",
JobId, unsigned(Task->IsFullRecoveryTask()),
rec->LogoBlobID().ToString().data(),
- rec->Ingress.ToString(SyncerCtx->VCtx->Top.get(),
+ rec->Ingress.ToString(SyncerCtx->VCtx->Top.get(),
SyncerCtx->VCtx->ShortSelfVDisk,
rec->LogoBlobID()).data()));
};
@@ -162,39 +162,39 @@ namespace NKikimr {
"TSyncerJob::Sync: JobId# %" PRIu64 " FullRecover# %u rec# %s",
JobId, unsigned(Task->IsFullRecoveryTask()), rec->ToString().data()));
};
- auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
- LOG_ERROR(ctx, BS_SYNCER, VDISKP(SyncerCtx->VCtx->VDiskLogPrefix, "TSyncerJob::Sync: JobId# %" PRIu64
- " FullRecover# %u rec# %s", JobId, unsigned(Task->IsFullRecoveryTask()), rec->ToString().data()));
- };
+ auto blockHandlerV2 = [&](const NSyncLog::TBlockRecV2 *rec) {
+ LOG_ERROR(ctx, BS_SYNCER, VDISKP(SyncerCtx->VCtx->VDiskLogPrefix, "TSyncerJob::Sync: JobId# %" PRIu64
+ " FullRecover# %u rec# %s", JobId, unsigned(Task->IsFullRecoveryTask()), rec->ToString().data()));
+ };
NSyncLog::TFragmentReader fragment(data);
- fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
+ fragment.ForEach(blobHandler, blockHandler, barrierHandler, blockHandlerV2);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCER_JOB;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCER_JOB;
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvBlobStorage::TEvVSyncFullResult, Handle)
- HFunc(TEvBlobStorage::TEvVSyncResult, Handle)
- HFunc(TEvLocalSyncDataResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
- IgnoreFunc(TEvInterconnect::TEvNodeConnected)
- HFunc(TEvents::TEvUndelivered, Handle)
- IgnoreFunc(TEvBlobStorage::TEvVWindowChange) // ignore TEvVWindowChange
- )
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvBlobStorage::TEvVSyncFullResult, Handle)
+ HFunc(TEvBlobStorage::TEvVSyncResult, Handle)
+ HFunc(TEvLocalSyncDataResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ HFunc(TEvInterconnect::TEvNodeDisconnected, Handle)
+ IgnoreFunc(TEvInterconnect::TEvNodeConnected)
+ HFunc(TEvents::TEvUndelivered, Handle)
+ IgnoreFunc(TEvBlobStorage::TEvVWindowChange) // ignore TEvVWindowChange
+ )
public:
TSyncerJob(const TIntrusivePtr<TSyncerContext> &sc,
- std::unique_ptr<TSyncerJobTask> task,
+ std::unique_ptr<TSyncerJobTask> task,
const TActorId &notifyId)
: TActorBootstrapped<TSyncerJob>()
, SyncerCtx(sc)
- , Task(std::move(task))
+ , Task(std::move(task))
, NodeId(Task->ServiceId.NodeId())
, NotifyId(notifyId)
, JobId(TAppData::RandomProvider->GenRand64())
@@ -205,9 +205,9 @@ namespace NKikimr {
// TSyncerJob CREATOR
////////////////////////////////////////////////////////////////////////////
IActor* CreateSyncerJob(const TIntrusivePtr<TSyncerContext> &sc,
- std::unique_ptr<TSyncerJobTask> task,
+ std::unique_ptr<TSyncerJobTask> task,
const TActorId &notifyId) {
- return new TSyncerJob(sc, std::move(task), notifyId);
+ return new TSyncerJob(sc, std::move(task), notifyId);
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.h b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.h
index 835c33cbebb..937f69dfad7 100644
--- a/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.h
+++ b/ydb/core/blobstorage/vdisk/syncer/syncer_job_actor.h
@@ -16,10 +16,10 @@ namespace NKikimr {
struct TEvSyncerJobDone :
public TEventLocal<TEvSyncerJobDone, TEvBlobStorage::EvSyncJobDone>
{
- std::unique_ptr<NSyncer::TSyncerJobTask> Task;
+ std::unique_ptr<NSyncer::TSyncerJobTask> Task;
- TEvSyncerJobDone(std::unique_ptr<NSyncer::TSyncerJobTask> task)
- : Task(std::move(task))
+ TEvSyncerJobDone(std::unique_ptr<NSyncer::TSyncerJobTask> task)
+ : Task(std::move(task))
{}
};
@@ -27,7 +27,7 @@ namespace NKikimr {
// TSyncerJob CREATOR
////////////////////////////////////////////////////////////////////////////
IActor* CreateSyncerJob(const TIntrusivePtr<TSyncerContext> &sc,
- std::unique_ptr<NSyncer::TSyncerJobTask> task,
+ std::unique_ptr<NSyncer::TSyncerJobTask> task,
const TActorId &notifyId);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.cpp b/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.cpp
index de98610b833..1a075f9f22d 100644
--- a/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.cpp
+++ b/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.cpp
@@ -16,12 +16,12 @@ namespace NKikimr {
{}
// create TSjCtx using actual Db and GInfo
- std::shared_ptr<TSjCtx> TSjCtx::Create(const TIntrusivePtr<TSyncerContext> &sc,
+ std::shared_ptr<TSjCtx> TSjCtx::Create(const TIntrusivePtr<TSyncerContext> &sc,
const TIntrusivePtr<TBlobStorageGroupInfo> &info)
{
const TVDiskID vdiskId = info->GetVDiskId(sc->VCtx->ShortSelfVDisk);
- // to prevent memory leaks -- unique_ptr ctor does not throw, unlike shared_ptr's one
- return std::shared_ptr<TSjCtx>(std::unique_ptr<TSjCtx>(new TSjCtx(vdiskId, sc)));
+ // to prevent memory leaks -- unique_ptr ctor does not throw, unlike shared_ptr's one
+ return std::shared_ptr<TSjCtx>(std::unique_ptr<TSjCtx>(new TSjCtx(vdiskId, sc)));
}
@@ -52,7 +52,7 @@ namespace NKikimr {
const TVDiskID &vdisk,
const TActorId &service,
const NSyncer::TPeerSyncState &peerState,
- const std::shared_ptr<TSjCtx> &ctx)
+ const std::shared_ptr<TSjCtx> &ctx)
: VDiskId(vdisk)
, ServiceId(service)
, Type(type)
@@ -158,15 +158,15 @@ namespace NKikimr {
Phase = EWaitRemote;
++SentMsg;
if (Type == EFullRecover) {
- auto msg = std::make_unique<TEvBlobStorage::TEvVSyncFull>(Current.SyncState, Ctx->SelfVDiskId, VDiskId,
- FullRecoverInfo->VSyncFullMsgsReceived, FullRecoverInfo->Stage,
- FullRecoverInfo->LogoBlobFrom.LogoBlobID(), FullRecoverInfo->BlockTabletFrom.TabletId,
- FullRecoverInfo->BarrierFrom);
+ auto msg = std::make_unique<TEvBlobStorage::TEvVSyncFull>(Current.SyncState, Ctx->SelfVDiskId, VDiskId,
+ FullRecoverInfo->VSyncFullMsgsReceived, FullRecoverInfo->Stage,
+ FullRecoverInfo->LogoBlobFrom.LogoBlobID(), FullRecoverInfo->BlockTabletFrom.TabletId,
+ FullRecoverInfo->BarrierFrom);
Ctx->SyncerCtx->MonGroup.SyncerVSyncFullBytesSent() += msg->GetCachedByteSize();
++Ctx->SyncerCtx->MonGroup.SyncerVSyncFullMessagesSent();
return TSjOutcome::Event(ServiceId, std::move(msg));
} else {
- auto msg = std::make_unique<TEvBlobStorage::TEvVSync>(Current.SyncState, Ctx->SelfVDiskId, VDiskId);
+ auto msg = std::make_unique<TEvBlobStorage::TEvVSync>(Current.SyncState, Ctx->SelfVDiskId, VDiskId);
Ctx->SyncerCtx->MonGroup.SyncerVSyncBytesSent() += msg->GetCachedByteSize();
++Ctx->SyncerCtx->MonGroup.SyncerVSyncMessagesSent();
return TSjOutcome::Event(ServiceId, std::move(msg));
@@ -191,10 +191,10 @@ namespace NKikimr {
Phase = EWaitLocal;
const TVDiskID vdisk(VDiskIDFromVDiskID(record.GetVDiskID()));
auto syncState = GetCurrent().SyncState;
- auto msg = std::make_unique<TEvLocalSyncData>(vdisk, syncState, data);
+ auto msg = std::make_unique<TEvLocalSyncData>(vdisk, syncState, data);
#ifdef UNPACK_LOCALSYNCDATA
- std::unique_ptr<IActor> actor(CreateLocalSyncDataExtractor(Ctx->SyncerCtx->VCtx, Ctx->SyncerCtx->SkeletonId,
+ std::unique_ptr<IActor> actor(CreateLocalSyncDataExtractor(Ctx->SyncerCtx->VCtx, Ctx->SyncerCtx->SkeletonId,
parentId, std::move(msg)));
return TSjOutcome::Actor(actor.Release(), true);
#else
@@ -330,9 +330,9 @@ namespace NKikimr {
// by lsn, so we need to get them all at once and finally write the correct
// SyncState position.
Phase = EWaitLocal;
- auto msg = std::make_unique<TEvLocalSyncData>(vdisk, OldSyncState, data);
+ auto msg = std::make_unique<TEvLocalSyncData>(vdisk, OldSyncState, data);
#ifdef UNPACK_LOCALSYNCDATA
- std::unique_ptr<IActor> actor(CreateLocalSyncDataExtractor(Ctx->SyncerCtx->VCtx, Ctx->SyncerCtx->SkeletonId,
+ std::unique_ptr<IActor> actor(CreateLocalSyncDataExtractor(Ctx->SyncerCtx->VCtx, Ctx->SyncerCtx->SkeletonId,
parentId, std::move(msg)));
return TSjOutcome::Actor(actor.Release(), true);
#else
diff --git a/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.h b/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.h
index 9d6d0870092..bb296d7461a 100644
--- a/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.h
+++ b/ydb/core/blobstorage/vdisk/syncer/syncer_job_task.h
@@ -26,22 +26,22 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
struct TSjOutcome {
// we can send a message as a result ...
- std::unique_ptr<IEventBase> Ev;
+ std::unique_ptr<IEventBase> Ev;
TActorId To;
// ... or run a actor
- std::unique_ptr<IActor> ActorActivity;
+ std::unique_ptr<IActor> ActorActivity;
bool RunInBatchPool = false;
// ... or/and finish working
bool Die = false;
- static TSjOutcome Event(const TActorId &to, std::unique_ptr<IEventBase> &&ev) {
+ static TSjOutcome Event(const TActorId &to, std::unique_ptr<IEventBase> &&ev) {
TSjOutcome outcome;
outcome.To = to;
outcome.Ev = std::move(ev);
return outcome;
}
- static TSjOutcome Actor(std::unique_ptr<IActor> actor, bool runInBatchPool = false) {
+ static TSjOutcome Actor(std::unique_ptr<IActor> actor, bool runInBatchPool = false) {
TSjOutcome outcome;
outcome.ActorActivity = std::move(actor);
outcome.RunInBatchPool = runInBatchPool;
@@ -71,7 +71,7 @@ namespace NKikimr {
const TIntrusivePtr<TSyncerContext> SyncerCtx;
// create TSjCtx using actual Db and GInfo
- static std::shared_ptr<TSjCtx> Create(
+ static std::shared_ptr<TSjCtx> Create(
const TIntrusivePtr<TSyncerContext> &sc,
const TIntrusivePtr<TBlobStorageGroupInfo> &info);
@@ -133,7 +133,7 @@ namespace NKikimr {
const TVDiskID &vdisk,
const TActorId &service,
const NSyncer::TPeerSyncState &peerState,
- const std::shared_ptr<TSjCtx> &ctx);
+ const std::shared_ptr<TSjCtx> &ctx);
void Output(IOutputStream &str) const;
TString ToString() const;
TSjOutcome NextRequest();
@@ -200,7 +200,7 @@ namespace NKikimr {
// if performing FullRecovery, we save state here
TMaybe<TFullRecoverInfo> FullRecoverInfo;
// context passed to us from outside
- std::shared_ptr<TSjCtx> Ctx;
+ std::shared_ptr<TSjCtx> Ctx;
// Sublog
TSublog<> Sublog;
};
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.cpp
index 907b3873f86..49149ddd67c 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.cpp
@@ -37,7 +37,7 @@ namespace NKikimr {
}
void Handle(TEvSyncLogLocalStatusResult::TPtr &ev, const TActorContext &ctx) {
- std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
+ std::unique_ptr<TEvLocalStatusResult> result(new TEvLocalStatusResult());
NKikimrBlobStorage::TSyncLogStatus *rec = result->Record.MutableSyncLogStatus();
const TLogEssence &e = ev->Get()->Essence;
rec->SetLogStartLsn(e.LogStartLsn);
@@ -48,7 +48,7 @@ namespace NKikimr {
rec->SetFirstDiskLsn(e.FirstDiskLsn);
rec->SetLastDiskLsn(e.LastDiskLsn);
- ctx.Send(Ev->Sender, result.release());
+ ctx.Send(Ev->Sender, result.release());
ctx.Send(NotifyId, new TEvents::TEvCompleted());
Die(ctx);
}
@@ -58,14 +58,14 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
+ STRICT_STFUNC(StateFunc,
HFunc(TEvSyncLogLocalStatusResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_LOCAL_STATUS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_LOCAL_STATUS;
}
TSyncLogGetLocalStatusActor(TIntrusivePtr<TSyncLogCtx> &slCtx,
@@ -95,7 +95,7 @@ namespace NKikimr {
TIntrusivePtr<TBlobStorageGroupInfo> GInfo;
// actual self VDiskID, it is changed during BlobStorage Group reconfiguration
TVDiskID SelfVDiskId;
- std::unique_ptr<TSyncLogRepaired> Repaired;
+ std::unique_ptr<TSyncLogRepaired> Repaired;
TSyncLogNeighborsPtr NeighborsPtr;
const TVDiskIncarnationGuid VDiskIncarnationGuid;
TActorId KeeperId;
@@ -114,7 +114,7 @@ namespace NKikimr {
SlCtx->VCtx->Top,
SlCtx->VCtx->VDiskLogPrefix,
ctx.ExecutorThread.ActorSystem);
- KeeperId = ctx.Register(CreateSyncLogKeeperActor(SlCtx, std::move(Repaired)));
+ KeeperId = ctx.Register(CreateSyncLogKeeperActor(SlCtx, std::move(Repaired)));
ActiveActors.Insert(KeeperId);
TThis::Become(&TThis::StateFunc);
}
@@ -138,11 +138,11 @@ namespace NKikimr {
SelfVDiskId.ToString().data(), sourceVDisk.ToString().data(),
targetVDisk.ToString().data()));
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(NKikimrProto::RACE, SelfVDiskId,
- TSyncState(), true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
- SlCtx->CountersMonGroup.VDiskCheckFailedPtr(), nullptr, std::move(ev->TraceId),
- ev->GetChannel());
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(NKikimrProto::RACE, SelfVDiskId,
+ TSyncState(), true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
+ SlCtx->CountersMonGroup.VDiskCheckFailedPtr(), nullptr, std::move(ev->TraceId),
+ ev->GetChannel());
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
return;
}
@@ -158,10 +158,10 @@ namespace NKikimr {
"sourceVDisk# %s targetVDisk# %s",
sourceVDisk.ToString().data(), targetVDisk.ToString().data()));
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(NKikimrProto::BLOCKED, SelfVDiskId,
- TSyncState(), true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
- SlCtx->CountersMonGroup.DiskLockedPtr(), nullptr, std::move(ev->TraceId), ev->GetChannel());
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(NKikimrProto::BLOCKED, SelfVDiskId,
+ TSyncState(), true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
+ SlCtx->CountersMonGroup.DiskLockedPtr(), nullptr, std::move(ev->TraceId), ev->GetChannel());
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
return;
}
@@ -178,10 +178,10 @@ namespace NKikimr {
auto status = NKikimrProto::RESTART;
TSyncState syncState(VDiskIncarnationGuid, GetDbBirthLsn());
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, SelfVDiskId, syncState,
- true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
- SlCtx->CountersMonGroup.UnequalGuidPtr(), nullptr, std::move(ev->TraceId), ev->GetChannel());
- SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, SelfVDiskId, syncState,
+ true, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(), now,
+ SlCtx->CountersMonGroup.UnequalGuidPtr(), nullptr, std::move(ev->TraceId), ev->GetChannel());
+ SendVDiskResponse(ctx, ev->Sender, result.release(), *this, ev->Cookie);
return;
}
@@ -189,8 +189,8 @@ namespace NKikimr {
CutLog(ctx, sourceVDisk, oldSyncState.SyncedLsn);
// process the request further asyncronously
NeighborsPtr->Lock(sourceVDisk, oldSyncState.SyncedLsn);
- auto aid = ctx.Register(CreateSyncLogReaderActor(SlCtx, VDiskIncarnationGuid, ev, ctx.SelfID, KeeperId,
- SelfVDiskId, sourceVDisk, GetDbBirthLsn(), now));
+ auto aid = ctx.Register(CreateSyncLogReaderActor(SlCtx, VDiskIncarnationGuid, ev, ctx.SelfID, KeeperId,
+ SelfVDiskId, sourceVDisk, GetDbBirthLsn(), now));
ActiveActors.Insert(aid);
}
@@ -203,11 +203,11 @@ namespace NKikimr {
ctx.Send(ev->Forward(KeeperId));
}
- void Handle(TEvSyncLogPutSst::TPtr& ev, const TActorContext& ctx) {
+ void Handle(TEvSyncLogPutSst::TPtr& ev, const TActorContext& ctx) {
++SlCtx->IFaceMonGroup.SyncPutSstMsgs();
ctx.Send(ev->Forward(KeeperId));
- }
-
+ }
+
void Handle(TEvSyncLogReadFinished::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ctx);
NeighborsPtr->Unlock(ev->Get()->VDiskID);
@@ -246,8 +246,8 @@ namespace NKikimr {
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx) {
Y_VERIFY_DEBUG(ev->Get()->SubRequestId == TDbMon::SyncLogId);
- auto aid = ctx.RegisterWithSameMailbox(CreateGetHttpInfoActor(SlCtx->VCtx, GInfo, ev, SelfId(), KeeperId,
- NeighborsPtr));
+ auto aid = ctx.RegisterWithSameMailbox(CreateGetHttpInfoActor(SlCtx->VCtx, GInfo, ev, SelfId(), KeeperId,
+ NeighborsPtr));
ActiveActors.Insert(aid);
}
@@ -257,8 +257,8 @@ namespace NKikimr {
void Handle(TEvLocalStatus::TPtr &ev, const TActorContext &ctx) {
auto selfId = ctx.SelfID;
- auto actor = std::make_unique<TSyncLogGetLocalStatusActor>(SlCtx, ev, selfId, KeeperId);
- auto aid = ctx.Register(actor.release());
+ auto actor = std::make_unique<TSyncLogGetLocalStatusActor>(SlCtx, ev, selfId, KeeperId);
+ auto aid = ctx.Register(actor.release());
ActiveActors.Insert(aid);
}
@@ -285,36 +285,36 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncLogPut, Handle)
- HFunc(TEvSyncLogPutSst, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncLogPut, Handle)
+ HFunc(TEvSyncLogPutSst, Handle)
HFunc(TEvBlobStorage::TEvVSync, Handle)
- HFunc(TEvSyncLogReadFinished, Handle)
- HFunc(TEvSyncLogDbBirthLsn, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(NMon::TEvHttpInfo, Handle)
+ HFunc(TEvSyncLogReadFinished, Handle)
+ HFunc(TEvSyncLogDbBirthLsn, Handle)
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(NMon::TEvHttpInfo, Handle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, Handle)
- HFunc(TEvLocalStatus, Handle)
- HFunc(TEvVGenerationChange, Handle)
- HFunc(TEvents::TEvCompleted, HandleActorCompletion)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvLocalStatus, Handle)
+ HFunc(TEvVGenerationChange, Handle)
+ HFunc(TEvents::TEvCompleted, HandleActorCompletion)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_ACTOR;
}
TSyncLogActor(
const TIntrusivePtr<TSyncLogCtx> &slCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo,
const TVDiskID &selfVDiskId,
- std::unique_ptr<TSyncLogRepaired> repaired)
+ std::unique_ptr<TSyncLogRepaired> repaired)
: TActorBootstrapped<TSyncLogActor>()
, SlCtx(slCtx)
, GInfo(ginfo)
, SelfVDiskId(selfVDiskId)
- , Repaired(std::move(repaired))
+ , Repaired(std::move(repaired))
, NeighborsPtr()
, VDiskIncarnationGuid(Repaired->SyncLogPtr->Header.VDiskIncarnationGuid)
, KeeperId()
@@ -327,8 +327,8 @@ namespace NKikimr {
const TIntrusivePtr<TSyncLogCtx> &slCtx,
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo,
const TVDiskID &selfVDiskId,
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired) {
- return new TSyncLogActor(slCtx, ginfo, selfVDiskId, std::move(repaired));
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired) {
+ return new TSyncLogActor(slCtx, ginfo, selfVDiskId, std::move(repaired));
}
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.h
index 3347e9d0607..70f8ea72bb1 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog.h
@@ -21,6 +21,6 @@ namespace NKikimr {
const TIntrusivePtr<TBlobStorageGroupInfo> &ginfo,
const TVDiskID &selfVDiskId,
// state we got after local recovery
- std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired);
+ std::unique_ptr<NSyncLog::TSyncLogRepaired> repaired);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h
index 48616643a85..46a297b5376 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclog_public_events.h
@@ -26,8 +26,8 @@ namespace NKikimr {
SeqOfRecs.SetLogoBlob(gtype, lsn, id, ingress);
}
- TEvSyncLogPut(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
- SeqOfRecs.SetBlock(lsn, tabletId, gen, issuerGuid);
+ TEvSyncLogPut(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
+ SeqOfRecs.SetBlock(lsn, tabletId, gen, issuerGuid);
}
TEvSyncLogPut(const TBlobStorageGroupType &gtype,
@@ -147,7 +147,7 @@ namespace NKikimr {
const ui64 SyncLogMaxEntryPointSize;
const ui64 SyncLogMaxMemAmount;
const ui32 MaxResponseSize;
- std::shared_ptr<TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
+ std::shared_ptr<TSyncLogFirstLsnToKeep> SyncLogFirstLsnToKeep;
NMonGroup::TSyncLogIFaceGroup IFaceMonGroup;
NMonGroup::TSyncLogCountersGroup CountersMonGroup;
@@ -161,7 +161,7 @@ namespace NKikimr {
ui64 syncLogMaxEntryPointSize,
ui64 syncLogMaxMemAmount,
ui32 maxResponseSize,
- std::shared_ptr<TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep)
+ std::shared_ptr<TSyncLogFirstLsnToKeep> syncLogFirstLsnToKeep)
: VCtx(std::move(vctx))
, LsnMngr(std::move(lsnMngr))
, PDiskCtx(std::move(pdiskCtx))
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.cpp
index c58468bd599..0b11ac0b5f5 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.cpp
@@ -258,8 +258,8 @@ namespace NKikimr {
const TEntryPointDbgInfo &TSyncLog::GetLastEntryPointDbgInfo() const {
return LastEntryPointDbgInfo;
- }
-
+ }
+
TString TSyncLog::BoundariesToString() const {
return Sprintf("{LogStartLsn: %" PRIu64 " LastLsnOfIndexRecord: %" PRIu64
" %s %s}", LogStartLsn, LastLsnOfIndexRecord,
@@ -310,7 +310,7 @@ namespace NKikimr {
TVector<ui32> TSyncLog::TrimLogByConfirmedLsn(
ui64 confirmedCutLsn,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
std::function<void(const TString&)> logger)
{
if (LogStartLsn > confirmedCutLsn + 1) {
@@ -331,7 +331,7 @@ namespace NKikimr {
TVector<ui32> TSyncLog::TrimLogByRemovingChunks(
ui32 numChunksToDel,
- std::shared_ptr<IActorNotify> notifier)
+ std::shared_ptr<IActorNotify> notifier)
{
TVector<ui32> chunks;
ui64 sLsn = DiskRecLog.DeleteChunks(numChunksToDel, std::move(notifier), chunks);
@@ -488,9 +488,9 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TEntryPointParser - a class for parsing SyncLog entry point
////////////////////////////////////////////////////////////////////////////
- bool TEntryPointParser::Parse(const TString &serializedData, bool &needsInitialCommit, TString &explanation) {
+ bool TEntryPointParser::Parse(const TString &serializedData, bool &needsInitialCommit, TString &explanation) {
NKikimrVDiskData::TSyncLogEntryPoint pb;
- bool success = ParseToProto(pb, serializedData, needsInitialCommit, explanation);
+ bool success = ParseToProto(pb, serializedData, needsInitialCommit, explanation);
if (!success) {
return false;
}
@@ -529,13 +529,13 @@ namespace NKikimr {
bool TEntryPointParser::ParseToProto(
NKikimrVDiskData::TSyncLogEntryPoint &pb,
const TString &serializedData,
- bool &needsInitialCommit,
+ bool &needsInitialCommit,
TString &explanation)
{
TStringStream err;
if (serializedData.empty()) {
// empty entry point
- needsInitialCommit = true;
+ needsInitialCommit = true;
FillInEmptyEntryPoint(pb);
return true;
}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.h
index 15ee59bfe46..8aa6f952b71 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata.h
@@ -195,12 +195,12 @@ namespace NKikimr {
// chunks to delete (i.e. free)
TVector<ui32> TrimLogByConfirmedLsn(
ui64 confirmedCutLsn,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
std::function<void(const TString&)> logger);
// trim log by removing chunks over some quota, i.e. we got
// too many chunks allocated for SyncLog and want to remove numChunksToDel;
// the function returns chunks to delete (i.e. free)
- TVector<ui32> TrimLogByRemovingChunks(ui32 numChunksToDel, std::shared_ptr<IActorNotify> notifier);
+ TVector<ui32> TrimLogByRemovingChunks(ui32 numChunksToDel, std::shared_ptr<IActorNotify> notifier);
////////////////////////////////////////////////////////////////////////
@@ -304,7 +304,7 @@ namespace NKikimr {
: Params(std::move(params))
{}
- bool Parse(const TString &serializedData, bool &needsInitialCommit, TString &explanation);
+ bool Parse(const TString &serializedData, bool &needsInitialCommit, TString &explanation);
TSyncLogPtr GetSyncLogPtr() const { return SyncLogPtr; }
TVector<ui32> GetChunksToDelete() const { return ChunksToDelete; }
ui64 GetRecoveryLogConfirmedLsn() const { return RecoveryLogConfirmedLsn; }
@@ -318,7 +318,7 @@ namespace NKikimr {
bool ParseToProto(
NKikimrVDiskData::TSyncLogEntryPoint &pb,
const TString &serializedData,
- bool &needsInitialCommit,
+ bool &needsInitialCommit,
TString &explanation);
bool ConvertOldFormatToProto(
NKikimrVDiskData::TSyncLogEntryPoint &pb,
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata_ut.cpp
index 5a5024382a3..3f38e9df8c4 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdata_ut.cpp
@@ -23,8 +23,8 @@ namespace NKikimr {
TSyncLogParams params(pDiskGuid, chunkSize, appendBlockSize, syncLogAdvisedIndexedBlockSize, memConsumer);
TEntryPointParser parser(std::move(params));
TString explanation;
- bool needsInitialCommit;
- bool success = parser.Parse(serializedData, needsInitialCommit, explanation);
+ bool needsInitialCommit;
+ bool success = parser.Parse(serializedData, needsInitialCommit, explanation);
UNIT_ASSERT(success);
return parser;
}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.cpp
index 1a2fb95e1c5..a9e88e92a2a 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.cpp
@@ -340,15 +340,15 @@ namespace NKikimr {
PagesInChunk,
IndexBulk));
ptr->ManyIdxChunks = ManyIdxChunks;
- if (!ManyIdxChunks.empty()) {
- auto& lastChunk = ptr->ManyIdxChunks.back();
- lastChunk = lastChunk->DeepCopy();
- }
+ if (!ManyIdxChunks.empty()) {
+ auto& lastChunk = ptr->ManyIdxChunks.back();
+ lastChunk = lastChunk->DeepCopy();
+ }
return ptr;
}
ui32 TDiskRecLog::TrimLog(ui64 confirmedCutLsn,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
TVector<ui32> &chunks) {
auto m = Guard(Lock);
ui32 nchunks = 0;
@@ -367,7 +367,7 @@ namespace NKikimr {
// force to delete nchunks (if we don't have space for instance)
ui64 TDiskRecLog::DeleteChunks(ui32 nchunks,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
TVector<ui32> &chunks) {
auto m = Guard(Lock);
const ui32 curChunks = ManyIdxChunks.size();
@@ -462,11 +462,11 @@ namespace NKikimr {
}
void TDiskRecLog::GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- for (const TIndexedChunkPtr& chunk : ManyIdxChunks) {
- chunk->GetOwnedChunks(chunks);
- }
- }
-
+ for (const TIndexedChunkPtr& chunk : ManyIdxChunks) {
+ chunk->GetOwnedChunks(chunks);
+ }
+ }
+
ui32 TDiskRecLog::HowManyChunksAdds(const TMemRecLogSnapshotPtr &swapSnap) const {
auto m = Guard(Lock);
// find out how many new chunks swapSnap adds
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.h
index f6b8a3abaaf..30c86274eec 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk.h
@@ -9,7 +9,7 @@
#include <util/generic/deque.h>
#include <util/generic/queue.h>
#include <util/generic/algorithm.h>
-#include <util/generic/set.h>
+#include <util/generic/set.h>
#include <util/string/printf.h>
namespace NKikimr {
@@ -112,7 +112,7 @@ namespace NKikimr {
return ChunkIdx == c.ChunkIdx;
}
- void SetUpNotifier(std::shared_ptr<IActorNotify> n) {
+ void SetUpNotifier(std::shared_ptr<IActorNotify> n) {
Notifier = std::move(n);
}
@@ -133,15 +133,15 @@ namespace NKikimr {
}
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- const bool inserted = chunks.insert(ChunkIdx).second;
- Y_VERIFY(inserted);
- }
-
+ const bool inserted = chunks.insert(ChunkIdx).second;
+ Y_VERIFY(inserted);
+ }
+
static std::pair<TOneChunkPtr, const char *> Construct(const char *serialized);
private:
ui32 ChunkIdx = 0;
- std::shared_ptr<IActorNotify> Notifier;
+ std::shared_ptr<IActorNotify> Notifier;
};
////////////////////////////////////////////////////////////////////////////
@@ -187,10 +187,10 @@ namespace NKikimr {
return s.Str();
}
- TOneChunkIndexPtr DeepCopy() const {
- return new TOneChunkIndex(*this);
- }
-
+ TOneChunkIndexPtr DeepCopy() const {
+ return new TOneChunkIndex(*this);
+ }
+
void UpdateIndex(const TVector<TSyncLogPageSnap> &pages, ui32 indexBulk);
void OutputHtml(IOutputStream &str) const;
// returns number of index records
@@ -311,7 +311,7 @@ namespace NKikimr {
return IndexPtr->GetLastLsn();
}
- void SetUpNotifier(std::shared_ptr<IActorNotify> n) {
+ void SetUpNotifier(std::shared_ptr<IActorNotify> n) {
ChunkPtr->SetUpNotifier(std::move(n));
}
@@ -340,10 +340,10 @@ namespace NKikimr {
return TOneChunkIndex::TIterator(IndexPtr);
}
- TIndexedChunkPtr DeepCopy() const {
- return new TIndexedChunk(ChunkPtr, IndexPtr->DeepCopy());
- }
-
+ TIndexedChunkPtr DeepCopy() const {
+ return new TIndexedChunk(ChunkPtr, IndexPtr->DeepCopy());
+ }
+
void OutputHtml(IOutputStream &str) const;
static std::pair<TIndexedChunkPtr, const char *> Construct(const char *serialized);
TString ToString() const {
@@ -353,9 +353,9 @@ namespace NKikimr {
}
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const {
- ChunkPtr->GetOwnedChunks(chunks);
- }
-
+ ChunkPtr->GetOwnedChunks(chunks);
+ }
+
private:
TOneChunkPtr ChunkPtr;
TOneChunkIndexPtr IndexPtr;
@@ -490,7 +490,7 @@ namespace NKikimr {
++ChunkIt;
if (ChunkIt != SnapPtr->ManyIdxChunks.end()) {
IdxBulkIt = (*ChunkIt)->GetIndexIterator();
- IdxBulkIt.SeekToFirst();
+ IdxBulkIt.SeekToFirst();
Y_VERIFY_DEBUG(IdxBulkIt.Valid(), "ChunkIdx# %u", (*ChunkIt)->GetChunkIdx());
}
}
@@ -564,12 +564,12 @@ namespace NKikimr {
// cut log because we synced
ui32 TrimLog(ui64 confirmedCutLsn,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
TVector<ui32> &chunks);
// force to delete nchunks (if we don't have space for instance);
// returns new LogStartLsn
ui64 DeleteChunks(ui32 nchunks,
- std::shared_ptr<IActorNotify> notifier,
+ std::shared_ptr<IActorNotify> notifier,
TVector<ui32> &chunks);
void UpdateIndex(ui32 chunkIdx, const TVector<TSyncLogPageSnap> &pages);
void UpdateIndex(const TDeltaToDiskRecLog &delta);
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk_ut.cpp
index 59d02b15f5f..5e3369a2a76 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogdsk_ut.cpp
@@ -19,7 +19,7 @@ namespace NKikimr {
ui32 size = 0;
ui64 tabletId = 1;
for (unsigned i = 0; i < num; i++) {
- size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
+ size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
ctx.Lsn += 2;
ctx.Gen++;
page->Put(pageSize, (const NSyncLog::TRecordHdr *)buf, size);
@@ -43,7 +43,7 @@ namespace NKikimr {
char buf[NSyncLog::MaxRecFullSize];
ui64 tabletId = 1;
while (memLog.GetNumberOfPages() < pagesNum) {
- ui32 size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
+ ui32 size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
ctx.Lsn++;
ctx.Gen++;
memLog.PutOne((const TRecordHdr *)buf, size);
@@ -70,7 +70,7 @@ namespace NKikimr {
// that 'dsk->UpdateIndex' == 'dsk->GetSnapshot()->Serialize(delta) + Load'
void UpdateIndexWithCheck(TDiskRecLog *dsk, const TDeltaToDiskRecLog &delta) {
// build separate index via snapshot
- std::unique_ptr<TDiskRecLog> uDsk = BuildUpdatedIndex(dsk, delta);
+ std::unique_ptr<TDiskRecLog> uDsk = BuildUpdatedIndex(dsk, delta);
// update dsk in 'traditional way'
dsk->UpdateIndex(delta);
// check that both ways give the same result
@@ -83,14 +83,14 @@ namespace NKikimr {
ui32 IndexBulk;
// Build new TDiskRecLog via snapshot serialization and loading
- std::unique_ptr<TDiskRecLog> BuildUpdatedIndex(TDiskRecLog *dsk,
+ std::unique_ptr<TDiskRecLog> BuildUpdatedIndex(TDiskRecLog *dsk,
const TDeltaToDiskRecLog &delta) {
// get snapshot and serialize it with delta
auto snap = dsk->GetSnapshot();
TStringStream s;
snap->Serialize(s, delta);
const TString serialized = s.Str();
- std::unique_ptr<TDiskRecLog> uDsk = std::make_unique<TDiskRecLog>(ChunkSize,
+ std::unique_ptr<TDiskRecLog> uDsk = std::make_unique<TDiskRecLog>(ChunkSize,
PageSize,
IndexBulk,
serialized.data(),
@@ -107,7 +107,7 @@ namespace NKikimr {
ui32 pageSize = 16u << 10u;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int i = 0; i < 5; i++) {
@@ -118,12 +118,12 @@ namespace NKikimr {
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
}
TString result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 1} {FirstLsn# 21 OffsInPages# 1 PagesNum# 1} "
@@ -151,7 +151,7 @@ namespace NKikimr {
ui32 pageSize = 16u << 10u;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
// add first portion
@@ -164,12 +164,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TString result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 4} {FirstLsn# 81 OffsInPages# 4 PagesNum# 1} "
@@ -187,12 +187,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 4} {FirstLsn# 81 OffsInPages# 4 PagesNum# 1} "
@@ -209,7 +209,7 @@ namespace NKikimr {
ui32 pagesInChunk = chunkSize / pageSize;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int k = 0; k < 4; k++) {
@@ -222,12 +222,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(k * 2 / pagesInChunk, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TString result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 2} {FirstLsn# 41 OffsInPages# 2 PagesNum# 2} "
"LastRealLsn# 79}} {1 {{FirstLsn# 81 OffsInPages# 0 PagesNum# 2} "
@@ -242,7 +242,7 @@ namespace NKikimr {
ui32 pageSize = 16u << 10u;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int i = 0; i < 2; i++) {
@@ -253,12 +253,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
// create a page
@@ -270,12 +270,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
@@ -288,12 +288,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TString result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 1} {FirstLsn# 21 OffsInPages# 1 PagesNum# 1} "
@@ -308,7 +308,7 @@ namespace NKikimr {
ui32 pageSize = 16u << 10u;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int i = 0; i < 2; i++) {
@@ -319,12 +319,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
// create a page
@@ -338,12 +338,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
// append to the page
@@ -355,12 +355,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TString result = "{0 {{FirstLsn# 1 OffsInPages# 0 PagesNum# 1} {FirstLsn# 21 OffsInPages# 1 PagesNum# 1} "
@@ -376,7 +376,7 @@ namespace NKikimr {
ui32 pageSize = 16u << 10u;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
@@ -392,7 +392,7 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(0, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
}
{
@@ -411,7 +411,7 @@ namespace NKikimr {
delta.Append(1, pages);
// update: update page from chunk 0 and add page from chunk 1
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
}
}
@@ -421,7 +421,7 @@ namespace NKikimr {
ui32 pagesInChunk = chunkSize / pageSize;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int k = 0; k < 8; k++) {
@@ -433,12 +433,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(k * 2 / pagesInChunk, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TVector<ui32> chunks;
@@ -465,7 +465,7 @@ namespace NKikimr {
ui32 pagesInChunk = chunkSize / pageSize;
ui32 indexBulk = 4;
TUpdChecker uc(chunkSize, pageSize, indexBulk);
- std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
+ std::unique_ptr<TDiskRecLog> dsk(new TDiskRecLog(chunkSize, pageSize, indexBulk, nullptr, nullptr));
TFillIn1Context ctx {1, 1};
for (int k = 0; k < 8; k++) {
@@ -477,12 +477,12 @@ namespace NKikimr {
// update
TDeltaToDiskRecLog delta(indexBulk);
delta.Append(k * 2 / pagesInChunk, pages);
- uc.UpdateIndexWithCheck(dsk.get(), delta);
+ uc.UpdateIndexWithCheck(dsk.get(), delta);
TStringStream s;
dsk->Serialize(s);
TString serialized = s.Str();
- dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
+ dsk.reset(new TDiskRecLog(chunkSize, pageSize, indexBulk, serialized.data(), serialized.data() + serialized.size()));
}
TVector<ui32> chunks;
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.cpp
index 3648ac95b90..85e975cdda1 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.cpp
@@ -28,22 +28,22 @@ namespace NKikimr {
}
// Block
- ui32 TSerializeRoutines::SetBlock(char *buf, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
- if (issuerGuid) {
- TRecordHdr *hdr = (TRecordHdr *)buf;
- hdr->RecType = TRecordHdr::RecBlockV2;
- hdr->Lsn = lsn;
- new(hdr + 1) TBlockRecV2(tabletId, gen, issuerGuid);
- return sizeof(TRecordHdr) + sizeof(TBlockRecV2);
- } else {
- TRecordHdr *hdr = (TRecordHdr *)buf;
- TBlockRec *rec = (TBlockRec *)(hdr + 1);
- hdr->RecType = TRecordHdr::RecBlock;
- hdr->Lsn = lsn;
- rec->TabletId = tabletId;
- rec->Generation = gen;
- return sizeof(TRecordHdr) + sizeof(TBlockRec);
- }
+ ui32 TSerializeRoutines::SetBlock(char *buf, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
+ if (issuerGuid) {
+ TRecordHdr *hdr = (TRecordHdr *)buf;
+ hdr->RecType = TRecordHdr::RecBlockV2;
+ hdr->Lsn = lsn;
+ new(hdr + 1) TBlockRecV2(tabletId, gen, issuerGuid);
+ return sizeof(TRecordHdr) + sizeof(TBlockRecV2);
+ } else {
+ TRecordHdr *hdr = (TRecordHdr *)buf;
+ TBlockRec *rec = (TBlockRec *)(hdr + 1);
+ hdr->RecType = TRecordHdr::RecBlock;
+ hdr->Lsn = lsn;
+ rec->TabletId = tabletId;
+ rec->Generation = gen;
+ return sizeof(TRecordHdr) + sizeof(TBlockRec);
+ }
}
// Barrier
@@ -67,7 +67,7 @@ namespace NKikimr {
rec->GenCounter = genCounter;
rec->CollectGeneration = collGen;
rec->CollectStep = collStep;
- rec->Hard = hard;
+ rec->Hard = hard;
rec->Ingress = ingress;
return sizeof(TRecordHdr) + sizeof(TBarrierRec);
}
@@ -88,7 +88,7 @@ namespace NKikimr {
const ui32 genCounter = record.GetPerGenerationCounter();
const ui32 collectGeneration = record.GetCollectGeneration();
const ui32 collectStep = record.GetCollectStep();
- const bool hard = record.GetHard();
+ const bool hard = record.GetHard();
ui64 lsnAdvance = !!collect + record.KeepSize() + record.DoNotKeepSize();
ui64 lsnPos = lsn - lsnAdvance + 1;
@@ -96,7 +96,7 @@ namespace NKikimr {
// set up keep bits
TIngress ingressKeep;
- ingressKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeKeep);
+ ingressKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeKeep);
for (ui32 i = 0; i < record.KeepSize(); ++i, ++lsnPos) {
if (lsnPos > lastLsnOfIndexRecord) {
TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetKeep(i));
@@ -108,7 +108,7 @@ namespace NKikimr {
// set up do not keep bits
TIngress ingressDontKeep;
- ingressDontKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeDoNotKeep);
+ ingressDontKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeDoNotKeep);
for (ui32 i = 0; i < record.DoNotKeepSize(); ++i, ++lsnPos) {
if (lsnPos > lastLsnOfIndexRecord) {
TLogoBlobID id = LogoBlobIDFromLogoBlobID(record.GetDoNotKeep(i));
@@ -122,7 +122,7 @@ namespace NKikimr {
if (collect && (lsnPos > lastLsnOfIndexRecord)) {
ui32 size = SetBarrier(pos, lsnPos++, tabletId, channel, gen,
genCounter, collectGeneration,
- collectStep, hard, ingress);
+ collectStep, hard, ingress);
pos += size;
}
@@ -133,17 +133,17 @@ namespace NKikimr {
char *buf,
ui64 lsn,
const TDeque<TLogoBlobID>& phantoms) {
- char *pos = buf;
-
- TIngress ingressDontKeep;
- ingressDontKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeDoNotKeep);
- for (const TLogoBlobID& id : phantoms) {
+ char *pos = buf;
+
+ TIngress ingressDontKeep;
+ ingressDontKeep.SetKeep(TIngress::IngressMode(gtype), CollectModeDoNotKeep);
+ for (const TLogoBlobID& id : phantoms) {
pos += SetLogoBlob(gtype, pos, lsn++, id, ingressDontKeep);
- }
-
- return pos - buf;
- }
-
+ }
+
+ return pos - buf;
+ }
+
bool TSerializeRoutines::CheckData(const TString &data, TString &errorString) {
const TRecordHdr *begin = (const TRecordHdr *)(data.data());
const TRecordHdr *end = (const TRecordHdr *)(data.data() + data.size());
@@ -153,7 +153,7 @@ namespace NKikimr {
case TRecordHdr::RecLogoBlob:
case TRecordHdr::RecBlock:
case TRecordHdr::RecBarrier:
- case TRecordHdr::RecBlockV2:
+ case TRecordHdr::RecBlockV2:
break;
default: {
TStringStream str;
@@ -178,9 +178,9 @@ namespace NKikimr {
Size = TSerializeRoutines::SetLogoBlob(gtype, Buf, lsn, id, ingress);
}
- void TSequenceOfRecs::SetBlock(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
+ void TSequenceOfRecs::SetBlock(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid) {
Y_VERIFY(Size == 0);
- Size = TSerializeRoutines::SetBlock(Buf, lsn, tabletId, gen, issuerGuid);
+ Size = TSerializeRoutines::SetBlock(Buf, lsn, tabletId, gen, issuerGuid);
}
void TSequenceOfRecs::SetBarrier(ui64 lsn,
@@ -190,11 +190,11 @@ namespace NKikimr {
ui32 genCounter,
ui32 collGen,
ui32 collStep,
- bool hard,
+ bool hard,
const TBarrierIngress &ingress) {
Y_VERIFY(Size == 0);
Size = TSerializeRoutines::SetBarrier(Buf, lsn, tabletId, channel, gen, genCounter,
- collGen, collStep, hard, ingress);
+ collGen, collStep, hard, ingress);
}
void TSequenceOfRecs::SetGC(const TBlobStorageGroupType &gtype,
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.h
index 396c4e7a39a..aa443315229 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogformat.h
@@ -51,29 +51,29 @@ namespace NKikimr {
return Sprintf("[TabletId# %" PRIu64 " Generation# %" PRIu32 "]", TabletId, Generation);
}
};
-
- struct TBlockRecV2 {
- ui64 TabletId;
- ui32 Generation;
- ui64 IssuerGuid;
-
- TBlockRecV2(ui64 tabletId = 0, ui32 generation = 0, ui64 issuerGuid = 0)
- : TabletId(tabletId)
- , Generation(generation)
- , IssuerGuid(issuerGuid)
- {}
-
- TString ToString() const {
- return TStringBuilder() << "[TabletId# " << TabletId << " Generation# " << Generation
- << " IssuerGuid# " << IssuerGuid << "]";
- }
- };
+
+ struct TBlockRecV2 {
+ ui64 TabletId;
+ ui32 Generation;
+ ui64 IssuerGuid;
+
+ TBlockRecV2(ui64 tabletId = 0, ui32 generation = 0, ui64 issuerGuid = 0)
+ : TabletId(tabletId)
+ , Generation(generation)
+ , IssuerGuid(issuerGuid)
+ {}
+
+ TString ToString() const {
+ return TStringBuilder() << "[TabletId# " << TabletId << " Generation# " << Generation
+ << " IssuerGuid# " << IssuerGuid << "]";
+ }
+ };
struct TBarrierRec {
ui64 TabletId;
- ui32 Channel : 8;
- ui32 Reserved : 23;
- ui32 Hard : 1;
+ ui32 Channel : 8;
+ ui32 Reserved : 23;
+ ui32 Hard : 1;
ui32 Gen;
ui32 GenCounter;
ui32 CollectGeneration;
@@ -81,11 +81,11 @@ namespace NKikimr {
TBarrierIngress Ingress;
TBarrierRec(ui64 tabletId = 0, ui32 channel = 0, ui32 gen = 0, ui32 genCounter = 0, ui32 collGen = 0,
- ui32 collStep = 0, bool hard = false, ui64 ingressRaw = 0)
+ ui32 collStep = 0, bool hard = false, ui64 ingressRaw = 0)
: TabletId(tabletId)
, Channel(channel)
- , Reserved(0)
- , Hard(hard)
+ , Reserved(0)
+ , Hard(hard)
, Gen(gen)
, GenCounter(genCounter)
, CollectGeneration(collGen)
@@ -94,7 +94,7 @@ namespace NKikimr {
{}
TString ToString() const {
- return Sprintf("[TabletId# %" PRIu64 " Channel# %" PRIu32 " %s]", TabletId, Channel, Hard ? "hard" : "soft");
+ return Sprintf("[TabletId# %" PRIu64 " Channel# %" PRIu32 " %s]", TabletId, Channel, Hard ? "hard" : "soft");
}
};
@@ -102,8 +102,8 @@ namespace NKikimr {
enum ESyncLogRecType {
RecLogoBlob,
RecBlock,
- RecBarrier,
- RecBlockV2,
+ RecBarrier,
+ RecBlockV2,
};
ui64 RecType : 2;
@@ -123,7 +123,7 @@ namespace NKikimr {
case RecLogoBlob: payloadSize = sizeof(TLogoBlobRec); break;
case RecBlock: payloadSize = sizeof(TBlockRec); break;
case RecBarrier: payloadSize = sizeof(TBarrierRec); break;
- case RecBlockV2: payloadSize = sizeof(TBlockRecV2); break;
+ case RecBlockV2: payloadSize = sizeof(TBlockRecV2); break;
default: Y_FAIL("Unsupported type: RecType=%" PRIu64 " Lsn=%" PRIu64, (ui64)RecType, Lsn);
}
return sizeof(*this) + payloadSize;
@@ -134,7 +134,7 @@ namespace NKikimr {
case RecLogoBlob: return "LogoBlob";
case RecBlock: return "Block";
case RecBarrier: return "Barrier";
- case RecBlockV2: return "Block";
+ case RecBlockV2: return "Block";
default: return "Unknown";
}
}
@@ -154,11 +154,11 @@ namespace NKikimr {
return (const TBarrierRec *)(this + 1);
}
- const TBlockRecV2 *GetBlockV2() const {
- Y_VERIFY_DEBUG(RecType == RecBlockV2);
- return (const TBlockRecV2 *)(this + 1);
- }
-
+ const TBlockRecV2 *GetBlockV2() const {
+ Y_VERIFY_DEBUG(RecType == RecBlockV2);
+ return (const TBlockRecV2 *)(this + 1);
+ }
+
TString ToString() const {
return Sprintf("{Lsn# %" PRIu64 " Rec# %s %s}", Lsn, RecTypeToStr(RecType), ValueToString().data());
}
@@ -168,7 +168,7 @@ namespace NKikimr {
case RecLogoBlob: return GetLogoBlob()->ToString();
case RecBlock: return GetBlock()->ToString();
case RecBarrier: return GetBarrier()->ToString();
- case RecBlockV2: return GetBlockV2()->ToString();
+ case RecBlockV2: return GetBlockV2()->ToString();
default: Y_FAIL("Unsupported type: RecType=%" PRIu64 " Lsn=%" PRIu64, (ui64)RecType, Lsn);
}
}
@@ -196,7 +196,7 @@ namespace NKikimr {
ui64 lsn,
const TLogoBlobID &id,
const TIngress &ingress);
- static ui32 SetBlock(char *buf, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid);
+ static ui32 SetBlock(char *buf, ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid);
static ui32 SetBarrier(char *buf,
ui64 lsn,
ui64 tabletId,
@@ -205,7 +205,7 @@ namespace NKikimr {
ui32 genCounter,
ui32 collGen,
ui32 collStep,
- bool hard,
+ bool hard,
const TBarrierIngress &ingress);
static ui32 SetGC(const TBlobStorageGroupType &gtype,
char *buf,
@@ -230,7 +230,7 @@ namespace NKikimr {
ui64 lsn,
const TLogoBlobID &id,
const TIngress &ingress);
- void SetBlock(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid);
+ void SetBlock(ui64 lsn, ui64 tabletId, ui32 gen, ui64 issuerGuid);
void SetBarrier(ui64 lsn,
ui64 tabletId,
ui32 channel,
@@ -238,7 +238,7 @@ namespace NKikimr {
ui32 genCounter,
ui32 collGen,
ui32 collStep,
- bool hard,
+ bool hard,
const TBarrierIngress &ingress);
void SetGC(const TBlobStorageGroupType &gtype,
ui64 lsn,
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_syncloghttp.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_syncloghttp.cpp
index cc10f0ceed6..412eae66788 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_syncloghttp.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_syncloghttp.cpp
@@ -93,15 +93,15 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncLogSnapshotResult, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncLogSnapshotResult, Handle)
HFunc(TEvInterconnect::TEvNodesInfo, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_HTTPINFO;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_HTTPINFO;
}
TSyncLogGetHttpInfoActor(const TIntrusivePtr<TVDiskContext> &vctx,
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.cpp
index c7893daa0a6..135c374ec12 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.cpp
@@ -31,9 +31,9 @@ namespace NKikimr {
void Bootstrap(const TActorContext &ctx) {
KeepState.Init(
- std::make_shared<TActorNotify>(ctx.ExecutorThread.ActorSystem, ctx.SelfID),
- std::make_shared<TActorSystemLoggerCtx>(ctx.ExecutorThread.ActorSystem));
- PerformActions(ctx);
+ std::make_shared<TActorNotify>(ctx.ExecutorThread.ActorSystem, ctx.SelfID),
+ std::make_shared<TActorSystemLoggerCtx>(ctx.ExecutorThread.ActorSystem));
+ PerformActions(ctx);
Become(&TThis::StateFunc);
}
@@ -68,11 +68,11 @@ namespace NKikimr {
return KeepState.PerformDeleteChunkAction();
}
- bool PerformInitialCommit() {
- return KeepState.PerformInitialCommit();
- }
-
+ bool PerformInitialCommit() {
+ return KeepState.PerformInitialCommit();
+ }
+
////////////////////////////////////////////////////////////////////////
// PERFORM ACTIONS
////////////////////////////////////////////////////////////////////////
@@ -87,7 +87,7 @@ namespace NKikimr {
generateCommit |= PerformCutLogAction(ctx);
generateCommit |= PerformMemOverflowAction();
generateCommit |= PerformDeleteChunkAction();
- generateCommit |= PerformInitialCommit();
+ generateCommit |= PerformInitialCommit();
if (generateCommit) {
Y_VERIFY(!CommitterId);
@@ -240,38 +240,38 @@ namespace NKikimr {
PerformActions(ctx);
}
- STRICT_STFUNC(StateFunc,
- HFunc(TEvSyncLogPut, Handle)
- HFunc(TEvSyncLogPutSst, Handle)
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvSyncLogPut, Handle)
+ HFunc(TEvSyncLogPutSst, Handle)
HFunc(TEvSyncLogTrim, Handle)
- HFunc(TEvSyncLogFreeChunk, Handle)
- HFunc(TEvSyncLogCommitDone, Handle)
- HFunc(TEvSyncLogSnapshot, Handle)
+ HFunc(TEvSyncLogFreeChunk, Handle)
+ HFunc(TEvSyncLogCommitDone, Handle)
+ HFunc(TEvSyncLogSnapshot, Handle)
HFunc(TEvSyncLogLocalStatus, Handle)
HFunc(TEvBlobStorage::TEvVBaldSyncLog, Handle)
- HFunc(NPDisk::TEvCutLog, Handle)
- HFunc(TEvents::TEvPoisonPill, Handle)
- )
+ HFunc(NPDisk::TEvCutLog, Handle)
+ HFunc(TEvents::TEvPoisonPill, Handle)
+ )
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_KEEPER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_KEEPER;
}
TSyncLogKeeperActor(
TIntrusivePtr<TSyncLogCtx> slCtx,
- std::unique_ptr<TSyncLogRepaired> repaired)
+ std::unique_ptr<TSyncLogRepaired> repaired)
: TActorBootstrapped<TSyncLogKeeperActor>()
, SlCtx(std::move(slCtx))
- , KeepState(SlCtx->VCtx, std::move(repaired), SlCtx->SyncLogMaxMemAmount, SlCtx->SyncLogMaxDiskAmount,
+ , KeepState(SlCtx->VCtx, std::move(repaired), SlCtx->SyncLogMaxMemAmount, SlCtx->SyncLogMaxDiskAmount,
SlCtx->SyncLogMaxEntryPointSize)
{}
};
IActor* CreateSyncLogKeeperActor(
TIntrusivePtr<TSyncLogCtx> slCtx,
- std::unique_ptr<TSyncLogRepaired> repaired) {
- return new TSyncLogKeeperActor(std::move(slCtx), std::move(repaired));
+ std::unique_ptr<TSyncLogRepaired> repaired) {
+ return new TSyncLogKeeperActor(std::move(slCtx), std::move(repaired));
}
} // NSyncLog
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.h
index 16cd089d696..395313bb4bf 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper.h
@@ -16,7 +16,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
IActor* CreateSyncLogKeeperActor(
TIntrusivePtr<TSyncLogCtx> slCtx,
- std::unique_ptr<TSyncLogRepaired> repaired);
+ std::unique_ptr<TSyncLogRepaired> repaired);
} // NSyncLog
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_committer.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_committer.cpp
index e02b627a698..e260136b6c4 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_committer.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_committer.cpp
@@ -41,7 +41,7 @@ namespace NKikimr {
// lsn
TLsnSeg seg = SlCtx->LsnMngr->AllocLsnForLocalUse();
// commit msg
- auto commitMsg = std::make_unique<NPDisk::TEvLog>(SlCtx->PDiskCtx->Dsk->Owner,
+ auto commitMsg = std::make_unique<NPDisk::TEvLog>(SlCtx->PDiskCtx->Dsk->Owner,
SlCtx->PDiskCtx->Dsk->OwnerRound, TLogSignature::SignatureSyncLogIdx,
CommitRecord, EntryPointSerializer.GetSerializedData(), seg, nullptr);
@@ -62,7 +62,7 @@ namespace NKikimr {
"COMMIT: type# SyncLog msg# %s",
commitMsg->CommitRecord.ToString().data()));
- ctx.Send(SlCtx->LoggerID, commitMsg.release());
+ ctx.Send(SlCtx->LoggerID, commitMsg.release());
Become(&TThis::StateCommit);
}
@@ -99,7 +99,7 @@ namespace NKikimr {
}
// generate write
- Parts->GenRefs();
+ Parts->GenRefs();
Y_VERIFY_DEBUG(Parts->Size());
NPDisk::TEvChunkWrite::TPartsPtr p(Parts.Get());
ctx.Send(SlCtx->PDiskCtx->PDiskId,
@@ -132,7 +132,7 @@ namespace NKikimr {
ui32 offset = 0;
FillInPortion(PagesInChunk);
// generate write
- Parts->GenRefs();
+ Parts->GenRefs();
Y_VERIFY_DEBUG(Parts->Size());
NPDisk::TEvChunkWrite::TPartsPtr p(Parts.Get());
ctx.Send(SlCtx->PDiskCtx->PDiskId,
@@ -173,8 +173,8 @@ namespace NKikimr {
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_COMMITTER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_COMMITTER;
}
TSyncLogCommitterActor(
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.cpp
index 31448b8e468..0e288b78a32 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.cpp
@@ -28,7 +28,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
TSyncLogKeeperState::TSyncLogKeeperState(
TIntrusivePtr<TVDiskContext> vctx,
- std::unique_ptr<TSyncLogRepaired> repaired,
+ std::unique_ptr<TSyncLogRepaired> repaired,
ui64 syncLogMaxMemAmount,
ui64 syncLogMaxDiskAmount,
ui64 syncLogMaxEntryPointSize)
@@ -39,7 +39,7 @@ namespace NKikimr {
, MaxMemPages(CalcMaxMemPages(syncLogMaxMemAmount, SyncLogPtr->GetAppendBlockSize()))
, MaxDiskChunks(CalcMaxDiskChunks(syncLogMaxDiskAmount, SyncLogPtr->GetChunkSize()))
, SyncLogMaxEntryPointSize(syncLogMaxEntryPointSize)
- , NeedsInitialCommit(repaired->NeedsInitialCommit)
+ , NeedsInitialCommit(repaired->NeedsInitialCommit)
{}
// Calculate first lsn in recovery log we must to keep
@@ -252,10 +252,10 @@ namespace NKikimr {
return !ChunksToDelete.empty();
}
- bool TSyncLogKeeperState::PerformInitialCommit() {
- return std::exchange(NeedsInitialCommit, false);
- }
-
+ bool TSyncLogKeeperState::PerformInitialCommit() {
+ return std::exchange(NeedsInitialCommit, false);
+ }
+
TSyncLogKeeperCommitData TSyncLogKeeperState::PrepareCommitData(ui64 recoveryLogConfirmedLsn) {
// we _copy_ ChunksToDeleteDelayed and _move_ ChunksToDelete
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.h
index be9a6735f97..50ccb5708b1 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_state.h
@@ -100,12 +100,12 @@ namespace NKikimr {
public:
TSyncLogKeeperState(
TIntrusivePtr<TVDiskContext> vctx,
- std::unique_ptr<TSyncLogRepaired> repaired,
+ std::unique_ptr<TSyncLogRepaired> repaired,
ui64 syncLogMaxMemAmount,
ui64 syncLogMaxDiskAmount,
ui64 syncLogMaxEntryPointSize);
- void Init(std::shared_ptr<IActorNotify> notifier, std::shared_ptr<ILoggerCtx> loggerCtx) {
+ void Init(std::shared_ptr<IActorNotify> notifier, std::shared_ptr<ILoggerCtx> loggerCtx) {
Notifier = std::move(notifier);
LoggerCtx = std::move(loggerCtx);
}
@@ -143,7 +143,7 @@ namespace NKikimr {
bool PerformTrimTailAction();
bool PerformMemOverflowAction();
bool PerformDeleteChunkAction();
- bool PerformInitialCommit();
+ bool PerformInitialCommit();
bool FreeUpToLsnSatisfied() const { return CalculateFirstLsnToKeep() >= FreeUpToLsn; }
TSyncLogKeeperCommitData PrepareCommitData(ui64 recoveryLogConfirmedLsn);
@@ -168,17 +168,17 @@ namespace NKikimr {
// chunks that are still used by snapshots
TChunksToDeleteDelayed ChunksToDeleteDelayed;
// notifier for deleted chunks
- std::shared_ptr<IActorNotify> Notifier;
+ std::shared_ptr<IActorNotify> Notifier;
// logger ctx
- std::shared_ptr<ILoggerCtx> LoggerCtx;
+ std::shared_ptr<ILoggerCtx> LoggerCtx;
// number of retries me made to cut the log
ui32 CutLogRetries = 0;
// settings:
const ui32 MaxMemPages;
const ui32 MaxDiskChunks;
const ui64 SyncLogMaxEntryPointSize;
- // does it need initial commit?
- bool NeedsInitialCommit;
+ // does it need initial commit?
+ bool NeedsInitialCommit;
// Fix Disk overflow, i.e. remove some chunks from SyncLog
TVector<ui32> FixDiskOverflow(ui32 numChunksToAdd);
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_ut.cpp
index 44808438bee..e885bf8f22b 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogkeeper_ut.cpp
@@ -38,7 +38,7 @@ namespace NKikimr {
void WriteToLog(TSyncLogKeeperState *state, ui64 *lsn) {
++*lsn;
++Gen;
- ui32 size = NSyncLog::TSerializeRoutines::SetBlock(Buf, *lsn, TabletId, Gen, 0);
+ ui32 size = NSyncLog::TSerializeRoutines::SetBlock(Buf, *lsn, TabletId, Gen, 0);
state->PutOne((const NSyncLog::TRecordHdr *)Buf, size);
STR << "Put lsn# " << *lsn << "\n";
}
@@ -58,10 +58,10 @@ namespace NKikimr {
void Run(bool oldFormatForEntryPoint);
void PrintStatus(const TString &str = {}) {
- ::NKikimr::PrintStatus(State.get(), str);
+ ::NKikimr::PrintStatus(State.get(), str);
}
private:
- std::unique_ptr<TSyncLogKeeperState> State;
+ std::unique_ptr<TSyncLogKeeperState> State;
TPayloadWriter PayloadWriter;
bool Trim(ui64 lsn);
@@ -95,16 +95,16 @@ namespace NKikimr {
TString explanation;
auto r = TSyncLogRepaired::Construct(std::move(params), ep.EntryPoint, ep.EntryPointLsn, explanation);
Y_VERIFY(r);
- std::unique_ptr<NSyncLog::TSyncLogRecovery> recovery = std::make_unique<NSyncLog::TSyncLogRecovery>(std::move(r));
+ std::unique_ptr<NSyncLog::TSyncLogRecovery> recovery = std::make_unique<NSyncLog::TSyncLogRecovery>(std::move(r));
const ui64 lastLsnOfIndexRecord = recovery->GetLastLsnOfIndexRecord();
- std::unique_ptr<TSyncLogRepaired> repaired = recovery->ReleaseRepaired();
+ std::unique_ptr<TSyncLogRepaired> repaired = recovery->ReleaseRepaired();
const ui64 syncLogMaxMemAmount = ui64(64) << ui64(20);
const ui64 syncLogMaxDiskAmount = 0;
- State = std::make_unique<TSyncLogKeeperState>(vctx, std::move(repaired), syncLogMaxMemAmount, syncLogMaxDiskAmount,
+ State = std::make_unique<TSyncLogKeeperState>(vctx, std::move(repaired), syncLogMaxMemAmount, syncLogMaxDiskAmount,
syncLogMaxEntryPointSize);
- State->Init(nullptr, std::make_shared<TFakeLoggerCtx>());
+ State->Init(nullptr, std::make_shared<TFakeLoggerCtx>());
STR << "CREATE STATE entryPointLsn# " << ep.EntryPointLsn <<
" entryPoint# " << (ep.EntryPoint.empty() ? "<empty>" : "<exists>") << "\n";
@@ -135,7 +135,7 @@ namespace NKikimr {
{}
void Start(TSyncLogKeeperState *state, ui64 recoveryLogConfirmedLsn) {
- CommitData = std::make_unique<TSyncLogKeeperCommitData>(state->PrepareCommitData(recoveryLogConfirmedLsn));
+ CommitData = std::make_unique<TSyncLogKeeperCommitData>(state->PrepareCommitData(recoveryLogConfirmedLsn));
Y_VERIFY((!CommitData->SwapSnap || CommitData->SwapSnap->Empty()) &&
CommitData->ChunksToDeleteDelayed.empty() &&
CommitData->ChunksToDelete.empty());
@@ -163,7 +163,7 @@ namespace NKikimr {
}
private:
const bool OldFormatForEntryPoint;
- std::unique_ptr<TSyncLogKeeperCommitData> CommitData;
+ std::unique_ptr<TSyncLogKeeperCommitData> CommitData;
};
void TSyncLogKeeperTest::Run(bool oldFormatForEntryPoint) {
@@ -174,7 +174,7 @@ namespace NKikimr {
bool commit = false;
// write sample payload
for (ui64 i = 0; i < 10; ++i) {
- PayloadWriter.WriteToLog(State.get(), &lsn);
+ PayloadWriter.WriteToLog(State.get(), &lsn);
}
PrintStatus();
@@ -188,17 +188,17 @@ namespace NKikimr {
// start parallel commit
TCommitWithNoSwapAndDelChunks parallelCommit(oldFormatForEntryPoint);
- parallelCommit.Start(State.get(), 10);
+ parallelCommit.Start(State.get(), 10);
// write more messages during parallel commit
lsn = 21;
for (ui64 i = 0; i < 10; ++i) {
- PayloadWriter.WriteToLog(State.get(), &lsn);
+ PayloadWriter.WriteToLog(State.get(), &lsn);
}
PrintStatus();
// commit finished with lsn=31
- entryPointPair = parallelCommit.Finish(State.get(), 31);
+ entryPointPair = parallelCommit.Finish(State.get(), 31);
// trim all written data
commit = Trim(31);
@@ -209,17 +209,17 @@ namespace NKikimr {
// start parallel commit
TCommitWithNoSwapAndDelChunks parallelCommit2(oldFormatForEntryPoint);
- parallelCommit2.Start(State.get(), 31);
+ parallelCommit2.Start(State.get(), 31);
// commit finished with lsn=33
- entryPointPair = parallelCommit2.Finish(State.get(), 33);
+ entryPointPair = parallelCommit2.Finish(State.get(), 33);
STR << "\n************************** RESTART ***********************************************************\n\n";
////////////////////////////////////////////////////////////////////////////////////
// RESTART
////////////////////////////////////////////////////////////////////////////////////
- State.reset();
+ State.reset();
CreateState(entryPointPair);
// imitate other VDisk that is syncing with current VDisk
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.cpp
index 75d6349b824..c580b7f7355 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.cpp
@@ -258,19 +258,19 @@ namespace NKikimr {
}
ui32 TMemRecLog::TrimLog(ui64 confirmedCutLsn) {
- return DiscardPages(0, confirmedCutLsn);
- }
+ return DiscardPages(0, confirmedCutLsn);
+ }
- ui32 TMemRecLog::RemoveCachedPages(ui32 pagesMax, ui64 diskLastLsn) {
- return DiscardPages(pagesMax, diskLastLsn);
+ ui32 TMemRecLog::RemoveCachedPages(ui32 pagesMax, ui64 diskLastLsn) {
+ return DiscardPages(pagesMax, diskLastLsn);
}
- ui32 TMemRecLog::DiscardPages(ui32 pagesToKeep, ui64 lastUnneededLsn) {
+ ui32 TMemRecLog::DiscardPages(ui32 pagesToKeep, ui64 lastUnneededLsn) {
ui32 removed = 0;
- while (Pages.size() > pagesToKeep && Pages.front()->GetLastLsn() <= lastUnneededLsn) {
- RecsNum -= Pages.front()->Header.RecsNum;
- Pages.pop_front();
- removed++;
+ while (Pages.size() > pagesToKeep && Pages.front()->GetLastLsn() <= lastUnneededLsn) {
+ RecsNum -= Pages.front()->Header.RecsNum;
+ Pages.pop_front();
+ removed++;
}
return removed;
}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.h
index 4186dea1c6a..382497d9024 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem.h
@@ -20,7 +20,7 @@ namespace NKikimr {
class TSyncLogPageDeleter;
using TSyncLogPagePtr = std::shared_ptr<TSyncLogPage>;
- class TSyncLogPage : public TNonCopyable {
+ class TSyncLogPage : public TNonCopyable {
public:
// TODO: we may need to add additional index
@@ -565,9 +565,9 @@ namespace NKikimr {
TString ToString() const;
private:
- ui32 DiscardPages(ui32 pagesToKeep, ui64 lastUnneededLsn);
-
- private:
+ ui32 DiscardPages(ui32 pagesToKeep, ui64 lastUnneededLsn);
+
+ private:
TSyncLogPages Pages;
ui32 RecsNum;
TSyncLogPageDeleter SyncLogPageDeleter;
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem_ut.cpp
index 995a2156a66..9c4d05779a2 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmem_ut.cpp
@@ -25,7 +25,7 @@ namespace NKikimr {
ui64 tabletId = 1;
for (ui64 i = 0; i < num; i++) {
- size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
+ size = NSyncLog::TSerializeRoutines::SetBlock(buf, ctx.Lsn, tabletId, ctx.Gen, 0);
ctx.Lsn += 2;
ctx.Gen++;
mem->PutOne((const NSyncLog::TRecordHdr *)buf, size);
@@ -44,12 +44,12 @@ namespace NKikimr {
};
TFillInLogoBlobContext FillInLogoBlob(NSyncLog::TMemRecLog *mem, ui64 num, TFillInLogoBlobContext ctx) {
- TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
+ TBlobStorageGroupInfo groupInfo(TBlobStorageGroupType::ErasureMirror3, 2, 4);
char buf[NSyncLog::MaxRecFullSize];
ui32 size = 0;
for (unsigned i = 0; i < num; i++) {
- size = NSyncLog::TSerializeRoutines::SetLogoBlob(groupInfo.Type, buf, ctx.Lsn, ctx.Id, TIngress());
+ size = NSyncLog::TSerializeRoutines::SetLogoBlob(groupInfo.Type, buf, ctx.Lsn, ctx.Id, TIngress());
ctx.Lsn += 2;
ctx.Id = TLogoBlobID(ctx.Id.TabletID(), ctx.Id.Generation(), ctx.Id.Step() + 1,
ctx.Id.Channel(), ctx.Id.BlobSize(), ctx.Id.Cookie());
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.cpp
index ec10a5c1e1b..13a1a166f37 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.cpp
@@ -57,11 +57,11 @@ namespace NKikimr {
void Columnize(TVector<TLogoBlobRecWithSerial> &logoBlobs) {
Clear();
- auto comp = [](const TLogoBlobRecWithSerial& x, const TLogoBlobRecWithSerial& y) {
- return std::make_tuple(x.LogoBlobID(), x.Ingress.Raw(), x.Counter) <
- std::make_tuple(y.LogoBlobID(), y.Ingress.Raw(), y.Counter);
- };
- Sort(logoBlobs.begin(), logoBlobs.end(), comp);
+ auto comp = [](const TLogoBlobRecWithSerial& x, const TLogoBlobRecWithSerial& y) {
+ return std::make_tuple(x.LogoBlobID(), x.Ingress.Raw(), x.Counter) <
+ std::make_tuple(y.LogoBlobID(), y.Ingress.Raw(), y.Counter);
+ };
+ Sort(logoBlobs.begin(), logoBlobs.end(), comp);
const ui32 blobsSize = logoBlobs.size();
TabletIds.reserve(blobsSize);
@@ -319,127 +319,127 @@ namespace NKikimr {
TImpl(EEncoding enc) {
switch (enc) {
case EEncoding::Trivial:
- LogoBlobsColumns.reset(new TLogoBlobColumnsTrivialCodec);
+ LogoBlobsColumns.reset(new TLogoBlobColumnsTrivialCodec);
break;
case EEncoding::Custom:
- LogoBlobsColumns.reset(new TLogoBlobColumnsCustomCodec);
+ LogoBlobsColumns.reset(new TLogoBlobColumnsCustomCodec);
break;
default:
Y_FAIL("Unexpected case");
}
}
- TString Encode(TRecordsWithSerial& records) {
- const ui32 blobsSize = records.LogoBlobs.size();
- LogoBlobsColumns->Columnize(records.LogoBlobs);
+ TString Encode(TRecordsWithSerial& records) {
+ const ui32 blobsSize = records.LogoBlobs.size();
+ LogoBlobsColumns->Columnize(records.LogoBlobs);
- const ui32 blocksSize = records.Blocks.size();
- const ui32 barriersSize = records.Barriers.size();
- const ui32 blocksSizeV2 = records.BlocksV2.size();
+ const ui32 blocksSize = records.Blocks.size();
+ const ui32 barriersSize = records.Barriers.size();
+ const ui32 blocksSizeV2 = records.BlocksV2.size();
size_t blobsSerializedSize = sizeof(ui32) + blobsSize * LogoBlobsColumns->GetEncodedApproximationSize();
size_t blocksSerializedSize = sizeof(ui32) + blocksSize * sizeof(TBlockRecWithSerial);
size_t barriersSerializedSize = sizeof(ui32) + barriersSize * sizeof(TBarrierRecWithSerial);
- size_t blocksSerializedSizeV2 = blocksSizeV2 ? sizeof(ui32) + blocksSizeV2 * sizeof(TBlockRecWithSerialV2) : 0;
- size_t serializedSize = blobsSerializedSize + blocksSerializedSize + barriersSerializedSize + blocksSerializedSizeV2;
+ size_t blocksSerializedSizeV2 = blocksSizeV2 ? sizeof(ui32) + blocksSizeV2 * sizeof(TBlockRecWithSerialV2) : 0;
+ size_t serializedSize = blobsSerializedSize + blocksSerializedSize + barriersSerializedSize + blocksSerializedSizeV2;
TStringStream str;
str.Reserve(serializedSize);
-
+
LogoBlobsColumns->Encode(str);
-
+
str.Write(&blocksSize, sizeof(ui32));
if (blocksSize) {
- str.Write(records.Blocks.data(), sizeof(TBlockRecWithSerial) * blocksSize);
+ str.Write(records.Blocks.data(), sizeof(TBlockRecWithSerial) * blocksSize);
}
-
+
str.Write(&barriersSize, sizeof(ui32));
if (barriersSize) {
- str.Write(records.Barriers.data(), sizeof(TBarrierRecWithSerial) * barriersSize);
- }
-
- if (blocksSizeV2) {
- str.Write(&blocksSizeV2, sizeof(ui32));
- str.Write(records.BlocksV2.data(), sizeof(TBlockRecWithSerialV2) * blocksSizeV2);
+ str.Write(records.Barriers.data(), sizeof(TBarrierRecWithSerial) * barriersSize);
}
+ if (blocksSizeV2) {
+ str.Write(&blocksSizeV2, sizeof(ui32));
+ str.Write(records.BlocksV2.data(), sizeof(TBlockRecWithSerialV2) * blocksSizeV2);
+ }
+
return str.Str();
}
- bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) {
+ bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) {
// clear output
- records.LogoBlobs.clear();
- records.Blocks.clear();
- records.Barriers.clear();
- records.BlocksV2.clear();
+ records.LogoBlobs.clear();
+ records.Blocks.clear();
+ records.Barriers.clear();
+ records.BlocksV2.clear();
// logoblobs
pos = LogoBlobsColumns->Decode(pos, end);
- if (!pos) {
+ if (!pos) {
return false;
- }
- LogoBlobsColumns->Decolumnize(records.LogoBlobs);
+ }
+ LogoBlobsColumns->Decolumnize(records.LogoBlobs);
// blocks
- if (size_t(end - pos) < sizeof(ui32)) {
+ if (size_t(end - pos) < sizeof(ui32)) {
return false;
- }
+ }
const ui32 blocksSize = ReadUnaligned<ui32>(pos);
- pos += sizeof(ui32);
- if (size_t(end - pos) < sizeof(TBlockRecWithSerial) * blocksSize) {
+ pos += sizeof(ui32);
+ if (size_t(end - pos) < sizeof(TBlockRecWithSerial) * blocksSize) {
return false;
- }
+ }
if (blocksSize) {
- records.Blocks.resize(blocksSize);
- memcpy(records.Blocks.data(), pos, sizeof(TBlockRecWithSerial) * blocksSize);
+ records.Blocks.resize(blocksSize);
+ memcpy(records.Blocks.data(), pos, sizeof(TBlockRecWithSerial) * blocksSize);
pos += sizeof(TBlockRecWithSerial) * blocksSize;
}
// barriers
- if (size_t(end - pos) < sizeof(ui32)) {
+ if (size_t(end - pos) < sizeof(ui32)) {
return false;
- }
+ }
const ui32 barriersSize = ReadUnaligned<ui32>(pos);
- pos += sizeof(ui32);
- if (size_t(end - pos) < sizeof(TBarrierRecWithSerial) * barriersSize) {
+ pos += sizeof(ui32);
+ if (size_t(end - pos) < sizeof(TBarrierRecWithSerial) * barriersSize) {
return false;
- }
+ }
if (barriersSize) {
- records.Barriers.resize(barriersSize);
- memcpy(records.Barriers.data(), pos, sizeof(TBarrierRecWithSerial) * barriersSize);
+ records.Barriers.resize(barriersSize);
+ memcpy(records.Barriers.data(), pos, sizeof(TBarrierRecWithSerial) * barriersSize);
pos += sizeof(TBarrierRecWithSerial) * barriersSize;
}
- if (end != pos) {
- if (size_t(end - pos) < sizeof(ui32)) {
- return false;
- }
- const ui32 blocksSizeV2 = ReadUnaligned<ui32>(pos);
- pos += sizeof(ui32);
- if (!blocksSizeV2) {
- return false;
- }
- const size_t len = sizeof(TBlockRecWithSerialV2) * blocksSizeV2;
- if (size_t(end - pos) < len) {
- return false;
- }
- records.BlocksV2.resize(blocksSizeV2);
- memcpy(records.BlocksV2.data(), pos, len);
- pos += len;
- }
-
- if (end != pos) {
- return false;
- }
-
+ if (end != pos) {
+ if (size_t(end - pos) < sizeof(ui32)) {
+ return false;
+ }
+ const ui32 blocksSizeV2 = ReadUnaligned<ui32>(pos);
+ pos += sizeof(ui32);
+ if (!blocksSizeV2) {
+ return false;
+ }
+ const size_t len = sizeof(TBlockRecWithSerialV2) * blocksSizeV2;
+ if (size_t(end - pos) < len) {
+ return false;
+ }
+ records.BlocksV2.resize(blocksSizeV2);
+ memcpy(records.BlocksV2.data(), pos, len);
+ pos += len;
+ }
+
+ if (end != pos) {
+ return false;
+ }
+
return true;
}
private:
- std::unique_ptr<TLogoBlobColumns> LogoBlobsColumns;
+ std::unique_ptr<TLogoBlobColumns> LogoBlobsColumns;
};
@@ -453,12 +453,12 @@ namespace NKikimr {
TReorderCodec::~TReorderCodec() {}
- TString TReorderCodec::Encode(TRecordsWithSerial& records) {
- return Impl->Encode(records);
+ TString TReorderCodec::Encode(TRecordsWithSerial& records) {
+ return Impl->Encode(records);
}
- bool TReorderCodec::Decode(const char *pos, const char *end, TRecordsWithSerial& records) {
- return Impl->Decode(pos, end, records);
+ bool TReorderCodec::Decode(const char *pos, const char *end, TRecordsWithSerial& records) {
+ return Impl->Decode(pos, end, records);
}
} // NSyncLog
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.h
index 0b9251e5169..998b86e4687 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl.h
@@ -98,7 +98,7 @@ namespace NKikimr {
};
struct TBlockRecWithSerial : public TBlockRec {
- explicit TBlockRecWithSerial() = default;
+ explicit TBlockRecWithSerial() = default;
explicit TBlockRecWithSerial(const TBlockRec &rec, ui32 counter)
: TBlockRec(rec)
@@ -110,18 +110,18 @@ namespace NKikimr {
, Counter(counter)
{}
- ui32 Counter = 0;
- };
-
- struct TBlockRecWithSerialV2 : public TBlockRecV2 {
- explicit TBlockRecWithSerialV2() = default;
-
- explicit TBlockRecWithSerialV2(const TBlockRecV2& rec, ui32 counter)
- : TBlockRecV2(rec)
- , Counter(counter)
- {}
-
- ui32 Counter = 0;
+ ui32 Counter = 0;
+ };
+
+ struct TBlockRecWithSerialV2 : public TBlockRecV2 {
+ explicit TBlockRecWithSerialV2() = default;
+
+ explicit TBlockRecWithSerialV2(const TBlockRecV2& rec, ui32 counter)
+ : TBlockRecV2(rec)
+ , Counter(counter)
+ {}
+
+ ui32 Counter = 0;
};
struct TBarrierRecWithSerial : public TBarrierRec {
@@ -136,8 +136,8 @@ namespace NKikimr {
{}
explicit TBarrierRecWithSerial(ui64 tabletId, ui32 channel, ui32 gen, ui32 genCounter, ui32 collGen,
- ui32 collStep, bool hard, ui64 ingressRaw, ui32 counter)
- : TBarrierRec(tabletId, channel, gen, genCounter, collGen, collStep, hard, ingressRaw)
+ ui32 collStep, bool hard, ui64 ingressRaw, ui32 counter)
+ : TBarrierRec(tabletId, channel, gen, genCounter, collGen, collStep, hard, ingressRaw)
, Counter(counter)
{}
@@ -145,13 +145,13 @@ namespace NKikimr {
};
#pragma pack(pop)
- struct TRecordsWithSerial {
- TVector<TLogoBlobRecWithSerial> LogoBlobs;
- TVector<TBlockRecWithSerial> Blocks;
- TVector<TBarrierRecWithSerial> Barriers;
- TVector<TBlockRecWithSerialV2> BlocksV2;
- };
-
+ struct TRecordsWithSerial {
+ TVector<TLogoBlobRecWithSerial> LogoBlobs;
+ TVector<TBlockRecWithSerial> Blocks;
+ TVector<TBarrierRecWithSerial> Barriers;
+ TVector<TBlockRecWithSerialV2> BlocksV2;
+ };
+
////////////////////////////////////////////////////////////////////////////
// SyncLog message specific codec interface
// It works with vectors of TLogoBlobRec, TBlockRec and TBarrierRec
@@ -159,13 +159,13 @@ namespace NKikimr {
class ISpecificCodec {
public:
virtual ~ISpecificCodec() {}
-
+
// NOTE: Encode method writes into arguments (sort them, for instance)
- virtual TString Encode(TRecordsWithSerial& records) = 0;
- virtual bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) = 0;
-
- bool DecodeString(const TString &s, TRecordsWithSerial& records) {
- return Decode(s.data(), s.data() + s.size(), records);
+ virtual TString Encode(TRecordsWithSerial& records) = 0;
+ virtual bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) = 0;
+
+ bool DecodeString(const TString &s, TRecordsWithSerial& records) {
+ return Decode(s.data(), s.data() + s.size(), records);
}
};
@@ -183,12 +183,12 @@ namespace NKikimr {
TReorderCodec(EEncoding enc);
~TReorderCodec();
- virtual TString Encode(TRecordsWithSerial& records) override;
- virtual bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) override;
+ virtual TString Encode(TRecordsWithSerial& records) override;
+ virtual bool Decode(const char *pos, const char *end, TRecordsWithSerial& records) override;
private:
class TImpl;
- std::unique_ptr<TImpl> Impl;
+ std::unique_ptr<TImpl> Impl;
};
} // NSyncLog
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl_ut.cpp
index 344377c9a30..f6545052d65 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgimpl_ut.cpp
@@ -11,52 +11,52 @@ using namespace NKikimr::NSyncLog;
#define STR Cnull
-std::tuple<TLogoBlobID, ui64, ui64> AsTuple(const TLogoBlobRecWithSerial& x) {
- return {x.LogoBlobID(), x.Ingress.Raw(), x.Counter};
-}
-
-std::tuple<ui64, ui32, ui64> AsTuple(const TBlockRecWithSerial& x) {
- return {x.TabletId, x.Generation, x.Counter};
-}
-
-std::tuple<ui64, ui32, ui64, ui64> AsTuple(const TBlockRecWithSerialV2& x) {
- return {x.TabletId, x.Generation, x.IssuerGuid, x.Counter};
-}
-
-std::tuple<ui64, ui32, ui32, ui32, ui32, ui32, ui32, ui64, ui64> AsTuple(const TBarrierRecWithSerial& x) {
- return {x.TabletId, x.Channel, x.Hard, x.Gen, x.GenCounter, x.CollectGeneration, x.CollectStep, x.Ingress.Raw(), x.Counter};
-}
-
-template<typename T, typename... Tx, typename = std::enable_if<std::is_same_v<decltype(AsTuple(std::declval<const T&>())), std::tuple<Tx...>>>>
-bool Equal(const T& x, const T& y) {
- return AsTuple(x) == AsTuple(y);
-}
-
-template<typename T>
-bool Equal(const std::vector<T>& x, const std::vector<T>& y) {
- if (x.size() != y.size()) {
- return false;
- }
- for (size_t i = 0; i < x.size(); ++i) {
- if (!Equal(x[i], y[i])) {
- return false;
- }
- }
- return true;
-}
-
-bool Equal(const TRecordsWithSerial& x, const TRecordsWithSerial& y) {
- return Equal(x.LogoBlobs, y.LogoBlobs) && Equal(x.Blocks, y.Blocks) && Equal(x.Barriers, y.Barriers) &&
- Equal(x.BlocksV2, y.BlocksV2);
-}
-
+std::tuple<TLogoBlobID, ui64, ui64> AsTuple(const TLogoBlobRecWithSerial& x) {
+ return {x.LogoBlobID(), x.Ingress.Raw(), x.Counter};
+}
+
+std::tuple<ui64, ui32, ui64> AsTuple(const TBlockRecWithSerial& x) {
+ return {x.TabletId, x.Generation, x.Counter};
+}
+
+std::tuple<ui64, ui32, ui64, ui64> AsTuple(const TBlockRecWithSerialV2& x) {
+ return {x.TabletId, x.Generation, x.IssuerGuid, x.Counter};
+}
+
+std::tuple<ui64, ui32, ui32, ui32, ui32, ui32, ui32, ui64, ui64> AsTuple(const TBarrierRecWithSerial& x) {
+ return {x.TabletId, x.Channel, x.Hard, x.Gen, x.GenCounter, x.CollectGeneration, x.CollectStep, x.Ingress.Raw(), x.Counter};
+}
+
+template<typename T, typename... Tx, typename = std::enable_if<std::is_same_v<decltype(AsTuple(std::declval<const T&>())), std::tuple<Tx...>>>>
+bool Equal(const T& x, const T& y) {
+ return AsTuple(x) == AsTuple(y);
+}
+
+template<typename T>
+bool Equal(const std::vector<T>& x, const std::vector<T>& y) {
+ if (x.size() != y.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < x.size(); ++i) {
+ if (!Equal(x[i], y[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Equal(const TRecordsWithSerial& x, const TRecordsWithSerial& y) {
+ return Equal(x.LogoBlobs, y.LogoBlobs) && Equal(x.Blocks, y.Blocks) && Equal(x.Barriers, y.Barriers) &&
+ Equal(x.BlocksV2, y.BlocksV2);
+}
+
Y_UNIT_TEST_SUITE(ReorderCodecTest) {
Y_UNIT_TEST(Basic) {
- TRecordsWithSerial recsSrc;
-
+ TRecordsWithSerial recsSrc;
+
// logoblobs
- TVector<TLogoBlobRecWithSerial>& logoBlobsSrc = recsSrc.LogoBlobs;
+ TVector<TLogoBlobRecWithSerial>& logoBlobsSrc = recsSrc.LogoBlobs;
logoBlobsSrc.emplace_back(TLogoBlobID(66, 1, 0, 0, 110, 20), 0, 0);
logoBlobsSrc.emplace_back(TLogoBlobID(66, 1, 0, 0, 109, 21), 0, 1);
logoBlobsSrc.emplace_back(TLogoBlobID(66, 1, 0, 0, 108, 22), 0, 2);
@@ -70,28 +70,28 @@ Y_UNIT_TEST_SUITE(ReorderCodecTest) {
logoBlobsSrc.emplace_back(TLogoBlobID(42, 2, 0, 0, 100, 20), 0, 10);
// blocks
- TVector<TBlockRecWithSerial>& blocksSrc = recsSrc.Blocks;
+ TVector<TBlockRecWithSerial>& blocksSrc = recsSrc.Blocks;
blocksSrc.emplace_back(42, 1, 11);
blocksSrc.emplace_back(73, 0, 12);
// barriers
- TVector<TBarrierRecWithSerial>& barriersSrc = recsSrc.Barriers;
- barriersSrc.emplace_back(42, 0, 0, 345, 0, 3, false, 0, 13);
+ TVector<TBarrierRecWithSerial>& barriersSrc = recsSrc.Barriers;
+ barriersSrc.emplace_back(42, 0, 0, 345, 0, 3, false, 0, 13);
// save original vectors
- TRecordsWithSerial origRecsSrc(recsSrc);
+ TRecordsWithSerial origRecsSrc(recsSrc);
// encode
TReorderCodec codec(TReorderCodec::EEncoding::Trivial);
- TString encoded = codec.Encode(recsSrc);
+ TString encoded = codec.Encode(recsSrc);
// decode
- TRecordsWithSerial recsRes;
- bool res = codec.DecodeString(encoded, recsRes);
+ TRecordsWithSerial recsRes;
+ bool res = codec.DecodeString(encoded, recsRes);
// check
UNIT_ASSERT_VALUES_EQUAL(res, true);
- UNIT_ASSERT(Equal(recsRes, origRecsSrc));
+ UNIT_ASSERT(Equal(recsRes, origRecsSrc));
}
}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.cpp
index f4c59ec890f..2a60b265875 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.cpp
@@ -7,53 +7,53 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TNaiveFragmentReader
////////////////////////////////////////////////////////////////////////////
- void TNaiveFragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
- ForEach(Data, fblob, fblock, fbar, fblock2);
+ void TNaiveFragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
+ ForEach(Data, fblob, fblock, fbar, fblock2);
}
void TNaiveFragmentReader::ForEach(const TString &d, TReadLogoBlobRec fblob, TReadBlockRec fblock,
- TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
+ TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
const TRecordHdr *begin = (const TRecordHdr *)(d.data());
const TRecordHdr *end = (const TRecordHdr *)(d.data() + d.size());
for (const TRecordHdr *it = begin; it < end; it = it->Next()) {
switch (it->RecType) {
- case TRecordHdr::RecLogoBlob:
- fblob(it->GetLogoBlob());
+ case TRecordHdr::RecLogoBlob:
+ fblob(it->GetLogoBlob());
break;
- case TRecordHdr::RecBlock:
- fblock(it->GetBlock());
+ case TRecordHdr::RecBlock:
+ fblock(it->GetBlock());
break;
- case TRecordHdr::RecBarrier:
- fbar(it->GetBarrier());
+ case TRecordHdr::RecBarrier:
+ fbar(it->GetBarrier());
break;
- case TRecordHdr::RecBlockV2:
- fblock2(it->GetBlockV2());
- break;
- default:
- Y_FAIL("Unknown RecType: %s", it->ToString().data());
+ case TRecordHdr::RecBlockV2:
+ fblock2(it->GetBlockV2());
+ break;
+ default:
+ Y_FAIL("Unknown RecType: %s", it->ToString().data());
}
}
}
- bool TNaiveFragmentReader::Check(TString &errorString) {
+ bool TNaiveFragmentReader::Check(TString &errorString) {
return TSerializeRoutines::CheckData(Data, errorString);
}
////////////////////////////////////////////////////////////////////////////
// TLz4FragmentReader
////////////////////////////////////////////////////////////////////////////
- void TLz4FragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
+ void TLz4FragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
Decompress();
- TNaiveFragmentReader::ForEach(Uncompressed, fblob, fblock, fbar, fblock2);
+ TNaiveFragmentReader::ForEach(Uncompressed, fblob, fblock, fbar, fblock2);
}
- bool TLz4FragmentReader::Check(TString &errorString) {
+ bool TLz4FragmentReader::Check(TString &errorString) {
Decompress();
return TSerializeRoutines::CheckData(Uncompressed, errorString);
}
- void TLz4FragmentReader::Decompress() {
+ void TLz4FragmentReader::Decompress() {
if (Uncompressed.empty()) {
// remove header from original string
size_t hdrSize = GetLz4HeaderSize();
@@ -65,50 +65,50 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TBaseOrderedFragmentReader
////////////////////////////////////////////////////////////////////////////
- void TBaseOrderedFragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
- Decompress();
-
- using THeapItem = std::tuple<TRecordHdr::ESyncLogRecType, const void*, ui32>;
- auto comp = [](const THeapItem& x, const THeapItem& y) { return std::get<2>(y) < std::get<2>(x); };
-
- TStackVec<THeapItem, 4> heap;
-
-#define ADD_HEAP(NAME, TYPE) \
- if (!Records.NAME.empty()) { \
- heap.emplace_back(TRecordHdr::TYPE, &Records.NAME.front(), Records.NAME.front().Counter); \
- }
- ADD_HEAP(LogoBlobs, RecLogoBlob)
- ADD_HEAP(Blocks, RecBlock)
- ADD_HEAP(Barriers, RecBarrier)
- ADD_HEAP(BlocksV2, RecBlockV2)
-
- std::make_heap(heap.begin(), heap.end(), comp);
-
- while (!heap.empty()) {
- std::pop_heap(heap.begin(), heap.end(), comp);
- auto& item = heap.back(); // say thanks to Microsoft compiler for not supporting tuple binding correctly
- auto& type = std::get<0>(item);
- auto& ptr = std::get<1>(item);
- auto& counter = std::get<2>(item);
- switch (type) {
-#define PROCESS(NAME, TYPE, FUNC) \
- case TRecordHdr::TYPE: { \
- using T = std::decay_t<decltype(Records.NAME)>::value_type; \
- const T *item = static_cast<const T*>(ptr); \
- FUNC(item); \
- if (++item != Records.NAME.data() + Records.NAME.size()) { \
- ptr = item; \
- counter = item->Counter; \
- std::push_heap(heap.begin(), heap.end(), comp); \
- } else { \
- heap.pop_back(); \
- } \
- break; \
+ void TBaseOrderedFragmentReader::ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
+ Decompress();
+
+ using THeapItem = std::tuple<TRecordHdr::ESyncLogRecType, const void*, ui32>;
+ auto comp = [](const THeapItem& x, const THeapItem& y) { return std::get<2>(y) < std::get<2>(x); };
+
+ TStackVec<THeapItem, 4> heap;
+
+#define ADD_HEAP(NAME, TYPE) \
+ if (!Records.NAME.empty()) { \
+ heap.emplace_back(TRecordHdr::TYPE, &Records.NAME.front(), Records.NAME.front().Counter); \
+ }
+ ADD_HEAP(LogoBlobs, RecLogoBlob)
+ ADD_HEAP(Blocks, RecBlock)
+ ADD_HEAP(Barriers, RecBarrier)
+ ADD_HEAP(BlocksV2, RecBlockV2)
+
+ std::make_heap(heap.begin(), heap.end(), comp);
+
+ while (!heap.empty()) {
+ std::pop_heap(heap.begin(), heap.end(), comp);
+ auto& item = heap.back(); // say thanks to Microsoft compiler for not supporting tuple binding correctly
+ auto& type = std::get<0>(item);
+ auto& ptr = std::get<1>(item);
+ auto& counter = std::get<2>(item);
+ switch (type) {
+#define PROCESS(NAME, TYPE, FUNC) \
+ case TRecordHdr::TYPE: { \
+ using T = std::decay_t<decltype(Records.NAME)>::value_type; \
+ const T *item = static_cast<const T*>(ptr); \
+ FUNC(item); \
+ if (++item != Records.NAME.data() + Records.NAME.size()) { \
+ ptr = item; \
+ counter = item->Counter; \
+ std::push_heap(heap.begin(), heap.end(), comp); \
+ } else { \
+ heap.pop_back(); \
+ } \
+ break; \
}
- PROCESS(LogoBlobs, RecLogoBlob, fblob)
- PROCESS(Blocks, RecBlock, fblock)
- PROCESS(Barriers, RecBarrier, fbar)
- PROCESS(BlocksV2, RecBlockV2, fblock2)
+ PROCESS(LogoBlobs, RecLogoBlob, fblob)
+ PROCESS(Blocks, RecBlock, fblock)
+ PROCESS(Barriers, RecBarrier, fbar)
+ PROCESS(BlocksV2, RecBlockV2, fblock2)
}
}
}
@@ -116,12 +116,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TOrderedLz4FragmentReader
////////////////////////////////////////////////////////////////////////////
- bool TOrderedLz4FragmentReader::Check(TString &errorString) {
+ bool TOrderedLz4FragmentReader::Check(TString &errorString) {
Y_UNUSED(errorString);
return Decompress();
}
- bool TOrderedLz4FragmentReader::Decompress() {
+ bool TOrderedLz4FragmentReader::Decompress() {
if (!Decompressed) {
// remove header from original string
TString uncompressed;
@@ -131,7 +131,7 @@ namespace NKikimr {
// build vectors
TReorderCodec codec(TReorderCodec::EEncoding::Trivial);
- Decompressed = codec.DecodeString(uncompressed, Records);
+ Decompressed = codec.DecodeString(uncompressed, Records);
}
return Decompressed;
@@ -140,19 +140,19 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TCustomCodecFragmentReader
////////////////////////////////////////////////////////////////////////////
- bool TCustomCodecFragmentReader::Check(TString &errorString) {
+ bool TCustomCodecFragmentReader::Check(TString &errorString) {
Y_UNUSED(errorString);
return Decompress();
}
- bool TCustomCodecFragmentReader::Decompress() {
+ bool TCustomCodecFragmentReader::Decompress() {
if (!Decompressed) {
// build vectors
size_t hdrSize = GetCustomCodecHeaderSize();
TReorderCodec codec(TReorderCodec::EEncoding::Custom);
const char *pos = Data.data() + hdrSize;
const char *end = pos + (Data.size() - hdrSize);
- Decompressed = codec.Decode(pos, end, Records);
+ Decompressed = codec.Decode(pos, end, Records);
}
return Decompressed;
@@ -165,16 +165,16 @@ namespace NKikimr {
ECodec codec = FragmentCodecDetector(data);
switch (codec) {
case ECodec::Naive:
- Impl.reset(new TNaiveFragmentReader(data));
+ Impl.reset(new TNaiveFragmentReader(data));
break;
case ECodec::Lz4:
- Impl.reset(new TLz4FragmentReader(data));
+ Impl.reset(new TLz4FragmentReader(data));
break;
case ECodec::OrderedLz4:
- Impl.reset(new TOrderedLz4FragmentReader(data));
+ Impl.reset(new TOrderedLz4FragmentReader(data));
break;
case ECodec::CustomCodec:
- Impl.reset(new TCustomCodecFragmentReader(data));
+ Impl.reset(new TCustomCodecFragmentReader(data));
break;
default:
Y_FAIL("Unknwon codec");
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h
index d3c7780e929..a3cb3a79343 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgreader.h
@@ -13,7 +13,7 @@ namespace NKikimr {
using TReadLogoBlobRec = std::function<void(const TLogoBlobRec *)>;
using TReadBlockRec = std::function<void(const TBlockRec *)>;
using TReadBarrierRec = std::function<void(const TBarrierRec *)>;
- using TReadBlockRecV2 = std::function<void(const TBlockRecV2 *)>;
+ using TReadBlockRecV2 = std::function<void(const TBlockRecV2 *)>;
////////////////////////////////////////////////////////////////////////////
@@ -21,8 +21,8 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class IFragmentReader {
public:
- virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) = 0;
- virtual bool Check(TString &errorString) = 0;
+ virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) = 0;
+ virtual bool Check(TString &errorString) = 0;
virtual ~IFragmentReader() {}
};
@@ -36,12 +36,12 @@ namespace NKikimr {
: Data(data)
{}
- virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
- virtual bool Check(TString &errorString) override;
+ virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
+ virtual bool Check(TString &errorString) override;
protected:
const TString &Data;
- void ForEach(const TString &d, TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2);
+ void ForEach(const TString &d, TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2);
};
@@ -55,12 +55,12 @@ namespace NKikimr {
, Uncompressed()
{}
- virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
- virtual bool Check(TString &errorString) override;
+ virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
+ virtual bool Check(TString &errorString) override;
private:
mutable TString Uncompressed;
- void Decompress();
+ void Decompress();
};
@@ -69,12 +69,12 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
class TBaseOrderedFragmentReader : public IFragmentReader {
public:
- virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
+ virtual void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) override;
protected:
- TRecordsWithSerial Records;
+ TRecordsWithSerial Records;
- virtual bool Decompress() = 0;
+ virtual bool Decompress() = 0;
};
////////////////////////////////////////////////////////////////////////////
@@ -87,13 +87,13 @@ namespace NKikimr {
, Decompressed(false)
{}
- virtual bool Check(TString &errorString) override;
+ virtual bool Check(TString &errorString) override;
private:
const TString &Data;
- bool Decompressed;
+ bool Decompressed;
- bool Decompress() override;
+ bool Decompress() override;
};
////////////////////////////////////////////////////////////////////////////
@@ -106,13 +106,13 @@ namespace NKikimr {
, Decompressed(false)
{}
- virtual bool Check(TString &errorString) override;
+ virtual bool Check(TString &errorString) override;
private:
const TString &Data;
- bool Decompressed;
+ bool Decompressed;
- bool Decompress() override;
+ bool Decompress() override;
};
@@ -123,16 +123,16 @@ namespace NKikimr {
public:
TFragmentReader(const TString &data);
- void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
- Impl->ForEach(fblob, fblock, fbar, fblock2);
+ void ForEach(TReadLogoBlobRec fblob, TReadBlockRec fblock, TReadBarrierRec fbar, TReadBlockRecV2 fblock2) {
+ Impl->ForEach(fblob, fblock, fbar, fblock2);
}
- bool Check(TString &errorString) {
+ bool Check(TString &errorString) {
return Impl->Check(errorString);
}
private:
- std::unique_ptr<IFragmentReader> Impl;
+ std::unique_ptr<IFragmentReader> Impl;
};
} // NSyncLog
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.cpp
index ab2b6dc161f..a91b100e954 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.cpp
@@ -44,7 +44,7 @@ namespace NKikimr {
void TOrderedLz4FragmentWriter::Finish(TString *respData) {
// reorder
TReorderCodec codec(TReorderCodec::EEncoding::Trivial);
- const TString reordered = codec.Encode(Records);
+ const TString reordered = codec.Encode(Records);
// compress
const TString compressed = GetLz4Codec()->Encode(reordered);
// header
@@ -63,7 +63,7 @@ namespace NKikimr {
void TCustomCodecFragmentWriter::Finish(TString *respData) {
// reorder
TReorderCodec codec(TReorderCodec::EEncoding::Custom);
- const TString result = codec.Encode(Records);
+ const TString result = codec.Encode(Records);
// header
std::pair<const char *, size_t> hdr = GetCustomCodecHeader();
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.h
index 70612240593..800e8756026 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter.h
@@ -1,32 +1,32 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
#include "blobstorage_synclogformat.h"
#include "blobstorage_synclogmsgimpl.h"
-#include <util/generic/buffer.h>
+#include <util/generic/buffer.h>
#include <util/generic/string.h>
-#include <util/generic/list.h>
-
-namespace NKikimr {
+#include <util/generic/list.h>
+
+namespace NKikimr {
namespace NSyncLog {
-
+
////////////////////////////////////////////////////////////////////////////
// TNaiveFragmentWriter
////////////////////////////////////////////////////////////////////////////
class TNaiveFragmentWriter {
TList<TBuffer> Chain;
size_t DataSize;
-
+
public:
TNaiveFragmentWriter()
: Chain({{64 << 10}}) // 64 KiB initial storage
, DataSize(0)
{}
-
+
size_t GetSize() const {
return DataSize;
}
-
+
void Push(const TRecordHdr *hdr) {
Push(hdr, hdr->GetSize());
}
@@ -45,12 +45,12 @@ namespace NKikimr {
d += len;
size -= len;
}
- }
- }
+ }
+ }
void Finish(TString *respData);
};
-
+
////////////////////////////////////////////////////////////////////////////
// TLz4FragmentWriter
////////////////////////////////////////////////////////////////////////////
@@ -73,7 +73,7 @@ namespace NKikimr {
, Counter(0)
{
// TODO: think about better approximation
- Records.LogoBlobs.reserve(10000);
+ Records.LogoBlobs.reserve(10000);
}
size_t GetSize() const {
@@ -88,17 +88,17 @@ namespace NKikimr {
Y_VERIFY((size & 3) == 0); // ensure that size is multiple of 4
switch (hdr->RecType) {
case TRecordHdr::RecLogoBlob:
- Records.LogoBlobs.emplace_back(*hdr->GetLogoBlob(), Counter);
+ Records.LogoBlobs.emplace_back(*hdr->GetLogoBlob(), Counter);
break;
case TRecordHdr::RecBlock:
- Records.Blocks.emplace_back(*hdr->GetBlock(), Counter);
+ Records.Blocks.emplace_back(*hdr->GetBlock(), Counter);
break;
case TRecordHdr::RecBarrier:
- Records.Barriers.emplace_back(*hdr->GetBarrier(), Counter);
- break;
- case TRecordHdr::RecBlockV2:
- Records.BlocksV2.emplace_back(*hdr->GetBlockV2(), Counter);
+ Records.Barriers.emplace_back(*hdr->GetBarrier(), Counter);
break;
+ case TRecordHdr::RecBlockV2:
+ Records.BlocksV2.emplace_back(*hdr->GetBlockV2(), Counter);
+ break;
default:
Y_FAIL("Unexpected RecType# %" PRIu64, (ui64)hdr->RecType);
}
@@ -111,7 +111,7 @@ namespace NKikimr {
protected:
size_t DataSize;
ui32 Counter;
- TRecordsWithSerial Records;
+ TRecordsWithSerial Records;
};
////////////////////////////////////////////////////////////////////////////
@@ -139,4 +139,4 @@ namespace NKikimr {
};
} // NSyncLog
-} // NKikimr
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter_ut.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter_ut.cpp
index 9699c12a446..d4da129e6fb 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter_ut.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogmsgwriter_ut.cpp
@@ -1,14 +1,14 @@
#include "blobstorage_synclogmsgwriter.h"
#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NKikimr;
+
+using namespace NKikimr;
using namespace NKikimr::NSyncLog;
-
+
Y_UNIT_TEST_SUITE(NaiveFragmentWriterTest) {
-
+
void AppendBlock(TString &data, ui64 lsn, ui64 tabletId, ui32 gen) {
char buf[MaxRecFullSize];
- ui32 len = TSerializeRoutines::SetBlock(buf, lsn, tabletId, gen, 0);
+ ui32 len = TSerializeRoutines::SetBlock(buf, lsn, tabletId, gen, 0);
data.append(buf, len);
}
@@ -19,7 +19,7 @@ Y_UNIT_TEST_SUITE(NaiveFragmentWriterTest) {
AppendBlock(data, 102, 66, 3);
AppendBlock(data, 103, 66, 4);
AppendBlock(data, 104, 66, 5);
-
+
TNaiveFragmentWriter w;
TString result;
const TRecordHdr *begin = (const TRecordHdr *)(data.data());
@@ -28,12 +28,12 @@ Y_UNIT_TEST_SUITE(NaiveFragmentWriterTest) {
w.Push(it);
result.append((const char *)it, it->GetSize());
UNIT_ASSERT_VALUES_EQUAL(w.GetSize(), result.size());
- }
+ }
TString temp;
w.Finish(&temp);
- UNIT_ASSERT_STRINGS_EQUAL(temp, result);
- }
-
+ UNIT_ASSERT_STRINGS_EQUAL(temp, result);
+ }
+
Y_UNIT_TEST(Long) {
TString data;
AppendBlock(data, 100, 66, 1);
@@ -45,10 +45,10 @@ Y_UNIT_TEST_SUITE(NaiveFragmentWriterTest) {
w.Push(rec);
result.append((const char *)rec, rec->GetSize());
UNIT_ASSERT_VALUES_EQUAL(w.GetSize(), result.size());
- }
-
+ }
+
TString temp;
w.Finish(&temp);
- UNIT_ASSERT_STRINGS_EQUAL(temp, result);
- }
-}
+ UNIT_ASSERT_STRINGS_EQUAL(temp, result);
+ }
+}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.cpp
index b9cf5c78ee6..7abc4049fe5 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.cpp
@@ -64,7 +64,7 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
void TSyncLogNeighbors::Lock(const TVDiskID &vdisk, ui64 lsn) {
LOG_DEBUG(*ActorSystem, BS_SYNCLOG,
- VDISKP(LogPrefix, "Lock: vdisk# %s lsn# %" PRIu64,
+ VDISKP(LogPrefix, "Lock: vdisk# %s lsn# %" PRIu64,
vdisk.ToString().data(), lsn));
TNeighbors::TValue &ref = Neighbors[vdisk];
@@ -75,7 +75,7 @@ namespace NKikimr {
void TSyncLogNeighbors::Unlock(const TVDiskID &vdisk) {
LOG_DEBUG(*ActorSystem, BS_SYNCLOG,
- VDISKP(LogPrefix, "Unlock: vdisk# %s",
+ VDISKP(LogPrefix, "Unlock: vdisk# %s",
vdisk.ToString().data()));
TNeighbors::TValue &ref = Neighbors[vdisk];
@@ -89,7 +89,7 @@ namespace NKikimr {
const bool isLocked = ref.Get().LockedLsn != (ui64)-1;
LOG_DEBUG(*ActorSystem, BS_SYNCLOG,
- VDISKP(LogPrefix, "IsLocked: vdisk# %s res# %s",
+ VDISKP(LogPrefix, "IsLocked: vdisk# %s res# %s",
vdisk.ToString().data(),
(isLocked ? "true" : "false")));
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.h
index 72bb1c825d8..a2995114319 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogneighbors.h
@@ -115,7 +115,7 @@ namespace NKikimr {
}
TSyncLogNeighbors(const TVDiskIdShort &selfVDisk,
- std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
+ std::shared_ptr<TBlobStorageGroupInfo::TTopology> top,
const TString &logPrefix, TActorSystem *actorSystem)
: Neighbors(selfVDisk, top)
, SyncPosQueue()
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogreader.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogreader.cpp
index 2873bcb56c8..3089a8f8a8d 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogreader.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogreader.cpp
@@ -117,7 +117,7 @@ namespace NKikimr {
// TSyncLogFilter
////////////////////////////////////////////////////////////////////////////
struct TSyncLogFilter : private TLogoBlobFilter {
- TSyncLogFilter(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
+ TSyncLogFilter(const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top,
const TVDiskID &vdisk)
: TLogoBlobFilter(top, vdisk)
{}
@@ -165,9 +165,9 @@ namespace NKikimr {
"SYNCLOG REPLY: SourceVDisk# %s guid# %" PRIu64 " lsn# %" PRIu64,
SourceVDisk.ToString().data(), static_cast<ui64>(VDiskIncarnationGuid), lsn));
- auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, SelfVDiskId,
- TSyncState(VDiskIncarnationGuid, lsn), finished, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(),
- Now, SlCtx->IFaceMonGroup.SyncReadResMsgsPtr(), nullptr, std::move(Ev->TraceId), Ev->GetChannel());
+ auto result = std::make_unique<TEvBlobStorage::TEvVSyncResult>(status, SelfVDiskId,
+ TSyncState(VDiskIncarnationGuid, lsn), finished, SlCtx->VCtx->GetOutOfSpaceState().GetLocalStatusFlags(),
+ Now, SlCtx->IFaceMonGroup.SyncReadResMsgsPtr(), nullptr, std::move(Ev->TraceId), Ev->GetChannel());
if (DiskReads) {
NKikimrBlobStorage::TEvVSyncResult::TStat *stat = nullptr;
stat = result->Record.MutableStat();
@@ -177,7 +177,7 @@ namespace NKikimr {
FragmentWriter.Finish(result->Record.MutableData());
}
- SendVDiskResponse(ctx, Ev->Sender, result.release(), *this, Ev->Cookie);
+ SendVDiskResponse(ctx, Ev->Sender, result.release(), *this, Ev->Cookie);
ctx.Send(ParentId, new TEvSyncLogReadFinished(SourceVDisk));
Die(ctx);
}
@@ -209,7 +209,7 @@ namespace NKikimr {
str << "SYNCLOG LOGIC ERROR: " << wno.Explanation
<< " " << InternalsToString(Ev->Get(), SnapPtr.Get(), DbBirthLsn);
LOG_ERROR(ctx, BS_SYNCLOG, str.Str());
- // Y_FAIL("%s", str.Str().data()); // TODO(alexvru): fix logic
+ // Y_FAIL("%s", str.Str().data()); // TODO(alexvru): fix logic
}
Finish(ctx, NKikimrProto::ERROR, 0, true);
}
@@ -344,7 +344,7 @@ namespace NKikimr {
ui32 chunkIdx = p.first;
const TDiskIndexRecord *idxRec = p.second;
auto msg = ev->Get();
- const TBufferWithGaps &readData = ev->Get()->Data;
+ const TBufferWithGaps &readData = ev->Get()->Data;
Y_VERIFY(chunkIdx == msg->ChunkIdx &&
idxRec->OffsetInPages * SnapPtr->AppendBlockSize == msg->Offset &&
idxRec->PagesNum * SnapPtr->AppendBlockSize == readData.Size(),
@@ -388,21 +388,21 @@ namespace NKikimr {
Die(ctx);
}
- STRICT_STFUNC(StateInitFunc,
- HFunc(TEvSyncLogSnapshotResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateInitFunc,
+ HFunc(TEvSyncLogSnapshotResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
- STRICT_STFUNC(StateReadFunc,
- HFunc(NPDisk::TEvChunkReadResult, Handle)
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- )
+ STRICT_STFUNC(StateReadFunc,
+ HFunc(NPDisk::TEvChunkReadResult, Handle)
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ )
PDISK_TERMINATE_STATE_FUNC_DEF;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_SYNCLOG_READER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_SYNCLOG_READER;
}
TSyncLogReaderActor(
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.cpp b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.cpp
index 9564b78c00b..38b97c60b82 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.cpp
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.cpp
@@ -7,15 +7,15 @@ namespace NKikimr {
////////////////////////////////////////////////////////////////////////////
// TSyncLogRepaired
////////////////////////////////////////////////////////////////////////////
- std::unique_ptr<TSyncLogRepaired> TSyncLogRepaired::Construct(
+ std::unique_ptr<TSyncLogRepaired> TSyncLogRepaired::Construct(
TSyncLogParams &&params,
const TString &data,
ui64 entryPointLsn,
TString &explanation)
{
TEntryPointParser parser(std::move(params));
- bool needsInitialCommit = false;
- bool success = parser.Parse(data, needsInitialCommit, explanation);
+ bool needsInitialCommit = false;
+ bool success = parser.Parse(data, needsInitialCommit, explanation);
if (!success) {
return nullptr;
}
@@ -23,28 +23,28 @@ namespace NKikimr {
const ui64 recoveryLogConfirmedLsn = parser.GetRecoveryLogConfirmedLsn();
TCommitHistory commitHistory(TAppData::TimeProvider->Now(), entryPointLsn, recoveryLogConfirmedLsn);
// build TSyncLogRepaired
- return std::unique_ptr<TSyncLogRepaired>(new TSyncLogRepaired(parser.GetSyncLogPtr(),
+ return std::unique_ptr<TSyncLogRepaired>(new TSyncLogRepaired(parser.GetSyncLogPtr(),
parser.GetChunksToDelete(),
- std::move(commitHistory),
- needsInitialCommit));
+ std::move(commitHistory),
+ needsInitialCommit));
}
TSyncLogRepaired::TSyncLogRepaired(
TSyncLogPtr &&syncLog,
TVector<ui32> &&chunksToDelete,
- TCommitHistory &&commitHistory,
- bool needsInitialCommit)
+ TCommitHistory &&commitHistory,
+ bool needsInitialCommit)
: SyncLogPtr(std::move(syncLog))
, ChunksToDelete(std::move(chunksToDelete))
, CommitHistory(std::move(commitHistory))
- , NeedsInitialCommit(needsInitialCommit)
+ , NeedsInitialCommit(needsInitialCommit)
{}
////////////////////////////////////////////////////////////////////////////
// TSyncLogRecovery
////////////////////////////////////////////////////////////////////////////
- TSyncLogRecovery::TSyncLogRecovery(std::unique_ptr<TSyncLogRepaired> &&repaired) {
+ TSyncLogRecovery::TSyncLogRecovery(std::unique_ptr<TSyncLogRepaired> &&repaired) {
Repaired = std::move(repaired);
}
@@ -69,7 +69,7 @@ namespace NKikimr {
++Blocks;
char buf[NSyncLog::MaxRecFullSize];
- ui32 size = NSyncLog::TSerializeRoutines::SetBlock(buf, lsn, tabletId, gen, 0);
+ ui32 size = NSyncLog::TSerializeRoutines::SetBlock(buf, lsn, tabletId, gen, 0);
Repaired->SyncLogPtr->PutOne((const NSyncLog::TRecordHdr *)buf, size);
}
@@ -122,11 +122,11 @@ namespace NKikimr {
Repaired->SyncLogPtr->PutOne((const NSyncLog::TRecordHdr *)buf, size);
}
- std::unique_ptr<TSyncLogRepaired> TSyncLogRecovery::ReleaseRepaired() {
+ std::unique_ptr<TSyncLogRepaired> TSyncLogRecovery::ReleaseRepaired() {
// after finishing recovery check that Dsk and Mem do not intersect
Y_VERIFY(Repaired->SyncLogPtr->CheckMemAndDiskRecLogsDoNotIntersect(),
"%s", Repaired->SyncLogPtr->BoundariesToString().data());
- return std::exchange(Repaired, nullptr);
+ return std::exchange(Repaired, nullptr);
}
ui64 TSyncLogRecovery::GetLastLsnOfIndexRecord() const {
@@ -154,7 +154,7 @@ namespace NKikimr {
s << "{GetLastLsnOfIndexRecord# " << GetLastLsnOfIndexRecord()
<< " AddSegs# " << AddSegs << " LogoBlobs# " << LogoBlobs
<< " Blocks# " << Blocks << " Gcs# " << Gcs
- << " Barriers# " << Barriers << "}";
+ << " Barriers# " << Barriers << "}";
return s.Str();
}
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.h
index 9e7ea1ab997..83a30dec506 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogrecovery.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include "defs.h"
-#include "blobstorage_synclogdata.h"
+#include "blobstorage_synclogdata.h"
#include "blobstorage_synclogkeeper_committer.h"
#include <ydb/core/blobstorage/vdisk/hulldb/generic/hullds_sst.h>
#include <ydb/core/blobstorage/vdisk/hulldb/base/hullbase_logoblob.h>
-
-namespace NKikimr {
- namespace NSyncLog {
-
- ////////////////////////////////////////////////////////////////////////////
+
+namespace NKikimr {
+ namespace NSyncLog {
+
+ ////////////////////////////////////////////////////////////////////////////
// TSyncLogRepaired
// This is output of local recovery process concerning SyncLog, we pass
// it to new SyncLog actor and then to SyncLogKeeper respectively
@@ -18,12 +18,12 @@ namespace NKikimr {
TSyncLogPtr SyncLogPtr;
TVector<ui32> ChunksToDelete;
TCommitHistory CommitHistory;
- bool NeedsInitialCommit;
+ bool NeedsInitialCommit;
~TSyncLogRepaired() = default;
// return nullptr on error
- static std::unique_ptr<TSyncLogRepaired> Construct(
+ static std::unique_ptr<TSyncLogRepaired> Construct(
TSyncLogParams &&params,
const TString &data,
ui64 entryPointLsn,
@@ -33,22 +33,22 @@ namespace NKikimr {
TSyncLogRepaired(
TSyncLogPtr &&syncLog,
TVector<ui32> &&chunksToDelete,
- TCommitHistory &&commitHistory,
- bool needsInitialCommit);
+ TCommitHistory &&commitHistory,
+ bool needsInitialCommit);
};
////////////////////////////////////////////////////////////////////////////
- // TSyncLogRecovery
+ // TSyncLogRecovery
// The class manages the process of local recovery for SyncLog
- ////////////////////////////////////////////////////////////////////////////
- class TSyncLogRecovery : public TThrRefBase {
- public:
- using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
- using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
-
- public:
- TSyncLogRecovery(std::unique_ptr<TSyncLogRepaired> &&repaired);
+ ////////////////////////////////////////////////////////////////////////////
+ class TSyncLogRecovery : public TThrRefBase {
+ public:
+ using TLevelSegment = NKikimr::TLevelSegment<TKeyLogoBlob, TMemRecLogoBlob>;
+ using TLevelSegmentPtr = TIntrusivePtr<TLevelSegment>;
+
+ public:
+ TSyncLogRecovery(std::unique_ptr<TSyncLogRepaired> &&repaired);
void PutLogoBlob(
const TBlobStorageGroupType &gtype,
ui64 lsn,
@@ -70,22 +70,22 @@ namespace NKikimr {
ui32 collectStep,
bool hard,
const TBarrierIngress &ingress);
- std::unique_ptr<TSyncLogRepaired> ReleaseRepaired();
+ std::unique_ptr<TSyncLogRepaired> ReleaseRepaired();
ui64 GetLastLsnOfIndexRecord() const;
ui64 GetLastLsn() const;
const TSyncLogHeader &GetSyncLogHeader() const;
void GetOwnedChunks(TSet<TChunkIdx>& chunks) const;
-
- private:
+
+ private:
TString ToString() const;
-
- std::unique_ptr<TSyncLogRepaired> Repaired;
+
+ std::unique_ptr<TSyncLogRepaired> Repaired;
ui64 AddSegs = 0;
ui64 LogoBlobs = 0;
ui64 Blocks = 0;
ui64 Gcs = 0;
ui64 Barriers = 0;
- };
-
- } // NSyncLog
-} // NKikimr
+ };
+
+ } // NSyncLog
+} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogwriteparts.h b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogwriteparts.h
index 4b2347b4c4c..8f1f2083f89 100644
--- a/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogwriteparts.h
+++ b/ydb/core/blobstorage/vdisk/synclog/blobstorage_synclogwriteparts.h
@@ -18,23 +18,23 @@ namespace NKikimr {
: PageSize(pageSize)
{}
- virtual TDataRef operator[] (ui32 i) const { return Refs[i]; }
- virtual ui32 Size() const { return Refs.size(); }
+ virtual TDataRef operator[] (ui32 i) const { return Refs[i]; }
+ virtual ui32 Size() const { return Refs.size(); }
- void Push(TSyncLogPageSnap pageSnap) {
- Pages.push_back(pageSnap);
+ void Push(TSyncLogPageSnap pageSnap) {
+ Pages.push_back(pageSnap);
}
- void GenRefs() {
- Refs.clear();
- Refs.reserve(Pages.size() * PartsForPage);
- for (const auto& p : Pages) {
- Refs.push_back(p.GetFirstRaw());
- Refs.push_back(p.GetSecondRaw());
- if (const TDataRef& ref = p.GetThirdRaw(PageSize); ref.second) {
- Refs.push_back(ref);
- }
- }
+ void GenRefs() {
+ Refs.clear();
+ Refs.reserve(Pages.size() * PartsForPage);
+ for (const auto& p : Pages) {
+ Refs.push_back(p.GetFirstRaw());
+ Refs.push_back(p.GetSecondRaw());
+ if (const TDataRef& ref = p.GetThirdRaw(PageSize); ref.second) {
+ Refs.push_back(ref);
+ }
+ }
}
const TVector<TSyncLogPageSnap> &GetSnapPages() const {
@@ -54,7 +54,7 @@ namespace NKikimr {
private:
const ui32 PageSize;
TVector<TSyncLogPageSnap> Pages;
- std::vector<TDataRef> Refs;
+ std::vector<TDataRef> Refs;
};
} // NSyncLog
diff --git a/ydb/core/blobstorage/vdisk/vdisk_services.h b/ydb/core/blobstorage/vdisk/vdisk_services.h
index 8f4ad3a98cd..7534914305a 100644
--- a/ydb/core/blobstorage/vdisk/vdisk_services.h
+++ b/ydb/core/blobstorage/vdisk/vdisk_services.h
@@ -6,7 +6,7 @@ namespace NKikimr {
// Some services to run on a node for correct functionalily of VDisks
- extern IActor *CreateReplBrokerActor(ui64 maxMemBytes);
+ extern IActor *CreateReplBrokerActor(ui64 maxMemBytes);
} // NKikimr
diff --git a/ydb/core/blobstorage/vdisk/ya.make b/ydb/core/blobstorage/vdisk/ya.make
index d1762b411c7..2097facbca8 100644
--- a/ydb/core/blobstorage/vdisk/ya.make
+++ b/ydb/core/blobstorage/vdisk/ya.make
@@ -41,7 +41,7 @@ RECURSE(
localrecovery
query
repl
- scrub
+ scrub
skeleton
syncer
synclog
diff --git a/ydb/core/blobstorage/ya.make b/ydb/core/blobstorage/ya.make
index 17f379ebf17..ea12d1713da 100644
--- a/ydb/core/blobstorage/ya.make
+++ b/ydb/core/blobstorage/ya.make
@@ -54,10 +54,10 @@ RECURSE(
)
RECURSE_FOR_TESTS(
- ut_blobstorage
- ut_group
- ut_mirror3of4
+ ut_blobstorage
+ ut_group
+ ut_mirror3of4
ut_pdiskfit
ut_vdisk
- ut_vdisk2
+ ut_vdisk2
)
diff --git a/ydb/core/client/flat_ut.cpp b/ydb/core/client/flat_ut.cpp
index 362c052aa11..011d1ebd1e5 100644
--- a/ydb/core/client/flat_ut.cpp
+++ b/ydb/core/client/flat_ut.cpp
@@ -1474,7 +1474,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
")";
TClient::TFlatQueryOptions opts;
- NKikimrClient::TResponse response;
+ NKikimrClient::TResponse response;
int errorCount = 0;
for (ui32 i = 0; i < 20; ++i) {
@@ -1545,7 +1545,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
ui32 status = 0;
TClient::TFlatQueryOptions opts;
- NKikimrClient::TResponse response;
+ NKikimrClient::TResponse response;
status = annoyingClient.FlatQueryRaw(Sprintf(R"(
(
(let range '('ExcFrom 'ExcTo '('Key (Null) (Void))))
@@ -1643,7 +1643,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
ui32 status = 0;
TClient::TFlatQueryOptions opts;
- NKikimrClient::TResponse response;
+ NKikimrClient::TResponse response;
status = annoyingClient.FlatQueryRaw(readQuery, opts, response);
UNIT_ASSERT_VALUES_EQUAL_C((NMsgBusProxy::EResponseStatus)status, NMsgBusProxy::MSTATUS_ERROR, "Big read should fail");
}
@@ -1703,7 +1703,7 @@ Y_UNIT_TEST_SUITE(TFlatTest) {
ui32 status = 0;
TClient::TFlatQueryOptions opts;
- NKikimrClient::TResponse response;
+ NKikimrClient::TResponse response;
status = annoyingClient.FlatQueryRaw(readQuery, opts, response);
UNIT_ASSERT_VALUES_EQUAL_C((NMsgBusProxy::EResponseStatus)status, NMsgBusProxy::MSTATUS_ERROR, "Big read should fail");
}
diff --git a/ydb/core/client/flat_ut_client.h b/ydb/core/client/flat_ut_client.h
index 07f5b30cc6b..999bab4f22c 100644
--- a/ydb/core/client/flat_ut_client.h
+++ b/ydb/core/client/flat_ut_client.h
@@ -49,7 +49,7 @@ public:
}
TAutoPtr<NMsgBusProxy::TBusResponse> LsPathId(ui64 schemeshardId, ui64 pathId) {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
request->Record.SetPathId(pathId);
request->Record.SetSchemeshardId(schemeshardId);
TAutoPtr<NBus::TBusMessage> reply;
@@ -86,7 +86,7 @@ public:
TVector<ui64> GetTablePartitions(const TString& tablePath) {
TAutoPtr<NMsgBusProxy::TBusResponse> msg = Ls(tablePath);
- const NKikimrClient::TResponse &response = msg->Record;
+ const NKikimrClient::TResponse &response = msg->Record;
UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), NMsgBusProxy::MSTATUS_OK);
const auto& descr = response.GetPathDescription();
TVector<ui64> partitions;
@@ -98,7 +98,7 @@ public:
}
void TrySplitTablePartition(const TString& tablePath, const TString& splitDescription, NKikimrClient::TResponse& response) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpSplitMergeTablePartitions);
UNIT_ASSERT(::google::protobuf::TextFormat::ParseFromString(splitDescription, op->MutableSplitMergeTablePartitions()));
diff --git a/ydb/core/client/locks_ut.cpp b/ydb/core/client/locks_ut.cpp
index 47b7c3dfdd5..3a555e201f7 100644
--- a/ydb/core/client/locks_ut.cpp
+++ b/ydb/core/client/locks_ut.cpp
@@ -37,7 +37,7 @@ public:
}
TAutoPtr<NMsgBusProxy::TBusResponse> LsPathId(ui64 schemeshardId, ui64 pathId) {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
request->Record.SetPathId(pathId);
request->Record.SetSchemeshardId(schemeshardId);
TAutoPtr<NBus::TBusMessage> reply;
diff --git a/ydb/core/client/minikql_compile/mkql_compile_service.cpp b/ydb/core/client/minikql_compile/mkql_compile_service.cpp
index e01d61a22cc..7fb001fbebb 100644
--- a/ydb/core/client/minikql_compile/mkql_compile_service.cpp
+++ b/ydb/core/client/minikql_compile/mkql_compile_service.cpp
@@ -59,8 +59,8 @@ public:
bool ForceRefresh;
};
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MINIKQL_COMPILE_SERVICE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MINIKQL_COMPILE_SERVICE;
}
TMiniKQLCompileService(size_t compileInflightLimit, THolder<NYql::IDbSchemeResolver>&& dbSchemeResolver)
diff --git a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
index 76f38bf35cb..7d35b7d3c30 100644
--- a/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
+++ b/ydb/core/client/minikql_compile/yql_expr_minikql.cpp
@@ -1422,8 +1422,8 @@ TMiniKQLCompileActorEvents::TEvCompileResult::TEvCompileResult(const TMiniKQLCom
class TMiniKQLCompileActor : public TActorBootstrapped<TMiniKQLCompileActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MINIKQL_COMPILE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MINIKQL_COMPILE_ACTOR;
}
TMiniKQLCompileActor(const TString& program,
diff --git a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp
index eb74fa36e94..ae713f0ec4b 100644
--- a/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp
+++ b/ydb/core/client/scheme_cache_lib/yql_db_scheme_resolver.cpp
@@ -97,8 +97,8 @@ class TTableProxyActor : public TActorBootstrapped<TTableProxyActor> {
return Die(ctx);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLE_SCHEME_RESOLVER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLE_SCHEME_RESOLVER;
}
TTableProxyActor(TActorId schemeCache, TActorId responseTo, const TVector<TTable> &tables)
diff --git a/ydb/core/client/server/grpc_proxy_status.cpp b/ydb/core/client/server/grpc_proxy_status.cpp
index 827335ad408..f7368b7a1f1 100644
--- a/ydb/core/client/server/grpc_proxy_status.cpp
+++ b/ydb/core/client/server/grpc_proxy_status.cpp
@@ -37,13 +37,13 @@ class TChooseProxyActorImpl : public TActorBootstrapped<TChooseProxyActorImpl> {
THolder<NMsgBusProxy::TBusChooseProxy> Request;
TVector<ui32> Nodes;
THashMap<ui32, TString> NodeNames;
- THashMap<ui32, TString> NodeDataCenter;
+ THashMap<ui32, TString> NodeDataCenter;
THashMap<ui32, std::shared_ptr<TEvGRpcProxyStatus::TEvGetStatusResponse>> PerNodeResponse;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FRONT_CHOOSE_RROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FRONT_CHOOSE_RROXY;
}
//
@@ -101,7 +101,7 @@ public:
Nodes.reserve(nodesInfo->Nodes.size());
for (const auto& ni : nodesInfo->Nodes) {
NodeNames[ni.NodeId] = ni.Host;
- NodeDataCenter[ni.NodeId] = ni.Location.GetDataCenterId();
+ NodeDataCenter[ni.NodeId] = ni.Location.GetDataCenterId();
SendRequest(ni.NodeId, ctx);
++NodesRequested;
}
@@ -164,8 +164,8 @@ public:
////////////////////////////////////////////
class TGRpcProxyStatusActor : public TActorBootstrapped<TGRpcProxyStatusActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FRONT_GRPC_PROXY_STATUS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FRONT_GRPC_PROXY_STATUS;
}
//
@@ -321,13 +321,13 @@ class TChooseProxyActor : public TActorBootstrapped<TChooseProxyActor>, public N
using TBase = TActorBootstrapped<TChooseProxyActor>;
THolder<NMsgBusProxy::TBusChooseProxy> Request;
THashMap<ui32, TString> NodeNames;
- THashMap<ui32, TString> NodeDataCenter;
+ THashMap<ui32, TString> NodeDataCenter;
THashMap<ui32, std::shared_ptr<TEvGRpcProxyStatus::TEvGetStatusResponse>> PerNodeResponse;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FRONT_CHOOSE_RROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FRONT_CHOOSE_RROXY;
}
//
@@ -370,9 +370,9 @@ public:
TString name;
ui64 totalWeight = 0;
ui64 cookie = 0;
- const auto& record = Request->Record;
- const std::optional<TString> filterDataCenter = record.HasDataCenter() ? std::make_optional(record.GetDataCenter()) :
- record.HasDataCenterNum() ? std::make_optional(DataCenterToString(record.GetDataCenterNum())) : std::nullopt;
+ const auto& record = Request->Record;
+ const std::optional<TString> filterDataCenter = record.HasDataCenter() ? std::make_optional(record.GetDataCenter()) :
+ record.HasDataCenterNum() ? std::make_optional(DataCenterToString(record.GetDataCenterNum())) : std::nullopt;
const bool preferLocalProxy = Request->Record.GetPreferLocalProxy();
const ui32 localNodeId = ctx.SelfID.NodeId();
//choose random proxy
@@ -382,7 +382,7 @@ public:
if (!resp.second)
continue;
s << " " << NodeNames[resp.first] << "[" << resp.first << "], " << resp.second->Record.GetWeight() << " ";
- if (filterDataCenter && filterDataCenter != NodeDataCenter[resp.first])
+ if (filterDataCenter && filterDataCenter != NodeDataCenter[resp.first])
continue;
ui64 weight = resp.second->Record.GetWeight();
diff --git a/ydb/core/client/server/grpc_proxy_status.h b/ydb/core/client/server/grpc_proxy_status.h
index 13ea9302624..b1a9d294b96 100644
--- a/ydb/core/client/server/grpc_proxy_status.h
+++ b/ydb/core/client/server/grpc_proxy_status.h
@@ -72,7 +72,7 @@ struct TEvGRpcProxyStatus {
struct TEvResponse : public TEventLocal<TEvResponse, EvResponse> {
THashMap<ui32, std::shared_ptr<TEvGRpcProxyStatus::TEvGetStatusResponse>> PerNodeResponse;
THashMap<ui32, TString> NodeNames;
- THashMap<ui32, TString> NodeDataCenter;
+ THashMap<ui32, TString> NodeDataCenter;
};
};
diff --git a/ydb/core/client/server/grpc_server.cpp b/ydb/core/client/server/grpc_server.cpp
index aa122da36a1..f2e360aa438 100644
--- a/ydb/core/client/server/grpc_server.cpp
+++ b/ydb/core/client/server/grpc_server.cpp
@@ -8,11 +8,11 @@
#include <library/cpp/grpc/server/grpc_async_ctx_base.h>
#include <library/cpp/json/json_writer.h>
-
+
#include <util/string/join.h>
#include <google/protobuf/text_format.h>
-
+
#include <grpc++/resource_quota.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/server_builder.h>
@@ -26,10 +26,10 @@ using grpc::ServerAsyncWriter;
using grpc::Status;
using grpc::StatusCode;
using grpc::ServerCompletionQueue;
-using grpc::CompletionQueue;
+using grpc::CompletionQueue;
-using NKikimrClient::TResponse;
-using NKikimrClient::TPersQueueRequest;
+using NKikimrClient::TResponse;
+using NKikimrClient::TPersQueueRequest;
using NGrpc::IQueueEvent;
@@ -42,34 +42,34 @@ namespace {
using TGrpcBaseAsyncContext = NGrpc::TBaseAsyncContext<NGRpcProxy::TGRpcService>;
-template <typename TIn, typename TOut = TResponse>
+template <typename TIn, typename TOut = TResponse>
class TSimpleRequest
: public IQueueEvent
, public TGrpcBaseAsyncContext
, public IRequestContext
{
- using TOnRequest = std::function<void (IRequestContext* ctx)>;
-
- using TRequestCallback = void (NKikimrClient::TGRpcServer::AsyncService::*)(ServerContext*, TIn*,
- ServerAsyncResponseWriter<TOut>*, CompletionQueue*, ServerCompletionQueue*, void*);
+ using TOnRequest = std::function<void (IRequestContext* ctx)>;
+ using TRequestCallback = void (NKikimrClient::TGRpcServer::AsyncService::*)(ServerContext*, TIn*,
+ ServerAsyncResponseWriter<TOut>*, CompletionQueue*, ServerCompletionQueue*, void*);
+
public:
TSimpleRequest(TGRpcService* server,
- NKikimrClient::TGRpcServer::AsyncService* service,
+ NKikimrClient::TGRpcServer::AsyncService* service,
ServerCompletionQueue* cq,
- TOnRequest cb,
- TRequestCallback requestCallback,
- TActorSystem& as,
- const char* name,
+ TOnRequest cb,
+ TRequestCallback requestCallback,
+ TActorSystem& as,
+ const char* name,
NGrpc::ICounterBlockPtr counters)
: TGrpcBaseAsyncContext(service, cq)
, Server(server)
, Cb(cb)
, RequestCallback(requestCallback)
- , ActorSystem(as)
- , Name(name)
- , Counters(std::move(counters))
+ , ActorSystem(as)
+ , Name(name)
+ , Counters(std::move(counters))
, Writer(new ServerAsyncResponseWriter<TOut>(&Context))
, StateFunc(&TSimpleRequest::RequestDone)
, RequestSize(0)
@@ -77,10 +77,10 @@ public:
, ResponseStatus(0)
, InProgress_(false)
{
- LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] created request Name# %s", this, Name);
+ LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] created request Name# %s", this, Name);
}
- ~TSimpleRequest() {
+ ~TSimpleRequest() {
if (InProgress_) {
//If we are ShuttingDown probably ActorSystem unable to recieve new events
if (!Server->IsShuttingDown()) {
@@ -89,9 +89,9 @@ public:
Counters->FinishProcessing(RequestSize, ResponseSize, false, ResponseStatus,
TDuration::Seconds(RequestTimer.Passed()));
Server->DecRequest();
- }
- }
-
+ }
+ }
+
void Start() {
if (auto guard = Server->ProtectShutdown()) {
(Service->*RequestCallback)(&Context, &Request, Writer.Get(), CQ, CQ, GetGRpcTag());
@@ -102,14 +102,14 @@ public:
}
public:
- //! Start another instance of request to grab next incoming query (only when the server is not shutting down)
- void Clone() {
- if (!Server->IsShuttingDown()) {
+ //! Start another instance of request to grab next incoming query (only when the server is not shutting down)
+ void Clone() {
+ if (!Server->IsShuttingDown()) {
if (RequestCallback)
(new TSimpleRequest(Server, Service, CQ, Cb, RequestCallback, ActorSystem, Name, Counters))->Start();
- }
- }
-
+ }
+ }
+
bool Execute(bool ok) override {
return (this->*StateFunc)(ok);
}
@@ -122,37 +122,37 @@ public:
delete this;
}
-public:
+public:
//! Get pointer to the request's message.
const NProtoBuf::Message* GetRequest() const override {
return &Request;
}
//! Send reply.
- void Reply(const NKikimrClient::TResponse& resp) override {
- if (const TOut *x = dynamic_cast<const TOut *>(&resp)) {
+ void Reply(const NKikimrClient::TResponse& resp) override {
+ if (const TOut *x = dynamic_cast<const TOut *>(&resp)) {
Finish(*x, 0);
- } else {
- ReplyError(resp.GetErrorReason());
- }
- }
-
- void Reply(const NKikimrClient::TBsTestLoadResponse& resp) override {
- if (const TOut *x = dynamic_cast<const TOut *>(&resp)) {
+ } else {
+ ReplyError(resp.GetErrorReason());
+ }
+ }
+
+ void Reply(const NKikimrClient::TBsTestLoadResponse& resp) override {
+ if (const TOut *x = dynamic_cast<const TOut *>(&resp)) {
Finish(*x, 0);
- } else {
- ReplyError("request failed");
- }
- }
-
- void Reply(const NKikimrClient::TJSON& resp) override {
- try {
+ } else {
+ ReplyError("request failed");
+ }
+ }
+
+ void Reply(const NKikimrClient::TJSON& resp) override {
+ try {
Finish(dynamic_cast<const TOut&>(resp), 0);
- } catch (const std::bad_cast&) {
- Y_FAIL("unexpected response type generated");
- }
- }
-
+ } catch (const std::bad_cast&) {
+ Y_FAIL("unexpected response type generated");
+ }
+ }
+
void Reply(const NKikimrClient::TNodeRegistrationResponse& resp) override {
try {
Finish(dynamic_cast<const TOut&>(resp), 0);
@@ -193,20 +193,20 @@ public:
}
}
- //! Send error reply.
- void ReplyError(const TString& reason) override {
- TOut resp;
- GenerateErrorResponse(resp, reason);
+ //! Send error reply.
+ void ReplyError(const TString& reason) override {
+ TOut resp;
+ GenerateErrorResponse(resp, reason);
Finish(resp, 0);
}
- static void GenerateErrorResponse(NKikimrClient::TResponse& resp, const TString& reason) {
- resp.SetStatus(NMsgBusProxy::MSTATUS_ERROR);
- if (reason) {
- resp.SetErrorReason(reason);
- }
- }
-
+ static void GenerateErrorResponse(NKikimrClient::TResponse& resp, const TString& reason) {
+ resp.SetStatus(NMsgBusProxy::MSTATUS_ERROR);
+ if (reason) {
+ resp.SetErrorReason(reason);
+ }
+ }
+
static void GenerateErrorResponse(NKikimrClient::TNodeRegistrationResponse& resp, const TString& reason) {
resp.MutableStatus()->SetCode(NKikimrNodeBroker::TStatus::ERROR);
resp.MutableStatus()->SetReason(reason);
@@ -217,12 +217,12 @@ public:
resp.MutableStatus()->SetReason(reason);
}
- static void GenerateErrorResponse(NKikimrClient::TJSON& resp, const TString& reason) {
- NJson::TJsonValue json(NJson::JSON_MAP);
- json["ErrorReason"] = reason;
- resp.SetJSON(NJson::WriteJson(json, false));
- }
-
+ static void GenerateErrorResponse(NKikimrClient::TJSON& resp, const TString& reason) {
+ NJson::TJsonValue json(NJson::JSON_MAP);
+ json["ErrorReason"] = reason;
+ resp.SetJSON(NJson::WriteJson(json, false));
+ }
+
static void GenerateErrorResponse(NKikimrClient::TSqsResponse&, const TString&)
{ }
@@ -236,10 +236,10 @@ public:
resp.MutableStatus()->SetReason(reason);
}
- NMsgBusProxy::TBusMessageContext BindBusContext(int type) override {
+ NMsgBusProxy::TBusMessageContext BindBusContext(int type) override {
return BusContext.ConstructInPlace(this, type);
- }
-
+ }
+
TString GetPeer() const override {
return GetPeerName();
}
@@ -250,16 +250,16 @@ private:
}
void Finish(const TOut& resp, ui32 status) {
- auto makeResponseString = [&] {
- TString x;
- google::protobuf::TextFormat::Printer printer;
- printer.SetSingleLineMode(true);
- printer.PrintToString(resp, &x);
- return x;
- };
+ auto makeResponseString = [&] {
+ TString x;
+ google::protobuf::TextFormat::Printer printer;
+ printer.SetSingleLineMode(true);
+ printer.PrintToString(resp, &x);
+ return x;
+ };
LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] issuing response Name# %s data# %s peer# %s", this,
Name, makeResponseString().data(), Context.peer().c_str());
- ResponseSize = resp.ByteSize();
+ ResponseSize = resp.ByteSize();
ResponseStatus = status;
StateFunc = &TSimpleRequest::FinishDone;
Writer->Finish(resp, Status::OK, GetGRpcTag());
@@ -278,20 +278,20 @@ private:
}
bool RequestDone(bool ok) {
- auto makeRequestString = [&] {
- TString resp;
- if (ok) {
- google::protobuf::TextFormat::Printer printer;
- printer.SetSingleLineMode(true);
- printer.PrintToString(Request, &resp);
- } else {
- resp = "<not ok>";
- }
- return resp;
- };
+ auto makeRequestString = [&] {
+ TString resp;
+ if (ok) {
+ google::protobuf::TextFormat::Printer printer;
+ printer.SetSingleLineMode(true);
+ printer.PrintToString(Request, &resp);
+ } else {
+ resp = "<not ok>";
+ }
+ return resp;
+ };
LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] received request Name# %s ok# %s data# %s peer# %s current inflight# %li", this,
Name, ok ? "true" : "false", makeRequestString().data(), Context.peer().c_str(), Server->GetCurrentInFlight());
-
+
if (Context.c_call() == nullptr) {
Y_VERIFY(!ok);
} else if (!(RequestRegistered_ = Server->RegisterRequestCtx(this))) {
@@ -306,36 +306,36 @@ private:
Clone();
if (!ok) {
- Counters->CountNotOkRequest();
+ Counters->CountNotOkRequest();
return false;
}
if (Server->IncRequest()) {
-
+
RequestSize = Request.ByteSize();
Counters->StartProcessing(RequestSize);
- RequestTimer.Reset();
+ RequestTimer.Reset();
InProgress_ = true;
-
+
Cb(this);
} else {
FinishNoResource();
}
-
+
return true;
}
- bool FinishDone(bool ok) {
+ bool FinishDone(bool ok) {
LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] finished request Name# %s ok# %s peer# %s", this,
Name, ok ? "true" : "false", Context.peer().c_str());
Counters->FinishProcessing(RequestSize, ResponseSize, ok, ResponseStatus,
TDuration::Seconds(RequestTimer.Passed()));
Server->DecRequest();
InProgress_ = false;
-
+
return false;
}
-
+
bool FinishDoneWithoutProcessing(bool ok) {
LOG_DEBUG(ActorSystem, NKikimrServices::GRPC_SERVER, "[%p] finished request without processing Name# %s ok# %s peer# %s", this,
Name, ok ? "true" : "false", Context.peer().c_str());
@@ -349,8 +349,8 @@ private:
TGRpcService* const Server;
TOnRequest Cb;
TRequestCallback RequestCallback;
- TActorSystem& ActorSystem;
- const char* const Name;
+ TActorSystem& ActorSystem;
+ const char* const Name;
NGrpc::ICounterBlockPtr Counters;
THolder<ServerAsyncResponseWriter<TOut>> Writer;
@@ -360,8 +360,8 @@ private:
ui32 RequestSize;
ui32 ResponseSize;
ui32 ResponseStatus;
- THPTimer RequestTimer;
-
+ THPTimer RequestTimer;
+
TMaybe<NMsgBusProxy::TBusMessageContext> BusContext;
bool InProgress_;
bool RequestRegistered_ = false;
@@ -395,8 +395,8 @@ TFuture<void> TGRpcService::Prepare(TActorSystem* system, const TActorId& pqMeta
}
};
return promise.GetFuture();
-}
-
+}
+
void TGRpcService::SetGlobalLimiterHandle(NGrpc::TGlobalLimiter *limiter) {
Limiter_ = limiter;
}
@@ -419,7 +419,7 @@ void TGRpcService::Start() {
ui32 nodeId = ActorSystem->NodeId;
ActorSystem->Send(MakeGRpcProxyStatusID(nodeId), new TEvGRpcProxyStatus::TEvSetup(true, PersQueueWriteSessionsMaxCount,
PersQueueReadSessionsMaxCount));
- SetupIncomingRequests();
+ SetupIncomingRequests();
}
void TGRpcService::RegisterRequestActor(NActors::IActor* req) {
@@ -428,9 +428,9 @@ void TGRpcService::RegisterRequestActor(NActors::IActor* req) {
void TGRpcService::SetupIncomingRequests() {
- auto getCounterBlock = NGRpcService::CreateCounterCb(Counters, ActorSystem);
-
-#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
+ auto getCounterBlock = NGRpcService::CreateCounterCb(Counters, ActorSystem);
+
+#define ADD_REQUEST(NAME, IN, OUT, ACTION) \
(new TSimpleRequest<NKikimrClient::IN, NKikimrClient::OUT>(this, &Service_, CQ, \
[this](IRequestContext *ctx) { \
NGRpcService::ReportGrpcReqToMon(*ActorSystem, ctx->GetPeer()); \
@@ -438,25 +438,25 @@ void TGRpcService::SetupIncomingRequests() {
}, &NKikimrClient::TGRpcServer::AsyncService::Request ## NAME, \
*ActorSystem, #NAME, getCounterBlock("legacy", #NAME)))->Start();
-#define ADD_ACTOR_REQUEST(NAME, TYPE, MTYPE) \
- ADD_REQUEST(NAME, TYPE, TResponse, { \
- NMsgBusProxy::TBusMessageContext msg(ctx->BindBusContext(NMsgBusProxy::MTYPE)); \
+#define ADD_ACTOR_REQUEST(NAME, TYPE, MTYPE) \
+ ADD_REQUEST(NAME, TYPE, TResponse, { \
+ NMsgBusProxy::TBusMessageContext msg(ctx->BindBusContext(NMsgBusProxy::MTYPE)); \
NGRpcService::ReportGrpcReqToMon(*ActorSystem, ctx->GetPeer()); \
RegisterRequestActor(CreateMessageBus ## NAME(msg)); \
- })
-
-
- // actor requests
- ADD_ACTOR_REQUEST(BSAdm, TBSAdm, MTYPE_CLIENT_BSADM)
- ADD_ACTOR_REQUEST(BlobStorageConfig, TBlobStorageConfigRequest, MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST)
- ADD_ACTOR_REQUEST(HiveCreateTablet, THiveCreateTablet, MTYPE_CLIENT_HIVE_CREATE_TABLET)
- ADD_ACTOR_REQUEST(LocalEnumerateTablets, TLocalEnumerateTablets, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS)
- ADD_ACTOR_REQUEST(KeyValue, TKeyValueRequest, MTYPE_CLIENT_KEYVALUE)
- ADD_ACTOR_REQUEST(TabletStateRequest, TTabletStateRequest, MTYPE_CLIENT_TABLET_STATE_REQUEST)
- ADD_ACTOR_REQUEST(LocalMKQL, TLocalMKQL, MTYPE_CLIENT_LOCAL_MINIKQL)
- ADD_ACTOR_REQUEST(LocalSchemeTx, TLocalSchemeTx, MTYPE_CLIENT_LOCAL_SCHEME_TX)
- ADD_ACTOR_REQUEST(TabletKillRequest, TTabletKillRequest, MTYPE_CLIENT_TABLET_KILL_REQUEST)
- ADD_ACTOR_REQUEST(SchemeOperationStatus, TSchemeOperationStatus, MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST)
+ })
+
+
+ // actor requests
+ ADD_ACTOR_REQUEST(BSAdm, TBSAdm, MTYPE_CLIENT_BSADM)
+ ADD_ACTOR_REQUEST(BlobStorageConfig, TBlobStorageConfigRequest, MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST)
+ ADD_ACTOR_REQUEST(HiveCreateTablet, THiveCreateTablet, MTYPE_CLIENT_HIVE_CREATE_TABLET)
+ ADD_ACTOR_REQUEST(LocalEnumerateTablets, TLocalEnumerateTablets, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS)
+ ADD_ACTOR_REQUEST(KeyValue, TKeyValueRequest, MTYPE_CLIENT_KEYVALUE)
+ ADD_ACTOR_REQUEST(TabletStateRequest, TTabletStateRequest, MTYPE_CLIENT_TABLET_STATE_REQUEST)
+ ADD_ACTOR_REQUEST(LocalMKQL, TLocalMKQL, MTYPE_CLIENT_LOCAL_MINIKQL)
+ ADD_ACTOR_REQUEST(LocalSchemeTx, TLocalSchemeTx, MTYPE_CLIENT_LOCAL_SCHEME_TX)
+ ADD_ACTOR_REQUEST(TabletKillRequest, TTabletKillRequest, MTYPE_CLIENT_TABLET_KILL_REQUEST)
+ ADD_ACTOR_REQUEST(SchemeOperationStatus, TSchemeOperationStatus, MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST)
ADD_ACTOR_REQUEST(BlobStorageLoadRequest, TBsTestLoadRequest, MTYPE_CLIENT_LOAD_REQUEST)
ADD_ACTOR_REQUEST(BlobStorageGetRequest, TBsGetRequest, MTYPE_CLIENT_GET_REQUEST)
ADD_ACTOR_REQUEST(ChooseProxy, TChooseProxyRequest, MTYPE_CLIENT_CHOOSE_PROXY)
@@ -464,9 +464,9 @@ void TGRpcService::SetupIncomingRequests() {
ADD_ACTOR_REQUEST(ResolveNode, TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE)
ADD_ACTOR_REQUEST(FillNode, TFillNodeRequest, MTYPE_CLIENT_FILL_NODE)
ADD_ACTOR_REQUEST(DrainNode, TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE)
- ADD_ACTOR_REQUEST(InterconnectDebug, TInterconnectDebug, MTYPE_CLIENT_INTERCONNECT_DEBUG)
- ADD_ACTOR_REQUEST(TestShardControl, TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL)
-
+ ADD_ACTOR_REQUEST(InterconnectDebug, TInterconnectDebug, MTYPE_CLIENT_INTERCONNECT_DEBUG)
+ ADD_ACTOR_REQUEST(TestShardControl, TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL)
+
// dynamic node registration
ADD_REQUEST(RegisterNode, TNodeRegistrationRequest, TNodeRegistrationResponse, {
NMsgBusProxy::TBusMessageContext msg(ctx->BindBusContext(NMsgBusProxy::MTYPE_CLIENT_NODE_REGISTRATION_REQUEST));
@@ -497,34 +497,34 @@ void TGRpcService::SetupIncomingRequests() {
RegisterRequestActor(CreateMessageBusConsoleRequest(msg));
})
-#define ADD_PROXY_REQUEST_BASE(NAME, TYPE, RES_TYPE, EVENT_TYPE, MTYPE) \
- ADD_REQUEST(NAME, TYPE, RES_TYPE, { \
+#define ADD_PROXY_REQUEST_BASE(NAME, TYPE, RES_TYPE, EVENT_TYPE, MTYPE) \
+ ADD_REQUEST(NAME, TYPE, RES_TYPE, { \
if (MsgBusProxy) { \
- NMsgBusProxy::TBusMessageContext msg(ctx->BindBusContext(NMsgBusProxy::MTYPE)); \
+ NMsgBusProxy::TBusMessageContext msg(ctx->BindBusContext(NMsgBusProxy::MTYPE)); \
ActorSystem->Send(MsgBusProxy, new NMsgBusProxy::EVENT_TYPE(msg)); \
- } else { \
- ctx->ReplyError("no MessageBus proxy"); \
- } \
- })
-
-#define ADD_PROXY_REQUEST(NAME, TYPE, EVENT_TYPE, MTYPE) \
- ADD_PROXY_REQUEST_BASE(NAME, TYPE, TResponse, EVENT_TYPE, MTYPE)
-
- // proxy requests
+ } else { \
+ ctx->ReplyError("no MessageBus proxy"); \
+ } \
+ })
+
+#define ADD_PROXY_REQUEST(NAME, TYPE, EVENT_TYPE, MTYPE) \
+ ADD_PROXY_REQUEST_BASE(NAME, TYPE, TResponse, EVENT_TYPE, MTYPE)
+
+ // proxy requests
ADD_PROXY_REQUEST(SchemeInitRoot, TSchemeInitRoot, TEvBusProxy::TEvInitRoot, MTYPE_CLIENT_SCHEME_INITROOT)
-
+
ADD_PROXY_REQUEST(PersQueueRequest, TPersQueueRequest, TEvBusProxy::TEvPersQueue, MTYPE_CLIENT_PERSQUEUE)
ADD_PROXY_REQUEST(Request, TRequest, TEvBusProxy::TEvRequest, MTYPE_CLIENT_REQUEST)
ADD_PROXY_REQUEST(SchemeOperation, TSchemeOperation, TEvBusProxy::TEvFlatTxRequest, MTYPE_CLIENT_FLAT_TX_REQUEST)
ADD_PROXY_REQUEST(SchemeDescribe, TSchemeDescribe, TEvBusProxy::TEvFlatDescribeRequest, MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST)
-#define ADD_PROXY_REQUEST_JJ(NAME, EVENT_TYPE, MTYPE) \
- ADD_PROXY_REQUEST_BASE(NAME, TJSON, TJSON, EVENT_TYPE, MTYPE)
-
- // DB proxy requests both consuming and returning TJSON
- ADD_PROXY_REQUEST_JJ(DbSchema, TEvBusProxy::TEvDbSchema, MTYPE_CLIENT_DB_SCHEMA)
- ADD_PROXY_REQUEST_JJ(DbOperation, TEvBusProxy::TEvDbOperation, MTYPE_CLIENT_DB_OPERATION)
- ADD_PROXY_REQUEST_JJ(DbBatch, TEvBusProxy::TEvDbBatch, MTYPE_CLIENT_DB_BATCH)
+#define ADD_PROXY_REQUEST_JJ(NAME, EVENT_TYPE, MTYPE) \
+ ADD_PROXY_REQUEST_BASE(NAME, TJSON, TJSON, EVENT_TYPE, MTYPE)
+
+ // DB proxy requests both consuming and returning TJSON
+ ADD_PROXY_REQUEST_JJ(DbSchema, TEvBusProxy::TEvDbSchema, MTYPE_CLIENT_DB_SCHEMA)
+ ADD_PROXY_REQUEST_JJ(DbOperation, TEvBusProxy::TEvDbOperation, MTYPE_CLIENT_DB_OPERATION)
+ ADD_PROXY_REQUEST_JJ(DbBatch, TEvBusProxy::TEvDbBatch, MTYPE_CLIENT_DB_BATCH)
}
}
diff --git a/ydb/core/client/server/grpc_server.h b/ydb/core/client/server/grpc_server.h
index 2f2ae1da6b6..367d339b5b7 100644
--- a/ydb/core/client/server/grpc_server.h
+++ b/ydb/core/client/server/grpc_server.h
@@ -10,14 +10,14 @@
#include <ydb/public/lib/base/msgbus.h>
#include <util/thread/factory.h>
-#include <util/generic/queue.h>
+#include <util/generic/queue.h>
namespace NKikimr {
-
-namespace NMsgBusProxy {
- class TBusMessageContext;
-} // NMsgBusProxy
-
+
+namespace NMsgBusProxy {
+ class TBusMessageContext;
+} // NMsgBusProxy
+
namespace NGRpcProxy {
//! State of current request. It allows to:
@@ -31,20 +31,20 @@ public:
virtual const NProtoBuf::Message* GetRequest() const = 0;
//! Send reply.
- virtual void Reply(const NKikimrClient::TResponse& resp) = 0;
- virtual void Reply(const NKikimrClient::TBsTestLoadResponse& resp) = 0;
- virtual void Reply(const NKikimrClient::TJSON& resp) = 0;
+ virtual void Reply(const NKikimrClient::TResponse& resp) = 0;
+ virtual void Reply(const NKikimrClient::TBsTestLoadResponse& resp) = 0;
+ virtual void Reply(const NKikimrClient::TJSON& resp) = 0;
virtual void Reply(const NKikimrClient::TNodeRegistrationResponse& resp) = 0;
virtual void Reply(const NKikimrClient::TCmsResponse& resp) = 0;
virtual void Reply(const NKikimrClient::TSqsResponse& resp) = 0;
virtual void Reply(const NKikimrClient::TS3ListingResponse& resp) = 0;
virtual void Reply(const NKikimrClient::TConsoleResponse& resp) = 0;
-
- //! Send error reply when request wasn't handled properly.
- virtual void ReplyError(const TString& reason) = 0;
-
- //! Bind MessageBus context to the request.
- virtual NMsgBusProxy::TBusMessageContext BindBusContext(int type) = 0;
+
+ //! Send error reply when request wasn't handled properly.
+ virtual void ReplyError(const TString& reason) = 0;
+
+ //! Bind MessageBus context to the request.
+ virtual NMsgBusProxy::TBusMessageContext BindBusContext(int type) = 0;
//! Returns peer address
virtual TString GetPeer() const = 0;
@@ -61,12 +61,12 @@ public:
void SetGlobalLimiterHandle(NGrpc::TGlobalLimiter* limiter) override;
NThreading::TFuture<void> Prepare(NActors::TActorSystem* system, const NActors::TActorId& pqMeta, const NActors::TActorId& msgBusProxy, TIntrusivePtr<NMonitoring::TDynamicCounters> counters);
- void Start();
-
+ void Start();
+
bool IncRequest();
void DecRequest();
i64 GetCurrentInFlight() const;
-
+
private:
void RegisterRequestActor(NActors::IActor* req);
@@ -76,7 +76,7 @@ private:
private:
using IThreadRef = TAutoPtr<IThreadFactory::IThread>;
-
+
NActors::TActorSystem* ActorSystem;
NActors::TActorId PQMeta;
NActors::TActorId MsgBusProxy;
@@ -87,11 +87,11 @@ private:
size_t PersQueueReadSessionsMaxCount = 100000;
TIntrusivePtr<NMonitoring::TDynamicCounters> Counters;
-
+
std::function<void()> InitCb_;
- // In flight request management.
+ // In flight request management.
NGrpc::TGlobalLimiter* Limiter_ = nullptr;
-
+
};
}
diff --git a/ydb/core/client/server/msgbus_blobstorage_config.cpp b/ydb/core/client/server/msgbus_blobstorage_config.cpp
index a0af40eac95..3775d7e8a24 100644
--- a/ydb/core/client/server/msgbus_blobstorage_config.cpp
+++ b/ydb/core/client/server/msgbus_blobstorage_config.cpp
@@ -1,57 +1,57 @@
-#include "msgbus_tabletreq.h"
-#include "msgbus_securereq.h"
+#include "msgbus_tabletreq.h"
+#include "msgbus_securereq.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-namespace {
- const ui64 DefaultTimeout = 90000;
-}
-
-class TMessageBusBlobStorageConfig
- : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<
- TMessageBusBlobStorageConfig,
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+namespace {
+ const ui64 DefaultTimeout = 90000;
+}
+
+class TMessageBusBlobStorageConfig
+ : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<
+ TMessageBusBlobStorageConfig,
TEvBlobStorage::TEvControllerConfigResponse,
- NKikimrServices::TActivity::FRONT_BSADM_CONFIG
- >>
-{
+ NKikimrServices::TActivity::FRONT_BSADM_CONFIG
+ >>
+{
NKikimrBlobStorage::TConfigRequest Request;
-
-public:
- TMessageBusBlobStorageConfig(TBusMessageContext &msg, ui64 tabletId,
- const NKikimrBlobStorage::TConfigRequest &request, bool withRetry, TDuration timeout,
- const TString& token)
- : TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, false)
- , Request(request)
- {
- SetSecurityToken(token);
- SetRequireAdminAccess(true);
- }
-
- void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr &ev, const TActorContext &ctx) {
- auto &pb = *ev->Get()->Record.MutableResponse();
- TAutoPtr<TBusResponse> response(new TBusResponse);
- response->Record.SetStatus(MSTATUS_OK);
- pb.Swap(response->Record.MutableBlobStorageConfigResponse());
- SendReplyAndDie(response.Release(), ctx);
- }
-
- TEvBlobStorage::TEvControllerConfigRequest *MakeReq(const TActorContext&) {
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- auto &record = ev->Record;
- Request.Swap(record.MutableRequest());
- return ev.Release();
- }
-};
-
-IActor* CreateMessageBusBlobStorageConfig(TBusMessageContext &msg) {
- const NKikimrClient::TBlobStorageConfigRequest &record = static_cast<TBusBlobStorageConfigRequest*>(msg.GetMessage())->Record;
- const ui32 targetDomain = record.GetDomain();
- const ui64 tabletId = MakeBSControllerID(targetDomain);
- return new TMessageBusBlobStorageConfig(msg, tabletId, record.GetRequest(), true,
- TDuration::MilliSeconds(DefaultTimeout), record.GetSecurityToken());
-}
-
-}
-}
+
+public:
+ TMessageBusBlobStorageConfig(TBusMessageContext &msg, ui64 tabletId,
+ const NKikimrBlobStorage::TConfigRequest &request, bool withRetry, TDuration timeout,
+ const TString& token)
+ : TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, false)
+ , Request(request)
+ {
+ SetSecurityToken(token);
+ SetRequireAdminAccess(true);
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr &ev, const TActorContext &ctx) {
+ auto &pb = *ev->Get()->Record.MutableResponse();
+ TAutoPtr<TBusResponse> response(new TBusResponse);
+ response->Record.SetStatus(MSTATUS_OK);
+ pb.Swap(response->Record.MutableBlobStorageConfigResponse());
+ SendReplyAndDie(response.Release(), ctx);
+ }
+
+ TEvBlobStorage::TEvControllerConfigRequest *MakeReq(const TActorContext&) {
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto &record = ev->Record;
+ Request.Swap(record.MutableRequest());
+ return ev.Release();
+ }
+};
+
+IActor* CreateMessageBusBlobStorageConfig(TBusMessageContext &msg) {
+ const NKikimrClient::TBlobStorageConfigRequest &record = static_cast<TBusBlobStorageConfigRequest*>(msg.GetMessage())->Record;
+ const ui32 targetDomain = record.GetDomain();
+ const ui64 tabletId = MakeBSControllerID(targetDomain);
+ return new TMessageBusBlobStorageConfig(msg, tabletId, record.GetRequest(), true,
+ TDuration::MilliSeconds(DefaultTimeout), record.GetSecurityToken());
+}
+
+}
+}
diff --git a/ydb/core/client/server/msgbus_bsadm.cpp b/ydb/core/client/server/msgbus_bsadm.cpp
index a3bed376f43..54cb3104425 100644
--- a/ydb/core/client/server/msgbus_bsadm.cpp
+++ b/ydb/core/client/server/msgbus_bsadm.cpp
@@ -13,7 +13,7 @@ class TMessageBusBSAdmGroupReconfigureWipe : public TMessageBusSecureRequest<
TMessageBusSimpleTabletRequest<
TMessageBusBSAdmGroupReconfigureWipe,
TEvBlobStorage::TEvControllerGroupReconfigureWipeResult,
- NKikimrServices::TActivity::FRONT_BSADM_RECONF_REPLACE>> {
+ NKikimrServices::TActivity::FRONT_BSADM_RECONF_REPLACE>> {
TAutoPtr<TEvBlobStorage::TEvControllerGroupReconfigureWipe> Ev;
public:
TMessageBusBSAdmGroupReconfigureWipe(TBusMessageContext &msg, ui64 tabletId,
@@ -46,18 +46,18 @@ public:
}
}
- TEvBlobStorage::TEvControllerGroupReconfigureWipe* MakeReq(const TActorContext&) {
+ TEvBlobStorage::TEvControllerGroupReconfigureWipe* MakeReq(const TActorContext&) {
return Ev.Release();
}
};
IActor* CreateMessageBusBSAdm(TBusMessageContext &msg) {
- const NKikimrClient::TBSAdm &record = static_cast<TBusBSAdm *>(msg.GetMessage())->Record;
+ const NKikimrClient::TBSAdm &record = static_cast<TBusBSAdm *>(msg.GetMessage())->Record;
const ui32 targetDomain = record.GetDomain();
const ui64 tabletId = MakeBSControllerID(targetDomain);
- if (record.HasGroupReconfigureWipe()) {
+ if (record.HasGroupReconfigureWipe()) {
const auto &x = record.GetGroupReconfigureWipe();
if (!x.HasLocation()) {
return nullptr;
diff --git a/ydb/core/client/server/msgbus_http_server.cpp b/ydb/core/client/server/msgbus_http_server.cpp
index e535ebe3350..a3e28de8c39 100644
--- a/ydb/core/client/server/msgbus_http_server.cpp
+++ b/ydb/core/client/server/msgbus_http_server.cpp
@@ -54,7 +54,7 @@ public:
TAutoPtr<NBus::TBusBufferBase> response(static_cast<NBus::TBusBufferBase*>(pRep));
IOutputStream& out(Request.Output());
if (response->GetHeader()->Type == MTYPE_CLIENT_RESPONSE) {
- NKikimrClient::TResponse* pbResponse(static_cast<NKikimrClient::TResponse*>(response->GetRecord()));
+ NKikimrClient::TResponse* pbResponse(static_cast<NKikimrClient::TResponse*>(response->GetRecord()));
NMsgBusProxy::EResponseStatus status = static_cast<NMsgBusProxy::EResponseStatus>(pbResponse->GetStatus());
switch (status) {
case MSTATUS_OK:
@@ -85,7 +85,7 @@ public:
HttpServer->Status200->Inc();
}
if (response->GetRecord()->GetDescriptor()->name() == "TJSON") {
- NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(response->GetRecord()));
+ NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(response->GetRecord()));
const auto& jsonString(json->GetJSON());
out << jsonString;
*HttpServer->OutboundSize += jsonString.size();
@@ -180,7 +180,7 @@ void TMessageBusHttpServer::Output(NMonitoring::IMonHttpRequest& request) {
*InboundSize += postContent.size();
const ::google::protobuf::Descriptor* msgDescriptor = message->GetRecord()->GetDescriptor();
if (msgDescriptor->name() == "TJSON") {
- NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(message->GetRecord()));
+ NKikimrClient::TJSON* json(static_cast<NKikimrClient::TJSON*>(message->GetRecord()));
json->SetJSON(TString(postContent));
} else {
static NJson::TJsonReaderConfig readerConfig;
diff --git a/ydb/core/client/server/msgbus_securereq.h b/ydb/core/client/server/msgbus_securereq.h
index 5e68ca0eeb2..53694582826 100644
--- a/ydb/core/client/server/msgbus_securereq.h
+++ b/ydb/core/client/server/msgbus_securereq.h
@@ -29,7 +29,7 @@ public:
{}
};
-template <typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity>
+template <typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity>
class TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>> :
public TSecureRequestActor<
TMessageBusSimpleTabletRequest<TDerived, TTabletReplyEvent, Activity>,
diff --git a/ydb/core/client/server/msgbus_server.cpp b/ydb/core/client/server/msgbus_server.cpp
index 8a4d8a3bbd5..a6818313e78 100644
--- a/ydb/core/client/server/msgbus_server.cpp
+++ b/ydb/core/client/server/msgbus_server.cpp
@@ -4,121 +4,121 @@
#include "msgbus_server.h"
#include "msgbus_server_tracer.h"
#include "msgbus_http_server.h"
-#include "grpc_server.h"
+#include "grpc_server.h"
namespace NKikimr {
namespace NMsgBusProxy {
-class TBusMessageContext::TImpl : public TThrRefBase {
-public:
- virtual ~TImpl() = default;
- virtual NBus::TBusMessage* GetMessage() = 0;
- virtual NBus::TBusMessage* ReleaseMessage() = 0;
- virtual void SendReplyMove(NBus::TBusMessageAutoPtr response) = 0;
- virtual THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder() = 0;
-};
-
-class TBusMessageContext::TImplMessageBus
- : public TBusMessageContext::TImpl
- , private NBus::TOnMessageContext
- , private TBusMessageWatcher
-{
-public:
- TImplMessageBus()
- {}
-
- TImplMessageBus(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher)
- : TBusMessageWatcher(messageWatcher)
- {
- NBus::TOnMessageContext::Swap(messageContext);
- }
-
- ~TImplMessageBus() {
- if (NBus::TOnMessageContext::IsInWork()) {
- NotifyForget();
- NBus::TOnMessageContext::ForgetRequest();
- }
- }
-
- NBus::TBusMessage* GetMessage() override {
- return NBus::TOnMessageContext::GetMessage();
- }
-
- NBus::TBusMessage* ReleaseMessage() override {
- return NBus::TOnMessageContext::ReleaseMessage();
- }
-
- void SendReplyMove(NBus::TBusMessageAutoPtr response) override {
- NotifyReply(response.Get());
- NBus::TOnMessageContext::SendReplyMove(response);
- }
-
- NBus::TBusKey GetMessageId() override {
- return GetMessage()->GetHeader()->Id;
- }
-
+class TBusMessageContext::TImpl : public TThrRefBase {
+public:
+ virtual ~TImpl() = default;
+ virtual NBus::TBusMessage* GetMessage() = 0;
+ virtual NBus::TBusMessage* ReleaseMessage() = 0;
+ virtual void SendReplyMove(NBus::TBusMessageAutoPtr response) = 0;
+ virtual THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder() = 0;
+};
+
+class TBusMessageContext::TImplMessageBus
+ : public TBusMessageContext::TImpl
+ , private NBus::TOnMessageContext
+ , private TBusMessageWatcher
+{
+public:
+ TImplMessageBus()
+ {}
+
+ TImplMessageBus(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher)
+ : TBusMessageWatcher(messageWatcher)
+ {
+ NBus::TOnMessageContext::Swap(messageContext);
+ }
+
+ ~TImplMessageBus() {
+ if (NBus::TOnMessageContext::IsInWork()) {
+ NotifyForget();
+ NBus::TOnMessageContext::ForgetRequest();
+ }
+ }
+
+ NBus::TBusMessage* GetMessage() override {
+ return NBus::TOnMessageContext::GetMessage();
+ }
+
+ NBus::TBusMessage* ReleaseMessage() override {
+ return NBus::TOnMessageContext::ReleaseMessage();
+ }
+
+ void SendReplyMove(NBus::TBusMessageAutoPtr response) override {
+ NotifyReply(response.Get());
+ NBus::TOnMessageContext::SendReplyMove(response);
+ }
+
+ NBus::TBusKey GetMessageId() override {
+ return GetMessage()->GetHeader()->Id;
+ }
+
THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder() override;
-};
-
-class TBusMessageContext::TImplGRpc
- : public TBusMessageContext::TImpl
-{
- NGRpcProxy::IRequestContext *RequestContext;
- THolder<NBus::TBusMessage> Message;
-
-public:
- TImplGRpc(NGRpcProxy::IRequestContext *requestContext, int type)
- : RequestContext(requestContext)
- {
- switch (type) {
-#define MTYPE(TYPE) \
- case TYPE::MessageType: \
- Message.Reset(new TYPE()); \
- try { \
- static_cast<TYPE&>(*Message).Record = dynamic_cast<const TYPE::RecordType&>(*RequestContext->GetRequest()); \
- } catch (const std::bad_cast&) { \
- Y_FAIL("incorrect request message type"); \
- } \
- return;
-
- MTYPE(TBusRequest)
- MTYPE(TBusResponse)
- MTYPE(TBusFakeConfigDummy)
- MTYPE(TBusSchemeInitRoot)
- MTYPE(TBusBSAdm)
- MTYPE(TBusTypesRequest)
- MTYPE(TBusTypesResponse)
- MTYPE(TBusHiveCreateTablet)
- MTYPE(TBusOldHiveCreateTablet)
- MTYPE(TBusHiveCreateTabletResult)
- MTYPE(TBusLocalEnumerateTablets)
- MTYPE(TBusOldLocalEnumerateTablets)
- MTYPE(TBusLocalEnumerateTabletsResult)
- MTYPE(TBusKeyValue)
- MTYPE(TBusOldKeyValue)
- MTYPE(TBusKeyValueResponse)
- MTYPE(TBusPersQueue)
- MTYPE(TBusMessageBusTraceRequest)
- MTYPE(TBusMessageBusTraceStatus)
- MTYPE(TBusTabletKillRequest)
- MTYPE(TBusTabletStateRequest)
+};
+
+class TBusMessageContext::TImplGRpc
+ : public TBusMessageContext::TImpl
+{
+ NGRpcProxy::IRequestContext *RequestContext;
+ THolder<NBus::TBusMessage> Message;
+
+public:
+ TImplGRpc(NGRpcProxy::IRequestContext *requestContext, int type)
+ : RequestContext(requestContext)
+ {
+ switch (type) {
+#define MTYPE(TYPE) \
+ case TYPE::MessageType: \
+ Message.Reset(new TYPE()); \
+ try { \
+ static_cast<TYPE&>(*Message).Record = dynamic_cast<const TYPE::RecordType&>(*RequestContext->GetRequest()); \
+ } catch (const std::bad_cast&) { \
+ Y_FAIL("incorrect request message type"); \
+ } \
+ return;
+
+ MTYPE(TBusRequest)
+ MTYPE(TBusResponse)
+ MTYPE(TBusFakeConfigDummy)
+ MTYPE(TBusSchemeInitRoot)
+ MTYPE(TBusBSAdm)
+ MTYPE(TBusTypesRequest)
+ MTYPE(TBusTypesResponse)
+ MTYPE(TBusHiveCreateTablet)
+ MTYPE(TBusOldHiveCreateTablet)
+ MTYPE(TBusHiveCreateTabletResult)
+ MTYPE(TBusLocalEnumerateTablets)
+ MTYPE(TBusOldLocalEnumerateTablets)
+ MTYPE(TBusLocalEnumerateTabletsResult)
+ MTYPE(TBusKeyValue)
+ MTYPE(TBusOldKeyValue)
+ MTYPE(TBusKeyValueResponse)
+ MTYPE(TBusPersQueue)
+ MTYPE(TBusMessageBusTraceRequest)
+ MTYPE(TBusMessageBusTraceStatus)
+ MTYPE(TBusTabletKillRequest)
+ MTYPE(TBusTabletStateRequest)
MTYPE(TBusTabletCountersRequest)
- MTYPE(TBusTabletLocalMKQL)
- MTYPE(TBusTabletLocalSchemeTx)
- MTYPE(TBusSchemeOperation)
- MTYPE(TBusSchemeOperationStatus)
- MTYPE(TBusSchemeDescribe)
- MTYPE(TBusOldFlatDescribeRequest)
- MTYPE(TBusOldFlatDescribeResponse)
- MTYPE(TBusBsTestLoadRequest)
- MTYPE(TBusBsTestLoadResponse)
- MTYPE(TBusBsGetRequest)
- MTYPE(TBusBsGetResponse)
- MTYPE(TBusDbSchema)
- MTYPE(TBusDbOperation)
- MTYPE(TBusDbResponse)
- MTYPE(TBusDbBatch)
- MTYPE(TBusBlobStorageConfigRequest)
+ MTYPE(TBusTabletLocalMKQL)
+ MTYPE(TBusTabletLocalSchemeTx)
+ MTYPE(TBusSchemeOperation)
+ MTYPE(TBusSchemeOperationStatus)
+ MTYPE(TBusSchemeDescribe)
+ MTYPE(TBusOldFlatDescribeRequest)
+ MTYPE(TBusOldFlatDescribeResponse)
+ MTYPE(TBusBsTestLoadRequest)
+ MTYPE(TBusBsTestLoadResponse)
+ MTYPE(TBusBsGetRequest)
+ MTYPE(TBusBsGetResponse)
+ MTYPE(TBusDbSchema)
+ MTYPE(TBusDbOperation)
+ MTYPE(TBusDbResponse)
+ MTYPE(TBusDbBatch)
+ MTYPE(TBusBlobStorageConfigRequest)
MTYPE(TBusNodeRegistrationRequest)
MTYPE(TBusCmsRequest)
MTYPE(TBusChooseProxy)
@@ -127,205 +127,205 @@ public:
MTYPE(TBusStreamRequest)
MTYPE(TBusS3ListingRequest)
MTYPE(TBusS3ListingResponse)
- MTYPE(TBusInterconnectDebug)
+ MTYPE(TBusInterconnectDebug)
MTYPE(TBusConsoleRequest)
MTYPE(TBusResolveNode)
MTYPE(TBusFillNode)
MTYPE(TBusDrainNode)
- MTYPE(TBusTestShardControlRequest)
-#undef MTYPE
- }
-
- Y_FAIL();
- }
-
- ~TImplGRpc() {
- ForgetRequest();
- }
-
- void ForgetRequest() {
- if (RequestContext) {
+ MTYPE(TBusTestShardControlRequest)
+#undef MTYPE
+ }
+
+ Y_FAIL();
+ }
+
+ ~TImplGRpc() {
+ ForgetRequest();
+ }
+
+ void ForgetRequest() {
+ if (RequestContext) {
RequestContext->ReplyError("request wasn't processed properly");
- RequestContext = nullptr;
- }
- }
-
- NBus::TBusMessage* GetMessage() override {
- return Message.Get();
- }
-
- NBus::TBusMessage* ReleaseMessage() override {
- return Message.Release();
- }
-
- void SendReply(NBus::TBusMessage *resp) {
- Y_VERIFY(RequestContext);
- switch (const ui32 type = resp->GetHeader()->Type) {
-#define REPLY_OPTION(TYPE) \
- case TYPE::MessageType: { \
- auto *msg = dynamic_cast<TYPE *>(resp); \
- Y_VERIFY(msg); \
- RequestContext->Reply(msg->Record); \
- break; \
- }
-
- REPLY_OPTION(TBusResponse)
- REPLY_OPTION(TBusDbResponse)
- REPLY_OPTION(TBusBsTestLoadResponse)
+ RequestContext = nullptr;
+ }
+ }
+
+ NBus::TBusMessage* GetMessage() override {
+ return Message.Get();
+ }
+
+ NBus::TBusMessage* ReleaseMessage() override {
+ return Message.Release();
+ }
+
+ void SendReply(NBus::TBusMessage *resp) {
+ Y_VERIFY(RequestContext);
+ switch (const ui32 type = resp->GetHeader()->Type) {
+#define REPLY_OPTION(TYPE) \
+ case TYPE::MessageType: { \
+ auto *msg = dynamic_cast<TYPE *>(resp); \
+ Y_VERIFY(msg); \
+ RequestContext->Reply(msg->Record); \
+ break; \
+ }
+
+ REPLY_OPTION(TBusResponse)
+ REPLY_OPTION(TBusDbResponse)
+ REPLY_OPTION(TBusBsTestLoadResponse)
REPLY_OPTION(TBusNodeRegistrationResponse)
REPLY_OPTION(TBusCmsResponse)
REPLY_OPTION(TBusSqsResponse)
REPLY_OPTION(TBusS3ListingResponse)
REPLY_OPTION(TBusConsoleResponse)
-
- default:
- Y_FAIL("unexpected response type %" PRIu32, type);
- }
+
+ default:
+ Y_FAIL("unexpected response type %" PRIu32, type);
+ }
RequestContext = nullptr;
- }
-
- void SendReplyMove(NBus::TBusMessageAutoPtr response) override {
- SendReply(response.Get());
- }
-
+ }
+
+ void SendReplyMove(NBus::TBusMessageAutoPtr response) override {
+ SendReply(response.Get());
+ }
+
THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder() override;
-};
-
-TBusMessageContext::TBusMessageContext()
-{}
-
-TBusMessageContext::TBusMessageContext(const TBusMessageContext& other)
- : Impl(other.Impl)
-{}
-
-TBusMessageContext::TBusMessageContext(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher)
- : Impl(new TImplMessageBus(messageContext, messageWatcher))
-{}
-
-TBusMessageContext::TBusMessageContext(NGRpcProxy::IRequestContext *requestContext, int type)
- : Impl(new TImplGRpc(requestContext, type))
-{}
-
-TBusMessageContext::~TBusMessageContext()
-{}
-
-TBusMessageContext& TBusMessageContext::operator =(TBusMessageContext other) {
- Impl = std::move(other.Impl);
- return *this;
-}
-
-NBus::TBusMessage *TBusMessageContext::GetMessage() {
- Y_VERIFY(Impl);
- return Impl->GetMessage();
-}
-
-NBus::TBusMessage *TBusMessageContext::ReleaseMessage() {
- Y_VERIFY(Impl);
- return Impl->ReleaseMessage();
-}
-
-void TBusMessageContext::SendReplyMove(NBus::TBusMessageAutoPtr response) {
- Y_VERIFY(Impl);
- Impl->SendReplyMove(response);
-}
-
-void TBusMessageContext::Swap(TBusMessageContext &msg) {
- std::swap(Impl, msg.Impl);
-}
-
-THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::CreateSessionIdentHolder() {
- Y_VERIFY(Impl);
- return Impl->CreateSessionIdentHolder();
-}
-
-
-class TMessageBusSessionIdentHolder::TImpl {
-public:
- virtual ~TImpl() = default;
- virtual void SendReply(NBus::TBusMessage *resp) = 0;
- virtual void SendReplyMove(NBus::TBusMessageAutoPtr resp) = 0;
- virtual ui64 GetTotalTimeout() const = 0;
-};
-
-class TMessageBusSessionIdentHolder::TImplMessageBus
- : public TMessageBusSessionIdentHolder::TImpl
- , private TBusMessageWatcher
-{
- NBus::TBusServerSession *Session;
- NBus::TBusIdentity Ident;
-
-public:
- TImplMessageBus(NBus::TOnMessageContext &ctx) {
- Session = ctx.GetSession();
- ctx.AckMessage(Ident);
- }
-
- ~TImplMessageBus() {
- if (Session && Ident.IsInWork()) {
- NotifyForget();
- Session->ForgetRequest(Ident);
- }
- }
-
- void SendReply(NBus::TBusMessage *resp) override {
- NotifyReply(resp);
- Session->SendReply(Ident, resp);
- }
-
- void SendReplyMove(NBus::TBusMessageAutoPtr resp) override {
- NotifyReply(resp.Get());
- Session->SendReplyMove(Ident, resp);
- }
-
- NBus::TBusKey GetMessageId() override {
- return Ident.MessageId;
- }
-
- ui64 GetTotalTimeout() const override {
- return Session->GetConfig()->TotalTimeout;
- }
-};
-
+};
+
+TBusMessageContext::TBusMessageContext()
+{}
+
+TBusMessageContext::TBusMessageContext(const TBusMessageContext& other)
+ : Impl(other.Impl)
+{}
+
+TBusMessageContext::TBusMessageContext(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher)
+ : Impl(new TImplMessageBus(messageContext, messageWatcher))
+{}
+
+TBusMessageContext::TBusMessageContext(NGRpcProxy::IRequestContext *requestContext, int type)
+ : Impl(new TImplGRpc(requestContext, type))
+{}
+
+TBusMessageContext::~TBusMessageContext()
+{}
+
+TBusMessageContext& TBusMessageContext::operator =(TBusMessageContext other) {
+ Impl = std::move(other.Impl);
+ return *this;
+}
+
+NBus::TBusMessage *TBusMessageContext::GetMessage() {
+ Y_VERIFY(Impl);
+ return Impl->GetMessage();
+}
+
+NBus::TBusMessage *TBusMessageContext::ReleaseMessage() {
+ Y_VERIFY(Impl);
+ return Impl->ReleaseMessage();
+}
+
+void TBusMessageContext::SendReplyMove(NBus::TBusMessageAutoPtr response) {
+ Y_VERIFY(Impl);
+ Impl->SendReplyMove(response);
+}
+
+void TBusMessageContext::Swap(TBusMessageContext &msg) {
+ std::swap(Impl, msg.Impl);
+}
+
+THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::CreateSessionIdentHolder() {
+ Y_VERIFY(Impl);
+ return Impl->CreateSessionIdentHolder();
+}
+
+
+class TMessageBusSessionIdentHolder::TImpl {
+public:
+ virtual ~TImpl() = default;
+ virtual void SendReply(NBus::TBusMessage *resp) = 0;
+ virtual void SendReplyMove(NBus::TBusMessageAutoPtr resp) = 0;
+ virtual ui64 GetTotalTimeout() const = 0;
+};
+
+class TMessageBusSessionIdentHolder::TImplMessageBus
+ : public TMessageBusSessionIdentHolder::TImpl
+ , private TBusMessageWatcher
+{
+ NBus::TBusServerSession *Session;
+ NBus::TBusIdentity Ident;
+
+public:
+ TImplMessageBus(NBus::TOnMessageContext &ctx) {
+ Session = ctx.GetSession();
+ ctx.AckMessage(Ident);
+ }
+
+ ~TImplMessageBus() {
+ if (Session && Ident.IsInWork()) {
+ NotifyForget();
+ Session->ForgetRequest(Ident);
+ }
+ }
+
+ void SendReply(NBus::TBusMessage *resp) override {
+ NotifyReply(resp);
+ Session->SendReply(Ident, resp);
+ }
+
+ void SendReplyMove(NBus::TBusMessageAutoPtr resp) override {
+ NotifyReply(resp.Get());
+ Session->SendReplyMove(Ident, resp);
+ }
+
+ NBus::TBusKey GetMessageId() override {
+ return Ident.MessageId;
+ }
+
+ ui64 GetTotalTimeout() const override {
+ return Session->GetConfig()->TotalTimeout;
+ }
+};
+
THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::TImplMessageBus::CreateSessionIdentHolder() {
return MakeHolder<TMessageBusSessionIdentHolder::TImplMessageBus>(static_cast<NBus::TOnMessageContext&>(*this));
}
-class TMessageBusSessionIdentHolder::TImplGRpc
- : public TMessageBusSessionIdentHolder::TImpl
-{
- TIntrusivePtr<TBusMessageContext::TImplGRpc> Context;
-
-public:
- TImplGRpc(TIntrusivePtr<TBusMessageContext::TImplGRpc> context)
- : Context(context)
+class TMessageBusSessionIdentHolder::TImplGRpc
+ : public TMessageBusSessionIdentHolder::TImpl
+{
+ TIntrusivePtr<TBusMessageContext::TImplGRpc> Context;
+
+public:
+ TImplGRpc(TIntrusivePtr<TBusMessageContext::TImplGRpc> context)
+ : Context(context)
{
}
-
- ~TImplGRpc() {
- if (Context) {
- Context->ForgetRequest();
- }
- }
-
- void SendReply(NBus::TBusMessage *resp) override {
+
+ ~TImplGRpc() {
+ if (Context) {
+ Context->ForgetRequest();
+ }
+ }
+
+ void SendReply(NBus::TBusMessage *resp) override {
Y_VERIFY(Context);
Context->SendReply(resp);
auto context = std::move(Context);
- }
-
- void SendReplyMove(NBus::TBusMessageAutoPtr resp) override {
+ }
+
+ void SendReplyMove(NBus::TBusMessageAutoPtr resp) override {
Y_VERIFY(Context);
Context->SendReplyMove(resp);
auto context = std::move(Context);
- }
-
- ui64 GetTotalTimeout() const override {
- return 90000;
- }
-};
-
+ }
+
+ ui64 GetTotalTimeout() const override {
+ return 90000;
+ }
+};
+
THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::TImplGRpc::CreateSessionIdentHolder() {
return MakeHolder<TMessageBusSessionIdentHolder::TImplGRpc>(this);
}
@@ -333,34 +333,34 @@ THolder<TMessageBusSessionIdentHolder::TImpl> TBusMessageContext::TImplGRpc::Cre
TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder()
{}
-TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder(TBusMessageContext &msg)
-{
+TMessageBusSessionIdentHolder::TMessageBusSessionIdentHolder(TBusMessageContext &msg)
+{
InitSession(msg);
}
-TMessageBusSessionIdentHolder::~TMessageBusSessionIdentHolder()
-{}
-
-void TMessageBusSessionIdentHolder::InitSession(TBusMessageContext &msg) {
- Impl = msg.CreateSessionIdentHolder();
-}
-
-ui64 TMessageBusSessionIdentHolder::GetTotalTimeout() const {
- Y_VERIFY(Impl);
- return Impl->GetTotalTimeout();
-}
-
-void TMessageBusSessionIdentHolder::SendReply(NBus::TBusMessage *resp) {
- Y_VERIFY(Impl);
- Impl->SendReply(resp);
-}
-
-void TMessageBusSessionIdentHolder::SendReplyMove(NBus::TBusMessageAutoPtr resp) {
- Y_VERIFY(Impl);
- Impl->SendReplyMove(resp);
-}
-
-
+TMessageBusSessionIdentHolder::~TMessageBusSessionIdentHolder()
+{}
+
+void TMessageBusSessionIdentHolder::InitSession(TBusMessageContext &msg) {
+ Impl = msg.CreateSessionIdentHolder();
+}
+
+ui64 TMessageBusSessionIdentHolder::GetTotalTimeout() const {
+ Y_VERIFY(Impl);
+ return Impl->GetTotalTimeout();
+}
+
+void TMessageBusSessionIdentHolder::SendReply(NBus::TBusMessage *resp) {
+ Y_VERIFY(Impl);
+ Impl->SendReply(resp);
+}
+
+void TMessageBusSessionIdentHolder::SendReplyMove(NBus::TBusMessageAutoPtr resp) {
+ Y_VERIFY(Impl);
+ Impl->SendReplyMove(resp);
+}
+
+
void TBusMessageWatcher::NotifyForget() {
if (MessageWatcher) {
MessageWatcher->OnMessageDied(GetMessageId());
@@ -376,7 +376,7 @@ void TBusMessageWatcher::NotifyReply(NBus::TBusMessage *response) {
}
-
+
class TMessageBusMonitorActor : public TActorBootstrapped<TMessageBusMonitorActor> {
struct TEvPrivate {
enum EEv {
@@ -397,7 +397,7 @@ public:
, SessionConfig(sessionConfig)
{}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
void Bootstrap(const TActorContext &ctx) {
WhiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(ctx.SelfID.NodeId());
@@ -516,13 +516,13 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
case MTYPE_CLIENT_FLAT_TX_REQUEST:
return ClientProxyRequest<TEvBusProxy::TEvFlatTxRequest>(msg);
case MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST:
- return ClientActorRequest(CreateMessageBusSchemeOperationStatus, msg);
+ return ClientActorRequest(CreateMessageBusSchemeOperationStatus, msg);
case MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST:
case MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST:
return ClientProxyRequest<TEvBusProxy::TEvFlatDescribeRequest>(msg);
- case MTYPE_CLIENT_LOAD_REQUEST:
+ case MTYPE_CLIENT_LOAD_REQUEST:
return ClientActorRequest(CreateMessageBusBlobStorageLoadRequest, msg);
- case MTYPE_CLIENT_GET_REQUEST:
+ case MTYPE_CLIENT_GET_REQUEST:
return ClientActorRequest(CreateMessageBusBlobStorageGetRequest, msg);
case MTYPE_CLIENT_DB_SCHEMA:
return ClientProxyRequest<TEvBusProxy::TEvDbSchema>(msg);
@@ -530,8 +530,8 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
return ClientProxyRequest<TEvBusProxy::TEvDbOperation>(msg);
case MTYPE_CLIENT_DB_BATCH:
return ClientProxyRequest<TEvBusProxy::TEvDbBatch>(msg);
- case MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST:
- return ClientActorRequest(CreateMessageBusBlobStorageConfig, msg);
+ case MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST:
+ return ClientActorRequest(CreateMessageBusBlobStorageConfig, msg);
case MTYPE_CLIENT_DRAIN_NODE:
return ClientActorRequest(CreateMessageBusDrainNode, msg);
case MTYPE_CLIENT_FILL_NODE:
@@ -546,12 +546,12 @@ void TMessageBusServer::OnMessage(TBusMessageContext &msg) {
return ClientActorRequest(CreateMessageBusWhoAmI, msg);
case MTYPE_CLIENT_S3_LISTING_REQUEST:
return ClientActorRequest(CreateMessageBusS3ListingRequest, msg);
- case MTYPE_CLIENT_INTERCONNECT_DEBUG:
- return ClientActorRequest(CreateMessageBusInterconnectDebug, msg);
+ case MTYPE_CLIENT_INTERCONNECT_DEBUG:
+ return ClientActorRequest(CreateMessageBusInterconnectDebug, msg);
case MTYPE_CLIENT_CONSOLE_REQUEST:
return ClientActorRequest(CreateMessageBusConsoleRequest, msg);
- case MTYPE_CLIENT_TEST_SHARD_CONTROL:
- return ClientActorRequest(CreateMessageBusTestShardControl, msg);
+ case MTYPE_CLIENT_TEST_SHARD_CONTROL:
+ return ClientActorRequest(CreateMessageBusTestShardControl, msg);
default:
return UnknownMessage(msg);
}
@@ -580,7 +580,7 @@ void TMessageBusServer::ClientProxyRequest(TBusMessageContext &msg) {
void TMessageBusServer::ClientActorRequest(ActorCreationFunc func, TBusMessageContext &msg) {
if (IActor *x = func(msg))
ActorSystem->Register(x, TMailboxType::HTSwap, ActorSystem->AppData<TAppData>()->UserPoolId);
- else
+ else
msg.SendReplyMove(new TBusResponseStatus(MSTATUS_ERROR));
}
diff --git a/ydb/core/client/server/msgbus_server.h b/ydb/core/client/server/msgbus_server.h
index 3d40fc90017..cf62a394eb2 100644
--- a/ydb/core/client/server/msgbus_server.h
+++ b/ydb/core/client/server/msgbus_server.h
@@ -11,11 +11,11 @@ namespace NMonitoring {
}
namespace NKikimr {
-
-namespace NGRpcProxy {
- class IRequestContext;
-} // NGRpcProxy
-
+
+namespace NGRpcProxy {
+ class IRequestContext;
+} // NGRpcProxy
+
namespace NMsgBusProxy {
class IMessageWatcher {
@@ -37,57 +37,57 @@ protected:
virtual NBus::TBusKey GetMessageId() = 0;
};
-class TBusMessageContext;
-
-class TMessageBusSessionIdentHolder {
- class TImpl;
- THolder<TImpl> Impl;
-
- class TImplMessageBus;
- class TImplGRpc;
-
- // to create session
- friend class TBusMessageContext;
-
-protected:
- TMessageBusSessionIdentHolder();
- void InitSession(TBusMessageContext &msg);
- ui64 GetTotalTimeout() const;
-
+class TBusMessageContext;
+
+class TMessageBusSessionIdentHolder {
+ class TImpl;
+ THolder<TImpl> Impl;
+
+ class TImplMessageBus;
+ class TImplGRpc;
+
+ // to create session
+ friend class TBusMessageContext;
+
+protected:
+ TMessageBusSessionIdentHolder();
+ void InitSession(TBusMessageContext &msg);
+ ui64 GetTotalTimeout() const;
+
+public:
+ TMessageBusSessionIdentHolder(TBusMessageContext &msg);
+ ~TMessageBusSessionIdentHolder();
+ void SendReply(NBus::TBusMessage *resp);
+ void SendReplyMove(NBus::TBusMessageAutoPtr resp);
+
+ template <typename U /* <: TBusMessage */>
+ void SendReplyAutoPtr(TAutoPtr<U>& resp) { SendReplyMove(resp); }
+};
+
+class TBusMessageContext {
+ class TImpl;
+ TIntrusivePtr<TImpl> Impl;
+
+ class TImplMessageBus;
+ class TImplGRpc;
+
public:
- TMessageBusSessionIdentHolder(TBusMessageContext &msg);
- ~TMessageBusSessionIdentHolder();
- void SendReply(NBus::TBusMessage *resp);
- void SendReplyMove(NBus::TBusMessageAutoPtr resp);
-
- template <typename U /* <: TBusMessage */>
- void SendReplyAutoPtr(TAutoPtr<U>& resp) { SendReplyMove(resp); }
-};
-
-class TBusMessageContext {
- class TImpl;
- TIntrusivePtr<TImpl> Impl;
-
- class TImplMessageBus;
- class TImplGRpc;
-
-public:
- TBusMessageContext();
- TBusMessageContext(const TBusMessageContext& other);
+ TBusMessageContext();
+ TBusMessageContext(const TBusMessageContext& other);
TBusMessageContext(NBus::TOnMessageContext &messageContext, IMessageWatcher *messageWatcher = nullptr);
- TBusMessageContext(NGRpcProxy::IRequestContext *requestContext, int type);
+ TBusMessageContext(NGRpcProxy::IRequestContext *requestContext, int type);
~TBusMessageContext();
- TBusMessageContext& operator =(TBusMessageContext other);
-
- NBus::TBusMessage* GetMessage();
- NBus::TBusMessage* ReleaseMessage();
- void SendReplyMove(NBus::TBusMessageAutoPtr response);
- void Swap(TBusMessageContext& msg);
-
-private:
- friend class TMessageBusSessionIdentHolder;
- THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder();
+ TBusMessageContext& operator =(TBusMessageContext other);
+
+ NBus::TBusMessage* GetMessage();
+ NBus::TBusMessage* ReleaseMessage();
+ void SendReplyMove(NBus::TBusMessageAutoPtr response);
+ void Swap(TBusMessageContext& msg);
+
+private:
+ friend class TMessageBusSessionIdentHolder;
+ THolder<TMessageBusSessionIdentHolder::TImpl> CreateSessionIdentHolder();
};
struct TEvBusProxy {
@@ -293,11 +293,11 @@ IActor* CreateMessageBusPersQueue(TBusMessageContext &msg);
IActor* CreateMessageBusChooseProxy(TBusMessageContext &msg);
IActor* CreateMessageBusTabletStateRequest(TBusMessageContext &msg);
IActor* CreateMessageBusTabletKillRequest(TBusMessageContext &msg);
-IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg);
+IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg);
IActor* CreateMessageBusBlobStorageLoadRequest(TBusMessageContext &msg);
IActor* CreateMessageBusBlobStorageGetRequest(TBusMessageContext &msg);
IActor* CreateMessageBusHiveLookupTablet(TBusMessageContext &msg);
-IActor* CreateMessageBusBlobStorageConfig(TBusMessageContext &msg);
+IActor* CreateMessageBusBlobStorageConfig(TBusMessageContext &msg);
IActor* CreateMessageBusDrainNode(TBusMessageContext &msg);
IActor* CreateMessageBusFillNode(TBusMessageContext &msg);
IActor* CreateMessageBusResolveNode(TBusMessageContext &msg);
@@ -306,9 +306,9 @@ IActor* CreateMessageBusCmsRequest(TBusMessageContext &msg);
IActor* CreateMessageBusSqsRequest(TBusMessageContext &msg);
IActor* CreateMessageBusWhoAmI(TBusMessageContext &msg);
IActor* CreateMessageBusS3ListingRequest(TBusMessageContext& msg);
-IActor* CreateMessageBusInterconnectDebug(TBusMessageContext& msg);
+IActor* CreateMessageBusInterconnectDebug(TBusMessageContext& msg);
IActor* CreateMessageBusConsoleRequest(TBusMessageContext &msg);
-IActor* CreateMessageBusTestShardControl(TBusMessageContext &msg);
+IActor* CreateMessageBusTestShardControl(TBusMessageContext &msg);
TBusResponse* ProposeTransactionStatusToResponse(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result);
diff --git a/ydb/core/client/server/msgbus_server_cms.cpp b/ydb/core/client/server/msgbus_server_cms.cpp
index 53ada2a3fad..45423aecebd 100644
--- a/ydb/core/client/server/msgbus_server_cms.cpp
+++ b/ydb/core/client/server/msgbus_server_cms.cpp
@@ -22,8 +22,8 @@ class TCmsRequestActor : public TMessageBusSecureRequest<TMessageBusServerReques
using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TCmsRequestActor>>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TCmsRequestActor(NKikimrClient::TCmsRequest &request, NMsgBusProxy::TBusMessageContext &msg)
diff --git a/ydb/core/client/server/msgbus_server_console.cpp b/ydb/core/client/server/msgbus_server_console.cpp
index 66bc0b02ebe..c8c7283a660 100644
--- a/ydb/core/client/server/msgbus_server_console.cpp
+++ b/ydb/core/client/server/msgbus_server_console.cpp
@@ -22,8 +22,8 @@ class TConsoleRequestActor : public TMessageBusSecureRequest<TMessageBusServerRe
using TBase = TMessageBusSecureRequest<TMessageBusServerRequestBase<TConsoleRequestActor>>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TConsoleRequestActor(NKikimrClient::TConsoleRequest &request, NMsgBusProxy::TBusMessageContext &msg)
diff --git a/ydb/core/client/server/msgbus_server_db.cpp b/ydb/core/client/server/msgbus_server_db.cpp
index 08f3d717864..732afeea334 100644
--- a/ydb/core/client/server/msgbus_server_db.cpp
+++ b/ydb/core/client/server/msgbus_server_db.cpp
@@ -65,9 +65,9 @@ private:
public:
TMessageBusInterface(TBusMessageContext& msg)
- : TMessageBusSessionIdentHolder(msg)
- , Request(static_cast<RequestType*>(msg.ReleaseMessage()))
- {}
+ : TMessageBusSessionIdentHolder(msg)
+ , Request(static_cast<RequestType*>(msg.ReleaseMessage()))
+ {}
void ReplyWithErrorToInterface(EResponseStatus status, TEvTxUserProxy::TResultStatus::EStatus proxyStatus, const TString& message, const TActorContext&) {
TAutoPtr<TBusResponse> response(new TBusResponseStatus(status, message));
@@ -294,7 +294,7 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_COMMON; }
TServerDbOperation(TBusMessageContext& msg, TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
@@ -727,8 +727,8 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TServerDbSchema(TBusMessageContext &msg, TActorId txProxyId, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
@@ -981,8 +981,8 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TServerDbBatch(TBusMessageContext &msg, const TActorId txProxyId, const TActorId& schemeCache, const TIntrusivePtr<TMessageBusDbOpsCounters>& dbOperationsCounters);
diff --git a/ydb/core/client/server/msgbus_server_get.cpp b/ydb/core/client/server/msgbus_server_get.cpp
index 326de522b12..f03b4334031 100644
--- a/ydb/core/client/server/msgbus_server_get.cpp
+++ b/ydb/core/client/server/msgbus_server_get.cpp
@@ -1,85 +1,85 @@
-#include "msgbus_servicereq.h"
+#include "msgbus_servicereq.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TBsGetRequest : public TActorBootstrapped<TBsGetRequest>, public TMessageBusSessionIdentHolder {
- NKikimrClient::TBsGetRequest Request;
- NKikimrClient::TBsGetResponse Response;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
- }
-
- TBsGetRequest(NKikimrClient::TBsGetRequest& record, NMsgBusProxy::TBusMessageContext& msg)
- : TMessageBusSessionIdentHolder(msg)
- , Request(record)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- ui32 groupId = 0;
- if (!Request.HasGroupId()) {
- return IssueErrorResponse("GroupId field is not set", ctx);
- } else {
- groupId = Request.GetGroupId();
- }
-
- THolder<IEventBase> request;
-
- switch (Request.Query_case()) {
- case NKikimrClient::TBsGetRequest::kExtreme: {
- const TLogoBlobID id(LogoBlobIDFromLogoBlobID(Request.GetExtreme()));
- if (id != id.FullID()) {
- return IssueErrorResponse("LogoBlobId is not full one", ctx);
- }
- request.Reset(new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(), NKikimrBlobStorage::AsyncRead));
- break;
- }
-
- case NKikimrClient::TBsGetRequest::QUERY_NOT_SET:
- return IssueErrorResponse("Query field is not set", ctx);
- }
-
- SendToBSProxy(ctx, groupId, request.Release());
- Become(&TBsGetRequest::StateFunc);
- }
-
- void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev, const TActorContext& ctx) {
- TEvBlobStorage::TEvGetResult *msg = ev->Get();
- Response.SetStatus(msg->Status);
- if (msg->Status == NKikimrProto::OK && msg->ResponseSz == 1) {
- const TEvBlobStorage::TEvGetResult::TResponse& resp = msg->Responses[0];
- Response.SetStatus(resp.Status);
- Response.SetBuffer(resp.Buffer);
- }
- IssueResponse(ctx);
- }
-
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TBsGetRequest : public TActorBootstrapped<TBsGetRequest>, public TMessageBusSessionIdentHolder {
+ NKikimrClient::TBsGetRequest Request;
+ NKikimrClient::TBsGetResponse Response;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
+ }
+
+ TBsGetRequest(NKikimrClient::TBsGetRequest& record, NMsgBusProxy::TBusMessageContext& msg)
+ : TMessageBusSessionIdentHolder(msg)
+ , Request(record)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ ui32 groupId = 0;
+ if (!Request.HasGroupId()) {
+ return IssueErrorResponse("GroupId field is not set", ctx);
+ } else {
+ groupId = Request.GetGroupId();
+ }
+
+ THolder<IEventBase> request;
+
+ switch (Request.Query_case()) {
+ case NKikimrClient::TBsGetRequest::kExtreme: {
+ const TLogoBlobID id(LogoBlobIDFromLogoBlobID(Request.GetExtreme()));
+ if (id != id.FullID()) {
+ return IssueErrorResponse("LogoBlobId is not full one", ctx);
+ }
+ request.Reset(new TEvBlobStorage::TEvGet(id, 0, 0, TInstant::Max(), NKikimrBlobStorage::AsyncRead));
+ break;
+ }
+
+ case NKikimrClient::TBsGetRequest::QUERY_NOT_SET:
+ return IssueErrorResponse("Query field is not set", ctx);
+ }
+
+ SendToBSProxy(ctx, groupId, request.Release());
+ Become(&TBsGetRequest::StateFunc);
+ }
+
+ void Handle(TEvBlobStorage::TEvGetResult::TPtr& ev, const TActorContext& ctx) {
+ TEvBlobStorage::TEvGetResult *msg = ev->Get();
+ Response.SetStatus(msg->Status);
+ if (msg->Status == NKikimrProto::OK && msg->ResponseSz == 1) {
+ const TEvBlobStorage::TEvGetResult::TResponse& resp = msg->Responses[0];
+ Response.SetStatus(resp.Status);
+ Response.SetBuffer(resp.Buffer);
+ }
+ IssueResponse(ctx);
+ }
+
void IssueErrorResponse(TString message, const TActorContext& ctx) {
- Response.SetErrorDescription(message);
- IssueResponse(ctx);
- }
-
- void IssueResponse(const TActorContext& ctx) {
- auto response = MakeHolder<TBusBsGetResponse>();
- response->Record = Response;
- SendReplyMove(response.Release());
- Die(ctx);
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvBlobStorage::TEvGetResult, Handle);
- }
- }
-};
-
+ Response.SetErrorDescription(message);
+ IssueResponse(ctx);
+ }
+
+ void IssueResponse(const TActorContext& ctx) {
+ auto response = MakeHolder<TBusBsGetResponse>();
+ response->Record = Response;
+ SendReplyMove(response.Release());
+ Die(ctx);
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvBlobStorage::TEvGetResult, Handle);
+ }
+ }
+};
+
IActor *CreateMessageBusBlobStorageGetRequest(NMsgBusProxy::TBusMessageContext& msg) {
- NKikimrClient::TBsGetRequest& record = static_cast<TBusBsGetRequest *>(msg.GetMessage())->Record;
- return new TBsGetRequest(record, msg);
-}
-
-} // NMsgBusProxy
-} // NKikimr
+ NKikimrClient::TBsGetRequest& record = static_cast<TBusBsGetRequest *>(msg.GetMessage())->Record;
+ return new TBsGetRequest(record, msg);
+}
+
+} // NMsgBusProxy
+} // NKikimr
diff --git a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
index 0c41e53f090..2732cfcdd28 100644
--- a/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
+++ b/ydb/core/client/server/msgbus_server_hive_create_tablet.cpp
@@ -65,8 +65,8 @@ using TBase = TActorBootstrapped<TMessageBusHiveCreateTablet<ResponseType>>;
ui32 DomainUid;
TString ErrorReason;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TMessageBusHiveCreateTablet(TBusMessageContext &msg)
diff --git a/ydb/core/client/server/msgbus_server_ic_debug.cpp b/ydb/core/client/server/msgbus_server_ic_debug.cpp
index 7757757fee6..b778c5d5555 100644
--- a/ydb/core/client/server/msgbus_server_ic_debug.cpp
+++ b/ydb/core/client/server/msgbus_server_ic_debug.cpp
@@ -1,93 +1,93 @@
-#include "msgbus_servicereq.h"
+#include "msgbus_servicereq.h"
#include <library/cpp/actors/interconnect/load.h>
#include <library/cpp/actors/interconnect/slowpoke_actor.h>
#include <library/cpp/actors/core/interconnect.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TInterconnectDebugActor : public TActorBootstrapped<TInterconnectDebugActor>, public TMessageBusSessionIdentHolder {
- std::function<void(const TActorContext&)> Callback;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
- }
-
- TInterconnectDebugActor(NKikimrClient::TInterconnectDebug& record, NMsgBusProxy::TBusMessageContext& msg)
- : TMessageBusSessionIdentHolder(msg)
- {
- if (record.HasNumSlowpokeActors()) {
- const ui32 num = record.GetNumSlowpokeActors();
- const ui32 poolId = record.GetPoolId();
- const TDuration sleepMin = TDuration::FromValue(record.GetSleepMin());
- const TDuration sleepMax = TDuration::FromValue(record.GetSleepMax());
- const TDuration rescheduleMin = TDuration::FromValue(record.GetRescheduleMin());
- const TDuration rescheduleMax = TDuration::FromValue(record.GetRescheduleMax());
- const TDuration duration = TDuration::FromValue(record.GetDuration());
- Callback = [=](const TActorContext& ctx) {
- for (ui32 i = 0; i < num; ++i) {
- ctx.Register(new TSlowpokeActor(duration, sleepMin, sleepMax, rescheduleMin, rescheduleMax),
- TMailboxType::HTSwap, poolId);
- }
- };
- } else if (record.HasPoisonSessionNodeId()) {
- const ui32 nodeId = record.GetPoisonSessionNodeId();
- Callback = [=](const TActorContext& ctx) {
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TInterconnectDebugActor : public TActorBootstrapped<TInterconnectDebugActor>, public TMessageBusSessionIdentHolder {
+ std::function<void(const TActorContext&)> Callback;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
+ }
+
+ TInterconnectDebugActor(NKikimrClient::TInterconnectDebug& record, NMsgBusProxy::TBusMessageContext& msg)
+ : TMessageBusSessionIdentHolder(msg)
+ {
+ if (record.HasNumSlowpokeActors()) {
+ const ui32 num = record.GetNumSlowpokeActors();
+ const ui32 poolId = record.GetPoolId();
+ const TDuration sleepMin = TDuration::FromValue(record.GetSleepMin());
+ const TDuration sleepMax = TDuration::FromValue(record.GetSleepMax());
+ const TDuration rescheduleMin = TDuration::FromValue(record.GetRescheduleMin());
+ const TDuration rescheduleMax = TDuration::FromValue(record.GetRescheduleMax());
+ const TDuration duration = TDuration::FromValue(record.GetDuration());
+ Callback = [=](const TActorContext& ctx) {
+ for (ui32 i = 0; i < num; ++i) {
+ ctx.Register(new TSlowpokeActor(duration, sleepMin, sleepMax, rescheduleMin, rescheduleMax),
+ TMailboxType::HTSwap, poolId);
+ }
+ };
+ } else if (record.HasPoisonSessionNodeId()) {
+ const ui32 nodeId = record.GetPoisonSessionNodeId();
+ Callback = [=](const TActorContext& ctx) {
ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvPoisonSession);
- };
- } else if (record.HasCloseInputSessionNodeId()) {
- const ui32 nodeId = record.GetCloseInputSessionNodeId();
- Callback = [=](const TActorContext& ctx) {
+ };
+ } else if (record.HasCloseInputSessionNodeId()) {
+ const ui32 nodeId = record.GetCloseInputSessionNodeId();
+ Callback = [=](const TActorContext& ctx) {
ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvCloseInputSession);
- };
- } else if (record.HasClosePeerSocketNodeId()) {
- const ui32 nodeId = record.GetClosePeerSocketNodeId();
- Callback = [=](const TActorContext& ctx) {
+ };
+ } else if (record.HasClosePeerSocketNodeId()) {
+ const ui32 nodeId = record.GetClosePeerSocketNodeId();
+ Callback = [=](const TActorContext& ctx) {
ctx.Send(TActivationContext::InterconnectProxy(nodeId), new NActors::TEvInterconnect::TEvClosePeerSocket);
- };
- } else {
- NInterconnect::TLoadParams params;
- params.Name = record.GetName();
- params.Channel = record.GetChannel();
- const auto &hops = record.GetHops();
- params.NodeHops = {hops.begin(), hops.end()};
- params.SizeMin = record.GetSizeMin();
- params.SizeMax = record.GetSizeMax();
- params.InFlyMax = record.GetInFlyMax();
+ };
+ } else {
+ NInterconnect::TLoadParams params;
+ params.Name = record.GetName();
+ params.Channel = record.GetChannel();
+ const auto &hops = record.GetHops();
+ params.NodeHops = {hops.begin(), hops.end()};
+ params.SizeMin = record.GetSizeMin();
+ params.SizeMax = record.GetSizeMax();
+ params.InFlyMax = record.GetInFlyMax();
params.IntervalMin = TDuration::MicroSeconds(record.GetIntervalMin());
params.IntervalMax = TDuration::MicroSeconds(record.GetIntervalMax());
- params.SoftLoad = record.GetSoftLoad();
+ params.SoftLoad = record.GetSoftLoad();
params.Duration = TDuration::MicroSeconds(record.GetDuration());
- params.UseProtobufWithPayload = record.GetUseProtobufWithPayload();
- Callback = [=](const TActorContext& ctx) {
- ui32 poolId = 0;
- if (record.HasServicePool()) {
- auto *appData = AppData(ctx);
- if (const auto it = appData->ServicePools.find(record.GetServicePool()); it != appData->ServicePools.end()) {
- poolId = it->second;
- }
- }
- ctx.Register(NInterconnect::CreateLoadActor(params), TMailboxType::HTSwap, poolId);
- };
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- Callback(ctx);
-
- auto response = MakeHolder<TBusResponse>();
- response->Record.SetStatus(MSTATUS_OK);
- SendReplyMove(response.Release());
-
- Die(ctx);
- }
-};
-
-IActor *CreateMessageBusInterconnectDebug(NMsgBusProxy::TBusMessageContext& msg) {
- NKikimrClient::TInterconnectDebug& record = static_cast<TBusInterconnectDebug *>(msg.GetMessage())->Record;
- return new TInterconnectDebugActor(record, msg);
-}
-
-} // NMsgBusProxy
-} // NKikimr
+ params.UseProtobufWithPayload = record.GetUseProtobufWithPayload();
+ Callback = [=](const TActorContext& ctx) {
+ ui32 poolId = 0;
+ if (record.HasServicePool()) {
+ auto *appData = AppData(ctx);
+ if (const auto it = appData->ServicePools.find(record.GetServicePool()); it != appData->ServicePools.end()) {
+ poolId = it->second;
+ }
+ }
+ ctx.Register(NInterconnect::CreateLoadActor(params), TMailboxType::HTSwap, poolId);
+ };
+ }
+ }
+
+ void Bootstrap(const TActorContext& ctx) {
+ Callback(ctx);
+
+ auto response = MakeHolder<TBusResponse>();
+ response->Record.SetStatus(MSTATUS_OK);
+ SendReplyMove(response.Release());
+
+ Die(ctx);
+ }
+};
+
+IActor *CreateMessageBusInterconnectDebug(NMsgBusProxy::TBusMessageContext& msg) {
+ NKikimrClient::TInterconnectDebug& record = static_cast<TBusInterconnectDebug *>(msg.GetMessage())->Record;
+ return new TInterconnectDebugActor(record, msg);
+}
+
+} // NMsgBusProxy
+} // NKikimr
diff --git a/ydb/core/client/server/msgbus_server_keyvalue.cpp b/ydb/core/client/server/msgbus_server_keyvalue.cpp
index ad644f4c269..bb76153b6c7 100644
--- a/ydb/core/client/server/msgbus_server_keyvalue.cpp
+++ b/ydb/core/client/server/msgbus_server_keyvalue.cpp
@@ -11,10 +11,10 @@ namespace {
template <typename ResponseType>
class TMessageBusKeyValue
- : public TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST> {
- using TBase = TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST>;
+ : public TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST> {
+ using TBase = TMessageBusSimpleTabletRequest<TMessageBusKeyValue<ResponseType>, TEvKeyValue::TEvResponse, NKikimrServices::TActivity::FRONT_KV_REQUEST>;
public:
- NKikimrClient::TKeyValueRequest RequestProto;
+ NKikimrClient::TKeyValueRequest RequestProto;
ui64 TabletId;
TMessageBusKeyValue(TBusMessageContext &msg, ui64 tabletId, bool withRetry, TDuration timeout)
diff --git a/ydb/core/client/server/msgbus_server_load.cpp b/ydb/core/client/server/msgbus_server_load.cpp
index 4c9bee8ea0a..bfea82f1020 100644
--- a/ydb/core/client/server/msgbus_server_load.cpp
+++ b/ydb/core/client/server/msgbus_server_load.cpp
@@ -1,77 +1,77 @@
-#include "msgbus_servicereq.h"
+#include "msgbus_servicereq.h"
#include <ydb/core/blobstorage/base/blobstorage_events.h>
-
-namespace NKikimr {
-namespace NMsgBusProxy {
-
-class TBsTestLoadActorRequest : public TActorBootstrapped<TBsTestLoadActorRequest>, public TMessageBusSessionIdentHolder {
+
+namespace NKikimr {
+namespace NMsgBusProxy {
+
+class TBsTestLoadActorRequest : public TActorBootstrapped<TBsTestLoadActorRequest>, public TMessageBusSessionIdentHolder {
TVector<ui32> NodeIds;
- NKikimrBlobStorage::TEvTestLoadRequest Cmd;
- NKikimrClient::TBsTestLoadResponse Response;
- ui32 ResponsesPending;
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ NKikimrBlobStorage::TEvTestLoadRequest Cmd;
+ NKikimrClient::TBsTestLoadResponse Response;
+ ui32 ResponsesPending;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
- TBsTestLoadActorRequest(NKikimrClient::TBsTestLoadRequest& record, NMsgBusProxy::TBusMessageContext& msg)
- : TMessageBusSessionIdentHolder(msg)
- , NodeIds(record.GetNodeId().begin(), record.GetNodeId().end())
- , Cmd(record.GetEvent())
- , ResponsesPending(0)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- for (ui32 nodeId : NodeIds) {
- auto msg = MakeHolder<TEvBlobStorage::TEvTestLoadRequest>();
- msg->Record = Cmd;
- msg->Record.SetCookie(nodeId);
- ctx.Send(MakeBlobStorageLoadID(nodeId), msg.Release());
- ++ResponsesPending;
- }
+ TBsTestLoadActorRequest(NKikimrClient::TBsTestLoadRequest& record, NMsgBusProxy::TBusMessageContext& msg)
+ : TMessageBusSessionIdentHolder(msg)
+ , NodeIds(record.GetNodeId().begin(), record.GetNodeId().end())
+ , Cmd(record.GetEvent())
+ , ResponsesPending(0)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ for (ui32 nodeId : NodeIds) {
+ auto msg = MakeHolder<TEvBlobStorage::TEvTestLoadRequest>();
+ msg->Record = Cmd;
+ msg->Record.SetCookie(nodeId);
+ ctx.Send(MakeBlobStorageLoadID(nodeId), msg.Release());
+ ++ResponsesPending;
+ }
TVector<ui32>().swap(NodeIds);
- Become(&TBsTestLoadActorRequest::StateFunc);
- CheckResponse(ctx);
- }
-
- void Handle(TEvBlobStorage::TEvTestLoadResponse::TPtr& ev, const TActorContext& ctx) {
- const auto& record = ev->Get()->Record;
- ui32 nodeId = record.GetCookie();
- --ResponsesPending;
-
- NKikimrClient::TBsTestLoadResponse::TItem *item = Response.AddItems();
- item->SetNodeId(nodeId);
- if (record.HasStatus()) {
- item->SetStatus(record.GetStatus());
- }
- if (record.HasErrorReason()) {
- item->SetErrorReason(record.GetErrorReason());
- }
-
- CheckResponse(ctx);
- }
-
- void CheckResponse(const TActorContext& ctx) {
- if (!ResponsesPending) {
- auto response = MakeHolder<TBusBsTestLoadResponse>();
- response->Record = Response;
- SendReplyMove(response.Release());
- Die(ctx);
- }
- }
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvBlobStorage::TEvTestLoadResponse, Handle);
- }
- }
-};
-
+ Become(&TBsTestLoadActorRequest::StateFunc);
+ CheckResponse(ctx);
+ }
+
+ void Handle(TEvBlobStorage::TEvTestLoadResponse::TPtr& ev, const TActorContext& ctx) {
+ const auto& record = ev->Get()->Record;
+ ui32 nodeId = record.GetCookie();
+ --ResponsesPending;
+
+ NKikimrClient::TBsTestLoadResponse::TItem *item = Response.AddItems();
+ item->SetNodeId(nodeId);
+ if (record.HasStatus()) {
+ item->SetStatus(record.GetStatus());
+ }
+ if (record.HasErrorReason()) {
+ item->SetErrorReason(record.GetErrorReason());
+ }
+
+ CheckResponse(ctx);
+ }
+
+ void CheckResponse(const TActorContext& ctx) {
+ if (!ResponsesPending) {
+ auto response = MakeHolder<TBusBsTestLoadResponse>();
+ response->Record = Response;
+ SendReplyMove(response.Release());
+ Die(ctx);
+ }
+ }
+
+ STFUNC(StateFunc) {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvBlobStorage::TEvTestLoadResponse, Handle);
+ }
+ }
+};
+
IActor *CreateMessageBusBlobStorageLoadRequest(NMsgBusProxy::TBusMessageContext& msg) {
- NKikimrClient::TBsTestLoadRequest& record = static_cast<TBusBsTestLoadRequest *>(msg.GetMessage())->Record;
- return new TBsTestLoadActorRequest(record, msg);
-}
-
-} // NMsgBusProxy
-} // NKikimr
+ NKikimrClient::TBsTestLoadRequest& record = static_cast<TBusBsTestLoadRequest *>(msg.GetMessage())->Record;
+ return new TBsTestLoadActorRequest(record, msg);
+}
+
+} // NMsgBusProxy
+} // NKikimr
diff --git a/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp b/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
index 9f867dddc7c..93b5c0a6d1a 100644
--- a/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
+++ b/ydb/core/client/server/msgbus_server_local_enumerate_tablets.cpp
@@ -9,8 +9,8 @@ namespace {
}
template <typename ResponseType>
-class TMessageBusLocalEnumerateTablets: public TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS> {
- using TBase = TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS>;
+class TMessageBusLocalEnumerateTablets: public TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS> {
+ using TBase = TMessageBusLocalServiceRequest<TMessageBusLocalEnumerateTablets<ResponseType>, NKikimrServices::TActivity::FRONT_ENUMERATE_TABLETS>;
ui64 DomainUid;
ui32 NodeId;
TTabletTypes::EType TabletType;
diff --git a/ydb/core/client/server/msgbus_server_local_minikql.cpp b/ydb/core/client/server/msgbus_server_local_minikql.cpp
index 42fa4ed9a83..4eba74490a6 100644
--- a/ydb/core/client/server/msgbus_server_local_minikql.cpp
+++ b/ydb/core/client/server/msgbus_server_local_minikql.cpp
@@ -8,8 +8,8 @@ namespace {
const ui64 DefaultTimeout = 90000;
}
-class TMessageBusLocalMKQL : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalMKQL, TEvTablet::TEvLocalMKQLResponse, NKikimrServices::TActivity::FRONT_LOCAL_MQKL>> {
- const NKikimrClient::TLocalMKQL Request;
+class TMessageBusLocalMKQL : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalMKQL, TEvTablet::TEvLocalMKQLResponse, NKikimrServices::TActivity::FRONT_LOCAL_MQKL>> {
+ const NKikimrClient::TLocalMKQL Request;
public:
TMessageBusLocalMKQL(TBusMessageContext &msg, const NKikimrClient::TLocalMKQL &request, ui64 tabletId, bool withRetry, TDuration timeout, bool connectToFollower)
: TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, connectToFollower)
diff --git a/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp b/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
index c1eed46ef99..fdfef31dd59 100644
--- a/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
+++ b/ydb/core/client/server/msgbus_server_local_scheme_tx.cpp
@@ -9,10 +9,10 @@ namespace {
}
class TMessageBusLocalSchemeTx : public TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
- TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>> {
+ TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>> {
using TBase = TMessageBusSecureRequest<TMessageBusSimpleTabletRequest<TMessageBusLocalSchemeTx,
- TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>>;
- NKikimrClient::TLocalSchemeTx Request;
+ TEvTablet::TEvLocalSchemeTxResponse, NKikimrServices::TActivity::FRONT_LOCAL_TXRQ>>;
+ NKikimrClient::TLocalSchemeTx Request;
public:
TMessageBusLocalSchemeTx(TBusMessageContext &msg, NKikimrClient::TLocalSchemeTx &request, ui64 tabletId, bool withRetry, TDuration timeout, bool connectToFollower)
: TMessageBusSecureRequest(msg, tabletId, withRetry, timeout, connectToFollower)
diff --git a/ydb/core/client/server/msgbus_server_node_registration.cpp b/ydb/core/client/server/msgbus_server_node_registration.cpp
index a3dda6092d0..ca25327aa14 100644
--- a/ydb/core/client/server/msgbus_server_node_registration.cpp
+++ b/ydb/core/client/server/msgbus_server_node_registration.cpp
@@ -21,8 +21,8 @@ class TNodeRegistrationActor : public TActorBootstrapped<TNodeRegistrationActor>
using TActorBase = TActorBootstrapped<TNodeRegistrationActor>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TNodeRegistrationActor(NKikimrClient::TNodeRegistrationRequest &request, NMsgBusProxy::TBusMessageContext &msg)
@@ -68,9 +68,9 @@ public:
request->Record.SetAddress(Request.GetAddress());
request->Record.MutableLocation()->CopyFrom(Request.GetLocation());
request->Record.SetFixedNodeId(Request.GetFixedNodeId());
- if (Request.HasPath()) {
- request->Record.SetPath(Request.GetPath());
- }
+ if (Request.HasPath()) {
+ request->Record.SetPath(Request.GetPath());
+ }
NTabletPipe::SendData(ctx, NodeBrokerPipe, request.Release());
Become(&TNodeRegistrationActor::MainState);
@@ -90,13 +90,13 @@ public:
Response.SetDomainPath(Request.GetDomainPath());
Response.AddNodes()->CopyFrom(rec.GetNode());
- if (rec.HasScopeTabletId()) {
- Response.SetScopeTabletId(rec.GetScopeTabletId());
- }
- if (rec.HasScopePathId()) {
- Response.SetScopePathId(rec.GetScopePathId());
- }
-
+ if (rec.HasScopeTabletId()) {
+ Response.SetScopeTabletId(rec.GetScopeTabletId());
+ }
+ if (rec.HasScopePathId()) {
+ Response.SetScopePathId(rec.GetScopePathId());
+ }
+
const TActorId nameserviceId = GetNameserviceActorId();
ctx.Send(nameserviceId, new TEvInterconnect::TEvListNodes());
}
@@ -114,7 +114,7 @@ public:
info.SetAddress(node.Address);
info.SetResolveHost(node.ResolveHost);
info.SetPort(node.Port);
- node.Location.Serialize(info.MutableLocation());
+ node.Location.Serialize(info.MutableLocation());
}
}
diff --git a/ydb/core/client/server/msgbus_server_persqueue.cpp b/ydb/core/client/server/msgbus_server_persqueue.cpp
index 78b83ef3a3b..ef5a8fd9f0b 100644
--- a/ydb/core/client/server/msgbus_server_persqueue.cpp
+++ b/ydb/core/client/server/msgbus_server_persqueue.cpp
@@ -436,7 +436,7 @@ class TMessageBusServerPersQueueImpl : public TActorBootstrapped<TMessageBusServ
using TEvAllTopicsDescribeResponse = NMsgBusProxy::NPqMetaCacheV2::TEvPqNewMetaCache::TEvDescribeAllTopicsResponse;
protected:
- NKikimrClient::TPersQueueRequest RequestProto;
+ NKikimrClient::TPersQueueRequest RequestProto;
const TString RequestId;
const bool IsMetaRequest;
const bool IsFetchRequest;
@@ -446,7 +446,7 @@ protected:
ui64 FetchRequestCurrentReadTablet; //if zero then no read at this time
ui64 CurrentCookie;
ui32 FetchRequestBytesLeft;
- NKikimrClient::TPersQueueFetchResponse FetchResponse;
+ NKikimrClient::TPersQueueFetchResponse FetchResponse;
TVector<TActorId> PQClient;
const TActorId SchemeCache;
@@ -465,8 +465,8 @@ protected:
bool NoTopicsAtStart;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR;
}
virtual ~TMessageBusServerPersQueueImpl() {}
@@ -1380,8 +1380,8 @@ public:
SendReplyAndDie(CreateErrorReply(MSTATUS_ERROR, NPersQueue::NErrorCode::BAD_REQUEST, ErrorText), ctx);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
}
TString ErrorText;
diff --git a/ydb/core/client/server/msgbus_server_persqueue.h b/ydb/core/client/server/msgbus_server_persqueue.h
index 52c67832e4e..3e0e4dfa77f 100644
--- a/ydb/core/client/server/msgbus_server_persqueue.h
+++ b/ydb/core/client/server/msgbus_server_persqueue.h
@@ -96,8 +96,8 @@ public:
std::deque<THolder<TPerTopicInfo>> ChildrenToCreate;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
}
protected:
@@ -176,8 +176,8 @@ protected:
public:
void Bootstrap(const TActorContext& ctx);
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PQ_BASE_REQUEST_PROCESSOR;
}
};
diff --git a/ydb/core/client/server/msgbus_server_pq_metarequest.cpp b/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
index 32f37251cc5..9af356995c3 100644
--- a/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
+++ b/ydb/core/client/server/msgbus_server_pq_metarequest.cpp
@@ -49,7 +49,7 @@ TPersQueueGetTopicMetadataTopicWorker::TPersQueueGetTopicMetadataTopicWorker(
)
: TReplierToParent<TTopicInfoBasedActor>(parent, topicEntry, name)
{
- SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
+ SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
}
@@ -108,7 +108,7 @@ TPersQueueGetPartitionOffsetsTopicWorker::TPersQueueGetPartitionOffsetsTopicWork
, PartitionsToRequest(partitionsToRequest)
, RequestProto(requestProto)
{
- SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
+ SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
}
void TPersQueueGetPartitionOffsetsTopicWorker::BootstrapImpl(const TActorContext &ctx) {
@@ -221,7 +221,7 @@ TPersQueueGetPartitionStatusTopicWorker::TPersQueueGetPartitionStatusTopicWorker
, PartitionsToRequest(partitionsToRequest)
, RequestProto(requestProto)
{
- SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
+ SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
}
void TPersQueueGetPartitionStatusTopicWorker::BootstrapImpl(const TActorContext &ctx) {
@@ -345,7 +345,7 @@ TPersQueueGetPartitionLocationsTopicWorker::TPersQueueGetPartitionLocationsTopic
, RequestProto(requestProto)
, NodesInfo(nodesInfo)
{
- SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
+ SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
}
void TPersQueueGetPartitionLocationsTopicWorker::BootstrapImpl(const TActorContext& ctx) {
@@ -475,7 +475,7 @@ TPersQueueGetReadSessionsInfoTopicWorker::TPersQueueGetReadSessionsInfoTopicWork
, RequestProto(requestProto)
, NodesInfo(nodesInfo)
{
- SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
+ SetActivityType(NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR);
}
void TPersQueueGetReadSessionsInfoTopicWorker::Die(const TActorContext& ctx) {
diff --git a/ydb/core/client/server/msgbus_server_pq_metarequest_ut.cpp b/ydb/core/client/server/msgbus_server_pq_metarequest_ut.cpp
index 237bba147b9..b4a80fed460 100644
--- a/ydb/core/client/server/msgbus_server_pq_metarequest_ut.cpp
+++ b/ydb/core/client/server/msgbus_server_pq_metarequest_ut.cpp
@@ -384,7 +384,7 @@ protected:
for (const TActorId& actorId : TestActors) {
IActor* actor = Runtime->FindActor(actorId);
if (actor != nullptr) {
- const bool isPipe = actor->ActivityType == NKikimrServices::TActivity::TABLET_PIPE_CLIENT;
+ const bool isPipe = actor->ActivityType == NKikimrServices::TActivity::TABLET_PIPE_CLIENT;
if (isPipe) {
UNIT_ASSERT_C(IsIn(destroyedActors, actorId),
"Pipe client was not destroyed after test actor worked. Pipe client actor id: " << actorId);
diff --git a/ydb/core/client/server/msgbus_server_proxy.cpp b/ydb/core/client/server/msgbus_server_proxy.cpp
index 7f3146d21a7..ed3ef55e3d5 100644
--- a/ydb/core/client/server/msgbus_server_proxy.cpp
+++ b/ydb/core/client/server/msgbus_server_proxy.cpp
@@ -60,7 +60,7 @@ class TMessageBusServerFlatDescribeRequest : public TMessageBusSecureRequest<TMe
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_DESCRIBE; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_DESCRIBE; }
TMessageBusServerFlatDescribeRequest(TEvBusProxy::TEvFlatDescribeRequest* msg)
: TBase(msg->MsgContext)
@@ -178,14 +178,14 @@ void TMessageBusServerProxy::Bootstrap(const TActorContext& ctx) {
SchemeCache = ctx.ExecutorThread.RegisterActor(CreateSchemeBoardSchemeCache(cacheConfig.Get()));
PqMetaCache = CreatePersQueueMetaCacheV2Id();
- if (Server) {
- Server->InitSession(ctx.ExecutorThread.ActorSystem, ctx.SelfID);
- }
-
- if (Server) {
- if (auto *busMonPage = AppData(ctx)->BusMonPage)
- Server->RegisterMonPage(busMonPage);
- }
+ if (Server) {
+ Server->InitSession(ctx.ExecutorThread.ActorSystem, ctx.SelfID);
+ }
+
+ if (Server) {
+ if (auto *busMonPage = AppData(ctx)->BusMonPage)
+ Server->RegisterMonPage(busMonPage);
+ }
Become(&TThis::StateFunc);
}
diff --git a/ydb/core/client/server/msgbus_server_proxy.h b/ydb/core/client/server/msgbus_server_proxy.h
index cb9f9c19d38..86caea4f30c 100644
--- a/ydb/core/client/server/msgbus_server_proxy.h
+++ b/ydb/core/client/server/msgbus_server_proxy.h
@@ -57,8 +57,8 @@ private:
void Handle(TEvBusProxy::TEvInitRoot::TPtr &ev, const TActorContext &ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR;
}
TMessageBusServerProxy(
@@ -71,9 +71,9 @@ public:
}
~TMessageBusServerProxy() {
- if (Server) {
- Server->ShutdownSession();
- }
+ if (Server) {
+ Server->ShutdownSession();
+ }
}
void Bootstrap(const TActorContext &ctx);
diff --git a/ydb/core/client/server/msgbus_server_request.cpp b/ydb/core/client/server/msgbus_server_request.cpp
index 9223bea9f1a..4db3262a1ec 100644
--- a/ydb/core/client/server/msgbus_server_request.cpp
+++ b/ydb/core/client/server/msgbus_server_request.cpp
@@ -42,8 +42,8 @@ class TMessageBusServerRequest : public TMessageBusSecureRequest<TMessageBusServ
bool AllRequestsCompletedReadTable(const TActorContext& ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FRONT_MKQL_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FRONT_MKQL_REQUEST;
}
TMessageBusServerRequest(TEvBusProxy::TEvRequest* msg)
@@ -82,7 +82,7 @@ public:
if (Request->Record.HasExecTimeoutPeriod())
record.SetExecTimeoutPeriod(Request->Record.GetExecTimeoutPeriod());
else {
- ui64 msgBusTimeout = GetTotalTimeout() * 3 / 4;
+ ui64 msgBusTimeout = GetTotalTimeout() * 3 / 4;
if (msgBusTimeout > 3600000) // when we see something weird - rewrite with somewhat meaningful
msgBusTimeout = 1800000;
record.SetExecTimeoutPeriod(msgBusTimeout);
diff --git a/ydb/core/client/server/msgbus_server_request.h b/ydb/core/client/server/msgbus_server_request.h
index b77d50983e6..d6a74afb612 100644
--- a/ydb/core/client/server/msgbus_server_request.h
+++ b/ydb/core/client/server/msgbus_server_request.h
@@ -10,7 +10,7 @@ namespace NMsgBusProxy {
template <typename TDerived>
class TMessageBusServerRequestBase : public TActorBootstrapped<TDerived>, public TMessageBusSessionIdentHolder {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::MSGBUS_PROXY_ACTOR; }
TMessageBusServerRequestBase(TBusMessageContext &msg) {
InitSession(msg);
diff --git a/ydb/core/client/server/msgbus_server_resolve_node.cpp b/ydb/core/client/server/msgbus_server_resolve_node.cpp
index 762df383cb8..37622ef96b4 100644
--- a/ydb/core/client/server/msgbus_server_resolve_node.cpp
+++ b/ydb/core/client/server/msgbus_server_resolve_node.cpp
@@ -5,8 +5,8 @@
namespace NKikimr {
namespace NMsgBusProxy {
-class TMessageBusResolveNode : public TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON> {
- using TBase = TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON>;
+class TMessageBusResolveNode : public TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON> {
+ using TBase = TMessageBusLocalServiceRequest<TMessageBusResolveNode, NKikimrServices::TActivity::MSGBUS_COMMON>;
NKikimrClient::TResolveNodeRequest ResolveRequest;
public:
diff --git a/ydb/core/client/server/msgbus_server_s3_listing.cpp b/ydb/core/client/server/msgbus_server_s3_listing.cpp
index 3626866322b..be08332c3ca 100644
--- a/ydb/core/client/server/msgbus_server_s3_listing.cpp
+++ b/ydb/core/client/server/msgbus_server_s3_listing.cpp
@@ -14,7 +14,7 @@ namespace NKikimr {
namespace NMsgBusProxy {
-template <NKikimrServices::TActivity::EType acitvityType>
+template <NKikimrServices::TActivity::EType acitvityType>
class TS3ListingRequestBase : public TActorBootstrapped<TS3ListingRequestBase<acitvityType>> {
private:
typedef TS3ListingRequestBase<acitvityType> TSelf;
@@ -47,7 +47,7 @@ private:
TVector<TSerializedCellVec> ContentsRows;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return acitvityType;
}
@@ -568,7 +568,7 @@ private:
//////////////////////////////////////////////////////
// MsgBus and old GRPC API implementation
-class TS3ListingRequestMsgbus : public TMessageBusSessionIdentHolder, public TS3ListingRequestBase<NKikimrServices::TActivity::MSGBUS_COMMON> {
+class TS3ListingRequestMsgbus : public TMessageBusSessionIdentHolder, public TS3ListingRequestBase<NKikimrServices::TActivity::MSGBUS_COMMON> {
private:
TAutoPtr<TBusS3ListingRequest> RequestHolder;
@@ -710,7 +710,7 @@ protected:
};
-class TS3ListingRequestGrpc : protected TMessageConverter, public NMsgBusProxy::TS3ListingRequestBase<NKikimrServices::TActivity::GRPC_REQ> {
+class TS3ListingRequestGrpc : protected TMessageConverter, public NMsgBusProxy::TS3ListingRequestBase<NKikimrServices::TActivity::GRPC_REQ> {
private:
TAutoPtr<TEvS3ListingRequest> GrpcRequest;
NKikimrClient::TS3ListingRequest MsgbusRequest;
diff --git a/ydb/core/client/server/msgbus_server_scheme_request.cpp b/ydb/core/client/server/msgbus_server_scheme_request.cpp
index 7df5e262d07..61c288e512e 100644
--- a/ydb/core/client/server/msgbus_server_scheme_request.cpp
+++ b/ydb/core/client/server/msgbus_server_scheme_request.cpp
@@ -65,7 +65,7 @@ class TMessageBusServerSchemeRequest : public TMessageBusSecureRequest<TMessageB
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_REQUEST; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_SCHEME_REQUEST; }
template <TEvBusProxy::EEv EvId>
TMessageBusServerSchemeRequest(TEvBusProxy::TEvMsgBusRequest<EvId>* msg)
@@ -154,7 +154,7 @@ void TMessageBusServerSchemeRequest<TBusPersQueue>::ReplyWithResult(EResponseSta
}
template <>
-void TMessageBusServerSchemeRequest<TBusSchemeOperation>::SendProposeRequest(const TActorContext &ctx) {
+void TMessageBusServerSchemeRequest<TBusSchemeOperation>::SendProposeRequest(const TActorContext &ctx) {
TAutoPtr<TEvTxUserProxy::TEvProposeTransaction> req(new TEvTxUserProxy::TEvProposeTransaction());
NKikimrTxUserProxy::TEvProposeTransaction &record = req->Record;
@@ -199,7 +199,7 @@ void TMessageBusServerSchemeRequest<TBusSchemeOperation>::SendProposeRequest(con
}
template <>
-void TMessageBusServerSchemeRequest<TBusSchemeOperation>::ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) {
+void TMessageBusServerSchemeRequest<TBusSchemeOperation>::ReplyWithResult(EResponseStatus status, const NKikimrTxUserProxy::TEvProposeTransactionStatus &result, const TActorContext &ctx) {
TAutoPtr<TBusResponse> response(new TBusResponse());
FillStatus(status, result, response.Get());
diff --git a/ydb/core/client/server/msgbus_server_tablet_counters.cpp b/ydb/core/client/server/msgbus_server_tablet_counters.cpp
index 4cae1322582..c6cc6975d2a 100644
--- a/ydb/core/client/server/msgbus_server_tablet_counters.cpp
+++ b/ydb/core/client/server/msgbus_server_tablet_counters.cpp
@@ -7,7 +7,7 @@ namespace {
const ui64 DefaultTimeout = 90000;
}
-class TMessageBusTabletCounters : public TMessageBusSimpleTabletRequest<TMessageBusTabletCounters, TEvTablet::TEvGetCountersResponse, NKikimrServices::TActivity::FRONT_GETCOUNTERS> {
+class TMessageBusTabletCounters : public TMessageBusSimpleTabletRequest<TMessageBusTabletCounters, TEvTablet::TEvGetCountersResponse, NKikimrServices::TActivity::FRONT_GETCOUNTERS> {
NKikimrClient::TTabletCountersRequest Request;
public:
TMessageBusTabletCounters(TBusMessageContext &msg, NKikimrClient::TTabletCountersRequest &request, ui64 tabletId,
diff --git a/ydb/core/client/server/msgbus_server_tablet_kill.cpp b/ydb/core/client/server/msgbus_server_tablet_kill.cpp
index 62da8569e2c..ae7684b1fa3 100644
--- a/ydb/core/client/server/msgbus_server_tablet_kill.cpp
+++ b/ydb/core/client/server/msgbus_server_tablet_kill.cpp
@@ -4,7 +4,7 @@
namespace NKikimr {
namespace NMsgBusProxy {
-class TMessageBusTabletKillRequest : public TMessageBusSimpleTabletRequest<TMessageBusTabletKillRequest, TEvTablet::TEvTabletDead, NKikimrServices::TActivity::FRONT_POISON_TABLET> {
+class TMessageBusTabletKillRequest : public TMessageBusSimpleTabletRequest<TMessageBusTabletKillRequest, TEvTablet::TEvTabletDead, NKikimrServices::TActivity::FRONT_POISON_TABLET> {
public:
TMessageBusTabletKillRequest(TBusMessageContext &msg)
: TMessageBusSimpleTabletRequest(msg, static_cast<TBusTabletKillRequest*>(msg.GetMessage())->Record.GetTabletID(), false, TDuration::Seconds(60), false)
diff --git a/ydb/core/client/server/msgbus_server_tablet_state.cpp b/ydb/core/client/server/msgbus_server_tablet_state.cpp
index c8582fc5501..646d6405848 100644
--- a/ydb/core/client/server/msgbus_server_tablet_state.cpp
+++ b/ydb/core/client/server/msgbus_server_tablet_state.cpp
@@ -21,7 +21,7 @@ protected:
TMap<ui64, TAutoPtr<TEvWhiteboard::TEvTabletStateResponse>> PerNodeTabletInfo;
size_t NodesRequested;
size_t NodesReceived;
- const NKikimrClient::TTabletStateRequest Record;
+ const NKikimrClient::TTabletStateRequest Record;
public:
void SendReplyAndDie(NBus::TBusMessage *reply, const TActorContext &ctx) {
@@ -29,8 +29,8 @@ public:
Die(ctx);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TMessageBusTabletStateRequest(TBusMessageContext &msg)
diff --git a/ydb/core/client/server/msgbus_server_test_shard_request.cpp b/ydb/core/client/server/msgbus_server_test_shard_request.cpp
index 4776f4da85d..0e5a25a7299 100644
--- a/ydb/core/client/server/msgbus_server_test_shard_request.cpp
+++ b/ydb/core/client/server/msgbus_server_test_shard_request.cpp
@@ -1,51 +1,51 @@
-#include "msgbus_tabletreq.h"
+#include "msgbus_tabletreq.h"
#include <ydb/core/test_tablet/events.h>
-
-namespace NKikimr::NMsgBusProxy {
-
-static constexpr TDuration RequestTimeout = TDuration::Seconds(90);
-
-class TMessageBusTestShardControl : public TMessageBusSimpleTabletRequest<TMessageBusTestShardControl,
- NTestShard::TEvControlResponse, NKikimrServices::TActivity::FRONT_TEST_SHARD_REQUEST> {
- using TBase = TMessageBusSimpleTabletRequest;
-
- NKikimrClient::TTestShardControlRequest Request;
-
-public:
- TMessageBusTestShardControl(TBusMessageContext& msg, NKikimrClient::TTestShardControlRequest& record)
+
+namespace NKikimr::NMsgBusProxy {
+
+static constexpr TDuration RequestTimeout = TDuration::Seconds(90);
+
+class TMessageBusTestShardControl : public TMessageBusSimpleTabletRequest<TMessageBusTestShardControl,
+ NTestShard::TEvControlResponse, NKikimrServices::TActivity::FRONT_TEST_SHARD_REQUEST> {
+ using TBase = TMessageBusSimpleTabletRequest;
+
+ NKikimrClient::TTestShardControlRequest Request;
+
+public:
+ TMessageBusTestShardControl(TBusMessageContext& msg, NKikimrClient::TTestShardControlRequest& record)
: TBase(msg, record.GetTabletId(), true, RequestTimeout, false /* no followers */)
- , Request(std::move(record))
- {}
-
- void Handle(NTestShard::TEvControlResponse::TPtr /*ev*/, const TActorContext& ctx) {
- auto response = std::make_unique<TBusResponse>();
- auto& record = response->Record;
- record.SetStatus(MSTATUS_OK);
- TBase::SendReplyAndDie(response.release(), ctx);
- }
-
- NTestShard::TEvControlRequest *MakeReq(const TActorContext&) {
- auto request = std::make_unique<NTestShard::TEvControlRequest>();
- request->Record.CopyFrom(Request);
- return request.release();
- }
-
- NBus::TBusMessage *CreateErrorReply(EResponseStatus status, const TActorContext& /*ctx*/, const TString& text) override {
- auto response = std::make_unique<TBusResponse>();
- auto& record = response->Record;
- record.SetStatus(status);
- if (text) {
- record.SetErrorReason(text);
- } else {
- record.SetErrorReason(TStringBuilder() << "TMessageBusTestShardControl unknown error TabletId# " << TabletID
- << " Status# " << status);
- }
- return response.release();
- }
-};
-
-IActor* CreateMessageBusTestShardControl(NKikimr::NMsgBusProxy::TBusMessageContext& msg) {
- return new TMessageBusTestShardControl(msg, static_cast<TBusTestShardControlRequest*>(msg.GetMessage())->Record);
-}
-
-} // NKikimr::NMsgBusProxy
+ , Request(std::move(record))
+ {}
+
+ void Handle(NTestShard::TEvControlResponse::TPtr /*ev*/, const TActorContext& ctx) {
+ auto response = std::make_unique<TBusResponse>();
+ auto& record = response->Record;
+ record.SetStatus(MSTATUS_OK);
+ TBase::SendReplyAndDie(response.release(), ctx);
+ }
+
+ NTestShard::TEvControlRequest *MakeReq(const TActorContext&) {
+ auto request = std::make_unique<NTestShard::TEvControlRequest>();
+ request->Record.CopyFrom(Request);
+ return request.release();
+ }
+
+ NBus::TBusMessage *CreateErrorReply(EResponseStatus status, const TActorContext& /*ctx*/, const TString& text) override {
+ auto response = std::make_unique<TBusResponse>();
+ auto& record = response->Record;
+ record.SetStatus(status);
+ if (text) {
+ record.SetErrorReason(text);
+ } else {
+ record.SetErrorReason(TStringBuilder() << "TMessageBusTestShardControl unknown error TabletId# " << TabletID
+ << " Status# " << status);
+ }
+ return response.release();
+ }
+};
+
+IActor* CreateMessageBusTestShardControl(NKikimr::NMsgBusProxy::TBusMessageContext& msg) {
+ return new TMessageBusTestShardControl(msg, static_cast<TBusTestShardControlRequest*>(msg.GetMessage())->Record);
+}
+
+} // NKikimr::NMsgBusProxy
diff --git a/ydb/core/client/server/msgbus_server_tracer.cpp b/ydb/core/client/server/msgbus_server_tracer.cpp
index ff93f8d1cbe..7977206add1 100644
--- a/ydb/core/client/server/msgbus_server_tracer.cpp
+++ b/ydb/core/client/server/msgbus_server_tracer.cpp
@@ -25,9 +25,9 @@ void TMessageBusTracingServer::OnMessage(NBus::TOnMessageContext &msg) {
if (msgCtx.GetMessage()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE) {
const auto &record = static_cast<NMsgBusProxy::TBusMessageBusTraceRequest*>(msgCtx.GetMessage())->Record;
if (record.HasCommand()) {
- const NKikimrClient::TMessageBusTraceRequest::ECommand command = record.GetCommand();
+ const NKikimrClient::TMessageBusTraceRequest::ECommand command = record.GetCommand();
switch (command) {
- case NKikimrClient::TMessageBusTraceRequest::START:
+ case NKikimrClient::TMessageBusTraceRequest::START:
if (record.HasPath()) {
TFsPath basePath = TracePath;
TFsPath path = record.GetPath();
@@ -42,7 +42,7 @@ void TMessageBusTracingServer::OnMessage(NBus::TOnMessageContext &msg) {
}
}
break;
- case NKikimrClient::TMessageBusTraceRequest::STOP:
+ case NKikimrClient::TMessageBusTraceRequest::STOP:
if (IActor *x = CreateMessageBusTracerStopTrace(msgCtx)) {
TraceActive = false;
ActorSystem->Register(x);
@@ -152,10 +152,10 @@ namespace {
}
template <typename TDerived>
-class TMessageBusTraceSimpleActor : public NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR> {
+class TMessageBusTraceSimpleActor : public NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR> {
public:
TMessageBusTraceSimpleActor(NMsgBusProxy::TBusMessageContext &msg)
- : NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR>(msg, TDuration::MilliSeconds(DefaultTimeout))
+ : NMsgBusProxy::TMessageBusLocalServiceRequest<TDerived, NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR>(msg, TDuration::MilliSeconds(DefaultTimeout))
{}
void Handle(TEvMessageBusTracer::TEvTraceStatus::TPtr &ev, const TActorContext &ctx) {
diff --git a/ydb/core/client/server/msgbus_server_tracer.h b/ydb/core/client/server/msgbus_server_tracer.h
index 57a3812f5d5..c11d641a4b2 100644
--- a/ydb/core/client/server/msgbus_server_tracer.h
+++ b/ydb/core/client/server/msgbus_server_tracer.h
@@ -82,8 +82,8 @@ class TMessageBusTracerService : public TActor<TMessageBusTracerService> {
public:
using TProtocol = NKikimr::NMsgBusProxy::TProtocol;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_TRACER_ACTOR;
}
TMessageBusTracerService();
diff --git a/ydb/core/client/server/msgbus_server_tx_request.cpp b/ydb/core/client/server/msgbus_server_tx_request.cpp
index a0d73fa9d69..6d842707d97 100644
--- a/ydb/core/client/server/msgbus_server_tx_request.cpp
+++ b/ydb/core/client/server/msgbus_server_tx_request.cpp
@@ -66,7 +66,7 @@ public:
}
};
-IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg) {
+IActor* CreateMessageBusSchemeOperationStatus(TBusMessageContext &msg) {
return new TMessageBusTxStatusRequestActor(msg);
}
diff --git a/ydb/core/client/server/msgbus_server_types.cpp b/ydb/core/client/server/msgbus_server_types.cpp
index 0495040e3cd..cf839ec97f0 100644
--- a/ydb/core/client/server/msgbus_server_types.cpp
+++ b/ydb/core/client/server/msgbus_server_types.cpp
@@ -15,8 +15,8 @@ namespace NMsgBusProxy {
class TMessageBusGetTypes : public TActorBootstrapped<TMessageBusGetTypes>, public TMessageBusSessionIdentHolder {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
TMessageBusGetTypes(TBusMessageContext &msg, TMaybe<ui64> etag)
diff --git a/ydb/core/client/server/msgbus_server_whoami.cpp b/ydb/core/client/server/msgbus_server_whoami.cpp
index d0011548187..ee1e9e29fdd 100644
--- a/ydb/core/client/server/msgbus_server_whoami.cpp
+++ b/ydb/core/client/server/msgbus_server_whoami.cpp
@@ -15,8 +15,8 @@ class TMessageBusWhoAmI : public TMessageBusSecureRequest<TMessageBusServerReque
THolder<TBusWhoAmI> Request;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::WHOAMI;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::WHOAMI;
}
TMessageBusWhoAmI(NMsgBusProxy::TBusMessageContext& msg)
diff --git a/ydb/core/client/server/msgbus_servicereq.h b/ydb/core/client/server/msgbus_servicereq.h
index 704a231dd1d..9488dd08d1a 100644
--- a/ydb/core/client/server/msgbus_servicereq.h
+++ b/ydb/core/client/server/msgbus_servicereq.h
@@ -10,7 +10,7 @@
namespace NKikimr {
namespace NMsgBusProxy {
-template<typename TDerived, NKikimrServices::TActivity::EType Activity>
+template<typename TDerived, NKikimrServices::TActivity::EType Activity>
class TMessageBusLocalServiceRequest : public TActorBootstrapped<TDerived>, public TMessageBusSessionIdentHolder {
protected:
TActorId ServiceID;
diff --git a/ydb/core/client/server/msgbus_tabletreq.h b/ydb/core/client/server/msgbus_tabletreq.h
index f173ae90976..d282c4f808a 100644
--- a/ydb/core/client/server/msgbus_tabletreq.h
+++ b/ydb/core/client/server/msgbus_tabletreq.h
@@ -80,8 +80,8 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::MSGBUS_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::MSGBUS_COMMON;
}
void Bootstrap(const TActorContext &ctx) {
@@ -119,7 +119,7 @@ public:
}
};
-template<typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity>
+template<typename TDerived, typename TTabletReplyEvent, NKikimrServices::TActivity::EType Activity>
class TMessageBusSimpleTabletRequest : public TMessageBusTabletRequest<TDerived, TTabletReplyEvent> {
protected:
const ui64 TabletID;
diff --git a/ydb/core/client/server/ya.make b/ydb/core/client/server/ya.make
index 8cbeec21b77..4e65d8c1214 100644
--- a/ydb/core/client/server/ya.make
+++ b/ydb/core/client/server/ya.make
@@ -10,7 +10,7 @@ SRCS(
document_conversion.h
http_ping.cpp
http_ping.h
- msgbus_blobstorage_config.cpp
+ msgbus_blobstorage_config.cpp
msgbus_bsadm.cpp
msgbus_http_server.h
msgbus_http_server.cpp
@@ -22,7 +22,7 @@ SRCS(
msgbus_server_db.cpp
msgbus_server_drain_node.cpp
msgbus_server_fill_node.cpp
- msgbus_server_get.cpp
+ msgbus_server_get.cpp
msgbus_server_hive_create_tablet.cpp
msgbus_server_keyvalue.cpp
msgbus_server_persqueue.cpp
@@ -33,8 +33,8 @@ SRCS(
msgbus_server_pq_metarequest.cpp
msgbus_server_pq_read_session_info.cpp
msgbus_server_resolve_node.cpp
- msgbus_server_ic_debug.cpp
- msgbus_server_load.cpp
+ msgbus_server_ic_debug.cpp
+ msgbus_server_load.cpp
msgbus_server_local_enumerate_tablets.cpp
msgbus_server_local_minikql.cpp
msgbus_server_local_scheme_tx.cpp
@@ -50,7 +50,7 @@ SRCS(
msgbus_server_tablet_counters.cpp
msgbus_server_tablet_kill.cpp
msgbus_server_tablet_state.cpp
- msgbus_server_test_shard_request.cpp
+ msgbus_server_test_shard_request.cpp
msgbus_server_tracer.cpp
msgbus_server_tracer.h
msgbus_server_tx_request.cpp
diff --git a/ydb/core/cms/cluster_info.cpp b/ydb/core/cms/cluster_info.cpp
index a1dc8a0b95f..dc0614e8377 100644
--- a/ydb/core/cms/cluster_info.cpp
+++ b/ydb/core/cms/cluster_info.cpp
@@ -441,7 +441,7 @@ void TClusterInfo::UpdatePDiskState(const TPDiskID &id, const NKikimrWhiteboard:
}
auto &pdisk = PDiskRef(id);
- pdisk.State = info.GetState() == NKikimrBlobStorage::TPDiskState::Normal ? UP : DOWN;
+ pdisk.State = info.GetState() == NKikimrBlobStorage::TPDiskState::Normal ? UP : DOWN;
}
void TClusterInfo::AddVDisk(const NKikimrBlobStorage::TBaseConfig::TVSlot &info)
diff --git a/ydb/core/cms/cluster_info.h b/ydb/core/cms/cluster_info.h
index af5fe24af80..3b6d212fd83 100644
--- a/ydb/core/cms/cluster_info.h
+++ b/ydb/core/cms/cluster_info.h
@@ -184,7 +184,7 @@ public:
if (notification.Notification.HasTime())
LockStart = TInstant::MicroSeconds(notification.Notification.GetTime());
else
- LockStart = TActivationContext::Now();
+ LockStart = TActivationContext::Now();
LockDeadline = LockStart + TDuration::MicroSeconds(action.GetDuration());
}
@@ -318,7 +318,7 @@ public:
TString Host;
TString Address;
ui16 IcPort = 0;
- TNodeLocation Location;
+ TNodeLocation Location;
TString Version;
TSet<ui64> Tablets;
TSet<TPDiskID> PDisks;
diff --git a/ydb/core/cms/cluster_info_ut.cpp b/ydb/core/cms/cluster_info_ut.cpp
index 8b9d3b3d653..fc243fbbf07 100644
--- a/ydb/core/cms/cluster_info_ut.cpp
+++ b/ydb/core/cms/cluster_info_ut.cpp
@@ -50,7 +50,7 @@ TPDiskStateInfo MakePDiskInfo(ui32 id)
pdisk.SetGuid(id);
pdisk.SetAvailableSize(100ULL << 30);
pdisk.SetTotalSize(100ULL << 30);
- pdisk.SetState(NKikimrBlobStorage::TPDiskState::Normal);
+ pdisk.SetState(NKikimrBlobStorage::TPDiskState::Normal);
return pdisk;
}
@@ -255,13 +255,13 @@ Y_UNIT_TEST_SUITE(TClusterInfoTest) {
Y_UNIT_TEST(FillInfo) {
TEvInterconnect::TNodeInfo node1 =
- { 1, "::1", "test1", "test1", 1, TNodeLocation() };
+ { 1, "::1", "test1", "test1", 1, TNodeLocation() };
TEvInterconnect::TNodeInfo node2 =
- { 1, "::1", "test2", "test2", 1, TNodeLocation() };
+ { 1, "::1", "test2", "test2", 1, TNodeLocation() };
TEvInterconnect::TNodeInfo node3 =
- { 2, "::2", "localhost", "localhost", 1, TNodeLocation() };
+ { 2, "::2", "localhost", "localhost", 1, TNodeLocation() };
TEvInterconnect::TNodeInfo node4 =
- { 3, "::2", "localhost", "localhost", 1, TNodeLocation() };
+ { 3, "::2", "localhost", "localhost", 1, TNodeLocation() };
TClusterInfo cluster;
cluster.AddNode(node1, nullptr);
diff --git a/ydb/core/cms/cms.cpp b/ydb/core/cms/cms.cpp
index 0a205024e3c..43a69bfd9f2 100644
--- a/ydb/core/cms/cms.cpp
+++ b/ydb/core/cms/cms.cpp
@@ -26,7 +26,7 @@ void TCms::TNodeCounter::CountNode(const TNodeInfo &node,
{
++Total;
TErrorInfo error;
- if (node.IsLocked(error, TDuration(), TActivationContext::Now(), TDuration())) {
+ if (node.IsLocked(error, TDuration(), TActivationContext::Now(), TDuration())) {
++Locked;
if (error.Code == TStatus::DISALLOW)
Code = error.Code;
@@ -86,9 +86,9 @@ void TCms::TGroupCounter::CountVDisk(const TVDiskInfo &vdisk,
// Check locks.
TErrorInfo error;
- if (node.IsLocked(error, retryTime, TActivationContext::Now(), duration)
- || pdisk.IsLocked(error, retryTime, TActivationContext::Now(), duration)
- || vdisk.IsLocked(error, retryTime, TActivationContext::Now(), duration)) {
+ if (node.IsLocked(error, retryTime, TActivationContext::Now(), duration)
+ || pdisk.IsLocked(error, retryTime, TActivationContext::Now(), duration)
+ || vdisk.IsLocked(error, retryTime, TActivationContext::Now(), duration)) {
if (error.Code == TStatus::DISALLOW)
Code = error.Code;
++Locked;
@@ -107,7 +107,7 @@ void TCms::TGroupCounter::CountVDisk(const TVDiskInfo &vdisk,
}
// Check if disk is down.
- auto defaultDeadline = TActivationContext::Now() + retryTime;
+ auto defaultDeadline = TActivationContext::Now() + retryTime;
if ((node.NodeId != VDisk.NodeId && node.IsDown(error, defaultDeadline))
|| (pdisk.PDiskId != VDisk.PDiskId && pdisk.IsDown(error, defaultDeadline))
|| vdisk.IsDown(error, defaultDeadline)) {
@@ -500,7 +500,7 @@ bool TCms::CheckActionShutdownHost(const TAction &action,
}
}
- error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
+ error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
return true;
}
@@ -512,7 +512,7 @@ bool TCms::TryToLockNode(const TAction& action,
TDuration duration = TDuration::MicroSeconds(action.GetDuration());
duration += opts.PermissionDuration;
- if (node.IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
+ if (node.IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
return false;
ui32 tenantLimit = State->Config.TenantLimits.GetDisabledNodesLimit();
@@ -547,7 +547,7 @@ bool TCms::TryToLockNode(const TAction& action,
<< " down: " << tenantNodes.Down
<< " total: " << tenantNodes.Total
<< " limit: " << tenantLimit;
- error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
+ error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
return false;
}
if (!tenantNodes.CheckRatio(tenantRatioLimit, opts.AvailabilityMode)) {
@@ -557,7 +557,7 @@ bool TCms::TryToLockNode(const TAction& action,
<< " down: " << tenantNodes.Down
<< " total: " << tenantNodes.Total
<< " limit: " << tenantRatioLimit << "%";
- error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
+ error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
return false;
}
}
@@ -569,7 +569,7 @@ bool TCms::TryToLockNode(const TAction& action,
<< " down: " << clusterNodes.Down
<< " total: " << clusterNodes.Total
<< " limit: " << clusterLimit;
- error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
+ error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
return false;
}
if (!clusterNodes.CheckRatio(clusterRatioLimit, opts.AvailabilityMode)) {
@@ -579,7 +579,7 @@ bool TCms::TryToLockNode(const TAction& action,
<< " down: " << clusterNodes.Down
<< " total: " << clusterNodes.Total
<< " limit: " << clusterRatioLimit << "%";
- error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
+ error.Deadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
return false;
}
@@ -594,7 +594,7 @@ bool TCms::TryToLockPDisk(const TAction &action,
if (!TryToLockVDisks(action, opts, pdisk.VDisks, error))
return false;
- error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
+ error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
return true;
}
@@ -627,22 +627,22 @@ bool TCms::TryToLockVDisk(const TActionOptions& opts,
TDuration duration,
TErrorInfo &error) const
{
- if (vdisk.IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
+ if (vdisk.IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
return false;
if (vdisk.NodeId
&& ClusterInfo->Node(vdisk.NodeId)
- .IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
+ .IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
return false;
if (vdisk.PDiskId
&& ClusterInfo->PDisk(vdisk.PDiskId)
- .IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
+ .IsLocked(error, State->Config.DefaultRetryTime, TActivationContext::Now(), duration))
return false;
for (auto groupId : vdisk.BSGroups) {
const auto &group = ClusterInfo->BSGroup(groupId);
- TInstant defaultDeadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
+ TInstant defaultDeadline = TActivationContext::Now() + State->Config.DefaultRetryTime;
if (group.Erasure.GetErasure() == TErasureType::ErasureSpeciesCount) {
error.Code = TStatus::ERROR;
@@ -753,7 +753,7 @@ bool TCms::CheckActionReplaceDevices(const TAction &action,
ClusterInfo->RollbackLocks(point);
if (res)
- error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
+ error.Deadline = TActivationContext::Now() + opts.PermissionDuration;
return res;
}
diff --git a/ydb/core/cms/cms_impl.h b/ydb/core/cms/cms_impl.h
index 48138884907..6ef328d5571 100644
--- a/ydb/core/cms/cms_impl.h
+++ b/ydb/core/cms/cms_impl.h
@@ -436,9 +436,9 @@ public:
{
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_SERVICE;
+ return NKikimrServices::TActivity::CMS_SERVICE;
}
};
diff --git a/ydb/core/cms/cms_ut.cpp b/ydb/core/cms/cms_ut.cpp
index 9842fb71567..159632c2f7d 100644
--- a/ydb/core/cms/cms_ut.cpp
+++ b/ydb/core/cms/cms_ut.cpp
@@ -466,7 +466,7 @@ Y_UNIT_TEST_SUITE(TCmsTest) {
// PDisk-0 on node-0 is down.
auto &node = TFakeNodeWhiteboardService::Info[env.GetNodeId(0)];
- node.PDiskStateInfo[env.PDiskId(0).DiskId].SetState(NKikimrBlobStorage::TPDiskState::Initial);
+ node.PDiskStateInfo[env.PDiskId(0).DiskId].SetState(NKikimrBlobStorage::TPDiskState::Initial);
// OK to restart broken PDisk.
env.CheckPermissionRequest("user", false, true, false, true, TStatus::ALLOW,
diff --git a/ydb/core/cms/cms_ut_common.cpp b/ydb/core/cms/cms_ut_common.cpp
index b458fe672ce..8ec0e8c82e6 100644
--- a/ydb/core/cms/cms_ut_common.cpp
+++ b/ydb/core/cms/cms_ut_common.cpp
@@ -265,7 +265,7 @@ void GenerateExtendedInfo(TTestActorRuntime &runtime, NKikimrBlobStorage::TBaseC
pdisk.SetGuid(1);
pdisk.SetAvailableSize(100ULL << 30);
pdisk.SetTotalSize(200ULL << 30);
- pdisk.SetState(NKikimrBlobStorage::TPDiskState::Normal);
+ pdisk.SetState(NKikimrBlobStorage::TPDiskState::Normal);
auto &pdiskConfig = *config->AddPDisk();
pdiskConfig.SetNodeId(nodeId);
diff --git a/ydb/core/cms/config.h b/ydb/core/cms/config.h
index 471880e34f6..2499a048acb 100644
--- a/ydb/core/cms/config.h
+++ b/ydb/core/cms/config.h
@@ -125,13 +125,13 @@ struct TCmsSentinelConfig {
stateLimits[NKikimrBlobStorage::TPDiskState::ChunkQuotaError] = 60;
stateLimits[NKikimrBlobStorage::TPDiskState::DeviceIoError] = 60;
// node online, pdisk missing
- stateLimits[NKikimrBlobStorage::TPDiskState::Missing] = 60;
+ stateLimits[NKikimrBlobStorage::TPDiskState::Missing] = 60;
// node timeout
- stateLimits[NKikimrBlobStorage::TPDiskState::Timeout] = 60;
+ stateLimits[NKikimrBlobStorage::TPDiskState::Timeout] = 60;
// node offline
- stateLimits[NKikimrBlobStorage::TPDiskState::NodeDisconnected] = 60;
+ stateLimits[NKikimrBlobStorage::TPDiskState::NodeDisconnected] = 60;
// disable for unknown states
- stateLimits[NKikimrBlobStorage::TPDiskState::Unknown] = 0;
+ stateLimits[NKikimrBlobStorage::TPDiskState::Unknown] = 0;
return stateLimits;
}
diff --git a/ydb/core/cms/console/config_helpers.cpp b/ydb/core/cms/console/config_helpers.cpp
index 6d5a81beaf0..bb0888978af 100644
--- a/ydb/core/cms/console/config_helpers.cpp
+++ b/ydb/core/cms/console/config_helpers.cpp
@@ -51,9 +51,9 @@ private:
ui64 Cookie;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_CONFIGS_SUBSCRIBER;
+ return NKikimrServices::TActivity::CMS_CONFIGS_SUBSCRIBER;
}
// Add/replace subscription.
diff --git a/ydb/core/cms/console/configs_dispatcher.cpp b/ydb/core/cms/console/configs_dispatcher.cpp
index 8e507542392..09f840e7aec 100644
--- a/ydb/core/cms/console/configs_dispatcher.cpp
+++ b/ydb/core/cms/console/configs_dispatcher.cpp
@@ -77,9 +77,9 @@ private:
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CONFIGS_DISPATCHER_ACTOR;
+ return NKikimrServices::TActivity::CONFIGS_DISPATCHER_ACTOR;
}
TConfigsDispatcher(const NKikimrConfig::TAppConfig &config);
diff --git a/ydb/core/cms/console/console_configs_manager.h b/ydb/core/cms/console/console_configs_manager.h
index 2dca13be264..58f2fee4848 100644
--- a/ydb/core/cms/console/console_configs_manager.h
+++ b/ydb/core/cms/console/console_configs_manager.h
@@ -170,9 +170,9 @@ public:
ClearState();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_CONFIGS_MANAGER;
+ return NKikimrServices::TActivity::CMS_CONFIGS_MANAGER;
}
void Bootstrap(const TActorContext &ctx);
diff --git a/ydb/core/cms/console/console_configs_provider.cpp b/ydb/core/cms/console/console_configs_provider.cpp
index 4ba6f460338..192b3a533d7 100644
--- a/ydb/core/cms/console/console_configs_provider.cpp
+++ b/ydb/core/cms/console/console_configs_provider.cpp
@@ -22,9 +22,9 @@ private:
TSchedulerCookieHolder TimeoutTimerCookieHolder;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
+ return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
}
TTabletConfigSender(TSubscription::TPtr subscription, TActorId ownerId)
@@ -159,9 +159,9 @@ private:
bool ScheduledRetry;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
+ return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
}
TServiceConfigSender(TSubscription::TPtr subscription, TActorId ownerId)
diff --git a/ydb/core/cms/console/console_configs_provider.h b/ydb/core/cms/console/console_configs_provider.h
index ddb74d52d48..8ee78dddc84 100644
--- a/ydb/core/cms/console/console_configs_provider.h
+++ b/ydb/core/cms/console/console_configs_provider.h
@@ -196,9 +196,9 @@ public:
ClearState();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
+ return NKikimrServices::TActivity::CMS_CONFIGS_PROVIDER;
}
void Bootstrap(const TActorContext &ctx);
diff --git a/ydb/core/cms/console/console_configs_subscriber.cpp b/ydb/core/cms/console/console_configs_subscriber.cpp
index 20f3969f86f..39dc4ae5116 100644
--- a/ydb/core/cms/console/console_configs_subscriber.cpp
+++ b/ydb/core/cms/console/console_configs_subscriber.cpp
@@ -133,7 +133,7 @@ public:
}
void Handle(TEvConsole::TEvConfigSubscriptionError::TPtr &ev, const TActorContext &ctx) {
- NActors::TActivationContext::Send(ev->Forward(OwnerId));
+ NActors::TActivationContext::Send(ev->Forward(OwnerId));
Generation = 0;
Die(ctx);
diff --git a/ydb/core/cms/console/console_impl.h b/ydb/core/cms/console/console_impl.h
index 0894337c3ec..4d0adb1b003 100644
--- a/ydb/core/cms/console/console_impl.h
+++ b/ydb/core/cms/console/console_impl.h
@@ -137,8 +137,8 @@ public:
TxProcessor->Clear();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::CMS_SERVICE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::CMS_SERVICE;
}
void Execute(ITransaction *transaction, const TActorContext &ctx) override
diff --git a/ydb/core/cms/console/console_tenants_manager.cpp b/ydb/core/cms/console/console_tenants_manager.cpp
index 0db3f5dceda..d9054e3f9fc 100644
--- a/ydb/core/cms/console/console_tenants_manager.cpp
+++ b/ydb/core/cms/console/console_tenants_manager.cpp
@@ -49,9 +49,9 @@ private:
TString LogPrefix;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
+ return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
}
TPoolManip(TActorId ownerId, TDomainsInfo::TDomain::TPtr domain,
@@ -106,7 +106,7 @@ public:
void ReadPoolState(const TActorContext &ctx)
{
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
auto &read = *request->Record.MutableRequest()->AddCommand()->MutableReadStoragePool();
read.SetBoxId(Pool->Config.GetBoxId());
read.AddName(Pool->Config.GetName());
@@ -118,7 +118,7 @@ public:
void AllocatePool(const TActorContext &ctx)
{
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
request->Record.MutableRequest()->AddCommand()->MutableDefineStoragePool()->CopyFrom(Pool->Config);
BLOG_D(LogPrefix << "send pool request: " << request->Record.ShortDebugString());
@@ -135,7 +135,7 @@ public:
return;
}
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
auto &del = *request->Record.MutableRequest()->AddCommand()->MutableDeleteStoragePool();
del.SetBoxId(Pool->Config.GetBoxId());
del.SetStoragePoolId(PoolId);
@@ -400,9 +400,9 @@ private:
static THashMap<ui64, TString> IssuesMap;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
+ return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
}
TSubDomainManip(TActorId ownerId, TTenantsManager::TTenant::TPtr tenant, EAction action,
@@ -1075,7 +1075,7 @@ bool TTenantsManager::TTenantsConfig::Parse(const NKikimrConsole::TTenantsConfig
}
case NKikimrConsole::TAvailabilityZoneKind::ZONE_NOT_SET:
{
- TAvailabilityZone zone(kind.GetKind(), ANY_DATA_CENTER);
+ TAvailabilityZone zone(kind.GetKind(), ANY_DATA_CENTER);
AvailabilityZones[kind.GetKind()] = zone;
break;
}
@@ -2928,7 +2928,7 @@ void TTenantsManager::Handle(TEvConsole::TEvDescribeTenantOptionsRequest::TPtr &
auto &description = *result.add_availability_zones();
description.set_name(pr.first);
TString dc;
- if (pr.second.DataCenter != ANY_DATA_CENTER)
+ if (pr.second.DataCenter != ANY_DATA_CENTER)
(*description.mutable_labels())["fixed_data_center"] = pr.second.DataCenter;
else
(*description.mutable_labels())["any_data_center"] = "true";
diff --git a/ydb/core/cms/console/console_tenants_manager.h b/ydb/core/cms/console/console_tenants_manager.h
index a21615dd622..e3f39b1b971 100644
--- a/ydb/core/cms/console/console_tenants_manager.h
+++ b/ydb/core/cms/console/console_tenants_manager.h
@@ -973,9 +973,9 @@ public:
ClearState();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
+ return NKikimrServices::TActivity::CMS_TENANTS_MANAGER;
}
void Bootstrap(const TActorContext &ctx);
diff --git a/ydb/core/cms/console/console_ut_tenants.cpp b/ydb/core/cms/console/console_ut_tenants.cpp
index 57e4820af72..a207bb2b786 100644
--- a/ydb/core/cms/console/console_ut_tenants.cpp
+++ b/ydb/core/cms/console/console_ut_tenants.cpp
@@ -388,7 +388,7 @@ void CheckTenantGeneration(TTenantTestRuntime &runtime,
void CheckPoolScope(TTenantTestRuntime &runtime,
const TString &name)
{
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
auto &read = *request->Record.MutableRequest()->AddCommand()->MutableReadStoragePool();
read.SetBoxId(1);
read.AddName(name);
@@ -1338,7 +1338,7 @@ Y_UNIT_TEST_SUITE(TConsoleTests) {
NKikimrConsole::TConfig config1 = GetCurrentConfig(runtime);
for (ui64 i = 0; i < config1.GetTenantsConfig().AvailabilityZoneKindsSize(); ++i) {
if (config1.GetTenantsConfig().GetAvailabilityZoneKinds(i).GetKind() == ZONE1) {
- config1.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(2));
+ config1.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(2));
break;
}
}
@@ -1348,7 +1348,7 @@ Y_UNIT_TEST_SUITE(TConsoleTests) {
NKikimrConsole::TConfig config2 = GetCurrentConfig(runtime);
for (ui64 i = 0; i < config2.GetTenantsConfig().AvailabilityZoneKindsSize(); ++i) {
if (config2.GetTenantsConfig().GetAvailabilityZoneKinds(i).GetKind() == ZONE2) {
- config2.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(1));
+ config2.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(1));
break;
}
}
@@ -1361,7 +1361,7 @@ Y_UNIT_TEST_SUITE(TConsoleTests) {
for (ui64 i = 0; i < config2.GetTenantsConfig().AvailabilityZoneKindsSize(); ++i) {
if (config2.GetTenantsConfig().GetAvailabilityZoneKinds(i).GetKind() == ZONE2) {
- config2.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(2));
+ config2.MutableTenantsConfig()->MutableAvailabilityZoneKinds(i)->SetDataCenterName(ToString(2));
break;
}
}
@@ -1486,7 +1486,7 @@ Y_UNIT_TEST_SUITE(TConsoleTests) {
NKikimrConsole::TConfig delta;
auto zone = delta.MutableTenantsConfig()->AddAvailabilityZoneKinds();
zone->SetKind(ZONE1);
- zone->SetDataCenterName(ToString(1));
+ zone->SetDataCenterName(ToString(1));
CheckSetConfig(runtime, delta, Ydb::StatusIds::BAD_REQUEST, NKikimrConsole::TConfigItem::MERGE);
}
@@ -1495,7 +1495,7 @@ Y_UNIT_TEST_SUITE(TConsoleTests) {
NKikimrConsole::TConfig delta;
auto zone1 = delta.MutableTenantsConfig()->AddAvailabilityZoneKinds();
zone1->SetKind(ZONE1);
- zone1->SetDataCenterName(ToString(1));
+ zone1->SetDataCenterName(ToString(1));
auto set1 = delta.MutableTenantsConfig()->AddAvailabilityZoneSets();
set1->SetName("all");
set1->AddZoneKinds(ZONE1);
diff --git a/ydb/core/cms/console/immediate_controls_configurator.cpp b/ydb/core/cms/console/immediate_controls_configurator.cpp
index af3ad242171..e9f1e18ba5c 100644
--- a/ydb/core/cms/console/immediate_controls_configurator.cpp
+++ b/ydb/core/cms/console/immediate_controls_configurator.cpp
@@ -12,9 +12,9 @@ namespace NConsole {
class TImmediateControlsConfigurator : public TActorBootstrapped<TImmediateControlsConfigurator> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::IMMEDITE_CONTROLS_CONFIGURATOR;
+ return NKikimrServices::TActivity::IMMEDITE_CONTROLS_CONFIGURATOR;
}
TImmediateControlsConfigurator(TIntrusivePtr<TControlBoard> board,
diff --git a/ydb/core/cms/console/log_settings_configurator.cpp b/ydb/core/cms/console/log_settings_configurator.cpp
index 11d41e245e4..635298968bc 100644
--- a/ydb/core/cms/console/log_settings_configurator.cpp
+++ b/ydb/core/cms/console/log_settings_configurator.cpp
@@ -13,9 +13,9 @@ namespace NConsole {
class TLogSettingsConfigurator : public TActorBootstrapped<TLogSettingsConfigurator> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::LOG_SETTINGS_CONFIGURATOR;
+ return NKikimrServices::TActivity::LOG_SETTINGS_CONFIGURATOR;
}
TLogSettingsConfigurator();
diff --git a/ydb/core/cms/console/shared_cache_configurator.cpp b/ydb/core/cms/console/shared_cache_configurator.cpp
index 60118148496..e9ef06d8dfe 100644
--- a/ydb/core/cms/console/shared_cache_configurator.cpp
+++ b/ydb/core/cms/console/shared_cache_configurator.cpp
@@ -11,8 +11,8 @@ namespace NConsole {
class TSharedCacheConfigurator : public TActorBootstrapped<TSharedCacheConfigurator> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SHARED_CACHE_CONFIGURATOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SHARED_CACHE_CONFIGURATOR;
}
TSharedCacheConfigurator() = default;
diff --git a/ydb/core/cms/http.cpp b/ydb/core/cms/http.cpp
index 648d864b6ed..514c3de541c 100644
--- a/ydb/core/cms/http.cpp
+++ b/ydb/core/cms/http.cpp
@@ -33,9 +33,9 @@ public:
class TCmsHttp : public TActorBootstrapped<TCmsHttp> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
+ return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
}
void Bootstrap(const TActorContext &ctx)
@@ -127,17 +127,17 @@ private:
return;
}
- if (filename == "cms/ui/index.html") {
+ if (filename == "cms/ui/index.html") {
type = "text/html";
- }
-
- TStringStream response;
- response << "HTTP/1.1 200 Ok\r\n";
- response << "Content-Type: " << type << "\r\n";
- response << "Content-Length: " << blob.size() << "\r\n";
- response << "\r\n";
- response.Write(blob.data(), blob.size());
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ }
+
+ TStringStream response;
+ response << "HTTP/1.1 200 Ok\r\n";
+ response << "Content-Type: " << type << "\r\n";
+ response << "Content-Length: " << blob.size() << "\r\n";
+ response << "\r\n";
+ response.Write(blob.data(), blob.size());
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(response.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
}
static TString DumpRequest(const NMonitoring::IMonHttpRequest& request) {
diff --git a/ydb/core/cms/json_proxy.h b/ydb/core/cms/json_proxy.h
index 185d0ce01b6..f0376220a2c 100644
--- a/ydb/core/cms/json_proxy.h
+++ b/ydb/core/cms/json_proxy.h
@@ -33,9 +33,9 @@ protected:
using TResponse = TResponseEvent;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
+ return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
}
TJsonProxyBase(NMon::TEvHttpInfo::TPtr &event)
diff --git a/ydb/core/cms/json_proxy_proto.h b/ydb/core/cms/json_proxy_proto.h
index b1b87f30cda..578b3fbebcd 100644
--- a/ydb/core/cms/json_proxy_proto.h
+++ b/ydb/core/cms/json_proxy_proto.h
@@ -25,9 +25,9 @@ private:
using TBase = TActorBootstrapped<TJsonProxyProto>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
+ return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
}
TJsonProxyProto(NMon::TEvHttpInfo::TPtr &event)
@@ -62,7 +62,7 @@ protected:
else if (name == "NKikimrCms::TLogRecordData::EType")
return ReplyWithEnumDescription(*NKikimrCms::TLogRecordData::EType_descriptor(), ctx);
else if (name == "NCms::EPDiskState")
- return ReplyWithEnumDescription(*NKikimrBlobStorage::TPDiskState::E_descriptor(), ctx);
+ return ReplyWithEnumDescription(*NKikimrBlobStorage::TPDiskState::E_descriptor(), ctx);
} else if (cgi.Has("type")) {
TString name = cgi.Get("type");
if (name == ".NKikimrConfig.TImmediateControlsConfig")
diff --git a/ydb/core/cms/pdisk_state.h b/ydb/core/cms/pdisk_state.h
index 6dd673a7299..223f8af39c6 100644
--- a/ydb/core/cms/pdisk_state.h
+++ b/ydb/core/cms/pdisk_state.h
@@ -6,7 +6,7 @@ namespace NKikimr {
namespace NCms {
using TPDiskStateInfo = NKikimrWhiteboard::TPDiskStateInfo;
-using EPDiskState = NKikimrBlobStorage::TPDiskState::E;
+using EPDiskState = NKikimrBlobStorage::TPDiskState::E;
} // NCms
} // NKikimr
diff --git a/ydb/core/cms/sentinel.cpp b/ydb/core/cms/sentinel.cpp
index 638b78fe09b..6bf36f2c5b6 100644
--- a/ydb/core/cms/sentinel.cpp
+++ b/ydb/core/cms/sentinel.cpp
@@ -94,7 +94,7 @@ EPDiskStatus TPDiskStatusComputer::Compute(EPDiskStatus current, TString& reason
PrevState = State;
switch (State) {
- case NKikimrBlobStorage::TPDiskState::Normal:
+ case NKikimrBlobStorage::TPDiskState::Normal:
return EPDiskStatus::ACTIVE;
default:
return EPDiskStatus::FAULTY;
@@ -198,9 +198,9 @@ void TClusterMap::AddPDisk(const TPDiskID& id) {
Y_VERIFY(State->ClusterInfo->HasPDisk(id));
const auto& location = State->ClusterInfo->Node(id.NodeId).Location;
- ByDataCenter[location.HasKey(TNodeLocation::TKeys::DataCenter) ? location.GetDataCenterId() : ""].insert(id);
- ByRoom[location.HasKey(TNodeLocation::TKeys::Module) ? location.GetModuleId() : ""].insert(id);
- ByRack[location.HasKey(TNodeLocation::TKeys::Rack) ? location.GetRackId() : ""].insert(id);
+ ByDataCenter[location.HasKey(TNodeLocation::TKeys::DataCenter) ? location.GetDataCenterId() : ""].insert(id);
+ ByRoom[location.HasKey(TNodeLocation::TKeys::Module) ? location.GetModuleId() : ""].insert(id);
+ ByRack[location.HasKey(TNodeLocation::TKeys::Rack) ? location.GetRackId() : ""].insert(id);
}
/// TGuardian
@@ -230,10 +230,10 @@ TClusterMap::TPDiskIDSet TGuardian::GetAllowedPDisks(const TClusterMap& all, TSt
Y_VERIFY(all.ByDataCenter.contains(kv.first));
if (!kv.first || CheckRatio(kv, all.ByDataCenter, DataCenterRatio)) {
- result.insert(kv.second.begin(), kv.second.end());
+ result.insert(kv.second.begin(), kv.second.end());
} else {
LOG_IGNORED(DataCenter);
- disallowed.insert(kv.second.begin(), kv.second.end());
+ disallowed.insert(kv.second.begin(), kv.second.end());
}
}
@@ -242,7 +242,7 @@ TClusterMap::TPDiskIDSet TGuardian::GetAllowedPDisks(const TClusterMap& all, TSt
if (kv.first && !CheckRatio(kv, all.ByRoom, RoomRatio)) {
LOG_IGNORED(Room);
- disallowed.insert(kv.second.begin(), kv.second.end());
+ disallowed.insert(kv.second.begin(), kv.second.end());
EraseNodesIf(result, [&room = kv.second](const TPDiskID& id) {
return room.contains(id);
});
@@ -257,7 +257,7 @@ TClusterMap::TPDiskIDSet TGuardian::GetAllowedPDisks(const TClusterMap& all, TSt
}
if (kv.first && !CheckRatio(kv, all.ByRack, RackRatio)) {
LOG_IGNORED(Rack);
- disallowed.insert(kv.second.begin(), kv.second.end());
+ disallowed.insert(kv.second.begin(), kv.second.end());
EraseNodesIf(result, [&rack = kv.second](const TPDiskID& id) {
return rack.contains(id);
});
@@ -349,7 +349,7 @@ class TConfigUpdater: public TUpdaterBase<TEvSentinel::TEvConfigUpdated, TConfig
ConnectBSC();
}
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
request->Record.MutableRequest()->AddCommand()->MutableQueryBaseConfig();
NTabletPipe::SendData(SelfId(), CmsState->BSControllerPipe, request.Release());
}
@@ -431,24 +431,24 @@ class TStateUpdater: public TUpdaterBase<TEvSentinel::TEvStateUpdated, TStateUpd
static EPDiskState SafePDiskState(EPDiskState state) {
switch (state) {
- case NKikimrBlobStorage::TPDiskState::Initial:
- case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
- case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
- case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
- case NKikimrBlobStorage::TPDiskState::Normal:
- case NKikimrBlobStorage::TPDiskState::OpenFileError:
- case NKikimrBlobStorage::TPDiskState::ChunkQuotaError:
- case NKikimrBlobStorage::TPDiskState::DeviceIoError:
+ case NKikimrBlobStorage::TPDiskState::Initial:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
+ case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
+ case NKikimrBlobStorage::TPDiskState::Normal:
+ case NKikimrBlobStorage::TPDiskState::OpenFileError:
+ case NKikimrBlobStorage::TPDiskState::ChunkQuotaError:
+ case NKikimrBlobStorage::TPDiskState::DeviceIoError:
return state;
default:
LOG_C("Unknown pdisk state: " << (ui32)state);
- return NKikimrBlobStorage::TPDiskState::Unknown;
+ return NKikimrBlobStorage::TPDiskState::Unknown;
}
}
@@ -511,7 +511,7 @@ class TStateUpdater: public TUpdaterBase<TEvSentinel::TEvStateUpdated, TStateUpd
if (!record.PDiskStateInfoSize()) {
LOG_E("There is no pdisk info"
<< ": nodeId# " << nodeId);
- MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Missing);
+ MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Missing);
} else {
for (const auto& info : record.GetPDiskStateInfo()) {
auto it = SentinelState->PDisks.find(TPDiskID(nodeId, info.GetPDiskId()));
@@ -528,7 +528,7 @@ class TStateUpdater: public TUpdaterBase<TEvSentinel::TEvStateUpdated, TStateUpd
it->second.AddState(safeState);
}
- MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Missing, true);
+ MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Missing, true);
}
MaybeReply();
@@ -557,11 +557,11 @@ class TStateUpdater: public TUpdaterBase<TEvSentinel::TEvStateUpdated, TStateUpd
switch (reason) {
case EReason::Disconnected:
- MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::NodeDisconnected);
+ MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::NodeDisconnected);
break;
default:
- MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Unknown);
+ MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Unknown);
break;
}
@@ -575,7 +575,7 @@ class TStateUpdater: public TUpdaterBase<TEvSentinel::TEvStateUpdated, TStateUpd
while (WaitNodes) {
const ui32 nodeId = *WaitNodes.begin();
- MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Timeout);
+ MarkNodePDisks(nodeId, NKikimrBlobStorage::TPDiskState::Timeout);
AcceptNodeReply(nodeId);
}
@@ -644,7 +644,7 @@ class TStatusChanger: public TSentinelChildBase<TStatusChanger> {
ConnectBSC();
}
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
auto& command = *request->Record.MutableRequest()->AddCommand()->MutableUpdateDriveStatus();
command.MutableHostKey()->SetNodeId(Id.NodeId);
command.SetPDiskId(Id.DiskId);
diff --git a/ydb/core/cms/sentinel_impl.h b/ydb/core/cms/sentinel_impl.h
index 8aa6934bafa..7a973ff52cf 100644
--- a/ydb/core/cms/sentinel_impl.h
+++ b/ydb/core/cms/sentinel_impl.h
@@ -77,7 +77,7 @@ private:
class TClusterMap {
public:
using TPDiskIDSet = THashSet<TPDiskID, TPDiskIDHash>;
- using TDistribution = THashMap<TString, TPDiskIDSet>;
+ using TDistribution = THashMap<TString, TPDiskIDSet>;
TCmsStatePtr State;
TDistribution ByDataCenter;
diff --git a/ydb/core/cms/sentinel_ut.cpp b/ydb/core/cms/sentinel_ut.cpp
index 62c0fdf309d..b8e9ea79bcc 100644
--- a/ydb/core/cms/sentinel_ut.cpp
+++ b/ydb/core/cms/sentinel_ut.cpp
@@ -18,22 +18,22 @@ static constexpr ui32 DefaultErrorStateLimit = 60;
auto DefaultStateLimits = NCms::TCmsSentinelConfig::DefaultStateLimits();
static constexpr NCms::EPDiskState ErrorStates[] = {
- NKikimrBlobStorage::TPDiskState::InitialFormatReadError,
- NKikimrBlobStorage::TPDiskState::InitialSysLogReadError,
- NKikimrBlobStorage::TPDiskState::InitialSysLogParseError,
- NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError,
- NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError,
- NKikimrBlobStorage::TPDiskState::CommonLoggerInitError,
- NKikimrBlobStorage::TPDiskState::OpenFileError,
- NKikimrBlobStorage::TPDiskState::ChunkQuotaError,
- NKikimrBlobStorage::TPDiskState::DeviceIoError,
+ NKikimrBlobStorage::TPDiskState::InitialFormatReadError,
+ NKikimrBlobStorage::TPDiskState::InitialSysLogReadError,
+ NKikimrBlobStorage::TPDiskState::InitialSysLogParseError,
+ NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError,
+ NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError,
+ NKikimrBlobStorage::TPDiskState::CommonLoggerInitError,
+ NKikimrBlobStorage::TPDiskState::OpenFileError,
+ NKikimrBlobStorage::TPDiskState::ChunkQuotaError,
+ NKikimrBlobStorage::TPDiskState::DeviceIoError,
};
constexpr NCms::EPDiskState FaultyStates[] = {
- NKikimrBlobStorage::TPDiskState::Initial,
- NKikimrBlobStorage::TPDiskState::InitialFormatRead,
- NKikimrBlobStorage::TPDiskState::InitialSysLogRead,
- NKikimrBlobStorage::TPDiskState::InitialCommonLogRead,
+ NKikimrBlobStorage::TPDiskState::Initial,
+ NKikimrBlobStorage::TPDiskState::InitialFormatRead,
+ NKikimrBlobStorage::TPDiskState::InitialSysLogRead,
+ NKikimrBlobStorage::TPDiskState::InitialCommonLogRead,
};
Y_UNIT_TEST_SUITE(TSentinelBaseTests) {
@@ -146,17 +146,17 @@ Y_UNIT_TEST_SUITE(TSentinelBaseTests) {
const ui64 id = (dc << 32) | (rack << 16) | node;
const TString name = TStringBuilder() << "dc_" << dc << "-rack_" << rack << "-node_" << node;
- NActorsInterconnect::TNodeLocation location;
- if (!anyDC) {
- location.SetDataCenter(ToString(dc + 1));
- }
- if (!anyRack) {
- location.SetRack(ToString(rack + 1));
- }
- location.SetUnit(ToString(id));
+ NActorsInterconnect::TNodeLocation location;
+ if (!anyDC) {
+ location.SetDataCenter(ToString(dc + 1));
+ }
+ if (!anyRack) {
+ location.SetRack(ToString(rack + 1));
+ }
+ location.SetUnit(ToString(id));
state->ClusterInfo->AddNode(TEvInterconnect::TNodeInfo(id, name, name, name, 10000, TNodeLocation(location)), nullptr);
-
+
NKikimrBlobStorage::TBaseConfig::TPDisk pdisk;
pdisk.SetNodeId(id);
pdisk.SetPDiskId(0);
@@ -499,9 +499,9 @@ Y_UNIT_TEST_SUITE(TSentinelTests) {
TTestEnv env(8, 4);
const auto reservedStates = TVector<EPDiskState>{
- NKikimrBlobStorage::TPDiskState::Reserved14,
- NKikimrBlobStorage::TPDiskState::Reserved15,
- NKikimrBlobStorage::TPDiskState::Reserved16,
+ NKikimrBlobStorage::TPDiskState::Reserved14,
+ NKikimrBlobStorage::TPDiskState::Reserved15,
+ NKikimrBlobStorage::TPDiskState::Reserved16,
};
for (const auto state : reservedStates) {
diff --git a/ydb/core/cms/walle_api_handler.cpp b/ydb/core/cms/walle_api_handler.cpp
index 7b62f3275a9..884fa6fe5d0 100644
--- a/ydb/core/cms/walle_api_handler.cpp
+++ b/ydb/core/cms/walle_api_handler.cpp
@@ -21,9 +21,9 @@ class TWalleCrateTaskHandler : public TActorBootstrapped<TWalleCrateTaskHandler>
public:
using TBase = TActorBootstrapped<TWalleCrateTaskHandler>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
+ return NKikimrServices::TActivity::CMS_SERVICE_PROXY;
}
TWalleCrateTaskHandler(NMon::TEvHttpInfo::TPtr &event)
diff --git a/ydb/core/cms/walle_check_task_adapter.cpp b/ydb/core/cms/walle_check_task_adapter.cpp
index e5570c9af91..60d7ad42197 100644
--- a/ydb/core/cms/walle_check_task_adapter.cpp
+++ b/ydb/core/cms/walle_check_task_adapter.cpp
@@ -11,8 +11,8 @@ using namespace NNodeWhiteboard;
class TWalleCheckTaskAdapter : public TActorBootstrapped<TWalleCheckTaskAdapter> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::CMS_WALLE_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::CMS_WALLE_REQ;
}
TWalleCheckTaskAdapter(TEvCms::TEvWalleCheckTaskRequest::TPtr &event,
diff --git a/ydb/core/cms/walle_create_task_adapter.cpp b/ydb/core/cms/walle_create_task_adapter.cpp
index 56989e2db03..78d3285dfc4 100644
--- a/ydb/core/cms/walle_create_task_adapter.cpp
+++ b/ydb/core/cms/walle_create_task_adapter.cpp
@@ -12,8 +12,8 @@ using namespace NKikimrCms;
class TWalleCreateTaskAdapter : public TActorBootstrapped<TWalleCreateTaskAdapter> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::CMS_WALLE_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::CMS_WALLE_REQ;
}
TWalleCreateTaskAdapter(TEvCms::TEvWalleCreateTaskRequest::TPtr &event, TActorId cms)
diff --git a/ydb/core/cms/walle_list_tasks_adapter.cpp b/ydb/core/cms/walle_list_tasks_adapter.cpp
index d256294cc18..1a681af5e53 100644
--- a/ydb/core/cms/walle_list_tasks_adapter.cpp
+++ b/ydb/core/cms/walle_list_tasks_adapter.cpp
@@ -11,8 +11,8 @@ using namespace NNodeWhiteboard;
class TWalleListTasksAdapter : public TActorBootstrapped<TWalleListTasksAdapter> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::CMS_WALLE_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::CMS_WALLE_REQ;
}
TWalleListTasksAdapter(TEvCms::TEvWalleListTasksRequest::TPtr &event, const TCmsStatePtr state)
diff --git a/ydb/core/cms/walle_remove_task_adapter.cpp b/ydb/core/cms/walle_remove_task_adapter.cpp
index 899d4848250..b29c6fd9ba9 100644
--- a/ydb/core/cms/walle_remove_task_adapter.cpp
+++ b/ydb/core/cms/walle_remove_task_adapter.cpp
@@ -11,8 +11,8 @@ using namespace NNodeWhiteboard;
class TWalleRemoveTaskAdapter : public TActorBootstrapped<TWalleRemoveTaskAdapter> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::CMS_WALLE_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::CMS_WALLE_REQ;
}
TWalleRemoveTaskAdapter(TEvCms::TEvWalleRemoveTaskRequest::TPtr &event, const TCmsStatePtr state, TActorId cms)
diff --git a/ydb/core/control/immediate_control_board_actor.cpp b/ydb/core/control/immediate_control_board_actor.cpp
index bcb4a3344c3..65543d64498 100644
--- a/ydb/core/control/immediate_control_board_actor.cpp
+++ b/ydb/core/control/immediate_control_board_actor.cpp
@@ -40,8 +40,8 @@ class TImmediateControlActor : public TActorBootstrapped<TImmediateControlActor>
NMonitoring::TDynamicCounters::TCounterPtr ChangedCount;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::IMMEDIATE_CONTROL_BOARD;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::IMMEDIATE_CONTROL_BOARD;
}
TImmediateControlActor(TIntrusivePtr<TControlBoard> board,
diff --git a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
index 450d4135c6c..39620881827 100644
--- a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
+++ b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
@@ -31,7 +31,7 @@ public:
: TClientCommand("mkdir", {}, "Create directory")
{}
- TAutoPtr<NKikimrClient::TSchemeOperation> Request;
+ TAutoPtr<NKikimrClient::TSchemeOperation> Request;
virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
@@ -62,11 +62,11 @@ public:
}
virtual int Run(TConfig& config) override {
- auto handler = [this](NClient::TKikimr& kikimr) {
- kikimr.GetSchemaRoot(Base).MakeDirectory(Name);
- return 0;
- };
- return InvokeThroughKikimr(config, std::move(handler));
+ auto handler = [this](NClient::TKikimr& kikimr) {
+ kikimr.GetSchemaRoot(Base).MakeDirectory(Name);
+ return 0;
+ };
+ return InvokeThroughKikimr(config, std::move(handler));
}
};
@@ -138,7 +138,7 @@ public:
NKikimrSchemeOp::TModifyScript protoScript;
ParseProtobuf(&protoScript, config.ParseResult->GetFreeArgs()[0]);
for (const auto& modifyScheme : protoScript.GetModifyScheme()) {
- TAutoPtr<NKikimrClient::TSchemeOperation> request = new NKikimrClient::TSchemeOperation();
+ TAutoPtr<NKikimrClient::TSchemeOperation> request = new NKikimrClient::TSchemeOperation();
request->MutablePollOptions()->SetTimeout(NClient::TKikimr::POLLING_TIMEOUT);
request->MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
Requests.emplace_back(request);
@@ -148,9 +148,9 @@ public:
virtual int Run(TConfig& config) override {
int result = 0;
for (const auto& pbRequest : Requests) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
request->Record.MergeFrom(*pbRequest);
- result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
+ result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[this](const NMsgBusProxy::TBusResponse& response) -> int {
if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
@@ -179,7 +179,7 @@ public:
: TClientCommand("describe", { "desc" }, "Describe schema object")
{}
- TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
+ TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
TString Path;
bool Tree;
bool Details;
@@ -214,7 +214,7 @@ public:
virtual void Parse(TConfig& config) override {
TClientCommand::Parse(config);
- Request = new NKikimrClient::TSchemeDescribe();
+ Request = new NKikimrClient::TSchemeDescribe();
Path = config.ParseResult->GetFreeArgs()[0];
if (Path.StartsWith('/')) {
Request->SetPath(Path);
@@ -390,14 +390,14 @@ public:
}
virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
if (Request != nullptr)
request->Record.MergeFrom(*Request);
TList<NKikimrSchemeOp::TPathDescription> entries;
for(;;) {
- MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
+ MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
[&entries](const NMsgBusProxy::TBusResponse& response) -> int {
entries.push_front(response.Record.GetPathDescription());
return 0;
@@ -407,7 +407,7 @@ public:
&& entries.front().GetSelf().HasParentPathId()
&& entries.front().GetSelf().HasSchemeshardId()
&& entries.front().GetSelf().GetParentPathId() != entries.front().GetSelf().GetPathId()) {
- request = new NMsgBusProxy::TBusSchemeDescribe();
+ request = new NMsgBusProxy::TBusSchemeDescribe();
request->Record.SetSchemeshardId(entries.front().GetSelf().GetSchemeshardId());
request->Record.SetPathId(entries.front().GetSelf().GetParentPathId());
continue;
@@ -434,7 +434,7 @@ public:
: TClientCommand("ls", {}, "List schema object or path content")
{}
- TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
+ TAutoPtr<NKikimrClient::TSchemeDescribe> Request;
virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
@@ -444,16 +444,16 @@ public:
virtual void Parse(TConfig& config) override {
TClientCommand::Parse(config);
- Request = new NKikimrClient::TSchemeDescribe();
+ Request = new NKikimrClient::TSchemeDescribe();
Request->SetPath(config.ParseResult->GetFreeArgs()[0]);
}
virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
if (Request != nullptr)
request->Record.MergeFrom(*Request);
- return MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
+ return MessageBusCall<NMsgBusProxy::TBusSchemeDescribe, NMsgBusProxy::TBusResponse>(config, request,
[this](const NMsgBusProxy::TBusResponse& response) -> int {
return PrintResponse(response);
});
@@ -495,7 +495,7 @@ public:
}
int PrintResponse(const NMsgBusProxy::TBusResponse& response) const {
- const NKikimrClient::TResponse& record(response.Record);
+ const NKikimrClient::TResponse& record(response.Record);
const auto& description(record.GetPathDescription());
if (description.GetSelf().GetPathType() == NKikimrSchemeOp::EPathTypeDir
|| description.GetSelf().GetPathType() == NKikimrSchemeOp::EPathTypeSubDomain
@@ -516,7 +516,7 @@ public:
: TClientCommand("init", {}, "Initialize schema root")
{}
- TAutoPtr<NKikimrClient::TSchemeInitRoot> Request;
+ TAutoPtr<NKikimrClient::TSchemeInitRoot> Request;
TString Root;
TString DefaultStoragePool;
@@ -529,7 +529,7 @@ public:
virtual void Parse(TConfig& config) override {
TClientCommand::Parse(config);
- Request = new NKikimrClient::TSchemeInitRoot();
+ Request = new NKikimrClient::TSchemeInitRoot();
Root = config.ParseResult->GetFreeArgs()[0];
if (Root.StartsWith('/'))
Root = Root.substr(1);
@@ -558,7 +558,7 @@ public:
: TClientCommand("chown", {}, "Change owner")
{}
- TAutoPtr<NKikimrClient::TSchemeOperation> Request;
+ TAutoPtr<NKikimrClient::TSchemeOperation> Request;
bool Recursive = false;
bool Verbose = false;
@@ -596,8 +596,8 @@ public:
size_t pos = path.rfind('/');
TString base = path.substr(0, pos);
TString name = path.substr(pos + 1);
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- NKikimrClient::TSchemeOperation& record(request->Record);
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ NKikimrClient::TSchemeOperation& record(request->Record);
auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
modifyScheme.SetWorkingDir(base);
@@ -607,7 +607,7 @@ public:
if (Verbose) {
Cout << path << Endl;
}
- int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
+ int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[path](const NMsgBusProxy::TBusResponse& response) -> int {
if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
Cerr << path << ' ' << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
@@ -658,7 +658,7 @@ public:
: TClientCommand("add", {}, "Add access right")
{}
- TAutoPtr<NKikimrClient::TSchemeOperation> Request;
+ TAutoPtr<NKikimrClient::TSchemeOperation> Request;
virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
@@ -694,8 +694,8 @@ public:
}
virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- NKikimrClient::TSchemeOperation& record(request->Record);
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ NKikimrClient::TSchemeOperation& record(request->Record);
auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
modifyScheme.SetWorkingDir(Base);
@@ -711,7 +711,7 @@ public:
diffAcl.AddAccess(ace);
}
modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
- int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
+ int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[](const NMsgBusProxy::TBusResponse& response) -> int {
if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
@@ -729,7 +729,7 @@ public:
: TClientCommand("remove", {}, "Remove access right")
{}
- TAutoPtr<NKikimrClient::TSchemeOperation> Request;
+ TAutoPtr<NKikimrClient::TSchemeOperation> Request;
virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
@@ -765,8 +765,8 @@ public:
}
virtual int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
- NKikimrClient::TSchemeOperation& record(request->Record);
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ NKikimrClient::TSchemeOperation& record(request->Record);
auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
modifyScheme.SetWorkingDir(Base);
@@ -779,7 +779,7 @@ public:
diffAcl.RemoveAccess(ace);
}
modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
- int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
+ int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[](const NMsgBusProxy::TBusResponse& response) -> int {
if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
@@ -1308,24 +1308,24 @@ public:
}
virtual int Run(TConfig& config) override {
- auto handler = [this](NClient::TKikimr& kikimr) {
- NClient::TTextQuery query(kikimr.Query(MiniKQL));
-
- NThreading::TFuture<NClient::TQueryResult> future;
- if (Proto) {
- NKikimrMiniKQL::TParams mkqlParams;
- NClient::TQuery::ParseTextParameters(mkqlParams, Params);
- future = query.AsyncExecute(mkqlParams);
- } else {
- future = query.AsyncExecute(Params);
- }
-
- return HandleResponse<NClient::TQueryResult>(future, [](const NClient::TQueryResult& result) -> int {
- Cout << result.GetValue().GetValueText<NClient::TFormatJSON>() << '\n';
- return 0;
- });
- };
- return InvokeThroughKikimr(config, std::move(handler));
+ auto handler = [this](NClient::TKikimr& kikimr) {
+ NClient::TTextQuery query(kikimr.Query(MiniKQL));
+
+ NThreading::TFuture<NClient::TQueryResult> future;
+ if (Proto) {
+ NKikimrMiniKQL::TParams mkqlParams;
+ NClient::TQuery::ParseTextParameters(mkqlParams, Params);
+ future = query.AsyncExecute(mkqlParams);
+ } else {
+ future = query.AsyncExecute(Params);
+ }
+
+ return HandleResponse<NClient::TQueryResult>(future, [](const NClient::TQueryResult& result) -> int {
+ Cout << result.GetValue().GetValueText<NClient::TFormatJSON>() << '\n';
+ return 0;
+ });
+ };
+ return InvokeThroughKikimr(config, std::move(handler));
}
};
diff --git a/ydb/core/driver_lib/cli_config_base/config_base.h b/ydb/core/driver_lib/cli_config_base/config_base.h
index 6db66dc7d1b..728325cc6fa 100644
--- a/ydb/core/driver_lib/cli_config_base/config_base.h
+++ b/ydb/core/driver_lib/cli_config_base/config_base.h
@@ -15,7 +15,7 @@
#include <util/generic/strbuf.h>
#include <util/generic/string.h>
#include <util/generic/yexception.h>
-#include <util/generic/variant.h>
+#include <util/generic/variant.h>
#include <util/stream/file.h>
#include <util/stream/format.h>
diff --git a/ydb/core/driver_lib/cli_utils/cli.h b/ydb/core/driver_lib/cli_utils/cli.h
index 099664792ea..38f2e414e61 100644
--- a/ydb/core/driver_lib/cli_utils/cli.h
+++ b/ydb/core/driver_lib/cli_utils/cli.h
@@ -35,7 +35,7 @@ namespace NDriverClient {
int PersQueueRequest(TCommandConfig &cmdConf, int argc, char **argv);
int PersQueueStress(TCommandConfig &cmdConf, int argc, char **argv);
int PersQueueDiscoverClustersRequest(TCommandConfig &cmdConf, int argc, char **argv);
- int LoadRequest(TCommandConfig &cmdConf, int argc, char **argv);
+ int LoadRequest(TCommandConfig &cmdConf, int argc, char **argv);
int ActorsysPerfTest(TCommandConfig &cmdConf, int argc, char **argv);
void HideOptions(NLastGetopt::TOpts& opts, const TString& prefix);
void HideOptions(NLastGetopt::TOpts& opts);
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp b/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
index fcc93059966..499135029de 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmd_config.cpp
@@ -10,7 +10,7 @@ namespace NDriverClient {
opts.AddHelpOption('h');
opts.AddLongOption('s', "server", "server address to connect")
- .RequiredArgument("ADDR").StoreResult(&Address);
+ .RequiredArgument("ADDR").StoreResult(&Address);
opts.SetFreeArgTitle(0, "mbus", "- use to override message bus client default settings");
opts.SetFreeArgsMin(0);
@@ -39,20 +39,20 @@ namespace NDriverClient {
endpoint.Address,
MsgBusClientConfig.Ip,
MsgBusClientConfig.Port);
- }
- SetMsgBusDefaults(MsgBusClientConfig.BusSessionConfig, MsgBusClientConfig.BusQueueConfig);
- if ((res.GetFreeArgCount() > 0) && (res.GetFreeArgs().at(0) == "mbus")) {
- size_t freeArgsPos = res.GetFreeArgsPos();
- argc -= freeArgsPos;
- argv += freeArgsPos;
- NLastGetopt::TOpts msgBusOpts = NLastGetopt::TOpts::Default();
- msgBusOpts.AddHelpOption('h');
- MsgBusClientConfig.ConfigureLastGetopt(msgBusOpts);
- NLastGetopt::TOptsParseResult mbusRes(&msgBusOpts, argc, argv);
- Y_UNUSED(mbusRes);
- }
-
- ClientConfig = MsgBusClientConfig;
+ }
+ SetMsgBusDefaults(MsgBusClientConfig.BusSessionConfig, MsgBusClientConfig.BusQueueConfig);
+ if ((res.GetFreeArgCount() > 0) && (res.GetFreeArgs().at(0) == "mbus")) {
+ size_t freeArgsPos = res.GetFreeArgsPos();
+ argc -= freeArgsPos;
+ argv += freeArgsPos;
+ NLastGetopt::TOpts msgBusOpts = NLastGetopt::TOpts::Default();
+ msgBusOpts.AddHelpOption('h');
+ MsgBusClientConfig.ConfigureLastGetopt(msgBusOpts);
+ NLastGetopt::TOptsParseResult mbusRes(&msgBusOpts, argc, argv);
+ Y_UNUSED(mbusRes);
+ }
+
+ ClientConfig = MsgBusClientConfig;
break;
}
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmd_config.h b/ydb/core/driver_lib/cli_utils/cli_cmd_config.h
index bb0b69dbcb6..3bdc0e0885d 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmd_config.h
+++ b/ydb/core/driver_lib/cli_utils/cli_cmd_config.h
@@ -2,52 +2,52 @@
#include <ydb/public/lib/deprecated/kicli/kicli.h>
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
#include <ydb/public/lib/deprecated/client/grpc_client.h>
-#include <util/generic/variant.h>
+#include <util/generic/variant.h>
namespace NKikimr {
namespace NDriverClient {
struct TCliCmdConfig : TNonCopyable {
TMaybe<std::variant<NMsgBusProxy::TMsgBusClientConfig, NGRpcProxy::TGRpcClientConfig>> ClientConfig;
- NMsgBusProxy::TMsgBusClientConfig MsgBusClientConfig;
- TString Address;
+ NMsgBusProxy::TMsgBusClientConfig MsgBusClientConfig;
+ TString Address;
void ConfigureBaseLastGetopt(NLastGetopt::TOpts &opts);
void ConfigureMsgBusLastGetopt(const NLastGetopt::TOptsParseResult& res, int argc, char** argv);
-
- template<typename TRequest>
- NBus::EMessageStatus SyncCall(TAutoPtr<TRequest> request, TAutoPtr<NBus::TBusMessage>& response) const {
- auto visitor = [&](const auto& config) {
- NClient::TKikimr kikimr(config);
- auto future = kikimr.ExecuteRequest(request.Release());
- auto data = future.GetValue(TDuration::Max());
- if (data.GetTransportStatus() == NBus::MESSAGE_OK) {
- switch (data.GetType()) {
- case NMsgBusProxy::MTYPE_CLIENT_RESPONSE: {
- TAutoPtr<NMsgBusProxy::TBusResponse> x(new NMsgBusProxy::TBusResponse);
- x->Record = data.template GetResult<NKikimrClient::TResponse>();
- response = x.Release();
- break;
- }
-
- case NMsgBusProxy::MTYPE_CLIENT_LOAD_RESPONSE: {
- TAutoPtr<NMsgBusProxy::TBusBsTestLoadResponse> x(new NMsgBusProxy::TBusBsTestLoadResponse);
- x->Record = data.template GetResult<NKikimrClient::TBsTestLoadResponse>();
- response = x.Release();
- break;
- }
-
- default:
- Y_FAIL("unexpected reply message type");
- }
- }
- return data.GetTransportStatus();
- };
- if (const auto& conf = ClientConfig) {
+
+ template<typename TRequest>
+ NBus::EMessageStatus SyncCall(TAutoPtr<TRequest> request, TAutoPtr<NBus::TBusMessage>& response) const {
+ auto visitor = [&](const auto& config) {
+ NClient::TKikimr kikimr(config);
+ auto future = kikimr.ExecuteRequest(request.Release());
+ auto data = future.GetValue(TDuration::Max());
+ if (data.GetTransportStatus() == NBus::MESSAGE_OK) {
+ switch (data.GetType()) {
+ case NMsgBusProxy::MTYPE_CLIENT_RESPONSE: {
+ TAutoPtr<NMsgBusProxy::TBusResponse> x(new NMsgBusProxy::TBusResponse);
+ x->Record = data.template GetResult<NKikimrClient::TResponse>();
+ response = x.Release();
+ break;
+ }
+
+ case NMsgBusProxy::MTYPE_CLIENT_LOAD_RESPONSE: {
+ TAutoPtr<NMsgBusProxy::TBusBsTestLoadResponse> x(new NMsgBusProxy::TBusBsTestLoadResponse);
+ x->Record = data.template GetResult<NKikimrClient::TBsTestLoadResponse>();
+ response = x.Release();
+ break;
+ }
+
+ default:
+ Y_FAIL("unexpected reply message type");
+ }
+ }
+ return data.GetTransportStatus();
+ };
+ if (const auto& conf = ClientConfig) {
return std::visit(std::move(visitor), *conf);
- } else {
- Y_FAIL("Client configuration is not provided");
- }
- }
+ } else {
+ Y_FAIL("Client configuration is not provided");
+ }
+ }
};
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
index ef731708bf8..e38032ad805 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_bs.cpp
@@ -15,9 +15,9 @@ TClientCommandBlobStorage::TClientCommandBlobStorage()
{
AddCommand(CreateClientCommandDisk());
AddCommand(CreateClientCommandGroup());
- AddCommand(CreateClientCommandGenConfig());
- AddCommand(CreateClientCommandGet());
- AddCommand(CreateClientCommandBsConfig());
+ AddCommand(CreateClientCommandGenConfig());
+ AddCommand(CreateClientCommandGet());
+ AddCommand(CreateClientCommandBsConfig());
}
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_config.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_config.cpp
index aae54255e91..4caac4329d0 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_config.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_config.cpp
@@ -1,74 +1,74 @@
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/protos/config.pb.h>
#include <ydb/library/yaml_config/yaml_config_parser.h>
-#include "cli.h"
-#include "cli_cmds.h"
-#include "proto_common.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-class TProposeStoragePools : public TClientCommand {
- ui32 AvailabilityDomain = 1;
-
-public:
- TProposeStoragePools()
- : TClientCommand("storage-pools", {"sp"}, "Propose cluster Storage Pool configuration for migration")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("domain", "availability domain")
- .Optional()
- .RequiredArgument("NUM")
- .StoreResult(&AvailabilityDomain);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> msg(new NMsgBusProxy::TBusBlobStorageConfigRequest);
-
- NKikimrClient::TBlobStorageConfigRequest& request = msg->Record;
- request.SetDomain(AvailabilityDomain);
- if (config.SecurityToken) {
- request.SetSecurityToken(config.SecurityToken);
- }
-
- auto *cmd = request.MutableRequest()->AddCommand();
- cmd->MutableProposeStoragePools();
-
+#include "cli.h"
+#include "cli_cmds.h"
+#include "proto_common.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+class TProposeStoragePools : public TClientCommand {
+ ui32 AvailabilityDomain = 1;
+
+public:
+ TProposeStoragePools()
+ : TClientCommand("storage-pools", {"sp"}, "Propose cluster Storage Pool configuration for migration")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("domain", "availability domain")
+ .Optional()
+ .RequiredArgument("NUM")
+ .StoreResult(&AvailabilityDomain);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> msg(new NMsgBusProxy::TBusBlobStorageConfigRequest);
+
+ NKikimrClient::TBlobStorageConfigRequest& request = msg->Record;
+ request.SetDomain(AvailabilityDomain);
+ if (config.SecurityToken) {
+ request.SetSecurityToken(config.SecurityToken);
+ }
+
+ auto *cmd = request.MutableRequest()->AddCommand();
+ cmd->MutableProposeStoragePools();
+
auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- const auto& record = response.Record;
- if (!record.HasBlobStorageConfigResponse()) {
- return 1;
- } else {
- NKikimrBlobStorage::TConfigRequest cmd;
- for (const auto &status : record.GetBlobStorageConfigResponse().GetStatus()) {
- if (!status.GetSuccess()) {
- Cerr << "ProposeStoragePools command failed: " << status.GetErrorDescription() << Endl;
- return 2;
- }
- for (const auto &sp : status.GetStoragePool()) {
- cmd.AddCommand()->MutableDefineStoragePool()->CopyFrom(sp);
- }
- }
-
- TString data;
- if (google::protobuf::TextFormat::PrintToString(cmd, &data)) {
- Cout << data;
- } else {
- Cerr << "PrintToString failed" << Endl;
- return 3;
- }
-
- return 0;
- }
-
- return record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusBlobStorageConfigRequest, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
+ const auto& record = response.Record;
+ if (!record.HasBlobStorageConfigResponse()) {
+ return 1;
+ } else {
+ NKikimrBlobStorage::TConfigRequest cmd;
+ for (const auto &status : record.GetBlobStorageConfigResponse().GetStatus()) {
+ if (!status.GetSuccess()) {
+ Cerr << "ProposeStoragePools command failed: " << status.GetErrorDescription() << Endl;
+ return 2;
+ }
+ for (const auto &sp : status.GetStoragePool()) {
+ cmd.AddCommand()->MutableDefineStoragePool()->CopyFrom(sp);
+ }
+ }
+
+ TString data;
+ if (google::protobuf::TextFormat::PrintToString(cmd, &data)) {
+ Cout << data;
+ } else {
+ Cerr << "PrintToString failed" << Endl;
+ return 3;
+ }
+
+ return 0;
+ }
+
+ return record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusBlobStorageConfigRequest, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
class TInit : public TClientCommand {
ui32 AvailabilityDomain = 1;
TString YamlFile;
@@ -148,118 +148,118 @@ public:
};
-class TInvoke : public TClientCommand {
- ui32 AvailabilityDomain = 1;
- TString ProtoFile;
- TString Protobuf;
- bool DryRun = false;
-
-public:
- TInvoke()
- : TClientCommand("invoke", {}, "Query or update blob storage configuration")
- {}
-
- void Config(TConfig& config) override {
- TClientCommand::Config(config);
-
- config.Opts->AddLongOption("domain", "availability domain")
- .Optional()
- .RequiredArgument("NUM")
- .StoreResult(&AvailabilityDomain);
-
- config.Opts->AddLongOption("proto-file", "read protobuf query from file")
- .Optional()
- .RequiredArgument("PATH")
- .StoreResult(&ProtoFile);
-
- config.Opts->AddLongOption("proto", "query protobuf")
- .Optional()
- .RequiredArgument("PROTOBUF")
- .StoreResult(&Protobuf);
-
- config.Opts->AddLongOption('n', "dry-run", "do not apply updates")
- .Optional()
- .NoArgument()
- .SetFlag(&DryRun);
- }
-
- int Run(TConfig& config) override {
- TString data;
-
- if (ProtoFile) {
- try {
+class TInvoke : public TClientCommand {
+ ui32 AvailabilityDomain = 1;
+ TString ProtoFile;
+ TString Protobuf;
+ bool DryRun = false;
+
+public:
+ TInvoke()
+ : TClientCommand("invoke", {}, "Query or update blob storage configuration")
+ {}
+
+ void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+
+ config.Opts->AddLongOption("domain", "availability domain")
+ .Optional()
+ .RequiredArgument("NUM")
+ .StoreResult(&AvailabilityDomain);
+
+ config.Opts->AddLongOption("proto-file", "read protobuf query from file")
+ .Optional()
+ .RequiredArgument("PATH")
+ .StoreResult(&ProtoFile);
+
+ config.Opts->AddLongOption("proto", "query protobuf")
+ .Optional()
+ .RequiredArgument("PROTOBUF")
+ .StoreResult(&Protobuf);
+
+ config.Opts->AddLongOption('n', "dry-run", "do not apply updates")
+ .Optional()
+ .NoArgument()
+ .SetFlag(&DryRun);
+ }
+
+ int Run(TConfig& config) override {
+ TString data;
+
+ if (ProtoFile) {
+ try {
data = TUnbufferedFileInput(ProtoFile).ReadAll();
- } catch (const yexception& ex) {
- Cerr << "failed to ready query from file: " << ex.what() << Endl;
- return EXIT_FAILURE;
- }
- } else if (Protobuf) {
- data = std::move(Protobuf);
- } else {
- Cerr << "either --proto-file or --proto must be provided" << Endl;
- return EXIT_FAILURE;
- }
-
- TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> msg(new NMsgBusProxy::TBusBlobStorageConfigRequest);
-
- NKikimrClient::TBlobStorageConfigRequest& request = msg->Record;
- request.SetDomain(AvailabilityDomain);
- if (config.SecurityToken) {
- request.SetSecurityToken(config.SecurityToken);
- }
- bool success = google::protobuf::TextFormat::ParseFromString(data, request.MutableRequest());
- if (!success) {
- Cerr << "failed to parse input protobuf" << Endl;
- return EXIT_FAILURE;
- }
-
- if (DryRun) {
- request.MutableRequest()->SetRollback(true);
- }
-
+ } catch (const yexception& ex) {
+ Cerr << "failed to ready query from file: " << ex.what() << Endl;
+ return EXIT_FAILURE;
+ }
+ } else if (Protobuf) {
+ data = std::move(Protobuf);
+ } else {
+ Cerr << "either --proto-file or --proto must be provided" << Endl;
+ return EXIT_FAILURE;
+ }
+
+ TAutoPtr<NMsgBusProxy::TBusBlobStorageConfigRequest> msg(new NMsgBusProxy::TBusBlobStorageConfigRequest);
+
+ NKikimrClient::TBlobStorageConfigRequest& request = msg->Record;
+ request.SetDomain(AvailabilityDomain);
+ if (config.SecurityToken) {
+ request.SetSecurityToken(config.SecurityToken);
+ }
+ bool success = google::protobuf::TextFormat::ParseFromString(data, request.MutableRequest());
+ if (!success) {
+ Cerr << "failed to parse input protobuf" << Endl;
+ return EXIT_FAILURE;
+ }
+
+ if (DryRun) {
+ request.MutableRequest()->SetRollback(true);
+ }
+
auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- const auto& record = response.Record;
- if (record.HasBlobStorageConfigResponse()) {
- TString data;
- const auto& response = record.GetBlobStorageConfigResponse();
- if (google::protobuf::TextFormat::PrintToString(response, &data)) {
- Cout << data;
- } else {
- Cerr << "failed to print protobuf" << Endl;
- return EXIT_FAILURE;
- }
- return response.GetSuccess() ? EXIT_SUCCESS : 2;
- }
- return record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? EXIT_SUCCESS : EXIT_FAILURE;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusBlobStorageConfigRequest, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TPropose : public TClientCommandTree {
-public:
- TPropose()
- : TClientCommandTree("propose", {}, "Configuration proposition for migration and initial configuring")
- {
+ const auto& record = response.Record;
+ if (record.HasBlobStorageConfigResponse()) {
+ TString data;
+ const auto& response = record.GetBlobStorageConfigResponse();
+ if (google::protobuf::TextFormat::PrintToString(response, &data)) {
+ Cout << data;
+ } else {
+ Cerr << "failed to print protobuf" << Endl;
+ return EXIT_FAILURE;
+ }
+ return response.GetSuccess() ? EXIT_SUCCESS : 2;
+ }
+ return record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? EXIT_SUCCESS : EXIT_FAILURE;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusBlobStorageConfigRequest, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TPropose : public TClientCommandTree {
+public:
+ TPropose()
+ : TClientCommandTree("propose", {}, "Configuration proposition for migration and initial configuring")
+ {
AddCommand(std::make_unique<TProposeStoragePools>());
- }
-};
-
-class TClientCommandBsConfig : public TClientCommandTree {
-public:
- TClientCommandBsConfig()
- : TClientCommandTree("config", {}, "Configuration management")
- {
+ }
+};
+
+class TClientCommandBsConfig : public TClientCommandTree {
+public:
+ TClientCommandBsConfig()
+ : TClientCommandTree("config", {}, "Configuration management")
+ {
AddCommand(std::make_unique<TPropose>());
AddCommand(std::make_unique<TInvoke>());
AddCommand(std::make_unique<TInit>());
- }
-};
-
+ }
+};
+
std::unique_ptr<TClientCommand> CreateClientCommandBsConfig() {
return std::make_unique<TClientCommandBsConfig>();
-}
-
-} // NDriverClient
-} // NKikimr
+}
+
+} // NDriverClient
+} // NKikimr
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
index 9cd9e582fa8..73abd877f06 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_debug.cpp
@@ -5,295 +5,295 @@
namespace NKikimr {
namespace NDriverClient {
-class TInterconnectLoad : public TClientCommand {
- TString Name;
- ui32 Channel = 0;
- TString Hops;
- ui32 SizeMin = 0;
- ui32 SizeMax = 0;
- ui32 InFlyMax = 0;
- TDuration IntervalMin;
- TDuration IntervalMax;
- bool Soft = false;
- TDuration Duration;
- bool UseProtobufWithPayload = false;
- TString ServicePool;
-
-public:
- TInterconnectLoad()
- : TClientCommand("load", {}, "Initiate load actor on Interconnect")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("name", "load name to distinguish between several load processes")
- .Optional()
- .RequiredArgument()
- .StoreResult(&Name);
-
- config.Opts->AddLongOption("channel", "Interconnect channel number")
- .Optional()
- .RequiredArgument()
- .StoreResult(&Channel);
-
- config.Opts->AddLongOption("hops", "comma-separated list of node ids making up packet route")
- .Required()
- .RequiredArgument()
- .StoreResult(&Hops);
-
- config.Opts->AddLongOption("size-min", "minimal size of payload")
- .Optional()
- .RequiredArgument()
- .StoreResult(&SizeMin);
-
- config.Opts->AddLongOption("size-max", "maximal size of payload")
- .Optional()
- .RequiredArgument()
- .StoreResult(&SizeMax);
-
- config.Opts->AddLongOption("infly", "maximal number of unanswered packets")
- .Required()
- .RequiredArgument()
- .StoreResult(&InFlyMax);
-
- config.Opts->AddLongOption("interval-min", "minimal interval between messages")
- .Optional()
- .RequiredArgument()
- .StoreResult(&IntervalMin);
-
- config.Opts->AddLongOption("interval-max", "maximal interval between messages")
- .Optional()
- .RequiredArgument()
- .StoreResult(&IntervalMax);
-
- config.Opts->AddLongOption("soft", "enable soft load")
- .Optional()
- .NoArgument()
- .StoreTrue(&Soft);
-
- config.Opts->AddLongOption("rope", "use ropes for payload instead of protobuf")
- .Optional()
- .NoArgument()
- .StoreTrue(&UseProtobufWithPayload);
-
- config.Opts->AddLongOption("duration", "test duration")
- .Required()
- .RequiredArgument()
- .StoreResult(&Duration);
-
- config.Opts->AddLongOption("service-pool", "service pool name")
- .RequiredArgument()
- .StoreResult(&ServicePool);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
-
- NKikimrClient::TInterconnectDebug& request = msg->Record;
- request.SetName(Name);
- request.SetChannel(Channel);
-
- TVector<TString> nodes;
+class TInterconnectLoad : public TClientCommand {
+ TString Name;
+ ui32 Channel = 0;
+ TString Hops;
+ ui32 SizeMin = 0;
+ ui32 SizeMax = 0;
+ ui32 InFlyMax = 0;
+ TDuration IntervalMin;
+ TDuration IntervalMax;
+ bool Soft = false;
+ TDuration Duration;
+ bool UseProtobufWithPayload = false;
+ TString ServicePool;
+
+public:
+ TInterconnectLoad()
+ : TClientCommand("load", {}, "Initiate load actor on Interconnect")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("name", "load name to distinguish between several load processes")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&Name);
+
+ config.Opts->AddLongOption("channel", "Interconnect channel number")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&Channel);
+
+ config.Opts->AddLongOption("hops", "comma-separated list of node ids making up packet route")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&Hops);
+
+ config.Opts->AddLongOption("size-min", "minimal size of payload")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&SizeMin);
+
+ config.Opts->AddLongOption("size-max", "maximal size of payload")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&SizeMax);
+
+ config.Opts->AddLongOption("infly", "maximal number of unanswered packets")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&InFlyMax);
+
+ config.Opts->AddLongOption("interval-min", "minimal interval between messages")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&IntervalMin);
+
+ config.Opts->AddLongOption("interval-max", "maximal interval between messages")
+ .Optional()
+ .RequiredArgument()
+ .StoreResult(&IntervalMax);
+
+ config.Opts->AddLongOption("soft", "enable soft load")
+ .Optional()
+ .NoArgument()
+ .StoreTrue(&Soft);
+
+ config.Opts->AddLongOption("rope", "use ropes for payload instead of protobuf")
+ .Optional()
+ .NoArgument()
+ .StoreTrue(&UseProtobufWithPayload);
+
+ config.Opts->AddLongOption("duration", "test duration")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&Duration);
+
+ config.Opts->AddLongOption("service-pool", "service pool name")
+ .RequiredArgument()
+ .StoreResult(&ServicePool);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
+
+ NKikimrClient::TInterconnectDebug& request = msg->Record;
+ request.SetName(Name);
+ request.SetChannel(Channel);
+
+ TVector<TString> nodes;
StringSplitter(Hops).Split(',').AddTo(&nodes);
- for (const TString &node : nodes) {
- request.AddHops(FromString<ui32>(node));
- }
-
- request.SetSizeMin(SizeMin);
- request.SetSizeMax(SizeMax);
- request.SetInFlyMax(InFlyMax);
- request.SetIntervalMin(IntervalMin.GetValue());
- request.SetIntervalMax(IntervalMax.GetValue());
- request.SetSoftLoad(Soft);
- request.SetUseProtobufWithPayload(UseProtobufWithPayload);
- request.SetDuration(Duration.GetValue());
- if (ServicePool) {
- request.SetServicePool(ServicePool);
- }
-
- auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TInterconnectClosePeerSocket : public TClientCommand {
- ui32 NodeId = 0;
-
-public:
- TInterconnectClosePeerSocket()
- : TClientCommand("closepeersocket", {}, "Close peer socket on existing session")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("node", "peer node id to close socket for")
- .Required()
- .RequiredArgument()
- .StoreResult(&NodeId);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
-
- NKikimrClient::TInterconnectDebug& request = msg->Record;
- request.SetClosePeerSocketNodeId(NodeId);
-
- auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TInterconnectCloseInputSession : public TClientCommand {
- ui32 NodeId = 0;
-
-public:
- TInterconnectCloseInputSession()
- : TClientCommand("closeinputsession", {}, "Terminate input session")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("node", "peer node id to close input session for")
- .Required()
- .RequiredArgument()
- .StoreResult(&NodeId);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
-
- NKikimrClient::TInterconnectDebug& request = msg->Record;
- request.SetCloseInputSessionNodeId(NodeId);
-
- auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TInterconnectPoisonSession : public TClientCommand {
- ui32 NodeId = 0;
-
-public:
- TInterconnectPoisonSession()
- : TClientCommand("poisonsession", {}, "Poison session")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("node", "peer node id to poison session for")
- .Required()
- .RequiredArgument()
- .StoreResult(&NodeId);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
-
- NKikimrClient::TInterconnectDebug& request = msg->Record;
- request.SetPoisonSessionNodeId(NodeId);
-
- auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TInterconnectSlowpoke : public TClientCommand {
- ui32 NumActors = 0;
- ui32 PoolId = 0;
- TDuration SleepMin;
- TDuration SleepMax;
- TDuration RescheduleMin;
- TDuration RescheduleMax;
- TDuration Duration;
-
-public:
- TInterconnectSlowpoke()
- : TClientCommand("slowpoke", {}, "Make actor system work a bit worse")
- {}
-
- void Config(TConfig& config) override {
- config.Opts->AddLongOption("num-actors", "number of actors to spawn")
- .Required()
- .RequiredArgument()
- .StoreResult(&NumActors);
-
- config.Opts->AddLongOption("pool-id", "pool id to spawn actors within")
- .Required()
- .RequiredArgument()
- .StoreResult(&PoolId);
-
- config.Opts->AddLongOption("duration", "test duration")
- .Required()
- .RequiredArgument()
- .StoreResult(&Duration);
-
- config.Opts->AddLongOption("sleep-min", "min uniform interval for event processing")
- .Required()
- .RequiredArgument()
- .StoreResult(&SleepMin);
-
- config.Opts->AddLongOption("sleep-max", "max uniform interval for event processing")
- .Required()
- .RequiredArgument()
- .StoreResult(&SleepMax);
-
- config.Opts->AddLongOption("reschedule-min", "min uniform interval between events")
- .Required()
- .RequiredArgument()
- .StoreResult(&RescheduleMin);
-
- config.Opts->AddLongOption("reschedule-max", "max uniform interval between events")
- .Required()
- .RequiredArgument()
- .StoreResult(&RescheduleMax);
- }
-
- int Run(TConfig& config) override {
- TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
-
- NKikimrClient::TInterconnectDebug& request = msg->Record;
- request.SetNumSlowpokeActors(NumActors);
- request.SetPoolId(PoolId);
- request.SetDuration(Duration.GetValue());
- request.SetSleepMin(SleepMin.GetValue());
- request.SetSleepMax(SleepMax.GetValue());
- request.SetRescheduleMin(RescheduleMin.GetValue());
- request.SetRescheduleMax(RescheduleMax.GetValue());
-
- auto callback = [](const NMsgBusProxy::TBusResponse& response) {
- return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
- };
-
- return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
- }
-};
-
-class TInterconnect : public TClientCommandTree {
-public:
- TInterconnect()
- : TClientCommandTree("interconnect", {"ic"}, "Interconnect debugging facilities")
- {
+ for (const TString &node : nodes) {
+ request.AddHops(FromString<ui32>(node));
+ }
+
+ request.SetSizeMin(SizeMin);
+ request.SetSizeMax(SizeMax);
+ request.SetInFlyMax(InFlyMax);
+ request.SetIntervalMin(IntervalMin.GetValue());
+ request.SetIntervalMax(IntervalMax.GetValue());
+ request.SetSoftLoad(Soft);
+ request.SetUseProtobufWithPayload(UseProtobufWithPayload);
+ request.SetDuration(Duration.GetValue());
+ if (ServicePool) {
+ request.SetServicePool(ServicePool);
+ }
+
+ auto callback = [](const NMsgBusProxy::TBusResponse& response) {
+ return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TInterconnectClosePeerSocket : public TClientCommand {
+ ui32 NodeId = 0;
+
+public:
+ TInterconnectClosePeerSocket()
+ : TClientCommand("closepeersocket", {}, "Close peer socket on existing session")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("node", "peer node id to close socket for")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&NodeId);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
+
+ NKikimrClient::TInterconnectDebug& request = msg->Record;
+ request.SetClosePeerSocketNodeId(NodeId);
+
+ auto callback = [](const NMsgBusProxy::TBusResponse& response) {
+ return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TInterconnectCloseInputSession : public TClientCommand {
+ ui32 NodeId = 0;
+
+public:
+ TInterconnectCloseInputSession()
+ : TClientCommand("closeinputsession", {}, "Terminate input session")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("node", "peer node id to close input session for")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&NodeId);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
+
+ NKikimrClient::TInterconnectDebug& request = msg->Record;
+ request.SetCloseInputSessionNodeId(NodeId);
+
+ auto callback = [](const NMsgBusProxy::TBusResponse& response) {
+ return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TInterconnectPoisonSession : public TClientCommand {
+ ui32 NodeId = 0;
+
+public:
+ TInterconnectPoisonSession()
+ : TClientCommand("poisonsession", {}, "Poison session")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("node", "peer node id to poison session for")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&NodeId);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
+
+ NKikimrClient::TInterconnectDebug& request = msg->Record;
+ request.SetPoisonSessionNodeId(NodeId);
+
+ auto callback = [](const NMsgBusProxy::TBusResponse& response) {
+ return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TInterconnectSlowpoke : public TClientCommand {
+ ui32 NumActors = 0;
+ ui32 PoolId = 0;
+ TDuration SleepMin;
+ TDuration SleepMax;
+ TDuration RescheduleMin;
+ TDuration RescheduleMax;
+ TDuration Duration;
+
+public:
+ TInterconnectSlowpoke()
+ : TClientCommand("slowpoke", {}, "Make actor system work a bit worse")
+ {}
+
+ void Config(TConfig& config) override {
+ config.Opts->AddLongOption("num-actors", "number of actors to spawn")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&NumActors);
+
+ config.Opts->AddLongOption("pool-id", "pool id to spawn actors within")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&PoolId);
+
+ config.Opts->AddLongOption("duration", "test duration")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&Duration);
+
+ config.Opts->AddLongOption("sleep-min", "min uniform interval for event processing")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&SleepMin);
+
+ config.Opts->AddLongOption("sleep-max", "max uniform interval for event processing")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&SleepMax);
+
+ config.Opts->AddLongOption("reschedule-min", "min uniform interval between events")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&RescheduleMin);
+
+ config.Opts->AddLongOption("reschedule-max", "max uniform interval between events")
+ .Required()
+ .RequiredArgument()
+ .StoreResult(&RescheduleMax);
+ }
+
+ int Run(TConfig& config) override {
+ TAutoPtr<NMsgBusProxy::TBusInterconnectDebug> msg(new NMsgBusProxy::TBusInterconnectDebug);
+
+ NKikimrClient::TInterconnectDebug& request = msg->Record;
+ request.SetNumSlowpokeActors(NumActors);
+ request.SetPoolId(PoolId);
+ request.SetDuration(Duration.GetValue());
+ request.SetSleepMin(SleepMin.GetValue());
+ request.SetSleepMax(SleepMax.GetValue());
+ request.SetRescheduleMin(RescheduleMin.GetValue());
+ request.SetRescheduleMax(RescheduleMax.GetValue());
+
+ auto callback = [](const NMsgBusProxy::TBusResponse& response) {
+ return response.Record.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
+ };
+
+ return MessageBusCall<NMsgBusProxy::TBusInterconnectDebug, NMsgBusProxy::TBusResponse>(config, msg, callback);
+ }
+};
+
+class TInterconnect : public TClientCommandTree {
+public:
+ TInterconnect()
+ : TClientCommandTree("interconnect", {"ic"}, "Interconnect debugging facilities")
+ {
AddCommand(std::make_unique<TInterconnectLoad>());
AddCommand(std::make_unique<TInterconnectClosePeerSocket>());
AddCommand(std::make_unique<TInterconnectCloseInputSession>());
AddCommand(std::make_unique<TInterconnectPoisonSession>());
AddCommand(std::make_unique<TInterconnectSlowpoke>());
- }
-};
-
+ }
+};
+
TClientCommandDebug::TClientCommandDebug()
: TClientCommandTree("debug")
-{
+{
AddCommand(std::make_unique<TInterconnect>());
-}
+}
}
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
index af2801de362..1318a1eed81 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
@@ -2,248 +2,248 @@
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/protos/config.pb.h>
#include <ydb/core/mind/bscontroller/grouper.h>
-#include "cli.h"
-#include "cli_cmds.h"
-#include "proto_common.h"
-
-namespace NKikimr {
-namespace NDriverClient {
-
-using NBsController::TCandidate;
-using NBsController::GroupFromCandidates;
-
+#include "cli.h"
+#include "cli_cmds.h"
+#include "proto_common.h"
+
+namespace NKikimr {
+namespace NDriverClient {
+
+using NBsController::TCandidate;
+using NBsController::GroupFromCandidates;
+
class TClientCommandGenConfigStatic : public TClientCommandConfig {
TString ErasureList;
-
+
TString ErasureStr;
TString DesiredPDiskType = "ROT";
TString DistinctionLevelStr = "body";
TString BsFormatFile;
TString RingDistinctionLevelStr;
-
- TBlobStorageGroupType Type;
- ui32 AvailabilityDomain = 1;
- ui32 GroupId = 0;
- ui32 GroupGen = 1;
- ui32 FailDomains = 0;
- ui32 VDisksPerFailDomain = 1;
- ui32 BeginLevel;
- ui32 EndLevel;
- ui32 RingBeginLevel;
- ui32 RingEndLevel;
- ui32 VSlot = 0;
- ui32 NumRings = 0;
+
+ TBlobStorageGroupType Type;
+ ui32 AvailabilityDomain = 1;
+ ui32 GroupId = 0;
+ ui32 GroupGen = 1;
+ ui32 FailDomains = 0;
+ ui32 VDisksPerFailDomain = 1;
+ ui32 BeginLevel;
+ ui32 EndLevel;
+ ui32 RingBeginLevel;
+ ui32 RingEndLevel;
+ ui32 VSlot = 0;
+ ui32 NumRings = 0;
TString VDiskKind = "Default";
- int VDiskKindVal = 0;
-
- int ExpectedSlotCount = -1;
-
- ui64 Dc = -1;
- ui64 Room = -1;
- ui64 Rack = -1;
- ui64 Body = -1;
-
- TFailDomain Prefix;
-
- struct TPDiskInfo {
+ int VDiskKindVal = 0;
+
+ int ExpectedSlotCount = -1;
+
+ ui64 Dc = -1;
+ ui64 Room = -1;
+ ui64 Rack = -1;
+ ui64 Body = -1;
+
+ TFailDomain Prefix;
+
+ struct TPDiskInfo {
const TString Type; // PDisk type as mentioned in bs_format.txt
const TString Path; // path to device on a node
- const TFailDomain FailDom; // physical location of a PDisk
- const ui64 PDiskGuid; // PDisk unique identifier
- const ui32 PDiskId; // PDisk per-node identifier
- const ui32 NodeId; // the node PDisk resides on
-
- std::optional<NKikimrBlobStorage::TPDiskConfig> PDiskConfig;
-
- explicit TPDiskInfo(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive)
- : Type(drive.GetType())
- , Path(drive.GetPath())
- , FailDom(ParseFailDomain(drive))
- , PDiskGuid(drive.GetGuid())
- , PDiskId(drive.GetPDiskId())
- , NodeId(drive.GetNodeId())
- {
-#define MANDATORY_FIELD(NAME) if (!drive.Has##NAME()) { ythrow yexception() << "missing \"" #NAME "\" field in Drive record"; }
- MANDATORY_FIELD(Type)
- MANDATORY_FIELD(Path)
- MANDATORY_FIELD(Guid)
- MANDATORY_FIELD(PDiskId)
- MANDATORY_FIELD(NodeId)
-#undef MANDATORY_FIELD
- if (drive.HasPDiskConfig()) {
- PDiskConfig.emplace(drive.GetPDiskConfig());
- }
- }
-
+ const TFailDomain FailDom; // physical location of a PDisk
+ const ui64 PDiskGuid; // PDisk unique identifier
+ const ui32 PDiskId; // PDisk per-node identifier
+ const ui32 NodeId; // the node PDisk resides on
+
+ std::optional<NKikimrBlobStorage::TPDiskConfig> PDiskConfig;
+
+ explicit TPDiskInfo(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive)
+ : Type(drive.GetType())
+ , Path(drive.GetPath())
+ , FailDom(ParseFailDomain(drive))
+ , PDiskGuid(drive.GetGuid())
+ , PDiskId(drive.GetPDiskId())
+ , NodeId(drive.GetNodeId())
+ {
+#define MANDATORY_FIELD(NAME) if (!drive.Has##NAME()) { ythrow yexception() << "missing \"" #NAME "\" field in Drive record"; }
+ MANDATORY_FIELD(Type)
+ MANDATORY_FIELD(Path)
+ MANDATORY_FIELD(Guid)
+ MANDATORY_FIELD(PDiskId)
+ MANDATORY_FIELD(NodeId)
+#undef MANDATORY_FIELD
+ if (drive.HasPDiskConfig()) {
+ PDiskConfig.emplace(drive.GetPDiskConfig());
+ }
+ }
+
TString ToString() const {
- TStringStream str;
- str << "{Type# " << Type << " FailDom# " << FailDom.ToString() << " PDiskGuid# " << PDiskGuid << " PDiskId# "
- << PDiskId << " NodeId# " << NodeId << "}";
- return str.Str();
- }
-
- private:
- static TFailDomain ParseFailDomain(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive) {
- TFailDomain fdom;
-
- using T = NKikimrConfig::TBlobStorageFormatConfig::TDrive;
+ TStringStream str;
+ str << "{Type# " << Type << " FailDom# " << FailDom.ToString() << " PDiskGuid# " << PDiskGuid << " PDiskId# "
+ << PDiskId << " NodeId# " << NodeId << "}";
+ return str.Str();
+ }
+
+ private:
+ static TFailDomain ParseFailDomain(const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive) {
+ TFailDomain fdom;
+
+ using T = NKikimrConfig::TBlobStorageFormatConfig::TDrive;
TVector<std::tuple<int, bool(T::*)() const, ui64(T::*)() const>> levels = {
- std::make_tuple(10, &T::HasDataCenterId, &T::GetDataCenterId),
- std::make_tuple(20, &T::HasRoomId, &T::GetRoomId ),
- std::make_tuple(30, &T::HasRackId, &T::GetRackId ),
- std::make_tuple(40, &T::HasBodyId, &T::GetBodyId )
- };
- for (const auto& triplet : levels) {
- ui32 level;
- bool (T::*pfnHas)() const;
- ui64 (T::*pfnGet)() const;
- std::tie(level, pfnHas, pfnGet) = triplet;
- if ((drive.*pfnHas)()) {
- fdom.Levels[level] = (drive.*pfnGet)();
- }
- }
-
- return fdom;
- }
- };
-
-public:
- TClientCommandGenConfigStatic()
+ std::make_tuple(10, &T::HasDataCenterId, &T::GetDataCenterId),
+ std::make_tuple(20, &T::HasRoomId, &T::GetRoomId ),
+ std::make_tuple(30, &T::HasRackId, &T::GetRackId ),
+ std::make_tuple(40, &T::HasBodyId, &T::GetBodyId )
+ };
+ for (const auto& triplet : levels) {
+ ui32 level;
+ bool (T::*pfnHas)() const;
+ ui64 (T::*pfnGet)() const;
+ std::tie(level, pfnHas, pfnGet) = triplet;
+ if ((drive.*pfnHas)()) {
+ fdom.Levels[level] = (drive.*pfnGet)();
+ }
+ }
+
+ return fdom;
+ }
+ };
+
+public:
+ TClientCommandGenConfigStatic()
: TClientCommandConfig("static", {}, "Generate configuration for static group")
- {
- TStringStream erasureList("{");
- for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
- erasureList << (species ? "|" : "") << TBlobStorageGroupType::ErasureName[species];
- }
- erasureList << "}";
- ErasureList = erasureList.Str();
- }
-
- void Config(TConfig& config) override {
- TClientCommand::Config(config);
-
- config.Opts->AddLongOption("erasure", "erasure species").Required().RequiredArgument(ErasureList).StoreResult(&ErasureStr);
- config.Opts->AddLongOption("avdomain", "availability domain").Optional().RequiredArgument("NUM").StoreResult(&AvailabilityDomain);
- config.Opts->AddLongOption("groupid", "group identifier").Optional().RequiredArgument("NUM").StoreResult(&GroupId);
- config.Opts->AddLongOption("pdisktype", "desired pdisk type").Optional().RequiredArgument("{SSD|ROT}").StoreResult(&DesiredPDiskType);
- config.Opts->AddLongOption("vdiskkind", "vdisk kind")
- .Optional()
- .RequiredArgument(GetProtobufEnumOptions(NKikimrBlobStorage::TVDiskKind_EVDiskKind_descriptor()))
- .StoreResult(&VDiskKind);
- config.Opts->AddLongOption("expected-slot-count", "expected (maximum) slot count for PDisk")
- .Optional()
- .RequiredArgument("NUM")
- .StoreResult(&ExpectedSlotCount);
- config.Opts->AddLongOption("faildomains", "desired fail domains").RequiredArgument("NUM").StoreResult(&FailDomains);
- config.Opts->AddLongOption("vdisks", "vdisks per fail domain").RequiredArgument("NUM").StoreResult(&VDisksPerFailDomain);
- config.Opts->AddLongOption("vslot", "vslot id for created group").Optional().RequiredArgument("NUM").StoreResult(&VSlot);
- config.Opts->AddLongOption("dc", "location: dc").RequiredArgument("NUM").StoreResult(&Dc);
- config.Opts->AddLongOption("room", "location: room").RequiredArgument("NUM").StoreResult(&Room);
- config.Opts->AddLongOption("rack", "location: rack").RequiredArgument("NUM").StoreResult(&Rack);
- config.Opts->AddLongOption("body", "location: body").RequiredArgument("NUM").StoreResult(&Body);
- config.Opts->AddLongOption("dx", "distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&DistinctionLevelStr);
- config.Opts->AddLongOption("ringdx", "ring distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&RingDistinctionLevelStr);
- config.Opts->AddLongOption("rings", "number of rings").RequiredArgument("NUM").StoreResult(&NumRings);
-
- config.Opts->AddLongOption("bs-format-file", "path to bs_format.txt file").Required().RequiredArgument("PATH")
- .StoreResult(&BsFormatFile);
- }
-
+ {
+ TStringStream erasureList("{");
+ for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
+ erasureList << (species ? "|" : "") << TBlobStorageGroupType::ErasureName[species];
+ }
+ erasureList << "}";
+ ErasureList = erasureList.Str();
+ }
+
+ void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+
+ config.Opts->AddLongOption("erasure", "erasure species").Required().RequiredArgument(ErasureList).StoreResult(&ErasureStr);
+ config.Opts->AddLongOption("avdomain", "availability domain").Optional().RequiredArgument("NUM").StoreResult(&AvailabilityDomain);
+ config.Opts->AddLongOption("groupid", "group identifier").Optional().RequiredArgument("NUM").StoreResult(&GroupId);
+ config.Opts->AddLongOption("pdisktype", "desired pdisk type").Optional().RequiredArgument("{SSD|ROT}").StoreResult(&DesiredPDiskType);
+ config.Opts->AddLongOption("vdiskkind", "vdisk kind")
+ .Optional()
+ .RequiredArgument(GetProtobufEnumOptions(NKikimrBlobStorage::TVDiskKind_EVDiskKind_descriptor()))
+ .StoreResult(&VDiskKind);
+ config.Opts->AddLongOption("expected-slot-count", "expected (maximum) slot count for PDisk")
+ .Optional()
+ .RequiredArgument("NUM")
+ .StoreResult(&ExpectedSlotCount);
+ config.Opts->AddLongOption("faildomains", "desired fail domains").RequiredArgument("NUM").StoreResult(&FailDomains);
+ config.Opts->AddLongOption("vdisks", "vdisks per fail domain").RequiredArgument("NUM").StoreResult(&VDisksPerFailDomain);
+ config.Opts->AddLongOption("vslot", "vslot id for created group").Optional().RequiredArgument("NUM").StoreResult(&VSlot);
+ config.Opts->AddLongOption("dc", "location: dc").RequiredArgument("NUM").StoreResult(&Dc);
+ config.Opts->AddLongOption("room", "location: room").RequiredArgument("NUM").StoreResult(&Room);
+ config.Opts->AddLongOption("rack", "location: rack").RequiredArgument("NUM").StoreResult(&Rack);
+ config.Opts->AddLongOption("body", "location: body").RequiredArgument("NUM").StoreResult(&Body);
+ config.Opts->AddLongOption("dx", "distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&DistinctionLevelStr);
+ config.Opts->AddLongOption("ringdx", "ring distinction level").RequiredArgument("{dc|room|rack|body}").StoreResult(&RingDistinctionLevelStr);
+ config.Opts->AddLongOption("rings", "number of rings").RequiredArgument("NUM").StoreResult(&NumRings);
+
+ config.Opts->AddLongOption("bs-format-file", "path to bs_format.txt file").Required().RequiredArgument("PATH")
+ .StoreResult(&BsFormatFile);
+ }
+
ui32 ParseDistinctionLevel(const TString& s) {
- const ui32 level =
- s == "dc" ? 10 :
- s == "room" ? 20 :
- s == "rack" ? 30 :
- s == "body" ? 40 : 0;
- if (!level) {
- ythrow yexception() << "unknown distinction level provided: \"" << s << "\"";
- }
- return level;
- }
-
- void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
-
+ const ui32 level =
+ s == "dc" ? 10 :
+ s == "room" ? 20 :
+ s == "rack" ? 30 :
+ s == "body" ? 40 : 0;
+ if (!level) {
+ ythrow yexception() << "unknown distinction level provided: \"" << s << "\"";
+ }
+ return level;
+ }
+
+ void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+
auto erasure = TBlobStorageGroupType::ErasureSpeciesByName(ErasureStr);
Type = TBlobStorageGroupType(erasure);
if (Type.GetErasure() == TBlobStorageGroupType::ErasureSpeciesCount) {
- ythrow TWithBackTrace<yexception>() << "unknown erasure species: \"" << ErasureStr << "\", valid values are: " << ErasureList;
- }
-
+ ythrow TWithBackTrace<yexception>() << "unknown erasure species: \"" << ErasureStr << "\", valid values are: " << ErasureList;
+ }
+
if (!RingDistinctionLevelStr && Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc) {
- RingDistinctionLevelStr = "dc";
- }
-
- BeginLevel = 0;
- EndLevel = ParseDistinctionLevel(DistinctionLevelStr);
- RingBeginLevel = 0;
- RingEndLevel = RingDistinctionLevelStr ? ParseDistinctionLevel(RingDistinctionLevelStr) : 0;
-
- if (Dc != (ui64)-1) {
- Prefix.Levels[10] = Dc;
- }
- if (Room != (ui64)-1) {
- Prefix.Levels[20] = Room;
- }
- if (Rack != (ui64)-1) {
- Prefix.Levels[30] = Rack;
- }
- if (Body != (ui64)-1) {
- Prefix.Levels[40] = Body;
- }
-
- if (!FailDomains) {
+ RingDistinctionLevelStr = "dc";
+ }
+
+ BeginLevel = 0;
+ EndLevel = ParseDistinctionLevel(DistinctionLevelStr);
+ RingBeginLevel = 0;
+ RingEndLevel = RingDistinctionLevelStr ? ParseDistinctionLevel(RingDistinctionLevelStr) : 0;
+
+ if (Dc != (ui64)-1) {
+ Prefix.Levels[10] = Dc;
+ }
+ if (Room != (ui64)-1) {
+ Prefix.Levels[20] = Room;
+ }
+ if (Rack != (ui64)-1) {
+ Prefix.Levels[30] = Rack;
+ }
+ if (Body != (ui64)-1) {
+ Prefix.Levels[40] = Body;
+ }
+
+ if (!FailDomains) {
FailDomains = Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc ? 3 : Type.BlobSubgroupSize();
- }
-
+ }
+
ui32 minRings = Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc ? 3 : 1;
- if (!NumRings) {
- NumRings = minRings;
- } else if (NumRings < minRings) {
- ythrow yexception() << "number of rings (" << NumRings << ") is less than minimum possible number of rings ("
- << minRings << ") for this erasure type";
- }
-
- VDiskKindVal = GetProtobufOption(NKikimrBlobStorage::TVDiskKind_EVDiskKind_descriptor(), "--vdiskkind", VDiskKind);
- }
-
- int Run(TConfig& config) override {
+ if (!NumRings) {
+ NumRings = minRings;
+ } else if (NumRings < minRings) {
+ ythrow yexception() << "number of rings (" << NumRings << ") is less than minimum possible number of rings ("
+ << minRings << ") for this erasure type";
+ }
+
+ VDiskKindVal = GetProtobufOption(NKikimrBlobStorage::TVDiskKind_EVDiskKind_descriptor(), "--vdiskkind", VDiskKind);
+ }
+
+ int Run(TConfig& config) override {
const ui32 minSubgroupSize = Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc ? 3 : Type.BlobSubgroupSize();
- if (FailDomains < minSubgroupSize) {
- Cerr << "not enough fail domains (" << FailDomains << ") to build group; minimum " << minSubgroupSize
- << " domains required" << Endl;
- return EXIT_FAILURE;
- }
-
- NKikimrConfig::TBlobStorageFormatConfig bsFormat;
- try {
+ if (FailDomains < minSubgroupSize) {
+ Cerr << "not enough fail domains (" << FailDomains << ") to build group; minimum " << minSubgroupSize
+ << " domains required" << Endl;
+ return EXIT_FAILURE;
+ }
+
+ NKikimrConfig::TBlobStorageFormatConfig bsFormat;
+ try {
TUnbufferedFileInput input(BsFormatFile);
- const bool status = google::protobuf::TextFormat::ParseFromString(input.ReadAll(), &bsFormat);
- if (!status) {
- ythrow yexception() << "failed to parse protobuf";
- }
- } catch (const yexception& ex) {
- Cerr << "Failed to read BS format \"" << BsFormatFile << "\": " << ex.what() << Endl;
- return EXIT_FAILURE;
- }
-
- // make a set of PDisks that fit our filtering condition
+ const bool status = google::protobuf::TextFormat::ParseFromString(input.ReadAll(), &bsFormat);
+ if (!status) {
+ ythrow yexception() << "failed to parse protobuf";
+ }
+ } catch (const yexception& ex) {
+ Cerr << "Failed to read BS format \"" << BsFormatFile << "\": " << ex.what() << Endl;
+ return EXIT_FAILURE;
+ }
+
+ // make a set of PDisks that fit our filtering condition
TVector<TPDiskInfo> pdisks;
- for (const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive : bsFormat.GetDrive()) {
- TPDiskInfo pdiskInfo(drive);
- if (pdiskInfo.Type == DesiredPDiskType && Prefix.IsSubdomainOf(pdiskInfo.FailDom)) {
- pdisks.push_back(std::move(pdiskInfo));
- }
- }
-
+ for (const NKikimrConfig::TBlobStorageFormatConfig::TDrive& drive : bsFormat.GetDrive()) {
+ TPDiskInfo pdiskInfo(drive);
+ if (pdiskInfo.Type == DesiredPDiskType && Prefix.IsSubdomainOf(pdiskInfo.FailDom)) {
+ pdisks.push_back(std::move(pdiskInfo));
+ }
+ }
+
TVector<TCandidate> candidates;
- for (const TPDiskInfo& pdisk : pdisks) {
- candidates.emplace_back(pdisk.FailDom, BeginLevel, EndLevel, 0 /*badness*/, pdisk.NodeId, pdisk.PDiskId, VSlot);
- }
-
+ for (const TPDiskInfo& pdisk : pdisks) {
+ candidates.emplace_back(pdisk.FailDom, BeginLevel, EndLevel, 0 /*badness*/, pdisk.NodeId, pdisk.PDiskId, VSlot);
+ }
+
TVector<TVector<TVector<const TCandidate*>>> bestGroup;
- if (!CreateGroupWithRings(candidates, NumRings, FailDomains, VDisksPerFailDomain, RingBeginLevel, RingEndLevel,
- bestGroup)) {
+ if (!CreateGroupWithRings(candidates, NumRings, FailDomains, VDisksPerFailDomain, RingBeginLevel, RingEndLevel,
+ bestGroup)) {
Cerr << "Can't create group with given parameters"
<< " NumRings = " << NumRings
<< ", FailDomains = " << FailDomains
@@ -251,108 +251,108 @@ public:
<< ", RingBeginLevel = " << RingBeginLevel
<< ", RingEndLevel = " << RingEndLevel
<< Endl;
- return EXIT_FAILURE;
- }
-
- NKikimrConfig::TBlobStorageConfig pb;
- NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet = *pb.MutableServiceSet();
- serviceSet.AddAvailabilityDomains(AvailabilityDomain);
-
- auto transformVDisk = [&](const TCandidate *vdisk, auto& outFailDomain, ui32 ringIdx, ui32 domainIdx, ui32& vdiskIdx) {
- // calculate index of candidate inside our PDisk vector and find matching PDisk info
- const ui32 index = vdisk - candidates.data();
- const TPDiskInfo& pdiskInfo = pdisks[index];
-
- // add pdisk meta
- auto& pdiskItem = *serviceSet.AddPDisks();
- pdiskItem.SetNodeID(pdiskInfo.NodeId);
- pdiskItem.SetPDiskID(pdiskInfo.PDiskId);
- pdiskItem.SetPath(pdiskInfo.Path);
- pdiskItem.SetPDiskGuid(pdiskInfo.PDiskGuid);
-
+ return EXIT_FAILURE;
+ }
+
+ NKikimrConfig::TBlobStorageConfig pb;
+ NKikimrBlobStorage::TNodeWardenServiceSet& serviceSet = *pb.MutableServiceSet();
+ serviceSet.AddAvailabilityDomains(AvailabilityDomain);
+
+ auto transformVDisk = [&](const TCandidate *vdisk, auto& outFailDomain, ui32 ringIdx, ui32 domainIdx, ui32& vdiskIdx) {
+ // calculate index of candidate inside our PDisk vector and find matching PDisk info
+ const ui32 index = vdisk - candidates.data();
+ const TPDiskInfo& pdiskInfo = pdisks[index];
+
+ // add pdisk meta
+ auto& pdiskItem = *serviceSet.AddPDisks();
+ pdiskItem.SetNodeID(pdiskInfo.NodeId);
+ pdiskItem.SetPDiskID(pdiskInfo.PDiskId);
+ pdiskItem.SetPath(pdiskInfo.Path);
+ pdiskItem.SetPDiskGuid(pdiskInfo.PDiskGuid);
+
TPDiskCategory::EDeviceType deviceType = TPDiskCategory::DeviceTypeFromStr(pdiskInfo.Type);
if (deviceType == TPDiskCategory::DEVICE_TYPE_UNKNOWN) {
- ythrow yexception() << "invalid PDisk Type " << pdiskInfo.Type;
- }
- const ui64 kind = 0;
+ ythrow yexception() << "invalid PDisk Type " << pdiskInfo.Type;
+ }
+ const ui64 kind = 0;
TPDiskCategory cat(deviceType, kind);
- pdiskItem.SetPDiskCategory(cat.GetRaw());
-
- if (pdiskInfo.PDiskConfig) {
- auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
- pdiskConfig->CopyFrom(*pdiskInfo.PDiskConfig);
- } else if (config.ParseResult->Has("expected-slot-count")) {
- auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
- pdiskConfig->SetExpectedSlotCount(ExpectedSlotCount);
- }
-
- // add vdisk meta
- auto& vdiskItem = *serviceSet.AddVDisks();
- auto& vdiskId = *vdiskItem.MutableVDiskID();
- vdiskId.SetGroupID(GroupId);
- vdiskId.SetGroupGeneration(GroupGen);
- vdiskId.SetRing(ringIdx);
- vdiskId.SetDomain(domainIdx);
- vdiskId.SetVDisk(vdiskIdx);
- auto& vdiskLocation = *vdiskItem.MutableVDiskLocation();
- vdiskLocation.SetNodeID(vdisk->NodeId);
- vdiskLocation.SetPDiskID(vdisk->PDiskId);
- vdiskLocation.SetVDiskSlotID(vdisk->VDiskSlotId);
- vdiskLocation.SetPDiskGuid(pdiskInfo.PDiskGuid);
- vdiskItem.SetVDiskKind((NKikimrBlobStorage::TVDiskKind_EVDiskKind)VDiskKindVal);
-
- // add vdisk location to the group descriptor
- *outFailDomain.AddVDiskLocations() = vdiskLocation;
-
- ++vdiskIdx;
- };
-
+ pdiskItem.SetPDiskCategory(cat.GetRaw());
+
+ if (pdiskInfo.PDiskConfig) {
+ auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
+ pdiskConfig->CopyFrom(*pdiskInfo.PDiskConfig);
+ } else if (config.ParseResult->Has("expected-slot-count")) {
+ auto *pdiskConfig = pdiskItem.MutablePDiskConfig();
+ pdiskConfig->SetExpectedSlotCount(ExpectedSlotCount);
+ }
+
+ // add vdisk meta
+ auto& vdiskItem = *serviceSet.AddVDisks();
+ auto& vdiskId = *vdiskItem.MutableVDiskID();
+ vdiskId.SetGroupID(GroupId);
+ vdiskId.SetGroupGeneration(GroupGen);
+ vdiskId.SetRing(ringIdx);
+ vdiskId.SetDomain(domainIdx);
+ vdiskId.SetVDisk(vdiskIdx);
+ auto& vdiskLocation = *vdiskItem.MutableVDiskLocation();
+ vdiskLocation.SetNodeID(vdisk->NodeId);
+ vdiskLocation.SetPDiskID(vdisk->PDiskId);
+ vdiskLocation.SetVDiskSlotID(vdisk->VDiskSlotId);
+ vdiskLocation.SetPDiskGuid(pdiskInfo.PDiskGuid);
+ vdiskItem.SetVDiskKind((NKikimrBlobStorage::TVDiskKind_EVDiskKind)VDiskKindVal);
+
+ // add vdisk location to the group descriptor
+ *outFailDomain.AddVDiskLocations() = vdiskLocation;
+
+ ++vdiskIdx;
+ };
+
auto transformDomain = [&](const TVector<const TCandidate*>& inVDisks, auto& outRing, ui32 ringIdx, ui32& domainIdx) {
- ui32 vdiskIdx = 0;
- std::for_each(inVDisks.begin(), inVDisks.end(), std::bind(transformVDisk, std::placeholders::_1,
- std::ref(*outRing.AddFailDomains()), ringIdx, domainIdx, std::ref(vdiskIdx)));
- ++domainIdx;
- };
-
+ ui32 vdiskIdx = 0;
+ std::for_each(inVDisks.begin(), inVDisks.end(), std::bind(transformVDisk, std::placeholders::_1,
+ std::ref(*outRing.AddFailDomains()), ringIdx, domainIdx, std::ref(vdiskIdx)));
+ ++domainIdx;
+ };
+
auto transformRing = [&](const TVector<TVector<const TCandidate*>>& inDomains, auto& outGroup, ui32& ringIdx) {
- ui32 domainIdx = 0;
- std::for_each(inDomains.begin(), inDomains.end(), std::bind(transformDomain, std::placeholders::_1,
- std::ref(*outGroup.AddRings()), ringIdx, std::ref(domainIdx)));
- ++ringIdx;
- };
-
- auto& group = *serviceSet.AddGroups();
- group.SetGroupID(GroupId);
- group.SetGroupGeneration(GroupGen);
+ ui32 domainIdx = 0;
+ std::for_each(inDomains.begin(), inDomains.end(), std::bind(transformDomain, std::placeholders::_1,
+ std::ref(*outGroup.AddRings()), ringIdx, std::ref(domainIdx)));
+ ++ringIdx;
+ };
+
+ auto& group = *serviceSet.AddGroups();
+ group.SetGroupID(GroupId);
+ group.SetGroupGeneration(GroupGen);
group.SetErasureSpecies(Type.GetErasure());
-
- ui32 ringIdx = 0;
- std::for_each(bestGroup.begin(), bestGroup.end(), std::bind(transformRing, std::placeholders::_1,
- std::ref(group), std::ref(ringIdx)));
-
+
+ ui32 ringIdx = 0;
+ std::for_each(bestGroup.begin(), bestGroup.end(), std::bind(transformRing, std::placeholders::_1,
+ std::ref(group), std::ref(ringIdx)));
+
TString message;
- if (!google::protobuf::TextFormat::PrintToString(pb, &message)) {
- Cerr << "failed to format resulting protobuf" << Endl;
- return EXIT_FAILURE;
- }
- Cout << message;
-
- return EXIT_SUCCESS;
- }
-};
-
-class TClientCommandGenConfig : public TClientCommandTree {
-public:
- TClientCommandGenConfig()
- : TClientCommandTree("genconfig", {}, "Config generation")
- {
+ if (!google::protobuf::TextFormat::PrintToString(pb, &message)) {
+ Cerr << "failed to format resulting protobuf" << Endl;
+ return EXIT_FAILURE;
+ }
+ Cout << message;
+
+ return EXIT_SUCCESS;
+ }
+};
+
+class TClientCommandGenConfig : public TClientCommandTree {
+public:
+ TClientCommandGenConfig()
+ : TClientCommandTree("genconfig", {}, "Config generation")
+ {
AddCommand(std::make_unique<TClientCommandGenConfigStatic>());
- }
-};
-
+ }
+};
+
std::unique_ptr<TClientCommand> CreateClientCommandGenConfig() {
return std::make_unique<TClientCommandGenConfig>();
-}
-
-} // NDriverClient
-} // NKikimr
+}
+
+} // NDriverClient
+} // NKikimr
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_get.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_get.cpp
index f6593600871..c77ca2a8bc2 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_get.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_get.cpp
@@ -1,94 +1,94 @@
-#include "cli.h"
-#include "cli_cmds.h"
+#include "cli.h"
+#include "cli_cmds.h"
#include <ydb/core/base/logoblob.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
-class TClientCommandGetBlob : public TClientCommand {
- ui32 GroupId = 0;
- TMaybe<TLogoBlobID> ExtremeQuery;
-
-public:
- TClientCommandGetBlob()
- : TClientCommand("blob", {}, "Get blob raw content")
- {
- }
-
- void Config(TConfig& config) override {
- TClientCommand::Config(config);
-
- config.Opts->AddLongOption("group", "group id").Required().RequiredArgument("NUM").StoreResult(&GroupId);
- config.Opts->AddLongOption("extreme", "perform extreme query").Optional().RequiredArgument("BLOB_ID");
- }
-
- void Parse(TConfig& config) override {
- TClientCommand::Parse(config);
-
- if (config.ParseResult->Has("extreme")) {
- TLogoBlobID id;
+
+namespace NKikimr {
+namespace NDriverClient {
+
+class TClientCommandGetBlob : public TClientCommand {
+ ui32 GroupId = 0;
+ TMaybe<TLogoBlobID> ExtremeQuery;
+
+public:
+ TClientCommandGetBlob()
+ : TClientCommand("blob", {}, "Get blob raw content")
+ {
+ }
+
+ void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+
+ config.Opts->AddLongOption("group", "group id").Required().RequiredArgument("NUM").StoreResult(&GroupId);
+ config.Opts->AddLongOption("extreme", "perform extreme query").Optional().RequiredArgument("BLOB_ID");
+ }
+
+ void Parse(TConfig& config) override {
+ TClientCommand::Parse(config);
+
+ if (config.ParseResult->Has("extreme")) {
+ TLogoBlobID id;
TString errorExplanation;
const TString& blob = config.ParseResult->Get("extreme");
- if (!TLogoBlobID::Parse(id, blob, errorExplanation)) {
- ythrow yexception() << "Failed to parse LogoBlobId '" << blob << "': " << errorExplanation;
- }
- ExtremeQuery = id;
- } else {
- ythrow yexception() << "No query type specified";
- }
- }
-
- int Run(TConfig& config) override {
- using TRequest = NMsgBusProxy::TBusBsGetRequest;
- using TResponse = NMsgBusProxy::TBusBsGetResponse;
-
- // prepare request
- TAutoPtr<TRequest> request(new TRequest);
- auto& record = request->Record;
- record.SetGroupId(GroupId);
- if (ExtremeQuery) {
- LogoBlobIDFromLogoBlobID(*ExtremeQuery, record.MutableExtreme());
- }
-
+ if (!TLogoBlobID::Parse(id, blob, errorExplanation)) {
+ ythrow yexception() << "Failed to parse LogoBlobId '" << blob << "': " << errorExplanation;
+ }
+ ExtremeQuery = id;
+ } else {
+ ythrow yexception() << "No query type specified";
+ }
+ }
+
+ int Run(TConfig& config) override {
+ using TRequest = NMsgBusProxy::TBusBsGetRequest;
+ using TResponse = NMsgBusProxy::TBusBsGetResponse;
+
+ // prepare request
+ TAutoPtr<TRequest> request(new TRequest);
+ auto& record = request->Record;
+ record.SetGroupId(GroupId);
+ if (ExtremeQuery) {
+ LogoBlobIDFromLogoBlobID(*ExtremeQuery, record.MutableExtreme());
+ }
+
auto callback = [](const TResponse& response) -> int {
- if (response.Record.HasErrorDescription()) {
- Cerr << "error: " << response.Record.GetErrorDescription() << Endl;
- return 1;
- } else {
- switch (auto status = response.Record.GetStatus()) {
- case NKikimrProto::OK:
- Cout.Write(response.Record.GetBuffer());
- return 0;
-
- case NKikimrProto::NODATA:
- Cerr << "no data" << Endl;
- return 3;
-
- default:
- Cerr << "proxy error: " << NKikimrProto::EReplyStatus_Name(status) << Endl;
- return 2;
- }
- }
-
- Y_FAIL();
- };
-
- return MessageBusCall<TRequest, TResponse>(config, request, callback);
- }
-};
-
-class TClientCommandGet : public TClientCommandTree {
-public:
- TClientCommandGet()
- : TClientCommandTree("get", {}, "Various storage low-level queries")
- {
+ if (response.Record.HasErrorDescription()) {
+ Cerr << "error: " << response.Record.GetErrorDescription() << Endl;
+ return 1;
+ } else {
+ switch (auto status = response.Record.GetStatus()) {
+ case NKikimrProto::OK:
+ Cout.Write(response.Record.GetBuffer());
+ return 0;
+
+ case NKikimrProto::NODATA:
+ Cerr << "no data" << Endl;
+ return 3;
+
+ default:
+ Cerr << "proxy error: " << NKikimrProto::EReplyStatus_Name(status) << Endl;
+ return 2;
+ }
+ }
+
+ Y_FAIL();
+ };
+
+ return MessageBusCall<TRequest, TResponse>(config, request, callback);
+ }
+};
+
+class TClientCommandGet : public TClientCommandTree {
+public:
+ TClientCommandGet()
+ : TClientCommandTree("get", {}, "Various storage low-level queries")
+ {
AddCommand(std::make_unique<TClientCommandGetBlob>());
- }
-};
-
+ }
+};
+
std::unique_ptr<TClientCommand> CreateClientCommandGet() {
return std::make_unique<TClientCommandGet>();
-}
-
-} // NDriverClient
-} // NKikimr
+}
+
+} // NDriverClient
+} // NKikimr
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
index 0b4804c1c17..63e4aa6f454 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_group.cpp
@@ -1,7 +1,7 @@
#include <ydb/core/erasure/erasure.h>
#include "cli.h"
#include "cli_cmds.h"
-#include "proto_common.h"
+#include "proto_common.h"
namespace NKikimr {
namespace NDriverClient {
@@ -50,9 +50,9 @@ public:
virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusBSAdm> request(new NMsgBusProxy::TBusBSAdm);
request->Record.SetDomain(Domain);
- if (config.SecurityToken) {
- request->Record.SetSecurityToken(config.SecurityToken);
- }
+ if (config.SecurityToken) {
+ request->Record.SetSecurityToken(config.SecurityToken);
+ }
auto *x = request->Record.MutableGroupReconfigureWipe();
auto *location = x->MutableLocation();
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
index 6766dd31719..77232cec8a9 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_server.cpp
@@ -19,9 +19,9 @@ extern TAutoPtr<NKikimrConfig::TAllocatorConfig> DummyAllocatorConfig();
namespace NKikimr {
namespace NDriverClient {
-class TClientCommandServerBase : public TClientCommand {
-protected:
- NKikimrConfig::TAppConfig BaseConfig;
+class TClientCommandServerBase : public TClientCommand {
+protected:
+ NKikimrConfig::TAppConfig BaseConfig;
NKikimrConfig::TAppConfig AppConfig;
TKikimrRunConfig RunConfig;
@@ -80,16 +80,16 @@ protected:
TVector<TString> GRpcPublicAddressesV4;
TVector<TString> GRpcPublicAddressesV6;
TString GRpcPublicTargetNameOverride;
- TString PathToCert;
- TString PathToPKey;
- TString PathToCA;
+ TString PathToCert;
+ TString PathToPKey;
+ TString PathToCA;
TVector<TString> YamlConfigFiles;
- TClientCommandServerBase(const char *cmd, const char *description)
- : TClientCommand(cmd, {}, description)
- , RunConfig(AppConfig)
- {}
-
+ TClientCommandServerBase(const char *cmd, const char *description)
+ : TClientCommand(cmd, {}, description)
+ , RunConfig(AppConfig)
+ {}
+
virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
@@ -183,9 +183,9 @@ protected:
config.Opts->AddLongOption("mon-port", "Monitoring port").OptionalArgument("NUM").StoreResult(&MonitoringPort);
config.Opts->AddLongOption("mon-address", "Monitoring address").OptionalArgument("ADDR").StoreResult(&MonitoringAddress);
config.Opts->AddLongOption("mon-threads", "Monitoring http server threads").RequiredArgument("NUM").StoreResult(&MonitoringThreads);
- config.Opts->AddLongOption("suppress-version-check", "Suppress version compatibility checking via IC").NoArgument();
+ config.Opts->AddLongOption("suppress-version-check", "Suppress version compatibility checking via IC").NoArgument();
-// config.Opts->AddLongOption('u', "url-base", "url base to request configs from").OptionalArgument("URL");
+// config.Opts->AddLongOption('u', "url-base", "url base to request configs from").OptionalArgument("URL");
config.Opts->AddLongOption("sys-file", "actor system config file (use dummy config by default)").OptionalArgument("PATH");
config.Opts->AddLongOption("naming-file", "static nameservice config file").OptionalArgument("PATH");
config.Opts->AddLongOption("domains-file", "domain config file").OptionalArgument("PATH");
@@ -195,7 +195,7 @@ protected:
config.Opts->AddLongOption("channels-file", "tablet channel profile config file").OptionalArgument("PATH");
config.Opts->AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
config.Opts->AddLongOption("drivemodel-file", "drive model config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("grpc-file", "gRPC config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("grpc-file", "gRPC config file").OptionalArgument("PATH");
config.Opts->AddLongOption("tenant-pool-file", "Tenant Pool service config file").OptionalArgument("PATH");
config.Opts->AddLongOption("grpc-port", "enable gRPC server on port").RequiredArgument("PORT").StoreResult(&GRpcPort);
config.Opts->AddLongOption("grpcs-port", "enable gRPC SSL server on port").RequiredArgument("PORT").StoreResult(&GRpcsPort);
@@ -205,9 +205,9 @@ protected:
config.Opts->AddLongOption("grpc-public-address-v4", "set public ipv4 address for discovery").RequiredArgument("ADDR").EmplaceTo(&GRpcPublicAddressesV4);
config.Opts->AddLongOption("grpc-public-address-v6", "set public ipv6 address for discovery").RequiredArgument("ADDR").EmplaceTo(&GRpcPublicAddressesV6);
config.Opts->AddLongOption("grpc-public-target-name-override", "set public hostname override for TLS in discovery").RequiredArgument("HOST").StoreResult(&GRpcPublicTargetNameOverride);
- config.Opts->AddLongOption("kqp-file", "Kikimr Query Processor config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("incrhuge-file", "incremental huge blob keeper config file").OptionalArgument("PATH");
- config.Opts->AddLongOption("memorylog-file", "set buffer size for memory log").OptionalArgument("PATH");
+ config.Opts->AddLongOption("kqp-file", "Kikimr Query Processor config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("incrhuge-file", "incremental huge blob keeper config file").OptionalArgument("PATH");
+ config.Opts->AddLongOption("memorylog-file", "set buffer size for memory log").OptionalArgument("PATH");
config.Opts->AddLongOption("pq-file", "PersQueue config file").OptionalArgument("PATH");
config.Opts->AddLongOption("pqcd-file", "PersQueue cluster discovery config file").OptionalArgument("PATH");
config.Opts->AddLongOption("netclassifier-file", "NetClassifier config file").OptionalArgument("PATH");
@@ -234,9 +234,9 @@ protected:
.RequiredArgument("NAME").StoreResult(&NodeType);
config.Opts->AddLongOption("ignore-cms-configs", "Don't load configs from CMS")
.NoArgument().SetFlag(&IgnoreCmsConfigs);
- config.Opts->AddLongOption("cert", "Path to client certificate file (PEM)").RequiredArgument("PATH").StoreResult(&PathToCert);
- config.Opts->AddLongOption("key", "Path to private key file (PEM)").RequiredArgument("PATH").StoreResult(&PathToPKey);
- config.Opts->AddLongOption("ca", "Path to certificate authority file (PEM)").RequiredArgument("PATH").StoreResult(&PathToCA);
+ config.Opts->AddLongOption("cert", "Path to client certificate file (PEM)").RequiredArgument("PATH").StoreResult(&PathToCert);
+ config.Opts->AddLongOption("key", "Path to private key file (PEM)").RequiredArgument("PATH").StoreResult(&PathToPKey);
+ config.Opts->AddLongOption("ca", "Path to certificate authority file (PEM)").RequiredArgument("PATH").StoreResult(&PathToCA);
config.Opts->AddLongOption("data-center", "data center name (used to describe dynamic node location)")
.RequiredArgument("NAME").StoreResult(&DataCenter);
config.Opts->AddLongOption("rack", "rack name (used to describe dynamic node location)")
@@ -247,43 +247,43 @@ protected:
config.Opts->AddLongOption("cms-config-cache-file", "Path to CMS cache config file").OptionalArgument("PATH")
.StoreResult(&RunConfig.PathToConfigCacheFile);
config.Opts->AddHelpOption('h');
-
- // add messagebus proxy options
- config.Opts->AddLongOption("mbus", "Start MessageBus proxy").NoArgument();
- config.Opts->AddLongOption("mbus-port", "MessageBus proxy port").RequiredArgument("PORT").StoreResult(&BusProxyPort);
- config.Opts->AddLongOption("mbus-trace-path", "Path for trace files").RequiredArgument("PATH").StoreResult(&TracePath);
- SetMsgBusDefaults(ProxyBusSessionConfig, ProxyBusQueueConfig);
- ProxyBusSessionConfig.ConfigureLastGetopt(*config.Opts, "mbus-");
- ProxyBusQueueConfig.ConfigureLastGetopt(*config.Opts, "mbus-");
-
+
+ // add messagebus proxy options
+ config.Opts->AddLongOption("mbus", "Start MessageBus proxy").NoArgument();
+ config.Opts->AddLongOption("mbus-port", "MessageBus proxy port").RequiredArgument("PORT").StoreResult(&BusProxyPort);
+ config.Opts->AddLongOption("mbus-trace-path", "Path for trace files").RequiredArgument("PATH").StoreResult(&TracePath);
+ SetMsgBusDefaults(ProxyBusSessionConfig, ProxyBusQueueConfig);
+ ProxyBusSessionConfig.ConfigureLastGetopt(*config.Opts, "mbus-");
+ ProxyBusQueueConfig.ConfigureLastGetopt(*config.Opts, "mbus-");
+
config.Opts->AddLongOption("hierarchic-cfg", "Use hierarchical approach for configuration parts overriding")
.NoArgument().SetFlag(&HierarchicalCfg);
config.SetFreeArgsMin(0);
- config.Opts->SetFreeArgDefaultTitle("PATH", "path to protobuf file; files are merged in order in which they are enlisted");
+ config.Opts->SetFreeArgDefaultTitle("PATH", "path to protobuf file; files are merged in order in which they are enlisted");
}
- template<typename TProto>
+ template<typename TProto>
TProto *MutableConfigPart(TConfig& config, const char *optname,
- bool (NKikimrConfig::TAppConfig::*hasConfig)() const,
- const TProto& (NKikimrConfig::TAppConfig::*getConfig)() const,
- TProto* (NKikimrConfig::TAppConfig::*mutableConfig)()) {
- TProto *res = nullptr;
+ bool (NKikimrConfig::TAppConfig::*hasConfig)() const,
+ const TProto& (NKikimrConfig::TAppConfig::*getConfig)() const,
+ TProto* (NKikimrConfig::TAppConfig::*mutableConfig)()) {
+ TProto *res = nullptr;
if (!HierarchicalCfg && (AppConfig.*hasConfig)()) {
- return nullptr; // this field is already provided in AppConfig, so we don't overwrite it
- }
-
- if (config.ParseResult->Has(optname)) {
- const bool success = ParsePBFromFile(config.ParseResult->Get(optname), res = (AppConfig.*mutableConfig)());
- Y_VERIFY(success);
- } else if ((BaseConfig.*hasConfig)()) {
- res = (AppConfig.*mutableConfig)();
- res->CopyFrom((BaseConfig.*getConfig)());
- }
-
- return res;
- }
-
+ return nullptr; // this field is already provided in AppConfig, so we don't overwrite it
+ }
+
+ if (config.ParseResult->Has(optname)) {
+ const bool success = ParsePBFromFile(config.ParseResult->Get(optname), res = (AppConfig.*mutableConfig)());
+ Y_VERIFY(success);
+ } else if ((BaseConfig.*hasConfig)()) {
+ res = (AppConfig.*mutableConfig)();
+ res->CopyFrom((BaseConfig.*getConfig)());
+ }
+
+ return res;
+ }
+
template<typename TProto>
TProto *MutableConfigPartMerge(TConfig& config, const char *optname,
TProto* (NKikimrConfig::TAppConfig::*mutableConfig)()) {
@@ -304,32 +304,32 @@ protected:
TClientCommand::Parse(config);
#define OPTION(NAME, FIELD) MutableConfigPart(config, NAME, &NKikimrConfig::TAppConfig::Has##FIELD, \
- &NKikimrConfig::TAppConfig::Get##FIELD, &NKikimrConfig::TAppConfig::Mutable##FIELD)
+ &NKikimrConfig::TAppConfig::Get##FIELD, &NKikimrConfig::TAppConfig::Mutable##FIELD)
#define OPTION_MERGE(NAME, FIELD) MutableConfigPartMerge(config, NAME, &NKikimrConfig::TAppConfig::Mutable##FIELD)
-
+
OPTION("auth-file", AuthConfig);
OPTION_MERGE("auth-token-file", AuthConfig);
LoadBaseConfig(config);
LoadYamlConfig();
- // start memorylog as soon as possible
- if (auto mem = OPTION("memorylog-file", MemoryLogConfig)) {
- if (mem->HasLogBufferSize() && mem->GetLogBufferSize() > 0) {
- if (mem->HasLogGrainSize() && mem->GetLogGrainSize() > 0) {
- TMemoryLog::CreateMemoryLogBuffer(mem->GetLogBufferSize(), mem->GetLogGrainSize());
- } else {
- TMemoryLog::CreateMemoryLogBuffer(mem->GetLogBufferSize());
- }
- MemLogWriteNullTerm("Memory_log_has_been_started_YAHOO_");
- }
- }
-
- OPTION("naming-file", NameserviceConfig);
+ // start memorylog as soon as possible
+ if (auto mem = OPTION("memorylog-file", MemoryLogConfig)) {
+ if (mem->HasLogBufferSize() && mem->GetLogBufferSize() > 0) {
+ if (mem->HasLogGrainSize() && mem->GetLogGrainSize() > 0) {
+ TMemoryLog::CreateMemoryLogBuffer(mem->GetLogBufferSize(), mem->GetLogGrainSize());
+ } else {
+ TMemoryLog::CreateMemoryLogBuffer(mem->GetLogBufferSize());
+ }
+ MemLogWriteNullTerm("Memory_log_has_been_started_YAHOO_");
+ }
+ }
+
+ OPTION("naming-file", NameserviceConfig);
if (config.ParseResult->Has("node")) {
if (NodeIdValue == "static") {
- if (!AppConfig.HasNameserviceConfig() || !InterconnectPort)
+ if (!AppConfig.HasNameserviceConfig() || !InterconnectPort)
ythrow yexception() << "'--node static' requires naming file and IC port to be specified";
TString hostname;
try {
@@ -373,15 +373,15 @@ protected:
LoadYamlConfig();
- OPTION("sys-file", ActorSystemConfig);
+ OPTION("sys-file", ActorSystemConfig);
if (!AppConfig.HasActorSystemConfig()) {
- AppConfig.MutableActorSystemConfig()->CopyFrom(*DummyActorSystemConfig());
+ AppConfig.MutableActorSystemConfig()->CopyFrom(*DummyActorSystemConfig());
}
- OPTION("domains-file", DomainsConfig);
- OPTION("bs-file", BlobStorageConfig);
+ OPTION("domains-file", DomainsConfig);
+ OPTION("bs-file", BlobStorageConfig);
- if (auto logConfig = OPTION("log-file", LogConfig)) {
+ if (auto logConfig = OPTION("log-file", LogConfig)) {
if (config.ParseResult->Has("syslog"))
logConfig->SetSysLog(true);
if (config.ParseResult->Has("log-level"))
@@ -403,37 +403,37 @@ protected:
if (config.ParseResult->Has("log-file-name"))
AppConfig.MutableLogConfig()->SetBackendFileName(LogFileName);
- if (auto interconnectConfig = OPTION("ic-file", InterconnectConfig)) {
- if (config.ParseResult->Has("tcp")) {
- interconnectConfig->SetStartTcp(true);
- }
+ if (auto interconnectConfig = OPTION("ic-file", InterconnectConfig)) {
+ if (config.ParseResult->Has("tcp")) {
+ interconnectConfig->SetStartTcp(true);
+ }
}
- OPTION("channels-file", ChannelProfileConfig);
+ OPTION("channels-file", ChannelProfileConfig);
- if (auto bootstrapConfig = OPTION("bootstrap-file", BootstrapConfig)) {
- bootstrapConfig->MutableCompileServiceConfig()->SetInflightLimit(CompileInflightLimit);
+ if (auto bootstrapConfig = OPTION("bootstrap-file", BootstrapConfig)) {
+ bootstrapConfig->MutableCompileServiceConfig()->SetInflightLimit(CompileInflightLimit);
}
- OPTION("vdisk-file", VDiskConfig);
- OPTION("drivemodel-file", DriveModelConfig);
- OPTION("grpc-file", GRpcConfig);
- OPTION("tenant-pool-file", TenantPoolConfig);
- OPTION("dyn-nodes-file", DynamicNameserviceConfig);
- OPTION("cms-file", CmsConfig);
- OPTION("pq-file", PQConfig);
+ OPTION("vdisk-file", VDiskConfig);
+ OPTION("drivemodel-file", DriveModelConfig);
+ OPTION("grpc-file", GRpcConfig);
+ OPTION("tenant-pool-file", TenantPoolConfig);
+ OPTION("dyn-nodes-file", DynamicNameserviceConfig);
+ OPTION("cms-file", CmsConfig);
+ OPTION("pq-file", PQConfig);
OPTION("pqcd-file", PQClusterDiscoveryConfig);
OPTION("netclassifier-file", NetClassifierConfig);
OPTION("auth-file", AuthConfig);
OPTION_MERGE("auth-token-file", AuthConfig);
- OPTION("key-file", KeyConfig);
+ OPTION("key-file", KeyConfig);
OPTION("pdisk-key-file", PDiskKeyConfig);
- OPTION("sqs-file", SqsConfig);
- OPTION("feature-flags-file", FeatureFlags);
+ OPTION("sqs-file", SqsConfig);
+ OPTION("feature-flags-file", FeatureFlags);
OPTION("rb-file", ResourceBrokerConfig);
OPTION("metering-file", MeteringConfig);
- OPTION("kqp-file", KQPConfig);
- OPTION("incrhuge-file", IncrHugeConfig);
+ OPTION("kqp-file", KQPConfig);
+ OPTION("incrhuge-file", IncrHugeConfig);
OPTION("alloc-file", AllocatorConfig);
OPTION("yq-file", YandexQueryConfig);
@@ -441,35 +441,35 @@ protected:
AppConfig.MutableAllocatorConfig()->CopyFrom(*DummyAllocatorConfig());
}
- // apply certificates, if any
- if (config.ParseResult->Has("cert")) {
- AppConfig.MutableInterconnectConfig()->SetPathToCertificateFile(PathToCert);
- }
- if (config.ParseResult->Has("key")) {
- AppConfig.MutableInterconnectConfig()->SetPathToPrivateKeyFile(PathToPKey);
- }
- if (config.ParseResult->Has("ca")) {
- AppConfig.MutableInterconnectConfig()->SetPathToCaFile(PathToCA);
- }
-
- if (!AppConfig.HasDomainsConfig())
- ythrow yexception() << "DomainsConfig is not provided";
- if (!AppConfig.HasChannelProfileConfig())
- ythrow yexception() << "ChannelProfileConfig is not provided";
-
- if ((!config.ParseResult->Has("tenant") || TenantName == "no") && RunConfig.ScopeId.IsEmpty()) {
- const TString myDomain = DeduceNodeDomain();
- for (const auto& domain : AppConfig.GetDomainsConfig().GetDomain()) {
- if (domain.GetName() == myDomain) {
- RunConfig.ScopeId = TKikimrScopeId(0, domain.GetDomainId());
- break;
- }
- }
- }
- if (TenantName == "dynamic") {
- Y_VERIFY(RunConfig.ScopeId.IsEmpty());
- RunConfig.ScopeId = TKikimrScopeId::DynamicTenantScopeId;
- }
+ // apply certificates, if any
+ if (config.ParseResult->Has("cert")) {
+ AppConfig.MutableInterconnectConfig()->SetPathToCertificateFile(PathToCert);
+ }
+ if (config.ParseResult->Has("key")) {
+ AppConfig.MutableInterconnectConfig()->SetPathToPrivateKeyFile(PathToPKey);
+ }
+ if (config.ParseResult->Has("ca")) {
+ AppConfig.MutableInterconnectConfig()->SetPathToCaFile(PathToCA);
+ }
+
+ if (!AppConfig.HasDomainsConfig())
+ ythrow yexception() << "DomainsConfig is not provided";
+ if (!AppConfig.HasChannelProfileConfig())
+ ythrow yexception() << "ChannelProfileConfig is not provided";
+
+ if ((!config.ParseResult->Has("tenant") || TenantName == "no") && RunConfig.ScopeId.IsEmpty()) {
+ const TString myDomain = DeduceNodeDomain();
+ for (const auto& domain : AppConfig.GetDomainsConfig().GetDomain()) {
+ if (domain.GetName() == myDomain) {
+ RunConfig.ScopeId = TKikimrScopeId(0, domain.GetDomainId());
+ break;
+ }
+ }
+ }
+ if (TenantName == "dynamic") {
+ Y_VERIFY(RunConfig.ScopeId.IsEmpty());
+ RunConfig.ScopeId = TKikimrScopeId::DynamicTenantScopeId;
+ }
if (NodeId)
RunConfig.NodeId = NodeId;
if (AppConfig.HasNameserviceConfig() && NodeId) {
@@ -497,13 +497,13 @@ protected:
}
Y_VERIFY(nodeIdMatchesConfig, "Cannot find passed NodeId = %" PRIu32 " for hostname %s", NodeId, hostname.data());
}
- if (config.ParseResult->Has("suppress-version-check")) {
- if (AppConfig.HasNameserviceConfig()) {
- AppConfig.MutableNameserviceConfig()->SetSuppressVersionCheck(true);
- } else {
- ythrow yexception() << "--suppress-version-check option is provided without static nameservice config";
- }
- }
+ if (config.ParseResult->Has("suppress-version-check")) {
+ if (AppConfig.HasNameserviceConfig()) {
+ AppConfig.MutableNameserviceConfig()->SetSuppressVersionCheck(true);
+ } else {
+ ythrow yexception() << "--suppress-version-check option is provided without static nameservice config";
+ }
+ }
// apply options affecting UDF paths
if (!AppConfig.HasUDFsDir())
@@ -607,23 +607,23 @@ protected:
}
}
- // MessageBus options.
-
+ // MessageBus options.
+
if (!AppConfig.HasMessageBusConfig()) {
auto messageBusConfig = AppConfig.MutableMessageBusConfig();
messageBusConfig->SetStartBusProxy(config.ParseResult->Has(config.Opts->FindLongOption("mbus")));
messageBusConfig->SetBusProxyPort(BusProxyPort);
-
+
if (!messageBusConfig->GetStartBusProxy()) {
for (const auto &option : config.Opts->Opts_) {
for (const TString &longName : option->GetLongNames()) {
if (longName.StartsWith("mbus-") && config.ParseResult->Has(option.Get())) {
ythrow yexception() << "option --" << longName << " is useless without --mbus option";
}
- }
- }
- }
-
+ }
+ }
+ }
+
auto queueConfig = messageBusConfig->MutableProxyBusQueueConfig();
queueConfig->SetName(ProxyBusQueueConfig.Name);
queueConfig->SetNumWorkers(ProxyBusQueueConfig.NumWorkers);
@@ -861,24 +861,24 @@ protected:
const TString &domainName,
const TString &nodeHost,
const TString &nodeAddress,
- const TString &nodeResolveHost,
+ const TString &nodeResolveHost,
const TMaybe<TString>& path) {
NClient::TKikimr kikimr(GetKikimr(addr));
auto registrant = kikimr.GetNodeRegistrant();
-
- NActorsInterconnect::TNodeLocation location;
- location.SetDataCenter(DataCenter);
- location.SetRack(Rack);
- location.SetUnit(ToString(Body));
- TNodeLocation loc(location);
-
- NActorsInterconnect::TNodeLocation legacy;
- legacy.SetDataCenterNum(DataCenterFromString(DataCenter));
- legacy.SetRoomNum(0);
- legacy.SetRackNum(RackFromString(Rack));
- legacy.SetBodyNum(Body);
- loc.InheritLegacyValue(TNodeLocation(legacy));
-
+
+ NActorsInterconnect::TNodeLocation location;
+ location.SetDataCenter(DataCenter);
+ location.SetRack(Rack);
+ location.SetUnit(ToString(Body));
+ TNodeLocation loc(location);
+
+ NActorsInterconnect::TNodeLocation legacy;
+ legacy.SetDataCenterNum(DataCenterFromString(DataCenter));
+ legacy.SetRoomNum(0);
+ legacy.SetRackNum(RackFromString(Rack));
+ legacy.SetBodyNum(Body);
+ loc.InheritLegacyValue(TNodeLocation(legacy));
+
Cout << "Trying to register at " << addr << Endl;
return MakeHolder<NClient::TRegistrationResult>
@@ -887,9 +887,9 @@ protected:
InterconnectPort,
nodeAddress,
nodeResolveHost,
- std::move(loc),
- FixedNodeID,
- path));
+ std::move(loc),
+ FixedNodeID,
+ path));
}
void FillClusterEndpoints(TVector<TString> &addrs) {
@@ -916,13 +916,13 @@ protected:
}
}
- TMaybe<TString> GetSchemePath() {
- if (TenantName.StartsWith('/')) {
- return TenantName; // TODO(alexvru): fix it
- }
- return {};
- }
-
+ TMaybe<TString> GetSchemePath() {
+ if (TenantName.StartsWith('/')) {
+ return TenantName; // TODO(alexvru): fix it
+ }
+ return {};
+ }
+
void RegisterDynamicNode() {
TVector<TString> addrs;
auto &dnConfig = *RunConfig.AppConfig.MutableDynamicNodeConfig();
@@ -945,7 +945,7 @@ protected:
THolder<NClient::TRegistrationResult> result;
while (!result || !result->IsSuccess()) {
for (auto addr : addrs) {
- result = TryToRegisterDynamicNode(addr, domainName, NodeHost, NodeAddress, NodeResolveHost, GetSchemePath());
+ result = TryToRegisterDynamicNode(addr, domainName, NodeHost, NodeAddress, NodeResolveHost, GetSchemePath());
if (result->IsSuccess()) {
Cout << "Success. Registered as " << result->GetNodeId() << Endl;
break;
@@ -961,7 +961,7 @@ protected:
ythrow yexception() << "Cannot register dynamic node: " << result->GetErrorMessage();
RunConfig.NodeId = result->GetNodeId();
- RunConfig.ScopeId = TKikimrScopeId(result->GetScopeId());
+ RunConfig.ScopeId = TKikimrScopeId(result->GetScopeId());
auto &nsConfig = *RunConfig.AppConfig.MutableNameserviceConfig();
nsConfig.ClearNode();
@@ -1110,48 +1110,48 @@ private:
}
};
-class TClientCommandServerConfig : public TClientCommandServerBase {
-public:
- TClientCommandServerConfig()
- : TClientCommandServerBase("serverconfig", "Generate configs for new-style invocation of server")
- {
- }
-
- virtual void Config(TConfig& config) override {
- TClientCommandServerBase::Config(config);
- config.Opts->AddLongOption("dump-config-to", "Dump final application config protobuf to PATH and terminate").RequiredArgument("PATH").Required();
- }
-
- virtual int Run(TConfig& config) override {
- Y_VERIFY(config.ParseResult->Has("dump-config-to"));
-
- TString proto;
- const bool status = google::protobuf::TextFormat::PrintToString(AppConfig, &proto);
- Y_VERIFY(status);
- TString path = config.ParseResult->Get("dump-config-to");
- TFileOutput file(path);
- file << proto;
-
- return 0;
- }
-};
-
-class TClientCommandServer : public TClientCommandServerBase {
-public:
+class TClientCommandServerConfig : public TClientCommandServerBase {
+public:
+ TClientCommandServerConfig()
+ : TClientCommandServerBase("serverconfig", "Generate configs for new-style invocation of server")
+ {
+ }
+
+ virtual void Config(TConfig& config) override {
+ TClientCommandServerBase::Config(config);
+ config.Opts->AddLongOption("dump-config-to", "Dump final application config protobuf to PATH and terminate").RequiredArgument("PATH").Required();
+ }
+
+ virtual int Run(TConfig& config) override {
+ Y_VERIFY(config.ParseResult->Has("dump-config-to"));
+
+ TString proto;
+ const bool status = google::protobuf::TextFormat::PrintToString(AppConfig, &proto);
+ Y_VERIFY(status);
+ TString path = config.ParseResult->Get("dump-config-to");
+ TFileOutput file(path);
+ file << proto;
+
+ return 0;
+ }
+};
+
+class TClientCommandServer : public TClientCommandServerBase {
+public:
TClientCommandServer(std::shared_ptr<TModuleFactories> factories)
- : TClientCommandServerBase("server", "Execute KiKiMR server")
+ : TClientCommandServerBase("server", "Execute KiKiMR server")
, Factories(std::move(factories))
- {}
-
- virtual int Run(TConfig &/*config*/) override {
- Y_VERIFY(RunConfig.NodeId);
+ {}
+
+ virtual int Run(TConfig &/*config*/) override {
+ Y_VERIFY(RunConfig.NodeId);
return MainRun(RunConfig, Factories);
- }
+ }
private:
std::shared_ptr<TModuleFactories> Factories;
-};
-
+};
+
void AddClientCommandServer(TClientCommandTree& parent, std::shared_ptr<TModuleFactories> factories) {
parent.AddCommand(std::make_unique<TClientCommandServer>(factories));
parent.AddCommand(std::make_unique<TClientCommandServerConfig>());
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
index 361e757ca1d..ebb8eaf52a5 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
@@ -11,11 +11,11 @@ public:
{}
TString ProtoBuf;
- TAutoPtr<NKikimrClient::TKeyValueRequest> Request;
+ TAutoPtr<NKikimrClient::TKeyValueRequest> Request;
TString OutputFile;
TString InputFile;
- int OnResponse(const NKikimrClient::TResponse& response) {
+ int OnResponse(const NKikimrClient::TResponse& response) {
if (!OutputFile.empty()) {
Y_VERIFY(response.ReadResultSize() == 1);
Y_VERIFY(response.GetReadResult(0).HasStatus());
@@ -61,7 +61,7 @@ public:
virtual void Parse(TConfig& config) override {
TClientCommand::Parse(config);
ProtoBuf = config.ParseResult->GetFreeArgs().at(0);
- Request = GetProtobuf<NKikimrClient::TKeyValueRequest>(ProtoBuf);
+ Request = GetProtobuf<NKikimrClient::TKeyValueRequest>(ProtoBuf);
if (!InputFile.empty()) {
Y_VERIFY(Request->CmdWriteSize() == 1);
Y_VERIFY(Request->GetCmdWrite(0).HasKey());
diff --git a/ydb/core/driver_lib/cli_utils/cli_keyvalue.cpp b/ydb/core/driver_lib/cli_utils/cli_keyvalue.cpp
index a1756c0b11d..b25400e9383 100644
--- a/ydb/core/driver_lib/cli_utils/cli_keyvalue.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_keyvalue.cpp
@@ -1,7 +1,7 @@
#include "cli.h"
#include <google/protobuf/text_format.h>
#include <util/stream/file.h>
-#include <util/string/printf.h>
+#include <util/string/printf.h>
namespace NKikimr {
namespace NDriverClient {
@@ -22,12 +22,12 @@ struct TCmdKeyValueConfig : public TCliCmdConfig {
template<typename TSuccessOp>
int ClientSyncCall(TAutoPtr<NBus::TBusMessage> request, const TCliCmdConfig &cliConfig, TSuccessOp successOp) {
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = cliConfig.SyncCall(request, reply);
+ NBus::EMessageStatus status = cliConfig.SyncCall(request, reply);
switch (status) {
case NBus::MESSAGE_OK:
{
- const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
successOp(response);
return response.GetStatus() == NMsgBusProxy::MSTATUS_OK ? 0 : 1;
}
@@ -53,85 +53,85 @@ int KeyValueRequest(TCommandConfig &cmdConf, int argc, char **argv) {
requestConfig.Parse(argc, argv);
TVector<NKikimrClient::TKeyValueRequest> records;
- NKikimrClient::TKeyValueRequest& record = *records.emplace(records.end());
-
- const bool isOk = ::google::protobuf::TextFormat::ParseFromString(requestConfig.Proto, &record);
+ NKikimrClient::TKeyValueRequest& record = *records.emplace(records.end());
+
+ const bool isOk = ::google::protobuf::TextFormat::ParseFromString(requestConfig.Proto, &record);
if (!isOk) {
ythrow TWithBackTrace<yexception>() << "Error parsing protobuf: \'" << requestConfig.Proto << "\'";
}
- const ui32 maxReadBlockSize = 20 << 20;
- const ui32 maxWriteBlockSize = 16 << 20;
-
+ const ui32 maxReadBlockSize = 20 << 20;
+ const ui32 maxWriteBlockSize = 16 << 20;
+
TString readBuffer;
- if (requestConfig.IsReadToFile) {
- Y_VERIFY(record.CmdReadSize() == 1);
- auto& cmdRead = *record.MutableCmdRead(0);
- cmdRead.SetSize(maxReadBlockSize);
- }
-
+ if (requestConfig.IsReadToFile) {
+ Y_VERIFY(record.CmdReadSize() == 1);
+ auto& cmdRead = *record.MutableCmdRead(0);
+ cmdRead.SetSize(maxReadBlockSize);
+ }
+
if (requestConfig.IsWriteFromFile) {
- Y_VERIFY(record.CmdWriteSize() == 1);
- Y_VERIFY(record.GetCmdWrite(0).HasKey());
- Y_VERIFY(!record.GetCmdWrite(0).HasValue());
+ Y_VERIFY(record.CmdWriteSize() == 1);
+ Y_VERIFY(record.GetCmdWrite(0).HasKey());
+ Y_VERIFY(!record.GetCmdWrite(0).HasValue());
TString data = TUnbufferedFileInput(requestConfig.WriteFromPath).ReadAll();
if (data.size() <= maxWriteBlockSize) {
- record.MutableCmdWrite(0)->SetValue(data);
- } else {
- const auto& originalCmdWrite = record.GetCmdWrite(0);
+ record.MutableCmdWrite(0)->SetValue(data);
+ } else {
+ const auto& originalCmdWrite = record.GetCmdWrite(0);
TString key = originalCmdWrite.GetKey();
TVector<TString> parts;
-
- ui64 tabletId = record.GetTabletId();
-
- TMaybe<NKikimrClient::TKeyValueRequest::EStorageChannel> storageChannel;
- if (originalCmdWrite.HasStorageChannel()) {
- storageChannel = originalCmdWrite.GetStorageChannel();
- }
-
- TMaybe<NKikimrClient::TKeyValueRequest::EPriority> priority;
- if (originalCmdWrite.HasPriority()) {
- priority = originalCmdWrite.GetPriority();
- }
-
- records.clear();
-
+
+ ui64 tabletId = record.GetTabletId();
+
+ TMaybe<NKikimrClient::TKeyValueRequest::EStorageChannel> storageChannel;
+ if (originalCmdWrite.HasStorageChannel()) {
+ storageChannel = originalCmdWrite.GetStorageChannel();
+ }
+
+ TMaybe<NKikimrClient::TKeyValueRequest::EPriority> priority;
+ if (originalCmdWrite.HasPriority()) {
+ priority = originalCmdWrite.GetPriority();
+ }
+
+ records.clear();
+
for (ui32 offset = 0, partId = 0; offset < data.size(); ++partId) {
const ui32 size = Min<ui32>(maxWriteBlockSize, data.size() - offset);
- NKikimrClient::TKeyValueRequest& last = *records.emplace(records.end());
- last.SetTabletId(tabletId);
- auto& cmdWrite = *last.AddCmdWrite();
+ NKikimrClient::TKeyValueRequest& last = *records.emplace(records.end());
+ last.SetTabletId(tabletId);
+ auto& cmdWrite = *last.AddCmdWrite();
TString partKey = Sprintf("%s@PartId#%09" PRIu32, key.data(), partId);
- cmdWrite.SetKey(partKey);
- cmdWrite.SetValue(data.substr(offset, size));
- if (storageChannel) {
- cmdWrite.SetStorageChannel(*storageChannel);
- }
- if (priority) {
- cmdWrite.SetPriority(*priority);
- }
- parts.push_back(partKey);
- offset += size;
- }
-
- NKikimrClient::TKeyValueRequest& last = *records.emplace(records.end());
- last.SetTabletId(tabletId);
- auto& cmdConcat = *last.AddCmdConcat();
+ cmdWrite.SetKey(partKey);
+ cmdWrite.SetValue(data.substr(offset, size));
+ if (storageChannel) {
+ cmdWrite.SetStorageChannel(*storageChannel);
+ }
+ if (priority) {
+ cmdWrite.SetPriority(*priority);
+ }
+ parts.push_back(partKey);
+ offset += size;
+ }
+
+ NKikimrClient::TKeyValueRequest& last = *records.emplace(records.end());
+ last.SetTabletId(tabletId);
+ auto& cmdConcat = *last.AddCmdConcat();
for (const TString& part : parts) {
- cmdConcat.AddInputKeys(part);
- }
- cmdConcat.SetOutputKey(key);
- cmdConcat.SetKeepInputs(false);
- }
+ cmdConcat.AddInputKeys(part);
+ }
+ cmdConcat.SetOutputKey(key);
+ cmdConcat.SetKeepInputs(false);
+ }
}
- auto successOp = [&](const NKikimrClient::TResponse &response) {
+ auto successOp = [&](const NKikimrClient::TResponse &response) {
const ui32 status = response.GetStatus();
Cout << "status: " << status << Endl;
Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl;
- if (status != NMsgBusProxy::MSTATUS_OK) {
- Cout << "error reason: " << response.GetErrorReason() << Endl;
- }
+ if (status != NMsgBusProxy::MSTATUS_OK) {
+ Cout << "error reason: " << response.GetErrorReason() << Endl;
+ }
if (requestConfig.IsReadToFile) {
Y_VERIFY(status == NMsgBusProxy::MSTATUS_OK);
@@ -140,24 +140,24 @@ int KeyValueRequest(TCommandConfig &cmdConf, int argc, char **argv) {
Y_VERIFY(response.GetReadResult(0).GetStatus() == NKikimrProto::OK);
Y_VERIFY(response.GetReadResult(0).HasValue());
TString data = response.GetReadResult(0).GetValue();
- readBuffer += data;
-
+ readBuffer += data;
+
if (data.size() == maxReadBlockSize) {
- auto& last = *records.emplace(records.end());
- last = records[0];
+ auto& last = *records.emplace(records.end());
+ last = records[0];
last.MutableCmdRead(0)->SetOffset(readBuffer.size());
- }
+ }
} else if (requestConfig.IsWriteFromFile) {
Y_VERIFY(status == NMsgBusProxy::MSTATUS_OK);
- if (response.WriteResultSize() == 1) {
- Y_VERIFY(response.GetWriteResult(0).HasStatus());
- Y_VERIFY(response.GetWriteResult(0).GetStatus() == NKikimrProto::OK);
- } else if (response.ConcatResultSize() == 1) {
- Y_VERIFY(response.GetConcatResult(0).HasStatus());
- Y_VERIFY(response.GetConcatResult(0).GetStatus() == NKikimrProto::OK);
- } else {
- Y_FAIL("unexpected case");
- }
+ if (response.WriteResultSize() == 1) {
+ Y_VERIFY(response.GetWriteResult(0).HasStatus());
+ Y_VERIFY(response.GetWriteResult(0).GetStatus() == NKikimrProto::OK);
+ } else if (response.ConcatResultSize() == 1) {
+ Y_VERIFY(response.GetConcatResult(0).HasStatus());
+ Y_VERIFY(response.GetConcatResult(0).GetStatus() == NKikimrProto::OK);
+ } else {
+ Y_FAIL("unexpected case");
+ }
} else {
TString str;
const bool isOk = ::google::protobuf::TextFormat::PrintToString(response, &str);
@@ -166,25 +166,25 @@ int KeyValueRequest(TCommandConfig &cmdConf, int argc, char **argv) {
}
Cout << "response: " << str << Endl;
}
- };
-
+ };
+
int status = 0;
for (size_t i = 0; i < records.size(); ++i) {
- auto request = MakeHolder<NMsgBusProxy::TBusKeyValue>();
- request->Record = records[i];
- status = ClientSyncCall(request.Release(), requestConfig, successOp);
- if (status) {
- break;
- }
- }
-
- if (requestConfig.IsReadToFile) {
- TFile file(requestConfig.ReadToPath, CreateNew | WrOnly);
+ auto request = MakeHolder<NMsgBusProxy::TBusKeyValue>();
+ request->Record = records[i];
+ status = ClientSyncCall(request.Release(), requestConfig, successOp);
+ if (status) {
+ break;
+ }
+ }
+
+ if (requestConfig.IsReadToFile) {
+ TFile file(requestConfig.ReadToPath, CreateNew | WrOnly);
file.Write(readBuffer.data(), readBuffer.size());
- file.Close();
- }
-
- return status;
+ file.Close();
+ }
+
+ return status;
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_load.cpp b/ydb/core/driver_lib/cli_utils/cli_load.cpp
index c2567f5e4f9..7fc8a9ec1ad 100644
--- a/ydb/core/driver_lib/cli_utils/cli_load.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_load.cpp
@@ -1,63 +1,63 @@
-#include "cli.h"
+#include "cli.h"
#include <google/protobuf/text_format.h>
-
-namespace NKikimr {
-namespace NDriverClient {
-
-struct TCmdLoadConfig : public TCliCmdConfig {
+
+namespace NKikimr {
+namespace NDriverClient {
+
+struct TCmdLoadConfig : public TCliCmdConfig {
TString Proto;
-
- void Parse(int argc, char **argv) {
- using namespace NLastGetopt;
- TOpts opts = TOpts::Default();
- opts.AddLongOption("protobuf", "string representation of the keyvalue request protobuf").Required()
- .RequiredArgument("PROTOBUF").StoreResult(&Proto);
-
- ConfigureBaseLastGetopt(opts);
- TOptsParseResult res(&opts, argc, argv);
- ConfigureMsgBusLastGetopt(res, argc, argv);
- }
-};
-
-int LoadRequest(TCommandConfig& /*cmdConf*/, int argc, char **argv) {
- TCmdLoadConfig config;
- config.Parse(argc, argv);
-
- TAutoPtr<NMsgBusProxy::TBusBsTestLoadRequest> request(new NMsgBusProxy::TBusBsTestLoadRequest);
- const bool isOk = ::google::protobuf::TextFormat::ParseFromString(config.Proto, &request->Record);
- if (!isOk) {
- ythrow TWithBackTrace<yexception>() << "Error parsing protobuf: '" << config.Proto << "'";
- }
-
- TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = config.SyncCall(request, reply);
-
- switch (status) {
- case NBus::MESSAGE_OK: {
- const NKikimrClient::TBsTestLoadResponse& response =
- static_cast<NMsgBusProxy::TBusBsTestLoadResponse *>(reply.Get())->Record;
- bool status = true;
- for (const NKikimrClient::TBsTestLoadResponse::TItem& item : response.GetItems()) {
- if (item.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- Cerr << "NodeId# " << item.GetNodeId() << " ErrorReason# " << item.GetErrorReason() << Endl;
- status = false;
- }
- }
- if (!status) {
- return EXIT_FAILURE;
- }
- break;
- }
-
- default: {
- const char *description = NBus::MessageStatusDescription(status);
- Cerr << description << Endl;
- return EXIT_FAILURE;
- }
- }
-
- return EXIT_SUCCESS;
-}
-
-} // NKikimr
-} // NDriverClient
+
+ void Parse(int argc, char **argv) {
+ using namespace NLastGetopt;
+ TOpts opts = TOpts::Default();
+ opts.AddLongOption("protobuf", "string representation of the keyvalue request protobuf").Required()
+ .RequiredArgument("PROTOBUF").StoreResult(&Proto);
+
+ ConfigureBaseLastGetopt(opts);
+ TOptsParseResult res(&opts, argc, argv);
+ ConfigureMsgBusLastGetopt(res, argc, argv);
+ }
+};
+
+int LoadRequest(TCommandConfig& /*cmdConf*/, int argc, char **argv) {
+ TCmdLoadConfig config;
+ config.Parse(argc, argv);
+
+ TAutoPtr<NMsgBusProxy::TBusBsTestLoadRequest> request(new NMsgBusProxy::TBusBsTestLoadRequest);
+ const bool isOk = ::google::protobuf::TextFormat::ParseFromString(config.Proto, &request->Record);
+ if (!isOk) {
+ ythrow TWithBackTrace<yexception>() << "Error parsing protobuf: '" << config.Proto << "'";
+ }
+
+ TAutoPtr<NBus::TBusMessage> reply;
+ NBus::EMessageStatus status = config.SyncCall(request, reply);
+
+ switch (status) {
+ case NBus::MESSAGE_OK: {
+ const NKikimrClient::TBsTestLoadResponse& response =
+ static_cast<NMsgBusProxy::TBusBsTestLoadResponse *>(reply.Get())->Record;
+ bool status = true;
+ for (const NKikimrClient::TBsTestLoadResponse::TItem& item : response.GetItems()) {
+ if (item.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ Cerr << "NodeId# " << item.GetNodeId() << " ErrorReason# " << item.GetErrorReason() << Endl;
+ status = false;
+ }
+ }
+ if (!status) {
+ return EXIT_FAILURE;
+ }
+ break;
+ }
+
+ default: {
+ const char *description = NBus::MessageStatusDescription(status);
+ Cerr << description << Endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
+
+} // NKikimr
+} // NDriverClient
diff --git a/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp b/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
index df1fa4a79f3..43dff4e123d 100644
--- a/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_mb_trace.cpp
@@ -44,9 +44,9 @@ int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv) {
} else {
NMsgBusProxy::TBusMessageBusTraceRequest *request(new NMsgBusProxy::TBusMessageBusTraceRequest());
if (messageBusTraceConfig.Command == "start") {
- request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
+ request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
} else if (messageBusTraceConfig.Command == "stop") {
- request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
+ request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
}
if (messageBusTraceConfig.Path)
request->Record.SetPath(messageBusTraceConfig.Path);
@@ -57,7 +57,7 @@ int MessageBusTrace(TCommandConfig &cmdConf, int argc, char** argv) {
switch (status) {
case NBus::MESSAGE_OK:
{
- const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
+ const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
// Cout << "status: " << response.GetStatus() << Endl;
// Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl;
Cout << "trace active: " << response.GetTraceActive() << Endl;
diff --git a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
index b4429d5721b..d4628592bdc 100644
--- a/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_minikql_compile_and_exec.cpp
@@ -43,7 +43,7 @@ int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv) {
NMiniKQL::TScopedAlloc alloc(countersStub);
NMiniKQL::TTypeEnvironment TypeEnv(alloc);
- TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
+ TAutoPtr<NMsgBusProxy::TBusRequest> request(new NMsgBusProxy::TBusRequest());
auto* mkqlTx = request->Record.MutableTransaction()->MutableMiniKQLTransaction();
if (config.PathToBinPgm) {
@@ -65,13 +65,13 @@ int CompileAndExecMiniKQL(TCommandConfig &cmdConf, int argc, char **argv) {
mkqlTx->SetFlatMKQL(true);
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus msgStatus = config.SyncCall(request, reply);
+ NBus::EMessageStatus msgStatus = config.SyncCall(request, reply);
if (msgStatus != NBus::MESSAGE_OK) {
Cerr << "Can't send request, msgstatus=" << msgStatus << ".\n";
return 1;
}
- const NKikimrClient::TResponse& response = static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
+ const NKikimrClient::TResponse& response = static_cast<NMsgBusProxy::TBusResponse*>(reply.Get())->Record;
auto txRes = response.GetMiniKQLCompileResults();
diff --git a/ydb/core/driver_lib/cli_utils/cli_persqueue.cpp b/ydb/core/driver_lib/cli_utils/cli_persqueue.cpp
index 66bc9151e50..108de78388e 100644
--- a/ydb/core/driver_lib/cli_utils/cli_persqueue.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_persqueue.cpp
@@ -25,7 +25,7 @@ int PersQueueRequest(TCommandConfig &cmdConf, int argc, char** argv) {
ythrow TWithBackTrace<yexception>() << "Error parsing protobuf: \'" << config.Proto << "\'";
}
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = config.SyncCall(request, reply);
+ NBus::EMessageStatus status = config.SyncCall(request, reply);
Cerr << status << "\n";
Y_VERIFY(status == NBus::MESSAGE_OK);
const auto& result = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
diff --git a/ydb/core/driver_lib/cli_utils/cli_persqueue_stress.cpp b/ydb/core/driver_lib/cli_utils/cli_persqueue_stress.cpp
index 39b6a0c07c9..77118cc2085 100644
--- a/ydb/core/driver_lib/cli_utils/cli_persqueue_stress.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_persqueue_stress.cpp
@@ -45,7 +45,7 @@ int PersQueueStress(TCommandConfig &cmdConf, int argc, char** argv) {
pr->SetPartition(config.Partition);
pr->MutableCmdGetOwnership();
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = config.SyncCall(request, reply);
+ NBus::EMessageStatus status = config.SyncCall(request, reply);
Y_VERIFY(status == NBus::MESSAGE_OK);
const auto& result = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
Cerr << result.DebugString() << "\n";
@@ -62,7 +62,7 @@ int PersQueueStress(TCommandConfig &cmdConf, int argc, char** argv) {
pr->SetPartition(config.Partition);
pr->MutableCmdGetMaxSeqNo()->AddSourceId(config.SourceId);
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = config.SyncCall(request, reply);
+ NBus::EMessageStatus status = config.SyncCall(request, reply);
Y_VERIFY(status == NBus::MESSAGE_OK);
const auto& result = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
Cerr << result.DebugString() << "\n";
@@ -87,7 +87,7 @@ int PersQueueStress(TCommandConfig &cmdConf, int argc, char** argv) {
totalSize += size;
}
TInstant tt = TInstant::Now();
- status = config.SyncCall(request, reply);
+ status = config.SyncCall(request, reply);
if (status != NBus::MESSAGE_OK)
Cerr << status << "\n";
Y_VERIFY(status == NBus::MESSAGE_OK);
@@ -132,7 +132,7 @@ int PersQueueStress(TCommandConfig &cmdConf, int argc, char** argv) {
read->SetCount(config.BatchSize);
read->SetClientId("user");
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = config.SyncCall(request, reply);
+ NBus::EMessageStatus status = config.SyncCall(request, reply);
Y_VERIFY(status == NBus::MESSAGE_OK);
const auto& result = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
if (result.GetStatus() != NMsgBusProxy::MSTATUS_OK || result.GetErrorCode() != NPersQueue::NErrorCode::OK) {
@@ -154,7 +154,7 @@ int PersQueueStress(TCommandConfig &cmdConf, int argc, char** argv) {
set->SetOffset(offset);
set->SetClientId("user");
- status = config.SyncCall(request, reply);
+ status = config.SyncCall(request, reply);
Y_VERIFY(status == NBus::MESSAGE_OK);
if (config.Speed) {
TInstant T2 = timestamp + TDuration::MilliSeconds(bytes * 1000 / 1024.0 / config.Speed);
diff --git a/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp b/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp
index ebca272cc4d..1055cc5da14 100644
--- a/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_scheme_initroot.cpp
@@ -28,7 +28,7 @@ int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv) {
TCmdSchemeInitShardConfig schemeInitShardConfig;
schemeInitShardConfig.Parse(argc, argv);
- TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot> request(new NMsgBusProxy::TBusSchemeInitRoot());
+ TAutoPtr<NMsgBusProxy::TBusSchemeInitRoot> request(new NMsgBusProxy::TBusSchemeInitRoot());
request->Record.SetTagName(schemeInitShardConfig.TagName);
@@ -36,12 +36,12 @@ int SchemeInitRoot(TCommandConfig &cmdConf, int argc, char** argv) {
request->Record.MutableGlobalConfig()->MergeFrom(*schemeInitShardConfig.GlobalConfig);
TAutoPtr<NBus::TBusMessage> reply;
- NBus::EMessageStatus status = schemeInitShardConfig.SyncCall(request, reply);
+ NBus::EMessageStatus status = schemeInitShardConfig.SyncCall(request, reply);
switch (status) {
case NBus::MESSAGE_OK:
{
- const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
Cout << "status: " << response.GetStatus() << Endl;
Cout << "status transcript: " << static_cast<NMsgBusProxy::EResponseStatus>(response.GetStatus()) << Endl;
if (response.HasTabletId())
diff --git a/ydb/core/driver_lib/cli_utils/proto_common.h b/ydb/core/driver_lib/cli_utils/proto_common.h
index 7220fa47eee..3abfe1a2519 100644
--- a/ydb/core/driver_lib/cli_utils/proto_common.h
+++ b/ydb/core/driver_lib/cli_utils/proto_common.h
@@ -1,32 +1,32 @@
-#pragma once
-
-namespace NKikimr {
- namespace NDriverClient {
-
+#pragma once
+
+namespace NKikimr {
+ namespace NDriverClient {
+
inline TString GetProtobufEnumOptions(const google::protobuf::EnumDescriptor *desc) {
- TStringStream options;
- options << "{";
- for (int i = 0; i < desc->value_count(); ++i) {
- options << (i ? "|" : "") << desc->value(i)->name();
- }
- options << "}";
- return options.Str();
- }
-
+ TStringStream options;
+ options << "{";
+ for (int i = 0; i < desc->value_count(); ++i) {
+ options << (i ? "|" : "") << desc->value(i)->name();
+ }
+ options << "}";
+ return options.Str();
+ }
+
inline int GetProtobufOption(const google::protobuf::EnumDescriptor *desc, const char *option, const TString& optval) {
- const google::protobuf::EnumValueDescriptor *value = desc->FindValueByName(optval);
- if (!value) {
- int num;
- if (TryFromString(optval, num)) {
- value = desc->FindValueByNumber(num);
- }
- }
- if (!value) {
- ythrow yexception() << "invalid value for option " << option << ": '" << optval << "'; possible values: "
- << GetProtobufEnumOptions(desc);
- }
- return value->number();
- }
-
- } // NDriverClient
-} // NKikimr
+ const google::protobuf::EnumValueDescriptor *value = desc->FindValueByName(optval);
+ if (!value) {
+ int num;
+ if (TryFromString(optval, num)) {
+ value = desc->FindValueByNumber(num);
+ }
+ }
+ if (!value) {
+ ythrow yexception() << "invalid value for option " << option << ": '" << optval << "'; possible values: "
+ << GetProtobufEnumOptions(desc);
+ }
+ return value->number();
+ }
+
+ } // NDriverClient
+} // NKikimr
diff --git a/ydb/core/driver_lib/cli_utils/ya.make b/ydb/core/driver_lib/cli_utils/ya.make
index cb1f9670bea..960565ea68e 100644
--- a/ydb/core/driver_lib/cli_utils/ya.make
+++ b/ydb/core/driver_lib/cli_utils/ya.make
@@ -12,12 +12,12 @@ SRCS(
cli_cmds_admin.cpp
cli_cmds_bs.cpp
cli_cmds_cms.cpp
- cli_cmds_config.cpp
+ cli_cmds_config.cpp
cli_cmds_console.cpp
cli_cmds_debug.cpp
cli_cmds_disk.cpp
- cli_cmds_genconfig.cpp
- cli_cmds_get.cpp
+ cli_cmds_genconfig.cpp
+ cli_cmds_get.cpp
cli_cmds_group.cpp
cli_cmds_node.cpp
cli_cmds_root.cpp
@@ -29,7 +29,7 @@ SRCS(
cli_persqueue.cpp
cli_persqueue_cluster_discovery.cpp
cli_persqueue_stress.cpp
- cli_load.cpp
+ cli_load.cpp
cli_minikql_compile_and_exec.cpp
cli_mb_trace.cpp
cli_scheme_cache_append.cpp
diff --git a/ydb/core/driver_lib/run/config.cpp b/ydb/core/driver_lib/run/config.cpp
index 01f82b98ed2..ea4431ecfeb 100644
--- a/ydb/core/driver_lib/run/config.cpp
+++ b/ydb/core/driver_lib/run/config.cpp
@@ -2,10 +2,10 @@
namespace NKikimr {
-TKikimrRunConfig::TKikimrRunConfig(NKikimrConfig::TAppConfig& appConfig, ui32 nodeId, const TKikimrScopeId& scopeId)
+TKikimrRunConfig::TKikimrRunConfig(NKikimrConfig::TAppConfig& appConfig, ui32 nodeId, const TKikimrScopeId& scopeId)
: AppConfig(appConfig)
- , NodeId(nodeId)
- , ScopeId(scopeId)
-{}
+ , NodeId(nodeId)
+ , ScopeId(scopeId)
+{}
} // namespace NKikimr
diff --git a/ydb/core/driver_lib/run/config.h b/ydb/core/driver_lib/run/config.h
index faf1797413e..c2adbfea3a8 100644
--- a/ydb/core/driver_lib/run/config.h
+++ b/ydb/core/driver_lib/run/config.h
@@ -38,7 +38,7 @@ union TBasicKikimrServicesMask {
bool EnableTabletMonitor:1;
bool EnableViewerService:1;
bool EnableLoadService:1;
- bool EnableFailureInjectionService:1;
+ bool EnableFailureInjectionService:1;
bool EnablePersQueueL2Cache:1;
bool EnableKqp:1;
bool EnableMemoryLog:1;
@@ -87,12 +87,12 @@ static_assert(sizeof(TBasicKikimrServicesMask) == 8, "expected sizeof(TBasicKiki
struct TKikimrRunConfig {
NKikimrConfig::TAppConfig& AppConfig;
ui32 NodeId;
- TKikimrScopeId ScopeId;
+ TKikimrScopeId ScopeId;
TString PathToConfigCacheFile;
TKikimrRunConfig(NKikimrConfig::TAppConfig& appConfig,
- ui32 nodeId = 0, const TKikimrScopeId& scopeId = {});
+ ui32 nodeId = 0, const TKikimrScopeId& scopeId = {});
};
}
diff --git a/ydb/core/driver_lib/run/config_parser.cpp b/ydb/core/driver_lib/run/config_parser.cpp
index bb686562912..ca138d497ba 100644
--- a/ydb/core/driver_lib/run/config_parser.cpp
+++ b/ydb/core/driver_lib/run/config_parser.cpp
@@ -57,10 +57,10 @@ void TRunCommandConfigParser::SetupLastGetOptForConfigFiles(NLastGetopt::TOpts&
opts.AddLongOption("vdisk-file", "vdisk kind config file").OptionalArgument("PATH");
opts.AddLongOption("drivemodel-file", "drive model config file").OptionalArgument("PATH");
opts.AddLongOption("kqp-file", "Kikimr Query Processor config file").OptionalArgument("PATH");
- opts.AddLongOption("incrhuge-file", "incremental huge blob keeper config file").OptionalArgument("PATH");
+ opts.AddLongOption("incrhuge-file", "incremental huge blob keeper config file").OptionalArgument("PATH");
opts.AddLongOption("memorylog-file", "set buffer size for memory log").OptionalArgument("PATH");
- opts.AddLongOption("grpc-file", "gRPC config file").OptionalArgument("PATH");
- opts.AddLongOption("grpc-port", "enable gRPC server on port").RequiredArgument("PORT");
+ opts.AddLongOption("grpc-file", "gRPC config file").OptionalArgument("PATH");
+ opts.AddLongOption("grpc-port", "enable gRPC server on port").RequiredArgument("PORT");
opts.AddLongOption("grpcs-port", "enable gRPC SSL server on port").RequiredArgument("PORT");
opts.AddLongOption("grpc-public-host", "set public gRPC host for discovery").RequiredArgument("HOST");
opts.AddLongOption("grpc-public-port", "set public gRPC port for discovery").RequiredArgument("PORT");
@@ -124,15 +124,15 @@ void TRunCommandConfigParser::ParseConfigFiles(const NLastGetopt::TOptsParseResu
if (res.Has("kqp-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("kqp-file"), Config.AppConfig.MutableKQPConfig()));
}
-
- if (res.Has("incrhuge-file")) {
- Y_VERIFY(ParsePBFromFile(res.Get("incrhuge-file"), Config.AppConfig.MutableIncrHugeConfig()));
- }
-
- if (res.Has("grpc-file")) {
- Y_VERIFY(ParsePBFromFile(res.Get("grpc-file"), Config.AppConfig.MutableGRpcConfig()));
- }
-
+
+ if (res.Has("incrhuge-file")) {
+ Y_VERIFY(ParsePBFromFile(res.Get("incrhuge-file"), Config.AppConfig.MutableIncrHugeConfig()));
+ }
+
+ if (res.Has("grpc-file")) {
+ Y_VERIFY(ParsePBFromFile(res.Get("grpc-file"), Config.AppConfig.MutableGRpcConfig()));
+ }
+
if (res.Has("feature-flags-file")) {
Y_VERIFY(ParsePBFromFile(res.Get("feature-flags-file"), Config.AppConfig.MutableFeatureFlags(), true));
}
@@ -141,11 +141,11 @@ void TRunCommandConfigParser::ParseConfigFiles(const NLastGetopt::TOptsParseResu
Y_VERIFY(ParsePBFromFile(res.Get("sqs-file"), Config.AppConfig.MutableSqsConfig()));
}
- if (res.Has("grpc-port")) {
- auto& conf = *Config.AppConfig.MutableGRpcConfig();
- conf.SetStartGRpcProxy(true);
- conf.SetPort(FromString<ui16>(res.Get("grpc-port")));
- }
+ if (res.Has("grpc-port")) {
+ auto& conf = *Config.AppConfig.MutableGRpcConfig();
+ conf.SetStartGRpcProxy(true);
+ conf.SetPort(FromString<ui16>(res.Get("grpc-port")));
+ }
if (res.Has("grpcs-port")) {
auto& conf = *Config.AppConfig.MutableGRpcConfig();
diff --git a/ydb/core/driver_lib/run/driver.h b/ydb/core/driver_lib/run/driver.h
index 7ad96718d11..ffd3ab49d22 100644
--- a/ydb/core/driver_lib/run/driver.h
+++ b/ydb/core/driver_lib/run/driver.h
@@ -31,7 +31,7 @@ namespace NKikimr {
XX(EDM_SCHEME_INITROOT, "scheme-initroot", "init scheme root") \
XX(EDM_COMPILE_AND_EXEC_MINIKQL, "minikql-exec", "compile and execute MiniKQL program") \
XX(EDM_TRACE, "mb-trace", "control message bus trace") \
- XX(EDM_KEYVALUE_REQUEST, "keyvalue-request", "send protobuf request to a keyvalue tablet") \
+ XX(EDM_KEYVALUE_REQUEST, "keyvalue-request", "send protobuf request to a keyvalue tablet") \
XX(EDM_PERSQUEUE_REQUEST, "persqueue-request", "send protobuf request to a persqueue tablet") \
XX(EDM_PERSQUEUE_STRESS, "persqueue-stress", "stress read or write to a persqueue tablet") \
XX(EDM_PERSQUEUE_DISCOVER_CLUSTERS, "persqueue-discover-clusters", "persqueue session clusters discovery") \
diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
index 819c1478d19..4aeb3a711a3 100644
--- a/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
+++ b/ydb/core/driver_lib/run/kikimr_services_initializers.cpp
@@ -1,7 +1,7 @@
#include "config.h"
#include "kikimr_services_initializers.h"
#include "service_initializer.h"
-#include "version.h"
+#include "version.h"
#include <ydb/core/actorlib_impl/destruct_actor.h>
#include <ydb/core/actorlib_impl/load_network.h>
@@ -26,7 +26,7 @@
#include <ydb/core/blobstorage/other/mon_get_blob_page.h>
#include <ydb/core/blobstorage/testload/test_load_actor.h>
#include <ydb/core/blobstorage/vdisk/common/blobstorage_event_filter.h>
-
+
#include <ydb/core/client/minikql_compile/mkql_compile_service.h>
#include <ydb/core/client/server/grpc_proxy_status.h>
#include <ydb/core/client/server/msgbus_server_pq_metacache.h>
@@ -54,7 +54,7 @@
#include <ydb/core/test_tablet/test_tablet.h>
#include <ydb/core/test_tablet/state_server_interface.h>
-
+
#include <ydb/core/health_check/health_check.h>
#include <ydb/core/kqp/kqp.h>
@@ -157,14 +157,14 @@
#include <library/cpp/actors/core/probes.h>
#include <library/cpp/actors/core/process_stats.h>
#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/core/io_dispatcher.h>
+#include <library/cpp/actors/core/io_dispatcher.h>
#include <library/cpp/actors/dnsresolver/dnsresolver.h>
#include <library/cpp/actors/helpers/selfping_actor.h>
#include <library/cpp/actors/http/http_proxy.h>
#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/actors/interconnect/interconnect_mon.h>
#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
+#include <library/cpp/actors/interconnect/interconnect_proxy_wrapper.h>
#include <library/cpp/actors/interconnect/interconnect_tcp_server.h>
#include <library/cpp/actors/interconnect/load.h>
#include <library/cpp/actors/interconnect/poller_actor.h>
@@ -194,9 +194,9 @@ ui32 TYandexQueryInitializer::IcPort = 0;
IKikimrServicesInitializer::IKikimrServicesInitializer(const TKikimrRunConfig& runConfig)
: Config(runConfig.AppConfig)
- , NodeId(runConfig.NodeId)
- , ScopeId(runConfig.ScopeId)
-{}
+ , NodeId(runConfig.NodeId)
+ , ScopeId(runConfig.ScopeId)
+{}
// TBasicServicesInitializer
@@ -352,9 +352,9 @@ static TSchedulerConfig CreateSchedulerConfig(const NKikimrConfig::TActorSystemC
return TSchedulerConfig(resolution, spinThreshold, progressThreshold, useSchedulerActor);
}
-TBasicServicesInitializer::TBasicServicesInitializer(const TKikimrRunConfig& runConfig)
+TBasicServicesInitializer::TBasicServicesInitializer(const TKikimrRunConfig& runConfig)
: IKikimrServicesInitializer(runConfig)
-{
+{
}
static ui32 GetInterconnectThreadPoolId(const NKikimr::TAppData* appData) {
@@ -366,86 +366,86 @@ static ui32 GetInterconnectThreadPoolId(const NKikimr::TAppData* appData) {
return appData->SystemPoolId;
}
-static TInterconnectSettings GetInterconnectSettings(const NKikimrConfig::TInterconnectConfig& config, ui32 numNodes, ui32 numDataCenters) {
- TInterconnectSettings result;
-
- if (config.HasSelfKickDelayDuration() || config.HasSelfKickDelay()) {
- Cerr << "SelfKickDelayDuration/SelfKickDelay option is deprecated" << Endl;
- }
+static TInterconnectSettings GetInterconnectSettings(const NKikimrConfig::TInterconnectConfig& config, ui32 numNodes, ui32 numDataCenters) {
+ TInterconnectSettings result;
+
+ if (config.HasSelfKickDelayDuration() || config.HasSelfKickDelay()) {
+ Cerr << "SelfKickDelayDuration/SelfKickDelay option is deprecated" << Endl;
+ }
- if (config.HasHandshakeTimeoutDuration()) {
- result.Handshake = DurationFromProto(config.GetHandshakeTimeoutDuration());
- } else if (config.HasHandshakeTimeout()) {
- result.Handshake = TDuration::MilliSeconds(config.GetHandshakeTimeout());
- }
+ if (config.HasHandshakeTimeoutDuration()) {
+ result.Handshake = DurationFromProto(config.GetHandshakeTimeoutDuration());
+ } else if (config.HasHandshakeTimeout()) {
+ result.Handshake = TDuration::MilliSeconds(config.GetHandshakeTimeout());
+ }
- if (config.HasHeartbeatIntervalDuration() || config.HasHeartbeatInterval()) {
- Cerr << "HeartbeatIntervalDuration/HeartbeatInterval option is deprecated" << Endl;
- }
+ if (config.HasHeartbeatIntervalDuration() || config.HasHeartbeatInterval()) {
+ Cerr << "HeartbeatIntervalDuration/HeartbeatInterval option is deprecated" << Endl;
+ }
- if (config.HasDeadPeerTimeoutDuration()) {
- result.DeadPeer = DurationFromProto(config.GetDeadPeerTimeoutDuration());
- } else if (config.HasDeadPeerTimeout()) {
- result.DeadPeer = TDuration::MilliSeconds(config.GetDeadPeerTimeout());
- }
+ if (config.HasDeadPeerTimeoutDuration()) {
+ result.DeadPeer = DurationFromProto(config.GetDeadPeerTimeoutDuration());
+ } else if (config.HasDeadPeerTimeout()) {
+ result.DeadPeer = TDuration::MilliSeconds(config.GetDeadPeerTimeout());
+ }
- if (config.HasSendBufferDieLimitInMB()) {
+ if (config.HasSendBufferDieLimitInMB()) {
result.SendBufferDieLimitInMB = config.GetSendBufferDieLimitInMB();
- } else {
+ } else {
result.SendBufferDieLimitInMB = 512;
- }
+ }
- if (config.HasCloseOnIdleTimeoutDuration()) {
- result.CloseOnIdle = DurationFromProto(config.GetCloseOnIdleTimeoutDuration());
- } else if (config.HasCloseOnIdleTimeout()) {
+ if (config.HasCloseOnIdleTimeoutDuration()) {
+ result.CloseOnIdle = DurationFromProto(config.GetCloseOnIdleTimeoutDuration());
+ } else if (config.HasCloseOnIdleTimeout()) {
result.CloseOnIdle = TDuration::Seconds(config.GetCloseOnIdleTimeout());
- }
-
- auto mode = config.GetCounterMergeMode();
- if (config.HasMergePerPeerCounters() && !config.HasCounterMergeMode()) {
- mode = !config.GetMergePerPeerCounters()
- ? NKikimrConfig::TInterconnectConfig::NO_MERGE : numDataCenters > 1
- ? NKikimrConfig::TInterconnectConfig::PER_DATA_CENTER
- : NKikimrConfig::TInterconnectConfig::PER_PEER;
- }
- switch (mode) {
- case NKikimrConfig::TInterconnectConfig::AUTO:
- if (numNodes > 100) {
- if (numDataCenters > 1) {
- result.MergePerDataCenterCounters = true;
- } else {
- result.MergePerPeerCounters = true;
- }
- }
- break;
- case NKikimrConfig::TInterconnectConfig::PER_PEER:
- result.MergePerPeerCounters = true;
- break;
- case NKikimrConfig::TInterconnectConfig::PER_DATA_CENTER:
- result.MergePerDataCenterCounters = true;
- break;
- case NKikimrConfig::TInterconnectConfig::NO_MERGE:
- break;
- }
-
- switch (config.GetEncryptionMode()) {
- case NKikimrConfig::TInterconnectConfig::DISABLED:
- result.EncryptionMode = EEncryptionMode::DISABLED;
- break;
- case NKikimrConfig::TInterconnectConfig::OPTIONAL:
- result.EncryptionMode = EEncryptionMode::OPTIONAL;
- break;
- case NKikimrConfig::TInterconnectConfig::REQUIRED:
- result.EncryptionMode = EEncryptionMode::REQUIRED;
- break;
- }
- result.TlsAuthOnly = config.GetTlsAuthOnly();
-
+ }
+
+ auto mode = config.GetCounterMergeMode();
+ if (config.HasMergePerPeerCounters() && !config.HasCounterMergeMode()) {
+ mode = !config.GetMergePerPeerCounters()
+ ? NKikimrConfig::TInterconnectConfig::NO_MERGE : numDataCenters > 1
+ ? NKikimrConfig::TInterconnectConfig::PER_DATA_CENTER
+ : NKikimrConfig::TInterconnectConfig::PER_PEER;
+ }
+ switch (mode) {
+ case NKikimrConfig::TInterconnectConfig::AUTO:
+ if (numNodes > 100) {
+ if (numDataCenters > 1) {
+ result.MergePerDataCenterCounters = true;
+ } else {
+ result.MergePerPeerCounters = true;
+ }
+ }
+ break;
+ case NKikimrConfig::TInterconnectConfig::PER_PEER:
+ result.MergePerPeerCounters = true;
+ break;
+ case NKikimrConfig::TInterconnectConfig::PER_DATA_CENTER:
+ result.MergePerDataCenterCounters = true;
+ break;
+ case NKikimrConfig::TInterconnectConfig::NO_MERGE:
+ break;
+ }
+
+ switch (config.GetEncryptionMode()) {
+ case NKikimrConfig::TInterconnectConfig::DISABLED:
+ result.EncryptionMode = EEncryptionMode::DISABLED;
+ break;
+ case NKikimrConfig::TInterconnectConfig::OPTIONAL:
+ result.EncryptionMode = EEncryptionMode::OPTIONAL;
+ break;
+ case NKikimrConfig::TInterconnectConfig::REQUIRED:
+ result.EncryptionMode = EEncryptionMode::REQUIRED;
+ break;
+ }
+ result.TlsAuthOnly = config.GetTlsAuthOnly();
+
if (config.HasTCPSocketBufferSize())
result.TCPSocketBufferSize = config.GetTCPSocketBufferSize();
if (config.HasMaxTimePerEventInMks()) {
- Cerr << "MaxTimePerEventInMks option is deprecated" << Endl;
+ Cerr << "MaxTimePerEventInMks option is deprecated" << Endl;
}
if (config.HasTotalInflightAmountOfData()) {
@@ -464,43 +464,43 @@ static TInterconnectSettings GetInterconnectSettings(const NKikimrConfig::TInter
result.LostConnection = DurationFromProto(config.GetLostConnectionDuration());
}
- if (config.HasBatchPeriodDuration()) {
- result.BatchPeriod = DurationFromProto(config.GetBatchPeriodDuration());
- } else {
+ if (config.HasBatchPeriodDuration()) {
+ result.BatchPeriod = DurationFromProto(config.GetBatchPeriodDuration());
+ } else {
result.BatchPeriod = TDuration();
- }
-
- result.BindOnAllAddresses = config.GetBindOnAllAddresses();
-
- auto readFile = [](std::optional<TString> value, std::optional<TString> path, const char *name) {
- if (value) {
- return *value;
- } else if (path) {
- try {
- return TFileInput(*path).ReadAll();
- } catch (const std::exception& ex) {
- Cerr << "failed to read " << name << " file '" << *path << "': " << ex.what() << Endl;
- exit(1);
- }
- }
- return TString();
- };
- result.Certificate = readFile(config.HasCertificate() ? std::make_optional(config.GetCertificate()) : std::nullopt,
- config.HasPathToCertificateFile() ? std::make_optional(config.GetPathToCertificateFile()) : std::nullopt,
- "certificate");
- result.PrivateKey = readFile(config.HasPrivateKey() ? std::make_optional(config.GetPrivateKey()) : std::nullopt,
- config.HasPathToPrivateKeyFile() ? std::make_optional(config.GetPathToPrivateKeyFile()) : std::nullopt,
- "private key");
- result.CaFilePath = config.GetPathToCaFile();
- result.CipherList = config.GetCipherList();
-
- if (config.HasMessagePendingTimeout()) {
- result.MessagePendingTimeout = DurationFromProto(config.GetMessagePendingTimeout());
- }
- if (config.HasMessagePendingSize()) {
- result.MessagePendingSize = config.GetMessagePendingSize();
- }
-
+ }
+
+ result.BindOnAllAddresses = config.GetBindOnAllAddresses();
+
+ auto readFile = [](std::optional<TString> value, std::optional<TString> path, const char *name) {
+ if (value) {
+ return *value;
+ } else if (path) {
+ try {
+ return TFileInput(*path).ReadAll();
+ } catch (const std::exception& ex) {
+ Cerr << "failed to read " << name << " file '" << *path << "': " << ex.what() << Endl;
+ exit(1);
+ }
+ }
+ return TString();
+ };
+ result.Certificate = readFile(config.HasCertificate() ? std::make_optional(config.GetCertificate()) : std::nullopt,
+ config.HasPathToCertificateFile() ? std::make_optional(config.GetPathToCertificateFile()) : std::nullopt,
+ "certificate");
+ result.PrivateKey = readFile(config.HasPrivateKey() ? std::make_optional(config.GetPrivateKey()) : std::nullopt,
+ config.HasPathToPrivateKeyFile() ? std::make_optional(config.GetPathToPrivateKeyFile()) : std::nullopt,
+ "private key");
+ result.CaFilePath = config.GetPathToCaFile();
+ result.CipherList = config.GetCipherList();
+
+ if (config.HasMessagePendingTimeout()) {
+ result.MessagePendingTimeout = DurationFromProto(config.GetMessagePendingTimeout());
+ }
+ if (config.HasMessagePendingSize()) {
+ result.MessagePendingSize = config.GetMessagePendingSize();
+ }
+
return result;
}
@@ -530,8 +530,8 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
auto schedulerConfig = CreateSchedulerConfig(systemConfig.GetScheduler());
schedulerConfig.MonCounters = GetServiceCounters(counters, "utils");
setup->Scheduler.Reset(CreateSchedulerThread(schedulerConfig));
- setup->LocalServices.emplace_back(MakeIoDispatcherActorId(), TActorSetupCmd(CreateIoDispatcherActor(
- schedulerConfig.MonCounters->GetSubgroup("subsystem", "io_dispatcher")), TMailboxType::HTSwap, systemPoolId));
+ setup->LocalServices.emplace_back(MakeIoDispatcherActorId(), TActorSetupCmd(CreateIoDispatcherActor(
+ schedulerConfig.MonCounters->GetSubgroup("subsystem", "io_dispatcher")), TMailboxType::HTSwap, systemPoolId));
NLwTraceMonPage::DashboardRegistry().Register(NActors::LWTraceDashboards(setup));
@@ -540,9 +540,9 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
const TActorId resolverId = NDnsResolver::MakeDnsResolverActorId();
const TActorId nameserviceId = GetNameserviceActorId();
- ui32 numNodes = 0;
- TSet<TString> dataCenters;
-
+ ui32 numNodes = 0;
+ TSet<TString> dataCenters;
+
TIntrusivePtr<TTableNameserverSetup> table(new TTableNameserverSetup());
for (const auto &node : nsConfig.GetNode()) {
const ui32 nodeId = node.GetNodeId();
@@ -555,17 +555,17 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
// Use ip address only when dns host not specified
const TString addr = resolveHost ? TString() : node.GetAddress();
- TNodeLocation location;
+ TNodeLocation location;
if (node.HasWalleLocation()) {
- location = TNodeLocation(node.GetWalleLocation());
- } else if (node.HasLocation()) {
- location = TNodeLocation(node.GetLocation());
+ location = TNodeLocation(node.GetWalleLocation());
+ } else if (node.HasLocation()) {
+ location = TNodeLocation(node.GetLocation());
}
-
- table->StaticNodeTable[nodeId] = TTableNameserverSetup::TNodeInfo(addr, host, resolveHost, port, location);
-
- ++numNodes;
- dataCenters.insert(location.GetDataCenterId());
+
+ table->StaticNodeTable[nodeId] = TTableNameserverSetup::TNodeInfo(addr, host, resolveHost, port, location);
+
+ ++numNodes;
+ dataCenters.insert(location.GetDataCenterId());
}
NDnsResolver::TOnDemandDnsResolverOptions resolverOptions;
@@ -600,15 +600,15 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
nameserviceId,
TActorSetupCmd(nameservice, TMailboxType::HTSwap, systemPoolId));
- if (Config.HasInterconnectConfig() && Config.GetInterconnectConfig().GetStartTcp()) {
+ if (Config.HasInterconnectConfig() && Config.GetInterconnectConfig().GetStartTcp()) {
const auto& icConfig = Config.GetInterconnectConfig();
TChannelsConfig channels;
- auto settings = GetInterconnectSettings(icConfig, numNodes, dataCenters.size());
+ auto settings = GetInterconnectSettings(icConfig, numNodes, dataCenters.size());
ui32 interconnectPoolId = GetInterconnectThreadPoolId(appData);
- for (const auto& channel : icConfig.GetChannel()) {
- const auto index = channel.GetIndex();
+ for (const auto& channel : icConfig.GetChannel()) {
+ const auto index = channel.GetIndex();
ui32 weight = 0;
Y_VERIFY(!(channel.HasQuota() && channel.HasWeight()), "Only one field should be set: Weight or Quota, Weight is preffered");
if (channel.HasWeight()) {
@@ -623,66 +623,66 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
channels.insert({ui16(index), TChannelSettings{ui16(weight)}});
}
- // create poller actor (whether platform supports it)
- setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, systemPoolId));
-
+ // create poller actor (whether platform supports it)
+ setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, systemPoolId));
+
auto destructorQueueSize = std::make_shared<std::atomic<TAtomicBase>>(0);
-
+
TIntrusivePtr<TInterconnectProxyCommon> icCommon;
icCommon.Reset(new TInterconnectProxyCommon);
icCommon->NameserviceId = nameserviceId;
icCommon->MonCounters = GetServiceCounters(counters, "interconnect");
icCommon->ChannelsConfig = channels;
- icCommon->Settings = settings;
+ icCommon->Settings = settings;
icCommon->DestructorId = GetDestructActorID();
- icCommon->DestructorQueueSize = destructorQueueSize;
- icCommon->HandshakeBallastSize = icConfig.GetHandshakeBallastSize();
- icCommon->LocalScopeId = ScopeId.GetInterconnectScopeId();
- icCommon->Cookie = icConfig.GetSuppressConnectivityCheck() ? TString() : CreateGuidAsString();
-
-#define CHANNEL(NAME) {TInterconnectChannels::NAME, #NAME}
- icCommon->ChannelName = {
- CHANNEL(IC_COMMON),
- CHANNEL(IC_BLOBSTORAGE),
- CHANNEL(IC_BLOBSTORAGE_ASYNC_DATA),
- CHANNEL(IC_BLOBSTORAGE_SYNCER),
- CHANNEL(IC_BLOBSTORAGE_DISCOVER),
- CHANNEL(IC_BLOBSTORAGE_SMALL_MSG),
- CHANNEL(IC_TABLETS_SMALL),
- CHANNEL(IC_TABLETS_MEDIUM),
- CHANNEL(IC_TABLETS_LARGE),
- };
-
- if (icConfig.GetEnforceScopeValidation()) {
- icCommon->EventFilter = std::make_shared<TEventFilter>();
+ icCommon->DestructorQueueSize = destructorQueueSize;
+ icCommon->HandshakeBallastSize = icConfig.GetHandshakeBallastSize();
+ icCommon->LocalScopeId = ScopeId.GetInterconnectScopeId();
+ icCommon->Cookie = icConfig.GetSuppressConnectivityCheck() ? TString() : CreateGuidAsString();
+
+#define CHANNEL(NAME) {TInterconnectChannels::NAME, #NAME}
+ icCommon->ChannelName = {
+ CHANNEL(IC_COMMON),
+ CHANNEL(IC_BLOBSTORAGE),
+ CHANNEL(IC_BLOBSTORAGE_ASYNC_DATA),
+ CHANNEL(IC_BLOBSTORAGE_SYNCER),
+ CHANNEL(IC_BLOBSTORAGE_DISCOVER),
+ CHANNEL(IC_BLOBSTORAGE_SMALL_MSG),
+ CHANNEL(IC_TABLETS_SMALL),
+ CHANNEL(IC_TABLETS_MEDIUM),
+ CHANNEL(IC_TABLETS_LARGE),
+ };
+
+ if (icConfig.GetEnforceScopeValidation()) {
+ icCommon->EventFilter = std::make_shared<TEventFilter>();
RegisterBlobStorageEventScopes(icCommon->EventFilter);
RegisterStateStorageEventScopes(icCommon->EventFilter);
- }
-
- if (const auto& whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(NodeId)) {
+ }
+
+ if (const auto& whiteboardId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(NodeId)) {
icCommon->InitWhiteboard = [whiteboardId](ui16 port, TActorSystem *actorSystem) {
actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint("ic", Sprintf(":%d", port)));
};
- icCommon->UpdateWhiteboard = [whiteboardId](const TString& peer, bool connected, bool green, bool yellow,
- bool orange, bool red, TActorSystem *actorSystem) {
- actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvNodeStateUpdate(
- peer, connected,
- green ? NKikimrWhiteboard::EFlag::Green :
- yellow ? NKikimrWhiteboard::EFlag::Yellow :
- orange ? NKikimrWhiteboard::EFlag::Orange :
- red ? NKikimrWhiteboard::EFlag::Red : NKikimrWhiteboard::EFlag()));
- };
- }
-
- if (const auto& mon = appData->Mon) {
+ icCommon->UpdateWhiteboard = [whiteboardId](const TString& peer, bool connected, bool green, bool yellow,
+ bool orange, bool red, TActorSystem *actorSystem) {
+ actorSystem->Send(whiteboardId, new NNodeWhiteboard::TEvWhiteboard::TEvNodeStateUpdate(
+ peer, connected,
+ green ? NKikimrWhiteboard::EFlag::Green :
+ yellow ? NKikimrWhiteboard::EFlag::Yellow :
+ orange ? NKikimrWhiteboard::EFlag::Orange :
+ red ? NKikimrWhiteboard::EFlag::Red : NKikimrWhiteboard::EFlag()));
+ };
+ }
+
+ if (const auto& mon = appData->Mon) {
icCommon->RegisterMonPage = [mon](const TString& path, const TString& title, TActorSystem *actorSystem, const TActorId& actorId) {
- NMonitoring::TIndexMonPage *page = mon->RegisterIndexPage("actors", "Actors")->RegisterIndexPage("interconnect", "Interconnect");
- mon->RegisterActorPage(page, path, title, false, actorSystem, actorId);
- };
- setup->LocalServices.emplace_back(NInterconnect::MakeInterconnectMonActorId(NodeId), TActorSetupCmd(
- NInterconnect::CreateInterconnectMonActor(icCommon), TMailboxType::ReadAsFilled, systemPoolId));
- }
-
+ NMonitoring::TIndexMonPage *page = mon->RegisterIndexPage("actors", "Actors")->RegisterIndexPage("interconnect", "Interconnect");
+ mon->RegisterActorPage(page, path, title, false, actorSystem, actorId);
+ };
+ setup->LocalServices.emplace_back(NInterconnect::MakeInterconnectMonActorId(NodeId), TActorSetupCmd(
+ NInterconnect::CreateInterconnectMonActor(icCommon), TMailboxType::ReadAsFilled, systemPoolId));
+ }
+
if (nsConfig.HasClusterUUID()) {
icCommon->ClusterUUID = nsConfig.GetClusterUUID();
}
@@ -691,30 +691,30 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
icCommon->AcceptUUID.emplace_back(item);
}
- if (!nsConfig.GetSuppressVersionCheck()) {
- icCommon->VersionInfo = VERSION;
- CheckVersionTag();
- }
+ if (!nsConfig.GetSuppressVersionCheck()) {
+ icCommon->VersionInfo = VERSION;
+ CheckVersionTag();
+ }
+
+ setup->LocalServices.emplace_back(GetDestructActorID(), TActorSetupCmd(new TDestructActor,
+ TMailboxType::ReadAsFilled, interconnectPoolId));
- setup->LocalServices.emplace_back(GetDestructActorID(), TActorSetupCmd(new TDestructActor,
- TMailboxType::ReadAsFilled, interconnectPoolId));
-
- Y_VERIFY(!table->StaticNodeTable.empty());
- ui32 maxNode = 0;
+ Y_VERIFY(!table->StaticNodeTable.empty());
+ ui32 maxNode = 0;
for (const auto &node : table->StaticNodeTable) {
- maxNode = Max(maxNode, node.first);
- }
- setup->Interconnect.ProxyActors.resize(maxNode + 1);
- setup->Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(icCommon, interconnectPoolId);
-
+ maxNode = Max(maxNode, node.first);
+ }
+ setup->Interconnect.ProxyActors.resize(maxNode + 1);
+ setup->Interconnect.ProxyWrapperFactory = CreateProxyWrapperFactory(icCommon, interconnectPoolId);
+
std::unordered_set<ui32> staticIds;
for (const auto& node : table->StaticNodeTable) {
const ui32 destId = node.first;
if (destId != NodeId) {
staticIds.insert(destId);
- setup->Interconnect.ProxyActors[destId] = TActorSetupCmd(new TInterconnectProxyTCP(destId, icCommon),
- TMailboxType::ReadAsFilled, interconnectPoolId);
+ setup->Interconnect.ProxyActors[destId] = TActorSetupCmd(new TInterconnectProxyTCP(destId, icCommon),
+ TMailboxType::ReadAsFilled, interconnectPoolId);
} else {
TYandexQueryInitializer::SetIcPort(node.second.second);
icCommon->TechnicalSelfHostName = node.second.Host;
@@ -723,13 +723,13 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
address = node.second.first;
auto listener = new TInterconnectListenerTCP(
address, node.second.second, icCommon);
- if (int err = listener->Bind()) {
- Cerr << "Failed to set up IC listener on port " << node.second.second
- << " errno# " << err << " (" << strerror(err) << ")" << Endl;
- exit(1);
- }
- setup->LocalServices.emplace_back(MakeInterconnectListenerActorId(false), TActorSetupCmd(listener,
- TMailboxType::ReadAsFilled, interconnectPoolId));
+ if (int err = listener->Bind()) {
+ Cerr << "Failed to set up IC listener on port " << node.second.second
+ << " errno# " << err << " (" << strerror(err) << ")" << Endl;
+ exit(1);
+ }
+ setup->LocalServices.emplace_back(MakeInterconnectListenerActorId(false), TActorSetupCmd(listener,
+ TMailboxType::ReadAsFilled, interconnectPoolId));
}
}
@@ -743,20 +743,20 @@ void TBasicServicesInitializer::InitializeServices(NActors::TActorSystemSetup* s
address = info.GetAddress();
}
auto listener = new TInterconnectListenerTCP(address, info.GetPort(), icCommon);
- if (int err = listener->Bind()) {
- Cerr << "Failed to set up IC listener on port " << info.GetPort()
- << " errno# " << err << " (" << strerror(err) << ")" << Endl;
- exit(1);
- }
- setup->LocalServices.emplace_back(MakeInterconnectListenerActorId(true), TActorSetupCmd(listener,
- TMailboxType::ReadAsFilled, interconnectPoolId));
+ if (int err = listener->Bind()) {
+ Cerr << "Failed to set up IC listener on port " << info.GetPort()
+ << " errno# " << err << " (" << strerror(err) << ")" << Endl;
+ exit(1);
+ }
+ setup->LocalServices.emplace_back(MakeInterconnectListenerActorId(true), TActorSetupCmd(listener,
+ TMailboxType::ReadAsFilled, interconnectPoolId));
}
- // create load responder for interconnect
- // TODO(alexvru): pool?
- setup->LocalServices.emplace_back(NInterconnect::MakeLoadResponderActorId(NodeId),
- TActorSetupCmd(NInterconnect::CreateLoadResponderActor(), TMailboxType::ReadAsFilled, systemPoolId));
-
+ // create load responder for interconnect
+ // TODO(alexvru): pool?
+ setup->LocalServices.emplace_back(NInterconnect::MakeLoadResponderActorId(NodeId),
+ TActorSetupCmd(NInterconnect::CreateLoadResponderActor(), TMailboxType::ReadAsFilled, systemPoolId));
+
//IC_Load::InitializeService(setup, appData, maxNode);
}
}
@@ -793,34 +793,34 @@ void TBSNodeWardenInitializer::InitializeServices(NActors::TActorSystemSetup* se
const NKikimr::TAppData* appData) {
TIntrusivePtr<TNodeWardenConfig> nodeWardenConfig(new TNodeWardenConfig(new TRealPDiskServiceFactory()));
if (Config.HasBlobStorageConfig()) {
- const auto& bsc = Config.GetBlobStorageConfig();
- appData->StaticBlobStorageConfig->MergeFrom(bsc.GetServiceSet());
+ const auto& bsc = Config.GetBlobStorageConfig();
+ appData->StaticBlobStorageConfig->MergeFrom(bsc.GetServiceSet());
nodeWardenConfig->FeatureFlags = Config.GetFeatureFlags();
- nodeWardenConfig->ServiceSet.MergeFrom(bsc.GetServiceSet());
+ nodeWardenConfig->ServiceSet.MergeFrom(bsc.GetServiceSet());
if (Config.HasVDiskConfig()) {
nodeWardenConfig->AllVDiskKinds->Merge(Config.GetVDiskConfig());
}
if (Config.HasDriveModelConfig()) {
nodeWardenConfig->AllDriveModels->Merge(Config.GetDriveModelConfig());
}
- if (bsc.HasCacheFilePath()) {
- nodeWardenConfig->CacheAccessor = CreateFileCacheAccessor(bsc.GetCacheFilePath());
- }
- nodeWardenConfig->CachePDisks = bsc.GetCachePDisks();
- nodeWardenConfig->CacheVDisks = bsc.GetCacheVDisks();
- nodeWardenConfig->EnableVDiskCooldownTimeout = true;
+ if (bsc.HasCacheFilePath()) {
+ nodeWardenConfig->CacheAccessor = CreateFileCacheAccessor(bsc.GetCacheFilePath());
+ }
+ nodeWardenConfig->CachePDisks = bsc.GetCachePDisks();
+ nodeWardenConfig->CacheVDisks = bsc.GetCacheVDisks();
+ nodeWardenConfig->EnableVDiskCooldownTimeout = true;
}
- ObtainTenantKey(&nodeWardenConfig->TenantKey, Config.GetKeyConfig());
- ObtainStaticKey(&nodeWardenConfig->StaticKey);
+ ObtainTenantKey(&nodeWardenConfig->TenantKey, Config.GetKeyConfig());
+ ObtainStaticKey(&nodeWardenConfig->StaticKey);
ObtainPDiskKey(&nodeWardenConfig->PDiskKey, Config.GetPDiskKeyConfig());
-
+
setup->LocalServices.push_back(std::pair<TActorId, TActorSetupCmd>(MakeBlobStorageNodeWardenID(NodeId),
TActorSetupCmd(CreateBSNodeWarden(nodeWardenConfig.Release()),
TMailboxType::ReadAsFilled, appData->SystemPoolId)));
-
- setup->LocalServices.emplace_back(MakeUniversalSchedulerActorId(), TActorSetupCmd(CreateUniversalSchedulerActor(),
- TMailboxType::ReadAsFilled, appData->SystemPoolId));
+
+ setup->LocalServices.emplace_back(MakeUniversalSchedulerActorId(), TActorSetupCmd(CreateUniversalSchedulerActor(),
+ TMailboxType::ReadAsFilled, appData->SystemPoolId));
}
// TStateStorageServiceInitializer
@@ -920,8 +920,8 @@ void TLocalServiceInitializer::InitializeServices(
new TTabletSetupInfo(&CreateDefaultHive, TMailboxType::ReadAsFilled, importantPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.SysViewProcessor] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&NSysView::CreateSysViewProcessor, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
- localConfig->TabletClassInfo[appData->DefaultTabletTypes.TestShard] = TLocalConfig::TTabletClassInfo(
- new TTabletSetupInfo(&NTestShard::CreateTestShard, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
+ localConfig->TabletClassInfo[appData->DefaultTabletTypes.TestShard] = TLocalConfig::TTabletClassInfo(
+ new TTabletSetupInfo(&NTestShard::CreateTestShard, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.ColumnShard] = TLocalConfig::TTabletClassInfo(
new TTabletSetupInfo(&CreateColumnShard, TMailboxType::ReadAsFilled, appData->UserPoolId, TMailboxType::ReadAsFilled, appData->SystemPoolId));
localConfig->TabletClassInfo[appData->DefaultTabletTypes.SequenceShard] = TLocalConfig::TTabletClassInfo(
@@ -950,9 +950,9 @@ void TLocalServiceInitializer::InitializeServices(
TActorSetupCmd(CreateLabelsMaintainer(Config.GetMonitoringConfig()),
TMailboxType::ReadAsFilled, 0)));
- setup->LocalServices.emplace_back(NTestShard::MakeStateServerInterfaceActorId(), TActorSetupCmd(
- NTestShard::CreateStateServerInterfaceActor(), TMailboxType::ReadAsFilled, 0));
-
+ setup->LocalServices.emplace_back(NTestShard::MakeStateServerInterfaceActorId(), TActorSetupCmd(
+ NTestShard::CreateStateServerInterfaceActor(), TMailboxType::ReadAsFilled, 0));
+
NKesus::AddKesusProbesList();
}
@@ -1766,31 +1766,31 @@ void TViewerInitializer::InitializeServices(NActors::TActorSystemSetup* setup,
appData->BatchPoolId)));
}
-// TLoadInitializer
-
-TLoadInitializer::TLoadInitializer(const TKikimrRunConfig& runConfig)
- : IKikimrServicesInitializer(runConfig)
-{}
-
-void TLoadInitializer::InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) {
+// TLoadInitializer
+
+TLoadInitializer::TLoadInitializer(const TKikimrRunConfig& runConfig)
+ : IKikimrServicesInitializer(runConfig)
+{}
+
+void TLoadInitializer::InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) {
IActor *actor = CreateTestLoadActor(appData->Counters);
setup->LocalServices.emplace_back(MakeBlobStorageLoadID(NodeId), TActorSetupCmd(actor, TMailboxType::HTSwap, appData->UserPoolId));
- // FIXME: correct service id
-}
-
-// TFailureInjectionInitializer
-
-TFailureInjectionInitializer::TFailureInjectionInitializer(const TKikimrRunConfig& runConfig)
- : IKikimrServicesInitializer(runConfig)
-{}
-
-void TFailureInjectionInitializer::InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) {
- IActor *actor = CreateFailureInjectionActor();
- setup->LocalServices.emplace_back(MakeBlobStorageFailureInjectionID(NodeId),
+ // FIXME: correct service id
+}
+
+// TFailureInjectionInitializer
+
+TFailureInjectionInitializer::TFailureInjectionInitializer(const TKikimrRunConfig& runConfig)
+ : IKikimrServicesInitializer(runConfig)
+{}
+
+void TFailureInjectionInitializer::InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) {
+ IActor *actor = CreateFailureInjectionActor();
+ setup->LocalServices.emplace_back(MakeBlobStorageFailureInjectionID(NodeId),
TActorSetupCmd(actor, TMailboxType::HTSwap, appData->UserPoolId));
- // FIXME: correct service id
-}
-
+ // FIXME: correct service id
+}
+
// TPersQueueL2CacheInitializer
TPersQueueL2CacheInitializer::TPersQueueL2CacheInitializer(const TKikimrRunConfig& runConfig)
diff --git a/ydb/core/driver_lib/run/kikimr_services_initializers.h b/ydb/core/driver_lib/run/kikimr_services_initializers.h
index 407ce1bb7ba..314854516c3 100644
--- a/ydb/core/driver_lib/run/kikimr_services_initializers.h
+++ b/ydb/core/driver_lib/run/kikimr_services_initializers.h
@@ -34,7 +34,7 @@ class IKikimrServicesInitializer : public IServiceInitializer {
protected:
const NKikimrConfig::TAppConfig& Config;
const ui32 NodeId;
- const TKikimrScopeId ScopeId;
+ const TKikimrScopeId ScopeId;
public:
IKikimrServicesInitializer(const TKikimrRunConfig& runConfig);
@@ -50,7 +50,7 @@ class TBasicServicesInitializer : public IKikimrServicesInitializer {
static ISchedulerThread* CreateScheduler(const NKikimrConfig::TActorSystemConfig::TScheduler &config);
public:
- TBasicServicesInitializer(const TKikimrRunConfig& runConfig);
+ TBasicServicesInitializer(const TKikimrRunConfig& runConfig);
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
};
@@ -315,19 +315,19 @@ public:
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
};
-class TLoadInitializer : public IKikimrServicesInitializer {
-public:
- TLoadInitializer(const TKikimrRunConfig& runConfig);
+class TLoadInitializer : public IKikimrServicesInitializer {
+public:
+ TLoadInitializer(const TKikimrRunConfig& runConfig);
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
-};
-
-class TFailureInjectionInitializer : public IKikimrServicesInitializer {
-public:
- TFailureInjectionInitializer(const TKikimrRunConfig& runConfig);
+};
+
+class TFailureInjectionInitializer : public IKikimrServicesInitializer {
+public:
+ TFailureInjectionInitializer(const TKikimrRunConfig& runConfig);
void InitializeServices(NActors::TActorSystemSetup *setup, const NKikimr::TAppData *appData) override;
-};
+};
class TPersQueueL2CacheInitializer : public IKikimrServicesInitializer {
public:
diff --git a/ydb/core/driver_lib/run/main.cpp b/ydb/core/driver_lib/run/main.cpp
index f0a9315685b..be427bed94c 100644
--- a/ydb/core/driver_lib/run/main.cpp
+++ b/ydb/core/driver_lib/run/main.cpp
@@ -140,8 +140,8 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
return NDriverClient::PersQueueStress(cmdConf, argc, argv);
case EDM_PERSQUEUE_DISCOVER_CLUSTERS:
return NDriverClient::PersQueueDiscoverClustersRequest(cmdConf, argc, argv);
- case EDM_LOAD_REQUEST:
- return NDriverClient::LoadRequest(cmdConf, argc, argv);
+ case EDM_LOAD_REQUEST:
+ return NDriverClient::LoadRequest(cmdConf, argc, argv);
case EDM_ACTORSYS_PERFTEST:
return NDriverClient::ActorsysPerfTest(cmdConf, argc, argv);
default:
diff --git a/ydb/core/driver_lib/run/run.cpp b/ydb/core/driver_lib/run/run.cpp
index a4f74aa4e0f..cac7c27dcee 100644
--- a/ydb/core/driver_lib/run/run.cpp
+++ b/ydb/core/driver_lib/run/run.cpp
@@ -68,7 +68,7 @@
#include <ydb/core/blobstorage/other/mon_get_blob_page.h>
#include <ydb/core/blobstorage/other/mon_blob_range_page.h>
#include <ydb/core/blobstorage/other/mon_vdisk_stream.h>
-
+
#include <ydb/public/lib/deprecated/client/msgbus_client.h>
#include <ydb/core/client/minikql_compile/mkql_compile_service.h>
#include <ydb/core/client/server/msgbus_server_pq_metacache.h>
@@ -737,7 +737,7 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
opts.SetHost(grpcConfig.GetHost());
opts.SetPort(grpcConfig.GetPort());
opts.SetWorkerThreads(grpcConfig.GetWorkerThreads());
- opts.SetGRpcMemoryQuotaBytes(grpcConfig.GetGRpcMemoryQuotaBytes());
+ opts.SetGRpcMemoryQuotaBytes(grpcConfig.GetGRpcMemoryQuotaBytes());
opts.SetMaxMessageSize(grpcConfig.HasMaxMessageSize() ? grpcConfig.GetMaxMessageSize() : DEFAULT_GRPC_MESSAGE_SIZE_LIMIT);
opts.SetMaxGlobalRequestInFlight(grpcConfig.GetMaxInFlight());
opts.SetLogger(NGrpc::CreateActorSystemLogger(*ActorSystem.Get(), NKikimrServices::GRPC_SERVER));
@@ -748,21 +748,21 @@ void TKikimrRunner::InitializeGRpc(const TKikimrRunConfig& runConfig) {
opts.SetUseAuth(appConfig.GetDomainsConfig().GetSecurityConfig().GetEnforceUserTokenRequirement());
}
- if (grpcConfig.HasKeepAliveEnable()) {
- if (grpcConfig.GetKeepAliveEnable()) {
- Y_VERIFY(grpcConfig.HasKeepAliveIdleTimeoutTriggerSec(), "KeepAliveIdleTimeoutTriggerSec not set");
- Y_VERIFY(grpcConfig.HasKeepAliveMaxProbeCount(), "KeepAliveMaxProbeCount not set");
- Y_VERIFY(grpcConfig.HasKeepAliveProbeIntervalSec(), "KeepAliveProbeIntervalSec not set");
- opts.SetKeepAliveEnable(true);
- opts.SetKeepAliveIdleTimeoutTriggerSec(grpcConfig.GetKeepAliveIdleTimeoutTriggerSec());
- opts.SetKeepAliveMaxProbeCount(grpcConfig.GetKeepAliveMaxProbeCount());
- opts.SetKeepAliveProbeIntervalSec(grpcConfig.GetKeepAliveProbeIntervalSec());
+ if (grpcConfig.HasKeepAliveEnable()) {
+ if (grpcConfig.GetKeepAliveEnable()) {
+ Y_VERIFY(grpcConfig.HasKeepAliveIdleTimeoutTriggerSec(), "KeepAliveIdleTimeoutTriggerSec not set");
+ Y_VERIFY(grpcConfig.HasKeepAliveMaxProbeCount(), "KeepAliveMaxProbeCount not set");
+ Y_VERIFY(grpcConfig.HasKeepAliveProbeIntervalSec(), "KeepAliveProbeIntervalSec not set");
+ opts.SetKeepAliveEnable(true);
+ opts.SetKeepAliveIdleTimeoutTriggerSec(grpcConfig.GetKeepAliveIdleTimeoutTriggerSec());
+ opts.SetKeepAliveMaxProbeCount(grpcConfig.GetKeepAliveMaxProbeCount());
+ opts.SetKeepAliveProbeIntervalSec(grpcConfig.GetKeepAliveProbeIntervalSec());
}
else {
- opts.SetKeepAliveEnable(false);
- }
- }
-
+ opts.SetKeepAliveEnable(false);
+ }
+ }
+
NGrpc::TServerOptions sslOpts = opts;
if (grpcConfig.HasSslPort() && grpcConfig.GetSslPort()) {
Y_VERIFY(grpcConfig.HasCA(), "CA not set");
@@ -867,7 +867,7 @@ void TKikimrRunner::InitializeAppData(const TKikimrRunConfig& runConfig)
AppData->Mon = Monitoring.Get();
AppData->BusMonPage = BusMonPage.Get();
AppData->PollerThreads = PollerThreads;
- AppData->LocalScopeId = runConfig.ScopeId;
+ AppData->LocalScopeId = runConfig.ScopeId;
// setup streaming config
if (runConfig.AppConfig.GetGRpcConfig().HasStreamingConfig()) {
@@ -1036,11 +1036,11 @@ void TKikimrRunner::InitializeActorSystem(
serviceInitializers->InitializeServices(setup.Get(), AppData.Get());
- if (Monitoring) {
- setup->LocalServices.emplace_back(NCrossRef::MakeCrossRefActorId(), TActorSetupCmd(NCrossRef::CreateCrossRefActor(),
- TMailboxType::HTSwap, AppData->SystemPoolId));
- }
-
+ if (Monitoring) {
+ setup->LocalServices.emplace_back(NCrossRef::MakeCrossRefActorId(), TActorSetupCmd(NCrossRef::CreateCrossRefActor(),
+ TMailboxType::HTSwap, AppData->SystemPoolId));
+ }
+
ApplyLogSettings(runConfig);
ActorSystem.Reset(new TActorSystem(setup, AppData.Get(), LogSettings));
@@ -1055,7 +1055,7 @@ void TKikimrRunner::InitializeActorSystem(
ActorSystem.Get(),
LogSettings->LoggerActorId);
}
-
+
if (servicesMask.EnableProfiler) {
Monitoring->RegisterActorPage(
ActorsMonPage,
@@ -1086,17 +1086,17 @@ void TKikimrRunner::InitializeActorSystem(
MakeBlobStorageFailureInjectionID(runConfig.NodeId));
}
- Monitoring->Register(CreateMonGetBlobPage("get_blob", ActorSystem.Get()));
- Monitoring->Register(CreateMonBlobRangePage("blob_range", ActorSystem.Get()));
- Monitoring->Register(CreateMonVDiskStreamPage("vdisk_stream", ActorSystem.Get()));
-
- Monitoring->RegisterActorPage(
- ActorsMonPage->RegisterIndexPage("interconnect", "Interconnect"),
- "overview",
- "Interconnect overview",
- false,
- ActorSystem.Get(),
- NInterconnect::MakeInterconnectMonActorId(runConfig.NodeId));
+ Monitoring->Register(CreateMonGetBlobPage("get_blob", ActorSystem.Get()));
+ Monitoring->Register(CreateMonBlobRangePage("blob_range", ActorSystem.Get()));
+ Monitoring->Register(CreateMonVDiskStreamPage("vdisk_stream", ActorSystem.Get()));
+
+ Monitoring->RegisterActorPage(
+ ActorsMonPage->RegisterIndexPage("interconnect", "Interconnect"),
+ "overview",
+ "Interconnect overview",
+ false,
+ ActorSystem.Get(),
+ NInterconnect::MakeInterconnectMonActorId(runConfig.NodeId));
if (servicesMask.EnableGRpcService) {
Monitoring->RegisterActorPage(nullptr, "grpc", "GRPC", false, ActorSystem.Get(), NGRpcService::GrpcMonServiceId());
@@ -1139,7 +1139,7 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
}
if (serviceMask.EnableBasicServices) {
- sil->AddServiceInitializer(new TBasicServicesInitializer(runConfig));
+ sil->AddServiceInitializer(new TBasicServicesInitializer(runConfig));
}
if (serviceMask.EnableIcbService) {
sil->AddServiceInitializer(new TImmediateControlBoardInitializer(runConfig));
@@ -1247,9 +1247,9 @@ TIntrusivePtr<TServiceInitializersList> TKikimrRunner::CreateServiceInitializers
if (serviceMask.EnableLoadService) {
sil->AddServiceInitializer(new TLoadInitializer(runConfig));
}
- if (serviceMask.EnableFailureInjectionService) {
- sil->AddServiceInitializer(new TFailureInjectionInitializer(runConfig));
- }
+ if (serviceMask.EnableFailureInjectionService) {
+ sil->AddServiceInitializer(new TFailureInjectionInitializer(runConfig));
+ }
if (serviceMask.EnablePersQueueL2Cache) {
sil->AddServiceInitializer(new TPersQueueL2CacheInitializer(runConfig));
}
@@ -1334,9 +1334,9 @@ void RegisterBaseTagForMemoryProfiling(TActorSystem* as) {
return;
TVector<TString> holders;
TVector<const char*> activityNames;
- for (ui32 i = 0; i < NKikimrServices::TActivity::EType_ARRAYSIZE; ++i) {
- auto current = (NKikimrServices::TActivity::EType)i;
- const char* currName = NKikimrServices::TActivity::EType_Name(current).c_str();
+ for (ui32 i = 0; i < NKikimrServices::TActivity::EType_ARRAYSIZE; ++i) {
+ auto current = (NKikimrServices::TActivity::EType)i;
+ const char* currName = NKikimrServices::TActivity::EType_Name(current).c_str();
if (currName[0] == '\0') {
holders.push_back("EActivityType_" + ToString<ui32>(i));
currName = holders.back().c_str();
@@ -1375,8 +1375,8 @@ void TKikimrRunner::KikimrStart() {
ActorSystem->Send(NNodeWhiteboard::MakeNodeWhiteboardServiceId(ActorSystem->NodeId),
new NNodeWhiteboard::TEvWhiteboard::TEvSystemStateAddEndpoint(server.first, endpoint));
}
- }
-
+ }
+
if (SqsHttp) {
SqsHttp->Start();
}
@@ -1425,14 +1425,14 @@ void TKikimrRunner::KikimrStop(bool graceful) {
}
}
- if (ActorSystem) {
+ if (ActorSystem) {
ActorSystem->BroadcastToProxies([](const TActorId& proxyId) {
- return new IEventHandle(proxyId, {}, new TEvInterconnect::TEvTerminate);
- });
- ActorSystem->Send(new IEventHandle(MakeInterconnectListenerActorId(false), {}, new TEvents::TEvPoisonPill));
- ActorSystem->Send(new IEventHandle(MakeInterconnectListenerActorId(true), {}, new TEvents::TEvPoisonPill));
- }
-
+ return new IEventHandle(proxyId, {}, new TEvInterconnect::TEvTerminate);
+ });
+ ActorSystem->Send(new IEventHandle(MakeInterconnectListenerActorId(false), {}, new TEvents::TEvPoisonPill));
+ ActorSystem->Send(new IEventHandle(MakeInterconnectListenerActorId(true), {}, new TEvents::TEvPoisonPill));
+ }
+
if (SqsHttp) {
SqsHttp->Shutdown();
}
diff --git a/ydb/core/driver_lib/run/ut/ya.make b/ydb/core/driver_lib/run/ut/ya.make
index 79c50cf0e9c..3bc55b41da5 100644
--- a/ydb/core/driver_lib/run/ut/ya.make
+++ b/ydb/core/driver_lib/run/ut/ya.make
@@ -1,7 +1,7 @@
UNITTEST_FOR(ydb/core/driver_lib/run)
-
+
OWNER(alexvru)
-
+
SRCS(version_ut.cpp)
-
-END()
+
+END()
diff --git a/ydb/core/driver_lib/run/version.cpp b/ydb/core/driver_lib/run/version.cpp
index b8f2ef8cafd..018cc1583a6 100644
--- a/ydb/core/driver_lib/run/version.cpp
+++ b/ydb/core/driver_lib/run/version.cpp
@@ -1,61 +1,61 @@
#include <library/cpp/svnversion/svnversion.h>
-#include "version.h"
-
-TMaybe<NActors::TInterconnectProxyCommon::TVersionInfo> VERSION = NActors::TInterconnectProxyCommon::TVersionInfo{
- // version of this binary
- "trunk",
-
- // compatible versions; must include all compatible old ones, including this one; version verification occurs on both
- // peers and connection is accepted if at least one of peers accepts the version of the other peer
- {
- "trunk"
- }
-};
-
-TString GetBranchName(TString url) {
- bool found = false;
+#include "version.h"
+
+TMaybe<NActors::TInterconnectProxyCommon::TVersionInfo> VERSION = NActors::TInterconnectProxyCommon::TVersionInfo{
+ // version of this binary
+ "trunk",
+
+ // compatible versions; must include all compatible old ones, including this one; version verification occurs on both
+ // peers and connection is accepted if at least one of peers accepts the version of the other peer
+ {
+ "trunk"
+ }
+};
+
+TString GetBranchName(TString url) {
+ bool found = false;
for (const char *prefix : {"arcadia.yandex.ru/arc/", "arcadia/arc/", "arcadia.arc.yandex.ru/arc/"}) {
const char *base = url.data();
- const char *p = strstr(base, prefix);
- if (p) {
- url = url.substr(p + strlen(prefix) - base);
- found = true;
- break;
- }
- }
- if (!found) {
- return TString();
- }
-
- static TString suffix("/arcadia");
- if (url.EndsWith(suffix)) {
- url = url.substr(0, url.length() - suffix.length());
- } else if (url.EndsWith("/arc/trunk")) {
- url = "trunk";
- } else {
- return TString();
- }
-
- return url;
-}
-
-void CheckVersionTag() {
- if (VERSION) {
- const char *version = GetProgramSvnVersion();
- const char *p = strstr(version, "URL: ");
- if (p) {
- p += 5; // shift "URL: "
- const char *end = strchr(p, '\n');
- if (end) {
- while (end > p && std::isspace(end[-1])) {
- --end;
- }
- TString url(p, end);
- TString branch = GetBranchName(url);
- if (branch != "trunk" && VERSION->Tag == "trunk") {
+ const char *p = strstr(base, prefix);
+ if (p) {
+ url = url.substr(p + strlen(prefix) - base);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return TString();
+ }
+
+ static TString suffix("/arcadia");
+ if (url.EndsWith(suffix)) {
+ url = url.substr(0, url.length() - suffix.length());
+ } else if (url.EndsWith("/arc/trunk")) {
+ url = "trunk";
+ } else {
+ return TString();
+ }
+
+ return url;
+}
+
+void CheckVersionTag() {
+ if (VERSION) {
+ const char *version = GetProgramSvnVersion();
+ const char *p = strstr(version, "URL: ");
+ if (p) {
+ p += 5; // shift "URL: "
+ const char *end = strchr(p, '\n');
+ if (end) {
+ while (end > p && std::isspace(end[-1])) {
+ --end;
+ }
+ TString url(p, end);
+ TString branch = GetBranchName(url);
+ if (branch != "trunk" && VERSION->Tag == "trunk") {
Y_FAIL("non-trunk branch %s from URL# %s contains VersionTag# trunk", branch.data(), url.data());
- }
- }
- }
- }
-}
+ }
+ }
+ }
+ }
+}
diff --git a/ydb/core/driver_lib/run/version.h b/ydb/core/driver_lib/run/version.h
index 27230577aa4..3e881e53791 100644
--- a/ydb/core/driver_lib/run/version.h
+++ b/ydb/core/driver_lib/run/version.h
@@ -1,8 +1,8 @@
-#pragma once
-
+#pragma once
+
#include <library/cpp/actors/interconnect/interconnect_common.h>
-
-extern TMaybe<NActors::TInterconnectProxyCommon::TVersionInfo> VERSION;
-
-void CheckVersionTag();
-TString GetBranchName(TString url);
+
+extern TMaybe<NActors::TInterconnectProxyCommon::TVersionInfo> VERSION;
+
+void CheckVersionTag();
+TString GetBranchName(TString url);
diff --git a/ydb/core/driver_lib/run/version_ut.cpp b/ydb/core/driver_lib/run/version_ut.cpp
index 319f7e52669..41152953bf6 100644
--- a/ydb/core/driver_lib/run/version_ut.cpp
+++ b/ydb/core/driver_lib/run/version_ut.cpp
@@ -1,11 +1,11 @@
#include <library/cpp/testing/unittest/registar.h>
-#include "version.h"
-
-Y_UNIT_TEST_SUITE(VersionParser) {
- Y_UNIT_TEST(Basic) {
- UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn+ssh://arcadia.yandex.ru/arc/trunk/arcadia"), "trunk");
- UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn+ssh://arcadia/arc/trunk/arcadia"), "trunk");
- UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn://arcadia/arc/trunk/arcadia"), "trunk");
- UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn://arcadia/arc/branches/kikimr/arcadia"), "branches/kikimr");
- }
-}
+#include "version.h"
+
+Y_UNIT_TEST_SUITE(VersionParser) {
+ Y_UNIT_TEST(Basic) {
+ UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn+ssh://arcadia.yandex.ru/arc/trunk/arcadia"), "trunk");
+ UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn+ssh://arcadia/arc/trunk/arcadia"), "trunk");
+ UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn://arcadia/arc/trunk/arcadia"), "trunk");
+ UNIT_ASSERT_VALUES_EQUAL(GetBranchName("svn://arcadia/arc/branches/kikimr/arcadia"), "branches/kikimr");
+ }
+}
diff --git a/ydb/core/driver_lib/run/ya.make b/ydb/core/driver_lib/run/ya.make
index f410ef42f20..a5c9814d68b 100644
--- a/ydb/core/driver_lib/run/ya.make
+++ b/ydb/core/driver_lib/run/ya.make
@@ -37,8 +37,8 @@ SRCS(
run.h
service_initializer.cpp
service_initializer.h
- version.cpp
- version.h
+ version.cpp
+ version.h
)
PEERDIR(
diff --git a/ydb/core/engine/minikql/flat_local_tx_read_columns.h b/ydb/core/engine/minikql/flat_local_tx_read_columns.h
index 57d3c7bef9d..db4ddea68e1 100644
--- a/ydb/core/engine/minikql/flat_local_tx_read_columns.h
+++ b/ydb/core/engine/minikql/flat_local_tx_read_columns.h
@@ -79,7 +79,7 @@ public:
TVector<NTable::TTag> valueColumns;
TVector<std::pair<TString, NScheme::TTypeId>> columns;
- for (const auto& col : Ev->Get()->Record.GetColumns()) {
+ for (const auto& col : Ev->Get()->Record.GetColumns()) {
const auto* colNameInfo = tableInfo->ColumnNames.FindPtr(col);
if (!colNameInfo) {
SetError(Ydb::StatusIds::SCHEME_ERROR, Sprintf("Unknown column %s", col.c_str()));
diff --git a/ydb/core/erasure/erasure.cpp b/ydb/core/erasure/erasure.cpp
index a41b0279328..0f59497bf07 100644
--- a/ydb/core/erasure/erasure.cpp
+++ b/ydb/core/erasure/erasure.cpp
@@ -77,7 +77,7 @@ const char *TErasureType::ErasureSpeciesToStr(TErasureType::EErasureSpecies es)
case Erasure2Plus3Stripe: return "2Plus3Stripe";
case Erasure2Plus2Block: return "2Plus2Block";
case Erasure2Plus2Stripe: return "2Plus2Stripe";
- case ErasureMirror3of4: return "ErasureMirror3of4";
+ case ErasureMirror3of4: return "ErasureMirror3of4";
default: return "UNKNOWN";
}
}
@@ -89,7 +89,7 @@ struct TErasureParameters {
ui32 Prime; // for parity - smallest prime number >= DataParts, for mirror - 1
};
-static const std::array<TErasureParameters, TErasureType::ErasureSpeciesCount> ErasureSpeciesParameters{{
+static const std::array<TErasureParameters, TErasureType::ErasureSpeciesCount> ErasureSpeciesParameters{{
{TErasureType::ErasureMirror, 1, 0, 1} // 0 = ErasureSpicies::ErasureNone
,{TErasureType::ErasureMirror, 1, 2, 1} // 1 = ErasureSpicies::ErasureMirror3
,{TErasureType::ErasureParityBlock, 3, 1, 3} // 2 = ErasureSpicies::Erasure3Plus1Block
@@ -99,7 +99,7 @@ static const std::array<TErasureParameters, TErasureType::ErasureSpeciesCount> E
,{TErasureType::ErasureParityStripe, 4, 2, 5} // 6 = ErasureSpicies::Erasure4Plus2Stipe
,{TErasureType::ErasureParityStripe, 3, 2, 3} // 7 = ErasureSpicies::Erasure3Plus2Stipe
,{TErasureType::ErasureMirror, 1, 2, 1} // 8 = ErasureSpicies::ErasureMirror3Plus2
- ,{TErasureType::ErasureMirror, 1, 2, 1} // 9 = ErasureSpicies::ErasureMirror3dc
+ ,{TErasureType::ErasureMirror, 1, 2, 1} // 9 = ErasureSpicies::ErasureMirror3dc
,{TErasureType::ErasureParityBlock, 4, 3, 5} // 10 = ErasureSpicies::Erasure4Plus3Block
,{TErasureType::ErasureParityStripe, 4, 3, 5} // 11 = ErasureSpicies::Erasure4Plus3Stripe
,{TErasureType::ErasureParityBlock, 3, 3, 3} // 12 = ErasureSpicies::Erasure3Plus3Block
@@ -108,8 +108,8 @@ static const std::array<TErasureParameters, TErasureType::ErasureSpeciesCount> E
,{TErasureType::ErasureParityStripe, 2, 3, 3} // 15 = ErasureSpicies::Erasure2Plus3Stripe
,{TErasureType::ErasureParityBlock, 2, 2, 3} // 16 = ErasureSpicies::Erasure2Plus2Block
,{TErasureType::ErasureParityStripe, 2, 2, 3} // 17 = ErasureSpicies::Erasure2Plus2Stripe
- ,{TErasureType::ErasureMirror, 1, 2, 1} // 18 = ErasureSpicies::ErasureMirror3of4
-}};
+ ,{TErasureType::ErasureMirror, 1, 2, 1} // 18 = ErasureSpicies::ErasureMirror3of4
+}};
void PadAndCrcAtTheEnd(char *data, ui64 dataSize, ui64 bufferSize) {
ui64 marginSize = bufferSize - dataSize - sizeof(ui32);
@@ -492,10 +492,10 @@ public:
memset(bufferDataPart[i], 0, ColumnSize);
}
bufferDataPart[DataParts - 1] = (ui64*)(lastBlockSource + (DataParts - 1) * ColumnSize);
- char *lastColumnData = reinterpret_cast<char*>(bufferDataPart[DataParts - 1]);
+ char *lastColumnData = reinterpret_cast<char*>(bufferDataPart[DataParts - 1]);
if (LastPartTailSize) {
memcpy(lastColumnData,
- reinterpret_cast<const char*>(BufferDataPart[DataParts - 1]) + WholeBlocks * ColumnSize,
+ reinterpret_cast<const char*>(BufferDataPart[DataParts - 1]) + WholeBlocks * ColumnSize,
LastPartTailSize);
}
memset(lastColumnData + LastPartTailSize, 0, ColumnSize - LastPartTailSize);
@@ -518,10 +518,10 @@ public:
memcpy(Data + WholeBlocks * BlockSize, lastBlock, TailSize);
} else {
for (ui32 i = 0; i < FirstSmallPartIdx; ++i) {
- memcpy(reinterpret_cast<char*>(BufferDataPart[i]) + WholeBlocks * ColumnSize,
+ memcpy(reinterpret_cast<char*>(BufferDataPart[i]) + WholeBlocks * ColumnSize,
bufferDataPart[i], ColumnSize);
}
- memcpy(reinterpret_cast<char*>(BufferDataPart[DataParts - 1]) + WholeBlocks * ColumnSize,
+ memcpy(reinterpret_cast<char*>(BufferDataPart[DataParts - 1]) + WholeBlocks * ColumnSize,
bufferDataPart[DataParts - 1], LastPartTailSize);
}
}
@@ -1289,7 +1289,7 @@ public:
VERBOSE_COUT("Out: " << Endl);
for (ui64 lineIdx = 0; lineIdx < LineCount; ++lineIdx) {
for (ui32 part = 0; part <= DataParts; ++part) {
- ui64 partData = *reinterpret_cast<const ui64*>(
+ ui64 partData = *reinterpret_cast<const ui64*>(
partSet.Parts[part].GetDataAt(readPosition - ColumnSize + lineIdx * sizeof(ui64)));
VERBOSE_COUT(DebugFormatBits(partData) << ", ");
}
@@ -1383,7 +1383,7 @@ void StarBlockSplit(TErasureType::ECrcMode crcMode, const TErasureType &type, co
TBlockParams p(crcMode, type, buffer.size());
// Prepare input data pointers
- p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
+ p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
outPartSet.FullDataSize = buffer.size();
outPartSet.PartsMask = ~((~(ui32)0) << p.TotalParts);
@@ -1404,7 +1404,7 @@ void EoBlockSplit(TErasureType::ECrcMode crcMode, const TErasureType &type, cons
TBlockParams p(crcMode, type, buffer.size());
// Prepare input data pointers
- p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
+ p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
// Prepare if not yet
if (!outPartSet.IsSplitStarted()) {
@@ -1434,7 +1434,7 @@ void XorBlockSplit(TErasureType::ECrcMode crcMode, const TErasureType &type, con
TBlockParams p(crcMode, type, buffer.size());
// Prepare input data pointers
- p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
+ p.PrepareInputDataPointers<isStripe>(const_cast<char*>(buffer.data()));
outPartSet.FullDataSize = buffer.size();
outPartSet.PartsMask = ~((~(ui32)0) << p.TotalParts);
@@ -1515,17 +1515,17 @@ void EoBlockRestore(TErasureType::ECrcMode crcMode, const TErasureType &type, TD
(!restoreParts && missingDataPartIdxA >= p.TotalParts - 2)) {
VERBOSE_COUT(__LINE__ << " of " << __FILE__ << Endl);
if (isStripe) {
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
p.XorRestorePart<isStripe, false, true, false>(partSet, p.DataParts);
} else {
- p.GlueBlockParts(outBuffer.Detach(), partSet);
+ p.GlueBlockParts(outBuffer.Detach(), partSet);
}
return;
}
// Prepare output data pointers
if (restoreFullData) {
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
}
// Consider failed disk cases
@@ -1598,7 +1598,7 @@ void EoBlockRestore(TErasureType::ECrcMode crcMode, const TErasureType &type, TD
}
if (isStripe) {
TRACE(__LINE__ << Endl);
- p.PrepareInputDataPointers<isStripe>(buffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(buffer.Detach());
p.XorRestorePart<isStripe, false, true, false>(partSet, p.DataParts);
} else {
TRACE(__LINE__ << Endl);
@@ -1728,7 +1728,7 @@ void StarBlockRestore(TErasureType::ECrcMode crcMode, const TErasureType &type,
TBlockParams p(crcMode, type, dataSize);
if (restoreFullData) {
Refurbish(outBuffer, dataSize);
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
} else if (missingDataPartCount == 0) {
return;
}
@@ -1738,10 +1738,10 @@ void StarBlockRestore(TErasureType::ECrcMode crcMode, const TErasureType &type,
(!restoreParts && missingDataPartIdxA >= p.DataParts)) {
VERBOSE_COUT(__LINE__ << " of " << __FILE__ << Endl);
if (isStripe) {
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
p.XorRestorePart<isStripe, false, true, false>(partSet, p.DataParts);
} else {
- p.GlueBlockParts(outBuffer.Detach(), partSet);
+ p.GlueBlockParts(outBuffer.Detach(), partSet);
}
return;
}
@@ -1919,16 +1919,16 @@ void XorBlockRestore(TErasureType::ECrcMode crcMode, const TErasureType &type, T
if (missingDataPartCount == 0 ||
(missingDataPartCount == 1 && !restoreParts && missingDataPartIdx == p.TotalParts - 1)) {
if (isStripe) {
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
p.XorRestorePart<isStripe, false, true, false>(partSet, p.DataParts);
} else {
- p.GlueBlockParts(outBuffer.Detach(), partSet);
+ p.GlueBlockParts(outBuffer.Detach(), partSet);
}
return;
}
// Prepare output data pointers
if (restoreFullData) {
- p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
+ p.PrepareInputDataPointers<isStripe>(outBuffer.Detach());
}
p.XorRestorePart<isStripe, restoreParts, restoreFullData, restoreParityParts>(partSet, missingDataPartIdx);
@@ -1942,8 +1942,8 @@ const std::array<TString, TErasureType::ErasureSpeciesCount> TErasureType::Erasu
"block-4-2",
"block-3-2",
"stripe-4-2",
- "stripe-3-2",
- "mirror-3-2",
+ "stripe-3-2",
+ "mirror-3-2",
"mirror-3-dc",
"block-4-3",
"stripe-4-3",
@@ -1953,8 +1953,8 @@ const std::array<TString, TErasureType::ErasureSpeciesCount> TErasureType::Erasu
"stripe-2-3",
"block-2-2",
"stripe-2-2",
- "mirror-3of4",
-}};
+ "mirror-3of4",
+}};
TErasureType::EErasureFamily TErasureType::ErasureFamily() const {
const TErasureParameters &erasure = ErasureSpeciesParameters[ErasureSpecies];
diff --git a/ydb/core/erasure/erasure.h b/ydb/core/erasure/erasure.h
index 35bd68c2d2f..ff4366e264f 100644
--- a/ydb/core/erasure/erasure.h
+++ b/ydb/core/erasure/erasure.h
@@ -1,7 +1,7 @@
#pragma once
-
-#include <array>
-
+
+#include <array>
+
#include <ydb/core/debug/valgrind_check.h>
#include <ydb/core/util/yverify_stream.h>
@@ -238,9 +238,9 @@ struct TErasureType {
Erasure4Plus2Stripe = 6,
Erasure3Plus2Stripe = 7,
- ErasureMirror3Plus2 = 8,
- ErasureMirror3dc = 9,
-
+ ErasureMirror3Plus2 = 8,
+ ErasureMirror3dc = 9,
+
Erasure4Plus3Block = 10,
Erasure4Plus3Stripe = 11,
Erasure3Plus3Block = 12,
@@ -251,9 +251,9 @@ struct TErasureType {
Erasure2Plus2Block = 16,
Erasure2Plus2Stripe = 17,
- ErasureMirror3of4 = 18,
-
- ErasureSpeciesCount = 19
+ ErasureMirror3of4 = 18,
+
+ ErasureSpeciesCount = 19
};
static const char *ErasureSpeciesToStr(EErasureSpecies es);
diff --git a/ydb/core/erasure/erasure_rope.cpp b/ydb/core/erasure/erasure_rope.cpp
index b1de833d936..7f1c2a52b00 100644
--- a/ydb/core/erasure/erasure_rope.cpp
+++ b/ydb/core/erasure/erasure_rope.cpp
@@ -77,7 +77,7 @@ const char *TRopeErasureType::ErasureSpeciesToStr(TRopeErasureType::EErasureSpec
case Erasure2Plus3Stripe: return "2Plus3Stripe";
case Erasure2Plus2Block: return "2Plus2Block";
case Erasure2Plus2Stripe: return "2Plus2Stripe";
- case ErasureMirror3of4: return "Mirror3of4";
+ case ErasureMirror3of4: return "Mirror3of4";
default: return "UNKNOWN";
}
}
@@ -108,7 +108,7 @@ static const std::array<TErasureParameters, TRopeErasureType::ErasureSpeciesCoun
,{TRopeErasureType::ErasureParityStripe, 2, 3, 3} // 15 = ErasureSpicies::Erasure2Plus3Stripe
,{TRopeErasureType::ErasureParityBlock, 2, 2, 3} // 16 = ErasureSpicies::Erasure2Plus2Block
,{TRopeErasureType::ErasureParityStripe, 2, 2, 3} // 17 = ErasureSpicies::Erasure2Plus2Stripe
- ,{TRopeErasureType::ErasureMirror, 1, 2, 1} // 18 = ErasureSpicies::ErasureMirror3of4
+ ,{TRopeErasureType::ErasureMirror, 1, 2, 1} // 18 = ErasureSpicies::ErasureMirror3of4
}};
void PadAndCrcAtTheEnd(TRopeHelpers::Iterator data, ui64 dataSize, ui64 bufferSize) {
@@ -2266,7 +2266,7 @@ const std::array<TString, TRopeErasureType::ErasureSpeciesCount> TRopeErasureTyp
"stripe-2-3",
"block-2-2",
"stripe-2-2",
- "mirror-3of4",
+ "mirror-3of4",
}};
ui32 TRopeErasureType::ParityParts() const {
diff --git a/ydb/core/erasure/erasure_rope.h b/ydb/core/erasure/erasure_rope.h
index a4835ce8341..5422a6cee58 100644
--- a/ydb/core/erasure/erasure_rope.h
+++ b/ydb/core/erasure/erasure_rope.h
@@ -66,7 +66,7 @@ public:
if (string.Empty()) {
return rope;
}
- rope.Insert(rope.End(), TRope(std::move(string)));
+ rope.Insert(rope.End(), TRope(std::move(string)));
return rope;
}
@@ -439,9 +439,9 @@ struct TRopeErasureType {
Erasure2Plus2Block = 16,
Erasure2Plus2Stripe = 17, // Not implemented in TRope version of erasure
- ErasureMirror3of4 = 18,
-
- ErasureSpeciesCount = 19
+ ErasureMirror3of4 = 18,
+
+ ErasureSpeciesCount = 19
};
static const char *ErasureSpeciesToStr(EErasureSpecies es);
diff --git a/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp b/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
index ce65619641b..7caa30f6be6 100644
--- a/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
+++ b/ydb/core/grpc_services/grpc_endpoint_publish_actor.cpp
@@ -109,8 +109,8 @@ class TGRpcEndpointPublishActor : public TActorBootstrapped<TGRpcEndpointPublish
void Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
auto *msg = ev->Get();
- if (msg->Node && msg->Node->Location.GetDataCenterId())
- SelfDatacenter = msg->Node->Location.GetDataCenterId();
+ if (msg->Node && msg->Node->Location.GetDataCenterId())
+ SelfDatacenter = msg->Node->Location.GetDataCenterId();
if (Description->ServedDatabases) {
TString payload;
@@ -164,4 +164,4 @@ IActor* CreateGrpcEndpointPublishActor(TGrpcEndpointDescription *description) {
}
}
-}
+}
diff --git a/ydb/core/grpc_services/grpc_helper.cpp b/ydb/core/grpc_services/grpc_helper.cpp
index b1ef484cc7d..8c8024ad935 100644
--- a/ydb/core/grpc_services/grpc_helper.cpp
+++ b/ydb/core/grpc_services/grpc_helper.cpp
@@ -4,7 +4,7 @@ namespace NKikimr {
namespace NGRpcService {
//using namespace NActors;
-
+
NGrpc::IGRpcRequestLimiterPtr TCreateLimiterCB::operator()(const char* serviceName, const char* requestName, i64 limit) const {
TString fullName = TString(serviceName) + "_" + requestName;
return LimiterRegistry->RegisterRequestType(fullName, limit);
diff --git a/ydb/core/grpc_services/grpc_mon.cpp b/ydb/core/grpc_services/grpc_mon.cpp
index cd15157b052..19104257276 100644
--- a/ydb/core/grpc_services/grpc_mon.cpp
+++ b/ydb/core/grpc_services/grpc_mon.cpp
@@ -42,8 +42,8 @@ public:
, Peers(2000)
{}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_MON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_MON;
}
private:
diff --git a/ydb/core/grpc_services/grpc_request_proxy.cpp b/ydb/core/grpc_services/grpc_request_proxy.cpp
index a1e7accb877..807d0725a3f 100644
--- a/ydb/core/grpc_services/grpc_request_proxy.cpp
+++ b/ydb/core/grpc_services/grpc_request_proxy.cpp
@@ -85,7 +85,7 @@ public:
void Bootstrap(const TActorContext& ctx);
void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& ctx);
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::GRPC_PROXY;
}
diff --git a/ydb/core/grpc_services/rpc_discovery.cpp b/ydb/core/grpc_services/rpc_discovery.cpp
index 75550f92acf..89a7a0ddbd0 100644
--- a/ydb/core/grpc_services/rpc_discovery.cpp
+++ b/ydb/core/grpc_services/rpc_discovery.cpp
@@ -140,8 +140,8 @@ class TListEndpointsRPC : public TActorBootstrapped<TListEndpointsRPC> {
ui64 LookupCookie = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_REQ;
}
TListEndpointsRPC(TEvListEndpointsRequest::TPtr &msg, TActorId cacheId)
@@ -395,8 +395,8 @@ public:
}
auto &nodeInfo = NameserviceResponse->Node;
- if (nodeInfo && nodeInfo->Location.GetDataCenterId()) {
- const auto &location = nodeInfo->Location.GetDataCenterId();
+ if (nodeInfo && nodeInfo->Location.GetDataCenterId()) {
+ const auto &location = nodeInfo->Location.GetDataCenterId();
if (IsSafeLocationMarker(location))
result->set_self_location(location);
}
diff --git a/ydb/core/grpc_services/rpc_get_shard_locations.cpp b/ydb/core/grpc_services/rpc_get_shard_locations.cpp
index f7088c8eb60..3804d5c436d 100644
--- a/ydb/core/grpc_services/rpc_get_shard_locations.cpp
+++ b/ydb/core/grpc_services/rpc_get_shard_locations.cpp
@@ -39,8 +39,8 @@ private:
THashMap<ui32, TNodeInfo> NodeInfos;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_REQ;
}
explicit TGetShardLocationsRPC(TAutoPtr<TEvGetShardLocationsRequest> request)
diff --git a/ydb/core/grpc_services/rpc_read_columns.cpp b/ydb/core/grpc_services/rpc_read_columns.cpp
index 4baae606a97..92605bd3d53 100644
--- a/ydb/core/grpc_services/rpc_read_columns.cpp
+++ b/ydb/core/grpc_services/rpc_read_columns.cpp
@@ -69,8 +69,8 @@ private:
TKikhouseSnapshotId SnapshotId;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_REQ;
}
explicit TReadColumnsRPC(TAutoPtr<TEvReadColumnsRequest> request)
diff --git a/ydb/core/grpc_services/rpc_read_table.cpp b/ydb/core/grpc_services/rpc_read_table.cpp
index bbb87907289..23dfdbcfec2 100644
--- a/ydb/core/grpc_services/rpc_read_table.cpp
+++ b/ydb/core/grpc_services/rpc_read_table.cpp
@@ -103,8 +103,8 @@ class TReadTableRPC : public TActorBootstrapped<TReadTableRPC> {
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_STREAM_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_STREAM_REQ;
}
TReadTableRPC(TEvReadTableRequest* msg)
diff --git a/ydb/core/grpc_services/rpc_stream_execute_scan_query.cpp b/ydb/core/grpc_services/rpc_stream_execute_scan_query.cpp
index 5f95f263c6f..8a23f4a7d98 100644
--- a/ydb/core/grpc_services/rpc_stream_execute_scan_query.cpp
+++ b/ydb/core/grpc_services/rpc_stream_execute_scan_query.cpp
@@ -249,8 +249,8 @@ private:
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::GRPC_STREAM_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::GRPC_STREAM_REQ;
}
TStreamExecuteScanQueryRPC(TRequestEv* request, ui64 rpcBufferSize)
diff --git a/ydb/core/grpc_services/ut/ya.make b/ydb/core/grpc_services/ut/ya.make
index b1888784b2d..ee594c216cb 100644
--- a/ydb/core/grpc_services/ut/ya.make
+++ b/ydb/core/grpc_services/ut/ya.make
@@ -7,10 +7,10 @@ OWNER(
FORK_SUBTESTS()
-IF (SANITIZER_TYPE OR WITH_VALGRIND)
- SIZE(MEDIUM)
-ENDIF()
-
+IF (SANITIZER_TYPE OR WITH_VALGRIND)
+ SIZE(MEDIUM)
+ENDIF()
+
SRCS(
rpc_calls_ut.cpp
operation_helpers_ut.cpp
diff --git a/ydb/core/health_check/health_check.cpp b/ydb/core/health_check/health_check.cpp
index 7995c58aafc..3d1b2dc9448 100644
--- a/ydb/core/health_check/health_check.cpp
+++ b/ydb/core/health_check/health_check.cpp
@@ -1475,37 +1475,37 @@ public:
if (pDiskInfo.HasState()) {
switch (pDiskInfo.GetState()) {
- case NKikimrBlobStorage::TPDiskState::Normal:
+ case NKikimrBlobStorage::TPDiskState::Normal:
context.ReportStatus(Ydb::Monitoring::StatusFlag::GREEN);
break;
- case NKikimrBlobStorage::TPDiskState::Initial:
- case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
+ case NKikimrBlobStorage::TPDiskState::Initial:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
context.ReportStatus(Ydb::Monitoring::StatusFlag::YELLOW,
- TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
+ TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
"pdisk-state");
break;
- case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
- case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
- case NKikimrBlobStorage::TPDiskState::OpenFileError:
- case NKikimrBlobStorage::TPDiskState::ChunkQuotaError:
- case NKikimrBlobStorage::TPDiskState::DeviceIoError:
- case NKikimrBlobStorage::TPDiskState::Missing:
- case NKikimrBlobStorage::TPDiskState::Timeout:
- case NKikimrBlobStorage::TPDiskState::NodeDisconnected:
- case NKikimrBlobStorage::TPDiskState::Unknown:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
+ case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
+ case NKikimrBlobStorage::TPDiskState::OpenFileError:
+ case NKikimrBlobStorage::TPDiskState::ChunkQuotaError:
+ case NKikimrBlobStorage::TPDiskState::DeviceIoError:
+ case NKikimrBlobStorage::TPDiskState::Missing:
+ case NKikimrBlobStorage::TPDiskState::Timeout:
+ case NKikimrBlobStorage::TPDiskState::NodeDisconnected:
+ case NKikimrBlobStorage::TPDiskState::Unknown:
context.ReportStatus(Ydb::Monitoring::StatusFlag::RED,
- TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
+ TStringBuilder() << "PDisk state is " << NKikimrBlobStorage::TPDiskState::E_Name(pDiskInfo.GetState()),
"pdisk-state");
break;
- case NKikimrBlobStorage::TPDiskState::Reserved14:
- case NKikimrBlobStorage::TPDiskState::Reserved15:
- case NKikimrBlobStorage::TPDiskState::Reserved16:
+ case NKikimrBlobStorage::TPDiskState::Reserved14:
+ case NKikimrBlobStorage::TPDiskState::Reserved15:
+ case NKikimrBlobStorage::TPDiskState::Reserved16:
context.ReportStatus(Ydb::Monitoring::StatusFlag::RED, "Unknown PDisk state");
break;
}
diff --git a/ydb/core/kesus/proxy/proxy.cpp b/ydb/core/kesus/proxy/proxy.cpp
index 9633816e60a..89638913fdd 100644
--- a/ydb/core/kesus/proxy/proxy.cpp
+++ b/ydb/core/kesus/proxy/proxy.cpp
@@ -68,8 +68,8 @@ public:
: TActor(&TThis::StateWork)
{}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KESUS_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KESUS_PROXY_ACTOR;
}
private:
@@ -240,8 +240,8 @@ public:
Become(&TThis::StateWork);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KESUS_RESOLVE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KESUS_RESOLVE_ACTOR;
}
private:
diff --git a/ydb/core/kesus/proxy/proxy_actor.cpp b/ydb/core/kesus/proxy/proxy_actor.cpp
index e93d90355fc..32bb31dc128 100644
--- a/ydb/core/kesus/proxy/proxy_actor.cpp
+++ b/ydb/core/kesus/proxy/proxy_actor.cpp
@@ -93,8 +93,8 @@ public:
Become(&TThis::StateWork);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KESUS_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KESUS_PROXY_ACTOR;
}
private:
diff --git a/ydb/core/kesus/tablet/tablet_impl.h b/ydb/core/kesus/tablet/tablet_impl.h
index 1607e352d05..127807431a1 100644
--- a/ydb/core/kesus/tablet/tablet_impl.h
+++ b/ydb/core/kesus/tablet/tablet_impl.h
@@ -320,8 +320,8 @@ public:
TKesusTablet(const TActorId& tablet, TTabletStorageInfo* info);
virtual ~TKesusTablet();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KESUS_TABLET_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KESUS_TABLET_ACTOR;
}
private:
diff --git a/ydb/core/keyvalue/channel_balancer.h b/ydb/core/keyvalue/channel_balancer.h
index 36c3bea5ab2..96500289701 100644
--- a/ydb/core/keyvalue/channel_balancer.h
+++ b/ydb/core/keyvalue/channel_balancer.h
@@ -1,177 +1,177 @@
-#pragma once
-
-#include "defs.h"
-#include "keyvalue_events.h"
-#include <bitset>
-
-namespace NKikimr::NKeyValue {
-
- class TChannelBalancer : public TActorBootstrapped<TChannelBalancer> {
- public:
- class TWeightManager {
- TVector<ui64> Weights;
-
- public:
- TWeightManager(TVector<ui64> weights)
- : Weights(std::move(weights))
- {
- Y_VERIFY(0 < Weights.size() && Weights.size() <= 256);
- }
-
- int Pick(const std::bitset<256>& enabled) const {
- std::array<ui64, 256> accum;
- ui64 counter = 0;
- for (size_t i = 0; i < Weights.size(); ++i) {
- if (enabled[i]) {
- counter += Weights[i];
- }
- accum[i] = counter;
- }
- if (!counter) {
- return -1;
- }
-
- const ui64 r = RandomNumber(counter);
- const auto begin = accum.begin();
- const auto end = begin + Weights.size();
- const auto iter = std::upper_bound(begin, end, r);
- Y_VERIFY(iter != end);
- return iter - begin;
- }
- };
-
- struct TEvReportWriteLatency : TEventLocal<TEvReportWriteLatency, TEvKeyValue::EvReportWriteLatency> {
- const ui8 Channel;
- const TDuration Latency;
-
- TEvReportWriteLatency(ui8 channel, TDuration latency)
- : Channel(channel)
- , Latency(latency)
- {}
- };
-
- struct TEvUpdateWeights : TEventLocal<TEvUpdateWeights, TEvKeyValue::EvUpdateWeights> {
- THolder<TWeightManager> WeightManager;
-
- TEvUpdateWeights(THolder<TWeightManager>&& wm)
- : WeightManager(std::move(wm))
- {}
- };
-
- private:
- static constexpr TDuration UpdateWeightsTimeout = TDuration::Seconds(10);
-
- class TChannelInfo {
- struct TLatencyRecord {
- TInstant Timestamp;
- TDuration Latency;
- };
-
- static constexpr TDuration AggregationWindow = TDuration::Minutes(10);
- static constexpr ui32 MaxSamples = 65536;
- static constexpr TDuration MeanExpectedLatency = TDuration::MilliSeconds(100);
- static constexpr ui32 MinSamplesToDecide = 10;
-
- TDeque<TLatencyRecord> LatencyQueue;
- TMaybe<ui64> PrevWeight;
-
- public:
- void ReportWriteLatency(TInstant timestamp, TDuration latency) {
- Cleanup(timestamp);
- if (LatencyQueue.size() == MaxSamples) {
- TDeque<TLatencyRecord> filtered;
- for (auto it = LatencyQueue.begin(); it != LatencyQueue.end(); it += 2) {
- filtered.push_back(*it);
- }
- LatencyQueue = std::move(filtered);
- }
- LatencyQueue.push_back(TLatencyRecord{timestamp, latency});
- }
-
- ui64 UpdateWeight(TInstant timestamp) {
- // IIR filter with depth=1
- ui64 w = GetWeight(timestamp);
- if (PrevWeight) {
- w = (w + *PrevWeight * 9) / 10;
- }
- PrevWeight = w;
- return w;
- }
-
- private:
- ui64 GetWeight(TInstant timestamp) {
- Cleanup(timestamp);
-
- ui64 weight = 1000;
-
- if (LatencyQueue.size() >= MinSamplesToDecide) {
- TVector<TDuration> latencies;
- latencies.reserve(LatencyQueue.size());
- for (const TLatencyRecord& record : LatencyQueue) {
- latencies.push_back(record.Latency);
- }
- std::sort(latencies.begin(), latencies.end());
- const size_t index = (LatencyQueue.size() - 1) * 99 / 100;
- const TDuration perc = latencies[index];
- weight = MeanExpectedLatency.GetValue() * weight / Max(perc, TDuration::MilliSeconds(1)).GetValue();
- Y_VERIFY_DEBUG(weight);
- if (!weight) {
- weight = 1;
- }
- }
-
- return weight;
- }
-
- void Cleanup(TInstant now) {
- // leave only aggregation window samples
- while (LatencyQueue && now - LatencyQueue.front().Timestamp > AggregationWindow) {
- LatencyQueue.pop_front();
- }
- }
- };
-
- TVector<TChannelInfo> ChannelInfo;
+#pragma once
+
+#include "defs.h"
+#include "keyvalue_events.h"
+#include <bitset>
+
+namespace NKikimr::NKeyValue {
+
+ class TChannelBalancer : public TActorBootstrapped<TChannelBalancer> {
+ public:
+ class TWeightManager {
+ TVector<ui64> Weights;
+
+ public:
+ TWeightManager(TVector<ui64> weights)
+ : Weights(std::move(weights))
+ {
+ Y_VERIFY(0 < Weights.size() && Weights.size() <= 256);
+ }
+
+ int Pick(const std::bitset<256>& enabled) const {
+ std::array<ui64, 256> accum;
+ ui64 counter = 0;
+ for (size_t i = 0; i < Weights.size(); ++i) {
+ if (enabled[i]) {
+ counter += Weights[i];
+ }
+ accum[i] = counter;
+ }
+ if (!counter) {
+ return -1;
+ }
+
+ const ui64 r = RandomNumber(counter);
+ const auto begin = accum.begin();
+ const auto end = begin + Weights.size();
+ const auto iter = std::upper_bound(begin, end, r);
+ Y_VERIFY(iter != end);
+ return iter - begin;
+ }
+ };
+
+ struct TEvReportWriteLatency : TEventLocal<TEvReportWriteLatency, TEvKeyValue::EvReportWriteLatency> {
+ const ui8 Channel;
+ const TDuration Latency;
+
+ TEvReportWriteLatency(ui8 channel, TDuration latency)
+ : Channel(channel)
+ , Latency(latency)
+ {}
+ };
+
+ struct TEvUpdateWeights : TEventLocal<TEvUpdateWeights, TEvKeyValue::EvUpdateWeights> {
+ THolder<TWeightManager> WeightManager;
+
+ TEvUpdateWeights(THolder<TWeightManager>&& wm)
+ : WeightManager(std::move(wm))
+ {}
+ };
+
+ private:
+ static constexpr TDuration UpdateWeightsTimeout = TDuration::Seconds(10);
+
+ class TChannelInfo {
+ struct TLatencyRecord {
+ TInstant Timestamp;
+ TDuration Latency;
+ };
+
+ static constexpr TDuration AggregationWindow = TDuration::Minutes(10);
+ static constexpr ui32 MaxSamples = 65536;
+ static constexpr TDuration MeanExpectedLatency = TDuration::MilliSeconds(100);
+ static constexpr ui32 MinSamplesToDecide = 10;
+
+ TDeque<TLatencyRecord> LatencyQueue;
+ TMaybe<ui64> PrevWeight;
+
+ public:
+ void ReportWriteLatency(TInstant timestamp, TDuration latency) {
+ Cleanup(timestamp);
+ if (LatencyQueue.size() == MaxSamples) {
+ TDeque<TLatencyRecord> filtered;
+ for (auto it = LatencyQueue.begin(); it != LatencyQueue.end(); it += 2) {
+ filtered.push_back(*it);
+ }
+ LatencyQueue = std::move(filtered);
+ }
+ LatencyQueue.push_back(TLatencyRecord{timestamp, latency});
+ }
+
+ ui64 UpdateWeight(TInstant timestamp) {
+ // IIR filter with depth=1
+ ui64 w = GetWeight(timestamp);
+ if (PrevWeight) {
+ w = (w + *PrevWeight * 9) / 10;
+ }
+ PrevWeight = w;
+ return w;
+ }
+
+ private:
+ ui64 GetWeight(TInstant timestamp) {
+ Cleanup(timestamp);
+
+ ui64 weight = 1000;
+
+ if (LatencyQueue.size() >= MinSamplesToDecide) {
+ TVector<TDuration> latencies;
+ latencies.reserve(LatencyQueue.size());
+ for (const TLatencyRecord& record : LatencyQueue) {
+ latencies.push_back(record.Latency);
+ }
+ std::sort(latencies.begin(), latencies.end());
+ const size_t index = (LatencyQueue.size() - 1) * 99 / 100;
+ const TDuration perc = latencies[index];
+ weight = MeanExpectedLatency.GetValue() * weight / Max(perc, TDuration::MilliSeconds(1)).GetValue();
+ Y_VERIFY_DEBUG(weight);
+ if (!weight) {
+ weight = 1;
+ }
+ }
+
+ return weight;
+ }
+
+ void Cleanup(TInstant now) {
+ // leave only aggregation window samples
+ while (LatencyQueue && now - LatencyQueue.front().Timestamp > AggregationWindow) {
+ LatencyQueue.pop_front();
+ }
+ }
+ };
+
+ TVector<TChannelInfo> ChannelInfo;
const TActorId ActorId;
-
- public:
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::KEYVALUE_ACTOR;
}
TChannelBalancer(ui8 numChannels, TActorId actorId)
- : ChannelInfo(numChannels)
- , ActorId(actorId)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc, ctx, UpdateWeightsTimeout, new TEvents::TEvWakeup);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvReportWriteLatency, Handle)
- CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
- CFunc(TEvents::TSystem::PoisonPill, Die)
- )
-
- void Handle(TEvReportWriteLatency::TPtr ev, const TActorContext& ctx) {
- const ui8 channel = ev->Get()->Channel;
- if (channel < ChannelInfo.size()) {
- TChannelInfo& info = ChannelInfo[channel];
- info.ReportWriteLatency(ctx.Now(), ev->Get()->Latency);
- }
- }
-
- void HandleWakeup(const TActorContext& ctx) {
- ctx.Schedule(UpdateWeightsTimeout, new TEvents::TEvWakeup);
- const TInstant now = ctx.Now();
- TVector<ui64> weights;
- weights.reserve(ChannelInfo.size());
- for (TChannelInfo& info : ChannelInfo) {
- weights.push_back(info.UpdateWeight(now));
- }
- ctx.Send(ActorId, new TEvUpdateWeights(MakeHolder<TWeightManager>(std::move(weights))));
- }
- };
-
-} // NKikimr::NKeyValue
+ : ChannelInfo(numChannels)
+ , ActorId(actorId)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc, ctx, UpdateWeightsTimeout, new TEvents::TEvWakeup);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvReportWriteLatency, Handle)
+ CFunc(TEvents::TSystem::Wakeup, HandleWakeup)
+ CFunc(TEvents::TSystem::PoisonPill, Die)
+ )
+
+ void Handle(TEvReportWriteLatency::TPtr ev, const TActorContext& ctx) {
+ const ui8 channel = ev->Get()->Channel;
+ if (channel < ChannelInfo.size()) {
+ TChannelInfo& info = ChannelInfo[channel];
+ info.ReportWriteLatency(ctx.Now(), ev->Get()->Latency);
+ }
+ }
+
+ void HandleWakeup(const TActorContext& ctx) {
+ ctx.Schedule(UpdateWeightsTimeout, new TEvents::TEvWakeup);
+ const TInstant now = ctx.Now();
+ TVector<ui64> weights;
+ weights.reserve(ChannelInfo.size());
+ for (TChannelInfo& info : ChannelInfo) {
+ weights.push_back(info.UpdateWeight(now));
+ }
+ ctx.Send(ActorId, new TEvUpdateWeights(MakeHolder<TWeightManager>(std::move(weights))));
+ }
+ };
+
+} // NKikimr::NKeyValue
diff --git a/ydb/core/keyvalue/keyvalue_collector.cpp b/ydb/core/keyvalue/keyvalue_collector.cpp
index 8b7696bcb25..8839065ecc4 100644
--- a/ydb/core/keyvalue/keyvalue_collector.cpp
+++ b/ydb/core/keyvalue/keyvalue_collector.cpp
@@ -26,8 +26,8 @@ class TKeyValueCollector : public TActorBootstrapped<TKeyValueCollector> {
TMap<ui32, TMap<ui32, TGroupCollector>> CollectorForGroupForChannel;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KEYVALUE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KEYVALUE_ACTOR;
}
TKeyValueCollector(const TActorId &keyValueActorId, TIntrusivePtr<TCollectOperation> &collectOperation,
diff --git a/ydb/core/keyvalue/keyvalue_events.h b/ydb/core/keyvalue/keyvalue_events.h
index 03bc81ad8fc..c92afd078dd 100644
--- a/ydb/core/keyvalue/keyvalue_events.h
+++ b/ydb/core/keyvalue/keyvalue_events.h
@@ -21,8 +21,8 @@ struct TEvKeyValue {
EvCollect,
EvEraseCollect,
EvPeriodicRefresh,
- EvReportWriteLatency,
- EvUpdateWeights,
+ EvReportWriteLatency,
+ EvUpdateWeights,
EvRead = EvRequest + 16,
EvReadRange,
@@ -116,12 +116,12 @@ struct TEvKeyValue {
};
struct TEvRequest : public TEventPB<TEvRequest,
- NKikimrClient::TKeyValueRequest, EvRequest> {
+ NKikimrClient::TKeyValueRequest, EvRequest> {
TEvRequest() { }
};
struct TEvResponse : public TEventPB<TEvResponse,
- NKikimrClient::TResponse, EvResponse> {
+ NKikimrClient::TResponse, EvResponse> {
TEvResponse() { }
};
diff --git a/ydb/core/keyvalue/keyvalue_flat_impl.h b/ydb/core/keyvalue/keyvalue_flat_impl.h
index 292f2feff93..e7122462336 100644
--- a/ydb/core/keyvalue/keyvalue_flat_impl.h
+++ b/ydb/core/keyvalue/keyvalue_flat_impl.h
@@ -67,7 +67,7 @@ protected:
Self.State.Clear();
} else {
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << txc.Tablet << " TTxInit flat ReadDb Tree");
- if (!LoadStateFromDB(Self.State, txc.DB)) {
+ if (!LoadStateFromDB(Self.State, txc.DB)) {
return false;
}
if (Self.State.GetIsDamaged()) {
@@ -119,7 +119,7 @@ protected:
TKeyValueFlat *Self;
TTxRequest(THolder<TIntermediate> intermediate, TKeyValueFlat *keyValueFlat)
- : Intermediate(std::move(intermediate))
+ : Intermediate(std::move(intermediate))
, Self(keyValueFlat)
{
Intermediate->Response.SetStatus(NMsgBusProxy::MSTATUS_UNKNOWN);
@@ -151,7 +151,7 @@ protected:
bool CheckConsistency(NTabletFlatExecutor::TTransactionContext &txc) {
#ifdef KIKIMR_KEYVALUE_CONSISTENCY_CHECKS
TKeyValueState state;
- if (!TTxInit::LoadStateFromDB(state, txc.DB)) {
+ if (!TTxInit::LoadStateFromDB(state, txc.DB)) {
return false;
}
Y_VERIFY(!state.IsDamaged());
@@ -166,36 +166,36 @@ protected:
};
struct TTxMonitoring : public NTabletFlatExecutor::ITransaction {
- const THolder<NMon::TEvRemoteHttpInfo> Event;
+ const THolder<NMon::TEvRemoteHttpInfo> Event;
const TActorId RespondTo;
TKeyValueFlat *Self;
TTxMonitoring(THolder<NMon::TEvRemoteHttpInfo> event, const TActorId &respondTo, TKeyValueFlat *keyValue)
- : Event(std::move(event))
- , RespondTo(respondTo)
+ : Event(std::move(event))
+ , RespondTo(respondTo)
, Self(keyValue)
{}
bool Execute(NTabletFlatExecutor::TTransactionContext &txc, const TActorContext &ctx) override {
Y_UNUSED(txc);
TStringStream str;
- THolder<IEventBase> response;
- TCgiParameters params(Event->Cgi());
- if (params.Has("section")) {
- const TString section = params.Get("section");
- NJson::TJsonValue json;
- if (section == "channelstat") {
- Self->State.MonChannelStat(json);
- } else {
- json["Error"] = "invalid json parameter value";
- }
- NJson::WriteJson(&str, &json);
- response = MakeHolder<NMon::TEvRemoteJsonInfoRes>(str.Str());
- } else {
- Self->State.RenderHTMLPage(str);
- response = MakeHolder<NMon::TEvRemoteHttpInfoRes>(str.Str());
- }
- ctx.Send(RespondTo, response.Release());
+ THolder<IEventBase> response;
+ TCgiParameters params(Event->Cgi());
+ if (params.Has("section")) {
+ const TString section = params.Get("section");
+ NJson::TJsonValue json;
+ if (section == "channelstat") {
+ Self->State.MonChannelStat(json);
+ } else {
+ json["Error"] = "invalid json parameter value";
+ }
+ NJson::WriteJson(&str, &json);
+ response = MakeHolder<NMon::TEvRemoteJsonInfoRes>(str.Str());
+ } else {
+ Self->State.RenderHTMLPage(str);
+ response = MakeHolder<NMon::TEvRemoteHttpInfoRes>(str.Str());
+ }
+ ctx.Send(RespondTo, response.Release());
return true;
}
@@ -269,7 +269,7 @@ protected:
}
void Enqueue(STFUNC_SIG) override {
- SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR);
+ SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR);
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE,
"KeyValue# " << TabletID()
<< " Enqueue, event type# " << (ui32)ev->GetTypeRewrite()
@@ -353,7 +353,7 @@ protected:
CheckYellowChannels(ev->Get()->Intermediate->Stat);
State.OnEvIntermediate(*(ev->Get()->Intermediate), ctx);
- Execute(new TTxRequest(std::move(ev->Get()->Intermediate), this), ctx);
+ Execute(new TTxRequest(std::move(ev->Get()->Intermediate), this), ctx);
}
void Handle(TEvKeyValue::TEvNotify::TPtr &ev, const TActorContext &ctx) {
@@ -386,10 +386,10 @@ protected:
State.OnPeriodicRefresh(ctx);
}
- void Handle(TChannelBalancer::TEvUpdateWeights::TPtr ev, const TActorContext& /*ctx*/) {
- State.OnUpdateWeights(ev);
- }
-
+ void Handle(TChannelBalancer::TEvUpdateWeights::TPtr ev, const TActorContext& /*ctx*/) {
+ State.OnUpdateWeights(ev);
+ }
+
bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext &ctx) override {
if (!Executor() || !Executor()->GetStats().IsActive)
return false;
@@ -399,7 +399,7 @@ protected:
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletID() << " Handle TEvRemoteHttpInfo: %s"
<< ev->Get()->Query.data());
- Execute(new TTxMonitoring(ev->Release(), ev->Sender, this), ctx);
+ Execute(new TTxMonitoring(ev->Release(), ev->Sender, this), ctx);
return true;
}
@@ -412,12 +412,12 @@ protected:
}
void RestoreActorActivity() {
- SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR);
+ SetActivityType(NKikimrServices::TActivity::KEYVALUE_ACTOR);
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KEYVALUE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KEYVALUE_ACTOR;
}
TKeyValueFlat(const TActorId &tablet, TTabletStorageInfo *info)
@@ -440,7 +440,7 @@ public:
if (CollectorActorId) {
ctx.Send(CollectorActorId, new TEvents::TEvPoisonPill);
}
- State.Terminate(ctx);
+ State.Terminate(ctx);
Die(ctx);
}
@@ -482,7 +482,7 @@ public:
HFunc(TEvKeyValue::TEvIntermediate, Handle);
HFunc(TEvKeyValue::TEvNotify, Handle);
HFunc(TEvKeyValue::TEvPeriodicRefresh, Handle);
- HFunc(TChannelBalancer::TEvUpdateWeights, Handle);
+ HFunc(TChannelBalancer::TEvUpdateWeights, Handle);
HFunc(TEvBlobStorage::TEvCollectGarbageResult, Handle);
HFunc(TEvents::TEvPoisonPill, Handle);
diff --git a/ydb/core/keyvalue/keyvalue_intermediate.cpp b/ydb/core/keyvalue/keyvalue_intermediate.cpp
index 82a78d9fa29..4b07aa6d0a7 100644
--- a/ydb/core/keyvalue/keyvalue_intermediate.cpp
+++ b/ydb/core/keyvalue/keyvalue_intermediate.cpp
@@ -10,12 +10,12 @@ TIntermediate::TRead::TRead()
, Size(0)
, ValueSize(0)
, CreationUnixTime(0)
- , StorageChannel(NKikimrClient::TKeyValueRequest::MAIN)
+ , StorageChannel(NKikimrClient::TKeyValueRequest::MAIN)
, Status(NKikimrProto::UNKNOWN)
{}
TIntermediate::TRead::TRead(const TString &key, ui32 valueSize, ui64 creationUnixTime,
- NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel)
+ NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel)
: Key(key)
, Offset(0)
, Size(valueSize)
diff --git a/ydb/core/keyvalue/keyvalue_intermediate.h b/ydb/core/keyvalue/keyvalue_intermediate.h
index c28c14b9c37..3b993de3bde 100644
--- a/ydb/core/keyvalue/keyvalue_intermediate.h
+++ b/ydb/core/keyvalue/keyvalue_intermediate.h
@@ -40,14 +40,14 @@ struct TIntermediate {
ui32 ValueSize;
ui32 RequestedSize = 0;
ui64 CreationUnixTime;
- NKikimrClient::TKeyValueRequest::EStorageChannel StorageChannel;
+ NKikimrClient::TKeyValueRequest::EStorageChannel StorageChannel;
NKikimrBlobStorage::EGetHandleClass HandleClass;
NKikimrProto::EReplyStatus Status;
TString Message;
TRead();
TRead(const TString &key, ui32 valueSize, ui64 creationUnixTime,
- NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel);
+ NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel);
NKikimrProto::EReplyStatus ItemsStatus() const;
NKikimrProto::EReplyStatus CumulativeStatus() const;
};
@@ -66,7 +66,7 @@ struct TIntermediate {
NKikimrBlobStorage::EPutHandleClass HandleClass;
NKikimrProto::EReplyStatus Status;
TStorageStatusFlags StatusFlags;
- TDuration Latency;
+ TDuration Latency;
};
struct TDelete {
TKeyRange Range;
@@ -86,16 +86,16 @@ struct TIntermediate {
bool KeepInputs;
};
struct TGetStatus {
- NKikimrClient::TKeyValueRequest::EStorageChannel StorageChannel;
+ NKikimrClient::TKeyValueRequest::EStorageChannel StorageChannel;
TLogoBlobID LogoBlobId;
NKikimrProto::EReplyStatus Status;
TStorageStatusFlags StatusFlags;
};
- struct TTrimLeakedBlobs {
- ui32 MaxItemsToTrim;
+ struct TTrimLeakedBlobs {
+ ui32 MaxItemsToTrim;
TMultiMap<ui32, ui32> ChannelGroupMap;
TVector<TLogoBlobID> FoundBlobs;
- };
+ };
struct TSetExecutorFastLogPolicy {
bool IsAllowed;
};
@@ -111,7 +111,7 @@ struct TIntermediate {
TDeque<TCopyRange> CopyRanges;
TDeque<TConcat> Concats;
TDeque<TGetStatus> GetStatuses;
- TMaybe<TTrimLeakedBlobs> TrimLeakedBlobs;
+ TMaybe<TTrimLeakedBlobs> TrimLeakedBlobs;
TMaybe<TSetExecutorFastLogPolicy> SetExecutorFastLogPolicy;
TStackVec<TCmd, 1> Commands;
@@ -149,7 +149,7 @@ struct TIntermediate {
TRequestStat Stat;
- NKikimrClient::TResponse Response;
+ NKikimrClient::TResponse Response;
NKikimrKeyValue::ExecuteTransactionResult ExecuteTransactionResponse;
NKikimrKeyValue::GetStatusResult GetStatusResponse;
diff --git a/ydb/core/keyvalue/keyvalue_state.cpp b/ydb/core/keyvalue/keyvalue_state.cpp
index 6b31c463f83..0414f294c4f 100644
--- a/ydb/core/keyvalue/keyvalue_state.cpp
+++ b/ydb/core/keyvalue/keyvalue_state.cpp
@@ -80,14 +80,14 @@ void TKeyValueState::Clear() {
NextLogoBlobStep = 1;
NextLogoBlobCookie = 1;
Index.clear();
- RefCounts.clear();
+ RefCounts.clear();
Trash.clear();
InFlightForStep.clear();
CollectOperation.Reset(nullptr);
IsCollectEventSent = false;
IsSpringCleanupDone = false;
- ChannelDataUsage.fill(0);
- UsedChannels.reset();
+ ChannelDataUsage.fill(0);
+ UsedChannels.reset();
TabletId = 0;
KeyValueActorId = TActorId();
@@ -219,8 +219,8 @@ void TKeyValueState::CountRequestComplete(NMsgBusProxy::EResponseStatus status,
TabletCounters->Cumulative()[COUNTER_CMD_RENAME_OK].Increment(stat.Renames);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_BYTES_OK].Increment(stat.WriteBytes);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_OK].Increment(stat.Writes);
- TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_OK].Increment(stat.CopyRanges);
- TabletCounters->Cumulative()[COUNTER_CMD_GUM_OK].Increment(stat.Concats);
+ TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_OK].Increment(stat.CopyRanges);
+ TabletCounters->Cumulative()[COUNTER_CMD_GUM_OK].Increment(stat.Concats);
} else if (status == NMsgBusProxy::MSTATUS_TIMEOUT) {
TabletCounters->Cumulative()[COUNTER_CMD_READ_BYTES_TIMEOUT].Increment(stat.ReadBytes);
TabletCounters->Cumulative()[COUNTER_CMD_READ_TIMEOUT].Increment(stat.Reads);
@@ -232,8 +232,8 @@ void TKeyValueState::CountRequestComplete(NMsgBusProxy::EResponseStatus status,
TabletCounters->Cumulative()[COUNTER_CMD_RENAME_TIMEOUT].Increment(stat.Renames);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_BYTES_TIMEOUT].Increment(stat.WriteBytes);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_TIMEOUT].Increment(stat.Writes);
- TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_TIMEOUT].Increment(stat.CopyRanges);
- TabletCounters->Cumulative()[COUNTER_CMD_GUM_TIMEOUT].Increment(stat.Concats);
+ TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_TIMEOUT].Increment(stat.CopyRanges);
+ TabletCounters->Cumulative()[COUNTER_CMD_GUM_TIMEOUT].Increment(stat.Concats);
} else {
TabletCounters->Cumulative()[COUNTER_CMD_READ_BYTES_OTHER_ERROR].Increment(stat.ReadBytes);
TabletCounters->Cumulative()[COUNTER_CMD_READ_OTHER_ERROR].Increment(stat.Reads);
@@ -245,8 +245,8 @@ void TKeyValueState::CountRequestComplete(NMsgBusProxy::EResponseStatus status,
TabletCounters->Cumulative()[COUNTER_CMD_RENAME_OTHER_ERROR].Increment(stat.Renames);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_BYTES_OTHER_ERROR].Increment(stat.WriteBytes);
TabletCounters->Cumulative()[COUNTER_CMD_WRITE_OTHER_ERROR].Increment(stat.Writes);
- TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_OTHER_ERROR].Increment(stat.CopyRanges);
- TabletCounters->Cumulative()[COUNTER_CMD_GUM_OTHER_ERROR].Increment(stat.Concats);
+ TabletCounters->Cumulative()[COUNTER_CMD_COPY_RANGE_OTHER_ERROR].Increment(stat.CopyRanges);
+ TabletCounters->Cumulative()[COUNTER_CMD_GUM_OTHER_ERROR].Increment(stat.Concats);
}
for (const auto latency: stat.GetLatencies) {
@@ -292,7 +292,7 @@ void TKeyValueState::CountRequestIncoming(TRequestType::EType requestType) {
}
}
-void TKeyValueState::CountTrashRecord(ui32 sizeBytes) {
+void TKeyValueState::CountTrashRecord(ui32 sizeBytes) {
TabletCounters->Simple()[COUNTER_TRASH_COUNT].Add((ui64)1);
TabletCounters->Simple()[COUNTER_TRASH_BYTES].Add((ui64)sizeBytes);
TabletCounters->Simple()[COUNTER_RECORD_COUNT].Add((ui64)-1);
@@ -300,12 +300,12 @@ void TKeyValueState::CountTrashRecord(ui32 sizeBytes) {
ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
}
-void TKeyValueState::CountWriteRecord(ui8 channel, ui32 sizeBytes) {
+void TKeyValueState::CountWriteRecord(ui8 channel, ui32 sizeBytes) {
TabletCounters->Simple()[COUNTER_RECORD_COUNT].Add(1);
TabletCounters->Simple()[COUNTER_RECORD_BYTES].Add(sizeBytes);
ResourceMetrics->StorageUser.Set(TabletCounters->Simple()[COUNTER_RECORD_BYTES].Get());
- Y_VERIFY(channel < ChannelDataUsage.size());
- ChannelDataUsage[channel] += sizeBytes;
+ Y_VERIFY(channel < ChannelDataUsage.size());
+ ChannelDataUsage[channel] += sizeBytes;
}
void TKeyValueState::CountInitialTrashRecord(ui32 sizeBytes) {
@@ -374,11 +374,11 @@ void TKeyValueState::CountOnline() {
// Initialization
//
-void TKeyValueState::Terminate(const TActorContext& ctx) {
- ctx.Send(ChannelBalancerActorId, new TEvents::TEvPoisonPill);
-}
-
-void TKeyValueState::Load(const TString &key, const TString& value) {
+void TKeyValueState::Terminate(const TActorContext& ctx) {
+ ctx.Send(ChannelBalancerActorId, new TEvents::TEvPoisonPill);
+}
+
+void TKeyValueState::Load(const TString &key, const TString& value) {
if (IsEmptyDbStart) {
IsEmptyDbStart = false;
}
@@ -417,7 +417,7 @@ void TKeyValueState::Load(const TString &key, const TString& value) {
Y_VERIFY(false, "%s", str.Str().data());
}
}
- for (const TIndexRecord::TChainItem& item : record.Chain) {
+ for (const TIndexRecord::TChainItem& item : record.Chain) {
if (!item.IsInline()) {
const ui32 newRefCount = ++RefCounts[item.LogoBlobId];
if (newRefCount == 1) {
@@ -425,8 +425,8 @@ void TKeyValueState::Load(const TString &key, const TString& value) {
}
} else {
CountWriteRecord(0, item.InlineData.size());
- }
- }
+ }
+ }
break;
}
case EIT_TRASH: {
@@ -490,83 +490,83 @@ void TKeyValueState::InitExecute(ui64 tabletId, TActorId keyValueActorId, ui32 e
if (IsDamaged) {
return;
}
- ui8 maxChannel = 0;
- for (const auto& channel : info->Channels) {
- const ui32 index = channel.Channel;
- Y_VERIFY(index <= UsedChannels.size());
- if (index == 0 || index >= 2) {
- UsedChannels[index] = true;
- maxChannel = Max<ui8>(maxChannel, index);
- }
- }
- ChannelBalancerActorId = ctx.Register(new TChannelBalancer(maxChannel + 1, KeyValueActorId));
-
- // Issue hard barriers
- {
- using TGroupChannel = std::tuple<ui32, ui8>;
+ ui8 maxChannel = 0;
+ for (const auto& channel : info->Channels) {
+ const ui32 index = channel.Channel;
+ Y_VERIFY(index <= UsedChannels.size());
+ if (index == 0 || index >= 2) {
+ UsedChannels[index] = true;
+ maxChannel = Max<ui8>(maxChannel, index);
+ }
+ }
+ ChannelBalancerActorId = ctx.Register(new TChannelBalancer(maxChannel + 1, KeyValueActorId));
+
+ // Issue hard barriers
+ {
+ using TGroupChannel = std::tuple<ui32, ui8>;
THashMap<TGroupChannel, THelpers::TGenerationStep> hardBarriers;
- for (const auto &kv : RefCounts) {
- // extract blob id and validate its channel
- const TLogoBlobID &id = kv.first;
- const ui8 channel = id.Channel();
- Y_VERIFY(channel >= BLOB_CHANNEL);
-
- // create (generation, step) pair for current item and decrement it by one step as the barriers
- // are always inclusive
- const ui32 generation = id.Generation();
- const ui32 step = id.Step();
+ for (const auto &kv : RefCounts) {
+ // extract blob id and validate its channel
+ const TLogoBlobID &id = kv.first;
+ const ui8 channel = id.Channel();
+ Y_VERIFY(channel >= BLOB_CHANNEL);
+
+ // create (generation, step) pair for current item and decrement it by one step as the barriers
+ // are always inclusive
+ const ui32 generation = id.Generation();
+ const ui32 step = id.Step();
TMaybe<THelpers::TGenerationStep> current;
- if (step) {
+ if (step) {
current = THelpers::TGenerationStep(generation, step - 1);
- } else if (generation) {
+ } else if (generation) {
current = THelpers::TGenerationStep(generation - 1, Max<ui32>());
- }
-
- // update minimum barrier value for this channel/group
- if (current) {
- const ui32 group = info->GroupFor(channel, generation);
- if (group != Max<ui32>()) {
- const TGroupChannel key(group, channel);
- auto it = hardBarriers.find(key);
- if (it == hardBarriers.end()) {
- hardBarriers.emplace(key, *current);
- } else if (*current < it->second) {
- it->second = *current;
- }
- }
- }
- }
- for (const auto &channel : info->Channels) {
- if (channel.Channel < BLOB_CHANNEL) {
- continue;
- }
- for (const auto &history : channel.History) {
- const TGroupChannel key(history.GroupID, channel.Channel);
- if (!hardBarriers.count(key)) {
+ }
+
+ // update minimum barrier value for this channel/group
+ if (current) {
+ const ui32 group = info->GroupFor(channel, generation);
+ if (group != Max<ui32>()) {
+ const TGroupChannel key(group, channel);
+ auto it = hardBarriers.find(key);
+ if (it == hardBarriers.end()) {
+ hardBarriers.emplace(key, *current);
+ } else if (*current < it->second) {
+ it->second = *current;
+ }
+ }
+ }
+ }
+ for (const auto &channel : info->Channels) {
+ if (channel.Channel < BLOB_CHANNEL) {
+ continue;
+ }
+ for (const auto &history : channel.History) {
+ const TGroupChannel key(history.GroupID, channel.Channel);
+ if (!hardBarriers.count(key)) {
hardBarriers.emplace(key, THelpers::TGenerationStep(executorGeneration - 1, Max<ui32>()));
- }
- }
- }
- for (const auto &kv : hardBarriers) {
- ui32 group;
- ui8 channel;
- std::tie(group, channel) = kv.first;
-
- ui32 generation;
- ui32 step;
- std::tie(generation, step) = kv.second;
-
- auto ev = TEvBlobStorage::TEvCollectGarbage::CreateHardBarrier(info->TabletID, executorGeneration,
+ }
+ }
+ }
+ for (const auto &kv : hardBarriers) {
+ ui32 group;
+ ui8 channel;
+ std::tie(group, channel) = kv.first;
+
+ ui32 generation;
+ ui32 step;
+ std::tie(generation, step) = kv.second;
+
+ auto ev = TEvBlobStorage::TEvCollectGarbage::CreateHardBarrier(info->TabletID, executorGeneration,
PerGenerationCounter, channel, generation, step, TInstant::Max());
++PerGenerationCounter;
-
+
const TActorId nodeWarden = MakeBlobStorageNodeWardenID(ctx.SelfID.NodeId());
const TActorId proxy = MakeBlobStorageProxyID(group);
ctx.ExecutorThread.Send(new IEventHandle(proxy, TActorId(), ev.Release(),
- IEventHandle::FlagForwardOnNondelivery, 0, &nodeWarden));
- }
- }
-
+ IEventHandle::FlagForwardOnNondelivery, 0, &nodeWarden));
+ }
+ }
+
// Issue soft barriers
// Mark fresh blobs (after previous collected GenStep) with keep flag and issue barrier at current GenStep
// to remove all phantom blobs
@@ -795,7 +795,7 @@ void TKeyValueState::RequestExecute(THolder<TIntermediate> &intermediate, ISimpl
str << "KeyValue# " << TabletId;
str << " Generation mismatch! Requested# " << intermediate->Generation;
str << " Actual# " << StoredState.GetUserGeneration();
- str << " Marker# KV17";
+ str << " Marker# KV17";
LOG_INFO_S(ctx, NKikimrServices::KEYVALUE, str.Str());
// All reads done
intermediate->Response.SetStatus(NMsgBusProxy::MSTATUS_REJECTED);
@@ -826,7 +826,7 @@ void TKeyValueState::RequestExecute(THolder<TIntermediate> &intermediate, ISimpl
str << " Renames# " << intermediate->Renames.size();
str << " Writes# " << intermediate->Writes.size();
str << " GetStatuses# " << intermediate->GetStatuses.size();
- str << " CopyRanges# " << intermediate->CopyRanges.size();
+ str << " CopyRanges# " << intermediate->CopyRanges.size();
LOG_INFO_S(ctx, NKikimrServices::KEYVALUE, str.Str());
// All reads done
intermediate->Response.SetStatus(NMsgBusProxy::MSTATUS_INTERNALERROR);
@@ -1125,7 +1125,7 @@ void TKeyValueState::ProcessCmd(const TIntermediate::TCopyRange &request,
++RefCounts[item.LogoBlobId];
}
}
-
+
TString newKey = request.PrefixToAdd + it->first.substr(request.PrefixToRemove.size());
TIndexRecord& record = Index[newKey];
Dereference(record, db, ctx);
@@ -1175,7 +1175,7 @@ void TKeyValueState::ProcessCmd(const TIntermediate::TConcat &request,
record.Chain = std::move(chain);
record.CreationUnixTime = unixTime;
UpdateKeyValue(request.OutputKey, record, db, ctx);
-
+
if (legacyResponse) {
legacyResponse->SetStatus(NKikimrProto::OK);
}
@@ -1220,7 +1220,7 @@ void TKeyValueState::CmdRename(THolder<TIntermediate> &intermediate, ISimpleDb &
void TKeyValueState::CmdDelete(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx) {
for (ui32 i = 0; i < intermediate->Deletes.size(); ++i) {
- auto& request = intermediate->Deletes[i];
+ auto& request = intermediate->Deletes[i];
auto *response = intermediate->Response.AddDeleteRangeResult();
ProcessCmd(request, response, nullptr, db, ctx, intermediate->Stat, 0);
}
@@ -1229,7 +1229,7 @@ void TKeyValueState::CmdDelete(THolder<TIntermediate> &intermediate, ISimpleDb &
void TKeyValueState::CmdWrite(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx) {
ui64 unixTime = TAppData::TimeProvider->Now().Seconds();
for (ui32 i = 0; i < intermediate->Writes.size(); ++i) {
- auto& request = intermediate->Writes[i];
+ auto& request = intermediate->Writes[i];
auto *response = intermediate->Response.AddWriteResult();
ProcessCmd(request, response, nullptr, db, ctx, intermediate->Stat, unixTime);
}
@@ -1270,48 +1270,48 @@ void TKeyValueState::CmdGetStatus(THolder<TIntermediate> &intermediate, ISimpleD
intermediate->GetStatusResponse.set_status(NKikimrKeyValue::Statuses::RSTATUS_OK);
}
-void TKeyValueState::CmdCopyRange(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
- for (const auto& request : intermediate->CopyRanges) {
+void TKeyValueState::CmdCopyRange(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
+ for (const auto& request : intermediate->CopyRanges) {
auto *response = intermediate->Response.AddCopyRangeResult();
ProcessCmd(request, response, nullptr, db, ctx, intermediate->Stat, 0);
- }
-}
-
-void TKeyValueState::CmdConcat(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
+ }
+}
+
+void TKeyValueState::CmdConcat(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
ui64 unixTime = TAppData::TimeProvider->Now().Seconds();
- for (const auto& request : intermediate->Concats) {
+ for (const auto& request : intermediate->Concats) {
auto *response = intermediate->Response.AddConcatResult();
ProcessCmd(request, response, nullptr, db, ctx, intermediate->Stat, unixTime);
- }
-}
-
-void TKeyValueState::CmdTrimLeakedBlobs(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
- if (intermediate->TrimLeakedBlobs) {
- auto& response = *intermediate->Response.MutableTrimLeakedBlobsResult();
- response.SetStatus(NKikimrProto::OK);
- ui32 numItems = 0;
- ui32 numUntrimmed = 0;
- for (const TLogoBlobID& id : intermediate->TrimLeakedBlobs->FoundBlobs) {
- auto it = RefCounts.find(id);
- if (it != RefCounts.end()) {
- Y_VERIFY(it->second != 0);
- } else if (!Trash.count(id)) { // we found a candidate for trash
- if (numItems < intermediate->TrimLeakedBlobs->MaxItemsToTrim) {
- LOG_WARN_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId << " trimming " << id.ToString());
- Trash.insert(id);
+ }
+}
+
+void TKeyValueState::CmdTrimLeakedBlobs(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx) {
+ if (intermediate->TrimLeakedBlobs) {
+ auto& response = *intermediate->Response.MutableTrimLeakedBlobsResult();
+ response.SetStatus(NKikimrProto::OK);
+ ui32 numItems = 0;
+ ui32 numUntrimmed = 0;
+ for (const TLogoBlobID& id : intermediate->TrimLeakedBlobs->FoundBlobs) {
+ auto it = RefCounts.find(id);
+ if (it != RefCounts.end()) {
+ Y_VERIFY(it->second != 0);
+ } else if (!Trash.count(id)) { // we found a candidate for trash
+ if (numItems < intermediate->TrimLeakedBlobs->MaxItemsToTrim) {
+ LOG_WARN_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId << " trimming " << id.ToString());
+ Trash.insert(id);
CountTrashRecord(id.BlobSize());
- THelpers::DbUpdateTrash(id, db, ctx);
- ++numItems;
- } else {
- ++numUntrimmed;
- }
- }
- }
- response.SetNumItemsTrimmed(numItems);
- response.SetNumItemsLeft(numUntrimmed);
- }
-}
-
+ THelpers::DbUpdateTrash(id, db, ctx);
+ ++numItems;
+ } else {
+ ++numUntrimmed;
+ }
+ }
+ }
+ response.SetNumItemsTrimmed(numItems);
+ response.SetNumItemsLeft(numUntrimmed);
+ }
+}
+
void TKeyValueState::CmdSetExecutorFastLogPolicy(THolder<TIntermediate> &intermediate, ISimpleDb &/*db*/,
const TActorContext &/*ctx*/) {
if (intermediate->SetExecutorFastLogPolicy) {
@@ -1351,7 +1351,7 @@ void TKeyValueState::CmdCmds(THolder<TIntermediate> &intermediate, ISimpleDb &db
if constexpr (std::is_same_v<Type, TIntermediate::TWrite>) {
wasWrite = true;
return intermediate->Response.AddWriteResult();
- }
+ }
if constexpr (std::is_same_v<Type, TIntermediate::TDelete>) {
return intermediate->Response.AddDeleteRangeResult();
}
@@ -1370,7 +1370,7 @@ void TKeyValueState::CmdCmds(THolder<TIntermediate> &intermediate, ISimpleDb &db
};
for (auto &cmd : intermediate->Commands) {
std::visit(process, cmd);
- }
+ }
if (wasWrite) {
ResourceMetrics->TryUpdate(ctx);
}
@@ -1448,56 +1448,56 @@ bool TKeyValueState::CheckCmdCopyRanges(THolder<TIntermediate>& intermediate, co
for (const auto& cmd : intermediate->CopyRanges) {
CheckCmd(cmd, keys, 0);
}
- return true;
-}
-
+ return true;
+}
+
bool TKeyValueState::CheckCmdRenames(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
const TTabletStorageInfo *info)
{
- ui32 index = 0;
- for (const auto& cmd : intermediate->Renames) {
+ ui32 index = 0;
+ for (const auto& cmd : intermediate->Renames) {
const auto &[ok, msg] = CheckCmd(cmd, keys, index++);
if (!ok) {
ReplyError(ctx, msg, NMsgBusProxy::MSTATUS_ERROR, intermediate, info);
- return false;
- }
- }
- return true;
-}
-
+ return false;
+ }
+ }
+ return true;
+}
+
bool TKeyValueState::CheckCmdConcats(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
const TTabletStorageInfo *info)
{
- ui32 index = 0;
- for (const auto& cmd : intermediate->Concats) {
+ ui32 index = 0;
+ for (const auto& cmd : intermediate->Concats) {
const auto &[ok, msg] = CheckCmd(cmd, keys, index++);
if (!ok) {
ReplyError(ctx, msg, NMsgBusProxy::MSTATUS_ERROR, intermediate, info);
return false;
- }
- }
-
- return true;
-}
-
+ }
+ }
+
+ return true;
+}
+
bool TKeyValueState::CheckCmdDeletes(THolder<TIntermediate>& intermediate, const TActorContext& /*ctx*/, TKeySet& keys,
const TTabletStorageInfo* /*info*/)
{
- for (const auto& cmd : intermediate->Deletes) {
+ for (const auto& cmd : intermediate->Deletes) {
CheckCmd(cmd, keys, 0);
- }
- return true;
-}
-
+ }
+ return true;
+}
+
bool TKeyValueState::CheckCmdWrites(THolder<TIntermediate>& intermediate, const TActorContext& /*ctx*/, TKeySet& keys,
const TTabletStorageInfo* /*info*/)
{
- for (const auto& cmd : intermediate->Writes) {
+ for (const auto& cmd : intermediate->Writes) {
CheckCmd(cmd, keys, 0);
- }
- return true;
-}
-
+ }
+ return true;
+}
+
bool TKeyValueState::CheckCmdGetStatus(THolder<TIntermediate>& /*intermediate*/, const TActorContext& /*ctx*/,
TKeySet& /*keys*/, const TTabletStorageInfo* /*info*/)
{
@@ -1538,19 +1538,19 @@ void TKeyValueState::ProcessCmds(THolder<TIntermediate> &intermediate, ISimpleDb
const TTabletStorageInfo *info) {
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId << " TTxRequest ProcessCmds");
- TKeySet keys(Index);
-
- bool success = true;
+ TKeySet keys(Index);
+ bool success = true;
+
if (intermediate->HasGeneration && intermediate->Generation != StoredState.GetUserGeneration()) {
- TStringStream str;
- str << "KeyValue# " << TabletId
- << " Generation changed during command execution, aborted"
- << " Marker# KV04";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_REJECTED, intermediate, info);
- success = false;
- }
-
+ TStringStream str;
+ str << "KeyValue# " << TabletId
+ << " Generation changed during command execution, aborted"
+ << " Marker# KV04";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_REJECTED, intermediate, info);
+ success = false;
+ }
+
success = success && CheckCmdCopyRanges(intermediate, ctx, keys, info);
success = success && CheckCmdRenames(intermediate, ctx, keys, info);
success = success && CheckCmdConcats(intermediate, ctx, keys, info);
@@ -1558,12 +1558,12 @@ void TKeyValueState::ProcessCmds(THolder<TIntermediate> &intermediate, ISimpleDb
success = success && CheckCmdWrites(intermediate, ctx, keys, info);
success = success && CheckCmds(intermediate, ctx, keys, info);
success = success && CheckCmdGetStatus(intermediate, ctx, keys, info);
- if (!success) {
- for (const auto& cmd : intermediate->Writes) {
- for (const TLogoBlobID& logoBlobId : cmd.LogoBlobIds) {
- Dereference(logoBlobId, db, ctx, true);
- }
- }
+ if (!success) {
+ for (const auto& cmd : intermediate->Writes) {
+ for (const TLogoBlobID& logoBlobId : cmd.LogoBlobIds) {
+ Dereference(logoBlobId, db, ctx, true);
+ }
+ }
for (const auto& cmd : intermediate->Commands) {
if (!std::holds_alternative<TIntermediate::TWrite>(cmd)) {
continue;
@@ -1573,26 +1573,26 @@ void TKeyValueState::ProcessCmds(THolder<TIntermediate> &intermediate, ISimpleDb
Dereference(logoBlobId, db, ctx, true);
}
}
- } else {
- // Read + validate
- CmdRead(intermediate, db, ctx);
- CmdReadRange(intermediate, db, ctx);
- CmdCopyRange(intermediate, db, ctx);
- CmdRename(intermediate, db, ctx);
-
- // All reads done
- CmdConcat(intermediate, db, ctx);
- CmdDelete(intermediate, db, ctx);
- CmdWrite(intermediate, db, ctx);
+ } else {
+ // Read + validate
+ CmdRead(intermediate, db, ctx);
+ CmdReadRange(intermediate, db, ctx);
+ CmdCopyRange(intermediate, db, ctx);
+ CmdRename(intermediate, db, ctx);
+
+ // All reads done
+ CmdConcat(intermediate, db, ctx);
+ CmdDelete(intermediate, db, ctx);
+ CmdWrite(intermediate, db, ctx);
CmdGetStatus(intermediate, db, ctx);
CmdCmds(intermediate, db, ctx);
-
- // Blob trimming
- CmdTrimLeakedBlobs(intermediate, db, ctx);
+
+ // Blob trimming
+ CmdTrimLeakedBlobs(intermediate, db, ctx);
CmdSetExecutorFastLogPolicy(intermediate, db, ctx);
- }
-
+ }
+
// Safe to change the internal state and prepare the response
intermediate->Response.SetStatus(NMsgBusProxy::MSTATUS_OK);
@@ -1618,39 +1618,39 @@ bool TKeyValueState::IncrementGeneration(THolder<TIntermediate> &intermediate, I
return true;
}
-void TKeyValueState::Dereference(const TIndexRecord& record, ISimpleDb& db, const TActorContext& ctx) {
- for (const TIndexRecord::TChainItem& item : record.Chain) {
+void TKeyValueState::Dereference(const TIndexRecord& record, ISimpleDb& db, const TActorContext& ctx) {
+ for (const TIndexRecord::TChainItem& item : record.Chain) {
if (!item.IsInline()) {
- Dereference(item.LogoBlobId, db, ctx, false);
- }
- }
-}
-
-void TKeyValueState::Dereference(const TLogoBlobID& id, ISimpleDb& db, const TActorContext& ctx, bool initial) {
- auto it = RefCounts.find(id);
- Y_VERIFY(it != RefCounts.end());
- --it->second;
- if (!it->second) {
- RefCounts.erase(it);
- Trash.insert(id);
- THelpers::DbUpdateTrash(id, db, ctx);
- if (initial) {
- CountInitialTrashRecord(id.BlobSize());
- } else {
- CountTrashRecord(id.BlobSize());
- }
- const ui8 channel = id.Channel();
- Y_VERIFY(channel < ChannelDataUsage.size());
- ChannelDataUsage[channel] -= id.BlobSize();
- }
-}
-
+ Dereference(item.LogoBlobId, db, ctx, false);
+ }
+ }
+}
+
+void TKeyValueState::Dereference(const TLogoBlobID& id, ISimpleDb& db, const TActorContext& ctx, bool initial) {
+ auto it = RefCounts.find(id);
+ Y_VERIFY(it != RefCounts.end());
+ --it->second;
+ if (!it->second) {
+ RefCounts.erase(it);
+ Trash.insert(id);
+ THelpers::DbUpdateTrash(id, db, ctx);
+ if (initial) {
+ CountInitialTrashRecord(id.BlobSize());
+ } else {
+ CountTrashRecord(id.BlobSize());
+ }
+ const ui8 channel = id.Channel();
+ Y_VERIFY(channel < ChannelDataUsage.size());
+ ChannelDataUsage[channel] -= id.BlobSize();
+ }
+}
+
void TKeyValueState::UpdateKeyValue(const TString& key, const TIndexRecord& record, ISimpleDb& db,
const TActorContext& ctx) {
TString value = record.Serialize();
- THelpers::DbUpdateUserKeyValue(key, value, db, ctx);
-}
-
+ THelpers::DbUpdateUserKeyValue(key, value, db, ctx);
+}
+
void TKeyValueState::OnPeriodicRefresh(const TActorContext &ctx) {
Y_UNUSED(ctx);
TInstant now = TAppData::TimeProvider->Now();
@@ -1662,10 +1662,10 @@ void TKeyValueState::OnPeriodicRefresh(const TActorContext &ctx) {
TabletCounters->Simple()[COUNTER_REQ_AGE_MS].Set(maxDuration.MilliSeconds());
}
-void TKeyValueState::OnUpdateWeights(TChannelBalancer::TEvUpdateWeights::TPtr ev) {
- WeightManager = std::move(ev->Get()->WeightManager);
-}
-
+void TKeyValueState::OnUpdateWeights(TChannelBalancer::TEvUpdateWeights::TPtr ev) {
+ WeightManager = std::move(ev->Get()->WeightManager);
+}
+
void TKeyValueState::OnRequestComplete(ui64 requestUid, ui64 generation, ui64 step, const TActorContext &ctx,
const TTabletStorageInfo *info, NMsgBusProxy::EResponseStatus status, const TRequestStat &stat) {
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId
@@ -1707,14 +1707,14 @@ void TKeyValueState::OnRequestComplete(ui64 requestUid, ui64 generation, ui64 st
if (it->second == 0) {
InFlightForStep.erase(it);
- // Initiate Garbage collection process if needed
+ // Initiate Garbage collection process if needed
StartCollectingIfPossible(ctx);
}
}
}
-bool TKeyValueState::CheckDeadline(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate) {
+bool TKeyValueState::CheckDeadline(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate) {
if (kvRequest.HasDeadlineInstantMs()) {
TInstant now = TAppData::TimeProvider->Now();
intermediate->Deadline = TInstant::MicroSeconds(kvRequest.GetDeadlineInstantMs() * 1000ull);
@@ -1725,15 +1725,15 @@ bool TKeyValueState::CheckDeadline(const TActorContext &ctx, NKikimrClient::TKey
str << " Deadline reached before processing the request!";
str << " DeadlineInstantMs# " << (ui64)kvRequest.GetDeadlineInstantMs();
str << " < Now# " << (ui64)now.MilliSeconds();
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_TIMEOUT, intermediate);
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_TIMEOUT, intermediate);
return true;
}
}
return false;
}
-bool TKeyValueState::CheckGeneration(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate) {
+bool TKeyValueState::CheckGeneration(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate) {
if (kvRequest.HasGeneration()) {
intermediate->HasGeneration = true;
intermediate->Generation = kvRequest.GetGeneration();
@@ -1742,8 +1742,8 @@ bool TKeyValueState::CheckGeneration(const TActorContext &ctx, NKikimrClient::TK
str << "KeyValue# " << TabletId;
str << " Generation mismatch! Requested# " << kvRequest.GetGeneration();
str << " Actual# " << StoredState.GetUserGeneration();
- str << " Marker# KV01";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_REJECTED, intermediate);
+ str << " Marker# KV01";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_REJECTED, intermediate);
return true;
}
} else {
@@ -1955,7 +1955,7 @@ bool PrepareOneReadFromRangeReadWithData(const TString &key, TIndexRecord &index
return false;
}
-bool TKeyValueState::PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+bool TKeyValueState::PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, bool &outIsInlineOnly) {
outIsInlineOnly = true;
intermediate->Reads.resize(kvRequest.CmdReadSize());
@@ -1966,8 +1966,8 @@ bool TKeyValueState::PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKe
if (!request.HasKey()) {
TStringStream str;
str << "KeyValue# " << TabletId;
- str << " Missing Key in CmdRead(" << (ui32)i << ") Marker# KV02";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ str << " Missing Key in CmdRead(" << (ui32)i << ") Marker# KV02";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
@@ -1978,8 +1978,8 @@ bool TKeyValueState::PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKe
priority = request.GetPriority();
}
- auto it = Index.find(request.GetKey());
- if (it == Index.end()) {
+ auto it = Index.find(request.GetKey());
+ if (it == Index.end()) {
response.Status = NKikimrProto::NODATA;
response.Message = "No such key Marker# KV48";
} else {
@@ -2046,7 +2046,7 @@ void ProcessOneCmdReadRange(TKeyValueState *self, const TKeyRange &range, ui64 c
}
}
-bool TKeyValueState::PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+bool TKeyValueState::PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, bool &inOutIsInlineOnly) {
intermediate->RangeReads.resize(kvRequest.CmdReadRangeSize());
for (ui32 i = 0; i < kvRequest.CmdReadRangeSize(); ++i) {
@@ -2056,13 +2056,13 @@ bool TKeyValueState::PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient
if (!request.HasRange()) {
TStringStream str;
str << "KeyValue# " << TabletId;
- str << " Missing Range in CmdReadRange(" << i << ") Marker# KV03";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ str << " Missing Range in CmdReadRange(" << i << ") Marker# KV03";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
-
- TKeyRange range;
- if (!ConvertRange(request.GetRange(), &range, ctx, intermediate, "CmdReadRange", i)) {
+
+ TKeyRange range;
+ if (!ConvertRange(request.GetRange(), &range, ctx, intermediate, "CmdReadRange", i)) {
return true;
}
@@ -2071,17 +2071,17 @@ bool TKeyValueState::PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient
ui8 priority = request.HasPriority() ? request.GetPriority() : Max<ui8>();
response.IncludeData = includeData;
response.LimitBytes = cmdLimitBytes;
-
+
ProcessOneCmdReadRange<NKikimrClient::TKeyValueRequest>(this, range, cmdLimitBytes, includeData, priority,
response, intermediate, &inOutIsInlineOnly);
}
return false;
}
-bool TKeyValueState::PrepareCmdRename(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate) {
+bool TKeyValueState::PrepareCmdRename(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate) {
for (ui32 i = 0; i < kvRequest.CmdRenameSize(); ++i) {
- auto& request = kvRequest.GetCmdRename(i);
+ auto& request = kvRequest.GetCmdRename(i);
intermediate->Commands.emplace_back(TIntermediate::TRename());
auto& interm = std::get<TIntermediate::TRename>(intermediate->Commands.back());
@@ -2089,28 +2089,28 @@ bool TKeyValueState::PrepareCmdRename(const TActorContext &ctx, NKikimrClient::T
TStringStream str;
str << "KeyValue# " << TabletId;
str << " Missing OldKey in CmdRename(" << i << ") Marker# KV06";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
if (!request.HasNewKey()) {
TStringStream str;
str << "KeyValue# " << TabletId;
- str << " Missing NewKey in CmdRename(" << i << ") Marker# KV07";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ str << " Missing NewKey in CmdRename(" << i << ") Marker# KV07";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
-
- interm.OldKey = request.GetOldKey();
- interm.NewKey = request.GetNewKey();
+
+ interm.OldKey = request.GetOldKey();
+ interm.NewKey = request.GetNewKey();
}
return false;
}
-bool TKeyValueState::PrepareCmdDelete(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate) {
+bool TKeyValueState::PrepareCmdDelete(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate) {
ui64 nToDelete = 0;
for (ui32 i = 0; i < kvRequest.CmdDeleteRangeSize(); ++i) {
- auto& request = kvRequest.GetCmdDeleteRange(i);
+ auto& request = kvRequest.GetCmdDeleteRange(i);
intermediate->Commands.emplace_back(TIntermediate::TDelete());
auto& interm = std::get<TIntermediate::TDelete>(intermediate->Commands.back());
@@ -2118,10 +2118,10 @@ bool TKeyValueState::PrepareCmdDelete(const TActorContext &ctx, NKikimrClient::T
TStringStream str;
str << "KeyValue# " << TabletId;
str << " Missing Range in CmdDelete(" << i << ") Marker# KV08";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
- if (!ConvertRange(request.GetRange(), &interm.Range, ctx, intermediate, "CmdDelete", i)) {
+ if (!ConvertRange(request.GetRange(), &interm.Range, ctx, intermediate, "CmdDelete", i)) {
return true;
}
TraverseRange(interm.Range, [&](TIndex::iterator it) {
@@ -2166,11 +2166,11 @@ void TKeyValueState::SplitIntoBlobs(TIntermediate::TWrite &cmd, bool isInline, u
}
}
-bool TKeyValueState::PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+bool TKeyValueState::PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, const TTabletStorageInfo *info) {
intermediate->WriteIndices.reserve(kvRequest.CmdWriteSize());
for (ui32 i = 0; i < kvRequest.CmdWriteSize(); ++i) {
- auto& request = kvRequest.GetCmdWrite(i);
+ auto& request = kvRequest.GetCmdWrite(i);
intermediate->WriteIndices.push_back(intermediate->Commands.size());
auto& cmd = intermediate->Commands.emplace_back(TIntermediate::TWrite());
auto& interm = std::get<TIntermediate::TWrite>(cmd);
@@ -2178,15 +2178,15 @@ bool TKeyValueState::PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TK
if (!request.HasKey()) {
TStringStream str;
str << "KeyValue# " << TabletId;
- str << " Missing Key in CmdWrite(" << i << ") Marker# KV09";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ str << " Missing Key in CmdWrite(" << i << ") Marker# KV09";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
if (!request.HasValue()) {
TStringStream str;
str << "KeyValue# " << TabletId;
- str << " Missing Value in CmdWrite(" << i << ") Marker# KV10";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ str << " Missing Value in CmdWrite(" << i << ") Marker# KV10";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
return true;
}
@@ -2195,7 +2195,7 @@ bool TKeyValueState::PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TK
if (request.HasStorageChannel()) {
auto storageChannel = request.GetStorageChannel();
ui32 storageChannelOffset = (ui32)storageChannel;
- if (storageChannelOffset == NKikimrClient::TKeyValueRequest::INLINE) {
+ if (storageChannelOffset == NKikimrClient::TKeyValueRequest::INLINE) {
isInline = true;
} else {
storageChannelIdx = storageChannelOffset + BLOB_CHANNEL;
@@ -2207,28 +2207,28 @@ bool TKeyValueState::PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TK
<< " does not exist, using MAIN");
}
}
- } else if (request.AutoselectChannelSize() && WeightManager) {
- std::bitset<256> enabled;
- for (const auto& channel : request.GetAutoselectChannel()) {
- if (channel != NKikimrClient::TKeyValueRequest::INLINE) {
- const ui32 index = channel + BLOB_CHANNEL;
- if (index < info->Channels.size()) {
- Y_VERIFY(index < enabled.size());
- enabled.set(index);
- }
- }
- }
- // TODO(alexvru): trim enabled channels by used space
- if (enabled.any()) {
- int index = WeightManager->Pick(enabled);
- if (index != -1) {
- storageChannelIdx = index;
- }
- }
- }
-
- interm.Key = request.GetKey();
- interm.Data = request.GetValue();
+ } else if (request.AutoselectChannelSize() && WeightManager) {
+ std::bitset<256> enabled;
+ for (const auto& channel : request.GetAutoselectChannel()) {
+ if (channel != NKikimrClient::TKeyValueRequest::INLINE) {
+ const ui32 index = channel + BLOB_CHANNEL;
+ if (index < info->Channels.size()) {
+ Y_VERIFY(index < enabled.size());
+ enabled.set(index);
+ }
+ }
+ }
+ // TODO(alexvru): trim enabled channels by used space
+ if (enabled.any()) {
+ int index = WeightManager->Pick(enabled);
+ if (index != -1) {
+ storageChannelIdx = index;
+ }
+ }
+ }
+
+ interm.Key = request.GetKey();
+ interm.Data = request.GetValue();
interm.Tactic = TEvBlobStorage::TEvPut::TacticDefault;
switch (request.GetTactic()) {
case NKikimrClient::TKeyValueRequest::MIN_LATENCY:
@@ -2288,15 +2288,15 @@ TKeyValueState::TPrepareResult TKeyValueState::InitGetStatusCommand(TIntermediat
return {false, msg};
}
-bool TKeyValueState::PrepareCmdGetStatus(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+bool TKeyValueState::PrepareCmdGetStatus(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, const TTabletStorageInfo *info) {
intermediate->GetStatuses.resize(kvRequest.CmdGetStatusSize());
for (ui32 i = 0; i < kvRequest.CmdGetStatusSize(); ++i) {
auto& request = kvRequest.GetCmdGetStatus(i);
auto& interm = intermediate->GetStatuses[i];
- NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel =
- NKikimrClient::TKeyValueRequest::MAIN;
+ NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel =
+ NKikimrClient::TKeyValueRequest::MAIN;
if (request.HasStorageChannel()) {
storageChannel = request.GetStorageChannel();
@@ -2310,73 +2310,73 @@ bool TKeyValueState::PrepareCmdGetStatus(const TActorContext &ctx, NKikimrClient
}
-bool TKeyValueState::PrepareCmdCopyRange(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
- THolder<TIntermediate>& intermediate) {
- for (ui32 i = 0; i < kvRequest.CmdCopyRangeSize(); ++i) {
- auto& request = kvRequest.GetCmdCopyRange(i);
+bool TKeyValueState::PrepareCmdCopyRange(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
+ THolder<TIntermediate>& intermediate) {
+ for (ui32 i = 0; i < kvRequest.CmdCopyRangeSize(); ++i) {
+ auto& request = kvRequest.GetCmdCopyRange(i);
intermediate->Commands.emplace_back(TIntermediate::TCopyRange());
auto& interm = std::get<TIntermediate::TCopyRange>(intermediate->Commands.back());
-
+
if ((!request.HasPrefixToAdd() || request.GetPrefixToAdd().empty()) &&
(!request.HasPrefixToRemove() || request.GetPrefixToRemove().empty())) {
- TStringStream str;
+ TStringStream str;
str << "KeyValue# " << TabletId
<< " Missing or empty both PrefixToAdd and PrefixToRemove in CmdCopyRange(" << i << ") Marker# KV11";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
- return true;
- }
- if (!request.HasRange()) {
- interm.Range = TKeyRange::WholeDatabase();
- } else if (!ConvertRange(request.GetRange(), &interm.Range, ctx, intermediate, "CmdCopyRange", i)) {
- return false;
- }
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ return true;
+ }
+ if (!request.HasRange()) {
+ interm.Range = TKeyRange::WholeDatabase();
+ } else if (!ConvertRange(request.GetRange(), &interm.Range, ctx, intermediate, "CmdCopyRange", i)) {
+ return false;
+ }
interm.PrefixToAdd = request.HasPrefixToAdd() ? request.GetPrefixToAdd() : TString();
interm.PrefixToRemove = request.HasPrefixToRemove() ? request.GetPrefixToRemove() : TString();
- }
- return false;
-}
-
-bool TKeyValueState::PrepareCmdConcat(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
- THolder<TIntermediate>& intermediate) {
- for (ui32 i = 0; i < kvRequest.CmdConcatSize(); ++i) {
- auto& request = kvRequest.GetCmdConcat(i);
+ }
+ return false;
+}
+
+bool TKeyValueState::PrepareCmdConcat(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
+ THolder<TIntermediate>& intermediate) {
+ for (ui32 i = 0; i < kvRequest.CmdConcatSize(); ++i) {
+ auto& request = kvRequest.GetCmdConcat(i);
intermediate->Commands.emplace_back(TIntermediate::TConcat());
auto& interm = std::get<TIntermediate::TConcat>(intermediate->Commands.back());
-
- if (!request.HasOutputKey()) {
- TStringStream str;
- str << "KeyValue# " << TabletId << " Missing OutputKey in CmdConcat(" << i << ") Marker# KV12";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
- return true;
- }
-
- const auto& inputKeys = request.GetInputKeys();
- interm.InputKeys = {inputKeys.begin(), inputKeys.end()};
- interm.OutputKey = request.GetOutputKey();
- interm.KeepInputs = request.HasKeepInputs() && request.GetKeepInputs();
- }
- return false;
-}
-
-bool TKeyValueState::PrepareCmdTrimLeakedBlobs(const TActorContext& /*ctx*/,
- NKikimrClient::TKeyValueRequest& kvRequest, THolder<TIntermediate>& intermediate,
- const TTabletStorageInfo *info) {
- if (kvRequest.HasCmdTrimLeakedBlobs()) {
- const auto& request = kvRequest.GetCmdTrimLeakedBlobs();
- TIntermediate::TTrimLeakedBlobs interm;
- interm.MaxItemsToTrim = request.GetMaxItemsToTrim();
- for (const auto& channel : info->Channels) {
- if (channel.Channel >= BLOB_CHANNEL) {
- for (const auto& history : channel.History) {
- interm.ChannelGroupMap.emplace(channel.Channel, history.GroupID);
- }
- }
- }
- intermediate->TrimLeakedBlobs = std::move(interm);
- }
- return false;
-}
-
+
+ if (!request.HasOutputKey()) {
+ TStringStream str;
+ str << "KeyValue# " << TabletId << " Missing OutputKey in CmdConcat(" << i << ") Marker# KV12";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_INTERNALERROR, intermediate);
+ return true;
+ }
+
+ const auto& inputKeys = request.GetInputKeys();
+ interm.InputKeys = {inputKeys.begin(), inputKeys.end()};
+ interm.OutputKey = request.GetOutputKey();
+ interm.KeepInputs = request.HasKeepInputs() && request.GetKeepInputs();
+ }
+ return false;
+}
+
+bool TKeyValueState::PrepareCmdTrimLeakedBlobs(const TActorContext& /*ctx*/,
+ NKikimrClient::TKeyValueRequest& kvRequest, THolder<TIntermediate>& intermediate,
+ const TTabletStorageInfo *info) {
+ if (kvRequest.HasCmdTrimLeakedBlobs()) {
+ const auto& request = kvRequest.GetCmdTrimLeakedBlobs();
+ TIntermediate::TTrimLeakedBlobs interm;
+ interm.MaxItemsToTrim = request.GetMaxItemsToTrim();
+ for (const auto& channel : info->Channels) {
+ if (channel.Channel >= BLOB_CHANNEL) {
+ for (const auto& history : channel.History) {
+ interm.ChannelGroupMap.emplace(channel.Channel, history.GroupID);
+ }
+ }
+ }
+ intermediate->TrimLeakedBlobs = std::move(interm);
+ }
+ return false;
+}
+
bool TKeyValueState::PrepareCmdSetExecutorFastLogPolicy(const TActorContext & /*ctx*/,
NKikimrClient::TKeyValueRequest &kvRequest, THolder<TIntermediate> &intermediate,
const TTabletStorageInfo * /*info*/) {
@@ -2534,10 +2534,10 @@ TPrepareResult TKeyValueState::PrepareCommands(NKikimrKeyValue::ExecuteTransacti
}
void TKeyValueState::ReplyError(const TActorContext &ctx, TString errorDescription,
- NMsgBusProxy::EResponseStatus status, THolder<TIntermediate> &intermediate,
- const TTabletStorageInfo *info) {
+ NMsgBusProxy::EResponseStatus status, THolder<TIntermediate> &intermediate,
+ const TTabletStorageInfo *info) {
LOG_INFO_S(ctx, NKikimrServices::KEYVALUE, errorDescription);
- Y_VERIFY(!intermediate->IsReplied);
+ Y_VERIFY(!intermediate->IsReplied);
THolder<TEvKeyValue::TEvResponse> response(new TEvKeyValue::TEvResponse);
if (intermediate->HasCookie) {
response->Record.SetCookie(intermediate->Cookie);
@@ -2549,14 +2549,14 @@ void TKeyValueState::ReplyError(const TActorContext &ctx, TString errorDescripti
intermediate->IsReplied = true;
ctx.Send(intermediate->RespondTo, response.Release());
- if (info) {
- intermediate->UpdateStat();
+ if (info) {
+ intermediate->UpdateStat();
OnRequestComplete(intermediate->RequestUid, intermediate->CreatedAtGeneration, intermediate->CreatedAtStep,
ctx, info, status, intermediate->Stat);
} else { //metrics change report in OnRequestComplete is not done
ResourceMetrics->TryUpdate(ctx);
RequestInputTime.erase(intermediate->RequestUid);
- }
+ }
}
bool TKeyValueState::PrepareReadRequest(const TActorContext &ctx, TEvKeyValue::TEvRead::TPtr &ev,
@@ -2985,16 +2985,16 @@ void TKeyValueState::OnEvIntermediate(TIntermediate &intermediate, const TActorC
void TKeyValueState::OnEvRequest(TEvKeyValue::TEvRequest::TPtr &ev, const TActorContext &ctx,
const TTabletStorageInfo *info) {
THolder<TIntermediate> intermediate;
- NKikimrClient::TKeyValueRequest &request = ev->Get()->Record;
+ NKikimrClient::TKeyValueRequest &request = ev->Get()->Record;
ResourceMetrics->Network.Increment(request.ByteSize());
ResourceMetrics->TryUpdate(ctx);
- bool hasWrites = request.CmdWriteSize() || request.CmdDeleteRangeSize() || request.CmdRenameSize()
+ bool hasWrites = request.CmdWriteSize() || request.CmdDeleteRangeSize() || request.CmdRenameSize()
|| request.CmdCopyRangeSize() || request.CmdConcatSize() || request.HasCmdSetExecutorFastLogPolicy();
-
+
bool hasReads = request.CmdReadSize() || request.CmdReadRangeSize();
-
+
TRequestType::EType requestType;
if (hasWrites) {
if (hasReads) {
@@ -3045,7 +3045,7 @@ void TKeyValueState::OnEvRequest(TEvKeyValue::TEvRequest::TPtr &ev, const TActor
bool TKeyValueState::PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THolder<TIntermediate> &intermediate,
TRequestType::EType &inOutRequestType, const TActorContext &ctx, const TTabletStorageInfo *info) {
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId << " PrepareIntermediate Marker# KV40");
- NKikimrClient::TKeyValueRequest &request = ev->Get()->Record;
+ NKikimrClient::TKeyValueRequest &request = ev->Get()->Record;
StoredState.SetChannelGeneration(ExecutorGeneration);
StoredState.SetChannelStep(NextLogoBlobStep - 1);
@@ -3063,16 +3063,16 @@ bool TKeyValueState::PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THol
}
intermediate->HasIncrementGeneration = request.HasCmdIncrementGeneration();
- if (CheckDeadline(ctx, request, intermediate)) {
+ if (CheckDeadline(ctx, request, intermediate)) {
return false;
}
- if (CheckGeneration(ctx, request, intermediate)) {
+ if (CheckGeneration(ctx, request, intermediate)) {
return false;
}
- bool error = false;
-
+ bool error = false;
+
bool isInlineOnly = true;
error = error || PrepareCmdRead(ctx, request, intermediate, isInlineOnly);
error = error || PrepareCmdReadRange(ctx, request, intermediate, isInlineOnly);
@@ -3080,35 +3080,35 @@ bool TKeyValueState::PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THol
inOutRequestType = TRequestType::ReadOnlyInline;
intermediate->Stat.RequestType = inOutRequestType;
}
-
+
ui32 cmdCount = request.CmdWriteSize() + request.CmdDeleteRangeSize() + request.CmdRenameSize()
+ request.CmdCopyRangeSize() + request.CmdConcatSize();
intermediate->Commands.reserve(cmdCount);
- error = error || PrepareCmdCopyRange(ctx, request, intermediate);
- error = error || PrepareCmdRename(ctx, request, intermediate);
- error = error || PrepareCmdConcat(ctx, request, intermediate);
- error = error || PrepareCmdDelete(ctx, request, intermediate);
+ error = error || PrepareCmdCopyRange(ctx, request, intermediate);
+ error = error || PrepareCmdRename(ctx, request, intermediate);
+ error = error || PrepareCmdConcat(ctx, request, intermediate);
+ error = error || PrepareCmdDelete(ctx, request, intermediate);
error = error || PrepareCmdWrite(ctx, request, intermediate, info);
error = error || PrepareCmdGetStatus(ctx, request, intermediate, info);
- error = error || PrepareCmdTrimLeakedBlobs(ctx, request, intermediate, info);
+ error = error || PrepareCmdTrimLeakedBlobs(ctx, request, intermediate, info);
error = error || PrepareCmdSetExecutorFastLogPolicy(ctx, request, intermediate, info);
-
+
intermediate->WriteCount = request.CmdWriteSize();
intermediate->DeleteCount = request.CmdDeleteRangeSize();
intermediate->RenameCount = request.CmdRenameSize();
intermediate->CopyRangeCount = request.CmdCopyRangeSize();
intermediate->ConcatCount = request.CmdConcatSize();
- if (error) {
- // discard allocated LogoBlobIds from the Write commands
- for (const auto &write : intermediate->Writes) {
- for (const TLogoBlobID &id : write.LogoBlobIds) {
- const ui32 count = RefCounts.erase(id);
- Y_VERIFY(count == 1);
- }
- }
-
+ if (error) {
+ // discard allocated LogoBlobIds from the Write commands
+ for (const auto &write : intermediate->Writes) {
+ for (const TLogoBlobID &id : write.LogoBlobIds) {
+ const ui32 count = RefCounts.erase(id);
+ Y_VERIFY(count == 1);
+ }
+ }
+
for (ui32 idx : intermediate->WriteIndices) {
const auto &cmd = intermediate->Commands[idx];
Y_VERIFY(std::holds_alternative<TIntermediate::TWrite>(cmd));
@@ -3121,63 +3121,63 @@ bool TKeyValueState::PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THol
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletId
<< " PrepareIntermediate return flase, Marker# KV41");
- return false;
- }
-
- return true;
-}
-
+ return false;
+ }
+
+ return true;
+}
+
void TKeyValueState::UpdateResourceMetrics(const TActorContext& ctx) {
ResourceMetrics->TryUpdate(ctx);
}
-bool TKeyValueState::ConvertRange(const NKikimrClient::TKeyValueRequest::TKeyRange& from, TKeyRange *to,
- const TActorContext& ctx, THolder<TIntermediate>& intermediate, const char *cmd,
- ui32 index) {
- to->HasFrom = from.HasFrom();
- if (to->HasFrom) {
- to->KeyFrom = from.GetFrom();
- to->IncludeFrom = from.HasIncludeFrom() && from.GetIncludeFrom();
- } else if (from.HasIncludeFrom()) {
- TStringStream str;
- str << "KeyValue# " << TabletId
- << " Range.IncludeFrom unexpectedly set without Range.From in " << cmd << "(" << index << ")"
- << " Marker# KV13";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
- return false;
- }
-
- to->HasTo = from.HasTo();
- if (to->HasTo) {
- to->KeyTo = from.GetTo();
- to->IncludeTo = from.HasIncludeTo() && from.GetIncludeTo();
- } else if (from.HasIncludeTo()) {
- TStringStream str;
- str << "KeyValue# " << TabletId
- << " Range.IncludeTo unexpectedly set without Range.To in " << cmd << "(" << index << ")"
- << " Marker# KV14";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
+bool TKeyValueState::ConvertRange(const NKikimrClient::TKeyValueRequest::TKeyRange& from, TKeyRange *to,
+ const TActorContext& ctx, THolder<TIntermediate>& intermediate, const char *cmd,
+ ui32 index) {
+ to->HasFrom = from.HasFrom();
+ if (to->HasFrom) {
+ to->KeyFrom = from.GetFrom();
+ to->IncludeFrom = from.HasIncludeFrom() && from.GetIncludeFrom();
+ } else if (from.HasIncludeFrom()) {
+ TStringStream str;
+ str << "KeyValue# " << TabletId
+ << " Range.IncludeFrom unexpectedly set without Range.From in " << cmd << "(" << index << ")"
+ << " Marker# KV13";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
+ return false;
+ }
+
+ to->HasTo = from.HasTo();
+ if (to->HasTo) {
+ to->KeyTo = from.GetTo();
+ to->IncludeTo = from.HasIncludeTo() && from.GetIncludeTo();
+ } else if (from.HasIncludeTo()) {
+ TStringStream str;
+ str << "KeyValue# " << TabletId
+ << " Range.IncludeTo unexpectedly set without Range.To in " << cmd << "(" << index << ")"
+ << " Marker# KV14";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
return false;
}
- if (to->HasFrom && to->HasTo) {
- if (!to->IncludeFrom && !to->IncludeTo && to->KeyFrom >= to->KeyTo) {
- TStringStream str;
- str << "KeyValue# " << TabletId
- << " Range.KeyFrom >= Range.KeyTo in " << cmd << "(" << index << ")"
- << " Marker# KV15";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
- return false;
- } else if (to->KeyFrom > to->KeyTo) {
- TStringStream str;
- str << "KeyValue# " << TabletId
- << " Range.KeyFrom > Range.KeyTo in " << cmd << "(" << index << ")"
- << " Marker# KV16";
- ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
- return false;
- }
- }
-
+ if (to->HasFrom && to->HasTo) {
+ if (!to->IncludeFrom && !to->IncludeTo && to->KeyFrom >= to->KeyTo) {
+ TStringStream str;
+ str << "KeyValue# " << TabletId
+ << " Range.KeyFrom >= Range.KeyTo in " << cmd << "(" << index << ")"
+ << " Marker# KV15";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
+ return false;
+ } else if (to->KeyFrom > to->KeyTo) {
+ TStringStream str;
+ str << "KeyValue# " << TabletId
+ << " Range.KeyFrom > Range.KeyTo in " << cmd << "(" << index << ")"
+ << " Marker# KV16";
+ ReplyError(ctx, str.Str(), NMsgBusProxy::MSTATUS_ERROR, intermediate);
+ return false;
+ }
+ }
+
return true;
}
@@ -3220,14 +3220,14 @@ void TKeyValueState::RenderHTMLPage(IOutputStream &out) const {
out << "<a href=\"#database\" data-toggle=\"tab\">Database</a>";
}
LI() {
- out << "<a href=\"#refcounts\" data-toggle=\"tab\">RefCounts</a>";
+ out << "<a href=\"#refcounts\" data-toggle=\"tab\">RefCounts</a>";
}
LI() {
out << "<a href=\"#trash\" data-toggle=\"tab\">Trash</a>";
}
- LI() {
- out << "<a href=\"#channelstat\" data-toggle=\"tab\">Channel Stat</a>";
- }
+ LI() {
+ out << "<a href=\"#channelstat\" data-toggle=\"tab\">Channel Stat</a>";
+ }
}
DIV_CLASS("tab-content") {
DIV_CLASS_ID("tab-pane fade in active", "database") {
@@ -3252,33 +3252,33 @@ void TKeyValueState::RenderHTMLPage(IOutputStream &out) const {
TABLED() {out << it->second.GetFullValueSize();}
TABLED() {out << it->second.CreationUnixTime;}
TABLED() {
- NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel =
- NKikimrClient::TKeyValueRequest::MAIN;
+ NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel =
+ NKikimrClient::TKeyValueRequest::MAIN;
if (it->second.Chain.size()) {
if (it->second.Chain[0].IsInline()) {
- storageChannel = NKikimrClient::TKeyValueRequest::INLINE;
+ storageChannel = NKikimrClient::TKeyValueRequest::INLINE;
} else {
ui32 storageChannelIdx = it->second.Chain[0].LogoBlobId.Channel();
ui32 storageChannelOffset = storageChannelIdx - BLOB_CHANNEL;
- storageChannel = (NKikimrClient::TKeyValueRequest::EStorageChannel)
+ storageChannel = (NKikimrClient::TKeyValueRequest::EStorageChannel)
storageChannelOffset;
}
}
- out << NKikimrClient::TKeyValueRequest::EStorageChannel_Name(
+ out << NKikimrClient::TKeyValueRequest::EStorageChannel_Name(
storageChannel);
}
-
+
TABLED() {
- for (ui32 i = 0; i < it->second.Chain.size(); ++i) {
- if (i > 0) {
- out << "<br/>";
- }
+ for (ui32 i = 0; i < it->second.Chain.size(); ++i) {
+ if (i > 0) {
+ out << "<br/>";
+ }
if (it->second.Chain[i].IsInline()) {
out << "[INLINE:" << it->second.Chain[i].InlineData.size() << "]";
} else {
out << it->second.Chain[i].LogoBlobId.ToString();
}
- }
+ }
}
}
}
@@ -3295,15 +3295,15 @@ void TKeyValueState::RenderHTMLPage(IOutputStream &out) const {
}
}
TABLEBODY() {
- ui32 idx = 1;
- for (const auto& kv : RefCounts) {
+ ui32 idx = 1;
+ for (const auto& kv : RefCounts) {
TABLER() {
TABLED() {out << idx;}
TABLED() {out << kv.first.ToString();}
TABLED() {out << kv.second;}
}
- ++idx;
- }
+ ++idx;
+ }
}
}
}
@@ -3327,52 +3327,52 @@ void TKeyValueState::RenderHTMLPage(IOutputStream &out) const {
}
}
}
- DIV_CLASS_ID("tab-pane fade", "channelstat") {
- TABLE_SORTABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {out << "Channel";}
- TABLEH() {out << "Total values size";}
- }
- }
- TABLEBODY() {
- for (size_t i = 0; i < ChannelDataUsage.size(); ++i) {
- if (UsedChannels[i]) {
- TABLER() {
- TABLED() {
- if (i) {
- out << i;
- } else {
- out << "inline";
- }
- }
- ui64 size = ChannelDataUsage[i];
- out << "<td title=" << size << ">";
- TString value;
- for (; size >= 1000; size /= 1000) {
- value = Sprintf(" %03" PRIu64, size % 1000) + value;
- }
- value = Sprintf("%" PRIu64, size) + value;
- out << value;
- out << "</td>";
- }
- }
- }
- }
- }
- }
-
- }
- }
-}
-
-void TKeyValueState::MonChannelStat(NJson::TJsonValue& out) const {
- for (size_t i = 0; i < ChannelDataUsage.size(); ++i) {
- if (UsedChannels[i]) {
- const TString key = i ? Sprintf("%zu", i) : "inline";
- out[key] = ChannelDataUsage[i];
- }
- }
+ DIV_CLASS_ID("tab-pane fade", "channelstat") {
+ TABLE_SORTABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() {out << "Channel";}
+ TABLEH() {out << "Total values size";}
+ }
+ }
+ TABLEBODY() {
+ for (size_t i = 0; i < ChannelDataUsage.size(); ++i) {
+ if (UsedChannels[i]) {
+ TABLER() {
+ TABLED() {
+ if (i) {
+ out << i;
+ } else {
+ out << "inline";
+ }
+ }
+ ui64 size = ChannelDataUsage[i];
+ out << "<td title=" << size << ">";
+ TString value;
+ for (; size >= 1000; size /= 1000) {
+ value = Sprintf(" %03" PRIu64, size % 1000) + value;
+ }
+ value = Sprintf("%" PRIu64, size) + value;
+ out << value;
+ out << "</td>";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+}
+
+void TKeyValueState::MonChannelStat(NJson::TJsonValue& out) const {
+ for (size_t i = 0; i < ChannelDataUsage.size(); ++i) {
+ if (UsedChannels[i]) {
+ const TString key = i ? Sprintf("%zu", i) : "inline";
+ out[key] = ChannelDataUsage[i];
+ }
+ }
}
} // NKeyValue
diff --git a/ydb/core/keyvalue/keyvalue_state.h b/ydb/core/keyvalue/keyvalue_state.h
index f57a69d35d3..80b9c1fe847 100644
--- a/ydb/core/keyvalue/keyvalue_state.h
+++ b/ydb/core/keyvalue/keyvalue_state.h
@@ -11,14 +11,14 @@
#include "keyvalue_item_type.h"
#include "keyvalue_stored_state_data.h"
#include "keyvalue_simple_db.h"
-#include "channel_balancer.h"
+#include "channel_balancer.h"
#include <util/generic/set.h>
#include <ydb/core/base/appdata.h>
#include <ydb/public/lib/base/msgbus.h>
#include <ydb/core/tablet/tablet_counters.h>
#include <ydb/core/tablet/tablet_metrics.h>
#include <ydb/core/keyvalue/protos/events.pb.h>
-#include <bitset>
+#include <bitset>
namespace NActors {
struct TActorContext;
@@ -55,183 +55,183 @@ class TKeyValueState {
}
};
-public:
+public:
using TIndex = TMap<TString, TIndexRecord>;
using TCommand = NKikimrKeyValue::ExecuteTransactionRequest::Command;
- class TIncrementalKeySet {
+ class TIncrementalKeySet {
TMap<TString, TIndexRecord>& Index;
TSet<TString> AddedKeys;
TSet<TString> DeletedKeys;
-
- class TIterator {
- TIncrementalKeySet& KeySet;
+
+ class TIterator {
+ TIncrementalKeySet& KeySet;
TMap<TString, TIndexRecord>::iterator IndexIterator;
TSet<TString>::iterator AddedKeysIterator;
TSet<TString>::iterator DeletedKeysIterator;
-
- public:
+
+ public:
TIterator(TIncrementalKeySet& keySet, TMap<TString, TIndexRecord>::iterator indexIterator,
TSet<TString>::iterator addedKeysIterator, TSet<TString>::iterator deletedKeysIterator)
- : KeySet(keySet)
- , IndexIterator(indexIterator)
- , AddedKeysIterator(addedKeysIterator)
- , DeletedKeysIterator(deletedKeysIterator)
- {
- AdvanceToNonDeleted();
- }
-
- TIterator(const TIterator&) = default;
-
- TIterator& operator=(const TIterator& other) {
- IndexIterator = other.IndexIterator;
- AddedKeysIterator = other.AddedKeysIterator;
- DeletedKeysIterator = other.DeletedKeysIterator;
- return *this;
- }
-
+ : KeySet(keySet)
+ , IndexIterator(indexIterator)
+ , AddedKeysIterator(addedKeysIterator)
+ , DeletedKeysIterator(deletedKeysIterator)
+ {
+ AdvanceToNonDeleted();
+ }
+
+ TIterator(const TIterator&) = default;
+
+ TIterator& operator=(const TIterator& other) {
+ IndexIterator = other.IndexIterator;
+ AddedKeysIterator = other.AddedKeysIterator;
+ DeletedKeysIterator = other.DeletedKeysIterator;
+ return *this;
+ }
+
const TString& operator*() const {
- if (IndexIterator != KeySet.Index.end() && AddedKeysIterator != KeySet.AddedKeys.end()) {
- return std::min(IndexIterator->first, *AddedKeysIterator);
- } else if (IndexIterator != KeySet.Index.end()) {
- return IndexIterator->first;
- } else if (AddedKeysIterator != KeySet.AddedKeys.end()) {
- return *AddedKeysIterator;
- } else {
+ if (IndexIterator != KeySet.Index.end() && AddedKeysIterator != KeySet.AddedKeys.end()) {
+ return std::min(IndexIterator->first, *AddedKeysIterator);
+ } else if (IndexIterator != KeySet.Index.end()) {
+ return IndexIterator->first;
+ } else if (AddedKeysIterator != KeySet.AddedKeys.end()) {
+ return *AddedKeysIterator;
+ } else {
Y_FAIL("operator*() called on invalid iterator");
- }
- }
-
+ }
+ }
+
const TString *operator->() const {
- return &**this;
- }
-
- TIterator& operator++() {
- MoveNext();
- AdvanceToNonDeleted();
- return *this;
- }
-
- void AdvanceToNonDeleted() {
- for (;;) {
- if (IndexIterator == KeySet.Index.end() && AddedKeysIterator == KeySet.AddedKeys.end()) {
- DeletedKeysIterator = KeySet.DeletedKeys.end();
- break;
- } else {
+ return &**this;
+ }
+
+ TIterator& operator++() {
+ MoveNext();
+ AdvanceToNonDeleted();
+ return *this;
+ }
+
+ void AdvanceToNonDeleted() {
+ for (;;) {
+ if (IndexIterator == KeySet.Index.end() && AddedKeysIterator == KeySet.AddedKeys.end()) {
+ DeletedKeysIterator = KeySet.DeletedKeys.end();
+ break;
+ } else {
const TString& currentKey = **this;
- while (DeletedKeysIterator != KeySet.DeletedKeys.end() && *DeletedKeysIterator < currentKey) {
- ++DeletedKeysIterator; // FIXME: optimize
- }
- if (DeletedKeysIterator == KeySet.DeletedKeys.end() || *DeletedKeysIterator != currentKey) {
- break;
- }
- MoveNext();
- ++DeletedKeysIterator;
- }
- }
- }
-
- void MoveNext() {
- if (IndexIterator != KeySet.Index.end() && AddedKeysIterator != KeySet.AddedKeys.end()) {
+ while (DeletedKeysIterator != KeySet.DeletedKeys.end() && *DeletedKeysIterator < currentKey) {
+ ++DeletedKeysIterator; // FIXME: optimize
+ }
+ if (DeletedKeysIterator == KeySet.DeletedKeys.end() || *DeletedKeysIterator != currentKey) {
+ break;
+ }
+ MoveNext();
+ ++DeletedKeysIterator;
+ }
+ }
+ }
+
+ void MoveNext() {
+ if (IndexIterator != KeySet.Index.end() && AddedKeysIterator != KeySet.AddedKeys.end()) {
const TString& key = std::min(IndexIterator->first, *AddedKeysIterator);
- if (IndexIterator->first == key) {
- ++IndexIterator;
- }
- if (*AddedKeysIterator == key) {
- ++AddedKeysIterator;
- }
- } else if (IndexIterator != KeySet.Index.end()) {
- ++IndexIterator;
- } else if (AddedKeysIterator != KeySet.AddedKeys.end()) {
- ++AddedKeysIterator;
- } else {
+ if (IndexIterator->first == key) {
+ ++IndexIterator;
+ }
+ if (*AddedKeysIterator == key) {
+ ++AddedKeysIterator;
+ }
+ } else if (IndexIterator != KeySet.Index.end()) {
+ ++IndexIterator;
+ } else if (AddedKeysIterator != KeySet.AddedKeys.end()) {
+ ++AddedKeysIterator;
+ } else {
Y_FAIL("operator++() called on invalid iterator");
- }
- }
-
- friend bool operator==(const TIterator& left, const TIterator& right) {
- return left.IndexIterator == right.IndexIterator
- && left.AddedKeysIterator == right.AddedKeysIterator
- && left.DeletedKeysIterator == right.DeletedKeysIterator;
- }
-
- friend bool operator!=(const TIterator& left, const TIterator& right) {
- return !(left == right);
- }
- };
-
- public:
- using iterator = TIterator;
-
- public:
+ }
+ }
+
+ friend bool operator==(const TIterator& left, const TIterator& right) {
+ return left.IndexIterator == right.IndexIterator
+ && left.AddedKeysIterator == right.AddedKeysIterator
+ && left.DeletedKeysIterator == right.DeletedKeysIterator;
+ }
+
+ friend bool operator!=(const TIterator& left, const TIterator& right) {
+ return !(left == right);
+ }
+ };
+
+ public:
+ using iterator = TIterator;
+
+ public:
TIncrementalKeySet(TMap<TString, TIndexRecord>& index)
- : Index(index)
- {}
-
- template<typename Iterator>
- void insert(Iterator first, Iterator last) {
- AddedKeys.insert(first, last);
- if (last != first) {
- --last;
+ : Index(index)
+ {}
+
+ template<typename Iterator>
+ void insert(Iterator first, Iterator last) {
+ AddedKeys.insert(first, last);
+ if (last != first) {
+ --last;
TSet<TString>::iterator begin = DeletedKeys.lower_bound(*first);
TSet<TString>::iterator end = DeletedKeys.upper_bound(*last);
- DeletedKeys.erase(begin, end);
- }
- }
-
+ DeletedKeys.erase(begin, end);
+ }
+ }
+
void insert(const TString& key) {
- AddedKeys.insert(key);
- DeletedKeys.erase(key);
- }
-
- void erase(const iterator& iter) {
+ AddedKeys.insert(key);
+ DeletedKeys.erase(key);
+ }
+
+ void erase(const iterator& iter) {
const TString& key = *iter;
- DeletedKeys.insert(key);
- AddedKeys.erase(key);
- }
-
- void erase(iterator first, const iterator& last) {
- // FIXME: optimize
- while (first != last) {
- iterator temp = first;
- ++first;
- erase(temp);
- }
- }
-
+ DeletedKeys.insert(key);
+ AddedKeys.erase(key);
+ }
+
+ void erase(iterator first, const iterator& last) {
+ // FIXME: optimize
+ while (first != last) {
+ iterator temp = first;
+ ++first;
+ erase(temp);
+ }
+ }
+
iterator find(const TString& key) {
TSet<TString>::iterator deleted = DeletedKeys.lower_bound(key);
- if (deleted != DeletedKeys.end() && *deleted == key) {
- return end();
- }
-
+ if (deleted != DeletedKeys.end() && *deleted == key) {
+ return end();
+ }
+
TMap<TString, TIndexRecord>::iterator index = Index.lower_bound(key);
TSet<TString>::iterator added = AddedKeys.lower_bound(key);
-
- if ((index != Index.end() && index->first == key) || (added != AddedKeys.end() && *added == key)) {
- return TIterator{*this, index, added, deleted};
- }
-
- return end();
- }
-
- iterator begin() {
- return TIterator{*this, Index.begin(), AddedKeys.begin(), DeletedKeys.begin()};
- }
-
- iterator end() {
- return TIterator{*this, Index.end(), AddedKeys.end(), DeletedKeys.end()};
- }
-
+
+ if ((index != Index.end() && index->first == key) || (added != AddedKeys.end() && *added == key)) {
+ return TIterator{*this, index, added, deleted};
+ }
+
+ return end();
+ }
+
+ iterator begin() {
+ return TIterator{*this, Index.begin(), AddedKeys.begin(), DeletedKeys.begin()};
+ }
+
+ iterator end() {
+ return TIterator{*this, Index.end(), AddedKeys.end(), DeletedKeys.end()};
+ }
+
iterator lower_bound(const TString& key) {
- return TIterator{*this, Index.lower_bound(key), AddedKeys.lower_bound(key), DeletedKeys.lower_bound(key)};
- }
-
+ return TIterator{*this, Index.lower_bound(key), AddedKeys.lower_bound(key), DeletedKeys.lower_bound(key)};
+ }
+
iterator upper_bound(const TString& key) {
- return TIterator{*this, Index.upper_bound(key), AddedKeys.upper_bound(key), DeletedKeys.upper_bound(key)};
- }
- };
-
+ return TIterator{*this, Index.upper_bound(key), AddedKeys.upper_bound(key), DeletedKeys.upper_bound(key)};
+ }
+ };
+
ui32 GetGeneration() const {
return StoredState.UserGeneration;
}
@@ -241,10 +241,10 @@ protected:
ui32 NextLogoBlobStep;
ui32 NextLogoBlobCookie;
- using TKeySet = TIncrementalKeySet;
+ using TKeySet = TIncrementalKeySet;
TVector<TRangeSet> ChannelRangeSets;
- TIndex Index;
+ TIndex Index;
THashMap<TLogoBlobID, ui32> RefCounts;
TSet<TLogoBlobID> Trash;
TMap<ui64, ui64> InFlightForStep;
@@ -253,9 +253,9 @@ protected:
TIntrusivePtr<TCollectOperation> CollectOperation;
bool IsCollectEventSent;
bool IsSpringCleanupDone;
- std::array<ui64, 256> ChannelDataUsage;
- std::bitset<256> UsedChannels;
- THolder<TChannelBalancer::TWeightManager> WeightManager;
+ std::array<ui64, 256> ChannelDataUsage;
+ std::bitset<256> UsedChannels;
+ THolder<TChannelBalancer::TWeightManager> WeightManager;
ui64 TabletId;
TActorId KeyValueActorId;
@@ -278,7 +278,7 @@ protected:
TAutoPtr<TTabletCountersBase> TabletCountersPtr;
TInstant LastCollectStartedAt;
-
+
ui32 PerGenerationCounter; // for garbage collection
NMetrics::TResourceMetrics* ResourceMetrics;
@@ -296,7 +296,7 @@ public:
void CountRequestOtherError(TRequestType::EType requestType);
void CountRequestIncoming(TRequestType::EType requestType);
void CountTrashRecord(ui32 sizeBytes);
- void CountWriteRecord(ui8 channel, ui32 sizeBytes);
+ void CountWriteRecord(ui8 channel, ui32 sizeBytes);
void CountInitialTrashRecord(ui32 sizeBytes);
void CountTrashCollected(ui32 sizeBytes);
void CountOverrun();
@@ -308,8 +308,8 @@ public:
void CountProcessingInitQueue();
void CountOnline();
- void Terminate(const TActorContext& ctx);
- void Load(const TString &key, const TString& value);
+ void Terminate(const TActorContext& ctx);
+ void Load(const TString &key, const TString& value);
void InitExecute(ui64 tabletId, TActorId keyValueActorId, ui32 executorGeneration, ISimpleDb &db,
const TActorContext &ctx, const TTabletStorageInfo *info);
void RegisterInitialCollectResult(const TActorContext &ctx);
@@ -368,9 +368,9 @@ public:
void CmdDelete(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx);
void CmdWrite(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx);
void CmdGetStatus(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx);
- void CmdCopyRange(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
- void CmdConcat(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
- void CmdTrimLeakedBlobs(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
+ void CmdCopyRange(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
+ void CmdConcat(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
+ void CmdTrimLeakedBlobs(THolder<TIntermediate>& intermediate, ISimpleDb& db, const TActorContext& ctx);
void CmdSetExecutorFastLogPolicy(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx);
void CmdCmds(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx);
void ProcessCmds(THolder<TIntermediate> &intermediate, ISimpleDb &db, const TActorContext &ctx,
@@ -389,30 +389,30 @@ public:
TCheckResult CheckCmd(const TIntermediate::TConcat &cmd, TKeySet& keys, ui32 index) const;
bool CheckCmdRenames(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
- const TTabletStorageInfo *info);
+ const TTabletStorageInfo *info);
bool CheckCmdDeletes(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
- const TTabletStorageInfo *info);
+ const TTabletStorageInfo *info);
bool CheckCmdWrites(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
- const TTabletStorageInfo *info);
+ const TTabletStorageInfo *info);
bool CheckCmdCopyRanges(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
- const TTabletStorageInfo *info);
+ const TTabletStorageInfo *info);
bool CheckCmdConcats(THolder<TIntermediate>& intermediate, const TActorContext& ctx, TKeySet& keys,
- const TTabletStorageInfo *info);
+ const TTabletStorageInfo *info);
bool CheckCmdGetStatus(THolder<TIntermediate>& /*intermediate*/, const TActorContext& /*ctx*/,
TKeySet& /*keys*/, const TTabletStorageInfo* /*info*/);
bool CheckCmds(THolder<TIntermediate>& intermediate, const TActorContext& /*ctx*/, TKeySet& keys,
const TTabletStorageInfo* /*info*/);
-
+
void Step();
TLogoBlobID AllocateLogoBlobId(ui32 size, ui32 storageChannelIdx);
TIntrusivePtr<TCollectOperation>& GetCollectOperation() {
return CollectOperation;
}
- void Dereference(const TIndexRecord& record, ISimpleDb& db, const TActorContext& ctx);
+ void Dereference(const TIndexRecord& record, ISimpleDb& db, const TActorContext& ctx);
void UpdateKeyValue(const TString& key, const TIndexRecord& record, ISimpleDb& db, const TActorContext& ctx);
- void Dereference(const TLogoBlobID& id, ISimpleDb& db, const TActorContext& ctx, bool initial);
-
+ void Dereference(const TLogoBlobID& id, ISimpleDb& db, const TActorContext& ctx, bool initial);
+
ui32 GetPerGenerationCounter() {
return PerGenerationCounter;
}
@@ -429,7 +429,7 @@ public:
const TTabletStorageInfo *info);
void OnPeriodicRefresh(const TActorContext &ctx);
- void OnUpdateWeights(TChannelBalancer::TEvUpdateWeights::TPtr ev);
+ void OnUpdateWeights(TChannelBalancer::TEvUpdateWeights::TPtr ev);
void OnRequestComplete(ui64 requestUid, ui64 generation, ui64 step, const TActorContext &ctx,
const TTabletStorageInfo *info, NMsgBusProxy::EResponseStatus status, const TRequestStat &stat);
@@ -439,10 +439,10 @@ public:
bool PrepareIntermediate(TEvKeyValue::TEvRequest::TPtr &ev, THolder<TIntermediate> &intermediate,
TRequestType::EType &inOutRequestType, const TActorContext &ctx, const TTabletStorageInfo *info);
void RenderHTMLPage(IOutputStream &out) const;
- void MonChannelStat(NJson::TJsonValue& out) const;
+ void MonChannelStat(NJson::TJsonValue& out) const;
- bool CheckDeadline(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate);
+ bool CheckDeadline(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate);
template <typename TRequest>
bool CheckDeadline(const TActorContext &ctx, TRequest *request,
@@ -469,8 +469,8 @@ public:
return false;
}
- bool CheckGeneration(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate);
+ bool CheckGeneration(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate);
template <typename TGrpcRequestWithLockGeneration>
bool CheckGeneration(const TActorContext &ctx, TGrpcRequestWithLockGeneration *kvRequest,
@@ -494,24 +494,24 @@ public:
void SplitIntoBlobs(TIntermediate::TWrite &cmd, bool isInline, ui32 storageChannelIdx);
- bool PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ bool PrepareCmdRead(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, bool &outIsInlineOnly);
- bool PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ bool PrepareCmdReadRange(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, bool &inOutIsInlineOnly);
- bool PrepareCmdRename(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate);
- bool PrepareCmdDelete(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
- THolder<TIntermediate> &intermediate);
- bool PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ bool PrepareCmdRename(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate);
+ bool PrepareCmdDelete(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ THolder<TIntermediate> &intermediate);
+ bool PrepareCmdWrite(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, const TTabletStorageInfo *info);
- bool PrepareCmdGetStatus(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
+ bool PrepareCmdGetStatus(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, const TTabletStorageInfo *info);
- bool PrepareCmdCopyRange(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
- THolder<TIntermediate>& intermediate);
- bool PrepareCmdConcat(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
- THolder<TIntermediate>& intermediate);
- bool PrepareCmdTrimLeakedBlobs(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
- THolder<TIntermediate>& intermediate, const TTabletStorageInfo *info);
+ bool PrepareCmdCopyRange(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
+ THolder<TIntermediate>& intermediate);
+ bool PrepareCmdConcat(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
+ THolder<TIntermediate>& intermediate);
+ bool PrepareCmdTrimLeakedBlobs(const TActorContext& ctx, NKikimrClient::TKeyValueRequest& kvRequest,
+ THolder<TIntermediate>& intermediate, const TTabletStorageInfo *info);
bool PrepareCmdSetExecutorFastLogPolicy(const TActorContext &ctx, NKikimrClient::TKeyValueRequest &kvRequest,
THolder<TIntermediate> &intermediate, const TTabletStorageInfo *info);
@@ -534,9 +534,9 @@ public:
TPrepareResult InitGetStatusCommand(TIntermediate::TGetStatus &cmd,
NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel, const TTabletStorageInfo *info);
void ReplyError(const TActorContext &ctx, TString errorDescription,
- NMsgBusProxy::EResponseStatus status, THolder<TIntermediate> &intermediate,
- const TTabletStorageInfo *info = nullptr);
-
+ NMsgBusProxy::EResponseStatus status, THolder<TIntermediate> &intermediate,
+ const TTabletStorageInfo *info = nullptr);
+
template <typename TResponse>
void ReplyError(const TActorContext &ctx, TString errorDescription,
NKikimrKeyValue::Statuses::ReplyStatus status, THolder<TIntermediate> &intermediate,
@@ -600,9 +600,9 @@ public:
void ProcessPostponedIntermediate(const TActorContext& ctx, THolder<TIntermediate> &&intermediate,
const TTabletStorageInfo *info);
- bool ConvertRange(const NKikimrClient::TKeyValueRequest::TKeyRange& from, TKeyRange *to,
- const TActorContext& ctx, THolder<TIntermediate>& intermediate, const char *cmd, ui32 index);
-
+ bool ConvertRange(const NKikimrClient::TKeyValueRequest::TKeyRange& from, TKeyRange *to,
+ const TActorContext& ctx, THolder<TIntermediate>& intermediate, const char *cmd, ui32 index);
+
struct TConvertRangeResult {
TString ErrorMsg;
bool WithError = false;
@@ -652,28 +652,28 @@ public:
return {};
}
- template<typename Container, typename Iterator = typename Container::iterator>
- static std::pair<Iterator, Iterator> GetRange(const TKeyRange& range, Container& container) {
- auto first = !range.HasFrom ? container.begin()
- : range.IncludeFrom ? container.lower_bound(range.KeyFrom)
- : container.upper_bound(range.KeyFrom);
-
- auto last = !range.HasTo ? container.end()
- : range.IncludeTo ? container.upper_bound(range.KeyTo)
- : container.lower_bound(range.KeyTo);
-
- return {first, last};
- }
-
- template<typename Func>
- void TraverseRange(const TKeyRange& range, Func&& callback) {
- std::pair<TIndex::iterator, TIndex::iterator> r = GetRange(range, Index);
- TIndex::iterator nextIt;
- for (TIndex::iterator it = r.first; it != r.second; it = nextIt) {
- nextIt = std::next(it);
- callback(it);
- }
- }
+ template<typename Container, typename Iterator = typename Container::iterator>
+ static std::pair<Iterator, Iterator> GetRange(const TKeyRange& range, Container& container) {
+ auto first = !range.HasFrom ? container.begin()
+ : range.IncludeFrom ? container.lower_bound(range.KeyFrom)
+ : container.upper_bound(range.KeyFrom);
+
+ auto last = !range.HasTo ? container.end()
+ : range.IncludeTo ? container.upper_bound(range.KeyTo)
+ : container.lower_bound(range.KeyTo);
+
+ return {first, last};
+ }
+
+ template<typename Func>
+ void TraverseRange(const TKeyRange& range, Func&& callback) {
+ std::pair<TIndex::iterator, TIndex::iterator> r = GetRange(range, Index);
+ TIndex::iterator nextIt;
+ for (TIndex::iterator it = r.first; it != r.second; it = nextIt) {
+ nextIt = std::next(it);
+ callback(it);
+ }
+ }
void UpdateResourceMetrics(const TActorContext& ctx);
bool GetIsDamaged() const {
@@ -704,13 +704,13 @@ public:
IsSpringCleanupDone = true;
}
- ui64 GetTrashTotalBytes() const {
- ui64 res = 0;
- for (const TLogoBlobID& id : Trash) {
- res += id.BlobSize();
- }
- return res;
- }
+ ui64 GetTrashTotalBytes() const {
+ ui64 res = 0;
+ for (const TLogoBlobID& id : Trash) {
+ res += id.BlobSize();
+ }
+ return res;
+ }
public: // For testing
TString Dump() const;
diff --git a/ydb/core/keyvalue/keyvalue_storage_request.cpp b/ydb/core/keyvalue/keyvalue_storage_request.cpp
index e9032d2ed3d..5e0af3abed9 100644
--- a/ydb/core/keyvalue/keyvalue_storage_request.cpp
+++ b/ydb/core/keyvalue/keyvalue_storage_request.cpp
@@ -21,19 +21,19 @@ class TKeyValueStorageRequest : public TActorBootstrapped<TKeyValueStorageReques
ui64 WriteRequestsReplied;
ui64 GetStatusRequestsSent;
ui64 GetStatusRequestsReplied;
- ui64 RangeRequestsSent;
- ui64 RangeRequestsReplied;
+ ui64 RangeRequestsSent;
+ ui64 RangeRequestsReplied;
ui64 InFlightLimit;
- ui64 InFlightLimitSeq;
- ui64 InFlightQueries;
- ui64 InFlightRequestsLimit;
+ ui64 InFlightLimitSeq;
+ ui64 InFlightQueries;
+ ui64 InFlightRequestsLimit;
ui64 NextInFlightBatchCookie;
THolder<TIntermediate> IntermediateResults;
TIntrusivePtr<TTabletStorageInfo> TabletInfo;
- THPTimer PutTimer;
+ THPTimer PutTimer;
TInstant GetStatusSentAt;
TInstant LastSuccess;
const TDuration MuteDuration = TDuration::Seconds(5);
@@ -41,46 +41,46 @@ class TKeyValueStorageRequest : public TActorBootstrapped<TKeyValueStorageReques
THashMap<ui32, TInstant> TimeForNextSend;
- struct TReadQueueItem {
- TIntermediate::TRead *Read;
- TIntermediate::TRead::TReadItem *ReadItem;
-
- friend bool operator <(const TReadQueueItem& left, const TReadQueueItem& right) {
- return left.ReadItem->LogoBlobId < right.ReadItem->LogoBlobId;
- }
- };
-
+ struct TReadQueueItem {
+ TIntermediate::TRead *Read;
+ TIntermediate::TRead::TReadItem *ReadItem;
+
+ friend bool operator <(const TReadQueueItem& left, const TReadQueueItem& right) {
+ return left.ReadItem->LogoBlobId < right.ReadItem->LogoBlobId;
+ }
+ };
+
struct TInFlightBatch {
TVector<TReadQueueItem> ReadQueue;
- TInstant SentAt;
- };
-
+ TInstant SentAt;
+ };
+
TMap<ui64, TInFlightBatch> InFlightBatchByCookie;
TDeque<TReadQueueItem> ReadItems;
-
+
TStackVec<ui32, 16> YellowMoveChannels;
TStackVec<ui32, 16> YellowStopChannels;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KEYVALUE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KEYVALUE_ACTOR;
}
- TKeyValueStorageRequest(THolder<TIntermediate>&& intermediate, const TTabletStorageInfo *tabletInfo)
+ TKeyValueStorageRequest(THolder<TIntermediate>&& intermediate, const TTabletStorageInfo *tabletInfo)
: ReadRequestsSent(0)
, ReadRequestsReplied(0)
, WriteRequestsSent(0)
, WriteRequestsReplied(0)
, GetStatusRequestsSent(0)
, GetStatusRequestsReplied(0)
- , RangeRequestsSent(0)
- , RangeRequestsReplied(0)
- , InFlightLimit(50)
- , InFlightLimitSeq(intermediate->SequentialReadLimit)
- , InFlightQueries(0)
+ , RangeRequestsSent(0)
+ , RangeRequestsReplied(0)
+ , InFlightLimit(50)
+ , InFlightLimitSeq(intermediate->SequentialReadLimit)
+ , InFlightQueries(0)
, InFlightRequestsLimit(10)
, NextInFlightBatchCookie(1)
- , IntermediateResults(std::move(intermediate))
+ , IntermediateResults(std::move(intermediate))
, TabletInfo(const_cast<TTabletStorageInfo*>(tabletInfo))
{
IntermediateResults->Stat.KeyvalueStorageRequestSentAt = TAppData::TimeProvider->Now();
@@ -108,8 +108,8 @@ public:
}
void Handle(TEvBlobStorage::TEvPutResult::TPtr &ev, const TActorContext &ctx) {
- const TDuration duration = TDuration::Seconds(PutTimer.Passed());
- IntermediateResults->Stat.PutLatencies.push_back(duration.MilliSeconds());
+ const TDuration duration = TDuration::Seconds(PutTimer.Passed());
+ IntermediateResults->Stat.PutLatencies.push_back(duration.MilliSeconds());
auto groupId = ev->Get()->GroupId;
CheckYellow(ev->Get()->StatusFlags, groupId);
@@ -123,13 +123,13 @@ public:
str << " Unexpected EvPut result# " << NKikimrProto::EReplyStatus_Name(status).data();
str << " Deadline# " << IntermediateResults->Deadline.MilliSeconds();
str << " Now# " << now.MilliSeconds();
- str << " duration# " << duration;
+ str << " duration# " << duration;
str << " GotAt# " << IntermediateResults->Stat.IntermediateCreatedAt.MilliSeconds();
str << " LastSuccess# " << LastSuccess;
str << " SinceLastSuccess# " << (now - LastSuccess).MilliSeconds();
str << " EnqueuedAs# " << IntermediateResults->Stat.EnqueuedAs;
str << " ErrorReason# " << ev->Get()->ErrorReason;
- str << " Marker# KV24";
+ str << " Marker# KV24";
NLog::EPriority logPriority = ErrorStateMuteChecker.Register(now, MuteDuration);
@@ -145,7 +145,7 @@ public:
str << "KeyValue# " << TabletInfo->TabletID;
str << " EvPut cookie# " << (ui64)cookie;
str << " > writes#" << (ui32)IntermediateResults->Writes.size();
- str << " Marker# KV25";
+ str << " Marker# KV25";
ReplyErrorAndDie(ctx, str.Str());
return;
}
@@ -161,7 +161,7 @@ public:
++WriteRequestsReplied;
IntermediateResults->Stat.GroupWrittenBytes[std::make_pair(ev->Get()->Id.Channel(), groupId)] += ev->Get()->Id.BlobSize();
IntermediateResults->Stat.GroupWrittenIops[std::make_pair(ev->Get()->Id.Channel(), groupId)] += 1; // FIXME: count distinct blobs?
- UpdateRequest(ctx);
+ UpdateRequest(ctx);
}
void Handle(TEvBlobStorage::TEvStatusResult::TPtr &ev, const TActorContext &ctx) {
@@ -205,18 +205,18 @@ public:
UpdateRequest(ctx);
}
- void Handle(TEvBlobStorage::TEvRangeResult::TPtr &ev, const TActorContext &ctx) {
- TEvBlobStorage::TEvRangeResult *msg = ev->Get();
- if (msg->Status == NKikimrProto::OK) {
- auto &v = IntermediateResults->TrimLeakedBlobs->FoundBlobs;
- for (const auto &resp : msg->Responses) {
- v.push_back(resp.Id);
- }
- }
- ++RangeRequestsReplied;
- UpdateRequest(ctx);
- }
-
+ void Handle(TEvBlobStorage::TEvRangeResult::TPtr &ev, const TActorContext &ctx) {
+ TEvBlobStorage::TEvRangeResult *msg = ev->Get();
+ if (msg->Status == NKikimrProto::OK) {
+ auto &v = IntermediateResults->TrimLeakedBlobs->FoundBlobs;
+ for (const auto &resp : msg->Responses) {
+ v.push_back(resp.Id);
+ }
+ }
+ ++RangeRequestsReplied;
+ UpdateRequest(ctx);
+ }
+
void Handle(TEvBlobStorage::TEvGetResult::TPtr &ev, const TActorContext &ctx) {
Y_VERIFY(!InFlightBatchByCookie.empty());
@@ -225,20 +225,20 @@ public:
Y_VERIFY(foundIt != InFlightBatchByCookie.end(), "Cookie# %" PRIu64 " not found!", ev->Cookie);
TInFlightBatch &request = foundIt->second;
- InFlightQueries -= request.ReadQueue.size();
-
+ InFlightQueries -= request.ReadQueue.size();
+
ui64 durationMs = (TAppData::TimeProvider->Now() - request.SentAt).MilliSeconds();
IntermediateResults->Stat.GetLatencies.push_back(durationMs);
- auto resetReadItems = [&](NKikimrProto::EReplyStatus status) {
- Y_VERIFY(status != NKikimrProto::UNKNOWN);
- for (const auto& item : request.ReadQueue) {
- auto& readItem = *item.ReadItem;
- readItem.Status = status;
- readItem.InFlight = false;
- }
- };
-
+ auto resetReadItems = [&](NKikimrProto::EReplyStatus status) {
+ Y_VERIFY(status != NKikimrProto::UNKNOWN);
+ for (const auto& item : request.ReadQueue) {
+ auto& readItem = *item.ReadItem;
+ readItem.Status = status;
+ readItem.InFlight = false;
+ }
+ };
+
NKikimrProto::EReplyStatus status = ev->Get()->Status;
if (status != NKikimrProto::OK) {
TInstant now = TAppData::TimeProvider->Now();
@@ -248,65 +248,65 @@ public:
str << " Unexpected EvGet result# " << NKikimrProto::EReplyStatus_Name(status).data();
str << " Deadline# " << IntermediateResults->Deadline.MilliSeconds();
str << " Now# " << now.MilliSeconds();
- str << " SentAt# " << request.SentAt.MilliSeconds();
+ str << " SentAt# " << request.SentAt.MilliSeconds();
str << " GotAt# " << IntermediateResults->Stat.IntermediateCreatedAt.MilliSeconds();
str << " LastSuccess# " << LastSuccess;
str << " SinceLastSuccess# " << (now - LastSuccess).MilliSeconds();
str << " EnqueuedAs# " << IntermediateResults->Stat.EnqueuedAs;
str << " ErrorReason# " << ev->Get()->ErrorReason;
- str << " Marker# KV26";
- resetReadItems(status);
+ str << " Marker# KV26";
+ resetReadItems(status);
ReplyErrorAndDie(ctx, str.Str(),
status == NKikimrProto::TIMEOUT ? NMsgBusProxy::MSTATUS_TIMEOUT : NMsgBusProxy::MSTATUS_INTERNALERROR);
return;
}
- if (ev->Get()->ResponseSz != request.ReadQueue.size()) {
+ if (ev->Get()->ResponseSz != request.ReadQueue.size()) {
LOG_ERROR_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletInfo->TabletID
<< " Got# " << ev->Get()->Print(false));
TStringStream str;
str << "KeyValue# " << TabletInfo->TabletID;
str << " Unexpected EvGet ResponseSz# " << (ui32)ev->Get()->ResponseSz;
- str << " InFlightQueries# " << (ui32)InFlightQueries;
- str << " ReadQueue.size# " << request.ReadQueue.size();
- str << " Marker# KV27";
- resetReadItems(NKikimrProto::ERROR);
+ str << " InFlightQueries# " << (ui32)InFlightQueries;
+ str << " ReadQueue.size# " << request.ReadQueue.size();
+ str << " Marker# KV27";
+ resetReadItems(NKikimrProto::ERROR);
ReplyErrorAndDie(ctx, str.Str());
return;
}
Y_VERIFY(ev->Get()->ResponseSz == request.ReadQueue.size());
auto groupId = ev->Get()->GroupId;
- decltype(request.ReadQueue)::iterator it = request.ReadQueue.begin();
- for (ui32 i = 0, num = ev->Get()->ResponseSz; i < num; ++i, ++it) {
- const auto& response = ev->Get()->Responses[i];
- auto& read = *it->Read;
- auto& readItem = *it->ReadItem;
+ decltype(request.ReadQueue)::iterator it = request.ReadQueue.begin();
+ for (ui32 i = 0, num = ev->Get()->ResponseSz; i < num; ++i, ++it) {
+ const auto& response = ev->Get()->Responses[i];
+ auto& read = *it->Read;
+ auto& readItem = *it->ReadItem;
- if (response.Status == NKikimrProto::OK) {
+ if (response.Status == NKikimrProto::OK) {
if (read.Value.size() != read.ValueSize) {
- read.Value.resize(read.ValueSize);
+ read.Value.resize(read.ValueSize);
}
Y_VERIFY(response.Buffer.size() == readItem.BlobSize);
Y_VERIFY(readItem.ValueOffset + readItem.BlobSize <= read.ValueSize);
memcpy(const_cast<char *>(read.Value.data()) + readItem.ValueOffset, response.Buffer.data(), response.Buffer.size());
IntermediateResults->Stat.GroupReadBytes[std::make_pair(response.Id.Channel(), groupId)] += response.Buffer.size();
IntermediateResults->Stat.GroupReadIops[std::make_pair(response.Id.Channel(), groupId)] += 1; // FIXME: count distinct blobs?
- } else {
- TStringStream err;
+ } else {
+ TStringStream err;
if (read.Message.size()) {
- err << read.Message << Endl;
+ err << read.Message << Endl;
}
- err << "BS EvGet query failed"
- << " LogoBlobId# " << readItem.LogoBlobId.ToString()
- << " Status# " << NKikimrProto::EReplyStatus_Name(response.Status)
- << " Response# " << ev->Get()->ToString()
- << " Marker# KV22";
- read.Message = err.Str();
+ err << "BS EvGet query failed"
+ << " LogoBlobId# " << readItem.LogoBlobId.ToString()
+ << " Status# " << NKikimrProto::EReplyStatus_Name(response.Status)
+ << " Response# " << ev->Get()->ToString()
+ << " Marker# KV22";
+ read.Message = err.Str();
}
- Y_VERIFY(response.Status != NKikimrProto::UNKNOWN);
- readItem.Status = response.Status;
- readItem.InFlight = false;
+ Y_VERIFY(response.Status != NKikimrProto::UNKNOWN);
+ readItem.Status = response.Status;
+ readItem.InFlight = false;
}
InFlightBatchByCookie.erase(foundIt);
@@ -314,7 +314,7 @@ public:
++ReadRequestsReplied;
- UpdateRequest(ctx);
+ UpdateRequest(ctx);
}
bool UpdateRequest(const TActorContext &ctx) {
@@ -331,11 +331,11 @@ public:
return true;
}
LastSuccess = now;
- bool sentSomething = false;
- while (SendSomeReadRequests(ctx)) {
- sentSomething = true;
- }
- if (sentSomething) {
+ bool sentSomething = false;
+ while (SendSomeReadRequests(ctx)) {
+ sentSomething = true;
+ }
+ if (sentSomething) {
return false;
}
@@ -349,13 +349,13 @@ public:
<< " Marker# KV45");
if (ReadRequestsReplied == ReadRequestsSent &&
WriteRequestsReplied == WriteRequestsSent &&
- GetStatusRequestsReplied == GetStatusRequestsSent &&
- RangeRequestsSent == RangeRequestsReplied) {
- for (auto& write : IntermediateResults->Writes) {
- if (write.Status == NKikimrProto::UNKNOWN) {
- write.Status = NKikimrProto::OK;
- }
- }
+ GetStatusRequestsReplied == GetStatusRequestsSent &&
+ RangeRequestsSent == RangeRequestsReplied) {
+ for (auto& write : IntermediateResults->Writes) {
+ if (write.Status == NKikimrProto::UNKNOWN) {
+ write.Status = NKikimrProto::OK;
+ }
+ }
for (auto& getStatus : IntermediateResults->GetStatuses) {
if (getStatus.Status == NKikimrProto::UNKNOWN) {
getStatus.Status = NKikimrProto::OK;
@@ -377,29 +377,29 @@ public:
IntermediateResults->Stat.YellowMoveChannels.insert(IntermediateResults->Stat.YellowMoveChannels.end(),
YellowMoveChannels.begin(), YellowMoveChannels.end());
TActorId keyValueActorId = IntermediateResults->KeyValueActorId;
- ctx.Send(keyValueActorId, new TEvKeyValue::TEvIntermediate(std::move(IntermediateResults)));
+ ctx.Send(keyValueActorId, new TEvKeyValue::TEvIntermediate(std::move(IntermediateResults)));
Die(ctx);
return true;
}
return false;
}
- template<typename Func>
- void TraverseReadItems(Func&& func) {
- auto traverseRead = [&](TIntermediate::TRead& read) {
- for (auto& readItem : read.ReadItems) {
- func(read, readItem);
- }
- };
- for (auto& rangeRead : IntermediateResults->RangeReads) {
- for (auto& read : rangeRead.Reads) {
- traverseRead(read);
- }
- }
- for (auto& read : IntermediateResults->Reads) {
- traverseRead(read);
- }
- }
+ template<typename Func>
+ void TraverseReadItems(Func&& func) {
+ auto traverseRead = [&](TIntermediate::TRead& read) {
+ for (auto& readItem : read.ReadItems) {
+ func(read, readItem);
+ }
+ };
+ for (auto& rangeRead : IntermediateResults->RangeReads) {
+ for (auto& read : rangeRead.Reads) {
+ traverseRead(read);
+ }
+ }
+ for (auto& read : IntermediateResults->Reads) {
+ traverseRead(read);
+ }
+ }
void Handle(TEvents::TEvWakeup::TPtr &ev, const TActorContext &ctx) {
Y_UNUSED(ev);
@@ -440,16 +440,16 @@ public:
ctx.Schedule(timeout, new TEvents::TEvWakeup());
}
- TraverseReadItems([&](TIntermediate::TRead& read, TIntermediate::TRead::TReadItem& readItem) {
+ TraverseReadItems([&](TIntermediate::TRead& read, TIntermediate::TRead::TReadItem& readItem) {
if (readItem.Status != NKikimrProto::SCHEDULED) {
ReadItems.push_back(TReadQueueItem{&read, &readItem});
}
- });
- Sort(ReadItems.begin(), ReadItems.end());
-
+ });
+ Sort(ReadItems.begin(), ReadItems.end());
+
SendWriteRequests(ctx);
SendGetStatusRequests(ctx);
- SendRangeRequests(ctx);
+ SendRangeRequests(ctx);
if (UpdateRequest(ctx)) {
return;
@@ -487,37 +487,37 @@ public:
Die(ctx);
}
- bool SendSomeReadRequests(const TActorContext &ctx) {
+ bool SendSomeReadRequests(const TActorContext &ctx) {
if (InFlightBatchByCookie.size() >= InFlightRequestsLimit) {
- return false;
+ return false;
}
-
+
TInFlightBatch request;
- ui32 expectedResponseSize = 0;
-
- TLogoBlobID prevId;
+ ui32 expectedResponseSize = 0;
+
+ TLogoBlobID prevId;
ui32 prevGroup = Max<ui32>();
- decltype(ReadItems)::iterator it;
+ decltype(ReadItems)::iterator it;
TVector<TReadQueueItem> skippedItems;
NKikimrBlobStorage::EGetHandleClass handleClass = NKikimrBlobStorage::FastRead;
bool isHandleClassSet = false;
- for (it = ReadItems.begin(); it != ReadItems.end(); ++it) {
- auto& readItem = *it->ReadItem;
- Y_VERIFY(!readItem.InFlight && readItem.Status == NKikimrProto::UNKNOWN);
-
- const TLogoBlobID& id = readItem.LogoBlobId;
+ for (it = ReadItems.begin(); it != ReadItems.end(); ++it) {
+ auto& readItem = *it->ReadItem;
+ Y_VERIFY(!readItem.InFlight && readItem.Status == NKikimrProto::UNKNOWN);
+
+ const TLogoBlobID& id = readItem.LogoBlobId;
bool isSameChannel = (request.ReadQueue.empty() || id.Channel() == prevId.Channel());
if (!isSameChannel) {
- skippedItems.push_back(std::move(*it));
- continue;
+ skippedItems.push_back(std::move(*it));
+ continue;
}
const ui32 group = TabletInfo->GroupFor(id.Channel(), id.Generation());
Y_VERIFY(group != Max<ui32>(), "ReadItem Blob# %s is mapped to an invalid group (-1)!",
id.ToString().c_str());
bool isSameGroup = (prevGroup == group || prevGroup == Max<ui32>());
if (!isSameGroup) {
- skippedItems.push_back(std::move(*it));
- continue;
+ skippedItems.push_back(std::move(*it));
+ continue;
}
if (isHandleClassSet) {
bool isSameClass = (handleClass == it->Read->HandleClass);
@@ -531,68 +531,68 @@ public:
}
bool isSeq = id.TabletID() == prevId.TabletID()
- && id.Generation() == prevId.Generation()
- && id.Step() == prevId.Step()
- && id.Cookie() == prevId.Cookie() + 1;
- prevId = id;
+ && id.Generation() == prevId.Generation()
+ && id.Step() == prevId.Step()
+ && id.Cookie() == prevId.Cookie() + 1;
+ prevId = id;
prevGroup = group;
-
+
if (InFlightQueries >= (isSeq ? InFlightLimitSeq : InFlightLimit)) {
- break;
+ break;
}
-
- // approximate expected response size
- expectedResponseSize += BlobProtobufHeaderMaxSize + readItem.BlobSize;
- if (expectedResponseSize > MaxProtobufSize) {
- break;
- }
-
- readItem.InFlight = true;
- request.ReadQueue.push_back(std::move(*it));
- ++InFlightQueries;
+
+ // approximate expected response size
+ expectedResponseSize += BlobProtobufHeaderMaxSize + readItem.BlobSize;
+ if (expectedResponseSize > MaxProtobufSize) {
+ break;
+ }
+
+ readItem.InFlight = true;
+ request.ReadQueue.push_back(std::move(*it));
+ ++InFlightQueries;
}
- std::move(skippedItems.begin(), skippedItems.end(), ReadItems.erase(ReadItems.begin(), it - skippedItems.size()));
-
- if (request.ReadQueue.empty()) {
- return false;
- }
-
- const ui32 readQueryCount = request.ReadQueue.size();
- TArrayHolder <TEvBlobStorage::TEvGet::TQuery> readQueries(new TEvBlobStorage::TEvGet::TQuery[readQueryCount]);
- ui32 queryIdx = 0;
-
+ std::move(skippedItems.begin(), skippedItems.end(), ReadItems.erase(ReadItems.begin(), it - skippedItems.size()));
+
+ if (request.ReadQueue.empty()) {
+ return false;
+ }
+
+ const ui32 readQueryCount = request.ReadQueue.size();
+ TArrayHolder <TEvBlobStorage::TEvGet::TQuery> readQueries(new TEvBlobStorage::TEvGet::TQuery[readQueryCount]);
+ ui32 queryIdx = 0;
+
prevGroup = Max<ui32>();
- for (const auto& rq : request.ReadQueue) {
- const auto& readItem = *rq.ReadItem;
+ for (const auto& rq : request.ReadQueue) {
+ const auto& readItem = *rq.ReadItem;
readQueries[queryIdx].Set(readItem.LogoBlobId, readItem.BlobOffset, readItem.BlobSize);
- ++queryIdx;
-
+ ++queryIdx;
+
const ui32 group = TabletInfo->GroupFor(readItem.LogoBlobId.Channel(), readItem.LogoBlobId.Generation());
Y_VERIFY(group != Max<ui32>(), "Get Blob# %s is mapped to an invalid group (-1)!",
readItem.LogoBlobId.ToString().c_str());
if (prevGroup != Max<ui32>()) {
Y_VERIFY(prevGroup == group);
- } else {
+ } else {
prevGroup = group;
}
- }
+ }
- ++ReadRequestsSent;
+ ++ReadRequestsSent;
request.SentAt = TAppData::TimeProvider->Now();
-
+
ui64 cookie = NextInFlightBatchCookie;
++NextInFlightBatchCookie;
InFlightBatchByCookie[cookie] = std::move(request);
Y_VERIFY(queryIdx == readQueryCount);
- SendToBSProxy(
+ SendToBSProxy(
ctx, prevGroup,
new TEvBlobStorage::TEvGet(readQueries, readQueryCount, IntermediateResults->Deadline,
handleClass, false),
cookie);
-
- return true;
+
+ return true;
}
void SendGetStatusRequests(const TActorContext &ctx) {
@@ -612,29 +612,29 @@ public:
GetStatusSentAt = TAppData::TimeProvider->Now();
}
- void SendRangeRequests(const TActorContext &ctx) {
- if (auto& cmd = IntermediateResults->TrimLeakedBlobs) {
- for (const auto& item : cmd->ChannelGroupMap) {
- ui32 channel;
- ui32 groupId;
- std::tie(channel, groupId) = item;
- const ui64 tabletId = TabletInfo->TabletID;
- TLogoBlobID from(tabletId, 0, 0, channel, 0, 0);
- TLogoBlobID to(tabletId, Max<ui32>(), Max<ui32>(), channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
- auto request = MakeHolder<TEvBlobStorage::TEvRange>(tabletId, from, to, false, TInstant::Max(), true);
- SendToBSProxy(ctx, groupId, request.Release());
- ++RangeRequestsSent;
- }
- }
- }
-
+ void SendRangeRequests(const TActorContext &ctx) {
+ if (auto& cmd = IntermediateResults->TrimLeakedBlobs) {
+ for (const auto& item : cmd->ChannelGroupMap) {
+ ui32 channel;
+ ui32 groupId;
+ std::tie(channel, groupId) = item;
+ const ui64 tabletId = TabletInfo->TabletID;
+ TLogoBlobID from(tabletId, 0, 0, channel, 0, 0);
+ TLogoBlobID to(tabletId, Max<ui32>(), Max<ui32>(), channel, TLogoBlobID::MaxBlobSize, TLogoBlobID::MaxCookie);
+ auto request = MakeHolder<TEvBlobStorage::TEvRange>(tabletId, from, to, false, TInstant::Max(), true);
+ SendToBSProxy(ctx, groupId, request.Release());
+ ++RangeRequestsSent;
+ }
+ }
+ }
+
void SendWriteRequests(const TActorContext &ctx) {
auto sendWrite = [&](ui32 i, auto &request) -> void {
using Type = std::decay_t<decltype(request)>;
if constexpr (std::is_same_v<Type, TIntermediate::TWrite>) {
if (request.Status != NKikimrProto::SCHEDULED) {
Y_VERIFY(request.Status == NKikimrProto::UNKNOWN);
-
+
ui64 offset = 0;
for (const TLogoBlobID& logoBlobId : request.LogoBlobIds) {
THolder<TEvBlobStorage::TEvPut> put(
@@ -648,7 +648,7 @@ public:
LOG_DEBUG_S(ctx, NKikimrServices::KEYVALUE, "KeyValue# " << TabletInfo->TabletID
<< " Send TEvPut# " << put->ToString() << " to groupId# " << groupId
<< " now# " << TAppData::TimeProvider->Now().MilliSeconds() << " Marker# KV60");
-
+
SendPutToGroup(ctx, groupId, TabletInfo.Get(), std::move(put), i);
++WriteRequestsSent;
@@ -668,7 +668,7 @@ public:
for (ui64 i = 0; i < IntermediateResults->Writes.size(); ++i) {
sendWrite(i, IntermediateResults->Writes[i]);
}
- PutTimer.Reset();
+ PutTimer.Reset();
}
STFUNC(StateWait) {
@@ -676,7 +676,7 @@ public:
HFunc(TEvBlobStorage::TEvGetResult, Handle);
HFunc(TEvBlobStorage::TEvPutResult, Handle);
HFunc(TEvBlobStorage::TEvStatusResult, Handle);
- HFunc(TEvBlobStorage::TEvRangeResult, Handle);
+ HFunc(TEvBlobStorage::TEvRangeResult, Handle);
HFunc(TEvents::TEvWakeup, Handle);
default:
break;
@@ -684,9 +684,9 @@ public:
}
};
-IActor* CreateKeyValueStorageRequest(THolder<TIntermediate>&& intermediate,
+IActor* CreateKeyValueStorageRequest(THolder<TIntermediate>&& intermediate,
const TTabletStorageInfo *tabletInfo) {
- return new TKeyValueStorageRequest(std::move(intermediate), tabletInfo);
+ return new TKeyValueStorageRequest(std::move(intermediate), tabletInfo);
}
} // NKeyValue
diff --git a/ydb/core/keyvalue/keyvalue_ut.cpp b/ydb/core/keyvalue/keyvalue_ut.cpp
index 4ae1fcf56a6..3f85319c88e 100644
--- a/ydb/core/keyvalue/keyvalue_ut.cpp
+++ b/ydb/core/keyvalue/keyvalue_ut.cpp
@@ -1,10 +1,10 @@
#include "defs.h"
#include "keyvalue.h"
-#include "keyvalue_state.h"
+#include "keyvalue_state.h"
#include <ydb/public/lib/base/msgbus.h>
#include <ydb/core/testlib/tablet_helpers.h>
#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/fast.h>
+#include <util/random/fast.h>
const bool ENABLE_DETAILED_KV_LOG = false;
@@ -128,8 +128,8 @@ void DoWithRetry(std::function<bool(void)> action, i32 retryCount = 2) {
}
void CmdWrite(const TDeque<TString> &keys, const TDeque<TString> &values,
- const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
- const NKikimrClient::TKeyValueRequest::EPriority priority, TTestContext &tc) {
+ const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
+ const NKikimrClient::TKeyValueRequest::EPriority priority, TTestContext &tc) {
Y_VERIFY(keys.size() == values.size());
TAutoPtr<IEventHandle> handle;
TEvKeyValue::TEvResponse *result;
@@ -164,15 +164,15 @@ void CmdWrite(const TDeque<TString> &keys, const TDeque<TString> &values,
}
void CmdWrite(const TString &key, const TString &value,
- const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
- const NKikimrClient::TKeyValueRequest::EPriority priority, TTestContext &tc) {
+ const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
+ const NKikimrClient::TKeyValueRequest::EPriority priority, TTestContext &tc) {
TDeque<TString> keys = {key};
TDeque<TString> values = {value};
CmdWrite(keys, values, storageChannel, priority, tc);
}
void CmdRead(const TDeque<TString> &keys,
- const NKikimrClient::TKeyValueRequest::EPriority priority,
+ const NKikimrClient::TKeyValueRequest::EPriority priority,
const TDeque<TString> &expectedValues, const TDeque<bool> expectedNodatas, TTestContext &tc) {
Y_VERIFY(keys.size() == expectedValues.size());
Y_VERIFY(expectedNodatas.size() == 0 || expectedNodatas.size() == keys.size());
@@ -405,7 +405,7 @@ void RunRequest(TDesiredPair<TEvKeyValue::TEvRequest> &dp, TTestContext &tc, ui6
return true;
});
}
-
+
void AddCmdReadRange(const TString &from, const bool includeFrom, const TString &to, const bool includeTo,
const bool includeData, const ui64 limitBytes,
const NKikimrClient::TKeyValueRequest::EPriority priority,
@@ -441,7 +441,7 @@ void AddCmdReadRange(const TString &from, const bool includeFrom, const TString
}
}
-void CmdGetStatus(const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
+void CmdGetStatus(const NKikimrClient::TKeyValueRequest::EStorageChannel storageChannel,
const ui32 expectedStatusFlags, TTestContext &tc) {
TAutoPtr<IEventHandle> handle;
TEvKeyValue::TEvResponse *result;
@@ -820,7 +820,7 @@ void ExecuteObtainLock(TTestContext &tc, ui64 expectedLockGeneration) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TEST CASES
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+
Y_UNIT_TEST(TestBasicWriteRead) {
TTestContext tc;
RunTestWithReboots(tc.TabletIds, [&]() {
@@ -858,16 +858,16 @@ Y_UNIT_TEST(TestWriteReadDeleteWithRestartsThenResponseOk) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite("key", "value", NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdWrite("key", "value", NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{"value"}, {}, tc);
CmdDeleteRange("key", true, "key", true, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {true}, tc);
- });
-}
-
+ });
+}
+
Y_UNIT_TEST(TestWriteReadDeleteWithRestartsThenResponseOkWithNewApi) {
TTestContext tc;
@@ -1013,16 +1013,16 @@ Y_UNIT_TEST(TestInlineWriteReadDeleteWithRestartsThenResponseOk) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite("key", "value", NKikimrClient::TKeyValueRequest::INLINE,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdWrite("key", "value", NKikimrClient::TKeyValueRequest::INLINE,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{"value"}, {}, tc);
CmdDeleteRange("key", true, "key", true, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {true}, tc);
});
}
-
+
Y_UNIT_TEST(TestInlineWriteReadDeleteWithRestartsThenResponseOkNewApi) {
TTestContext tc;
@@ -1152,17 +1152,17 @@ Y_UNIT_TEST(TestWriteReadWithRestartsThenResponseOk) {
value << "x";
keys.push_back(Sprintf("key%" PRIu32, itemIdx));
values.push_back(value.Str());
- }
- }
+ }
+ }
CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::EXTRA9,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
-
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+
TDeque<TString> expectedKeys;
TDeque<TString> expectedValues;
for (ui32 itemIdx = 1; itemIdx < 4; ++itemIdx) {
expectedKeys.push_back(keys[itemIdx]);
expectedValues.push_back(values[itemIdx]);
- }
+ }
{
TDesiredPair<TEvKeyValue::TEvRequest> dp;
AddCmdReadRange("key1", true, "key4", false, true, Max<ui64>(), NKikimrClient::TKeyValueRequest::REALTIME,
@@ -1183,7 +1183,7 @@ Y_UNIT_TEST(TestWriteReadWithRestartsThenResponseOk) {
}
});
}
-
+
Y_UNIT_TEST(TestWriteReadWithRestartsThenResponseOkNewApi) {
TTestContext tc;
@@ -1237,9 +1237,9 @@ Y_UNIT_TEST(TestInlineWriteReadWithRestartsThenResponseOk) {
values.push_back(value.Str());
CmdWrite(keys1, values1,
itemIdx % 2 == 0 ?
- NKikimrClient::TKeyValueRequest::INLINE :
- NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ NKikimrClient::TKeyValueRequest::INLINE :
+ NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
}
}
@@ -1324,9 +1324,9 @@ Y_UNIT_TEST(TestEmptyWriteReadDeleteWithRestartsThenResponseOk) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite("key", "", NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdWrite("key", "", NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {}, tc);
TDeque<TString> expectedKeys;
@@ -1341,7 +1341,7 @@ Y_UNIT_TEST(TestEmptyWriteReadDeleteWithRestartsThenResponseOk) {
}
CmdDeleteRange("key", true, "key", true, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {true}, tc);
});
}
@@ -1373,9 +1373,9 @@ Y_UNIT_TEST(TestInlineEmptyWriteReadDeleteWithRestartsThenResponseOk) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite("key", "", NKikimrClient::TKeyValueRequest::INLINE,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdWrite("key", "", NKikimrClient::TKeyValueRequest::INLINE,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {}, tc);
TDeque<TString> expectedKeys;
@@ -1390,7 +1390,7 @@ Y_UNIT_TEST(TestInlineEmptyWriteReadDeleteWithRestartsThenResponseOk) {
}
CmdDeleteRange("key", true, "key", true, tc);
- CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdRead({"key"}, NKikimrClient::TKeyValueRequest::REALTIME,
{""}, {true}, tc);
});
}
@@ -1531,10 +1531,10 @@ Y_UNIT_TEST(TestWriteReadRangeDataLimitThenLimitWorks) {
for (ui32 itemIdx = 0; itemIdx < itemCount; ++itemIdx) {
keys.push_back(Sprintf("k%07" PRIu32, itemIdx));
values.push_back(PrepareData(8, itemIdx));
- }
- CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
-
+ }
+ CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+
TDeque<TString> expectedKeys;
TDeque<TString> expectedValues;
ui64 totalSize = 0;
@@ -1543,12 +1543,12 @@ Y_UNIT_TEST(TestWriteReadRangeDataLimitThenLimitWorks) {
totalSize += values[itemIdx].size() + keys[itemIdx].size() + 32;
if (totalSize > sizeLimit) {
break;
- }
+ }
expectedKeys.push_back(keys[itemIdx]);
expectedValues.push_back(values[itemIdx]);
- }
+ }
Y_VERIFY(expectedKeys.size());
-
+
{
TDesiredPair<TEvKeyValue::TEvRequest> dp;
AddCmdReadRange("k0000000", true, "k9999999", true, true, sizeLimit,
@@ -1563,9 +1563,9 @@ Y_UNIT_TEST(TestWriteReadRangeDataLimitThenLimitWorks) {
NKikimrClient::TKeyValueRequest::REALTIME, {}, {}, NKikimrProto::OVERRUN, tc, dp);
RunRequest(dp, tc, __LINE__);
}
- });
-}
-
+ });
+}
+
void MakeTestWriteReadRangeDataLimitThenLimitWorksNewApi(ui32 storageChannel) {
TTestContext tc;
@@ -1620,9 +1620,9 @@ Y_UNIT_TEST(TestInlineWriteReadRangeLimitThenLimitWorks) {
keys.push_back(Sprintf("k%07" PRIu32, itemIdx));
values.push_back(PrepareData(8, itemIdx));
}
- CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::INLINE,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
-
+ CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::INLINE,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+
TDeque<TString> expectedKeys;
TDeque<TString> expectedValues;
ui64 totalSize = 0;
@@ -1674,26 +1674,26 @@ Y_UNIT_TEST(TestCopyRangeWorks) {
keys.push_back(Sprintf("k%07" PRIu32, itemIdx));
values.push_back(Sprintf("v%07" PRIu32, (ui32)itemIdx));
}
- CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
-
+ CmdWrite(keys, values, NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+
CmdCopyRange("", false, "~", false, "p", "", tc);
- CmdWrite("0", "0", NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
-
+ CmdWrite("0", "0", NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+
TDeque<TString> expectedKeys;
TDeque<TString> expectedValues;
for (ui32 itemIdx = 0; itemIdx < itemCount; ++itemIdx) {
expectedKeys.push_back(Sprintf("pk%07" PRIu32, itemIdx));
expectedValues.push_back(Sprintf("v%07" PRIu32, (ui32)itemIdx));
- }
+ }
TDesiredPair<TEvKeyValue::TEvRequest> dp;
AddCmdReadRange("p", false, "q", false, true, Max<ui64>(), NKikimrClient::TKeyValueRequest::REALTIME,
expectedKeys, expectedValues, NKikimrProto::OK, tc, dp);
RunRequest(dp, tc, __LINE__);
});
}
-
+
void MakeTestCopyRangeWorksNewApi(ui64 storageChannel) {
TTestContext tc;
@@ -1748,14 +1748,14 @@ Y_UNIT_TEST(TestInlineCopyRangeWorks) {
}
CmdWrite(keys, values,
((itemIdx / 20) % 2 == 0) ?
- NKikimrClient::TKeyValueRequest::INLINE :
- NKikimrClient::TKeyValueRequest::INLINE,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ NKikimrClient::TKeyValueRequest::INLINE :
+ NKikimrClient::TKeyValueRequest::INLINE,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
}
-
+
CmdCopyRange("", false, "~", false, "p", "", tc);
- CmdWrite("0", "0", NKikimrClient::TKeyValueRequest::INLINE,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdWrite("0", "0", NKikimrClient::TKeyValueRequest::INLINE,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
TDeque<TString> expectedKeys;
TDeque<TString> expectedValues;
@@ -1783,8 +1783,8 @@ Y_UNIT_TEST(TestConcatWorks) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite({"1", "2", "3", "4"}, {"hello", ", ", "world", "!"}, NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdWrite({"1", "2", "3", "4"}, {"hello", ", ", "world", "!"}, NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
CmdConcat({"1", "2", "3", "4"}, "5", false, tc);
{
TDesiredPair<TEvKeyValue::TEvRequest> dp;
@@ -1799,9 +1799,9 @@ Y_UNIT_TEST(TestConcatWorks) {
{"5"}, {"hello, world!hello, world!"}, NKikimrProto::OK, tc, dp);
RunRequest(dp, tc, __LINE__);
}
- });
-}
-
+ });
+}
+
Y_UNIT_TEST(TestConcatWorksNewApi) {
TTestContext tc;
@@ -1833,8 +1833,8 @@ Y_UNIT_TEST(TestRenameWorks) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite({"1", "2", "3", "4"}, {"123", "456", "789", "012"}, NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdWrite({"1", "2", "3", "4"}, {"123", "456", "789", "012"}, NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
CmdRename("2", "3", tc);
{
TDesiredPair<TEvKeyValue::TEvRequest> dp;
@@ -1843,8 +1843,8 @@ Y_UNIT_TEST(TestRenameWorks) {
RunRequest(dp, tc, __LINE__);
}
});
-}
-
+}
+
Y_UNIT_TEST(TestRenameWorksewApi) {
TTestContext tc;
@@ -1875,13 +1875,13 @@ Y_UNIT_TEST(TestWriteToExtraChannelThenReadMixedChannelsReturnsOk) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdWrite("key1", "value1", NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdWrite("key2", "value2", NKikimrClient::TKeyValueRequest::EXTRA,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdWrite("key3", "value3", NKikimrClient::TKeyValueRequest::MAIN,
- NKikimrClient::TKeyValueRequest::REALTIME, tc);
- CmdRead({"key1", "key2", "key3"}, NKikimrClient::TKeyValueRequest::REALTIME,
+ CmdWrite("key1", "value1", NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdWrite("key2", "value2", NKikimrClient::TKeyValueRequest::EXTRA,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdWrite("key3", "value3", NKikimrClient::TKeyValueRequest::MAIN,
+ NKikimrClient::TKeyValueRequest::REALTIME, tc);
+ CmdRead({"key1", "key2", "key3"}, NKikimrClient::TKeyValueRequest::REALTIME,
{"value1", "value2", "value3"}, {}, tc);
{
TDesiredPair<TEvKeyValue::TEvRequest> dp;
@@ -1890,8 +1890,8 @@ Y_UNIT_TEST(TestWriteToExtraChannelThenReadMixedChannelsReturnsOk) {
RunRequest(dp, tc, __LINE__);
}
});
-}
-
+}
+
Y_UNIT_TEST(TestWriteToExtraChannelThenReadMixedChannelsReturnsOkNewApi) {
TTestContext tc;
@@ -1911,84 +1911,84 @@ Y_UNIT_TEST(TestWriteToExtraChannelThenReadMixedChannelsReturnsOkNewApi) {
Y_UNIT_TEST(TestIncrementalKeySet) {
- // generate initial key set
+ // generate initial key set
TSet<TString> keys;
- for (ui32 i = 0; i < 100; ++i) {
- keys.insert(Sprintf("%04d", i));
- }
-
- // fill index to match those keys
+ for (ui32 i = 0; i < 100; ++i) {
+ keys.insert(Sprintf("%04d", i));
+ }
+
+ // fill index to match those keys
TMap<TString, NKeyValue::TIndexRecord> index;
for (const TString& key : keys) {
- index[key];
- }
-
- TReallyFastRng32 rng(1);
-
- NKeyValue::TKeyValueState::TIncrementalKeySet incr(index);
- for (ui32 iteration = 0; iteration < 1500; ++iteration) {
- // compare
- auto iter = keys.begin();
- auto iiter = incr.begin();
- while (iter != keys.end() && iiter != incr.end()) {
- UNIT_ASSERT_VALUES_EQUAL(*iter, *iiter);
- ++iter;
- ++iiter;
- }
- UNIT_ASSERT_EQUAL(iter, keys.end());
- UNIT_ASSERT_EQUAL(iiter, incr.end());
-
- // find
+ index[key];
+ }
+
+ TReallyFastRng32 rng(1);
+
+ NKeyValue::TKeyValueState::TIncrementalKeySet incr(index);
+ for (ui32 iteration = 0; iteration < 1500; ++iteration) {
+ // compare
+ auto iter = keys.begin();
+ auto iiter = incr.begin();
+ while (iter != keys.end() && iiter != incr.end()) {
+ UNIT_ASSERT_VALUES_EQUAL(*iter, *iiter);
+ ++iter;
+ ++iiter;
+ }
+ UNIT_ASSERT_EQUAL(iter, keys.end());
+ UNIT_ASSERT_EQUAL(iiter, incr.end());
+
+ // find
for (const TString& key : keys) {
- auto iiter = incr.find(key);
- UNIT_ASSERT_UNEQUAL(iiter, incr.end());
- UNIT_ASSERT_VALUES_EQUAL(key, *iiter);
- }
-
- // lower_bound
- for (ui32 i = 0; i < 150; ++i) {
+ auto iiter = incr.find(key);
+ UNIT_ASSERT_UNEQUAL(iiter, incr.end());
+ UNIT_ASSERT_VALUES_EQUAL(key, *iiter);
+ }
+
+ // lower_bound
+ for (ui32 i = 0; i < 150; ++i) {
TString key = Sprintf("%04d", i);
- auto iter = keys.lower_bound(key);
- auto iiter = incr.lower_bound(key);
- if (iter == keys.end()) {
- UNIT_ASSERT_EQUAL(iiter, incr.end());
- } else {
- UNIT_ASSERT_VALUES_EQUAL(*iiter, *iter);
- }
- }
-
- // same for upper_bound
- for (ui32 i = 0; i < 150; ++i) {
+ auto iter = keys.lower_bound(key);
+ auto iiter = incr.lower_bound(key);
+ if (iter == keys.end()) {
+ UNIT_ASSERT_EQUAL(iiter, incr.end());
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(*iiter, *iter);
+ }
+ }
+
+ // same for upper_bound
+ for (ui32 i = 0; i < 150; ++i) {
TString key = Sprintf("%04d", i);
- auto iter = keys.upper_bound(key);
- auto iiter = incr.upper_bound(key);
- if (iter == keys.end()) {
- UNIT_ASSERT_EQUAL(iiter, incr.end());
- } else {
- UNIT_ASSERT_VALUES_EQUAL(*iiter, *iter);
- }
- }
-
- if (!keys.empty() && rng() % 2 == 1) {
- // generate delete command
- ui32 index = rng() % keys.size();
+ auto iter = keys.upper_bound(key);
+ auto iiter = incr.upper_bound(key);
+ if (iter == keys.end()) {
+ UNIT_ASSERT_EQUAL(iiter, incr.end());
+ } else {
+ UNIT_ASSERT_VALUES_EQUAL(*iiter, *iter);
+ }
+ }
+
+ if (!keys.empty() && rng() % 2 == 1) {
+ // generate delete command
+ ui32 index = rng() % keys.size();
TSet<TString>::iterator iter = keys.begin();
- std::advance(iter, index);
+ std::advance(iter, index);
TString key = *iter;
- auto iiter = incr.find(key);
- UNIT_ASSERT_UNEQUAL(iiter, incr.end());
- UNIT_ASSERT_VALUES_EQUAL(*iiter, key);
- keys.erase(iter);
- incr.erase(iiter);
- } else {
- // generate insert command
+ auto iiter = incr.find(key);
+ UNIT_ASSERT_UNEQUAL(iiter, incr.end());
+ UNIT_ASSERT_VALUES_EQUAL(*iiter, key);
+ keys.erase(iter);
+ incr.erase(iiter);
+ } else {
+ // generate insert command
TString key = Sprintf("%04d", rng() % 150);
- keys.insert(key);
- incr.insert(key);
- }
- }
-}
-
+ keys.insert(key);
+ incr.insert(key);
+ }
+ }
+}
+
Y_UNIT_TEST(TestGetStatusWorks) {
TTestContext tc;
RunTestWithReboots(tc.TabletIds, [&]() {
@@ -1996,7 +1996,7 @@ Y_UNIT_TEST(TestGetStatusWorks) {
}, [&](const TString &dispatchName, std::function<void(TTestActorRuntime&)> setup, bool &activeZone) {
TFinalizer finalizer(tc);
tc.Prepare(dispatchName, setup, activeZone);
- CmdGetStatus(NKikimrClient::TKeyValueRequest::MAIN,
+ CmdGetStatus(NKikimrClient::TKeyValueRequest::MAIN,
ui32(NKikimrBlobStorage::StatusIsValid), tc);
CmdGetStatus(NKikimrClient::TKeyValueRequest::INLINE,
ui32(NKikimrBlobStorage::StatusIsValid), tc);
diff --git a/ydb/core/kqp/executer/kqp_scan_executer.cpp b/ydb/core/kqp/executer/kqp_scan_executer.cpp
index 07c29f64e21..893c7103eb5 100644
--- a/ydb/core/kqp/executer/kqp_scan_executer.cpp
+++ b/ydb/core/kqp/executer/kqp_scan_executer.cpp
@@ -38,8 +38,8 @@ class TKqpScanExecuter : public TKqpExecuterBase<TKqpScanExecuter, EExecType::Sc
using TBase = TKqpExecuterBase<TKqpScanExecuter, EExecType::Scan>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KQP_EXECUTER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KQP_EXECUTER_ACTOR;
}
TKqpScanExecuter(IKqpGateway::TExecPhysicalRequest&& request, const TString& database,
diff --git a/ydb/core/kqp/kqp.h b/ydb/core/kqp/kqp.h
index 09f794591d3..ee417907b38 100644
--- a/ydb/core/kqp/kqp.h
+++ b/ydb/core/kqp/kqp.h
@@ -284,10 +284,10 @@ struct TEvKqp {
return Protobuf_->ParseFromString(data);
}
- bool ParseFromZeroCopyStream(google::protobuf::io::ZeroCopyInputStream* input) {
- return Protobuf_->ParseFromZeroCopyStream(input);
- }
-
+ bool ParseFromZeroCopyStream(google::protobuf::io::ZeroCopyInputStream* input) {
+ return Protobuf_->ParseFromZeroCopyStream(input);
+ }
+
bool SerializeToZeroCopyStream(google::protobuf::io::ZeroCopyOutputStream* output) const {
return Protobuf_->SerializeToZeroCopyStream(output);
}
@@ -304,10 +304,10 @@ struct TEvKqp {
return Protobuf_->DebugString();
}
- TString ShortDebugString() const {
- return Protobuf_->ShortDebugString();
- }
-
+ TString ShortDebugString() const {
+ return Protobuf_->ShortDebugString();
+ }
+
TString GetTypeName() const {
return Protobuf_->GetTypeName();
}
diff --git a/ydb/core/kqp/kqp_ic_gateway.cpp b/ydb/core/kqp/kqp_ic_gateway.cpp
index 47489a9bd54..95e3239fd4a 100644
--- a/ydb/core/kqp/kqp_ic_gateway.cpp
+++ b/ydb/core/kqp/kqp_ic_gateway.cpp
@@ -71,8 +71,8 @@ static NThreading::TFuture<TResult> NotImplemented() {
struct TAppConfigResult : public IKqpGateway::TGenericResult {
std::shared_ptr<const NKikimrConfig::TAppConfig> Config;
-};
-
+};
+
template<typename TRequest, typename TResponse, typename TResult>
class TProxyRequestHandler: public TRequestHandlerBase<
@@ -827,7 +827,7 @@ public:
using TRequest = TEvTxUserProxy::TEvProposeKqpTransaction;
using TResult = IKqpGateway::TExecPhysicalResult;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::KQP_EXEC_PHYSICAL_REQUEST_HANDLER;
}
diff --git a/ydb/core/kqp/kqp_worker_actor.cpp b/ydb/core/kqp/kqp_worker_actor.cpp
index cccb8a51e8e..0caf70d7adc 100644
--- a/ydb/core/kqp/kqp_worker_actor.cpp
+++ b/ydb/core/kqp/kqp_worker_actor.cpp
@@ -140,8 +140,8 @@ EKikimrStatsMode GetStatsMode(const NKikimrKqp::TQueryRequest& queryRequest, EKi
class TKqpWorkerActor : public TActorBootstrapped<TKqpWorkerActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KQP_WORKER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KQP_WORKER_ACTOR;
}
TKqpWorkerActor(const TActorId& owner, const TString& sessionId, const TKqpSettings::TConstPtr& kqpSettings,
diff --git a/ydb/core/kqp/proxy/kqp_proxy_peer_stats_calculator.cpp b/ydb/core/kqp/proxy/kqp_proxy_peer_stats_calculator.cpp
index 57fe7ff1c62..772b07e509f 100644
--- a/ydb/core/kqp/proxy/kqp_proxy_peer_stats_calculator.cpp
+++ b/ydb/core/kqp/proxy/kqp_proxy_peer_stats_calculator.cpp
@@ -16,14 +16,14 @@ TSimpleResourceStats CalcPeerStats(
if (data.empty())
return TSimpleResourceStats(0.0, 0.0, 0);
- auto getDataCenterId = [](const auto& entry) {
- return entry.HasDataCenterId() ? entry.GetDataCenterId() : DataCenterToString(entry.GetDataCenterNumId());
- };
-
+ auto getDataCenterId = [](const auto& entry) {
+ return entry.HasDataCenterId() ? entry.GetDataCenterId() : DataCenterToString(entry.GetDataCenterNumId());
+ };
+
double sum = 0;
ui32 cnt = 0;
for(const auto& entry: data) {
- if (getDataCenterId(entry) != selfDataCenterId && localDatacenterPolicy)
+ if (getDataCenterId(entry) != selfDataCenterId && localDatacenterPolicy)
continue;
sum += ExtractValue(entry);
@@ -38,7 +38,7 @@ TSimpleResourceStats CalcPeerStats(
double deviation = 0;
double xadd = 0;
for(const auto& entry: data) {
- if (getDataCenterId(entry) != selfDataCenterId && localDatacenterPolicy)
+ if (getDataCenterId(entry) != selfDataCenterId && localDatacenterPolicy)
continue;
xadd = static_cast<double> (entry.GetActiveWorkersCount()) - mean;
diff --git a/ydb/core/kqp/proxy/kqp_proxy_service.cpp b/ydb/core/kqp/proxy/kqp_proxy_service.cpp
index decd2cb3011..34be3de2aef 100644
--- a/ydb/core/kqp/proxy/kqp_proxy_service.cpp
+++ b/ydb/core/kqp/proxy/kqp_proxy_service.cpp
@@ -238,8 +238,8 @@ class TKqpProxyService : public TActorBootstrapped<TKqpProxyService> {
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KQP_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KQP_PROXY_ACTOR;
}
TKqpProxyService(const NKikimrConfig::TLogConfig& logConfig,
@@ -320,9 +320,9 @@ public:
void Handle(TEvInterconnect::TEvNodeInfo::TPtr& ev) {
if (const auto& node = ev->Get()->Node) {
- SelfDataCenterId = node->Location.GetDataCenterId();
+ SelfDataCenterId = node->Location.GetDataCenterId();
} else {
- SelfDataCenterId = TString();
+ SelfDataCenterId = TString();
}
NodeResources.SetNodeId(SelfId().NodeId());
@@ -1283,7 +1283,7 @@ private:
TLocalSessionsRegistry LocalSessions;
bool ServerWorkerBalancerComplete = false;
- std::optional<TString> SelfDataCenterId;
+ std::optional<TString> SelfDataCenterId;
TVector<NKikimrKqp::TKqpProxyNodeResources> PeerProxyNodeResources;
bool ResourcesPublishScheduled = false;
TString PublishBoardPath;
diff --git a/ydb/core/kqp/proxy/kqp_proxy_service.h b/ydb/core/kqp/proxy/kqp_proxy_service.h
index f5059d3f36b..d0283f36791 100644
--- a/ydb/core/kqp/proxy/kqp_proxy_service.h
+++ b/ydb/core/kqp/proxy/kqp_proxy_service.h
@@ -124,6 +124,6 @@ struct TPeerStats {
TSimpleResourceStats CalcPeerStats(
const TVector<NKikimrKqp::TKqpProxyNodeResources>& data, const TString& selfDataCenterId, bool localDatacenterPolicy,
std::function<double(const NKikimrKqp::TKqpProxyNodeResources& entry)> ExtractValue);
-TPeerStats CalcPeerStats(const TVector<NKikimrKqp::TKqpProxyNodeResources>& data, const TString& selfDataCenterId, bool localDatacenterPolicy);
+TPeerStats CalcPeerStats(const TVector<NKikimrKqp::TKqpProxyNodeResources>& data, const TString& selfDataCenterId, bool localDatacenterPolicy);
} // namespace NKikimr::NKqp
diff --git a/ydb/core/kqp/proxy/kqp_proxy_ut.cpp b/ydb/core/kqp/proxy/kqp_proxy_ut.cpp
index 49224bf2f46..ddab9e1698e 100644
--- a/ydb/core/kqp/proxy/kqp_proxy_ut.cpp
+++ b/ydb/core/kqp/proxy/kqp_proxy_ut.cpp
@@ -21,12 +21,12 @@ using namespace NSchemeShard;
struct TSimpleResource {
ui32 Cnt;
ui32 NodeId;
- TString DataCenterId;
+ TString DataCenterId;
- TSimpleResource(ui32 cnt, ui32 nodeId, TString dataCenterId)
+ TSimpleResource(ui32 cnt, ui32 nodeId, TString dataCenterId)
: Cnt(cnt)
, NodeId(nodeId)
- , DataCenterId(std::move(dataCenterId))
+ , DataCenterId(std::move(dataCenterId))
{}
};
diff --git a/ydb/core/mind/bscontroller/bsc.cpp b/ydb/core/mind/bscontroller/bsc.cpp
index 779381fd513..12baca385b8 100644
--- a/ydb/core/mind/bscontroller/bsc.cpp
+++ b/ydb/core/mind/bscontroller/bsc.cpp
@@ -1,376 +1,376 @@
-#include "impl.h"
-#include "config.h"
-#include "self_heal.h"
+#include "impl.h"
+#include "config.h"
+#include "self_heal.h"
#include "sys_view.h"
-
-namespace NKikimr {
-
-TString TGroupID::ToString() const {
- TStringStream str;
- str << "{TGroupID ConfigurationType# "
- << (ConfigurationType() == GroupConfigurationTypeStatic ? "Static" : "Dynamic");
- str << " AvailabilityDomainID# " << AvailabilityDomainID();
- str << " GroupLocalID# " << GroupLocalID();
- str << "}";
- return str.Str();
-}
-
-TString TPDiskID::ToString() const {
- TStringStream str;
- str << "{TPDiskID ConfigurationType# "
- << (ConfigurationType() == GroupConfigurationTypeStatic ? "Static" : "Dynamic");
- str << " AvailabilityDomainID# " << AvailabilityDomainID();
- str << " PDiskLocalID# " << PDiskLocalID();
- str << "}";
- return str.Str();
-}
-
+
+namespace NKikimr {
+
+TString TGroupID::ToString() const {
+ TStringStream str;
+ str << "{TGroupID ConfigurationType# "
+ << (ConfigurationType() == GroupConfigurationTypeStatic ? "Static" : "Dynamic");
+ str << " AvailabilityDomainID# " << AvailabilityDomainID();
+ str << " GroupLocalID# " << GroupLocalID();
+ str << "}";
+ return str.Str();
+}
+
+TString TPDiskID::ToString() const {
+ TStringStream str;
+ str << "{TPDiskID ConfigurationType# "
+ << (ConfigurationType() == GroupConfigurationTypeStatic ? "Static" : "Dynamic");
+ str << " AvailabilityDomainID# " << AvailabilityDomainID();
+ str << " PDiskLocalID# " << PDiskLocalID();
+ str << "}";
+ return str.Str();
+}
+
IActor* CreateFlatBsController(const TActorId &tablet, TTabletStorageInfo *info) {
- return new NBsController::TBlobStorageController(tablet, info);
-}
-
-namespace NBsController {
-
-TBlobStorageController::TVSlotInfo::TVSlotInfo(TVSlotId vSlotId, TPDiskInfo *pdisk, TGroupId groupId,
- Table::GroupGeneration::Type groupPrevGeneration, Table::GroupGeneration::Type groupGeneration,
- Table::Category::Type kind, Table::RingIdx::Type ringIdx, Table::FailDomainIdx::Type failDomainIdx,
- Table::VDiskIdx::Type vDiskIdx, Table::Mood::Type mood, TGroupInfo *group,
- TVSlotReadyTimestampQ *vslotReadyTimestampQ, TInstant lastSeenReady)
- : VSlotId(vSlotId)
- , PDisk(pdisk)
- , GroupId(groupId)
- , GroupPrevGeneration(groupPrevGeneration)
- , GroupGeneration(groupGeneration)
- , Kind(kind)
- , RingIdx(ringIdx)
- , FailDomainIdx(failDomainIdx)
- , VDiskIdx(vDiskIdx)
- , Mood(mood)
- , LastSeenReady(lastSeenReady)
- , VSlotReadyTimestampQ(*vslotReadyTimestampQ)
-{
- Y_VERIFY(pdisk);
- const auto& [it, inserted] = pdisk->VSlotsOnPDisk.emplace(VSlotId.VSlotId, this);
- Y_VERIFY(inserted);
-
- if (!IsBeingDeleted()) {
- if (Mood != TMood::Donor) {
- Y_VERIFY(group);
- Group = group;
- group->AddVSlot(this);
- }
- ++pdisk->NumActiveSlots;
- }
-}
-
-void TBlobStorageController::TGroupInfo::CalculateGroupStatus() {
- TBlobStorageGroupInfo::TGroupVDisks failed(Topology.get());
- TBlobStorageGroupInfo::TGroupVDisks failedByPDisk(Topology.get());
- for (const TVSlotInfo *slot : VDisksInGroup) {
- if (!slot->IsReady) {
- failed |= {Topology.get(), slot->GetShortVDiskId()};
- } else if (!slot->PDisk->HasGoodExpectedStatus()) {
- failedByPDisk |= {Topology.get(), slot->GetShortVDiskId()};
- }
- }
- auto deriveStatus = [&](const auto& failed) {
- auto& checker = *Topology->QuorumChecker;
- if (!failed.GetNumSetItems()) { // all disks of group are operational
+ return new NBsController::TBlobStorageController(tablet, info);
+}
+
+namespace NBsController {
+
+TBlobStorageController::TVSlotInfo::TVSlotInfo(TVSlotId vSlotId, TPDiskInfo *pdisk, TGroupId groupId,
+ Table::GroupGeneration::Type groupPrevGeneration, Table::GroupGeneration::Type groupGeneration,
+ Table::Category::Type kind, Table::RingIdx::Type ringIdx, Table::FailDomainIdx::Type failDomainIdx,
+ Table::VDiskIdx::Type vDiskIdx, Table::Mood::Type mood, TGroupInfo *group,
+ TVSlotReadyTimestampQ *vslotReadyTimestampQ, TInstant lastSeenReady)
+ : VSlotId(vSlotId)
+ , PDisk(pdisk)
+ , GroupId(groupId)
+ , GroupPrevGeneration(groupPrevGeneration)
+ , GroupGeneration(groupGeneration)
+ , Kind(kind)
+ , RingIdx(ringIdx)
+ , FailDomainIdx(failDomainIdx)
+ , VDiskIdx(vDiskIdx)
+ , Mood(mood)
+ , LastSeenReady(lastSeenReady)
+ , VSlotReadyTimestampQ(*vslotReadyTimestampQ)
+{
+ Y_VERIFY(pdisk);
+ const auto& [it, inserted] = pdisk->VSlotsOnPDisk.emplace(VSlotId.VSlotId, this);
+ Y_VERIFY(inserted);
+
+ if (!IsBeingDeleted()) {
+ if (Mood != TMood::Donor) {
+ Y_VERIFY(group);
+ Group = group;
+ group->AddVSlot(this);
+ }
+ ++pdisk->NumActiveSlots;
+ }
+}
+
+void TBlobStorageController::TGroupInfo::CalculateGroupStatus() {
+ TBlobStorageGroupInfo::TGroupVDisks failed(Topology.get());
+ TBlobStorageGroupInfo::TGroupVDisks failedByPDisk(Topology.get());
+ for (const TVSlotInfo *slot : VDisksInGroup) {
+ if (!slot->IsReady) {
+ failed |= {Topology.get(), slot->GetShortVDiskId()};
+ } else if (!slot->PDisk->HasGoodExpectedStatus()) {
+ failedByPDisk |= {Topology.get(), slot->GetShortVDiskId()};
+ }
+ }
+ auto deriveStatus = [&](const auto& failed) {
+ auto& checker = *Topology->QuorumChecker;
+ if (!failed.GetNumSetItems()) { // all disks of group are operational
return NKikimrBlobStorage::TGroupStatus::FULL;
- } else if (!checker.CheckFailModelForGroup(failed)) { // fail model exceeded
+ } else if (!checker.CheckFailModelForGroup(failed)) { // fail model exceeded
return NKikimrBlobStorage::TGroupStatus::DISINTEGRATED;
- } else if (checker.IsDegraded(failed)) { // group degraded
+ } else if (checker.IsDegraded(failed)) { // group degraded
return NKikimrBlobStorage::TGroupStatus::DEGRADED;
- } else if (failed.GetNumSetItems()) { // group partially available, but not degraded
+ } else if (failed.GetNumSetItems()) { // group partially available, but not degraded
return NKikimrBlobStorage::TGroupStatus::PARTIAL;
- } else {
- Y_FAIL("unexpected case");
- }
- };
- Status = {
- deriveStatus(failed),
- deriveStatus(failed | failedByPDisk),
- };
-}
-
-void TBlobStorageController::OnActivateExecutor(const TActorContext&) {
- // fill in static disks
- if (const auto& ss = AppData()->StaticBlobStorageConfig) {
- for (const auto& pdisk : ss->GetPDisks()) {
- const TPDiskId pdiskId(pdisk.GetNodeID(), pdisk.GetPDiskID());
- StaticPDisks.emplace(pdiskId, pdisk);
- SysViewChangedPDisks.insert(pdiskId);
- }
- for (const auto& vslot : ss->GetVDisks()) {
- const auto& location = vslot.GetVDiskLocation();
- const TPDiskId pdiskId(location.GetNodeID(), location.GetPDiskID());
- const TVSlotId vslotId(pdiskId, location.GetVDiskSlotID());
- StaticVSlots.emplace(vslotId, vslot);
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(vslot.GetVDiskID());
- StaticVDiskMap.emplace(vdiskId, vslotId);
- StaticVDiskMap.emplace(TVDiskID(vdiskId.GroupID, 0, vdiskId), vslotId);
- ++StaticPDisks.at(pdiskId).StaticSlotUsage;
- SysViewChangedVSlots.insert(vslotId);
- SysViewChangedGroups.insert(vdiskId.GroupID);
- }
- }
-
- // create self-heal actor
- SelfHealId = Register(CreateSelfHealActor(TabletID(), SelfHealUnreassignableGroups));
-
- // create stat processor
- StatProcessorActorId = Register(CreateStatProcessorActor());
-
+ } else {
+ Y_FAIL("unexpected case");
+ }
+ };
+ Status = {
+ deriveStatus(failed),
+ deriveStatus(failed | failedByPDisk),
+ };
+}
+
+void TBlobStorageController::OnActivateExecutor(const TActorContext&) {
+ // fill in static disks
+ if (const auto& ss = AppData()->StaticBlobStorageConfig) {
+ for (const auto& pdisk : ss->GetPDisks()) {
+ const TPDiskId pdiskId(pdisk.GetNodeID(), pdisk.GetPDiskID());
+ StaticPDisks.emplace(pdiskId, pdisk);
+ SysViewChangedPDisks.insert(pdiskId);
+ }
+ for (const auto& vslot : ss->GetVDisks()) {
+ const auto& location = vslot.GetVDiskLocation();
+ const TPDiskId pdiskId(location.GetNodeID(), location.GetPDiskID());
+ const TVSlotId vslotId(pdiskId, location.GetVDiskSlotID());
+ StaticVSlots.emplace(vslotId, vslot);
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(vslot.GetVDiskID());
+ StaticVDiskMap.emplace(vdiskId, vslotId);
+ StaticVDiskMap.emplace(TVDiskID(vdiskId.GroupID, 0, vdiskId), vslotId);
+ ++StaticPDisks.at(pdiskId).StaticSlotUsage;
+ SysViewChangedVSlots.insert(vslotId);
+ SysViewChangedGroups.insert(vdiskId.GroupID);
+ }
+ }
+
+ // create self-heal actor
+ SelfHealId = Register(CreateSelfHealActor(TabletID(), SelfHealUnreassignableGroups));
+
+ // create stat processor
+ StatProcessorActorId = Register(CreateStatProcessorActor());
+
// create system views collector
- SystemViewsCollectorId = Register(CreateSystemViewsCollector());
-
- Executor()->RegisterExternalTabletCounters(TabletCountersPtr);
- if (!ResponsivenessPinger) {
- ResponsivenessPinger = new TTabletResponsivenessPinger(TabletCounters->Simple()[NBlobStorageController::COUNTER_RESPONSE_TIME_USEC], TDuration::Seconds(1));
- ResponsivenessActorID = RegisterWithSameMailbox(ResponsivenessPinger);
- }
-
- // request node list
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
-
- // create storage pool stats monitor
- StoragePoolStat = std::make_unique<TStoragePoolStat>(GetServiceCounters(AppData()->Counters, "storage_pool_stat"));
-
- // initiate timer
- ScrubState.HandleTimer();
-
- // initialize not-ready histograms
- VSlotNotReadyHistogramUpdate();
-}
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr& ev) {
- TActivationContext::Send(ev->Forward(StatProcessorActorId));
-}
-
-void TBlobStorageController::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC01, "Handle TEvInterconnect::TEvNodesInfo");
- const bool initial = !HostRecords;
- HostRecords = std::make_shared<THostRecordMap::element_type>(ev->Get());
- Schedule(TDuration::Minutes(5), new TEvPrivate::TEvHostRecordsTimeToLiveExceeded);
- if (initial) {
- Execute(CreateTxInitScheme());
- }
-}
-
-void TBlobStorageController::HandleHostRecordsTimeToLiveExceeded() {
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
-}
-
-void TBlobStorageController::IssueInitialGroupContent() {
- auto ev = MakeHolder<TEvControllerNotifyGroupChange>();
- for (const auto& kv : GroupMap) {
- ev->Created.push_back(kv.first);
- }
- Send(StatProcessorActorId, ev.Release());
-}
-
-void TBlobStorageController::Handle(TEvents::TEvPoisonPill::TPtr&) {
- Become(&TThis::StateBroken);
- for (TActorId *ptr : {&SelfHealId, &StatProcessorActorId, &SystemViewsCollectorId}) {
- if (const TActorId actorId = std::exchange(*ptr, {})) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, SelfId(), nullptr, 0));
- }
- }
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, Tablet(), SelfId(), nullptr, 0));
-}
-
-void TBlobStorageController::NotifyNodesAwaitingKeysForGroups(ui32 groupId) {
- if (const auto it = NodesAwaitingKeysForGroup.find(groupId); it != NodesAwaitingKeysForGroup.end()) {
- TSet<ui32> nodes = std::move(it->second);
- NodesAwaitingKeysForGroup.erase(it);
- for (const TNodeId nodeId : nodes) {
- Send(SelfId(), new TEvBlobStorage::TEvControllerGetGroup(nodeId, groupId));
+ SystemViewsCollectorId = Register(CreateSystemViewsCollector());
+
+ Executor()->RegisterExternalTabletCounters(TabletCountersPtr);
+ if (!ResponsivenessPinger) {
+ ResponsivenessPinger = new TTabletResponsivenessPinger(TabletCounters->Simple()[NBlobStorageController::COUNTER_RESPONSE_TIME_USEC], TDuration::Seconds(1));
+ ResponsivenessActorID = RegisterWithSameMailbox(ResponsivenessPinger);
+ }
+
+ // request node list
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
+
+ // create storage pool stats monitor
+ StoragePoolStat = std::make_unique<TStoragePoolStat>(GetServiceCounters(AppData()->Counters, "storage_pool_stat"));
+
+ // initiate timer
+ ScrubState.HandleTimer();
+
+ // initialize not-ready histograms
+ VSlotNotReadyHistogramUpdate();
+}
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr& ev) {
+ TActivationContext::Send(ev->Forward(StatProcessorActorId));
+}
+
+void TBlobStorageController::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC01, "Handle TEvInterconnect::TEvNodesInfo");
+ const bool initial = !HostRecords;
+ HostRecords = std::make_shared<THostRecordMap::element_type>(ev->Get());
+ Schedule(TDuration::Minutes(5), new TEvPrivate::TEvHostRecordsTimeToLiveExceeded);
+ if (initial) {
+ Execute(CreateTxInitScheme());
+ }
+}
+
+void TBlobStorageController::HandleHostRecordsTimeToLiveExceeded() {
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes);
+}
+
+void TBlobStorageController::IssueInitialGroupContent() {
+ auto ev = MakeHolder<TEvControllerNotifyGroupChange>();
+ for (const auto& kv : GroupMap) {
+ ev->Created.push_back(kv.first);
+ }
+ Send(StatProcessorActorId, ev.Release());
+}
+
+void TBlobStorageController::Handle(TEvents::TEvPoisonPill::TPtr&) {
+ Become(&TThis::StateBroken);
+ for (TActorId *ptr : {&SelfHealId, &StatProcessorActorId, &SystemViewsCollectorId}) {
+ if (const TActorId actorId = std::exchange(*ptr, {})) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, SelfId(), nullptr, 0));
+ }
+ }
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, Tablet(), SelfId(), nullptr, 0));
+}
+
+void TBlobStorageController::NotifyNodesAwaitingKeysForGroups(ui32 groupId) {
+ if (const auto it = NodesAwaitingKeysForGroup.find(groupId); it != NodesAwaitingKeysForGroup.end()) {
+ TSet<ui32> nodes = std::move(it->second);
+ NodesAwaitingKeysForGroup.erase(it);
+ for (const TNodeId nodeId : nodes) {
+ Send(SelfId(), new TEvBlobStorage::TEvControllerGetGroup(nodeId, groupId));
}
}
}
-void TBlobStorageController::ValidateInternalState() {
- // here we compare different structures to ensure that the memory state is sane
-#ifndef NDEBUG
- for (const auto& [pdiskId, pdisk] : PDisks) {
- ui32 numActiveSlots = 0;
- for (const auto& [vslotId, vslot] : pdisk->VSlotsOnPDisk) {
- Y_VERIFY(vslot == FindVSlot(TVSlotId(pdiskId, vslotId)));
- Y_VERIFY(vslot->PDisk == pdisk.Get());
- numActiveSlots += !vslot->IsBeingDeleted();
- }
- Y_VERIFY(pdisk->NumActiveSlots == numActiveSlots);
- }
- for (const auto& [vslotId, vslot] : VSlots) {
- Y_VERIFY(vslot->VSlotId == vslotId);
- Y_VERIFY(vslot->PDisk == FindPDisk(vslot->VSlotId.ComprisingPDiskId()));
- const auto it = vslot->PDisk->VSlotsOnPDisk.find(vslotId.VSlotId);
- Y_VERIFY(it != vslot->PDisk->VSlotsOnPDisk.end());
- Y_VERIFY(it->second == vslot.Get());
- if (!vslot->IsBeingDeleted() && vslot->Mood != TMood::Donor) {
- Y_VERIFY(vslot->Group == FindGroup(vslot->GroupId));
- } else {
- Y_VERIFY(!vslot->Group);
- }
- if (vslot->Mood == TMood::Donor) {
- const TVSlotInfo *acceptor = FindVSlot(vslot->AcceptorVSlotId);
- Y_VERIFY(acceptor);
- auto& donors = acceptor->Donors;
- const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, vslot->GetVDiskId()));
- Y_VERIFY(it != donors.end());
- }
- for (const auto& [donorVSlotId, donorVDiskId] : vslot->Donors) {
- const TVSlotInfo *donor = FindVSlot(donorVSlotId);
- Y_VERIFY(donor);
- Y_VERIFY(donor->GetVDiskId() == donorVDiskId);
- Y_VERIFY(donor->Mood == TMood::Donor);
- Y_VERIFY(donor->AcceptorVSlotId == vslotId);
- }
- }
- for (const auto& [groupId, group] : GroupMap) {
- Y_VERIFY(groupId == group->ID);
- Y_VERIFY(FindGroup(groupId) == group.Get());
- for (const TVSlotInfo *vslot : group->VDisksInGroup) {
- Y_VERIFY(FindVSlot(vslot->VSlotId) == vslot);
- Y_VERIFY(vslot->Group == group.Get());
- Y_VERIFY(vslot->GroupId == groupId);
- Y_VERIFY(vslot->GroupGeneration == group->Generation);
- }
- }
- for (const auto& [key, value] : GroupLookup) {
- const auto it = GroupMap.find(key);
- Y_VERIFY(it != GroupMap.end());
- Y_VERIFY(value == it->second.Get());
- }
- Y_VERIFY(GroupLookup.size() == GroupMap.size());
-#endif
-}
-
-ui32 TBlobStorageController::GetEventPriority(IEventHandle *ev) {
- switch (ev->GetTypeRewrite()) {
- // essential NodeWarden messages (also includes SelfHeal-generated commands and UpdateDiskStatus when status gets worse than last reported)
- case TEvBlobStorage::EvControllerRegisterNode: return 1;
- case TEvBlobStorage::EvControllerNodeReport: return 1;
- case TEvBlobStorage::EvControllerProposeGroupKey: return 1;
- case TEvBlobStorage::EvControllerGetGroup: return 1;
-
- // auxiliary messages that are not usually urgent (also includes RW transactions in TConfigRequest and UpdateDiskStatus)
- case TEvBlobStorage::EvControllerGroupReconfigureWipe: return 2;
- case TEvPrivate::EvDropDonor: return 2;
- case TEvBlobStorage::EvControllerScrubQueryStartQuantum: return 2;
- case TEvBlobStorage::EvControllerScrubQuantumFinished: return 2;
- case TEvBlobStorage::EvControllerScrubReportQuantumInProgress: return 2;
+void TBlobStorageController::ValidateInternalState() {
+ // here we compare different structures to ensure that the memory state is sane
+#ifndef NDEBUG
+ for (const auto& [pdiskId, pdisk] : PDisks) {
+ ui32 numActiveSlots = 0;
+ for (const auto& [vslotId, vslot] : pdisk->VSlotsOnPDisk) {
+ Y_VERIFY(vslot == FindVSlot(TVSlotId(pdiskId, vslotId)));
+ Y_VERIFY(vslot->PDisk == pdisk.Get());
+ numActiveSlots += !vslot->IsBeingDeleted();
+ }
+ Y_VERIFY(pdisk->NumActiveSlots == numActiveSlots);
+ }
+ for (const auto& [vslotId, vslot] : VSlots) {
+ Y_VERIFY(vslot->VSlotId == vslotId);
+ Y_VERIFY(vslot->PDisk == FindPDisk(vslot->VSlotId.ComprisingPDiskId()));
+ const auto it = vslot->PDisk->VSlotsOnPDisk.find(vslotId.VSlotId);
+ Y_VERIFY(it != vslot->PDisk->VSlotsOnPDisk.end());
+ Y_VERIFY(it->second == vslot.Get());
+ if (!vslot->IsBeingDeleted() && vslot->Mood != TMood::Donor) {
+ Y_VERIFY(vslot->Group == FindGroup(vslot->GroupId));
+ } else {
+ Y_VERIFY(!vslot->Group);
+ }
+ if (vslot->Mood == TMood::Donor) {
+ const TVSlotInfo *acceptor = FindVSlot(vslot->AcceptorVSlotId);
+ Y_VERIFY(acceptor);
+ auto& donors = acceptor->Donors;
+ const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, vslot->GetVDiskId()));
+ Y_VERIFY(it != donors.end());
+ }
+ for (const auto& [donorVSlotId, donorVDiskId] : vslot->Donors) {
+ const TVSlotInfo *donor = FindVSlot(donorVSlotId);
+ Y_VERIFY(donor);
+ Y_VERIFY(donor->GetVDiskId() == donorVDiskId);
+ Y_VERIFY(donor->Mood == TMood::Donor);
+ Y_VERIFY(donor->AcceptorVSlotId == vslotId);
+ }
+ }
+ for (const auto& [groupId, group] : GroupMap) {
+ Y_VERIFY(groupId == group->ID);
+ Y_VERIFY(FindGroup(groupId) == group.Get());
+ for (const TVSlotInfo *vslot : group->VDisksInGroup) {
+ Y_VERIFY(FindVSlot(vslot->VSlotId) == vslot);
+ Y_VERIFY(vslot->Group == group.Get());
+ Y_VERIFY(vslot->GroupId == groupId);
+ Y_VERIFY(vslot->GroupGeneration == group->Generation);
+ }
+ }
+ for (const auto& [key, value] : GroupLookup) {
+ const auto it = GroupMap.find(key);
+ Y_VERIFY(it != GroupMap.end());
+ Y_VERIFY(value == it->second.Get());
+ }
+ Y_VERIFY(GroupLookup.size() == GroupMap.size());
+#endif
+}
+
+ui32 TBlobStorageController::GetEventPriority(IEventHandle *ev) {
+ switch (ev->GetTypeRewrite()) {
+ // essential NodeWarden messages (also includes SelfHeal-generated commands and UpdateDiskStatus when status gets worse than last reported)
+ case TEvBlobStorage::EvControllerRegisterNode: return 1;
+ case TEvBlobStorage::EvControllerNodeReport: return 1;
+ case TEvBlobStorage::EvControllerProposeGroupKey: return 1;
+ case TEvBlobStorage::EvControllerGetGroup: return 1;
+
+ // auxiliary messages that are not usually urgent (also includes RW transactions in TConfigRequest and UpdateDiskStatus)
+ case TEvBlobStorage::EvControllerGroupReconfigureWipe: return 2;
+ case TEvPrivate::EvDropDonor: return 2;
+ case TEvBlobStorage::EvControllerScrubQueryStartQuantum: return 2;
+ case TEvBlobStorage::EvControllerScrubQuantumFinished: return 2;
+ case TEvBlobStorage::EvControllerScrubReportQuantumInProgress: return 2;
case TEvBlobStorage::EvControllerUpdateNodeDrives: return 2;
-
- // hive-related commands
- case TEvBlobStorage::EvControllerSelectGroups: return 4;
-
- // timers and different observation (also includes RO transactions in TConfigRequest)
- case TEvPrivate::EvScrub: return 5;
- case TEvPrivate::EvVSlotReadyUpdate: return 5;
-
- // external observation and non-latency-bound activities
- case TEvPrivate::EvUpdateSystemViews: return 10;
- case TEvBlobStorage::EvControllerUpdateGroupStat: return 10;
- case TEvControllerCommitGroupLatencies::EventType: return 10;
- case TEvBlobStorage::EvRequestControllerInfo: return 10;
- case TEvPrivate::EvUpdateSelfHealCounters: return 10;
-
- case TEvBlobStorage::EvControllerUpdateDiskStatus: {
- auto *msg = ev->Get<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
- const auto& record = msg->Record;
- for (const auto& item : record.GetVDiskStatus()) {
- const TVSlotId vslotId(item.GetNodeId(), item.GetPDiskId(), item.GetVSlotId());
- if (TVSlotInfo *slot = FindVSlot(vslotId); slot && slot->GetStatus() > item.GetStatus()) {
- return 1;
- } else if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end() && it->second.VDiskStatus > item.GetStatus()) {
- return 1;
- }
- }
- return 2;
- }
-
- case TEvBlobStorage::EvControllerConfigRequest: {
- auto *msg = ev->Get<TEvBlobStorage::TEvControllerConfigRequest>();
- if (msg->SelfHeal) {
- return 1; // locally-generated self-heal commands
- }
- const auto& record = msg->Record;
- const auto& request = record.GetRequest();
- if (request.GetCito()) {
- return 0; // user-generated commands explicitly marked as OOB
- }
- for (const auto& cmd : request.GetCommand()) {
- switch (cmd.GetCommandCase()) {
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineHostConfig:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteHostConfig:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineBox:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteBox:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineStoragePool:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteStoragePool:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateDriveStatus:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kProposeStoragePools:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kMergeBoxes:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kMoveGroups:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kAddMigrationPlan:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteMigrationPlan:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDeclareIntent:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableDonorMode:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kDropDonorDisk:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kSetScrubPeriodicity:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kAddDriveSerial:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kRemoveDriveSerial:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kForgetDriveSerial:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kMigrateToSerial:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kSetPDiskSpaceMarginPromille:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateSettings:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReassignGroupDisk:
- return 2; // read-write commands go with higher priority as they are needed to keep cluster intact
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReadHostConfig:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReadBox:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReadStoragePool:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReadDriveStatus:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kQueryBaseConfig:
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReadIntent:
- case NKikimrBlobStorage::TConfigRequest::TCommand::COMMAND_NOT_SET:
- // handle explicitly these commands to prevent forgetting priority handling when adding a new one
- break;
- }
- }
- return 5; // no read-write commands were in the query, so lower the priority for observation requests
- }
- }
-
- Y_FAIL();
-}
-
-} // NBsController
-
-} // NKikimr
-
-template<>
-void Out<NKikimr::NBsController::TPDiskId>(IOutputStream &str, const NKikimr::NBsController::TPDiskId &value) {
- str << value.ToString();
-}
-
-template<>
+
+ // hive-related commands
+ case TEvBlobStorage::EvControllerSelectGroups: return 4;
+
+ // timers and different observation (also includes RO transactions in TConfigRequest)
+ case TEvPrivate::EvScrub: return 5;
+ case TEvPrivate::EvVSlotReadyUpdate: return 5;
+
+ // external observation and non-latency-bound activities
+ case TEvPrivate::EvUpdateSystemViews: return 10;
+ case TEvBlobStorage::EvControllerUpdateGroupStat: return 10;
+ case TEvControllerCommitGroupLatencies::EventType: return 10;
+ case TEvBlobStorage::EvRequestControllerInfo: return 10;
+ case TEvPrivate::EvUpdateSelfHealCounters: return 10;
+
+ case TEvBlobStorage::EvControllerUpdateDiskStatus: {
+ auto *msg = ev->Get<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
+ const auto& record = msg->Record;
+ for (const auto& item : record.GetVDiskStatus()) {
+ const TVSlotId vslotId(item.GetNodeId(), item.GetPDiskId(), item.GetVSlotId());
+ if (TVSlotInfo *slot = FindVSlot(vslotId); slot && slot->GetStatus() > item.GetStatus()) {
+ return 1;
+ } else if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end() && it->second.VDiskStatus > item.GetStatus()) {
+ return 1;
+ }
+ }
+ return 2;
+ }
+
+ case TEvBlobStorage::EvControllerConfigRequest: {
+ auto *msg = ev->Get<TEvBlobStorage::TEvControllerConfigRequest>();
+ if (msg->SelfHeal) {
+ return 1; // locally-generated self-heal commands
+ }
+ const auto& record = msg->Record;
+ const auto& request = record.GetRequest();
+ if (request.GetCito()) {
+ return 0; // user-generated commands explicitly marked as OOB
+ }
+ for (const auto& cmd : request.GetCommand()) {
+ switch (cmd.GetCommandCase()) {
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineHostConfig:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteHostConfig:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineBox:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteBox:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDefineStoragePool:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteStoragePool:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateDriveStatus:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kProposeStoragePools:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kMergeBoxes:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kMoveGroups:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kAddMigrationPlan:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDeleteMigrationPlan:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDeclareIntent:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableDonorMode:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kDropDonorDisk:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kSetScrubPeriodicity:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kAddDriveSerial:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kRemoveDriveSerial:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kForgetDriveSerial:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kMigrateToSerial:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kSetPDiskSpaceMarginPromille:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateSettings:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReassignGroupDisk:
+ return 2; // read-write commands go with higher priority as they are needed to keep cluster intact
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReadHostConfig:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReadBox:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReadStoragePool:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReadDriveStatus:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kQueryBaseConfig:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReadIntent:
+ case NKikimrBlobStorage::TConfigRequest::TCommand::COMMAND_NOT_SET:
+ // handle explicitly these commands to prevent forgetting priority handling when adding a new one
+ break;
+ }
+ }
+ return 5; // no read-write commands were in the query, so lower the priority for observation requests
+ }
+ }
+
+ Y_FAIL();
+}
+
+} // NBsController
+
+} // NKikimr
+
+template<>
+void Out<NKikimr::NBsController::TPDiskId>(IOutputStream &str, const NKikimr::NBsController::TPDiskId &value) {
+ str << value.ToString();
+}
+
+template<>
void Out<NKikimr::NBsController::TPDiskLocation>(IOutputStream &str, const NKikimr::NBsController::TPDiskLocation &value) {
- str << value.NodeId << ":" << value.Path.Quote();
-}
-
-template<>
-void Out<NKikimr::NBsController::TVSlotId>(IOutputStream &str, const NKikimr::NBsController::TVSlotId &value) {
- str << value.ToString();
+ str << value.NodeId << ":" << value.Path.Quote();
}
template<>
-void Out<NKikimr::NBsController::TResourceNormalizedValues>(IOutputStream &str, const NKikimr::NBsController::TResourceNormalizedValues &value) {
- str << value.ToString();
-}
-
-template<>
-void Out<NKikimr::NBsController::TResourceRawValues>(IOutputStream &str, const NKikimr::NBsController::TResourceRawValues &value) {
- str << value.ToString();
-}
+void Out<NKikimr::NBsController::TVSlotId>(IOutputStream &str, const NKikimr::NBsController::TVSlotId &value) {
+ str << value.ToString();
+}
+
+template<>
+void Out<NKikimr::NBsController::TResourceNormalizedValues>(IOutputStream &str, const NKikimr::NBsController::TResourceNormalizedValues &value) {
+ str << value.ToString();
+}
+
+template<>
+void Out<NKikimr::NBsController::TResourceRawValues>(IOutputStream &str, const NKikimr::NBsController::TResourceRawValues &value) {
+ str << value.ToString();
+}
diff --git a/ydb/core/mind/bscontroller/bsc.h b/ydb/core/mind/bscontroller/bsc.h
index afa641dc094..fd661effcf7 100644
--- a/ydb/core/mind/bscontroller/bsc.h
+++ b/ydb/core/mind/bscontroller/bsc.h
@@ -1,8 +1,8 @@
-#pragma once
-#include "defs.h"
-
-namespace NKikimr {
-
+#pragma once
+#include "defs.h"
+
+namespace NKikimr {
+
IActor* CreateFlatBsController(const TActorId &tablet, TTabletStorageInfo *info);
-
-} //NKikimr
+
+} //NKikimr
diff --git a/ydb/core/mind/bscontroller/cmds_box.cpp b/ydb/core/mind/bscontroller/cmds_box.cpp
index 4555eeea421..2997694f951 100644
--- a/ydb/core/mind/bscontroller/cmds_box.cpp
+++ b/ydb/core/mind/bscontroller/cmds_box.cpp
@@ -1,190 +1,190 @@
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineBox& cmd, TStatus& /*status*/) {
- const TBoxId &id = cmd.GetBoxId();
- const ui64 nextGen = CheckGeneration(cmd, Boxes.Get(), id);
-
- TBoxInfo box;
- box.Name = cmd.GetName();
- box.Generation = nextGen;
- for (const auto &userId : cmd.GetUserId()) {
- box.UserIds.emplace(id, userId);
- }
- for (const auto &host : cmd.GetHost()) {
- TBoxInfo::THostKey hostKey;
- hostKey.BoxId = id;
-
- NKikimrBlobStorage::THostKey key = NormalizeHostKey(host.GetKey());
- hostKey.Fqdn = key.GetFqdn();
- hostKey.IcPort = key.GetIcPort();
-
- TBoxInfo::THostInfo info;
- info.HostConfigId = host.GetHostConfigId();
-
- const auto &hostConfigs = HostConfigs.Get();
- if (!hostConfigs.count(info.HostConfigId)) {
- throw TExHostConfigNotFound(info.HostConfigId);
- }
-
- box.Hosts.emplace(std::move(hostKey), std::move(info));
- }
-
- auto &boxes = Boxes.Unshare();
- boxes[id] = std::move(box);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadBox& cmd, TStatus& status) {
- TSet<TBoxId> queryIds;
- if (cmd.BoxIdSize()) {
- const auto &ids = cmd.GetBoxId();
- queryIds.insert(ids.begin(), ids.end());
- } else {
- for (const auto &kv : Boxes.Get()) {
- queryIds.insert(kv.first);
- }
- }
-
- const auto &boxes = Boxes.Get();
- for (const TBoxId &id : queryIds) {
- auto it = boxes.find(id);
- if (it == boxes.end()) {
- throw TExError() << "BoxId# " << id << " not found";
- }
- Serialize(status.AddBox(), it->first, it->second);
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteBox& cmd, TStatus& /*status*/) {
- const TBoxId &id = cmd.GetBoxId();
- CheckGeneration(cmd, Boxes.Get(), id);
-
- auto &boxes = Boxes.Unshare();
- auto it = boxes.find(id);
- if (it == boxes.end()) {
- throw TExError() << "BoxId# " << id << " not found";
- }
-
- const auto &storagePools = StoragePools.Get();
- using T = std::tuple_element<1, TBoxStoragePoolId>::type;
- const auto min = TBoxStoragePoolId(id, std::numeric_limits<T>::min());
- const auto max = TBoxStoragePoolId(id, std::numeric_limits<T>::max());
- if (storagePools.lower_bound(min) != storagePools.upper_bound(max)) {
- throw TExError() << "BoxId# " << id << " has storage pools";
- }
-
- boxes.erase(it);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TMergeBoxes& cmd, TStatus& /*status*/) {
- auto& boxes = Boxes.Unshare();
-
- auto getBox = [&](ui64 boxId, ui64 boxGeneration, const char *name) -> TBoxInfo& {
- auto it = boxes.find(boxId);
- if (it == boxes.end()) {
- throw TExError() << name << " BoxId# " << boxId << " not found";
- }
- TBoxInfo& box = it->second;
- const ui64 generation = box.Generation.GetOrElse(1);
- if (generation != boxGeneration) {
- throw TExError() << name << " BoxId# " << boxId << " Generation# " << generation
- << " does not match expected Generation# " << boxGeneration;
- }
- box.Generation = generation + 1;
- return box;
- };
-
- TBoxInfo& origin = getBox(cmd.GetOriginBoxId(), cmd.GetOriginBoxGeneration(), "origin");
- TBoxInfo& target = getBox(cmd.GetTargetBoxId(), cmd.GetTargetBoxGeneration(), "target");
-
- while (origin.Hosts) {
- auto node = origin.Hosts.extract(origin.Hosts.begin());
- node.key().BoxId = cmd.GetTargetBoxId();
- if (!target.Hosts.insert(std::move(node)).inserted) {
- throw TExError() << "duplicate hosts in merged box";
- }
- }
-
- // spin the generation
- target.Generation = target.Generation.GetOrElse(1) + 1;
-
- auto& storagePools = StoragePools.Unshare();
- auto& storagePoolGroups = StoragePoolGroups.Unshare();
-
- for (const auto& item : cmd.GetStoragePoolIdMap()) {
- const TBoxStoragePoolId origin(cmd.GetOriginBoxId(), item.GetOriginStoragePoolId());
- auto it = storagePools.find(origin);
- if (it == storagePools.end()) {
- throw TExError() << "origin StoragePoolId# " << origin << " not found";
- }
-
- const TBoxStoragePoolId target(cmd.GetTargetBoxId(), item.GetTargetStoragePoolId());
- if (storagePools.count(target)) {
- throw TExError() << "target StoragePoolId# " << target << " is duplicate";
- }
-
- // update the key for the storage pool; also update PDiskFilters which contain BoxId/StoragePoolId
- auto node = storagePools.extract(it);
- node.key() = target;
- TStoragePoolInfo& sp = node.mapped();
-
- // fix PDisk filters
- TStoragePoolInfo::TPDiskFilters filters;
- while (sp.PDiskFilters) {
- auto node = sp.PDiskFilters.extract(sp.PDiskFilters.begin());
- node.value().BoxId = cmd.GetTargetBoxId();
- node.value().StoragePoolId = item.GetTargetStoragePoolId();
- filters.insert(filters.end(), std::move(node));
- }
- filters.swap(sp.PDiskFilters);
-
- // fix user ids
- TStoragePoolInfo::TUserIds userIds;
- while (sp.UserIds) {
- auto node = sp.UserIds.extract(sp.UserIds.begin());
- node.value() = std::tuple_cat(target, std::tie(std::get<2>(node.value())));
- userIds.insert(userIds.end(), std::move(node));
- }
- userIds.swap(sp.UserIds);
-
- storagePools.insert(std::move(node));
-
- // process storage pool to group mapping
- for (;;) {
- auto node = storagePoolGroups.extract(origin);
- if (node.empty()) {
- break;
- }
-
- // update storage pool id mapping in group itself
- TGroupInfo *group = Groups.FindForUpdate(node.mapped());
- Y_VERIFY(group);
- Y_VERIFY(group->StoragePoolId == origin);
- group->StoragePoolId = target;
-
- // update the key and insert item back into map
- node.key() = target;
- storagePoolGroups.insert(std::move(node));
- }
- }
-
- auto it = storagePools.lower_bound(TBoxStoragePoolId(cmd.GetOriginBoxId(), 0));
- if (it != storagePools.end() && std::get<0>(it->first) == cmd.GetOriginBoxId()) {
- throw TExError() << "not all storage pools from origin Box are enlisted in StoragePoolIdMap field";
- }
-
- // process PDisks of this box
- PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
- if (pdiskInfo.BoxId == cmd.GetOriginBoxId()) {
- TPDiskInfo *mut = PDisks.FindForUpdate(pdiskId);
- Y_VERIFY(mut);
- mut->BoxId = cmd.GetTargetBoxId();
- }
- });
-
- // drop origin box
- boxes.erase(cmd.GetOriginBoxId());
- }
-
-} // namespace NKikimr::NBsController
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineBox& cmd, TStatus& /*status*/) {
+ const TBoxId &id = cmd.GetBoxId();
+ const ui64 nextGen = CheckGeneration(cmd, Boxes.Get(), id);
+
+ TBoxInfo box;
+ box.Name = cmd.GetName();
+ box.Generation = nextGen;
+ for (const auto &userId : cmd.GetUserId()) {
+ box.UserIds.emplace(id, userId);
+ }
+ for (const auto &host : cmd.GetHost()) {
+ TBoxInfo::THostKey hostKey;
+ hostKey.BoxId = id;
+
+ NKikimrBlobStorage::THostKey key = NormalizeHostKey(host.GetKey());
+ hostKey.Fqdn = key.GetFqdn();
+ hostKey.IcPort = key.GetIcPort();
+
+ TBoxInfo::THostInfo info;
+ info.HostConfigId = host.GetHostConfigId();
+
+ const auto &hostConfigs = HostConfigs.Get();
+ if (!hostConfigs.count(info.HostConfigId)) {
+ throw TExHostConfigNotFound(info.HostConfigId);
+ }
+
+ box.Hosts.emplace(std::move(hostKey), std::move(info));
+ }
+
+ auto &boxes = Boxes.Unshare();
+ boxes[id] = std::move(box);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadBox& cmd, TStatus& status) {
+ TSet<TBoxId> queryIds;
+ if (cmd.BoxIdSize()) {
+ const auto &ids = cmd.GetBoxId();
+ queryIds.insert(ids.begin(), ids.end());
+ } else {
+ for (const auto &kv : Boxes.Get()) {
+ queryIds.insert(kv.first);
+ }
+ }
+
+ const auto &boxes = Boxes.Get();
+ for (const TBoxId &id : queryIds) {
+ auto it = boxes.find(id);
+ if (it == boxes.end()) {
+ throw TExError() << "BoxId# " << id << " not found";
+ }
+ Serialize(status.AddBox(), it->first, it->second);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteBox& cmd, TStatus& /*status*/) {
+ const TBoxId &id = cmd.GetBoxId();
+ CheckGeneration(cmd, Boxes.Get(), id);
+
+ auto &boxes = Boxes.Unshare();
+ auto it = boxes.find(id);
+ if (it == boxes.end()) {
+ throw TExError() << "BoxId# " << id << " not found";
+ }
+
+ const auto &storagePools = StoragePools.Get();
+ using T = std::tuple_element<1, TBoxStoragePoolId>::type;
+ const auto min = TBoxStoragePoolId(id, std::numeric_limits<T>::min());
+ const auto max = TBoxStoragePoolId(id, std::numeric_limits<T>::max());
+ if (storagePools.lower_bound(min) != storagePools.upper_bound(max)) {
+ throw TExError() << "BoxId# " << id << " has storage pools";
+ }
+
+ boxes.erase(it);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TMergeBoxes& cmd, TStatus& /*status*/) {
+ auto& boxes = Boxes.Unshare();
+
+ auto getBox = [&](ui64 boxId, ui64 boxGeneration, const char *name) -> TBoxInfo& {
+ auto it = boxes.find(boxId);
+ if (it == boxes.end()) {
+ throw TExError() << name << " BoxId# " << boxId << " not found";
+ }
+ TBoxInfo& box = it->second;
+ const ui64 generation = box.Generation.GetOrElse(1);
+ if (generation != boxGeneration) {
+ throw TExError() << name << " BoxId# " << boxId << " Generation# " << generation
+ << " does not match expected Generation# " << boxGeneration;
+ }
+ box.Generation = generation + 1;
+ return box;
+ };
+
+ TBoxInfo& origin = getBox(cmd.GetOriginBoxId(), cmd.GetOriginBoxGeneration(), "origin");
+ TBoxInfo& target = getBox(cmd.GetTargetBoxId(), cmd.GetTargetBoxGeneration(), "target");
+
+ while (origin.Hosts) {
+ auto node = origin.Hosts.extract(origin.Hosts.begin());
+ node.key().BoxId = cmd.GetTargetBoxId();
+ if (!target.Hosts.insert(std::move(node)).inserted) {
+ throw TExError() << "duplicate hosts in merged box";
+ }
+ }
+
+ // spin the generation
+ target.Generation = target.Generation.GetOrElse(1) + 1;
+
+ auto& storagePools = StoragePools.Unshare();
+ auto& storagePoolGroups = StoragePoolGroups.Unshare();
+
+ for (const auto& item : cmd.GetStoragePoolIdMap()) {
+ const TBoxStoragePoolId origin(cmd.GetOriginBoxId(), item.GetOriginStoragePoolId());
+ auto it = storagePools.find(origin);
+ if (it == storagePools.end()) {
+ throw TExError() << "origin StoragePoolId# " << origin << " not found";
+ }
+
+ const TBoxStoragePoolId target(cmd.GetTargetBoxId(), item.GetTargetStoragePoolId());
+ if (storagePools.count(target)) {
+ throw TExError() << "target StoragePoolId# " << target << " is duplicate";
+ }
+
+ // update the key for the storage pool; also update PDiskFilters which contain BoxId/StoragePoolId
+ auto node = storagePools.extract(it);
+ node.key() = target;
+ TStoragePoolInfo& sp = node.mapped();
+
+ // fix PDisk filters
+ TStoragePoolInfo::TPDiskFilters filters;
+ while (sp.PDiskFilters) {
+ auto node = sp.PDiskFilters.extract(sp.PDiskFilters.begin());
+ node.value().BoxId = cmd.GetTargetBoxId();
+ node.value().StoragePoolId = item.GetTargetStoragePoolId();
+ filters.insert(filters.end(), std::move(node));
+ }
+ filters.swap(sp.PDiskFilters);
+
+ // fix user ids
+ TStoragePoolInfo::TUserIds userIds;
+ while (sp.UserIds) {
+ auto node = sp.UserIds.extract(sp.UserIds.begin());
+ node.value() = std::tuple_cat(target, std::tie(std::get<2>(node.value())));
+ userIds.insert(userIds.end(), std::move(node));
+ }
+ userIds.swap(sp.UserIds);
+
+ storagePools.insert(std::move(node));
+
+ // process storage pool to group mapping
+ for (;;) {
+ auto node = storagePoolGroups.extract(origin);
+ if (node.empty()) {
+ break;
+ }
+
+ // update storage pool id mapping in group itself
+ TGroupInfo *group = Groups.FindForUpdate(node.mapped());
+ Y_VERIFY(group);
+ Y_VERIFY(group->StoragePoolId == origin);
+ group->StoragePoolId = target;
+
+ // update the key and insert item back into map
+ node.key() = target;
+ storagePoolGroups.insert(std::move(node));
+ }
+ }
+
+ auto it = storagePools.lower_bound(TBoxStoragePoolId(cmd.GetOriginBoxId(), 0));
+ if (it != storagePools.end() && std::get<0>(it->first) == cmd.GetOriginBoxId()) {
+ throw TExError() << "not all storage pools from origin Box are enlisted in StoragePoolIdMap field";
+ }
+
+ // process PDisks of this box
+ PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
+ if (pdiskInfo.BoxId == cmd.GetOriginBoxId()) {
+ TPDiskInfo *mut = PDisks.FindForUpdate(pdiskId);
+ Y_VERIFY(mut);
+ mut->BoxId = cmd.GetTargetBoxId();
+ }
+ });
+
+ // drop origin box
+ boxes.erase(cmd.GetOriginBoxId());
+ }
+
+} // namespace NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/cmds_drive_status.cpp b/ydb/core/mind/bscontroller/cmds_drive_status.cpp
index 8abaaa5979c..3ab9a4c71fd 100644
--- a/ydb/core/mind/bscontroller/cmds_drive_status.cpp
+++ b/ydb/core/mind/bscontroller/cmds_drive_status.cpp
@@ -1,91 +1,91 @@
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TUpdateDriveStatus& cmd, TStatus& /*status*/) {
- const auto& host = NormalizeHostKey(cmd.GetHostKey());
-
- TPDiskId pdiskId;
- if (cmd.GetPDiskId()) {
- if (cmd.GetPath()) {
- throw TExError() << "TUpdateDriveStatus.Path and PDiskId are mutually exclusive";
- }
- pdiskId = TPDiskId(host.GetNodeId(), cmd.GetPDiskId());
- if (!PDisks.Find(pdiskId) || PDisksToRemove.count(pdiskId)) {
- throw TExPDiskNotFound(host, cmd.GetPDiskId(), TString());
- }
- } else {
- const auto it = PDiskLocationMap.find(TPDiskLocation(host.GetNodeId(), cmd.GetPath()));
- if (it != PDiskLocationMap.end() && !PDisksToRemove.count(it->second)) {
- pdiskId = it->second;
- } else {
- throw TExPDiskNotFound(host, 0, cmd.GetPath());
- }
- }
-
- TPDiskInfo *pdisk = PDisks.FindForUpdate(pdiskId);
- if (cmd.GetStatus() != pdisk->Status) {
- const bool wasGoodExpectedStatus = pdisk->HasGoodExpectedStatus();
- pdisk->Status = cmd.GetStatus();
- pdisk->StatusTimestamp = Timestamp;
- if (pdisk->HasGoodExpectedStatus() != wasGoodExpectedStatus) {
- for (const auto& [id, slot] : pdisk->VSlotsOnPDisk) {
- if (slot->Group) {
- TGroupInfo *group = Groups.FindForUpdate(slot->Group->ID);
- group->CalculateGroupStatus();
- }
- }
- }
- }
-
- STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA01, "UpdateDriveStatus",
- (UniqueId, UniqueId),
- (FQDN, host.GetFqdn()),
- (IcPort, host.GetIcPort()),
- (NodeId, host.GetNodeId()),
- (Path, cmd.GetPath()),
- (Status, cmd.GetStatus()));
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadDriveStatus& cmd, TStatus& status) {
- const TString& path = cmd.GetPath();
-
- TPDiskId from = Min<TPDiskId>();
- TPDiskId to = Max<TPDiskId>();
-
- if (cmd.HasHostKey()) {
- const auto& host = NormalizeHostKey(cmd.GetHostKey());
- const TNodeId& nodeId = host.GetNodeId();
- from = TPDiskId::MinForNode(nodeId);
- to = TPDiskId::MaxForNode(nodeId);
- }
-
- PDisks.ForEachInRange(from, to, [&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
- if (!path || path == pdiskInfo.Path) {
- NKikimrBlobStorage::TUpdateDriveStatus *item = status.AddDriveStatus();
- NKikimrBlobStorage::THostKey *host = item->MutableHostKey();
- host->SetFqdn(std::get<0>(pdiskInfo.HostId));
- host->SetIcPort(std::get<1>(pdiskInfo.HostId));
- host->SetNodeId(pdiskId.NodeId);
- item->SetPath(pdiskInfo.Path);
- item->SetStatus(pdiskInfo.Status);
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TUpdateDriveStatus& cmd, TStatus& /*status*/) {
+ const auto& host = NormalizeHostKey(cmd.GetHostKey());
+
+ TPDiskId pdiskId;
+ if (cmd.GetPDiskId()) {
+ if (cmd.GetPath()) {
+ throw TExError() << "TUpdateDriveStatus.Path and PDiskId are mutually exclusive";
+ }
+ pdiskId = TPDiskId(host.GetNodeId(), cmd.GetPDiskId());
+ if (!PDisks.Find(pdiskId) || PDisksToRemove.count(pdiskId)) {
+ throw TExPDiskNotFound(host, cmd.GetPDiskId(), TString());
+ }
+ } else {
+ const auto it = PDiskLocationMap.find(TPDiskLocation(host.GetNodeId(), cmd.GetPath()));
+ if (it != PDiskLocationMap.end() && !PDisksToRemove.count(it->second)) {
+ pdiskId = it->second;
+ } else {
+ throw TExPDiskNotFound(host, 0, cmd.GetPath());
+ }
+ }
+
+ TPDiskInfo *pdisk = PDisks.FindForUpdate(pdiskId);
+ if (cmd.GetStatus() != pdisk->Status) {
+ const bool wasGoodExpectedStatus = pdisk->HasGoodExpectedStatus();
+ pdisk->Status = cmd.GetStatus();
+ pdisk->StatusTimestamp = Timestamp;
+ if (pdisk->HasGoodExpectedStatus() != wasGoodExpectedStatus) {
+ for (const auto& [id, slot] : pdisk->VSlotsOnPDisk) {
+ if (slot->Group) {
+ TGroupInfo *group = Groups.FindForUpdate(slot->Group->ID);
+ group->CalculateGroupStatus();
+ }
+ }
+ }
+ }
+
+ STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA01, "UpdateDriveStatus",
+ (UniqueId, UniqueId),
+ (FQDN, host.GetFqdn()),
+ (IcPort, host.GetIcPort()),
+ (NodeId, host.GetNodeId()),
+ (Path, cmd.GetPath()),
+ (Status, cmd.GetStatus()));
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadDriveStatus& cmd, TStatus& status) {
+ const TString& path = cmd.GetPath();
+
+ TPDiskId from = Min<TPDiskId>();
+ TPDiskId to = Max<TPDiskId>();
+
+ if (cmd.HasHostKey()) {
+ const auto& host = NormalizeHostKey(cmd.GetHostKey());
+ const TNodeId& nodeId = host.GetNodeId();
+ from = TPDiskId::MinForNode(nodeId);
+ to = TPDiskId::MaxForNode(nodeId);
+ }
+
+ PDisks.ForEachInRange(from, to, [&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
+ if (!path || path == pdiskInfo.Path) {
+ NKikimrBlobStorage::TUpdateDriveStatus *item = status.AddDriveStatus();
+ NKikimrBlobStorage::THostKey *host = item->MutableHostKey();
+ host->SetFqdn(std::get<0>(pdiskInfo.HostId));
+ host->SetIcPort(std::get<1>(pdiskInfo.HostId));
+ host->SetNodeId(pdiskId.NodeId);
+ item->SetPath(pdiskInfo.Path);
+ item->SetStatus(pdiskInfo.Status);
item->SetPDiskId(pdiskId.PDiskId);
item->SetSerial(pdiskInfo.ExpectedSerial);
- item->SetStatusChangeTimestamp(pdiskInfo.StatusTimestamp.GetValue());
- }
- return true;
- });
- }
-
+ item->SetStatusChangeTimestamp(pdiskInfo.StatusTimestamp.GetValue());
+ }
+ return true;
+ });
+ }
+
void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TAddDriveSerial& cmd,
TStatus& /*status*/) {
const TString& newSerial = cmd.GetSerial();
Schema::DriveSerial::BoxId::Type boxId = cmd.GetBoxId();
- const TDriveSerialInfo *driveInfo = DrivesSerials.Find(newSerial);
+ const TDriveSerialInfo *driveInfo = DrivesSerials.Find(newSerial);
- if (driveInfo && driveInfo->LifeStage != NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
+ if (driveInfo && driveInfo->LifeStage != NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
throw TExAlready() << "Device with such serial already exists in BSC database and not in lifeStage REMOVED";
}
@@ -109,9 +109,9 @@ namespace NKikimr::NBsController {
if (updatePDiskId) {
// PDisk is defined through HostConfigs, but there may be fictional row in DrivesSerials
// if row is present - delete it
- if (driveInfo) {
- DrivesSerials.DeleteExistingEntry(newSerial);
- driveInfo = nullptr;
+ if (driveInfo) {
+ DrivesSerials.DeleteExistingEntry(newSerial);
+ driveInfo = nullptr;
}
TPDiskInfo *pdiskInfo = PDisks.FindForUpdate(*updatePDiskId);
if (pdiskInfo->ExpectedSerial == newSerial) {
@@ -151,23 +151,23 @@ namespace NKikimr::NBsController {
}
}
- // delete existing entry, if any, but keep its GUID
- std::optional<TMaybe<Schema::DriveSerial::Guid::Type>> guid = driveInfo ? std::make_optional(driveInfo->Guid) : std::nullopt;
- if (driveInfo) {
- DrivesSerials.DeleteExistingEntry(newSerial);
- }
-
- TDriveSerialInfo *driveInfoNew = DrivesSerials.ConstructInplaceNewEntry(newSerial, boxId);
- if (guid) {
- driveInfoNew->Guid = *guid;
+ // delete existing entry, if any, but keep its GUID
+ std::optional<TMaybe<Schema::DriveSerial::Guid::Type>> guid = driveInfo ? std::make_optional(driveInfo->Guid) : std::nullopt;
+ if (driveInfo) {
+ DrivesSerials.DeleteExistingEntry(newSerial);
}
- driveInfoNew->Kind = cmd.GetKind();
- driveInfoNew->PDiskType = cmd.GetPDiskType();
+ TDriveSerialInfo *driveInfoNew = DrivesSerials.ConstructInplaceNewEntry(newSerial, boxId);
+ if (guid) {
+ driveInfoNew->Guid = *guid;
+ }
+
+ driveInfoNew->Kind = cmd.GetKind();
+ driveInfoNew->PDiskType = cmd.GetPDiskType();
TString config;
const bool success = cmd.GetPDiskConfig().SerializeToString(&config);
Y_VERIFY(success);
- driveInfoNew->PDiskConfig = config;
+ driveInfoNew->PDiskConfig = config;
STLOG(PRI_NOTICE, BS_CONTROLLER_AUDIT, BSCA06, "AddDriveSerial", (Serial, newSerial), (BoxId, boxId));
}
@@ -177,7 +177,7 @@ namespace NKikimr::NBsController {
const TString& serial = cmd.GetSerial();
- if (const TDriveSerialInfo *driveInfo = DrivesSerials.Find(serial); !driveInfo) {
+ if (const TDriveSerialInfo *driveInfo = DrivesSerials.Find(serial); !driveInfo) {
// Drive is defined in HostConfigs
//
@@ -225,19 +225,19 @@ namespace NKikimr::NBsController {
// create fictional row in DrivesSerials to be able to reply kAlready for already removed disk
// even if they are defined through HostConfig
- TDriveSerialInfo *driveInfoNew = DrivesSerials.ConstructInplaceNewEntry(serial, pdiskUpdate->BoxId);
- driveInfoNew->Guid = pdiskUpdate->Guid;
- driveInfoNew->Kind = pdiskUpdate->Kind.Kind();
- driveInfoNew->PDiskType = PDiskTypeToPDiskType(pdiskUpdate->Kind.Type());
- driveInfoNew->PDiskConfig = pdiskUpdate->PDiskConfig;
- driveInfoNew->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
+ TDriveSerialInfo *driveInfoNew = DrivesSerials.ConstructInplaceNewEntry(serial, pdiskUpdate->BoxId);
+ driveInfoNew->Guid = pdiskUpdate->Guid;
+ driveInfoNew->Kind = pdiskUpdate->Kind.Kind();
+ driveInfoNew->PDiskType = PDiskTypeToPDiskType(pdiskUpdate->Kind.Type());
+ driveInfoNew->PDiskConfig = pdiskUpdate->PDiskConfig;
+ driveInfoNew->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
} else {
- if (driveInfo->LifeStage == NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
+ if (driveInfo->LifeStage == NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
throw TExAlready() << "Drive is already removed";
}
- if (driveInfo->NodeId && driveInfo->PDiskId) {
- TPDiskId pdiskId(*driveInfo->NodeId, *driveInfo->PDiskId);
+ if (driveInfo->NodeId && driveInfo->PDiskId) {
+ TPDiskId pdiskId(*driveInfo->NodeId, *driveInfo->PDiskId);
if (auto* pdiskInfo = PDisks.Find(pdiskId)) {
if (pdiskInfo->NumActiveSlots) {
throw TExError() << "There are active vdisks on that drive";
@@ -247,10 +247,10 @@ namespace NKikimr::NBsController {
}
}
- TDriveSerialInfo *driveInfoMutable = DrivesSerials.FindForUpdate(serial);
- driveInfoMutable->NodeId.Clear();
- driveInfoMutable->PDiskId.Clear();
- driveInfoMutable->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
+ TDriveSerialInfo *driveInfoMutable = DrivesSerials.FindForUpdate(serial);
+ driveInfoMutable->NodeId.Clear();
+ driveInfoMutable->PDiskId.Clear();
+ driveInfoMutable->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
STLOG(PRI_NOTICE, BS_CONTROLLER_AUDIT, BSCA07, "RemoveDriveSerial", (Serial, serial));
}
@@ -261,12 +261,12 @@ namespace NKikimr::NBsController {
const TString& serial = cmd.GetSerial();
- if (const TDriveSerialInfo *driveInfo = DrivesSerials.Find(serial)) {
- switch (driveInfo->LifeStage) {
+ if (const TDriveSerialInfo *driveInfo = DrivesSerials.Find(serial)) {
+ switch (driveInfo->LifeStage) {
case NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN:
[[fallthrough]];
- case NKikimrBlobStorage::TDriveLifeStage::REMOVED:
- DrivesSerials.DeleteExistingEntry(serial);
+ case NKikimrBlobStorage::TDriveLifeStage::REMOVED:
+ DrivesSerials.DeleteExistingEntry(serial);
break;
default: {
throw TExError() << "Drive not in {NOT_SEEN, REMOVED} lifestage and cannot be forgotten. Remove it first";
@@ -274,7 +274,7 @@ namespace NKikimr::NBsController {
}
}
} else {
- throw TExAlready() << "Drive is unknown for BS_CONTROLLER and cannot be forgotten";
+ throw TExAlready() << "Drive is unknown for BS_CONTROLLER and cannot be forgotten";
}
}
@@ -302,4 +302,4 @@ namespace NKikimr::NBsController {
SerialManagementStage.Unshare() = newStage;
}
-} // NKikimr::NBsController
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/cmds_host_config.cpp b/ydb/core/mind/bscontroller/cmds_host_config.cpp
index bd145d8837a..915aabd42c1 100644
--- a/ydb/core/mind/bscontroller/cmds_host_config.cpp
+++ b/ydb/core/mind/bscontroller/cmds_host_config.cpp
@@ -1,89 +1,89 @@
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineHostConfig& cmd, TStatus& /*status*/) {
- const THostConfigId id = cmd.GetHostConfigId();
- const ui64 nextGen = CheckGeneration(cmd, HostConfigs.Get(), id);
-
- TMaybe<TString> defaultPDiskConfig;
- if (cmd.HasDefaultHostPDiskConfig()) {
- TString config;
- const bool success = cmd.GetDefaultHostPDiskConfig().SerializeToString(&config);
- Y_VERIFY(success);
- defaultPDiskConfig = config;
- }
-
- THostConfigInfo config;
- config.Name = cmd.GetName();
- config.Generation = nextGen;
- for (const auto &drive : cmd.GetDrive()) {
- THostConfigInfo::TDriveInfo driveInfo;
- driveInfo.Type = drive.GetType();
- driveInfo.SharedWithOs = drive.GetSharedWithOs();
- driveInfo.ReadCentric = drive.GetReadCentric();
- driveInfo.Kind = drive.GetKind();
-
- if (drive.HasPDiskConfig()) {
- TString config;
- const bool success = drive.GetPDiskConfig().SerializeToString(&config);
- Y_VERIFY(success);
- driveInfo.PDiskConfig = config;
- } else {
- driveInfo.PDiskConfig = defaultPDiskConfig;
- }
-
- Schema::HostConfigDrive::TKey::Type key(id, drive.GetPath());
- config.Drives.emplace(std::move(key), std::move(driveInfo));
- }
-
- auto &hostConfigs = HostConfigs.Unshare();
- hostConfigs[id] = std::move(config);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadHostConfig& cmd, TStatus& status) {
- TSet<THostConfigId> queryIds;
- if (cmd.HostConfigIdSize()) {
- const auto &ids = cmd.GetHostConfigId();
- queryIds.insert(ids.begin(), ids.end());
- } else {
- for (const auto &kv : HostConfigs.Get()) {
- queryIds.insert(kv.first);
- }
- }
-
- const auto &hostConfigs = HostConfigs.Get();
- for (const THostConfigId &id : queryIds) {
- auto it = hostConfigs.find(id);
- if (it == hostConfigs.end()) {
- throw TExHostConfigNotFound(id);
- }
- Serialize(status.AddHostConfig(), it->first, it->second);
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteHostConfig& cmd, TStatus& /*status*/) {
- const THostConfigId &id = cmd.GetHostConfigId();
- CheckGeneration(cmd, HostConfigs.Get(), id);
-
- // unshare host configs and find the required entry
- auto &hostConfigs = HostConfigs.Unshare();
- auto it = hostConfigs.find(id);
- if (it == hostConfigs.end()) {
- throw TExHostConfigNotFound(id);
- }
-
- // check that this configuration is not used in boxes
- for (const auto &kv : Boxes.Get()) {
- for (const auto &host : kv.second.Hosts) {
- if (id == host.second.HostConfigId) {
- throw TExError() << "HostConfigId# " << id << " is used in BoxId# " << kv.first;
- }
- }
- }
-
- // remove entry from the table
- hostConfigs.erase(it);
- }
-
-} // NKikimr::NBsController
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineHostConfig& cmd, TStatus& /*status*/) {
+ const THostConfigId id = cmd.GetHostConfigId();
+ const ui64 nextGen = CheckGeneration(cmd, HostConfigs.Get(), id);
+
+ TMaybe<TString> defaultPDiskConfig;
+ if (cmd.HasDefaultHostPDiskConfig()) {
+ TString config;
+ const bool success = cmd.GetDefaultHostPDiskConfig().SerializeToString(&config);
+ Y_VERIFY(success);
+ defaultPDiskConfig = config;
+ }
+
+ THostConfigInfo config;
+ config.Name = cmd.GetName();
+ config.Generation = nextGen;
+ for (const auto &drive : cmd.GetDrive()) {
+ THostConfigInfo::TDriveInfo driveInfo;
+ driveInfo.Type = drive.GetType();
+ driveInfo.SharedWithOs = drive.GetSharedWithOs();
+ driveInfo.ReadCentric = drive.GetReadCentric();
+ driveInfo.Kind = drive.GetKind();
+
+ if (drive.HasPDiskConfig()) {
+ TString config;
+ const bool success = drive.GetPDiskConfig().SerializeToString(&config);
+ Y_VERIFY(success);
+ driveInfo.PDiskConfig = config;
+ } else {
+ driveInfo.PDiskConfig = defaultPDiskConfig;
+ }
+
+ Schema::HostConfigDrive::TKey::Type key(id, drive.GetPath());
+ config.Drives.emplace(std::move(key), std::move(driveInfo));
+ }
+
+ auto &hostConfigs = HostConfigs.Unshare();
+ hostConfigs[id] = std::move(config);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadHostConfig& cmd, TStatus& status) {
+ TSet<THostConfigId> queryIds;
+ if (cmd.HostConfigIdSize()) {
+ const auto &ids = cmd.GetHostConfigId();
+ queryIds.insert(ids.begin(), ids.end());
+ } else {
+ for (const auto &kv : HostConfigs.Get()) {
+ queryIds.insert(kv.first);
+ }
+ }
+
+ const auto &hostConfigs = HostConfigs.Get();
+ for (const THostConfigId &id : queryIds) {
+ auto it = hostConfigs.find(id);
+ if (it == hostConfigs.end()) {
+ throw TExHostConfigNotFound(id);
+ }
+ Serialize(status.AddHostConfig(), it->first, it->second);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteHostConfig& cmd, TStatus& /*status*/) {
+ const THostConfigId &id = cmd.GetHostConfigId();
+ CheckGeneration(cmd, HostConfigs.Get(), id);
+
+ // unshare host configs and find the required entry
+ auto &hostConfigs = HostConfigs.Unshare();
+ auto it = hostConfigs.find(id);
+ if (it == hostConfigs.end()) {
+ throw TExHostConfigNotFound(id);
+ }
+
+ // check that this configuration is not used in boxes
+ for (const auto &kv : Boxes.Get()) {
+ for (const auto &host : kv.second.Hosts) {
+ if (id == host.second.HostConfigId) {
+ throw TExError() << "HostConfigId# " << id << " is used in BoxId# " << kv.first;
+ }
+ }
+ }
+
+ // remove entry from the table
+ hostConfigs.erase(it);
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/cmds_storage_pool.cpp b/ydb/core/mind/bscontroller/cmds_storage_pool.cpp
index 7a61ac078ce..a19ca1f3fb6 100644
--- a/ydb/core/mind/bscontroller/cmds_storage_pool.cpp
+++ b/ydb/core/mind/bscontroller/cmds_storage_pool.cpp
@@ -1,551 +1,551 @@
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineStoragePool& cmd, TStatus& status) {
- ui64 storagePoolId = cmd.GetStoragePoolId();
- if (!storagePoolId) {
- ui64 maxPoolId = 0;
-
- // TODO: optimize linear search
-
- const auto &pools = StoragePools.Get();
- for (auto it = pools.lower_bound({cmd.GetBoxId(), 0});
- it != pools.end() && std::get<0>(it->first) == cmd.GetBoxId();
- ++it) {
- const ui64 id = std::get<1>(it->first);
- const TStoragePoolInfo &info = it->second;
-
- if (info.Name == cmd.GetName()) {
- if (!id) {
- throw TExError() << "StoragePoolId# 0 for Name# " << info.Name;
- } else if (storagePoolId) {
- throw TExError() << "Storage pool Name# " << info.Name << " is ambiguous";
- } else {
- storagePoolId = id;
- }
- }
-
- maxPoolId = Max(maxPoolId, id);
- }
-
- if (!storagePoolId) {
- auto& nextStoragePoolId = NextStoragePoolId.Unshare();
- storagePoolId = Max(nextStoragePoolId, maxPoolId + 1);
- status.SetAssignedStoragePoolId(storagePoolId);
- nextStoragePoolId = storagePoolId + 1;
- }
- }
-
- const TBoxStoragePoolId id(cmd.GetBoxId(), storagePoolId);
- const ui64 nextGen = CheckGeneration(cmd, StoragePools.Get(), id);
-
- TStoragePoolInfo storagePool;
- storagePool.Name = cmd.GetName();
- storagePool.Generation = nextGen;
-
- const TString &erasureSpecies = cmd.GetErasureSpecies();
- storagePool.ErasureSpecies = TBlobStorageGroupType::ErasureSpeciesByName(erasureSpecies);
- if (storagePool.ErasureSpecies == TBlobStorageGroupType::ErasureSpeciesCount) {
- throw TExError() << "invalid ErasureSpecies# " << erasureSpecies;
- }
-
- if (cmd.HasGeometry()) {
- const auto &geom = cmd.GetGeometry();
- storagePool.RealmLevelBegin = geom.GetRealmLevelBegin();
- storagePool.RealmLevelEnd = geom.GetRealmLevelEnd();
- storagePool.DomainLevelBegin = geom.GetDomainLevelBegin();
- storagePool.DomainLevelEnd = geom.GetDomainLevelEnd();
- storagePool.NumFailRealms = geom.GetNumFailRealms();
- storagePool.NumFailDomainsPerFailRealm = geom.GetNumFailDomainsPerFailRealm();
- storagePool.NumVDisksPerFailDomain = geom.GetNumVDisksPerFailDomain();
- }
-
- // parse VDisk kind
- {
- const TString &kind = cmd.GetVDiskKind();
- const google::protobuf::EnumDescriptor *descr = NKikimrBlobStorage::TVDiskKind::EVDiskKind_descriptor();
- const google::protobuf::EnumValueDescriptor *value = descr->FindValueByName(kind);
- if (!value) {
- throw TExError() << "invalid VDiskKind# " << kind;
- }
- storagePool.VDiskKind = static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(value->number());
- }
-
- if (cmd.HasUsagePattern()) {
- const auto &usage = cmd.GetUsagePattern();
- storagePool.SpaceBytes = usage.GetSpaceBytes();
- storagePool.WriteIOPS = usage.GetWriteIOPS();
- storagePool.WriteBytesPerSecond = usage.GetWriteBytesPerSecond();
- storagePool.ReadIOPS = usage.GetReadIOPS();
- storagePool.ReadBytesPerSecond = usage.GetReadBytesPerSecond();
- storagePool.InMemCacheBytes = usage.GetInMemCacheBytes();
- }
-
- storagePool.Kind = cmd.GetKind();
- storagePool.NumGroups = cmd.GetNumGroups();
- storagePool.EncryptionMode = cmd.GetEncryptionMode();
- storagePool.RandomizeGroupMapping = cmd.GetRandomizeGroupMapping();
-
- for (const auto &userId : cmd.GetUserId()) {
- storagePool.UserIds.emplace(cmd.GetBoxId(), storagePoolId, userId);
- }
-
- for (const auto &item : cmd.GetPDiskFilter()) {
- TStoragePoolInfo::TPDiskFilter filter;
- filter.BoxId = cmd.GetBoxId();
- filter.StoragePoolId = storagePoolId;
-
- bool hasTypeProperty = false;
-
- for (const auto &property : item.GetProperty()) {
- switch (property.GetPropertyCase()) {
-#define PROPERTY(NAME, PTR) \
- case NKikimrBlobStorage::TPDiskFilter::TRequiredProperty::k ## NAME: { \
- if (filter.NAME) { \
- throw TExError() << #NAME << " already set"; \
- } else { \
- filter.NAME = property.Get ## NAME(); \
- if (bool *p = (PTR)) { \
- *p = true; \
- } \
- continue; \
- } \
- }
-
- PROPERTY(Type, &hasTypeProperty)
- PROPERTY(SharedWithOs, nullptr)
- PROPERTY(ReadCentric, nullptr)
- PROPERTY(Kind, nullptr)
-
- case NKikimrBlobStorage::TPDiskFilter::TRequiredProperty::PROPERTY_NOT_SET:
- throw TExError() << "TPDiskFilter.TRequiredProperty.Property not set";
- }
-
- throw TExError() << "TPDiskFilter.TRequiredProperty.Property has invalid case";
- }
-
- if (!hasTypeProperty) {
- throw TExError() << "TPDiskFilter did not specify Type property";
- }
-
- storagePool.PDiskFilters.insert(std::move(filter));
- }
-
- if (cmd.HasExistingGroups()) {
- throw TExError() << "migration is not supported anymore";
- }
-
- if (cmd.HasScopeId()) {
- const auto& pb = cmd.GetScopeId();
- const TScopeId scopeId(pb.GetX1(), pb.GetX2());
- TKikimrScopeId x(scopeId);
- storagePool.SchemeshardId = x.GetSchemeshardId();
- storagePool.PathItemId = x.GetPathItemId();
- }
-
- const auto& spToGroups = StoragePoolGroups.Get();
- auto r = spToGroups.equal_range(id);
- for (auto it = r.first; it != r.second; ++it) {
- const TGroupInfo *group = Groups.Find(it->second);
- Y_VERIFY(group);
- if (group->ErasureSpecies != storagePool.ErasureSpecies) {
- throw TExError() << "GroupId# " << it->second << " has different erasure species";
- }
- }
-
- auto &storagePools = StoragePools.Unshare();
- storagePools[id] = std::move(storagePool);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadStoragePool& cmd, TStatus& status) {
- const bool queryAllBoxes = cmd.GetBoxId() == Max<TBoxId>();
-
- // create set of allowed storage pool ids to query
- const auto& ids = cmd.GetStoragePoolId();
- THashSet<TBoxStoragePoolId> storagePoolIds;
- if (!ids.empty()) {
- if (queryAllBoxes) {
- throw TExError() << "StoragePoolId may only be specified when BoxId is defined";
- } else {
- for (const auto storagePoolId : ids) {
- storagePoolIds.emplace(cmd.GetBoxId(), storagePoolId);
- }
- }
- }
-
- const auto& names = cmd.GetName();
- THashSet<TString> nameSet(names.begin(), names.end());
-
- // calculate lower and upper bounds for search
- const TBoxStoragePoolId since(queryAllBoxes ? Min<Schema::BoxStoragePool::BoxId::Type>() : cmd.GetBoxId(),
- Min<Schema::BoxStoragePool::StoragePoolId::Type>());
- const TBoxStoragePoolId till(queryAllBoxes ? Max<Schema::BoxStoragePool::BoxId::Type>() : cmd.GetBoxId(),
- Max<Schema::BoxStoragePool::StoragePoolId::Type>());
-
- // iterate through subset and add only requested entities
- const auto &storagePools = StoragePools.Get();
- for (auto it = storagePools.lower_bound(since); it != storagePools.end() && it->first <= till; ++it) {
- if ((!storagePoolIds || storagePoolIds.count(it->first)) && (!nameSet || nameSet.count(it->second.Name))) {
- Serialize(status.AddStoragePool(), it->first, it->second);
- }
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteStoragePool& cmd, TStatus& /*status*/) {
- const TBoxStoragePoolId id(cmd.GetBoxId(), cmd.GetStoragePoolId());
- CheckGeneration(cmd, StoragePools.Get(), id);
- auto &storagePools = StoragePools.Unshare();
- if (!storagePools.erase(id)) {
- throw TExError() << "StoragePoolId# " << id << " not found";
- }
-
- auto &storagePoolGroups = StoragePoolGroups.Unshare();
- auto range = storagePoolGroups.equal_range(id);
- for (auto it = range.first; it != range.second; ++it) {
- const TGroupId groupId = it->second;
- if (const TGroupInfo *groupInfo = Groups.Find(groupId)) {
- for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
- DestroyVSlot(vslot->VSlotId);
- }
- Groups.DeleteExistingEntry(groupId);
- } else {
- throw TExError() << "GroupId# " << groupId << " not found";
- }
- }
- storagePoolGroups.erase(range.first, range.second);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TProposeStoragePools& /*cmd*/,TStatus& status) {
- // first, scan through all existing groups that are not defined as a part of storage pools and check
- // their respective VDisks; as a first step, prepare set of groups inside storage pools
- THashSet<TGroupId> storagePoolGroups;
- for (const auto &kv : StoragePoolGroups.Get()) {
- const bool inserted = storagePoolGroups.insert(kv.second).second;
- Y_VERIFY(inserted);
- }
-
- using TProperties = std::tuple<TBoxId,
- Schema::VSlot::Category::Type,
- Schema::PDisk::SharedWithOs::Type,
- Schema::PDisk::ReadCentric::Type,
- Schema::PDisk::Category::Type,
- Schema::Group::ErasureSpecies::Type>;
-
- THashMap<TProperties, TVector<TGroupId>> groupMap;
-
- // second, scan all groups and check those who are not in SPs
- Groups.ForEach([&](TGroupId groupId, const TGroupInfo& groupInfo) {
- if (storagePoolGroups.count(groupId)) {
- return;
- }
-
- TMaybe<TBoxId> boxId;
- TMaybe<Schema::VSlot::Category::Type> vdiskKind;
- TMaybe<Schema::PDisk::SharedWithOs::Type> sharedWithOs;
- TMaybe<Schema::PDisk::ReadCentric::Type> readCentric;
- TMaybe<Schema::PDisk::Category::Type> category;
-
- for (const TVSlotInfo *vslot : groupInfo.VDisksInGroup) {
- auto updateProperty = [&](auto &dest, const auto &source, const char *name) {
- if (!source) {
- throw TExError() << "GroupId# " << groupId << " VSlot# " << vslot->VSlotId
- << " " << name << " property not set";
- } else if (!dest) {
- dest = *source;
- } else if (*dest != *source) {
- throw TExError() << "GroupId# " << groupId << " VSlot# " << vslot->VSlotId
- << " has different comprising VDisks/PDisks " << name << " property value";
- }
- };
-
- updateProperty(vdiskKind, TMaybe<Schema::VSlot::Category::Type>(vslot->Kind), "VDiskKind");
- updateProperty(sharedWithOs, vslot->PDisk->SharedWithOs, "SharedWithOs");
- updateProperty(readCentric, vslot->PDisk->ReadCentric, "ReadCentric");
- updateProperty(category, TMaybe<Schema::PDisk::Category::Type>(vslot->PDisk->Kind), "PDisk Kind/Type");
-
- // find box that holds this PDisk
- updateProperty(boxId, MakeMaybe(vslot->PDisk->BoxId), "BoxId");
- }
-
- Y_VERIFY(boxId && vdiskKind && sharedWithOs && readCentric && category);
-
- const TProperties key(*boxId, *vdiskKind, *sharedWithOs, *readCentric, *category, groupInfo.ErasureSpecies);
- groupMap[key].push_back(groupId);
- });
-
- THashMap<TBoxId, Schema::BoxStoragePool::StoragePoolId::Type> storagePoolIdPerBox;
- for (const auto &kv : groupMap) {
- TBoxId boxId;
- Schema::VSlot::Category::Type vdiskKind;
- Schema::PDisk::SharedWithOs::Type sharedWithOs;
- Schema::PDisk::ReadCentric::Type readCentric;
- Schema::PDisk::Category::Type pdiskCategory;
- Schema::Group::ErasureSpecies::Type erasure;
- std::tie(boxId, vdiskKind, sharedWithOs, readCentric, pdiskCategory, erasure) = kv.first;
-
- Schema::BoxStoragePool::StoragePoolId::Type storagePoolId = 1;
-
- auto it = storagePoolIdPerBox.find(boxId);
- if (it == storagePoolIdPerBox.end()) {
- const auto &storagePools = StoragePools.Get();
- auto it = storagePools.upper_bound(std::make_tuple(boxId,
- Max<Schema::BoxStoragePool::StoragePoolId::Type>()));
- if (it != storagePools.begin() && std::get<0>((--it)->first) == boxId) {
- storagePoolId = std::get<1>(it->first);
- }
- storagePoolIdPerBox[boxId] = storagePoolId + 1;
- } else {
- storagePoolId = it->second++;
- }
-
- const TPDiskCategory category(pdiskCategory);
-
- TString name = Sprintf("autogenerated %" PRIu64 ":%" PRIu64, boxId, storagePoolId);
-
- auto *sp = status.AddStoragePool();
- sp->SetBoxId(boxId);
- sp->SetStoragePoolId(storagePoolId);
- sp->SetName(name);
- sp->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
- sp->SetVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(vdiskKind));
- sp->SetNumGroups(kv.second.size());
-
- auto *filter = sp->AddPDiskFilter();
- filter->AddProperty()->SetType(PDiskTypeToPDiskType(category.Type()));
- filter->AddProperty()->SetSharedWithOs(sharedWithOs);
- filter->AddProperty()->SetReadCentric(readCentric);
- filter->AddProperty()->SetKind(category.Kind());
-
- auto *existing = sp->MutableExistingGroups();
- for (TGroupId groupId : kv.second) {
- existing->AddGroupId(groupId);
- }
- }
-
- // add any existing storage pools to the resulting set
- NKikimrBlobStorage::TReadStoragePool query;
- query.SetBoxId(Max<ui64>());
- ExecuteStep(query, status);
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReassignGroupDisk& cmd, NKikimrBlobStorage::TConfigResponse::TStatus& /*status*/) {
- // find matching TVSlotInfo entity
- const TVDiskID vdiskId(cmd.GetGroupId(), cmd.GetGroupGeneration(), cmd.GetFailRealmIdx(),
- cmd.GetFailDomainIdx(), cmd.GetVDiskIdx());
-
- TMaybe<TVSlotId> matchingVSlotId;
- VSlots.ForEachInRange({}, {}, [&](const TVSlotId& vslotId, const TVSlotInfo& vslotInfo) {
- if (!vslotInfo.IsBeingDeleted() && vslotInfo.GetVDiskId() == vdiskId) {
- matchingVSlotId = vslotId;
- return false;
- }
- return true;
- });
- if (!matchingVSlotId) {
- throw TExError() << "VDisk# " << vdiskId.ToString() << " not found";
- }
-
- // update group generation to mark this VSlot being destroyed
- TVSlotInfo *vslotInfo = VSlots.FindForUpdate(*matchingVSlotId);
- TPDiskId targetPDiskId;
- if (cmd.HasTargetPDiskId()) {
- const NKikimrBlobStorage::TPDiskId& proto = cmd.GetTargetPDiskId();
- const TPDiskId pdiskId(proto.GetNodeId(), proto.GetPDiskId());
- if (!PDisks.Find(pdiskId)) {
- throw TExError() << "TargetPDiskId# " << pdiskId.ToString() << " not found";
- }
- targetPDiskId = pdiskId;
- }
- ExplicitReconfigureMap.emplace(vslotInfo->VSlotId, targetPDiskId);
- if (cmd.GetSuppressDonorMode()) {
- SuppressDonorMode.insert(vslotInfo->VSlotId);
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TMoveGroups& cmd, TStatus& /*status*/) {
- auto& storagePools = StoragePools.Unshare();
-
- const TBoxStoragePoolId originId(cmd.GetBoxId(), cmd.GetOriginStoragePoolId());
- const TBoxStoragePoolId targetId(cmd.GetBoxId(), cmd.GetTargetStoragePoolId());
-
- auto getPool = [&](TBoxStoragePoolId poolId, ui64 poolGeneration, const char *name) -> TStoragePoolInfo& {
- if (auto it = storagePools.find(poolId); it != storagePools.end()) {
- TStoragePoolInfo& pool = it->second;
- const ui64 generation = pool.Generation.GetOrElse(1);
- if (generation != poolGeneration) {
- throw TExError() << name << " StoragePoolId# " << poolId << " Generation# " << generation
- << " does not match expected Generation# " << poolGeneration;
- }
- pool.Generation = generation + 1;
- return pool;
- } else {
- throw TExError() << name << " StoragePoolId# " << poolId << " not found";
- }
- };
-
- // find the origin and the target storage pools
- TStoragePoolInfo& origin = getPool(originId, cmd.GetOriginStoragePoolGeneration(), "origin");
- TStoragePoolInfo& target = getPool(targetId, cmd.GetTargetStoragePoolGeneration(), "target");
-
- auto& storagePoolGroups = StoragePoolGroups.Unshare();
-
- // create a list of groups to be moved
- const auto& m = cmd.GetExplicitGroupId();
- TVector<TGroupId> groups(m.begin(), m.end());
- if (!groups) {
- for (auto it = storagePoolGroups.lower_bound(originId); it != storagePoolGroups.end() && it->first == originId; ++it) {
- groups.push_back(it->second);
- }
- }
-
- for (TGroupId groupId : groups) {
- // find the group belonging to the origin storage pool and remove it from the multimap
- auto p = storagePoolGroups.equal_range(originId);
- if (auto it = std::find(p.first, p.second, TMultiMap<TBoxStoragePoolId, TGroupId>::value_type(originId, groupId)); it != p.second) {
- storagePoolGroups.erase(it);
- } else {
- throw TExError() << "GroupId# " << groupId << " not found in origin StoragePoolId# " << originId;
- }
-
- // make group belonging to the target storage pool
- storagePoolGroups.emplace(targetId, groupId);
-
- // find the group
- TGroupInfo *group = Groups.FindForUpdate(groupId);
-
- // internal consistency checks
- Y_VERIFY(group);
- Y_VERIFY(group->StoragePoolId == originId);
-
- // update the pool id of the group
- group->StoragePoolId = targetId;
-
- // correct the number of groups in the pools
- --origin.NumGroups;
- ++target.NumGroups;
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TQueryBaseConfig& /*cmd*/, TStatus& status) {
- NKikimrBlobStorage::TBaseConfig *pb = status.MutableBaseConfig();
- PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
- Serialize(pb->AddPDisk(), pdiskId, pdiskInfo);
- });
- auto vslotFinder = [this](const TVSlotId& vslotId, const std::function<void(const TVSlotInfo&)>& callback) {
- if (const TVSlotInfo *vslot = VSlots.Find(vslotId)) {
- callback(*vslot);
- }
- };
- VSlots.ForEach([pb, &vslotFinder](const TVSlotId& /*vslotId*/, const TVSlotInfo& vslotInfo) {
- if (vslotInfo.Group) {
- Serialize(pb->AddVSlot(), vslotInfo, vslotFinder);
- }
- });
- Groups.ForEach([pb](TGroupId /*groupId*/, const TGroupInfo& groupInfo) {
- Serialize(pb->AddGroup(), groupInfo);
- });
-
- // apply static group
- for (const auto& [pdiskId, pdisk] : StaticPDisks) {
- if (PDisks.Find(pdiskId)) {
- continue; // this pdisk was already reported
- }
- auto *x = pb->AddPDisk();
- x->SetNodeId(pdisk.NodeId);
- x->SetPDiskId(pdisk.PDiskId);
- x->SetPath(pdisk.Path);
- x->SetType(PDiskTypeToPDiskType(pdisk.Category.Type()));
- x->SetKind(pdisk.Category.Kind());
- if (pdisk.PDiskConfig) {
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDefineStoragePool& cmd, TStatus& status) {
+ ui64 storagePoolId = cmd.GetStoragePoolId();
+ if (!storagePoolId) {
+ ui64 maxPoolId = 0;
+
+ // TODO: optimize linear search
+
+ const auto &pools = StoragePools.Get();
+ for (auto it = pools.lower_bound({cmd.GetBoxId(), 0});
+ it != pools.end() && std::get<0>(it->first) == cmd.GetBoxId();
+ ++it) {
+ const ui64 id = std::get<1>(it->first);
+ const TStoragePoolInfo &info = it->second;
+
+ if (info.Name == cmd.GetName()) {
+ if (!id) {
+ throw TExError() << "StoragePoolId# 0 for Name# " << info.Name;
+ } else if (storagePoolId) {
+ throw TExError() << "Storage pool Name# " << info.Name << " is ambiguous";
+ } else {
+ storagePoolId = id;
+ }
+ }
+
+ maxPoolId = Max(maxPoolId, id);
+ }
+
+ if (!storagePoolId) {
+ auto& nextStoragePoolId = NextStoragePoolId.Unshare();
+ storagePoolId = Max(nextStoragePoolId, maxPoolId + 1);
+ status.SetAssignedStoragePoolId(storagePoolId);
+ nextStoragePoolId = storagePoolId + 1;
+ }
+ }
+
+ const TBoxStoragePoolId id(cmd.GetBoxId(), storagePoolId);
+ const ui64 nextGen = CheckGeneration(cmd, StoragePools.Get(), id);
+
+ TStoragePoolInfo storagePool;
+ storagePool.Name = cmd.GetName();
+ storagePool.Generation = nextGen;
+
+ const TString &erasureSpecies = cmd.GetErasureSpecies();
+ storagePool.ErasureSpecies = TBlobStorageGroupType::ErasureSpeciesByName(erasureSpecies);
+ if (storagePool.ErasureSpecies == TBlobStorageGroupType::ErasureSpeciesCount) {
+ throw TExError() << "invalid ErasureSpecies# " << erasureSpecies;
+ }
+
+ if (cmd.HasGeometry()) {
+ const auto &geom = cmd.GetGeometry();
+ storagePool.RealmLevelBegin = geom.GetRealmLevelBegin();
+ storagePool.RealmLevelEnd = geom.GetRealmLevelEnd();
+ storagePool.DomainLevelBegin = geom.GetDomainLevelBegin();
+ storagePool.DomainLevelEnd = geom.GetDomainLevelEnd();
+ storagePool.NumFailRealms = geom.GetNumFailRealms();
+ storagePool.NumFailDomainsPerFailRealm = geom.GetNumFailDomainsPerFailRealm();
+ storagePool.NumVDisksPerFailDomain = geom.GetNumVDisksPerFailDomain();
+ }
+
+ // parse VDisk kind
+ {
+ const TString &kind = cmd.GetVDiskKind();
+ const google::protobuf::EnumDescriptor *descr = NKikimrBlobStorage::TVDiskKind::EVDiskKind_descriptor();
+ const google::protobuf::EnumValueDescriptor *value = descr->FindValueByName(kind);
+ if (!value) {
+ throw TExError() << "invalid VDiskKind# " << kind;
+ }
+ storagePool.VDiskKind = static_cast<NKikimrBlobStorage::TVDiskKind::EVDiskKind>(value->number());
+ }
+
+ if (cmd.HasUsagePattern()) {
+ const auto &usage = cmd.GetUsagePattern();
+ storagePool.SpaceBytes = usage.GetSpaceBytes();
+ storagePool.WriteIOPS = usage.GetWriteIOPS();
+ storagePool.WriteBytesPerSecond = usage.GetWriteBytesPerSecond();
+ storagePool.ReadIOPS = usage.GetReadIOPS();
+ storagePool.ReadBytesPerSecond = usage.GetReadBytesPerSecond();
+ storagePool.InMemCacheBytes = usage.GetInMemCacheBytes();
+ }
+
+ storagePool.Kind = cmd.GetKind();
+ storagePool.NumGroups = cmd.GetNumGroups();
+ storagePool.EncryptionMode = cmd.GetEncryptionMode();
+ storagePool.RandomizeGroupMapping = cmd.GetRandomizeGroupMapping();
+
+ for (const auto &userId : cmd.GetUserId()) {
+ storagePool.UserIds.emplace(cmd.GetBoxId(), storagePoolId, userId);
+ }
+
+ for (const auto &item : cmd.GetPDiskFilter()) {
+ TStoragePoolInfo::TPDiskFilter filter;
+ filter.BoxId = cmd.GetBoxId();
+ filter.StoragePoolId = storagePoolId;
+
+ bool hasTypeProperty = false;
+
+ for (const auto &property : item.GetProperty()) {
+ switch (property.GetPropertyCase()) {
+#define PROPERTY(NAME, PTR) \
+ case NKikimrBlobStorage::TPDiskFilter::TRequiredProperty::k ## NAME: { \
+ if (filter.NAME) { \
+ throw TExError() << #NAME << " already set"; \
+ } else { \
+ filter.NAME = property.Get ## NAME(); \
+ if (bool *p = (PTR)) { \
+ *p = true; \
+ } \
+ continue; \
+ } \
+ }
+
+ PROPERTY(Type, &hasTypeProperty)
+ PROPERTY(SharedWithOs, nullptr)
+ PROPERTY(ReadCentric, nullptr)
+ PROPERTY(Kind, nullptr)
+
+ case NKikimrBlobStorage::TPDiskFilter::TRequiredProperty::PROPERTY_NOT_SET:
+ throw TExError() << "TPDiskFilter.TRequiredProperty.Property not set";
+ }
+
+ throw TExError() << "TPDiskFilter.TRequiredProperty.Property has invalid case";
+ }
+
+ if (!hasTypeProperty) {
+ throw TExError() << "TPDiskFilter did not specify Type property";
+ }
+
+ storagePool.PDiskFilters.insert(std::move(filter));
+ }
+
+ if (cmd.HasExistingGroups()) {
+ throw TExError() << "migration is not supported anymore";
+ }
+
+ if (cmd.HasScopeId()) {
+ const auto& pb = cmd.GetScopeId();
+ const TScopeId scopeId(pb.GetX1(), pb.GetX2());
+ TKikimrScopeId x(scopeId);
+ storagePool.SchemeshardId = x.GetSchemeshardId();
+ storagePool.PathItemId = x.GetPathItemId();
+ }
+
+ const auto& spToGroups = StoragePoolGroups.Get();
+ auto r = spToGroups.equal_range(id);
+ for (auto it = r.first; it != r.second; ++it) {
+ const TGroupInfo *group = Groups.Find(it->second);
+ Y_VERIFY(group);
+ if (group->ErasureSpecies != storagePool.ErasureSpecies) {
+ throw TExError() << "GroupId# " << it->second << " has different erasure species";
+ }
+ }
+
+ auto &storagePools = StoragePools.Unshare();
+ storagePools[id] = std::move(storagePool);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReadStoragePool& cmd, TStatus& status) {
+ const bool queryAllBoxes = cmd.GetBoxId() == Max<TBoxId>();
+
+ // create set of allowed storage pool ids to query
+ const auto& ids = cmd.GetStoragePoolId();
+ THashSet<TBoxStoragePoolId> storagePoolIds;
+ if (!ids.empty()) {
+ if (queryAllBoxes) {
+ throw TExError() << "StoragePoolId may only be specified when BoxId is defined";
+ } else {
+ for (const auto storagePoolId : ids) {
+ storagePoolIds.emplace(cmd.GetBoxId(), storagePoolId);
+ }
+ }
+ }
+
+ const auto& names = cmd.GetName();
+ THashSet<TString> nameSet(names.begin(), names.end());
+
+ // calculate lower and upper bounds for search
+ const TBoxStoragePoolId since(queryAllBoxes ? Min<Schema::BoxStoragePool::BoxId::Type>() : cmd.GetBoxId(),
+ Min<Schema::BoxStoragePool::StoragePoolId::Type>());
+ const TBoxStoragePoolId till(queryAllBoxes ? Max<Schema::BoxStoragePool::BoxId::Type>() : cmd.GetBoxId(),
+ Max<Schema::BoxStoragePool::StoragePoolId::Type>());
+
+ // iterate through subset and add only requested entities
+ const auto &storagePools = StoragePools.Get();
+ for (auto it = storagePools.lower_bound(since); it != storagePools.end() && it->first <= till; ++it) {
+ if ((!storagePoolIds || storagePoolIds.count(it->first)) && (!nameSet || nameSet.count(it->second.Name))) {
+ Serialize(status.AddStoragePool(), it->first, it->second);
+ }
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDeleteStoragePool& cmd, TStatus& /*status*/) {
+ const TBoxStoragePoolId id(cmd.GetBoxId(), cmd.GetStoragePoolId());
+ CheckGeneration(cmd, StoragePools.Get(), id);
+ auto &storagePools = StoragePools.Unshare();
+ if (!storagePools.erase(id)) {
+ throw TExError() << "StoragePoolId# " << id << " not found";
+ }
+
+ auto &storagePoolGroups = StoragePoolGroups.Unshare();
+ auto range = storagePoolGroups.equal_range(id);
+ for (auto it = range.first; it != range.second; ++it) {
+ const TGroupId groupId = it->second;
+ if (const TGroupInfo *groupInfo = Groups.Find(groupId)) {
+ for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
+ DestroyVSlot(vslot->VSlotId);
+ }
+ Groups.DeleteExistingEntry(groupId);
+ } else {
+ throw TExError() << "GroupId# " << groupId << " not found";
+ }
+ }
+ storagePoolGroups.erase(range.first, range.second);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TProposeStoragePools& /*cmd*/,TStatus& status) {
+ // first, scan through all existing groups that are not defined as a part of storage pools and check
+ // their respective VDisks; as a first step, prepare set of groups inside storage pools
+ THashSet<TGroupId> storagePoolGroups;
+ for (const auto &kv : StoragePoolGroups.Get()) {
+ const bool inserted = storagePoolGroups.insert(kv.second).second;
+ Y_VERIFY(inserted);
+ }
+
+ using TProperties = std::tuple<TBoxId,
+ Schema::VSlot::Category::Type,
+ Schema::PDisk::SharedWithOs::Type,
+ Schema::PDisk::ReadCentric::Type,
+ Schema::PDisk::Category::Type,
+ Schema::Group::ErasureSpecies::Type>;
+
+ THashMap<TProperties, TVector<TGroupId>> groupMap;
+
+ // second, scan all groups and check those who are not in SPs
+ Groups.ForEach([&](TGroupId groupId, const TGroupInfo& groupInfo) {
+ if (storagePoolGroups.count(groupId)) {
+ return;
+ }
+
+ TMaybe<TBoxId> boxId;
+ TMaybe<Schema::VSlot::Category::Type> vdiskKind;
+ TMaybe<Schema::PDisk::SharedWithOs::Type> sharedWithOs;
+ TMaybe<Schema::PDisk::ReadCentric::Type> readCentric;
+ TMaybe<Schema::PDisk::Category::Type> category;
+
+ for (const TVSlotInfo *vslot : groupInfo.VDisksInGroup) {
+ auto updateProperty = [&](auto &dest, const auto &source, const char *name) {
+ if (!source) {
+ throw TExError() << "GroupId# " << groupId << " VSlot# " << vslot->VSlotId
+ << " " << name << " property not set";
+ } else if (!dest) {
+ dest = *source;
+ } else if (*dest != *source) {
+ throw TExError() << "GroupId# " << groupId << " VSlot# " << vslot->VSlotId
+ << " has different comprising VDisks/PDisks " << name << " property value";
+ }
+ };
+
+ updateProperty(vdiskKind, TMaybe<Schema::VSlot::Category::Type>(vslot->Kind), "VDiskKind");
+ updateProperty(sharedWithOs, vslot->PDisk->SharedWithOs, "SharedWithOs");
+ updateProperty(readCentric, vslot->PDisk->ReadCentric, "ReadCentric");
+ updateProperty(category, TMaybe<Schema::PDisk::Category::Type>(vslot->PDisk->Kind), "PDisk Kind/Type");
+
+ // find box that holds this PDisk
+ updateProperty(boxId, MakeMaybe(vslot->PDisk->BoxId), "BoxId");
+ }
+
+ Y_VERIFY(boxId && vdiskKind && sharedWithOs && readCentric && category);
+
+ const TProperties key(*boxId, *vdiskKind, *sharedWithOs, *readCentric, *category, groupInfo.ErasureSpecies);
+ groupMap[key].push_back(groupId);
+ });
+
+ THashMap<TBoxId, Schema::BoxStoragePool::StoragePoolId::Type> storagePoolIdPerBox;
+ for (const auto &kv : groupMap) {
+ TBoxId boxId;
+ Schema::VSlot::Category::Type vdiskKind;
+ Schema::PDisk::SharedWithOs::Type sharedWithOs;
+ Schema::PDisk::ReadCentric::Type readCentric;
+ Schema::PDisk::Category::Type pdiskCategory;
+ Schema::Group::ErasureSpecies::Type erasure;
+ std::tie(boxId, vdiskKind, sharedWithOs, readCentric, pdiskCategory, erasure) = kv.first;
+
+ Schema::BoxStoragePool::StoragePoolId::Type storagePoolId = 1;
+
+ auto it = storagePoolIdPerBox.find(boxId);
+ if (it == storagePoolIdPerBox.end()) {
+ const auto &storagePools = StoragePools.Get();
+ auto it = storagePools.upper_bound(std::make_tuple(boxId,
+ Max<Schema::BoxStoragePool::StoragePoolId::Type>()));
+ if (it != storagePools.begin() && std::get<0>((--it)->first) == boxId) {
+ storagePoolId = std::get<1>(it->first);
+ }
+ storagePoolIdPerBox[boxId] = storagePoolId + 1;
+ } else {
+ storagePoolId = it->second++;
+ }
+
+ const TPDiskCategory category(pdiskCategory);
+
+ TString name = Sprintf("autogenerated %" PRIu64 ":%" PRIu64, boxId, storagePoolId);
+
+ auto *sp = status.AddStoragePool();
+ sp->SetBoxId(boxId);
+ sp->SetStoragePoolId(storagePoolId);
+ sp->SetName(name);
+ sp->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
+ sp->SetVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(vdiskKind));
+ sp->SetNumGroups(kv.second.size());
+
+ auto *filter = sp->AddPDiskFilter();
+ filter->AddProperty()->SetType(PDiskTypeToPDiskType(category.Type()));
+ filter->AddProperty()->SetSharedWithOs(sharedWithOs);
+ filter->AddProperty()->SetReadCentric(readCentric);
+ filter->AddProperty()->SetKind(category.Kind());
+
+ auto *existing = sp->MutableExistingGroups();
+ for (TGroupId groupId : kv.second) {
+ existing->AddGroupId(groupId);
+ }
+ }
+
+ // add any existing storage pools to the resulting set
+ NKikimrBlobStorage::TReadStoragePool query;
+ query.SetBoxId(Max<ui64>());
+ ExecuteStep(query, status);
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TReassignGroupDisk& cmd, NKikimrBlobStorage::TConfigResponse::TStatus& /*status*/) {
+ // find matching TVSlotInfo entity
+ const TVDiskID vdiskId(cmd.GetGroupId(), cmd.GetGroupGeneration(), cmd.GetFailRealmIdx(),
+ cmd.GetFailDomainIdx(), cmd.GetVDiskIdx());
+
+ TMaybe<TVSlotId> matchingVSlotId;
+ VSlots.ForEachInRange({}, {}, [&](const TVSlotId& vslotId, const TVSlotInfo& vslotInfo) {
+ if (!vslotInfo.IsBeingDeleted() && vslotInfo.GetVDiskId() == vdiskId) {
+ matchingVSlotId = vslotId;
+ return false;
+ }
+ return true;
+ });
+ if (!matchingVSlotId) {
+ throw TExError() << "VDisk# " << vdiskId.ToString() << " not found";
+ }
+
+ // update group generation to mark this VSlot being destroyed
+ TVSlotInfo *vslotInfo = VSlots.FindForUpdate(*matchingVSlotId);
+ TPDiskId targetPDiskId;
+ if (cmd.HasTargetPDiskId()) {
+ const NKikimrBlobStorage::TPDiskId& proto = cmd.GetTargetPDiskId();
+ const TPDiskId pdiskId(proto.GetNodeId(), proto.GetPDiskId());
+ if (!PDisks.Find(pdiskId)) {
+ throw TExError() << "TargetPDiskId# " << pdiskId.ToString() << " not found";
+ }
+ targetPDiskId = pdiskId;
+ }
+ ExplicitReconfigureMap.emplace(vslotInfo->VSlotId, targetPDiskId);
+ if (cmd.GetSuppressDonorMode()) {
+ SuppressDonorMode.insert(vslotInfo->VSlotId);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TMoveGroups& cmd, TStatus& /*status*/) {
+ auto& storagePools = StoragePools.Unshare();
+
+ const TBoxStoragePoolId originId(cmd.GetBoxId(), cmd.GetOriginStoragePoolId());
+ const TBoxStoragePoolId targetId(cmd.GetBoxId(), cmd.GetTargetStoragePoolId());
+
+ auto getPool = [&](TBoxStoragePoolId poolId, ui64 poolGeneration, const char *name) -> TStoragePoolInfo& {
+ if (auto it = storagePools.find(poolId); it != storagePools.end()) {
+ TStoragePoolInfo& pool = it->second;
+ const ui64 generation = pool.Generation.GetOrElse(1);
+ if (generation != poolGeneration) {
+ throw TExError() << name << " StoragePoolId# " << poolId << " Generation# " << generation
+ << " does not match expected Generation# " << poolGeneration;
+ }
+ pool.Generation = generation + 1;
+ return pool;
+ } else {
+ throw TExError() << name << " StoragePoolId# " << poolId << " not found";
+ }
+ };
+
+ // find the origin and the target storage pools
+ TStoragePoolInfo& origin = getPool(originId, cmd.GetOriginStoragePoolGeneration(), "origin");
+ TStoragePoolInfo& target = getPool(targetId, cmd.GetTargetStoragePoolGeneration(), "target");
+
+ auto& storagePoolGroups = StoragePoolGroups.Unshare();
+
+ // create a list of groups to be moved
+ const auto& m = cmd.GetExplicitGroupId();
+ TVector<TGroupId> groups(m.begin(), m.end());
+ if (!groups) {
+ for (auto it = storagePoolGroups.lower_bound(originId); it != storagePoolGroups.end() && it->first == originId; ++it) {
+ groups.push_back(it->second);
+ }
+ }
+
+ for (TGroupId groupId : groups) {
+ // find the group belonging to the origin storage pool and remove it from the multimap
+ auto p = storagePoolGroups.equal_range(originId);
+ if (auto it = std::find(p.first, p.second, TMultiMap<TBoxStoragePoolId, TGroupId>::value_type(originId, groupId)); it != p.second) {
+ storagePoolGroups.erase(it);
+ } else {
+ throw TExError() << "GroupId# " << groupId << " not found in origin StoragePoolId# " << originId;
+ }
+
+ // make group belonging to the target storage pool
+ storagePoolGroups.emplace(targetId, groupId);
+
+ // find the group
+ TGroupInfo *group = Groups.FindForUpdate(groupId);
+
+ // internal consistency checks
+ Y_VERIFY(group);
+ Y_VERIFY(group->StoragePoolId == originId);
+
+ // update the pool id of the group
+ group->StoragePoolId = targetId;
+
+ // correct the number of groups in the pools
+ --origin.NumGroups;
+ ++target.NumGroups;
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TQueryBaseConfig& /*cmd*/, TStatus& status) {
+ NKikimrBlobStorage::TBaseConfig *pb = status.MutableBaseConfig();
+ PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
+ Serialize(pb->AddPDisk(), pdiskId, pdiskInfo);
+ });
+ auto vslotFinder = [this](const TVSlotId& vslotId, const std::function<void(const TVSlotInfo&)>& callback) {
+ if (const TVSlotInfo *vslot = VSlots.Find(vslotId)) {
+ callback(*vslot);
+ }
+ };
+ VSlots.ForEach([pb, &vslotFinder](const TVSlotId& /*vslotId*/, const TVSlotInfo& vslotInfo) {
+ if (vslotInfo.Group) {
+ Serialize(pb->AddVSlot(), vslotInfo, vslotFinder);
+ }
+ });
+ Groups.ForEach([pb](TGroupId /*groupId*/, const TGroupInfo& groupInfo) {
+ Serialize(pb->AddGroup(), groupInfo);
+ });
+
+ // apply static group
+ for (const auto& [pdiskId, pdisk] : StaticPDisks) {
+ if (PDisks.Find(pdiskId)) {
+ continue; // this pdisk was already reported
+ }
+ auto *x = pb->AddPDisk();
+ x->SetNodeId(pdisk.NodeId);
+ x->SetPDiskId(pdisk.PDiskId);
+ x->SetPath(pdisk.Path);
+ x->SetType(PDiskTypeToPDiskType(pdisk.Category.Type()));
+ x->SetKind(pdisk.Category.Kind());
+ if (pdisk.PDiskConfig) {
bool success = x->MutablePDiskConfig()->ParseFromString(pdisk.PDiskConfig);
Y_VERIFY(success);
- }
- x->SetGuid(pdisk.Guid);
- x->SetNumStaticSlots(pdisk.StaticSlotUsage);
- x->SetDriveStatus(NKikimrBlobStorage::EDriveStatus::ACTIVE);
- x->SetExpectedSlotCount(pdisk.ExpectedSlotCount);
- if (pdisk.PDiskMetrics) {
- x->MutablePDiskMetrics()->CopyFrom(*pdisk.PDiskMetrics);
- x->MutablePDiskMetrics()->ClearPDiskId();
- }
- }
- for (const auto& [vslotId, vslot] : StaticVSlots) {
- auto *x = pb->AddVSlot();
- vslotId.Serialize(x->MutableVSlotId());
- x->SetGroupId(vslot.VDiskId.GroupID);
- x->SetGroupGeneration(vslot.VDiskId.GroupGeneration);
- x->SetFailRealmIdx(vslot.VDiskId.FailRealm);
- x->SetFailDomainIdx(vslot.VDiskId.FailDomain);
- x->SetVDiskIdx(vslot.VDiskId.VDisk);
- if (vslot.VDiskMetrics) {
- x->SetAllocatedSize(vslot.VDiskMetrics->GetAllocatedSize());
- x->MutableVDiskMetrics()->CopyFrom(*vslot.VDiskMetrics);
- x->MutableVDiskMetrics()->ClearVDiskId();
- }
- x->SetStatus(NKikimrBlobStorage::EVDiskStatus_Name(vslot.VDiskStatus));
- }
-
- if (const auto& ss = AppData()->StaticBlobStorageConfig) {
- for (const auto& group : ss->GetGroups()) {
- auto *x = pb->AddGroup();
- x->SetGroupId(group.GetGroupID());
- x->SetGroupGeneration(group.GetGroupGeneration());
- x->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(group.GetErasureSpecies()));
- for (const auto& realm : group.GetRings()) {
- for (const auto& domain : realm.GetFailDomains()) {
- for (const auto& location : domain.GetVDiskLocations()) {
- const TVSlotId vslotId(location.GetNodeID(), location.GetPDiskID(), location.GetVDiskSlotID());
- vslotId.Serialize(x->AddVSlotId());
- }
- }
- }
- }
- }
-
- TMap<TNodeId, NKikimrBlobStorage::TBaseConfig::TNode> nodes;
- for (const auto& [hostId, record] : *HostRecords) {
- TStringStream s;
- std::unordered_map<TString, ui32> map;
- for (const auto& [key, value] : record.Location.GetItems()) {
- Save(&s, static_cast<ui8>(key));
- Save(&s, static_cast<ui32>(map.emplace(value, map.size() + 1).first->second));
- }
-
- auto& node = nodes[record.NodeId];
- node.SetNodeId(record.NodeId);
- node.SetPhysicalLocation(s.Str());
- record.Location.Serialize(node.MutableLocation());
- auto *key = node.MutableHostKey();
- key->SetFqdn(std::get<0>(hostId));
- key->SetIcPort(std::get<1>(hostId));
- }
- for (auto& [nodeId, node] : nodes) {
- pb->AddNode()->Swap(&node);
- }
- }
-
- void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDropDonorDisk& cmd, TStatus& /*status*/) {
- // first, find matching vslot
- const TVSlotId& vslotId = cmd.GetVSlotId();
- const TVSlotInfo *vslot = VSlots.Find(vslotId);
- if (!vslot) {
- throw TExVSlotNotFound(vslotId);
- }
-
- // second, validate vdisk id
- const TVDiskID& vdiskId = VDiskIDFromVDiskID(cmd.GetVDiskId());
- if (vslot->GetVDiskId() != vdiskId) {
- throw TExVDiskIdIncorrect(vdiskId, vslotId);
- }
-
- // check the donor mode
- if (vslot->Mood != TMood::Donor) {
- throw TExDiskIsNotDonor(vslotId, vdiskId);
- }
-
- // commit destruction
- DestroyVSlot(vslotId);
- }
-
-} // NKikimr::NBsController
+ }
+ x->SetGuid(pdisk.Guid);
+ x->SetNumStaticSlots(pdisk.StaticSlotUsage);
+ x->SetDriveStatus(NKikimrBlobStorage::EDriveStatus::ACTIVE);
+ x->SetExpectedSlotCount(pdisk.ExpectedSlotCount);
+ if (pdisk.PDiskMetrics) {
+ x->MutablePDiskMetrics()->CopyFrom(*pdisk.PDiskMetrics);
+ x->MutablePDiskMetrics()->ClearPDiskId();
+ }
+ }
+ for (const auto& [vslotId, vslot] : StaticVSlots) {
+ auto *x = pb->AddVSlot();
+ vslotId.Serialize(x->MutableVSlotId());
+ x->SetGroupId(vslot.VDiskId.GroupID);
+ x->SetGroupGeneration(vslot.VDiskId.GroupGeneration);
+ x->SetFailRealmIdx(vslot.VDiskId.FailRealm);
+ x->SetFailDomainIdx(vslot.VDiskId.FailDomain);
+ x->SetVDiskIdx(vslot.VDiskId.VDisk);
+ if (vslot.VDiskMetrics) {
+ x->SetAllocatedSize(vslot.VDiskMetrics->GetAllocatedSize());
+ x->MutableVDiskMetrics()->CopyFrom(*vslot.VDiskMetrics);
+ x->MutableVDiskMetrics()->ClearVDiskId();
+ }
+ x->SetStatus(NKikimrBlobStorage::EVDiskStatus_Name(vslot.VDiskStatus));
+ }
+
+ if (const auto& ss = AppData()->StaticBlobStorageConfig) {
+ for (const auto& group : ss->GetGroups()) {
+ auto *x = pb->AddGroup();
+ x->SetGroupId(group.GetGroupID());
+ x->SetGroupGeneration(group.GetGroupGeneration());
+ x->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(group.GetErasureSpecies()));
+ for (const auto& realm : group.GetRings()) {
+ for (const auto& domain : realm.GetFailDomains()) {
+ for (const auto& location : domain.GetVDiskLocations()) {
+ const TVSlotId vslotId(location.GetNodeID(), location.GetPDiskID(), location.GetVDiskSlotID());
+ vslotId.Serialize(x->AddVSlotId());
+ }
+ }
+ }
+ }
+ }
+
+ TMap<TNodeId, NKikimrBlobStorage::TBaseConfig::TNode> nodes;
+ for (const auto& [hostId, record] : *HostRecords) {
+ TStringStream s;
+ std::unordered_map<TString, ui32> map;
+ for (const auto& [key, value] : record.Location.GetItems()) {
+ Save(&s, static_cast<ui8>(key));
+ Save(&s, static_cast<ui32>(map.emplace(value, map.size() + 1).first->second));
+ }
+
+ auto& node = nodes[record.NodeId];
+ node.SetNodeId(record.NodeId);
+ node.SetPhysicalLocation(s.Str());
+ record.Location.Serialize(node.MutableLocation());
+ auto *key = node.MutableHostKey();
+ key->SetFqdn(std::get<0>(hostId));
+ key->SetIcPort(std::get<1>(hostId));
+ }
+ for (auto& [nodeId, node] : nodes) {
+ pb->AddNode()->Swap(&node);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ExecuteStep(const NKikimrBlobStorage::TDropDonorDisk& cmd, TStatus& /*status*/) {
+ // first, find matching vslot
+ const TVSlotId& vslotId = cmd.GetVSlotId();
+ const TVSlotInfo *vslot = VSlots.Find(vslotId);
+ if (!vslot) {
+ throw TExVSlotNotFound(vslotId);
+ }
+
+ // second, validate vdisk id
+ const TVDiskID& vdiskId = VDiskIDFromVDiskID(cmd.GetVDiskId());
+ if (vslot->GetVDiskId() != vdiskId) {
+ throw TExVDiskIdIncorrect(vdiskId, vslotId);
+ }
+
+ // check the donor mode
+ if (vslot->Mood != TMood::Donor) {
+ throw TExDiskIsNotDonor(vslotId, vdiskId);
+ }
+
+ // commit destruction
+ DestroyVSlot(vslotId);
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/config.cpp b/ydb/core/mind/bscontroller/config.cpp
index aa7d6efceea..90151293303 100644
--- a/ydb/core/mind/bscontroller/config.cpp
+++ b/ydb/core/mind/bscontroller/config.cpp
@@ -1,929 +1,929 @@
-#include "impl.h"
-#include "config.h"
-#include "diff.h"
-#include "table_merger.h"
-
-namespace NKikimr::NBsController {
-
- class TBlobStorageController::TNodeWardenUpdateNotifier {
- TBlobStorageController *Self;
- TConfigState &State;
- THashMap<TNodeId, NKikimrBlobStorage::TEvControllerNodeServiceSetUpdate> Services;
- THashSet<TPDiskId> DeletedPDiskIds;
-
- public:
- TNodeWardenUpdateNotifier(TBlobStorageController *self, TConfigState &state)
- : Self(self)
- , State(state)
- {}
-
- void Execute(std::deque<std::unique_ptr<IEventHandle>>& outbox) {
- ApplyUpdates();
-
- for (auto &pair : Services) {
- const TNodeId &nodeId = pair.first;
-
- if (TNodeInfo *node = Self->FindNode(nodeId); node && node->IsRegistered) {
- auto event = MakeHolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>();
- auto& record = event->Record;
- pair.second.Swap(&record);
- record.SetStatus(NKikimrProto::OK);
- record.SetNodeID(nodeId);
- record.SetInstanceId(Self->InstanceId);
- record.SetAvailDomain(AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID()));
- outbox.push_back(std::make_unique<IEventHandle>(MakeBlobStorageNodeWardenID(nodeId),
- Self->SelfId(), event.Release()));
- }
- }
- }
-
- private:
- void ApplyUpdates() {
- for (auto&& [base, overlay] : State.PDisks.Diff()) {
- if (!overlay->second) {
- ApplyPDiskDeleted(overlay->first, *base->second);
- } else if (!base) {
- ApplyPDiskCreated(overlay->first, *overlay->second);
- }
- }
- for (auto&& [base, overlay] : State.VSlots.Diff()) {
- if (!overlay->second) {
- ApplyVSlotDeleted(overlay->first, *base->second);
- } else if (!base) {
- ApplyVSlotCreated(overlay->first, *overlay->second);
- } else {
- ApplyVSlotDiff(overlay->first, *base->second, *overlay->second);
- }
- }
- for (auto&& [base, overlay] : State.Groups.Diff()) {
- if (!overlay->second) {
- ApplyGroupDeleted(overlay->first, *base->second);
- } else if (!base) {
- ApplyGroupCreated(overlay->first, *overlay->second);
- } else {
- ApplyGroupDiff(overlay->first, *base->second, *overlay->second);
- }
- }
- }
-
- void ApplyPDiskCreated(const TPDiskId &pdiskId, const TPDiskInfo &pdiskInfo) {
- const TPDiskLocation location(pdiskId.NodeId, pdiskInfo.Path);
- if (!State.StaticPDisks.count(pdiskId)) {
- // don't create static PDisks as they are already created
- NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = CreatePDiskEntry(pdiskId, pdiskInfo);
- pdisk->SetEntityStatus(NKikimrBlobStorage::CREATE);
- }
- }
-
- void ApplyPDiskDeleted(const TPDiskId &pdiskId, const TPDiskInfo &pdiskInfo) {
- DeletedPDiskIds.insert(pdiskId);
- const TNodeId nodeId = pdiskId.NodeId;
- const TPDiskLocation location(nodeId, pdiskInfo.Path);
- if (!State.StaticPDisks.count(pdiskId)) {
- NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = CreatePDiskEntry(pdiskId, pdiskInfo);
- pdisk->SetEntityStatus(NKikimrBlobStorage::DESTROY);
- }
- }
-
- NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *CreatePDiskEntry(const TPDiskId &fullPDiskId,
- const TPDiskInfo &pdiskInfo) {
- const ui32 nodeId = fullPDiskId.NodeId;
- const ui32 pdiskId = fullPDiskId.PDiskId;
-
- NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[nodeId].MutableServiceSet();
- NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = service.AddPDisks();
- pdisk->SetNodeID(nodeId);
- pdisk->SetPDiskID(pdiskId);
+#include "impl.h"
+#include "config.h"
+#include "diff.h"
+#include "table_merger.h"
+
+namespace NKikimr::NBsController {
+
+ class TBlobStorageController::TNodeWardenUpdateNotifier {
+ TBlobStorageController *Self;
+ TConfigState &State;
+ THashMap<TNodeId, NKikimrBlobStorage::TEvControllerNodeServiceSetUpdate> Services;
+ THashSet<TPDiskId> DeletedPDiskIds;
+
+ public:
+ TNodeWardenUpdateNotifier(TBlobStorageController *self, TConfigState &state)
+ : Self(self)
+ , State(state)
+ {}
+
+ void Execute(std::deque<std::unique_ptr<IEventHandle>>& outbox) {
+ ApplyUpdates();
+
+ for (auto &pair : Services) {
+ const TNodeId &nodeId = pair.first;
+
+ if (TNodeInfo *node = Self->FindNode(nodeId); node && node->IsRegistered) {
+ auto event = MakeHolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>();
+ auto& record = event->Record;
+ pair.second.Swap(&record);
+ record.SetStatus(NKikimrProto::OK);
+ record.SetNodeID(nodeId);
+ record.SetInstanceId(Self->InstanceId);
+ record.SetAvailDomain(AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID()));
+ outbox.push_back(std::make_unique<IEventHandle>(MakeBlobStorageNodeWardenID(nodeId),
+ Self->SelfId(), event.Release()));
+ }
+ }
+ }
+
+ private:
+ void ApplyUpdates() {
+ for (auto&& [base, overlay] : State.PDisks.Diff()) {
+ if (!overlay->second) {
+ ApplyPDiskDeleted(overlay->first, *base->second);
+ } else if (!base) {
+ ApplyPDiskCreated(overlay->first, *overlay->second);
+ }
+ }
+ for (auto&& [base, overlay] : State.VSlots.Diff()) {
+ if (!overlay->second) {
+ ApplyVSlotDeleted(overlay->first, *base->second);
+ } else if (!base) {
+ ApplyVSlotCreated(overlay->first, *overlay->second);
+ } else {
+ ApplyVSlotDiff(overlay->first, *base->second, *overlay->second);
+ }
+ }
+ for (auto&& [base, overlay] : State.Groups.Diff()) {
+ if (!overlay->second) {
+ ApplyGroupDeleted(overlay->first, *base->second);
+ } else if (!base) {
+ ApplyGroupCreated(overlay->first, *overlay->second);
+ } else {
+ ApplyGroupDiff(overlay->first, *base->second, *overlay->second);
+ }
+ }
+ }
+
+ void ApplyPDiskCreated(const TPDiskId &pdiskId, const TPDiskInfo &pdiskInfo) {
+ const TPDiskLocation location(pdiskId.NodeId, pdiskInfo.Path);
+ if (!State.StaticPDisks.count(pdiskId)) {
+ // don't create static PDisks as they are already created
+ NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = CreatePDiskEntry(pdiskId, pdiskInfo);
+ pdisk->SetEntityStatus(NKikimrBlobStorage::CREATE);
+ }
+ }
+
+ void ApplyPDiskDeleted(const TPDiskId &pdiskId, const TPDiskInfo &pdiskInfo) {
+ DeletedPDiskIds.insert(pdiskId);
+ const TNodeId nodeId = pdiskId.NodeId;
+ const TPDiskLocation location(nodeId, pdiskInfo.Path);
+ if (!State.StaticPDisks.count(pdiskId)) {
+ NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = CreatePDiskEntry(pdiskId, pdiskInfo);
+ pdisk->SetEntityStatus(NKikimrBlobStorage::DESTROY);
+ }
+ }
+
+ NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *CreatePDiskEntry(const TPDiskId &fullPDiskId,
+ const TPDiskInfo &pdiskInfo) {
+ const ui32 nodeId = fullPDiskId.NodeId;
+ const ui32 pdiskId = fullPDiskId.PDiskId;
+
+ NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[nodeId].MutableServiceSet();
+ NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pdisk = service.AddPDisks();
+ pdisk->SetNodeID(nodeId);
+ pdisk->SetPDiskID(pdiskId);
if (pdiskInfo.Path) {
pdisk->SetPath(pdiskInfo.Path);
} else if (pdiskInfo.LastSeenPath) {
pdisk->SetPath(pdiskInfo.LastSeenPath);
}
- pdisk->SetPDiskGuid(pdiskInfo.Guid);
+ pdisk->SetPDiskGuid(pdiskInfo.Guid);
pdisk->SetPDiskCategory(pdiskInfo.Kind.GetRaw());
pdisk->SetExpectedSerial(pdiskInfo.ExpectedSerial);
pdisk->SetManagementStage(Self->SerialManagementStage);
- if (pdiskInfo.PDiskConfig && !pdisk->MutablePDiskConfig()->ParseFromString(pdiskInfo.PDiskConfig)) {
- // TODO(alexvru): report this somehow
- }
+ if (pdiskInfo.PDiskConfig && !pdisk->MutablePDiskConfig()->ParseFromString(pdiskInfo.PDiskConfig)) {
+ // TODO(alexvru): report this somehow
+ }
pdisk->SetSpaceColorBorder(Self->PDiskSpaceColorBorder);
-
- return pdisk;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VSLOT OPERATIONS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void AddVSlotToProtobuf(const TVSlotId &vslotId, const TVSlotInfo &vslotInfo, TMood::EValue mood,
- TMaybe<NKikimrBlobStorage::EEntityStatus> status = Nothing()) {
- NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[vslotId.NodeId].MutableServiceSet();
-
- NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk &item = *service.AddVDisks();
-
- // fill in VDiskID for this new VSlot
- VDiskIDFromVDiskID(vslotInfo.GetVDiskId(), item.MutableVDiskID());
-
- // fill in VDiskLocation
- Serialize(item.MutableVDiskLocation(), vslotInfo);
-
- // set up kind
- item.SetVDiskKind(vslotInfo.Kind);
-
- // set destroy/donor flag if needed
- switch (mood) {
- case TMood::Delete:
- item.SetDoDestroy(true);
- item.SetEntityStatus(NKikimrBlobStorage::DESTROY); // set explicitly
- Y_VERIFY(!status);
- break;
-
- case TMood::Donor:
- Y_VERIFY(!status);
- break;
-
- case TMood::Normal:
- if (status) {
- item.SetEntityStatus(*status);
- }
- break;
-
- default:
- Y_FAIL();
- }
-
- if (const TGroupInfo *group = State.Groups.Find(vslotInfo.GroupId); group && mood != TMood::Delete) {
- item.SetStoragePoolName(State.StoragePools.Get().at(group->StoragePoolId).Name);
- SerializeDonors(&item, vslotInfo, *group);
- } else {
- Y_VERIFY(mood != TMood::Donor);
- }
- }
-
- void ApplyVSlotCreated(const TVSlotId &vslotId, const TVSlotInfo &vslotInfo) {
- AddVSlotToProtobuf(vslotId, vslotInfo, TMood::Normal, NKikimrBlobStorage::CREATE);
- }
-
- void ApplyVSlotDeleted(const TVSlotId& vslotId, const TVSlotInfo& vslotInfo) {
- if (DeletedPDiskIds.count(vslotId.ComprisingPDiskId()) && vslotInfo.IsBeingDeleted()) {
- // the slot has been deleted along with its PDisk; although it is useless to slay slots over PDisk
- // that is being stopped, we issue this command to terminate VDisk actors correctly
- AddVSlotToProtobuf(vslotId, vslotInfo, TMood::Delete);
- }
- }
-
- void ApplyVSlotDiff(const TVSlotId &vslotId, const TVSlotInfo &prev, const TVSlotInfo &cur) {
- if (!prev.IsBeingDeleted() && cur.IsBeingDeleted()) {
- // the slot has started deletion during this update
- AddVSlotToProtobuf(vslotId, prev, TMood::Delete);
- } else if (prev.Mood != TMood::Donor && cur.Mood == TMood::Donor) {
- // the slot has became a donor
- AddVSlotToProtobuf(vslotId, cur, TMood::Donor);
- } else if (prev.GroupGeneration != cur.GroupGeneration) {
- // the slot generation has changed
- AddVSlotToProtobuf(vslotId, cur, TMood::Normal);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // GROUP OPERATIONS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void ApplyGroupCreated(const TGroupId& /*groupId*/, const TGroupInfo &groupInfo) {
- // create ordered map of VDisk entries for group
- THashSet<TNodeId> nodes;
- for (const TVSlotInfo *vslot : groupInfo.VDisksInGroup) {
- Y_VERIFY(vslot->GroupGeneration == groupInfo.Generation);
- nodes.insert(vslot->VSlotId.NodeId);
- }
-
- // check tenant id, if necessary
- TMaybe<TKikimrScopeId> scopeId;
- const TStoragePoolInfo& info = State.StoragePools.Get().at(groupInfo.StoragePoolId);
- if (info.SchemeshardId && info.PathItemId) {
- scopeId = TKikimrScopeId(*info.SchemeshardId, *info.PathItemId);
- } else {
- Y_VERIFY(!info.SchemeshardId && !info.PathItemId);
- }
- const TString storagePoolName = info.Name;
-
- // push group information to each node that will receive VDisk status update
- for (TNodeId nodeId : nodes) {
- NKikimrBlobStorage::TNodeWardenServiceSet *service = Services[nodeId].MutableServiceSet();
- SerializeGroupInfo(service->AddGroups(), groupInfo, storagePoolName, scopeId);
- }
- }
-
- void ApplyGroupDeleted(const TGroupId &groupId, const TGroupInfo& /*groupInfo*/) {
- for (const auto &kv : State.Nodes.Get()) {
- const TNodeId nodeId = kv.first;
- NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[nodeId].MutableServiceSet();
- NKikimrBlobStorage::TGroupInfo &item = *service.AddGroups();
- item.SetGroupID(groupId);
- item.SetEntityStatus(NKikimrBlobStorage::DESTROY);
- }
- }
-
- void ApplyGroupDiff(const TGroupId &groupId, const TGroupInfo &prev, const TGroupInfo &cur) {
- if (prev.Generation != cur.Generation) {
- ApplyGroupCreated(groupId, cur);
- for (const auto& [key, info] : *State.HostRecords) {
- auto *meta = Services[info.NodeId].AddGroupMetadata();
- meta->SetGroupId(groupId);
- meta->SetCurrentGeneration(cur.Generation);
- }
- }
- Y_VERIFY(prev.VDisksInGroup.size() == cur.VDisksInGroup.size());
- for (size_t i = 0; i < prev.VDisksInGroup.size(); ++i) {
- const TVSlotInfo& prevSlot = *prev.VDisksInGroup[i];
- const TVSlotInfo& curSlot = *cur.VDisksInGroup[i];
- if (prevSlot.VSlotId != curSlot.VSlotId) {
- STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA05, "VDisk moved",
- (UniqueId, State.UniqueId),
- (PrevSlot, prevSlot.VSlotId),
- (CurSlot, curSlot.VSlotId),
- (VDiskId, curSlot.GetVDiskId()));
- }
- }
- }
- };
-
- bool TBlobStorageController::CommitConfigUpdates(TConfigState& state, bool suppressFailModelChecking,
- bool suppressDegradedGroupsChecking, TTransactionContext& txc, TString *errorDescription) {
- NIceDb::TNiceDb db(txc.DB);
-
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- if (base && overlay->second && std::exchange(overlay->second->ContentChanged, false)) {
- const auto& groupInfo = overlay->second;
- ++groupInfo->Generation;
- for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
- if (slot->GroupGeneration != groupInfo->Generation) {
- TVSlotInfo *mutableSlot = state.VSlots.FindForUpdate(slot->VSlotId);
- Y_VERIFY(mutableSlot);
- mutableSlot->GroupGeneration = groupInfo->Generation;
- }
- }
- }
- }
-
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- if (base && overlay->second) {
- const TGroupInfo::TGroupStatus& prev = base->second->Status;
- const TGroupInfo::TGroupStatus& status = overlay->second->Status;
+
+ return pdisk;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VSLOT OPERATIONS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void AddVSlotToProtobuf(const TVSlotId &vslotId, const TVSlotInfo &vslotInfo, TMood::EValue mood,
+ TMaybe<NKikimrBlobStorage::EEntityStatus> status = Nothing()) {
+ NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[vslotId.NodeId].MutableServiceSet();
+
+ NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk &item = *service.AddVDisks();
+
+ // fill in VDiskID for this new VSlot
+ VDiskIDFromVDiskID(vslotInfo.GetVDiskId(), item.MutableVDiskID());
+
+ // fill in VDiskLocation
+ Serialize(item.MutableVDiskLocation(), vslotInfo);
+
+ // set up kind
+ item.SetVDiskKind(vslotInfo.Kind);
+
+ // set destroy/donor flag if needed
+ switch (mood) {
+ case TMood::Delete:
+ item.SetDoDestroy(true);
+ item.SetEntityStatus(NKikimrBlobStorage::DESTROY); // set explicitly
+ Y_VERIFY(!status);
+ break;
+
+ case TMood::Donor:
+ Y_VERIFY(!status);
+ break;
+
+ case TMood::Normal:
+ if (status) {
+ item.SetEntityStatus(*status);
+ }
+ break;
+
+ default:
+ Y_FAIL();
+ }
+
+ if (const TGroupInfo *group = State.Groups.Find(vslotInfo.GroupId); group && mood != TMood::Delete) {
+ item.SetStoragePoolName(State.StoragePools.Get().at(group->StoragePoolId).Name);
+ SerializeDonors(&item, vslotInfo, *group);
+ } else {
+ Y_VERIFY(mood != TMood::Donor);
+ }
+ }
+
+ void ApplyVSlotCreated(const TVSlotId &vslotId, const TVSlotInfo &vslotInfo) {
+ AddVSlotToProtobuf(vslotId, vslotInfo, TMood::Normal, NKikimrBlobStorage::CREATE);
+ }
+
+ void ApplyVSlotDeleted(const TVSlotId& vslotId, const TVSlotInfo& vslotInfo) {
+ if (DeletedPDiskIds.count(vslotId.ComprisingPDiskId()) && vslotInfo.IsBeingDeleted()) {
+ // the slot has been deleted along with its PDisk; although it is useless to slay slots over PDisk
+ // that is being stopped, we issue this command to terminate VDisk actors correctly
+ AddVSlotToProtobuf(vslotId, vslotInfo, TMood::Delete);
+ }
+ }
+
+ void ApplyVSlotDiff(const TVSlotId &vslotId, const TVSlotInfo &prev, const TVSlotInfo &cur) {
+ if (!prev.IsBeingDeleted() && cur.IsBeingDeleted()) {
+ // the slot has started deletion during this update
+ AddVSlotToProtobuf(vslotId, prev, TMood::Delete);
+ } else if (prev.Mood != TMood::Donor && cur.Mood == TMood::Donor) {
+ // the slot has became a donor
+ AddVSlotToProtobuf(vslotId, cur, TMood::Donor);
+ } else if (prev.GroupGeneration != cur.GroupGeneration) {
+ // the slot generation has changed
+ AddVSlotToProtobuf(vslotId, cur, TMood::Normal);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GROUP OPERATIONS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void ApplyGroupCreated(const TGroupId& /*groupId*/, const TGroupInfo &groupInfo) {
+ // create ordered map of VDisk entries for group
+ THashSet<TNodeId> nodes;
+ for (const TVSlotInfo *vslot : groupInfo.VDisksInGroup) {
+ Y_VERIFY(vslot->GroupGeneration == groupInfo.Generation);
+ nodes.insert(vslot->VSlotId.NodeId);
+ }
+
+ // check tenant id, if necessary
+ TMaybe<TKikimrScopeId> scopeId;
+ const TStoragePoolInfo& info = State.StoragePools.Get().at(groupInfo.StoragePoolId);
+ if (info.SchemeshardId && info.PathItemId) {
+ scopeId = TKikimrScopeId(*info.SchemeshardId, *info.PathItemId);
+ } else {
+ Y_VERIFY(!info.SchemeshardId && !info.PathItemId);
+ }
+ const TString storagePoolName = info.Name;
+
+ // push group information to each node that will receive VDisk status update
+ for (TNodeId nodeId : nodes) {
+ NKikimrBlobStorage::TNodeWardenServiceSet *service = Services[nodeId].MutableServiceSet();
+ SerializeGroupInfo(service->AddGroups(), groupInfo, storagePoolName, scopeId);
+ }
+ }
+
+ void ApplyGroupDeleted(const TGroupId &groupId, const TGroupInfo& /*groupInfo*/) {
+ for (const auto &kv : State.Nodes.Get()) {
+ const TNodeId nodeId = kv.first;
+ NKikimrBlobStorage::TNodeWardenServiceSet &service = *Services[nodeId].MutableServiceSet();
+ NKikimrBlobStorage::TGroupInfo &item = *service.AddGroups();
+ item.SetGroupID(groupId);
+ item.SetEntityStatus(NKikimrBlobStorage::DESTROY);
+ }
+ }
+
+ void ApplyGroupDiff(const TGroupId &groupId, const TGroupInfo &prev, const TGroupInfo &cur) {
+ if (prev.Generation != cur.Generation) {
+ ApplyGroupCreated(groupId, cur);
+ for (const auto& [key, info] : *State.HostRecords) {
+ auto *meta = Services[info.NodeId].AddGroupMetadata();
+ meta->SetGroupId(groupId);
+ meta->SetCurrentGeneration(cur.Generation);
+ }
+ }
+ Y_VERIFY(prev.VDisksInGroup.size() == cur.VDisksInGroup.size());
+ for (size_t i = 0; i < prev.VDisksInGroup.size(); ++i) {
+ const TVSlotInfo& prevSlot = *prev.VDisksInGroup[i];
+ const TVSlotInfo& curSlot = *cur.VDisksInGroup[i];
+ if (prevSlot.VSlotId != curSlot.VSlotId) {
+ STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA05, "VDisk moved",
+ (UniqueId, State.UniqueId),
+ (PrevSlot, prevSlot.VSlotId),
+ (CurSlot, curSlot.VSlotId),
+ (VDiskId, curSlot.GetVDiskId()));
+ }
+ }
+ }
+ };
+
+ bool TBlobStorageController::CommitConfigUpdates(TConfigState& state, bool suppressFailModelChecking,
+ bool suppressDegradedGroupsChecking, TTransactionContext& txc, TString *errorDescription) {
+ NIceDb::TNiceDb db(txc.DB);
+
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ if (base && overlay->second && std::exchange(overlay->second->ContentChanged, false)) {
+ const auto& groupInfo = overlay->second;
+ ++groupInfo->Generation;
+ for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
+ if (slot->GroupGeneration != groupInfo->Generation) {
+ TVSlotInfo *mutableSlot = state.VSlots.FindForUpdate(slot->VSlotId);
+ Y_VERIFY(mutableSlot);
+ mutableSlot->GroupGeneration = groupInfo->Generation;
+ }
+ }
+ }
+ }
+
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ if (base && overlay->second) {
+ const TGroupInfo::TGroupStatus& prev = base->second->Status;
+ const TGroupInfo::TGroupStatus& status = overlay->second->Status;
if (status.ExpectedStatus == NKikimrBlobStorage::TGroupStatus::DISINTEGRATED &&
- status.ExpectedStatus != prev.ExpectedStatus) { // status did really change
- *errorDescription = TStringBuilder() << "GroupId# " << overlay->first
+ status.ExpectedStatus != prev.ExpectedStatus) { // status did really change
+ *errorDescription = TStringBuilder() << "GroupId# " << overlay->first
<< " ExpectedStatus# DISINTEGRATED";
- return false;
- }
- }
- }
-
- // check that group modification would not degrade failure model
- if (!suppressFailModelChecking) {
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- if (overlay->second && base && base->second->Generation != overlay->second->Generation) {
- // process only groups with changed content; create topology for group
- auto& topology = *overlay->second->Topology;
- // fill in vector of failed disks (that are not fully operational)
- TBlobStorageGroupInfo::TGroupVDisks failed(&topology);
- for (const TVSlotInfo *slot : overlay->second->VDisksInGroup) {
- if (!slot->IsReady) {
- failed |= {&topology, slot->GetShortVDiskId()};
- }
- }
- // check the failure model
- auto& checker = *topology.QuorumChecker;
- if (!checker.CheckFailModelForGroup(failed)) {
- *errorDescription = TStringBuilder() << "GroupId# " << base->first
- << " may lose data while modifying group";
- return false;
- } else if (!suppressDegradedGroupsChecking && checker.IsDegraded(failed)) {
- *errorDescription = TStringBuilder() << "GroupId# " << base->first
- << " may become DEGRADED while modifying group";
- return false;
- }
- }
- }
- }
-
- // trim PDisks awaiting deletion
- for (const TPDiskId& pdiskId : state.PDisksToRemove) {
- TPDiskInfo *pdiskInfo = state.PDisks.FindForUpdate(pdiskId);
- Y_VERIFY(pdiskInfo);
- if (pdiskInfo->NumActiveSlots) {
- *errorDescription = TStringBuilder() << "failed to remove PDisk# " << pdiskId << " as it has active VSlots";
- return false;
- }
- for (const auto& [vslotId, vslot] : std::exchange(pdiskInfo->VSlotsOnPDisk, {})) {
- Y_VERIFY(vslot->IsBeingDeleted());
- state.VSlots.DeleteExistingEntry(TVSlotId(pdiskId, vslotId));
- }
- state.PDisks.DeleteExistingEntry(pdiskId);
- }
-
- MakeTableMerger<Schema::HostConfig>(&HostConfigs, &state.HostConfigs.Get(), this)(txc);
- MakeTableMerger<Schema::Box>(&Boxes, &state.Boxes.Get(), this)(txc);
- MakeTableMerger<Schema::BoxStoragePool>(&StoragePools, &state.StoragePools.Get(), this)(txc);
- MakeTableMerger<Schema::Node>(&Nodes, &state.Nodes.Get(), this)(txc);
-
- // apply overlay maps to their respective tables
- state.PDisks.ApplyToTable(this, txc);
- state.VSlots.ApplyToTable(this, txc);
- state.Groups.ApplyToTable(this, txc);
- state.DrivesSerials.ApplyToTable(this, txc);
-
- // apply group to storage pool mapping
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- using Table = Schema::GroupStoragePool;
- if (!overlay->second) {
- db.Table<Table>().Key(overlay->first).Delete();
- } else if (!base || base->second->StoragePoolId != overlay->second->StoragePoolId) {
- db.Table<Table>().Key(overlay->first).Update<Table::BoxId, Table::StoragePoolId>(
- std::get<0>(overlay->second->StoragePoolId),
- std::get<1>(overlay->second->StoragePoolId));
- }
- }
-
- // trim the PDiskMetrics table
- for (auto&& [base, overlay] : state.PDisks.Diff()) {
- if (!overlay->second) {
- db.Table<Schema::PDiskMetrics>().Key(overlay->first.GetKey()).Delete();
- }
- }
-
- // remove unused group latency and vdisk metrics records
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- if (!overlay->second) {
- const TGroupId groupId = overlay->first;
- db.Table<Schema::GroupLatencies>().Key(groupId).Delete();
- }
- }
-
- // remove unused vdisk metrics for either deleted vslots or with changed generation
- for (auto&& [base, overlay] : state.VSlots.Diff()) {
- if (!overlay->second || (base && overlay->second->GroupGeneration != base->second->GroupGeneration)) {
- const TVDiskID& vdiskId = base->second->GetVDiskId();
- db.Table<Schema::VDiskMetrics>().Key(vdiskId.GroupID, vdiskId.GroupGeneration, vdiskId.FailRealm,
- vdiskId.FailDomain, vdiskId.VDisk).Delete();
- }
- }
-
- // write down NextGroupId if it has changed
- if (state.NextGroupId.Changed()) {
- db.Table<Schema::State>().Key(true).Update<Schema::State::NextGroupID>(state.NextGroupId.Get());
- }
- if (state.NextStoragePoolId.Changed()) {
- db.Table<Schema::State>().Key(true).Update<Schema::State::NextStoragePoolId>(state.NextStoragePoolId.Get());
- }
+ return false;
+ }
+ }
+ }
+
+ // check that group modification would not degrade failure model
+ if (!suppressFailModelChecking) {
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ if (overlay->second && base && base->second->Generation != overlay->second->Generation) {
+ // process only groups with changed content; create topology for group
+ auto& topology = *overlay->second->Topology;
+ // fill in vector of failed disks (that are not fully operational)
+ TBlobStorageGroupInfo::TGroupVDisks failed(&topology);
+ for (const TVSlotInfo *slot : overlay->second->VDisksInGroup) {
+ if (!slot->IsReady) {
+ failed |= {&topology, slot->GetShortVDiskId()};
+ }
+ }
+ // check the failure model
+ auto& checker = *topology.QuorumChecker;
+ if (!checker.CheckFailModelForGroup(failed)) {
+ *errorDescription = TStringBuilder() << "GroupId# " << base->first
+ << " may lose data while modifying group";
+ return false;
+ } else if (!suppressDegradedGroupsChecking && checker.IsDegraded(failed)) {
+ *errorDescription = TStringBuilder() << "GroupId# " << base->first
+ << " may become DEGRADED while modifying group";
+ return false;
+ }
+ }
+ }
+ }
+
+ // trim PDisks awaiting deletion
+ for (const TPDiskId& pdiskId : state.PDisksToRemove) {
+ TPDiskInfo *pdiskInfo = state.PDisks.FindForUpdate(pdiskId);
+ Y_VERIFY(pdiskInfo);
+ if (pdiskInfo->NumActiveSlots) {
+ *errorDescription = TStringBuilder() << "failed to remove PDisk# " << pdiskId << " as it has active VSlots";
+ return false;
+ }
+ for (const auto& [vslotId, vslot] : std::exchange(pdiskInfo->VSlotsOnPDisk, {})) {
+ Y_VERIFY(vslot->IsBeingDeleted());
+ state.VSlots.DeleteExistingEntry(TVSlotId(pdiskId, vslotId));
+ }
+ state.PDisks.DeleteExistingEntry(pdiskId);
+ }
+
+ MakeTableMerger<Schema::HostConfig>(&HostConfigs, &state.HostConfigs.Get(), this)(txc);
+ MakeTableMerger<Schema::Box>(&Boxes, &state.Boxes.Get(), this)(txc);
+ MakeTableMerger<Schema::BoxStoragePool>(&StoragePools, &state.StoragePools.Get(), this)(txc);
+ MakeTableMerger<Schema::Node>(&Nodes, &state.Nodes.Get(), this)(txc);
+
+ // apply overlay maps to their respective tables
+ state.PDisks.ApplyToTable(this, txc);
+ state.VSlots.ApplyToTable(this, txc);
+ state.Groups.ApplyToTable(this, txc);
+ state.DrivesSerials.ApplyToTable(this, txc);
+
+ // apply group to storage pool mapping
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ using Table = Schema::GroupStoragePool;
+ if (!overlay->second) {
+ db.Table<Table>().Key(overlay->first).Delete();
+ } else if (!base || base->second->StoragePoolId != overlay->second->StoragePoolId) {
+ db.Table<Table>().Key(overlay->first).Update<Table::BoxId, Table::StoragePoolId>(
+ std::get<0>(overlay->second->StoragePoolId),
+ std::get<1>(overlay->second->StoragePoolId));
+ }
+ }
+
+ // trim the PDiskMetrics table
+ for (auto&& [base, overlay] : state.PDisks.Diff()) {
+ if (!overlay->second) {
+ db.Table<Schema::PDiskMetrics>().Key(overlay->first.GetKey()).Delete();
+ }
+ }
+
+ // remove unused group latency and vdisk metrics records
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ if (!overlay->second) {
+ const TGroupId groupId = overlay->first;
+ db.Table<Schema::GroupLatencies>().Key(groupId).Delete();
+ }
+ }
+
+ // remove unused vdisk metrics for either deleted vslots or with changed generation
+ for (auto&& [base, overlay] : state.VSlots.Diff()) {
+ if (!overlay->second || (base && overlay->second->GroupGeneration != base->second->GroupGeneration)) {
+ const TVDiskID& vdiskId = base->second->GetVDiskId();
+ db.Table<Schema::VDiskMetrics>().Key(vdiskId.GroupID, vdiskId.GroupGeneration, vdiskId.FailRealm,
+ vdiskId.FailDomain, vdiskId.VDisk).Delete();
+ }
+ }
+
+ // write down NextGroupId if it has changed
+ if (state.NextGroupId.Changed()) {
+ db.Table<Schema::State>().Key(true).Update<Schema::State::NextGroupID>(state.NextGroupId.Get());
+ }
+ if (state.NextStoragePoolId.Changed()) {
+ db.Table<Schema::State>().Key(true).Update<Schema::State::NextStoragePoolId>(state.NextStoragePoolId.Get());
+ }
if (state.SerialManagementStage.Changed()) {
- db.Table<Schema::State>().Key(true).Update<Schema::State::SerialManagementStage>(state.SerialManagementStage.Get());
- }
-
- CommitSelfHealUpdates(state);
- CommitScrubUpdates(state, txc);
- CommitStoragePoolStatUpdates(state);
- CommitSysViewUpdates(state);
-
- // remove deleted vslots from VSlotReadyTimestampQ
- for (auto&& [base, overlay] : state.VSlots.Diff()) {
- if (!overlay->second || !overlay->second->Group) { // deleted one
- base->second->DropFromVSlotReadyTimestampQ();
- if (overlay->second) {
- overlay->second->ResetVSlotReadyTimestampIter();
- }
- NotReadyVSlotIds.erase(overlay->first);
- }
- }
-
- TNodeWardenUpdateNotifier(this, state).Execute(state.Outbox);
-
- state.CheckConsistency();
- state.Commit();
-
- return true;
- }
-
- void TBlobStorageController::CommitSelfHealUpdates(TConfigState& state) {
- auto ev = MakeHolder<TEvControllerNotifyGroupChange>();
- auto sh = MakeHolder<TEvControllerUpdateSelfHealInfo>();
-
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- const TGroupId groupId = overlay->first;
- if (!overlay->second) { // item was deleted, drop it from the cache
- const ui32 erased = GroupLookup.erase(groupId);
- Y_VERIFY(erased);
- sh->GroupsToUpdate[groupId].reset();
- ev->Deleted.push_back(groupId);
- } else if (base) { // item was overwritten, just update pointer in the lookup cache
- const auto it = GroupLookup.find(groupId);
- Y_VERIFY(it != GroupLookup.end());
- TGroupInfo *prev = std::exchange(it->second, overlay->second.Get());
- Y_VERIFY(prev == base->second.Get());
- if (base->second->Generation != overlay->second->Generation) {
- sh->GroupsToUpdate[groupId].emplace();
- }
- } else { // a new item was inserted
- auto&& [it, inserted] = GroupLookup.emplace(groupId, overlay->second.Get());
- Y_VERIFY(inserted);
- sh->GroupsToUpdate[groupId].emplace();
- ev->Created.push_back(groupId);
- }
- }
- for (auto&& [base, overlay] : state.PDisks.Diff()) {
- if (!overlay->second) {
- continue; // ignore cases with PDisk was deleted -- groups over this disk must be deleted too
- } else if (base && base->second->GetSelfHealStatusTuple() == overlay->second->GetSelfHealStatusTuple()) {
- continue; // nothing changed for this PDisk
- } else {
- for (const auto& [id, slot] : overlay->second->VSlotsOnPDisk) {
- if (slot->Group) {
- sh->GroupsToUpdate[slot->GroupId].emplace();
- }
- }
- }
- }
-
- if (ev->Created || ev->Deleted) {
- state.Outbox.push_back(std::make_unique<IEventHandle>(StatProcessorActorId, SelfId(), ev.Release()));
- }
- if (sh->GroupsToUpdate) {
- FillInSelfHealGroups(*sh, &state);
- state.Outbox.push_back(std::make_unique<IEventHandle>(SelfHealId, SelfId(), sh.Release()));
- }
- }
-
- void TBlobStorageController::CommitScrubUpdates(TConfigState& state, TTransactionContext& txc) {
- // remove scrubbing entries
- for (auto&& [base, overlay] : state.PDisks.Diff()) {
- if (!overlay->second) { // PDisk deleted
- ScrubState.OnDeletePDisk(overlay->first);
- }
- }
- for (auto&& [base, overlay] : state.VSlots.Diff()) {
- if (!overlay->second) {
- ScrubState.OnDeleteVSlot(overlay->first, txc);
- } else if (!base) {
- Y_VERIFY_DEBUG(!overlay->second->IsBeingDeleted());
- ScrubState.UpdateVDiskState(&*overlay->second);
- } else if (overlay->second->IsBeingDeleted() && !base->second->IsBeingDeleted()) {
- ScrubState.OnDeleteVSlot(overlay->first, txc);
- }
- }
- for (auto&& [base, overlay] : state.Groups.Diff()) {
- if (!overlay->second) { // group deleted
- ScrubState.OnDeleteGroup(overlay->first);
- }
- }
- }
-
- void TBlobStorageController::CommitStoragePoolStatUpdates(TConfigState& state) {
- // scan for created/renamed storage pools
- for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
- if (!prev) { // created storage pool
- StoragePoolStat->AddStoragePool(TStoragePoolStat::ConvertId(cur->first), cur->second.Name, 0);
- } else if (cur && prev->second.Name != cur->second.Name) { // renamed storage pool
- StoragePoolStat->RenameStoragePool(TStoragePoolStat::ConvertId(cur->first), cur->second.Name);
- }
- }
-
- // apply created/deleted groups
- for (const auto& [base, overlay] : state.Groups.Diff()) {
- if (!base) { // newly created group
- overlay->second->StatusFlags = overlay->second->GetStorageStatusFlags();
- StoragePoolStat->Update(TStoragePoolStat::ConvertId(overlay->second->StoragePoolId),
- std::nullopt, overlay->second->StatusFlags);
- } else if (!overlay->second) { // deleted group
- if (state.StoragePools.Get().count(base->second->StoragePoolId)) {
- StoragePoolStat->Update(TStoragePoolStat::ConvertId(base->second->StoragePoolId),
- base->second->StatusFlags, std::nullopt);
- }
- }
- }
-
- // apply VDisks going for destruction
- for (const auto& [base, overlay] : state.VSlots.Diff()) {
- if (overlay->second && overlay->second->DeletedFromStoragePoolId && overlay->second->Metrics.GetAllocatedSize()) {
- StoragePoolStat->UpdateAllocatedSize(TStoragePoolStat::ConvertId(*overlay->second->DeletedFromStoragePoolId),
- -overlay->second->Metrics.GetAllocatedSize());
- }
- }
-
- // scan for deleted storage pools
- for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
- if (prev && !cur) {
- StoragePoolStat->DeleteStoragePool(TStoragePoolStat::ConvertId(prev->first));
- }
- }
- }
-
- void TBlobStorageController::CommitSysViewUpdates(TConfigState& state) {
- for (const auto& [base, overlay] : state.PDisks.Diff()) {
- SysViewChangedPDisks.insert(overlay->first);
- }
- for (const auto& [base, overlay] : state.VSlots.Diff()) {
- SysViewChangedPDisks.insert(overlay->first.ComprisingPDiskId());
- SysViewChangedVSlots.insert(overlay->first);
- SysViewChangedGroups.insert(overlay->second ? overlay->second->GroupId : base->second->GroupId);
- }
- for (const auto& [base, overlay] : state.Groups.Diff()) {
- SysViewChangedGroups.insert(overlay->first);
- }
- for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
- SysViewChangedStoragePools.insert(cur ? cur->first : prev->first);
- }
- }
-
- void TBlobStorageController::TConfigState::ApplyConfigUpdates() {
- for (auto& msg : Outbox) {
- TActivationContext::Send(msg.release());
- }
- }
-
- void TBlobStorageController::TConfigState::DestroyVSlot(const TVSlotId vslotId) {
- // obtain mutable slot pointer
- TVSlotInfo *mutableSlot = VSlots.FindForUpdate(vslotId);
- Y_VERIFY(mutableSlot);
-
- // ensure it hasn't started deletion yet
- Y_VERIFY(!mutableSlot->IsBeingDeleted());
-
- if (mutableSlot->Mood == TMood::Donor) {
- // this is the donor disk and it is being deleted; here we have to inform the acceptor disk of changed
- // donor set by simply removing the donor disk
- TVSlotInfo *mutableAcceptor = VSlots.FindForUpdate(mutableSlot->AcceptorVSlotId);
- Y_VERIFY(mutableAcceptor);
- auto& donors = mutableAcceptor->Donors;
- const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, mutableSlot->GetVDiskId()));
- Y_VERIFY(it != donors.end());
- donors.erase(it);
- }
-
- for (const auto& [donorVSlotId, donorVDiskId] : std::exchange(mutableSlot->Donors, {})) {
- // this is the acceptor disk and we have to delete all the donors as they are not needed anymore
- DestroyVSlot(donorVSlotId);
- }
-
- // remove slot info from the PDisk
- TPDiskInfo *pdisk = PDisks.FindForUpdate(vslotId.ComprisingPDiskId());
- Y_VERIFY(pdisk);
- --pdisk->NumActiveSlots;
-
- if (UncommittedVSlots.erase(vslotId)) {
- const ui32 erased = pdisk->VSlotsOnPDisk.erase(vslotId.VSlotId);
- Y_VERIFY(erased);
- VSlots.DeleteExistingEntry(vslotId); // this slot hasn't been created yet and can be deleted safely
- } else {
- const TGroupInfo *group = Groups.Find(mutableSlot->GroupId);
- Y_VERIFY(group);
- mutableSlot->ScheduleForDeletion(group->StoragePoolId);
- }
- }
-
- void TBlobStorageController::TConfigState::CheckConsistency() const {
-#ifndef NDEBUG
- PDisks.ForEach([&](const auto& pdiskId, const auto& pdisk) {
- ui32 numActiveSlots = 0;
- for (const auto& [vslotId, vslot] : pdisk.VSlotsOnPDisk) {
- const TVSlotInfo *vslotInTable = VSlots.Find(TVSlotId(pdiskId, vslotId));
- Y_VERIFY(vslot == vslotInTable);
- Y_VERIFY(vslot->PDisk == &pdisk);
- numActiveSlots += !vslot->IsBeingDeleted();
- }
- Y_VERIFY(pdisk.NumActiveSlots == numActiveSlots);
- });
- VSlots.ForEach([&](const auto& vslotId, const auto& vslot) {
- Y_VERIFY(vslot.VSlotId == vslotId);
- const TPDiskInfo *pdisk = PDisks.Find(vslot.VSlotId.ComprisingPDiskId());
- Y_VERIFY(vslot.PDisk == pdisk);
- const auto it = vslot.PDisk->VSlotsOnPDisk.find(vslotId.VSlotId);
- Y_VERIFY(it != vslot.PDisk->VSlotsOnPDisk.end());
- Y_VERIFY(it->second == &vslot);
- if (!vslot.IsBeingDeleted() && vslot.Mood != TMood::Donor) {
- Y_VERIFY(vslot.Group == Groups.Find(vslot.GroupId));
- } else {
- Y_VERIFY(!vslot.Group);
- }
- if (vslot.Mood == TMood::Donor) {
- const TVSlotInfo *acceptor = VSlots.Find(vslot.AcceptorVSlotId);
- Y_VERIFY(acceptor);
- auto& donors = acceptor->Donors;
- const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, vslot.GetVDiskId()));
- Y_VERIFY(it != donors.end());
- }
- for (const auto& [donorVSlotId, donorVDiskId] : vslot.Donors) {
- const TVSlotInfo *donor = VSlots.Find(donorVSlotId);
- Y_VERIFY(donor);
- Y_VERIFY(donor->GetVDiskId() == donorVDiskId);
- Y_VERIFY(donor->Mood == TMood::Donor);
- Y_VERIFY(donor->AcceptorVSlotId == vslotId);
- }
- });
- Groups.ForEach([&](const auto& groupId, const auto& group) {
- Y_VERIFY(groupId == group.ID);
- for (const TVSlotInfo *vslot : group.VDisksInGroup) {
- Y_VERIFY(VSlots.Find(vslot->VSlotId) == vslot);
- Y_VERIFY(vslot->Group == &group);
- Y_VERIFY(vslot->GroupId == groupId);
- Y_VERIFY(vslot->GroupGeneration == group.Generation);
- }
- });
-#endif
- }
-
- void TBlobStorageController::TPDiskInfo::OnCommit() {
- for (const auto& [id, slot] : VSlotsOnPDisk) {
- slot.Mutable().PDisk = this;
- }
- }
-
- void TBlobStorageController::TVSlotInfo::OnCommit() {
- PDisk.Mutable().VSlotsOnPDisk[VSlotId.VSlotId] = this;
- if (Group) {
- const ui32 index = Group->Topology->GetOrderNumber(GetShortVDiskId());
- Group.Mutable().VDisksInGroup[index] = this;
- }
- if (VSlotReadyTimestampIter != TVSlotReadyTimestampQ::iterator()) {
- VSlotReadyTimestampIter->second = this;
- }
- DeletedFromStoragePoolId.reset();
- }
-
- void TBlobStorageController::TGroupInfo::OnCommit() {
- for (const auto& slot : VDisksInGroup) {
- slot.Mutable().Group = this;
- }
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineHostConfig *pb, const THostConfigId &id,
- const THostConfigInfo &hostConfig) {
- pb->SetHostConfigId(id);
- pb->SetName(hostConfig.Name);
- pb->SetItemConfigGeneration(hostConfig.Generation.GetOrElse(1));
- for (const auto& [key, value] : hostConfig.Drives) {
- auto &drive = *pb->AddDrive();
- drive.SetPath(key.Path);
- drive.SetType(value.Type);
- drive.SetSharedWithOs(value.SharedWithOs);
- drive.SetReadCentric(value.ReadCentric);
- drive.SetKind(value.Kind);
-
- if (const auto& config = value.PDiskConfig) {
- NKikimrBlobStorage::TPDiskConfig& pb = *drive.MutablePDiskConfig();
- if (!pb.ParseFromString(*config)) {
- throw TExError() << "HostConfigId# " << id << " undeserializable PDiskConfig string"
- << " Path# " << key.Path;
- }
- }
- }
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineBox *pb, const TBoxId &id, const TBoxInfo &box) {
- pb->SetBoxId(id);
- pb->SetName(box.Name);
- pb->SetItemConfigGeneration(box.Generation.GetOrElse(1));
- for (const auto &userId : box.UserIds) {
- pb->AddUserId(std::get<1>(userId));
- }
- for (const auto &kv : box.Hosts) {
- auto *host = pb->AddHost();
- host->SetHostConfigId(kv.second.HostConfigId);
- auto *key = host->MutableKey();
- key->SetFqdn(kv.first.Fqdn);
- key->SetIcPort(kv.first.IcPort);
- }
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineStoragePool *pb, const TBoxStoragePoolId &id, const TStoragePoolInfo &pool) {
- pb->SetBoxId(std::get<0>(id));
- pb->SetStoragePoolId(std::get<1>(id));
- pb->SetName(pool.Name);
- pb->SetItemConfigGeneration(pool.Generation.GetOrElse(1));
- pb->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(pool.ErasureSpecies));
- pb->SetEncryptionMode(pool.EncryptionMode.GetOrElse(0));
- auto* geometry = pb->MutableGeometry();
- if (pool.RealmLevelBegin) {
- geometry->SetRealmLevelBegin(*pool.RealmLevelBegin);
- }
- if (pool.RealmLevelEnd) {
- geometry->SetRealmLevelEnd(*pool.RealmLevelEnd);
- }
- if (pool.DomainLevelBegin) {
- geometry->SetDomainLevelBegin(*pool.DomainLevelBegin);
- }
- if (pool.DomainLevelEnd) {
- geometry->SetDomainLevelEnd(*pool.DomainLevelEnd);
- }
- if (pool.NumFailRealms) {
- geometry->SetNumFailRealms(*pool.NumFailRealms);
- }
- if (pool.NumFailDomainsPerFailRealm) {
- geometry->SetNumFailDomainsPerFailRealm(*pool.NumFailDomainsPerFailRealm);
- }
- if (pool.NumVDisksPerFailDomain) {
- geometry->SetNumVDisksPerFailDomain(*pool.NumVDisksPerFailDomain);
- }
- if (pool.SchemeshardId && pool.PathItemId) {
- auto *x = pb->MutableScopeId();
- x->SetX1(*pool.SchemeshardId);
- x->SetX2(*pool.PathItemId);
- }
-
- // group geometry
- if (pool.HasGroupGeometry()) {
- pb->MutableGeometry()->CopyFrom(pool.GetGroupGeometry());
- }
-
- // serialize VDiskKind as a string
- {
- const google::protobuf::EnumDescriptor *descr = NKikimrBlobStorage::TVDiskKind::EVDiskKind_descriptor();
- const google::protobuf::EnumValueDescriptor *value = descr->FindValueByNumber(pool.VDiskKind);
- if (!value) {
- throw TExError() << "invalid VDiskKind# " << pool.VDiskKind;
- }
- pb->SetVDiskKind(value->name());
- }
-
- // usage pattern
- if (pool.HasUsagePattern()) {
- pb->MutableUsagePattern()->CopyFrom(pool.GetUsagePattern());
- }
-
- pb->SetKind(pool.Kind);
- pb->SetNumGroups(pool.NumGroups);
- pb->SetRandomizeGroupMapping(pool.RandomizeGroupMapping);
-
- for (const auto &userId : pool.UserIds) {
- pb->AddUserId(std::get<2>(userId));
- }
-
- for (const TStoragePoolInfo::TPDiskFilter &filter : pool.PDiskFilters) {
- Serialize(pb->AddPDiskFilter(), filter);
- }
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TPDiskFilter *pb, const TStoragePoolInfo::TPDiskFilter &filter) {
-#define SERIALIZE_VARIABLE(NAME) (filter.NAME && (pb->AddProperty()->Set##NAME(*filter.NAME), true))
- SERIALIZE_VARIABLE(Type);
- SERIALIZE_VARIABLE(SharedWithOs);
- SERIALIZE_VARIABLE(ReadCentric);
- SERIALIZE_VARIABLE(Kind);
-#undef SERIALIZE_VARIABLE
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TPDisk *pb, const TPDiskId &id, const TPDiskInfo &pdisk) {
- const TPDiskCategory category(pdisk.Kind);
-
- pb->SetNodeId(id.NodeId);
- pb->SetPDiskId(id.PDiskId);
- pb->SetPath(pdisk.Path);
- pb->SetType(PDiskTypeToPDiskType(category.Type()));
- pb->SetSharedWithOs(!pdisk.SharedWithOs ? NKikimrBlobStorage::ETriStateBool::kNotSet
- : *pdisk.SharedWithOs ? NKikimrBlobStorage::ETriStateBool::kTrue
- : NKikimrBlobStorage::ETriStateBool::kFalse);
- pb->SetReadCentric(!pdisk.ReadCentric ? NKikimrBlobStorage::ETriStateBool::kNotSet
- : *pdisk.ReadCentric ? NKikimrBlobStorage::ETriStateBool::kTrue
- : NKikimrBlobStorage::ETriStateBool::kFalse);
- pb->SetKind(category.Kind());
- pb->SetGuid(pdisk.Guid);
- if (pdisk.PDiskConfig && !pb->MutablePDiskConfig()->ParseFromString(pdisk.PDiskConfig)) {
- throw TExError() << "failed to parse PDiskConfig for PDisk# " << id;
- }
- pb->SetBoxId(pdisk.BoxId);
- pb->SetNumStaticSlots(pdisk.StaticSlotUsage);
- pb->SetDriveStatus(pdisk.Status);
- pb->SetExpectedSlotCount(pdisk.ExpectedSlotCount);
- pb->SetDriveStatusChangeTimestamp(pdisk.StatusTimestamp.GetValue());
- pb->MutablePDiskMetrics()->CopyFrom(pdisk.Metrics);
- pb->MutablePDiskMetrics()->ClearPDiskId();
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TVSlotId *pb, TVSlotId id) {
- id.Serialize(pb);
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotInfo& vslot) {
- pb->SetNodeID(vslot.VSlotId.NodeId);
- pb->SetPDiskID(vslot.VSlotId.PDiskId);
- pb->SetVDiskSlotID(vslot.VSlotId.VSlotId);
- pb->SetPDiskGuid(vslot.PDisk->Guid);
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotId& vslotId) {
- pb->SetNodeID(vslotId.NodeId);
- pb->SetPDiskID(vslotId.PDiskId);
- pb->SetVDiskSlotID(vslotId.VSlotId);
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TVSlot *pb, const TVSlotInfo &vslot,
- const TVSlotFinder& finder) {
- Serialize(pb->MutableVSlotId(), vslot.VSlotId);
- pb->SetGroupId(vslot.GroupId);
- pb->SetGroupGeneration(vslot.GroupGeneration);
- pb->SetVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(vslot.Kind));
- pb->SetFailRealmIdx(vslot.RingIdx);
- pb->SetFailDomainIdx(vslot.FailDomainIdx);
- pb->SetVDiskIdx(vslot.VDiskIdx);
- pb->SetAllocatedSize(vslot.Metrics.GetAllocatedSize());
- pb->MutableVDiskMetrics()->CopyFrom(vslot.Metrics);
- pb->MutableVDiskMetrics()->ClearVDiskId();
- pb->SetStatus(NKikimrBlobStorage::EVDiskStatus_Name(vslot.GetStatus()));
- for (const auto& [vslotId, vdiskId] : vslot.Donors) {
- auto *item = pb->AddDonors();
- Serialize(item->MutableVSlotId(), vslotId);
- VDiskIDFromVDiskID(vdiskId, item->MutableVDiskId());
- finder(vslotId, [item](const TVSlotInfo& vslot) {
- item->MutableVDiskMetrics()->CopyFrom(vslot.Metrics);
- item->MutableVDiskMetrics()->ClearVDiskId();
- });
- }
- pb->SetReady(vslot.IsReady);
- }
-
- void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TGroup *pb, const TGroupInfo &group) {
- pb->SetGroupId(group.ID);
- pb->SetGroupGeneration(group.Generation);
- pb->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(group.ErasureSpecies));
- for (const TVSlotInfo *vslot : group.VDisksInGroup) {
- Serialize(pb->AddVSlotId(), vslot->VSlotId);
- }
- pb->SetBoxId(std::get<0>(group.StoragePoolId));
- pb->SetStoragePoolId(std::get<1>(group.StoragePoolId));
- pb->SetSeenOperational(group.SeenOperational);
-
- const auto& status = group.Status;
- pb->SetOperatingStatus(status.OperatingStatus);
- pb->SetExpectedStatus(status.ExpectedStatus);
- }
-
- void TBlobStorageController::SerializeDonors(NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vdisk,
- const TVSlotInfo& vslot, const TGroupInfo& group) {
- if (vslot.Mood == TMood::Donor) {
- ui32 numFailRealms = 0, numFailDomainsPerFailRealm = 0, numVDisksPerFailDomain = 0;
- for (const TVSlotInfo *slot : group.VDisksInGroup) {
- numFailRealms = Max(numFailRealms, slot->RingIdx + 1);
- numFailDomainsPerFailRealm = Max(numFailDomainsPerFailRealm, slot->FailDomainIdx + 1);
- numVDisksPerFailDomain = Max(numVDisksPerFailDomain, slot->VDiskIdx + 1);
- }
- Y_VERIFY(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain == group.VDisksInGroup.size());
- auto *pb = vdisk->MutableDonorMode();
- pb->SetNumFailRealms(numFailRealms);
- pb->SetNumFailDomainsPerFailRealm(numFailDomainsPerFailRealm);
- pb->SetNumVDisksPerFailDomain(numVDisksPerFailDomain);
- pb->SetErasureSpecies(group.ErasureSpecies);
- }
- for (const auto& [vslotId, vdiskId] : vslot.Donors) {
- auto *pb = vdisk->AddDonors();
- VDiskIDFromVDiskID(vdiskId, pb->MutableVDiskId());
- Serialize(pb->MutableVDiskLocation(), vslotId);
- }
- }
-
- void TBlobStorageController::SerializeGroupInfo(NKikimrBlobStorage::TGroupInfo *group, const TGroupInfo& groupInfo,
- const TString& storagePoolName, const TMaybe<TKikimrScopeId>& scopeId) {
- group->SetGroupID(groupInfo.ID);
- group->SetGroupGeneration(groupInfo.Generation);
- group->SetErasureSpecies(groupInfo.ErasureSpecies);
- group->SetStoragePoolName(storagePoolName);
- group->SetDeviceType(PDiskTypeToPDiskType(groupInfo.GetCommonDeviceType()));
-
- group->SetEncryptionMode(groupInfo.EncryptionMode.GetOrElse(0));
- group->SetLifeCyclePhase(groupInfo.LifeCyclePhase.GetOrElse(0));
+ db.Table<Schema::State>().Key(true).Update<Schema::State::SerialManagementStage>(state.SerialManagementStage.Get());
+ }
+
+ CommitSelfHealUpdates(state);
+ CommitScrubUpdates(state, txc);
+ CommitStoragePoolStatUpdates(state);
+ CommitSysViewUpdates(state);
+
+ // remove deleted vslots from VSlotReadyTimestampQ
+ for (auto&& [base, overlay] : state.VSlots.Diff()) {
+ if (!overlay->second || !overlay->second->Group) { // deleted one
+ base->second->DropFromVSlotReadyTimestampQ();
+ if (overlay->second) {
+ overlay->second->ResetVSlotReadyTimestampIter();
+ }
+ NotReadyVSlotIds.erase(overlay->first);
+ }
+ }
+
+ TNodeWardenUpdateNotifier(this, state).Execute(state.Outbox);
+
+ state.CheckConsistency();
+ state.Commit();
+
+ return true;
+ }
+
+ void TBlobStorageController::CommitSelfHealUpdates(TConfigState& state) {
+ auto ev = MakeHolder<TEvControllerNotifyGroupChange>();
+ auto sh = MakeHolder<TEvControllerUpdateSelfHealInfo>();
+
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ const TGroupId groupId = overlay->first;
+ if (!overlay->second) { // item was deleted, drop it from the cache
+ const ui32 erased = GroupLookup.erase(groupId);
+ Y_VERIFY(erased);
+ sh->GroupsToUpdate[groupId].reset();
+ ev->Deleted.push_back(groupId);
+ } else if (base) { // item was overwritten, just update pointer in the lookup cache
+ const auto it = GroupLookup.find(groupId);
+ Y_VERIFY(it != GroupLookup.end());
+ TGroupInfo *prev = std::exchange(it->second, overlay->second.Get());
+ Y_VERIFY(prev == base->second.Get());
+ if (base->second->Generation != overlay->second->Generation) {
+ sh->GroupsToUpdate[groupId].emplace();
+ }
+ } else { // a new item was inserted
+ auto&& [it, inserted] = GroupLookup.emplace(groupId, overlay->second.Get());
+ Y_VERIFY(inserted);
+ sh->GroupsToUpdate[groupId].emplace();
+ ev->Created.push_back(groupId);
+ }
+ }
+ for (auto&& [base, overlay] : state.PDisks.Diff()) {
+ if (!overlay->second) {
+ continue; // ignore cases with PDisk was deleted -- groups over this disk must be deleted too
+ } else if (base && base->second->GetSelfHealStatusTuple() == overlay->second->GetSelfHealStatusTuple()) {
+ continue; // nothing changed for this PDisk
+ } else {
+ for (const auto& [id, slot] : overlay->second->VSlotsOnPDisk) {
+ if (slot->Group) {
+ sh->GroupsToUpdate[slot->GroupId].emplace();
+ }
+ }
+ }
+ }
+
+ if (ev->Created || ev->Deleted) {
+ state.Outbox.push_back(std::make_unique<IEventHandle>(StatProcessorActorId, SelfId(), ev.Release()));
+ }
+ if (sh->GroupsToUpdate) {
+ FillInSelfHealGroups(*sh, &state);
+ state.Outbox.push_back(std::make_unique<IEventHandle>(SelfHealId, SelfId(), sh.Release()));
+ }
+ }
+
+ void TBlobStorageController::CommitScrubUpdates(TConfigState& state, TTransactionContext& txc) {
+ // remove scrubbing entries
+ for (auto&& [base, overlay] : state.PDisks.Diff()) {
+ if (!overlay->second) { // PDisk deleted
+ ScrubState.OnDeletePDisk(overlay->first);
+ }
+ }
+ for (auto&& [base, overlay] : state.VSlots.Diff()) {
+ if (!overlay->second) {
+ ScrubState.OnDeleteVSlot(overlay->first, txc);
+ } else if (!base) {
+ Y_VERIFY_DEBUG(!overlay->second->IsBeingDeleted());
+ ScrubState.UpdateVDiskState(&*overlay->second);
+ } else if (overlay->second->IsBeingDeleted() && !base->second->IsBeingDeleted()) {
+ ScrubState.OnDeleteVSlot(overlay->first, txc);
+ }
+ }
+ for (auto&& [base, overlay] : state.Groups.Diff()) {
+ if (!overlay->second) { // group deleted
+ ScrubState.OnDeleteGroup(overlay->first);
+ }
+ }
+ }
+
+ void TBlobStorageController::CommitStoragePoolStatUpdates(TConfigState& state) {
+ // scan for created/renamed storage pools
+ for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
+ if (!prev) { // created storage pool
+ StoragePoolStat->AddStoragePool(TStoragePoolStat::ConvertId(cur->first), cur->second.Name, 0);
+ } else if (cur && prev->second.Name != cur->second.Name) { // renamed storage pool
+ StoragePoolStat->RenameStoragePool(TStoragePoolStat::ConvertId(cur->first), cur->second.Name);
+ }
+ }
+
+ // apply created/deleted groups
+ for (const auto& [base, overlay] : state.Groups.Diff()) {
+ if (!base) { // newly created group
+ overlay->second->StatusFlags = overlay->second->GetStorageStatusFlags();
+ StoragePoolStat->Update(TStoragePoolStat::ConvertId(overlay->second->StoragePoolId),
+ std::nullopt, overlay->second->StatusFlags);
+ } else if (!overlay->second) { // deleted group
+ if (state.StoragePools.Get().count(base->second->StoragePoolId)) {
+ StoragePoolStat->Update(TStoragePoolStat::ConvertId(base->second->StoragePoolId),
+ base->second->StatusFlags, std::nullopt);
+ }
+ }
+ }
+
+ // apply VDisks going for destruction
+ for (const auto& [base, overlay] : state.VSlots.Diff()) {
+ if (overlay->second && overlay->second->DeletedFromStoragePoolId && overlay->second->Metrics.GetAllocatedSize()) {
+ StoragePoolStat->UpdateAllocatedSize(TStoragePoolStat::ConvertId(*overlay->second->DeletedFromStoragePoolId),
+ -overlay->second->Metrics.GetAllocatedSize());
+ }
+ }
+
+ // scan for deleted storage pools
+ for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
+ if (prev && !cur) {
+ StoragePoolStat->DeleteStoragePool(TStoragePoolStat::ConvertId(prev->first));
+ }
+ }
+ }
+
+ void TBlobStorageController::CommitSysViewUpdates(TConfigState& state) {
+ for (const auto& [base, overlay] : state.PDisks.Diff()) {
+ SysViewChangedPDisks.insert(overlay->first);
+ }
+ for (const auto& [base, overlay] : state.VSlots.Diff()) {
+ SysViewChangedPDisks.insert(overlay->first.ComprisingPDiskId());
+ SysViewChangedVSlots.insert(overlay->first);
+ SysViewChangedGroups.insert(overlay->second ? overlay->second->GroupId : base->second->GroupId);
+ }
+ for (const auto& [base, overlay] : state.Groups.Diff()) {
+ SysViewChangedGroups.insert(overlay->first);
+ }
+ for (const auto& [prev, cur] : Diff(&StoragePools, &state.StoragePools.Get())) {
+ SysViewChangedStoragePools.insert(cur ? cur->first : prev->first);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::ApplyConfigUpdates() {
+ for (auto& msg : Outbox) {
+ TActivationContext::Send(msg.release());
+ }
+ }
+
+ void TBlobStorageController::TConfigState::DestroyVSlot(const TVSlotId vslotId) {
+ // obtain mutable slot pointer
+ TVSlotInfo *mutableSlot = VSlots.FindForUpdate(vslotId);
+ Y_VERIFY(mutableSlot);
+
+ // ensure it hasn't started deletion yet
+ Y_VERIFY(!mutableSlot->IsBeingDeleted());
+
+ if (mutableSlot->Mood == TMood::Donor) {
+ // this is the donor disk and it is being deleted; here we have to inform the acceptor disk of changed
+ // donor set by simply removing the donor disk
+ TVSlotInfo *mutableAcceptor = VSlots.FindForUpdate(mutableSlot->AcceptorVSlotId);
+ Y_VERIFY(mutableAcceptor);
+ auto& donors = mutableAcceptor->Donors;
+ const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, mutableSlot->GetVDiskId()));
+ Y_VERIFY(it != donors.end());
+ donors.erase(it);
+ }
+
+ for (const auto& [donorVSlotId, donorVDiskId] : std::exchange(mutableSlot->Donors, {})) {
+ // this is the acceptor disk and we have to delete all the donors as they are not needed anymore
+ DestroyVSlot(donorVSlotId);
+ }
+
+ // remove slot info from the PDisk
+ TPDiskInfo *pdisk = PDisks.FindForUpdate(vslotId.ComprisingPDiskId());
+ Y_VERIFY(pdisk);
+ --pdisk->NumActiveSlots;
+
+ if (UncommittedVSlots.erase(vslotId)) {
+ const ui32 erased = pdisk->VSlotsOnPDisk.erase(vslotId.VSlotId);
+ Y_VERIFY(erased);
+ VSlots.DeleteExistingEntry(vslotId); // this slot hasn't been created yet and can be deleted safely
+ } else {
+ const TGroupInfo *group = Groups.Find(mutableSlot->GroupId);
+ Y_VERIFY(group);
+ mutableSlot->ScheduleForDeletion(group->StoragePoolId);
+ }
+ }
+
+ void TBlobStorageController::TConfigState::CheckConsistency() const {
+#ifndef NDEBUG
+ PDisks.ForEach([&](const auto& pdiskId, const auto& pdisk) {
+ ui32 numActiveSlots = 0;
+ for (const auto& [vslotId, vslot] : pdisk.VSlotsOnPDisk) {
+ const TVSlotInfo *vslotInTable = VSlots.Find(TVSlotId(pdiskId, vslotId));
+ Y_VERIFY(vslot == vslotInTable);
+ Y_VERIFY(vslot->PDisk == &pdisk);
+ numActiveSlots += !vslot->IsBeingDeleted();
+ }
+ Y_VERIFY(pdisk.NumActiveSlots == numActiveSlots);
+ });
+ VSlots.ForEach([&](const auto& vslotId, const auto& vslot) {
+ Y_VERIFY(vslot.VSlotId == vslotId);
+ const TPDiskInfo *pdisk = PDisks.Find(vslot.VSlotId.ComprisingPDiskId());
+ Y_VERIFY(vslot.PDisk == pdisk);
+ const auto it = vslot.PDisk->VSlotsOnPDisk.find(vslotId.VSlotId);
+ Y_VERIFY(it != vslot.PDisk->VSlotsOnPDisk.end());
+ Y_VERIFY(it->second == &vslot);
+ if (!vslot.IsBeingDeleted() && vslot.Mood != TMood::Donor) {
+ Y_VERIFY(vslot.Group == Groups.Find(vslot.GroupId));
+ } else {
+ Y_VERIFY(!vslot.Group);
+ }
+ if (vslot.Mood == TMood::Donor) {
+ const TVSlotInfo *acceptor = VSlots.Find(vslot.AcceptorVSlotId);
+ Y_VERIFY(acceptor);
+ auto& donors = acceptor->Donors;
+ const auto it = std::find(donors.begin(), donors.end(), std::make_pair(vslotId, vslot.GetVDiskId()));
+ Y_VERIFY(it != donors.end());
+ }
+ for (const auto& [donorVSlotId, donorVDiskId] : vslot.Donors) {
+ const TVSlotInfo *donor = VSlots.Find(donorVSlotId);
+ Y_VERIFY(donor);
+ Y_VERIFY(donor->GetVDiskId() == donorVDiskId);
+ Y_VERIFY(donor->Mood == TMood::Donor);
+ Y_VERIFY(donor->AcceptorVSlotId == vslotId);
+ }
+ });
+ Groups.ForEach([&](const auto& groupId, const auto& group) {
+ Y_VERIFY(groupId == group.ID);
+ for (const TVSlotInfo *vslot : group.VDisksInGroup) {
+ Y_VERIFY(VSlots.Find(vslot->VSlotId) == vslot);
+ Y_VERIFY(vslot->Group == &group);
+ Y_VERIFY(vslot->GroupId == groupId);
+ Y_VERIFY(vslot->GroupGeneration == group.Generation);
+ }
+ });
+#endif
+ }
+
+ void TBlobStorageController::TPDiskInfo::OnCommit() {
+ for (const auto& [id, slot] : VSlotsOnPDisk) {
+ slot.Mutable().PDisk = this;
+ }
+ }
+
+ void TBlobStorageController::TVSlotInfo::OnCommit() {
+ PDisk.Mutable().VSlotsOnPDisk[VSlotId.VSlotId] = this;
+ if (Group) {
+ const ui32 index = Group->Topology->GetOrderNumber(GetShortVDiskId());
+ Group.Mutable().VDisksInGroup[index] = this;
+ }
+ if (VSlotReadyTimestampIter != TVSlotReadyTimestampQ::iterator()) {
+ VSlotReadyTimestampIter->second = this;
+ }
+ DeletedFromStoragePoolId.reset();
+ }
+
+ void TBlobStorageController::TGroupInfo::OnCommit() {
+ for (const auto& slot : VDisksInGroup) {
+ slot.Mutable().Group = this;
+ }
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineHostConfig *pb, const THostConfigId &id,
+ const THostConfigInfo &hostConfig) {
+ pb->SetHostConfigId(id);
+ pb->SetName(hostConfig.Name);
+ pb->SetItemConfigGeneration(hostConfig.Generation.GetOrElse(1));
+ for (const auto& [key, value] : hostConfig.Drives) {
+ auto &drive = *pb->AddDrive();
+ drive.SetPath(key.Path);
+ drive.SetType(value.Type);
+ drive.SetSharedWithOs(value.SharedWithOs);
+ drive.SetReadCentric(value.ReadCentric);
+ drive.SetKind(value.Kind);
+
+ if (const auto& config = value.PDiskConfig) {
+ NKikimrBlobStorage::TPDiskConfig& pb = *drive.MutablePDiskConfig();
+ if (!pb.ParseFromString(*config)) {
+ throw TExError() << "HostConfigId# " << id << " undeserializable PDiskConfig string"
+ << " Path# " << key.Path;
+ }
+ }
+ }
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineBox *pb, const TBoxId &id, const TBoxInfo &box) {
+ pb->SetBoxId(id);
+ pb->SetName(box.Name);
+ pb->SetItemConfigGeneration(box.Generation.GetOrElse(1));
+ for (const auto &userId : box.UserIds) {
+ pb->AddUserId(std::get<1>(userId));
+ }
+ for (const auto &kv : box.Hosts) {
+ auto *host = pb->AddHost();
+ host->SetHostConfigId(kv.second.HostConfigId);
+ auto *key = host->MutableKey();
+ key->SetFqdn(kv.first.Fqdn);
+ key->SetIcPort(kv.first.IcPort);
+ }
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TDefineStoragePool *pb, const TBoxStoragePoolId &id, const TStoragePoolInfo &pool) {
+ pb->SetBoxId(std::get<0>(id));
+ pb->SetStoragePoolId(std::get<1>(id));
+ pb->SetName(pool.Name);
+ pb->SetItemConfigGeneration(pool.Generation.GetOrElse(1));
+ pb->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(pool.ErasureSpecies));
+ pb->SetEncryptionMode(pool.EncryptionMode.GetOrElse(0));
+ auto* geometry = pb->MutableGeometry();
+ if (pool.RealmLevelBegin) {
+ geometry->SetRealmLevelBegin(*pool.RealmLevelBegin);
+ }
+ if (pool.RealmLevelEnd) {
+ geometry->SetRealmLevelEnd(*pool.RealmLevelEnd);
+ }
+ if (pool.DomainLevelBegin) {
+ geometry->SetDomainLevelBegin(*pool.DomainLevelBegin);
+ }
+ if (pool.DomainLevelEnd) {
+ geometry->SetDomainLevelEnd(*pool.DomainLevelEnd);
+ }
+ if (pool.NumFailRealms) {
+ geometry->SetNumFailRealms(*pool.NumFailRealms);
+ }
+ if (pool.NumFailDomainsPerFailRealm) {
+ geometry->SetNumFailDomainsPerFailRealm(*pool.NumFailDomainsPerFailRealm);
+ }
+ if (pool.NumVDisksPerFailDomain) {
+ geometry->SetNumVDisksPerFailDomain(*pool.NumVDisksPerFailDomain);
+ }
+ if (pool.SchemeshardId && pool.PathItemId) {
+ auto *x = pb->MutableScopeId();
+ x->SetX1(*pool.SchemeshardId);
+ x->SetX2(*pool.PathItemId);
+ }
+
+ // group geometry
+ if (pool.HasGroupGeometry()) {
+ pb->MutableGeometry()->CopyFrom(pool.GetGroupGeometry());
+ }
+
+ // serialize VDiskKind as a string
+ {
+ const google::protobuf::EnumDescriptor *descr = NKikimrBlobStorage::TVDiskKind::EVDiskKind_descriptor();
+ const google::protobuf::EnumValueDescriptor *value = descr->FindValueByNumber(pool.VDiskKind);
+ if (!value) {
+ throw TExError() << "invalid VDiskKind# " << pool.VDiskKind;
+ }
+ pb->SetVDiskKind(value->name());
+ }
+
+ // usage pattern
+ if (pool.HasUsagePattern()) {
+ pb->MutableUsagePattern()->CopyFrom(pool.GetUsagePattern());
+ }
+
+ pb->SetKind(pool.Kind);
+ pb->SetNumGroups(pool.NumGroups);
+ pb->SetRandomizeGroupMapping(pool.RandomizeGroupMapping);
+
+ for (const auto &userId : pool.UserIds) {
+ pb->AddUserId(std::get<2>(userId));
+ }
+
+ for (const TStoragePoolInfo::TPDiskFilter &filter : pool.PDiskFilters) {
+ Serialize(pb->AddPDiskFilter(), filter);
+ }
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TPDiskFilter *pb, const TStoragePoolInfo::TPDiskFilter &filter) {
+#define SERIALIZE_VARIABLE(NAME) (filter.NAME && (pb->AddProperty()->Set##NAME(*filter.NAME), true))
+ SERIALIZE_VARIABLE(Type);
+ SERIALIZE_VARIABLE(SharedWithOs);
+ SERIALIZE_VARIABLE(ReadCentric);
+ SERIALIZE_VARIABLE(Kind);
+#undef SERIALIZE_VARIABLE
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TPDisk *pb, const TPDiskId &id, const TPDiskInfo &pdisk) {
+ const TPDiskCategory category(pdisk.Kind);
+
+ pb->SetNodeId(id.NodeId);
+ pb->SetPDiskId(id.PDiskId);
+ pb->SetPath(pdisk.Path);
+ pb->SetType(PDiskTypeToPDiskType(category.Type()));
+ pb->SetSharedWithOs(!pdisk.SharedWithOs ? NKikimrBlobStorage::ETriStateBool::kNotSet
+ : *pdisk.SharedWithOs ? NKikimrBlobStorage::ETriStateBool::kTrue
+ : NKikimrBlobStorage::ETriStateBool::kFalse);
+ pb->SetReadCentric(!pdisk.ReadCentric ? NKikimrBlobStorage::ETriStateBool::kNotSet
+ : *pdisk.ReadCentric ? NKikimrBlobStorage::ETriStateBool::kTrue
+ : NKikimrBlobStorage::ETriStateBool::kFalse);
+ pb->SetKind(category.Kind());
+ pb->SetGuid(pdisk.Guid);
+ if (pdisk.PDiskConfig && !pb->MutablePDiskConfig()->ParseFromString(pdisk.PDiskConfig)) {
+ throw TExError() << "failed to parse PDiskConfig for PDisk# " << id;
+ }
+ pb->SetBoxId(pdisk.BoxId);
+ pb->SetNumStaticSlots(pdisk.StaticSlotUsage);
+ pb->SetDriveStatus(pdisk.Status);
+ pb->SetExpectedSlotCount(pdisk.ExpectedSlotCount);
+ pb->SetDriveStatusChangeTimestamp(pdisk.StatusTimestamp.GetValue());
+ pb->MutablePDiskMetrics()->CopyFrom(pdisk.Metrics);
+ pb->MutablePDiskMetrics()->ClearPDiskId();
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TVSlotId *pb, TVSlotId id) {
+ id.Serialize(pb);
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotInfo& vslot) {
+ pb->SetNodeID(vslot.VSlotId.NodeId);
+ pb->SetPDiskID(vslot.VSlotId.PDiskId);
+ pb->SetVDiskSlotID(vslot.VSlotId.VSlotId);
+ pb->SetPDiskGuid(vslot.PDisk->Guid);
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotId& vslotId) {
+ pb->SetNodeID(vslotId.NodeId);
+ pb->SetPDiskID(vslotId.PDiskId);
+ pb->SetVDiskSlotID(vslotId.VSlotId);
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TVSlot *pb, const TVSlotInfo &vslot,
+ const TVSlotFinder& finder) {
+ Serialize(pb->MutableVSlotId(), vslot.VSlotId);
+ pb->SetGroupId(vslot.GroupId);
+ pb->SetGroupGeneration(vslot.GroupGeneration);
+ pb->SetVDiskKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(vslot.Kind));
+ pb->SetFailRealmIdx(vslot.RingIdx);
+ pb->SetFailDomainIdx(vslot.FailDomainIdx);
+ pb->SetVDiskIdx(vslot.VDiskIdx);
+ pb->SetAllocatedSize(vslot.Metrics.GetAllocatedSize());
+ pb->MutableVDiskMetrics()->CopyFrom(vslot.Metrics);
+ pb->MutableVDiskMetrics()->ClearVDiskId();
+ pb->SetStatus(NKikimrBlobStorage::EVDiskStatus_Name(vslot.GetStatus()));
+ for (const auto& [vslotId, vdiskId] : vslot.Donors) {
+ auto *item = pb->AddDonors();
+ Serialize(item->MutableVSlotId(), vslotId);
+ VDiskIDFromVDiskID(vdiskId, item->MutableVDiskId());
+ finder(vslotId, [item](const TVSlotInfo& vslot) {
+ item->MutableVDiskMetrics()->CopyFrom(vslot.Metrics);
+ item->MutableVDiskMetrics()->ClearVDiskId();
+ });
+ }
+ pb->SetReady(vslot.IsReady);
+ }
+
+ void TBlobStorageController::Serialize(NKikimrBlobStorage::TBaseConfig::TGroup *pb, const TGroupInfo &group) {
+ pb->SetGroupId(group.ID);
+ pb->SetGroupGeneration(group.Generation);
+ pb->SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(group.ErasureSpecies));
+ for (const TVSlotInfo *vslot : group.VDisksInGroup) {
+ Serialize(pb->AddVSlotId(), vslot->VSlotId);
+ }
+ pb->SetBoxId(std::get<0>(group.StoragePoolId));
+ pb->SetStoragePoolId(std::get<1>(group.StoragePoolId));
+ pb->SetSeenOperational(group.SeenOperational);
+
+ const auto& status = group.Status;
+ pb->SetOperatingStatus(status.OperatingStatus);
+ pb->SetExpectedStatus(status.ExpectedStatus);
+ }
+
+ void TBlobStorageController::SerializeDonors(NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vdisk,
+ const TVSlotInfo& vslot, const TGroupInfo& group) {
+ if (vslot.Mood == TMood::Donor) {
+ ui32 numFailRealms = 0, numFailDomainsPerFailRealm = 0, numVDisksPerFailDomain = 0;
+ for (const TVSlotInfo *slot : group.VDisksInGroup) {
+ numFailRealms = Max(numFailRealms, slot->RingIdx + 1);
+ numFailDomainsPerFailRealm = Max(numFailDomainsPerFailRealm, slot->FailDomainIdx + 1);
+ numVDisksPerFailDomain = Max(numVDisksPerFailDomain, slot->VDiskIdx + 1);
+ }
+ Y_VERIFY(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain == group.VDisksInGroup.size());
+ auto *pb = vdisk->MutableDonorMode();
+ pb->SetNumFailRealms(numFailRealms);
+ pb->SetNumFailDomainsPerFailRealm(numFailDomainsPerFailRealm);
+ pb->SetNumVDisksPerFailDomain(numVDisksPerFailDomain);
+ pb->SetErasureSpecies(group.ErasureSpecies);
+ }
+ for (const auto& [vslotId, vdiskId] : vslot.Donors) {
+ auto *pb = vdisk->AddDonors();
+ VDiskIDFromVDiskID(vdiskId, pb->MutableVDiskId());
+ Serialize(pb->MutableVDiskLocation(), vslotId);
+ }
+ }
+
+ void TBlobStorageController::SerializeGroupInfo(NKikimrBlobStorage::TGroupInfo *group, const TGroupInfo& groupInfo,
+ const TString& storagePoolName, const TMaybe<TKikimrScopeId>& scopeId) {
+ group->SetGroupID(groupInfo.ID);
+ group->SetGroupGeneration(groupInfo.Generation);
+ group->SetErasureSpecies(groupInfo.ErasureSpecies);
+ group->SetStoragePoolName(storagePoolName);
+ group->SetDeviceType(PDiskTypeToPDiskType(groupInfo.GetCommonDeviceType()));
+
+ group->SetEncryptionMode(groupInfo.EncryptionMode.GetOrElse(0));
+ group->SetLifeCyclePhase(groupInfo.LifeCyclePhase.GetOrElse(0));
group->SetMainKeyId(groupInfo.MainKeyId.GetOrElse(""));
- group->SetEncryptedGroupKey(groupInfo.EncryptedGroupKey.GetOrElse(""));
- group->SetGroupKeyNonce(groupInfo.GroupKeyNonce.GetOrElse(0));
+ group->SetEncryptedGroupKey(groupInfo.EncryptedGroupKey.GetOrElse(""));
+ group->SetGroupKeyNonce(groupInfo.GroupKeyNonce.GetOrElse(0));
group->SetMainKeyVersion(groupInfo.MainKeyVersion.GetOrElse(0));
-
- if (scopeId) {
- auto *pb = group->MutableAcceptedScope();
- const TScopeId& x = scopeId->GetInterconnectScopeId();
- pb->SetX1(x.first);
- pb->SetX2(x.second);
- }
-
- std::vector<std::pair<TVDiskID, const TVSlotInfo*>> vdisks;
- for (const auto& vslot : groupInfo.VDisksInGroup) {
- vdisks.emplace_back(vslot->GetVDiskId(), vslot);
- }
- auto comp = [](const auto& x, const auto& y) { return x.first < y.first; };
- std::sort(vdisks.begin(), vdisks.end(), comp);
-
- TVDiskID prevVDiskId;
- NKikimrBlobStorage::TGroupInfo::TFailRealm *realm = nullptr;
- NKikimrBlobStorage::TGroupInfo::TFailRealm::TFailDomain *domain = nullptr;
- for (const auto& [vdiskId, vslot] : vdisks) {
- if (!realm || prevVDiskId.FailRealm != vdiskId.FailRealm) {
- realm = group->AddRings();
- domain = nullptr;
- }
- if (!domain || prevVDiskId.FailDomain != vdiskId.FailDomain) {
- Y_VERIFY(realm);
- domain = realm->AddFailDomains();
- }
- prevVDiskId = vdiskId;
-
- Serialize(domain->AddVDiskLocations(), *vslot);
- }
- }
-
-} // NKikimr::NBsController
+
+ if (scopeId) {
+ auto *pb = group->MutableAcceptedScope();
+ const TScopeId& x = scopeId->GetInterconnectScopeId();
+ pb->SetX1(x.first);
+ pb->SetX2(x.second);
+ }
+
+ std::vector<std::pair<TVDiskID, const TVSlotInfo*>> vdisks;
+ for (const auto& vslot : groupInfo.VDisksInGroup) {
+ vdisks.emplace_back(vslot->GetVDiskId(), vslot);
+ }
+ auto comp = [](const auto& x, const auto& y) { return x.first < y.first; };
+ std::sort(vdisks.begin(), vdisks.end(), comp);
+
+ TVDiskID prevVDiskId;
+ NKikimrBlobStorage::TGroupInfo::TFailRealm *realm = nullptr;
+ NKikimrBlobStorage::TGroupInfo::TFailRealm::TFailDomain *domain = nullptr;
+ for (const auto& [vdiskId, vslot] : vdisks) {
+ if (!realm || prevVDiskId.FailRealm != vdiskId.FailRealm) {
+ realm = group->AddRings();
+ domain = nullptr;
+ }
+ if (!domain || prevVDiskId.FailDomain != vdiskId.FailDomain) {
+ Y_VERIFY(realm);
+ domain = realm->AddFailDomains();
+ }
+ prevVDiskId = vdiskId;
+
+ Serialize(domain->AddVDiskLocations(), *vslot);
+ }
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/config.h b/ydb/core/mind/bscontroller/config.h
index 006b0578e78..c1b7a5a9707 100644
--- a/ydb/core/mind/bscontroller/config.h
+++ b/ydb/core/mind/bscontroller/config.h
@@ -1,252 +1,252 @@
-#pragma once
-
-#include "defs.h"
-#include "error.h"
-#include "impl.h"
-
-namespace NKikimr {
- namespace NBsController {
-
- class TBlobStorageController::TConfigState {
- template<typename T>
- class TCowHolder {
- T *Origin;
- THolder<T> Ptr;
- std::function<THolder<T> (T*)> Clone;
-
- public:
- TCowHolder(T *ptr, std::function<THolder<T> (T*)> clone = {})
- : Origin(ptr)
- , Clone(std::move(clone))
- {}
-
- const T &Get() const {
- return *(Ptr ? Ptr.Get() : Origin);
- }
-
- T &Unshare() {
- if (!Ptr) {
- Ptr = Clone ? Clone(Origin) : MakeHolder<T>(*Origin);
- }
- return *Ptr;
- }
-
- bool Changed() const {
- return Ptr != nullptr;
- }
-
- void Commit() {
- if (Ptr) {
- std::swap(*Origin, *Ptr);
- }
- }
- };
-
- public:
- TBlobStorageController& Self;
-
- // user-defined configuration
+#pragma once
+
+#include "defs.h"
+#include "error.h"
+#include "impl.h"
+
+namespace NKikimr {
+ namespace NBsController {
+
+ class TBlobStorageController::TConfigState {
+ template<typename T>
+ class TCowHolder {
+ T *Origin;
+ THolder<T> Ptr;
+ std::function<THolder<T> (T*)> Clone;
+
+ public:
+ TCowHolder(T *ptr, std::function<THolder<T> (T*)> clone = {})
+ : Origin(ptr)
+ , Clone(std::move(clone))
+ {}
+
+ const T &Get() const {
+ return *(Ptr ? Ptr.Get() : Origin);
+ }
+
+ T &Unshare() {
+ if (!Ptr) {
+ Ptr = Clone ? Clone(Origin) : MakeHolder<T>(*Origin);
+ }
+ return *Ptr;
+ }
+
+ bool Changed() const {
+ return Ptr != nullptr;
+ }
+
+ void Commit() {
+ if (Ptr) {
+ std::swap(*Origin, *Ptr);
+ }
+ }
+ };
+
+ public:
+ TBlobStorageController& Self;
+
+ // user-defined configuration
TCowHolder<TMap<THostConfigId, THostConfigInfo>> HostConfigs;
TCowHolder<TMap<TBoxId, TBoxInfo>> Boxes;
TCowHolder<TMap<TBoxStoragePoolId, TStoragePoolInfo>> StoragePools;
TCowHolder<TMultiMap<TBoxStoragePoolId, TGroupId>> StoragePoolGroups;
-
- // system-level configuration
- TOverlayMap<TPDiskId, TPDiskInfo> PDisks;
- TOverlayMap<TSerial, TDriveSerialInfo> DrivesSerials;
+
+ // system-level configuration
+ TOverlayMap<TPDiskId, TPDiskInfo> PDisks;
+ TOverlayMap<TSerial, TDriveSerialInfo> DrivesSerials;
TCowHolder<TMap<TNodeId, TNodeInfo>> Nodes;
- TOverlayMap<TVSlotId, TVSlotInfo> VSlots;
- TOverlayMap<TGroupId, TGroupInfo> Groups;
- TCowHolder<TMap<TGroupSpecies, TVector<TGroupId>>> IndexGroupSpeciesToGroup;
- TCowHolder<Schema::Group::ID::Type> NextGroupId;
- TCowHolder<Schema::State::NextStoragePoolId::Type> NextStoragePoolId;
-
- // helper classes
+ TOverlayMap<TVSlotId, TVSlotInfo> VSlots;
+ TOverlayMap<TGroupId, TGroupInfo> Groups;
+ TCowHolder<TMap<TGroupSpecies, TVector<TGroupId>>> IndexGroupSpeciesToGroup;
+ TCowHolder<Schema::Group::ID::Type> NextGroupId;
+ TCowHolder<Schema::State::NextStoragePoolId::Type> NextStoragePoolId;
+
+ // helper classes
using TLocationMap = THashMap<TPDiskLocation, TPDiskId>;
TLocationMap PDiskLocationMap;
TLocationMap StaticPDiskLocationMap;
-
- THostRecordMap HostRecords;
-
- ui64 UniqueId = RandomNumber<ui64>();
-
- // volatile reconfiguration state
- THashMap<TVSlotId, TPDiskId> ExplicitReconfigureMap;
- std::set<TVSlotId> SuppressDonorMode;
-
- // just-created vslots, which are not yet committed to the storage
- TSet<TVSlotId> UncommittedVSlots;
-
- // PDisks we are going to delete
- THashSet<TPDiskId> PDisksToRemove;
-
- // outgoing messages
- std::deque<std::unique_ptr<IEventHandle>> Outbox;
-
- // when the config cmd received
- const TInstant Timestamp;
-
- // various settings from controller
- const bool DonorMode;
-
- // default number for ExpectedSlotCount
- const ui32 DefaultMaxSlots;
-
- // static pdisk/vdisk states
- std::map<TVSlotId, TStaticVSlotInfo>& StaticVSlots;
- std::map<TPDiskId, TStaticPDiskInfo>& StaticPDisks;
+
+ THostRecordMap HostRecords;
+
+ ui64 UniqueId = RandomNumber<ui64>();
+
+ // volatile reconfiguration state
+ THashMap<TVSlotId, TPDiskId> ExplicitReconfigureMap;
+ std::set<TVSlotId> SuppressDonorMode;
+
+ // just-created vslots, which are not yet committed to the storage
+ TSet<TVSlotId> UncommittedVSlots;
+
+ // PDisks we are going to delete
+ THashSet<TPDiskId> PDisksToRemove;
+
+ // outgoing messages
+ std::deque<std::unique_ptr<IEventHandle>> Outbox;
+
+ // when the config cmd received
+ const TInstant Timestamp;
+
+ // various settings from controller
+ const bool DonorMode;
+
+ // default number for ExpectedSlotCount
+ const ui32 DefaultMaxSlots;
+
+ // static pdisk/vdisk states
+ std::map<TVSlotId, TStaticVSlotInfo>& StaticVSlots;
+ std::map<TPDiskId, TStaticPDiskInfo>& StaticPDisks;
const std::map<TString, TNodeId>& NodeForSerial;
-
+
TCowHolder<Schema::State::SerialManagementStage::Type> SerialManagementStage;
- TStoragePoolStat& StoragePoolStat;
-
- public:
- TConfigState(TBlobStorageController &controller, const THostRecordMap &hostRecords, TInstant timestamp)
- : Self(controller)
- , HostConfigs(&controller.HostConfigs)
- , Boxes(&controller.Boxes)
- , StoragePools(&controller.StoragePools)
- , StoragePoolGroups(&controller.StoragePoolGroups)
- , PDisks(controller.PDisks)
- , DrivesSerials(controller.DrivesSerials)
- , Nodes(&controller.Nodes)
- , VSlots(controller.VSlots)
- , Groups(controller.GroupMap)
- , IndexGroupSpeciesToGroup(&controller.IndexGroupSpeciesToGroup)
- , NextGroupId(&controller.NextGroupID)
- , NextStoragePoolId(&controller.NextStoragePoolId)
- , HostRecords(hostRecords)
- , Timestamp(timestamp)
- , DonorMode(controller.DonorMode)
- , DefaultMaxSlots(controller.DefaultMaxSlots)
- , StaticVSlots(controller.StaticVSlots)
- , StaticPDisks(controller.StaticPDisks)
+ TStoragePoolStat& StoragePoolStat;
+
+ public:
+ TConfigState(TBlobStorageController &controller, const THostRecordMap &hostRecords, TInstant timestamp)
+ : Self(controller)
+ , HostConfigs(&controller.HostConfigs)
+ , Boxes(&controller.Boxes)
+ , StoragePools(&controller.StoragePools)
+ , StoragePoolGroups(&controller.StoragePoolGroups)
+ , PDisks(controller.PDisks)
+ , DrivesSerials(controller.DrivesSerials)
+ , Nodes(&controller.Nodes)
+ , VSlots(controller.VSlots)
+ , Groups(controller.GroupMap)
+ , IndexGroupSpeciesToGroup(&controller.IndexGroupSpeciesToGroup)
+ , NextGroupId(&controller.NextGroupID)
+ , NextStoragePoolId(&controller.NextStoragePoolId)
+ , HostRecords(hostRecords)
+ , Timestamp(timestamp)
+ , DonorMode(controller.DonorMode)
+ , DefaultMaxSlots(controller.DefaultMaxSlots)
+ , StaticVSlots(controller.StaticVSlots)
+ , StaticPDisks(controller.StaticPDisks)
, NodeForSerial(controller.NodeForSerial)
, SerialManagementStage(&controller.SerialManagementStage)
- , StoragePoolStat(*controller.StoragePoolStat)
- {
- Y_VERIFY(HostRecords);
- Init();
- }
-
- void Commit() {
- HostConfigs.Commit();
- Boxes.Commit();
- StoragePools.Commit();
- StoragePoolGroups.Commit();
- PDisks.Commit();
+ , StoragePoolStat(*controller.StoragePoolStat)
+ {
+ Y_VERIFY(HostRecords);
+ Init();
+ }
+
+ void Commit() {
+ HostConfigs.Commit();
+ Boxes.Commit();
+ StoragePools.Commit();
+ StoragePoolGroups.Commit();
+ PDisks.Commit();
DrivesSerials.Commit();
- Nodes.Commit();
- VSlots.Commit();
- Groups.Commit();
- IndexGroupSpeciesToGroup.Commit();
- NextGroupId.Commit();
- NextStoragePoolId.Commit();
+ Nodes.Commit();
+ VSlots.Commit();
+ Groups.Commit();
+ IndexGroupSpeciesToGroup.Commit();
+ NextGroupId.Commit();
+ NextStoragePoolId.Commit();
SerialManagementStage.Commit();
- }
-
- void Rollback() {
- PDisks.Rollback();
- VSlots.Rollback();
- Groups.Rollback();
- }
-
- bool Changed() const {
- return HostConfigs.Changed() || Boxes.Changed() || StoragePools.Changed() ||
+ }
+
+ void Rollback() {
+ PDisks.Rollback();
+ VSlots.Rollback();
+ Groups.Rollback();
+ }
+
+ bool Changed() const {
+ return HostConfigs.Changed() || Boxes.Changed() || StoragePools.Changed() ||
StoragePoolGroups.Changed() || PDisks.Changed() || DrivesSerials.Changed() || Nodes.Changed() ||
VSlots.Changed() || Groups.Changed() || IndexGroupSpeciesToGroup.Changed() || NextGroupId.Changed() ||
- NextStoragePoolId.Changed() || SerialManagementStage.Changed();
- }
-
- bool NormalizeHostKey(NKikimrBlobStorage::THostKey *host) const {
- if (!host->GetNodeId()) {
- const THostId key(host->GetFqdn(), host->GetIcPort());
- if (const auto& nodeId = HostRecords->GetNodeId(key)) {
- host->SetNodeId(*nodeId);
- return true;
- } else {
- return false;
- }
- }
-
- if (!host->GetFqdn() && !host->GetIcPort()) {
- if (const auto& hostId = HostRecords->GetHostId(host->GetNodeId())) {
- host->SetFqdn(std::get<0>(*hostId));
- host->SetIcPort(std::get<1>(*hostId));
- return true;
- } else {
- return false;
- }
- }
-
- // when both fqdn:port and node id were filled, we have to ensure that they match each other
- return HostRecords->GetHostId(host->GetNodeId()) == std::make_tuple(host->GetFqdn(), host->GetIcPort());
- }
-
- NKikimrBlobStorage::THostKey NormalizeHostKey(const NKikimrBlobStorage::THostKey& host) const {
- NKikimrBlobStorage::THostKey res(host);
- if (!NormalizeHostKey(&res)) {
- throw TExHostNotFound(host) << "HostKey# " << host.DebugString() << " incorrect";
- }
- return res;
- }
-
- void DestroyVSlot(const TVSlotId vslotId);
-
- void CheckConsistency() const;
-
- void ApplyConfigUpdates();
-
- private:
- void Init() {
- PDisks.ForEach([this](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
- const TNodeId &nodeId = pdiskId.NodeId;
+ NextStoragePoolId.Changed() || SerialManagementStage.Changed();
+ }
+
+ bool NormalizeHostKey(NKikimrBlobStorage::THostKey *host) const {
+ if (!host->GetNodeId()) {
+ const THostId key(host->GetFqdn(), host->GetIcPort());
+ if (const auto& nodeId = HostRecords->GetNodeId(key)) {
+ host->SetNodeId(*nodeId);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ if (!host->GetFqdn() && !host->GetIcPort()) {
+ if (const auto& hostId = HostRecords->GetHostId(host->GetNodeId())) {
+ host->SetFqdn(std::get<0>(*hostId));
+ host->SetIcPort(std::get<1>(*hostId));
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // when both fqdn:port and node id were filled, we have to ensure that they match each other
+ return HostRecords->GetHostId(host->GetNodeId()) == std::make_tuple(host->GetFqdn(), host->GetIcPort());
+ }
+
+ NKikimrBlobStorage::THostKey NormalizeHostKey(const NKikimrBlobStorage::THostKey& host) const {
+ NKikimrBlobStorage::THostKey res(host);
+ if (!NormalizeHostKey(&res)) {
+ throw TExHostNotFound(host) << "HostKey# " << host.DebugString() << " incorrect";
+ }
+ return res;
+ }
+
+ void DestroyVSlot(const TVSlotId vslotId);
+
+ void CheckConsistency() const;
+
+ void ApplyConfigUpdates();
+
+ private:
+ void Init() {
+ PDisks.ForEach([this](const TPDiskId& pdiskId, const TPDiskInfo& pdiskInfo) {
+ const TNodeId &nodeId = pdiskId.NodeId;
TPDiskLocation location{nodeId, pdiskInfo.PathOrSerial()};
PDiskLocationMap.emplace(location, pdiskId);
- });
- for (const auto& [pdiskId, pdisk] : StaticPDisks) {
+ });
+ for (const auto& [pdiskId, pdisk] : StaticPDisks) {
TPDiskLocation location{pdiskId.NodeId, pdisk.Path};
StaticPDiskLocationMap.emplace(location, pdiskId);
- }
- }
-
- private:
- template<typename TCommand, typename TKey, typename TValue>
- static ui64 CheckGeneration(const TCommand &cmd, const TMap<TKey, TValue> &map, const TKey &id) {
- const ui64 cmdGen = cmd.GetItemConfigGeneration();
- const auto it = map.find(id);
- const ui64 itemGen = it != map.end() ? it->second.Generation.GetOrElse(1) : 0;
- if (cmdGen != Max<ui64>() && cmdGen != itemGen) {
- throw TExItemConfigGenerationMismatch(cmdGen, itemGen);
- }
- return itemGen + 1;
- }
-
- friend class TBlobStorageController::TTxConfigCmd;
- using TStatus = NKikimrBlobStorage::TConfigResponse::TStatus;
- void ExecuteStep(const NKikimrBlobStorage::TDefineBox& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TReadBox& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDeleteBox& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TMergeBoxes& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TUpdateDriveStatus& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TReadDriveStatus& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDefineHostConfig& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TReadHostConfig& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDeleteHostConfig& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDefineStoragePool& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TReadStoragePool& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDeleteStoragePool& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TProposeStoragePools& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TReassignGroupDisk& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TMoveGroups& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TQueryBaseConfig& cmd, TStatus& status);
- void ExecuteStep(const NKikimrBlobStorage::TDropDonorDisk& cmd, TStatus& status);
+ }
+ }
+
+ private:
+ template<typename TCommand, typename TKey, typename TValue>
+ static ui64 CheckGeneration(const TCommand &cmd, const TMap<TKey, TValue> &map, const TKey &id) {
+ const ui64 cmdGen = cmd.GetItemConfigGeneration();
+ const auto it = map.find(id);
+ const ui64 itemGen = it != map.end() ? it->second.Generation.GetOrElse(1) : 0;
+ if (cmdGen != Max<ui64>() && cmdGen != itemGen) {
+ throw TExItemConfigGenerationMismatch(cmdGen, itemGen);
+ }
+ return itemGen + 1;
+ }
+
+ friend class TBlobStorageController::TTxConfigCmd;
+ using TStatus = NKikimrBlobStorage::TConfigResponse::TStatus;
+ void ExecuteStep(const NKikimrBlobStorage::TDefineBox& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TReadBox& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDeleteBox& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TMergeBoxes& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TUpdateDriveStatus& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TReadDriveStatus& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDefineHostConfig& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TReadHostConfig& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDeleteHostConfig& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDefineStoragePool& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TReadStoragePool& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDeleteStoragePool& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TProposeStoragePools& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TReassignGroupDisk& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TMoveGroups& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TQueryBaseConfig& cmd, TStatus& status);
+ void ExecuteStep(const NKikimrBlobStorage::TDropDonorDisk& cmd, TStatus& status);
void ExecuteStep(const NKikimrBlobStorage::TAddDriveSerial& cmd, TStatus& status);
void ExecuteStep(const NKikimrBlobStorage::TRemoveDriveSerial& cmd, TStatus& status);
void ExecuteStep(const NKikimrBlobStorage::TForgetDriveSerial& cmd, TStatus& status);
void ExecuteStep(const NKikimrBlobStorage::TMigrateToSerial& cmd, TStatus& status);
- };
-
- } // NBsController
-} // NKikimr
+ };
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/config_cmd.cpp b/ydb/core/mind/bscontroller/config_cmd.cpp
index 2fc925a9cd7..cadf0eaa65c 100644
--- a/ydb/core/mind/bscontroller/config_cmd.cpp
+++ b/ydb/core/mind/bscontroller/config_cmd.cpp
@@ -1,345 +1,345 @@
-#include "impl.h"
-#include "config.h"
-#include "select_groups.h"
-
-namespace NKikimr::NBsController {
-
- class TBlobStorageController::TBlobStorageController::TTxConfigCmd
- : public TTransactionBase<TBlobStorageController>
- {
+#include "impl.h"
+#include "config.h"
+#include "select_groups.h"
+
+namespace NKikimr::NBsController {
+
+ class TBlobStorageController::TBlobStorageController::TTxConfigCmd
+ : public TTransactionBase<TBlobStorageController>
+ {
const TActorId NotifyId;
- const ui64 Cookie;
- const NKikimrBlobStorage::TConfigRequest Cmd;
- const bool SelfHeal;
- THolder<TEvBlobStorage::TEvControllerConfigResponse> Ev;
- NKikimrBlobStorage::TConfigResponse *Response;
- std::optional<TConfigState> State;
- bool Success = true;
- TString Error;
-
- public:
- TTxConfigCmd(const NKikimrBlobStorage::TConfigRequest &cmd, const TActorId &notifyId, ui64 cookie,
- bool selfHeal, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , NotifyId(notifyId)
- , Cookie(cookie)
- , Cmd(cmd)
- , SelfHeal(selfHeal)
- , Ev(new TEvBlobStorage::TEvControllerConfigResponse())
- , Response(Ev->Record.MutableResponse())
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_CONFIG_CMD; }
-
- template<typename TCallback>
- void WrapCommand(TCallback&& callback) {
- auto *status = Response->AddStatus();
- try {
- callback();
- status->SetSuccess(true);
- } catch (const TExError& e) {
- Success = false;
- Error = e.what();
- e.FillInStatus(*status);
- } catch (const std::exception& e) {
- Success = false;
- Error = TStringBuilder() << "unknown exception: " << e.what();
- status->SetErrorDescription(Error);
- }
- }
-
- void Finish() {
- Response->SetSuccess(Success);
- if (!Success) {
- Response->SetErrorDescription(Error);
- }
- }
-
- bool ExecuteSoleCommand(const NKikimrBlobStorage::TConfigRequest::TCommand& cmd, TTransactionContext& txc) {
- NIceDb::TNiceDb db(txc.DB);
- switch (cmd.GetCommandCase()) {
- case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal:
- Self->SelfHealEnable = cmd.GetEnableSelfHeal().GetEnable();
- db.Table<Schema::State>().Key(true).Update<Schema::State::SelfHealEnable>(Self->SelfHealEnable);
- return true;
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableDonorMode:
- Self->DonorMode = cmd.GetEnableDonorMode().GetEnable();
- db.Table<Schema::State>().Key(true).Update<Schema::State::DonorModeEnable>(Self->DonorMode);
- return true;
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kSetScrubPeriodicity: {
- const ui32 seconds = cmd.GetSetScrubPeriodicity().GetScrubPeriodicity();
- Self->ScrubPeriodicity = TDuration::Seconds(seconds);
- db.Table<Schema::State>().Key(true).Update<Schema::State::ScrubPeriodicity>(seconds);
- Self->ScrubState.OnScrubPeriodicityChange();
- return true;
- }
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kSetPDiskSpaceMarginPromille: {
- const ui32 value = cmd.GetSetPDiskSpaceMarginPromille().GetPDiskSpaceMarginPromille();
- Self->PDiskSpaceMarginPromille = value;
- db.Table<Schema::State>().Key(true).Update<Schema::State::PDiskSpaceMarginPromille>(value);
- return true;
- }
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateSettings: {
- const auto& settings = cmd.GetUpdateSettings();
- using T = Schema::State;
- for (ui32 value : settings.GetDefaultMaxSlots()) {
- Self->DefaultMaxSlots = value;
- db.Table<T>().Key(true).Update<T::DefaultMaxSlots>(Self->DefaultMaxSlots);
- }
- for (bool value : settings.GetEnableSelfHeal()) {
- Self->SelfHealEnable = value;
- db.Table<T>().Key(true).Update<T::SelfHealEnable>(Self->SelfHealEnable);
- }
- for (bool value : settings.GetEnableDonorMode()) {
- Self->DonorMode = value;
- db.Table<T>().Key(true).Update<T::DonorModeEnable>(Self->DonorMode);
- }
- for (ui64 value : settings.GetScrubPeriodicitySeconds()) {
- Self->ScrubPeriodicity = TDuration::Seconds(value);
- db.Table<T>().Key(true).Update<T::ScrubPeriodicity>(Self->ScrubPeriodicity.Seconds());
- Self->ScrubState.OnScrubPeriodicityChange();
- }
- for (ui32 value : settings.GetPDiskSpaceMarginPromille()) {
- Self->PDiskSpaceMarginPromille = value;
- db.Table<T>().Key(true).Update<T::PDiskSpaceMarginPromille>(Self->PDiskSpaceMarginPromille);
- }
- for (ui32 value : settings.GetGroupReserveMin()) {
- Self->GroupReserveMin = value;
- db.Table<T>().Key(true).Update<T::GroupReserveMin>(Self->GroupReserveMin);
- Self->SysViewChangedSettings = true;
- }
- for (ui32 value : settings.GetGroupReservePartPPM()) {
- Self->GroupReservePart = value;
- db.Table<T>().Key(true).Update<T::GroupReservePart>(Self->GroupReservePart);
- Self->SysViewChangedSettings = true;
- }
- for (ui32 value : settings.GetMaxScrubbedDisksAtOnce()) {
- Self->MaxScrubbedDisksAtOnce = value;
- db.Table<T>().Key(true).Update<T::MaxScrubbedDisksAtOnce>(Self->MaxScrubbedDisksAtOnce);
- Self->ScrubState.OnMaxScrubbedDisksAtOnceChange();
- }
+ const ui64 Cookie;
+ const NKikimrBlobStorage::TConfigRequest Cmd;
+ const bool SelfHeal;
+ THolder<TEvBlobStorage::TEvControllerConfigResponse> Ev;
+ NKikimrBlobStorage::TConfigResponse *Response;
+ std::optional<TConfigState> State;
+ bool Success = true;
+ TString Error;
+
+ public:
+ TTxConfigCmd(const NKikimrBlobStorage::TConfigRequest &cmd, const TActorId &notifyId, ui64 cookie,
+ bool selfHeal, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , NotifyId(notifyId)
+ , Cookie(cookie)
+ , Cmd(cmd)
+ , SelfHeal(selfHeal)
+ , Ev(new TEvBlobStorage::TEvControllerConfigResponse())
+ , Response(Ev->Record.MutableResponse())
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_CONFIG_CMD; }
+
+ template<typename TCallback>
+ void WrapCommand(TCallback&& callback) {
+ auto *status = Response->AddStatus();
+ try {
+ callback();
+ status->SetSuccess(true);
+ } catch (const TExError& e) {
+ Success = false;
+ Error = e.what();
+ e.FillInStatus(*status);
+ } catch (const std::exception& e) {
+ Success = false;
+ Error = TStringBuilder() << "unknown exception: " << e.what();
+ status->SetErrorDescription(Error);
+ }
+ }
+
+ void Finish() {
+ Response->SetSuccess(Success);
+ if (!Success) {
+ Response->SetErrorDescription(Error);
+ }
+ }
+
+ bool ExecuteSoleCommand(const NKikimrBlobStorage::TConfigRequest::TCommand& cmd, TTransactionContext& txc) {
+ NIceDb::TNiceDb db(txc.DB);
+ switch (cmd.GetCommandCase()) {
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal:
+ Self->SelfHealEnable = cmd.GetEnableSelfHeal().GetEnable();
+ db.Table<Schema::State>().Key(true).Update<Schema::State::SelfHealEnable>(Self->SelfHealEnable);
+ return true;
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableDonorMode:
+ Self->DonorMode = cmd.GetEnableDonorMode().GetEnable();
+ db.Table<Schema::State>().Key(true).Update<Schema::State::DonorModeEnable>(Self->DonorMode);
+ return true;
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kSetScrubPeriodicity: {
+ const ui32 seconds = cmd.GetSetScrubPeriodicity().GetScrubPeriodicity();
+ Self->ScrubPeriodicity = TDuration::Seconds(seconds);
+ db.Table<Schema::State>().Key(true).Update<Schema::State::ScrubPeriodicity>(seconds);
+ Self->ScrubState.OnScrubPeriodicityChange();
+ return true;
+ }
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kSetPDiskSpaceMarginPromille: {
+ const ui32 value = cmd.GetSetPDiskSpaceMarginPromille().GetPDiskSpaceMarginPromille();
+ Self->PDiskSpaceMarginPromille = value;
+ db.Table<Schema::State>().Key(true).Update<Schema::State::PDiskSpaceMarginPromille>(value);
+ return true;
+ }
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateSettings: {
+ const auto& settings = cmd.GetUpdateSettings();
+ using T = Schema::State;
+ for (ui32 value : settings.GetDefaultMaxSlots()) {
+ Self->DefaultMaxSlots = value;
+ db.Table<T>().Key(true).Update<T::DefaultMaxSlots>(Self->DefaultMaxSlots);
+ }
+ for (bool value : settings.GetEnableSelfHeal()) {
+ Self->SelfHealEnable = value;
+ db.Table<T>().Key(true).Update<T::SelfHealEnable>(Self->SelfHealEnable);
+ }
+ for (bool value : settings.GetEnableDonorMode()) {
+ Self->DonorMode = value;
+ db.Table<T>().Key(true).Update<T::DonorModeEnable>(Self->DonorMode);
+ }
+ for (ui64 value : settings.GetScrubPeriodicitySeconds()) {
+ Self->ScrubPeriodicity = TDuration::Seconds(value);
+ db.Table<T>().Key(true).Update<T::ScrubPeriodicity>(Self->ScrubPeriodicity.Seconds());
+ Self->ScrubState.OnScrubPeriodicityChange();
+ }
+ for (ui32 value : settings.GetPDiskSpaceMarginPromille()) {
+ Self->PDiskSpaceMarginPromille = value;
+ db.Table<T>().Key(true).Update<T::PDiskSpaceMarginPromille>(Self->PDiskSpaceMarginPromille);
+ }
+ for (ui32 value : settings.GetGroupReserveMin()) {
+ Self->GroupReserveMin = value;
+ db.Table<T>().Key(true).Update<T::GroupReserveMin>(Self->GroupReserveMin);
+ Self->SysViewChangedSettings = true;
+ }
+ for (ui32 value : settings.GetGroupReservePartPPM()) {
+ Self->GroupReservePart = value;
+ db.Table<T>().Key(true).Update<T::GroupReservePart>(Self->GroupReservePart);
+ Self->SysViewChangedSettings = true;
+ }
+ for (ui32 value : settings.GetMaxScrubbedDisksAtOnce()) {
+ Self->MaxScrubbedDisksAtOnce = value;
+ db.Table<T>().Key(true).Update<T::MaxScrubbedDisksAtOnce>(Self->MaxScrubbedDisksAtOnce);
+ Self->ScrubState.OnMaxScrubbedDisksAtOnceChange();
+ }
for (auto value : settings.GetPDiskSpaceColorBorder()) {
Self->PDiskSpaceColorBorder = static_cast<T::PDiskSpaceColorBorder::Type>(value);
db.Table<T>().Key(true).Update<T::PDiskSpaceColorBorder>(Self->PDiskSpaceColorBorder);
}
- return true;
- }
-
- default:
- return false;
- }
- }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_CONFIG_USEC);
- THPTimer timer;
-
- // check if there is some special sole command
- if (Cmd.CommandSize() == 1) {
- bool res = true;
- WrapCommand([&] {
- res = ExecuteSoleCommand(Cmd.GetCommand(0), txc);
- });
- if (res) {
- Finish();
- LogCommand(txc, TDuration::Seconds(timer.Passed()));
- return true;
- }
- Y_VERIFY(Success);
- Response->MutableStatus()->RemoveLast();
- }
-
- State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
- State->CheckConsistency();
-
- TString m;
- google::protobuf::TextFormat::Printer printer;
- printer.SetSingleLineMode(true);
- printer.PrintToString(Cmd, &m);
- STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA02, "Generic command",
- (UniqueId, State->UniqueId),
- (Request, Cmd),
- (SelfHeal, SelfHeal));
-
- for (const auto& step : Cmd.GetCommand()) {
- WrapCommand([&] {
- THPTimer timer;
- bool fitPDisks = false;
- bool fitGroups = false;
- auto& status = *Response->MutableStatus()->rbegin();
- ExecuteStep(*State, step, status, fitPDisks, fitGroups);
- State->CheckConsistency();
- if (fitPDisks) {
- Self->FitPDisksForUserConfig(*State);
- State->CheckConsistency();
- }
- if (fitGroups) {
- std::deque<ui64> expectedSlotSize;
- if (step.GetCommandCase() == NKikimrBlobStorage::TConfigRequest::TCommand::kDefineStoragePool) {
- const auto& cmd = step.GetDefineStoragePool();
- for (ui64 size : cmd.GetExpectedGroupSlotSize()) {
- expectedSlotSize.push_back(size);
- }
- }
- const auto availabilityDomainId = AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID());
- Self->FitGroupsForUserConfig(*State, availabilityDomainId, Cmd, std::move(expectedSlotSize), status);
- State->CheckConsistency();
- }
- const TDuration passed = TDuration::Seconds(timer.Passed());
- switch (step.GetCommandCase()) {
-#define MAP_TIMING(CMD, NAME) \
- case NKikimrBlobStorage::TConfigRequest::TCommand::k ## CMD: \
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_CONFIGCMD_## NAME ##_USEC].Increment(passed.MicroSeconds()); \
- break;
- MAP_TIMING(DefineHostConfig, DEFINE_HOST_CONFIG)
- MAP_TIMING(ReadHostConfig, READ_HOST_CONFIG)
- MAP_TIMING(DeleteHostConfig, DELETE_HOST_CONFIG)
- MAP_TIMING(DefineBox, DEFINE_BOX)
- MAP_TIMING(ReadBox, READ_BOX)
- MAP_TIMING(DeleteBox, DELETE_BOX)
- MAP_TIMING(DefineStoragePool, DEFINE_STORAGE_POOL)
- MAP_TIMING(ReadStoragePool, READ_STORAGE_POOL)
- MAP_TIMING(DeleteStoragePool, DELETE_STORAGE_POOL)
- MAP_TIMING(UpdateDriveStatus, UPDATE_DRIVE_STATUS)
- MAP_TIMING(ReadDriveStatus, READ_DRIVE_STATUS)
- MAP_TIMING(ProposeStoragePools, PROPOSE_STORAGE_POOLS)
- MAP_TIMING(QueryBaseConfig, QUERY_BASE_CONFIG)
- MAP_TIMING(MergeBoxes, MERGE_BOXES)
- MAP_TIMING(MoveGroups, MOVE_GROUPS)
- MAP_TIMING(AddMigrationPlan, ADD_MIGRATION_PLAN)
- MAP_TIMING(DeleteMigrationPlan, DELETE_MIGRATION_PLAN)
- MAP_TIMING(DeclareIntent, DECLARE_INTENT)
- MAP_TIMING(ReadIntent, READ_INTENT)
- MAP_TIMING(DropDonorDisk, DROP_DONOR_DISK)
- MAP_TIMING(ReassignGroupDisk, REASSIGN_GROUP_DISK)
-
- default:
- break;
- }
- });
- if (!Success) {
- break;
- }
- }
-
- if (Success && Cmd.GetRollback()) {
- Success = false;
- Error = "transaction rollback";
- }
-
- if (Success && SelfHeal && !Self->SelfHealEnable) {
- Success = false;
- Error = "SelfHeal is disabled, transaction rollback";
- }
-
- const bool doLogCommand = Success && State->Changed();
- Success = Success && Self->CommitConfigUpdates(*State, Cmd.GetIgnoreGroupFailModelChecks(),
- Cmd.GetIgnoreDegradedGroupsChecks(), txc, &Error);
-
- Finish();
- if (doLogCommand) {
- LogCommand(txc, TDuration::Seconds(timer.Passed()));
- }
-
- STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA03, "Transaction complete",
- (UniqueId, State->UniqueId),
- (Status, Success ? "commit" : "rollback"),
- (Error, Error));
-
- if (SelfHeal) {
- const auto counter = Success
- ? NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_OK
- : NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_ERR;
- Self->TabletCounters->Cumulative()[counter].Increment(1);
- }
-
- if (!Success) {
- // rollback transaction
- std::exchange(State, std::nullopt)->Rollback();
- }
-
- return true;
- }
-
- void LogCommand(TTransactionContext& txc, TDuration executionTime) {
- // update operation log for write transaction
- NIceDb::TNiceDb db(txc.DB);
- TString requestBuffer, responseBuffer;
+ return true;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_CONFIG_USEC);
+ THPTimer timer;
+
+ // check if there is some special sole command
+ if (Cmd.CommandSize() == 1) {
+ bool res = true;
+ WrapCommand([&] {
+ res = ExecuteSoleCommand(Cmd.GetCommand(0), txc);
+ });
+ if (res) {
+ Finish();
+ LogCommand(txc, TDuration::Seconds(timer.Passed()));
+ return true;
+ }
+ Y_VERIFY(Success);
+ Response->MutableStatus()->RemoveLast();
+ }
+
+ State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
+ State->CheckConsistency();
+
+ TString m;
+ google::protobuf::TextFormat::Printer printer;
+ printer.SetSingleLineMode(true);
+ printer.PrintToString(Cmd, &m);
+ STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA02, "Generic command",
+ (UniqueId, State->UniqueId),
+ (Request, Cmd),
+ (SelfHeal, SelfHeal));
+
+ for (const auto& step : Cmd.GetCommand()) {
+ WrapCommand([&] {
+ THPTimer timer;
+ bool fitPDisks = false;
+ bool fitGroups = false;
+ auto& status = *Response->MutableStatus()->rbegin();
+ ExecuteStep(*State, step, status, fitPDisks, fitGroups);
+ State->CheckConsistency();
+ if (fitPDisks) {
+ Self->FitPDisksForUserConfig(*State);
+ State->CheckConsistency();
+ }
+ if (fitGroups) {
+ std::deque<ui64> expectedSlotSize;
+ if (step.GetCommandCase() == NKikimrBlobStorage::TConfigRequest::TCommand::kDefineStoragePool) {
+ const auto& cmd = step.GetDefineStoragePool();
+ for (ui64 size : cmd.GetExpectedGroupSlotSize()) {
+ expectedSlotSize.push_back(size);
+ }
+ }
+ const auto availabilityDomainId = AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID());
+ Self->FitGroupsForUserConfig(*State, availabilityDomainId, Cmd, std::move(expectedSlotSize), status);
+ State->CheckConsistency();
+ }
+ const TDuration passed = TDuration::Seconds(timer.Passed());
+ switch (step.GetCommandCase()) {
+#define MAP_TIMING(CMD, NAME) \
+ case NKikimrBlobStorage::TConfigRequest::TCommand::k ## CMD: \
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_CONFIGCMD_## NAME ##_USEC].Increment(passed.MicroSeconds()); \
+ break;
+ MAP_TIMING(DefineHostConfig, DEFINE_HOST_CONFIG)
+ MAP_TIMING(ReadHostConfig, READ_HOST_CONFIG)
+ MAP_TIMING(DeleteHostConfig, DELETE_HOST_CONFIG)
+ MAP_TIMING(DefineBox, DEFINE_BOX)
+ MAP_TIMING(ReadBox, READ_BOX)
+ MAP_TIMING(DeleteBox, DELETE_BOX)
+ MAP_TIMING(DefineStoragePool, DEFINE_STORAGE_POOL)
+ MAP_TIMING(ReadStoragePool, READ_STORAGE_POOL)
+ MAP_TIMING(DeleteStoragePool, DELETE_STORAGE_POOL)
+ MAP_TIMING(UpdateDriveStatus, UPDATE_DRIVE_STATUS)
+ MAP_TIMING(ReadDriveStatus, READ_DRIVE_STATUS)
+ MAP_TIMING(ProposeStoragePools, PROPOSE_STORAGE_POOLS)
+ MAP_TIMING(QueryBaseConfig, QUERY_BASE_CONFIG)
+ MAP_TIMING(MergeBoxes, MERGE_BOXES)
+ MAP_TIMING(MoveGroups, MOVE_GROUPS)
+ MAP_TIMING(AddMigrationPlan, ADD_MIGRATION_PLAN)
+ MAP_TIMING(DeleteMigrationPlan, DELETE_MIGRATION_PLAN)
+ MAP_TIMING(DeclareIntent, DECLARE_INTENT)
+ MAP_TIMING(ReadIntent, READ_INTENT)
+ MAP_TIMING(DropDonorDisk, DROP_DONOR_DISK)
+ MAP_TIMING(ReassignGroupDisk, REASSIGN_GROUP_DISK)
+
+ default:
+ break;
+ }
+ });
+ if (!Success) {
+ break;
+ }
+ }
+
+ if (Success && Cmd.GetRollback()) {
+ Success = false;
+ Error = "transaction rollback";
+ }
+
+ if (Success && SelfHeal && !Self->SelfHealEnable) {
+ Success = false;
+ Error = "SelfHeal is disabled, transaction rollback";
+ }
+
+ const bool doLogCommand = Success && State->Changed();
+ Success = Success && Self->CommitConfigUpdates(*State, Cmd.GetIgnoreGroupFailModelChecks(),
+ Cmd.GetIgnoreDegradedGroupsChecks(), txc, &Error);
+
+ Finish();
+ if (doLogCommand) {
+ LogCommand(txc, TDuration::Seconds(timer.Passed()));
+ }
+
+ STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA03, "Transaction complete",
+ (UniqueId, State->UniqueId),
+ (Status, Success ? "commit" : "rollback"),
+ (Error, Error));
+
+ if (SelfHeal) {
+ const auto counter = Success
+ ? NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_OK
+ : NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_ERR;
+ Self->TabletCounters->Cumulative()[counter].Increment(1);
+ }
+
+ if (!Success) {
+ // rollback transaction
+ std::exchange(State, std::nullopt)->Rollback();
+ }
+
+ return true;
+ }
+
+ void LogCommand(TTransactionContext& txc, TDuration executionTime) {
+ // update operation log for write transaction
+ NIceDb::TNiceDb db(txc.DB);
+ TString requestBuffer, responseBuffer;
Y_PROTOBUF_SUPPRESS_NODISCARD Cmd.SerializeToString(&requestBuffer);
Y_PROTOBUF_SUPPRESS_NODISCARD Response->SerializeToString(&responseBuffer);
- db.Table<Schema::OperationLog>().Key(Self->NextOperationLogIndex).Update(
- NIceDb::TUpdate<Schema::OperationLog::Timestamp>(TActivationContext::Now()),
- NIceDb::TUpdate<Schema::OperationLog::Request>(requestBuffer),
- NIceDb::TUpdate<Schema::OperationLog::Response>(responseBuffer),
- NIceDb::TUpdate<Schema::OperationLog::ExecutionTime>(executionTime));
- db.Table<Schema::State>().Key(true).Update(
- NIceDb::TUpdate<Schema::State::NextOperationLogIndex>(++Self->NextOperationLogIndex));
- }
-
- void ExecuteStep(TConfigState& state, const NKikimrBlobStorage::TConfigRequest::TCommand& cmd,
- NKikimrBlobStorage::TConfigResponse::TStatus& status, bool& fitPDisks, bool& fitGroups) {
- switch (cmd.GetCommandCase()) {
-#define HANDLE_COMMAND(NAME, FP, FG) \
- case NKikimrBlobStorage::TConfigRequest::TCommand::k ## NAME: \
- if (FG) { \
- state.ExplicitReconfigureMap.clear(); \
- state.SuppressDonorMode.clear(); \
- } \
- state.ExecuteStep(cmd.Get ## NAME(), status); \
- fitPDisks = FP; \
- fitGroups = FG; \
- break;
-
- HANDLE_COMMAND(DefineHostConfig, true, false)
- HANDLE_COMMAND(ReadHostConfig, false, false)
- HANDLE_COMMAND(DeleteHostConfig, false, false)
- HANDLE_COMMAND(DefineBox, true, false)
- HANDLE_COMMAND(ReadBox, false, false)
- HANDLE_COMMAND(DeleteBox, true, false)
- HANDLE_COMMAND(DefineStoragePool, false, true )
- HANDLE_COMMAND(ReadStoragePool, false, false)
- HANDLE_COMMAND(DeleteStoragePool, false, false)
- HANDLE_COMMAND(UpdateDriveStatus, false, true )
- HANDLE_COMMAND(ReadDriveStatus, false, false)
- HANDLE_COMMAND(ProposeStoragePools, false, false)
- HANDLE_COMMAND(QueryBaseConfig, false, false)
- HANDLE_COMMAND(ReassignGroupDisk, false, true )
- HANDLE_COMMAND(MergeBoxes, false, false)
- HANDLE_COMMAND(MoveGroups, false, false)
- HANDLE_COMMAND(DropDonorDisk, false, false)
+ db.Table<Schema::OperationLog>().Key(Self->NextOperationLogIndex).Update(
+ NIceDb::TUpdate<Schema::OperationLog::Timestamp>(TActivationContext::Now()),
+ NIceDb::TUpdate<Schema::OperationLog::Request>(requestBuffer),
+ NIceDb::TUpdate<Schema::OperationLog::Response>(responseBuffer),
+ NIceDb::TUpdate<Schema::OperationLog::ExecutionTime>(executionTime));
+ db.Table<Schema::State>().Key(true).Update(
+ NIceDb::TUpdate<Schema::State::NextOperationLogIndex>(++Self->NextOperationLogIndex));
+ }
+
+ void ExecuteStep(TConfigState& state, const NKikimrBlobStorage::TConfigRequest::TCommand& cmd,
+ NKikimrBlobStorage::TConfigResponse::TStatus& status, bool& fitPDisks, bool& fitGroups) {
+ switch (cmd.GetCommandCase()) {
+#define HANDLE_COMMAND(NAME, FP, FG) \
+ case NKikimrBlobStorage::TConfigRequest::TCommand::k ## NAME: \
+ if (FG) { \
+ state.ExplicitReconfigureMap.clear(); \
+ state.SuppressDonorMode.clear(); \
+ } \
+ state.ExecuteStep(cmd.Get ## NAME(), status); \
+ fitPDisks = FP; \
+ fitGroups = FG; \
+ break;
+
+ HANDLE_COMMAND(DefineHostConfig, true, false)
+ HANDLE_COMMAND(ReadHostConfig, false, false)
+ HANDLE_COMMAND(DeleteHostConfig, false, false)
+ HANDLE_COMMAND(DefineBox, true, false)
+ HANDLE_COMMAND(ReadBox, false, false)
+ HANDLE_COMMAND(DeleteBox, true, false)
+ HANDLE_COMMAND(DefineStoragePool, false, true )
+ HANDLE_COMMAND(ReadStoragePool, false, false)
+ HANDLE_COMMAND(DeleteStoragePool, false, false)
+ HANDLE_COMMAND(UpdateDriveStatus, false, true )
+ HANDLE_COMMAND(ReadDriveStatus, false, false)
+ HANDLE_COMMAND(ProposeStoragePools, false, false)
+ HANDLE_COMMAND(QueryBaseConfig, false, false)
+ HANDLE_COMMAND(ReassignGroupDisk, false, true )
+ HANDLE_COMMAND(MergeBoxes, false, false)
+ HANDLE_COMMAND(MoveGroups, false, false)
+ HANDLE_COMMAND(DropDonorDisk, false, false)
HANDLE_COMMAND(AddDriveSerial, true, false)
HANDLE_COMMAND(RemoveDriveSerial, true, false)
HANDLE_COMMAND(ForgetDriveSerial, false, false)
HANDLE_COMMAND(MigrateToSerial, false, false)
-
- default:
- throw TExError() << "unsupported command";
- }
- }
-
- void Complete(const TActorContext&) override {
- if (auto state = std::exchange(State, std::nullopt)) {
- state->ApplyConfigUpdates();
- }
- TActivationContext::Send(new IEventHandle(NotifyId, Self->SelfId(), Ev.Release(), 0, Cookie));
+
+ default:
+ throw TExError() << "unsupported command";
+ }
+ }
+
+ void Complete(const TActorContext&) override {
+ if (auto state = std::exchange(State, std::nullopt)) {
+ state->ApplyConfigUpdates();
+ }
+ TActivationContext::Send(new IEventHandle(NotifyId, Self->SelfId(), Ev.Release(), 0, Cookie));
Self->UpdatePDisksCounters();
- }
- };
-
- void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerConfigRequest::TPtr &ev) {
- TabletCounters->Cumulative()[NBlobStorageController::COUNTER_CONFIG_COUNT].Increment(1);
- if (ev->Get()->SelfHeal) {
- TabletCounters->Cumulative()[NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_REQUESTS].Increment(1);
- }
-
- NKikimrBlobStorage::TEvControllerConfigRequest& record(ev->Get()->Record);
- const NKikimrBlobStorage::TConfigRequest& request = record.GetRequest();
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXCC01, "Execute TEvControllerConfigRequest", (Request, request));
- Execute(new TTxConfigCmd(request, ev->Sender, ev->Cookie, ev->Get()->SelfHeal, this));
- }
-
-} // NKikimr::NBsController
+ }
+ };
+
+ void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerConfigRequest::TPtr &ev) {
+ TabletCounters->Cumulative()[NBlobStorageController::COUNTER_CONFIG_COUNT].Increment(1);
+ if (ev->Get()->SelfHeal) {
+ TabletCounters->Cumulative()[NBlobStorageController::COUNTER_SELFHEAL_REASSIGN_BSC_REQUESTS].Increment(1);
+ }
+
+ NKikimrBlobStorage::TEvControllerConfigRequest& record(ev->Get()->Record);
+ const NKikimrBlobStorage::TConfigRequest& request = record.GetRequest();
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXCC01, "Execute TEvControllerConfigRequest", (Request, request));
+ Execute(new TTxConfigCmd(request, ev->Sender, ev->Cookie, ev->Get()->SelfHeal, this));
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/config_fit_groups.cpp b/ydb/core/mind/bscontroller/config_fit_groups.cpp
index cb8801b0f5f..79cc06ac42b 100644
--- a/ydb/core/mind/bscontroller/config_fit_groups.cpp
+++ b/ydb/core/mind/bscontroller/config_fit_groups.cpp
@@ -1,589 +1,589 @@
-#include "impl.h"
-#include "config.h"
-#include "group_mapper.h"
+#include "impl.h"
+#include "config.h"
+#include "group_mapper.h"
#include "group_geometry_info.h"
-
-namespace NKikimr {
- namespace NBsController {
-
- class TBlobStorageController::TGroupFitter {
- TConfigState& State;
- const ui32 AvailabilityDomainId;
- const bool IgnoreGroupSanityChecks;
- const bool IgnoreGroupFailModelChecks;
- const bool IgnoreDegradedGroupsChecks;
- const bool IgnoreVSlotQuotaCheck;
- const bool AllowUnusableDisks;
- const bool SettleOnlyOnOperationalDisks;
- std::deque<ui64> ExpectedSlotSize;
- const ui32 PDiskSpaceMarginPromille;
- const TGroupGeometryInfo Geometry;
- const TBoxStoragePoolId StoragePoolId;
- const TStoragePoolInfo& StoragePool;
- std::optional<TGroupMapper> Mapper;
- NKikimrBlobStorage::TConfigResponse::TStatus& Status;
- TVSlotReadyTimestampQ& VSlotReadyTimestampQ;
-
- public:
- TGroupFitter(TConfigState& state, ui32 availabilityDomainId, const NKikimrBlobStorage::TConfigRequest& cmd,
- std::deque<ui64>& expectedSlotSize, ui32 pdiskSpaceMarginPromille,
- const TBoxStoragePoolId& storagePoolId, const TStoragePoolInfo& storagePool,
- NKikimrBlobStorage::TConfigResponse::TStatus& status, TVSlotReadyTimestampQ& vslotReadyTimestampQ)
- : State(state)
- , AvailabilityDomainId(availabilityDomainId)
- , IgnoreGroupSanityChecks(cmd.GetIgnoreGroupSanityChecks())
- , IgnoreGroupFailModelChecks(cmd.GetIgnoreGroupFailModelChecks())
- , IgnoreDegradedGroupsChecks(cmd.GetIgnoreDegradedGroupsChecks())
- , IgnoreVSlotQuotaCheck(cmd.GetIgnoreVSlotQuotaCheck())
- , AllowUnusableDisks(cmd.GetAllowUnusableDisks())
- , SettleOnlyOnOperationalDisks(cmd.GetSettleOnlyOnOperationalDisks())
- , ExpectedSlotSize(expectedSlotSize)
- , PDiskSpaceMarginPromille(pdiskSpaceMarginPromille)
- , Geometry(TBlobStorageGroupType(storagePool.ErasureSpecies), storagePool.GetGroupGeometry())
- , StoragePoolId(storagePoolId)
- , StoragePool(storagePool)
- , Status(status)
- , VSlotReadyTimestampQ(vslotReadyTimestampQ)
- {}
-
- void CheckReserve(ui32 total, ui32 min, ui32 part) {
- // number of reserved groups is min + part * maxGroups in cluster
- for (ui64 reserve = 0; reserve < min || (reserve - min) * 1000000 / Max<ui64>(1, total) < part; ++reserve, ++total) {
- TGroupMapper::TGroupDefinition group;
- try {
- AllocateGroup(0, group, nullptr, 0, {}, 0, false);
- } catch (const TExFitGroupError&) {
- throw TExError() << "group reserve constraint hit";
- }
- }
- }
-
- void CreateGroup() {
- ////////////////////////////////////////////////////////////////////////////////////////////
- // ALLOCATE GROUP ID FOR THE NEW GROUP
- ////////////////////////////////////////////////////////////////////////////////////////////
- TGroupId groupId;
- for (;;) {
- // obtain group local id
- auto& nextGroupId = State.NextGroupId.Unshare();
- const ui32 groupLocalId = nextGroupId ? TGroupID(nextGroupId).GroupLocalID() : 0;
-
- // create new full group id
- TGroupID fullGroupId(GroupConfigurationTypeDynamic, AvailabilityDomainId, groupLocalId);
- TGroupID nextFullGroupId = fullGroupId;
- ++nextFullGroupId;
-
- // write down NextGroupId
- nextGroupId = nextFullGroupId.GetRaw();
-
- // exit if there is no collision
- groupId = fullGroupId.GetRaw();
- if (!State.Groups.Find(groupId)) {
- break;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // CREATE MORE GROUPS
- ////////////////////////////////////////////////////////////////////////////////////////////////
- TGroupMapper::TGroupDefinition group;
- i64 requiredSpace = Min<i64>();
- if (!ExpectedSlotSize.empty()) {
- requiredSpace = ExpectedSlotSize.front();
- ExpectedSlotSize.pop_front();
- }
- AllocateGroup(groupId, group, nullptr, 0, {}, requiredSpace, false);
-
- // scan all comprising PDisks for PDiskCategory
- TMaybe<TPDiskCategory> desiredPDiskCategory;
-
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const TPDiskId& disk : domain) {
- if (const TPDiskInfo *pdisk = State.PDisks.Find(disk); pdisk && !State.PDisksToRemove.find(disk)) {
- if (requiredSpace != Min<i64>() && !pdisk->SlotSpaceEnforced(State.Self)) {
- Mapper->AdjustSpaceAvailable(disk, -requiredSpace);
- }
- if (!desiredPDiskCategory) {
- desiredPDiskCategory = pdisk->Kind;
- } else if (*desiredPDiskCategory != pdisk->Kind) {
- desiredPDiskCategory = 0;
- }
- } else {
- throw TExFitGroupError() << "can't find PDisk# " << disk;
- }
- }
- }
- }
-
- // create group info
+
+namespace NKikimr {
+ namespace NBsController {
+
+ class TBlobStorageController::TGroupFitter {
+ TConfigState& State;
+ const ui32 AvailabilityDomainId;
+ const bool IgnoreGroupSanityChecks;
+ const bool IgnoreGroupFailModelChecks;
+ const bool IgnoreDegradedGroupsChecks;
+ const bool IgnoreVSlotQuotaCheck;
+ const bool AllowUnusableDisks;
+ const bool SettleOnlyOnOperationalDisks;
+ std::deque<ui64> ExpectedSlotSize;
+ const ui32 PDiskSpaceMarginPromille;
+ const TGroupGeometryInfo Geometry;
+ const TBoxStoragePoolId StoragePoolId;
+ const TStoragePoolInfo& StoragePool;
+ std::optional<TGroupMapper> Mapper;
+ NKikimrBlobStorage::TConfigResponse::TStatus& Status;
+ TVSlotReadyTimestampQ& VSlotReadyTimestampQ;
+
+ public:
+ TGroupFitter(TConfigState& state, ui32 availabilityDomainId, const NKikimrBlobStorage::TConfigRequest& cmd,
+ std::deque<ui64>& expectedSlotSize, ui32 pdiskSpaceMarginPromille,
+ const TBoxStoragePoolId& storagePoolId, const TStoragePoolInfo& storagePool,
+ NKikimrBlobStorage::TConfigResponse::TStatus& status, TVSlotReadyTimestampQ& vslotReadyTimestampQ)
+ : State(state)
+ , AvailabilityDomainId(availabilityDomainId)
+ , IgnoreGroupSanityChecks(cmd.GetIgnoreGroupSanityChecks())
+ , IgnoreGroupFailModelChecks(cmd.GetIgnoreGroupFailModelChecks())
+ , IgnoreDegradedGroupsChecks(cmd.GetIgnoreDegradedGroupsChecks())
+ , IgnoreVSlotQuotaCheck(cmd.GetIgnoreVSlotQuotaCheck())
+ , AllowUnusableDisks(cmd.GetAllowUnusableDisks())
+ , SettleOnlyOnOperationalDisks(cmd.GetSettleOnlyOnOperationalDisks())
+ , ExpectedSlotSize(expectedSlotSize)
+ , PDiskSpaceMarginPromille(pdiskSpaceMarginPromille)
+ , Geometry(TBlobStorageGroupType(storagePool.ErasureSpecies), storagePool.GetGroupGeometry())
+ , StoragePoolId(storagePoolId)
+ , StoragePool(storagePool)
+ , Status(status)
+ , VSlotReadyTimestampQ(vslotReadyTimestampQ)
+ {}
+
+ void CheckReserve(ui32 total, ui32 min, ui32 part) {
+ // number of reserved groups is min + part * maxGroups in cluster
+ for (ui64 reserve = 0; reserve < min || (reserve - min) * 1000000 / Max<ui64>(1, total) < part; ++reserve, ++total) {
+ TGroupMapper::TGroupDefinition group;
+ try {
+ AllocateGroup(0, group, nullptr, 0, {}, 0, false);
+ } catch (const TExFitGroupError&) {
+ throw TExError() << "group reserve constraint hit";
+ }
+ }
+ }
+
+ void CreateGroup() {
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ // ALLOCATE GROUP ID FOR THE NEW GROUP
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ TGroupId groupId;
+ for (;;) {
+ // obtain group local id
+ auto& nextGroupId = State.NextGroupId.Unshare();
+ const ui32 groupLocalId = nextGroupId ? TGroupID(nextGroupId).GroupLocalID() : 0;
+
+ // create new full group id
+ TGroupID fullGroupId(GroupConfigurationTypeDynamic, AvailabilityDomainId, groupLocalId);
+ TGroupID nextFullGroupId = fullGroupId;
+ ++nextFullGroupId;
+
+ // write down NextGroupId
+ nextGroupId = nextFullGroupId.GetRaw();
+
+ // exit if there is no collision
+ groupId = fullGroupId.GetRaw();
+ if (!State.Groups.Find(groupId)) {
+ break;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // CREATE MORE GROUPS
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ TGroupMapper::TGroupDefinition group;
+ i64 requiredSpace = Min<i64>();
+ if (!ExpectedSlotSize.empty()) {
+ requiredSpace = ExpectedSlotSize.front();
+ ExpectedSlotSize.pop_front();
+ }
+ AllocateGroup(groupId, group, nullptr, 0, {}, requiredSpace, false);
+
+ // scan all comprising PDisks for PDiskCategory
+ TMaybe<TPDiskCategory> desiredPDiskCategory;
+
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const TPDiskId& disk : domain) {
+ if (const TPDiskInfo *pdisk = State.PDisks.Find(disk); pdisk && !State.PDisksToRemove.find(disk)) {
+ if (requiredSpace != Min<i64>() && !pdisk->SlotSpaceEnforced(State.Self)) {
+ Mapper->AdjustSpaceAvailable(disk, -requiredSpace);
+ }
+ if (!desiredPDiskCategory) {
+ desiredPDiskCategory = pdisk->Kind;
+ } else if (*desiredPDiskCategory != pdisk->Kind) {
+ desiredPDiskCategory = 0;
+ }
+ } else {
+ throw TExFitGroupError() << "can't find PDisk# " << disk;
+ }
+ }
+ }
+ }
+
+ // create group info
const ui64 MainKeyVersion = 0;
- ui32 lifeCyclePhase = 0;
+ ui32 lifeCyclePhase = 0;
TString mainKeyId = "";
- TString encryptedGroupKey = "";
- ui64 groupKeyNonce = groupId; // For the first time use groupId, then use low 32 bits of the
- // NextGroupKeyNonce to produce high 32 bits of the groupKeyNonce.
-
- TGroupInfo *groupInfo = State.Groups.ConstructInplaceNewEntry(groupId, groupId, 1,
- 0, Geometry.GetErasure(), desiredPDiskCategory.GetOrElse(0), StoragePool.VDiskKind,
+ TString encryptedGroupKey = "";
+ ui64 groupKeyNonce = groupId; // For the first time use groupId, then use low 32 bits of the
+ // NextGroupKeyNonce to produce high 32 bits of the groupKeyNonce.
+
+ TGroupInfo *groupInfo = State.Groups.ConstructInplaceNewEntry(groupId, groupId, 1,
+ 0, Geometry.GetErasure(), desiredPDiskCategory.GetOrElse(0), StoragePool.VDiskKind,
StoragePool.EncryptionMode.GetOrElse(0), lifeCyclePhase, mainKeyId, encryptedGroupKey,
groupKeyNonce, MainKeyVersion, false, false, StoragePoolId, Geometry.GetNumFailRealms(),
- Geometry.GetNumFailDomainsPerFailRealm(), Geometry.GetNumVDisksPerFailDomain());
-
- // bind group to storage pool
- groupInfo->StoragePoolId = StoragePoolId;
- State.StoragePoolGroups.Unshare().emplace(StoragePoolId, groupId);
-
- const TGroupSpecies species = groupInfo->GetGroupSpecies();
- auto& index = State.IndexGroupSpeciesToGroup.Unshare();
- index[species].push_back(groupId);
-
- // create VSlots
- CreateVSlotsForGroup(groupInfo, group, {});
- }
-
- void CheckExistingGroup(TGroupId groupId) {
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- // extract TGroupInfo for specified group
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- const TGroupInfo *groupInfo = State.Groups.Find(groupId);
- if (!groupInfo) {
- throw TExFitGroupError() << "GroupId# " << groupId << " not found";
- }
-
- TGroupMapper::TGroupDefinition group;
-
- auto getGroup = [&]() -> TGroupMapper::TGroupDefinition& {
- if (!group) {
- Geometry.ResizeGroup(group);
- for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
- const TPDiskId& pdiskId = vslot->VSlotId.ComprisingPDiskId();
- group[vslot->RingIdx][vslot->FailDomainIdx][vslot->VDiskIdx] = pdiskId;
- }
- }
-
- return group;
- };
-
- // a set of preserved slots (which are not changed during this transaction)
+ Geometry.GetNumFailDomainsPerFailRealm(), Geometry.GetNumVDisksPerFailDomain());
+
+ // bind group to storage pool
+ groupInfo->StoragePoolId = StoragePoolId;
+ State.StoragePoolGroups.Unshare().emplace(StoragePoolId, groupId);
+
+ const TGroupSpecies species = groupInfo->GetGroupSpecies();
+ auto& index = State.IndexGroupSpeciesToGroup.Unshare();
+ index[species].push_back(groupId);
+
+ // create VSlots
+ CreateVSlotsForGroup(groupInfo, group, {});
+ }
+
+ void CheckExistingGroup(TGroupId groupId) {
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // extract TGroupInfo for specified group
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ const TGroupInfo *groupInfo = State.Groups.Find(groupId);
+ if (!groupInfo) {
+ throw TExFitGroupError() << "GroupId# " << groupId << " not found";
+ }
+
+ TGroupMapper::TGroupDefinition group;
+
+ auto getGroup = [&]() -> TGroupMapper::TGroupDefinition& {
+ if (!group) {
+ Geometry.ResizeGroup(group);
+ for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
+ const TPDiskId& pdiskId = vslot->VSlotId.ComprisingPDiskId();
+ group[vslot->RingIdx][vslot->FailDomainIdx][vslot->VDiskIdx] = pdiskId;
+ }
+ }
+
+ return group;
+ };
+
+ // a set of preserved slots (which are not changed during this transaction)
TMap<TVDiskID, TVSlotId> preservedSlots;
-
- // mapping for audit log
- TMap<TVDiskIdShort, TVSlotId> replacedSlots;
- TStackVec<std::pair<TVSlotId, bool>, 32> replaceQueue;
- i64 requiredSpace = Min<i64>();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- // scan through all VSlots and find matching PDisks
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
- const auto it = State.ExplicitReconfigureMap.find(vslot->VSlotId);
- bool replace = it != State.ExplicitReconfigureMap.end();
- const TPDiskId targetPDiskId = replace ? it->second : TPDiskId();
- if (!replace) {
- // check status
- switch (vslot->PDisk->Status) {
- case NKikimrBlobStorage::EDriveStatus::ACTIVE:
- // nothing to do, it's okay
- break;
-
- case NKikimrBlobStorage::EDriveStatus::INACTIVE:
- // nothing to do as well, new groups are not created on this drive, but existing ones continue
- // to function as expected
- break;
-
- case NKikimrBlobStorage::EDriveStatus::BROKEN:
- // reconfigure group
- replace = true;
- break;
-
- case NKikimrBlobStorage::EDriveStatus::SPARE:
- break;
-
- case NKikimrBlobStorage::EDriveStatus::FAULTY:
+
+ // mapping for audit log
+ TMap<TVDiskIdShort, TVSlotId> replacedSlots;
+ TStackVec<std::pair<TVSlotId, bool>, 32> replaceQueue;
+ i64 requiredSpace = Min<i64>();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // scan through all VSlots and find matching PDisks
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ for (const TVSlotInfo *vslot : groupInfo->VDisksInGroup) {
+ const auto it = State.ExplicitReconfigureMap.find(vslot->VSlotId);
+ bool replace = it != State.ExplicitReconfigureMap.end();
+ const TPDiskId targetPDiskId = replace ? it->second : TPDiskId();
+ if (!replace) {
+ // check status
+ switch (vslot->PDisk->Status) {
+ case NKikimrBlobStorage::EDriveStatus::ACTIVE:
+ // nothing to do, it's okay
+ break;
+
+ case NKikimrBlobStorage::EDriveStatus::INACTIVE:
+ // nothing to do as well, new groups are not created on this drive, but existing ones continue
+ // to function as expected
+ break;
+
+ case NKikimrBlobStorage::EDriveStatus::BROKEN:
+ // reconfigure group
+ replace = true;
+ break;
+
+ case NKikimrBlobStorage::EDriveStatus::SPARE:
+ break;
+
+ case NKikimrBlobStorage::EDriveStatus::FAULTY:
case NKikimrBlobStorage::EDriveStatus::TO_BE_REMOVED:
- // groups are moved out asynchronously
- break;
-
- default:
- Y_FAIL("unexpected drive status");
- }
- }
-
- if (replace) {
- auto& g = getGroup();
- // get the current PDisk in the desired slot and replace it with the target one; if the target
- // PDisk id is zero, then new PDisk will be picked up automatically
- g[vslot->RingIdx][vslot->FailDomainIdx][vslot->VDiskIdx] = targetPDiskId;
- replacedSlots.emplace(TVDiskIdShort(vslot->RingIdx, vslot->FailDomainIdx, vslot->VDiskIdx), vslot->VSlotId);
- replaceQueue.emplace_back(vslot->VSlotId, State.SuppressDonorMode.count(vslot->VSlotId));
- } else {
- preservedSlots.emplace(vslot->GetVDiskId(), vslot->VSlotId);
- auto& m = vslot->Metrics;
- if (m.HasAllocatedSize() && !IgnoreVSlotQuotaCheck) {
- // calculate space as the maximum of allocated sizes of untouched vdisks
- requiredSpace = Max<i64>(requiredSpace, m.GetAllocatedSize());
- }
- }
- }
-
- if (group) {
- TGroupInfo *groupInfo = State.Groups.FindForUpdate(groupId);
-
- // we have something changed in the group; initiate remapping
- bool hasMissingSlots = false;
- bool adjustSpaceAvailable = false;
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const TPDiskId& pdisk : domain) {
- if (pdisk == TPDiskId()) {
- hasMissingSlots = true;
- }
- }
- }
- }
- if (hasMissingSlots || !IgnoreGroupSanityChecks) {
- TStackVec<TPDiskId, 32> replacedDiskIds;
- for (const auto& [vslotId, suppressDonorMode] : replaceQueue) {
- replacedDiskIds.push_back(vslotId.ComprisingPDiskId());
- }
- TGroupMapper::TForbiddenPDisks forbid;
- for (const auto& vslot : groupInfo->VDisksInGroup) {
- for (const auto& [vslotId, vdiskId] : vslot->Donors) {
- if (group[vdiskId.FailRealm][vdiskId.FailDomain][vdiskId.VDisk] == TPDiskId()) {
- forbid.insert(vslotId.ComprisingPDiskId());
- }
- }
- }
- AllocateGroup(groupId, group, replacedDiskIds.data(), replacedDiskIds.size(), std::move(forbid),
- requiredSpace, AllowUnusableDisks);
- if (!IgnoreVSlotQuotaCheck) {
- adjustSpaceAvailable = true;
- for (const auto& [pos, vslotId] : replacedSlots) {
- const TPDiskId& pdiskId = group[pos.FailRealm][pos.FailDomain][pos.VDisk];
- const TPDiskInfo *pdisk = State.PDisks.Find(pdiskId);
- if (!pdisk->SlotSpaceEnforced(State.Self)) {
- Mapper->AdjustSpaceAvailable(pdiskId, -requiredSpace);
- }
- }
- }
- }
-
- // create slots for the new group
- auto newSlots = CreateVSlotsForGroup(groupInfo, group, preservedSlots);
- groupInfo->ContentChanged = true;
-
- if (replacedSlots) {
- if (!IgnoreGroupFailModelChecks) {
- // process only groups with changed content; create topology for group
- auto& topology = *groupInfo->Topology;
- // fill in vector of failed disks (that are not fully operational)
- TBlobStorageGroupInfo::TGroupVDisks failed(&topology);
- for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
- if (!slot->IsOperational()) {
- failed |= {&topology, slot->GetShortVDiskId()};
- }
- }
- // check the failure model
- auto& checker = *topology.QuorumChecker;
- if (!checker.CheckFailModelForGroup(failed)) {
- throw TExMayLoseData(groupId);
- } else if (!IgnoreDegradedGroupsChecks && checker.IsDegraded(failed)) {
- throw TExMayGetDegraded(groupId);
- }
- }
-
- for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
- const TVDiskIdShort pos(slot->RingIdx, slot->FailDomainIdx, slot->VDiskIdx);
- if (const auto it = replacedSlots.find(pos); it != replacedSlots.end()) {
- auto *item = Status.AddReassignedItem();
- VDiskIDFromVDiskID(TVDiskID(groupInfo->ID, groupInfo->Generation - 1, pos), item->MutableVDiskId());
- Serialize(item->MutableFrom(), it->second);
- Serialize(item->MutableTo(), slot->VSlotId);
- if (auto *pdisk = State.PDisks.Find(it->second.ComprisingPDiskId())) {
- item->SetFromFqdn(std::get<0>(pdisk->HostId));
- item->SetFromPath(pdisk->Path);
- }
- if (auto *pdisk = State.PDisks.Find(slot->VSlotId.ComprisingPDiskId())) {
- item->SetToFqdn(std::get<0>(pdisk->HostId));
- item->SetToPath(pdisk->Path);
- }
- }
- }
-
- auto makeReplacements = [&] {
- TStringBuilder s;
- s << "[";
- bool first = true;
- for (const auto& kv : replacedSlots) {
- s << (std::exchange(first, false) ? "" : " ")
- << "{" << kv.first << " from# " << kv.second << " to# "
- << group[kv.first.FailRealm][kv.first.FailDomain][kv.first.VDisk] << "}";
- }
- return static_cast<TString>(s << "]");
- };
- STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA04, "ReconfigGroup", (UniqueId, State.UniqueId),
- (GroupId, groupInfo->ID),
- (GroupGeneration, groupInfo->Generation),
- (Replacements, makeReplacements()));
- }
-
- for (const auto& [vslotId, suppressDonorMode] : replaceQueue) {
- if (State.DonorMode && !suppressDonorMode && !State.UncommittedVSlots.count(vslotId)) {
- TVSlotInfo *mutableSlot = State.VSlots.FindForUpdate(vslotId);
- Y_VERIFY(mutableSlot);
- // make slot the donor one for the newly created slot
- const auto it = newSlots.find(mutableSlot->GetShortVDiskId());
- Y_VERIFY(it != newSlots.end());
- mutableSlot->MakeDonorFor(it->second);
- for (const auto& [donorVSlotId, donorVDiskId] : it->second->Donors) {
- TVSlotInfo *mutableDonor = State.VSlots.FindForUpdate(donorVSlotId);
- Y_VERIFY(mutableDonor);
- Y_VERIFY(mutableDonor->Mood == TMood::Donor);
- mutableDonor->AcceptorVSlotId = it->second->VSlotId;
- }
- } else {
- if (adjustSpaceAvailable) {
- const TVSlotInfo *slot = State.VSlots.Find(vslotId);
- Y_VERIFY(slot);
- if (!slot->PDisk->SlotSpaceEnforced(State.Self)) {
- // mark the space from destroyed slot as available
- Mapper->AdjustSpaceAvailable(vslotId.ComprisingPDiskId(), slot->Metrics.GetAllocatedSize());
- }
- }
-
- State.DestroyVSlot(vslotId);
- }
- }
- } else {
- Y_VERIFY(replaceQueue.empty());
- }
- }
-
- private:
- void AllocateGroup(TGroupId groupId, TGroupMapper::TGroupDefinition& group, const TPDiskId replacedDiskIds[],
- size_t numReplacedDisks, TGroupMapper::TForbiddenPDisks forbid, i64 requiredSpace,
- bool addExistingDisks) {
- if (!Mapper) {
- Mapper.emplace(Geometry, StoragePool.RandomizeGroupMapping);
- PopulateGroupMapper();
- }
- TStackVec<TPDiskId, 32> removeQ;
- if (addExistingDisks) {
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const TPDiskId id : domain) {
- if (id != TPDiskId()) {
- if (auto *info = State.PDisks.Find(id); info && RegisterPDisk(id, *info, false)) {
- removeQ.push_back(id);
- }
- }
- }
- }
- }
- }
- Geometry.AllocateGroup(*Mapper, groupId, group, replacedDiskIds, numReplacedDisks, std::move(forbid),
- requiredSpace);
- for (const TPDiskId pdiskId : removeQ) {
- Mapper->UnregisterPDisk(pdiskId);
- }
- }
-
- void PopulateGroupMapper() {
- const TBoxId boxId = std::get<0>(StoragePoolId);
-
- State.PDisks.ForEach([&](const TPDiskId& id, const TPDiskInfo& info) {
- if (info.BoxId != boxId) {
- return; // ignore disks not from desired box
- }
-
- if (State.PDisksToRemove.count(id)) {
- return; // this PDisk is scheduled for removal
- }
-
- for (const auto& filter : StoragePool.PDiskFilters) {
- if (filter.MatchPDisk(info)) {
- const bool inserted = RegisterPDisk(id, info, true);
- Y_VERIFY(inserted);
- break;
- }
- }
- });
- }
-
- bool RegisterPDisk(TPDiskId id, const TPDiskInfo& info, bool usable) {
- // calculate number of used slots on this PDisk, also counting the static ones
- ui32 numSlots = info.NumActiveSlots + info.StaticSlotUsage;
-
- // create a set of groups residing on this PDisk
- TStackVec<ui32, 16> groups;
- for (const auto& [vslotId, vslot] : info.VSlotsOnPDisk) {
- if (!vslot->IsBeingDeleted()) {
- groups.push_back(vslot->GroupId);
- }
- }
-
- // calculate vdisk space quota (or amount of available space when no enforcement is enabled)
- i64 availableSpace = Max<i64>();
- if (usable && !IgnoreVSlotQuotaCheck) {
- if (info.SlotSpaceEnforced(State.Self)) {
- availableSpace = info.Metrics.GetEnforcedDynamicSlotSize() * (1000 - PDiskSpaceMarginPromille) / 1000;
- } else {
- // here we assume that no space enforcement takes place and we have to calculate available space
- // for this disk; we take it as available space and keep in mind that PDisk must have at least
- // PDiskSpaceMarginPromille space remaining
- availableSpace = info.Metrics.GetAvailableSize() - info.Metrics.GetTotalSize() * PDiskSpaceMarginPromille / 1000;
-
- // also we have to find replicating VSlots on this PDisk and assume they consume up to
- // max(vslotSize for every slot in group), not their actual AllocatedSize
- for (const auto& [id, slot] : info.VSlotsOnPDisk) {
- if (slot->Group && slot->GetStatus() != NKikimrBlobStorage::EVDiskStatus::READY) {
- ui64 maxGroupSlotSize = 0;
- for (const TVSlotInfo *peer : slot->Group->VDisksInGroup) {
- maxGroupSlotSize = Max(maxGroupSlotSize, peer->Metrics.GetAllocatedSize());
- }
- // return actually used space to available pool
- availableSpace += slot->Metrics.GetAllocatedSize();
- // and consume expected slot size after replication finishes
- availableSpace -= maxGroupSlotSize;
- }
- }
- }
- }
-
- if (info.Status != NKikimrBlobStorage::EDriveStatus::ACTIVE) {
- usable = false;
- }
-
- if (SettleOnlyOnOperationalDisks && !info.Operational) {
- usable = false;
- }
-
- // register PDisk in the mapper
- return Mapper->RegisterPDisk(id, State.HostRecords->GetLocation(id.NodeId), usable, numSlots,
- info.ExpectedSlotCount, groups.data(), groups.size(), availableSpace, info.Operational);
- }
-
- std::map<TVDiskIdShort, TVSlotInfo*> CreateVSlotsForGroup(TGroupInfo *groupInfo,
- const TGroupMapper::TGroupDefinition& group, const TMap<TVDiskID, TVSlotId>& preservedSlots) {
- std::map<TVDiskIdShort, TVSlotInfo*> res;
-
- // reset group contents as we are going to fill it right now
- groupInfo->ClearVDisksInGroup();
-
- for (ui32 failRealmIdx = 0; failRealmIdx < group.size(); ++failRealmIdx) {
- const auto& realm = group[failRealmIdx];
- for (ui32 failDomainIdx = 0; failDomainIdx < realm.size(); ++failDomainIdx) {
- const auto& domain = realm[failDomainIdx];
- for (ui32 vdiskIdx = 0; vdiskIdx < domain.size(); ++vdiskIdx) {
- const TVDiskID vdiskId(groupInfo->ID, groupInfo->Generation, failRealmIdx, failDomainIdx, vdiskIdx);
- if (auto it = preservedSlots.find(vdiskId); it != preservedSlots.end()) {
- const TVSlotInfo *vslotInfo = State.VSlots.Find(it->second);
- Y_VERIFY(vslotInfo);
- groupInfo->AddVSlot(vslotInfo);
- } else {
- const TPDiskId pdiskId = domain[vdiskIdx];
- Y_VERIFY(!State.PDisksToRemove.count(pdiskId));
- TPDiskInfo *pdiskInfo = State.PDisks.FindForUpdate(pdiskId);
- Y_VERIFY(pdiskInfo);
- TVSlotId vslotId;
-
- // allocate new VSlot id; avoid collisions
- for (;;) {
- const auto currentVSlotId = pdiskInfo->NextVSlotId;
- pdiskInfo->NextVSlotId = currentVSlotId + 1;
- vslotId = TVSlotId(pdiskId, currentVSlotId);
- if (!State.VSlots.Find(vslotId)) {
- break;
- }
- }
-
- // insert new VSlot
- TVSlotInfo *vslotInfo = State.VSlots.ConstructInplaceNewEntry(vslotId, vslotId, pdiskInfo,
- groupInfo->ID, 0, groupInfo->Generation, StoragePool.VDiskKind, failRealmIdx,
- failDomainIdx, vdiskIdx, TMood::Normal, groupInfo, &VSlotReadyTimestampQ,
- TInstant::Zero());
-
- // mark as uncommitted
- State.UncommittedVSlots.insert(vslotId);
-
- // remember newly created slot
- res.emplace(vdiskId, vslotInfo);
- }
- }
- }
- }
-
- groupInfo->FinishVDisksInGroup();
- groupInfo->CalculateGroupStatus();
-
- return res;
- }
- };
-
- void TBlobStorageController::FitGroupsForUserConfig(TConfigState& state, ui32 availabilityDomainId,
- const NKikimrBlobStorage::TConfigRequest& cmd, std::deque<ui64> expectedSlotSize,
- NKikimrBlobStorage::TConfigResponse::TStatus& status) {
- std::unordered_map<TString, std::pair<ui32, TBoxStoragePoolId>> filterMap;
- std::unordered_set<TString> changedFilters;
-
- // scan through all storage pools and fit the number of groups to desired one
- for (const auto& [storagePoolId, storagePool] : state.StoragePools.Get()) {
- TGroupFitter fitter(state, availabilityDomainId, cmd, expectedSlotSize, PDiskSpaceMarginPromille,
- storagePoolId, storagePool, status, VSlotReadyTimestampQ);
-
- const auto& storagePoolGroups = state.StoragePoolGroups.Get();
- const auto range = storagePoolGroups.equal_range(storagePoolId);
- ui32 numActualGroups = 0;
-
- try {
- TStringBuilder identifier;
- identifier << "Erasure# " << storagePool.ErasureSpecies
- << " Geometry# " << storagePool.RealmLevelBegin << "," << storagePool.RealmLevelEnd
- << "," << storagePool.DomainLevelBegin << "," << storagePool.DomainLevelEnd
- << "," << storagePool.NumFailRealms << "," << storagePool.NumFailDomainsPerFailRealm
- << "," << storagePool.NumVDisksPerFailDomain;
- for (const auto& filter : storagePool.PDiskFilters) {
- identifier << " Filter# " << filter.Type << "," << filter.SharedWithOs
- << "," << filter.ReadCentric << "," << filter.Kind;
- }
- auto& [numGroups, id] = filterMap[identifier];
- numGroups += storagePool.NumGroups;
- id = storagePoolId;
-
- for (auto it = range.first; it != range.second; ++it, ++numActualGroups) {
- fitter.CheckExistingGroup(it->second);
- }
- if (numActualGroups < storagePool.NumGroups) {
- changedFilters.insert(identifier);
- }
- for (; numActualGroups < storagePool.NumGroups; ++numActualGroups) {
- fitter.CreateGroup();
- }
- } catch (const TExFitGroupError& ex) {
- throw TExError() << "Group fit error"
- << " BoxId# " << std::get<0>(storagePoolId)
- << " StoragePoolId# " << std::get<1>(storagePoolId)
- << " Error# " << ex.what();
- }
- if (storagePool.NumGroups < numActualGroups) {
- throw TExError() << "Storage pool modification error"
- << " BoxId# " << std::get<0>(storagePoolId)
- << " StoragePoolId# " << std::get<1>(storagePoolId)
- << " impossible to reduce number of groups";
- }
- }
-
- if (!cmd.GetIgnoreGroupReserve()) {
- for (const auto& identifier : changedFilters) {
- auto& [numGroups, storagePoolId] = filterMap.at(identifier);
- const auto& storagePool = state.StoragePools.Get().at(storagePoolId);
- TGroupFitter fitter(state, availabilityDomainId, cmd, expectedSlotSize, PDiskSpaceMarginPromille,
- storagePoolId, storagePool, status, VSlotReadyTimestampQ);
- fitter.CheckReserve(numGroups, GroupReserveMin, GroupReservePart);
- }
- }
- }
-
- } // NBsController
-} // NKikimr
+ // groups are moved out asynchronously
+ break;
+
+ default:
+ Y_FAIL("unexpected drive status");
+ }
+ }
+
+ if (replace) {
+ auto& g = getGroup();
+ // get the current PDisk in the desired slot and replace it with the target one; if the target
+ // PDisk id is zero, then new PDisk will be picked up automatically
+ g[vslot->RingIdx][vslot->FailDomainIdx][vslot->VDiskIdx] = targetPDiskId;
+ replacedSlots.emplace(TVDiskIdShort(vslot->RingIdx, vslot->FailDomainIdx, vslot->VDiskIdx), vslot->VSlotId);
+ replaceQueue.emplace_back(vslot->VSlotId, State.SuppressDonorMode.count(vslot->VSlotId));
+ } else {
+ preservedSlots.emplace(vslot->GetVDiskId(), vslot->VSlotId);
+ auto& m = vslot->Metrics;
+ if (m.HasAllocatedSize() && !IgnoreVSlotQuotaCheck) {
+ // calculate space as the maximum of allocated sizes of untouched vdisks
+ requiredSpace = Max<i64>(requiredSpace, m.GetAllocatedSize());
+ }
+ }
+ }
+
+ if (group) {
+ TGroupInfo *groupInfo = State.Groups.FindForUpdate(groupId);
+
+ // we have something changed in the group; initiate remapping
+ bool hasMissingSlots = false;
+ bool adjustSpaceAvailable = false;
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const TPDiskId& pdisk : domain) {
+ if (pdisk == TPDiskId()) {
+ hasMissingSlots = true;
+ }
+ }
+ }
+ }
+ if (hasMissingSlots || !IgnoreGroupSanityChecks) {
+ TStackVec<TPDiskId, 32> replacedDiskIds;
+ for (const auto& [vslotId, suppressDonorMode] : replaceQueue) {
+ replacedDiskIds.push_back(vslotId.ComprisingPDiskId());
+ }
+ TGroupMapper::TForbiddenPDisks forbid;
+ for (const auto& vslot : groupInfo->VDisksInGroup) {
+ for (const auto& [vslotId, vdiskId] : vslot->Donors) {
+ if (group[vdiskId.FailRealm][vdiskId.FailDomain][vdiskId.VDisk] == TPDiskId()) {
+ forbid.insert(vslotId.ComprisingPDiskId());
+ }
+ }
+ }
+ AllocateGroup(groupId, group, replacedDiskIds.data(), replacedDiskIds.size(), std::move(forbid),
+ requiredSpace, AllowUnusableDisks);
+ if (!IgnoreVSlotQuotaCheck) {
+ adjustSpaceAvailable = true;
+ for (const auto& [pos, vslotId] : replacedSlots) {
+ const TPDiskId& pdiskId = group[pos.FailRealm][pos.FailDomain][pos.VDisk];
+ const TPDiskInfo *pdisk = State.PDisks.Find(pdiskId);
+ if (!pdisk->SlotSpaceEnforced(State.Self)) {
+ Mapper->AdjustSpaceAvailable(pdiskId, -requiredSpace);
+ }
+ }
+ }
+ }
+
+ // create slots for the new group
+ auto newSlots = CreateVSlotsForGroup(groupInfo, group, preservedSlots);
+ groupInfo->ContentChanged = true;
+
+ if (replacedSlots) {
+ if (!IgnoreGroupFailModelChecks) {
+ // process only groups with changed content; create topology for group
+ auto& topology = *groupInfo->Topology;
+ // fill in vector of failed disks (that are not fully operational)
+ TBlobStorageGroupInfo::TGroupVDisks failed(&topology);
+ for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
+ if (!slot->IsOperational()) {
+ failed |= {&topology, slot->GetShortVDiskId()};
+ }
+ }
+ // check the failure model
+ auto& checker = *topology.QuorumChecker;
+ if (!checker.CheckFailModelForGroup(failed)) {
+ throw TExMayLoseData(groupId);
+ } else if (!IgnoreDegradedGroupsChecks && checker.IsDegraded(failed)) {
+ throw TExMayGetDegraded(groupId);
+ }
+ }
+
+ for (const TVSlotInfo *slot : groupInfo->VDisksInGroup) {
+ const TVDiskIdShort pos(slot->RingIdx, slot->FailDomainIdx, slot->VDiskIdx);
+ if (const auto it = replacedSlots.find(pos); it != replacedSlots.end()) {
+ auto *item = Status.AddReassignedItem();
+ VDiskIDFromVDiskID(TVDiskID(groupInfo->ID, groupInfo->Generation - 1, pos), item->MutableVDiskId());
+ Serialize(item->MutableFrom(), it->second);
+ Serialize(item->MutableTo(), slot->VSlotId);
+ if (auto *pdisk = State.PDisks.Find(it->second.ComprisingPDiskId())) {
+ item->SetFromFqdn(std::get<0>(pdisk->HostId));
+ item->SetFromPath(pdisk->Path);
+ }
+ if (auto *pdisk = State.PDisks.Find(slot->VSlotId.ComprisingPDiskId())) {
+ item->SetToFqdn(std::get<0>(pdisk->HostId));
+ item->SetToPath(pdisk->Path);
+ }
+ }
+ }
+
+ auto makeReplacements = [&] {
+ TStringBuilder s;
+ s << "[";
+ bool first = true;
+ for (const auto& kv : replacedSlots) {
+ s << (std::exchange(first, false) ? "" : " ")
+ << "{" << kv.first << " from# " << kv.second << " to# "
+ << group[kv.first.FailRealm][kv.first.FailDomain][kv.first.VDisk] << "}";
+ }
+ return static_cast<TString>(s << "]");
+ };
+ STLOG(PRI_INFO, BS_CONTROLLER_AUDIT, BSCA04, "ReconfigGroup", (UniqueId, State.UniqueId),
+ (GroupId, groupInfo->ID),
+ (GroupGeneration, groupInfo->Generation),
+ (Replacements, makeReplacements()));
+ }
+
+ for (const auto& [vslotId, suppressDonorMode] : replaceQueue) {
+ if (State.DonorMode && !suppressDonorMode && !State.UncommittedVSlots.count(vslotId)) {
+ TVSlotInfo *mutableSlot = State.VSlots.FindForUpdate(vslotId);
+ Y_VERIFY(mutableSlot);
+ // make slot the donor one for the newly created slot
+ const auto it = newSlots.find(mutableSlot->GetShortVDiskId());
+ Y_VERIFY(it != newSlots.end());
+ mutableSlot->MakeDonorFor(it->second);
+ for (const auto& [donorVSlotId, donorVDiskId] : it->second->Donors) {
+ TVSlotInfo *mutableDonor = State.VSlots.FindForUpdate(donorVSlotId);
+ Y_VERIFY(mutableDonor);
+ Y_VERIFY(mutableDonor->Mood == TMood::Donor);
+ mutableDonor->AcceptorVSlotId = it->second->VSlotId;
+ }
+ } else {
+ if (adjustSpaceAvailable) {
+ const TVSlotInfo *slot = State.VSlots.Find(vslotId);
+ Y_VERIFY(slot);
+ if (!slot->PDisk->SlotSpaceEnforced(State.Self)) {
+ // mark the space from destroyed slot as available
+ Mapper->AdjustSpaceAvailable(vslotId.ComprisingPDiskId(), slot->Metrics.GetAllocatedSize());
+ }
+ }
+
+ State.DestroyVSlot(vslotId);
+ }
+ }
+ } else {
+ Y_VERIFY(replaceQueue.empty());
+ }
+ }
+
+ private:
+ void AllocateGroup(TGroupId groupId, TGroupMapper::TGroupDefinition& group, const TPDiskId replacedDiskIds[],
+ size_t numReplacedDisks, TGroupMapper::TForbiddenPDisks forbid, i64 requiredSpace,
+ bool addExistingDisks) {
+ if (!Mapper) {
+ Mapper.emplace(Geometry, StoragePool.RandomizeGroupMapping);
+ PopulateGroupMapper();
+ }
+ TStackVec<TPDiskId, 32> removeQ;
+ if (addExistingDisks) {
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const TPDiskId id : domain) {
+ if (id != TPDiskId()) {
+ if (auto *info = State.PDisks.Find(id); info && RegisterPDisk(id, *info, false)) {
+ removeQ.push_back(id);
+ }
+ }
+ }
+ }
+ }
+ }
+ Geometry.AllocateGroup(*Mapper, groupId, group, replacedDiskIds, numReplacedDisks, std::move(forbid),
+ requiredSpace);
+ for (const TPDiskId pdiskId : removeQ) {
+ Mapper->UnregisterPDisk(pdiskId);
+ }
+ }
+
+ void PopulateGroupMapper() {
+ const TBoxId boxId = std::get<0>(StoragePoolId);
+
+ State.PDisks.ForEach([&](const TPDiskId& id, const TPDiskInfo& info) {
+ if (info.BoxId != boxId) {
+ return; // ignore disks not from desired box
+ }
+
+ if (State.PDisksToRemove.count(id)) {
+ return; // this PDisk is scheduled for removal
+ }
+
+ for (const auto& filter : StoragePool.PDiskFilters) {
+ if (filter.MatchPDisk(info)) {
+ const bool inserted = RegisterPDisk(id, info, true);
+ Y_VERIFY(inserted);
+ break;
+ }
+ }
+ });
+ }
+
+ bool RegisterPDisk(TPDiskId id, const TPDiskInfo& info, bool usable) {
+ // calculate number of used slots on this PDisk, also counting the static ones
+ ui32 numSlots = info.NumActiveSlots + info.StaticSlotUsage;
+
+ // create a set of groups residing on this PDisk
+ TStackVec<ui32, 16> groups;
+ for (const auto& [vslotId, vslot] : info.VSlotsOnPDisk) {
+ if (!vslot->IsBeingDeleted()) {
+ groups.push_back(vslot->GroupId);
+ }
+ }
+
+ // calculate vdisk space quota (or amount of available space when no enforcement is enabled)
+ i64 availableSpace = Max<i64>();
+ if (usable && !IgnoreVSlotQuotaCheck) {
+ if (info.SlotSpaceEnforced(State.Self)) {
+ availableSpace = info.Metrics.GetEnforcedDynamicSlotSize() * (1000 - PDiskSpaceMarginPromille) / 1000;
+ } else {
+ // here we assume that no space enforcement takes place and we have to calculate available space
+ // for this disk; we take it as available space and keep in mind that PDisk must have at least
+ // PDiskSpaceMarginPromille space remaining
+ availableSpace = info.Metrics.GetAvailableSize() - info.Metrics.GetTotalSize() * PDiskSpaceMarginPromille / 1000;
+
+ // also we have to find replicating VSlots on this PDisk and assume they consume up to
+ // max(vslotSize for every slot in group), not their actual AllocatedSize
+ for (const auto& [id, slot] : info.VSlotsOnPDisk) {
+ if (slot->Group && slot->GetStatus() != NKikimrBlobStorage::EVDiskStatus::READY) {
+ ui64 maxGroupSlotSize = 0;
+ for (const TVSlotInfo *peer : slot->Group->VDisksInGroup) {
+ maxGroupSlotSize = Max(maxGroupSlotSize, peer->Metrics.GetAllocatedSize());
+ }
+ // return actually used space to available pool
+ availableSpace += slot->Metrics.GetAllocatedSize();
+ // and consume expected slot size after replication finishes
+ availableSpace -= maxGroupSlotSize;
+ }
+ }
+ }
+ }
+
+ if (info.Status != NKikimrBlobStorage::EDriveStatus::ACTIVE) {
+ usable = false;
+ }
+
+ if (SettleOnlyOnOperationalDisks && !info.Operational) {
+ usable = false;
+ }
+
+ // register PDisk in the mapper
+ return Mapper->RegisterPDisk(id, State.HostRecords->GetLocation(id.NodeId), usable, numSlots,
+ info.ExpectedSlotCount, groups.data(), groups.size(), availableSpace, info.Operational);
+ }
+
+ std::map<TVDiskIdShort, TVSlotInfo*> CreateVSlotsForGroup(TGroupInfo *groupInfo,
+ const TGroupMapper::TGroupDefinition& group, const TMap<TVDiskID, TVSlotId>& preservedSlots) {
+ std::map<TVDiskIdShort, TVSlotInfo*> res;
+
+ // reset group contents as we are going to fill it right now
+ groupInfo->ClearVDisksInGroup();
+
+ for (ui32 failRealmIdx = 0; failRealmIdx < group.size(); ++failRealmIdx) {
+ const auto& realm = group[failRealmIdx];
+ for (ui32 failDomainIdx = 0; failDomainIdx < realm.size(); ++failDomainIdx) {
+ const auto& domain = realm[failDomainIdx];
+ for (ui32 vdiskIdx = 0; vdiskIdx < domain.size(); ++vdiskIdx) {
+ const TVDiskID vdiskId(groupInfo->ID, groupInfo->Generation, failRealmIdx, failDomainIdx, vdiskIdx);
+ if (auto it = preservedSlots.find(vdiskId); it != preservedSlots.end()) {
+ const TVSlotInfo *vslotInfo = State.VSlots.Find(it->second);
+ Y_VERIFY(vslotInfo);
+ groupInfo->AddVSlot(vslotInfo);
+ } else {
+ const TPDiskId pdiskId = domain[vdiskIdx];
+ Y_VERIFY(!State.PDisksToRemove.count(pdiskId));
+ TPDiskInfo *pdiskInfo = State.PDisks.FindForUpdate(pdiskId);
+ Y_VERIFY(pdiskInfo);
+ TVSlotId vslotId;
+
+ // allocate new VSlot id; avoid collisions
+ for (;;) {
+ const auto currentVSlotId = pdiskInfo->NextVSlotId;
+ pdiskInfo->NextVSlotId = currentVSlotId + 1;
+ vslotId = TVSlotId(pdiskId, currentVSlotId);
+ if (!State.VSlots.Find(vslotId)) {
+ break;
+ }
+ }
+
+ // insert new VSlot
+ TVSlotInfo *vslotInfo = State.VSlots.ConstructInplaceNewEntry(vslotId, vslotId, pdiskInfo,
+ groupInfo->ID, 0, groupInfo->Generation, StoragePool.VDiskKind, failRealmIdx,
+ failDomainIdx, vdiskIdx, TMood::Normal, groupInfo, &VSlotReadyTimestampQ,
+ TInstant::Zero());
+
+ // mark as uncommitted
+ State.UncommittedVSlots.insert(vslotId);
+
+ // remember newly created slot
+ res.emplace(vdiskId, vslotInfo);
+ }
+ }
+ }
+ }
+
+ groupInfo->FinishVDisksInGroup();
+ groupInfo->CalculateGroupStatus();
+
+ return res;
+ }
+ };
+
+ void TBlobStorageController::FitGroupsForUserConfig(TConfigState& state, ui32 availabilityDomainId,
+ const NKikimrBlobStorage::TConfigRequest& cmd, std::deque<ui64> expectedSlotSize,
+ NKikimrBlobStorage::TConfigResponse::TStatus& status) {
+ std::unordered_map<TString, std::pair<ui32, TBoxStoragePoolId>> filterMap;
+ std::unordered_set<TString> changedFilters;
+
+ // scan through all storage pools and fit the number of groups to desired one
+ for (const auto& [storagePoolId, storagePool] : state.StoragePools.Get()) {
+ TGroupFitter fitter(state, availabilityDomainId, cmd, expectedSlotSize, PDiskSpaceMarginPromille,
+ storagePoolId, storagePool, status, VSlotReadyTimestampQ);
+
+ const auto& storagePoolGroups = state.StoragePoolGroups.Get();
+ const auto range = storagePoolGroups.equal_range(storagePoolId);
+ ui32 numActualGroups = 0;
+
+ try {
+ TStringBuilder identifier;
+ identifier << "Erasure# " << storagePool.ErasureSpecies
+ << " Geometry# " << storagePool.RealmLevelBegin << "," << storagePool.RealmLevelEnd
+ << "," << storagePool.DomainLevelBegin << "," << storagePool.DomainLevelEnd
+ << "," << storagePool.NumFailRealms << "," << storagePool.NumFailDomainsPerFailRealm
+ << "," << storagePool.NumVDisksPerFailDomain;
+ for (const auto& filter : storagePool.PDiskFilters) {
+ identifier << " Filter# " << filter.Type << "," << filter.SharedWithOs
+ << "," << filter.ReadCentric << "," << filter.Kind;
+ }
+ auto& [numGroups, id] = filterMap[identifier];
+ numGroups += storagePool.NumGroups;
+ id = storagePoolId;
+
+ for (auto it = range.first; it != range.second; ++it, ++numActualGroups) {
+ fitter.CheckExistingGroup(it->second);
+ }
+ if (numActualGroups < storagePool.NumGroups) {
+ changedFilters.insert(identifier);
+ }
+ for (; numActualGroups < storagePool.NumGroups; ++numActualGroups) {
+ fitter.CreateGroup();
+ }
+ } catch (const TExFitGroupError& ex) {
+ throw TExError() << "Group fit error"
+ << " BoxId# " << std::get<0>(storagePoolId)
+ << " StoragePoolId# " << std::get<1>(storagePoolId)
+ << " Error# " << ex.what();
+ }
+ if (storagePool.NumGroups < numActualGroups) {
+ throw TExError() << "Storage pool modification error"
+ << " BoxId# " << std::get<0>(storagePoolId)
+ << " StoragePoolId# " << std::get<1>(storagePoolId)
+ << " impossible to reduce number of groups";
+ }
+ }
+
+ if (!cmd.GetIgnoreGroupReserve()) {
+ for (const auto& identifier : changedFilters) {
+ auto& [numGroups, storagePoolId] = filterMap.at(identifier);
+ const auto& storagePool = state.StoragePools.Get().at(storagePoolId);
+ TGroupFitter fitter(state, availabilityDomainId, cmd, expectedSlotSize, PDiskSpaceMarginPromille,
+ storagePoolId, storagePool, status, VSlotReadyTimestampQ);
+ fitter.CheckReserve(numGroups, GroupReserveMin, GroupReservePart);
+ }
+ }
+ }
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/config_fit_pdisks.cpp b/ydb/core/mind/bscontroller/config_fit_pdisks.cpp
index 3112a243172..ccff76ef792 100644
--- a/ydb/core/mind/bscontroller/config_fit_pdisks.cpp
+++ b/ydb/core/mind/bscontroller/config_fit_pdisks.cpp
@@ -1,8 +1,8 @@
-#include "config.h"
-
-namespace NKikimr {
- namespace NBsController {
-
+#include "config.h"
+
+namespace NKikimr {
+ namespace NBsController {
+
TPDiskId FindFirstEmptyPDiskId(const TOverlayMap<TPDiskId, TBlobStorageController::TPDiskInfo>& pdisks,
TNodeId nodeId) {
Schema::PDisk::PDiskID::Type nextPDiskID = 1000; // start allocation from this number
@@ -17,8 +17,8 @@ namespace NKikimr {
}
Schema::PDisk::Guid::Type TBlobStorageController::CheckStaticPDisk(TConfigState &state, TPDiskId pdiskId,
- const TPDiskCategory& category, const TMaybe<Schema::PDisk::PDiskConfig::Type>& pdiskConfig,
- ui32 *staticSlotUsage) {
+ const TPDiskCategory& category, const TMaybe<Schema::PDisk::PDiskConfig::Type>& pdiskConfig,
+ ui32 *staticSlotUsage) {
const TStaticPDiskInfo& info = state.StaticPDisks.at(pdiskId);
// create new disk entry; the PDisk with this number MUST NOT exist, otherwise we can
@@ -37,187 +37,187 @@ namespace NKikimr {
throw TExError() << "Type/Kind fields do not match static one";
}
- *staticSlotUsage = info.StaticSlotUsage;
+ *staticSlotUsage = info.StaticSlotUsage;
return info.Guid;
}
- void TBlobStorageController::AllocatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial,
- TDriveSerialInfo *driveInfo) {
- TPDiskId pdiskId = FindFirstEmptyPDiskId(state.PDisks, nodeId);
-
- const TNodeInfo& nodeInfo = state.Nodes.Get().at(nodeId);
- const NPDisk::TDriveData& driveData = nodeInfo.KnownDrives.at(serial.Serial);
- TString fsPath = driveData.Path;
-
- TPDiskCategory::EDeviceType type = PDiskTypeToPDiskType(driveInfo->PDiskType);
- if (type == TPDiskCategory::DEVICE_TYPE_UNKNOWN) {
- type = driveData.DeviceType;
- }
- const TPDiskCategory category(type, driveInfo->Kind);
-
- auto pdiskIt = state.PDiskLocationMap.find(TPDiskLocation{nodeId, fsPath});
- if (pdiskIt != state.PDiskLocationMap.end()) {
- throw TExError() << "PDisk found in PDiskLocationMap, fsPath# " << fsPath.Quote()
- << " pdiskId# " << pdiskIt->second;
- }
-
- ui32 staticSlotUsage = 0;
- auto staticPDiskIt = state.StaticPDiskLocationMap.find(TPDiskLocation{nodeId, fsPath});
- if (staticPDiskIt == state.StaticPDiskLocationMap.end()) {
- staticPDiskIt = state.StaticPDiskLocationMap.find(TPDiskLocation{nodeId, serial.Serial});
- }
- if (staticPDiskIt != state.StaticPDiskLocationMap.end()) {
- // PDisk is static one, so take it's pdiskId and guid
- // and check that parameters match
- pdiskId = staticPDiskIt->second;
- driveInfo->Guid = CheckStaticPDisk(state, pdiskId, category, driveInfo->PDiskConfig, &staticSlotUsage);
- }
- // Update FK in DriveSerial table and check for guid
- driveInfo->NodeId = pdiskId.NodeId;
- driveInfo->PDiskId = pdiskId.PDiskId;
- driveInfo->LifeStage = NKikimrBlobStorage::TDriveLifeStage::ALLOCATED;
-
- // if guid is known, reuse it, else generate new
- if (!driveInfo->Guid) {
- driveInfo->Guid = RandomNumber<Schema::PDisk::Guid::Type>();
- }
-
- const auto hostId = state.HostRecords->GetHostId(nodeId);
- if (!hostId) {
- throw TExError() << "Unable to find hostId by nodeId# " << nodeId;
- }
- state.PDisks.ConstructInplaceNewEntry(pdiskId, *hostId, TString(), category.GetRaw(),
- *driveInfo->Guid, false, false, 1000, driveInfo->PDiskConfig.GetOrElse(TString()),
- driveInfo->BoxId, DefaultMaxSlots, NKikimrBlobStorage::EDriveStatus::ACTIVE,
- TInstant::Zero(), serial.Serial, TString(), fsPath, staticSlotUsage);
-
- const TPDiskLocation location(nodeId, serial.Serial);
- state.PDiskLocationMap.emplace(location, pdiskId);
- STLOG(PRI_NOTICE, BS_CONTROLLER, BSCFP01, "Create new pdisk", (PDiskId, pdiskId),
- (Location, location));
- }
-
- void TBlobStorageController::ValidatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial,
- const TDriveSerialInfo& driveInfo, std::function<TDriveSerialInfo*()> getMutableItem) {
- // check existing pdisk
- if (!driveInfo.NodeId || !driveInfo.PDiskId) {
- throw TExError() << "Drive is in ALLOCATED stage but has "
- << " NodeId# " << driveInfo.NodeId
- << " PDiskId# " << driveInfo.PDiskId;
- }
-
- const TPDiskId pdiskId(*driveInfo.NodeId, *driveInfo.PDiskId);
- const TPDiskInfo *pdiskInfo = state.PDisks.Find(pdiskId);
- if (!pdiskInfo) {
- throw TExError() << "Unable to find pdisk# " << pdiskId << " from DriveSerial table";
- } else if (pdiskInfo->Path) {
- throw TExError() << "Going to replace existing pdisk with non-empty path# " << pdiskInfo->Path;
- } else if (pdiskInfo->ExpectedSerial != serial.Serial) {
- throw TExError() << "Going to replace existing pdisk with different serial number"
- << " new sn# " << serial.Serial << " existing serial# " << pdiskInfo->ExpectedSerial;
- } else if (pdiskInfo->Guid != *driveInfo.Guid) {
- throw TExError() << "Going to replace existring pdisk with different guid"
- << " guid from DrivesSerials# " << *driveInfo.Guid
- << " guid from PDisks# " << pdiskInfo->Guid;
- }
-
- const TPDiskLocation location(*driveInfo.NodeId, serial.Serial);
- if (state.PDiskLocationMap.count(location) + state.StaticPDiskLocationMap.count(location) == 0) {
- throw TExError() << "Drive is in ALLOCATED state and PDisk is created,"
- " but is not found neither in PDiskLocationMap, nor in StaticPDiskLocationMap";
- }
-
- if (nodeId && nodeId != *driveInfo.NodeId) {
- // Drive was moved from previous node to new
- TDriveSerialInfo *info = getMutableItem();
- info->LifeStage = NKikimrBlobStorage::TDriveLifeStage::ERROR;
- }
-
- state.PDisksToRemove.erase(pdiskId);
- }
-
- void TBlobStorageController::FitPDisksForUserConfig(TConfigState &state) {
- // re-fill PDisksToRemove set with all PDisks, we will erase remaining ones from this set a bit later
- state.PDisksToRemove.clear();
- state.PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& /*pdiskInfo*/) {
- state.PDisksToRemove.insert(pdiskId);
- return true;
- });
-
+ void TBlobStorageController::AllocatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial,
+ TDriveSerialInfo *driveInfo) {
+ TPDiskId pdiskId = FindFirstEmptyPDiskId(state.PDisks, nodeId);
+
+ const TNodeInfo& nodeInfo = state.Nodes.Get().at(nodeId);
+ const NPDisk::TDriveData& driveData = nodeInfo.KnownDrives.at(serial.Serial);
+ TString fsPath = driveData.Path;
+
+ TPDiskCategory::EDeviceType type = PDiskTypeToPDiskType(driveInfo->PDiskType);
+ if (type == TPDiskCategory::DEVICE_TYPE_UNKNOWN) {
+ type = driveData.DeviceType;
+ }
+ const TPDiskCategory category(type, driveInfo->Kind);
+
+ auto pdiskIt = state.PDiskLocationMap.find(TPDiskLocation{nodeId, fsPath});
+ if (pdiskIt != state.PDiskLocationMap.end()) {
+ throw TExError() << "PDisk found in PDiskLocationMap, fsPath# " << fsPath.Quote()
+ << " pdiskId# " << pdiskIt->second;
+ }
+
+ ui32 staticSlotUsage = 0;
+ auto staticPDiskIt = state.StaticPDiskLocationMap.find(TPDiskLocation{nodeId, fsPath});
+ if (staticPDiskIt == state.StaticPDiskLocationMap.end()) {
+ staticPDiskIt = state.StaticPDiskLocationMap.find(TPDiskLocation{nodeId, serial.Serial});
+ }
+ if (staticPDiskIt != state.StaticPDiskLocationMap.end()) {
+ // PDisk is static one, so take it's pdiskId and guid
+ // and check that parameters match
+ pdiskId = staticPDiskIt->second;
+ driveInfo->Guid = CheckStaticPDisk(state, pdiskId, category, driveInfo->PDiskConfig, &staticSlotUsage);
+ }
+ // Update FK in DriveSerial table and check for guid
+ driveInfo->NodeId = pdiskId.NodeId;
+ driveInfo->PDiskId = pdiskId.PDiskId;
+ driveInfo->LifeStage = NKikimrBlobStorage::TDriveLifeStage::ALLOCATED;
+
+ // if guid is known, reuse it, else generate new
+ if (!driveInfo->Guid) {
+ driveInfo->Guid = RandomNumber<Schema::PDisk::Guid::Type>();
+ }
+
+ const auto hostId = state.HostRecords->GetHostId(nodeId);
+ if (!hostId) {
+ throw TExError() << "Unable to find hostId by nodeId# " << nodeId;
+ }
+ state.PDisks.ConstructInplaceNewEntry(pdiskId, *hostId, TString(), category.GetRaw(),
+ *driveInfo->Guid, false, false, 1000, driveInfo->PDiskConfig.GetOrElse(TString()),
+ driveInfo->BoxId, DefaultMaxSlots, NKikimrBlobStorage::EDriveStatus::ACTIVE,
+ TInstant::Zero(), serial.Serial, TString(), fsPath, staticSlotUsage);
+
+ const TPDiskLocation location(nodeId, serial.Serial);
+ state.PDiskLocationMap.emplace(location, pdiskId);
+ STLOG(PRI_NOTICE, BS_CONTROLLER, BSCFP01, "Create new pdisk", (PDiskId, pdiskId),
+ (Location, location));
+ }
+
+ void TBlobStorageController::ValidatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial,
+ const TDriveSerialInfo& driveInfo, std::function<TDriveSerialInfo*()> getMutableItem) {
+ // check existing pdisk
+ if (!driveInfo.NodeId || !driveInfo.PDiskId) {
+ throw TExError() << "Drive is in ALLOCATED stage but has "
+ << " NodeId# " << driveInfo.NodeId
+ << " PDiskId# " << driveInfo.PDiskId;
+ }
+
+ const TPDiskId pdiskId(*driveInfo.NodeId, *driveInfo.PDiskId);
+ const TPDiskInfo *pdiskInfo = state.PDisks.Find(pdiskId);
+ if (!pdiskInfo) {
+ throw TExError() << "Unable to find pdisk# " << pdiskId << " from DriveSerial table";
+ } else if (pdiskInfo->Path) {
+ throw TExError() << "Going to replace existing pdisk with non-empty path# " << pdiskInfo->Path;
+ } else if (pdiskInfo->ExpectedSerial != serial.Serial) {
+ throw TExError() << "Going to replace existing pdisk with different serial number"
+ << " new sn# " << serial.Serial << " existing serial# " << pdiskInfo->ExpectedSerial;
+ } else if (pdiskInfo->Guid != *driveInfo.Guid) {
+ throw TExError() << "Going to replace existring pdisk with different guid"
+ << " guid from DrivesSerials# " << *driveInfo.Guid
+ << " guid from PDisks# " << pdiskInfo->Guid;
+ }
+
+ const TPDiskLocation location(*driveInfo.NodeId, serial.Serial);
+ if (state.PDiskLocationMap.count(location) + state.StaticPDiskLocationMap.count(location) == 0) {
+ throw TExError() << "Drive is in ALLOCATED state and PDisk is created,"
+ " but is not found neither in PDiskLocationMap, nor in StaticPDiskLocationMap";
+ }
+
+ if (nodeId && nodeId != *driveInfo.NodeId) {
+ // Drive was moved from previous node to new
+ TDriveSerialInfo *info = getMutableItem();
+ info->LifeStage = NKikimrBlobStorage::TDriveLifeStage::ERROR;
+ }
+
+ state.PDisksToRemove.erase(pdiskId);
+ }
+
+ void TBlobStorageController::FitPDisksForUserConfig(TConfigState &state) {
+ // re-fill PDisksToRemove set with all PDisks, we will erase remaining ones from this set a bit later
+ state.PDisksToRemove.clear();
+ state.PDisks.ForEach([&](const TPDiskId& pdiskId, const TPDiskInfo& /*pdiskInfo*/) {
+ state.PDisksToRemove.insert(pdiskId);
+ return true;
+ });
+
// Create new pdisks from DriveSerial table
// Iterate over initial DrivesSerials map since every call to Unshare will invalidate iterators
- state.DrivesSerials.ScanRange({}, {}, [&](const auto& serial, const auto& driveInfo, const auto& getMutableItem) {
+ state.DrivesSerials.ScanRange({}, {}, [&](const auto& serial, const auto& driveInfo, const auto& getMutableItem) {
if (driveInfo.LifeStage == NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN) {
// Try to find drive in currently online nodes and create new PDisk
if (auto nodeIt = NodeForSerial.find(serial.Serial); nodeIt != NodeForSerial.end()) {
- AllocatePDiskWithSerial(state, nodeIt->second, serial, getMutableItem());
+ AllocatePDiskWithSerial(state, nodeIt->second, serial, getMutableItem());
}
} else if (driveInfo.LifeStage == NKikimrBlobStorage::TDriveLifeStage::ALLOCATED
|| driveInfo.LifeStage == NKikimrBlobStorage::TDriveLifeStage::ERROR) {
- const auto it = NodeForSerial.find(serial.Serial);
- const ui32 nodeId = it != NodeForSerial.end() ? it->second : 0;
- // TODO(alexvru): check where no entry in NodeForSerial is a valid case
- ValidatePDiskWithSerial(state, nodeId, serial, driveInfo, getMutableItem);
+ const auto it = NodeForSerial.find(serial.Serial);
+ const ui32 nodeId = it != NodeForSerial.end() ? it->second : 0;
+ // TODO(alexvru): check where no entry in NodeForSerial is a valid case
+ ValidatePDiskWithSerial(state, nodeId, serial, driveInfo, getMutableItem);
}
- return true;
- });
-
- const auto &hostConfigs = state.HostConfigs.Get();
- for (const auto &kvBox : state.Boxes.Get()) {
- const TBoxId &boxId = kvBox.first;
- const TBoxInfo &box = kvBox.second;
- for (const auto& [hostKey, hostValue] : box.Hosts) {
- const THostConfigId &hostConfigId = hostValue.HostConfigId;
- auto it = hostConfigs.find(hostConfigId);
- if (it == hostConfigs.end()) {
- throw TExHostConfigNotFound(hostConfigId);
- }
- const THostConfigInfo &hostConfig = it->second;
-
- const THostId hostId(hostKey.Fqdn, hostKey.IcPort);
- const auto& nodeId = state.HostRecords->GetNodeId(hostId);
- if (!nodeId) {
- throw TExHostNotFound(hostKey);
- }
-
- for (const auto& [drive, driveInfo] : hostConfig.Drives) {
- const TPDiskLocation location(*nodeId, drive.Path);
- TPDiskId pdiskId;
- const TPDiskCategory category(PDiskTypeToPDiskType(driveInfo.Type), driveInfo.Kind);
-
- // check if we already have spawned some PDisk at this location
- auto pdiskIt = state.PDiskLocationMap.find(location);
- if (pdiskIt != state.PDiskLocationMap.end()) {
- // yes, we do; find it by id and update some characteristics (that we can update)
- pdiskId = pdiskIt->second;
- const TPDiskInfo *pdisk = state.PDisks.Find(pdiskId);
- Y_VERIFY(pdisk);
- // update PDisk configuration if needed
- if (pdisk->Kind != category || pdisk->SharedWithOs != driveInfo.SharedWithOs ||
- pdisk->ReadCentric != driveInfo.ReadCentric || pdisk->BoxId != boxId ||
+ return true;
+ });
+
+ const auto &hostConfigs = state.HostConfigs.Get();
+ for (const auto &kvBox : state.Boxes.Get()) {
+ const TBoxId &boxId = kvBox.first;
+ const TBoxInfo &box = kvBox.second;
+ for (const auto& [hostKey, hostValue] : box.Hosts) {
+ const THostConfigId &hostConfigId = hostValue.HostConfigId;
+ auto it = hostConfigs.find(hostConfigId);
+ if (it == hostConfigs.end()) {
+ throw TExHostConfigNotFound(hostConfigId);
+ }
+ const THostConfigInfo &hostConfig = it->second;
+
+ const THostId hostId(hostKey.Fqdn, hostKey.IcPort);
+ const auto& nodeId = state.HostRecords->GetNodeId(hostId);
+ if (!nodeId) {
+ throw TExHostNotFound(hostKey);
+ }
+
+ for (const auto& [drive, driveInfo] : hostConfig.Drives) {
+ const TPDiskLocation location(*nodeId, drive.Path);
+ TPDiskId pdiskId;
+ const TPDiskCategory category(PDiskTypeToPDiskType(driveInfo.Type), driveInfo.Kind);
+
+ // check if we already have spawned some PDisk at this location
+ auto pdiskIt = state.PDiskLocationMap.find(location);
+ if (pdiskIt != state.PDiskLocationMap.end()) {
+ // yes, we do; find it by id and update some characteristics (that we can update)
+ pdiskId = pdiskIt->second;
+ const TPDiskInfo *pdisk = state.PDisks.Find(pdiskId);
+ Y_VERIFY(pdisk);
+ // update PDisk configuration if needed
+ if (pdisk->Kind != category || pdisk->SharedWithOs != driveInfo.SharedWithOs ||
+ pdisk->ReadCentric != driveInfo.ReadCentric || pdisk->BoxId != boxId ||
pdisk->PDiskConfig != driveInfo.PDiskConfig.GetOrElse(TString())) {
- TPDiskInfo *pdisk = state.PDisks.FindForUpdate(pdiskId);
- pdisk->Kind = category;
- pdisk->SharedWithOs = driveInfo.SharedWithOs;
- pdisk->ReadCentric = driveInfo.ReadCentric;
- pdisk->BoxId = boxId;
- pdisk->PDiskConfig = driveInfo.PDiskConfig.GetOrElse(TString());
- pdisk->ExtractConfig(DefaultMaxSlots);
- }
- } else {
- Schema::PDisk::Guid::Type guid;
-
- // no, this disk is not in map yet; see if it is mentioned in static configuration
- ui32 staticSlotUsage = 0;
- if (auto pdiskIt = state.StaticPDiskLocationMap.find(location); pdiskIt != state.StaticPDiskLocationMap.end()) {
- // yes, take some data from static configuration
- pdiskId = pdiskIt->second;
- guid = CheckStaticPDisk(state, pdiskId, category, driveInfo.PDiskConfig, &staticSlotUsage);
- } else {
+ TPDiskInfo *pdisk = state.PDisks.FindForUpdate(pdiskId);
+ pdisk->Kind = category;
+ pdisk->SharedWithOs = driveInfo.SharedWithOs;
+ pdisk->ReadCentric = driveInfo.ReadCentric;
+ pdisk->BoxId = boxId;
+ pdisk->PDiskConfig = driveInfo.PDiskConfig.GetOrElse(TString());
+ pdisk->ExtractConfig(DefaultMaxSlots);
+ }
+ } else {
+ Schema::PDisk::Guid::Type guid;
+
+ // no, this disk is not in map yet; see if it is mentioned in static configuration
+ ui32 staticSlotUsage = 0;
+ if (auto pdiskIt = state.StaticPDiskLocationMap.find(location); pdiskIt != state.StaticPDiskLocationMap.end()) {
+ // yes, take some data from static configuration
+ pdiskId = pdiskIt->second;
+ guid = CheckStaticPDisk(state, pdiskId, category, driveInfo.PDiskConfig, &staticSlotUsage);
+ } else {
pdiskId = FindFirstEmptyPDiskId(state.PDisks, *nodeId);
- guid = RandomNumber<Schema::PDisk::Guid::Type>();
- }
+ guid = RandomNumber<Schema::PDisk::Guid::Type>();
+ }
TString path = drive.Path;
// try find current serial number for device
TString currentSerial;
@@ -235,43 +235,43 @@ namespace NKikimr {
guid, driveInfo.SharedWithOs, driveInfo.ReadCentric, 1000,
driveInfo.PDiskConfig.GetOrElse(TString()), boxId, DefaultMaxSlots,
NKikimrBlobStorage::EDriveStatus::ACTIVE, TInstant::Zero(), currentSerial, currentSerial,
- TString(), staticSlotUsage);
-
- // insert PDisk into location map
- state.PDiskLocationMap.emplace(location, pdiskId);
+ TString(), staticSlotUsage);
+
+ // insert PDisk into location map
+ state.PDiskLocationMap.emplace(location, pdiskId);
STLOG(PRI_NOTICE, BS_CONTROLLER, BSCFP02, "Create new pdisk", (PDiskId, pdiskId),
(Location, location));
- }
-
- state.PDisksToRemove.erase(pdiskId);
- }
- }
- }
+ }
+
+ state.PDisksToRemove.erase(pdiskId);
+ }
+ }
+ }
for (const auto& pdiskId : state.PDisksToRemove) {
STLOG(PRI_NOTICE, BS_CONTROLLER, BSCFP03, "PDisk to remove:", (PDiskId, pdiskId));
}
- }
-
- void TBlobStorageController::FitPDisksForNode(TConfigState& state, ui32 nodeId, const std::vector<TSerial>& serials) {
- for (const TString& serial : serials) {
- if (const TDriveSerialInfo *driveInfo = state.DrivesSerials.Find(serial)) {
- switch (driveInfo->LifeStage) {
- case NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN:
- AllocatePDiskWithSerial(state, nodeId, serial, state.DrivesSerials.FindForUpdate(serial));
- break;
-
- case NKikimrBlobStorage::TDriveLifeStage::ALLOCATED:
- case NKikimrBlobStorage::TDriveLifeStage::ERROR:
- ValidatePDiskWithSerial(state, nodeId, serial, *driveInfo,
- [&] { return state.DrivesSerials.FindForUpdate(serial); });
- break;
-
- default:
- break;
- }
- }
- }
- }
-
- } // NBsController
-} // NKikimr
+ }
+
+ void TBlobStorageController::FitPDisksForNode(TConfigState& state, ui32 nodeId, const std::vector<TSerial>& serials) {
+ for (const TString& serial : serials) {
+ if (const TDriveSerialInfo *driveInfo = state.DrivesSerials.Find(serial)) {
+ switch (driveInfo->LifeStage) {
+ case NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN:
+ AllocatePDiskWithSerial(state, nodeId, serial, state.DrivesSerials.FindForUpdate(serial));
+ break;
+
+ case NKikimrBlobStorage::TDriveLifeStage::ALLOCATED:
+ case NKikimrBlobStorage::TDriveLifeStage::ERROR:
+ ValidatePDiskWithSerial(state, nodeId, serial, *driveInfo,
+ [&] { return state.DrivesSerials.FindForUpdate(serial); });
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/defs.h b/ydb/core/mind/bscontroller/defs.h
index 162907fe8e3..f394f237525 100644
--- a/ydb/core/mind/bscontroller/defs.h
+++ b/ydb/core/mind/bscontroller/defs.h
@@ -1,7 +1,7 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/mind/defs.h>
-
+
#include <google/protobuf/text_format.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/blobstorage.h>
@@ -41,14 +41,14 @@
#include <library/cpp/actors/core/log.h>
#include <library/cpp/actors/interconnect/interconnect.h>
#include <library/cpp/monlib/service/pages/templates.h>
-#include <type_traits>
-#include <util/generic/algorithm.h>
-#include <util/generic/intrlist.h>
-#include <util/generic/map.h>
-#include <util/generic/ptr.h>
-#include <util/generic/set.h>
-#include <util/generic/string.h>
-#include <util/generic/vector.h>
-#include <util/string/builder.h>
-#include <util/string/strip.h>
-#include <util/system/hp_timer.h>
+#include <type_traits>
+#include <util/generic/algorithm.h>
+#include <util/generic/intrlist.h>
+#include <util/generic/map.h>
+#include <util/generic/ptr.h>
+#include <util/generic/set.h>
+#include <util/generic/string.h>
+#include <util/generic/vector.h>
+#include <util/string/builder.h>
+#include <util/string/strip.h>
+#include <util/system/hp_timer.h>
diff --git a/ydb/core/mind/bscontroller/diff.h b/ydb/core/mind/bscontroller/diff.h
index cf8fb352245..ec397ada8eb 100644
--- a/ydb/core/mind/bscontroller/diff.h
+++ b/ydb/core/mind/bscontroller/diff.h
@@ -1,134 +1,134 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NDiffUtils {
-
- template<typename T>
- struct TKeyLess;
-
- template<typename TKey, typename TValue>
- struct TKeyLess<TMap<TKey, TValue>> {
- using T = typename TMap<TKey, TValue>::value_type;
- bool operator ()(const T &x, const T &y) const { return x.first < y.first; }
- };
-
- template<typename TItem>
- struct TKeyLess<TSet<TItem>> {
- using T = typename TSet<TItem>::value_type;
- bool operator ()(const T &x, const T &y) const { return x < y; }
- };
-
- template<typename TCont, typename TContIterator>
- class TDiffCalculator {
- class TIterator {
- const TDiffCalculator *Calc;
- TContIterator Left;
- TContIterator Right;
- enum class EState {
- LEFT,
- RIGHT,
- BOTH
- } State;
-
- using TValueRef = typename std::remove_reference<decltype(*std::declval<TContIterator>())>::type;
-
- public:
- TIterator(const TDiffCalculator *calc, TContIterator left, TContIterator right)
- : Calc(calc)
- , Left(left)
- , Right(right)
- {
- UpdateState();
- }
-
- std::pair<TValueRef*, TValueRef*> operator *() const {
- switch (State) {
- case EState::LEFT:
- return {&*Left, nullptr};
-
- case EState::BOTH:
- return {&*Left, &*Right};
-
- case EState::RIGHT:
- return {nullptr, &*Right};
- }
- }
-
- TIterator& operator ++() {
- if (State == EState::LEFT || State == EState::BOTH) {
- ++Left;
- }
- if (State == EState::RIGHT || State == EState::BOTH) {
- ++Right;
- }
- UpdateState();
- return *this;
- }
-
- bool operator !=(const TIterator& other) const {
- return Left != other.Left || Right != other.Right;
- }
-
- void UpdateState() {
- static constexpr TKeyLess<typename std::remove_const<TCont>::type> less;
- State =
- Left == Calc->Left->end() ? EState::RIGHT :
- Right == Calc->Right->end() ? EState::LEFT :
- less(*Left, *Right) ? EState::LEFT :
- less(*Right, *Left) ? EState::RIGHT :
- EState::BOTH;
- }
- };
-
- TCont LeftCont;
- TCont RightCont;
- TCont *Left;
- TCont *Right;
-
- public:
- TDiffCalculator(TCont *left, TCont *right)
- : Left(left ? left : &LeftCont)
- , Right(right ? right : &RightCont)
- {}
-
- TDiffCalculator(TCont&& left, TCont&& right)
- : LeftCont(std::move(left))
- , RightCont(std::move(right))
- , Left(&LeftCont)
- , Right(&RightCont)
- {}
-
- TIterator begin() const {
- return TIterator(this, Left->begin(), Right->begin());
- }
-
- TIterator end() const {
- return TIterator(this, Left->end(), Right->end());
- }
- };
-
-} // NDiffUtils
-
-template<typename TCont>
-NDiffUtils::TDiffCalculator<TCont, typename TCont::iterator> Diff(TCont *left, TCont *right) {
- if (left != right) {
- return {left, right};
- } else {
- return {nullptr, nullptr};
- }
-}
-
-template<typename TCont>
-NDiffUtils::TDiffCalculator<const TCont, typename TCont::const_iterator> Diff(const TCont *left, const TCont *right) {
- if (left != right) {
- return {left, right};
- } else {
- return {nullptr, nullptr};
- }
-}
-
-template<typename TCont>
-NDiffUtils::TDiffCalculator<TCont, typename TCont::iterator> Diff(TCont&& left, TCont&& right) {
- return {std::forward<TCont>(left), std::forward<TCont>(right)};
-}
+#pragma once
+
+#include "defs.h"
+
+namespace NDiffUtils {
+
+ template<typename T>
+ struct TKeyLess;
+
+ template<typename TKey, typename TValue>
+ struct TKeyLess<TMap<TKey, TValue>> {
+ using T = typename TMap<TKey, TValue>::value_type;
+ bool operator ()(const T &x, const T &y) const { return x.first < y.first; }
+ };
+
+ template<typename TItem>
+ struct TKeyLess<TSet<TItem>> {
+ using T = typename TSet<TItem>::value_type;
+ bool operator ()(const T &x, const T &y) const { return x < y; }
+ };
+
+ template<typename TCont, typename TContIterator>
+ class TDiffCalculator {
+ class TIterator {
+ const TDiffCalculator *Calc;
+ TContIterator Left;
+ TContIterator Right;
+ enum class EState {
+ LEFT,
+ RIGHT,
+ BOTH
+ } State;
+
+ using TValueRef = typename std::remove_reference<decltype(*std::declval<TContIterator>())>::type;
+
+ public:
+ TIterator(const TDiffCalculator *calc, TContIterator left, TContIterator right)
+ : Calc(calc)
+ , Left(left)
+ , Right(right)
+ {
+ UpdateState();
+ }
+
+ std::pair<TValueRef*, TValueRef*> operator *() const {
+ switch (State) {
+ case EState::LEFT:
+ return {&*Left, nullptr};
+
+ case EState::BOTH:
+ return {&*Left, &*Right};
+
+ case EState::RIGHT:
+ return {nullptr, &*Right};
+ }
+ }
+
+ TIterator& operator ++() {
+ if (State == EState::LEFT || State == EState::BOTH) {
+ ++Left;
+ }
+ if (State == EState::RIGHT || State == EState::BOTH) {
+ ++Right;
+ }
+ UpdateState();
+ return *this;
+ }
+
+ bool operator !=(const TIterator& other) const {
+ return Left != other.Left || Right != other.Right;
+ }
+
+ void UpdateState() {
+ static constexpr TKeyLess<typename std::remove_const<TCont>::type> less;
+ State =
+ Left == Calc->Left->end() ? EState::RIGHT :
+ Right == Calc->Right->end() ? EState::LEFT :
+ less(*Left, *Right) ? EState::LEFT :
+ less(*Right, *Left) ? EState::RIGHT :
+ EState::BOTH;
+ }
+ };
+
+ TCont LeftCont;
+ TCont RightCont;
+ TCont *Left;
+ TCont *Right;
+
+ public:
+ TDiffCalculator(TCont *left, TCont *right)
+ : Left(left ? left : &LeftCont)
+ , Right(right ? right : &RightCont)
+ {}
+
+ TDiffCalculator(TCont&& left, TCont&& right)
+ : LeftCont(std::move(left))
+ , RightCont(std::move(right))
+ , Left(&LeftCont)
+ , Right(&RightCont)
+ {}
+
+ TIterator begin() const {
+ return TIterator(this, Left->begin(), Right->begin());
+ }
+
+ TIterator end() const {
+ return TIterator(this, Left->end(), Right->end());
+ }
+ };
+
+} // NDiffUtils
+
+template<typename TCont>
+NDiffUtils::TDiffCalculator<TCont, typename TCont::iterator> Diff(TCont *left, TCont *right) {
+ if (left != right) {
+ return {left, right};
+ } else {
+ return {nullptr, nullptr};
+ }
+}
+
+template<typename TCont>
+NDiffUtils::TDiffCalculator<const TCont, typename TCont::const_iterator> Diff(const TCont *left, const TCont *right) {
+ if (left != right) {
+ return {left, right};
+ } else {
+ return {nullptr, nullptr};
+ }
+}
+
+template<typename TCont>
+NDiffUtils::TDiffCalculator<TCont, typename TCont::iterator> Diff(TCont&& left, TCont&& right) {
+ return {std::forward<TCont>(left), std::forward<TCont>(right)};
+}
diff --git a/ydb/core/mind/bscontroller/disk_metrics.cpp b/ydb/core/mind/bscontroller/disk_metrics.cpp
index 3d045243fe4..6bfb64af744 100644
--- a/ydb/core/mind/bscontroller/disk_metrics.cpp
+++ b/ydb/core/mind/bscontroller/disk_metrics.cpp
@@ -1,115 +1,115 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxUpdateDiskMetrics : public TTransactionBase<TBlobStorageController> {
-public:
- TTxUpdateDiskMetrics(TBlobStorageController *controller)
- : TBase(controller)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_DISK_METRICS; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_USEC);
-
- NIceDb::TNiceDb db(txc.DB);
-
- for (const auto& [pdiskId, pdisk] : Self->PDisks) {
- if (std::exchange(pdisk->MetricsDirty, false)) {
- auto&& key = pdiskId.GetKey();
- auto value = pdisk->Metrics;
- value.ClearPDiskId();
- db.Table<Schema::PDiskMetrics>().Key(key).Update<Schema::PDiskMetrics::Metrics>(value);
- Self->SysViewChangedPDisks.insert(pdiskId);
- }
- }
-
- for (const auto& [vslotId, v] : Self->VSlots) {
- if (std::exchange(v->MetricsDirty, false)) {
- auto&& key = std::tie(v->GroupId, v->GroupGeneration, v->RingIdx, v->FailDomainIdx, v->VDiskIdx);
- auto value = v->Metrics;
- value.ClearVDiskId();
- db.Table<Schema::VDiskMetrics>().Key(key).Update<Schema::VDiskMetrics::Metrics>(value);
- Self->SysViewChangedVSlots.insert(vslotId);
- Self->SysViewChangedGroups.insert(v->GroupId);
- }
- }
-
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev) {
- TabletCounters->Cumulative()[NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_COUNT].Increment(1);
- TRequestCounter counter(TabletCounters, NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_USEC);
-
- auto& record = ev->Get()->Record;
-
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXUDM01, "Updating disk status", (Record, record));
-
- // apply VDisk metrics update
- std::set<const TGroupInfo*> dirtyGroups;
- for (const auto& m : record.GetVDisksMetrics()) {
- const TVDiskID vdiskId = VDiskIDFromVDiskID(m.GetVDiskId());
- if (const auto *slot = FindVSlot(vdiskId)) {
- i64 allocatedSizeIncrement;
- if (slot->UpdateVDiskMetrics(m, &allocatedSizeIncrement) && slot->Group) {
- dirtyGroups.insert(slot->Group);
- }
- if (allocatedSizeIncrement && !slot->IsBeingDeleted()) {
- const TGroupInfo *group = FindGroup(slot->GroupId);
- Y_VERIFY(group);
- StoragePoolStat->UpdateAllocatedSize(TStoragePoolStat::ConvertId(group->StoragePoolId), allocatedSizeIncrement);
- }
- } else if (const auto it = StaticVDiskMap.find(vdiskId); it != StaticVDiskMap.end()) {
- TStaticVSlotInfo& info = StaticVSlots.at(it->second);
- info.VDiskMetrics = m;
- } else {
- STLOG(PRI_NOTICE, BS_CONTROLLER, BSCTXUDM02, "VDisk not found", (VDiskId, vdiskId));
- }
- }
- for (const TGroupInfo *group : dirtyGroups) {
- const TStorageStatusFlags flags = group->GetStorageStatusFlags();
- StoragePoolStat->Update(TStoragePoolStat::ConvertId(group->StoragePoolId), group->StatusFlags, flags);
- group->StatusFlags = flags;
- }
-
- // apply PDisk metrics update
- TSet<TList<TSelectGroupsQueueItem>::iterator, TPDiskToQueueComp> queues;
- for (const auto& m : record.GetPDisksMetrics()) {
- const TPDiskId pdiskId(ev->Sender.NodeId(), m.GetPDiskId());
- if (auto *pdisk = FindPDisk(pdiskId)) {
- if (pdisk->UpdatePDiskMetrics(m)) {
- const auto first = std::make_pair(pdiskId, TList<TSelectGroupsQueueItem>::iterator());
- for (auto it = PDiskToQueue.lower_bound(first); it != PDiskToQueue.end() && it->first == pdiskId; ++it) {
- queues.insert(it->second);
- }
- }
- pdisk->UpdateOperational(true);
- } else if (const auto it = StaticPDisks.find(pdiskId); it != StaticPDisks.end()) {
- it->second.PDiskMetrics = m;
- } else {
- STLOG(PRI_NOTICE, BS_CONTROLLER, BSCTXUDM03, "PDisk not found", (PDiskId, pdiskId));
- }
- }
- for (const TList<TSelectGroupsQueueItem>::iterator it : queues) {
- ProcessSelectGroupsQueueItem(it);
- }
-
- // process VDisk status
- ProcessVDiskStatus(record.GetVDiskStatus());
-
- // commit into database if enough time has passed
- const TInstant now = TActivationContext::Now();
- if (now - LastMetricsCommit >= TDuration::Seconds(15)) {
- Execute(new TTxUpdateDiskMetrics(this));
- LastMetricsCommit = now;
- }
-}
-
-}
-}
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxUpdateDiskMetrics : public TTransactionBase<TBlobStorageController> {
+public:
+ TTxUpdateDiskMetrics(TBlobStorageController *controller)
+ : TBase(controller)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_DISK_METRICS; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_USEC);
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ for (const auto& [pdiskId, pdisk] : Self->PDisks) {
+ if (std::exchange(pdisk->MetricsDirty, false)) {
+ auto&& key = pdiskId.GetKey();
+ auto value = pdisk->Metrics;
+ value.ClearPDiskId();
+ db.Table<Schema::PDiskMetrics>().Key(key).Update<Schema::PDiskMetrics::Metrics>(value);
+ Self->SysViewChangedPDisks.insert(pdiskId);
+ }
+ }
+
+ for (const auto& [vslotId, v] : Self->VSlots) {
+ if (std::exchange(v->MetricsDirty, false)) {
+ auto&& key = std::tie(v->GroupId, v->GroupGeneration, v->RingIdx, v->FailDomainIdx, v->VDiskIdx);
+ auto value = v->Metrics;
+ value.ClearVDiskId();
+ db.Table<Schema::VDiskMetrics>().Key(key).Update<Schema::VDiskMetrics::Metrics>(value);
+ Self->SysViewChangedVSlots.insert(vslotId);
+ Self->SysViewChangedGroups.insert(v->GroupId);
+ }
+ }
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev) {
+ TabletCounters->Cumulative()[NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_COUNT].Increment(1);
+ TRequestCounter counter(TabletCounters, NBlobStorageController::COUNTER_UPDATE_DISK_METRICS_USEC);
+
+ auto& record = ev->Get()->Record;
+
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXUDM01, "Updating disk status", (Record, record));
+
+ // apply VDisk metrics update
+ std::set<const TGroupInfo*> dirtyGroups;
+ for (const auto& m : record.GetVDisksMetrics()) {
+ const TVDiskID vdiskId = VDiskIDFromVDiskID(m.GetVDiskId());
+ if (const auto *slot = FindVSlot(vdiskId)) {
+ i64 allocatedSizeIncrement;
+ if (slot->UpdateVDiskMetrics(m, &allocatedSizeIncrement) && slot->Group) {
+ dirtyGroups.insert(slot->Group);
+ }
+ if (allocatedSizeIncrement && !slot->IsBeingDeleted()) {
+ const TGroupInfo *group = FindGroup(slot->GroupId);
+ Y_VERIFY(group);
+ StoragePoolStat->UpdateAllocatedSize(TStoragePoolStat::ConvertId(group->StoragePoolId), allocatedSizeIncrement);
+ }
+ } else if (const auto it = StaticVDiskMap.find(vdiskId); it != StaticVDiskMap.end()) {
+ TStaticVSlotInfo& info = StaticVSlots.at(it->second);
+ info.VDiskMetrics = m;
+ } else {
+ STLOG(PRI_NOTICE, BS_CONTROLLER, BSCTXUDM02, "VDisk not found", (VDiskId, vdiskId));
+ }
+ }
+ for (const TGroupInfo *group : dirtyGroups) {
+ const TStorageStatusFlags flags = group->GetStorageStatusFlags();
+ StoragePoolStat->Update(TStoragePoolStat::ConvertId(group->StoragePoolId), group->StatusFlags, flags);
+ group->StatusFlags = flags;
+ }
+
+ // apply PDisk metrics update
+ TSet<TList<TSelectGroupsQueueItem>::iterator, TPDiskToQueueComp> queues;
+ for (const auto& m : record.GetPDisksMetrics()) {
+ const TPDiskId pdiskId(ev->Sender.NodeId(), m.GetPDiskId());
+ if (auto *pdisk = FindPDisk(pdiskId)) {
+ if (pdisk->UpdatePDiskMetrics(m)) {
+ const auto first = std::make_pair(pdiskId, TList<TSelectGroupsQueueItem>::iterator());
+ for (auto it = PDiskToQueue.lower_bound(first); it != PDiskToQueue.end() && it->first == pdiskId; ++it) {
+ queues.insert(it->second);
+ }
+ }
+ pdisk->UpdateOperational(true);
+ } else if (const auto it = StaticPDisks.find(pdiskId); it != StaticPDisks.end()) {
+ it->second.PDiskMetrics = m;
+ } else {
+ STLOG(PRI_NOTICE, BS_CONTROLLER, BSCTXUDM03, "PDisk not found", (PDiskId, pdiskId));
+ }
+ }
+ for (const TList<TSelectGroupsQueueItem>::iterator it : queues) {
+ ProcessSelectGroupsQueueItem(it);
+ }
+
+ // process VDisk status
+ ProcessVDiskStatus(record.GetVDiskStatus());
+
+ // commit into database if enough time has passed
+ const TInstant now = TActivationContext::Now();
+ if (now - LastMetricsCommit >= TDuration::Seconds(15)) {
+ Execute(new TTxUpdateDiskMetrics(this));
+ LastMetricsCommit = now;
+ }
+}
+
+}
+}
diff --git a/ydb/core/mind/bscontroller/drop_donor.cpp b/ydb/core/mind/bscontroller/drop_donor.cpp
index a445e7a9eb8..2ea2c8b0e59 100644
--- a/ydb/core/mind/bscontroller/drop_donor.cpp
+++ b/ydb/core/mind/bscontroller/drop_donor.cpp
@@ -1,50 +1,50 @@
-#include "impl.h"
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxDropDonor
- : public TTransactionBase<TBlobStorageController>
-{
- std::vector<TVSlotId> VSlotIds;
- std::optional<TConfigState> State;
-
-public:
- TTxDropDonor(TEvPrivate::TEvDropDonor::TPtr ev, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , VSlotIds(std::move(ev->Get()->VSlotIds))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_DROP_DONOR; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
- State->CheckConsistency();
- for (const TVSlotId& vslotId : VSlotIds) {
- if (const TVSlotInfo *vslot = State->VSlots.Find(vslotId); vslot && !vslot->IsBeingDeleted()) {
- Y_VERIFY(vslot->Mood == TMood::Donor);
- State->DestroyVSlot(vslotId);
- }
- }
- State->CheckConsistency();
- TString error;
- if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
- State->Rollback();
- State.reset();
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {
- if (State) {
- State->ApplyConfigUpdates();
- State.reset();
- }
- }
-};
-
-void TBlobStorageController::Handle(TEvPrivate::TEvDropDonor::TPtr ev) {
- Execute(new TTxDropDonor(ev, this));
-}
-
-} // NKikimr::NBsController
+#include "impl.h"
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxDropDonor
+ : public TTransactionBase<TBlobStorageController>
+{
+ std::vector<TVSlotId> VSlotIds;
+ std::optional<TConfigState> State;
+
+public:
+ TTxDropDonor(TEvPrivate::TEvDropDonor::TPtr ev, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , VSlotIds(std::move(ev->Get()->VSlotIds))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_DROP_DONOR; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
+ State->CheckConsistency();
+ for (const TVSlotId& vslotId : VSlotIds) {
+ if (const TVSlotInfo *vslot = State->VSlots.Find(vslotId); vslot && !vslot->IsBeingDeleted()) {
+ Y_VERIFY(vslot->Mood == TMood::Donor);
+ State->DestroyVSlot(vslotId);
+ }
+ }
+ State->CheckConsistency();
+ TString error;
+ if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
+ State->Rollback();
+ State.reset();
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ if (State) {
+ State->ApplyConfigUpdates();
+ State.reset();
+ }
+ }
+};
+
+void TBlobStorageController::Handle(TEvPrivate::TEvDropDonor::TPtr ev) {
+ Execute(new TTxDropDonor(ev, this));
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/error.h b/ydb/core/mind/bscontroller/error.h
index 6cd4a22cb2e..a15029e2ed2 100644
--- a/ydb/core/mind/bscontroller/error.h
+++ b/ydb/core/mind/bscontroller/error.h
@@ -1,208 +1,208 @@
-#pragma once
-
-#include "defs.h"
-#include "scheme.h"
-#include "types.h"
-
-namespace NKikimr::NBsController {
-
- template<typename Traits>
- struct TErrorParam {
- const typename Traits::Type Value;
-
- template<typename T>
- TErrorParam(T&& value)
- : Value(std::forward<T>(value))
- {}
- };
-
- struct TErrorParams {
-#define P(NAME, TYPE) \
- struct T##NAME##Traits { \
- using Type = TYPE; \
- static constexpr const char *GetName() { return #NAME; } \
- static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) { p.Set##NAME(value); } \
- }; \
- using NAME = TErrorParam<T##NAME##Traits>;
- P(Fqdn, TString)
- P(IcPort, i32)
- P(NodeId, ui32)
- P(PDiskId, ui32)
- P(Path, TString)
- P(HostConfigId, ui64)
- P(BoxId, ui64)
- P(StoragePoolId, ui64)
- P(ItemConfigGenerationProvided, ui64)
- P(ItemConfigGenerationExpected, ui64)
- P(GroupId, ui32)
-
- struct TVDiskIdTraits {
- using Type = TVDiskID;
- static constexpr const char *GetName() { return "VDiskId"; }
- static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) {
- VDiskIDFromVDiskID(value, p.MutableVDiskId());
- }
- };
- using VDiskId = TErrorParam<TVDiskIdTraits>;
-
- struct TVSlotIdTraits {
- using Type = TVSlotId;
- static constexpr const char *GetName() { return "VSlotId"; }
- static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) {
- value.Serialize(p.MutableVSlotId());
- }
- };
- using VSlotId = TErrorParam<TVSlotIdTraits>;
-#undef P
- };
-
- struct TExError : yexception {
- mutable std::deque<NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam> FailParams;
-
- void FillInStatus(NKikimrBlobStorage::TConfigResponse::TStatus& status) const {
- status.SetErrorDescription(what());
- status.SetFailReason(GetFailReason());
- for (const auto& p : FailParams) {
- auto *xp = status.AddFailParam();
- xp->CopyFrom(p);
- }
- }
-
- virtual NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kGeneric;
- }
-
- template<typename Traits>
- void Append(const TErrorParam<Traits>& p) {
- Traits::SetProto(*FailParams.emplace(FailParams.end()), p.Value);
- TStringStream s;
- s << " " << Traits::GetName() << "# " << p.Value;
- *this << s.Str();
- }
-
- template<typename T>
- void Append(const T& x) {
- yexception::Append(x);
- }
- };
-
- struct TExHostNotFound : TExError {
- TExHostNotFound(const NKikimrBlobStorage::THostKey& hostKey) {
- *this << "Host not found";
- if (hostKey.GetFqdn() || hostKey.GetIcPort()) {
- *this << TErrorParams::Fqdn(hostKey.GetFqdn()) << TErrorParams::IcPort(hostKey.GetIcPort());
- }
- if (hostKey.GetNodeId()) {
- *this << TErrorParams::NodeId(hostKey.GetNodeId());
- }
- }
-
- TExHostNotFound(const std::tuple<TString, i32>& hostKey) {
- *this << "Host not found"
- << TErrorParams::Fqdn(std::get<0>(hostKey))
- << TErrorParams::IcPort(std::get<1>(hostKey));
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kHostNotFound;
- }
- };
-
- struct TExPDiskNotFound : TExError {
- TExPDiskNotFound(const NKikimrBlobStorage::THostKey& hostKey, ui32 pdiskId, TString path) {
- *this << "PDisk not found"
- << TErrorParams::Fqdn(hostKey.GetFqdn())
- << TErrorParams::IcPort(hostKey.GetIcPort())
+#pragma once
+
+#include "defs.h"
+#include "scheme.h"
+#include "types.h"
+
+namespace NKikimr::NBsController {
+
+ template<typename Traits>
+ struct TErrorParam {
+ const typename Traits::Type Value;
+
+ template<typename T>
+ TErrorParam(T&& value)
+ : Value(std::forward<T>(value))
+ {}
+ };
+
+ struct TErrorParams {
+#define P(NAME, TYPE) \
+ struct T##NAME##Traits { \
+ using Type = TYPE; \
+ static constexpr const char *GetName() { return #NAME; } \
+ static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) { p.Set##NAME(value); } \
+ }; \
+ using NAME = TErrorParam<T##NAME##Traits>;
+ P(Fqdn, TString)
+ P(IcPort, i32)
+ P(NodeId, ui32)
+ P(PDiskId, ui32)
+ P(Path, TString)
+ P(HostConfigId, ui64)
+ P(BoxId, ui64)
+ P(StoragePoolId, ui64)
+ P(ItemConfigGenerationProvided, ui64)
+ P(ItemConfigGenerationExpected, ui64)
+ P(GroupId, ui32)
+
+ struct TVDiskIdTraits {
+ using Type = TVDiskID;
+ static constexpr const char *GetName() { return "VDiskId"; }
+ static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) {
+ VDiskIDFromVDiskID(value, p.MutableVDiskId());
+ }
+ };
+ using VDiskId = TErrorParam<TVDiskIdTraits>;
+
+ struct TVSlotIdTraits {
+ using Type = TVSlotId;
+ static constexpr const char *GetName() { return "VSlotId"; }
+ static void SetProto(NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam& p, const Type& value) {
+ value.Serialize(p.MutableVSlotId());
+ }
+ };
+ using VSlotId = TErrorParam<TVSlotIdTraits>;
+#undef P
+ };
+
+ struct TExError : yexception {
+ mutable std::deque<NKikimrBlobStorage::TConfigResponse::TStatus::TFailParam> FailParams;
+
+ void FillInStatus(NKikimrBlobStorage::TConfigResponse::TStatus& status) const {
+ status.SetErrorDescription(what());
+ status.SetFailReason(GetFailReason());
+ for (const auto& p : FailParams) {
+ auto *xp = status.AddFailParam();
+ xp->CopyFrom(p);
+ }
+ }
+
+ virtual NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kGeneric;
+ }
+
+ template<typename Traits>
+ void Append(const TErrorParam<Traits>& p) {
+ Traits::SetProto(*FailParams.emplace(FailParams.end()), p.Value);
+ TStringStream s;
+ s << " " << Traits::GetName() << "# " << p.Value;
+ *this << s.Str();
+ }
+
+ template<typename T>
+ void Append(const T& x) {
+ yexception::Append(x);
+ }
+ };
+
+ struct TExHostNotFound : TExError {
+ TExHostNotFound(const NKikimrBlobStorage::THostKey& hostKey) {
+ *this << "Host not found";
+ if (hostKey.GetFqdn() || hostKey.GetIcPort()) {
+ *this << TErrorParams::Fqdn(hostKey.GetFqdn()) << TErrorParams::IcPort(hostKey.GetIcPort());
+ }
+ if (hostKey.GetNodeId()) {
+ *this << TErrorParams::NodeId(hostKey.GetNodeId());
+ }
+ }
+
+ TExHostNotFound(const std::tuple<TString, i32>& hostKey) {
+ *this << "Host not found"
+ << TErrorParams::Fqdn(std::get<0>(hostKey))
+ << TErrorParams::IcPort(std::get<1>(hostKey));
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kHostNotFound;
+ }
+ };
+
+ struct TExPDiskNotFound : TExError {
+ TExPDiskNotFound(const NKikimrBlobStorage::THostKey& hostKey, ui32 pdiskId, TString path) {
+ *this << "PDisk not found"
+ << TErrorParams::Fqdn(hostKey.GetFqdn())
+ << TErrorParams::IcPort(hostKey.GetIcPort())
<< TErrorParams::NodeId(hostKey.GetNodeId())
<< TErrorParams::PDiskId(pdiskId)
<< TErrorParams::Path(path);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kPDiskNotFound;
- }
- };
-
- struct TExHostConfigNotFound : TExError {
- TExHostConfigNotFound(Schema::HostConfig::HostConfigId::Type hostConfigId) {
- *this << "HostConfig not found"
- << TErrorParams::HostConfigId(hostConfigId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kHostConfigNotFound;
- }
- };
-
- struct TExItemConfigGenerationMismatch : TExError {
- TExItemConfigGenerationMismatch(ui64 provided, ui64 expected) {
- *this << "ItemConfigGeneration mismatch"
- << TErrorParams::ItemConfigGenerationProvided(provided)
- << TErrorParams::ItemConfigGenerationExpected(expected);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kItemConfigGenerationMismatch;
- }
- };
-
- struct TExMayLoseData : TExError {
- TExMayLoseData(ui32 groupId) {
- *this << "Group may lose data"
- << TErrorParams::GroupId(groupId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kMayLoseData;
- }
- };
-
- struct TExMayGetDegraded : TExError {
- TExMayGetDegraded(ui32 groupId) {
- *this << "Group may become degraded"
- << TErrorParams::GroupId(groupId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kMayGetDegraded;
- }
- };
-
- struct TExVDiskIdIncorrect : TExError {
- TExVDiskIdIncorrect(const TVDiskID& vdiskId, const TVSlotId& vslotId) {
- *this << "VDiskId is incorrect for specified VSlotId" << TErrorParams::VDiskId(vdiskId)
- << TErrorParams::VSlotId(vslotId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kVDiskIdIncorrect;
- }
- };
-
- struct TExVSlotNotFound : TExError {
- TExVSlotNotFound(const TVSlotId& vslotId) {
- *this << "VSlot not found" << TErrorParams::VSlotId(vslotId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kVSlotNotFound;
- }
- };
-
- struct TExDiskIsNotDonor : TExError {
- TExDiskIsNotDonor(const TVSlotId& vslotId, const TVDiskID& vdiskId) {
- *this << "Disk is not in donor more" << TErrorParams::VSlotId(vslotId) << TErrorParams::VDiskId(vdiskId);
- }
-
- NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
- return NKikimrBlobStorage::TConfigResponse::TStatus::kDiskIsNotDonor;
- }
- };
-
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kPDiskNotFound;
+ }
+ };
+
+ struct TExHostConfigNotFound : TExError {
+ TExHostConfigNotFound(Schema::HostConfig::HostConfigId::Type hostConfigId) {
+ *this << "HostConfig not found"
+ << TErrorParams::HostConfigId(hostConfigId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kHostConfigNotFound;
+ }
+ };
+
+ struct TExItemConfigGenerationMismatch : TExError {
+ TExItemConfigGenerationMismatch(ui64 provided, ui64 expected) {
+ *this << "ItemConfigGeneration mismatch"
+ << TErrorParams::ItemConfigGenerationProvided(provided)
+ << TErrorParams::ItemConfigGenerationExpected(expected);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kItemConfigGenerationMismatch;
+ }
+ };
+
+ struct TExMayLoseData : TExError {
+ TExMayLoseData(ui32 groupId) {
+ *this << "Group may lose data"
+ << TErrorParams::GroupId(groupId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kMayLoseData;
+ }
+ };
+
+ struct TExMayGetDegraded : TExError {
+ TExMayGetDegraded(ui32 groupId) {
+ *this << "Group may become degraded"
+ << TErrorParams::GroupId(groupId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kMayGetDegraded;
+ }
+ };
+
+ struct TExVDiskIdIncorrect : TExError {
+ TExVDiskIdIncorrect(const TVDiskID& vdiskId, const TVSlotId& vslotId) {
+ *this << "VDiskId is incorrect for specified VSlotId" << TErrorParams::VDiskId(vdiskId)
+ << TErrorParams::VSlotId(vslotId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kVDiskIdIncorrect;
+ }
+ };
+
+ struct TExVSlotNotFound : TExError {
+ TExVSlotNotFound(const TVSlotId& vslotId) {
+ *this << "VSlot not found" << TErrorParams::VSlotId(vslotId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kVSlotNotFound;
+ }
+ };
+
+ struct TExDiskIsNotDonor : TExError {
+ TExDiskIsNotDonor(const TVSlotId& vslotId, const TVDiskID& vdiskId) {
+ *this << "Disk is not in donor more" << TErrorParams::VSlotId(vslotId) << TErrorParams::VDiskId(vdiskId);
+ }
+
+ NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
+ return NKikimrBlobStorage::TConfigResponse::TStatus::kDiskIsNotDonor;
+ }
+ };
+
struct TExAlready : TExError {
NKikimrBlobStorage::TConfigResponse::TStatus::EFailReason GetFailReason() const override {
return NKikimrBlobStorage::TConfigResponse::TStatus::kAlready;
}
};
-} // NKikimr::NBsController
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/get_group.cpp b/ydb/core/mind/bscontroller/get_group.cpp
index 235c3ee8d23..b6de6514443 100644
--- a/ydb/core/mind/bscontroller/get_group.cpp
+++ b/ydb/core/mind/bscontroller/get_group.cpp
@@ -1,46 +1,46 @@
-#include "impl.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxGetGroup : public TTransactionBase<TBlobStorageController> {
- TEvBlobStorage::TEvControllerGetGroup::TPtr Request;
- std::unique_ptr<IEventHandle> Response;
-
-public:
- TTxGetGroup(TEvBlobStorage::TEvControllerGetGroup::TPtr& ev, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , Request(ev)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_GET_GROUP; }
-
- bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_GET_GROUP_COUNT].Increment(1);
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_GET_GROUP_USEC);
-
- auto request = std::move(Request);
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGG01, "Handle TEvControllerGetGroup", (Request, request->Get()->Record));
-
- const auto& v = request->Get()->Record.GetGroupIDs();
- TSet<ui32> groupIDsToRead(v.begin(), v.end());
-
- const TNodeId nodeId = request->Get()->Record.GetNodeID();
- auto res = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
- Self->ReadGroups(groupIDsToRead, true, res.get());
-
- Response = std::make_unique<IEventHandle>(MakeBlobStorageNodeWardenID(nodeId), Self->SelfId(), res.release());
- return true;
- }
-
- void Complete(const TActorContext&) override {
- TActivationContext::Send(Response.release());
- }
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerGetGroup::TPtr& ev) {
- if (!StopGivingGroups) {
- Execute(new TTxGetGroup(ev, this));
- }
-}
-
-} // NKikimr::NBsController
+#include "impl.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxGetGroup : public TTransactionBase<TBlobStorageController> {
+ TEvBlobStorage::TEvControllerGetGroup::TPtr Request;
+ std::unique_ptr<IEventHandle> Response;
+
+public:
+ TTxGetGroup(TEvBlobStorage::TEvControllerGetGroup::TPtr& ev, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , Request(ev)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_GET_GROUP; }
+
+ bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_GET_GROUP_COUNT].Increment(1);
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_GET_GROUP_USEC);
+
+ auto request = std::move(Request);
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGG01, "Handle TEvControllerGetGroup", (Request, request->Get()->Record));
+
+ const auto& v = request->Get()->Record.GetGroupIDs();
+ TSet<ui32> groupIDsToRead(v.begin(), v.end());
+
+ const TNodeId nodeId = request->Get()->Record.GetNodeID();
+ auto res = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
+ Self->ReadGroups(groupIDsToRead, true, res.get());
+
+ Response = std::make_unique<IEventHandle>(MakeBlobStorageNodeWardenID(nodeId), Self->SelfId(), res.release());
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ TActivationContext::Send(Response.release());
+ }
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerGetGroup::TPtr& ev) {
+ if (!StopGivingGroups) {
+ Execute(new TTxGetGroup(ev, this));
+ }
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/group_geometry_info.h b/ydb/core/mind/bscontroller/group_geometry_info.h
index 10e5daedba0..92074d2f776 100644
--- a/ydb/core/mind/bscontroller/group_geometry_info.h
+++ b/ydb/core/mind/bscontroller/group_geometry_info.h
@@ -1,123 +1,123 @@
#pragma once
-#include "defs.h"
-
+#include "defs.h"
+
#include "impl.h"
#include "config.h"
#include "group_mapper.h"
-namespace NKikimr::NBsController {
+namespace NKikimr::NBsController {
- struct TExFitGroupError : yexception {};
+ struct TExFitGroupError : yexception {};
- class TGroupGeometryInfo {
- const TBlobStorageGroupType Type;
- ui32 NumFailRealms;
- ui32 NumFailDomainsPerFailRealm;
- ui32 NumVDisksPerFailDomain;
- ui32 RealmLevelBegin;
- ui32 RealmLevelEnd;
- ui32 DomainLevelBegin;
- ui32 DomainLevelEnd;
+ class TGroupGeometryInfo {
+ const TBlobStorageGroupType Type;
+ ui32 NumFailRealms;
+ ui32 NumFailDomainsPerFailRealm;
+ ui32 NumVDisksPerFailDomain;
+ ui32 RealmLevelBegin;
+ ui32 RealmLevelEnd;
+ ui32 DomainLevelBegin;
+ ui32 DomainLevelEnd;
- public:
- TGroupGeometryInfo(TBlobStorageGroupType type, NKikimrBlobStorage::TGroupGeometry g)
- : Type(type)
- , NumFailRealms(g.GetNumFailRealms())
- , NumFailDomainsPerFailRealm(g.GetNumFailDomainsPerFailRealm())
- , NumVDisksPerFailDomain(g.GetNumVDisksPerFailDomain())
- , RealmLevelBegin(g.GetRealmLevelBegin())
- , RealmLevelEnd(g.GetRealmLevelEnd())
- , DomainLevelBegin(g.GetDomainLevelBegin())
- , DomainLevelEnd(g.GetDomainLevelEnd())
- {
- // calculate default minimum values
- const bool isMirror3dc = Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc;
- const ui32 minNumFailRealms = isMirror3dc ? 3 : 1;
- const ui32 minNumFailDomainsPerFailRealm = isMirror3dc ? 3 : Type.BlobSubgroupSize();
- const ui32 minNumVDisksPerFailDomain = 1;
+ public:
+ TGroupGeometryInfo(TBlobStorageGroupType type, NKikimrBlobStorage::TGroupGeometry g)
+ : Type(type)
+ , NumFailRealms(g.GetNumFailRealms())
+ , NumFailDomainsPerFailRealm(g.GetNumFailDomainsPerFailRealm())
+ , NumVDisksPerFailDomain(g.GetNumVDisksPerFailDomain())
+ , RealmLevelBegin(g.GetRealmLevelBegin())
+ , RealmLevelEnd(g.GetRealmLevelEnd())
+ , DomainLevelBegin(g.GetDomainLevelBegin())
+ , DomainLevelEnd(g.GetDomainLevelEnd())
+ {
+ // calculate default minimum values
+ const bool isMirror3dc = Type.GetErasure() == TBlobStorageGroupType::ErasureMirror3dc;
+ const ui32 minNumFailRealms = isMirror3dc ? 3 : 1;
+ const ui32 minNumFailDomainsPerFailRealm = isMirror3dc ? 3 : Type.BlobSubgroupSize();
+ const ui32 minNumVDisksPerFailDomain = 1;
- if (!NumFailRealms && !NumFailDomainsPerFailRealm && !NumVDisksPerFailDomain) {
- // no values are set, this means we're going to use the default ones
- NumFailRealms = minNumFailRealms;
- NumFailDomainsPerFailRealm = minNumFailDomainsPerFailRealm;
- NumVDisksPerFailDomain = minNumVDisksPerFailDomain;
- } else if (NumFailRealms < minNumFailRealms ||
- NumFailDomainsPerFailRealm < minNumFailDomainsPerFailRealm ||
- NumVDisksPerFailDomain < minNumVDisksPerFailDomain) {
- throw TExFitGroupError() << "not enough fail domains, fail realms, or vdisks for specified erasure";
+ if (!NumFailRealms && !NumFailDomainsPerFailRealm && !NumVDisksPerFailDomain) {
+ // no values are set, this means we're going to use the default ones
+ NumFailRealms = minNumFailRealms;
+ NumFailDomainsPerFailRealm = minNumFailDomainsPerFailRealm;
+ NumVDisksPerFailDomain = minNumVDisksPerFailDomain;
+ } else if (NumFailRealms < minNumFailRealms ||
+ NumFailDomainsPerFailRealm < minNumFailDomainsPerFailRealm ||
+ NumVDisksPerFailDomain < minNumVDisksPerFailDomain) {
+ throw TExFitGroupError() << "not enough fail domains, fail realms, or vdisks for specified erasure";
}
- if (RealmLevelBegin || RealmLevelEnd || DomainLevelBegin || DomainLevelEnd) {
- if (RealmLevelEnd < RealmLevelBegin || DomainLevelEnd < DomainLevelBegin) {
- throw TExFitGroupError() << "XxxLevelBegin must be less than or equal to XxxLevelEnd";
- }
- } else {
- RealmLevelBegin = 10;
- RealmLevelEnd = 20;
- DomainLevelBegin = 10;
- DomainLevelEnd = 40;
+ if (RealmLevelBegin || RealmLevelEnd || DomainLevelBegin || DomainLevelEnd) {
+ if (RealmLevelEnd < RealmLevelBegin || DomainLevelEnd < DomainLevelBegin) {
+ throw TExFitGroupError() << "XxxLevelBegin must be less than or equal to XxxLevelEnd";
+ }
+ } else {
+ RealmLevelBegin = 10;
+ RealmLevelEnd = 20;
+ DomainLevelBegin = 10;
+ DomainLevelEnd = 40;
}
- }
+ }
- ui32 GetNumFailRealms() const { return NumFailRealms; }
- ui32 GetNumFailDomainsPerFailRealm() const { return NumFailDomainsPerFailRealm; }
- ui32 GetNumVDisksPerFailDomain() const { return NumVDisksPerFailDomain; }
- ui32 GetRealmLevelBegin() const { return RealmLevelBegin; }
- ui32 GetRealmLevelEnd() const { return RealmLevelEnd; }
- ui32 GetDomainLevelBegin() const { return DomainLevelBegin; }
- ui32 GetDomainLevelEnd() const { return DomainLevelEnd; }
-
- void AllocateGroup(TGroupMapper &mapper, TGroupId groupId, TGroupMapper::TGroupDefinition &group,
- const TPDiskId replacedDiskIds[], size_t numReplacedDisks, TGroupMapper::TForbiddenPDisks forbid,
- i64 requiredSpace) const {
- TString error;
- for (const bool requireOperational : {true, false}) {
+ ui32 GetNumFailRealms() const { return NumFailRealms; }
+ ui32 GetNumFailDomainsPerFailRealm() const { return NumFailDomainsPerFailRealm; }
+ ui32 GetNumVDisksPerFailDomain() const { return NumVDisksPerFailDomain; }
+ ui32 GetRealmLevelBegin() const { return RealmLevelBegin; }
+ ui32 GetRealmLevelEnd() const { return RealmLevelEnd; }
+ ui32 GetDomainLevelBegin() const { return DomainLevelBegin; }
+ ui32 GetDomainLevelEnd() const { return DomainLevelEnd; }
+
+ void AllocateGroup(TGroupMapper &mapper, TGroupId groupId, TGroupMapper::TGroupDefinition &group,
+ const TPDiskId replacedDiskIds[], size_t numReplacedDisks, TGroupMapper::TForbiddenPDisks forbid,
+ i64 requiredSpace) const {
+ TString error;
+ for (const bool requireOperational : {true, false}) {
if (mapper.AllocateGroup(groupId, group, replacedDiskIds, numReplacedDisks, forbid,
- requiredSpace, requireOperational, error)) {
- return;
- }
+ requiredSpace, requireOperational, error)) {
+ return;
+ }
}
- throw TExFitGroupError() << "failed to allocate group: " << error;
- }
+ throw TExFitGroupError() << "failed to allocate group: " << error;
+ }
- bool ResizeGroup(TGroupMapper::TGroupDefinition& group) const {
- if (!group) {
- group.resize(NumFailRealms);
+ bool ResizeGroup(TGroupMapper::TGroupDefinition& group) const {
+ if (!group) {
+ group.resize(NumFailRealms);
for (auto &realm : group) {
- realm.resize(NumFailDomainsPerFailRealm);
+ realm.resize(NumFailDomainsPerFailRealm);
for (auto &domain : realm) {
- domain.resize(NumVDisksPerFailDomain);
+ domain.resize(NumVDisksPerFailDomain);
}
}
- } else {
- bool ok = group.size() == NumFailRealms;
- if (ok) {
- for (const auto& realm : group) {
- ok = realm.size() == NumFailDomainsPerFailRealm;
- if (ok) {
- for (const auto& domain : realm) {
- ok = domain.size() == NumVDisksPerFailDomain;
- if (!ok) {
- break;
- }
- }
- }
- if (!ok) {
- break;
- }
- }
- }
- if (!ok) {
- return false;
- }
+ } else {
+ bool ok = group.size() == NumFailRealms;
+ if (ok) {
+ for (const auto& realm : group) {
+ ok = realm.size() == NumFailDomainsPerFailRealm;
+ if (ok) {
+ for (const auto& domain : realm) {
+ ok = domain.size() == NumVDisksPerFailDomain;
+ if (!ok) {
+ break;
+ }
+ }
+ }
+ if (!ok) {
+ break;
+ }
+ }
+ }
+ if (!ok) {
+ return false;
+ }
}
- return true;
- }
+ return true;
+ }
- TBlobStorageGroupType::EErasureSpecies GetErasure() const {
- return Type.GetErasure();
- }
- };
+ TBlobStorageGroupType::EErasureSpecies GetErasure() const {
+ return Type.GetErasure();
+ }
+ };
-} // NKikimr::NBsController
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/group_mapper.cpp b/ydb/core/mind/bscontroller/group_mapper.cpp
index 84b5ac6d7a8..196969b3c15 100644
--- a/ydb/core/mind/bscontroller/group_mapper.cpp
+++ b/ydb/core/mind/bscontroller/group_mapper.cpp
@@ -1,793 +1,793 @@
-#include "group_mapper.h"
-#include "group_geometry_info.h"
-
-namespace NKikimr::NBsController {
-
- class TGroupMapper::TImpl : TNonCopyable {
- class TDomainMapper {
- std::unordered_map<TString, ui32> FailDomainId;
-
- public:
- ui32 operator ()(TString item) {
- return FailDomainId.emplace(std::move(item), FailDomainId.size() + 1).first->second;
- }
- };
-
- struct TPDiskLayoutPosition {
- ui32 RealmGroup = 0;
- ui32 RealmInGroup = 0;
- ui32 DomainGroup = 0;
- ui32 DomainInGroup = 0;
-
- TPDiskLayoutPosition() = default;
-
- TPDiskLayoutPosition(TDomainMapper& mapper, const TNodeLocation& location, TPDiskId pdiskId, const TGroupGeometryInfo& geom) {
- TStringStream realmGroup, realmInGroup, domainGroup, domainInGroup;
- const std::pair<int, TStringStream*> levels[] = {
- {geom.GetRealmLevelBegin(), &realmGroup},
- {geom.GetRealmLevelEnd(), &realmInGroup},
- {geom.GetDomainLevelBegin(), &domainGroup},
- {geom.GetDomainLevelEnd(), &domainInGroup}
- };
- auto addLevel = [&](int key, const TString& value) {
- for (const auto& [reference, stream] : levels) {
- if (key < reference) {
- Save(stream, std::make_tuple(key, value));
- }
- }
- };
- for (const auto& [key, value] : location.GetItems()) {
- addLevel(key, value);
- }
- addLevel(255, pdiskId.ToString()); // ephemeral level to distinguish between PDisks on the same node
- RealmGroup = mapper(realmGroup.Str());
- RealmInGroup = mapper(realmInGroup.Str());
- DomainGroup = mapper(domainGroup.Str());
- DomainInGroup = mapper(domainInGroup.Str());
- }
-
- auto AsTuple() const {
- return std::tie(RealmGroup, RealmInGroup, DomainGroup, DomainInGroup);
- }
-
- friend bool operator <(const TPDiskLayoutPosition& x, const TPDiskLayoutPosition& y) {
- return x.AsTuple() < y.AsTuple();
- }
-
- size_t GetDiffIndex(const TPDiskLayoutPosition& other) const {
- return RealmGroup != other.RealmGroup ? 0 :
- RealmInGroup != other.RealmInGroup ? 1 :
- DomainGroup != other.DomainGroup ? 2 :
- DomainInGroup != other.DomainInGroup ? 3 : 4;
- }
- };
-
- struct TFailDomainInfo;
-
- struct TPDiskInfo {
- const TNodeLocation Location;
- i64 SpaceAvailable;
- bool Usable;
- ui32 NumSlots;
- const ui32 MaxSlots;
- TPDiskLayoutPosition Position;
- const TPDiskId PDiskId;
- TStackVec<ui32, 32> Groups;
- const bool Operational;
- TFailDomainInfo *FailDomain;
- bool Matching = false;
-
- TPDiskInfo(TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots, TPDiskLayoutPosition position,
- const TPDiskId& pdiskId, const ui32 groupIds[], size_t numGroups, i64 spaceAvailable,
- bool operational, TFailDomainInfo *failDomain)
- : Location(std::move(location))
- , SpaceAvailable(spaceAvailable)
- , Usable(usable)
- , NumSlots(numSlots)
- , MaxSlots(maxSlots)
- , Position(std::move(position))
- , PDiskId(pdiskId)
- , Groups(groupIds, groupIds + numGroups)
- , Operational(operational)
- , FailDomain(failDomain)
- {
- std::sort(Groups.begin(), Groups.end());
- }
-
- TString ToString() const {
- return Location.ToString();
- }
-
- bool IsUsable() const {
- return Usable && NumSlots < MaxSlots;
- }
-
- void InsertGroup(ui32 groupId) {
- if (const auto it = std::lower_bound(Groups.begin(), Groups.end(), groupId); it == Groups.end() || *it < groupId) {
- Groups.insert(it, groupId);
- }
- }
-
- void EraseGroup(ui32 groupId) {
- if (const auto it = std::lower_bound(Groups.begin(), Groups.end(), groupId); it != Groups.end() && !(*it < groupId)) {
- Groups.erase(it);
- }
- }
-
- ui32 GetPickerScore() const {
- return NumSlots;
- }
- };
-
- using TPDisks = THashMap<TPDiskId, TPDiskInfo>;
-
- struct TFailDomainInfo : std::vector<TPDisks::value_type*> {
- bool Matching;
- ui32 NumMatchingDisks;
- };
-
- struct TFailDomainGroup : std::unordered_map<ui32, TFailDomainInfo> {
- bool Matching;
- };
-
- struct TFailRealmInfo : std::unordered_map<ui32, TFailDomainGroup> {
- bool Matching;
- };
-
- struct TFailRealmGroup : std::unordered_map<ui32, TFailRealmInfo> {
- bool Matching;
- };
-
- struct TBox : std::unordered_map<ui32, TFailRealmGroup> {
- auto& operator ()(const TPDiskLayoutPosition& p) {
- return (*this)[p.RealmGroup][p.RealmInGroup][p.DomainGroup][p.DomainInGroup];
- }
- };
-
- struct TAllocateContext {
- const ui32 NumFailRealms;
- const ui32 NumFailDomainsPerFailRealm;
- ui32 RealmGroup = 0; // the realm group we are forced to use (if forced, of course)
- TStackVec<ui32, 8> RealmInGroup; // indexed by realm number
- TStackVec<ui32, 8> DomainGroup; // indexed by realm number
- TStackVec<ui32, 32> DomainInGroup; // indexed by realm/domain
- THashSet<TPDiskId> OldGroupContent; // set of all existing disks in the group, inclusing ones which are replaced
- THashSet<TPDiskId> NewGroupContent; // newly generated group content
- const i64 RequiredSpace;
- const bool RequireOperational;
- TForbiddenPDisks Forbid;
-
- TAllocateContext(const TGroupGeometryInfo& geom, i64 requiredSpace, bool requireOperational,
- TForbiddenPDisks forbid)
- : NumFailRealms(geom.GetNumFailRealms())
- , NumFailDomainsPerFailRealm(geom.GetNumFailDomainsPerFailRealm())
- , RealmInGroup(NumFailRealms, 0)
- , DomainGroup(NumFailRealms, 0)
- , DomainInGroup(NumFailRealms * NumFailDomainsPerFailRealm, 0)
- , RequiredSpace(requiredSpace)
- , RequireOperational(requireOperational)
- , Forbid(std::move(forbid))
- {}
-
- bool ProcessExistingGroup(const TGroupDefinition& group, const TPDisks& pdisks, const TPDiskId replacedDiskIds[],
- size_t numReplacedDisks, TString& error) {
- OldGroupContent = {replacedDiskIds, replacedDiskIds + numReplacedDisks};
-
- for (ui32 failRealmIdx = 0, domainThroughIdx = 0; failRealmIdx < group.size(); ++failRealmIdx) {
- const auto& realm = group[failRealmIdx];
- for (ui32 failDomainIdx = 0; failDomainIdx < realm.size(); ++failDomainIdx, ++domainThroughIdx) {
- const auto& domain = realm[failDomainIdx];
- for (const TPDiskId pdiskId : domain) {
- if (pdiskId != TPDiskId()) {
- // add to used pdisk set
- const bool inserted = OldGroupContent.insert(pdiskId).second;
- Y_VERIFY(inserted);
-
- // find existing pdisk
- auto it = pdisks.find(pdiskId);
- if (it == pdisks.end()) {
- error = TStringBuilder() << "existing group contains missing PDisks";
- return false;
- }
- const TPDiskInfo& pdisk = it->second;
-
- // register the disk in context
- if (!AddDisk(pdisk, failRealmIdx, domainThroughIdx, error)) {
- return false;
- }
- }
- }
- }
- }
- return true;
- }
-
- bool AddDisk(const TPDiskInfo& pdisk, ui32 failRealmIdx, ui32 domainThroughIdx, TString& error) {
- auto update = [](ui32& place, ui32 value) {
- const ui32 prev = std::exchange(place, value);
- return !prev || prev == value;
- };
- if (!update(RealmGroup, pdisk.Position.RealmGroup)) {
- error = "group contains PDisks from different realm groups";
- } else if (!update(RealmInGroup[failRealmIdx], pdisk.Position.RealmInGroup)) {
- error = "group contains PDisks from different realms within same realm";
- } else if (!update(DomainGroup[failRealmIdx], pdisk.Position.DomainGroup)) {
- error = "group contains PDisks from different domain groups within same realm";
- } else if (!update(DomainInGroup[domainThroughIdx], pdisk.Position.DomainInGroup)) {
- error = "group contains PDisks from different domain groups within same realm";
- } else if (!NewGroupContent.insert(pdisk.PDiskId).second) {
- error = "group contains duplicate PDisks";
- } else {
- return true;
- }
- return false;
- }
-
- bool DiskIsUsable(const TPDiskInfo& pdisk) const {
- if (!pdisk.IsUsable()) {
- return false; // disk is not usable in this case
- }
- if (OldGroupContent.count(pdisk.PDiskId) || NewGroupContent.count(pdisk.PDiskId) || Forbid.count(pdisk.PDiskId)) {
- return false; // can't allow duplicate disks
- }
- if (RequireOperational && !pdisk.Operational) {
- return false;
- }
- return pdisk.SpaceAvailable >= RequiredSpace;
- }
- };
-
- class THelper {
- TImpl& Self;
- TAllocateContext& Ctx;
- std::unordered_map<ui32, unsigned> LocalityFactor;
-
- public:
- THelper(TImpl& self, TAllocateContext& ctx)
- : Self(self)
- , Ctx(ctx)
- {
- for (const TPDiskId& pdiskId : Ctx.NewGroupContent) {
- if (const auto it = Self.PDisks.find(pdiskId); it != Self.PDisks.end()) {
- for (ui32 groupId : it->second.Groups) {
- ++LocalityFactor[groupId];
- }
- } else {
- Y_FAIL();
- }
- }
- if (const ui32 id = Ctx.RealmGroup) {
- auto& realmGroup = Self.Box.at(id);
- Y_VERIFY_DEBUG(realmGroup.Matching);
- realmGroup.Matching = false;
- for (size_t i = 0; i < Ctx.NumFailRealms; ++i) {
- if (const ui32 id = Ctx.RealmInGroup[i]) {
- auto& realm = realmGroup.at(id);
- Y_VERIFY_DEBUG(realm.Matching);
- realm.Matching = false;
- if (const ui32 id = Ctx.DomainGroup[i]) {
- auto& domainGroup = realm.at(id);
- Y_VERIFY_DEBUG(domainGroup.Matching);
- domainGroup.Matching = false;
- for (size_t j = 0; j < Ctx.NumFailDomainsPerFailRealm; ++j) {
- const size_t domainThroughIdx = i * Ctx.NumFailDomainsPerFailRealm + j;
- if (const ui32 id = Ctx.DomainInGroup[domainThroughIdx]) {
- auto& domain = domainGroup.at(id);
- Y_VERIFY_DEBUG(domain.Matching);
- domain.Matching = false;
- }
- }
- }
- }
- }
- }
- }
-
- TPDiskId AddBestDisk(ui32 realmIdx, ui32 domainThroughIdx) {
- TPDiskInfo *pdisk = nullptr;
- auto descend = [&](auto& level, ui32& id, ui32 TPDiskLayoutPosition::*pos) -> auto& {
- if (!id) {
- pdisk = pdisk ? pdisk : FindBestDisk(level);
- id = pdisk->Position.*pos;
- level[id].Matching = false; // do not allow this level for further selection
- } else if (pdisk) {
- Y_VERIFY(id == pdisk->Position.*pos);
- }
- return level[id];
- };
- auto& realmGroup = descend(Self.Box, Ctx.RealmGroup, &TPDiskLayoutPosition::RealmGroup);
- auto& realm = descend(realmGroup, Ctx.RealmInGroup[realmIdx], &TPDiskLayoutPosition::RealmInGroup);
- auto& domainGroup = descend(realm, Ctx.DomainGroup[realmIdx], &TPDiskLayoutPosition::DomainGroup);
- auto& domain = descend(domainGroup, Ctx.DomainInGroup[domainThroughIdx], &TPDiskLayoutPosition::DomainInGroup);
- pdisk = pdisk ? pdisk : FindBestDisk(domain);
-
- TString error;
- const bool success = Ctx.AddDisk(*pdisk, realmIdx, domainThroughIdx, error);
- Y_VERIFY(success, "AddDisk: %s", error.data());
- pdisk->Matching = false; // disable this disk for further selection
-
- AddUsedDisk(*pdisk);
-
- return pdisk->PDiskId;
- }
-
- private:
- template<typename T>
- TPDiskInfo *FindBestDisk(T& level) {
- TPDiskInfo *res = nullptr;
- for (auto& [id, item] : level) {
- if (item.Matching) {
- TPDiskInfo *candidate = FindBestDisk(item);
- Y_VERIFY(candidate);
- res = !res || DiskIsBetter(*candidate, *res) ? candidate : res;
- }
- }
- Y_VERIFY(res);
- return res;
- }
-
- TPDiskInfo *FindBestDisk(TFailDomainInfo& level) {
- TPDiskInfo *res = nullptr;
- for (TPDisks::value_type *it : level) {
- auto& [pdiskId, pdisk] = *it;
- if (pdisk.Matching) {
- res = !res || DiskIsBetter(pdisk, *res) ? &pdisk : res;
- }
- }
- Y_VERIFY(res);
- return res;
- }
-
- bool DiskIsBetter(TPDiskInfo& pretender, TPDiskInfo& king) const {
- if (pretender.NumSlots != king.NumSlots) {
- return pretender.NumSlots < king.NumSlots;
- } else if (GivesLocalityBoost(pretender, king) || BetterQuotaMatch(pretender, king)) {
- return true;
- } else {
- const TFailDomainInfo& pretenderDomain = Self.Box(pretender.Position);
- const TFailDomainInfo& kingDomain = Self.Box(king.Position);
- if (pretenderDomain.NumMatchingDisks != kingDomain.NumMatchingDisks) {
- return pretenderDomain.NumMatchingDisks > kingDomain.NumMatchingDisks;
- }
- return pretender.PDiskId < king.PDiskId;
- }
- }
-
- bool GivesLocalityBoost(TPDiskInfo& pretender, TPDiskInfo& king) const {
- const ui32 a = GetLocalityFactor(pretender);
- const ui32 b = GetLocalityFactor(king);
- return Self.Randomize ? a < b : a > b;
- }
-
- bool BetterQuotaMatch(TPDiskInfo& pretender, TPDiskInfo& king) const {
- return pretender.SpaceAvailable < king.SpaceAvailable;
- }
-
- void AddUsedDisk(const TPDiskInfo& pdisk) {
- for (ui32 groupId : pdisk.Groups) {
- ++LocalityFactor[groupId];
- }
- }
-
- unsigned GetLocalityFactor(const TPDiskInfo& pdisk) const {
- unsigned res = 0;
- for (ui32 groupId : pdisk.Groups) {
- res += GetLocalityFactor(groupId);
- }
- return res;
- }
-
- unsigned GetLocalityFactor(ui32 groupId) const {
- const auto it = LocalityFactor.find(groupId);
- return it != LocalityFactor.end() ? it->second : 0;
- }
- };
-
- private:
- const TGroupGeometryInfo Geom;
- const bool Randomize;
- TDomainMapper DomainMapper;
- TPDisks PDisks;
- TBox Box;
-
- public:
- TImpl(TGroupGeometryInfo geom, bool randomize)
- : Geom(std::move(geom))
- , Randomize(randomize)
- {}
-
- bool RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
- const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational) {
- // calculate disk position
- const TPDiskLayoutPosition p(DomainMapper, location, pdiskId, Geom);
-
- // insert PDisk into specific map
- TPDisks::iterator it;
- bool inserted;
- std::tie(it, inserted) = PDisks.try_emplace(pdiskId, std::move(location), usable, numSlots, maxSlots,
- p, pdiskId, groupIds, numGroups, spaceAvailable, operational, &Box(p));
- if (inserted) {
- it->second.FailDomain->push_back(&*it);
- }
-
- return inserted;
- }
-
- void UnregisterPDisk(TPDiskId pdiskId) {
- const auto it = PDisks.find(pdiskId);
- Y_VERIFY(it != PDisks.end());
- TFailDomainInfo& fdom = *it->second.FailDomain;
- bool erased = false;
- for (auto x = fdom.begin(); x != fdom.end(); ++x) {
- if (*x == &*it) {
- fdom.erase(x);
- erased = true;
- break;
- }
- }
- Y_VERIFY(erased);
- PDisks.erase(it);
- }
-
- void AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment) {
- const auto it = PDisks.find(pdiskId);
- Y_VERIFY(it != PDisks.end());
- it->second.SpaceAvailable += increment;
- }
-
- TString FormatPDisks(const TAllocateContext& ctx) const {
- TStringStream s;
- s << "PDisks# ";
-
- bool first1 = true;
- for (const auto& [id, realmGroup] : Box) {
- s << (std::exchange(first1, false) ? "" : " | ") << "<";
- bool first2 = true;
- for (const auto& [id, realm] : realmGroup) {
- s << (std::exchange(first2, false) ? "" : " ") << "{";
- bool first3 = true;
- for (const auto& [id, domainGroup] : realm) {
- s << (std::exchange(first3, false) ? "" : " | ") << "[";
- bool first4 = true;
- for (const auto& [id, domain] : domainGroup) {
- if (!domain.empty()) {
- s << (std::exchange(first4, false) ? "" : " ") << "(";
- std::vector<TPDisks::value_type*> v(domain);
- auto comp = [](const auto *x, const auto *y) { return x->first < y->first; };
- std::sort(v.begin(), v.end(), comp);
- bool first5 = true;
- for (const TPDisks::value_type *it : v) {
- s << (std::exchange(first5, false) ? "" : " ")
- << it->first.NodeId << ":" << it->first.PDiskId;
- if (ctx.OldGroupContent.count(it->first)) {
- s << "*";
- }
- const char *minus = "-";
- if (ctx.Forbid.count(it->second.PDiskId)) {
- s << std::exchange(minus, "") << "f";
- }
- if (!it->second.Usable) {
- s << std::exchange(minus, "") << "u";
- }
- if (it->second.NumSlots >= it->second.MaxSlots) {
- s << std::exchange(minus, "") << "m";
- }
- if (it->second.NumSlots >= it->second.MaxSlots) {
- s << std::exchange(minus, "") << "s";
- }
- if (it->second.SpaceAvailable < ctx.RequiredSpace) {
- s << std::exchange(minus, "") << "v";
- }
- if (!it->second.Operational) {
- s << std::exchange(minus, "") << "o";
- }
- if (ctx.DiskIsUsable(it->second)) {
- s << "+";
- }
- }
- s << ")";
- }
- }
- s << "]";
- }
- s << "}";
- }
- s << ">";
- }
-
- return s.Str();
- }
-
- bool AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
- size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational,
- TString& error) {
- // fill in the allocation context
- TAllocateContext ctx(Geom, requiredSpace, requireOperational, std::move(forbid));
- if (!ctx.ProcessExistingGroup(group, PDisks, replacedDiskIds, numReplacedDisks, error)) {
- return false;
- }
-
- // create group of required size, if it is not created yet
- if (!Geom.ResizeGroup(group)) {
- error = "incorrect existing group";
- return false;
- }
-
- // if the group is already created, check for missing entities
- bool hasMissingEntities = false;
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const TPDiskId& pdiskId : domain) {
- if (pdiskId == TPDiskId()) {
- hasMissingEntities = true;
- break;
- }
- }
- if (hasMissingEntities) {
- break;
- }
- }
- if (hasMissingEntities) {
- break;
- }
- }
- if (!hasMissingEntities) {
- return true; // group is okay
- }
-
- // adjust number of slots
- for (TPDiskId pdiskId : ctx.OldGroupContent) {
- --PDisks.at(pdiskId).NumSlots;
- }
- for (size_t i = 0; i < numReplacedDisks; ++i) {
- PDisks.at(replacedDiskIds[i]).EraseGroup(groupId);
- }
-
- // check if we can map a group only with PDisks that have NumSlots <= nums
- if (!FindMatchingDisks(ctx)) {
- // undo changes to the mapper content
- for (TPDiskId pdiskId : ctx.OldGroupContent) {
- ++PDisks.at(pdiskId).NumSlots;
- }
- for (size_t i = 0; i < numReplacedDisks; ++i) {
- PDisks.at(replacedDiskIds[i]).InsertGroup(groupId);
- }
- error = "no group options " + FormatPDisks(ctx);
- return false;
- }
-
- // fill in missing PDisk entities
- THelper helper(*this, ctx);
- for (ui32 realmIdx = 0, domainThroughIdx = 0; realmIdx < ctx.NumFailRealms; ++realmIdx) {
- for (ui32 domainIdx = 0; domainIdx < ctx.NumFailDomainsPerFailRealm; ++domainIdx, ++domainThroughIdx) {
- for (TPDiskId& pdiskId : group[realmIdx][domainIdx]) {
- if (pdiskId == TPDiskId()) {
- pdiskId = helper.AddBestDisk(realmIdx, domainThroughIdx);
- }
- }
- }
- }
-
- // adjust number of slots
- for (TPDiskId pdiskId : ctx.NewGroupContent) {
- if (const auto it = PDisks.find(pdiskId); it != PDisks.end()) {
- ++it->second.NumSlots;
- it->second.InsertGroup(groupId);
- } else {
- Y_FAIL();
- }
- }
-
- return true;
- }
-
- class TScorePicker {
- static constexpr size_t MaxStaticItems = 16;
- ui32 NumFake = 0;
- TStackVec<ui32, MaxStaticItems> StaticHist;
- std::map<ui32, ui32> ScoreHist;
-
- public:
- static constexpr ui32 FakeScore = Max<ui32>();
-
- public:
- void AddFake() {
- ++NumFake;
- }
-
- void Add(ui32 score) {
- if (score < MaxStaticItems) {
- if (StaticHist.size() <= score) {
- StaticHist.resize(score + 1);
- }
- ++StaticHist[score];
- } else {
- ++ScoreHist[score];
- }
- }
-
- std::optional<ui32> CalculateMaxScore(ui32 threshold) const {
- if (threshold <= NumFake) {
- return FakeScore;
- } else {
- threshold -= NumFake;
- }
- for (size_t score = 0; score < StaticHist.size(); ++score) {
- if (threshold <= StaticHist[score]) {
- return score;
- } else {
- threshold -= StaticHist[score];
- }
- }
- for (const auto& [score, num] : ScoreHist) {
- if (threshold <= num) {
- return score;
- } else {
- threshold -= num;
- }
- }
- Y_VERIFY_DEBUG(threshold);
- return std::nullopt;
- }
-
- void Cascade(TScorePicker& parent, ui32 threshold) {
- if (std::optional<ui32> maxScore = CalculateMaxScore(threshold)) {
- if (*maxScore != FakeScore) {
- parent.Add(*maxScore);
- } else {
- parent.AddFake();
- }
- }
- }
- };
-
- bool FindMatchingDisks(const TAllocateContext& ctx) {
- struct TMatchingDisk {
- TPDiskInfo *PDisk;
- bool IsInGroup;
- ui32 Score = 0;
-
- TPDiskInfo *operator ->() const { return PDisk; }
- bool operator <(const TMatchingDisk& other) const { return PDisk->Position < other->Position; }
- };
-
- TScorePicker realmGroupPicker;
- std::vector<TMatchingDisk> matchingDisks;
- for (auto& [id, realmGroup] : Box) {
- TScorePicker realmPicker;
- realmGroup.Matching = false;
- for (auto& [id, realm] : realmGroup) {
- TScorePicker domainGroupPicker;
- realm.Matching = false;
- for (auto& [id, domainGroup] : realm) {
- TScorePicker domainPicker;
- domainGroup.Matching = false;
- for (auto& [id, domain] : domainGroup) {
- TScorePicker diskPicker;
- domain.Matching = false;
- domain.NumMatchingDisks = 0;
- for (TPDisks::value_type *it : domain) {
- auto& [pdiskId, pdisk] = *it;
- pdisk.Matching = ctx.DiskIsUsable(pdisk);
- if (pdisk.Matching) {
- const ui32 score = pdisk.GetPickerScore();
- matchingDisks.push_back(TMatchingDisk{&pdisk, false, score});
- diskPicker.Add(score);
- } else if (ctx.NewGroupContent.count(pdiskId)) {
- // we create a fake record to keep correct count of fail realms and domains, but
- // this particular one never gets selected
- matchingDisks.push_back(TMatchingDisk{&pdisk, true});
- diskPicker.AddFake();
- }
- }
- diskPicker.Cascade(domainPicker, Geom.GetNumVDisksPerFailDomain());
- }
- domainPicker.Cascade(domainGroupPicker, Geom.GetNumFailDomainsPerFailRealm());
- }
- domainGroupPicker.Cascade(realmPicker, 1);
- }
- realmPicker.Cascade(realmGroupPicker, Geom.GetNumFailRealms());
- }
-
- bool boxMatching = false;
-
- if (const std::optional<ui32> maxScore = realmGroupPicker.CalculateMaxScore(1)) {
- Y_VERIFY_DEBUG(*maxScore != TScorePicker::FakeScore);
-
- // remove all mismatched candidate disks and sort them according to their position
- auto remove = [maxScore = *maxScore](const TMatchingDisk& p) {
- p->Matching = p->Matching && p.Score <= maxScore;
- return !p->Matching && !p.IsInGroup;
- };
- const auto begin = matchingDisks.begin();
- const auto end = matchingDisks.end();
- matchingDisks.erase(std::remove_if(begin, end, remove), end);
- std::sort(matchingDisks.begin(), matchingDisks.end());
-
- std::optional<TPDiskLayoutPosition> prev;
-
- ui32 numMatchingRealmGroupsInBox = 0;
- ui32 numMatchingRealmsInRealmGroup = 0;
- ui32 numMatchingDomainGroupsInRealm = 0;
- ui32 numMatchingDomainsInDomainGroup = 0;
- ui32 numMatchingDisksInDomain = 0;
-
- TFailRealmGroup *realmGroup = nullptr;
- TFailRealmInfo *realm = nullptr;
- TFailDomainGroup *domainGroup = nullptr;
- TFailDomainInfo *domain = nullptr;
-
- for (const auto& disk : matchingDisks) {
- const auto& cur = disk->Position;
- switch (prev ? prev->GetDiffIndex(cur) : 0) {
- case 0:
- numMatchingRealmsInRealmGroup = 0;
- realmGroup = &Box[cur.RealmGroup];
- [[fallthrough]];
- case 1:
- numMatchingDomainGroupsInRealm = 0;
- realm = &(*realmGroup)[cur.RealmInGroup];
- [[fallthrough]];
- case 2:
- numMatchingDomainsInDomainGroup = 0;
- domainGroup = &(*realm)[cur.DomainGroup];
- [[fallthrough]];
- case 3:
- numMatchingDisksInDomain = 0;
- domain = &(*domainGroup)[cur.DomainInGroup];
- prev = cur;
- [[fallthrough]];
- case 4:
- break;
- }
-
- ++domain->NumMatchingDisks;
- const std::tuple<ui32&, ui32, bool&> items[] = {
- {numMatchingDisksInDomain, Geom.GetNumVDisksPerFailDomain(), domain->Matching },
- {numMatchingDomainsInDomainGroup, Geom.GetNumFailDomainsPerFailRealm(), domainGroup->Matching},
- {numMatchingDomainGroupsInRealm, 1, realm->Matching },
- {numMatchingRealmsInRealmGroup, Geom.GetNumFailRealms(), realmGroup->Matching },
- {numMatchingRealmGroupsInBox, 1, boxMatching },
- };
- for (const auto& item : items) {
- if (++std::get<0>(item) == std::get<1>(item)) {
- std::get<2>(item) = true;
- } else {
- break;
- }
- }
- }
- Y_VERIFY(boxMatching);
- }
-
- return boxMatching;
- }
- };
-
- TGroupMapper::TGroupMapper(TGroupGeometryInfo geom, bool randomize)
- : Impl(new TImpl(std::move(geom), randomize))
- {}
-
- TGroupMapper::~TGroupMapper() = default;
-
- bool TGroupMapper::RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
- const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational) {
- return Impl->RegisterPDisk(pdiskId, std::move(location), usable, numSlots, maxSlots, groupIds, numGroups,
- spaceAvailable, operational);
- }
-
- void TGroupMapper::UnregisterPDisk(TPDiskId pdiskId) {
- return Impl->UnregisterPDisk(pdiskId);
- }
-
- void TGroupMapper::AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment) {
- return Impl->AdjustSpaceAvailable(pdiskId, increment);
- }
-
- bool TGroupMapper::AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
- size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational, TString& error) {
- return Impl->AllocateGroup(groupId, group, replacedDiskIds, numReplacedDisks, std::move(forbid),
- requiredSpace, requireOperational, error);
- }
-
-} // NKikimr::NBsController
+#include "group_mapper.h"
+#include "group_geometry_info.h"
+
+namespace NKikimr::NBsController {
+
+ class TGroupMapper::TImpl : TNonCopyable {
+ class TDomainMapper {
+ std::unordered_map<TString, ui32> FailDomainId;
+
+ public:
+ ui32 operator ()(TString item) {
+ return FailDomainId.emplace(std::move(item), FailDomainId.size() + 1).first->second;
+ }
+ };
+
+ struct TPDiskLayoutPosition {
+ ui32 RealmGroup = 0;
+ ui32 RealmInGroup = 0;
+ ui32 DomainGroup = 0;
+ ui32 DomainInGroup = 0;
+
+ TPDiskLayoutPosition() = default;
+
+ TPDiskLayoutPosition(TDomainMapper& mapper, const TNodeLocation& location, TPDiskId pdiskId, const TGroupGeometryInfo& geom) {
+ TStringStream realmGroup, realmInGroup, domainGroup, domainInGroup;
+ const std::pair<int, TStringStream*> levels[] = {
+ {geom.GetRealmLevelBegin(), &realmGroup},
+ {geom.GetRealmLevelEnd(), &realmInGroup},
+ {geom.GetDomainLevelBegin(), &domainGroup},
+ {geom.GetDomainLevelEnd(), &domainInGroup}
+ };
+ auto addLevel = [&](int key, const TString& value) {
+ for (const auto& [reference, stream] : levels) {
+ if (key < reference) {
+ Save(stream, std::make_tuple(key, value));
+ }
+ }
+ };
+ for (const auto& [key, value] : location.GetItems()) {
+ addLevel(key, value);
+ }
+ addLevel(255, pdiskId.ToString()); // ephemeral level to distinguish between PDisks on the same node
+ RealmGroup = mapper(realmGroup.Str());
+ RealmInGroup = mapper(realmInGroup.Str());
+ DomainGroup = mapper(domainGroup.Str());
+ DomainInGroup = mapper(domainInGroup.Str());
+ }
+
+ auto AsTuple() const {
+ return std::tie(RealmGroup, RealmInGroup, DomainGroup, DomainInGroup);
+ }
+
+ friend bool operator <(const TPDiskLayoutPosition& x, const TPDiskLayoutPosition& y) {
+ return x.AsTuple() < y.AsTuple();
+ }
+
+ size_t GetDiffIndex(const TPDiskLayoutPosition& other) const {
+ return RealmGroup != other.RealmGroup ? 0 :
+ RealmInGroup != other.RealmInGroup ? 1 :
+ DomainGroup != other.DomainGroup ? 2 :
+ DomainInGroup != other.DomainInGroup ? 3 : 4;
+ }
+ };
+
+ struct TFailDomainInfo;
+
+ struct TPDiskInfo {
+ const TNodeLocation Location;
+ i64 SpaceAvailable;
+ bool Usable;
+ ui32 NumSlots;
+ const ui32 MaxSlots;
+ TPDiskLayoutPosition Position;
+ const TPDiskId PDiskId;
+ TStackVec<ui32, 32> Groups;
+ const bool Operational;
+ TFailDomainInfo *FailDomain;
+ bool Matching = false;
+
+ TPDiskInfo(TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots, TPDiskLayoutPosition position,
+ const TPDiskId& pdiskId, const ui32 groupIds[], size_t numGroups, i64 spaceAvailable,
+ bool operational, TFailDomainInfo *failDomain)
+ : Location(std::move(location))
+ , SpaceAvailable(spaceAvailable)
+ , Usable(usable)
+ , NumSlots(numSlots)
+ , MaxSlots(maxSlots)
+ , Position(std::move(position))
+ , PDiskId(pdiskId)
+ , Groups(groupIds, groupIds + numGroups)
+ , Operational(operational)
+ , FailDomain(failDomain)
+ {
+ std::sort(Groups.begin(), Groups.end());
+ }
+
+ TString ToString() const {
+ return Location.ToString();
+ }
+
+ bool IsUsable() const {
+ return Usable && NumSlots < MaxSlots;
+ }
+
+ void InsertGroup(ui32 groupId) {
+ if (const auto it = std::lower_bound(Groups.begin(), Groups.end(), groupId); it == Groups.end() || *it < groupId) {
+ Groups.insert(it, groupId);
+ }
+ }
+
+ void EraseGroup(ui32 groupId) {
+ if (const auto it = std::lower_bound(Groups.begin(), Groups.end(), groupId); it != Groups.end() && !(*it < groupId)) {
+ Groups.erase(it);
+ }
+ }
+
+ ui32 GetPickerScore() const {
+ return NumSlots;
+ }
+ };
+
+ using TPDisks = THashMap<TPDiskId, TPDiskInfo>;
+
+ struct TFailDomainInfo : std::vector<TPDisks::value_type*> {
+ bool Matching;
+ ui32 NumMatchingDisks;
+ };
+
+ struct TFailDomainGroup : std::unordered_map<ui32, TFailDomainInfo> {
+ bool Matching;
+ };
+
+ struct TFailRealmInfo : std::unordered_map<ui32, TFailDomainGroup> {
+ bool Matching;
+ };
+
+ struct TFailRealmGroup : std::unordered_map<ui32, TFailRealmInfo> {
+ bool Matching;
+ };
+
+ struct TBox : std::unordered_map<ui32, TFailRealmGroup> {
+ auto& operator ()(const TPDiskLayoutPosition& p) {
+ return (*this)[p.RealmGroup][p.RealmInGroup][p.DomainGroup][p.DomainInGroup];
+ }
+ };
+
+ struct TAllocateContext {
+ const ui32 NumFailRealms;
+ const ui32 NumFailDomainsPerFailRealm;
+ ui32 RealmGroup = 0; // the realm group we are forced to use (if forced, of course)
+ TStackVec<ui32, 8> RealmInGroup; // indexed by realm number
+ TStackVec<ui32, 8> DomainGroup; // indexed by realm number
+ TStackVec<ui32, 32> DomainInGroup; // indexed by realm/domain
+ THashSet<TPDiskId> OldGroupContent; // set of all existing disks in the group, inclusing ones which are replaced
+ THashSet<TPDiskId> NewGroupContent; // newly generated group content
+ const i64 RequiredSpace;
+ const bool RequireOperational;
+ TForbiddenPDisks Forbid;
+
+ TAllocateContext(const TGroupGeometryInfo& geom, i64 requiredSpace, bool requireOperational,
+ TForbiddenPDisks forbid)
+ : NumFailRealms(geom.GetNumFailRealms())
+ , NumFailDomainsPerFailRealm(geom.GetNumFailDomainsPerFailRealm())
+ , RealmInGroup(NumFailRealms, 0)
+ , DomainGroup(NumFailRealms, 0)
+ , DomainInGroup(NumFailRealms * NumFailDomainsPerFailRealm, 0)
+ , RequiredSpace(requiredSpace)
+ , RequireOperational(requireOperational)
+ , Forbid(std::move(forbid))
+ {}
+
+ bool ProcessExistingGroup(const TGroupDefinition& group, const TPDisks& pdisks, const TPDiskId replacedDiskIds[],
+ size_t numReplacedDisks, TString& error) {
+ OldGroupContent = {replacedDiskIds, replacedDiskIds + numReplacedDisks};
+
+ for (ui32 failRealmIdx = 0, domainThroughIdx = 0; failRealmIdx < group.size(); ++failRealmIdx) {
+ const auto& realm = group[failRealmIdx];
+ for (ui32 failDomainIdx = 0; failDomainIdx < realm.size(); ++failDomainIdx, ++domainThroughIdx) {
+ const auto& domain = realm[failDomainIdx];
+ for (const TPDiskId pdiskId : domain) {
+ if (pdiskId != TPDiskId()) {
+ // add to used pdisk set
+ const bool inserted = OldGroupContent.insert(pdiskId).second;
+ Y_VERIFY(inserted);
+
+ // find existing pdisk
+ auto it = pdisks.find(pdiskId);
+ if (it == pdisks.end()) {
+ error = TStringBuilder() << "existing group contains missing PDisks";
+ return false;
+ }
+ const TPDiskInfo& pdisk = it->second;
+
+ // register the disk in context
+ if (!AddDisk(pdisk, failRealmIdx, domainThroughIdx, error)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ bool AddDisk(const TPDiskInfo& pdisk, ui32 failRealmIdx, ui32 domainThroughIdx, TString& error) {
+ auto update = [](ui32& place, ui32 value) {
+ const ui32 prev = std::exchange(place, value);
+ return !prev || prev == value;
+ };
+ if (!update(RealmGroup, pdisk.Position.RealmGroup)) {
+ error = "group contains PDisks from different realm groups";
+ } else if (!update(RealmInGroup[failRealmIdx], pdisk.Position.RealmInGroup)) {
+ error = "group contains PDisks from different realms within same realm";
+ } else if (!update(DomainGroup[failRealmIdx], pdisk.Position.DomainGroup)) {
+ error = "group contains PDisks from different domain groups within same realm";
+ } else if (!update(DomainInGroup[domainThroughIdx], pdisk.Position.DomainInGroup)) {
+ error = "group contains PDisks from different domain groups within same realm";
+ } else if (!NewGroupContent.insert(pdisk.PDiskId).second) {
+ error = "group contains duplicate PDisks";
+ } else {
+ return true;
+ }
+ return false;
+ }
+
+ bool DiskIsUsable(const TPDiskInfo& pdisk) const {
+ if (!pdisk.IsUsable()) {
+ return false; // disk is not usable in this case
+ }
+ if (OldGroupContent.count(pdisk.PDiskId) || NewGroupContent.count(pdisk.PDiskId) || Forbid.count(pdisk.PDiskId)) {
+ return false; // can't allow duplicate disks
+ }
+ if (RequireOperational && !pdisk.Operational) {
+ return false;
+ }
+ return pdisk.SpaceAvailable >= RequiredSpace;
+ }
+ };
+
+ class THelper {
+ TImpl& Self;
+ TAllocateContext& Ctx;
+ std::unordered_map<ui32, unsigned> LocalityFactor;
+
+ public:
+ THelper(TImpl& self, TAllocateContext& ctx)
+ : Self(self)
+ , Ctx(ctx)
+ {
+ for (const TPDiskId& pdiskId : Ctx.NewGroupContent) {
+ if (const auto it = Self.PDisks.find(pdiskId); it != Self.PDisks.end()) {
+ for (ui32 groupId : it->second.Groups) {
+ ++LocalityFactor[groupId];
+ }
+ } else {
+ Y_FAIL();
+ }
+ }
+ if (const ui32 id = Ctx.RealmGroup) {
+ auto& realmGroup = Self.Box.at(id);
+ Y_VERIFY_DEBUG(realmGroup.Matching);
+ realmGroup.Matching = false;
+ for (size_t i = 0; i < Ctx.NumFailRealms; ++i) {
+ if (const ui32 id = Ctx.RealmInGroup[i]) {
+ auto& realm = realmGroup.at(id);
+ Y_VERIFY_DEBUG(realm.Matching);
+ realm.Matching = false;
+ if (const ui32 id = Ctx.DomainGroup[i]) {
+ auto& domainGroup = realm.at(id);
+ Y_VERIFY_DEBUG(domainGroup.Matching);
+ domainGroup.Matching = false;
+ for (size_t j = 0; j < Ctx.NumFailDomainsPerFailRealm; ++j) {
+ const size_t domainThroughIdx = i * Ctx.NumFailDomainsPerFailRealm + j;
+ if (const ui32 id = Ctx.DomainInGroup[domainThroughIdx]) {
+ auto& domain = domainGroup.at(id);
+ Y_VERIFY_DEBUG(domain.Matching);
+ domain.Matching = false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ TPDiskId AddBestDisk(ui32 realmIdx, ui32 domainThroughIdx) {
+ TPDiskInfo *pdisk = nullptr;
+ auto descend = [&](auto& level, ui32& id, ui32 TPDiskLayoutPosition::*pos) -> auto& {
+ if (!id) {
+ pdisk = pdisk ? pdisk : FindBestDisk(level);
+ id = pdisk->Position.*pos;
+ level[id].Matching = false; // do not allow this level for further selection
+ } else if (pdisk) {
+ Y_VERIFY(id == pdisk->Position.*pos);
+ }
+ return level[id];
+ };
+ auto& realmGroup = descend(Self.Box, Ctx.RealmGroup, &TPDiskLayoutPosition::RealmGroup);
+ auto& realm = descend(realmGroup, Ctx.RealmInGroup[realmIdx], &TPDiskLayoutPosition::RealmInGroup);
+ auto& domainGroup = descend(realm, Ctx.DomainGroup[realmIdx], &TPDiskLayoutPosition::DomainGroup);
+ auto& domain = descend(domainGroup, Ctx.DomainInGroup[domainThroughIdx], &TPDiskLayoutPosition::DomainInGroup);
+ pdisk = pdisk ? pdisk : FindBestDisk(domain);
+
+ TString error;
+ const bool success = Ctx.AddDisk(*pdisk, realmIdx, domainThroughIdx, error);
+ Y_VERIFY(success, "AddDisk: %s", error.data());
+ pdisk->Matching = false; // disable this disk for further selection
+
+ AddUsedDisk(*pdisk);
+
+ return pdisk->PDiskId;
+ }
+
+ private:
+ template<typename T>
+ TPDiskInfo *FindBestDisk(T& level) {
+ TPDiskInfo *res = nullptr;
+ for (auto& [id, item] : level) {
+ if (item.Matching) {
+ TPDiskInfo *candidate = FindBestDisk(item);
+ Y_VERIFY(candidate);
+ res = !res || DiskIsBetter(*candidate, *res) ? candidate : res;
+ }
+ }
+ Y_VERIFY(res);
+ return res;
+ }
+
+ TPDiskInfo *FindBestDisk(TFailDomainInfo& level) {
+ TPDiskInfo *res = nullptr;
+ for (TPDisks::value_type *it : level) {
+ auto& [pdiskId, pdisk] = *it;
+ if (pdisk.Matching) {
+ res = !res || DiskIsBetter(pdisk, *res) ? &pdisk : res;
+ }
+ }
+ Y_VERIFY(res);
+ return res;
+ }
+
+ bool DiskIsBetter(TPDiskInfo& pretender, TPDiskInfo& king) const {
+ if (pretender.NumSlots != king.NumSlots) {
+ return pretender.NumSlots < king.NumSlots;
+ } else if (GivesLocalityBoost(pretender, king) || BetterQuotaMatch(pretender, king)) {
+ return true;
+ } else {
+ const TFailDomainInfo& pretenderDomain = Self.Box(pretender.Position);
+ const TFailDomainInfo& kingDomain = Self.Box(king.Position);
+ if (pretenderDomain.NumMatchingDisks != kingDomain.NumMatchingDisks) {
+ return pretenderDomain.NumMatchingDisks > kingDomain.NumMatchingDisks;
+ }
+ return pretender.PDiskId < king.PDiskId;
+ }
+ }
+
+ bool GivesLocalityBoost(TPDiskInfo& pretender, TPDiskInfo& king) const {
+ const ui32 a = GetLocalityFactor(pretender);
+ const ui32 b = GetLocalityFactor(king);
+ return Self.Randomize ? a < b : a > b;
+ }
+
+ bool BetterQuotaMatch(TPDiskInfo& pretender, TPDiskInfo& king) const {
+ return pretender.SpaceAvailable < king.SpaceAvailable;
+ }
+
+ void AddUsedDisk(const TPDiskInfo& pdisk) {
+ for (ui32 groupId : pdisk.Groups) {
+ ++LocalityFactor[groupId];
+ }
+ }
+
+ unsigned GetLocalityFactor(const TPDiskInfo& pdisk) const {
+ unsigned res = 0;
+ for (ui32 groupId : pdisk.Groups) {
+ res += GetLocalityFactor(groupId);
+ }
+ return res;
+ }
+
+ unsigned GetLocalityFactor(ui32 groupId) const {
+ const auto it = LocalityFactor.find(groupId);
+ return it != LocalityFactor.end() ? it->second : 0;
+ }
+ };
+
+ private:
+ const TGroupGeometryInfo Geom;
+ const bool Randomize;
+ TDomainMapper DomainMapper;
+ TPDisks PDisks;
+ TBox Box;
+
+ public:
+ TImpl(TGroupGeometryInfo geom, bool randomize)
+ : Geom(std::move(geom))
+ , Randomize(randomize)
+ {}
+
+ bool RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
+ const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational) {
+ // calculate disk position
+ const TPDiskLayoutPosition p(DomainMapper, location, pdiskId, Geom);
+
+ // insert PDisk into specific map
+ TPDisks::iterator it;
+ bool inserted;
+ std::tie(it, inserted) = PDisks.try_emplace(pdiskId, std::move(location), usable, numSlots, maxSlots,
+ p, pdiskId, groupIds, numGroups, spaceAvailable, operational, &Box(p));
+ if (inserted) {
+ it->second.FailDomain->push_back(&*it);
+ }
+
+ return inserted;
+ }
+
+ void UnregisterPDisk(TPDiskId pdiskId) {
+ const auto it = PDisks.find(pdiskId);
+ Y_VERIFY(it != PDisks.end());
+ TFailDomainInfo& fdom = *it->second.FailDomain;
+ bool erased = false;
+ for (auto x = fdom.begin(); x != fdom.end(); ++x) {
+ if (*x == &*it) {
+ fdom.erase(x);
+ erased = true;
+ break;
+ }
+ }
+ Y_VERIFY(erased);
+ PDisks.erase(it);
+ }
+
+ void AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment) {
+ const auto it = PDisks.find(pdiskId);
+ Y_VERIFY(it != PDisks.end());
+ it->second.SpaceAvailable += increment;
+ }
+
+ TString FormatPDisks(const TAllocateContext& ctx) const {
+ TStringStream s;
+ s << "PDisks# ";
+
+ bool first1 = true;
+ for (const auto& [id, realmGroup] : Box) {
+ s << (std::exchange(first1, false) ? "" : " | ") << "<";
+ bool first2 = true;
+ for (const auto& [id, realm] : realmGroup) {
+ s << (std::exchange(first2, false) ? "" : " ") << "{";
+ bool first3 = true;
+ for (const auto& [id, domainGroup] : realm) {
+ s << (std::exchange(first3, false) ? "" : " | ") << "[";
+ bool first4 = true;
+ for (const auto& [id, domain] : domainGroup) {
+ if (!domain.empty()) {
+ s << (std::exchange(first4, false) ? "" : " ") << "(";
+ std::vector<TPDisks::value_type*> v(domain);
+ auto comp = [](const auto *x, const auto *y) { return x->first < y->first; };
+ std::sort(v.begin(), v.end(), comp);
+ bool first5 = true;
+ for (const TPDisks::value_type *it : v) {
+ s << (std::exchange(first5, false) ? "" : " ")
+ << it->first.NodeId << ":" << it->first.PDiskId;
+ if (ctx.OldGroupContent.count(it->first)) {
+ s << "*";
+ }
+ const char *minus = "-";
+ if (ctx.Forbid.count(it->second.PDiskId)) {
+ s << std::exchange(minus, "") << "f";
+ }
+ if (!it->second.Usable) {
+ s << std::exchange(minus, "") << "u";
+ }
+ if (it->second.NumSlots >= it->second.MaxSlots) {
+ s << std::exchange(minus, "") << "m";
+ }
+ if (it->second.NumSlots >= it->second.MaxSlots) {
+ s << std::exchange(minus, "") << "s";
+ }
+ if (it->second.SpaceAvailable < ctx.RequiredSpace) {
+ s << std::exchange(minus, "") << "v";
+ }
+ if (!it->second.Operational) {
+ s << std::exchange(minus, "") << "o";
+ }
+ if (ctx.DiskIsUsable(it->second)) {
+ s << "+";
+ }
+ }
+ s << ")";
+ }
+ }
+ s << "]";
+ }
+ s << "}";
+ }
+ s << ">";
+ }
+
+ return s.Str();
+ }
+
+ bool AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
+ size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational,
+ TString& error) {
+ // fill in the allocation context
+ TAllocateContext ctx(Geom, requiredSpace, requireOperational, std::move(forbid));
+ if (!ctx.ProcessExistingGroup(group, PDisks, replacedDiskIds, numReplacedDisks, error)) {
+ return false;
+ }
+
+ // create group of required size, if it is not created yet
+ if (!Geom.ResizeGroup(group)) {
+ error = "incorrect existing group";
+ return false;
+ }
+
+ // if the group is already created, check for missing entities
+ bool hasMissingEntities = false;
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const TPDiskId& pdiskId : domain) {
+ if (pdiskId == TPDiskId()) {
+ hasMissingEntities = true;
+ break;
+ }
+ }
+ if (hasMissingEntities) {
+ break;
+ }
+ }
+ if (hasMissingEntities) {
+ break;
+ }
+ }
+ if (!hasMissingEntities) {
+ return true; // group is okay
+ }
+
+ // adjust number of slots
+ for (TPDiskId pdiskId : ctx.OldGroupContent) {
+ --PDisks.at(pdiskId).NumSlots;
+ }
+ for (size_t i = 0; i < numReplacedDisks; ++i) {
+ PDisks.at(replacedDiskIds[i]).EraseGroup(groupId);
+ }
+
+ // check if we can map a group only with PDisks that have NumSlots <= nums
+ if (!FindMatchingDisks(ctx)) {
+ // undo changes to the mapper content
+ for (TPDiskId pdiskId : ctx.OldGroupContent) {
+ ++PDisks.at(pdiskId).NumSlots;
+ }
+ for (size_t i = 0; i < numReplacedDisks; ++i) {
+ PDisks.at(replacedDiskIds[i]).InsertGroup(groupId);
+ }
+ error = "no group options " + FormatPDisks(ctx);
+ return false;
+ }
+
+ // fill in missing PDisk entities
+ THelper helper(*this, ctx);
+ for (ui32 realmIdx = 0, domainThroughIdx = 0; realmIdx < ctx.NumFailRealms; ++realmIdx) {
+ for (ui32 domainIdx = 0; domainIdx < ctx.NumFailDomainsPerFailRealm; ++domainIdx, ++domainThroughIdx) {
+ for (TPDiskId& pdiskId : group[realmIdx][domainIdx]) {
+ if (pdiskId == TPDiskId()) {
+ pdiskId = helper.AddBestDisk(realmIdx, domainThroughIdx);
+ }
+ }
+ }
+ }
+
+ // adjust number of slots
+ for (TPDiskId pdiskId : ctx.NewGroupContent) {
+ if (const auto it = PDisks.find(pdiskId); it != PDisks.end()) {
+ ++it->second.NumSlots;
+ it->second.InsertGroup(groupId);
+ } else {
+ Y_FAIL();
+ }
+ }
+
+ return true;
+ }
+
+ class TScorePicker {
+ static constexpr size_t MaxStaticItems = 16;
+ ui32 NumFake = 0;
+ TStackVec<ui32, MaxStaticItems> StaticHist;
+ std::map<ui32, ui32> ScoreHist;
+
+ public:
+ static constexpr ui32 FakeScore = Max<ui32>();
+
+ public:
+ void AddFake() {
+ ++NumFake;
+ }
+
+ void Add(ui32 score) {
+ if (score < MaxStaticItems) {
+ if (StaticHist.size() <= score) {
+ StaticHist.resize(score + 1);
+ }
+ ++StaticHist[score];
+ } else {
+ ++ScoreHist[score];
+ }
+ }
+
+ std::optional<ui32> CalculateMaxScore(ui32 threshold) const {
+ if (threshold <= NumFake) {
+ return FakeScore;
+ } else {
+ threshold -= NumFake;
+ }
+ for (size_t score = 0; score < StaticHist.size(); ++score) {
+ if (threshold <= StaticHist[score]) {
+ return score;
+ } else {
+ threshold -= StaticHist[score];
+ }
+ }
+ for (const auto& [score, num] : ScoreHist) {
+ if (threshold <= num) {
+ return score;
+ } else {
+ threshold -= num;
+ }
+ }
+ Y_VERIFY_DEBUG(threshold);
+ return std::nullopt;
+ }
+
+ void Cascade(TScorePicker& parent, ui32 threshold) {
+ if (std::optional<ui32> maxScore = CalculateMaxScore(threshold)) {
+ if (*maxScore != FakeScore) {
+ parent.Add(*maxScore);
+ } else {
+ parent.AddFake();
+ }
+ }
+ }
+ };
+
+ bool FindMatchingDisks(const TAllocateContext& ctx) {
+ struct TMatchingDisk {
+ TPDiskInfo *PDisk;
+ bool IsInGroup;
+ ui32 Score = 0;
+
+ TPDiskInfo *operator ->() const { return PDisk; }
+ bool operator <(const TMatchingDisk& other) const { return PDisk->Position < other->Position; }
+ };
+
+ TScorePicker realmGroupPicker;
+ std::vector<TMatchingDisk> matchingDisks;
+ for (auto& [id, realmGroup] : Box) {
+ TScorePicker realmPicker;
+ realmGroup.Matching = false;
+ for (auto& [id, realm] : realmGroup) {
+ TScorePicker domainGroupPicker;
+ realm.Matching = false;
+ for (auto& [id, domainGroup] : realm) {
+ TScorePicker domainPicker;
+ domainGroup.Matching = false;
+ for (auto& [id, domain] : domainGroup) {
+ TScorePicker diskPicker;
+ domain.Matching = false;
+ domain.NumMatchingDisks = 0;
+ for (TPDisks::value_type *it : domain) {
+ auto& [pdiskId, pdisk] = *it;
+ pdisk.Matching = ctx.DiskIsUsable(pdisk);
+ if (pdisk.Matching) {
+ const ui32 score = pdisk.GetPickerScore();
+ matchingDisks.push_back(TMatchingDisk{&pdisk, false, score});
+ diskPicker.Add(score);
+ } else if (ctx.NewGroupContent.count(pdiskId)) {
+ // we create a fake record to keep correct count of fail realms and domains, but
+ // this particular one never gets selected
+ matchingDisks.push_back(TMatchingDisk{&pdisk, true});
+ diskPicker.AddFake();
+ }
+ }
+ diskPicker.Cascade(domainPicker, Geom.GetNumVDisksPerFailDomain());
+ }
+ domainPicker.Cascade(domainGroupPicker, Geom.GetNumFailDomainsPerFailRealm());
+ }
+ domainGroupPicker.Cascade(realmPicker, 1);
+ }
+ realmPicker.Cascade(realmGroupPicker, Geom.GetNumFailRealms());
+ }
+
+ bool boxMatching = false;
+
+ if (const std::optional<ui32> maxScore = realmGroupPicker.CalculateMaxScore(1)) {
+ Y_VERIFY_DEBUG(*maxScore != TScorePicker::FakeScore);
+
+ // remove all mismatched candidate disks and sort them according to their position
+ auto remove = [maxScore = *maxScore](const TMatchingDisk& p) {
+ p->Matching = p->Matching && p.Score <= maxScore;
+ return !p->Matching && !p.IsInGroup;
+ };
+ const auto begin = matchingDisks.begin();
+ const auto end = matchingDisks.end();
+ matchingDisks.erase(std::remove_if(begin, end, remove), end);
+ std::sort(matchingDisks.begin(), matchingDisks.end());
+
+ std::optional<TPDiskLayoutPosition> prev;
+
+ ui32 numMatchingRealmGroupsInBox = 0;
+ ui32 numMatchingRealmsInRealmGroup = 0;
+ ui32 numMatchingDomainGroupsInRealm = 0;
+ ui32 numMatchingDomainsInDomainGroup = 0;
+ ui32 numMatchingDisksInDomain = 0;
+
+ TFailRealmGroup *realmGroup = nullptr;
+ TFailRealmInfo *realm = nullptr;
+ TFailDomainGroup *domainGroup = nullptr;
+ TFailDomainInfo *domain = nullptr;
+
+ for (const auto& disk : matchingDisks) {
+ const auto& cur = disk->Position;
+ switch (prev ? prev->GetDiffIndex(cur) : 0) {
+ case 0:
+ numMatchingRealmsInRealmGroup = 0;
+ realmGroup = &Box[cur.RealmGroup];
+ [[fallthrough]];
+ case 1:
+ numMatchingDomainGroupsInRealm = 0;
+ realm = &(*realmGroup)[cur.RealmInGroup];
+ [[fallthrough]];
+ case 2:
+ numMatchingDomainsInDomainGroup = 0;
+ domainGroup = &(*realm)[cur.DomainGroup];
+ [[fallthrough]];
+ case 3:
+ numMatchingDisksInDomain = 0;
+ domain = &(*domainGroup)[cur.DomainInGroup];
+ prev = cur;
+ [[fallthrough]];
+ case 4:
+ break;
+ }
+
+ ++domain->NumMatchingDisks;
+ const std::tuple<ui32&, ui32, bool&> items[] = {
+ {numMatchingDisksInDomain, Geom.GetNumVDisksPerFailDomain(), domain->Matching },
+ {numMatchingDomainsInDomainGroup, Geom.GetNumFailDomainsPerFailRealm(), domainGroup->Matching},
+ {numMatchingDomainGroupsInRealm, 1, realm->Matching },
+ {numMatchingRealmsInRealmGroup, Geom.GetNumFailRealms(), realmGroup->Matching },
+ {numMatchingRealmGroupsInBox, 1, boxMatching },
+ };
+ for (const auto& item : items) {
+ if (++std::get<0>(item) == std::get<1>(item)) {
+ std::get<2>(item) = true;
+ } else {
+ break;
+ }
+ }
+ }
+ Y_VERIFY(boxMatching);
+ }
+
+ return boxMatching;
+ }
+ };
+
+ TGroupMapper::TGroupMapper(TGroupGeometryInfo geom, bool randomize)
+ : Impl(new TImpl(std::move(geom), randomize))
+ {}
+
+ TGroupMapper::~TGroupMapper() = default;
+
+ bool TGroupMapper::RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
+ const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational) {
+ return Impl->RegisterPDisk(pdiskId, std::move(location), usable, numSlots, maxSlots, groupIds, numGroups,
+ spaceAvailable, operational);
+ }
+
+ void TGroupMapper::UnregisterPDisk(TPDiskId pdiskId) {
+ return Impl->UnregisterPDisk(pdiskId);
+ }
+
+ void TGroupMapper::AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment) {
+ return Impl->AdjustSpaceAvailable(pdiskId, increment);
+ }
+
+ bool TGroupMapper::AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
+ size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational, TString& error) {
+ return Impl->AllocateGroup(groupId, group, replacedDiskIds, numReplacedDisks, std::move(forbid),
+ requiredSpace, requireOperational, error);
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/group_mapper.h b/ydb/core/mind/bscontroller/group_mapper.h
index f66ba3171c3..da48cd18853 100644
--- a/ydb/core/mind/bscontroller/group_mapper.h
+++ b/ydb/core/mind/bscontroller/group_mapper.h
@@ -1,61 +1,61 @@
-#pragma once
-
-#include "defs.h"
-#include "types.h"
-
-namespace NKikimr {
- namespace NBsController {
-
- class TGroupGeometryInfo;
-
- // TGroupMapper is a helper class used to create groups from a set of PDisks with their respective locations
- // over physical hardware
- class TGroupMapper {
- class TImpl;
- THolder<TImpl> Impl;
-
- public:
+#pragma once
+
+#include "defs.h"
+#include "types.h"
+
+namespace NKikimr {
+ namespace NBsController {
+
+ class TGroupGeometryInfo;
+
+ // TGroupMapper is a helper class used to create groups from a set of PDisks with their respective locations
+ // over physical hardware
+ class TGroupMapper {
+ class TImpl;
+ THolder<TImpl> Impl;
+
+ public:
using TGroupDefinition = TVector<TVector<TVector<TPDiskId>>>; // Realm/Domain/Disk
- using TForbiddenPDisks = std::unordered_set<TPDiskId, THash<TPDiskId>>;
-
- public:
- TGroupMapper(TGroupGeometryInfo geom, bool randomize = false);
- ~TGroupMapper();
-
- // Register PDisk inside mapper to use it in subsequent map operations
- bool RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
- const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational);
-
- // Remove PDisk from the table.
- void UnregisterPDisk(TPDiskId pdiskId);
-
- // Adjust VDisk space quota.
- void AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment);
-
- // Allocate group (with incrementing number of used slots in internal structures) of given geometry. This
- // function returns true if group allocation succeeds returning PDisk layout in result variable, or false
- // otherwise. Allocation occurs on less occupied disks (measured with number of used VSlots). The resulting
- // group, if allocated, meets following requirements:
- // 1. Realm prefix and infix is the same for every disk in the same realm.
- // 2. Realm prefix is the same for all realms, but infix differs for every realm.
- // 3. Inside any fail realm the domain prefix is the same for all disks in that realm, but for every domain
- // infix differs.
- //
- // The PDisk location given in RegisterPDisk is split into three parts (prefix, infix, suffix) depending on
- // the context (realm or domain). Prefix part includes all levels with their respective values with level
- // key strictly less than FirstDxLevel; infix part includes all levels with key in [BeginDxLevel,
- // EndDxLevel) semi-open range; and the suffix part covers the remaining parts.
- //
- // According to the stated requirements, the algorithm is as follows:
- //
- // 1. Allocate realms by splitting all PDisk locations into tuples (prefix, infix, suffix) according to
- // failRealmBeginDxLevel, failRealmEndDxLevel, and then by finding possible options to meet requirements
- // (1) and (2). That is, prefix gives us unique domains in which we can find realms to operate, while
- // prefix+infix part gives us distinct fail realms we can use while generating groups.
- bool AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
- size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational,
- TString& error);
- };
-
- } // NBsController
-} // NKikimr
+ using TForbiddenPDisks = std::unordered_set<TPDiskId, THash<TPDiskId>>;
+
+ public:
+ TGroupMapper(TGroupGeometryInfo geom, bool randomize = false);
+ ~TGroupMapper();
+
+ // Register PDisk inside mapper to use it in subsequent map operations
+ bool RegisterPDisk(TPDiskId pdiskId, TNodeLocation location, bool usable, ui32 numSlots, ui32 maxSlots,
+ const ui32 groupIds[], size_t numGroups, i64 spaceAvailable, bool operational);
+
+ // Remove PDisk from the table.
+ void UnregisterPDisk(TPDiskId pdiskId);
+
+ // Adjust VDisk space quota.
+ void AdjustSpaceAvailable(TPDiskId pdiskId, i64 increment);
+
+ // Allocate group (with incrementing number of used slots in internal structures) of given geometry. This
+ // function returns true if group allocation succeeds returning PDisk layout in result variable, or false
+ // otherwise. Allocation occurs on less occupied disks (measured with number of used VSlots). The resulting
+ // group, if allocated, meets following requirements:
+ // 1. Realm prefix and infix is the same for every disk in the same realm.
+ // 2. Realm prefix is the same for all realms, but infix differs for every realm.
+ // 3. Inside any fail realm the domain prefix is the same for all disks in that realm, but for every domain
+ // infix differs.
+ //
+ // The PDisk location given in RegisterPDisk is split into three parts (prefix, infix, suffix) depending on
+ // the context (realm or domain). Prefix part includes all levels with their respective values with level
+ // key strictly less than FirstDxLevel; infix part includes all levels with key in [BeginDxLevel,
+ // EndDxLevel) semi-open range; and the suffix part covers the remaining parts.
+ //
+ // According to the stated requirements, the algorithm is as follows:
+ //
+ // 1. Allocate realms by splitting all PDisk locations into tuples (prefix, infix, suffix) according to
+ // failRealmBeginDxLevel, failRealmEndDxLevel, and then by finding possible options to meet requirements
+ // (1) and (2). That is, prefix gives us unique domains in which we can find realms to operate, while
+ // prefix+infix part gives us distinct fail realms we can use while generating groups.
+ bool AllocateGroup(ui32 groupId, TGroupDefinition& group, const TPDiskId replacedDiskIds[],
+ size_t numReplacedDisks, TForbiddenPDisks forbid, i64 requiredSpace, bool requireOperational,
+ TString& error);
+ };
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/group_mapper_ut.cpp b/ydb/core/mind/bscontroller/group_mapper_ut.cpp
index 0dcb5be0863..d8e25b5f48a 100644
--- a/ydb/core/mind/bscontroller/group_mapper_ut.cpp
+++ b/ydb/core/mind/bscontroller/group_mapper_ut.cpp
@@ -1,633 +1,633 @@
#include <library/cpp/testing/unittest/registar.h>
#include "group_geometry_info.h"
-#include "group_mapper.h"
+#include "group_mapper.h"
#include "ut_helpers.h"
-
-using namespace NKikimr;
-using namespace NKikimr::NBsController;
-
-class TTestContext {
- struct TPDiskRecord {
- ui32 DataCenterId;
- ui32 RoomId;
- ui32 RackId;
- ui32 BodyId;
- ui32 NumSlots;
-
- TPDiskRecord(ui32 dataCenterId, ui32 roomId, ui32 rackId, ui32 bodyId)
- : DataCenterId(dataCenterId)
- , RoomId(roomId)
- , RackId(rackId)
- , BodyId(bodyId)
- , NumSlots(0)
- {}
-
- TNodeLocation GetLocation() const {
- NActorsInterconnect::TNodeLocation proto;
- proto.SetDataCenter(ToString(DataCenterId));
- proto.SetModule(ToString(RoomId));
- proto.SetRack(ToString(RackId));
- proto.SetUnit(ToString(BodyId));
- return TNodeLocation(proto);
- }
- };
-
- struct TGroupRecord {
- TGroupMapper::TGroupDefinition Group;
- TVector<TPDiskId> PDisks;
- };
-
- TMap<TPDiskId, TPDiskRecord> PDisks;
- TMap<ui32, TGroupRecord> Groups;
- ui32 NextGroupId = 1;
-
-public:
- TTestContext(ui32 numDataCenters, ui32 numRooms, ui32 numRacks, ui32 numBodies, ui32 numDisks) {
- ui32 nodeId = 1;
- ui32 pdiskId = 1;
- ui32 dataCenter = 1;
- ui32 room = 1;
- ui32 rack = 1;
- ui32 body = 1;
- for (ui32 a = 0; a < numDataCenters; ++a, ++dataCenter) {
- for (ui32 b = 0; b < numRooms; ++b, ++room) {
- for (ui32 c = 0; c < numRacks; ++c, ++rack) {
- for (ui32 d = 0; d < numBodies; ++d, ++body, ++nodeId) {
- for (ui32 e = 0; e < numDisks; ++e, ++pdiskId) {
- PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body));
- }
- }
- }
- }
- }
- }
-
- TTestContext(const std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>>& disks) {
- ui32 nodeId = 1;
- for (const auto& disk : disks) {
- ui32 dataCenter, room, rack, body, numDisks;
- std::tie(dataCenter, room, rack, body, numDisks) = disk;
- for (ui32 pdiskId = 1; numDisks--; ++pdiskId) {
- const bool inserted = PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body)).second;
- UNIT_ASSERT(inserted);
- }
- ++nodeId;
- }
- }
-
- TTestContext(const std::vector<std::vector<ui32>>& disposition, ui32 numDisks) {
- ui32 nodeId = 1;
- ui32 dataCenter = 1;
- ui32 room = 1;
- for (const auto& realm : disposition) {
- ui32 rack = 1;
- for (const auto& domain : realm) {
- for (ui32 body = 1; body <= domain; ++body) {
- for (ui32 pdiskId = 1, i = numDisks; i--; ++pdiskId) {
- const bool inserted = PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body)).second;
- UNIT_ASSERT(inserted);
- }
-
- ++nodeId;
- }
- ++rack;
- }
- ++dataCenter;
- }
- }
-
- static TGroupGeometryInfo CreateGroupGeometry(TBlobStorageGroupType type, ui32 numFailRealms = 0, ui32 numFailDomains = 0,
- ui32 numVDisks = 0, ui32 realmBegin = 0, ui32 realmEnd = 0, ui32 domainBegin = 0, ui32 domainEnd = 0) {
- NKikimrBlobStorage::TGroupGeometry g;
- g.SetNumFailRealms(numFailRealms);
- g.SetNumFailDomainsPerFailRealm(numFailDomains);
- g.SetNumVDisksPerFailDomain(numVDisks);
- g.SetRealmLevelBegin(realmBegin);
- g.SetRealmLevelEnd(realmEnd);
- g.SetDomainLevelBegin(domainBegin);
- g.SetDomainLevelEnd(domainEnd);
- return TGroupGeometryInfo(type, g);
- }
-
- ui32 GetTotalDisks() const {
- return PDisks.size();
- }
-
- TVector<ui32> GetSlots() const {
- TVector<ui32> slots;
- for (const auto& pair : PDisks) {
- slots.push_back(pair.second.NumSlots);
- }
- return slots;
- }
-
- template<typename TFunc>
- void IterateGroups(TFunc&& callback) {
- for (const auto& kv : Groups) {
- callback(kv.second.PDisks);
- }
- }
-
- template<typename TFunc>
- void IteratePDisks(TFunc&& callback) {
- for (auto& [k, v] : PDisks) {
- callback(k, v);
- }
- }
-
- ui32 AllocateGroup(TGroupMapper& mapper, TGroupMapper::TGroupDefinition& group, bool allowFailure = false) {
- ui32 groupId = NextGroupId++;
- TString error;
- bool success = mapper.AllocateGroup(groupId, group, nullptr, 0, {}, 0, false, error);
- if (!success && allowFailure) {
- return 0;
- }
- if (!success) {
+
+using namespace NKikimr;
+using namespace NKikimr::NBsController;
+
+class TTestContext {
+ struct TPDiskRecord {
+ ui32 DataCenterId;
+ ui32 RoomId;
+ ui32 RackId;
+ ui32 BodyId;
+ ui32 NumSlots;
+
+ TPDiskRecord(ui32 dataCenterId, ui32 roomId, ui32 rackId, ui32 bodyId)
+ : DataCenterId(dataCenterId)
+ , RoomId(roomId)
+ , RackId(rackId)
+ , BodyId(bodyId)
+ , NumSlots(0)
+ {}
+
+ TNodeLocation GetLocation() const {
+ NActorsInterconnect::TNodeLocation proto;
+ proto.SetDataCenter(ToString(DataCenterId));
+ proto.SetModule(ToString(RoomId));
+ proto.SetRack(ToString(RackId));
+ proto.SetUnit(ToString(BodyId));
+ return TNodeLocation(proto);
+ }
+ };
+
+ struct TGroupRecord {
+ TGroupMapper::TGroupDefinition Group;
+ TVector<TPDiskId> PDisks;
+ };
+
+ TMap<TPDiskId, TPDiskRecord> PDisks;
+ TMap<ui32, TGroupRecord> Groups;
+ ui32 NextGroupId = 1;
+
+public:
+ TTestContext(ui32 numDataCenters, ui32 numRooms, ui32 numRacks, ui32 numBodies, ui32 numDisks) {
+ ui32 nodeId = 1;
+ ui32 pdiskId = 1;
+ ui32 dataCenter = 1;
+ ui32 room = 1;
+ ui32 rack = 1;
+ ui32 body = 1;
+ for (ui32 a = 0; a < numDataCenters; ++a, ++dataCenter) {
+ for (ui32 b = 0; b < numRooms; ++b, ++room) {
+ for (ui32 c = 0; c < numRacks; ++c, ++rack) {
+ for (ui32 d = 0; d < numBodies; ++d, ++body, ++nodeId) {
+ for (ui32 e = 0; e < numDisks; ++e, ++pdiskId) {
+ PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ TTestContext(const std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>>& disks) {
+ ui32 nodeId = 1;
+ for (const auto& disk : disks) {
+ ui32 dataCenter, room, rack, body, numDisks;
+ std::tie(dataCenter, room, rack, body, numDisks) = disk;
+ for (ui32 pdiskId = 1; numDisks--; ++pdiskId) {
+ const bool inserted = PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body)).second;
+ UNIT_ASSERT(inserted);
+ }
+ ++nodeId;
+ }
+ }
+
+ TTestContext(const std::vector<std::vector<ui32>>& disposition, ui32 numDisks) {
+ ui32 nodeId = 1;
+ ui32 dataCenter = 1;
+ ui32 room = 1;
+ for (const auto& realm : disposition) {
+ ui32 rack = 1;
+ for (const auto& domain : realm) {
+ for (ui32 body = 1; body <= domain; ++body) {
+ for (ui32 pdiskId = 1, i = numDisks; i--; ++pdiskId) {
+ const bool inserted = PDisks.emplace(TPDiskId(nodeId, pdiskId), TPDiskRecord(dataCenter, room, rack, body)).second;
+ UNIT_ASSERT(inserted);
+ }
+
+ ++nodeId;
+ }
+ ++rack;
+ }
+ ++dataCenter;
+ }
+ }
+
+ static TGroupGeometryInfo CreateGroupGeometry(TBlobStorageGroupType type, ui32 numFailRealms = 0, ui32 numFailDomains = 0,
+ ui32 numVDisks = 0, ui32 realmBegin = 0, ui32 realmEnd = 0, ui32 domainBegin = 0, ui32 domainEnd = 0) {
+ NKikimrBlobStorage::TGroupGeometry g;
+ g.SetNumFailRealms(numFailRealms);
+ g.SetNumFailDomainsPerFailRealm(numFailDomains);
+ g.SetNumVDisksPerFailDomain(numVDisks);
+ g.SetRealmLevelBegin(realmBegin);
+ g.SetRealmLevelEnd(realmEnd);
+ g.SetDomainLevelBegin(domainBegin);
+ g.SetDomainLevelEnd(domainEnd);
+ return TGroupGeometryInfo(type, g);
+ }
+
+ ui32 GetTotalDisks() const {
+ return PDisks.size();
+ }
+
+ TVector<ui32> GetSlots() const {
+ TVector<ui32> slots;
+ for (const auto& pair : PDisks) {
+ slots.push_back(pair.second.NumSlots);
+ }
+ return slots;
+ }
+
+ template<typename TFunc>
+ void IterateGroups(TFunc&& callback) {
+ for (const auto& kv : Groups) {
+ callback(kv.second.PDisks);
+ }
+ }
+
+ template<typename TFunc>
+ void IteratePDisks(TFunc&& callback) {
+ for (auto& [k, v] : PDisks) {
+ callback(k, v);
+ }
+ }
+
+ ui32 AllocateGroup(TGroupMapper& mapper, TGroupMapper::TGroupDefinition& group, bool allowFailure = false) {
+ ui32 groupId = NextGroupId++;
+ TString error;
+ bool success = mapper.AllocateGroup(groupId, group, nullptr, 0, {}, 0, false, error);
+ if (!success && allowFailure) {
+ return 0;
+ }
+ if (!success) {
Ctest << "error# " << error << Endl;
- }
- UNIT_ASSERT(success);
- TGroupRecord& record = Groups[groupId];
- record.Group = group;
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const auto& pdisk : domain) {
- record.PDisks.push_back(pdisk);
- ++PDisks.at(pdisk).NumSlots;
- }
- }
- }
- return groupId;
- }
-
- TGroupMapper::TGroupDefinition ReallocateGroup(TGroupMapper& mapper, ui32 groupId, const TSet<TPDiskId>& unusableDisks,
- bool makeThemForbidden = false, bool requireOperational = false, bool requireError = false) {
- TGroupRecord& group = Groups.at(groupId);
-
- TGroupMapper::TForbiddenPDisks forbid(unusableDisks.begin(), unusableDisks.end());
- if (!makeThemForbidden) {
- forbid.clear();
- }
-
- // remove unusable disks from the set
- std::vector<TPDiskId> replaced;
- for (auto& realm : group.Group) {
- for (auto& domain : realm) {
- for (auto& pdisk : domain) {
- --PDisks.at(pdisk).NumSlots;
- if (unusableDisks.count(pdisk)) {
- replaced.push_back(std::exchange(pdisk, {}));
- }
- }
- }
- }
-
+ }
+ UNIT_ASSERT(success);
+ TGroupRecord& record = Groups[groupId];
+ record.Group = group;
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const auto& pdisk : domain) {
+ record.PDisks.push_back(pdisk);
+ ++PDisks.at(pdisk).NumSlots;
+ }
+ }
+ }
+ return groupId;
+ }
+
+ TGroupMapper::TGroupDefinition ReallocateGroup(TGroupMapper& mapper, ui32 groupId, const TSet<TPDiskId>& unusableDisks,
+ bool makeThemForbidden = false, bool requireOperational = false, bool requireError = false) {
+ TGroupRecord& group = Groups.at(groupId);
+
+ TGroupMapper::TForbiddenPDisks forbid(unusableDisks.begin(), unusableDisks.end());
+ if (!makeThemForbidden) {
+ forbid.clear();
+ }
+
+ // remove unusable disks from the set
+ std::vector<TPDiskId> replaced;
+ for (auto& realm : group.Group) {
+ for (auto& domain : realm) {
+ for (auto& pdisk : domain) {
+ --PDisks.at(pdisk).NumSlots;
+ if (unusableDisks.count(pdisk)) {
+ replaced.push_back(std::exchange(pdisk, {}));
+ }
+ }
+ }
+ }
+
Ctest << "groupId# " << groupId << " reallocating group# " << FormatGroup(group.Group) << Endl;
-
- TString error;
- bool success = mapper.AllocateGroup(groupId, group.Group, replaced.data(), replaced.size(), std::move(forbid),
- 0, requireOperational, error);
- if (!success) {
- if (requireError) {
- return {};
- }
+
+ TString error;
+ bool success = mapper.AllocateGroup(groupId, group.Group, replaced.data(), replaced.size(), std::move(forbid),
+ 0, requireOperational, error);
+ if (!success) {
+ if (requireError) {
+ return {};
+ }
Ctest << "error# " << error << Endl;
- } else {
- UNIT_ASSERT(!requireError);
- }
- UNIT_ASSERT(success);
-
- group.PDisks.clear();
- for (const auto& realm : group.Group) {
- for (const auto& domain : realm) {
- for (const auto& pdisk : domain) {
- group.PDisks.push_back(pdisk);
- ++PDisks.at(pdisk).NumSlots;
- }
- }
- }
-
- return group.Group;
- }
-
- TString FormatGroup(const TGroupMapper::TGroupDefinition& group) {
- TStringStream str;
- str << "[";
- for (auto it = group.begin(); it != group.end(); ++it) {
- if (it != group.begin()) {
- str << " ";
- }
- str << "[";
- for (auto jt = it->begin(); jt != it->end(); ++jt) {
- if (jt != it->begin()) {
- str << " ";
- }
- str << "[";
- for (auto kt = jt->begin(); kt != jt->end(); ++kt) {
- str << kt->ToString();
- }
- str << "]";
- }
- str << "]";
- }
- str << "]";
- return str.Str();
- }
-
- void CheckGroupErasure(const TGroupMapper::TGroupDefinition& group) {
- TSet<ui32> dataCenters;
- for (const auto& realm : group) {
- TMaybe<ui32> dataCenter;
- TSet<std::tuple<ui32, ui32>> domains;
- for (const auto& domain : realm) {
- TMaybe<std::tuple<ui32, ui32>> currentDom;
- for (const auto& pdisk : domain) {
- const TPDiskRecord& record = PDisks.at(pdisk);
- if (dataCenter) {
- UNIT_ASSERT_VALUES_EQUAL(*dataCenter, record.DataCenterId);
- } else {
- dataCenter = record.DataCenterId;
- const bool inserted = dataCenters.insert(*dataCenter).second;
- UNIT_ASSERT(inserted);
- }
- std::tuple<ui32, ui32> dom = {record.RoomId, record.RackId};
- if (currentDom) {
- // check that all disks from the same domain reside in the same domain :)
- UNIT_ASSERT_EQUAL(dom, *currentDom);
- } else {
- currentDom = dom;
- const bool inserted = domains.insert(dom).second;
- UNIT_ASSERT(inserted); // check if it is new domain
- }
- }
- }
- }
- }
-
- void CheckIfGroupsAreMappedCompact() {
- // create PDisk -> GroupId mapping
- TMap<TPDiskId, TVector<ui32>> pdiskToGroup;
- for (const auto& pair : Groups) {
- const TGroupRecord& group = pair.second;
- for (const TPDiskId& pdisk : group.PDisks) {
- pdiskToGroup[pdisk].push_back(pair.first);
- }
- }
-
- for (const auto& pair : Groups) {
- const TGroupRecord& group = pair.second;
-
- // first, pick up all PDisks from this group and check other groups on these PDisks
- TSet<ui32> groupIds;
- for (const TPDiskId& pdisk : group.PDisks) {
- for (ui32 groupId : pdiskToGroup.at(pdisk)) {
- groupIds.insert(groupId);
- }
- }
-
- // now lets see if each of these groups occupies the same set of PDisks
- for (ui32 groupId : groupIds) {
- auto sorted = [](TVector<TPDiskId> pdisks) {
- std::sort(pdisks.begin(), pdisks.end());
- return pdisks;
- };
- UNIT_ASSERT_EQUAL(sorted(Groups.at(groupId).PDisks), sorted(group.PDisks));
- }
- }
- }
-
- void PopulateGroupMapper(TGroupMapper& mapper, ui32 maxSlots = 16, TSet<TPDiskId> unusableDisks = {},
- TSet<TPDiskId> nonoperationalDisks = {}) {
- std::map<TPDiskId, std::vector<ui32>> groupDisks;
- for (const auto& [groupId, group] : Groups) {
- for (TPDiskId pdiskId : group.PDisks) {
- groupDisks[pdiskId].push_back(groupId);
- }
- }
- for (const auto& pair : PDisks) {
- auto& g = groupDisks[pair.first];
- mapper.RegisterPDisk(pair.first, pair.second.GetLocation(), !unusableDisks.count(pair.first),
- pair.second.NumSlots, maxSlots, g.data(), g.size(), 0, nonoperationalDisks.count(pair.first));
- }
- }
-};
-
-Y_UNIT_TEST_SUITE(TGroupMapperTest) {
-
- Y_UNIT_TEST(MapperSequentialCalls) {
- TTestContext globalContext(3, 4, 20, 5, 4);
- TTestContext localContext(3, 4, 20, 5, 4);
-
- TGroupMapper globalMapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, 2));
- globalContext.PopulateGroupMapper(globalMapper, 16);
- for (ui32 i = 0; i < globalContext.GetTotalDisks(); ++i) {
+ } else {
+ UNIT_ASSERT(!requireError);
+ }
+ UNIT_ASSERT(success);
+
+ group.PDisks.clear();
+ for (const auto& realm : group.Group) {
+ for (const auto& domain : realm) {
+ for (const auto& pdisk : domain) {
+ group.PDisks.push_back(pdisk);
+ ++PDisks.at(pdisk).NumSlots;
+ }
+ }
+ }
+
+ return group.Group;
+ }
+
+ TString FormatGroup(const TGroupMapper::TGroupDefinition& group) {
+ TStringStream str;
+ str << "[";
+ for (auto it = group.begin(); it != group.end(); ++it) {
+ if (it != group.begin()) {
+ str << " ";
+ }
+ str << "[";
+ for (auto jt = it->begin(); jt != it->end(); ++jt) {
+ if (jt != it->begin()) {
+ str << " ";
+ }
+ str << "[";
+ for (auto kt = jt->begin(); kt != jt->end(); ++kt) {
+ str << kt->ToString();
+ }
+ str << "]";
+ }
+ str << "]";
+ }
+ str << "]";
+ return str.Str();
+ }
+
+ void CheckGroupErasure(const TGroupMapper::TGroupDefinition& group) {
+ TSet<ui32> dataCenters;
+ for (const auto& realm : group) {
+ TMaybe<ui32> dataCenter;
+ TSet<std::tuple<ui32, ui32>> domains;
+ for (const auto& domain : realm) {
+ TMaybe<std::tuple<ui32, ui32>> currentDom;
+ for (const auto& pdisk : domain) {
+ const TPDiskRecord& record = PDisks.at(pdisk);
+ if (dataCenter) {
+ UNIT_ASSERT_VALUES_EQUAL(*dataCenter, record.DataCenterId);
+ } else {
+ dataCenter = record.DataCenterId;
+ const bool inserted = dataCenters.insert(*dataCenter).second;
+ UNIT_ASSERT(inserted);
+ }
+ std::tuple<ui32, ui32> dom = {record.RoomId, record.RackId};
+ if (currentDom) {
+ // check that all disks from the same domain reside in the same domain :)
+ UNIT_ASSERT_EQUAL(dom, *currentDom);
+ } else {
+ currentDom = dom;
+ const bool inserted = domains.insert(dom).second;
+ UNIT_ASSERT(inserted); // check if it is new domain
+ }
+ }
+ }
+ }
+ }
+
+ void CheckIfGroupsAreMappedCompact() {
+ // create PDisk -> GroupId mapping
+ TMap<TPDiskId, TVector<ui32>> pdiskToGroup;
+ for (const auto& pair : Groups) {
+ const TGroupRecord& group = pair.second;
+ for (const TPDiskId& pdisk : group.PDisks) {
+ pdiskToGroup[pdisk].push_back(pair.first);
+ }
+ }
+
+ for (const auto& pair : Groups) {
+ const TGroupRecord& group = pair.second;
+
+ // first, pick up all PDisks from this group and check other groups on these PDisks
+ TSet<ui32> groupIds;
+ for (const TPDiskId& pdisk : group.PDisks) {
+ for (ui32 groupId : pdiskToGroup.at(pdisk)) {
+ groupIds.insert(groupId);
+ }
+ }
+
+ // now lets see if each of these groups occupies the same set of PDisks
+ for (ui32 groupId : groupIds) {
+ auto sorted = [](TVector<TPDiskId> pdisks) {
+ std::sort(pdisks.begin(), pdisks.end());
+ return pdisks;
+ };
+ UNIT_ASSERT_EQUAL(sorted(Groups.at(groupId).PDisks), sorted(group.PDisks));
+ }
+ }
+ }
+
+ void PopulateGroupMapper(TGroupMapper& mapper, ui32 maxSlots = 16, TSet<TPDiskId> unusableDisks = {},
+ TSet<TPDiskId> nonoperationalDisks = {}) {
+ std::map<TPDiskId, std::vector<ui32>> groupDisks;
+ for (const auto& [groupId, group] : Groups) {
+ for (TPDiskId pdiskId : group.PDisks) {
+ groupDisks[pdiskId].push_back(groupId);
+ }
+ }
+ for (const auto& pair : PDisks) {
+ auto& g = groupDisks[pair.first];
+ mapper.RegisterPDisk(pair.first, pair.second.GetLocation(), !unusableDisks.count(pair.first),
+ pair.second.NumSlots, maxSlots, g.data(), g.size(), 0, nonoperationalDisks.count(pair.first));
+ }
+ }
+};
+
+Y_UNIT_TEST_SUITE(TGroupMapperTest) {
+
+ Y_UNIT_TEST(MapperSequentialCalls) {
+ TTestContext globalContext(3, 4, 20, 5, 4);
+ TTestContext localContext(3, 4, 20, 5, 4);
+
+ TGroupMapper globalMapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, 2));
+ globalContext.PopulateGroupMapper(globalMapper, 16);
+ for (ui32 i = 0; i < globalContext.GetTotalDisks(); ++i) {
Ctest << i << "/" << globalContext.GetTotalDisks() << Endl;
-
- TGroupMapper::TGroupDefinition group;
- globalContext.AllocateGroup(globalMapper, group);
-
- TGroupMapper localMapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, 2));
- localContext.PopulateGroupMapper(localMapper, 16);
- TGroupMapper::TGroupDefinition localGroup;
- localContext.AllocateGroup(localMapper, localGroup);
-
- UNIT_ASSERT_EQUAL(localGroup, group);
- }
- }
-
- void TestBlock42(ui32 numVDisksPerFailDomain) {
- TTestContext context(3, 4, 20, 5, 4);
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, numVDisksPerFailDomain));
- context.PopulateGroupMapper(mapper, 8 * numVDisksPerFailDomain);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+
+ TGroupMapper::TGroupDefinition group;
+ globalContext.AllocateGroup(globalMapper, group);
+
+ TGroupMapper localMapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, 2));
+ localContext.PopulateGroupMapper(localMapper, 16);
+ TGroupMapper::TGroupDefinition localGroup;
+ localContext.AllocateGroup(localMapper, localGroup);
+
+ UNIT_ASSERT_EQUAL(localGroup, group);
+ }
+ }
+
+ void TestBlock42(ui32 numVDisksPerFailDomain) {
+ TTestContext context(3, 4, 20, 5, 4);
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block, 1, 8, numVDisksPerFailDomain));
+ context.PopulateGroupMapper(mapper, 8 * numVDisksPerFailDomain);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
Ctest << i << "/" << context.GetTotalDisks() << Endl;
- TGroupMapper::TGroupDefinition group;
- context.AllocateGroup(mapper, group);
- context.CheckGroupErasure(group);
- }
- TVector<ui32> slots = context.GetSlots();
- for (ui32 numSlots : slots) {
- UNIT_ASSERT_VALUES_EQUAL(8 * numVDisksPerFailDomain, numSlots);
- }
- context.CheckIfGroupsAreMappedCompact();
- }
-
- Y_UNIT_TEST(Block42_1disk) {
- TestBlock42(1);
- }
-
- Y_UNIT_TEST(Block42_2disk) {
- TestBlock42(2);
- }
-
- Y_UNIT_TEST(Mirror3dc) {
- TTestContext context(6, 3, 3, 3, 3);
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::ErasureMirror3dc));
- context.PopulateGroupMapper(mapper, 9);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ context.AllocateGroup(mapper, group);
+ context.CheckGroupErasure(group);
+ }
+ TVector<ui32> slots = context.GetSlots();
+ for (ui32 numSlots : slots) {
+ UNIT_ASSERT_VALUES_EQUAL(8 * numVDisksPerFailDomain, numSlots);
+ }
+ context.CheckIfGroupsAreMappedCompact();
+ }
+
+ Y_UNIT_TEST(Block42_1disk) {
+ TestBlock42(1);
+ }
+
+ Y_UNIT_TEST(Block42_2disk) {
+ TestBlock42(2);
+ }
+
+ Y_UNIT_TEST(Mirror3dc) {
+ TTestContext context(6, 3, 3, 3, 3);
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::ErasureMirror3dc));
+ context.PopulateGroupMapper(mapper, 9);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
Ctest << i << "/" << context.GetTotalDisks() << Endl;
- TGroupMapper::TGroupDefinition group;
- context.AllocateGroup(mapper, group);
- context.CheckGroupErasure(group);
- }
- TVector<ui32> slots = context.GetSlots();
- for (ui32 numSlots : slots) {
- UNIT_ASSERT_VALUES_EQUAL(9, numSlots);
- }
- context.CheckIfGroupsAreMappedCompact();
- }
-
- Y_UNIT_TEST(NonUniformCluster) {
- std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
- for (ui32 rack = 0, body = 0; rack < 12; ++rack) {
- for (ui32 i = 0; i < (rack < 4 ? 32 : 33); ++i, ++body) {
- disks.emplace_back(1, 1, rack, body, 8);
- }
- }
- std::random_shuffle(disks.begin(), disks.end());
- TTestContext context(disks);
- UNIT_ASSERT_VALUES_EQUAL(8 * (4 * 32 + 8 * 33), context.GetTotalDisks());
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, 8);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ context.AllocateGroup(mapper, group);
+ context.CheckGroupErasure(group);
+ }
+ TVector<ui32> slots = context.GetSlots();
+ for (ui32 numSlots : slots) {
+ UNIT_ASSERT_VALUES_EQUAL(9, numSlots);
+ }
+ context.CheckIfGroupsAreMappedCompact();
+ }
+
+ Y_UNIT_TEST(NonUniformCluster) {
+ std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
+ for (ui32 rack = 0, body = 0; rack < 12; ++rack) {
+ for (ui32 i = 0; i < (rack < 4 ? 32 : 33); ++i, ++body) {
+ disks.emplace_back(1, 1, rack, body, 8);
+ }
+ }
+ std::random_shuffle(disks.begin(), disks.end());
+ TTestContext context(disks);
+ UNIT_ASSERT_VALUES_EQUAL(8 * (4 * 32 + 8 * 33), context.GetTotalDisks());
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, 8);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
Ctest << i << "/" << context.GetTotalDisks() << Endl;
- TGroupMapper::TGroupDefinition group;
- context.AllocateGroup(mapper, group);
- context.CheckGroupErasure(group);
- }
- TVector<ui32> slots = context.GetSlots();
- for (ui32 numSlots : slots) {
- UNIT_ASSERT_VALUES_EQUAL(8, numSlots);
- }
- }
-
- Y_UNIT_TEST(NonUniformCluster2) {
- std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
- for (ui32 rack = 0, body = 0; rack < 12; ++rack) {
- ui32 array[] = {
- 168, 168, 168, 168,
- 96, 96, 96, 96,
- 80, 80, 80, 80,
- };
- ui32 numDisks = array[rack];
- for (ui32 i = 0; i < numDisks / 8; ++i, ++body) {
- disks.emplace_back(1, 1, rack, body, 8);
- }
- }
- std::random_shuffle(disks.begin(), disks.end());
- TTestContext context(disks);
- UNIT_ASSERT_VALUES_EQUAL(8 * (168 + 96 + 80) / 2, context.GetTotalDisks());
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, 8);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ context.AllocateGroup(mapper, group);
+ context.CheckGroupErasure(group);
+ }
+ TVector<ui32> slots = context.GetSlots();
+ for (ui32 numSlots : slots) {
+ UNIT_ASSERT_VALUES_EQUAL(8, numSlots);
+ }
+ }
+
+ Y_UNIT_TEST(NonUniformCluster2) {
+ std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
+ for (ui32 rack = 0, body = 0; rack < 12; ++rack) {
+ ui32 array[] = {
+ 168, 168, 168, 168,
+ 96, 96, 96, 96,
+ 80, 80, 80, 80,
+ };
+ ui32 numDisks = array[rack];
+ for (ui32 i = 0; i < numDisks / 8; ++i, ++body) {
+ disks.emplace_back(1, 1, rack, body, 8);
+ }
+ }
+ std::random_shuffle(disks.begin(), disks.end());
+ TTestContext context(disks);
+ UNIT_ASSERT_VALUES_EQUAL(8 * (168 + 96 + 80) / 2, context.GetTotalDisks());
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, 8);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
Ctest << i << "/" << context.GetTotalDisks() << Endl;
- TGroupMapper::TGroupDefinition group;
- context.AllocateGroup(mapper, group);
- context.CheckGroupErasure(group);
- }
- TVector<ui32> slots = context.GetSlots();
- for (ui32 numSlots : slots) {
- UNIT_ASSERT_VALUES_EQUAL(8, numSlots);
- }
- }
-
- Y_UNIT_TEST(NonUniformClusterMirror3dc) {
- std::vector<std::vector<ui32>> disposition{
- { // datacenter1
- 4, 4, 4, 4, 4, 2, 2, 4, 2, 5, 5, 5,
- },
- { // datacenter2
- 2, 2, 2, 2, 2, 2, 1, 1, 2, 4, 8, 8, 9,
- },
- { // datacenter3
- 4, 4, 1, 3, 4, 4, 2, 6, 9, 8,
- },
- };
- TTestContext context(disposition, 4);
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::ErasureMirror3dc));
- context.PopulateGroupMapper(mapper, 9);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ context.AllocateGroup(mapper, group);
+ context.CheckGroupErasure(group);
+ }
+ TVector<ui32> slots = context.GetSlots();
+ for (ui32 numSlots : slots) {
+ UNIT_ASSERT_VALUES_EQUAL(8, numSlots);
+ }
+ }
+
+ Y_UNIT_TEST(NonUniformClusterMirror3dc) {
+ std::vector<std::vector<ui32>> disposition{
+ { // datacenter1
+ 4, 4, 4, 4, 4, 2, 2, 4, 2, 5, 5, 5,
+ },
+ { // datacenter2
+ 2, 2, 2, 2, 2, 2, 1, 1, 2, 4, 8, 8, 9,
+ },
+ { // datacenter3
+ 4, 4, 1, 3, 4, 4, 2, 6, 9, 8,
+ },
+ };
+ TTestContext context(disposition, 4);
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::ErasureMirror3dc));
+ context.PopulateGroupMapper(mapper, 9);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
Ctest << i << "/" << context.GetTotalDisks() << Endl;
- TGroupMapper::TGroupDefinition group;
- context.AllocateGroup(mapper, group);
- context.CheckGroupErasure(group);
-
- TVector<ui32> slots = context.GetSlots();
- UNIT_ASSERT(slots);
- ui32 min = slots[0];
- ui32 max = slots[0];
- for (size_t i = 1; i < slots.size(); ++i) {
- min = Min(min, slots[i]);
- max = Max(max, slots[i]);
- }
- UNIT_ASSERT_C(max - min <= 1, Sprintf("min# %" PRIu32 " max# %" PRIu32, min, max));
- }
- TVector<ui32> slots = context.GetSlots();
- for (ui32 numSlots : slots) {
- UNIT_ASSERT_VALUES_EQUAL(9, numSlots);
- }
- }
-
- Y_UNIT_TEST(MakeDisksUnusable) {
- TTestContext context(1, 1, 10, 1, 1);
- TVector<ui32> groupIds;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, 8);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
- TGroupMapper::TGroupDefinition group;
- ui32 groupId = context.AllocateGroup(mapper, group);
- groupIds.push_back(groupId);
+ TGroupMapper::TGroupDefinition group;
+ context.AllocateGroup(mapper, group);
+ context.CheckGroupErasure(group);
+
+ TVector<ui32> slots = context.GetSlots();
+ UNIT_ASSERT(slots);
+ ui32 min = slots[0];
+ ui32 max = slots[0];
+ for (size_t i = 1; i < slots.size(); ++i) {
+ min = Min(min, slots[i]);
+ max = Max(max, slots[i]);
+ }
+ UNIT_ASSERT_C(max - min <= 1, Sprintf("min# %" PRIu32 " max# %" PRIu32, min, max));
+ }
+ TVector<ui32> slots = context.GetSlots();
+ for (ui32 numSlots : slots) {
+ UNIT_ASSERT_VALUES_EQUAL(9, numSlots);
+ }
+ }
+
+ Y_UNIT_TEST(MakeDisksUnusable) {
+ TTestContext context(1, 1, 10, 1, 1);
+ TVector<ui32> groupIds;
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, 8);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ ui32 groupId = context.AllocateGroup(mapper, group);
+ groupIds.push_back(groupId);
Ctest << "groupId# " << groupId << " content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- context.ReallocateGroup(mapper, groupId, {});
- }
- }
+ context.CheckGroupErasure(group);
+ context.ReallocateGroup(mapper, groupId, {});
+ }
+ }
Ctest << "remapping disks" << Endl;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- TSet<TPDiskId> unusableDisks;
- context.IterateGroups([&](const auto& pdisks) {
- for (const TPDiskId& pdiskId : pdisks) {
- if (unusableDisks.size() < 2) {
- if (unusableDisks.insert(pdiskId).second) {
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ TSet<TPDiskId> unusableDisks;
+ context.IterateGroups([&](const auto& pdisks) {
+ for (const TPDiskId& pdiskId : pdisks) {
+ if (unusableDisks.size() < 2) {
+ if (unusableDisks.insert(pdiskId).second) {
Ctest << "making unusable disk# " << pdiskId.ToString() << Endl;
- }
- }
- }
- });
- context.PopulateGroupMapper(mapper, 10, unusableDisks);
- for (ui32 groupId : groupIds) {
- auto group = context.ReallocateGroup(mapper, groupId, unusableDisks);
+ }
+ }
+ }
+ });
+ context.PopulateGroupMapper(mapper, 10, unusableDisks);
+ for (ui32 groupId : groupIds) {
+ auto group = context.ReallocateGroup(mapper, groupId, unusableDisks);
Ctest << "groupId# " << groupId << " new content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- }
- }
- }
-
- Y_UNIT_TEST(MakeDisksNonoperational) {
- TTestContext context(1, 1, 10, 1, 1);
- TVector<ui32> groupIds;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, 8);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
- TGroupMapper::TGroupDefinition group;
- ui32 groupId = context.AllocateGroup(mapper, group);
- groupIds.push_back(groupId);
- Ctest << "groupId# " << groupId << " content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- context.ReallocateGroup(mapper, groupId, {});
- }
- }
- Ctest << "remapping disks" << Endl;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- TSet<TPDiskId> unusableDisks, nonoperationalDisks;
- context.IterateGroups([&](const auto& pdisks) {
- for (const TPDiskId& pdiskId : pdisks) {
- if (unusableDisks.size() < 2) {
- if (unusableDisks.insert(pdiskId).second) {
- Ctest << "making unusable disk# " << pdiskId.ToString() << Endl;
- continue;
- }
- }
- }
- });
- context.IteratePDisks([&](const auto& pdiskId, const auto&) {
- nonoperationalDisks.insert(pdiskId);
- });
- context.PopulateGroupMapper(mapper, 10, unusableDisks, nonoperationalDisks);
- for (ui32 groupId : groupIds) {
- auto group = context.ReallocateGroup(mapper, groupId, unusableDisks, true, true);
- group = context.ReallocateGroup(mapper, groupId, unusableDisks);
- Ctest << "groupId# " << groupId << " new content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- }
- }
- }
-
- Y_UNIT_TEST(MakeDisksForbidden) {
- TTestContext context(1, 1, 10, 1, 1);
- TVector<ui32> groupIds;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, 8);
- for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
- TGroupMapper::TGroupDefinition group;
- ui32 groupId = context.AllocateGroup(mapper, group);
- groupIds.push_back(groupId);
- Ctest << "groupId# " << groupId << " content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- context.ReallocateGroup(mapper, groupId, {});
- }
- }
- Ctest << "remapping disks" << Endl;
- {
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
- TSet<TPDiskId> unusableDisks;
- context.IterateGroups([&](const auto& pdisks) {
- for (const TPDiskId& pdiskId : pdisks) {
- if (unusableDisks.size() < 2) {
- if (unusableDisks.insert(pdiskId).second) {
- Ctest << "making unusable disk# " << pdiskId.ToString() << Endl;
- }
- }
- }
- });
- context.PopulateGroupMapper(mapper, 10, {});
- for (ui32 groupId : groupIds) {
- auto group = context.ReallocateGroup(mapper, groupId, unusableDisks, true);
- Ctest << "groupId# " << groupId << " new content# " << context.FormatGroup(group) << Endl;
- context.CheckGroupErasure(group);
- }
- }
- }
-
- Y_UNIT_TEST(MonteCarlo) {
- auto rand = [](ui32 min, ui32 max) {
- return min + RandomNumber(max - min + 1);
- };
- for (size_t k = 0; k < 1000; ++k) {
- std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
-
- const ui32 numDisks = rand(2, 4);
- ui32 numDataCenters = rand(1, 3);
- for (ui32 dataCenter = 1; dataCenter <= numDataCenters; ++dataCenter) {
- const ui32 room = 1;
- ui32 numRacks = rand(8, 12);
- for (ui32 rack = 1; rack <= numRacks; ++rack) {
- ui32 numBodies = rand(3, 5);
- for (ui32 body = 1; body <= numBodies; ++body) {
- disks.emplace_back(dataCenter, room, rack, body, numDisks);
- }
- }
- }
-
+ context.CheckGroupErasure(group);
+ }
+ }
+ }
+
+ Y_UNIT_TEST(MakeDisksNonoperational) {
+ TTestContext context(1, 1, 10, 1, 1);
+ TVector<ui32> groupIds;
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, 8);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ ui32 groupId = context.AllocateGroup(mapper, group);
+ groupIds.push_back(groupId);
+ Ctest << "groupId# " << groupId << " content# " << context.FormatGroup(group) << Endl;
+ context.CheckGroupErasure(group);
+ context.ReallocateGroup(mapper, groupId, {});
+ }
+ }
+ Ctest << "remapping disks" << Endl;
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ TSet<TPDiskId> unusableDisks, nonoperationalDisks;
+ context.IterateGroups([&](const auto& pdisks) {
+ for (const TPDiskId& pdiskId : pdisks) {
+ if (unusableDisks.size() < 2) {
+ if (unusableDisks.insert(pdiskId).second) {
+ Ctest << "making unusable disk# " << pdiskId.ToString() << Endl;
+ continue;
+ }
+ }
+ }
+ });
+ context.IteratePDisks([&](const auto& pdiskId, const auto&) {
+ nonoperationalDisks.insert(pdiskId);
+ });
+ context.PopulateGroupMapper(mapper, 10, unusableDisks, nonoperationalDisks);
+ for (ui32 groupId : groupIds) {
+ auto group = context.ReallocateGroup(mapper, groupId, unusableDisks, true, true);
+ group = context.ReallocateGroup(mapper, groupId, unusableDisks);
+ Ctest << "groupId# " << groupId << " new content# " << context.FormatGroup(group) << Endl;
+ context.CheckGroupErasure(group);
+ }
+ }
+ }
+
+ Y_UNIT_TEST(MakeDisksForbidden) {
+ TTestContext context(1, 1, 10, 1, 1);
+ TVector<ui32> groupIds;
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, 8);
+ for (ui32 i = 0; i < context.GetTotalDisks(); ++i) {
+ TGroupMapper::TGroupDefinition group;
+ ui32 groupId = context.AllocateGroup(mapper, group);
+ groupIds.push_back(groupId);
+ Ctest << "groupId# " << groupId << " content# " << context.FormatGroup(group) << Endl;
+ context.CheckGroupErasure(group);
+ context.ReallocateGroup(mapper, groupId, {});
+ }
+ }
+ Ctest << "remapping disks" << Endl;
+ {
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(TBlobStorageGroupType::Erasure4Plus2Block));
+ TSet<TPDiskId> unusableDisks;
+ context.IterateGroups([&](const auto& pdisks) {
+ for (const TPDiskId& pdiskId : pdisks) {
+ if (unusableDisks.size() < 2) {
+ if (unusableDisks.insert(pdiskId).second) {
+ Ctest << "making unusable disk# " << pdiskId.ToString() << Endl;
+ }
+ }
+ }
+ });
+ context.PopulateGroupMapper(mapper, 10, {});
+ for (ui32 groupId : groupIds) {
+ auto group = context.ReallocateGroup(mapper, groupId, unusableDisks, true);
+ Ctest << "groupId# " << groupId << " new content# " << context.FormatGroup(group) << Endl;
+ context.CheckGroupErasure(group);
+ }
+ }
+ }
+
+ Y_UNIT_TEST(MonteCarlo) {
+ auto rand = [](ui32 min, ui32 max) {
+ return min + RandomNumber(max - min + 1);
+ };
+ for (size_t k = 0; k < 1000; ++k) {
+ std::vector<std::tuple<ui32, ui32, ui32, ui32, ui32>> disks;
+
+ const ui32 numDisks = rand(2, 4);
+ ui32 numDataCenters = rand(1, 3);
+ for (ui32 dataCenter = 1; dataCenter <= numDataCenters; ++dataCenter) {
+ const ui32 room = 1;
+ ui32 numRacks = rand(8, 12);
+ for (ui32 rack = 1; rack <= numRacks; ++rack) {
+ ui32 numBodies = rand(3, 5);
+ for (ui32 body = 1; body <= numBodies; ++body) {
+ disks.emplace_back(dataCenter, room, rack, body, numDisks);
+ }
+ }
+ }
+
Ctest << "iteration# " << k << " numBodies# " << disks.size() << " numDisks# " << numDisks << Endl;
- const ui32 maxSlots = 16;
- TTestContext context(std::move(disks));
- context.IteratePDisks([&](auto&, auto& v) {
- v.NumSlots = rand(0, maxSlots);
- });
- for (;;) {
+ const ui32 maxSlots = 16;
+ TTestContext context(std::move(disks));
+ context.IteratePDisks([&](auto&, auto& v) {
+ v.NumSlots = rand(0, maxSlots);
+ });
+ for (;;) {
Ctest << "spawning new mapper" << Endl;
- TGroupMapper mapper(TTestContext::CreateGroupGeometry(numDataCenters >= 3
- ? TBlobStorageGroupType::ErasureMirror3dc
- : TBlobStorageGroupType::Erasure4Plus2Block));
- context.PopulateGroupMapper(mapper, maxSlots);
- TGroupMapper::TGroupDefinition group;
- while (context.AllocateGroup(mapper, group, true)) {
- group.clear();
- if (rand(0, 99) < 5) {
- goto next_cycle;
- }
- }
- break;
- next_cycle:;
- }
- }
- }
-
-}
+ TGroupMapper mapper(TTestContext::CreateGroupGeometry(numDataCenters >= 3
+ ? TBlobStorageGroupType::ErasureMirror3dc
+ : TBlobStorageGroupType::Erasure4Plus2Block));
+ context.PopulateGroupMapper(mapper, maxSlots);
+ TGroupMapper::TGroupDefinition group;
+ while (context.AllocateGroup(mapper, group, true)) {
+ group.clear();
+ if (rand(0, 99) < 5) {
+ goto next_cycle;
+ }
+ }
+ break;
+ next_cycle:;
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/mind/bscontroller/group_reconfigure_wipe.cpp b/ydb/core/mind/bscontroller/group_reconfigure_wipe.cpp
index b3bf230de82..f6ec3802bba 100644
--- a/ydb/core/mind/bscontroller/group_reconfigure_wipe.cpp
+++ b/ydb/core/mind/bscontroller/group_reconfigure_wipe.cpp
@@ -1,93 +1,93 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxGroupReconfigureWipe : public TTransactionBase<TBlobStorageController> {
-protected:
- TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr Event;
- NKikimrProto::EReplyStatus Status;
- TString ErrorReason;
- typedef TMap<TNodeId, THolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>> TResultForNode;
- TResultForNode ResultForNode;
-
-public:
- TTxGroupReconfigureWipe(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr &ev,
- TBlobStorageController *controller)
- : TBase(controller)
- , Event(ev)
- , Status(NKikimrProto::OK)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_GROUP_RECONFIGURE_WIPE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGRW01, "TTxGroupReconfigureWipe execute");
- NIceDb::TNiceDb db(txc.DB);
-
- Status = NKikimrProto::ERROR;
- ResultForNode.clear();
-
- auto& record = Event->Get()->Record;
- const TVSlotId id(record.GetVSlotId());
-
- if (TVSlotInfo *info = Self->FindVSlot(id); !info) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW02, "VSlot does not exist", (VSlotId, id));
- ErrorReason = TStringBuilder() << "VSlotId# " << id << " does not exist";
- } else if (info->Mood != TMood::Normal) { // Reply ERROR if From VSlot is improper mood
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW03, "VSlot is not in the 'Normal' mood", (VSlotId, id),
- (Mood, TMood::Name(TMood::EValue(info->Mood))));
- ErrorReason = TStringBuilder() << "VSlotId# " << id << " is in Mood# " << TMood::Name(TMood::EValue(info->Mood));
- } else {
- // TODO(cthulhu): Prohibit more than Max simultaneous reconfigurations on one group
-
- // Mark VSlot for wipe
- info->Mood = TMood::Wipe;
- db.Table<Schema::VSlot>().Key(id.GetKey()).Update<Schema::VSlot::Mood>(info->Mood);
-
- // Prepare results for nodes
- if (TNodeInfo *node = Self->FindNode(id.NodeId); node && node->IsRegistered) {
- auto& msg = ResultForNode[id.NodeId];
- msg = MakeHolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, id.NodeId);
- Self->ReadVSlot(*info, msg.Get());
- TSet<ui32> groupIDsToRead;
- groupIDsToRead.insert(info->GroupId);
- Self->ReadGroups(groupIDsToRead, false, msg.Get());
- for (const TGroupId groupId : groupIDsToRead) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW05, "No configuration for group", (GroupId, groupId));
- }
- }
-
- Status = NKikimrProto::OK;
- }
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- // Send results to nodes
- if (Status == NKikimrProto::OK) {
- for (auto& [nodeId, msg] : ResultForNode) {
- // TODO(cthulhu): Availability Domain !!!
- const auto& node = nodeId;
- const auto& record = msg->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGRW07, "Sending update", (NodeId, node), (Message, record));
- TActivationContext::Send(new IEventHandle(MakeBlobStorageNodeWardenID(nodeId), Self->SelfId(), msg.Release()));
- }
- }
-
- // Respond
- auto response = MakeHolder<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(Status, ErrorReason);
- auto& record = Event->Get()->Record;
- STLOG(Status == NKikimrProto::OK ? PRI_DEBUG : PRI_ERROR, BS_CONTROLLER, BSCTXGRW06, "TTxGroupReconfigureWipe complete",
- (Status, Status), (Request, record), (Response, response->Record));
- TActivationContext::Send(new IEventHandle(Event->Sender, Self->SelfId(), response.Release(), 0, Event->Cookie));
- }
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr& ev) {
- Execute(new TTxGroupReconfigureWipe(ev, this));
-}
-
-}
-}
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxGroupReconfigureWipe : public TTransactionBase<TBlobStorageController> {
+protected:
+ TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr Event;
+ NKikimrProto::EReplyStatus Status;
+ TString ErrorReason;
+ typedef TMap<TNodeId, THolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>> TResultForNode;
+ TResultForNode ResultForNode;
+
+public:
+ TTxGroupReconfigureWipe(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr &ev,
+ TBlobStorageController *controller)
+ : TBase(controller)
+ , Event(ev)
+ , Status(NKikimrProto::OK)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_GROUP_RECONFIGURE_WIPE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGRW01, "TTxGroupReconfigureWipe execute");
+ NIceDb::TNiceDb db(txc.DB);
+
+ Status = NKikimrProto::ERROR;
+ ResultForNode.clear();
+
+ auto& record = Event->Get()->Record;
+ const TVSlotId id(record.GetVSlotId());
+
+ if (TVSlotInfo *info = Self->FindVSlot(id); !info) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW02, "VSlot does not exist", (VSlotId, id));
+ ErrorReason = TStringBuilder() << "VSlotId# " << id << " does not exist";
+ } else if (info->Mood != TMood::Normal) { // Reply ERROR if From VSlot is improper mood
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW03, "VSlot is not in the 'Normal' mood", (VSlotId, id),
+ (Mood, TMood::Name(TMood::EValue(info->Mood))));
+ ErrorReason = TStringBuilder() << "VSlotId# " << id << " is in Mood# " << TMood::Name(TMood::EValue(info->Mood));
+ } else {
+ // TODO(cthulhu): Prohibit more than Max simultaneous reconfigurations on one group
+
+ // Mark VSlot for wipe
+ info->Mood = TMood::Wipe;
+ db.Table<Schema::VSlot>().Key(id.GetKey()).Update<Schema::VSlot::Mood>(info->Mood);
+
+ // Prepare results for nodes
+ if (TNodeInfo *node = Self->FindNode(id.NodeId); node && node->IsRegistered) {
+ auto& msg = ResultForNode[id.NodeId];
+ msg = MakeHolder<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, id.NodeId);
+ Self->ReadVSlot(*info, msg.Get());
+ TSet<ui32> groupIDsToRead;
+ groupIDsToRead.insert(info->GroupId);
+ Self->ReadGroups(groupIDsToRead, false, msg.Get());
+ for (const TGroupId groupId : groupIDsToRead) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXGRW05, "No configuration for group", (GroupId, groupId));
+ }
+ }
+
+ Status = NKikimrProto::OK;
+ }
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ // Send results to nodes
+ if (Status == NKikimrProto::OK) {
+ for (auto& [nodeId, msg] : ResultForNode) {
+ // TODO(cthulhu): Availability Domain !!!
+ const auto& node = nodeId;
+ const auto& record = msg->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXGRW07, "Sending update", (NodeId, node), (Message, record));
+ TActivationContext::Send(new IEventHandle(MakeBlobStorageNodeWardenID(nodeId), Self->SelfId(), msg.Release()));
+ }
+ }
+
+ // Respond
+ auto response = MakeHolder<TEvBlobStorage::TEvControllerGroupReconfigureWipeResult>(Status, ErrorReason);
+ auto& record = Event->Get()->Record;
+ STLOG(Status == NKikimrProto::OK ? PRI_DEBUG : PRI_ERROR, BS_CONTROLLER, BSCTXGRW06, "TTxGroupReconfigureWipe complete",
+ (Status, Status), (Request, record), (Response, response->Record));
+ TActivationContext::Send(new IEventHandle(Event->Sender, Self->SelfId(), response.Release(), 0, Event->Cookie));
+ }
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr& ev) {
+ Execute(new TTxGroupReconfigureWipe(ev, this));
+}
+
+}
+}
diff --git a/ydb/core/mind/bscontroller/grouper.cpp b/ydb/core/mind/bscontroller/grouper.cpp
index db44d16898d..04220f9e6ef 100644
--- a/ydb/core/mind/bscontroller/grouper.cpp
+++ b/ydb/core/mind/bscontroller/grouper.cpp
@@ -1,363 +1,363 @@
-#include "grouper.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-TCandidate::TCandidate(TFailDomain failDomain, ui8 beginLevel, ui8 lastLevel, ui32 badness, ui32 nodeId, ui32 pDiskId,
- ui32 vDiskSlotId)
- : FailDomain(failDomain)
- , Badness(badness)
- , NodeId(nodeId)
- , PDiskId(pDiskId)
- , VDiskSlotId(vDiskSlotId)
-{
- TFailDomain::TLevels::iterator a = failDomain.Levels.begin();
- while (a != failDomain.Levels.end()) {
- if (a->first < beginLevel) {
- PrefixFailDomain.Levels[a->first] = a->second;
- ++a;
- } else if (a->first <= lastLevel) {
- InfixFailDomain.Levels[a->first] = a->second;
- ++a;
- } else {
- PostfixFailDomain.Levels[a->first] = a->second;
- ++a;
- }
- }
-}
-
-struct TGrouper {
- struct TCandidateSet {
+#include "grouper.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+TCandidate::TCandidate(TFailDomain failDomain, ui8 beginLevel, ui8 lastLevel, ui32 badness, ui32 nodeId, ui32 pDiskId,
+ ui32 vDiskSlotId)
+ : FailDomain(failDomain)
+ , Badness(badness)
+ , NodeId(nodeId)
+ , PDiskId(pDiskId)
+ , VDiskSlotId(vDiskSlotId)
+{
+ TFailDomain::TLevels::iterator a = failDomain.Levels.begin();
+ while (a != failDomain.Levels.end()) {
+ if (a->first < beginLevel) {
+ PrefixFailDomain.Levels[a->first] = a->second;
+ ++a;
+ } else if (a->first <= lastLevel) {
+ InfixFailDomain.Levels[a->first] = a->second;
+ ++a;
+ } else {
+ PostfixFailDomain.Levels[a->first] = a->second;
+ ++a;
+ }
+ }
+}
+
+struct TGrouper {
+ struct TCandidateSet {
typedef TVector<const TCandidate*> TGroupFailDomain;
- struct TGroup {
+ struct TGroup {
TVector<TGroupFailDomain> Domains;
- ui32 FullDomainCount;
-
- TGroup()
- : FullDomainCount(0)
- {}
- };
+ ui32 FullDomainCount;
+
+ TGroup()
+ : FullDomainCount(0)
+ {}
+ };
typedef TMap<TFailDomain, TGroup> TGroupMap;
-
- TGroupMap CandidatesMap;
- TGroup *LastGroup;
-
- TCandidateSet()
- : LastGroup(nullptr)
- {}
-
- bool IsEmpty() const {
- return (LastGroup == nullptr);
- }
-
- bool Insert(const TFailDomain::TLevelIds &id, const TCandidate *candidate, ui32 domainCount,
- ui32 candidatePerDomainCount) {
- // Candidates may belong to more than 1 equiv. class!
- // Store several sets of candidates, attempt adding to each one.
- TGroup &group = CandidatesMap[candidate->PrefixFailDomain];
- i32 matchingGroupDomainIdx = -1;
- for (size_t domainIdx = 0; domainIdx < group.Domains.size(); ++domainIdx) {
- TGroupFailDomain &domain = group.Domains[domainIdx];
- bool isColliding = false;
- for (size_t i = 0; i < domain.size(); ++i) {
- if (!domain[i]->InfixFailDomain.IsDifferentAt(id, candidate->InfixFailDomain)) {
- isColliding = true;
- break;
- }
- }
- if (isColliding) {
- if (matchingGroupDomainIdx == -1 && group.Domains[domainIdx].size() < candidatePerDomainCount) {
- matchingGroupDomainIdx = (i32)domainIdx;
- } else {
- return false;
- }
- }
- }
-
- if (matchingGroupDomainIdx < 0) {
- group.Domains.emplace_back();
- matchingGroupDomainIdx = (i32)group.Domains.size() - 1;
- //Cout << "push group " << matchingGroupDomainIdx << " back" << Endl;
- }
-
- //Cout << "push candidate " << group.Domains[matchingGroupDomainIdx].size();
- //Cout << " to " << matchingGroupDomainIdx << " back" << Endl;
- group.Domains[matchingGroupDomainIdx].push_back(candidate);
- if (group.Domains[matchingGroupDomainIdx].size() == candidatePerDomainCount) {
- ++group.FullDomainCount;
- };
- LastGroup = &group;
- return (group.FullDomainCount == domainCount);
- }
-
- void GetLastGroup(ui32 domainCount, ui32 candidatePerDomainCount,
+
+ TGroupMap CandidatesMap;
+ TGroup *LastGroup;
+
+ TCandidateSet()
+ : LastGroup(nullptr)
+ {}
+
+ bool IsEmpty() const {
+ return (LastGroup == nullptr);
+ }
+
+ bool Insert(const TFailDomain::TLevelIds &id, const TCandidate *candidate, ui32 domainCount,
+ ui32 candidatePerDomainCount) {
+ // Candidates may belong to more than 1 equiv. class!
+ // Store several sets of candidates, attempt adding to each one.
+ TGroup &group = CandidatesMap[candidate->PrefixFailDomain];
+ i32 matchingGroupDomainIdx = -1;
+ for (size_t domainIdx = 0; domainIdx < group.Domains.size(); ++domainIdx) {
+ TGroupFailDomain &domain = group.Domains[domainIdx];
+ bool isColliding = false;
+ for (size_t i = 0; i < domain.size(); ++i) {
+ if (!domain[i]->InfixFailDomain.IsDifferentAt(id, candidate->InfixFailDomain)) {
+ isColliding = true;
+ break;
+ }
+ }
+ if (isColliding) {
+ if (matchingGroupDomainIdx == -1 && group.Domains[domainIdx].size() < candidatePerDomainCount) {
+ matchingGroupDomainIdx = (i32)domainIdx;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ if (matchingGroupDomainIdx < 0) {
+ group.Domains.emplace_back();
+ matchingGroupDomainIdx = (i32)group.Domains.size() - 1;
+ //Cout << "push group " << matchingGroupDomainIdx << " back" << Endl;
+ }
+
+ //Cout << "push candidate " << group.Domains[matchingGroupDomainIdx].size();
+ //Cout << " to " << matchingGroupDomainIdx << " back" << Endl;
+ group.Domains[matchingGroupDomainIdx].push_back(candidate);
+ if (group.Domains[matchingGroupDomainIdx].size() == candidatePerDomainCount) {
+ ++group.FullDomainCount;
+ };
+ LastGroup = &group;
+ return (group.FullDomainCount == domainCount);
+ }
+
+ void GetLastGroup(ui32 domainCount, ui32 candidatePerDomainCount,
TVector<TVector<const TCandidate*>> &outGroup) {
- outGroup.resize(domainCount);
- size_t writeDomainIdx = 0;
- for (size_t domainIdx = 0; domainIdx < LastGroup->Domains.size(); ++domainIdx) {
- if (LastGroup->Domains[domainIdx].size() == candidatePerDomainCount) {
- outGroup[writeDomainIdx] = LastGroup->Domains[domainIdx];
- ++writeDomainIdx;
- }
- }
- return;
- }
- };
-
+ outGroup.resize(domainCount);
+ size_t writeDomainIdx = 0;
+ for (size_t domainIdx = 0; domainIdx < LastGroup->Domains.size(); ++domainIdx) {
+ if (LastGroup->Domains[domainIdx].size() == candidatePerDomainCount) {
+ outGroup[writeDomainIdx] = LastGroup->Domains[domainIdx];
+ ++writeDomainIdx;
+ }
+ }
+ return;
+ }
+ };
+
TMap<TFailDomain::TLevelIds, TCandidateSet> Maps;
TVector<TMap<TFailDomain::TLevelIds, TCandidateSet>::iterator> SetsToPopulate;
- ui32 DomainCount;
- ui32 CandidatePerDomainCount;
- bool IsBingo;
-
+ ui32 DomainCount;
+ ui32 CandidatePerDomainCount;
+ bool IsBingo;
+
TVector<TVector<const TCandidate*>> *BestGroup;
-
- TGrouper(ui32 domainCount, ui32 candidatesPerDomainCount)
- : DomainCount(domainCount)
- , CandidatePerDomainCount(candidatesPerDomainCount)
- , IsBingo(false)
- , BestGroup(nullptr)
- {}
-
+
+ TGrouper(ui32 domainCount, ui32 candidatesPerDomainCount)
+ : DomainCount(domainCount)
+ , CandidatePerDomainCount(candidatesPerDomainCount)
+ , IsBingo(false)
+ , BestGroup(nullptr)
+ {}
+
bool Populate(TMap<TFailDomain::TLevelIds, TCandidateSet>::iterator it, const TCandidate *candidate) {
- // TODO: Calculate isEmpty and isKeyEqual without creating the intersection.
- TFailDomain::TLevelIds intersection = candidate->InfixFailDomain.Intersect(it->first);
- if (intersection.IsEmpty()) {
- return false;
- }
- bool isKeyEqual = (intersection == it->first);
-
- // Set IsBingo flag and fill on success.
- if (it->second.Insert(intersection, candidate, DomainCount, CandidatePerDomainCount)) {
- IsBingo = true;
- it->second.GetLastGroup(DomainCount, CandidatePerDomainCount, *BestGroup);
- }
-
- return isKeyEqual;
- }
-
- void AddToMaps(const TCandidate *candidate) {
- // Add candidate to all existing sets, while checking for exact match of the keys.
- bool isEqualKeyPresent = false;
+ // TODO: Calculate isEmpty and isKeyEqual without creating the intersection.
+ TFailDomain::TLevelIds intersection = candidate->InfixFailDomain.Intersect(it->first);
+ if (intersection.IsEmpty()) {
+ return false;
+ }
+ bool isKeyEqual = (intersection == it->first);
+
+ // Set IsBingo flag and fill on success.
+ if (it->second.Insert(intersection, candidate, DomainCount, CandidatePerDomainCount)) {
+ IsBingo = true;
+ it->second.GetLastGroup(DomainCount, CandidatePerDomainCount, *BestGroup);
+ }
+
+ return isKeyEqual;
+ }
+
+ void AddToMaps(const TCandidate *candidate) {
+ // Add candidate to all existing sets, while checking for exact match of the keys.
+ bool isEqualKeyPresent = false;
for (TMap<TFailDomain::TLevelIds, TCandidateSet>::iterator it = Maps.begin(); it != Maps.end(); ++it) {
- bool isKeyEqual = Populate(it, candidate);
- if (IsBingo) {
- return;
- }
- isEqualKeyPresent |= isKeyEqual;
- }
- // If there is no such key in the map, generate all intersections.
- if (!isEqualKeyPresent) {
+ bool isKeyEqual = Populate(it, candidate);
+ if (IsBingo) {
+ return;
+ }
+ isEqualKeyPresent |= isKeyEqual;
+ }
+ // If there is no such key in the map, generate all intersections.
+ if (!isEqualKeyPresent) {
TVector<TFailDomain::TLevelIds> newIds;
newIds.reserve(Maps.size());
for (TMap<TFailDomain::TLevelIds, TCandidateSet>::iterator it = Maps.begin(); it != Maps.end(); ++it) {
- newIds.push_back(candidate->InfixFailDomain.Intersect(it->first));
- }
- TFailDomain::TLevelIds idToInsert = candidate->InfixFailDomain.MakeIds();
- Maps[idToInsert];
- for (size_t i = 0; i < newIds.size(); ++i) {
- Maps[newIds[i]];
- }
- // List all empty sets in SetsToPopulate.
+ newIds.push_back(candidate->InfixFailDomain.Intersect(it->first));
+ }
+ TFailDomain::TLevelIds idToInsert = candidate->InfixFailDomain.MakeIds();
+ Maps[idToInsert];
+ for (size_t i = 0; i < newIds.size(); ++i) {
+ Maps[newIds[i]];
+ }
+ // List all empty sets in SetsToPopulate.
for (TMap<TFailDomain::TLevelIds, TCandidateSet>::iterator it = Maps.begin(); it != Maps.end(); ++it) {
- if (it->second.IsEmpty()) {
- SetsToPopulate.push_back(it);
- }
- }
- }
- }
-
- void PopulateSets(const TCandidate* candidate) {
- // Populate all sets listed in SetsToPopulate.
- for (size_t i = 0; i < SetsToPopulate.size(); ++i) {
- Populate(SetsToPopulate[i], candidate);
- if (IsBingo) {
- return;
- }
- }
- }
-
+ if (it->second.IsEmpty()) {
+ SetsToPopulate.push_back(it);
+ }
+ }
+ }
+ }
+
+ void PopulateSets(const TCandidate* candidate) {
+ // Populate all sets listed in SetsToPopulate.
+ for (size_t i = 0; i < SetsToPopulate.size(); ++i) {
+ Populate(SetsToPopulate[i], candidate);
+ if (IsBingo) {
+ return;
+ }
+ }
+ }
+
bool SelectCandidates(const TVector<TCandidate> &candidates, TVector<TVector<const TCandidate*>> &outBestGroup) {
- IsBingo = false;
- BestGroup = &outBestGroup;
-
- Maps.clear();
- SetsToPopulate.clear();
-
- // TODO: Candidates may be required to have a specific prefix.
+ IsBingo = false;
+ BestGroup = &outBestGroup;
+
+ Maps.clear();
+ SetsToPopulate.clear();
+
+ // TODO: Candidates may be required to have a specific prefix.
TVector<const TCandidate*> sortedCandidates(candidates.size());
- for (size_t i = 0; i < candidates.size(); ++i) {
- sortedCandidates[i] = &candidates[i];
- }
- StableSort(sortedCandidates.begin(), sortedCandidates.end(),
- [&](const TCandidate *a, const TCandidate *b) {
- return a->Badness < b->Badness;
- });
-
- for (size_t candidateIdx = 0; candidateIdx < sortedCandidates.size(); ++candidateIdx) {
- AddToMaps(sortedCandidates[candidateIdx]);
- if (IsBingo) {
- return true;
- }
- if (!SetsToPopulate.empty()) {
- for (size_t i = 0; i <= candidateIdx; ++i) {
- PopulateSets(sortedCandidates[i]);
- if (IsBingo) {
- return true;
- }
- }
- SetsToPopulate.clear();
- }
- }
- return false;
- }
-
+ for (size_t i = 0; i < candidates.size(); ++i) {
+ sortedCandidates[i] = &candidates[i];
+ }
+ StableSort(sortedCandidates.begin(), sortedCandidates.end(),
+ [&](const TCandidate *a, const TCandidate *b) {
+ return a->Badness < b->Badness;
+ });
+
+ for (size_t candidateIdx = 0; candidateIdx < sortedCandidates.size(); ++candidateIdx) {
+ AddToMaps(sortedCandidates[candidateIdx]);
+ if (IsBingo) {
+ return true;
+ }
+ if (!SetsToPopulate.empty()) {
+ for (size_t i = 0; i <= candidateIdx; ++i) {
+ PopulateSets(sortedCandidates[i]);
+ if (IsBingo) {
+ return true;
+ }
+ }
+ SetsToPopulate.clear();
+ }
+ }
+ return false;
+ }
+
bool VerifyGroup(const TVector<TVector<const TCandidate*>> &group) const {
- if (group.size() != DomainCount) {
- Cout << "a" << Endl;
- return false;
- }
- for (ui32 aDomainIdx = 0; aDomainIdx < DomainCount; ++aDomainIdx) {
- if (group[aDomainIdx].size() != CandidatePerDomainCount) {
- Cout << "aDomainIdx = " << aDomainIdx << " size = " << group[aDomainIdx].size() << Endl;
- return false;
- }
- }
- for (ui32 aDomainIdx = 0; aDomainIdx < DomainCount; ++aDomainIdx) {
- for (ui32 aIdx = 0; aIdx < CandidatePerDomainCount; ++aIdx) {
- const TCandidate *a = group[aDomainIdx][aIdx];
- for (ui32 bIdx = aIdx + 1; bIdx < CandidatePerDomainCount; ++bIdx) {
- const TCandidate *b = group[aDomainIdx][bIdx];
- if (a == b) {
- Cout << "c" << Endl;
- return false;
- }
- }
- for (ui32 bDomainIdx = aDomainIdx + 1; bDomainIdx < DomainCount; ++bDomainIdx) {
- for (ui32 bIdx = 0; bIdx < CandidatePerDomainCount; ++bIdx) {
- const TCandidate *b = group[bDomainIdx][bIdx];
- if (!a->PrefixFailDomain.IsEqual(b->PrefixFailDomain)) {
- Cout << "d" << Endl;
- return false;
- }
- if (a->InfixFailDomain.IsColliding(b->InfixFailDomain)) {
- Cout << "e" << Endl;
- return false;
- }
- }
- }
- }
- }
- return true;
- }
-};
-
+ if (group.size() != DomainCount) {
+ Cout << "a" << Endl;
+ return false;
+ }
+ for (ui32 aDomainIdx = 0; aDomainIdx < DomainCount; ++aDomainIdx) {
+ if (group[aDomainIdx].size() != CandidatePerDomainCount) {
+ Cout << "aDomainIdx = " << aDomainIdx << " size = " << group[aDomainIdx].size() << Endl;
+ return false;
+ }
+ }
+ for (ui32 aDomainIdx = 0; aDomainIdx < DomainCount; ++aDomainIdx) {
+ for (ui32 aIdx = 0; aIdx < CandidatePerDomainCount; ++aIdx) {
+ const TCandidate *a = group[aDomainIdx][aIdx];
+ for (ui32 bIdx = aIdx + 1; bIdx < CandidatePerDomainCount; ++bIdx) {
+ const TCandidate *b = group[aDomainIdx][bIdx];
+ if (a == b) {
+ Cout << "c" << Endl;
+ return false;
+ }
+ }
+ for (ui32 bDomainIdx = aDomainIdx + 1; bDomainIdx < DomainCount; ++bDomainIdx) {
+ for (ui32 bIdx = 0; bIdx < CandidatePerDomainCount; ++bIdx) {
+ const TCandidate *b = group[bDomainIdx][bIdx];
+ if (!a->PrefixFailDomain.IsEqual(b->PrefixFailDomain)) {
+ Cout << "d" << Endl;
+ return false;
+ }
+ if (a->InfixFailDomain.IsColliding(b->InfixFailDomain)) {
+ Cout << "e" << Endl;
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+};
+
bool GroupFromCandidates(TVector<TCandidate> &candidates, ui32 domainCount, ui32 candidatesPerDomainCount,
TVector<TVector<const TCandidate*>> &outBestGroup) {
- TGrouper grouper(domainCount, candidatesPerDomainCount);
- return grouper.SelectCandidates(candidates, outBestGroup);
-}
-
+ TGrouper grouper(domainCount, candidatesPerDomainCount);
+ return grouper.SelectCandidates(candidates, outBestGroup);
+}
+
bool VerifyGroup(const TVector<TVector<const TCandidate*>> &group, ui32 domainCount, ui32 candidatesPerDomainCount) {
- TGrouper grouper(domainCount, candidatesPerDomainCount);
- return grouper.VerifyGroup(group);
-}
-
+ TGrouper grouper(domainCount, candidatesPerDomainCount);
+ return grouper.VerifyGroup(group);
+}
+
bool CreateGroupWithRings(const TVector<TCandidate>& candidates, ui32 numRings, ui32 numFailDomainsPerRing,
- ui32 numDisksPerFailDomain, ui32 firstRingDxLevel, ui32 lastRingDxLevel,
+ ui32 numDisksPerFailDomain, ui32 firstRingDxLevel, ui32 lastRingDxLevel,
TVector<TVector<TVector<const TCandidate*>>>& bestGroup) {
- // calculate per-ring map of candidates
+ // calculate per-ring map of candidates
TVector<TString> keys;
TMultiMap<TString, const TCandidate*> perRingMap;
- for (const TCandidate& candidate : candidates) {
- // calculate infix according to ring distinction rules
- TFailDomain infix;
- for (const auto& level : candidate.FailDomain.Levels) {
- if (level.first >= firstRingDxLevel && level.first <= lastRingDxLevel) {
- infix.Levels.insert(level);
- }
- }
-
- // insert key into vector to keep ordering of candidates according to initial sequence
- TString key = infix.SerializeFailDomain();
- if (!perRingMap.count(key)) {
- keys.push_back(key);
- }
-
- perRingMap.emplace(key, &candidate);
- }
-
- // traverse through all rings and create groups for these rings
+ for (const TCandidate& candidate : candidates) {
+ // calculate infix according to ring distinction rules
+ TFailDomain infix;
+ for (const auto& level : candidate.FailDomain.Levels) {
+ if (level.first >= firstRingDxLevel && level.first <= lastRingDxLevel) {
+ infix.Levels.insert(level);
+ }
+ }
+
+ // insert key into vector to keep ordering of candidates according to initial sequence
+ TString key = infix.SerializeFailDomain();
+ if (!perRingMap.count(key)) {
+ keys.push_back(key);
+ }
+
+ perRingMap.emplace(key, &candidate);
+ }
+
+ // traverse through all rings and create groups for these rings
TVector<const TCandidate*> candptr;
TVector<TCandidate> ringCandidates;
bestGroup.reserve(bestGroup.size() + keys.size());
- for (const TString& key : keys) {
- // get candidates for this ring
- auto range = perRingMap.equal_range(key);
- for (auto it = range.first; it != range.second; ++it) {
- candptr.push_back(it->second);
- }
-
- // create vector of candidates to generate fail domain
- for (const TCandidate *ptr : candptr) {
- ringCandidates.push_back(*ptr);
- }
-
- // generate group
+ for (const TString& key : keys) {
+ // get candidates for this ring
+ auto range = perRingMap.equal_range(key);
+ for (auto it = range.first; it != range.second; ++it) {
+ candptr.push_back(it->second);
+ }
+
+ // create vector of candidates to generate fail domain
+ for (const TCandidate *ptr : candptr) {
+ ringCandidates.push_back(*ptr);
+ }
+
+ // generate group
TVector<TVector<const TCandidate*>> failDomain;
- if (!GroupFromCandidates(ringCandidates, numFailDomainsPerRing, numDisksPerFailDomain, failDomain)) {
- return false;
- }
-
- // convert pointers
- for (auto& domain : failDomain) {
- for (auto& item : domain) {
- ui32 index = item - ringCandidates.data();
- item = candptr[index];
- }
- }
-
- bestGroup.push_back(std::move(failDomain));
-
- // clear vectors for next cycle
- candptr.clear();
- ringCandidates.clear();
- }
-
- if (bestGroup.size() < numRings) {
- // there is not enough rings to build up requested group
- return false;
- } else if (bestGroup.size() == numRings) {
- // there is a group of exactly requested rings count
- return true;
- }
-
- // calculate overall badness of all fail domains and delete the worst ones
+ if (!GroupFromCandidates(ringCandidates, numFailDomainsPerRing, numDisksPerFailDomain, failDomain)) {
+ return false;
+ }
+
+ // convert pointers
+ for (auto& domain : failDomain) {
+ for (auto& item : domain) {
+ ui32 index = item - ringCandidates.data();
+ item = candptr[index];
+ }
+ }
+
+ bestGroup.push_back(std::move(failDomain));
+
+ // clear vectors for next cycle
+ candptr.clear();
+ ringCandidates.clear();
+ }
+
+ if (bestGroup.size() < numRings) {
+ // there is not enough rings to build up requested group
+ return false;
+ } else if (bestGroup.size() == numRings) {
+ // there is a group of exactly requested rings count
+ return true;
+ }
+
+ // calculate overall badness of all fail domains and delete the worst ones
TVector<ui32> badness;
badness.reserve(bestGroup.size());
- for (const auto& ring : bestGroup) {
- ui32 sum = 0;
- for (const auto& failDomain : ring) {
- for (const auto& disk : failDomain) {
- sum += disk->Badness;
- }
- }
- badness.push_back(sum);
- }
- while (bestGroup.size() > numRings) {
- ui32 worstIdx = 0;
- for (ui32 i = 1; i < badness.size(); ++i) {
- if (badness[i] > badness[worstIdx]) {
- worstIdx = i;
- }
- }
- badness.erase(badness.begin() + worstIdx);
- bestGroup.erase(bestGroup.begin() + worstIdx);
- }
-
- return true;
-}
-
-} //NBsController
-
-} //NKikimr
+ for (const auto& ring : bestGroup) {
+ ui32 sum = 0;
+ for (const auto& failDomain : ring) {
+ for (const auto& disk : failDomain) {
+ sum += disk->Badness;
+ }
+ }
+ badness.push_back(sum);
+ }
+ while (bestGroup.size() > numRings) {
+ ui32 worstIdx = 0;
+ for (ui32 i = 1; i < badness.size(); ++i) {
+ if (badness[i] > badness[worstIdx]) {
+ worstIdx = i;
+ }
+ }
+ badness.erase(badness.begin() + worstIdx);
+ bestGroup.erase(bestGroup.begin() + worstIdx);
+ }
+
+ return true;
+}
+
+} //NBsController
+
+} //NKikimr
diff --git a/ydb/core/mind/bscontroller/grouper.h b/ydb/core/mind/bscontroller/grouper.h
index d5541986332..2a857ac648d 100644
--- a/ydb/core/mind/bscontroller/grouper.h
+++ b/ydb/core/mind/bscontroller/grouper.h
@@ -1,33 +1,33 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-struct TCandidate {
- TFailDomain FailDomain;
- TFailDomain PrefixFailDomain;
- TFailDomain InfixFailDomain;
- TFailDomain PostfixFailDomain;
- ui32 Badness;
- ui32 NodeId;
- ui32 PDiskId;
- ui32 VDiskSlotId;
-
- TCandidate(TFailDomain failDomain, ui8 beginLevel, ui8 lastLevel, ui32 badness, ui32 nodeId, ui32 pDiskId,
- ui32 vDiskSlotId);
-};
-
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+struct TCandidate {
+ TFailDomain FailDomain;
+ TFailDomain PrefixFailDomain;
+ TFailDomain InfixFailDomain;
+ TFailDomain PostfixFailDomain;
+ ui32 Badness;
+ ui32 NodeId;
+ ui32 PDiskId;
+ ui32 VDiskSlotId;
+
+ TCandidate(TFailDomain failDomain, ui8 beginLevel, ui8 lastLevel, ui32 badness, ui32 nodeId, ui32 pDiskId,
+ ui32 vDiskSlotId);
+};
+
bool GroupFromCandidates(TVector<TCandidate> &candidates, ui32 domainCount, ui32 candidatesPerDomainCount,
TVector<TVector<const TCandidate*>> &outBestGroup);
-
+
bool VerifyGroup(const TVector<TVector<const TCandidate*>> &group, ui32 domainCount, ui32 candidatesPerDomainCount);
-
+
bool CreateGroupWithRings(const TVector<TCandidate>& candidates, ui32 numRings, ui32 numFailDomainsPerRing,
- ui32 numDisksPerFailDomain, ui32 firstRingDxLevel, ui32 lastRingDxLevel,
+ ui32 numDisksPerFailDomain, ui32 firstRingDxLevel, ui32 lastRingDxLevel,
TVector<TVector<TVector<const TCandidate*>>>& bestGroup);
-
-} //NBsController
-
-} //NKikimr
+
+} //NBsController
+
+} //NKikimr
diff --git a/ydb/core/mind/bscontroller/grouper_ut.cpp b/ydb/core/mind/bscontroller/grouper_ut.cpp
index a119ff665ae..1ba82c57ba8 100644
--- a/ydb/core/mind/bscontroller/grouper_ut.cpp
+++ b/ydb/core/mind/bscontroller/grouper_ut.cpp
@@ -1,165 +1,165 @@
-#include "defs.h"
-
+#include "defs.h"
+
#include <library/cpp/actors/util/affinity.h>
#include <library/cpp/svnversion/svnversion.h>
#include <library/cpp/testing/unittest/registar.h>
-
-#include "grouper.h"
-
-namespace NKikimr {
-
-enum ELevel {
- LevelDomain = 50,
- LevelRoom = 75,
- LevelRack = 100,
- LevelServer = 150,
- LevelDrive = 200
-};
-
+
+#include "grouper.h"
+
+namespace NKikimr {
+
+enum ELevel {
+ LevelDomain = 50,
+ LevelRoom = 75,
+ LevelRack = 100,
+ LevelServer = 150,
+ LevelDrive = 200
+};
+
Y_UNIT_TEST_SUITE(TBlobStorageControllerGrouperTest) {
-
- static void construct_group_and_assert_it_is_valid(
+
+ static void construct_group_and_assert_it_is_valid(
TVector<NBsController::TCandidate> candidates,
- const ui32 domainCount,
- const ui32 candidatesPerDomainCount = 1
- ) {
+ const ui32 domainCount,
+ const ui32 candidatesPerDomainCount = 1
+ ) {
TVector<TVector<const NBsController::TCandidate*>> group;
- bool isOk = NBsController::GroupFromCandidates(candidates, domainCount, candidatesPerDomainCount, group);
- UNIT_ASSERT(isOk);
- isOk = NBsController::VerifyGroup(group, domainCount, candidatesPerDomainCount);
- UNIT_ASSERT(isOk);
- }
-
- static void construct_group_and_assert_it_is_NOT_valid(
+ bool isOk = NBsController::GroupFromCandidates(candidates, domainCount, candidatesPerDomainCount, group);
+ UNIT_ASSERT(isOk);
+ isOk = NBsController::VerifyGroup(group, domainCount, candidatesPerDomainCount);
+ UNIT_ASSERT(isOk);
+ }
+
+ static void construct_group_and_assert_it_is_NOT_valid(
TVector<NBsController::TCandidate> candidates,
- const ui32 domainCount,
- const ui32 candidatesPerDomainCount = 1
- ) {
+ const ui32 domainCount,
+ const ui32 candidatesPerDomainCount = 1
+ ) {
TVector<TVector<const NBsController::TCandidate*>> group;
- bool isOk = NBsController::GroupFromCandidates(candidates, domainCount, candidatesPerDomainCount, group);
- UNIT_ASSERT(!isOk);
- }
-
+ bool isOk = NBsController::GroupFromCandidates(candidates, domainCount, candidatesPerDomainCount, group);
+ UNIT_ASSERT(!isOk);
+ }
+
Y_UNIT_TEST(TestGroupFromCandidatesEmpty) {
TVector<NBsController::TCandidate> candidates;
- construct_group_and_assert_it_is_NOT_valid(candidates, 4, 1);
- }
-
+ construct_group_and_assert_it_is_NOT_valid(candidates, 4, 1);
+ }
+
Y_UNIT_TEST(TestGroupFromCandidatesTrivial) {
- ui32 nodeId = 0;
- ui32 pDiskId = 0;
- ui32 badness = 0;
- const ui32 vDiskSlotId = 1;
+ ui32 nodeId = 0;
+ ui32 pDiskId = 0;
+ ui32 badness = 0;
+ const ui32 vDiskSlotId = 1;
TVector<NBsController::TCandidate> candidates;
- for (ui32 rackIdx = 0; rackIdx < 4; ++rackIdx) {
- TFailDomain failDomain;
- failDomain.Levels[LevelRack] = rackIdx;
- candidates.push_back(NBsController::TCandidate(failDomain, LevelDomain, LevelDrive,
- badness, nodeId, pDiskId, vDiskSlotId));
- ++badness;
- ++nodeId;
- ++pDiskId;
- }
-
- // Assert
- construct_group_and_assert_it_is_valid(candidates, 4);
- }
-
+ for (ui32 rackIdx = 0; rackIdx < 4; ++rackIdx) {
+ TFailDomain failDomain;
+ failDomain.Levels[LevelRack] = rackIdx;
+ candidates.push_back(NBsController::TCandidate(failDomain, LevelDomain, LevelDrive,
+ badness, nodeId, pDiskId, vDiskSlotId));
+ ++badness;
+ ++nodeId;
+ ++pDiskId;
+ }
+
+ // Assert
+ construct_group_and_assert_it_is_valid(candidates, 4);
+ }
+
Y_UNIT_TEST(TestGroupFromCandidatesHuge) {
- ui32 nodeId = 0;
- const ui32 vDiskSlotId = 1;
-
+ ui32 nodeId = 0;
+ const ui32 vDiskSlotId = 1;
+
TVector<NBsController::TCandidate> candidates;
- for (ui32 domainIdx = 0; domainIdx < 3; ++domainIdx) {
- for (ui32 roomIdx = 0; roomIdx < 10; ++roomIdx) {
- for (ui32 rackIdx = 0; rackIdx < 8; ++rackIdx) {
- for (ui32 serverIdx = 0; serverIdx < 16; ++serverIdx) {
- ui32 pDiskId = 0;
- for (ui32 driveIdx = 0; driveIdx < 6; ++driveIdx) {
- TFailDomain failDomain;
- failDomain.Levels[LevelDomain] = domainIdx;
- failDomain.Levels[LevelRoom] = roomIdx;
- failDomain.Levels[LevelRack] = rackIdx;
- failDomain.Levels[LevelServer] = serverIdx;
- failDomain.Levels[LevelDrive] = driveIdx;
- candidates.push_back(NBsController::TCandidate(failDomain, LevelRack, LevelRack,
- (ui32)rand(), nodeId, pDiskId, vDiskSlotId));
- ++nodeId;
- ++pDiskId;
- }
- }
- }
- }
- }
-
- // Assert
- construct_group_and_assert_it_is_valid(candidates, 8, 4);
- construct_group_and_assert_it_is_NOT_valid(candidates, 9, 4);
- }
-
+ for (ui32 domainIdx = 0; domainIdx < 3; ++domainIdx) {
+ for (ui32 roomIdx = 0; roomIdx < 10; ++roomIdx) {
+ for (ui32 rackIdx = 0; rackIdx < 8; ++rackIdx) {
+ for (ui32 serverIdx = 0; serverIdx < 16; ++serverIdx) {
+ ui32 pDiskId = 0;
+ for (ui32 driveIdx = 0; driveIdx < 6; ++driveIdx) {
+ TFailDomain failDomain;
+ failDomain.Levels[LevelDomain] = domainIdx;
+ failDomain.Levels[LevelRoom] = roomIdx;
+ failDomain.Levels[LevelRack] = rackIdx;
+ failDomain.Levels[LevelServer] = serverIdx;
+ failDomain.Levels[LevelDrive] = driveIdx;
+ candidates.push_back(NBsController::TCandidate(failDomain, LevelRack, LevelRack,
+ (ui32)rand(), nodeId, pDiskId, vDiskSlotId));
+ ++nodeId;
+ ++pDiskId;
+ }
+ }
+ }
+ }
+ }
+
+ // Assert
+ construct_group_and_assert_it_is_valid(candidates, 8, 4);
+ construct_group_and_assert_it_is_NOT_valid(candidates, 9, 4);
+ }
+
static TVector<NBsController::TCandidate> create_server(
- const ui32 domainIdx, const ui32 roomIdx, const ui32 rackIdx, const ui32 serverIdx,
+ const ui32 domainIdx, const ui32 roomIdx, const ui32 rackIdx, const ui32 serverIdx,
TVector<std::pair<ui32, ui32>> driveIdx_badness
- ) {
- const ui32 vDiskSlotId = 1;
-
+ ) {
+ const ui32 vDiskSlotId = 1;
+
TVector<NBsController::TCandidate> candidates;
-
- for (auto x: driveIdx_badness) {
- const ui32 driveIdx = x.first;
- const ui32 badness = x.second;
-
- TFailDomain failDomain;
- failDomain.Levels[LevelDomain] = domainIdx;
- failDomain.Levels[LevelRoom] = roomIdx;
- failDomain.Levels[LevelRack] = rackIdx;
- failDomain.Levels[LevelServer] = serverIdx;
- failDomain.Levels[LevelDrive] = driveIdx;
-
- candidates.push_back(
- NBsController::TCandidate(
- failDomain, LevelRack, LevelRack, badness, serverIdx, driveIdx, vDiskSlotId
- )
- );
- }
-
- return candidates;
- }
-
+
+ for (auto x: driveIdx_badness) {
+ const ui32 driveIdx = x.first;
+ const ui32 badness = x.second;
+
+ TFailDomain failDomain;
+ failDomain.Levels[LevelDomain] = domainIdx;
+ failDomain.Levels[LevelRoom] = roomIdx;
+ failDomain.Levels[LevelRack] = rackIdx;
+ failDomain.Levels[LevelServer] = serverIdx;
+ failDomain.Levels[LevelDrive] = driveIdx;
+
+ candidates.push_back(
+ NBsController::TCandidate(
+ failDomain, LevelRack, LevelRack, badness, serverIdx, driveIdx, vDiskSlotId
+ )
+ );
+ }
+
+ return candidates;
+ }
+
Y_UNIT_TEST(when_one_server_per_rack_in_4_racks_then_can_construct_group_with_4_domains) {
TVector<NBsController::TCandidate> candidates;
-
- for (ui32 rackIdx = 0; rackIdx < 4; ++rackIdx) {
- auto s = create_server(1, 1, rackIdx, 1, {{1, 2}});
- std::copy(s.begin(), s.end(), std::back_inserter(candidates));
- }
-
- // Assert
- construct_group_and_assert_it_is_valid(candidates, 4);
- construct_group_and_assert_it_is_NOT_valid(candidates, 4, 2);
- construct_group_and_assert_it_is_NOT_valid(candidates, 4, 3);
- }
-
+
+ for (ui32 rackIdx = 0; rackIdx < 4; ++rackIdx) {
+ auto s = create_server(1, 1, rackIdx, 1, {{1, 2}});
+ std::copy(s.begin(), s.end(), std::back_inserter(candidates));
+ }
+
+ // Assert
+ construct_group_and_assert_it_is_valid(candidates, 4);
+ construct_group_and_assert_it_is_NOT_valid(candidates, 4, 2);
+ construct_group_and_assert_it_is_NOT_valid(candidates, 4, 3);
+ }
+
Y_UNIT_TEST(when_one_server_per_rack_in_4_racks_then_can_construct_group_with_4_domains_and_one_small_node) {
- const ui32 domainIdx = 1;
- const ui32 roomIdx = 0;
-
+ const ui32 domainIdx = 1;
+ const ui32 roomIdx = 0;
+
TVector<NBsController::TCandidate> candidates;
-
- auto s1 = create_server(domainIdx, roomIdx, 1, 1, {{1, 0}});
- auto s2 = create_server(domainIdx, roomIdx, 2, 1, {{2, 0}});
- auto s3 = create_server(domainIdx, roomIdx, 3, 1, {{3, 0}});
- auto s4 = create_server(domainIdx, roomIdx, 4, 1, {{4, 0}});
-
- std::copy(s1.begin(), s1.end(), std::back_inserter(candidates));
- std::copy(s2.begin(), s2.end(), std::back_inserter(candidates));
- std::copy(s3.begin(), s3.end(), std::back_inserter(candidates));
- std::copy(s4.begin(), s4.end(), std::back_inserter(candidates));
-
- // Assert
- construct_group_and_assert_it_is_valid(candidates, 4);
- }
-}
-
-} // namespace NKikimr
-
+
+ auto s1 = create_server(domainIdx, roomIdx, 1, 1, {{1, 0}});
+ auto s2 = create_server(domainIdx, roomIdx, 2, 1, {{2, 0}});
+ auto s3 = create_server(domainIdx, roomIdx, 3, 1, {{3, 0}});
+ auto s4 = create_server(domainIdx, roomIdx, 4, 1, {{4, 0}});
+
+ std::copy(s1.begin(), s1.end(), std::back_inserter(candidates));
+ std::copy(s2.begin(), s2.end(), std::back_inserter(candidates));
+ std::copy(s3.begin(), s3.end(), std::back_inserter(candidates));
+ std::copy(s4.begin(), s4.end(), std::back_inserter(candidates));
+
+ // Assert
+ construct_group_and_assert_it_is_valid(candidates, 4);
+ }
+}
+
+} // namespace NKikimr
+
diff --git a/ydb/core/mind/bscontroller/impl.h b/ydb/core/mind/bscontroller/impl.h
index ba311a254c3..8e81b31b053 100644
--- a/ydb/core/mind/bscontroller/impl.h
+++ b/ydb/core/mind/bscontroller/impl.h
@@ -1,404 +1,404 @@
-#pragma once
-#include "defs.h"
-#include "bsc.h"
-#include "scheme.h"
-#include "mood.h"
-#include "types.h"
-#include "resources.h"
-#include "stat_processor.h"
-#include "indir.h"
-#include "self_heal.h"
-#include "storage_pool_stat.h"
-
-inline IOutputStream& operator <<(IOutputStream& o, NKikimr::TErasureType::EErasureSpecies p) {
- return o << NKikimr::TErasureType::ErasureSpeciesName(p);
-}
-
-namespace NKikimr {
-
-namespace NBsController {
-
-using NTabletFlatExecutor::TTabletExecutedFlat;
+#pragma once
+#include "defs.h"
+#include "bsc.h"
+#include "scheme.h"
+#include "mood.h"
+#include "types.h"
+#include "resources.h"
+#include "stat_processor.h"
+#include "indir.h"
+#include "self_heal.h"
+#include "storage_pool_stat.h"
+
+inline IOutputStream& operator <<(IOutputStream& o, NKikimr::TErasureType::EErasureSpecies p) {
+ return o << NKikimr::TErasureType::ErasureSpeciesName(p);
+}
+
+namespace NKikimr {
+
+namespace NBsController {
+
+using NTabletFlatExecutor::TTabletExecutedFlat;
using NTabletFlatExecutor::ITransaction;
-using NTabletFlatExecutor::TTransactionBase;
-using NTabletFlatExecutor::TTransactionContext;
-
-class TRequestCounter {
- TTabletCountersBase *Counters;
- THPTimer Timer;
- int MicrosecIndex;
-
-public:
- TRequestCounter(TTabletCountersBase *counters, int microsecIndex)
- : Counters(counters)
- , MicrosecIndex(microsecIndex)
- {}
-
- ~TRequestCounter() {
- TDuration passed = TDuration::Seconds(Timer.Passed());
- Counters->Cumulative()[MicrosecIndex].Increment(passed.MicroSeconds());
- }
-};
-
-class TBlobStorageController : public TActor<TBlobStorageController>, public TTabletExecutedFlat {
-public:
- using THostConfigId = Schema::HostConfig::TKey::Type;
- using TBoxId = Schema::Box::TKey::Type;
- using TBoxStoragePoolId = Schema::BoxStoragePool::TKey::Type;
+using NTabletFlatExecutor::TTransactionBase;
+using NTabletFlatExecutor::TTransactionContext;
+
+class TRequestCounter {
+ TTabletCountersBase *Counters;
+ THPTimer Timer;
+ int MicrosecIndex;
+
+public:
+ TRequestCounter(TTabletCountersBase *counters, int microsecIndex)
+ : Counters(counters)
+ , MicrosecIndex(microsecIndex)
+ {}
+
+ ~TRequestCounter() {
+ TDuration passed = TDuration::Seconds(Timer.Passed());
+ Counters->Cumulative()[MicrosecIndex].Increment(passed.MicroSeconds());
+ }
+};
+
+class TBlobStorageController : public TActor<TBlobStorageController>, public TTabletExecutedFlat {
+public:
+ using THostConfigId = Schema::HostConfig::TKey::Type;
+ using TBoxId = Schema::Box::TKey::Type;
+ using TBoxStoragePoolId = Schema::BoxStoragePool::TKey::Type;
using THostId = std::tuple<TString, i32>; // (Host, IcPort) identifier
-
- class TTxInitScheme;
- class TTxMigrate;
- class TTxLoadEverything;
- class TTxMonEvent_OperationLog;
- class TTxMonEvent_HealthEvents;
- class TTxMonEvent_SetDown;
+
+ class TTxInitScheme;
+ class TTxMigrate;
+ class TTxLoadEverything;
+ class TTxMonEvent_OperationLog;
+ class TTxMonEvent_HealthEvents;
+ class TTxMonEvent_SetDown;
class TTxMonEvent_GetDown;
- class TTxUpdateDiskMetrics;
- class TTxUpdateGroupLatencies;
- class TTxGroupReconfigureWipe;
- class TTxNodeReport;
- class TTxUpdateSeenOperational;
- class TTxConfigCmd;
+ class TTxUpdateDiskMetrics;
+ class TTxUpdateGroupLatencies;
+ class TTxGroupReconfigureWipe;
+ class TTxNodeReport;
+ class TTxUpdateSeenOperational;
+ class TTxConfigCmd;
class TTxProposeGroupKey;
- class TTxRegisterNode;
- class TTxGetGroup;
- class TTxRequestControllerInfo;
- class TTxSelectGroups;
- class TTxDropDonor;
- class TTxScrubStart;
- class TTxScrubQuantumFinished;
- class TTxUpdateLastSeenReady;
+ class TTxRegisterNode;
+ class TTxGetGroup;
+ class TTxRequestControllerInfo;
+ class TTxSelectGroups;
+ class TTxDropDonor;
+ class TTxScrubStart;
+ class TTxScrubQuantumFinished;
+ class TTxUpdateLastSeenReady;
class TTxUpdateNodeDrives;
-
- class TVSlotInfo;
- class TPDiskInfo;
- class TGroupInfo;
- class TConfigState;
- class TGroupSelector;
- class TGroupFitter;
-
- using TVSlotReadyTimestampQ = std::list<std::pair<TInstant, TVSlotInfo*>>;
-
- class TVSlotInfo : public TIndirectReferable<TVSlotInfo> {
- public:
- using Table = Schema::VSlot;
-
- const TVSlotId VSlotId;
- TIndirectReferable<TPDiskInfo>::TPtr PDisk; // PDisk this slot resides on
- TGroupId GroupId = 0;
- Table::GroupGeneration::Type GroupPrevGeneration = 0;
- Table::GroupGeneration::Type GroupGeneration = 0;
- Table::Category::Type Kind = NKikimrBlobStorage::TVDiskKind::Default;
- Table::RingIdx::Type RingIdx = 0;
- Table::FailDomainIdx::Type FailDomainIdx = 0;
- Table::VDiskIdx::Type VDiskIdx = 0;
- Table::Mood::Type Mood;
- TIndirectReferable<TGroupInfo>::TPtr Group; // group to which this VSlot belongs (or nullptr if it doesn't belong to any)
- std::vector<std::pair<TVSlotId, TVDiskID>> Donors; // a set of alive donors for this disk
- TVSlotId AcceptorVSlotId;
- TInstant LastSeenReady;
-
- // volatile state
- mutable NKikimrBlobStorage::TVDiskMetrics Metrics;
- mutable bool MetricsDirty = false;
- mutable TResourceRawValues DiskResourceValues;
- mutable TResourceRawValues MaximumResourceValues{
- 1ULL << 40, // 1 TB
- };
-
- // not persistent field; set only when VSlot is scheduled for deletion
- std::optional<TBoxStoragePoolId> DeletedFromStoragePoolId;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VDisk status management
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- private:
- TVSlotReadyTimestampQ& VSlotReadyTimestampQ;
- TVSlotReadyTimestampQ::iterator VSlotReadyTimestampIter;
- NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
-
- // VDisk will be considered READY during this period after reporting its READY state
- static constexpr TDuration ReadyStablePeriod = TDuration::Seconds(15);
-
- public:
- bool IsReady = false;
-
- public:
- void SetStatus(NKikimrBlobStorage::EVDiskStatus status, TInstant now) {
- if (status != Status) {
- Status = status;
- IsReady = false;
- if (status == NKikimrBlobStorage::EVDiskStatus::READY) {
- const TInstant readyAfter = now + ReadyStablePeriod; // vdisk will be treated as READY one shortly, but not now
- Y_VERIFY(VSlotReadyTimestampIter == TVSlotReadyTimestampQ::iterator());
- Y_VERIFY(Group);
- VSlotReadyTimestampIter = VSlotReadyTimestampQ.emplace(VSlotReadyTimestampQ.end(), readyAfter, this);
- } else {
- DropFromVSlotReadyTimestampQ();
- }
- }
- }
-
- void DropFromVSlotReadyTimestampQ() {
- if (VSlotReadyTimestampIter != TVSlotReadyTimestampQ::iterator()) {
- VSlotReadyTimestampQ.erase(VSlotReadyTimestampIter);
- ResetVSlotReadyTimestampIter();
- }
- }
-
- void ResetVSlotReadyTimestampIter() {
- VSlotReadyTimestampIter = {};
- }
-
- NKikimrBlobStorage::EVDiskStatus GetStatus() const {
- return Status;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TVSlotInfo,
- Table::Category,
- Table::GroupID,
- Table::GroupGeneration,
- Table::RingIdx,
- Table::FailDomainIdx,
- Table::VDiskIdx,
- Table::GroupPrevGeneration,
- Table::Mood,
- Table::LastSeenReady
- > adapter(
- &TVSlotInfo::Kind,
- &TVSlotInfo::GroupId,
- &TVSlotInfo::GroupGeneration,
- &TVSlotInfo::RingIdx,
- &TVSlotInfo::FailDomainIdx,
- &TVSlotInfo::VDiskIdx,
- &TVSlotInfo::GroupPrevGeneration,
- &TVSlotInfo::Mood,
- &TVSlotInfo::LastSeenReady
- );
- callback(&adapter);
- }
-
- TVSlotInfo() = delete;
-
- TVSlotInfo(TVSlotId vSlotId, TPDiskInfo *pdisk, TGroupId groupId, Table::GroupGeneration::Type groupPrevGeneration,
- Table::GroupGeneration::Type groupGeneration, Table::Category::Type kind, Table::RingIdx::Type ringIdx,
- Table::FailDomainIdx::Type failDomainIdx, Table::VDiskIdx::Type vDiskIdx, Table::Mood::Type mood,
- TGroupInfo *group, TVSlotReadyTimestampQ *vslotReadyTimestampQ, TInstant lastSeenReady); // implemented in bsc.cpp
-
- // is the slot being deleted (marked as deleted)
- bool IsBeingDeleted() const {
- return Mood == TMood::Delete;
- }
-
- void ScheduleForDeletion(TBoxStoragePoolId deletedFromStoragePoolId) {
- Y_VERIFY(!IsBeingDeleted());
- Mood = TMood::Delete;
- GroupPrevGeneration = std::exchange(GroupGeneration, 0);
- Group = nullptr;
- DeletedFromStoragePoolId = deletedFromStoragePoolId;
- }
-
- void MakeDonorFor(TVSlotInfo *newSlot) {
- Y_VERIFY(newSlot);
- Y_VERIFY(!IsBeingDeleted());
- Mood = TMood::Donor;
- Group = nullptr; // we are not part of this group anymore
- Donors.emplace_back(VSlotId, GetVDiskId());
- newSlot->Donors = std::exchange(Donors, {});
- }
-
- TVDiskID GetVDiskId() const {
- ui32 generation = IsBeingDeleted() // when the slot is scheduled for deletion, its last known generation is
- ? GroupPrevGeneration // stored in GroupPrevGeneration
- : GroupGeneration; // otherwise actual value is held in GroupGeneration
- Y_VERIFY(generation);
- return TVDiskID(GroupId, generation, RingIdx, FailDomainIdx, VDiskIdx);
- }
-
- TVDiskIdShort GetShortVDiskId() const {
- return TVDiskIdShort(RingIdx, FailDomainIdx, VDiskIdx);
- }
-
- bool IsSameVDisk(const TVDiskID &id) {
- return (GroupId == id.GroupID &&
- RingIdx == id.FailRealm &&
- FailDomainIdx == id.FailDomain &&
- VDiskIdx == id.VDisk);
- }
-
- void UpdateVDiskMetrics() const {
- DiskResourceValues.DataSize = Metrics.GetAllocatedSize();
- MaximumResourceValues.DataSize = Metrics.GetAvailableSize() + DiskResourceValues.DataSize;
- }
-
- bool UpdateVDiskMetrics(const NKikimrBlobStorage::TVDiskMetrics& vDiskMetrics, i64 *allocatedSizeIncrementPtr) const {
- const ui64 allocatedSizeBefore = Metrics.GetAllocatedSize();
- const ui32 prevStatusFlags = Metrics.GetStatusFlags();
- Metrics.MergeFrom(vDiskMetrics);
- MetricsDirty = true;
- UpdateVDiskMetrics();
- *allocatedSizeIncrementPtr = Metrics.GetAllocatedSize() - allocatedSizeBefore;
- return prevStatusFlags != Metrics.GetStatusFlags();
- }
-
- TResourceRawValues GetResourceCurrentValues() const {
- return DiskResourceValues;
- }
-
- TResourceRawValues GetResourceMaximumValues() const {
- return MaximumResourceValues;
- }
-
- TString GetStatusString() const {
- return NKikimrBlobStorage::EVDiskStatus_Name(Status);
- }
-
- bool IsOperational() const {
- return Status >= NKikimrBlobStorage::REPLICATING;
- }
-
- void OnCommit();
- };
-
- using TVSlots = TMap<TVSlotId, THolder<TVSlotInfo>>;
-
- class TPDiskInfo : public TIndirectReferable<TPDiskInfo> {
- public:
- using Table = Schema::PDisk;
-
- THostId HostId;
- Table::Path::Type Path;
- Table::Category::Type Kind = 0;
- Table::Guid::Type Guid = 0;
- TMaybe<Table::SharedWithOs::Type> SharedWithOs; // null on old versions
- TMaybe<Table::ReadCentric::Type> ReadCentric; // null on old versions
- Table::NextVSlotId::Type NextVSlotId; // null on old versions
- Table::PDiskConfig::Type PDiskConfig;
- TBoxId BoxId;
- ui32 ExpectedSlotCount = 0;
- bool HasExpectedSlotCount = false;
- ui32 NumActiveSlots = 0; // number of active VSlots created over this PDisk
- TMap<Schema::VSlot::VSlotID::Type, TIndirectReferable<TVSlotInfo>::TPtr> VSlotsOnPDisk; // vslots over this PDisk
-
- bool Operational = false; // set to true when both containing node is connected and Operational is reported in Metrics
-
- NKikimrBlobStorage::TPDiskMetrics Metrics;
- bool MetricsDirty = false;
-
- NKikimrBlobStorage::EDriveStatus Status;
- TInstant StatusTimestamp;
+
+ class TVSlotInfo;
+ class TPDiskInfo;
+ class TGroupInfo;
+ class TConfigState;
+ class TGroupSelector;
+ class TGroupFitter;
+
+ using TVSlotReadyTimestampQ = std::list<std::pair<TInstant, TVSlotInfo*>>;
+
+ class TVSlotInfo : public TIndirectReferable<TVSlotInfo> {
+ public:
+ using Table = Schema::VSlot;
+
+ const TVSlotId VSlotId;
+ TIndirectReferable<TPDiskInfo>::TPtr PDisk; // PDisk this slot resides on
+ TGroupId GroupId = 0;
+ Table::GroupGeneration::Type GroupPrevGeneration = 0;
+ Table::GroupGeneration::Type GroupGeneration = 0;
+ Table::Category::Type Kind = NKikimrBlobStorage::TVDiskKind::Default;
+ Table::RingIdx::Type RingIdx = 0;
+ Table::FailDomainIdx::Type FailDomainIdx = 0;
+ Table::VDiskIdx::Type VDiskIdx = 0;
+ Table::Mood::Type Mood;
+ TIndirectReferable<TGroupInfo>::TPtr Group; // group to which this VSlot belongs (or nullptr if it doesn't belong to any)
+ std::vector<std::pair<TVSlotId, TVDiskID>> Donors; // a set of alive donors for this disk
+ TVSlotId AcceptorVSlotId;
+ TInstant LastSeenReady;
+
+ // volatile state
+ mutable NKikimrBlobStorage::TVDiskMetrics Metrics;
+ mutable bool MetricsDirty = false;
+ mutable TResourceRawValues DiskResourceValues;
+ mutable TResourceRawValues MaximumResourceValues{
+ 1ULL << 40, // 1 TB
+ };
+
+ // not persistent field; set only when VSlot is scheduled for deletion
+ std::optional<TBoxStoragePoolId> DeletedFromStoragePoolId;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VDisk status management
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ private:
+ TVSlotReadyTimestampQ& VSlotReadyTimestampQ;
+ TVSlotReadyTimestampQ::iterator VSlotReadyTimestampIter;
+ NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::EVDiskStatus::INIT_PENDING;
+
+ // VDisk will be considered READY during this period after reporting its READY state
+ static constexpr TDuration ReadyStablePeriod = TDuration::Seconds(15);
+
+ public:
+ bool IsReady = false;
+
+ public:
+ void SetStatus(NKikimrBlobStorage::EVDiskStatus status, TInstant now) {
+ if (status != Status) {
+ Status = status;
+ IsReady = false;
+ if (status == NKikimrBlobStorage::EVDiskStatus::READY) {
+ const TInstant readyAfter = now + ReadyStablePeriod; // vdisk will be treated as READY one shortly, but not now
+ Y_VERIFY(VSlotReadyTimestampIter == TVSlotReadyTimestampQ::iterator());
+ Y_VERIFY(Group);
+ VSlotReadyTimestampIter = VSlotReadyTimestampQ.emplace(VSlotReadyTimestampQ.end(), readyAfter, this);
+ } else {
+ DropFromVSlotReadyTimestampQ();
+ }
+ }
+ }
+
+ void DropFromVSlotReadyTimestampQ() {
+ if (VSlotReadyTimestampIter != TVSlotReadyTimestampQ::iterator()) {
+ VSlotReadyTimestampQ.erase(VSlotReadyTimestampIter);
+ ResetVSlotReadyTimestampIter();
+ }
+ }
+
+ void ResetVSlotReadyTimestampIter() {
+ VSlotReadyTimestampIter = {};
+ }
+
+ NKikimrBlobStorage::EVDiskStatus GetStatus() const {
+ return Status;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TVSlotInfo,
+ Table::Category,
+ Table::GroupID,
+ Table::GroupGeneration,
+ Table::RingIdx,
+ Table::FailDomainIdx,
+ Table::VDiskIdx,
+ Table::GroupPrevGeneration,
+ Table::Mood,
+ Table::LastSeenReady
+ > adapter(
+ &TVSlotInfo::Kind,
+ &TVSlotInfo::GroupId,
+ &TVSlotInfo::GroupGeneration,
+ &TVSlotInfo::RingIdx,
+ &TVSlotInfo::FailDomainIdx,
+ &TVSlotInfo::VDiskIdx,
+ &TVSlotInfo::GroupPrevGeneration,
+ &TVSlotInfo::Mood,
+ &TVSlotInfo::LastSeenReady
+ );
+ callback(&adapter);
+ }
+
+ TVSlotInfo() = delete;
+
+ TVSlotInfo(TVSlotId vSlotId, TPDiskInfo *pdisk, TGroupId groupId, Table::GroupGeneration::Type groupPrevGeneration,
+ Table::GroupGeneration::Type groupGeneration, Table::Category::Type kind, Table::RingIdx::Type ringIdx,
+ Table::FailDomainIdx::Type failDomainIdx, Table::VDiskIdx::Type vDiskIdx, Table::Mood::Type mood,
+ TGroupInfo *group, TVSlotReadyTimestampQ *vslotReadyTimestampQ, TInstant lastSeenReady); // implemented in bsc.cpp
+
+ // is the slot being deleted (marked as deleted)
+ bool IsBeingDeleted() const {
+ return Mood == TMood::Delete;
+ }
+
+ void ScheduleForDeletion(TBoxStoragePoolId deletedFromStoragePoolId) {
+ Y_VERIFY(!IsBeingDeleted());
+ Mood = TMood::Delete;
+ GroupPrevGeneration = std::exchange(GroupGeneration, 0);
+ Group = nullptr;
+ DeletedFromStoragePoolId = deletedFromStoragePoolId;
+ }
+
+ void MakeDonorFor(TVSlotInfo *newSlot) {
+ Y_VERIFY(newSlot);
+ Y_VERIFY(!IsBeingDeleted());
+ Mood = TMood::Donor;
+ Group = nullptr; // we are not part of this group anymore
+ Donors.emplace_back(VSlotId, GetVDiskId());
+ newSlot->Donors = std::exchange(Donors, {});
+ }
+
+ TVDiskID GetVDiskId() const {
+ ui32 generation = IsBeingDeleted() // when the slot is scheduled for deletion, its last known generation is
+ ? GroupPrevGeneration // stored in GroupPrevGeneration
+ : GroupGeneration; // otherwise actual value is held in GroupGeneration
+ Y_VERIFY(generation);
+ return TVDiskID(GroupId, generation, RingIdx, FailDomainIdx, VDiskIdx);
+ }
+
+ TVDiskIdShort GetShortVDiskId() const {
+ return TVDiskIdShort(RingIdx, FailDomainIdx, VDiskIdx);
+ }
+
+ bool IsSameVDisk(const TVDiskID &id) {
+ return (GroupId == id.GroupID &&
+ RingIdx == id.FailRealm &&
+ FailDomainIdx == id.FailDomain &&
+ VDiskIdx == id.VDisk);
+ }
+
+ void UpdateVDiskMetrics() const {
+ DiskResourceValues.DataSize = Metrics.GetAllocatedSize();
+ MaximumResourceValues.DataSize = Metrics.GetAvailableSize() + DiskResourceValues.DataSize;
+ }
+
+ bool UpdateVDiskMetrics(const NKikimrBlobStorage::TVDiskMetrics& vDiskMetrics, i64 *allocatedSizeIncrementPtr) const {
+ const ui64 allocatedSizeBefore = Metrics.GetAllocatedSize();
+ const ui32 prevStatusFlags = Metrics.GetStatusFlags();
+ Metrics.MergeFrom(vDiskMetrics);
+ MetricsDirty = true;
+ UpdateVDiskMetrics();
+ *allocatedSizeIncrementPtr = Metrics.GetAllocatedSize() - allocatedSizeBefore;
+ return prevStatusFlags != Metrics.GetStatusFlags();
+ }
+
+ TResourceRawValues GetResourceCurrentValues() const {
+ return DiskResourceValues;
+ }
+
+ TResourceRawValues GetResourceMaximumValues() const {
+ return MaximumResourceValues;
+ }
+
+ TString GetStatusString() const {
+ return NKikimrBlobStorage::EVDiskStatus_Name(Status);
+ }
+
+ bool IsOperational() const {
+ return Status >= NKikimrBlobStorage::REPLICATING;
+ }
+
+ void OnCommit();
+ };
+
+ using TVSlots = TMap<TVSlotId, THolder<TVSlotInfo>>;
+
+ class TPDiskInfo : public TIndirectReferable<TPDiskInfo> {
+ public:
+ using Table = Schema::PDisk;
+
+ THostId HostId;
+ Table::Path::Type Path;
+ Table::Category::Type Kind = 0;
+ Table::Guid::Type Guid = 0;
+ TMaybe<Table::SharedWithOs::Type> SharedWithOs; // null on old versions
+ TMaybe<Table::ReadCentric::Type> ReadCentric; // null on old versions
+ Table::NextVSlotId::Type NextVSlotId; // null on old versions
+ Table::PDiskConfig::Type PDiskConfig;
+ TBoxId BoxId;
+ ui32 ExpectedSlotCount = 0;
+ bool HasExpectedSlotCount = false;
+ ui32 NumActiveSlots = 0; // number of active VSlots created over this PDisk
+ TMap<Schema::VSlot::VSlotID::Type, TIndirectReferable<TVSlotInfo>::TPtr> VSlotsOnPDisk; // vslots over this PDisk
+
+ bool Operational = false; // set to true when both containing node is connected and Operational is reported in Metrics
+
+ NKikimrBlobStorage::TPDiskMetrics Metrics;
+ bool MetricsDirty = false;
+
+ NKikimrBlobStorage::EDriveStatus Status;
+ TInstant StatusTimestamp;
TString ExpectedSerial;
TString LastSeenSerial;
TString LastSeenPath;
- const ui32 StaticSlotUsage = 0;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TPDiskInfo,
- Table::Path,
- Table::Category,
- Table::Guid,
- Table::SharedWithOs,
- Table::ReadCentric,
- Table::NextVSlotId,
- Table::PDiskConfig,
- Table::Status,
+ const ui32 StaticSlotUsage = 0;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TPDiskInfo,
+ Table::Path,
+ Table::Category,
+ Table::Guid,
+ Table::SharedWithOs,
+ Table::ReadCentric,
+ Table::NextVSlotId,
+ Table::PDiskConfig,
+ Table::Status,
Table::Timestamp,
Table::ExpectedSerial,
Table::LastSeenSerial,
Table::LastSeenPath
- > adapter(
- &TPDiskInfo::Path,
- &TPDiskInfo::Kind,
- &TPDiskInfo::Guid,
- &TPDiskInfo::SharedWithOs,
- &TPDiskInfo::ReadCentric,
- &TPDiskInfo::NextVSlotId,
- &TPDiskInfo::PDiskConfig,
- &TPDiskInfo::Status,
+ > adapter(
+ &TPDiskInfo::Path,
+ &TPDiskInfo::Kind,
+ &TPDiskInfo::Guid,
+ &TPDiskInfo::SharedWithOs,
+ &TPDiskInfo::ReadCentric,
+ &TPDiskInfo::NextVSlotId,
+ &TPDiskInfo::PDiskConfig,
+ &TPDiskInfo::Status,
&TPDiskInfo::StatusTimestamp,
&TPDiskInfo::ExpectedSerial,
&TPDiskInfo::LastSeenSerial,
&TPDiskInfo::LastSeenPath
- );
- callback(&adapter);
- }
-
- TPDiskInfo(THostId hostId,
- Table::Path::Type path,
- Table::Category::Type kind,
- Table::Guid::Type guid,
- TMaybe<Table::SharedWithOs::Type> sharedWithOs,
- TMaybe<Table::ReadCentric::Type> readCentric,
- Table::NextVSlotId::Type nextVSlotId,
- Table::PDiskConfig::Type pdiskConfig,
- TBoxId boxId,
- ui32 defaultMaxSlots,
- NKikimrBlobStorage::EDriveStatus status,
+ );
+ callback(&adapter);
+ }
+
+ TPDiskInfo(THostId hostId,
+ Table::Path::Type path,
+ Table::Category::Type kind,
+ Table::Guid::Type guid,
+ TMaybe<Table::SharedWithOs::Type> sharedWithOs,
+ TMaybe<Table::ReadCentric::Type> readCentric,
+ Table::NextVSlotId::Type nextVSlotId,
+ Table::PDiskConfig::Type pdiskConfig,
+ TBoxId boxId,
+ ui32 defaultMaxSlots,
+ NKikimrBlobStorage::EDriveStatus status,
TInstant statusTimestamp,
const TString& expectedSerial,
const TString& lastSeenSerial,
- const TString& lastSeenPath,
- ui32 staticSlotUsage)
- : HostId(hostId)
- , Path(path)
- , Kind(kind)
- , Guid(guid)
- , SharedWithOs(sharedWithOs)
- , ReadCentric(readCentric)
- , NextVSlotId(nextVSlotId)
- , PDiskConfig(std::move(pdiskConfig))
- , BoxId(boxId)
- , Status(status)
- , StatusTimestamp(statusTimestamp)
+ const TString& lastSeenPath,
+ ui32 staticSlotUsage)
+ : HostId(hostId)
+ , Path(path)
+ , Kind(kind)
+ , Guid(guid)
+ , SharedWithOs(sharedWithOs)
+ , ReadCentric(readCentric)
+ , NextVSlotId(nextVSlotId)
+ , PDiskConfig(std::move(pdiskConfig))
+ , BoxId(boxId)
+ , Status(status)
+ , StatusTimestamp(statusTimestamp)
, ExpectedSerial(expectedSerial)
, LastSeenSerial(lastSeenSerial)
, LastSeenPath(lastSeenPath)
- , StaticSlotUsage(staticSlotUsage)
- {
- ExtractConfig(defaultMaxSlots);
- }
-
- void ExtractConfig(ui32 defaultMaxSlots) {
- ExpectedSlotCount = defaultMaxSlots;
-
- NKikimrBlobStorage::TPDiskConfig pdiskConfig;
- if (pdiskConfig.ParseFromString(PDiskConfig) && pdiskConfig.HasExpectedSlotCount()) {
- ExpectedSlotCount = pdiskConfig.GetExpectedSlotCount();
- HasExpectedSlotCount = true;
- }
- }
-
- bool SlotSpaceEnforced(TBlobStorageController& self) const {
- return Metrics.HasEnforcedDynamicSlotSize() &&
- self.PDiskSpaceColorBorder >= NKikimrBlobStorage::TPDiskSpaceColor::YELLOW;
- }
-
- bool HasFullMetrics() const {
- return Metrics.GetTotalSize()
- && Metrics.HasMaxIOPS()
- && Metrics.HasMaxReadThroughput()
- && Metrics.HasMaxWriteThroughput();
- }
-
- bool UpdatePDiskMetrics(const NKikimrBlobStorage::TPDiskMetrics& pDiskMetrics) {
- const bool hadMetrics = HasFullMetrics();
- Metrics.CopyFrom(pDiskMetrics);
- MetricsDirty = true;
- return !hadMetrics && HasFullMetrics(); // true if metrics have just arrived
- }
-
- void UpdateOperational(bool nodeConnected) {
- Operational = nodeConnected && (!Metrics.HasState() ||
- Metrics.GetState() == NKikimrBlobStorage::TPDiskState::Normal);
- }
-
+ , StaticSlotUsage(staticSlotUsage)
+ {
+ ExtractConfig(defaultMaxSlots);
+ }
+
+ void ExtractConfig(ui32 defaultMaxSlots) {
+ ExpectedSlotCount = defaultMaxSlots;
+
+ NKikimrBlobStorage::TPDiskConfig pdiskConfig;
+ if (pdiskConfig.ParseFromString(PDiskConfig) && pdiskConfig.HasExpectedSlotCount()) {
+ ExpectedSlotCount = pdiskConfig.GetExpectedSlotCount();
+ HasExpectedSlotCount = true;
+ }
+ }
+
+ bool SlotSpaceEnforced(TBlobStorageController& self) const {
+ return Metrics.HasEnforcedDynamicSlotSize() &&
+ self.PDiskSpaceColorBorder >= NKikimrBlobStorage::TPDiskSpaceColor::YELLOW;
+ }
+
+ bool HasFullMetrics() const {
+ return Metrics.GetTotalSize()
+ && Metrics.HasMaxIOPS()
+ && Metrics.HasMaxReadThroughput()
+ && Metrics.HasMaxWriteThroughput();
+ }
+
+ bool UpdatePDiskMetrics(const NKikimrBlobStorage::TPDiskMetrics& pDiskMetrics) {
+ const bool hadMetrics = HasFullMetrics();
+ Metrics.CopyFrom(pDiskMetrics);
+ MetricsDirty = true;
+ return !hadMetrics && HasFullMetrics(); // true if metrics have just arrived
+ }
+
+ void UpdateOperational(bool nodeConnected) {
+ Operational = nodeConnected && (!Metrics.HasState() ||
+ Metrics.GetState() == NKikimrBlobStorage::TPDiskState::Normal);
+ }
+
bool ShouldBeSettledBySelfHeal() const {
switch (Status) {
case NKikimrBlobStorage::EDriveStatus::FAULTY:
@@ -409,106 +409,106 @@ public:
}
}
- bool BadInTermsOfSelfHeal() const {
- return ShouldBeSettledBySelfHeal() || Status == NKikimrBlobStorage::EDriveStatus::INACTIVE;
- }
-
- std::tuple<bool, bool> GetSelfHealStatusTuple() const {
- return {ShouldBeSettledBySelfHeal(), BadInTermsOfSelfHeal()};
- }
-
- bool HasGoodExpectedStatus() const {
- switch (Status) {
- case NKikimrBlobStorage::EDriveStatus::UNKNOWN:
- case NKikimrBlobStorage::EDriveStatus::BROKEN:
- return false;
-
- case NKikimrBlobStorage::EDriveStatus::ACTIVE:
- case NKikimrBlobStorage::EDriveStatus::INACTIVE:
- case NKikimrBlobStorage::EDriveStatus::SPARE:
- case NKikimrBlobStorage::EDriveStatus::FAULTY:
+ bool BadInTermsOfSelfHeal() const {
+ return ShouldBeSettledBySelfHeal() || Status == NKikimrBlobStorage::EDriveStatus::INACTIVE;
+ }
+
+ std::tuple<bool, bool> GetSelfHealStatusTuple() const {
+ return {ShouldBeSettledBySelfHeal(), BadInTermsOfSelfHeal()};
+ }
+
+ bool HasGoodExpectedStatus() const {
+ switch (Status) {
+ case NKikimrBlobStorage::EDriveStatus::UNKNOWN:
+ case NKikimrBlobStorage::EDriveStatus::BROKEN:
+ return false;
+
+ case NKikimrBlobStorage::EDriveStatus::ACTIVE:
+ case NKikimrBlobStorage::EDriveStatus::INACTIVE:
+ case NKikimrBlobStorage::EDriveStatus::SPARE:
+ case NKikimrBlobStorage::EDriveStatus::FAULTY:
case NKikimrBlobStorage::EDriveStatus::TO_BE_REMOVED:
- return true;
-
- case NKikimrBlobStorage::EDriveStatus::EDriveStatus_INT_MIN_SENTINEL_DO_NOT_USE_:
- case NKikimrBlobStorage::EDriveStatus::EDriveStatus_INT_MAX_SENTINEL_DO_NOT_USE_:
- break;
- }
- Y_FAIL("unexpected EDriveStatus");
- }
-
+ return true;
+
+ case NKikimrBlobStorage::EDriveStatus::EDriveStatus_INT_MIN_SENTINEL_DO_NOT_USE_:
+ case NKikimrBlobStorage::EDriveStatus::EDriveStatus_INT_MAX_SENTINEL_DO_NOT_USE_:
+ break;
+ }
+ Y_FAIL("unexpected EDriveStatus");
+ }
+
TString PathOrSerial() const {
return Path ? Path : ExpectedSerial;
}
- void OnCommit();
- };
-
- using TPDisks = TMap<TPDiskId, THolder<TPDiskInfo>>;
-
- using TGroupSpecies = std::tuple<Schema::Group::ErasureSpecies::Type,
- Schema::Group::DesiredPDiskCategory::Type,
- Schema::Group::DesiredVDiskCategory::Type>;
-
- class TGroupInfo : public TIndirectReferable<TGroupInfo> {
- public:
- using Table = Schema::Group;
-
- TGroupId ID;
- Table::Generation::Type Generation = 0;
- Table::Owner::Type Owner = 0;
- Table::ErasureSpecies::Type ErasureSpecies = Schema::Group::ErasureSpecies::Type();
- Table::DesiredPDiskCategory::Type DesiredPDiskCategory = 0;
- Table::DesiredVDiskCategory::Type DesiredVDiskCategory = NKikimrBlobStorage::TVDiskKind::Default;
+ void OnCommit();
+ };
+
+ using TPDisks = TMap<TPDiskId, THolder<TPDiskInfo>>;
+
+ using TGroupSpecies = std::tuple<Schema::Group::ErasureSpecies::Type,
+ Schema::Group::DesiredPDiskCategory::Type,
+ Schema::Group::DesiredVDiskCategory::Type>;
+
+ class TGroupInfo : public TIndirectReferable<TGroupInfo> {
+ public:
+ using Table = Schema::Group;
+
+ TGroupId ID;
+ Table::Generation::Type Generation = 0;
+ Table::Owner::Type Owner = 0;
+ Table::ErasureSpecies::Type ErasureSpecies = Schema::Group::ErasureSpecies::Type();
+ Table::DesiredPDiskCategory::Type DesiredPDiskCategory = 0;
+ Table::DesiredVDiskCategory::Type DesiredVDiskCategory = NKikimrBlobStorage::TVDiskKind::Default;
TMaybe<Table::EncryptionMode::Type> EncryptionMode; // null on old versions
TMaybe<Table::LifeCyclePhase::Type> LifeCyclePhase; // null on old versions
TMaybe<Table::MainKeyId::Type> MainKeyId; // null on old versions
TMaybe<Table::EncryptedGroupKey::Type> EncryptedGroupKey; // null on old versions
TMaybe<Table::GroupKeyNonce::Type> GroupKeyNonce; // null on old versions
TMaybe<Table::MainKeyVersion::Type> MainKeyVersion; // null on old verstions
- bool PersistedDown = false; // the value stored in the database
- bool SeenOperational = false;
-
- bool Down = false; // is group are down right now (not selectable)
- TVector<TIndirectReferable<TVSlotInfo>::TPtr> VDisksInGroup;
- TGroupLatencyStats LatencyStats;
- TBoxStoragePoolId StoragePoolId;
- mutable TStorageStatusFlags StatusFlags;
- bool ContentChanged = false;
-
- // group's geometry; it doesn't ever change since the group is created
- const ui32 NumFailRealms = 0;
- const ui32 NumFailDomainsPerFailRealm = 0;
- const ui32 NumVDisksPerFailDomain = 0;
-
- // topology according to the geometry
- const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
-
- struct TGroupStatus {
- // status derived from the actual state of VDisks (IsReady() to be exact)
+ bool PersistedDown = false; // the value stored in the database
+ bool SeenOperational = false;
+
+ bool Down = false; // is group are down right now (not selectable)
+ TVector<TIndirectReferable<TVSlotInfo>::TPtr> VDisksInGroup;
+ TGroupLatencyStats LatencyStats;
+ TBoxStoragePoolId StoragePoolId;
+ mutable TStorageStatusFlags StatusFlags;
+ bool ContentChanged = false;
+
+ // group's geometry; it doesn't ever change since the group is created
+ const ui32 NumFailRealms = 0;
+ const ui32 NumFailDomainsPerFailRealm = 0;
+ const ui32 NumVDisksPerFailDomain = 0;
+
+ // topology according to the geometry
+ const std::shared_ptr<TBlobStorageGroupInfo::TTopology> Topology;
+
+ struct TGroupStatus {
+ // status derived from the actual state of VDisks (IsReady() to be exact)
NKikimrBlobStorage::TGroupStatus::E OperatingStatus = NKikimrBlobStorage::TGroupStatus::UNKNOWN;
- // status derived by adding underlying PDisk status (FAULTY&BROKEN are assumed to be not working ones)
+ // status derived by adding underlying PDisk status (FAULTY&BROKEN are assumed to be not working ones)
NKikimrBlobStorage::TGroupStatus::E ExpectedStatus = NKikimrBlobStorage::TGroupStatus::UNKNOWN;
- } Status;
-
- // group status depends on the IsReady value for every VDisk; so it has to be updated every time there is possible
- // change; source of this change include:
- // 1. Node disconnection
- // 2. VDisk status update
- // 3. VSlotReadyUpdate timer hit
- // 4. Group contents change
- //
- // also it depends on the Status of underlying PDisks, so every time their status change, group status has to
- // be recalculated too
- void CalculateGroupStatus();
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TGroupInfo,
- Table::Generation,
- Table::Owner,
- Table::ErasureSpecies,
- Table::DesiredPDiskCategory,
+ } Status;
+
+ // group status depends on the IsReady value for every VDisk; so it has to be updated every time there is possible
+ // change; source of this change include:
+ // 1. Node disconnection
+ // 2. VDisk status update
+ // 3. VSlotReadyUpdate timer hit
+ // 4. Group contents change
+ //
+ // also it depends on the Status of underlying PDisks, so every time their status change, group status has to
+ // be recalculated too
+ void CalculateGroupStatus();
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TGroupInfo,
+ Table::Generation,
+ Table::Owner,
+ Table::ErasureSpecies,
+ Table::DesiredPDiskCategory,
Table::DesiredVDiskCategory,
Table::EncryptionMode,
Table::LifeCyclePhase,
@@ -516,12 +516,12 @@ public:
Table::EncryptedGroupKey,
Table::GroupKeyNonce,
Table::MainKeyVersion,
- Table::SeenOperational
- > adapter(
- &TGroupInfo::Generation,
- &TGroupInfo::Owner,
- &TGroupInfo::ErasureSpecies,
- &TGroupInfo::DesiredPDiskCategory,
+ Table::SeenOperational
+ > adapter(
+ &TGroupInfo::Generation,
+ &TGroupInfo::Owner,
+ &TGroupInfo::ErasureSpecies,
+ &TGroupInfo::DesiredPDiskCategory,
&TGroupInfo::DesiredVDiskCategory,
&TGroupInfo::EncryptionMode,
&TGroupInfo::LifeCyclePhase,
@@ -529,16 +529,16 @@ public:
&TGroupInfo::EncryptedGroupKey,
&TGroupInfo::GroupKeyNonce,
&TGroupInfo::MainKeyVersion,
- &TGroupInfo::SeenOperational
- );
- callback(&adapter);
- }
-
- TGroupInfo(TGroupId id,
- Schema::Group::Generation::Type generation,
- Schema::Group::Owner::Type owner,
- Schema::Group::ErasureSpecies::Type erasureSpecies,
- Schema::Group::DesiredPDiskCategory::Type desiredPDiskCategory,
+ &TGroupInfo::SeenOperational
+ );
+ callback(&adapter);
+ }
+
+ TGroupInfo(TGroupId id,
+ Schema::Group::Generation::Type generation,
+ Schema::Group::Owner::Type owner,
+ Schema::Group::ErasureSpecies::Type erasureSpecies,
+ Schema::Group::DesiredPDiskCategory::Type desiredPDiskCategory,
Schema::Group::DesiredVDiskCategory::Type desiredVDiskCategory,
Schema::Group::EncryptionMode::Type encryptionMode,
Schema::Group::LifeCyclePhase::Type lifeCyclePhase,
@@ -546,72 +546,72 @@ public:
Schema::Group::EncryptedGroupKey::Type encryptedGroupKey,
Schema::Group::GroupKeyNonce::Type groupKeyNonce,
Schema::Group::MainKeyVersion::Type mainKeyVersion,
- Schema::Group::Down::Type down,
- Schema::Group::SeenOperational::Type seenOperational,
- TBoxStoragePoolId storagePoolId,
- ui32 numFailRealms,
- ui32 numFailDomainsPerFailRealm,
- ui32 numVDisksPerFailDomain)
- : ID(id)
- , Generation(generation)
- , Owner(owner)
- , ErasureSpecies(erasureSpecies)
- , DesiredPDiskCategory(desiredPDiskCategory)
- , DesiredVDiskCategory(desiredVDiskCategory)
+ Schema::Group::Down::Type down,
+ Schema::Group::SeenOperational::Type seenOperational,
+ TBoxStoragePoolId storagePoolId,
+ ui32 numFailRealms,
+ ui32 numFailDomainsPerFailRealm,
+ ui32 numVDisksPerFailDomain)
+ : ID(id)
+ , Generation(generation)
+ , Owner(owner)
+ , ErasureSpecies(erasureSpecies)
+ , DesiredPDiskCategory(desiredPDiskCategory)
+ , DesiredVDiskCategory(desiredVDiskCategory)
, EncryptionMode(encryptionMode)
, LifeCyclePhase(lifeCyclePhase)
, MainKeyId(mainKeyId)
, EncryptedGroupKey(encryptedGroupKey)
, GroupKeyNonce(groupKeyNonce)
, MainKeyVersion(mainKeyVersion)
- , PersistedDown(down)
- , SeenOperational(seenOperational)
- , Down(PersistedDown)
- , VDisksInGroup(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain)
- , StoragePoolId(storagePoolId)
- , NumFailRealms(numFailRealms)
- , NumFailDomainsPerFailRealm(numFailDomainsPerFailRealm)
- , NumVDisksPerFailDomain(numVDisksPerFailDomain)
- , Topology(std::make_shared<TBlobStorageGroupInfo::TTopology>(TBlobStorageGroupType(ErasureSpecies),
- NumFailRealms, NumFailDomainsPerFailRealm, NumVDisksPerFailDomain))
- {
- Topology->FinalizeConstruction();
- Y_VERIFY(VDisksInGroup.size() == Topology->GetTotalVDisksNum());
- }
-
- void ClearVDisksInGroup() {
- std::fill(VDisksInGroup.begin(), VDisksInGroup.end(), nullptr);
- }
-
- void AddVSlot(const TVSlotInfo *vslot) {
- Y_VERIFY(vslot->Group == this);
- const ui32 index = Topology->GetOrderNumber(vslot->GetShortVDiskId());
- Y_VERIFY(!VDisksInGroup[index]);
- VDisksInGroup[index] = vslot;
- }
-
- void FinishVDisksInGroup() {
- for (const TVSlotInfo *slot : VDisksInGroup) {
- Y_VERIFY(slot);
- }
- }
-
- TGroupSpecies GetGroupSpecies() const {
- return TGroupSpecies(ErasureSpecies, DesiredPDiskCategory, DesiredVDiskCategory);
- }
-
- TResourceRawValues GetResourceCurrentValues() const {
- TResourceRawValues values = {};
- for (const TVSlotInfo *vslot : VDisksInGroup) {
- values += vslot->GetResourceCurrentValues();
- }
- return values;
- }
-
+ , PersistedDown(down)
+ , SeenOperational(seenOperational)
+ , Down(PersistedDown)
+ , VDisksInGroup(numFailRealms * numFailDomainsPerFailRealm * numVDisksPerFailDomain)
+ , StoragePoolId(storagePoolId)
+ , NumFailRealms(numFailRealms)
+ , NumFailDomainsPerFailRealm(numFailDomainsPerFailRealm)
+ , NumVDisksPerFailDomain(numVDisksPerFailDomain)
+ , Topology(std::make_shared<TBlobStorageGroupInfo::TTopology>(TBlobStorageGroupType(ErasureSpecies),
+ NumFailRealms, NumFailDomainsPerFailRealm, NumVDisksPerFailDomain))
+ {
+ Topology->FinalizeConstruction();
+ Y_VERIFY(VDisksInGroup.size() == Topology->GetTotalVDisksNum());
+ }
+
+ void ClearVDisksInGroup() {
+ std::fill(VDisksInGroup.begin(), VDisksInGroup.end(), nullptr);
+ }
+
+ void AddVSlot(const TVSlotInfo *vslot) {
+ Y_VERIFY(vslot->Group == this);
+ const ui32 index = Topology->GetOrderNumber(vslot->GetShortVDiskId());
+ Y_VERIFY(!VDisksInGroup[index]);
+ VDisksInGroup[index] = vslot;
+ }
+
+ void FinishVDisksInGroup() {
+ for (const TVSlotInfo *slot : VDisksInGroup) {
+ Y_VERIFY(slot);
+ }
+ }
+
+ TGroupSpecies GetGroupSpecies() const {
+ return TGroupSpecies(ErasureSpecies, DesiredPDiskCategory, DesiredVDiskCategory);
+ }
+
+ TResourceRawValues GetResourceCurrentValues() const {
+ TResourceRawValues values = {};
+ for (const TVSlotInfo *vslot : VDisksInGroup) {
+ values += vslot->GetResourceCurrentValues();
+ }
+ return values;
+ }
+
TPDiskCategory::EDeviceType GetCommonDeviceType() const {
- if (VDisksInGroup) {
- const TPDiskCategory::EDeviceType type = VDisksInGroup.front()->PDisk->Kind.Type();
- for (const TVSlotInfo *vslot : VDisksInGroup) {
+ if (VDisksInGroup) {
+ const TPDiskCategory::EDeviceType type = VDisksInGroup.front()->PDisk->Kind.Type();
+ for (const TVSlotInfo *vslot : VDisksInGroup) {
if (type != vslot->PDisk->Kind.Type()) {
return TPDiskCategory::DEVICE_TYPE_UNKNOWN;
}
@@ -622,533 +622,533 @@ public:
}
}
- void FillInGroupParameters(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *params) const {
- FillInResources(params->MutableAssuredResources(), true);
- FillInResources(params->MutableCurrentResources(), false);
- FillInVDiskResources(params);
- }
-
- void FillInResources(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters::TResources *pb, bool countMaxSlots) const {
- // count minimum params for each of slots assuming they are shared fairly between all the slots (expected or currently created)
- std::optional<ui64> size;
- std::optional<double> iops;
- std::optional<ui64> readThroughput;
- std::optional<ui64> writeThroughput;
- std::optional<double> occupancy;
- for (const TVSlotInfo *vslot : VDisksInGroup) {
- const TPDiskInfo *pdisk = vslot->PDisk;
- const auto& metrics = pdisk->Metrics;
- const ui32 shareFactor = countMaxSlots ? pdisk->ExpectedSlotCount : pdisk->NumActiveSlots;
- ui64 vdiskSlotSize = 0;
- if (metrics.HasEnforcedDynamicSlotSize()) {
- vdiskSlotSize = metrics.GetEnforcedDynamicSlotSize();
- } else if (metrics.GetTotalSize()) {
- vdiskSlotSize = metrics.GetTotalSize() / shareFactor;
- }
- if (vdiskSlotSize) {
- size = Min(size.value_or(Max<ui64>()), vdiskSlotSize);
- }
- if (metrics.HasMaxIOPS()) {
- iops = Min(iops.value_or(Max<double>()), metrics.GetMaxIOPS() * 100 / shareFactor * 0.01);
- }
- if (metrics.HasMaxReadThroughput()) {
- readThroughput = Min(readThroughput.value_or(Max<ui64>()), metrics.GetMaxReadThroughput() / shareFactor);
- }
- if (metrics.HasMaxWriteThroughput()) {
- writeThroughput = Min(writeThroughput.value_or(Max<ui64>()), metrics.GetMaxWriteThroughput() / shareFactor);
- }
- if (const auto& vm = vslot->Metrics; vm.HasOccupancy()) {
- occupancy = Max(occupancy.value_or(0), vm.GetOccupancy());
- }
- }
-
- // and recalculate it to the total size of the group according to the erasure
- TBlobStorageGroupType type(ErasureSpecies);
- const double factor = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
- if (size) {
- pb->SetSpace(*size * factor);
- }
- if (iops) {
- pb->SetIOPS(*iops * VDisksInGroup.size() / type.TotalPartCount());
- }
- if (readThroughput) {
- pb->SetReadThroughput(*readThroughput * factor);
- }
- if (writeThroughput) {
- pb->SetWriteThroughput(*writeThroughput * factor);
- }
- if (occupancy) {
- pb->SetOccupancy(*occupancy);
- }
- }
-
- void FillInVDiskResources(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *pb) const {
- TBlobStorageGroupType type(ErasureSpecies);
- const double f = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
- for (const TVSlotInfo *vslot : VDisksInGroup) {
- const auto& m = vslot->Metrics;
- if (m.HasAvailableSize()) {
- pb->SetAvailableSize(Min<ui64>(pb->HasAvailableSize() ? pb->GetAvailableSize() : Max<ui64>(), f * m.GetAvailableSize()));
- }
- if (m.HasAllocatedSize()) {
- pb->SetAllocatedSize(Max<ui64>(pb->HasAllocatedSize() ? pb->GetAllocatedSize() : 0, f * m.GetAllocatedSize()));
- }
- if (m.HasSpaceColor()) {
- pb->SetSpaceColor(pb->HasSpaceColor() ? Max(pb->GetSpaceColor(), m.GetSpaceColor()) : m.GetSpaceColor());
- }
- }
- }
-
- void UpdateSeenOperational() {
- TBlobStorageGroupInfo::TGroupFailDomains failed(Topology.get());
- for (const TVSlotInfo *slot : VDisksInGroup) {
- if (!slot->IsOperational()) {
- failed |= {Topology.get(), {(ui8)slot->RingIdx, (ui8)slot->FailDomainIdx, (ui8)slot->VDiskIdx}};
- }
- }
- if (Topology->QuorumChecker->CheckFailModelForGroupDomains(failed)) {
- SeenOperational = true;
- }
- }
-
- TStorageStatusFlags GetStorageStatusFlags() const {
- TStorageStatusFlags res;
- for (const TVSlotInfo *slot : VDisksInGroup) {
- if (const auto& m = slot->Metrics; m.HasStatusFlags()) {
- res.Merge(m.GetStatusFlags());
- }
- }
- return res;
- }
-
- void OnCommit();
- };
-
- using TGroups = TMap<TGroupId, THolder<TGroupInfo>>;
-
- class TNodeInfo {
- public:
- using Table = Schema::Node;
-
- bool IsRegistered = false;
- Table::NextPDiskID::Type NextPDiskID;
+ void FillInGroupParameters(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *params) const {
+ FillInResources(params->MutableAssuredResources(), true);
+ FillInResources(params->MutableCurrentResources(), false);
+ FillInVDiskResources(params);
+ }
+
+ void FillInResources(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters::TResources *pb, bool countMaxSlots) const {
+ // count minimum params for each of slots assuming they are shared fairly between all the slots (expected or currently created)
+ std::optional<ui64> size;
+ std::optional<double> iops;
+ std::optional<ui64> readThroughput;
+ std::optional<ui64> writeThroughput;
+ std::optional<double> occupancy;
+ for (const TVSlotInfo *vslot : VDisksInGroup) {
+ const TPDiskInfo *pdisk = vslot->PDisk;
+ const auto& metrics = pdisk->Metrics;
+ const ui32 shareFactor = countMaxSlots ? pdisk->ExpectedSlotCount : pdisk->NumActiveSlots;
+ ui64 vdiskSlotSize = 0;
+ if (metrics.HasEnforcedDynamicSlotSize()) {
+ vdiskSlotSize = metrics.GetEnforcedDynamicSlotSize();
+ } else if (metrics.GetTotalSize()) {
+ vdiskSlotSize = metrics.GetTotalSize() / shareFactor;
+ }
+ if (vdiskSlotSize) {
+ size = Min(size.value_or(Max<ui64>()), vdiskSlotSize);
+ }
+ if (metrics.HasMaxIOPS()) {
+ iops = Min(iops.value_or(Max<double>()), metrics.GetMaxIOPS() * 100 / shareFactor * 0.01);
+ }
+ if (metrics.HasMaxReadThroughput()) {
+ readThroughput = Min(readThroughput.value_or(Max<ui64>()), metrics.GetMaxReadThroughput() / shareFactor);
+ }
+ if (metrics.HasMaxWriteThroughput()) {
+ writeThroughput = Min(writeThroughput.value_or(Max<ui64>()), metrics.GetMaxWriteThroughput() / shareFactor);
+ }
+ if (const auto& vm = vslot->Metrics; vm.HasOccupancy()) {
+ occupancy = Max(occupancy.value_or(0), vm.GetOccupancy());
+ }
+ }
+
+ // and recalculate it to the total size of the group according to the erasure
+ TBlobStorageGroupType type(ErasureSpecies);
+ const double factor = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
+ if (size) {
+ pb->SetSpace(*size * factor);
+ }
+ if (iops) {
+ pb->SetIOPS(*iops * VDisksInGroup.size() / type.TotalPartCount());
+ }
+ if (readThroughput) {
+ pb->SetReadThroughput(*readThroughput * factor);
+ }
+ if (writeThroughput) {
+ pb->SetWriteThroughput(*writeThroughput * factor);
+ }
+ if (occupancy) {
+ pb->SetOccupancy(*occupancy);
+ }
+ }
+
+ void FillInVDiskResources(NKikimrBlobStorage::TEvControllerSelectGroupsResult::TGroupParameters *pb) const {
+ TBlobStorageGroupType type(ErasureSpecies);
+ const double f = (double)VDisksInGroup.size() * type.DataParts() / type.TotalPartCount();
+ for (const TVSlotInfo *vslot : VDisksInGroup) {
+ const auto& m = vslot->Metrics;
+ if (m.HasAvailableSize()) {
+ pb->SetAvailableSize(Min<ui64>(pb->HasAvailableSize() ? pb->GetAvailableSize() : Max<ui64>(), f * m.GetAvailableSize()));
+ }
+ if (m.HasAllocatedSize()) {
+ pb->SetAllocatedSize(Max<ui64>(pb->HasAllocatedSize() ? pb->GetAllocatedSize() : 0, f * m.GetAllocatedSize()));
+ }
+ if (m.HasSpaceColor()) {
+ pb->SetSpaceColor(pb->HasSpaceColor() ? Max(pb->GetSpaceColor(), m.GetSpaceColor()) : m.GetSpaceColor());
+ }
+ }
+ }
+
+ void UpdateSeenOperational() {
+ TBlobStorageGroupInfo::TGroupFailDomains failed(Topology.get());
+ for (const TVSlotInfo *slot : VDisksInGroup) {
+ if (!slot->IsOperational()) {
+ failed |= {Topology.get(), {(ui8)slot->RingIdx, (ui8)slot->FailDomainIdx, (ui8)slot->VDiskIdx}};
+ }
+ }
+ if (Topology->QuorumChecker->CheckFailModelForGroupDomains(failed)) {
+ SeenOperational = true;
+ }
+ }
+
+ TStorageStatusFlags GetStorageStatusFlags() const {
+ TStorageStatusFlags res;
+ for (const TVSlotInfo *slot : VDisksInGroup) {
+ if (const auto& m = slot->Metrics; m.HasStatusFlags()) {
+ res.Merge(m.GetStatusFlags());
+ }
+ }
+ return res;
+ }
+
+ void OnCommit();
+ };
+
+ using TGroups = TMap<TGroupId, THolder<TGroupInfo>>;
+
+ class TNodeInfo {
+ public:
+ using Table = Schema::Node;
+
+ bool IsRegistered = false;
+ Table::NextPDiskID::Type NextPDiskID;
// in-mem only
std::map<TString, NPDisk::TDriveData> KnownDrives;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TNodeInfo,
- Table::NextPDiskID
- > adapter(
- &TNodeInfo::NextPDiskID
- );
- callback(&adapter);
- }
-
- TNodeInfo()
- : NextPDiskID(0)
- {}
-
- TNodeInfo(Table::NextPDiskID::Type nextPDiskID)
- : NextPDiskID(nextPDiskID)
- {}
-
- };
-
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TNodeInfo,
+ Table::NextPDiskID
+ > adapter(
+ &TNodeInfo::NextPDiskID
+ );
+ callback(&adapter);
+ }
+
+ TNodeInfo()
+ : NextPDiskID(0)
+ {}
+
+ TNodeInfo(Table::NextPDiskID::Type nextPDiskID)
+ : NextPDiskID(nextPDiskID)
+ {}
+
+ };
+
std::map<TString, TNodeId> NodeForSerial;
TMap<ui32, TSet<ui32>> NodesAwaitingKeysForGroup;
- struct THostConfigInfo {
- struct TDriveKey {
- Schema::HostConfigDrive::HostConfigId::Type HostConfigId;
- Schema::HostConfigDrive::Path::Type Path;
-
- TDriveKey() = default;
- TDriveKey(const TDriveKey&) = default;
- TDriveKey(TDriveKey&&) = default;
-
- TDriveKey(Schema::HostConfigDrive::TKey::Type key) {
- std::tie(HostConfigId, Path) = std::move(key);
- }
-
- auto GetKey() const {
- return std::tie(HostConfigId, Path);
- }
-
- friend bool operator<(const TDriveKey &x, const TDriveKey &y) {
- return x.GetKey() < y.GetKey();
- }
- };
-
- struct TDriveInfo {
- using Table = Schema::HostConfigDrive;
-
- Table::TypeCol::Type Type;
- Table::SharedWithOs::Type SharedWithOs;
- Table::ReadCentric::Type ReadCentric;
- Table::Kind::Type Kind;
- TMaybe<Table::PDiskConfig::Type> PDiskConfig;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TDriveInfo,
- Table::TypeCol,
- Table::SharedWithOs,
- Table::ReadCentric,
- Table::Kind,
- Table::PDiskConfig
- > adapter(
- &TDriveInfo::Type,
- &TDriveInfo::SharedWithOs,
- &TDriveInfo::ReadCentric,
- &TDriveInfo::Kind,
- &TDriveInfo::PDiskConfig
- );
- callback(&adapter);
- }
- };
-
- using TDrives = TMap<TDriveKey, TDriveInfo>;
-
- using Table = Schema::HostConfig;
-
- Table::Name::Type Name;
- TMaybe<Table::Generation::Type> Generation;
- TDrives Drives;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, THostConfigInfo,
- Table::Name,
- Table::Generation,
- TInlineTable<TDrives, Schema::HostConfigDrive>
- > adapter(
- &THostConfigInfo::Name,
- &THostConfigInfo::Generation,
- &THostConfigInfo::Drives
- );
- callback(&adapter);
- }
- };
-
- struct TBoxInfo {
- struct THostKey {
- Schema::BoxHostV2::BoxId::Type BoxId;
- Schema::BoxHostV2::Fqdn::Type Fqdn;
- Schema::BoxHostV2::IcPort::Type IcPort;
-
- THostKey() = default;
- THostKey(const THostKey&) = default;
- THostKey(THostKey&&) = default;
-
- THostKey(Schema::BoxHostV2::TKey::Type key) {
- std::tie(BoxId, Fqdn, IcPort) = std::move(key);
- }
-
- auto GetKey() const {
- return std::tie(BoxId, Fqdn, IcPort);
- }
-
- friend bool operator<(const THostKey &x, const THostKey &y) {
- return x.GetKey() < y.GetKey();
- }
-
- operator THostId() const {
- return {Fqdn, IcPort};
- }
- };
-
- struct THostInfo {
- using Table = Schema::BoxHostV2;
-
- Schema::BoxHostV2::HostConfigId::Type HostConfigId;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, THostInfo,
- Table::HostConfigId
- > adapter(
- &THostInfo::HostConfigId
- );
- callback(&adapter);
- }
- };
-
- using Table = Schema::Box;
-
+ struct THostConfigInfo {
+ struct TDriveKey {
+ Schema::HostConfigDrive::HostConfigId::Type HostConfigId;
+ Schema::HostConfigDrive::Path::Type Path;
+
+ TDriveKey() = default;
+ TDriveKey(const TDriveKey&) = default;
+ TDriveKey(TDriveKey&&) = default;
+
+ TDriveKey(Schema::HostConfigDrive::TKey::Type key) {
+ std::tie(HostConfigId, Path) = std::move(key);
+ }
+
+ auto GetKey() const {
+ return std::tie(HostConfigId, Path);
+ }
+
+ friend bool operator<(const TDriveKey &x, const TDriveKey &y) {
+ return x.GetKey() < y.GetKey();
+ }
+ };
+
+ struct TDriveInfo {
+ using Table = Schema::HostConfigDrive;
+
+ Table::TypeCol::Type Type;
+ Table::SharedWithOs::Type SharedWithOs;
+ Table::ReadCentric::Type ReadCentric;
+ Table::Kind::Type Kind;
+ TMaybe<Table::PDiskConfig::Type> PDiskConfig;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TDriveInfo,
+ Table::TypeCol,
+ Table::SharedWithOs,
+ Table::ReadCentric,
+ Table::Kind,
+ Table::PDiskConfig
+ > adapter(
+ &TDriveInfo::Type,
+ &TDriveInfo::SharedWithOs,
+ &TDriveInfo::ReadCentric,
+ &TDriveInfo::Kind,
+ &TDriveInfo::PDiskConfig
+ );
+ callback(&adapter);
+ }
+ };
+
+ using TDrives = TMap<TDriveKey, TDriveInfo>;
+
+ using Table = Schema::HostConfig;
+
+ Table::Name::Type Name;
+ TMaybe<Table::Generation::Type> Generation;
+ TDrives Drives;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, THostConfigInfo,
+ Table::Name,
+ Table::Generation,
+ TInlineTable<TDrives, Schema::HostConfigDrive>
+ > adapter(
+ &THostConfigInfo::Name,
+ &THostConfigInfo::Generation,
+ &THostConfigInfo::Drives
+ );
+ callback(&adapter);
+ }
+ };
+
+ struct TBoxInfo {
+ struct THostKey {
+ Schema::BoxHostV2::BoxId::Type BoxId;
+ Schema::BoxHostV2::Fqdn::Type Fqdn;
+ Schema::BoxHostV2::IcPort::Type IcPort;
+
+ THostKey() = default;
+ THostKey(const THostKey&) = default;
+ THostKey(THostKey&&) = default;
+
+ THostKey(Schema::BoxHostV2::TKey::Type key) {
+ std::tie(BoxId, Fqdn, IcPort) = std::move(key);
+ }
+
+ auto GetKey() const {
+ return std::tie(BoxId, Fqdn, IcPort);
+ }
+
+ friend bool operator<(const THostKey &x, const THostKey &y) {
+ return x.GetKey() < y.GetKey();
+ }
+
+ operator THostId() const {
+ return {Fqdn, IcPort};
+ }
+ };
+
+ struct THostInfo {
+ using Table = Schema::BoxHostV2;
+
+ Schema::BoxHostV2::HostConfigId::Type HostConfigId;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, THostInfo,
+ Table::HostConfigId
+ > adapter(
+ &THostInfo::HostConfigId
+ );
+ callback(&adapter);
+ }
+ };
+
+ using Table = Schema::Box;
+
using TUserIds = TSet<Schema::BoxUser::TKey::Type>;
using THosts = TMap<THostKey, THostInfo>;
-
- Table::Name::Type Name;
- TMaybe<Table::Generation::Type> Generation;
- TUserIds UserIds;
- THosts Hosts;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TBoxInfo,
- Table::Name,
- Table::Generation,
- TInlineTable<TUserIds, Schema::BoxUser>,
- TInlineTable<THosts, Schema::BoxHostV2>
- > adapter(
- &TBoxInfo::Name,
- &TBoxInfo::Generation,
- &TBoxInfo::UserIds,
- &TBoxInfo::Hosts
- );
- callback(&adapter);
- }
- };
-
- struct TStoragePoolInfo {
- using Table = Schema::BoxStoragePool;
-
- struct TPDiskFilter {
+
+ Table::Name::Type Name;
+ TMaybe<Table::Generation::Type> Generation;
+ TUserIds UserIds;
+ THosts Hosts;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TBoxInfo,
+ Table::Name,
+ Table::Generation,
+ TInlineTable<TUserIds, Schema::BoxUser>,
+ TInlineTable<THosts, Schema::BoxHostV2>
+ > adapter(
+ &TBoxInfo::Name,
+ &TBoxInfo::Generation,
+ &TBoxInfo::UserIds,
+ &TBoxInfo::Hosts
+ );
+ callback(&adapter);
+ }
+ };
+
+ struct TStoragePoolInfo {
+ using Table = Schema::BoxStoragePool;
+
+ struct TPDiskFilter {
Schema::BoxStoragePoolPDiskFilter::BoxId::Type BoxId{};
Schema::BoxStoragePoolPDiskFilter::StoragePoolId::Type StoragePoolId{};
- TMaybe<Schema::BoxStoragePoolPDiskFilter::TypeCol::Type> Type;
- TMaybe<Schema::BoxStoragePoolPDiskFilter::SharedWithOs::Type> SharedWithOs;
- TMaybe<Schema::BoxStoragePoolPDiskFilter::ReadCentric::Type> ReadCentric;
- TMaybe<Schema::BoxStoragePoolPDiskFilter::Kind::Type> Kind;
-
- template<typename TRowset>
- static TPDiskFilter CreateFromRowset(const TRowset &rowset) {
- using T = Schema::BoxStoragePoolPDiskFilter;
- TPDiskFilter result;
- result.BoxId = rowset.template GetValue<T::BoxId>();
- result.StoragePoolId = rowset.template GetValue<T::StoragePoolId>();
- if (rowset.template HaveValue<T::TypeCol>()) {
- result.Type = rowset.template GetValue<T::TypeCol>();
- }
- if (rowset.template HaveValue<T::SharedWithOs>()) {
- result.SharedWithOs = rowset.template GetValue<T::SharedWithOs>();
- }
- if (rowset.template HaveValue<T::ReadCentric>()) {
- result.ReadCentric = rowset.template GetValue<T::ReadCentric>();
- }
- if (rowset.template HaveValue<T::Kind>()) {
- result.Kind = rowset.template GetValue<T::Kind>();
- }
- return result;
- }
-
- bool MatchPDisk(ui64 category, TMaybe<bool> sharedWithOs, TMaybe<bool> readCentric) const {
- TPDiskCategory c(category);
-
- // determine disk type in terms of configuration
- Schema::BoxStoragePoolPDiskFilter::TypeCol::Type type = PDiskTypeToPDiskType(c.Type());
-
- // obtain disk kind
- Schema::BoxStoragePoolPDiskFilter::Kind::Type kind = c.Kind();
-
- return (!Type || *Type == type)
- && (!SharedWithOs || *SharedWithOs == sharedWithOs)
- && (!ReadCentric || *ReadCentric == readCentric)
- && (!Kind || *Kind == kind);
- }
-
- bool MatchPDisk(const TPDiskInfo& pdisk) const {
- return MatchPDisk(pdisk.Kind, pdisk.SharedWithOs, pdisk.ReadCentric);
- }
-
- void Output(IOutputStream& s) const {
- bool first = true;
- auto comma = [&] { return std::exchange(first, false) ? "" : ","; };
- if (const auto& x = Type) {
- s << comma() << "Type:" << NKikimrBlobStorage::EPDiskType_Name(*x);
- }
- if (const auto& x = SharedWithOs) {
- s << comma() << "SharedWithOs:" << (int)*x;
- }
- if (const auto& x = ReadCentric) {
- s << comma() << "ReadCentric:" << (int)*x;
- }
- if (const auto& x = Kind) {
- s << comma() << "Kind:" << *x;
- }
- }
-
- static TString ToString(const TSet<TPDiskFilter>& filters) {
- TStringStream s;
- for (auto it = filters.begin(); it != filters.end(); ++it) {
- if (it != filters.begin()) {
- s << "|";
- }
- it->Output(s);
- }
- return s.Str();
- }
-
- auto GetKey() const {
- return std::tie(BoxId, StoragePoolId, Type, SharedWithOs, ReadCentric, Kind);
- }
-
- friend bool operator <(const TPDiskFilter &x, const TPDiskFilter &y) {
- return x.GetKey() < y.GetKey();
- }
-
- Y_SAVELOAD_DEFINE(Type, SharedWithOs, ReadCentric, Kind)
- };
-
- Table::Name::Type Name;
- Table::ErasureSpecies::Type ErasureSpecies;
- TMaybe<Table::RealmLevelBegin::Type> RealmLevelBegin;
- TMaybe<Table::RealmLevelEnd::Type> RealmLevelEnd;
- TMaybe<Table::DomainLevelBegin::Type> DomainLevelBegin;
- TMaybe<Table::DomainLevelEnd::Type> DomainLevelEnd;
- TMaybe<Table::NumFailRealms::Type> NumFailRealms;
- TMaybe<Table::NumFailDomainsPerFailRealm::Type> NumFailDomainsPerFailRealm;
- TMaybe<Table::NumVDisksPerFailDomain::Type> NumVDisksPerFailDomain;
- Table::VDiskKind::Type VDiskKind;
- TMaybe<Table::SpaceBytes::Type> SpaceBytes;
- TMaybe<Table::WriteIOPS::Type> WriteIOPS;
- TMaybe<Table::WriteBytesPerSecond::Type> WriteBytesPerSecond;
- TMaybe<Table::ReadIOPS::Type> ReadIOPS;
- TMaybe<Table::ReadBytesPerSecond::Type> ReadBytesPerSecond;
- TMaybe<Table::InMemCacheBytes::Type> InMemCacheBytes;
- Table::Kind::Type Kind;
- Table::NumGroups::Type NumGroups;
- TMaybe<Table::Generation::Type> Generation;
+ TMaybe<Schema::BoxStoragePoolPDiskFilter::TypeCol::Type> Type;
+ TMaybe<Schema::BoxStoragePoolPDiskFilter::SharedWithOs::Type> SharedWithOs;
+ TMaybe<Schema::BoxStoragePoolPDiskFilter::ReadCentric::Type> ReadCentric;
+ TMaybe<Schema::BoxStoragePoolPDiskFilter::Kind::Type> Kind;
+
+ template<typename TRowset>
+ static TPDiskFilter CreateFromRowset(const TRowset &rowset) {
+ using T = Schema::BoxStoragePoolPDiskFilter;
+ TPDiskFilter result;
+ result.BoxId = rowset.template GetValue<T::BoxId>();
+ result.StoragePoolId = rowset.template GetValue<T::StoragePoolId>();
+ if (rowset.template HaveValue<T::TypeCol>()) {
+ result.Type = rowset.template GetValue<T::TypeCol>();
+ }
+ if (rowset.template HaveValue<T::SharedWithOs>()) {
+ result.SharedWithOs = rowset.template GetValue<T::SharedWithOs>();
+ }
+ if (rowset.template HaveValue<T::ReadCentric>()) {
+ result.ReadCentric = rowset.template GetValue<T::ReadCentric>();
+ }
+ if (rowset.template HaveValue<T::Kind>()) {
+ result.Kind = rowset.template GetValue<T::Kind>();
+ }
+ return result;
+ }
+
+ bool MatchPDisk(ui64 category, TMaybe<bool> sharedWithOs, TMaybe<bool> readCentric) const {
+ TPDiskCategory c(category);
+
+ // determine disk type in terms of configuration
+ Schema::BoxStoragePoolPDiskFilter::TypeCol::Type type = PDiskTypeToPDiskType(c.Type());
+
+ // obtain disk kind
+ Schema::BoxStoragePoolPDiskFilter::Kind::Type kind = c.Kind();
+
+ return (!Type || *Type == type)
+ && (!SharedWithOs || *SharedWithOs == sharedWithOs)
+ && (!ReadCentric || *ReadCentric == readCentric)
+ && (!Kind || *Kind == kind);
+ }
+
+ bool MatchPDisk(const TPDiskInfo& pdisk) const {
+ return MatchPDisk(pdisk.Kind, pdisk.SharedWithOs, pdisk.ReadCentric);
+ }
+
+ void Output(IOutputStream& s) const {
+ bool first = true;
+ auto comma = [&] { return std::exchange(first, false) ? "" : ","; };
+ if (const auto& x = Type) {
+ s << comma() << "Type:" << NKikimrBlobStorage::EPDiskType_Name(*x);
+ }
+ if (const auto& x = SharedWithOs) {
+ s << comma() << "SharedWithOs:" << (int)*x;
+ }
+ if (const auto& x = ReadCentric) {
+ s << comma() << "ReadCentric:" << (int)*x;
+ }
+ if (const auto& x = Kind) {
+ s << comma() << "Kind:" << *x;
+ }
+ }
+
+ static TString ToString(const TSet<TPDiskFilter>& filters) {
+ TStringStream s;
+ for (auto it = filters.begin(); it != filters.end(); ++it) {
+ if (it != filters.begin()) {
+ s << "|";
+ }
+ it->Output(s);
+ }
+ return s.Str();
+ }
+
+ auto GetKey() const {
+ return std::tie(BoxId, StoragePoolId, Type, SharedWithOs, ReadCentric, Kind);
+ }
+
+ friend bool operator <(const TPDiskFilter &x, const TPDiskFilter &y) {
+ return x.GetKey() < y.GetKey();
+ }
+
+ Y_SAVELOAD_DEFINE(Type, SharedWithOs, ReadCentric, Kind)
+ };
+
+ Table::Name::Type Name;
+ Table::ErasureSpecies::Type ErasureSpecies;
+ TMaybe<Table::RealmLevelBegin::Type> RealmLevelBegin;
+ TMaybe<Table::RealmLevelEnd::Type> RealmLevelEnd;
+ TMaybe<Table::DomainLevelBegin::Type> DomainLevelBegin;
+ TMaybe<Table::DomainLevelEnd::Type> DomainLevelEnd;
+ TMaybe<Table::NumFailRealms::Type> NumFailRealms;
+ TMaybe<Table::NumFailDomainsPerFailRealm::Type> NumFailDomainsPerFailRealm;
+ TMaybe<Table::NumVDisksPerFailDomain::Type> NumVDisksPerFailDomain;
+ Table::VDiskKind::Type VDiskKind;
+ TMaybe<Table::SpaceBytes::Type> SpaceBytes;
+ TMaybe<Table::WriteIOPS::Type> WriteIOPS;
+ TMaybe<Table::WriteBytesPerSecond::Type> WriteBytesPerSecond;
+ TMaybe<Table::ReadIOPS::Type> ReadIOPS;
+ TMaybe<Table::ReadBytesPerSecond::Type> ReadBytesPerSecond;
+ TMaybe<Table::InMemCacheBytes::Type> InMemCacheBytes;
+ Table::Kind::Type Kind;
+ Table::NumGroups::Type NumGroups;
+ TMaybe<Table::Generation::Type> Generation;
TMaybe<Table::EncryptionMode::Type> EncryptionMode; // null on old versions
- TMaybe<ui64> SchemeshardId;
- TMaybe<ui64> PathItemId;
- bool RandomizeGroupMapping;
-
- bool IsSameGeometry(const TStoragePoolInfo& other) const {
- return ErasureSpecies == other.ErasureSpecies
- && RealmLevelBegin == other.RealmLevelBegin
- && RealmLevelEnd == other.RealmLevelEnd
- && DomainLevelBegin == other.DomainLevelBegin
- && DomainLevelEnd == other.DomainLevelEnd
- && NumFailRealms == other.NumFailRealms
- && NumFailDomainsPerFailRealm == other.NumFailDomainsPerFailRealm
- && NumVDisksPerFailDomain == other.NumVDisksPerFailDomain;
- }
-
- bool HasGroupGeometry() const {
- return RealmLevelBegin || RealmLevelEnd || DomainLevelBegin || DomainLevelEnd || NumFailRealms ||
- NumFailDomainsPerFailRealm || NumVDisksPerFailDomain;
- }
-
- NKikimrBlobStorage::TGroupGeometry GetGroupGeometry() const {
- NKikimrBlobStorage::TGroupGeometry res;
- if (RealmLevelBegin) {
- res.SetRealmLevelBegin(*RealmLevelBegin);
- }
- if (RealmLevelEnd) {
- res.SetRealmLevelEnd(*RealmLevelEnd);
- }
- if (DomainLevelBegin) {
- res.SetDomainLevelBegin(*DomainLevelBegin);
- }
- if (DomainLevelEnd) {
- res.SetDomainLevelEnd(*DomainLevelEnd);
- }
- if (NumFailRealms) {
- res.SetNumFailRealms(*NumFailRealms);
- }
- if (NumFailDomainsPerFailRealm) {
- res.SetNumFailDomainsPerFailRealm(*NumFailDomainsPerFailRealm);
- }
- if (NumVDisksPerFailDomain) {
- res.SetNumVDisksPerFailDomain(*NumVDisksPerFailDomain);
- }
- return res;
- }
-
- bool HasUsagePattern() const {
- return SpaceBytes || WriteIOPS || WriteBytesPerSecond || ReadIOPS || ReadBytesPerSecond || InMemCacheBytes;
- }
-
- NKikimrBlobStorage::TGroupUsagePattern GetUsagePattern() const {
- NKikimrBlobStorage::TGroupUsagePattern res;
- if (SpaceBytes) {
- res.SetSpaceBytes(*SpaceBytes);
- }
- if (WriteIOPS) {
- res.SetWriteIOPS(*WriteIOPS);
- }
- if (WriteBytesPerSecond) {
- res.SetWriteBytesPerSecond(*WriteBytesPerSecond);
- }
- if (ReadIOPS) {
- res.SetReadIOPS(*ReadIOPS);
- }
- if (ReadBytesPerSecond) {
- res.SetReadBytesPerSecond(*ReadBytesPerSecond);
- }
- if (InMemCacheBytes) {
- res.SetInMemCacheBytes(*InMemCacheBytes);
- }
- return res;
- }
-
+ TMaybe<ui64> SchemeshardId;
+ TMaybe<ui64> PathItemId;
+ bool RandomizeGroupMapping;
+
+ bool IsSameGeometry(const TStoragePoolInfo& other) const {
+ return ErasureSpecies == other.ErasureSpecies
+ && RealmLevelBegin == other.RealmLevelBegin
+ && RealmLevelEnd == other.RealmLevelEnd
+ && DomainLevelBegin == other.DomainLevelBegin
+ && DomainLevelEnd == other.DomainLevelEnd
+ && NumFailRealms == other.NumFailRealms
+ && NumFailDomainsPerFailRealm == other.NumFailDomainsPerFailRealm
+ && NumVDisksPerFailDomain == other.NumVDisksPerFailDomain;
+ }
+
+ bool HasGroupGeometry() const {
+ return RealmLevelBegin || RealmLevelEnd || DomainLevelBegin || DomainLevelEnd || NumFailRealms ||
+ NumFailDomainsPerFailRealm || NumVDisksPerFailDomain;
+ }
+
+ NKikimrBlobStorage::TGroupGeometry GetGroupGeometry() const {
+ NKikimrBlobStorage::TGroupGeometry res;
+ if (RealmLevelBegin) {
+ res.SetRealmLevelBegin(*RealmLevelBegin);
+ }
+ if (RealmLevelEnd) {
+ res.SetRealmLevelEnd(*RealmLevelEnd);
+ }
+ if (DomainLevelBegin) {
+ res.SetDomainLevelBegin(*DomainLevelBegin);
+ }
+ if (DomainLevelEnd) {
+ res.SetDomainLevelEnd(*DomainLevelEnd);
+ }
+ if (NumFailRealms) {
+ res.SetNumFailRealms(*NumFailRealms);
+ }
+ if (NumFailDomainsPerFailRealm) {
+ res.SetNumFailDomainsPerFailRealm(*NumFailDomainsPerFailRealm);
+ }
+ if (NumVDisksPerFailDomain) {
+ res.SetNumVDisksPerFailDomain(*NumVDisksPerFailDomain);
+ }
+ return res;
+ }
+
+ bool HasUsagePattern() const {
+ return SpaceBytes || WriteIOPS || WriteBytesPerSecond || ReadIOPS || ReadBytesPerSecond || InMemCacheBytes;
+ }
+
+ NKikimrBlobStorage::TGroupUsagePattern GetUsagePattern() const {
+ NKikimrBlobStorage::TGroupUsagePattern res;
+ if (SpaceBytes) {
+ res.SetSpaceBytes(*SpaceBytes);
+ }
+ if (WriteIOPS) {
+ res.SetWriteIOPS(*WriteIOPS);
+ }
+ if (WriteBytesPerSecond) {
+ res.SetWriteBytesPerSecond(*WriteBytesPerSecond);
+ }
+ if (ReadIOPS) {
+ res.SetReadIOPS(*ReadIOPS);
+ }
+ if (ReadBytesPerSecond) {
+ res.SetReadBytesPerSecond(*ReadBytesPerSecond);
+ }
+ if (InMemCacheBytes) {
+ res.SetInMemCacheBytes(*InMemCacheBytes);
+ }
+ return res;
+ }
+
using TUserIds = TSet<Schema::BoxStoragePoolUser::TKey::Type>;
using TPDiskFilters = TSet<TPDiskFilter>;
-
- TUserIds UserIds;
- TPDiskFilters PDiskFilters;
-
- template<typename T>
- static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
- static TTableAdapter<Table, TStoragePoolInfo,
- Table::Name,
- Table::ErasureSpecies,
- Table::RealmLevelBegin,
- Table::RealmLevelEnd,
- Table::DomainLevelBegin,
- Table::DomainLevelEnd,
- Table::NumFailRealms,
- Table::NumFailDomainsPerFailRealm,
- Table::NumVDisksPerFailDomain,
- Table::VDiskKind,
- Table::SpaceBytes,
- Table::WriteIOPS,
- Table::WriteBytesPerSecond,
- Table::ReadIOPS,
- Table::ReadBytesPerSecond,
- Table::InMemCacheBytes,
- Table::Kind,
- Table::NumGroups,
- Table::Generation,
+
+ TUserIds UserIds;
+ TPDiskFilters PDiskFilters;
+
+ template<typename T>
+ static void Apply(TBlobStorageController* /*controller*/, T&& callback) {
+ static TTableAdapter<Table, TStoragePoolInfo,
+ Table::Name,
+ Table::ErasureSpecies,
+ Table::RealmLevelBegin,
+ Table::RealmLevelEnd,
+ Table::DomainLevelBegin,
+ Table::DomainLevelEnd,
+ Table::NumFailRealms,
+ Table::NumFailDomainsPerFailRealm,
+ Table::NumVDisksPerFailDomain,
+ Table::VDiskKind,
+ Table::SpaceBytes,
+ Table::WriteIOPS,
+ Table::WriteBytesPerSecond,
+ Table::ReadIOPS,
+ Table::ReadBytesPerSecond,
+ Table::InMemCacheBytes,
+ Table::Kind,
+ Table::NumGroups,
+ Table::Generation,
Table::EncryptionMode,
- Table::SchemeshardId,
- Table::PathItemId,
- Table::RandomizeGroupMapping,
- TInlineTable<TUserIds, Schema::BoxStoragePoolUser>,
- TInlineTable<TPDiskFilters, Schema::BoxStoragePoolPDiskFilter>
- > adapter(
- &TStoragePoolInfo::Name,
- &TStoragePoolInfo::ErasureSpecies,
- &TStoragePoolInfo::RealmLevelBegin,
- &TStoragePoolInfo::RealmLevelEnd,
- &TStoragePoolInfo::DomainLevelBegin,
- &TStoragePoolInfo::DomainLevelEnd,
- &TStoragePoolInfo::NumFailRealms,
- &TStoragePoolInfo::NumFailDomainsPerFailRealm,
- &TStoragePoolInfo::NumVDisksPerFailDomain,
- &TStoragePoolInfo::VDiskKind,
- &TStoragePoolInfo::SpaceBytes,
- &TStoragePoolInfo::WriteIOPS,
- &TStoragePoolInfo::WriteBytesPerSecond,
- &TStoragePoolInfo::ReadIOPS,
- &TStoragePoolInfo::ReadBytesPerSecond,
- &TStoragePoolInfo::InMemCacheBytes,
- &TStoragePoolInfo::Kind,
- &TStoragePoolInfo::NumGroups,
- &TStoragePoolInfo::Generation,
+ Table::SchemeshardId,
+ Table::PathItemId,
+ Table::RandomizeGroupMapping,
+ TInlineTable<TUserIds, Schema::BoxStoragePoolUser>,
+ TInlineTable<TPDiskFilters, Schema::BoxStoragePoolPDiskFilter>
+ > adapter(
+ &TStoragePoolInfo::Name,
+ &TStoragePoolInfo::ErasureSpecies,
+ &TStoragePoolInfo::RealmLevelBegin,
+ &TStoragePoolInfo::RealmLevelEnd,
+ &TStoragePoolInfo::DomainLevelBegin,
+ &TStoragePoolInfo::DomainLevelEnd,
+ &TStoragePoolInfo::NumFailRealms,
+ &TStoragePoolInfo::NumFailDomainsPerFailRealm,
+ &TStoragePoolInfo::NumVDisksPerFailDomain,
+ &TStoragePoolInfo::VDiskKind,
+ &TStoragePoolInfo::SpaceBytes,
+ &TStoragePoolInfo::WriteIOPS,
+ &TStoragePoolInfo::WriteBytesPerSecond,
+ &TStoragePoolInfo::ReadIOPS,
+ &TStoragePoolInfo::ReadBytesPerSecond,
+ &TStoragePoolInfo::InMemCacheBytes,
+ &TStoragePoolInfo::Kind,
+ &TStoragePoolInfo::NumGroups,
+ &TStoragePoolInfo::Generation,
&TStoragePoolInfo::EncryptionMode,
- &TStoragePoolInfo::SchemeshardId,
- &TStoragePoolInfo::PathItemId,
- &TStoragePoolInfo::RandomizeGroupMapping,
- &TStoragePoolInfo::UserIds,
- &TStoragePoolInfo::PDiskFilters
- );
- callback(&adapter);
- }
- };
-
+ &TStoragePoolInfo::SchemeshardId,
+ &TStoragePoolInfo::PathItemId,
+ &TStoragePoolInfo::RandomizeGroupMapping,
+ &TStoragePoolInfo::UserIds,
+ &TStoragePoolInfo::PDiskFilters
+ );
+ callback(&adapter);
+ }
+ };
+
struct TSerial {
TString Serial;
@@ -1220,613 +1220,613 @@ public:
);
callback(&adapter);
}
-
- void OnCommit() {}
- void OnClone(const THolder<TDriveSerialInfo>&) {}
- };
-
- struct THostRecord {
- TNodeId NodeId;
- TNodeLocation Location;
-
- THostRecord(TEvInterconnect::TNodeInfo&& nodeInfo)
- : NodeId(nodeInfo.NodeId)
- , Location(std::move(nodeInfo.Location))
- {}
- };
-
- class THostRecordMapImpl {
- THashMap<THostId, THostRecord> HostIdToRecord;
- THashMap<TNodeId, THostId> NodeIdToHostId;
-
- public:
- THostRecordMapImpl(TEvInterconnect::TEvNodesInfo *msg) {
- for (TEvInterconnect::TNodeInfo& nodeInfo : msg->Nodes) {
- const THostId hostId(nodeInfo.Host, nodeInfo.Port);
- NodeIdToHostId.emplace(nodeInfo.NodeId, hostId);
- HostIdToRecord.emplace(hostId, std::move(nodeInfo));
- }
- }
-
- const TNodeLocation& GetLocation(TNodeId nodeId) const {
- if (auto it = NodeIdToHostId.find(nodeId); it != NodeIdToHostId.end()) {
- if (auto hostIt = HostIdToRecord.find(it->second); hostIt != HostIdToRecord.end()) {
- return hostIt->second.Location;
- }
- }
- Y_FAIL();
- }
-
- TMaybe<TNodeId> GetNodeId(const THostId& hostId) const {
- if (const auto it = HostIdToRecord.find(hostId); it != HostIdToRecord.end()) {
- return it->second.NodeId;
- } else {
- return {};
- }
- }
-
- TMaybe<THostId> GetHostId(TNodeId nodeId) const {
- if (const auto it = NodeIdToHostId.find(nodeId); it != NodeIdToHostId.end()) {
- return it->second;
- } else {
- return {};
- }
- }
-
- auto begin() const {
- return HostIdToRecord.begin();
- }
-
- auto end() const {
- return HostIdToRecord.end();
- }
+
+ void OnCommit() {}
+ void OnClone(const THolder<TDriveSerialInfo>&) {}
};
- using THostRecordMap = std::shared_ptr<THostRecordMapImpl>;
-
-private:
- TString InstanceId;
- TActorId SelfHealId;
- std::shared_ptr<std::atomic_uint64_t> SelfHealUnreassignableGroups = std::make_shared<std::atomic_uint64_t>();
- TMaybe<TActorId> MigrationId;
- TVSlots VSlots; // ordering is important
- TPDisks PDisks; // ordering is important
- TMap<TSerial, THolder<TDriveSerialInfo>> DrivesSerials;
- TGroups GroupMap;
- THashMap<TGroupId, TGroupInfo*> GroupLookup;
- TMap<TGroupSpecies, TVector<TGroupId>> IndexGroupSpeciesToGroup;
- TMap<TNodeId, TNodeInfo> Nodes;
- Schema::Group::ID::Type NextGroupID = 0;
- Schema::State::NextStoragePoolId::Type NextStoragePoolId = 0;
- ui32 DefaultMaxSlots = 0;
- ui32 PDiskSpaceMarginPromille = 0;
- ui32 GroupReserveMin = 0;
- ui32 GroupReservePart = 0;
- ui32 MaxScrubbedDisksAtOnce = 0;
- TTabletCountersBase* TabletCounters;
- TAutoPtr<TTabletCountersBase> TabletCountersPtr;
- TActorId ResponsivenessActorID;
- TTabletResponsivenessPinger* ResponsivenessPinger;
- TMap<THostConfigId, THostConfigInfo> HostConfigs;
- TMap<TBoxId, TBoxInfo> Boxes;
- TMap<TBoxStoragePoolId, TStoragePoolInfo> StoragePools;
- TMultiMap<TBoxStoragePoolId, TGroupId> StoragePoolGroups;
- ui64 NextOperationLogIndex = 1;
- TActorId StatProcessorActorId;
- TInstant LastMetricsCommit;
- bool SelfHealEnable = false;
- bool DonorMode = false;
- TDuration ScrubPeriodicity;
- THashMap<TPDiskId, std::reference_wrapper<const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk>> StaticPDiskMap;
- THashMap<TPDiskId, ui32> StaticPDiskSlotUsage;
- std::unique_ptr<TStoragePoolStat> StoragePoolStat;
- bool StopGivingGroups = false;
- NKikimrBlobStorage::TSerialManagementStage::E SerialManagementStage
- = NKikimrBlobStorage::TSerialManagementStage::DISCOVER_SERIAL;
-
- NKikimrBlobStorage::TPDiskSpaceColor::E PDiskSpaceColorBorder
- = NKikimrBlobStorage::TPDiskSpaceColor::GREEN;
-
- TActorId SystemViewsCollectorId;
-
- // a set of VSlots with LastSeenReady != TInstant::Zero()
- std::unordered_set<TVSlotId, THash<TVSlotId>> NotReadyVSlotIds;
-
- friend class TConfigState;
-
- class TNodeWardenUpdateNotifier;
+ struct THostRecord {
+ TNodeId NodeId;
+ TNodeLocation Location;
+
+ THostRecord(TEvInterconnect::TNodeInfo&& nodeInfo)
+ : NodeId(nodeInfo.NodeId)
+ , Location(std::move(nodeInfo.Location))
+ {}
+ };
+
+ class THostRecordMapImpl {
+ THashMap<THostId, THostRecord> HostIdToRecord;
+ THashMap<TNodeId, THostId> NodeIdToHostId;
+
+ public:
+ THostRecordMapImpl(TEvInterconnect::TEvNodesInfo *msg) {
+ for (TEvInterconnect::TNodeInfo& nodeInfo : msg->Nodes) {
+ const THostId hostId(nodeInfo.Host, nodeInfo.Port);
+ NodeIdToHostId.emplace(nodeInfo.NodeId, hostId);
+ HostIdToRecord.emplace(hostId, std::move(nodeInfo));
+ }
+ }
+
+ const TNodeLocation& GetLocation(TNodeId nodeId) const {
+ if (auto it = NodeIdToHostId.find(nodeId); it != NodeIdToHostId.end()) {
+ if (auto hostIt = HostIdToRecord.find(it->second); hostIt != HostIdToRecord.end()) {
+ return hostIt->second.Location;
+ }
+ }
+ Y_FAIL();
+ }
+
+ TMaybe<TNodeId> GetNodeId(const THostId& hostId) const {
+ if (const auto it = HostIdToRecord.find(hostId); it != HostIdToRecord.end()) {
+ return it->second.NodeId;
+ } else {
+ return {};
+ }
+ }
+
+ TMaybe<THostId> GetHostId(TNodeId nodeId) const {
+ if (const auto it = NodeIdToHostId.find(nodeId); it != NodeIdToHostId.end()) {
+ return it->second;
+ } else {
+ return {};
+ }
+ }
+
+ auto begin() const {
+ return HostIdToRecord.begin();
+ }
+
+ auto end() const {
+ return HostIdToRecord.end();
+ }
+ };
+
+ using THostRecordMap = std::shared_ptr<THostRecordMapImpl>;
+
+private:
+ TString InstanceId;
+ TActorId SelfHealId;
+ std::shared_ptr<std::atomic_uint64_t> SelfHealUnreassignableGroups = std::make_shared<std::atomic_uint64_t>();
+ TMaybe<TActorId> MigrationId;
+ TVSlots VSlots; // ordering is important
+ TPDisks PDisks; // ordering is important
+ TMap<TSerial, THolder<TDriveSerialInfo>> DrivesSerials;
+ TGroups GroupMap;
+ THashMap<TGroupId, TGroupInfo*> GroupLookup;
+ TMap<TGroupSpecies, TVector<TGroupId>> IndexGroupSpeciesToGroup;
+ TMap<TNodeId, TNodeInfo> Nodes;
+ Schema::Group::ID::Type NextGroupID = 0;
+ Schema::State::NextStoragePoolId::Type NextStoragePoolId = 0;
+ ui32 DefaultMaxSlots = 0;
+ ui32 PDiskSpaceMarginPromille = 0;
+ ui32 GroupReserveMin = 0;
+ ui32 GroupReservePart = 0;
+ ui32 MaxScrubbedDisksAtOnce = 0;
+ TTabletCountersBase* TabletCounters;
+ TAutoPtr<TTabletCountersBase> TabletCountersPtr;
+ TActorId ResponsivenessActorID;
+ TTabletResponsivenessPinger* ResponsivenessPinger;
+ TMap<THostConfigId, THostConfigInfo> HostConfigs;
+ TMap<TBoxId, TBoxInfo> Boxes;
+ TMap<TBoxStoragePoolId, TStoragePoolInfo> StoragePools;
+ TMultiMap<TBoxStoragePoolId, TGroupId> StoragePoolGroups;
+ ui64 NextOperationLogIndex = 1;
+ TActorId StatProcessorActorId;
+ TInstant LastMetricsCommit;
+ bool SelfHealEnable = false;
+ bool DonorMode = false;
+ TDuration ScrubPeriodicity;
+ THashMap<TPDiskId, std::reference_wrapper<const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk>> StaticPDiskMap;
+ THashMap<TPDiskId, ui32> StaticPDiskSlotUsage;
+ std::unique_ptr<TStoragePoolStat> StoragePoolStat;
+ bool StopGivingGroups = false;
+ NKikimrBlobStorage::TSerialManagementStage::E SerialManagementStage
+ = NKikimrBlobStorage::TSerialManagementStage::DISCOVER_SERIAL;
+
+ NKikimrBlobStorage::TPDiskSpaceColor::E PDiskSpaceColorBorder
+ = NKikimrBlobStorage::TPDiskSpaceColor::GREEN;
+
+ TActorId SystemViewsCollectorId;
+
+ // a set of VSlots with LastSeenReady != TInstant::Zero()
+ std::unordered_set<TVSlotId, THash<TVSlotId>> NotReadyVSlotIds;
+
+ friend class TConfigState;
+
+ class TNodeWardenUpdateNotifier;
struct TEvPrivate {
enum EEv {
EvUpdateSystemViews = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvUpdateSelfHealCounters,
- EvHostRecordsTimeToLiveExceeded,
- EvDropDonor,
- EvScrub,
- EvVSlotReadyUpdate,
- EvVSlotNotReadyHistogramUpdate,
- EvProcessIncomingEvent,
+ EvUpdateSelfHealCounters,
+ EvHostRecordsTimeToLiveExceeded,
+ EvDropDonor,
+ EvScrub,
+ EvVSlotReadyUpdate,
+ EvVSlotNotReadyHistogramUpdate,
+ EvProcessIncomingEvent,
};
struct TEvUpdateSystemViews : public TEventLocal<TEvUpdateSystemViews, EvUpdateSystemViews> {};
- struct TEvUpdateSelfHealCounters : TEventLocal<TEvUpdateSelfHealCounters, EvUpdateSelfHealCounters> {};
- struct TEvHostRecordsTimeToLiveExceeded : TEventLocal<TEvHostRecordsTimeToLiveExceeded, EvHostRecordsTimeToLiveExceeded> {};
-
- struct TEvDropDonor : TEventLocal<TEvDropDonor, EvDropDonor> {
- std::vector<TVSlotId> VSlotIds;
- };
-
- struct TEvScrub : TEventLocal<TEvScrub, EvScrub> {};
- struct TEvVSlotReadyUpdate : TEventLocal<TEvVSlotReadyUpdate, EvVSlotReadyUpdate> {};
- struct TEvVSlotNotReadyHistogramUpdate : TEventLocal<TEvVSlotNotReadyHistogramUpdate, EvVSlotNotReadyHistogramUpdate> {};
+ struct TEvUpdateSelfHealCounters : TEventLocal<TEvUpdateSelfHealCounters, EvUpdateSelfHealCounters> {};
+ struct TEvHostRecordsTimeToLiveExceeded : TEventLocal<TEvHostRecordsTimeToLiveExceeded, EvHostRecordsTimeToLiveExceeded> {};
+
+ struct TEvDropDonor : TEventLocal<TEvDropDonor, EvDropDonor> {
+ std::vector<TVSlotId> VSlotIds;
+ };
+
+ struct TEvScrub : TEventLocal<TEvScrub, EvScrub> {};
+ struct TEvVSlotReadyUpdate : TEventLocal<TEvVSlotReadyUpdate, EvVSlotReadyUpdate> {};
+ struct TEvVSlotNotReadyHistogramUpdate : TEventLocal<TEvVSlotNotReadyHistogramUpdate, EvVSlotNotReadyHistogramUpdate> {};
};
static constexpr TDuration UpdateSystemViewsPeriod = TDuration::Seconds(5);
- std::unordered_set<TPDiskId, THash<TPDiskId>> SysViewChangedPDisks;
- std::unordered_set<TVSlotId, THash<TVSlotId>> SysViewChangedVSlots;
- std::unordered_set<TGroupId, THash<TGroupId>> SysViewChangedGroups;
- std::unordered_set<TBoxStoragePoolId, THash<TBoxStoragePoolId>> SysViewChangedStoragePools;
- bool SysViewChangedSettings = false;
-
- IActor* CreateSystemViewsCollector();
- void UpdateSystemViews();
-
- bool CommitConfigUpdates(TConfigState& state, bool suppressFailModelChecking, bool suppressDegradedGroupsChecking,
- TTransactionContext& txc, TString *errorDescription);
-
- void CommitSelfHealUpdates(TConfigState& state);
- void CommitScrubUpdates(TConfigState& state, TTransactionContext& txc);
- void CommitStoragePoolStatUpdates(TConfigState& state);
- void CommitSysViewUpdates(TConfigState& state);
-
- void InitializeSelfHealState();
- void FillInSelfHealGroups(TEvControllerUpdateSelfHealInfo& msg, TConfigState *state);
- void ProcessVDiskStatus(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus>& s);
-
- void UpdateSelfHealCounters();
-
- void ValidateInternalState();
-
- TVSlotInfo* FindVSlot(TVSlotId id) {
- auto it = VSlots.find(id);
- return it != VSlots.end() ? it->second.Get() : nullptr;
- }
-
- TVSlotInfo* FindVSlot(TVDiskID id) { // GroupGeneration may be zero
- if (TGroupInfo *group = FindGroup(id.GroupID)) {
- const ui32 index = group->Topology->GetOrderNumber(id);
- const TVSlotInfo *slot = group->VDisksInGroup[index];
- Y_VERIFY(slot->GetShortVDiskId() == TVDiskIdShort(id)); // sanity check
- if (id.GroupGeneration == 0 || id.GroupGeneration == slot->GroupGeneration) {
- return const_cast<TVSlotInfo*>(slot);
- }
- }
- return nullptr;
- }
-
- bool HasScrubVSlot(TVSlotId id) {
- if (TVSlotInfo *slot = FindVSlot(id); slot && !slot->IsBeingDeleted()) {
- return true;
- } else {
- return StaticVSlots.count(id);
- }
- }
-
- template <typename... Types>
- TVSlotInfo& AddVSlot(TVSlotId id, Types... values) {
- SysViewChangedVSlots.insert(id);
- return *VSlots.emplace(id, MakeHolder<TVSlotInfo>(id, std::forward<Types>(values)...)).first->second;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // GROUP ACCESS
-
- TGroupInfo* FindGroup(TGroupId id) {
- if (const auto it = GroupLookup.find(id); it != GroupLookup.end()) {
- Y_VERIFY_DEBUG(GroupMap[id].Get() == it->second && it->second);
- return it->second;
- } else {
- Y_VERIFY_DEBUG(!GroupMap.count(id));
- return nullptr;
- }
- }
-
- template <typename... Types>
- TGroupInfo& AddGroup(TGroupId id, Types&&... values) {
- SysViewChangedGroups.insert(id);
- auto&& [it, inserted] = GroupMap.emplace(id, MakeHolder<TGroupInfo>(id, std::forward<Types>(values)...));
- Y_VERIFY(inserted);
- GroupLookup.emplace(id, it->second.Get());
- return *it->second;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // NODE ACCESS
-
- TNodeInfo* FindNode(TNodeId id) {
- auto it = Nodes.find(id);
- if (it == Nodes.end())
- return nullptr;
- return &it->second;
- }
-
- TNodeInfo& GetNode(TNodeId id) {
- auto it = Nodes.find(id);
- if (it == Nodes.end()) {
- it = Nodes.emplace(id, TNodeInfo()).first;
- }
- return it->second;
- }
-
- bool AddNode(TNodeId id, const TNodeInfo& info) {
- return Nodes.emplace(id, info).second;
- }
-
- TPDiskInfo* FindPDisk(TPDiskId id) {
- auto it = PDisks.find(id);
- return it != PDisks.end() ? it->second.Get() : nullptr;
- }
-
- template<typename... Types>
- TPDiskInfo& AddPDisk(TPDiskId id, Types&&... values) {
- SysViewChangedPDisks.insert(id);
- auto&& [it, inserted] = PDisks.emplace(id, MakeHolder<TPDiskInfo>(std::forward<Types>(values)...));
- Y_VERIFY(inserted);
- return *it->second;
- }
-
- //TGroupStatusTracker GroupStatusTracker;
+ std::unordered_set<TPDiskId, THash<TPDiskId>> SysViewChangedPDisks;
+ std::unordered_set<TVSlotId, THash<TVSlotId>> SysViewChangedVSlots;
+ std::unordered_set<TGroupId, THash<TGroupId>> SysViewChangedGroups;
+ std::unordered_set<TBoxStoragePoolId, THash<TBoxStoragePoolId>> SysViewChangedStoragePools;
+ bool SysViewChangedSettings = false;
+
+ IActor* CreateSystemViewsCollector();
+ void UpdateSystemViews();
+
+ bool CommitConfigUpdates(TConfigState& state, bool suppressFailModelChecking, bool suppressDegradedGroupsChecking,
+ TTransactionContext& txc, TString *errorDescription);
+
+ void CommitSelfHealUpdates(TConfigState& state);
+ void CommitScrubUpdates(TConfigState& state, TTransactionContext& txc);
+ void CommitStoragePoolStatUpdates(TConfigState& state);
+ void CommitSysViewUpdates(TConfigState& state);
+
+ void InitializeSelfHealState();
+ void FillInSelfHealGroups(TEvControllerUpdateSelfHealInfo& msg, TConfigState *state);
+ void ProcessVDiskStatus(const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus>& s);
+
+ void UpdateSelfHealCounters();
+
+ void ValidateInternalState();
+
+ TVSlotInfo* FindVSlot(TVSlotId id) {
+ auto it = VSlots.find(id);
+ return it != VSlots.end() ? it->second.Get() : nullptr;
+ }
+
+ TVSlotInfo* FindVSlot(TVDiskID id) { // GroupGeneration may be zero
+ if (TGroupInfo *group = FindGroup(id.GroupID)) {
+ const ui32 index = group->Topology->GetOrderNumber(id);
+ const TVSlotInfo *slot = group->VDisksInGroup[index];
+ Y_VERIFY(slot->GetShortVDiskId() == TVDiskIdShort(id)); // sanity check
+ if (id.GroupGeneration == 0 || id.GroupGeneration == slot->GroupGeneration) {
+ return const_cast<TVSlotInfo*>(slot);
+ }
+ }
+ return nullptr;
+ }
+
+ bool HasScrubVSlot(TVSlotId id) {
+ if (TVSlotInfo *slot = FindVSlot(id); slot && !slot->IsBeingDeleted()) {
+ return true;
+ } else {
+ return StaticVSlots.count(id);
+ }
+ }
+
+ template <typename... Types>
+ TVSlotInfo& AddVSlot(TVSlotId id, Types... values) {
+ SysViewChangedVSlots.insert(id);
+ return *VSlots.emplace(id, MakeHolder<TVSlotInfo>(id, std::forward<Types>(values)...)).first->second;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GROUP ACCESS
+
+ TGroupInfo* FindGroup(TGroupId id) {
+ if (const auto it = GroupLookup.find(id); it != GroupLookup.end()) {
+ Y_VERIFY_DEBUG(GroupMap[id].Get() == it->second && it->second);
+ return it->second;
+ } else {
+ Y_VERIFY_DEBUG(!GroupMap.count(id));
+ return nullptr;
+ }
+ }
+
+ template <typename... Types>
+ TGroupInfo& AddGroup(TGroupId id, Types&&... values) {
+ SysViewChangedGroups.insert(id);
+ auto&& [it, inserted] = GroupMap.emplace(id, MakeHolder<TGroupInfo>(id, std::forward<Types>(values)...));
+ Y_VERIFY(inserted);
+ GroupLookup.emplace(id, it->second.Get());
+ return *it->second;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // NODE ACCESS
+
+ TNodeInfo* FindNode(TNodeId id) {
+ auto it = Nodes.find(id);
+ if (it == Nodes.end())
+ return nullptr;
+ return &it->second;
+ }
+
+ TNodeInfo& GetNode(TNodeId id) {
+ auto it = Nodes.find(id);
+ if (it == Nodes.end()) {
+ it = Nodes.emplace(id, TNodeInfo()).first;
+ }
+ return it->second;
+ }
+
+ bool AddNode(TNodeId id, const TNodeInfo& info) {
+ return Nodes.emplace(id, info).second;
+ }
+
+ TPDiskInfo* FindPDisk(TPDiskId id) {
+ auto it = PDisks.find(id);
+ return it != PDisks.end() ? it->second.Get() : nullptr;
+ }
+
+ template<typename... Types>
+ TPDiskInfo& AddPDisk(TPDiskId id, Types&&... values) {
+ SysViewChangedPDisks.insert(id);
+ auto&& [it, inserted] = PDisks.emplace(id, MakeHolder<TPDiskInfo>(std::forward<Types>(values)...));
+ Y_VERIFY(inserted);
+ return *it->second;
+ }
+
+ //TGroupStatusTracker GroupStatusTracker;
TDeque<TAutoPtr<IEventHandle>> InitQueue;
THashMap<Schema::Group::Owner::Type, Schema::Group::ID::Type> OwnerIdIdxToGroup;
-
- void ReadGroups(TSet<ui32>& groupIDsToRead, bool discard, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result);
-
+
+ void ReadGroups(TSet<ui32>& groupIDsToRead, bool discard, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result);
+
void ReadPDisk(const TPDiskId& pdiskId, const TPDiskInfo& pdisk,
TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result,
const NKikimrBlobStorage::EEntityStatus entityStatus);
-
- void ReadVSlot(const TVSlotInfo& vslot, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result);
-
- void DefaultSignalTabletActive(const TActorContext&) override
- {} // do nothing, we will signal tablet active explicitly after initialization
-
- void PassAway() override {
- if (ResponsivenessPinger) {
- ResponsivenessPinger->Detach(TActivationContext::ActorContextFor(ResponsivenessActorID));
- ResponsivenessPinger = nullptr;
- }
- for (TActorId *ptr : {&SelfHealId, &StatProcessorActorId, &SystemViewsCollectorId}) {
- if (const TActorId actorId = std::exchange(*ptr, {})) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, SelfId(), nullptr, 0));
- }
- }
- return TActor::PassAway();
- }
-
- void OnDetach(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC02, "OnDetach");
- PassAway();
- }
-
- void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC03, "OnTabletDead", (Event, ev->Get()->ToString()));
- PassAway();
- }
-
+
+ void ReadVSlot(const TVSlotInfo& vslot, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result);
+
+ void DefaultSignalTabletActive(const TActorContext&) override
+ {} // do nothing, we will signal tablet active explicitly after initialization
+
+ void PassAway() override {
+ if (ResponsivenessPinger) {
+ ResponsivenessPinger->Detach(TActivationContext::ActorContextFor(ResponsivenessActorID));
+ ResponsivenessPinger = nullptr;
+ }
+ for (TActorId *ptr : {&SelfHealId, &StatProcessorActorId, &SystemViewsCollectorId}) {
+ if (const TActorId actorId = std::exchange(*ptr, {})) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, actorId, SelfId(), nullptr, 0));
+ }
+ }
+ return TActor::PassAway();
+ }
+
+ void OnDetach(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC02, "OnDetach");
+ PassAway();
+ }
+
+ void OnTabletDead(TEvTablet::TEvTabletDead::TPtr &ev, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC03, "OnTabletDead", (Event, ev->Get()->ToString()));
+ PassAway();
+ }
+
void Execute(TAutoPtr<ITransaction> tx) {
- TTabletExecutedFlat::Execute(tx, TActivationContext::AsActorContext());
- }
-
- void OnActivateExecutor(const TActorContext&) override;
-
- bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) override;
-
- void RenderResourceValues(IOutputStream& out, const TResourceRawValues& current);
- void RenderHeader(IOutputStream& out);
- void RenderFooter(IOutputStream& out);
- void RenderMonPage(IOutputStream& out);
+ TTabletExecutedFlat::Execute(tx, TActivationContext::AsActorContext());
+ }
+
+ void OnActivateExecutor(const TActorContext&) override;
+
+ bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) override;
+
+ void RenderResourceValues(IOutputStream& out, const TResourceRawValues& current);
+ void RenderHeader(IOutputStream& out);
+ void RenderFooter(IOutputStream& out);
+ void RenderMonPage(IOutputStream& out);
void RenderInternalTables(IOutputStream& out, const TString& table);
- void RenderGroupDetail(IOutputStream &out, TGroupId groupId);
- void RenderGroupsInStoragePool(IOutputStream &out, const TBoxStoragePoolId& id);
- void RenderVSlotTable(IOutputStream& out, std::function<void()> callback);
- void RenderVSlotRow(IOutputStream& out, const TVSlotInfo& slot);
- void RenderGroupTable(IOutputStream& out, std::function<void()> callback);
- void RenderGroupRow(IOutputStream& out, const TGroupInfo& group);
-
- void Enqueue(STFUNC_SIG) override {
- Y_UNUSED(ctx);
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC04, "Enqueue", (TabletID, TabletID()), (Type, ev->GetTypeRewrite()),
- (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
- InitQueue.push_back(ev);
- }
-
- THostRecordMap HostRecords;
- void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev);
- void HandleHostRecordsTimeToLiveExceeded();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Online state
- void Handle(TEvBlobStorage::TEvControllerRegisterNode::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerGetGroup::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerSelectGroups::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr &ev);
+ void RenderGroupDetail(IOutputStream &out, TGroupId groupId);
+ void RenderGroupsInStoragePool(IOutputStream &out, const TBoxStoragePoolId& id);
+ void RenderVSlotTable(IOutputStream& out, std::function<void()> callback);
+ void RenderVSlotRow(IOutputStream& out, const TVSlotInfo& slot);
+ void RenderGroupTable(IOutputStream& out, std::function<void()> callback);
+ void RenderGroupRow(IOutputStream& out, const TGroupInfo& group);
+
+ void Enqueue(STFUNC_SIG) override {
+ Y_UNUSED(ctx);
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC04, "Enqueue", (TabletID, TabletID()), (Type, ev->GetTypeRewrite()),
+ (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
+ InitQueue.push_back(ev);
+ }
+
+ THostRecordMap HostRecords;
+ void Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev);
+ void HandleHostRecordsTimeToLiveExceeded();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Online state
+ void Handle(TEvBlobStorage::TEvControllerRegisterNode::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerGetGroup::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerSelectGroups::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerUpdateDiskStatus::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr &ev);
void Handle(TEvBlobStorage::TEvControllerUpdateNodeDrives::TPtr &ev);
- void Handle(TEvControllerCommitGroupLatencies::TPtr &ev);
- void Handle(TEvBlobStorage::TEvRequestControllerInfo::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerConfigRequest::TPtr &ev);
- void Handle(TEvBlobStorage::TEvControllerProposeGroupKey::TPtr &ev);
- void ForwardToSystemViewsCollector(STATEFN_SIG);
- void Handle(TEvPrivate::TEvUpdateSystemViews::TPtr &ev);
- void Handle(TEvents::TEvPoisonPill::TPtr& ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Scrub handling
-
- class TScrubState {
- friend class TBlobStorageController;
- friend class TTxScrubCommit;
- class TImpl;
- std::unique_ptr<TImpl> Impl;
-
- public:
- TScrubState(TBlobStorageController *self);
- ~TScrubState();
- void HandleTimer();
- void AddItem(TVSlotId vslotId, std::optional<TString> state, TInstant scrubCycleStartTime,
- TInstant scrubCycleFinishTime, std::optional<bool> success);
- void OnDeletePDisk(TPDiskId pdiskId);
- void OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc);
- void OnDeleteGroup(TGroupId groupId);
- void Render(IOutputStream& str);
- void OnNodeDisconnected(TNodeId nodeId);
- void OnScrubPeriodicityChange();
- void OnMaxScrubbedDisksAtOnceChange();
- void UpdateVDiskState(const TVSlotInfo *vslot);
- };
-
- TScrubState ScrubState;
-
- void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev);
- void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev);
- void Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev);
-
- void IssueInitialGroupContent();
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Metric collection
-
- struct TSelectGroupsQueueItem {
+ void Handle(TEvControllerCommitGroupLatencies::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvRequestControllerInfo::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerGroupReconfigureWipe::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerConfigRequest::TPtr &ev);
+ void Handle(TEvBlobStorage::TEvControllerProposeGroupKey::TPtr &ev);
+ void ForwardToSystemViewsCollector(STATEFN_SIG);
+ void Handle(TEvPrivate::TEvUpdateSystemViews::TPtr &ev);
+ void Handle(TEvents::TEvPoisonPill::TPtr& ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Scrub handling
+
+ class TScrubState {
+ friend class TBlobStorageController;
+ friend class TTxScrubCommit;
+ class TImpl;
+ std::unique_ptr<TImpl> Impl;
+
+ public:
+ TScrubState(TBlobStorageController *self);
+ ~TScrubState();
+ void HandleTimer();
+ void AddItem(TVSlotId vslotId, std::optional<TString> state, TInstant scrubCycleStartTime,
+ TInstant scrubCycleFinishTime, std::optional<bool> success);
+ void OnDeletePDisk(TPDiskId pdiskId);
+ void OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc);
+ void OnDeleteGroup(TGroupId groupId);
+ void Render(IOutputStream& str);
+ void OnNodeDisconnected(TNodeId nodeId);
+ void OnScrubPeriodicityChange();
+ void OnMaxScrubbedDisksAtOnceChange();
+ void UpdateVDiskState(const TVSlotInfo *vslot);
+ };
+
+ TScrubState ScrubState;
+
+ void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev);
+ void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev);
+ void Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev);
+
+ void IssueInitialGroupContent();
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Metric collection
+
+ struct TSelectGroupsQueueItem {
TActorId RespondTo;
- ui64 Cookie;
- THolder<TEvBlobStorage::TEvControllerSelectGroupsResult> Event;
- TSet<TPDiskId> BlockedPDisks;
-
- TSelectGroupsQueueItem(TActorId respondTo, ui64 cookie, THolder<TEvBlobStorage::TEvControllerSelectGroupsResult> event)
- : RespondTo(respondTo)
- , Cookie(cookie)
- , Event(std::move(event))
- {}
- };
-
- struct TPDiskToQueueComp {
- using TIterator = TList<TSelectGroupsQueueItem>::iterator;
- using T = std::pair<TPDiskId, TIterator>;
-
- static void *IteratorToPtr(const TIterator& x) {
- return x == TIterator() ? nullptr : &*x;
- }
-
- bool operator ()(const TIterator& x, const TIterator& y) const {
- return IteratorToPtr(x) < IteratorToPtr(y);
- }
-
- bool operator ()(const T& x, const T& y) const {
- return x.first < y.first || (x.first == y.first && (*this)(x.second, y.second));
- }
- };
-
- TList<TSelectGroupsQueueItem> SelectGroupsQueue;
- TSet<std::pair<TPDiskId, TList<TSelectGroupsQueueItem>::iterator>, TPDiskToQueueComp> PDiskToQueue;
-
- void ProcessSelectGroupsQueueItem(TList<TSelectGroupsQueueItem>::iterator it);
-
- void NotifyNodesAwaitingKeysForGroups(ui32 groupId);
+ ui64 Cookie;
+ THolder<TEvBlobStorage::TEvControllerSelectGroupsResult> Event;
+ TSet<TPDiskId> BlockedPDisks;
+
+ TSelectGroupsQueueItem(TActorId respondTo, ui64 cookie, THolder<TEvBlobStorage::TEvControllerSelectGroupsResult> event)
+ : RespondTo(respondTo)
+ , Cookie(cookie)
+ , Event(std::move(event))
+ {}
+ };
+
+ struct TPDiskToQueueComp {
+ using TIterator = TList<TSelectGroupsQueueItem>::iterator;
+ using T = std::pair<TPDiskId, TIterator>;
+
+ static void *IteratorToPtr(const TIterator& x) {
+ return x == TIterator() ? nullptr : &*x;
+ }
+
+ bool operator ()(const TIterator& x, const TIterator& y) const {
+ return IteratorToPtr(x) < IteratorToPtr(y);
+ }
+
+ bool operator ()(const T& x, const T& y) const {
+ return x.first < y.first || (x.first == y.first && (*this)(x.second, y.second));
+ }
+ };
+
+ TList<TSelectGroupsQueueItem> SelectGroupsQueue;
+ TSet<std::pair<TPDiskId, TList<TSelectGroupsQueueItem>::iterator>, TPDiskToQueueComp> PDiskToQueue;
+
+ void ProcessSelectGroupsQueueItem(TList<TSelectGroupsQueueItem>::iterator it);
+
+ void NotifyNodesAwaitingKeysForGroups(ui32 groupId);
ITransaction* CreateTxInitScheme();
ITransaction* CreateTxMigrate();
- ITransaction* CreateTxLoadEverything();
- ITransaction* CreateTxUpdateSeenOperational(TVector<TGroupId> groups);
- ITransaction* CreateTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ);
-
- void Handle(TEvPrivate::TEvDropDonor::TPtr ev);
-
+ ITransaction* CreateTxLoadEverything();
+ ITransaction* CreateTxUpdateSeenOperational(TVector<TGroupId> groups);
+ ITransaction* CreateTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ);
+
+ void Handle(TEvPrivate::TEvDropDonor::TPtr ev);
+
Schema::PDisk::Guid::Type CheckStaticPDisk(TConfigState &state, TPDiskId pdiskId, const TPDiskCategory& category,
- const TMaybe<Schema::PDisk::PDiskConfig::Type>& pdiskConfig, ui32 *staticSlotUsage);
- void AllocatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial, TDriveSerialInfo *driveInfo);
- void ValidatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial, const TDriveSerialInfo& driveInfo,
- std::function<TDriveSerialInfo*()> getMutableItem);
- void FitPDisksForUserConfig(TConfigState &state);
- void FitPDisksForNode(TConfigState& state, ui32 nodeId, const std::vector<TSerial>& serials);
- void FitGroupsForUserConfig(TConfigState &state, ui32 availabilityDomainId,
- const NKikimrBlobStorage::TConfigRequest& cmd, std::deque<ui64> expectedSlotSize,
- NKikimrBlobStorage::TConfigResponse::TStatus& status);
-
-public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_CONTROLLER_ACTOR;
- }
-
+ const TMaybe<Schema::PDisk::PDiskConfig::Type>& pdiskConfig, ui32 *staticSlotUsage);
+ void AllocatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial, TDriveSerialInfo *driveInfo);
+ void ValidatePDiskWithSerial(TConfigState& state, ui32 nodeId, const TSerial& serial, const TDriveSerialInfo& driveInfo,
+ std::function<TDriveSerialInfo*()> getMutableItem);
+ void FitPDisksForUserConfig(TConfigState &state);
+ void FitPDisksForNode(TConfigState& state, ui32 nodeId, const std::vector<TSerial>& serials);
+ void FitGroupsForUserConfig(TConfigState &state, ui32 availabilityDomainId,
+ const NKikimrBlobStorage::TConfigRequest& cmd, std::deque<ui64> expectedSlotSize,
+ NKikimrBlobStorage::TConfigResponse::TStatus& status);
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_CONTROLLER_ACTOR;
+ }
+
TBlobStorageController(const TActorId &tablet, TTabletStorageInfo *info)
- : TActor(&TThis::StateInit)
+ : TActor(&TThis::StateInit)
, TTabletExecutedFlat(info, tablet, new NMiniKQL::TMiniKQLFactory)
- , ResponsivenessPinger(nullptr)
- , ScrubState(this)
- {
- using namespace NBlobStorageController;
- TabletCountersPtr.Reset(new TProtobufTabletCounters<
- ESimpleCounters_descriptor,
- ECumulativeCounters_descriptor,
- EPercentileCounters_descriptor,
- ETxTypes_descriptor
- >());
- TabletCounters = TabletCountersPtr.Get();
- }
-
- STFUNC(StateInit) {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC05, "StateInit event", (Type, ev->GetTypeRewrite()),
- (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- default:
- StateInitImpl(ev, ctx);
- }
- }
-
- std::multimap<ui32, std::unique_ptr<IEventHandle>> IncomingEventQ; // sorted by priority
-
- ui32 GetEventPriority(IEventHandle *ev);
-
- void EnqueueIncomingEvent(STATEFN_SIG) {
- const ui32 priority = GetEventPriority(ev.Get());
- if (IncomingEventQ.empty()) { // for the first event in the queue we have to push special event
- PushProcessIncomingEvent();
- }
- IncomingEventQ.emplace(priority, std::unique_ptr<IEventHandle>(ev.Release()));
- }
-
- void PushProcessIncomingEvent() {
- TActivationContext::Send(new IEventHandle(TEvPrivate::EvProcessIncomingEvent, 0, SelfId(), {}, nullptr, 0));
- }
-
- void ProcessIncomingEvent() {
- Y_VERIFY(!IncomingEventQ.empty());
- const auto it = IncomingEventQ.begin();
- ProcessControllerEvent(it->second.release());
- IncomingEventQ.erase(it);
- if (!IncomingEventQ.empty()) {
- PushProcessIncomingEvent();
- }
- }
-
- void ProcessControllerEvent(TAutoPtr<IEventHandle> ev) {
- const ui32 type = ev->GetTypeRewrite();
- THPTimer timer;
-
- switch (type) {
- hFunc(TEvBlobStorage::TEvControllerRegisterNode, Handle);
- hFunc(TEvBlobStorage::TEvControllerGetGroup, Handle);
- hFunc(TEvBlobStorage::TEvControllerSelectGroups, Handle);
- hFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
- hFunc(TEvBlobStorage::TEvControllerUpdateGroupStat, Handle);
+ , ResponsivenessPinger(nullptr)
+ , ScrubState(this)
+ {
+ using namespace NBlobStorageController;
+ TabletCountersPtr.Reset(new TProtobufTabletCounters<
+ ESimpleCounters_descriptor,
+ ECumulativeCounters_descriptor,
+ EPercentileCounters_descriptor,
+ ETxTypes_descriptor
+ >());
+ TabletCounters = TabletCountersPtr.Get();
+ }
+
+ STFUNC(StateInit) {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC05, "StateInit event", (Type, ev->GetTypeRewrite()),
+ (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ default:
+ StateInitImpl(ev, ctx);
+ }
+ }
+
+ std::multimap<ui32, std::unique_ptr<IEventHandle>> IncomingEventQ; // sorted by priority
+
+ ui32 GetEventPriority(IEventHandle *ev);
+
+ void EnqueueIncomingEvent(STATEFN_SIG) {
+ const ui32 priority = GetEventPriority(ev.Get());
+ if (IncomingEventQ.empty()) { // for the first event in the queue we have to push special event
+ PushProcessIncomingEvent();
+ }
+ IncomingEventQ.emplace(priority, std::unique_ptr<IEventHandle>(ev.Release()));
+ }
+
+ void PushProcessIncomingEvent() {
+ TActivationContext::Send(new IEventHandle(TEvPrivate::EvProcessIncomingEvent, 0, SelfId(), {}, nullptr, 0));
+ }
+
+ void ProcessIncomingEvent() {
+ Y_VERIFY(!IncomingEventQ.empty());
+ const auto it = IncomingEventQ.begin();
+ ProcessControllerEvent(it->second.release());
+ IncomingEventQ.erase(it);
+ if (!IncomingEventQ.empty()) {
+ PushProcessIncomingEvent();
+ }
+ }
+
+ void ProcessControllerEvent(TAutoPtr<IEventHandle> ev) {
+ const ui32 type = ev->GetTypeRewrite();
+ THPTimer timer;
+
+ switch (type) {
+ hFunc(TEvBlobStorage::TEvControllerRegisterNode, Handle);
+ hFunc(TEvBlobStorage::TEvControllerGetGroup, Handle);
+ hFunc(TEvBlobStorage::TEvControllerSelectGroups, Handle);
+ hFunc(TEvBlobStorage::TEvControllerUpdateDiskStatus, Handle);
+ hFunc(TEvBlobStorage::TEvControllerUpdateGroupStat, Handle);
hFunc(TEvBlobStorage::TEvControllerUpdateNodeDrives, Handle);
- hFunc(TEvControllerCommitGroupLatencies, Handle);
- hFunc(TEvBlobStorage::TEvRequestControllerInfo, Handle);
- hFunc(TEvBlobStorage::TEvControllerGroupReconfigureWipe, Handle);
- hFunc(TEvBlobStorage::TEvControllerNodeReport, Handle);
- hFunc(TEvBlobStorage::TEvControllerConfigRequest, Handle);
- hFunc(TEvBlobStorage::TEvControllerProposeGroupKey, Handle);
- hFunc(TEvPrivate::TEvUpdateSystemViews, Handle);
- cFunc(TEvPrivate::EvUpdateSelfHealCounters, UpdateSelfHealCounters);
- hFunc(TEvPrivate::TEvDropDonor, Handle);
- hFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum, Handle);
- hFunc(TEvBlobStorage::TEvControllerScrubQuantumFinished, Handle);
- hFunc(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress, Handle);
- cFunc(TEvPrivate::EvScrub, ScrubState.HandleTimer);
- cFunc(TEvPrivate::EvVSlotReadyUpdate, VSlotReadyUpdate);
- }
-
- if (const TDuration time = TDuration::Seconds(timer.Passed()); time >= TDuration::MilliSeconds(100)) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSC07, "ProcessControllerEvent event processing took too much time", (Type, type),
- (Duration, time));
- }
- }
-
- STFUNC(StateWork) {
- const ui32 type = ev->GetTypeRewrite();
- THPTimer timer;
-
- switch (type) {
- fFunc(TEvBlobStorage::EvControllerRegisterNode, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerGetGroup, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerSelectGroups, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerUpdateDiskStatus, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerUpdateGroupStat, EnqueueIncomingEvent);
+ hFunc(TEvControllerCommitGroupLatencies, Handle);
+ hFunc(TEvBlobStorage::TEvRequestControllerInfo, Handle);
+ hFunc(TEvBlobStorage::TEvControllerGroupReconfigureWipe, Handle);
+ hFunc(TEvBlobStorage::TEvControllerNodeReport, Handle);
+ hFunc(TEvBlobStorage::TEvControllerConfigRequest, Handle);
+ hFunc(TEvBlobStorage::TEvControllerProposeGroupKey, Handle);
+ hFunc(TEvPrivate::TEvUpdateSystemViews, Handle);
+ cFunc(TEvPrivate::EvUpdateSelfHealCounters, UpdateSelfHealCounters);
+ hFunc(TEvPrivate::TEvDropDonor, Handle);
+ hFunc(TEvBlobStorage::TEvControllerScrubQueryStartQuantum, Handle);
+ hFunc(TEvBlobStorage::TEvControllerScrubQuantumFinished, Handle);
+ hFunc(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress, Handle);
+ cFunc(TEvPrivate::EvScrub, ScrubState.HandleTimer);
+ cFunc(TEvPrivate::EvVSlotReadyUpdate, VSlotReadyUpdate);
+ }
+
+ if (const TDuration time = TDuration::Seconds(timer.Passed()); time >= TDuration::MilliSeconds(100)) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSC07, "ProcessControllerEvent event processing took too much time", (Type, type),
+ (Duration, time));
+ }
+ }
+
+ STFUNC(StateWork) {
+ const ui32 type = ev->GetTypeRewrite();
+ THPTimer timer;
+
+ switch (type) {
+ fFunc(TEvBlobStorage::EvControllerRegisterNode, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerGetGroup, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerSelectGroups, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerUpdateDiskStatus, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerUpdateGroupStat, EnqueueIncomingEvent);
fFunc(TEvBlobStorage::EvControllerUpdateNodeDrives, EnqueueIncomingEvent);
- fFunc(TEvControllerCommitGroupLatencies::EventType, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvRequestControllerInfo, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerGroupReconfigureWipe, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerNodeReport, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerConfigRequest, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerProposeGroupKey, EnqueueIncomingEvent);
- fFunc(NSysView::TEvSysView::EvGetPDisksRequest, ForwardToSystemViewsCollector);
- fFunc(NSysView::TEvSysView::EvGetVSlotsRequest, ForwardToSystemViewsCollector);
- fFunc(NSysView::TEvSysView::EvGetGroupsRequest, ForwardToSystemViewsCollector);
- fFunc(NSysView::TEvSysView::EvGetStoragePoolsRequest, ForwardToSystemViewsCollector);
- fFunc(NSysView::TEvSysView::EvGetStorageStatsRequest, ForwardToSystemViewsCollector);
- fFunc(TEvPrivate::EvUpdateSystemViews, EnqueueIncomingEvent);
- hFunc(TEvInterconnect::TEvNodesInfo, Handle);
- hFunc(TEvents::TEvPoisonPill, Handle);
- hFunc(TEvTabletPipe::TEvServerConnected, Handle);
- hFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
- fFunc(TEvPrivate::EvUpdateSelfHealCounters, EnqueueIncomingEvent);
- cFunc(TEvPrivate::EvHostRecordsTimeToLiveExceeded, HandleHostRecordsTimeToLiveExceeded);
- fFunc(TEvPrivate::EvDropDonor, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerScrubQueryStartQuantum, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerScrubQuantumFinished, EnqueueIncomingEvent);
- fFunc(TEvBlobStorage::EvControllerScrubReportQuantumInProgress, EnqueueIncomingEvent);
- fFunc(TEvPrivate::EvScrub, EnqueueIncomingEvent);
- fFunc(TEvPrivate::EvVSlotReadyUpdate, EnqueueIncomingEvent);
- cFunc(TEvPrivate::EvVSlotNotReadyHistogramUpdate, VSlotNotReadyHistogramUpdate);
- cFunc(TEvPrivate::EvProcessIncomingEvent, ProcessIncomingEvent);
- default:
- if (!HandleDefaultEvents(ev, ctx)) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSC06, "StateWork unexpected event", (Type, type),
- (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
- }
- break;
- }
-
- if (const TDuration time = TDuration::Seconds(timer.Passed()); time >= TDuration::MilliSeconds(100)) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSC07, "StateWork event processing took too much time", (Type, type),
- (Duration, time));
- }
- }
-
- STFUNC(StateBroken) {
- HandleDefaultEvents(ev, ctx);
- }
-
- void LoadFinished() {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC09, "LoadFinished");
- Become(&TThis::StateWork);
-
- while (!InitQueue.empty()) {
- TAutoPtr<IEventHandle> &ev = InitQueue.front();
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC08, "Dequeue", (TabletID, TabletID()), (Type, ev->GetTypeRewrite()),
- (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
- TActivationContext::Send(ev.Release());
- InitQueue.pop_front();
- }
-
- ValidateInternalState();
+ fFunc(TEvControllerCommitGroupLatencies::EventType, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvRequestControllerInfo, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerGroupReconfigureWipe, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerNodeReport, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerConfigRequest, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerProposeGroupKey, EnqueueIncomingEvent);
+ fFunc(NSysView::TEvSysView::EvGetPDisksRequest, ForwardToSystemViewsCollector);
+ fFunc(NSysView::TEvSysView::EvGetVSlotsRequest, ForwardToSystemViewsCollector);
+ fFunc(NSysView::TEvSysView::EvGetGroupsRequest, ForwardToSystemViewsCollector);
+ fFunc(NSysView::TEvSysView::EvGetStoragePoolsRequest, ForwardToSystemViewsCollector);
+ fFunc(NSysView::TEvSysView::EvGetStorageStatsRequest, ForwardToSystemViewsCollector);
+ fFunc(TEvPrivate::EvUpdateSystemViews, EnqueueIncomingEvent);
+ hFunc(TEvInterconnect::TEvNodesInfo, Handle);
+ hFunc(TEvents::TEvPoisonPill, Handle);
+ hFunc(TEvTabletPipe::TEvServerConnected, Handle);
+ hFunc(TEvTabletPipe::TEvServerDisconnected, Handle);
+ fFunc(TEvPrivate::EvUpdateSelfHealCounters, EnqueueIncomingEvent);
+ cFunc(TEvPrivate::EvHostRecordsTimeToLiveExceeded, HandleHostRecordsTimeToLiveExceeded);
+ fFunc(TEvPrivate::EvDropDonor, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerScrubQueryStartQuantum, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerScrubQuantumFinished, EnqueueIncomingEvent);
+ fFunc(TEvBlobStorage::EvControllerScrubReportQuantumInProgress, EnqueueIncomingEvent);
+ fFunc(TEvPrivate::EvScrub, EnqueueIncomingEvent);
+ fFunc(TEvPrivate::EvVSlotReadyUpdate, EnqueueIncomingEvent);
+ cFunc(TEvPrivate::EvVSlotNotReadyHistogramUpdate, VSlotNotReadyHistogramUpdate);
+ cFunc(TEvPrivate::EvProcessIncomingEvent, ProcessIncomingEvent);
+ default:
+ if (!HandleDefaultEvents(ev, ctx)) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSC06, "StateWork unexpected event", (Type, type),
+ (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
+ }
+ break;
+ }
+
+ if (const TDuration time = TDuration::Seconds(timer.Passed()); time >= TDuration::MilliSeconds(100)) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSC07, "StateWork event processing took too much time", (Type, type),
+ (Duration, time));
+ }
+ }
+
+ STFUNC(StateBroken) {
+ HandleDefaultEvents(ev, ctx);
+ }
+
+ void LoadFinished() {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC09, "LoadFinished");
+ Become(&TThis::StateWork);
+
+ while (!InitQueue.empty()) {
+ TAutoPtr<IEventHandle> &ev = InitQueue.front();
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC08, "Dequeue", (TabletID, TabletID()), (Type, ev->GetTypeRewrite()),
+ (Event, ev->HasEvent() ? ev->GetBase()->ToString() : "serialized"));
+ TActivationContext::Send(ev.Release());
+ InitQueue.pop_front();
+ }
+
+ ValidateInternalState();
UpdatePDisksCounters();
- IssueInitialGroupContent();
- InitializeSelfHealState();
- UpdateSystemViews();
- UpdateSelfHealCounters();
- SignalTabletActive(TActivationContext::AsActorContext());
- }
-
+ IssueInitialGroupContent();
+ InitializeSelfHealState();
+ UpdateSystemViews();
+ UpdateSelfHealCounters();
+ SignalTabletActive(TActivationContext::AsActorContext());
+ }
+
void UpdatePDisksCounters() {
ui32 numWithoutSlotCount = 0;
ui32 numWithoutSerial = 0;
- for (const auto& [id, pdisk] : PDisks) {
+ for (const auto& [id, pdisk] : PDisks) {
numWithoutSlotCount += !pdisk->HasExpectedSlotCount;
numWithoutSerial += !pdisk->ExpectedSerial;
- }
+ }
auto& counters = TabletCounters->Simple();
counters[NBlobStorageController::COUNTER_PDISKS_WITHOUT_EXPECTED_SLOT_COUNT].Set(numWithoutSlotCount);
counters[NBlobStorageController::COUNTER_PDISKS_WITHOUT_EXPECTED_SERIAL].Set(numWithoutSerial);
@@ -1835,121 +1835,121 @@ public:
ui32 numRemoved = 0;
ui32 numError = 0;
for (const auto& [serial, driveInfo] : DrivesSerials) {
- switch (driveInfo->LifeStage) {
- case NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN:
- ++numNotSeen;
- break;
- case NKikimrBlobStorage::TDriveLifeStage::REMOVED:
- ++numRemoved;
- break;
- case NKikimrBlobStorage::TDriveLifeStage::ERROR:
- ++numError;
- break;
- default:
- break;
+ switch (driveInfo->LifeStage) {
+ case NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN:
+ ++numNotSeen;
+ break;
+ case NKikimrBlobStorage::TDriveLifeStage::REMOVED:
+ ++numRemoved;
+ break;
+ case NKikimrBlobStorage::TDriveLifeStage::ERROR:
+ ++numError;
+ break;
+ default:
+ break;
}
}
counters[NBlobStorageController::COUNTER_DRIVE_SERIAL_NOT_SEEN].Set(numNotSeen);
counters[NBlobStorageController::COUNTER_DRIVE_SERIAL_REMOVED].Set(numRemoved);
counters[NBlobStorageController::COUNTER_DRIVE_SERIAL_ERROR].Set(numError);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // VSLOT READINESS EVALUATION
-
- TVSlotReadyTimestampQ VSlotReadyTimestampQ;
- bool VSlotReadyUpdateScheduled = false;
-
- void VSlotReadyUpdate() {
- std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
-
- Y_VERIFY(VSlotReadyUpdateScheduled);
- VSlotReadyUpdateScheduled = false;
-
- const TInstant now = TActivationContext::Now();
- THashSet<TGroupInfo*> groups;
- for (auto it = VSlotReadyTimestampQ.begin(); it != VSlotReadyTimestampQ.end() && it->first <= now;
- it = VSlotReadyTimestampQ.erase(it)) {
- it->second->IsReady = true;
- it->second->ResetVSlotReadyTimestampIter();
- if (const TGroupInfo *group = it->second->Group) {
- groups.insert(const_cast<TGroupInfo*>(group));
- it->second->LastSeenReady = TInstant::Zero();
- lastSeenReadyQ.emplace_back(it->second->VSlotId, it->second->LastSeenReady);
- NotReadyVSlotIds.erase(it->second->VSlotId);
- }
- ScrubState.UpdateVDiskState(&*it->second);
- }
- for (TGroupInfo *group : groups) {
- group->CalculateGroupStatus();
- }
- ScheduleVSlotReadyUpdate();
- if (!lastSeenReadyQ.empty()) {
- Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
- }
- }
-
- void ScheduleVSlotReadyUpdate() {
- if (!VSlotReadyTimestampQ.empty() && !std::exchange(VSlotReadyUpdateScheduled, true)) {
- Schedule(VSlotReadyTimestampQ.front().first, new TEvPrivate::TEvVSlotReadyUpdate);
- }
- }
-
- void VSlotNotReadyHistogramUpdate() {
- const TInstant now = TActivationContext::Now();
- auto& histo = TabletCounters->Percentile()[NBlobStorageController::COUNTER_NUM_NOT_READY_VDISKS];
- histo.Clear();
- for (const TVSlotId vslotId : NotReadyVSlotIds) {
- if (const TVSlotInfo *slot = FindVSlot(vslotId)) {
- Y_VERIFY(slot->LastSeenReady != TInstant::Zero());
- const TDuration passed = now - slot->LastSeenReady;
- histo.IncrementFor(passed.Seconds());
- } else {
- Y_VERIFY_DEBUG(false);
- }
- }
- Schedule(TDuration::Seconds(15), new TEvPrivate::TEvVSlotNotReadyHistogramUpdate);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // STATIC GROUP OVERSEEING
-
- struct TStaticVSlotInfo {
- const TVDiskID VDiskId;
- const NKikimrBlobStorage::TVDiskKind::EVDiskKind VDiskKind;
-
- std::optional<NKikimrBlobStorage::TVDiskMetrics> VDiskMetrics;
- NKikimrBlobStorage::EVDiskStatus VDiskStatus = NKikimrBlobStorage::EVDiskStatus::ERROR;
-
- TStaticVSlotInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk)
- : VDiskId(VDiskIDFromVDiskID(vdisk.GetVDiskID()))
- , VDiskKind(vdisk.GetVDiskKind())
- {}
- };
-
- std::map<TVSlotId, TStaticVSlotInfo> StaticVSlots;
- std::map<TVDiskID, TVSlotId> StaticVDiskMap;
-
- struct TStaticPDiskInfo {
- const Schema::PDisk::NodeID::Type NodeId;
- const Schema::PDisk::PDiskID::Type PDiskId;
- const TString Path;
- const TPDiskCategory Category;
- const Schema::PDisk::Guid::Type Guid;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // VSLOT READINESS EVALUATION
+
+ TVSlotReadyTimestampQ VSlotReadyTimestampQ;
+ bool VSlotReadyUpdateScheduled = false;
+
+ void VSlotReadyUpdate() {
+ std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
+
+ Y_VERIFY(VSlotReadyUpdateScheduled);
+ VSlotReadyUpdateScheduled = false;
+
+ const TInstant now = TActivationContext::Now();
+ THashSet<TGroupInfo*> groups;
+ for (auto it = VSlotReadyTimestampQ.begin(); it != VSlotReadyTimestampQ.end() && it->first <= now;
+ it = VSlotReadyTimestampQ.erase(it)) {
+ it->second->IsReady = true;
+ it->second->ResetVSlotReadyTimestampIter();
+ if (const TGroupInfo *group = it->second->Group) {
+ groups.insert(const_cast<TGroupInfo*>(group));
+ it->second->LastSeenReady = TInstant::Zero();
+ lastSeenReadyQ.emplace_back(it->second->VSlotId, it->second->LastSeenReady);
+ NotReadyVSlotIds.erase(it->second->VSlotId);
+ }
+ ScrubState.UpdateVDiskState(&*it->second);
+ }
+ for (TGroupInfo *group : groups) {
+ group->CalculateGroupStatus();
+ }
+ ScheduleVSlotReadyUpdate();
+ if (!lastSeenReadyQ.empty()) {
+ Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
+ }
+ }
+
+ void ScheduleVSlotReadyUpdate() {
+ if (!VSlotReadyTimestampQ.empty() && !std::exchange(VSlotReadyUpdateScheduled, true)) {
+ Schedule(VSlotReadyTimestampQ.front().first, new TEvPrivate::TEvVSlotReadyUpdate);
+ }
+ }
+
+ void VSlotNotReadyHistogramUpdate() {
+ const TInstant now = TActivationContext::Now();
+ auto& histo = TabletCounters->Percentile()[NBlobStorageController::COUNTER_NUM_NOT_READY_VDISKS];
+ histo.Clear();
+ for (const TVSlotId vslotId : NotReadyVSlotIds) {
+ if (const TVSlotInfo *slot = FindVSlot(vslotId)) {
+ Y_VERIFY(slot->LastSeenReady != TInstant::Zero());
+ const TDuration passed = now - slot->LastSeenReady;
+ histo.IncrementFor(passed.Seconds());
+ } else {
+ Y_VERIFY_DEBUG(false);
+ }
+ }
+ Schedule(TDuration::Seconds(15), new TEvPrivate::TEvVSlotNotReadyHistogramUpdate);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STATIC GROUP OVERSEEING
+
+ struct TStaticVSlotInfo {
+ const TVDiskID VDiskId;
+ const NKikimrBlobStorage::TVDiskKind::EVDiskKind VDiskKind;
+
+ std::optional<NKikimrBlobStorage::TVDiskMetrics> VDiskMetrics;
+ NKikimrBlobStorage::EVDiskStatus VDiskStatus = NKikimrBlobStorage::EVDiskStatus::ERROR;
+
+ TStaticVSlotInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk)
+ : VDiskId(VDiskIDFromVDiskID(vdisk.GetVDiskID()))
+ , VDiskKind(vdisk.GetVDiskKind())
+ {}
+ };
+
+ std::map<TVSlotId, TStaticVSlotInfo> StaticVSlots;
+ std::map<TVDiskID, TVSlotId> StaticVDiskMap;
+
+ struct TStaticPDiskInfo {
+ const Schema::PDisk::NodeID::Type NodeId;
+ const Schema::PDisk::PDiskID::Type PDiskId;
+ const TString Path;
+ const TPDiskCategory Category;
+ const Schema::PDisk::Guid::Type Guid;
Schema::PDisk::PDiskConfig::Type PDiskConfig;
ui32 ExpectedSlotCount = 0;
-
- // runtime info
- ui32 StaticSlotUsage = 0;
- std::optional<NKikimrBlobStorage::TPDiskMetrics> PDiskMetrics;
-
- TStaticPDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk)
- : NodeId(pdisk.GetNodeID())
- , PDiskId(pdisk.GetPDiskID())
- , Path(pdisk.GetPath())
- , Category(pdisk.GetPDiskCategory())
- , Guid(pdisk.GetPDiskGuid())
+
+ // runtime info
+ ui32 StaticSlotUsage = 0;
+ std::optional<NKikimrBlobStorage::TPDiskMetrics> PDiskMetrics;
+
+ TStaticPDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk)
+ : NodeId(pdisk.GetNodeID())
+ , PDiskId(pdisk.GetPDiskID())
+ , Path(pdisk.GetPath())
+ , Category(pdisk.GetPDiskCategory())
+ , Guid(pdisk.GetPDiskGuid())
{
if (pdisk.HasPDiskConfig()) {
const auto& cfg = pdisk.GetPDiskConfig();
@@ -1958,40 +1958,40 @@ public:
ExpectedSlotCount = cfg.GetExpectedSlotCount();
}
}
- };
-
- std::map<TPDiskId, TStaticPDiskInfo> StaticPDisks;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // NODE WARDEN PIPE LIFETIME MANAGEMENT
-
+ };
+
+ std::map<TPDiskId, TStaticPDiskInfo> StaticPDisks;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // NODE WARDEN PIPE LIFETIME MANAGEMENT
+
THashMap<TActorId, std::optional<TNodeId>> PipeServerToNode;
-
- void Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev);
- void Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev);
- void OnRegisterNode(const TActorId& serverId, TNodeId nodeId);
- void OnWardenConnected(TNodeId nodeId);
- void OnWardenDisconnected(TNodeId nodeId);
+
+ void Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev);
+ void Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev);
+ void OnRegisterNode(const TActorId& serverId, TNodeId nodeId);
+ void OnWardenConnected(TNodeId nodeId);
+ void OnWardenDisconnected(TNodeId nodeId);
void EraseKnownDrivesOnDisconnected(TNodeInfo *nodeInfo);
-
- using TVSlotFinder = std::function<void(const TVSlotId&, const std::function<void(const TVSlotInfo&)>&)>;
-
- static void Serialize(NKikimrBlobStorage::TDefineHostConfig *pb, const THostConfigId &id, const THostConfigInfo &hostConfig);
- static void Serialize(NKikimrBlobStorage::TDefineBox *pb, const TBoxId &id, const TBoxInfo &box);
- static void Serialize(NKikimrBlobStorage::TDefineStoragePool *pb, const TBoxStoragePoolId &id, const TStoragePoolInfo &pool);
- static void Serialize(NKikimrBlobStorage::TPDiskFilter *pb, const TStoragePoolInfo::TPDiskFilter &filter);
- static void Serialize(NKikimrBlobStorage::TBaseConfig::TPDisk *pb, const TPDiskId &id, const TPDiskInfo &pdisk);
- static void Serialize(NKikimrBlobStorage::TVSlotId *pb, TVSlotId id);
- static void Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotInfo& vslot);
- static void Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotId& vslotId);
- static void Serialize(NKikimrBlobStorage::TBaseConfig::TVSlot *pb, const TVSlotInfo &vslot, const TVSlotFinder& finder);
- static void Serialize(NKikimrBlobStorage::TBaseConfig::TGroup *pb, const TGroupInfo &group);
- static void SerializeDonors(NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vdisk, const TVSlotInfo& vslot,
- const TGroupInfo& group);
- static void SerializeGroupInfo(NKikimrBlobStorage::TGroupInfo *group, const TGroupInfo& groupInfo,
- const TString& storagePoolName, const TMaybe<TKikimrScopeId>& scopeId);
-};
-
-} //NBsController
-} // NKikimr
-
+
+ using TVSlotFinder = std::function<void(const TVSlotId&, const std::function<void(const TVSlotInfo&)>&)>;
+
+ static void Serialize(NKikimrBlobStorage::TDefineHostConfig *pb, const THostConfigId &id, const THostConfigInfo &hostConfig);
+ static void Serialize(NKikimrBlobStorage::TDefineBox *pb, const TBoxId &id, const TBoxInfo &box);
+ static void Serialize(NKikimrBlobStorage::TDefineStoragePool *pb, const TBoxStoragePoolId &id, const TStoragePoolInfo &pool);
+ static void Serialize(NKikimrBlobStorage::TPDiskFilter *pb, const TStoragePoolInfo::TPDiskFilter &filter);
+ static void Serialize(NKikimrBlobStorage::TBaseConfig::TPDisk *pb, const TPDiskId &id, const TPDiskInfo &pdisk);
+ static void Serialize(NKikimrBlobStorage::TVSlotId *pb, TVSlotId id);
+ static void Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotInfo& vslot);
+ static void Serialize(NKikimrBlobStorage::TVDiskLocation *pb, const TVSlotId& vslotId);
+ static void Serialize(NKikimrBlobStorage::TBaseConfig::TVSlot *pb, const TVSlotInfo &vslot, const TVSlotFinder& finder);
+ static void Serialize(NKikimrBlobStorage::TBaseConfig::TGroup *pb, const TGroupInfo &group);
+ static void SerializeDonors(NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vdisk, const TVSlotInfo& vslot,
+ const TGroupInfo& group);
+ static void SerializeGroupInfo(NKikimrBlobStorage::TGroupInfo *group, const TGroupInfo& groupInfo,
+ const TString& storagePoolName, const TMaybe<TKikimrScopeId>& scopeId);
+};
+
+} //NBsController
+} // NKikimr
+
diff --git a/ydb/core/mind/bscontroller/indir.h b/ydb/core/mind/bscontroller/indir.h
index 329f82b123e..ed2df12c437 100644
--- a/ydb/core/mind/bscontroller/indir.h
+++ b/ydb/core/mind/bscontroller/indir.h
@@ -1,74 +1,74 @@
-#pragma once
-
-#include "defs.h"
-
-template<typename TValue>
-class TIndirectReferable {
- friend class TPtr;
- TValue *Current;
-
-public:
- class TPtr {
- const TValue *Object = nullptr;
-
- public:
- TPtr() = default;
-
- TPtr(const TValue *object)
- : Object(object)
- {}
-
- operator const TValue*() const {
- return Get();
- }
-
- const TValue *operator ->() const {
- return *this;
- }
-
- const TValue& operator *() const {
- const TValue *ptr = Get();
- Y_VERIFY_DEBUG(ptr);
- return *ptr;
- }
-
- // MUST be called from OnCommit() only
- TValue& Mutable() const {
- TValue *ptr = Get();
- Y_VERIFY_DEBUG(ptr);
- return *ptr;
- }
-
- private:
- TValue *Get() const {
- return Object ? Object->Current : nullptr;
- }
- };
-
-public:
- TIndirectReferable()
- : Current(static_cast<TValue*>(this))
- {}
-
- TIndirectReferable(const TIndirectReferable&)
- : TIndirectReferable() // prevent from copying link -- set it up for outselves
- {}
-
- TIndirectReferable& operator =(const TIndirectReferable&) = delete;
- TIndirectReferable& operator =(TIndirectReferable&&) = delete;
-
- // TOverlayMap machinery
- void OnClone(const THolder<TValue>& clone) {
- Y_VERIFY_DEBUG(Current == this);
- Current = clone.Get();
- }
-
- std::pair<void**, void*> Preserve() {
- Y_VERIFY_DEBUG(Current != this);
- return std::make_pair((void**)&Current, (void*)std::exchange(Current, static_cast<TValue*>(this)));
- }
-
- void OnRollback() {
- Current = static_cast<TValue*>(this);
- }
-};
+#pragma once
+
+#include "defs.h"
+
+template<typename TValue>
+class TIndirectReferable {
+ friend class TPtr;
+ TValue *Current;
+
+public:
+ class TPtr {
+ const TValue *Object = nullptr;
+
+ public:
+ TPtr() = default;
+
+ TPtr(const TValue *object)
+ : Object(object)
+ {}
+
+ operator const TValue*() const {
+ return Get();
+ }
+
+ const TValue *operator ->() const {
+ return *this;
+ }
+
+ const TValue& operator *() const {
+ const TValue *ptr = Get();
+ Y_VERIFY_DEBUG(ptr);
+ return *ptr;
+ }
+
+ // MUST be called from OnCommit() only
+ TValue& Mutable() const {
+ TValue *ptr = Get();
+ Y_VERIFY_DEBUG(ptr);
+ return *ptr;
+ }
+
+ private:
+ TValue *Get() const {
+ return Object ? Object->Current : nullptr;
+ }
+ };
+
+public:
+ TIndirectReferable()
+ : Current(static_cast<TValue*>(this))
+ {}
+
+ TIndirectReferable(const TIndirectReferable&)
+ : TIndirectReferable() // prevent from copying link -- set it up for outselves
+ {}
+
+ TIndirectReferable& operator =(const TIndirectReferable&) = delete;
+ TIndirectReferable& operator =(TIndirectReferable&&) = delete;
+
+ // TOverlayMap machinery
+ void OnClone(const THolder<TValue>& clone) {
+ Y_VERIFY_DEBUG(Current == this);
+ Current = clone.Get();
+ }
+
+ std::pair<void**, void*> Preserve() {
+ Y_VERIFY_DEBUG(Current != this);
+ return std::make_pair((void**)&Current, (void*)std::exchange(Current, static_cast<TValue*>(this)));
+ }
+
+ void OnRollback() {
+ Current = static_cast<TValue*>(this);
+ }
+};
diff --git a/ydb/core/mind/bscontroller/init_scheme.cpp b/ydb/core/mind/bscontroller/init_scheme.cpp
index 0a7779a131d..91de3698c2d 100644
--- a/ydb/core/mind/bscontroller/init_scheme.cpp
+++ b/ydb/core/mind/bscontroller/init_scheme.cpp
@@ -1,55 +1,55 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxInitScheme : public TTransactionBase<TBlobStorageController> {
- bool Failed = false;
-
-public:
- TTxInitScheme(TBlobStorageController *controller)
- : TBase(controller)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_INIT_SCHEME; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXIS01, "TTxInitScheme Execute");
-
- // check if we have State table and a row with valid SchemaVersion, ensure that this version does not exceed this one
- if (txc.DB.GetScheme().GetTableInfo(Schema::State::TableId)) {
- NIceDb::TNiceDb db(txc.DB);
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxInitScheme : public TTransactionBase<TBlobStorageController> {
+ bool Failed = false;
+
+public:
+ TTxInitScheme(TBlobStorageController *controller)
+ : TBase(controller)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_INIT_SCHEME; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXIS01, "TTxInitScheme Execute");
+
+ // check if we have State table and a row with valid SchemaVersion, ensure that this version does not exceed this one
+ if (txc.DB.GetScheme().GetTableInfo(Schema::State::TableId)) {
+ NIceDb::TNiceDb db(txc.DB);
auto state = db.Table<Schema::State>().Select<Schema::State::SchemaVersion>();
- if (!state.IsReady()) {
- return false;
- } else if (state.IsValid()) {
- const ui32 version = state.GetValue<Schema::State::SchemaVersion>();
- if (version > Schema::CurrentSchemaVersion) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXIS02, "Stored scheme version is newer than supported",
- (SchemeVersion, version), (SupportedVersion, ui32(Schema::CurrentSchemaVersion)));
- Failed = true;
- return true;
- }
- }
- }
-
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
- return true;
- }
-
- void Complete(const TActorContext&) override {
- if (Failed) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, Self->SelfId(), {}, {}, 0));
- } else {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXIS03, "TTxInitScheme Complete");
- Self->Execute(Self->CreateTxMigrate());
- }
- }
-};
-
+ if (!state.IsReady()) {
+ return false;
+ } else if (state.IsValid()) {
+ const ui32 version = state.GetValue<Schema::State::SchemaVersion>();
+ if (version > Schema::CurrentSchemaVersion) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXIS02, "Stored scheme version is newer than supported",
+ (SchemeVersion, version), (SupportedVersion, ui32(Schema::CurrentSchemaVersion)));
+ Failed = true;
+ return true;
+ }
+ }
+ }
+
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ if (Failed) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, Self->SelfId(), {}, {}, 0));
+ } else {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXIS03, "TTxInitScheme Complete");
+ Self->Execute(Self->CreateTxMigrate());
+ }
+ }
+};
+
ITransaction* TBlobStorageController::CreateTxInitScheme() {
- return new TTxInitScheme(this);
-}
-
-} // NBlobStorageController
-} // NKikimr
+ return new TTxInitScheme(this);
+}
+
+} // NBlobStorageController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/load_everything.cpp b/ydb/core/mind/bscontroller/load_everything.cpp
index 8fa32c53f75..c8585ebeea0 100644
--- a/ydb/core/mind/bscontroller/load_everything.cpp
+++ b/ydb/core/mind/bscontroller/load_everything.cpp
@@ -1,186 +1,186 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxLoadEverything : public TTransactionBase<TBlobStorageController> {
-public:
- TTxLoadEverything(TBlobStorageController *controller)
- : TBase(controller)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_LOAD_EVERYTHING; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE01, "TTxLoadEverything Execute");
-
- NIceDb::TNiceDb db(txc.DB);
-
- {
- // precharge
- auto state = db.Table<Schema::State>().Range().Select();
- auto nodes = db.Table<Schema::Node>().Range().Select();
- auto disk = db.Table<Schema::PDisk>().Range().Select();
- auto slot = db.Table<Schema::VSlot>().Range().Select();
- auto group = db.Table<Schema::Group>().Range().Select();
- auto pdiskMetrics = db.Table<Schema::PDiskMetrics>().Range().Select();
- auto vdiskMetrics = db.Table<Schema::VDiskMetrics>().Range().Select();
- auto hostConfig = db.Table<Schema::HostConfig>().Range().Select();
- auto hostConfigDrive = db.Table<Schema::HostConfigDrive>().Range().Select();
- auto box = db.Table<Schema::Box>().Range().Select();
- auto boxUser = db.Table<Schema::BoxUser>().Range().Select();
- auto boxHost = db.Table<Schema::BoxHostV2>().Range().Select();
- auto boxStoragePool = db.Table<Schema::BoxStoragePool>().Range().Select();
- auto boxStoragePoolUser = db.Table<Schema::BoxStoragePoolUser>().Range().Select();
- auto boxStoragePoolPDiskFilter = db.Table<Schema::BoxStoragePoolPDiskFilter>().Range().Select();
- auto groupStoragePool = db.Table<Schema::GroupStoragePool>().Range().Select();
- auto groupLatencies = db.Table<Schema::GroupLatencies>().Select();
- auto scrubState = db.Table<Schema::ScrubState>().Select();
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxLoadEverything : public TTransactionBase<TBlobStorageController> {
+public:
+ TTxLoadEverything(TBlobStorageController *controller)
+ : TBase(controller)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_LOAD_EVERYTHING; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE01, "TTxLoadEverything Execute");
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ {
+ // precharge
+ auto state = db.Table<Schema::State>().Range().Select();
+ auto nodes = db.Table<Schema::Node>().Range().Select();
+ auto disk = db.Table<Schema::PDisk>().Range().Select();
+ auto slot = db.Table<Schema::VSlot>().Range().Select();
+ auto group = db.Table<Schema::Group>().Range().Select();
+ auto pdiskMetrics = db.Table<Schema::PDiskMetrics>().Range().Select();
+ auto vdiskMetrics = db.Table<Schema::VDiskMetrics>().Range().Select();
+ auto hostConfig = db.Table<Schema::HostConfig>().Range().Select();
+ auto hostConfigDrive = db.Table<Schema::HostConfigDrive>().Range().Select();
+ auto box = db.Table<Schema::Box>().Range().Select();
+ auto boxUser = db.Table<Schema::BoxUser>().Range().Select();
+ auto boxHost = db.Table<Schema::BoxHostV2>().Range().Select();
+ auto boxStoragePool = db.Table<Schema::BoxStoragePool>().Range().Select();
+ auto boxStoragePoolUser = db.Table<Schema::BoxStoragePoolUser>().Range().Select();
+ auto boxStoragePoolPDiskFilter = db.Table<Schema::BoxStoragePoolPDiskFilter>().Range().Select();
+ auto groupStoragePool = db.Table<Schema::GroupStoragePool>().Range().Select();
+ auto groupLatencies = db.Table<Schema::GroupLatencies>().Select();
+ auto scrubState = db.Table<Schema::ScrubState>().Select();
auto pdiskSerial = db.Table<Schema::DriveSerial>().Select();
- if (!state.IsReady()
- || !nodes.IsReady()
- || !disk.IsReady()
- || !slot.IsReady()
- || !group.IsReady()
- || !pdiskMetrics.IsReady()
- || !vdiskMetrics.IsReady()
- || !hostConfig.IsReady()
- || !hostConfigDrive.IsReady()
- || !box.IsReady()
- || !boxUser.IsReady()
- || !boxHost.IsReady()
- || !boxStoragePool.IsReady()
- || !boxStoragePoolUser.IsReady()
- || !boxStoragePoolPDiskFilter.IsReady()
- || !groupStoragePool.IsReady()
- || !groupLatencies.IsReady()
+ if (!state.IsReady()
+ || !nodes.IsReady()
+ || !disk.IsReady()
+ || !slot.IsReady()
+ || !group.IsReady()
+ || !pdiskMetrics.IsReady()
+ || !vdiskMetrics.IsReady()
+ || !hostConfig.IsReady()
+ || !hostConfigDrive.IsReady()
+ || !box.IsReady()
+ || !boxUser.IsReady()
+ || !boxHost.IsReady()
+ || !boxStoragePool.IsReady()
+ || !boxStoragePoolUser.IsReady()
+ || !boxStoragePoolPDiskFilter.IsReady()
+ || !groupStoragePool.IsReady()
+ || !groupLatencies.IsReady()
|| !scrubState.IsReady()
|| !pdiskSerial.IsReady()) {
- return false;
- }
- }
-
- // State
- {
- using T = Schema::State;
- auto state = db.Table<T>().Select();
- if (!state.IsReady())
- return false;
+ return false;
+ }
+ }
+
+ // State
+ {
+ using T = Schema::State;
+ auto state = db.Table<T>().Select();
+ if (!state.IsReady())
+ return false;
if (state.IsValid()) {
- Self->NextGroupID = state.GetValue<T::NextGroupID>();
- Self->NextStoragePoolId = state.GetValue<T::NextStoragePoolId>();
- Self->NextOperationLogIndex = state.GetValueOrDefault<T::NextOperationLogIndex>(1);
- Self->DefaultMaxSlots = state.GetValue<T::DefaultMaxSlots>();
- if (state.HaveValue<T::InstanceId>()) {
- Self->InstanceId = state.GetValue<T::InstanceId>();
- }
- Self->SelfHealEnable = state.GetValue<T::SelfHealEnable>();
- Self->DonorMode = state.GetValue<T::DonorModeEnable>();
- Self->ScrubPeriodicity = TDuration::Seconds(state.GetValue<T::ScrubPeriodicity>());
+ Self->NextGroupID = state.GetValue<T::NextGroupID>();
+ Self->NextStoragePoolId = state.GetValue<T::NextStoragePoolId>();
+ Self->NextOperationLogIndex = state.GetValueOrDefault<T::NextOperationLogIndex>(1);
+ Self->DefaultMaxSlots = state.GetValue<T::DefaultMaxSlots>();
+ if (state.HaveValue<T::InstanceId>()) {
+ Self->InstanceId = state.GetValue<T::InstanceId>();
+ }
+ Self->SelfHealEnable = state.GetValue<T::SelfHealEnable>();
+ Self->DonorMode = state.GetValue<T::DonorModeEnable>();
+ Self->ScrubPeriodicity = TDuration::Seconds(state.GetValue<T::ScrubPeriodicity>());
Self->SerialManagementStage = state.GetValue<T::SerialManagementStage>();
- Self->PDiskSpaceMarginPromille = state.GetValue<T::PDiskSpaceMarginPromille>();
- Self->GroupReserveMin = state.GetValue<T::GroupReserveMin>();
- Self->GroupReservePart = state.GetValue<T::GroupReservePart>();
- Self->MaxScrubbedDisksAtOnce = state.GetValue<T::MaxScrubbedDisksAtOnce>();
+ Self->PDiskSpaceMarginPromille = state.GetValue<T::PDiskSpaceMarginPromille>();
+ Self->GroupReserveMin = state.GetValue<T::GroupReserveMin>();
+ Self->GroupReservePart = state.GetValue<T::GroupReservePart>();
+ Self->MaxScrubbedDisksAtOnce = state.GetValue<T::MaxScrubbedDisksAtOnce>();
Self->PDiskSpaceColorBorder = state.GetValue<T::PDiskSpaceColorBorder>();
- Self->SysViewChangedSettings = true;
- }
- }
-
- // Node
- Self->Nodes.clear();
- {
- auto nodes = db.Table<Schema::Node>().Range().Select();
- if (!nodes.IsReady())
- return false;
- while (!nodes.EndOfSet()) {
- Self->AddNode(nodes.GetKey(),
- {nodes.GetValue<Schema::Node::NextPDiskID>()});
- if (!nodes.Next())
- return false;
- }
- }
-
- // GroupStoragePool
- std::unordered_map<TGroupId, TBoxStoragePoolId> groupToStoragePool;
- {
- using Table = Schema::GroupStoragePool;
- auto groupStoragePool = db.Table<Table>().Range().Select();
- if (!groupStoragePool.IsReady()) {
- return false;
- }
- while (groupStoragePool.IsValid()) {
- const auto groupId = groupStoragePool.GetValue<Table::GroupId>();
- const auto boxId = groupStoragePool.GetValue<Table::BoxId>();
- const auto storagePoolId = groupStoragePool.GetValue<Table::StoragePoolId>();
- const bool inserted = groupToStoragePool.try_emplace(groupId, boxId, storagePoolId).second;
- Y_VERIFY(inserted);
- Self->StoragePoolGroups.emplace(TBoxStoragePoolId(boxId, storagePoolId), groupId);
- if (!groupStoragePool.Next()) {
- return false;
- }
- }
- }
-
- // parse group geometry -- it is not known prior to VSlot processing, but we need it to construct correct groups
- std::unordered_map<TGroupId, std::tuple<ui32, ui32, ui32>> geometry;
- {
- using Table = Schema::VSlot;
- auto vslot = db.Table<Table>().Select();
- if (!vslot.IsReady()) {
- return false;
- }
- while (vslot.IsValid()) {
- const auto groupId = vslot.GetValue<Table::GroupID>();
- auto& record = geometry[groupId];
-
- {
- auto& numFailRealms = std::get<0>(record);
- const auto failRealmIdx = vslot.GetValue<Table::RingIdx>();
- numFailRealms = Max(numFailRealms, failRealmIdx + 1);
- }
-
- {
- auto& numFailDomainsPerFailRealm = std::get<1>(record);
- const auto failDomainIdx = vslot.GetValue<Table::FailDomainIdx>();
- numFailDomainsPerFailRealm = Max(numFailDomainsPerFailRealm, failDomainIdx + 1);
- }
-
- {
- auto& numVDisksPerFailDomain = std::get<2>(record);
- const auto vdiskIdx = vslot.GetValue<Table::VDiskIdx>();
- numVDisksPerFailDomain = Max(numVDisksPerFailDomain, vdiskIdx + 1);
- }
-
- if (!vslot.Next()) {
- return false;
- }
+ Self->SysViewChangedSettings = true;
}
- }
-
- // Group
- Self->GroupMap.clear();
- Self->GroupLookup.clear();
- Self->OwnerIdIdxToGroup.clear();
- Self->IndexGroupSpeciesToGroup.clear();
- {
- auto groups = db.Table<Schema::Group>().Range().Select();
- if (!groups.IsReady())
- return false;
- while (!groups.EndOfSet()) {
- const auto it = groupToStoragePool.find(groups.GetKey());
- Y_VERIFY(it != groupToStoragePool.end());
- const TBoxStoragePoolId storagePoolId = it->second;
- groupToStoragePool.erase(it);
-
- const auto geomIt = geometry.find(groups.GetKey());
- Y_VERIFY(geomIt != geometry.end());
-
- TGroupInfo& group = Self->AddGroup(groups.GetKey(),
- groups.GetValue<Schema::Group::Generation>(),
- groups.GetValue<Schema::Group::Owner>(),
- groups.GetValue<Schema::Group::ErasureSpecies>(),
- groups.GetValue<Schema::Group::DesiredPDiskCategory>(),
+ }
+
+ // Node
+ Self->Nodes.clear();
+ {
+ auto nodes = db.Table<Schema::Node>().Range().Select();
+ if (!nodes.IsReady())
+ return false;
+ while (!nodes.EndOfSet()) {
+ Self->AddNode(nodes.GetKey(),
+ {nodes.GetValue<Schema::Node::NextPDiskID>()});
+ if (!nodes.Next())
+ return false;
+ }
+ }
+
+ // GroupStoragePool
+ std::unordered_map<TGroupId, TBoxStoragePoolId> groupToStoragePool;
+ {
+ using Table = Schema::GroupStoragePool;
+ auto groupStoragePool = db.Table<Table>().Range().Select();
+ if (!groupStoragePool.IsReady()) {
+ return false;
+ }
+ while (groupStoragePool.IsValid()) {
+ const auto groupId = groupStoragePool.GetValue<Table::GroupId>();
+ const auto boxId = groupStoragePool.GetValue<Table::BoxId>();
+ const auto storagePoolId = groupStoragePool.GetValue<Table::StoragePoolId>();
+ const bool inserted = groupToStoragePool.try_emplace(groupId, boxId, storagePoolId).second;
+ Y_VERIFY(inserted);
+ Self->StoragePoolGroups.emplace(TBoxStoragePoolId(boxId, storagePoolId), groupId);
+ if (!groupStoragePool.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // parse group geometry -- it is not known prior to VSlot processing, but we need it to construct correct groups
+ std::unordered_map<TGroupId, std::tuple<ui32, ui32, ui32>> geometry;
+ {
+ using Table = Schema::VSlot;
+ auto vslot = db.Table<Table>().Select();
+ if (!vslot.IsReady()) {
+ return false;
+ }
+ while (vslot.IsValid()) {
+ const auto groupId = vslot.GetValue<Table::GroupID>();
+ auto& record = geometry[groupId];
+
+ {
+ auto& numFailRealms = std::get<0>(record);
+ const auto failRealmIdx = vslot.GetValue<Table::RingIdx>();
+ numFailRealms = Max(numFailRealms, failRealmIdx + 1);
+ }
+
+ {
+ auto& numFailDomainsPerFailRealm = std::get<1>(record);
+ const auto failDomainIdx = vslot.GetValue<Table::FailDomainIdx>();
+ numFailDomainsPerFailRealm = Max(numFailDomainsPerFailRealm, failDomainIdx + 1);
+ }
+
+ {
+ auto& numVDisksPerFailDomain = std::get<2>(record);
+ const auto vdiskIdx = vslot.GetValue<Table::VDiskIdx>();
+ numVDisksPerFailDomain = Max(numVDisksPerFailDomain, vdiskIdx + 1);
+ }
+
+ if (!vslot.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // Group
+ Self->GroupMap.clear();
+ Self->GroupLookup.clear();
+ Self->OwnerIdIdxToGroup.clear();
+ Self->IndexGroupSpeciesToGroup.clear();
+ {
+ auto groups = db.Table<Schema::Group>().Range().Select();
+ if (!groups.IsReady())
+ return false;
+ while (!groups.EndOfSet()) {
+ const auto it = groupToStoragePool.find(groups.GetKey());
+ Y_VERIFY(it != groupToStoragePool.end());
+ const TBoxStoragePoolId storagePoolId = it->second;
+ groupToStoragePool.erase(it);
+
+ const auto geomIt = geometry.find(groups.GetKey());
+ Y_VERIFY(geomIt != geometry.end());
+
+ TGroupInfo& group = Self->AddGroup(groups.GetKey(),
+ groups.GetValue<Schema::Group::Generation>(),
+ groups.GetValue<Schema::Group::Owner>(),
+ groups.GetValue<Schema::Group::ErasureSpecies>(),
+ groups.GetValue<Schema::Group::DesiredPDiskCategory>(),
groups.GetValueOrDefault<Schema::Group::DesiredVDiskCategory>(NKikimrBlobStorage::TVDiskKind::Default),
groups.GetValueOrDefault<Schema::Group::EncryptionMode>(),
groups.GetValueOrDefault<Schema::Group::LifeCyclePhase>(),
@@ -188,305 +188,305 @@ public:
groups.GetValueOrDefault<Schema::Group::EncryptedGroupKey>(nullptr),
groups.GetValueOrDefault<Schema::Group::GroupKeyNonce>(),
groups.GetValueOrDefault<Schema::Group::MainKeyVersion>(),
- groups.GetValueOrDefault<Schema::Group::Down>(),
- groups.GetValueOrDefault<Schema::Group::SeenOperational>(),
- storagePoolId,
- std::get<0>(geomIt->second),
- std::get<1>(geomIt->second),
- std::get<2>(geomIt->second));
- Self->OwnerIdIdxToGroup.emplace(groups.GetValue<Schema::Group::Owner>(), groups.GetKey());
- Self->IndexGroupSpeciesToGroup[group.GetGroupSpecies()].push_back(group.ID);
- if (!groups.Next())
- return false;
- }
- }
- Y_VERIFY(groupToStoragePool.empty());
-
- // HostConfig, Box, BoxStoragePool
- if (!NTableAdapter::FetchTable<Schema::HostConfig>(db, Self, Self->HostConfigs)
- || !NTableAdapter::FetchTable<Schema::Box>(db, Self, Self->Boxes)
+ groups.GetValueOrDefault<Schema::Group::Down>(),
+ groups.GetValueOrDefault<Schema::Group::SeenOperational>(),
+ storagePoolId,
+ std::get<0>(geomIt->second),
+ std::get<1>(geomIt->second),
+ std::get<2>(geomIt->second));
+ Self->OwnerIdIdxToGroup.emplace(groups.GetValue<Schema::Group::Owner>(), groups.GetKey());
+ Self->IndexGroupSpeciesToGroup[group.GetGroupSpecies()].push_back(group.ID);
+ if (!groups.Next())
+ return false;
+ }
+ }
+ Y_VERIFY(groupToStoragePool.empty());
+
+ // HostConfig, Box, BoxStoragePool
+ if (!NTableAdapter::FetchTable<Schema::HostConfig>(db, Self, Self->HostConfigs)
+ || !NTableAdapter::FetchTable<Schema::Box>(db, Self, Self->Boxes)
|| !NTableAdapter::FetchTable<Schema::BoxStoragePool>(db, Self, Self->StoragePools)
|| !NTableAdapter::FetchTable<Schema::DriveSerial>(db, Self, Self->DrivesSerials)) {
- return false;
- }
- for (const auto& [storagePoolId, storagePool] : Self->StoragePools) {
- Self->SysViewChangedStoragePools.insert(storagePoolId);
- }
-
- // create revmap
- std::map<std::tuple<THostId, TString>, TBoxId> driveToBox;
- for (const auto& [boxId, box] : Self->Boxes) {
- for (const auto& [host, value] : box.Hosts) {
- if (const auto it = Self->HostConfigs.find(value.HostConfigId); it != Self->HostConfigs.end()) {
- for (const auto& [drive, info] : it->second.Drives) {
- const bool inserted = driveToBox.emplace(std::make_tuple(host, drive.Path), boxId).second;
- Y_VERIFY(inserted, "duplicate Box-generated drive BoxId# %" PRIu64 " FQDN# %s IcPort# %d Path# '%s'",
- host.BoxId, host.Fqdn.data(), host.IcPort, drive.Path.data());
- }
- } else {
- Y_FAIL("HostConfigId# %" PRIu64 " not found in BoxId# %" PRIu64 " FQDN# %s IcPort# %d",
- value.HostConfigId, host.BoxId, host.Fqdn.data(), host.IcPort);
- }
- }
- }
-
+ return false;
+ }
+ for (const auto& [storagePoolId, storagePool] : Self->StoragePools) {
+ Self->SysViewChangedStoragePools.insert(storagePoolId);
+ }
+
+ // create revmap
+ std::map<std::tuple<THostId, TString>, TBoxId> driveToBox;
+ for (const auto& [boxId, box] : Self->Boxes) {
+ for (const auto& [host, value] : box.Hosts) {
+ if (const auto it = Self->HostConfigs.find(value.HostConfigId); it != Self->HostConfigs.end()) {
+ for (const auto& [drive, info] : it->second.Drives) {
+ const bool inserted = driveToBox.emplace(std::make_tuple(host, drive.Path), boxId).second;
+ Y_VERIFY(inserted, "duplicate Box-generated drive BoxId# %" PRIu64 " FQDN# %s IcPort# %d Path# '%s'",
+ host.BoxId, host.Fqdn.data(), host.IcPort, drive.Path.data());
+ }
+ } else {
+ Y_FAIL("HostConfigId# %" PRIu64 " not found in BoxId# %" PRIu64 " FQDN# %s IcPort# %d",
+ value.HostConfigId, host.BoxId, host.Fqdn.data(), host.IcPort);
+ }
+ }
+ }
+
for (const auto& [serial, info] : Self->DrivesSerials) {
- if (info->NodeId && info->PDiskId) {
- const auto hostId = Self->HostRecords->GetHostId(*info->NodeId);
- const bool inserted = driveToBox.emplace(std::make_tuple(*hostId, serial.Serial), info->BoxId).second;
+ if (info->NodeId && info->PDiskId) {
+ const auto hostId = Self->HostRecords->GetHostId(*info->NodeId);
+ const bool inserted = driveToBox.emplace(std::make_tuple(*hostId, serial.Serial), info->BoxId).second;
Y_VERIFY(inserted, "duplicate Serial-generated drive");
}
}
- // PDisks
- Self->PDisks.clear();
- {
- using T = Schema::PDisk;
- auto disks = db.Table<T>().Range().Select();
- if (!disks.IsReady())
- return false;
- while (!disks.EndOfSet()) {
- auto getOpt = [&](auto col) {
- using TCol = decltype(col);
- TMaybe<typename TCol::Type> res;
- if (disks.HaveValue<TCol>()) {
- res = disks.GetValue<TCol>();
- }
- return res;
- };
-
- THostId hostId;
- TBoxId boxId;
+ // PDisks
+ Self->PDisks.clear();
+ {
+ using T = Schema::PDisk;
+ auto disks = db.Table<T>().Range().Select();
+ if (!disks.IsReady())
+ return false;
+ while (!disks.EndOfSet()) {
+ auto getOpt = [&](auto col) {
+ using TCol = decltype(col);
+ TMaybe<typename TCol::Type> res;
+ if (disks.HaveValue<TCol>()) {
+ res = disks.GetValue<TCol>();
+ }
+ return res;
+ };
+
+ THostId hostId;
+ TBoxId boxId;
TString path = disks.GetValue<T::Path>();
TString pathOrSerial = path ? path : disks.GetValue<T::ExpectedSerial>();
Y_VERIFY_S(pathOrSerial, "For pdiskId# " << disks.GetValue<T::PDiskID>()
<< " not found neither pathOrSerial nor serial");
-
- if (const auto& x = Self->HostRecords->GetHostId(disks.GetValue<T::NodeID>())) {
- hostId = *x;
- } else {
- Y_FAIL("unknown node NodeId# %" PRIu32, disks.GetValue<T::NodeID>());
- }
-
- // find the owning box
+
+ if (const auto& x = Self->HostRecords->GetHostId(disks.GetValue<T::NodeID>())) {
+ hostId = *x;
+ } else {
+ Y_FAIL("unknown node NodeId# %" PRIu32, disks.GetValue<T::NodeID>());
+ }
+
+ // find the owning box
if (const auto it = driveToBox.find(std::make_tuple(hostId, pathOrSerial)); it != driveToBox.end()) {
- boxId = it->second;
- driveToBox.erase(it);
- } else {
- Y_FAIL("PDisk NodeId# %" PRIu32 " PDiskId# %" PRIu32 " not belonging to a box",
- disks.GetValue<T::NodeID>(), disks.GetValue<T::PDiskID>());
- }
-
- const auto it = Self->StaticPDisks.find(disks.GetKey());
- const ui32 staticSlotUsage = it != Self->StaticPDisks.end() ? it->second.StaticSlotUsage : 0;
-
- // construct PDisk item
+ boxId = it->second;
+ driveToBox.erase(it);
+ } else {
+ Y_FAIL("PDisk NodeId# %" PRIu32 " PDiskId# %" PRIu32 " not belonging to a box",
+ disks.GetValue<T::NodeID>(), disks.GetValue<T::PDiskID>());
+ }
+
+ const auto it = Self->StaticPDisks.find(disks.GetKey());
+ const ui32 staticSlotUsage = it != Self->StaticPDisks.end() ? it->second.StaticSlotUsage : 0;
+
+ // construct PDisk item
Self->AddPDisk(disks.GetKey(), hostId, disks.GetValue<T::Path>(), disks.GetValue<T::Category>(),
disks.GetValue<T::Guid>(), getOpt(T::SharedWithOs()), getOpt(T::ReadCentric()),
disks.GetValueOrDefault<T::NextVSlotId>(), disks.GetValue<T::PDiskConfig>(), boxId,
Self->DefaultMaxSlots, disks.GetValue<T::Status>(), disks.GetValue<T::Timestamp>(),
disks.GetValue<T::ExpectedSerial>(), disks.GetValue<T::LastSeenSerial>(),
- disks.GetValue<T::LastSeenPath>(), staticSlotUsage);
-
- if (!disks.Next())
- return false;
- }
- }
- Y_VERIFY(driveToBox.empty(), "missing PDisks defined by the box exist");
-
- // PDiskMetrics
- TVector<Schema::PDiskMetrics::TKey::Type> pdiskMetricsToDelete;
- {
- using Table = Schema::PDiskMetrics;
- auto table = db.Table<Table>().Range().Select();
- if (!table.IsReady()) {
- return false;
- }
- while (!table.EndOfSet()) {
- const TPDiskId pdiskId(table.GetValue<Table::NodeID>(), table.GetValue<Table::PDiskID>());
- if (TPDiskInfo *pdisk = Self->FindPDisk(pdiskId)) {
- pdisk->Metrics = table.GetValueOrDefault<Table::Metrics>();
- } else {
- pdiskMetricsToDelete.push_back(table.GetKey());
- }
- if (!table.Next()) {
- return false;
- }
- }
- }
-
- // VSlots
- Self->VSlots.clear();
- {
- using T = Schema::VSlot;
- auto slot = db.Table<T>().Range().Select();
- if (!slot.IsReady())
- return false;
- while (!slot.EndOfSet()) {
- const TVSlotId& vslotId(slot.GetKey());
- TPDiskInfo *pdisk = Self->FindPDisk(vslotId.ComprisingPDiskId());
- Y_VERIFY(pdisk);
-
- const TGroupId groupId = slot.GetValue<T::GroupID>();
- Y_VERIFY(groupId);
-
- auto& x = Self->AddVSlot(vslotId, pdisk, groupId, slot.GetValueOrDefault<T::GroupPrevGeneration>(),
- slot.GetValue<T::GroupGeneration>(), slot.GetValue<T::Category>(), slot.GetValue<T::RingIdx>(),
- slot.GetValue<T::FailDomainIdx>(), slot.GetValue<T::VDiskIdx>(), slot.GetValueOrDefault<T::Mood>(),
- Self->FindGroup(groupId), &Self->VSlotReadyTimestampQ, slot.GetValue<T::LastSeenReady>());
- if (x.LastSeenReady != TInstant::Zero()) {
- Self->NotReadyVSlotIds.insert(x.VSlotId);
- }
-
- if (!slot.Next()) {
- return false;
- }
- }
- }
- for (const auto& [id, group] : Self->GroupMap) {
- group->FinishVDisksInGroup();
- }
-
- // fixup donors and acceptors
- {
- std::map<TGroupId, std::map<TVDiskIdShort, std::vector<TVSlotInfo*>>> map;
- for (const auto& [vslotId, vslot] : Self->VSlots) {
- if (!vslot->IsBeingDeleted()) {
- map[vslot->GroupId][vslot->GetShortVDiskId()].push_back(vslot.Get());
- }
- }
- for (auto& [groupId, disks] : map) {
- for (auto& [shortVDiskId, array] : disks) {
- auto comp = [](const TVSlotInfo *x, const TVSlotInfo *y) {
- Y_VERIFY(x->GroupGeneration != y->GroupGeneration);
- return x->GroupGeneration < y->GroupGeneration;
- };
- std::sort(array.begin(), array.end(), comp);
- TVSlotInfo *acceptor = array.back();
- for (size_t i = 0; i < array.size() - 1; ++i) {
- Y_VERIFY(array[i]->Mood == TMood::Donor);
- array[i]->AcceptorVSlotId = acceptor->VSlotId;
- acceptor->Donors.emplace_back(array[i]->VSlotId, array[i]->GetVDiskId());
- }
- }
- }
- }
-
- // VDiskMetrics
- TVector<Schema::VDiskMetrics::TKey::Type> vdiskMetricsToDelete;
- {
- using Table = Schema::VDiskMetrics;
- auto table = db.Table<Table>().Range().Select();
- if (!table.IsReady()) {
- return false;
- }
- while (!table.EndOfSet()) {
- const TVDiskID key(table.GetValue<Table::GroupID>(), table.GetValue<Table::GroupGeneration>(),
- table.GetValue<Table::Ring>(), table.GetValue<Table::FailDomain>(), table.GetValue<Table::VDisk>());
- if (TVSlotInfo *slot = Self->FindVSlot(key)) {
- slot->Metrics = table.GetValueOrDefault<Table::Metrics>();
- slot->UpdateVDiskMetrics();
- } else {
- vdiskMetricsToDelete.push_back(table.GetKey());
- }
- if (!table.Next()) {
- return false;
- }
- }
- }
-
- // GroupLatencies
- {
- using Table = Schema::GroupLatencies;
- auto groupLatencies = db.Table<Table>().Select();
- if (!groupLatencies.IsReady()) {
- return false;
- }
- while (groupLatencies.IsValid()) {
- const TGroupId groupId = groupLatencies.GetValue<Table::GroupId>();
- if (TGroupInfo *groupInfo = Self->FindGroup(groupId)) {
- if (groupLatencies.HaveValue<Table::PutTabletLogLatencyUs>()) {
- groupInfo->LatencyStats.PutTabletLog = TDuration::MicroSeconds(groupLatencies.GetValue<Table::PutTabletLogLatencyUs>());
- }
- if (groupLatencies.HaveValue<Table::PutUserDataLatencyUs>()) {
- groupInfo->LatencyStats.PutUserData = TDuration::MicroSeconds(groupLatencies.GetValue<Table::PutUserDataLatencyUs>());
- }
- if (groupLatencies.HaveValue<Table::GetFastLatencyUs>()) {
- groupInfo->LatencyStats.GetFast = TDuration::MicroSeconds(groupLatencies.GetValue<Table::GetFastLatencyUs>());
- }
- } else {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXLE02, "Nonexistent group in GroupLatencies", (GroupId, groupId));
- }
-
- if (!groupLatencies.Next()) {
- return false;
- }
- }
- }
-
- // primitive garbage collection for obsolete metrics
- for (const auto& key : pdiskMetricsToDelete) {
- db.Table<Schema::PDiskMetrics>().Key(key).Delete();
- }
- for (const auto& key : vdiskMetricsToDelete) {
- db.Table<Schema::VDiskMetrics>().Key(key).Delete();
- }
-
- // apply storage pool stats
- std::unordered_map<TBoxStoragePoolId, ui64> allocatedSizeMap;
- for (const auto& [vslotId, slot] : Self->VSlots) {
- if (!slot->IsBeingDeleted()) {
- TGroupInfo *group = Self->FindGroup(slot->GroupId);
- Y_VERIFY(group);
- allocatedSizeMap[group->StoragePoolId] += slot->Metrics.GetAllocatedSize();
- }
- }
- for (const auto& [id, info] : Self->StoragePools) {
- Self->StoragePoolStat->AddStoragePool(TStoragePoolStat::ConvertId(id), info.Name, allocatedSizeMap[id]);
- }
- for (const auto& [groupId, group] : Self->GroupMap) {
- group->StatusFlags = group->GetStorageStatusFlags();
- Self->StoragePoolStat->Update(TStoragePoolStat::ConvertId(group->StoragePoolId), std::nullopt, group->StatusFlags);
- }
-
- // scrub state
- {
- using Table = Schema::ScrubState;
- auto scrubState = db.Table<Table>().Select();
- if (!scrubState.IsReady()) {
- return false;
- }
- while (scrubState.IsValid()) {
- Self->ScrubState.AddItem(
- scrubState.GetKey(),
- scrubState.HaveValue<Table::State>() ? std::make_optional(scrubState.GetValue<Table::State>()) : std::nullopt,
- scrubState.GetValue<Table::ScrubCycleStartTime>(),
- scrubState.GetValue<Table::ScrubCycleFinishTime>(),
- scrubState.GetValue<Table::Success>());
- if (!scrubState.Next()) {
- return false;
- }
- }
- }
-
- // calculate group status for all groups
- for (auto& [id, group] : Self->GroupMap) {
- group->CalculateGroupStatus();
- }
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE03, "TTxLoadEverything Complete");
- Self->LoadFinished();
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE04, "TTxLoadEverything InitQueue processed");
- }
-};
-
-ITransaction* TBlobStorageController::CreateTxLoadEverything() {
- return new TTxLoadEverything(this);
-}
-
-} // NBlobStorageController
-} // NKikimr
+ disks.GetValue<T::LastSeenPath>(), staticSlotUsage);
+
+ if (!disks.Next())
+ return false;
+ }
+ }
+ Y_VERIFY(driveToBox.empty(), "missing PDisks defined by the box exist");
+
+ // PDiskMetrics
+ TVector<Schema::PDiskMetrics::TKey::Type> pdiskMetricsToDelete;
+ {
+ using Table = Schema::PDiskMetrics;
+ auto table = db.Table<Table>().Range().Select();
+ if (!table.IsReady()) {
+ return false;
+ }
+ while (!table.EndOfSet()) {
+ const TPDiskId pdiskId(table.GetValue<Table::NodeID>(), table.GetValue<Table::PDiskID>());
+ if (TPDiskInfo *pdisk = Self->FindPDisk(pdiskId)) {
+ pdisk->Metrics = table.GetValueOrDefault<Table::Metrics>();
+ } else {
+ pdiskMetricsToDelete.push_back(table.GetKey());
+ }
+ if (!table.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // VSlots
+ Self->VSlots.clear();
+ {
+ using T = Schema::VSlot;
+ auto slot = db.Table<T>().Range().Select();
+ if (!slot.IsReady())
+ return false;
+ while (!slot.EndOfSet()) {
+ const TVSlotId& vslotId(slot.GetKey());
+ TPDiskInfo *pdisk = Self->FindPDisk(vslotId.ComprisingPDiskId());
+ Y_VERIFY(pdisk);
+
+ const TGroupId groupId = slot.GetValue<T::GroupID>();
+ Y_VERIFY(groupId);
+
+ auto& x = Self->AddVSlot(vslotId, pdisk, groupId, slot.GetValueOrDefault<T::GroupPrevGeneration>(),
+ slot.GetValue<T::GroupGeneration>(), slot.GetValue<T::Category>(), slot.GetValue<T::RingIdx>(),
+ slot.GetValue<T::FailDomainIdx>(), slot.GetValue<T::VDiskIdx>(), slot.GetValueOrDefault<T::Mood>(),
+ Self->FindGroup(groupId), &Self->VSlotReadyTimestampQ, slot.GetValue<T::LastSeenReady>());
+ if (x.LastSeenReady != TInstant::Zero()) {
+ Self->NotReadyVSlotIds.insert(x.VSlotId);
+ }
+
+ if (!slot.Next()) {
+ return false;
+ }
+ }
+ }
+ for (const auto& [id, group] : Self->GroupMap) {
+ group->FinishVDisksInGroup();
+ }
+
+ // fixup donors and acceptors
+ {
+ std::map<TGroupId, std::map<TVDiskIdShort, std::vector<TVSlotInfo*>>> map;
+ for (const auto& [vslotId, vslot] : Self->VSlots) {
+ if (!vslot->IsBeingDeleted()) {
+ map[vslot->GroupId][vslot->GetShortVDiskId()].push_back(vslot.Get());
+ }
+ }
+ for (auto& [groupId, disks] : map) {
+ for (auto& [shortVDiskId, array] : disks) {
+ auto comp = [](const TVSlotInfo *x, const TVSlotInfo *y) {
+ Y_VERIFY(x->GroupGeneration != y->GroupGeneration);
+ return x->GroupGeneration < y->GroupGeneration;
+ };
+ std::sort(array.begin(), array.end(), comp);
+ TVSlotInfo *acceptor = array.back();
+ for (size_t i = 0; i < array.size() - 1; ++i) {
+ Y_VERIFY(array[i]->Mood == TMood::Donor);
+ array[i]->AcceptorVSlotId = acceptor->VSlotId;
+ acceptor->Donors.emplace_back(array[i]->VSlotId, array[i]->GetVDiskId());
+ }
+ }
+ }
+ }
+
+ // VDiskMetrics
+ TVector<Schema::VDiskMetrics::TKey::Type> vdiskMetricsToDelete;
+ {
+ using Table = Schema::VDiskMetrics;
+ auto table = db.Table<Table>().Range().Select();
+ if (!table.IsReady()) {
+ return false;
+ }
+ while (!table.EndOfSet()) {
+ const TVDiskID key(table.GetValue<Table::GroupID>(), table.GetValue<Table::GroupGeneration>(),
+ table.GetValue<Table::Ring>(), table.GetValue<Table::FailDomain>(), table.GetValue<Table::VDisk>());
+ if (TVSlotInfo *slot = Self->FindVSlot(key)) {
+ slot->Metrics = table.GetValueOrDefault<Table::Metrics>();
+ slot->UpdateVDiskMetrics();
+ } else {
+ vdiskMetricsToDelete.push_back(table.GetKey());
+ }
+ if (!table.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // GroupLatencies
+ {
+ using Table = Schema::GroupLatencies;
+ auto groupLatencies = db.Table<Table>().Select();
+ if (!groupLatencies.IsReady()) {
+ return false;
+ }
+ while (groupLatencies.IsValid()) {
+ const TGroupId groupId = groupLatencies.GetValue<Table::GroupId>();
+ if (TGroupInfo *groupInfo = Self->FindGroup(groupId)) {
+ if (groupLatencies.HaveValue<Table::PutTabletLogLatencyUs>()) {
+ groupInfo->LatencyStats.PutTabletLog = TDuration::MicroSeconds(groupLatencies.GetValue<Table::PutTabletLogLatencyUs>());
+ }
+ if (groupLatencies.HaveValue<Table::PutUserDataLatencyUs>()) {
+ groupInfo->LatencyStats.PutUserData = TDuration::MicroSeconds(groupLatencies.GetValue<Table::PutUserDataLatencyUs>());
+ }
+ if (groupLatencies.HaveValue<Table::GetFastLatencyUs>()) {
+ groupInfo->LatencyStats.GetFast = TDuration::MicroSeconds(groupLatencies.GetValue<Table::GetFastLatencyUs>());
+ }
+ } else {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXLE02, "Nonexistent group in GroupLatencies", (GroupId, groupId));
+ }
+
+ if (!groupLatencies.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // primitive garbage collection for obsolete metrics
+ for (const auto& key : pdiskMetricsToDelete) {
+ db.Table<Schema::PDiskMetrics>().Key(key).Delete();
+ }
+ for (const auto& key : vdiskMetricsToDelete) {
+ db.Table<Schema::VDiskMetrics>().Key(key).Delete();
+ }
+
+ // apply storage pool stats
+ std::unordered_map<TBoxStoragePoolId, ui64> allocatedSizeMap;
+ for (const auto& [vslotId, slot] : Self->VSlots) {
+ if (!slot->IsBeingDeleted()) {
+ TGroupInfo *group = Self->FindGroup(slot->GroupId);
+ Y_VERIFY(group);
+ allocatedSizeMap[group->StoragePoolId] += slot->Metrics.GetAllocatedSize();
+ }
+ }
+ for (const auto& [id, info] : Self->StoragePools) {
+ Self->StoragePoolStat->AddStoragePool(TStoragePoolStat::ConvertId(id), info.Name, allocatedSizeMap[id]);
+ }
+ for (const auto& [groupId, group] : Self->GroupMap) {
+ group->StatusFlags = group->GetStorageStatusFlags();
+ Self->StoragePoolStat->Update(TStoragePoolStat::ConvertId(group->StoragePoolId), std::nullopt, group->StatusFlags);
+ }
+
+ // scrub state
+ {
+ using Table = Schema::ScrubState;
+ auto scrubState = db.Table<Table>().Select();
+ if (!scrubState.IsReady()) {
+ return false;
+ }
+ while (scrubState.IsValid()) {
+ Self->ScrubState.AddItem(
+ scrubState.GetKey(),
+ scrubState.HaveValue<Table::State>() ? std::make_optional(scrubState.GetValue<Table::State>()) : std::nullopt,
+ scrubState.GetValue<Table::ScrubCycleStartTime>(),
+ scrubState.GetValue<Table::ScrubCycleFinishTime>(),
+ scrubState.GetValue<Table::Success>());
+ if (!scrubState.Next()) {
+ return false;
+ }
+ }
+ }
+
+ // calculate group status for all groups
+ for (auto& [id, group] : Self->GroupMap) {
+ group->CalculateGroupStatus();
+ }
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE03, "TTxLoadEverything Complete");
+ Self->LoadFinished();
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXLE04, "TTxLoadEverything InitQueue processed");
+ }
+};
+
+ITransaction* TBlobStorageController::CreateTxLoadEverything() {
+ return new TTxLoadEverything(this);
+}
+
+} // NBlobStorageController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/migrate.cpp b/ydb/core/mind/bscontroller/migrate.cpp
index 20d10f8b621..5c1e2238668 100644
--- a/ydb/core/mind/bscontroller/migrate.cpp
+++ b/ydb/core/mind/bscontroller/migrate.cpp
@@ -1,217 +1,217 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxMigrate : public TTransactionBase<TBlobStorageController> {
- class TTxBase {
- protected:
- TBlobStorageController *Self = nullptr;
-
- public:
- virtual ~TTxBase() = default;
- virtual bool Execute(TTransactionContext& txc) = 0;
- virtual void Complete() {}
- void SetController(TBlobStorageController *self) { Self = self; }
- };
-
- class TTxQueue : public TTransactionBase<TBlobStorageController> {
- TDeque<THolder<TTxBase>> Queue;
-
- public:
- TTxQueue(TBlobStorageController *controller, TDeque<THolder<TTxBase>> queue)
- : TTransactionBase(controller)
- , Queue(std::move(queue))
- {
- Y_VERIFY(Queue);
- auto& front = Queue.front();
- front->SetController(controller);
- }
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MIGRATE; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- auto& front = Queue.front();
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxMigrate : public TTransactionBase<TBlobStorageController> {
+ class TTxBase {
+ protected:
+ TBlobStorageController *Self = nullptr;
+
+ public:
+ virtual ~TTxBase() = default;
+ virtual bool Execute(TTransactionContext& txc) = 0;
+ virtual void Complete() {}
+ void SetController(TBlobStorageController *self) { Self = self; }
+ };
+
+ class TTxQueue : public TTransactionBase<TBlobStorageController> {
+ TDeque<THolder<TTxBase>> Queue;
+
+ public:
+ TTxQueue(TBlobStorageController *controller, TDeque<THolder<TTxBase>> queue)
+ : TTransactionBase(controller)
+ , Queue(std::move(queue))
+ {
+ Y_VERIFY(Queue);
+ auto& front = Queue.front();
+ front->SetController(controller);
+ }
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MIGRATE; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ auto& front = Queue.front();
STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM03, "Execute tx from queue", (Type, TypeName(*front)));
- return front->Execute(txc);
- }
-
- void Complete(const TActorContext&) override {
- auto& front = Queue.front();
+ return front->Execute(txc);
+ }
+
+ void Complete(const TActorContext&) override {
+ auto& front = Queue.front();
STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM04, "Complete tx from queue", (Type, TypeName(*front)));
- front->Complete();
- Queue.pop_front();
- if (Queue) {
- Self->Execute(new TTxQueue(Self, std::move(Queue)));
- } else {
- Self->Execute(Self->CreateTxLoadEverything());
- }
- }
- };
-
- class TTxTrimUnusedSlots : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- NIceDb::TNiceDb db(txc.DB);
-
- using Table = Schema::VSlot;
-
- TVector<Table::TKey::TupleType> eraseList;
-
- auto slots = db.Table<Table>().Range().Select();
- if (!slots.IsReady()) {
- return false;
- }
- while (!slots.EndOfSet()) {
- if (!slots.GetValue<Table::GroupID>()) {
- // item scheduled for deletion
- eraseList.push_back(slots.GetKey());
- }
- if (!slots.Next()) {
- return false;
- }
- }
-
- for (const auto& key : eraseList) {
- db.Table<Table>().Key(key).Delete();
- }
-
- return true;
- }
- };
-
- class TTxUpdateSchemaVersion : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(true).Update<Schema::State::SchemaVersion>(Schema::CurrentSchemaVersion);
- return true;
- }
- };
-
- class TTxGenerateInstanceId : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(true).Update<Schema::State::InstanceId>(CreateGuidAsString());
- return true;
- }
- };
-
- class TTxUpdateStaticPDiskInfo : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::PDisk;
- using TUpdateItem = std::tuple<T::Category::Type, T::Guid::Type, T::PDiskConfig::Type>;
- std::deque<std::pair<T::TKey::Type, TUpdateItem>> updates;
- for (const auto& [key, value] : Self->StaticPDiskMap) {
- const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk = value;
- auto table = db.Table<T>().Key(key.GetKey()).Select();
- if (!table.IsReady()) {
- return false;
- } else if (table.IsValid()) {
- TString pdiskConfig;
+ front->Complete();
+ Queue.pop_front();
+ if (Queue) {
+ Self->Execute(new TTxQueue(Self, std::move(Queue)));
+ } else {
+ Self->Execute(Self->CreateTxLoadEverything());
+ }
+ }
+ };
+
+ class TTxTrimUnusedSlots : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ NIceDb::TNiceDb db(txc.DB);
+
+ using Table = Schema::VSlot;
+
+ TVector<Table::TKey::TupleType> eraseList;
+
+ auto slots = db.Table<Table>().Range().Select();
+ if (!slots.IsReady()) {
+ return false;
+ }
+ while (!slots.EndOfSet()) {
+ if (!slots.GetValue<Table::GroupID>()) {
+ // item scheduled for deletion
+ eraseList.push_back(slots.GetKey());
+ }
+ if (!slots.Next()) {
+ return false;
+ }
+ }
+
+ for (const auto& key : eraseList) {
+ db.Table<Table>().Key(key).Delete();
+ }
+
+ return true;
+ }
+ };
+
+ class TTxUpdateSchemaVersion : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(true).Update<Schema::State::SchemaVersion>(Schema::CurrentSchemaVersion);
+ return true;
+ }
+ };
+
+ class TTxGenerateInstanceId : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ NIceDb::TNiceDb(txc.DB).Table<Schema::State>().Key(true).Update<Schema::State::InstanceId>(CreateGuidAsString());
+ return true;
+ }
+ };
+
+ class TTxUpdateStaticPDiskInfo : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::PDisk;
+ using TUpdateItem = std::tuple<T::Category::Type, T::Guid::Type, T::PDiskConfig::Type>;
+ std::deque<std::pair<T::TKey::Type, TUpdateItem>> updates;
+ for (const auto& [key, value] : Self->StaticPDiskMap) {
+ const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk = value;
+ auto table = db.Table<T>().Key(key.GetKey()).Select();
+ if (!table.IsReady()) {
+ return false;
+ } else if (table.IsValid()) {
+ TString pdiskConfig;
Y_PROTOBUF_SUPPRESS_NODISCARD pdisk.GetPDiskConfig().SerializeToString(&pdiskConfig);
- updates.emplace_back(key.GetKey(), TUpdateItem(pdisk.GetPDiskCategory(), pdisk.GetPDiskGuid(), pdiskConfig));
- }
- }
- for (const auto& [key, value] : updates) {
- db.Table<T>().Key(key).Update<T::Category, T::Guid, T::PDiskConfig>(std::get<0>(value),
- std::get<1>(value), std::get<2>(value));
- }
- return true;
- }
- };
-
- class TTxFillInNonNullConfigForPDisk : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::PDisk;
- std::deque<T::TKey::Type> keys;
- auto table = db.Table<T>().Select();
- if (!table.IsReady()) {
- return false;
- }
- while (table.IsValid()) {
- if (!table.HaveValue<T::PDiskConfig>()) {
- keys.emplace_back(table.GetKey());
- }
- if (!table.Next()) {
- return false;
- }
- }
- for (const auto& key : keys) {
- db.Table<T>().Key(key).Update<T::PDiskConfig>(TString());
- }
- return true;
- }
- };
-
- class TTxDropDriveStatus : public TTxBase {
- public:
- bool Execute(TTransactionContext& txc) override {
- if (txc.DB.GetScheme().GetTableInfo(Schema::DriveStatusTableId)) {
- txc.DB.Alter().DropTable(Schema::DriveStatusTableId);
- }
- return true;
- }
- };
-
- TDeque<THolder<TTxBase>> Queue;
-
-public:
- using TTransactionBase::TTransactionBase;
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MIGRATE; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM01, "Execute tx");
- Queue.clear();
-
- NIceDb::TNiceDb db(txc.DB);
-
- auto state = db.Table<Schema::State>().Select<Schema::State::SchemaVersion, Schema::State::InstanceId>();
- if (!state.IsReady()) {
- return false;
- }
- bool hasInstanceId = false;
- if (state.IsValid()) {
- const ui32 version = state.GetValue<Schema::State::SchemaVersion>();
- if (Schema::CurrentSchemaVersion >= Schema::BoxHostMigrationSchemaVersion && version < Schema::BoxHostMigrationSchemaVersion) {
- Y_FAIL("unsupported schema");
- }
- hasInstanceId = state.HaveValue<Schema::State::InstanceId>();
- }
-
- // trim unused VSlots to prevent them from loading
- Queue.emplace_back(new TTxTrimUnusedSlots);
-
- // update schema version to current value
- Queue.emplace_back(new TTxUpdateSchemaVersion);
-
- // generate cluster instance id
- if (!hasInstanceId) {
- Queue.emplace_back(new TTxGenerateInstanceId);
- }
-
- Queue.emplace_back(new TTxUpdateStaticPDiskInfo);
-
- Queue.emplace_back(new TTxFillInNonNullConfigForPDisk);
-
- Queue.emplace_back(new TTxDropDriveStatus);
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM02, "Complete tx");
- Self->Execute(new TTxQueue(Self, std::move(Queue)));
- }
-};
-
+ updates.emplace_back(key.GetKey(), TUpdateItem(pdisk.GetPDiskCategory(), pdisk.GetPDiskGuid(), pdiskConfig));
+ }
+ }
+ for (const auto& [key, value] : updates) {
+ db.Table<T>().Key(key).Update<T::Category, T::Guid, T::PDiskConfig>(std::get<0>(value),
+ std::get<1>(value), std::get<2>(value));
+ }
+ return true;
+ }
+ };
+
+ class TTxFillInNonNullConfigForPDisk : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::PDisk;
+ std::deque<T::TKey::Type> keys;
+ auto table = db.Table<T>().Select();
+ if (!table.IsReady()) {
+ return false;
+ }
+ while (table.IsValid()) {
+ if (!table.HaveValue<T::PDiskConfig>()) {
+ keys.emplace_back(table.GetKey());
+ }
+ if (!table.Next()) {
+ return false;
+ }
+ }
+ for (const auto& key : keys) {
+ db.Table<T>().Key(key).Update<T::PDiskConfig>(TString());
+ }
+ return true;
+ }
+ };
+
+ class TTxDropDriveStatus : public TTxBase {
+ public:
+ bool Execute(TTransactionContext& txc) override {
+ if (txc.DB.GetScheme().GetTableInfo(Schema::DriveStatusTableId)) {
+ txc.DB.Alter().DropTable(Schema::DriveStatusTableId);
+ }
+ return true;
+ }
+ };
+
+ TDeque<THolder<TTxBase>> Queue;
+
+public:
+ using TTransactionBase::TTransactionBase;
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MIGRATE; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM01, "Execute tx");
+ Queue.clear();
+
+ NIceDb::TNiceDb db(txc.DB);
+
+ auto state = db.Table<Schema::State>().Select<Schema::State::SchemaVersion, Schema::State::InstanceId>();
+ if (!state.IsReady()) {
+ return false;
+ }
+ bool hasInstanceId = false;
+ if (state.IsValid()) {
+ const ui32 version = state.GetValue<Schema::State::SchemaVersion>();
+ if (Schema::CurrentSchemaVersion >= Schema::BoxHostMigrationSchemaVersion && version < Schema::BoxHostMigrationSchemaVersion) {
+ Y_FAIL("unsupported schema");
+ }
+ hasInstanceId = state.HaveValue<Schema::State::InstanceId>();
+ }
+
+ // trim unused VSlots to prevent them from loading
+ Queue.emplace_back(new TTxTrimUnusedSlots);
+
+ // update schema version to current value
+ Queue.emplace_back(new TTxUpdateSchemaVersion);
+
+ // generate cluster instance id
+ if (!hasInstanceId) {
+ Queue.emplace_back(new TTxGenerateInstanceId);
+ }
+
+ Queue.emplace_back(new TTxUpdateStaticPDiskInfo);
+
+ Queue.emplace_back(new TTxFillInNonNullConfigForPDisk);
+
+ Queue.emplace_back(new TTxDropDriveStatus);
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXM02, "Complete tx");
+ Self->Execute(new TTxQueue(Self, std::move(Queue)));
+ }
+};
+
ITransaction* TBlobStorageController::CreateTxMigrate() {
- return new TTxMigrate(this);
-}
-
-} // NBlobStorageController
-} // NKikimr
+ return new TTxMigrate(this);
+}
+
+} // NBlobStorageController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/monitoring.cpp b/ydb/core/mind/bscontroller/monitoring.cpp
index 245c782cea6..dccc066b373 100644
--- a/ydb/core/mind/bscontroller/monitoring.cpp
+++ b/ydb/core/mind/bscontroller/monitoring.cpp
@@ -1,20 +1,20 @@
-#include "impl.h"
-
+#include "impl.h"
+
#include <library/cpp/json/json_writer.h>
-namespace NKikimr {
-namespace NBsController {
-
-static const char *DataSizeSuffix[] = {"B", "KiB", "MiB", "GiB", nullptr};
-
-static void RenderBytesCell(IOutputStream& out, ui64 bytes) {
- HTML(out) {
- TABLED_ATTRS({{"data-text", ToString(bytes)}}) {
- FormatHumanReadable(out, bytes, 1024, 2, DataSizeSuffix);
- }
- }
-}
-
+namespace NKikimr {
+namespace NBsController {
+
+static const char *DataSizeSuffix[] = {"B", "KiB", "MiB", "GiB", nullptr};
+
+static void RenderBytesCell(IOutputStream& out, ui64 bytes) {
+ HTML(out) {
+ TABLED_ATTRS({{"data-text", ToString(bytes)}}) {
+ FormatHumanReadable(out, bytes, 1024, 2, DataSizeSuffix);
+ }
+ }
+}
+
template<typename T>
static TString PrintMaybe(const TMaybe<T>& m) {
if (m) {
@@ -24,743 +24,743 @@ static TString PrintMaybe(const TMaybe<T>& m) {
}
}
-class TBlobStorageController::TTxMonEvent_OperationLog : public TTransactionBase<TBlobStorageController> {
+class TBlobStorageController::TTxMonEvent_OperationLog : public TTransactionBase<TBlobStorageController> {
const TActorId RespondTo;
- const TCgiParameters Params;
-
-private:
+ const TCgiParameters Params;
+
+private:
struct TOperationLogEntry {
- using T = Schema::OperationLog;
- T::Index::Type Index;
- T::Timestamp::Type Timestamp;
- T::Request::Type Request;
- T::Response::Type Response;
- T::ExecutionTime::Type ExecutionTime;
+ using T = Schema::OperationLog;
+ T::Index::Type Index;
+ T::Timestamp::Type Timestamp;
+ T::Request::Type Request;
+ T::Response::Type Response;
+ T::ExecutionTime::Type ExecutionTime;
};
-private:
+private:
TVector<TOperationLogEntry> Logs;
- ui64 NumRows = 0;
+ ui64 NumRows = 0;
-public:
+public:
TTxMonEvent_OperationLog(const TActorId& sender, TCgiParameters params, TSelf *controller)
- : TBase(controller)
- , RespondTo(sender)
- , Params(std::move(params))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_OPERATION_LOG; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- ui64 count = FromStringWithDefault<ui64>(Params.Get("RowsCount"), 1000);
- ui64 offset = FromStringWithDefault<ui64>(Params.Get("RowsOffset"), 0);
- if (!count) {
- count = 1;
- }
- if (!LoadOperationLog(txc, count, offset)) {
- return false;
- }
- TStringStream str;
- RenderOperationLog(str, count, offset);
- TActivationContext::Send(new IEventHandle(RespondTo, Self->SelfId(), new NMon::TEvRemoteHttpInfoRes(str.Str())));
- return true;
- }
-
- void Complete(const TActorContext&) override
- {}
-
- bool LoadOperationLog(TTransactionContext& txc, ui64 count, ui64 offset) {
+ : TBase(controller)
+ , RespondTo(sender)
+ , Params(std::move(params))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_OPERATION_LOG; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ ui64 count = FromStringWithDefault<ui64>(Params.Get("RowsCount"), 1000);
+ ui64 offset = FromStringWithDefault<ui64>(Params.Get("RowsOffset"), 0);
+ if (!count) {
+ count = 1;
+ }
+ if (!LoadOperationLog(txc, count, offset)) {
+ return false;
+ }
+ TStringStream str;
+ RenderOperationLog(str, count, offset);
+ TActivationContext::Send(new IEventHandle(RespondTo, Self->SelfId(), new NMon::TEvRemoteHttpInfoRes(str.Str())));
+ return true;
+ }
+
+ void Complete(const TActorContext&) override
+ {}
+
+ bool LoadOperationLog(TTransactionContext& txc, ui64 count, ui64 offset) {
NIceDb::TNiceDb db(txc.DB);
- using T = Schema::OperationLog;
-
- // obtain the very first record index
- ui64 firstRecordIndex = 0;
- {
- auto table = db.Table<T>().Select();
- if (!table.IsReady()) {
- return false;
- } else if (!table.EndOfSet()) {
- firstRecordIndex = table.GetValue<T::Index>();
- NumRows = Self->NextOperationLogIndex - firstRecordIndex;
- }
- }
-
- // scan the table
- auto table = db.Table<T>().GreaterOrEqual(firstRecordIndex + offset).Select();
- if (!table.IsReady()) {
+ using T = Schema::OperationLog;
+
+ // obtain the very first record index
+ ui64 firstRecordIndex = 0;
+ {
+ auto table = db.Table<T>().Select();
+ if (!table.IsReady()) {
+ return false;
+ } else if (!table.EndOfSet()) {
+ firstRecordIndex = table.GetValue<T::Index>();
+ NumRows = Self->NextOperationLogIndex - firstRecordIndex;
+ }
+ }
+
+ // scan the table
+ auto table = db.Table<T>().GreaterOrEqual(firstRecordIndex + offset).Select();
+ if (!table.IsReady()) {
return false;
}
- Logs.reserve(count);
- for (; !table.EndOfSet() && count; --count) {
- const auto& index = table.GetValue<Schema::OperationLog::Index>();
- const auto& timestamp = table.GetValue<Schema::OperationLog::Timestamp>();
- const auto& request = table.GetValue<Schema::OperationLog::Request>();
- const auto& response = table.GetValue<Schema::OperationLog::Response>();
- const auto& executionTime = table.GetValue<Schema::OperationLog::ExecutionTime>();
- Logs.emplace_back(TOperationLogEntry{index, timestamp, request, response, executionTime});
- if (!table.Next()) {
+ Logs.reserve(count);
+ for (; !table.EndOfSet() && count; --count) {
+ const auto& index = table.GetValue<Schema::OperationLog::Index>();
+ const auto& timestamp = table.GetValue<Schema::OperationLog::Timestamp>();
+ const auto& request = table.GetValue<Schema::OperationLog::Request>();
+ const auto& response = table.GetValue<Schema::OperationLog::Response>();
+ const auto& executionTime = table.GetValue<Schema::OperationLog::ExecutionTime>();
+ Logs.emplace_back(TOperationLogEntry{index, timestamp, request, response, executionTime});
+ if (!table.Next()) {
return false;
}
}
return true;
}
- void RenderOperationLog(IOutputStream& out, const ui64 count, const ui64 offset) {
- Self->RenderHeader(out);
-
- HTML(out) {
- H3() {
- out << "Operation Log";
- }
+ void RenderOperationLog(IOutputStream& out, const ui64 count, const ui64 offset) {
+ Self->RenderHeader(out);
+
+ HTML(out) {
+ H3() {
+ out << "Operation Log";
+ }
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { out << "Index"; }
- TABLEH() { out << "Timestamp"; }
- TABLEH() { out << "Request"; }
- TABLEH() { out << "Response"; }
- TABLEH() { out << "Execution<br/>time"; }
- }
- }
- TABLEBODY() {
- for (size_t id = 0; id < Logs.size(); ++id) {
- TABLER() {
- const auto &entry = Logs[id];
- NKikimrBlobStorage::TConfigRequest request;
- NKikimrBlobStorage::TConfigResponse response;
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { out << "Index"; }
+ TABLEH() { out << "Timestamp"; }
+ TABLEH() { out << "Request"; }
+ TABLEH() { out << "Response"; }
+ TABLEH() { out << "Execution<br/>time"; }
+ }
+ }
+ TABLEBODY() {
+ for (size_t id = 0; id < Logs.size(); ++id) {
+ TABLER() {
+ const auto &entry = Logs[id];
+ NKikimrBlobStorage::TConfigRequest request;
+ NKikimrBlobStorage::TConfigResponse response;
Y_PROTOBUF_SUPPRESS_NODISCARD request.ParseFromString(entry.Request);
Y_PROTOBUF_SUPPRESS_NODISCARD response.ParseFromString(entry.Response);
- TABLED() { out << entry.Index; }
- TABLED() { out << entry.Timestamp.ToRfc822String(); }
- TABLED() {
- out << "<input class='hide' id='request-" << id << "' type='checkbox'>"
- "<label for='request-" << id << "'>Show</label>"
- "<pre>" << request.DebugString() << "</pre>";
- }
- TABLED() {
- out << "<input class='hide' id='response-" << id << "' type='checkbox'>"
- "<label for='response-" << id << "'>Show</label>"
- "<pre>" << response.DebugString() << "</pre>";
- }
- TABLED() {
- out << entry.ExecutionTime;
- }
- }
- }
- }
- }
- }
-
- out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
- << (Max(offset, count) - count) << "'>Previous</a>";
- out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
- << (offset + count) << "' style='padding-left: 15px;'>Next</a>";
- out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
- << 0 << "' style='padding-left: 15px;'>First page</a>";
- ui64 lastPageIndex = 0;
- if (NumRows) {
- lastPageIndex = NumRows - 10;
- lastPageIndex -= lastPageIndex % count;
- ++lastPageIndex;
- }
- out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
- << lastPageIndex << "' style='padding-left: 15px;'>Last page</a>";
-
- Self->RenderFooter(out);
- }
-};
-
-class TBlobStorageController::TTxMonEvent_HealthEvents
- : public TTransactionBase<TBlobStorageController>
-{
+ TABLED() { out << entry.Index; }
+ TABLED() { out << entry.Timestamp.ToRfc822String(); }
+ TABLED() {
+ out << "<input class='hide' id='request-" << id << "' type='checkbox'>"
+ "<label for='request-" << id << "'>Show</label>"
+ "<pre>" << request.DebugString() << "</pre>";
+ }
+ TABLED() {
+ out << "<input class='hide' id='response-" << id << "' type='checkbox'>"
+ "<label for='response-" << id << "'>Show</label>"
+ "<pre>" << response.DebugString() << "</pre>";
+ }
+ TABLED() {
+ out << entry.ExecutionTime;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
+ << (Max(offset, count) - count) << "'>Previous</a>";
+ out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
+ << (offset + count) << "' style='padding-left: 15px;'>Next</a>";
+ out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
+ << 0 << "' style='padding-left: 15px;'>First page</a>";
+ ui64 lastPageIndex = 0;
+ if (NumRows) {
+ lastPageIndex = NumRows - 10;
+ lastPageIndex -= lastPageIndex % count;
+ ++lastPageIndex;
+ }
+ out << "<a href='?TabletID=" << Self->TabletID() << "&page=OperationLog&RowsCount=" << count << "&RowsOffset="
+ << lastPageIndex << "' style='padding-left: 15px;'>Last page</a>";
+
+ Self->RenderFooter(out);
+ }
+};
+
+class TBlobStorageController::TTxMonEvent_HealthEvents
+ : public TTransactionBase<TBlobStorageController>
+{
const TActorId RespondTo;
- const bool Json;
- const ui64 Offset = 0;
- const ui64 NumRows = 1000;
-
- TInstant Since;
-
- struct TReassignItem {
- TVDiskID VDiskId;
- TVSlotId From;
- TVSlotId To;
- TString FromFqdn, FromPath;
- TString ToFqdn, ToPath;
- };
-
- struct TEvent {
- TInstant Timestamp;
- TString Message;
- std::vector<TReassignItem> Reassign;
- NJson::TJsonValue Json;
-
- TEvent(TInstant timestamp, TString message, std::vector<TReassignItem> reassign = {})
- : Timestamp(timestamp)
- , Message(message)
- , Reassign(std::move(reassign))
- {}
- };
- std::deque<TEvent> Events;
-
- static NJson::TJsonValue ToJson(const TVDiskID& vdiskId) {
- NJson::TJsonValue j(NJson::JSON_MAP);
- j["GroupId"] = vdiskId.GroupID;
- j["GroupGeneration"] = vdiskId.GroupGeneration;
- j["FailRealmIdx"] = vdiskId.FailRealm;
- j["FailDomainIdx"] = vdiskId.FailDomain;
- j["VDiskIdx"] = vdiskId.VDisk;
- return j;
- }
-
- static NJson::TJsonValue ToJson(const TPDiskId& pdiskId) {
- NJson::TJsonValue j(NJson::JSON_MAP);
- j["NodeId"] = pdiskId.NodeId;
- j["PDiskId"] = pdiskId.PDiskId;
- return j;
- }
-
- static NJson::TJsonValue ToJson(const TVSlotId& vslotId) {
- auto j = ToJson(vslotId.ComprisingPDiskId());
- j["VSlotId"] = vslotId.VSlotId;
- return j;
- }
-
- template<typename T>
- static NJson::TJsonValue ToJson(const std::optional<T>& x) {
- return x ? ToJson(*x) : NJson::TJsonValue(NJson::JSON_NULL);
- }
-
- template<typename T>
- static NJson::TJsonValue ToJsonOrNullOnDefault(const T& x) {
- return x != T() ? NJson::TJsonValue(x) : NJson::TJsonValue(NJson::JSON_NULL);
- }
-
-public:
- TTxMonEvent_HealthEvents(const TActorId& sender, const TCgiParameters& cgi, TSelf *controller)
- : TBase(controller)
- , RespondTo(sender)
- , Json(cgi.Has("fmt") && cgi.Get("fmt") == "json")
- , Offset(FromStringWithDefault<ui64>(cgi.Get("RowsOffset"), 0))
- , NumRows(FromStringWithDefault<ui64>(cgi.Get("RowsCount"), 1000))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_HEALTH_EVENTS; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- const TInstant now = TActivationContext::Now();
- Since = now - TDuration::Days(14) - TDuration::FromValue(now.GetValue() % TDuration::Days(1).GetValue());
- Events.clear();
-
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::OperationLog;
- auto table = db.Table<T>().Reverse().Select();
- if (!table.IsReady()) {
- return false;
- }
- while (table.IsValid()) {
- const TInstant timestamp = table.GetValue<T::Timestamp>();
- if (timestamp < Since) {
- break;
- }
-
- NKikimrBlobStorage::TConfigRequest request;
- NKikimrBlobStorage::TConfigResponse response;
- if (!request.ParseFromString(table.GetValue<T::Request>())) {
- Events.emplace_front(timestamp, Sprintf("Failed to parse Request Index# %" PRIu64, table.GetValue<T::Index>()));
- } else if (!response.ParseFromString(table.GetValue<T::Response>())) {
- Events.emplace_front(timestamp, Sprintf("Failed to parse Response Index# %" PRIu64, table.GetValue<T::Index>()));
- } else {
- for (size_t k = 0; k < request.CommandSize() && k < response.StatusSize(); ++k) {
- const auto& r = response.GetStatus(k);
- if (!r.GetSuccess()) {
- continue;
- }
- std::vector<TReassignItem> reassign;
- for (const auto& item : r.GetReassignedItem()) {
- TReassignItem r;
- r.VDiskId = VDiskIDFromVDiskID(item.GetVDiskId());
- r.From = item.GetFrom();
- r.To = item.GetTo();
- r.FromFqdn = item.GetFromFqdn();
- r.FromPath = item.GetFromPath();
- r.ToFqdn = item.GetToFqdn();
- r.ToPath = item.GetToPath();
- reassign.push_back(std::move(r));
- }
-
- const auto& q = request.GetCommand(k);
- switch (q.GetCommandCase()) {
- case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal: {
- const auto& cmd = q.GetEnableSelfHeal();
- const char *message = cmd.GetEnable() ? "Self-Heal enabled" : "Self-Heal disabled";
- Events.emplace_front(timestamp, message);
- auto& j = Events.front().Json;
- j["Event"] = message;
- break;
- }
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kReassignGroupDisk: {
- const auto& cmd = q.GetReassignGroupDisk();
-
- const TVDiskID vdiskId(cmd.GetGroupId(), cmd.GetGroupGeneration(),
- cmd.GetFailRealmIdx(), cmd.GetFailDomainIdx(), cmd.GetVDiskIdx());
-
- std::optional<TPDiskId> pdiskId;
- if (cmd.HasTargetPDiskId()) {
- const auto& x = cmd.GetTargetPDiskId();
- pdiskId.emplace(x.GetNodeId(), x.GetPDiskId());
- }
-
- TStringStream msg;
- msg << "VDisk reassign request"
- << "<br/>VDiskId# " << vdiskId
- << "<br/>GroupId# " << vdiskId.GroupID;
-
- if (pdiskId) {
- msg << "<br/>PDiskId# " << *pdiskId;
- }
-
- Events.emplace_front(timestamp, msg.Str(), std::move(reassign));
- auto& j = Events.front().Json;
- j["Event"] = "ReassignGroupDisk";
- j["VDiskId"] = ToJson(vdiskId);
- j["TargetPDiskId"] = ToJson(pdiskId);
- break;
- }
-
- case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateDriveStatus: {
- const auto& cmd = q.GetUpdateDriveStatus();
-
- const auto& key = cmd.GetHostKey();
- TString fqdn = key.GetFqdn();
- i32 icPort = key.GetIcPort();
- ui32 nodeId = key.GetNodeId();
- if (!fqdn) {
- if (auto x = Self->HostRecords->GetHostId(nodeId)) {
- std::tie(fqdn, icPort) = *x;
- }
- }
- if (!nodeId) {
- if (auto x = Self->HostRecords->GetNodeId(std::make_tuple(fqdn, icPort))) {
- nodeId = *x;
- }
- }
-
- TStringStream msg;
- msg << "Update drive status"
- << "<br/>FQDN# " << (fqdn ? fqdn : "unknown")
- << "<br/>NodeId# " << (nodeId ? ToString(nodeId) : "unknown")
- << "<br/>Path# " << cmd.GetPath();
-
- if (const auto& pdiskId = cmd.GetPDiskId()) {
- msg << "<br/>PDiskId# " << pdiskId;
- }
-
- msg << "<br/>to " << NKikimrBlobStorage::EDriveStatus_Name(cmd.GetStatus());
- Events.emplace_front(timestamp, msg.Str(), std::move(reassign));
- auto& j = Events.front().Json;
- j["Event"] = "UpdateDriveStatus";
- j["FQDN"] = ToJsonOrNullOnDefault(fqdn);
- j["IcPort"] = ToJsonOrNullOnDefault(icPort);
- j["NodeId"] = ToJsonOrNullOnDefault(nodeId);
- j["Path"] = ToJsonOrNullOnDefault(cmd.GetPath());
- j["PDiskId"] = ToJsonOrNullOnDefault(cmd.GetPDiskId());
- j["Status"] = NKikimrBlobStorage::EDriveStatus_Name(cmd.GetStatus());
- break;
- }
-
- default:
- break;
- }
- }
- }
-
- if (!table.Next()) {
- return false;
- }
- }
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- TActivationContext::Send(new IEventHandle(RespondTo, Self->SelfId(), Json
- ? static_cast<IEventBase*>(new NMon::TEvRemoteJsonInfoRes(GenerateJson()))
- : static_cast<IEventBase*>(new NMon::TEvRemoteHttpInfoRes(GenerateHtml()))));
- }
-
- TString GenerateHtml() {
- TStringStream s;
+ const bool Json;
+ const ui64 Offset = 0;
+ const ui64 NumRows = 1000;
+
+ TInstant Since;
+
+ struct TReassignItem {
+ TVDiskID VDiskId;
+ TVSlotId From;
+ TVSlotId To;
+ TString FromFqdn, FromPath;
+ TString ToFqdn, ToPath;
+ };
+
+ struct TEvent {
+ TInstant Timestamp;
+ TString Message;
+ std::vector<TReassignItem> Reassign;
+ NJson::TJsonValue Json;
+
+ TEvent(TInstant timestamp, TString message, std::vector<TReassignItem> reassign = {})
+ : Timestamp(timestamp)
+ , Message(message)
+ , Reassign(std::move(reassign))
+ {}
+ };
+ std::deque<TEvent> Events;
+
+ static NJson::TJsonValue ToJson(const TVDiskID& vdiskId) {
+ NJson::TJsonValue j(NJson::JSON_MAP);
+ j["GroupId"] = vdiskId.GroupID;
+ j["GroupGeneration"] = vdiskId.GroupGeneration;
+ j["FailRealmIdx"] = vdiskId.FailRealm;
+ j["FailDomainIdx"] = vdiskId.FailDomain;
+ j["VDiskIdx"] = vdiskId.VDisk;
+ return j;
+ }
+
+ static NJson::TJsonValue ToJson(const TPDiskId& pdiskId) {
+ NJson::TJsonValue j(NJson::JSON_MAP);
+ j["NodeId"] = pdiskId.NodeId;
+ j["PDiskId"] = pdiskId.PDiskId;
+ return j;
+ }
+
+ static NJson::TJsonValue ToJson(const TVSlotId& vslotId) {
+ auto j = ToJson(vslotId.ComprisingPDiskId());
+ j["VSlotId"] = vslotId.VSlotId;
+ return j;
+ }
+
+ template<typename T>
+ static NJson::TJsonValue ToJson(const std::optional<T>& x) {
+ return x ? ToJson(*x) : NJson::TJsonValue(NJson::JSON_NULL);
+ }
+
+ template<typename T>
+ static NJson::TJsonValue ToJsonOrNullOnDefault(const T& x) {
+ return x != T() ? NJson::TJsonValue(x) : NJson::TJsonValue(NJson::JSON_NULL);
+ }
+
+public:
+ TTxMonEvent_HealthEvents(const TActorId& sender, const TCgiParameters& cgi, TSelf *controller)
+ : TBase(controller)
+ , RespondTo(sender)
+ , Json(cgi.Has("fmt") && cgi.Get("fmt") == "json")
+ , Offset(FromStringWithDefault<ui64>(cgi.Get("RowsOffset"), 0))
+ , NumRows(FromStringWithDefault<ui64>(cgi.Get("RowsCount"), 1000))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_HEALTH_EVENTS; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ const TInstant now = TActivationContext::Now();
+ Since = now - TDuration::Days(14) - TDuration::FromValue(now.GetValue() % TDuration::Days(1).GetValue());
+ Events.clear();
+
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::OperationLog;
+ auto table = db.Table<T>().Reverse().Select();
+ if (!table.IsReady()) {
+ return false;
+ }
+ while (table.IsValid()) {
+ const TInstant timestamp = table.GetValue<T::Timestamp>();
+ if (timestamp < Since) {
+ break;
+ }
+
+ NKikimrBlobStorage::TConfigRequest request;
+ NKikimrBlobStorage::TConfigResponse response;
+ if (!request.ParseFromString(table.GetValue<T::Request>())) {
+ Events.emplace_front(timestamp, Sprintf("Failed to parse Request Index# %" PRIu64, table.GetValue<T::Index>()));
+ } else if (!response.ParseFromString(table.GetValue<T::Response>())) {
+ Events.emplace_front(timestamp, Sprintf("Failed to parse Response Index# %" PRIu64, table.GetValue<T::Index>()));
+ } else {
+ for (size_t k = 0; k < request.CommandSize() && k < response.StatusSize(); ++k) {
+ const auto& r = response.GetStatus(k);
+ if (!r.GetSuccess()) {
+ continue;
+ }
+ std::vector<TReassignItem> reassign;
+ for (const auto& item : r.GetReassignedItem()) {
+ TReassignItem r;
+ r.VDiskId = VDiskIDFromVDiskID(item.GetVDiskId());
+ r.From = item.GetFrom();
+ r.To = item.GetTo();
+ r.FromFqdn = item.GetFromFqdn();
+ r.FromPath = item.GetFromPath();
+ r.ToFqdn = item.GetToFqdn();
+ r.ToPath = item.GetToPath();
+ reassign.push_back(std::move(r));
+ }
+
+ const auto& q = request.GetCommand(k);
+ switch (q.GetCommandCase()) {
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kEnableSelfHeal: {
+ const auto& cmd = q.GetEnableSelfHeal();
+ const char *message = cmd.GetEnable() ? "Self-Heal enabled" : "Self-Heal disabled";
+ Events.emplace_front(timestamp, message);
+ auto& j = Events.front().Json;
+ j["Event"] = message;
+ break;
+ }
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kReassignGroupDisk: {
+ const auto& cmd = q.GetReassignGroupDisk();
+
+ const TVDiskID vdiskId(cmd.GetGroupId(), cmd.GetGroupGeneration(),
+ cmd.GetFailRealmIdx(), cmd.GetFailDomainIdx(), cmd.GetVDiskIdx());
+
+ std::optional<TPDiskId> pdiskId;
+ if (cmd.HasTargetPDiskId()) {
+ const auto& x = cmd.GetTargetPDiskId();
+ pdiskId.emplace(x.GetNodeId(), x.GetPDiskId());
+ }
+
+ TStringStream msg;
+ msg << "VDisk reassign request"
+ << "<br/>VDiskId# " << vdiskId
+ << "<br/>GroupId# " << vdiskId.GroupID;
+
+ if (pdiskId) {
+ msg << "<br/>PDiskId# " << *pdiskId;
+ }
+
+ Events.emplace_front(timestamp, msg.Str(), std::move(reassign));
+ auto& j = Events.front().Json;
+ j["Event"] = "ReassignGroupDisk";
+ j["VDiskId"] = ToJson(vdiskId);
+ j["TargetPDiskId"] = ToJson(pdiskId);
+ break;
+ }
+
+ case NKikimrBlobStorage::TConfigRequest::TCommand::kUpdateDriveStatus: {
+ const auto& cmd = q.GetUpdateDriveStatus();
+
+ const auto& key = cmd.GetHostKey();
+ TString fqdn = key.GetFqdn();
+ i32 icPort = key.GetIcPort();
+ ui32 nodeId = key.GetNodeId();
+ if (!fqdn) {
+ if (auto x = Self->HostRecords->GetHostId(nodeId)) {
+ std::tie(fqdn, icPort) = *x;
+ }
+ }
+ if (!nodeId) {
+ if (auto x = Self->HostRecords->GetNodeId(std::make_tuple(fqdn, icPort))) {
+ nodeId = *x;
+ }
+ }
+
+ TStringStream msg;
+ msg << "Update drive status"
+ << "<br/>FQDN# " << (fqdn ? fqdn : "unknown")
+ << "<br/>NodeId# " << (nodeId ? ToString(nodeId) : "unknown")
+ << "<br/>Path# " << cmd.GetPath();
+
+ if (const auto& pdiskId = cmd.GetPDiskId()) {
+ msg << "<br/>PDiskId# " << pdiskId;
+ }
+
+ msg << "<br/>to " << NKikimrBlobStorage::EDriveStatus_Name(cmd.GetStatus());
+ Events.emplace_front(timestamp, msg.Str(), std::move(reassign));
+ auto& j = Events.front().Json;
+ j["Event"] = "UpdateDriveStatus";
+ j["FQDN"] = ToJsonOrNullOnDefault(fqdn);
+ j["IcPort"] = ToJsonOrNullOnDefault(icPort);
+ j["NodeId"] = ToJsonOrNullOnDefault(nodeId);
+ j["Path"] = ToJsonOrNullOnDefault(cmd.GetPath());
+ j["PDiskId"] = ToJsonOrNullOnDefault(cmd.GetPDiskId());
+ j["Status"] = NKikimrBlobStorage::EDriveStatus_Name(cmd.GetStatus());
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!table.Next()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ TActivationContext::Send(new IEventHandle(RespondTo, Self->SelfId(), Json
+ ? static_cast<IEventBase*>(new NMon::TEvRemoteJsonInfoRes(GenerateJson()))
+ : static_cast<IEventBase*>(new NMon::TEvRemoteHttpInfoRes(GenerateHtml()))));
+ }
+
+ TString GenerateHtml() {
+ TStringStream s;
Self->RenderHeader(s);
- HTML(s) {
- ui64 offset = Offset;
-
- H3() {
+ HTML(s) {
+ ui64 offset = Offset;
+
+ H3() {
s << "Health events";
- }
+ }
H3() {
s << "Health-related operations since " << Since.ToRfc822StringLocal();
}
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { s << "UTC ts"; }
- TABLEH() { s << "Local ts"; }
- TABLEH() { s << "Message"; }
- TABLEH() { s << "Reassign"; }
- }
- }
- TABLEBODY() {
- auto it = Events.begin();
- std::advance(it, Min<size_t>(offset, Events.size()));
- for (ui64 i = 0; i < NumRows && it != Events.end(); ++i, ++offset, ++it) {
- const TEvent& event = *it;
- TABLER() {
- TABLED() { s << event.Timestamp.ToStringUpToSeconds(); }
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { s << "UTC ts"; }
+ TABLEH() { s << "Local ts"; }
+ TABLEH() { s << "Message"; }
+ TABLEH() { s << "Reassign"; }
+ }
+ }
+ TABLEBODY() {
+ auto it = Events.begin();
+ std::advance(it, Min<size_t>(offset, Events.size()));
+ for (ui64 i = 0; i < NumRows && it != Events.end(); ++i, ++offset, ++it) {
+ const TEvent& event = *it;
+ TABLER() {
+ TABLED() { s << event.Timestamp.ToStringUpToSeconds(); }
TABLED() { s << event.Timestamp.ToRfc822StringLocal(); }
- TABLED() { s << event.Message; }
- TABLED() {
- for (const TReassignItem& item : event.Reassign) {
- s << "<p>VDiskId# " << item.VDiskId << " (" << item.VDiskId.GroupID << ")"
- << "<br/>From# " << item.From
- << " " << item.FromFqdn << ":" << item.FromPath
- << "<br/>To# " << item.To
- << " " << item.ToFqdn << ":" << item.ToPath
- << "</p>";
- }
- }
- }
- }
- }
- }
-
- bool first = true;
- auto renderPageLink = [&](const char *name, ui64 offset) {
- s << "<a href='?TabletID=" << Self->TabletID() << "&page=HealthEvents&RowsCount=" << NumRows
- << "&RowsOffset=" << offset << "'" << (first ? "" : " style='padding-left: 15px;'")
- << ">" << name << "</a>";
- first = false;
- };
-
- if (Offset) {
- renderPageLink("Previous", Offset < NumRows ? 0 : Offset - NumRows);
- }
- if (offset != Events.size()) {
- renderPageLink("Next", offset);
- }
- if (Offset) {
- renderPageLink("First page", 0);
- }
- const ui64 lastPageOffset = Events.size() - Events.size() % NumRows;
- if (Offset < lastPageOffset) {
- renderPageLink("Last page", lastPageOffset);
- }
- }
+ TABLED() { s << event.Message; }
+ TABLED() {
+ for (const TReassignItem& item : event.Reassign) {
+ s << "<p>VDiskId# " << item.VDiskId << " (" << item.VDiskId.GroupID << ")"
+ << "<br/>From# " << item.From
+ << " " << item.FromFqdn << ":" << item.FromPath
+ << "<br/>To# " << item.To
+ << " " << item.ToFqdn << ":" << item.ToPath
+ << "</p>";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bool first = true;
+ auto renderPageLink = [&](const char *name, ui64 offset) {
+ s << "<a href='?TabletID=" << Self->TabletID() << "&page=HealthEvents&RowsCount=" << NumRows
+ << "&RowsOffset=" << offset << "'" << (first ? "" : " style='padding-left: 15px;'")
+ << ">" << name << "</a>";
+ first = false;
+ };
+
+ if (Offset) {
+ renderPageLink("Previous", Offset < NumRows ? 0 : Offset - NumRows);
+ }
+ if (offset != Events.size()) {
+ renderPageLink("Next", offset);
+ }
+ if (Offset) {
+ renderPageLink("First page", 0);
+ }
+ const ui64 lastPageOffset = Events.size() - Events.size() % NumRows;
+ if (Offset < lastPageOffset) {
+ renderPageLink("Last page", lastPageOffset);
+ }
+ }
Self->RenderFooter(s);
- return s.Str();
- }
-
- TString GenerateJson() {
- NJson::TJsonValue json, events(NJson::JSON_ARRAY);
- for (auto& event : Events) {
- auto& j = event.Json;
- j["Timestamp"] = event.Timestamp.ToString();
- if (!event.Reassign.empty()) {
- NJson::TJsonValue reassign(NJson::JSON_ARRAY);
- for (const TReassignItem& item : event.Reassign) {
- NJson::TJsonValue x;
- x["VDiskId"] = ToJson(item.VDiskId);
- x["From"] = ToJson(item.From);
- x["From"]["FQDN"] = ToJsonOrNullOnDefault(item.FromFqdn);
- x["From"]["Path"] = ToJsonOrNullOnDefault(item.FromPath);
- x["To"] = ToJson(item.To);
- x["To"]["FQDN"] = ToJsonOrNullOnDefault(item.ToFqdn);
- x["To"]["Path"] = ToJsonOrNullOnDefault(item.ToPath);
- reassign.AppendValue(std::move(x));
- }
- j["Reassign"] = std::move(reassign);
- }
- events.AppendValue(std::move(j));
- }
- json["Events"] = std::move(events);
- TStringStream s;
- NJson::WriteJson(&s, &json);
- return s.Str();
- }
-};
-
-class TBlobStorageController::TTxMonEvent_SetDown : public TTransactionBase<TBlobStorageController> {
-public:
+ return s.Str();
+ }
+
+ TString GenerateJson() {
+ NJson::TJsonValue json, events(NJson::JSON_ARRAY);
+ for (auto& event : Events) {
+ auto& j = event.Json;
+ j["Timestamp"] = event.Timestamp.ToString();
+ if (!event.Reassign.empty()) {
+ NJson::TJsonValue reassign(NJson::JSON_ARRAY);
+ for (const TReassignItem& item : event.Reassign) {
+ NJson::TJsonValue x;
+ x["VDiskId"] = ToJson(item.VDiskId);
+ x["From"] = ToJson(item.From);
+ x["From"]["FQDN"] = ToJsonOrNullOnDefault(item.FromFqdn);
+ x["From"]["Path"] = ToJsonOrNullOnDefault(item.FromPath);
+ x["To"] = ToJson(item.To);
+ x["To"]["FQDN"] = ToJsonOrNullOnDefault(item.ToFqdn);
+ x["To"]["Path"] = ToJsonOrNullOnDefault(item.ToPath);
+ reassign.AppendValue(std::move(x));
+ }
+ j["Reassign"] = std::move(reassign);
+ }
+ events.AppendValue(std::move(j));
+ }
+ json["Events"] = std::move(events);
+ TStringStream s;
+ NJson::WriteJson(&s, &json);
+ return s.Str();
+ }
+};
+
+class TBlobStorageController::TTxMonEvent_SetDown : public TTransactionBase<TBlobStorageController> {
+public:
const TActorId Source;
- const TGroupId GroupId;
- const bool Down;
- const bool Persist;
- TString Response;
-
+ const TGroupId GroupId;
+ const bool Down;
+ const bool Persist;
+ TString Response;
+
TTxMonEvent_SetDown(const TActorId& source, TGroupId groupId, bool down, bool persist, TSelf* bsc)
- : TBase(bsc)
- , Source(source)
- , GroupId(groupId)
- , Down(down)
- , Persist(persist)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_SET_DOWN; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TGroupInfo* group = Self->FindGroup(GroupId);
- if (group == nullptr) {
- Response = "{\"Error\":\"Group " + ToString(GroupId) + " not found\"}";
- return true;
- }
- group->Down = Down;
- if (Persist) {
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::Group>().Key(GroupId).Update<Schema::Group::Down>(Down);
- group->PersistedDown = Down;
- }
- Response = "{\"GroupId\":" + ToString(GroupId) + ',' + "\"Down\":" + (Down ? "true" : "false") + "}";
- return true;
- }
-
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXMO01, "TBlobStorageController::TTxMonEvent_SetDown",
- (GroupId, GroupId), (Down, Down), (Persist, Persist), (Response, Response));
- TActivationContext::Send(new IEventHandle(Source, Self->SelfId(), new NMon::TEvRemoteJsonInfoRes(Response)));
- }
-};
-
-class TBlobStorageController::TTxMonEvent_GetDown : public TTransactionBase<TBlobStorageController> {
-public:
+ : TBase(bsc)
+ , Source(source)
+ , GroupId(groupId)
+ , Down(down)
+ , Persist(persist)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_SET_DOWN; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ TGroupInfo* group = Self->FindGroup(GroupId);
+ if (group == nullptr) {
+ Response = "{\"Error\":\"Group " + ToString(GroupId) + " not found\"}";
+ return true;
+ }
+ group->Down = Down;
+ if (Persist) {
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::Group>().Key(GroupId).Update<Schema::Group::Down>(Down);
+ group->PersistedDown = Down;
+ }
+ Response = "{\"GroupId\":" + ToString(GroupId) + ',' + "\"Down\":" + (Down ? "true" : "false") + "}";
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXMO01, "TBlobStorageController::TTxMonEvent_SetDown",
+ (GroupId, GroupId), (Down, Down), (Persist, Persist), (Response, Response));
+ TActivationContext::Send(new IEventHandle(Source, Self->SelfId(), new NMon::TEvRemoteJsonInfoRes(Response)));
+ }
+};
+
+class TBlobStorageController::TTxMonEvent_GetDown : public TTransactionBase<TBlobStorageController> {
+public:
const TActorId Source;
- const TGroupId GroupId;
- TString Response;
+ const TGroupId GroupId;
+ TString Response;
TTxMonEvent_GetDown(const TActorId& source, TGroupId groupId, TSelf* bsc)
- : TBase(bsc)
- , Source(source)
- , GroupId(groupId)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_GET_DOWN; }
-
- bool Execute(TTransactionContext&, const TActorContext&) override {
- NJson::TJsonValue json;
-
- auto reportGroup = [](const TGroupInfo& group) {
- NJson::TJsonValue item;
- item["GroupId"] = group.ID;
- item["Down"] = group.Down;
- item["PersistedDown"] = group.PersistedDown;
- return item;
- };
-
- if (GroupId) {
- if (TGroupInfo* group = Self->FindGroup(GroupId)) {
- json = reportGroup(*group);
- } else {
- json["Error"] = Sprintf("GroupId# %" PRIu32 " not found", GroupId);
- }
- } else {
- for (const auto& kv : Self->GroupMap) {
- json.AppendValue(reportGroup(*kv.second));
+ : TBase(bsc)
+ , Source(source)
+ , GroupId(groupId)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_MON_EVENT_GET_DOWN; }
+
+ bool Execute(TTransactionContext&, const TActorContext&) override {
+ NJson::TJsonValue json;
+
+ auto reportGroup = [](const TGroupInfo& group) {
+ NJson::TJsonValue item;
+ item["GroupId"] = group.ID;
+ item["Down"] = group.Down;
+ item["PersistedDown"] = group.PersistedDown;
+ return item;
+ };
+
+ if (GroupId) {
+ if (TGroupInfo* group = Self->FindGroup(GroupId)) {
+ json = reportGroup(*group);
+ } else {
+ json["Error"] = Sprintf("GroupId# %" PRIu32 " not found", GroupId);
}
+ } else {
+ for (const auto& kv : Self->GroupMap) {
+ json.AppendValue(reportGroup(*kv.second));
+ }
}
-
- TStringStream stream;
- NJson::WriteJson(&stream, &json);
- Response = stream.Str();
-
- return true;
+
+ TStringStream stream;
+ NJson::WriteJson(&stream, &json);
+ Response = stream.Str();
+
+ return true;
}
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXMO02, "TBlobStorageController::TTxMonEvent_GetDown", (GroupId, GroupId),
- (Response, Response));
- TActivationContext::Send(new IEventHandle(Source, Self->SelfId(), new NMon::TEvRemoteJsonInfoRes(Response)));
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXMO02, "TBlobStorageController::TTxMonEvent_GetDown", (GroupId, GroupId),
+ (Response, Response));
+ TActivationContext::Send(new IEventHandle(Source, Self->SelfId(), new NMon::TEvRemoteJsonInfoRes(Response)));
}
-};
+};
-class TDisableSelfHealActor : public TActorBootstrapped<TDisableSelfHealActor> {
+class TDisableSelfHealActor : public TActorBootstrapped<TDisableSelfHealActor> {
const TActorId MonProxy;
- const TString Url;
-
-public:
+ const TString Url;
+
+public:
TDisableSelfHealActor(TActorId monProxy, TString url)
- : MonProxy(monProxy)
- , Url(std::move(url))
- {}
-
+ : MonProxy(monProxy)
+ , Url(std::move(url))
+ {}
+
void Bootstrap(const TActorId& parent) {
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- ev->Record.MutableRequest()->AddCommand()->MutableEnableSelfHeal()->SetEnable(false);
- Send(parent, ev.Release());
- Become(&TThis::StateFunc);
- }
-
- void HandleResponse() {
- Send(MonProxy, new NMon::TEvRemoteBinaryInfoRes(TStringBuilder()
- << NMonitoring::HTTPOKHTML
- << "<html><head><meta http-equiv=\"refresh\" content=\"0; " << Url << "\"></head></html>"
- ));
- PassAway();
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ ev->Record.MutableRequest()->AddCommand()->MutableEnableSelfHeal()->SetEnable(false);
+ Send(parent, ev.Release());
+ Become(&TThis::StateFunc);
+ }
+
+ void HandleResponse() {
+ Send(MonProxy, new NMon::TEvRemoteBinaryInfoRes(TStringBuilder()
+ << NMonitoring::HTTPOKHTML
+ << "<html><head><meta http-equiv=\"refresh\" content=\"0; " << Url << "\"></head></html>"
+ ));
+ PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ cFunc(TEvBlobStorage::EvControllerConfigResponse, HandleResponse)
+ )
+};
+
+bool TBlobStorageController::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) {
+ if (!Executor() || !Executor()->GetStats().IsActive) {
+ return false;
}
-
- STRICT_STFUNC(StateFunc,
- cFunc(TEvBlobStorage::EvControllerConfigResponse, HandleResponse)
- )
-};
-
-bool TBlobStorageController::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext&) {
- if (!Executor() || !Executor()->GetStats().IsActive) {
- return false;
- }
- if (!ev) {
- return true;
- }
-
- THolder<TTransactionBase<TBlobStorageController>> tx;
- TStringStream str;
- const TCgiParameters& cgi(ev->Get()->Cgi());
-
- if (!cgi.count("page")) {
- RenderMonPage(str);
- } else {
- const TString& page = cgi.Get("page");
- if (page == "SetDown") {
- TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("group"), 0);
- const bool down = FromStringWithDefault<i32>(cgi.Get("down"), 0);
- const bool persist = FromStringWithDefault<i32>(cgi.Get("persist"), 0);
- tx.Reset(new TTxMonEvent_SetDown(ev->Sender, groupId, down, persist, this));
- } else if (page == "GetDown") {
- TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("group"), 0);
- tx.Reset(new TTxMonEvent_GetDown(ev->Sender, groupId, this));
- } else if (page == "OperationLog") {
- tx.Reset(new TTxMonEvent_OperationLog(ev->Sender, cgi, this));
- } else if (page == "HealthEvents") {
- Execute(new TTxMonEvent_HealthEvents(ev->Sender, cgi, this));
- return true;
- } else if (page == "SelfHeal") {
+ if (!ev) {
+ return true;
+ }
+
+ THolder<TTransactionBase<TBlobStorageController>> tx;
+ TStringStream str;
+ const TCgiParameters& cgi(ev->Get()->Cgi());
+
+ if (!cgi.count("page")) {
+ RenderMonPage(str);
+ } else {
+ const TString& page = cgi.Get("page");
+ if (page == "SetDown") {
+ TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("group"), 0);
+ const bool down = FromStringWithDefault<i32>(cgi.Get("down"), 0);
+ const bool persist = FromStringWithDefault<i32>(cgi.Get("persist"), 0);
+ tx.Reset(new TTxMonEvent_SetDown(ev->Sender, groupId, down, persist, this));
+ } else if (page == "GetDown") {
+ TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("group"), 0);
+ tx.Reset(new TTxMonEvent_GetDown(ev->Sender, groupId, this));
+ } else if (page == "OperationLog") {
+ tx.Reset(new TTxMonEvent_OperationLog(ev->Sender, cgi, this));
+ } else if (page == "HealthEvents") {
+ Execute(new TTxMonEvent_HealthEvents(ev->Sender, cgi, this));
+ return true;
+ } else if (page == "SelfHeal") {
bool hiddenAction = cgi.Has("action") && cgi.Get("action") == "disableSelfHeal";
if (cgi.Has("disable") && cgi.Get("disable") == "1" && hiddenAction) {
- Register(new TDisableSelfHealActor(ev->Sender, TStringBuilder() << "?TabletID="
- << TabletID() << "&page=SelfHeal"));
- } else {
- TActivationContext::Send(new IEventHandle(SelfHealId, ev->Sender, ev->Release().Release(), 0,
- SelfHealEnable));
- }
- return true;
- } else if (page == "Groups") {
- const ui64 boxId = FromStringWithDefault<ui64>(cgi.Get("BoxId"), -1);
- const ui64 storagePoolId = FromStringWithDefault<ui64>(cgi.Get("StoragePoolId"), -1);
- RenderGroupsInStoragePool(str, TBoxStoragePoolId(boxId, storagePoolId));
- } else if (page == "GroupDetail") {
- const TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("GroupId"), -1);
- RenderGroupDetail(str, groupId);
- } else if (page == "Scrub") {
- ScrubState.Render(str);
+ Register(new TDisableSelfHealActor(ev->Sender, TStringBuilder() << "?TabletID="
+ << TabletID() << "&page=SelfHeal"));
+ } else {
+ TActivationContext::Send(new IEventHandle(SelfHealId, ev->Sender, ev->Release().Release(), 0,
+ SelfHealEnable));
+ }
+ return true;
+ } else if (page == "Groups") {
+ const ui64 boxId = FromStringWithDefault<ui64>(cgi.Get("BoxId"), -1);
+ const ui64 storagePoolId = FromStringWithDefault<ui64>(cgi.Get("StoragePoolId"), -1);
+ RenderGroupsInStoragePool(str, TBoxStoragePoolId(boxId, storagePoolId));
+ } else if (page == "GroupDetail") {
+ const TGroupId groupId = FromStringWithDefault<TGroupId>(cgi.Get("GroupId"), -1);
+ RenderGroupDetail(str, groupId);
+ } else if (page == "Scrub") {
+ ScrubState.Render(str);
} else if (page == "InternalTables") {
const TString table = cgi.Has("table") ? cgi.Get("table") : "pdisks";
RenderInternalTables(str, table);
- } else if (page == "StopGivingGroups") {
- StopGivingGroups = true;
- str << "OK";
- } else if (page == "StartGivingGroups") {
- StopGivingGroups = false;
- str << "OK";
- } else {
- str << "Invalid URL";
- }
- }
-
- if (tx) {
- Execute(tx.Release());
- } else {
- Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- }
-
- return true;
-}
-
-void TBlobStorageController::RenderResourceValues(IOutputStream& out, const TResourceRawValues& current) {
- RenderBytesCell(out, current.DataSize);
-}
-
-void TBlobStorageController::RenderHeader(IOutputStream& out) {
- out << "<html>";
- out << "<script>"
- "$('.container').toggleClass('container container-fluid');"
- "</script>";
- out << "<style>";
- out << ".hide, .hide + label ~ pre { display: none; }";
- out << ".hide + label, .hide:checked + label { padding: 0; user-select: none; "
- " cursor: pointer; color: red; cursor: pointer; border-bottom: 1px solid red; }";
- out << ".hide:checked + label { color: red; border-bottom: 0; }";
- out << ".hide:checked + label + pre { display: block; }";
- out << "</style>";
- out << "<h2>BlobStorage Controller</h2>";
-}
-
-void TBlobStorageController::RenderFooter(IOutputStream& out) {
- out << "</html>";
-}
-
-void TBlobStorageController::RenderMonPage(IOutputStream& out) {
- RenderHeader(out);
-
+ } else if (page == "StopGivingGroups") {
+ StopGivingGroups = true;
+ str << "OK";
+ } else if (page == "StartGivingGroups") {
+ StopGivingGroups = false;
+ str << "OK";
+ } else {
+ str << "Invalid URL";
+ }
+ }
+
+ if (tx) {
+ Execute(tx.Release());
+ } else {
+ Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ }
+
+ return true;
+}
+
+void TBlobStorageController::RenderResourceValues(IOutputStream& out, const TResourceRawValues& current) {
+ RenderBytesCell(out, current.DataSize);
+}
+
+void TBlobStorageController::RenderHeader(IOutputStream& out) {
+ out << "<html>";
+ out << "<script>"
+ "$('.container').toggleClass('container container-fluid');"
+ "</script>";
+ out << "<style>";
+ out << ".hide, .hide + label ~ pre { display: none; }";
+ out << ".hide + label, .hide:checked + label { padding: 0; user-select: none; "
+ " cursor: pointer; color: red; cursor: pointer; border-bottom: 1px solid red; }";
+ out << ".hide:checked + label { color: red; border-bottom: 0; }";
+ out << ".hide:checked + label + pre { display: block; }";
+ out << "</style>";
+ out << "<h2>BlobStorage Controller</h2>";
+}
+
+void TBlobStorageController::RenderFooter(IOutputStream& out) {
+ out << "</html>";
+}
+
+void TBlobStorageController::RenderMonPage(IOutputStream& out) {
+ RenderHeader(out);
+
out << "<a href='app?TabletID=" << TabletID() << "&page=OperationLog'>Operation Log</a><br>";
out << "<a href='app?TabletID=" << TabletID() << "&page=SelfHeal'>Self Heal Status</a> (" <<
- (SelfHealEnable ? "enabled" : "disabled") << ")<br>";
+ (SelfHealEnable ? "enabled" : "disabled") << ")<br>";
out << "<a href='app?TabletID=" << TabletID() << "&page=HealthEvents'>Health events</a><br>";
out << "<a href='app?TabletID=" << TabletID() << "&page=Scrub'>Scrub state</a><br>";
out << "<a href='app?TabletID=" << TabletID() << "&page=InternalTables'>Internal tables</a><br>";
- HTML(out) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Settings";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { out << "Parameter"; }
- TABLEH() { out << "Value"; }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { out << "Donor Mode"; }
- TABLED() { out << (DonorMode ? "enabled" : "disabled"); }
- }
- TABLER() {
- TABLED() { out << "Self Heal"; }
- TABLED() { out << (SelfHealEnable ? "enabled" : "disabled"); }
- }
- TABLER() {
- TABLED() { out << "Serial drive management stage"; }
- TABLED() { out << SerialManagementStage; }
- }
- TABLER() {
- TABLED() { out << "Default Max Slots"; }
- TABLED() { out << DefaultMaxSlots; }
- }
- TABLER() {
- TABLED() { out << "PDisk space margin (&#8240;)"; }
- TABLED() { out << PDiskSpaceMarginPromille; }
- }
+ HTML(out) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Settings";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { out << "Parameter"; }
+ TABLEH() { out << "Value"; }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { out << "Donor Mode"; }
+ TABLED() { out << (DonorMode ? "enabled" : "disabled"); }
+ }
+ TABLER() {
+ TABLED() { out << "Self Heal"; }
+ TABLED() { out << (SelfHealEnable ? "enabled" : "disabled"); }
+ }
+ TABLER() {
+ TABLED() { out << "Serial drive management stage"; }
+ TABLED() { out << SerialManagementStage; }
+ }
+ TABLER() {
+ TABLED() { out << "Default Max Slots"; }
+ TABLED() { out << DefaultMaxSlots; }
+ }
+ TABLER() {
+ TABLED() { out << "PDisk space margin (&#8240;)"; }
+ TABLED() { out << PDiskSpaceMarginPromille; }
+ }
TABLER() {
TABLED() { out << "PDisk space color border"; }
TABLED() { out << NKikimrBlobStorage::TPDiskSpaceColor::E_Name(PDiskSpaceColorBorder); }
}
- }
- }
- }
- }
- }
-
+ }
+ }
+ }
+ }
+ }
+
RenderFooter(out);
}
@@ -774,132 +774,132 @@ void TBlobStorageController::RenderInternalTables(IOutputStream& out, const TStr
out << "</li>";
};
- out << "<ul class='nav nav-tabs'>";
+ out << "<ul class='nav nav-tabs'>";
gen_li("pdisks");
gen_li("vdisks");
gen_li("groups");
gen_li("boxes");
gen_li("serials");
- out << "</ul>";
-
- HTML(out) {
+ out << "</ul>";
+
+ HTML(out) {
if (table == "pdisks") {
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TAG_ATTRS(TTableH, {{"title", "NodeId:PDiskId"}}) { out << "Id"; }
- TABLEH() { out << "Type"; }
- TABLEH() { out << "Kind"; }
- TABLEH() { out << "Path"; }
- TABLEH() { out << "Guid"; }
- TABLEH() { out << "BoxId"; }
+ TABLEHEAD() {
+ TABLER() {
+ TAG_ATTRS(TTableH, {{"title", "NodeId:PDiskId"}}) { out << "Id"; }
+ TABLEH() { out << "Type"; }
+ TABLEH() { out << "Kind"; }
+ TABLEH() { out << "Path"; }
+ TABLEH() { out << "Guid"; }
+ TABLEH() { out << "BoxId"; }
TABLEH() { out << "Total Size"; }
- TABLEH() { out << "Status"; }
- TABLEH() { out << "State"; }
+ TABLEH() { out << "Status"; }
+ TABLEH() { out << "State"; }
TABLEH() { out << "ExpectedSerial"; }
TABLEH() { out << "LastSeenSerial"; }
TABLEH() { out << "LastSeenPath"; }
- }
- }
- TABLEBODY() {
- for (const auto& [pdiskId, pdisk] : PDisks) {
- const auto& m = pdisk->Metrics;
- TAG_ATTRS(TTableR, {{"title", m.DebugString()}}) {
- TPDiskCategory category(pdisk->Kind);
- TABLED() { out << pdiskId; }
- TABLED() { out << category.TypeStrShort(); }
- TABLED() { out << category.Kind(); }
- TABLED() { out << pdisk->Path; }
- TABLED() { out << pdisk->Guid; }
- TABLED() { out << pdisk->BoxId; }
- RenderBytesCell(out, m.GetTotalSize());
- TABLED() { out << NKikimrBlobStorage::EDriveStatus_Name(pdisk->Status); }
- TABLED() {
- if (const auto& m = pdisk->Metrics; m.HasState()) {
- out << NKikimrBlobStorage::TPDiskState::E_Name(m.GetState());
- }
- }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& [pdiskId, pdisk] : PDisks) {
+ const auto& m = pdisk->Metrics;
+ TAG_ATTRS(TTableR, {{"title", m.DebugString()}}) {
+ TPDiskCategory category(pdisk->Kind);
+ TABLED() { out << pdiskId; }
+ TABLED() { out << category.TypeStrShort(); }
+ TABLED() { out << category.Kind(); }
+ TABLED() { out << pdisk->Path; }
+ TABLED() { out << pdisk->Guid; }
+ TABLED() { out << pdisk->BoxId; }
+ RenderBytesCell(out, m.GetTotalSize());
+ TABLED() { out << NKikimrBlobStorage::EDriveStatus_Name(pdisk->Status); }
+ TABLED() {
+ if (const auto& m = pdisk->Metrics; m.HasState()) {
+ out << NKikimrBlobStorage::TPDiskState::E_Name(m.GetState());
+ }
+ }
TABLED() { out << pdisk->ExpectedSerial.Quote(); }
TABLED() {
TString color = pdisk->ExpectedSerial == pdisk->LastSeenSerial ? "green" : "red";
out << "<font color='" << color << "'>" << pdisk->LastSeenSerial.Quote() << "</font>";
}
TABLED() { out << pdisk->LastSeenPath; }
- }
- }
- }
- }
+ }
+ }
+ }
+ }
} else if (table == "vdisks") {
- RenderVSlotTable(out, [&] {
- for (const auto& [key, value] : VSlots) {
- RenderVSlotRow(out, *value);
- }
- });
+ RenderVSlotTable(out, [&] {
+ for (const auto& [key, value] : VSlots) {
+ RenderVSlotRow(out, *value);
+ }
+ });
} else if (table == "groups") {
- RenderGroupTable(out, [&] {
- for (const auto& [key, value] : GroupMap) {
- RenderGroupRow(out, *value);
- }
- });
+ RenderGroupTable(out, [&] {
+ for (const auto& [key, value] : GroupMap) {
+ RenderGroupRow(out, *value);
+ }
+ });
} else if (table == "boxes") {
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TAG_ATTRS(TTableH, {{"colspan", "3"}}) { out << "Box attributes"; }
- TAG_ATTRS(TTableH, {{"colspan", "7"}}) { out << "Storage pools"; }
- }
- TABLER() {
- TABLEH() { out << "BoxId"; }
- TABLEH() { out << "Name"; }
- TABLEH() { out << "Generation"; }
-
- TABLEH() { out << "StoragePoolId"; }
- TABLEH() { out << "Name"; }
- TABLEH() { out << "ErasureSpecies"; }
- TABLEH() { out << "VDiskKind"; }
- TABLEH() { out << "Kind"; }
- TABLEH() { out << "NumGroups"; }
- TABLEH() { out << "Detail"; }
- }
- }
- TABLEBODY() {
- for (const auto& [boxId, box] : Boxes) {
- auto renderBoxPart = [&, boxId = boxId, &box = box] {
- TABLED() { out << boxId; }
- TABLED() { out << box.Name; }
- TABLED() { out << box.Generation.GetOrElse(0); }
- };
-
- const TBoxStoragePoolId storagePoolId(boxId, Min<Schema::BoxStoragePool::StoragePoolId::Type>());
- size_t enlistedStoragePools = 0;
- for (auto it = StoragePools.lower_bound(storagePoolId); it != StoragePools.end() &&
- std::get<0>(it->first) == boxId; ++it, ++enlistedStoragePools) {
- TABLER() {
- renderBoxPart();
- TABLED() { out << std::get<1>(it->first); }
- TABLED() { out << it->second.Name; }
- TABLED() { out << TBlobStorageGroupType::ErasureSpeciesName(it->second.ErasureSpecies); }
- TABLED() { out << NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(it->second.VDiskKind); }
- TABLED() { out << it->second.Kind; }
- TABLED() { out << it->second.NumGroups; }
- TABLED() {
- out << "<a href='?TabletID=" << TabletID()
- << "&page=Groups&BoxId=" << boxId
- << "&StoragePoolId=" << std::get<1>(it->first)
- << "'>Detail</a>";
- }
- }
- }
- if (!enlistedStoragePools) {
- TABLER() {
- renderBoxPart();
- TABLED_ATTRS({{"colspan", "7"}, {"align", "center"}}) {
- out << "No storage pools";
- }
- }
- }
- }
- }
+ TABLEHEAD() {
+ TABLER() {
+ TAG_ATTRS(TTableH, {{"colspan", "3"}}) { out << "Box attributes"; }
+ TAG_ATTRS(TTableH, {{"colspan", "7"}}) { out << "Storage pools"; }
+ }
+ TABLER() {
+ TABLEH() { out << "BoxId"; }
+ TABLEH() { out << "Name"; }
+ TABLEH() { out << "Generation"; }
+
+ TABLEH() { out << "StoragePoolId"; }
+ TABLEH() { out << "Name"; }
+ TABLEH() { out << "ErasureSpecies"; }
+ TABLEH() { out << "VDiskKind"; }
+ TABLEH() { out << "Kind"; }
+ TABLEH() { out << "NumGroups"; }
+ TABLEH() { out << "Detail"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& [boxId, box] : Boxes) {
+ auto renderBoxPart = [&, boxId = boxId, &box = box] {
+ TABLED() { out << boxId; }
+ TABLED() { out << box.Name; }
+ TABLED() { out << box.Generation.GetOrElse(0); }
+ };
+
+ const TBoxStoragePoolId storagePoolId(boxId, Min<Schema::BoxStoragePool::StoragePoolId::Type>());
+ size_t enlistedStoragePools = 0;
+ for (auto it = StoragePools.lower_bound(storagePoolId); it != StoragePools.end() &&
+ std::get<0>(it->first) == boxId; ++it, ++enlistedStoragePools) {
+ TABLER() {
+ renderBoxPart();
+ TABLED() { out << std::get<1>(it->first); }
+ TABLED() { out << it->second.Name; }
+ TABLED() { out << TBlobStorageGroupType::ErasureSpeciesName(it->second.ErasureSpecies); }
+ TABLED() { out << NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(it->second.VDiskKind); }
+ TABLED() { out << it->second.Kind; }
+ TABLED() { out << it->second.NumGroups; }
+ TABLED() {
+ out << "<a href='?TabletID=" << TabletID()
+ << "&page=Groups&BoxId=" << boxId
+ << "&StoragePoolId=" << std::get<1>(it->first)
+ << "'>Detail</a>";
+ }
+ }
+ }
+ if (!enlistedStoragePools) {
+ TABLER() {
+ renderBoxPart();
+ TABLED_ATTRS({{"colspan", "7"}, {"align", "center"}}) {
+ out << "No storage pools";
+ }
+ }
+ }
+ }
+ }
}
} else if (table == "serials") {
TABLE_CLASS("table") {
@@ -918,207 +918,207 @@ void TBlobStorageController::RenderInternalTables(IOutputStream& out, const TStr
for (const auto& [serial, info] : DrivesSerials) {
TABLER() {
TABLED() { out << serial.Serial.Quote(); }
- TABLED() { out << "(" << PrintMaybe(info->NodeId) << ":" << PrintMaybe(info->PDiskId) << ")"; }
- TABLED() { out << info->BoxId; }
- TABLED() { out << PrintMaybe(info->Guid); }
- TABLED() { out << info->LifeStage; }
- TABLED() { out << info->Kind; }
- TABLED() { out << info->PDiskType; }
+ TABLED() { out << "(" << PrintMaybe(info->NodeId) << ":" << PrintMaybe(info->PDiskId) << ")"; }
+ TABLED() { out << info->BoxId; }
+ TABLED() { out << PrintMaybe(info->Guid); }
+ TABLED() { out << info->LifeStage; }
+ TABLED() { out << info->Kind; }
+ TABLED() { out << info->PDiskType; }
}
}
}
}
}
- }
-
- RenderFooter(out);
-}
-
-void TBlobStorageController::RenderGroupDetail(IOutputStream &out, TGroupId groupId) {
- RenderHeader(out);
- HTML(out) {
- H3() {
- out << "VDisks for group " << groupId;
- }
-
- if (TGroupInfo *group = FindGroup(groupId)) {
- RenderVSlotTable(out, [&] {
- for (const TVSlotInfo *slot : group->VDisksInGroup) {
- RenderVSlotRow(out, *slot);
- }
- });
- }
- }
- RenderFooter(out);
-}
-
-void TBlobStorageController::RenderGroupsInStoragePool(IOutputStream &out, const TBoxStoragePoolId& id) {
- RenderHeader(out);
- HTML(out) {
- H3() {
- TString name;
- if (const auto it = StoragePools.find(id); it != StoragePools.end()) {
- name = it->second.Name;
- }
- out << "Groups in storage pool " << name << " (" << std::get<0>(id) << ", " << std::get<1>(id) << ")";
- }
- RenderGroupTable(out, [&] {
- auto range = StoragePoolGroups.equal_range(id);
- for (auto it = range.first; it != range.second; ++it) {
- if (TGroupInfo *group = FindGroup(it->second)) {
- RenderGroupRow(out, *group);
- }
- }
- });
- }
- RenderFooter(out);
-}
-
-void TBlobStorageController::RenderVSlotTable(IOutputStream& out, std::function<void()> callback) {
- HTML(out) {
+ }
+
+ RenderFooter(out);
+}
+
+void TBlobStorageController::RenderGroupDetail(IOutputStream &out, TGroupId groupId) {
+ RenderHeader(out);
+ HTML(out) {
+ H3() {
+ out << "VDisks for group " << groupId;
+ }
+
+ if (TGroupInfo *group = FindGroup(groupId)) {
+ RenderVSlotTable(out, [&] {
+ for (const TVSlotInfo *slot : group->VDisksInGroup) {
+ RenderVSlotRow(out, *slot);
+ }
+ });
+ }
+ }
+ RenderFooter(out);
+}
+
+void TBlobStorageController::RenderGroupsInStoragePool(IOutputStream &out, const TBoxStoragePoolId& id) {
+ RenderHeader(out);
+ HTML(out) {
+ H3() {
+ TString name;
+ if (const auto it = StoragePools.find(id); it != StoragePools.end()) {
+ name = it->second.Name;
+ }
+ out << "Groups in storage pool " << name << " (" << std::get<0>(id) << ", " << std::get<1>(id) << ")";
+ }
+ RenderGroupTable(out, [&] {
+ auto range = StoragePoolGroups.equal_range(id);
+ for (auto it = range.first; it != range.second; ++it) {
+ if (TGroupInfo *group = FindGroup(it->second)) {
+ RenderGroupRow(out, *group);
+ }
+ }
+ });
+ }
+ RenderFooter(out);
+}
+
+void TBlobStorageController::RenderVSlotTable(IOutputStream& out, std::function<void()> callback) {
+ HTML(out) {
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TAG_ATTRS(TTableH, {{"colspan", "8"}}) { out << "VDisk attributes"; }
- TAG_ATTRS(TTableH, {{"colspan", "1"}}) { out << "Current"; }
- TAG_ATTRS(TTableH, {{"colspan", "1"}}) { out << "Maximum"; }
- }
- TABLER() {
- TAG_ATTRS(TTableH, {{"title", "ID:Gen:Ring:Domain:VDisk"}}) { out << "VDisk id"; }
- TABLEH() { out << "PDisk id"; }
- TABLEH() { out << "Kind"; }
- TABLEH() { out << "VSlot id"; }
- TABLEH() { out << "Allocated"; }
- TABLEH() { out << "Available"; }
- TABLEH() { out << "Status"; }
- TABLEH() { out << "IsReady"; }
- TABLEH() { out << "LastSeenReady"; }
+ TABLEHEAD() {
+ TABLER() {
+ TAG_ATTRS(TTableH, {{"colspan", "8"}}) { out << "VDisk attributes"; }
+ TAG_ATTRS(TTableH, {{"colspan", "1"}}) { out << "Current"; }
+ TAG_ATTRS(TTableH, {{"colspan", "1"}}) { out << "Maximum"; }
+ }
+ TABLER() {
+ TAG_ATTRS(TTableH, {{"title", "ID:Gen:Ring:Domain:VDisk"}}) { out << "VDisk id"; }
+ TABLEH() { out << "PDisk id"; }
+ TABLEH() { out << "Kind"; }
+ TABLEH() { out << "VSlot id"; }
+ TABLEH() { out << "Allocated"; }
+ TABLEH() { out << "Available"; }
+ TABLEH() { out << "Status"; }
+ TABLEH() { out << "IsReady"; }
+ TABLEH() { out << "LastSeenReady"; }
TABLEH() { out << "Data Size"; }
TABLEH() { out << "Data Size"; }
- }
- }
- TABLEBODY() {
- callback();
- }
- }
- }
-}
-
-void TBlobStorageController::RenderVSlotRow(IOutputStream& out, const TVSlotInfo& vslot) {
- HTML(out) {
- TAG_ATTRS(TTableR, {{"title", vslot.Metrics.DebugString()}}) {
- TABLED() {
- out << vslot.GetVDiskId();
- }
- TABLED() {
- out << vslot.VSlotId.ComprisingPDiskId();
- }
- TABLED() {
- out << vslot.Kind;
- }
- TABLED() {
- out << vslot.VSlotId;
- }
- RenderBytesCell(out, vslot.Metrics.GetAllocatedSize());
- RenderBytesCell(out, vslot.Metrics.GetAvailableSize());
- TABLED() { out << vslot.GetStatusString(); }
- TABLED() { out << (vslot.IsReady ? "YES" : ""); }
- TABLED() {
- if (vslot.LastSeenReady != TInstant::Zero()) {
- out << vslot.LastSeenReady;
- }
- }
- RenderResourceValues(out, vslot.GetResourceCurrentValues());
- RenderResourceValues(out, vslot.GetResourceMaximumValues());
- }
- }
-}
-
-void TBlobStorageController::RenderGroupTable(IOutputStream& out, std::function<void()> callback) {
- HTML(out) {
+ }
+ }
+ TABLEBODY() {
+ callback();
+ }
+ }
+ }
+}
+
+void TBlobStorageController::RenderVSlotRow(IOutputStream& out, const TVSlotInfo& vslot) {
+ HTML(out) {
+ TAG_ATTRS(TTableR, {{"title", vslot.Metrics.DebugString()}}) {
+ TABLED() {
+ out << vslot.GetVDiskId();
+ }
+ TABLED() {
+ out << vslot.VSlotId.ComprisingPDiskId();
+ }
+ TABLED() {
+ out << vslot.Kind;
+ }
+ TABLED() {
+ out << vslot.VSlotId;
+ }
+ RenderBytesCell(out, vslot.Metrics.GetAllocatedSize());
+ RenderBytesCell(out, vslot.Metrics.GetAvailableSize());
+ TABLED() { out << vslot.GetStatusString(); }
+ TABLED() { out << (vslot.IsReady ? "YES" : ""); }
+ TABLED() {
+ if (vslot.LastSeenReady != TInstant::Zero()) {
+ out << vslot.LastSeenReady;
+ }
+ }
+ RenderResourceValues(out, vslot.GetResourceCurrentValues());
+ RenderResourceValues(out, vslot.GetResourceMaximumValues());
+ }
+ }
+}
+
+void TBlobStorageController::RenderGroupTable(IOutputStream& out, std::function<void()> callback) {
+ HTML(out) {
TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TAG_ATTRS(TTableH, {{"title", "GroupId:Gen"}}) { out << "ID"; }
- TABLEH() { out << "Erasure species"; }
- TABLEH() { out << "Storage pool"; }
- TABLEH() { out << "Encryption mode"; }
- TABLEH() { out << "Life cycle phase"; }
- TABLEH() { out << "Allocated size"; }
- TABLEH() { out << "Available size"; }
+ TABLEHEAD() {
+ TABLER() {
+ TAG_ATTRS(TTableH, {{"title", "GroupId:Gen"}}) { out << "ID"; }
+ TABLEH() { out << "Erasure species"; }
+ TABLEH() { out << "Storage pool"; }
+ TABLEH() { out << "Encryption mode"; }
+ TABLEH() { out << "Life cycle phase"; }
+ TABLEH() { out << "Allocated size"; }
+ TABLEH() { out << "Available size"; }
TAG_ATTRS(TTableH, {{"title", "Data Size"}}) { out << "Data<br/>Size"; }
TAG_ATTRS(TTableH, {{"title", "PutTabletLog Latency"}}) { out << "PutTabletLog<br/>Latency"; }
TAG_ATTRS(TTableH, {{"title", "PutUserData Latency"}}) { out << "PutUserData<br/>Latency"; }
TAG_ATTRS(TTableH, {{"title", "GetFast Latency"}}) { out << "GetFast<br/>Latency"; }
- TABLEH() { out << "Seen operational"; }
- TABLEH() { out << "Operating<br/>status"; }
- TABLEH() { out << "Expected<br/>status"; }
- }
- }
- TABLEBODY() {
- callback();
- }
- }
- }
-}
-
-void TBlobStorageController::RenderGroupRow(IOutputStream& out, const TGroupInfo& group) {
- HTML(out) {
- ui64 allocatedSize = 0;
- ui64 availableSize = 0;
- ui32 satisfactionRank = 0;
- for (const TVSlotInfo *vslot : group.VDisksInGroup) {
- const auto& m = vslot->Metrics;
- allocatedSize += m.GetAllocatedSize();
- availableSize += m.GetAvailableSize();
- satisfactionRank = std::max(satisfactionRank, m.GetSatisfactionRank());
- }
-
- auto renderLatency = [&](const auto& perc) {
- TABLED() {
- if (perc) {
- out << perc->ToString();
- } else {
- out << "-";
- }
- }
- };
-
- TABLER() {
- TString storagePool = "<strong>none</strong>";
- if (auto it = StoragePools.find(group.StoragePoolId); it != StoragePools.end()) {
- storagePool = TStringBuilder() << "<a href='?TabletID=" << TabletID()
- << "&page=Groups&BoxId=" << std::get<0>(group.StoragePoolId)
- << "&StoragePoolId=" << std::get<1>(group.StoragePoolId)
- << "'>" << it->second.Name << "</a>";
- }
-
- TABLED() {
- out << "<a href='?TabletID=" << TabletID() << "&page=GroupDetail&GroupId=" << group.ID << "'>";
- out << group.ID;
- out << "</a>:" << group.Generation;
- }
-
- TABLED() { out << TBlobStorageGroupType::ErasureSpeciesName(group.ErasureSpecies); }
- TABLED() { out << storagePool; }
- TABLED() { out << group.EncryptionMode; }
- TABLED() { out << group.LifeCyclePhase; }
- RenderBytesCell(out, allocatedSize);
- RenderBytesCell(out, availableSize);
- RenderResourceValues(out, group.GetResourceCurrentValues());
- renderLatency(group.LatencyStats.PutTabletLog);
- renderLatency(group.LatencyStats.PutUserData);
- renderLatency(group.LatencyStats.GetFast);
- TABLED() { out << (group.SeenOperational ? "YES" : ""); }
-
- const auto& status = group.Status;
+ TABLEH() { out << "Seen operational"; }
+ TABLEH() { out << "Operating<br/>status"; }
+ TABLEH() { out << "Expected<br/>status"; }
+ }
+ }
+ TABLEBODY() {
+ callback();
+ }
+ }
+ }
+}
+
+void TBlobStorageController::RenderGroupRow(IOutputStream& out, const TGroupInfo& group) {
+ HTML(out) {
+ ui64 allocatedSize = 0;
+ ui64 availableSize = 0;
+ ui32 satisfactionRank = 0;
+ for (const TVSlotInfo *vslot : group.VDisksInGroup) {
+ const auto& m = vslot->Metrics;
+ allocatedSize += m.GetAllocatedSize();
+ availableSize += m.GetAvailableSize();
+ satisfactionRank = std::max(satisfactionRank, m.GetSatisfactionRank());
+ }
+
+ auto renderLatency = [&](const auto& perc) {
+ TABLED() {
+ if (perc) {
+ out << perc->ToString();
+ } else {
+ out << "-";
+ }
+ }
+ };
+
+ TABLER() {
+ TString storagePool = "<strong>none</strong>";
+ if (auto it = StoragePools.find(group.StoragePoolId); it != StoragePools.end()) {
+ storagePool = TStringBuilder() << "<a href='?TabletID=" << TabletID()
+ << "&page=Groups&BoxId=" << std::get<0>(group.StoragePoolId)
+ << "&StoragePoolId=" << std::get<1>(group.StoragePoolId)
+ << "'>" << it->second.Name << "</a>";
+ }
+
+ TABLED() {
+ out << "<a href='?TabletID=" << TabletID() << "&page=GroupDetail&GroupId=" << group.ID << "'>";
+ out << group.ID;
+ out << "</a>:" << group.Generation;
+ }
+
+ TABLED() { out << TBlobStorageGroupType::ErasureSpeciesName(group.ErasureSpecies); }
+ TABLED() { out << storagePool; }
+ TABLED() { out << group.EncryptionMode; }
+ TABLED() { out << group.LifeCyclePhase; }
+ RenderBytesCell(out, allocatedSize);
+ RenderBytesCell(out, availableSize);
+ RenderResourceValues(out, group.GetResourceCurrentValues());
+ renderLatency(group.LatencyStats.PutTabletLog);
+ renderLatency(group.LatencyStats.PutUserData);
+ renderLatency(group.LatencyStats.GetFast);
+ TABLED() { out << (group.SeenOperational ? "YES" : ""); }
+
+ const auto& status = group.Status;
TABLED() { out << NKikimrBlobStorage::TGroupStatus::E_Name(status.OperatingStatus); }
TABLED() { out << NKikimrBlobStorage::TGroupStatus::E_Name(status.ExpectedStatus); }
}
}
-}
-
-} // NBlobStorageController
-} // NKikimr
+}
+
+} // NBlobStorageController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/mood.h b/ydb/core/mind/bscontroller/mood.h
index 9e2452f78c6..60abbc3d343 100644
--- a/ydb/core/mind/bscontroller/mood.h
+++ b/ydb/core/mind/bscontroller/mood.h
@@ -1,16 +1,16 @@
-#pragma once
-#include "defs.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-struct TMood {
- enum EValue {
- Normal = 0,
- Wipe = 1,
- Delete = 2,
- Donor = 3,
- };
+#pragma once
+#include "defs.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+struct TMood {
+ enum EValue {
+ Normal = 0,
+ Wipe = 1,
+ Delete = 2,
+ Donor = 3,
+ };
static TString Name(const EValue value) {
switch (value) {
@@ -18,14 +18,14 @@ struct TMood {
return "Normal";
case Wipe:
return "Wipe";
- case Delete:
- return "Delete";
- case Donor:
- return "Donor";
+ case Delete:
+ return "Delete";
+ case Donor:
+ return "Donor";
}
return Sprintf("Unknown%" PRIu64, (ui64)value);
}
-};
-
-} // NBsController
-} // NKikimr
+};
+
+} // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/mv_object_map.h b/ydb/core/mind/bscontroller/mv_object_map.h
index 251c8709ed3..a4ec331439e 100644
--- a/ydb/core/mind/bscontroller/mv_object_map.h
+++ b/ydb/core/mind/bscontroller/mv_object_map.h
@@ -1,310 +1,310 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NBsController {
-
- template<typename TKey, typename TValue>
- class TMultiversionObjectMap {
- // a single item containing version and object pair; object may be marked as deleted if there is nullopt in the
- // value; there may be no two consequent deletion marks; also there could be no starting deletion mark -- it
- // should be deleted (starting item for a key is its committed value and deletion mark can't be committed)
- struct TItem {
- ui64 Version;
- std::optional<TValue> Value; // deleted if nullopt
-
- template<typename... TArgs>
- TItem(ui64 version, TArgs&&... args)
- : Version(version)
- , Value(std::forward<TArgs>(args)...)
- {}
-
- const TValue& operator *() const {
- return *Value;
- }
-
- operator const TValue *() const {
- return Value ? &Value.value() : nullptr;
- }
-
- operator TValue *() {
- return Value ? &Value.value() : nullptr;
- }
-
- operator bool() const {
- return Value;
- }
-
- template<typename... TArgs>
- void Construct(TArgs&&... args) {
- Y_VERIFY_DEBUG(!Value);
- Value.emplace(std::forward<TArgs>(args)...);
- }
-
- void Destruct() {
- Y_VERIFY_DEBUG(Value);
- Value.reset();
- }
- };
-
- // a map of items; for a single key there is a sorted history of versions in ascending order contaning different
- // object values or deletion marks
- using TItems = std::multimap<TKey, TItem>;
- std::multimap<TKey, TItem> Items;
-
- // per-version information structure
- struct TPerVersionInfo {
- struct TComp {
- bool operator ()(const typename TItems::iterator& x, const typename TItems::iterator& y) const {
- return &*x < &*y;
- }
- };
- std::set<typename TItems::iterator, TComp> Touched; // a set of touched items; every item must have matching version
- };
-
- // per-version map
- std::map<ui64, TPerVersionInfo> PerVersionInfo;
-
- // current transaction version
- ui64 CurrentVersion = 0;
-
- // last committed version
- ui64 CommittedVersion = 0;
-
- public:
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TRANSACTIONS
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // start new transaction -- within this transaction any changes may be made
- void BeginTx(ui64 version) {
- Y_VERIFY_DEBUG(!CurrentVersion);
- Y_VERIFY_DEBUG(version);
- CurrentVersion = version;
- Y_VERIFY_DEBUG(PerVersionInfo.empty() || PerVersionInfo.rbegin()->first < version);
- PerVersionInfo.emplace_hint(PerVersionInfo.end(), version, TPerVersionInfo());
- }
-
- // finish transaction -- it is not yet committed, but no more changes are made after this point
- void FinishTx() {
- Y_VERIFY_DEBUG(CurrentVersion != 0);
- Y_VERIFY_DEBUG(!PerVersionInfo.empty() && std::prev(PerVersionInfo.end())->first == CurrentVersion);
- CurrentVersion = 0;
- }
-
- // commit version in front of transaction queue
- void Commit(ui64 version) {
- const auto pvIter = PerVersionInfo.begin();
- Y_VERIFY_DEBUG(pvIter != PerVersionInfo.end() && pvIter->first == version);
- // the main logic of commit is to remove obsolete versions of items to ensure at most one item with Version
- // <= CommittedVersion exists
- for (typename TItems::iterator it : pvIter->second.Touched) {
- // ensure the correctness of item's version
- Y_VERIFY_DEBUG(it->second.Version == version);
-
- // this item was either newly added in this version, deleted, or replaced; let's figure out what happened
- if (const auto pred = Predecessor(it); pred != Items.end()) {
- // item has a predecessor, so it may be either added or replaced; predecessor must have correct version
- // and value in either way
- Y_VERIFY_DEBUG(pred->second.Version < version); // check version ordering
- Y_VERIFY_DEBUG(pred->second); // check that predecessor has value
- Items.erase(pred); // terminate the predecessor as we don't need it anymore
- Y_VERIFY_DEBUG(Predecessor(it) == Items.end()); // ensure that there are no more predecessors
- if (!it->second) {
- Items.erase(it); // item was deleted itself in this version, so we delete it from the map
- }
- } else {
- // item does not have a predecessor, so it means that it is newly added, so it must have a value
- Y_VERIFY_DEBUG(it->second);
- }
- }
- PerVersionInfo.erase(pvIter);
- // update last committed version
- CommittedVersion = version;
- }
-
- // drop version in back of transaction queue
- void Drop(ui64 version) {
- Y_VERIFY_DEBUG(!PerVersionInfo.empty());
- const auto pvIter = std::prev(PerVersionInfo.end());
- Y_VERIFY_DEBUG(pvIter->first == version);
- // the logic of drop is to delete all entries with the specified version; actually it is simple delete
- // touched items from the map
- for (const typename TItems::iterator it : pvIter->second.Touched) {
- Y_VERIFY_DEBUG(it->second.Version == version);
- Items.erase(it);
- }
- PerVersionInfo.erase(pvIter);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // READ-ONLY CODE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const TValue *FindCommitted(const TKey& key) {
- // find the item with the least version and ensure it is committed
- const auto it = Items.lower_bound(key);
- return it != Items.end() && it->first == key && it->second.Version <= CommittedVersion ? static_cast<const TValue*>(it->second) : nullptr;
- }
-
- const TValue *FindLatest(const TKey& key) {
- Y_VERIFY_DEBUG(CurrentVersion);
- // find the item with the most version for this key; should be called only from inside the transaction code
- auto it = Items.upper_bound(key);
- if (it != Items.begin()) {
- --it;
- }
- return it != Items.end() && it->first == key ? static_cast<const TValue*>(it->second) : nullptr;
- }
-
- template<typename T>
- void ScanRangeCommitted(T&& callback, const std::optional<TKey>& min = std::nullopt,
- const std::optional<TKey>& max = std::nullopt) {
- auto it = min ? Items.lower_bound(*min) : Items.begin();
- while (it != Items.end() && (!max || it->first <= *max)) {
- const TKey& key = it->first;
- if (it->second.Version <= CommittedVersion) {
- Y_VERIFY_DEBUG(it->second);
- if (!callback(key, *it->second)) {
- break;
- }
- }
- while (it != Items.end() && it->first == key) {
- ++it;
- }
- }
- }
-
- template<typename T>
- void ScanRangeLatest(T&& callback, const std::optional<TKey>& min = std::nullopt,
- const std::optional<TKey>& max = std::nullopt) {
- Y_VERIFY_DEBUG(CurrentVersion);
- for (auto it = min ? Items.lower_bound(*min) : Items.begin(); it != Items.end() && (!max || it->first <= *max); ++it) {
- const TKey& key = it->first;
-
- // find the latest version of this key
- while (it != Items.end() && it->first == key) {
- ++it;
- }
- --it;
-
- // check if the item has value
- if (it->second) {
- auto getMutPtr = [&] {
- if (it->second.Version != CurrentVersion) {
- Y_VERIFY_DEBUG(it->second.Version < CurrentVersion);
- const TValue *value = it->second;
- Y_VERIFY_DEBUG(value);
- it = Items.emplace_hint(std::next(it), CurrentVersion, *value);
- MarkTouched(it);
- }
- return static_cast<TValue*>(it->second);
- };
- if (!callback(key, *it->second, getMutPtr)) {
- break;
- }
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // UPDATE CODE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<typename... TArgs>
- TValue *CreateNewEntry(TKey key, TArgs&&... args) {
- Y_VERIFY_DEBUG(CurrentVersion);
- // here we have to possible cases:
- // 1. this is the new entry for this version, so we just place it into the map and update touched keys
- // 2. this is re-creation of alreay deleted item inside this version, so we just have to construct item again
- const auto upperIt = Items.upper_bound(key);
- auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
- if (it != Items.end() && it->first == key && it->second.Version == CurrentVersion) {
- // the second case -- entry already exists and was deleted; if it wasn't deleted, the program will fail
- it->second.Construct(std::forward<TArgs>(args)...);
- } else {
- // item wasn't inserted for this version before, so we construct new entry
- it = Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(std::move(key)),
- std::forward_as_tuple(CurrentVersion, std::in_place, std::forward<TArgs>(args)...));
- // and mark it touched
- MarkTouched(it);
- }
- return it->second;
- }
-
- void DeleteExistingEntry(const TKey& key) {
- Y_VERIFY_DEBUG(CurrentVersion);
- // we also have two possible cases as with insertion:
- // 1. item was inserted in previous version (and it must exist, so last value must be non-nullopt)
- // 2. item was constructed in this version and is going to be deleted
- const auto upperIt = Items.upper_bound(key);
- const auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
- if (it != Items.end() && it->first == key && it->second.Version == CurrentVersion) {
- // the item being deleted may have a predecessor, which may have or may have no value; in first case,
- // it means that in current version item was first replaced, but then got erased, and we have to put
- // deletion mark; in second case, it means item was first created, but then erased, and we can delete
- // this item completely
- if (const auto pred = Predecessor(it); pred != Items.end() && pred->second) {
- // item was first replaced/re-created, and then got deleted
- it->second.Destruct();
- } else {
- // item was created and then destroyed
- MarkUntouched(it);
- Items.erase(it);
- }
- } else {
- // the first case, create new entry and mark it touched
- MarkTouched(Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(key),
- std::forward_as_tuple(CurrentVersion, std::nullopt)));
- }
- }
-
- TValue *FindForUpdate(const TKey& key) {
- Y_VERIFY_DEBUG(CurrentVersion);
- // the code is same as before, but with some minor differences
- const auto upperIt = Items.upper_bound(key);
- auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
- if (it == Items.end() || it->first != key) {
- // here we found that there is no item by such key, so we simply return null
- return nullptr;
- }
- if (it->second.Version != CurrentVersion) {
- Y_VERIFY_DEBUG(it->second.Version < CurrentVersion);
- // here we found something from previous version; this may be an item, but can be a deletion marker
- if (!it->second) {
- return nullptr; // item was deleted, so in this version we have no item at all by this key
- }
- // item was not deleted, we have to clone it in current version
- const TValue *value = it->second;
- Y_VERIFY_DEBUG(value);
- it = Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(key),
- std::forward_as_tuple(CurrentVersion, *value));
- MarkTouched(it);
- }
- return it->second;
- }
-
- private:
- void MarkTouched(typename TItems::iterator it) {
- Y_VERIFY_DEBUG(!PerVersionInfo.empty());
- const auto pvIter = std::prev(PerVersionInfo.end());
- Y_VERIFY_DEBUG(pvIter->first == CurrentVersion);
- const bool inserted = pvIter->second.Touched.insert(it).second;
- Y_VERIFY_DEBUG(inserted);
- }
-
- void MarkUntouched(typename TItems::iterator it) {
- Y_VERIFY_DEBUG(!PerVersionInfo.empty());
- const auto pvIter = std::prev(PerVersionInfo.end());
- Y_VERIFY_DEBUG(pvIter->first == CurrentVersion);
- const ui32 erased = pvIter->second.Touched.erase(it);
- Y_VERIFY_DEBUG(erased);
- }
-
- typename TItems::iterator Predecessor(const typename TItems::iterator& it) {
- const auto prevIt = it != Items.begin() ? std::prev(it) : Items.end();
- return prevIt != Items.end() && prevIt->first == it->first ? prevIt : Items.end();
- }
- };
-
-} // NKikimr::NBsController
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NBsController {
+
+ template<typename TKey, typename TValue>
+ class TMultiversionObjectMap {
+ // a single item containing version and object pair; object may be marked as deleted if there is nullopt in the
+ // value; there may be no two consequent deletion marks; also there could be no starting deletion mark -- it
+ // should be deleted (starting item for a key is its committed value and deletion mark can't be committed)
+ struct TItem {
+ ui64 Version;
+ std::optional<TValue> Value; // deleted if nullopt
+
+ template<typename... TArgs>
+ TItem(ui64 version, TArgs&&... args)
+ : Version(version)
+ , Value(std::forward<TArgs>(args)...)
+ {}
+
+ const TValue& operator *() const {
+ return *Value;
+ }
+
+ operator const TValue *() const {
+ return Value ? &Value.value() : nullptr;
+ }
+
+ operator TValue *() {
+ return Value ? &Value.value() : nullptr;
+ }
+
+ operator bool() const {
+ return Value;
+ }
+
+ template<typename... TArgs>
+ void Construct(TArgs&&... args) {
+ Y_VERIFY_DEBUG(!Value);
+ Value.emplace(std::forward<TArgs>(args)...);
+ }
+
+ void Destruct() {
+ Y_VERIFY_DEBUG(Value);
+ Value.reset();
+ }
+ };
+
+ // a map of items; for a single key there is a sorted history of versions in ascending order contaning different
+ // object values or deletion marks
+ using TItems = std::multimap<TKey, TItem>;
+ std::multimap<TKey, TItem> Items;
+
+ // per-version information structure
+ struct TPerVersionInfo {
+ struct TComp {
+ bool operator ()(const typename TItems::iterator& x, const typename TItems::iterator& y) const {
+ return &*x < &*y;
+ }
+ };
+ std::set<typename TItems::iterator, TComp> Touched; // a set of touched items; every item must have matching version
+ };
+
+ // per-version map
+ std::map<ui64, TPerVersionInfo> PerVersionInfo;
+
+ // current transaction version
+ ui64 CurrentVersion = 0;
+
+ // last committed version
+ ui64 CommittedVersion = 0;
+
+ public:
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TRANSACTIONS
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // start new transaction -- within this transaction any changes may be made
+ void BeginTx(ui64 version) {
+ Y_VERIFY_DEBUG(!CurrentVersion);
+ Y_VERIFY_DEBUG(version);
+ CurrentVersion = version;
+ Y_VERIFY_DEBUG(PerVersionInfo.empty() || PerVersionInfo.rbegin()->first < version);
+ PerVersionInfo.emplace_hint(PerVersionInfo.end(), version, TPerVersionInfo());
+ }
+
+ // finish transaction -- it is not yet committed, but no more changes are made after this point
+ void FinishTx() {
+ Y_VERIFY_DEBUG(CurrentVersion != 0);
+ Y_VERIFY_DEBUG(!PerVersionInfo.empty() && std::prev(PerVersionInfo.end())->first == CurrentVersion);
+ CurrentVersion = 0;
+ }
+
+ // commit version in front of transaction queue
+ void Commit(ui64 version) {
+ const auto pvIter = PerVersionInfo.begin();
+ Y_VERIFY_DEBUG(pvIter != PerVersionInfo.end() && pvIter->first == version);
+ // the main logic of commit is to remove obsolete versions of items to ensure at most one item with Version
+ // <= CommittedVersion exists
+ for (typename TItems::iterator it : pvIter->second.Touched) {
+ // ensure the correctness of item's version
+ Y_VERIFY_DEBUG(it->second.Version == version);
+
+ // this item was either newly added in this version, deleted, or replaced; let's figure out what happened
+ if (const auto pred = Predecessor(it); pred != Items.end()) {
+ // item has a predecessor, so it may be either added or replaced; predecessor must have correct version
+ // and value in either way
+ Y_VERIFY_DEBUG(pred->second.Version < version); // check version ordering
+ Y_VERIFY_DEBUG(pred->second); // check that predecessor has value
+ Items.erase(pred); // terminate the predecessor as we don't need it anymore
+ Y_VERIFY_DEBUG(Predecessor(it) == Items.end()); // ensure that there are no more predecessors
+ if (!it->second) {
+ Items.erase(it); // item was deleted itself in this version, so we delete it from the map
+ }
+ } else {
+ // item does not have a predecessor, so it means that it is newly added, so it must have a value
+ Y_VERIFY_DEBUG(it->second);
+ }
+ }
+ PerVersionInfo.erase(pvIter);
+ // update last committed version
+ CommittedVersion = version;
+ }
+
+ // drop version in back of transaction queue
+ void Drop(ui64 version) {
+ Y_VERIFY_DEBUG(!PerVersionInfo.empty());
+ const auto pvIter = std::prev(PerVersionInfo.end());
+ Y_VERIFY_DEBUG(pvIter->first == version);
+ // the logic of drop is to delete all entries with the specified version; actually it is simple delete
+ // touched items from the map
+ for (const typename TItems::iterator it : pvIter->second.Touched) {
+ Y_VERIFY_DEBUG(it->second.Version == version);
+ Items.erase(it);
+ }
+ PerVersionInfo.erase(pvIter);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // READ-ONLY CODE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ const TValue *FindCommitted(const TKey& key) {
+ // find the item with the least version and ensure it is committed
+ const auto it = Items.lower_bound(key);
+ return it != Items.end() && it->first == key && it->second.Version <= CommittedVersion ? static_cast<const TValue*>(it->second) : nullptr;
+ }
+
+ const TValue *FindLatest(const TKey& key) {
+ Y_VERIFY_DEBUG(CurrentVersion);
+ // find the item with the most version for this key; should be called only from inside the transaction code
+ auto it = Items.upper_bound(key);
+ if (it != Items.begin()) {
+ --it;
+ }
+ return it != Items.end() && it->first == key ? static_cast<const TValue*>(it->second) : nullptr;
+ }
+
+ template<typename T>
+ void ScanRangeCommitted(T&& callback, const std::optional<TKey>& min = std::nullopt,
+ const std::optional<TKey>& max = std::nullopt) {
+ auto it = min ? Items.lower_bound(*min) : Items.begin();
+ while (it != Items.end() && (!max || it->first <= *max)) {
+ const TKey& key = it->first;
+ if (it->second.Version <= CommittedVersion) {
+ Y_VERIFY_DEBUG(it->second);
+ if (!callback(key, *it->second)) {
+ break;
+ }
+ }
+ while (it != Items.end() && it->first == key) {
+ ++it;
+ }
+ }
+ }
+
+ template<typename T>
+ void ScanRangeLatest(T&& callback, const std::optional<TKey>& min = std::nullopt,
+ const std::optional<TKey>& max = std::nullopt) {
+ Y_VERIFY_DEBUG(CurrentVersion);
+ for (auto it = min ? Items.lower_bound(*min) : Items.begin(); it != Items.end() && (!max || it->first <= *max); ++it) {
+ const TKey& key = it->first;
+
+ // find the latest version of this key
+ while (it != Items.end() && it->first == key) {
+ ++it;
+ }
+ --it;
+
+ // check if the item has value
+ if (it->second) {
+ auto getMutPtr = [&] {
+ if (it->second.Version != CurrentVersion) {
+ Y_VERIFY_DEBUG(it->second.Version < CurrentVersion);
+ const TValue *value = it->second;
+ Y_VERIFY_DEBUG(value);
+ it = Items.emplace_hint(std::next(it), CurrentVersion, *value);
+ MarkTouched(it);
+ }
+ return static_cast<TValue*>(it->second);
+ };
+ if (!callback(key, *it->second, getMutPtr)) {
+ break;
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // UPDATE CODE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<typename... TArgs>
+ TValue *CreateNewEntry(TKey key, TArgs&&... args) {
+ Y_VERIFY_DEBUG(CurrentVersion);
+ // here we have to possible cases:
+ // 1. this is the new entry for this version, so we just place it into the map and update touched keys
+ // 2. this is re-creation of alreay deleted item inside this version, so we just have to construct item again
+ const auto upperIt = Items.upper_bound(key);
+ auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
+ if (it != Items.end() && it->first == key && it->second.Version == CurrentVersion) {
+ // the second case -- entry already exists and was deleted; if it wasn't deleted, the program will fail
+ it->second.Construct(std::forward<TArgs>(args)...);
+ } else {
+ // item wasn't inserted for this version before, so we construct new entry
+ it = Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(std::move(key)),
+ std::forward_as_tuple(CurrentVersion, std::in_place, std::forward<TArgs>(args)...));
+ // and mark it touched
+ MarkTouched(it);
+ }
+ return it->second;
+ }
+
+ void DeleteExistingEntry(const TKey& key) {
+ Y_VERIFY_DEBUG(CurrentVersion);
+ // we also have two possible cases as with insertion:
+ // 1. item was inserted in previous version (and it must exist, so last value must be non-nullopt)
+ // 2. item was constructed in this version and is going to be deleted
+ const auto upperIt = Items.upper_bound(key);
+ const auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
+ if (it != Items.end() && it->first == key && it->second.Version == CurrentVersion) {
+ // the item being deleted may have a predecessor, which may have or may have no value; in first case,
+ // it means that in current version item was first replaced, but then got erased, and we have to put
+ // deletion mark; in second case, it means item was first created, but then erased, and we can delete
+ // this item completely
+ if (const auto pred = Predecessor(it); pred != Items.end() && pred->second) {
+ // item was first replaced/re-created, and then got deleted
+ it->second.Destruct();
+ } else {
+ // item was created and then destroyed
+ MarkUntouched(it);
+ Items.erase(it);
+ }
+ } else {
+ // the first case, create new entry and mark it touched
+ MarkTouched(Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(CurrentVersion, std::nullopt)));
+ }
+ }
+
+ TValue *FindForUpdate(const TKey& key) {
+ Y_VERIFY_DEBUG(CurrentVersion);
+ // the code is same as before, but with some minor differences
+ const auto upperIt = Items.upper_bound(key);
+ auto it = upperIt != Items.begin() ? std::prev(upperIt) : Items.end();
+ if (it == Items.end() || it->first != key) {
+ // here we found that there is no item by such key, so we simply return null
+ return nullptr;
+ }
+ if (it->second.Version != CurrentVersion) {
+ Y_VERIFY_DEBUG(it->second.Version < CurrentVersion);
+ // here we found something from previous version; this may be an item, but can be a deletion marker
+ if (!it->second) {
+ return nullptr; // item was deleted, so in this version we have no item at all by this key
+ }
+ // item was not deleted, we have to clone it in current version
+ const TValue *value = it->second;
+ Y_VERIFY_DEBUG(value);
+ it = Items.emplace_hint(upperIt, std::piecewise_construct, std::forward_as_tuple(key),
+ std::forward_as_tuple(CurrentVersion, *value));
+ MarkTouched(it);
+ }
+ return it->second;
+ }
+
+ private:
+ void MarkTouched(typename TItems::iterator it) {
+ Y_VERIFY_DEBUG(!PerVersionInfo.empty());
+ const auto pvIter = std::prev(PerVersionInfo.end());
+ Y_VERIFY_DEBUG(pvIter->first == CurrentVersion);
+ const bool inserted = pvIter->second.Touched.insert(it).second;
+ Y_VERIFY_DEBUG(inserted);
+ }
+
+ void MarkUntouched(typename TItems::iterator it) {
+ Y_VERIFY_DEBUG(!PerVersionInfo.empty());
+ const auto pvIter = std::prev(PerVersionInfo.end());
+ Y_VERIFY_DEBUG(pvIter->first == CurrentVersion);
+ const ui32 erased = pvIter->second.Touched.erase(it);
+ Y_VERIFY_DEBUG(erased);
+ }
+
+ typename TItems::iterator Predecessor(const typename TItems::iterator& it) {
+ const auto prevIt = it != Items.begin() ? std::prev(it) : Items.end();
+ return prevIt != Items.end() && prevIt->first == it->first ? prevIt : Items.end();
+ }
+ };
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/mv_object_map_ut.cpp b/ydb/core/mind/bscontroller/mv_object_map_ut.cpp
index 2d80013a1fc..f79ee167bf2 100644
--- a/ydb/core/mind/bscontroller/mv_object_map_ut.cpp
+++ b/ydb/core/mind/bscontroller/mv_object_map_ut.cpp
@@ -1,119 +1,119 @@
#include <library/cpp/testing/unittest/registar.h>
-
+
#include "mv_object_map.h"
#include "ut_helpers.h"
-using namespace NKikimr::NBsController;
-
-Y_UNIT_TEST_SUITE(TMultiversionObjectMap) {
-
- Y_UNIT_TEST(MonteCarlo) {
- using TMap = std::unordered_map<ui32, ui32>;
- using TVersionedMap = std::map<ui64, TMap>;
- TVersionedMap vm;
- TMultiversionObjectMap<ui32, ui32> test;
-
- for (ui64 version = 1; version < 100; ++version) {
- TMap prev;
- if (vm.size()) {
- prev = std::prev(vm.end())->second;
- }
- TMap& m = vm[version];
- m = prev;
- test.BeginTx(version);
-
+using namespace NKikimr::NBsController;
+
+Y_UNIT_TEST_SUITE(TMultiversionObjectMap) {
+
+ Y_UNIT_TEST(MonteCarlo) {
+ using TMap = std::unordered_map<ui32, ui32>;
+ using TVersionedMap = std::map<ui64, TMap>;
+ TVersionedMap vm;
+ TMultiversionObjectMap<ui32, ui32> test;
+
+ for (ui64 version = 1; version < 100; ++version) {
+ TMap prev;
+ if (vm.size()) {
+ prev = std::prev(vm.end())->second;
+ }
+ TMap& m = vm[version];
+ m = prev;
+ test.BeginTx(version);
+
Ctest << "begin version " << version << Endl;
-
- for (size_t iter = 0; iter < 100; ++iter) {
- ui32 key = RandomNumber<ui32>(1000);
- ui32 value = RandomNumber<ui32>();
+
+ for (size_t iter = 0; iter < 100; ++iter) {
+ ui32 key = RandomNumber<ui32>(1000);
+ ui32 value = RandomNumber<ui32>();
// Ctest << key << " -> " << value << Endl;
- m[key] = value;
- if (ui32 *p = test.FindForUpdate(key)) {
- *p = value;
- } else {
- test.CreateNewEntry(key, value);
- }
- }
-
- for (size_t iter = 0; iter < 10000; ++iter) {
- if (m.size() >= 50 && RandomNumber(2u) == 0) {
- auto it = m.begin();
- std::advance(it, RandomNumber(m.size()));
+ m[key] = value;
+ if (ui32 *p = test.FindForUpdate(key)) {
+ *p = value;
+ } else {
+ test.CreateNewEntry(key, value);
+ }
+ }
+
+ for (size_t iter = 0; iter < 10000; ++iter) {
+ if (m.size() >= 50 && RandomNumber(2u) == 0) {
+ auto it = m.begin();
+ std::advance(it, RandomNumber(m.size()));
// Ctest << "delete " << it->first << Endl;
- test.DeleteExistingEntry(it->first);
- m.erase(it);
- } else if (!m.size() || RandomNumber(2u) == 0) {
- // create new entry
- for (;;) {
- ui32 key = RandomNumber<ui32>(1000);
- if (!m.count(key)) {
- ui32 value = RandomNumber<ui32>();
- m.emplace(key, value);
- test.CreateNewEntry(key, value);
+ test.DeleteExistingEntry(it->first);
+ m.erase(it);
+ } else if (!m.size() || RandomNumber(2u) == 0) {
+ // create new entry
+ for (;;) {
+ ui32 key = RandomNumber<ui32>(1000);
+ if (!m.count(key)) {
+ ui32 value = RandomNumber<ui32>();
+ m.emplace(key, value);
+ test.CreateNewEntry(key, value);
// Ctest << "new " << key << " -> " << value << Endl;
- break;
- }
- }
- } else if (RandomNumber(2u) == 0) {
- // modify existing entry
- auto it = m.begin();
- std::advance(it, RandomNumber(m.size()));
- const auto *readp = test.FindLatest(it->first);
- UNIT_ASSERT(readp);
- UNIT_ASSERT_VALUES_EQUAL(*readp, it->second);
- const ui32 value = RandomNumber<ui32>();
+ break;
+ }
+ }
+ } else if (RandomNumber(2u) == 0) {
+ // modify existing entry
+ auto it = m.begin();
+ std::advance(it, RandomNumber(m.size()));
+ const auto *readp = test.FindLatest(it->first);
+ UNIT_ASSERT(readp);
+ UNIT_ASSERT_VALUES_EQUAL(*readp, it->second);
+ const ui32 value = RandomNumber<ui32>();
// Ctest << "modify " << it->first << " -> " << value << Endl;
- auto *p = test.FindForUpdate(it->first);
- UNIT_ASSERT(p);
- UNIT_ASSERT_VALUES_EQUAL(*p, it->second);
- it->second = *p = value;
- } else {
- // do scan
- TMap x = m;
- test.ScanRangeLatest([&](ui32 key, ui32 value, auto) {
- UNIT_ASSERT(x.count(key));
- UNIT_ASSERT_VALUES_EQUAL(value, x[key]);
- x.erase(key);
- return true;
- });
- UNIT_ASSERT(x.empty());
- }
- }
-
- test.FinishTx();
-
- if (version % 2 == 0) {
+ auto *p = test.FindForUpdate(it->first);
+ UNIT_ASSERT(p);
+ UNIT_ASSERT_VALUES_EQUAL(*p, it->second);
+ it->second = *p = value;
+ } else {
+ // do scan
+ TMap x = m;
+ test.ScanRangeLatest([&](ui32 key, ui32 value, auto) {
+ UNIT_ASSERT(x.count(key));
+ UNIT_ASSERT_VALUES_EQUAL(value, x[key]);
+ x.erase(key);
+ return true;
+ });
+ UNIT_ASSERT(x.empty());
+ }
+ }
+
+ test.FinishTx();
+
+ if (version % 2 == 0) {
Ctest << "drop version " << version << Endl;
- test.Drop(version);
- vm.erase(version);
- }
-
- if (vm.size() >= 3 && RandomNumber(2u) == 0) {
- auto it = vm.begin();
- ui32 version = it->first;
+ test.Drop(version);
+ vm.erase(version);
+ }
+
+ if (vm.size() >= 3 && RandomNumber(2u) == 0) {
+ auto it = vm.begin();
+ ui32 version = it->first;
Ctest << "commit version " << version << Endl;
- test.Commit(version);
- TMap& x = it->second;
- for (ui32 key = 0; key < 1000; ++key) {
- const ui32 *p = test.FindCommitted(key);
- if (x.count(key)) {
- UNIT_ASSERT(p);
- UNIT_ASSERT_VALUES_EQUAL(*p, x[key]);
- } else {
- UNIT_ASSERT(!p);
- }
- }
- test.ScanRangeCommitted([&](ui32 key, ui32 value) {
- UNIT_ASSERT(x.count(key));
- UNIT_ASSERT_VALUES_EQUAL(value, x[key]);
- x.erase(key);
- return true;
- });
- UNIT_ASSERT(x.empty());
- vm.erase(it);
- }
- }
- }
-
-}
+ test.Commit(version);
+ TMap& x = it->second;
+ for (ui32 key = 0; key < 1000; ++key) {
+ const ui32 *p = test.FindCommitted(key);
+ if (x.count(key)) {
+ UNIT_ASSERT(p);
+ UNIT_ASSERT_VALUES_EQUAL(*p, x[key]);
+ } else {
+ UNIT_ASSERT(!p);
+ }
+ }
+ test.ScanRangeCommitted([&](ui32 key, ui32 value) {
+ UNIT_ASSERT(x.count(key));
+ UNIT_ASSERT_VALUES_EQUAL(value, x[key]);
+ x.erase(key);
+ return true;
+ });
+ UNIT_ASSERT(x.empty());
+ vm.erase(it);
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/mind/bscontroller/node_report.cpp b/ydb/core/mind/bscontroller/node_report.cpp
index 1cd3fa5a2ce..a31cd0fb7a3 100644
--- a/ydb/core/mind/bscontroller/node_report.cpp
+++ b/ydb/core/mind/bscontroller/node_report.cpp
@@ -1,115 +1,115 @@
-#include "impl.h"
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxNodeReport
- : public TTransactionBase<TBlobStorageController>
-{
- TEvBlobStorage::TEvControllerNodeReport::TPtr Event;
- std::optional<TConfigState> State;
-
-public:
- TTxNodeReport(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev, TBlobStorageController *controller)
- : TBase(controller)
- , Event(ev)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_NODE_REPORT; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_NODE_REPORT_USEC);
-
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXNR01, "TTxNodeReport execute");
-
- State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
- State->CheckConsistency();
-
- std::vector<TVSlotId> droppedDonorVSlotIds;
-
- NIceDb::TNiceDb db(txc.DB);
- const auto& record = Event->Get()->Record;
-
- if (!record.HasNodeId()) {
- return true;
- }
- for (const auto& report : record.GetVDiskReports()) {
- if (!report.HasVSlotId() || !report.HasVDiskId() || !report.HasPhase()) {
- continue; // ignore incorrect report
- }
-
- TVSlotInfo *slot = State->VSlots.FindForUpdate(report.GetVSlotId());
- if (!slot || !slot->IsSameVDisk(VDiskIDFromVDiskID(report.GetVDiskId()))) {
- continue; // ignore entry -- possibly race/obsolete reply
- }
-
- switch (report.GetPhase()) {
- case NKikimrBlobStorage::TEvControllerNodeReport::UNKNOWN:
- continue; // ignore incorrect report
-
- case NKikimrBlobStorage::TEvControllerNodeReport::WIPED:
- if (slot->Mood == TMood::Wipe) {
- slot->Mood = TMood::Normal;
- }
- break;
-
- case NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED:
- if (slot->IsBeingDeleted()) {
- const size_t num = const_cast<TPDiskInfo&>(*slot->PDisk).VSlotsOnPDisk.erase(slot->VSlotId.VSlotId);
- Y_VERIFY(num);
- State->VSlots.DeleteExistingEntry(slot->VSlotId);
- }
- break;
-
- case NKikimrBlobStorage::TEvControllerNodeReport::OPERATION_ERROR:
- switch (slot->Mood) { // TODO(alexvru): implement some retry logic?
- case TMood::Normal:
- break;
- case TMood::Wipe:
- break;
- case TMood::Delete:
- break;
- case TMood::Donor:
- break;
- }
- break;
-
- case NKikimrBlobStorage::TEvControllerNodeReport::DROP_DONOR:
- for (const auto& [donorVSlotId, donorVDiskId] : slot->Donors) {
- if (donorVDiskId == VDiskIDFromVDiskID(report.GetOtherVDiskId())) {
- if (const TVSlotInfo *vslot = State->VSlots.Find(donorVSlotId); vslot && !vslot->IsBeingDeleted()) {
- Y_VERIFY(vslot->Mood == TMood::Donor);
- State->DestroyVSlot(vslot->VSlotId);
- }
- break;
- }
- }
- break;
- }
- }
-
- State->CheckConsistency();
- TString error;
- if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
- State->Rollback();
- State.reset();
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXNR02, "TTxNodeReport complete");
- if (State) {
- State->ApplyConfigUpdates();
- State.reset();
- }
- }
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev) {
- TabletCounters->Cumulative()[NBlobStorageController::COUNTER_NODE_REPORT_COUNT].Increment(1);
- TRequestCounter counter(TabletCounters, NBlobStorageController::COUNTER_NODE_REPORT_USEC);
- Execute(new TTxNodeReport(ev, this));
-}
-
-} // NKikimr::NBsController
+#include "impl.h"
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxNodeReport
+ : public TTransactionBase<TBlobStorageController>
+{
+ TEvBlobStorage::TEvControllerNodeReport::TPtr Event;
+ std::optional<TConfigState> State;
+
+public:
+ TTxNodeReport(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev, TBlobStorageController *controller)
+ : TBase(controller)
+ , Event(ev)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_NODE_REPORT; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_NODE_REPORT_USEC);
+
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXNR01, "TTxNodeReport execute");
+
+ State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
+ State->CheckConsistency();
+
+ std::vector<TVSlotId> droppedDonorVSlotIds;
+
+ NIceDb::TNiceDb db(txc.DB);
+ const auto& record = Event->Get()->Record;
+
+ if (!record.HasNodeId()) {
+ return true;
+ }
+ for (const auto& report : record.GetVDiskReports()) {
+ if (!report.HasVSlotId() || !report.HasVDiskId() || !report.HasPhase()) {
+ continue; // ignore incorrect report
+ }
+
+ TVSlotInfo *slot = State->VSlots.FindForUpdate(report.GetVSlotId());
+ if (!slot || !slot->IsSameVDisk(VDiskIDFromVDiskID(report.GetVDiskId()))) {
+ continue; // ignore entry -- possibly race/obsolete reply
+ }
+
+ switch (report.GetPhase()) {
+ case NKikimrBlobStorage::TEvControllerNodeReport::UNKNOWN:
+ continue; // ignore incorrect report
+
+ case NKikimrBlobStorage::TEvControllerNodeReport::WIPED:
+ if (slot->Mood == TMood::Wipe) {
+ slot->Mood = TMood::Normal;
+ }
+ break;
+
+ case NKikimrBlobStorage::TEvControllerNodeReport::DESTROYED:
+ if (slot->IsBeingDeleted()) {
+ const size_t num = const_cast<TPDiskInfo&>(*slot->PDisk).VSlotsOnPDisk.erase(slot->VSlotId.VSlotId);
+ Y_VERIFY(num);
+ State->VSlots.DeleteExistingEntry(slot->VSlotId);
+ }
+ break;
+
+ case NKikimrBlobStorage::TEvControllerNodeReport::OPERATION_ERROR:
+ switch (slot->Mood) { // TODO(alexvru): implement some retry logic?
+ case TMood::Normal:
+ break;
+ case TMood::Wipe:
+ break;
+ case TMood::Delete:
+ break;
+ case TMood::Donor:
+ break;
+ }
+ break;
+
+ case NKikimrBlobStorage::TEvControllerNodeReport::DROP_DONOR:
+ for (const auto& [donorVSlotId, donorVDiskId] : slot->Donors) {
+ if (donorVDiskId == VDiskIDFromVDiskID(report.GetOtherVDiskId())) {
+ if (const TVSlotInfo *vslot = State->VSlots.Find(donorVSlotId); vslot && !vslot->IsBeingDeleted()) {
+ Y_VERIFY(vslot->Mood == TMood::Donor);
+ State->DestroyVSlot(vslot->VSlotId);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ State->CheckConsistency();
+ TString error;
+ if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
+ State->Rollback();
+ State.reset();
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXNR02, "TTxNodeReport complete");
+ if (State) {
+ State->ApplyConfigUpdates();
+ State.reset();
+ }
+ }
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerNodeReport::TPtr &ev) {
+ TabletCounters->Cumulative()[NBlobStorageController::COUNTER_NODE_REPORT_COUNT].Increment(1);
+ TRequestCounter counter(TabletCounters, NBlobStorageController::COUNTER_NODE_REPORT_USEC);
+ Execute(new TTxNodeReport(ev, this));
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/propose_group_key.cpp b/ydb/core/mind/bscontroller/propose_group_key.cpp
index ebca302ee67..d1006bcfc9e 100644
--- a/ydb/core/mind/bscontroller/propose_group_key.cpp
+++ b/ydb/core/mind/bscontroller/propose_group_key.cpp
@@ -29,91 +29,91 @@ public:
GroupKeyNonce = Proto.GetGroupKeyNonce();
}
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_PROPOSE_GROUP_KEY; }
-
- void ReadStep() {
- const auto prevStatus = std::exchange(Status, NKikimrProto::ERROR); // assume error
- TGroupInfo *group = Self->FindGroup(GroupId);
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_PROPOSE_GROUP_KEY; }
+
+ void ReadStep() {
+ const auto prevStatus = std::exchange(Status, NKikimrProto::ERROR); // assume error
+ TGroupInfo *group = Self->FindGroup(GroupId);
if (TGroupID(GroupId).ConfigurationType() != GroupConfigurationTypeDynamic) {
- STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK01, "Can't propose key for non-dynamic group", (GroupId, GroupId));
- } else if (!group) {
- STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK02, "Can't read group info", (GroupId, GroupId));
- } else if (group->EncryptionMode.GetOrElse(0) == 0) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK03, "Group is not encrypted", (GroupId, GroupId));
- } else if (group->LifeCyclePhase.GetOrElse(0) != TBlobStorageGroupInfo::ELCP_INITIAL) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK04, "Group LifeCyclePhase does not match ELCP_INITIAL",
- (GroupId, GroupId), (LifeCyclePhase, group->LifeCyclePhase.GetOrElse(0)));
+ STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK01, "Can't propose key for non-dynamic group", (GroupId, GroupId));
+ } else if (!group) {
+ STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK02, "Can't read group info", (GroupId, GroupId));
+ } else if (group->EncryptionMode.GetOrElse(0) == 0) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK03, "Group is not encrypted", (GroupId, GroupId));
+ } else if (group->LifeCyclePhase.GetOrElse(0) != TBlobStorageGroupInfo::ELCP_INITIAL) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK04, "Group LifeCyclePhase does not match ELCP_INITIAL",
+ (GroupId, GroupId), (LifeCyclePhase, group->LifeCyclePhase.GetOrElse(0)));
IsAnotherTxInProgress = (group->LifeCyclePhase.GetOrElse(0) == TBlobStorageGroupInfo::ELCP_IN_TRANSITION);
} else if (group->MainKeyVersion.GetOrElse(0) != (MainKeyVersion - 1)) {
STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK05, "Group MainKeyVersion does not match required MainKeyVersion",
(GroupId, GroupId), (MainKeyVersion, group->MainKeyVersion.GetOrElse(0)),
(RequiredMainKeyVersion, MainKeyVersion - 1));
- } else if (EncryptedGroupKey.size() != 32 + sizeof(ui32)) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK06, "Group does not accept EncryptedGroupKey size",
- (GroupId, GroupId), (EncryptedGroupKeySize, EncryptedGroupKey.size()),
- (ExpectedEncryptedGroupKeySize, 32 + sizeof(ui32)));
- } else {
- Status = prevStatus; // return old status
+ } else if (EncryptedGroupKey.size() != 32 + sizeof(ui32)) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK06, "Group does not accept EncryptedGroupKey size",
+ (GroupId, GroupId), (EncryptedGroupKeySize, EncryptedGroupKey.size()),
+ (ExpectedEncryptedGroupKeySize, 32 + sizeof(ui32)));
+ } else {
+ Status = prevStatus; // return old status
}
}
- void WriteStep(TTransactionContext &txc) {
+ void WriteStep(TTransactionContext &txc) {
NIceDb::TNiceDb db(txc.DB);
// Reflect group structure in the database (pass)
TGroupInfo *group = Self->FindGroup(GroupId);
- Y_VERIFY(group); // the existence of this group must have been checked during ReadStep
+ Y_VERIFY(group); // the existence of this group must have been checked during ReadStep
group->LifeCyclePhase = TBlobStorageGroupInfo::ELCP_IN_TRANSITION;
group->MainKeyId = MainKeyId;
group->EncryptedGroupKey = EncryptedGroupKey;
group->GroupKeyNonce = GroupKeyNonce;
group->MainKeyVersion = MainKeyVersion;
db.Table<Schema::Group>().Key(GroupId).Update(
- NIceDb::TUpdate<Schema::Group::LifeCyclePhase>(TBlobStorageGroupInfo::ELCP_IN_USE),
+ NIceDb::TUpdate<Schema::Group::LifeCyclePhase>(TBlobStorageGroupInfo::ELCP_IN_USE),
NIceDb::TUpdate<Schema::Group::MainKeyId>(MainKeyId),
- NIceDb::TUpdate<Schema::Group::EncryptedGroupKey>(EncryptedGroupKey),
- NIceDb::TUpdate<Schema::Group::GroupKeyNonce>(GroupKeyNonce),
+ NIceDb::TUpdate<Schema::Group::EncryptedGroupKey>(EncryptedGroupKey),
+ NIceDb::TUpdate<Schema::Group::GroupKeyNonce>(GroupKeyNonce),
NIceDb::TUpdate<Schema::Group::MainKeyVersion>(MainKeyVersion));
}
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK07, "TTxProposeGroupKey Execute");
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK07, "TTxProposeGroupKey Execute");
Status = NKikimrProto::OK;
- ReadStep();
+ ReadStep();
if (Status == NKikimrProto::OK) {
- WriteStep(txc);
+ WriteStep(txc);
}
- return true;
+ return true;
}
- void Complete(const TActorContext&) override {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK08, "TTxProposeGroupKey Complete");
+ void Complete(const TActorContext&) override {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK08, "TTxProposeGroupKey Complete");
if (Status == NKikimrProto::OK) {
- TGroupInfo *group = Self->FindGroup(GroupId);
- Y_VERIFY(group);
- if (group->LifeCyclePhase == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
- group->LifeCyclePhase = TBlobStorageGroupInfo::ELCP_IN_USE;
+ TGroupInfo *group = Self->FindGroup(GroupId);
+ Y_VERIFY(group);
+ if (group->LifeCyclePhase == TBlobStorageGroupInfo::ELCP_IN_TRANSITION) {
+ group->LifeCyclePhase = TBlobStorageGroupInfo::ELCP_IN_USE;
} else {
- STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK09, "TTxProposeGroupKey unexpected LifyCyclePhase",
- (GroupId, GroupId), (LifeCyclePhase, group->LifeCyclePhase));
+ STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXPGK09, "TTxProposeGroupKey unexpected LifyCyclePhase",
+ (GroupId, GroupId), (LifeCyclePhase, group->LifeCyclePhase));
}
} else {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK10, "TTxProposeGroupKey error", (GroupId, GroupId),
- (Status, Status), (Request, Proto));
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXPGK10, "TTxProposeGroupKey error", (GroupId, GroupId),
+ (Status, Status), (Request, Proto));
}
if (!IsAnotherTxInProgress) {
// Get groupinfo for the group and send it to all whom it may concern.
- Self->NotifyNodesAwaitingKeysForGroups(GroupId);
+ Self->NotifyNodesAwaitingKeysForGroups(GroupId);
}
}
};
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerProposeGroupKey::TPtr &ev) {
- const NKikimrBlobStorage::TEvControllerProposeGroupKey& proto = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK11, "Handle TEvControllerProposeGroupKey", (Request, proto));
- Y_VERIFY(AppData());
- NodesAwaitingKeysForGroup[proto.GetGroupId()].insert(proto.GetNodeId());
- Execute(new TTxProposeGroupKey(proto, this));
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerProposeGroupKey::TPtr &ev) {
+ const NKikimrBlobStorage::TEvControllerProposeGroupKey& proto = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXPGK11, "Handle TEvControllerProposeGroupKey", (Request, proto));
+ Y_VERIFY(AppData());
+ NodesAwaitingKeysForGroup[proto.GetGroupId()].insert(proto.GetNodeId());
+ Execute(new TTxProposeGroupKey(proto, this));
}
} // NBlobStorageController
diff --git a/ydb/core/mind/bscontroller/register_node.cpp b/ydb/core/mind/bscontroller/register_node.cpp
index a54801b7428..3f042de7633 100644
--- a/ydb/core/mind/bscontroller/register_node.cpp
+++ b/ydb/core/mind/bscontroller/register_node.cpp
@@ -1,16 +1,16 @@
-#include "impl.h"
-
+#include "impl.h"
+
#include <ydb/core/blobstorage/base/utility.h>
#include "config.h"
-namespace NKikimr::NBsController {
-
+namespace NKikimr::NBsController {
+
class TBlobStorageController::TTxUpdateNodeDrives
: public TTransactionBase<TBlobStorageController>
{
NKikimrBlobStorage::TEvControllerUpdateNodeDrives Record;
std::optional<TConfigState> State;
-
+
std::unique_ptr<IEventHandle> Response;
void UpdateDevicesInfo(TTransactionContext& txc, TEvBlobStorage::TEvControllerNodeServiceSetUpdate* result) {
@@ -62,13 +62,13 @@ class TBlobStorageController::TTxUpdateNodeDrives
if (!info.ExpectedSerial) {
if (auto driveIt = Self->DrivesSerials.find(TSerial{serial}); driveIt != Self->DrivesSerials.end()) {
log << "device is managed by HostConfigs and was removed.";
- if (driveIt->second->LifeStage == NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN) {
+ if (driveIt->second->LifeStage == NKikimrBlobStorage::TDriveLifeStage::NOT_SEEN) {
log << " Drive was added while node was offline, so update ExpectedSerial and"
<< " remove fictional row from DriveSerial table";
info.ExpectedSerial = serial;
Self->DrivesSerials.erase(driveIt);
db.Table<Schema::DriveSerial>().Key(TSerial{serial}.GetKey()).Delete();
- } else if (driveIt->second->LifeStage == NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
+ } else if (driveIt->second->LifeStage == NKikimrBlobStorage::TDriveLifeStage::REMOVED) {
log << " Drive is still marked as REMOVED, so do not update ExpectedSerial";
}
} else {
@@ -81,15 +81,15 @@ class TBlobStorageController::TTxUpdateNodeDrives
} else {
log << "Set new ExpectedSerial for pdisk";
- auto [it, emplaced] = Self->DrivesSerials.emplace(serial, MakeHolder<TDriveSerialInfo>(info.BoxId));
- it->second->Guid = info.Guid;
- it->second->Kind = info.Kind.Kind();
- it->second->PDiskType = PDiskTypeToPDiskType(info.Kind.Type());
- it->second->PDiskConfig = info.PDiskConfig;
- it->second->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
+ auto [it, emplaced] = Self->DrivesSerials.emplace(serial, MakeHolder<TDriveSerialInfo>(info.BoxId));
+ it->second->Guid = info.Guid;
+ it->second->Kind = info.Kind.Kind();
+ it->second->PDiskType = PDiskTypeToPDiskType(info.Kind.Type());
+ it->second->PDiskConfig = info.PDiskConfig;
+ it->second->LifeStage = NKikimrBlobStorage::TDriveLifeStage::REMOVED;
TDriveSerialInfo::Apply(Self, [&, it = it] (auto* adapter) {
- adapter->IssueUpdateRow(txc, TSerial{serial}, *it->second);
+ adapter->IssueUpdateRow(txc, TSerial{serial}, *it->second);
});
info.ExpectedSerial = serial;
@@ -113,7 +113,7 @@ class TBlobStorageController::TTxUpdateNodeDrives
for (const auto& data : Record.GetDrivesData()) {
const auto& serial = data.GetSerialNumber();
- if (auto it = Self->NodeForSerial.find(serial); it != Self->NodeForSerial.end() && it->second != nodeId) {
+ if (auto it = Self->NodeForSerial.find(serial); it != Self->NodeForSerial.end() && it->second != nodeId) {
STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXRN03,
"Received drive from NewNodeId, but drive is reported as placed in OldNodeId",
(NewNodeId, nodeId), (OldNodeId, it->second), (Serial, serial));
@@ -127,7 +127,7 @@ class TBlobStorageController::TTxUpdateNodeDrives
}
}
-public:
+public:
TTxUpdateNodeDrives(NKikimrBlobStorage::TEvControllerUpdateNodeDrives&& rec, TBlobStorageController *controller)
: TTransactionBase(controller)
, Record(std::move(rec))
@@ -140,7 +140,7 @@ public:
auto result = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
- State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
+ State.emplace(*Self, Self->HostRecords, TActivationContext::Now());
State->CheckConsistency();
UpdateDevicesInfo(txc, result.get());
@@ -167,7 +167,7 @@ public:
Response = std::make_unique<IEventHandle>(MakeBlobStorageNodeWardenID(nodeId), Self->SelfId(), result.release(), 0, 0);
TString error;
- if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
+ if (State->Changed() && !Self->CommitConfigUpdates(*State, false, false, txc, &error)) {
State->Rollback();
State.reset();
}
@@ -196,282 +196,282 @@ class TBlobStorageController::TTxRegisterNode
public:
- TTxRegisterNode(TEvBlobStorage::TEvControllerRegisterNode::TPtr& ev, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , Request(ev)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_REGISTER_NODE; }
-
+ TTxRegisterNode(TEvBlobStorage::TEvControllerRegisterNode::TPtr& ev, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , Request(ev)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_REGISTER_NODE; }
+
bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_REGISTER_NODE_COUNT].Increment(1);
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_REGISTER_NODE_USEC);
-
- auto request = std::move(Request);
- const auto& record = request->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXRN01, "Handle TEvControllerRegisterNode", (Request, record));
-
- const TNodeId nodeId = record.GetNodeID();
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_REGISTER_NODE_COUNT].Increment(1);
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_REGISTER_NODE_USEC);
+
+ auto request = std::move(Request);
+ const auto& record = request->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXRN01, "Handle TEvControllerRegisterNode", (Request, record));
+
+ const TNodeId nodeId = record.GetNodeID();
UpdateNodeDrivesRecord.SetNodeId(nodeId);
for (const auto& data : record.GetDrivesData()) {
*UpdateNodeDrivesRecord.AddDrivesData() = data;
}
- Self->OnRegisterNode(request->Recipient, nodeId);
- Self->ProcessVDiskStatus(record.GetVDiskStatus());
-
- // create map of group ids to their generations as reported by the node warden
- TMap<ui32, ui32> startedGroups;
- if (record.GroupsSize() == record.GroupGenerationsSize()) {
- for (size_t i = 0; i < record.GroupsSize(); ++i) {
- startedGroups.emplace(record.GetGroups(i), record.GetGroupGenerations(i));
- }
- } else {
- for (ui32 groupId : record.GetGroups()) {
- startedGroups.emplace(groupId, 0);
- }
- }
-
+ Self->OnRegisterNode(request->Recipient, nodeId);
+ Self->ProcessVDiskStatus(record.GetVDiskStatus());
+
+ // create map of group ids to their generations as reported by the node warden
+ TMap<ui32, ui32> startedGroups;
+ if (record.GroupsSize() == record.GroupGenerationsSize()) {
+ for (size_t i = 0; i < record.GroupsSize(); ++i) {
+ startedGroups.emplace(record.GetGroups(i), record.GetGroupGenerations(i));
+ }
+ } else {
+ for (ui32 groupId : record.GetGroups()) {
+ startedGroups.emplace(groupId, 0);
+ }
+ }
+
TNodeInfo& nodeInfo = Self->GetNode(nodeId);
- auto res = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
-
+ auto res = std::make_unique<TEvBlobStorage::TEvControllerNodeServiceSetUpdate>(NKikimrProto::OK, nodeId);
+
TSet<ui32> groupIDsToRead;
const TPDiskId minPDiskId(TPDiskId::MinForNode(nodeId));
const TVSlotId vslotId = TVSlotId::MinForPDisk(minPDiskId);
- for (auto it = Self->VSlots.lower_bound(vslotId); it != Self->VSlots.end() && it->first.NodeId == nodeId; ++it) {
- Self->ReadVSlot(*it->second, res.get());
- if (!it->second->IsBeingDeleted()) {
- groupIDsToRead.insert(it->second->GroupId);
- }
- }
-
- TSet<ui32> groupsToDiscard;
-
- auto processGroup = [&](const auto& p, TGroupInfo *group) {
- auto&& [groupId, generation] = p;
- if (!group) {
- groupsToDiscard.insert(groupsToDiscard.end(), groupId);
- } else if (group->Generation > generation) {
- auto *meta = res->Record.AddGroupMetadata();
- meta->SetGroupId(groupId);
- meta->SetCurrentGeneration(group->Generation);
- groupIDsToRead.insert(groupId);
- }
- };
-
- if (startedGroups.size() <= Self->GroupMap.size() / 10) {
- for (const auto& p : startedGroups) {
- processGroup(p, Self->FindGroup(p.first));
- }
- } else {
- auto started = startedGroups.begin();
- auto groupIt = Self->GroupMap.begin();
-
- while (started != startedGroups.end()) {
- TGroupInfo *group = nullptr;
-
- // scan through groups until we find matching one
- for (; groupIt != Self->GroupMap.end() && groupIt->first <= started->first; ++groupIt) {
- if (groupIt->first == started->first) {
- group = groupIt->second.Get();
- }
- }
-
- processGroup(*started++, group);
- }
- }
-
- Self->ReadGroups(groupIDsToRead, false, res.get());
- Y_VERIFY(groupIDsToRead.empty());
-
- Self->ReadGroups(groupsToDiscard, true, res.get());
-
+ for (auto it = Self->VSlots.lower_bound(vslotId); it != Self->VSlots.end() && it->first.NodeId == nodeId; ++it) {
+ Self->ReadVSlot(*it->second, res.get());
+ if (!it->second->IsBeingDeleted()) {
+ groupIDsToRead.insert(it->second->GroupId);
+ }
+ }
+
+ TSet<ui32> groupsToDiscard;
+
+ auto processGroup = [&](const auto& p, TGroupInfo *group) {
+ auto&& [groupId, generation] = p;
+ if (!group) {
+ groupsToDiscard.insert(groupsToDiscard.end(), groupId);
+ } else if (group->Generation > generation) {
+ auto *meta = res->Record.AddGroupMetadata();
+ meta->SetGroupId(groupId);
+ meta->SetCurrentGeneration(group->Generation);
+ groupIDsToRead.insert(groupId);
+ }
+ };
+
+ if (startedGroups.size() <= Self->GroupMap.size() / 10) {
+ for (const auto& p : startedGroups) {
+ processGroup(p, Self->FindGroup(p.first));
+ }
+ } else {
+ auto started = startedGroups.begin();
+ auto groupIt = Self->GroupMap.begin();
+
+ while (started != startedGroups.end()) {
+ TGroupInfo *group = nullptr;
+
+ // scan through groups until we find matching one
+ for (; groupIt != Self->GroupMap.end() && groupIt->first <= started->first; ++groupIt) {
+ if (groupIt->first == started->first) {
+ group = groupIt->second.Get();
+ }
+ }
+
+ processGroup(*started++, group);
+ }
+ }
+
+ Self->ReadGroups(groupIDsToRead, false, res.get());
+ Y_VERIFY(groupIDsToRead.empty());
+
+ Self->ReadGroups(groupsToDiscard, true, res.get());
+
nodeInfo.IsRegistered = true;
-
+
for (auto it = Self->PDisks.lower_bound(minPDiskId); it != Self->PDisks.end() && it->first.NodeId == nodeId; ++it) {
Self->ReadPDisk(it->first, *it->second, res.get(), NKikimrBlobStorage::INITIAL);
}
- res->Record.SetInstanceId(Self->InstanceId);
- res->Record.SetComprehensive(true);
- res->Record.SetAvailDomain(AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID()));
- Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), res.release(), 0, request->Cookie);
-
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- TActivationContext::Send(Response.release());
- Self->Execute(new TTxUpdateNodeDrives(std::move(UpdateNodeDrivesRecord), Self));
- }
-};
-
-void TBlobStorageController::ReadGroups(TSet<ui32>& groupIDsToRead, bool discard,
- TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result) {
- for (auto it = groupIDsToRead.begin(); it != groupIDsToRead.end(); ) {
- const TGroupId groupId = *it;
- if (TGroupInfo *group = FindGroup(groupId); group || discard) {
- NKikimrBlobStorage::TNodeWardenServiceSet *serviceSetProto = result->Record.MutableServiceSet();
- NKikimrBlobStorage::TGroupInfo *groupProto = serviceSetProto->AddGroups();
- if (!group) {
- groupProto->SetGroupID(groupId);
- groupProto->SetEntityStatus(NKikimrBlobStorage::DESTROY);
- } else {
- const TStoragePoolInfo& info = StoragePools.at(group->StoragePoolId);
-
- TMaybe<TKikimrScopeId> scopeId;
- if (info.SchemeshardId && info.PathItemId) {
- scopeId.ConstructInPlace(*info.SchemeshardId, *info.PathItemId);
- } else {
- Y_VERIFY(!info.SchemeshardId && !info.PathItemId);
- }
-
- SerializeGroupInfo(groupProto, *group, info.Name, scopeId);
- }
-
- // this group is processed, remove it from the set
- it = groupIDsToRead.erase(it);
- } else {
- ++it; // keep this group in the set as deleted one
- }
- }
-}
-
-void TBlobStorageController::ReadPDisk(const TPDiskId& pdiskId, const TPDiskInfo& pdisk,
+ res->Record.SetInstanceId(Self->InstanceId);
+ res->Record.SetComprehensive(true);
+ res->Record.SetAvailDomain(AppData()->DomainsInfo->GetDomainUidByTabletId(Self->TabletID()));
+ Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), res.release(), 0, request->Cookie);
+
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ TActivationContext::Send(Response.release());
+ Self->Execute(new TTxUpdateNodeDrives(std::move(UpdateNodeDrivesRecord), Self));
+ }
+};
+
+void TBlobStorageController::ReadGroups(TSet<ui32>& groupIDsToRead, bool discard,
+ TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result) {
+ for (auto it = groupIDsToRead.begin(); it != groupIDsToRead.end(); ) {
+ const TGroupId groupId = *it;
+ if (TGroupInfo *group = FindGroup(groupId); group || discard) {
+ NKikimrBlobStorage::TNodeWardenServiceSet *serviceSetProto = result->Record.MutableServiceSet();
+ NKikimrBlobStorage::TGroupInfo *groupProto = serviceSetProto->AddGroups();
+ if (!group) {
+ groupProto->SetGroupID(groupId);
+ groupProto->SetEntityStatus(NKikimrBlobStorage::DESTROY);
+ } else {
+ const TStoragePoolInfo& info = StoragePools.at(group->StoragePoolId);
+
+ TMaybe<TKikimrScopeId> scopeId;
+ if (info.SchemeshardId && info.PathItemId) {
+ scopeId.ConstructInPlace(*info.SchemeshardId, *info.PathItemId);
+ } else {
+ Y_VERIFY(!info.SchemeshardId && !info.PathItemId);
+ }
+
+ SerializeGroupInfo(groupProto, *group, info.Name, scopeId);
+ }
+
+ // this group is processed, remove it from the set
+ it = groupIDsToRead.erase(it);
+ } else {
+ ++it; // keep this group in the set as deleted one
+ }
+ }
+}
+
+void TBlobStorageController::ReadPDisk(const TPDiskId& pdiskId, const TPDiskInfo& pdisk,
TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result, const NKikimrBlobStorage::EEntityStatus entityStatus) {
- NKikimrBlobStorage::TNodeWardenServiceSet *serviceSet = result->Record.MutableServiceSet();
- NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pDisk = serviceSet->AddPDisks();
- if (const auto it = StaticPDiskMap.find(pdiskId); it != StaticPDiskMap.end()) {
- pDisk->CopyFrom(it->second);
- } else {
- pDisk->SetNodeID(pdiskId.NodeId);
- pDisk->SetPDiskID(pdiskId.PDiskId);
+ NKikimrBlobStorage::TNodeWardenServiceSet *serviceSet = result->Record.MutableServiceSet();
+ NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk *pDisk = serviceSet->AddPDisks();
+ if (const auto it = StaticPDiskMap.find(pdiskId); it != StaticPDiskMap.end()) {
+ pDisk->CopyFrom(it->second);
+ } else {
+ pDisk->SetNodeID(pdiskId.NodeId);
+ pDisk->SetPDiskID(pdiskId.PDiskId);
if (pdisk.Path) {
pDisk->SetPath(pdisk.Path);
} else if (pdisk.LastSeenPath) {
pDisk->SetPath(pdisk.LastSeenPath);
}
- pDisk->SetPDiskCategory(pdisk.Kind.GetRaw());
- pDisk->SetPDiskGuid(pdisk.Guid);
- if (pdisk.PDiskConfig && !pDisk->MutablePDiskConfig()->ParseFromString(pdisk.PDiskConfig)) {
- STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXRN02, "PDiskConfig invalid", (NodeId, pdiskId.NodeId),
- (PDiskId, pdiskId.PDiskId));
- }
- }
+ pDisk->SetPDiskCategory(pdisk.Kind.GetRaw());
+ pDisk->SetPDiskGuid(pdisk.Guid);
+ if (pdisk.PDiskConfig && !pDisk->MutablePDiskConfig()->ParseFromString(pdisk.PDiskConfig)) {
+ STLOG(PRI_CRIT, BS_CONTROLLER, BSCTXRN02, "PDiskConfig invalid", (NodeId, pdiskId.NodeId),
+ (PDiskId, pdiskId.PDiskId));
+ }
+ }
pDisk->SetExpectedSerial(pdisk.ExpectedSerial);
pDisk->SetManagementStage(SerialManagementStage);
pDisk->SetSpaceColorBorder(PDiskSpaceColorBorder);
pDisk->SetEntityStatus(entityStatus);
-}
-
-void TBlobStorageController::ReadVSlot(const TVSlotInfo& vslot, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result) {
- NKikimrBlobStorage::TNodeWardenServiceSet *serviceSet = result->Record.MutableServiceSet();
- NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vDisk = serviceSet->AddVDisks();
- Serialize(vDisk->MutableVDiskLocation(), vslot);
-
- VDiskIDFromVDiskID(vslot.GetVDiskId(), vDisk->MutableVDiskID());
-
- vDisk->SetVDiskKind(vslot.Kind);
- if (vslot.IsBeingDeleted()) {
- vDisk->SetDoDestroy(true);
- vDisk->SetEntityStatus(NKikimrBlobStorage::DESTROY);
- } else {
- vDisk->SetDoWipe(vslot.Mood == TMood::Wipe);
- }
-
- if (TGroupInfo *group = FindGroup(vslot.GroupId)) {
- const TStoragePoolInfo& info = StoragePools.at(group->StoragePoolId);
- vDisk->SetStoragePoolName(info.Name);
- SerializeDonors(vDisk, vslot, *group);
- } else {
- Y_VERIFY(vslot.Mood != TMood::Donor);
- }
-}
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerRegisterNode::TPtr& ev) {
- Execute(new TTxRegisterNode(ev, this));
-}
-
+}
+
+void TBlobStorageController::ReadVSlot(const TVSlotInfo& vslot, TEvBlobStorage::TEvControllerNodeServiceSetUpdate *result) {
+ NKikimrBlobStorage::TNodeWardenServiceSet *serviceSet = result->Record.MutableServiceSet();
+ NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk *vDisk = serviceSet->AddVDisks();
+ Serialize(vDisk->MutableVDiskLocation(), vslot);
+
+ VDiskIDFromVDiskID(vslot.GetVDiskId(), vDisk->MutableVDiskID());
+
+ vDisk->SetVDiskKind(vslot.Kind);
+ if (vslot.IsBeingDeleted()) {
+ vDisk->SetDoDestroy(true);
+ vDisk->SetEntityStatus(NKikimrBlobStorage::DESTROY);
+ } else {
+ vDisk->SetDoWipe(vslot.Mood == TMood::Wipe);
+ }
+
+ if (TGroupInfo *group = FindGroup(vslot.GroupId)) {
+ const TStoragePoolInfo& info = StoragePools.at(group->StoragePoolId);
+ vDisk->SetStoragePoolName(info.Name);
+ SerializeDonors(vDisk, vslot, *group);
+ } else {
+ Y_VERIFY(vslot.Mood != TMood::Donor);
+ }
+}
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerRegisterNode::TPtr& ev) {
+ Execute(new TTxRegisterNode(ev, this));
+}
+
void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateNodeDrives::TPtr& ev) {
- Execute(new TTxUpdateNodeDrives(std::move(ev->Get()->Record), this));
+ Execute(new TTxUpdateNodeDrives(std::move(ev->Get()->Record), this));
}
-void TBlobStorageController::Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev) {
- auto&& [it, inserted] = PipeServerToNode.emplace(ev->Get()->ServerId, std::nullopt);
- Y_VERIFY_DEBUG(inserted);
-}
-
-void TBlobStorageController::Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev) {
- if (auto it = PipeServerToNode.find(ev->Get()->ServerId); it != PipeServerToNode.end()) {
- if (auto&& nodeId = it->second) {
- OnWardenDisconnected(*nodeId);
- }
- PipeServerToNode.erase(it);
- } else {
- Y_VERIFY_DEBUG(false);
- }
-}
-
-void TBlobStorageController::OnRegisterNode(const TActorId& serverId, TNodeId nodeId) {
- if (auto it = PipeServerToNode.find(serverId); it != PipeServerToNode.end()) {
- if (!it->second) {
- it->second = nodeId;
- OnWardenConnected(nodeId);
- } else {
- Y_VERIFY_DEBUG(*it->second == nodeId);
- }
- } else {
- Y_VERIFY_DEBUG(false);
- }
-}
-
-void TBlobStorageController::OnWardenConnected(TNodeId nodeId) {
- for (auto it = PDisks.lower_bound(TPDiskId::MinForNode(nodeId)); it != PDisks.end() && it->first.NodeId == nodeId; ++it) {
- it->second->UpdateOperational(true);
- SysViewChangedPDisks.insert(it->first);
- }
-}
-
-void TBlobStorageController::OnWardenDisconnected(TNodeId nodeId) {
- const TInstant now = TActivationContext::Now();
- std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
- for (auto it = PDisks.lower_bound(TPDiskId::MinForNode(nodeId)); it != PDisks.end() && it->first.NodeId == nodeId; ++it) {
- it->second->UpdateOperational(false);
- SysViewChangedPDisks.insert(it->first);
- }
- const TVSlotId startingId(nodeId, Min<Schema::VSlot::PDiskID::Type>(), Min<Schema::VSlot::VSlotID::Type>());
- auto sh = MakeHolder<TEvControllerUpdateSelfHealInfo>();
- for (auto it = VSlots.lower_bound(startingId); it != VSlots.end() && it->first.NodeId == nodeId; ++it) {
- if (const TGroupInfo *group = it->second->Group) {
- if (it->second->IsReady) {
- it->second->LastSeenReady = now;
- lastSeenReadyQ.emplace_back(it->second->VSlotId, now);
- NotReadyVSlotIds.insert(it->second->VSlotId);
- }
- it->second->SetStatus(NKikimrBlobStorage::EVDiskStatus::ERROR, now);
- const_cast<TGroupInfo*>(group)->CalculateGroupStatus();
- sh->VDiskStatusUpdate.emplace_back(it->second->GetVDiskId(), it->second->GetStatus());
- ScrubState.UpdateVDiskState(&*it->second);
- }
- }
- for (auto it = StaticVSlots.lower_bound(startingId); it != StaticVSlots.end() && it->first.NodeId == nodeId; ++it) {
- it->second.VDiskStatus = NKikimrBlobStorage::EVDiskStatus::ERROR;
- }
- if (sh->VDiskStatusUpdate) {
- Send(SelfHealId, sh.Release());
- }
- ScrubState.OnNodeDisconnected(nodeId);
- TNodeInfo& node = GetNode(nodeId);
- node.IsRegistered = false;
+void TBlobStorageController::Handle(TEvTabletPipe::TEvServerConnected::TPtr& ev) {
+ auto&& [it, inserted] = PipeServerToNode.emplace(ev->Get()->ServerId, std::nullopt);
+ Y_VERIFY_DEBUG(inserted);
+}
+
+void TBlobStorageController::Handle(TEvTabletPipe::TEvServerDisconnected::TPtr& ev) {
+ if (auto it = PipeServerToNode.find(ev->Get()->ServerId); it != PipeServerToNode.end()) {
+ if (auto&& nodeId = it->second) {
+ OnWardenDisconnected(*nodeId);
+ }
+ PipeServerToNode.erase(it);
+ } else {
+ Y_VERIFY_DEBUG(false);
+ }
+}
+
+void TBlobStorageController::OnRegisterNode(const TActorId& serverId, TNodeId nodeId) {
+ if (auto it = PipeServerToNode.find(serverId); it != PipeServerToNode.end()) {
+ if (!it->second) {
+ it->second = nodeId;
+ OnWardenConnected(nodeId);
+ } else {
+ Y_VERIFY_DEBUG(*it->second == nodeId);
+ }
+ } else {
+ Y_VERIFY_DEBUG(false);
+ }
+}
+
+void TBlobStorageController::OnWardenConnected(TNodeId nodeId) {
+ for (auto it = PDisks.lower_bound(TPDiskId::MinForNode(nodeId)); it != PDisks.end() && it->first.NodeId == nodeId; ++it) {
+ it->second->UpdateOperational(true);
+ SysViewChangedPDisks.insert(it->first);
+ }
+}
+
+void TBlobStorageController::OnWardenDisconnected(TNodeId nodeId) {
+ const TInstant now = TActivationContext::Now();
+ std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
+ for (auto it = PDisks.lower_bound(TPDiskId::MinForNode(nodeId)); it != PDisks.end() && it->first.NodeId == nodeId; ++it) {
+ it->second->UpdateOperational(false);
+ SysViewChangedPDisks.insert(it->first);
+ }
+ const TVSlotId startingId(nodeId, Min<Schema::VSlot::PDiskID::Type>(), Min<Schema::VSlot::VSlotID::Type>());
+ auto sh = MakeHolder<TEvControllerUpdateSelfHealInfo>();
+ for (auto it = VSlots.lower_bound(startingId); it != VSlots.end() && it->first.NodeId == nodeId; ++it) {
+ if (const TGroupInfo *group = it->second->Group) {
+ if (it->second->IsReady) {
+ it->second->LastSeenReady = now;
+ lastSeenReadyQ.emplace_back(it->second->VSlotId, now);
+ NotReadyVSlotIds.insert(it->second->VSlotId);
+ }
+ it->second->SetStatus(NKikimrBlobStorage::EVDiskStatus::ERROR, now);
+ const_cast<TGroupInfo*>(group)->CalculateGroupStatus();
+ sh->VDiskStatusUpdate.emplace_back(it->second->GetVDiskId(), it->second->GetStatus());
+ ScrubState.UpdateVDiskState(&*it->second);
+ }
+ }
+ for (auto it = StaticVSlots.lower_bound(startingId); it != StaticVSlots.end() && it->first.NodeId == nodeId; ++it) {
+ it->second.VDiskStatus = NKikimrBlobStorage::EVDiskStatus::ERROR;
+ }
+ if (sh->VDiskStatusUpdate) {
+ Send(SelfHealId, sh.Release());
+ }
+ ScrubState.OnNodeDisconnected(nodeId);
+ TNodeInfo& node = GetNode(nodeId);
+ node.IsRegistered = false;
EraseKnownDrivesOnDisconnected(&node);
- if (!lastSeenReadyQ.empty()) {
- Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
- }
-}
-
+ if (!lastSeenReadyQ.empty()) {
+ Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
+ }
+}
+
void TBlobStorageController::EraseKnownDrivesOnDisconnected(TNodeInfo *nodeInfo) {
for (const auto& [serial, driveData] : nodeInfo->KnownDrives) {
NodeForSerial.erase(serial);
@@ -479,4 +479,4 @@ void TBlobStorageController::EraseKnownDrivesOnDisconnected(TNodeInfo *nodeInfo)
nodeInfo->KnownDrives.clear();
}
-} // NKikimr::NBsController
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/request_controller_info.cpp b/ydb/core/mind/bscontroller/request_controller_info.cpp
index 7f2952f8bb8..2ea648624dc 100644
--- a/ydb/core/mind/bscontroller/request_controller_info.cpp
+++ b/ydb/core/mind/bscontroller/request_controller_info.cpp
@@ -1,67 +1,67 @@
-#include "impl.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxRequestControllerInfo : public TTransactionBase<TBlobStorageController> {
- TEvBlobStorage::TEvRequestControllerInfo::TPtr Request;
- std::unique_ptr<IEventHandle> Response;
-
-public:
- TTxRequestControllerInfo(TEvBlobStorage::TEvRequestControllerInfo::TPtr& ev, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , Request(ev)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_REQUEST_CONTROLLER_INFO; }
-
- bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_REQUEST_INFO_COUNT].Increment(1);
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_REQUEST_INFO_USEC);
-
- auto request = std::move(Request);
- const auto& requestRecord = request->Get()->Record;
-
- auto response = std::make_unique<TEvBlobStorage::TEvResponseControllerInfo>();
- auto& responseRecord = response->Record;
-
- auto processGroup = [&](TGroupInfo *group) {
- auto *protoGroupInfo = responseRecord.AddBSGroupInfo();
- protoGroupInfo->SetGroupId(group->ID);
- protoGroupInfo->SetErasureSpecies(group->ErasureSpecies);
- const TResourceRawValues& groupResources = group->GetResourceCurrentValues();
- protoGroupInfo->SetDataSize(groupResources.DataSize);
-
- for (const TVSlotInfo *vslot : group->VDisksInGroup) {
- auto *vDiskInfo = protoGroupInfo->AddVDiskInfo();
- vDiskInfo->SetNodeId(vslot->VSlotId.NodeId);
- vDiskInfo->SetPDiskId(vslot->VSlotId.PDiskId);
- vDiskInfo->SetVDiskCategory(vslot->Kind);
- vDiskInfo->SetPDiskCategory(vslot->PDisk->Kind.GetRaw());
- VDiskIDFromVDiskID(vslot->GetVDiskId(), vDiskInfo->MutableVDiskId());
- }
- };
-
- if (requestRecord.HasGroupId()) {
- if (TGroupInfo *group = Self->FindGroup(requestRecord.GetGroupId())) {
- processGroup(group);
- }
- } else {
- for (const auto& [groupId, group] : Self->GroupMap) {
- processGroup(group.Get());
- }
- }
-
- Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), response.release());
- return true;
- }
-
- void Complete(const TActorContext&) override {
- TActivationContext::Send(Response.release());
- }
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvRequestControllerInfo::TPtr& ev) {
- Execute(new TTxRequestControllerInfo(ev, this));
-}
-
-} // NKikimr::NBsController
+#include "impl.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxRequestControllerInfo : public TTransactionBase<TBlobStorageController> {
+ TEvBlobStorage::TEvRequestControllerInfo::TPtr Request;
+ std::unique_ptr<IEventHandle> Response;
+
+public:
+ TTxRequestControllerInfo(TEvBlobStorage::TEvRequestControllerInfo::TPtr& ev, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , Request(ev)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_REQUEST_CONTROLLER_INFO; }
+
+ bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_REQUEST_INFO_COUNT].Increment(1);
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_REQUEST_INFO_USEC);
+
+ auto request = std::move(Request);
+ const auto& requestRecord = request->Get()->Record;
+
+ auto response = std::make_unique<TEvBlobStorage::TEvResponseControllerInfo>();
+ auto& responseRecord = response->Record;
+
+ auto processGroup = [&](TGroupInfo *group) {
+ auto *protoGroupInfo = responseRecord.AddBSGroupInfo();
+ protoGroupInfo->SetGroupId(group->ID);
+ protoGroupInfo->SetErasureSpecies(group->ErasureSpecies);
+ const TResourceRawValues& groupResources = group->GetResourceCurrentValues();
+ protoGroupInfo->SetDataSize(groupResources.DataSize);
+
+ for (const TVSlotInfo *vslot : group->VDisksInGroup) {
+ auto *vDiskInfo = protoGroupInfo->AddVDiskInfo();
+ vDiskInfo->SetNodeId(vslot->VSlotId.NodeId);
+ vDiskInfo->SetPDiskId(vslot->VSlotId.PDiskId);
+ vDiskInfo->SetVDiskCategory(vslot->Kind);
+ vDiskInfo->SetPDiskCategory(vslot->PDisk->Kind.GetRaw());
+ VDiskIDFromVDiskID(vslot->GetVDiskId(), vDiskInfo->MutableVDiskId());
+ }
+ };
+
+ if (requestRecord.HasGroupId()) {
+ if (TGroupInfo *group = Self->FindGroup(requestRecord.GetGroupId())) {
+ processGroup(group);
+ }
+ } else {
+ for (const auto& [groupId, group] : Self->GroupMap) {
+ processGroup(group.Get());
+ }
+ }
+
+ Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), response.release());
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ TActivationContext::Send(Response.release());
+ }
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvRequestControllerInfo::TPtr& ev) {
+ Execute(new TTxRequestControllerInfo(ev, this));
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/resources.h b/ydb/core/mind/bscontroller/resources.h
index 9234b546df5..6e4b4e51533 100644
--- a/ydb/core/mind/bscontroller/resources.h
+++ b/ydb/core/mind/bscontroller/resources.h
@@ -1,71 +1,71 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
- namespace NBsController {
-
- template<typename T>
- struct TResourceValues {
- T DataSize;
-
- TResourceValues(const TResourceValues&) = default;
-
- TResourceValues()
- : DataSize(0)
- {}
-
- TResourceValues(T dataSize)
- : DataSize(dataSize)
- {}
-
- T Max() const {
- return DataSize;
- }
-
- template<typename TFunc>
- static TResourceValues Apply(const TResourceValues& x, const TResourceValues& y, TFunc&& op) {
- return {
- op(x.DataSize, y.DataSize),
- };
- }
-
- template<typename TMultiplier>
- friend TResourceValues operator *(const TResourceValues& x, const TMultiplier& y) {
- return {
- T(x.DataSize * y),
- };
- }
-
- friend TResourceValues operator -(const TResourceValues& x, const TResourceValues& y) {
- return Apply(x, y, [](auto x, auto y) { return x - y; });
- }
-
- friend TResourceValues operator +(const TResourceValues& x, const TResourceValues& y) {
- return Apply(x, y, [](auto x, auto y) { return x + y; });
- }
-
- TResourceValues& operator +=(const TResourceValues& x) {
- return *this = *this + x;
- }
-
- TResourceValues<double> Normalize(const TResourceValues& max) const {
- return {
- max.DataSize ? static_cast<double>(DataSize) / max.DataSize : 0,
- };
- }
-
- static TResourceValues PiecewiseMax(const TResourceValues& x, const TResourceValues& y) {
- return Apply(x, y, [](auto x, auto y) { return std::max(x, y); });
- }
-
- TString ToString() const {
- return TStringBuilder() << "(" << DataSize << ")";
- }
- };
-
- using TResourceRawValues = TResourceValues<i64>;
- using TResourceNormalizedValues = TResourceValues<double>;
-
- } // NBsController
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+ namespace NBsController {
+
+ template<typename T>
+ struct TResourceValues {
+ T DataSize;
+
+ TResourceValues(const TResourceValues&) = default;
+
+ TResourceValues()
+ : DataSize(0)
+ {}
+
+ TResourceValues(T dataSize)
+ : DataSize(dataSize)
+ {}
+
+ T Max() const {
+ return DataSize;
+ }
+
+ template<typename TFunc>
+ static TResourceValues Apply(const TResourceValues& x, const TResourceValues& y, TFunc&& op) {
+ return {
+ op(x.DataSize, y.DataSize),
+ };
+ }
+
+ template<typename TMultiplier>
+ friend TResourceValues operator *(const TResourceValues& x, const TMultiplier& y) {
+ return {
+ T(x.DataSize * y),
+ };
+ }
+
+ friend TResourceValues operator -(const TResourceValues& x, const TResourceValues& y) {
+ return Apply(x, y, [](auto x, auto y) { return x - y; });
+ }
+
+ friend TResourceValues operator +(const TResourceValues& x, const TResourceValues& y) {
+ return Apply(x, y, [](auto x, auto y) { return x + y; });
+ }
+
+ TResourceValues& operator +=(const TResourceValues& x) {
+ return *this = *this + x;
+ }
+
+ TResourceValues<double> Normalize(const TResourceValues& max) const {
+ return {
+ max.DataSize ? static_cast<double>(DataSize) / max.DataSize : 0,
+ };
+ }
+
+ static TResourceValues PiecewiseMax(const TResourceValues& x, const TResourceValues& y) {
+ return Apply(x, y, [](auto x, auto y) { return std::max(x, y); });
+ }
+
+ TString ToString() const {
+ return TStringBuilder() << "(" << DataSize << ")";
+ }
+ };
+
+ using TResourceRawValues = TResourceValues<i64>;
+ using TResourceNormalizedValues = TResourceValues<double>;
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/scheme.h b/ydb/core/mind/bscontroller/scheme.h
index 3b7a425c95c..e8241048899 100644
--- a/ydb/core/mind/bscontroller/scheme.h
+++ b/ydb/core/mind/bscontroller/scheme.h
@@ -1,313 +1,313 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-struct Schema : NIceDb::Schema {
-
- enum : ui32 {
- CurrentSchemaVersion = 2,
- BoxHostMigrationSchemaVersion = 2,
- };
-
- struct Node : Table<2> {
- struct ID : Column<1, NScheme::NTypeIds::Uint32> {};
- struct NextPDiskID : Column<2, NScheme::NTypeIds::Uint32> {};
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+struct Schema : NIceDb::Schema {
+
+ enum : ui32 {
+ CurrentSchemaVersion = 2,
+ BoxHostMigrationSchemaVersion = 2,
+ };
+
+ struct Node : Table<2> {
+ struct ID : Column<1, NScheme::NTypeIds::Uint32> {};
+ struct NextPDiskID : Column<2, NScheme::NTypeIds::Uint32> {};
struct NextGroupKeyNonce : Column<9, NScheme::NTypeIds::Uint64> { static constexpr Type Default = 0; };
-
- using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, NextPDiskID>;
- };
-
- struct PDisk : Table<3> {
- struct NodeID : Column<1, Node::ID::ColumnType> {}; // PK
- struct PDiskID : Column<2, Node::NextPDiskID::ColumnType> {}; // PK
- struct Path : Column<3, NScheme::NTypeIds::Utf8> {};
+
+ using TKey = TableKey<ID>;
+ using TColumns = TableColumns<ID, NextPDiskID>;
+ };
+
+ struct PDisk : Table<3> {
+ struct NodeID : Column<1, Node::ID::ColumnType> {}; // PK
+ struct PDiskID : Column<2, Node::NextPDiskID::ColumnType> {}; // PK
+ struct Path : Column<3, NScheme::NTypeIds::Utf8> {};
struct Category : Column<4, NScheme::NTypeIds::Uint64> { using Type = TPDiskCategory;};
- //struct SystemConfig : Column<5, NScheme::NTypeIds::String> {};
- //struct PhysicalLocation : Column<6, NScheme::NTypeIds::String> {};
- struct Guid : Column<7, NScheme::NTypeIds::Uint64> {};
- struct SharedWithOs : Column<8, NScheme::NTypeIds::Bool> {};
- struct ReadCentric : Column<9, NScheme::NTypeIds::Bool> {};
- struct NextVSlotId : Column<10, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 1000; };
- struct PDiskConfig : Column<11, NScheme::NTypeIds::String> {};
- struct Status : Column<12, NScheme::NTypeIds::Uint32> { using Type = NKikimrBlobStorage::EDriveStatus; };
- struct Timestamp : Column<13, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
+ //struct SystemConfig : Column<5, NScheme::NTypeIds::String> {};
+ //struct PhysicalLocation : Column<6, NScheme::NTypeIds::String> {};
+ struct Guid : Column<7, NScheme::NTypeIds::Uint64> {};
+ struct SharedWithOs : Column<8, NScheme::NTypeIds::Bool> {};
+ struct ReadCentric : Column<9, NScheme::NTypeIds::Bool> {};
+ struct NextVSlotId : Column<10, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 1000; };
+ struct PDiskConfig : Column<11, NScheme::NTypeIds::String> {};
+ struct Status : Column<12, NScheme::NTypeIds::Uint32> { using Type = NKikimrBlobStorage::EDriveStatus; };
+ struct Timestamp : Column<13, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
struct ExpectedSerial : Column<14, NScheme::NTypeIds::String> {};
struct LastSeenSerial : Column<15, NScheme::NTypeIds::String> {};
struct LastSeenPath : Column<16, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<NodeID, PDiskID>; // order is important
- using TColumns = TableColumns<NodeID, PDiskID, Path, Category, Guid, SharedWithOs, ReadCentric, NextVSlotId,
+
+ using TKey = TableKey<NodeID, PDiskID>; // order is important
+ using TColumns = TableColumns<NodeID, PDiskID, Path, Category, Guid, SharedWithOs, ReadCentric, NextVSlotId,
Status, Timestamp, PDiskConfig, ExpectedSerial, LastSeenSerial, LastSeenPath>;
- };
-
- struct Group : Table<4> {
- struct ID : Column<1, NScheme::NTypeIds::Uint32> {}; // PK
- struct Generation : Column<2, NScheme::NTypeIds::Uint32> {};
- struct ErasureSpecies : Column<3, NScheme::NTypeIds::Uint32> { using Type = TErasureType::EErasureSpecies; };
- struct Owner : Column<4, NScheme::NTypeIds::Uint64> {};
+ };
+
+ struct Group : Table<4> {
+ struct ID : Column<1, NScheme::NTypeIds::Uint32> {}; // PK
+ struct Generation : Column<2, NScheme::NTypeIds::Uint32> {};
+ struct ErasureSpecies : Column<3, NScheme::NTypeIds::Uint32> { using Type = TErasureType::EErasureSpecies; };
+ struct Owner : Column<4, NScheme::NTypeIds::Uint64> {};
struct DesiredPDiskCategory : Column<5, NScheme::NTypeIds::Uint64> { using Type = TPDiskCategory; };
- struct DesiredVDiskCategory : Column<6, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
+ struct DesiredVDiskCategory : Column<6, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
struct EncryptionMode : Column<7, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
struct LifeCyclePhase : Column<8, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
struct MainKeyId : Column<9, NScheme::NTypeIds::String> {};
struct EncryptedGroupKey : Column<10, NScheme::NTypeIds::String> {};
struct GroupKeyNonce : Column<11, NScheme::NTypeIds::Uint64> { static constexpr Type Default = 0; };
struct MainKeyVersion : Column<12, NScheme::NTypeIds::Uint64> { static constexpr Type Default = 0; };
- struct Down : Column<13, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
- struct SeenOperational : Column<14, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
-
- using TKey = TableKey<ID>;
+ struct Down : Column<13, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
+ struct SeenOperational : Column<14, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
+
+ using TKey = TableKey<ID>;
using TColumns = TableColumns<ID, Generation, ErasureSpecies, Owner, DesiredPDiskCategory, DesiredVDiskCategory,
EncryptionMode, LifeCyclePhase, MainKeyId, EncryptedGroupKey, GroupKeyNonce, MainKeyVersion, Down,
- SeenOperational>;
- };
-
- struct State : Table<1> {
- struct FixedKey : Column<1, NScheme::NTypeIds::Bool> {}; // PK, forever 'true'
- struct NextGroupID : Column<2, Group::ID::ColumnType> {};
- //struct GroupSelectionPercent : Column<3, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 7; };
- struct SchemaVersion : Column<4, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
- struct NextOperationLogIndex : Column<5, NScheme::NTypeIds::Uint64> {};
- struct DefaultMaxSlots : Column<6, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 16; };
- struct InstanceId : Column<7, NScheme::NTypeIds::String> {};
- struct SelfHealEnable : Column<8, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
- struct DonorModeEnable : Column<9, NScheme::NTypeIds::Bool> { static constexpr Type Default = true; };
- struct ScrubPeriodicity : Column<10, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 86400 * 30; };
+ SeenOperational>;
+ };
+
+ struct State : Table<1> {
+ struct FixedKey : Column<1, NScheme::NTypeIds::Bool> {}; // PK, forever 'true'
+ struct NextGroupID : Column<2, Group::ID::ColumnType> {};
+ //struct GroupSelectionPercent : Column<3, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 7; };
+ struct SchemaVersion : Column<4, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
+ struct NextOperationLogIndex : Column<5, NScheme::NTypeIds::Uint64> {};
+ struct DefaultMaxSlots : Column<6, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 16; };
+ struct InstanceId : Column<7, NScheme::NTypeIds::String> {};
+ struct SelfHealEnable : Column<8, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
+ struct DonorModeEnable : Column<9, NScheme::NTypeIds::Bool> { static constexpr Type Default = true; };
+ struct ScrubPeriodicity : Column<10, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 86400 * 30; };
struct SerialManagementStage : Column<11, NScheme::NTypeIds::Uint32> { using Type = NKikimrBlobStorage::TSerialManagementStage::E; };
- struct NextStoragePoolId : Column<12, NScheme::NTypeIds::Uint64> { static constexpr Type Default = 0; };
- struct PDiskSpaceMarginPromille : Column<13, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 150; }; // 15% default margin (85% max usage)
- struct GroupReserveMin : Column<14, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
- struct GroupReservePart : Column<15, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; }; // parts per million
- struct MaxScrubbedDisksAtOnce : Column<16, NScheme::NTypeIds::Uint32> { static constexpr Type Default = Max<ui32>(); }; // no limit
+ struct NextStoragePoolId : Column<12, NScheme::NTypeIds::Uint64> { static constexpr Type Default = 0; };
+ struct PDiskSpaceMarginPromille : Column<13, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 150; }; // 15% default margin (85% max usage)
+ struct GroupReserveMin : Column<14, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
+ struct GroupReservePart : Column<15, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; }; // parts per million
+ struct MaxScrubbedDisksAtOnce : Column<16, NScheme::NTypeIds::Uint32> { static constexpr Type Default = Max<ui32>(); }; // no limit
struct PDiskSpaceColorBorder : Column<17, NScheme::NTypeIds::Uint32> { using Type = NKikimrBlobStorage::TPDiskSpaceColor::E; static constexpr Type Default = NKikimrBlobStorage::TPDiskSpaceColor::GREEN; };
-
- using TKey = TableKey<FixedKey>;
- using TColumns = TableColumns<FixedKey, NextGroupID, SchemaVersion, NextOperationLogIndex, DefaultMaxSlots,
- InstanceId, SelfHealEnable, DonorModeEnable, ScrubPeriodicity, SerialManagementStage, NextStoragePoolId,
+
+ using TKey = TableKey<FixedKey>;
+ using TColumns = TableColumns<FixedKey, NextGroupID, SchemaVersion, NextOperationLogIndex, DefaultMaxSlots,
+ InstanceId, SelfHealEnable, DonorModeEnable, ScrubPeriodicity, SerialManagementStage, NextStoragePoolId,
PDiskSpaceMarginPromille, GroupReserveMin, GroupReservePart, MaxScrubbedDisksAtOnce, PDiskSpaceColorBorder>;
- };
-
- struct VSlot : Table<5> {
- struct NodeID : Column<1, PDisk::NodeID::ColumnType> {}; // PK + FK PDisk.NodeID;
- struct PDiskID : Column<2, PDisk::PDiskID::ColumnType> {}; // PK + FK PDisk.PDiskID
- struct VSlotID : Column<3, NScheme::NTypeIds::Uint32> {}; // PK
- struct Category : Column<4, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
- struct GroupID : Column<5, Group::ID::ColumnType> {}; // FK Group.ID
- struct GroupGeneration : Column<6, Group::Generation::ColumnType> {};
- struct RingIdx : Column<7, NScheme::NTypeIds::Uint32> {};
- struct FailDomainIdx : Column<8, NScheme::NTypeIds::Uint32> {};
- struct VDiskIdx : Column<9, NScheme::NTypeIds::Uint32> {};
- struct GroupPrevGeneration : Column<10, Group::Generation::ColumnType> { static constexpr ui32 Default = 0; };
- struct Mood : Column<11, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
- struct LastSeenReady : Column<12, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
-
- using TKey = TableKey<NodeID, PDiskID, VSlotID>; // order is important
- using TColumns = TableColumns<NodeID, PDiskID, VSlotID, Category, GroupID, GroupGeneration, RingIdx, FailDomainIdx, VDiskIdx, GroupPrevGeneration, Mood, LastSeenReady>;
- };
-
- struct VDiskMetrics : Table<6> {
- struct GroupID : Column<1, Group::ID::ColumnType> {};
- struct GroupGeneration : Column<2, Group::Generation::ColumnType> {};
- struct Ring : Column<3, VSlot::RingIdx::ColumnType> {};
- struct FailDomain : Column<4, VSlot::FailDomainIdx::ColumnType> {};
- struct VDisk : Column<5, VSlot::VDiskIdx::ColumnType> {};
- struct Metrics : Column<11, NScheme::NTypeIds::String> { using Type = NKikimrBlobStorage::TVDiskMetrics; };
-
- using TKey = TableKey<GroupID, GroupGeneration, Ring, FailDomain, VDisk>;
- using TColumns = TableColumns<
- GroupID,
- GroupGeneration,
- Ring,
- FailDomain,
- VDisk,
- Metrics
- >;
- };
-
- struct PDiskMetrics : Table<7> {
- struct NodeID : Column<1, Node::ID::ColumnType> {}; // PK
- struct PDiskID : Column<2, Node::NextPDiskID::ColumnType> {}; // PK
- struct Metrics : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrBlobStorage::TPDiskMetrics; };
-
- using TKey = TableKey<NodeID, PDiskID>;
- using TColumns = TableColumns<
- NodeID,
- PDiskID,
- Metrics
- >;
- };
-
- struct GroupLatencies : Table<8> {
- struct GroupId : Column<1, NScheme::NTypeIds::Uint32> {};
- //struct GetLatencyUs : Column<2, NScheme::NTypeIds::Uint32> {};
- //struct PutLatencyUs : Column<3, NScheme::NTypeIds::Uint32> {};
- struct PutTabletLogLatencyUs : Column<4, NScheme::NTypeIds::Uint32> {};
- struct PutUserDataLatencyUs : Column<5, NScheme::NTypeIds::Uint32> {};
- struct GetFastLatencyUs : Column<6, NScheme::NTypeIds::Uint32> {};
-
- using TKey = TableKey<GroupId>;
- using TColumns = TableColumns<GroupId, PutTabletLogLatencyUs, PutUserDataLatencyUs, GetFastLatencyUs>;
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // BLOBSTORAGE CONFIGURATION USER-DEFINED TABLES
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- struct Box : Table<100> {
- struct BoxId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct Name : Column<2, NScheme::NTypeIds::Utf8> {};
- struct Generation : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<BoxId>;
- using TColumns = TableColumns<BoxId, Name, Generation>;
- };
-
- struct BoxUser : Table<101> {
- struct BoxId : Column<1, Box::BoxId::ColumnType> {};
- struct UserId : Column<2, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<BoxId, UserId>;
- using TColumns = TableColumns<BoxId, UserId>;
- };
-
- struct HostConfig : Table<102> {
- struct HostConfigId : Column<1, NScheme::NTypeIds::Uint64> {};
- struct Name : Column<2, NScheme::NTypeIds::Utf8> {};
- struct Generation : Column<3, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<HostConfigId>;
- using TColumns = TableColumns<HostConfigId, Name, Generation>;
- };
-
- struct HostConfigDrive : Table<103> {
- struct HostConfigId : Column<1, HostConfig::HostConfigId::ColumnType> {};
- struct Path : Column<2, NScheme::NTypeIds::Utf8> {};
- struct TypeCol : Column<3, NScheme::NTypeIds::Int32> { static TString GetColumnName(const TString&) { return "Type"; } using Type = NKikimrBlobStorage::EPDiskType; };
- struct SharedWithOs : Column<4, NScheme::NTypeIds::Bool> {};
- struct ReadCentric : Column<5, NScheme::NTypeIds::Bool> {};
- struct Kind : Column<6, NScheme::NTypeIds::Uint64> {};
- struct PDiskConfig : Column<7, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<HostConfigId, Path>;
- using TColumns = TableColumns<HostConfigId, Path, TypeCol, SharedWithOs, ReadCentric, Kind, PDiskConfig>;
- };
-
- struct BoxHostV2 : Table<105> {
- struct BoxId : Column<1, Box::BoxId::ColumnType> {};
- struct Fqdn : Column<2, NScheme::NTypeIds::Utf8> {};
- struct IcPort : Column<3, NScheme::NTypeIds::Int32> {};
- struct HostConfigId : Column<4, HostConfig::HostConfigId::ColumnType> {};
-
- using TKey = TableKey<BoxId, Fqdn, IcPort>;
- using TColumns = TableColumns<BoxId, Fqdn, IcPort, HostConfigId>;
- };
-
- struct BoxStoragePool : Table<120> {
- // the box this storage pool belongs to
- struct BoxId : Column<1, Box::BoxId::ColumnType> {};
- // unique identifier of the storage pool itself (must be unique to the box)
- struct StoragePoolId : Column<2, NScheme::NTypeIds::Uint64> {};
- // user-friendly name
- struct Name : Column<20, NScheme::NTypeIds::Utf8> {};
- // erasure kind for groups of the pool
- struct ErasureSpecies : Column<3, NScheme::NTypeIds::Int32> { using Type = TErasureType::EErasureSpecies; };
- // first level to distinguish between fail realms while generating groups
- struct RealmLevelBegin : Column<4, NScheme::NTypeIds::Int32> {};
- // last level to distinguish between fail realms while generating groups
- struct RealmLevelEnd : Column<5, NScheme::NTypeIds::Int32> {};
- // first level to distinguish between fail domains while generating groups
- struct DomainLevelBegin : Column<6, NScheme::NTypeIds::Int32> {};
- // last level to distinguish between fail domains while generating groups
- struct DomainLevelEnd : Column<7, NScheme::NTypeIds::Int32> {};
- // number of fail realms per single group
- struct NumFailRealms : Column<8, NScheme::NTypeIds::Int32> {};
- // number of fail domains per fail realm
- struct NumFailDomainsPerFailRealm : Column<9, NScheme::NTypeIds::Int32> {};
- // number of vdisks per fail domain
- struct NumVDisksPerFailDomain : Column<10, NScheme::NTypeIds::Int32> {};
- // kind of vdisks to create (as defined in NKikimrBlobStorage.TVDiskKind.EVDiskKind enum)
- struct VDiskKind : Column<11, NScheme::NTypeIds::Int32> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
- // how much space user wants to reserve in this storage pool (measured in bytes)
- struct SpaceBytes : Column<12, NScheme::NTypeIds::Uint64> {};
- // planned number of write IOPS
- struct WriteIOPS : Column<13, NScheme::NTypeIds::Uint64> {};
- // planned write throughput (measured in bytes per second)
- struct WriteBytesPerSecond : Column<14, NScheme::NTypeIds::Uint64> {};
- // planned number of read IOPS
- struct ReadIOPS : Column<15, NScheme::NTypeIds::Uint64> {};
- // planned read throughput (measured in bytes per second)
- struct ReadBytesPerSecond : Column<16, NScheme::NTypeIds::Uint64> {};
- // size of in-memory cache for this storage pool (measured in bytes)
- struct InMemCacheBytes : Column<17, NScheme::NTypeIds::Uint64> {};
- // user-defined nontransparent storage pool kind used for searching
- struct Kind : Column<18, NScheme::NTypeIds::Utf8> {};
- // internally defined value -- number of groups required to fulfil user requirements
- struct NumGroups : Column<19, NScheme::NTypeIds::Uint32> {};
- // configuration item generation to prevent concurrent access
- struct Generation : Column<21, NScheme::NTypeIds::Uint64> {};
- // DS_PROXY encryption params
+ };
+
+ struct VSlot : Table<5> {
+ struct NodeID : Column<1, PDisk::NodeID::ColumnType> {}; // PK + FK PDisk.NodeID;
+ struct PDiskID : Column<2, PDisk::PDiskID::ColumnType> {}; // PK + FK PDisk.PDiskID
+ struct VSlotID : Column<3, NScheme::NTypeIds::Uint32> {}; // PK
+ struct Category : Column<4, NScheme::NTypeIds::Uint64> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
+ struct GroupID : Column<5, Group::ID::ColumnType> {}; // FK Group.ID
+ struct GroupGeneration : Column<6, Group::Generation::ColumnType> {};
+ struct RingIdx : Column<7, NScheme::NTypeIds::Uint32> {};
+ struct FailDomainIdx : Column<8, NScheme::NTypeIds::Uint32> {};
+ struct VDiskIdx : Column<9, NScheme::NTypeIds::Uint32> {};
+ struct GroupPrevGeneration : Column<10, Group::Generation::ColumnType> { static constexpr ui32 Default = 0; };
+ struct Mood : Column<11, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
+ struct LastSeenReady : Column<12, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
+
+ using TKey = TableKey<NodeID, PDiskID, VSlotID>; // order is important
+ using TColumns = TableColumns<NodeID, PDiskID, VSlotID, Category, GroupID, GroupGeneration, RingIdx, FailDomainIdx, VDiskIdx, GroupPrevGeneration, Mood, LastSeenReady>;
+ };
+
+ struct VDiskMetrics : Table<6> {
+ struct GroupID : Column<1, Group::ID::ColumnType> {};
+ struct GroupGeneration : Column<2, Group::Generation::ColumnType> {};
+ struct Ring : Column<3, VSlot::RingIdx::ColumnType> {};
+ struct FailDomain : Column<4, VSlot::FailDomainIdx::ColumnType> {};
+ struct VDisk : Column<5, VSlot::VDiskIdx::ColumnType> {};
+ struct Metrics : Column<11, NScheme::NTypeIds::String> { using Type = NKikimrBlobStorage::TVDiskMetrics; };
+
+ using TKey = TableKey<GroupID, GroupGeneration, Ring, FailDomain, VDisk>;
+ using TColumns = TableColumns<
+ GroupID,
+ GroupGeneration,
+ Ring,
+ FailDomain,
+ VDisk,
+ Metrics
+ >;
+ };
+
+ struct PDiskMetrics : Table<7> {
+ struct NodeID : Column<1, Node::ID::ColumnType> {}; // PK
+ struct PDiskID : Column<2, Node::NextPDiskID::ColumnType> {}; // PK
+ struct Metrics : Column<3, NScheme::NTypeIds::String> { using Type = NKikimrBlobStorage::TPDiskMetrics; };
+
+ using TKey = TableKey<NodeID, PDiskID>;
+ using TColumns = TableColumns<
+ NodeID,
+ PDiskID,
+ Metrics
+ >;
+ };
+
+ struct GroupLatencies : Table<8> {
+ struct GroupId : Column<1, NScheme::NTypeIds::Uint32> {};
+ //struct GetLatencyUs : Column<2, NScheme::NTypeIds::Uint32> {};
+ //struct PutLatencyUs : Column<3, NScheme::NTypeIds::Uint32> {};
+ struct PutTabletLogLatencyUs : Column<4, NScheme::NTypeIds::Uint32> {};
+ struct PutUserDataLatencyUs : Column<5, NScheme::NTypeIds::Uint32> {};
+ struct GetFastLatencyUs : Column<6, NScheme::NTypeIds::Uint32> {};
+
+ using TKey = TableKey<GroupId>;
+ using TColumns = TableColumns<GroupId, PutTabletLogLatencyUs, PutUserDataLatencyUs, GetFastLatencyUs>;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BLOBSTORAGE CONFIGURATION USER-DEFINED TABLES
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ struct Box : Table<100> {
+ struct BoxId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct Name : Column<2, NScheme::NTypeIds::Utf8> {};
+ struct Generation : Column<3, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<BoxId>;
+ using TColumns = TableColumns<BoxId, Name, Generation>;
+ };
+
+ struct BoxUser : Table<101> {
+ struct BoxId : Column<1, Box::BoxId::ColumnType> {};
+ struct UserId : Column<2, NScheme::NTypeIds::String> {};
+
+ using TKey = TableKey<BoxId, UserId>;
+ using TColumns = TableColumns<BoxId, UserId>;
+ };
+
+ struct HostConfig : Table<102> {
+ struct HostConfigId : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct Name : Column<2, NScheme::NTypeIds::Utf8> {};
+ struct Generation : Column<3, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<HostConfigId>;
+ using TColumns = TableColumns<HostConfigId, Name, Generation>;
+ };
+
+ struct HostConfigDrive : Table<103> {
+ struct HostConfigId : Column<1, HostConfig::HostConfigId::ColumnType> {};
+ struct Path : Column<2, NScheme::NTypeIds::Utf8> {};
+ struct TypeCol : Column<3, NScheme::NTypeIds::Int32> { static TString GetColumnName(const TString&) { return "Type"; } using Type = NKikimrBlobStorage::EPDiskType; };
+ struct SharedWithOs : Column<4, NScheme::NTypeIds::Bool> {};
+ struct ReadCentric : Column<5, NScheme::NTypeIds::Bool> {};
+ struct Kind : Column<6, NScheme::NTypeIds::Uint64> {};
+ struct PDiskConfig : Column<7, NScheme::NTypeIds::String> {};
+
+ using TKey = TableKey<HostConfigId, Path>;
+ using TColumns = TableColumns<HostConfigId, Path, TypeCol, SharedWithOs, ReadCentric, Kind, PDiskConfig>;
+ };
+
+ struct BoxHostV2 : Table<105> {
+ struct BoxId : Column<1, Box::BoxId::ColumnType> {};
+ struct Fqdn : Column<2, NScheme::NTypeIds::Utf8> {};
+ struct IcPort : Column<3, NScheme::NTypeIds::Int32> {};
+ struct HostConfigId : Column<4, HostConfig::HostConfigId::ColumnType> {};
+
+ using TKey = TableKey<BoxId, Fqdn, IcPort>;
+ using TColumns = TableColumns<BoxId, Fqdn, IcPort, HostConfigId>;
+ };
+
+ struct BoxStoragePool : Table<120> {
+ // the box this storage pool belongs to
+ struct BoxId : Column<1, Box::BoxId::ColumnType> {};
+ // unique identifier of the storage pool itself (must be unique to the box)
+ struct StoragePoolId : Column<2, NScheme::NTypeIds::Uint64> {};
+ // user-friendly name
+ struct Name : Column<20, NScheme::NTypeIds::Utf8> {};
+ // erasure kind for groups of the pool
+ struct ErasureSpecies : Column<3, NScheme::NTypeIds::Int32> { using Type = TErasureType::EErasureSpecies; };
+ // first level to distinguish between fail realms while generating groups
+ struct RealmLevelBegin : Column<4, NScheme::NTypeIds::Int32> {};
+ // last level to distinguish between fail realms while generating groups
+ struct RealmLevelEnd : Column<5, NScheme::NTypeIds::Int32> {};
+ // first level to distinguish between fail domains while generating groups
+ struct DomainLevelBegin : Column<6, NScheme::NTypeIds::Int32> {};
+ // last level to distinguish between fail domains while generating groups
+ struct DomainLevelEnd : Column<7, NScheme::NTypeIds::Int32> {};
+ // number of fail realms per single group
+ struct NumFailRealms : Column<8, NScheme::NTypeIds::Int32> {};
+ // number of fail domains per fail realm
+ struct NumFailDomainsPerFailRealm : Column<9, NScheme::NTypeIds::Int32> {};
+ // number of vdisks per fail domain
+ struct NumVDisksPerFailDomain : Column<10, NScheme::NTypeIds::Int32> {};
+ // kind of vdisks to create (as defined in NKikimrBlobStorage.TVDiskKind.EVDiskKind enum)
+ struct VDiskKind : Column<11, NScheme::NTypeIds::Int32> { using Type = NKikimrBlobStorage::TVDiskKind::EVDiskKind; };
+ // how much space user wants to reserve in this storage pool (measured in bytes)
+ struct SpaceBytes : Column<12, NScheme::NTypeIds::Uint64> {};
+ // planned number of write IOPS
+ struct WriteIOPS : Column<13, NScheme::NTypeIds::Uint64> {};
+ // planned write throughput (measured in bytes per second)
+ struct WriteBytesPerSecond : Column<14, NScheme::NTypeIds::Uint64> {};
+ // planned number of read IOPS
+ struct ReadIOPS : Column<15, NScheme::NTypeIds::Uint64> {};
+ // planned read throughput (measured in bytes per second)
+ struct ReadBytesPerSecond : Column<16, NScheme::NTypeIds::Uint64> {};
+ // size of in-memory cache for this storage pool (measured in bytes)
+ struct InMemCacheBytes : Column<17, NScheme::NTypeIds::Uint64> {};
+ // user-defined nontransparent storage pool kind used for searching
+ struct Kind : Column<18, NScheme::NTypeIds::Utf8> {};
+ // internally defined value -- number of groups required to fulfil user requirements
+ struct NumGroups : Column<19, NScheme::NTypeIds::Uint32> {};
+ // configuration item generation to prevent concurrent access
+ struct Generation : Column<21, NScheme::NTypeIds::Uint64> {};
+ // DS_PROXY encryption params
struct EncryptionMode : Column<22, NScheme::NTypeIds::Uint32> { static constexpr Type Default = 0; };
- // scope id for the tenant
- struct SchemeshardId : Column<23, NScheme::NTypeIds::Uint64> {};
- struct PathItemId : Column<24, NScheme::NTypeIds::Uint64> {};
- // flag used to minimize correlation between groups and drives
- struct RandomizeGroupMapping : Column<25, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
-
- using TKey = TableKey<BoxId, StoragePoolId>;
-
- using TColumns = TableColumns<BoxId, StoragePoolId, Name, ErasureSpecies, RealmLevelBegin, RealmLevelEnd,
- DomainLevelBegin, DomainLevelEnd, NumFailRealms, NumFailDomainsPerFailRealm, NumVDisksPerFailDomain,
- VDiskKind, SpaceBytes, WriteIOPS, WriteBytesPerSecond, ReadIOPS, ReadBytesPerSecond, InMemCacheBytes,
- Kind, NumGroups, Generation, EncryptionMode, SchemeshardId, PathItemId, RandomizeGroupMapping>;
- };
-
- struct BoxStoragePoolUser : Table<121> {
- struct BoxId : Column<1, BoxStoragePool::BoxId::ColumnType> {};
- struct StoragePoolId : Column<2, BoxStoragePool::StoragePoolId::ColumnType> {};
- struct UserId : Column<3, BoxUser::UserId::ColumnType> {};
-
- using TKey = TableKey<BoxId, StoragePoolId, UserId>;
- using TColumns = TableColumns<BoxId, StoragePoolId, UserId>;
- };
-
- struct BoxStoragePoolPDiskFilter : Table<122> {
- struct BoxId : Column<1, BoxStoragePool::BoxId::ColumnType> {};
- struct StoragePoolId : Column<2, BoxStoragePool::StoragePoolId::ColumnType> {};
- struct TypeCol : Column<3, HostConfigDrive::TypeCol::ColumnType> { static TString GetColumnName(const TString&) { return "Type"; } using Type = NKikimrBlobStorage::EPDiskType; };
- struct SharedWithOs : Column<4, HostConfigDrive::SharedWithOs::ColumnType> {};
- struct ReadCentric : Column<5, HostConfigDrive::ReadCentric::ColumnType> {};
- struct Kind : Column<6, HostConfigDrive::Kind::ColumnType> {};
-
- using TKey = TableKey<BoxId, StoragePoolId, TypeCol, SharedWithOs, ReadCentric, Kind>;
- using TColumns = TableColumns<BoxId, StoragePoolId, TypeCol, SharedWithOs, ReadCentric, Kind>;
- };
-
- struct GroupStoragePool : Table<123> {
- struct GroupId : Column<1, Group::ID::ColumnType> {};
- struct BoxId : Column<2, BoxStoragePool::BoxId::ColumnType> {};
- struct StoragePoolId : Column<3, BoxStoragePool::StoragePoolId::ColumnType> {};
-
- using TKey = TableKey<GroupId>;
- using TColumns = TableColumns<GroupId, BoxId, StoragePoolId>;
- };
-
- static constexpr ui32 DriveStatusTableId = 124;
-
- struct OperationLog : Table<125> {
- struct Index : Column<1, NScheme::NTypeIds::Uint64> {};
- struct Timestamp : Column<2, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
- struct Request : Column<3, NScheme::NTypeIds::String> {};
- struct Response : Column<4, NScheme::NTypeIds::String> {};
- struct ExecutionTime : Column<5, NScheme::NTypeIds::Uint64> { using Type = TDuration; static constexpr Type Default = TDuration::Zero(); };
-
- using TKey = TableKey<Index>;
- using TColumns = TableColumns<Index, Timestamp, Request, Response, ExecutionTime>;
- };
-
+ // scope id for the tenant
+ struct SchemeshardId : Column<23, NScheme::NTypeIds::Uint64> {};
+ struct PathItemId : Column<24, NScheme::NTypeIds::Uint64> {};
+ // flag used to minimize correlation between groups and drives
+ struct RandomizeGroupMapping : Column<25, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
+
+ using TKey = TableKey<BoxId, StoragePoolId>;
+
+ using TColumns = TableColumns<BoxId, StoragePoolId, Name, ErasureSpecies, RealmLevelBegin, RealmLevelEnd,
+ DomainLevelBegin, DomainLevelEnd, NumFailRealms, NumFailDomainsPerFailRealm, NumVDisksPerFailDomain,
+ VDiskKind, SpaceBytes, WriteIOPS, WriteBytesPerSecond, ReadIOPS, ReadBytesPerSecond, InMemCacheBytes,
+ Kind, NumGroups, Generation, EncryptionMode, SchemeshardId, PathItemId, RandomizeGroupMapping>;
+ };
+
+ struct BoxStoragePoolUser : Table<121> {
+ struct BoxId : Column<1, BoxStoragePool::BoxId::ColumnType> {};
+ struct StoragePoolId : Column<2, BoxStoragePool::StoragePoolId::ColumnType> {};
+ struct UserId : Column<3, BoxUser::UserId::ColumnType> {};
+
+ using TKey = TableKey<BoxId, StoragePoolId, UserId>;
+ using TColumns = TableColumns<BoxId, StoragePoolId, UserId>;
+ };
+
+ struct BoxStoragePoolPDiskFilter : Table<122> {
+ struct BoxId : Column<1, BoxStoragePool::BoxId::ColumnType> {};
+ struct StoragePoolId : Column<2, BoxStoragePool::StoragePoolId::ColumnType> {};
+ struct TypeCol : Column<3, HostConfigDrive::TypeCol::ColumnType> { static TString GetColumnName(const TString&) { return "Type"; } using Type = NKikimrBlobStorage::EPDiskType; };
+ struct SharedWithOs : Column<4, HostConfigDrive::SharedWithOs::ColumnType> {};
+ struct ReadCentric : Column<5, HostConfigDrive::ReadCentric::ColumnType> {};
+ struct Kind : Column<6, HostConfigDrive::Kind::ColumnType> {};
+
+ using TKey = TableKey<BoxId, StoragePoolId, TypeCol, SharedWithOs, ReadCentric, Kind>;
+ using TColumns = TableColumns<BoxId, StoragePoolId, TypeCol, SharedWithOs, ReadCentric, Kind>;
+ };
+
+ struct GroupStoragePool : Table<123> {
+ struct GroupId : Column<1, Group::ID::ColumnType> {};
+ struct BoxId : Column<2, BoxStoragePool::BoxId::ColumnType> {};
+ struct StoragePoolId : Column<3, BoxStoragePool::StoragePoolId::ColumnType> {};
+
+ using TKey = TableKey<GroupId>;
+ using TColumns = TableColumns<GroupId, BoxId, StoragePoolId>;
+ };
+
+ static constexpr ui32 DriveStatusTableId = 124;
+
+ struct OperationLog : Table<125> {
+ struct Index : Column<1, NScheme::NTypeIds::Uint64> {};
+ struct Timestamp : Column<2, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
+ struct Request : Column<3, NScheme::NTypeIds::String> {};
+ struct Response : Column<4, NScheme::NTypeIds::String> {};
+ struct ExecutionTime : Column<5, NScheme::NTypeIds::Uint64> { using Type = TDuration; static constexpr Type Default = TDuration::Zero(); };
+
+ using TKey = TableKey<Index>;
+ using TColumns = TableColumns<Index, Timestamp, Request, Response, ExecutionTime>;
+ };
+
struct MigrationPlan : Table<126> {
enum EState : ui32 {
CREATED,
@@ -341,19 +341,19 @@ struct Schema : NIceDb::Schema {
OriginPDiskId, OriginVSlotId, TargetNodeId, TargetPDiskId, Done>;
};
- struct ScrubState : Table<128> {
- struct NodeId : Column<1, VSlot::NodeID::ColumnType> {};
- struct PDiskId : Column<2, VSlot::PDiskID::ColumnType> {};
- struct VSlotId : Column<3, VSlot::VSlotID::ColumnType> {};
- struct State : Column<5, NScheme::NTypeIds::String> {};
- struct ScrubCycleStartTime : Column<6, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
- struct ScrubCycleFinishTime : Column<8, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
- struct Success : Column<7, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
-
- using TKey = TableKey<NodeId, PDiskId, VSlotId>;
- using TColumns = TableColumns<NodeId, PDiskId, VSlotId, State, ScrubCycleStartTime, ScrubCycleFinishTime, Success>;
- };
-
+ struct ScrubState : Table<128> {
+ struct NodeId : Column<1, VSlot::NodeID::ColumnType> {};
+ struct PDiskId : Column<2, VSlot::PDiskID::ColumnType> {};
+ struct VSlotId : Column<3, VSlot::VSlotID::ColumnType> {};
+ struct State : Column<5, NScheme::NTypeIds::String> {};
+ struct ScrubCycleStartTime : Column<6, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
+ struct ScrubCycleFinishTime : Column<8, NScheme::NTypeIds::Uint64> { using Type = TInstant; static constexpr Type Default = TInstant::Zero(); };
+ struct Success : Column<7, NScheme::NTypeIds::Bool> { static constexpr Type Default = false; };
+
+ using TKey = TableKey<NodeId, PDiskId, VSlotId>;
+ using TColumns = TableColumns<NodeId, PDiskId, VSlotId, State, ScrubCycleStartTime, ScrubCycleFinishTime, Success>;
+ };
+
struct DriveSerial : Table<129> {
struct Serial : Column<1, NScheme::NTypeIds::String> {}; // PK
struct BoxId : Column<2, Box::BoxId::ColumnType> {};
@@ -369,36 +369,36 @@ struct Schema : NIceDb::Schema {
using TColumns = TableColumns<Serial, BoxId, NodeId, PDiskId, Guid, LifeStage, Kind, PDiskType, PDiskConfig>;
};
- using TTables = SchemaTables<
- Node,
- PDisk,
- Group,
- State,
- VSlot,
- VDiskMetrics,
- PDiskMetrics,
- GroupLatencies,
- Box,
- BoxUser,
- HostConfig,
- HostConfigDrive,
- BoxHostV2,
- BoxStoragePool,
- BoxStoragePoolUser,
- BoxStoragePoolPDiskFilter,
- GroupStoragePool,
+ using TTables = SchemaTables<
+ Node,
+ PDisk,
+ Group,
+ State,
+ VSlot,
+ VDiskMetrics,
+ PDiskMetrics,
+ GroupLatencies,
+ Box,
+ BoxUser,
+ HostConfig,
+ HostConfigDrive,
+ BoxHostV2,
+ BoxStoragePool,
+ BoxStoragePoolUser,
+ BoxStoragePoolPDiskFilter,
+ GroupStoragePool,
OperationLog,
MigrationPlan,
- MigrationEntry,
+ MigrationEntry,
ScrubState,
DriveSerial
- >;
-
- using TSettings = SchemaSettings<
- ExecutorLogBatching<true>,
- ExecutorLogFlushPeriod<TDuration::MicroSeconds(512).GetValue()>
- >;
-};
-
-} // NBsController
-} // NKikimr
+ >;
+
+ using TSettings = SchemaSettings<
+ ExecutorLogBatching<true>,
+ ExecutorLogFlushPeriod<TDuration::MicroSeconds(512).GetValue()>
+ >;
+};
+
+} // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/scrub.cpp b/ydb/core/mind/bscontroller/scrub.cpp
index ad4a4aff91b..e78afac91e3 100644
--- a/ydb/core/mind/bscontroller/scrub.cpp
+++ b/ydb/core/mind/bscontroller/scrub.cpp
@@ -1,830 +1,830 @@
-#include "impl.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxScrubStart : public TTransactionBase<TBlobStorageController> {
- const TVSlotId VSlotId;
- const TInstant ScrubCycleStartTime;
-
-public:
- TTxScrubStart(TBlobStorageController *controller, const TVSlotId& vslotId, TInstant scrubCycleStartTime)
- : TBase(controller)
- , VSlotId(vslotId)
- , ScrubCycleStartTime(scrubCycleStartTime)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SCRUB_START; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- if (Self->HasScrubVSlot(VSlotId)) {
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::ScrubState;
- const T::TKey::Type key(VSlotId.NodeId, VSlotId.PDiskId, VSlotId.VSlotId);
- db.Table<T>().Key(key).Update<T::ScrubCycleStartTime>(ScrubCycleStartTime);
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TBlobStorageController::TTxScrubQuantumFinished : public TTransactionBase<TBlobStorageController> {
- const TVSlotId VSlotId;
- const std::optional<TString> State;
- const bool Success;
- const TInstant Timestamp;
-
-public:
- TTxScrubQuantumFinished(TBlobStorageController *controller,
- const NKikimrBlobStorage::TEvControllerScrubQuantumFinished& r, const TInstant timestamp)
- : TBase(controller)
- , VSlotId(r.GetVSlotId())
- , State(r.HasState() ? std::make_optional(r.GetState()) : std::nullopt)
- , Success(r.GetSuccess())
- , Timestamp(timestamp)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SCRUB_QUANTUM_FINISHED; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- if (Self->HasScrubVSlot(VSlotId)) {
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::ScrubState;
- const T::TKey::Type key(VSlotId.NodeId, VSlotId.PDiskId, VSlotId.VSlotId);
- if (State) {
- db.Table<T>().Key(key).Update<T::State>(*State);
- } else {
- db.Table<T>().Key(key).UpdateToNull<T::State>();
- db.Table<T>().Key(key).Update<T::ScrubCycleFinishTime, T::Success>(Timestamp, Success);
- }
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-class TBlobStorageController::TScrubState::TImpl {
- static constexpr TDuration UnavailableResetTimeout = TDuration::Minutes(10);
-
- enum class EUserState : ui32 {
- WAITING_FOR_START = NBlobStorageController::COUNTER_DISK_SCRUB_WAITING_FOR_START,
- RUNNING = NBlobStorageController::COUNTER_DISK_SCRUB_RUNNING,
- IN_PROGRESS = NBlobStorageController::COUNTER_DISK_SCRUB_IN_PROGRESS,
- FINISHED_OK = NBlobStorageController::COUNTER_DISK_SCRUB_FINISHED_OK,
- FINISHED_ERR = NBlobStorageController::COUNTER_DISK_SCRUB_FINISHED_ERR,
- };
-
- // predicates for the reason of enqueued item being held out of queue
- struct TPredLockedByPDisk {};
- struct TPredLockedByGroup {};
- struct TPredLockedByTime {};
- struct TPredLockedByProhibitGroup {};
- struct TCandidates {};
-
- struct TVDiskItem
- : TIntrusiveListItem<TVDiskItem, TPredLockedByPDisk>
- , TIntrusiveListItem<TVDiskItem, TPredLockedByGroup>
- , TIntrusiveListItem<TVDiskItem, TPredLockedByTime>
- , TIntrusiveListItem<TVDiskItem, TPredLockedByProhibitGroup>
- , TIntrusiveListItem<TVDiskItem, TCandidates>
- {
- using Table = Schema::ScrubState;
-
- enum class EScrubState {
- IDLE, // disk did not ask for scrubbing yet
- ENQUEUED, // disk asked, but it was enqueued; must have valid position in the queue
- IN_PROGRESS, // disk is being scrubbed right now
- };
-
- const TVSlotId VSlotId;
- const TVDiskID VDiskId;
- std::optional<TString> State;
- TInstant ScrubCycleStartTime;
- TInstant ScrubCycleFinishTime;
- std::optional<bool> Success;
- EScrubState ScrubState = EScrubState::IDLE;
- ui64 Cookie = 0;
- ui64 QueueIndex = 0; // index inside the queue, or 0 if not in queue
- std::optional<EUserState> UserState;
-
- TVDiskItem(TVSlotId vslotId, TVDiskID vdiskId)
- : VSlotId(vslotId)
- , VDiskId(vdiskId)
- {}
-
- TVDiskItem(TVSlotId vslotId, TVDiskID vdiskId, std::optional<TString> state, TInstant scrubCycleStartTime,
- TInstant scrubCycleFinishTime, std::optional<bool> success)
- : VSlotId(vslotId)
- , VDiskId(vdiskId)
- , State(std::move(state))
- , ScrubCycleStartTime(scrubCycleStartTime)
- , ScrubCycleFinishTime(scrubCycleFinishTime)
- , Success(success)
- {}
-
- struct TCompare {
- bool operator ()(const TVDiskItem& x, const TVDiskItem& y) const { return x.VSlotId < y.VSlotId; }
- bool operator ()(const TVDiskItem& x, const TVSlotId& y) const { return x.VSlotId < y; }
- bool operator ()(const TVSlotId& x, const TVDiskItem& y) const { return x < y.VSlotId; }
- bool operator ()(const TVDiskItem& x, ui32 y) const { return x.VSlotId.NodeId < y; }
- using is_transparent = void;
- };
- };
-
- TBlobStorageController* const Self;
- std::set<TVDiskItem, TVDiskItem::TCompare> VDiskState;
-
- static TString ToString(TVDiskItem::EScrubState state) {
- switch (state) {
- case TVDiskItem::EScrubState::IDLE: return "IDLE";
- case TVDiskItem::EScrubState::ENQUEUED: return "ENQUEUED";
- case TVDiskItem::EScrubState::IN_PROGRESS: return "IN_PROGRESS";
- }
- Y_FAIL();
- }
-
-public:
- TImpl(TBlobStorageController *self)
- : Self(self)
- {}
-
- TActorId SelfId() const {
- return Self->SelfId();
- }
-
- void Transition(TVDiskItem *scrub, std::optional<EUserState> state) {
- if (const auto prev = std::exchange(scrub->UserState, state); prev != state) {
- if (state) {
- auto& counter = Self->TabletCounters->Simple()[static_cast<ui32>(*state)];
- counter.Add(1);
- }
- if (prev) {
- auto& counter = Self->TabletCounters->Simple()[static_cast<ui32>(*prev)];
- counter.Set(counter.Get() - 1);
- }
- }
- }
-
- void AdjustUserState(TVDiskItem *scrub) {
- if (scrub->ScrubState == TVDiskItem::EScrubState::IN_PROGRESS) {
- Transition(scrub, EUserState::IN_PROGRESS);
- } else if (scrub->State) {
- Transition(scrub, EUserState::RUNNING);
- } else if (!scrub->Success) {
- Transition(scrub, EUserState::WAITING_FOR_START);
- } else if (*scrub->Success) {
- Transition(scrub, EUserState::FINISHED_OK);
- } else {
- Transition(scrub, EUserState::FINISHED_ERR);
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev, TInstant now) {
- const auto& r = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC10, "Handle(TEvControllerScrubQueryStartQuantum)", (Msg, r));
- if (TVDiskItem *scrub = GetVDiskState(r)) {
- scrub->Cookie = ev->Cookie; // store cookie to issue correct answer later
- switch (scrub->ScrubState) {
- case TVDiskItem::EScrubState::IN_PROGRESS:
- // BSC thought that scrub was in progress, but it suddenly got restarted; we handle it like the IDLE
- // state here, but first we have to drop InProgress state
- RemoveFromInProgress(scrub, now);
- [[fallthrough]];
- case TVDiskItem::EScrubState::IDLE:
- // ordinary situation -- we assume this disk idle and it asks for scrubbing permission; try to issue
- // that permission, enqueue otherwise
- PutToQueue(scrub);
- scrub->ScrubState = TVDiskItem::EScrubState::ENQUEUED;
- ProcessQueue(now);
- break;
-
- case TVDiskItem::EScrubState::ENQUEUED:
- // item is enqueued, but the disk is asking again for this permission; maybe VDisk has just restarted
- // anyway, keep this item enqueued (with cookie updated)
- break;
- }
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev, TInstant now) {
- const auto& r = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC11, "Handle(TEvControllerScrubQuantumFinished)", (Msg, r));
- if (TVDiskItem *scrub = GetVDiskState(r)) {
- switch (scrub->ScrubState) {
- case TVDiskItem::EScrubState::IDLE:
- break;
-
- case TVDiskItem::EScrubState::ENQUEUED:
- RemoveFromQueue(scrub);
- break;
-
- case TVDiskItem::EScrubState::IN_PROGRESS:
- RemoveFromInProgress(scrub, now);
- break;
- }
- scrub->ScrubState = TVDiskItem::EScrubState::IDLE;
-
- do {
- if (r.HasState()) {
- scrub->State = r.GetState();
- } else if (r.HasSuccess()) {
- scrub->State = std::nullopt;
- scrub->ScrubCycleFinishTime = now;
- scrub->Success = r.GetSuccess();
- } else {
- break; // quantum aborted
- }
- Self->Execute(new TTxScrubQuantumFinished(Self, r, now));
- } while (false);
- AdjustUserState(scrub);
-
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_DISK_SCRUB_QUANTUM_FINISHED] += 1;
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev) {
- const auto& r = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC12, "Handle(TEvControllerScrubReportQuantumInProgress)", (Msg, r));
- if (TVDiskItem *scrub = GetVDiskState(r)) {
- switch (scrub->ScrubState) {
- case TVDiskItem::EScrubState::ENQUEUED:
- RemoveFromQueue(scrub);
- [[fallthrough]];
- case TVDiskItem::EScrubState::IDLE:
- SetInProgress(scrub);
- break;
- case TVDiskItem::EScrubState::IN_PROGRESS:
- break;
- }
- scrub->ScrubState = TVDiskItem::EScrubState::IN_PROGRESS;
- AdjustUserState(scrub);
- }
- }
-
- void OnNodeDisconnected(TNodeId nodeId, TInstant now) {
- for (auto it = VDiskState.lower_bound(nodeId); it != VDiskState.end() && it->VSlotId.NodeId == nodeId; ++it) {
- TVDiskItem *scrub = &const_cast<TVDiskItem&>(*it);
- switch (scrub->ScrubState) {
- case TVDiskItem::EScrubState::ENQUEUED:
- RemoveFromQueue(scrub);
- break;
- case TVDiskItem::EScrubState::IN_PROGRESS:
- RemoveFromInProgress(scrub, now);
- break;
- case TVDiskItem::EScrubState::IDLE:
- break;
- }
- scrub->ScrubState = TVDiskItem::EScrubState::IDLE;
- AdjustUserState(scrub);
- }
- }
-
- TVDiskItem *GetVDiskState(TVSlotId vslotId) {
- // lookup for existing items
- auto it = VDiskState.lower_bound(vslotId);
- if (it != VDiskState.end() && it->VSlotId == vslotId) {
- return const_cast<TVDiskItem*>(&*it);
- }
-
- // find VDisk id for this vslot
- TVDiskID vdiskId;
- if (TVSlotInfo *slot = Self->FindVSlot(vslotId); slot && !slot->IsBeingDeleted()) {
- vdiskId = slot->GetVDiskId();
- } else if (const auto it = Self->StaticVSlots.find(vslotId); it != Self->StaticVSlots.end()) {
- vdiskId = it->second.VDiskId;
- } else {
- return nullptr;
- }
- vdiskId.GroupGeneration = 0;
-
- // create entry for static group
- auto *scrub = const_cast<TVDiskItem*>(&*VDiskState.emplace_hint(it, vslotId, vdiskId));
- AdjustUserState(scrub);
- return scrub;
- }
-
- template<typename TProto>
- TVDiskItem *GetVDiskState(const TProto& proto) {
- return GetVDiskState(TVSlotId(proto.GetVSlotId()));
- }
-
- void AddItem(TVSlotId vslotId, std::optional<TString> state, TInstant scrubCycleStartTime,
- TInstant scrubCycleFinishTime, std::optional<bool> success) {
- TVDiskID vdiskId;
- if (TVSlotInfo *slot = Self->FindVSlot(vslotId)) {
- if (slot->IsBeingDeleted()) {
- return;
- }
- vdiskId = slot->GetVDiskId();
- } else if (const auto it = Self->StaticVSlots.find(vslotId); it != Self->StaticVSlots.end()) {
- vdiskId = it->second.VDiskId;
- } else {
- Y_FAIL_S("unexpected VSlotId# " << vslotId);
- }
- vdiskId.GroupGeneration = 0;
-
- auto [it, inserted] = VDiskState.emplace(vslotId, vdiskId, std::move(state), scrubCycleStartTime,
- scrubCycleFinishTime, success);
- Y_VERIFY(inserted);
- AdjustUserState(&const_cast<TVDiskItem&>(*it));
- }
-
- void OnDeletePDisk(TPDiskId pdiskId) {
- CurrentlyScrubbedDisks.erase(pdiskId);
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
- }
-
- void OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc, TInstant now) {
- if (const auto it = VDiskState.find(vslotId); it != VDiskState.end()) {
- TVDiskItem *scrub = &const_cast<TVDiskItem&>(*it);
- switch (scrub->ScrubState) {
- case TVDiskItem::EScrubState::IDLE:
- break;
-
- case TVDiskItem::EScrubState::ENQUEUED:
- RemoveFromQueue(scrub);
- break;
-
- case TVDiskItem::EScrubState::IN_PROGRESS:
- RemoveFromInProgress(scrub, now);
- break;
- }
-
- NIceDb::TNiceDb db(txc.DB);
- using T = Schema::ScrubState;
- db.Table<T>().Key(vslotId.GetKey()).Delete();
- Transition(scrub, std::nullopt);
- VDiskState.erase(it);
- ProcessQueue(now);
- }
- }
-
- void OnDeleteGroup(TGroupId groupId) {
- CurrentlyScrubbedGroups.erase(groupId);
- ScrubProhibitedGroups.erase(groupId);
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
- }
-
- void Render(IOutputStream& str) {
- HTML(str) {
- H3() {
- str << "Scrub state"
- << "<br/>"
- << (Self->ScrubPeriodicity != TDuration::Zero() ? TString(TStringBuilder() << "every " <<
- Self->ScrubPeriodicity) : "disabled");
- }
- auto dumpBlockedSlots = [&](const auto& value) {
- for (auto it = value.begin(); it != value.end(); ++it) {
- if (it != value.begin()) {
- str << "<br/>";
- }
- str << it->VSlotId;
- }
- };
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Scrubbed PDisks";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "PDiskId"; }
- TABLEH() { str << "Count"; }
- TABLEH() { str << "Blocked slots"; }
- }
- }
- TABLEBODY() {
- for (const auto& [key, value] : CurrentlyScrubbedDisks) {
- TABLER() {
- TABLED() { str << key; }
- TABLED() { str << value.Count; }
- TABLED() { dumpBlockedSlots(value); }
- }
- }
- }
- }
- }
- }
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Scrubbed Groups";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "GroupId"; }
- TABLEH() { str << "Count"; }
- TABLEH() { str << "Blocked slots"; }
- }
- }
- TABLEBODY() {
- for (const auto& [key, value] : CurrentlyScrubbedGroups) {
- TABLER() {
- TABLED() { str << key; }
- TABLED() { str << value.Count; }
- TABLED() { dumpBlockedSlots(value); }
- }
- }
- }
- }
- }
- }
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Groups prohibited from scrubbing";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "GroupId"; }
- TABLEH() { str << "Blocked slots"; }
- }
- }
- TABLEBODY() {
- for (const auto& [key, value] : ScrubProhibitedGroups) {
- TABLER() {
- TABLED() { str << key; }
- TABLED() { dumpBlockedSlots(value); }
- }
- }
- }
- }
- }
- }
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "VDisk queue";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "VSlotId"; }
- TABLEH() { str << "VDiskId"; }
- TABLEH() { str << "IsReady"; }
- TABLEH() { str << "State"; }
- TABLEH() { str << "ScrubCycleFinishTime"; }
- TABLEH() { str << "Success"; }
- TABLEH() { str << "ScrubCycleStartTime"; }
- TABLEH() { str << "Running"; }
- }
- }
- TABLEBODY() {
- TInstant minScrubCycleFinishTime = TInstant::Max();
- for (const auto& item : VDiskState) {
- if (item.ScrubCycleFinishTime != TInstant::Zero() &&
- item.ScrubCycleFinishTime < minScrubCycleFinishTime) {
- minScrubCycleFinishTime = item.ScrubCycleFinishTime;
- }
- }
-
- for (const auto& item : VDiskState) {
- TABLER() {
- TABLED() { str << item.VSlotId; }
- TABLED() { str << item.VDiskId; }
- TABLED() {
- if (TVSlotInfo *slot = Self->FindVSlot(item.VSlotId)) {
- str << (slot->IsReady ? "Y" : "N");
- if (CurrentlyScrubbedDisks.count(item.VSlotId.ComprisingPDiskId())) {
- str << "/N";
- }
- }
- }
- TABLED() {
- str << ToString(item.ScrubState);
- if (item.ScrubState == TVDiskItem::EScrubState::ENQUEUED) {
- str << ", " << item.QueueIndex;
- }
- }
- TABLED() {
- if (item.ScrubCycleFinishTime == minScrubCycleFinishTime) {
- str << "<b>";
- }
- if (item.ScrubCycleFinishTime != TInstant::Zero()) {
- str << item.ScrubCycleFinishTime;
- }
- if (item.ScrubCycleFinishTime == minScrubCycleFinishTime) {
- str << "</b>";
- }
- }
- TABLED() { str << (!item.Success ? "" : *item.Success ? "ok" : "error"); }
- TABLED() { str << (item.ScrubCycleStartTime != TInstant::Zero()
- ? item.ScrubCycleStartTime.ToString() : "did not start"); }
- TABLED() { str << (item.State ? "yes" : ""); }
- }
- }
- }
- }
- }
- }
- }
- }
-
- template<typename TPred>
- struct TScrubbedEntityInfo : TIntrusiveList<TVDiskItem, TPred> {
- ui32 Count = 0;
- };
-
- struct TProhibitInfo : TIntrusiveList<TVDiskItem, TPredLockedByProhibitGroup>
- {};
-
- std::unordered_map<TPDiskId, TScrubbedEntityInfo<TPredLockedByPDisk>, THash<TPDiskId>> CurrentlyScrubbedDisks;
- std::unordered_map<TGroupId, TScrubbedEntityInfo<TPredLockedByGroup>> CurrentlyScrubbedGroups;
- std::unordered_map<TGroupId, TProhibitInfo> ScrubProhibitedGroups;
- std::map<TInstant, TIntrusiveList<TVDiskItem, TPredLockedByTime>> LockedByTime;
- ui64 LastQueueIndex = 0;
- TIntrusiveList<TVDiskItem, TCandidates> Candidates;
- using TCandidateItem = TIntrusiveListItem<TVDiskItem, TCandidates>;
- size_t NumCandidates = 0;
- bool ScrubDisabled = false;
-
- void PutToQueue(TVDiskItem *scrub) {
- Y_VERIFY(!scrub->QueueIndex);
- scrub->QueueIndex = ++LastQueueIndex;
- AddCandidate(scrub);
- }
-
- void RemoveFromQueue(TVDiskItem *scrub) {
- Y_VERIFY(scrub->QueueIndex);
- scrub->QueueIndex = 0;
- static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByPDisk>*>(scrub)->Unlink();
- static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByGroup>*>(scrub)->Unlink();
- static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByTime>*>(scrub)->Unlink();
- static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByProhibitGroup>*>(scrub)->Unlink();
- if (!static_cast<TCandidateItem*>(scrub)->Empty()) {
- --NumCandidates;
- }
- static_cast<TCandidateItem*>(scrub)->Unlink();
- }
-
- bool CheckIfScrubPermitted(TVDiskItem *scrub, TInstant now) {
- Y_VERIFY(scrub->QueueIndex);
-
- if (Self->ScrubPeriodicity == TDuration::Zero()) {
- ScrubDisabled = true;
- return false; // scrub disabled
- }
-
- const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
- const TGroupId groupId = GetGroupId(scrub);
-
- if (const auto it = CurrentlyScrubbedDisks.find(pdiskId); it != CurrentlyScrubbedDisks.end()) {
- it->second.PushBack(scrub);
- } else if (const auto it = CurrentlyScrubbedGroups.find(groupId); it != CurrentlyScrubbedGroups.end()) {
- it->second.PushBack(scrub);
- } else if (const auto it = ScrubProhibitedGroups.find(groupId); it != ScrubProhibitedGroups.end()) {
- it->second.PushBack(scrub);
- } else if (scrub->Success && *scrub->Success && !scrub->State && now < scrub->ScrubCycleStartTime + Self->ScrubPeriodicity) {
- LockedByTime[scrub->ScrubCycleStartTime].PushBack(scrub);
- } else {
- return true;
- }
-
- return false;
- }
-
- void IssueScrubStartQuantum(TVDiskItem *scrub, TInstant now) {
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerScrubStartQuantum>(scrub->VSlotId.NodeId,
- scrub->VSlotId.PDiskId, scrub->VSlotId.VSlotId, scrub->State);
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSC13, "sending TEvControllerScrubStartQuantum", (Msg, ev->ToString()));
- TActivationContext::Send(new IEventHandle(MakeBlobStorageNodeWardenID(scrub->VSlotId.NodeId), Self->SelfId(),
- ev.release(), 0, scrub->Cookie));
- SetInProgress(scrub);
- if (!scrub->State) { // scrubbing has just started for this disk
- scrub->ScrubCycleStartTime = now;
- Self->Execute(new TTxScrubStart(Self, scrub->VSlotId, scrub->ScrubCycleStartTime));
- }
- }
-
- void OnTimer(TInstant now) {
- std::map<TInstant, TIntrusiveList<TVDiskItem, TPredLockedByTime>>::iterator it;
- for (it = LockedByTime.begin(); it != LockedByTime.end() && it->first + Self->ScrubPeriodicity <= now; ++it) {
- AddCandidates(it->second);
- }
- LockedByTime.erase(LockedByTime.begin(), it);
- ProcessQueue(now);
- }
-
- void OnScrubPeriodicityChange(TInstant now) {
- if (Self->ScrubPeriodicity != TDuration::Zero() && ScrubDisabled) {
- for (const TVDiskItem& item : VDiskState) {
- TVDiskItem *scrub = const_cast<TVDiskItem*>(&item);
- if (scrub->QueueIndex && CheckIfScrubPermitted(scrub, now)) {
- AddCandidate(scrub);
- }
- }
- ScrubDisabled = false;
- }
- OnTimer(now);
- }
-
- void OnMaxScrubbedDisksAtOnceChange(TInstant now) {
- ProcessQueue(now);
- }
-
- void ProcessQueue(TInstant now) {
- if (CurrentlyScrubbedDisks.size() >= Self->MaxScrubbedDisksAtOnce) {
- return;
- }
-
- // prepare a heap to traverse Candidates
- std::vector<TVDiskItem*> heap;
- heap.reserve(NumCandidates);
- for (auto& item : Candidates) {
- heap.push_back(&item);
- }
- auto comp = [](TVDiskItem *x, TVDiskItem *y) { return x->QueueIndex > y->QueueIndex; };
- std::make_heap(heap.begin(), heap.end(), comp); // make a min-heap
-
- while (!heap.empty()) {
- if (CurrentlyScrubbedDisks.size() >= Self->MaxScrubbedDisksAtOnce) {
- break;
- }
-
- // extract item with the least QueueIndex from the heap
- std::pop_heap(heap.begin(), heap.end());
- TVDiskItem *scrub = heap.back();
- heap.pop_back();
-
- // remove item from the candidates list -- we will either run it, or it will be blocked by some predicate
- static_cast<TCandidateItem*>(scrub)->Unlink();
- --NumCandidates;
-
- // some sanity checks
- Y_VERIFY(scrub == &*VDiskState.find(scrub->VSlotId));
- Y_VERIFY(scrub->ScrubState == TVDiskItem::EScrubState::ENQUEUED);
-
- // run scrubbing for this item if it is allowed
- if (CheckIfScrubPermitted(scrub, now)) {
- RemoveFromQueue(scrub);
- IssueScrubStartQuantum(scrub, now);
- scrub->ScrubState = TVDiskItem::EScrubState::IN_PROGRESS;
- AdjustUserState(scrub);
- }
- }
- }
-
- template<typename TPred>
- void AddCandidates(TIntrusiveList<TVDiskItem, TPred>& list) {
- list.ForEach([&](TVDiskItem *item) { AddCandidate(item); });
- }
-
- void AddCandidate(TVDiskItem *scrub) {
- if (static_cast<TCandidateItem*>(scrub)->Empty()) {
- Candidates.PushBack(scrub);
- ++NumCandidates;
- }
- }
-
- void RemoveFromInProgress(TVDiskItem *scrub, TInstant now) {
- const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
- const auto pdiskIt = CurrentlyScrubbedDisks.find(pdiskId);
- Y_VERIFY(pdiskIt != CurrentlyScrubbedDisks.end());
- if (!--pdiskIt->second.Count) {
- AddCandidates(pdiskIt->second);
- CurrentlyScrubbedDisks.erase(pdiskIt);
- UpdateGroupProhibition(pdiskId);
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
- }
-
- const TGroupId groupId = GetGroupId(scrub);
- const auto groupIt = CurrentlyScrubbedGroups.find(groupId);
- Y_VERIFY(groupIt != CurrentlyScrubbedGroups.end());
- if (!--groupIt->second.Count) {
- AddCandidates(groupIt->second);
- CurrentlyScrubbedGroups.erase(groupIt);
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
- }
-
- ProcessQueue(now);
- }
-
- void SetInProgress(TVDiskItem *scrub) {
- // mark PDisk as the one being scrubbed and pop out all pending items from the queue on the same PDisk
- const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
- ++CurrentlyScrubbedDisks[pdiskId].Count;
- UpdateGroupProhibition(pdiskId);
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
-
- // do the same thing for the group
- const TGroupId groupId = GetGroupId(scrub);
- ++CurrentlyScrubbedGroups[groupId].Count;
- Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
- }
-
- TGroupId GetGroupId(TVDiskItem *scrub) {
- return scrub->VDiskId.GroupID;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Group prohibition logic. Any VSlot in group should not be scrubbed if there is any chance that group will become
- // DEGRADED. We presume that every scrubbing VDisk may render PDisk unusable due to read errors and related hardware
- // issues. So we check readiness and conjunction of IsReady property of every VDisk as reported to BSC (READY state
- // is being applied only after specific amount of time) and the fact that the underlying PDisk is not being scrubbed.
- // When this property may change for the group, UpdateGroupProhibition should be called. When this property changes
- // for the whole PDisk (CurrentlyScrubbedDisks are updated), then UpdateGroupProhibition overload is called in which
- // it enumerates every slot available on the PDisk.
-
- bool CheckGroupProhibition(const TGroupInfo *group) {
- TBlobStorageGroupInfo::TGroupVDisks working(&*group->Topology);
- for (const TVSlotInfo *slot : group->VDisksInGroup) {
- if (slot->IsReady && !CurrentlyScrubbedDisks.count(slot->VSlotId.ComprisingPDiskId())) {
- working += {&*group->Topology, slot->GetShortVDiskId()};
- }
- }
- return group->Topology->QuorumChecker->OneStepFromDegradedOrWorse(~working);
- }
-
- void UpdateVDiskState(const TVSlotInfo *slot, TInstant now) {
- if (slot->Group) {
- UpdateGroupProhibition(slot->Group);
- }
- ProcessQueue(now);
- }
-
- void UpdateGroupProhibition(const TGroupInfo *group) {
- if (CheckGroupProhibition(group)) {
- ScrubProhibitedGroups.try_emplace(group->ID);
- } else if (const auto it = ScrubProhibitedGroups.find(group->ID); it != ScrubProhibitedGroups.end()) {
- AddCandidates(it->second);
- ScrubProhibitedGroups.erase(it);
- }
- }
-
- void UpdateGroupProhibition(TPDiskId pdiskId) {
- if (TPDiskInfo *pdisk = Self->FindPDisk(pdiskId)) {
- for (const auto& [id, slot] : pdisk->VSlotsOnPDisk) {
- if (slot->Group) {
- UpdateGroupProhibition(slot->Group);
- }
- }
- }
- }
-};
-
-TBlobStorageController::TScrubState::TScrubState(TBlobStorageController *self)
- : Impl(new TImpl(self))
-{}
-
-TBlobStorageController::TScrubState::~TScrubState()
-{}
-
-void TBlobStorageController::TScrubState::HandleTimer() {
- Impl->OnTimer(TActivationContext::Now());
- TActivationContext::Schedule(TDuration::Minutes(1), new IEventHandle(Impl->SelfId(), {}, new TEvPrivate::TEvScrub));
-}
-
-void TBlobStorageController::TScrubState::AddItem(TVSlotId vslotId, std::optional<TString> state,
- TInstant scrubCycleStartTime, TInstant scrubCycleFinishTime, std::optional<bool> success) {
- Impl->AddItem(vslotId, std::move(state), scrubCycleStartTime, scrubCycleFinishTime, success);
-}
-
-void TBlobStorageController::TScrubState::OnDeletePDisk(TPDiskId pdiskId) {
- Impl->OnDeletePDisk(pdiskId);
-}
-
-void TBlobStorageController::TScrubState::OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc) {
- Impl->OnDeleteVSlot(vslotId, txc, TActivationContext::Now());
-}
-
-void TBlobStorageController::TScrubState::OnDeleteGroup(TGroupId groupId) {
- Impl->OnDeleteGroup(groupId);
-}
-
-void TBlobStorageController::TScrubState::Render(IOutputStream& str) {
- Impl->Render(str);
-}
-
-void TBlobStorageController::TScrubState::OnNodeDisconnected(TNodeId nodeId) {
- Impl->OnNodeDisconnected(nodeId, TActivationContext::Now());
-}
-
-void TBlobStorageController::TScrubState::OnScrubPeriodicityChange() {
- Impl->OnScrubPeriodicityChange(TActivationContext::Now());
-}
-
-void TBlobStorageController::TScrubState::OnMaxScrubbedDisksAtOnceChange() {
- Impl->OnMaxScrubbedDisksAtOnceChange(TActivationContext::Now());
-}
-
-void TBlobStorageController::TScrubState::UpdateVDiskState(const TVSlotInfo *slot) {
- Impl->UpdateVDiskState(slot, TActivationContext::Now());
-}
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev) {
- ScrubState.Impl->Handle(ev, TActivationContext::Now());
-}
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev) {
- ScrubState.Impl->Handle(ev, TActivationContext::Now());
-}
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev) {
- ScrubState.Impl->Handle(ev);
-}
-
-}
+#include "impl.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxScrubStart : public TTransactionBase<TBlobStorageController> {
+ const TVSlotId VSlotId;
+ const TInstant ScrubCycleStartTime;
+
+public:
+ TTxScrubStart(TBlobStorageController *controller, const TVSlotId& vslotId, TInstant scrubCycleStartTime)
+ : TBase(controller)
+ , VSlotId(vslotId)
+ , ScrubCycleStartTime(scrubCycleStartTime)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SCRUB_START; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ if (Self->HasScrubVSlot(VSlotId)) {
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::ScrubState;
+ const T::TKey::Type key(VSlotId.NodeId, VSlotId.PDiskId, VSlotId.VSlotId);
+ db.Table<T>().Key(key).Update<T::ScrubCycleStartTime>(ScrubCycleStartTime);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TBlobStorageController::TTxScrubQuantumFinished : public TTransactionBase<TBlobStorageController> {
+ const TVSlotId VSlotId;
+ const std::optional<TString> State;
+ const bool Success;
+ const TInstant Timestamp;
+
+public:
+ TTxScrubQuantumFinished(TBlobStorageController *controller,
+ const NKikimrBlobStorage::TEvControllerScrubQuantumFinished& r, const TInstant timestamp)
+ : TBase(controller)
+ , VSlotId(r.GetVSlotId())
+ , State(r.HasState() ? std::make_optional(r.GetState()) : std::nullopt)
+ , Success(r.GetSuccess())
+ , Timestamp(timestamp)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SCRUB_QUANTUM_FINISHED; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ if (Self->HasScrubVSlot(VSlotId)) {
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::ScrubState;
+ const T::TKey::Type key(VSlotId.NodeId, VSlotId.PDiskId, VSlotId.VSlotId);
+ if (State) {
+ db.Table<T>().Key(key).Update<T::State>(*State);
+ } else {
+ db.Table<T>().Key(key).UpdateToNull<T::State>();
+ db.Table<T>().Key(key).Update<T::ScrubCycleFinishTime, T::Success>(Timestamp, Success);
+ }
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+class TBlobStorageController::TScrubState::TImpl {
+ static constexpr TDuration UnavailableResetTimeout = TDuration::Minutes(10);
+
+ enum class EUserState : ui32 {
+ WAITING_FOR_START = NBlobStorageController::COUNTER_DISK_SCRUB_WAITING_FOR_START,
+ RUNNING = NBlobStorageController::COUNTER_DISK_SCRUB_RUNNING,
+ IN_PROGRESS = NBlobStorageController::COUNTER_DISK_SCRUB_IN_PROGRESS,
+ FINISHED_OK = NBlobStorageController::COUNTER_DISK_SCRUB_FINISHED_OK,
+ FINISHED_ERR = NBlobStorageController::COUNTER_DISK_SCRUB_FINISHED_ERR,
+ };
+
+ // predicates for the reason of enqueued item being held out of queue
+ struct TPredLockedByPDisk {};
+ struct TPredLockedByGroup {};
+ struct TPredLockedByTime {};
+ struct TPredLockedByProhibitGroup {};
+ struct TCandidates {};
+
+ struct TVDiskItem
+ : TIntrusiveListItem<TVDiskItem, TPredLockedByPDisk>
+ , TIntrusiveListItem<TVDiskItem, TPredLockedByGroup>
+ , TIntrusiveListItem<TVDiskItem, TPredLockedByTime>
+ , TIntrusiveListItem<TVDiskItem, TPredLockedByProhibitGroup>
+ , TIntrusiveListItem<TVDiskItem, TCandidates>
+ {
+ using Table = Schema::ScrubState;
+
+ enum class EScrubState {
+ IDLE, // disk did not ask for scrubbing yet
+ ENQUEUED, // disk asked, but it was enqueued; must have valid position in the queue
+ IN_PROGRESS, // disk is being scrubbed right now
+ };
+
+ const TVSlotId VSlotId;
+ const TVDiskID VDiskId;
+ std::optional<TString> State;
+ TInstant ScrubCycleStartTime;
+ TInstant ScrubCycleFinishTime;
+ std::optional<bool> Success;
+ EScrubState ScrubState = EScrubState::IDLE;
+ ui64 Cookie = 0;
+ ui64 QueueIndex = 0; // index inside the queue, or 0 if not in queue
+ std::optional<EUserState> UserState;
+
+ TVDiskItem(TVSlotId vslotId, TVDiskID vdiskId)
+ : VSlotId(vslotId)
+ , VDiskId(vdiskId)
+ {}
+
+ TVDiskItem(TVSlotId vslotId, TVDiskID vdiskId, std::optional<TString> state, TInstant scrubCycleStartTime,
+ TInstant scrubCycleFinishTime, std::optional<bool> success)
+ : VSlotId(vslotId)
+ , VDiskId(vdiskId)
+ , State(std::move(state))
+ , ScrubCycleStartTime(scrubCycleStartTime)
+ , ScrubCycleFinishTime(scrubCycleFinishTime)
+ , Success(success)
+ {}
+
+ struct TCompare {
+ bool operator ()(const TVDiskItem& x, const TVDiskItem& y) const { return x.VSlotId < y.VSlotId; }
+ bool operator ()(const TVDiskItem& x, const TVSlotId& y) const { return x.VSlotId < y; }
+ bool operator ()(const TVSlotId& x, const TVDiskItem& y) const { return x < y.VSlotId; }
+ bool operator ()(const TVDiskItem& x, ui32 y) const { return x.VSlotId.NodeId < y; }
+ using is_transparent = void;
+ };
+ };
+
+ TBlobStorageController* const Self;
+ std::set<TVDiskItem, TVDiskItem::TCompare> VDiskState;
+
+ static TString ToString(TVDiskItem::EScrubState state) {
+ switch (state) {
+ case TVDiskItem::EScrubState::IDLE: return "IDLE";
+ case TVDiskItem::EScrubState::ENQUEUED: return "ENQUEUED";
+ case TVDiskItem::EScrubState::IN_PROGRESS: return "IN_PROGRESS";
+ }
+ Y_FAIL();
+ }
+
+public:
+ TImpl(TBlobStorageController *self)
+ : Self(self)
+ {}
+
+ TActorId SelfId() const {
+ return Self->SelfId();
+ }
+
+ void Transition(TVDiskItem *scrub, std::optional<EUserState> state) {
+ if (const auto prev = std::exchange(scrub->UserState, state); prev != state) {
+ if (state) {
+ auto& counter = Self->TabletCounters->Simple()[static_cast<ui32>(*state)];
+ counter.Add(1);
+ }
+ if (prev) {
+ auto& counter = Self->TabletCounters->Simple()[static_cast<ui32>(*prev)];
+ counter.Set(counter.Get() - 1);
+ }
+ }
+ }
+
+ void AdjustUserState(TVDiskItem *scrub) {
+ if (scrub->ScrubState == TVDiskItem::EScrubState::IN_PROGRESS) {
+ Transition(scrub, EUserState::IN_PROGRESS);
+ } else if (scrub->State) {
+ Transition(scrub, EUserState::RUNNING);
+ } else if (!scrub->Success) {
+ Transition(scrub, EUserState::WAITING_FOR_START);
+ } else if (*scrub->Success) {
+ Transition(scrub, EUserState::FINISHED_OK);
+ } else {
+ Transition(scrub, EUserState::FINISHED_ERR);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev, TInstant now) {
+ const auto& r = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC10, "Handle(TEvControllerScrubQueryStartQuantum)", (Msg, r));
+ if (TVDiskItem *scrub = GetVDiskState(r)) {
+ scrub->Cookie = ev->Cookie; // store cookie to issue correct answer later
+ switch (scrub->ScrubState) {
+ case TVDiskItem::EScrubState::IN_PROGRESS:
+ // BSC thought that scrub was in progress, but it suddenly got restarted; we handle it like the IDLE
+ // state here, but first we have to drop InProgress state
+ RemoveFromInProgress(scrub, now);
+ [[fallthrough]];
+ case TVDiskItem::EScrubState::IDLE:
+ // ordinary situation -- we assume this disk idle and it asks for scrubbing permission; try to issue
+ // that permission, enqueue otherwise
+ PutToQueue(scrub);
+ scrub->ScrubState = TVDiskItem::EScrubState::ENQUEUED;
+ ProcessQueue(now);
+ break;
+
+ case TVDiskItem::EScrubState::ENQUEUED:
+ // item is enqueued, but the disk is asking again for this permission; maybe VDisk has just restarted
+ // anyway, keep this item enqueued (with cookie updated)
+ break;
+ }
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev, TInstant now) {
+ const auto& r = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC11, "Handle(TEvControllerScrubQuantumFinished)", (Msg, r));
+ if (TVDiskItem *scrub = GetVDiskState(r)) {
+ switch (scrub->ScrubState) {
+ case TVDiskItem::EScrubState::IDLE:
+ break;
+
+ case TVDiskItem::EScrubState::ENQUEUED:
+ RemoveFromQueue(scrub);
+ break;
+
+ case TVDiskItem::EScrubState::IN_PROGRESS:
+ RemoveFromInProgress(scrub, now);
+ break;
+ }
+ scrub->ScrubState = TVDiskItem::EScrubState::IDLE;
+
+ do {
+ if (r.HasState()) {
+ scrub->State = r.GetState();
+ } else if (r.HasSuccess()) {
+ scrub->State = std::nullopt;
+ scrub->ScrubCycleFinishTime = now;
+ scrub->Success = r.GetSuccess();
+ } else {
+ break; // quantum aborted
+ }
+ Self->Execute(new TTxScrubQuantumFinished(Self, r, now));
+ } while (false);
+ AdjustUserState(scrub);
+
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_DISK_SCRUB_QUANTUM_FINISHED] += 1;
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev) {
+ const auto& r = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC12, "Handle(TEvControllerScrubReportQuantumInProgress)", (Msg, r));
+ if (TVDiskItem *scrub = GetVDiskState(r)) {
+ switch (scrub->ScrubState) {
+ case TVDiskItem::EScrubState::ENQUEUED:
+ RemoveFromQueue(scrub);
+ [[fallthrough]];
+ case TVDiskItem::EScrubState::IDLE:
+ SetInProgress(scrub);
+ break;
+ case TVDiskItem::EScrubState::IN_PROGRESS:
+ break;
+ }
+ scrub->ScrubState = TVDiskItem::EScrubState::IN_PROGRESS;
+ AdjustUserState(scrub);
+ }
+ }
+
+ void OnNodeDisconnected(TNodeId nodeId, TInstant now) {
+ for (auto it = VDiskState.lower_bound(nodeId); it != VDiskState.end() && it->VSlotId.NodeId == nodeId; ++it) {
+ TVDiskItem *scrub = &const_cast<TVDiskItem&>(*it);
+ switch (scrub->ScrubState) {
+ case TVDiskItem::EScrubState::ENQUEUED:
+ RemoveFromQueue(scrub);
+ break;
+ case TVDiskItem::EScrubState::IN_PROGRESS:
+ RemoveFromInProgress(scrub, now);
+ break;
+ case TVDiskItem::EScrubState::IDLE:
+ break;
+ }
+ scrub->ScrubState = TVDiskItem::EScrubState::IDLE;
+ AdjustUserState(scrub);
+ }
+ }
+
+ TVDiskItem *GetVDiskState(TVSlotId vslotId) {
+ // lookup for existing items
+ auto it = VDiskState.lower_bound(vslotId);
+ if (it != VDiskState.end() && it->VSlotId == vslotId) {
+ return const_cast<TVDiskItem*>(&*it);
+ }
+
+ // find VDisk id for this vslot
+ TVDiskID vdiskId;
+ if (TVSlotInfo *slot = Self->FindVSlot(vslotId); slot && !slot->IsBeingDeleted()) {
+ vdiskId = slot->GetVDiskId();
+ } else if (const auto it = Self->StaticVSlots.find(vslotId); it != Self->StaticVSlots.end()) {
+ vdiskId = it->second.VDiskId;
+ } else {
+ return nullptr;
+ }
+ vdiskId.GroupGeneration = 0;
+
+ // create entry for static group
+ auto *scrub = const_cast<TVDiskItem*>(&*VDiskState.emplace_hint(it, vslotId, vdiskId));
+ AdjustUserState(scrub);
+ return scrub;
+ }
+
+ template<typename TProto>
+ TVDiskItem *GetVDiskState(const TProto& proto) {
+ return GetVDiskState(TVSlotId(proto.GetVSlotId()));
+ }
+
+ void AddItem(TVSlotId vslotId, std::optional<TString> state, TInstant scrubCycleStartTime,
+ TInstant scrubCycleFinishTime, std::optional<bool> success) {
+ TVDiskID vdiskId;
+ if (TVSlotInfo *slot = Self->FindVSlot(vslotId)) {
+ if (slot->IsBeingDeleted()) {
+ return;
+ }
+ vdiskId = slot->GetVDiskId();
+ } else if (const auto it = Self->StaticVSlots.find(vslotId); it != Self->StaticVSlots.end()) {
+ vdiskId = it->second.VDiskId;
+ } else {
+ Y_FAIL_S("unexpected VSlotId# " << vslotId);
+ }
+ vdiskId.GroupGeneration = 0;
+
+ auto [it, inserted] = VDiskState.emplace(vslotId, vdiskId, std::move(state), scrubCycleStartTime,
+ scrubCycleFinishTime, success);
+ Y_VERIFY(inserted);
+ AdjustUserState(&const_cast<TVDiskItem&>(*it));
+ }
+
+ void OnDeletePDisk(TPDiskId pdiskId) {
+ CurrentlyScrubbedDisks.erase(pdiskId);
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
+ }
+
+ void OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc, TInstant now) {
+ if (const auto it = VDiskState.find(vslotId); it != VDiskState.end()) {
+ TVDiskItem *scrub = &const_cast<TVDiskItem&>(*it);
+ switch (scrub->ScrubState) {
+ case TVDiskItem::EScrubState::IDLE:
+ break;
+
+ case TVDiskItem::EScrubState::ENQUEUED:
+ RemoveFromQueue(scrub);
+ break;
+
+ case TVDiskItem::EScrubState::IN_PROGRESS:
+ RemoveFromInProgress(scrub, now);
+ break;
+ }
+
+ NIceDb::TNiceDb db(txc.DB);
+ using T = Schema::ScrubState;
+ db.Table<T>().Key(vslotId.GetKey()).Delete();
+ Transition(scrub, std::nullopt);
+ VDiskState.erase(it);
+ ProcessQueue(now);
+ }
+ }
+
+ void OnDeleteGroup(TGroupId groupId) {
+ CurrentlyScrubbedGroups.erase(groupId);
+ ScrubProhibitedGroups.erase(groupId);
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
+ }
+
+ void Render(IOutputStream& str) {
+ HTML(str) {
+ H3() {
+ str << "Scrub state"
+ << "<br/>"
+ << (Self->ScrubPeriodicity != TDuration::Zero() ? TString(TStringBuilder() << "every " <<
+ Self->ScrubPeriodicity) : "disabled");
+ }
+ auto dumpBlockedSlots = [&](const auto& value) {
+ for (auto it = value.begin(); it != value.end(); ++it) {
+ if (it != value.begin()) {
+ str << "<br/>";
+ }
+ str << it->VSlotId;
+ }
+ };
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Scrubbed PDisks";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "PDiskId"; }
+ TABLEH() { str << "Count"; }
+ TABLEH() { str << "Blocked slots"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& [key, value] : CurrentlyScrubbedDisks) {
+ TABLER() {
+ TABLED() { str << key; }
+ TABLED() { str << value.Count; }
+ TABLED() { dumpBlockedSlots(value); }
+ }
+ }
+ }
+ }
+ }
+ }
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Scrubbed Groups";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "GroupId"; }
+ TABLEH() { str << "Count"; }
+ TABLEH() { str << "Blocked slots"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& [key, value] : CurrentlyScrubbedGroups) {
+ TABLER() {
+ TABLED() { str << key; }
+ TABLED() { str << value.Count; }
+ TABLED() { dumpBlockedSlots(value); }
+ }
+ }
+ }
+ }
+ }
+ }
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Groups prohibited from scrubbing";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "GroupId"; }
+ TABLEH() { str << "Blocked slots"; }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& [key, value] : ScrubProhibitedGroups) {
+ TABLER() {
+ TABLED() { str << key; }
+ TABLED() { dumpBlockedSlots(value); }
+ }
+ }
+ }
+ }
+ }
+ }
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "VDisk queue";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "VSlotId"; }
+ TABLEH() { str << "VDiskId"; }
+ TABLEH() { str << "IsReady"; }
+ TABLEH() { str << "State"; }
+ TABLEH() { str << "ScrubCycleFinishTime"; }
+ TABLEH() { str << "Success"; }
+ TABLEH() { str << "ScrubCycleStartTime"; }
+ TABLEH() { str << "Running"; }
+ }
+ }
+ TABLEBODY() {
+ TInstant minScrubCycleFinishTime = TInstant::Max();
+ for (const auto& item : VDiskState) {
+ if (item.ScrubCycleFinishTime != TInstant::Zero() &&
+ item.ScrubCycleFinishTime < minScrubCycleFinishTime) {
+ minScrubCycleFinishTime = item.ScrubCycleFinishTime;
+ }
+ }
+
+ for (const auto& item : VDiskState) {
+ TABLER() {
+ TABLED() { str << item.VSlotId; }
+ TABLED() { str << item.VDiskId; }
+ TABLED() {
+ if (TVSlotInfo *slot = Self->FindVSlot(item.VSlotId)) {
+ str << (slot->IsReady ? "Y" : "N");
+ if (CurrentlyScrubbedDisks.count(item.VSlotId.ComprisingPDiskId())) {
+ str << "/N";
+ }
+ }
+ }
+ TABLED() {
+ str << ToString(item.ScrubState);
+ if (item.ScrubState == TVDiskItem::EScrubState::ENQUEUED) {
+ str << ", " << item.QueueIndex;
+ }
+ }
+ TABLED() {
+ if (item.ScrubCycleFinishTime == minScrubCycleFinishTime) {
+ str << "<b>";
+ }
+ if (item.ScrubCycleFinishTime != TInstant::Zero()) {
+ str << item.ScrubCycleFinishTime;
+ }
+ if (item.ScrubCycleFinishTime == minScrubCycleFinishTime) {
+ str << "</b>";
+ }
+ }
+ TABLED() { str << (!item.Success ? "" : *item.Success ? "ok" : "error"); }
+ TABLED() { str << (item.ScrubCycleStartTime != TInstant::Zero()
+ ? item.ScrubCycleStartTime.ToString() : "did not start"); }
+ TABLED() { str << (item.State ? "yes" : ""); }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ template<typename TPred>
+ struct TScrubbedEntityInfo : TIntrusiveList<TVDiskItem, TPred> {
+ ui32 Count = 0;
+ };
+
+ struct TProhibitInfo : TIntrusiveList<TVDiskItem, TPredLockedByProhibitGroup>
+ {};
+
+ std::unordered_map<TPDiskId, TScrubbedEntityInfo<TPredLockedByPDisk>, THash<TPDiskId>> CurrentlyScrubbedDisks;
+ std::unordered_map<TGroupId, TScrubbedEntityInfo<TPredLockedByGroup>> CurrentlyScrubbedGroups;
+ std::unordered_map<TGroupId, TProhibitInfo> ScrubProhibitedGroups;
+ std::map<TInstant, TIntrusiveList<TVDiskItem, TPredLockedByTime>> LockedByTime;
+ ui64 LastQueueIndex = 0;
+ TIntrusiveList<TVDiskItem, TCandidates> Candidates;
+ using TCandidateItem = TIntrusiveListItem<TVDiskItem, TCandidates>;
+ size_t NumCandidates = 0;
+ bool ScrubDisabled = false;
+
+ void PutToQueue(TVDiskItem *scrub) {
+ Y_VERIFY(!scrub->QueueIndex);
+ scrub->QueueIndex = ++LastQueueIndex;
+ AddCandidate(scrub);
+ }
+
+ void RemoveFromQueue(TVDiskItem *scrub) {
+ Y_VERIFY(scrub->QueueIndex);
+ scrub->QueueIndex = 0;
+ static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByPDisk>*>(scrub)->Unlink();
+ static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByGroup>*>(scrub)->Unlink();
+ static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByTime>*>(scrub)->Unlink();
+ static_cast<TIntrusiveListItem<TVDiskItem, TPredLockedByProhibitGroup>*>(scrub)->Unlink();
+ if (!static_cast<TCandidateItem*>(scrub)->Empty()) {
+ --NumCandidates;
+ }
+ static_cast<TCandidateItem*>(scrub)->Unlink();
+ }
+
+ bool CheckIfScrubPermitted(TVDiskItem *scrub, TInstant now) {
+ Y_VERIFY(scrub->QueueIndex);
+
+ if (Self->ScrubPeriodicity == TDuration::Zero()) {
+ ScrubDisabled = true;
+ return false; // scrub disabled
+ }
+
+ const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
+ const TGroupId groupId = GetGroupId(scrub);
+
+ if (const auto it = CurrentlyScrubbedDisks.find(pdiskId); it != CurrentlyScrubbedDisks.end()) {
+ it->second.PushBack(scrub);
+ } else if (const auto it = CurrentlyScrubbedGroups.find(groupId); it != CurrentlyScrubbedGroups.end()) {
+ it->second.PushBack(scrub);
+ } else if (const auto it = ScrubProhibitedGroups.find(groupId); it != ScrubProhibitedGroups.end()) {
+ it->second.PushBack(scrub);
+ } else if (scrub->Success && *scrub->Success && !scrub->State && now < scrub->ScrubCycleStartTime + Self->ScrubPeriodicity) {
+ LockedByTime[scrub->ScrubCycleStartTime].PushBack(scrub);
+ } else {
+ return true;
+ }
+
+ return false;
+ }
+
+ void IssueScrubStartQuantum(TVDiskItem *scrub, TInstant now) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerScrubStartQuantum>(scrub->VSlotId.NodeId,
+ scrub->VSlotId.PDiskId, scrub->VSlotId.VSlotId, scrub->State);
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSC13, "sending TEvControllerScrubStartQuantum", (Msg, ev->ToString()));
+ TActivationContext::Send(new IEventHandle(MakeBlobStorageNodeWardenID(scrub->VSlotId.NodeId), Self->SelfId(),
+ ev.release(), 0, scrub->Cookie));
+ SetInProgress(scrub);
+ if (!scrub->State) { // scrubbing has just started for this disk
+ scrub->ScrubCycleStartTime = now;
+ Self->Execute(new TTxScrubStart(Self, scrub->VSlotId, scrub->ScrubCycleStartTime));
+ }
+ }
+
+ void OnTimer(TInstant now) {
+ std::map<TInstant, TIntrusiveList<TVDiskItem, TPredLockedByTime>>::iterator it;
+ for (it = LockedByTime.begin(); it != LockedByTime.end() && it->first + Self->ScrubPeriodicity <= now; ++it) {
+ AddCandidates(it->second);
+ }
+ LockedByTime.erase(LockedByTime.begin(), it);
+ ProcessQueue(now);
+ }
+
+ void OnScrubPeriodicityChange(TInstant now) {
+ if (Self->ScrubPeriodicity != TDuration::Zero() && ScrubDisabled) {
+ for (const TVDiskItem& item : VDiskState) {
+ TVDiskItem *scrub = const_cast<TVDiskItem*>(&item);
+ if (scrub->QueueIndex && CheckIfScrubPermitted(scrub, now)) {
+ AddCandidate(scrub);
+ }
+ }
+ ScrubDisabled = false;
+ }
+ OnTimer(now);
+ }
+
+ void OnMaxScrubbedDisksAtOnceChange(TInstant now) {
+ ProcessQueue(now);
+ }
+
+ void ProcessQueue(TInstant now) {
+ if (CurrentlyScrubbedDisks.size() >= Self->MaxScrubbedDisksAtOnce) {
+ return;
+ }
+
+ // prepare a heap to traverse Candidates
+ std::vector<TVDiskItem*> heap;
+ heap.reserve(NumCandidates);
+ for (auto& item : Candidates) {
+ heap.push_back(&item);
+ }
+ auto comp = [](TVDiskItem *x, TVDiskItem *y) { return x->QueueIndex > y->QueueIndex; };
+ std::make_heap(heap.begin(), heap.end(), comp); // make a min-heap
+
+ while (!heap.empty()) {
+ if (CurrentlyScrubbedDisks.size() >= Self->MaxScrubbedDisksAtOnce) {
+ break;
+ }
+
+ // extract item with the least QueueIndex from the heap
+ std::pop_heap(heap.begin(), heap.end());
+ TVDiskItem *scrub = heap.back();
+ heap.pop_back();
+
+ // remove item from the candidates list -- we will either run it, or it will be blocked by some predicate
+ static_cast<TCandidateItem*>(scrub)->Unlink();
+ --NumCandidates;
+
+ // some sanity checks
+ Y_VERIFY(scrub == &*VDiskState.find(scrub->VSlotId));
+ Y_VERIFY(scrub->ScrubState == TVDiskItem::EScrubState::ENQUEUED);
+
+ // run scrubbing for this item if it is allowed
+ if (CheckIfScrubPermitted(scrub, now)) {
+ RemoveFromQueue(scrub);
+ IssueScrubStartQuantum(scrub, now);
+ scrub->ScrubState = TVDiskItem::EScrubState::IN_PROGRESS;
+ AdjustUserState(scrub);
+ }
+ }
+ }
+
+ template<typename TPred>
+ void AddCandidates(TIntrusiveList<TVDiskItem, TPred>& list) {
+ list.ForEach([&](TVDiskItem *item) { AddCandidate(item); });
+ }
+
+ void AddCandidate(TVDiskItem *scrub) {
+ if (static_cast<TCandidateItem*>(scrub)->Empty()) {
+ Candidates.PushBack(scrub);
+ ++NumCandidates;
+ }
+ }
+
+ void RemoveFromInProgress(TVDiskItem *scrub, TInstant now) {
+ const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
+ const auto pdiskIt = CurrentlyScrubbedDisks.find(pdiskId);
+ Y_VERIFY(pdiskIt != CurrentlyScrubbedDisks.end());
+ if (!--pdiskIt->second.Count) {
+ AddCandidates(pdiskIt->second);
+ CurrentlyScrubbedDisks.erase(pdiskIt);
+ UpdateGroupProhibition(pdiskId);
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
+ }
+
+ const TGroupId groupId = GetGroupId(scrub);
+ const auto groupIt = CurrentlyScrubbedGroups.find(groupId);
+ Y_VERIFY(groupIt != CurrentlyScrubbedGroups.end());
+ if (!--groupIt->second.Count) {
+ AddCandidates(groupIt->second);
+ CurrentlyScrubbedGroups.erase(groupIt);
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
+ }
+
+ ProcessQueue(now);
+ }
+
+ void SetInProgress(TVDiskItem *scrub) {
+ // mark PDisk as the one being scrubbed and pop out all pending items from the queue on the same PDisk
+ const TPDiskId pdiskId = scrub->VSlotId.ComprisingPDiskId();
+ ++CurrentlyScrubbedDisks[pdiskId].Count;
+ UpdateGroupProhibition(pdiskId);
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_DISKS].Set(CurrentlyScrubbedDisks.size());
+
+ // do the same thing for the group
+ const TGroupId groupId = GetGroupId(scrub);
+ ++CurrentlyScrubbedGroups[groupId].Count;
+ Self->TabletCounters->Simple()[NBlobStorageController::COUNTER_DISK_SCRUB_CUR_GROUPS].Set(CurrentlyScrubbedGroups.size());
+ }
+
+ TGroupId GetGroupId(TVDiskItem *scrub) {
+ return scrub->VDiskId.GroupID;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Group prohibition logic. Any VSlot in group should not be scrubbed if there is any chance that group will become
+ // DEGRADED. We presume that every scrubbing VDisk may render PDisk unusable due to read errors and related hardware
+ // issues. So we check readiness and conjunction of IsReady property of every VDisk as reported to BSC (READY state
+ // is being applied only after specific amount of time) and the fact that the underlying PDisk is not being scrubbed.
+ // When this property may change for the group, UpdateGroupProhibition should be called. When this property changes
+ // for the whole PDisk (CurrentlyScrubbedDisks are updated), then UpdateGroupProhibition overload is called in which
+ // it enumerates every slot available on the PDisk.
+
+ bool CheckGroupProhibition(const TGroupInfo *group) {
+ TBlobStorageGroupInfo::TGroupVDisks working(&*group->Topology);
+ for (const TVSlotInfo *slot : group->VDisksInGroup) {
+ if (slot->IsReady && !CurrentlyScrubbedDisks.count(slot->VSlotId.ComprisingPDiskId())) {
+ working += {&*group->Topology, slot->GetShortVDiskId()};
+ }
+ }
+ return group->Topology->QuorumChecker->OneStepFromDegradedOrWorse(~working);
+ }
+
+ void UpdateVDiskState(const TVSlotInfo *slot, TInstant now) {
+ if (slot->Group) {
+ UpdateGroupProhibition(slot->Group);
+ }
+ ProcessQueue(now);
+ }
+
+ void UpdateGroupProhibition(const TGroupInfo *group) {
+ if (CheckGroupProhibition(group)) {
+ ScrubProhibitedGroups.try_emplace(group->ID);
+ } else if (const auto it = ScrubProhibitedGroups.find(group->ID); it != ScrubProhibitedGroups.end()) {
+ AddCandidates(it->second);
+ ScrubProhibitedGroups.erase(it);
+ }
+ }
+
+ void UpdateGroupProhibition(TPDiskId pdiskId) {
+ if (TPDiskInfo *pdisk = Self->FindPDisk(pdiskId)) {
+ for (const auto& [id, slot] : pdisk->VSlotsOnPDisk) {
+ if (slot->Group) {
+ UpdateGroupProhibition(slot->Group);
+ }
+ }
+ }
+ }
+};
+
+TBlobStorageController::TScrubState::TScrubState(TBlobStorageController *self)
+ : Impl(new TImpl(self))
+{}
+
+TBlobStorageController::TScrubState::~TScrubState()
+{}
+
+void TBlobStorageController::TScrubState::HandleTimer() {
+ Impl->OnTimer(TActivationContext::Now());
+ TActivationContext::Schedule(TDuration::Minutes(1), new IEventHandle(Impl->SelfId(), {}, new TEvPrivate::TEvScrub));
+}
+
+void TBlobStorageController::TScrubState::AddItem(TVSlotId vslotId, std::optional<TString> state,
+ TInstant scrubCycleStartTime, TInstant scrubCycleFinishTime, std::optional<bool> success) {
+ Impl->AddItem(vslotId, std::move(state), scrubCycleStartTime, scrubCycleFinishTime, success);
+}
+
+void TBlobStorageController::TScrubState::OnDeletePDisk(TPDiskId pdiskId) {
+ Impl->OnDeletePDisk(pdiskId);
+}
+
+void TBlobStorageController::TScrubState::OnDeleteVSlot(TVSlotId vslotId, TTransactionContext& txc) {
+ Impl->OnDeleteVSlot(vslotId, txc, TActivationContext::Now());
+}
+
+void TBlobStorageController::TScrubState::OnDeleteGroup(TGroupId groupId) {
+ Impl->OnDeleteGroup(groupId);
+}
+
+void TBlobStorageController::TScrubState::Render(IOutputStream& str) {
+ Impl->Render(str);
+}
+
+void TBlobStorageController::TScrubState::OnNodeDisconnected(TNodeId nodeId) {
+ Impl->OnNodeDisconnected(nodeId, TActivationContext::Now());
+}
+
+void TBlobStorageController::TScrubState::OnScrubPeriodicityChange() {
+ Impl->OnScrubPeriodicityChange(TActivationContext::Now());
+}
+
+void TBlobStorageController::TScrubState::OnMaxScrubbedDisksAtOnceChange() {
+ Impl->OnMaxScrubbedDisksAtOnceChange(TActivationContext::Now());
+}
+
+void TBlobStorageController::TScrubState::UpdateVDiskState(const TVSlotInfo *slot) {
+ Impl->UpdateVDiskState(slot, TActivationContext::Now());
+}
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubQueryStartQuantum::TPtr ev) {
+ ScrubState.Impl->Handle(ev, TActivationContext::Now());
+}
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubQuantumFinished::TPtr ev) {
+ ScrubState.Impl->Handle(ev, TActivationContext::Now());
+}
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerScrubReportQuantumInProgress::TPtr ev) {
+ ScrubState.Impl->Handle(ev);
+}
+
+}
diff --git a/ydb/core/mind/bscontroller/select_groups.cpp b/ydb/core/mind/bscontroller/select_groups.cpp
index 50c438dec45..fa3ea1a3f04 100644
--- a/ydb/core/mind/bscontroller/select_groups.cpp
+++ b/ydb/core/mind/bscontroller/select_groups.cpp
@@ -1,135 +1,135 @@
-#include "impl.h"
-#include "select_groups.h"
-
-namespace NKikimr::NBsController {
-
-class TBlobStorageController::TTxSelectGroups : public TTransactionBase<TBlobStorageController> {
- TEvBlobStorage::TEvControllerSelectGroups::TPtr Request;
- std::unique_ptr<IEventHandle> Response;
-
-public:
- TTxSelectGroups(TEvBlobStorage::TEvControllerSelectGroups::TPtr& ev, TBlobStorageController *controller)
- : TTransactionBase(controller)
- , Request(ev)
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SELECT_GROUPS; }
-
- bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
- Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_SELECT_GROUPS_COUNT].Increment(1);
- TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_SELECT_GROUPS_USEC);
-
- auto request = std::move(Request);
-
- THPTimer timer;
-
- const auto& record = request->Get()->Record;
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG01, "Handle TEvControllerSelectGroups", (Request, record));
-
- auto result = MakeHolder<TEvBlobStorage::TEvControllerSelectGroupsResult>();
- auto& out = result->Record;
- out.SetStatus(NKikimrProto::OK);
- out.SetNewStyleQuerySupported(true);
-
- if (!record.GetReturnAllMatchingGroups()) {
- Y_VERIFY_DEBUG(false, "obsolete command");
- out.SetStatus(NKikimrProto::ERROR);
- } else {
- TVector<const TGroupInfo*> groups;
-
- for (const auto& params : record.GetGroupParameters()) {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG02, "Searching for group with parameters", (Params, params));
-
- if (!TGroupSelector::PopulateGroups(groups, params, *Self)) {
- STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXSG03, "Handle TEvControllerSelectGroups: invalid parameters requested",
- (Params, params));
- out.SetStatus(NKikimrProto::ERROR);
- break;
- }
-
- auto *pb = out.AddMatchingGroups();
- for (const TGroupInfo *group : groups) {
- if (!group->Down && (group->SeenOperational || !record.GetOnlySeenOperational())) {
- auto *reportedGroup = pb->AddGroups();
- reportedGroup->SetErasureSpecies(group->ErasureSpecies);
- reportedGroup->SetGroupID(group->ID);
- reportedGroup->SetStoragePoolName(Self->StoragePools.at(group->StoragePoolId).Name);
- group->FillInGroupParameters(reportedGroup);
- }
- }
- }
- }
-
- if (record.GetBlockUntilAllResourcesAreComplete()) {
- auto it = Self->SelectGroupsQueue.emplace(Self->SelectGroupsQueue.end(), request->Sender, request->Cookie,
- std::move(result));
- Self->ProcessSelectGroupsQueueItem(it);
- } else {
- STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG04, "TEvControllerSelectGroups finished", (Result, result->Record));
- Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), result.Release(), 0, request->Cookie);
-
- const TDuration passed = TDuration::Seconds(timer.Passed());
- Self->TabletCounters->Percentile()[NBlobStorageController::COUNTER_PERCENTILE_SELECT_GROUPS].IncrementFor(passed.MicroSeconds());
- }
-
- return true;
- }
-
- void Complete(const TActorContext&) override {
- if (Response) {
- TActivationContext::Send(Response.release());
- }
- }
-};
-
-void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerSelectGroups::TPtr &ev) {
- Execute(new TTxSelectGroups(ev, this));
-}
-
-void TBlobStorageController::ProcessSelectGroupsQueueItem(TList<TSelectGroupsQueueItem>::iterator it) {
- for (const TPDiskId& key : std::exchange(it->BlockedPDisks, {})) {
- const ui32 num = PDiskToQueue.erase(std::make_pair(key, it));
- Y_VERIFY(num);
- }
-
- auto& record = it->Event->Record;
- for (size_t i = 0; i < record.MatchingGroupsSize(); ++i) {
- auto& mg = *record.MutableMatchingGroups(i);
- for (size_t j = 0; j < mg.GroupsSize(); ++j) {
- auto& g = *mg.MutableGroups(j);
-
- const auto hasResources = [&] {
- const auto& assured = g.GetAssuredResources();
- const auto& current = g.GetCurrentResources();
- return assured.HasSpace()
- && assured.HasIOPS()
- && assured.HasReadThroughput()
- && assured.HasWriteThroughput()
- && current.HasSpace()
- && current.HasIOPS()
- && current.HasReadThroughput()
- && current.HasWriteThroughput();
-
- };
-
- if (TGroupInfo *group = FindGroup(g.GetGroupID()); group && !hasResources()) {
- group->FillInGroupParameters(&g);
- if (!hasResources()) {
- // any of PDisks will do
- for (const TVSlotInfo *vslot : group->VDisksInGroup) {
- const TPDiskId pdiskId = vslot->VSlotId.ComprisingPDiskId();
- it->BlockedPDisks.insert(pdiskId);
- PDiskToQueue.emplace(pdiskId, it);
- }
- }
- }
- }
- }
-
- if (!it->BlockedPDisks) {
- Send(it->RespondTo, it->Event.Release(), 0, it->Cookie);
- SelectGroupsQueue.erase(it);
- }
-}
-
-} // NKikimr::NBsController
+#include "impl.h"
+#include "select_groups.h"
+
+namespace NKikimr::NBsController {
+
+class TBlobStorageController::TTxSelectGroups : public TTransactionBase<TBlobStorageController> {
+ TEvBlobStorage::TEvControllerSelectGroups::TPtr Request;
+ std::unique_ptr<IEventHandle> Response;
+
+public:
+ TTxSelectGroups(TEvBlobStorage::TEvControllerSelectGroups::TPtr& ev, TBlobStorageController *controller)
+ : TTransactionBase(controller)
+ , Request(ev)
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_SELECT_GROUPS; }
+
+ bool Execute(TTransactionContext& /*txc*/, const TActorContext&) override {
+ Self->TabletCounters->Cumulative()[NBlobStorageController::COUNTER_SELECT_GROUPS_COUNT].Increment(1);
+ TRequestCounter counter(Self->TabletCounters, NBlobStorageController::COUNTER_SELECT_GROUPS_USEC);
+
+ auto request = std::move(Request);
+
+ THPTimer timer;
+
+ const auto& record = request->Get()->Record;
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG01, "Handle TEvControllerSelectGroups", (Request, record));
+
+ auto result = MakeHolder<TEvBlobStorage::TEvControllerSelectGroupsResult>();
+ auto& out = result->Record;
+ out.SetStatus(NKikimrProto::OK);
+ out.SetNewStyleQuerySupported(true);
+
+ if (!record.GetReturnAllMatchingGroups()) {
+ Y_VERIFY_DEBUG(false, "obsolete command");
+ out.SetStatus(NKikimrProto::ERROR);
+ } else {
+ TVector<const TGroupInfo*> groups;
+
+ for (const auto& params : record.GetGroupParameters()) {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG02, "Searching for group with parameters", (Params, params));
+
+ if (!TGroupSelector::PopulateGroups(groups, params, *Self)) {
+ STLOG(PRI_ERROR, BS_CONTROLLER, BSCTXSG03, "Handle TEvControllerSelectGroups: invalid parameters requested",
+ (Params, params));
+ out.SetStatus(NKikimrProto::ERROR);
+ break;
+ }
+
+ auto *pb = out.AddMatchingGroups();
+ for (const TGroupInfo *group : groups) {
+ if (!group->Down && (group->SeenOperational || !record.GetOnlySeenOperational())) {
+ auto *reportedGroup = pb->AddGroups();
+ reportedGroup->SetErasureSpecies(group->ErasureSpecies);
+ reportedGroup->SetGroupID(group->ID);
+ reportedGroup->SetStoragePoolName(Self->StoragePools.at(group->StoragePoolId).Name);
+ group->FillInGroupParameters(reportedGroup);
+ }
+ }
+ }
+ }
+
+ if (record.GetBlockUntilAllResourcesAreComplete()) {
+ auto it = Self->SelectGroupsQueue.emplace(Self->SelectGroupsQueue.end(), request->Sender, request->Cookie,
+ std::move(result));
+ Self->ProcessSelectGroupsQueueItem(it);
+ } else {
+ STLOG(PRI_DEBUG, BS_CONTROLLER, BSCTXSG04, "TEvControllerSelectGroups finished", (Result, result->Record));
+ Response = std::make_unique<IEventHandle>(request->Sender, Self->SelfId(), result.Release(), 0, request->Cookie);
+
+ const TDuration passed = TDuration::Seconds(timer.Passed());
+ Self->TabletCounters->Percentile()[NBlobStorageController::COUNTER_PERCENTILE_SELECT_GROUPS].IncrementFor(passed.MicroSeconds());
+ }
+
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {
+ if (Response) {
+ TActivationContext::Send(Response.release());
+ }
+ }
+};
+
+void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerSelectGroups::TPtr &ev) {
+ Execute(new TTxSelectGroups(ev, this));
+}
+
+void TBlobStorageController::ProcessSelectGroupsQueueItem(TList<TSelectGroupsQueueItem>::iterator it) {
+ for (const TPDiskId& key : std::exchange(it->BlockedPDisks, {})) {
+ const ui32 num = PDiskToQueue.erase(std::make_pair(key, it));
+ Y_VERIFY(num);
+ }
+
+ auto& record = it->Event->Record;
+ for (size_t i = 0; i < record.MatchingGroupsSize(); ++i) {
+ auto& mg = *record.MutableMatchingGroups(i);
+ for (size_t j = 0; j < mg.GroupsSize(); ++j) {
+ auto& g = *mg.MutableGroups(j);
+
+ const auto hasResources = [&] {
+ const auto& assured = g.GetAssuredResources();
+ const auto& current = g.GetCurrentResources();
+ return assured.HasSpace()
+ && assured.HasIOPS()
+ && assured.HasReadThroughput()
+ && assured.HasWriteThroughput()
+ && current.HasSpace()
+ && current.HasIOPS()
+ && current.HasReadThroughput()
+ && current.HasWriteThroughput();
+
+ };
+
+ if (TGroupInfo *group = FindGroup(g.GetGroupID()); group && !hasResources()) {
+ group->FillInGroupParameters(&g);
+ if (!hasResources()) {
+ // any of PDisks will do
+ for (const TVSlotInfo *vslot : group->VDisksInGroup) {
+ const TPDiskId pdiskId = vslot->VSlotId.ComprisingPDiskId();
+ it->BlockedPDisks.insert(pdiskId);
+ PDiskToQueue.emplace(pdiskId, it);
+ }
+ }
+ }
+ }
+ }
+
+ if (!it->BlockedPDisks) {
+ Send(it->RespondTo, it->Event.Release(), 0, it->Cookie);
+ SelectGroupsQueue.erase(it);
+ }
+}
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/select_groups.h b/ydb/core/mind/bscontroller/select_groups.h
index 6a2988949c8..6fc6d3c3c66 100644
--- a/ydb/core/mind/bscontroller/select_groups.h
+++ b/ydb/core/mind/bscontroller/select_groups.h
@@ -1,63 +1,63 @@
-#pragma once
-
-#include "defs.h"
-
-#include "impl.h"
-
-namespace NKikimr {
- namespace NBsController {
-
- class TBlobStorageController::TGroupSelector {
- public:
- static bool PopulateGroups(TVector<const TGroupInfo*>& groups,
- const NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters& params,
- TBlobStorageController& controller) {
- groups.clear();
- if (params.HasErasureSpecies() && params.HasDesiredPDiskCategory() && params.HasDesiredVDiskCategory() &&
- !params.HasStoragePoolSpecifier()) {
- TGroupSpecies groupSpecies((TBlobStorageGroupType::EErasureSpecies)params.GetErasureSpecies(),
- params.GetDesiredPDiskCategory(),
- (NKikimrBlobStorage::TVDiskKind::EVDiskKind)params.GetDesiredVDiskCategory());
- const auto iter = controller.IndexGroupSpeciesToGroup.find(groupSpecies);
- if (iter != controller.IndexGroupSpeciesToGroup.end()) {
- for (TGroupId groupId : iter->second) {
- const TGroupInfo *group = controller.FindGroup(groupId);
- Y_VERIFY_DEBUG(group);
- if (group) {
- groups.push_back(group);
- }
- }
- }
- } else if (!params.HasErasureSpecies() && !params.HasDesiredPDiskCategory() &&
- !params.HasDesiredVDiskCategory() && params.HasStoragePoolSpecifier()) {
- PopulateGroupsFromStoragePools(groups, controller.StoragePools, controller.StoragePoolGroups,
- std::bind(&TBlobStorageController::FindGroup, &controller, std::placeholders::_1),
- params.GetStoragePoolSpecifier());
- } else {
- return false;
- }
- return true;
- }
-
- private:
- template<typename T1, typename T2, typename T3, typename T4>
- static void PopulateGroupsFromStoragePools(TVector<const TGroupInfo*>& groups, const T1& storagePools,
- const T2& storagePoolGroups, T3&& findGroupCallback, const T4& params) {
- for (const auto& kv : storagePools) {
- const TStoragePoolInfo& info = kv.second;
- if ((!params.HasName() || params.GetName() == info.Name) && (!params.HasKind() || params.GetKind() == info.Kind)) {
- const TBoxStoragePoolId& id = kv.first;
- for (auto it = storagePoolGroups.lower_bound(id); it != storagePoolGroups.end() && it->first == id; ++it) {
- const TGroupInfo *groupInfo = findGroupCallback(it->second);
- Y_VERIFY_DEBUG(groupInfo);
- if (groupInfo) {
- groups.push_back(groupInfo);
- }
- }
- }
- }
- }
- };
-
- } // NBsController
-} // NKikimr
+#pragma once
+
+#include "defs.h"
+
+#include "impl.h"
+
+namespace NKikimr {
+ namespace NBsController {
+
+ class TBlobStorageController::TGroupSelector {
+ public:
+ static bool PopulateGroups(TVector<const TGroupInfo*>& groups,
+ const NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters& params,
+ TBlobStorageController& controller) {
+ groups.clear();
+ if (params.HasErasureSpecies() && params.HasDesiredPDiskCategory() && params.HasDesiredVDiskCategory() &&
+ !params.HasStoragePoolSpecifier()) {
+ TGroupSpecies groupSpecies((TBlobStorageGroupType::EErasureSpecies)params.GetErasureSpecies(),
+ params.GetDesiredPDiskCategory(),
+ (NKikimrBlobStorage::TVDiskKind::EVDiskKind)params.GetDesiredVDiskCategory());
+ const auto iter = controller.IndexGroupSpeciesToGroup.find(groupSpecies);
+ if (iter != controller.IndexGroupSpeciesToGroup.end()) {
+ for (TGroupId groupId : iter->second) {
+ const TGroupInfo *group = controller.FindGroup(groupId);
+ Y_VERIFY_DEBUG(group);
+ if (group) {
+ groups.push_back(group);
+ }
+ }
+ }
+ } else if (!params.HasErasureSpecies() && !params.HasDesiredPDiskCategory() &&
+ !params.HasDesiredVDiskCategory() && params.HasStoragePoolSpecifier()) {
+ PopulateGroupsFromStoragePools(groups, controller.StoragePools, controller.StoragePoolGroups,
+ std::bind(&TBlobStorageController::FindGroup, &controller, std::placeholders::_1),
+ params.GetStoragePoolSpecifier());
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ template<typename T1, typename T2, typename T3, typename T4>
+ static void PopulateGroupsFromStoragePools(TVector<const TGroupInfo*>& groups, const T1& storagePools,
+ const T2& storagePoolGroups, T3&& findGroupCallback, const T4& params) {
+ for (const auto& kv : storagePools) {
+ const TStoragePoolInfo& info = kv.second;
+ if ((!params.HasName() || params.GetName() == info.Name) && (!params.HasKind() || params.GetKind() == info.Kind)) {
+ const TBoxStoragePoolId& id = kv.first;
+ for (auto it = storagePoolGroups.lower_bound(id); it != storagePoolGroups.end() && it->first == id; ++it) {
+ const TGroupInfo *groupInfo = findGroupCallback(it->second);
+ Y_VERIFY_DEBUG(groupInfo);
+ if (groupInfo) {
+ groups.push_back(groupInfo);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ } // NBsController
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/self_heal.cpp b/ydb/core/mind/bscontroller/self_heal.cpp
index b732d98e937..3b03115969e 100644
--- a/ydb/core/mind/bscontroller/self_heal.cpp
+++ b/ydb/core/mind/bscontroller/self_heal.cpp
@@ -1,392 +1,392 @@
-#include "self_heal.h"
-#include "impl.h"
-#include "vdisk_status_tracker.h"
-#include "config.h"
-
-namespace NKikimr::NBsController {
-
- enum {
- EvReassignerDone = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- };
-
- struct TEvReassignerDone : TEventLocal<TEvReassignerDone, EvReassignerDone> {
- TGroupId GroupId;
- bool Success;
-
- TEvReassignerDone(TGroupId groupId, bool success)
- : GroupId(groupId)
- , Success(success)
- {}
- };
-
- class TReassignerActor : public TActorBootstrapped<TReassignerActor> {
+#include "self_heal.h"
+#include "impl.h"
+#include "vdisk_status_tracker.h"
+#include "config.h"
+
+namespace NKikimr::NBsController {
+
+ enum {
+ EvReassignerDone = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ };
+
+ struct TEvReassignerDone : TEventLocal<TEvReassignerDone, EvReassignerDone> {
+ TGroupId GroupId;
+ bool Success;
+
+ TEvReassignerDone(TGroupId groupId, bool success)
+ : GroupId(groupId)
+ , Success(success)
+ {}
+ };
+
+ class TReassignerActor : public TActorBootstrapped<TReassignerActor> {
const TActorId ControllerId;
TActorId SelfHealId; // filled on bootstrap
- const TGroupId GroupId;
- const TEvControllerUpdateSelfHealInfo::TGroupContent Group;
- const TVDiskID VDiskToReplace;
- TBlobStorageGroupInfo::TTopology Topology;
- THolder<TBlobStorageGroupInfo::TGroupVDisks> FailedGroupDisks;
- THashSet<TVDiskID> PendingVDisks;
+ const TGroupId GroupId;
+ const TEvControllerUpdateSelfHealInfo::TGroupContent Group;
+ const TVDiskID VDiskToReplace;
+ TBlobStorageGroupInfo::TTopology Topology;
+ THolder<TBlobStorageGroupInfo::TGroupVDisks> FailedGroupDisks;
+ THashSet<TVDiskID> PendingVDisks;
THashMap<TActorId, TVDiskID> ActorToDiskMap;
- THashMap<TNodeId, TVector<TVDiskID>> NodeToDiskMap;
-
- public:
+ THashMap<TNodeId, TVector<TVDiskID>> NodeToDiskMap;
+
+ public:
TReassignerActor(TActorId controllerId, TGroupId groupId, TEvControllerUpdateSelfHealInfo::TGroupContent group,
- TVDiskID vdiskToReplace)
- : ControllerId(controllerId)
- , GroupId(groupId)
- , Group(std::move(group))
- , VDiskToReplace(vdiskToReplace)
- , Topology(Group.Type)
- {}
-
+ TVDiskID vdiskToReplace)
+ : ControllerId(controllerId)
+ , GroupId(groupId)
+ , Group(std::move(group))
+ , VDiskToReplace(vdiskToReplace)
+ , Topology(Group.Type)
+ {}
+
void Bootstrap(const TActorId& parent) {
- SelfHealId = parent;
- Become(&TThis::StateFunc, TDuration::Seconds(60), new TEvents::TEvWakeup);
-
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH01, "Reassigner starting", (GroupId, GroupId));
-
- // create the topology
- for (const auto& [vdiskId, vdisk] : Group.VDisks) {
- Y_VERIFY(vdiskId.GroupID == GroupId);
- Y_VERIFY(vdiskId.GroupGeneration == Group.Generation);
-
- // allocate new fail realm (if needed)
- if (Topology.FailRealms.size() == vdiskId.FailRealm) {
- Topology.FailRealms.emplace_back();
- }
- Y_VERIFY(vdiskId.FailRealm == Topology.FailRealms.size() - 1);
- auto& realm = Topology.FailRealms.back();
-
- // allocate new fail domain (if needed)
- if (realm.FailDomains.size() == vdiskId.FailDomain) {
- realm.FailDomains.emplace_back();
- }
- Y_VERIFY(vdiskId.FailDomain == realm.FailDomains.size() - 1);
- auto& domain = realm.FailDomains.back();
-
- // allocate new VDisk id
- Y_VERIFY(vdiskId.VDisk == domain.VDisks.size());
- domain.VDisks.emplace_back();
- }
-
- // fill in topology structures
- Topology.FinalizeConstruction();
- FailedGroupDisks = MakeHolder<TBlobStorageGroupInfo::TGroupVDisks>(&Topology);
-
- for (const auto& [vdiskId, vdisk] : Group.VDisks) {
- if (vdiskId == VDiskToReplace) {
- *FailedGroupDisks |= {&Topology, vdiskId};
- continue; // skip disk we are going to replcate -- it will be wiped out anyway
- }
-
- // send TEvVStatus message to disk
- const auto& l = vdisk.Location;
+ SelfHealId = parent;
+ Become(&TThis::StateFunc, TDuration::Seconds(60), new TEvents::TEvWakeup);
+
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH01, "Reassigner starting", (GroupId, GroupId));
+
+ // create the topology
+ for (const auto& [vdiskId, vdisk] : Group.VDisks) {
+ Y_VERIFY(vdiskId.GroupID == GroupId);
+ Y_VERIFY(vdiskId.GroupGeneration == Group.Generation);
+
+ // allocate new fail realm (if needed)
+ if (Topology.FailRealms.size() == vdiskId.FailRealm) {
+ Topology.FailRealms.emplace_back();
+ }
+ Y_VERIFY(vdiskId.FailRealm == Topology.FailRealms.size() - 1);
+ auto& realm = Topology.FailRealms.back();
+
+ // allocate new fail domain (if needed)
+ if (realm.FailDomains.size() == vdiskId.FailDomain) {
+ realm.FailDomains.emplace_back();
+ }
+ Y_VERIFY(vdiskId.FailDomain == realm.FailDomains.size() - 1);
+ auto& domain = realm.FailDomains.back();
+
+ // allocate new VDisk id
+ Y_VERIFY(vdiskId.VDisk == domain.VDisks.size());
+ domain.VDisks.emplace_back();
+ }
+
+ // fill in topology structures
+ Topology.FinalizeConstruction();
+ FailedGroupDisks = MakeHolder<TBlobStorageGroupInfo::TGroupVDisks>(&Topology);
+
+ for (const auto& [vdiskId, vdisk] : Group.VDisks) {
+ if (vdiskId == VDiskToReplace) {
+ *FailedGroupDisks |= {&Topology, vdiskId};
+ continue; // skip disk we are going to replcate -- it will be wiped out anyway
+ }
+
+ // send TEvVStatus message to disk
+ const auto& l = vdisk.Location;
const TActorId& vdiskActorId = MakeBlobStorageVDiskID(l.NodeId, l.PDiskId, l.VSlotId);
- Send(vdiskActorId, new TEvBlobStorage::TEvVStatus(vdiskId), IEventHandle::MakeFlags(0,
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession));
- ActorToDiskMap.emplace(vdiskActorId, vdiskId);
- NodeToDiskMap[l.NodeId].push_back(vdiskId);
- PendingVDisks.insert(vdiskId);
- }
-
- if (!PendingVDisks) {
- ProcessResult();
- }
- }
-
- void ProcessVDiskReply(const TVDiskID& vdiskId, bool diskIsOk) {
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH02, "Reassigner ProcessVDiskReply", (GroupId, GroupId),
- (VDiskId, vdiskId), (DiskIsOk, diskIsOk));
- if (PendingVDisks.erase(vdiskId)) {
- if (!diskIsOk) {
- *FailedGroupDisks |= {&Topology, vdiskId};
- }
- if (!PendingVDisks) {
- ProcessResult();
- }
- }
- }
-
- void Handle(TEvBlobStorage::TEvVStatusResult::TPtr& ev) {
- const auto& record = ev->Get()->Record;
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH03, "Reassigner TEvVStatusResult", (GroupId, GroupId), (Response, record));
-
- bool diskIsOk = false;
- if (record.GetStatus() == NKikimrProto::RACE) {
- return Finish(false); // group reconfigured while we were querying it
- } else if (record.GetStatus() == NKikimrProto::OK) {
- diskIsOk = record.GetJoinedGroup() && record.GetReplicated();
- }
- ProcessVDiskReply(VDiskIDFromVDiskID(record.GetVDiskID()), diskIsOk);
- }
-
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr&) {} // not interesting
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH04, "Reassigner TEvNodeDisconnected", (GroupId, GroupId),
- (NodeId, ev->Get()->NodeId));
- for (const auto& vdiskId : NodeToDiskMap[ev->Get()->NodeId]) {
- ProcessVDiskReply(vdiskId, false);
- }
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr& ev) {
- auto it = ActorToDiskMap.find(ev->Sender);
- Y_VERIFY(it != ActorToDiskMap.end());
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH05, "Reassigner TEvUndelivered", (GroupId, GroupId),
- (Sender, ev->Sender), (VDiskId, it->second));
- ProcessVDiskReply(it->second, false);
- ActorToDiskMap.erase(it);
- }
-
- void ProcessResult() {
- auto& checker = Topology.GetQuorumChecker();
- if (!checker.CheckFailModelForGroup(*FailedGroupDisks)) {
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH06, "Reassigner ProcessResult quorum checker failed", (GroupId, GroupId));
- return Finish(false); // this change will render group unusable
- }
-
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- ev->SelfHeal = true;
- auto& record = ev->Record;
- auto *request = record.MutableRequest();
- request->SetIgnoreGroupReserve(true);
- request->SetSettleOnlyOnOperationalDisks(true);
- auto *cmd = request->AddCommand()->MutableReassignGroupDisk();
- cmd->SetGroupId(VDiskToReplace.GroupID);
- cmd->SetGroupGeneration(VDiskToReplace.GroupGeneration);
- cmd->SetFailRealmIdx(VDiskToReplace.FailRealm);
- cmd->SetFailDomainIdx(VDiskToReplace.FailDomain);
- cmd->SetVDiskIdx(VDiskToReplace.VDisk);
-
- Send(ControllerId, ev.Release());
- }
-
- void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
- const auto& record = ev->Get()->Record;
- if (!record.GetResponse().GetSuccess()) {
- STLOG(PRI_WARN, BS_SELFHEAL, BSSH07, "Reassigner ReassignGroupDisk request failed", (GroupId, GroupId),
- (VDiskToReplace, VDiskToReplace), (Response, record));
- }
- Finish(record.GetResponse().GetSuccess());
- }
-
- void Finish(bool success) {
- STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH08, "Reassigner finished", (GroupId, GroupId), (Success, success));
- Send(SelfHealId, new TEvReassignerDone(GroupId, success));
- PassAway();
- }
-
- void HandleWakeup() {
- // actually it is watchdog timer for VDisk status query
- if (PendingVDisks) {
- Finish(false);
- }
- }
-
- void PassAway() override {
- for (const auto& [nodeId, info] : NodeToDiskMap) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
- }
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StateFunc, {
- hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
- hFunc(TEvInterconnect::TEvNodeConnected, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
- hFunc(TEvents::TEvUndelivered, Handle);
- hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- })
- };
-
- class TSelfHealActor : public TActorBootstrapped<TSelfHealActor> {
- static constexpr TDuration MinRetryTimeout = TDuration::Seconds(1);
- static constexpr TDuration MaxRetryTimeout = TDuration::Seconds(60);
-
- struct TGroupRecord {
- TEvControllerUpdateSelfHealInfo::TGroupContent Content;
+ Send(vdiskActorId, new TEvBlobStorage::TEvVStatus(vdiskId), IEventHandle::MakeFlags(0,
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession));
+ ActorToDiskMap.emplace(vdiskActorId, vdiskId);
+ NodeToDiskMap[l.NodeId].push_back(vdiskId);
+ PendingVDisks.insert(vdiskId);
+ }
+
+ if (!PendingVDisks) {
+ ProcessResult();
+ }
+ }
+
+ void ProcessVDiskReply(const TVDiskID& vdiskId, bool diskIsOk) {
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH02, "Reassigner ProcessVDiskReply", (GroupId, GroupId),
+ (VDiskId, vdiskId), (DiskIsOk, diskIsOk));
+ if (PendingVDisks.erase(vdiskId)) {
+ if (!diskIsOk) {
+ *FailedGroupDisks |= {&Topology, vdiskId};
+ }
+ if (!PendingVDisks) {
+ ProcessResult();
+ }
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatusResult::TPtr& ev) {
+ const auto& record = ev->Get()->Record;
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH03, "Reassigner TEvVStatusResult", (GroupId, GroupId), (Response, record));
+
+ bool diskIsOk = false;
+ if (record.GetStatus() == NKikimrProto::RACE) {
+ return Finish(false); // group reconfigured while we were querying it
+ } else if (record.GetStatus() == NKikimrProto::OK) {
+ diskIsOk = record.GetJoinedGroup() && record.GetReplicated();
+ }
+ ProcessVDiskReply(VDiskIDFromVDiskID(record.GetVDiskID()), diskIsOk);
+ }
+
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr&) {} // not interesting
+
+ void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr& ev) {
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH04, "Reassigner TEvNodeDisconnected", (GroupId, GroupId),
+ (NodeId, ev->Get()->NodeId));
+ for (const auto& vdiskId : NodeToDiskMap[ev->Get()->NodeId]) {
+ ProcessVDiskReply(vdiskId, false);
+ }
+ }
+
+ void Handle(TEvents::TEvUndelivered::TPtr& ev) {
+ auto it = ActorToDiskMap.find(ev->Sender);
+ Y_VERIFY(it != ActorToDiskMap.end());
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH05, "Reassigner TEvUndelivered", (GroupId, GroupId),
+ (Sender, ev->Sender), (VDiskId, it->second));
+ ProcessVDiskReply(it->second, false);
+ ActorToDiskMap.erase(it);
+ }
+
+ void ProcessResult() {
+ auto& checker = Topology.GetQuorumChecker();
+ if (!checker.CheckFailModelForGroup(*FailedGroupDisks)) {
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH06, "Reassigner ProcessResult quorum checker failed", (GroupId, GroupId));
+ return Finish(false); // this change will render group unusable
+ }
+
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ ev->SelfHeal = true;
+ auto& record = ev->Record;
+ auto *request = record.MutableRequest();
+ request->SetIgnoreGroupReserve(true);
+ request->SetSettleOnlyOnOperationalDisks(true);
+ auto *cmd = request->AddCommand()->MutableReassignGroupDisk();
+ cmd->SetGroupId(VDiskToReplace.GroupID);
+ cmd->SetGroupGeneration(VDiskToReplace.GroupGeneration);
+ cmd->SetFailRealmIdx(VDiskToReplace.FailRealm);
+ cmd->SetFailDomainIdx(VDiskToReplace.FailDomain);
+ cmd->SetVDiskIdx(VDiskToReplace.VDisk);
+
+ Send(ControllerId, ev.Release());
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr& ev) {
+ const auto& record = ev->Get()->Record;
+ if (!record.GetResponse().GetSuccess()) {
+ STLOG(PRI_WARN, BS_SELFHEAL, BSSH07, "Reassigner ReassignGroupDisk request failed", (GroupId, GroupId),
+ (VDiskToReplace, VDiskToReplace), (Response, record));
+ }
+ Finish(record.GetResponse().GetSuccess());
+ }
+
+ void Finish(bool success) {
+ STLOG(PRI_DEBUG, BS_SELFHEAL, BSSH08, "Reassigner finished", (GroupId, GroupId), (Success, success));
+ Send(SelfHealId, new TEvReassignerDone(GroupId, success));
+ PassAway();
+ }
+
+ void HandleWakeup() {
+ // actually it is watchdog timer for VDisk status query
+ if (PendingVDisks) {
+ Finish(false);
+ }
+ }
+
+ void PassAway() override {
+ for (const auto& [nodeId, info] : NodeToDiskMap) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ }
+ TActorBootstrapped::PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ hFunc(TEvBlobStorage::TEvVStatusResult, Handle);
+ hFunc(TEvInterconnect::TEvNodeConnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
+ hFunc(TEvents::TEvUndelivered, Handle);
+ hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ })
+ };
+
+ class TSelfHealActor : public TActorBootstrapped<TSelfHealActor> {
+ static constexpr TDuration MinRetryTimeout = TDuration::Seconds(1);
+ static constexpr TDuration MaxRetryTimeout = TDuration::Seconds(60);
+
+ struct TGroupRecord {
+ TEvControllerUpdateSelfHealInfo::TGroupContent Content;
TActorId ReassignerActorId; // reassigner in flight
- TDuration RetryTimeout = MinRetryTimeout;
- TInstant NextRetryTimestamp = TInstant::Zero();
- THashMap<TVDiskID, TVDiskStatusTracker> VDiskStatus;
- };
-
- const ui64 TabletId;
+ TDuration RetryTimeout = MinRetryTimeout;
+ TInstant NextRetryTimestamp = TInstant::Zero();
+ THashMap<TVDiskID, TVDiskStatusTracker> VDiskStatus;
+ };
+
+ const ui64 TabletId;
TActorId ControllerId;
- THashMap<TGroupId, TGroupRecord> Groups;
- TSet<TGroupId> GroupsWithFaultyDisks;
- std::shared_ptr<std::atomic_uint64_t> UnreassignableGroups;
-
- public:
- TSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups)
- : TabletId(tabletId)
- , UnreassignableGroups(std::move(unreassignableGroups))
- {}
-
+ THashMap<TGroupId, TGroupRecord> Groups;
+ TSet<TGroupId> GroupsWithFaultyDisks;
+ std::shared_ptr<std::atomic_uint64_t> UnreassignableGroups;
+
+ public:
+ TSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups)
+ : TabletId(tabletId)
+ , UnreassignableGroups(std::move(unreassignableGroups))
+ {}
+
void Bootstrap(const TActorId& parentId) {
- ControllerId = parentId;
- Become(&TThis::StateFunc);
- HandleWakeup();
- }
-
- void Handle(TEvControllerUpdateSelfHealInfo::TPtr& ev) {
- const TInstant now = TActivationContext::Now();
- for (const auto& [groupId, data] : ev->Get()->GroupsToUpdate) {
- if (data) {
- auto& g = Groups[groupId];
- bool hasFaultyDisks = false;
- g.Content = std::move(*data);
- for (const auto& [vdiskId, vdisk] : g.Content.VDisks) {
- g.VDiskStatus[vdiskId].Update(vdisk.VDiskStatus, now);
- hasFaultyDisks |= vdisk.Faulty;
- }
- for (auto it = g.VDiskStatus.begin(); it != g.VDiskStatus.end(); ) {
- if (g.Content.VDisks.count(it->first)) {
- ++it;
- } else {
- g.VDiskStatus.erase(it++);
- }
- }
- if (hasFaultyDisks) {
- GroupsWithFaultyDisks.insert(groupId);
- } else {
- GroupsWithFaultyDisks.erase(groupId);
- }
- } else {
- // find the group to delete
- const auto it = Groups.find(groupId);
- if (it == Groups.end()) {
- continue; // TODO(alexvru): this should not happen
- }
- Y_VERIFY(it != Groups.end());
- TGroupRecord& group = it->second;
-
- // kill reassigner, if it is working
- if (group.ReassignerActorId) {
- Send(group.ReassignerActorId, new TEvents::TEvPoison);
- }
-
- // remove the group
- GroupsWithFaultyDisks.erase(groupId);
- Groups.erase(it);
- }
- }
- for (const auto& [vdiskId, status] : ev->Get()->VDiskStatusUpdate) {
- if (const auto it = Groups.find(vdiskId.GroupID); it != Groups.end()) {
- auto& group = it->second;
- if (const auto it = group.Content.VDisks.find(vdiskId); it != group.Content.VDisks.end()) {
- it->second.VDiskStatus = status;
- group.VDiskStatus[vdiskId].Update(status, now);
- }
- }
- }
- CheckGroups();
- }
-
- void CheckGroups() {
- const TInstant now = TActivationContext::Now();
-
- ui64 counter = 0;
-
- for (const TGroupId groupId : GroupsWithFaultyDisks) {
- // find the group to process
- const auto it = Groups.find(groupId);
- Y_VERIFY(it != Groups.end());
- TGroupRecord& group = it->second;
-
- if (group.ReassignerActorId || now < group.NextRetryTimestamp) {
- continue; // we are already running reassigner for this group
- }
-
- // check if it is possible to move anything out
- if (const auto v = FindVDiskToReplace(group.VDiskStatus, group.Content, now)) {
- group.ReassignerActorId = Register(new TReassignerActor(ControllerId, groupId, group.Content, *v));
- } else {
- ++counter; // this group can't be reassigned right now
- }
- }
-
- UnreassignableGroups->store(counter);
- }
-
- std::optional<TVDiskID> FindVDiskToReplace(const THashMap<TVDiskID, TVDiskStatusTracker>& tracker,
- const TEvControllerUpdateSelfHealInfo::TGroupContent& content, const TInstant now) {
- auto status = [&](const TVDiskID& id) {
- try {
- return tracker.at(id).GetStatus(now);
- } catch (const std::out_of_range&) {
- Y_FAIL();
- }
- };
-
- ui32 numBadDisks = 0;
- for (const auto& [vdiskId, vdisk] : content.VDisks) {
- if (status(vdiskId) != NKikimrBlobStorage::EVDiskStatus::READY || vdisk.Bad) {
- ++numBadDisks;
- }
- }
- if (numBadDisks > 1) {
- return std::nullopt; // do not touch groups with -2 disks or worse
- }
-
- for (const auto& [vdiskId, vdisk] : content.VDisks) {
- if (vdisk.Faulty) {
- return vdiskId;
- }
- }
-
- // no options for this group
- return std::nullopt;
- }
-
- void Handle(TEvReassignerDone::TPtr& ev) {
- if (const auto it = Groups.find(ev->Get()->GroupId); it != Groups.end() && it->second.ReassignerActorId == ev->Sender) {
- auto& group = it->second;
- group.ReassignerActorId = {};
-
- const TInstant now = TActivationContext::Now();
- if (ev->Get()->Success) {
- group.NextRetryTimestamp = now;
- group.RetryTimeout = MinRetryTimeout;
- } else {
- group.NextRetryTimestamp = now + group.RetryTimeout;
- group.RetryTimeout = std::min(MaxRetryTimeout, group.RetryTimeout * 3 / 2);
- }
-
- CheckGroups();
- }
- }
-
- void HandleWakeup() {
- CheckGroups();
- Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup);
- }
-
- void Handle(NMon::TEvRemoteHttpInfo::TPtr& ev) {
- TStringStream str;
- RenderMonPage(str, ev->Cookie);
- Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
- }
-
- void RenderMonPage(IOutputStream& out, bool selfHealEnabled) {
- const TInstant now = TActivationContext::Now();
-
- HTML(out) {
+ ControllerId = parentId;
+ Become(&TThis::StateFunc);
+ HandleWakeup();
+ }
+
+ void Handle(TEvControllerUpdateSelfHealInfo::TPtr& ev) {
+ const TInstant now = TActivationContext::Now();
+ for (const auto& [groupId, data] : ev->Get()->GroupsToUpdate) {
+ if (data) {
+ auto& g = Groups[groupId];
+ bool hasFaultyDisks = false;
+ g.Content = std::move(*data);
+ for (const auto& [vdiskId, vdisk] : g.Content.VDisks) {
+ g.VDiskStatus[vdiskId].Update(vdisk.VDiskStatus, now);
+ hasFaultyDisks |= vdisk.Faulty;
+ }
+ for (auto it = g.VDiskStatus.begin(); it != g.VDiskStatus.end(); ) {
+ if (g.Content.VDisks.count(it->first)) {
+ ++it;
+ } else {
+ g.VDiskStatus.erase(it++);
+ }
+ }
+ if (hasFaultyDisks) {
+ GroupsWithFaultyDisks.insert(groupId);
+ } else {
+ GroupsWithFaultyDisks.erase(groupId);
+ }
+ } else {
+ // find the group to delete
+ const auto it = Groups.find(groupId);
+ if (it == Groups.end()) {
+ continue; // TODO(alexvru): this should not happen
+ }
+ Y_VERIFY(it != Groups.end());
+ TGroupRecord& group = it->second;
+
+ // kill reassigner, if it is working
+ if (group.ReassignerActorId) {
+ Send(group.ReassignerActorId, new TEvents::TEvPoison);
+ }
+
+ // remove the group
+ GroupsWithFaultyDisks.erase(groupId);
+ Groups.erase(it);
+ }
+ }
+ for (const auto& [vdiskId, status] : ev->Get()->VDiskStatusUpdate) {
+ if (const auto it = Groups.find(vdiskId.GroupID); it != Groups.end()) {
+ auto& group = it->second;
+ if (const auto it = group.Content.VDisks.find(vdiskId); it != group.Content.VDisks.end()) {
+ it->second.VDiskStatus = status;
+ group.VDiskStatus[vdiskId].Update(status, now);
+ }
+ }
+ }
+ CheckGroups();
+ }
+
+ void CheckGroups() {
+ const TInstant now = TActivationContext::Now();
+
+ ui64 counter = 0;
+
+ for (const TGroupId groupId : GroupsWithFaultyDisks) {
+ // find the group to process
+ const auto it = Groups.find(groupId);
+ Y_VERIFY(it != Groups.end());
+ TGroupRecord& group = it->second;
+
+ if (group.ReassignerActorId || now < group.NextRetryTimestamp) {
+ continue; // we are already running reassigner for this group
+ }
+
+ // check if it is possible to move anything out
+ if (const auto v = FindVDiskToReplace(group.VDiskStatus, group.Content, now)) {
+ group.ReassignerActorId = Register(new TReassignerActor(ControllerId, groupId, group.Content, *v));
+ } else {
+ ++counter; // this group can't be reassigned right now
+ }
+ }
+
+ UnreassignableGroups->store(counter);
+ }
+
+ std::optional<TVDiskID> FindVDiskToReplace(const THashMap<TVDiskID, TVDiskStatusTracker>& tracker,
+ const TEvControllerUpdateSelfHealInfo::TGroupContent& content, const TInstant now) {
+ auto status = [&](const TVDiskID& id) {
+ try {
+ return tracker.at(id).GetStatus(now);
+ } catch (const std::out_of_range&) {
+ Y_FAIL();
+ }
+ };
+
+ ui32 numBadDisks = 0;
+ for (const auto& [vdiskId, vdisk] : content.VDisks) {
+ if (status(vdiskId) != NKikimrBlobStorage::EVDiskStatus::READY || vdisk.Bad) {
+ ++numBadDisks;
+ }
+ }
+ if (numBadDisks > 1) {
+ return std::nullopt; // do not touch groups with -2 disks or worse
+ }
+
+ for (const auto& [vdiskId, vdisk] : content.VDisks) {
+ if (vdisk.Faulty) {
+ return vdiskId;
+ }
+ }
+
+ // no options for this group
+ return std::nullopt;
+ }
+
+ void Handle(TEvReassignerDone::TPtr& ev) {
+ if (const auto it = Groups.find(ev->Get()->GroupId); it != Groups.end() && it->second.ReassignerActorId == ev->Sender) {
+ auto& group = it->second;
+ group.ReassignerActorId = {};
+
+ const TInstant now = TActivationContext::Now();
+ if (ev->Get()->Success) {
+ group.NextRetryTimestamp = now;
+ group.RetryTimeout = MinRetryTimeout;
+ } else {
+ group.NextRetryTimestamp = now + group.RetryTimeout;
+ group.RetryTimeout = std::min(MaxRetryTimeout, group.RetryTimeout * 3 / 2);
+ }
+
+ CheckGroups();
+ }
+ }
+
+ void HandleWakeup() {
+ CheckGroups();
+ Schedule(TDuration::Seconds(10), new TEvents::TEvWakeup);
+ }
+
+ void Handle(NMon::TEvRemoteHttpInfo::TPtr& ev) {
+ TStringStream str;
+ RenderMonPage(str, ev->Cookie);
+ Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()));
+ }
+
+ void RenderMonPage(IOutputStream& out, bool selfHealEnabled) {
+ const TInstant now = TActivationContext::Now();
+
+ HTML(out) {
H2() {
out << "BlobStorage Controller";
}
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Self-Heal status";
- }
- DIV_CLASS("panel-body") {
- out << (selfHealEnabled ? "Enabled" : "Disabled");
- if (selfHealEnabled) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Self-Heal status";
+ }
+ DIV_CLASS("panel-body") {
+ out << (selfHealEnabled ? "Enabled" : "Disabled");
+ if (selfHealEnabled) {
out << "<br/>" << Endl;
out << "<form method='POST'>" << Endl;
out << "<input type='hidden' name='TabletID' value='" << TabletId << "'>" << Endl;
@@ -395,246 +395,246 @@ namespace NKikimr::NBsController {
out << "<input type='hidden' name='action' value='disableSelfHeal'>" << Endl;
out << "<input class='btn btn-primary' type='submit' value='DISABLE NOW'/>" << Endl;
out << "</form>";
- }
- }
- }
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "VDisk states";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { out << "State"; }
- TABLEH() { out << "Description"; }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { out << "ERROR"; }
- TABLED() { out << "VDisk is not available now or is in error state"; }
- }
- TABLER() {
- TABLED() { out << "INIT_PENDING"; }
- TABLED() { out << "VDisk is being initialized or synced with other disks in the group"; }
- }
- TABLER() {
- TABLED() { out << "REPLICATING"; }
- TABLED() { out << "VDisk is being currently replicated"; }
- }
- TABLER() {
- TABLED() { out << "READY"; }
- TABLED() { out << "VDisk is replicated and ready"; }
- }
- }
- }
- }
- }
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- out << "Broken groups";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table-sortable table") {
- TABLEHEAD() {
- ui32 numCols = 0;
- for (const auto& id : GroupsWithFaultyDisks) {
- const auto& info = Groups.at(id);
- numCols = Max<ui32>(numCols, info.Content.VDisks.size());
- }
-
- TABLER() {
- TABLEH() { out << "GroupId:Gen"; }
- for (ui32 i = 0; i < numCols; ++i) {
- TABLEH() { out << "OrderNum# " << i; }
- }
- }
- }
- TABLEBODY() {
- for (const auto& id : GroupsWithFaultyDisks) {
- const auto& info = Groups.at(id);
- TABLER() {
- out << "<td rowspan='2'><a href='?TabletID=" << TabletId
- << "&page=GroupDetail&GroupId=" << id << "'>"
- << id << "</a>:" << info.Content.Generation << "</td>";
-
- for (const auto& [vdiskId, vdisk] : info.Content.VDisks) {
- TABLED() {
- out << vdiskId.ToString();
- out << "<br/>";
- out << vdisk.VDiskStatus;
- out << "<br/><strong>";
- if (const auto it = info.VDiskStatus.find(vdiskId); it != info.VDiskStatus.end()) {
- if (const auto& status = it->second.GetStatus(now)) {
- out << *status;
- } else {
- out << "unsure";
- }
- } else {
- out << "?";
- }
- out << "</strong>";
- }
- }
- }
- TABLER() {
- for (const auto& [vdiskId, vdisk] : info.Content.VDisks) {
- TABLED() {
- const auto& l = vdisk.Location;
- if (vdisk.Faulty) {
- out << "<strong>";
- }
- if (vdisk.Bad) {
- out << "<font color='red'>";
- }
- out << "[" << l.NodeId << ":" << l.PDiskId << ":" << l.VSlotId << "]";
- if (vdisk.Bad) {
- out << "</font>";
- }
- if (vdisk.Faulty) {
- out << "</strong>";
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- STRICT_STFUNC(StateFunc, {
- cFunc(TEvents::TSystem::Poison, PassAway);
- hFunc(TEvControllerUpdateSelfHealInfo, Handle);
- hFunc(NMon::TEvRemoteHttpInfo, Handle);
- hFunc(TEvReassignerDone, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- })
- };
-
- IActor *CreateSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups) {
- return new TSelfHealActor(tabletId, std::move(unreassignableGroups));
- }
-
- void TBlobStorageController::InitializeSelfHealState() {
- auto ev = MakeHolder<TEvControllerUpdateSelfHealInfo>();
- for (const auto& [groupId, group] : GroupMap) {
- ev->GroupsToUpdate.emplace(groupId, TEvControllerUpdateSelfHealInfo::TGroupContent());
- }
- FillInSelfHealGroups(*ev, nullptr);
- Send(SelfHealId, ev.Release());
- }
-
- void TBlobStorageController::FillInSelfHealGroups(TEvControllerUpdateSelfHealInfo& msg, TConfigState *state) {
- for (auto& [groupId, group] : msg.GroupsToUpdate) {
- if (!group) {
- continue;
- }
-
- const TGroupInfo *p = state ? state->Groups.Find(groupId) : FindGroup(groupId);
- Y_VERIFY(p);
-
- group->Generation = p->Generation;
- group->Type = TBlobStorageGroupType(p->ErasureSpecies);
-
- for (const TVSlotInfo *slot : p->VDisksInGroup) {
- group->VDisks[slot->GetVDiskId()] = {
- slot->VSlotId,
- slot->PDisk->ShouldBeSettledBySelfHeal(),
- slot->PDisk->BadInTermsOfSelfHeal(),
- slot->GetStatus(),
- };
- }
- }
- }
-
- void TBlobStorageController::ProcessVDiskStatus(
- const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus>& s) {
- THashSet<TGroupInfo*> groups, status;
- const TInstant now = TActivationContext::Now();
- std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
-
- std::unique_ptr<TEvPrivate::TEvDropDonor> dropDonorEv;
-
- auto ev = MakeHolder<TEvControllerUpdateSelfHealInfo>();
- for (const auto& m : s) {
- const TVSlotId vslotId(m.GetNodeId(), m.GetPDiskId(), m.GetVSlotId());
- const auto vdiskId = VDiskIDFromVDiskID(m.GetVDiskId());
- if (TVSlotInfo *slot = FindVSlot(vslotId); slot && !slot->IsBeingDeleted() &&
- slot->PDisk->Guid == m.GetPDiskGuid() && vdiskId.SameExceptGeneration(slot->GetVDiskId())) {
- const bool was = slot->IsOperational();
- if (const TGroupInfo *group = slot->Group) {
- const bool wasReady = slot->IsReady;
- slot->SetStatus(m.GetStatus(), now);
- if (slot->IsReady != wasReady) {
- ScrubState.UpdateVDiskState(slot);
- if (wasReady) {
- slot->LastSeenReady = now;
- lastSeenReadyQ.emplace_back(slot->VSlotId, now);
- NotReadyVSlotIds.insert(slot->VSlotId);
- }
- }
- ScheduleVSlotReadyUpdate();
- status.insert(const_cast<TGroupInfo*>(group));
- ev->VDiskStatusUpdate.emplace_back(vdiskId, m.GetStatus());
- if (!was && slot->IsOperational() && !group->SeenOperational) {
- groups.insert(const_cast<TGroupInfo*>(group));
- }
- }
- if (slot->GetStatus() == NKikimrBlobStorage::EVDiskStatus::READY) {
- // we can release donor slots without further notice then the VDisk is completely replicated; we
- // intentionally use GetStatus() here instead of IsReady() to prevent waiting
- for (const auto& [donorVSlotId, donorVDiskId] : slot->Donors) {
- if (!dropDonorEv) {
- dropDonorEv.reset(new TEvPrivate::TEvDropDonor);
- }
- dropDonorEv->VSlotIds.push_back(donorVSlotId);
- }
- }
- }
- if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end() && it->second.VDiskId == vdiskId) {
- it->second.VDiskStatus = m.GetStatus();
- }
- }
-
- if (dropDonorEv) {
- Send(SelfId(), dropDonorEv.release());
- }
-
- // issue updated statuses to self-healer
- if (ev->VDiskStatusUpdate) {
- Send(SelfHealId, ev.Release());
- }
-
- // update operational status for groups
- TVector<TGroupId> groupIds;
- for (TGroupInfo *group : groups) {
- group->UpdateSeenOperational();
- if (group->SeenOperational) {
- groupIds.push_back(group->ID);
- }
- }
- if (groupIds) {
- Execute(CreateTxUpdateSeenOperational(std::move(groupIds)));
- }
-
- if (!lastSeenReadyQ.empty()) {
- Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
- }
-
- for (TGroupInfo *group : status) {
- group->CalculateGroupStatus();
- }
- }
-
- void TBlobStorageController::UpdateSelfHealCounters() {
- // WARNING: keep this logic consistent with updateSelfHealCounters flag calculation in CommitConfigUpdates
- const TInstant now = TActivationContext::Now();
- bool reschedule = false;
-
+ }
+ }
+ }
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "VDisk states";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { out << "State"; }
+ TABLEH() { out << "Description"; }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { out << "ERROR"; }
+ TABLED() { out << "VDisk is not available now or is in error state"; }
+ }
+ TABLER() {
+ TABLED() { out << "INIT_PENDING"; }
+ TABLED() { out << "VDisk is being initialized or synced with other disks in the group"; }
+ }
+ TABLER() {
+ TABLED() { out << "REPLICATING"; }
+ TABLED() { out << "VDisk is being currently replicated"; }
+ }
+ TABLER() {
+ TABLED() { out << "READY"; }
+ TABLED() { out << "VDisk is replicated and ready"; }
+ }
+ }
+ }
+ }
+ }
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ out << "Broken groups";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table-sortable table") {
+ TABLEHEAD() {
+ ui32 numCols = 0;
+ for (const auto& id : GroupsWithFaultyDisks) {
+ const auto& info = Groups.at(id);
+ numCols = Max<ui32>(numCols, info.Content.VDisks.size());
+ }
+
+ TABLER() {
+ TABLEH() { out << "GroupId:Gen"; }
+ for (ui32 i = 0; i < numCols; ++i) {
+ TABLEH() { out << "OrderNum# " << i; }
+ }
+ }
+ }
+ TABLEBODY() {
+ for (const auto& id : GroupsWithFaultyDisks) {
+ const auto& info = Groups.at(id);
+ TABLER() {
+ out << "<td rowspan='2'><a href='?TabletID=" << TabletId
+ << "&page=GroupDetail&GroupId=" << id << "'>"
+ << id << "</a>:" << info.Content.Generation << "</td>";
+
+ for (const auto& [vdiskId, vdisk] : info.Content.VDisks) {
+ TABLED() {
+ out << vdiskId.ToString();
+ out << "<br/>";
+ out << vdisk.VDiskStatus;
+ out << "<br/><strong>";
+ if (const auto it = info.VDiskStatus.find(vdiskId); it != info.VDiskStatus.end()) {
+ if (const auto& status = it->second.GetStatus(now)) {
+ out << *status;
+ } else {
+ out << "unsure";
+ }
+ } else {
+ out << "?";
+ }
+ out << "</strong>";
+ }
+ }
+ }
+ TABLER() {
+ for (const auto& [vdiskId, vdisk] : info.Content.VDisks) {
+ TABLED() {
+ const auto& l = vdisk.Location;
+ if (vdisk.Faulty) {
+ out << "<strong>";
+ }
+ if (vdisk.Bad) {
+ out << "<font color='red'>";
+ }
+ out << "[" << l.NodeId << ":" << l.PDiskId << ":" << l.VSlotId << "]";
+ if (vdisk.Bad) {
+ out << "</font>";
+ }
+ if (vdisk.Faulty) {
+ out << "</strong>";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ hFunc(TEvControllerUpdateSelfHealInfo, Handle);
+ hFunc(NMon::TEvRemoteHttpInfo, Handle);
+ hFunc(TEvReassignerDone, Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ })
+ };
+
+ IActor *CreateSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups) {
+ return new TSelfHealActor(tabletId, std::move(unreassignableGroups));
+ }
+
+ void TBlobStorageController::InitializeSelfHealState() {
+ auto ev = MakeHolder<TEvControllerUpdateSelfHealInfo>();
+ for (const auto& [groupId, group] : GroupMap) {
+ ev->GroupsToUpdate.emplace(groupId, TEvControllerUpdateSelfHealInfo::TGroupContent());
+ }
+ FillInSelfHealGroups(*ev, nullptr);
+ Send(SelfHealId, ev.Release());
+ }
+
+ void TBlobStorageController::FillInSelfHealGroups(TEvControllerUpdateSelfHealInfo& msg, TConfigState *state) {
+ for (auto& [groupId, group] : msg.GroupsToUpdate) {
+ if (!group) {
+ continue;
+ }
+
+ const TGroupInfo *p = state ? state->Groups.Find(groupId) : FindGroup(groupId);
+ Y_VERIFY(p);
+
+ group->Generation = p->Generation;
+ group->Type = TBlobStorageGroupType(p->ErasureSpecies);
+
+ for (const TVSlotInfo *slot : p->VDisksInGroup) {
+ group->VDisks[slot->GetVDiskId()] = {
+ slot->VSlotId,
+ slot->PDisk->ShouldBeSettledBySelfHeal(),
+ slot->PDisk->BadInTermsOfSelfHeal(),
+ slot->GetStatus(),
+ };
+ }
+ }
+ }
+
+ void TBlobStorageController::ProcessVDiskStatus(
+ const google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus>& s) {
+ THashSet<TGroupInfo*> groups, status;
+ const TInstant now = TActivationContext::Now();
+ std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ;
+
+ std::unique_ptr<TEvPrivate::TEvDropDonor> dropDonorEv;
+
+ auto ev = MakeHolder<TEvControllerUpdateSelfHealInfo>();
+ for (const auto& m : s) {
+ const TVSlotId vslotId(m.GetNodeId(), m.GetPDiskId(), m.GetVSlotId());
+ const auto vdiskId = VDiskIDFromVDiskID(m.GetVDiskId());
+ if (TVSlotInfo *slot = FindVSlot(vslotId); slot && !slot->IsBeingDeleted() &&
+ slot->PDisk->Guid == m.GetPDiskGuid() && vdiskId.SameExceptGeneration(slot->GetVDiskId())) {
+ const bool was = slot->IsOperational();
+ if (const TGroupInfo *group = slot->Group) {
+ const bool wasReady = slot->IsReady;
+ slot->SetStatus(m.GetStatus(), now);
+ if (slot->IsReady != wasReady) {
+ ScrubState.UpdateVDiskState(slot);
+ if (wasReady) {
+ slot->LastSeenReady = now;
+ lastSeenReadyQ.emplace_back(slot->VSlotId, now);
+ NotReadyVSlotIds.insert(slot->VSlotId);
+ }
+ }
+ ScheduleVSlotReadyUpdate();
+ status.insert(const_cast<TGroupInfo*>(group));
+ ev->VDiskStatusUpdate.emplace_back(vdiskId, m.GetStatus());
+ if (!was && slot->IsOperational() && !group->SeenOperational) {
+ groups.insert(const_cast<TGroupInfo*>(group));
+ }
+ }
+ if (slot->GetStatus() == NKikimrBlobStorage::EVDiskStatus::READY) {
+ // we can release donor slots without further notice then the VDisk is completely replicated; we
+ // intentionally use GetStatus() here instead of IsReady() to prevent waiting
+ for (const auto& [donorVSlotId, donorVDiskId] : slot->Donors) {
+ if (!dropDonorEv) {
+ dropDonorEv.reset(new TEvPrivate::TEvDropDonor);
+ }
+ dropDonorEv->VSlotIds.push_back(donorVSlotId);
+ }
+ }
+ }
+ if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end() && it->second.VDiskId == vdiskId) {
+ it->second.VDiskStatus = m.GetStatus();
+ }
+ }
+
+ if (dropDonorEv) {
+ Send(SelfId(), dropDonorEv.release());
+ }
+
+ // issue updated statuses to self-healer
+ if (ev->VDiskStatusUpdate) {
+ Send(SelfHealId, ev.Release());
+ }
+
+ // update operational status for groups
+ TVector<TGroupId> groupIds;
+ for (TGroupInfo *group : groups) {
+ group->UpdateSeenOperational();
+ if (group->SeenOperational) {
+ groupIds.push_back(group->ID);
+ }
+ }
+ if (groupIds) {
+ Execute(CreateTxUpdateSeenOperational(std::move(groupIds)));
+ }
+
+ if (!lastSeenReadyQ.empty()) {
+ Execute(CreateTxUpdateLastSeenReady(std::move(lastSeenReadyQ)));
+ }
+
+ for (TGroupInfo *group : status) {
+ group->CalculateGroupStatus();
+ }
+ }
+
+ void TBlobStorageController::UpdateSelfHealCounters() {
+ // WARNING: keep this logic consistent with updateSelfHealCounters flag calculation in CommitConfigUpdates
+ const TInstant now = TActivationContext::Now();
+ bool reschedule = false;
+
auto updateDiskCounters = [&](
NKikimrBlobStorage::EDriveStatus status,
NBlobStorageController::EPercentileCounters histCounter,
@@ -654,8 +654,8 @@ namespace NKikimr::NBsController {
histo.IncrementForRange(idx);
reschedule = true;
}
- }
-
+ }
+
// calculate some simple counters
ui64 vslotsOnFaultyPDisks = 0;
ui64 bytesOnFaultyPDisks = 0;
@@ -666,13 +666,13 @@ namespace NKikimr::NBsController {
bytesOnFaultyPDisks += vslot->Metrics.GetAllocatedSize();
groupsWithSlotsOnFaultyPDisks.insert(vslot->GroupId);
}
- }
+ }
auto& s = TabletCounters->Simple();
s[groups].Set(groupsWithSlotsOnFaultyPDisks.size());
s[slots].Set(vslotsOnFaultyPDisks);
s[bytes].Set(bytesOnFaultyPDisks);
};
-
+
updateDiskCounters(
NKikimrBlobStorage::EDriveStatus::FAULTY,
NBlobStorageController::COUNTER_FAULTY_USETTLED_PDISKS,
@@ -689,23 +689,23 @@ namespace NKikimr::NBsController {
NBlobStorageController::COUNTER_BYTES_ON_TO_BE_REMOVED_DISKS
);
- TabletCounters->Simple()[NBlobStorageController::COUNTER_SELF_HEAL_UNREASSIGNABLE_GROUPS] = SelfHealUnreassignableGroups->load();
-
- Schedule(TDuration::Seconds(15), new TEvPrivate::TEvUpdateSelfHealCounters);
- }
-
-} // NKikimr::NBsController
-
-template<>
-void Out<std::nullopt_t>(IOutputStream& out, const std::nullopt_t&) {
- out << "null";
-}
-
-template<>
-void Out<std::optional<NKikimrBlobStorage::EVDiskStatus>>(IOutputStream& out, const std::optional<NKikimrBlobStorage::EVDiskStatus>& s) {
- if (s) {
- out << *s;
- } else {
- out << std::nullopt;
- }
-}
+ TabletCounters->Simple()[NBlobStorageController::COUNTER_SELF_HEAL_UNREASSIGNABLE_GROUPS] = SelfHealUnreassignableGroups->load();
+
+ Schedule(TDuration::Seconds(15), new TEvPrivate::TEvUpdateSelfHealCounters);
+ }
+
+} // NKikimr::NBsController
+
+template<>
+void Out<std::nullopt_t>(IOutputStream& out, const std::nullopt_t&) {
+ out << "null";
+}
+
+template<>
+void Out<std::optional<NKikimrBlobStorage::EVDiskStatus>>(IOutputStream& out, const std::optional<NKikimrBlobStorage::EVDiskStatus>& s) {
+ if (s) {
+ out << *s;
+ } else {
+ out << std::nullopt;
+ }
+}
diff --git a/ydb/core/mind/bscontroller/self_heal.h b/ydb/core/mind/bscontroller/self_heal.h
index 287f05d4670..0b12e46754b 100644
--- a/ydb/core/mind/bscontroller/self_heal.h
+++ b/ydb/core/mind/bscontroller/self_heal.h
@@ -1,34 +1,34 @@
-#pragma once
-
-#include "defs.h"
-
-#include "types.h"
-
-namespace NKikimr::NBsController {
-
- struct TEvControllerUpdateSelfHealInfo : TEventLocal<TEvControllerUpdateSelfHealInfo, TEvBlobStorage::EvControllerUpdateSelfHealInfo> {
- struct TGroupContent {
- struct TVDiskInfo {
- TVSlotId Location;
- bool Faulty;
- bool Bad;
- NKikimrBlobStorage::EVDiskStatus VDiskStatus;
- };
- ui32 Generation;
- TBlobStorageGroupType Type;
- TMap<TVDiskID, TVDiskInfo> VDisks;
- };
-
- THashMap<TGroupId, std::optional<TGroupContent>> GroupsToUpdate; // groups with faulty groups that are changed or got faulty PDisks for the first time
- TVector<std::pair<TVDiskID, NKikimrBlobStorage::EVDiskStatus>> VDiskStatusUpdate;
- };
-
- // Self-heal actor's main purpose is to monitor FAULTY pdisks and to slightly move groups out of them; every move
- // should not render group unusable, also it should not exceed its fail model. It also takes into account replication
- // broker features such as only one vslot over PDisk is being replicated at a moment.
- //
- // It interacts with BS_CONTROLLER and group observer (which provides information about group state on a per-vdisk
- // basis). BS_CONTROLLER reports faulty PDisks and all involved groups in a push notification manner.
- IActor *CreateSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups);
-
-} // NKikimr::NBsController
+#pragma once
+
+#include "defs.h"
+
+#include "types.h"
+
+namespace NKikimr::NBsController {
+
+ struct TEvControllerUpdateSelfHealInfo : TEventLocal<TEvControllerUpdateSelfHealInfo, TEvBlobStorage::EvControllerUpdateSelfHealInfo> {
+ struct TGroupContent {
+ struct TVDiskInfo {
+ TVSlotId Location;
+ bool Faulty;
+ bool Bad;
+ NKikimrBlobStorage::EVDiskStatus VDiskStatus;
+ };
+ ui32 Generation;
+ TBlobStorageGroupType Type;
+ TMap<TVDiskID, TVDiskInfo> VDisks;
+ };
+
+ THashMap<TGroupId, std::optional<TGroupContent>> GroupsToUpdate; // groups with faulty groups that are changed or got faulty PDisks for the first time
+ TVector<std::pair<TVDiskID, NKikimrBlobStorage::EVDiskStatus>> VDiskStatusUpdate;
+ };
+
+ // Self-heal actor's main purpose is to monitor FAULTY pdisks and to slightly move groups out of them; every move
+ // should not render group unusable, also it should not exceed its fail model. It also takes into account replication
+ // broker features such as only one vslot over PDisk is being replicated at a moment.
+ //
+ // It interacts with BS_CONTROLLER and group observer (which provides information about group state on a per-vdisk
+ // basis). BS_CONTROLLER reports faulty PDisks and all involved groups in a push notification manner.
+ IActor *CreateSelfHealActor(ui64 tabletId, std::shared_ptr<std::atomic_uint64_t> unreassignableGroups);
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/stat_processor.cpp b/ydb/core/mind/bscontroller/stat_processor.cpp
index 8cfe681dd42..b5f26745004 100644
--- a/ydb/core/mind/bscontroller/stat_processor.cpp
+++ b/ydb/core/mind/bscontroller/stat_processor.cpp
@@ -1,156 +1,156 @@
-#include "stat_processor.h"
-
-namespace NKikimr::NBsController {
-
- class TStatProcessorActor : public TActorBootstrapped<TStatProcessorActor> {
+#include "stat_processor.h"
+
+namespace NKikimr::NBsController {
+
+ class TStatProcessorActor : public TActorBootstrapped<TStatProcessorActor> {
using TGroupCleanupSchedule = TMultiMap<TInstant, std::pair<TGroupId, TActorId>>;
-
- struct TPerGroupRecord {
- struct TPerAggregatorInfo {
- TGroupStat Stat;
- TGroupCleanupSchedule::iterator ScheduleIter;
- };
-
- TGroupStat Accum;
+
+ struct TPerGroupRecord {
+ struct TPerAggregatorInfo {
+ TGroupStat Stat;
+ TGroupCleanupSchedule::iterator ScheduleIter;
+ };
+
+ TGroupStat Accum;
THashMap<TActorId, TPerAggregatorInfo> PerAggegatorInfo;
- TGroupLatencyStats Stats;
-
- void Update(const NKikimrBlobStorage::TEvGroupStatReport& report, TInstant now, TGroupId groupId, TGroupCleanupSchedule& schedule) {
- TGroupStat stat;
- if (stat.Deserialize(report)) {
+ TGroupLatencyStats Stats;
+
+ void Update(const NKikimrBlobStorage::TEvGroupStatReport& report, TInstant now, TGroupId groupId, TGroupCleanupSchedule& schedule) {
+ TGroupStat stat;
+ if (stat.Deserialize(report)) {
const TActorId vdiskServiceId = ActorIdFromProto(report.GetVDiskServiceId());
- auto& item = PerAggegatorInfo[vdiskServiceId];
- Accum.Replace(stat, item.Stat);
- item.Stat = std::move(stat);
-
- const TInstant barrier = now + TDuration::Seconds(30);
- if (item.ScheduleIter != TGroupCleanupSchedule::iterator()) {
- schedule.erase(item.ScheduleIter);
- }
- item.ScheduleIter = schedule.emplace(barrier, std::make_pair(groupId, vdiskServiceId));
- }
- }
-
+ auto& item = PerAggegatorInfo[vdiskServiceId];
+ Accum.Replace(stat, item.Stat);
+ item.Stat = std::move(stat);
+
+ const TInstant barrier = now + TDuration::Seconds(30);
+ if (item.ScheduleIter != TGroupCleanupSchedule::iterator()) {
+ schedule.erase(item.ScheduleIter);
+ }
+ item.ScheduleIter = schedule.emplace(barrier, std::make_pair(groupId, vdiskServiceId));
+ }
+ }
+
void Cleanup(const TActorId& vdiskServiceId) {
- auto it = PerAggegatorInfo.find(vdiskServiceId);
- Y_VERIFY(it != PerAggegatorInfo.end());
- auto& item = it->second;
- Accum.Subtract(item.Stat);
- PerAggegatorInfo.erase(it);
- }
-
- void RecalculatePercentiles() {
- Stats.PutTabletLog = Accum.GetPercentile(TGroupStat::EKind::PUT_TABLET_LOG, 0.90);
- Stats.PutUserData = Accum.GetPercentile(TGroupStat::EKind::PUT_USER_DATA, 0.90);
- Stats.GetFast = Accum.GetPercentile(TGroupStat::EKind::GET_FAST, 0.90);
- }
- };
-
- static constexpr TDuration UpdatePeriod = TDuration::Seconds(10);
-
+ auto it = PerAggegatorInfo.find(vdiskServiceId);
+ Y_VERIFY(it != PerAggegatorInfo.end());
+ auto& item = it->second;
+ Accum.Subtract(item.Stat);
+ PerAggegatorInfo.erase(it);
+ }
+
+ void RecalculatePercentiles() {
+ Stats.PutTabletLog = Accum.GetPercentile(TGroupStat::EKind::PUT_TABLET_LOG, 0.90);
+ Stats.PutUserData = Accum.GetPercentile(TGroupStat::EKind::PUT_USER_DATA, 0.90);
+ Stats.GetFast = Accum.GetPercentile(TGroupStat::EKind::GET_FAST, 0.90);
+ }
+ };
+
+ static constexpr TDuration UpdatePeriod = TDuration::Seconds(10);
+
TActorId ParentActorId;
- TMap<TGroupId, TPerGroupRecord> Groups;
- TSet<TGroupId> UpdatedGroupIds;
- TGroupCleanupSchedule GroupCleanupSchedule;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BSC_STAT_PROCESSOR;
- }
-
- void Bootstrap(const TActorId& parentActorId) {
- ParentActorId = parentActorId;
- Become(&TThis::StateFunc, UpdatePeriod, new TEvents::TEvWakeup);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvControllerUpdateGroupStat, Handle);
- hFunc(TEvControllerNotifyGroupChange, Handle);
- cFunc(TEvents::TSystem::PoisonPill, PassAway);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- )
-
- void Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr& ev) {
- TSet<TGroupId> ids;
- const TInstant now = TActivationContext::Now();
-
- // apply new report
- auto& record = ev->Get()->Record;
- for (const NKikimrBlobStorage::TEvGroupStatReport& item : record.GetPerGroupReport()) {
- const TGroupId groupId = item.GetGroupId();
- auto it = Groups.find(groupId);
- if (it != Groups.end()) {
- it->second.Update(item, now, groupId, GroupCleanupSchedule);
- ids.insert(groupId);
- }
- }
-
- // cleanup obsolete items from the schedule
- TGroupCleanupSchedule::iterator it;
- for (it = GroupCleanupSchedule.begin(); it != GroupCleanupSchedule.end() && it->first <= now; ++it) {
- TGroupId groupId;
+ TMap<TGroupId, TPerGroupRecord> Groups;
+ TSet<TGroupId> UpdatedGroupIds;
+ TGroupCleanupSchedule GroupCleanupSchedule;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BSC_STAT_PROCESSOR;
+ }
+
+ void Bootstrap(const TActorId& parentActorId) {
+ ParentActorId = parentActorId;
+ Become(&TThis::StateFunc, UpdatePeriod, new TEvents::TEvWakeup);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvControllerUpdateGroupStat, Handle);
+ hFunc(TEvControllerNotifyGroupChange, Handle);
+ cFunc(TEvents::TSystem::PoisonPill, PassAway);
+ cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
+ )
+
+ void Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr& ev) {
+ TSet<TGroupId> ids;
+ const TInstant now = TActivationContext::Now();
+
+ // apply new report
+ auto& record = ev->Get()->Record;
+ for (const NKikimrBlobStorage::TEvGroupStatReport& item : record.GetPerGroupReport()) {
+ const TGroupId groupId = item.GetGroupId();
+ auto it = Groups.find(groupId);
+ if (it != Groups.end()) {
+ it->second.Update(item, now, groupId, GroupCleanupSchedule);
+ ids.insert(groupId);
+ }
+ }
+
+ // cleanup obsolete items from the schedule
+ TGroupCleanupSchedule::iterator it;
+ for (it = GroupCleanupSchedule.begin(); it != GroupCleanupSchedule.end() && it->first <= now; ++it) {
+ TGroupId groupId;
TActorId vdiskServiceId;
- std::tie(groupId, vdiskServiceId) = it->second;
- auto groupIt = Groups.find(groupId);
- if (groupIt != Groups.end()) {
- groupIt->second.Cleanup(vdiskServiceId);
- ids.insert(groupId);
- }
- }
- GroupCleanupSchedule.erase(GroupCleanupSchedule.begin(), it);
-
- // recalculate percentiles for changed groups
- for (const TGroupId groupId : ids) {
- Groups[groupId].RecalculatePercentiles();
- UpdatedGroupIds.insert(groupId);
- }
- }
-
- void Handle(TEvControllerNotifyGroupChange::TPtr& ev) {
- for (TGroupId groupId : ev->Get()->Created) {
- Groups.emplace(groupId, TPerGroupRecord());
- UpdatedGroupIds.insert(groupId);
- }
- for (TGroupId groupId : ev->Get()->Deleted) {
- Groups.erase(groupId);
- UpdatedGroupIds.erase(groupId);
- }
- }
-
- void HandleWakeup() {
- if (UpdatedGroupIds) {
- auto ev = MakeHolder<TEvControllerCommitGroupLatencies>();
-
- const bool scanLowerBound = UpdatedGroupIds.size() <= Groups.size() / 10;
- auto it = Groups.begin();
- for (TGroupId groupId : UpdatedGroupIds) {
- if (scanLowerBound) {
- // use lower bound logic as the number of updated groups is not so big
- it = Groups.lower_bound(groupId);
- } else {
- // advance second iterator to the corresponding group -- it must exist
- for (; it != Groups.end() && it->first < groupId; ++it)
- {}
- }
- Y_VERIFY(it != Groups.end() && it->first == groupId);
-
- // report this group to the event
- ev->Updates.emplace_hint(ev->Updates.end(), groupId, it->second.Stats);
- }
-
- // report updates to the controller
- Send(ParentActorId, ev.Release());
-
- // reset updates
- UpdatedGroupIds.clear();
- }
-
- Schedule(UpdatePeriod, new TEvents::TEvWakeup);
- }
- };
-
- IActor *CreateStatProcessorActor() {
- return new TStatProcessorActor;
- }
-
-} // NKikimr::NBsController
+ std::tie(groupId, vdiskServiceId) = it->second;
+ auto groupIt = Groups.find(groupId);
+ if (groupIt != Groups.end()) {
+ groupIt->second.Cleanup(vdiskServiceId);
+ ids.insert(groupId);
+ }
+ }
+ GroupCleanupSchedule.erase(GroupCleanupSchedule.begin(), it);
+
+ // recalculate percentiles for changed groups
+ for (const TGroupId groupId : ids) {
+ Groups[groupId].RecalculatePercentiles();
+ UpdatedGroupIds.insert(groupId);
+ }
+ }
+
+ void Handle(TEvControllerNotifyGroupChange::TPtr& ev) {
+ for (TGroupId groupId : ev->Get()->Created) {
+ Groups.emplace(groupId, TPerGroupRecord());
+ UpdatedGroupIds.insert(groupId);
+ }
+ for (TGroupId groupId : ev->Get()->Deleted) {
+ Groups.erase(groupId);
+ UpdatedGroupIds.erase(groupId);
+ }
+ }
+
+ void HandleWakeup() {
+ if (UpdatedGroupIds) {
+ auto ev = MakeHolder<TEvControllerCommitGroupLatencies>();
+
+ const bool scanLowerBound = UpdatedGroupIds.size() <= Groups.size() / 10;
+ auto it = Groups.begin();
+ for (TGroupId groupId : UpdatedGroupIds) {
+ if (scanLowerBound) {
+ // use lower bound logic as the number of updated groups is not so big
+ it = Groups.lower_bound(groupId);
+ } else {
+ // advance second iterator to the corresponding group -- it must exist
+ for (; it != Groups.end() && it->first < groupId; ++it)
+ {}
+ }
+ Y_VERIFY(it != Groups.end() && it->first == groupId);
+
+ // report this group to the event
+ ev->Updates.emplace_hint(ev->Updates.end(), groupId, it->second.Stats);
+ }
+
+ // report updates to the controller
+ Send(ParentActorId, ev.Release());
+
+ // reset updates
+ UpdatedGroupIds.clear();
+ }
+
+ Schedule(UpdatePeriod, new TEvents::TEvWakeup);
+ }
+ };
+
+ IActor *CreateStatProcessorActor() {
+ return new TStatProcessorActor;
+ }
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/stat_processor.h b/ydb/core/mind/bscontroller/stat_processor.h
index 6b1ff9a0c97..b4ccb5b6305 100644
--- a/ydb/core/mind/bscontroller/stat_processor.h
+++ b/ydb/core/mind/bscontroller/stat_processor.h
@@ -1,20 +1,20 @@
-#pragma once
-
-#include "defs.h"
-
-#include "types.h"
-
-namespace NKikimr::NBsController {
-
- struct TEvControllerNotifyGroupChange : TEventLocal<TEvControllerNotifyGroupChange, TEvBlobStorage::EvControllerNotifyGroupChange> {
- TVector<TGroupId> Created;
- TVector<TGroupId> Deleted;
- };
-
- struct TEvControllerCommitGroupLatencies : TEventLocal<TEvControllerCommitGroupLatencies, TEvBlobStorage::EvControllerCommitGroupLatencies> {
- TMap<TGroupId, TGroupLatencyStats> Updates;
- };
-
- IActor *CreateStatProcessorActor();
-
-} // NKikimr::NBsController
+#pragma once
+
+#include "defs.h"
+
+#include "types.h"
+
+namespace NKikimr::NBsController {
+
+ struct TEvControllerNotifyGroupChange : TEventLocal<TEvControllerNotifyGroupChange, TEvBlobStorage::EvControllerNotifyGroupChange> {
+ TVector<TGroupId> Created;
+ TVector<TGroupId> Deleted;
+ };
+
+ struct TEvControllerCommitGroupLatencies : TEventLocal<TEvControllerCommitGroupLatencies, TEvBlobStorage::EvControllerCommitGroupLatencies> {
+ TMap<TGroupId, TGroupLatencyStats> Updates;
+ };
+
+ IActor *CreateStatProcessorActor();
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/storage_pool_stat.h b/ydb/core/mind/bscontroller/storage_pool_stat.h
index 0e6527f58ed..db953acfab3 100644
--- a/ydb/core/mind/bscontroller/storage_pool_stat.h
+++ b/ydb/core/mind/bscontroller/storage_pool_stat.h
@@ -1,137 +1,137 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NBsController {
-
- class TStoragePoolStat {
- struct TStoragePoolCounters {
- TString Id;
- NMonitoring::TDynamicCounterPtr Root;
- TString Name;
- NMonitoring::TDynamicCounterPtr Subgroup;
- NMonitoring::TDynamicCounterPtr FlagsSubgroup;
- NMonitoring::TDynamicCounters::TCounterPtr NumUnknown;
- NMonitoring::TDynamicCounters::TCounterPtr NumGreen;
- NMonitoring::TDynamicCounters::TCounterPtr NumCyan;
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NBsController {
+
+ class TStoragePoolStat {
+ struct TStoragePoolCounters {
+ TString Id;
+ NMonitoring::TDynamicCounterPtr Root;
+ TString Name;
+ NMonitoring::TDynamicCounterPtr Subgroup;
+ NMonitoring::TDynamicCounterPtr FlagsSubgroup;
+ NMonitoring::TDynamicCounters::TCounterPtr NumUnknown;
+ NMonitoring::TDynamicCounters::TCounterPtr NumGreen;
+ NMonitoring::TDynamicCounters::TCounterPtr NumCyan;
NMonitoring::TDynamicCounters::TCounterPtr NumLightYellow;
- NMonitoring::TDynamicCounters::TCounterPtr NumYellow;
- NMonitoring::TDynamicCounters::TCounterPtr NumLightOrange;
- NMonitoring::TDynamicCounters::TCounterPtr NumOrange;
- NMonitoring::TDynamicCounters::TCounterPtr NumRed;
- NMonitoring::TDynamicCounters::TCounterPtr NumBlack;
- NMonitoring::TDynamicCounters::TCounterPtr AllocatedSize;
-
- TStoragePoolCounters(NMonitoring::TDynamicCounterPtr counters, TString id, TString name, ui64 allocatedSize)
- : Id(std::move(id))
- , Root(std::move(counters))
- , Name(std::move(name))
- , Subgroup(Root->GetSubgroup("storagePool", Name))
- , FlagsSubgroup(Subgroup->GetSubgroup("subsystem", "flags"))
- , NumUnknown(FlagsSubgroup->GetCounter("unknown"))
- , NumGreen(FlagsSubgroup->GetCounter("green"))
- , NumCyan(FlagsSubgroup->GetCounter("cyan"))
+ NMonitoring::TDynamicCounters::TCounterPtr NumYellow;
+ NMonitoring::TDynamicCounters::TCounterPtr NumLightOrange;
+ NMonitoring::TDynamicCounters::TCounterPtr NumOrange;
+ NMonitoring::TDynamicCounters::TCounterPtr NumRed;
+ NMonitoring::TDynamicCounters::TCounterPtr NumBlack;
+ NMonitoring::TDynamicCounters::TCounterPtr AllocatedSize;
+
+ TStoragePoolCounters(NMonitoring::TDynamicCounterPtr counters, TString id, TString name, ui64 allocatedSize)
+ : Id(std::move(id))
+ , Root(std::move(counters))
+ , Name(std::move(name))
+ , Subgroup(Root->GetSubgroup("storagePool", Name))
+ , FlagsSubgroup(Subgroup->GetSubgroup("subsystem", "flags"))
+ , NumUnknown(FlagsSubgroup->GetCounter("unknown"))
+ , NumGreen(FlagsSubgroup->GetCounter("green"))
+ , NumCyan(FlagsSubgroup->GetCounter("cyan"))
, NumLightYellow(FlagsSubgroup->GetCounter("lightYellow"))
- , NumYellow(FlagsSubgroup->GetCounter("yellow"))
- , NumLightOrange(FlagsSubgroup->GetCounter("lightOrange"))
- , NumOrange(FlagsSubgroup->GetCounter("orange"))
- , NumRed(FlagsSubgroup->GetCounter("red"))
- , NumBlack(FlagsSubgroup->GetCounter("black"))
- , AllocatedSize(Subgroup->GetCounter("allocatedSize"))
- {
- *AllocatedSize = allocatedSize;
- }
-
- void Rename(const TString& name) {
- Root->RemoveSubgroup("storagePool", std::exchange(Name, name));
- Root->RegisterSubgroup("storagePool", Name, Subgroup);
- }
-
- void Update(std::optional<TStorageStatusFlags> previous, std::optional<TStorageStatusFlags> current) {
- if (previous != current) {
- if (previous) {
- GetCounter(*previous)->Dec();
- }
- if (current) {
- GetCounter(*current)->Inc();
- }
- }
- }
-
- void UpdateAllocatedSize(i64 allocatedSizeIncrement) {
- *AllocatedSize += allocatedSizeIncrement;
- }
-
- const NMonitoring::TDynamicCounters::TCounterPtr& GetCounter(TStorageStatusFlags flags) const {
- if (!flags.Check(NKikimrBlobStorage::StatusIsValid)) {
- return NumUnknown;
- } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceBlack)) {
- return NumBlack;
- } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceRed)) {
- return NumRed;
- } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceOrange)) {
- return NumOrange;
- } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceLightOrange)) {
- return NumLightOrange;
+ , NumYellow(FlagsSubgroup->GetCounter("yellow"))
+ , NumLightOrange(FlagsSubgroup->GetCounter("lightOrange"))
+ , NumOrange(FlagsSubgroup->GetCounter("orange"))
+ , NumRed(FlagsSubgroup->GetCounter("red"))
+ , NumBlack(FlagsSubgroup->GetCounter("black"))
+ , AllocatedSize(Subgroup->GetCounter("allocatedSize"))
+ {
+ *AllocatedSize = allocatedSize;
+ }
+
+ void Rename(const TString& name) {
+ Root->RemoveSubgroup("storagePool", std::exchange(Name, name));
+ Root->RegisterSubgroup("storagePool", Name, Subgroup);
+ }
+
+ void Update(std::optional<TStorageStatusFlags> previous, std::optional<TStorageStatusFlags> current) {
+ if (previous != current) {
+ if (previous) {
+ GetCounter(*previous)->Dec();
+ }
+ if (current) {
+ GetCounter(*current)->Inc();
+ }
+ }
+ }
+
+ void UpdateAllocatedSize(i64 allocatedSizeIncrement) {
+ *AllocatedSize += allocatedSizeIncrement;
+ }
+
+ const NMonitoring::TDynamicCounters::TCounterPtr& GetCounter(TStorageStatusFlags flags) const {
+ if (!flags.Check(NKikimrBlobStorage::StatusIsValid)) {
+ return NumUnknown;
+ } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceBlack)) {
+ return NumBlack;
+ } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceRed)) {
+ return NumRed;
+ } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceOrange)) {
+ return NumOrange;
+ } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceLightOrange)) {
+ return NumLightOrange;
} else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceYellowStop)) {
- return NumYellow;
+ return NumYellow;
} else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceLightYellowMove)) {
return NumLightYellow;
- } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceCyan)) {
- return NumCyan;
- } else {
- return NumGreen;
- }
- }
- };
-
- NMonitoring::TDynamicCounterPtr Counters;
- std::unordered_map<TString, TStoragePoolCounters> Map;
-
- public:
- TStoragePoolStat(NMonitoring::TDynamicCounterPtr counters)
- : Counters(std::move(counters))
- {}
-
- ~TStoragePoolStat() {
- for (const auto& [name, value] : Map) {
- Counters->RemoveSubgroup("storagePoolId", value.Id);
- }
- }
-
- void AddStoragePool(const TString& id, const TString& name, ui64 allocatedSize) {
- const bool inserted = Map.try_emplace(id, Counters->GetSubgroup("storagePoolId", id), id, name,
- allocatedSize).second;
- Y_VERIFY(inserted);
- }
-
- void DeleteStoragePool(const TString& id) {
- Counters->RemoveSubgroup("storagePool", id);
- const size_t erased = Map.erase(id);
- Y_VERIFY(erased);
- }
-
- void RenameStoragePool(const TString& id, const TString& name) {
- const auto it = Map.find(id);
- Y_VERIFY(it != Map.end());
- it->second.Rename(name);
- }
-
- void Update(const TString& id, std::optional<TStorageStatusFlags> previous, std::optional<TStorageStatusFlags> current) {
- const auto it = Map.find(id);
- Y_VERIFY(it != Map.end());
- it->second.Update(previous, current);
- }
-
- void UpdateAllocatedSize(const TString& id, i64 allocatedSizeIncrement) {
- const auto it = Map.find(id);
- Y_VERIFY(it != Map.end());
- it->second.UpdateAllocatedSize(allocatedSizeIncrement);
- }
-
- static TString ConvertId(const std::tuple<ui64, ui64>& id) {
- return TStringBuilder() << std::get<0>(id) << ":" << std::get<1>(id);
- }
- };
-
-} // NKikimr::NBsController
+ } else if (flags.Check(NKikimrBlobStorage::StatusDiskSpaceCyan)) {
+ return NumCyan;
+ } else {
+ return NumGreen;
+ }
+ }
+ };
+
+ NMonitoring::TDynamicCounterPtr Counters;
+ std::unordered_map<TString, TStoragePoolCounters> Map;
+
+ public:
+ TStoragePoolStat(NMonitoring::TDynamicCounterPtr counters)
+ : Counters(std::move(counters))
+ {}
+
+ ~TStoragePoolStat() {
+ for (const auto& [name, value] : Map) {
+ Counters->RemoveSubgroup("storagePoolId", value.Id);
+ }
+ }
+
+ void AddStoragePool(const TString& id, const TString& name, ui64 allocatedSize) {
+ const bool inserted = Map.try_emplace(id, Counters->GetSubgroup("storagePoolId", id), id, name,
+ allocatedSize).second;
+ Y_VERIFY(inserted);
+ }
+
+ void DeleteStoragePool(const TString& id) {
+ Counters->RemoveSubgroup("storagePool", id);
+ const size_t erased = Map.erase(id);
+ Y_VERIFY(erased);
+ }
+
+ void RenameStoragePool(const TString& id, const TString& name) {
+ const auto it = Map.find(id);
+ Y_VERIFY(it != Map.end());
+ it->second.Rename(name);
+ }
+
+ void Update(const TString& id, std::optional<TStorageStatusFlags> previous, std::optional<TStorageStatusFlags> current) {
+ const auto it = Map.find(id);
+ Y_VERIFY(it != Map.end());
+ it->second.Update(previous, current);
+ }
+
+ void UpdateAllocatedSize(const TString& id, i64 allocatedSizeIncrement) {
+ const auto it = Map.find(id);
+ Y_VERIFY(it != Map.end());
+ it->second.UpdateAllocatedSize(allocatedSizeIncrement);
+ }
+
+ static TString ConvertId(const std::tuple<ui64, ui64>& id) {
+ return TStringBuilder() << std::get<0>(id) << ":" << std::get<1>(id);
+ }
+ };
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/sys_view.cpp b/ydb/core/mind/bscontroller/sys_view.cpp
index ba9b50cde00..6ea9b81f959 100644
--- a/ydb/core/mind/bscontroller/sys_view.cpp
+++ b/ydb/core/mind/bscontroller/sys_view.cpp
@@ -1,5 +1,5 @@
#include "sys_view.h"
-#include "group_geometry_info.h"
+#include "group_geometry_info.h"
namespace NKikimr::NBsController {
@@ -41,373 +41,373 @@ void FillKey(NKikimrSysView::TStoragePoolKey* key, const TBlobStorageController:
key->SetStoragePoolId(std::get<1>(id));
}
-struct TGroupDiskInfo {
- const NKikimrBlobStorage::TPDiskMetrics *PDiskMetrics;
- const NKikimrBlobStorage::TVDiskMetrics *VDiskMetrics;
- ui32 ExpectedSlotCount;
-};
-
-void CalculateGroupUsageStats(NKikimrSysView::TGroupInfo *info, const std::vector<TGroupDiskInfo>& disks,
- TBlobStorageGroupType type) {
- ui64 allocatedSize = 0;
- ui64 totalSize = 0;
- for (const TGroupDiskInfo& disk : disks) {
- const auto& metrics = *disk.VDiskMetrics;
- if (metrics.HasAllocatedSize()) {
- allocatedSize = Max(allocatedSize, metrics.GetAllocatedSize());
- }
-
- const auto& pdiskMetrics = *disk.PDiskMetrics;
- ui64 slotSize = 0;
- if (pdiskMetrics.HasEnforcedDynamicSlotSize()) {
- slotSize = pdiskMetrics.GetEnforcedDynamicSlotSize();
- } else if (pdiskMetrics.GetTotalSize()) {
- slotSize = pdiskMetrics.GetTotalSize() / disk.ExpectedSlotCount;
- }
-
- if (slotSize) {
- totalSize = Min(totalSize ? totalSize : Max<ui64>(), slotSize);
- }
- }
- const ui64 a = totalSize * disks.size() * type.DataParts() / type.TotalPartCount();
- const ui64 b = allocatedSize * disks.size() * type.DataParts() / type.TotalPartCount();
- info->SetAllocatedSize(b);
- info->SetAvailableSize(b < a ? a - b : 0);
-}
-
+struct TGroupDiskInfo {
+ const NKikimrBlobStorage::TPDiskMetrics *PDiskMetrics;
+ const NKikimrBlobStorage::TVDiskMetrics *VDiskMetrics;
+ ui32 ExpectedSlotCount;
+};
+
+void CalculateGroupUsageStats(NKikimrSysView::TGroupInfo *info, const std::vector<TGroupDiskInfo>& disks,
+ TBlobStorageGroupType type) {
+ ui64 allocatedSize = 0;
+ ui64 totalSize = 0;
+ for (const TGroupDiskInfo& disk : disks) {
+ const auto& metrics = *disk.VDiskMetrics;
+ if (metrics.HasAllocatedSize()) {
+ allocatedSize = Max(allocatedSize, metrics.GetAllocatedSize());
+ }
+
+ const auto& pdiskMetrics = *disk.PDiskMetrics;
+ ui64 slotSize = 0;
+ if (pdiskMetrics.HasEnforcedDynamicSlotSize()) {
+ slotSize = pdiskMetrics.GetEnforcedDynamicSlotSize();
+ } else if (pdiskMetrics.GetTotalSize()) {
+ slotSize = pdiskMetrics.GetTotalSize() / disk.ExpectedSlotCount;
+ }
+
+ if (slotSize) {
+ totalSize = Min(totalSize ? totalSize : Max<ui64>(), slotSize);
+ }
+ }
+ const ui64 a = totalSize * disks.size() * type.DataParts() / type.TotalPartCount();
+ const ui64 b = allocatedSize * disks.size() * type.DataParts() / type.TotalPartCount();
+ info->SetAllocatedSize(b);
+ info->SetAvailableSize(b < a ? a - b : 0);
+}
+
class TSystemViewsCollector : public TActor<TSystemViewsCollector> {
TControllerSystemViewsState State;
- std::optional<std::vector<NKikimrSysView::TStorageStatsEntry>> StorageStats;
- std::vector<std::pair<TPDiskId, const NKikimrSysView::TPDiskInfo*>> PDiskIndex;
- std::vector<std::pair<TVSlotId, const NKikimrSysView::TVSlotInfo*>> VSlotIndex;
- std::vector<std::pair<TGroupId, const NKikimrSysView::TGroupInfo*>> GroupIndex;
- std::vector<std::pair<TBlobStorageController::TBoxStoragePoolId, const NKikimrSysView::TStoragePoolInfo*>> StoragePoolIndex;
- TBlobStorageController::THostRecordMap HostRecords;
- ui32 GroupReserveMin = 0;
- ui32 GroupReservePart = 0;
- NMonitoring::TDynamicCounterPtr Counters;
- std::unordered_set<std::tuple<TString>> PDiskFilterCounters;
- std::unordered_set<std::tuple<TString, TString>> ErasureCounters;
+ std::optional<std::vector<NKikimrSysView::TStorageStatsEntry>> StorageStats;
+ std::vector<std::pair<TPDiskId, const NKikimrSysView::TPDiskInfo*>> PDiskIndex;
+ std::vector<std::pair<TVSlotId, const NKikimrSysView::TVSlotInfo*>> VSlotIndex;
+ std::vector<std::pair<TGroupId, const NKikimrSysView::TGroupInfo*>> GroupIndex;
+ std::vector<std::pair<TBlobStorageController::TBoxStoragePoolId, const NKikimrSysView::TStoragePoolInfo*>> StoragePoolIndex;
+ TBlobStorageController::THostRecordMap HostRecords;
+ ui32 GroupReserveMin = 0;
+ ui32 GroupReservePart = 0;
+ NMonitoring::TDynamicCounterPtr Counters;
+ std::unordered_set<std::tuple<TString>> PDiskFilterCounters;
+ std::unordered_set<std::tuple<TString, TString>> ErasureCounters;
public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::BSC_SYSTEM_VIEWS_COLLECTOR;
}
- TSystemViewsCollector(NMonitoring::TDynamicCounterPtr counters)
+ TSystemViewsCollector(NMonitoring::TDynamicCounterPtr counters)
: TActor(&TSystemViewsCollector::StateWork)
- , Counters(std::move(counters))
+ , Counters(std::move(counters))
{}
- ~TSystemViewsCollector() {
- Counters->RemoveSubgroup("subsystem", "storage_stats");
- }
-
+ ~TSystemViewsCollector() {
+ Counters->RemoveSubgroup("subsystem", "storage_stats");
+ }
+
STRICT_STFUNC(StateWork,
hFunc(TEvControllerUpdateSystemViews, Handle);
hFunc(TEvSysView::TEvGetPDisksRequest, Handle);
hFunc(TEvSysView::TEvGetVSlotsRequest, Handle);
hFunc(TEvSysView::TEvGetGroupsRequest, Handle);
hFunc(TEvSysView::TEvGetStoragePoolsRequest, Handle);
- hFunc(TEvSysView::TEvGetStorageStatsRequest, Handle);
+ hFunc(TEvSysView::TEvGetStorageStatsRequest, Handle);
cFunc(TEvents::TSystem::Poison, PassAway);
)
void Handle(TEvControllerUpdateSystemViews::TPtr& ev) {
- auto *msg = ev->Get();
- auto& newState = msg->State;
- Merge(State.PDisks, newState.PDisks, msg->DeletedPDisks, PDiskIndex);
- Merge(State.VSlots, newState.VSlots, msg->DeletedVSlots, VSlotIndex);
- Merge(State.Groups, newState.Groups, msg->DeletedGroups, GroupIndex);
- Merge(State.StoragePools, newState.StoragePools, msg->DeletedStoragePools, StoragePoolIndex);
- HostRecords = std::move(msg->HostRecords);
- GroupReserveMin = msg->GroupReserveMin;
- GroupReservePart = msg->GroupReservePart;
- GenerateStorageStats();
- }
-
- template<typename TDest, typename TSrc, typename TDeleted, typename TIndex>
- void Merge(TDest& dest, TSrc& src, const TDeleted& deleted, TIndex& index) {
- if (!src.empty() || !deleted.empty()) {
- index.clear();
- }
- for (const auto& key : deleted) {
- dest.erase(key);
- }
- for (auto& [key, _] : src) {
- dest.erase(key);
- }
- dest.merge(std::move(src));
- }
-
- template <typename TResponse, typename TRequest, typename TMap, typename TIndex>
- void Reply(TRequest& request, const TMap& entries, TIndex& index) {
+ auto *msg = ev->Get();
+ auto& newState = msg->State;
+ Merge(State.PDisks, newState.PDisks, msg->DeletedPDisks, PDiskIndex);
+ Merge(State.VSlots, newState.VSlots, msg->DeletedVSlots, VSlotIndex);
+ Merge(State.Groups, newState.Groups, msg->DeletedGroups, GroupIndex);
+ Merge(State.StoragePools, newState.StoragePools, msg->DeletedStoragePools, StoragePoolIndex);
+ HostRecords = std::move(msg->HostRecords);
+ GroupReserveMin = msg->GroupReserveMin;
+ GroupReservePart = msg->GroupReservePart;
+ GenerateStorageStats();
+ }
+
+ template<typename TDest, typename TSrc, typename TDeleted, typename TIndex>
+ void Merge(TDest& dest, TSrc& src, const TDeleted& deleted, TIndex& index) {
+ if (!src.empty() || !deleted.empty()) {
+ index.clear();
+ }
+ for (const auto& key : deleted) {
+ dest.erase(key);
+ }
+ for (auto& [key, _] : src) {
+ dest.erase(key);
+ }
+ dest.merge(std::move(src));
+ }
+
+ template <typename TResponse, typename TRequest, typename TMap, typename TIndex>
+ void Reply(TRequest& request, const TMap& entries, TIndex& index) {
const auto& record = request->Get()->Record;
- auto response = MakeHolder<TResponse>();
-
- if (index.empty() && !entries.empty()) {
- index.reserve(entries.size());
- for (const auto& [key, value] : entries) {
- index.emplace_back(key, &value);
- }
- std::sort(index.begin(), index.end());
- }
-
- auto begin = index.begin();
- auto end = index.end();
- auto comp = [](const auto& kv, const auto& key) { return kv.first < key; };
-
+ auto response = MakeHolder<TResponse>();
+
+ if (index.empty() && !entries.empty()) {
+ index.reserve(entries.size());
+ for (const auto& [key, value] : entries) {
+ index.emplace_back(key, &value);
+ }
+ std::sort(index.begin(), index.end());
+ }
+
+ auto begin = index.begin();
+ auto end = index.end();
+ auto comp = [](const auto& kv, const auto& key) { return kv.first < key; };
+
if (record.HasFrom()) {
- auto from = TransformKey(record.GetFrom());
- begin = std::lower_bound(index.begin(), index.end(), from, comp);
- if (begin != index.end() && begin->first == from && record.HasInclusiveFrom() && !record.GetInclusiveFrom()) {
- ++begin;
+ auto from = TransformKey(record.GetFrom());
+ begin = std::lower_bound(index.begin(), index.end(), from, comp);
+ if (begin != index.end() && begin->first == from && record.HasInclusiveFrom() && !record.GetInclusiveFrom()) {
+ ++begin;
}
}
if (record.HasTo()) {
- auto to = TransformKey(record.GetTo());
- end = std::lower_bound(index.begin(), index.end(), to, comp);
- if (end != index.end() && end->first == to && record.GetInclusiveTo()) {
- ++end;
+ auto to = TransformKey(record.GetTo());
+ end = std::lower_bound(index.begin(), index.end(), to, comp);
+ if (end != index.end() && end->first == to && record.GetInclusiveTo()) {
+ ++end;
}
}
- for (; begin < end; ++begin) {
+ for (; begin < end; ++begin) {
auto* entry = response->Record.AddEntries();
- FillKey(entry->MutableKey(), begin->first);
- entry->MutableInfo()->CopyFrom(*begin->second);
+ FillKey(entry->MutableKey(), begin->first);
+ entry->MutableInfo()->CopyFrom(*begin->second);
}
Send(request->Sender, response.Release());
}
void Handle(TEvSysView::TEvGetPDisksRequest::TPtr& ev) {
- Reply<TEvSysView::TEvGetPDisksResponse>(ev, State.PDisks, PDiskIndex);
+ Reply<TEvSysView::TEvGetPDisksResponse>(ev, State.PDisks, PDiskIndex);
}
void Handle(TEvSysView::TEvGetVSlotsRequest::TPtr& ev) {
- Reply<TEvSysView::TEvGetVSlotsResponse>(ev, State.VSlots, VSlotIndex);
+ Reply<TEvSysView::TEvGetVSlotsResponse>(ev, State.VSlots, VSlotIndex);
}
void Handle(TEvSysView::TEvGetGroupsRequest::TPtr& ev) {
- Reply<TEvSysView::TEvGetGroupsResponse>(ev, State.Groups, GroupIndex);
+ Reply<TEvSysView::TEvGetGroupsResponse>(ev, State.Groups, GroupIndex);
}
void Handle(TEvSysView::TEvGetStoragePoolsRequest::TPtr& ev) {
- Reply<TEvSysView::TEvGetStoragePoolsResponse>(ev, State.StoragePools, StoragePoolIndex);
- }
-
- void Handle(TEvSysView::TEvGetStorageStatsRequest::TPtr& ev) {
- auto response = std::make_unique<TEvSysView::TEvGetStorageStatsResponse>();
- auto& r = response->Record;
- if (StorageStats) {
- for (const auto& item : *StorageStats) {
- auto *e = r.AddEntries();
- e->CopyFrom(item);
- }
- }
- Send(ev->Sender, response.release());
- }
-
- void GenerateStorageStats() {
- StorageStats.emplace();
- auto& v = *StorageStats;
-
- using TEntityKey = std::tuple<TString, TString>; // PDiskFilter, ErasureSpecies
- std::unordered_map<TEntityKey, size_t> entityMap;
- std::unordered_map<TBlobStorageController::TBoxStoragePoolId, size_t> spToEntity;
-
- for (const auto erasure : {TBlobStorageGroupType::ErasureMirror3dc, TBlobStorageGroupType::Erasure4Plus2Block}) {
- for (const NKikimrBlobStorage::EPDiskType type : {NKikimrBlobStorage::ROT, NKikimrBlobStorage::SSD}) {
- TBlobStorageController::TStoragePoolInfo::TPDiskFilter filter{.Type = type};
- TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters{filter};
- TStringStream filterData;
- Save(&filterData, filters);
-
- NKikimrSysView::TStorageStatsEntry e;
- e.SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(filters));
- e.SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
- e.SetPDiskFilterData(filterData.Str());
- entityMap[{e.GetPDiskFilter(), e.GetErasureSpecies()}] = v.size();
- v.push_back(std::move(e));
- }
- }
-
- for (const auto& [key, value] : State.StoragePools) {
- TEntityKey entityKey(value.GetPDiskFilter(), value.GetErasureSpeciesV2());
- const size_t index = entityMap.try_emplace(entityKey, v.size()).first->second;
- if (index == v.size()) {
- NKikimrSysView::TStorageStatsEntry entry;
- entry.SetPDiskFilter(value.GetPDiskFilter());
- entry.SetErasureSpecies(value.GetErasureSpeciesV2());
- entry.SetPDiskFilterData(value.GetPDiskFilterData());
- v.push_back(std::move(entry));
- } else {
- const auto& entry = v[index];
- Y_VERIFY(entry.GetPDiskFilter() == value.GetPDiskFilter());
- Y_VERIFY(entry.GetErasureSpecies() == value.GetErasureSpeciesV2());
- Y_VERIFY(entry.GetPDiskFilterData() == value.GetPDiskFilterData());
- }
- spToEntity[key] = index;
- }
-
- for (const auto& [groupId, group] : State.Groups) {
- const TBlobStorageController::TBoxStoragePoolId key(group.GetBoxId(), group.GetStoragePoolId());
- if (const auto it = spToEntity.find(key); it != spToEntity.end()) {
- auto& e = v[it->second];
- e.SetCurrentGroupsCreated(e.GetCurrentGroupsCreated() + 1);
- e.SetCurrentAllocatedSize(e.GetCurrentAllocatedSize() + group.GetAllocatedSize());
- e.SetCurrentAvailableSize(e.GetCurrentAvailableSize() + group.GetAvailableSize());
- }
- }
-
- auto pdiskFilterCountersToDelete = std::exchange(PDiskFilterCounters, {});
- auto erasureCountersToDelete = std::exchange(ErasureCounters, {});
-
- using T = std::decay_t<decltype(State.PDisks)>::value_type;
- std::unordered_map<TBlobStorageController::TBoxId, std::vector<const T*>> boxes;
- for (const auto& kv : State.PDisks) {
- if (kv.second.HasBoxId()) {
- boxes[kv.second.GetBoxId()].push_back(&kv);
- }
- }
-
- for (auto& entry : v) {
- TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters;
- TStringInput s(entry.GetPDiskFilterData());
- Load(&s, filters);
-
- for (const auto& [boxId, pdisks] : boxes) {
- TBlobStorageGroupType type(TBlobStorageGroupType::ErasureSpeciesByName(entry.GetErasureSpecies()));
- TGroupMapper mapper(TGroupGeometryInfo(type, NKikimrBlobStorage::TGroupGeometry())); // default geometry
-
- for (const auto& kv : pdisks) {
- const auto& [pdiskId, pdisk] = *kv;
- for (const auto& filter : filters) {
- const auto sharedWithOs = pdisk.HasSharedWithOs() ? MakeMaybe(pdisk.GetSharedWithOs()) : Nothing();
- const auto readCentric = pdisk.HasReadCentric() ? MakeMaybe(pdisk.GetReadCentric()) : Nothing();
- if (filter.MatchPDisk(pdisk.GetCategory(), sharedWithOs, readCentric)) {
- const TNodeLocation& location = HostRecords->GetLocation(pdiskId.NodeId);
- const bool ok = mapper.RegisterPDisk(pdiskId, location, true, pdisk.GetNumActiveSlots(),
- pdisk.GetExpectedSlotCount(), nullptr, 0, 0, true);
- Y_VERIFY(ok);
- break;
- }
- }
- }
-
- // calculate number of groups we can create without accounting reserve
- TGroupMapper::TGroupDefinition group;
- TString error;
- std::deque<ui64> groupSizes;
- while (mapper.AllocateGroup(groupSizes.size(), group, nullptr, 0, {}, 0, false, error)) {
- std::vector<TGroupDiskInfo> disks;
- std::deque<NKikimrBlobStorage::TPDiskMetrics> pdiskMetrics;
- std::deque<NKikimrBlobStorage::TVDiskMetrics> vdiskMetrics;
-
- for (const auto& realm : group) {
- for (const auto& domain : realm) {
- for (const auto& pdiskId : domain) {
- if (const auto it = State.PDisks.find(pdiskId); it != State.PDisks.end()) {
- const NKikimrSysView::TPDiskInfo& pdisk = it->second;
- auto& pm = *pdiskMetrics.emplace(pdiskMetrics.end());
- auto& vm = *vdiskMetrics.emplace(vdiskMetrics.end());
- if (pdisk.HasTotalSize()) {
- pm.SetTotalSize(pdisk.GetTotalSize());
- }
- if (pdisk.HasEnforcedDynamicSlotSize()) {
- pm.SetEnforcedDynamicSlotSize(pdisk.GetEnforcedDynamicSlotSize());
- }
- vm.SetAllocatedSize(0);
- disks.push_back({&pm, &vm, pdisk.GetExpectedSlotCount()});
- }
- }
- }
- }
-
- NKikimrSysView::TGroupInfo groupInfo;
- CalculateGroupUsageStats(&groupInfo, disks, type);
- groupSizes.push_back(groupInfo.GetAvailableSize());
-
- group.clear();
- }
-
- std::sort(groupSizes.begin(), groupSizes.end());
-
- // adjust it according to reserve
- const ui32 total = groupSizes.size() + entry.GetCurrentGroupsCreated();
- ui32 reserve = GroupReserveMin;
- while (reserve < groupSizes.size() && (reserve - GroupReserveMin) * 1000000 / total < GroupReservePart) {
- ++reserve;
- }
- reserve = Min<ui32>(reserve, groupSizes.size());
-
- // cut sizes
- while (reserve >= 2) {
- groupSizes.pop_front();
- groupSizes.pop_back();
- }
- if (reserve) {
- groupSizes.pop_front();
- }
-
- entry.SetAvailableGroupsToCreate(entry.GetAvailableGroupsToCreate() + groupSizes.size());
- entry.SetAvailableSizeToCreate(entry.GetAvailableSizeToCreate() + std::accumulate(groupSizes.begin(),
- groupSizes.end(), ui64(0)));
- }
-
- auto g = Counters->GetSubgroup("subsystem", "storage_stats");
-
- PDiskFilterCounters.emplace(entry.GetPDiskFilter());
- pdiskFilterCountersToDelete.erase({entry.GetPDiskFilter()});
- auto pdiskFilterGroup = g->GetSubgroup("pdiskFilter", entry.GetPDiskFilter());
-
- ErasureCounters.emplace(entry.GetPDiskFilter(), entry.GetErasureSpecies());
- erasureCountersToDelete.erase({entry.GetPDiskFilter(), entry.GetErasureSpecies()});
- auto erasureGroup = pdiskFilterGroup->GetSubgroup("erasureSpecies", entry.GetErasureSpecies());
-
- erasureGroup->GetCounter("CurrentGroupsCreated")->Set(entry.GetCurrentGroupsCreated());
- erasureGroup->GetCounter("CurrentAllocatedSize")->Set(entry.GetCurrentAllocatedSize());
- erasureGroup->GetCounter("CurrentAvailableSize")->Set(entry.GetCurrentAvailableSize());
- erasureGroup->GetCounter("AvailableGroupsToCreate")->Set(entry.GetAvailableGroupsToCreate());
- erasureGroup->GetCounter("AvailableSizeToCreate")->Set(entry.GetAvailableSizeToCreate());
- }
-
- for (const auto& item : erasureCountersToDelete) {
- Counters
- ->GetSubgroup("subsystem", "storage_stats")
- ->GetSubgroup("pdiskFilter", std::get<0>(item))
- ->RemoveSubgroup("erasureSpecies", std::get<1>(item));
- }
- for (const auto& item : pdiskFilterCountersToDelete) {
- Counters
- ->GetSubgroup("subsystem", "storage_stats")
- ->RemoveSubgroup("pdiskFilter", std::get<0>(item));
- }
- }
+ Reply<TEvSysView::TEvGetStoragePoolsResponse>(ev, State.StoragePools, StoragePoolIndex);
+ }
+
+ void Handle(TEvSysView::TEvGetStorageStatsRequest::TPtr& ev) {
+ auto response = std::make_unique<TEvSysView::TEvGetStorageStatsResponse>();
+ auto& r = response->Record;
+ if (StorageStats) {
+ for (const auto& item : *StorageStats) {
+ auto *e = r.AddEntries();
+ e->CopyFrom(item);
+ }
+ }
+ Send(ev->Sender, response.release());
+ }
+
+ void GenerateStorageStats() {
+ StorageStats.emplace();
+ auto& v = *StorageStats;
+
+ using TEntityKey = std::tuple<TString, TString>; // PDiskFilter, ErasureSpecies
+ std::unordered_map<TEntityKey, size_t> entityMap;
+ std::unordered_map<TBlobStorageController::TBoxStoragePoolId, size_t> spToEntity;
+
+ for (const auto erasure : {TBlobStorageGroupType::ErasureMirror3dc, TBlobStorageGroupType::Erasure4Plus2Block}) {
+ for (const NKikimrBlobStorage::EPDiskType type : {NKikimrBlobStorage::ROT, NKikimrBlobStorage::SSD}) {
+ TBlobStorageController::TStoragePoolInfo::TPDiskFilter filter{.Type = type};
+ TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters{filter};
+ TStringStream filterData;
+ Save(&filterData, filters);
+
+ NKikimrSysView::TStorageStatsEntry e;
+ e.SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(filters));
+ e.SetErasureSpecies(TBlobStorageGroupType::ErasureSpeciesName(erasure));
+ e.SetPDiskFilterData(filterData.Str());
+ entityMap[{e.GetPDiskFilter(), e.GetErasureSpecies()}] = v.size();
+ v.push_back(std::move(e));
+ }
+ }
+
+ for (const auto& [key, value] : State.StoragePools) {
+ TEntityKey entityKey(value.GetPDiskFilter(), value.GetErasureSpeciesV2());
+ const size_t index = entityMap.try_emplace(entityKey, v.size()).first->second;
+ if (index == v.size()) {
+ NKikimrSysView::TStorageStatsEntry entry;
+ entry.SetPDiskFilter(value.GetPDiskFilter());
+ entry.SetErasureSpecies(value.GetErasureSpeciesV2());
+ entry.SetPDiskFilterData(value.GetPDiskFilterData());
+ v.push_back(std::move(entry));
+ } else {
+ const auto& entry = v[index];
+ Y_VERIFY(entry.GetPDiskFilter() == value.GetPDiskFilter());
+ Y_VERIFY(entry.GetErasureSpecies() == value.GetErasureSpeciesV2());
+ Y_VERIFY(entry.GetPDiskFilterData() == value.GetPDiskFilterData());
+ }
+ spToEntity[key] = index;
+ }
+
+ for (const auto& [groupId, group] : State.Groups) {
+ const TBlobStorageController::TBoxStoragePoolId key(group.GetBoxId(), group.GetStoragePoolId());
+ if (const auto it = spToEntity.find(key); it != spToEntity.end()) {
+ auto& e = v[it->second];
+ e.SetCurrentGroupsCreated(e.GetCurrentGroupsCreated() + 1);
+ e.SetCurrentAllocatedSize(e.GetCurrentAllocatedSize() + group.GetAllocatedSize());
+ e.SetCurrentAvailableSize(e.GetCurrentAvailableSize() + group.GetAvailableSize());
+ }
+ }
+
+ auto pdiskFilterCountersToDelete = std::exchange(PDiskFilterCounters, {});
+ auto erasureCountersToDelete = std::exchange(ErasureCounters, {});
+
+ using T = std::decay_t<decltype(State.PDisks)>::value_type;
+ std::unordered_map<TBlobStorageController::TBoxId, std::vector<const T*>> boxes;
+ for (const auto& kv : State.PDisks) {
+ if (kv.second.HasBoxId()) {
+ boxes[kv.second.GetBoxId()].push_back(&kv);
+ }
+ }
+
+ for (auto& entry : v) {
+ TSet<TBlobStorageController::TStoragePoolInfo::TPDiskFilter> filters;
+ TStringInput s(entry.GetPDiskFilterData());
+ Load(&s, filters);
+
+ for (const auto& [boxId, pdisks] : boxes) {
+ TBlobStorageGroupType type(TBlobStorageGroupType::ErasureSpeciesByName(entry.GetErasureSpecies()));
+ TGroupMapper mapper(TGroupGeometryInfo(type, NKikimrBlobStorage::TGroupGeometry())); // default geometry
+
+ for (const auto& kv : pdisks) {
+ const auto& [pdiskId, pdisk] = *kv;
+ for (const auto& filter : filters) {
+ const auto sharedWithOs = pdisk.HasSharedWithOs() ? MakeMaybe(pdisk.GetSharedWithOs()) : Nothing();
+ const auto readCentric = pdisk.HasReadCentric() ? MakeMaybe(pdisk.GetReadCentric()) : Nothing();
+ if (filter.MatchPDisk(pdisk.GetCategory(), sharedWithOs, readCentric)) {
+ const TNodeLocation& location = HostRecords->GetLocation(pdiskId.NodeId);
+ const bool ok = mapper.RegisterPDisk(pdiskId, location, true, pdisk.GetNumActiveSlots(),
+ pdisk.GetExpectedSlotCount(), nullptr, 0, 0, true);
+ Y_VERIFY(ok);
+ break;
+ }
+ }
+ }
+
+ // calculate number of groups we can create without accounting reserve
+ TGroupMapper::TGroupDefinition group;
+ TString error;
+ std::deque<ui64> groupSizes;
+ while (mapper.AllocateGroup(groupSizes.size(), group, nullptr, 0, {}, 0, false, error)) {
+ std::vector<TGroupDiskInfo> disks;
+ std::deque<NKikimrBlobStorage::TPDiskMetrics> pdiskMetrics;
+ std::deque<NKikimrBlobStorage::TVDiskMetrics> vdiskMetrics;
+
+ for (const auto& realm : group) {
+ for (const auto& domain : realm) {
+ for (const auto& pdiskId : domain) {
+ if (const auto it = State.PDisks.find(pdiskId); it != State.PDisks.end()) {
+ const NKikimrSysView::TPDiskInfo& pdisk = it->second;
+ auto& pm = *pdiskMetrics.emplace(pdiskMetrics.end());
+ auto& vm = *vdiskMetrics.emplace(vdiskMetrics.end());
+ if (pdisk.HasTotalSize()) {
+ pm.SetTotalSize(pdisk.GetTotalSize());
+ }
+ if (pdisk.HasEnforcedDynamicSlotSize()) {
+ pm.SetEnforcedDynamicSlotSize(pdisk.GetEnforcedDynamicSlotSize());
+ }
+ vm.SetAllocatedSize(0);
+ disks.push_back({&pm, &vm, pdisk.GetExpectedSlotCount()});
+ }
+ }
+ }
+ }
+
+ NKikimrSysView::TGroupInfo groupInfo;
+ CalculateGroupUsageStats(&groupInfo, disks, type);
+ groupSizes.push_back(groupInfo.GetAvailableSize());
+
+ group.clear();
+ }
+
+ std::sort(groupSizes.begin(), groupSizes.end());
+
+ // adjust it according to reserve
+ const ui32 total = groupSizes.size() + entry.GetCurrentGroupsCreated();
+ ui32 reserve = GroupReserveMin;
+ while (reserve < groupSizes.size() && (reserve - GroupReserveMin) * 1000000 / total < GroupReservePart) {
+ ++reserve;
+ }
+ reserve = Min<ui32>(reserve, groupSizes.size());
+
+ // cut sizes
+ while (reserve >= 2) {
+ groupSizes.pop_front();
+ groupSizes.pop_back();
+ }
+ if (reserve) {
+ groupSizes.pop_front();
+ }
+
+ entry.SetAvailableGroupsToCreate(entry.GetAvailableGroupsToCreate() + groupSizes.size());
+ entry.SetAvailableSizeToCreate(entry.GetAvailableSizeToCreate() + std::accumulate(groupSizes.begin(),
+ groupSizes.end(), ui64(0)));
+ }
+
+ auto g = Counters->GetSubgroup("subsystem", "storage_stats");
+
+ PDiskFilterCounters.emplace(entry.GetPDiskFilter());
+ pdiskFilterCountersToDelete.erase({entry.GetPDiskFilter()});
+ auto pdiskFilterGroup = g->GetSubgroup("pdiskFilter", entry.GetPDiskFilter());
+
+ ErasureCounters.emplace(entry.GetPDiskFilter(), entry.GetErasureSpecies());
+ erasureCountersToDelete.erase({entry.GetPDiskFilter(), entry.GetErasureSpecies()});
+ auto erasureGroup = pdiskFilterGroup->GetSubgroup("erasureSpecies", entry.GetErasureSpecies());
+
+ erasureGroup->GetCounter("CurrentGroupsCreated")->Set(entry.GetCurrentGroupsCreated());
+ erasureGroup->GetCounter("CurrentAllocatedSize")->Set(entry.GetCurrentAllocatedSize());
+ erasureGroup->GetCounter("CurrentAvailableSize")->Set(entry.GetCurrentAvailableSize());
+ erasureGroup->GetCounter("AvailableGroupsToCreate")->Set(entry.GetAvailableGroupsToCreate());
+ erasureGroup->GetCounter("AvailableSizeToCreate")->Set(entry.GetAvailableSizeToCreate());
+ }
+
+ for (const auto& item : erasureCountersToDelete) {
+ Counters
+ ->GetSubgroup("subsystem", "storage_stats")
+ ->GetSubgroup("pdiskFilter", std::get<0>(item))
+ ->RemoveSubgroup("erasureSpecies", std::get<1>(item));
+ }
+ for (const auto& item : pdiskFilterCountersToDelete) {
+ Counters
+ ->GetSubgroup("subsystem", "storage_stats")
+ ->RemoveSubgroup("pdiskFilter", std::get<0>(item));
+ }
+ }
};
-IActor* TBlobStorageController::CreateSystemViewsCollector() {
- return new TSystemViewsCollector(GetServiceCounters(AppData()->Counters, "storage_pool_stat"));
+IActor* TBlobStorageController::CreateSystemViewsCollector() {
+ return new TSystemViewsCollector(GetServiceCounters(AppData()->Counters, "storage_pool_stat"));
}
-void TBlobStorageController::ForwardToSystemViewsCollector(STATEFN_SIG) {
- TActivationContext::Send(ev->Forward(SystemViewsCollectorId));
+void TBlobStorageController::ForwardToSystemViewsCollector(STATEFN_SIG) {
+ TActivationContext::Send(ev->Forward(SystemViewsCollectorId));
}
-void TBlobStorageController::Handle(TEvPrivate::TEvUpdateSystemViews::TPtr&) {
- UpdateSystemViews();
+void TBlobStorageController::Handle(TEvPrivate::TEvUpdateSystemViews::TPtr&) {
+ UpdateSystemViews();
}
void CopyInfo(NKikimrSysView::TPDiskInfo* info, const THolder<TBlobStorageController::TPDiskInfo>& pDiskInfo) {
TPDiskCategory category(pDiskInfo->Kind);
info->SetType(category.TypeStrShort());
info->SetKind(category.Kind());
- info->SetCategory(category);
+ info->SetCategory(category);
info->SetPath(pDiskInfo->Path);
info->SetGuid(pDiskInfo->Guid);
- info->SetBoxId(pDiskInfo->BoxId);
+ info->SetBoxId(pDiskInfo->BoxId);
if (pDiskInfo->SharedWithOs) {
info->SetSharedWithOs(*pDiskInfo->SharedWithOs);
}
@@ -417,59 +417,59 @@ void CopyInfo(NKikimrSysView::TPDiskInfo* info, const THolder<TBlobStorageContro
info->SetAvailableSize(pDiskInfo->Metrics.GetAvailableSize());
info->SetTotalSize(pDiskInfo->Metrics.GetTotalSize());
info->SetStatusV2(NKikimrBlobStorage::EDriveStatus_Name(pDiskInfo->Status));
- if (pDiskInfo->StatusTimestamp != TInstant::Zero()) {
- info->SetStatusChangeTimestamp(pDiskInfo->StatusTimestamp.GetValue());
- }
- if (pDiskInfo->Metrics.HasEnforcedDynamicSlotSize()) {
- info->SetEnforcedDynamicSlotSize(pDiskInfo->Metrics.GetEnforcedDynamicSlotSize());
- }
- info->SetExpectedSlotCount(pDiskInfo->ExpectedSlotCount);
- info->SetNumActiveSlots(pDiskInfo->NumActiveSlots + pDiskInfo->StaticSlotUsage);
-}
-
-void SerializeVSlotInfo(NKikimrSysView::TVSlotInfo *pb, const TVDiskID& vdiskId, const NKikimrBlobStorage::TVDiskMetrics& m,
- NKikimrBlobStorage::EVDiskStatus status, NKikimrBlobStorage::TVDiskKind::EVDiskKind kind, bool isBeingDeleted) {
- pb->SetGroupId(vdiskId.GroupID);
- pb->SetGroupGeneration(vdiskId.GroupGeneration);
- pb->SetFailRealm(vdiskId.FailRealm);
- pb->SetFailDomain(vdiskId.FailDomain);
- pb->SetVDisk(vdiskId.VDisk);
- if (m.HasAllocatedSize()) {
- pb->SetAllocatedSize(m.GetAllocatedSize());
- }
- if (m.HasAvailableSize()) {
- pb->SetAvailableSize(m.GetAvailableSize());
- }
- pb->SetStatusV2(NKikimrBlobStorage::EVDiskStatus_Name(status));
- pb->SetKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(kind));
- if (isBeingDeleted) {
- pb->SetIsBeingDeleted(true);
- }
+ if (pDiskInfo->StatusTimestamp != TInstant::Zero()) {
+ info->SetStatusChangeTimestamp(pDiskInfo->StatusTimestamp.GetValue());
+ }
+ if (pDiskInfo->Metrics.HasEnforcedDynamicSlotSize()) {
+ info->SetEnforcedDynamicSlotSize(pDiskInfo->Metrics.GetEnforcedDynamicSlotSize());
+ }
+ info->SetExpectedSlotCount(pDiskInfo->ExpectedSlotCount);
+ info->SetNumActiveSlots(pDiskInfo->NumActiveSlots + pDiskInfo->StaticSlotUsage);
}
+void SerializeVSlotInfo(NKikimrSysView::TVSlotInfo *pb, const TVDiskID& vdiskId, const NKikimrBlobStorage::TVDiskMetrics& m,
+ NKikimrBlobStorage::EVDiskStatus status, NKikimrBlobStorage::TVDiskKind::EVDiskKind kind, bool isBeingDeleted) {
+ pb->SetGroupId(vdiskId.GroupID);
+ pb->SetGroupGeneration(vdiskId.GroupGeneration);
+ pb->SetFailRealm(vdiskId.FailRealm);
+ pb->SetFailDomain(vdiskId.FailDomain);
+ pb->SetVDisk(vdiskId.VDisk);
+ if (m.HasAllocatedSize()) {
+ pb->SetAllocatedSize(m.GetAllocatedSize());
+ }
+ if (m.HasAvailableSize()) {
+ pb->SetAvailableSize(m.GetAvailableSize());
+ }
+ pb->SetStatusV2(NKikimrBlobStorage::EVDiskStatus_Name(status));
+ pb->SetKind(NKikimrBlobStorage::TVDiskKind::EVDiskKind_Name(kind));
+ if (isBeingDeleted) {
+ pb->SetIsBeingDeleted(true);
+ }
+}
+
void CopyInfo(NKikimrSysView::TVSlotInfo* info, const THolder<TBlobStorageController::TVSlotInfo>& vSlotInfo) {
- SerializeVSlotInfo(info, vSlotInfo->GetVDiskId(), vSlotInfo->Metrics, vSlotInfo->GetStatus(), vSlotInfo->Kind,
- vSlotInfo->IsBeingDeleted());
+ SerializeVSlotInfo(info, vSlotInfo->GetVDiskId(), vSlotInfo->Metrics, vSlotInfo->GetStatus(), vSlotInfo->Kind,
+ vSlotInfo->IsBeingDeleted());
}
void CopyInfo(NKikimrSysView::TGroupInfo* info, const THolder<TBlobStorageController::TGroupInfo>& groupInfo) {
info->SetGeneration(groupInfo->Generation);
info->SetErasureSpeciesV2(TErasureType::ErasureSpeciesName(groupInfo->ErasureSpecies));
- info->SetBoxId(std::get<0>(groupInfo->StoragePoolId));
- info->SetStoragePoolId(std::get<1>(groupInfo->StoragePoolId));
+ info->SetBoxId(std::get<0>(groupInfo->StoragePoolId));
+ info->SetStoragePoolId(std::get<1>(groupInfo->StoragePoolId));
if (groupInfo->EncryptionMode) {
info->SetEncryptionMode(*groupInfo->EncryptionMode);
}
if (groupInfo->LifeCyclePhase) {
info->SetLifeCyclePhase(*groupInfo->LifeCyclePhase);
}
-
- std::vector<TGroupDiskInfo> disks;
- for (const auto& vslot : groupInfo->VDisksInGroup) {
- disks.push_back({&vslot->PDisk->Metrics, &vslot->Metrics, vslot->PDisk->ExpectedSlotCount});
+
+ std::vector<TGroupDiskInfo> disks;
+ for (const auto& vslot : groupInfo->VDisksInGroup) {
+ disks.push_back({&vslot->PDisk->Metrics, &vslot->Metrics, vslot->PDisk->ExpectedSlotCount});
}
- CalculateGroupUsageStats(info, disks, TBlobStorageGroupType(groupInfo->ErasureSpecies));
-
+ CalculateGroupUsageStats(info, disks, TBlobStorageGroupType(groupInfo->ErasureSpecies));
+
info->SetSeenOperational(groupInfo->SeenOperational);
const auto& latencyStats = groupInfo->LatencyStats;
if (latencyStats.PutTabletLog) {
@@ -501,112 +501,112 @@ void CopyInfo(NKikimrSysView::TStoragePoolInfo* info, const TBlobStorageControll
if (poolInfo.PathItemId) {
info->SetPathId(*poolInfo.PathItemId);
}
-
- info->SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(poolInfo.PDiskFilters));
-
- TStringStream pdiskFilterData;
- Save(&pdiskFilterData, poolInfo.PDiskFilters);
- info->SetPDiskFilterData(pdiskFilterData.Str());
+
+ info->SetPDiskFilter(TBlobStorageController::TStoragePoolInfo::TPDiskFilter::ToString(poolInfo.PDiskFilters));
+
+ TStringStream pdiskFilterData;
+ Save(&pdiskFilterData, poolInfo.PDiskFilters);
+ info->SetPDiskFilterData(pdiskFilterData.Str());
}
-template<typename TDstMap, typename TDeletedSet, typename TSrcMap, typename TChangedSet>
-void CopyInfo(TDstMap& dst, TDeletedSet& deleted, const TSrcMap& src, TChangedSet& changed) {
- for (const auto& key : changed) {
- if (const auto it = src.find(key); it != src.end()) {
- CopyInfo(&dst[key], it->second);
- } else {
- deleted.insert(key);
- }
+template<typename TDstMap, typename TDeletedSet, typename TSrcMap, typename TChangedSet>
+void CopyInfo(TDstMap& dst, TDeletedSet& deleted, const TSrcMap& src, TChangedSet& changed) {
+ for (const auto& key : changed) {
+ if (const auto it = src.find(key); it != src.end()) {
+ CopyInfo(&dst[key], it->second);
+ } else {
+ deleted.insert(key);
+ }
}
- changed.clear();
+ changed.clear();
}
-void TBlobStorageController::UpdateSystemViews() {
+void TBlobStorageController::UpdateSystemViews() {
if (!AppData()->FeatureFlags.GetEnableSystemViews()) {
return;
}
- if (!SysViewChangedPDisks.empty() || !SysViewChangedVSlots.empty() || !SysViewChangedGroups.empty() ||
- !SysViewChangedStoragePools.empty()) {
- auto update = MakeHolder<TEvControllerUpdateSystemViews>();
- update->HostRecords = HostRecords;
- update->GroupReserveMin = GroupReserveMin;
- update->GroupReservePart = GroupReservePart;
-
- auto& state = update->State;
- CopyInfo(state.PDisks, update->DeletedPDisks, PDisks, SysViewChangedPDisks);
- CopyInfo(state.VSlots, update->DeletedVSlots, VSlots, SysViewChangedVSlots);
- CopyInfo(state.Groups, update->DeletedGroups, GroupMap, SysViewChangedGroups);
- CopyInfo(state.StoragePools, update->DeletedStoragePools, StoragePools, SysViewChangedStoragePools);
- SysViewChangedSettings = false;
-
- // process static slots and static groups
- for (const auto& [pdiskId, pdisk] : StaticPDisks) {
- if (SysViewChangedPDisks.count(pdiskId) && !FindPDisk(pdiskId)) {
- auto *pb = &state.PDisks[pdiskId];
- TPDiskCategory category(pdisk.Category);
- pb->SetType(category.TypeStrShort());
- pb->SetKind(category.Kind());
- pb->SetCategory(category);
- pb->SetPath(pdisk.Path);
- pb->SetGuid(pdisk.Guid);
- if (pdisk.PDiskMetrics) {
- pb->SetAvailableSize(pdisk.PDiskMetrics->GetAvailableSize());
- pb->SetTotalSize(pdisk.PDiskMetrics->GetTotalSize());
- if (pdisk.PDiskMetrics->HasEnforcedDynamicSlotSize()) {
- pb->SetEnforcedDynamicSlotSize(pdisk.PDiskMetrics->GetEnforcedDynamicSlotSize());
- }
- }
- pb->SetStatusV2(NKikimrBlobStorage::EDriveStatus_Name(NKikimrBlobStorage::EDriveStatus::ACTIVE));
- pb->SetExpectedSlotCount(pdisk.ExpectedSlotCount ? pdisk.ExpectedSlotCount : pdisk.StaticSlotUsage);
- pb->SetNumActiveSlots(pdisk.StaticSlotUsage);
- }
- }
- for (const auto& [vslotId, vslot] : StaticVSlots) {
- if (SysViewChangedVSlots.count(vslotId)) {
- static const NKikimrBlobStorage::TVDiskMetrics zero;
- SerializeVSlotInfo(&state.VSlots[vslotId], vslot.VDiskId, vslot.VDiskMetrics ? *vslot.VDiskMetrics : zero,
- vslot.VDiskStatus, vslot.VDiskKind, false);
- }
- }
- for (const auto& group : AppData()->StaticBlobStorageConfig->GetGroups()) {
- if (!SysViewChangedGroups.count(group.GetGroupID())) {
- continue;
- }
- auto *pb = &state.Groups[group.GetGroupID()];
- pb->SetGeneration(group.GetGroupGeneration());
- pb->SetEncryptionMode(group.GetEncryptionMode());
- pb->SetLifeCyclePhase(group.GetLifeCyclePhase());
- pb->SetSeenOperational(true);
- pb->SetErasureSpeciesV2(TBlobStorageGroupType::ErasureSpeciesName(group.GetErasureSpecies()));
-
- const NKikimrBlobStorage::TVDiskMetrics zero;
- std::vector<TGroupDiskInfo> disks;
- for (const auto& realm : group.GetRings()) {
- for (const auto& domain : realm.GetFailDomains()) {
- for (const auto& location : domain.GetVDiskLocations()) {
- const TVSlotId vslotId(location.GetNodeID(), location.GetPDiskID(), location.GetVDiskSlotID());
- TGroupDiskInfo disk{nullptr, nullptr, 0};
- if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end()) {
- disk.VDiskMetrics = it->second.VDiskMetrics ? &*it->second.VDiskMetrics : &zero;
- }
- if (const auto it = PDisks.find(vslotId.ComprisingPDiskId()); it != PDisks.end()) {
- disk.PDiskMetrics = &it->second->Metrics;
- disk.ExpectedSlotCount = it->second->ExpectedSlotCount;
- }
- if (disk.VDiskMetrics && disk.PDiskMetrics) {
- disks.push_back(std::move(disk));
- }
- }
- }
- }
- CalculateGroupUsageStats(pb, disks, (TBlobStorageGroupType::EErasureSpecies)group.GetErasureSpecies());
- }
-
- Send(SystemViewsCollectorId, update.Release());
- }
-
- Schedule(UpdateSystemViewsPeriod, new TEvPrivate::TEvUpdateSystemViews);
+ if (!SysViewChangedPDisks.empty() || !SysViewChangedVSlots.empty() || !SysViewChangedGroups.empty() ||
+ !SysViewChangedStoragePools.empty()) {
+ auto update = MakeHolder<TEvControllerUpdateSystemViews>();
+ update->HostRecords = HostRecords;
+ update->GroupReserveMin = GroupReserveMin;
+ update->GroupReservePart = GroupReservePart;
+
+ auto& state = update->State;
+ CopyInfo(state.PDisks, update->DeletedPDisks, PDisks, SysViewChangedPDisks);
+ CopyInfo(state.VSlots, update->DeletedVSlots, VSlots, SysViewChangedVSlots);
+ CopyInfo(state.Groups, update->DeletedGroups, GroupMap, SysViewChangedGroups);
+ CopyInfo(state.StoragePools, update->DeletedStoragePools, StoragePools, SysViewChangedStoragePools);
+ SysViewChangedSettings = false;
+
+ // process static slots and static groups
+ for (const auto& [pdiskId, pdisk] : StaticPDisks) {
+ if (SysViewChangedPDisks.count(pdiskId) && !FindPDisk(pdiskId)) {
+ auto *pb = &state.PDisks[pdiskId];
+ TPDiskCategory category(pdisk.Category);
+ pb->SetType(category.TypeStrShort());
+ pb->SetKind(category.Kind());
+ pb->SetCategory(category);
+ pb->SetPath(pdisk.Path);
+ pb->SetGuid(pdisk.Guid);
+ if (pdisk.PDiskMetrics) {
+ pb->SetAvailableSize(pdisk.PDiskMetrics->GetAvailableSize());
+ pb->SetTotalSize(pdisk.PDiskMetrics->GetTotalSize());
+ if (pdisk.PDiskMetrics->HasEnforcedDynamicSlotSize()) {
+ pb->SetEnforcedDynamicSlotSize(pdisk.PDiskMetrics->GetEnforcedDynamicSlotSize());
+ }
+ }
+ pb->SetStatusV2(NKikimrBlobStorage::EDriveStatus_Name(NKikimrBlobStorage::EDriveStatus::ACTIVE));
+ pb->SetExpectedSlotCount(pdisk.ExpectedSlotCount ? pdisk.ExpectedSlotCount : pdisk.StaticSlotUsage);
+ pb->SetNumActiveSlots(pdisk.StaticSlotUsage);
+ }
+ }
+ for (const auto& [vslotId, vslot] : StaticVSlots) {
+ if (SysViewChangedVSlots.count(vslotId)) {
+ static const NKikimrBlobStorage::TVDiskMetrics zero;
+ SerializeVSlotInfo(&state.VSlots[vslotId], vslot.VDiskId, vslot.VDiskMetrics ? *vslot.VDiskMetrics : zero,
+ vslot.VDiskStatus, vslot.VDiskKind, false);
+ }
+ }
+ for (const auto& group : AppData()->StaticBlobStorageConfig->GetGroups()) {
+ if (!SysViewChangedGroups.count(group.GetGroupID())) {
+ continue;
+ }
+ auto *pb = &state.Groups[group.GetGroupID()];
+ pb->SetGeneration(group.GetGroupGeneration());
+ pb->SetEncryptionMode(group.GetEncryptionMode());
+ pb->SetLifeCyclePhase(group.GetLifeCyclePhase());
+ pb->SetSeenOperational(true);
+ pb->SetErasureSpeciesV2(TBlobStorageGroupType::ErasureSpeciesName(group.GetErasureSpecies()));
+
+ const NKikimrBlobStorage::TVDiskMetrics zero;
+ std::vector<TGroupDiskInfo> disks;
+ for (const auto& realm : group.GetRings()) {
+ for (const auto& domain : realm.GetFailDomains()) {
+ for (const auto& location : domain.GetVDiskLocations()) {
+ const TVSlotId vslotId(location.GetNodeID(), location.GetPDiskID(), location.GetVDiskSlotID());
+ TGroupDiskInfo disk{nullptr, nullptr, 0};
+ if (const auto it = StaticVSlots.find(vslotId); it != StaticVSlots.end()) {
+ disk.VDiskMetrics = it->second.VDiskMetrics ? &*it->second.VDiskMetrics : &zero;
+ }
+ if (const auto it = PDisks.find(vslotId.ComprisingPDiskId()); it != PDisks.end()) {
+ disk.PDiskMetrics = &it->second->Metrics;
+ disk.ExpectedSlotCount = it->second->ExpectedSlotCount;
+ }
+ if (disk.VDiskMetrics && disk.PDiskMetrics) {
+ disks.push_back(std::move(disk));
+ }
+ }
+ }
+ }
+ CalculateGroupUsageStats(pb, disks, (TBlobStorageGroupType::EErasureSpecies)group.GetErasureSpecies());
+ }
+
+ Send(SystemViewsCollectorId, update.Release());
+ }
+
+ Schedule(UpdateSystemViewsPeriod, new TEvPrivate::TEvUpdateSystemViews);
}
} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/sys_view.h b/ydb/core/mind/bscontroller/sys_view.h
index 9effe8c5bb8..a76722ebed0 100644
--- a/ydb/core/mind/bscontroller/sys_view.h
+++ b/ydb/core/mind/bscontroller/sys_view.h
@@ -5,24 +5,24 @@
namespace NKikimr::NBsController {
struct TControllerSystemViewsState {
- std::unordered_map<TPDiskId, NKikimrSysView::TPDiskInfo, THash<TPDiskId>> PDisks;
- std::unordered_map<TVSlotId, NKikimrSysView::TVSlotInfo, THash<TVSlotId>> VSlots;
- std::unordered_map<TGroupId, NKikimrSysView::TGroupInfo, THash<TGroupId>> Groups;
- std::unordered_map<TBlobStorageController::TBoxStoragePoolId, NKikimrSysView::TStoragePoolInfo,
- THash<TBlobStorageController::TBoxStoragePoolId>> StoragePools;
+ std::unordered_map<TPDiskId, NKikimrSysView::TPDiskInfo, THash<TPDiskId>> PDisks;
+ std::unordered_map<TVSlotId, NKikimrSysView::TVSlotInfo, THash<TVSlotId>> VSlots;
+ std::unordered_map<TGroupId, NKikimrSysView::TGroupInfo, THash<TGroupId>> Groups;
+ std::unordered_map<TBlobStorageController::TBoxStoragePoolId, NKikimrSysView::TStoragePoolInfo,
+ THash<TBlobStorageController::TBoxStoragePoolId>> StoragePools;
};
struct TEvControllerUpdateSystemViews :
TEventLocal<TEvControllerUpdateSystemViews, TEvBlobStorage::EvControllerUpdateSystemViews>
{
TControllerSystemViewsState State;
- std::unordered_set<TPDiskId, THash<TPDiskId>> DeletedPDisks;
- std::unordered_set<TVSlotId, THash<TVSlotId>> DeletedVSlots;
- std::unordered_set<TGroupId, THash<TGroupId>> DeletedGroups;
- std::unordered_set<TBlobStorageController::TBoxStoragePoolId, THash<TBlobStorageController::TBoxStoragePoolId>> DeletedStoragePools;
- TBlobStorageController::THostRecordMap HostRecords;
- ui32 GroupReserveMin;
- ui32 GroupReservePart;
+ std::unordered_set<TPDiskId, THash<TPDiskId>> DeletedPDisks;
+ std::unordered_set<TVSlotId, THash<TVSlotId>> DeletedVSlots;
+ std::unordered_set<TGroupId, THash<TGroupId>> DeletedGroups;
+ std::unordered_set<TBlobStorageController::TBoxStoragePoolId, THash<TBlobStorageController::TBoxStoragePoolId>> DeletedStoragePools;
+ TBlobStorageController::THostRecordMap HostRecords;
+ ui32 GroupReserveMin;
+ ui32 GroupReservePart;
};
} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/table_merger.h b/ydb/core/mind/bscontroller/table_merger.h
index d63db583eef..9a7e18cf3dc 100644
--- a/ydb/core/mind/bscontroller/table_merger.h
+++ b/ydb/core/mind/bscontroller/table_merger.h
@@ -1,111 +1,111 @@
-#pragma once
-
-#include "defs.h"
-#include "diff.h"
-
-namespace NKikimr {
-
- using NTabletFlatExecutor::TTransactionContext;
-
- // Base table merger
- template<typename Table, typename TParam, typename T>
- class TTableMerger;
-
- template<typename Table, typename TParam, typename TKey, typename TRow>
- class TTableMerger<Table, TParam, TMap<TKey, TRow>>
- {
- using TContainer = TMap<TKey, TRow>;
- using TItem = typename TContainer::value_type;
-
- const TContainer *Original;
- const TContainer *Changed;
- TParam Param;
-
- public:
- template<typename T>
- TTableMerger(const TContainer *original, const TContainer *changed, T&& param)
- : Original(original)
- , Changed(changed)
- , Param(std::forward<T>(param))
- {}
-
- void operator()(TTransactionContext &txc) const;
- };
-
- template<typename Table, typename TParam, typename TKey>
- class TTableMerger<Table, TParam, TSet<TKey>>
- {
- using TContainer = TSet<TKey>;
- using TItem = typename TContainer::value_type;
-
- const TContainer *Original;
- const TContainer *Changed;
- TParam Param;
-
- public:
- template<typename T>
- TTableMerger(const TContainer *original, const TContainer *changed, T&& param)
- : Original(original)
- , Changed(changed)
- , Param(std::forward<T>(param))
- {}
-
- void operator()(TTransactionContext &txc) const;
- };
-
- template<typename Table, typename TParam, typename T>
- TTableMerger<Table, TParam, T> MakeTableMerger(const T *original, const T *changed, TParam&& param) {
- return {original, changed, std::forward<TParam>(param)};
- }
-
- template<typename Table, typename TParam, typename TKey, typename TRow>
- void TTableMerger<Table, TParam, TMap<TKey, TRow>>::operator()(TTransactionContext &txc) const {
- for (auto row : Diff(Original, Changed)) {
- auto callback = [&](auto *adapter) {
- auto [prev, cur] = row;
- if (!cur) {
- // the row has been deleted
- adapter->IssueEraseRow(txc, prev->first);
- } else if (!prev || !adapter->Equals(prev->second, cur->second)) {
- // the row has been added or modified
- adapter->IssueUpdateRow(txc, cur->first, cur->second);
- }
+#pragma once
+
+#include "defs.h"
+#include "diff.h"
+
+namespace NKikimr {
+
+ using NTabletFlatExecutor::TTransactionContext;
+
+ // Base table merger
+ template<typename Table, typename TParam, typename T>
+ class TTableMerger;
+
+ template<typename Table, typename TParam, typename TKey, typename TRow>
+ class TTableMerger<Table, TParam, TMap<TKey, TRow>>
+ {
+ using TContainer = TMap<TKey, TRow>;
+ using TItem = typename TContainer::value_type;
+
+ const TContainer *Original;
+ const TContainer *Changed;
+ TParam Param;
+
+ public:
+ template<typename T>
+ TTableMerger(const TContainer *original, const TContainer *changed, T&& param)
+ : Original(original)
+ , Changed(changed)
+ , Param(std::forward<T>(param))
+ {}
+
+ void operator()(TTransactionContext &txc) const;
+ };
+
+ template<typename Table, typename TParam, typename TKey>
+ class TTableMerger<Table, TParam, TSet<TKey>>
+ {
+ using TContainer = TSet<TKey>;
+ using TItem = typename TContainer::value_type;
+
+ const TContainer *Original;
+ const TContainer *Changed;
+ TParam Param;
+
+ public:
+ template<typename T>
+ TTableMerger(const TContainer *original, const TContainer *changed, T&& param)
+ : Original(original)
+ , Changed(changed)
+ , Param(std::forward<T>(param))
+ {}
+
+ void operator()(TTransactionContext &txc) const;
+ };
+
+ template<typename Table, typename TParam, typename T>
+ TTableMerger<Table, TParam, T> MakeTableMerger(const T *original, const T *changed, TParam&& param) {
+ return {original, changed, std::forward<TParam>(param)};
+ }
+
+ template<typename Table, typename TParam, typename TKey, typename TRow>
+ void TTableMerger<Table, TParam, TMap<TKey, TRow>>::operator()(TTransactionContext &txc) const {
+ for (auto row : Diff(Original, Changed)) {
+ auto callback = [&](auto *adapter) {
+ auto [prev, cur] = row;
+ if (!cur) {
+ // the row has been deleted
+ adapter->IssueEraseRow(txc, prev->first);
+ } else if (!prev || !adapter->Equals(prev->second, cur->second)) {
+ // the row has been added or modified
+ adapter->IssueUpdateRow(txc, cur->first, cur->second);
+ }
auto processInline = [&](const auto (TRow::*cell), const auto *table) {
- auto [prev, cur] = row;
- using TCell = std::remove_reference_t<decltype(std::declval<TRow>().*cell)>;
- const TCell *prevInline = prev ? &(prev->second.*cell) : nullptr;
- const TCell *curInline = cur ? &(cur->second.*cell) : nullptr;
- auto merger = MakeTableMerger<std::remove_pointer_t<decltype(table)>>(prevInline, curInline, Param);
- merger(txc);
- };
- adapter->ForEachInlineTable(std::move(processInline));
- };
- TRow::Apply(Param, std::move(callback));
- }
- }
-
- template<typename Table, typename TParam, typename TKey>
- void TTableMerger<Table, TParam, TSet<TKey>>::operator ()(TTransactionContext &txc) const {
- for (auto [prev, cur] : Diff(Original, Changed)) {
- // pick the operation we want -- either insert row, or erase row
- const TKey *key = nullptr;
+ auto [prev, cur] = row;
+ using TCell = std::remove_reference_t<decltype(std::declval<TRow>().*cell)>;
+ const TCell *prevInline = prev ? &(prev->second.*cell) : nullptr;
+ const TCell *curInline = cur ? &(cur->second.*cell) : nullptr;
+ auto merger = MakeTableMerger<std::remove_pointer_t<decltype(table)>>(prevInline, curInline, Param);
+ merger(txc);
+ };
+ adapter->ForEachInlineTable(std::move(processInline));
+ };
+ TRow::Apply(Param, std::move(callback));
+ }
+ }
+
+ template<typename Table, typename TParam, typename TKey>
+ void TTableMerger<Table, TParam, TSet<TKey>>::operator ()(TTransactionContext &txc) const {
+ for (auto [prev, cur] : Diff(Original, Changed)) {
+ // pick the operation we want -- either insert row, or erase row
+ const TKey *key = nullptr;
NTable::ERowOp op;
- if (!cur) {
- key = prev;
+ if (!cur) {
+ key = prev;
op = NTable::ERowOp::Erase;
- } else if (!prev) {
- key = cur;
+ } else if (!prev) {
+ key = cur;
op = NTable::ERowOp::Upsert;
- }
-
- if (key) {
- auto x = NTableAdapter::WrapTuple(*key);
- auto keyTuple = NTableAdapter::PrepareKeyTuple<Table>(&x);
- TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
- NTableAdapter::MapKey<Table>(&keyTuple, keyForTable);
- txc.DB.Update(Table::TableId, op, keyForTable, {});
- }
- }
- }
-
-} // NKikimr
+ }
+
+ if (key) {
+ auto x = NTableAdapter::WrapTuple(*key);
+ auto keyTuple = NTableAdapter::PrepareKeyTuple<Table>(&x);
+ TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
+ NTableAdapter::MapKey<Table>(&keyTuple, keyForTable);
+ txc.DB.Update(Table::TableId, op, keyForTable, {});
+ }
+ }
+ }
+
+} // NKikimr
diff --git a/ydb/core/mind/bscontroller/types.h b/ydb/core/mind/bscontroller/types.h
index 2fafd50cd16..66cbfd877a8 100644
--- a/ydb/core/mind/bscontroller/types.h
+++ b/ydb/core/mind/bscontroller/types.h
@@ -1,468 +1,468 @@
-#pragma once
-
-#include "defs.h"
-
-#include "scheme.h"
-#include "diff.h"
-
-namespace NKikimr::NBsController {
- struct TPDiskId;
- struct TVSlotId;
- struct TPDiskLocation;
-}
-
-template<>
-struct THash<NKikimr::NBsController::TPDiskId> {
- size_t operator ()(NKikimr::NBsController::TPDiskId) const;
-};
-
-template<>
-struct THash<NKikimr::NBsController::TVSlotId> {
- size_t operator ()(NKikimr::NBsController::TVSlotId) const;
-};
-
-template<>
-struct THash<NKikimr::NBsController::TPDiskLocation> {
- size_t operator ()(const NKikimr::NBsController::TPDiskLocation&) const;
-};
-
-namespace NKikimr {
- namespace NBsController {
-
- using TNodeId = Schema::Node::TKey::Type;
- using TGroupId = Schema::Group::TKey::Type;
-
- class TBlobStorageController;
-
- struct TGroupLatencyStats {
- TMaybe<TDuration> PutTabletLog;
- TMaybe<TDuration> PutUserData;
- TMaybe<TDuration> GetFast;
-
- double GetNormalizedLatencyValue() const {
- i64 value = 0;
- for (const auto& item : {PutTabletLog, PutUserData, GetFast}) {
- if (item) {
- i64 itemValue = item->MicroSeconds();
- value = Max(value, itemValue);
- }
- }
- return Min(1.0, value * 0.2e-6); // 5 seconds is the maximum latency
- }
- };
-
- struct TPDiskId {
- Schema::PDisk::NodeID::Type NodeId = 0;
- Schema::PDisk::PDiskID::Type PDiskId = 0;
-
- TPDiskId(const Schema::PDisk::TKey::Type &key)
- : NodeId(std::get<0>(key))
- , PDiskId(std::get<1>(key))
- {}
-
- TPDiskId(Schema::PDisk::NodeID::Type nodeId, Schema::PDisk::PDiskID::Type pdiskId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- {}
-
- static TPDiskId MinForNode(Schema::PDisk::NodeID::Type nodeId) {
- return TPDiskId(nodeId, Min<Schema::PDisk::PDiskID::Type>());
- }
-
- static TPDiskId MaxForNode(Schema::PDisk::NodeID::Type nodeId) {
- return TPDiskId(nodeId, Max<Schema::PDisk::PDiskID::Type>());
- }
-
- TPDiskId() = default;
- TPDiskId(const TPDiskId&) = default;
-
- TString ToString() const {
- return TStringBuilder() << NodeId << ":" << PDiskId;
- }
-
- Schema::PDisk::TKey::Type GetKey() const {
- return std::tie(NodeId, PDiskId);
- }
-
- friend bool operator ==(const TPDiskId &x, const TPDiskId &y) { return x.GetKey() == y.GetKey(); }
- friend bool operator !=(const TPDiskId &x, const TPDiskId &y) { return x.GetKey() != y.GetKey(); }
- friend bool operator < (const TPDiskId &x, const TPDiskId &y) { return x.GetKey() < y.GetKey(); }
- };
-
- struct TVSlotId {
- Schema::VSlot::NodeID::Type NodeId = 0;
- Schema::VSlot::PDiskID::Type PDiskId = 0;
- Schema::VSlot::VSlotID::Type VSlotId = 0;
-
- TVSlotId(const Schema::VSlot::TKey::Type &key)
- : NodeId(std::get<0>(key))
- , PDiskId(std::get<1>(key))
- , VSlotId(std::get<2>(key))
- {}
-
- TVSlotId(Schema::VSlot::NodeID::Type nodeId, Schema::VSlot::PDiskID::Type pdiskId, Schema::VSlot::VSlotID::Type vslotId)
- : NodeId(nodeId)
- , PDiskId(pdiskId)
- , VSlotId(vslotId)
- {}
-
- TVSlotId() = default;
- TVSlotId(const TVSlotId&) = default;
-
- TVSlotId(TPDiskId pdiskId, Schema::VSlot::VSlotID::Type vslotId)
- : NodeId(pdiskId.NodeId)
- , PDiskId(pdiskId.PDiskId)
- , VSlotId(vslotId)
- {}
-
- TVSlotId(const NKikimrBlobStorage::TVSlotId& pb)
- : NodeId(pb.GetNodeId())
- , PDiskId(pb.GetPDiskId())
- , VSlotId(pb.GetVSlotId())
- {}
-
- static TVSlotId MinForPDisk(TPDiskId pdiskId) {
- return TVSlotId(pdiskId, Min<Schema::VSlot::VSlotID::Type>());
- }
-
- static TVSlotId MaxForPDisk(TPDiskId pdiskId) {
- return TVSlotId(pdiskId, Max<Schema::VSlot::VSlotID::Type>());
- }
-
- TPDiskId ComprisingPDiskId() const {
- return TPDiskId(NodeId, PDiskId);
- }
-
- TString ToString() const {
- return TStringBuilder() << NodeId << ":" << PDiskId << ":" << VSlotId;
- }
-
- Schema::VSlot::TKey::Type GetKey() const {
- return std::tie(NodeId, PDiskId, VSlotId);
- }
-
- void Serialize(NKikimrBlobStorage::TVSlotId *pb) const {
- pb->SetNodeId(NodeId);
- pb->SetPDiskId(PDiskId);
- pb->SetVSlotId(VSlotId);
- }
-
- friend bool operator ==(const TVSlotId &x, const TVSlotId &y) { return x.GetKey() == y.GetKey(); }
- friend bool operator !=(const TVSlotId &x, const TVSlotId &y) { return x.GetKey() != y.GetKey(); }
- friend bool operator < (const TVSlotId &x, const TVSlotId &y) { return x.GetKey() < y.GetKey(); }
- };
-
- template<typename TKey, typename TValue>
- class TOverlayMap {
- using TBaseMap = TMap<TKey, THolder<TValue>>;
- using TIterator = typename TBaseMap::iterator;
- using TConstIterator = typename TBaseMap::const_iterator;
-
- TBaseMap& Base;
- TBaseMap Overlay;
-
- class TDiff {
- const TOverlayMap& Map;
-
- public:
- class TIterator {
- const TOverlayMap& Map;
- TConstIterator OverlayIt;
- TConstIterator BaseIt;
-
- public:
- TIterator(const TOverlayMap& map, TConstIterator overlayIt)
- : Map(map)
- , OverlayIt(overlayIt)
- , BaseIt(overlayIt != map.Overlay.end() ? map.Base.lower_bound(overlayIt->first) : map.Base.end())
- {}
-
- std::pair<const typename TBaseMap::value_type*, TConstIterator> operator *() const {
- Y_VERIFY_DEBUG(OverlayIt != Map.Overlay.end());
- return std::make_pair(BaseIt != Map.Base.end() && BaseIt->first == OverlayIt->first ?
- &*BaseIt : nullptr, OverlayIt);
- }
-
- TIterator& operator ++() {
- if (++OverlayIt != Map.Overlay.end()) {
- ui8 n; // optimistically try a few options ahead
- for (n = 4; BaseIt != Map.Base.end() && BaseIt->first < OverlayIt->first && --n; ++BaseIt)
- {}
- if (!n) { // locate using O(log2(N)) algorithm
- BaseIt = Map.Base.lower_bound(OverlayIt->first);
- }
- }
- return *this;
- }
-
- bool operator !=(const TIterator& other) const {
- return OverlayIt != other.OverlayIt;
- }
- };
-
- public:
- TDiff(const TOverlayMap& map) : Map(map) {}
- TIterator begin() const { return TIterator(Map, Map.Overlay.begin()); }
- TIterator end() const { return TIterator(Map, Map.Overlay.end()); }
- };
-
- public:
- TOverlayMap(TBaseMap& base)
- : Base(base)
- {}
-
- // SCAN RANGE -- function scans all items with key fitting condition from <= key <= to when bounds are provided;
- // in other case minimum and maximum values are used for these bounds. Callback is invoked with parameters
- // (RO key, RO value, getMutableItem callback), where getMutableItem returns pointer to item that can be
- // modified safely (when being added to delta map).
- template<typename T>
- void ScanRange(const TMaybe<TKey>& from, const TMaybe<TKey>& to, T&& callback) {
- auto baseIt = from ? Base.lower_bound(*from) : Base.begin();
- auto overlayIt = from ? Overlay.lower_bound(*from) : Overlay.begin();
- while (baseIt != Base.end() || overlayIt != Overlay.end()) {
- // first, check exit condition (if set)
- if (to) {
- const TKey& current = baseIt == Base.end() ? overlayIt->first :
- overlayIt == Overlay.end() ? baseIt->first : std::min(baseIt->first, overlayIt->first);
- if (*to < current) {
- break;
- }
- }
-
- // check if we have only the base item, but no overlay one
- if (overlayIt == Overlay.end() || (baseIt != Base.end() && baseIt->first < overlayIt->first)) {
- TValue *mutableItem = nullptr;
- auto getMutableItem = [&] {
- if (!mutableItem) {
- overlayIt = Clone(overlayIt, baseIt);
- mutableItem = overlayIt->second.Get();
- ++overlayIt;
- }
- return mutableItem;
- };
- if (!callback(baseIt->first, *baseIt->second, getMutableItem)) {
- break;
- }
- ++baseIt;
- } else {
- if (overlayIt->second) {
- auto getMutableItem = [&] { return overlayIt->second.Get(); };
- if (!callback(overlayIt->first, *overlayIt->second, getMutableItem)) {
- break;
- }
- }
- if (baseIt != Base.end() && !(overlayIt->first < baseIt->first)) {
- ++baseIt;
- }
- ++overlayIt;
- }
- }
- }
-
- template<typename T>
- void ForEachInRange(const TMaybe<TKey>& from, const TMaybe<TKey>& to, T&& callback) const {
- auto& m = const_cast<TOverlayMap&>(*this); // we remove const qualifier as it is completely safe unless getMutableItem is called
- m.ScanRange(from, to, [&](const TKey& key, const TValue& value, const auto& /*getMutableItem*/) {
- return callback(key, value);
- });
- }
-
- template<typename T>
- void ForEach(T&& callback) const {
- ForEachInRange({}, {}, [&](const TKey& key, const TValue& value) {
- callback(key, value);
- return true;
- });
- }
-
- const TValue *Find(const TKey& key) const {
- TConstIterator it = Overlay.find(key);
- if (it != Overlay.end()) {
- return it->second.Get();
- }
- it = Base.find(key);
- return it != Base.end() ? it->second.Get() : nullptr;
- }
-
- TValue *FindForUpdate(const TKey& key) {
- TIterator it = Overlay.lower_bound(key);
- if (it == Overlay.end() || it->first != key) {
- const TConstIterator baseIt = Base.find(key);
- if (baseIt != Base.end()) {
- it = Clone(it, baseIt);
- } else {
- return nullptr;
- }
- }
- return it->second.Get();
- }
-
- template<typename... TArgs>
- TValue *ConstructInplaceNewEntry(TKey key, TArgs&&... args) {
- TIterator it = Overlay.lower_bound(key);
- if (it != Overlay.end() && it->first == key) {
- Y_VERIFY(!it->second);
- it->second = MakeHolder<TValue>(std::forward<TArgs>(args)...);
- } else {
- Y_VERIFY(!Base.count(key));
- it = Overlay.emplace_hint(it, std::move(key), MakeHolder<TValue>(std::forward<TArgs>(args)...));
- }
- return it->second.Get();
- }
-
- void DeleteExistingEntry(const TKey& key) {
- TIterator it = Overlay.lower_bound(key);
- if (it == Overlay.end() || it->first != key) {
- Y_VERIFY(Base.count(key)); // ensure that this entry exists in the base map
- Overlay.emplace_hint(it, key, nullptr);
- } else if (Base.count(key)) {
- auto& value = it->second;
- Y_VERIFY(value); // this entry must not be already deleted
- value.Reset();
- } else {
- // just remove this entity from overlay as there is no corresponding entity in base map
- Overlay.erase(it);
- }
- }
-
- void ApplyToTable(TBlobStorageController *controller, NTabletFlatExecutor::TTransactionContext& txc) const {
- TValue::Apply(controller, [&](auto *adapter) {
- for (const auto& row : Overlay) {
- if (row.second) {
- adapter->IssueUpdateRow(txc, row.first, *row.second);
- } else {
- adapter->IssueEraseRow(txc, row.first);
- }
- }
- });
- }
-
- auto Diff() const {
- return TDiff(*this);
- }
-
- auto Diff() {
- return TDiff(*this);
- }
-
- bool Changed() const {
- return !Overlay.empty();
- }
-
- void Preserve(std::deque<std::pair<void**, void*>>& v) {
- auto baseIt = Base.begin();
- for (const auto& [key, overlay] : Overlay) {
- while (baseIt != Base.end() && baseIt->first < key) {
- ++baseIt;
- }
- if (baseIt == Base.end()) {
- break;
- }
- if (overlay && baseIt->first == key) {
- v.push_back(baseIt->second->Preserve());
- }
- }
- }
-
- void Commit() {
- auto baseIt = Base.begin();
- for (auto it = Overlay.begin(), next = it; it != Overlay.end() && (++next, true); it = next) {
- auto& [key, overlay] = *it;
-
- while (baseIt != Base.end() && baseIt->first < key) {
- ++baseIt;
- }
- const bool hasBase = baseIt != Base.end() && !(key < baseIt->first);
-
- if (!overlay) {
- Y_VERIFY_DEBUG(hasBase);
- baseIt = Base.erase(baseIt);
- } else if (hasBase) {
- overlay->OnCommit();
- baseIt->second = std::move(overlay);
- } else {
- baseIt = Base.insert(baseIt, Overlay.extract(it));
- }
- }
- Overlay.clear();
- }
-
- void Rollback() {
- auto baseIt = Base.begin();
- for (const auto& [key, overlay] : Overlay) {
- while (baseIt != Base.end() && baseIt->first < key) {
- ++baseIt;
- }
- if (baseIt == Base.end()) {
- break;
- }
- if (overlay && baseIt->first == key) {
- baseIt->second->OnRollback();
- }
- }
- }
-
- private:
- TIterator Clone(TIterator it, TConstIterator baseIt) {
- TIterator res = Overlay.emplace_hint(it, baseIt->first, MakeHolder<TValue>(*baseIt->second));
- baseIt->second->OnClone(res->second);
- return res;
- }
- };
-
- struct TPDiskLocation {
- TNodeId NodeId;
- TString Path;
-
- TPDiskLocation() = default;
- TPDiskLocation(const TPDiskLocation&) = default;
- TPDiskLocation(TPDiskLocation&&) = default;
-
- TPDiskLocation(TNodeId nodeId, TString path)
- : NodeId(nodeId)
- , Path(std::move(path))
- {}
-
- friend bool operator ==(const TPDiskLocation& x, const TPDiskLocation& y) {
- return x.NodeId == y.NodeId && x.Path == y.Path;
- }
- };
-
- } // NBsController
-} // NKikimr
-
-inline size_t THash<NKikimr::NBsController::TPDiskId>::operator ()(NKikimr::NBsController::TPDiskId x) const {
- auto key = x.GetKey();
- using T = decltype(key);
- return THash<T>()(key);
-}
-
-inline size_t THash<NKikimr::NBsController::TVSlotId>::operator ()(NKikimr::NBsController::TVSlotId x) const {
- auto key = x.GetKey();
- using T = decltype(key);
- return THash<T>()(key);
-}
-
-inline size_t THash<NKikimr::NBsController::TPDiskLocation>::operator ()(const NKikimr::NBsController::TPDiskLocation& x) const {
- auto value = std::tie(x.NodeId, x.Path);
- using T = decltype(value);
- return THash<T>()(value);
-}
-
-template<>
-inline NKikimr::NBsController::TPDiskId Min<NKikimr::NBsController::TPDiskId>() noexcept {
- using T = NKikimr::NBsController::Schema::PDisk;
- return {
- Min<T::NodeID::Type>(),
- Min<T::PDiskID::Type>()
- };
-}
-
-template<>
-inline NKikimr::NBsController::TPDiskId Max<NKikimr::NBsController::TPDiskId>() noexcept {
- using T = NKikimr::NBsController::Schema::PDisk;
- return {
- Max<T::NodeID::Type>(),
- Max<T::PDiskID::Type>()
- };
-}
+#pragma once
+
+#include "defs.h"
+
+#include "scheme.h"
+#include "diff.h"
+
+namespace NKikimr::NBsController {
+ struct TPDiskId;
+ struct TVSlotId;
+ struct TPDiskLocation;
+}
+
+template<>
+struct THash<NKikimr::NBsController::TPDiskId> {
+ size_t operator ()(NKikimr::NBsController::TPDiskId) const;
+};
+
+template<>
+struct THash<NKikimr::NBsController::TVSlotId> {
+ size_t operator ()(NKikimr::NBsController::TVSlotId) const;
+};
+
+template<>
+struct THash<NKikimr::NBsController::TPDiskLocation> {
+ size_t operator ()(const NKikimr::NBsController::TPDiskLocation&) const;
+};
+
+namespace NKikimr {
+ namespace NBsController {
+
+ using TNodeId = Schema::Node::TKey::Type;
+ using TGroupId = Schema::Group::TKey::Type;
+
+ class TBlobStorageController;
+
+ struct TGroupLatencyStats {
+ TMaybe<TDuration> PutTabletLog;
+ TMaybe<TDuration> PutUserData;
+ TMaybe<TDuration> GetFast;
+
+ double GetNormalizedLatencyValue() const {
+ i64 value = 0;
+ for (const auto& item : {PutTabletLog, PutUserData, GetFast}) {
+ if (item) {
+ i64 itemValue = item->MicroSeconds();
+ value = Max(value, itemValue);
+ }
+ }
+ return Min(1.0, value * 0.2e-6); // 5 seconds is the maximum latency
+ }
+ };
+
+ struct TPDiskId {
+ Schema::PDisk::NodeID::Type NodeId = 0;
+ Schema::PDisk::PDiskID::Type PDiskId = 0;
+
+ TPDiskId(const Schema::PDisk::TKey::Type &key)
+ : NodeId(std::get<0>(key))
+ , PDiskId(std::get<1>(key))
+ {}
+
+ TPDiskId(Schema::PDisk::NodeID::Type nodeId, Schema::PDisk::PDiskID::Type pdiskId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ {}
+
+ static TPDiskId MinForNode(Schema::PDisk::NodeID::Type nodeId) {
+ return TPDiskId(nodeId, Min<Schema::PDisk::PDiskID::Type>());
+ }
+
+ static TPDiskId MaxForNode(Schema::PDisk::NodeID::Type nodeId) {
+ return TPDiskId(nodeId, Max<Schema::PDisk::PDiskID::Type>());
+ }
+
+ TPDiskId() = default;
+ TPDiskId(const TPDiskId&) = default;
+
+ TString ToString() const {
+ return TStringBuilder() << NodeId << ":" << PDiskId;
+ }
+
+ Schema::PDisk::TKey::Type GetKey() const {
+ return std::tie(NodeId, PDiskId);
+ }
+
+ friend bool operator ==(const TPDiskId &x, const TPDiskId &y) { return x.GetKey() == y.GetKey(); }
+ friend bool operator !=(const TPDiskId &x, const TPDiskId &y) { return x.GetKey() != y.GetKey(); }
+ friend bool operator < (const TPDiskId &x, const TPDiskId &y) { return x.GetKey() < y.GetKey(); }
+ };
+
+ struct TVSlotId {
+ Schema::VSlot::NodeID::Type NodeId = 0;
+ Schema::VSlot::PDiskID::Type PDiskId = 0;
+ Schema::VSlot::VSlotID::Type VSlotId = 0;
+
+ TVSlotId(const Schema::VSlot::TKey::Type &key)
+ : NodeId(std::get<0>(key))
+ , PDiskId(std::get<1>(key))
+ , VSlotId(std::get<2>(key))
+ {}
+
+ TVSlotId(Schema::VSlot::NodeID::Type nodeId, Schema::VSlot::PDiskID::Type pdiskId, Schema::VSlot::VSlotID::Type vslotId)
+ : NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VSlotId(vslotId)
+ {}
+
+ TVSlotId() = default;
+ TVSlotId(const TVSlotId&) = default;
+
+ TVSlotId(TPDiskId pdiskId, Schema::VSlot::VSlotID::Type vslotId)
+ : NodeId(pdiskId.NodeId)
+ , PDiskId(pdiskId.PDiskId)
+ , VSlotId(vslotId)
+ {}
+
+ TVSlotId(const NKikimrBlobStorage::TVSlotId& pb)
+ : NodeId(pb.GetNodeId())
+ , PDiskId(pb.GetPDiskId())
+ , VSlotId(pb.GetVSlotId())
+ {}
+
+ static TVSlotId MinForPDisk(TPDiskId pdiskId) {
+ return TVSlotId(pdiskId, Min<Schema::VSlot::VSlotID::Type>());
+ }
+
+ static TVSlotId MaxForPDisk(TPDiskId pdiskId) {
+ return TVSlotId(pdiskId, Max<Schema::VSlot::VSlotID::Type>());
+ }
+
+ TPDiskId ComprisingPDiskId() const {
+ return TPDiskId(NodeId, PDiskId);
+ }
+
+ TString ToString() const {
+ return TStringBuilder() << NodeId << ":" << PDiskId << ":" << VSlotId;
+ }
+
+ Schema::VSlot::TKey::Type GetKey() const {
+ return std::tie(NodeId, PDiskId, VSlotId);
+ }
+
+ void Serialize(NKikimrBlobStorage::TVSlotId *pb) const {
+ pb->SetNodeId(NodeId);
+ pb->SetPDiskId(PDiskId);
+ pb->SetVSlotId(VSlotId);
+ }
+
+ friend bool operator ==(const TVSlotId &x, const TVSlotId &y) { return x.GetKey() == y.GetKey(); }
+ friend bool operator !=(const TVSlotId &x, const TVSlotId &y) { return x.GetKey() != y.GetKey(); }
+ friend bool operator < (const TVSlotId &x, const TVSlotId &y) { return x.GetKey() < y.GetKey(); }
+ };
+
+ template<typename TKey, typename TValue>
+ class TOverlayMap {
+ using TBaseMap = TMap<TKey, THolder<TValue>>;
+ using TIterator = typename TBaseMap::iterator;
+ using TConstIterator = typename TBaseMap::const_iterator;
+
+ TBaseMap& Base;
+ TBaseMap Overlay;
+
+ class TDiff {
+ const TOverlayMap& Map;
+
+ public:
+ class TIterator {
+ const TOverlayMap& Map;
+ TConstIterator OverlayIt;
+ TConstIterator BaseIt;
+
+ public:
+ TIterator(const TOverlayMap& map, TConstIterator overlayIt)
+ : Map(map)
+ , OverlayIt(overlayIt)
+ , BaseIt(overlayIt != map.Overlay.end() ? map.Base.lower_bound(overlayIt->first) : map.Base.end())
+ {}
+
+ std::pair<const typename TBaseMap::value_type*, TConstIterator> operator *() const {
+ Y_VERIFY_DEBUG(OverlayIt != Map.Overlay.end());
+ return std::make_pair(BaseIt != Map.Base.end() && BaseIt->first == OverlayIt->first ?
+ &*BaseIt : nullptr, OverlayIt);
+ }
+
+ TIterator& operator ++() {
+ if (++OverlayIt != Map.Overlay.end()) {
+ ui8 n; // optimistically try a few options ahead
+ for (n = 4; BaseIt != Map.Base.end() && BaseIt->first < OverlayIt->first && --n; ++BaseIt)
+ {}
+ if (!n) { // locate using O(log2(N)) algorithm
+ BaseIt = Map.Base.lower_bound(OverlayIt->first);
+ }
+ }
+ return *this;
+ }
+
+ bool operator !=(const TIterator& other) const {
+ return OverlayIt != other.OverlayIt;
+ }
+ };
+
+ public:
+ TDiff(const TOverlayMap& map) : Map(map) {}
+ TIterator begin() const { return TIterator(Map, Map.Overlay.begin()); }
+ TIterator end() const { return TIterator(Map, Map.Overlay.end()); }
+ };
+
+ public:
+ TOverlayMap(TBaseMap& base)
+ : Base(base)
+ {}
+
+ // SCAN RANGE -- function scans all items with key fitting condition from <= key <= to when bounds are provided;
+ // in other case minimum and maximum values are used for these bounds. Callback is invoked with parameters
+ // (RO key, RO value, getMutableItem callback), where getMutableItem returns pointer to item that can be
+ // modified safely (when being added to delta map).
+ template<typename T>
+ void ScanRange(const TMaybe<TKey>& from, const TMaybe<TKey>& to, T&& callback) {
+ auto baseIt = from ? Base.lower_bound(*from) : Base.begin();
+ auto overlayIt = from ? Overlay.lower_bound(*from) : Overlay.begin();
+ while (baseIt != Base.end() || overlayIt != Overlay.end()) {
+ // first, check exit condition (if set)
+ if (to) {
+ const TKey& current = baseIt == Base.end() ? overlayIt->first :
+ overlayIt == Overlay.end() ? baseIt->first : std::min(baseIt->first, overlayIt->first);
+ if (*to < current) {
+ break;
+ }
+ }
+
+ // check if we have only the base item, but no overlay one
+ if (overlayIt == Overlay.end() || (baseIt != Base.end() && baseIt->first < overlayIt->first)) {
+ TValue *mutableItem = nullptr;
+ auto getMutableItem = [&] {
+ if (!mutableItem) {
+ overlayIt = Clone(overlayIt, baseIt);
+ mutableItem = overlayIt->second.Get();
+ ++overlayIt;
+ }
+ return mutableItem;
+ };
+ if (!callback(baseIt->first, *baseIt->second, getMutableItem)) {
+ break;
+ }
+ ++baseIt;
+ } else {
+ if (overlayIt->second) {
+ auto getMutableItem = [&] { return overlayIt->second.Get(); };
+ if (!callback(overlayIt->first, *overlayIt->second, getMutableItem)) {
+ break;
+ }
+ }
+ if (baseIt != Base.end() && !(overlayIt->first < baseIt->first)) {
+ ++baseIt;
+ }
+ ++overlayIt;
+ }
+ }
+ }
+
+ template<typename T>
+ void ForEachInRange(const TMaybe<TKey>& from, const TMaybe<TKey>& to, T&& callback) const {
+ auto& m = const_cast<TOverlayMap&>(*this); // we remove const qualifier as it is completely safe unless getMutableItem is called
+ m.ScanRange(from, to, [&](const TKey& key, const TValue& value, const auto& /*getMutableItem*/) {
+ return callback(key, value);
+ });
+ }
+
+ template<typename T>
+ void ForEach(T&& callback) const {
+ ForEachInRange({}, {}, [&](const TKey& key, const TValue& value) {
+ callback(key, value);
+ return true;
+ });
+ }
+
+ const TValue *Find(const TKey& key) const {
+ TConstIterator it = Overlay.find(key);
+ if (it != Overlay.end()) {
+ return it->second.Get();
+ }
+ it = Base.find(key);
+ return it != Base.end() ? it->second.Get() : nullptr;
+ }
+
+ TValue *FindForUpdate(const TKey& key) {
+ TIterator it = Overlay.lower_bound(key);
+ if (it == Overlay.end() || it->first != key) {
+ const TConstIterator baseIt = Base.find(key);
+ if (baseIt != Base.end()) {
+ it = Clone(it, baseIt);
+ } else {
+ return nullptr;
+ }
+ }
+ return it->second.Get();
+ }
+
+ template<typename... TArgs>
+ TValue *ConstructInplaceNewEntry(TKey key, TArgs&&... args) {
+ TIterator it = Overlay.lower_bound(key);
+ if (it != Overlay.end() && it->first == key) {
+ Y_VERIFY(!it->second);
+ it->second = MakeHolder<TValue>(std::forward<TArgs>(args)...);
+ } else {
+ Y_VERIFY(!Base.count(key));
+ it = Overlay.emplace_hint(it, std::move(key), MakeHolder<TValue>(std::forward<TArgs>(args)...));
+ }
+ return it->second.Get();
+ }
+
+ void DeleteExistingEntry(const TKey& key) {
+ TIterator it = Overlay.lower_bound(key);
+ if (it == Overlay.end() || it->first != key) {
+ Y_VERIFY(Base.count(key)); // ensure that this entry exists in the base map
+ Overlay.emplace_hint(it, key, nullptr);
+ } else if (Base.count(key)) {
+ auto& value = it->second;
+ Y_VERIFY(value); // this entry must not be already deleted
+ value.Reset();
+ } else {
+ // just remove this entity from overlay as there is no corresponding entity in base map
+ Overlay.erase(it);
+ }
+ }
+
+ void ApplyToTable(TBlobStorageController *controller, NTabletFlatExecutor::TTransactionContext& txc) const {
+ TValue::Apply(controller, [&](auto *adapter) {
+ for (const auto& row : Overlay) {
+ if (row.second) {
+ adapter->IssueUpdateRow(txc, row.first, *row.second);
+ } else {
+ adapter->IssueEraseRow(txc, row.first);
+ }
+ }
+ });
+ }
+
+ auto Diff() const {
+ return TDiff(*this);
+ }
+
+ auto Diff() {
+ return TDiff(*this);
+ }
+
+ bool Changed() const {
+ return !Overlay.empty();
+ }
+
+ void Preserve(std::deque<std::pair<void**, void*>>& v) {
+ auto baseIt = Base.begin();
+ for (const auto& [key, overlay] : Overlay) {
+ while (baseIt != Base.end() && baseIt->first < key) {
+ ++baseIt;
+ }
+ if (baseIt == Base.end()) {
+ break;
+ }
+ if (overlay && baseIt->first == key) {
+ v.push_back(baseIt->second->Preserve());
+ }
+ }
+ }
+
+ void Commit() {
+ auto baseIt = Base.begin();
+ for (auto it = Overlay.begin(), next = it; it != Overlay.end() && (++next, true); it = next) {
+ auto& [key, overlay] = *it;
+
+ while (baseIt != Base.end() && baseIt->first < key) {
+ ++baseIt;
+ }
+ const bool hasBase = baseIt != Base.end() && !(key < baseIt->first);
+
+ if (!overlay) {
+ Y_VERIFY_DEBUG(hasBase);
+ baseIt = Base.erase(baseIt);
+ } else if (hasBase) {
+ overlay->OnCommit();
+ baseIt->second = std::move(overlay);
+ } else {
+ baseIt = Base.insert(baseIt, Overlay.extract(it));
+ }
+ }
+ Overlay.clear();
+ }
+
+ void Rollback() {
+ auto baseIt = Base.begin();
+ for (const auto& [key, overlay] : Overlay) {
+ while (baseIt != Base.end() && baseIt->first < key) {
+ ++baseIt;
+ }
+ if (baseIt == Base.end()) {
+ break;
+ }
+ if (overlay && baseIt->first == key) {
+ baseIt->second->OnRollback();
+ }
+ }
+ }
+
+ private:
+ TIterator Clone(TIterator it, TConstIterator baseIt) {
+ TIterator res = Overlay.emplace_hint(it, baseIt->first, MakeHolder<TValue>(*baseIt->second));
+ baseIt->second->OnClone(res->second);
+ return res;
+ }
+ };
+
+ struct TPDiskLocation {
+ TNodeId NodeId;
+ TString Path;
+
+ TPDiskLocation() = default;
+ TPDiskLocation(const TPDiskLocation&) = default;
+ TPDiskLocation(TPDiskLocation&&) = default;
+
+ TPDiskLocation(TNodeId nodeId, TString path)
+ : NodeId(nodeId)
+ , Path(std::move(path))
+ {}
+
+ friend bool operator ==(const TPDiskLocation& x, const TPDiskLocation& y) {
+ return x.NodeId == y.NodeId && x.Path == y.Path;
+ }
+ };
+
+ } // NBsController
+} // NKikimr
+
+inline size_t THash<NKikimr::NBsController::TPDiskId>::operator ()(NKikimr::NBsController::TPDiskId x) const {
+ auto key = x.GetKey();
+ using T = decltype(key);
+ return THash<T>()(key);
+}
+
+inline size_t THash<NKikimr::NBsController::TVSlotId>::operator ()(NKikimr::NBsController::TVSlotId x) const {
+ auto key = x.GetKey();
+ using T = decltype(key);
+ return THash<T>()(key);
+}
+
+inline size_t THash<NKikimr::NBsController::TPDiskLocation>::operator ()(const NKikimr::NBsController::TPDiskLocation& x) const {
+ auto value = std::tie(x.NodeId, x.Path);
+ using T = decltype(value);
+ return THash<T>()(value);
+}
+
+template<>
+inline NKikimr::NBsController::TPDiskId Min<NKikimr::NBsController::TPDiskId>() noexcept {
+ using T = NKikimr::NBsController::Schema::PDisk;
+ return {
+ Min<T::NodeID::Type>(),
+ Min<T::PDiskID::Type>()
+ };
+}
+
+template<>
+inline NKikimr::NBsController::TPDiskId Max<NKikimr::NBsController::TPDiskId>() noexcept {
+ using T = NKikimr::NBsController::Schema::PDisk;
+ return {
+ Max<T::NodeID::Type>(),
+ Max<T::PDiskID::Type>()
+ };
+}
diff --git a/ydb/core/mind/bscontroller/update_group_latencies.cpp b/ydb/core/mind/bscontroller/update_group_latencies.cpp
index cc1187bc5c7..313b4510aeb 100644
--- a/ydb/core/mind/bscontroller/update_group_latencies.cpp
+++ b/ydb/core/mind/bscontroller/update_group_latencies.cpp
@@ -1,80 +1,80 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxUpdateGroupLatencies : public TTransactionBase<TBlobStorageController> {
- THashSet<TGroupId> Ids;
-
-public:
- TTxUpdateGroupLatencies(THashSet<TGroupId> ids, TBlobStorageController *controller)
- : TBase(controller)
- , Ids(std::move(ids))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_GROUP_LATENCIES; }
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- for (const TGroupId groupId : Ids) {
- TGroupInfo *groupInfo = Self->FindGroup(groupId);
- if (!groupInfo) {
- continue;
- }
- TGroupLatencyStats& stats = groupInfo->LatencyStats;
-
-#define UPDATE_CELL(VALUE, COLUMN) \
- if (const auto& x = stats.VALUE) { \
- db.Table<Schema::GroupLatencies>().Key(groupId).Update(NIceDb::TUpdate<Schema::GroupLatencies::COLUMN>(x->MicroSeconds())); \
- } else { \
- db.Table<Schema::GroupLatencies>().Key(groupId).Update(NIceDb::TNull<Schema::GroupLatencies::COLUMN>()); \
- }
-
- UPDATE_CELL(PutTabletLog, PutTabletLogLatencyUs);
- UPDATE_CELL(PutUserData, PutUserDataLatencyUs);
- UPDATE_CELL(GetFast, GetFastLatencyUs);
-
- Self->SysViewChangedGroups.insert(groupId);
- }
- return true;
- }
-
- void Complete(const TActorContext&) override
- {}
-};
-
-void TBlobStorageController::Handle(TEvControllerCommitGroupLatencies::TPtr& ev) {
- THashSet<TGroupId> ids;
-
- auto& updates = ev->Get()->Updates;
- if (updates.size() <= GroupMap.size() / 2) {
- for (auto& [key, value] : updates) {
- if (TGroupInfo *group = FindGroup(key)) {
- group->LatencyStats = std::move(value);
- ids.insert(key);
- }
- }
- } else {
- auto updateIt = updates.begin();
- auto groupIt = GroupMap.begin();
- while (updateIt != updates.end() && groupIt != GroupMap.end()) {
- if (updateIt->first < groupIt->first) {
- ++updateIt;
- } else if (groupIt->first < updateIt->first) {
- ++groupIt;
- } else {
- groupIt->second->LatencyStats = std::move(updateIt->second);
- ids.insert(groupIt->first);
- ++groupIt;
- ++updateIt;
- }
- }
- }
-
- if (ids) {
- Execute(new TTxUpdateGroupLatencies(std::move(ids), this));
- }
-}
-
-}
-}
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxUpdateGroupLatencies : public TTransactionBase<TBlobStorageController> {
+ THashSet<TGroupId> Ids;
+
+public:
+ TTxUpdateGroupLatencies(THashSet<TGroupId> ids, TBlobStorageController *controller)
+ : TBase(controller)
+ , Ids(std::move(ids))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_GROUP_LATENCIES; }
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ for (const TGroupId groupId : Ids) {
+ TGroupInfo *groupInfo = Self->FindGroup(groupId);
+ if (!groupInfo) {
+ continue;
+ }
+ TGroupLatencyStats& stats = groupInfo->LatencyStats;
+
+#define UPDATE_CELL(VALUE, COLUMN) \
+ if (const auto& x = stats.VALUE) { \
+ db.Table<Schema::GroupLatencies>().Key(groupId).Update(NIceDb::TUpdate<Schema::GroupLatencies::COLUMN>(x->MicroSeconds())); \
+ } else { \
+ db.Table<Schema::GroupLatencies>().Key(groupId).Update(NIceDb::TNull<Schema::GroupLatencies::COLUMN>()); \
+ }
+
+ UPDATE_CELL(PutTabletLog, PutTabletLogLatencyUs);
+ UPDATE_CELL(PutUserData, PutUserDataLatencyUs);
+ UPDATE_CELL(GetFast, GetFastLatencyUs);
+
+ Self->SysViewChangedGroups.insert(groupId);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override
+ {}
+};
+
+void TBlobStorageController::Handle(TEvControllerCommitGroupLatencies::TPtr& ev) {
+ THashSet<TGroupId> ids;
+
+ auto& updates = ev->Get()->Updates;
+ if (updates.size() <= GroupMap.size() / 2) {
+ for (auto& [key, value] : updates) {
+ if (TGroupInfo *group = FindGroup(key)) {
+ group->LatencyStats = std::move(value);
+ ids.insert(key);
+ }
+ }
+ } else {
+ auto updateIt = updates.begin();
+ auto groupIt = GroupMap.begin();
+ while (updateIt != updates.end() && groupIt != GroupMap.end()) {
+ if (updateIt->first < groupIt->first) {
+ ++updateIt;
+ } else if (groupIt->first < updateIt->first) {
+ ++groupIt;
+ } else {
+ groupIt->second->LatencyStats = std::move(updateIt->second);
+ ids.insert(groupIt->first);
+ ++groupIt;
+ ++updateIt;
+ }
+ }
+ }
+
+ if (ids) {
+ Execute(new TTxUpdateGroupLatencies(std::move(ids), this));
+ }
+}
+
+}
+}
diff --git a/ydb/core/mind/bscontroller/update_last_seen_ready.cpp b/ydb/core/mind/bscontroller/update_last_seen_ready.cpp
index daf18702d84..0b591295315 100644
--- a/ydb/core/mind/bscontroller/update_last_seen_ready.cpp
+++ b/ydb/core/mind/bscontroller/update_last_seen_ready.cpp
@@ -1,33 +1,33 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxUpdateLastSeenReady : public TTransactionBase<TBlobStorageController> {
- std::vector<std::pair<TVSlotId, TInstant>> LastSeenReadyQ;
-
-public:
- TTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ, TBlobStorageController *controller)
- : TBase(controller)
- , LastSeenReadyQ(std::move(lastSeenReadyQ))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_LAST_SEEN_READY; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- for (const auto& [vslotId, lastSeenReady] : LastSeenReadyQ) {
- db.Table<Schema::VSlot>().Key(vslotId.GetKey()).Update<Schema::VSlot::LastSeenReady>(lastSeenReady);
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-ITransaction* TBlobStorageController::CreateTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ) {
- return new TTxUpdateLastSeenReady(std::move(lastSeenReadyQ), this);
-}
-
-}
-}
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxUpdateLastSeenReady : public TTransactionBase<TBlobStorageController> {
+ std::vector<std::pair<TVSlotId, TInstant>> LastSeenReadyQ;
+
+public:
+ TTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ, TBlobStorageController *controller)
+ : TBase(controller)
+ , LastSeenReadyQ(std::move(lastSeenReadyQ))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_LAST_SEEN_READY; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ for (const auto& [vslotId, lastSeenReady] : LastSeenReadyQ) {
+ db.Table<Schema::VSlot>().Key(vslotId.GetKey()).Update<Schema::VSlot::LastSeenReady>(lastSeenReady);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+ITransaction* TBlobStorageController::CreateTxUpdateLastSeenReady(std::vector<std::pair<TVSlotId, TInstant>> lastSeenReadyQ) {
+ return new TTxUpdateLastSeenReady(std::move(lastSeenReadyQ), this);
+}
+
+}
+}
diff --git a/ydb/core/mind/bscontroller/update_seen_operational.cpp b/ydb/core/mind/bscontroller/update_seen_operational.cpp
index 82784d3e0b0..276e46194a6 100644
--- a/ydb/core/mind/bscontroller/update_seen_operational.cpp
+++ b/ydb/core/mind/bscontroller/update_seen_operational.cpp
@@ -1,34 +1,34 @@
-#include "impl.h"
-
-namespace NKikimr {
-namespace NBsController {
-
-class TBlobStorageController::TTxUpdateSeenOperational : public TTransactionBase<TBlobStorageController> {
- TVector<TGroupId> GroupIds;
-
-public:
- TTxUpdateSeenOperational(TVector<TGroupId> groupIds, TBlobStorageController *controller)
- : TBase(controller)
- , GroupIds(std::move(groupIds))
- {}
-
- TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_SEEN_OPERATIONAL; }
-
- bool Execute(TTransactionContext &txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- for (const TGroupId groupId : GroupIds) {
- db.Table<Schema::Group>().Key(groupId).Update<Schema::Group::SeenOperational>(true);
- Self->SysViewChangedGroups.insert(groupId);
- }
- return true;
- }
-
- void Complete(const TActorContext&) override {}
-};
-
-ITransaction* TBlobStorageController::CreateTxUpdateSeenOperational(TVector<TGroupId> groupIds) {
- return new TTxUpdateSeenOperational(std::move(groupIds), this);
-}
-
-}
-}
+#include "impl.h"
+
+namespace NKikimr {
+namespace NBsController {
+
+class TBlobStorageController::TTxUpdateSeenOperational : public TTransactionBase<TBlobStorageController> {
+ TVector<TGroupId> GroupIds;
+
+public:
+ TTxUpdateSeenOperational(TVector<TGroupId> groupIds, TBlobStorageController *controller)
+ : TBase(controller)
+ , GroupIds(std::move(groupIds))
+ {}
+
+ TTxType GetTxType() const override { return NBlobStorageController::TXTYPE_UPDATE_SEEN_OPERATIONAL; }
+
+ bool Execute(TTransactionContext &txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ for (const TGroupId groupId : GroupIds) {
+ db.Table<Schema::Group>().Key(groupId).Update<Schema::Group::SeenOperational>(true);
+ Self->SysViewChangedGroups.insert(groupId);
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext&) override {}
+};
+
+ITransaction* TBlobStorageController::CreateTxUpdateSeenOperational(TVector<TGroupId> groupIds) {
+ return new TTxUpdateSeenOperational(std::move(groupIds), this);
+}
+
+}
+}
diff --git a/ydb/core/mind/bscontroller/ut/ya.make b/ydb/core/mind/bscontroller/ut/ya.make
index 46321b23789..e99f262b709 100644
--- a/ydb/core/mind/bscontroller/ut/ya.make
+++ b/ydb/core/mind/bscontroller/ut/ya.make
@@ -1,13 +1,13 @@
UNITTEST_FOR(ydb/core/mind/bscontroller)
-
-OWNER(alexvru g:kikimr)
-
-SRCS(
- grouper_ut.cpp
- group_mapper_ut.cpp
- mv_object_map_ut.cpp
-)
-
+
+OWNER(alexvru g:kikimr)
+
+SRCS(
+ grouper_ut.cpp
+ group_mapper_ut.cpp
+ mv_object_map_ut.cpp
+)
+
FORK_SUBTESTS()
IF (SANITIZER_TYPE OR WITH_VALGRIND)
@@ -19,9 +19,9 @@ ELSE()
SIZE(MEDIUM)
ENDIF()
-PEERDIR(
+PEERDIR(
library/cpp/actors/util
ydb/core/yql_testlib
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/mind/bscontroller/ut_bscontroller/main.cpp b/ydb/core/mind/bscontroller/ut_bscontroller/main.cpp
index 87f7b18fb35..aaaf2a5e358 100644
--- a/ydb/core/mind/bscontroller/ut_bscontroller/main.cpp
+++ b/ydb/core/mind/bscontroller/ut_bscontroller/main.cpp
@@ -16,44 +16,44 @@
#include <library/cpp/actors/interconnect/interconnect.h>
#include <util/datetime/cputimer.h>
-#include <util/random/random.h>
-
+#include <util/random/random.h>
+
#include <google/protobuf/text_format.h>
-using namespace NActors;
-using namespace NKikimr;
-using namespace NKikimr::NBsController;
-
-class TInitialEventsFilter : TNonCopyable {
-public:
- TTestActorRuntime::TEventFilter Prepare() {
+using namespace NActors;
+using namespace NKikimr;
+using namespace NKikimr::NBsController;
+
+class TInitialEventsFilter : TNonCopyable {
+public:
+ TTestActorRuntime::TEventFilter Prepare() {
return [](TTestActorRuntimeBase& /*runtime*/, TAutoPtr<IEventHandle>& /*event*/) {
- return false;
- };
- }
-};
-
-struct TEnvironmentSetup {
- THolder<TTestBasicRuntime> Runtime;
- const ui32 NodeCount;
- const ui32 DataCenterCount;
- const ui32 Domain = 0;
- const ui64 TabletId = MakeBSControllerID(Domain);
- const TVector<ui64> TabletIds = {TabletId};
- const TDuration Timeout = TDuration::Seconds(30);
- const ui32 GroupId = 0;
- const ui32 NodeId = 0;
- ui64 NextHostConfigId = 1;
- TInitialEventsFilter InitialEventsFilter;
-
- using TNodeRecord = std::tuple<TString, i32, ui32>;
- using TPDiskDefinition = std::tuple<TString, NKikimrBlobStorage::EPDiskType, bool, bool, ui64>;
- using TPDiskRecord = std::tuple<ui32, TPDiskDefinition>;
-
- TSet<TPDiskRecord> ExpectedPDisks;
-
- TPDiskRecord ParsePDiskRecord(const NKikimrBlobStorage::TBaseConfig::TPDisk& pdisk) {
- return std::make_tuple(
+ return false;
+ };
+ }
+};
+
+struct TEnvironmentSetup {
+ THolder<TTestBasicRuntime> Runtime;
+ const ui32 NodeCount;
+ const ui32 DataCenterCount;
+ const ui32 Domain = 0;
+ const ui64 TabletId = MakeBSControllerID(Domain);
+ const TVector<ui64> TabletIds = {TabletId};
+ const TDuration Timeout = TDuration::Seconds(30);
+ const ui32 GroupId = 0;
+ const ui32 NodeId = 0;
+ ui64 NextHostConfigId = 1;
+ TInitialEventsFilter InitialEventsFilter;
+
+ using TNodeRecord = std::tuple<TString, i32, ui32>;
+ using TPDiskDefinition = std::tuple<TString, NKikimrBlobStorage::EPDiskType, bool, bool, ui64>;
+ using TPDiskRecord = std::tuple<ui32, TPDiskDefinition>;
+
+ TSet<TPDiskRecord> ExpectedPDisks;
+
+ TPDiskRecord ParsePDiskRecord(const NKikimrBlobStorage::TBaseConfig::TPDisk& pdisk) {
+ return std::make_tuple(
pdisk.GetNodeId(),
std::make_tuple(
pdisk.GetPath(),
@@ -61,44 +61,44 @@ struct TEnvironmentSetup {
pdisk.GetSharedWithOs(),
pdisk.GetReadCentric(),
pdisk.GetKind()));
- }
-
- TSet<TPDiskRecord> ParsePDisks(const NKikimrBlobStorage::TBaseConfig& config) {
- TSet<TPDiskRecord> res;
- for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pdisk : config.GetPDisk()) {
- res.insert(ParsePDiskRecord(pdisk));
- }
- return res;
- }
-
- TEnvironmentSetup(ui32 nodeCount, ui32 dataCenterCount)
- : NodeCount(nodeCount)
- , DataCenterCount(dataCenterCount)
+ }
+
+ TSet<TPDiskRecord> ParsePDisks(const NKikimrBlobStorage::TBaseConfig& config) {
+ TSet<TPDiskRecord> res;
+ for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pdisk : config.GetPDisk()) {
+ res.insert(ParsePDiskRecord(pdisk));
+ }
+ return res;
+ }
+
+ TEnvironmentSetup(ui32 nodeCount, ui32 dataCenterCount)
+ : NodeCount(nodeCount)
+ , DataCenterCount(dataCenterCount)
{
}
-
- void Prepare(const TString& /*dispatchName*/, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- outActiveZone = false;
- SetupRuntime(NodeCount, DataCenterCount);
- SetupLogging();
- SetupStorage();
- setup(*Runtime);
- SetupTablet();
- }
-
- TTestActorRuntime::TEventFilter PrepareInitialEventsFilter() {
- return InitialEventsFilter.Prepare();
- }
-
- NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
+
+ void Prepare(const TString& /*dispatchName*/, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
+ outActiveZone = false;
+ SetupRuntime(NodeCount, DataCenterCount);
+ SetupLogging();
+ SetupStorage();
+ setup(*Runtime);
+ SetupTablet();
+ }
+
+ TTestActorRuntime::TEventFilter PrepareInitialEventsFilter() {
+ return InitialEventsFilter.Prepare();
+ }
+
+ NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
const TActorId self = Runtime->AllocateEdgeActor();
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- ev->Record.MutableRequest()->CopyFrom(request);
- Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, GetPipeConfigWithRetries());
- auto response = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(self);
- return response->Get()->Record.GetResponse();
- }
-
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ ev->Record.MutableRequest()->CopyFrom(request);
+ Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, GetPipeConfigWithRetries());
+ auto response = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(self);
+ return response->Get()->Record.GetResponse();
+ }
+
void RegisterNode() {
for (ui32 i = 1; i <= NodeCount; ++i) {
const TActorId self = Runtime->AllocateEdgeActor();
@@ -109,190 +109,190 @@ struct TEnvironmentSetup {
}
- NKikimrBlobStorage::TEvControllerSelectGroupsResult SelectGroups(const NKikimrBlobStorage::TEvControllerSelectGroups& request) {
+ NKikimrBlobStorage::TEvControllerSelectGroupsResult SelectGroups(const NKikimrBlobStorage::TEvControllerSelectGroups& request) {
const TActorId self = Runtime->AllocateEdgeActor();
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
- ev->Record.MergeFrom(request);
- Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, GetPipeConfigWithRetries());
- auto response = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerSelectGroupsResult>(self);
- return response->Get()->Record;
- }
-
- TVector<std::tuple<TString, i32, ui32>> GetNodes() {
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
+ ev->Record.MergeFrom(request);
+ Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, GetPipeConfigWithRetries());
+ auto response = Runtime->GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerSelectGroupsResult>(self);
+ return response->Get()->Record;
+ }
+
+ TVector<std::tuple<TString, i32, ui32>> GetNodes() {
const TActorId edge = Runtime->AllocateEdgeActor();
Runtime->Send(new IEventHandle(GetNameserviceActorId(), edge, new TEvInterconnect::TEvListNodes));
- auto response = Runtime->GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(edge);
- TVector<std::tuple<TString, i32, ui32>> res;
- for (const auto& nodeInfo : response->Get()->Nodes) {
- res.emplace_back(nodeInfo.Host, nodeInfo.Port, nodeInfo.NodeId);
- }
- return res;
- }
-
- void DefineBox(ui64 boxId, const TString& name, const TVector<TPDiskDefinition>& pdisks,
+ auto response = Runtime->GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(edge);
+ TVector<std::tuple<TString, i32, ui32>> res;
+ for (const auto& nodeInfo : response->Get()->Nodes) {
+ res.emplace_back(nodeInfo.Host, nodeInfo.Port, nodeInfo.NodeId);
+ }
+ return res;
+ }
+
+ void DefineBox(ui64 boxId, const TString& name, const TVector<TPDiskDefinition>& pdisks,
const TVector<TNodeRecord>& nodes, NKikimrBlobStorage::TConfigRequest& request,
const ui64 generation = 0) {
- auto& hostcfg = *request.AddCommand()->MutableDefineHostConfig();
- hostcfg.SetHostConfigId(NextHostConfigId++);
- for (const auto& pdisk : pdisks) {
- TString path;
- NKikimrBlobStorage::EPDiskType type;
- bool sharedWithOs, readCentric;
- ui64 kind;
- std::tie(path, type, sharedWithOs, readCentric, kind) = pdisk;
- auto& drive = *hostcfg.AddDrive();
- drive.SetPath(path);
- drive.SetType(type);
- drive.SetSharedWithOs(sharedWithOs);
- drive.SetReadCentric(readCentric);
- drive.SetKind(kind);
- }
-
- auto& box = *request.AddCommand()->MutableDefineBox();
- box.SetBoxId(boxId);
- box.SetName(name);
+ auto& hostcfg = *request.AddCommand()->MutableDefineHostConfig();
+ hostcfg.SetHostConfigId(NextHostConfigId++);
+ for (const auto& pdisk : pdisks) {
+ TString path;
+ NKikimrBlobStorage::EPDiskType type;
+ bool sharedWithOs, readCentric;
+ ui64 kind;
+ std::tie(path, type, sharedWithOs, readCentric, kind) = pdisk;
+ auto& drive = *hostcfg.AddDrive();
+ drive.SetPath(path);
+ drive.SetType(type);
+ drive.SetSharedWithOs(sharedWithOs);
+ drive.SetReadCentric(readCentric);
+ drive.SetKind(kind);
+ }
+
+ auto& box = *request.AddCommand()->MutableDefineBox();
+ box.SetBoxId(boxId);
+ box.SetName(name);
box.SetItemConfigGeneration(generation);
- for (const auto& node : nodes) {
- TString fqdn;
- i32 icPort;
- ui32 nodeId;
- std::tie(fqdn, icPort, nodeId) = node;
-
- auto& host = *box.AddHost();
- host.SetHostConfigId(hostcfg.GetHostConfigId());
- auto& key = *host.MutableKey();
- key.SetFqdn(fqdn);
- key.SetIcPort(icPort);
-
- for (const auto& pdisk : pdisks) {
- ExpectedPDisks.emplace(nodeId, pdisk);
- }
- }
- }
-
- void DefineStoragePool(ui64 boxId, ui64 storagePoolId, const TString& name, ui32 numGroups,
+ for (const auto& node : nodes) {
+ TString fqdn;
+ i32 icPort;
+ ui32 nodeId;
+ std::tie(fqdn, icPort, nodeId) = node;
+
+ auto& host = *box.AddHost();
+ host.SetHostConfigId(hostcfg.GetHostConfigId());
+ auto& key = *host.MutableKey();
+ key.SetFqdn(fqdn);
+ key.SetIcPort(icPort);
+
+ for (const auto& pdisk : pdisks) {
+ ExpectedPDisks.emplace(nodeId, pdisk);
+ }
+ }
+ }
+
+ void DefineStoragePool(ui64 boxId, ui64 storagePoolId, const TString& name, ui32 numGroups,
TMaybe<NKikimrBlobStorage::EPDiskType> pdiskType, TMaybe<bool> sharedWithOs,
NKikimrBlobStorage::TConfigRequest& request, const TString& erasure = "block-4-2",
const ui64 generation = 0) {
- auto& cmd = *request.AddCommand()->MutableDefineStoragePool();
- cmd.SetBoxId(boxId);
- cmd.SetStoragePoolId(storagePoolId);
- cmd.SetName(name);
- cmd.SetErasureSpecies(erasure);
- cmd.SetVDiskKind("Default");
- cmd.SetNumGroups(numGroups);
+ auto& cmd = *request.AddCommand()->MutableDefineStoragePool();
+ cmd.SetBoxId(boxId);
+ cmd.SetStoragePoolId(storagePoolId);
+ cmd.SetName(name);
+ cmd.SetErasureSpecies(erasure);
+ cmd.SetVDiskKind("Default");
+ cmd.SetNumGroups(numGroups);
cmd.SetItemConfigGeneration(generation);
- if (pdiskType || sharedWithOs) {
- auto& filter = *cmd.AddPDiskFilter();
- if (pdiskType) {
- filter.AddProperty()->SetType(*pdiskType);
- }
- if (sharedWithOs) {
- filter.AddProperty()->SetSharedWithOs(*sharedWithOs);
- }
- }
- }
-
- void SetupRuntime(ui32 nodeCount, ui32 dataCenterCount) {
- Runtime = MakeHolder<TTestBasicRuntime>(nodeCount, dataCenterCount);
-
- TAppPrepare app;
- app.AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dc-1").Release());
- for (ui32 i = 0; i < nodeCount; ++i) {
- SetupStateStorage(*Runtime, i, 0, true);
- SetupTabletResolver(*Runtime, i);
- }
- Runtime->Initialize(app.Unwrap());
- }
-
- void SetupLogging() {
- Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
-
- auto prio = NLog::PRI_ERROR;
- Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
- Runtime->SetLogPriority(NKikimrServices::BS_NODE, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
- Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
- Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
- }
-
- void DisableLogging() {
- Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_ERROR);
- }
-
- void SetupStorage() {
+ if (pdiskType || sharedWithOs) {
+ auto& filter = *cmd.AddPDiskFilter();
+ if (pdiskType) {
+ filter.AddProperty()->SetType(*pdiskType);
+ }
+ if (sharedWithOs) {
+ filter.AddProperty()->SetSharedWithOs(*sharedWithOs);
+ }
+ }
+ }
+
+ void SetupRuntime(ui32 nodeCount, ui32 dataCenterCount) {
+ Runtime = MakeHolder<TTestBasicRuntime>(nodeCount, dataCenterCount);
+
+ TAppPrepare app;
+ app.AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dc-1").Release());
+ for (ui32 i = 0; i < nodeCount; ++i) {
+ SetupStateStorage(*Runtime, i, 0, true);
+ SetupTabletResolver(*Runtime, i);
+ }
+ Runtime->Initialize(app.Unwrap());
+ }
+
+ void SetupLogging() {
+ Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
+
+ auto prio = NLog::PRI_ERROR;
+ Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
+ Runtime->SetLogPriority(NKikimrServices::BS_NODE, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
+ Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
+ }
+
+ void DisableLogging() {
+ Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_ERROR);
+ }
+
+ void SetupStorage() {
const TActorId proxyId = MakeBlobStorageProxyID(GroupId);
- Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(), NodeId), NodeId);
- }
-
- void SetupTablet() {
+ Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(), NodeId), NodeId);
+ }
+
+ void SetupTablet() {
const TActorId bootstrapper = CreateTestBootstrapper(*Runtime,
CreateTestTabletInfo(TabletId, TTabletTypes::FLAT_BS_CONTROLLER, TErasureType::ErasureNone, GroupId),
&CreateFlatBsController, NodeId);
- Runtime->EnableScheduleForActor(bootstrapper);
- {
- TDispatchOptions options;
- options.FinalEvents.emplace_back(TEvTablet::EvBoot);
- Runtime->DispatchEvents(options);
- }
- }
-
- void Finalize() {
- Runtime.Reset();
- ExpectedPDisks.clear();
- }
-};
-
-class TFinalizer {
- TEnvironmentSetup& Env;
-
-public:
- TFinalizer(TEnvironmentSetup& env)
- : Env(env)
+ Runtime->EnableScheduleForActor(bootstrapper);
+ {
+ TDispatchOptions options;
+ options.FinalEvents.emplace_back(TEvTablet::EvBoot);
+ Runtime->DispatchEvents(options);
+ }
+ }
+
+ void Finalize() {
+ Runtime.Reset();
+ ExpectedPDisks.clear();
+ }
+};
+
+class TFinalizer {
+ TEnvironmentSetup& Env;
+
+public:
+ TFinalizer(TEnvironmentSetup& env)
+ : Env(env)
{
}
-
- ~TFinalizer() {
- Env.Finalize();
- }
-};
-
-Y_UNIT_TEST_SUITE(BsControllerConfig) {
- Y_UNIT_TEST(Basic) {
- TEnvironmentSetup env(10, 1);
+
+ ~TFinalizer() {
+ Env.Finalize();
+ }
+};
+
+Y_UNIT_TEST_SUITE(BsControllerConfig) {
+ Y_UNIT_TEST(Basic) {
+ TEnvironmentSetup env(10, 1);
RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- NKikimrBlobStorage::TConfigRequest request;
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
UNIT_ASSERT(response.GetSuccess()); });
- }
-
- Y_UNIT_TEST(PDiskCreate) {
- TEnvironmentSetup env(10, 1);
+ }
+
+ Y_UNIT_TEST(PDiskCreate) {
+ TEnvironmentSetup env(10, 1);
RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, "test box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, env.GetNodes(), request);
-
- size_t baseConfigIndex = request.CommandSize();
- request.AddCommand()->MutableQueryBaseConfig();
-
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, "test box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, env.GetNodes(), request);
+
+ size_t baseConfigIndex = request.CommandSize();
+ request.AddCommand()->MutableQueryBaseConfig();
+
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
UNIT_ASSERT(env.ParsePDisks(response.GetStatus(baseConfigIndex).GetBaseConfig()) == env.ExpectedPDisks); });
- }
-
+ }
+
Y_UNIT_TEST(ManyPDisksRestarts) {
int nodes = 100;
TEnvironmentSetup env(nodes, 1);
@@ -324,90 +324,90 @@ Y_UNIT_TEST_SUITE(BsControllerConfig) {
});
}
- Y_UNIT_TEST(ExtendByCreatingSeparateBox) {
- const ui32 numNodes = 50;
- const ui32 numNodes1 = 20;
- const ui32 numNodes2 = numNodes - numNodes1;
- const ui32 numGroups1 = numNodes1 * 3;
- const ui32 numGroups2 = numNodes2 * 4;
- TEnvironmentSetup env(numNodes, 1);
+ Y_UNIT_TEST(ExtendByCreatingSeparateBox) {
+ const ui32 numNodes = 50;
+ const ui32 numNodes1 = 20;
+ const ui32 numNodes2 = numNodes - numNodes1;
+ const ui32 numGroups1 = numNodes1 * 3;
+ const ui32 numGroups2 = numNodes2 * 4;
+ TEnvironmentSetup env(numNodes, 1);
RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- TVector<TEnvironmentSetup::TNodeRecord> nodes1, nodes2;
- for (const auto& node : env.GetNodes()) {
- (nodes1.size() < numNodes1 ? nodes1 : nodes2).push_back(node);
- }
-
- TSet<ui32> nodeIds1, nodeIds2;
- for (const auto& item : nodes1) {
- nodeIds1.insert(std::get<2>(item));
- }
- for (const auto& item : nodes2) {
- nodeIds2.insert(std::get<2>(item));
- }
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, "first box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, nodes1, request);
- env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
-
- size_t baseConfigIndex = request.CommandSize();
- request.AddCommand()->MutableQueryBaseConfig();
-
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- TMap<ui32, ui32> groups1;
- {
- const auto& baseConfig = response.GetStatus(baseConfigIndex).GetBaseConfig();
- UNIT_ASSERT(env.ParsePDisks(baseConfig) == env.ExpectedPDisks);
- for (const auto& vslot : baseConfig.GetVSlot()) {
- UNIT_ASSERT(vslot.HasVSlotId());
- UNIT_ASSERT(nodeIds1.count(vslot.GetVSlotId().GetNodeId()));
- ++groups1[vslot.GetGroupId()];
- }
- UNIT_ASSERT_EQUAL(groups1.size(), numGroups1);
- for (const auto& kv : groups1) {
- UNIT_ASSERT_EQUAL(kv.second, 8);
- }
- }
-
- request.Clear();
- env.DefineBox(2, "second box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, nodes2, request);
- env.DefineStoragePool(2, 1, "second storage pool", numGroups2, NKikimrBlobStorage::ROT, {}, request);
-
- baseConfigIndex = request.CommandSize();
- request.AddCommand()->MutableQueryBaseConfig();
-
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- TMap<ui32, ui32> groups2;
- {
- const auto& baseConfig = response.GetStatus(baseConfigIndex).GetBaseConfig();
- UNIT_ASSERT(env.ParsePDisks(baseConfig) == env.ExpectedPDisks);
- for (const auto& vslot : baseConfig.GetVSlot()) {
- UNIT_ASSERT(vslot.HasVSlotId());
- if (groups1.count(vslot.GetGroupId())) {
- UNIT_ASSERT(nodeIds1.count(vslot.GetVSlotId().GetNodeId()));
- } else {
- UNIT_ASSERT(nodeIds2.count(vslot.GetVSlotId().GetNodeId()));
- ++groups2[vslot.GetGroupId()];
- }
- }
- UNIT_ASSERT_EQUAL(groups2.size(), numGroups2);
- for (const auto& kv : groups2) {
- UNIT_ASSERT_EQUAL(kv.second, 8);
- }
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ TVector<TEnvironmentSetup::TNodeRecord> nodes1, nodes2;
+ for (const auto& node : env.GetNodes()) {
+ (nodes1.size() < numNodes1 ? nodes1 : nodes2).push_back(node);
+ }
+
+ TSet<ui32> nodeIds1, nodeIds2;
+ for (const auto& item : nodes1) {
+ nodeIds1.insert(std::get<2>(item));
+ }
+ for (const auto& item : nodes2) {
+ nodeIds2.insert(std::get<2>(item));
+ }
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, "first box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, nodes1, request);
+ env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
+
+ size_t baseConfigIndex = request.CommandSize();
+ request.AddCommand()->MutableQueryBaseConfig();
+
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ TMap<ui32, ui32> groups1;
+ {
+ const auto& baseConfig = response.GetStatus(baseConfigIndex).GetBaseConfig();
+ UNIT_ASSERT(env.ParsePDisks(baseConfig) == env.ExpectedPDisks);
+ for (const auto& vslot : baseConfig.GetVSlot()) {
+ UNIT_ASSERT(vslot.HasVSlotId());
+ UNIT_ASSERT(nodeIds1.count(vslot.GetVSlotId().GetNodeId()));
+ ++groups1[vslot.GetGroupId()];
+ }
+ UNIT_ASSERT_EQUAL(groups1.size(), numGroups1);
+ for (const auto& kv : groups1) {
+ UNIT_ASSERT_EQUAL(kv.second, 8);
+ }
+ }
+
+ request.Clear();
+ env.DefineBox(2, "second box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, nodes2, request);
+ env.DefineStoragePool(2, 1, "second storage pool", numGroups2, NKikimrBlobStorage::ROT, {}, request);
+
+ baseConfigIndex = request.CommandSize();
+ request.AddCommand()->MutableQueryBaseConfig();
+
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ TMap<ui32, ui32> groups2;
+ {
+ const auto& baseConfig = response.GetStatus(baseConfigIndex).GetBaseConfig();
+ UNIT_ASSERT(env.ParsePDisks(baseConfig) == env.ExpectedPDisks);
+ for (const auto& vslot : baseConfig.GetVSlot()) {
+ UNIT_ASSERT(vslot.HasVSlotId());
+ if (groups1.count(vslot.GetGroupId())) {
+ UNIT_ASSERT(nodeIds1.count(vslot.GetVSlotId().GetNodeId()));
+ } else {
+ UNIT_ASSERT(nodeIds2.count(vslot.GetVSlotId().GetNodeId()));
+ ++groups2[vslot.GetGroupId()];
+ }
+ }
+ UNIT_ASSERT_EQUAL(groups2.size(), numGroups2);
+ for (const auto& kv : groups2) {
+ UNIT_ASSERT_EQUAL(kv.second, 8);
+ }
} });
}
@@ -425,8 +425,8 @@ Y_UNIT_TEST_SUITE(BsControllerConfig) {
for (auto &node : nodes) {
(part1.size() < originNumNodes ? part1 : part2).push_back(node);
- }
-
+ }
+
// creating box of originNumNodes nodes
NKikimrBlobStorage::TConfigRequest request;
env.DefineBox(1, "first box", {
@@ -483,313 +483,313 @@ Y_UNIT_TEST_SUITE(BsControllerConfig) {
UNIT_ASSERT_EQUAL(kv.second, 8);
}
} });
- }
-
- Y_UNIT_TEST(DeleteStoragePool) {
- const ui32 numNodes = 50;
- const ui32 numGroups = 50;
- TEnvironmentSetup env(numNodes, 1);
- RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- NKikimrBlobStorage::TConfigRequest request;
- NKikimrBlobStorage::TConfigResponse response;
-
- env.DefineBox(1, "box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, env.GetNodes(), request);
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- request.Clear();
-
- env.DefineStoragePool(1, 1, "storage pool 1", numGroups, NKikimrBlobStorage::ROT, {}, request);
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- request.Clear();
-
- env.DefineStoragePool(1, 2, "storage pool 2", numGroups, NKikimrBlobStorage::SSD, {}, request);
- auto *m = request.AddCommand()->MutableDeleteStoragePool();
- m->SetBoxId(1);
- m->SetStoragePoolId(2);
- m->SetItemConfigGeneration(1);
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- request.Clear();
-
- m = request.AddCommand()->MutableDeleteStoragePool();
- m->SetBoxId(1);
- m->SetStoragePoolId(1);
- m->SetItemConfigGeneration(1);
- request.AddCommand()->MutableQueryBaseConfig();
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
- const auto& baseConfig = response.GetStatus(1).GetBaseConfig();
- UNIT_ASSERT(baseConfig.GetGroup().empty());
- UNIT_ASSERT(baseConfig.GetVSlot().empty());
- });
- }
-
- Y_UNIT_TEST(ReassignGroupDisk) {
- const ui32 numNodes = 12;
- const ui32 numGroups = 8;
- TEnvironmentSetup env(numNodes, 1);
-
- RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- NKikimrBlobStorage::TConfigRequest request;
- NKikimrBlobStorage::TConfigResponse response;
-
- auto invoke = [&] {
- response = env.Invoke(std::exchange(request, {}));
- auto fmt = [&] {
- google::protobuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString s;
- p.PrintToString(response, &s);
- return s;
- };
- Cerr << Sprintf("Response# %s", fmt().data());
- };
-
- env.DefineBox(1, "box", {{"/dev/disk", NKikimrBlobStorage::ROT, false, false, 0}}, env.GetNodes(), request);
- env.DefineStoragePool(1, 1, "storage pool", numGroups, NKikimrBlobStorage::ROT, {}, request);
-
- invoke();
-
- auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
- cmd->MutableHostKey()->SetNodeId(1);
- cmd->SetPath("/dev/disk");
- cmd->SetStatus(NKikimrBlobStorage::INACTIVE);
-
- invoke();
-
- auto *cmd2 = request.AddCommand()->MutableReassignGroupDisk();
- cmd2->SetGroupId(2147483649);
- cmd2->SetGroupGeneration(1);
- cmd2->SetFailDomainIdx(3);
- });
- }
-
- Y_UNIT_TEST(MergeBoxes) {
- const ui32 numNodes = 50;
- const ui32 numNodes1 = 20;
- const ui32 numNodes2 = numNodes - numNodes1;
- const ui32 numGroups1 = numNodes1 * 3;
- const ui32 numGroups2 = numNodes2 * 4;
- TEnvironmentSetup env(numNodes, 1);
- RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- TVector<TEnvironmentSetup::TNodeRecord> nodes1, nodes2;
- for (const auto& node : env.GetNodes()) {
- (nodes1.size() < numNodes1 ? nodes1 : nodes2).push_back(node);
- }
-
- TSet<ui32> nodeIds1, nodeIds2;
- for (const auto& item : nodes1) {
- nodeIds1.insert(std::get<2>(item));
- }
- for (const auto& item : nodes2) {
- nodeIds2.insert(std::get<2>(item));
- }
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, "first box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, nodes1, request);
- env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
-
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- request.Clear();
- env.DefineBox(2, "second box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, nodes2, request);
- env.DefineStoragePool(2, 1, "second storage pool", numGroups2, NKikimrBlobStorage::ROT, {}, request);
-
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- // merge boxes
-
- request.Clear();
- auto& cmd = *request.AddCommand()->MutableMergeBoxes();
- cmd.SetOriginBoxId(2);
- cmd.SetOriginBoxGeneration(1);
- cmd.SetTargetBoxId(1);
- cmd.SetTargetBoxGeneration(1);
- auto& item = *cmd.AddStoragePoolIdMap();
- item.SetOriginStoragePoolId(1);
- item.SetTargetStoragePoolId(2);
-
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- // validate result
-
- request.Clear();
- {
- auto& cmd = *request.AddCommand()->MutableReadBox();
- cmd.AddBoxId(1);
- }
-
- request.AddCommand()->MutableQueryBaseConfig();
-
- response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- UNIT_ASSERT(response.GetStatus(0).GetSuccess());
-
- // check box nodes
- TSet<std::tuple<TString, i32>> nodes;
- for (const auto& node : env.GetNodes()) {
- nodes.emplace(std::get<0>(node), std::get<1>(node));
- }
- UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(0).BoxSize(), 1);
- for (const auto& host : response.GetStatus(0).GetBox(0).GetHost()) {
- const auto& key = host.GetKey();
- const ui32 erased = nodes.erase(std::make_tuple(key.GetFqdn(), key.GetIcPort()));
- UNIT_ASSERT_VALUES_EQUAL(erased, 1);
- }
- UNIT_ASSERT(nodes.empty());
-
- // validate base config
- ui32 num1 = 0, num2 = 0;
- {
- const auto& baseConfig = response.GetStatus(1).GetBaseConfig();
- for (const auto& pdisk : baseConfig.GetPDisk()) {
- UNIT_ASSERT_VALUES_EQUAL(pdisk.GetBoxId(), 1);
- }
- for (const auto& group : baseConfig.GetGroup()) {
- UNIT_ASSERT_VALUES_EQUAL(group.GetBoxId(), 1);
- const ui64 storagePoolId = group.GetStoragePoolId();
- UNIT_ASSERT(storagePoolId == 1 || storagePoolId == 2);
- ++(storagePoolId == 1 ? num1 : num2);
- }
- UNIT_ASSERT_VALUES_EQUAL(num1, numGroups1);
- UNIT_ASSERT_VALUES_EQUAL(num2, numGroups2);
- }
-
- });
- }
-
- Y_UNIT_TEST(MoveGroups) {
- const ui32 numNodes = 50;
- const ui32 numGroups1 = 100;
- const ui32 numGroups2 = 50;
- TEnvironmentSetup env(numNodes, 1);
- RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
- TFinalizer finalizer(env);
- env.Prepare(dispatchName, setup, outActiveZone);
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, "first box", {
- {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
- {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
- {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
- }, env.GetNodes(), request);
- env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
- env.DefineStoragePool(1, 2, "second storage pool", numGroups2, NKikimrBlobStorage::SSD, {}, request);
-
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- auto check = [](const auto& proto) {
- google::protobuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString buffer;
- p.PrintToString(proto, &buffer);
- UNIT_ASSERT_C(proto.GetSuccess(), buffer);
- };
-
- auto getGroupMapping = [&] {
- request.Clear();
- request.AddCommand()->MutableQueryBaseConfig();
- response = env.Invoke(request);
- check(response);
- const auto& base = response.GetStatus(0);
- check(base);
- const auto& config = base.GetBaseConfig();
- TMap<std::pair<ui64, ui64>, TSet<ui32>> groups;
- for (const auto& group : config.GetGroup()) {
- groups[std::make_pair(group.GetBoxId(), group.GetStoragePoolId())].insert(group.GetGroupId());
- }
- return groups;
- };
-
- auto reference = getGroupMapping();
-
- auto& a = reference[std::make_pair(1, 1)];
- auto& b = reference[std::make_pair(1, 2)];
-
- UNIT_ASSERT_VALUES_EQUAL(a.size(), numGroups1);
- UNIT_ASSERT_VALUES_EQUAL(b.size(), numGroups2);
-
- request.Clear();
- auto *pb = request.AddCommand()->MutableMoveGroups();
- pb->SetBoxId(1);
- pb->SetOriginStoragePoolId(2);
- pb->SetOriginStoragePoolGeneration(1);
- pb->SetTargetStoragePoolId(1);
- pb->SetTargetStoragePoolGeneration(1);
- pb->AddExplicitGroupId(*b.begin());
- response = env.Invoke(request);
- check(response);
- a.insert(*b.begin());
- b.erase(b.begin());
- UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
-
- request.Clear();
- pb = request.AddCommand()->MutableMoveGroups();
- pb->SetBoxId(1);
- pb->SetOriginStoragePoolId(2);
- pb->SetOriginStoragePoolGeneration(2);
- pb->SetTargetStoragePoolId(1);
- pb->SetTargetStoragePoolGeneration(2);
- pb->AddExplicitGroupId(*b.begin());
- response = env.Invoke(request);
- check(response);
- a.insert(*b.begin());
- b.erase(b.begin());
- UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
-
- request.Clear();
- pb = request.AddCommand()->MutableMoveGroups();
- pb->SetBoxId(1);
- pb->SetOriginStoragePoolId(2);
- pb->SetOriginStoragePoolGeneration(3);
- pb->SetTargetStoragePoolId(1);
- pb->SetTargetStoragePoolGeneration(3);
- response = env.Invoke(request);
- check(response);
- a.merge(std::move(b));
- reference.erase(std::make_pair(1, 2));
- UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
- });
- }
-
- Y_UNIT_TEST(SelectAllGroups) {
- const int numGroups = 80;
- TEnvironmentSetup env(10, 1);
- bool activeZone;
- env.Prepare("", [](TTestActorRuntime&) {}, activeZone);
- env.DisableLogging();
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, "test box", {
+ }
+
+ Y_UNIT_TEST(DeleteStoragePool) {
+ const ui32 numNodes = 50;
+ const ui32 numGroups = 50;
+ TEnvironmentSetup env(numNodes, 1);
+ RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ NKikimrBlobStorage::TConfigResponse response;
+
+ env.DefineBox(1, "box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, env.GetNodes(), request);
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ request.Clear();
+
+ env.DefineStoragePool(1, 1, "storage pool 1", numGroups, NKikimrBlobStorage::ROT, {}, request);
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ request.Clear();
+
+ env.DefineStoragePool(1, 2, "storage pool 2", numGroups, NKikimrBlobStorage::SSD, {}, request);
+ auto *m = request.AddCommand()->MutableDeleteStoragePool();
+ m->SetBoxId(1);
+ m->SetStoragePoolId(2);
+ m->SetItemConfigGeneration(1);
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ request.Clear();
+
+ m = request.AddCommand()->MutableDeleteStoragePool();
+ m->SetBoxId(1);
+ m->SetStoragePoolId(1);
+ m->SetItemConfigGeneration(1);
+ request.AddCommand()->MutableQueryBaseConfig();
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+ const auto& baseConfig = response.GetStatus(1).GetBaseConfig();
+ UNIT_ASSERT(baseConfig.GetGroup().empty());
+ UNIT_ASSERT(baseConfig.GetVSlot().empty());
+ });
+ }
+
+ Y_UNIT_TEST(ReassignGroupDisk) {
+ const ui32 numNodes = 12;
+ const ui32 numGroups = 8;
+ TEnvironmentSetup env(numNodes, 1);
+
+ RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ NKikimrBlobStorage::TConfigResponse response;
+
+ auto invoke = [&] {
+ response = env.Invoke(std::exchange(request, {}));
+ auto fmt = [&] {
+ google::protobuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString s;
+ p.PrintToString(response, &s);
+ return s;
+ };
+ Cerr << Sprintf("Response# %s", fmt().data());
+ };
+
+ env.DefineBox(1, "box", {{"/dev/disk", NKikimrBlobStorage::ROT, false, false, 0}}, env.GetNodes(), request);
+ env.DefineStoragePool(1, 1, "storage pool", numGroups, NKikimrBlobStorage::ROT, {}, request);
+
+ invoke();
+
+ auto *cmd = request.AddCommand()->MutableUpdateDriveStatus();
+ cmd->MutableHostKey()->SetNodeId(1);
+ cmd->SetPath("/dev/disk");
+ cmd->SetStatus(NKikimrBlobStorage::INACTIVE);
+
+ invoke();
+
+ auto *cmd2 = request.AddCommand()->MutableReassignGroupDisk();
+ cmd2->SetGroupId(2147483649);
+ cmd2->SetGroupGeneration(1);
+ cmd2->SetFailDomainIdx(3);
+ });
+ }
+
+ Y_UNIT_TEST(MergeBoxes) {
+ const ui32 numNodes = 50;
+ const ui32 numNodes1 = 20;
+ const ui32 numNodes2 = numNodes - numNodes1;
+ const ui32 numGroups1 = numNodes1 * 3;
+ const ui32 numGroups2 = numNodes2 * 4;
+ TEnvironmentSetup env(numNodes, 1);
+ RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ TVector<TEnvironmentSetup::TNodeRecord> nodes1, nodes2;
+ for (const auto& node : env.GetNodes()) {
+ (nodes1.size() < numNodes1 ? nodes1 : nodes2).push_back(node);
+ }
+
+ TSet<ui32> nodeIds1, nodeIds2;
+ for (const auto& item : nodes1) {
+ nodeIds1.insert(std::get<2>(item));
+ }
+ for (const auto& item : nodes2) {
+ nodeIds2.insert(std::get<2>(item));
+ }
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, "first box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, nodes1, request);
+ env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
+
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ request.Clear();
+ env.DefineBox(2, "second box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, nodes2, request);
+ env.DefineStoragePool(2, 1, "second storage pool", numGroups2, NKikimrBlobStorage::ROT, {}, request);
+
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // merge boxes
+
+ request.Clear();
+ auto& cmd = *request.AddCommand()->MutableMergeBoxes();
+ cmd.SetOriginBoxId(2);
+ cmd.SetOriginBoxGeneration(1);
+ cmd.SetTargetBoxId(1);
+ cmd.SetTargetBoxGeneration(1);
+ auto& item = *cmd.AddStoragePoolIdMap();
+ item.SetOriginStoragePoolId(1);
+ item.SetTargetStoragePoolId(2);
+
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // validate result
+
+ request.Clear();
+ {
+ auto& cmd = *request.AddCommand()->MutableReadBox();
+ cmd.AddBoxId(1);
+ }
+
+ request.AddCommand()->MutableQueryBaseConfig();
+
+ response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ UNIT_ASSERT(response.GetStatus(0).GetSuccess());
+
+ // check box nodes
+ TSet<std::tuple<TString, i32>> nodes;
+ for (const auto& node : env.GetNodes()) {
+ nodes.emplace(std::get<0>(node), std::get<1>(node));
+ }
+ UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(0).BoxSize(), 1);
+ for (const auto& host : response.GetStatus(0).GetBox(0).GetHost()) {
+ const auto& key = host.GetKey();
+ const ui32 erased = nodes.erase(std::make_tuple(key.GetFqdn(), key.GetIcPort()));
+ UNIT_ASSERT_VALUES_EQUAL(erased, 1);
+ }
+ UNIT_ASSERT(nodes.empty());
+
+ // validate base config
+ ui32 num1 = 0, num2 = 0;
+ {
+ const auto& baseConfig = response.GetStatus(1).GetBaseConfig();
+ for (const auto& pdisk : baseConfig.GetPDisk()) {
+ UNIT_ASSERT_VALUES_EQUAL(pdisk.GetBoxId(), 1);
+ }
+ for (const auto& group : baseConfig.GetGroup()) {
+ UNIT_ASSERT_VALUES_EQUAL(group.GetBoxId(), 1);
+ const ui64 storagePoolId = group.GetStoragePoolId();
+ UNIT_ASSERT(storagePoolId == 1 || storagePoolId == 2);
+ ++(storagePoolId == 1 ? num1 : num2);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(num1, numGroups1);
+ UNIT_ASSERT_VALUES_EQUAL(num2, numGroups2);
+ }
+
+ });
+ }
+
+ Y_UNIT_TEST(MoveGroups) {
+ const ui32 numNodes = 50;
+ const ui32 numGroups1 = 100;
+ const ui32 numGroups2 = 50;
+ TEnvironmentSetup env(numNodes, 1);
+ RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, [&](const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
+ TFinalizer finalizer(env);
+ env.Prepare(dispatchName, setup, outActiveZone);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, "first box", {
+ {"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
+ {"/dev/disk2", NKikimrBlobStorage::ROT, true, false, 0},
+ {"/dev/disk3", NKikimrBlobStorage::SSD, false, false, 0},
+ }, env.GetNodes(), request);
+ env.DefineStoragePool(1, 1, "first storage pool", numGroups1, NKikimrBlobStorage::ROT, {}, request);
+ env.DefineStoragePool(1, 2, "second storage pool", numGroups2, NKikimrBlobStorage::SSD, {}, request);
+
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ auto check = [](const auto& proto) {
+ google::protobuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString buffer;
+ p.PrintToString(proto, &buffer);
+ UNIT_ASSERT_C(proto.GetSuccess(), buffer);
+ };
+
+ auto getGroupMapping = [&] {
+ request.Clear();
+ request.AddCommand()->MutableQueryBaseConfig();
+ response = env.Invoke(request);
+ check(response);
+ const auto& base = response.GetStatus(0);
+ check(base);
+ const auto& config = base.GetBaseConfig();
+ TMap<std::pair<ui64, ui64>, TSet<ui32>> groups;
+ for (const auto& group : config.GetGroup()) {
+ groups[std::make_pair(group.GetBoxId(), group.GetStoragePoolId())].insert(group.GetGroupId());
+ }
+ return groups;
+ };
+
+ auto reference = getGroupMapping();
+
+ auto& a = reference[std::make_pair(1, 1)];
+ auto& b = reference[std::make_pair(1, 2)];
+
+ UNIT_ASSERT_VALUES_EQUAL(a.size(), numGroups1);
+ UNIT_ASSERT_VALUES_EQUAL(b.size(), numGroups2);
+
+ request.Clear();
+ auto *pb = request.AddCommand()->MutableMoveGroups();
+ pb->SetBoxId(1);
+ pb->SetOriginStoragePoolId(2);
+ pb->SetOriginStoragePoolGeneration(1);
+ pb->SetTargetStoragePoolId(1);
+ pb->SetTargetStoragePoolGeneration(1);
+ pb->AddExplicitGroupId(*b.begin());
+ response = env.Invoke(request);
+ check(response);
+ a.insert(*b.begin());
+ b.erase(b.begin());
+ UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
+
+ request.Clear();
+ pb = request.AddCommand()->MutableMoveGroups();
+ pb->SetBoxId(1);
+ pb->SetOriginStoragePoolId(2);
+ pb->SetOriginStoragePoolGeneration(2);
+ pb->SetTargetStoragePoolId(1);
+ pb->SetTargetStoragePoolGeneration(2);
+ pb->AddExplicitGroupId(*b.begin());
+ response = env.Invoke(request);
+ check(response);
+ a.insert(*b.begin());
+ b.erase(b.begin());
+ UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
+
+ request.Clear();
+ pb = request.AddCommand()->MutableMoveGroups();
+ pb->SetBoxId(1);
+ pb->SetOriginStoragePoolId(2);
+ pb->SetOriginStoragePoolGeneration(3);
+ pb->SetTargetStoragePoolId(1);
+ pb->SetTargetStoragePoolGeneration(3);
+ response = env.Invoke(request);
+ check(response);
+ a.merge(std::move(b));
+ reference.erase(std::make_pair(1, 2));
+ UNIT_ASSERT_VALUES_EQUAL(reference, getGroupMapping());
+ });
+ }
+
+ Y_UNIT_TEST(SelectAllGroups) {
+ const int numGroups = 80;
+ TEnvironmentSetup env(10, 1);
+ bool activeZone;
+ env.Prepare("", [](TTestActorRuntime&) {}, activeZone);
+ env.DisableLogging();
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, "test box", {
{"/dev/disk1", NKikimrBlobStorage::ROT, false, false, 0},
{"/dev/disk2", NKikimrBlobStorage::ROT, false, false, 0},
{"/dev/disk3", NKikimrBlobStorage::ROT, false, false, 0},
@@ -800,32 +800,32 @@ Y_UNIT_TEST_SUITE(BsControllerConfig) {
{"/dev/disk8", NKikimrBlobStorage::ROT, false, false, 0},
},
env.GetNodes(), request);
-
- env.DefineStoragePool(1, 1, "test pool", numGroups, NKikimrBlobStorage::ROT, false, request);
-
- NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
- UNIT_ASSERT(response.GetSuccess());
-
- {
- NKikimrBlobStorage::TEvControllerSelectGroups request;
- request.SetReturnAllMatchingGroups(true);
-
+
+ env.DefineStoragePool(1, 1, "test pool", numGroups, NKikimrBlobStorage::ROT, false, request);
+
+ NKikimrBlobStorage::TConfigResponse response = env.Invoke(request);
+ UNIT_ASSERT(response.GetSuccess());
+
+ {
+ NKikimrBlobStorage::TEvControllerSelectGroups request;
+ request.SetReturnAllMatchingGroups(true);
+
auto* p = request.AddGroupParameters();
- p->SetErasureSpecies(TBlobStorageGroupType::Erasure4Plus2Block);
- p->SetDesiredPDiskCategory(0);
- p->SetDesiredVDiskCategory(0);
-
- NKikimrBlobStorage::TEvControllerSelectGroupsResult res = env.SelectGroups(request);
- UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
- UNIT_ASSERT_VALUES_EQUAL(res.MatchingGroupsSize(), 1);
- THashSet<ui32> groupIds;
- for (const auto& item : res.GetMatchingGroups(0).GetGroups()) {
- UNIT_ASSERT(groupIds.insert(item.GetGroupID()).second);
- }
- UNIT_ASSERT_VALUES_EQUAL(groupIds.size(), numGroups);
- }
- }
-
+ p->SetErasureSpecies(TBlobStorageGroupType::Erasure4Plus2Block);
+ p->SetDesiredPDiskCategory(0);
+ p->SetDesiredVDiskCategory(0);
+
+ NKikimrBlobStorage::TEvControllerSelectGroupsResult res = env.SelectGroups(request);
+ UNIT_ASSERT_VALUES_EQUAL(res.GetStatus(), NKikimrProto::OK);
+ UNIT_ASSERT_VALUES_EQUAL(res.MatchingGroupsSize(), 1);
+ THashSet<ui32> groupIds;
+ for (const auto& item : res.GetMatchingGroups(0).GetGroups()) {
+ UNIT_ASSERT(groupIds.insert(item.GetGroupID()).second);
+ }
+ UNIT_ASSERT_VALUES_EQUAL(groupIds.size(), numGroups);
+ }
+ }
+
Y_UNIT_TEST(AddDriveSerial) {
TEnvironmentSetup env(10, 1);
auto test = [&] (const TString& dispatchName, std::function<void(TTestActorRuntime&)> setup, bool& outActiveZone) {
@@ -884,226 +884,226 @@ Y_UNIT_TEST_SUITE(BsControllerConfig) {
RunTestWithReboots(env.TabletIds, [&] { return env.PrepareInitialEventsFilter(); }, test);
}
- Y_UNIT_TEST(OverlayMap) {
- for (ui32 iter = 0; iter < 100; ++iter) {
- struct TItem {
- ui32 Value;
-
- TItem() = default;
- TItem(TItem&&) = default;
- TItem(const TItem&) = default;
-
- TItem(ui32 value)
- : Value(value)
- {}
-
- bool operator ==(const TItem& other) const {
- return Value == other.Value;
- }
-
- void OnClone(const THolder<TItem>&) {}
- void OnCommit(...) {}
- void OnRollback(...) {}
- };
-
- TMap<ui32, THolder<TItem>> base, reference;
-
- for (ui32 i = 0; i < 1000; ++i) {
- ui32 index = RandomNumber<ui32>(1000);
- base[index] = MakeHolder<TItem>(i);
- reference[index] = MakeHolder<TItem>(i);
+ Y_UNIT_TEST(OverlayMap) {
+ for (ui32 iter = 0; iter < 100; ++iter) {
+ struct TItem {
+ ui32 Value;
+
+ TItem() = default;
+ TItem(TItem&&) = default;
+ TItem(const TItem&) = default;
+
+ TItem(ui32 value)
+ : Value(value)
+ {}
+
+ bool operator ==(const TItem& other) const {
+ return Value == other.Value;
+ }
+
+ void OnClone(const THolder<TItem>&) {}
+ void OnCommit(...) {}
+ void OnRollback(...) {}
+ };
+
+ TMap<ui32, THolder<TItem>> base, reference;
+
+ for (ui32 i = 0; i < 1000; ++i) {
+ ui32 index = RandomNumber<ui32>(1000);
+ base[index] = MakeHolder<TItem>(i);
+ reference[index] = MakeHolder<TItem>(i);
Ctest << "initial " << index << " -> " << i << Endl;
- }
-
- TOverlayMap<ui32, TItem> overlay(base);
-
- for (ui32 i = 0; i < 100; ++i) {
- bool deleteSomething = reference && RandomNumber<ui32>(100) < 20;
- if (deleteSomething) {
- const ui32 index = RandomNumber(reference.size());
- auto it = reference.begin();
- std::advance(it, index);
+ }
+
+ TOverlayMap<ui32, TItem> overlay(base);
+
+ for (ui32 i = 0; i < 100; ++i) {
+ bool deleteSomething = reference && RandomNumber<ui32>(100) < 20;
+ if (deleteSomething) {
+ const ui32 index = RandomNumber(reference.size());
+ auto it = reference.begin();
+ std::advance(it, index);
Ctest << "deleting " << it->first << Endl;
- overlay.DeleteExistingEntry(it->first);
- reference.erase(it);
- } else {
- const ui32 index = RandomNumber<ui32>(1000);
- const ui32 value = RandomNumber<ui32>();
- if (reference.count(index)) {
+ overlay.DeleteExistingEntry(it->first);
+ reference.erase(it);
+ } else {
+ const ui32 index = RandomNumber<ui32>(1000);
+ const ui32 value = RandomNumber<ui32>();
+ if (reference.count(index)) {
Ctest << "updating " << index << " -> " << value << Endl;
- TItem *valp = overlay.FindForUpdate(index);
- Y_VERIFY(valp);
- valp->Value = value;
- } else {
+ TItem *valp = overlay.FindForUpdate(index);
+ Y_VERIFY(valp);
+ valp->Value = value;
+ } else {
Ctest << "inserting " << index << " -> " << value << Endl;
- overlay.ConstructInplaceNewEntry(index, value);
- }
- reference[index] = MakeHolder<TItem>(value);
- }
- }
-
- TMap<ui32, TItem> generated;
- overlay.ForEach([&](ui32 key, const TItem& value) {
- const bool inserted = generated.emplace(key, value).second;
- UNIT_ASSERT(inserted);
- });
-
- auto downgradeMap = [](const TMap<ui32, THolder<TItem>>& m) {
- TMap<ui32, TItem> res;
- for (auto&& [key, value] : m) {
- UNIT_ASSERT(value);
- res.emplace(key, *value);
- }
- return res;
- };
-
- UNIT_ASSERT_EQUAL(generated, downgradeMap(reference));
-
- overlay.Commit();
-
- UNIT_ASSERT_EQUAL(downgradeMap(base), downgradeMap(reference));
- }
- }
-
- struct TBeta;
-
- struct TAlpha : TIndirectReferable<TAlpha> {
- const unsigned Key;
- unsigned Value = 0;
- TMap<unsigned, TIndirectReferable<TBeta>::TPtr> BetaRefs;
-
- TAlpha(unsigned key) : Key(key) {}
- TAlpha(const TAlpha&) = default;
-
- void OnCommit();
- };
-
- struct TBeta : TIndirectReferable<TBeta> {
- const unsigned Key;
- unsigned Value = 0;
- TMap<unsigned, TIndirectReferable<TAlpha>::TPtr> AlphaRefs;
-
- TBeta(unsigned key) : Key(key) {}
- TBeta(const TBeta&) = default;
-
- void OnCommit();
- };
-
- void TAlpha::OnCommit() {
- for (const auto& [key, value] : BetaRefs) {
- value.Mutable().AlphaRefs[Key] = this;
- }
- }
-
- void TBeta::OnCommit() {
- for (const auto& [key, value] : AlphaRefs) {
- value.Mutable().BetaRefs[Key] = this;
- }
- }
-
- Y_UNIT_TEST(OverlayMapCrossReferences) {
- struct TState {
- TOverlayMap<unsigned, TAlpha> Alphas;
- TOverlayMap<unsigned, TBeta> Betas;
-
- TState(TMap<unsigned, THolder<TAlpha>>& alphas, TMap<unsigned, THolder<TBeta>>& betas)
- : Alphas(alphas)
- , Betas(betas)
- {}
- };
-
- for (int iter = 0; iter < 100; ++iter) {
+ overlay.ConstructInplaceNewEntry(index, value);
+ }
+ reference[index] = MakeHolder<TItem>(value);
+ }
+ }
+
+ TMap<ui32, TItem> generated;
+ overlay.ForEach([&](ui32 key, const TItem& value) {
+ const bool inserted = generated.emplace(key, value).second;
+ UNIT_ASSERT(inserted);
+ });
+
+ auto downgradeMap = [](const TMap<ui32, THolder<TItem>>& m) {
+ TMap<ui32, TItem> res;
+ for (auto&& [key, value] : m) {
+ UNIT_ASSERT(value);
+ res.emplace(key, *value);
+ }
+ return res;
+ };
+
+ UNIT_ASSERT_EQUAL(generated, downgradeMap(reference));
+
+ overlay.Commit();
+
+ UNIT_ASSERT_EQUAL(downgradeMap(base), downgradeMap(reference));
+ }
+ }
+
+ struct TBeta;
+
+ struct TAlpha : TIndirectReferable<TAlpha> {
+ const unsigned Key;
+ unsigned Value = 0;
+ TMap<unsigned, TIndirectReferable<TBeta>::TPtr> BetaRefs;
+
+ TAlpha(unsigned key) : Key(key) {}
+ TAlpha(const TAlpha&) = default;
+
+ void OnCommit();
+ };
+
+ struct TBeta : TIndirectReferable<TBeta> {
+ const unsigned Key;
+ unsigned Value = 0;
+ TMap<unsigned, TIndirectReferable<TAlpha>::TPtr> AlphaRefs;
+
+ TBeta(unsigned key) : Key(key) {}
+ TBeta(const TBeta&) = default;
+
+ void OnCommit();
+ };
+
+ void TAlpha::OnCommit() {
+ for (const auto& [key, value] : BetaRefs) {
+ value.Mutable().AlphaRefs[Key] = this;
+ }
+ }
+
+ void TBeta::OnCommit() {
+ for (const auto& [key, value] : AlphaRefs) {
+ value.Mutable().BetaRefs[Key] = this;
+ }
+ }
+
+ Y_UNIT_TEST(OverlayMapCrossReferences) {
+ struct TState {
+ TOverlayMap<unsigned, TAlpha> Alphas;
+ TOverlayMap<unsigned, TBeta> Betas;
+
+ TState(TMap<unsigned, THolder<TAlpha>>& alphas, TMap<unsigned, THolder<TBeta>>& betas)
+ : Alphas(alphas)
+ , Betas(betas)
+ {}
+ };
+
+ for (int iter = 0; iter < 100; ++iter) {
Ctest << "Next iteration\n";
- const unsigned num = 1000;
- TMap<unsigned, THolder<TAlpha>> alphas;
- TMap<unsigned, THolder<TBeta>> betas;
- for (unsigned key = 0; key < num; ++key) {
- alphas.emplace(key, MakeHolder<TAlpha>(key));
- betas.emplace(key, MakeHolder<TBeta>(key));
+ const unsigned num = 1000;
+ TMap<unsigned, THolder<TAlpha>> alphas;
+ TMap<unsigned, THolder<TBeta>> betas;
+ for (unsigned key = 0; key < num; ++key) {
+ alphas.emplace(key, MakeHolder<TAlpha>(key));
+ betas.emplace(key, MakeHolder<TBeta>(key));
Ctest << Sprintf("Alpha[%u]# %p\n", key, alphas[key].Get());
Ctest << Sprintf("Beta[%u]# %p\n", key, alphas[key].Get());
- }
- for (int i = 0; i < 1000; ++i) {
- const unsigned a = RandomNumber(num);
- const unsigned b = RandomNumber(num);
- alphas[a]->BetaRefs[b] = betas[b].Get();
- betas[b]->AlphaRefs[a] = alphas[a].Get();
- }
-
- TState state(alphas, betas);
-
- THashSet<unsigned> alphaKeys, betaKeys;
- for (int i = 0; i < 100; ++i) {
- alphaKeys.insert(RandomNumber(num));
- betaKeys.insert(RandomNumber(num));
- }
-
- for (unsigned key : alphaKeys) {
+ }
+ for (int i = 0; i < 1000; ++i) {
+ const unsigned a = RandomNumber(num);
+ const unsigned b = RandomNumber(num);
+ alphas[a]->BetaRefs[b] = betas[b].Get();
+ betas[b]->AlphaRefs[a] = alphas[a].Get();
+ }
+
+ TState state(alphas, betas);
+
+ THashSet<unsigned> alphaKeys, betaKeys;
+ for (int i = 0; i < 100; ++i) {
+ alphaKeys.insert(RandomNumber(num));
+ betaKeys.insert(RandomNumber(num));
+ }
+
+ for (unsigned key : alphaKeys) {
Ctest << Sprintf("Alphas.FindForUpdate Key# %u\n", key);
- ++state.Alphas.FindForUpdate(key)->Value;
- }
- for (unsigned key : betaKeys) {
+ ++state.Alphas.FindForUpdate(key)->Value;
+ }
+ for (unsigned key : betaKeys) {
Ctest << Sprintf("Betas.FindForUpdate Key# %u\n", key);
- ++state.Betas.FindForUpdate(key)->Value;
- }
-
- for (unsigned key = 0; key < num; ++key) {
- UNIT_ASSERT_VALUES_EQUAL(key, state.Alphas.Find(key)->Key);
- UNIT_ASSERT_VALUES_EQUAL(key, state.Betas.Find(key)->Key);
-
- const TAlpha *alpha = state.Alphas.Find(key);
- UNIT_ASSERT_VALUES_EQUAL(alpha->Value, alphaKeys.count(key));
- for (const auto& [key, value] : alpha->BetaRefs) {
- UNIT_ASSERT_VALUES_EQUAL(Sprintf("%p", (const TBeta*)value), Sprintf("%p", state.Betas.Find(key)));
- }
-
- const TBeta *beta = state.Betas.Find(key);
- UNIT_ASSERT_VALUES_EQUAL(beta->Value, betaKeys.count(key));
- for (const auto& [key, value] : beta->AlphaRefs) {
- UNIT_ASSERT_VALUES_EQUAL(Sprintf("%p", (const TAlpha*)value), Sprintf("%p", state.Alphas.Find(key)));
- }
- }
-
- state.Alphas.Commit();
- state.Betas.Commit();
-
- for (unsigned key = 0; key < num; ++key) {
- const TAlpha& alpha = *alphas.at(key);
- UNIT_ASSERT_VALUES_EQUAL(alpha.Value, alphaKeys.count(key));
- for (const auto& [key, value] : alpha.BetaRefs) {
- UNIT_ASSERT_VALUES_EQUAL((const TBeta*)value, betas.at(key).Get());
- }
-
- const TBeta& beta = *betas.at(key);
- UNIT_ASSERT_VALUES_EQUAL(beta.Value, betaKeys.count(key));
- for (const auto& [key, value] : beta.AlphaRefs) {
- UNIT_ASSERT_VALUES_EQUAL((const TAlpha*)value, alphas.at(key).Get());
- }
- }
- }
- }
-
- Y_UNIT_TEST(VDiskStatusTracker) {
- using E = NKikimrBlobStorage::EVDiskStatus;
- TInstant base = TInstant::Zero();
- TVDiskStatusTracker tracker(TDuration::Seconds(60));
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(0)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
- tracker.Update(E::INIT_PENDING, base + TDuration::Seconds(10));
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), E::INIT_PENDING);
- tracker.Update(E::REPLICATING, base + TDuration::Seconds(20));
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), E::REPLICATING);
- tracker.Update(E::READY, base + TDuration::Seconds(30));
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(95)), E::READY);
- tracker.Update(E::ERROR, base + TDuration::Seconds(40));
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), std::nullopt);
- UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(95)), std::nullopt);
- }
-}
+ ++state.Betas.FindForUpdate(key)->Value;
+ }
+
+ for (unsigned key = 0; key < num; ++key) {
+ UNIT_ASSERT_VALUES_EQUAL(key, state.Alphas.Find(key)->Key);
+ UNIT_ASSERT_VALUES_EQUAL(key, state.Betas.Find(key)->Key);
+
+ const TAlpha *alpha = state.Alphas.Find(key);
+ UNIT_ASSERT_VALUES_EQUAL(alpha->Value, alphaKeys.count(key));
+ for (const auto& [key, value] : alpha->BetaRefs) {
+ UNIT_ASSERT_VALUES_EQUAL(Sprintf("%p", (const TBeta*)value), Sprintf("%p", state.Betas.Find(key)));
+ }
+
+ const TBeta *beta = state.Betas.Find(key);
+ UNIT_ASSERT_VALUES_EQUAL(beta->Value, betaKeys.count(key));
+ for (const auto& [key, value] : beta->AlphaRefs) {
+ UNIT_ASSERT_VALUES_EQUAL(Sprintf("%p", (const TAlpha*)value), Sprintf("%p", state.Alphas.Find(key)));
+ }
+ }
+
+ state.Alphas.Commit();
+ state.Betas.Commit();
+
+ for (unsigned key = 0; key < num; ++key) {
+ const TAlpha& alpha = *alphas.at(key);
+ UNIT_ASSERT_VALUES_EQUAL(alpha.Value, alphaKeys.count(key));
+ for (const auto& [key, value] : alpha.BetaRefs) {
+ UNIT_ASSERT_VALUES_EQUAL((const TBeta*)value, betas.at(key).Get());
+ }
+
+ const TBeta& beta = *betas.at(key);
+ UNIT_ASSERT_VALUES_EQUAL(beta.Value, betaKeys.count(key));
+ for (const auto& [key, value] : beta.AlphaRefs) {
+ UNIT_ASSERT_VALUES_EQUAL((const TAlpha*)value, alphas.at(key).Get());
+ }
+ }
+ }
+ }
+
+ Y_UNIT_TEST(VDiskStatusTracker) {
+ using E = NKikimrBlobStorage::EVDiskStatus;
+ TInstant base = TInstant::Zero();
+ TVDiskStatusTracker tracker(TDuration::Seconds(60));
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(0)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
+ tracker.Update(E::INIT_PENDING, base + TDuration::Seconds(10));
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), E::INIT_PENDING);
+ tracker.Update(E::REPLICATING, base + TDuration::Seconds(20));
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), E::REPLICATING);
+ tracker.Update(E::READY, base + TDuration::Seconds(30));
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(15)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(95)), E::READY);
+ tracker.Update(E::ERROR, base + TDuration::Seconds(40));
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(75)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(85)), std::nullopt);
+ UNIT_ASSERT_VALUES_EQUAL(tracker.GetStatus(base + TDuration::Seconds(95)), std::nullopt);
+ }
+}
diff --git a/ydb/core/mind/bscontroller/ut_bscontroller/ya.make b/ydb/core/mind/bscontroller/ut_bscontroller/ya.make
index afe250e60f0..bf35bb98392 100644
--- a/ydb/core/mind/bscontroller/ut_bscontroller/ya.make
+++ b/ydb/core/mind/bscontroller/ut_bscontroller/ya.make
@@ -1,12 +1,12 @@
-UNITTEST()
-
+UNITTEST()
+
FORK_SUBTESTS()
OWNER(
alexvru
g:kikimr
)
-
+
REQUIREMENTS(
cpu:4
ram:16
@@ -24,7 +24,7 @@ ENDIF()
SRCS(
main.cpp
)
-
+
PEERDIR(
ydb/core/base
ydb/core/blobstorage
@@ -35,9 +35,9 @@ PEERDIR(
ydb/core/testlib
ydb/core/testlib/basics
)
-
+
YQL_LAST_ABI_VERSION()
REQUIREMENTS(network:full)
-END()
+END()
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/defs.h b/ydb/core/mind/bscontroller/ut_selfheal/defs.h
index 7841958b2b0..8277275e3f0 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/defs.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/defs.h
@@ -1,15 +1,15 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/mind/bscontroller/defs.h>
-
+
#include <ydb/core/blobstorage/dsproxy/mock/dsproxy_mock.h>
#include <ydb/core/blobstorage/pdisk/mock/pdisk_mock.h>
-
+
#include <ydb/core/mind/bscontroller/bsc.h>
#include <ydb/core/mind/bscontroller/types.h>
-
+
#include <ydb/core/util/testactorsys.h>
-
-using namespace NActors;
-using namespace NKikimr;
-using namespace NKikimr::NBsController;
+
+using namespace NActors;
+using namespace NKikimr;
+using namespace NKikimr::NBsController;
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/env.h b/ydb/core/mind/bscontroller/ut_selfheal/env.h
index e79bf914a17..b1392e4ba02 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/env.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/env.h
@@ -1,209 +1,209 @@
-#pragma once
-
-#include "defs.h"
-
-#include "node_warden_mock.h"
-#include "timer_actor.h"
-#include "events.h"
-
-struct TEnvironmentSetup {
- std::unique_ptr<TTestActorSystem> Runtime;
- const ui32 NodeCount;
- const ui32 Domain = 0;
- const ui64 TabletId = MakeBSControllerID(Domain);
- const TDuration Timeout = TDuration::Seconds(30);
- const ui32 GroupId = 0;
- const ui32 NodeId = 1;
- ui64 NextHostConfigId = 1;
+#pragma once
+
+#include "defs.h"
+
+#include "node_warden_mock.h"
+#include "timer_actor.h"
+#include "events.h"
+
+struct TEnvironmentSetup {
+ std::unique_ptr<TTestActorSystem> Runtime;
+ const ui32 NodeCount;
+ const ui32 Domain = 0;
+ const ui64 TabletId = MakeBSControllerID(Domain);
+ const TDuration Timeout = TDuration::Seconds(30);
+ const ui32 GroupId = 0;
+ const ui32 NodeId = 1;
+ ui64 NextHostConfigId = 1;
TActorId TimerActor;
-
- TEnvironmentSetup(ui32 nodeCount)
- : NodeCount(nodeCount)
- {
- Initialize();
- }
-
- ~TEnvironmentSetup() {
- Cleanup();
- }
-
- void Initialize() {
- Runtime = std::make_unique<TTestActorSystem>(NodeCount);
- TimerActor = Runtime->Register(new TTimerActor, NodeId);
- SetupLogging();
- Runtime->Start();
- auto *appData = Runtime->GetAppData();
- appData->DomainsInfo->AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dom", Domain).Release());
- Runtime->SetupTabletRuntime();
- SetupStorage();
- SetupTablet();
- }
-
- void Cleanup() {
- Runtime->Stop();
- Runtime.reset();
- }
-
- template<typename TEvent>
- TAutoPtr<TEventHandle<TEvent>> WaitForEdgeActorEvent(const TActorId& actorId, bool termOnCapture = true) {
- for (;;) {
- auto ev = Runtime->WaitForEdgeActorEvent({actorId});
- if (ev->GetTypeRewrite() == TEvent::EventType) {
- TAutoPtr<TEventHandle<TEvent>> res = reinterpret_cast<TEventHandle<TEvent>*>(ev.release());
- if (termOnCapture) {
- Runtime->DestroyActor(actorId);
- }
- return res;
- }
- }
- }
-
- NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
- const TActorId self = Runtime->AllocateEdgeActor(NodeId);
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- ev->Record.MutableRequest()->CopyFrom(request);
- Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, TTestActorSystem::GetPipeConfigWithRetries());
- auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerConfigResponse>(self);
- return response->Get()->Record.GetResponse();
- }
-
- std::map<ui32, std::tuple<TString, i32>> GetNodeMap() {
- const TActorId edge = Runtime->AllocateEdgeActor(NodeId);
- Runtime->Send(new IEventHandle(GetNameserviceActorId(), edge, new TEvInterconnect::TEvListNodes), NodeId);
- auto response = WaitForEdgeActorEvent<TEvInterconnect::TEvNodesInfo>(edge);
- std::map<ui32, std::tuple<TString, i32>> res;
- for (const auto& nodeInfo : response->Get()->Nodes) {
- res.emplace(nodeInfo.NodeId, std::tie(nodeInfo.Host, nodeInfo.Port));
- }
- return res;
- }
-
- struct TDrive {
- TString Path;
- NKikimrBlobStorage::EPDiskType Type = NKikimrBlobStorage::ROT;
- bool SharedWithOs = false, ReadCentric = false;
- ui64 Kind = 0;
- };
-
- struct TNodeRange {
- ui32 From;
- ui32 To;
- };
-
- void DefineBox(ui64 boxId, const TVector<TDrive>& drives, const TVector<TNodeRange>& nodes,
- NKikimrBlobStorage::TConfigRequest *request, const ui64 generation = 0) {
- auto *hostcfg = request->AddCommand()->MutableDefineHostConfig();
- hostcfg->SetHostConfigId(NextHostConfigId);
- for (const auto& d : drives) {
- auto *pb = hostcfg->AddDrive();
- pb->SetPath(d.Path);
- pb->SetType(d.Type);
- pb->SetSharedWithOs(d.SharedWithOs);
- pb->SetReadCentric(d.ReadCentric);
- pb->SetKind(d.Kind);
- }
-
- auto *box = request->AddCommand()->MutableDefineBox();
- box->SetBoxId(boxId);
- box->SetName(TStringBuilder() << "BoxId# " << boxId);
- box->SetItemConfigGeneration(generation);
- for (const auto& range : nodes) {
- for (ui32 nodeId = range.From; nodeId <= range.To; ++nodeId) {
- auto *host = box->AddHost();
- host->SetHostConfigId(NextHostConfigId);
- auto *key = host->MutableKey();
- key->SetNodeId(nodeId);
- }
- }
-
- ++NextHostConfigId;
- }
-
- void DefineStoragePool(ui64 boxId, ui64 storagePoolId, ui32 numGroups,
- std::optional<NKikimrBlobStorage::EPDiskType> pdiskType, std::optional<bool> sharedWithOs,
- NKikimrBlobStorage::TConfigRequest *request, const TString& erasure = "block-4-2",
- const ui64 generation = 0) {
- auto *cmd = request->AddCommand()->MutableDefineStoragePool();
- cmd->SetBoxId(boxId);
- cmd->SetStoragePoolId(storagePoolId);
- cmd->SetName(TStringBuilder() << "BoxId# " << boxId << " StoragePoolId# " << storagePoolId);
- cmd->SetErasureSpecies(erasure);
- cmd->SetVDiskKind("Default");
- cmd->SetNumGroups(numGroups);
- cmd->SetItemConfigGeneration(generation);
- auto *filter = cmd->AddPDiskFilter();
- if (pdiskType) {
- filter->AddProperty()->SetType(*pdiskType);
- }
- if (sharedWithOs) {
- filter->AddProperty()->SetSharedWithOs(*sharedWithOs);
- }
- }
-
- void QueryBaseConfig(NKikimrBlobStorage::TConfigRequest *request) {
- request->AddCommand()->MutableQueryBaseConfig();
- }
-
- void UpdateDriveStatus(const TPDiskId& pdiskId, NKikimrBlobStorage::EDriveStatus status,
- NKikimrBlobStorage::TConfigRequest *request) {
- auto *cmd = request->AddCommand()->MutableUpdateDriveStatus();
- cmd->MutableHostKey()->SetNodeId(pdiskId.NodeId);
- cmd->SetPDiskId(pdiskId.PDiskId);
- cmd->SetStatus(status);
- }
-
- void SetupLogging() {
-// Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
- Runtime->SetLogPriority(NKikimrServices::BS_SELFHEAL, NLog::PRI_DEBUG);
- Runtime->SetLogPriority(NKikimrServices::BS_NODE, NLog::PRI_DEBUG);
-
- auto prio = NLog::PRI_ERROR;
- Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
- Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
- Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
- Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
- Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
- }
-
- void SetupStorage() {
+
+ TEnvironmentSetup(ui32 nodeCount)
+ : NodeCount(nodeCount)
+ {
+ Initialize();
+ }
+
+ ~TEnvironmentSetup() {
+ Cleanup();
+ }
+
+ void Initialize() {
+ Runtime = std::make_unique<TTestActorSystem>(NodeCount);
+ TimerActor = Runtime->Register(new TTimerActor, NodeId);
+ SetupLogging();
+ Runtime->Start();
+ auto *appData = Runtime->GetAppData();
+ appData->DomainsInfo->AddDomain(TDomainsInfo::TDomain::ConstructEmptyDomain("dom", Domain).Release());
+ Runtime->SetupTabletRuntime();
+ SetupStorage();
+ SetupTablet();
+ }
+
+ void Cleanup() {
+ Runtime->Stop();
+ Runtime.reset();
+ }
+
+ template<typename TEvent>
+ TAutoPtr<TEventHandle<TEvent>> WaitForEdgeActorEvent(const TActorId& actorId, bool termOnCapture = true) {
+ for (;;) {
+ auto ev = Runtime->WaitForEdgeActorEvent({actorId});
+ if (ev->GetTypeRewrite() == TEvent::EventType) {
+ TAutoPtr<TEventHandle<TEvent>> res = reinterpret_cast<TEventHandle<TEvent>*>(ev.release());
+ if (termOnCapture) {
+ Runtime->DestroyActor(actorId);
+ }
+ return res;
+ }
+ }
+ }
+
+ NKikimrBlobStorage::TConfigResponse Invoke(const NKikimrBlobStorage::TConfigRequest& request) {
+ const TActorId self = Runtime->AllocateEdgeActor(NodeId);
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ ev->Record.MutableRequest()->CopyFrom(request);
+ Runtime->SendToPipe(TabletId, self, ev.Release(), NodeId, TTestActorSystem::GetPipeConfigWithRetries());
+ auto response = WaitForEdgeActorEvent<TEvBlobStorage::TEvControllerConfigResponse>(self);
+ return response->Get()->Record.GetResponse();
+ }
+
+ std::map<ui32, std::tuple<TString, i32>> GetNodeMap() {
+ const TActorId edge = Runtime->AllocateEdgeActor(NodeId);
+ Runtime->Send(new IEventHandle(GetNameserviceActorId(), edge, new TEvInterconnect::TEvListNodes), NodeId);
+ auto response = WaitForEdgeActorEvent<TEvInterconnect::TEvNodesInfo>(edge);
+ std::map<ui32, std::tuple<TString, i32>> res;
+ for (const auto& nodeInfo : response->Get()->Nodes) {
+ res.emplace(nodeInfo.NodeId, std::tie(nodeInfo.Host, nodeInfo.Port));
+ }
+ return res;
+ }
+
+ struct TDrive {
+ TString Path;
+ NKikimrBlobStorage::EPDiskType Type = NKikimrBlobStorage::ROT;
+ bool SharedWithOs = false, ReadCentric = false;
+ ui64 Kind = 0;
+ };
+
+ struct TNodeRange {
+ ui32 From;
+ ui32 To;
+ };
+
+ void DefineBox(ui64 boxId, const TVector<TDrive>& drives, const TVector<TNodeRange>& nodes,
+ NKikimrBlobStorage::TConfigRequest *request, const ui64 generation = 0) {
+ auto *hostcfg = request->AddCommand()->MutableDefineHostConfig();
+ hostcfg->SetHostConfigId(NextHostConfigId);
+ for (const auto& d : drives) {
+ auto *pb = hostcfg->AddDrive();
+ pb->SetPath(d.Path);
+ pb->SetType(d.Type);
+ pb->SetSharedWithOs(d.SharedWithOs);
+ pb->SetReadCentric(d.ReadCentric);
+ pb->SetKind(d.Kind);
+ }
+
+ auto *box = request->AddCommand()->MutableDefineBox();
+ box->SetBoxId(boxId);
+ box->SetName(TStringBuilder() << "BoxId# " << boxId);
+ box->SetItemConfigGeneration(generation);
+ for (const auto& range : nodes) {
+ for (ui32 nodeId = range.From; nodeId <= range.To; ++nodeId) {
+ auto *host = box->AddHost();
+ host->SetHostConfigId(NextHostConfigId);
+ auto *key = host->MutableKey();
+ key->SetNodeId(nodeId);
+ }
+ }
+
+ ++NextHostConfigId;
+ }
+
+ void DefineStoragePool(ui64 boxId, ui64 storagePoolId, ui32 numGroups,
+ std::optional<NKikimrBlobStorage::EPDiskType> pdiskType, std::optional<bool> sharedWithOs,
+ NKikimrBlobStorage::TConfigRequest *request, const TString& erasure = "block-4-2",
+ const ui64 generation = 0) {
+ auto *cmd = request->AddCommand()->MutableDefineStoragePool();
+ cmd->SetBoxId(boxId);
+ cmd->SetStoragePoolId(storagePoolId);
+ cmd->SetName(TStringBuilder() << "BoxId# " << boxId << " StoragePoolId# " << storagePoolId);
+ cmd->SetErasureSpecies(erasure);
+ cmd->SetVDiskKind("Default");
+ cmd->SetNumGroups(numGroups);
+ cmd->SetItemConfigGeneration(generation);
+ auto *filter = cmd->AddPDiskFilter();
+ if (pdiskType) {
+ filter->AddProperty()->SetType(*pdiskType);
+ }
+ if (sharedWithOs) {
+ filter->AddProperty()->SetSharedWithOs(*sharedWithOs);
+ }
+ }
+
+ void QueryBaseConfig(NKikimrBlobStorage::TConfigRequest *request) {
+ request->AddCommand()->MutableQueryBaseConfig();
+ }
+
+ void UpdateDriveStatus(const TPDiskId& pdiskId, NKikimrBlobStorage::EDriveStatus status,
+ NKikimrBlobStorage::TConfigRequest *request) {
+ auto *cmd = request->AddCommand()->MutableUpdateDriveStatus();
+ cmd->MutableHostKey()->SetNodeId(pdiskId.NodeId);
+ cmd->SetPDiskId(pdiskId.PDiskId);
+ cmd->SetStatus(status);
+ }
+
+ void SetupLogging() {
+// Runtime->SetLogPriority(NKikimrServices::BS_CONTROLLER, NLog::PRI_DEBUG);
+ Runtime->SetLogPriority(NKikimrServices::BS_SELFHEAL, NLog::PRI_DEBUG);
+ Runtime->SetLogPriority(NKikimrServices::BS_NODE, NLog::PRI_DEBUG);
+
+ auto prio = NLog::PRI_ERROR;
+ Runtime->SetLogPriority(NKikimrServices::TABLET_MAIN, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_EXECUTOR, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_CLIENT, prio);
+ Runtime->SetLogPriority(NKikimrServices::PIPE_SERVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::TABLET_RESOLVER, prio);
+ Runtime->SetLogPriority(NKikimrServices::STATESTORAGE, prio);
+ Runtime->SetLogPriority(NKikimrServices::BOOTSTRAPPER, prio);
+ }
+
+ void SetupStorage() {
const TActorId proxyId = MakeBlobStorageProxyID(GroupId);
- Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(), NodeId));
-
- for (ui32 nodeId : Runtime->GetNodes()) {
- const TActorId wardenId = Runtime->Register(new TNodeWardenMock(nodeId, TabletId), nodeId);
- Runtime->RegisterService(MakeBlobStorageNodeWardenID(nodeId), wardenId);
- }
- }
-
- void SetupTablet() {
+ Runtime->RegisterService(proxyId, Runtime->Register(CreateBlobStorageGroupProxyMockActor(), NodeId));
+
+ for (ui32 nodeId : Runtime->GetNodes()) {
+ const TActorId wardenId = Runtime->Register(new TNodeWardenMock(nodeId, TabletId), nodeId);
+ Runtime->RegisterService(MakeBlobStorageNodeWardenID(nodeId), wardenId);
+ }
+ }
+
+ void SetupTablet() {
Runtime->CreateTestBootstrapper(
TTestActorSystem::CreateTestTabletInfo(TabletId, TTabletTypes::FLAT_BS_CONTROLLER, TErasureType::ErasureNone, GroupId),
- &CreateFlatBsController,
- NodeId);
-
- bool working = true;
- Runtime->Sim([&] { return working; }, [&](IEventHandle& event) { working = event.GetTypeRewrite() != TEvTablet::EvBoot; });
- }
-
- void WaitForNodeWardensToConnect() {
- std::vector<TActorId> edges;
- for (ui32 nodeId : Runtime->GetNodes()) {
+ &CreateFlatBsController,
+ NodeId);
+
+ bool working = true;
+ Runtime->Sim([&] { return working; }, [&](IEventHandle& event) { working = event.GetTypeRewrite() != TEvTablet::EvBoot; });
+ }
+
+ void WaitForNodeWardensToConnect() {
+ std::vector<TActorId> edges;
+ for (ui32 nodeId : Runtime->GetNodes()) {
const TActorId wardenId = MakeBlobStorageNodeWardenID(nodeId);
- const TActorId edge = Runtime->AllocateEdgeActor(nodeId);
- Runtime->Send(new IEventHandle(wardenId, edge, new TEvCheckState(EState::CONNECTED)), nodeId);
- edges.push_back(edge);
- }
- for (TActorId edge : edges) {
- WaitForEdgeActorEvent<TEvDone>(edge);
- }
+ const TActorId edge = Runtime->AllocateEdgeActor(nodeId);
+ Runtime->Send(new IEventHandle(wardenId, edge, new TEvCheckState(EState::CONNECTED)), nodeId);
+ edges.push_back(edge);
+ }
+ for (TActorId edge : edges) {
+ WaitForEdgeActorEvent<TEvDone>(edge);
+ }
Ctest << "All node wardens are connected to BSC" << Endl;
- }
-
- void Wait(TDuration timeout) {
- const TActorId edge = Runtime->AllocateEdgeActor(NodeId);
- Runtime->Send(new IEventHandle(TimerActor, edge, new TEvArmTimer(timeout)), NodeId);
- WaitForEdgeActorEvent<TEvents::TEvWakeup>(edge);
- }
-};
+ }
+
+ void Wait(TDuration timeout) {
+ const TActorId edge = Runtime->AllocateEdgeActor(NodeId);
+ Runtime->Send(new IEventHandle(TimerActor, edge, new TEvArmTimer(timeout)), NodeId);
+ WaitForEdgeActorEvent<TEvents::TEvWakeup>(edge);
+ }
+};
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/events.h b/ydb/core/mind/bscontroller/ut_selfheal/events.h
index 40b9c3a22bf..f0cb41150cc 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/events.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/events.h
@@ -1,11 +1,11 @@
-#pragma once
-
-#include "defs.h"
-
-enum {
- EvCheckState = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
- EvDone,
- EvUpdateDriveStatus,
- EvArmTimer,
- EvTimer,
-};
+#pragma once
+
+#include "defs.h"
+
+enum {
+ EvCheckState = EventSpaceBegin(TKikimrEvents::ES_PRIVATE),
+ EvDone,
+ EvUpdateDriveStatus,
+ EvArmTimer,
+ EvTimer,
+};
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/main.cpp b/ydb/core/mind/bscontroller/ut_selfheal/main.cpp
index 79bba0a26a2..8f898c214f8 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/main.cpp
+++ b/ydb/core/mind/bscontroller/ut_selfheal/main.cpp
@@ -2,83 +2,83 @@
#include <library/cpp/testing/unittest/registar.h>
-#include "env.h"
-
-Y_UNIT_TEST_SUITE(BsControllerTest) {
-
- Y_UNIT_TEST(SelfHeal) {
- const ui32 numNodes = 32;
- const ui32 numDisksPerNode = 2;
- const ui32 numGroups = numNodes * numDisksPerNode;
- TEnvironmentSetup env(numNodes);
-
- NKikimrBlobStorage::TConfigRequest request;
- env.DefineBox(1, {{"/dev/disk1"}, {"/dev/disk2"}}, {{1, numNodes}}, &request);
- env.DefineStoragePool(1, 1, numGroups, NKikimrBlobStorage::ROT, {}, &request);
- auto response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- env.WaitForNodeWardensToConnect();
-
- request.Clear();
- auto *cmd = request.AddCommand()->MutableEnableSelfHeal();
- cmd->SetEnable(true);
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
-
- std::set<TPDiskId> active, faulty;
-
- request = {};
- env.QueryBaseConfig(&request);
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
- active.emplace(pdisk.GetNodeId(), pdisk.GetPDiskId());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(active.size(), numNodes * numDisksPerNode);
-
- auto move = [&](auto& from, auto& to, NKikimrBlobStorage::EDriveStatus status) {
- auto it = from.begin();
- std::advance(it, RandomNumber(from.size()));
+#include "env.h"
+
+Y_UNIT_TEST_SUITE(BsControllerTest) {
+
+ Y_UNIT_TEST(SelfHeal) {
+ const ui32 numNodes = 32;
+ const ui32 numDisksPerNode = 2;
+ const ui32 numGroups = numNodes * numDisksPerNode;
+ TEnvironmentSetup env(numNodes);
+
+ NKikimrBlobStorage::TConfigRequest request;
+ env.DefineBox(1, {{"/dev/disk1"}, {"/dev/disk2"}}, {{1, numNodes}}, &request);
+ env.DefineStoragePool(1, 1, numGroups, NKikimrBlobStorage::ROT, {}, &request);
+ auto response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ env.WaitForNodeWardensToConnect();
+
+ request.Clear();
+ auto *cmd = request.AddCommand()->MutableEnableSelfHeal();
+ cmd->SetEnable(true);
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+
+ std::set<TPDiskId> active, faulty;
+
+ request = {};
+ env.QueryBaseConfig(&request);
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
+ active.emplace(pdisk.GetNodeId(), pdisk.GetPDiskId());
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL(active.size(), numNodes * numDisksPerNode);
+
+ auto move = [&](auto& from, auto& to, NKikimrBlobStorage::EDriveStatus status) {
+ auto it = from.begin();
+ std::advance(it, RandomNumber(from.size()));
Ctest << "PDisk# " << *it
- << " setting status to " << NKikimrBlobStorage::EDriveStatus_Name(status)
- << Endl;
- request = {};
- env.UpdateDriveStatus(*it, status, &request);
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- to.insert(from.extract(it));
- };
-
- for (size_t i = 0; i < 32; ++i) {
- env.Wait(TDuration::Seconds(300));
- if (faulty.size() < 8) {
- move(active, faulty, NKikimrBlobStorage::FAULTY);
- } else {
- move(faulty, active, NKikimrBlobStorage::ACTIVE);
- }
- env.Wait(TDuration::Seconds(300));
-
- request = {};
- env.QueryBaseConfig(&request);
- response = env.Invoke(request);
- UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
- for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
- const TPDiskId pdiskId(pdisk.GetNodeId(), pdisk.GetPDiskId());
- if (pdisk.GetDriveStatus() == NKikimrBlobStorage::ACTIVE) {
- UNIT_ASSERT(active.count(pdiskId));
- } else {
- UNIT_ASSERT(pdisk.GetDriveStatus() == NKikimrBlobStorage::FAULTY);
- UNIT_ASSERT(faulty.count(pdiskId));
- }
- }
- for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
- const auto& id = vslot.GetVSlotId();
- const TPDiskId pdiskId(id.GetNodeId(), id.GetPDiskId());
- UNIT_ASSERT(active.count(pdiskId));
- }
- }
- }
-
-}
+ << " setting status to " << NKikimrBlobStorage::EDriveStatus_Name(status)
+ << Endl;
+ request = {};
+ env.UpdateDriveStatus(*it, status, &request);
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ to.insert(from.extract(it));
+ };
+
+ for (size_t i = 0; i < 32; ++i) {
+ env.Wait(TDuration::Seconds(300));
+ if (faulty.size() < 8) {
+ move(active, faulty, NKikimrBlobStorage::FAULTY);
+ } else {
+ move(faulty, active, NKikimrBlobStorage::ACTIVE);
+ }
+ env.Wait(TDuration::Seconds(300));
+
+ request = {};
+ env.QueryBaseConfig(&request);
+ response = env.Invoke(request);
+ UNIT_ASSERT_C(response.GetSuccess(), response.GetErrorDescription());
+ for (const auto& pdisk : response.GetStatus(0).GetBaseConfig().GetPDisk()) {
+ const TPDiskId pdiskId(pdisk.GetNodeId(), pdisk.GetPDiskId());
+ if (pdisk.GetDriveStatus() == NKikimrBlobStorage::ACTIVE) {
+ UNIT_ASSERT(active.count(pdiskId));
+ } else {
+ UNIT_ASSERT(pdisk.GetDriveStatus() == NKikimrBlobStorage::FAULTY);
+ UNIT_ASSERT(faulty.count(pdiskId));
+ }
+ }
+ for (const auto& vslot : response.GetStatus(0).GetBaseConfig().GetVSlot()) {
+ const auto& id = vslot.GetVSlotId();
+ const TPDiskId pdiskId(id.GetNodeId(), id.GetPDiskId());
+ UNIT_ASSERT(active.count(pdiskId));
+ }
+ }
+ }
+
+}
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/node_warden_mock.h b/ydb/core/mind/bscontroller/ut_selfheal/node_warden_mock.h
index 5c993ba0fb3..94a4947d3a2 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/node_warden_mock.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/node_warden_mock.h
@@ -1,184 +1,184 @@
-#pragma once
-
-#include "defs.h"
-
-#include "vdisk_mock.h"
-#include "events.h"
-
-enum class EState {
- INITIAL,
- CONNECTED,
-};
-
-struct TEvCheckState : TEventLocal<TEvCheckState, EvCheckState> {
- const EState State;
-
- TEvCheckState(EState state)
- : State(state)
- {}
-};
-
-struct TEvDone : TEventLocal<TEvDone, EvDone> {};
-struct TEvUpdateDriveStatus : TEventLocal<TEvUpdateDriveStatus, EvUpdateDriveStatus> {};
-
-class TNodeWardenMock : public TActorBootstrapped<TNodeWardenMock> {
- const ui32 NodeId;
- const ui64 TabletId;
+#pragma once
+
+#include "defs.h"
+
+#include "vdisk_mock.h"
+#include "events.h"
+
+enum class EState {
+ INITIAL,
+ CONNECTED,
+};
+
+struct TEvCheckState : TEventLocal<TEvCheckState, EvCheckState> {
+ const EState State;
+
+ TEvCheckState(EState state)
+ : State(state)
+ {}
+};
+
+struct TEvDone : TEventLocal<TEvDone, EvDone> {};
+struct TEvUpdateDriveStatus : TEventLocal<TEvUpdateDriveStatus, EvUpdateDriveStatus> {};
+
+class TNodeWardenMock : public TActorBootstrapped<TNodeWardenMock> {
+ const ui32 NodeId;
+ const ui64 TabletId;
TActorId PipeClient;
- bool Connected = false;
- EState CurrentState = EState::INITIAL;
+ bool Connected = false;
+ EState CurrentState = EState::INITIAL;
std::multimap<EState, TActorId> Queue;
- std::map<ui32, ui32> Groups;
- std::map<std::tuple<ui32, ui32>, std::unique_ptr<TVDisk>> VDisks;
-
-public:
- TNodeWardenMock(ui32 nodeId, ui64 tabletId)
- : NodeId(nodeId)
- , TabletId(tabletId)
- {}
-
- void Bootstrap() {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] Bootstrap", NodeId);
- Connect();
- Become(&TThis::StateFunc);
- }
-
- void Connect() {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] Connect", NodeId);
- UNIT_ASSERT(!PipeClient);
- PipeClient = Register(NTabletPipe::CreateClient(SelfId(), TabletId, {}));
- }
-
- void Handle(TEvCheckState::TPtr ev) {
- auto& msg = *ev->Get();
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] CheckState from %s expected %u current %u",
- NodeId, ev->Sender.ToString().data(), msg.State, CurrentState);
- if (CurrentState == msg.State) {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] sending Done to %s", NodeId, ev->Sender.ToString().data());
- Send(ev->Sender, new TEvDone);
- } else {
- Queue.emplace(msg.State, ev->Sender);
- }
- }
-
- void SwitchToState(EState state) {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] State switched from %u to %u", NodeId,
- CurrentState, state);
- CurrentState = state;
- auto r = Queue.equal_range(CurrentState);
- for (auto it = r.first; it != r.second; ++it) {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] sending Done to %s", NodeId, it->second.ToString().data());
- Send(it->second, new TEvDone);
- }
- Queue.erase(r.first, r.second);
- }
-
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
- auto& msg = *ev->Get();
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] ClientConnected Sender# %s Status# %s"
- " ClientId# %s ServerId# %s PipeClient# %s", NodeId, ev->Sender.ToString().data(),
- NKikimrProto::EReplyStatus_Name(msg.Status).data(), msg.ClientId.ToString().data(),
- msg.ServerId.ToString().data(), PipeClient.ToString().data());
- if (ev->Sender == PipeClient) {
- if (msg.Status != NKikimrProto::OK) {
- NTabletPipe::CloseAndForgetClient(SelfId(), PipeClient);
- Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
- } else {
- UNIT_ASSERT(!Connected);
- Connected = true;
- SwitchToState(EState::CONNECTED);
- OnConnected();
- }
- }
- }
-
- void OnConnected() {
- TVector<ui32> startedDynamicGroups, groupGenerations;
- for (const auto& [groupId, gen] : Groups) {
- startedDynamicGroups.push_back(groupId);
- groupGenerations.push_back(gen);
- }
-
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(NodeId, startedDynamicGroups,
+ std::map<ui32, ui32> Groups;
+ std::map<std::tuple<ui32, ui32>, std::unique_ptr<TVDisk>> VDisks;
+
+public:
+ TNodeWardenMock(ui32 nodeId, ui64 tabletId)
+ : NodeId(nodeId)
+ , TabletId(tabletId)
+ {}
+
+ void Bootstrap() {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] Bootstrap", NodeId);
+ Connect();
+ Become(&TThis::StateFunc);
+ }
+
+ void Connect() {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] Connect", NodeId);
+ UNIT_ASSERT(!PipeClient);
+ PipeClient = Register(NTabletPipe::CreateClient(SelfId(), TabletId, {}));
+ }
+
+ void Handle(TEvCheckState::TPtr ev) {
+ auto& msg = *ev->Get();
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] CheckState from %s expected %u current %u",
+ NodeId, ev->Sender.ToString().data(), msg.State, CurrentState);
+ if (CurrentState == msg.State) {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] sending Done to %s", NodeId, ev->Sender.ToString().data());
+ Send(ev->Sender, new TEvDone);
+ } else {
+ Queue.emplace(msg.State, ev->Sender);
+ }
+ }
+
+ void SwitchToState(EState state) {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] State switched from %u to %u", NodeId,
+ CurrentState, state);
+ CurrentState = state;
+ auto r = Queue.equal_range(CurrentState);
+ for (auto it = r.first; it != r.second; ++it) {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] sending Done to %s", NodeId, it->second.ToString().data());
+ Send(it->second, new TEvDone);
+ }
+ Queue.erase(r.first, r.second);
+ }
+
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr ev) {
+ auto& msg = *ev->Get();
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] ClientConnected Sender# %s Status# %s"
+ " ClientId# %s ServerId# %s PipeClient# %s", NodeId, ev->Sender.ToString().data(),
+ NKikimrProto::EReplyStatus_Name(msg.Status).data(), msg.ClientId.ToString().data(),
+ msg.ServerId.ToString().data(), PipeClient.ToString().data());
+ if (ev->Sender == PipeClient) {
+ if (msg.Status != NKikimrProto::OK) {
+ NTabletPipe::CloseAndForgetClient(SelfId(), PipeClient);
+ Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
+ } else {
+ UNIT_ASSERT(!Connected);
+ Connected = true;
+ SwitchToState(EState::CONNECTED);
+ OnConnected();
+ }
+ }
+ }
+
+ void OnConnected() {
+ TVector<ui32> startedDynamicGroups, groupGenerations;
+ for (const auto& [groupId, gen] : Groups) {
+ startedDynamicGroups.push_back(groupId);
+ groupGenerations.push_back(gen);
+ }
+
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerRegisterNode>(NodeId, startedDynamicGroups,
groupGenerations, TVector<NPDisk::TDriveData>{});
- auto& record = ev->Record;
- for (const auto& [id, vdisk] : VDisks) {
- vdisk->Serialize(record.AddVDiskStatus());
- }
- NTabletPipe::SendData(SelfId(), PipeClient, ev.release());
- }
-
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
- auto& msg = *ev->Get();
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] ClientDestroyed Sender# %s"
- " ClientId# %s ServerId# %s PipeClient# %s", NodeId, ev->Sender.ToString().data(), msg.ClientId.ToString().data(), msg.ServerId.ToString().data(), PipeClient.ToString().data());
- if (ev->Sender == PipeClient) {
- PipeClient = {};
- Connected = false;
- SwitchToState(EState::INITIAL);
- Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
- }
- }
-
- void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
- auto& msg = *ev->Get();
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] NodeServiceSetUpdate", NodeId);
-
- const auto& ss = msg.Record.GetServiceSet();
-
- for (const auto& group : ss.GetGroups()) {
- if (group.GetEntityStatus() != NKikimrBlobStorage::DESTROY) {
- Groups.emplace(group.GetGroupID(), group.GetGroupGeneration());
- } else {
- Groups.erase(group.GetGroupID());
- }
- }
-
- for (const auto& vdisk : ss.GetVDisks()) {
- const auto& location = vdisk.GetVDiskLocation();
- UNIT_ASSERT_VALUES_EQUAL(location.GetNodeID(), NodeId);
- const auto id = std::make_tuple(location.GetPDiskID(), location.GetVDiskSlotID());
- if (vdisk.GetEntityStatus() != NKikimrBlobStorage::DESTROY) {
- const TVDiskID vdiskId = VDiskIDFromVDiskID(vdisk.GetVDiskID());
- if (const auto it = VDisks.lower_bound(id); it != VDisks.end() && it->first == id) {
- it->second->UpdateVDiskId(vdiskId);
- } else {
- VDisks.emplace_hint(it, id, std::make_unique<TVDisk>(vdiskId, location.GetNodeID(),
- location.GetPDiskID(), location.GetVDiskSlotID(), location.GetPDiskGuid()));
+ auto& record = ev->Record;
+ for (const auto& [id, vdisk] : VDisks) {
+ vdisk->Serialize(record.AddVDiskStatus());
+ }
+ NTabletPipe::SendData(SelfId(), PipeClient, ev.release());
+ }
+
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr ev) {
+ auto& msg = *ev->Get();
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] ClientDestroyed Sender# %s"
+ " ClientId# %s ServerId# %s PipeClient# %s", NodeId, ev->Sender.ToString().data(), msg.ClientId.ToString().data(), msg.ServerId.ToString().data(), PipeClient.ToString().data());
+ if (ev->Sender == PipeClient) {
+ PipeClient = {};
+ Connected = false;
+ SwitchToState(EState::INITIAL);
+ Schedule(TDuration::MilliSeconds(100), new TEvents::TEvWakeup);
+ }
+ }
+
+ void Handle(TEvBlobStorage::TEvControllerNodeServiceSetUpdate::TPtr ev) {
+ auto& msg = *ev->Get();
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] NodeServiceSetUpdate", NodeId);
+
+ const auto& ss = msg.Record.GetServiceSet();
+
+ for (const auto& group : ss.GetGroups()) {
+ if (group.GetEntityStatus() != NKikimrBlobStorage::DESTROY) {
+ Groups.emplace(group.GetGroupID(), group.GetGroupGeneration());
+ } else {
+ Groups.erase(group.GetGroupID());
+ }
+ }
+
+ for (const auto& vdisk : ss.GetVDisks()) {
+ const auto& location = vdisk.GetVDiskLocation();
+ UNIT_ASSERT_VALUES_EQUAL(location.GetNodeID(), NodeId);
+ const auto id = std::make_tuple(location.GetPDiskID(), location.GetVDiskSlotID());
+ if (vdisk.GetEntityStatus() != NKikimrBlobStorage::DESTROY) {
+ const TVDiskID vdiskId = VDiskIDFromVDiskID(vdisk.GetVDiskID());
+ if (const auto it = VDisks.lower_bound(id); it != VDisks.end() && it->first == id) {
+ it->second->UpdateVDiskId(vdiskId);
+ } else {
+ VDisks.emplace_hint(it, id, std::make_unique<TVDisk>(vdiskId, location.GetNodeID(),
+ location.GetPDiskID(), location.GetVDiskSlotID(), location.GetPDiskGuid()));
}
- } else if (const auto it = VDisks.find(id); it != VDisks.end()) {
- it->second->StopActor();
- VDisks.erase(it);
- } else {
- UNIT_ASSERT(false);
- }
- }
-
- UpdateDriveStatus();
- }
-
- void UpdateDriveStatus() {
- if (Connected) {
- auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
- TInstant nextStatusChange = TInstant::Max();
- const TInstant now = TActivationContext::Now();
- for (auto& [id, vdisk] : VDisks) {
- nextStatusChange = Min(nextStatusChange, vdisk->HandleStatusChange(now));
- vdisk->Report(&ev->Record);
- }
- NTabletPipe::SendData(SelfId(), PipeClient, ev.release());
- if (nextStatusChange != TInstant::Max()) {
- Schedule(nextStatusChange - now, new TEvUpdateDriveStatus);
- }
- }
- }
-
- STRICT_STFUNC(StateFunc, {
- hFunc(TEvCheckState, Handle);
- hFunc(TEvTabletPipe::TEvClientConnected, Handle);
- hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
- hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
- cFunc(EvUpdateDriveStatus, UpdateDriveStatus);
- cFunc(TEvents::TSystem::Wakeup, Connect);
- })
-};
+ } else if (const auto it = VDisks.find(id); it != VDisks.end()) {
+ it->second->StopActor();
+ VDisks.erase(it);
+ } else {
+ UNIT_ASSERT(false);
+ }
+ }
+
+ UpdateDriveStatus();
+ }
+
+ void UpdateDriveStatus() {
+ if (Connected) {
+ auto ev = std::make_unique<TEvBlobStorage::TEvControllerUpdateDiskStatus>();
+ TInstant nextStatusChange = TInstant::Max();
+ const TInstant now = TActivationContext::Now();
+ for (auto& [id, vdisk] : VDisks) {
+ nextStatusChange = Min(nextStatusChange, vdisk->HandleStatusChange(now));
+ vdisk->Report(&ev->Record);
+ }
+ NTabletPipe::SendData(SelfId(), PipeClient, ev.release());
+ if (nextStatusChange != TInstant::Max()) {
+ Schedule(nextStatusChange - now, new TEvUpdateDriveStatus);
+ }
+ }
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ hFunc(TEvCheckState, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, Handle);
+ hFunc(TEvTabletPipe::TEvClientDestroyed, Handle);
+ hFunc(TEvBlobStorage::TEvControllerNodeServiceSetUpdate, Handle);
+ cFunc(EvUpdateDriveStatus, UpdateDriveStatus);
+ cFunc(TEvents::TSystem::Wakeup, Connect);
+ })
+};
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/self_heal_actor_ut.cpp b/ydb/core/mind/bscontroller/ut_selfheal/self_heal_actor_ut.cpp
index 5c2d0aad201..38a082a1d93 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/self_heal_actor_ut.cpp
+++ b/ydb/core/mind/bscontroller/ut_selfheal/self_heal_actor_ut.cpp
@@ -1,110 +1,110 @@
-#include <library/cpp/testing/unittest/registar.h>
+#include <library/cpp/testing/unittest/registar.h>
#include <ydb/core/util/testactorsys.h>
#include <ydb/core/mind/bscontroller/self_heal.h>
-
-using namespace NActors;
-using namespace NKikimr;
-using namespace NKikimr::NBsController;
-
-using E = NKikimrBlobStorage::EVDiskStatus;
-
-template<typename TCallback>
-void RunTestCase(TCallback&& callback) {
- TTestActorSystem runtime(1);
- runtime.Start();
- const TActorId& parentId = runtime.AllocateEdgeActor(1);
- std::shared_ptr<std::atomic_uint64_t> UnreassignableGroups = std::make_shared<std::atomic_uint64_t>();
- const TActorId& selfHealId = runtime.Register(CreateSelfHealActor(1, UnreassignableGroups), parentId, {}, {}, 1);
- callback(selfHealId, parentId, runtime);
- runtime.Stop();
-}
-
-class TVDiskResponder : public TActor<TVDiskResponder> {
-public:
- TVDiskResponder()
- : TActor(&TThis::StateFunc)
- {}
-
- void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
- Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::OK,
- VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()), true, true, 1));
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvBlobStorage::TEvVStatus, Handle);
- )
-};
-
-void RegisterDiskResponders(TTestActorSystem& runtime, const TIntrusivePtr<TBlobStorageGroupInfo>& info) {
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- runtime.RegisterService(info->GetActorId(i), runtime.Register(new TVDiskResponder, 1));
- }
-}
-
-TIntrusivePtr<TBlobStorageGroupInfo> CreateGroup() {
- TVector<TActorId> actorIds;
- for (ui32 i = 0; i < 8; ++i) {
- actorIds.push_back(MakeBlobStorageVDiskID(1, 1000 + i, 1000));
- }
- return MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block, 1u, 0u, 1u, &actorIds);
-}
-
-TEvControllerUpdateSelfHealInfo::TGroupContent Convert(const TIntrusivePtr<TBlobStorageGroupInfo>& info,
- std::set<ui32> faultyIndexes, std::vector<E> status) {
- TEvControllerUpdateSelfHealInfo::TGroupContent res;
- res.Generation = info->GroupGeneration;
- res.Type = info->Type;
- for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
- auto& x = res.VDisks[info->GetVDiskId(i)];
- x.Location = {1, 1000 + i, 1000};
- x.Faulty = faultyIndexes.count(i);
- x.VDiskStatus = i < status.size() ? status[i] : E::READY;
- }
- return res;
-}
-
-void ValidateCmd(const TActorId& parentId, TTestActorSystem& runtime, ui32 groupId, ui32 groupGeneration,
- ui32 failRealmIdx, ui32 failDomainIdx, ui32 vdiskIdx) {
- auto res = runtime.WaitForEdgeActorEvent({parentId});
- auto *m = res->Get<TEvBlobStorage::TEvControllerConfigRequest>();
- UNIT_ASSERT(m->SelfHeal);
- auto& record = m->Record;
- auto& request = record.GetRequest();
- UNIT_ASSERT_VALUES_EQUAL(request.CommandSize(), 1);
- auto& cmd = request.GetCommand(0);
- UNIT_ASSERT(cmd.HasReassignGroupDisk());
- auto& reassign = cmd.GetReassignGroupDisk();
- UNIT_ASSERT_VALUES_EQUAL(reassign.GetGroupId(), groupId);
- UNIT_ASSERT_VALUES_EQUAL(reassign.GetGroupGeneration(), groupGeneration);
- UNIT_ASSERT_VALUES_EQUAL(reassign.GetFailRealmIdx(), failRealmIdx);
- UNIT_ASSERT_VALUES_EQUAL(reassign.GetFailDomainIdx(), failDomainIdx);
- UNIT_ASSERT_VALUES_EQUAL(reassign.GetVDiskIdx(), vdiskIdx);
-}
-
-Y_UNIT_TEST_SUITE(SelfHealActorTest) {
-
- Y_UNIT_TEST(SingleErrorDisk) {
- RunTestCase([&](const TActorId& selfHealId, const TActorId& parentId, TTestActorSystem& runtime) {
- auto info = CreateGroup();
- RegisterDiskResponders(runtime, info);
- auto ev = std::make_unique<TEvControllerUpdateSelfHealInfo>();
- ev->GroupsToUpdate[info->GroupID] = Convert(info, {0}, {E::ERROR});
- runtime.Send(new IEventHandle(selfHealId, parentId, ev.release()), 1);
- ValidateCmd(parentId, runtime, 0, 1, 0, 0, 0);
- });
- }
-
- Y_UNIT_TEST(NoMoreThanOneReplicating) {
- RunTestCase([&](const TActorId& selfHealId, const TActorId& parentId, TTestActorSystem& runtime) {
- auto info = CreateGroup();
- RegisterDiskResponders(runtime, info);
- auto ev = std::make_unique<TEvControllerUpdateSelfHealInfo>();
- ev->GroupsToUpdate[info->GroupID] = Convert(info, {0}, {E::ERROR, E::REPLICATING});
- runtime.Send(new IEventHandle(selfHealId, parentId, ev.release()), 1);
- runtime.Schedule(TDuration::Minutes(30), new IEventHandle(TEvents::TSystem::Wakeup, 0, parentId, {}, nullptr, 0), nullptr, 1);
- auto res = runtime.WaitForEdgeActorEvent({parentId});
- UNIT_ASSERT_EQUAL(res->GetTypeRewrite(), TEvents::TSystem::Wakeup);
- });
- }
-
-}
+
+using namespace NActors;
+using namespace NKikimr;
+using namespace NKikimr::NBsController;
+
+using E = NKikimrBlobStorage::EVDiskStatus;
+
+template<typename TCallback>
+void RunTestCase(TCallback&& callback) {
+ TTestActorSystem runtime(1);
+ runtime.Start();
+ const TActorId& parentId = runtime.AllocateEdgeActor(1);
+ std::shared_ptr<std::atomic_uint64_t> UnreassignableGroups = std::make_shared<std::atomic_uint64_t>();
+ const TActorId& selfHealId = runtime.Register(CreateSelfHealActor(1, UnreassignableGroups), parentId, {}, {}, 1);
+ callback(selfHealId, parentId, runtime);
+ runtime.Stop();
+}
+
+class TVDiskResponder : public TActor<TVDiskResponder> {
+public:
+ TVDiskResponder()
+ : TActor(&TThis::StateFunc)
+ {}
+
+ void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
+ Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::OK,
+ VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskID()), true, true, 1));
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvBlobStorage::TEvVStatus, Handle);
+ )
+};
+
+void RegisterDiskResponders(TTestActorSystem& runtime, const TIntrusivePtr<TBlobStorageGroupInfo>& info) {
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ runtime.RegisterService(info->GetActorId(i), runtime.Register(new TVDiskResponder, 1));
+ }
+}
+
+TIntrusivePtr<TBlobStorageGroupInfo> CreateGroup() {
+ TVector<TActorId> actorIds;
+ for (ui32 i = 0; i < 8; ++i) {
+ actorIds.push_back(MakeBlobStorageVDiskID(1, 1000 + i, 1000));
+ }
+ return MakeIntrusive<TBlobStorageGroupInfo>(TBlobStorageGroupType::Erasure4Plus2Block, 1u, 0u, 1u, &actorIds);
+}
+
+TEvControllerUpdateSelfHealInfo::TGroupContent Convert(const TIntrusivePtr<TBlobStorageGroupInfo>& info,
+ std::set<ui32> faultyIndexes, std::vector<E> status) {
+ TEvControllerUpdateSelfHealInfo::TGroupContent res;
+ res.Generation = info->GroupGeneration;
+ res.Type = info->Type;
+ for (ui32 i = 0; i < info->GetTotalVDisksNum(); ++i) {
+ auto& x = res.VDisks[info->GetVDiskId(i)];
+ x.Location = {1, 1000 + i, 1000};
+ x.Faulty = faultyIndexes.count(i);
+ x.VDiskStatus = i < status.size() ? status[i] : E::READY;
+ }
+ return res;
+}
+
+void ValidateCmd(const TActorId& parentId, TTestActorSystem& runtime, ui32 groupId, ui32 groupGeneration,
+ ui32 failRealmIdx, ui32 failDomainIdx, ui32 vdiskIdx) {
+ auto res = runtime.WaitForEdgeActorEvent({parentId});
+ auto *m = res->Get<TEvBlobStorage::TEvControllerConfigRequest>();
+ UNIT_ASSERT(m->SelfHeal);
+ auto& record = m->Record;
+ auto& request = record.GetRequest();
+ UNIT_ASSERT_VALUES_EQUAL(request.CommandSize(), 1);
+ auto& cmd = request.GetCommand(0);
+ UNIT_ASSERT(cmd.HasReassignGroupDisk());
+ auto& reassign = cmd.GetReassignGroupDisk();
+ UNIT_ASSERT_VALUES_EQUAL(reassign.GetGroupId(), groupId);
+ UNIT_ASSERT_VALUES_EQUAL(reassign.GetGroupGeneration(), groupGeneration);
+ UNIT_ASSERT_VALUES_EQUAL(reassign.GetFailRealmIdx(), failRealmIdx);
+ UNIT_ASSERT_VALUES_EQUAL(reassign.GetFailDomainIdx(), failDomainIdx);
+ UNIT_ASSERT_VALUES_EQUAL(reassign.GetVDiskIdx(), vdiskIdx);
+}
+
+Y_UNIT_TEST_SUITE(SelfHealActorTest) {
+
+ Y_UNIT_TEST(SingleErrorDisk) {
+ RunTestCase([&](const TActorId& selfHealId, const TActorId& parentId, TTestActorSystem& runtime) {
+ auto info = CreateGroup();
+ RegisterDiskResponders(runtime, info);
+ auto ev = std::make_unique<TEvControllerUpdateSelfHealInfo>();
+ ev->GroupsToUpdate[info->GroupID] = Convert(info, {0}, {E::ERROR});
+ runtime.Send(new IEventHandle(selfHealId, parentId, ev.release()), 1);
+ ValidateCmd(parentId, runtime, 0, 1, 0, 0, 0);
+ });
+ }
+
+ Y_UNIT_TEST(NoMoreThanOneReplicating) {
+ RunTestCase([&](const TActorId& selfHealId, const TActorId& parentId, TTestActorSystem& runtime) {
+ auto info = CreateGroup();
+ RegisterDiskResponders(runtime, info);
+ auto ev = std::make_unique<TEvControllerUpdateSelfHealInfo>();
+ ev->GroupsToUpdate[info->GroupID] = Convert(info, {0}, {E::ERROR, E::REPLICATING});
+ runtime.Send(new IEventHandle(selfHealId, parentId, ev.release()), 1);
+ runtime.Schedule(TDuration::Minutes(30), new IEventHandle(TEvents::TSystem::Wakeup, 0, parentId, {}, nullptr, 0), nullptr, 1);
+ auto res = runtime.WaitForEdgeActorEvent({parentId});
+ UNIT_ASSERT_EQUAL(res->GetTypeRewrite(), TEvents::TSystem::Wakeup);
+ });
+ }
+
+}
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/timer_actor.h b/ydb/core/mind/bscontroller/ut_selfheal/timer_actor.h
index 2bbf215c7a1..33f79b59d2f 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/timer_actor.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/timer_actor.h
@@ -1,45 +1,45 @@
-#pragma once
-
-#include "defs.h"
-
-#include "events.h"
-
-struct TEvArmTimer : TEventLocal<TEvArmTimer, EvArmTimer> {
- const TDuration Timeout;
-
- TEvArmTimer(TDuration timeout)
- : Timeout(timeout)
- {}
-};
-
-struct TEvTimer : TEventLocal<TEvTimer, EvTimer> {
- std::unique_ptr<IEventHandle> HitEvent;
-
- TEvTimer(const IEventHandle& ev)
+#pragma once
+
+#include "defs.h"
+
+#include "events.h"
+
+struct TEvArmTimer : TEventLocal<TEvArmTimer, EvArmTimer> {
+ const TDuration Timeout;
+
+ TEvArmTimer(TDuration timeout)
+ : Timeout(timeout)
+ {}
+};
+
+struct TEvTimer : TEventLocal<TEvTimer, EvTimer> {
+ std::unique_ptr<IEventHandle> HitEvent;
+
+ TEvTimer(const IEventHandle& ev)
: HitEvent(new IEventHandle(TEvents::TSystem::Wakeup, 0, ev.Sender, TActorId(), {}, ev.Cookie))
- {}
-
- void Hit() {
- TActivationContext::Send(HitEvent.release());
- }
-};
-
-class TTimerActor : public TActor<TTimerActor> {
-public:
- TTimerActor()
- : TActor(&TThis::StateFunc)
- {}
-
- void Handle(TEvArmTimer::TPtr ev) {
- Schedule(ev->Get()->Timeout, new TEvTimer(*ev));
- }
-
- void Handle(TEvTimer::TPtr ev) {
- ev->Get()->Hit();
- }
-
- STRICT_STFUNC(StateFunc, {
- hFunc(TEvArmTimer, Handle);
- hFunc(TEvTimer, Handle);
- })
-};
+ {}
+
+ void Hit() {
+ TActivationContext::Send(HitEvent.release());
+ }
+};
+
+class TTimerActor : public TActor<TTimerActor> {
+public:
+ TTimerActor()
+ : TActor(&TThis::StateFunc)
+ {}
+
+ void Handle(TEvArmTimer::TPtr ev) {
+ Schedule(ev->Get()->Timeout, new TEvTimer(*ev));
+ }
+
+ void Handle(TEvTimer::TPtr ev) {
+ ev->Get()->Hit();
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ hFunc(TEvArmTimer, Handle);
+ hFunc(TEvTimer, Handle);
+ })
+};
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/vdisk_mock.h b/ydb/core/mind/bscontroller/ut_selfheal/vdisk_mock.h
index dddd4728ac1..97639ee30e4 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/vdisk_mock.h
+++ b/ydb/core/mind/bscontroller/ut_selfheal/vdisk_mock.h
@@ -1,122 +1,122 @@
-#pragma once
-
-#include "defs.h"
-
-#include "events.h"
-
-class TVDisk : TNonCopyable {
- TVDiskID VDiskId;
- const ui32 NodeId;
- const ui32 PDiskId;
- const ui32 VSlotId;
- const ui64 PDiskGuid;
- NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::INIT_PENDING;
- std::optional<NKikimrBlobStorage::EVDiskStatus> ReportedStatus;
- TInstant NextStatusChange = TInstant::Zero();
-
-private:
- class TVDiskMockActor : public TActor<TVDiskMockActor> {
- TVDisk& Self;
-
- public:
- TVDiskMockActor(TVDisk& self)
- : TActor(&TThis::StateFunc)
- , Self(self)
- {
- Y_UNUSED(Self);
- }
-
- void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
- Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::OK, Self.VDiskId,
- Self.Status >= NKikimrBlobStorage::REPLICATING, Self.Status >= NKikimrBlobStorage::READY, 0));
- }
-
- STRICT_STFUNC(StateFunc, {
- cFunc(TEvents::TSystem::Poison, PassAway);
- hFunc(TEvBlobStorage::TEvVStatus, Handle);
- })
- };
-
-public:
- TVDisk(const TVDiskID& vdiskId, ui32 nodeId, ui32 pdiskId, ui32 vslotId, ui64 pdiskGuid)
- : VDiskId(vdiskId)
- , NodeId(nodeId)
- , PDiskId(pdiskId)
- , VSlotId(vslotId)
- , PDiskGuid(pdiskGuid)
- {
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s PDiskId# %u VSlotId# %u created",
- NodeId, VDiskId.ToString().data(), PDiskId, VSlotId);
- auto *actorSystem = TActivationContext::ActorSystem();
- actorSystem->RegisterLocalService(GetActorId(), actorSystem->Register(new TVDiskMockActor(*this)));
- }
-
- void StopActor() {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, GetActorId(), {}, {}, 0));
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s destroyed", NodeId, VDiskId.ToString().data());
- }
-
- void UpdateVDiskId(const TVDiskID& newVDiskId) {
- if (VDiskId != newVDiskId) {
- UNIT_ASSERT_VALUES_EQUAL(VDiskId.GroupID, newVDiskId.GroupID);
- UNIT_ASSERT_VALUES_EQUAL(VDiskId.FailRealm, newVDiskId.FailRealm);
- UNIT_ASSERT_VALUES_EQUAL(VDiskId.FailDomain, newVDiskId.FailDomain);
- UNIT_ASSERT_VALUES_EQUAL(VDiskId.VDisk, newVDiskId.VDisk);
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s -> %s",
- NodeId, VDiskId.ToString().data(), newVDiskId.ToString().data());
- VDiskId = newVDiskId;
- }
- }
-
+#pragma once
+
+#include "defs.h"
+
+#include "events.h"
+
+class TVDisk : TNonCopyable {
+ TVDiskID VDiskId;
+ const ui32 NodeId;
+ const ui32 PDiskId;
+ const ui32 VSlotId;
+ const ui64 PDiskGuid;
+ NKikimrBlobStorage::EVDiskStatus Status = NKikimrBlobStorage::INIT_PENDING;
+ std::optional<NKikimrBlobStorage::EVDiskStatus> ReportedStatus;
+ TInstant NextStatusChange = TInstant::Zero();
+
+private:
+ class TVDiskMockActor : public TActor<TVDiskMockActor> {
+ TVDisk& Self;
+
+ public:
+ TVDiskMockActor(TVDisk& self)
+ : TActor(&TThis::StateFunc)
+ , Self(self)
+ {
+ Y_UNUSED(Self);
+ }
+
+ void Handle(TEvBlobStorage::TEvVStatus::TPtr ev) {
+ Send(ev->Sender, new TEvBlobStorage::TEvVStatusResult(NKikimrProto::OK, Self.VDiskId,
+ Self.Status >= NKikimrBlobStorage::REPLICATING, Self.Status >= NKikimrBlobStorage::READY, 0));
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ hFunc(TEvBlobStorage::TEvVStatus, Handle);
+ })
+ };
+
+public:
+ TVDisk(const TVDiskID& vdiskId, ui32 nodeId, ui32 pdiskId, ui32 vslotId, ui64 pdiskGuid)
+ : VDiskId(vdiskId)
+ , NodeId(nodeId)
+ , PDiskId(pdiskId)
+ , VSlotId(vslotId)
+ , PDiskGuid(pdiskGuid)
+ {
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s PDiskId# %u VSlotId# %u created",
+ NodeId, VDiskId.ToString().data(), PDiskId, VSlotId);
+ auto *actorSystem = TActivationContext::ActorSystem();
+ actorSystem->RegisterLocalService(GetActorId(), actorSystem->Register(new TVDiskMockActor(*this)));
+ }
+
+ void StopActor() {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, GetActorId(), {}, {}, 0));
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s destroyed", NodeId, VDiskId.ToString().data());
+ }
+
+ void UpdateVDiskId(const TVDiskID& newVDiskId) {
+ if (VDiskId != newVDiskId) {
+ UNIT_ASSERT_VALUES_EQUAL(VDiskId.GroupID, newVDiskId.GroupID);
+ UNIT_ASSERT_VALUES_EQUAL(VDiskId.FailRealm, newVDiskId.FailRealm);
+ UNIT_ASSERT_VALUES_EQUAL(VDiskId.FailDomain, newVDiskId.FailDomain);
+ UNIT_ASSERT_VALUES_EQUAL(VDiskId.VDisk, newVDiskId.VDisk);
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s -> %s",
+ NodeId, VDiskId.ToString().data(), newVDiskId.ToString().data());
+ VDiskId = newVDiskId;
+ }
+ }
+
TActorId GetActorId() const {
- return MakeBlobStorageVDiskID(NodeId, PDiskId, VSlotId);
- }
-
- void Serialize(NKikimrBlobStorage::TVDiskStatus *pb) const {
- VDiskIDFromVDiskID(VDiskId, pb->MutableVDiskId());
- pb->SetNodeId(NodeId);
- pb->SetPDiskId(PDiskId);
- pb->SetVSlotId(VSlotId);
- pb->SetPDiskGuid(PDiskGuid);
- pb->SetStatus(Status);
- }
-
- TInstant HandleStatusChange(const TInstant now) {
- if (now >= NextStatusChange) {
- const TDuration duration = OnStatusChange();
- LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s status changed to %s",
- NodeId, VDiskId.ToString().data(), EVDiskStatus_Name(Status).data());
- NextStatusChange = duration != TDuration::Max() ? now + duration : TInstant::Max();
- }
- return NextStatusChange;
- }
-
- TDuration OnStatusChange() {
- switch (Status) {
- case NKikimrBlobStorage::INIT_PENDING:
- if (NextStatusChange == TInstant::Zero()) {
- return TDuration::MilliSeconds(1000 + RandomNumber(5000u));
- } else {
- Status = NKikimrBlobStorage::REPLICATING;
- return TDuration::MilliSeconds(5000 + RandomNumber(30000u));
- }
-
- case NKikimrBlobStorage::REPLICATING:
- Status = NKikimrBlobStorage::READY;
-
- case NKikimrBlobStorage::READY:
- return TDuration::Max();
-
- case NKikimrBlobStorage::ERROR:
- break;
- }
-
- Y_FAIL();
- }
-
- void Report(NKikimrBlobStorage::TEvControllerUpdateDiskStatus *pb) {
- if (std::exchange(ReportedStatus, Status) != Status) {
- Serialize(pb->AddVDiskStatus());
- }
- }
-};
+ return MakeBlobStorageVDiskID(NodeId, PDiskId, VSlotId);
+ }
+
+ void Serialize(NKikimrBlobStorage::TVDiskStatus *pb) const {
+ VDiskIDFromVDiskID(VDiskId, pb->MutableVDiskId());
+ pb->SetNodeId(NodeId);
+ pb->SetPDiskId(PDiskId);
+ pb->SetVSlotId(VSlotId);
+ pb->SetPDiskGuid(PDiskGuid);
+ pb->SetStatus(Status);
+ }
+
+ TInstant HandleStatusChange(const TInstant now) {
+ if (now >= NextStatusChange) {
+ const TDuration duration = OnStatusChange();
+ LOG_DEBUG(*TlsActivationContext, NKikimrServices::BS_NODE, "[%u] VDiskId# %s status changed to %s",
+ NodeId, VDiskId.ToString().data(), EVDiskStatus_Name(Status).data());
+ NextStatusChange = duration != TDuration::Max() ? now + duration : TInstant::Max();
+ }
+ return NextStatusChange;
+ }
+
+ TDuration OnStatusChange() {
+ switch (Status) {
+ case NKikimrBlobStorage::INIT_PENDING:
+ if (NextStatusChange == TInstant::Zero()) {
+ return TDuration::MilliSeconds(1000 + RandomNumber(5000u));
+ } else {
+ Status = NKikimrBlobStorage::REPLICATING;
+ return TDuration::MilliSeconds(5000 + RandomNumber(30000u));
+ }
+
+ case NKikimrBlobStorage::REPLICATING:
+ Status = NKikimrBlobStorage::READY;
+
+ case NKikimrBlobStorage::READY:
+ return TDuration::Max();
+
+ case NKikimrBlobStorage::ERROR:
+ break;
+ }
+
+ Y_FAIL();
+ }
+
+ void Report(NKikimrBlobStorage::TEvControllerUpdateDiskStatus *pb) {
+ if (std::exchange(ReportedStatus, Status) != Status) {
+ Serialize(pb->AddVDiskStatus());
+ }
+ }
+};
diff --git a/ydb/core/mind/bscontroller/ut_selfheal/ya.make b/ydb/core/mind/bscontroller/ut_selfheal/ya.make
index 7bebb4b1c13..e629bf224f7 100644
--- a/ydb/core/mind/bscontroller/ut_selfheal/ya.make
+++ b/ydb/core/mind/bscontroller/ut_selfheal/ya.make
@@ -1,30 +1,30 @@
-UNITTEST()
-
-FORK_SUBTESTS()
-
-SIZE(MEDIUM)
-
+UNITTEST()
+
+FORK_SUBTESTS()
+
+SIZE(MEDIUM)
+
OWNER(alexvru)
-
-SRCS(
- main.cpp
- self_heal_actor_ut.cpp
- defs.h
- env.h
- events.h
- node_warden_mock.h
- timer_actor.h
- vdisk_mock.h
-)
-
-PEERDIR(
+
+SRCS(
+ main.cpp
+ self_heal_actor_ut.cpp
+ defs.h
+ env.h
+ events.h
+ node_warden_mock.h
+ timer_actor.h
+ vdisk_mock.h
+)
+
+PEERDIR(
ydb/core/blobstorage/dsproxy/mock
ydb/core/blobstorage/pdisk/mock
ydb/core/mind/bscontroller
ydb/core/tx/scheme_board
ydb/library/yql/public/udf/service/stub
-)
-
-YQL_LAST_ABI_VERSION()
+)
+
+YQL_LAST_ABI_VERSION()
-END()
+END()
diff --git a/ydb/core/mind/bscontroller/vdisk_status_tracker.h b/ydb/core/mind/bscontroller/vdisk_status_tracker.h
index 35d626ed152..a7b0240f448 100644
--- a/ydb/core/mind/bscontroller/vdisk_status_tracker.h
+++ b/ydb/core/mind/bscontroller/vdisk_status_tracker.h
@@ -1,29 +1,29 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NBsController {
-
- class TVDiskStatusTracker {
- NKikimrBlobStorage::EVDiskStatus Status;
- TInstant SwitchTime = TInstant::Max();
- const TDuration Threshold;
-
- public:
- TVDiskStatusTracker(TDuration threshold = TDuration::Seconds(60))
- : Threshold(threshold)
- {}
-
- void Update(NKikimrBlobStorage::EVDiskStatus status, TInstant now) {
- if (SwitchTime == TInstant::Max() || status != Status) {
- Status = status;
- SwitchTime = now;
- }
- }
-
- std::optional<NKikimrBlobStorage::EVDiskStatus> GetStatus(TInstant now) const {
- return SwitchTime <= now - Threshold ? std::make_optional(Status) : std::nullopt;
- }
- };
-
-} // NKikimr::NBsController
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NBsController {
+
+ class TVDiskStatusTracker {
+ NKikimrBlobStorage::EVDiskStatus Status;
+ TInstant SwitchTime = TInstant::Max();
+ const TDuration Threshold;
+
+ public:
+ TVDiskStatusTracker(TDuration threshold = TDuration::Seconds(60))
+ : Threshold(threshold)
+ {}
+
+ void Update(NKikimrBlobStorage::EVDiskStatus status, TInstant now) {
+ if (SwitchTime == TInstant::Max() || status != Status) {
+ Status = status;
+ SwitchTime = now;
+ }
+ }
+
+ std::optional<NKikimrBlobStorage::EVDiskStatus> GetStatus(TInstant now) const {
+ return SwitchTime <= now - Threshold ? std::make_optional(Status) : std::nullopt;
+ }
+ };
+
+} // NKikimr::NBsController
diff --git a/ydb/core/mind/bscontroller/ya.make b/ydb/core/mind/bscontroller/ya.make
index 275a4dc2385..ad9d2daafdd 100644
--- a/ydb/core/mind/bscontroller/ya.make
+++ b/ydb/core/mind/bscontroller/ya.make
@@ -1,66 +1,66 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(
alexvru
g:kikimr
)
-
-SRCS(
- bsc.cpp
- bsc.h
- cmds_box.cpp
- cmds_drive_status.cpp
- cmds_host_config.cpp
- cmds_storage_pool.cpp
- config_cmd.cpp
- config.cpp
- config_fit_groups.cpp
- config_fit_pdisks.cpp
- config.h
- defs.h
- diff.h
- disk_metrics.cpp
- drop_donor.cpp
- error.h
- get_group.cpp
- grouper.cpp
- grouper.h
- group_mapper.cpp
- group_mapper.h
- group_reconfigure_wipe.cpp
- impl.h
- indir.h
- init_scheme.cpp
- load_everything.cpp
- migrate.cpp
- monitoring.cpp
- mood.h
- mv_object_map.h
- node_report.cpp
+
+SRCS(
+ bsc.cpp
+ bsc.h
+ cmds_box.cpp
+ cmds_drive_status.cpp
+ cmds_host_config.cpp
+ cmds_storage_pool.cpp
+ config_cmd.cpp
+ config.cpp
+ config_fit_groups.cpp
+ config_fit_pdisks.cpp
+ config.h
+ defs.h
+ diff.h
+ disk_metrics.cpp
+ drop_donor.cpp
+ error.h
+ get_group.cpp
+ grouper.cpp
+ grouper.h
+ group_mapper.cpp
+ group_mapper.h
+ group_reconfigure_wipe.cpp
+ impl.h
+ indir.h
+ init_scheme.cpp
+ load_everything.cpp
+ migrate.cpp
+ monitoring.cpp
+ mood.h
+ mv_object_map.h
+ node_report.cpp
propose_group_key.cpp
- register_node.cpp
- request_controller_info.cpp
- resources.h
- scheme.h
- scrub.cpp
- select_groups.cpp
- select_groups.h
- self_heal.cpp
- self_heal.h
- stat_processor.cpp
- stat_processor.h
- storage_pool_stat.h
+ register_node.cpp
+ request_controller_info.cpp
+ resources.h
+ scheme.h
+ scrub.cpp
+ select_groups.cpp
+ select_groups.h
+ self_heal.cpp
+ self_heal.h
+ stat_processor.cpp
+ stat_processor.h
+ storage_pool_stat.h
sys_view.cpp
sys_view.h
- table_merger.h
- types.h
- update_group_latencies.cpp
- update_last_seen_ready.cpp
- update_seen_operational.cpp
- vdisk_status_tracker.h
-)
-
-PEERDIR(
+ table_merger.h
+ types.h
+ update_group_latencies.cpp
+ update_last_seen_ready.cpp
+ update_seen_operational.cpp
+ vdisk_status_tracker.h
+)
+
+PEERDIR(
library/cpp/actors/core
ydb/core/base
ydb/core/base/services
@@ -72,9 +72,9 @@ PEERDIR(
ydb/core/sys_view/common
ydb/core/tablet
ydb/core/tablet_flat
-)
-
-END()
+)
+
+END()
RECURSE_FOR_TESTS(
ut
diff --git a/ydb/core/mind/configured_tablet_bootstrapper.cpp b/ydb/core/mind/configured_tablet_bootstrapper.cpp
index 008acd2b400..6dea4f4f452 100644
--- a/ydb/core/mind/configured_tablet_bootstrapper.cpp
+++ b/ydb/core/mind/configured_tablet_bootstrapper.cpp
@@ -214,9 +214,9 @@ TIntrusivePtr<TTabletSetupInfo> MakeTabletSetupInfo(
case TTabletTypes::SysViewProcessor:
createFunc = &NSysView::CreateSysViewProcessor;
break;
- case TTabletTypes::TestShard:
- createFunc = &NTestShard::CreateTestShard;
- break;
+ case TTabletTypes::TestShard:
+ createFunc = &NTestShard::CreateTestShard;
+ break;
case TTabletTypes::SequenceShard:
createFunc = &NSequenceShard::CreateSequenceShard;
break;
diff --git a/ydb/core/mind/defs.h b/ydb/core/mind/defs.h
index a746b59cd37..1f533163fb1 100644
--- a/ydb/core/mind/defs.h
+++ b/ydb/core/mind/defs.h
@@ -5,11 +5,11 @@
namespace NKikimr {
- // ensure that the type of passed variable is the same as given one
- template<typename T, typename U>
- inline T EnsureType(U &&value) {
- static_assert(std::is_same<T, U>::value, "unexpected returned value type");
- return std::move(value);
- }
-
+ // ensure that the type of passed variable is the same as given one
+ template<typename T, typename U>
+ inline T EnsureType(U &&value) {
+ static_assert(std::is_same<T, U>::value, "unexpected returned value type");
+ return std::move(value);
+ }
+
}
diff --git a/ydb/core/mind/dynamic_nameserver.cpp b/ydb/core/mind/dynamic_nameserver.cpp
index 6f4f147982a..d1a784904cc 100644
--- a/ydb/core/mind/dynamic_nameserver.cpp
+++ b/ydb/core/mind/dynamic_nameserver.cpp
@@ -7,7 +7,7 @@
namespace NKikimr {
namespace NNodeBroker {
-static void ResetInterconnectProxyConfig(ui32 nodeId, const TActorContext &ctx)
+static void ResetInterconnectProxyConfig(ui32 nodeId, const TActorContext &ctx)
{
auto aid = TActivationContext::InterconnectProxy(nodeId);
if (!aid)
@@ -40,9 +40,9 @@ void TDynamicNodeResolverBase::Bootstrap(const TActorContext &ctx)
NTabletPipe::SendData(ctx, NodeBrokerPipe, request.Release());
Become(&TDynamicNodeResolverBase::StateWork);
- if (Deadline != TInstant::Max()) {
- Schedule(Deadline, new TEvents::TEvWakeup);
- }
+ if (Deadline != TInstant::Max()) {
+ Schedule(Deadline, new TEvents::TEvWakeup);
+ }
}
void TDynamicNodeResolverBase::Die(const TActorContext &ctx)
@@ -173,7 +173,7 @@ void TDynamicNameserver::RequestEpochUpdate(ui32 domain,
EpochUpdates[domain] = epoch;
}
-void TDynamicNameserver::ResolveStaticNode(ui32 nodeId, TActorId sender, TInstant deadline, const TActorContext &ctx)
+void TDynamicNameserver::ResolveStaticNode(ui32 nodeId, TActorId sender, TInstant deadline, const TActorContext &ctx)
{
auto it = StaticConfig->StaticNodeTable.find(nodeId);
@@ -189,8 +189,8 @@ void TDynamicNameserver::ResolveStaticNode(ui32 nodeId, TActorId sender, TInstan
void TDynamicNameserver::ResolveDynamicNode(ui32 nodeId,
TAutoPtr<IEventHandle> ev,
- TInstant deadline,
- const TActorContext &ctx)
+ TInstant deadline,
+ const TActorContext &ctx)
{
ui32 domain = NodeIdToDomain(nodeId, *AppData(ctx)->DomainsInfo);
auto it = DynamicConfigs[domain]->DynamicNodes.find(nodeId);
@@ -209,7 +209,7 @@ void TDynamicNameserver::ResolveDynamicNode(ui32 nodeId,
}
}
-void TDynamicNameserver::SendNodesList(const TActorContext &ctx)
+void TDynamicNameserver::SendNodesList(const TActorContext &ctx)
{
auto now = ctx.Now();
for (auto &sender : ListNodesQueue) {
@@ -234,7 +234,7 @@ void TDynamicNameserver::SendNodesList(const TActorContext &ctx)
ListNodesQueue.clear();
}
-void TDynamicNameserver::PendingRequestAnswered(ui32 domain, const TActorContext &ctx)
+void TDynamicNameserver::PendingRequestAnswered(ui32 domain, const TActorContext &ctx)
{
PendingRequests.Reset(domain);
if (PendingRequests.Empty())
@@ -312,17 +312,17 @@ void TDynamicNameserver::OnPipeDestroyed(ui32 domain,
}
void TDynamicNameserver::Handle(TEvInterconnect::TEvResolveNode::TPtr &ev,
- const TActorContext &ctx)
+ const TActorContext &ctx)
{
- auto& record = ev->Get()->Record;
- const ui32 nodeId = record.GetNodeId();
- const TInstant deadline = record.HasDeadline() ? TInstant::FromValue(record.GetDeadline()) : TInstant::Max();
+ auto& record = ev->Get()->Record;
+ const ui32 nodeId = record.GetNodeId();
+ const TInstant deadline = record.HasDeadline() ? TInstant::FromValue(record.GetDeadline()) : TInstant::Max();
auto config = AppData(ctx)->DynamicNameserviceConfig;
if (!config || nodeId <= config->MaxStaticNodeId)
- ResolveStaticNode(nodeId, ev->Sender, deadline, ctx);
+ ResolveStaticNode(nodeId, ev->Sender, deadline, ctx);
else
- ResolveDynamicNode(nodeId, ev.Release(), deadline, ctx);
+ ResolveDynamicNode(nodeId, ev.Release(), deadline, ctx);
}
void TDynamicNameserver::Handle(TEvResolveAddress::TPtr &ev, const TActorContext &ctx) {
@@ -334,7 +334,7 @@ void TDynamicNameserver::Handle(TEvResolveAddress::TPtr &ev, const TActorContext
}
void TDynamicNameserver::Handle(TEvInterconnect::TEvListNodes::TPtr &ev,
- const TActorContext &ctx)
+ const TActorContext &ctx)
{
if (ListNodesQueue.empty()) {
auto dinfo = AppData(ctx)->DomainsInfo;
@@ -353,7 +353,7 @@ void TDynamicNameserver::Handle(TEvInterconnect::TEvListNodes::TPtr &ev,
ListNodesQueue.push_back(ev->Sender);
}
-void TDynamicNameserver::Handle(TEvInterconnect::TEvGetNode::TPtr &ev, const TActorContext &ctx)
+void TDynamicNameserver::Handle(TEvInterconnect::TEvGetNode::TPtr &ev, const TActorContext &ctx)
{
ui32 nodeId = ev->Get()->NodeId;
THolder<TEvInterconnect::TEvNodeInfo> reply(new TEvInterconnect::TEvNodeInfo(nodeId));
@@ -378,21 +378,21 @@ void TDynamicNameserver::Handle(TEvInterconnect::TEvGetNode::TPtr &ev, const TAc
&& ctx.Now() < DynamicConfigs[domain]->Epoch.End) {
ctx.Send(ev->Sender, reply.Release());
} else {
- const TInstant deadline = ev->Get()->Deadline;
+ const TInstant deadline = ev->Get()->Deadline;
ctx.RegisterWithSameMailbox(new TDynamicNodeSearcher(SelfId(), nodeId, DynamicConfigs[domain], ev.Release(),
- deadline));
+ deadline));
}
}
}
-void TDynamicNameserver::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx)
+void TDynamicNameserver::Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx)
{
ui32 domain = AppData(ctx)->DomainsInfo->GetDomainUidByTabletId(ev->Get()->TabletId);
if (NodeBrokerPipes[domain] == ev->Get()->ClientId)
OnPipeDestroyed(domain, ctx);
}
-void TDynamicNameserver::Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx)
+void TDynamicNameserver::Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx)
{
if (ev->Get()->Status != NKikimrProto::OK) {
ui32 domain = AppData(ctx)->DomainsInfo->GetDomainUidByTabletId(ev->Get()->TabletId);
@@ -429,7 +429,7 @@ void TDynamicNameserver::Handle(TEvPrivate::TEvUpdateEpoch::TPtr &ev, const TAct
RequestEpochUpdate(domain, epoch, ctx);
}
-IActor *CreateDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup> &setup, ui32 poolId) {
+IActor *CreateDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup> &setup, ui32 poolId) {
return new TDynamicNameserver(setup, poolId);
}
diff --git a/ydb/core/mind/dynamic_nameserver_impl.h b/ydb/core/mind/dynamic_nameserver_impl.h
index ae0e1889511..64c233adbca 100644
--- a/ydb/core/mind/dynamic_nameserver_impl.h
+++ b/ydb/core/mind/dynamic_nameserver_impl.h
@@ -27,7 +27,7 @@ struct TDynamicConfig : public TThrRefBase {
const TString &host,
const TString &resolveHost,
ui16 port,
- const TNodeLocation &location,
+ const TNodeLocation &location,
TInstant expire)
: TNodeInfo(address, host, resolveHost, port, location)
, Expire(expire)
@@ -39,14 +39,14 @@ struct TDynamicConfig : public TThrRefBase {
info.GetHost(),
info.GetResolveHost(),
(ui16)info.GetPort(),
- TNodeLocation(info.GetLocation()),
+ TNodeLocation(info.GetLocation()),
TInstant::MicroSeconds(info.GetExpire()))
{
}
TDynamicNodeInfo(const TDynamicNodeInfo &other) = default;
- bool EqualExceptExpire(const TDynamicNodeInfo &other) const
+ bool EqualExceptExpire(const TDynamicNodeInfo &other) const
{
return Host == other.Host
&& Address == other.Address
@@ -69,17 +69,17 @@ class TDynamicNodeResolverBase : public TActorBootstrapped<TDynamicNodeResolverB
public:
using TBase = TActorBootstrapped<TDynamicNodeResolverBase>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::NAMESERVICE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::NAMESERVICE;
}
TDynamicNodeResolverBase(TActorId owner, ui32 nodeId, TDynamicConfigPtr config,
- TAutoPtr<IEventHandle> origRequest, TInstant deadline)
+ TAutoPtr<IEventHandle> origRequest, TInstant deadline)
: Owner(owner)
, NodeId(nodeId)
, Config(config)
, OrigRequest(origRequest)
- , Deadline(deadline)
+ , Deadline(deadline)
{
}
@@ -88,7 +88,7 @@ public:
CFunc(TEvTabletPipe::EvClientDestroyed, ReplyWithErrorAndDie);
HFunc(TEvTabletPipe::TEvClientConnected, Handle);
HFunc(TEvNodeBroker::TEvResolvedNode, Handle);
- CFunc(TEvents::TSystem::Wakeup, ReplyWithErrorAndDie);
+ CFunc(TEvents::TSystem::Wakeup, ReplyWithErrorAndDie);
}
}
@@ -115,7 +115,7 @@ protected:
ui32 NodeId;
TDynamicConfigPtr Config;
TAutoPtr<IEventHandle> OrigRequest;
- const TInstant Deadline;
+ const TInstant Deadline;
private:
TActorId NodeBrokerPipe;
@@ -124,8 +124,8 @@ private:
class TDynamicNodeResolver : public TDynamicNodeResolverBase {
public:
TDynamicNodeResolver(TActorId owner, ui32 nodeId, TDynamicConfigPtr config,
- TAutoPtr<IEventHandle> origRequest, TInstant deadline)
- : TDynamicNodeResolverBase(owner, nodeId, config, origRequest, deadline)
+ TAutoPtr<IEventHandle> origRequest, TInstant deadline)
+ : TDynamicNodeResolverBase(owner, nodeId, config, origRequest, deadline)
{
}
@@ -136,8 +136,8 @@ public:
class TDynamicNodeSearcher : public TDynamicNodeResolverBase {
public:
TDynamicNodeSearcher(TActorId owner, ui32 nodeId, TDynamicConfigPtr config,
- TAutoPtr<IEventHandle> origRequest, TInstant deadline)
- : TDynamicNodeResolverBase(owner, nodeId, config, origRequest, deadline)
+ TAutoPtr<IEventHandle> origRequest, TInstant deadline)
+ : TDynamicNodeResolverBase(owner, nodeId, config, origRequest, deadline)
{
}
@@ -149,8 +149,8 @@ class TDynamicNameserver : public TActorBootstrapped<TDynamicNameserver> {
public:
using TBase = TActorBootstrapped<TDynamicNameserver>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::NAMESERVICE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::NAMESERVICE;
}
struct TEvPrivate {
@@ -174,7 +174,7 @@ public:
};
};
- TDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup> &setup, ui32 resolvePoolId)
+ TDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup> &setup, ui32 resolvePoolId)
: StaticConfig(setup)
, ResolvePoolId(resolvePoolId)
{
@@ -218,22 +218,22 @@ private:
void RequestEpochUpdate(ui32 domain,
ui32 epoch,
const TActorContext &ctx);
- void ResolveStaticNode(ui32 nodeId, TActorId sender, TInstant deadline, const TActorContext &ctx);
- void ResolveDynamicNode(ui32 nodeId, TAutoPtr<IEventHandle> ev, TInstant deadline, const TActorContext &ctx);
- void SendNodesList(const TActorContext &ctx);
- void PendingRequestAnswered(ui32 domain, const TActorContext &ctx);
+ void ResolveStaticNode(ui32 nodeId, TActorId sender, TInstant deadline, const TActorContext &ctx);
+ void ResolveDynamicNode(ui32 nodeId, TAutoPtr<IEventHandle> ev, TInstant deadline, const TActorContext &ctx);
+ void SendNodesList(const TActorContext &ctx);
+ void PendingRequestAnswered(ui32 domain, const TActorContext &ctx);
void UpdateState(const NKikimrNodeBroker::TNodesInfo &rec,
const TActorContext &ctx);
void OnPipeDestroyed(ui32 domain,
const TActorContext &ctx);
- void Handle(TEvInterconnect::TEvResolveNode::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvResolveAddress::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvInterconnect::TEvListNodes::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvInterconnect::TEvGetNode::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx);
- void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvInterconnect::TEvResolveNode::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvResolveAddress::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvInterconnect::TEvListNodes::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvInterconnect::TEvGetNode::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx);
+ void Handle(TEvTabletPipe::TEvClientConnected::TPtr &ev, const TActorContext &ctx);
void Handle(TEvNodeBroker::TEvNodesInfo::TPtr &ev, const TActorContext &ctx);
void Handle(TEvPrivate::TEvUpdateEpoch::TPtr &ev, const TActorContext &ctx);
void Handle(NMon::TEvHttpInfo::TPtr &ev, const TActorContext &ctx);
diff --git a/ydb/core/mind/dynamic_nameserver_mon.cpp b/ydb/core/mind/dynamic_nameserver_mon.cpp
index 65a3b9664e4..3d5cb325cef 100644
--- a/ydb/core/mind/dynamic_nameserver_mon.cpp
+++ b/ydb/core/mind/dynamic_nameserver_mon.cpp
@@ -83,8 +83,8 @@ void OutputNodeInfo(ui32 nodeId,
<< " <td>" << info.Host << ":" << info.Port << "</td>" << Endl
<< " <td>" << info.ResolveHost << "</td>" << Endl
<< " <td>" << info.Address << "</td>" << Endl
- << " <td>" << info.Location.GetDataCenterId() << "</td>" << Endl
- << " <td>" << info.Location.ToString() << "</td>" << Endl;
+ << " <td>" << info.Location.GetDataCenterId() << "</td>" << Endl
+ << " <td>" << info.Location.ToString() << "</td>" << Endl;
if (expire)
str << "<td>" << ToString(expire) << "</td>" << Endl;
str << "</tr>" << Endl;
@@ -102,7 +102,7 @@ void OutputStaticNodes(const TTableNameserverSetup &setup,
<< " <th>Resolve Host</th>" << Endl
<< " <th>Address</th>" << Endl
<< " <th>Data Center</th>" << Endl
- << " <th>Location</th>" << Endl
+ << " <th>Location</th>" << Endl
<< " </tr>" << Endl
<< " </thead>" << Endl
<< " <tbody class='center-align'>" << Endl;
diff --git a/ydb/core/mind/hive/balancer.cpp b/ydb/core/mind/hive/balancer.cpp
index 8521e30499e..100109ecb6e 100644
--- a/ydb/core/mind/hive/balancer.cpp
+++ b/ydb/core/mind/hive/balancer.cpp
@@ -291,8 +291,8 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
}
THiveBalancer(THive* hive, int maxMovements = 0, bool recheckOnFinish = false, const std::vector<TNodeId>& filterNodeIds = {})
diff --git a/ydb/core/mind/hive/drain.cpp b/ydb/core/mind/hive/drain.cpp
index 2e263a7f0e1..3ad4f2d27b0 100644
--- a/ydb/core/mind/hive/drain.cpp
+++ b/ydb/core/mind/hive/drain.cpp
@@ -141,8 +141,8 @@ protected:
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
}
THiveDrain(THive* hive, TNodeId nodeId, TDrainSettings settings)
diff --git a/ydb/core/mind/hive/fill.cpp b/ydb/core/mind/hive/fill.cpp
index f90fa56f422..1b863bc132a 100644
--- a/ydb/core/mind/hive/fill.cpp
+++ b/ydb/core/mind/hive/fill.cpp
@@ -79,8 +79,8 @@ protected:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
}
THiveFill(THive* hive, TNodeId nodeId, const TActorId& initiator)
diff --git a/ydb/core/mind/hive/follower_group.h b/ydb/core/mind/hive/follower_group.h
index 33ab3189ffe..d7653a8c463 100644
--- a/ydb/core/mind/hive/follower_group.h
+++ b/ydb/core/mind/hive/follower_group.h
@@ -38,13 +38,13 @@ struct TFollowerGroup {
std::copy(allowedNodes.begin(), allowedNodes.end(), std::back_inserter(AllowedNodes));
}
{
- if (const auto& x = followerGroup.GetAllowedDataCenters(); !x.empty()) {
- AllowedDataCenters.insert(AllowedDataCenters.end(), x.begin(), x.end());
- } else {
- for (const auto& dataCenterId : followerGroup.GetAllowedDataCenterNumIDs()) {
- AllowedDataCenters.push_back(DataCenterToString(dataCenterId));
- }
- }
+ if (const auto& x = followerGroup.GetAllowedDataCenters(); !x.empty()) {
+ AllowedDataCenters.insert(AllowedDataCenters.end(), x.begin(), x.end());
+ } else {
+ for (const auto& dataCenterId : followerGroup.GetAllowedDataCenterNumIDs()) {
+ AllowedDataCenters.push_back(DataCenterToString(dataCenterId));
+ }
+ }
}
LocalNodeOnly = followerGroup.GetLocalNodeOnly();
RequireDifferentNodes = followerGroup.GetRequireDifferentNodes();
diff --git a/ydb/core/mind/hive/hive.h b/ydb/core/mind/hive/hive.h
index cce565aecd6..aac553ea28e 100644
--- a/ydb/core/mind/hive/hive.h
+++ b/ydb/core/mind/hive/hive.h
@@ -40,7 +40,7 @@ using NTabletFlatExecutor::TExecutorCounters;
using TTabletId = ui64;
using TTabletCategoryId = ui64;
using TNodeId = ui32;
-using TDataCenterId = TString;
+using TDataCenterId = TString;
using TFollowerId = ui32;
using TFollowerGroupId = ui32;
using TStorageGroupId = ui32;
diff --git a/ydb/core/mind/hive/hive_impl.cpp b/ydb/core/mind/hive/hive_impl.cpp
index 58ca2ac3e43..92d14688cef 100644
--- a/ydb/core/mind/hive/hive_impl.cpp
+++ b/ydb/core/mind/hive/hive_impl.cpp
@@ -342,7 +342,7 @@ void THive::Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
NKikimrBlobStorage::TEvControllerSelectGroupsResult& rec = ev->Get()->Record;
if (rec.GetStatus() == NKikimrProto::OK) {
BLOG_D("THive::Handle TEvControllerSelectGroupsResult: success " << rec.ShortDebugString());
- if (rec.MatchingGroupsSize()) {
+ if (rec.MatchingGroupsSize()) {
TVector<TTabletId> tablets;
for (const auto& matchingGroups : rec.GetMatchingGroups()) {
if (matchingGroups.GroupsSize() == 0) {
@@ -365,7 +365,7 @@ void THive::Handle(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr& ev) {
Execute(CreateUpdateTabletGroups(tabletId));
}
}
- } else {
+ } else {
BLOG_ERROR("THive::Handle TEvControllerSelectGroupsResult: obsolete BSC response");
}
} else {
@@ -622,8 +622,8 @@ void THive::Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
NodesInfo[node->NodeId] = nodeInfo;
TNodeInfo* hiveNodeInfo = FindNode(nodeInfo.NodeId);
if (hiveNodeInfo != nullptr) {
- hiveNodeInfo->Location = nodeInfo.Location;
- hiveNodeInfo->LocationAcquired = true;
+ hiveNodeInfo->Location = nodeInfo.Location;
+ hiveNodeInfo->LocationAcquired = true;
BLOG_D("TEvInterconnect::TEvNodeInfo NodeId " << nodeInfo.NodeId << " Location " << GetLocationString(hiveNodeInfo->Location));
if (hiveNodeInfo->IsRegistered()) {
UpdateRegisteredDataCenters(hiveNodeInfo->Location.GetDataCenterId());
@@ -633,10 +633,10 @@ void THive::Handle(TEvInterconnect::TEvNodeInfo::TPtr &ev) {
}
void THive::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) {
- THashSet<TDataCenterId> dataCenters;
+ THashSet<TDataCenterId> dataCenters;
for (const TEvInterconnect::TNodeInfo& node : ev->Get()->Nodes) {
NodesInfo[node.NodeId] = node;
- dataCenters.insert(node.Location.GetDataCenterId());
+ dataCenters.insert(node.Location.GetDataCenterId());
}
dataCenters.erase(0); // remove default data center id if exists
if (!dataCenters.empty()) {
@@ -857,19 +857,19 @@ void THive::DefaultSignalTabletActive(const TActorContext& ctx) {
void THive::AssignTabletGroups(TLeaderTabletInfo& tablet) {
ui32 channels = tablet.GetChannelCount();
THashSet<TString> storagePoolsToRefresh;
- // was this method called for the first time for this tablet?
+ // was this method called for the first time for this tablet?
bool firstInvocation = tablet.ChannelProfileNewGroup.none();
-
- for (ui32 channelId = 0; channelId < channels; ++channelId) {
- if (firstInvocation || tablet.ChannelProfileNewGroup.test(channelId)) {
- tablet.ChannelProfileNewGroup.set(channelId);
+
+ for (ui32 channelId = 0; channelId < channels; ++channelId) {
+ if (firstInvocation || tablet.ChannelProfileNewGroup.test(channelId)) {
+ tablet.ChannelProfileNewGroup.set(channelId);
TStoragePoolInfo& storagePool = tablet.GetStoragePool(channelId);
if (!storagePool.IsFresh() || storagePool.ConfigurationGeneration != ConfigurationGeneration) {
storagePoolsToRefresh.insert(storagePool.Name);
- }
+ }
}
}
-
+
if (!storagePoolsToRefresh.empty()) {
// we had to refresh storage pool state from BSC
TVector<THolder<NKikimrBlobStorage::TEvControllerSelectGroups::TGroupParameters>> requests;
@@ -882,7 +882,7 @@ void THive::AssignTabletGroups(TLeaderTabletInfo& tablet) {
}
}
if (!requests.empty()) {
- THolder<TEvBlobStorage::TEvControllerSelectGroups> ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
+ THolder<TEvBlobStorage::TEvControllerSelectGroups> ev = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>();
NKikimrBlobStorage::TEvControllerSelectGroups& record = ev->Record;
record.SetReturnAllMatchingGroups(true);
for (auto& request : requests) {
@@ -1085,7 +1085,7 @@ THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
});
for (size_t i = 0; i < dcs.size(); ++i) {
dataCentersGroupsHolder[i].AddDataCenter(dcs[i]);
- dataCentersGroupsHolder[i].AddDataCenterNum(DataCenterFromString(dcs[i]));
+ dataCentersGroupsHolder[i].AddDataCenterNum(DataCenterFromString(dcs[i]));
dataCentersGroupsPointers[i] = dataCentersGroupsHolder.data() + i;
}
dataCentersGroups = TArrayRef<const NKikimrHive::TDataCentersGroup*>(dataCentersGroupsPointers.data(), dcTablets.size());
@@ -1102,14 +1102,14 @@ THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
std::unordered_map<TDataCenterId, std::vector<TNodeInfo*>*> indexDC2Group;
for (size_t numGroup = 0; numGroup < dataCentersGroups.size(); ++numGroup) {
const NKikimrHive::TDataCentersGroup* dcGroup = dataCentersGroups[numGroup];
- if (dcGroup->DataCenterSize()) {
- for (TDataCenterId dc : dcGroup->GetDataCenter()) {
+ if (dcGroup->DataCenterSize()) {
+ for (TDataCenterId dc : dcGroup->GetDataCenter()) {
indexDC2Group[dc] = candidateGroups.data() + numGroup;
- }
- } else {
- for (const ui64 dcId : dcGroup->GetDataCenterNum()) {
+ }
+ } else {
+ for (const ui64 dcId : dcGroup->GetDataCenterNum()) {
indexDC2Group[DataCenterToString(dcId)] = candidateGroups.data() + numGroup;
- }
+ }
}
}
for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
@@ -1280,11 +1280,11 @@ THive::TBestNodeResult THive::FindBestNode(const TTabletInfo& tablet) {
}
}
-const TNodeLocation& THive::GetNodeLocation(TNodeId nodeId) const {
+const TNodeLocation& THive::GetNodeLocation(TNodeId nodeId) const {
auto it = NodesInfo.find(nodeId);
if (it != NodesInfo.end())
return it->second.Location;
- static TNodeLocation defaultLocation;
+ static TNodeLocation defaultLocation;
return defaultLocation;
}
@@ -1397,8 +1397,8 @@ void THive::DeleteTablet(TTabletId tabletId) {
itType->second.DecreaseCount();
if (itType->second.Counter == 0) {
TabletTypeToTabletMetrics.erase(itType);
- }
- }
+ }
+ }
for (auto nt = Nodes.begin(); nt != Nodes.end(); ++nt) {
for (auto st = nt->second.Tablets.begin(); st != nt->second.Tablets.end(); ++st) {
Y_ENSURE_LOG(st->second.count(&tablet) == 0, " Deleting tablet found on node " << nt->first << " in state " << TTabletInfo::EVolatileStateName(st->first));
@@ -2097,16 +2097,16 @@ NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForObject(TObjectId o
return metrics;
}
-NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForTabletType(TTabletTypes::EType type) {
- NKikimrTabletBase::TMetrics metrics;
+NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForTabletType(TTabletTypes::EType type) {
+ NKikimrTabletBase::TMetrics metrics;
auto it = TabletTypeToTabletMetrics.find(type);
if (it != TabletTypeToTabletMetrics.end()) {
metrics = it->second.GetAverage();
metrics.ClearCounter();
- }
- return metrics;
-}
-
+ }
+ return metrics;
+}
+
NKikimrTabletBase::TMetrics THive::GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile) {
NKikimrTabletBase::TMetrics resourceValues;
// copy default resource usage from resource profile
diff --git a/ydb/core/mind/hive/hive_impl.h b/ydb/core/mind/hive/hive_impl.h
index 70c4530fee0..e73e6174c64 100644
--- a/ydb/core/mind/hive/hive_impl.h
+++ b/ydb/core/mind/hive/hive_impl.h
@@ -503,8 +503,8 @@ protected:
void RestartPipeTx(ui64 tabletId);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_ACTOR;
}
THive(TTabletStorageInfo *info, const TActorId &tablet);
@@ -566,7 +566,7 @@ public:
TStoragePoolInfo& GetStoragePool(const TString& name);
TStoragePoolInfo* FindStoragePool(const TString& name);
TDomainInfo* FindDomain(TSubDomainKey key);
- const TNodeLocation& GetNodeLocation(TNodeId nodeId) const;
+ const TNodeLocation& GetNodeLocation(TNodeId nodeId) const;
void DeleteTablet(TTabletId tabletId);
void DeleteNode(TNodeId nodeId);
TVector<TNodeId> GetNodesForWhiteboardBroadcast(size_t maxNodesToReturn = 3);
@@ -776,7 +776,7 @@ protected:
void RemoveSubActor(ISubActor* subActor);
const NKikimrLocal::TLocalConfig &GetLocalConfig() const { return LocalConfig; }
NKikimrTabletBase::TMetrics GetDefaultResourceValuesForObject(TObjectId objectId);
- NKikimrTabletBase::TMetrics GetDefaultResourceValuesForTabletType(TTabletTypes::EType type);
+ NKikimrTabletBase::TMetrics GetDefaultResourceValuesForTabletType(TTabletTypes::EType type);
NKikimrTabletBase::TMetrics GetDefaultResourceValuesForProfile(TTabletTypes::EType type, const TString& resourceProfile);
static void AggregateMetricsMax(NKikimrTabletBase::TMetrics& aggregate, const NKikimrTabletBase::TMetrics& value);
static void AggregateMetricsDiff(NKikimrTabletBase::TMetrics& aggregate,
diff --git a/ydb/core/mind/hive/hive_schema.h b/ydb/core/mind/hive/hive_schema.h
index 6289499cc31..1deacfd49bd 100644
--- a/ydb/core/mind/hive/hive_schema.h
+++ b/ydb/core/mind/hive/hive_schema.h
@@ -71,7 +71,7 @@ struct Schema : NIceDb::Schema {
struct ActorToNotify : Column<11, NScheme::NTypeIds::ActorId> {}; // deprecated because of ActorsToNotify down here
//struct Weight : Column<12, NScheme::NTypeIds::Uint64> {};
struct Category : Column<13, NScheme::NTypeIds::Uint64> {};
- struct AllowedDataCenters : Column<17, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
+ struct AllowedDataCenters : Column<17, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
struct TabletStorageVersion : Column<18, NScheme::NTypeIds::Uint32> { static constexpr ui32 Default = 0; };
struct ObjectID : Column<19, NScheme::NTypeIds::Uint64> { using Type = TObjectId; };
struct ActorsToNotify : Column<111, NScheme::NTypeIds::String> { using Type = TVector<TActorId>; };
@@ -90,7 +90,7 @@ struct Schema : NIceDb::Schema {
};
struct Statistics : Column<120, NScheme::NTypeIds::String> { using Type = NKikimrHive::TTabletStatistics; };
struct DataCentersPreference : Column<121, NScheme::NTypeIds::String> { using Type = NKikimrHive::TDataCentersPreference; };
- struct AllowedDataCenterIds : Column<122, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
+ struct AllowedDataCenterIds : Column<122, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
using TKey = TableKey<ID>;
using TColumns = TableColumns<
@@ -116,8 +116,8 @@ struct Schema : NIceDb::Schema {
NeedToReleaseFromParent,
ReassignReason,
Statistics,
- DataCentersPreference,
- AllowedDataCenterIds
+ DataCentersPreference,
+ AllowedDataCenterIds
>;
};
@@ -128,17 +128,17 @@ struct Schema : NIceDb::Schema {
struct AllowLeaderPromotion : Column<4, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct AllowClientRead : Column<5, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct AllowedNodes : Column<6, NScheme::NTypeIds::String> { using Type = TVector<TNodeId>; };
- struct AllowedDataCenters : Column<7, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
+ struct AllowedDataCenters : Column<7, NScheme::NTypeIds::String> { using Type = TVector<ui32>; };
struct RequireAllDataCenters : Column<8, NScheme::NTypeIds::Bool> {};
struct LocalNodeOnly : Column<9, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct FollowerCountPerDataCenter : Column<10, NScheme::NTypeIds::Bool> { static constexpr bool Default = false; };
struct RequireDifferentNodes : Column<11, NScheme::NTypeIds::Bool> {};
- struct AllowedDataCenterIds : Column<12, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
+ struct AllowedDataCenterIds : Column<12, NScheme::NTypeIds::String> { using Type = TVector<TString>; };
using TKey = TableKey<TabletID, GroupID>;
using TColumns = TableColumns<TabletID, GroupID, FollowerCount, AllowLeaderPromotion, AllowClientRead,
AllowedNodes, AllowedDataCenters, RequireAllDataCenters, LocalNodeOnly,
- FollowerCountPerDataCenter, RequireDifferentNodes, AllowedDataCenterIds>;
+ FollowerCountPerDataCenter, RequireDifferentNodes, AllowedDataCenterIds>;
};
struct TabletFollowerTablet : Table<10> {
diff --git a/ydb/core/mind/hive/hive_ut.cpp b/ydb/core/mind/hive/hive_ut.cpp
index 0383d49a123..ba182dc7753 100644
--- a/ydb/core/mind/hive/hive_ut.cpp
+++ b/ydb/core/mind/hive/hive_ut.cpp
@@ -307,7 +307,7 @@ namespace {
TAutoPtr<IEventHandle> handleNodesInfo;
auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
- auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
NKikimrBlobStorage::TDefineBox boxConfig;
boxConfig.SetBoxId(1);
@@ -1734,7 +1734,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
SendReassignTablet(runtime, hiveTablet, tabletId, {}, 0);
{
TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroupsResult));
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroupsResult));
runtime.DispatchEvents(options);
}
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -2374,7 +2374,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
/*{
TDispatchOptions options;
- options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroupsResult));
+ options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvBlobStorage::EvControllerSelectGroupsResult));
runtime.DispatchEvents(options);
}*/
@@ -3005,21 +3005,21 @@ Y_UNIT_TEST_SUITE(THiveTest) {
}
}
- TNodeLocation GetLocation(ui32 nodeId) {
- NActorsInterconnect::TNodeLocation location;
- location.SetDataCenter(ToString(nodeId / 2 + 1));
- location.SetModule("1");
- location.SetRack("1");
- location.SetUnit("1");
- return TNodeLocation(location); // DC = [1,1,2,2,3,3]
- }
-
+ TNodeLocation GetLocation(ui32 nodeId) {
+ NActorsInterconnect::TNodeLocation location;
+ location.SetDataCenter(ToString(nodeId / 2 + 1));
+ location.SetModule("1");
+ location.SetRack("1");
+ location.SetUnit("1");
+ return TNodeLocation(location); // DC = [1,1,2,2,3,3]
+ }
+
Y_UNIT_TEST(TestHiveBalancerWithPrefferedDC1) {
static const int NUM_NODES = 6;
static const int NUM_TABLETS = NUM_NODES * 3;
TTestBasicRuntime runtime(NUM_NODES, false);
- runtime.LocationCallback = GetLocation;
+ runtime.LocationCallback = GetLocation;
Setup(runtime, true);
const int nodeBase = runtime.GetNodeId(0);
@@ -3039,8 +3039,8 @@ Y_UNIT_TEST_SUITE(THiveTest) {
for (int i = 0; i < NUM_TABLETS; ++i) {
THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(3);
- ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(1));
- ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(2));
+ ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(1));
+ ev->Record.MutableDataCentersPreference()->AddDataCentersGroups()->AddDataCenter(ToString(2));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
tablets.emplace_back(tabletId);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -3084,7 +3084,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
static const int NUM_TABLETS = NUM_NODES * 3;
TTestBasicRuntime runtime(NUM_NODES, false);
- runtime.LocationCallback = GetLocation;
+ runtime.LocationCallback = GetLocation;
Setup(runtime, true);
const int nodeBase = runtime.GetNodeId(0);
@@ -3105,8 +3105,8 @@ Y_UNIT_TEST_SUITE(THiveTest) {
THolder<TEvHive::TEvCreateTablet> ev(new TEvHive::TEvCreateTablet(testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
ev->Record.SetFollowerCount(3);
auto* group = ev->Record.MutableDataCentersPreference()->AddDataCentersGroups();
- group->AddDataCenter(ToString(1));
- group->AddDataCenter(ToString(2));
+ group->AddDataCenter(ToString(1));
+ group->AddDataCenter(ToString(2));
ui64 tabletId = SendCreateTestTablet(runtime, hiveTablet, testerTablet, std::move(ev), 0, true);
tablets.emplace_back(tabletId);
MakeSureTabletIsUp(runtime, tabletId, 0);
@@ -3150,7 +3150,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
static const int NUM_TABLETS = 12;
TTestBasicRuntime runtime(NUM_NODES, false);
- runtime.LocationCallback = GetLocation;
+ runtime.LocationCallback = GetLocation;
Setup(runtime, true);
const int nodeBase = runtime.GetNodeId(0);
@@ -3176,16 +3176,16 @@ Y_UNIT_TEST_SUITE(THiveTest) {
// checking distribution, all leaders should be on the first node
{
- std::unordered_map<TString, ui64> dcTablets;
+ std::unordered_map<TString, ui64> dcTablets;
{
THolder<TEvHive::TEvRequestHiveInfo> request = MakeHolder<TEvHive::TEvRequestHiveInfo>();
runtime.SendToPipe(hiveTablet, senderA, request.Release());
TAutoPtr<IEventHandle> handle;
TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow<TEvHive::TEvResponseHiveInfo>(handle);
for (const NKikimrHive::TTabletInfo& tablet : response->Record.GetTablets()) {
- dcTablets[runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId()]++;
+ dcTablets[runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId()]++;
Ctest << "tablet " << tablet.GetTabletID() << "." << tablet.GetFollowerID() << " on node " << tablet.GetNodeID()
- << " on DC " << runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId() << Endl;
+ << " on DC " << runtime.LocationCallback(tablet.GetNodeID() - nodeBase).GetDataCenterId() << Endl;
}
}
UNIT_ASSERT_VALUES_EQUAL(dcTablets.size(), 1);
diff --git a/ydb/core/mind/hive/leader_tablet_info.cpp b/ydb/core/mind/hive/leader_tablet_info.cpp
index 13e1d5b2ee2..101ccc66d7b 100644
--- a/ydb/core/mind/hive/leader_tablet_info.cpp
+++ b/ydb/core/mind/hive/leader_tablet_info.cpp
@@ -27,7 +27,7 @@ bool TLeaderTabletInfo::IsSomeoneAliveOnNode(TNodeId nodeId) const {
ui32 TLeaderTabletInfo::GetFollowersAliveOnDataCenter(TDataCenterId dataCenterId) const {
ui32 followers = 0;
for (const TTabletInfo& follower : Followers) {
- if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
+ if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
++followers;
}
}
@@ -39,7 +39,7 @@ ui32 TLeaderTabletInfo::GetFollowersAliveOnDataCenterExcludingFollower(TDataCent
for (const TTabletInfo& follower : Followers) {
if (follower == excludingFollower)
continue;
- if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
+ if (follower.CanBeAlive() && follower.Node->Location.GetDataCenterId() == dataCenterId) {
++followers;
}
}
diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp
index 7e9a83b354e..ada80155a42 100644
--- a/ydb/core/mind/hive/monitoring.cpp
+++ b/ydb/core/mind/hive/monitoring.cpp
@@ -681,8 +681,8 @@ public:
TTabletTypes::KeyValue,
TTabletTypes::PersQueue,
TTabletTypes::PersQueueReadBalancer,
- TTabletTypes::NodeBroker,
- TTabletTypes::TestShard}) {
+ TTabletTypes::NodeBroker,
+ TTabletTypes::TestShard}) {
if (shortType == LongToShortTabletName(TTabletTypes::TypeToStr(tabletType))) {
return tabletType;
}
@@ -927,8 +927,8 @@ public:
TTabletTypes::KeyValue,
TTabletTypes::PersQueue,
TTabletTypes::PersQueueReadBalancer,
- TTabletTypes::NodeBroker,
- TTabletTypes::TestShard}) {
+ TTabletTypes::NodeBroker,
+ TTabletTypes::TestShard}) {
const TVector<i64>& allowedMetrics = Self->GetTabletTypeAllowedMetricIds(tabletType);
out << "<tr>"
"<td>" << LongToShortTabletName(TTabletTypes::TypeToStr(tabletType)) << "</td>";
@@ -1088,8 +1088,8 @@ public:
return "SV";
case TTabletTypes::FileStore:
return "FS";
- case TTabletTypes::TestShard:
- return "TS";
+ case TTabletTypes::TestShard:
+ return "TS";
case TTabletTypes::SequenceShard:
return "S";
case TTabletTypes::ReplicationController:
@@ -1825,8 +1825,8 @@ public:
jsonNode["Id"] = id;
jsonNode["Host"] = host;
jsonNode["Name"] = name;
- if (node.LocationAcquired) {
- jsonNode["DataCenter"] = node.Location.GetDataCenterId();
+ if (node.LocationAcquired) {
+ jsonNode["DataCenter"] = node.Location.GetDataCenterId();
}
jsonNode["Domain"] = node.ServicedDomains.empty() ? "" : Self->GetDomainName(node.GetServicedDomain());
jsonNode["Alive"] = node.IsAlive();
@@ -2697,10 +2697,10 @@ public:
return item;
}
- static NJson::TJsonValue MakeFrom(TString item) {
- return item;
- }
-
+ static NJson::TJsonValue MakeFrom(TString item) {
+ return item;
+ }
+
template<typename Type>
static NJson::TJsonValue MakeFrom(const TVector<Type>& array) {
NJson::TJsonValue result;
@@ -2867,87 +2867,87 @@ public:
}
};
-class TTxMonEvent_ResetTablet : public TTransactionBase<THive> {
- class TResetter : public TActorBootstrapped<TResetter> {
- TIntrusivePtr<TTabletStorageInfo> Info;
+class TTxMonEvent_ResetTablet : public TTransactionBase<THive> {
+ class TResetter : public TActorBootstrapped<TResetter> {
+ TIntrusivePtr<TTabletStorageInfo> Info;
const TActorId Source;
const ui32 KnownGeneration;
-
- public:
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TResetter(TIntrusivePtr<TTabletStorageInfo> info, TActorId source, ui32 knownGeneration)
- : Info(std::move(info))
- , Source(source)
+ : Info(std::move(info))
+ , Source(source)
, KnownGeneration(knownGeneration)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc);
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc);
ctx.Register(CreateTabletReqReset(SelfId(), std::move(Info), KnownGeneration));
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvTablet::TEvResetTabletResult, Handle)
- )
-
- void Handle(TEvTablet::TEvResetTabletResult::TPtr& ev, const TActorContext& ctx) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Sprintf("{\"status\": \"%s\"}",
- NKikimrProto::EReplyStatus_Name(ev->Get()->Status).data())));
- }
- };
-
-public:
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvTablet::TEvResetTabletResult, Handle)
+ )
+
+ void Handle(TEvTablet::TEvResetTabletResult::TPtr& ev, const TActorContext& ctx) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(Sprintf("{\"status\": \"%s\"}",
+ NKikimrProto::EReplyStatus_Name(ev->Get()->Status).data())));
+ }
+ };
+
+public:
const TActorId Source;
- TTabletId TabletId = 0;
- TString Error;
- TIntrusivePtr<TTabletStorageInfo> Info;
+ TTabletId TabletId = 0;
+ TString Error;
+ TIntrusivePtr<TTabletStorageInfo> Info;
ui32 KnownGeneration = 0;
-
+
TTxMonEvent_ResetTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive)
- : TBase(hive)
- , Source(source)
- {
- TabletId = FromStringWithDefault<TTabletId>(ev->Get()->Cgi().Get("tablet"), TabletId);
- }
-
+ : TBase(hive)
+ , Source(source)
+ {
+ TabletId = FromStringWithDefault<TTabletId>(ev->Get()->Cgi().Get("tablet"), TabletId);
+ }
+
TTxType GetTxType() const override { return NHive::TXTYPE_MON_RESET_TABLET; }
- bool Execute(TTransactionContext&, const TActorContext& /*ctx*/) override {
- if (TabletId) {
+ bool Execute(TTransactionContext&, const TActorContext& /*ctx*/) override {
+ if (TabletId) {
if (TLeaderTabletInfo* tablet = Self->FindTablet(TabletId)) {
- Info = tablet->TabletStorageInfo;
+ Info = tablet->TabletStorageInfo;
KnownGeneration = tablet->KnownGeneration;
- } else {
- Error = "tablet not found";
- }
- } else {
- Error = "tablet parameter not set";
- }
- return true;
- }
-
- void Complete(const TActorContext& ctx) override {
- if (Info) {
+ } else {
+ Error = "tablet not found";
+ }
+ } else {
+ Error = "tablet parameter not set";
+ }
+ return true;
+ }
+
+ void Complete(const TActorContext& ctx) override {
+ if (Info) {
ctx.Register(new TResetter(std::move(Info), Source, KnownGeneration));
- } else if (Error) {
- ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"" << Error << "\"}"));
- } else {
- Y_FAIL("unexpected state");
- }
- }
-};
-
+ } else if (Error) {
+ ctx.Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"error\":\"" << Error << "\"}"));
+ } else {
+ Y_FAIL("unexpected state");
+ }
+ }
+};
+
class TUpdateResourcesActor : public TActorBootstrapped<TUpdateResourcesActor> {
public:
TActorId Source;
TActorId Hive;
NKikimrHive::TTabletMetrics Metrics;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TUpdateResourcesActor(const TActorId& source, const TActorId& hive, const NKikimrHive::TTabletMetrics& metrics)
@@ -2989,8 +2989,8 @@ public:
TAutoPtr<TEvHive::TEvCreateTablet> Event;
THive* Hive;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TCreateTabletActor(const TActorId& source, ui64 owner, ui64 ownerIdx, TTabletTypes::EType type, ui32 channelsProfile, ui32 followers, THive* hive)
@@ -3057,8 +3057,8 @@ public:
Event->Record.SetTxId_Deprecated(FAKE_TXID);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_MON_REQUEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_MON_REQUEST;
}
TDeleteTabletActor(const TActorId& source, ui64 tabletId, THive* hive)
@@ -3384,9 +3384,9 @@ void THive::CreateEvMonitoring(NMon::TEvRemoteHttpInfo::TPtr& ev, const TActorCo
if (page == "TabletInfo") {
return Execute(new TTxMonEvent_TabletInfo(ev->Sender, ev, this), ctx);
}
- if (page == "ResetTablet") {
- return Execute(new TTxMonEvent_ResetTablet(ev->Sender, ev, this), ctx);
- }
+ if (page == "ResetTablet") {
+ return Execute(new TTxMonEvent_ResetTablet(ev->Sender, ev, this), ctx);
+ }
if (page == "CreateTablet") {
ui64 owner = FromStringWithDefault<ui64>(cgi.Get("owner"), 0);
ui64 ownerIdx = FromStringWithDefault<ui64>(cgi.Get("owner_idx"), 0);
diff --git a/ydb/core/mind/hive/node_info.cpp b/ydb/core/mind/hive/node_info.cpp
index 8b6913c9819..20b7d5dd116 100644
--- a/ydb/core/mind/hive/node_info.cpp
+++ b/ydb/core/mind/hive/node_info.cpp
@@ -15,8 +15,8 @@ TNodeInfo::TNodeInfo(TNodeId nodeId, THive& hive)
, ResourceTotalValues()
, ResourceMaximumValues(GetResourceInitialMaximumValues())
, StartTime(TInstant::MicroSeconds(0))
- , Location()
- , LocationAcquired(false)
+ , Location()
+ , LocationAcquired(false)
{}
void TNodeInfo::ChangeVolatileState(EVolatileState state) {
@@ -99,7 +99,7 @@ bool TNodeInfo::IsAllowedToRunTablet(TTabletDebugState* debugState) const {
return false;
}
- if (!LocationAcquired) {
+ if (!LocationAcquired) {
if (debugState) {
debugState->NodesWithoutLocation++;
}
@@ -200,9 +200,9 @@ bool TNodeInfo::IsAbleToRunTablet(const TTabletInfo& tablet, TTabletDebugState*
ui32 maxFollowersPerDataCenter = (followerGroup.GetComputedFollowerCount(Hive.GetDataCenters()) + dataCenters - 1) / dataCenters; // ceil
ui32 existingFollowers;
if (tablet.IsAlive()) {
- existingFollowers = leader.GetFollowersAliveOnDataCenterExcludingFollower(Location.GetDataCenterId(), tablet);
+ existingFollowers = leader.GetFollowersAliveOnDataCenterExcludingFollower(Location.GetDataCenterId(), tablet);
} else {
- existingFollowers = leader.GetFollowersAliveOnDataCenter(Location.GetDataCenterId());
+ existingFollowers = leader.GetFollowersAliveOnDataCenter(Location.GetDataCenterId());
}
if (maxFollowersPerDataCenter <= existingFollowers) {
if (debugState) {
diff --git a/ydb/core/mind/hive/node_info.h b/ydb/core/mind/hive/node_info.h
index fa7400fd25b..3d61e5d0d81 100644
--- a/ydb/core/mind/hive/node_info.h
+++ b/ydb/core/mind/hive/node_info.h
@@ -50,8 +50,8 @@ public:
NMetrics::TFastRiseAverageValue<double, 20> AveragedNodeTotalUsage;
TResourceRawValues ResourceMaximumValues;
TInstant StartTime;
- TNodeLocation Location;
- bool LocationAcquired;
+ TNodeLocation Location;
+ bool LocationAcquired;
std::unordered_map<TTabletTypes::EType, NKikimrLocal::TTabletAvailability> TabletAvailability;
TVector<TSubDomainKey> ServicedDomains;
TVector<TSubDomainKey> LastSeenServicedDomains;
@@ -247,7 +247,7 @@ public:
void ActualizeNodeStatistics(TInstant now);
TDataCenterId GetDataCenter() const {
- return Location.GetDataCenterId();
+ return Location.GetDataCenterId();
}
};
diff --git a/ydb/core/mind/hive/tx__create_tablet.cpp b/ydb/core/mind/hive/tx__create_tablet.cpp
index f3b27bfd9ac..579c050c7dc 100644
--- a/ydb/core/mind/hive/tx__create_tablet.cpp
+++ b/ydb/core/mind/hive/tx__create_tablet.cpp
@@ -57,16 +57,16 @@ public:
AllowedNodeIds.push_back(RequestData.GetAllowedNodeIDs(idx));
}
Sort(AllowedNodeIds);
-
- if (const auto& x = RequestData.GetAllowedDataCenters(); !x.empty()) {
- AllowedDataCenterIds.insert(AllowedDataCenterIds.end(), x.begin(), x.end());
- } else {
- for (const auto& dataCenterId : RequestData.GetAllowedDataCenterNumIDs()) {
- AllowedDataCenterIds.push_back(DataCenterToString(dataCenterId));
- }
+
+ if (const auto& x = RequestData.GetAllowedDataCenters(); !x.empty()) {
+ AllowedDataCenterIds.insert(AllowedDataCenterIds.end(), x.begin(), x.end());
+ } else {
+ for (const auto& dataCenterId : RequestData.GetAllowedDataCenterNumIDs()) {
+ AllowedDataCenterIds.push_back(DataCenterToString(dataCenterId));
+ }
}
Sort(AllowedDataCenterIds);
-
+
DataCentersPreference = RequestData.GetDataCentersPreference();
if (RequestData.HasTabletCategory()) {
TabletCategory.CopyFrom(RequestData.GetTabletCategory());
@@ -100,13 +100,13 @@ public:
}
void UpdateChannelsBinding(TLeaderTabletInfo& tablet, NIceDb::TNiceDb& db) {
- Y_VERIFY(tablet.BoundChannels.size() <= BoundChannels.size(), "only expansion channels number is allowed in Binded Channels");
+ Y_VERIFY(tablet.BoundChannels.size() <= BoundChannels.size(), "only expansion channels number is allowed in Binded Channels");
std::bitset<MAX_TABLET_CHANNELS> newChannels;
// compare channel list with erasure and category information
- for (ui32 channelId = 0; channelId < tablet.BoundChannels.size(); ++channelId) {
- auto& channelA = tablet.BoundChannels[channelId];
+ for (ui32 channelId = 0; channelId < tablet.BoundChannels.size(); ++channelId) {
+ auto& channelA = tablet.BoundChannels[channelId];
auto channelB = BoundChannels[channelId]; // copy, not reference
Self->InitDefaultChannelBind(channelB);
if (channelA.SerializeAsString() != channelB.SerializeAsString()) {
@@ -118,7 +118,7 @@ public:
}
// new channels found in the tablet profile
- for (ui32 channelId = tablet.BoundChannels.size(); channelId < BoundChannels.size(); ++channelId) {
+ for (ui32 channelId = tablet.BoundChannels.size(); channelId < BoundChannels.size(); ++channelId) {
auto channel = BoundChannels[channelId]; // copy, not reference
Self->InitDefaultChannelBind(channel);
db.Table<Schema::TabletChannel>().Key(TabletId, channelId).Update<Schema::TabletChannel::StoragePool>(BoundChannels[channelId].GetStoragePoolName());
@@ -131,7 +131,7 @@ public:
tablet.ChannelProfileNewGroup |= newChannels;
tablet.State = State = ETabletState::GroupAssignment;
tablet.ChannelProfileReassignReason = NKikimrHive::TEvReassignTablet::HIVE_REASSIGN_REASON_NO;
- tablet.BoundChannels = BoundChannels;
+ tablet.BoundChannels = BoundChannels;
for (auto& bind : tablet.BoundChannels) {
Self->InitDefaultChannelBind(bind);
}
@@ -259,18 +259,18 @@ public:
TFollowerGroup& followerGroup = itFollowerGroup != tablet->FollowerGroups.end() ? *itFollowerGroup : tablet->AddFollowerGroup();
ui32 oldFollowerCount = followerGroup.GetComputedFollowerCount(Self->GetDataCenters());
followerGroup = srcFollowerGroup;
-
- TVector<ui32> allowedDataCenters;
- for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
- allowedDataCenters.push_back(DataCenterFromString(dc));
- }
+
+ TVector<ui32> allowedDataCenters;
+ for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
+ allowedDataCenters.push_back(DataCenterFromString(dc));
+ }
db.Table<Schema::TabletFollowerGroup>().Key(TabletId, followerGroup.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCount>(followerGroup.GetRawFollowerCount()),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowLeaderPromotion>(followerGroup.AllowLeaderPromotion),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowClientRead>(followerGroup.AllowClientRead),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedNodes>(followerGroup.AllowedNodes),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireDifferentNodes>(followerGroup.RequireDifferentNodes));
@@ -355,10 +355,10 @@ public:
tablet.AssignDomains(ObjectDomain, AllowedDomains);
tablet.Statistics.SetLastAliveTimestamp(now.MilliSeconds());
- TVector<ui32> allowedDataCenters;
- for (const TDataCenterId& dc : tablet.AllowedDataCenters) {
- allowedDataCenters.push_back(DataCenterFromString(dc));
- }
+ TVector<ui32> allowedDataCenters;
+ for (const TDataCenterId& dc : tablet.AllowedDataCenters) {
+ allowedDataCenters.push_back(DataCenterFromString(dc));
+ }
db.Table<Schema::Tablet>().Key(TabletId).Update(NIceDb::TUpdate<Schema::Tablet::Owner>(tablet.Owner),
NIceDb::TUpdate<Schema::Tablet::LeaderNode>(tablet.NodeId),
NIceDb::TUpdate<Schema::Tablet::TabletType>(tablet.Type),
@@ -366,8 +366,8 @@ public:
NIceDb::TUpdate<Schema::Tablet::State>(tablet.State),
NIceDb::TUpdate<Schema::Tablet::ActorsToNotify>(TVector<TActorId>(1, Sender)),
NIceDb::TUpdate<Schema::Tablet::AllowedNodes>(tablet.AllowedNodes),
- NIceDb::TUpdate<Schema::Tablet::AllowedDataCenters>(allowedDataCenters),
- NIceDb::TUpdate<Schema::Tablet::AllowedDataCenterIds>(tablet.AllowedDataCenters),
+ NIceDb::TUpdate<Schema::Tablet::AllowedDataCenters>(allowedDataCenters),
+ NIceDb::TUpdate<Schema::Tablet::AllowedDataCenterIds>(tablet.AllowedDataCenters),
NIceDb::TUpdate<Schema::Tablet::DataCentersPreference>(tablet.DataCentersPreference),
NIceDb::TUpdate<Schema::Tablet::AllowedDomains>(AllowedDomains),
NIceDb::TUpdate<Schema::Tablet::BootMode>(tablet.BootMode),
@@ -417,7 +417,7 @@ public:
resourceValues.SetWriteThroughput(10ULL << 20); // 10 MB/s
}
tablet.UpdateResourceUsage(resourceValues);
- tablet.BoundChannels.clear();
+ tablet.BoundChannels.clear();
tablet.TabletStorageInfo.Reset(new TTabletStorageInfo(tablet.Id, tablet.Type));
tablet.TabletStorageInfo->TenantPathId = tablet.GetTenant();
@@ -426,18 +426,18 @@ public:
for (const auto& srcFollowerGroup : FollowerGroups) {
TFollowerGroup& followerGroup = tablet.AddFollowerGroup();
followerGroup = srcFollowerGroup;
-
- TVector<ui32> allowedDataCenters;
- for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
- allowedDataCenters.push_back(DataCenterFromString(dc));
- }
+
+ TVector<ui32> allowedDataCenters;
+ for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
+ allowedDataCenters.push_back(DataCenterFromString(dc));
+ }
db.Table<Schema::TabletFollowerGroup>().Key(TabletId, followerGroup.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCount>(followerGroup.GetRawFollowerCount()),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowLeaderPromotion>(followerGroup.AllowLeaderPromotion),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowClientRead>(followerGroup.AllowClientRead),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedNodes>(followerGroup.AllowedNodes),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter));
diff --git a/ydb/core/mind/hive/tx__load_everything.cpp b/ydb/core/mind/hive/tx__load_everything.cpp
index e4c1cf1f51e..25bca680888 100644
--- a/ydb/core/mind/hive/tx__load_everything.cpp
+++ b/ydb/core/mind/hive/tx__load_everything.cpp
@@ -346,15 +346,15 @@ public:
Self->ObjectToTabletMetrics[tablet.ObjectId].IncreaseCount();
Self->TabletTypeToTabletMetrics[tablet.Type].IncreaseCount();
tablet.AllowedNodes = tabletRowset.GetValue<Schema::Tablet::AllowedNodes>();
- if (tabletRowset.HaveValue<Schema::Tablet::AllowedDataCenters>()) {
- // this is priority format due to migration issues; when migration is complete, this code will
- // be removed
- for (const ui32 dcId : tabletRowset.GetValue<Schema::Tablet::AllowedDataCenters>()) {
- tablet.AllowedDataCenters.push_back(DataCenterToString(dcId));
- }
- } else {
- tablet.AllowedDataCenters = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDataCenterIds>();
- }
+ if (tabletRowset.HaveValue<Schema::Tablet::AllowedDataCenters>()) {
+ // this is priority format due to migration issues; when migration is complete, this code will
+ // be removed
+ for (const ui32 dcId : tabletRowset.GetValue<Schema::Tablet::AllowedDataCenters>()) {
+ tablet.AllowedDataCenters.push_back(DataCenterToString(dcId));
+ }
+ } else {
+ tablet.AllowedDataCenters = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDataCenterIds>();
+ }
tablet.DataCentersPreference = tabletRowset.GetValueOrDefault<Schema::Tablet::DataCentersPreference>();
TVector<TSubDomainKey> allowedDomains = tabletRowset.GetValueOrDefault<Schema::Tablet::AllowedDomains>();
TSubDomainKey objectDomain = TSubDomainKey(tabletRowset.GetValueOrDefault<Schema::Tablet::ObjectDomain>());
@@ -424,17 +424,17 @@ public:
followerGroup.AllowLeaderPromotion = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::AllowLeaderPromotion>();
followerGroup.AllowClientRead = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::AllowClientRead>();
followerGroup.AllowedNodes = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::AllowedNodes>();
-
- if (tabletFollowerGroupRowset.HaveValue<Schema::TabletFollowerGroup::AllowedDataCenters>()) {
- // this is priority format due to migration issues; when migration is complete, this code will
- // be removed
- for (const ui32 dcId : tabletFollowerGroupRowset.GetValue<Schema::TabletFollowerGroup::AllowedDataCenters>()) {
- followerGroup.AllowedDataCenters.push_back(DataCenterToString(dcId));
- }
- } else {
- followerGroup.AllowedDataCenters = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::AllowedDataCenterIds>();
- }
-
+
+ if (tabletFollowerGroupRowset.HaveValue<Schema::TabletFollowerGroup::AllowedDataCenters>()) {
+ // this is priority format due to migration issues; when migration is complete, this code will
+ // be removed
+ for (const ui32 dcId : tabletFollowerGroupRowset.GetValue<Schema::TabletFollowerGroup::AllowedDataCenters>()) {
+ followerGroup.AllowedDataCenters.push_back(DataCenterToString(dcId));
+ }
+ } else {
+ followerGroup.AllowedDataCenters = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::AllowedDataCenterIds>();
+ }
+
followerGroup.RequireAllDataCenters = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::RequireAllDataCenters>();
followerGroup.LocalNodeOnly = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::LocalNodeOnly>();
followerGroup.FollowerCountPerDataCenter = tabletFollowerGroupRowset.GetValueOrDefault<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>();
diff --git a/ydb/core/mind/hive/tx__seize_tablets_reply.cpp b/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
index 6e6db7131be..bb24a1675e8 100644
--- a/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
+++ b/ydb/core/mind/hive/tx__seize_tablets_reply.cpp
@@ -114,18 +114,18 @@ public:
for (const auto& protoFollowerGroup : protoTabletInfo.GetFollowerGroups()) {
TFollowerGroup& followerGroup = tablet.AddFollowerGroup();
followerGroup = protoFollowerGroup;
-
- TVector<ui32> allowedDataCenters;
- for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
- allowedDataCenters.push_back(DataCenterFromString(dc));
- }
+
+ TVector<ui32> allowedDataCenters;
+ for (const TDataCenterId& dc : followerGroup.AllowedDataCenters) {
+ allowedDataCenters.push_back(DataCenterFromString(dc));
+ }
db.Table<Schema::TabletFollowerGroup>().Key(tabletId, followerGroup.Id).Update(
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCount>(followerGroup.GetRawFollowerCount()),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowLeaderPromotion>(followerGroup.AllowLeaderPromotion),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowClientRead>(followerGroup.AllowClientRead),
NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedNodes>(followerGroup.AllowedNodes),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
- NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenters>(allowedDataCenters),
+ NIceDb::TUpdate<Schema::TabletFollowerGroup::AllowedDataCenterIds>(followerGroup.AllowedDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireAllDataCenters>(followerGroup.RequireAllDataCenters),
NIceDb::TUpdate<Schema::TabletFollowerGroup::RequireDifferentNodes>(followerGroup.RequireDifferentNodes),
NIceDb::TUpdate<Schema::TabletFollowerGroup::FollowerCountPerDataCenter>(followerGroup.FollowerCountPerDataCenter));
diff --git a/ydb/core/mind/hive/tx__update_tablet_groups.cpp b/ydb/core/mind/hive/tx__update_tablet_groups.cpp
index 2d9a11bc3b8..d876ef558ad 100644
--- a/ydb/core/mind/hive/tx__update_tablet_groups.cpp
+++ b/ydb/core/mind/hive/tx__update_tablet_groups.cpp
@@ -40,15 +40,15 @@ public:
<< tablet->Id << "," << tablet->ChannelProfileReassignReason << "," << Groups << ")");
Y_VERIFY(tablet->TabletStorageInfo);
-
+
if (tablet->ChannelProfileNewGroup.count() != Groups.size() && !Groups.empty()) {
BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
<< tablet->Id
<< " ChannelProfileNewGroup has incorrect size");
Ignored = true;
return true;
- }
-
+ }
+
if (!tablet->ChannelProfileNewGroup.any()) {
BLOG_W("THive::TTxUpdateTabletGroups::Execute{" << (ui64)this << "}: tablet "
<< tablet->Id
diff --git a/ydb/core/mind/labels_maintainer.cpp b/ydb/core/mind/labels_maintainer.cpp
index 19138c7d23b..6c6b53a2ba2 100644
--- a/ydb/core/mind/labels_maintainer.cpp
+++ b/ydb/core/mind/labels_maintainer.cpp
@@ -17,9 +17,9 @@ class TLabelsMaintainer : public TActorBootstrapped<TLabelsMaintainer> {
using TActorBase = TActorBootstrapped<TLabelsMaintainer>;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::LABELS_MAINTAINER_ACTOR;
+ return NKikimrServices::TActivity::LABELS_MAINTAINER_ACTOR;
}
TLabelsMaintainer(const NKikimrConfig::TMonitoringConfig &config)
diff --git a/ydb/core/mind/lease_holder.cpp b/ydb/core/mind/lease_holder.cpp
index 5d47d04c71f..ef512d1fa0c 100644
--- a/ydb/core/mind/lease_holder.cpp
+++ b/ydb/core/mind/lease_holder.cpp
@@ -33,8 +33,8 @@ private:
public:
using TBase = TActorBootstrapped<TLeaseHolder>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::NODE_BROKER_LEASE_HOLDER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::NODE_BROKER_LEASE_HOLDER;
}
TLeaseHolder(TInstant expire)
diff --git a/ydb/core/mind/local.cpp b/ydb/core/mind/local.cpp
index 09fc15f76dd..71a61a5904c 100644
--- a/ydb/core/mind/local.cpp
+++ b/ydb/core/mind/local.cpp
@@ -857,8 +857,8 @@ class TLocalNodeRegistrar : public TActorBootstrapped<TLocalNodeRegistrar> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::LOCAL_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::LOCAL_ACTOR;
}
TLocalNodeRegistrar(const TActorId &owner, ui64 hiveId, TVector<TSubDomainKey> servicedDomains,
@@ -1344,8 +1344,8 @@ class TDomainLocal : public TActorBootstrapped<TDomainLocal> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::LOCAL_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::LOCAL_ACTOR;
}
TDomainLocal(const TDomainsInfo &domainsInfo, const TDomainsInfo::TDomain &domain,
@@ -1398,8 +1398,8 @@ class TLocal : public TActorBootstrapped<TLocal> {
THashMap<TString, TActorId> DomainLocals;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::LOCAL_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::LOCAL_ACTOR;
}
TLocal(TLocalConfig *cfg)
diff --git a/ydb/core/mind/node_broker.cpp b/ydb/core/mind/node_broker.cpp
index a2ef9383691..fa8e67a9ae2 100644
--- a/ydb/core/mind/node_broker.cpp
+++ b/ydb/core/mind/node_broker.cpp
@@ -112,8 +112,8 @@ bool TNodeBroker::OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev,
<< " Host: " << node.Host << Endl
<< " ResolveHost: " << node.ResolveHost << Endl
<< " Port: " << node.Port << Endl
- << " DataCenter: " << node.Location.GetDataCenterId() << Endl
- << " Location: " << node.Location.ToString() << Endl
+ << " DataCenter: " << node.Location.GetDataCenterId() << Endl
+ << " Location: " << node.Location.ToString() << Endl
<< " Lease: " << node.Lease << Endl
<< " Expire: " << node.ExpirationString() << Endl;
}
@@ -299,7 +299,7 @@ void TNodeBroker::FillNodeInfo(const TNodeInfo &node,
info.SetResolveHost(node.ResolveHost);
info.SetAddress(node.Address);
info.SetExpire(node.Expire.GetValue());
- node.Location.Serialize(info.MutableLocation());
+ node.Location.Serialize(info.MutableLocation());
}
void TNodeBroker::ComputeNextEpochDiff(TStateDiff &diff)
@@ -452,25 +452,25 @@ void TNodeBroker::DbAddNode(const TNodeInfo &node,
"Adding node " << node.IdString() << " to database"
<< " resolvehost=" << node.ResolveHost
<< " address=" << node.Address
- << " dc=" << node.Location.GetDataCenterId()
- << " location=" << node.Location.ToString()
+ << " dc=" << node.Location.GetDataCenterId()
+ << " location=" << node.Location.ToString()
<< " lease=" << node.Lease
<< " expire=" << node.ExpirationString());
NIceDb::TNiceDb db(txc.DB);
- using T = Schema::Nodes;
- db.Table<T>().Key(node.NodeId)
- .Update<T::Host>(node.Host)
- .Update<T::Port>(node.Port)
- .Update<T::ResolveHost>(node.ResolveHost)
- .Update<T::Address>(node.Address)
- .Update<T::Lease>(node.Lease)
- .Update<T::Expire>(node.Expire.GetValue())
- .Update<T::Location>(node.Location.GetSerializedLocation());
-
- // to be removed
- const auto& x = node.Location.GetLegacyValue();
- db.Table<T>().Key(node.NodeId).Update<T::DataCenter, T::Room, T::Rack, T::Body>(x.DataCenter, x.Room, x.Rack, x.Body);
+ using T = Schema::Nodes;
+ db.Table<T>().Key(node.NodeId)
+ .Update<T::Host>(node.Host)
+ .Update<T::Port>(node.Port)
+ .Update<T::ResolveHost>(node.ResolveHost)
+ .Update<T::Address>(node.Address)
+ .Update<T::Lease>(node.Lease)
+ .Update<T::Expire>(node.Expire.GetValue())
+ .Update<T::Location>(node.Location.GetSerializedLocation());
+
+ // to be removed
+ const auto& x = node.Location.GetLegacyValue();
+ db.Table<T>().Key(node.NodeId).Update<T::DataCenter, T::Room, T::Rack, T::Body>(x.DataCenter, x.Room, x.Rack, x.Body);
}
void TNodeBroker::DbApplyStateDiff(const TStateDiff &diff,
@@ -578,8 +578,8 @@ bool TNodeBroker::DbLoadState(TTransactionContext &txc,
TVector<ui32> toRemove;
while (!nodesRowset.EndOfSet()) {
- using T = Schema::Nodes;
- auto id = nodesRowset.GetValue<T::ID>();
+ using T = Schema::Nodes;
+ auto id = nodesRowset.GetValue<T::ID>();
// We don't remove nodes with a different domain id when there's a
// single domain. We may have been running in a single domain allocation
// mode, and now temporarily restarted without this mode enabled. We
@@ -596,49 +596,49 @@ bool TNodeBroker::DbLoadState(TTransactionContext &txc,
<< MaxStaticId << ", " << MaxDynamicId << "]");
toRemove.push_back(id);
} else {
- auto expire = TInstant::FromValue(nodesRowset.GetValue<T::Expire>());
- std::optional<TNodeLocation> legacyLocation, modernLocation;
- if (nodesRowset.HaveValue<T::DataCenter>() && nodesRowset.HaveValue<T::Room>() &&
- nodesRowset.HaveValue<T::Rack>() && nodesRowset.HaveValue<T::Body>()) {
- // priority value for compatibility issues
- NActorsInterconnect::TNodeLocation proto;
- proto.SetDataCenterNum(nodesRowset.GetValue<T::DataCenter>());
- proto.SetRoomNum(nodesRowset.GetValue<T::Room>());
- proto.SetRackNum(nodesRowset.GetValue<T::Rack>());
- proto.SetBodyNum(nodesRowset.GetValue<T::Body>());
- legacyLocation.emplace(proto);
- }
- if (nodesRowset.HaveValue<T::Location>()) {
- modernLocation.emplace(TNodeLocation::FromSerialized, nodesRowset.GetValue<T::Location>());
- }
-
- TNodeLocation location;
-
- if (!legacyLocation) {
- // only modern value found in database
- Y_VERIFY(modernLocation);
- location = std::move(*modernLocation);
- } else if (!modernLocation) {
- // only legacy value found in database
- Y_VERIFY(legacyLocation);
- location = std::move(*legacyLocation);
- } else if (*modernLocation == *legacyLocation) {
- // both modern and legacy values and they match; use modern one with legacy value filled
- location = std::move(*modernLocation);
- location.InheritLegacyValue(*legacyLocation);
- } else {
- // both values found, but there is no match -- legacy value was rewritten after modern one was written
- location = std::move(*legacyLocation);
- }
-
- TNodeInfo info{id,
- nodesRowset.GetValue<T::Address>(),
- nodesRowset.GetValue<T::Host>(),
- nodesRowset.GetValue<T::ResolveHost>(),
- (ui16)nodesRowset.GetValue<T::Port>(),
- location,
- legacyLocation && !modernLocation}; // format update pending
- info.Lease = nodesRowset.GetValue<T::Lease>();
+ auto expire = TInstant::FromValue(nodesRowset.GetValue<T::Expire>());
+ std::optional<TNodeLocation> legacyLocation, modernLocation;
+ if (nodesRowset.HaveValue<T::DataCenter>() && nodesRowset.HaveValue<T::Room>() &&
+ nodesRowset.HaveValue<T::Rack>() && nodesRowset.HaveValue<T::Body>()) {
+ // priority value for compatibility issues
+ NActorsInterconnect::TNodeLocation proto;
+ proto.SetDataCenterNum(nodesRowset.GetValue<T::DataCenter>());
+ proto.SetRoomNum(nodesRowset.GetValue<T::Room>());
+ proto.SetRackNum(nodesRowset.GetValue<T::Rack>());
+ proto.SetBodyNum(nodesRowset.GetValue<T::Body>());
+ legacyLocation.emplace(proto);
+ }
+ if (nodesRowset.HaveValue<T::Location>()) {
+ modernLocation.emplace(TNodeLocation::FromSerialized, nodesRowset.GetValue<T::Location>());
+ }
+
+ TNodeLocation location;
+
+ if (!legacyLocation) {
+ // only modern value found in database
+ Y_VERIFY(modernLocation);
+ location = std::move(*modernLocation);
+ } else if (!modernLocation) {
+ // only legacy value found in database
+ Y_VERIFY(legacyLocation);
+ location = std::move(*legacyLocation);
+ } else if (*modernLocation == *legacyLocation) {
+ // both modern and legacy values and they match; use modern one with legacy value filled
+ location = std::move(*modernLocation);
+ location.InheritLegacyValue(*legacyLocation);
+ } else {
+ // both values found, but there is no match -- legacy value was rewritten after modern one was written
+ location = std::move(*legacyLocation);
+ }
+
+ TNodeInfo info{id,
+ nodesRowset.GetValue<T::Address>(),
+ nodesRowset.GetValue<T::Host>(),
+ nodesRowset.GetValue<T::ResolveHost>(),
+ (ui16)nodesRowset.GetValue<T::Port>(),
+ location,
+ legacyLocation && !modernLocation}; // format update pending
+ info.Lease = nodesRowset.GetValue<T::Lease>();
info.Expire = expire;
AddNode(info);
@@ -747,15 +747,15 @@ void TNodeBroker::DbUpdateNodeLocation(const TNodeInfo &node,
{
LOG_DEBUG_S(TActorContext::AsActorContext(), NKikimrServices::NODE_BROKER,
"Update node " << node.IdString() << " location in database"
- << " location=" << node.Location.ToString());
+ << " location=" << node.Location.ToString());
NIceDb::TNiceDb db(txc.DB);
- using T = Schema::Nodes;
- db.Table<T>().Key(node.NodeId).Update<T::Location>(node.Location.GetSerializedLocation());
-
- // to be removed
- const auto& x = node.Location.GetLegacyValue();
- db.Table<T>().Key(node.NodeId).Update<T::DataCenter, T::Room, T::Rack, T::Body>(x.DataCenter, x.Room, x.Rack, x.Body);
+ using T = Schema::Nodes;
+ db.Table<T>().Key(node.NodeId).Update<T::Location>(node.Location.GetSerializedLocation());
+
+ // to be removed
+ const auto& x = node.Location.GetLegacyValue();
+ db.Table<T>().Key(node.NodeId).Update<T::DataCenter, T::Room, T::Rack, T::Body>(x.DataCenter, x.Room, x.Rack, x.Body);
}
void TNodeBroker::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev,
@@ -826,45 +826,45 @@ void TNodeBroker::Handle(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev,
LOG_TRACE_S(ctx, NKikimrServices::NODE_BROKER, "Handle TEvNodeBroker::TEvRegistrationRequest"
<< ": request# " << ev->Get()->Record.ShortDebugString());
- class TRegisterNodeActor : public TActorBootstrapped<TRegisterNodeActor> {
- TEvNodeBroker::TEvRegistrationRequest::TPtr Ev;
- TNodeBroker *Self;
- NActors::TScopeId ScopeId;
-
- public:
+ class TRegisterNodeActor : public TActorBootstrapped<TRegisterNodeActor> {
+ TEvNodeBroker::TEvRegistrationRequest::TPtr Ev;
+ TNodeBroker *Self;
+ NActors::TScopeId ScopeId;
+
+ public:
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::NODE_BROKER_ACTOR;
}
- TRegisterNodeActor(TEvNodeBroker::TEvRegistrationRequest::TPtr& ev, TNodeBroker *self)
- : Ev(ev)
- , Self(self)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc);
-
- auto& record = Ev->Get()->Record;
-
- if (record.HasPath()) {
- auto req = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
- auto& rset = req->ResultSet;
- rset.emplace_back();
- auto& item = rset.back();
- item.Path = NKikimr::SplitPath(record.GetPath());
+ TRegisterNodeActor(TEvNodeBroker::TEvRegistrationRequest::TPtr& ev, TNodeBroker *self)
+ : Ev(ev)
+ , Self(self)
+ {}
+
+ void Bootstrap(const TActorContext& ctx) {
+ Become(&TThis::StateFunc);
+
+ auto& record = Ev->Get()->Record;
+
+ if (record.HasPath()) {
+ auto req = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
+ auto& rset = req->ResultSet;
+ rset.emplace_back();
+ auto& item = rset.back();
+ item.Path = NKikimr::SplitPath(record.GetPath());
item.RedirectRequired = false;
- item.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
- ctx.Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(req), IEventHandle::FlagTrackDelivery, 0);
- } else {
- Finish(ctx);
- }
- }
-
- void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev, const TActorContext& ctx) {
- const auto& navigate = ev->Get()->Request;
- auto& rset = navigate->ResultSet;
- Y_VERIFY(rset.size() == 1);
- auto& response = rset.front();
+ item.Operation = NSchemeCache::TSchemeCacheNavigate::OpPath;
+ ctx.Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(req), IEventHandle::FlagTrackDelivery, 0);
+ } else {
+ Finish(ctx);
+ }
+ }
+
+ void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev, const TActorContext& ctx) {
+ const auto& navigate = ev->Get()->Request;
+ auto& rset = navigate->ResultSet;
+ Y_VERIFY(rset.size() == 1);
+ auto& response = rset.front();
LOG_TRACE_S(ctx, NKikimrServices::NODE_BROKER, "Handle TEvTxProxySchemeCache::TEvNavigateKeySetResult"
<< ": response# " << response.ToString(*AppData()->TypeRegistry));
@@ -875,29 +875,29 @@ void TNodeBroker::Handle(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev,
LOG_WARN_S(ctx, NKikimrServices::NODE_BROKER, "Cannot resolve scope id"
<< ": request# " << Ev->Get()->Record.ShortDebugString()
<< ", response# " << response.ToString(*AppData()->TypeRegistry));
- }
-
- Finish(ctx);
- }
-
- void HandleUndelivered(const TActorContext& ctx) {
- Finish(ctx);
- }
-
- void Finish(const TActorContext& ctx) {
+ }
+
+ Finish(ctx);
+ }
+
+ void HandleUndelivered(const TActorContext& ctx) {
+ Finish(ctx);
+ }
+
+ void Finish(const TActorContext& ctx) {
LOG_TRACE_S(ctx, NKikimrServices::NODE_BROKER, "Finished resolving scope id"
<< ": request# " << Ev->Get()->Record.ShortDebugString()
<< ": scope id# " << ScopeIdToString(ScopeId));
- Self->ProcessTx(Self->CreateTxRegisterNode(Ev, ScopeId), ctx);
+ Self->ProcessTx(Self->CreateTxRegisterNode(Ev, ScopeId), ctx);
Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc, {
- HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle)
- CFunc(TEvents::TSystem::Undelivered, HandleUndelivered)
- })
- };
+ }
+
+ STRICT_STFUNC(StateFunc, {
+ HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle)
+ CFunc(TEvents::TSystem::Undelivered, HandleUndelivered)
+ })
+ };
ctx.RegisterWithSameMailbox(new TRegisterNodeActor(ev, this));
}
diff --git a/ydb/core/mind/node_broker__register_node.cpp b/ydb/core/mind/node_broker__register_node.cpp
index b656297837b..01ee215414a 100644
--- a/ydb/core/mind/node_broker__register_node.cpp
+++ b/ydb/core/mind/node_broker__register_node.cpp
@@ -10,10 +10,10 @@ using namespace NKikimrNodeBroker;
class TNodeBroker::TTxRegisterNode : public TTransactionBase<TNodeBroker> {
public:
- TTxRegisterNode(TNodeBroker *self, TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId)
+ TTxRegisterNode(TNodeBroker *self, TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId)
: TBase(self)
, Event(ev)
- , ScopeId(scopeId)
+ , ScopeId(scopeId)
, NodeId(0)
, ExtendLease(false)
, FixNodeId(false)
@@ -50,7 +50,7 @@ public:
<< (rec.GetFixedNodeId() ? "(fixed)" : "(not fixed)") << " "
<< "tenant: " << (rec.HasPath() ? rec.GetPath() : "<unspecified>"));
- TNodeLocation loc(rec.GetLocation());
+ TNodeLocation loc(rec.GetLocation());
Response = new TEvNodeBroker::TEvRegistrationResponse;
@@ -73,15 +73,15 @@ public:
<< host << ":" << port,
ctx);
- if (node.Location != loc && node.Location != TNodeLocation()) {
- return Error(TStatus::WRONG_REQUEST,
- TStringBuilder() << "Another location is registered for "
- << host << ":" << port,
- ctx);
- } else if (node.Location != loc || node.LegacyUpdatePending) {
- node.Location = loc;
- Self->DbUpdateNodeLocation(node, txc);
- node.LegacyUpdatePending = false;
+ if (node.Location != loc && node.Location != TNodeLocation()) {
+ return Error(TStatus::WRONG_REQUEST,
+ TStringBuilder() << "Another location is registered for "
+ << host << ":" << port,
+ ctx);
+ } else if (node.Location != loc || node.LegacyUpdatePending) {
+ node.Location = loc;
+ Self->DbUpdateNodeLocation(node, txc);
+ node.LegacyUpdatePending = false;
}
if (!node.IsFixed() && rec.GetFixedNodeId()) {
@@ -104,14 +104,14 @@ public:
NodeId = Self->FreeIds.FirstNonZeroBit();
Self->FreeIds.Reset(NodeId);
- Node = MakeHolder<TNodeInfo>(NodeId, rec.GetAddress(), host, rec.GetResolveHost(), port, loc, false);
+ Node = MakeHolder<TNodeInfo>(NodeId, rec.GetAddress(), host, rec.GetResolveHost(), port, loc, false);
Node->Lease = 1;
Node->Expire = expire;
Response->Record.MutableStatus()->SetCode(TStatus::OK);
Self->DbAddNode(*Node, txc);
- Self->DbUpdateEpochVersion(Self->Epoch.Version + 1, txc);
+ Self->DbUpdateEpochVersion(Self->Epoch.Version + 1, txc);
return true;
}
@@ -135,13 +135,13 @@ public:
Self->FillNodeInfo(Self->Nodes.at(NodeId), *Response->Record.MutableNode());
LOG_TRACE_S(ctx, NKikimrServices::NODE_BROKER,
"TTxRegisterNode reply with: " << Response->Record.ShortDebugString());
-
- if (ScopeId != NActors::TScopeId()) {
- auto& record = Response->Record;
- record.SetScopeTabletId(ScopeId.first);
- record.SetScopePathId(ScopeId.second);
- }
-
+
+ if (ScopeId != NActors::TScopeId()) {
+ auto& record = Response->Record;
+ record.SetScopeTabletId(ScopeId.first);
+ record.SetScopePathId(ScopeId.second);
+ }
+
ctx.Send(Event->Sender, Response.Release());
Self->TxCompleted(this, ctx);
@@ -149,7 +149,7 @@ public:
private:
TEvNodeBroker::TEvRegistrationRequest::TPtr Event;
- const NActors::TScopeId ScopeId;
+ const NActors::TScopeId ScopeId;
TAutoPtr<TEvNodeBroker::TEvRegistrationResponse> Response;
THolder<TNodeInfo> Node;
ui32 NodeId;
@@ -157,9 +157,9 @@ private:
bool FixNodeId;
};
-ITransaction *TNodeBroker::CreateTxRegisterNode(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId)
+ITransaction *TNodeBroker::CreateTxRegisterNode(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId)
{
- return new TTxRegisterNode(this, ev, scopeId);
+ return new TTxRegisterNode(this, ev, scopeId);
}
} // NNodeBroker
diff --git a/ydb/core/mind/node_broker__scheme.h b/ydb/core/mind/node_broker__scheme.h
index ee12a28cd78..0ffb5b3ae62 100644
--- a/ydb/core/mind/node_broker__scheme.h
+++ b/ydb/core/mind/node_broker__scheme.h
@@ -21,11 +21,11 @@ struct Schema : NIceDb::Schema {
struct Body : Column<9, NScheme::NTypeIds::Uint64> {};
struct Lease : Column<10, NScheme::NTypeIds::Uint32> {};
struct Expire : Column<11, NScheme::NTypeIds::Uint64> {};
- struct Location : Column<12, NScheme::NTypeIds::String> {};
+ struct Location : Column<12, NScheme::NTypeIds::String> {};
using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Host, Port, ResolveHost, Address, DataCenter, Room, Rack, Body, Lease, Expire,
- Location>;
+ using TColumns = TableColumns<ID, Host, Port, ResolveHost, Address, DataCenter, Room, Rack, Body, Lease, Expire,
+ Location>;
};
struct Config : Table<2> {
diff --git a/ydb/core/mind/node_broker_impl.h b/ydb/core/mind/node_broker_impl.h
index e3b68b0587b..c6783e16fba 100644
--- a/ydb/core/mind/node_broker_impl.h
+++ b/ydb/core/mind/node_broker_impl.h
@@ -59,19 +59,19 @@ private:
};
struct TNodeInfo : public TEvInterconnect::TNodeInfo {
- TNodeInfo() = delete;
-
+ TNodeInfo() = delete;
+
TNodeInfo(ui32 nodeId,
const TString &address,
const TString &host,
const TString &resolveHost,
ui16 port,
- const TNodeLocation &location,
- bool legacyUpdatePending)
+ const TNodeLocation &location,
+ bool legacyUpdatePending)
: TEvInterconnect::TNodeInfo(nodeId, address, host, resolveHost,
port, location)
, Lease(0)
- , LegacyUpdatePending(legacyUpdatePending)
+ , LegacyUpdatePending(legacyUpdatePending)
{
}
@@ -102,7 +102,7 @@ private:
// Lease is incremented each time node extends its lifetime.
ui32 Lease;
TInstant Expire;
- bool LegacyUpdatePending = false;
+ bool LegacyUpdatePending = false;
};
// State changes to apply while moving to the next epoch.
@@ -123,7 +123,7 @@ private:
ITransaction *CreateTxExtendLease(TEvNodeBroker::TEvExtendLeaseRequest::TPtr &ev);
ITransaction *CreateTxInitScheme();
ITransaction *CreateTxLoadState();
- ITransaction *CreateTxRegisterNode(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId);
+ ITransaction *CreateTxRegisterNode(TEvNodeBroker::TEvRegistrationRequest::TPtr &ev, const NActors::TScopeId& scopeId);
ITransaction *CreateTxUpdateConfig(TEvConsole::TEvConfigNotificationRequest::TPtr &ev);
ITransaction *CreateTxUpdateConfig(TEvNodeBroker::TEvSetConfigRequest::TPtr &ev);
ITransaction *CreateTxUpdateConfigSubscription(TEvConsole::TEvReplaceConfigSubscriptionsResponse::TPtr &ev);
@@ -326,9 +326,9 @@ public:
{
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::NODE_BROKER_ACTOR;
+ return NKikimrServices::TActivity::NODE_BROKER_ACTOR;
}
void Execute(ITransaction *transaction, const TActorContext &ctx) override
diff --git a/ydb/core/mind/node_broker_ut.cpp b/ydb/core/mind/node_broker_ut.cpp
index 0d9498ddcdd..56748d7c49b 100644
--- a/ydb/core/mind/node_broker_ut.cpp
+++ b/ydb/core/mind/node_broker_ut.cpp
@@ -243,10 +243,10 @@ MakeRegistrationRequest(const TString &host,
event->Record.SetResolveHost(resolveHost);
event->Record.SetAddress(address);
auto &loc = *event->Record.MutableLocation();
- loc.SetDataCenter(ToString(dc));
- loc.SetModule(ToString(room));
- loc.SetRack(ToString(rack));
- loc.SetUnit(ToString(body));
+ loc.SetDataCenter(ToString(dc));
+ loc.SetModule(ToString(room));
+ loc.SetRack(ToString(rack));
+ loc.SetUnit(ToString(body));
event->Record.SetFixedNodeId(fixed);
return event;
}
@@ -282,10 +282,10 @@ void CheckRegistration(TTestActorRuntime &runtime,
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetPort(), port);
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetResolveHost(), resolveHost);
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetAddress(), address);
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetDataCenter(), ToString(dc));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetModule(), ToString(room));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetRack(), ToString(rack));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetUnit(), ToString(body));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetDataCenter(), ToString(dc));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetModule(), ToString(room));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetRack(), ToString(rack));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetUnit(), ToString(body));
if (expire)
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetExpire(), expire);
}
@@ -458,10 +458,10 @@ void CheckNodeInfo(TTestActorRuntime &runtime,
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetPort(), port);
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetResolveHost(), resolveHost);
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetAddress(), address);
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetDataCenter(), ToString(dc));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetModule(), ToString(room));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetRack(), ToString(rack));
- UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetUnit(), ToString(body));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetDataCenter(), ToString(dc));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetModule(), ToString(room));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetRack(), ToString(rack));
+ UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetLocation().GetUnit(), ToString(body));
UNIT_ASSERT_VALUES_EQUAL(rec.GetNode().GetExpire(), expire);
}
@@ -576,12 +576,12 @@ TEvInterconnect::TNodeInfo MakeICNodeInfo(ui32 nodeId,
ui64 rack,
ui64 body)
{
- NActorsInterconnect::TNodeLocation location;
- location.SetDataCenter(ToString(dc));
- location.SetModule(ToString(room));
- location.SetRack(ToString(rack));
- location.SetUnit(ToString(body));
- return TEvInterconnect::TNodeInfo(nodeId, address, host, resolveHost, port, TNodeLocation(location));
+ NActorsInterconnect::TNodeLocation location;
+ location.SetDataCenter(ToString(dc));
+ location.SetModule(ToString(room));
+ location.SetRack(ToString(rack));
+ location.SetUnit(ToString(body));
+ return TEvInterconnect::TNodeInfo(nodeId, address, host, resolveHost, port, TNodeLocation(location));
}
void CheckNameserverDynamicNodesList(const THashMap<ui32, TEvInterconnect::TNodeInfo> &nodes,
diff --git a/ydb/core/mind/table_adapter.h b/ydb/core/mind/table_adapter.h
index f0ec8db1e2a..8c5d3e2911e 100644
--- a/ydb/core/mind/table_adapter.h
+++ b/ydb/core/mind/table_adapter.h
@@ -1,561 +1,561 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/tablet_flat/tablet_flat_executor.h>
#include <ydb/core/tablet_flat/flat_cxx_database.h>
-namespace NKikimr {
-
- // inline table specifier
- template<typename TContainer, typename TTable>
- struct TInlineTable
- {};
-
- namespace NTableAdapter {
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // KEY COLUMN MANAGER
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<size_t Index, typename... TableKeyTypes>
- struct TGetTableKeyColumnImpl;
-
- template<typename First, typename... TableKeyTypes>
- struct TGetTableKeyColumnImpl<0, First, TableKeyTypes...> {
- using Type = First;
- };
-
- template<size_t Index, typename First, typename... TableKeyTypes>
- struct TGetTableKeyColumnImpl<Index, First, TableKeyTypes...> : TGetTableKeyColumnImpl<Index - 1, TableKeyTypes...> {};
-
- template<size_t Index, typename T>
- struct TGetTableKeyColumn;
-
- template<size_t Index, typename... TableKeyTypes>
- struct TGetTableKeyColumn<Index, std::tuple<TableKeyTypes...>> : TGetTableKeyColumnImpl<Index, TableKeyTypes...> {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // KEY MAPPER
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<typename Table, size_t Index, size_t Count, typename... TKeyItems>
- struct TTupleKeyMapper {
- using TColumn = typename TGetTableKeyColumn<Index, typename Table::TKey::KeyColumnsType>::Type;
-
- template<typename... TArgs>
- static auto PrepareKeyTuple(const std::tuple<TKeyItems...> *items, std::tuple<TArgs...> &&tuple) {
- TMaybe<typename NIceDb::NSchemeTypeMapper<TColumn::ColumnType>::Type> value(std::get<Index>(*items));
- return TTupleKeyMapper<Table, Index + 1, Count, TKeyItems...>::PrepareKeyTuple(items,
- std::tuple_cat(std::forward<std::tuple<TArgs...>>(tuple), std::make_tuple(std::move(value))));
- }
-
- template<typename TTuple, typename TKey>
- static void MapKey(TTuple *tuple, TKey &key) {
- Y_VERIFY(key.size() == Index);
-
- auto &maybe = std::get<Index>(*tuple);
- key.push_back(NIceDb::TConvertTypeValue<TColumn::ColumnType>(
- maybe ? NIceDb::TTypeValue(*maybe) : NIceDb::TTypeValue()
- ));
-
- TTupleKeyMapper<Table, Index + 1, Count, TKeyItems...>::MapKey(tuple, key);
- }
- };
-
- template<typename Table, size_t Count, typename... TKeyItems>
- struct TTupleKeyMapper<Table, Count, Count, TKeyItems...> {
- template<typename... TArgs>
- static std::tuple<TArgs...> PrepareKeyTuple(const std::tuple<TKeyItems...>* /*items*/,
- std::tuple<TArgs...> &&tuple) {
- return std::move(tuple);
- }
-
- template<typename TTuple, typename TKey>
- static void MapKey(TTuple* /*tuple*/, TKey& /*key*/)
- {}
- };
-
- template<typename Table, typename... TKeyItems>
- auto PrepareKeyTuple(const std::tuple<TKeyItems...> *key) {
- return TTupleKeyMapper<Table, 0, sizeof...(TKeyItems), TKeyItems...>::PrepareKeyTuple(key, std::make_tuple());
- }
-
- template<typename Table, typename... TTupleItems, typename TKey>
- inline void MapKey(std::tuple<TTupleItems...> *tuple, TKey &key) {
- TTupleKeyMapper<Table, 0, sizeof...(TTupleItems), TTupleItems...>::MapKey(tuple, key);
- }
-
- template<typename T, typename TTuple = decltype(std::declval<T>().GetKey())>
- TTuple WrapTuple(const T &object) {
- return object.GetKey();
- }
-
- template<typename... TItems>
- auto WrapTuple(const std::tuple<TItems...> &tuple) {
- return tuple;
- }
-
- template<typename T>
+namespace NKikimr {
+
+ // inline table specifier
+ template<typename TContainer, typename TTable>
+ struct TInlineTable
+ {};
+
+ namespace NTableAdapter {
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // KEY COLUMN MANAGER
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<size_t Index, typename... TableKeyTypes>
+ struct TGetTableKeyColumnImpl;
+
+ template<typename First, typename... TableKeyTypes>
+ struct TGetTableKeyColumnImpl<0, First, TableKeyTypes...> {
+ using Type = First;
+ };
+
+ template<size_t Index, typename First, typename... TableKeyTypes>
+ struct TGetTableKeyColumnImpl<Index, First, TableKeyTypes...> : TGetTableKeyColumnImpl<Index - 1, TableKeyTypes...> {};
+
+ template<size_t Index, typename T>
+ struct TGetTableKeyColumn;
+
+ template<size_t Index, typename... TableKeyTypes>
+ struct TGetTableKeyColumn<Index, std::tuple<TableKeyTypes...>> : TGetTableKeyColumnImpl<Index, TableKeyTypes...> {};
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // KEY MAPPER
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<typename Table, size_t Index, size_t Count, typename... TKeyItems>
+ struct TTupleKeyMapper {
+ using TColumn = typename TGetTableKeyColumn<Index, typename Table::TKey::KeyColumnsType>::Type;
+
+ template<typename... TArgs>
+ static auto PrepareKeyTuple(const std::tuple<TKeyItems...> *items, std::tuple<TArgs...> &&tuple) {
+ TMaybe<typename NIceDb::NSchemeTypeMapper<TColumn::ColumnType>::Type> value(std::get<Index>(*items));
+ return TTupleKeyMapper<Table, Index + 1, Count, TKeyItems...>::PrepareKeyTuple(items,
+ std::tuple_cat(std::forward<std::tuple<TArgs...>>(tuple), std::make_tuple(std::move(value))));
+ }
+
+ template<typename TTuple, typename TKey>
+ static void MapKey(TTuple *tuple, TKey &key) {
+ Y_VERIFY(key.size() == Index);
+
+ auto &maybe = std::get<Index>(*tuple);
+ key.push_back(NIceDb::TConvertTypeValue<TColumn::ColumnType>(
+ maybe ? NIceDb::TTypeValue(*maybe) : NIceDb::TTypeValue()
+ ));
+
+ TTupleKeyMapper<Table, Index + 1, Count, TKeyItems...>::MapKey(tuple, key);
+ }
+ };
+
+ template<typename Table, size_t Count, typename... TKeyItems>
+ struct TTupleKeyMapper<Table, Count, Count, TKeyItems...> {
+ template<typename... TArgs>
+ static std::tuple<TArgs...> PrepareKeyTuple(const std::tuple<TKeyItems...>* /*items*/,
+ std::tuple<TArgs...> &&tuple) {
+ return std::move(tuple);
+ }
+
+ template<typename TTuple, typename TKey>
+ static void MapKey(TTuple* /*tuple*/, TKey& /*key*/)
+ {}
+ };
+
+ template<typename Table, typename... TKeyItems>
+ auto PrepareKeyTuple(const std::tuple<TKeyItems...> *key) {
+ return TTupleKeyMapper<Table, 0, sizeof...(TKeyItems), TKeyItems...>::PrepareKeyTuple(key, std::make_tuple());
+ }
+
+ template<typename Table, typename... TTupleItems, typename TKey>
+ inline void MapKey(std::tuple<TTupleItems...> *tuple, TKey &key) {
+ TTupleKeyMapper<Table, 0, sizeof...(TTupleItems), TTupleItems...>::MapKey(tuple, key);
+ }
+
+ template<typename T, typename TTuple = decltype(std::declval<T>().GetKey())>
+ TTuple WrapTuple(const T &object) {
+ return object.GetKey();
+ }
+
+ template<typename... TItems>
+ auto WrapTuple(const std::tuple<TItems...> &tuple) {
+ return tuple;
+ }
+
+ template<typename T>
auto WrapTuple(const T &item, std::enable_if_t<std::is_integral<T>::value>* = nullptr) {
- return std::make_tuple(item);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CELL
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<typename To, typename From>
- std::enable_if_t<std::is_convertible_v<From, To>> Cast(const From& from, TMaybe<To>& to) {
- to.ConstructInPlace(from);
- }
-
- inline void Cast(const TInstant& from, TMaybe<ui64>& to) {
- to.ConstructInPlace(from.GetValue());
- }
-
- template<typename TRow, typename TColumn>
- struct TCell {
- typename TColumn::Type TRow::*CellPtr = nullptr;
- TMaybe<typename TColumn::Type> TRow::*MaybeCellPtr = nullptr;
-
- constexpr TCell(typename TColumn::Type TRow::*cell)
- : CellPtr(cell)
- {}
-
- constexpr TCell(TMaybe<typename TColumn::Type> TRow::*maybe)
- : MaybeCellPtr(maybe)
- {}
-
- const typename TColumn::Type& GetValue(const TRow &row) const {
- if (CellPtr) {
- return row.*CellPtr;
- } else if (MaybeCellPtr) {
- return *(row.*MaybeCellPtr);
- } else {
- Y_FAIL();
- }
- }
-
- bool Equals(const TRow &x, const TRow &y) const {
- if (CellPtr) {
- return x.*CellPtr == y.*CellPtr;
- } else if (MaybeCellPtr) {
- return x.*MaybeCellPtr == y.*MaybeCellPtr;
- } else {
- Y_FAIL();
- }
- }
-
- template<typename TRowset>
- void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
- if (CellPtr) {
- row.*CellPtr = rowset.template GetValue<TColumn>();
- } else if (MaybeCellPtr) {
- if (rowset.template HaveValue<TColumn>()) {
- row.*MaybeCellPtr = rowset.template GetValue<TColumn>();
- }
- } else {
- Y_FAIL();
- }
- }
-
- // extend tuple with one more item
- template<typename... TArgs>
- auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
- using T = typename NIceDb::NSchemeTypeMapper<TColumn::ColumnType>::Type;
- TMaybe<T> value;
-
- if (CellPtr) {
- Cast(row.*CellPtr, value);
- } else if (MaybeCellPtr) {
- if (const auto& m = row.*MaybeCellPtr) {
- Cast(*m, value);
- } else {
- value = Nothing();
- }
- } else {
- Y_FAIL();
- }
-
- return std::tuple_cat(tuple, std::make_tuple(std::move(value)));
- }
-
- template<size_t Index, typename TUpdates, typename... TArgs>
- static void PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
- NTable::TUpdateOp op;
- op.Tag = TColumn::ColumnId;
+ return std::make_tuple(item);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CELL
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<typename To, typename From>
+ std::enable_if_t<std::is_convertible_v<From, To>> Cast(const From& from, TMaybe<To>& to) {
+ to.ConstructInPlace(from);
+ }
+
+ inline void Cast(const TInstant& from, TMaybe<ui64>& to) {
+ to.ConstructInPlace(from.GetValue());
+ }
+
+ template<typename TRow, typename TColumn>
+ struct TCell {
+ typename TColumn::Type TRow::*CellPtr = nullptr;
+ TMaybe<typename TColumn::Type> TRow::*MaybeCellPtr = nullptr;
+
+ constexpr TCell(typename TColumn::Type TRow::*cell)
+ : CellPtr(cell)
+ {}
+
+ constexpr TCell(TMaybe<typename TColumn::Type> TRow::*maybe)
+ : MaybeCellPtr(maybe)
+ {}
+
+ const typename TColumn::Type& GetValue(const TRow &row) const {
+ if (CellPtr) {
+ return row.*CellPtr;
+ } else if (MaybeCellPtr) {
+ return *(row.*MaybeCellPtr);
+ } else {
+ Y_FAIL();
+ }
+ }
+
+ bool Equals(const TRow &x, const TRow &y) const {
+ if (CellPtr) {
+ return x.*CellPtr == y.*CellPtr;
+ } else if (MaybeCellPtr) {
+ return x.*MaybeCellPtr == y.*MaybeCellPtr;
+ } else {
+ Y_FAIL();
+ }
+ }
+
+ template<typename TRowset>
+ void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
+ if (CellPtr) {
+ row.*CellPtr = rowset.template GetValue<TColumn>();
+ } else if (MaybeCellPtr) {
+ if (rowset.template HaveValue<TColumn>()) {
+ row.*MaybeCellPtr = rowset.template GetValue<TColumn>();
+ }
+ } else {
+ Y_FAIL();
+ }
+ }
+
+ // extend tuple with one more item
+ template<typename... TArgs>
+ auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
+ using T = typename NIceDb::NSchemeTypeMapper<TColumn::ColumnType>::Type;
+ TMaybe<T> value;
+
+ if (CellPtr) {
+ Cast(row.*CellPtr, value);
+ } else if (MaybeCellPtr) {
+ if (const auto& m = row.*MaybeCellPtr) {
+ Cast(*m, value);
+ } else {
+ value = Nothing();
+ }
+ } else {
+ Y_FAIL();
+ }
+
+ return std::tuple_cat(tuple, std::make_tuple(std::move(value)));
+ }
+
+ template<size_t Index, typename TUpdates, typename... TArgs>
+ static void PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
+ NTable::TUpdateOp op;
+ op.Tag = TColumn::ColumnId;
op.Op = NTable::ECellOp::Set;
-
+
std::tuple_element_t<Index, std::tuple<TArgs...>> &maybe = std::get<Index>(*tuple);
- op.Value = NIceDb::TConvertTypeValue<TColumn::ColumnType>(
- maybe ? NIceDb::TTypeValue(*maybe) : NIceDb::TTypeValue()
- );
-
- updates.push_back(std::move(op));
- }
-
- template<typename TCallback>
- void ForEachInlineTable(TCallback&& /*callback*/) const
- {}
- };
-
- template<typename TRow, typename TContainer, typename Table>
- struct TInlineTableCell {
- TContainer TRow::*ContainerPtr;
-
- constexpr TInlineTableCell(TContainer TRow::*m)
- : ContainerPtr(m)
- {}
-
- bool Equals(const TRow& /*x*/, const TRow& /*y*/) const {
- return true; // ignored in inlined tables
- }
-
- template<typename TRowset>
- void ConstructFromRowset(const TRowset& /*rowset*/, TRow& /*row*/) const
- {}
-
- template<typename... TArgs>
- std::tuple<TArgs...> PrepareUpdateRow(const TRow& /*row*/, std::tuple<TArgs...> &&tuple) const {
- return std::move(tuple);
- }
-
- template<size_t Index, typename TUpdates, typename... TArgs>
- static void PopulateUpdateOp(TUpdates& /*updates*/, std::tuple<TArgs...>* /*tuple*/)
- {}
-
- template<typename TCallback>
- void ForEachInlineTable(TCallback &&callback) const {
- callback(ContainerPtr, static_cast<Table*>(nullptr));
- }
- };
-
- template<typename TRow, typename TColumn>
- struct TMapColumnToCell {
- using Type = TCell<TRow, TColumn>;
- };
-
- template<typename TRow, typename TContainer, typename Table>
- struct TMapColumnToCell<TRow, TInlineTable<TContainer, Table>> {
- using Type = TInlineTableCell<TRow, TContainer, Table>;
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CELL TUPLE
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // Cell tuple is a tuple container for TCell instances describing columns of a specific table
-
- template<typename... T>
- struct TCellTuple;
-
- template<typename TCell>
- struct TCellTuple<TCell> {
- const TCell Value;
-
- template<typename... TArgs>
- constexpr TCellTuple(TCell&& value)
- : Value(std::forward<TCell>(value))
- {}
-
- template<typename TRow>
- bool Equals(const TRow &x, const TRow &y) const {
- return Value.Equals(x, y);
- }
-
- template<typename TRowset, typename TRow>
- void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
- Value.ConstructFromRowset(rowset, row);
- }
-
- template<typename TRow, typename... TArgs>
- auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
- return Value.PrepareUpdateRow(row, std::forward<std::tuple<TArgs...>>(tuple));
- }
-
- template<size_t Index, typename TUpdates, typename... TArgs>
- static void PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
- TCell::template PopulateUpdateOp<Index>(updates, tuple);
- }
-
- template<typename TCallback>
- void ForEachInlineTable(TCallback &&callback) const {
+ op.Value = NIceDb::TConvertTypeValue<TColumn::ColumnType>(
+ maybe ? NIceDb::TTypeValue(*maybe) : NIceDb::TTypeValue()
+ );
+
+ updates.push_back(std::move(op));
+ }
+
+ template<typename TCallback>
+ void ForEachInlineTable(TCallback&& /*callback*/) const
+ {}
+ };
+
+ template<typename TRow, typename TContainer, typename Table>
+ struct TInlineTableCell {
+ TContainer TRow::*ContainerPtr;
+
+ constexpr TInlineTableCell(TContainer TRow::*m)
+ : ContainerPtr(m)
+ {}
+
+ bool Equals(const TRow& /*x*/, const TRow& /*y*/) const {
+ return true; // ignored in inlined tables
+ }
+
+ template<typename TRowset>
+ void ConstructFromRowset(const TRowset& /*rowset*/, TRow& /*row*/) const
+ {}
+
+ template<typename... TArgs>
+ std::tuple<TArgs...> PrepareUpdateRow(const TRow& /*row*/, std::tuple<TArgs...> &&tuple) const {
+ return std::move(tuple);
+ }
+
+ template<size_t Index, typename TUpdates, typename... TArgs>
+ static void PopulateUpdateOp(TUpdates& /*updates*/, std::tuple<TArgs...>* /*tuple*/)
+ {}
+
+ template<typename TCallback>
+ void ForEachInlineTable(TCallback &&callback) const {
+ callback(ContainerPtr, static_cast<Table*>(nullptr));
+ }
+ };
+
+ template<typename TRow, typename TColumn>
+ struct TMapColumnToCell {
+ using Type = TCell<TRow, TColumn>;
+ };
+
+ template<typename TRow, typename TContainer, typename Table>
+ struct TMapColumnToCell<TRow, TInlineTable<TContainer, Table>> {
+ using Type = TInlineTableCell<TRow, TContainer, Table>;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CELL TUPLE
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // Cell tuple is a tuple container for TCell instances describing columns of a specific table
+
+ template<typename... T>
+ struct TCellTuple;
+
+ template<typename TCell>
+ struct TCellTuple<TCell> {
+ const TCell Value;
+
+ template<typename... TArgs>
+ constexpr TCellTuple(TCell&& value)
+ : Value(std::forward<TCell>(value))
+ {}
+
+ template<typename TRow>
+ bool Equals(const TRow &x, const TRow &y) const {
+ return Value.Equals(x, y);
+ }
+
+ template<typename TRowset, typename TRow>
+ void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
+ Value.ConstructFromRowset(rowset, row);
+ }
+
+ template<typename TRow, typename... TArgs>
+ auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
+ return Value.PrepareUpdateRow(row, std::forward<std::tuple<TArgs...>>(tuple));
+ }
+
+ template<size_t Index, typename TUpdates, typename... TArgs>
+ static void PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
+ TCell::template PopulateUpdateOp<Index>(updates, tuple);
+ }
+
+ template<typename TCallback>
+ void ForEachInlineTable(TCallback &&callback) const {
Value.ForEachInlineTable(std::forward<TCallback>(callback));
- }
- };
-
- template<typename TCell, typename... TRest>
- struct TCellTuple<TCell, TRest...> {
- const TCellTuple<TCell> Value;
- const TCellTuple<TRest...> Rest;
-
- template<typename TCellV, typename... TRestV>
- constexpr TCellTuple(TCellV&& value, TRestV&&... rest)
- : Value(std::forward<TCellV>(value))
- , Rest(std::forward<TRestV>(rest)...)
- {}
-
- template<typename TRow>
- bool Equals(const TRow &x, const TRow &y) const {
- return Value.Equals(x, y) && Rest.Equals(x, y);
- }
-
- template<typename TRowset, typename TRow>
- void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
- Value.ConstructFromRowset(rowset, row);
- Rest.ConstructFromRowset(rowset, row);
- }
-
- template<typename TRow, typename... TArgs>
- auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
- return Rest.PrepareUpdateRow(row, Value.PrepareUpdateRow(row, std::forward<std::tuple<TArgs...>>(tuple)));
- }
-
- template<size_t Index, typename TUpdates, typename... TArgs>
- static auto PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
- TCellTuple<TCell>::template PopulateUpdateOp<Index>(updates, tuple);
- TCellTuple<TRest...>::template PopulateUpdateOp<Index + 1>(updates, tuple);
- }
-
- template<typename TCallback>
- void ForEachInlineTable(TCallback &&callback) const {
+ }
+ };
+
+ template<typename TCell, typename... TRest>
+ struct TCellTuple<TCell, TRest...> {
+ const TCellTuple<TCell> Value;
+ const TCellTuple<TRest...> Rest;
+
+ template<typename TCellV, typename... TRestV>
+ constexpr TCellTuple(TCellV&& value, TRestV&&... rest)
+ : Value(std::forward<TCellV>(value))
+ , Rest(std::forward<TRestV>(rest)...)
+ {}
+
+ template<typename TRow>
+ bool Equals(const TRow &x, const TRow &y) const {
+ return Value.Equals(x, y) && Rest.Equals(x, y);
+ }
+
+ template<typename TRowset, typename TRow>
+ void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
+ Value.ConstructFromRowset(rowset, row);
+ Rest.ConstructFromRowset(rowset, row);
+ }
+
+ template<typename TRow, typename... TArgs>
+ auto PrepareUpdateRow(const TRow &row, std::tuple<TArgs...> &&tuple) const {
+ return Rest.PrepareUpdateRow(row, Value.PrepareUpdateRow(row, std::forward<std::tuple<TArgs...>>(tuple)));
+ }
+
+ template<size_t Index, typename TUpdates, typename... TArgs>
+ static auto PopulateUpdateOp(TUpdates &updates, std::tuple<TArgs...> *tuple) {
+ TCellTuple<TCell>::template PopulateUpdateOp<Index>(updates, tuple);
+ TCellTuple<TRest...>::template PopulateUpdateOp<Index + 1>(updates, tuple);
+ }
+
+ template<typename TCallback>
+ void ForEachInlineTable(TCallback &&callback) const {
Value.ForEachInlineTable(callback);
Rest.ForEachInlineTable(callback);
- }
- };
-
-
-
-
- template<typename T1, typename T2>
- struct TConcatTuple;
-
- template<typename T1, typename... T2>
- struct TConcatTuple<TCellTuple<T1>, TCellTuple<T2...>> {
- using Type = TCellTuple<T1, T2...>;
- };
-
-
- template<typename TRow, typename... TColumns>
- struct TCreateCellTuple;
-
- template<typename TRow, typename TFirstCol>
- struct TCreateCellTuple<TRow, TFirstCol> {
- using Type = TCellTuple<typename TMapColumnToCell<TRow, TFirstCol>::Type>;
- };
-
- template<typename TRow, typename TFirstCol, typename... TRest>
- struct TCreateCellTuple<TRow, TFirstCol, TRest...>
- {
- using Type = typename TConcatTuple<
- typename TCreateCellTuple<TRow, TFirstCol>::Type,
- typename TCreateCellTuple<TRow, TRest...>::Type
- >::Type;
- };
-
- template<typename TRow, typename... T>
- struct TColumnList {
- using TCellTuple = typename TCreateCellTuple<TRow, T...>::Type;
- };
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // TABLE FETCHER
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- template<typename TKey, typename TRowset>
- auto CreateFromRowset(const TRowset &rowset) -> decltype(TKey(std::declval<TRowset>().GetKey())) {
- return TKey(rowset.GetKey());
- }
-
- template<typename TKey, typename TRowset>
- auto CreateFromRowset(const TRowset &rowset) -> decltype(TKey::CreateFromRowset(std::declval<const TRowset&>())) {
- return TKey::CreateFromRowset(rowset);
- }
-
- template<typename TTableSelector>
- auto CreateRange(TTableSelector &&table) {
- return table.Range();
- }
-
- template<size_t Index, size_t Count, typename... TArgs>
- struct TUnrollRange {
- template<typename TTableSelector, typename... TPrefix>
- static auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...> &key, TPrefix&&... prefix) {
- return TUnrollRange<Index + 1, Count, TArgs...>::CreateRange(std::forward<TTableSelector>(table),
- key, std::forward<TPrefix>(prefix)..., std::get<Index>(key));
- }
- };
-
- template<size_t Count, typename... TArgs>
- struct TUnrollRange<Count, Count, TArgs...> {
- template<typename TTableSelector, typename... TPrefix>
- static auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...>& /*key*/, TPrefix&&... prefix) {
- return table.Range(std::forward<TPrefix>(prefix)...);
- }
- };
-
- template<typename TTableSelector, typename... TArgs>
- auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...> &prefixKey) {
- return TUnrollRange<0, sizeof...(TArgs), TArgs...>::CreateRange(std::forward<TTableSelector>(table),
- prefixKey);
- }
-
- template<typename T> struct TIsTuple : std::false_type {};
- template<typename... TArgs> struct TIsTuple<std::tuple<TArgs...>> : std::true_type {};
-
- template<typename TTableSelector, typename T>
- auto CreateRange(TTableSelector &&table, const T &prefixKey) {
- return table.Range(prefixKey);
- }
-
- template<typename Table, typename TParam, typename TKey, typename... TPrefixKey>
- bool FetchTable(NIceDb::TNiceDb &db, TParam /*param*/, TSet<TKey> &data, TPrefixKey&&... prefixKey) {
- auto rowset = CreateRange(db.Table<Table>(), std::forward<TPrefixKey>(prefixKey)...).Select();
- if (!rowset.IsReady()) {
- return false;
- }
- while (rowset.IsValid()) {
- data.emplace(CreateFromRowset<TKey>(rowset));
- if (!rowset.Next()) {
- return false;
- }
- }
-
- return true;
- }
-
- template<typename Table>
- struct TConstructFromRowset {
- // use SFINAE here to prevent constructing Table from adapter of different Table; in this case generate runtime error
- template<typename TAdapter>
- using TCheckTable = typename std::enable_if<Table::TableId == TAdapter::Table::TableId>::type;
-
- template<typename TRowset, typename TRow, typename TAdapter>
- TConstructFromRowset(TRowset *rowset, TRow *item, TAdapter *adapter, TCheckTable<TAdapter>* = nullptr) {
- adapter->ConstructFromRowset(*rowset, *item);
- }
-
- TConstructFromRowset(...) {
- Y_FAIL("table mismatch");
- }
- };
-
- template<typename TRow>
- struct TRowTraits {
- using TBase = TRow;
-
- template<typename TMap, typename TKey, typename TValue>
- static void Insert(TMap& map, TKey&& key, TValue&& value) {
- map.emplace(std::forward<TKey>(key), std::forward<TValue>(value));
- }
- };
-
- template<typename TRow>
- struct TRowTraits<THolder<TRow>> {
- using TBase = TRow;
-
- template<typename TMap, typename TKey, typename TValue>
- static void Insert(TMap& map, TKey&& key, TValue&& value) {
- map.emplace(std::forward<TKey>(key), MakeHolder<TValue>(std::forward<TValue>(value)));
- }
- };
-
- template<typename Table, typename TParam, typename TKey, typename TRow, typename... TPrefixKey>
- bool FetchTable(NIceDb::TNiceDb &db, TParam param, TMap<TKey, TRow> &data, TPrefixKey&&... prefixKey) {
- using TTraits = TRowTraits<TRow>;
- using TBase = typename TTraits::TBase;
-
- auto rowset = db.Table<Table>().Range(std::forward<TPrefixKey>(prefixKey)...).Select();
- if (!rowset.IsReady()) {
- return false;
- }
- while (rowset.IsValid()) {
- TKey key = CreateFromRowset<TKey>(rowset);
-
- TBase item;
- TBase::Apply(param, [&](auto *adapter) { TConstructFromRowset<Table>(&rowset, &item, adapter); });
-
- struct TNotReady : yexception {};
-
+ }
+ };
+
+
+
+
+ template<typename T1, typename T2>
+ struct TConcatTuple;
+
+ template<typename T1, typename... T2>
+ struct TConcatTuple<TCellTuple<T1>, TCellTuple<T2...>> {
+ using Type = TCellTuple<T1, T2...>;
+ };
+
+
+ template<typename TRow, typename... TColumns>
+ struct TCreateCellTuple;
+
+ template<typename TRow, typename TFirstCol>
+ struct TCreateCellTuple<TRow, TFirstCol> {
+ using Type = TCellTuple<typename TMapColumnToCell<TRow, TFirstCol>::Type>;
+ };
+
+ template<typename TRow, typename TFirstCol, typename... TRest>
+ struct TCreateCellTuple<TRow, TFirstCol, TRest...>
+ {
+ using Type = typename TConcatTuple<
+ typename TCreateCellTuple<TRow, TFirstCol>::Type,
+ typename TCreateCellTuple<TRow, TRest...>::Type
+ >::Type;
+ };
+
+ template<typename TRow, typename... T>
+ struct TColumnList {
+ using TCellTuple = typename TCreateCellTuple<TRow, T...>::Type;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TABLE FETCHER
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template<typename TKey, typename TRowset>
+ auto CreateFromRowset(const TRowset &rowset) -> decltype(TKey(std::declval<TRowset>().GetKey())) {
+ return TKey(rowset.GetKey());
+ }
+
+ template<typename TKey, typename TRowset>
+ auto CreateFromRowset(const TRowset &rowset) -> decltype(TKey::CreateFromRowset(std::declval<const TRowset&>())) {
+ return TKey::CreateFromRowset(rowset);
+ }
+
+ template<typename TTableSelector>
+ auto CreateRange(TTableSelector &&table) {
+ return table.Range();
+ }
+
+ template<size_t Index, size_t Count, typename... TArgs>
+ struct TUnrollRange {
+ template<typename TTableSelector, typename... TPrefix>
+ static auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...> &key, TPrefix&&... prefix) {
+ return TUnrollRange<Index + 1, Count, TArgs...>::CreateRange(std::forward<TTableSelector>(table),
+ key, std::forward<TPrefix>(prefix)..., std::get<Index>(key));
+ }
+ };
+
+ template<size_t Count, typename... TArgs>
+ struct TUnrollRange<Count, Count, TArgs...> {
+ template<typename TTableSelector, typename... TPrefix>
+ static auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...>& /*key*/, TPrefix&&... prefix) {
+ return table.Range(std::forward<TPrefix>(prefix)...);
+ }
+ };
+
+ template<typename TTableSelector, typename... TArgs>
+ auto CreateRange(TTableSelector &&table, const std::tuple<TArgs...> &prefixKey) {
+ return TUnrollRange<0, sizeof...(TArgs), TArgs...>::CreateRange(std::forward<TTableSelector>(table),
+ prefixKey);
+ }
+
+ template<typename T> struct TIsTuple : std::false_type {};
+ template<typename... TArgs> struct TIsTuple<std::tuple<TArgs...>> : std::true_type {};
+
+ template<typename TTableSelector, typename T>
+ auto CreateRange(TTableSelector &&table, const T &prefixKey) {
+ return table.Range(prefixKey);
+ }
+
+ template<typename Table, typename TParam, typename TKey, typename... TPrefixKey>
+ bool FetchTable(NIceDb::TNiceDb &db, TParam /*param*/, TSet<TKey> &data, TPrefixKey&&... prefixKey) {
+ auto rowset = CreateRange(db.Table<Table>(), std::forward<TPrefixKey>(prefixKey)...).Select();
+ if (!rowset.IsReady()) {
+ return false;
+ }
+ while (rowset.IsValid()) {
+ data.emplace(CreateFromRowset<TKey>(rowset));
+ if (!rowset.Next()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ template<typename Table>
+ struct TConstructFromRowset {
+ // use SFINAE here to prevent constructing Table from adapter of different Table; in this case generate runtime error
+ template<typename TAdapter>
+ using TCheckTable = typename std::enable_if<Table::TableId == TAdapter::Table::TableId>::type;
+
+ template<typename TRowset, typename TRow, typename TAdapter>
+ TConstructFromRowset(TRowset *rowset, TRow *item, TAdapter *adapter, TCheckTable<TAdapter>* = nullptr) {
+ adapter->ConstructFromRowset(*rowset, *item);
+ }
+
+ TConstructFromRowset(...) {
+ Y_FAIL("table mismatch");
+ }
+ };
+
+ template<typename TRow>
+ struct TRowTraits {
+ using TBase = TRow;
+
+ template<typename TMap, typename TKey, typename TValue>
+ static void Insert(TMap& map, TKey&& key, TValue&& value) {
+ map.emplace(std::forward<TKey>(key), std::forward<TValue>(value));
+ }
+ };
+
+ template<typename TRow>
+ struct TRowTraits<THolder<TRow>> {
+ using TBase = TRow;
+
+ template<typename TMap, typename TKey, typename TValue>
+ static void Insert(TMap& map, TKey&& key, TValue&& value) {
+ map.emplace(std::forward<TKey>(key), MakeHolder<TValue>(std::forward<TValue>(value)));
+ }
+ };
+
+ template<typename Table, typename TParam, typename TKey, typename TRow, typename... TPrefixKey>
+ bool FetchTable(NIceDb::TNiceDb &db, TParam param, TMap<TKey, TRow> &data, TPrefixKey&&... prefixKey) {
+ using TTraits = TRowTraits<TRow>;
+ using TBase = typename TTraits::TBase;
+
+ auto rowset = db.Table<Table>().Range(std::forward<TPrefixKey>(prefixKey)...).Select();
+ if (!rowset.IsReady()) {
+ return false;
+ }
+ while (rowset.IsValid()) {
+ TKey key = CreateFromRowset<TKey>(rowset);
+
+ TBase item;
+ TBase::Apply(param, [&](auto *adapter) { TConstructFromRowset<Table>(&rowset, &item, adapter); });
+
+ struct TNotReady : yexception {};
+
auto processInlineTable = [&](auto (TRow::*member), const auto *inlineTable) {
using TInlineTable = std::remove_pointer_t<decltype(inlineTable)>;
- if (!FetchTable<TInlineTable>(db, param, item.*member, key)) {
- ythrow TNotReady();
- }
- };
- try {
+ if (!FetchTable<TInlineTable>(db, param, item.*member, key)) {
+ ythrow TNotReady();
+ }
+ };
+ try {
TBase::Apply(param, [&](auto *adapter) { adapter->ForEachInlineTable(processInlineTable); });
- } catch (const TNotReady&) {
- return false;
- }
-
- TTraits::Insert(data, std::move(key), std::move(item));
-
- if (!rowset.Next()) {
- return false;
- }
- }
-
- return true;
- }
-
- } // NTableAdapter
-
- template<typename TTable, typename TRow, typename... TColumns>
- class TTableAdapter {
- using TColumnList = NTableAdapter::TColumnList<TRow, TColumns...>;
- using TCells = typename TColumnList::TCellTuple;
-
- private:
- const TCells Cells;
-
- public:
- using Table = TTable;
-
- template<typename... TArgs>
- constexpr TTableAdapter(TArgs&&... args)
- : Cells(std::forward<TArgs>(args)...)
- {}
-
- bool Equals(const TRow &x, const TRow &y) const {
- return Cells.Equals(x, y);
- }
-
- template<typename TRowset>
- void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
- return Cells.ConstructFromRowset(rowset, row);
- }
-
- template<typename TKey>
- void IssueUpdateRow(NTabletFlatExecutor::TTransactionContext &txc, const TKey &key, const TRow &row) const {
- auto x = NTableAdapter::WrapTuple(key);
- auto keyTuple = NTableAdapter::PrepareKeyTuple<TTable>(&x);
- TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
- NTableAdapter::MapKey<TTable>(&keyTuple, keyForTable);
-
- // prepare data row in single tuple to obtain correct references in TRawTypeValue
- auto data = Cells.PrepareUpdateRow(row, std::make_tuple());
-
- // create vector of references to row cell values
- TStackVec<NTable::TUpdateOp, std::tuple_size<decltype(data)>::value> updates;
- TCells::template PopulateUpdateOp<0>(updates, &data);
-
+ } catch (const TNotReady&) {
+ return false;
+ }
+
+ TTraits::Insert(data, std::move(key), std::move(item));
+
+ if (!rowset.Next()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ } // NTableAdapter
+
+ template<typename TTable, typename TRow, typename... TColumns>
+ class TTableAdapter {
+ using TColumnList = NTableAdapter::TColumnList<TRow, TColumns...>;
+ using TCells = typename TColumnList::TCellTuple;
+
+ private:
+ const TCells Cells;
+
+ public:
+ using Table = TTable;
+
+ template<typename... TArgs>
+ constexpr TTableAdapter(TArgs&&... args)
+ : Cells(std::forward<TArgs>(args)...)
+ {}
+
+ bool Equals(const TRow &x, const TRow &y) const {
+ return Cells.Equals(x, y);
+ }
+
+ template<typename TRowset>
+ void ConstructFromRowset(const TRowset &rowset, TRow &row) const {
+ return Cells.ConstructFromRowset(rowset, row);
+ }
+
+ template<typename TKey>
+ void IssueUpdateRow(NTabletFlatExecutor::TTransactionContext &txc, const TKey &key, const TRow &row) const {
+ auto x = NTableAdapter::WrapTuple(key);
+ auto keyTuple = NTableAdapter::PrepareKeyTuple<TTable>(&x);
+ TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
+ NTableAdapter::MapKey<TTable>(&keyTuple, keyForTable);
+
+ // prepare data row in single tuple to obtain correct references in TRawTypeValue
+ auto data = Cells.PrepareUpdateRow(row, std::make_tuple());
+
+ // create vector of references to row cell values
+ TStackVec<NTable::TUpdateOp, std::tuple_size<decltype(data)>::value> updates;
+ TCells::template PopulateUpdateOp<0>(updates, &data);
+
txc.DB.Update(TTable::TableId, NTable::ERowOp::Upsert, keyForTable, updates);
- }
-
- template<typename TKey>
- void IssueEraseRow(NTabletFlatExecutor::TTransactionContext &txc, const TKey &key) const {
- auto x = NTableAdapter::WrapTuple(key);
- auto keyTuple = NTableAdapter::PrepareKeyTuple<TTable>(&x);
- TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
- NTableAdapter::MapKey<TTable>(&keyTuple, keyForTable);
-
+ }
+
+ template<typename TKey>
+ void IssueEraseRow(NTabletFlatExecutor::TTransactionContext &txc, const TKey &key) const {
+ auto x = NTableAdapter::WrapTuple(key);
+ auto keyTuple = NTableAdapter::PrepareKeyTuple<TTable>(&x);
+ TStackVec<TRawTypeValue, std::tuple_size<decltype(keyTuple)>::value> keyForTable;
+ NTableAdapter::MapKey<TTable>(&keyTuple, keyForTable);
+
txc.DB.Update(TTable::TableId, NTable::ERowOp::Erase, keyForTable, { });
- }
-
- template<typename TCallback>
- void ForEachInlineTable(TCallback &&callback) const {
+ }
+
+ template<typename TCallback>
+ void ForEachInlineTable(TCallback &&callback) const {
Cells.ForEachInlineTable(std::forward<TCallback>(callback));
- }
- };
-
-} // NKikimr
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/mind/tenant_node_enumeration_ut.cpp b/ydb/core/mind/tenant_node_enumeration_ut.cpp
index f8c7a505c29..76e431aeb3b 100644
--- a/ydb/core/mind/tenant_node_enumeration_ut.cpp
+++ b/ydb/core/mind/tenant_node_enumeration_ut.cpp
@@ -40,8 +40,8 @@ void CheckAddTenant(TTenantTestRuntime &runtime, const TString &tenant, TEvLocal
Y_UNIT_TEST_SUITE(TEnumerationTest) {
Y_UNIT_TEST(TestPublish) {
- return;
-
+ return;
+
TTenantTestRuntime runtime(DefaultTenantTestConfig);
CheckAddTenant(runtime, TENANT1_1_NAME, TEvLocal::TEvTenantStatus::STARTED, 5);
@@ -53,13 +53,13 @@ Y_UNIT_TEST_SUITE(TEnumerationTest) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
{TENANT1_1_NAME, 5, 1, 1},
- {TENANT1_2_NAME, 1, 1, 1}}});
+ {TENANT1_2_NAME, 1, 1, 1}}});
runtime.Register(CreateTenantNodeEnumerationPublisher(), 0);
runtime.DispatchEvents(TDispatchOptions(), TDuration::MilliSeconds(1000));
TActorId sender = runtime.AllocateEdgeActor();
- runtime.Register(CreateTenantNodeEnumerationLookup(sender, "/" + DOMAIN1_NAME));
+ runtime.Register(CreateTenantNodeEnumerationLookup(sender, "/" + DOMAIN1_NAME));
TAutoPtr<IEventHandle> handle;
const auto event = runtime.GrabEdgeEvent<TEvTenantNodeEnumerator::TEvLookupResult>(handle);
diff --git a/ydb/core/mind/tenant_pool.cpp b/ydb/core/mind/tenant_pool.cpp
index 80236570b9e..96bbbbb5259 100644
--- a/ydb/core/mind/tenant_pool.cpp
+++ b/ydb/core/mind/tenant_pool.cpp
@@ -129,9 +129,9 @@ class TDomainTenantPool : public TActorBootstrapped<TDomainTenantPool> {
THashSet<TActorId> StatusSubscribers;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::TENANT_POOL_ACTOR;
+ return NKikimrServices::TActivity::TENANT_POOL_ACTOR;
}
TDomainTenantPool(const TString &domain, TActorId localID, TTenantPoolConfig::TPtr config)
@@ -793,9 +793,9 @@ class TTenantPool : public TActorBootstrapped<TTenantPool> {
const TString DomainPrefix;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::TENANT_POOL_ACTOR;
+ return NKikimrServices::TActivity::TENANT_POOL_ACTOR;
}
TTenantPool(TTenantPoolConfig::TPtr config)
diff --git a/ydb/core/mind/tenant_slot_broker.cpp b/ydb/core/mind/tenant_slot_broker.cpp
index 65f7a86328b..cd5a0e228f8 100644
--- a/ydb/core/mind/tenant_slot_broker.cpp
+++ b/ydb/core/mind/tenant_slot_broker.cpp
@@ -25,13 +25,13 @@ bool TTenantSlotBroker::TSlotsAllocation::IsSlotOk(const TString &type,
&& Description.SlotType != ANY_SLOT_TYPE)
return false;
if (dc != Description.DataCenter
- && Description.DataCenter != ANY_DATA_CENTER) {
+ && Description.DataCenter != ANY_DATA_CENTER) {
if (strictMatch || Description.ForceLocation)
return false;
}
if (Group) {
if (Group->GetPreferredDataCenter() != dc
- && Group->GetPreferredDataCenter() != ANY_DATA_CENTER) {
+ && Group->GetPreferredDataCenter() != ANY_DATA_CENTER) {
if (strictMatch || Description.ForceCollocation)
return false;
}
@@ -60,7 +60,7 @@ void TTenantSlotBroker::TTenant::AddSlotsAllocation(const TSlotDescription &desc
TSlotsAllocation::TPtr allocation = new TSlotsAllocation(descr, Stats);
Allocations[descr] = allocation;
if (descr.CollocationGroup
- && (descr.DataCenter == ANY_DATA_CENTER
+ && (descr.DataCenter == ANY_DATA_CENTER
|| !descr.ForceLocation)) {
auto group = GetOrCreateCollocationGroup(descr.CollocationGroup);
group->Allocations.insert(allocation);
@@ -120,7 +120,7 @@ void TTenantSlotBroker::TTenant::DetermineDataCenterForCollocationGroups()
for (auto allocation : pr.second->Allocations) {
for (auto slot : allocation->AssignedSlots) {
- if (slot->DataCenter != ANY_DATA_CENTER)
+ if (slot->DataCenter != ANY_DATA_CENTER)
slots[slot->DataCenter] += 1;
}
}
@@ -380,11 +380,11 @@ TTenantSlotBroker::TSlot::TPtr TTenantSlotBroker::TFreeSlotsIndex::FindByDC(cons
TTenantSlotBroker::TSlot::TPtr TTenantSlotBroker::TFreeSlotsIndex::Find(const TString &type,
const TString &dataCenter)
{
- if (type == ANY_SLOT_TYPE && dataCenter == ANY_DATA_CENTER)
+ if (type == ANY_SLOT_TYPE && dataCenter == ANY_DATA_CENTER)
return Find();
if (type == ANY_SLOT_TYPE)
return FindByDC(dataCenter);
- if (dataCenter == ANY_DATA_CENTER)
+ if (dataCenter == ANY_DATA_CENTER)
return FindByType(type);
auto it1 = FreeSlotsByType.find(type);
@@ -817,7 +817,7 @@ bool TTenantSlotBroker::UpdateSlotDataCenter(TSlot::TPtr slot,
// Check if slot has to be detached due to updated data center.
if (slot->AssignedTenant
&& !slot->IsPinned
- && (slot->UsedAs.DataCenter != ANY_DATA_CENTER
+ && (slot->UsedAs.DataCenter != ANY_DATA_CENTER
|| slot->UsedAs.CollocationGroup)) {
DetachSlot(slot, txc, ctx);
res = true;
@@ -964,7 +964,7 @@ void TTenantSlotBroker::DetachSlotNoConfigureNoDb(TSlot::TPtr slot,
if (slot->IsPending())
allocation->DecPending();
allocation->IncMissing();
- if (allocation->Description.DataCenter != ANY_DATA_CENTER
+ if (allocation->Description.DataCenter != ANY_DATA_CENTER
&& allocation->Description.DataCenter != slot->DataCenter)
allocation->DecMisplaced();
if (allocation->Group
@@ -1029,7 +1029,7 @@ void TTenantSlotBroker::AttachSlotNoConfigureNoDb(TSlot::TPtr slot,
auto allocation = tenant->GetAllocation(usedAs);
allocation->AddAssignedSlot(slot);
allocation->DecMissing();
- if (allocation->Description.DataCenter != ANY_DATA_CENTER
+ if (allocation->Description.DataCenter != ANY_DATA_CENTER
&& allocation->Description.DataCenter != slot->DataCenter)
allocation->IncMisplaced();
if (allocation->Group
@@ -1150,7 +1150,7 @@ bool TTenantSlotBroker::AssignFreeSlots(TTenant::TPtr tenant,
// Try to find slot in another data center if allowed.
if (!freeSlot && !allocation->Description.ForceLocation)
freeSlot = FreeSlots.Find(allocation->Description.SlotType,
- ANY_DATA_CENTER);
+ ANY_DATA_CENTER);
if (!freeSlot)
break;
@@ -1217,7 +1217,7 @@ TTenantSlotBroker::ComputeLayoutForGroup(TCollocationGroup::TPtr group,
for (auto allocation : group->Allocations) {
auto &assigned = layout->AssignedSlots[allocation];
- if (allocation->Description.DataCenter != ANY_DATA_CENTER
+ if (allocation->Description.DataCenter != ANY_DATA_CENTER
&& allocation->Description.DataCenter != dc)
continue;
@@ -1236,7 +1236,7 @@ TTenantSlotBroker::ComputeLayoutForGroup(TCollocationGroup::TPtr group,
for (auto allocation : group->Allocations) {
auto &assigned = layout->AssignedSlots[allocation];
- if (allocation->Description.DataCenter == ANY_DATA_CENTER
+ if (allocation->Description.DataCenter == ANY_DATA_CENTER
|| allocation->Description.DataCenter == dc)
continue;
@@ -1274,10 +1274,10 @@ TTenantSlotBroker::ComputeLayoutForGroup(TCollocationGroup::TPtr group,
while (assigned.size() < allocation->RequiredCount) {
auto slot = ExtractSlot(current, index, allocation->Description.SlotType,
- ANY_DATA_CENTER);
+ ANY_DATA_CENTER);
if (slot) {
assigned.insert(slot);
- if (allocation->Description.DataCenter != ANY_DATA_CENTER
+ if (allocation->Description.DataCenter != ANY_DATA_CENTER
&& allocation->Description.DataCenter != slot->DataCenter)
++layout->MisplacedCount;
Y_VERIFY(slot->DataCenter != dc);
@@ -1370,7 +1370,7 @@ bool TTenantSlotBroker::AssignFreeSlotsForGroup(TTenant::TPtr tenant,
currentMissing += allocation->MissingCount;
currentMisplaced += allocation->MisplacedCount;
currentSplit += allocation->SplitCount;
- if (allocation->Description.DataCenter != ANY_DATA_CENTER) {
+ if (allocation->Description.DataCenter != ANY_DATA_CENTER) {
Y_VERIFY(!allocation->Description.ForceLocation);
preferredDCs.insert(allocation->Description.DataCenter);
}
diff --git a/ydb/core/mind/tenant_slot_broker.h b/ydb/core/mind/tenant_slot_broker.h
index 922924fb14d..975634bac8c 100644
--- a/ydb/core/mind/tenant_slot_broker.h
+++ b/ydb/core/mind/tenant_slot_broker.h
@@ -7,7 +7,7 @@
namespace NKikimr {
namespace NTenantSlotBroker {
-static const TString ANY_DATA_CENTER = "";
+static const TString ANY_DATA_CENTER = "";
constexpr char ANY_SLOT_TYPE[] = "";
constexpr char PIN_DATA_CENTER[] = "pinned";
diff --git a/ydb/core/mind/tenant_slot_broker__alter_tenant.cpp b/ydb/core/mind/tenant_slot_broker__alter_tenant.cpp
index 6b3066e7d7f..5ab5a18691e 100644
--- a/ydb/core/mind/tenant_slot_broker__alter_tenant.cpp
+++ b/ydb/core/mind/tenant_slot_broker__alter_tenant.cpp
@@ -40,7 +40,7 @@ public:
continue;
} else if (onlyMisplaced) {
Y_VERIFY(!onlySplit);
- Y_VERIFY(allocation->Description.DataCenter != ANY_DATA_CENTER);
+ Y_VERIFY(allocation->Description.DataCenter != ANY_DATA_CENTER);
if (!allocation->MisplacedCount)
return;
if (slot->DataCenter == allocation->Description.DataCenter)
diff --git a/ydb/core/mind/tenant_slot_broker__update_node_location.cpp b/ydb/core/mind/tenant_slot_broker__update_node_location.cpp
index 3ed528dcbc3..385ffe30fb3 100644
--- a/ydb/core/mind/tenant_slot_broker__update_node_location.cpp
+++ b/ydb/core/mind/tenant_slot_broker__update_node_location.cpp
@@ -24,7 +24,7 @@ public:
if (!nodeInfo)
return true;
- auto dc = nodeInfo->Location.GetDataCenterId();
+ auto dc = nodeInfo->Location.GetDataCenterId();
if (Self->NodeIdToDataCenter.contains(nodeId)
&& Self->NodeIdToDataCenter[nodeId] == dc)
diff --git a/ydb/core/mind/tenant_slot_broker__update_pool_status.cpp b/ydb/core/mind/tenant_slot_broker__update_pool_status.cpp
index 1e43062762c..6c0845aff12 100644
--- a/ydb/core/mind/tenant_slot_broker__update_pool_status.cpp
+++ b/ydb/core/mind/tenant_slot_broker__update_pool_status.cpp
@@ -21,7 +21,7 @@ public:
LOG_DEBUG_S(ctx, NKikimrServices::TENANT_SLOT_BROKER, "TTxUpdatePoolStatus execute for node " << nodeId);
- TString dc = ANY_DATA_CENTER;
+ TString dc = ANY_DATA_CENTER;
if (Self->NodeIdToDataCenter.contains(nodeId))
dc = Self->NodeIdToDataCenter[nodeId];
diff --git a/ydb/core/mind/tenant_slot_broker_impl.h b/ydb/core/mind/tenant_slot_broker_impl.h
index b5e3b107ab5..b4c38851205 100644
--- a/ydb/core/mind/tenant_slot_broker_impl.h
+++ b/ydb/core/mind/tenant_slot_broker_impl.h
@@ -92,7 +92,7 @@ struct TSlotDescription {
TSlotDescription(const NKikimrTenantSlotBroker::TSlotAllocation &slot)
{
SlotType = slot.GetType();
- DataCenter = slot.HasDataCenter() ? slot.GetDataCenter() : DataCenterToString(slot.GetDataCenterNum());
+ DataCenter = slot.HasDataCenter() ? slot.GetDataCenter() : DataCenterToString(slot.GetDataCenterNum());
ForceLocation = slot.GetForceLocation();
CollocationGroup = slot.GetCollocationGroup();
ForceCollocation = slot.GetForceCollocation();
@@ -121,8 +121,8 @@ struct TSlotDescription {
void Serialize(NKikimrTenantSlotBroker::TSlotAllocation &slot) const
{
slot.SetType(SlotType);
- slot.SetDataCenterNum(DataCenterFromString(DataCenter));
- slot.SetDataCenter(DataCenter);
+ slot.SetDataCenterNum(DataCenterFromString(DataCenter));
+ slot.SetDataCenter(DataCenter);
slot.SetForceLocation(ForceLocation);
slot.SetCollocationGroup(CollocationGroup);
slot.SetForceCollocation(ForceCollocation);
@@ -1144,9 +1144,9 @@ public:
ClearState();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType()
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType()
{
- return NKikimrServices::TActivity::TENANT_SLOT_BROKER_ACTOR;
+ return NKikimrServices::TActivity::TENANT_SLOT_BROKER_ACTOR;
}
private:
diff --git a/ydb/core/mind/tenant_ut_broker.cpp b/ydb/core/mind/tenant_ut_broker.cpp
index 4c124b3d83b..930485b0db4 100644
--- a/ydb/core/mind/tenant_ut_broker.cpp
+++ b/ydb/core/mind/tenant_ut_broker.cpp
@@ -19,9 +19,9 @@ using namespace NTenantSlotBroker;
namespace {
-static const TString DATA_CENTER1 = ToString(1);
-static const TString DATA_CENTER2 = ToString(2);
-static const TString DATA_CENTER3 = ToString(3);
+static const TString DATA_CENTER1 = ToString(1);
+static const TString DATA_CENTER2 = ToString(2);
+static const TString DATA_CENTER3 = ToString(3);
const TString SLOT1 = "slot-1";
const TString SLOT2 = "slot-2";
@@ -260,20 +260,20 @@ struct TSlotRequest {
TSlotCount Count;
TSlotRequest(const TString &type,
- TString dc,
+ TString dc,
ui64 required,
ui64 pending,
ui64 missing,
ui64 misplaced = 0,
ui64 split = 0,
ui64 pinned = 0)
- : Description(type, dc)
+ : Description(type, dc)
, Count(required, pending, missing, misplaced, split, pinned)
{
}
TSlotRequest(const TString &type,
- TString dc,
+ TString dc,
bool forceLocation,
ui32 group,
bool forceCollocation,
@@ -283,7 +283,7 @@ struct TSlotRequest {
ui64 misplaced,
ui64 split,
ui64 pinned = 0)
- : Description(type, dc, forceLocation, group, forceCollocation)
+ : Description(type, dc, forceLocation, group, forceCollocation)
, Count(required, pending, missing, misplaced, split, pinned)
{
}
@@ -293,13 +293,13 @@ void CollectRequests(TVector<TSlotRequest> &)
{
}
-void CollectRequests(TVector<TSlotRequest> &requests, const TString &type, TString dataCenter, ui64 required, ui64 pending, ui64 missing)
+void CollectRequests(TVector<TSlotRequest> &requests, const TString &type, TString dataCenter, ui64 required, ui64 pending, ui64 missing)
{
requests.push_back({type, dataCenter, required, pending, missing});
}
template <typename ...Ts>
-void CollectRequests(TVector<TSlotRequest> &requests, const TString &type, TString dataCenter, ui64 required, ui64 pending, ui64 missing,
+void CollectRequests(TVector<TSlotRequest> &requests, const TString &type, TString dataCenter, ui64 required, ui64 pending, ui64 missing,
Ts... args)
{
CollectRequests(requests, type, dataCenter, required, pending, missing);
@@ -880,28 +880,28 @@ Y_UNIT_TEST_SUITE(TTenantSlotBrokerTests) {
if (tsb) {
auto slot = tsb->GetSubgroup("SlotType", SLOT1_TYPE);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("FreeSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("AssignedSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("ConnectedSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("DisconnectedSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("RequiredSlots")->Val(), 9);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("MissingSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", ANY_DATA_CENTER)
->GetCounter("PendingSlots")->Val(), 0);
- for (auto &dc : TVector<TString>({DATA_CENTER1, DATA_CENTER2, DATA_CENTER3})) {
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
+ for (auto &dc : TVector<TString>({DATA_CENTER1, DATA_CENTER2, DATA_CENTER3})) {
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
->GetCounter("FreeSlots")->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
->GetCounter("AssignedSlots")->Val(), 3);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
->GetCounter("ConnectedSlots")->Val(), 3);
- UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
+ UNIT_ASSERT_VALUES_EQUAL(slot->GetSubgroup("SlotDataCenter", dc)
->GetCounter("DisconnectedSlots")->Val(), 0);
}
break;
@@ -1148,7 +1148,7 @@ Y_UNIT_TEST_SUITE(TTenantSlotBrokerTests) {
TVector<TString> type = {SLOT1_TYPE, SLOT2_TYPE, SLOT3_TYPE};
TVector<ui64> size = {1, 2, 3};
- TVector<TString> dc = {DATA_CENTER1, DATA_CENTER2, DATA_CENTER3};
+ TVector<TString> dc = {DATA_CENTER1, DATA_CENTER2, DATA_CENTER3};
TVector<TString> tenants = {TENANT1_1_NAME, TENANT1_2_NAME, TENANT1_3_NAME, TENANT1_4_NAME};
for (int i = 0; i < NITERS; ++i) {
TVector<TVector<ui64>> freeSlots = { {{3, 3, 3}}, {{3, 3, 3}}, {{3, 3, 3}} };
@@ -1486,24 +1486,24 @@ Y_UNIT_TEST_SUITE(TTenantSlotBrokerTests) {
slots[std::make_pair(rec.GetType(), rec.GetDataCenter())]
= std::make_pair(rec.GetConnected(), rec.GetFree());
UNIT_ASSERT_VALUES_EQUAL(slots.size(), 9);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER1)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER1)].second, 0);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER2)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER2)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER3)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER3)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER1)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER1)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER2)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER2)].second, 1);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER3)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER3)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER1)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER1)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER2)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER2)].second, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER3)].first, 3);
- UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER3)].second, 2);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER1)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER1)].second, 0);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER2)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER2)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER3)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT1_TYPE, DATA_CENTER3)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER1)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER1)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER2)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER2)].second, 1);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER3)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT2_TYPE, DATA_CENTER3)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER1)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER1)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER2)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER2)].second, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER3)].first, 3);
+ UNIT_ASSERT_VALUES_EQUAL(slots[std::make_pair(SLOT3_TYPE, DATA_CENTER3)].second, 2);
}
Y_UNIT_TEST(TestRandomActions) {
@@ -1524,7 +1524,7 @@ Y_UNIT_TEST_SUITE(TTenantSlotBrokerTests) {
TVector<TString> slots = {SLOT1, SLOT2, SLOT3};
TVector<TString> tenants = {TENANT1_1_NAME, TENANT1_2_NAME, TENANT1_3_NAME};
TVector<TString> types = {SLOT1_TYPE, SLOT2_TYPE, SLOT3_TYPE, ANY_SLOT_TYPE};
- TVector<TString> dcs = {DATA_CENTER1, DATA_CENTER2, DATA_CENTER3, ANY_DATA_CENTER};
+ TVector<TString> dcs = {DATA_CENTER1, DATA_CENTER2, DATA_CENTER3, ANY_DATA_CENTER};
for (int i = 0; i < 1000; ++i) {
EAction action = actions[RandomNumber<ui64>(actions.size())];
diff --git a/ydb/core/mind/tenant_ut_local.cpp b/ydb/core/mind/tenant_ut_local.cpp
index 5aab98212de..26f35005b61 100644
--- a/ydb/core/mind/tenant_ut_local.cpp
+++ b/ydb/core/mind/tenant_ut_local.cpp
@@ -69,7 +69,7 @@ Y_UNIT_TEST_SUITE(TLocalTests) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
{TENANT1_1_NAME, 5, 1, 1},
- {TENANT1_2_NAME, 1, 1, 1}}});
+ {TENANT1_2_NAME, 1, 1, 1}}});
}
Y_UNIT_TEST(TestAlterTenant) {
@@ -81,7 +81,7 @@ Y_UNIT_TEST_SUITE(TLocalTests) {
CheckAlterTenant(runtime, TENANT1_U_NAME, TEvLocal::TEvTenantStatus::STOPPED);
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
- {TENANT1_1_NAME, 10, 10, 10}}});
+ {TENANT1_1_NAME, 10, 10, 10}}});
}
Y_UNIT_TEST(TestAddTenantWhileResolving) {
@@ -125,7 +125,7 @@ Y_UNIT_TEST_SUITE(TLocalTests) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
{TENANT1_1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 1, 1, 1}}});
+ {TENANT1_2_NAME, 1, 1, 1}}});
}
Y_UNIT_TEST(TestRemoveTenantWhileResolving) {
@@ -169,7 +169,7 @@ Y_UNIT_TEST_SUITE(TLocalTests) {
UNIT_ASSERT(reply3->Status == TEvLocal::TEvTenantStatus::STARTED);
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 1, 1, 1}}});
+ {TENANT1_2_NAME, 1, 1, 1}}});
}
}
diff --git a/ydb/core/mind/tenant_ut_pool.cpp b/ydb/core/mind/tenant_ut_pool.cpp
index 9ac6b6843c3..e2018606593 100644
--- a/ydb/core/mind/tenant_ut_pool.cpp
+++ b/ydb/core/mind/tenant_ut_pool.cpp
@@ -136,7 +136,7 @@ void CheckConfigureSlot(TTenantTestRuntime &runtime, ui32 domain,
}
void CheckTenantPoolStatus(TTenantTestRuntime &runtime,
- const TString &d1s1 = "", const TString &d1s2 = "", const TString &d1s3 = "")
+ const TString &d1s1 = "", const TString &d1s2 = "", const TString &d1s3 = "")
{
THashMap<TString, NKikimrTenantPool::TSlotStatus> domain1;
domain1[DOMAIN1_SLOT1] = MakeSlotStatus(DOMAIN1_SLOT1, SLOT1_TYPE, d1s1, 1, 1, 1);
@@ -282,9 +282,9 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
{TENANT1_1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 2, 2, 2}}});
+ {TENANT1_2_NAME, 2, 2, 2}}});
- CheckTenantPoolStatus(runtime, TENANT1_1_NAME, TENANT1_2_NAME, "");
+ CheckTenantPoolStatus(runtime, TENANT1_1_NAME, TENANT1_2_NAME, "");
}
Y_UNIT_TEST(TestAssignTenantStatic) {
@@ -293,10 +293,10 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
CheckConfigureSlot(runtime, 0,
DOMAIN1_SLOT1, DOMAIN1_NAME, NKikimrTenantPool::SUCCESS);
- runtime.WaitForHiveState({{{DOMAIN1_NAME, 2, 2, 2}}});
+ runtime.WaitForHiveState({{{DOMAIN1_NAME, 2, 2, 2}}});
CheckTenantPoolStatus(runtime,
- DOMAIN1_NAME, "", "");
+ DOMAIN1_NAME, "", "");
}
Y_UNIT_TEST(TestAssignTenantMultiple) {
@@ -310,7 +310,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
DOMAIN1_SLOT3, TENANT1_1_NAME, NKikimrTenantPool::SUCCESS);
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
- {TENANT1_1_NAME, 6, 6, 6}}});
+ {TENANT1_1_NAME, 6, 6, 6}}});
CheckTenantPoolStatus(runtime,
TENANT1_1_NAME, TENANT1_1_NAME, TENANT1_1_NAME);
@@ -332,7 +332,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 4, 4, 4},
{TENANT1_1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 2, 2, 2}}});
+ {TENANT1_2_NAME, 2, 2, 2}}});
CheckTenantPoolStatus(runtime,
TENANT1_1_NAME, TENANT1_2_NAME, DOMAIN1_NAME);
@@ -357,7 +357,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
DOMAIN1_SLOT3, "", NKikimrTenantPool::SUCCESS);
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
- {TENANT1_1_NAME, 1, 1, 1}}});
+ {TENANT1_1_NAME, 1, 1, 1}}});
CheckTenantPoolStatus(runtime,
TENANT1_1_NAME, "", "");
@@ -369,7 +369,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
CheckConfigureSlot(runtime, 0,
DOMAIN1_SLOT1, TENANT1_U_NAME, NKikimrTenantPool::UNKNOWN_TENANT);
- runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1}}});
+ runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1}}});
CheckTenantPoolStatus(runtime);
}
@@ -390,7 +390,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
{TENANT1_1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 2, 2, 2}}});
+ {TENANT1_2_NAME, 2, 2, 2}}});
CheckTenantPoolStatus(runtime,
TENANT1_1_NAME, TENANT1_2_NAME, "");
@@ -447,7 +447,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
UNIT_ASSERT_VALUES_EQUAL((int)reply4->Record.GetStatus(), (int)NKikimrTenantPool::SUCCESS);
runtime.WaitForHiveState({{{DOMAIN1_NAME, 1, 1, 1},
- {TENANT1_2_NAME, 3, 3, 3}}});
+ {TENANT1_2_NAME, 3, 3, 3}}});
CheckTenantPoolStatus(runtime,
TENANT1_2_NAME, TENANT1_2_NAME, "");
@@ -456,7 +456,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
Y_UNIT_TEST(TestSensorLabels) {
const TTenantTestConfig config = {
// Domains {name, schemeshard {{ subdomain_names }}}
- {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
+ {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
// HiveId
HIVE_ID,
// FakeTenantSlotBroker
@@ -543,7 +543,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
Y_UNIT_TEST(TestForcedSensorLabels) {
const TTenantTestConfig config = {
// Domains {name, schemeshard {{ subdomain_names }}}
- {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
+ {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
// HiveId
HIVE_ID,
// FakeTenantSlotBroker
@@ -649,7 +649,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
Y_UNIT_TEST(TestSensorLabelsForStaticConfig) {
const TTenantTestConfig config = {
// Domains {name, schemeshard {{ subdomain_names }}}
- {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
+ {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
// HiveId
HIVE_ID,
// FakeTenantSlotBroker
@@ -789,7 +789,7 @@ Y_UNIT_TEST_SUITE(TTenantPoolTests) {
Y_UNIT_TEST(TestForcedSensorLabelsForStaticConfig) {
const TTenantTestConfig config = {
// Domains {name, schemeshard {{ subdomain_names }}}
- {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
+ {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
// HiveId
HIVE_ID,
// FakeTenantSlotBroker
diff --git a/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp b/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
index 011f03d93cd..f30aaa1f00d 100644
--- a/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
+++ b/ydb/core/mind/ut_fat/blobstorage_node_warden_ut_fat.cpp
@@ -192,10 +192,10 @@ void SetupServices(TTestActorRuntime &runtime) {
// nodeWardenConfig->Monitoring = monitoring;
google::protobuf::TextFormat::ParseFromString(staticConfig, &nodeWardenConfig->ServiceSet);
- app.SetKeyForNode(keyfile, nodeIndex);
- ObtainTenantKey(&nodeWardenConfig->TenantKey, app.Keys[nodeIndex]);
- ObtainStaticKey(&nodeWardenConfig->StaticKey);
-
+ app.SetKeyForNode(keyfile, nodeIndex);
+ ObtainTenantKey(&nodeWardenConfig->TenantKey, app.Keys[nodeIndex]);
+ ObtainStaticKey(&nodeWardenConfig->StaticKey);
+
if (nodeIndex == 0) {
static TTempDir tempDir;
TString pDiskPath = tempDir() + "/pdisk0.dat";
@@ -253,62 +253,62 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
}
void CreatePDiskInBox(TTestActorRuntime& runtime, const TActorId& sender, ui32 nodeId, ui64 boxId, TString pdiskPath,
- std::optional<ui64> size) {
- if (size) {
- TFile file(pdiskPath, CreateAlways | RdWr | ARW);
- file.Resize(0);
- file.Resize(*size);
- file.Close();
- }
-
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- auto& record = ev->Record;
- auto *request = record.MutableRequest();
- auto *cmd1 = request->AddCommand()->MutableDefineHostConfig();
- cmd1->SetHostConfigId(boxId);
- auto *drive = cmd1->AddDrive();
- drive->SetPath(pdiskPath);
- drive->SetType(NKikimrBlobStorage::ROT);
- drive->MutablePDiskConfig()->SetChunkSize(32 << 20); // 16 MB
- auto *cmd2 = request->AddCommand()->MutableDefineBox();
- cmd2->SetBoxId(boxId);
- auto *host = cmd2->AddHost();
- host->MutableKey()->SetNodeId(nodeId);
- host->SetHostConfigId(boxId);
- runtime.SendToPipe(GetBsc(runtime), sender, ev.Release(), sender.NodeId() - runtime.GetNodeId(0), GetPipeConfigWithRetries());
+ std::optional<ui64> size) {
+ if (size) {
+ TFile file(pdiskPath, CreateAlways | RdWr | ARW);
+ file.Resize(0);
+ file.Resize(*size);
+ file.Close();
+ }
+
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto& record = ev->Record;
+ auto *request = record.MutableRequest();
+ auto *cmd1 = request->AddCommand()->MutableDefineHostConfig();
+ cmd1->SetHostConfigId(boxId);
+ auto *drive = cmd1->AddDrive();
+ drive->SetPath(pdiskPath);
+ drive->SetType(NKikimrBlobStorage::ROT);
+ drive->MutablePDiskConfig()->SetChunkSize(32 << 20); // 16 MB
+ auto *cmd2 = request->AddCommand()->MutableDefineBox();
+ cmd2->SetBoxId(boxId);
+ auto *host = cmd2->AddHost();
+ host->MutableKey()->SetNodeId(nodeId);
+ host->SetHostConfigId(boxId);
+ runtime.SendToPipe(GetBsc(runtime), sender, ev.Release(), sender.NodeId() - runtime.GetNodeId(0), GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handle;
- auto res = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handle);
- UNIT_ASSERT(res);
- UNIT_ASSERT_C(res->Record.GetResponse().GetSuccess(), res->Record.GetResponse().GetErrorDescription().data());
+ auto res = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handle);
+ UNIT_ASSERT(res);
+ UNIT_ASSERT_C(res->Record.GetResponse().GetSuccess(), res->Record.GetResponse().GetErrorDescription().data());
}
ui32 CreateGroupInBox(TTestActorRuntime& runtime, const TActorId& sender, ui64 boxId, ui64 poolId,
ui32 encryptionMode) {
- auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
- auto& record = ev->Record;
- auto *request = record.MutableRequest();
- auto *cmd = request->AddCommand()->MutableDefineStoragePool();
- cmd->SetBoxId(boxId);
- cmd->SetStoragePoolId(poolId);
+ auto ev = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto& record = ev->Record;
+ auto *request = record.MutableRequest();
+ auto *cmd = request->AddCommand()->MutableDefineStoragePool();
+ cmd->SetBoxId(boxId);
+ cmd->SetStoragePoolId(poolId);
cmd->SetEncryptionMode(encryptionMode);
- cmd->SetErasureSpecies("none");
- cmd->SetVDiskKind("Default");
- cmd->SetNumGroups(1);
- cmd->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
- request->AddCommand()->MutableQueryBaseConfig();
- runtime.SendToPipe(GetBsc(runtime), sender, ev.Release(), sender.NodeId() - runtime.GetNodeId(0), GetPipeConfigWithRetries());
+ cmd->SetErasureSpecies("none");
+ cmd->SetVDiskKind("Default");
+ cmd->SetNumGroups(1);
+ cmd->AddPDiskFilter()->AddProperty()->SetType(NKikimrBlobStorage::ROT);
+ request->AddCommand()->MutableQueryBaseConfig();
+ runtime.SendToPipe(GetBsc(runtime), sender, ev.Release(), sender.NodeId() - runtime.GetNodeId(0), GetPipeConfigWithRetries());
TAutoPtr<IEventHandle> handle;
- auto res = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handle);
- UNIT_ASSERT(res);
- UNIT_ASSERT_C(res->Record.GetResponse().GetSuccess(), res->Record.GetResponse().GetErrorDescription().data());
- for (const auto& gr : res->Record.GetResponse().GetStatus(1).GetBaseConfig().GetGroup()) {
- if (gr.GetBoxId() == boxId && gr.GetStoragePoolId() == poolId) {
- return gr.GetGroupId();
+ auto res = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvControllerConfigResponse>(handle);
+ UNIT_ASSERT(res);
+ UNIT_ASSERT_C(res->Record.GetResponse().GetSuccess(), res->Record.GetResponse().GetErrorDescription().data());
+ for (const auto& gr : res->Record.GetResponse().GetStatus(1).GetBaseConfig().GetGroup()) {
+ if (gr.GetBoxId() == boxId && gr.GetStoragePoolId() == poolId) {
+ return gr.GetGroupId();
}
}
- return 0;
+ return 0;
}
void Put(TTestActorRuntime &runtime, TActorId &sender, ui32 groupId, TLogoBlobID logoBlobId, TString data) {
@@ -366,7 +366,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
TEvBlobStorage::TEvVGet::EFlags::None,
cookie,
{id});
- runtime.Send(new IEventHandle(vDiskActor, sender, x.release()), sender.NodeId() - runtime.GetNodeId(0));
+ runtime.Send(new IEventHandle(vDiskActor, sender, x.release()), sender.NodeId() - runtime.GetNodeId(0));
TAutoPtr<IEventHandle> handle;
auto vgetResult = runtime.GrabEdgeEventRethrow<TEvBlobStorage::TEvVGetResult>(handle);
@@ -392,9 +392,9 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) {
TActorId sender0 = runtime.AllocateEdgeActor(0);
TActorId sender1 = runtime.AllocateEdgeActor(1);
- CreatePDiskInBox(runtime, sender0, runtime.GetNodeId(0), 1, TFsPath(tempDir()) / "new_pdisk.dat", 16ULL << 30);
+ CreatePDiskInBox(runtime, sender0, runtime.GetNodeId(0), 1, TFsPath(tempDir()) / "new_pdisk.dat", 16ULL << 30);
const ui32 groupId = CreateGroupInBox(runtime, sender0, 1, 1, 0);
- UNIT_ASSERT(groupId != 0);
+ UNIT_ASSERT(groupId != 0);
Put(runtime, sender0, groupId, TLogoBlobID(100, 0, 0, 0, 3, 0), "xxx");
Get(runtime, sender0, groupId, TLogoBlobID(100, 0, 0, 0, 3, 0), "xxx");
VGet(runtime, sender0, groupId, runtime.GetNodeId(0), TLogoBlobID(100, 0, 0, 0, 3, 0), "xxx", EExpectedEqualData);
diff --git a/ydb/core/mind/ya.make b/ydb/core/mind/ya.make
index b9248c9d911..b54b3830347 100644
--- a/ydb/core/mind/ya.make
+++ b/ydb/core/mind/ya.make
@@ -31,7 +31,7 @@ SRCS(
node_broker__update_config.cpp
node_broker__update_config_subscription.cpp
node_broker__update_epoch.cpp
- table_adapter.h
+ table_adapter.h
tenant_node_enumeration.cpp
tenant_node_enumeration.h
tenant_pool.h
diff --git a/ydb/core/mon/crossref.cpp b/ydb/core/mon/crossref.cpp
index af9ad30bdcf..48656c37140 100644
--- a/ydb/core/mon/crossref.cpp
+++ b/ydb/core/mon/crossref.cpp
@@ -1,142 +1,142 @@
-#include "crossref.h"
+#include "crossref.h"
#include <ydb/core/node_whiteboard/node_whiteboard.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-
-namespace NKikimr::NCrossRef {
-
-using namespace NNodeWhiteboard;
-
-class TCrossRefActor : public TActor<TCrossRefActor> {
- struct TEndpoint {
- TString Address;
- ui16 Port;
- bool Valid = false;
- };
- std::unordered_map<ui32, TEndpoint> Endpoints;
-
- struct TEndpointRequest {
- std::deque<ui64> PendingIds;
- };
- std::unordered_map<ui32, TEndpointRequest> EndpointRequests;
-
- std::unordered_map<ui64, TEvGenerateCrossRef::TPtr> RequestsInProgress;
- ui64 NextRequestId = 1;
-
-public:
- TCrossRefActor()
- : TActor(&TThis::StateFunc)
- {}
-
- void Handle(TEvGenerateCrossRef::TPtr ev) {
- const ui32 nodeId = ev->Get()->TargetNodeId;
- if (const auto it = Endpoints.find(nodeId); it != Endpoints.end() && it->second.Valid) {
- IssueReply(ev, &it->second);
- } else {
- TEndpointRequest& request = EndpointRequests[nodeId];
-
- if (request.PendingIds.empty()) {
- Send(MakeNodeWhiteboardServiceId(nodeId), new TEvWhiteboard::TEvSystemStateRequest,
- IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
- }
-
- const ui64 id = NextRequestId++;
- request.PendingIds.push_back(id);
- TActivationContext::Schedule(ev->Get()->Deadline, new IEventHandle(NActors::TEvents::TSystem::Wakeup, 0, SelfId(), TActorId(), nullptr, id));
- RequestsInProgress.emplace(id, ev);
- }
- }
-
- void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr ev) {
- const ui32 nodeId = ev->Sender.NodeId();
-
- const auto& record = ev->Get()->Record;
- for (const auto& e : record.GetSystemStateInfo(0).GetEndpoints()) {
- if (e.GetName() == "http-mon") {
- const TString& address = e.GetAddress();
- const char *p = address.data();
- if (const char *x = strchr(p, ':')) {
- TEndpoint& endpoint = Endpoints[nodeId];
- endpoint.Port = atoi(x + 1);
- endpoint.Address = TString(p, x);
- if (endpoint.Address) {
- endpoint.Valid = true;
- ProcessEndpointRequests(nodeId, &endpoint); // fulfill pending requests
- } else {
- Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(nodeId));
- }
- return;
- }
- }
- }
-
- ProcessEndpointRequests(nodeId, nullptr);
- }
-
- void Handle(TEvInterconnect::TEvNodeInfo::TPtr ev) {
- const ui32 nodeId = ev->Get()->NodeId;
- if (const auto it = Endpoints.find(nodeId); it != Endpoints.end()) {
- if (const auto& info = ev->Get()->Node) {
- TEndpoint& endpoint = it->second;
- endpoint.Address = info->Host;
- endpoint.Valid = true;
- return ProcessEndpointRequests(nodeId, &endpoint); // fulfill pending requests
- }
- }
- ProcessEndpointRequests(nodeId, nullptr);
- }
-
- void Handle(NActors::TEvents::TEvUndelivered::TPtr ev) {
- ProcessEndpointRequests(ev->Sender.NodeId(), nullptr);
- }
-
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr) {}
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
- ProcessEndpointRequests(ev->Get()->NodeId, nullptr); // drop any pending requests
- Endpoints.erase(ev->Get()->NodeId); // terminate existing entries
- }
-
- void ProcessEndpointRequests(ui32 nodeId, const TEndpoint *endpoint) {
- if (const auto it = EndpointRequests.find(nodeId); it != EndpointRequests.end()) {
- for (ui64 id : it->second.PendingIds) {
- if (const auto it = RequestsInProgress.find(id); it != RequestsInProgress.end()) {
- IssueReply(it->second, endpoint);
- RequestsInProgress.erase(it);
- }
- }
- EndpointRequests.erase(it);
- }
- }
-
- void IssueReply(TEvGenerateCrossRef::TPtr ev, const TEndpoint *endpoint) {
- TString url = endpoint && endpoint->Valid // TODO: bastion, viewer
- ? Sprintf("http://%s:%u/%s", endpoint->Address.data(), endpoint->Port, ev->Get()->Path.data())
- : TString();
- Send(ev->Sender, new TEvCrossRef(url), 0, ev->Cookie);
- }
-
- void Handle(NActors::TEvents::TEvWakeup::TPtr ev) {
- if (const auto it = RequestsInProgress.find(ev->Cookie); it != RequestsInProgress.end()) {
- IssueReply(it->second, nullptr);
- RequestsInProgress.erase(it);
- }
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvGenerateCrossRef, Handle);
- hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
- hFunc(NActors::TEvents::TEvUndelivered, Handle);
- hFunc(TEvInterconnect::TEvNodeInfo, Handle);
- hFunc(TEvInterconnect::TEvNodeConnected, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
- hFunc(NActors::TEvents::TEvWakeup, Handle);
- )
-};
-
-IActor *CreateCrossRefActor() {
- return new TCrossRefActor;
-}
-
-} // NKikimr::NCrossRef
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+
+namespace NKikimr::NCrossRef {
+
+using namespace NNodeWhiteboard;
+
+class TCrossRefActor : public TActor<TCrossRefActor> {
+ struct TEndpoint {
+ TString Address;
+ ui16 Port;
+ bool Valid = false;
+ };
+ std::unordered_map<ui32, TEndpoint> Endpoints;
+
+ struct TEndpointRequest {
+ std::deque<ui64> PendingIds;
+ };
+ std::unordered_map<ui32, TEndpointRequest> EndpointRequests;
+
+ std::unordered_map<ui64, TEvGenerateCrossRef::TPtr> RequestsInProgress;
+ ui64 NextRequestId = 1;
+
+public:
+ TCrossRefActor()
+ : TActor(&TThis::StateFunc)
+ {}
+
+ void Handle(TEvGenerateCrossRef::TPtr ev) {
+ const ui32 nodeId = ev->Get()->TargetNodeId;
+ if (const auto it = Endpoints.find(nodeId); it != Endpoints.end() && it->second.Valid) {
+ IssueReply(ev, &it->second);
+ } else {
+ TEndpointRequest& request = EndpointRequests[nodeId];
+
+ if (request.PendingIds.empty()) {
+ Send(MakeNodeWhiteboardServiceId(nodeId), new TEvWhiteboard::TEvSystemStateRequest,
+ IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession);
+ }
+
+ const ui64 id = NextRequestId++;
+ request.PendingIds.push_back(id);
+ TActivationContext::Schedule(ev->Get()->Deadline, new IEventHandle(NActors::TEvents::TSystem::Wakeup, 0, SelfId(), TActorId(), nullptr, id));
+ RequestsInProgress.emplace(id, ev);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvSystemStateResponse::TPtr ev) {
+ const ui32 nodeId = ev->Sender.NodeId();
+
+ const auto& record = ev->Get()->Record;
+ for (const auto& e : record.GetSystemStateInfo(0).GetEndpoints()) {
+ if (e.GetName() == "http-mon") {
+ const TString& address = e.GetAddress();
+ const char *p = address.data();
+ if (const char *x = strchr(p, ':')) {
+ TEndpoint& endpoint = Endpoints[nodeId];
+ endpoint.Port = atoi(x + 1);
+ endpoint.Address = TString(p, x);
+ if (endpoint.Address) {
+ endpoint.Valid = true;
+ ProcessEndpointRequests(nodeId, &endpoint); // fulfill pending requests
+ } else {
+ Send(GetNameserviceActorId(), new TEvInterconnect::TEvGetNode(nodeId));
+ }
+ return;
+ }
+ }
+ }
+
+ ProcessEndpointRequests(nodeId, nullptr);
+ }
+
+ void Handle(TEvInterconnect::TEvNodeInfo::TPtr ev) {
+ const ui32 nodeId = ev->Get()->NodeId;
+ if (const auto it = Endpoints.find(nodeId); it != Endpoints.end()) {
+ if (const auto& info = ev->Get()->Node) {
+ TEndpoint& endpoint = it->second;
+ endpoint.Address = info->Host;
+ endpoint.Valid = true;
+ return ProcessEndpointRequests(nodeId, &endpoint); // fulfill pending requests
+ }
+ }
+ ProcessEndpointRequests(nodeId, nullptr);
+ }
+
+ void Handle(NActors::TEvents::TEvUndelivered::TPtr ev) {
+ ProcessEndpointRequests(ev->Sender.NodeId(), nullptr);
+ }
+
+ void Handle(TEvInterconnect::TEvNodeConnected::TPtr) {}
+
+ void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
+ ProcessEndpointRequests(ev->Get()->NodeId, nullptr); // drop any pending requests
+ Endpoints.erase(ev->Get()->NodeId); // terminate existing entries
+ }
+
+ void ProcessEndpointRequests(ui32 nodeId, const TEndpoint *endpoint) {
+ if (const auto it = EndpointRequests.find(nodeId); it != EndpointRequests.end()) {
+ for (ui64 id : it->second.PendingIds) {
+ if (const auto it = RequestsInProgress.find(id); it != RequestsInProgress.end()) {
+ IssueReply(it->second, endpoint);
+ RequestsInProgress.erase(it);
+ }
+ }
+ EndpointRequests.erase(it);
+ }
+ }
+
+ void IssueReply(TEvGenerateCrossRef::TPtr ev, const TEndpoint *endpoint) {
+ TString url = endpoint && endpoint->Valid // TODO: bastion, viewer
+ ? Sprintf("http://%s:%u/%s", endpoint->Address.data(), endpoint->Port, ev->Get()->Path.data())
+ : TString();
+ Send(ev->Sender, new TEvCrossRef(url), 0, ev->Cookie);
+ }
+
+ void Handle(NActors::TEvents::TEvWakeup::TPtr ev) {
+ if (const auto it = RequestsInProgress.find(ev->Cookie); it != RequestsInProgress.end()) {
+ IssueReply(it->second, nullptr);
+ RequestsInProgress.erase(it);
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvGenerateCrossRef, Handle);
+ hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle);
+ hFunc(NActors::TEvents::TEvUndelivered, Handle);
+ hFunc(TEvInterconnect::TEvNodeInfo, Handle);
+ hFunc(TEvInterconnect::TEvNodeConnected, Handle);
+ hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
+ hFunc(NActors::TEvents::TEvWakeup, Handle);
+ )
+};
+
+IActor *CreateCrossRefActor() {
+ return new TCrossRefActor;
+}
+
+} // NKikimr::NCrossRef
diff --git a/ydb/core/mon/crossref.h b/ydb/core/mon/crossref.h
index 14c07b8b9e1..6c6037aa684 100644
--- a/ydb/core/mon/crossref.h
+++ b/ydb/core/mon/crossref.h
@@ -1,44 +1,44 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/base/events.h>
-
-#include <library/cpp/cgiparam/cgiparam.h>
-
-namespace NKikimr::NCrossRef {
-
- struct TEvents {
- enum {
- EvGenerateCrossRef = EventSpaceBegin(TKikimrEvents::ES_CROSSREF),
- EvCrossRef,
- };
- };
-
- struct TEvGenerateCrossRef : TEventLocal<TEvGenerateCrossRef, TEvents::EvGenerateCrossRef> {
- const TString PagePath;
- const ui32 TargetNodeId;
- const TString Path;
- const TInstant Deadline;
-
- TEvGenerateCrossRef(TString pagePath, ui32 targetNodeId, TString path, TInstant deadline)
- : PagePath(std::move(pagePath))
- , TargetNodeId(targetNodeId)
- , Path(std::move(path))
- , Deadline(deadline)
- {}
- };
-
- struct TEvCrossRef : TEventLocal<TEvCrossRef, TEvents::EvCrossRef> {
- const TString Url;
-
- TEvCrossRef(TString url)
- : Url(std::move(url))
- {}
- };
-
- IActor *CreateCrossRefActor();
-
- inline TActorId MakeCrossRefActorId() {
- return TActorId(0, TStringBuf("CrossRefActr", 12));
- }
-
-} // NKikimr::NCrossRef
+
+#include <library/cpp/cgiparam/cgiparam.h>
+
+namespace NKikimr::NCrossRef {
+
+ struct TEvents {
+ enum {
+ EvGenerateCrossRef = EventSpaceBegin(TKikimrEvents::ES_CROSSREF),
+ EvCrossRef,
+ };
+ };
+
+ struct TEvGenerateCrossRef : TEventLocal<TEvGenerateCrossRef, TEvents::EvGenerateCrossRef> {
+ const TString PagePath;
+ const ui32 TargetNodeId;
+ const TString Path;
+ const TInstant Deadline;
+
+ TEvGenerateCrossRef(TString pagePath, ui32 targetNodeId, TString path, TInstant deadline)
+ : PagePath(std::move(pagePath))
+ , TargetNodeId(targetNodeId)
+ , Path(std::move(path))
+ , Deadline(deadline)
+ {}
+ };
+
+ struct TEvCrossRef : TEventLocal<TEvCrossRef, TEvents::EvCrossRef> {
+ const TString Url;
+
+ TEvCrossRef(TString url)
+ : Url(std::move(url))
+ {}
+ };
+
+ IActor *CreateCrossRefActor();
+
+ inline TActorId MakeCrossRefActorId() {
+ return TActorId(0, TStringBuf("CrossRefActr", 12));
+ }
+
+} // NKikimr::NCrossRef
diff --git a/ydb/core/mon/mon.cpp b/ydb/core/mon/mon.cpp
index d4722266f34..70825034395 100644
--- a/ydb/core/mon/mon.cpp
+++ b/ydb/core/mon/mon.cpp
@@ -28,8 +28,8 @@ namespace NActors {
////////////////////////////////////////////////////////////////////////////////
class TMonRequest : public NActors::TActor<TMonRequest> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::ACTORLIB_COMMON;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::ACTORLIB_COMMON;
}
TMonRequest(const TActorId &targetActorId, IMonHttpRequest& request,
diff --git a/ydb/core/mon/ya.make b/ydb/core/mon/ya.make
index c717b0f5b95..36755a2b099 100644
--- a/ydb/core/mon/ya.make
+++ b/ydb/core/mon/ya.make
@@ -9,8 +9,8 @@ OWNER(
SRCS(
mon.cpp
mon.h
- crossref.cpp
- crossref.h
+ crossref.cpp
+ crossref.h
)
PEERDIR(
diff --git a/ydb/core/node_whiteboard/node_whiteboard.h b/ydb/core/node_whiteboard/node_whiteboard.h
index cdf7601807c..6ec6df91cca 100644
--- a/ydb/core/node_whiteboard/node_whiteboard.h
+++ b/ydb/core/node_whiteboard/node_whiteboard.h
@@ -8,7 +8,7 @@
#include <ydb/core/blobstorage/groupinfo/blobstorage_groupinfo_iter.h>
#include <ydb/core/protos/node_whiteboard.pb.h>
#include <library/cpp/actors/interconnect/events_local.h>
-#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/interconnect.h>
#include <ydb/core/base/tracing.h>
namespace NKikimr {
@@ -24,10 +24,10 @@ struct TEvWhiteboard{
EvTabletStateUpdate = EventSpaceBegin(TKikimrEvents::ES_NODE_WHITEBOARD),
EvTabletStateRequest,
EvTabletStateResponse,
- EvNodeStateUpdate,
- EvNodeStateDelete,
- EvNodeStateRequest,
- EvNodeStateResponse,
+ EvNodeStateUpdate,
+ EvNodeStateDelete,
+ EvNodeStateRequest,
+ EvNodeStateResponse,
EvPDiskStateUpdate,
EvPDiskStateRequest,
EvPDiskStateResponse,
@@ -56,7 +56,7 @@ struct TEvWhiteboard{
EvSignalBodyRequest,
EvSignalBodyResponse,
EvPDiskStateDelete,
- EvVDiskStateGenerationChange,
+ EvVDiskStateGenerationChange,
EvEnd
};
@@ -125,7 +125,7 @@ struct TEvWhiteboard{
Record.SetPDiskId(pDiskId);
Record.SetAvailableSize(availableSize);
Record.SetTotalSize(totalSize);
- Record.SetState(static_cast<NKikimrBlobStorage::TPDiskState::E>(state));
+ Record.SetState(static_cast<NKikimrBlobStorage::TPDiskState::E>(state));
}
TEvPDiskStateUpdate(ui32 pDiskId, NKikimrWhiteboard::EFlag realtime, NKikimrWhiteboard::EFlag device) {
@@ -140,58 +140,58 @@ struct TEvWhiteboard{
struct TEvPDiskStateResponse : public TEventPB<TEvPDiskStateResponse, NKikimrWhiteboard::TEvPDiskStateResponse, EvPDiskStateResponse> {};
struct TEvVDiskStateUpdate : TEventPB<TEvVDiskStateUpdate, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateUpdate> {
- const bool Initial = false;
-
+ const bool Initial = false;
+
TEvVDiskStateUpdate() = default;
- // this message is generated by NodeWarden
- explicit TEvVDiskStateUpdate(const TVDiskID& vDiskId, const TMaybe<TString>& storagePoolName, ui32 pDiskId,
- ui32 vDiskSlotId, ui64 guid, NKikimrBlobStorage::TVDiskKind::EVDiskKind kind, bool donorMode,
- ui64 instanceGuid)
- : Initial(true)
- {
+ // this message is generated by NodeWarden
+ explicit TEvVDiskStateUpdate(const TVDiskID& vDiskId, const TMaybe<TString>& storagePoolName, ui32 pDiskId,
+ ui32 vDiskSlotId, ui64 guid, NKikimrBlobStorage::TVDiskKind::EVDiskKind kind, bool donorMode,
+ ui64 instanceGuid)
+ : Initial(true)
+ {
VDiskIDFromVDiskID(vDiskId, Record.MutableVDiskId());
- if (storagePoolName) {
- Record.SetStoragePoolName(*storagePoolName);
- }
+ if (storagePoolName) {
+ Record.SetStoragePoolName(*storagePoolName);
+ }
Record.SetPDiskId(pDiskId);
Record.SetVDiskSlotId(vDiskSlotId);
Record.SetGuid(guid);
Record.SetKind(kind);
- if (donorMode) {
- Record.SetDonorMode(true);
- }
- Record.SetInstanceGuid(instanceGuid);
+ if (donorMode) {
+ Record.SetDonorMode(true);
+ }
+ Record.SetInstanceGuid(instanceGuid);
}
- explicit TEvVDiskStateUpdate(NKikimrWhiteboard::TVDiskSatisfactionRank *satisfactionRank) {
+ explicit TEvVDiskStateUpdate(NKikimrWhiteboard::TVDiskSatisfactionRank *satisfactionRank) {
Record.MutableSatisfactionRank()->Swap(satisfactionRank);
}
- explicit TEvVDiskStateUpdate(NKikimrWhiteboard::EVDiskState state,
+ explicit TEvVDiskStateUpdate(NKikimrWhiteboard::EVDiskState state,
NKikimrWhiteboard::EFlag diskSpace,
bool replicated,
- bool unreplicatedPhantoms,
- bool unreplicatedNonPhantoms,
+ bool unreplicatedPhantoms,
+ bool unreplicatedNonPhantoms,
ui64 unsyncedVDisks,
- NKikimrWhiteboard::EFlag frontQueuesLigth,
- bool hasUnreadableBlobs) {
+ NKikimrWhiteboard::EFlag frontQueuesLigth,
+ bool hasUnreadableBlobs) {
Record.SetVDiskState(state);
Record.SetDiskSpace(diskSpace);
Record.SetReplicated(replicated);
- Record.SetUnreplicatedPhantoms(unreplicatedPhantoms);
- Record.SetUnreplicatedNonPhantoms(unreplicatedNonPhantoms);
+ Record.SetUnreplicatedPhantoms(unreplicatedPhantoms);
+ Record.SetUnreplicatedNonPhantoms(unreplicatedNonPhantoms);
Record.SetUnsyncedVDisks(unsyncedVDisks);
Record.SetFrontQueues(frontQueuesLigth);
- Record.SetHasUnreadableBlobs(hasUnreadableBlobs);
- }
-
- static constexpr struct TUpdateIncarnationGuid {} UpdateIncarnationGuid{};
-
- explicit TEvVDiskStateUpdate(TUpdateIncarnationGuid, ui64 incarnationGuid) {
- Record.SetIncarnationGuid(incarnationGuid);
+ Record.SetHasUnreadableBlobs(hasUnreadableBlobs);
}
+ static constexpr struct TUpdateIncarnationGuid {} UpdateIncarnationGuid{};
+
+ explicit TEvVDiskStateUpdate(TUpdateIncarnationGuid, ui64 incarnationGuid) {
+ Record.SetIncarnationGuid(incarnationGuid);
+ }
+
explicit TEvVDiskStateUpdate(NKikimrWhiteboard::TVDiskStateInfo&& rec) {
Record = std::move(rec);
}
@@ -199,24 +199,24 @@ struct TEvWhiteboard{
struct TEvVDiskStateDelete : TEventPB<TEvVDiskStateDelete, NKikimrWhiteboard::TVDiskStateInfo, EvVDiskStateDelete> {
TEvVDiskStateDelete() = default;
-
+
explicit TEvVDiskStateDelete(const TVDiskID& vDiskId) {
- VDiskIDFromVDiskID(vDiskId, Record.MutableVDiskId());
- }
- };
-
- struct TEvVDiskStateGenerationChange : TEventLocal<TEvVDiskStateGenerationChange, EvVDiskStateGenerationChange> {
- const TVDiskID VDiskId;
- const ui32 Generation;
- const ui64 InstanceGuid;
-
- TEvVDiskStateGenerationChange(const TVDiskID& vdiskId, ui32 generation, ui64 instanceGuid)
- : VDiskId(vdiskId)
- , Generation(generation)
- , InstanceGuid(instanceGuid)
- {}
- };
-
+ VDiskIDFromVDiskID(vDiskId, Record.MutableVDiskId());
+ }
+ };
+
+ struct TEvVDiskStateGenerationChange : TEventLocal<TEvVDiskStateGenerationChange, EvVDiskStateGenerationChange> {
+ const TVDiskID VDiskId;
+ const ui32 Generation;
+ const ui64 InstanceGuid;
+
+ TEvVDiskStateGenerationChange(const TVDiskID& vdiskId, ui32 generation, ui64 instanceGuid)
+ : VDiskId(vdiskId)
+ , Generation(generation)
+ , InstanceGuid(instanceGuid)
+ {}
+ };
+
struct TEvPDiskStateDelete : TEventPB<TEvPDiskStateDelete, NKikimrWhiteboard::TPDiskStateInfo, EvPDiskStateDelete> {
TEvPDiskStateDelete() = default;
@@ -233,18 +233,18 @@ struct TEvWhiteboard{
struct TEvBSGroupStateUpdate : TEventPB<TEvBSGroupStateUpdate, NKikimrWhiteboard::TBSGroupStateInfo, EvBSGroupStateUpdate> {
TEvBSGroupStateUpdate() = default;
- TEvBSGroupStateUpdate(const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo, const TMaybe<TString>& storagePoolName) {
+ TEvBSGroupStateUpdate(const TIntrusivePtr<TBlobStorageGroupInfo>& groupInfo, const TMaybe<TString>& storagePoolName) {
Record.SetGroupID(groupInfo->GroupID);
Record.SetGroupGeneration(groupInfo->GroupGeneration);
Record.SetErasureSpecies(groupInfo->Type.ErasureSpeciesName(groupInfo->Type.GetErasure()));
- for (auto it = groupInfo->VDisksBegin(), end = groupInfo->VDisksEnd(); it != end; ++it) {
+ for (auto it = groupInfo->VDisksBegin(), end = groupInfo->VDisksEnd(); it != end; ++it) {
auto vd = groupInfo->GetVDiskId(it->OrderNumber);
NKikimrBlobStorage::TVDiskID* addedVDisk = Record.AddVDiskIds();
VDiskIDFromVDiskID(vd, addedVDisk);
}
- if (storagePoolName) {
- Record.SetStoragePoolName(*storagePoolName);
- }
+ if (storagePoolName) {
+ Record.SetStoragePoolName(*storagePoolName);
+ }
}
};
@@ -286,22 +286,22 @@ struct TEvWhiteboard{
}
TEvSystemStateUpdate(const TVector<std::tuple<TString, double, ui32>>& poolStats) {
- for (const auto& row : poolStats) {
- auto& pb = *Record.AddPoolStats();
- pb.SetName(std::get<0>(row));
- pb.SetUsage(std::get<1>(row));
+ for (const auto& row : poolStats) {
+ auto& pb = *Record.AddPoolStats();
+ pb.SetName(std::get<0>(row));
+ pb.SetUsage(std::get<1>(row));
pb.SetThreads(std::get<2>(row));
- }
- }
-
- TEvSystemStateUpdate(const TNodeLocation& systemLocation) {
- systemLocation.Serialize(Record.MutableLocation());
- const auto& x = systemLocation.GetLegacyValue();
- auto *pb = Record.MutableSystemLocation();
- pb->SetDataCenter(x.DataCenter);
- pb->SetRoom(x.Room);
- pb->SetRack(x.Rack);
- pb->SetBody(x.Body);
+ }
+ }
+
+ TEvSystemStateUpdate(const TNodeLocation& systemLocation) {
+ systemLocation.Serialize(Record.MutableLocation());
+ const auto& x = systemLocation.GetLegacyValue();
+ auto *pb = Record.MutableSystemLocation();
+ pb->SetDataCenter(x.DataCenter);
+ pb->SetRoom(x.Room);
+ pb->SetRack(x.Rack);
+ pb->SetBody(x.Body);
}
TEvSystemStateUpdate(const NKikimrWhiteboard::TSystemStateInfo& systemStateInfo) {
@@ -347,34 +347,34 @@ struct TEvWhiteboard{
struct TEvSystemStateResponse : public TEventPB<TEvSystemStateResponse, NKikimrWhiteboard::TEvSystemStateResponse, EvSystemStateResponse> {};
- struct TEvNodeStateUpdate : TEventPB<TEvNodeStateUpdate, NKikimrWhiteboard::TNodeStateInfo, EvNodeStateUpdate> {
- TEvNodeStateUpdate() = default;
-
- TEvNodeStateUpdate(const TString& peerName, bool connected) {
- Record.SetPeerName(peerName);
- Record.SetConnected(connected);
- }
-
- TEvNodeStateUpdate(const TString& peerName, bool connected, NKikimrWhiteboard::EFlag connectStatus) {
- Record.SetPeerName(peerName);
- Record.SetConnected(connected);
- Record.SetConnectStatus(connectStatus);
- }
- };
-
- struct TEvNodeStateDelete : TEventPB<TEvNodeStateDelete, NKikimrWhiteboard::TNodeStateInfo, EvNodeStateDelete> {
- TEvNodeStateDelete() = default;
-
- TEvNodeStateDelete(const TString& peerName) {
- Record.SetPeerName(peerName);
- }
- };
-
- struct TEvNodeStateRequest : TEventPB<TEvNodeStateRequest, NKikimrWhiteboard::TEvNodeStateRequest, EvNodeStateRequest>
- {};
-
- struct TEvNodeStateResponse : TEventPB<TEvNodeStateResponse, NKikimrWhiteboard::TEvNodeStateResponse, EvNodeStateResponse>
- {};
+ struct TEvNodeStateUpdate : TEventPB<TEvNodeStateUpdate, NKikimrWhiteboard::TNodeStateInfo, EvNodeStateUpdate> {
+ TEvNodeStateUpdate() = default;
+
+ TEvNodeStateUpdate(const TString& peerName, bool connected) {
+ Record.SetPeerName(peerName);
+ Record.SetConnected(connected);
+ }
+
+ TEvNodeStateUpdate(const TString& peerName, bool connected, NKikimrWhiteboard::EFlag connectStatus) {
+ Record.SetPeerName(peerName);
+ Record.SetConnected(connected);
+ Record.SetConnectStatus(connectStatus);
+ }
+ };
+
+ struct TEvNodeStateDelete : TEventPB<TEvNodeStateDelete, NKikimrWhiteboard::TNodeStateInfo, EvNodeStateDelete> {
+ TEvNodeStateDelete() = default;
+
+ TEvNodeStateDelete(const TString& peerName) {
+ Record.SetPeerName(peerName);
+ }
+ };
+
+ struct TEvNodeStateRequest : TEventPB<TEvNodeStateRequest, NKikimrWhiteboard::TEvNodeStateRequest, EvNodeStateRequest>
+ {};
+
+ struct TEvNodeStateResponse : TEventPB<TEvNodeStateResponse, NKikimrWhiteboard::TEvNodeStateResponse, EvNodeStateResponse>
+ {};
struct TEvIntrospectionData : TEventLocal<TEvIntrospectionData, EvIntrospectionData> {
diff --git a/ydb/core/persqueue/events/global.h b/ydb/core/persqueue/events/global.h
index e1957e7a16f..d564ecb6a2d 100644
--- a/ydb/core/persqueue/events/global.h
+++ b/ydb/core/persqueue/events/global.h
@@ -53,12 +53,12 @@ struct TEvPersQueue {
"expect EvEnd < EventSpaceEnd(TKikimrEvents::ES_PQ)");
struct TEvRequest : public TEventPB<TEvRequest,
- NKikimrClient::TPersQueueRequest, EvRequest> {
+ NKikimrClient::TPersQueueRequest, EvRequest> {
TEvRequest() {}
};
struct TEvResponse: public TEventPB<TEvResponse,
- NKikimrClient::TResponse, EvResponse> {
+ NKikimrClient::TResponse, EvResponse> {
TEvResponse() {}
};
diff --git a/ydb/core/persqueue/events/internal.h b/ydb/core/persqueue/events/internal.h
index bc892988b47..0c9b68f4da2 100644
--- a/ydb/core/persqueue/events/internal.h
+++ b/ydb/core/persqueue/events/internal.h
@@ -322,7 +322,7 @@ struct TEvPQ {
: Cookie(cookie)
{}
ui64 Cookie;
- NKikimrClient::TResponse Response;
+ NKikimrClient::TResponse Response;
};
struct TEvInitComplete : public TEventLocal<TEvInitComplete, EvInitComplete> {
diff --git a/ydb/core/persqueue/partition.cpp b/ydb/core/persqueue/partition.cpp
index cc8e2419cf2..811c216cfb7 100644
--- a/ydb/core/persqueue/partition.cpp
+++ b/ydb/core/persqueue/partition.cpp
@@ -250,7 +250,7 @@ void TPartition::ReplyError(const TActorContext& ctx, const ui64 dst, NPersQueue
void TPartition::ReplyOk(const TActorContext& ctx, const ui64 dst)
{
THolder<TEvPQ::TEvProxyResponse> response = MakeHolder<TEvPQ::TEvProxyResponse>(dst);
- NKikimrClient::TResponse& resp = response->Response;
+ NKikimrClient::TResponse& resp = response->Response;
resp.SetStatus(NMsgBusProxy::MSTATUS_OK);
resp.SetErrorCode(NPersQueue::NErrorCode::OK);
ctx.Send(Tablet, response.Release());
@@ -259,7 +259,7 @@ void TPartition::ReplyOk(const TActorContext& ctx, const ui64 dst)
void TPartition::ReplyOwnerOk(const TActorContext& ctx, const ui64 dst, const TString& cookie)
{
THolder<TEvPQ::TEvProxyResponse> response = MakeHolder<TEvPQ::TEvProxyResponse>(dst);
- NKikimrClient::TResponse& resp = response->Response;
+ NKikimrClient::TResponse& resp = response->Response;
resp.SetStatus(NMsgBusProxy::MSTATUS_OK);
resp.SetErrorCode(NPersQueue::NErrorCode::OK);
resp.MutablePartitionResponse()->MutableCmdGetOwnershipResult()->SetOwnerCookie(cookie);
@@ -275,7 +275,7 @@ void TPartition::ReplyWrite(
Y_VERIFY(seqNo <= (ui64)Max<i64>(), "SeqNo is too big: %" PRIu64, seqNo);
THolder<TEvPQ::TEvProxyResponse> response = MakeHolder<TEvPQ::TEvProxyResponse>(dst);
- NKikimrClient::TResponse& resp = response->Response;
+ NKikimrClient::TResponse& resp = response->Response;
resp.SetStatus(NMsgBusProxy::MSTATUS_OK);
resp.SetErrorCode(NPersQueue::NErrorCode::OK);
auto write = resp.MutablePartitionResponse()->AddCmdWriteResult();
@@ -302,7 +302,7 @@ void TPartition::ReplyGetClientOffsetOk(const TActorContext& ctx, const ui64 dst
const TInstant writeTimestamp, const TInstant createTimestamp)
{
THolder<TEvPQ::TEvProxyResponse> response = MakeHolder<TEvPQ::TEvProxyResponse>(dst);
- NKikimrClient::TResponse& resp = response->Response;
+ NKikimrClient::TResponse& resp = response->Response;
resp.SetStatus(NMsgBusProxy::MSTATUS_OK);
resp.SetErrorCode(NPersQueue::NErrorCode::OK);
@@ -453,8 +453,8 @@ void TPartition::FillReadFromTimestamps(const NKikimrPQ::TPQTabletConfig& config
}
TPartition::TPartition(ui64 tabletId, ui32 partition, const TActorId& tablet, const TActorId& blobCache,
- const TString& topicName, const TString& topicPath, const bool localDC, TString dcId,
- const NKikimrPQ::TPQTabletConfig& config, const TTabletCountersBase& counters,
+ const TString& topicName, const TString& topicPath, const bool localDC, TString dcId,
+ const NKikimrPQ::TPQTabletConfig& config, const TTabletCountersBase& counters,
const TActorContext &ctx, bool newPartition)
: TabletID(tabletId)
, Partition(partition)
@@ -462,7 +462,7 @@ TPartition::TPartition(ui64 tabletId, ui32 partition, const TActorId& tablet, co
, TopicName(topicName)
, TopicPath(topicPath)
, LocalDC(localDC)
- , DCId(std::move(dcId))
+ , DCId(std::move(dcId))
, StartOffset(0)
, EndOffset(0)
, WriteInflightSize(0)
@@ -1372,7 +1372,7 @@ void TPartition::HandleMetaRead(const NKikimrClient::TKeyValueResponse::TReadRes
-void TPartition::HandleInfoRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
+void TPartition::HandleInfoRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
{
//megaqc check here all results
Y_VERIFY(range.HasStatus());
@@ -1427,7 +1427,7 @@ void TPartition::HandleInfoRangeRead(const NKikimrClient::TKeyValueResponse::TRe
};
}
-void TPartition::FillBlobsMetaData(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
+void TPartition::FillBlobsMetaData(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
{
for (ui32 i = 0; i < range.PairSize(); ++i) {
auto pair = range.GetPair(i);
@@ -1492,7 +1492,7 @@ void TPartition::FormHeadAndProceed(const TActorContext& ctx)
RequestData(ctx, Tablet, keys);
}
-void TPartition::HandleDataRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
+void TPartition::HandleDataRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx)
{
Y_VERIFY(range.HasStatus());
switch(range.GetStatus()) {
@@ -1517,7 +1517,7 @@ void TPartition::HandleDataRangeRead(const NKikimrClient::TKeyValueResponse::TRe
};
}
-void TPartition::HandleDataRead(const NKikimrClient::TResponse& response, const TActorContext& ctx)
+void TPartition::HandleDataRead(const NKikimrClient::TResponse& response, const TActorContext& ctx)
{
Y_VERIFY(InitState == WaitDataRead);
ui32 currentLevel = 0;
@@ -2172,7 +2172,7 @@ void TPartition::ProcessUserActs(TUserInfo& userInfo, const TActorContext& ctx)
void TPartition::Handle(TEvPQ::TEvGetMaxSeqNoRequest::TPtr& ev, const TActorContext& ctx) {
auto response = MakeHolder<TEvPQ::TEvProxyResponse>(ev->Get()->Cookie);
- NKikimrClient::TResponse& resp = response->Response;
+ NKikimrClient::TResponse& resp = response->Response;
resp.SetStatus(NMsgBusProxy::MSTATUS_OK);
resp.SetErrorCode(NPersQueue::NErrorCode::OK);
@@ -2291,7 +2291,7 @@ TReadAnswer TReadInfo::FormAnswer(
) {
Y_UNUSED(partition);
THolder<TEvPQ::TEvProxyResponse> answer = MakeHolder<TEvPQ::TEvProxyResponse>(cookie);
- NKikimrClient::TResponse& res = answer->Response;
+ NKikimrClient::TResponse& res = answer->Response;
const TEvPQ::TEvBlobResponse* response = &blobResponse;
if (HasError(blobResponse)) {
@@ -3374,7 +3374,7 @@ void TPartition::Handle(TEvPQ::TEvHandleWriteResponse::TPtr&, const TActorContex
HandleWriteResponse(ctx);
}
-void TPartition::HandleSetOffsetResponse(NKikimrClient::TResponse& response, const TActorContext& ctx) {
+void TPartition::HandleSetOffsetResponse(NKikimrClient::TResponse& response, const TActorContext& ctx) {
ui64 cookie = response.GetCookie();
auto it = CookieToUser.find(cookie);
Y_VERIFY(it != CookieToUser.end());
diff --git a/ydb/core/persqueue/partition.h b/ydb/core/persqueue/partition.h
index 2eec26f2516..9d7ebb5bc03 100644
--- a/ydb/core/persqueue/partition.h
+++ b/ydb/core/persqueue/partition.h
@@ -82,16 +82,16 @@ private:
void HandleOnInit(TEvKeyValue::TEvResponse::TPtr& ev, const TActorContext& ctx);
void HandleGetDiskStatus(const NKikimrClient::TResponse& res, const TActorContext& ctx);
- void HandleInfoRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
- void HandleDataRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
+ void HandleInfoRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
+ void HandleDataRangeRead(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
void HandleMetaRead(const NKikimrClient::TKeyValueResponse::TReadResult& response, const TActorContext& ctx);
//forms DataKeysBody and other partition's info
//ctx here only for logging
- void FillBlobsMetaData(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
+ void FillBlobsMetaData(const NKikimrClient::TKeyValueResponse::TReadRangeResult& range, const TActorContext& ctx);
//will form head and request data keys from head or finish initialization
void FormHeadAndProceed(const TActorContext& ctx);
- void HandleDataRead(const NKikimrClient::TResponse& range, const TActorContext& ctx);
+ void HandleDataRead(const NKikimrClient::TResponse& range, const TActorContext& ctx);
void InitComplete(const TActorContext& ctx);
@@ -176,7 +176,7 @@ private:
ui64 GetSizeLag(i64 offset);
void Handle(TEvKeyValue::TEvResponse::TPtr& ev, const TActorContext& ctx);
- void HandleSetOffsetResponse(NKikimrClient::TResponse& response, const TActorContext& ctx);
+ void HandleSetOffsetResponse(NKikimrClient::TResponse& response, const TActorContext& ctx);
void HandleWriteResponse(const TActorContext& ctx);
void Handle(TEvPQ::TEvHandleWriteResponse::TPtr&, const TActorContext& ctx);
@@ -214,12 +214,12 @@ private:
void SetupStreamCounters(const TActorContext& ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_PARTITION_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_PARTITION_ACTOR;
}
TPartition(ui64 tabletId, ui32 partition, const TActorId& tablet, const TActorId& blobCache,
- const TString& topicName, const TString& topicPath, const bool localDC, TString dcId,
+ const TString& topicName, const TString& topicPath, const bool localDC, TString dcId,
const NKikimrPQ::TPQTabletConfig& config, const TTabletCountersBase& counters,
const TActorContext& ctx, bool newPartition = false);
@@ -418,7 +418,7 @@ private:
TString TopicName;
TString TopicPath;
bool LocalDC;
- TString DCId;
+ TString DCId;
ui32 MaxBlobSize;
const ui32 TotalLevels = 4;
diff --git a/ydb/core/persqueue/pq_impl.cpp b/ydb/core/persqueue/pq_impl.cpp
index 9937dbe561c..a6b5d21562c 100644
--- a/ydb/core/persqueue/pq_impl.cpp
+++ b/ydb/core/persqueue/pq_impl.cpp
@@ -86,8 +86,8 @@ static TMaybe<TPartitionKeyRange> GetPartitionKeyRange(const NKikimrPQ::TPQTable
//megaqc - remove it when LB will be ready
class TReadProxy : public TActorBootstrapped<TReadProxy> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_ANS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_ANS_ACTOR;
}
TReadProxy(const TActorId& sender, const TActorId& tablet, const NKikimrClient::TPersQueueRequest& request)
@@ -199,7 +199,7 @@ private:
const TActorId Sender;
const TActorId Tablet;
- NKikimrClient::TPersQueueRequest Request;
+ NKikimrClient::TPersQueueRequest Request;
THolder<TEvPersQueue::TEvResponse> Response;
};
@@ -325,8 +325,8 @@ class TBuilderProxy : public TActorBootstrapped<TBuilderProxy<T,T2,T3>> {
typedef T TEvent;
typedef typename TEvent::TPtr TTPtr;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_ANS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_ANS_ACTOR;
}
TBuilderProxy(const ui64 tabletId, const TActorId& sender, const ui32 count)
@@ -413,8 +413,8 @@ TActorId CreateStatusProxyActor(const ui64 tabletId, const TActorId& sender, con
class TMonitoringProxy : public TActorBootstrapped<TMonitoringProxy> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_MON_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_MON_ACTOR;
}
TMonitoringProxy(const TActorId& sender, const TString& query, const TMap<ui32, TActorId>& partitions, const TActorId& cache,
@@ -646,7 +646,7 @@ void TPersQueue::ApplyNewConfigAndReply(const TActorContext& ctx)
}
-void TPersQueue::HandleConfigWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
+void TPersQueue::HandleConfigWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
{
if (resp.GetStatus() != NMsgBusProxy::MSTATUS_OK ||
resp.WriteResultSize() != 1 ||
@@ -666,7 +666,7 @@ void TPersQueue::HandleConfigWriteResponse(const NKikimrClient::TResponse& resp,
NewConfigShouldBeApplied = true; //when config will be inited with old value new config will be applied
}
-void TPersQueue::HandleConfigReadResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
+void TPersQueue::HandleConfigReadResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
{
bool ok = (resp.GetStatus() == NMsgBusProxy::MSTATUS_OK) && (resp.ReadResultSize() == 2) && (resp.HasSetExecutorFastLogPolicyResult()) &&
(resp.GetSetExecutorFastLogPolicyResult().GetStatus() == NKikimrProto::OK);
@@ -681,7 +681,7 @@ void TPersQueue::HandleConfigReadResponse(const NKikimrClient::TResponse& resp,
ReadState(resp.GetReadResult(1), ctx);
}
-void TPersQueue::ReadConfig(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx)
+void TPersQueue::ReadConfig(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx)
{
if (read.GetStatus() != NKikimrProto::OK && read.GetStatus() != NKikimrProto::NODATA) {
LOG_ERROR_S(ctx, NKikimrServices::PERSQUEUE,
@@ -759,7 +759,7 @@ void TPersQueue::ReadConfig(const NKikimrClient::TKeyValueResponse::TReadResult&
}
-void TPersQueue::ReadState(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx)
+void TPersQueue::ReadState(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx)
{
Y_UNUSED(ctx);
@@ -794,7 +794,7 @@ void TPersQueue::ReturnTabletStateAll(const TActorContext& ctx, NKikimrProto::ER
TabletStateRequests.clear();
}
-void TPersQueue::HandleStateWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
+void TPersQueue::HandleStateWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx)
{
bool ok = (resp.GetStatus() == NMsgBusProxy::MSTATUS_OK) &&
(resp.WriteResultSize() == 1) &&
@@ -1294,7 +1294,7 @@ void TPersQueue::InitResponseBuilder(const ui64 responseCookie, const ui32 count
}
void TPersQueue::HandleGetMaxSeqNoRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdGetMaxSeqNo());
InitResponseBuilder(responseCookie, 1, COUNTER_LATENCY_PQ_GET_MAX_SEQ_NO);
@@ -1308,7 +1308,7 @@ void TPersQueue::HandleGetMaxSeqNoRequest(const ui64 responseCookie, const TActo
}
void TPersQueue::HandleDeleteSessionRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdDeleteSession());
InitResponseBuilder(responseCookie, 1, COUNTER_LATENCY_PQ_DELETE_SESSION);
@@ -1328,7 +1328,7 @@ void TPersQueue::HandleDeleteSessionRequest(const ui64 responseCookie, const TAc
}
void TPersQueue::HandleCreateSessionRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdCreateSession());
const auto& cmd = req.GetCmdCreateSession();
@@ -1354,7 +1354,7 @@ void TPersQueue::HandleCreateSessionRequest(const ui64 responseCookie, const TAc
}
void TPersQueue::HandleSetClientOffsetRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdSetClientOffset());
const auto& cmd = req.GetCmdSetClientOffset();
@@ -1378,7 +1378,7 @@ void TPersQueue::HandleSetClientOffsetRequest(const ui64 responseCookie, const T
}
void TPersQueue::HandleGetClientOffsetRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdGetClientOffset());
const auto& cmd = req.GetCmdGetClientOffset();
@@ -1403,7 +1403,7 @@ void TPersQueue::HandleUpdateWriteTimestampRequest(const ui64 responseCookie, co
}
void TPersQueue::HandleWriteRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.CmdWriteSize());
FlushMetrics(false, ctx); // To ensure hours' border;
@@ -1564,7 +1564,7 @@ void TPersQueue::HandleWriteRequest(const ui64 responseCookie, const TActorId& p
void TPersQueue::HandleReserveBytesRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,
const TActorId& pipeClient, const TActorId&)
{
Y_VERIFY(req.HasCmdReserveBytes());
@@ -1593,7 +1593,7 @@ void TPersQueue::HandleReserveBytesRequest(const ui64 responseCookie, const TAct
void TPersQueue::HandleGetOwnershipRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,
const TActorId& pipeClient, const TActorId& sender)
{
Y_VERIFY(req.HasCmdGetOwnership());
@@ -1621,7 +1621,7 @@ void TPersQueue::HandleGetOwnershipRequest(const ui64 responseCookie, const TAct
void TPersQueue::HandleReadRequest(const ui64 responseCookie, const TActorId& partActor,
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx)
{
Y_VERIFY(req.HasCmdRead());
@@ -1789,7 +1789,7 @@ void TPersQueue::HandleSplitMessageGroupRequest(ui64 responseCookie, const TActo
void TPersQueue::Handle(TEvPersQueue::TEvRequest::TPtr& ev, const TActorContext& ctx)
{
- NKikimrClient::TPersQueueRequest& request = ev->Get()->Record;
+ NKikimrClient::TPersQueueRequest& request = ev->Get()->Record;
TString s = request.HasRequestId() ? request.GetRequestId() : "<none>";
ui32 p = request.HasPartitionRequest() && request.GetPartitionRequest().HasPartition() ? request.GetPartitionRequest().GetPartition() : 0;
ui64 m = request.HasPartitionRequest() && request.GetPartitionRequest().HasMessageNo() ? request.GetPartitionRequest().GetMessageNo() : 0;
@@ -2011,7 +2011,7 @@ void TPersQueue::CreatedHook(const TActorContext& ctx)
void TPersQueue::Handle(TEvInterconnect::TEvNodeInfo::TPtr& ev, const TActorContext& ctx)
{
Y_VERIFY(ev->Get()->Node);
- DCId = ev->Get()->Node->Location.GetDataCenterId();
+ DCId = ev->Get()->Node->Location.GetDataCenterId();
ResourceMetrics = Executor()->GetResourceMetrics();
THolder<TEvKeyValue::TEvRequest> request(new TEvKeyValue::TEvRequest);
@@ -2152,7 +2152,7 @@ void TPersQueue::FlushMetrics(bool force, const TActorContext &ctx) {
bool TPersQueue::HandleHook(STFUNC_SIG)
{
- SetActivityType(NKikimrServices::TActivity::PERSQUEUE_ACTOR);
+ SetActivityType(NKikimrServices::TActivity::PERSQUEUE_ACTOR);
TRACE_EVENT(NKikimrServices::PERSQUEUE);
switch(ev->GetTypeRewrite())
{
diff --git a/ydb/core/persqueue/pq_impl.h b/ydb/core/persqueue/pq_impl.h
index bc3bfb10ba5..1162b71dcfb 100644
--- a/ydb/core/persqueue/pq_impl.h
+++ b/ydb/core/persqueue/pq_impl.h
@@ -71,13 +71,13 @@ class TPersQueue : public NKeyValue::TKeyValueFlat {
//response from KV on READ or WRITE config request
void Handle(TEvKeyValue::TEvResponse::TPtr& ev, const TActorContext& ctx);
- void HandleConfigWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
- void HandleConfigReadResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
+ void HandleConfigWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
+ void HandleConfigReadResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
void ApplyNewConfigAndReply(const TActorContext& ctx);
- void HandleStateWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
+ void HandleStateWriteResponse(const NKikimrClient::TResponse& resp, const TActorContext& ctx);
- void ReadConfig(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx);
- void ReadState(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx);
+ void ReadConfig(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx);
+ void ReadState(const NKikimrClient::TKeyValueResponse::TReadResult& read, const TActorContext& ctx);
void FillMeteringParams(const TActorContext& ctx);
TString GetMeteringJson(const TString& metricBillingId, const TString& schemeName, const THashMap<TString, ui64>& tags,
@@ -99,7 +99,7 @@ class TPersQueue : public NKeyValue::TKeyValueFlat {
//client request
void Handle(TEvPersQueue::TEvRequest::TPtr& ev, const TActorContext& ctx);
#define DESCRIBE_HANDLE(A) void A(const ui64 responseCookie, const TActorId& partActor, \
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx);
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx);
DESCRIBE_HANDLE(HandleGetMaxSeqNoRequest)
DESCRIBE_HANDLE(HandleDeleteSessionRequest)
DESCRIBE_HANDLE(HandleCreateSessionRequest)
@@ -113,7 +113,7 @@ class TPersQueue : public NKeyValue::TKeyValueFlat {
DESCRIBE_HANDLE(HandleSplitMessageGroupRequest)
#undef DESCRIBE_HANDLE
#define DESCRIBE_HANDLE_WITH_SENDER(A) void A(const ui64 responseCookie, const TActorId& partActor, \
- const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,\
+ const NKikimrClient::TPersQueuePartitionRequest& req, const TActorContext& ctx,\
const TActorId& pipeClient, const TActorId& sender);
DESCRIBE_HANDLE_WITH_SENDER(HandleGetOwnershipRequest)
DESCRIBE_HANDLE_WITH_SENDER(HandleReserveBytesRequest)
@@ -126,8 +126,8 @@ class TPersQueue : public NKeyValue::TKeyValueFlat {
static constexpr const char * KeyState() { return "_state"; }
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_ACTOR;
}
TPersQueue(const TActorId& tablet, TTabletStorageInfo *info);
@@ -147,7 +147,7 @@ private:
TString TopicName;
TString TopicPath;
bool LocalDC;
- TString DCId;
+ TString DCId;
TVector<NScheme::TTypeId> KeySchema;
NKikimrPQ::TPQTabletConfig Config;
diff --git a/ydb/core/persqueue/pq_l2_cache.h b/ydb/core/persqueue/pq_l2_cache.h
index f9fcccbc8ed..2937abe3229 100644
--- a/ydb/core/persqueue/pq_l2_cache.h
+++ b/ydb/core/persqueue/pq_l2_cache.h
@@ -73,8 +73,8 @@ public:
ui64 KeyHash;
};
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_CACHE_L2_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_CACHE_L2_ACTOR;
}
TPersQueueCacheL2(const TCacheL2Parameters& params, TIntrusivePtr<NMonitoring::TDynamicCounters> countersGroup)
diff --git a/ydb/core/persqueue/read.h b/ydb/core/persqueue/read.h
index d0bc79c6929..9d9331c6a1a 100644
--- a/ydb/core/persqueue/read.h
+++ b/ydb/core/persqueue/read.h
@@ -17,8 +17,8 @@ namespace NPQ {
/// Intablet cache proxy: Partition <-> CacheProxy <-> KV
class TPQCacheProxy : public TActorBootstrapped<TPQCacheProxy> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_CACHE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_CACHE_ACTOR;
}
TPQCacheProxy(const TActorId& tablet, TString topicName, ui32 size)
diff --git a/ydb/core/persqueue/read_balancer.h b/ydb/core/persqueue/read_balancer.h
index 6a07edcb784..8c8c6b6afda 100644
--- a/ydb/core/persqueue/read_balancer.h
+++ b/ydb/core/persqueue/read_balancer.h
@@ -432,8 +432,8 @@ class TPersQueueReadBalancer : public TActor<TPersQueueReadBalancer>, public TTa
std::deque<TAutoPtr<TEvPersQueue::TEvRegisterReadSession>> RegisterEvents;
std::deque<TAutoPtr<TEvPersQueue::TEvPersQueue::TEvUpdateBalancerConfig>> UpdateEvents;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PERSQUEUE_READ_BALANCER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PERSQUEUE_READ_BALANCER_ACTOR;
}
TPersQueueReadBalancer(const TActorId &tablet, TTabletStorageInfo *info)
diff --git a/ydb/core/persqueue/user_info.cpp b/ydb/core/persqueue/user_info.cpp
index 26811765e20..f6f9cf24d54 100644
--- a/ydb/core/persqueue/user_info.cpp
+++ b/ydb/core/persqueue/user_info.cpp
@@ -29,7 +29,7 @@ namespace NDeprecatedUserData {
} // NDeprecatedUserData
TUsersInfoStorage::TUsersInfoStorage(
- TString dcId,
+ TString dcId,
ui64 tabletId,
const TString& topicName,
ui32 partition,
@@ -39,7 +39,7 @@ TUsersInfoStorage::TUsersInfoStorage(
const TString& dbId,
const TString& folderId
)
- : DCId(std::move(dcId))
+ : DCId(std::move(dcId))
, TabletId(tabletId)
, TopicName(topicName)
, Partition(partition)
diff --git a/ydb/core/persqueue/user_info.h b/ydb/core/persqueue/user_info.h
index 258e947c467..25d4d8ec556 100644
--- a/ydb/core/persqueue/user_info.h
+++ b/ydb/core/persqueue/user_info.h
@@ -540,7 +540,7 @@ private:
private:
THashMap<TString, TUserInfo> UsersInfo;
- const TString DCId;
+ const TString DCId;
ui64 TabletId;
const TString TopicName;
const ui32 Partition;
diff --git a/ydb/core/protos/blobstorage.proto b/ydb/core/protos/blobstorage.proto
index a08ccbf865c..ef377960701 100644
--- a/ydb/core/protos/blobstorage.proto
+++ b/ydb/core/protos/blobstorage.proto
@@ -23,7 +23,7 @@ enum EPutHandleClass {
enum EGetHandleClass {
AsyncRead = 1; // read of tablet's compacted data
FastRead = 2; // reads initiated by the user (fast)
- Discover = 3; // reads from Discover query (OOB)
+ Discover = 3; // reads from Discover query (OOB)
LowRead = 4; // background reads initiabed by the user (should not affect TabletLog and FastRead)
}
@@ -44,7 +44,7 @@ enum EVDiskQueueId {
// EGetHandleClass
GetAsyncRead = 4;
GetFastRead = 5;
- GetDiscover = 6;
+ GetDiscover = 6;
GetLowRead = 7;
// Declare Begin and End last in order to get real names from EVDiskQueueId_Name()
@@ -62,7 +62,7 @@ enum EVDiskInternalQueueId {
IntPutLog = 3;
IntPutHugeForeground = 4;
IntPutHugeBackground = 5;
- IntGetDiscover = 6;
+ IntGetDiscover = 6;
IntLowRead = 7;
IntEnd = 8;
};
@@ -94,60 +94,60 @@ message TWindowFeedback {
}
// execution stats for different kinds of BlobStorage requests; all durations are measured in µs
-message TExecTimeStats {
+message TExecTimeStats {
// dsproxy (i.e. sender) stats
- optional uint64 SubmitTimestamp = 1; // local timestamp of request submission
- optional uint64 InSenderQueue = 2; // time spent in BS_QUEUE or something like that
-
+ optional uint64 SubmitTimestamp = 1; // local timestamp of request submission
+ optional uint64 InSenderQueue = 2; // time spent in BS_QUEUE or something like that
+
// vdisk (i.e. executor) stats
optional uint64 ReceivedTimestamp = 3; // local (to vdisk node) timestamp of request reception
- optional uint64 Total = 4; // total time since reception of query until transmission of reply
- optional uint64 InQueue = 5; // time spent in queue (time spent since reception of query until it was transferred to executor)
- optional uint64 Execution = 6; // time spent while actually executing request
-
- // detailed stats
- optional uint64 HugeWriteTime = 7; // time spent while writing Huge Blob (included in Execution time)
-};
-
-message TMsgQoS {
- optional uint32 DeadlineSeconds = 1;
- optional TMessageId MsgId = 2;
- optional uint64 Cost = 3;
- optional EVDiskQueueId ExtQueueId = 5;
- optional EVDiskInternalQueueId IntQueueId = 6;
- optional TVDiskCostSettings CostSettings = 7;
- optional bool SendMeCostSettings = 8;
- optional TWindowFeedback Window = 9;
- oneof ClientId {
- uint32 ProxyNodeId = 10; // set when client is DS Proxy from specific node
- uint32 ReplVDiskId = 11; // set when client is replication actor from specific vdisk
- uint64 VDiskLoadId = 13; // set when client is load test with specific tag
+ optional uint64 Total = 4; // total time since reception of query until transmission of reply
+ optional uint64 InQueue = 5; // time spent in queue (time spent since reception of query until it was transferred to executor)
+ optional uint64 Execution = 6; // time spent while actually executing request
+
+ // detailed stats
+ optional uint64 HugeWriteTime = 7; // time spent while writing Huge Blob (included in Execution time)
+};
+
+message TMsgQoS {
+ optional uint32 DeadlineSeconds = 1;
+ optional TMessageId MsgId = 2;
+ optional uint64 Cost = 3;
+ optional EVDiskQueueId ExtQueueId = 5;
+ optional EVDiskInternalQueueId IntQueueId = 6;
+ optional TVDiskCostSettings CostSettings = 7;
+ optional bool SendMeCostSettings = 8;
+ optional TWindowFeedback Window = 9;
+ oneof ClientId {
+ uint32 ProxyNodeId = 10; // set when client is DS Proxy from specific node
+ uint32 ReplVDiskId = 11; // set when client is replication actor from specific vdisk
+ uint64 VDiskLoadId = 13; // set when client is load test with specific tag
uint32 VPatchVDiskId = 14; // set when client is vpatch actor from specific vdisk
- }
- optional TExecTimeStats ExecTimeStats = 12;
- optional NActorsProto.TActorId SenderActorId = 15;
-}
-
+ }
+ optional TExecTimeStats ExecTimeStats = 12;
+ optional NActorsProto.TActorId SenderActorId = 15;
+}
+
// message VDisk sends to the client, when backpressure window changes
message TEvVWindowChange {
optional EVDiskQueueId FrontQueueId = 1;
optional TWindowFeedback Window = 2;
- optional bool DropConnection = 3; // emergency connection drop
+ optional bool DropConnection = 3; // emergency connection drop
}
// status flags we provide in responses
enum EStatusFlags { // Never use this type for storage, use ui32 bitset
- StatusIsValid = 1; // 0000 0000 0001, if not set, status flags could not be obtained
- StatusDiskSpaceCyan = 128; // 0000 1000 0000
+ StatusIsValid = 1; // 0000 0000 0001, if not set, status flags could not be obtained
+ StatusDiskSpaceCyan = 128; // 0000 1000 0000
StatusDiskSpaceLightYellowMove = 2; // 0010 0000 0000
StatusDiskSpaceYellowStop = 512; // 0000 0000 0010
- StatusDiskSpaceLightOrange = 256; // 0001 0000 0000
- StatusDiskSpaceOrange = 4; // 0000 0000 0100
- StatusDiskSpaceRed = 8; // 0000 0000 1000
- StatusDiskSpaceBlack = 64; // 0000 0100 0000
+ StatusDiskSpaceLightOrange = 256; // 0001 0000 0000
+ StatusDiskSpaceOrange = 4; // 0000 0000 0100
+ StatusDiskSpaceRed = 8; // 0000 0000 1000
+ StatusDiskSpaceBlack = 64; // 0000 0100 0000
StatusMaskDiskSpace = 974; // 0011 1100 1110
- StatusNewOwner = 16; // 0000 0001 0000
- StatusNotEnoughDiskSpaceForOperation = 32; // 0000 0010 0000
+ StatusNewOwner = 16; // 0000 0001 0000
+ StatusNotEnoughDiskSpaceForOperation = 32; // 0000 0010 0000
}
message TTimestamps {
@@ -157,37 +157,37 @@ message TTimestamps {
optional uint64 ReceivedByDSProxyUs = 4 [default = 0];
}
-enum EEntityStatus {
- INITIAL = 1; // entity was generated from the current state by the configuration request
- CREATE = 2; // entity was just created and notification is being pushed to the warden
- DESTROY = 3; // entity was just destroyed and the notification is being pushed to the warden
+enum EEntityStatus {
+ INITIAL = 1; // entity was generated from the current state by the configuration request
+ CREATE = 2; // entity was just created and notification is being pushed to the warden
+ DESTROY = 3; // entity was just destroyed and the notification is being pushed to the warden
RESTART = 4; // entity has changed config or changed environment and should be restarted by warden
-}
-
-message TGroupInfo {
- message TFailRealm {
- message TFailDomain {
- repeated TVDiskLocation VDiskLocations = 1;
- }
- repeated TFailDomain FailDomains = 1;
- }
-
- optional uint32 GroupID = 1;
- optional uint32 GroupGeneration = 2;
- optional uint32 ErasureSpecies = 3;
- repeated TFailRealm Rings = 4; // name "Rings" for textual compatibility
- optional EEntityStatus EntityStatus = 5;
- optional uint32 EncryptionMode = 6 [default = 0];
- optional uint32 LifeCyclePhase = 7 [default = 0];
+}
+
+message TGroupInfo {
+ message TFailRealm {
+ message TFailDomain {
+ repeated TVDiskLocation VDiskLocations = 1;
+ }
+ repeated TFailDomain FailDomains = 1;
+ }
+
+ optional uint32 GroupID = 1;
+ optional uint32 GroupGeneration = 2;
+ optional uint32 ErasureSpecies = 3;
+ repeated TFailRealm Rings = 4; // name "Rings" for textual compatibility
+ optional EEntityStatus EntityStatus = 5;
+ optional uint32 EncryptionMode = 6 [default = 0];
+ optional uint32 LifeCyclePhase = 7 [default = 0];
optional bytes MainKeyId = 8 [default = ""];
- optional bytes EncryptedGroupKey = 9 [default = ""];
- optional uint64 GroupKeyNonce = 10 [default = 0];
+ optional bytes EncryptedGroupKey = 9 [default = ""];
+ optional uint64 GroupKeyNonce = 10 [default = 0];
optional uint64 MainKeyVersion = 11 [default = 0];
- optional NActorsInterconnect.TScopeId AcceptedScope = 12; // some kind of ACL for scopes; empty = no restrictions
- optional string StoragePoolName = 13;
- optional EPDiskType DeviceType = 14;
-}
-
+ optional NActorsInterconnect.TScopeId AcceptedScope = 12; // some kind of ACL for scopes; empty = no restrictions
+ optional string StoragePoolName = 13;
+ optional EPDiskType DeviceType = 14;
+}
+
message TEvVPatchStart {
optional NKikimrProto.TLogoBlobID OriginalBlobId = 1;
optional NKikimrProto.TLogoBlobID PatchedBlobId = 2;
@@ -358,7 +358,7 @@ message TEvVPut {
optional NKikimrProto.TLogoBlobID BlobID = 1;
optional bytes Buffer = 2;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
optional uint64 FullDataSize = 4;
optional bool IgnoreBlock = 5;
@@ -371,19 +371,19 @@ message TEvVPut {
message TEvVPutResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional string ErrorReason = 200; // textual description of error
+ optional string ErrorReason = 200; // textual description of error
optional NKikimrProto.TLogoBlobID BlobID = 2;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
optional uint64 Cookie = 4;
optional uint32 StatusFlags = 5;
optional TMsgQoS MsgQoS = 10;
optional TTimestamps Timestamps = 23;
optional float ApproximateFreeSpaceShare = 25 [default = 0]; // 0 is a special value for 'unknown'
- optional fixed64 IncarnationGuid = 30;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+ optional fixed64 IncarnationGuid = 30;
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TVMultiPutItem {
@@ -409,7 +409,7 @@ message TEvVMultiPut {
message TVMultiPutResultItem {
optional NKikimrProto.EReplyStatus Status = 1;
- optional string ErrorReason = 200;
+ optional string ErrorReason = 200;
optional NKikimrProto.TLogoBlobID BlobID = 2;
optional uint64 Cookie = 3;
@@ -418,7 +418,7 @@ message TVMultiPutResultItem {
message TEvVMultiPutResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional string ErrorReason = 200;
+ optional string ErrorReason = 200;
repeated TVMultiPutResultItem Items = 2;
optional TVDiskID VDiskID = 3;
@@ -428,9 +428,9 @@ message TEvVMultiPutResult {
optional TTimestamps Timestamps = 23;
optional float ApproximateFreeSpaceShare = 25 [default = 0]; // 0 is a special value for 'unknown'
- optional fixed64 IncarnationGuid = 30;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+ optional fixed64 IncarnationGuid = 30;
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TRangeQuery {
@@ -455,15 +455,15 @@ message TEvVGet {
optional TRangeQuery RangeQuery = 5;
repeated TExtremeQuery ExtremeQueries = 6;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
optional bool NotifyIfNotReady = 3;
optional bool ShowInternals = 4;
optional uint64 Cookie = 9;
optional TMsgQoS MsgQoS = 10;
optional bool IndexOnly = 12 [default = false];
optional EGetHandleClass HandleClass = 13;
-
- optional bool SuppressBarrierCheck = 20 [default = false]; // set to true to prevent hull from validating barriers
+
+ optional bool SuppressBarrierCheck = 20 [default = false]; // set to true to prevent hull from validating barriers
optional uint64 TabletId = 21 [default = 0]; // tabletId to get the blocked generation for
optional bool AcquireBlockedGeneration = 22 [default = false]; // set to true to get the blocked generation
@@ -483,14 +483,14 @@ message TQueryResult {
optional uint64 FullDataSize = 7;
optional uint64 Ingress = 8;
-
- repeated uint32 Parts = 9; // part id's (>0) residing on this disk; returned only through index range queries
+
+ repeated uint32 Parts = 9; // part id's (>0) residing on this disk; returned only through index range queries
}
message TEvVGetResult {
optional NKikimrProto.EReplyStatus Status = 1;
repeated TQueryResult Result = 2;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
optional uint64 Cookie = 5;
optional TMsgQoS MsgQoS = 10;
@@ -498,18 +498,18 @@ message TEvVGetResult {
optional uint32 BlockedGeneration = 11 [default = 0];
optional TTimestamps Timestamps = 23;
- optional bool IsRangeOverflow = 24 [default = false]; // true if RangeQuery response is too large and is cut
- optional fixed64 IncarnationGuid = 30;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+ optional bool IsRangeOverflow = 24 [default = false]; // true if RangeQuery response is too large and is cut
+ optional fixed64 IncarnationGuid = 30;
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TEvVBlock {
optional uint64 TabletId = 1;
optional uint32 Generation = 2;
- optional uint64 IssuerGuid = 5;
+ optional uint64 IssuerGuid = 5;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
optional bool NotifyIfNotReady = 4;
optional TMsgQoS MsgQoS = 10;
}
@@ -519,17 +519,17 @@ message TEvVBlockResult {
optional uint64 TabletId = 2;
optional uint32 Generation = 3;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
optional TMsgQoS MsgQoS = 10;
-
- optional fixed64 IncarnationGuid = 30;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+
+ optional fixed64 IncarnationGuid = 30;
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TEvVGetBlock {
optional uint64 TabletId = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
optional bool NotifyIfNotReady = 3;
optional TMsgQoS MsgQoS = 10;
@@ -540,10 +540,10 @@ message TEvVGetBlockResult {
optional uint64 TabletId = 2;
optional uint32 Generation = 3;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
optional TMsgQoS MsgQoS = 10;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TEvVCollectGarbage {
@@ -553,12 +553,12 @@ message TEvVCollectGarbage {
optional uint32 Channel = 3;
optional uint32 CollectGeneration = 4;
optional uint32 CollectStep = 5;
- optional bool Hard = 12 [default = false];
+ optional bool Hard = 12 [default = false];
repeated NKikimrProto.TLogoBlobID Keep = 6;
repeated NKikimrProto.TLogoBlobID DoNotKeep = 7;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 8;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 8;
optional bool NotifyIfNotReady = 9;
optional TMsgQoS MsgQoS = 10;
}
@@ -569,12 +569,12 @@ message TEvVCollectGarbageResult {
optional uint32 RecordGeneration = 3;
optional uint32 Channel = 4;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 5;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 5;
optional TMsgQoS MsgQoS = 10;
-
- optional fixed64 IncarnationGuid = 30;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+
+ optional fixed64 IncarnationGuid = 30;
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
message TBarrierKey {
@@ -582,7 +582,7 @@ message TBarrierKey {
optional uint32 Channel = 2;
optional uint32 RecordGeneration = 3;
optional uint32 PerGenerationCounter = 4;
- optional bool Hard = 5;
+ optional bool Hard = 5;
}
message TBarrierVal {
@@ -599,7 +599,7 @@ message TEvVGetBarrier {
optional TBarrierKey To = 2;
optional uint32 MaxResults = 3;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 4;
optional bool NotifyIfNotReady = 5;
optional bool ShowInternals = 6;
optional TMsgQoS MsgQoS = 10;
@@ -609,29 +609,29 @@ message TEvVGetBarrierResult {
optional NKikimrProto.EReplyStatus Status = 1;
repeated TBarrierKey Keys = 2;
repeated TBarrierVal Values = 4;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
optional TMsgQoS MsgQoS = 10;
-
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
-}
-
-// check if disk is ready or not (i.e. will return NOTREADY in reply to next request)
-message TEvVCheckReadiness {
- optional bool NotifyIfNotReady = 1;
- //optional bool SupportProtoWithPayload = 2;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
- optional TGroupInfo RecentGroup = 4;
- optional TMsgQoS QoS = 5; // queue and client identification is required
-}
-
-message TEvVCheckReadinessResult {
- optional NKikimrProto.EReplyStatus Status = 1;
- //optional bool SupportProtoWithPayload = 2;
- optional TMessageId ExpectedMsgId = 3;
- optional TVDiskCostSettings CostSettings = 4;
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
-}
-
+
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+}
+
+// check if disk is ready or not (i.e. will return NOTREADY in reply to next request)
+message TEvVCheckReadiness {
+ optional bool NotifyIfNotReady = 1;
+ //optional bool SupportProtoWithPayload = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 3;
+ optional TGroupInfo RecentGroup = 4;
+ optional TMsgQoS QoS = 5; // queue and client identification is required
+}
+
+message TEvVCheckReadinessResult {
+ optional NKikimrProto.EReplyStatus Status = 1;
+ //optional bool SupportProtoWithPayload = 2;
+ optional TMessageId ExpectedMsgId = 3;
+ optional TVDiskCostSettings CostSettings = 4;
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+}
+
message TEvVReadyNotify {
}
@@ -676,8 +676,8 @@ message TLocalGuidInfo {
}
message TEvVSyncGuid {
- optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
- optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
+ optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
+ optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
optional bool NotifyIfNotReady = 4;
// if Info is absent ==> we send TEvVSyncGuid to read remote vdisk state
@@ -687,7 +687,7 @@ message TEvVSyncGuid {
message TEvVSyncGuidResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
// if we answer to read request ==> ReadInfo contains result
// if we answer to write request ==> ReadInfo is empty
@@ -697,8 +697,8 @@ message TEvVSyncGuidResult {
message TEvVSync {
optional TSyncState SyncState = 1;
- optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
- optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
+ optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
+ optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
optional bool NotifyIfNotReady = 4;
}
@@ -709,7 +709,7 @@ message TEvVSyncResult {
optional bool Finished = 4;
optional bytes Data = 5;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 6;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 6;
message TStat {
optional uint32 DiskReads = 1;
@@ -727,8 +727,8 @@ enum ESyncFullStage {
message TEvVSyncFull {
optional TSyncState SyncState = 1;
- optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
- optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
+ optional NKikimrBlobStorage.TVDiskID SourceVDiskID = 2; // sync this vdisk with ...
+ optional NKikimrBlobStorage.TVDiskID TargetVDiskID = 3; // ... this vdisk
optional bool NotifyIfNotReady = 4;
optional uint64 Cookie = 5;
@@ -745,7 +745,7 @@ message TEvVSyncFullResult {
optional bool Finished = 4;
optional bytes Data = 5;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 6;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 6;
optional uint64 Cookie = 7;
optional ESyncFullStage Stage = 11;
@@ -800,7 +800,7 @@ message TLocalRecoveryInfo {
}
message TEvVStatus {
- optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional bool NotifyIfNotReady = 2;
}
@@ -812,12 +812,12 @@ message TEvVStatusResult {
optional TSyncerStatus SyncerStatus = 5;
optional TSyncLogStatus SyncLogStatus = 6;
optional TLocalRecoveryInfo LocalRecoveryInfo = 7;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 8;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 8;
optional uint32 StatusFlags = 9; // flags from EStatusFlags
- optional bool JoinedGroup = 10;
- optional bool Replicated = 11 [default = false];
- optional fixed64 IncarnationGuid = 30;
- optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
+ optional bool JoinedGroup = 10;
+ optional bool Replicated = 11 [default = false];
+ optional fixed64 IncarnationGuid = 30;
+ optional TGroupInfo RecentGroup = 100; // filled in by VDisk on RACE when VDisk has newer generation
}
// what db we address our query to
@@ -843,7 +843,7 @@ message TEvVDbStat {
optional uint32 Channel = 2;
}
- optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional bool NotifyIfNotReady = 2;
optional EDbStatType Type = 3;
optional EDbStatAction Action = 4;
@@ -854,7 +854,7 @@ message TEvVDbStat {
message TEvVDbStatResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
optional EDbStatType Type = 3;
optional EDbStatAction Action = 4;
@@ -873,7 +873,7 @@ message TEvVCompact {
// get compaction status
STATUS = 3;
}
- optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional bool NotifyIfNotReady = 2;
optional EOpType OpType = 3 [default = UNKNOWN];
// select databases to compact:
@@ -884,7 +884,7 @@ message TEvVCompact {
message TEvVCompactResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
}
// run manual huge heap defrag
@@ -912,22 +912,22 @@ message TEvVDefragResult {
// Say SyncLog to cut its log; for test/debug purposes only
message TEvVBaldSyncLog {
- optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional bool NotifyIfNotReady = 2;
}
message TEvVBaldSyncLogResult {
optional NKikimrProto.EReplyStatus Status = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
-}
-
-message TVDiskLocation {
- optional uint32 NodeID = 1;
- optional uint32 PDiskID = 2;
- optional uint32 VDiskSlotID = 3;
- optional uint64 PDiskGuid = 4;
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 2;
}
+message TVDiskLocation {
+ optional uint32 NodeID = 1;
+ optional uint32 PDiskID = 2;
+ optional uint32 VDiskSlotID = 3;
+ optional uint64 PDiskGuid = 4;
+}
+
message TNodeWardenServiceSet {
message TPDisk {
optional uint32 NodeID = 1; // optional parameter for static configuration
@@ -936,9 +936,9 @@ message TNodeWardenServiceSet {
optional uint64 PDiskGuid = 5;
optional uint64 PDiskCategory = 6;
- optional TPDiskConfig PDiskConfig = 7; // optional, pdisk will use the default config if not set
-
- optional EEntityStatus EntityStatus = 9;
+ optional TPDiskConfig PDiskConfig = 7; // optional, pdisk will use the default config if not set
+
+ optional EEntityStatus EntityStatus = 9;
optional uint64 InMemoryForTestsBufferBytes = 10 [default = 0]; // non zero == force in-memory pdisk use
optional string ExpectedSerial = 11; // optional, used for serial number check in PDisk
@@ -948,57 +948,57 @@ message TNodeWardenServiceSet {
}
message TVDisk {
- message TDonor {
- optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
- optional TVDiskLocation VDiskLocation = 2;
- }
- message TDonorMode {
- optional uint32 NumFailRealms = 1;
- optional uint32 NumFailDomainsPerFailRealm = 2;
- optional uint32 NumVDisksPerFailDomain = 3;
- optional uint32 ErasureSpecies = 4;
- }
- optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
+ message TDonor {
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ optional TVDiskLocation VDiskLocation = 2;
+ }
+ message TDonorMode {
+ optional uint32 NumFailRealms = 1;
+ optional uint32 NumFailDomainsPerFailRealm = 2;
+ optional uint32 NumVDisksPerFailDomain = 3;
+ optional uint32 ErasureSpecies = 4;
+ }
+ optional NKikimrBlobStorage.TVDiskID VDiskID = 1;
optional TVDiskLocation VDiskLocation = 2;
optional TVDiskKind.EVDiskKind VDiskKind = 3;
optional bool DoDestroy = 4 [default = false];
optional bool DoWipe = 5 [default = false];
- optional EEntityStatus EntityStatus = 6;
- optional string StoragePoolName = 8;
- optional TDonorMode DonorMode = 9; // vdisk runs in read-only limited mode without interaction with other disks of group
- repeated TDonor Donors = 10; // a set of donor disks used to accelerate replication
- }
-
- message TReplBrokerConfig {
- message TMediaTypeQuota {
- optional EPDiskType Type = 1;
- optional uint64 ReadBytesPerSecond = 2; // quota to be enforced on VDisk measured at VDisk/PDisk border
- optional uint64 WriteBytesPerSecond = 3; // quota for VDisk-issued PDisk writes (huge blobs and replicated SSTs)
- }
-
- optional uint64 RateBytesPerSecond = 1 [default = 10000000000]; // bytes per second, 10 GB/s
- optional uint64 CapacityMilliseconds = 2 [default = 100]; // 100 ms
- optional uint64 MaxInFlightReadBytes = 3 [default = 335544320]; // 320 MiB
- repeated TMediaTypeQuota MediaTypeQuota = 4;
- optional uint64 TotalRequestBytesPerSecond = 5; // quota for generated requests measured at network layer
- optional uint64 TotalResponseBytesPerSecond = 6; // quota for generated responses at network layer
+ optional EEntityStatus EntityStatus = 6;
+ optional string StoragePoolName = 8;
+ optional TDonorMode DonorMode = 9; // vdisk runs in read-only limited mode without interaction with other disks of group
+ repeated TDonor Donors = 10; // a set of donor disks used to accelerate replication
}
+ message TReplBrokerConfig {
+ message TMediaTypeQuota {
+ optional EPDiskType Type = 1;
+ optional uint64 ReadBytesPerSecond = 2; // quota to be enforced on VDisk measured at VDisk/PDisk border
+ optional uint64 WriteBytesPerSecond = 3; // quota for VDisk-issued PDisk writes (huge blobs and replicated SSTs)
+ }
+
+ optional uint64 RateBytesPerSecond = 1 [default = 10000000000]; // bytes per second, 10 GB/s
+ optional uint64 CapacityMilliseconds = 2 [default = 100]; // 100 ms
+ optional uint64 MaxInFlightReadBytes = 3 [default = 335544320]; // 320 MiB
+ repeated TMediaTypeQuota MediaTypeQuota = 4;
+ optional uint64 TotalRequestBytesPerSecond = 5; // quota for generated requests measured at network layer
+ optional uint64 TotalResponseBytesPerSecond = 6; // quota for generated responses at network layer
+ }
+
repeated TPDisk PDisks = 1;
repeated TVDisk VDisks = 2;
- repeated TGroupInfo Groups = 3;
+ repeated TGroupInfo Groups = 3;
repeated uint64 AvailabilityDomains = 4;
- optional TReplBrokerConfig ReplBrokerConfig = 5;
- // optional NActorsInterconnect.TNodeLocation PhysicalLocation = 6; // DEPRECATED
- optional bool EnableProxyMock = 7;
-}
-
-message TNodeWardenCache {
- optional uint64 AvailDomain = 1;
- optional string InstanceId = 2;
- optional TNodeWardenServiceSet ServiceSet = 3;
+ optional TReplBrokerConfig ReplBrokerConfig = 5;
+ // optional NActorsInterconnect.TNodeLocation PhysicalLocation = 6; // DEPRECATED
+ optional bool EnableProxyMock = 7;
}
+message TNodeWardenCache {
+ optional uint64 AvailDomain = 1;
+ optional string InstanceId = 2;
+ optional TNodeWardenServiceSet ServiceSet = 3;
+}
+
message TMockDevicesConfig {
repeated TDriveData Devices = 1;
}
@@ -1014,11 +1014,11 @@ message TDriveData {
}
message TEvControllerRegisterNode {
- reserved 1;
+ reserved 1;
optional uint32 NodeID = 2;
repeated uint32 Groups = 4;
- repeated uint32 GroupGenerations = 5; // must be zero entries (for old nodes) and the same number as in Groups for new ones
- repeated TVDiskStatus VDiskStatus = 6; // actual status for currently operating VDisks
+ repeated uint32 GroupGenerations = 5; // must be zero entries (for old nodes) and the same number as in Groups for new ones
+ repeated TVDiskStatus VDiskStatus = 6; // actual status for currently operating VDisks
repeated TDriveData DrivesData = 7;
}
@@ -1027,24 +1027,24 @@ message TEvControllerUpdateNodeDrives {
repeated TDriveData DrivesData = 2;
}
-message TEvControllerNodeServiceSetUpdate {
- message TGroupMetadata {
- optional uint32 GroupId = 1;
- optional uint32 CurrentGeneration = 2; // current state in the database
- }
-
+message TEvControllerNodeServiceSetUpdate {
+ message TGroupMetadata {
+ optional uint32 GroupId = 1;
+ optional uint32 CurrentGeneration = 2; // current state in the database
+ }
+
optional NKikimrProto.EReplyStatus Status = 1;
optional uint32 NodeID = 2;
optional TNodeWardenServiceSet ServiceSet = 3;
- repeated TGroupMetadata GroupMetadata = 4;
- optional string InstanceId = 5;
- optional bool Comprehensive = 6; // if this flag is set to true, then there will be no any other entities than elisted in the ServiceSet
- optional uint64 AvailDomain = 7; // availability domain of the controller
+ repeated TGroupMetadata GroupMetadata = 4;
+ optional string InstanceId = 5;
+ optional bool Comprehensive = 6; // if this flag is set to true, then there will be no any other entities than elisted in the ServiceSet
+ optional uint64 AvailDomain = 7; // availability domain of the controller
}
message TEvControllerGroupReconfigureWipe {
- reserved 1;
- optional NKikimrBlobStorage.TVSlotId VSlotId = 2;
+ reserved 1;
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 2;
}
message TEvControllerGroupReconfigureWipeResult {
@@ -1052,16 +1052,16 @@ message TEvControllerGroupReconfigureWipeResult {
optional string ErrorReason = 2;
}
-message TEvControllerConfigRequest {
- reserved 1;
+message TEvControllerConfigRequest {
+ reserved 1;
optional NKikimrBlobStorage.TConfigRequest Request = 2;
- reserved 3;
-}
+ reserved 3;
+}
-message TEvControllerConfigResponse {
+message TEvControllerConfigResponse {
optional NKikimrBlobStorage.TConfigResponse Response = 1;
- reserved 2;
-}
+ reserved 2;
+}
message TEvControllerGetGroup {
optional uint32 NodeID = 1;
@@ -1092,10 +1092,10 @@ message TStorageOwnerInfo {
}
message TEvControllerSelectGroups {
- message TStoragePoolSpecifier {
- optional string Name = 1; // filter by name if set
- optional string Kind = 2; // filter by kind if set
- }
+ message TStoragePoolSpecifier {
+ optional string Name = 1; // filter by name if set
+ optional string Kind = 2; // filter by kind if set
+ }
message TGroupParameters {
optional uint32 ErasureSpecies = 1;
optional uint64 DesiredPDiskCategory = 2;
@@ -1103,127 +1103,127 @@ message TEvControllerSelectGroups {
optional float RequiredIOPS = 4;
optional uint64 RequiredThroughput = 5;
optional uint64 RequiredDataSize = 6;
- optional TStoragePoolSpecifier StoragePoolSpecifier = 7;
+ optional TStoragePoolSpecifier StoragePoolSpecifier = 7;
}
- reserved 1;
- reserved 2;
+ reserved 1;
+ reserved 2;
repeated TGroupParameters GroupParameters = 3;
optional TStorageOwnerInfo StorageOwnerInfo = 4;
- optional uint64 ObjectId = 5; // scheme object id
- optional bool ReturnAllMatchingGroups = 6; // when true, then all matching groups are returned
- optional bool BlockUntilAllResourcesAreComplete = 7; // do not respond unless resources for all groups are filled up
- optional bool OnlySeenOperational = 8; // report only those groups which were seen working at any time
-}
-
-// VDiskStatus ordering is assumed to be lower for bad statuses and higher for good ones
-enum EVDiskStatus {
- ERROR = 0; // the disk is not operational at all
- INIT_PENDING = 1; // initialization in process
- REPLICATING = 2; // the disk accepts queries, but not all the data was replicated
- READY = 3; // the disk is fully operational and does not affect group fault tolerance
-}
-
-message TVDiskStatus {
- // identification part
- optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
- optional uint32 NodeId = 2;
- optional uint32 PDiskId = 3;
- optional uint32 VSlotId = 4;
- optional uint64 PDiskGuid = 5;
-
- // payload
- optional EVDiskStatus Status = 6;
-}
-
-message TEvControllerUpdateDiskStatus {
- repeated NKikimrBlobStorage.TVDiskMetrics VDisksMetrics = 1;
- repeated NKikimrBlobStorage.TPDiskMetrics PDisksMetrics = 2;
- repeated TVDiskStatus VDiskStatus = 3;
-}
-
-message TEvGroupStatReport {
- message TLatencyHistogram {
- repeated uint32 Buckets = 1;
- }
- optional uint32 GroupId = 1;
+ optional uint64 ObjectId = 5; // scheme object id
+ optional bool ReturnAllMatchingGroups = 6; // when true, then all matching groups are returned
+ optional bool BlockUntilAllResourcesAreComplete = 7; // do not respond unless resources for all groups are filled up
+ optional bool OnlySeenOperational = 8; // report only those groups which were seen working at any time
+}
+
+// VDiskStatus ordering is assumed to be lower for bad statuses and higher for good ones
+enum EVDiskStatus {
+ ERROR = 0; // the disk is not operational at all
+ INIT_PENDING = 1; // initialization in process
+ REPLICATING = 2; // the disk accepts queries, but not all the data was replicated
+ READY = 3; // the disk is fully operational and does not affect group fault tolerance
+}
+
+message TVDiskStatus {
+ // identification part
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ optional uint32 NodeId = 2;
+ optional uint32 PDiskId = 3;
+ optional uint32 VSlotId = 4;
+ optional uint64 PDiskGuid = 5;
+
+ // payload
+ optional EVDiskStatus Status = 6;
+}
+
+message TEvControllerUpdateDiskStatus {
+ repeated NKikimrBlobStorage.TVDiskMetrics VDisksMetrics = 1;
+ repeated NKikimrBlobStorage.TPDiskMetrics PDisksMetrics = 2;
+ repeated TVDiskStatus VDiskStatus = 3;
+}
+
+message TEvGroupStatReport {
+ message TLatencyHistogram {
+ repeated uint32 Buckets = 1;
+ }
+ optional uint32 GroupId = 1;
optional NActorsProto.TActorId VDiskServiceId = 2;
- optional TLatencyHistogram PutTabletLog = 10;
- optional TLatencyHistogram PutUserData = 11;
- optional TLatencyHistogram GetFast = 12;
-}
-
-message TEvControllerUpdateGroupStat {
- repeated TEvGroupStatReport PerGroupReport = 1;
-}
-
+ optional TLatencyHistogram PutTabletLog = 10;
+ optional TLatencyHistogram PutUserData = 11;
+ optional TLatencyHistogram GetFast = 12;
+}
+
+message TEvControllerUpdateGroupStat {
+ repeated TEvGroupStatReport PerGroupReport = 1;
+}
+
message TEvControllerSelectGroupsResult {
message TGroupParameters {
optional uint32 ErasureSpecies = 1;
optional uint32 GroupID = 2;
- optional string StoragePoolName = 3; // if it was selected from the storage pool
-
- reserved 4;
-
- // group resourcs (as seen by user, that is, including erasure encoding and so on)
- message TResources {
- optional uint64 Space = 1; // bytes
- optional double IOPS = 2; // operations per second
- optional uint64 ReadThroughput = 3; // bytes per second
- optional uint64 WriteThroughput = 4; // bytes per second
- optional double Occupancy = 5; // part of full slot size of the worst VDisk of group
- }
-
- // assured part of group metrics -- when the underlying PDisks have all possible VSlots created; these metrics
- // are expected not to degrade over time, including vdisk movement; however, everything is possible :)
- optional TResources AssuredResources = 7;
-
- // instant part of group metrics -- with current VSlot count over PDisks
- optional TResources CurrentResources = 8;
-
- // VDisk metrics for this group
- optional uint64 AvailableSize = 9; // bytes as reported by VDisk metrics (pessimistic case)
- optional uint64 AllocatedSize = 10; // the same basis
- optional NKikimrBlobStorage.TPDiskSpaceColor.E SpaceColor = 11;
- }
- message TMatchingGroupList {
- repeated TGroupParameters Groups = 1;
+ optional string StoragePoolName = 3; // if it was selected from the storage pool
+
+ reserved 4;
+
+ // group resourcs (as seen by user, that is, including erasure encoding and so on)
+ message TResources {
+ optional uint64 Space = 1; // bytes
+ optional double IOPS = 2; // operations per second
+ optional uint64 ReadThroughput = 3; // bytes per second
+ optional uint64 WriteThroughput = 4; // bytes per second
+ optional double Occupancy = 5; // part of full slot size of the worst VDisk of group
+ }
+
+ // assured part of group metrics -- when the underlying PDisks have all possible VSlots created; these metrics
+ // are expected not to degrade over time, including vdisk movement; however, everything is possible :)
+ optional TResources AssuredResources = 7;
+
+ // instant part of group metrics -- with current VSlot count over PDisks
+ optional TResources CurrentResources = 8;
+
+ // VDisk metrics for this group
+ optional uint64 AvailableSize = 9; // bytes as reported by VDisk metrics (pessimistic case)
+ optional uint64 AllocatedSize = 10; // the same basis
+ optional NKikimrBlobStorage.TPDiskSpaceColor.E SpaceColor = 11;
}
+ message TMatchingGroupList {
+ repeated TGroupParameters Groups = 1;
+ }
optional NKikimrProto.EReplyStatus Status = 1;
optional uint64 Cookie = 2;
- //repeated TGroupParameters Groups = 3; // deprecated
- optional bool NewStyleQuerySupported = 4; // must be set to true
- repeated TMatchingGroupList MatchingGroups = 5; // when ReturnAllMatchingGroups is set to true
-}
-
-message TEvControllerScrubQueryStartQuantum {
- optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
-}
-
-message TEvControllerScrubStartQuantum {
- optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
- optional bytes State = 2; // serialized state; if not set, then scrub is not in progress
-}
-
-message TEvControllerScrubQuantumFinished {
- optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
- oneof Outcome {
- bytes State = 2; // intermediate scrub state or ...
- bool Success = 3; // successful (or unsuccessful) result
- }
-}
-
-message TEvControllerScrubReportQuantumInProgress {
- optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
-}
-
+ //repeated TGroupParameters Groups = 3; // deprecated
+ optional bool NewStyleQuerySupported = 4; // must be set to true
+ repeated TMatchingGroupList MatchingGroups = 5; // when ReturnAllMatchingGroups is set to true
+}
+
+message TEvControllerScrubQueryStartQuantum {
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
+}
+
+message TEvControllerScrubStartQuantum {
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ optional bytes State = 2; // serialized state; if not set, then scrub is not in progress
+}
+
+message TEvControllerScrubQuantumFinished {
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ oneof Outcome {
+ bytes State = 2; // intermediate scrub state or ...
+ bool Success = 3; // successful (or unsuccessful) result
+ }
+}
+
+message TEvControllerScrubReportQuantumInProgress {
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
+}
+
message TEvRequestBSControllerInfo {
optional uint32 GroupId = 1;
}
message TEvResponseBSControllerInfo {
message TVDiskInfo {
- optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
optional uint32 PDiskId = 2;
optional uint32 NodeId = 3;
optional uint64 PDiskCategory = 4;
@@ -1233,10 +1233,10 @@ message TEvResponseBSControllerInfo {
optional uint32 GroupId = 1;
optional uint32 ErasureSpecies = 2;
repeated TVDiskInfo VDiskInfo = 3;
- //optional uint64 ReadThroughput = 4; // bytes per second
- //optional uint64 WriteThroughput = 5; // bytes per second
+ //optional uint64 ReadThroughput = 4; // bytes per second
+ //optional uint64 WriteThroughput = 5; // bytes per second
optional uint64 DataSize = 6;
- //optional uint64 Counter = 7; // usage counter
+ //optional uint64 Counter = 7; // usage counter
}
repeated TBSGroupInfo BSGroupInfo = 1;
}
@@ -1244,153 +1244,153 @@ message TEvResponseBSControllerInfo {
message TEvControllerNodeReport {
enum EVDiskPhase {
UNKNOWN = 0;
- // NORMAL = 1; // unused one
+ // NORMAL = 1; // unused one
WIPED = 2;
DESTROYED = 3;
OPERATION_ERROR = 4;
- DROP_DONOR = 5;
+ DROP_DONOR = 5;
}
message TVDiskReport {
- optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
- optional NKikimrBlobStorage.TVDiskID VDiskId = 2;
+ optional NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 2;
optional EVDiskPhase Phase = 3;
- optional NKikimrBlobStorage.TVDiskID OtherVDiskId = 4;
+ optional NKikimrBlobStorage.TVDiskID OtherVDiskId = 4;
}
optional uint32 NodeId = 1;
repeated TVDiskReport VDiskReports = 2;
}
-message TEvTestLoadRequest {
- // an item for interval distribution setting
- message TIntervalInfo {
- message TIntervalUniform {
- optional uint32 MinMs = 1;
- optional uint32 MaxMs = 2;
- optional uint32 MinUs = 3;
- optional uint32 MaxUs = 4;
- }
- message TIntervalPoisson {
- optional double Frequency = 1; // Hz
- optional uint32 MaxIntervalMs = 2;
- }
- optional double Weight = 1;
- oneof Distribution {
- TIntervalUniform Uniform = 2;
- TIntervalPoisson Poisson = 3;
- }
- }
- // an item for size distribution setting
- message TSizeInfo {
- optional uint32 Min = 1;
- optional uint32 Max = 2;
- optional double Weight = 3;
- }
- message TLoadStart {
+message TEvTestLoadRequest {
+ // an item for interval distribution setting
+ message TIntervalInfo {
+ message TIntervalUniform {
+ optional uint32 MinMs = 1;
+ optional uint32 MaxMs = 2;
+ optional uint32 MinUs = 3;
+ optional uint32 MaxUs = 4;
+ }
+ message TIntervalPoisson {
+ optional double Frequency = 1; // Hz
+ optional uint32 MaxIntervalMs = 2;
+ }
+ optional double Weight = 1;
+ oneof Distribution {
+ TIntervalUniform Uniform = 2;
+ TIntervalPoisson Poisson = 3;
+ }
+ }
+ // an item for size distribution setting
+ message TSizeInfo {
+ optional uint32 Min = 1;
+ optional uint32 Max = 2;
+ optional double Weight = 3;
+ }
+ message TLoadStart {
message TRequestInfo {
optional float SendTime = 1;
optional uint64 Type = 2;
optional uint32 Size = 3;
optional EPutHandleClass PutHandleClass = 4;
}
- message TTabletInfo {
- optional uint64 TabletId = 1;
- optional uint32 Channel = 2;
- optional uint32 GroupId = 3;
- optional uint32 Generation = 4;
+ message TTabletInfo {
+ optional uint64 TabletId = 1;
+ optional uint32 Channel = 2;
+ optional uint32 GroupId = 3;
+ optional uint32 Generation = 4;
repeated TRequestInfo Requests = 5;
optional float ScriptedCycleDurationSec = 6;
- }
- message TPerTabletProfile {
- repeated TTabletInfo Tablets = 1;
- repeated TSizeInfo Sizes = 2;
- repeated TIntervalInfo WriteIntervals = 3;
- optional uint32 MaxInFlightRequests = 4;
- optional uint32 MaxInFlightBytes = 5;
- repeated TIntervalInfo FlushIntervals = 6;
- optional EPutHandleClass PutHandleClass = 7;
- optional bool Soft = 8;
- optional uint32 MaxInFlightReadRequests = 9;
- optional uint32 MaxInFlightReadBytes = 10;
- repeated TIntervalInfo ReadIntervals = 11;
- repeated TSizeInfo ReadSizes = 12;
+ }
+ message TPerTabletProfile {
+ repeated TTabletInfo Tablets = 1;
+ repeated TSizeInfo Sizes = 2;
+ repeated TIntervalInfo WriteIntervals = 3;
+ optional uint32 MaxInFlightRequests = 4;
+ optional uint32 MaxInFlightBytes = 5;
+ repeated TIntervalInfo FlushIntervals = 6;
+ optional EPutHandleClass PutHandleClass = 7;
+ optional bool Soft = 8;
+ optional uint32 MaxInFlightReadRequests = 9;
+ optional uint32 MaxInFlightReadBytes = 10;
+ repeated TIntervalInfo ReadIntervals = 11;
+ repeated TSizeInfo ReadSizes = 12;
optional uint64 MaxTotalBytesWritten = 13;
optional EGetHandleClass GetHandleClass = 14;
- };
- optional uint64 Tag = 1;
- optional uint32 DurationSeconds = 2;
- optional bool RequestTracking = 3 [default = false];
- repeated TPerTabletProfile Tablets = 4;
- optional uint64 ScheduleThresholdUs = 5;
- optional uint64 ScheduleRoundingUs = 6;
- }
- message TLoadStop {
- optional uint64 Tag = 1;
+ };
+ optional uint64 Tag = 1;
+ optional uint32 DurationSeconds = 2;
+ optional bool RequestTracking = 3 [default = false];
+ repeated TPerTabletProfile Tablets = 4;
+ optional uint64 ScheduleThresholdUs = 5;
+ optional uint64 ScheduleRoundingUs = 6;
+ }
+ message TLoadStop {
+ optional uint64 Tag = 1;
optional bool RemoveAllTags = 2;
- }
- enum ELogMode {
- LOG_PARALLEL = 1;
- LOG_SEQUENTIAL = 2;
- LOG_NONE = 3;
- }
- message TPDiskLoadStart {
- message TChunkInfo {
- optional uint32 Slots = 1; // number of slots per chunk
- optional uint32 Weight = 2; // probability weight
- }
- optional uint64 Tag = 1;
- optional uint32 PDiskId = 2;
- optional uint64 PDiskGuid = 3;
- optional NKikimrBlobStorage.TVDiskID VDiskId = 4;
- repeated TChunkInfo Chunks = 5;
- optional uint32 DurationSeconds = 6;
- optional uint32 InFlightWrites = 7;
- optional ELogMode LogMode = 8;
- optional bool Sequential = 9 [default = true];
+ }
+ enum ELogMode {
+ LOG_PARALLEL = 1;
+ LOG_SEQUENTIAL = 2;
+ LOG_NONE = 3;
+ }
+ message TPDiskLoadStart {
+ message TChunkInfo {
+ optional uint32 Slots = 1; // number of slots per chunk
+ optional uint32 Weight = 2; // probability weight
+ }
+ optional uint64 Tag = 1;
+ optional uint32 PDiskId = 2;
+ optional uint64 PDiskGuid = 3;
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 4;
+ repeated TChunkInfo Chunks = 5;
+ optional uint32 DurationSeconds = 6;
+ optional uint32 InFlightWrites = 7;
+ optional ELogMode LogMode = 8;
+ optional bool Sequential = 9 [default = true];
optional uint32 IntervalMsMin = 10;
optional uint32 IntervalMsMax = 11;
- optional bool Reuse = 12 [default = false];
+ optional bool Reuse = 12 [default = false];
optional bool IsWardenlessTest = 13 [default = false];
- }
- message TVDiskLoadStart {
- optional uint64 Tag = 1;
-
- // full VDisk identifier
- optional NKikimrBlobStorage.TVDiskID VDiskId = 2;
-
- reserved 3; // obsolete field
- reserved 4; // obsolete field
- optional TGroupInfo GroupInfo = 16;
-
- // tablet id, channel and generation used in blob ids and barriers
- optional uint64 TabletId = 5;
- optional uint32 Channel = 6;
- optional uint32 Generation = 7;
-
- // duration of the test in seconds
- optional uint32 DurationSeconds = 8;
-
- // a distribution of intervals between adjacent writes
- repeated TIntervalInfo WriteIntervals = 9;
-
- // a distribution of write block sizes (expressed in bytes of BlobSize; i.e. PartSize bytes are actually written)
- repeated TSizeInfo WriteSizes = 10;
-
- // maximum number of unconfirmed parallel writes
- optional uint32 InFlightPutsMax = 11;
-
- // soft maximum of total in flight put bytes
- optional uint64 InFlightPutBytesMax = 12;
-
- // put handle class
- optional EPutHandleClass PutHandleClass = 13;
-
- // a distribution of intervals between barrier advances
- repeated TIntervalInfo BarrierAdvanceIntervals = 14;
-
- // minimum distance kept between current Step of written blobs and CollectStep of barriers
- optional uint32 StepDistance = 15;
- }
+ }
+ message TVDiskLoadStart {
+ optional uint64 Tag = 1;
+
+ // full VDisk identifier
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 2;
+
+ reserved 3; // obsolete field
+ reserved 4; // obsolete field
+ optional TGroupInfo GroupInfo = 16;
+
+ // tablet id, channel and generation used in blob ids and barriers
+ optional uint64 TabletId = 5;
+ optional uint32 Channel = 6;
+ optional uint32 Generation = 7;
+
+ // duration of the test in seconds
+ optional uint32 DurationSeconds = 8;
+
+ // a distribution of intervals between adjacent writes
+ repeated TIntervalInfo WriteIntervals = 9;
+
+ // a distribution of write block sizes (expressed in bytes of BlobSize; i.e. PartSize bytes are actually written)
+ repeated TSizeInfo WriteSizes = 10;
+
+ // maximum number of unconfirmed parallel writes
+ optional uint32 InFlightPutsMax = 11;
+
+ // soft maximum of total in flight put bytes
+ optional uint64 InFlightPutBytesMax = 12;
+
+ // put handle class
+ optional EPutHandleClass PutHandleClass = 13;
+
+ // a distribution of intervals between barrier advances
+ repeated TIntervalInfo BarrierAdvanceIntervals = 14;
+
+ // minimum distance kept between current Step of written blobs and CollectStep of barriers
+ optional uint32 StepDistance = 15;
+ }
message TPDiskReadLoadStart {
message TChunkInfo {
optional uint32 Slots = 1; // number of slots per chunk
@@ -1399,7 +1399,7 @@ message TEvTestLoadRequest {
optional uint64 Tag = 1;
optional uint32 PDiskId = 2;
optional uint64 PDiskGuid = 3;
- optional NKikimrBlobStorage.TVDiskID VDiskId = 4;
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 4;
repeated TChunkInfo Chunks = 5;
optional uint32 DurationSeconds = 6;
optional uint32 InFlightReads = 7;
@@ -1412,7 +1412,7 @@ message TEvTestLoadRequest {
}
message TPDiskLogLoadStart {
message TWorkerConfig {
- optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ optional NKikimrBlobStorage.TVDiskID VDiskId = 1;
optional uint32 MaxInFlight = 2;
// Measurement units of all parameters is bytes
@@ -1477,31 +1477,31 @@ message TEvTestLoadRequest {
optional uint64 IntervalUs = 4;
}
- optional uint64 Cookie = 1;
- oneof Command {
- TLoadStart LoadStart = 2;
- TLoadStop LoadStop = 3;
- TPDiskLoadStart PDiskLoadStart = 4;
- TVDiskLoadStart VDiskLoadStart = 5;
+ optional uint64 Cookie = 1;
+ oneof Command {
+ TLoadStart LoadStart = 2;
+ TLoadStop LoadStop = 3;
+ TPDiskLoadStart PDiskLoadStart = 4;
+ TVDiskLoadStart VDiskLoadStart = 5;
TPDiskReadLoadStart PDiskReadLoadStart = 6;
TPDiskLogLoadStart PDiskLogLoadStart = 7;
TKeyValueLoadStart KeyValueLoadStart = 8;
TKqpLoadStart KqpLoadStart = 9;
TMemoryLoadStart MemoryLoadStart = 10;
- }
-}
-
-message TEvTestLoadResponse {
+ }
+}
+
+message TEvTestLoadResponse {
optional uint32 Status = 1; // EResponseStatus from ydb/core/client/base/msgbus.h
- optional string ErrorReason = 2;
- optional uint64 Cookie = 3;
-}
-
-message TEvNodeWardenQueryGroupInfo {
- optional uint32 GroupId = 1;
-}
-
-message TEvNodeWardenGroupInfo {
- optional TGroupInfo Group = 1;
- repeated uint32 StartedGroupIds = 2;
-}
+ optional string ErrorReason = 2;
+ optional uint64 Cookie = 3;
+}
+
+message TEvNodeWardenQueryGroupInfo {
+ optional uint32 GroupId = 1;
+}
+
+message TEvNodeWardenGroupInfo {
+ optional TGroupInfo Group = 1;
+ repeated uint32 StartedGroupIds = 2;
+}
diff --git a/ydb/core/protos/blobstorage_config.proto b/ydb/core/protos/blobstorage_config.proto
index 10d0a29e6c3..a83e9964b35 100644
--- a/ydb/core/protos/blobstorage_config.proto
+++ b/ydb/core/protos/blobstorage_config.proto
@@ -1,196 +1,196 @@
-syntax = "proto3";
-
+syntax = "proto3";
+
import "ydb/core/protos/blobstorage_disk.proto";
import "ydb/core/protos/blobstorage_disk_color.proto";
import "ydb/core/protos/blobstorage_pdisk_config.proto";
import "library/cpp/actors/protos/interconnect.proto";
-
+
package NKikimrBlobStorage;
-
-// Enum defining PDisk underlying drive type (rotational or solid state)
-enum EPDiskType {
- ROT = 0; // rotational drives (HDD)
- SSD = 1; // solid state drives (SSD)
+
+// Enum defining PDisk underlying drive type (rotational or solid state)
+enum EPDiskType {
+ ROT = 0; // rotational drives (HDD)
+ SSD = 1; // solid state drives (SSD)
NVME = 2; // PCIe-connected solid state drives (NVMe SSD)
UNKNOWN_TYPE = 3; // used if device type is unknown or if group consists of different PDisk device types
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// TYPICAL HOST CONFIGURATIONS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// Single drive descriptor of typical host configuration structure
-message THostConfigDrive {
- string Path = 1; // path to the device on the host node
- EPDiskType Type = 2; // drive type (rotational or solid state)
- bool SharedWithOs = 3; // is this drive shared with OS in any way? (i.e. has OS partitions)
- bool ReadCentric = 4; // is this drive read-centric?
- uint64 Kind = 5; // nontransparent user-defined kind used for filtering when picking up groups
-
- // optional PDisk config for these drives; if not set, default configuration is applied; overrides host-wide default
- NKikimrBlobStorage.TPDiskConfig PDiskConfig = 6;
-}
-
-// Command used to define typical host configuration. It it used while defining new typical host configurations and as
-// a returned structure when reading them.
-message TDefineHostConfig {
- uint64 HostConfigId = 1; // unique (to BS_CONTROLLER tablet) host configuration integer id (key)
- string Name = 2; // user-friendly name of typical configuration
- repeated THostConfigDrive Drive = 3; // a full set of drives on every host
-
- // host-wide default configuration for every PDisk
- NKikimrBlobStorage.TPDiskConfig DefaultHostPDiskConfig = 4;
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
-}
-
-// Command issued to read specific (or all) host configurations associated with the BS_CONTROLLER tablet.
-message TReadHostConfig {
- repeated uint64 HostConfigId = 1; // if empty, then all host configuration entries are returned
-}
-
-// Command used to delete typical host configuration identified by its key.
-message TDeleteHostConfig {
- uint64 HostConfigId = 1;
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// HOSTS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// Host key structure defines node by providing its FQDN and Interconnect port. There must be unique mapping from
-// FQDN:port to NodeId.
-message THostKey {
- string Fqdn = 1; // fully qualified domain name of the host
- int32 IcPort = 2; // interconnect port to use
- uint32 NodeId = 3; // may be set instead of Fqdn/IcPort to specify explicit NodeId
-}
-
-// Definition of a host entry containing its key (which provides NodeId) and reference to typical host configuration
-// that must exist.
-message THost {
- THostKey Key = 1; // unique host key defining its location
- uint64 HostConfigId = 2; // reference to typical host configuration table
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// BOXES
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-message TDefineBox {
- uint64 BoxId = 1;
- string Name = 2;
- repeated bytes UserId = 3;
- repeated THost Host = 4;
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
-}
-
-message TReadBox {
- repeated uint64 BoxId = 1; // if empty, then all box entries are returned
-}
-
-message TDeleteBox {
- uint64 BoxId = 1;
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// STORAGE POOLS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-message TGroupGeometry {
- uint32 RealmLevelBegin = 1;
- uint32 RealmLevelEnd = 2;
- uint32 DomainLevelBegin = 3;
- uint32 DomainLevelEnd = 4;
- uint32 NumFailRealms = 5;
- uint32 NumFailDomainsPerFailRealm = 6;
- uint32 NumVDisksPerFailDomain = 7;
-}
-
-message TGroupUsagePattern {
- uint64 SpaceBytes = 1;
- uint64 WriteIOPS = 2;
- uint64 WriteBytesPerSecond = 3;
- uint64 ReadIOPS = 4;
- uint64 ReadBytesPerSecond = 5;
- uint64 InMemCacheBytes = 6;
-}
-
-message TPDiskFilter {
- message TRequiredProperty {
- oneof Property {
- EPDiskType Type = 1; // require certain drive type
- bool SharedWithOs = 2; // require certain SharedWithOs property
- bool ReadCentric = 3; // require certain ReadCentric property
- uint64 Kind = 4; // require certain kind
- }
- }
- repeated TRequiredProperty Property = 1; // conjunction of required properties; the same properties must not repeat
-}
-
-message TDefineStoragePool {
- message TExistingGroups {
- repeated uint32 GroupId = 1;
- }
-
- uint64 BoxId = 1; // the box in which we are creating this storage pool
- uint64 StoragePoolId = 2; // integer key unique to the box; if set to zero, Name is used for lookup
- string Name = 3; // user-friendly name
- string ErasureSpecies = 4; // name for erasure species of contained groups
- TGroupGeometry Geometry = 5; // group geometry defining
- string VDiskKind = 6; // kind of created VDisks/VSlots [TVDiskKind.EVDiskKind textual repr]
- TGroupUsagePattern UsagePattern = 7; // how this storage pool is going to be used
- string Kind = 8; // kind of storage pool (user-defined)
- uint32 NumGroups = 9; // explicit number of groups to create
- repeated bytes UserId = 10; // allowed users
- repeated TPDiskFilter PDiskFilter = 11; // matching PDisks
- TExistingGroups ExistingGroups = 12; // existing groups (used while migrating from old-style configuration)
- NActorsInterconnect.TScopeId ScopeId = 13; // scope id for the pool clients
- bool RandomizeGroupMapping = 14; // minimize correlation of groups and drives
- repeated uint64 ExpectedGroupSlotSize = 15; // primarily for debugging purposes; expected slot size for group allocation
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TYPICAL HOST CONFIGURATIONS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Single drive descriptor of typical host configuration structure
+message THostConfigDrive {
+ string Path = 1; // path to the device on the host node
+ EPDiskType Type = 2; // drive type (rotational or solid state)
+ bool SharedWithOs = 3; // is this drive shared with OS in any way? (i.e. has OS partitions)
+ bool ReadCentric = 4; // is this drive read-centric?
+ uint64 Kind = 5; // nontransparent user-defined kind used for filtering when picking up groups
+
+ // optional PDisk config for these drives; if not set, default configuration is applied; overrides host-wide default
+ NKikimrBlobStorage.TPDiskConfig PDiskConfig = 6;
+}
+
+// Command used to define typical host configuration. It it used while defining new typical host configurations and as
+// a returned structure when reading them.
+message TDefineHostConfig {
+ uint64 HostConfigId = 1; // unique (to BS_CONTROLLER tablet) host configuration integer id (key)
+ string Name = 2; // user-friendly name of typical configuration
+ repeated THostConfigDrive Drive = 3; // a full set of drives on every host
+
+ // host-wide default configuration for every PDisk
+ NKikimrBlobStorage.TPDiskConfig DefaultHostPDiskConfig = 4;
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
+}
+
+// Command issued to read specific (or all) host configurations associated with the BS_CONTROLLER tablet.
+message TReadHostConfig {
+ repeated uint64 HostConfigId = 1; // if empty, then all host configuration entries are returned
+}
+
+// Command used to delete typical host configuration identified by its key.
+message TDeleteHostConfig {
+ uint64 HostConfigId = 1;
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// HOSTS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Host key structure defines node by providing its FQDN and Interconnect port. There must be unique mapping from
+// FQDN:port to NodeId.
+message THostKey {
+ string Fqdn = 1; // fully qualified domain name of the host
+ int32 IcPort = 2; // interconnect port to use
+ uint32 NodeId = 3; // may be set instead of Fqdn/IcPort to specify explicit NodeId
+}
+
+// Definition of a host entry containing its key (which provides NodeId) and reference to typical host configuration
+// that must exist.
+message THost {
+ THostKey Key = 1; // unique host key defining its location
+ uint64 HostConfigId = 2; // reference to typical host configuration table
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// BOXES
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+message TDefineBox {
+ uint64 BoxId = 1;
+ string Name = 2;
+ repeated bytes UserId = 3;
+ repeated THost Host = 4;
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
+}
+
+message TReadBox {
+ repeated uint64 BoxId = 1; // if empty, then all box entries are returned
+}
+
+message TDeleteBox {
+ uint64 BoxId = 1;
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// STORAGE POOLS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+message TGroupGeometry {
+ uint32 RealmLevelBegin = 1;
+ uint32 RealmLevelEnd = 2;
+ uint32 DomainLevelBegin = 3;
+ uint32 DomainLevelEnd = 4;
+ uint32 NumFailRealms = 5;
+ uint32 NumFailDomainsPerFailRealm = 6;
+ uint32 NumVDisksPerFailDomain = 7;
+}
+
+message TGroupUsagePattern {
+ uint64 SpaceBytes = 1;
+ uint64 WriteIOPS = 2;
+ uint64 WriteBytesPerSecond = 3;
+ uint64 ReadIOPS = 4;
+ uint64 ReadBytesPerSecond = 5;
+ uint64 InMemCacheBytes = 6;
+}
+
+message TPDiskFilter {
+ message TRequiredProperty {
+ oneof Property {
+ EPDiskType Type = 1; // require certain drive type
+ bool SharedWithOs = 2; // require certain SharedWithOs property
+ bool ReadCentric = 3; // require certain ReadCentric property
+ uint64 Kind = 4; // require certain kind
+ }
+ }
+ repeated TRequiredProperty Property = 1; // conjunction of required properties; the same properties must not repeat
+}
+
+message TDefineStoragePool {
+ message TExistingGroups {
+ repeated uint32 GroupId = 1;
+ }
+
+ uint64 BoxId = 1; // the box in which we are creating this storage pool
+ uint64 StoragePoolId = 2; // integer key unique to the box; if set to zero, Name is used for lookup
+ string Name = 3; // user-friendly name
+ string ErasureSpecies = 4; // name for erasure species of contained groups
+ TGroupGeometry Geometry = 5; // group geometry defining
+ string VDiskKind = 6; // kind of created VDisks/VSlots [TVDiskKind.EVDiskKind textual repr]
+ TGroupUsagePattern UsagePattern = 7; // how this storage pool is going to be used
+ string Kind = 8; // kind of storage pool (user-defined)
+ uint32 NumGroups = 9; // explicit number of groups to create
+ repeated bytes UserId = 10; // allowed users
+ repeated TPDiskFilter PDiskFilter = 11; // matching PDisks
+ TExistingGroups ExistingGroups = 12; // existing groups (used while migrating from old-style configuration)
+ NActorsInterconnect.TScopeId ScopeId = 13; // scope id for the pool clients
+ bool RandomizeGroupMapping = 14; // minimize correlation of groups and drives
+ repeated uint64 ExpectedGroupSlotSize = 15; // primarily for debugging purposes; expected slot size for group allocation
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
// encryption mode: 0 for none, 1 for the current mode (chacha8)
uint32 EncryptionMode = 101;
-}
-
-message TReadStoragePool {
- uint64 BoxId = 1; // use Max<ui64> to query all the pools
-
- // calculates intersection of names and ids
- repeated uint64 StoragePoolId = 2; // when empty, then query all the boxes
- repeated string Name = 3; // when empty, then query all the boxes
-}
-
-message TDeleteStoragePool {
- uint64 BoxId = 1;
- uint64 StoragePoolId = 2;
-
- // item's generation to prevent concurrent modification
- uint64 ItemConfigGeneration = 100;
-}
-
-enum EDriveStatus {
- UNKNOWN = 0; // value of status is unknown (default)
- ACTIVE = 1; // working as expected
- INACTIVE = 2; // new groups are not created over this drive, but existing ones continue to work as expected
- BROKEN = 3; // drive is not working, groups are automatically moved out of this drive upon reception of this status
- SPARE = 4; // spare drive -- groups are created only when being moved from BROKEN drives
- FAULTY = 5; // drive is expected to become BROKEN soon, new groups are not created, old groups are asynchronously moved out from this drive
+}
+
+message TReadStoragePool {
+ uint64 BoxId = 1; // use Max<ui64> to query all the pools
+
+ // calculates intersection of names and ids
+ repeated uint64 StoragePoolId = 2; // when empty, then query all the boxes
+ repeated string Name = 3; // when empty, then query all the boxes
+}
+
+message TDeleteStoragePool {
+ uint64 BoxId = 1;
+ uint64 StoragePoolId = 2;
+
+ // item's generation to prevent concurrent modification
+ uint64 ItemConfigGeneration = 100;
+}
+
+enum EDriveStatus {
+ UNKNOWN = 0; // value of status is unknown (default)
+ ACTIVE = 1; // working as expected
+ INACTIVE = 2; // new groups are not created over this drive, but existing ones continue to work as expected
+ BROKEN = 3; // drive is not working, groups are automatically moved out of this drive upon reception of this status
+ SPARE = 4; // spare drive -- groups are created only when being moved from BROKEN drives
+ FAULTY = 5; // drive is expected to become BROKEN soon, new groups are not created, old groups are asynchronously moved out from this drive
TO_BE_REMOVED = 6; // same as INACTIVE, but drive is counted in fault model as not working
-}
-
+}
+
message TGroupStatus {
enum E {
UNKNOWN = 0; // group status is unknown (default value)
@@ -199,8 +199,8 @@ message TGroupStatus {
DEGRADED = 3; // group is DEGRADED -- one random failure may lead to group loss (but may not lead too)
DISINTEGRATED = 4; // group is not available for operation
}
-}
-
+}
+
message TDriveLifeStage {
enum E {
UNKNOWN = 0; // life stage is unknown (default)
@@ -219,54 +219,54 @@ message TSerialManagementStage {
}
}
-message TUpdateDriveStatus {
- THostKey HostKey = 1; // host on which we are looking for the drive
- string Path = 2; // absolute path to the device as enlisted in PDisk configuration
- EDriveStatus Status = 3; // new status
- uint32 PDiskId = 4; // may be set instead of path to identify PDisk
+message TUpdateDriveStatus {
+ THostKey HostKey = 1; // host on which we are looking for the drive
+ string Path = 2; // absolute path to the device as enlisted in PDisk configuration
+ EDriveStatus Status = 3; // new status
+ uint32 PDiskId = 4; // may be set instead of path to identify PDisk
string Serial = 5; // may be set instead of path and PDiskId to identify PDisk
- uint64 StatusChangeTimestamp = 6; // used only in return of ReadDriveStatus
-}
-
-message TReadDriveStatus {
- THostKey HostKey = 1; // host to query; if not set, then query all hosts
- string Path = 2; // path on the host; if empty, then query all drives on specified hosts (or on all hosts)
-}
-
-message TProposeStoragePools {
-}
-
-message TQueryBaseConfig {
-}
-
-message TPDiskId {
- uint32 NodeId = 1;
- uint32 PDiskId = 2;
-}
-
-message TReassignGroupDisk {
- uint32 GroupId = 1;
- uint32 GroupGeneration = 2;
- uint32 FailRealmIdx = 3;
- uint32 FailDomainIdx = 4;
- uint32 VDiskIdx = 5;
- TPDiskId TargetPDiskId = 6; // optional; when not specified, selected automatically
- bool SuppressDonorMode = 7; // when set, donor mode is not used even if it is enabled through BSC
-}
-
+ uint64 StatusChangeTimestamp = 6; // used only in return of ReadDriveStatus
+}
+
+message TReadDriveStatus {
+ THostKey HostKey = 1; // host to query; if not set, then query all hosts
+ string Path = 2; // path on the host; if empty, then query all drives on specified hosts (or on all hosts)
+}
+
+message TProposeStoragePools {
+}
+
+message TQueryBaseConfig {
+}
+
+message TPDiskId {
+ uint32 NodeId = 1;
+ uint32 PDiskId = 2;
+}
+
+message TReassignGroupDisk {
+ uint32 GroupId = 1;
+ uint32 GroupGeneration = 2;
+ uint32 FailRealmIdx = 3;
+ uint32 FailDomainIdx = 4;
+ uint32 VDiskIdx = 5;
+ TPDiskId TargetPDiskId = 6; // optional; when not specified, selected automatically
+ bool SuppressDonorMode = 7; // when set, donor mode is not used even if it is enabled through BSC
+}
+
enum EClusterFitAlgorithm {
QUADRATIC = 0;
HUNGARIAN = 1;
ANNEALING = 2;
}
-message TClusterFit {
+message TClusterFit {
EClusterFitAlgorithm Algorithm = 1;
uint64 Iterations = 2;
-}
-
+}
+
message TVSlotMetric {
- NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ NKikimrBlobStorage.TVSlotId VSlotId = 1;
uint64 Metric = 2;
}
@@ -277,28 +277,28 @@ message TClusterFitConfig {
TClusterFit Request = 4;
}
-message TMergeBoxes {
- message TStoragePoolIdMap {
- uint64 OriginStoragePoolId = 1;
- uint64 TargetStoragePoolId = 2;
- }
-
- uint64 OriginBoxId = 1;
- uint64 OriginBoxGeneration = 2;
- uint64 TargetBoxId = 3;
- uint64 TargetBoxGeneration = 4;
- repeated TStoragePoolIdMap StoragePoolIdMap = 5;
-}
-
-message TMoveGroups {
- uint64 BoxId = 1;
- uint64 OriginStoragePoolId = 2;
- uint64 OriginStoragePoolGeneration = 3;
- uint64 TargetStoragePoolId = 4;
- uint64 TargetStoragePoolGeneration = 5;
- repeated uint32 ExplicitGroupId = 6; // if no groups are provided, then all groups of origin storage pool are moved
-}
-
+message TMergeBoxes {
+ message TStoragePoolIdMap {
+ uint64 OriginStoragePoolId = 1;
+ uint64 TargetStoragePoolId = 2;
+ }
+
+ uint64 OriginBoxId = 1;
+ uint64 OriginBoxGeneration = 2;
+ uint64 TargetBoxId = 3;
+ uint64 TargetBoxGeneration = 4;
+ repeated TStoragePoolIdMap StoragePoolIdMap = 5;
+}
+
+message TMoveGroups {
+ uint64 BoxId = 1;
+ uint64 OriginStoragePoolId = 2;
+ uint64 OriginStoragePoolGeneration = 3;
+ uint64 TargetStoragePoolId = 4;
+ uint64 TargetStoragePoolGeneration = 5;
+ repeated uint32 ExplicitGroupId = 6; // if no groups are provided, then all groups of origin storage pool are moved
+}
+
message TAddMigrationPlan {
string Name = 1;
repeated TMoveCommand MoveCommand = 2;
@@ -308,85 +308,85 @@ message TDeleteMigrationPlan {
string Name = 1;
}
-message TEnableSelfHeal {
- bool Enable = 1;
-}
-
-message TEnableDonorMode {
- bool Enable = 1;
-}
-
-message TDeclareIntent {
- // intent is a generic description of an action going to be taken regarding to specific drive (BSC operating unit
- // is a drive, yes); when a whole node is going to be formatted/replaced/offline, one should enumerate all drives
- // of a specific node with the same Kind/BeginTimestamp/EndTimestamp/Action fields
-
- // in reponse to DeclareIntent command BSC sends response with TDeclareIntent Intent with copied QUERY PART and
- // filled in RESOLUTION; when kind is provided as STATEMENT, resolution is always 'approved'
-
- enum EKind {
- REQUEST = 0; // action is requested to be taken and may be either approved or not
- STATEMENT = 1; // action is going to be taken (or already taken) and this is just a notification
- }
- enum EDriveAction {
- REPLACE = 0; // drive is going to be replaced (or smth else with data loss); it is expected to become online
- // and empty just after EndTimestamp
- OFFLINE = 1; // drive is going to be offline, but data will be preserved; it is expected to go offline since
- // BeginTimestamp and return back online till EndTimestamp
- }
- enum EImpact {
- GROUP_OFFLINE = 0; // group will be offline (i.e. unavaiable for operation)
- GROUP_DATA_LOSS = 1; // group will most probably unrecoverably lose its data
- GROUP_FRAGILE = 2; // group will reach state when one fail may lead to offline or data loss, depending on its nature
- }
- message TAffectedGroup {
- uint32 GroupId = 1;
- EImpact Impact = 2;
- }
- message TDenyReason {
- // the reason for intent query denial; when set, then the query is denied; when cleared, then the query is approved
- string Message = 1; // textual description of denial reason
- repeated TAffectedGroup AffectedGroups = 2; // a set of degraded groups
- }
- message TIntent {
- // QUERY PART
- string UniqueId = 1; // filled in by sender; should not repeat; when matches other one, the intent is not
- // replaced, but the whole command terminates with an error
- EKind Kind = 2; // kind of the intent
- uint64 BeginTimestamp = 3; // microseconds since Epoch
- uint64 EndTimestamp = 4; // the same unit
- EDriveAction Action = 5; // action to be taken with the device
-
- // DRIVE PART
- THostKey HostKey = 6; // the host containing the requested drive
- // mutually exclusive fields at input -- exactly one of them MUST be provided; on output, all fields are set
- string Path = 7; // path to the drive (if empty, then considered not set)
- uint32 PDiskId = 8; // pdisk id (if nonzero, otherwise considered not set)
- string DriveSerNo = 9; // drive serial number (if empty, then considered not set)
-
- // RESOLUTION; when returned from the ReadIntent method, these fields are not set
- TDenyReason DenyReason = 100; // when not set, the query is approved, otherwise describes the reason of denial
- // it is necessary to mention that if even one intent from DeclareIntent command is denied, then the whole
- // command fails
- }
- repeated TIntent Intents = 1; // all or none are satisfied
- repeated string DropUniqueIds = 2; // drop intents with provided unique ids; suitable only for DeclareIntent command
-}
-
-message TReadIntent {
- // useful for synchronization of intents between CMS and BSC -- first CMS reads all the intents known to BSC,
- // then it deletes obsolete and creates new one
-}
-
-message TDropDonorDisk {
- NKikimrBlobStorage.TVSlotId VSlotId = 1;
- NKikimrBlobStorage.TVDiskID VDiskId = 2;
-}
-
-message TSetScrubPeriodicity {
- uint32 ScrubPeriodicity = 1; // in seconds; 0 = disable
-}
-
+message TEnableSelfHeal {
+ bool Enable = 1;
+}
+
+message TEnableDonorMode {
+ bool Enable = 1;
+}
+
+message TDeclareIntent {
+ // intent is a generic description of an action going to be taken regarding to specific drive (BSC operating unit
+ // is a drive, yes); when a whole node is going to be formatted/replaced/offline, one should enumerate all drives
+ // of a specific node with the same Kind/BeginTimestamp/EndTimestamp/Action fields
+
+ // in reponse to DeclareIntent command BSC sends response with TDeclareIntent Intent with copied QUERY PART and
+ // filled in RESOLUTION; when kind is provided as STATEMENT, resolution is always 'approved'
+
+ enum EKind {
+ REQUEST = 0; // action is requested to be taken and may be either approved or not
+ STATEMENT = 1; // action is going to be taken (or already taken) and this is just a notification
+ }
+ enum EDriveAction {
+ REPLACE = 0; // drive is going to be replaced (or smth else with data loss); it is expected to become online
+ // and empty just after EndTimestamp
+ OFFLINE = 1; // drive is going to be offline, but data will be preserved; it is expected to go offline since
+ // BeginTimestamp and return back online till EndTimestamp
+ }
+ enum EImpact {
+ GROUP_OFFLINE = 0; // group will be offline (i.e. unavaiable for operation)
+ GROUP_DATA_LOSS = 1; // group will most probably unrecoverably lose its data
+ GROUP_FRAGILE = 2; // group will reach state when one fail may lead to offline or data loss, depending on its nature
+ }
+ message TAffectedGroup {
+ uint32 GroupId = 1;
+ EImpact Impact = 2;
+ }
+ message TDenyReason {
+ // the reason for intent query denial; when set, then the query is denied; when cleared, then the query is approved
+ string Message = 1; // textual description of denial reason
+ repeated TAffectedGroup AffectedGroups = 2; // a set of degraded groups
+ }
+ message TIntent {
+ // QUERY PART
+ string UniqueId = 1; // filled in by sender; should not repeat; when matches other one, the intent is not
+ // replaced, but the whole command terminates with an error
+ EKind Kind = 2; // kind of the intent
+ uint64 BeginTimestamp = 3; // microseconds since Epoch
+ uint64 EndTimestamp = 4; // the same unit
+ EDriveAction Action = 5; // action to be taken with the device
+
+ // DRIVE PART
+ THostKey HostKey = 6; // the host containing the requested drive
+ // mutually exclusive fields at input -- exactly one of them MUST be provided; on output, all fields are set
+ string Path = 7; // path to the drive (if empty, then considered not set)
+ uint32 PDiskId = 8; // pdisk id (if nonzero, otherwise considered not set)
+ string DriveSerNo = 9; // drive serial number (if empty, then considered not set)
+
+ // RESOLUTION; when returned from the ReadIntent method, these fields are not set
+ TDenyReason DenyReason = 100; // when not set, the query is approved, otherwise describes the reason of denial
+ // it is necessary to mention that if even one intent from DeclareIntent command is denied, then the whole
+ // command fails
+ }
+ repeated TIntent Intents = 1; // all or none are satisfied
+ repeated string DropUniqueIds = 2; // drop intents with provided unique ids; suitable only for DeclareIntent command
+}
+
+message TReadIntent {
+ // useful for synchronization of intents between CMS and BSC -- first CMS reads all the intents known to BSC,
+ // then it deletes obsolete and creates new one
+}
+
+message TDropDonorDisk {
+ NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ NKikimrBlobStorage.TVDiskID VDiskId = 2;
+}
+
+message TSetScrubPeriodicity {
+ uint32 ScrubPeriodicity = 1; // in seconds; 0 = disable
+}
+
message TAddDriveSerial {
string Serial = 1;
uint64 BoxId = 2;
@@ -409,177 +409,177 @@ message TMigrateToSerial {
TSerialManagementStage.E Stage = 1;
}
-message TSetPDiskSpaceMarginPromille {
- uint32 PDiskSpaceMarginPromille = 1;
-}
-
-message TUpdateSettings {
- // each value may be specified either one time, or zero times; when it is specified, its value is written to State
- // and applied immediately; when no value specified, setting kept unchanged; if value is specified more than one
- // time, then last value is applied
- repeated uint32 DefaultMaxSlots = 1;
- repeated bool EnableSelfHeal = 2;
- repeated bool EnableDonorMode = 3;
- repeated uint64 ScrubPeriodicitySeconds = 4;
- repeated uint32 PDiskSpaceMarginPromille = 5;
- repeated uint32 GroupReserveMin = 6;
- repeated uint32 GroupReservePartPPM = 7;
- repeated uint32 MaxScrubbedDisksAtOnce = 8;
- repeated NKikimrBlobStorage.TPDiskSpaceColor.E PDiskSpaceColorBorder = 9;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// INTERFACE PART
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-message TConfigRequest {
- message TCommand {
- oneof Command {
- TDefineHostConfig DefineHostConfig = 1;
- TReadHostConfig ReadHostConfig = 2;
- TDeleteHostConfig DeleteHostConfig = 4;
- TDefineBox DefineBox = 5;
- TReadBox ReadBox = 6;
- TDeleteBox DeleteBox = 8;
- TDefineStoragePool DefineStoragePool = 9;
- TReadStoragePool ReadStoragePool = 10;
- TDeleteStoragePool DeleteStoragePool = 12;
- TUpdateDriveStatus UpdateDriveStatus = 13;
- TReadDriveStatus ReadDriveStatus = 14;
- TProposeStoragePools ProposeStoragePools = 15;
- TQueryBaseConfig QueryBaseConfig = 16; // introspection
- TMergeBoxes MergeBoxes = 23;
- TMoveGroups MoveGroups = 24; // move groups between storage pools; no checks of SP constraints are performed
+message TSetPDiskSpaceMarginPromille {
+ uint32 PDiskSpaceMarginPromille = 1;
+}
+
+message TUpdateSettings {
+ // each value may be specified either one time, or zero times; when it is specified, its value is written to State
+ // and applied immediately; when no value specified, setting kept unchanged; if value is specified more than one
+ // time, then last value is applied
+ repeated uint32 DefaultMaxSlots = 1;
+ repeated bool EnableSelfHeal = 2;
+ repeated bool EnableDonorMode = 3;
+ repeated uint64 ScrubPeriodicitySeconds = 4;
+ repeated uint32 PDiskSpaceMarginPromille = 5;
+ repeated uint32 GroupReserveMin = 6;
+ repeated uint32 GroupReservePartPPM = 7;
+ repeated uint32 MaxScrubbedDisksAtOnce = 8;
+ repeated NKikimrBlobStorage.TPDiskSpaceColor.E PDiskSpaceColorBorder = 9;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// INTERFACE PART
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+message TConfigRequest {
+ message TCommand {
+ oneof Command {
+ TDefineHostConfig DefineHostConfig = 1;
+ TReadHostConfig ReadHostConfig = 2;
+ TDeleteHostConfig DeleteHostConfig = 4;
+ TDefineBox DefineBox = 5;
+ TReadBox ReadBox = 6;
+ TDeleteBox DeleteBox = 8;
+ TDefineStoragePool DefineStoragePool = 9;
+ TReadStoragePool ReadStoragePool = 10;
+ TDeleteStoragePool DeleteStoragePool = 12;
+ TUpdateDriveStatus UpdateDriveStatus = 13;
+ TReadDriveStatus ReadDriveStatus = 14;
+ TProposeStoragePools ProposeStoragePools = 15;
+ TQueryBaseConfig QueryBaseConfig = 16; // introspection
+ TMergeBoxes MergeBoxes = 23;
+ TMoveGroups MoveGroups = 24; // move groups between storage pools; no checks of SP constraints are performed
TAddMigrationPlan AddMigrationPlan = 25;
TDeleteMigrationPlan DeleteMigrationPlan = 26;
- TEnableSelfHeal EnableSelfHeal = 27;
- TDeclareIntent DeclareIntent = 28;
- TReadIntent ReadIntent = 29;
- TEnableSelfHeal EnableDonorMode = 30;
- TDropDonorDisk DropDonorDisk = 31;
- TSetScrubPeriodicity SetScrubPeriodicity = 32;
+ TEnableSelfHeal EnableSelfHeal = 27;
+ TDeclareIntent DeclareIntent = 28;
+ TReadIntent ReadIntent = 29;
+ TEnableSelfHeal EnableDonorMode = 30;
+ TDropDonorDisk DropDonorDisk = 31;
+ TSetScrubPeriodicity SetScrubPeriodicity = 32;
TAddDriveSerial AddDriveSerial = 33;
TRemoveDriveSerial RemoveDriveSerial = 34;
TForgetDriveSerial ForgetDriveSerial = 36;
TMigrateToSerial MigrateToSerial = 35;
- TSetPDiskSpaceMarginPromille SetPDiskSpaceMarginPromille = 37;
- TUpdateSettings UpdateSettings = 38;
-
- // commands intended for internal use
- TReassignGroupDisk ReassignGroupDisk = 19;
- }
- }
-
- // a set of commands to execute; NOTE that commands are executed one by one and only the single command execution
- // is atomic -- whe whole config request is split into several transactions with the provided commands and some of
- // auxiliary BS_CONTROLLER transactions
- repeated TCommand Command = 1;
-
- // if set to true, then transaction is terminated and nothing is committed; useful for dry-run
- bool Rollback = 2;
-
- // ignore group sanity checks when remapping disks
- bool IgnoreGroupSanityChecks = 3;
-
- // ignore group failure model checks
- bool IgnoreGroupFailModelChecks = 4;
-
- // ignore vslot sizes when remapping groups
- bool IgnoreVSlotQuotaCheck = 5;
-
- // allow unusable disks to stay in place when replacing others
- bool AllowUnusableDisks = 6;
-
- // ignore group reserve
- bool IgnoreGroupReserve = 7;
-
- // ignore degraded groups checking
- bool IgnoreDegradedGroupsChecks = 8;
-
- // do not settle slots over non-operating PDisks
- bool SettleOnlyOnOperationalDisks = 9;
-
- // execute this request ASAP
- bool Cito = 10;
-}
-
-enum ETriStateBool {
- kFalse = 0;
- kTrue = 1;
- kNotSet = 2;
-}
-
-message TBaseConfig {
- message TPDisk {
- uint32 NodeId = 1;
- uint32 PDiskId = 2;
- string Path = 3;
- EPDiskType Type = 4;
- ETriStateBool SharedWithOs = 5;
- ETriStateBool ReadCentric = 6;
- uint64 Kind = 7;
- TPDiskConfig PDiskConfig = 8;
- uint64 Guid = 9;
- uint64 BoxId = 10;
- uint32 NumStaticSlots = 11;
- EDriveStatus DriveStatus = 12;
- uint32 ExpectedSlotCount = 13;
- NKikimrBlobStorage.TPDiskMetrics PDiskMetrics = 14;
- uint64 DriveStatusChangeTimestamp = 15; // TInstant::GetValue()
- }
- message TVSlot {
- message TDonorDisk {
- NKikimrBlobStorage.TVDiskID VDiskId = 1;
- NKikimrBlobStorage.TVSlotId VSlotId = 2;
- NKikimrBlobStorage.TVDiskMetrics VDiskMetrics = 3;
- }
-
- NKikimrBlobStorage.TVSlotId VSlotId = 1;
- uint32 GroupId = 2;
- uint32 GroupGeneration = 3;
- string VDiskKind = 4;
- uint32 FailRealmIdx = 5;
- uint32 FailDomainIdx = 6;
- uint32 VDiskIdx = 7;
- uint64 AllocatedSize = 8;
- NKikimrBlobStorage.TVDiskMetrics VDiskMetrics = 9;
- string Status = 10; // textual representation of EVDiskStatus or empty string if status is not known/reported
- repeated TDonorDisk Donors = 11;
- bool Ready = 12; // is disk READY in terms of BSC (stable READY status for some period of time)
- }
- message TGroup {
- uint32 GroupId = 1;
- uint32 GroupGeneration = 2;
- string ErasureSpecies = 3;
- repeated NKikimrBlobStorage.TVSlotId VSlotId = 4;
- uint64 BoxId = 5;
- uint64 StoragePoolId = 6;
- bool SeenOperational = 7;
+ TSetPDiskSpaceMarginPromille SetPDiskSpaceMarginPromille = 37;
+ TUpdateSettings UpdateSettings = 38;
+
+ // commands intended for internal use
+ TReassignGroupDisk ReassignGroupDisk = 19;
+ }
+ }
+
+ // a set of commands to execute; NOTE that commands are executed one by one and only the single command execution
+ // is atomic -- whe whole config request is split into several transactions with the provided commands and some of
+ // auxiliary BS_CONTROLLER transactions
+ repeated TCommand Command = 1;
+
+ // if set to true, then transaction is terminated and nothing is committed; useful for dry-run
+ bool Rollback = 2;
+
+ // ignore group sanity checks when remapping disks
+ bool IgnoreGroupSanityChecks = 3;
+
+ // ignore group failure model checks
+ bool IgnoreGroupFailModelChecks = 4;
+
+ // ignore vslot sizes when remapping groups
+ bool IgnoreVSlotQuotaCheck = 5;
+
+ // allow unusable disks to stay in place when replacing others
+ bool AllowUnusableDisks = 6;
+
+ // ignore group reserve
+ bool IgnoreGroupReserve = 7;
+
+ // ignore degraded groups checking
+ bool IgnoreDegradedGroupsChecks = 8;
+
+ // do not settle slots over non-operating PDisks
+ bool SettleOnlyOnOperationalDisks = 9;
+
+ // execute this request ASAP
+ bool Cito = 10;
+}
+
+enum ETriStateBool {
+ kFalse = 0;
+ kTrue = 1;
+ kNotSet = 2;
+}
+
+message TBaseConfig {
+ message TPDisk {
+ uint32 NodeId = 1;
+ uint32 PDiskId = 2;
+ string Path = 3;
+ EPDiskType Type = 4;
+ ETriStateBool SharedWithOs = 5;
+ ETriStateBool ReadCentric = 6;
+ uint64 Kind = 7;
+ TPDiskConfig PDiskConfig = 8;
+ uint64 Guid = 9;
+ uint64 BoxId = 10;
+ uint32 NumStaticSlots = 11;
+ EDriveStatus DriveStatus = 12;
+ uint32 ExpectedSlotCount = 13;
+ NKikimrBlobStorage.TPDiskMetrics PDiskMetrics = 14;
+ uint64 DriveStatusChangeTimestamp = 15; // TInstant::GetValue()
+ }
+ message TVSlot {
+ message TDonorDisk {
+ NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ NKikimrBlobStorage.TVSlotId VSlotId = 2;
+ NKikimrBlobStorage.TVDiskMetrics VDiskMetrics = 3;
+ }
+
+ NKikimrBlobStorage.TVSlotId VSlotId = 1;
+ uint32 GroupId = 2;
+ uint32 GroupGeneration = 3;
+ string VDiskKind = 4;
+ uint32 FailRealmIdx = 5;
+ uint32 FailDomainIdx = 6;
+ uint32 VDiskIdx = 7;
+ uint64 AllocatedSize = 8;
+ NKikimrBlobStorage.TVDiskMetrics VDiskMetrics = 9;
+ string Status = 10; // textual representation of EVDiskStatus or empty string if status is not known/reported
+ repeated TDonorDisk Donors = 11;
+ bool Ready = 12; // is disk READY in terms of BSC (stable READY status for some period of time)
+ }
+ message TGroup {
+ uint32 GroupId = 1;
+ uint32 GroupGeneration = 2;
+ string ErasureSpecies = 3;
+ repeated NKikimrBlobStorage.TVSlotId VSlotId = 4;
+ uint64 BoxId = 5;
+ uint64 StoragePoolId = 6;
+ bool SeenOperational = 7;
TGroupStatus.E OperatingStatus = 8; // group status based on latest VDisk reports only
TGroupStatus.E ExpectedStatus = 9; // status based not only on operational report, but on PDisk status and plans too
- }
- message TNode {
- uint32 NodeId = 1;
- bytes PhysicalLocation = 2 [deprecated=true];
- THostKey HostKey = 3;
- NActorsInterconnect.TNodeLocation Location = 4;
- }
-
- repeated TPDisk PDisk = 1;
- repeated TVSlot VSlot = 2;
- repeated TGroup Group = 3;
- repeated TNode Node = 4;
-}
-
-message TMoveCommand {
- uint32 GroupId = 1;
- uint32 OriginNodeId = 2;
- uint32 OriginPDiskId = 3;
- uint32 OriginVSlotId = 4;
- uint32 TargetNodeId = 5;
- uint32 TargetPDiskId = 6;
-}
-
+ }
+ message TNode {
+ uint32 NodeId = 1;
+ bytes PhysicalLocation = 2 [deprecated=true];
+ THostKey HostKey = 3;
+ NActorsInterconnect.TNodeLocation Location = 4;
+ }
+
+ repeated TPDisk PDisk = 1;
+ repeated TVSlot VSlot = 2;
+ repeated TGroup Group = 3;
+ repeated TNode Node = 4;
+}
+
+message TMoveCommand {
+ uint32 GroupId = 1;
+ uint32 OriginNodeId = 2;
+ uint32 OriginPDiskId = 3;
+ uint32 OriginVSlotId = 4;
+ uint32 TargetNodeId = 5;
+ uint32 TargetPDiskId = 6;
+}
+
message TPDiskStat {
uint32 NodeId = 1;
uint32 PDiskId = 2;
@@ -589,68 +589,68 @@ message TPDiskStat {
uint32 NumSlotsAfterMigration = 6;
}
-message TReassignedItem {
- NKikimrBlobStorage.TVDiskID VDiskId = 1;
- NKikimrBlobStorage.TVSlotId From = 2;
- NKikimrBlobStorage.TVSlotId To = 3;
- string FromFqdn = 4;
- string FromPath = 5;
- string ToFqdn = 6;
- string ToPath = 7;
-}
-
-message TConfigResponse {
- message TStatus {
- enum EFailReason {
- kGeneric = 0;
- kHostNotFound = 1;
- kPDiskNotFound = 2;
- kHostConfigNotFound = 3;
- kItemConfigGenerationMismatch = 4;
- kMayLoseData = 5;
- kVDiskIdIncorrect = 6;
- kVSlotNotFound = 7;
- kDiskIsNotDonor = 8;
+message TReassignedItem {
+ NKikimrBlobStorage.TVDiskID VDiskId = 1;
+ NKikimrBlobStorage.TVSlotId From = 2;
+ NKikimrBlobStorage.TVSlotId To = 3;
+ string FromFqdn = 4;
+ string FromPath = 5;
+ string ToFqdn = 6;
+ string ToPath = 7;
+}
+
+message TConfigResponse {
+ message TStatus {
+ enum EFailReason {
+ kGeneric = 0;
+ kHostNotFound = 1;
+ kPDiskNotFound = 2;
+ kHostConfigNotFound = 3;
+ kItemConfigGenerationMismatch = 4;
+ kMayLoseData = 5;
+ kVDiskIdIncorrect = 6;
+ kVSlotNotFound = 7;
+ kDiskIsNotDonor = 8;
kAlready = 9;
- kMayGetDegraded = 10;
- }
-
- message TFailParam {
- oneof Value {
- string Fqdn = 1;
- int32 IcPort = 2;
- uint32 NodeId = 3;
- uint32 PDiskId = 4;
- string Path = 5;
- uint64 HostConfigId = 6;
- uint64 BoxId = 7;
- uint64 StoragePoolId = 8;
- uint64 ItemConfigGenerationProvided = 9;
- uint64 ItemConfigGenerationExpected = 10;
- uint32 GroupId = 11;
- NKikimrBlobStorage.TVDiskID VDiskId = 12;
- NKikimrBlobStorage.TVSlotId VSlotId = 13;
- }
- }
-
- bool Success = 1;
- string ErrorDescription = 2;
- EFailReason FailReason = 12;
- repeated TFailParam FailParam = 13;
- repeated TDefineHostConfig HostConfig = 3;
- repeated TDefineBox Box = 4;
- repeated TUpdateDriveStatus DriveStatus = 5;
- repeated TDefineStoragePool StoragePool = 6;
- TBaseConfig BaseConfig = 7;
- repeated uint32 GroupId = 8;
- uint64 AssignedStoragePoolId = 9;
- repeated TMoveCommand MoveCommand = 10;
+ kMayGetDegraded = 10;
+ }
+
+ message TFailParam {
+ oneof Value {
+ string Fqdn = 1;
+ int32 IcPort = 2;
+ uint32 NodeId = 3;
+ uint32 PDiskId = 4;
+ string Path = 5;
+ uint64 HostConfigId = 6;
+ uint64 BoxId = 7;
+ uint64 StoragePoolId = 8;
+ uint64 ItemConfigGenerationProvided = 9;
+ uint64 ItemConfigGenerationExpected = 10;
+ uint32 GroupId = 11;
+ NKikimrBlobStorage.TVDiskID VDiskId = 12;
+ NKikimrBlobStorage.TVSlotId VSlotId = 13;
+ }
+ }
+
+ bool Success = 1;
+ string ErrorDescription = 2;
+ EFailReason FailReason = 12;
+ repeated TFailParam FailParam = 13;
+ repeated TDefineHostConfig HostConfig = 3;
+ repeated TDefineBox Box = 4;
+ repeated TUpdateDriveStatus DriveStatus = 5;
+ repeated TDefineStoragePool StoragePool = 6;
+ TBaseConfig BaseConfig = 7;
+ repeated uint32 GroupId = 8;
+ uint64 AssignedStoragePoolId = 9;
+ repeated TMoveCommand MoveCommand = 10;
repeated TPDiskStat PDiskStat = 11;
- repeated TReassignedItem ReassignedItem = 14;
- TDeclareIntent Intent = 15;
- }
-
- repeated TStatus Status = 1;
- bool Success = 2;
- string ErrorDescription = 3;
-}
+ repeated TReassignedItem ReassignedItem = 14;
+ TDeclareIntent Intent = 15;
+ }
+
+ repeated TStatus Status = 1;
+ bool Success = 2;
+ string ErrorDescription = 3;
+}
diff --git a/ydb/core/protos/blobstorage_disk.proto b/ydb/core/protos/blobstorage_disk.proto
index 6b3c4b1ed81..d20a414a456 100644
--- a/ydb/core/protos/blobstorage_disk.proto
+++ b/ydb/core/protos/blobstorage_disk.proto
@@ -1,76 +1,76 @@
-package NKikimrBlobStorage;
-option java_package = "ru.yandex.kikimr.proto";
-
+package NKikimrBlobStorage;
+option java_package = "ru.yandex.kikimr.proto";
+
import "ydb/core/protos/blobstorage_disk_color.proto";
-
-message TPDiskState {
- enum E {
- Initial = 0;
- InitialFormatRead = 1;
- InitialFormatReadError = 2;
- InitialSysLogRead = 3;
- InitialSysLogReadError = 4;
- InitialSysLogParseError = 5;
- InitialCommonLogRead = 6;
- InitialCommonLogReadError = 7;
- InitialCommonLogParseError = 8;
- CommonLoggerInitError = 9;
- Normal = 10;
- OpenFileError = 11;
- ChunkQuotaError = 12;
- DeviceIoError = 13;
- Reserved14 = 14;
- Reserved15 = 15;
- Reserved16 = 16;
-
- Missing = 252;
- Timeout = 253;
- NodeDisconnected = 254;
- Unknown = 255;
- // end
- }
-}
-
-message TVDiskID {
- optional uint32 GroupID = 1;
- optional uint32 GroupGeneration = 2;
- optional uint32 Ring = 3;
- optional uint32 Domain = 4;
- optional uint32 VDisk = 5;
-}
-
-message TVSlotId {
- optional uint32 NodeId = 1;
- optional uint32 PDiskId = 2;
- optional uint32 VSlotId = 3;
-}
-
-message TVDiskMetrics {
- optional TVDiskID VDiskId = 1;
- optional uint32 SatisfactionRank = 2;
- optional uint64 AvailableSize = 3;
- optional uint64 AllocatedSize = 4;
- //optional uint64 ReadThroughput = 5; // bytes per second
- //optional uint64 WriteThroughput = 6; // bytes per second
- optional uint32 StatusFlags = 7;
- optional TVSlotId VSlotId = 8;
- optional double Occupancy = 9;
- optional NKikimrBlobStorage.TPDiskSpaceColor.E SpaceColor = 10;
-}
-
-message TPDiskMetrics {
- optional uint32 PDiskId = 1;
- optional uint64 AvailableSize = 2;
- optional uint64 TotalSize = 3;
- optional uint64 MaxReadThroughput = 4; // bytes per second
- optional uint64 MaxWriteThroughput = 5; // bytes per second
- optional uint64 NonRealTimeMs = 6; // ms per second of non-realtime, [0..1000]
- optional uint64 SlowDeviceMs = 7; // ms per second of slow device, [0..1000]
- optional uint32 MaxIOPS = 8; // number of IOPS this device can carry out
-
- // maximum expected slot size; if set, then it is guaranteed that EnforcedDynamicSlotSize bytes of space are
- // available for every slot over this PDisk; if not set, then no space enforcement assumed
- optional uint64 EnforcedDynamicSlotSize = 9;
-
- optional TPDiskState.E State = 10;
-}
+
+message TPDiskState {
+ enum E {
+ Initial = 0;
+ InitialFormatRead = 1;
+ InitialFormatReadError = 2;
+ InitialSysLogRead = 3;
+ InitialSysLogReadError = 4;
+ InitialSysLogParseError = 5;
+ InitialCommonLogRead = 6;
+ InitialCommonLogReadError = 7;
+ InitialCommonLogParseError = 8;
+ CommonLoggerInitError = 9;
+ Normal = 10;
+ OpenFileError = 11;
+ ChunkQuotaError = 12;
+ DeviceIoError = 13;
+ Reserved14 = 14;
+ Reserved15 = 15;
+ Reserved16 = 16;
+
+ Missing = 252;
+ Timeout = 253;
+ NodeDisconnected = 254;
+ Unknown = 255;
+ // end
+ }
+}
+
+message TVDiskID {
+ optional uint32 GroupID = 1;
+ optional uint32 GroupGeneration = 2;
+ optional uint32 Ring = 3;
+ optional uint32 Domain = 4;
+ optional uint32 VDisk = 5;
+}
+
+message TVSlotId {
+ optional uint32 NodeId = 1;
+ optional uint32 PDiskId = 2;
+ optional uint32 VSlotId = 3;
+}
+
+message TVDiskMetrics {
+ optional TVDiskID VDiskId = 1;
+ optional uint32 SatisfactionRank = 2;
+ optional uint64 AvailableSize = 3;
+ optional uint64 AllocatedSize = 4;
+ //optional uint64 ReadThroughput = 5; // bytes per second
+ //optional uint64 WriteThroughput = 6; // bytes per second
+ optional uint32 StatusFlags = 7;
+ optional TVSlotId VSlotId = 8;
+ optional double Occupancy = 9;
+ optional NKikimrBlobStorage.TPDiskSpaceColor.E SpaceColor = 10;
+}
+
+message TPDiskMetrics {
+ optional uint32 PDiskId = 1;
+ optional uint64 AvailableSize = 2;
+ optional uint64 TotalSize = 3;
+ optional uint64 MaxReadThroughput = 4; // bytes per second
+ optional uint64 MaxWriteThroughput = 5; // bytes per second
+ optional uint64 NonRealTimeMs = 6; // ms per second of non-realtime, [0..1000]
+ optional uint64 SlowDeviceMs = 7; // ms per second of slow device, [0..1000]
+ optional uint32 MaxIOPS = 8; // number of IOPS this device can carry out
+
+ // maximum expected slot size; if set, then it is guaranteed that EnforcedDynamicSlotSize bytes of space are
+ // available for every slot over this PDisk; if not set, then no space enforcement assumed
+ optional uint64 EnforcedDynamicSlotSize = 9;
+
+ optional TPDiskState.E State = 10;
+}
diff --git a/ydb/core/protos/blobstorage_disk_color.proto b/ydb/core/protos/blobstorage_disk_color.proto
index cd8ca9c378e..35216ee1823 100644
--- a/ydb/core/protos/blobstorage_disk_color.proto
+++ b/ydb/core/protos/blobstorage_disk_color.proto
@@ -1,16 +1,16 @@
-syntax = "proto3";
-
-package NKikimrBlobStorage;
-
-message TPDiskSpaceColor {
- enum E {
- GREEN = 0;
- CYAN = 10;
+syntax = "proto3";
+
+package NKikimrBlobStorage;
+
+message TPDiskSpaceColor {
+ enum E {
+ GREEN = 0;
+ CYAN = 10;
LIGHT_YELLOW = 15;
- YELLOW = 20;
- LIGHT_ORANGE = 30;
- ORANGE = 40;
- RED = 50;
- BLACK = 60;
- }
-}
+ YELLOW = 20;
+ LIGHT_ORANGE = 30;
+ ORANGE = 40;
+ RED = 50;
+ BLACK = 60;
+ }
+}
diff --git a/ydb/core/protos/blobstorage_vdisk_config.proto b/ydb/core/protos/blobstorage_vdisk_config.proto
index 5b800c1cf65..207052787f9 100644
--- a/ydb/core/protos/blobstorage_vdisk_config.proto
+++ b/ydb/core/protos/blobstorage_vdisk_config.proto
@@ -14,13 +14,13 @@ message TVDiskConfig {
optional bool FreshUseDreg = 21;
optional bool AllowKeepFlags = 40;
-
+
optional uint32 HullCompLevel0MaxSstsAtOnce = 45;
optional uint32 HullCompSortedPartsNum = 46;
- optional uint32 ReplInterconnectChannel = 50;
-
- optional bool BarrierValidation = 60;
+ optional uint32 ReplInterconnectChannel = 50;
+
+ optional bool BarrierValidation = 60;
optional bool EnableOverseerLsnReporting = 61; // deprecated
};
@@ -52,10 +52,10 @@ message TAllVDiskKinds {
repeated TVDiskKind VDiskKinds = 1;
};
-message TIncrHugeConfig {
- optional uint32 MinHugeBlobInBytes = 1 [default = 500000];
- optional uint32 MinCleanChunks = 2 [default = 8];
- optional uint32 MinAllocationBatch = 3 [default = 4];
- optional uint32 UnalignedBlockSize = 4 [default = 50000];
- optional uint32 MaxInFlightWrites = 5 [default = 5];
-};
+message TIncrHugeConfig {
+ optional uint32 MinHugeBlobInBytes = 1 [default = 500000];
+ optional uint32 MinCleanChunks = 2 [default = 8];
+ optional uint32 MinAllocationBatch = 3 [default = 4];
+ optional uint32 UnalignedBlockSize = 4 [default = 50000];
+ optional uint32 MaxInFlightWrites = 5 [default = 5];
+};
diff --git a/ydb/core/protos/blobstorage_vdisk_internal.proto b/ydb/core/protos/blobstorage_vdisk_internal.proto
index fc674e70c08..e9836eaffde 100644
--- a/ydb/core/protos/blobstorage_vdisk_internal.proto
+++ b/ydb/core/protos/blobstorage_vdisk_internal.proto
@@ -1,19 +1,19 @@
import "ydb/core/protos/base.proto";
import "ydb/core/protos/blobstorage.proto";
import "ydb/core/protos/blobstorage_disk.proto";
-
-package NKikimrVDiskData;
-
-////////////////////////////////////////////////////////////////////////////////
-// On-disk structures
-////////////////////////////////////////////////////////////////////////////////
-
-message TDiskPart {
- optional uint32 ChunkIdx = 1;
- optional uint32 Offset = 2;
- optional uint32 Size = 3;
-};
-
+
+package NKikimrVDiskData;
+
+////////////////////////////////////////////////////////////////////////////////
+// On-disk structures
+////////////////////////////////////////////////////////////////////////////////
+
+message TDiskPart {
+ optional uint32 ChunkIdx = 1;
+ optional uint32 Offset = 2;
+ optional uint32 Size = 3;
+};
+
message TDiskPartVec {
repeated TDiskPart DiskParts = 1;
}
@@ -25,24 +25,24 @@ message TPhantomLogoBlobs {
////////////////////////////////////////////////////////////////////////////////
// Bulk formed sst info
////////////////////////////////////////////////////////////////////////////////
-message TBulkFormedSstInfo {
- optional uint64 FirstBlobLsn = 1;
- optional uint64 LastBlobLsn = 2;
- optional TDiskPart EntryPoint = 3;
- repeated uint32 ChunkIds = 4;
- optional bool RemovedFromIndex = 5 [default = false];
-};
-
-message TBulkFormedSstInfoSet {
- repeated TBulkFormedSstInfo Segments = 1;
-};
-
+message TBulkFormedSstInfo {
+ optional uint64 FirstBlobLsn = 1;
+ optional uint64 LastBlobLsn = 2;
+ optional TDiskPart EntryPoint = 3;
+ repeated uint32 ChunkIds = 4;
+ optional bool RemovedFromIndex = 5 [default = false];
+};
+
+message TBulkFormedSstInfoSet {
+ repeated TBulkFormedSstInfo Segments = 1;
+};
+
////////////////////////////////////////////////////////////////////////////////
// TLevelIndex -- record for hull db index
////////////////////////////////////////////////////////////////////////////////
message TLevel0 {
repeated TDiskPart Ssts = 1;
-};
+};
message TLevelX {
repeated TDiskPart Ssts = 1;
@@ -64,16 +64,16 @@ message TLevelIndex {
// THullDbEntryPoint -- entry point for the whole db
////////////////////////////////////////////////////////////////////////////////
message THullDbEntryPoint {
- message TUncommittedRemovedHugeBlob {
- optional uint64 RecordLsn = 1;
- optional TDiskPartVec RemovedHugeBlobs = 2;
- };
-
+ message TUncommittedRemovedHugeBlob {
+ optional uint64 RecordLsn = 1;
+ optional TDiskPartVec RemovedHugeBlobs = 2;
+ };
+
optional TLevelIndex LevelIndex = 1;
optional TDiskPartVec RemovedHugeBlobs = 2;
-
- // obsolete field
- repeated TUncommittedRemovedHugeBlob UncommittedRemovedHugeBlobs = 3;
+
+ // obsolete field
+ repeated TUncommittedRemovedHugeBlob UncommittedRemovedHugeBlobs = 3;
};
////////////////////////////////////////////////////////////////////////////////
@@ -123,54 +123,54 @@ message TSyncerEntryPoint {
repeated TSyncerVDiskEntry Entries = 10;
};
-message TIncrHugeChunks {
- enum EChunkState {
- Complete = 1;
- WriteIntent = 2;
- };
- message TChunkInfo {
- optional uint32 ChunkIdx = 1; // chunk index
- optional uint64 ChunkSerNum = 2; // unique id of allocated chunk
- optional EChunkState State = 3; // chunk state (whether it is complete and has index or write intent only)
- };
- repeated TChunkInfo Chunks = 1; // list of all consumed chunks
- repeated uint32 DeletedChunks = 2; // list of deleted chunks; incremental field only
- optional uint64 CurrentSerNum = 3; // current version of this state
-};
-
+message TIncrHugeChunks {
+ enum EChunkState {
+ Complete = 1;
+ WriteIntent = 2;
+ };
+ message TChunkInfo {
+ optional uint32 ChunkIdx = 1; // chunk index
+ optional uint64 ChunkSerNum = 2; // unique id of allocated chunk
+ optional EChunkState State = 3; // chunk state (whether it is complete and has index or write intent only)
+ };
+ repeated TChunkInfo Chunks = 1; // list of all consumed chunks
+ repeated uint32 DeletedChunks = 2; // list of deleted chunks; incremental field only
+ optional uint64 CurrentSerNum = 3; // current version of this state
+};
+
////////////////////////////////////////////////////////////////////////////////
// IncrHuge
////////////////////////////////////////////////////////////////////////////////
-message TIncrHugeDelete {
- message TChunkInfo {
- message TItemRange {
- optional uint32 First = 1;
- optional uint32 Count = 2;
- };
- message TDeletedItems {
- repeated uint32 Indexes = 1; // indexes of deleted items
- repeated TItemRange Ranges = 2; // ranges of deleted items
- };
- message TDeletedBits {
- optional bytes Bits = 1; // bitmap of deleted items
- };
-
- // unique id of this chunk
- optional uint64 ChunkSerNum = 1;
-
- // one of encodins of deletion
- oneof DeletedData {
- TDeletedItems DeletedItems = 2;
- bytes Bits = 3;
- };
- };
- message TOwnerInfo {
- optional uint32 Owner = 1; // owner of the record
- optional uint64 SeqNo = 2; // last sequence number of executed delete query from this owner
- };
- repeated TChunkInfo Chunks = 1; // deletes in active chunks
- repeated TOwnerInfo Owners = 2; // per-owner sequence numbers
-};
+message TIncrHugeDelete {
+ message TChunkInfo {
+ message TItemRange {
+ optional uint32 First = 1;
+ optional uint32 Count = 2;
+ };
+ message TDeletedItems {
+ repeated uint32 Indexes = 1; // indexes of deleted items
+ repeated TItemRange Ranges = 2; // ranges of deleted items
+ };
+ message TDeletedBits {
+ optional bytes Bits = 1; // bitmap of deleted items
+ };
+
+ // unique id of this chunk
+ optional uint64 ChunkSerNum = 1;
+
+ // one of encodins of deletion
+ oneof DeletedData {
+ TDeletedItems DeletedItems = 2;
+ bytes Bits = 3;
+ };
+ };
+ message TOwnerInfo {
+ optional uint32 Owner = 1; // owner of the record
+ optional uint64 SeqNo = 2; // last sequence number of executed delete query from this owner
+ };
+ repeated TChunkInfo Chunks = 1; // deletes in active chunks
+ repeated TOwnerInfo Owners = 2; // per-owner sequence numbers
+};
////////////////////////////////////////////////////////////////////////////////
@@ -218,19 +218,19 @@ message TSyncLogEntryPoint {
optional bytes DiskRecLogSerialized = 21;
};
-message TScrubState {
- optional uint64 NextSstIdToScrub = 1;
- optional NKikimrProto.TLogoBlobID BlobId = 2;
- optional bool Success = 3;
- optional fixed64 IncarnationGuid = 4;
-};
-
-message TScrubEntrypoint {
- message TUnreadableBlobState {
- optional NKikimrProto.TLogoBlobID BlobId = 1;
- optional uint32 UnreadableParts = 2;
- optional TDiskPart CorruptedPart = 3;
- }
- repeated TUnreadableBlobState UnreadableBlobs = 1;
- optional TScrubState ScrubState = 2;
-}
+message TScrubState {
+ optional uint64 NextSstIdToScrub = 1;
+ optional NKikimrProto.TLogoBlobID BlobId = 2;
+ optional bool Success = 3;
+ optional fixed64 IncarnationGuid = 4;
+};
+
+message TScrubEntrypoint {
+ message TUnreadableBlobState {
+ optional NKikimrProto.TLogoBlobID BlobId = 1;
+ optional uint32 UnreadableParts = 2;
+ optional TDiskPart CorruptedPart = 3;
+ }
+ repeated TUnreadableBlobState UnreadableBlobs = 1;
+ optional TScrubState ScrubState = 2;
+}
diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto
index d64169d4fc0..993efae40ae 100644
--- a/ydb/core/protos/config.proto
+++ b/ydb/core/protos/config.proto
@@ -132,19 +132,19 @@ message TStaticNameserviceConfig {
optional string Host = 4;
optional string InterconnectHost = 5;
-
- optional NActorsInterconnect.TNodeLocation Location = 6;
+
+ optional NActorsInterconnect.TNodeLocation Location = 6;
repeated TEndpoint Endpoint = 7;
- optional NActorsInterconnect.TNodeLocation WalleLocation = 8 [deprecated=true];
+ optional NActorsInterconnect.TNodeLocation WalleLocation = 8 [deprecated=true];
}
repeated TNode Node = 1;
optional string ClusterUUID = 2;
repeated string AcceptUUID = 3;
- optional bool SuppressVersionCheck = 4;
+ optional bool SuppressVersionCheck = 4;
optional ENameserviceType Type = 5;
}
@@ -231,9 +231,9 @@ message TDomainsConfig {
message TBlobStorageConfig {
optional NKikimrBlobStorage.TNodeWardenServiceSet ServiceSet = 1;
optional bool EnableOverseerLsnReporting = 2 [default = false]; // deprecated
- optional string CacheFilePath = 3;
- optional bool CachePDisks = 4 [default = true];
- optional bool CacheVDisks = 5 [default = true];
+ optional string CacheFilePath = 3;
+ optional bool CachePDisks = 4 [default = true];
+ optional bool CacheVDisks = 5 [default = true];
}
message TBlobStorageFormatConfig {
@@ -245,10 +245,10 @@ message TBlobStorageFormatConfig {
optional string Path = 5;
optional uint64 Guid = 6;
optional uint64 PDiskId = 7;
- optional uint64 DataCenterId = 8;
- optional uint64 RoomId = 9;
- optional uint64 BodyId = 10;
- optional NKikimrBlobStorage.TPDiskConfig PDiskConfig = 11;
+ optional uint64 DataCenterId = 8;
+ optional uint64 RoomId = 9;
+ optional uint64 BodyId = 10;
+ optional NKikimrBlobStorage.TPDiskConfig PDiskConfig = 11;
}
repeated TDrive Drive = 1;
@@ -358,23 +358,23 @@ message TInterconnectConfig {
optional uint32 Weight = 3; // use this instead of field "Quota"
}
- enum EMergeMode {
- AUTO = 0;
- PER_PEER = 1;
- PER_DATA_CENTER = 2;
- NO_MERGE = 3;
- }
-
- enum EEncryptionMode {
- DISABLED = 0;
- OPTIONAL = 1;
- REQUIRED = 2;
- };
-
+ enum EMergeMode {
+ AUTO = 0;
+ PER_PEER = 1;
+ PER_DATA_CENTER = 2;
+ NO_MERGE = 3;
+ }
+
+ enum EEncryptionMode {
+ DISABLED = 0;
+ OPTIONAL = 1;
+ REQUIRED = 2;
+ };
+
repeated TChannel Channel = 1;
- optional bool FirstTryBeforePoll = 2; // DEPRECATED
+ optional bool FirstTryBeforePoll = 2; // DEPRECATED
optional bool StartTcp = 3 [default = false];
- optional uint32 SelfKickDelay = 4; // DEPRECATED
+ optional uint32 SelfKickDelay = 4; // DEPRECATED
optional uint32 HandshakeTimeout = 5;
optional uint32 HeartbeatInterval = 6;
optional uint32 DeadPeerTimeout = 7;
@@ -382,38 +382,38 @@ message TInterconnectConfig {
optional uint32 CloseOnIdleTimeout = 9;
optional uint32 MaxInflightAmountOfDataInKB = 10;
optional bool MergePerPeerCounters = 11;
- optional EMergeMode CounterMergeMode = 15 [default = AUTO];
+ optional EMergeMode CounterMergeMode = 15 [default = AUTO];
optional uint32 TCPSocketBufferSize = 12;
optional uint32 MaxTimePerEventInMks = 13;
- optional bool BindOnAllAddresses = 16 [default = true];
- optional EEncryptionMode EncryptionMode = 17 [default = DISABLED];
- optional bool TlsAuthOnly = 38; // do not encrypt traffic
- optional bool EnforceScopeValidation = 18;
- optional bytes Certificate = 30; // in PEM format
- optional bytes PrivateKey = 31; // in PEM format
- optional string PathToCertificateFile = 35;
- optional string PathToPrivateKeyFile = 36;
- optional string PathToCaFile = 37;
- optional string CipherList = 34;
- optional NKikimrConfigUnits.TDuration MessagePendingTimeout = 32;
- optional uint64 MessagePendingSize = 33;
- optional bool SuppressConnectivityCheck = 39 [default = false];
-
- // ballast is added to IC handshake frames to ensure correctness of jumbo frames transmission over network
- optional uint32 HandshakeBallastSize = 14;
-
- // new-style definitions for various timeouts; when defined, they silently override values above
- optional NKikimrConfigUnits.TDuration SelfKickDelayDuration = 20; // DEPRECATED
- optional NKikimrConfigUnits.TDuration HandshakeTimeoutDuration = 21;
- optional NKikimrConfigUnits.TDuration HeartbeatIntervalDuration = 22;
- optional NKikimrConfigUnits.TDuration DeadPeerTimeoutDuration = 23;
- optional NKikimrConfigUnits.TDuration CloseOnIdleTimeoutDuration = 24;
+ optional bool BindOnAllAddresses = 16 [default = true];
+ optional EEncryptionMode EncryptionMode = 17 [default = DISABLED];
+ optional bool TlsAuthOnly = 38; // do not encrypt traffic
+ optional bool EnforceScopeValidation = 18;
+ optional bytes Certificate = 30; // in PEM format
+ optional bytes PrivateKey = 31; // in PEM format
+ optional string PathToCertificateFile = 35;
+ optional string PathToPrivateKeyFile = 36;
+ optional string PathToCaFile = 37;
+ optional string CipherList = 34;
+ optional NKikimrConfigUnits.TDuration MessagePendingTimeout = 32;
+ optional uint64 MessagePendingSize = 33;
+ optional bool SuppressConnectivityCheck = 39 [default = false];
+
+ // ballast is added to IC handshake frames to ensure correctness of jumbo frames transmission over network
+ optional uint32 HandshakeBallastSize = 14;
+
+ // new-style definitions for various timeouts; when defined, they silently override values above
+ optional NKikimrConfigUnits.TDuration SelfKickDelayDuration = 20; // DEPRECATED
+ optional NKikimrConfigUnits.TDuration HandshakeTimeoutDuration = 21;
+ optional NKikimrConfigUnits.TDuration HeartbeatIntervalDuration = 22;
+ optional NKikimrConfigUnits.TDuration DeadPeerTimeoutDuration = 23;
+ optional NKikimrConfigUnits.TDuration CloseOnIdleTimeoutDuration = 24;
optional uint64 TotalInflightAmountOfData = 25;
optional NKikimrConfigUnits.TDuration PingPeriodDuration = 26;
optional NKikimrConfigUnits.TDuration ForceConfirmPeriodDuration = 27;
optional NKikimrConfigUnits.TDuration LostConnectionDuration = 28;
- optional NKikimrConfigUnits.TDuration BatchPeriodDuration = 29;
+ optional NKikimrConfigUnits.TDuration BatchPeriodDuration = 29;
}
message TChannelProfileConfig {
@@ -422,9 +422,9 @@ message TChannelProfileConfig {
optional string ErasureSpecies = 1;
optional uint64 PDiskCategory = 2;
optional NKikimrBlobStorage.TVDiskKind.EVDiskKind VDiskCategory = 3 [default = Default];
-
- // this option uses new BS configuration interface to obtain matching groups, and it must not be provided
- // with any of the above fields
+
+ // this option uses new BS configuration interface to obtain matching groups, and it must not be provided
+ // with any of the above fields
optional string StoragePoolKind = 5;
}
@@ -559,19 +559,19 @@ message TMemoryLogConfig {
message TGRpcConfig {
optional bool StartGRpcProxy = 1 [default = true];
- optional string Host = 2 [default = "[::]"];
+ optional string Host = 2 [default = "[::]"];
optional uint32 Port = 3;
optional uint32 WorkerThreads = 4 [default = 2];
- optional uint64 GRpcMemoryQuotaBytes = 5 [default = 1073741824]; // 1 GB default; 0 == unlimited
+ optional uint64 GRpcMemoryQuotaBytes = 5 [default = 1073741824]; // 1 GB default; 0 == unlimited
optional uint64 MaxMessageSize = 6; // default = DEFAULT_GRPC_MESSAGE_SIZE_LIMIT
- optional uint32 MaxInFlight = 7; // 0 == unlimited [default]
+ optional uint32 MaxInFlight = 7; // 0 == unlimited [default]
optional NKikimrStream.TStreamingConfig StreamingConfig = 8;
// Ssl part
optional uint32 SslPort = 9;
optional string CA = 10;
optional string Cert = 11;
optional string Key = 12;
-
+
// public host/port for publishing
optional string PublicHost = 13;
optional uint32 PublicPort = 14;
@@ -588,7 +588,7 @@ message TGRpcConfig {
repeated string ServicesEnabled = 22;
repeated string ServicesDisabled = 23;
- // server socket options
+ // server socket options
optional bool KeepAliveEnable = 100 [default = true]; // SO_KEEPALIVE
optional uint32 KeepAliveIdleTimeoutTriggerSec = 101 [default = 90]; // TCP_KEEPIDLE
optional uint32 KeepAliveMaxProbeCount = 102 [default = 3]; // TCP_KEEPCNT
@@ -1345,7 +1345,7 @@ message TAppConfig {
optional TTabletsConfig TabletsConfig = 13; // alternative bootstrapper configuration
optional NKikimrBlobStorage.TAllVDiskKinds VDiskConfig = 14;
optional NKikimrBlobStorage.TDriveModelList DriveModelConfig = 31;
- optional NKikimrBlobStorage.TIncrHugeConfig IncrHugeConfig = 18;
+ optional NKikimrBlobStorage.TIncrHugeConfig IncrHugeConfig = 18;
optional string UDFsDir = 15;
repeated string UDFsPaths = 16;
optional TKQPConfig KQPConfig = 17;
diff --git a/ydb/core/protos/config_units.proto b/ydb/core/protos/config_units.proto
index ad164380906..0af06a2223d 100644
--- a/ydb/core/protos/config_units.proto
+++ b/ydb/core/protos/config_units.proto
@@ -1,13 +1,13 @@
-package NKikimrConfigUnits;
-
-// this file contains only structures used to describe different values expressed in corresponding units in configuration
-// protobufs; do not generate these structures in code -- they are intended only for handwritten configs
-
-// universal duration structure; resulting TDuration is obtained by summing all present values with their respective
-// weights; thus, you can define struct like "Duration { Seconds: 5 Milliseconds: 500 }" or
-// "Duration { Milliseconds: 5500 }", which has exactly the same duration value as the first one
-message TDuration {
- optional uint64 Seconds = 1;
- optional uint64 Milliseconds = 2;
- optional uint64 Microseconds = 3;
-}
+package NKikimrConfigUnits;
+
+// this file contains only structures used to describe different values expressed in corresponding units in configuration
+// protobufs; do not generate these structures in code -- they are intended only for handwritten configs
+
+// universal duration structure; resulting TDuration is obtained by summing all present values with their respective
+// weights; thus, you can define struct like "Duration { Seconds: 5 Milliseconds: 500 }" or
+// "Duration { Milliseconds: 5500 }", which has exactly the same duration value as the first one
+message TDuration {
+ optional uint64 Seconds = 1;
+ optional uint64 Milliseconds = 2;
+ optional uint64 Microseconds = 3;
+}
diff --git a/ydb/core/protos/counters.proto b/ydb/core/protos/counters.proto
index 05a8c93d905..0200a2df023 100644
--- a/ydb/core/protos/counters.proto
+++ b/ydb/core/protos/counters.proto
@@ -15,7 +15,7 @@ message TRange {
message TCounterOptions {
optional string Name = 1;
repeated TRange Ranges = 2;
- optional bool Integral = 3;
+ optional bool Integral = 3;
}
message TTxTypeOptions {
diff --git a/ydb/core/protos/counters_bs_controller.proto b/ydb/core/protos/counters_bs_controller.proto
index c0bd88bea17..25cd14b2137 100644
--- a/ydb/core/protos/counters_bs_controller.proto
+++ b/ydb/core/protos/counters_bs_controller.proto
@@ -8,10 +8,10 @@ option (TabletTypeName) = "BSController"; // Used as prefix for all counters
enum ESimpleCounters {
COUNTER_RESPONSE_TIME_USEC = 0 [(CounterOpts) = {Name: "ResponseTimeMicrosec"}];
- COUNTER_GROUPS_WITH_SLOTS_ON_FAULTY_DISKS = 1 [(CounterOpts) = {Name: "GroupsWithSlotsOnFaultyDisks"}];
- COUNTER_SLOTS_ON_FAULTY_DISKS = 2 [(CounterOpts) = {Name: "SlotsOnFaultyDisks"}];
- COUNTER_BYTES_ON_FAULTY_DISKS = 3 [(CounterOpts) = {Name: "BytesOnFaultyDisks"}];
- COUNTER_PDISKS_WITHOUT_EXPECTED_SLOT_COUNT = 4 [(CounterOpts) = {Name: "PDisksWithoutExpectedSlotCount"}];
+ COUNTER_GROUPS_WITH_SLOTS_ON_FAULTY_DISKS = 1 [(CounterOpts) = {Name: "GroupsWithSlotsOnFaultyDisks"}];
+ COUNTER_SLOTS_ON_FAULTY_DISKS = 2 [(CounterOpts) = {Name: "SlotsOnFaultyDisks"}];
+ COUNTER_BYTES_ON_FAULTY_DISKS = 3 [(CounterOpts) = {Name: "BytesOnFaultyDisks"}];
+ COUNTER_PDISKS_WITHOUT_EXPECTED_SLOT_COUNT = 4 [(CounterOpts) = {Name: "PDisksWithoutExpectedSlotCount"}];
COUNTER_TO_BE_REMOVED_DISKS = 5 [(CounterOpts) = {Name: "ToBeRemovedDisks"}];
COUNTER_GROUPS_WITH_SLOTS_ON_TO_BE_REMOVED_DISKS = 6 [(CounterOpts) = {Name: "GroupsWithSlotsOnToBeRemovedDisks"}];
COUNTER_SLOTS_ON_TO_BE_REMOVED_DISKS = 7 [(CounterOpts) = {Name: "SlotsOnToBeRemovedDisks"}];
@@ -20,118 +20,118 @@ enum ESimpleCounters {
COUNTER_DRIVE_SERIAL_NOT_SEEN = 10 [(CounterOpts) = {Name: "DriveSerialNotSeen"}];
COUNTER_DRIVE_SERIAL_REMOVED = 11 [(CounterOpts) = {Name: "DriveSerialRemoved"}];
COUNTER_DRIVE_SERIAL_ERROR = 12 [(CounterOpts) = {Name: "DriveSerialError"}];
- COUNTER_DISK_SCRUB_WAITING_FOR_START = 13 [(CounterOpts) = {Name: "DiskScrubWaitingForStart"}];
- COUNTER_DISK_SCRUB_RUNNING = 14 [(CounterOpts) = {Name: "DiskScrubRunning"}];
- COUNTER_DISK_SCRUB_IN_PROGRESS = 15 [(CounterOpts) = {Name: "DiskScrubInProgress"}];
- COUNTER_DISK_SCRUB_FINISHED_OK = 16 [(CounterOpts) = {Name: "DiskScrubFinishedOk"}];
- COUNTER_DISK_SCRUB_FINISHED_ERR = 17 [(CounterOpts) = {Name: "DiskScrubFinishedErr"}];
- COUNTER_DISK_SCRUB_CUR_DISKS = 18 [(CounterOpts) = {Name: "CurrentlyScrubbedDisks"}];
- COUNTER_DISK_SCRUB_CUR_GROUPS = 19 [(CounterOpts) = {Name: "CurrentlyScrubbedGroups"}];
- COUNTER_SELF_HEAL_UNREASSIGNABLE_GROUPS = 20 [(CounterOpts) = {Name: "SelfHealUnreassignableGroups"}];
+ COUNTER_DISK_SCRUB_WAITING_FOR_START = 13 [(CounterOpts) = {Name: "DiskScrubWaitingForStart"}];
+ COUNTER_DISK_SCRUB_RUNNING = 14 [(CounterOpts) = {Name: "DiskScrubRunning"}];
+ COUNTER_DISK_SCRUB_IN_PROGRESS = 15 [(CounterOpts) = {Name: "DiskScrubInProgress"}];
+ COUNTER_DISK_SCRUB_FINISHED_OK = 16 [(CounterOpts) = {Name: "DiskScrubFinishedOk"}];
+ COUNTER_DISK_SCRUB_FINISHED_ERR = 17 [(CounterOpts) = {Name: "DiskScrubFinishedErr"}];
+ COUNTER_DISK_SCRUB_CUR_DISKS = 18 [(CounterOpts) = {Name: "CurrentlyScrubbedDisks"}];
+ COUNTER_DISK_SCRUB_CUR_GROUPS = 19 [(CounterOpts) = {Name: "CurrentlyScrubbedGroups"}];
+ COUNTER_SELF_HEAL_UNREASSIGNABLE_GROUPS = 20 [(CounterOpts) = {Name: "SelfHealUnreassignableGroups"}];
}
enum ECumulativeCounters {
- COUNTER_REGISTER_NODE_COUNT = 0 [(CounterOpts) = {Name: "RegisterNodeCount"}];
- COUNTER_REGISTER_NODE_USEC = 1 [(CounterOpts) = {Name: "RegisterNodeMicrosec"}];
- COUNTER_GET_GROUP_COUNT = 2 [(CounterOpts) = {Name: "GetGroupCount"}];
- COUNTER_GET_GROUP_USEC = 3 [(CounterOpts) = {Name: "GetGroupMicrosec"}];
- COUNTER_SELECT_GROUPS_COUNT = 4 [(CounterOpts) = {Name: "SelectGroupsCount"}];
- COUNTER_SELECT_GROUPS_USEC = 5 [(CounterOpts) = {Name: "SelectGroupsMicrosec"}];
- COUNTER_UPDATE_DISK_METRICS_COUNT = 6 [(CounterOpts) = {Name: "UpdateDiskMetricsCount"}];
- COUNTER_UPDATE_DISK_METRICS_USEC = 7 [(CounterOpts) = {Name: "UpdateDiskMetricsMicrosec"}];
- COUNTER_NODE_REPORT_COUNT = 8 [(CounterOpts) = {Name: "NodeReportCount"}];
- COUNTER_NODE_REPORT_USEC = 9 [(CounterOpts) = {Name: "NodeReportMicrosec"}];
- COUNTER_CONFIG_COUNT = 10 [(CounterOpts) = {Name: "ConfigCount"}];
- COUNTER_CONFIG_USEC = 11 [(CounterOpts) = {Name: "ConfigMicrosec"}];
- COUNTER_REQUEST_INFO_COUNT = 12 [(CounterOpts) = {Name: "RequestInfoCount"}];
- COUNTER_REQUEST_INFO_USEC = 13 [(CounterOpts) = {Name: "RequestInfoMicrosec"}];
-
- COUNTER_SELFHEAL_REASSIGN_BSC_REQUESTS = 14 [(CounterOpts) = {Name: "SelfHealReassignBscRequests"}];
- COUNTER_SELFHEAL_REASSIGN_BSC_OK = 15 [(CounterOpts) = {Name: "SelfHealReassignBscOk"}];
- COUNTER_SELFHEAL_REASSIGN_BSC_ERR = 16 [(CounterOpts) = {Name: "SelfHealReassignBscErr"}];
-
- COUNTER_CONFIGCMD_DEFINE_HOST_CONFIG_USEC = 17 [(CounterOpts) = {Name: "DefineHostConfig"}];
- COUNTER_CONFIGCMD_READ_HOST_CONFIG_USEC = 18 [(CounterOpts) = {Name: "ReadHostConfig"}];
- COUNTER_CONFIGCMD_DELETE_HOST_CONFIG_USEC = 19 [(CounterOpts) = {Name: "DeleteHostConfig"}];
- COUNTER_CONFIGCMD_DEFINE_BOX_USEC = 20 [(CounterOpts) = {Name: "DefineBox"}];
- COUNTER_CONFIGCMD_READ_BOX_USEC = 21 [(CounterOpts) = {Name: "ReadBox"}];
- COUNTER_CONFIGCMD_DELETE_BOX_USEC = 22 [(CounterOpts) = {Name: "DeleteBox"}];
- COUNTER_CONFIGCMD_DEFINE_STORAGE_POOL_USEC = 23 [(CounterOpts) = {Name: "DefineStoragePool"}];
- COUNTER_CONFIGCMD_READ_STORAGE_POOL_USEC = 24 [(CounterOpts) = {Name: "ReadStoragePool"}];
- COUNTER_CONFIGCMD_DELETE_STORAGE_POOL_USEC = 25 [(CounterOpts) = {Name: "DeleteStoragePool"}];
- COUNTER_CONFIGCMD_UPDATE_DRIVE_STATUS_USEC = 26 [(CounterOpts) = {Name: "UpdateDriveStatus"}];
- COUNTER_CONFIGCMD_READ_DRIVE_STATUS_USEC = 27 [(CounterOpts) = {Name: "ReadDriveStatus"}];
- COUNTER_CONFIGCMD_PROPOSE_STORAGE_POOLS_USEC = 28 [(CounterOpts) = {Name: "ProposeStoragePools"}];
- COUNTER_CONFIGCMD_QUERY_BASE_CONFIG_USEC = 29 [(CounterOpts) = {Name: "QueryBaseConfig"}];
- COUNTER_CONFIGCMD_MERGE_BOXES_USEC = 30 [(CounterOpts) = {Name: "MergeBoxes"}];
- COUNTER_CONFIGCMD_MOVE_GROUPS_USEC = 31 [(CounterOpts) = {Name: "MoveGroups"}];
- COUNTER_CONFIGCMD_ADD_MIGRATION_PLAN_USEC = 32 [(CounterOpts) = {Name: "AddMigrationPlan"}];
- COUNTER_CONFIGCMD_DELETE_MIGRATION_PLAN_USEC = 33 [(CounterOpts) = {Name: "DeleteMigrationPlan"}];
- COUNTER_CONFIGCMD_DECLARE_INTENT_USEC = 34 [(CounterOpts) = {Name: "DeclareIntent"}];
- COUNTER_CONFIGCMD_READ_INTENT_USEC = 35 [(CounterOpts) = {Name: "ReadIntent"}];
- COUNTER_CONFIGCMD_DROP_DONOR_DISK_USEC = 36 [(CounterOpts) = {Name: "DropDonorDisk"}];
- COUNTER_CONFIGCMD_REASSIGN_GROUP_DISK_USEC = 37 [(CounterOpts) = {Name: "ReassignGroupDisk"}];
-
- COUNTER_DISK_SCRUB_QUANTUM_FINISHED = 38 [(CounterOpts) = {Name: "QuantumFinished"}];
+ COUNTER_REGISTER_NODE_COUNT = 0 [(CounterOpts) = {Name: "RegisterNodeCount"}];
+ COUNTER_REGISTER_NODE_USEC = 1 [(CounterOpts) = {Name: "RegisterNodeMicrosec"}];
+ COUNTER_GET_GROUP_COUNT = 2 [(CounterOpts) = {Name: "GetGroupCount"}];
+ COUNTER_GET_GROUP_USEC = 3 [(CounterOpts) = {Name: "GetGroupMicrosec"}];
+ COUNTER_SELECT_GROUPS_COUNT = 4 [(CounterOpts) = {Name: "SelectGroupsCount"}];
+ COUNTER_SELECT_GROUPS_USEC = 5 [(CounterOpts) = {Name: "SelectGroupsMicrosec"}];
+ COUNTER_UPDATE_DISK_METRICS_COUNT = 6 [(CounterOpts) = {Name: "UpdateDiskMetricsCount"}];
+ COUNTER_UPDATE_DISK_METRICS_USEC = 7 [(CounterOpts) = {Name: "UpdateDiskMetricsMicrosec"}];
+ COUNTER_NODE_REPORT_COUNT = 8 [(CounterOpts) = {Name: "NodeReportCount"}];
+ COUNTER_NODE_REPORT_USEC = 9 [(CounterOpts) = {Name: "NodeReportMicrosec"}];
+ COUNTER_CONFIG_COUNT = 10 [(CounterOpts) = {Name: "ConfigCount"}];
+ COUNTER_CONFIG_USEC = 11 [(CounterOpts) = {Name: "ConfigMicrosec"}];
+ COUNTER_REQUEST_INFO_COUNT = 12 [(CounterOpts) = {Name: "RequestInfoCount"}];
+ COUNTER_REQUEST_INFO_USEC = 13 [(CounterOpts) = {Name: "RequestInfoMicrosec"}];
+
+ COUNTER_SELFHEAL_REASSIGN_BSC_REQUESTS = 14 [(CounterOpts) = {Name: "SelfHealReassignBscRequests"}];
+ COUNTER_SELFHEAL_REASSIGN_BSC_OK = 15 [(CounterOpts) = {Name: "SelfHealReassignBscOk"}];
+ COUNTER_SELFHEAL_REASSIGN_BSC_ERR = 16 [(CounterOpts) = {Name: "SelfHealReassignBscErr"}];
+
+ COUNTER_CONFIGCMD_DEFINE_HOST_CONFIG_USEC = 17 [(CounterOpts) = {Name: "DefineHostConfig"}];
+ COUNTER_CONFIGCMD_READ_HOST_CONFIG_USEC = 18 [(CounterOpts) = {Name: "ReadHostConfig"}];
+ COUNTER_CONFIGCMD_DELETE_HOST_CONFIG_USEC = 19 [(CounterOpts) = {Name: "DeleteHostConfig"}];
+ COUNTER_CONFIGCMD_DEFINE_BOX_USEC = 20 [(CounterOpts) = {Name: "DefineBox"}];
+ COUNTER_CONFIGCMD_READ_BOX_USEC = 21 [(CounterOpts) = {Name: "ReadBox"}];
+ COUNTER_CONFIGCMD_DELETE_BOX_USEC = 22 [(CounterOpts) = {Name: "DeleteBox"}];
+ COUNTER_CONFIGCMD_DEFINE_STORAGE_POOL_USEC = 23 [(CounterOpts) = {Name: "DefineStoragePool"}];
+ COUNTER_CONFIGCMD_READ_STORAGE_POOL_USEC = 24 [(CounterOpts) = {Name: "ReadStoragePool"}];
+ COUNTER_CONFIGCMD_DELETE_STORAGE_POOL_USEC = 25 [(CounterOpts) = {Name: "DeleteStoragePool"}];
+ COUNTER_CONFIGCMD_UPDATE_DRIVE_STATUS_USEC = 26 [(CounterOpts) = {Name: "UpdateDriveStatus"}];
+ COUNTER_CONFIGCMD_READ_DRIVE_STATUS_USEC = 27 [(CounterOpts) = {Name: "ReadDriveStatus"}];
+ COUNTER_CONFIGCMD_PROPOSE_STORAGE_POOLS_USEC = 28 [(CounterOpts) = {Name: "ProposeStoragePools"}];
+ COUNTER_CONFIGCMD_QUERY_BASE_CONFIG_USEC = 29 [(CounterOpts) = {Name: "QueryBaseConfig"}];
+ COUNTER_CONFIGCMD_MERGE_BOXES_USEC = 30 [(CounterOpts) = {Name: "MergeBoxes"}];
+ COUNTER_CONFIGCMD_MOVE_GROUPS_USEC = 31 [(CounterOpts) = {Name: "MoveGroups"}];
+ COUNTER_CONFIGCMD_ADD_MIGRATION_PLAN_USEC = 32 [(CounterOpts) = {Name: "AddMigrationPlan"}];
+ COUNTER_CONFIGCMD_DELETE_MIGRATION_PLAN_USEC = 33 [(CounterOpts) = {Name: "DeleteMigrationPlan"}];
+ COUNTER_CONFIGCMD_DECLARE_INTENT_USEC = 34 [(CounterOpts) = {Name: "DeclareIntent"}];
+ COUNTER_CONFIGCMD_READ_INTENT_USEC = 35 [(CounterOpts) = {Name: "ReadIntent"}];
+ COUNTER_CONFIGCMD_DROP_DONOR_DISK_USEC = 36 [(CounterOpts) = {Name: "DropDonorDisk"}];
+ COUNTER_CONFIGCMD_REASSIGN_GROUP_DISK_USEC = 37 [(CounterOpts) = {Name: "ReassignGroupDisk"}];
+
+ COUNTER_DISK_SCRUB_QUANTUM_FINISHED = 38 [(CounterOpts) = {Name: "QuantumFinished"}];
}
enum EPercentileCounters {
option (GlobalCounterOpts) = {
- Ranges { Value: 0 Name: "(1) < 500 us" }
- Ranges { Value: 500 Name: "(2) 0.5-1 ms" }
- Ranges { Value: 1000 Name: "(3) 1-2 ms" }
- Ranges { Value: 2000 Name: "(4) 2-4 ms" }
- Ranges { Value: 4000 Name: "(5) 4-8 ms" }
- Ranges { Value: 8000 Name: "(6) 8-16 ms" }
- Ranges { Value: 16000 Name: "(7) 16-32 ms" }
- Ranges { Value: 32000 Name: "(8) 32-64 ms" }
- Ranges { Value: 64000 Name: "(9) 64-128 ms" }
- Ranges { Value: 128000 Name: "(10) 128-256 ms" }
- Ranges { Value: 256000 Name: "(11) 256-512 ms" }
- Ranges { Value: 512000 Name: "(12) 512-1024 ms" }
- Ranges { Value: 1024000 Name: "(13) 1024-2000 ms" }
- Ranges { Value: 2000000 Name: "(14) 2-4 s" }
- Ranges { Value: 4000000 Name: "(15) 4-8 s" }
- Ranges { Value: 8000000 Name: "(16) 8-16 s" }
- Ranges { Value: 16000000 Name: "(17) 16-32 s" }
- Ranges { Value: 32000000 Name: "(18) 32 < s" }
+ Ranges { Value: 0 Name: "(1) < 500 us" }
+ Ranges { Value: 500 Name: "(2) 0.5-1 ms" }
+ Ranges { Value: 1000 Name: "(3) 1-2 ms" }
+ Ranges { Value: 2000 Name: "(4) 2-4 ms" }
+ Ranges { Value: 4000 Name: "(5) 4-8 ms" }
+ Ranges { Value: 8000 Name: "(6) 8-16 ms" }
+ Ranges { Value: 16000 Name: "(7) 16-32 ms" }
+ Ranges { Value: 32000 Name: "(8) 32-64 ms" }
+ Ranges { Value: 64000 Name: "(9) 64-128 ms" }
+ Ranges { Value: 128000 Name: "(10) 128-256 ms" }
+ Ranges { Value: 256000 Name: "(11) 256-512 ms" }
+ Ranges { Value: 512000 Name: "(12) 512-1024 ms" }
+ Ranges { Value: 1024000 Name: "(13) 1024-2000 ms" }
+ Ranges { Value: 2000000 Name: "(14) 2-4 s" }
+ Ranges { Value: 4000000 Name: "(15) 4-8 s" }
+ Ranges { Value: 8000000 Name: "(16) 8-16 s" }
+ Ranges { Value: 16000000 Name: "(17) 16-32 s" }
+ Ranges { Value: 32000000 Name: "(18) 32 < s" }
};
- COUNTER_PERCENTILE_SELECT_GROUPS = 0 [(CounterOpts) = {Name: "SelectGroups"}];
-
- COUNTER_FAULTY_USETTLED_PDISKS = 1 [(CounterOpts) = {
- Name: "FaultyUnsettledPDisks"
- Integral: true
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 10 Name: "10" }
- Ranges { Value: 20 Name: "20" }
- Ranges { Value: 30 Name: "30" }
- Ranges { Value: 40 Name: "40" }
- Ranges { Value: 50 Name: "50" }
- Ranges { Value: 60 Name: "60" }
- Ranges { Value: 120 Name: "120" }
- Ranges { Value: 180 Name: "180" }
- Ranges { Value: 240 Name: "240" }
- Ranges { Value: 300 Name: "300" }
- Ranges { Value: 360 Name: "360" }
- Ranges { Value: 420 Name: "420" }
- Ranges { Value: 480 Name: "480" }
- Ranges { Value: 540 Name: "540" }
- Ranges { Value: 600 Name: "600" }
- Ranges { Value: 1200 Name: "1200" }
- Ranges { Value: 1800 Name: "1800" }
- Ranges { Value: 2400 Name: "2400" }
- Ranges { Value: 3000 Name: "3000" }
- Ranges { Value: 3600 Name: "3600" }
- Ranges { Value: 5400 Name: "5400" }
- Ranges { Value: 7200 Name: "7200" }
- Ranges { Value: 9000 Name: "9000" }
- Ranges { Value: 10800 Name: "10800" }
- Ranges { Value: 14400 Name: "14400" }
- Ranges { Value: 18000 Name: "18000" }
- Ranges { Value: 21600 Name: "21600" }
- Ranges { Value: 86400 Name: "inf" }
- }];
+ COUNTER_PERCENTILE_SELECT_GROUPS = 0 [(CounterOpts) = {Name: "SelectGroups"}];
+
+ COUNTER_FAULTY_USETTLED_PDISKS = 1 [(CounterOpts) = {
+ Name: "FaultyUnsettledPDisks"
+ Integral: true
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 10 Name: "10" }
+ Ranges { Value: 20 Name: "20" }
+ Ranges { Value: 30 Name: "30" }
+ Ranges { Value: 40 Name: "40" }
+ Ranges { Value: 50 Name: "50" }
+ Ranges { Value: 60 Name: "60" }
+ Ranges { Value: 120 Name: "120" }
+ Ranges { Value: 180 Name: "180" }
+ Ranges { Value: 240 Name: "240" }
+ Ranges { Value: 300 Name: "300" }
+ Ranges { Value: 360 Name: "360" }
+ Ranges { Value: 420 Name: "420" }
+ Ranges { Value: 480 Name: "480" }
+ Ranges { Value: 540 Name: "540" }
+ Ranges { Value: 600 Name: "600" }
+ Ranges { Value: 1200 Name: "1200" }
+ Ranges { Value: 1800 Name: "1800" }
+ Ranges { Value: 2400 Name: "2400" }
+ Ranges { Value: 3000 Name: "3000" }
+ Ranges { Value: 3600 Name: "3600" }
+ Ranges { Value: 5400 Name: "5400" }
+ Ranges { Value: 7200 Name: "7200" }
+ Ranges { Value: 9000 Name: "9000" }
+ Ranges { Value: 10800 Name: "10800" }
+ Ranges { Value: 14400 Name: "14400" }
+ Ranges { Value: 18000 Name: "18000" }
+ Ranges { Value: 21600 Name: "21600" }
+ Ranges { Value: 86400 Name: "inf" }
+ }];
COUNTER_TO_BE_REMOVED_USETTLED_PDISKS = 2 [(CounterOpts) = {
Name: "ToBeRemovedUnsettledPDisks"
@@ -166,52 +166,52 @@ enum EPercentileCounters {
Ranges { Value: 21600 Name: "21600" }
Ranges { Value: 86400 Name: "inf" }
}];
-
- COUNTER_NUM_NOT_READY_VDISKS = 3 [(CounterOpts) = {
- Name: "NumNotReadyVDisks"
- Integral: true
- Ranges { Value: 0 Name: "0" }
- Ranges { Value: 60 Name: "60" }
- Ranges { Value: 300 Name: "300" }
- Ranges { Value: 600 Name: "600" }
- Ranges { Value: 1200 Name: "1200" }
- Ranges { Value: 1800 Name: "1800" }
- Ranges { Value: 2400 Name: "2400" }
- Ranges { Value: 3000 Name: "3000" }
- Ranges { Value: 3600 Name: "3600" }
- Ranges { Value: 5400 Name: "5400" }
- Ranges { Value: 7200 Name: "7200" }
- Ranges { Value: 9000 Name: "9000" }
- Ranges { Value: 10800 Name: "10800" }
- Ranges { Value: 14400 Name: "14400" }
- Ranges { Value: 18000 Name: "18000" }
- Ranges { Value: 21600 Name: "21600" }
- Ranges { Value: 86400 Name: "inf" }
- }];
+
+ COUNTER_NUM_NOT_READY_VDISKS = 3 [(CounterOpts) = {
+ Name: "NumNotReadyVDisks"
+ Integral: true
+ Ranges { Value: 0 Name: "0" }
+ Ranges { Value: 60 Name: "60" }
+ Ranges { Value: 300 Name: "300" }
+ Ranges { Value: 600 Name: "600" }
+ Ranges { Value: 1200 Name: "1200" }
+ Ranges { Value: 1800 Name: "1800" }
+ Ranges { Value: 2400 Name: "2400" }
+ Ranges { Value: 3000 Name: "3000" }
+ Ranges { Value: 3600 Name: "3600" }
+ Ranges { Value: 5400 Name: "5400" }
+ Ranges { Value: 7200 Name: "7200" }
+ Ranges { Value: 9000 Name: "9000" }
+ Ranges { Value: 10800 Name: "10800" }
+ Ranges { Value: 14400 Name: "14400" }
+ Ranges { Value: 18000 Name: "18000" }
+ Ranges { Value: 21600 Name: "21600" }
+ Ranges { Value: 86400 Name: "inf" }
+ }];
}
enum ETxTypes {
- TXTYPE_INIT_SCHEME = 0 [(TxTypeOpts) = {Name: "TTxInitScheme"}];
- TXTYPE_MIGRATE = 1 [(TxTypeOpts) = {Name: "TTxMigrate"}];
- TXTYPE_LOAD_EVERYTHING = 2 [(TxTypeOpts) = {Name: "TTxLoadEverything"}];
- TXTYPE_MON_EVENT_OPERATION_LOG = 3 [(TxTypeOpts) = {Name: "TTxMonEvent_OperationLog"}];
- TXTYPE_MON_EVENT_SET_DOWN = 4 [(TxTypeOpts) = {Name: "TTxMonEvent_SetDown"}];
- TXTYPE_MON_EVENT_GET_DOWN = 5 [(TxTypeOpts) = {Name: "TTxMonEvent_GetDown"}];
- TXTYPE_UPDATE_DISK_METRICS = 6 [(TxTypeOpts) = {Name: "TTxUpdateDiskMetrics"}];
- TXTYPE_UPDATE_GROUP_LATENCIES = 7 [(TxTypeOpts) = {Name: "TTxUpdateGroupLatencies"}];
- TXTYPE_GROUP_RECONFIGURE_WIPE = 8 [(TxTypeOpts) = {Name: "TTxGroupReconfigureWipe"}];
- TXTYPE_NODE_REPORT = 9 [(TxTypeOpts) = {Name: "TTxNodeReport"}];
- TXTYPE_UPDATE_SEEN_OPERATIONAL = 10 [(TxTypeOpts) = {Name: "TTxUpdateSeenOperational"}];
- TXTYPE_CONFIG_CMD = 11 [(TxTypeOpts) = {Name: "TTxConfigCmd"}];
- TXTYPE_PROPOSE_GROUP_KEY = 12 [(TxTypeOpts) = {Name: "TTxProposeGroupKey"}];
- TXTYPE_REGISTER_NODE = 13 [(TxTypeOpts) = {Name: "TTxRegisterNode"}];
- TXTYPE_GET_GROUP = 14 [(TxTypeOpts) = {Name: "TTxGetGroup"}];
- TXTYPE_REQUEST_CONTROLLER_INFO = 15 [(TxTypeOpts) = {Name: "TTxRequestControllerInfo"}];
- TXTYPE_SELECT_GROUPS = 16 [(TxTypeOpts) = {Name: "TTxSelectGroups"}];
- TXTYPE_MON_EVENT_HEALTH_EVENTS = 17 [(TxTypeOpts) = {Name: "TTxMonEvent_HealthEvents"}];
- TXTYPE_DROP_DONOR = 18 [(TxTypeOpts) = {Name: "TTxDropDonor"}];
- TXTYPE_SCRUB_START = 19 [(TxTypeOpts) = {Name: "TTxScrubStart"}];
- TXTYPE_SCRUB_QUANTUM_FINISHED = 20 [(TxTypeOpts) = {Name: "TTxScrubQuantumFinished"}];
- TXTYPE_UPDATE_LAST_SEEN_READY = 21 [(TxTypeOpts) = {Name: "TTxUpdateLastSeenReady"}];
+ TXTYPE_INIT_SCHEME = 0 [(TxTypeOpts) = {Name: "TTxInitScheme"}];
+ TXTYPE_MIGRATE = 1 [(TxTypeOpts) = {Name: "TTxMigrate"}];
+ TXTYPE_LOAD_EVERYTHING = 2 [(TxTypeOpts) = {Name: "TTxLoadEverything"}];
+ TXTYPE_MON_EVENT_OPERATION_LOG = 3 [(TxTypeOpts) = {Name: "TTxMonEvent_OperationLog"}];
+ TXTYPE_MON_EVENT_SET_DOWN = 4 [(TxTypeOpts) = {Name: "TTxMonEvent_SetDown"}];
+ TXTYPE_MON_EVENT_GET_DOWN = 5 [(TxTypeOpts) = {Name: "TTxMonEvent_GetDown"}];
+ TXTYPE_UPDATE_DISK_METRICS = 6 [(TxTypeOpts) = {Name: "TTxUpdateDiskMetrics"}];
+ TXTYPE_UPDATE_GROUP_LATENCIES = 7 [(TxTypeOpts) = {Name: "TTxUpdateGroupLatencies"}];
+ TXTYPE_GROUP_RECONFIGURE_WIPE = 8 [(TxTypeOpts) = {Name: "TTxGroupReconfigureWipe"}];
+ TXTYPE_NODE_REPORT = 9 [(TxTypeOpts) = {Name: "TTxNodeReport"}];
+ TXTYPE_UPDATE_SEEN_OPERATIONAL = 10 [(TxTypeOpts) = {Name: "TTxUpdateSeenOperational"}];
+ TXTYPE_CONFIG_CMD = 11 [(TxTypeOpts) = {Name: "TTxConfigCmd"}];
+ TXTYPE_PROPOSE_GROUP_KEY = 12 [(TxTypeOpts) = {Name: "TTxProposeGroupKey"}];
+ TXTYPE_REGISTER_NODE = 13 [(TxTypeOpts) = {Name: "TTxRegisterNode"}];
+ TXTYPE_GET_GROUP = 14 [(TxTypeOpts) = {Name: "TTxGetGroup"}];
+ TXTYPE_REQUEST_CONTROLLER_INFO = 15 [(TxTypeOpts) = {Name: "TTxRequestControllerInfo"}];
+ TXTYPE_SELECT_GROUPS = 16 [(TxTypeOpts) = {Name: "TTxSelectGroups"}];
+ TXTYPE_MON_EVENT_HEALTH_EVENTS = 17 [(TxTypeOpts) = {Name: "TTxMonEvent_HealthEvents"}];
+ TXTYPE_DROP_DONOR = 18 [(TxTypeOpts) = {Name: "TTxDropDonor"}];
+ TXTYPE_SCRUB_START = 19 [(TxTypeOpts) = {Name: "TTxScrubStart"}];
+ TXTYPE_SCRUB_QUANTUM_FINISHED = 20 [(TxTypeOpts) = {Name: "TTxScrubQuantumFinished"}];
+ TXTYPE_UPDATE_LAST_SEEN_READY = 21 [(TxTypeOpts) = {Name: "TTxUpdateLastSeenReady"}];
TXTYPE_UPDATE_NODE_DRIVES = 22 [(TxTypeOpts) = {Name: "TTxUpdateNodeDrives"}];
}
diff --git a/ydb/core/protos/counters_testshard.proto b/ydb/core/protos/counters_testshard.proto
index 9940b5b84fa..f716fdce2d6 100644
--- a/ydb/core/protos/counters_testshard.proto
+++ b/ydb/core/protos/counters_testshard.proto
@@ -1,21 +1,21 @@
-import "ydb/core/protos/counters.proto";
-
-package NKikimr.NTestShard;
-
-option java_package = "ru.yandex.kikimr.proto";
-
-option (TabletTypeName) = "TestShard";
-
-enum ECumulativeCounters {
- COUNTER_CUMULATIVE_IGNORE = 0;
-}
-
-enum ESimpleCounters {
- COUNTER_MODE_WRITE = 0 [(CounterOpts) = {Name: "ModeWrite"}];
- COUNTER_MODE_READ_VALIDATE = 1 [(CounterOpts) = {Name: "ModeReadValidate"}];
- COUNTER_MODE_STATE_SERVER_CONNECT = 2 [(CounterOpts) = {Name: "StateServerConnect"}];
-}
-
-enum EPercentileCounters {
- COUNTER_PERCENTILE_IGNORE = 0;
-}
+import "ydb/core/protos/counters.proto";
+
+package NKikimr.NTestShard;
+
+option java_package = "ru.yandex.kikimr.proto";
+
+option (TabletTypeName) = "TestShard";
+
+enum ECumulativeCounters {
+ COUNTER_CUMULATIVE_IGNORE = 0;
+}
+
+enum ESimpleCounters {
+ COUNTER_MODE_WRITE = 0 [(CounterOpts) = {Name: "ModeWrite"}];
+ COUNTER_MODE_READ_VALIDATE = 1 [(CounterOpts) = {Name: "ModeReadValidate"}];
+ COUNTER_MODE_STATE_SERVER_CONNECT = 2 [(CounterOpts) = {Name: "StateServerConnect"}];
+}
+
+enum EPercentileCounters {
+ COUNTER_PERCENTILE_IGNORE = 0;
+}
diff --git a/ydb/core/protos/follower_group.proto b/ydb/core/protos/follower_group.proto
index d374752bcde..e678e2e0b69 100644
--- a/ydb/core/protos/follower_group.proto
+++ b/ydb/core/protos/follower_group.proto
@@ -6,10 +6,10 @@ message TFollowerGroup {
optional bool AllowLeaderPromotion = 2;
optional bool AllowClientRead = 3;
repeated uint32 AllowedNodeIDs = 4;
- repeated uint32 AllowedDataCenterNumIDs = 5 [deprecated=true]; // use AllowedDataCenters
+ repeated uint32 AllowedDataCenterNumIDs = 5 [deprecated=true]; // use AllowedDataCenters
optional bool RequireAllDataCenters = 6;
optional bool LocalNodeOnly = 7;
optional bool RequireDifferentNodes = 8;
optional bool FollowerCountPerDataCenter = 9; // multiplies FollowerCount by number of DataCenters
- repeated string AllowedDataCenters = 10;
+ repeated string AllowedDataCenters = 10;
}
diff --git a/ydb/core/protos/grpc.proto b/ydb/core/protos/grpc.proto
index 797cc2de829..e66d3f08bd1 100644
--- a/ydb/core/protos/grpc.proto
+++ b/ydb/core/protos/grpc.proto
@@ -1,12 +1,12 @@
syntax = "proto3";
-package NKikimrClient;
+package NKikimrClient;
import "ydb/core/protos/msgbus.proto";
import "ydb/core/protos/msgbus_kv.proto";
import "ydb/core/protos/msgbus_pq.proto";
-service TGRpcServer {
+service TGRpcServer {
// TODO
// * Rename Request to MiniKQLRequest ???
@@ -17,14 +17,14 @@ service TGRpcServer {
/////////////////////////////////////////////////////////////////////////////////////////////////
// MiniKQL request (DML)
- rpc Request(TRequest) returns (TResponse);
+ rpc Request(TRequest) returns (TResponse);
// DML transactions
- rpc SchemeOperation(TSchemeOperation) returns (TResponse);
+ rpc SchemeOperation(TSchemeOperation) returns (TResponse);
// status polling for scheme transactions
- rpc SchemeOperationStatus(TSchemeOperationStatus) returns (TResponse);
+ rpc SchemeOperationStatus(TSchemeOperationStatus) returns (TResponse);
// describe
- rpc SchemeDescribe(TSchemeDescribe) returns (TResponse);
+ rpc SchemeDescribe(TSchemeDescribe) returns (TResponse);
// whoami
rpc WhoAmI(TWhoAmI) returns (TResponse);
@@ -37,28 +37,28 @@ service TGRpcServer {
// PERSISTENT QUEUE CLIENT INTERFACE
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc PersQueueRequest(TPersQueueRequest) returns (TResponse);
-
+ rpc PersQueueRequest(TPersQueueRequest) returns (TResponse);
+
/////////////////////////////////////////////////////////////////////////////////////////////////
// ADMIN INTERNAL INTERFACE
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc SchemeInitRoot(TSchemeInitRoot) returns (TResponse);
- rpc BSAdm(TBSAdm) returns (TResponse);
+ rpc SchemeInitRoot(TSchemeInitRoot) returns (TResponse);
+ rpc BSAdm(TBSAdm) returns (TResponse);
rpc ResolveNode(TResolveNodeRequest) returns (TResponse);
rpc FillNode(TFillNodeRequest) returns (TResponse);
rpc DrainNode(TDrainNodeRequest) returns (TResponse);
- // Blob storage configuration manipulation/query interface
- rpc BlobStorageConfig(TBlobStorageConfigRequest) returns (TResponse);
-
+ // Blob storage configuration manipulation/query interface
+ rpc BlobStorageConfig(TBlobStorageConfigRequest) returns (TResponse);
+
/////////////////////////////////////////////////////////////////////////////////////////////////
// KV-TABLET INTERNAL INTERFACE
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc HiveCreateTablet(THiveCreateTablet) returns (TResponse);
- rpc LocalEnumerateTablets(TLocalEnumerateTablets) returns (TResponse);
- rpc KeyValue(TKeyValueRequest) returns (TResponse);
- rpc TestShardControl(TTestShardControlRequest) returns (TResponse);
+ rpc HiveCreateTablet(THiveCreateTablet) returns (TResponse);
+ rpc LocalEnumerateTablets(TLocalEnumerateTablets) returns (TResponse);
+ rpc KeyValue(TKeyValueRequest) returns (TResponse);
+ rpc TestShardControl(TTestShardControlRequest) returns (TResponse);
/////////////////////////////////////////////////////////////////////////////////////////////////
// DYNAMIC NODES INTERNAL INTERFACE
@@ -88,29 +88,29 @@ service TGRpcServer {
/////////////////////////////////////////////////////////////////////////////////////////////////
// INTROSPECTION
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc LocalMKQL(TLocalMKQL) returns (TResponse);
- rpc LocalSchemeTx(TLocalSchemeTx) returns (TResponse);
- rpc TabletKillRequest(TTabletKillRequest) returns (TResponse);
- rpc InterconnectDebug(TInterconnectDebug) returns (TResponse);
+ rpc LocalMKQL(TLocalMKQL) returns (TResponse);
+ rpc LocalSchemeTx(TLocalSchemeTx) returns (TResponse);
+ rpc TabletKillRequest(TTabletKillRequest) returns (TResponse);
+ rpc InterconnectDebug(TInterconnectDebug) returns (TResponse);
// [DEPRECATED]
//rpc Navigate(TSchemeNavigate) returns (TResponse);
-
+
/////////////////////////////////////////////////////////////////////////////////////////////////
// MONITORING
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc TabletStateRequest(TTabletStateRequest) returns (TResponse);
+ rpc TabletStateRequest(TTabletStateRequest) returns (TResponse);
/////////////////////////////////////////////////////////////////////////////////////////////////
// BLOBSTORAGE LOAD TEST
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc BlobStorageLoadRequest(TBsTestLoadRequest) returns (TResponse);
- rpc BlobStorageGetRequest(TBsGetRequest) returns (TResponse);
+ rpc BlobStorageLoadRequest(TBsTestLoadRequest) returns (TResponse);
+ rpc BlobStorageGetRequest(TBsGetRequest) returns (TResponse);
/////////////////////////////////////////////////////////////////////////////////////////////////
// HTTP INTERFACE
/////////////////////////////////////////////////////////////////////////////////////////////////
- rpc DbSchema(TJSON) returns (TJSON);
- rpc DbOperation(TJSON) returns (TJSON);
- rpc DbBatch(TJSON) returns (TJSON);
+ rpc DbSchema(TJSON) returns (TJSON);
+ rpc DbOperation(TJSON) returns (TJSON);
+ rpc DbBatch(TJSON) returns (TJSON);
}
diff --git a/ydb/core/protos/hive.proto b/ydb/core/protos/hive.proto
index 0059db81de8..9d7de76409c 100644
--- a/ydb/core/protos/hive.proto
+++ b/ydb/core/protos/hive.proto
@@ -70,8 +70,8 @@ message TTabletCategory {
}
message TDataCentersGroup {
- repeated uint64 DataCenterNum = 1 [deprecated=true]; // array of DC IDs preffered to run the tablet; obsolete
- repeated string DataCenter = 2;
+ repeated uint64 DataCenterNum = 1 [deprecated=true]; // array of DC IDs preffered to run the tablet; obsolete
+ repeated string DataCenter = 2;
}
message TDataCentersPreference {
@@ -84,7 +84,7 @@ message TEvCreateTablet {
optional NKikimrTabletBase.TTabletTypes.EType TabletType = 3;
optional uint32 AssignStateStorage = 4;
repeated uint32 AllowedNodeIDs = 7;
- repeated uint64 AllowedDataCenterNumIDs = 14 [deprecated=true]; // array of DC IDs allowed to run the tablet; obsolete; use AllowedDataCenters instead
+ repeated uint64 AllowedDataCenterNumIDs = 14 [deprecated=true]; // array of DC IDs allowed to run the tablet; obsolete; use AllowedDataCenters instead
optional TTabletCategory TabletCategory = 16;
repeated TFollowerGroup FollowerGroups = 17;
optional NKikimrSubDomains.TDomainKey ObjectDomain = 18;
@@ -94,7 +94,7 @@ message TEvCreateTablet {
optional fixed64 TabletID = 22;
repeated NKikimrSubDomains.TDomainKey AllowedDomains = 23;
optional TDataCentersPreference DataCentersPreference = 24;
- repeated string AllowedDataCenters = 25;
+ repeated string AllowedDataCenters = 25;
optional uint32 ChannelsProfile = 5 [deprecated = true]; // DEPRECATED
optional uint32 Flags = 6 [deprecated = true]; // DEPRECATED
diff --git a/ydb/core/protos/kqp.proto b/ydb/core/protos/kqp.proto
index 9b46b720e11..41d20cab5ba 100644
--- a/ydb/core/protos/kqp.proto
+++ b/ydb/core/protos/kqp.proto
@@ -400,9 +400,9 @@ message TEvExecuterProgress {
message TKqpProxyNodeResources {
optional uint32 NodeId = 1;
- optional uint64 DataCenterNumId = 2;
+ optional uint64 DataCenterNumId = 2;
optional uint32 ActiveWorkersCount = 3;
- optional string DataCenterId = 4;
+ optional string DataCenterId = 4;
optional double CpuUsage = 5;
optional uint32 Threads = 6;
}
diff --git a/ydb/core/protos/local.proto b/ydb/core/protos/local.proto
index a385a3cf3e1..8ea973e10ea 100644
--- a/ydb/core/protos/local.proto
+++ b/ydb/core/protos/local.proto
@@ -16,7 +16,7 @@ message TTabletAvailability {
message TEvRegisterNode {
optional fixed64 HiveId = 1;
repeated NKikimrSubDomains.TDomainKey ServicedDomains = 2;
- optional NActorsInterconnect.TNodeLocation SystemLocation = 3;
+ optional NActorsInterconnect.TNodeLocation SystemLocation = 3;
repeated TTabletAvailability TabletAvailability = 4;
}
diff --git a/ydb/core/protos/msgbus.proto b/ydb/core/protos/msgbus.proto
index df7cda59800..c4169d3744a 100644
--- a/ydb/core/protos/msgbus.proto
+++ b/ydb/core/protos/msgbus.proto
@@ -29,7 +29,7 @@ import "ydb/library/mkql_proto/protos/minikql.proto";
import "google/protobuf/descriptor.proto";
-package NKikimrClient;
+package NKikimrClient;
option java_package = "ru.yandex.kikimr.proto";
message TEnumValueHint {
@@ -180,11 +180,11 @@ message TResponse {
// TTabletStateRequest
repeated NKikimrWhiteboard.TTabletStateInfo TabletStateInfo = 500;
- // TSchemeDescribe
+ // TSchemeDescribe
optional NKikimrSchemeOp.TPathDescription PathDescription = 600;
optional string Path = 601;
- // TSchemeOperation
+ // TSchemeOperation
optional TFlatTxId FlatTxId = 700;
// TPersQueueRequest
@@ -204,7 +204,7 @@ message TResponse {
repeated TKeyValueResponse.TCopyRangeResult CopyRangeResult = 907;
repeated TKeyValueResponse.TConcatResult ConcatResult = 908;
repeated TKeyValueResponse.TGetStatusResult GetStatusResult = 909;
- optional TKeyValueResponse.TTrimLeakedBlobsResult TrimLeakedBlobsResult = 910;
+ optional TKeyValueResponse.TTrimLeakedBlobsResult TrimLeakedBlobsResult = 910;
optional TKeyValueResponse.TSetExecutorFastLogPolicyResult SetExecutorFastLogPolicyResult = 911;
// THiveCreateTablet
@@ -233,8 +233,8 @@ message TResponse {
// TTabletCountersRequest
optional NKikimrTabletBase.TTabletCounters TabletCounters = 1020;
-
- // TBlobStorageConfigRequest
+
+ // TBlobStorageConfigRequest
optional NKikimrBlobStorage.TConfigResponse BlobStorageConfigResponse = 1030;
optional TResolveNodeResponse ResolveNodeResponse = 1040;
@@ -428,14 +428,14 @@ message TFlatTxPollOptions {
optional uint32 Timeout = 1 [default = 1000]; // ms
};
-message TSchemeOperation {
+message TSchemeOperation {
optional NKikimrTxUserProxy.TTransaction Transaction = 1;
optional TFlatTxPollOptions PollOptions = 10;
optional string SecurityToken = 5;
};
-message TSchemeDescribe {
+message TSchemeDescribe {
optional string Path = 1;
optional uint64 PathId = 2;
optional uint64 SchemeshardId = 3;
@@ -456,38 +456,38 @@ message TFlatDescribeResponse {
repeated Ydb.Issue.IssueMessage Issues = 8;
};
-message TSchemeOperationStatus {
+message TSchemeOperationStatus {
optional TFlatTxId FlatTxId = 1;
optional TFlatTxPollOptions PollOptions = 10;
};
-
-message TBsTestLoadRequest {
- repeated uint32 NodeId = 1;
- optional NKikimrBlobStorage.TEvTestLoadRequest Event = 2;
-};
-
-message TBsTestLoadResponse {
- message TItem {
- optional uint32 NodeId = 1;
- optional uint32 Status = 2;
- optional string ErrorReason = 3;
- };
- repeated TItem Items = 1;
-};
-
-message TBsGetRequest {
- optional uint32 GroupId = 1;
- oneof Query {
- NKikimrProto.TLogoBlobID Extreme = 2;
- };
-};
-
-message TBsGetResponse {
- optional NKikimrProto.EReplyStatus Status = 1;
- optional bytes Buffer = 2;
- optional string ErrorDescription = 3;
-};
-
+
+message TBsTestLoadRequest {
+ repeated uint32 NodeId = 1;
+ optional NKikimrBlobStorage.TEvTestLoadRequest Event = 2;
+};
+
+message TBsTestLoadResponse {
+ message TItem {
+ optional uint32 NodeId = 1;
+ optional uint32 Status = 2;
+ optional string ErrorReason = 3;
+ };
+ repeated TItem Items = 1;
+};
+
+message TBsGetRequest {
+ optional uint32 GroupId = 1;
+ oneof Query {
+ NKikimrProto.TLogoBlobID Extreme = 2;
+ };
+};
+
+message TBsGetResponse {
+ optional NKikimrProto.EReplyStatus Status = 1;
+ optional bytes Buffer = 2;
+ optional string ErrorDescription = 3;
+};
+
message TJsonSettings {
optional bool UI64AsString = 1 [default = false];
};
@@ -499,8 +499,8 @@ message TJSON {
};
message TChooseProxyRequest {
- optional uint32 DataCenterNum = 1;
- optional string DataCenter = 3;
+ optional uint32 DataCenterNum = 1;
+ optional string DataCenter = 3;
optional bool PreferLocalProxy = 2 [default = false];
}
@@ -509,11 +509,11 @@ message TWhoAmI {
optional string SecurityToken = 5;
}
-message TBlobStorageConfigRequest {
- optional uint32 Domain = 1;
+message TBlobStorageConfigRequest {
+ optional uint32 Domain = 1;
optional NKikimrBlobStorage.TConfigRequest Request = 2;
- optional string SecurityToken = 3;
-}
+ optional string SecurityToken = 3;
+}
message TDrainNodeRequest {
optional uint32 NodeID = 1;
@@ -536,10 +536,10 @@ message TNodeRegistrationRequest {
optional uint32 Port = 2;
optional string ResolveHost = 3;
optional string Address = 4;
- optional NActorsInterconnect.TNodeLocation Location = 5;
+ optional NActorsInterconnect.TNodeLocation Location = 5;
optional string DomainPath = 6;
optional bool FixedNodeId = 7;
- optional string Path = 8;
+ optional string Path = 8;
}
message TNodeRegistrationResponse {
@@ -548,8 +548,8 @@ message TNodeRegistrationResponse {
optional string DomainPath = 3;
optional uint64 Expire = 4;
repeated NKikimrNodeBroker.TNodeInfo Nodes = 5;
- optional uint64 ScopeTabletId = 6;
- optional uint64 ScopePathId = 7;
+ optional uint64 ScopeTabletId = 6;
+ optional uint64 ScopePathId = 7;
}
message TCmsRequest {
@@ -673,32 +673,32 @@ message TS3ListingResponse {
optional uint32 KeySuffixSize = 4; // Number of key columns starting from path and up to the end
optional uint32 ErrorCode = 5; // Extended error code from NTXProxy::TResultStatus::EStatus enum
}
-
-message TInterconnectDebug {
- optional string Name = 1;
- optional uint32 Channel = 2;
- repeated uint32 Hops = 3;
- optional uint32 SizeMin = 4;
- optional uint32 SizeMax = 5;
- optional uint32 InFlyMax = 6;
- optional uint64 IntervalMin = 7;
- optional uint64 IntervalMax = 8;
- optional bool SoftLoad = 9;
- optional uint64 Duration = 10;
- optional bool UseProtobufWithPayload = 11;
- optional string ServicePool = 12;
-
- optional uint32 ClosePeerSocketNodeId = 100;
- optional uint32 CloseInputSessionNodeId = 101;
- optional uint32 PoisonSessionNodeId = 102;
-
- optional uint32 NumSlowpokeActors = 200;
- optional uint32 PoolId = 201;
- optional uint64 SleepMin = 202;
- optional uint64 SleepMax = 203;
- optional uint64 RescheduleMin = 204;
- optional uint64 RescheduleMax = 205;
-}
+
+message TInterconnectDebug {
+ optional string Name = 1;
+ optional uint32 Channel = 2;
+ repeated uint32 Hops = 3;
+ optional uint32 SizeMin = 4;
+ optional uint32 SizeMax = 5;
+ optional uint32 InFlyMax = 6;
+ optional uint64 IntervalMin = 7;
+ optional uint64 IntervalMax = 8;
+ optional bool SoftLoad = 9;
+ optional uint64 Duration = 10;
+ optional bool UseProtobufWithPayload = 11;
+ optional string ServicePool = 12;
+
+ optional uint32 ClosePeerSocketNodeId = 100;
+ optional uint32 CloseInputSessionNodeId = 101;
+ optional uint32 PoisonSessionNodeId = 102;
+
+ optional uint32 NumSlowpokeActors = 200;
+ optional uint32 PoolId = 201;
+ optional uint64 SleepMin = 202;
+ optional uint64 SleepMax = 203;
+ optional uint64 RescheduleMin = 204;
+ optional uint64 RescheduleMax = 205;
+}
message TConsoleRequest {
oneof Request {
@@ -743,33 +743,33 @@ message TConsoleResponse {
optional NKikimrConsole.TStatus Status = 100;
}
-message TTestShardControlRequest {
- message TSizeInterval {
- optional uint64 Weight = 1; // nonzero
- optional uint32 Min = 2;
- optional uint32 Max = 3;
- optional bool Inline = 4; // if true, then keys are stored as inline values of KV tablet rows
- }
- message TTimeInterval { // Poisson distribution of events
- optional uint64 Weight = 1; // nonzero
- optional double Frequency = 2; // events per second
- optional uint32 MaxIntervalMs = 3; // max interval between two events in milliseconds
- }
- message TCmdInitialize {
- optional string StorageServerHost = 1; // location of storage server containing tablet actual state
- optional int32 StorageServerPort = 2; // part of storage server location
- optional uint64 MaxDataBytes = 3; // when total length of stored keys reaches MaxDataBytes...
- optional uint64 MinDataBytes = 4; // then random keys are collected until total length drops below MinDataBytes
- optional uint32 MaxInFlight = 5;
- repeated TSizeInterval Sizes = 6; // distrubution of generated value size
- repeated TTimeInterval WritePeriods = 7; // time between two events
- }
-
- optional uint64 TabletId = 1;
- oneof Command {
- TCmdInitialize Initialize = 2;
- }
-}
-
-message TTestShardControlResponse {
-}
+message TTestShardControlRequest {
+ message TSizeInterval {
+ optional uint64 Weight = 1; // nonzero
+ optional uint32 Min = 2;
+ optional uint32 Max = 3;
+ optional bool Inline = 4; // if true, then keys are stored as inline values of KV tablet rows
+ }
+ message TTimeInterval { // Poisson distribution of events
+ optional uint64 Weight = 1; // nonzero
+ optional double Frequency = 2; // events per second
+ optional uint32 MaxIntervalMs = 3; // max interval between two events in milliseconds
+ }
+ message TCmdInitialize {
+ optional string StorageServerHost = 1; // location of storage server containing tablet actual state
+ optional int32 StorageServerPort = 2; // part of storage server location
+ optional uint64 MaxDataBytes = 3; // when total length of stored keys reaches MaxDataBytes...
+ optional uint64 MinDataBytes = 4; // then random keys are collected until total length drops below MinDataBytes
+ optional uint32 MaxInFlight = 5;
+ repeated TSizeInterval Sizes = 6; // distrubution of generated value size
+ repeated TTimeInterval WritePeriods = 7; // time between two events
+ }
+
+ optional uint64 TabletId = 1;
+ oneof Command {
+ TCmdInitialize Initialize = 2;
+ }
+}
+
+message TTestShardControlResponse {
+}
diff --git a/ydb/core/protos/msgbus_health.proto b/ydb/core/protos/msgbus_health.proto
index d0078190638..f9c4123349e 100644
--- a/ydb/core/protos/msgbus_health.proto
+++ b/ydb/core/protos/msgbus_health.proto
@@ -1,4 +1,4 @@
-package NKikimrClient;
+package NKikimrClient;
option java_package = "ru.yandex.kikimr.proto";
message THealthRequest {
diff --git a/ydb/core/protos/msgbus_kv.proto b/ydb/core/protos/msgbus_kv.proto
index 87c65e51764..a3213f55533 100644
--- a/ydb/core/protos/msgbus_kv.proto
+++ b/ydb/core/protos/msgbus_kv.proto
@@ -1,4 +1,4 @@
-package NKikimrClient;
+package NKikimrClient;
option java_package = "ru.yandex.kikimr.proto";
@@ -57,7 +57,7 @@ message TKeyValueRequest {
optional EPriority Priority = 4; // (default = REALTIME)
optional bytes KeyToCache = 5; // used in PQ
optional ETactic Tactic = 6 [default = MAX_THROUGHPUT]; // mandatory, used for non-inline puts only
- repeated EStorageChannel AutoselectChannel = 7; // when filled, channel is selected automatically from this set
+ repeated EStorageChannel AutoselectChannel = 7; // when filled, channel is selected automatically from this set
}
message TCmdRename {
optional bytes OldKey = 1; // mandatory
@@ -76,9 +76,9 @@ message TKeyValueRequest {
message TCmdGetStatus {
optional EStorageChannel StorageChannel = 1; // (default = MAIN)
}
- message TCmdTrimLeakedBlobs {
- optional uint32 MaxItemsToTrim = 1;
- }
+ message TCmdTrimLeakedBlobs {
+ optional uint32 MaxItemsToTrim = 1;
+ }
message TCmdSetExecutorFastLogPolicy {
optional bool IsAllowed = 1 [default = false]; // mandatory
}
@@ -95,7 +95,7 @@ message TKeyValueRequest {
repeated TCmdCopyRange CmdCopyRange = 11;
repeated TCmdConcat CmdConcat = 12;
repeated TCmdGetStatus CmdGetStatus = 13;
- optional TCmdTrimLeakedBlobs CmdTrimLeakedBlobs = 14;
+ optional TCmdTrimLeakedBlobs CmdTrimLeakedBlobs = 14;
optional TCmdSetExecutorFastLogPolicy CmdSetExecutorFastLogPolicy = 15;
optional uint64 DeadlineInstantMs = 10;
@@ -150,11 +150,11 @@ message TKeyValueResponse {
optional TKeyValueRequest.EStorageChannel StorageChannel = 2;
optional uint32 StatusFlags = 3; // A set of flags from EStatusFlags ydb/core/protos/blobstorage.proto
}
- message TTrimLeakedBlobsResult {
+ message TTrimLeakedBlobsResult {
optional uint32 Status = 1; // EReplyStatus from ydb/core/protos/base.proto
- optional uint32 NumItemsTrimmed = 2;
- optional uint32 NumItemsLeft = 3;
- }
+ optional uint32 NumItemsTrimmed = 2;
+ optional uint32 NumItemsLeft = 3;
+ }
message TSetExecutorFastLogPolicyResult {
optional uint32 Status = 1; // EReplyStatus from ydb/core/protos/base.proto
}
@@ -169,7 +169,7 @@ message TKeyValueResponse {
repeated TCopyRangeResult CopyRangeResult = 10;
repeated TConcatResult ConcatResult = 11;
repeated TGetStatusResult GetStatusResult = 12;
- optional TTrimLeakedBlobsResult TrimLeakedBlobsResult = 13;
+ optional TTrimLeakedBlobsResult TrimLeakedBlobsResult = 13;
optional TSetExecutorFastLogPolicyResult SetExecutorFastLogPolicyResult = 14;
optional string ErrorReason = 9; // When present contains human-readable error description
}
diff --git a/ydb/core/protos/msgbus_pq.proto b/ydb/core/protos/msgbus_pq.proto
index 849b292383a..b4c779b91cb 100644
--- a/ydb/core/protos/msgbus_pq.proto
+++ b/ydb/core/protos/msgbus_pq.proto
@@ -2,7 +2,7 @@ import "ydb/core/protos/pqconfig.proto";
import "ydb/public/api/protos/draft/persqueue_error_codes.proto";
import "library/cpp/actors/protos/actors.proto";
-package NKikimrClient;
+package NKikimrClient;
option java_package = "ru.yandex.kikimr.proto";
diff --git a/ydb/core/protos/node_broker.proto b/ydb/core/protos/node_broker.proto
index ee0908902c6..43170258266 100644
--- a/ydb/core/protos/node_broker.proto
+++ b/ydb/core/protos/node_broker.proto
@@ -18,7 +18,7 @@ message TNodeInfo {
optional uint32 Port = 3;
optional string ResolveHost = 4;
optional string Address = 5;
- optional NActorsInterconnect.TNodeLocation Location = 6;
+ optional NActorsInterconnect.TNodeLocation Location = 6;
optional uint64 Expire = 7;
}
@@ -64,16 +64,16 @@ message TRegistrationRequest {
optional uint32 Port = 2;
optional string ResolveHost = 3;
optional string Address = 4;
- optional NActorsInterconnect.TNodeLocation Location = 5;
+ optional NActorsInterconnect.TNodeLocation Location = 5;
optional bool FixedNodeId = 6;
- optional string Path = 7;
+ optional string Path = 7;
}
message TRegistrationResponse {
optional TStatus Status = 1;
optional TNodeInfo Node = 2;
- optional uint64 ScopeTabletId = 3;
- optional uint64 ScopePathId = 4;
+ optional uint64 ScopeTabletId = 3;
+ optional uint64 ScopePathId = 4;
}
message TExtendLeaseRequest {
diff --git a/ydb/core/protos/node_whiteboard.proto b/ydb/core/protos/node_whiteboard.proto
index b96713ca298..57aa2597855 100644
--- a/ydb/core/protos/node_whiteboard.proto
+++ b/ydb/core/protos/node_whiteboard.proto
@@ -105,7 +105,7 @@ message TPDiskStateInfo {
optional uint64 Category = 6;
optional uint64 AvailableSize = 7 [(InsignificantChangeAmount) = 104857600]; // 100Mb
optional uint64 TotalSize = 8;
- optional NKikimrBlobStorage.TPDiskState.E State = 9;
+ optional NKikimrBlobStorage.TPDiskState.E State = 9;
optional uint32 NodeId = 10; // filled during merge
optional uint32 Count = 13; // filled during group count
optional EFlag Device = 14;
@@ -176,32 +176,32 @@ message TVDiskStateInfo {
optional TVDiskSatisfactionRank SatisfactionRank = 13;
// Is VDisk replicated? (i.e. contains all blobs it must have)
optional bool Replicated = 14;
- // Does this VDisk has any yet unreplicated phantom-like blobs?
- optional bool UnreplicatedPhantoms = 20 [default = false];
- // The same for the non-phantom-like blobs.
- optional bool UnreplicatedNonPhantoms = 21 [default = false];
+ // Does this VDisk has any yet unreplicated phantom-like blobs?
+ optional bool UnreplicatedPhantoms = 20 [default = false];
+ // The same for the non-phantom-like blobs.
+ optional bool UnreplicatedNonPhantoms = 21 [default = false];
// How many unsynced VDisks from current BlobStorage group we see
- optional uint64 UnsyncedVDisks = 15 [default = 0];
+ optional uint64 UnsyncedVDisks = 15 [default = 0];
// How much this VDisk have allocated on corresponding PDisk
optional uint64 AllocatedSize = 16 [(InsignificantChangeAmount) = 536870912]; // 512MiB
// How much space is available for VDisk corresponding to PDisk's hard space limits
optional uint64 AvailableSize = 28 [(InsignificantChangeAmount) = 536870912]; // 512MiB
- // Does this disk has some unreadable but not yet restored blobs?
- optional bool HasUnreadableBlobs = 24;
- optional fixed64 IncarnationGuid = 25;
- optional bool DonorMode = 26;
- optional fixed64 InstanceGuid = 27; // VDisk actor instance guid
+ // Does this disk has some unreadable but not yet restored blobs?
+ optional bool HasUnreadableBlobs = 24;
+ optional fixed64 IncarnationGuid = 25;
+ optional bool DonorMode = 26;
+ optional fixed64 InstanceGuid = 27; // VDisk actor instance guid
// VDisk (Skeleton) Front Queue Status
optional EFlag FrontQueues = 18;
-
- // VDisk storage pool label
- optional string StoragePoolName = 19;
-
- // Read bytes per second from PDisk for TEvVGet blobs only
- optional uint64 ReadThroughput = 22;
- // Write bytes per second to PDisk for TEvVPut blobs and replication bytes only
- optional uint64 WriteThroughput = 23;
+
+ // VDisk storage pool label
+ optional string StoragePoolName = 19;
+
+ // Read bytes per second from PDisk for TEvVGet blobs only
+ optional uint64 ReadThroughput = 22;
+ // Write bytes per second to PDisk for TEvVPut blobs and replication bytes only
+ optional uint64 WriteThroughput = 23;
}
message TEvVDiskStateRequest {
@@ -224,7 +224,7 @@ message TBSGroupStateInfo {
optional EFlag Overall = 7;
optional EFlag Latency = 8;
optional uint32 Count = 13; // filled during group count
- optional string StoragePoolName = 14; // from BS_CONTROLLER
+ optional string StoragePoolName = 14; // from BS_CONTROLLER
}
message TEvBSGroupStateRequest {
@@ -243,27 +243,27 @@ enum EConfigState {
}
message TSystemStateInfo {
- message TPoolStats {
- optional string Name = 1;
+ message TPoolStats {
+ optional string Name = 1;
optional double Usage = 2 [(InsignificantChangePercent) = 30];
optional uint32 Threads = 3;
- }
-
+ }
+
message TEndpoint {
optional string Name = 1;
optional string Address = 2;
}
- message TLegacyNodeLocation {
- optional uint32 DataCenter = 1;
- optional uint32 Room = 2;
- optional uint32 Rack = 3;
- optional uint32 Body = 4;
- }
-
+ message TLegacyNodeLocation {
+ optional uint32 DataCenter = 1;
+ optional uint32 Room = 2;
+ optional uint32 Rack = 3;
+ optional uint32 Body = 4;
+ }
+
optional uint64 StartTime = 1;
optional uint64 ChangeTime = 2;
- optional TLegacyNodeLocation SystemLocation = 3;
+ optional TLegacyNodeLocation SystemLocation = 3;
repeated double LoadAverage = 4;
optional uint32 NumberOfCpus = 5;
optional EFlag SystemState = 6;
@@ -278,7 +278,7 @@ message TSystemStateInfo {
optional string Rack = 18;
optional string Host = 19;
optional string Version = 20;
- repeated TPoolStats PoolStats = 21;
+ repeated TPoolStats PoolStats = 21;
repeated TEndpoint Endpoints = 22;
repeated string Roles = 23;
repeated string Tenants = 24;
@@ -288,7 +288,7 @@ message TSystemStateInfo {
optional EConfigState ConfigState = 28 [default = Consistent];
optional uint64 MemoryUsedInAlloc = 29;
optional double MaxDiskUsage = 30;
- optional NActorsInterconnect.TNodeLocation Location = 31;
+ optional NActorsInterconnect.TNodeLocation Location = 31;
}
message TEvSystemStateRequest {
diff --git a/ydb/core/protos/out/out.cpp b/ydb/core/protos/out/out.cpp
index 28c49a5c363..25db40af8b6 100644
--- a/ydb/core/protos/out/out.cpp
+++ b/ydb/core/protos/out/out.cpp
@@ -141,8 +141,8 @@ Y_DECLARE_OUT_SPEC(, NKikimrTxDataShard::EDatashardState, stream, value) {
stream << NKikimrTxDataShard::EDatashardState_Name(value);
}
-Y_DECLARE_OUT_SPEC(, NKikimrBlobStorage::TPDiskState::E, stream, value) {
- stream << NKikimrBlobStorage::TPDiskState::E_Name(value);
+Y_DECLARE_OUT_SPEC(, NKikimrBlobStorage::TPDiskState::E, stream, value) {
+ stream << NKikimrBlobStorage::TPDiskState::E_Name(value);
}
Y_DECLARE_OUT_SPEC(, NKikimrBlobStorage::TPDiskSpaceColor::E, stream, value) {
diff --git a/ydb/core/protos/pdiskfit.proto b/ydb/core/protos/pdiskfit.proto
index 3b46d6c8ed3..b46921bf023 100644
--- a/ydb/core/protos/pdiskfit.proto
+++ b/ydb/core/protos/pdiskfit.proto
@@ -1,41 +1,41 @@
-package NPDiskFIT;
-
-message TFakeVDiskState {
- message TLogItem {
- optional uint64 Lsn = 1;
- optional uint32 Signature = 2;
- optional uint32 DataLen = 3;
- optional uint32 Checksum = 4;
- repeated uint32 CommitChunks = 5;
- repeated uint32 DeleteChunks = 6;
- };
- message TChunk {
- message TBlock {
- optional uint32 Index = 1;
- optional uint32 Checksum = 2;
- };
- optional uint32 ChunkIdx = 1;
- repeated TBlock Blocks = 2;
- optional uint32 CommitState = 3;
- };
- message TWriteRecord {
- optional uint32 ChunkIdx = 1;
- optional uint32 OffsetInBlocks = 2;
- optional uint32 SizeInBlocks = 3;
- repeated uint32 Checksums = 4;
- };
- repeated TLogItem LogItems = 1;
- repeated TLogItem InFlightItems = 2;
- optional uint64 FirstLsnToKeep = 3;
- optional uint32 BlocksInChunk = 4;
- repeated TChunk Chunks = 5;
- repeated TWriteRecord WritesInFlight = 6;
-};
-
-message TObjectWithStateDict {
- message TItem {
- optional string Key = 1;
- optional bytes Value = 2;
- };
- repeated TItem Items = 1;
-};
+package NPDiskFIT;
+
+message TFakeVDiskState {
+ message TLogItem {
+ optional uint64 Lsn = 1;
+ optional uint32 Signature = 2;
+ optional uint32 DataLen = 3;
+ optional uint32 Checksum = 4;
+ repeated uint32 CommitChunks = 5;
+ repeated uint32 DeleteChunks = 6;
+ };
+ message TChunk {
+ message TBlock {
+ optional uint32 Index = 1;
+ optional uint32 Checksum = 2;
+ };
+ optional uint32 ChunkIdx = 1;
+ repeated TBlock Blocks = 2;
+ optional uint32 CommitState = 3;
+ };
+ message TWriteRecord {
+ optional uint32 ChunkIdx = 1;
+ optional uint32 OffsetInBlocks = 2;
+ optional uint32 SizeInBlocks = 3;
+ repeated uint32 Checksums = 4;
+ };
+ repeated TLogItem LogItems = 1;
+ repeated TLogItem InFlightItems = 2;
+ optional uint64 FirstLsnToKeep = 3;
+ optional uint32 BlocksInChunk = 4;
+ repeated TChunk Chunks = 5;
+ repeated TWriteRecord WritesInFlight = 6;
+};
+
+message TObjectWithStateDict {
+ message TItem {
+ optional string Key = 1;
+ optional bytes Value = 2;
+ };
+ repeated TItem Items = 1;
+};
diff --git a/ydb/core/protos/services.proto b/ydb/core/protos/services.proto
index c17c8a7dc37..6c639275b98 100644
--- a/ydb/core/protos/services.proto
+++ b/ydb/core/protos/services.proto
@@ -44,10 +44,10 @@ enum EServiceKikimr {
BS_QUEUE = 287;
BS_PROXY_MULTIGET = 288;
BS_PROXY_MULTICOLLECT = 289;
- BS_CONTROLLER_AUDIT = 304;
- BS_SELFHEAL = 342;
+ BS_CONTROLLER_AUDIT = 304;
+ BS_SELFHEAL = 342;
BS_PROXY_PATCH = 343;
- BS_VDISK_SCRUB = 344;
+ BS_VDISK_SCRUB = 344;
BS_VDISK_PATCH = 345;
// DATASHARD section //
@@ -55,9 +55,9 @@ enum EServiceKikimr {
///////////////////////
BS_PROXY_INDEXRESTOREGET = 291;
BS_PROXY_STATUS = 292;
- BS_LOAD_TEST = 293;
- BS_INCRHUGE = 294;
- BS_LOGCUTTER = 297;
+ BS_LOAD_TEST = 293;
+ BS_INCRHUGE = 294;
+ BS_LOGCUTTER = 297;
BS_VDISK_CHUNKS = 299;
// SCHEMESHARD section
@@ -149,15 +149,15 @@ enum EServiceKikimr {
LOGGER = 410;
MSGBUS_TRACER = 411;
MSGBUS_REQUEST = 412; // deprecated, use RPC_REQUEST
- GRPC_SERVER = 413;
+ GRPC_SERVER = 413;
GRPC_PROXY = 415;
GRPC_PROXY_NO_CONNECT_ACCESS = 417;
READ_TABLE_API = 414; // deprecated, use RPC_REQUEST
RPC_REQUEST = 416;
// KEY VALUE section
KEYVALUE = 420;
-
- WILSON = 430;
+
+ WILSON = 430;
// PERSQUEUE section
PERSQUEUE = 440;
@@ -239,8 +239,8 @@ enum EServiceKikimr {
// Distributed Storage
DS_PROXY_NODE_MON = 600;
- TEST_SHARD = 601;
-
+ TEST_SHARD = 601;
+
// Sequences
SEQUENCESHARD = 602;
SEQUENCEPROXY = 603;
@@ -305,405 +305,405 @@ enum EServiceKikimr {
REPLICATION_CONTROLLER = 1200;
};
-message TActivity {
-
- // Must be consistent with IActor::EActorActivity in ActorLib's part.
- // NOTE: all values are used as indices in counters array.
- // NOTE: numeric values can be changed and must be used only locally (inside one process),
- // only string names are reported in monitoring.
- enum EType {
- OTHER = 0;
- ACTOR_SYSTEM = 1;
- ACTORLIB_COMMON = 2;
- ACTORLIB_STATS = 3;
- LOG_ACTOR = 4;
- ACTORLIB_LONG_TIMER = 5;
- TX_REQ_PROXY = 6;
- VDISK_COMPACTION = 7;
- TX_PROXY_ACTOR = 8;
- TX_ALLOCATOR_ACTOR = 9;
- TX_COORDINATOR_ACTOR = 10;
- TX_MEDIATOR_ACTOR = 11;
- INTERCONNECT_PROXY_TCP = 12;
- INTERCONNECT_SESSION_TCP = 13;
- BS_PROXY_PUT_ACTOR = 14;
- TX_DATASHARD_ACTOR = 15;
- TABLET_PIPE_CLIENT = 16;
- TABLET_PIPE_SERVER = 17;
- MSGBUS_PROXY_ACTOR = 18;
- VDISK_SKELETON = 19;
- PROXY_SCHEME_CACHE = 20;
- PDISK_ACTOR = 21;
- BS_PROXY_GET_ACTOR = 22;
- BS_PROXY_ACTOR = 23;
- BS_HULLCOMP_SELECTOR = 24;
- TABLET_REQ_WRITE_LOG = 25;
- BS_HULL_HUGE_BLOB_WRITER = 26;
- BS_HULL_HUGE_BLOB_CHUNKALLOC = 27;
- BS_HULL_HUGE_BLOB_CHUNKDESTROY = 28;
- BS_HULL_HUGE_BLOB_ENTRYPOINTSAVER = 29;
- BS_HULL_HUGE_KEEPER = 30;
- BS_HULL_SYNC_FULL = 31;
- BS_DB_LOCAL_RECOVERY = 32;
- BS_RECOVERY_LOG_CUTTER = 33;
- BS_RECOVERY_LOG_WRITER = 34;
- BS_MON_ERROR = 35;
- BS_MON_HIST_UPDATER = 36;
- BS_MON_MAIN_PAGE = 37;
- BS_MON_SF_LOGOBLOBS = 38;
- BS_MON_SF_BARRIERS = 39;
- BS_MON_SF_LBSTAT = 40;
- BS_MON_SF_MAIN_PAGE = 41;
- BS_ASYNC_LSN_COMMITTER = 42;
- BS_ASYNC_FRESH_COMMITTER = 43;
- BS_ASYNC_LEVEL_COMMITTER = 44;
- BS_ASYNC_LEVEL_INDEX = 45;
- BS_LEVEL_SEGMENT_LOADER = 46;
- BS_ORD_LEVEL_SEGMENT_LOADER = 47;
- BS_UNORD_LEVEL_SEGMENT_LOADER = 48;
- BS_LEVEL_INDEX_LOADER = 49;
- BS_VDISK = 50;
- BS_SYNCLOG_COMMITTER = 51;
- BS_SYNCLOG_KEEPER = 52;
- BS_LEVEL_INDEX_BARRIER = 53;
- BS_HULLQUERY_RANGE_INDEX_ONLY = 54;
- BS_HULLQUERY_RANGE_DATA = 55;
- BS_READ_BATCHER = 56;
- BS_LEVEL_INDEX_STAT_QUERY = 57;
- BS_HULL_REPL_JOB = 58;
- BS_PDISK_ACTOR = 59;
- BS_GROUP_BLOCK = 60;
- BS_GROUP_COLLECT_GARBAGE = 61;
- BS_GROUP_DISCOVER = 62;
- BS_GROUP_RANGE = 63;
- BS_GROUP_PROXY_MON = 64;
- BS_REPL_SCHEDULER = 65;
- BS_HANDOFF_SYNCLOG_PROXY = 66;
- BS_VDISK_REPL_PROXY = 67;
- BS_SYNC_FULL_HANDLER = 68;
- BS_SKELETON_BACK = 69;
- BS_SKELETON_FRONT = 70;
- BS_STATUS_REQUEST_HANDLER = 71;
- BS_SYNCER_JOB = 72;
- BS_SYNCER_COMMITTER = 73;
- BS_SYNCER_SCHEDULER = 74;
- BS_SYNCLOG_LOCAL_STATUS = 75;
- BS_SYNCLOG_HTTPINFO = 76;
- BS_SYNCLOG_READER = 77;
- BS_SYNCLOG_ACTOR = 78;
- BS_HANDOFF_PROXY = 79;
- BS_HANDOFF_MON_REQUEST = 80;
- BS_HANDOFF_MON = 81;
- BS_HULL_LOG_CUTTER_NOTIFY = 82;
- SS_REPLICA_GUARDIAN = 83;
- SS_TABLET_GUARDIAN = 84;
- SS_MON = 85;
- SS_PROXY_REQUEST = 86;
- SS_PROXY = 87;
- SS_PROXY_STUB = 88;
- SS_REPLICA = 89;
- TX_COORDINATOR_MEDIATORQ_ACTOR = 90;
- TABLET_EXECUTOR_ACTOR = 91;
- TX_PROXY_SCHEMEREQ = 92;
- TX_PROXY_SCHEMECACHE = 93;
- TABLET_FORWARDING_ACTOR = 94;
- TABLET_MONITORING_PROXY = 95;
- TABLET_RESOLVER_ACTOR = 96;
- TABLET_REQ_REBUILD_GRAPH = 97;
- TABLET_REQ_FIND_LATEST = 98;
- TABLET_REQ_BLOCK_BS = 99;
- TABLET_COUNTERS_AGGREGATOR = 100;
- TABLET_ACTOR = 101;
- TABLET_LOCGR_LOADER = 102;
- TABLET_GC = 103;
- TABLET_COMPACTION_BROKER = 104;
- TABLET_GET_THROTTLING = 105;
- TX_PROXY_NAVIGATE = 106;
- TABLET_OPS_HOST_A = 107;
- OPS_COMPACT_A = 108;
- OPS_BACKUP_A = 109;
- TABLET_INMEM_STATE_CLEANUP = 110;
- MINIKQL_COMPILE_SERVICE = 111;
- MINIKQL_COMPILE_ACTOR = 112;
- CLIENT_SCHEME_CACHE_LOOKUP = 113;
- CLIENT_SCHEME_CACHE_LOOKUP_BATCH = 114;
- CLIENT_SCHEME_CACHE_LOOKUP_TREE = 115;
- CLIENT_SCHEME_CACHE_ONLINE = 116;
- KEYVALUE_ACTOR = 117;
- MSGBUS_TRACER_ACTOR = 118;
- NODE_WHITEBOARD_SERVICE = 119;
- CMS_SERVICE = 120;
- CMS_SERVICE_PROXY = 121;
- NODE_BROKER_ACTOR = 122;
- RTMR_CACHE_SERVICE = 123;
- RTMR_CACHE_SERVICE_READ_QUEUE = 124;
- RTMR_CACHE_SERVICE_TABLET_QUEUE = 125;
- RTMR_CACHE_SERVICE_WRITER = 126;
- RTMR_CACHE_SERVICE_WRITE_QUEUE = 127;
- RTMR_COMPACTION_SERVICE = 128;
- RTMR_MONITORING_SERVICE = 129;
- RTMR_TABLET = 130;
- RTMR_TABLET_BOOTSTRAPPER = 131;
- RTMR_TABLET_EXECUTOR = 132;
- RTMR_TABLET_EXECUTOR_CLEANUP = 133;
- RTMR_TABLET_EXECUTOR_COMPACTION = 134;
- RTMR_TABLET_EXECUTOR_FLUSH = 135;
- RTMR_TABLET_EXECUTOR_INIT = 136;
- RTMR_TABLET_EXECUTOR_READ = 137;
- RTMR_TABLET_EXECUTOR_READBLOCKS = 138;
- RTMR_TABLET_EXECUTOR_READSTATS = 139;
- RTMR_TABLET_EXECUTOR_RECOVERY = 140;
+message TActivity {
+
+ // Must be consistent with IActor::EActorActivity in ActorLib's part.
+ // NOTE: all values are used as indices in counters array.
+ // NOTE: numeric values can be changed and must be used only locally (inside one process),
+ // only string names are reported in monitoring.
+ enum EType {
+ OTHER = 0;
+ ACTOR_SYSTEM = 1;
+ ACTORLIB_COMMON = 2;
+ ACTORLIB_STATS = 3;
+ LOG_ACTOR = 4;
+ ACTORLIB_LONG_TIMER = 5;
+ TX_REQ_PROXY = 6;
+ VDISK_COMPACTION = 7;
+ TX_PROXY_ACTOR = 8;
+ TX_ALLOCATOR_ACTOR = 9;
+ TX_COORDINATOR_ACTOR = 10;
+ TX_MEDIATOR_ACTOR = 11;
+ INTERCONNECT_PROXY_TCP = 12;
+ INTERCONNECT_SESSION_TCP = 13;
+ BS_PROXY_PUT_ACTOR = 14;
+ TX_DATASHARD_ACTOR = 15;
+ TABLET_PIPE_CLIENT = 16;
+ TABLET_PIPE_SERVER = 17;
+ MSGBUS_PROXY_ACTOR = 18;
+ VDISK_SKELETON = 19;
+ PROXY_SCHEME_CACHE = 20;
+ PDISK_ACTOR = 21;
+ BS_PROXY_GET_ACTOR = 22;
+ BS_PROXY_ACTOR = 23;
+ BS_HULLCOMP_SELECTOR = 24;
+ TABLET_REQ_WRITE_LOG = 25;
+ BS_HULL_HUGE_BLOB_WRITER = 26;
+ BS_HULL_HUGE_BLOB_CHUNKALLOC = 27;
+ BS_HULL_HUGE_BLOB_CHUNKDESTROY = 28;
+ BS_HULL_HUGE_BLOB_ENTRYPOINTSAVER = 29;
+ BS_HULL_HUGE_KEEPER = 30;
+ BS_HULL_SYNC_FULL = 31;
+ BS_DB_LOCAL_RECOVERY = 32;
+ BS_RECOVERY_LOG_CUTTER = 33;
+ BS_RECOVERY_LOG_WRITER = 34;
+ BS_MON_ERROR = 35;
+ BS_MON_HIST_UPDATER = 36;
+ BS_MON_MAIN_PAGE = 37;
+ BS_MON_SF_LOGOBLOBS = 38;
+ BS_MON_SF_BARRIERS = 39;
+ BS_MON_SF_LBSTAT = 40;
+ BS_MON_SF_MAIN_PAGE = 41;
+ BS_ASYNC_LSN_COMMITTER = 42;
+ BS_ASYNC_FRESH_COMMITTER = 43;
+ BS_ASYNC_LEVEL_COMMITTER = 44;
+ BS_ASYNC_LEVEL_INDEX = 45;
+ BS_LEVEL_SEGMENT_LOADER = 46;
+ BS_ORD_LEVEL_SEGMENT_LOADER = 47;
+ BS_UNORD_LEVEL_SEGMENT_LOADER = 48;
+ BS_LEVEL_INDEX_LOADER = 49;
+ BS_VDISK = 50;
+ BS_SYNCLOG_COMMITTER = 51;
+ BS_SYNCLOG_KEEPER = 52;
+ BS_LEVEL_INDEX_BARRIER = 53;
+ BS_HULLQUERY_RANGE_INDEX_ONLY = 54;
+ BS_HULLQUERY_RANGE_DATA = 55;
+ BS_READ_BATCHER = 56;
+ BS_LEVEL_INDEX_STAT_QUERY = 57;
+ BS_HULL_REPL_JOB = 58;
+ BS_PDISK_ACTOR = 59;
+ BS_GROUP_BLOCK = 60;
+ BS_GROUP_COLLECT_GARBAGE = 61;
+ BS_GROUP_DISCOVER = 62;
+ BS_GROUP_RANGE = 63;
+ BS_GROUP_PROXY_MON = 64;
+ BS_REPL_SCHEDULER = 65;
+ BS_HANDOFF_SYNCLOG_PROXY = 66;
+ BS_VDISK_REPL_PROXY = 67;
+ BS_SYNC_FULL_HANDLER = 68;
+ BS_SKELETON_BACK = 69;
+ BS_SKELETON_FRONT = 70;
+ BS_STATUS_REQUEST_HANDLER = 71;
+ BS_SYNCER_JOB = 72;
+ BS_SYNCER_COMMITTER = 73;
+ BS_SYNCER_SCHEDULER = 74;
+ BS_SYNCLOG_LOCAL_STATUS = 75;
+ BS_SYNCLOG_HTTPINFO = 76;
+ BS_SYNCLOG_READER = 77;
+ BS_SYNCLOG_ACTOR = 78;
+ BS_HANDOFF_PROXY = 79;
+ BS_HANDOFF_MON_REQUEST = 80;
+ BS_HANDOFF_MON = 81;
+ BS_HULL_LOG_CUTTER_NOTIFY = 82;
+ SS_REPLICA_GUARDIAN = 83;
+ SS_TABLET_GUARDIAN = 84;
+ SS_MON = 85;
+ SS_PROXY_REQUEST = 86;
+ SS_PROXY = 87;
+ SS_PROXY_STUB = 88;
+ SS_REPLICA = 89;
+ TX_COORDINATOR_MEDIATORQ_ACTOR = 90;
+ TABLET_EXECUTOR_ACTOR = 91;
+ TX_PROXY_SCHEMEREQ = 92;
+ TX_PROXY_SCHEMECACHE = 93;
+ TABLET_FORWARDING_ACTOR = 94;
+ TABLET_MONITORING_PROXY = 95;
+ TABLET_RESOLVER_ACTOR = 96;
+ TABLET_REQ_REBUILD_GRAPH = 97;
+ TABLET_REQ_FIND_LATEST = 98;
+ TABLET_REQ_BLOCK_BS = 99;
+ TABLET_COUNTERS_AGGREGATOR = 100;
+ TABLET_ACTOR = 101;
+ TABLET_LOCGR_LOADER = 102;
+ TABLET_GC = 103;
+ TABLET_COMPACTION_BROKER = 104;
+ TABLET_GET_THROTTLING = 105;
+ TX_PROXY_NAVIGATE = 106;
+ TABLET_OPS_HOST_A = 107;
+ OPS_COMPACT_A = 108;
+ OPS_BACKUP_A = 109;
+ TABLET_INMEM_STATE_CLEANUP = 110;
+ MINIKQL_COMPILE_SERVICE = 111;
+ MINIKQL_COMPILE_ACTOR = 112;
+ CLIENT_SCHEME_CACHE_LOOKUP = 113;
+ CLIENT_SCHEME_CACHE_LOOKUP_BATCH = 114;
+ CLIENT_SCHEME_CACHE_LOOKUP_TREE = 115;
+ CLIENT_SCHEME_CACHE_ONLINE = 116;
+ KEYVALUE_ACTOR = 117;
+ MSGBUS_TRACER_ACTOR = 118;
+ NODE_WHITEBOARD_SERVICE = 119;
+ CMS_SERVICE = 120;
+ CMS_SERVICE_PROXY = 121;
+ NODE_BROKER_ACTOR = 122;
+ RTMR_CACHE_SERVICE = 123;
+ RTMR_CACHE_SERVICE_READ_QUEUE = 124;
+ RTMR_CACHE_SERVICE_TABLET_QUEUE = 125;
+ RTMR_CACHE_SERVICE_WRITER = 126;
+ RTMR_CACHE_SERVICE_WRITE_QUEUE = 127;
+ RTMR_COMPACTION_SERVICE = 128;
+ RTMR_MONITORING_SERVICE = 129;
+ RTMR_TABLET = 130;
+ RTMR_TABLET_BOOTSTRAPPER = 131;
+ RTMR_TABLET_EXECUTOR = 132;
+ RTMR_TABLET_EXECUTOR_CLEANUP = 133;
+ RTMR_TABLET_EXECUTOR_COMPACTION = 134;
+ RTMR_TABLET_EXECUTOR_FLUSH = 135;
+ RTMR_TABLET_EXECUTOR_INIT = 136;
+ RTMR_TABLET_EXECUTOR_READ = 137;
+ RTMR_TABLET_EXECUTOR_READBLOCKS = 138;
+ RTMR_TABLET_EXECUTOR_READSTATS = 139;
+ RTMR_TABLET_EXECUTOR_RECOVERY = 140;
RTMR_TABLET_EXECUTOR_FOLLOWERREAD = 141;
RTMR_TABLET_EXECUTOR_FOLLOWERUPDATE = 142;
- RTMR_TABLET_EXECUTOR_SNAPSHOT = 143;
- RTMR_TABLET_EXECUTOR_UPDATE = 144;
- RTMR_TABLET_EXECUTOR_UPDATESTATS = 145;
- RTMR_TABLET_EXECUTOR_WRITEBLOB = 146;
- RTMR_TABLET_PROXY = 147;
- RTMR_TABLET_SERVICE = 148;
- BS_QUEUE_ACTOR = 149;
- BS_ASYNC_REPLSST_COMMITTER = 150;
- FLAT_SCHEMESHARD_ACTOR = 151;
- BS_HULL_REPL_PLANNER = 152;
- PROXY_GATEWAY = 153;
- BS_PROXY_MULTIGET_ACTOR = 154;
- PERSQUEUE_ACTOR = 155;
- PERSQUEUE_PARTITION_ACTOR = 156;
- PERSQUEUE_CACHE_ACTOR = 157;
- PERSQUEUE_MON_ACTOR = 158;
- PERSQUEUE_ANS_ACTOR = 159;
- OBJ_DELETER = 160;
- BS_LOAD_ACTOR = 161;
- HIVE_ACTOR = 162;
- HIVE_BALANCER_ACTOR = 163;
- BS_DISK_SPACE_TRACKER = 164;
- FLAT_EXECUTOR = 165;
- BS_PROXY_MULTICOLLECT_ACTOR = 166;
- PERSQUEUE_METACACHE = 167;
- BS_PROXY_INDEXRESTOREGET_ACTOR = 168;
- BS_HULLQUERY_EXTREME_INDEX_ONLY = 169;
- BS_HULLQUERY_EXTREME_DATA = 170;
- INTERCONNECT_COMMON = 171;
- MSGBUS_COMMON = 172;
- JOB_COMMON = 173;
- LABELS_MAINTAINER_ACTOR = 174;
- HEALTH_ACTOR = 175;
- HEALTH_MON = 176;
- BS_SYNC_OBTAIN_VDISK_GUID_PROXY = 177;
- PERSQUEUE_CACHE_L2_ACTOR = 178;
- BS_PROXY_STATUS_ACTOR = 179;
- TABLET_REQ_DELETE_TABLET = 180;
- BS_SYNCER_LOCALWRITER = 181;
- TOKEN_BUILDER_ACTOR = 182;
- TICKET_PARSER_ACTOR = 183;
- KQP_PROXY_ACTOR = 184;
- KQP_WORKER_ACTOR = 185;
- ASYNC_DESTROYER = 186;
- BLACKBOX_VALIDATOR_ACTOR = 187;
- BS_SYNC_VDISK_GUID_RECOVERY = 188;
- BS_SYNC_VDISK_GUID_FIRST_RUN = 189;
- BS_SYNC_WRITE_VDISK_GUID_PROXY = 190;
- BS_SYNCER_MAIN = 191;
- BS_SYNCER_GUID_PROPAGATOR = 192;
- BS_SYNCER_RECOVER_LOST_DATA = 193;
- BS_REPL_BROKER = 194;
- BS_LOAD_PDISK_WRITE = 195;
- BS_LOAD_PDISK_READ = 196;
- BS_SYNCER_COMMITTER_PROXY = 197;
- BS_DELAYED_HUGE_BLOB_DELETER = 198;
- BS_BULK_SST_LOADER = 199;
- BS_INCR_HUGE_KEEPER = 200;
- BS_INCR_HUGE_KEEPER_RECOVERY_SCAN = 201;
- BS_INCR_HUGE_KEEPER_RECOVERY_READ_LOG = 202;
- BS_HULL_OSIRIS = 203;
- BS_SYNCER_HTTPREQ = 204;
- BS_FAILURE_INJECTION = 205;
- BS_GET_ACTOR = 206;
- SELF_PING_ACTOR = 207;
- STORE_TO_YT_ACTOR = 208;
- GRPC_PROXY = 209;
- NODE_IDENTIFIER = 210;
- BS_SYNCER_ANUBIS = 211;
- PERSQUEUE_READ_BALANCER_ACTOR = 212;
- SAUSAGE_CACHE = 213;
- FRONT_BSADM_PDISK = 214;
- FRONT_BSADM_VSLOTS = 215;
- FRONT_BSADM_GROUP = 216;
- FRONT_BSADM_RECONF_REPLACE = 217;
- FRONT_BSADM_RECONF_WIPE = 218;
- FRONT_BSADM_CONFIG = 219;
- FRONT_DS_SETCONF = 220;
- FRONT_KV_REQUEST = 221;
- FRONT_LOCAL_MQKL = 222;
- FRONT_LOCAL_TXRQ = 223;
- FRONT_GETCOUNTERS = 224;
- FRONT_POISON_TABLET = 225;
- FRONT_SCHEME_TXSTATUS = 226;
- FRONT_ENUMERATE_TABLETS = 227;
- FRONT_MKQL_REQUEST = 228;
- FRONT_SCHEME_DESCRIBE = 229;
- FRONT_SCHEME_REQUEST = 230;
- FRONT_YQL_REQUEST = 231;
- FRONT_PQ_WRITE = 232;
- FRONT_PQ_COMMIT = 233;
- FRONT_PQ_READ = 234;
- FRONT_PQ_PARTITION = 235;
- FRONT_GRPC_PROXY_STATUS = 236;
- FRONT_CHOOSE_RROXY = 237;
- WHOAMI = 238;
- BLOCKSTORE_BOOTSTRAPPER = 239;
- BLOCKSTORE_HIVE_PROXY = 240;
- BLOCKSTORE_PARTITION = 241;
- BLOCKSTORE_SCHEDULER = 242;
- BLOCKSTORE_SERVICE = 243;
- BLOCKSTORE_SERVICE_PROXY = 244;
- BLOCKSTORE_SS_PROXY = 245;
- BLOCKSTORE_VOLUME = 246;
+ RTMR_TABLET_EXECUTOR_SNAPSHOT = 143;
+ RTMR_TABLET_EXECUTOR_UPDATE = 144;
+ RTMR_TABLET_EXECUTOR_UPDATESTATS = 145;
+ RTMR_TABLET_EXECUTOR_WRITEBLOB = 146;
+ RTMR_TABLET_PROXY = 147;
+ RTMR_TABLET_SERVICE = 148;
+ BS_QUEUE_ACTOR = 149;
+ BS_ASYNC_REPLSST_COMMITTER = 150;
+ FLAT_SCHEMESHARD_ACTOR = 151;
+ BS_HULL_REPL_PLANNER = 152;
+ PROXY_GATEWAY = 153;
+ BS_PROXY_MULTIGET_ACTOR = 154;
+ PERSQUEUE_ACTOR = 155;
+ PERSQUEUE_PARTITION_ACTOR = 156;
+ PERSQUEUE_CACHE_ACTOR = 157;
+ PERSQUEUE_MON_ACTOR = 158;
+ PERSQUEUE_ANS_ACTOR = 159;
+ OBJ_DELETER = 160;
+ BS_LOAD_ACTOR = 161;
+ HIVE_ACTOR = 162;
+ HIVE_BALANCER_ACTOR = 163;
+ BS_DISK_SPACE_TRACKER = 164;
+ FLAT_EXECUTOR = 165;
+ BS_PROXY_MULTICOLLECT_ACTOR = 166;
+ PERSQUEUE_METACACHE = 167;
+ BS_PROXY_INDEXRESTOREGET_ACTOR = 168;
+ BS_HULLQUERY_EXTREME_INDEX_ONLY = 169;
+ BS_HULLQUERY_EXTREME_DATA = 170;
+ INTERCONNECT_COMMON = 171;
+ MSGBUS_COMMON = 172;
+ JOB_COMMON = 173;
+ LABELS_MAINTAINER_ACTOR = 174;
+ HEALTH_ACTOR = 175;
+ HEALTH_MON = 176;
+ BS_SYNC_OBTAIN_VDISK_GUID_PROXY = 177;
+ PERSQUEUE_CACHE_L2_ACTOR = 178;
+ BS_PROXY_STATUS_ACTOR = 179;
+ TABLET_REQ_DELETE_TABLET = 180;
+ BS_SYNCER_LOCALWRITER = 181;
+ TOKEN_BUILDER_ACTOR = 182;
+ TICKET_PARSER_ACTOR = 183;
+ KQP_PROXY_ACTOR = 184;
+ KQP_WORKER_ACTOR = 185;
+ ASYNC_DESTROYER = 186;
+ BLACKBOX_VALIDATOR_ACTOR = 187;
+ BS_SYNC_VDISK_GUID_RECOVERY = 188;
+ BS_SYNC_VDISK_GUID_FIRST_RUN = 189;
+ BS_SYNC_WRITE_VDISK_GUID_PROXY = 190;
+ BS_SYNCER_MAIN = 191;
+ BS_SYNCER_GUID_PROPAGATOR = 192;
+ BS_SYNCER_RECOVER_LOST_DATA = 193;
+ BS_REPL_BROKER = 194;
+ BS_LOAD_PDISK_WRITE = 195;
+ BS_LOAD_PDISK_READ = 196;
+ BS_SYNCER_COMMITTER_PROXY = 197;
+ BS_DELAYED_HUGE_BLOB_DELETER = 198;
+ BS_BULK_SST_LOADER = 199;
+ BS_INCR_HUGE_KEEPER = 200;
+ BS_INCR_HUGE_KEEPER_RECOVERY_SCAN = 201;
+ BS_INCR_HUGE_KEEPER_RECOVERY_READ_LOG = 202;
+ BS_HULL_OSIRIS = 203;
+ BS_SYNCER_HTTPREQ = 204;
+ BS_FAILURE_INJECTION = 205;
+ BS_GET_ACTOR = 206;
+ SELF_PING_ACTOR = 207;
+ STORE_TO_YT_ACTOR = 208;
+ GRPC_PROXY = 209;
+ NODE_IDENTIFIER = 210;
+ BS_SYNCER_ANUBIS = 211;
+ PERSQUEUE_READ_BALANCER_ACTOR = 212;
+ SAUSAGE_CACHE = 213;
+ FRONT_BSADM_PDISK = 214;
+ FRONT_BSADM_VSLOTS = 215;
+ FRONT_BSADM_GROUP = 216;
+ FRONT_BSADM_RECONF_REPLACE = 217;
+ FRONT_BSADM_RECONF_WIPE = 218;
+ FRONT_BSADM_CONFIG = 219;
+ FRONT_DS_SETCONF = 220;
+ FRONT_KV_REQUEST = 221;
+ FRONT_LOCAL_MQKL = 222;
+ FRONT_LOCAL_TXRQ = 223;
+ FRONT_GETCOUNTERS = 224;
+ FRONT_POISON_TABLET = 225;
+ FRONT_SCHEME_TXSTATUS = 226;
+ FRONT_ENUMERATE_TABLETS = 227;
+ FRONT_MKQL_REQUEST = 228;
+ FRONT_SCHEME_DESCRIBE = 229;
+ FRONT_SCHEME_REQUEST = 230;
+ FRONT_YQL_REQUEST = 231;
+ FRONT_PQ_WRITE = 232;
+ FRONT_PQ_COMMIT = 233;
+ FRONT_PQ_READ = 234;
+ FRONT_PQ_PARTITION = 235;
+ FRONT_GRPC_PROXY_STATUS = 236;
+ FRONT_CHOOSE_RROXY = 237;
+ WHOAMI = 238;
+ BLOCKSTORE_BOOTSTRAPPER = 239;
+ BLOCKSTORE_HIVE_PROXY = 240;
+ BLOCKSTORE_PARTITION = 241;
+ BLOCKSTORE_SCHEDULER = 242;
+ BLOCKSTORE_SERVICE = 243;
+ BLOCKSTORE_SERVICE_PROXY = 244;
+ BLOCKSTORE_SS_PROXY = 245;
+ BLOCKSTORE_VOLUME = 246;
SAUSAGE_BIO_A = 247; // Generalized page collection blocks IO
- KQP_EXECUTER_ACTOR = 248;
- USER_REGISTRY_ACTOR = 249;
- TVM_SETTINGS_UPDATER_ACTOR = 250;
- PQ_BASE_REQUEST_PROCESSOR = 251;
- PQ_META_REQUEST_PROCESSOR = 252;
- FAKE_ENV_A = 253; // UT infrasturcture activity
- VIEWER_HANDLER = 254;
- DATASHARD_STATS_BUILDER = 255;
- KESUS_PROXY_ACTOR = 256;
- KESUS_TABLET_ACTOR = 257;
- RTMR_IC_BUS_SERVICE = 258;
- BLOCKSTORE_PARTITION_WORKER = 259;
- TX_DATASHARD_COMMON = 260;
- RTMR_TABLET_EXECUTOR_READBLOBS = 261;
- DS_PROXY_NODE_MON_ACTOR = 262;
- KQP_COMPUTE_ACTOR = 263;
- SQS_SERVICE_ACTOR = 264;
- SQS_ACTOR = 265;
- SQS_PROXY_ACTOR = 266;
- CMS_TENANTS_MANAGER = 267;
- CMS_CONFIGS_MANAGER = 268;
- CMS_CONFIGS_PROVIDER = 269;
- CMS_CONFIGS_SUBSCRIBER = 270;
- CONFIGS_DISPATCHER_ACTOR = 271;
- BOARD_REPLICA_ACTOR = 272;
- BOARD_LOOKUP_ACTOR = 273;
- BOARD_PUBLISH_ACTOR = 274;
- BOARD_REPLICA_PUBLISH_ACTOR = 275;
- USER_FETCHER_ACTOR = 276;
- TABLET_RESPONSIVENESS_PINGER = 277;
- BS_GROUP_OBSERVER = 278;
- GRPC_UPDATER = 279;
- TABLE_SCHEME_RESOLVER = 280;
- BS_GROUP_REQUEST = 281;
- TABLET_KILLER = 282;
- TEST_ACTOR_RUNTIME = 283;
- INTERCONNECT_HANDSHAKE = 284;
- INTERCONNECT_POLLER = 285;
- INTERCONNECT_SESSION_KILLER = 286;
- IMMEDIATE_CONTROL_BOARD = 287;
+ KQP_EXECUTER_ACTOR = 248;
+ USER_REGISTRY_ACTOR = 249;
+ TVM_SETTINGS_UPDATER_ACTOR = 250;
+ PQ_BASE_REQUEST_PROCESSOR = 251;
+ PQ_META_REQUEST_PROCESSOR = 252;
+ FAKE_ENV_A = 253; // UT infrasturcture activity
+ VIEWER_HANDLER = 254;
+ DATASHARD_STATS_BUILDER = 255;
+ KESUS_PROXY_ACTOR = 256;
+ KESUS_TABLET_ACTOR = 257;
+ RTMR_IC_BUS_SERVICE = 258;
+ BLOCKSTORE_PARTITION_WORKER = 259;
+ TX_DATASHARD_COMMON = 260;
+ RTMR_TABLET_EXECUTOR_READBLOBS = 261;
+ DS_PROXY_NODE_MON_ACTOR = 262;
+ KQP_COMPUTE_ACTOR = 263;
+ SQS_SERVICE_ACTOR = 264;
+ SQS_ACTOR = 265;
+ SQS_PROXY_ACTOR = 266;
+ CMS_TENANTS_MANAGER = 267;
+ CMS_CONFIGS_MANAGER = 268;
+ CMS_CONFIGS_PROVIDER = 269;
+ CMS_CONFIGS_SUBSCRIBER = 270;
+ CONFIGS_DISPATCHER_ACTOR = 271;
+ BOARD_REPLICA_ACTOR = 272;
+ BOARD_LOOKUP_ACTOR = 273;
+ BOARD_PUBLISH_ACTOR = 274;
+ BOARD_REPLICA_PUBLISH_ACTOR = 275;
+ USER_FETCHER_ACTOR = 276;
+ TABLET_RESPONSIVENESS_PINGER = 277;
+ BS_GROUP_OBSERVER = 278;
+ GRPC_UPDATER = 279;
+ TABLE_SCHEME_RESOLVER = 280;
+ BS_GROUP_REQUEST = 281;
+ TABLET_KILLER = 282;
+ TEST_ACTOR_RUNTIME = 283;
+ INTERCONNECT_HANDSHAKE = 284;
+ INTERCONNECT_POLLER = 285;
+ INTERCONNECT_SESSION_KILLER = 286;
+ IMMEDIATE_CONTROL_BOARD = 287;
DS_PROXY_OVERSEER_ACTOR = 288; // deprecated
- KQP_REQUEST_HANDLER = 289;
- KESUS_RESOLVE_ACTOR = 290;
- HIVE_MON_REQUEST = 291;
- IAM_SERVICE_ACTOR = 292;
- IAM_SERVICE_AUTHENTICATE = 293;
- IAM_SERVICE_AUTHORIZE = 294;
- DEFERRABLE_RPC = 295;
- CMS_MON_PDISK = 296;
- GRPC_REQ_AUTH = 297;
- GRPC_ENDPOINT_PUBLISH = 298;
- NODE_BROKER_LEASE_HOLDER = 299;
- CMS_INFO_COLLECTOR = 300;
- CMS_WALLE_REQ = 301;
- KESUS_REQ = 302;
- GRPC_REQ = 303;
- BLOCKSTORE_METERING = 304;
- SQS_CLEANUP_BACKGROUND_ACTOR = 305;
- SQS_RETENTION_BACKGROUND_ACTOR = 306;
- SQS_PURGE_ACTOR = 307;
- SQS_EXECUTOR_ACTOR = 308;
- KQP_TABLE_PROFILE_LOADER_ACTOR = 309;
- FOLDER_SERVICE_ACTOR = 310;
- FOLDER_SERVICE_LIST_FOLDER = 311;
- ACTOR_SYSTEM_SCHEDULER_ACTOR = 312;
- SQS_PROXY_SERVICE_ACTOR = 313;
+ KQP_REQUEST_HANDLER = 289;
+ KESUS_RESOLVE_ACTOR = 290;
+ HIVE_MON_REQUEST = 291;
+ IAM_SERVICE_ACTOR = 292;
+ IAM_SERVICE_AUTHENTICATE = 293;
+ IAM_SERVICE_AUTHORIZE = 294;
+ DEFERRABLE_RPC = 295;
+ CMS_MON_PDISK = 296;
+ GRPC_REQ_AUTH = 297;
+ GRPC_ENDPOINT_PUBLISH = 298;
+ NODE_BROKER_LEASE_HOLDER = 299;
+ CMS_INFO_COLLECTOR = 300;
+ CMS_WALLE_REQ = 301;
+ KESUS_REQ = 302;
+ GRPC_REQ = 303;
+ BLOCKSTORE_METERING = 304;
+ SQS_CLEANUP_BACKGROUND_ACTOR = 305;
+ SQS_RETENTION_BACKGROUND_ACTOR = 306;
+ SQS_PURGE_ACTOR = 307;
+ SQS_EXECUTOR_ACTOR = 308;
+ KQP_TABLE_PROFILE_LOADER_ACTOR = 309;
+ FOLDER_SERVICE_ACTOR = 310;
+ FOLDER_SERVICE_LIST_FOLDER = 311;
+ ACTOR_SYSTEM_SCHEDULER_ACTOR = 312;
+ SQS_PROXY_SERVICE_ACTOR = 313;
SQS_QUEUE_LEADER_ACTOR = 314;
- TABLET_LOOKUP_ACTOR = 315;
- TRACE_LOOKUP_ACTOR = 316;
- TRACE_REQUEST_ACTOR = 317;
- SIGNAL_BODY_REQUEST_ACTOR = 318;
- TABLET_INFO = 319;
- GRPC_STREAM_REQ = 320;
- TX_READ_TABLE_SCAN = 321;
- BLOCKSTORE_SCHEMESHARD = 322;
- GRPC_MON = 323;
- LOG_SETTINGS_CONFIGURATOR = 324;
- QUOTER_SERVICE_ACTOR = 325;
- QUOTER_PROXY_ACTOR = 326;
- ACCESS_SERVICE_ACTOR = 327;
- ACCESS_SERVICE_AUTHENTICATE = 328;
- ACCESS_SERVICE_AUTHORIZE = 329;
- USER_ACCOUNT_SERVICE_ACTOR = 330;
- USER_ACCOUNT_SERVICE_GET = 331;
- RTMR_TABLET_EXECUTOR_SETMETADATAATTRS = 332;
- BLOCKSTORE_VOLUME_PROXY = 333;
- SQS_QUEUE_MIGRATION_ACTOR = 334;
- SQS_PING_ACTOR = 335;
- SCHEME_BOARD_REPLICA_ACTOR = 336;
- ACTOR_FUTURE_CALLBACK = 337;
- SCHEME_BOARD_SUBSCRIBER_ACTOR = 338;
- SCHEME_BOARD_REPLICA_SUBSCRIBER_ACTOR = 339;
- SCHEME_BOARD_POPULATOR_ACTOR = 340;
- SCHEME_BOARD_REPLICA_POPULATOR_ACTOR = 341;
- SHARED_CACHE_CONFIGURATOR = 342;
- SQS_METERING_ACTOR = 343;
- IMMEDITE_CONTROLS_CONFIGURATOR = 344;
- SQS_USER_SETTINGS_READER_ACTOR = 345;
- KQP_EXEC_PHYSICAL_REQUEST_HANDLER = 346;
- TENANT_SLOT_BROKER_ACTOR = 347;
- GROUP_BALANCER_ACTOR = 348;
- BS_CONTROLLER_ACTOR = 349;
- TENANT_POOL_ACTOR = 350;
- LOCAL_ACTOR = 351;
- NODE_WARDEN = 352;
- TABLET_BOOTSTRAPPER = 353;
- BSC_STAT_PROCESSOR = 354;
- SQS_QUEUES_LIST_READER_ACTOR = 355;
- TX_PROXY_EXPORT = 356;
+ TABLET_LOOKUP_ACTOR = 315;
+ TRACE_LOOKUP_ACTOR = 316;
+ TRACE_REQUEST_ACTOR = 317;
+ SIGNAL_BODY_REQUEST_ACTOR = 318;
+ TABLET_INFO = 319;
+ GRPC_STREAM_REQ = 320;
+ TX_READ_TABLE_SCAN = 321;
+ BLOCKSTORE_SCHEMESHARD = 322;
+ GRPC_MON = 323;
+ LOG_SETTINGS_CONFIGURATOR = 324;
+ QUOTER_SERVICE_ACTOR = 325;
+ QUOTER_PROXY_ACTOR = 326;
+ ACCESS_SERVICE_ACTOR = 327;
+ ACCESS_SERVICE_AUTHENTICATE = 328;
+ ACCESS_SERVICE_AUTHORIZE = 329;
+ USER_ACCOUNT_SERVICE_ACTOR = 330;
+ USER_ACCOUNT_SERVICE_GET = 331;
+ RTMR_TABLET_EXECUTOR_SETMETADATAATTRS = 332;
+ BLOCKSTORE_VOLUME_PROXY = 333;
+ SQS_QUEUE_MIGRATION_ACTOR = 334;
+ SQS_PING_ACTOR = 335;
+ SCHEME_BOARD_REPLICA_ACTOR = 336;
+ ACTOR_FUTURE_CALLBACK = 337;
+ SCHEME_BOARD_SUBSCRIBER_ACTOR = 338;
+ SCHEME_BOARD_REPLICA_SUBSCRIBER_ACTOR = 339;
+ SCHEME_BOARD_POPULATOR_ACTOR = 340;
+ SCHEME_BOARD_REPLICA_POPULATOR_ACTOR = 341;
+ SHARED_CACHE_CONFIGURATOR = 342;
+ SQS_METERING_ACTOR = 343;
+ IMMEDITE_CONTROLS_CONFIGURATOR = 344;
+ SQS_USER_SETTINGS_READER_ACTOR = 345;
+ KQP_EXEC_PHYSICAL_REQUEST_HANDLER = 346;
+ TENANT_SLOT_BROKER_ACTOR = 347;
+ GROUP_BALANCER_ACTOR = 348;
+ BS_CONTROLLER_ACTOR = 349;
+ TENANT_POOL_ACTOR = 350;
+ LOCAL_ACTOR = 351;
+ NODE_WARDEN = 352;
+ TABLET_BOOTSTRAPPER = 353;
+ BSC_STAT_PROCESSOR = 354;
+ SQS_QUEUES_LIST_READER_ACTOR = 355;
+ TX_PROXY_EXPORT = 356;
KQP_SCAN_COMPUTE_ACTOR = 357;
- KQP_TABLE_SCAN = 358;
+ KQP_TABLE_SCAN = 358;
CONFIGURED_BOOTSTRAPPER = 359;
TX_ALLOCATOR_CLIENT_ACTOR = 360;
- BLOCKSTORE_AUTH = 361;
+ BLOCKSTORE_AUTH = 361;
INTERCONNECT_MONACTOR = 362;
BS_MONSTREAM_ACTOR = 363;
NODE_WARDEN_STATAGGR_ACTOR = 364;
UPLOAD_ROWS_INTERNAL = 365;
PERSQUEUE_CLUSTER_TRACKER = 366;
NET_CLASSIFIER_ACTOR = 367;
- KQP_COMPILE_SERVICE = 368;
- KQP_COMPILE_ACTOR = 369;
+ KQP_COMPILE_SERVICE = 368;
+ KQP_COMPILE_ACTOR = 369;
PERSQUEUE_CLUSTER_DISCOVERY = 370;
TX_FILL_INDEX_SCAN = 371;
NET_CLASSIFIER_UPDATER = 372;
- BS_LOAD_PDISK_LOG_WRITE = 373;
- RTMR_CONFIGURATION_STORAGE = 374;
- KQP_SYSTEM_VIEW_SCAN = 375;
- INTERCONNECT_LOAD_ACTOR = 376;
- INTERCONNECT_LOAD_RESPONDER = 377;
- INTERCONNECT_DESTRUCT_ACTOR = 378;
- BS_MIGRATION_ACTOR = 379;
- SQS_GARBAGE_COLLECTOR_ACTOR = 380;
+ BS_LOAD_PDISK_LOG_WRITE = 373;
+ RTMR_CONFIGURATION_STORAGE = 374;
+ KQP_SYSTEM_VIEW_SCAN = 375;
+ INTERCONNECT_LOAD_ACTOR = 376;
+ INTERCONNECT_LOAD_RESPONDER = 377;
+ INTERCONNECT_DESTRUCT_ACTOR = 378;
+ BS_MIGRATION_ACTOR = 379;
+ SQS_GARBAGE_COLLECTOR_ACTOR = 380;
SYSTEM_VIEW_SERVICE = 381;
CMS_SENTINEL_ACTOR = 382;
CMS_SENTINEL_CONFIG_UPDATER_ACTOR = 383;
CMS_SENTINEL_STATE_UPDATER_ACTOR = 384;
CMS_SENTINEL_STATUS_CHANGER_ACTOR = 385;
TENANT_NODES_ENUMERATION = 386;
- SCHEME_BOARD_SYNCHRONIZER_ACTOR = 387;
- SCHEME_BOARD_REPLICA_SYNCHRONIZER_ACTOR = 388;
- SYSTEM_VIEW_PART_STATS_COLLECTOR = 389;
- BLOCKSTORE_DISK_AGENT = 390;
- BLOCKSTORE_DISK_REGISTRY = 391;
+ SCHEME_BOARD_SYNCHRONIZER_ACTOR = 387;
+ SCHEME_BOARD_REPLICA_SYNCHRONIZER_ACTOR = 388;
+ SYSTEM_VIEW_PART_STATS_COLLECTOR = 389;
+ BLOCKSTORE_DISK_AGENT = 390;
+ BLOCKSTORE_DISK_REGISTRY = 391;
EXPORT_SCAN_ACTOR = 392;
EXPORT_YT_UPLOADER_ACTOR = 393;
EXPORT_S3_UPLOADER_ACTOR = 394;
@@ -742,10 +742,10 @@ message TActivity {
YF_RUNNER_WORKER_PRIVATE_ACTOR = 427;
YF_RUNNER_PRIVATE_ACTOR = 428;
YF_REQUEST_REGISTER_FUNCTION_ACTOR = 429;
- SERVICE_ACCOUNT_SERVICE_ACTOR = 430;
- BLOCKSTORE_DISK_REGISTRY_PROXY = 431;
- BSC_SYSTEM_VIEWS_COLLECTOR = 432;
- KQP_RESOURCE_MANAGER = 433;
+ SERVICE_ACCOUNT_SERVICE_ACTOR = 430;
+ BLOCKSTORE_DISK_REGISTRY_PROXY = 431;
+ BSC_SYSTEM_VIEWS_COLLECTOR = 432;
+ KQP_RESOURCE_MANAGER = 433;
YF_REQUEST_UNREGISTER_FUNCTION_ACTOR = 434;
YF_REQUEST_DESCRIBE_FUNCTION_ACTOR = 435;
YF_REQUEST_LIST_FUNCTIONS_ACTOR = 436;
@@ -753,49 +753,49 @@ message TActivity {
YF_REQUEST_LIST_INSTANCES_ACTOR = 438;
YF_REQUEST_GENERATE_UPLOAD_URL_ACTOR = 439;
YF_REQUEST_CALL_FUNCTION_ACTOR = 440;
- SCHEME_BOARD_DB_RESOLVER = 441;
+ SCHEME_BOARD_DB_RESOLVER = 441;
YF_LOGGER_ACTOR = 442;
CONDITIONAL_ERASE_ROWS_SCAN_ACTOR = 443;
- BLOCKSTORE_VOLUME_BALANCER = 444;
- BLOCKSTORE_DISK_REGISTRY_WORKER = 445;
- BLOCKSTORE_DISK_AGENT_WORKER = 446;
- SYSTEM_VIEW_PROCESSOR = 447;
- VDISK_LOCALSYNCDATA_EXTRACTOR = 448;
- VDISK_FRESH_APPENDIX_COMPACTION = 449;
- NAMESERVICE = 450;
- PERSQUEUE_MIRRORER = 451;
- LONG_TX_SERVICE = 452;
- LONG_TX_SERVICE_COMMIT = 453;
- PERSQUEUE_READ_SPEED_LIMITER = 454;
- LONG_TX_SERVICE_ACQUIRE_SNAPSHOT = 455;
- BLOCKSTORE_PARTITION_NONREPL = 456;
- BS_PROXY_PATCH_ACTOR = 457;
+ BLOCKSTORE_VOLUME_BALANCER = 444;
+ BLOCKSTORE_DISK_REGISTRY_WORKER = 445;
+ BLOCKSTORE_DISK_AGENT_WORKER = 446;
+ SYSTEM_VIEW_PROCESSOR = 447;
+ VDISK_LOCALSYNCDATA_EXTRACTOR = 448;
+ VDISK_FRESH_APPENDIX_COMPACTION = 449;
+ NAMESERVICE = 450;
+ PERSQUEUE_MIRRORER = 451;
+ LONG_TX_SERVICE = 452;
+ LONG_TX_SERVICE_COMMIT = 453;
+ PERSQUEUE_READ_SPEED_LIMITER = 454;
+ LONG_TX_SERVICE_ACQUIRE_SNAPSHOT = 455;
+ BLOCKSTORE_PARTITION_NONREPL = 456;
+ BS_PROXY_PATCH_ACTOR = 457;
SCHEME_BOARD_WATCH_CACHE_ACTOR = 458;
SEQUENCESHARD_ACTOR = 459;
BUILD_INDEX_SCAN_ACTOR = 460;
FLAT_EXECUTOR_REASSIGN = 461;
- DISTRIBUTED_ERASE_ROWS_ACTOR = 462;
- YT_WRAPPER_ACTOR = 463;
- YT_TABLE_WRITER_ACTOR = 464;
- SCHEME_BOARD_SUBSCRIBER_PROXY_ACTOR = 465;
- S3_WRAPPER_ACTOR = 466;
+ DISTRIBUTED_ERASE_ROWS_ACTOR = 462;
+ YT_WRAPPER_ACTOR = 463;
+ YT_TABLE_WRITER_ACTOR = 464;
+ SCHEME_BOARD_SUBSCRIBER_PROXY_ACTOR = 465;
+ S3_WRAPPER_ACTOR = 466;
FILESTORE_SCHEMESHARD = 467;
FILESTORE_SERVICE = 468;
FILESTORE_SERVICE_WORKER = 469;
- TX_OLAPSHARD_ACTOR = 470;
+ TX_OLAPSHARD_ACTOR = 470;
FILESTORE_TABLET = 471;
FILESTORE_TABLET_WORKER = 472;
FILESTORE_TABLET_PROXY = 473;
FILESTORE_SS_PROXY = 474;
- IMPORT_S3_DOWNLOADER_ACTOR = 475;
- MEMORY_TRACKER = 476;
- TX_COLUMNSHARD_ACTOR = 477;
+ IMPORT_S3_DOWNLOADER_ACTOR = 475;
+ MEMORY_TRACKER = 476;
+ TX_COLUMNSHARD_ACTOR = 477;
TX_COLUMNSHARD_WRITE_ACTOR = 496;
TX_COLUMNSHARD_READ_ACTOR = 497;
TX_COLUMNSHARD_INDEXING_ACTOR = 498;
TX_COLUMNSHARD_COMPACTION_ACTOR = 499;
- SCHEME_BOARD_MONITORING_ACTOR = 478;
- SCHEME_BOARD_INFO_REQUESTER_ACTOR = 479;
+ SCHEME_BOARD_MONITORING_ACTOR = 478;
+ SCHEME_BOARD_INFO_REQUESTER_ACTOR = 479;
METERING_WRITER_ACTOR = 480;
SEQUENCE_PROXY_SERVICE = 481;
KQP_TABLE_SCAN_PROXY = 482;
@@ -803,19 +803,19 @@ message TActivity {
KQP_RESULT_CHANNEL_PROXY = 484;
KQP_SHARDS_RESOLVER = 485;
KQP_COMPILE_REQUEST = 486;
- BS_DEFRAG = 487;
- BS_DEFRAG_QUANTUM = 488;
+ BS_DEFRAG = 487;
+ BS_DEFRAG_QUANTUM = 488;
KQP_LITERAL_EXECUTER_ACTOR = 489;
- FILESTORE_SERVICE_PROXY = 490;
+ FILESTORE_SERVICE_PROXY = 490;
TX_DATASHARD_SOURCE_OFFSETS_SERVER = 491;
KQP_OLAP_SCAN = 492;
KQP_DATA_EXECUTER_ACTOR = 493;
KQP_NODE_SERVICE = 494;
TX_DATASHARD_SOURCE_OFFSETS_CLIENT = 500;
YQL_PROXY_ACTOR = 510;
- TEST_SHARD_ACTOR = 511;
- FRONT_TEST_SHARD_REQUEST = 512;
- STATE_SERVER_INTERFACE_ACTOR = 513;
+ TEST_SHARD_ACTOR = 511;
+ FRONT_TEST_SHARD_REQUEST = 512;
+ STATE_SERVER_INTERFACE_ACTOR = 513;
IAM_TOKEN_SERVICE_ACTOR = 514;
YQL_EXECUTE_PLAN_ACTOR = 515;
YQL_DB_POOL_ACTOR = 516;
@@ -833,9 +833,9 @@ message TActivity {
YQL_MODIFY_CONNECTIONS_REQUEST_ACTOR = 528;
YQL_MODIFY_HISTORY_REQUEST_ACTOR = 529;
YQL_WRITE_RESULT_DATA_ACTOR = 530;
- BS_SCRUB_ACTOR = 531;
- BS_BLOB_RECOVERY_ACTOR = 532;
- BS_RESTORE_CORRUPTED_BLOB_ACTOR = 533;
+ BS_SCRUB_ACTOR = 531;
+ BS_BLOB_RECOVERY_ACTOR = 532;
+ BS_RESTORE_CORRUPTED_BLOB_ACTOR = 533;
YQ_CONTROL_PLANE_STORAGE_ACTOR = 534;
YQ_CONTROL_PLANE_PROXY_ACTOR = 535;
DB_WATCHER_ACTOR = 495;
@@ -849,7 +849,7 @@ message TActivity {
YQL_NODES_MANAGER_ACTOR = 543;
KESUS_ACCOUNTING_ACTOR = 544;
BLOCKSTORE_PARTITION_COMMON = 545;
- INTERCONNECT_PROXY_WRAPPER = 546;
+ INTERCONNECT_PROXY_WRAPPER = 546;
CLOUD_STORAGE_HIVE_PROXY = 547;
YQL_PRIVATE_NODES_HEALTH_CHECK_ACTOR = 548;
CHANGE_SENDER_CDC_ACTOR_MAIN = 549;
@@ -858,14 +858,14 @@ message TActivity {
CHANGE_SENDER_CDC_ACTOR_PARTITION = 552;
KQP_SESSION_ACTOR = 553;
CHANGE_EXCHANGE_SPLIT_ACTOR = 554;
- BS_DEFRAG_REWRITER = 555;
- BS_DEFRAG_SCHEDULER = 556;
- BS_DEFRAG_PLANNER = 557;
+ BS_DEFRAG_REWRITER = 555;
+ BS_DEFRAG_SCHEDULER = 556;
+ BS_DEFRAG_PLANNER = 557;
REPLICATION_CONTROLLER_ACTOR = 558;
REPLICATION_CONTROLLER_DISCOVERER = 559;
REPLICATION_CONTROLLER_STREAM_CREATOR = 561;
YQ_TEST_CONNECTION_ACTOR = 560;
REPLICATION_CONTROLLER_DST_CREATOR = 562;
BLOCKSTORE_STATS_SERVICE = 563;
- };
+ };
};
diff --git a/ydb/core/protos/sys_view.proto b/ydb/core/protos/sys_view.proto
index cfc03662725..5b85f0fc01f 100644
--- a/ydb/core/protos/sys_view.proto
+++ b/ydb/core/protos/sys_view.proto
@@ -159,13 +159,13 @@ message TPDiskInfo {
optional uint64 AvailableSize = 8;
optional uint64 TotalSize = 9;
reserved 10;
- reserved 11;
+ reserved 11;
optional string StatusV2 = 12;
- optional uint64 StatusChangeTimestamp = 13;
- optional uint64 EnforcedDynamicSlotSize = 14;
- optional uint32 ExpectedSlotCount = 15;
- optional uint32 NumActiveSlots = 16;
- optional uint64 Category = 17;
+ optional uint64 StatusChangeTimestamp = 13;
+ optional uint64 EnforcedDynamicSlotSize = 14;
+ optional uint32 ExpectedSlotCount = 15;
+ optional uint32 NumActiveSlots = 16;
+ optional uint64 Category = 17;
// metrics ?
// physical location ?
// config ?
@@ -198,16 +198,16 @@ message TVSlotInfo {
reserved 1;
optional uint32 GroupId = 2;
optional uint32 GroupGeneration = 3;
- optional uint32 FailRealm = 4;
+ optional uint32 FailRealm = 4;
optional uint32 FailDomain = 5;
optional uint32 VDisk = 6;
optional uint64 AllocatedSize = 7;
optional uint64 AvailableSize = 8;
reserved 9;
- reserved 10;
+ reserved 10;
optional string StatusV2 = 12;
optional string Kind = 13;
- optional bool IsBeingDeleted = 14;
+ optional bool IsBeingDeleted = 14;
// metrics ?
}
@@ -241,8 +241,8 @@ message TGroupInfo {
optional uint32 LifeCyclePhase = 6;
optional uint64 AllocatedSize = 7;
optional uint64 AvailableSize = 8;
- reserved 9;
- reserved 10;
+ reserved 9;
+ reserved 10;
optional bool SeenOperational = 11;
optional string ErasureSpeciesV2 = 12;
optional uint64 PutTabletLogLatency = 13;
@@ -289,8 +289,8 @@ message TStoragePoolInfo {
optional uint64 PathId = 9;
optional string ErasureSpeciesV2 = 10;
optional string VDiskKindV2 = 12;
- optional string PDiskFilter = 13;
- optional bytes PDiskFilterData = 14;
+ optional string PDiskFilter = 13;
+ optional bytes PDiskFilterData = 14;
// metrics ?
}
@@ -311,25 +311,25 @@ message TEvGetStoragePoolsResponse {
repeated TStoragePoolEntry Entries = 1;
}
-message TStorageStatsEntry {
- reserved 1;
- optional string PDiskFilter = 2;
- optional string ErasureSpecies = 3;
- optional uint32 CurrentGroupsCreated = 4;
- optional uint64 CurrentAllocatedSize = 5;
- optional uint64 CurrentAvailableSize = 6;
- optional uint32 AvailableGroupsToCreate = 7;
- optional uint64 AvailableSizeToCreate = 8; // total space of newly created groups, if they would've been created
- optional bytes PDiskFilterData = 9;
-}
-
-message TEvGetStorageStatsRequest {
-}
-
-message TEvGetStorageStatsResponse {
- repeated TStorageStatsEntry Entries = 1;
-}
-
+message TStorageStatsEntry {
+ reserved 1;
+ optional string PDiskFilter = 2;
+ optional string ErasureSpecies = 3;
+ optional uint32 CurrentGroupsCreated = 4;
+ optional uint64 CurrentAllocatedSize = 5;
+ optional uint64 CurrentAvailableSize = 6;
+ optional uint32 AvailableGroupsToCreate = 7;
+ optional uint64 AvailableSizeToCreate = 8; // total space of newly created groups, if they would've been created
+ optional bytes PDiskFilterData = 9;
+}
+
+message TEvGetStorageStatsRequest {
+}
+
+message TEvGetStorageStatsResponse {
+ repeated TStorageStatsEntry Entries = 1;
+}
+
message TTabletEntry {
optional fixed64 TabletId = 1;
optional uint32 FollowerId = 2;
diff --git a/ydb/core/protos/tablet.proto b/ydb/core/protos/tablet.proto
index f0bec238e78..96771299398 100644
--- a/ydb/core/protos/tablet.proto
+++ b/ydb/core/protos/tablet.proto
@@ -43,7 +43,7 @@ message TTabletTypes {
FileStore = 33;
OlapShard = 34;
ColumnShard = 35;
- TestShard = 36;
+ TestShard = 36;
SequenceShard = 37;
ReplicationController = 38;
@@ -51,7 +51,7 @@ message TTabletTypes {
// rename existing reserved item to desired one, and add new reserved item to
// the end of reserved list
Reserved39 = 39;
- Reserved40 = 40;
+ Reserved40 = 40;
Reserved41 = 41;
Reserved42 = 42;
diff --git a/ydb/core/protos/tablet_pipe.proto b/ydb/core/protos/tablet_pipe.proto
index e1fd3769f84..be846544ee0 100644
--- a/ydb/core/protos/tablet_pipe.proto
+++ b/ydb/core/protos/tablet_pipe.proto
@@ -28,7 +28,7 @@ message TEvPush {
optional NActorsProto.TActorId Sender = 3;
optional bytes Buffer = 4;
optional uint64 Cookie = 5;
- optional bool ExtendedFormat = 6;
+ optional bool ExtendedFormat = 6;
optional uint64 SeqNo = 7;
};
diff --git a/ydb/core/protos/tenant_slot_broker.proto b/ydb/core/protos/tenant_slot_broker.proto
index bccc7f7dc7b..7834fdebe5b 100644
--- a/ydb/core/protos/tenant_slot_broker.proto
+++ b/ydb/core/protos/tenant_slot_broker.proto
@@ -11,8 +11,8 @@ message TSlotAllocation {
// Empty string means any node type.
optional string Type = 1;
// If data center is 0 then any data center may be used.
- optional uint64 DataCenterNum = 2;
- optional string DataCenter = 7;
+ optional uint64 DataCenterNum = 2;
+ optional string DataCenter = 7;
optional uint64 Count = 3;
// This flag defines behaviour in case there are no free slots
// available in required data center. Forced location means slot
diff --git a/ydb/core/protos/test_shard.proto b/ydb/core/protos/test_shard.proto
index 51c9d717235..93e018cd207 100644
--- a/ydb/core/protos/test_shard.proto
+++ b/ydb/core/protos/test_shard.proto
@@ -1,61 +1,61 @@
-syntax = "proto3";
-
-package NTestShard;
-
-message TStateServer {
- enum EEntityState {
- ABSENT = 0;
- WRITE_PENDING = 1;
- CONFIRMED = 2;
- DELETE_PENDING = 3;
- DELETED = 4;
- }
-
- enum EStatus {
- OK = 0;
- ERROR = 1;
- RACE = 2;
- }
-
- message TWrite { // transition between two states
- uint64 TabletId = 1;
- uint32 Generation = 2;
- string Key = 3;
- EEntityState OriginState = 4;
- EEntityState TargetState = 5;
- }
-
- message TWriteResult {
- EStatus Status = 1;
- }
-
- message TRead {
- uint64 TabletId = 1;
- uint32 Generation = 2;
- bytes Cookie = 3; // returned from previous read result or empty for new query
- }
-
- message TReadResult {
- message TItem {
- string Key = 1;
- EEntityState State = 2;
- }
-
- EStatus Status = 1;
- bytes Cookie = 2;
- repeated TItem Items = 3;
- }
-
- message TTabletInfo {
- uint64 TabletId = 1;
- uint32 Generation = 2;
- }
-
- message TRequest {
- oneof Command {
- TWrite Write = 1;
- TRead Read = 2;
- TTabletInfo TabletInfo = 3; // recovery log only
- }
- }
-}
+syntax = "proto3";
+
+package NTestShard;
+
+message TStateServer {
+ enum EEntityState {
+ ABSENT = 0;
+ WRITE_PENDING = 1;
+ CONFIRMED = 2;
+ DELETE_PENDING = 3;
+ DELETED = 4;
+ }
+
+ enum EStatus {
+ OK = 0;
+ ERROR = 1;
+ RACE = 2;
+ }
+
+ message TWrite { // transition between two states
+ uint64 TabletId = 1;
+ uint32 Generation = 2;
+ string Key = 3;
+ EEntityState OriginState = 4;
+ EEntityState TargetState = 5;
+ }
+
+ message TWriteResult {
+ EStatus Status = 1;
+ }
+
+ message TRead {
+ uint64 TabletId = 1;
+ uint32 Generation = 2;
+ bytes Cookie = 3; // returned from previous read result or empty for new query
+ }
+
+ message TReadResult {
+ message TItem {
+ string Key = 1;
+ EEntityState State = 2;
+ }
+
+ EStatus Status = 1;
+ bytes Cookie = 2;
+ repeated TItem Items = 3;
+ }
+
+ message TTabletInfo {
+ uint64 TabletId = 1;
+ uint32 Generation = 2;
+ }
+
+ message TRequest {
+ oneof Command {
+ TWrite Write = 1;
+ TRead Read = 2;
+ TTabletInfo TabletInfo = 3; // recovery log only
+ }
+ }
+}
diff --git a/ydb/core/protos/ya.make b/ydb/core/protos/ya.make
index 70bb65514cd..aa20c1d340d 100644
--- a/ydb/core/protos/ya.make
+++ b/ydb/core/protos/ya.make
@@ -18,12 +18,12 @@ SRCS(
bind_channel_storage_pool.proto
blobstorage.proto
blobstorage_controller.proto
- blobstorage_disk.proto
- blobstorage_disk_color.proto
+ blobstorage_disk.proto
+ blobstorage_disk_color.proto
blobstorage_pdisk_config.proto
blobstorage_vdisk_config.proto
- blobstorage_vdisk_internal.proto
- blobstorage_config.proto
+ blobstorage_vdisk_internal.proto
+ blobstorage_config.proto
blockstore_config.proto
filestore_config.proto
bootstrapper.proto
@@ -31,7 +31,7 @@ SRCS(
channel_purpose.proto
cms.proto
config.proto
- config_units.proto
+ config_units.proto
console.proto
console_base.proto
console_config.proto
@@ -50,7 +50,7 @@ SRCS(
counters_schemeshard.proto
counters_sequenceshard.proto
counters_sysview_processor.proto
- counters_testshard.proto
+ counters_testshard.proto
counters_tx_proxy.proto
counters_mediator.proto
counters.proto
@@ -106,7 +106,7 @@ SRCS(
tablet_tx.proto
tenant_pool.proto
tenant_slot_broker.proto
- test_shard.proto
+ test_shard.proto
tracing.proto
tablet_tracing_signals.proto
node_whiteboard.proto
@@ -117,7 +117,7 @@ SRCS(
tx_proxy.proto
tx_scheme.proto
tx_sequenceshard.proto
- pdiskfit.proto
+ pdiskfit.proto
pqconfig.proto
auth.proto
key.proto
diff --git a/ydb/core/quoter/kesus_quoter_proxy.cpp b/ydb/core/quoter/kesus_quoter_proxy.cpp
index 4d2d20691e9..7abb404fd05 100644
--- a/ydb/core/quoter/kesus_quoter_proxy.cpp
+++ b/ydb/core/quoter/kesus_quoter_proxy.cpp
@@ -479,7 +479,7 @@ private:
}
void MarkAllActiveResourcesForOfflineAllocation() {
- const TInstant now = TActivationContext::Now();
+ const TInstant now = TActivationContext::Now();
for (auto&& [path, resState] : Resources) {
Y_UNUSED(path);
if (resState->ResId != Max<ui64>() && resState->SessionIsActive) {
@@ -532,7 +532,7 @@ private:
} else {
if (activate) {
res.AverageAllocationParams = res.AllocStats.GetAverageAllocationParams();
- MarkResourceForOfflineAllocation(res, TActivationContext::Now());
+ MarkResourceForOfflineAllocation(res, TActivationContext::Now());
}
}
}
@@ -655,7 +655,7 @@ private:
"Got EvClientDestroyed with tablet %" PRIu64 ", but kesus tablet is %" PRIu64, ev->Get()->TabletId, GetKesusTabletId());
KESUS_PROXY_LOG_WARN("Disconnected from tablet");
ConnectToKesus(true);
- DisconnectTime = TActivationContext::Now();
+ DisconnectTime = TActivationContext::Now();
OfflineAllocationCookie = NextCookie++;
MarkAllActiveResourcesForOfflineAllocation();
if (Counters.Disconnects) {
@@ -699,7 +699,7 @@ private:
void Handle(NKesus::TEvKesus::TEvResourcesAllocated::TPtr& ev) {
KESUS_PROXY_LOG_TRACE("ResourcesAllocated(" << ev->Get()->Record << ")");
- const TInstant now = TActivationContext::Now();
+ const TInstant now = TActivationContext::Now();
for (const NKikimrKesus::TEvResourcesAllocated::TResourceInfo& allocatedInfo : ev->Get()->Record.GetResourcesInfo()) {
TResourceState* res = FindResource(allocatedInfo.GetResourceId());
if (!res) {
@@ -730,7 +730,7 @@ private:
}
KESUS_PROXY_LOG_TRACE("OfflineResourceAllocation(" << PrintResources(*ev->Get()) << ")");
- const TInstant now = TActivationContext::Now();
+ const TInstant now = TActivationContext::Now();
for (const TEvPrivate::TEvOfflineResourceAllocation::TResourceInfo& allocatedInfo : ev->Get()->Resources) {
TResourceState* res = FindResource(allocatedInfo.ResourceId);
if (!res) {
@@ -856,8 +856,8 @@ private:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::QUOTER_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::QUOTER_PROXY_ACTOR;
}
TKesusQuoterProxy(ui64 quoterId, const NSchemeCache::TSchemeCacheNavigate::TEntry& navEntry, const TActorId& quoterServiceId, THolder<ITabletPipeFactory> tabletPipeFactory)
diff --git a/ydb/core/quoter/quoter_service_impl.h b/ydb/core/quoter/quoter_service_impl.h
index d27ea134e19..198f7fd86d3 100644
--- a/ydb/core/quoter/quoter_service_impl.h
+++ b/ydb/core/quoter/quoter_service_impl.h
@@ -300,8 +300,8 @@ class TQuoterService : public TActorBootstrapped<TQuoterService> {
TString PrintEvent(const TEvQuota::TEvRequest::TPtr& ev);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::QUOTER_SERVICE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::QUOTER_SERVICE_ACTOR;
}
TQuoterService(const TQuoterServiceConfig &config);
diff --git a/ydb/core/security/ticket_parser.cpp b/ydb/core/security/ticket_parser.cpp
index c7d024d03dc..73779898dc2 100644
--- a/ydb/core/security/ticket_parser.cpp
+++ b/ydb/core/security/ticket_parser.cpp
@@ -557,7 +557,7 @@ class TTicketParser : public TActorBootstrapped<TTicketParser> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TICKET_PARSER_ACTOR; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::TICKET_PARSER_ACTOR; }
void StateWork(TAutoPtr<NActors::IEventHandle>& ev, const NActors::TActorContext& ctx) {
switch (ev->GetTypeRewrite()) {
diff --git a/ydb/core/sys_view/common/events.h b/ydb/core/sys_view/common/events.h
index 6e19aadc2b7..8528926b117 100644
--- a/ydb/core/sys_view/common/events.h
+++ b/ydb/core/sys_view/common/events.h
@@ -63,9 +63,9 @@ struct TEvSysView {
EvUpdateTtlStats,
- EvGetStorageStatsRequest,
- EvGetStorageStatsResponse,
-
+ EvGetStorageStatsRequest,
+ EvGetStorageStatsResponse,
+
EvEnd,
};
@@ -353,14 +353,14 @@ struct TEvSysView {
, ShardIdx(shardIdx)
{}
};
-
- struct TEvGetStorageStatsRequest
- : TEventPB<TEvGetStorageStatsRequest, NKikimrSysView::TEvGetStorageStatsRequest, EvGetStorageStatsRequest>
- {};
-
- struct TEvGetStorageStatsResponse
- : TEventPB<TEvGetStorageStatsResponse, NKikimrSysView::TEvGetStorageStatsResponse, EvGetStorageStatsResponse>
- {};
+
+ struct TEvGetStorageStatsRequest
+ : TEventPB<TEvGetStorageStatsRequest, NKikimrSysView::TEvGetStorageStatsRequest, EvGetStorageStatsRequest>
+ {};
+
+ struct TEvGetStorageStatsResponse
+ : TEventPB<TEvGetStorageStatsResponse, NKikimrSysView::TEvGetStorageStatsResponse, EvGetStorageStatsResponse>
+ {};
};
} // NSysView
diff --git a/ydb/core/sys_view/common/schema.cpp b/ydb/core/sys_view/common/schema.cpp
index 1917ea35a49..7cacf49f1d0 100644
--- a/ydb/core/sys_view/common/schema.cpp
+++ b/ydb/core/sys_view/common/schema.cpp
@@ -208,7 +208,7 @@ private:
RegisterDomainSystemView<Schema::VSlots>(VSlotsName);
RegisterDomainSystemView<Schema::Groups>(GroupsName);
RegisterDomainSystemView<Schema::StoragePools>(StoragePoolsName);
- RegisterDomainSystemView<Schema::StorageStats>(StorageStatsName);
+ RegisterDomainSystemView<Schema::StorageStats>(StorageStatsName);
RegisterDomainSystemView<Schema::Tablets>(TabletsName);
diff --git a/ydb/core/sys_view/common/schema.h b/ydb/core/sys_view/common/schema.h
index f7a4f191e13..e51502e031f 100644
--- a/ydb/core/sys_view/common/schema.h
+++ b/ydb/core/sys_view/common/schema.h
@@ -24,7 +24,7 @@ constexpr TStringBuf PDisksName = "ds_pdisks";
constexpr TStringBuf VSlotsName = "ds_vslots";
constexpr TStringBuf GroupsName = "ds_groups";
constexpr TStringBuf StoragePoolsName = "ds_storage_pools";
-constexpr TStringBuf StorageStatsName = "ds_storage_stats";
+constexpr TStringBuf StorageStatsName = "ds_storage_stats";
constexpr TStringBuf TabletsName = "hive_tablets";
@@ -187,10 +187,10 @@ struct Schema : NIceDb::Schema {
struct AvailableSize : Column<10, NScheme::NTypeIds::Uint64> {};
struct TotalSize : Column<11, NScheme::NTypeIds::Uint64> {};
struct Status : Column<12, NScheme::NTypeIds::String> {};
- //struct StopFactor : Column<13, NScheme::NTypeIds::Double> {};
- struct StatusChangeTimestamp : Column<14, NScheme::NTypeIds::Timestamp> {};
- struct ExpectedSlotCount : Column<15, NScheme::NTypeIds::Uint32> {};
- struct NumActiveSlots : Column<16, NScheme::NTypeIds::Uint32> {};
+ //struct StopFactor : Column<13, NScheme::NTypeIds::Double> {};
+ struct StatusChangeTimestamp : Column<14, NScheme::NTypeIds::Timestamp> {};
+ struct ExpectedSlotCount : Column<15, NScheme::NTypeIds::Uint32> {};
+ struct NumActiveSlots : Column<16, NScheme::NTypeIds::Uint32> {};
using TKey = TableKey<NodeId, PDiskId>;
using TColumns = TableColumns<
@@ -205,10 +205,10 @@ struct Schema : NIceDb::Schema {
ReadCentric,
AvailableSize,
TotalSize,
- Status,
- StatusChangeTimestamp,
- ExpectedSlotCount,
- NumActiveSlots>;
+ Status,
+ StatusChangeTimestamp,
+ ExpectedSlotCount,
+ NumActiveSlots>;
};
struct VSlots : Table<5> {
@@ -224,7 +224,7 @@ struct Schema : NIceDb::Schema {
struct AllocatedSize : Column<10, NScheme::NTypeIds::Uint64> {};
struct AvailableSize : Column<11, NScheme::NTypeIds::Uint64> {};
struct Status : Column<12, NScheme::NTypeIds::String> {};
- //struct StopFactor : Column<13, NScheme::NTypeIds::Double> {};
+ //struct StopFactor : Column<13, NScheme::NTypeIds::Double> {};
struct Kind : Column<14, NScheme::NTypeIds::String> {};
struct FailRealm : Column<15, NScheme::NTypeIds::Uint32> {};
@@ -254,8 +254,8 @@ struct Schema : NIceDb::Schema {
struct LifeCyclePhase : Column<7, NScheme::NTypeIds::Uint32> {};
struct AllocatedSize : Column<8, NScheme::NTypeIds::Uint64> {};
struct AvailableSize : Column<9, NScheme::NTypeIds::Uint64> {};
- //struct Usage : Column<10, NScheme::NTypeIds::Double> {};
- //struct StopFactor : Column<11, NScheme::NTypeIds::Double> {};
+ //struct Usage : Column<10, NScheme::NTypeIds::Double> {};
+ //struct StopFactor : Column<11, NScheme::NTypeIds::Double> {};
struct SeenOperational : Column<12, NScheme::NTypeIds::Bool> {};
struct PutTabletLogLatency : Column<13, NScheme::NTypeIds::Interval> {};
struct PutUserDataLatency : Column<14, NScheme::NTypeIds::Interval> {};
@@ -404,20 +404,20 @@ struct Schema : NIceDb::Schema {
Portions,
Blobs>;
};
-
- struct StorageStats : Table<11> {
- struct PDiskFilter : Column<2, NScheme::NTypeIds::Utf8> {};
- struct ErasureSpecies : Column<3, NScheme::NTypeIds::Utf8> {};
- struct CurrentGroupsCreated : Column<4, NScheme::NTypeIds::Uint32> {};
- struct CurrentAllocatedSize : Column<5, NScheme::NTypeIds::Uint64> {};
- struct CurrentAvailableSize : Column<6, NScheme::NTypeIds::Uint64> {};
- struct AvailableGroupsToCreate : Column<7, NScheme::NTypeIds::Uint32> {};
- struct AvailableSizeToCreate : Column<8, NScheme::NTypeIds::Uint64> {};
-
- using TKey = TableKey<PDiskFilter, ErasureSpecies>;
- using TColumns = TableColumns<PDiskFilter, ErasureSpecies, CurrentGroupsCreated, CurrentAllocatedSize,
- CurrentAvailableSize, AvailableGroupsToCreate, AvailableSizeToCreate>;
- };
+
+ struct StorageStats : Table<11> {
+ struct PDiskFilter : Column<2, NScheme::NTypeIds::Utf8> {};
+ struct ErasureSpecies : Column<3, NScheme::NTypeIds::Utf8> {};
+ struct CurrentGroupsCreated : Column<4, NScheme::NTypeIds::Uint32> {};
+ struct CurrentAllocatedSize : Column<5, NScheme::NTypeIds::Uint64> {};
+ struct CurrentAvailableSize : Column<6, NScheme::NTypeIds::Uint64> {};
+ struct AvailableGroupsToCreate : Column<7, NScheme::NTypeIds::Uint32> {};
+ struct AvailableSizeToCreate : Column<8, NScheme::NTypeIds::Uint64> {};
+
+ using TKey = TableKey<PDiskFilter, ErasureSpecies>;
+ using TColumns = TableColumns<PDiskFilter, ErasureSpecies, CurrentGroupsCreated, CurrentAllocatedSize,
+ CurrentAvailableSize, AvailableGroupsToCreate, AvailableSizeToCreate>;
+ };
};
bool MaybeSystemViewPath(const TVector<TString>& path);
diff --git a/ydb/core/sys_view/scan.cpp b/ydb/core/sys_view/scan.cpp
index f337cb6ba77..09f5c742433 100644
--- a/ydb/core/sys_view/scan.cpp
+++ b/ydb/core/sys_view/scan.cpp
@@ -54,10 +54,10 @@ THolder<IActor> CreateSystemViewScan(const TActorId& ownerId, ui32 scanId, const
return CreateStoragePoolsScan(ownerId, scanId, tableId, tableRange, columns);
}
- if (tableId.SysViewInfo == StorageStatsName) {
- return CreateStorageStatsScan(ownerId, scanId, tableId, tableRange, columns);
- }
-
+ if (tableId.SysViewInfo == StorageStatsName) {
+ return CreateStorageStatsScan(ownerId, scanId, tableId, tableRange, columns);
+ }
+
if (tableId.SysViewInfo == TabletsName) {
return CreateTabletsScan(ownerId, scanId, tableId, tableRange, columns);
}
diff --git a/ydb/core/sys_view/storage/base.h b/ydb/core/sys_view/storage/base.h
index 649d08482c1..d7eed40e920 100644
--- a/ydb/core/sys_view/storage/base.h
+++ b/ydb/core/sys_view/storage/base.h
@@ -1,195 +1,195 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/sys_view/common/events.h>
#include <ydb/core/sys_view/common/keys.h>
#include <ydb/core/sys_view/common/schema.h>
#include <ydb/core/sys_view/common/scan_actor_base_impl.h>
#include <ydb/core/base/tablet_pipecache.h>
-
+
#include <ydb/library/yql/dq/actors/compute/dq_compute_actor.h>
-
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <library/cpp/actors/core/hfunc.h>
-
-namespace NKikimr::NSysView {
-
- template<typename TDerived, typename TEvResponse>
- class TStorageScanBase : public TScanActorBase<TStorageScanBase<TDerived, TEvResponse>> {
- using TBase = TScanActorBase<TStorageScanBase<TDerived, TEvResponse>>;
-
- public:
- using TScanActorBase<TStorageScanBase>::TScanActorBase;
-
- STRICT_STFUNC(StateScan,
- hFunc(NKqp::TEvKqpCompute::TEvScanDataAck, Handle);
- hFunc(TEvResponse, Handle);
- hFunc(TEvPipeCache::TEvDeliveryProblem, Handle);
- hFunc(NKqp::TEvKqp::TEvAbortExecution, TBase::HandleAbortExecution);
- cFunc(TEvents::TEvWakeup::EventType, TBase::HandleTimeout);
- cFunc(TEvents::TEvPoison::EventType, PassAway);
- )
-
- protected:
- using TFieldMap = std::unordered_map<NTable::TTag, std::vector<int>>;
-
- private:
- void ProceedToScan() override {
- TBase::Become(&TStorageScanBase::StateScan);
- if (TBase::AckReceived) {
- StartScan();
- }
- }
-
- void StartScan() {
- ui64 bsControllerId = TBase::GetBSControllerId();
- if (!bsControllerId) {
- return;
- }
-
- auto pipeCache = MakePipePeNodeCacheID(false);
- TBase::Send(pipeCache, new TEvPipeCache::TEvForward(static_cast<TDerived&>(*this).CreateQuery(),
- bsControllerId, true), IEventHandle::FlagTrackDelivery);
- }
-
- void Handle(NKqp::TEvKqpCompute::TEvScanDataAck::TPtr&) {
- StartScan();
- }
-
- void Handle(TEvPipeCache::TEvDeliveryProblem::TPtr&) {
- TBase::ReplyErrorAndDie(Ydb::StatusIds::UNAVAILABLE, TStringBuilder() << "Delivery problem in NSysView::"
- << static_cast<TDerived&>(*this).GetName());
- }
-
- template<typename TTo, typename TFrom>
- TCell Convert(const TFrom& value) {
- const TTo tmp(value);
- Y_VERIFY_DEBUG(TFrom(tmp) == value);
- return TCell::Make<TTo>(tmp);
- }
-
- template<typename T>
- TCell MakeCellFrom(const T& value, NScheme::TTypeId type) {
- switch (type) {
- case NScheme::NTypeIds::Int32: return Convert<i32>(value);
- case NScheme::NTypeIds::Uint32: return Convert<ui32>(value);
- case NScheme::NTypeIds::Int64: return Convert<i64>(value);
- case NScheme::NTypeIds::Uint64: return Convert<ui64>(value);
- case NScheme::NTypeIds::Bool: return Convert<bool>(value);
- case NScheme::NTypeIds::Int8: return Convert<i8>(value);
- case NScheme::NTypeIds::Uint8: return Convert<ui8>(value);
- case NScheme::NTypeIds::Int16: return Convert<i16>(value);
- case NScheme::NTypeIds::Uint16: return Convert<ui16>(value);
- case NScheme::NTypeIds::Double: return Convert<double>(value);
- case NScheme::NTypeIds::Float: return Convert<float>(value);
- case NScheme::NTypeIds::Interval: return Convert<i64>(value);
- case NScheme::NTypeIds::Timestamp: return Convert<ui64>(value);
- default: Y_FAIL();
- }
- }
-
- TCell MakeCellFrom(const TString& value, NScheme::TTypeId type) {
- Y_VERIFY(type == NScheme::NTypeIds::String || type == NScheme::NTypeIds::String4k ||
- NScheme::NTypeIds::String2m || type == NScheme::NTypeIds::Utf8);
- return TCell(value.data(), value.size());
- }
-
- TCell ExtractCell(const NProtoBuf::Message *m, const NProtoBuf::FieldDescriptor *f, NScheme::TTypeId type) {
- const NProtoBuf::Reflection *r = m->GetReflection();
- if (!r->HasField(*m, f)) {
- return TCell();
- }
-
- using E = NProtoBuf::FieldDescriptor::Type;
- switch (f->type()) {
- case E::TYPE_DOUBLE:
- return MakeCellFrom(r->GetDouble(*m, f), type);
-
- case E::TYPE_FLOAT:
- return MakeCellFrom(r->GetFloat(*m, f), type);
-
- case E::TYPE_INT64:
- case E::TYPE_SFIXED64:
- case E::TYPE_SINT64:
- return MakeCellFrom(r->GetInt64(*m, f), type);
-
- case E::TYPE_INT32:
- case E::TYPE_SFIXED32:
- case E::TYPE_SINT32:
- return MakeCellFrom(r->GetInt32(*m, f), type);
-
- case E::TYPE_UINT64:
- case E::TYPE_FIXED64:
- return MakeCellFrom(r->GetUInt64(*m, f), type);
-
- case E::TYPE_UINT32:
- case E::TYPE_FIXED32:
- return MakeCellFrom(r->GetUInt32(*m, f), type);
-
- case E::TYPE_BOOL:
- return MakeCellFrom(r->GetBool(*m, f), type);
-
- case E::TYPE_STRING:
- case E::TYPE_BYTES: {
- TString str;
- const TString& res = r->GetStringReference(*m, f, &str);
- if (&res == &str) {
- OwnedStringWarehouse.push_back(std::move(str));
- return MakeCellFrom(OwnedStringWarehouse.back(), type);
- } else {
- return MakeCellFrom(res, type);
- }
- }
-
- case E::TYPE_GROUP:
- case E::TYPE_MESSAGE:
- case E::TYPE_ENUM:
- Y_FAIL();
- }
- }
-
- void Handle(typename TEvResponse::TPtr& ev) {
- const auto& record = ev->Get()->Record;
- auto batch = MakeHolder<NKqp::TEvKqpCompute::TEvScanData>(TBase::ScanId);
-
- const auto& fieldMap = TDerived::GetFieldMap();
- TVector<TCell> cells;
- for (const auto& entry : record.GetEntries()) {
- for (auto column : TBase::Columns) {
- if (const auto it = fieldMap.find(column.Tag); it != fieldMap.end()) {
- const auto& path = it->second;
- const NProtoBuf::Message *m = &entry;
- for (auto it = path.begin(); it != path.end(); ++it) {
- const NProtoBuf::Descriptor *desc = m->GetDescriptor();
- const NProtoBuf::FieldDescriptor *fdesc = desc->FindFieldByNumber(*it);
- if (std::next(it) == path.end()) { // terminal entry
- cells.push_back(ExtractCell(m, fdesc, column.Type));
- } else { // submessage
- Y_VERIFY(fdesc->type() == NProtoBuf::FieldDescriptor::TYPE_MESSAGE);
- m = &m->GetReflection()->GetMessage(*m, fdesc);
- }
- }
- } else {
- cells.emplace_back();
- }
- }
-
- TArrayRef<const TCell> ref(cells);
- batch->Rows.emplace_back(TOwnedCellVec::Make(ref));
- cells.clear();
- }
-
- batch->Finished = true;
- TBase::SendBatch(std::move(batch));
- }
-
- void PassAway() override {
- TBase::Send(MakePipePeNodeCacheID(false), new TEvPipeCache::TEvUnlink(0));
- TBase::PassAway();
- }
-
- private:
- std::deque<TString> OwnedStringWarehouse;
- };
-
-} // NKikimr::NSysView
+
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/interconnect/interconnect.h>
+#include <library/cpp/actors/core/hfunc.h>
+
+namespace NKikimr::NSysView {
+
+ template<typename TDerived, typename TEvResponse>
+ class TStorageScanBase : public TScanActorBase<TStorageScanBase<TDerived, TEvResponse>> {
+ using TBase = TScanActorBase<TStorageScanBase<TDerived, TEvResponse>>;
+
+ public:
+ using TScanActorBase<TStorageScanBase>::TScanActorBase;
+
+ STRICT_STFUNC(StateScan,
+ hFunc(NKqp::TEvKqpCompute::TEvScanDataAck, Handle);
+ hFunc(TEvResponse, Handle);
+ hFunc(TEvPipeCache::TEvDeliveryProblem, Handle);
+ hFunc(NKqp::TEvKqp::TEvAbortExecution, TBase::HandleAbortExecution);
+ cFunc(TEvents::TEvWakeup::EventType, TBase::HandleTimeout);
+ cFunc(TEvents::TEvPoison::EventType, PassAway);
+ )
+
+ protected:
+ using TFieldMap = std::unordered_map<NTable::TTag, std::vector<int>>;
+
+ private:
+ void ProceedToScan() override {
+ TBase::Become(&TStorageScanBase::StateScan);
+ if (TBase::AckReceived) {
+ StartScan();
+ }
+ }
+
+ void StartScan() {
+ ui64 bsControllerId = TBase::GetBSControllerId();
+ if (!bsControllerId) {
+ return;
+ }
+
+ auto pipeCache = MakePipePeNodeCacheID(false);
+ TBase::Send(pipeCache, new TEvPipeCache::TEvForward(static_cast<TDerived&>(*this).CreateQuery(),
+ bsControllerId, true), IEventHandle::FlagTrackDelivery);
+ }
+
+ void Handle(NKqp::TEvKqpCompute::TEvScanDataAck::TPtr&) {
+ StartScan();
+ }
+
+ void Handle(TEvPipeCache::TEvDeliveryProblem::TPtr&) {
+ TBase::ReplyErrorAndDie(Ydb::StatusIds::UNAVAILABLE, TStringBuilder() << "Delivery problem in NSysView::"
+ << static_cast<TDerived&>(*this).GetName());
+ }
+
+ template<typename TTo, typename TFrom>
+ TCell Convert(const TFrom& value) {
+ const TTo tmp(value);
+ Y_VERIFY_DEBUG(TFrom(tmp) == value);
+ return TCell::Make<TTo>(tmp);
+ }
+
+ template<typename T>
+ TCell MakeCellFrom(const T& value, NScheme::TTypeId type) {
+ switch (type) {
+ case NScheme::NTypeIds::Int32: return Convert<i32>(value);
+ case NScheme::NTypeIds::Uint32: return Convert<ui32>(value);
+ case NScheme::NTypeIds::Int64: return Convert<i64>(value);
+ case NScheme::NTypeIds::Uint64: return Convert<ui64>(value);
+ case NScheme::NTypeIds::Bool: return Convert<bool>(value);
+ case NScheme::NTypeIds::Int8: return Convert<i8>(value);
+ case NScheme::NTypeIds::Uint8: return Convert<ui8>(value);
+ case NScheme::NTypeIds::Int16: return Convert<i16>(value);
+ case NScheme::NTypeIds::Uint16: return Convert<ui16>(value);
+ case NScheme::NTypeIds::Double: return Convert<double>(value);
+ case NScheme::NTypeIds::Float: return Convert<float>(value);
+ case NScheme::NTypeIds::Interval: return Convert<i64>(value);
+ case NScheme::NTypeIds::Timestamp: return Convert<ui64>(value);
+ default: Y_FAIL();
+ }
+ }
+
+ TCell MakeCellFrom(const TString& value, NScheme::TTypeId type) {
+ Y_VERIFY(type == NScheme::NTypeIds::String || type == NScheme::NTypeIds::String4k ||
+ NScheme::NTypeIds::String2m || type == NScheme::NTypeIds::Utf8);
+ return TCell(value.data(), value.size());
+ }
+
+ TCell ExtractCell(const NProtoBuf::Message *m, const NProtoBuf::FieldDescriptor *f, NScheme::TTypeId type) {
+ const NProtoBuf::Reflection *r = m->GetReflection();
+ if (!r->HasField(*m, f)) {
+ return TCell();
+ }
+
+ using E = NProtoBuf::FieldDescriptor::Type;
+ switch (f->type()) {
+ case E::TYPE_DOUBLE:
+ return MakeCellFrom(r->GetDouble(*m, f), type);
+
+ case E::TYPE_FLOAT:
+ return MakeCellFrom(r->GetFloat(*m, f), type);
+
+ case E::TYPE_INT64:
+ case E::TYPE_SFIXED64:
+ case E::TYPE_SINT64:
+ return MakeCellFrom(r->GetInt64(*m, f), type);
+
+ case E::TYPE_INT32:
+ case E::TYPE_SFIXED32:
+ case E::TYPE_SINT32:
+ return MakeCellFrom(r->GetInt32(*m, f), type);
+
+ case E::TYPE_UINT64:
+ case E::TYPE_FIXED64:
+ return MakeCellFrom(r->GetUInt64(*m, f), type);
+
+ case E::TYPE_UINT32:
+ case E::TYPE_FIXED32:
+ return MakeCellFrom(r->GetUInt32(*m, f), type);
+
+ case E::TYPE_BOOL:
+ return MakeCellFrom(r->GetBool(*m, f), type);
+
+ case E::TYPE_STRING:
+ case E::TYPE_BYTES: {
+ TString str;
+ const TString& res = r->GetStringReference(*m, f, &str);
+ if (&res == &str) {
+ OwnedStringWarehouse.push_back(std::move(str));
+ return MakeCellFrom(OwnedStringWarehouse.back(), type);
+ } else {
+ return MakeCellFrom(res, type);
+ }
+ }
+
+ case E::TYPE_GROUP:
+ case E::TYPE_MESSAGE:
+ case E::TYPE_ENUM:
+ Y_FAIL();
+ }
+ }
+
+ void Handle(typename TEvResponse::TPtr& ev) {
+ const auto& record = ev->Get()->Record;
+ auto batch = MakeHolder<NKqp::TEvKqpCompute::TEvScanData>(TBase::ScanId);
+
+ const auto& fieldMap = TDerived::GetFieldMap();
+ TVector<TCell> cells;
+ for (const auto& entry : record.GetEntries()) {
+ for (auto column : TBase::Columns) {
+ if (const auto it = fieldMap.find(column.Tag); it != fieldMap.end()) {
+ const auto& path = it->second;
+ const NProtoBuf::Message *m = &entry;
+ for (auto it = path.begin(); it != path.end(); ++it) {
+ const NProtoBuf::Descriptor *desc = m->GetDescriptor();
+ const NProtoBuf::FieldDescriptor *fdesc = desc->FindFieldByNumber(*it);
+ if (std::next(it) == path.end()) { // terminal entry
+ cells.push_back(ExtractCell(m, fdesc, column.Type));
+ } else { // submessage
+ Y_VERIFY(fdesc->type() == NProtoBuf::FieldDescriptor::TYPE_MESSAGE);
+ m = &m->GetReflection()->GetMessage(*m, fdesc);
+ }
+ }
+ } else {
+ cells.emplace_back();
+ }
+ }
+
+ TArrayRef<const TCell> ref(cells);
+ batch->Rows.emplace_back(TOwnedCellVec::Make(ref));
+ cells.clear();
+ }
+
+ batch->Finished = true;
+ TBase::SendBatch(std::move(batch));
+ }
+
+ void PassAway() override {
+ TBase::Send(MakePipePeNodeCacheID(false), new TEvPipeCache::TEvUnlink(0));
+ TBase::PassAway();
+ }
+
+ private:
+ std::deque<TString> OwnedStringWarehouse;
+ };
+
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/groups.cpp b/ydb/core/sys_view/storage/groups.cpp
index dabd46f9dc7..7a410e738ef 100644
--- a/ydb/core/sys_view/storage/groups.cpp
+++ b/ydb/core/sys_view/storage/groups.cpp
@@ -1,43 +1,43 @@
-#include "groups.h"
-#include "base.h"
+#include "groups.h"
+#include "base.h"
-namespace NKikimr::NSysView {
+namespace NKikimr::NSysView {
-template<> void SetField<0>(NKikimrSysView::TGroupKey& key, ui32 value) { key.SetGroupId(value); }
+template<> void SetField<0>(NKikimrSysView::TGroupKey& key, ui32 value) { key.SetGroupId(value); }
-class TGroupsScan : public TStorageScanBase<TGroupsScan, TEvSysView::TEvGetGroupsResponse> {
+class TGroupsScan : public TStorageScanBase<TGroupsScan, TEvSysView::TEvGetGroupsResponse> {
public:
- using TStorageScanBase::TStorageScanBase;
+ using TStorageScanBase::TStorageScanBase;
- static constexpr const char *GetName() { return "TGroupsScan"; }
+ static constexpr const char *GetName() { return "TGroupsScan"; }
- TEvSysView::TEvGetGroupsRequest *CreateQuery() {
+ TEvSysView::TEvGetGroupsRequest *CreateQuery() {
auto request = MakeHolder<TEvSysView::TEvGetGroupsRequest>();
ConvertKeyRange<NKikimrSysView::TEvGetGroupsRequest, ui32>(request->Record, TableRange);
- return request.Release();
+ return request.Release();
}
- static const TFieldMap& GetFieldMap() {
- using T = Schema::Groups;
- using E = NKikimrSysView::TGroupEntry;
- using K = NKikimrSysView::TGroupKey;
- using V = NKikimrSysView::TGroupInfo;
- static TFieldMap fieldMap{
- {T::GroupId::ColumnId, {E::kKeyFieldNumber, K::kGroupIdFieldNumber}},
- {T::Generation::ColumnId, {E::kInfoFieldNumber, V::kGenerationFieldNumber}},
- {T::ErasureSpecies::ColumnId, {E::kInfoFieldNumber, V::kErasureSpeciesV2FieldNumber}},
- {T::BoxId::ColumnId, {E::kInfoFieldNumber, V::kBoxIdFieldNumber}},
- {T::StoragePoolId::ColumnId, {E::kInfoFieldNumber, V::kStoragePoolIdFieldNumber}},
- {T::EncryptionMode::ColumnId, {E::kInfoFieldNumber, V::kEncryptionModeFieldNumber}},
- {T::LifeCyclePhase::ColumnId, {E::kInfoFieldNumber, V::kLifeCyclePhaseFieldNumber}},
- {T::AllocatedSize::ColumnId, {E::kInfoFieldNumber, V::kAllocatedSizeFieldNumber}},
- {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
- {T::SeenOperational::ColumnId, {E::kInfoFieldNumber, V::kSeenOperationalFieldNumber}},
- {T::PutTabletLogLatency::ColumnId, {E::kInfoFieldNumber, V::kPutTabletLogLatencyFieldNumber}},
- {T::PutUserDataLatency::ColumnId, {E::kInfoFieldNumber, V::kPutUserDataLatencyFieldNumber}},
- {T::GetFastLatency::ColumnId, {E::kInfoFieldNumber, V::kGetFastLatencyFieldNumber}},
+ static const TFieldMap& GetFieldMap() {
+ using T = Schema::Groups;
+ using E = NKikimrSysView::TGroupEntry;
+ using K = NKikimrSysView::TGroupKey;
+ using V = NKikimrSysView::TGroupInfo;
+ static TFieldMap fieldMap{
+ {T::GroupId::ColumnId, {E::kKeyFieldNumber, K::kGroupIdFieldNumber}},
+ {T::Generation::ColumnId, {E::kInfoFieldNumber, V::kGenerationFieldNumber}},
+ {T::ErasureSpecies::ColumnId, {E::kInfoFieldNumber, V::kErasureSpeciesV2FieldNumber}},
+ {T::BoxId::ColumnId, {E::kInfoFieldNumber, V::kBoxIdFieldNumber}},
+ {T::StoragePoolId::ColumnId, {E::kInfoFieldNumber, V::kStoragePoolIdFieldNumber}},
+ {T::EncryptionMode::ColumnId, {E::kInfoFieldNumber, V::kEncryptionModeFieldNumber}},
+ {T::LifeCyclePhase::ColumnId, {E::kInfoFieldNumber, V::kLifeCyclePhaseFieldNumber}},
+ {T::AllocatedSize::ColumnId, {E::kInfoFieldNumber, V::kAllocatedSizeFieldNumber}},
+ {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
+ {T::SeenOperational::ColumnId, {E::kInfoFieldNumber, V::kSeenOperationalFieldNumber}},
+ {T::PutTabletLogLatency::ColumnId, {E::kInfoFieldNumber, V::kPutTabletLogLatencyFieldNumber}},
+ {T::PutUserDataLatency::ColumnId, {E::kInfoFieldNumber, V::kPutUserDataLatencyFieldNumber}},
+ {T::GetFastLatency::ColumnId, {E::kInfoFieldNumber, V::kGetFastLatencyFieldNumber}},
};
- return fieldMap;
+ return fieldMap;
}
};
@@ -47,4 +47,4 @@ THolder<IActor> CreateGroupsScan(const TActorId& ownerId, ui32 scanId, const TTa
return MakeHolder<TGroupsScan>(ownerId, scanId, tableId, tableRange, columns);
}
-} // NKikimr::NSysView
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/pdisks.cpp b/ydb/core/sys_view/storage/pdisks.cpp
index 47f84ae9aa5..51f0f28e170 100644
--- a/ydb/core/sys_view/storage/pdisks.cpp
+++ b/ydb/core/sys_view/storage/pdisks.cpp
@@ -1,46 +1,46 @@
#include "pdisks.h"
-#include "base.h"
+#include "base.h"
-namespace NKikimr::NSysView {
+namespace NKikimr::NSysView {
-template<> void SetField<0>(NKikimrSysView::TPDiskKey& key, ui32 value) { key.SetNodeId(value); }
-template<> void SetField<1>(NKikimrSysView::TPDiskKey& key, ui32 value) { key.SetPDiskId(value); }
+template<> void SetField<0>(NKikimrSysView::TPDiskKey& key, ui32 value) { key.SetNodeId(value); }
+template<> void SetField<1>(NKikimrSysView::TPDiskKey& key, ui32 value) { key.SetPDiskId(value); }
-class TPDisksScan : public TStorageScanBase<TPDisksScan, TEvSysView::TEvGetPDisksResponse> {
+class TPDisksScan : public TStorageScanBase<TPDisksScan, TEvSysView::TEvGetPDisksResponse> {
public:
- using TStorageScanBase::TStorageScanBase;
+ using TStorageScanBase::TStorageScanBase;
- static constexpr const char *GetName() { return "TPDisksScan"; }
+ static constexpr const char *GetName() { return "TPDisksScan"; }
- TEvSysView::TEvGetPDisksRequest *CreateQuery() {
+ TEvSysView::TEvGetPDisksRequest *CreateQuery() {
auto request = MakeHolder<TEvSysView::TEvGetPDisksRequest>();
ConvertKeyRange<NKikimrSysView::TEvGetPDisksRequest, ui32, ui32>(request->Record, TableRange);
- return request.Release();
+ return request.Release();
}
- static const TFieldMap& GetFieldMap() {
- using T = Schema::PDisks;
- using E = NKikimrSysView::TPDiskEntry;
- using K = NKikimrSysView::TPDiskKey;
- using V = NKikimrSysView::TPDiskInfo;
- static TFieldMap fieldMap{
- {T::NodeId::ColumnId, {E::kKeyFieldNumber, K::kNodeIdFieldNumber}},
- {T::PDiskId::ColumnId, {E::kKeyFieldNumber, K::kPDiskIdFieldNumber}},
- {T::TypeCol::ColumnId, {E::kInfoFieldNumber, V::kTypeFieldNumber}},
- {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
- {T::Path::ColumnId, {E::kInfoFieldNumber, V::kPathFieldNumber}},
- {T::Guid::ColumnId, {E::kInfoFieldNumber, V::kGuidFieldNumber}},
- {T::BoxId::ColumnId, {E::kInfoFieldNumber, V::kBoxIdFieldNumber}},
- {T::SharedWithOS::ColumnId, {E::kInfoFieldNumber, V::kSharedWithOsFieldNumber}},
- {T::ReadCentric::ColumnId, {E::kInfoFieldNumber, V::kReadCentricFieldNumber}},
- {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
- {T::TotalSize::ColumnId, {E::kInfoFieldNumber, V::kTotalSizeFieldNumber}},
- {T::Status::ColumnId, {E::kInfoFieldNumber, V::kStatusV2FieldNumber}},
- {T::StatusChangeTimestamp::ColumnId, {E::kInfoFieldNumber, V::kStatusChangeTimestampFieldNumber}},
- {T::ExpectedSlotCount::ColumnId, {E::kInfoFieldNumber, V::kExpectedSlotCountFieldNumber}},
- {T::NumActiveSlots::ColumnId, {E::kInfoFieldNumber, V::kNumActiveSlotsFieldNumber}},
+ static const TFieldMap& GetFieldMap() {
+ using T = Schema::PDisks;
+ using E = NKikimrSysView::TPDiskEntry;
+ using K = NKikimrSysView::TPDiskKey;
+ using V = NKikimrSysView::TPDiskInfo;
+ static TFieldMap fieldMap{
+ {T::NodeId::ColumnId, {E::kKeyFieldNumber, K::kNodeIdFieldNumber}},
+ {T::PDiskId::ColumnId, {E::kKeyFieldNumber, K::kPDiskIdFieldNumber}},
+ {T::TypeCol::ColumnId, {E::kInfoFieldNumber, V::kTypeFieldNumber}},
+ {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
+ {T::Path::ColumnId, {E::kInfoFieldNumber, V::kPathFieldNumber}},
+ {T::Guid::ColumnId, {E::kInfoFieldNumber, V::kGuidFieldNumber}},
+ {T::BoxId::ColumnId, {E::kInfoFieldNumber, V::kBoxIdFieldNumber}},
+ {T::SharedWithOS::ColumnId, {E::kInfoFieldNumber, V::kSharedWithOsFieldNumber}},
+ {T::ReadCentric::ColumnId, {E::kInfoFieldNumber, V::kReadCentricFieldNumber}},
+ {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
+ {T::TotalSize::ColumnId, {E::kInfoFieldNumber, V::kTotalSizeFieldNumber}},
+ {T::Status::ColumnId, {E::kInfoFieldNumber, V::kStatusV2FieldNumber}},
+ {T::StatusChangeTimestamp::ColumnId, {E::kInfoFieldNumber, V::kStatusChangeTimestampFieldNumber}},
+ {T::ExpectedSlotCount::ColumnId, {E::kInfoFieldNumber, V::kExpectedSlotCountFieldNumber}},
+ {T::NumActiveSlots::ColumnId, {E::kInfoFieldNumber, V::kNumActiveSlotsFieldNumber}},
};
- return fieldMap;
+ return fieldMap;
}
};
@@ -50,4 +50,4 @@ THolder<IActor> CreatePDisksScan(const TActorId& ownerId, ui32 scanId, const TTa
return MakeHolder<TPDisksScan>(ownerId, scanId, tableId, tableRange, columns);
}
-} // NKikimr::NSysView
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/storage_pools.cpp b/ydb/core/sys_view/storage/storage_pools.cpp
index 66896a69995..2cced74faa4 100644
--- a/ydb/core/sys_view/storage/storage_pools.cpp
+++ b/ydb/core/sys_view/storage/storage_pools.cpp
@@ -1,42 +1,42 @@
-#include "storage_pools.h"
-#include "base.h"
+#include "storage_pools.h"
+#include "base.h"
-namespace NKikimr::NSysView {
+namespace NKikimr::NSysView {
-template<> void SetField<0>(NKikimrSysView::TStoragePoolKey& key, ui64 value) { key.SetBoxId(value); }
-template<> void SetField<1>(NKikimrSysView::TStoragePoolKey& key, ui64 value) { key.SetStoragePoolId(value); }
+template<> void SetField<0>(NKikimrSysView::TStoragePoolKey& key, ui64 value) { key.SetBoxId(value); }
+template<> void SetField<1>(NKikimrSysView::TStoragePoolKey& key, ui64 value) { key.SetStoragePoolId(value); }
-class TStoragePoolsScan : public TStorageScanBase<TStoragePoolsScan, TEvSysView::TEvGetStoragePoolsResponse> {
+class TStoragePoolsScan : public TStorageScanBase<TStoragePoolsScan, TEvSysView::TEvGetStoragePoolsResponse> {
public:
- using TStorageScanBase::TStorageScanBase;
+ using TStorageScanBase::TStorageScanBase;
- static constexpr const char *GetName() { return "TStoragePoolsScan"; }
+ static constexpr const char *GetName() { return "TStoragePoolsScan"; }
- TEvSysView::TEvGetStoragePoolsRequest *CreateQuery() {
+ TEvSysView::TEvGetStoragePoolsRequest *CreateQuery() {
auto request = MakeHolder<TEvSysView::TEvGetStoragePoolsRequest>();
ConvertKeyRange<NKikimrSysView::TEvGetStoragePoolsRequest, ui64, ui64>(request->Record, TableRange);
- return request.Release();
+ return request.Release();
}
- static const TFieldMap& GetFieldMap() {
- using T = Schema::StoragePools;
- using E = NKikimrSysView::TStoragePoolEntry;
- using K = NKikimrSysView::TStoragePoolKey;
- using V = NKikimrSysView::TStoragePoolInfo;
- static TFieldMap fieldMap{
- {T::BoxId::ColumnId, {E::kKeyFieldNumber, K::kBoxIdFieldNumber}},
- {T::StoragePoolId::ColumnId, {E::kKeyFieldNumber, K::kStoragePoolIdFieldNumber}},
- {T::Name::ColumnId, {E::kInfoFieldNumber, V::kNameFieldNumber}},
- {T::Generation::ColumnId, {E::kInfoFieldNumber, V::kGenerationFieldNumber}},
- {T::ErasureSpecies::ColumnId, {E::kInfoFieldNumber, V::kErasureSpeciesV2FieldNumber}},
- {T::VDiskKind::ColumnId, {E::kInfoFieldNumber, V::kVDiskKindV2FieldNumber}},
- {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
- {T::NumGroups::ColumnId, {E::kInfoFieldNumber, V::kNumGroupsFieldNumber}},
- {T::EncryptionMode::ColumnId, {E::kInfoFieldNumber, V::kEncryptionModeFieldNumber}},
- {T::SchemeshardId::ColumnId, {E::kInfoFieldNumber, V::kSchemeshardIdFieldNumber}},
- {T::PathId::ColumnId, {E::kInfoFieldNumber, V::kPathIdFieldNumber}},
+ static const TFieldMap& GetFieldMap() {
+ using T = Schema::StoragePools;
+ using E = NKikimrSysView::TStoragePoolEntry;
+ using K = NKikimrSysView::TStoragePoolKey;
+ using V = NKikimrSysView::TStoragePoolInfo;
+ static TFieldMap fieldMap{
+ {T::BoxId::ColumnId, {E::kKeyFieldNumber, K::kBoxIdFieldNumber}},
+ {T::StoragePoolId::ColumnId, {E::kKeyFieldNumber, K::kStoragePoolIdFieldNumber}},
+ {T::Name::ColumnId, {E::kInfoFieldNumber, V::kNameFieldNumber}},
+ {T::Generation::ColumnId, {E::kInfoFieldNumber, V::kGenerationFieldNumber}},
+ {T::ErasureSpecies::ColumnId, {E::kInfoFieldNumber, V::kErasureSpeciesV2FieldNumber}},
+ {T::VDiskKind::ColumnId, {E::kInfoFieldNumber, V::kVDiskKindV2FieldNumber}},
+ {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
+ {T::NumGroups::ColumnId, {E::kInfoFieldNumber, V::kNumGroupsFieldNumber}},
+ {T::EncryptionMode::ColumnId, {E::kInfoFieldNumber, V::kEncryptionModeFieldNumber}},
+ {T::SchemeshardId::ColumnId, {E::kInfoFieldNumber, V::kSchemeshardIdFieldNumber}},
+ {T::PathId::ColumnId, {E::kInfoFieldNumber, V::kPathIdFieldNumber}},
};
- return fieldMap;
+ return fieldMap;
}
};
@@ -46,4 +46,4 @@ THolder<IActor> CreateStoragePoolsScan(const TActorId& ownerId, ui32 scanId, con
return MakeHolder<TStoragePoolsScan>(ownerId, scanId, tableId, tableRange, columns);
}
-} // NKikimr::NSysView
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/storage_stats.cpp b/ydb/core/sys_view/storage/storage_stats.cpp
index 3668e797985..12b92c0d4d5 100644
--- a/ydb/core/sys_view/storage/storage_stats.cpp
+++ b/ydb/core/sys_view/storage/storage_stats.cpp
@@ -1,38 +1,38 @@
-#include "storage_stats.h"
-#include "base.h"
-
-namespace NKikimr::NSysView {
-
-class TStorageStatsScan : public TStorageScanBase<TStorageStatsScan, TEvSysView::TEvGetStorageStatsResponse> {
-public:
- using TStorageScanBase::TStorageScanBase;
-
- static constexpr const char *GetName() { return "TStorageStatsScan"; }
-
- TEvSysView::TEvGetStorageStatsRequest *CreateQuery() {
- return new TEvSysView::TEvGetStorageStatsRequest();
- }
-
- static const TFieldMap& GetFieldMap() {
- using T = Schema::StorageStats;
- using E = NKikimrSysView::TStorageStatsEntry;
- static TFieldMap fieldMap{
- {T::PDiskFilter::ColumnId, {E::kPDiskFilterFieldNumber}},
- {T::ErasureSpecies::ColumnId, {E::kErasureSpeciesFieldNumber}},
- {T::CurrentGroupsCreated::ColumnId, {E::kCurrentGroupsCreatedFieldNumber}},
- {T::CurrentAllocatedSize::ColumnId, {E::kCurrentAllocatedSizeFieldNumber}},
- {T::CurrentAvailableSize::ColumnId, {E::kCurrentAvailableSizeFieldNumber}},
- {T::AvailableGroupsToCreate::ColumnId, {E::kAvailableGroupsToCreateFieldNumber}},
- {T::AvailableSizeToCreate::ColumnId, {E::kAvailableSizeToCreateFieldNumber}},
- };
- return fieldMap;
- }
-};
-
-THolder<IActor> CreateStorageStatsScan(const TActorId& ownerId, ui32 scanId, const TTableId& tableId,
- const TTableRange& tableRange, const TArrayRef<NMiniKQL::TKqpComputeContextBase::TColumn>& columns)
-{
- return MakeHolder<TStorageStatsScan>(ownerId, scanId, tableId, tableRange, columns);
-}
-
-} // NKikimr::NSysView
+#include "storage_stats.h"
+#include "base.h"
+
+namespace NKikimr::NSysView {
+
+class TStorageStatsScan : public TStorageScanBase<TStorageStatsScan, TEvSysView::TEvGetStorageStatsResponse> {
+public:
+ using TStorageScanBase::TStorageScanBase;
+
+ static constexpr const char *GetName() { return "TStorageStatsScan"; }
+
+ TEvSysView::TEvGetStorageStatsRequest *CreateQuery() {
+ return new TEvSysView::TEvGetStorageStatsRequest();
+ }
+
+ static const TFieldMap& GetFieldMap() {
+ using T = Schema::StorageStats;
+ using E = NKikimrSysView::TStorageStatsEntry;
+ static TFieldMap fieldMap{
+ {T::PDiskFilter::ColumnId, {E::kPDiskFilterFieldNumber}},
+ {T::ErasureSpecies::ColumnId, {E::kErasureSpeciesFieldNumber}},
+ {T::CurrentGroupsCreated::ColumnId, {E::kCurrentGroupsCreatedFieldNumber}},
+ {T::CurrentAllocatedSize::ColumnId, {E::kCurrentAllocatedSizeFieldNumber}},
+ {T::CurrentAvailableSize::ColumnId, {E::kCurrentAvailableSizeFieldNumber}},
+ {T::AvailableGroupsToCreate::ColumnId, {E::kAvailableGroupsToCreateFieldNumber}},
+ {T::AvailableSizeToCreate::ColumnId, {E::kAvailableSizeToCreateFieldNumber}},
+ };
+ return fieldMap;
+ }
+};
+
+THolder<IActor> CreateStorageStatsScan(const TActorId& ownerId, ui32 scanId, const TTableId& tableId,
+ const TTableRange& tableRange, const TArrayRef<NMiniKQL::TKqpComputeContextBase::TColumn>& columns)
+{
+ return MakeHolder<TStorageStatsScan>(ownerId, scanId, tableId, tableRange, columns);
+}
+
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/storage_stats.h b/ydb/core/sys_view/storage/storage_stats.h
index 5ffe026e298..dadda201add 100644
--- a/ydb/core/sys_view/storage/storage_stats.h
+++ b/ydb/core/sys_view/storage/storage_stats.h
@@ -1,10 +1,10 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/kqp/runtime/kqp_compute.h>
-
-namespace NKikimr::NSysView {
-
-THolder<IActor> CreateStorageStatsScan(const TActorId& ownerId, ui32 scanId, const TTableId& tableId,
- const TTableRange& tableRange, const TArrayRef<NMiniKQL::TKqpComputeContextBase::TColumn>& columns);
-
-} // NKikimr::NSysView
+
+namespace NKikimr::NSysView {
+
+THolder<IActor> CreateStorageStatsScan(const TActorId& ownerId, ui32 scanId, const TTableId& tableId,
+ const TTableRange& tableRange, const TArrayRef<NMiniKQL::TKqpComputeContextBase::TColumn>& columns);
+
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/vslots.cpp b/ydb/core/sys_view/storage/vslots.cpp
index 987eb2750de..d53f0057740 100644
--- a/ydb/core/sys_view/storage/vslots.cpp
+++ b/ydb/core/sys_view/storage/vslots.cpp
@@ -1,44 +1,44 @@
#include "vslots.h"
-#include "base.h"
+#include "base.h"
-namespace NKikimr::NSysView {
+namespace NKikimr::NSysView {
-template<> void SetField<0>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetNodeId(value); }
-template<> void SetField<1>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetPDiskId(value); }
-template<> void SetField<2>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetVSlotId(value); }
+template<> void SetField<0>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetNodeId(value); }
+template<> void SetField<1>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetPDiskId(value); }
+template<> void SetField<2>(NKikimrSysView::TVSlotKey& key, ui32 value) { key.SetVSlotId(value); }
-class TVSlotsScan : public TStorageScanBase<TVSlotsScan, TEvSysView::TEvGetVSlotsResponse> {
+class TVSlotsScan : public TStorageScanBase<TVSlotsScan, TEvSysView::TEvGetVSlotsResponse> {
public:
- using TStorageScanBase::TStorageScanBase;
+ using TStorageScanBase::TStorageScanBase;
- static constexpr const char *GetName() { return "TVSlotsScan"; }
+ static constexpr const char *GetName() { return "TVSlotsScan"; }
- TEvSysView::TEvGetVSlotsRequest *CreateQuery() {
+ TEvSysView::TEvGetVSlotsRequest *CreateQuery() {
auto request = MakeHolder<TEvSysView::TEvGetVSlotsRequest>();
ConvertKeyRange<NKikimrSysView::TEvGetVSlotsRequest, ui32, ui32, ui32>(request->Record, TableRange);
- return request.Release();
+ return request.Release();
}
- static const TFieldMap& GetFieldMap() {
- using T = Schema::VSlots;
- using E = NKikimrSysView::TVSlotEntry;
- using K = NKikimrSysView::TVSlotKey;
- using V = NKikimrSysView::TVSlotInfo;
- static TFieldMap fieldMap{
- {T::NodeId::ColumnId, {E::kKeyFieldNumber, K::kNodeIdFieldNumber}},
- {T::PDiskId::ColumnId, {E::kKeyFieldNumber, K::kPDiskIdFieldNumber}},
- {T::VSlotId::ColumnId, {E::kKeyFieldNumber, K::kVSlotIdFieldNumber}},
- {T::GroupId::ColumnId, {E::kInfoFieldNumber, V::kGroupIdFieldNumber}},
- {T::GroupGeneration::ColumnId, {E::kInfoFieldNumber, V::kGroupGenerationFieldNumber}},
- {T::FailRealm::ColumnId, {E::kInfoFieldNumber, V::kFailRealmFieldNumber}},
- {T::FailDomain::ColumnId, {E::kInfoFieldNumber, V::kFailDomainFieldNumber}},
- {T::VDisk::ColumnId, {E::kInfoFieldNumber, V::kVDiskFieldNumber}},
- {T::AllocatedSize::ColumnId, {E::kInfoFieldNumber, V::kAllocatedSizeFieldNumber}},
- {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
- {T::Status::ColumnId, {E::kInfoFieldNumber, V::kStatusV2FieldNumber}},
- {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
+ static const TFieldMap& GetFieldMap() {
+ using T = Schema::VSlots;
+ using E = NKikimrSysView::TVSlotEntry;
+ using K = NKikimrSysView::TVSlotKey;
+ using V = NKikimrSysView::TVSlotInfo;
+ static TFieldMap fieldMap{
+ {T::NodeId::ColumnId, {E::kKeyFieldNumber, K::kNodeIdFieldNumber}},
+ {T::PDiskId::ColumnId, {E::kKeyFieldNumber, K::kPDiskIdFieldNumber}},
+ {T::VSlotId::ColumnId, {E::kKeyFieldNumber, K::kVSlotIdFieldNumber}},
+ {T::GroupId::ColumnId, {E::kInfoFieldNumber, V::kGroupIdFieldNumber}},
+ {T::GroupGeneration::ColumnId, {E::kInfoFieldNumber, V::kGroupGenerationFieldNumber}},
+ {T::FailRealm::ColumnId, {E::kInfoFieldNumber, V::kFailRealmFieldNumber}},
+ {T::FailDomain::ColumnId, {E::kInfoFieldNumber, V::kFailDomainFieldNumber}},
+ {T::VDisk::ColumnId, {E::kInfoFieldNumber, V::kVDiskFieldNumber}},
+ {T::AllocatedSize::ColumnId, {E::kInfoFieldNumber, V::kAllocatedSizeFieldNumber}},
+ {T::AvailableSize::ColumnId, {E::kInfoFieldNumber, V::kAvailableSizeFieldNumber}},
+ {T::Status::ColumnId, {E::kInfoFieldNumber, V::kStatusV2FieldNumber}},
+ {T::Kind::ColumnId, {E::kInfoFieldNumber, V::kKindFieldNumber}},
};
- return fieldMap;
+ return fieldMap;
}
};
@@ -48,4 +48,4 @@ THolder<IActor> CreateVSlotsScan(const TActorId& ownerId, ui32 scanId, const TTa
return MakeHolder<TVSlotsScan>(ownerId, scanId, tableId, tableRange, columns);
}
-} // NKikimr::NSysView
+} // NKikimr::NSysView
diff --git a/ydb/core/sys_view/storage/ya.make b/ydb/core/sys_view/storage/ya.make
index 324b36b7986..535d159bd1a 100644
--- a/ydb/core/sys_view/storage/ya.make
+++ b/ydb/core/sys_view/storage/ya.make
@@ -12,8 +12,8 @@ SRCS(
pdisks.cpp
storage_pools.h
storage_pools.cpp
- storage_stats.h
- storage_stats.cpp
+ storage_stats.h
+ storage_stats.cpp
vslots.h
vslots.cpp
)
diff --git a/ydb/core/sys_view/ut_kqp.cpp b/ydb/core/sys_view/ut_kqp.cpp
index 5e90eb59927..d50e1536a46 100644
--- a/ydb/core/sys_view/ut_kqp.cpp
+++ b/ydb/core/sys_view/ut_kqp.cpp
@@ -137,18 +137,18 @@ public:
RowIterator = row.begin();
}
- bool SkipNull() {
- if (RowIterator->IsNull()) {
- ++RowIterator;
- return true;
- } else {
- return false;
- }
- }
-
- void Null() {
+ bool SkipNull() {
+ if (RowIterator->IsNull()) {
+ ++RowIterator;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ void Null() {
const auto& value = *RowIterator++;
- UNIT_ASSERT(value.IsNull());
+ UNIT_ASSERT(value.IsNull());
}
void Bool(bool expected) {
@@ -157,12 +157,12 @@ public:
UNIT_ASSERT_VALUES_EQUAL(value.AsBool(), expected);
}
- void Uint64(ui64 expected, bool orNull = false) {
- if (!orNull || !SkipNull()) {
- const auto& value = ExtractOptional(*RowIterator++);
- UNIT_ASSERT(value.IsUint64());
- UNIT_ASSERT_VALUES_EQUAL(value.AsUint64(), expected);
- }
+ void Uint64(ui64 expected, bool orNull = false) {
+ if (!orNull || !SkipNull()) {
+ const auto& value = ExtractOptional(*RowIterator++);
+ UNIT_ASSERT(value.IsUint64());
+ UNIT_ASSERT_VALUES_EQUAL(value.AsUint64(), expected);
+ }
}
void Uint64Greater(ui64 expected) {
@@ -630,7 +630,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
check.String("data"); // Type
check.Uint64(0); // UpdateBytes
check.Uint64(0); // UpdateRows
- check.Null(); // UserSID
+ check.Null(); // UserSID
}
Y_UNIT_TEST(PartitionStatsTtlFields) {
@@ -880,11 +880,11 @@ Y_UNIT_TEST_SUITE(SystemView) {
ReadCentric,
SharedWithOS,
Status,
- StatusChangeTimestamp,
+ StatusChangeTimestamp,
TotalSize,
- Type,
- ExpectedSlotCount,
- NumActiveSlots
+ Type,
+ ExpectedSlotCount,
+ NumActiveSlots
FROM `/Root/.sys/ds_pdisks`;
)").GetValueSync();
@@ -900,7 +900,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
}
}
- TYsonFieldChecker check(ysonString, 15);
+ TYsonFieldChecker check(ysonString, 15);
check.Uint64(0u); // AvailableSize
check.Uint64(999u); // BoxId
@@ -912,11 +912,11 @@ Y_UNIT_TEST_SUITE(SystemView) {
check.Bool(false); // ReadCentric
check.Bool(false); // SharedWithOS
check.String("ACTIVE"); // Status
- check.Null(); // StatusChangeTimestamp
+ check.Null(); // StatusChangeTimestamp
check.Uint64(0u); // TotalSize
check.String("ROT"); // Type
- check.Uint64(16); // ExpectedSlotCount
- check.Uint64(2); // NumActiveSlots
+ check.Uint64(16); // ExpectedSlotCount
+ check.Uint64(2); // NumActiveSlots
}
Y_UNIT_TEST(VSlotsFields) {
@@ -941,7 +941,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
Status,
VDisk,
VSlotId
- FROM `/Root/.sys/ds_vslots` WHERE GroupId >= 0x80000000;
+ FROM `/Root/.sys/ds_vslots` WHERE GroupId >= 0x80000000;
)").GetValueSync();
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
@@ -956,10 +956,10 @@ Y_UNIT_TEST_SUITE(SystemView) {
}
}
- TYsonFieldChecker check(ysonString, 12);
+ TYsonFieldChecker check(ysonString, 12);
- check.Uint64(0u, true); // AllocatedSize
- check.Uint64(0u, true); // AvailableSize
+ check.Uint64(0u, true); // AllocatedSize
+ check.Uint64(0u, true); // AvailableSize
check.Uint64(0u); // FailDomain
check.Uint64(0u); // FailRealm
check.Uint64(1u); // GroupGeneration
@@ -967,7 +967,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
check.String("Default"); // Kind
check.Uint64(env.GetServer().GetRuntime()->GetNodeId(0)); // NodeId
check.Uint64(1u); // PDiskId
- check.String("INIT_PENDING"); // Status
+ check.String("INIT_PENDING"); // Status
check.Uint64(0u); // VDisk
check.Uint64(1000u); // VSlotId
}
@@ -993,8 +993,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
LifeCyclePhase,
PutTabletLogLatency,
PutUserDataLatency,
- StoragePoolId
- FROM `/Root/.sys/ds_groups` WHERE GroupId >= 0x80000000;
+ StoragePoolId
+ FROM `/Root/.sys/ds_groups` WHERE GroupId >= 0x80000000;
)").GetValueSync();
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
@@ -1009,7 +1009,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
}
}
- TYsonFieldChecker check(ysonString, 12);
+ TYsonFieldChecker check(ysonString, 12);
check.Uint64(0u); // AllocatedSize
check.Uint64(0u); // AvailableSize
@@ -1017,11 +1017,11 @@ Y_UNIT_TEST_SUITE(SystemView) {
check.Uint64(0u); // EncryptionMode
check.String("none"); // ErasureSpecies
check.Uint64(1u); // Generation
- check.Null(); // GetFastLatency
+ check.Null(); // GetFastLatency
check.Uint64(2181038080u); // GroupId
check.Uint64(0u); // LifeCyclePhase
- check.Null(); // PutTabletLogLatency
- check.Null(); // PutUserDataLatency
+ check.Null(); // PutTabletLogLatency
+ check.Null(); // PutUserDataLatency
check.Uint64(2u); // StoragePoolId
}
@@ -1070,8 +1070,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
check.String("test"); // Kind
check.String("/Root:test"); // Name
check.Uint64(1u); // NumGroups
- check.Null(); // PathId
- check.Null(); // SchemeshardId
+ check.Null(); // PathId
+ check.Null(); // SchemeshardId
check.Uint64(2u); // StoragePoolId
check.String("Default"); // VDiskKind
}
@@ -1341,7 +1341,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
UNIT_ASSERT_VALUES_EQUAL(entry.Type, ESchemeEntryType::Directory);
auto children = result.GetChildren();
- UNIT_ASSERT_VALUES_EQUAL(children.size(), 16);
+ UNIT_ASSERT_VALUES_EQUAL(children.size(), 16);
THashSet<TString> names;
for (const auto& child : children) {
diff --git a/ydb/core/tablet/bootstrapper.cpp b/ydb/core/tablet/bootstrapper.cpp
index d2e5dd8b7f3..6dc79c4482e 100644
--- a/ydb/core/tablet/bootstrapper.cpp
+++ b/ydb/core/tablet/bootstrapper.cpp
@@ -544,16 +544,16 @@ class TBootstrapper : public TActor<TBootstrapper> {
}
void PassAway() override {
- for (ui32 nodeId : BootstrapperInfo->OtherNodes) {
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
- }
+ for (ui32 nodeId : BootstrapperInfo->OtherNodes) {
+ Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
+ }
NotifyWatchers();
TActor::PassAway();
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_BOOTSTRAPPER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_BOOTSTRAPPER;
}
TBootstrapper(TTabletStorageInfo *tabletInfo, TBootstrapperInfo *bootstrapperInfo, bool standby)
diff --git a/ydb/core/tablet/node_tablet_monitor.cpp b/ydb/core/tablet/node_tablet_monitor.cpp
index 8bb34e7ea0b..9ea09c8e4e6 100644
--- a/ydb/core/tablet/node_tablet_monitor.cpp
+++ b/ydb/core/tablet/node_tablet_monitor.cpp
@@ -20,8 +20,8 @@ using namespace NNodeWhiteboard;
class TNodeList : public TActorBootstrapped<TNodeList> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TNodeList(const TActorId &sender)
@@ -132,8 +132,8 @@ protected:
class TTabletList : public TActorBootstrapped<TTabletList> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TTabletList(const TActorId &sender, ui32 filterNodeId,
@@ -297,8 +297,8 @@ protected:
class TStateStorageTabletList : public TActorBootstrapped<TStateStorageTabletList> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TStateStorageTabletList(const TActorId &sender, ui32 stateStorageId)
@@ -416,8 +416,8 @@ private:
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
}
TNodeTabletMonitor(const TIntrusivePtr<ITabletStateClassifier>& stateClassifier,
diff --git a/ydb/core/tablet/node_whiteboard.cpp b/ydb/core/tablet/node_whiteboard.cpp
index 783758e99d1..0fad2e2b6e0 100644
--- a/ydb/core/tablet/node_whiteboard.cpp
+++ b/ydb/core/tablet/node_whiteboard.cpp
@@ -31,8 +31,8 @@ class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService>
struct TEvCleanupDeadTablets : TEventLocal<TEvCleanupDeadTablets, EvCleanupDeadTablets> {};
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::NODE_WHITEBOARD_SERVICE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::NODE_WHITEBOARD_SERVICE;
}
void Bootstrap(const TActorContext &ctx) {
@@ -73,7 +73,7 @@ protected:
std::unordered_map<std::pair<TTabletId, TFollowerId>, NKikimrWhiteboard::TTabletStateInfo> TabletStateInfo;
std::unordered_map<TString, NKikimrWhiteboard::TNodeStateInfo> NodeStateInfo;
std::unordered_map<ui32, NKikimrWhiteboard::TPDiskStateInfo> PDiskStateInfo;
- std::unordered_map<TVDiskID, NKikimrWhiteboard::TVDiskStateInfo, THash<TVDiskID>> VDiskStateInfo;
+ std::unordered_map<TVDiskID, NKikimrWhiteboard::TVDiskStateInfo, THash<TVDiskID>> VDiskStateInfo;
std::unordered_map<ui32, NKikimrWhiteboard::TBSGroupStateInfo> BSGroupStateInfo;
NKikimrWhiteboard::TSystemStateInfo SystemStateInfo;
THolder<NTracing::ITraceCollection> TabletIntrospectionData;
@@ -105,26 +105,26 @@ protected:
const ::google::protobuf::Message& protoFrom,
const ::google::protobuf::FieldDescriptor* field,
PropertyType (::google::protobuf::Reflection::* getter)(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*) const,
- void (::google::protobuf::Reflection::* setter)(::google::protobuf::Message*, const ::google::protobuf::FieldDescriptor*, PropertyType) const,
- PropertyType defaultVal) {
+ void (::google::protobuf::Reflection::* setter)(::google::protobuf::Message*, const ::google::protobuf::FieldDescriptor*, PropertyType) const,
+ PropertyType defaultVal) {
int modified = 0;
bool has = reflectionTo.HasField(protoTo, field);
PropertyType newVal = (reflectionFrom.*getter)(protoFrom, field);
if (!has) {
- if (field->has_default_value() && newVal == defaultVal) {
- reflectionTo.ClearField(&protoTo, field);
- } else {
- (reflectionTo.*setter)(&protoTo, field, newVal);
- }
+ if (field->has_default_value() && newVal == defaultVal) {
+ reflectionTo.ClearField(&protoTo, field);
+ } else {
+ (reflectionTo.*setter)(&protoTo, field, newVal);
+ }
modified = 100;
} else {
PropertyType oldVal = (reflectionTo.*getter)(protoTo, field);
if (oldVal != newVal) {
- if (field->has_default_value() && newVal == defaultVal) {
- reflectionTo.ClearField(&protoTo, field);
- } else {
- (reflectionTo.*setter)(&protoTo, field, newVal);
- }
+ if (field->has_default_value() && newVal == defaultVal) {
+ reflectionTo.ClearField(&protoTo, field);
+ } else {
+ (reflectionTo.*setter)(&protoTo, field, newVal);
+ }
const auto& options(field->options());
if (options.HasExtension(NKikimrWhiteboard::InsignificantChangeAmount)) {
ui64 insignificantChangeAmount = options.GetExtension(NKikimrWhiteboard::InsignificantChangeAmount);
@@ -279,42 +279,42 @@ protected:
FieldDescriptor::CppType type = field->cpp_type();
switch (type) {
case FieldDescriptor::CPPTYPE_INT32: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt32, &Reflection::SetInt32, field->default_value_int32());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt32, &Reflection::SetInt32, field->default_value_int32());
break;
}
case FieldDescriptor::CPPTYPE_INT64: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt64, &Reflection::SetInt64, field->default_value_int64());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetInt64, &Reflection::SetInt64, field->default_value_int64());
break;
}
case FieldDescriptor::CPPTYPE_UINT32: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt32, &Reflection::SetUInt32, field->default_value_uint32());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt32, &Reflection::SetUInt32, field->default_value_uint32());
break;
}
case FieldDescriptor::CPPTYPE_UINT64: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt64, &Reflection::SetUInt64, field->default_value_uint64());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetUInt64, &Reflection::SetUInt64, field->default_value_uint64());
break;
}
case FieldDescriptor::CPPTYPE_DOUBLE: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetDouble, &Reflection::SetDouble, field->default_value_double());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetDouble, &Reflection::SetDouble, field->default_value_double());
break;
}
case FieldDescriptor::CPPTYPE_FLOAT: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetFloat, &Reflection::SetFloat, field->default_value_float());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetFloat, &Reflection::SetFloat, field->default_value_float());
break;
}
case FieldDescriptor::CPPTYPE_BOOL: {
- modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetBool, &Reflection::SetBool, field->default_value_bool());
+ modified += MergeProtoField(reflectionTo, reflectionFrom, protoTo, protoFrom, field, &Reflection::GetBool, &Reflection::SetBool, field->default_value_bool());
break;
}
case FieldDescriptor::CPPTYPE_ENUM: {
bool has = reflectionTo.HasField(protoTo, field);
auto val = reflectionFrom.GetEnum(protoFrom, field);
if (!has || reflectionTo.GetEnum(protoTo, field)->number() != val->number()) {
- if (field->has_default_value() && val->number() == field->default_value_enum()->number()) {
- reflectionTo.ClearField(&protoTo, field);
- } else {
- reflectionTo.SetEnum(&protoTo, field, val);
- }
+ if (field->has_default_value() && val->number() == field->default_value_enum()->number()) {
+ reflectionTo.ClearField(&protoTo, field);
+ } else {
+ reflectionTo.SetEnum(&protoTo, field, val);
+ }
modified += 100;
}
break;
@@ -323,11 +323,11 @@ protected:
bool has = reflectionTo.HasField(protoTo, field);
auto val = reflectionFrom.GetString(protoFrom, field);
if (!has || reflectionTo.GetString(protoTo, field) != val) {
- if (field->has_default_value() && field->default_value_string() == val) {
- reflectionTo.ClearField(&protoTo, field);
- } else {
- reflectionTo.SetString(&protoTo, field, val);
- }
+ if (field->has_default_value() && field->default_value_string() == val) {
+ reflectionTo.ClearField(&protoTo, field);
+ } else {
+ reflectionTo.SetString(&protoTo, field, val);
+ }
modified += 100;
}
break;
@@ -353,7 +353,7 @@ protected:
HFunc(TEvWhiteboard::TEvPDiskStateRequest, Handle);
HFunc(TEvWhiteboard::TEvPDiskStateDelete, Handle);
HFunc(TEvWhiteboard::TEvVDiskStateUpdate, Handle);
- HFunc(TEvWhiteboard::TEvVDiskStateGenerationChange, Handle);
+ HFunc(TEvWhiteboard::TEvVDiskStateGenerationChange, Handle);
HFunc(TEvWhiteboard::TEvVDiskStateDelete, Handle);
HFunc(TEvWhiteboard::TEvVDiskStateRequest, Handle);
HFunc(TEvWhiteboard::TEvBSGroupStateUpdate, Handle);
@@ -408,40 +408,40 @@ protected:
}
void Handle(TEvWhiteboard::TEvVDiskStateUpdate::TPtr &ev, const TActorContext &ctx) {
- auto& record = ev->Get()->Record;
- const auto& key = VDiskIDFromVDiskID(record.GetVDiskId());
- if (ev->Get()->Initial) {
- auto& value = VDiskStateInfo[key];
- value = record;
- value.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- } else if (const auto it = VDiskStateInfo.find(key); it != VDiskStateInfo.end() &&
- it->second.GetInstanceGuid() == record.GetInstanceGuid()) {
- auto& value = it->second;
- if (CheckedMerge(value, record) >= 100) {
- value.SetChangeTime(ctx.Now().MilliSeconds());
- UpdateSystemState(ctx);
- }
+ auto& record = ev->Get()->Record;
+ const auto& key = VDiskIDFromVDiskID(record.GetVDiskId());
+ if (ev->Get()->Initial) {
+ auto& value = VDiskStateInfo[key];
+ value = record;
+ value.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ } else if (const auto it = VDiskStateInfo.find(key); it != VDiskStateInfo.end() &&
+ it->second.GetInstanceGuid() == record.GetInstanceGuid()) {
+ auto& value = it->second;
+ if (CheckedMerge(value, record) >= 100) {
+ value.SetChangeTime(ctx.Now().MilliSeconds());
+ UpdateSystemState(ctx);
+ }
}
}
void Handle(TEvWhiteboard::TEvVDiskStateDelete::TPtr &ev, const TActorContext &ctx) {
- if (VDiskStateInfo.erase(VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskId()))) {
- UpdateSystemState(ctx);
- }
- }
-
- void Handle(TEvWhiteboard::TEvVDiskStateGenerationChange::TPtr &ev, const TActorContext &ctx) {
- auto *msg = ev->Get();
- if (const auto it = VDiskStateInfo.find(msg->VDiskId); it != VDiskStateInfo.end() &&
- it->second.GetInstanceGuid() == msg->InstanceGuid) {
- auto node = VDiskStateInfo.extract(it);
- node.key().GroupGeneration = msg->Generation;
- VDiskStateInfo.insert(std::move(node));
- UpdateSystemState(ctx);
- }
- }
-
+ if (VDiskStateInfo.erase(VDiskIDFromVDiskID(ev->Get()->Record.GetVDiskId()))) {
+ UpdateSystemState(ctx);
+ }
+ }
+
+ void Handle(TEvWhiteboard::TEvVDiskStateGenerationChange::TPtr &ev, const TActorContext &ctx) {
+ auto *msg = ev->Get();
+ if (const auto it = VDiskStateInfo.find(msg->VDiskId); it != VDiskStateInfo.end() &&
+ it->second.GetInstanceGuid() == msg->InstanceGuid) {
+ auto node = VDiskStateInfo.extract(it);
+ node.key().GroupGeneration = msg->Generation;
+ VDiskStateInfo.insert(std::move(node));
+ UpdateSystemState(ctx);
+ }
+ }
+
void Handle(TEvWhiteboard::TEvBSGroupStateUpdate::TPtr &ev, const TActorContext &ctx) {
auto& bSGroupStateInfo = BSGroupStateInfo[ev->Get()->Record.GetGroupID()];
if (CheckedMerge(bSGroupStateInfo, ev->Get()->Record) >= 100) {
@@ -511,15 +511,15 @@ protected:
++yellowFlags;
} else {
switch (pr.second.GetState()) {
- case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
- case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
+ case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Red);
break;
- case NKikimrBlobStorage::TPDiskState::OpenFileError:
+ case NKikimrBlobStorage::TPDiskState::OpenFileError:
pDiskFlag = std::max(pDiskFlag, NKikimrWhiteboard::EFlag::Yellow);
++yellowFlags;
break;
diff --git a/ydb/core/tablet/resource_broker_impl.h b/ydb/core/tablet/resource_broker_impl.h
index 2c781692f60..4f02a6125fa 100644
--- a/ydb/core/tablet/resource_broker_impl.h
+++ b/ydb/core/tablet/resource_broker_impl.h
@@ -436,8 +436,8 @@ private:
class TResourceBrokerActor : public TActorBootstrapped<TResourceBrokerActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_COMPACTION_BROKER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_COMPACTION_BROKER;
}
TResourceBrokerActor(const NKikimrResourceBroker::TResourceBrokerConfig &config,
diff --git a/ydb/core/tablet/tablet_counters.h b/ydb/core/tablet/tablet_counters.h
index a8cc27e9eda..0f157a65129 100644
--- a/ydb/core/tablet/tablet_counters.h
+++ b/ydb/core/tablet/tablet_counters.h
@@ -142,17 +142,17 @@ class TTabletPercentileCounter : TNonCopyable {
friend class TCountersArray<TTabletPercentileCounter>;
public:
//
- struct TRangeDef {
+ struct TRangeDef {
ui64 RangeVal;
const char* RangeName;
-
- friend bool operator <(const TRangeDef& x, const TRangeDef& y) { return x.RangeVal < y.RangeVal; }
- friend bool operator <(const ui64 x, const TRangeDef& y) { return x < y.RangeVal; }
+
+ friend bool operator <(const TRangeDef& x, const TRangeDef& y) { return x.RangeVal < y.RangeVal; }
+ friend bool operator <(const ui64 x, const TRangeDef& y) { return x < y.RangeVal; }
};
template <ui32 rangeCount>
- void Initialize(const TRangeDef(&ranges)[rangeCount], bool integral) {
- Initialize(rangeCount, ranges, integral);
+ void Initialize(const TRangeDef(&ranges)[rangeCount], bool integral) {
+ Initialize(rangeCount, ranges, integral);
}
TTabletPercentileCounter& IncrementFor(ui64 what) {
@@ -194,10 +194,10 @@ public:
return TVector<TRangeDef>(Ranges, Ranges + RangeCount);
}
- bool GetIntegral() const {
- return Integral;
- }
-
+ bool GetIntegral() const {
+ return Integral;
+ }
+
void PopulateFrom(const TTabletPercentileCounter& rp) {
Populate(rp);
}
@@ -209,9 +209,9 @@ private:
void AdjustToBaseLine(const TTabletPercentileCounter& baseLine) {
//
Y_VERIFY_DEBUG(RangeCount == baseLine.RangeCount);
- if (Integral) {
- return;
- }
+ if (Integral) {
+ return;
+ }
for (ui32 i = 0; i < RangeCount; ++i) {
Y_VERIFY_DEBUG(Values[i] >= baseLine.Values[i]);
@@ -237,7 +237,7 @@ private:
}
public:
- void Initialize(ui32 rangeCount, const TRangeDef* ranges, bool integral) {
+ void Initialize(ui32 rangeCount, const TRangeDef* ranges, bool integral) {
Y_VERIFY_DEBUG(!Ranges);
Y_VERIFY_DEBUG(!Values);
Y_VERIFY_DEBUG(rangeCount > 0);
@@ -245,7 +245,7 @@ public:
RangeCount = rangeCount;
Ranges = ranges;
- Integral = integral;
+ Integral = integral;
Y_VERIFY_DEBUG(IsSorted());
@@ -254,18 +254,18 @@ public:
void Clear() {
if (IsInitialized()) {
- std::fill(&Values[0], &Values[RangeCount], 0);
+ std::fill(&Values[0], &Values[RangeCount], 0);
}
}
private:
//
- ui32 FindSlot(ui64 what) const {
- return Max<ssize_t>(0, std::upper_bound(Ranges, Ranges + RangeCount, what) - Ranges - 1);
+ ui32 FindSlot(ui64 what) const {
+ return Max<ssize_t>(0, std::upper_bound(Ranges, Ranges + RangeCount, what) - Ranges - 1);
}
-
- bool IsSorted() const {
- return std::is_sorted(Ranges, Ranges + RangeCount);
+
+ bool IsSorted() const {
+ return std::is_sorted(Ranges, Ranges + RangeCount);
}
bool IsInitialized() const {
@@ -284,9 +284,9 @@ private:
}
//
- ui32 RangeCount = 0;
- const TRangeDef* Ranges = nullptr;
- bool Integral = false;
+ ui32 RangeCount = 0;
+ const TRangeDef* Ranges = nullptr;
+ bool Integral = false;
TArrayHolder<ui64> Values;
};
diff --git a/ydb/core/tablet/tablet_counters_aggregator.cpp b/ydb/core/tablet/tablet_counters_aggregator.cpp
index 1885b26e09c..43ff6bdafad 100644
--- a/ydb/core/tablet/tablet_counters_aggregator.cpp
+++ b/ydb/core/tablet/tablet_counters_aggregator.cpp
@@ -86,8 +86,8 @@ struct THistogramCounter {
}
void IncrementFor(ui64 value) {
- const size_t i = Max<ssize_t>(0, std::upper_bound(Ranges.begin(), Ranges.end(), value) - Ranges.begin() - 1);
- Values[i]->Inc();
+ const size_t i = Max<ssize_t>(0, std::upper_bound(Ranges.begin(), Ranges.end(), value) - Ranges.begin() - 1);
+ Values[i]->Inc();
Histogram->Collect(value);
}
@@ -973,11 +973,11 @@ private:
"inconsistent counters for tablet type %s", TTabletTypes::TypeToStr(tabletType));
for (ui32 r = 0; r < rangeCount; ++r) {
- if (percentileCounter.GetIntegral()) {
- *pcx[r] = percentileCounter.GetRangeValue(r);
- } else {
- *pcx[r] += percentileCounter.GetRangeValue(r);
- }
+ if (percentileCounter.GetIntegral()) {
+ *pcx[r] = percentileCounter.GetRangeValue(r);
+ } else {
+ *pcx[r] += percentileCounter.GetRangeValue(r);
+ }
}
if (rangeCount < 2) {
@@ -1558,8 +1558,8 @@ TIntrusivePtr<NSysView::IDbCounters> CreateTabletDbCounters(
////////////////////////////////////////////
class TTabletCountersAggregatorActor : public TActorBootstrapped<TTabletCountersAggregatorActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
}
//
@@ -1905,8 +1905,8 @@ class TClusterLabeledCountersAggregatorActorV1 : public TActorBootstrapped<TClus
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
}
//
@@ -2179,8 +2179,8 @@ class TClusterLabeledCountersAggregatorActorV2 : public TActorBootstrapped<TClus
bool NewFormat;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_COUNTERS_AGGREGATOR;
}
//
diff --git a/ydb/core/tablet/tablet_counters_aggregator_ut.cpp b/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
index 707ffb977ee..3483cd87cd4 100644
--- a/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
+++ b/ydb/core/tablet/tablet_counters_aggregator_ut.cpp
@@ -45,7 +45,7 @@ void TestHeavy(const ui32 v, ui32 numWorkers) {
for (const auto& a : cc) {
THolder<TEvInterconnect::TEvNodesInfo> nodesInfo = MakeHolder<TEvInterconnect::TEvNodesInfo>();
for (auto i = 1; i <= NODES; ++i) {
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(i, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(i, "::", "localhost", "localhost", 1234, TNodeLocation()));
}
runtime.Send(new NActors::IEventHandle(a, edge, nodesInfo.Release()), 0, true);
}
@@ -110,9 +110,9 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
runtime.DispatchEvents(options);
for (const auto& a : cc) {
THolder<TEvInterconnect::TEvNodesInfo> nodesInfo = MakeHolder<TEvInterconnect::TEvNodesInfo>();
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(1, "::", "localhost", "localhost", 1234, TNodeLocation()));
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(2, "::", "localhost", "localhost", 1234, TNodeLocation()));
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(3, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(1, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(2, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(3, "::", "localhost", "localhost", 1234, TNodeLocation()));
runtime.Send(new NActors::IEventHandle(a, edge, nodesInfo.Release()), 0, true);
}
@@ -208,9 +208,9 @@ Y_UNIT_TEST_SUITE(TTabletCountersAggregator) {
runtime.DispatchEvents(options);
for (const auto& a : cc) {
THolder<TEvInterconnect::TEvNodesInfo> nodesInfo = MakeHolder<TEvInterconnect::TEvNodesInfo>();
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(1, "::", "localhost", "localhost", 1234, TNodeLocation()));
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(2, "::", "localhost", "localhost", 1234, TNodeLocation()));
- nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(3, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(1, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(2, "::", "localhost", "localhost", 1234, TNodeLocation()));
+ nodesInfo->Nodes.emplace_back(TEvInterconnect::TNodeInfo(3, "::", "localhost", "localhost", 1234, TNodeLocation()));
runtime.Send(new NActors::IEventHandle(a, edge, nodesInfo.Release()), 0, true);
}
diff --git a/ydb/core/tablet/tablet_counters_protobuf.h b/ydb/core/tablet/tablet_counters_protobuf.h
index 11d3a334def..81ec5722e3c 100644
--- a/ydb/core/tablet/tablet_counters_protobuf.h
+++ b/ydb/core/tablet/tablet_counters_protobuf.h
@@ -20,7 +20,7 @@ protected:
TVector<const char*> Names;
TVector<TVector<TTabletPercentileCounter::TRangeDef>> Ranges;
TVector<TTabletPercentileCounter::TRangeDef> AppGlobalRanges;
- TVector<bool> Integral;
+ TVector<bool> Integral;
public:
explicit TAppParsedOpts(const size_t diff = 0)
: Size(AppCountersDesc()->value_count() + diff)
@@ -53,7 +53,7 @@ public:
}
NamesStrings.emplace_back(nameString);
Ranges.push_back(ParseRanges(co));
- Integral.push_back(co.GetIntegral());
+ Integral.push_back(co.GetIntegral());
}
// Make plain strings out of Strokas to fullfil interface of TTabletCountersBase
@@ -84,11 +84,11 @@ public:
Y_FAIL("Ranges for percentile counter '%s' are not defined", AppCountersDesc()->value(idx)->full_name().c_str());
}
- virtual bool GetIntegral(size_t idx) const {
- Y_VERIFY(idx < Size);
- return Integral[idx];
- }
-
+ virtual bool GetIntegral(size_t idx) const {
+ Y_VERIFY(idx < Size);
+ return Integral[idx];
+ }
+
protected:
TString GetFilePrefix(const NProtoBuf::FileDescriptor* desc) {
if (desc->options().HasExtension(TabletTypeName)) {
@@ -124,7 +124,7 @@ private:
using TBase::NamesStrings;
using TBase::Names;
using TBase::Ranges;
- using TBase::Integral;
+ using TBase::Integral;
using TBase::AppGlobalRanges;
TVector<TTabletPercentileCounter::TRangeDef> TxGlobalRanges;
public:
@@ -163,7 +163,7 @@ public:
TVector<TTabletPercentileCounter::TRangeDef> ranges = TBase::ParseRanges(co);
NamesStrings.push_back(TBase::GetFilePrefix(typesDesc->file()) + txPrefix + co.GetName());
Ranges.push_back(TBase::ParseRanges(co));
- Integral.push_back(co.GetIntegral());
+ Integral.push_back(co.GetIntegral());
}
}
// Make plain strings out of Strokas to fullfil interface of TTabletCountersBase
@@ -480,7 +480,7 @@ private:
continue;
}
const auto& vec = opts->GetRanges(i);
- Percentile()[i].Initialize(vec.size(), vec.begin(), opts->GetIntegral(i));
+ Percentile()[i].Initialize(vec.size(), vec.begin(), opts->GetIntegral(i));
}
}
};
@@ -533,7 +533,7 @@ private:
continue;
}
const auto& vec = opts->GetRanges(i);
- Percentile()[i].Initialize(vec.size(), vec.begin(), opts->GetIntegral(i));
+ Percentile()[i].Initialize(vec.size(), vec.begin(), opts->GetIntegral(i));
}
}
};
diff --git a/ydb/core/tablet/tablet_monitoring_proxy.cpp b/ydb/core/tablet/tablet_monitoring_proxy.cpp
index a61a43b7e5c..b846c248898 100644
--- a/ydb/core/tablet/tablet_monitoring_proxy.cpp
+++ b/ydb/core/tablet/tablet_monitoring_proxy.cpp
@@ -20,8 +20,8 @@ namespace {
class TForwardingActor : public TActorBootstrapped<TForwardingActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_FORWARDING_ACTOR;
}
TForwardingActor(const TTabletMonitoringProxyConfig& config, ui64 targetTablet, bool forceFollower, const TActorId& sender, const TString& query, HTTP_METHOD method)
@@ -124,8 +124,8 @@ private:
////////////////////////////////////////////
class TTabletMonitoringProxyActor : public TActorBootstrapped<TTabletMonitoringProxyActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
}
//
diff --git a/ydb/core/tablet/tablet_pipe_client.cpp b/ydb/core/tablet/tablet_pipe_client.cpp
index 2fa35af9a0e..43fdd0142ae 100644
--- a/ydb/core/tablet/tablet_pipe_client.cpp
+++ b/ydb/core/tablet/tablet_pipe_client.cpp
@@ -28,8 +28,8 @@ namespace NTabletPipe {
class TClient : public TActorBootstrapped<TClient> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_PIPE_CLIENT;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_PIPE_CLIENT;
}
TClient(const TActorId& owner, ui64 tabletId, const TClientConfig& config)
@@ -706,7 +706,7 @@ namespace NTabletPipe {
}
void SendData(TActorId self, TActorId clientId, ui32 eventType, TIntrusivePtr<TEventSerializedData> buffer, ui64 cookie) {
- auto ev = new IEventHandle(eventType, 0, clientId, self, buffer, cookie);
+ auto ev = new IEventHandle(eventType, 0, clientId, self, buffer, cookie);
ev->Rewrite(TEvTabletPipe::EvSend, clientId);
TActivationContext::Send(ev);
}
@@ -718,7 +718,7 @@ namespace NTabletPipe {
}
void SendData(const TActorContext& ctx, const TActorId& clientId, ui32 eventType, TIntrusivePtr<TEventSerializedData> buffer, ui64 cookie) {
- auto ev = new IEventHandle(eventType, 0, clientId, ctx.SelfID, buffer, cookie);
+ auto ev = new IEventHandle(eventType, 0, clientId, ctx.SelfID, buffer, cookie);
ev->Rewrite(TEvTabletPipe::EvSend, clientId);
ctx.ExecutorThread.Send(ev);
}
diff --git a/ydb/core/tablet/tablet_pipe_server.cpp b/ydb/core/tablet/tablet_pipe_server.cpp
index b7c669e72cc..6327f50a889 100644
--- a/ydb/core/tablet/tablet_pipe_server.cpp
+++ b/ydb/core/tablet/tablet_pipe_server.cpp
@@ -11,8 +11,8 @@ namespace NTabletPipe {
class TServer : public TActor<TServer> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_PIPE_SERVER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_PIPE_SERVER;
}
TServer(ui64 tabletId, const TActorId& clientId, const TActorId& interconnectSession, ui32 features, ui64 connectCookie)
@@ -72,7 +72,7 @@ namespace NTabletPipe {
return;
}
- auto buffer = MakeIntrusive<TEventSerializedData>(record.GetBuffer(), record.GetExtendedFormat());
+ auto buffer = MakeIntrusive<TEventSerializedData>(record.GetBuffer(), record.GetExtendedFormat());
auto result = std::make_unique<IEventHandle>(
ev->InterconnectSession,
record.GetType(),
diff --git a/ydb/core/tablet/tablet_pipecache.cpp b/ydb/core/tablet/tablet_pipecache.cpp
index 292571f661c..dd1ad3a8ba0 100644
--- a/ydb/core/tablet/tablet_pipecache.cpp
+++ b/ydb/core/tablet/tablet_pipecache.cpp
@@ -431,8 +431,8 @@ class TPipePeNodeCache : public TActor<TPipePeNodeCache> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_PIPE_SERVER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_PIPE_SERVER;
}
TPipePeNodeCache(const TIntrusivePtr<TPipePeNodeCacheConfig> &config)
diff --git a/ydb/core/tablet/tablet_req_blockbs.cpp b/ydb/core/tablet/tablet_req_blockbs.cpp
index 7e2e94ec95d..a672a4a1fb1 100644
--- a/ydb/core/tablet/tablet_req_blockbs.cpp
+++ b/ydb/core/tablet/tablet_req_blockbs.cpp
@@ -60,8 +60,8 @@ class TTabletReqBlockBlobStorageGroup : public TActorBootstrapped<TTabletReqBloc
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS;
}
void Bootstrap() {
@@ -123,8 +123,8 @@ public:
, BlockPrevEntry(blockPrevEntry)
{}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_BLOCK_BS;
}
void Bootstrap() {
diff --git a/ydb/core/tablet/tablet_req_delete.cpp b/ydb/core/tablet/tablet_req_delete.cpp
index 754c79bb325..8986bfcea23 100644
--- a/ydb/core/tablet/tablet_req_delete.cpp
+++ b/ydb/core/tablet/tablet_req_delete.cpp
@@ -54,17 +54,17 @@ class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> {
void SendRequest(int numRequest, const TActorContext& ctx) {
const TRequestInfo& info(Requests[numRequest]);
- bool total = Generation == std::numeric_limits<ui32>::max();
- const ui32 recordGeneration = total ? Generation : Generation + 1;
- const ui32 perGenerationCounter = total ? Max<ui32>() : 0;
- auto event = TEvBlobStorage::TEvCollectGarbage::CreateHardBarrier(
- TabletStorageInfo->TabletID, // tabletId
- recordGeneration, // recordGeneration
- perGenerationCounter, // perGenerationCounter
- info.Channel, // channel
- Generation, // collectGeneration
- std::numeric_limits<ui32>::max(), // collectStep
- TInstant::Max()); // deadline
+ bool total = Generation == std::numeric_limits<ui32>::max();
+ const ui32 recordGeneration = total ? Generation : Generation + 1;
+ const ui32 perGenerationCounter = total ? Max<ui32>() : 0;
+ auto event = TEvBlobStorage::TEvCollectGarbage::CreateHardBarrier(
+ TabletStorageInfo->TabletID, // tabletId
+ recordGeneration, // recordGeneration
+ perGenerationCounter, // perGenerationCounter
+ info.Channel, // channel
+ Generation, // collectGeneration
+ std::numeric_limits<ui32>::max(), // collectStep
+ TInstant::Max()); // deadline
event->IsMonitored = false;
SendToBSProxy(ctx, info.GroupId, event.Release(), numRequest);
}
@@ -113,8 +113,8 @@ class TTabletReqDelete : public TActorBootstrapped<TTabletReqDelete> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
}
TTabletReqDelete(const TActorId &owner, const TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo, ui32 generation = std::numeric_limits<ui32>::max())
diff --git a/ydb/core/tablet/tablet_req_findlatest.cpp b/ydb/core/tablet/tablet_req_findlatest.cpp
index ca3d09aa432..2388c627797 100644
--- a/ydb/core/tablet/tablet_req_findlatest.cpp
+++ b/ydb/core/tablet/tablet_req_findlatest.cpp
@@ -68,8 +68,8 @@ class TTabletReqFindLatestLogEntry : public TActorBootstrapped<TTabletReqFindLat
}
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_FIND_LATEST;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_FIND_LATEST;
}
TTabletReqFindLatestLogEntry(const TActorId &owner, bool readBody, TTabletStorageInfo *info, ui32 blockedGeneration)
diff --git a/ydb/core/tablet/tablet_req_rebuildhistory.cpp b/ydb/core/tablet/tablet_req_rebuildhistory.cpp
index c0b4c0c2bc1..f9b7a20b16b 100644
--- a/ydb/core/tablet/tablet_req_rebuildhistory.cpp
+++ b/ydb/core/tablet/tablet_req_rebuildhistory.cpp
@@ -508,9 +508,9 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil
ui64 totalSize = 0;
for (ui64 i = firstRequestIdx; i != endIdx; ++i) {
ui64 size = refs[i].BlobSize();
- Y_VERIFY(size != 0);
+ Y_VERIFY(size != 0);
- const ui64 replyDataSize = totalSize + size + NKikimr::BlobProtobufHeaderMaxSize;
+ const ui64 replyDataSize = totalSize + size + NKikimr::BlobProtobufHeaderMaxSize;
if (replyDataSize <= NKikimr::MaxProtobufSize) {
totalSize += size + NKikimr::BlobProtobufHeaderMaxSize;
} else {
@@ -862,8 +862,8 @@ class TTabletReqRebuildHistoryGraph : public TActorBootstrapped<TTabletReqRebuil
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_REBUILD_GRAPH;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_REBUILD_GRAPH;
}
TTabletReqRebuildHistoryGraph(const TActorId &owner, TTabletStorageInfo *info, ui32 blockedGen, NTracing::ITrace *trace, ui64 followerCookie)
diff --git a/ydb/core/tablet/tablet_req_reset.cpp b/ydb/core/tablet/tablet_req_reset.cpp
index b73c68c120f..4069ab3adf1 100644
--- a/ydb/core/tablet/tablet_req_reset.cpp
+++ b/ydb/core/tablet/tablet_req_reset.cpp
@@ -105,8 +105,8 @@ class TTabletReqReset : public TActorBootstrapped<TTabletReqReset> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_DELETE_TABLET;
}
TTabletReqReset(const TActorId& owner, const TIntrusivePtr<TTabletStorageInfo>& tabletStorageInfo, ui32 knownGeneration)
diff --git a/ydb/core/tablet/tablet_req_writelog.cpp b/ydb/core/tablet/tablet_req_writelog.cpp
index 7c4d02c405c..b51eb4d92b4 100644
--- a/ydb/core/tablet/tablet_req_writelog.cpp
+++ b/ydb/core/tablet/tablet_req_writelog.cpp
@@ -100,8 +100,8 @@ class TTabletReqWriteLog : public TActorBootstrapped<TTabletReqWriteLog> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_REQ_WRITE_LOG;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_REQ_WRITE_LOG;
}
TTabletReqWriteLog(const TActorId &owner, const TLogoBlobID &logid, NKikimrTabletBase::TTabletLogEntry *entry, TVector<TEvTablet::TLogEntryReference> &refs, TEvBlobStorage::TEvPut::ETactic commitTactic, TTabletStorageInfo *info)
diff --git a/ydb/core/tablet/tablet_resolver.cpp b/ydb/core/tablet/tablet_resolver.cpp
index c0a39a2216b..1a9950eeda8 100644
--- a/ydb/core/tablet/tablet_resolver.cpp
+++ b/ydb/core/tablet/tablet_resolver.cpp
@@ -166,7 +166,7 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
TUnresolvedTablets UnresolvedTablets;
TResolvedTablets ResolvedTablets;
THashSet<ui64> TabletsOnStopList;
- THashMap<ui32, TString> NodeToDcMapping;
+ THashMap<ui32, TString> NodeToDcMapping;
THashMap<ui32, ui64> NodeProblems;
ui64 LastNodeProblemsUpdateEpoch = 0;
@@ -185,9 +185,9 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
NMonitoring::TDynamicCounters::TCounterPtr InFlyResolveCounter;
- std::optional<TString> FindNodeDc(ui32 nodeId) const {
+ std::optional<TString> FindNodeDc(ui32 nodeId) const {
auto it = NodeToDcMapping.find(nodeId);
- return it != NodeToDcMapping.end() ? std::make_optional(it->second) : std::nullopt;
+ return it != NodeToDcMapping.end() ? std::make_optional(it->second) : std::nullopt;
}
void ResolveRequest(ui64 tabletId, const TActorContext &ctx) {
@@ -207,8 +207,8 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
std::pair<TActorId, TActorId> SelectForward(const TActorContext& ctx, const TEntry& entry, TResolveInfo& info, ui64 tabletId)
{
const ui32 selfNode = ctx.SelfID.NodeId();
- const std::optional<TString> selfDc = FindNodeDc(selfNode);
- const std::optional<TString> leaderDc = FindNodeDc(entry.KnownLeader.NodeId());
+ const std::optional<TString> selfDc = FindNodeDc(selfNode);
+ const std::optional<TString> leaderDc = FindNodeDc(entry.KnownLeader.NodeId());
struct TCandidate {
TActorId KnownLeader;
@@ -236,7 +236,7 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
bool countLeader = (entry.State == TEntry::StNormal || entry.State == TEntry::StFollowerUpdate);
if (countLeader) {
bool isLocal = (entry.KnownLeader.NodeId() == selfNode);
- bool isLocalDc = selfDc && leaderDc == selfDc;
+ bool isLocalDc = selfDc && leaderDc == selfDc;
info.Count(isLocal, isLocalDc);
ui32 prio = info.ResFlags.GetTabletPriority(isLocal, isLocalDc, false);
@@ -249,7 +249,7 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
if (info.ResFlags.AllowFollower()) {
for (const auto &x : entry.KnownFollowers) {
bool isLocal = (x.first.NodeId() == selfNode);
- bool isLocalDc = selfDc && FindNodeDc(x.first.NodeId()) == selfDc;
+ bool isLocalDc = selfDc && FindNodeDc(x.first.NodeId()) == selfDc;
info.Count(isLocal, isLocalDc);
ui32 prio = info.ResFlags.GetTabletPriority(isLocal, isLocalDc, true);
@@ -260,18 +260,18 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
}
}
- auto dcName = [](const std::optional<TString>& x) { return x ? x->data() : "<none>"; };
-
+ auto dcName = [](const std::optional<TString>& x) { return x ? x->data() : "<none>"; };
+
if (!winners.empty()) {
size_t winnerIndex = (winners.size() == 1 ? 0 : (AppData(ctx)->RandomProvider->GenRand64() % winners.size()));
const TCandidate& winner = winners[winnerIndex];
LOG_DEBUG(ctx, NKikimrServices::TABLET_RESOLVER,
- "SelectForward node %" PRIu32 " selfDC %s leaderDC %s %s"
+ "SelectForward node %" PRIu32 " selfDC %s leaderDC %s %s"
" local %" PRIu32 " localDc %" PRIu32 " other %" PRIu32 " disallowed %" PRIu32
" tabletId: %" PRIu64 " followers: %" PRIu64 " countLeader %" PRIu32
" allowFollowers %" PRIu32 " winner: %s",
- selfNode, dcName(selfDc), dcName(leaderDc), info.ResFlags.ToString().data(),
+ selfNode, dcName(selfDc), dcName(leaderDc), info.ResFlags.ToString().data(),
info.NumLocal, info.NumLocalDc, info.NumOtherDc, disallowed,
tabletId, entry.KnownFollowers.size(), countLeader, info.ResFlags.AllowFollower(),
winner.KnownLeader.ToString().c_str());
@@ -296,9 +296,9 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
}
LOG_INFO(ctx, NKikimrServices::TABLET_RESOLVER,
- "No candidates for SelectForward, node %" PRIu32 " selfDC %s leaderDC %s %s"
+ "No candidates for SelectForward, node %" PRIu32 " selfDC %s leaderDC %s %s"
" local %" PRIu32 " localDc %" PRIu32 " other %" PRIu32 " disallowed %" PRIu32,
- selfNode, dcName(selfDc), dcName(leaderDc), info.ResFlags.ToString().data(),
+ selfNode, dcName(selfDc), dcName(leaderDc), info.ResFlags.ToString().data(),
info.NumLocal, info.NumLocalDc, info.NumOtherDc, disallowed);
SelectedNone->Inc();
@@ -780,9 +780,9 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
const TEvInterconnect::TEvNodesInfo *msg = ev->Get();
bool distinct = false;
for (const auto &nodeInfo : msg->Nodes) {
- if (nodeInfo.Location.GetDataCenterId() != msg->Nodes[0].Location.GetDataCenterId())
+ if (nodeInfo.Location.GetDataCenterId() != msg->Nodes[0].Location.GetDataCenterId())
distinct = true;
- NodeToDcMapping[nodeInfo.NodeId] = nodeInfo.Location.GetDataCenterId();
+ NodeToDcMapping[nodeInfo.NodeId] = nodeInfo.Location.GetDataCenterId();
}
if (!distinct)
@@ -800,8 +800,8 @@ class TTabletResolver : public TActorBootstrapped<TTabletResolver> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_RESOLVER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_RESOLVER_ACTOR;
}
TTabletResolver(const TIntrusivePtr<TTabletResolverConfig> &config)
diff --git a/ydb/core/tablet/tablet_responsiveness_pinger.h b/ydb/core/tablet/tablet_responsiveness_pinger.h
index 93954ea0b4c..077ae1cd471 100644
--- a/ydb/core/tablet/tablet_responsiveness_pinger.h
+++ b/ydb/core/tablet/tablet_responsiveness_pinger.h
@@ -17,8 +17,8 @@ class TTabletResponsivenessPinger : public TActorBootstrapped<TTabletResponsiven
void DoPing(const TActorContext &ctx);
void ReceivePing(const TActorContext &ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_RESPONSIVENESS_PINGER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_RESPONSIVENESS_PINGER;
}
TTabletResponsivenessPinger(TTabletSimpleCounter &counter, TDuration pingInterval);
diff --git a/ydb/core/tablet/tablet_sys.h b/ydb/core/tablet/tablet_sys.h
index 661d75a4e0a..06185165c7d 100644
--- a/ydb/core/tablet/tablet_sys.h
+++ b/ydb/core/tablet/tablet_sys.h
@@ -593,8 +593,8 @@ class TTablet : public TActor<TTablet> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_ACTOR;
}
TTablet(
diff --git a/ydb/core/tablet_flat/flat_bio_actor.cpp b/ydb/core/tablet_flat/flat_bio_actor.cpp
index 6a866fb3956..dec1cf671d4 100644
--- a/ydb/core/tablet_flat/flat_bio_actor.cpp
+++ b/ydb/core/tablet_flat/flat_bio_actor.cpp
@@ -14,7 +14,7 @@ using TEvGet = TEvBlobStorage::TEvGet;
struct TBlockIO::TLoaded : public TEvBlobStorage::TEvGetResult::TResponse{ };
TBlockIO::TBlockIO(TActorId service, ui64 cookie)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TBlockIO::Inbox), NKikimrServices::TActivity::SAUSAGE_BIO_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TBlockIO::Inbox), NKikimrServices::TActivity::SAUSAGE_BIO_A)
, Service(service)
, Cookie(cookie)
{
diff --git a/ydb/core/tablet_flat/flat_cxx_database.h b/ydb/core/tablet_flat/flat_cxx_database.h
index 27a260bcb27..fe1d14f1438 100644
--- a/ydb/core/tablet_flat/flat_cxx_database.h
+++ b/ydb/core/tablet_flat/flat_cxx_database.h
@@ -326,44 +326,44 @@ struct TConvertValue {
}
};
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// TInstant conversion
-
-template <typename TColumnType>
-struct TConvertValue<TColumnType, TRawTypeValue, TInstant> {
- typename NSchemeTypeMapper<TColumnType::ColumnType>::Type Storage;
- TTypeValue Value;
- TConvertValue(const TInstant& value) : Storage(value.GetValue()), Value(Storage, TColumnType::ColumnType) {}
- operator const TRawTypeValue&() const { return Value; }
-};
-
-template <typename TColumnType>
-struct TConvertValue<TColumnType, TInstant, TRawTypeValue> {
- TTypeValue Value;
- TConvertValue(const TRawTypeValue& value) : Value(value) {}
- operator TInstant() const { return TInstant::FromValue(static_cast<ui64>(Value)); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// TDuration conversion
-
-template <typename TColumnType>
-struct TConvertValue<TColumnType, TRawTypeValue, TDuration> {
- typename NSchemeTypeMapper<TColumnType::ColumnType>::Type Storage;
- TTypeValue Value;
- TConvertValue(const TDuration& value) : Storage(value.GetValue()), Value(Storage, TColumnType::ColumnType) {}
- operator const TRawTypeValue&() const { return Value; }
-};
-
-template <typename TColumnType>
-struct TConvertValue<TColumnType, TDuration, TRawTypeValue> {
- TTypeValue Value;
- TConvertValue(const TRawTypeValue& value) : Value(value) {}
- operator TDuration() const { return TDuration::FromValue(static_cast<ui64>(Value)); }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TInstant conversion
+
+template <typename TColumnType>
+struct TConvertValue<TColumnType, TRawTypeValue, TInstant> {
+ typename NSchemeTypeMapper<TColumnType::ColumnType>::Type Storage;
+ TTypeValue Value;
+ TConvertValue(const TInstant& value) : Storage(value.GetValue()), Value(Storage, TColumnType::ColumnType) {}
+ operator const TRawTypeValue&() const { return Value; }
+};
+
+template <typename TColumnType>
+struct TConvertValue<TColumnType, TInstant, TRawTypeValue> {
+ TTypeValue Value;
+ TConvertValue(const TRawTypeValue& value) : Value(value) {}
+ operator TInstant() const { return TInstant::FromValue(static_cast<ui64>(Value)); }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TDuration conversion
+
+template <typename TColumnType>
+struct TConvertValue<TColumnType, TRawTypeValue, TDuration> {
+ typename NSchemeTypeMapper<TColumnType::ColumnType>::Type Storage;
+ TTypeValue Value;
+ TConvertValue(const TDuration& value) : Storage(value.GetValue()), Value(Storage, TColumnType::ColumnType) {}
+ operator const TRawTypeValue&() const { return Value; }
+};
+
+template <typename TColumnType>
+struct TConvertValue<TColumnType, TDuration, TRawTypeValue> {
+ TTypeValue Value;
+ TConvertValue(const TRawTypeValue& value) : Value(value) {}
+ operator TDuration() const { return TDuration::FromValue(static_cast<ui64>(Value)); }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
template <typename TColumnType, typename SourceType>
struct TConvertValue<TColumnType, TRawTypeValue, SourceType> {
TTypeValue Value;
diff --git a/ydb/core/tablet_flat/flat_cxx_database_ut.cpp b/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
index 0423d82e624..8ce9199b09e 100644
--- a/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
+++ b/ydb/core/tablet_flat/flat_cxx_database_ut.cpp
@@ -28,10 +28,10 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
struct EmptyValue : Column<5, NScheme::NTypeIds::Uint64> { static constexpr ui64 Default = 13; };
struct ProtoValue : Column<6, NScheme::NTypeIds::String> { using Type = NKikimrMiniKQL::TValue; };
struct EnumValue : Column<7, NScheme::NTypeIds::Uint64> { using Type = ESomeEnum; };
- struct InstantValue : Column<8, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
+ struct InstantValue : Column<8, NScheme::NTypeIds::Uint64> { using Type = TInstant; };
using TKey = TableKey<ID>;
- using TColumns = TableColumns<ID, Value, Name, BoolValue, EmptyValue, ProtoValue, EnumValue, InstantValue>;
+ using TColumns = TableColumns<ID, Value, Name, BoolValue, EmptyValue, ProtoValue, EnumValue, InstantValue>;
};
struct TestTable2 : Table<2> {
@@ -71,8 +71,8 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
NIceDb::TNiceDb db(DB);
ui64 stamp = 0;
- TInstant timestamp = TInstant::Now();
-
+ TInstant timestamp = TInstant::Now();
+
{
TDummyEnv env;
DB.Begin(++stamp, env);
@@ -98,8 +98,8 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
NIceDb::TUpdate<Schema::TestTable::Name>(ToString(i)),
NIceDb::TUpdate<Schema::TestTable::BoolValue>(i % 2 == 0),
NIceDb::TUpdate<Schema::TestTable::ProtoValue>(protoValue),
- NIceDb::TUpdate<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1),
- NIceDb::TUpdate<Schema::TestTable::InstantValue>(timestamp));
+ NIceDb::TUpdate<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1),
+ NIceDb::TUpdate<Schema::TestTable::InstantValue>(timestamp));
// modern syntax:
db.Table<Schema::TestTable>().Key(i).Update<
@@ -107,9 +107,9 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
Schema::TestTable::Name,
Schema::TestTable::BoolValue,
Schema::TestTable::ProtoValue,
- Schema::TestTable::EnumValue,
- Schema::TestTable::InstantValue>(i, ToString(i), i % 2 == 0, protoValue, ESomeEnum::SomeValue1,
- timestamp);
+ Schema::TestTable::EnumValue,
+ Schema::TestTable::InstantValue>(i, ToString(i), i % 2 == 0, protoValue, ESomeEnum::SomeValue1,
+ timestamp);
// also modern syntax:
db.Table<Schema::TestTable>().Key(i)
@@ -117,8 +117,8 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
.Update<Schema::TestTable::Name>(ToString(i))
.Update<Schema::TestTable::BoolValue>(i % 2 == 0)
.Update<Schema::TestTable::ProtoValue>(protoValue)
- .Update<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1)
- .Update<Schema::TestTable::InstantValue>(timestamp);
+ .Update<Schema::TestTable::EnumValue>(ESomeEnum::SomeValue1)
+ .Update<Schema::TestTable::InstantValue>(timestamp);
}
DB.Commit(stamp, true);
}
@@ -175,8 +175,8 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
Schema::TestTable::Name,
Schema::TestTable::BoolValue,
Schema::TestTable::EmptyValue,
- Schema::TestTable::EnumValue,
- Schema::TestTable::InstantValue>();
+ Schema::TestTable::EnumValue,
+ Schema::TestTable::InstantValue>();
// move semantics test
decltype(row) new_row = std::move(row);
row = std::move(new_row);
@@ -187,12 +187,12 @@ Y_UNIT_TEST_SUITE(TFlatCxxDatabaseTest) {
TString name = row.GetValue<Schema::TestTable::Name>();
bool boolValue = row.GetValue<Schema::TestTable::BoolValue>();
ESomeEnum enumValue = row.GetValue<Schema::TestTable::EnumValue>();
- TInstant instantValue = row.GetValue<Schema::TestTable::InstantValue>();
+ TInstant instantValue = row.GetValue<Schema::TestTable::InstantValue>();
UNIT_ASSERT_EQUAL(value, i);
UNIT_ASSERT_EQUAL(ToString(value), name);
UNIT_ASSERT_EQUAL(boolValue, (i % 2 == 0));
UNIT_ASSERT_EQUAL(enumValue, ESomeEnum::SomeValue1);
- UNIT_ASSERT_EQUAL(instantValue, timestamp);
+ UNIT_ASSERT_EQUAL(instantValue, timestamp);
UNIT_ASSERT_EQUAL(row.GetValue<Schema::TestTable::EmptyValue>(), 13);
UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(), 13);
UNIT_ASSERT_EQUAL(row.GetValueOrDefault<Schema::TestTable::EmptyValue>(i), i);
diff --git a/ydb/core/tablet_flat/flat_executor.h b/ydb/core/tablet_flat/flat_executor.h
index df08b3a338a..7aee709f5b7 100644
--- a/ydb/core/tablet_flat/flat_executor.h
+++ b/ydb/core/tablet_flat/flat_executor.h
@@ -611,8 +611,8 @@ public:
void RegisterExternalTabletCounters(TAutoPtr<TTabletCountersBase> appCounters) override;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FLAT_EXECUTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FLAT_EXECUTOR;
}
TExecutor(NFlatExecutorSetup::ITablet *owner, const TActorId& ownerActorId);
diff --git a/ydb/core/tablet_flat/flat_executor_counters.cpp b/ydb/core/tablet_flat/flat_executor_counters.cpp
index ddecce5206c..dcbf5630f04 100644
--- a/ydb/core/tablet_flat/flat_executor_counters.cpp
+++ b/ydb/core/tablet_flat/flat_executor_counters.cpp
@@ -81,19 +81,19 @@ TExecutorCounters::TExecutorCounters()
static TTabletPercentileCounter::TRangeDef txDataRate[] = { FLAT_EXECUTOR_DATA_RATE(COUNTER_PERCENTILE_CONFIG_ARRAY) };
static TTabletPercentileCounter::TRangeDef txConsumedCpu[] = { FLAT_EXECUTOR_CONSUMED_CPU_RANGES(COUNTER_PERCENTILE_CONFIG_ARRAY) };
- Percentile()[TX_PERCENTILE_LATENCY_RO].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_LATENCY_RW].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_LATENCY_COMMIT].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_EXECUTE_CPUTIME].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_BOOKKEEPING_CPUTIME].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_COMMITED_CPUTIME].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_LOGSNAP_CPUTIME].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_PARTSWITCH_CPUTIME].Initialize(txLatencyConfig, false);
- Percentile()[TX_PERCENTILE_TOUCHED_BLOCKS].Initialize(txTouchedConfig, false);
- Percentile()[TX_PERCENTILE_DB_DATA_BYTES].Initialize(txDataSize, false);
- Percentile()[TX_PERCENTILE_TABLET_BYTES_READ].Initialize(txDataRate, false);
- Percentile()[TX_PERCENTILE_TABLET_BYTES_WRITTEN].Initialize(txDataRate, false);
- Percentile()[TX_PERCENTILE_CONSUMED_CPU].Initialize(txConsumedCpu, false);
+ Percentile()[TX_PERCENTILE_LATENCY_RO].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_LATENCY_RW].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_LATENCY_COMMIT].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_EXECUTE_CPUTIME].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_BOOKKEEPING_CPUTIME].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_COMMITED_CPUTIME].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_LOGSNAP_CPUTIME].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_PARTSWITCH_CPUTIME].Initialize(txLatencyConfig, false);
+ Percentile()[TX_PERCENTILE_TOUCHED_BLOCKS].Initialize(txTouchedConfig, false);
+ Percentile()[TX_PERCENTILE_DB_DATA_BYTES].Initialize(txDataSize, false);
+ Percentile()[TX_PERCENTILE_TABLET_BYTES_READ].Initialize(txDataRate, false);
+ Percentile()[TX_PERCENTILE_TABLET_BYTES_WRITTEN].Initialize(txDataRate, false);
+ Percentile()[TX_PERCENTILE_CONSUMED_CPU].Initialize(txConsumedCpu, false);
Percentile()[TX_PERCENTILE_FOLLOWERSYNC_LATENCY].Initialize(txLatencyConfig, false);
}
diff --git a/ydb/core/tablet_flat/flat_mem_warm.h b/ydb/core/tablet_flat/flat_mem_warm.h
index 96bb9d65fad..968f8b631d5 100644
--- a/ydb/core/tablet_flat/flat_mem_warm.h
+++ b/ydb/core/tablet_flat/flat_mem_warm.h
@@ -274,7 +274,7 @@ namespace NMem {
ui32 dstIndex = 0;
auto missing = ScratchMergeTags.begin();
- for (const TTagWithPos& src : ScratchUpdateTags) {
+ for (const TTagWithPos& src : ScratchUpdateTags) {
const TTag tag = src.first;
while (missing != ScratchMergeTags.end() && (*missing)->Tag < tag) {
update->Ops()[dstIndex++] = **missing;
diff --git a/ydb/core/tablet_flat/flat_ops_compact.h b/ydb/core/tablet_flat/flat_ops_compact.h
index 2ac81c4113a..6278f1e54aa 100644
--- a/ydb/core/tablet_flat/flat_ops_compact.h
+++ b/ydb/core/tablet_flat/flat_ops_compact.h
@@ -65,7 +65,7 @@ namespace NTabletFlatExecutor {
constexpr static ui64 MaxFlight = 20ll * (1ll << 20);
TOpsCompact(TActorId owner, TLogoBlobID mask, TAutoPtr<TCompactCfg> conf)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TOpsCompact::Inbox), NKikimrServices::TActivity::OPS_COMPACT_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TOpsCompact::Inbox), NKikimrServices::TActivity::OPS_COMPACT_A)
, Mask(mask)
, Owner(owner)
, Conf(std::move(conf))
diff --git a/ydb/core/tablet_flat/shared_sausagecache.cpp b/ydb/core/tablet_flat/shared_sausagecache.cpp
index c60c30202ba..8d94c571aea 100644
--- a/ydb/core/tablet_flat/shared_sausagecache.cpp
+++ b/ydb/core/tablet_flat/shared_sausagecache.cpp
@@ -1031,8 +1031,8 @@ public:
}
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SAUSAGE_CACHE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SAUSAGE_CACHE;
}
};
diff --git a/ydb/core/tablet_flat/test/libs/exec/dummy.h b/ydb/core/tablet_flat/test/libs/exec/dummy.h
index 5c6e2f5b4f1..4da51012a52 100644
--- a/ydb/core/tablet_flat/test/libs/exec/dummy.h
+++ b/ydb/core/tablet_flat/test/libs/exec/dummy.h
@@ -34,7 +34,7 @@ namespace NFake {
TDummy(const TActorId &tablet, TInfo *info, const TActorId& owner,
ui32 flags = 0 /* ORed EFlg enum */)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TDummy::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TDummy::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
, TTabletExecutedFlat(info, tablet, nullptr)
, Owner(owner)
, Flags(flags)
diff --git a/ydb/core/tablet_flat/test/libs/exec/owner.h b/ydb/core/tablet_flat/test/libs/exec/owner.h
index f3e3d7363c8..84a99283bac 100644
--- a/ydb/core/tablet_flat/test/libs/exec/owner.h
+++ b/ydb/core/tablet_flat/test/libs/exec/owner.h
@@ -24,7 +24,7 @@ namespace NFake {
using TSetup = TTabletSetupInfo;
TOwner(TActorId user, ui32 limit, TIntrusivePtr<TInfo> info, TIntrusivePtr<TSetup> setup, ui32 followerId)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TOwner::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TOwner::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
, Info(std::move(info))
, Setup(std::move(setup))
, User(user)
diff --git a/ydb/core/tablet_flat/test/libs/exec/storage.h b/ydb/core/tablet_flat/test/libs/exec/storage.h
index 76a937c4f8b..5cc2feb9070 100644
--- a/ydb/core/tablet_flat/test/libs/exec/storage.h
+++ b/ydb/core/tablet_flat/test/libs/exec/storage.h
@@ -14,7 +14,7 @@ namespace NFake {
using NStore = TEvBlobStorage;
TStorage(ui32 group)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TStorage::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TStorage::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
, Group(group)
, Model(new NFake::TProxyDS)
{
diff --git a/ydb/core/tablet_flat/test/libs/exec/warden.h b/ydb/core/tablet_flat/test/libs/exec/warden.h
index cc2afbde883..d00f7b02f58 100644
--- a/ydb/core/tablet_flat/test/libs/exec/warden.h
+++ b/ydb/core/tablet_flat/test/libs/exec/warden.h
@@ -28,7 +28,7 @@ namespace NFake {
using ELnLev = NUtil::ELnLev;
TWarden(ui32 groups)
- : ::NActors::IActor(static_cast<TReceiveFunc>(&TWarden::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
+ : ::NActors::IActor(static_cast<TReceiveFunc>(&TWarden::Inbox), NKikimrServices::TActivity::FAKE_ENV_A)
{
Y_VERIFY(groups < State.size(), "Too many groups requested");
diff --git a/ydb/core/tablet_flat/test/libs/rows/heap.h b/ydb/core/tablet_flat/test/libs/rows/heap.h
index c50decaa2d8..44411f87143 100644
--- a/ydb/core/tablet_flat/test/libs/rows/heap.h
+++ b/ydb/core/tablet_flat/test/libs/rows/heap.h
@@ -2,8 +2,8 @@
#include "rows.h"
-#include <util/generic/deque.h>
-
+#include <util/generic/deque.h>
+
namespace NKikimr {
namespace NTable {
namespace NTest {
diff --git a/ydb/core/test_tablet/defs.h b/ydb/core/test_tablet/defs.h
index 12f33fe5910..a41734db8df 100644
--- a/ydb/core/test_tablet/defs.h
+++ b/ydb/core/test_tablet/defs.h
@@ -1,10 +1,10 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/keyvalue/keyvalue_flat_impl.h>
#include <ydb/core/tablet_flat/flat_cxx_database.h>
#include <ydb/core/util/stlog.h>
-#include <ydb/core/protos/counters_testshard.pb.h>
+#include <ydb/core/protos/counters_testshard.pb.h>
#include <ydb/core/protos/test_shard.pb.h>
-#include <library/cpp/actors/core/actor_coroutine.h>
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <library/cpp/digest/md5/md5.h>
+#include <library/cpp/actors/core/actor_coroutine.h>
+#include <library/cpp/actors/interconnect/poller_actor.h>
+#include <library/cpp/digest/md5/md5.h>
diff --git a/ydb/core/test_tablet/events.h b/ydb/core/test_tablet/events.h
index 7c2abc7bbed..5f9248c8824 100644
--- a/ydb/core/test_tablet/events.h
+++ b/ydb/core/test_tablet/events.h
@@ -1,26 +1,26 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NTestShard {
-
- struct TEvTestShard {
- enum {
- EvControlRequest = EventSpaceBegin(TKikimrEvents::ES_TEST_SHARD),
- EvControlResponse,
- EvStateServerConnect,
- EvStateServerDisconnect,
- EvStateServerStatus,
- EvStateServerRequest,
- EvStateServerWriteResult,
- EvStateServerReadResult,
- };
- };
-
- struct TEvControlRequest : TEventPB<TEvControlRequest, NKikimrClient::TTestShardControlRequest, TEvTestShard::EvControlRequest> {
- };
-
- struct TEvControlResponse : TEventPB<TEvControlResponse, NKikimrClient::TTestShardControlResponse, TEvTestShard::EvControlResponse> {
- };
-
-} // NKikimr::NTestShard
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NTestShard {
+
+ struct TEvTestShard {
+ enum {
+ EvControlRequest = EventSpaceBegin(TKikimrEvents::ES_TEST_SHARD),
+ EvControlResponse,
+ EvStateServerConnect,
+ EvStateServerDisconnect,
+ EvStateServerStatus,
+ EvStateServerRequest,
+ EvStateServerWriteResult,
+ EvStateServerReadResult,
+ };
+ };
+
+ struct TEvControlRequest : TEventPB<TEvControlRequest, NKikimrClient::TTestShardControlRequest, TEvTestShard::EvControlRequest> {
+ };
+
+ struct TEvControlResponse : TEventPB<TEvControlResponse, NKikimrClient::TTestShardControlResponse, TEvTestShard::EvControlResponse> {
+ };
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_delete.cpp b/ydb/core/test_tablet/load_actor_delete.cpp
index a06ab6655ac..356e32efd21 100644
--- a/ydb/core/test_tablet/load_actor_delete.cpp
+++ b/ydb/core/test_tablet/load_actor_delete.cpp
@@ -1,77 +1,77 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- std::optional<TString> TLoadActor::FindKeyToDelete() {
- std::vector<std::tuple<ui64, TString>> options; // (accumLen, key)
- options.reserve(Keys.size());
- ui64 accumLen = 0;
- for (const auto& [key, info] : Keys) {
- if (info.ConfirmedState == info.PendingState && info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED) {
- accumLen += info.Len;
- options.emplace_back(accumLen, key);
- }
- }
- if (options.empty()) {
- return std::nullopt;
- }
-
- const size_t num = std::upper_bound(options.begin(), options.end(), std::make_tuple(
- TAppData::RandomProvider->Uniform(accumLen), TString())) - options.begin();
- Y_VERIFY(num < options.size());
- return std::get<1>(options[num]);
- }
-
- void TLoadActor::IssueDelete() {
- const ui64 barrier = TAppData::RandomProvider->Uniform(Settings.GetMinDataBytes(), Settings.GetMaxDataBytes());
- while (BytesOfData > barrier) {
- const auto& key = FindKeyToDelete();
- if (!key) {
- break;
- }
-
- auto ev = CreateRequest();
- auto& record = ev->Record;
- auto *del = record.AddCmdDeleteRange();
- auto *r = del->MutableRange();
- r->SetFrom(*key);
- r->SetIncludeFrom(true);
- r->SetTo(*key);
- r->SetIncludeTo(true);
-
- STLOG(PRI_INFO, TEST_SHARD, TS09, "deleting data", (TabletId, TabletId), (Key, key));
-
- const auto [difIt, difInserted] = DeletesInFlight.try_emplace(record.GetCookie(), *key);
- Y_VERIFY(difInserted);
- Y_VERIFY(difIt->second.KeysInQuery.size() == 1);
-
- const auto it = Keys.find(*key);
- Y_VERIFY(it != Keys.end());
- RegisterTransition(*it, ::NTestShard::TStateServer::CONFIRMED, ::NTestShard::TStateServer::DELETE_PENDING, std::move(ev));
-
- BytesOfData -= it->second.Len;
- BytesProcessed += it->second.Len;
- ++KeysDeleted;
- }
- }
-
- void TLoadActor::ProcessDeleteResult(ui64 cookie,
- const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TDeleteRangeResult>& results) {
- if (const auto difIt = DeletesInFlight.find(cookie); difIt != DeletesInFlight.end()) {
- TDeleteInfo& info = difIt->second;
- Y_VERIFY(info.KeysInQuery.size() == (size_t)results.size(), "%zu/%d", info.KeysInQuery.size(), results.size());
- for (size_t i = 0; i < info.KeysInQuery.size(); ++i) {
- // validate that delete was successful
- const auto& res = results[i];
- Y_VERIFY_S(res.GetStatus() == NKikimrProto::OK, "TabletId# " << TabletId << " CmdDeleteRange failed Status# "
- << NKikimrProto::EReplyStatus_Name(NKikimrProto::EReplyStatus(res.GetStatus())));
-
- const auto it = Keys.find(info.KeysInQuery[i]);
- Y_VERIFY(it != Keys.end());
- RegisterTransition(*it, ::NTestShard::TStateServer::DELETE_PENDING, ::NTestShard::TStateServer::DELETED);
- }
- DeletesInFlight.erase(difIt);
- }
- }
-
-} // NKikimr::NTestShard
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ std::optional<TString> TLoadActor::FindKeyToDelete() {
+ std::vector<std::tuple<ui64, TString>> options; // (accumLen, key)
+ options.reserve(Keys.size());
+ ui64 accumLen = 0;
+ for (const auto& [key, info] : Keys) {
+ if (info.ConfirmedState == info.PendingState && info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED) {
+ accumLen += info.Len;
+ options.emplace_back(accumLen, key);
+ }
+ }
+ if (options.empty()) {
+ return std::nullopt;
+ }
+
+ const size_t num = std::upper_bound(options.begin(), options.end(), std::make_tuple(
+ TAppData::RandomProvider->Uniform(accumLen), TString())) - options.begin();
+ Y_VERIFY(num < options.size());
+ return std::get<1>(options[num]);
+ }
+
+ void TLoadActor::IssueDelete() {
+ const ui64 barrier = TAppData::RandomProvider->Uniform(Settings.GetMinDataBytes(), Settings.GetMaxDataBytes());
+ while (BytesOfData > barrier) {
+ const auto& key = FindKeyToDelete();
+ if (!key) {
+ break;
+ }
+
+ auto ev = CreateRequest();
+ auto& record = ev->Record;
+ auto *del = record.AddCmdDeleteRange();
+ auto *r = del->MutableRange();
+ r->SetFrom(*key);
+ r->SetIncludeFrom(true);
+ r->SetTo(*key);
+ r->SetIncludeTo(true);
+
+ STLOG(PRI_INFO, TEST_SHARD, TS09, "deleting data", (TabletId, TabletId), (Key, key));
+
+ const auto [difIt, difInserted] = DeletesInFlight.try_emplace(record.GetCookie(), *key);
+ Y_VERIFY(difInserted);
+ Y_VERIFY(difIt->second.KeysInQuery.size() == 1);
+
+ const auto it = Keys.find(*key);
+ Y_VERIFY(it != Keys.end());
+ RegisterTransition(*it, ::NTestShard::TStateServer::CONFIRMED, ::NTestShard::TStateServer::DELETE_PENDING, std::move(ev));
+
+ BytesOfData -= it->second.Len;
+ BytesProcessed += it->second.Len;
+ ++KeysDeleted;
+ }
+ }
+
+ void TLoadActor::ProcessDeleteResult(ui64 cookie,
+ const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TDeleteRangeResult>& results) {
+ if (const auto difIt = DeletesInFlight.find(cookie); difIt != DeletesInFlight.end()) {
+ TDeleteInfo& info = difIt->second;
+ Y_VERIFY(info.KeysInQuery.size() == (size_t)results.size(), "%zu/%d", info.KeysInQuery.size(), results.size());
+ for (size_t i = 0; i < info.KeysInQuery.size(); ++i) {
+ // validate that delete was successful
+ const auto& res = results[i];
+ Y_VERIFY_S(res.GetStatus() == NKikimrProto::OK, "TabletId# " << TabletId << " CmdDeleteRange failed Status# "
+ << NKikimrProto::EReplyStatus_Name(NKikimrProto::EReplyStatus(res.GetStatus())));
+
+ const auto it = Keys.find(info.KeysInQuery[i]);
+ Y_VERIFY(it != Keys.end());
+ RegisterTransition(*it, ::NTestShard::TStateServer::DELETE_PENDING, ::NTestShard::TStateServer::DELETED);
+ }
+ DeletesInFlight.erase(difIt);
+ }
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_impl.cpp b/ydb/core/test_tablet/load_actor_impl.cpp
index 13857d4a39b..10d8ee385f5 100644
--- a/ydb/core/test_tablet/load_actor_impl.cpp
+++ b/ydb/core/test_tablet/load_actor_impl.cpp
@@ -1,140 +1,140 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- TLoadActor::TLoadActor(ui64 tabletId, ui32 generation, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& settings)
- : TabletId(tabletId)
- , Generation(generation)
- , Settings(settings)
- , StateServerWriteLatency(1024)
- , WriteLatency(1024)
- {}
-
- void TLoadActor::Bootstrap(const TActorId& parentId) {
- TabletActorId = parentId;
- Send(MakeStateServerInterfaceActorId(), new TEvStateServerConnect(Settings.GetStorageServerHost(),
- Settings.GetStorageServerPort()));
- Send(parentId, new TTestShard::TEvSwitchMode(TTestShard::EMode::STATE_SERVER_CONNECT));
- Become(&TThis::StateFunc);
- }
-
- void TLoadActor::PassAway() {
- Send(MakeStateServerInterfaceActorId(), new TEvStateServerDisconnect);
- if (ValidationActorId) {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, ValidationActorId, SelfId(), nullptr, 0));
- }
- TActorBootstrapped::PassAway();
- }
-
- void TLoadActor::Action() {
- if (ValidationActorId) { // do nothing while validation is in progress
- return;
- }
- if (StallCounter > 500) {
- if (WritesInFlight.empty() && DeletesInFlight.empty() && TransitionInFlight.empty()) {
- StallCounter = 0;
- } else {
- return;
- }
- }
- if (BytesProcessed > 2 * Settings.GetMaxDataBytes()) { // time to perform validation
- if (WritesInFlight.empty() && DeletesInFlight.empty() && TransitionInFlight.empty()) {
- RunValidation(false);
- }
- } else { // resume load
- while (WritesInFlight.size() < Settings.GetMaxInFlight()) { // write until there is space in inflight
- IssueWrite();
- }
- if (BytesOfData > Settings.GetMaxDataBytes()) { // delete some data if needed
- IssueDelete();
- }
- }
- }
-
- void TLoadActor::Handle(TEvStateServerStatus::TPtr ev) {
- if (ev->Get()->Connected) {
- RunValidation(true);
- } else {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
- PassAway();
- }
- }
-
- TDuration TLoadActor::GenerateRandomInterval(const NKikimrClient::TTestShardControlRequest::TTimeInterval& interval) {
- Y_VERIFY(interval.HasFrequency() && interval.HasMaxIntervalMs());
- const double frequency = interval.GetFrequency();
- const double xMin = exp(-frequency * interval.GetMaxIntervalMs() * 1e-3);
- const double x = Max(xMin, TAppData::RandomProvider->GenRandReal2());
- return TDuration::Seconds(-log(x) / frequency);
- }
-
- TDuration TLoadActor::GenerateRandomInterval(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TTimeInterval>& intervals) {
- return intervals.empty()
- ? TDuration::Zero()
- : GenerateRandomInterval(intervals[intervals.size() == 1 ? 0 : PickInterval(intervals)]);
- }
-
- size_t TLoadActor::GenerateRandomSize(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TSizeInterval>& intervals,
- bool *isInline) {
- Y_VERIFY(!intervals.empty());
- const auto& interval = intervals[PickInterval(intervals)];
- Y_VERIFY(interval.HasMin() && interval.HasMax() && interval.GetMin() <= interval.GetMax());
- *isInline = interval.GetInline();
- return TAppData::RandomProvider->Uniform(interval.GetMin(), interval.GetMax());
- }
-
- std::unique_ptr<TEvKeyValue::TEvRequest> TLoadActor::CreateRequest() {
- auto request = std::make_unique<TEvKeyValue::TEvRequest>();
- auto& r = request->Record;
- r.SetTabletId(TabletId);
- r.SetCookie(++LastCookie);
- ++StallCounter;
- return request;
- }
-
- void TLoadActor::Handle(TEvKeyValue::TEvResponse::TPtr ev) {
- Y_VERIFY(!ValidationActorId); // no requests during validation
- auto& record = ev->Get()->Record;
- if (record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- STLOG(PRI_ERROR, TEST_SHARD, TS18, "TEvKeyValue::TEvRequest failed", (TabletId, TabletId),
- (Status, record.GetStatus()), (ErrorReason, record.GetErrorReason()));
- if (const auto it = WritesInFlight.find(record.GetCookie()); it != WritesInFlight.end()) {
- for (const TString& key : it->second.KeysInQuery) {
- const auto it = Keys.find(key);
- Y_VERIFY_S(it != Keys.end(), "Key# " << key << " not found in Keys dict");
- STLOG(PRI_WARN, TEST_SHARD, TS19, "write failed", (TabletId, TabletId), (Key, key));
- RegisterTransition(*it, ::NTestShard::TStateServer::WRITE_PENDING, ::NTestShard::TStateServer::DELETED);
- }
- WritesInFlight.erase(it);
- }
- if (const auto it = DeletesInFlight.find(record.GetCookie()); it != DeletesInFlight.end()) {
- for (const TString& key : it->second.KeysInQuery) {
- const auto it = Keys.find(key);
- Y_VERIFY_S(it != Keys.end(), "Key# " << key << " not found in Keys dict");
- STLOG(PRI_WARN, TEST_SHARD, TS20, "delete failed", (TabletId, TabletId), (Key, key));
- RegisterTransition(*it, ::NTestShard::TStateServer::DELETE_PENDING, ::NTestShard::TStateServer::CONFIRMED);
- BytesOfData += it->second.Len;
- }
- DeletesInFlight.erase(it);
- }
- } else {
- STLOG(PRI_INFO, TEST_SHARD, TS04, "TEvKeyValue::TEvResponse", (TabletId, TabletId), (Msg, ev->Get()->ToString()));
- ProcessWriteResult(record.GetCookie(), record.GetWriteResult());
- ProcessDeleteResult(record.GetCookie(), record.GetDeleteRangeResult());
- }
- Action();
- }
-
- void TTestShard::StartActivities() {
- if (!ActivityActorId && Settings) {
- ActivityActorId = Register(new TLoadActor(TabletID(), Executor()->Generation(), *Settings),
- TMailboxType::ReadAsFilled, AppData()->UserPoolId);
- }
- }
-
- void TTestShard::PassAway() {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, ActivityActorId, {}, {}, 0));
- TKeyValueFlat::PassAway();
- }
-
-} // NKikimr::NTestShard
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ TLoadActor::TLoadActor(ui64 tabletId, ui32 generation, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& settings)
+ : TabletId(tabletId)
+ , Generation(generation)
+ , Settings(settings)
+ , StateServerWriteLatency(1024)
+ , WriteLatency(1024)
+ {}
+
+ void TLoadActor::Bootstrap(const TActorId& parentId) {
+ TabletActorId = parentId;
+ Send(MakeStateServerInterfaceActorId(), new TEvStateServerConnect(Settings.GetStorageServerHost(),
+ Settings.GetStorageServerPort()));
+ Send(parentId, new TTestShard::TEvSwitchMode(TTestShard::EMode::STATE_SERVER_CONNECT));
+ Become(&TThis::StateFunc);
+ }
+
+ void TLoadActor::PassAway() {
+ Send(MakeStateServerInterfaceActorId(), new TEvStateServerDisconnect);
+ if (ValidationActorId) {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, ValidationActorId, SelfId(), nullptr, 0));
+ }
+ TActorBootstrapped::PassAway();
+ }
+
+ void TLoadActor::Action() {
+ if (ValidationActorId) { // do nothing while validation is in progress
+ return;
+ }
+ if (StallCounter > 500) {
+ if (WritesInFlight.empty() && DeletesInFlight.empty() && TransitionInFlight.empty()) {
+ StallCounter = 0;
+ } else {
+ return;
+ }
+ }
+ if (BytesProcessed > 2 * Settings.GetMaxDataBytes()) { // time to perform validation
+ if (WritesInFlight.empty() && DeletesInFlight.empty() && TransitionInFlight.empty()) {
+ RunValidation(false);
+ }
+ } else { // resume load
+ while (WritesInFlight.size() < Settings.GetMaxInFlight()) { // write until there is space in inflight
+ IssueWrite();
+ }
+ if (BytesOfData > Settings.GetMaxDataBytes()) { // delete some data if needed
+ IssueDelete();
+ }
+ }
+ }
+
+ void TLoadActor::Handle(TEvStateServerStatus::TPtr ev) {
+ if (ev->Get()->Connected) {
+ RunValidation(true);
+ } else {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
+ PassAway();
+ }
+ }
+
+ TDuration TLoadActor::GenerateRandomInterval(const NKikimrClient::TTestShardControlRequest::TTimeInterval& interval) {
+ Y_VERIFY(interval.HasFrequency() && interval.HasMaxIntervalMs());
+ const double frequency = interval.GetFrequency();
+ const double xMin = exp(-frequency * interval.GetMaxIntervalMs() * 1e-3);
+ const double x = Max(xMin, TAppData::RandomProvider->GenRandReal2());
+ return TDuration::Seconds(-log(x) / frequency);
+ }
+
+ TDuration TLoadActor::GenerateRandomInterval(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TTimeInterval>& intervals) {
+ return intervals.empty()
+ ? TDuration::Zero()
+ : GenerateRandomInterval(intervals[intervals.size() == 1 ? 0 : PickInterval(intervals)]);
+ }
+
+ size_t TLoadActor::GenerateRandomSize(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TSizeInterval>& intervals,
+ bool *isInline) {
+ Y_VERIFY(!intervals.empty());
+ const auto& interval = intervals[PickInterval(intervals)];
+ Y_VERIFY(interval.HasMin() && interval.HasMax() && interval.GetMin() <= interval.GetMax());
+ *isInline = interval.GetInline();
+ return TAppData::RandomProvider->Uniform(interval.GetMin(), interval.GetMax());
+ }
+
+ std::unique_ptr<TEvKeyValue::TEvRequest> TLoadActor::CreateRequest() {
+ auto request = std::make_unique<TEvKeyValue::TEvRequest>();
+ auto& r = request->Record;
+ r.SetTabletId(TabletId);
+ r.SetCookie(++LastCookie);
+ ++StallCounter;
+ return request;
+ }
+
+ void TLoadActor::Handle(TEvKeyValue::TEvResponse::TPtr ev) {
+ Y_VERIFY(!ValidationActorId); // no requests during validation
+ auto& record = ev->Get()->Record;
+ if (record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ STLOG(PRI_ERROR, TEST_SHARD, TS18, "TEvKeyValue::TEvRequest failed", (TabletId, TabletId),
+ (Status, record.GetStatus()), (ErrorReason, record.GetErrorReason()));
+ if (const auto it = WritesInFlight.find(record.GetCookie()); it != WritesInFlight.end()) {
+ for (const TString& key : it->second.KeysInQuery) {
+ const auto it = Keys.find(key);
+ Y_VERIFY_S(it != Keys.end(), "Key# " << key << " not found in Keys dict");
+ STLOG(PRI_WARN, TEST_SHARD, TS19, "write failed", (TabletId, TabletId), (Key, key));
+ RegisterTransition(*it, ::NTestShard::TStateServer::WRITE_PENDING, ::NTestShard::TStateServer::DELETED);
+ }
+ WritesInFlight.erase(it);
+ }
+ if (const auto it = DeletesInFlight.find(record.GetCookie()); it != DeletesInFlight.end()) {
+ for (const TString& key : it->second.KeysInQuery) {
+ const auto it = Keys.find(key);
+ Y_VERIFY_S(it != Keys.end(), "Key# " << key << " not found in Keys dict");
+ STLOG(PRI_WARN, TEST_SHARD, TS20, "delete failed", (TabletId, TabletId), (Key, key));
+ RegisterTransition(*it, ::NTestShard::TStateServer::DELETE_PENDING, ::NTestShard::TStateServer::CONFIRMED);
+ BytesOfData += it->second.Len;
+ }
+ DeletesInFlight.erase(it);
+ }
+ } else {
+ STLOG(PRI_INFO, TEST_SHARD, TS04, "TEvKeyValue::TEvResponse", (TabletId, TabletId), (Msg, ev->Get()->ToString()));
+ ProcessWriteResult(record.GetCookie(), record.GetWriteResult());
+ ProcessDeleteResult(record.GetCookie(), record.GetDeleteRangeResult());
+ }
+ Action();
+ }
+
+ void TTestShard::StartActivities() {
+ if (!ActivityActorId && Settings) {
+ ActivityActorId = Register(new TLoadActor(TabletID(), Executor()->Generation(), *Settings),
+ TMailboxType::ReadAsFilled, AppData()->UserPoolId);
+ }
+ }
+
+ void TTestShard::PassAway() {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, ActivityActorId, {}, {}, 0));
+ TKeyValueFlat::PassAway();
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_impl.h b/ydb/core/test_tablet/load_actor_impl.h
index 71bd0e4f41e..6743db7bd05 100644
--- a/ydb/core/test_tablet/load_actor_impl.h
+++ b/ydb/core/test_tablet/load_actor_impl.h
@@ -1,168 +1,168 @@
-#pragma once
-
-#include "defs.h"
-
-#include "test_shard_impl.h"
-#include "time_series.h"
-#include "state_server_interface.h"
-
-namespace NKikimr::NTestShard {
-
- class TLoadActor : public TActorBootstrapped<TLoadActor> {
- const ui64 TabletId;
- const ui32 Generation;
- TActorId TabletActorId;
- const NKikimrClient::TTestShardControlRequest::TCmdInitialize Settings;
-
+#pragma once
+
+#include "defs.h"
+
+#include "test_shard_impl.h"
+#include "time_series.h"
+#include "state_server_interface.h"
+
+namespace NKikimr::NTestShard {
+
+ class TLoadActor : public TActorBootstrapped<TLoadActor> {
+ const ui64 TabletId;
+ const ui32 Generation;
+ TActorId TabletActorId;
+ const NKikimrClient::TTestShardControlRequest::TCmdInitialize Settings;
+
ui64 ValidationRunningCount = 0;
- struct TKeyInfo {
- const ui32 Len = 0;
- ::NTestShard::TStateServer::EEntityState ConfirmedState = ::NTestShard::TStateServer::ABSENT;
- ::NTestShard::TStateServer::EEntityState PendingState = ::NTestShard::TStateServer::ABSENT;
- std::unique_ptr<TEvKeyValue::TEvRequest> Request;
-
- TKeyInfo(ui32 len)
- : Len(len)
- {}
- };
-
- enum {
- EvValidationFinished = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- struct TEvValidationFinished : TEventLocal<TEvValidationFinished, EvValidationFinished> {
- std::unordered_map<TString, TKeyInfo> Keys;
-
- TEvValidationFinished(std::unordered_map<TString, TKeyInfo> keys)
- : Keys(std::move(keys))
- {}
- };
-
- public:
- TLoadActor(ui64 tabletId, ui32 generation, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& settings);
- void Bootstrap(const TActorId& parentId);
- void PassAway() override;
- void Action();
- void Handle(TEvStateServerStatus::TPtr ev);
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvKeyValue::TEvResponse, Handle);
- hFunc(NMon::TEvRemoteHttpInfo, Handle);
- hFunc(TEvStateServerStatus, Handle);
- hFunc(TEvStateServerWriteResult, Handle);
- hFunc(TEvValidationFinished, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Generic request/response management
-
- ui32 BytesProcessed = 0;
- ui32 StallCounter = 0;
- ui64 LastCookie = 0;
-
- std::unique_ptr<TEvKeyValue::TEvRequest> CreateRequest();
- void Handle(TEvKeyValue::TEvResponse::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Key state
-
- std::unordered_map<TString, TKeyInfo> Keys;
-
- using TKey = std::unordered_map<TString, TKeyInfo>::value_type;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // State validation actor
-
- class TValidationActor;
- friend class TValidationActor;
-
- TActorId ValidationActorId;
- void RunValidation(bool initialCheck);
- void Handle(TEvValidationFinished::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // KV tablet write management code
-
- struct TWriteInfo {
- THPTimer Timer; // reset when write request is issued
- std::vector<TString> KeysInQuery;
-
- TWriteInfo(TString key)
- : KeysInQuery(1, std::move(key))
- {}
- };
-
- ui64 BytesOfData = 0;
-
- std::unordered_map<ui64, TWriteInfo> WritesInFlight; // cookie -> TWriteInfo
- ui32 KeysWritten = 0;
- static constexpr TDuration WriteSpeedWindow = TDuration::Seconds(10);
- TSpeedMeter WriteSpeed{WriteSpeedWindow};
- TTimeSeries StateServerWriteLatency;
- TTimeSeries WriteLatency;
-
- void GenerateKeyValue(TString *key, TString *value, bool *isInline);
- void IssueWrite();
- void ProcessWriteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TWriteResult>& results);
- void TrimBytesWritten(TInstant now);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // KV tablet delete management code
-
- struct TDeleteInfo {
- std::vector<TString> KeysInQuery; // keys being deleted
-
- TDeleteInfo(TString key)
- : KeysInQuery(1, std::move(key))
- {}
- };
-
- std::unordered_map<ui64, TDeleteInfo> DeletesInFlight; // cookie -> TDeleteInfo
- ui32 KeysDeleted = 0;
-
- std::optional<TString> FindKeyToDelete();
- void IssueDelete();
- void ProcessDeleteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TDeleteRangeResult>& results);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // State management
-
- std::deque<TKey*> TransitionInFlight;
-
- void RegisterTransition(TKey& key, ::NTestShard::TStateServer::EEntityState from,
- ::NTestShard::TStateServer::EEntityState to, std::unique_ptr<TEvKeyValue::TEvRequest> ev = nullptr);
- void Handle(TEvStateServerWriteResult::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Tablet monitoring
-
- void Handle(NMon::TEvRemoteHttpInfo::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Random generators
-
- template<typename T>
- size_t PickInterval(const google::protobuf::RepeatedPtrField<T>& intervals) {
- std::vector<ui64> cw;
- ui64 w = 0;
- cw.reserve(intervals.size());
- for (const auto& interval : intervals) {
- Y_VERIFY(interval.HasWeight());
- Y_VERIFY(interval.GetWeight());
- w += interval.GetWeight();
- cw.push_back(w);
- }
- const size_t num = std::upper_bound(cw.begin(), cw.end(), TAppData::RandomProvider->Uniform(w)) - cw.begin();
- Y_VERIFY(num < cw.size());
- return num;
- }
-
- TDuration GenerateRandomInterval(const NKikimrClient::TTestShardControlRequest::TTimeInterval& interval);
- TDuration GenerateRandomInterval(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TTimeInterval>& intervals);
- size_t GenerateRandomSize(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TSizeInterval>& intervals,
- bool *isInline);
- };
-
-} // NKikimr::NTestShard
+ struct TKeyInfo {
+ const ui32 Len = 0;
+ ::NTestShard::TStateServer::EEntityState ConfirmedState = ::NTestShard::TStateServer::ABSENT;
+ ::NTestShard::TStateServer::EEntityState PendingState = ::NTestShard::TStateServer::ABSENT;
+ std::unique_ptr<TEvKeyValue::TEvRequest> Request;
+
+ TKeyInfo(ui32 len)
+ : Len(len)
+ {}
+ };
+
+ enum {
+ EvValidationFinished = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ struct TEvValidationFinished : TEventLocal<TEvValidationFinished, EvValidationFinished> {
+ std::unordered_map<TString, TKeyInfo> Keys;
+
+ TEvValidationFinished(std::unordered_map<TString, TKeyInfo> keys)
+ : Keys(std::move(keys))
+ {}
+ };
+
+ public:
+ TLoadActor(ui64 tabletId, ui32 generation, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& settings);
+ void Bootstrap(const TActorId& parentId);
+ void PassAway() override;
+ void Action();
+ void Handle(TEvStateServerStatus::TPtr ev);
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvKeyValue::TEvResponse, Handle);
+ hFunc(NMon::TEvRemoteHttpInfo, Handle);
+ hFunc(TEvStateServerStatus, Handle);
+ hFunc(TEvStateServerWriteResult, Handle);
+ hFunc(TEvValidationFinished, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Generic request/response management
+
+ ui32 BytesProcessed = 0;
+ ui32 StallCounter = 0;
+ ui64 LastCookie = 0;
+
+ std::unique_ptr<TEvKeyValue::TEvRequest> CreateRequest();
+ void Handle(TEvKeyValue::TEvResponse::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Key state
+
+ std::unordered_map<TString, TKeyInfo> Keys;
+
+ using TKey = std::unordered_map<TString, TKeyInfo>::value_type;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // State validation actor
+
+ class TValidationActor;
+ friend class TValidationActor;
+
+ TActorId ValidationActorId;
+ void RunValidation(bool initialCheck);
+ void Handle(TEvValidationFinished::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // KV tablet write management code
+
+ struct TWriteInfo {
+ THPTimer Timer; // reset when write request is issued
+ std::vector<TString> KeysInQuery;
+
+ TWriteInfo(TString key)
+ : KeysInQuery(1, std::move(key))
+ {}
+ };
+
+ ui64 BytesOfData = 0;
+
+ std::unordered_map<ui64, TWriteInfo> WritesInFlight; // cookie -> TWriteInfo
+ ui32 KeysWritten = 0;
+ static constexpr TDuration WriteSpeedWindow = TDuration::Seconds(10);
+ TSpeedMeter WriteSpeed{WriteSpeedWindow};
+ TTimeSeries StateServerWriteLatency;
+ TTimeSeries WriteLatency;
+
+ void GenerateKeyValue(TString *key, TString *value, bool *isInline);
+ void IssueWrite();
+ void ProcessWriteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TWriteResult>& results);
+ void TrimBytesWritten(TInstant now);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // KV tablet delete management code
+
+ struct TDeleteInfo {
+ std::vector<TString> KeysInQuery; // keys being deleted
+
+ TDeleteInfo(TString key)
+ : KeysInQuery(1, std::move(key))
+ {}
+ };
+
+ std::unordered_map<ui64, TDeleteInfo> DeletesInFlight; // cookie -> TDeleteInfo
+ ui32 KeysDeleted = 0;
+
+ std::optional<TString> FindKeyToDelete();
+ void IssueDelete();
+ void ProcessDeleteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TDeleteRangeResult>& results);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // State management
+
+ std::deque<TKey*> TransitionInFlight;
+
+ void RegisterTransition(TKey& key, ::NTestShard::TStateServer::EEntityState from,
+ ::NTestShard::TStateServer::EEntityState to, std::unique_ptr<TEvKeyValue::TEvRequest> ev = nullptr);
+ void Handle(TEvStateServerWriteResult::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Tablet monitoring
+
+ void Handle(NMon::TEvRemoteHttpInfo::TPtr ev);
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Random generators
+
+ template<typename T>
+ size_t PickInterval(const google::protobuf::RepeatedPtrField<T>& intervals) {
+ std::vector<ui64> cw;
+ ui64 w = 0;
+ cw.reserve(intervals.size());
+ for (const auto& interval : intervals) {
+ Y_VERIFY(interval.HasWeight());
+ Y_VERIFY(interval.GetWeight());
+ w += interval.GetWeight();
+ cw.push_back(w);
+ }
+ const size_t num = std::upper_bound(cw.begin(), cw.end(), TAppData::RandomProvider->Uniform(w)) - cw.begin();
+ Y_VERIFY(num < cw.size());
+ return num;
+ }
+
+ TDuration GenerateRandomInterval(const NKikimrClient::TTestShardControlRequest::TTimeInterval& interval);
+ TDuration GenerateRandomInterval(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TTimeInterval>& intervals);
+ size_t GenerateRandomSize(const google::protobuf::RepeatedPtrField<NKikimrClient::TTestShardControlRequest::TSizeInterval>& intervals,
+ bool *isInline);
+ };
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_mon.cpp b/ydb/core/test_tablet/load_actor_mon.cpp
index 24dfb0bc3c2..de3a8658cc4 100644
--- a/ydb/core/test_tablet/load_actor_mon.cpp
+++ b/ydb/core/test_tablet/load_actor_mon.cpp
@@ -1,159 +1,159 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- void TLoadActor::Handle(NMon::TEvRemoteHttpInfo::TPtr ev) {
- class TQueryProcessorActor : public TActorBootstrapped<TQueryProcessorActor> {
- NMon::TEvRemoteHttpInfo::TPtr Ev;
- const TActorId ValidationActorId;
- TString Html;
- TString ValidationHtml;
-
- public:
- TQueryProcessorActor(NMon::TEvRemoteHttpInfo::TPtr ev, TLoadActor *self)
- : Ev(ev)
- , ValidationActorId(self->ValidationActorId)
- {
- Html = RenderHtml(self);
- }
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
- if (ValidationActorId) {
- Send(ValidationActorId, new NMon::TEvRemoteHttpInfo(Ev->Get()->Query));
- } else {
- PassAway();
- }
- }
-
- void Handle(NMon::TEvRemoteHttpInfoRes::TPtr ev) {
- ValidationHtml = ev->Get()->Html;
- PassAway();
- }
-
- TString RenderHtml(TLoadActor *self) {
- const TInstant now = TActivationContext::Now();
- const TCgiParameters& params = Ev->Get()->Cgi();
- TStringStream str;
- HTML(str) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Load Actor";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "Parameter"; }
- TABLEH() { str << "Value"; }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "Tablet id"; }
- TABLED() { str << self->TabletId; }
- }
-
- TABLER() {
- TABLED() { str << "Generation"; }
- TABLED() { str << self->Generation; }
- }
-
- TABLER() {
- size_t numPoints = 0;
- TDuration timeSpan;
- const ui64 speed = self->WriteSpeed.GetSpeedInBytesPerSecond(now, &numPoints, &timeSpan);
- TABLED() { str << "Write speed"; }
- TABLED() { str << Sprintf("%.2lf", speed * 1e-6) << " MB/s @" << numPoints << ":" << timeSpan; }
- }
-
- TABLER() {
- TABLED() { str << "Bytes of data stored"; }
- TABLED() { str << self->BytesOfData; }
- }
-
- TABLER() {
- TABLED() { str << "Bytes of trash stored"; }
- TABLED() { str << params.Get("trashvol"); }
- }
-
- TABLER() {
- TABLED() { str << "Bytes processed"; }
- TABLED() { str << self->BytesProcessed; }
- }
-
- TABLER() {
- TABLED() { str << "Bytes written"; }
- TABLED() { str << self->WriteSpeed.GetBytesAccum(); }
- }
-
- TABLER() {
- TABLED() { str << "Keys written"; }
- TABLED() { str << self->KeysWritten; }
- }
-
- TABLER() {
- TABLED() { str << "Keys deleted"; }
- TABLED() { str << self->KeysDeleted; }
- }
-
- TABLER() {
- TABLED() { str << "Writes in flight"; }
- TABLED() { str << self->WritesInFlight.size(); }
- }
-
- TABLER() {
- TABLED() { str << "Delete requests in flight"; }
- TABLED() { str << self->DeletesInFlight.size(); }
- }
-
- TABLER() {
- size_t num = 0;
- for (const auto& [cookie, item] : self->DeletesInFlight) {
- num += item.KeysInQuery.size();
- }
- TABLED() { str << "Delete keys in flight"; }
- TABLED() { str << num; }
- }
-
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ void TLoadActor::Handle(NMon::TEvRemoteHttpInfo::TPtr ev) {
+ class TQueryProcessorActor : public TActorBootstrapped<TQueryProcessorActor> {
+ NMon::TEvRemoteHttpInfo::TPtr Ev;
+ const TActorId ValidationActorId;
+ TString Html;
+ TString ValidationHtml;
+
+ public:
+ TQueryProcessorActor(NMon::TEvRemoteHttpInfo::TPtr ev, TLoadActor *self)
+ : Ev(ev)
+ , ValidationActorId(self->ValidationActorId)
+ {
+ Html = RenderHtml(self);
+ }
+
+ void Bootstrap() {
+ Become(&TThis::StateFunc);
+ if (ValidationActorId) {
+ Send(ValidationActorId, new NMon::TEvRemoteHttpInfo(Ev->Get()->Query));
+ } else {
+ PassAway();
+ }
+ }
+
+ void Handle(NMon::TEvRemoteHttpInfoRes::TPtr ev) {
+ ValidationHtml = ev->Get()->Html;
+ PassAway();
+ }
+
+ TString RenderHtml(TLoadActor *self) {
+ const TInstant now = TActivationContext::Now();
+ const TCgiParameters& params = Ev->Get()->Cgi();
+ TStringStream str;
+ HTML(str) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Load Actor";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "Parameter"; }
+ TABLEH() { str << "Value"; }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "Tablet id"; }
+ TABLED() { str << self->TabletId; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Generation"; }
+ TABLED() { str << self->Generation; }
+ }
+
+ TABLER() {
+ size_t numPoints = 0;
+ TDuration timeSpan;
+ const ui64 speed = self->WriteSpeed.GetSpeedInBytesPerSecond(now, &numPoints, &timeSpan);
+ TABLED() { str << "Write speed"; }
+ TABLED() { str << Sprintf("%.2lf", speed * 1e-6) << " MB/s @" << numPoints << ":" << timeSpan; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Bytes of data stored"; }
+ TABLED() { str << self->BytesOfData; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Bytes of trash stored"; }
+ TABLED() { str << params.Get("trashvol"); }
+ }
+
+ TABLER() {
+ TABLED() { str << "Bytes processed"; }
+ TABLED() { str << self->BytesProcessed; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Bytes written"; }
+ TABLED() { str << self->WriteSpeed.GetBytesAccum(); }
+ }
+
+ TABLER() {
+ TABLED() { str << "Keys written"; }
+ TABLED() { str << self->KeysWritten; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Keys deleted"; }
+ TABLED() { str << self->KeysDeleted; }
+ }
+
+ TABLER() {
+ TABLED() { str << "Writes in flight"; }
+ TABLED() { str << self->WritesInFlight.size(); }
+ }
+
+ TABLER() {
+ TABLED() { str << "Delete requests in flight"; }
+ TABLED() { str << self->DeletesInFlight.size(); }
+ }
+
+ TABLER() {
+ size_t num = 0;
+ for (const auto& [cookie, item] : self->DeletesInFlight) {
+ num += item.KeysInQuery.size();
+ }
+ TABLED() { str << "Delete keys in flight"; }
+ TABLED() { str << num; }
+ }
+
TABLER() {
TABLED() { str << "Count of validation runnings"; }
TABLED() { str << self->ValidationRunningCount; }
}
- const std::vector<double> ps{0.0, 0.5, 0.9, 0.99, 1.0};
-
- auto output = [&](auto& r, const char *name) {
- auto res = r.Percentiles(ps);
- for (size_t i = 0; i < ps.size(); ++i) {
- TABLER() {
- TABLED() { str << (i ? "" : name); }
- TABLED() { str << Sprintf("%4.2lf", ps[i]) << "# " << res[i]; }
- }
- }
- };
-
- output(self->StateServerWriteLatency, "StateServerWriteLatency");
- output(self->WriteLatency, "WriteLatency");
- }
- }
- }
- }
- }
- return str.Str();
- }
-
- void PassAway() override {
- Send(Ev->Sender, new NMon::TEvRemoteHttpInfoRes(Html + ValidationHtml), 0, Ev->Cookie);
- TActorBootstrapped::PassAway();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(NMon::TEvRemoteHttpInfoRes, Handle);
- )
- };
-
- Register(new TQueryProcessorActor(ev, this));
- }
-
-} // NKikimr::NTestShard
+ const std::vector<double> ps{0.0, 0.5, 0.9, 0.99, 1.0};
+
+ auto output = [&](auto& r, const char *name) {
+ auto res = r.Percentiles(ps);
+ for (size_t i = 0; i < ps.size(); ++i) {
+ TABLER() {
+ TABLED() { str << (i ? "" : name); }
+ TABLED() { str << Sprintf("%4.2lf", ps[i]) << "# " << res[i]; }
+ }
+ }
+ };
+
+ output(self->StateServerWriteLatency, "StateServerWriteLatency");
+ output(self->WriteLatency, "WriteLatency");
+ }
+ }
+ }
+ }
+ }
+ return str.Str();
+ }
+
+ void PassAway() override {
+ Send(Ev->Sender, new NMon::TEvRemoteHttpInfoRes(Html + ValidationHtml), 0, Ev->Cookie);
+ TActorBootstrapped::PassAway();
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(NMon::TEvRemoteHttpInfoRes, Handle);
+ )
+ };
+
+ Register(new TQueryProcessorActor(ev, this));
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_read_validate.cpp b/ydb/core/test_tablet/load_actor_read_validate.cpp
index f6fc171f1ec..6d8b85eff70 100644
--- a/ydb/core/test_tablet/load_actor_read_validate.cpp
+++ b/ydb/core/test_tablet/load_actor_read_validate.cpp
@@ -1,24 +1,24 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- class TLoadActor::TValidationActor : public TActorBootstrapped<TValidationActor> {
- const NKikimrClient::TTestShardControlRequest::TCmdInitialize Settings;
- const ui64 TabletId;
- const TActorId TabletActorId;
- const ui32 Generation;
- const bool InitialCheck;
- TActorId ParentId;
- std::optional<TString> LastKey;
- std::unordered_map<TString, ::NTestShard::TStateServer::EEntityState> State;
- TString ReadStateCookie;
- bool StateReadComplete = false, KeyValueReadComplete = false, StateValidated = false;
- std::unordered_map<TString, TKeyInfo> KeysBefore;
- std::unordered_map<TString, TKeyInfo> Keys;
- std::deque<TKey*> TransitionInFlight;
- std::unordered_map<ui64, TString> QueriesInFlight;
- ui64 LastCookie = 0;
-
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ class TLoadActor::TValidationActor : public TActorBootstrapped<TValidationActor> {
+ const NKikimrClient::TTestShardControlRequest::TCmdInitialize Settings;
+ const ui64 TabletId;
+ const TActorId TabletActorId;
+ const ui32 Generation;
+ const bool InitialCheck;
+ TActorId ParentId;
+ std::optional<TString> LastKey;
+ std::unordered_map<TString, ::NTestShard::TStateServer::EEntityState> State;
+ TString ReadStateCookie;
+ bool StateReadComplete = false, KeyValueReadComplete = false, StateValidated = false;
+ std::unordered_map<TString, TKeyInfo> KeysBefore;
+ std::unordered_map<TString, TKeyInfo> Keys;
+ std::deque<TKey*> TransitionInFlight;
+ std::unordered_map<ui64, TString> QueriesInFlight;
+ ui64 LastCookie = 0;
+
bool IssueReadMode = false; // true - via EvRequest, false - via EvReadRequest
bool IssueReadRangeMode = false; // true - via EvRequest, false - via EvReadRequest
@@ -27,70 +27,70 @@ namespace NKikimr::NTestShard {
ui32 WaitedReadRangesViaEvResponse = 0;
ui32 WaitedReadRangesViaEvReadRangeResponse = 0;
- // read retry logic
- std::unordered_set<TString> KeyReadsWaitingForRetry;
- ui32 RetryCount = 0;
- bool SendRetriesPending = false;
-
- enum {
- EvRetryKeyReads = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- public:
- TValidationActor(TLoadActor& self, bool initialCheck)
- : Settings(self.Settings)
- , TabletId(self.TabletId)
- , TabletActorId(self.TabletActorId)
- , Generation(self.Generation)
- , InitialCheck(initialCheck)
- , KeysBefore(std::exchange(self.Keys, {}))
- {
- // ensure no concurrent operations are running
- Y_VERIFY(self.WritesInFlight.empty());
- Y_VERIFY(self.DeletesInFlight.empty());
- Y_VERIFY(self.TransitionInFlight.empty());
- for (const auto& [key, info] : KeysBefore) {
- Y_VERIFY(info.ConfirmedState == info.PendingState);
- }
- }
-
- void Bootstrap(const TActorId& parentId) {
- ParentId = parentId;
- Send(MakeStateServerInterfaceActorId(), new TEvStateServerConnect(Settings.GetStorageServerHost(),
- Settings.GetStorageServerPort()));
- IssueNextReadRangeQuery();
- STLOG(PRI_INFO, TEST_SHARD, TS07, "starting read&validate", (TabletId, TabletId));
- Become(&TThis::StateFunc);
- }
-
- void PassAway() override {
- Send(MakeStateServerInterfaceActorId(), new TEvStateServerDisconnect);
- TActorBootstrapped::PassAway();
- }
-
- void Handle(TEvStateServerStatus::TPtr ev) {
- if (ev->Get()->Connected) {
- IssueNextStateServerQuery();
- } else {
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
- PassAway();
- }
- }
-
+ // read retry logic
+ std::unordered_set<TString> KeyReadsWaitingForRetry;
+ ui32 RetryCount = 0;
+ bool SendRetriesPending = false;
+
+ enum {
+ EvRetryKeyReads = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ public:
+ TValidationActor(TLoadActor& self, bool initialCheck)
+ : Settings(self.Settings)
+ , TabletId(self.TabletId)
+ , TabletActorId(self.TabletActorId)
+ , Generation(self.Generation)
+ , InitialCheck(initialCheck)
+ , KeysBefore(std::exchange(self.Keys, {}))
+ {
+ // ensure no concurrent operations are running
+ Y_VERIFY(self.WritesInFlight.empty());
+ Y_VERIFY(self.DeletesInFlight.empty());
+ Y_VERIFY(self.TransitionInFlight.empty());
+ for (const auto& [key, info] : KeysBefore) {
+ Y_VERIFY(info.ConfirmedState == info.PendingState);
+ }
+ }
+
+ void Bootstrap(const TActorId& parentId) {
+ ParentId = parentId;
+ Send(MakeStateServerInterfaceActorId(), new TEvStateServerConnect(Settings.GetStorageServerHost(),
+ Settings.GetStorageServerPort()));
+ IssueNextReadRangeQuery();
+ STLOG(PRI_INFO, TEST_SHARD, TS07, "starting read&validate", (TabletId, TabletId));
+ Become(&TThis::StateFunc);
+ }
+
+ void PassAway() override {
+ Send(MakeStateServerInterfaceActorId(), new TEvStateServerDisconnect);
+ TActorBootstrapped::PassAway();
+ }
+
+ void Handle(TEvStateServerStatus::TPtr ev) {
+ if (ev->Get()->Connected) {
+ IssueNextStateServerQuery();
+ } else {
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
+ PassAway();
+ }
+ }
+
void SendReadRangeViaEvRequest() {
- auto request = std::make_unique<TEvKeyValue::TEvRequest>();
- auto& record = request->Record;
- record.SetTabletId(TabletId);
- record.SetCookie(0);
- auto *read = record.AddCmdReadRange();
- auto *r = read->MutableRange();
- if (LastKey) {
- r->SetFrom(*LastKey);
- r->SetIncludeFrom(false);
- }
- Send(TabletActorId, request.release());
- }
-
+ auto request = std::make_unique<TEvKeyValue::TEvRequest>();
+ auto& record = request->Record;
+ record.SetTabletId(TabletId);
+ record.SetCookie(0);
+ auto *read = record.AddCmdReadRange();
+ auto *r = read->MutableRange();
+ if (LastKey) {
+ r->SetFrom(*LastKey);
+ r->SetIncludeFrom(false);
+ }
+ Send(TabletActorId, request.release());
+ }
+
void SendReadRangeViaEvReadRange() {
auto request = std::make_unique<TEvKeyValue::TEvReadRange>();
auto& record = request->Record;
@@ -120,66 +120,66 @@ namespace NKikimr::NTestShard {
return key;
}
- void Handle(TEvKeyValue::TEvResponse::TPtr ev) {
- auto& r = ev->Get()->Record;
- if (r.GetCookie()) {
+ void Handle(TEvKeyValue::TEvResponse::TPtr ev) {
+ auto& r = ev->Get()->Record;
+ if (r.GetCookie()) {
WaitedReadsViaEvResponse--;
TString key = PopQueryByCookie(r.GetCookie());
-
- if (r.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- STLOG(PRI_ERROR, TEST_SHARD, TS18, "CmdRead failed", (TabletId, TabletId), (Status, r.GetStatus()),
- (ErrorReason, r.GetErrorReason()));
- return IssueRead(key);
- }
-
- Y_VERIFY(r.ReadResultSize() == 1);
- const auto& res = r.GetReadResult(0);
- const auto status = static_cast<NKikimrProto::EReplyStatus>(res.GetStatus());
-
- if (status == NKikimrProto::ERROR && RetryCount < 10) {
- const bool inserted = KeyReadsWaitingForRetry.insert(key).second;
- Y_VERIFY(inserted);
- STLOG(PRI_ERROR, TEST_SHARD, TS22, "read key failed -- going to retry", (TabletId, TabletId), (Key, key));
- return;
- }
-
- Y_VERIFY_S(status == NKikimrProto::OK, "Status# " << NKikimrProto::EReplyStatus_Name(status) << " Message# "
- << res.GetMessage());
-
- const TString& value = res.GetValue();
- const bool inserted = Keys.try_emplace(key, value.size()).second;
- Y_VERIFY(inserted);
- Y_VERIFY_S(MD5::Calc(value) == key, "TabletId# " << TabletId << " Key# " << key << " digest mismatch"
- " actual# " << MD5::Calc(value) << " len# " << value.size());
- STLOG(PRI_DEBUG, TEST_SHARD, TS16, "read key", (TabletId, TabletId), (Key, key));
- } else {
+
+ if (r.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ STLOG(PRI_ERROR, TEST_SHARD, TS18, "CmdRead failed", (TabletId, TabletId), (Status, r.GetStatus()),
+ (ErrorReason, r.GetErrorReason()));
+ return IssueRead(key);
+ }
+
+ Y_VERIFY(r.ReadResultSize() == 1);
+ const auto& res = r.GetReadResult(0);
+ const auto status = static_cast<NKikimrProto::EReplyStatus>(res.GetStatus());
+
+ if (status == NKikimrProto::ERROR && RetryCount < 10) {
+ const bool inserted = KeyReadsWaitingForRetry.insert(key).second;
+ Y_VERIFY(inserted);
+ STLOG(PRI_ERROR, TEST_SHARD, TS22, "read key failed -- going to retry", (TabletId, TabletId), (Key, key));
+ return;
+ }
+
+ Y_VERIFY_S(status == NKikimrProto::OK, "Status# " << NKikimrProto::EReplyStatus_Name(status) << " Message# "
+ << res.GetMessage());
+
+ const TString& value = res.GetValue();
+ const bool inserted = Keys.try_emplace(key, value.size()).second;
+ Y_VERIFY(inserted);
+ Y_VERIFY_S(MD5::Calc(value) == key, "TabletId# " << TabletId << " Key# " << key << " digest mismatch"
+ " actual# " << MD5::Calc(value) << " len# " << value.size());
+ STLOG(PRI_DEBUG, TEST_SHARD, TS16, "read key", (TabletId, TabletId), (Key, key));
+ } else {
WaitedReadRangesViaEvResponse--;
- if (r.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
- STLOG(PRI_ERROR, TEST_SHARD, TS17, "CmdRangeRead failed", (TabletId, TabletId), (Status, r.GetStatus()),
- (ErrorReason, r.GetErrorReason()));
- return IssueNextReadRangeQuery();
- }
- Y_VERIFY(r.ReadRangeResultSize() == 1);
- const auto& res = r.GetReadRangeResult(0);
- const auto status = static_cast<NKikimrProto::EReplyStatus>(res.GetStatus());
- Y_VERIFY_S(status == NKikimrProto::OK || status == NKikimrProto::NODATA || status == NKikimrProto::OVERRUN,
- "TabletId# " << TabletId << " CmdReadRange failed Status# " << NKikimrProto::EReplyStatus_Name(status));
-
- for (const auto& pair : res.GetPair()) {
- const TString& key = pair.GetKey();
- LastKey = key;
- IssueRead(key);
- }
- if (res.GetPair().empty()) {
- STLOG(PRI_INFO, TEST_SHARD, TS11, "finished reading from KeyValue tablet", (TabletId, TabletId));
- KeyValueReadComplete = true;
- } else {
- IssueNextReadRangeQuery();
- }
- }
- FinishIfPossible();
- }
-
+ if (r.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
+ STLOG(PRI_ERROR, TEST_SHARD, TS17, "CmdRangeRead failed", (TabletId, TabletId), (Status, r.GetStatus()),
+ (ErrorReason, r.GetErrorReason()));
+ return IssueNextReadRangeQuery();
+ }
+ Y_VERIFY(r.ReadRangeResultSize() == 1);
+ const auto& res = r.GetReadRangeResult(0);
+ const auto status = static_cast<NKikimrProto::EReplyStatus>(res.GetStatus());
+ Y_VERIFY_S(status == NKikimrProto::OK || status == NKikimrProto::NODATA || status == NKikimrProto::OVERRUN,
+ "TabletId# " << TabletId << " CmdReadRange failed Status# " << NKikimrProto::EReplyStatus_Name(status));
+
+ for (const auto& pair : res.GetPair()) {
+ const TString& key = pair.GetKey();
+ LastKey = key;
+ IssueRead(key);
+ }
+ if (res.GetPair().empty()) {
+ STLOG(PRI_INFO, TEST_SHARD, TS11, "finished reading from KeyValue tablet", (TabletId, TabletId));
+ KeyValueReadComplete = true;
+ } else {
+ IssueNextReadRangeQuery();
+ }
+ }
+ FinishIfPossible();
+ }
+
void Handle(TEvKeyValue::TEvReadResponse::TPtr ev) {
auto& record = ev->Get()->Record;
WaitedReadsViaEvReadResponse--;
@@ -247,14 +247,14 @@ namespace NKikimr::NTestShard {
}
ui64 SendReadViaEvRequest(const TString& key) {
- auto request = std::make_unique<TEvKeyValue::TEvRequest>();
- auto& record = request->Record;
- record.SetTabletId(TabletId);
- const ui64 cookie = ++LastCookie;
- record.SetCookie(cookie);
- auto *read = record.AddCmdRead();
- read->SetKey(key);
- Send(TabletActorId, request.release());
+ auto request = std::make_unique<TEvKeyValue::TEvRequest>();
+ auto& record = request->Record;
+ record.SetTabletId(TabletId);
+ const ui64 cookie = ++LastCookie;
+ record.SetCookie(cookie);
+ auto *read = record.AddCmdRead();
+ read->SetKey(key);
+ Send(TabletActorId, request.release());
return cookie;
}
@@ -282,254 +282,254 @@ namespace NKikimr::NTestShard {
void IssueRead(const TString& key) {
const ui64 cookie = SendRead(key);
- const bool inserted = QueriesInFlight.emplace(cookie, key).second;
- Y_VERIFY(inserted);
- }
-
- void IssueNextStateServerQuery() {
- auto request = std::make_unique<TEvStateServerRequest>();
- auto& r = request->Record;
- auto *read = r.MutableRead();
- read->SetTabletId(TabletId);
- read->SetGeneration(Generation);
- read->SetCookie(ReadStateCookie);
- Send(MakeStateServerInterfaceActorId(), request.release());
- }
-
- void Handle(TEvStateServerReadResult::TPtr ev) {
- STLOG(PRI_INFO, TEST_SHARD, TS13, "received TEvStateServerReadResult", (TabletId, TabletId));
- auto& r = ev->Get()->Record;
- switch (r.GetStatus()) {
- case ::NTestShard::TStateServer::OK:
- break;
-
- case ::NTestShard::TStateServer::ERROR:
- Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
-
- case ::NTestShard::TStateServer::RACE:
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
- PassAway();
- return;
-
- default:
- Y_FAIL();
- }
-
- if (!r.ItemsSize()) {
- STLOG(PRI_INFO, TEST_SHARD, TS10, "finished reading from state server", (TabletId, TabletId));
- StateReadComplete = true;
- FinishIfPossible();
- } else {
- for (const auto& item : r.GetItems()) {
- STLOG(PRI_DEBUG, TEST_SHARD, TS21, "read state", (TabletId, TabletId), (Key, item.GetKey()),
- (State, item.GetState()));
- const auto& [it, inserted] = State.try_emplace(item.GetKey(), item.GetState());
- Y_VERIFY(inserted);
- }
- ReadStateCookie = r.GetCookie();
- IssueNextStateServerQuery();
- }
- }
-
- void FinishIfPossible() {
- if (StateReadComplete && KeyValueReadComplete && QueriesInFlight.empty() && !SendRetriesPending) {
- if (!KeyReadsWaitingForRetry.empty()) {
- SendRetriesPending = true;
- TActivationContext::Schedule(TDuration::Seconds(10), new IEventHandle(EvRetryKeyReads, 0, SelfId(), {}, nullptr, 0));
- return;
- }
- if (!StateValidated) {
- ValidateState();
- StateValidated = true;
- }
- if (TransitionInFlight.empty()) {
- STLOG(PRI_INFO, TEST_SHARD, TS08, "finished read&validate", (TabletId, TabletId));
- for (auto& [key, info] : Keys) {
- Y_VERIFY(info.ConfirmedState == info.PendingState);
- Y_VERIFY(info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED);
- }
- Send(ParentId, new TEvValidationFinished(std::move(Keys)));
- PassAway();
- }
- }
- }
-
- void SendRetries() {
- Y_VERIFY(SendRetriesPending);
- SendRetriesPending = false;
- ++RetryCount;
- for (TString key : std::exchange(KeyReadsWaitingForRetry, {})) {
- IssueRead(key);
- }
- }
-
- void ValidateState() {
- const bool emptyState = State.empty();
-
- // the main idea is to iterate over Keys found in the KV tablet and compare them to KeysBefore unless this is
- // initial check, and State; if the State is empty, then we have to populate the state (state server has its
- // data lost)
- for (auto& [key, info] : Keys) {
- if (emptyState) {
- // key's state will switch to CONFIRMED eventually and this will happen before this actor terminates
- RegisterTransition(key, ::NTestShard::TStateServer::ABSENT, ::NTestShard::TStateServer::CONFIRMED);
- } else if (const auto it = State.find(key); it != State.end()) {
- info.ConfirmedState = info.PendingState = it->second;
- switch (it->second) {
- case ::NTestShard::TStateServer::WRITE_PENDING: // confirm written key
- case ::NTestShard::TStateServer::DELETE_PENDING: // reinstate key previously scheduled for deletion
- RegisterTransition(key, it->second, ::NTestShard::TStateServer::CONFIRMED);
- break;
-
- case ::NTestShard::TStateServer::CONFIRMED: // do nothing -- key is in exact state
- break;
-
- default:
- Y_FAIL("unexpected key state in State dict");
- }
- State.erase(it);
- } else {
- Y_FAIL_S("extra Key# " << key << " not in State dict TabletId# " << TabletId);
- }
-
- // if this is not initial check, then validate state against last known state
- if (const auto it = KeysBefore.find(key); it != KeysBefore.end()) {
- KeysBefore.erase(it);
- } else if (!InitialCheck) {
- Y_FAIL_S("excessive Key# " << key << " emerged on validation process TabletId# " << TabletId);
- }
- }
-
- // traverse State to find keys not enlisted in Keys set
- for (const auto& [key, state] : State) {
- if (state == ::NTestShard::TStateServer::CONFIRMED) {
- Y_FAIL_S("Key# " << key << " is listed in State, but not found in KV tablet -- key is lost TabletId# "
- << TabletId);
- }
- }
-
- // scan KeysBefore to find missing keys
- for (const auto& [key, info] : KeysBefore) {
- if (info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED) {
- Y_FAIL_S("Key# " << key << " is listed in KeysBefore, but not found in KV tablet -- key is lost"
- " TabletId# " << TabletId);
- } else { // there should be no in flight requests while doing validation
- Y_FAIL_S("Key# " << key << " is in incorrect ConfirmedState# "
- << ::NTestShard::TStateServer::EEntityState_Name(info.ConfirmedState) << " in KeysBefore"
- " TabletId# " << TabletId);
- }
- }
- }
-
- void RegisterTransition(TString key, ::NTestShard::TStateServer::EEntityState from, ::NTestShard::TStateServer::EEntityState to) {
- auto request = std::make_unique<TEvStateServerRequest>();
- auto& r = request->Record;
- auto *write = r.MutableWrite();
- write->SetTabletId(TabletId);
- write->SetGeneration(Generation);
- write->SetKey(key);
- write->SetOriginState(from);
- write->SetTargetState(to);
- Send(MakeStateServerInterfaceActorId(), request.release());
-
- const auto it = Keys.find(key);
- Y_VERIFY(it != Keys.end());
- it->second.PendingState = to;
- TransitionInFlight.push_back(&*it);
- }
-
- void Handle(TEvStateServerWriteResult::TPtr ev) {
- // check response
- auto& r = ev->Get()->Record;
- switch (r.GetStatus()) {
- case ::NTestShard::TStateServer::OK:
- break;
-
- case ::NTestShard::TStateServer::ERROR:
- Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
-
- case ::NTestShard::TStateServer::RACE:
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
- PassAway();
- return;
-
- default:
- Y_FAIL();
- }
-
- Y_VERIFY(!TransitionInFlight.empty());
- auto& key = *TransitionInFlight.front();
- TransitionInFlight.pop_front();
- key.second.ConfirmedState = key.second.PendingState;
-
- if (TransitionInFlight.empty()) {
- FinishIfPossible();
- }
- }
-
- TString RenderHtml() {
- TStringStream str;
- HTML(str) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Validation Actor";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() { str << "Parameter"; }
- TABLEH() { str << "Value"; }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "StateReadComplete"; }
- TABLED() { str << (StateReadComplete ? "true" : "false"); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "KeyValueReadComplete"; }
- TABLED() { str << (KeyValueReadComplete ? "true" : "false"); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "StateValidated"; }
- TABLED() { str << (StateValidated ? "true" : "false"); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "Keys.size"; }
- TABLED() { str << Keys.size(); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "KeysBefore.size"; }
- TABLED() { str << KeysBefore.size(); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "State.size"; }
- TABLED() { str << State.size(); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "TransitionInFlight.size"; }
- TABLED() { str << TransitionInFlight.size(); }
- }
- }
- TABLEBODY() {
- TABLER() {
- TABLED() { str << "QueriesInFlight.size"; }
- TABLED() { str << QueriesInFlight.size(); }
- }
- }
+ const bool inserted = QueriesInFlight.emplace(cookie, key).second;
+ Y_VERIFY(inserted);
+ }
+
+ void IssueNextStateServerQuery() {
+ auto request = std::make_unique<TEvStateServerRequest>();
+ auto& r = request->Record;
+ auto *read = r.MutableRead();
+ read->SetTabletId(TabletId);
+ read->SetGeneration(Generation);
+ read->SetCookie(ReadStateCookie);
+ Send(MakeStateServerInterfaceActorId(), request.release());
+ }
+
+ void Handle(TEvStateServerReadResult::TPtr ev) {
+ STLOG(PRI_INFO, TEST_SHARD, TS13, "received TEvStateServerReadResult", (TabletId, TabletId));
+ auto& r = ev->Get()->Record;
+ switch (r.GetStatus()) {
+ case ::NTestShard::TStateServer::OK:
+ break;
+
+ case ::NTestShard::TStateServer::ERROR:
+ Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
+
+ case ::NTestShard::TStateServer::RACE:
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
+ PassAway();
+ return;
+
+ default:
+ Y_FAIL();
+ }
+
+ if (!r.ItemsSize()) {
+ STLOG(PRI_INFO, TEST_SHARD, TS10, "finished reading from state server", (TabletId, TabletId));
+ StateReadComplete = true;
+ FinishIfPossible();
+ } else {
+ for (const auto& item : r.GetItems()) {
+ STLOG(PRI_DEBUG, TEST_SHARD, TS21, "read state", (TabletId, TabletId), (Key, item.GetKey()),
+ (State, item.GetState()));
+ const auto& [it, inserted] = State.try_emplace(item.GetKey(), item.GetState());
+ Y_VERIFY(inserted);
+ }
+ ReadStateCookie = r.GetCookie();
+ IssueNextStateServerQuery();
+ }
+ }
+
+ void FinishIfPossible() {
+ if (StateReadComplete && KeyValueReadComplete && QueriesInFlight.empty() && !SendRetriesPending) {
+ if (!KeyReadsWaitingForRetry.empty()) {
+ SendRetriesPending = true;
+ TActivationContext::Schedule(TDuration::Seconds(10), new IEventHandle(EvRetryKeyReads, 0, SelfId(), {}, nullptr, 0));
+ return;
+ }
+ if (!StateValidated) {
+ ValidateState();
+ StateValidated = true;
+ }
+ if (TransitionInFlight.empty()) {
+ STLOG(PRI_INFO, TEST_SHARD, TS08, "finished read&validate", (TabletId, TabletId));
+ for (auto& [key, info] : Keys) {
+ Y_VERIFY(info.ConfirmedState == info.PendingState);
+ Y_VERIFY(info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED);
+ }
+ Send(ParentId, new TEvValidationFinished(std::move(Keys)));
+ PassAway();
+ }
+ }
+ }
+
+ void SendRetries() {
+ Y_VERIFY(SendRetriesPending);
+ SendRetriesPending = false;
+ ++RetryCount;
+ for (TString key : std::exchange(KeyReadsWaitingForRetry, {})) {
+ IssueRead(key);
+ }
+ }
+
+ void ValidateState() {
+ const bool emptyState = State.empty();
+
+ // the main idea is to iterate over Keys found in the KV tablet and compare them to KeysBefore unless this is
+ // initial check, and State; if the State is empty, then we have to populate the state (state server has its
+ // data lost)
+ for (auto& [key, info] : Keys) {
+ if (emptyState) {
+ // key's state will switch to CONFIRMED eventually and this will happen before this actor terminates
+ RegisterTransition(key, ::NTestShard::TStateServer::ABSENT, ::NTestShard::TStateServer::CONFIRMED);
+ } else if (const auto it = State.find(key); it != State.end()) {
+ info.ConfirmedState = info.PendingState = it->second;
+ switch (it->second) {
+ case ::NTestShard::TStateServer::WRITE_PENDING: // confirm written key
+ case ::NTestShard::TStateServer::DELETE_PENDING: // reinstate key previously scheduled for deletion
+ RegisterTransition(key, it->second, ::NTestShard::TStateServer::CONFIRMED);
+ break;
+
+ case ::NTestShard::TStateServer::CONFIRMED: // do nothing -- key is in exact state
+ break;
+
+ default:
+ Y_FAIL("unexpected key state in State dict");
+ }
+ State.erase(it);
+ } else {
+ Y_FAIL_S("extra Key# " << key << " not in State dict TabletId# " << TabletId);
+ }
+
+ // if this is not initial check, then validate state against last known state
+ if (const auto it = KeysBefore.find(key); it != KeysBefore.end()) {
+ KeysBefore.erase(it);
+ } else if (!InitialCheck) {
+ Y_FAIL_S("excessive Key# " << key << " emerged on validation process TabletId# " << TabletId);
+ }
+ }
+
+ // traverse State to find keys not enlisted in Keys set
+ for (const auto& [key, state] : State) {
+ if (state == ::NTestShard::TStateServer::CONFIRMED) {
+ Y_FAIL_S("Key# " << key << " is listed in State, but not found in KV tablet -- key is lost TabletId# "
+ << TabletId);
+ }
+ }
+
+ // scan KeysBefore to find missing keys
+ for (const auto& [key, info] : KeysBefore) {
+ if (info.ConfirmedState == ::NTestShard::TStateServer::CONFIRMED) {
+ Y_FAIL_S("Key# " << key << " is listed in KeysBefore, but not found in KV tablet -- key is lost"
+ " TabletId# " << TabletId);
+ } else { // there should be no in flight requests while doing validation
+ Y_FAIL_S("Key# " << key << " is in incorrect ConfirmedState# "
+ << ::NTestShard::TStateServer::EEntityState_Name(info.ConfirmedState) << " in KeysBefore"
+ " TabletId# " << TabletId);
+ }
+ }
+ }
+
+ void RegisterTransition(TString key, ::NTestShard::TStateServer::EEntityState from, ::NTestShard::TStateServer::EEntityState to) {
+ auto request = std::make_unique<TEvStateServerRequest>();
+ auto& r = request->Record;
+ auto *write = r.MutableWrite();
+ write->SetTabletId(TabletId);
+ write->SetGeneration(Generation);
+ write->SetKey(key);
+ write->SetOriginState(from);
+ write->SetTargetState(to);
+ Send(MakeStateServerInterfaceActorId(), request.release());
+
+ const auto it = Keys.find(key);
+ Y_VERIFY(it != Keys.end());
+ it->second.PendingState = to;
+ TransitionInFlight.push_back(&*it);
+ }
+
+ void Handle(TEvStateServerWriteResult::TPtr ev) {
+ // check response
+ auto& r = ev->Get()->Record;
+ switch (r.GetStatus()) {
+ case ::NTestShard::TStateServer::OK:
+ break;
+
+ case ::NTestShard::TStateServer::ERROR:
+ Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
+
+ case ::NTestShard::TStateServer::RACE:
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
+ PassAway();
+ return;
+
+ default:
+ Y_FAIL();
+ }
+
+ Y_VERIFY(!TransitionInFlight.empty());
+ auto& key = *TransitionInFlight.front();
+ TransitionInFlight.pop_front();
+ key.second.ConfirmedState = key.second.PendingState;
+
+ if (TransitionInFlight.empty()) {
+ FinishIfPossible();
+ }
+ }
+
+ TString RenderHtml() {
+ TStringStream str;
+ HTML(str) {
+ DIV_CLASS("panel panel-info") {
+ DIV_CLASS("panel-heading") {
+ str << "Validation Actor";
+ }
+ DIV_CLASS("panel-body") {
+ TABLE_CLASS("table table-condensed") {
+ TABLEHEAD() {
+ TABLER() {
+ TABLEH() { str << "Parameter"; }
+ TABLEH() { str << "Value"; }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "StateReadComplete"; }
+ TABLED() { str << (StateReadComplete ? "true" : "false"); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "KeyValueReadComplete"; }
+ TABLED() { str << (KeyValueReadComplete ? "true" : "false"); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "StateValidated"; }
+ TABLED() { str << (StateValidated ? "true" : "false"); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "Keys.size"; }
+ TABLED() { str << Keys.size(); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "KeysBefore.size"; }
+ TABLED() { str << KeysBefore.size(); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "State.size"; }
+ TABLED() { str << State.size(); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "TransitionInFlight.size"; }
+ TABLED() { str << TransitionInFlight.size(); }
+ }
+ }
+ TABLEBODY() {
+ TABLER() {
+ TABLED() { str << "QueriesInFlight.size"; }
+ TABLED() { str << QueriesInFlight.size(); }
+ }
+ }
TABLEBODY() {
TABLER() {
TABLED() { str << "WaitedReadsViaEvResponse"; }
@@ -554,47 +554,47 @@ namespace NKikimr::NTestShard {
TABLED() { str << WaitedReadRangesViaEvReadRangeResponse; }
}
}
- }
- }
- }
- }
- return str.Str();
- }
-
- void Handle(NMon::TEvRemoteHttpInfo::TPtr ev) {
- Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(RenderHtml()), 0, ev->Cookie);
- }
-
- STRICT_STFUNC(StateFunc,
+ }
+ }
+ }
+ }
+ return str.Str();
+ }
+
+ void Handle(NMon::TEvRemoteHttpInfo::TPtr ev) {
+ Send(ev->Sender, new NMon::TEvRemoteHttpInfoRes(RenderHtml()), 0, ev->Cookie);
+ }
+
+ STRICT_STFUNC(StateFunc,
hFunc(TEvKeyValue::TEvReadResponse, Handle);
hFunc(TEvKeyValue::TEvReadRangeResponse, Handle);
- hFunc(TEvKeyValue::TEvResponse, Handle);
- hFunc(TEvStateServerStatus, Handle);
- hFunc(TEvStateServerReadResult, Handle);
- hFunc(TEvStateServerWriteResult, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- hFunc(NMon::TEvRemoteHttpInfo, Handle);
- cFunc(EvRetryKeyReads, SendRetries);
- )
- };
-
- void TLoadActor::RunValidation(bool initialCheck) {
- Send(TabletActorId, new TTestShard::TEvSwitchMode(TTestShard::EMode::READ_VALIDATE));
- Y_VERIFY(!ValidationActorId);
- ValidationActorId = RegisterWithSameMailbox(new TValidationActor(*this, initialCheck));
+ hFunc(TEvKeyValue::TEvResponse, Handle);
+ hFunc(TEvStateServerStatus, Handle);
+ hFunc(TEvStateServerReadResult, Handle);
+ hFunc(TEvStateServerWriteResult, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ hFunc(NMon::TEvRemoteHttpInfo, Handle);
+ cFunc(EvRetryKeyReads, SendRetries);
+ )
+ };
+
+ void TLoadActor::RunValidation(bool initialCheck) {
+ Send(TabletActorId, new TTestShard::TEvSwitchMode(TTestShard::EMode::READ_VALIDATE));
+ Y_VERIFY(!ValidationActorId);
+ ValidationActorId = RegisterWithSameMailbox(new TValidationActor(*this, initialCheck));
ValidationRunningCount++;
- }
-
- void TLoadActor::Handle(TEvValidationFinished::TPtr ev) {
- Send(TabletActorId, new TTestShard::TEvSwitchMode(TTestShard::EMode::WRITE));
- ValidationActorId = {};
- BytesProcessed = 0;
- Keys = std::move(ev->Get()->Keys);
- BytesOfData = 0;
- for (const auto& [key, info] : Keys) {
- BytesOfData += info.Len;
- }
- Action();
- }
-
-} // NKikimr::NTestShard
+ }
+
+ void TLoadActor::Handle(TEvValidationFinished::TPtr ev) {
+ Send(TabletActorId, new TTestShard::TEvSwitchMode(TTestShard::EMode::WRITE));
+ ValidationActorId = {};
+ BytesProcessed = 0;
+ Keys = std::move(ev->Get()->Keys);
+ BytesOfData = 0;
+ for (const auto& [key, info] : Keys) {
+ BytesOfData += info.Len;
+ }
+ Action();
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_state.cpp b/ydb/core/test_tablet/load_actor_state.cpp
index adbd31cf53e..bf9dd45e5a3 100644
--- a/ydb/core/test_tablet/load_actor_state.cpp
+++ b/ydb/core/test_tablet/load_actor_state.cpp
@@ -1,84 +1,84 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- void TLoadActor::RegisterTransition(TKey& key, ::NTestShard::TStateServer::EEntityState from,
- ::NTestShard::TStateServer::EEntityState to, std::unique_ptr<TEvKeyValue::TEvRequest> ev) {
- STLOG(PRI_DEBUG, TEST_SHARD, TS14, "RegisterTransition", (TabletId, TabletId), (Key, key.first), (From, from),
- (To, to));
-
- // some sanity checks
- Y_VERIFY(key.second.ConfirmedState == key.second.PendingState);
- Y_VERIFY(key.second.ConfirmedState == from);
- Y_VERIFY(!key.second.Request);
- Y_VERIFY(from != to);
- Y_VERIFY(from != ::NTestShard::TStateServer::DELETED);
- Y_VERIFY(to != ::NTestShard::TStateServer::ABSENT);
-
- // generate transition command and send it to state server
- auto request = std::make_unique<TEvStateServerRequest>();
- auto& r = request->Record;
- auto *write = r.MutableWrite();
- write->SetTabletId(TabletId);
- write->SetGeneration(Generation);
- write->SetKey(key.first);
- write->SetOriginState(from);
- write->SetTargetState(to);
- Send(MakeStateServerInterfaceActorId(), request.release());
-
- // update local state
- key.second.PendingState = to;
- key.second.Request = std::move(ev);
- TransitionInFlight.push_back(&key);
- }
-
- void TLoadActor::Handle(TEvStateServerWriteResult::TPtr ev) {
- STLOG(PRI_DEBUG, TEST_SHARD, TS15, "received TEvStateServerWriteResult", (TabletId, TabletId));
-
- // check response
- auto& r = ev->Get()->Record;
- switch (r.GetStatus()) {
- case ::NTestShard::TStateServer::OK:
- break;
-
- case ::NTestShard::TStateServer::ERROR:
- Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
-
- case ::NTestShard::TStateServer::RACE:
- TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
- PassAway();
- return;
-
- default:
- Y_FAIL();
- }
-
- // obtain current key
- Y_VERIFY(!TransitionInFlight.empty());
- auto& key = *TransitionInFlight.front();
- TransitionInFlight.pop_front();
-
- // account data bytes if confirming written key
- Y_VERIFY(key.second.ConfirmedState != key.second.PendingState);
- if (key.second.ConfirmedState == ::NTestShard::TStateServer::WRITE_PENDING &&
- key.second.PendingState == ::NTestShard::TStateServer::CONFIRMED) {
- BytesOfData += key.second.Len;
- }
-
- // switch to correct state
- key.second.ConfirmedState = key.second.PendingState;
- if (auto& r = key.second.Request) {
- if (const auto it = WritesInFlight.find(r->Record.GetCookie()); it != WritesInFlight.end()) {
- StateServerWriteLatency.Add(TDuration::Seconds(it->second.Timer.PassedReset()));
- }
- Send(TabletActorId, r.release());
- }
- if (key.second.ConfirmedState == ::NTestShard::TStateServer::DELETED) {
- Keys.erase(key.first);
- }
-
- // perform some action if possible
- Action();
- }
-
-} // NKikimr::NTestShard
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ void TLoadActor::RegisterTransition(TKey& key, ::NTestShard::TStateServer::EEntityState from,
+ ::NTestShard::TStateServer::EEntityState to, std::unique_ptr<TEvKeyValue::TEvRequest> ev) {
+ STLOG(PRI_DEBUG, TEST_SHARD, TS14, "RegisterTransition", (TabletId, TabletId), (Key, key.first), (From, from),
+ (To, to));
+
+ // some sanity checks
+ Y_VERIFY(key.second.ConfirmedState == key.second.PendingState);
+ Y_VERIFY(key.second.ConfirmedState == from);
+ Y_VERIFY(!key.second.Request);
+ Y_VERIFY(from != to);
+ Y_VERIFY(from != ::NTestShard::TStateServer::DELETED);
+ Y_VERIFY(to != ::NTestShard::TStateServer::ABSENT);
+
+ // generate transition command and send it to state server
+ auto request = std::make_unique<TEvStateServerRequest>();
+ auto& r = request->Record;
+ auto *write = r.MutableWrite();
+ write->SetTabletId(TabletId);
+ write->SetGeneration(Generation);
+ write->SetKey(key.first);
+ write->SetOriginState(from);
+ write->SetTargetState(to);
+ Send(MakeStateServerInterfaceActorId(), request.release());
+
+ // update local state
+ key.second.PendingState = to;
+ key.second.Request = std::move(ev);
+ TransitionInFlight.push_back(&key);
+ }
+
+ void TLoadActor::Handle(TEvStateServerWriteResult::TPtr ev) {
+ STLOG(PRI_DEBUG, TEST_SHARD, TS15, "received TEvStateServerWriteResult", (TabletId, TabletId));
+
+ // check response
+ auto& r = ev->Get()->Record;
+ switch (r.GetStatus()) {
+ case ::NTestShard::TStateServer::OK:
+ break;
+
+ case ::NTestShard::TStateServer::ERROR:
+ Y_FAIL_S("ERROR from StateServer TabletId# " << TabletId);
+
+ case ::NTestShard::TStateServer::RACE:
+ TActivationContext::Send(new IEventHandle(TEvents::TSystem::Poison, 0, TabletActorId, SelfId(), nullptr, 0));
+ PassAway();
+ return;
+
+ default:
+ Y_FAIL();
+ }
+
+ // obtain current key
+ Y_VERIFY(!TransitionInFlight.empty());
+ auto& key = *TransitionInFlight.front();
+ TransitionInFlight.pop_front();
+
+ // account data bytes if confirming written key
+ Y_VERIFY(key.second.ConfirmedState != key.second.PendingState);
+ if (key.second.ConfirmedState == ::NTestShard::TStateServer::WRITE_PENDING &&
+ key.second.PendingState == ::NTestShard::TStateServer::CONFIRMED) {
+ BytesOfData += key.second.Len;
+ }
+
+ // switch to correct state
+ key.second.ConfirmedState = key.second.PendingState;
+ if (auto& r = key.second.Request) {
+ if (const auto it = WritesInFlight.find(r->Record.GetCookie()); it != WritesInFlight.end()) {
+ StateServerWriteLatency.Add(TDuration::Seconds(it->second.Timer.PassedReset()));
+ }
+ Send(TabletActorId, r.release());
+ }
+ if (key.second.ConfirmedState == ::NTestShard::TStateServer::DELETED) {
+ Keys.erase(key.first);
+ }
+
+ // perform some action if possible
+ Action();
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/load_actor_write.cpp b/ydb/core/test_tablet/load_actor_write.cpp
index 719a0a334cb..11ea02db9e5 100644
--- a/ydb/core/test_tablet/load_actor_write.cpp
+++ b/ydb/core/test_tablet/load_actor_write.cpp
@@ -1,71 +1,71 @@
-#include "load_actor_impl.h"
-
+#include "load_actor_impl.h"
+
#include <ydb/core/util/lz4_data_generator.h>
-namespace NKikimr::NTestShard {
-
- void TLoadActor::GenerateKeyValue(TString *key, TString *value, bool *isInline) {
+namespace NKikimr::NTestShard {
+
+ void TLoadActor::GenerateKeyValue(TString *key, TString *value, bool *isInline) {
const size_t len = GenerateRandomSize(Settings.GetSizes(), isInline) + sizeof(ui64);
ui64 seed = TAppData::RandomProvider->GenRand64();
- TString data = FastGenDataForLZ4(len, seed);
+ TString data = FastGenDataForLZ4(len, seed);
char *charData = data.Detach();
for (size_t i = 0; i < Min<size_t>(sizeof(seed), data.size()); ++i) {
charData[i] = *(reinterpret_cast<char*>(&seed) + i);
- }
- *key = MD5::Calc(data);
- *value = std::move(data);
- }
-
- void TLoadActor::IssueWrite() {
- TString key, value;
- bool isInline;
- do {
- GenerateKeyValue(&key, &value, &isInline);
- } while (Keys.count(key));
-
- auto ev = CreateRequest();
- auto& r = ev->Record;
- auto *write = r.AddCmdWrite();
- write->SetKey(key);
- write->SetValue(value);
- if (isInline) {
- write->SetStorageChannel(NKikimrClient::TKeyValueRequest::INLINE);
- }
-
- STLOG(PRI_INFO, TEST_SHARD, TS12, "writing data", (TabletId, TabletId), (Key, key), (Size, value.size()));
-
- auto [wifIt, wifInserted] = WritesInFlight.try_emplace(r.GetCookie(), key);
- Y_VERIFY(wifInserted);
- Y_VERIFY(wifIt->second.KeysInQuery.size() == 1);
-
- auto [it, inserted] = Keys.try_emplace(key, value.size());
- Y_VERIFY(inserted);
- RegisterTransition(*it, ::NTestShard::TStateServer::ABSENT, ::NTestShard::TStateServer::WRITE_PENDING, std::move(ev));
-
- ++KeysWritten;
- BytesProcessed += value.size();
- }
-
- void TLoadActor::ProcessWriteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TWriteResult>& results) {
- if (const auto wifIt = WritesInFlight.find(cookie); wifIt != WritesInFlight.end()) {
- TWriteInfo& info = wifIt->second;
- const TDuration latency = TDuration::Seconds(info.Timer.Passed());
- WriteLatency.Add(latency);
- Y_VERIFY(info.KeysInQuery.size() == (size_t)results.size(), "%zu/%d", info.KeysInQuery.size(), results.size());
- for (size_t i = 0; i < info.KeysInQuery.size(); ++i) {
- const auto& res = results[i];
- Y_VERIFY_S(res.GetStatus() == NKikimrProto::OK, "TabletId# " << TabletId << " CmdWrite failed Status# "
- << NKikimrProto::EReplyStatus_Name(NKikimrProto::EReplyStatus(res.GetStatus())));
-
- const auto it = Keys.find(info.KeysInQuery[i]);
- Y_VERIFY_S(it != Keys.end(), "Key# " << info.KeysInQuery[i] << " not found in Keys dict");
- TKeyInfo& k = it->second;
- WriteSpeed.Add(TActivationContext::Now(), k.Len);
-
- RegisterTransition(*it, ::NTestShard::TStateServer::WRITE_PENDING, ::NTestShard::TStateServer::CONFIRMED);
- }
- WritesInFlight.erase(wifIt);
- }
- }
-
-} // NKikimr::NTestShard
+ }
+ *key = MD5::Calc(data);
+ *value = std::move(data);
+ }
+
+ void TLoadActor::IssueWrite() {
+ TString key, value;
+ bool isInline;
+ do {
+ GenerateKeyValue(&key, &value, &isInline);
+ } while (Keys.count(key));
+
+ auto ev = CreateRequest();
+ auto& r = ev->Record;
+ auto *write = r.AddCmdWrite();
+ write->SetKey(key);
+ write->SetValue(value);
+ if (isInline) {
+ write->SetStorageChannel(NKikimrClient::TKeyValueRequest::INLINE);
+ }
+
+ STLOG(PRI_INFO, TEST_SHARD, TS12, "writing data", (TabletId, TabletId), (Key, key), (Size, value.size()));
+
+ auto [wifIt, wifInserted] = WritesInFlight.try_emplace(r.GetCookie(), key);
+ Y_VERIFY(wifInserted);
+ Y_VERIFY(wifIt->second.KeysInQuery.size() == 1);
+
+ auto [it, inserted] = Keys.try_emplace(key, value.size());
+ Y_VERIFY(inserted);
+ RegisterTransition(*it, ::NTestShard::TStateServer::ABSENT, ::NTestShard::TStateServer::WRITE_PENDING, std::move(ev));
+
+ ++KeysWritten;
+ BytesProcessed += value.size();
+ }
+
+ void TLoadActor::ProcessWriteResult(ui64 cookie, const google::protobuf::RepeatedPtrField<NKikimrClient::TKeyValueResponse::TWriteResult>& results) {
+ if (const auto wifIt = WritesInFlight.find(cookie); wifIt != WritesInFlight.end()) {
+ TWriteInfo& info = wifIt->second;
+ const TDuration latency = TDuration::Seconds(info.Timer.Passed());
+ WriteLatency.Add(latency);
+ Y_VERIFY(info.KeysInQuery.size() == (size_t)results.size(), "%zu/%d", info.KeysInQuery.size(), results.size());
+ for (size_t i = 0; i < info.KeysInQuery.size(); ++i) {
+ const auto& res = results[i];
+ Y_VERIFY_S(res.GetStatus() == NKikimrProto::OK, "TabletId# " << TabletId << " CmdWrite failed Status# "
+ << NKikimrProto::EReplyStatus_Name(NKikimrProto::EReplyStatus(res.GetStatus())));
+
+ const auto it = Keys.find(info.KeysInQuery[i]);
+ Y_VERIFY_S(it != Keys.end(), "Key# " << info.KeysInQuery[i] << " not found in Keys dict");
+ TKeyInfo& k = it->second;
+ WriteSpeed.Add(TActivationContext::Now(), k.Len);
+
+ RegisterTransition(*it, ::NTestShard::TStateServer::WRITE_PENDING, ::NTestShard::TStateServer::CONFIRMED);
+ }
+ WritesInFlight.erase(wifIt);
+ }
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/scheme.h b/ydb/core/test_tablet/scheme.h
index 1c32514c1ff..956684ebf9e 100644
--- a/ydb/core/test_tablet/scheme.h
+++ b/ydb/core/test_tablet/scheme.h
@@ -1,20 +1,20 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NTestShard {
-
- struct Schema : NIceDb::Schema {
- struct State : Table<100> {
- struct Key : Column<1, NScheme::NTypeIds::Bool> { static constexpr Type Default = {}; };
- struct Settings : Column<2, NScheme::NTypeIds::String> {};
- struct Digest : Column<3, NScheme::NTypeIds::String> {};
-
- using TKey = TableKey<Key>;
- using TColumns = TableColumns<Key, Settings, Digest>;
- };
-
- using TTables = SchemaTables<State>;
- };
-
-} // NKikimr::NTestShard
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NTestShard {
+
+ struct Schema : NIceDb::Schema {
+ struct State : Table<100> {
+ struct Key : Column<1, NScheme::NTypeIds::Bool> { static constexpr Type Default = {}; };
+ struct Settings : Column<2, NScheme::NTypeIds::String> {};
+ struct Digest : Column<3, NScheme::NTypeIds::String> {};
+
+ using TKey = TableKey<Key>;
+ using TColumns = TableColumns<Key, Settings, Digest>;
+ };
+
+ using TTables = SchemaTables<State>;
+ };
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/state_server_interface.cpp b/ydb/core/test_tablet/state_server_interface.cpp
index 47f3d39363b..b1c72cb17bb 100644
--- a/ydb/core/test_tablet/state_server_interface.cpp
+++ b/ydb/core/test_tablet/state_server_interface.cpp
@@ -1,271 +1,271 @@
-#include "load_actor_impl.h"
-
-namespace NKikimr::NTestShard {
-
- class TStateServerInterfaceActor : public TActorBootstrapped<TStateServerInterfaceActor> {
- struct TServerContext : TThrRefBase {
- const TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- const TString Host;
- i32 Port;
- std::unordered_set<TActorId, THash<TActorId>> Subscribers;
-
- TServerContext(const TString& host, i32 port, const TActorIdentity& self)
- : Socket(NInterconnect::TStreamSocket::Make(AF_INET6))
- , Host(host)
- , Port(port)
- {
- Y_VERIFY(*Socket != INVALID_SOCKET);
- SetNonBlock(*Socket);
- SetNoDelay(*Socket, true);
- Socket->Connect(NInterconnect::TAddress(host, port));
- self.Send(MakePollerActorId(), new TEvPollerRegister(Socket, self, self));
- }
-
- bool IsConnected = false;
- TPollerToken::TPtr PollerToken;
- bool NeedRead = false, NeedWrite = false;
-
- bool Action(TStateServerInterfaceActor *self) {
- if (IsConnected ? Read(self) && Write() : CheckConnect(self)) {
- if (NeedRead || NeedWrite) {
- PollerToken->Request(NeedRead, NeedWrite);
- }
- return true;
- } else {
- return false;
- }
- }
-
- bool CheckConnect(TStateServerInterfaceActor *self) {
- NeedRead = NeedWrite = false;
- int err = Socket->GetConnectStatus();
- if (err == EAGAIN || err == EINPROGRESS) {
- NeedWrite = true;
- } else if (!err) {
- STLOG(PRI_INFO, TEST_SHARD, TS06, "successfully connected to state server");
- IsConnected = true;
- return Read(self) && Write();
- } else {
- STLOG(PRI_ERROR, TEST_SHARD, TS01, "failed to establish connection to state server",
- (Error, strerror(err)));
- return false;
- }
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // read queue
-
- enum class EReadState {
- INITIAL,
- LENGTH,
- DATA,
- } ReadState = EReadState::INITIAL;
- ui32 ReadLength;
- TString ReadBuffer;
- char *ReadBufferPtr = nullptr;
- char *ReadBufferEnd = nullptr;
-
- bool Read(TStateServerInterfaceActor *self) {
- NeedRead = false;
- for (;;) {
- if (size_t num = ReadBufferEnd - ReadBufferPtr) {
- ssize_t read = Socket->Recv(ReadBufferPtr, num);
- if (read > 0) {
- ReadBufferPtr += read;
- } else if (-read == EAGAIN || -read == EWOULDBLOCK) {
- NeedRead = true;
- break;
- } else if (-read == EINTR) {
- continue;
- } else {
- STLOG(PRI_ERROR, TEST_SHARD, TS02, "failed to receive data from state server",
- (Error, strerror(-read)));
- return false;
- }
- } else {
- switch (ReadState) {
- case EReadState::LENGTH:
- ReadState = EReadState::DATA;
- Y_VERIFY(ReadLength <= 64 * 1024 * 1024);
- ReadBuffer = TString::Uninitialized(ReadLength);
- ReadBufferPtr = ReadBuffer.Detach();
- ReadBufferEnd = ReadBufferPtr + ReadLength;
- break;
-
- case EReadState::DATA:
- ProcessPacket(self);
- [[fallthrough]];
- case EReadState::INITIAL:
- ReadState = EReadState::LENGTH;
- ReadBufferPtr = reinterpret_cast<char*>(&ReadLength);
- ReadBufferEnd = ReadBufferPtr + sizeof(ReadLength);
- break;
- }
- }
- }
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // write queue
-
- std::deque<TString> WriteQ;
- size_t WriteOffset = 0;
-
- bool Write() {
- NeedWrite = false;
- while (!WriteQ.empty()) {
- const TString& s = WriteQ.front();
- if (WriteOffset == s.size()) {
- WriteQ.pop_front();
- WriteOffset = 0;
- } else {
- ssize_t written = Socket->Send(s.data() + WriteOffset, s.size() - WriteOffset);
- if (written > 0) {
- WriteOffset += written;
- } else if (-written == EAGAIN || -written == EWOULDBLOCK) {
- NeedWrite = true;
- break;
- } else if (-written == EINTR) {
- continue;
- } else {
- STLOG(PRI_ERROR, TEST_SHARD, TS03, "failed to send data to state server",
- (Error, strerror(-written)));
- return false;
- }
- }
- }
- return true;
- }
-
- struct TResponseInfo {
- const TActorId Sender;
- const ui64 Cookie;
- const ui32 Type;
- };
- std::deque<TResponseInfo> ResponseQ;
-
- void Push(TEvStateServerRequest::TPtr ev) {
- auto& record = ev->Get()->Record;
- const ui32 type = record.HasWrite() ? TEvTestShard::EvStateServerWriteResult :
- record.HasRead() ? TEvTestShard::EvStateServerReadResult : 0;
- Y_VERIFY(type);
- ResponseQ.push_back(TResponseInfo{ev->Sender, ev->Cookie, type});
- auto buffers = ev->ReleaseChainBuffer();
- Y_VERIFY(!buffers->IsExtendedFormat());
- const ui32 len = buffers->GetSize();
- Y_VERIFY(len <= 64 * 1024 * 1024);
- TString w = TString::Uninitialized(sizeof(ui32) + len);
- char *p = w.Detach();
- auto append = [&](const void *buffer, size_t len) { memcpy(std::exchange(p, p + len), buffer, len); };
- append(&len, sizeof(len));
- for (auto iter = buffers->GetBeginIter(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
- append(iter.ContiguousData(), iter.ContiguousSize());
- }
- WriteQ.push_back(std::move(w));
- }
-
- void ProcessPacket(TStateServerInterfaceActor *self) {
- Y_VERIFY(!ResponseQ.empty());
- TResponseInfo& response = ResponseQ.front();
- TActivationContext::Send(new IEventHandle(response.Type, 0, response.Sender, self->SelfId(),
- MakeIntrusive<TEventSerializedData>(std::move(ReadBuffer), false), response.Cookie));
- ResponseQ.pop_front();
- }
-
- using TPtr = TIntrusivePtr<TServerContext>;
- };
-
- std::unordered_map<TActorId, TServerContext::TPtr, THash<TActorId>> Servers;
- std::unordered_map<std::pair<TString, i32>, TServerContext::TPtr> HostMap;
- std::unordered_map<int, TServerContext::TPtr> SocketMap;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::STATE_SERVER_INTERFACE_ACTOR;
- }
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvStateServerConnect, Handle);
- hFunc(TEvStateServerDisconnect, Handle);
- hFunc(TEvPollerRegisterResult, Handle);
- hFunc(TEvPollerReady, Handle);
- hFunc(TEvStateServerRequest, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-
- void Handle(TEvStateServerConnect::TPtr ev) {
- auto *msg = ev->Get();
- const auto& key = std::make_pair(msg->Host, msg->Port);
- auto& ctx = HostMap[key];
- if (!ctx) {
- ctx = MakeIntrusive<TServerContext>(msg->Host, msg->Port, SelfId());
- SocketMap.emplace(*ctx->Socket, ctx);
- }
- bool inserted = Servers.emplace(ev->Sender, ctx).second;
- Y_VERIFY(inserted);
- if (ctx->IsConnected) {
- Send(ev->Sender, new TEvStateServerStatus(true));
- }
- inserted = ctx->Subscribers.insert(ev->Sender).second;
- Y_VERIFY(inserted);
- }
-
- void Handle(TEvStateServerDisconnect::TPtr ev) {
- const auto it = Servers.find(ev->Sender);
- Y_VERIFY(it != Servers.end());
- const size_t num = it->second->Subscribers.erase(ev->Sender);
- Y_VERIFY(num);
- if (it->second->Subscribers.empty()) {
- HostMap.erase(std::make_pair(it->second->Host, it->second->Port));
- SocketMap.erase(*it->second->Socket);
- }
- Servers.erase(it);
- }
-
- void Handle(TEvPollerRegisterResult::TPtr ev) {
- if (const auto it = SocketMap.find(ev->Get()->Socket->GetDescriptor()); it != SocketMap.end()) {
- it->second->PollerToken = std::move(ev->Get()->PollerToken);
- Action(it->second);
- }
- }
-
- void Handle(TEvPollerReady::TPtr ev) {
- if (const auto it = SocketMap.find(ev->Get()->Socket->GetDescriptor()); it != SocketMap.end()) {
- Action(it->second);
- }
- }
-
- void Action(const TServerContext::TPtr& ctx) {
- std::optional<bool> notify;
- const bool wasConnected = ctx->IsConnected;
- if (!ctx->Action(this)) {
- notify = false;
- } else if (!wasConnected && ctx->IsConnected) {
- notify = true;
- }
- if (notify) {
- for (TActorId subscriberId : ctx->Subscribers) {
- Send(subscriberId, new TEvStateServerStatus(*notify));
- }
- }
- }
-
- void Handle(TEvStateServerRequest::TPtr ev) {
- const auto it = Servers.find(ev->Sender);
- Y_VERIFY(it != Servers.end());
- it->second->Push(ev);
- Action(it->second);
- }
- };
-
- IActor *CreateStateServerInterfaceActor() {
- return new TStateServerInterfaceActor();
- }
-
-} // NKikimr::NTestShard
+#include "load_actor_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ class TStateServerInterfaceActor : public TActorBootstrapped<TStateServerInterfaceActor> {
+ struct TServerContext : TThrRefBase {
+ const TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
+ const TString Host;
+ i32 Port;
+ std::unordered_set<TActorId, THash<TActorId>> Subscribers;
+
+ TServerContext(const TString& host, i32 port, const TActorIdentity& self)
+ : Socket(NInterconnect::TStreamSocket::Make(AF_INET6))
+ , Host(host)
+ , Port(port)
+ {
+ Y_VERIFY(*Socket != INVALID_SOCKET);
+ SetNonBlock(*Socket);
+ SetNoDelay(*Socket, true);
+ Socket->Connect(NInterconnect::TAddress(host, port));
+ self.Send(MakePollerActorId(), new TEvPollerRegister(Socket, self, self));
+ }
+
+ bool IsConnected = false;
+ TPollerToken::TPtr PollerToken;
+ bool NeedRead = false, NeedWrite = false;
+
+ bool Action(TStateServerInterfaceActor *self) {
+ if (IsConnected ? Read(self) && Write() : CheckConnect(self)) {
+ if (NeedRead || NeedWrite) {
+ PollerToken->Request(NeedRead, NeedWrite);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool CheckConnect(TStateServerInterfaceActor *self) {
+ NeedRead = NeedWrite = false;
+ int err = Socket->GetConnectStatus();
+ if (err == EAGAIN || err == EINPROGRESS) {
+ NeedWrite = true;
+ } else if (!err) {
+ STLOG(PRI_INFO, TEST_SHARD, TS06, "successfully connected to state server");
+ IsConnected = true;
+ return Read(self) && Write();
+ } else {
+ STLOG(PRI_ERROR, TEST_SHARD, TS01, "failed to establish connection to state server",
+ (Error, strerror(err)));
+ return false;
+ }
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // read queue
+
+ enum class EReadState {
+ INITIAL,
+ LENGTH,
+ DATA,
+ } ReadState = EReadState::INITIAL;
+ ui32 ReadLength;
+ TString ReadBuffer;
+ char *ReadBufferPtr = nullptr;
+ char *ReadBufferEnd = nullptr;
+
+ bool Read(TStateServerInterfaceActor *self) {
+ NeedRead = false;
+ for (;;) {
+ if (size_t num = ReadBufferEnd - ReadBufferPtr) {
+ ssize_t read = Socket->Recv(ReadBufferPtr, num);
+ if (read > 0) {
+ ReadBufferPtr += read;
+ } else if (-read == EAGAIN || -read == EWOULDBLOCK) {
+ NeedRead = true;
+ break;
+ } else if (-read == EINTR) {
+ continue;
+ } else {
+ STLOG(PRI_ERROR, TEST_SHARD, TS02, "failed to receive data from state server",
+ (Error, strerror(-read)));
+ return false;
+ }
+ } else {
+ switch (ReadState) {
+ case EReadState::LENGTH:
+ ReadState = EReadState::DATA;
+ Y_VERIFY(ReadLength <= 64 * 1024 * 1024);
+ ReadBuffer = TString::Uninitialized(ReadLength);
+ ReadBufferPtr = ReadBuffer.Detach();
+ ReadBufferEnd = ReadBufferPtr + ReadLength;
+ break;
+
+ case EReadState::DATA:
+ ProcessPacket(self);
+ [[fallthrough]];
+ case EReadState::INITIAL:
+ ReadState = EReadState::LENGTH;
+ ReadBufferPtr = reinterpret_cast<char*>(&ReadLength);
+ ReadBufferEnd = ReadBufferPtr + sizeof(ReadLength);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // write queue
+
+ std::deque<TString> WriteQ;
+ size_t WriteOffset = 0;
+
+ bool Write() {
+ NeedWrite = false;
+ while (!WriteQ.empty()) {
+ const TString& s = WriteQ.front();
+ if (WriteOffset == s.size()) {
+ WriteQ.pop_front();
+ WriteOffset = 0;
+ } else {
+ ssize_t written = Socket->Send(s.data() + WriteOffset, s.size() - WriteOffset);
+ if (written > 0) {
+ WriteOffset += written;
+ } else if (-written == EAGAIN || -written == EWOULDBLOCK) {
+ NeedWrite = true;
+ break;
+ } else if (-written == EINTR) {
+ continue;
+ } else {
+ STLOG(PRI_ERROR, TEST_SHARD, TS03, "failed to send data to state server",
+ (Error, strerror(-written)));
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ struct TResponseInfo {
+ const TActorId Sender;
+ const ui64 Cookie;
+ const ui32 Type;
+ };
+ std::deque<TResponseInfo> ResponseQ;
+
+ void Push(TEvStateServerRequest::TPtr ev) {
+ auto& record = ev->Get()->Record;
+ const ui32 type = record.HasWrite() ? TEvTestShard::EvStateServerWriteResult :
+ record.HasRead() ? TEvTestShard::EvStateServerReadResult : 0;
+ Y_VERIFY(type);
+ ResponseQ.push_back(TResponseInfo{ev->Sender, ev->Cookie, type});
+ auto buffers = ev->ReleaseChainBuffer();
+ Y_VERIFY(!buffers->IsExtendedFormat());
+ const ui32 len = buffers->GetSize();
+ Y_VERIFY(len <= 64 * 1024 * 1024);
+ TString w = TString::Uninitialized(sizeof(ui32) + len);
+ char *p = w.Detach();
+ auto append = [&](const void *buffer, size_t len) { memcpy(std::exchange(p, p + len), buffer, len); };
+ append(&len, sizeof(len));
+ for (auto iter = buffers->GetBeginIter(); iter.Valid(); iter.AdvanceToNextContiguousBlock()) {
+ append(iter.ContiguousData(), iter.ContiguousSize());
+ }
+ WriteQ.push_back(std::move(w));
+ }
+
+ void ProcessPacket(TStateServerInterfaceActor *self) {
+ Y_VERIFY(!ResponseQ.empty());
+ TResponseInfo& response = ResponseQ.front();
+ TActivationContext::Send(new IEventHandle(response.Type, 0, response.Sender, self->SelfId(),
+ MakeIntrusive<TEventSerializedData>(std::move(ReadBuffer), false), response.Cookie));
+ ResponseQ.pop_front();
+ }
+
+ using TPtr = TIntrusivePtr<TServerContext>;
+ };
+
+ std::unordered_map<TActorId, TServerContext::TPtr, THash<TActorId>> Servers;
+ std::unordered_map<std::pair<TString, i32>, TServerContext::TPtr> HostMap;
+ std::unordered_map<int, TServerContext::TPtr> SocketMap;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::STATE_SERVER_INTERFACE_ACTOR;
+ }
+
+ void Bootstrap() {
+ Become(&TThis::StateFunc);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(TEvStateServerConnect, Handle);
+ hFunc(TEvStateServerDisconnect, Handle);
+ hFunc(TEvPollerRegisterResult, Handle);
+ hFunc(TEvPollerReady, Handle);
+ hFunc(TEvStateServerRequest, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+
+ void Handle(TEvStateServerConnect::TPtr ev) {
+ auto *msg = ev->Get();
+ const auto& key = std::make_pair(msg->Host, msg->Port);
+ auto& ctx = HostMap[key];
+ if (!ctx) {
+ ctx = MakeIntrusive<TServerContext>(msg->Host, msg->Port, SelfId());
+ SocketMap.emplace(*ctx->Socket, ctx);
+ }
+ bool inserted = Servers.emplace(ev->Sender, ctx).second;
+ Y_VERIFY(inserted);
+ if (ctx->IsConnected) {
+ Send(ev->Sender, new TEvStateServerStatus(true));
+ }
+ inserted = ctx->Subscribers.insert(ev->Sender).second;
+ Y_VERIFY(inserted);
+ }
+
+ void Handle(TEvStateServerDisconnect::TPtr ev) {
+ const auto it = Servers.find(ev->Sender);
+ Y_VERIFY(it != Servers.end());
+ const size_t num = it->second->Subscribers.erase(ev->Sender);
+ Y_VERIFY(num);
+ if (it->second->Subscribers.empty()) {
+ HostMap.erase(std::make_pair(it->second->Host, it->second->Port));
+ SocketMap.erase(*it->second->Socket);
+ }
+ Servers.erase(it);
+ }
+
+ void Handle(TEvPollerRegisterResult::TPtr ev) {
+ if (const auto it = SocketMap.find(ev->Get()->Socket->GetDescriptor()); it != SocketMap.end()) {
+ it->second->PollerToken = std::move(ev->Get()->PollerToken);
+ Action(it->second);
+ }
+ }
+
+ void Handle(TEvPollerReady::TPtr ev) {
+ if (const auto it = SocketMap.find(ev->Get()->Socket->GetDescriptor()); it != SocketMap.end()) {
+ Action(it->second);
+ }
+ }
+
+ void Action(const TServerContext::TPtr& ctx) {
+ std::optional<bool> notify;
+ const bool wasConnected = ctx->IsConnected;
+ if (!ctx->Action(this)) {
+ notify = false;
+ } else if (!wasConnected && ctx->IsConnected) {
+ notify = true;
+ }
+ if (notify) {
+ for (TActorId subscriberId : ctx->Subscribers) {
+ Send(subscriberId, new TEvStateServerStatus(*notify));
+ }
+ }
+ }
+
+ void Handle(TEvStateServerRequest::TPtr ev) {
+ const auto it = Servers.find(ev->Sender);
+ Y_VERIFY(it != Servers.end());
+ it->second->Push(ev);
+ Action(it->second);
+ }
+ };
+
+ IActor *CreateStateServerInterfaceActor() {
+ return new TStateServerInterfaceActor();
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/state_server_interface.h b/ydb/core/test_tablet/state_server_interface.h
index 68046ab21f1..37bf2eaeb5b 100644
--- a/ydb/core/test_tablet/state_server_interface.h
+++ b/ydb/core/test_tablet/state_server_interface.h
@@ -1,41 +1,41 @@
-#pragma once
-
-#include "defs.h"
-#include "events.h"
-
-namespace NKikimr::NTestShard {
-
- inline TActorId MakeStateServerInterfaceActorId() {
- return TActorId(0, TStringBuf("StateServerI", 12));
- }
-
- IActor *CreateStateServerInterfaceActor();
-
- struct TEvStateServerConnect : TEventLocal<TEvStateServerConnect, TEvTestShard::EvStateServerConnect> {
- const TString Host;
- const i32 Port;
-
- TEvStateServerConnect(TString host, i32 port)
- : Host(std::move(host))
- , Port(port)
- {}
- };
-
- struct TEvStateServerDisconnect : TEventLocal<TEvStateServerDisconnect, TEvTestShard::EvStateServerDisconnect>
- {};
-
- struct TEvStateServerStatus : TEventLocal<TEvStateServerStatus, TEvTestShard::EvStateServerStatus> {
- const bool Connected; // true if successfully connected, false on error
- TEvStateServerStatus(bool connected) : Connected(connected) {}
- };
-
- struct TEvStateServerRequest : TEventPB<TEvStateServerRequest, ::NTestShard::TStateServer::TRequest, TEvTestShard::EvStateServerRequest>
- {};
-
- struct TEvStateServerWriteResult : TEventPB<TEvStateServerWriteResult, ::NTestShard::TStateServer::TWriteResult, TEvTestShard::EvStateServerWriteResult>
- {};
-
- struct TEvStateServerReadResult : TEventPB<TEvStateServerReadResult, ::NTestShard::TStateServer::TReadResult, TEvTestShard::EvStateServerReadResult>
- {};
-
-} // NKikimr::NTestShard
+#pragma once
+
+#include "defs.h"
+#include "events.h"
+
+namespace NKikimr::NTestShard {
+
+ inline TActorId MakeStateServerInterfaceActorId() {
+ return TActorId(0, TStringBuf("StateServerI", 12));
+ }
+
+ IActor *CreateStateServerInterfaceActor();
+
+ struct TEvStateServerConnect : TEventLocal<TEvStateServerConnect, TEvTestShard::EvStateServerConnect> {
+ const TString Host;
+ const i32 Port;
+
+ TEvStateServerConnect(TString host, i32 port)
+ : Host(std::move(host))
+ , Port(port)
+ {}
+ };
+
+ struct TEvStateServerDisconnect : TEventLocal<TEvStateServerDisconnect, TEvTestShard::EvStateServerDisconnect>
+ {};
+
+ struct TEvStateServerStatus : TEventLocal<TEvStateServerStatus, TEvTestShard::EvStateServerStatus> {
+ const bool Connected; // true if successfully connected, false on error
+ TEvStateServerStatus(bool connected) : Connected(connected) {}
+ };
+
+ struct TEvStateServerRequest : TEventPB<TEvStateServerRequest, ::NTestShard::TStateServer::TRequest, TEvTestShard::EvStateServerRequest>
+ {};
+
+ struct TEvStateServerWriteResult : TEventPB<TEvStateServerWriteResult, ::NTestShard::TStateServer::TWriteResult, TEvTestShard::EvStateServerWriteResult>
+ {};
+
+ struct TEvStateServerReadResult : TEventPB<TEvStateServerReadResult, ::NTestShard::TStateServer::TReadResult, TEvTestShard::EvStateServerReadResult>
+ {};
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/test_shard_impl.h b/ydb/core/test_tablet/test_shard_impl.h
index 78b8e77fd3c..3188d49bf56 100644
--- a/ydb/core/test_tablet/test_shard_impl.h
+++ b/ydb/core/test_tablet/test_shard_impl.h
@@ -1,132 +1,132 @@
-#pragma once
-
-#include "defs.h"
-#include "events.h"
-
-namespace NKikimr::NTestShard {
-
- struct TExDie : std::exception {};
-
- using NTabletFlatExecutor::ITransaction;
- using NTabletFlatExecutor::TTransactionBase;
-
- class TTestShard : public NKeyValue::TKeyValueFlat {
- std::optional<NKikimrClient::TTestShardControlRequest::TCmdInitialize> Settings;
- std::unique_ptr<TTabletCountersBase> Counters;
-
- public:
- enum class EMode {
- WRITE,
- READ_VALIDATE,
- STATE_SERVER_CONNECT,
- };
-
- enum {
- EvSwitchMode = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- struct TEvSwitchMode : TEventLocal<TEvSwitchMode, EvSwitchMode> {
- EMode Mode;
- TEvSwitchMode(EMode mode) : Mode(mode) {}
- };
-
- public:
- TTestShard(const TActorId& tablet, TTabletStorageInfo *info)
- : TKeyValueFlat(tablet, info)
- {
- using TKeyValueCounters = TProtobufTabletCounters<
- NKeyValue::ESimpleCounters_descriptor,
- NKeyValue::ECumulativeCounters_descriptor,
- NKeyValue::EPercentileCounters_descriptor,
- NKeyValue::ETxTypes_descriptor>;
-
- using TTestShardCounters = TAppProtobufTabletCounters<
- NTestShard::ESimpleCounters_descriptor,
- NTestShard::ECumulativeCounters_descriptor,
- NTestShard::EPercentileCounters_descriptor>;
-
- TProtobufTabletCountersPair<TKeyValueCounters, TTestShardCounters> pair;
- State.SetupTabletCounters(pair.GetFirstTabletCounters().Release());
- Counters.reset(pair.GetSecondTabletCounters().Release());
- }
-
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TEST_SHARD_ACTOR;
- }
-
- void CreatedHook(const TActorContext& ctx) override {
- Execute(CreateTxInitScheme(), ctx);
- }
-
- bool HandleHook(STFUNC_SIG) override {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvControlRequest, Handle);
- HFunc(TEvSwitchMode, Handle);
- default:
- return false;
- }
- return true;
- }
-
- void Handle(TEvControlRequest::TPtr ev, const TActorContext& ctx) {
- const auto& record = ev->Get()->Record;
- switch (record.GetCommandCase()) {
- case NKikimrClient::TTestShardControlRequest::kInitialize:
- Execute(CreateTxInitialize(record.GetInitialize(), ev->Sender, ev->Cookie), ctx);
- break;
-
- case NKikimrClient::TTestShardControlRequest::COMMAND_NOT_SET:
- break;
- }
- }
-
- void Handle(TEvSwitchMode::TPtr ev, const TActorContext& /*ctx*/) {
- const EMode mode = ev->Get()->Mode;
- auto& s = Counters->Simple();
- s[NTestShard::COUNTER_MODE_WRITE] = mode == EMode::WRITE;
- s[NTestShard::COUNTER_MODE_READ_VALIDATE] = mode == EMode::READ_VALIDATE;
- s[NTestShard::COUNTER_MODE_STATE_SERVER_CONNECT] = mode == EMode::STATE_SERVER_CONNECT;
- }
-
- void OnLoadComplete() {
- StartActivities();
- }
-
- bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) override {
- if (!ev) {
- return true;
- }
- const auto& cgi = ev->Get()->Cgi();
- if (cgi.Get("page") == "keyvalue") {
- return TKeyValueFlat::OnRenderAppHtmlPage(ev, ctx);
- } else {
- Register(CreateMonQueryActor(ev));
- return true;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TActorId ActivityActorId;
-
- void StartActivities();
- void PassAway() override;
-
- private:
- class TTxInitialize;
- friend class TTxInitialize;
- ITransaction *CreateTxInitialize(const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
- TActorId sender, ui64 cookie);
-
- class TTxInitScheme;
- friend class TTxInitScheme;
- ITransaction *CreateTxInitScheme();
-
- class TTxLoadEverything;
- friend class TTxLoadEverything;
- ITransaction *CreateTxLoadEverything();
-
- class TMonQueryActor;
- IActor *CreateMonQueryActor(NMon::TEvRemoteHttpInfo::TPtr ev);
- };
-
-} // NKikimr::NTestShard
+#pragma once
+
+#include "defs.h"
+#include "events.h"
+
+namespace NKikimr::NTestShard {
+
+ struct TExDie : std::exception {};
+
+ using NTabletFlatExecutor::ITransaction;
+ using NTabletFlatExecutor::TTransactionBase;
+
+ class TTestShard : public NKeyValue::TKeyValueFlat {
+ std::optional<NKikimrClient::TTestShardControlRequest::TCmdInitialize> Settings;
+ std::unique_ptr<TTabletCountersBase> Counters;
+
+ public:
+ enum class EMode {
+ WRITE,
+ READ_VALIDATE,
+ STATE_SERVER_CONNECT,
+ };
+
+ enum {
+ EvSwitchMode = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+ struct TEvSwitchMode : TEventLocal<TEvSwitchMode, EvSwitchMode> {
+ EMode Mode;
+ TEvSwitchMode(EMode mode) : Mode(mode) {}
+ };
+
+ public:
+ TTestShard(const TActorId& tablet, TTabletStorageInfo *info)
+ : TKeyValueFlat(tablet, info)
+ {
+ using TKeyValueCounters = TProtobufTabletCounters<
+ NKeyValue::ESimpleCounters_descriptor,
+ NKeyValue::ECumulativeCounters_descriptor,
+ NKeyValue::EPercentileCounters_descriptor,
+ NKeyValue::ETxTypes_descriptor>;
+
+ using TTestShardCounters = TAppProtobufTabletCounters<
+ NTestShard::ESimpleCounters_descriptor,
+ NTestShard::ECumulativeCounters_descriptor,
+ NTestShard::EPercentileCounters_descriptor>;
+
+ TProtobufTabletCountersPair<TKeyValueCounters, TTestShardCounters> pair;
+ State.SetupTabletCounters(pair.GetFirstTabletCounters().Release());
+ Counters.reset(pair.GetSecondTabletCounters().Release());
+ }
+
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TEST_SHARD_ACTOR;
+ }
+
+ void CreatedHook(const TActorContext& ctx) override {
+ Execute(CreateTxInitScheme(), ctx);
+ }
+
+ bool HandleHook(STFUNC_SIG) override {
+ switch (ev->GetTypeRewrite()) {
+ HFunc(TEvControlRequest, Handle);
+ HFunc(TEvSwitchMode, Handle);
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ void Handle(TEvControlRequest::TPtr ev, const TActorContext& ctx) {
+ const auto& record = ev->Get()->Record;
+ switch (record.GetCommandCase()) {
+ case NKikimrClient::TTestShardControlRequest::kInitialize:
+ Execute(CreateTxInitialize(record.GetInitialize(), ev->Sender, ev->Cookie), ctx);
+ break;
+
+ case NKikimrClient::TTestShardControlRequest::COMMAND_NOT_SET:
+ break;
+ }
+ }
+
+ void Handle(TEvSwitchMode::TPtr ev, const TActorContext& /*ctx*/) {
+ const EMode mode = ev->Get()->Mode;
+ auto& s = Counters->Simple();
+ s[NTestShard::COUNTER_MODE_WRITE] = mode == EMode::WRITE;
+ s[NTestShard::COUNTER_MODE_READ_VALIDATE] = mode == EMode::READ_VALIDATE;
+ s[NTestShard::COUNTER_MODE_STATE_SERVER_CONNECT] = mode == EMode::STATE_SERVER_CONNECT;
+ }
+
+ void OnLoadComplete() {
+ StartActivities();
+ }
+
+ bool OnRenderAppHtmlPage(NMon::TEvRemoteHttpInfo::TPtr ev, const TActorContext& ctx) override {
+ if (!ev) {
+ return true;
+ }
+ const auto& cgi = ev->Get()->Cgi();
+ if (cgi.Get("page") == "keyvalue") {
+ return TKeyValueFlat::OnRenderAppHtmlPage(ev, ctx);
+ } else {
+ Register(CreateMonQueryActor(ev));
+ return true;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TActorId ActivityActorId;
+
+ void StartActivities();
+ void PassAway() override;
+
+ private:
+ class TTxInitialize;
+ friend class TTxInitialize;
+ ITransaction *CreateTxInitialize(const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
+ TActorId sender, ui64 cookie);
+
+ class TTxInitScheme;
+ friend class TTxInitScheme;
+ ITransaction *CreateTxInitScheme();
+
+ class TTxLoadEverything;
+ friend class TTxLoadEverything;
+ ITransaction *CreateTxLoadEverything();
+
+ class TMonQueryActor;
+ IActor *CreateMonQueryActor(NMon::TEvRemoteHttpInfo::TPtr ev);
+ };
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/test_shard_mon.cpp b/ydb/core/test_tablet/test_shard_mon.cpp
index 839b7a142d7..6eeb0de453d 100644
--- a/ydb/core/test_tablet/test_shard_mon.cpp
+++ b/ydb/core/test_tablet/test_shard_mon.cpp
@@ -1,86 +1,86 @@
-#include "test_shard_impl.h"
-
-namespace NKikimr::NTestShard {
-
- class TTestShard::TMonQueryActor : public TActorBootstrapped<TMonQueryActor> {
- const TActorId Sender;
- const ui64 Cookie;
- const TString Query;
- const TCgiParameters Params;
-
- const TActorId ActivityActorId;
- TString ActivityActorHtml;
- ui32 RepliesPending = 0;
-
- ui64 Trash = 0;
-
- enum ECookie : ui64 {
- LOAD_ACTOR = 1,
- };
-
- public:
- TMonQueryActor(TTestShard *self, NMon::TEvRemoteHttpInfo::TPtr ev)
- : Sender(ev->Sender)
- , Cookie(ev->Cookie)
- , Query(ev->Get()->Query)
- , Params(ev->Get()->Cgi())
- , ActivityActorId(self->ActivityActorId)
- {
- Trash = self->State.GetTrashTotalBytes();
- }
-
- void Bootstrap() {
- TCgiParameters params;
- params.InsertUnescaped("trashvol", ToString(Trash));
-
- RepliesPending += Send(ActivityActorId, new NMon::TEvRemoteHttpInfo('?' + params()), 0, ECookie::LOAD_ACTOR);
- if (!RepliesPending) {
- PassAway();
- }
- Become(&TThis::StateFunc);
- }
-
- void Handle(NMon::TEvRemoteHttpInfoRes::TPtr ev) {
- switch (ev->Cookie) {
- case ECookie::LOAD_ACTOR:
- ActivityActorHtml = ev->Get()->Html;
- break;
-
- default:
- Y_FAIL("unexpected Cookie");
- }
- if (!--RepliesPending) {
- PassAway();
- }
- }
-
- void PassAway() override {
- RenderHtml();
- TActorBootstrapped::PassAway();
- }
-
- void RenderHtml() {
- TStringStream str;
-
- HTML(str) {
- DIV() {
- str << "<a href='/tablets" << Query << "&page=keyvalue'>KeyValue state</a>";
- }
- DIV() {
- str << ActivityActorHtml;
- }
- }
-
- Send(Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()), 0, Cookie);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(NMon::TEvRemoteHttpInfoRes, Handle);
- )
- };
-
- IActor *TTestShard::CreateMonQueryActor(NMon::TEvRemoteHttpInfo::TPtr ev) {
- return new TMonQueryActor(this, ev);
- }
-
-} // NKikimr::NTestShard
+#include "test_shard_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ class TTestShard::TMonQueryActor : public TActorBootstrapped<TMonQueryActor> {
+ const TActorId Sender;
+ const ui64 Cookie;
+ const TString Query;
+ const TCgiParameters Params;
+
+ const TActorId ActivityActorId;
+ TString ActivityActorHtml;
+ ui32 RepliesPending = 0;
+
+ ui64 Trash = 0;
+
+ enum ECookie : ui64 {
+ LOAD_ACTOR = 1,
+ };
+
+ public:
+ TMonQueryActor(TTestShard *self, NMon::TEvRemoteHttpInfo::TPtr ev)
+ : Sender(ev->Sender)
+ , Cookie(ev->Cookie)
+ , Query(ev->Get()->Query)
+ , Params(ev->Get()->Cgi())
+ , ActivityActorId(self->ActivityActorId)
+ {
+ Trash = self->State.GetTrashTotalBytes();
+ }
+
+ void Bootstrap() {
+ TCgiParameters params;
+ params.InsertUnescaped("trashvol", ToString(Trash));
+
+ RepliesPending += Send(ActivityActorId, new NMon::TEvRemoteHttpInfo('?' + params()), 0, ECookie::LOAD_ACTOR);
+ if (!RepliesPending) {
+ PassAway();
+ }
+ Become(&TThis::StateFunc);
+ }
+
+ void Handle(NMon::TEvRemoteHttpInfoRes::TPtr ev) {
+ switch (ev->Cookie) {
+ case ECookie::LOAD_ACTOR:
+ ActivityActorHtml = ev->Get()->Html;
+ break;
+
+ default:
+ Y_FAIL("unexpected Cookie");
+ }
+ if (!--RepliesPending) {
+ PassAway();
+ }
+ }
+
+ void PassAway() override {
+ RenderHtml();
+ TActorBootstrapped::PassAway();
+ }
+
+ void RenderHtml() {
+ TStringStream str;
+
+ HTML(str) {
+ DIV() {
+ str << "<a href='/tablets" << Query << "&page=keyvalue'>KeyValue state</a>";
+ }
+ DIV() {
+ str << ActivityActorHtml;
+ }
+ }
+
+ Send(Sender, new NMon::TEvRemoteHttpInfoRes(str.Str()), 0, Cookie);
+ }
+
+ STRICT_STFUNC(StateFunc,
+ hFunc(NMon::TEvRemoteHttpInfoRes, Handle);
+ )
+ };
+
+ IActor *TTestShard::CreateMonQueryActor(NMon::TEvRemoteHttpInfo::TPtr ev) {
+ return new TMonQueryActor(this, ev);
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/test_tablet.cpp b/ydb/core/test_tablet/test_tablet.cpp
index 8f8995bf994..18398c442e1 100644
--- a/ydb/core/test_tablet/test_tablet.cpp
+++ b/ydb/core/test_tablet/test_tablet.cpp
@@ -1,10 +1,10 @@
-#include "test_tablet.h"
-#include "test_shard_impl.h"
-
-namespace NKikimr::NTestShard {
-
- IActor *CreateTestShard(const TActorId& tablet, TTabletStorageInfo *info) {
- return new NTestShard::TTestShard(tablet, info);
- }
-
-} // NKikimr::NTestShard
+#include "test_tablet.h"
+#include "test_shard_impl.h"
+
+namespace NKikimr::NTestShard {
+
+ IActor *CreateTestShard(const TActorId& tablet, TTabletStorageInfo *info) {
+ return new NTestShard::TTestShard(tablet, info);
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/test_tablet.h b/ydb/core/test_tablet/test_tablet.h
index 60ba4f3b726..3a0d78491b4 100644
--- a/ydb/core/test_tablet/test_tablet.h
+++ b/ydb/core/test_tablet/test_tablet.h
@@ -1,9 +1,9 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr::NTestShard {
-
- IActor *CreateTestShard(const TActorId& tablet, TTabletStorageInfo *info);
-
-} // NKikimr::NTestShard
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr::NTestShard {
+
+ IActor *CreateTestShard(const TActorId& tablet, TTabletStorageInfo *info);
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/time_series.h b/ydb/core/test_tablet/time_series.h
index c200d9dd83a..68cc8350cd8 100644
--- a/ydb/core/test_tablet/time_series.h
+++ b/ydb/core/test_tablet/time_series.h
@@ -1,94 +1,94 @@
-#pragma once
-
-namespace NKikimr {
-
- class TTimeSeries {
- const size_t NumItems;
- std::vector<TDuration> Queue;
- size_t Index = 0;
-
- public:
- TTimeSeries(size_t numItems)
- : NumItems(numItems)
- {
- Queue.reserve(NumItems);
- }
-
- void Add(TDuration value) {
- if (Index == Queue.size()) {
- Queue.push_back(value);
- } else {
- Queue[Index] = value;
- }
- ++Index %= NumItems;
- }
-
- std::vector<TDuration> Percentiles(const std::vector<double>& ps) const {
- std::vector<TDuration> q = Queue;
- std::sort(q.begin(), q.end());
- std::vector<TDuration> res;
- res.reserve(ps.size());
- for (double p : ps) {
- res.push_back(q.empty() ? TDuration::Zero() : q[Min<size_t>(q.size() - 1, q.size() * p)]);
- }
- return res;
- }
- };
-
- class TSpeedMeter {
- const TDuration Window;
- ui64 BytesAccum = 0;
- std::deque<std::pair<TInstant, ui64>> BytesQ;
-
- public:
- TSpeedMeter(TDuration window)
- : Window(window)
- {}
-
- void Add(TInstant ts, ui64 numBytes) {
- BytesAccum += numBytes;
- BytesQ.emplace_back(ts, BytesAccum);
- Trim(ts);
- }
-
- ui64 GetSpeedInBytesPerSecond(TInstant now, size_t *numPoints, TDuration *timeSpan) {
- Trim(now);
- if (BytesQ.empty()) {
- return 0;
- }
- const auto& [ts, ba] = BytesQ.front();
- if (numPoints) {
- *numPoints = BytesQ.size();
- }
- if (timeSpan) {
- *timeSpan = now - ts;
- }
- return ts != now ? (ui64)1000000 * (BytesAccum - ba) / (now - ts).MicroSeconds() : 0;
- }
-
- ui64 GetBytesAccum() const {
- return BytesAccum;
- }
-
- private:
- void Trim(TInstant now) {
- const TInstant barrier = now - Window;
- while (!BytesQ.empty()) {
- auto& [ts0, ba0] = BytesQ.front();
- if (ts0 >= barrier) {
- break;
- } else if (BytesQ.size() == 1) { // ts[0] < barrier AND only one item in queue -- linear interpolation
- ba0 += (BytesAccum - ba0) * (barrier - ts0).GetValue() / (now - ts0).GetValue();
- } else if (const auto& [ts1, ba1] = BytesQ[1]; barrier < ts1) { // ts[0] < barrier < ts[1]
- ba0 += (ba1 - ba0) * (barrier - ts0).GetValue() / (ts1 - ts0).GetValue();
- } else { // ts[0] < ts[1] < barrier
- BytesQ.pop_front();
- continue;
- }
- ts0 = barrier;
- break;
- }
- }
- };
-
-} // NKikimr
+#pragma once
+
+namespace NKikimr {
+
+ class TTimeSeries {
+ const size_t NumItems;
+ std::vector<TDuration> Queue;
+ size_t Index = 0;
+
+ public:
+ TTimeSeries(size_t numItems)
+ : NumItems(numItems)
+ {
+ Queue.reserve(NumItems);
+ }
+
+ void Add(TDuration value) {
+ if (Index == Queue.size()) {
+ Queue.push_back(value);
+ } else {
+ Queue[Index] = value;
+ }
+ ++Index %= NumItems;
+ }
+
+ std::vector<TDuration> Percentiles(const std::vector<double>& ps) const {
+ std::vector<TDuration> q = Queue;
+ std::sort(q.begin(), q.end());
+ std::vector<TDuration> res;
+ res.reserve(ps.size());
+ for (double p : ps) {
+ res.push_back(q.empty() ? TDuration::Zero() : q[Min<size_t>(q.size() - 1, q.size() * p)]);
+ }
+ return res;
+ }
+ };
+
+ class TSpeedMeter {
+ const TDuration Window;
+ ui64 BytesAccum = 0;
+ std::deque<std::pair<TInstant, ui64>> BytesQ;
+
+ public:
+ TSpeedMeter(TDuration window)
+ : Window(window)
+ {}
+
+ void Add(TInstant ts, ui64 numBytes) {
+ BytesAccum += numBytes;
+ BytesQ.emplace_back(ts, BytesAccum);
+ Trim(ts);
+ }
+
+ ui64 GetSpeedInBytesPerSecond(TInstant now, size_t *numPoints, TDuration *timeSpan) {
+ Trim(now);
+ if (BytesQ.empty()) {
+ return 0;
+ }
+ const auto& [ts, ba] = BytesQ.front();
+ if (numPoints) {
+ *numPoints = BytesQ.size();
+ }
+ if (timeSpan) {
+ *timeSpan = now - ts;
+ }
+ return ts != now ? (ui64)1000000 * (BytesAccum - ba) / (now - ts).MicroSeconds() : 0;
+ }
+
+ ui64 GetBytesAccum() const {
+ return BytesAccum;
+ }
+
+ private:
+ void Trim(TInstant now) {
+ const TInstant barrier = now - Window;
+ while (!BytesQ.empty()) {
+ auto& [ts0, ba0] = BytesQ.front();
+ if (ts0 >= barrier) {
+ break;
+ } else if (BytesQ.size() == 1) { // ts[0] < barrier AND only one item in queue -- linear interpolation
+ ba0 += (BytesAccum - ba0) * (barrier - ts0).GetValue() / (now - ts0).GetValue();
+ } else if (const auto& [ts1, ba1] = BytesQ[1]; barrier < ts1) { // ts[0] < barrier < ts[1]
+ ba0 += (ba1 - ba0) * (barrier - ts0).GetValue() / (ts1 - ts0).GetValue();
+ } else { // ts[0] < ts[1] < barrier
+ BytesQ.pop_front();
+ continue;
+ }
+ ts0 = barrier;
+ break;
+ }
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/test_tablet/tx_init_scheme.cpp b/ydb/core/test_tablet/tx_init_scheme.cpp
index 665760c1f03..49f35f98018 100644
--- a/ydb/core/test_tablet/tx_init_scheme.cpp
+++ b/ydb/core/test_tablet/tx_init_scheme.cpp
@@ -1,26 +1,26 @@
-#include "test_shard_impl.h"
-#include "scheme.h"
-
-namespace NKikimr::NTestShard {
-
- class TTestShard::TTxInitScheme : public TTransactionBase<TTestShard> {
- public:
- TTxInitScheme(TTestShard *self)
- : TTransactionBase(self)
- {}
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
- return true;
- }
-
+#include "test_shard_impl.h"
+#include "scheme.h"
+
+namespace NKikimr::NTestShard {
+
+ class TTestShard::TTxInitScheme : public TTransactionBase<TTestShard> {
+ public:
+ TTxInitScheme(TTestShard *self)
+ : TTransactionBase(self)
+ {}
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ NIceDb::TNiceDb(txc.DB).Materialize<Schema>();
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- Self->Execute(Self->CreateTxLoadEverything(), ctx);
- }
- };
-
- ITransaction *TTestShard::CreateTxInitScheme() {
- return new TTxInitScheme(this);
- }
-
-} // NKikimr::NTestShard
+ Self->Execute(Self->CreateTxLoadEverything(), ctx);
+ }
+ };
+
+ ITransaction *TTestShard::CreateTxInitScheme() {
+ return new TTxInitScheme(this);
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/tx_initialize.cpp b/ydb/core/test_tablet/tx_initialize.cpp
index 70614cd3e90..dc19551825d 100644
--- a/ydb/core/test_tablet/tx_initialize.cpp
+++ b/ydb/core/test_tablet/tx_initialize.cpp
@@ -1,47 +1,47 @@
-#include "test_shard_impl.h"
-#include "scheme.h"
-
-namespace NKikimr::NTestShard {
-
- class TTestShard::TTxInitialize : public TTransactionBase<TTestShard> {
- const TActorId Sender;
- const ui64 Cookie;
- NKikimrClient::TTestShardControlRequest::TCmdInitialize Cmd;
-
- public:
- TTxInitialize(TTestShard *self, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
- TActorId sender, ui64 cookie)
- : TTransactionBase(self)
- , Sender(sender)
- , Cookie(cookie)
- , Cmd(cmd)
- {}
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- TString settings;
- const bool success = Cmd.SerializeToString(&settings);
- Y_VERIFY(success);
-
- const TString digest = MD5::CalcRaw(settings);
-
- NIceDb::TNiceDb db(txc.DB);
- db.Table<Schema::State>().Key(Schema::State::Key::Default).Update(
- NIceDb::TUpdate<Schema::State::Settings>(settings),
- NIceDb::TUpdate<Schema::State::Digest>(digest));
-
- return true;
- }
-
+#include "test_shard_impl.h"
+#include "scheme.h"
+
+namespace NKikimr::NTestShard {
+
+ class TTestShard::TTxInitialize : public TTransactionBase<TTestShard> {
+ const TActorId Sender;
+ const ui64 Cookie;
+ NKikimrClient::TTestShardControlRequest::TCmdInitialize Cmd;
+
+ public:
+ TTxInitialize(TTestShard *self, const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
+ TActorId sender, ui64 cookie)
+ : TTransactionBase(self)
+ , Sender(sender)
+ , Cookie(cookie)
+ , Cmd(cmd)
+ {}
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ TString settings;
+ const bool success = Cmd.SerializeToString(&settings);
+ Y_VERIFY(success);
+
+ const TString digest = MD5::CalcRaw(settings);
+
+ NIceDb::TNiceDb db(txc.DB);
+ db.Table<Schema::State>().Key(Schema::State::Key::Default).Update(
+ NIceDb::TUpdate<Schema::State::Settings>(settings),
+ NIceDb::TUpdate<Schema::State::Digest>(digest));
+
+ return true;
+ }
+
void Complete(const TActorContext& ctx) override {
- ctx.Send(Sender, new TEvControlResponse, 0, Cookie);
- Self->Settings = Cmd;
- Self->StartActivities();
- }
- };
-
- ITransaction *TTestShard::CreateTxInitialize(const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
- TActorId sender, ui64 cookie) {
- return new TTxInitialize(this, cmd, sender, cookie);
- }
-
-} // NKikimr::NTestShard
+ ctx.Send(Sender, new TEvControlResponse, 0, Cookie);
+ Self->Settings = Cmd;
+ Self->StartActivities();
+ }
+ };
+
+ ITransaction *TTestShard::CreateTxInitialize(const NKikimrClient::TTestShardControlRequest::TCmdInitialize& cmd,
+ TActorId sender, ui64 cookie) {
+ return new TTxInitialize(this, cmd, sender, cookie);
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/tx_load_everything.cpp b/ydb/core/test_tablet/tx_load_everything.cpp
index b00a3dada11..f5d22d748b5 100644
--- a/ydb/core/test_tablet/tx_load_everything.cpp
+++ b/ydb/core/test_tablet/tx_load_everything.cpp
@@ -1,40 +1,40 @@
-#include "test_shard_impl.h"
-#include "scheme.h"
-
-namespace NKikimr::NTestShard {
-
- class TTestShard::TTxLoadEverything : public TTransactionBase<TTestShard> {
- public:
- TTxLoadEverything(TTestShard *self)
- : TTransactionBase(self)
- {}
-
- bool Execute(TTransactionContext& txc, const TActorContext&) override {
- NIceDb::TNiceDb db(txc.DB);
- {
- using T = Schema::State;
- auto table = db.Table<T>().Key(T::Key::Default).Select();
- if (!table.IsReady()) {
- return false;
- } else if (table.IsValid()) {
- const TString settings = table.GetValue<T::Settings>();
- const TString digest = table.GetValue<T::Digest>();
- Y_VERIFY(digest == MD5::CalcRaw(settings));
- Self->Settings.emplace();
- const bool success = Self->Settings->ParseFromString(settings);
- Y_VERIFY(success);
- }
- }
- return true;
- }
-
+#include "test_shard_impl.h"
+#include "scheme.h"
+
+namespace NKikimr::NTestShard {
+
+ class TTestShard::TTxLoadEverything : public TTransactionBase<TTestShard> {
+ public:
+ TTxLoadEverything(TTestShard *self)
+ : TTransactionBase(self)
+ {}
+
+ bool Execute(TTransactionContext& txc, const TActorContext&) override {
+ NIceDb::TNiceDb db(txc.DB);
+ {
+ using T = Schema::State;
+ auto table = db.Table<T>().Key(T::Key::Default).Select();
+ if (!table.IsReady()) {
+ return false;
+ } else if (table.IsValid()) {
+ const TString settings = table.GetValue<T::Settings>();
+ const TString digest = table.GetValue<T::Digest>();
+ Y_VERIFY(digest == MD5::CalcRaw(settings));
+ Self->Settings.emplace();
+ const bool success = Self->Settings->ParseFromString(settings);
+ Y_VERIFY(success);
+ }
+ }
+ return true;
+ }
+
void Complete(const TActorContext&) override {
- Self->OnLoadComplete();
- }
- };
-
- ITransaction *TTestShard::CreateTxLoadEverything() {
- return new TTxLoadEverything(this);
- }
-
-} // NKikimr::NTestShard
+ Self->OnLoadComplete();
+ }
+ };
+
+ ITransaction *TTestShard::CreateTxLoadEverything() {
+ return new TTxLoadEverything(this);
+ }
+
+} // NKikimr::NTestShard
diff --git a/ydb/core/test_tablet/ya.make b/ydb/core/test_tablet/ya.make
index 1310b8d9d54..9e51e8562a6 100644
--- a/ydb/core/test_tablet/ya.make
+++ b/ydb/core/test_tablet/ya.make
@@ -1,7 +1,7 @@
-LIBRARY()
-
+LIBRARY()
+
OWNER(alexvru)
-
+
SRCS(
defs.h
events.h
@@ -23,12 +23,12 @@ SRCS(
tx_initialize.cpp
tx_load_everything.cpp
)
-
+
PEERDIR(
library/cpp/digest/md5
ydb/core/keyvalue
ydb/core/protos
ydb/core/util
)
-
-END()
+
+END()
diff --git a/ydb/core/testlib/basics/helpers.cpp b/ydb/core/testlib/basics/helpers.cpp
index 259e4f9da94..6504ecdb175 100644
--- a/ydb/core/testlib/basics/helpers.cpp
+++ b/ydb/core/testlib/basics/helpers.cpp
@@ -66,7 +66,7 @@ namespace NKikimr {
TMaybe<ui64> LastLsn;
};
- void TStrandedPDiskServiceFactory::Create(const TActorContext &ctx, ui32 pDiskID,
+ void TStrandedPDiskServiceFactory::Create(const TActorContext &ctx, ui32 pDiskID,
const TIntrusivePtr<TPDiskConfig> &cfg, const NPDisk::TKey &mainKey, ui32 poolId, ui32 nodeId)
{
Y_UNUSED(ctx);
diff --git a/ydb/core/testlib/basics/helpers.h b/ydb/core/testlib/basics/helpers.h
index 7a70063f7a3..46db877bbe8 100644
--- a/ydb/core/testlib/basics/helpers.h
+++ b/ydb/core/testlib/basics/helpers.h
@@ -65,7 +65,7 @@ namespace NFake {
: Runtime(runtime)
{}
- void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
+ void Create(const TActorContext &ctx, ui32 pDiskID, const TIntrusivePtr<TPDiskConfig> &cfg,
const NPDisk::TKey &mainKey, ui32 poolId, ui32 nodeId) override;
virtual ~TStrandedPDiskServiceFactory()
diff --git a/ydb/core/testlib/basics/runtime.cpp b/ydb/core/testlib/basics/runtime.cpp
index cd62ce82bfc..38696606ba0 100644
--- a/ydb/core/testlib/basics/runtime.cpp
+++ b/ydb/core/testlib/basics/runtime.cpp
@@ -26,18 +26,18 @@ namespace NActors {
TIntrusivePtr<TTableNameserverSetup> table = new TTableNameserverSetup;
for (ui32 nodeIndex = 0; nodeIndex < GetNodeCount(); ++nodeIndex) {
- const ui16 port = 12001 + nodeIndex;
+ const ui16 port = 12001 + nodeIndex;
table->StaticNodeTable[FirstNodeId + nodeIndex] =
std::pair<TString, ui32>("::1", UseRealInterconnect ? GetPortManager().GetPort(port) : port);
-
- NActorsInterconnect::TNodeLocation proto;
- proto.SetDataCenter(ToString(nodeIndex % DataCenterCount + 1));
- proto.SetModule(ToString(nodeIndex + 1));
- proto.SetRack(ToString(nodeIndex + 1));
- proto.SetUnit(ToString(nodeIndex + 1));
- table->StaticNodeTable[FirstNodeId + nodeIndex].Location = LocationCallback
- ? LocationCallback(nodeIndex)
- : TNodeLocation(proto);
+
+ NActorsInterconnect::TNodeLocation proto;
+ proto.SetDataCenter(ToString(nodeIndex % DataCenterCount + 1));
+ proto.SetModule(ToString(nodeIndex + 1));
+ proto.SetRack(ToString(nodeIndex + 1));
+ proto.SetUnit(ToString(nodeIndex + 1));
+ table->StaticNodeTable[FirstNodeId + nodeIndex].Location = LocationCallback
+ ? LocationCallback(nodeIndex)
+ : TNodeLocation(proto);
}
const TActorId dnsId = NDnsResolver::MakeDnsResolverActorId();
@@ -65,11 +65,11 @@ namespace NActors {
common->ClusterUUID = ClusterUUID;
common->AcceptUUID = {ClusterUUID};
- if (UseRealInterconnect) {
+ if (UseRealInterconnect) {
auto listener = new TInterconnectListenerTCP(nameNode.first, nameNode.second, common);
- AddLocalService({}, TActorSetupCmd(listener, TMailboxType::Simple, InterconnectPoolId()), num);
- AddLocalService(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::Simple, 0), num);
- }
+ AddLocalService({}, TActorSetupCmd(listener, TMailboxType::Simple, InterconnectPoolId()), num);
+ AddLocalService(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::Simple, 0), num);
+ }
}
}
}
diff --git a/ydb/core/testlib/basics/runtime.h b/ydb/core/testlib/basics/runtime.h
index 982dd7500bf..96e5234a389 100644
--- a/ydb/core/testlib/basics/runtime.h
+++ b/ydb/core/testlib/basics/runtime.h
@@ -9,9 +9,9 @@ namespace NActors {
public:
using TTestActorRuntime::TTestActorRuntime;
- using TNodeLocationCallback = std::function<TNodeLocation(ui32)>;
- TNodeLocationCallback LocationCallback;
-
+ using TNodeLocationCallback = std::function<TNodeLocation(ui32)>;
+ TNodeLocationCallback LocationCallback;
+
~TTestBasicRuntime();
void Initialize(TEgg) override;
diff --git a/ydb/core/testlib/basics/services.cpp b/ydb/core/testlib/basics/services.cpp
index b4585ad96c6..90e36af6ea0 100644
--- a/ydb/core/testlib/basics/services.cpp
+++ b/ydb/core/testlib/basics/services.cpp
@@ -256,11 +256,11 @@ namespace NPDisk {
for (ui32 nodeIndex = 0; nodeIndex < runtime.GetNodeCount(); ++nodeIndex) {
SetupStateStorageGroups(runtime, nodeIndex, app);
- NKikimrProto::TKeyConfig keyConfig;
- if (const auto it = app.Keys.find(nodeIndex); it != app.Keys.end()) {
- keyConfig = it->second;
- }
- SetupBSNodeWarden(runtime, nodeIndex, disk.MakeWardenConf(*app.Domains, keyConfig));
+ NKikimrProto::TKeyConfig keyConfig;
+ if (const auto it = app.Keys.find(nodeIndex); it != app.Keys.end()) {
+ keyConfig = it->second;
+ }
+ SetupBSNodeWarden(runtime, nodeIndex, disk.MakeWardenConf(*app.Domains, keyConfig));
SetupTabletResolver(runtime, nodeIndex);
SetupTabletPipePeNodeCaches(runtime, nodeIndex);
diff --git a/ydb/core/testlib/basics/storage.h b/ydb/core/testlib/basics/storage.h
index 36cee178189..532e44fa574 100644
--- a/ydb/core/testlib/basics/storage.h
+++ b/ydb/core/testlib/basics/storage.h
@@ -81,7 +81,7 @@ namespace NKikimr {
return conf;
}
- TIntrusivePtr<TNodeWardenConfig> MakeWardenConf(const TDomainsInfo &domains, const NKikimrProto::TKeyConfig& keyConfig) const
+ TIntrusivePtr<TNodeWardenConfig> MakeWardenConf(const TDomainsInfo &domains, const NKikimrProto::TKeyConfig& keyConfig) const
{
TIntrusivePtr<TNodeWardenConfig> conf(new TNodeWardenConfig(Factory));
@@ -108,9 +108,9 @@ namespace NKikimr {
vDisk->LevelCompaction = true;
vDisk->MaxLogoBlobDataSize = Conf.UseDisk ? CHUNK_SIZE / 3 : MEM_CHUNK_SIZE / 3;
- ObtainTenantKey(&conf->TenantKey, keyConfig);
- ObtainStaticKey(&conf->StaticKey);
-
+ ObtainTenantKey(&conf->TenantKey, keyConfig);
+ ObtainStaticKey(&conf->StaticKey);
+
return conf;
}
diff --git a/ydb/core/testlib/fake_coordinator.h b/ydb/core/testlib/fake_coordinator.h
index b3098d60a59..5b49c00a682 100644
--- a/ydb/core/testlib/fake_coordinator.h
+++ b/ydb/core/testlib/fake_coordinator.h
@@ -20,8 +20,8 @@ namespace NKikimr {
typedef TIntrusivePtr<TState> TPtr;
};
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR;
}
TFakeCoordinator(const TActorId &tablet, TTabletStorageInfo *info, TState::TPtr state)
@@ -208,7 +208,7 @@ namespace NKikimr {
}
for (auto& ev : kv.second) {
- TAllocChunkSerializer serializer;
+ TAllocChunkSerializer serializer;
ev->SerializeToArcadiaStream(&serializer);
Cerr << "FAKE_COORDINATOR: Send Plan to tablet " << tabletId << " for txId: " << ev->Record.GetTransactions(0).GetTxId() << " at step: " << step << "\n";
diff --git a/ydb/core/testlib/fake_scheme_shard.h b/ydb/core/testlib/fake_scheme_shard.h
index 8c388d49dd0..f38543b29cd 100644
--- a/ydb/core/testlib/fake_scheme_shard.h
+++ b/ydb/core/testlib/fake_scheme_shard.h
@@ -30,8 +30,8 @@ class TFakeSchemeShard : public TActor<TFakeSchemeShard>, public NTabletFlatExec
public:
using TState = TFakeSchemeShardState;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
}
TFakeSchemeShard(const TActorId &tablet, TTabletStorageInfo *info, TState::TPtr state)
diff --git a/ydb/core/testlib/tablet_flat_dummy.cpp b/ydb/core/testlib/tablet_flat_dummy.cpp
index 1a9dca04a52..e6a0332e0ad 100644
--- a/ydb/core/testlib/tablet_flat_dummy.cpp
+++ b/ydb/core/testlib/tablet_flat_dummy.cpp
@@ -110,8 +110,8 @@ class TDummyFlatTablet : public TActor<TDummyFlatTablet>, public NTabletFlatExec
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TEST_ACTOR_RUNTIME;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TEST_ACTOR_RUNTIME;
}
TDummyFlatTablet(const TActorId &tablet, TTabletStorageInfo *info)
diff --git a/ydb/core/testlib/tablet_helpers.cpp b/ydb/core/testlib/tablet_helpers.cpp
index a853040b932..7e68944530e 100644
--- a/ydb/core/testlib/tablet_helpers.cpp
+++ b/ydb/core/testlib/tablet_helpers.cpp
@@ -68,8 +68,8 @@ namespace NKikimr {
class TFakeMediatorTimecastProxy : public TActor<TFakeMediatorTimecastProxy> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
}
TFakeMediatorTimecastProxy()
@@ -711,7 +711,7 @@ namespace NKikimr {
runtime.Send(new IEventHandle(GetNameserviceActorId(), sender, new TEvInterconnect::TEvListNodes));
TAutoPtr<IEventHandle> handleNodesInfo;
auto nodesInfo = runtime.GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
- auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
NKikimrBlobStorage::TDefineBox boxConfig;
boxConfig.SetBoxId(1);
@@ -1085,8 +1085,8 @@ namespace NKikimr {
using TTabletInfo = TFakeHiveTabletInfo;
using TState = TFakeHiveState;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_ACTOR;
}
TFakeHive(const TActorId &tablet, TTabletStorageInfo *info, TState::TPtr state,
diff --git a/ydb/core/testlib/tenant_runtime.cpp b/ydb/core/testlib/tenant_runtime.cpp
index 974cc166d0d..53a6fd387d9 100644
--- a/ydb/core/testlib/tenant_runtime.cpp
+++ b/ydb/core/testlib/tenant_runtime.cpp
@@ -82,7 +82,7 @@ const TString ZONE_ANY = "any";
const TTenantTestConfig DefaultTenantTestConfig = {
// Domains {name, schemeshard {{ subdomain_names }}}
- {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
+ {{ {DOMAIN1_NAME, SCHEME_SHARD1_ID, {{ TENANT1_1_NAME, TENANT1_2_NAME }}} }},
// HiveId
HIVE_ID,
// FakeTenantSlotBroker
@@ -98,11 +98,11 @@ const TTenantTestConfig DefaultTenantTestConfig = {
// TenantPoolConfig
{
// Static slots {tenant, {cpu, memory, network}}
- {{ {DOMAIN1_NAME, {1, 1, 1}} }},
+ {{ {DOMAIN1_NAME, {1, 1, 1}} }},
// Dynamic slots {id, type, domain, tenant, {cpu, memory, network}}
{{ {DOMAIN1_SLOT1, SLOT1_TYPE, DOMAIN1_NAME, "", {1, 1, 1}},
{DOMAIN1_SLOT2, SLOT2_TYPE, DOMAIN1_NAME, "", {2, 2, 2}},
- {DOMAIN1_SLOT3, SLOT3_TYPE, DOMAIN1_NAME, "", {3, 3, 3}} }},
+ {DOMAIN1_SLOT3, SLOT3_TYPE, DOMAIN1_NAME, "", {3, 3, 3}} }},
"node-type"
}
}
@@ -193,8 +193,8 @@ class TFakeSchemeShard : public TActor<TFakeSchemeShard>, public TTabletExecuted
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
}
TFakeSchemeShard(const TActorId &tablet, TTabletStorageInfo *info,
@@ -636,8 +636,8 @@ class TFakeHive : public TActor<TFakeHive>, public TTabletExecutedFlat {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::HIVE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::HIVE_ACTOR;
}
TFakeHive(const TActorId &tablet, TTabletStorageInfo *info, TActorId sender,
@@ -986,7 +986,7 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
host.MutableKey()->SetFqdn(node.Host);
host.MutableKey()->SetIcPort(node.Port);
}
- auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto request = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
request->Record.MutableRequest()->AddCommand()->MutableDefineHostConfig()->CopyFrom(hostConfig);
request->Record.MutableRequest()->AddCommand()->MutableDefineBox()->CopyFrom(boxConfig);
@@ -1047,16 +1047,16 @@ void TTenantTestRuntime::Setup(bool createTenantPools)
auto &config = *req->Record.MutableConfig()->MutableTenantsConfig();
auto zone1 = config.AddAvailabilityZoneKinds();
zone1->SetKind(ZONE1);
- zone1->SetDataCenterName(ToString(1));
+ zone1->SetDataCenterName(ToString(1));
auto zone2 = config.AddAvailabilityZoneKinds();
zone2->SetKind(ZONE2);
- zone2->SetDataCenterName(ToString(2));
+ zone2->SetDataCenterName(ToString(2));
auto zone3 = config.AddAvailabilityZoneKinds();
zone3->SetKind(ZONE3);
- zone3->SetDataCenterName(ToString(3));
+ zone3->SetDataCenterName(ToString(3));
auto zone4 = config.AddAvailabilityZoneKinds();
zone4->SetKind(ZONE_ANY);
- zone4->SetDataCenterName(NTenantSlotBroker::ANY_DATA_CENTER);
+ zone4->SetDataCenterName(NTenantSlotBroker::ANY_DATA_CENTER);
auto set1 = config.AddAvailabilityZoneSets();
set1->SetName("all");
set1->AddZoneKinds(ZONE1);
diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp
index d4907c26f1e..a0681d931dd 100644
--- a/ydb/core/testlib/test_client.cpp
+++ b/ydb/core/testlib/test_client.cpp
@@ -385,7 +385,7 @@ namespace Tests {
TAutoPtr<IEventHandle> handleNodesInfo;
auto nodesInfo = Runtime->GrabEdgeEventRethrow<TEvInterconnect::TEvNodesInfo>(handleNodesInfo);
- auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
+ auto bsConfigureRequest = MakeHolder<TEvBlobStorage::TEvControllerConfigRequest>();
NKikimrBlobStorage::TDefineBox boxConfig;
boxConfig.SetBoxId(Settings->BOX_ID);
@@ -943,7 +943,7 @@ namespace Tests {
TAutoPtr<NBus::TBusMessage> reply;
UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
- const NKikimrClient::TTypeMetadataResponse &response = static_cast<NMsgBusProxy::TBusTypesResponse*>(reply.Get())->Record;
+ const NKikimrClient::TTypeMetadataResponse &response = static_cast<NMsgBusProxy::TBusTypesResponse*>(reply.Get())->Record;
UNIT_ASSERT_VALUES_EQUAL((ui32)NMsgBusProxy::MSTATUS_OK, response.GetStatus());
if (!response.HasETag()) {
UNIT_ASSERT(TypesEtag.Defined());
@@ -1039,7 +1039,7 @@ namespace Tests {
}
- void TClient::ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path) {
+ void TClient::ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path) {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
request->Record.SetCommand(command);
if (path)
@@ -1050,13 +1050,13 @@ namespace Tests {
TString TClient::StartTrace(const TString &path) {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
- request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
+ request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::START);
if (path)
request->Record.SetPath(path);
TAutoPtr<NBus::TBusMessage> reply;
UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
if (reply.Get()->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS) {
- const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
+ const NKikimrClient::TMessageBusTraceStatus &response = static_cast<NMsgBusProxy::TBusMessageBusTraceStatus *>(reply.Get())->Record;
return response.GetPath();
} else {
ythrow yexception() << "MessageBus trace not enabled on the server (see mbus/--trace-path option)";
@@ -1065,7 +1065,7 @@ namespace Tests {
void TClient::StopTrace() {
TAutoPtr<NMsgBusProxy::TBusMessageBusTraceRequest> request(new NMsgBusProxy::TBusMessageBusTraceRequest());
- request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
+ request->Record.SetCommand(NKikimrClient::TMessageBusTraceRequest::STOP);
TAutoPtr<NBus::TBusMessage> reply;
UNIT_ASSERT_VALUES_EQUAL(SyncCall(request, reply), NBus::MESSAGE_OK);
}
@@ -1079,7 +1079,7 @@ namespace Tests {
NBus::EMessageStatus status;
const NKikimrClient::TResponse* response = nullptr;
do {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperationStatus> msg = new NMsgBusProxy::TBusSchemeOperationStatus();
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperationStatus> msg = new NMsgBusProxy::TBusSchemeOperationStatus();
msg->Record.MutableFlatTxId()->SetTxId(txId);
msg->Record.MutableFlatTxId()->SetSchemeShardTabletId(schemeshard);
msg->Record.MutableFlatTxId()->SetPathId(pathId);
@@ -1130,7 +1130,7 @@ namespace Tests {
}
NMsgBusProxy::EResponseStatus TClient::MkDir(const TString& parent, const TString& name, const TApplyIf& applyIf) {
- NMsgBusProxy::TBusSchemeOperation* request(new NMsgBusProxy::TBusSchemeOperation());
+ NMsgBusProxy::TBusSchemeOperation* request(new NMsgBusProxy::TBusSchemeOperation());
auto* mkDirTx = request->Record.MutableTransaction()->MutableModifyScheme();
mkDirTx->SetWorkingDir(parent);
mkDirTx->SetOperationType(NKikimrSchemeOp::ESchemeOpMkDir);
@@ -1142,7 +1142,7 @@ namespace Tests {
Cout << PrintResult<NMsgBusProxy::TBusResponse>(reply.Get()) << Endl;
#endif
UNIT_ASSERT_VALUES_EQUAL(msgStatus, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
}
@@ -1321,7 +1321,7 @@ namespace Tests {
}
NMsgBusProxy::EResponseStatus TClient::CreateTable(const TString& parent, const NKikimrSchemeOp::TTableDescription &table, TDuration timeout) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable);
op->SetWorkingDir(parent);
@@ -1329,7 +1329,7 @@ namespace Tests {
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply, timeout);
UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
}
@@ -1496,7 +1496,7 @@ namespace Tests {
}
TAutoPtr<NMsgBusProxy::TBusResponse> TClient::AlterTable(const TString& parent, const NKikimrSchemeOp::TTableDescription& alter, const TString& userToken) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpAlterTable);
op->SetWorkingDir(parent);
@@ -1531,7 +1531,7 @@ namespace Tests {
}
NMsgBusProxy::EResponseStatus TClient::StoreTableBackup(const TString& parent, const NKikimrSchemeOp::TBackupTask& task) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpBackup);
op->SetWorkingDir(parent);
@@ -1539,12 +1539,12 @@ namespace Tests {
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply);
UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
}
NMsgBusProxy::EResponseStatus TClient::DeleteTable(const TString& parent, const TString& name) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpDropTable);
op->SetWorkingDir(parent);
@@ -1552,7 +1552,7 @@ namespace Tests {
TAutoPtr<NBus::TBusMessage> reply;
NBus::EMessageStatus status = SendAndWaitCompletion(request.Release(), reply);
UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
return (NMsgBusProxy::EResponseStatus)response.GetStatus();
}
@@ -1570,7 +1570,7 @@ namespace Tests {
}
TAutoPtr<NMsgBusProxy::TBusResponse> TClient::TryDropPersQueueGroup(const TString& parent, const TString& name) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto * op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpDropPersQueueGroup);
op->SetWorkingDir(parent);
@@ -1608,7 +1608,7 @@ namespace Tests {
}
TAutoPtr<NMsgBusProxy::TBusResponse> TClient::LsImpl(const TString& path) {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
request->Record.SetPath(path);
request->Record.MutableOptions()->SetShowPrivateTable(true);
TAutoPtr<NBus::TBusMessage> reply;
@@ -1686,7 +1686,7 @@ namespace Tests {
}
void TClient::ModifyACL(const TString& parent, const TString& name, const TString& acl) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
auto *op = request->Record.MutableTransaction()->MutableModifyScheme();
op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
op->SetWorkingDir(parent);
@@ -1821,7 +1821,7 @@ namespace Tests {
auto status = SyncCall(request, reply);
UNIT_ASSERT_VALUES_EQUAL(status, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
UNIT_ASSERT_VALUES_EQUAL(response.GetStatus(), NMsgBusProxy::MSTATUS_OK);
if (response.HasExecutionEngineEvaluatedResponse())
@@ -1842,7 +1842,7 @@ namespace Tests {
auto status = SyncCall(request, reply);
UNIT_ASSERT_EQUAL(status, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
UNIT_ASSERT_EQUAL(response.GetStatus(), NMsgBusProxy::MSTATUS_OK);
err = response.GetErrorReason();
@@ -1869,7 +1869,7 @@ namespace Tests {
NBus::EMessageStatus msgStatus = SyncCall(request, reply);
UNIT_ASSERT_EQUAL(msgStatus, NBus::MESSAGE_OK);
- const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
+ const NKikimrClient::TResponse &response = static_cast<NMsgBusProxy::TBusResponse *>(reply.Get())->Record;
if (!response.HasMiniKQLCompileResults())
return false;
@@ -1888,7 +1888,7 @@ namespace Tests {
return true;
}
- ui32 TClient::FlatQueryRaw(const TString &query, TFlatQueryOptions& opts, NKikimrClient::TResponse& response, int retryCnt) {
+ ui32 TClient::FlatQueryRaw(const TString &query, TFlatQueryOptions& opts, NKikimrClient::TResponse& response, int retryCnt) {
while (retryCnt--) {
TAutoPtr<NMsgBusProxy::TBusRequest> request = new NMsgBusProxy::TBusRequest();
{
@@ -1925,7 +1925,7 @@ namespace Tests {
}
bool TClient::FlatQuery(const TString &query, TFlatQueryOptions& opts, NKikimrMiniKQL::TResult &result, const NKikimrClient::TResponse& expectedResponse) {
- NKikimrClient::TResponse response;
+ NKikimrClient::TResponse response;
FlatQueryRaw(query, opts, response);
if (!response.GetDataShardErrors().empty()) {
diff --git a/ydb/core/testlib/test_client.h b/ydb/core/testlib/test_client.h
index 2064752ab45..86e0c0e1d88 100644
--- a/ydb/core/testlib/test_client.h
+++ b/ydb/core/testlib/test_client.h
@@ -298,7 +298,7 @@ namespace Tests {
request->Record.SetSecurityToken(SecurityToken);
}
- void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeOperation>& request) {
+ void PrepareRequest(TAutoPtr<NMsgBusProxy::TBusSchemeOperation>& request) {
if (!SecurityToken.empty())
request->Record.SetSecurityToken(SecurityToken);
}
@@ -338,7 +338,7 @@ namespace Tests {
void InitRootScheme();
void InitRootScheme(const TString& root);
- void ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path = TString());
+ void ExecuteTraceCommand(NKikimrClient::TMessageBusTraceRequest::ECommand command, const TString &path = TString());
TString StartTrace(const TString &path);
void StopTrace();
@@ -394,7 +394,7 @@ namespace Tests {
bool FlatQueryParams(const TString &query, const TString &params, bool queryCompiled, NKikimrMiniKQL::TResult &result);
// returns NMsgBusProxy::MSTATUS_* and the raw response
- ui32 FlatQueryRaw(const TString &query, TFlatQueryOptions& opts, NKikimrClient::TResponse& response, int retryCnt = 10);
+ ui32 FlatQueryRaw(const TString &query, TFlatQueryOptions& opts, NKikimrClient::TResponse& response, int retryCnt = 10);
bool Compile(const TString &mkql, TString &compiled);
bool LocalQuery(ui64 tabletId, const TString &pgmText, NKikimrMiniKQL::TResult& result);
@@ -484,7 +484,7 @@ namespace Tests {
NBus::EMessageStatus WaitCompletion(ui64 txId, ui64 schemeshard, ui64 pathId,
TAutoPtr<NBus::TBusMessage>& reply,
TDuration timeout = TDuration::Seconds(1000));
- NBus::EMessageStatus SendAndWaitCompletion(TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request,
+ NBus::EMessageStatus SendAndWaitCompletion(TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request,
TAutoPtr<NBus::TBusMessage>& reply,
TDuration timeout = TDuration::Seconds(1000));
diff --git a/ydb/core/tracing/tablet_info.cpp b/ydb/core/tracing/tablet_info.cpp
index 6eb99ffc60e..704ce0cc54c 100644
--- a/ydb/core/tracing/tablet_info.cpp
+++ b/ydb/core/tracing/tablet_info.cpp
@@ -85,8 +85,8 @@ class TTabletLookupActor : public TActorBootstrapped<TTabletLookupActor> {
public:
using TReplyStatus = TWBReplyStatus<TEvWhiteboard::TEvTabletLookupResponse>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_LOOKUP_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_LOOKUP_ACTOR;
}
TTabletLookupActor(ui32 nodeId, const TActorId& sender, ui32 timeout)
@@ -271,7 +271,7 @@ class TTraceLookupActor : public TActorBootstrapped<TTraceLookupActor> {
public:
using TReplyStatus = TWBReplyStatus<TEvWhiteboard::TEvTraceLookupResponse>;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::TRACE_LOOKUP_ACTOR;
}
@@ -480,8 +480,8 @@ private:
class TTraceRequestActor : public TActorBootstrapped<TTraceRequestActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TRACE_REQUEST_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TRACE_REQUEST_ACTOR;
}
TTraceRequestActor(const NTracing::TTraceInfo& traceInfo, const TActorId& sender)
@@ -556,8 +556,8 @@ private:
class TSignalBodyRequestActor : public TActorBootstrapped<TSignalBodyRequestActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SIGNAL_BODY_REQUEST_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SIGNAL_BODY_REQUEST_ACTOR;
}
TSignalBodyRequestActor(const NTracing::TTraceInfo& traceInfo, const TString& signalId, const TActorId& sender)
@@ -656,8 +656,8 @@ void RenderTabletPage(NMon::TEvHttpInfo::TPtr ev, const TActorContext &ctx, ui64
class TTabletInfoActor : public TActorBootstrapped<TTabletInfoActor> {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_INFO;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_INFO;
}
void Bootstrap(const TActorContext &ctx);
STFUNC(StateWork);
diff --git a/ydb/core/tx/coordinator/coordinator_impl.h b/ydb/core/tx/coordinator/coordinator_impl.h
index 39018aff1e7..d8f0d61719c 100644
--- a/ydb/core/tx/coordinator/coordinator_impl.h
+++ b/ydb/core/tx/coordinator/coordinator_impl.h
@@ -501,8 +501,8 @@ private:
void MaybeFlushAcquireReadStep(const TActorContext &ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_COORDINATOR_ACTOR;
}
TTxCoordinator(TTabletStorageInfo *info, const TActorId &tablet);
diff --git a/ydb/core/tx/coordinator/mediator_queue.cpp b/ydb/core/tx/coordinator/mediator_queue.cpp
index 9b3955fa1bf..fd4ee61d1cc 100644
--- a/ydb/core/tx/coordinator/mediator_queue.cpp
+++ b/ydb/core/tx/coordinator/mediator_queue.cpp
@@ -134,8 +134,8 @@ class TTxCoordinatorMediatorQueue : public TActorBootstrapped<TTxCoordinatorMedi
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_COORDINATOR_MEDIATORQ_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_COORDINATOR_MEDIATORQ_ACTOR;
}
TTxCoordinatorMediatorQueue(const TActorId &owner, ui64 coordinator, ui64 mediator, ui64 coordinatorGeneration)
diff --git a/ydb/core/tx/datashard/datashard__conditional_erase_rows.cpp b/ydb/core/tx/datashard/datashard__conditional_erase_rows.cpp
index 026b14e461f..375c9b06615 100644
--- a/ydb/core/tx/datashard/datashard__conditional_erase_rows.cpp
+++ b/ydb/core/tx/datashard/datashard__conditional_erase_rows.cpp
@@ -392,7 +392,7 @@ protected:
}
for (const auto& [_, keyMap] : Indexes) {
- for (const auto& [indexColumnId, mainColumnId] : keyMap) {
+ for (const auto& [indexColumnId, mainColumnId] : keyMap) {
Y_UNUSED(indexColumnId);
if (keys.contains(mainColumnId)) {
diff --git a/ydb/core/tx/datashard/datashard__read_columns.cpp b/ydb/core/tx/datashard/datashard__read_columns.cpp
index 2b56a192d10..84f872705eb 100644
--- a/ydb/core/tx/datashard/datashard__read_columns.cpp
+++ b/ydb/core/tx/datashard/datashard__read_columns.cpp
@@ -350,7 +350,7 @@ public:
return true;
}
- for (const auto& col : Ev->Get()->Record.GetColumns()) {
+ for (const auto& col : Ev->Get()->Record.GetColumns()) {
if (!columnsByName.contains(col)) {
SetError(NKikimrTxDataShard::TError::SCHEME_ERROR,
Sprintf("Unknown column: %s", col.data()));
diff --git a/ydb/core/tx/datashard/datashard__stats.cpp b/ydb/core/tx/datashard/datashard__stats.cpp
index 129a14dca5f..8b4e229b3bd 100644
--- a/ydb/core/tx/datashard/datashard__stats.cpp
+++ b/ydb/core/tx/datashard/datashard__stats.cpp
@@ -24,7 +24,7 @@ public:
{}
static constexpr auto ActorActivityType() {
- return NKikimrServices::TActivity::DATASHARD_STATS_BUILDER;
+ return NKikimrServices::TActivity::DATASHARD_STATS_BUILDER;
}
void Bootstrap(const TActorContext& ctx) {
diff --git a/ydb/core/tx/datashard/datashard_distributed_erase.cpp b/ydb/core/tx/datashard/datashard_distributed_erase.cpp
index fae7d2edeb3..4709c7d05db 100644
--- a/ydb/core/tx/datashard/datashard_distributed_erase.cpp
+++ b/ydb/core/tx/datashard/datashard_distributed_erase.cpp
@@ -623,7 +623,7 @@ class TDistEraser: public TActorBootstrapped<TDistEraser> {
for (const auto& [tableId, info] : TableInfos) {
TVector<TCell> cells(Reserve(info.GetKeyMap().size()));
- for (const auto& [_, id] : info.GetKeyMap()) {
+ for (const auto& [_, id] : info.GetKeyMap()) {
if (!keyColumnIdToIdx.contains(id)) {
return BadRequest(TStringBuilder() << "Key column is absent"
<< ": tableId# " << tableId
@@ -693,7 +693,7 @@ class TDistEraser: public TActorBootstrapped<TDistEraser> {
request.SetTableId(tableId.PathId.LocalPathId);
request.SetSchemaVersion(tableId.SchemaVersion);
- for (const auto& [id, _] : keyMap) {
+ for (const auto& [id, _] : keyMap) {
request.AddKeyColumnIds(id);
}
diff --git a/ydb/core/tx/datashard/datashard_impl.h b/ydb/core/tx/datashard/datashard_impl.h
index 11313474f80..b9891c9ce4e 100644
--- a/ydb/core/tx/datashard/datashard_impl.h
+++ b/ydb/core/tx/datashard/datashard_impl.h
@@ -1058,8 +1058,8 @@ class TDataShard
TReadWriteVersions GetLocalReadWriteVersions() const;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_DATASHARD_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_DATASHARD_ACTOR;
}
TDataShard(const TActorId &tablet, TTabletStorageInfo *info);
diff --git a/ydb/core/tx/datashard/read_table_scan.cpp b/ydb/core/tx/datashard/read_table_scan.cpp
index 63e94fde967..3d9c7e35ffb 100644
--- a/ydb/core/tx/datashard/read_table_scan.cpp
+++ b/ydb/core/tx/datashard/read_table_scan.cpp
@@ -266,8 +266,8 @@ private:
class TReadTableScan : public TActor<TReadTableScan>, public NTable::IScan {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_READ_TABLE_SCAN;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_READ_TABLE_SCAN;
}
TReadTableScan(ui64 txId, ui64 shardId, TUserTable::TCPtr tableInfo,
diff --git a/ydb/core/tx/mediator/execute_queue.cpp b/ydb/core/tx/mediator/execute_queue.cpp
index 07740e9f826..d780c7ef6d9 100644
--- a/ydb/core/tx/mediator/execute_queue.cpp
+++ b/ydb/core/tx/mediator/execute_queue.cpp
@@ -172,8 +172,8 @@ namespace NTxMediator {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
}
TTxMediatorExecQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui32 timecastBuckets)
diff --git a/ydb/core/tx/mediator/mediator_impl.h b/ydb/core/tx/mediator/mediator_impl.h
index c98bd4246b0..ab87efd75fb 100644
--- a/ydb/core/tx/mediator/mediator_impl.h
+++ b/ydb/core/tx/mediator/mediator_impl.h
@@ -382,8 +382,8 @@ public:
using TTables = SchemaTables<State, DomainConfiguration>;
};
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
}
TTxMediator(TTabletStorageInfo *info, const TActorId &tablet);
diff --git a/ydb/core/tx/mediator/tablet_queue.cpp b/ydb/core/tx/mediator/tablet_queue.cpp
index b28179517ca..9d28e815505 100644
--- a/ydb/core/tx/mediator/tablet_queue.cpp
+++ b/ydb/core/tx/mediator/tablet_queue.cpp
@@ -118,17 +118,17 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
evx.Record.SetMediator(Mediator);
evx.Record.SetBucket(HashBucket);
evx.Record.SetTimeBarrier(CommitedStep);
- TAllocChunkSerializer serializer;
+ TAllocChunkSerializer serializer;
const bool success = evx.SerializeToArcadiaStream(&serializer);
- Y_VERIFY(success);
- TIntrusivePtr<TEventSerializedData> data = serializer.Release(evx.IsExtendedFormat());
+ Y_VERIFY(success);
+ TIntrusivePtr<TEventSerializedData> data = serializer.Release(evx.IsExtendedFormat());
// todo: we must throttle delivery
const ui32 sendFlags = IEventHandle::FlagTrackDelivery;
for (const TActorId &x : TimecastWatches) {
LOG_DEBUG_S(ctx, NKikimrServices::TX_MEDIATOR_TABLETQUEUE, "Actor# " << ctx.SelfID.ToString()
<< " Mediator# " << Mediator << " SEND to# " << x.ToString() << " " << evx.ToString());
- ctx.ExecutorThread.Send(new IEventHandle(TEvMediatorTimecast::TEvUpdate::EventType, sendFlags, x, ctx.SelfID, data, 0));
+ ctx.ExecutorThread.Send(new IEventHandle(TEvMediatorTimecast::TEvUpdate::EventType, sendFlags, x, ctx.SelfID, data, 0));
}
}
}
@@ -336,8 +336,8 @@ class TTxMediatorTabletQueue : public TActor<TTxMediatorTabletQueue> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
}
TTxMediatorTabletQueue(const TActorId &owner, ui64 mediator, ui64 hashRange, ui64 hashBucket)
diff --git a/ydb/core/tx/scheme_board/cache.cpp b/ydb/core/tx/scheme_board/cache.cpp
index 8e778a4a1d8..69358e9e791 100644
--- a/ydb/core/tx/scheme_board/cache.cpp
+++ b/ydb/core/tx/scheme_board/cache.cpp
@@ -2531,8 +2531,8 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::PROXY_SCHEME_CACHE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::PROXY_SCHEME_CACHE;
}
TSchemeCache(NSchemeCache::TSchemeCacheConfig* config)
diff --git a/ydb/core/tx/scheme_board/populator.cpp b/ydb/core/tx/scheme_board/populator.cpp
index f860bb88cb1..b13af411427 100644
--- a/ydb/core/tx/scheme_board/populator.cpp
+++ b/ydb/core/tx/scheme_board/populator.cpp
@@ -403,8 +403,8 @@ class TReplicaPopulator: public TMonitorableActor<TReplicaPopulator> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SCHEME_BOARD_REPLICA_POPULATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SCHEME_BOARD_REPLICA_POPULATOR_ACTOR;
}
explicit TReplicaPopulator(
@@ -901,8 +901,8 @@ class TPopulator: public TMonitorableActor<TPopulator> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SCHEME_BOARD_POPULATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SCHEME_BOARD_POPULATOR_ACTOR;
}
explicit TPopulator(
diff --git a/ydb/core/tx/scheme_board/replica.cpp b/ydb/core/tx/scheme_board/replica.cpp
index 638656e91db..ae22b2f1aec 100644
--- a/ydb/core/tx/scheme_board/replica.cpp
+++ b/ydb/core/tx/scheme_board/replica.cpp
@@ -1299,8 +1299,8 @@ private:
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SCHEME_BOARD_REPLICA_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SCHEME_BOARD_REPLICA_ACTOR;
}
void Bootstrap() {
diff --git a/ydb/core/tx/scheme_board/subscriber.cpp b/ydb/core/tx/scheme_board/subscriber.cpp
index 97173d81ad5..7f04ac4eeeb 100644
--- a/ydb/core/tx/scheme_board/subscriber.cpp
+++ b/ydb/core/tx/scheme_board/subscriber.cpp
@@ -507,7 +507,7 @@ class TSubscriberProxy: public TMonitorableActor<TDerived> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::SCHEME_BOARD_SUBSCRIBER_PROXY_ACTOR;
}
@@ -915,8 +915,8 @@ class TSubscriber: public TMonitorableActor<TDerived> {
}
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SCHEME_BOARD_SUBSCRIBER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SCHEME_BOARD_SUBSCRIBER_ACTOR;
}
static constexpr TStringBuf LogPrefix() {
diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.h b/ydb/core/tx/schemeshard/schemeshard_impl.h
index e1a1d08b9a6..50eb7f3ac49 100644
--- a/ydb/core/tx/schemeshard/schemeshard_impl.h
+++ b/ydb/core/tx/schemeshard/schemeshard_impl.h
@@ -1081,8 +1081,8 @@ private:
static NTabletPipe::TClientConfig GetPipeClientConfig();
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR;
}
TSchemeShard(const TActorId &tablet, TTabletStorageInfo *info);
diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
index fcb564b6065..22a566414c5 100644
--- a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
@@ -804,7 +804,7 @@ bool TPartitionConfigMerger::VerifyCreateParams(
return false;
}
- if (followerGroup.AllowedDataCenterNumIDsSize() || followerGroup.AllowedDataCentersSize()) {
+ if (followerGroup.AllowedDataCenterNumIDsSize() || followerGroup.AllowedDataCentersSize()) {
errDescr = TStringBuilder()
<< "FollowerGroup: AllowedDataCenterIDs is enabled, hasn't been tested";
return false;
diff --git a/ydb/core/tx/schemeshard/ut_helpers/ls_checks.cpp b/ydb/core/tx/schemeshard/ut_helpers/ls_checks.cpp
index c5d6c5a973a..e6d018ab05f 100644
--- a/ydb/core/tx/schemeshard/ut_helpers/ls_checks.cpp
+++ b/ydb/core/tx/schemeshard/ut_helpers/ls_checks.cpp
@@ -743,9 +743,9 @@ TCheckFunc FollowerGroups(const TVector<NKikimrHive::TFollowerGroup>& followerGr
UNIT_ASSERT_VALUES_EQUAL(srcSG.GetAllowedNodeIDs(i), dstSG.GetAllowedNodeIDs(i));
}
- UNIT_ASSERT_VALUES_EQUAL(srcSG.AllowedDataCentersSize(), dstSG.AllowedDataCentersSize());
- for(ui32 i = 0; i < srcSG.AllowedDataCentersSize(); ++i) {
- UNIT_ASSERT_VALUES_EQUAL(srcSG.GetAllowedDataCenters(i), dstSG.GetAllowedDataCenters(i));
+ UNIT_ASSERT_VALUES_EQUAL(srcSG.AllowedDataCentersSize(), dstSG.AllowedDataCentersSize());
+ for(ui32 i = 0; i < srcSG.AllowedDataCentersSize(); ++i) {
+ UNIT_ASSERT_VALUES_EQUAL(srcSG.GetAllowedDataCenters(i), dstSG.GetAllowedDataCenters(i));
}
UNIT_ASSERT_VALUES_EQUAL(srcSG.GetRequireAllDataCenters(), dstSG.GetRequireAllDataCenters());
UNIT_ASSERT_VALUES_EQUAL(srcSG.GetLocalNodeOnly(), dstSG.GetLocalNodeOnly());
diff --git a/ydb/core/tx/schemeshard/ut_pq/ya.make b/ydb/core/tx/schemeshard/ut_pq/ya.make
index fe304ef882b..6cce4522e37 100644
--- a/ydb/core/tx/schemeshard/ut_pq/ya.make
+++ b/ydb/core/tx/schemeshard/ut_pq/ya.make
@@ -1,24 +1,24 @@
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
+
OWNER(
vvvv
g:kikimr
)
-
-FORK_SUBTESTS()
+
+FORK_SUBTESTS()
SPLIT_FACTOR(10)
-IF (SANITIZER_TYPE OR WITH_VALGRIND)
- TIMEOUT(3600)
- SIZE(LARGE)
+IF (SANITIZER_TYPE OR WITH_VALGRIND)
+ TIMEOUT(3600)
+ SIZE(LARGE)
TAG(ya:fat)
-ELSE()
+ELSE()
TIMEOUT(600)
SIZE(MEDIUM)
-ENDIF()
-
-PEERDIR(
+ENDIF()
+
+PEERDIR(
library/cpp/getopt
library/cpp/regex/pcre
library/cpp/svnversion
@@ -26,10 +26,10 @@ PEERDIR(
ydb/core/tx
ydb/core/tx/schemeshard/ut_helpers
ydb/library/yql/public/udf/service/exception_policy
-)
-
-SRCS(
+)
+
+SRCS(
ut_pq.cpp
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/tx/schemeshard/ut_reboots.cpp b/ydb/core/tx/schemeshard/ut_reboots.cpp
index dce2c127122..53cf542de35 100644
--- a/ydb/core/tx/schemeshard/ut_reboots.cpp
+++ b/ydb/core/tx/schemeshard/ut_reboots.cpp
@@ -1,15 +1,15 @@
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
-
+
#include <ydb/core/tx/datashard/datashard.h>
#include <ydb/core/protos/flat_scheme_op.pb.h>
#include <google/protobuf/text_format.h>
-using namespace NKikimr;
+using namespace NKikimr;
using namespace NSchemeShard;
-using namespace NSchemeShardUT_Private;
-
+using namespace NSchemeShardUT_Private;
+
Y_UNIT_TEST_SUITE(IntermediateDirsReboots) {
Y_UNIT_TEST(Fake) {
}
@@ -68,18 +68,18 @@ Y_UNIT_TEST_SUITE(IntermediateDirsReboots) {
)";
const auto validStatus = NKikimrScheme::StatusAccepted;
const auto invalidStatus = NKikimrScheme::StatusSchemeError;
-
+
CreateWithIntermediateDirs([&](TTestActorRuntime& runtime, ui64 txId, const TString& root, bool valid) {
TestCreateSolomon(runtime, txId, root, valid ? validScheme : invalidScheme, {valid ? validStatus : invalidStatus});
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateDirWithIntermediateDirsForceDrop) {
CreateWithIntermediateDirsForceDrop([](TTestActorRuntime& runtime, ui64 txId, const TString& root) {
AsyncMkDir(runtime, txId, root, "x/y/z");
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateTableWithIntermediateDirsForceDrop) {
CreateWithIntermediateDirsForceDrop([](TTestActorRuntime& runtime, ui64 txId, const TString& root) {
AsyncCreateTable(runtime, txId, root, R"(
@@ -87,41 +87,41 @@ Y_UNIT_TEST_SUITE(IntermediateDirsReboots) {
Columns { Name: "RowId" Type: "Uint64" }
KeyColumnNames: ["RowId"]
)");
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateKesusWithIntermediateDirsForceDrop) {
CreateWithIntermediateDirsForceDrop([](TTestActorRuntime& runtime, ui64 txId, const TString& root) {
AsyncCreateKesus(runtime, txId, root, R"(
Name: "x/y/z"
)");
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateSolomonWithIntermediateDirsForceDrop) {
CreateWithIntermediateDirsForceDrop([](TTestActorRuntime& runtime, ui64 txId, const TString& root) {
AsyncCreateSolomon(runtime, txId, root, R"(
Name: "x/y/z"
PartitionCount: 2
)");
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateDirWithIntermediateDirsForceDropMiddle) {
- TTestWithReboots t;
- t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
+ TTestWithReboots t;
+ t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
AsyncMkDir(runtime, ++t.TxId, "/MyRoot", "x/y/z");
TestForceDropUnsafe(runtime, ++t.TxId, 4, TVector<NKikimrScheme::EStatus>{NKikimrScheme::StatusMultipleModifications});
t.TestEnv->TestWaitNotification(runtime, {t.TxId - 1, t.TxId});
-
+
{
TInactiveZone inactive(activeZone);
TestDescribeResult(DescribePath(runtime, "/MyRoot/x/y/z"),
{NLs::PathExist});
}
- });
- }
-
+ });
+ }
+
Y_UNIT_TEST(CreateSubDomainWithIntermediateDirs) {
const TString validScheme = R"(
Name: "Valid/x/y/z"
@@ -163,28 +163,28 @@ Y_UNIT_TEST_SUITE(IntermediateDirsReboots) {
Name: "x/y/z"
PartitionsCount: 0
)");
- });
- }
+ });
+ }
}
-
+
Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
Y_UNIT_TEST(Fake) {
}
Y_UNIT_TEST(CopyWithData) {
- TTestWithReboots t;
- t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
+ TTestWithReboots t;
+ t.Run([&](TTestActorRuntime& runtime, bool& activeZone) {
TPathVersion pathVersion;
{
TInactiveZone inactive(activeZone);
TestMkDir(runtime, ++t.TxId, "/MyRoot", "DirB");
TestCreateTable(runtime, ++t.TxId, "/MyRoot/DirB",
"Name: \"src1\""
- "Columns { Name: \"key1\" Type: \"Uint32\"}"
- "Columns { Name: \"key2\" Type: \"Utf8\"}"
- "Columns { Name: \"key3\" Type: \"Uint64\"}"
- "Columns { Name: \"Value\" Type: \"Utf8\"}"
- "KeyColumnNames: [\"key1\", \"key2\", \"key3\"]"
+ "Columns { Name: \"key1\" Type: \"Uint32\"}"
+ "Columns { Name: \"key2\" Type: \"Utf8\"}"
+ "Columns { Name: \"key3\" Type: \"Uint64\"}"
+ "Columns { Name: \"Value\" Type: \"Utf8\"}"
+ "KeyColumnNames: [\"key1\", \"key2\", \"key3\"]"
"UniformPartitionsCount: 1"
);
TestCreateTable(runtime, ++t.TxId, "/MyRoot/DirB",
@@ -197,7 +197,7 @@ Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
"UniformPartitionsCount: 1"
);
t.TestEnv->TestWaitNotification(runtime, {t.TxId-2, t.TxId-1, t.TxId});
-
+
// Write some data to the user table
auto fnWriteRow = [&] (ui64 tabletId) {
TString writeQuery = R"(
@@ -214,11 +214,11 @@ Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
UNIT_ASSERT_VALUES_EQUAL(status, NKikimrProto::EReplyStatus::OK);;
};
fnWriteRow(TTestTxConfig::FakeHiveTablets);
-
+
pathVersion = TestDescribeResult(DescribePath(runtime, "/MyRoot/DirB"),
{NLs::PathVersionEqual(7)});
- }
-
+ }
+
t.TestEnv->ReliablePropose(runtime, ConsistentCopyTablesRequest(++t.TxId, "/", R"(
CopyTableDescriptions {
SrcPath: "/MyRoot/DirB/src1"
@@ -230,8 +230,8 @@ Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
}
)", {pathVersion}),
{NKikimrScheme::StatusAccepted, NKikimrScheme::StatusMultipleModifications, NKikimrScheme::StatusPreconditionFailed});
- t.TestEnv->TestWaitNotification(runtime, t.TxId);
-
+ t.TestEnv->TestWaitNotification(runtime, t.TxId);
+
{
TInactiveZone inactive(activeZone);
TestDescribeResult(DescribePath(runtime, "/MyRoot/DirB"),
@@ -250,8 +250,8 @@ Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
{NLs::PathVersionEqual(3),
NLs::IsTable});
}
- });
- }
+ });
+ }
Y_UNIT_TEST(DropWithData) {
TTestWithReboots t;
@@ -654,7 +654,7 @@ Y_UNIT_TEST_SUITE(TConsistentOpsWithReboots) {
}
});
}
-}
+}
Y_UNIT_TEST_SUITE(TSolomonReboots) {
Y_UNIT_TEST(CreateDropSolomonWithReboots) {
diff --git a/ydb/core/tx/schemeshard/ut_reboots/ya.make b/ydb/core/tx/schemeshard/ut_reboots/ya.make
index 4c122ebe2f0..843709203ed 100644
--- a/ydb/core/tx/schemeshard/ut_reboots/ya.make
+++ b/ydb/core/tx/schemeshard/ut_reboots/ya.make
@@ -1,15 +1,15 @@
IF (NOT WITH_VALGRIND)
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
+
OWNER(
vvvv
g:kikimr
)
-
+
FORK_SUBTESTS()
SPLIT_FACTOR(60)
-
+
IF (SANITIZER_TYPE OR WITH_VALGRIND)
TIMEOUT(3600)
SIZE(LARGE)
@@ -19,7 +19,7 @@ IF (NOT WITH_VALGRIND)
SIZE(LARGE)
TAG(ya:fat)
ENDIF()
-
+
PEERDIR(
library/cpp/getopt
library/cpp/regex/pcre
diff --git a/ydb/core/tx/schemeshard/ut_rtmr.cpp b/ydb/core/tx/schemeshard/ut_rtmr.cpp
index 8ecff10e02a..03d0be17083 100644
--- a/ydb/core/tx/schemeshard/ut_rtmr.cpp
+++ b/ydb/core/tx/schemeshard/ut_rtmr.cpp
@@ -1,10 +1,10 @@
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
-
+
using namespace NKikimr::NSchemeShard;
-using namespace NKikimr;
+using namespace NKikimr;
using namespace NKikimrSchemeOp;
-using namespace NSchemeShardUT_Private;
-
+using namespace NSchemeShardUT_Private;
+
Y_UNIT_TEST_SUITE(TRtmrTest) {
Y_UNIT_TEST(CreataWithoutTimeCastBuckets) {
TTestBasicRuntime runtime;
diff --git a/ydb/core/tx/schemeshard/ut_rtmr/ya.make b/ydb/core/tx/schemeshard/ut_rtmr/ya.make
index 43ff241e878..d9a601559a9 100644
--- a/ydb/core/tx/schemeshard/ut_rtmr/ya.make
+++ b/ydb/core/tx/schemeshard/ut_rtmr/ya.make
@@ -1,22 +1,22 @@
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
+
OWNER(
vvvv
g:kikimr
)
-
-FORK_SUBTESTS()
+
+FORK_SUBTESTS()
IF (WITH_VALGRIND)
- TIMEOUT(3600)
- SIZE(LARGE)
+ TIMEOUT(3600)
+ SIZE(LARGE)
TAG(ya:fat)
-ELSE()
+ELSE()
TIMEOUT(600)
SIZE(MEDIUM)
-ENDIF()
-
-PEERDIR(
+ENDIF()
+
+PEERDIR(
library/cpp/getopt
library/cpp/regex/pcre
library/cpp/svnversion
@@ -24,12 +24,12 @@ PEERDIR(
ydb/core/tx
ydb/core/tx/schemeshard/ut_helpers
ydb/library/yql/public/udf/service/exception_policy
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-SRCS(
+SRCS(
ut_rtmr.cpp
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/tx/schemeshard/ut_split_merge/ya.make b/ydb/core/tx/schemeshard/ut_split_merge/ya.make
index df02fbd44f7..f7baa063f1f 100644
--- a/ydb/core/tx/schemeshard/ut_split_merge/ya.make
+++ b/ydb/core/tx/schemeshard/ut_split_merge/ya.make
@@ -1,12 +1,12 @@
IF (NOT WITH_VALGRIND)
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
+
OWNER(g:kikimr)
-
+
FORK_SUBTESTS()
SPLIT_FACTOR(20)
-
+
IF (SANITIZER_TYPE OR WITH_VALGRIND)
TIMEOUT(3600)
SIZE(LARGE)
@@ -15,7 +15,7 @@ IF (NOT WITH_VALGRIND)
TIMEOUT(600)
SIZE(MEDIUM)
ENDIF()
-
+
PEERDIR(
library/cpp/getopt
library/cpp/regex/pcre
diff --git a/ydb/core/tx/schemeshard/ut_subdomain/ya.make b/ydb/core/tx/schemeshard/ut_subdomain/ya.make
index aaa80b70904..5679626ca9d 100644
--- a/ydb/core/tx/schemeshard/ut_subdomain/ya.make
+++ b/ydb/core/tx/schemeshard/ut_subdomain/ya.make
@@ -1,24 +1,24 @@
UNITTEST_FOR(ydb/core/tx/schemeshard)
-
+
OWNER(
vvvv
g:kikimr
)
-
-FORK_SUBTESTS()
+
+FORK_SUBTESTS()
SPLIT_FACTOR(60)
-IF (SANITIZER_TYPE OR WITH_VALGRIND)
- TIMEOUT(3600)
- SIZE(LARGE)
+IF (SANITIZER_TYPE OR WITH_VALGRIND)
+ TIMEOUT(3600)
+ SIZE(LARGE)
TAG(ya:fat)
-ELSE()
+ELSE()
TIMEOUT(600)
SIZE(MEDIUM)
-ENDIF()
-
-PEERDIR(
+ENDIF()
+
+PEERDIR(
library/cpp/getopt
library/cpp/regex/pcre
library/cpp/svnversion
@@ -26,12 +26,12 @@ PEERDIR(
ydb/core/tx
ydb/core/tx/schemeshard/ut_helpers
ydb/library/yql/public/udf/service/exception_policy
-)
-
+)
+
YQL_LAST_ABI_VERSION()
-SRCS(
+SRCS(
ut_subdomain.cpp
-)
-
-END()
+)
+
+END()
diff --git a/ydb/core/tx/time_cast/time_cast.cpp b/ydb/core/tx/time_cast/time_cast.cpp
index 08042194fc5..f545c267a43 100644
--- a/ydb/core/tx/time_cast/time_cast.cpp
+++ b/ydb/core/tx/time_cast/time_cast.cpp
@@ -139,8 +139,8 @@ class TMediatorTimecastProxy : public TActor<TMediatorTimecastProxy> {
void Handle(TEvTabletPipe::TEvClientDestroyed::TPtr &ev, const TActorContext &ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_MEDIATOR_ACTOR;
}
TMediatorTimecastProxy()
diff --git a/ydb/core/tx/tx_allocator/txallocator_impl.h b/ydb/core/tx/tx_allocator/txallocator_impl.h
index 5a539f9b7bc..72737437b18 100644
--- a/ydb/core/tx/tx_allocator/txallocator_impl.h
+++ b/ydb/core/tx/tx_allocator/txallocator_impl.h
@@ -75,8 +75,8 @@ public:
};
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_ALLOCATOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_ALLOCATOR_ACTOR;
}
TTxAllocator(const TActorId &tablet, TTabletStorageInfo *info);
diff --git a/ydb/core/tx/tx_proxy/datareq.cpp b/ydb/core/tx/tx_proxy/datareq.cpp
index af48b42d60f..90a6b068833 100644
--- a/ydb/core/tx/tx_proxy/datareq.cpp
+++ b/ydb/core/tx/tx_proxy/datareq.cpp
@@ -448,8 +448,8 @@ private:
bool IsReadOnlyRequest() const;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_REQ_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_REQ_PROXY;
}
TDataReq(const TTxProxyServices &services, ui64 txid, const TIntrusivePtr<TTxProxyMon> mon,
diff --git a/ydb/core/tx/tx_proxy/describe.cpp b/ydb/core/tx/tx_proxy/describe.cpp
index deb38ca2b7d..6320dd63cf5 100644
--- a/ydb/core/tx/tx_proxy/describe.cpp
+++ b/ydb/core/tx/tx_proxy/describe.cpp
@@ -182,8 +182,8 @@ class TDescribeReq : public TActor<TDescribeReq> {
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr &ev, const TActorContext &ctx);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_PROXY_NAVIGATE;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_PROXY_NAVIGATE;
}
TDescribeReq(const TTxProxyServices &services, const TIntrusivePtr<TTxProxyMon>& txProxyMon)
diff --git a/ydb/core/tx/tx_proxy/proxy.h b/ydb/core/tx/tx_proxy/proxy.h
index 86d4f1ac79e..53244553003 100644
--- a/ydb/core/tx/tx_proxy/proxy.h
+++ b/ydb/core/tx/tx_proxy/proxy.h
@@ -169,7 +169,7 @@ struct TEvTxUserProxy {
}
};
- struct TEvInvalidateTableResult : public TEventSimple<TEvInvalidateTableResult, EvInvalidateTableResult> {};
+ struct TEvInvalidateTableResult : public TEventSimple<TEvInvalidateTableResult, EvInvalidateTableResult> {};
struct TEvProposeKqpTransaction : public TEventLocal<TEvProposeKqpTransaction, EvProposeKqpTransaction> {
TActorId ExecuterId;
diff --git a/ydb/core/tx/tx_proxy/proxy_impl.cpp b/ydb/core/tx/tx_proxy/proxy_impl.cpp
index 20dc8cce176..44c537a2a1a 100644
--- a/ydb/core/tx/tx_proxy/proxy_impl.cpp
+++ b/ydb/core/tx/tx_proxy/proxy_impl.cpp
@@ -453,8 +453,8 @@ public:
" Become StateWork");
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TX_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TX_PROXY_ACTOR;
}
STFUNC(StateWork) {
diff --git a/ydb/core/util/defs.h b/ydb/core/util/defs.h
index 77c876c9c13..b47d87de156 100644
--- a/ydb/core/util/defs.h
+++ b/ydb/core/util/defs.h
@@ -1,11 +1,11 @@
#pragma once
// unique tag to fix pragma once gcc glueing: ./ydb/core/util/defs.h
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/interconnect/interconnect_common.h>
-
+#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/hfunc.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/interconnect/interconnect_common.h>
+
#include <util/system/defaults.h>
#include <util/generic/bt_exception.h>
#include <util/generic/noncopyable.h>
diff --git a/ydb/core/util/failure_injection.cpp b/ydb/core/util/failure_injection.cpp
index 9eeaaa968ba..3e9e00e0639 100644
--- a/ydb/core/util/failure_injection.cpp
+++ b/ydb/core/util/failure_injection.cpp
@@ -1,4 +1,4 @@
-#include "failure_injection.h"
+#include "failure_injection.h"
#include <ydb/core/protos/services.pb.h>
#include <util/system/mutex.h>
#include <util/generic/queue.h>
@@ -7,302 +7,302 @@
#include <library/cpp/actors/core/event_local.h>
#include <library/cpp/actors/core/actor_bootstrapped.h>
#include <library/cpp/actors/core/log.h>
-
+
using namespace NActors;
-namespace NKikimr {
-
- using namespace NLWTrace;
-
- namespace {
-
- class TFailureInjectionManager {
- struct TFailureQueueItem {
+namespace NKikimr {
+
+ using namespace NLWTrace;
+
+ namespace {
+
+ class TFailureInjectionManager {
+ struct TFailureQueueItem {
TString Name;
- TMaybe<TParams> Params;
- ui32 HitCount;
- };
+ TMaybe<TParams> Params;
+ ui32 HitCount;
+ };
TDeque<TFailureQueueItem> FailureQ;
- TMutex Mutex;
- volatile bool Committed = false;
-
- public:
+ TMutex Mutex;
+ volatile bool Committed = false;
+
+ public:
void Inject(const TString& name, const TParams& params) {
- if (Committed) {
- with_lock (Mutex) {
- if (FailureQ) {
- TFailureQueueItem& item = FailureQ.front();
- if (item.Name == name && CompareParams(item.Params, params) && !--item.HitCount) {
- FailureQ.pop_front();
- if (FailureQ.empty()) {
- InjectFailure();
- }
- }
- }
- }
- }
- }
-
+ if (Committed) {
+ with_lock (Mutex) {
+ if (FailureQ) {
+ TFailureQueueItem& item = FailureQ.front();
+ if (item.Name == name && CompareParams(item.Params, params) && !--item.HitCount) {
+ FailureQ.pop_front();
+ if (FailureQ.empty()) {
+ InjectFailure();
+ }
+ }
+ }
+ }
+ }
+ }
+
void EnqueueFailureItem(const TString& name, const TMaybe<TParams>& params, ui32 hitCount = 1) {
- with_lock (Mutex) {
- FailureQ.push_back(TFailureQueueItem{name, params, hitCount});
- }
- }
-
- void Commit() {
- Committed = true;
- }
-
+ with_lock (Mutex) {
+ FailureQ.push_back(TFailureQueueItem{name, params, hitCount});
+ }
+ }
+
+ void Commit() {
+ Committed = true;
+ }
+
void DumpQueue(IOutputStream& str) {
HTML(str) {
TABLE() {
TABLEHEAD() {
TABLER() {
TABLEH() {
- str << "Probe name";
+ str << "Probe name";
}
TABLEH() {
- str << "Remaining hit count";
+ str << "Remaining hit count";
}
}
}
TABLEBODY() {
- with_lock (Mutex) {
- for (const TFailureQueueItem& item : FailureQ) {
+ with_lock (Mutex) {
+ for (const TFailureQueueItem& item : FailureQ) {
TABLER() {
TABLED() {
- str << item.Name;
+ str << item.Name;
}
TABLED() {
- str << item.HitCount;
+ str << item.HitCount;
}
}
- }
- }
+ }
+ }
}
}
}
- }
-
- private:
- static bool CompareParams(const TMaybe<TParams>& x, const TParams& /*y*/) {
- return !x || /* *x == y */ true; // FIXME: implement parameter comparison
- }
-
- void InjectFailure() {
- raise(SIGKILL);
- }
- };
-
- class TTraceActionExecutor : public TCustomActionExecutor {
- TFailureInjectionManager *Manager = nullptr;
+ }
+
+ private:
+ static bool CompareParams(const TMaybe<TParams>& x, const TParams& /*y*/) {
+ return !x || /* *x == y */ true; // FIXME: implement parameter comparison
+ }
+
+ void InjectFailure() {
+ raise(SIGKILL);
+ }
+ };
+
+ class TTraceActionExecutor : public TCustomActionExecutor {
+ TFailureInjectionManager *Manager = nullptr;
TString Name;
-
- public:
+
+ public:
TTraceActionExecutor(TProbe *probe, TFailureInjectionManager *manager, TString name)
- : TCustomActionExecutor(probe, true /*destructive*/)
- , Manager(manager)
- , Name(std::move(name))
- {}
-
- private:
+ : TCustomActionExecutor(probe, true /*destructive*/)
+ , Manager(manager)
+ , Name(std::move(name))
+ {}
+
+ private:
bool DoExecute(TOrbit&, const TParams& params) override {
- Manager->Inject(Name, params);
- return true;
- }
- };
-
- class TFailureInjectionActor : public TActorBootstrapped<TFailureInjectionActor> {
+ Manager->Inject(Name, params);
+ return true;
+ }
+ };
+
+ class TFailureInjectionActor : public TActorBootstrapped<TFailureInjectionActor> {
TManager TraceManager;
TVector<TString> Probes;
- TFailureInjectionManager Manager;
- bool Enabled = false;
-
- public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::BS_FAILURE_INJECTION;
- }
-
- TFailureInjectionActor()
- : TraceManager(*Singleton<TProbeRegistry>(), true)
- {}
-
- void Bootstrap(const TActorContext& /*ctx*/) {
- struct TCallback {
+ TFailureInjectionManager Manager;
+ bool Enabled = false;
+
+ public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::BS_FAILURE_INJECTION;
+ }
+
+ TFailureInjectionActor()
+ : TraceManager(*Singleton<TProbeRegistry>(), true)
+ {}
+
+ void Bootstrap(const TActorContext& /*ctx*/) {
+ struct TCallback {
TVector<TString>& Probes;
-
+
TCallback(TVector<TString>& probes)
- : Probes(probes)
- {}
-
- void Push(const TProbe *probe) {
- if (!strcmp(probe->Event.Groups[0], "FAIL_INJECTION_PROVIDER")) {
- Probes.push_back(probe->Event.Name);
- }
- }
- };
-
- TCallback callback(Probes);
- TraceManager.ReadProbes(callback);
-
- Become(&TFailureInjectionActor::StateFunc);
- }
-
- void Enable() {
- if (!Enabled) {
- TQuery query;
+ : Probes(probes)
+ {}
+
+ void Push(const TProbe *probe) {
+ if (!strcmp(probe->Event.Groups[0], "FAIL_INJECTION_PROVIDER")) {
+ Probes.push_back(probe->Event.Name);
+ }
+ }
+ };
+
+ TCallback callback(Probes);
+ TraceManager.ReadProbes(callback);
+
+ Become(&TFailureInjectionActor::StateFunc);
+ }
+
+ void Enable() {
+ if (!Enabled) {
+ TQuery query;
for (const TString& name : Probes) {
TString actionName = "FailureInjection_" + name;
-
- auto& block = *query.AddBlocks();
- auto& desc = *block.MutableProbeDesc();
- desc.SetName(name);
- desc.SetProvider("FAIL_INJECTION_PROVIDER");
- auto& action = *block.AddAction();
- auto& custom = *action.MutableCustomAction();
- custom.SetName(actionName);
-
+
+ auto& block = *query.AddBlocks();
+ auto& desc = *block.MutableProbeDesc();
+ desc.SetName(name);
+ desc.SetProvider("FAIL_INJECTION_PROVIDER");
+ auto& action = *block.AddAction();
+ auto& custom = *action.MutableCustomAction();
+ custom.SetName(actionName);
+
auto factory = [=](TProbe *probe, const TCustomAction& /*action*/, TSession* /*trace*/) {
- return new TTraceActionExecutor(probe, &Manager, name);
- };
- TraceManager.RegisterCustomAction(actionName, factory);
- }
-
- TraceManager.New("env", query);
- Manager.Commit();
- Enabled = true;
- }
- }
-
- void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
- ctx.Send(ev->Sender, new TEvents::TEvPoisonTaken);
- Die(ctx);
- }
-
- void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- TStringStream str;
-
+ return new TTraceActionExecutor(probe, &Manager, name);
+ };
+ TraceManager.RegisterCustomAction(actionName, factory);
+ }
+
+ TraceManager.New("env", query);
+ Manager.Commit();
+ Enabled = true;
+ }
+ }
+
+ void HandlePoison(TEvents::TEvPoisonPill::TPtr& ev, const TActorContext& ctx) {
+ ctx.Send(ev->Sender, new TEvents::TEvPoisonTaken);
+ Die(ctx);
+ }
+
+ void Handle(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
+ TStringStream str;
+
const auto& params = ev->Get()->Request.GetParams();
- if (params.Has("queue")) {
+ if (params.Has("queue")) {
TString queue = params.Get("queue");
- if (queue) {
- ProcessQueue(str, queue);
- }
- }
- if (params.Has("probe")) {
+ if (queue) {
+ ProcessQueue(str, queue);
+ }
+ }
+ if (params.Has("probe")) {
TString probe = params.Get("probe");
- if (probe) {
- try {
+ if (probe) {
+ try {
TString hc = params.Has("hitcount") ? params.Get("hitcount") : TString();
- ui32 hitCount = hc ? FromString<ui32>(hc) : 1;
- Manager.EnqueueFailureItem(probe, {}, hitCount);
- } catch (const yexception& ex) {
+ ui32 hitCount = hc ? FromString<ui32>(hc) : 1;
+ Manager.EnqueueFailureItem(probe, {}, hitCount);
+ } catch (const yexception& ex) {
HTML(str) {
DIV() {
- str << "<h1><font color=red>" << ex.what() << "</font></h1>";
+ str << "<h1><font color=red>" << ex.what() << "</font></h1>";
}
}
- }
- }
- }
- if (params.Has("enable")) {
- Enable();
- }
-
+ }
+ }
+ }
+ if (params.Has("enable")) {
+ Enable();
+ }
+
HTML(str) {
DIV() {
- Manager.DumpQueue(str);
+ Manager.DumpQueue(str);
}
-
+
FORM_CLASS("form-horizontal") {
DIV_CLASS("control-group") {
LABEL_CLASS_FOR("control-label", "probe") {
- str << "Probe";
+ str << "Probe";
}
DIV_CLASS("controls") {
- str << "<select id=\"probe\" name=\"probe\">";
+ str << "<select id=\"probe\" name=\"probe\">";
for (const TString& probe : Probes) {
- str << "<option value=\"" << probe << "\">" << probe << "</option>";
- }
- str << "</select>";
+ str << "<option value=\"" << probe << "\">" << probe << "</option>";
+ }
+ str << "</select>";
}
-
+
LABEL_CLASS_FOR("control-label", "hitcount") {
- str << "Hit count";
+ str << "Hit count";
}
DIV_CLASS("controls") {
- str << "<input type=\"number\" id=\"hitcount\" name=\"hitcount\">";
+ str << "<input type=\"number\" id=\"hitcount\" name=\"hitcount\">";
}
-
+
LABEL_CLASS_FOR("control-label", "queue") {
- str << "Queue definition string";
+ str << "Queue definition string";
}
DIV_CLASS("controls") {
- str << "<input id=\"queue\" name=\"queue\">";
+ str << "<input id=\"queue\" name=\"queue\">";
}
}
DIV_CLASS("control-group") {
DIV_CLASS("controls") {
- str << "<button type=\"submit\" name=\"submit\" class=\"btn btn-default\">Add to queue</button>";
+ str << "<button type=\"submit\" name=\"submit\" class=\"btn btn-default\">Add to queue</button>";
}
}
}
}
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
- }
-
+ ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str(), ev->Get()->SubRequestId));
+ }
+
void ProcessQueue(IOutputStream& str, const TString& queue) {
TVector<std::tuple<TString, TMaybe<TParams>, ui32>> items;
-
+
HTML(str) {
- size_t pos = 0;
- for (;;) {
+ size_t pos = 0;
+ for (;;) {
TString probe;
- for (; pos < queue.size() && queue[pos] != ';' && queue[pos] != '#'; ++pos) {
- probe.append(queue[pos]);
- }
- if (std::find(Probes.begin(), Probes.end(), probe) == Probes.end()) {
+ for (; pos < queue.size() && queue[pos] != ';' && queue[pos] != '#'; ++pos) {
+ probe.append(queue[pos]);
+ }
+ if (std::find(Probes.begin(), Probes.end(), probe) == Probes.end()) {
DIV() {
- str << "<h1><font color=red>Probe " << probe << " does not exist</font></h1>";
+ str << "<h1><font color=red>Probe " << probe << " does not exist</font></h1>";
}
- return;
- }
- ui32 hitCount = 1;
- if (pos < queue.size() && queue[pos] == '#') {
- for (++pos, hitCount = 0; pos < queue.size() && isdigit(queue[pos]); ++pos) {
- hitCount = hitCount * 10 + (queue[pos] - '0');
- }
- }
- if (pos < queue.size() && queue[pos] != ';') {
+ return;
+ }
+ ui32 hitCount = 1;
+ if (pos < queue.size() && queue[pos] == '#') {
+ for (++pos, hitCount = 0; pos < queue.size() && isdigit(queue[pos]); ++pos) {
+ hitCount = hitCount * 10 + (queue[pos] - '0');
+ }
+ }
+ if (pos < queue.size() && queue[pos] != ';') {
DIV() {
- str << "<h1><font color=red>Missing semicolon</font></h1>";
+ str << "<h1><font color=red>Missing semicolon</font></h1>";
}
- return;
- }
+ return;
+ }
items.emplace_back(std::move(probe), Nothing(), hitCount);
- if (pos < queue.size()) {
- ++pos;
- } else {
- break;
- }
- }
- }
-
- for (const auto& item : items) {
- Manager.EnqueueFailureItem(std::get<0>(item), std::get<1>(item), std::get<2>(item));
+ if (pos < queue.size()) {
+ ++pos;
+ } else {
+ break;
+ }
+ }
}
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvPoisonPill, HandlePoison)
- HFunc(NMon::TEvHttpInfo, Handle)
- )
- };
-
- } // anon
-
- IActor *CreateFailureInjectionActor() {
- return new TFailureInjectionActor();
- }
-
-} // NKikimr
+
+ for (const auto& item : items) {
+ Manager.EnqueueFailureItem(std::get<0>(item), std::get<1>(item), std::get<2>(item));
+ }
+ }
+
+ STRICT_STFUNC(StateFunc,
+ HFunc(TEvents::TEvPoisonPill, HandlePoison)
+ HFunc(NMon::TEvHttpInfo, Handle)
+ )
+ };
+
+ } // anon
+
+ IActor *CreateFailureInjectionActor() {
+ return new TFailureInjectionActor();
+ }
+
+} // NKikimr
diff --git a/ydb/core/util/failure_injection.h b/ydb/core/util/failure_injection.h
index 65d3397d534..6d000cc7ca1 100644
--- a/ydb/core/util/failure_injection.h
+++ b/ydb/core/util/failure_injection.h
@@ -1,10 +1,10 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <library/cpp/actors/core/actor.h>
-
-namespace NKikimr {
-
+
+namespace NKikimr {
+
NActors::IActor *CreateFailureInjectionActor();
-
-} // NKikimr
+
+} // NKikimr
diff --git a/ydb/core/util/format.cpp b/ydb/core/util/format.cpp
index b22338fef3a..3e6753dea1f 100644
--- a/ydb/core/util/format.cpp
+++ b/ydb/core/util/format.cpp
@@ -1,53 +1,53 @@
-#include "format.h"
-#include <cstdlib>
-
-namespace NKikimr {
-
- void FormatHumanReadable(IOutputStream& out, ui64 number, ui32 base, unsigned fracw, const char *suffixes[]) {
- Y_VERIFY(suffixes[0]);
-
- ui64 exp = 1;
- ui64 top = base;
- while (suffixes[1] && number >= top) {
- ++suffixes;
- exp = top;
- top *= base;
- }
-
- const auto& d = std::lldiv(number, exp);
- static ui64 fparts[] = {0, 10, 100, 1000, 10000, 100000, 1000000};
- fracw = exp != 1 ? std::min<unsigned>(fracw, std::size(fparts) - 1) : 0;
- const ui64 frac = fparts[fracw] * d.rem / exp;
-
- char num[32];
- int numLen = snprintf(num, sizeof(num), "%lld", d.quot);
- const char *in = num + numLen;
-
- char res[128];
- const int numSpaces = (numLen - 1) / 3;
- char *end = res + numLen + numSpaces;
- {
- char *out = end;
- int r = 0;
- while (numLen--) {
- *--out = *--in;
- if (++r == 3 && numLen) {
- *--out = ' ';
- r = 0;
- }
- }
- Y_VERIFY(out == res);
- }
-
- if (fracw) {
- end += snprintf(end, sizeof(res) - (end - res), ".%0*" PRIu64, fracw, frac);
- }
-
- if (**suffixes) {
- end += snprintf(end, sizeof(res) - (end - res), " %s", *suffixes);
- }
-
- out << TStringBuf(res, end);
- }
-
-} // NKikimr
+#include "format.h"
+#include <cstdlib>
+
+namespace NKikimr {
+
+ void FormatHumanReadable(IOutputStream& out, ui64 number, ui32 base, unsigned fracw, const char *suffixes[]) {
+ Y_VERIFY(suffixes[0]);
+
+ ui64 exp = 1;
+ ui64 top = base;
+ while (suffixes[1] && number >= top) {
+ ++suffixes;
+ exp = top;
+ top *= base;
+ }
+
+ const auto& d = std::lldiv(number, exp);
+ static ui64 fparts[] = {0, 10, 100, 1000, 10000, 100000, 1000000};
+ fracw = exp != 1 ? std::min<unsigned>(fracw, std::size(fparts) - 1) : 0;
+ const ui64 frac = fparts[fracw] * d.rem / exp;
+
+ char num[32];
+ int numLen = snprintf(num, sizeof(num), "%lld", d.quot);
+ const char *in = num + numLen;
+
+ char res[128];
+ const int numSpaces = (numLen - 1) / 3;
+ char *end = res + numLen + numSpaces;
+ {
+ char *out = end;
+ int r = 0;
+ while (numLen--) {
+ *--out = *--in;
+ if (++r == 3 && numLen) {
+ *--out = ' ';
+ r = 0;
+ }
+ }
+ Y_VERIFY(out == res);
+ }
+
+ if (fracw) {
+ end += snprintf(end, sizeof(res) - (end - res), ".%0*" PRIu64, fracw, frac);
+ }
+
+ if (**suffixes) {
+ end += snprintf(end, sizeof(res) - (end - res), " %s", *suffixes);
+ }
+
+ out << TStringBuf(res, end);
+ }
+
+} // NKikimr
diff --git a/ydb/core/util/format.h b/ydb/core/util/format.h
index 872a8dd05f4..024e0e4ad7d 100644
--- a/ydb/core/util/format.h
+++ b/ydb/core/util/format.h
@@ -1,9 +1,9 @@
-#pragma once
-
-#include <util/stream/output.h>
-
-namespace NKikimr {
-
- void FormatHumanReadable(IOutputStream& out, ui64 number, ui32 base, unsigned fracw /*0...6*/, const char *suffixes[]);
-
-} // NKikimr
+#pragma once
+
+#include <util/stream/output.h>
+
+namespace NKikimr {
+
+ void FormatHumanReadable(IOutputStream& out, ui64 number, ui32 base, unsigned fracw /*0...6*/, const char *suffixes[]);
+
+} // NKikimr
diff --git a/ydb/core/util/fragmented_buffer.cpp b/ydb/core/util/fragmented_buffer.cpp
index 6da04399b60..9c86ee097f5 100644
--- a/ydb/core/util/fragmented_buffer.cpp
+++ b/ydb/core/util/fragmented_buffer.cpp
@@ -23,7 +23,7 @@ TString TFragmentedBuffer::GetMonolith() {
}
void TFragmentedBuffer::SetMonolith(TString &data) {
- Y_VERIFY(data);
+ Y_VERIFY(data);
BufferForOffset.clear();
BufferForOffset.emplace(0, data);
}
@@ -120,26 +120,26 @@ TString TFragmentedBuffer::Print() const {
}
std::pair<const char*, i32> TFragmentedBuffer::Get(i32 begin) const {
- auto it = BufferForOffset.upper_bound(begin);
- Y_VERIFY(it != BufferForOffset.begin());
- --it;
+ auto it = BufferForOffset.upper_bound(begin);
+ Y_VERIFY(it != BufferForOffset.begin());
+ --it;
const i32 offset = begin - it->first;
- Y_VERIFY(offset >= 0 && (size_t)offset < it->second.size());
- return std::make_pair(it->second.data() + offset, it->second.size() - offset);
-}
-
+ Y_VERIFY(offset >= 0 && (size_t)offset < it->second.size());
+ return std::make_pair(it->second.data() + offset, it->second.size() - offset);
+}
+
void TFragmentedBuffer::CopyFrom(const TFragmentedBuffer& from, const TIntervalSet<i32>& range) {
- Y_VERIFY(range);
+ Y_VERIFY(range);
for (auto it = range.begin(); it != range.end(); ++it) {
auto [begin, end] = *it;
i32 offset = begin;
- while (offset < end) {
- const auto& [data, maxLen] = from.Get(offset);
+ while (offset < end) {
+ const auto& [data, maxLen] = from.Get(offset);
i32 len = Min(maxLen, end - offset);
- Write(offset, data, len);
- offset += len;
- }
- }
-}
-
+ Write(offset, data, len);
+ offset += len;
+ }
+ }
+}
+
} // NKikimr
diff --git a/ydb/core/util/fragmented_buffer.h b/ydb/core/util/fragmented_buffer.h
index 0e7ce9f8425..af8b0644ae3 100644
--- a/ydb/core/util/fragmented_buffer.h
+++ b/ydb/core/util/fragmented_buffer.h
@@ -2,7 +2,7 @@
#include "defs.h"
#include <util/generic/map.h>
-#include "interval_set.h"
+#include "interval_set.h"
namespace NKikimr {
@@ -20,21 +20,21 @@ public:
void Write(i32 begin, const char* buffer, i32 size);
void Read(i32 begin, char* buffer, i32 size) const;
TString Print() const;
-
+
std::pair<const char*, i32> Get(i32 begin) const;
void CopyFrom(const TFragmentedBuffer& from, const TIntervalSet<i32>& range);
-
- explicit operator bool() const {
- return !BufferForOffset.empty();
- }
-
- size_t GetTotalSize() const {
- size_t res = 0;
- for (const auto& [offset, buffer] : BufferForOffset) {
- res += buffer.size();
- }
- return res;
- }
+
+ explicit operator bool() const {
+ return !BufferForOffset.empty();
+ }
+
+ size_t GetTotalSize() const {
+ size_t res = 0;
+ for (const auto& [offset, buffer] : BufferForOffset) {
+ res += buffer.size();
+ }
+ return res;
+ }
};
} // NKikimr
diff --git a/ydb/core/util/fragmented_buffer_ut.cpp b/ydb/core/util/fragmented_buffer_ut.cpp
index 7e7dee86df5..126d3cce436 100644
--- a/ydb/core/util/fragmented_buffer_ut.cpp
+++ b/ydb/core/util/fragmented_buffer_ut.cpp
@@ -159,27 +159,27 @@ Y_UNIT_TEST_SUITE(TFragmentedBufferTest) {
TString res = fb.GetMonolith();
UNIT_ASSERT_VALUES_EQUAL(inData, res);
}
-
- Y_UNIT_TEST(CopyFrom) {
+
+ Y_UNIT_TEST(CopyFrom) {
TFragmentedBuffer buffer;
buffer.Write(0, "HELLO", 5);
buffer.Write(10, "WORLD", 5);
- TFragmentedBuffer copy;
+ TFragmentedBuffer copy;
copy.CopyFrom(buffer, TIntervalSet<i32>(0, 5));
buffer.Write(5, "BRAVE", 5);
copy.CopyFrom(buffer, TIntervalSet<i32>(5, 15));
- UNIT_ASSERT(copy.Get(0).second == 5);
- UNIT_ASSERT(!memcmp(copy.Get(0).first, "HELLO", 5));
- UNIT_ASSERT(copy.Get(10).second == 5);
- UNIT_ASSERT(!memcmp(copy.Get(10).first, "WORLD", 5));
- UNIT_ASSERT(copy.Get(12).second == 3);
- UNIT_ASSERT(!memcmp(copy.Get(12).first, "RLD", 3));
+ UNIT_ASSERT(copy.Get(0).second == 5);
+ UNIT_ASSERT(!memcmp(copy.Get(0).first, "HELLO", 5));
+ UNIT_ASSERT(copy.Get(10).second == 5);
+ UNIT_ASSERT(!memcmp(copy.Get(10).first, "WORLD", 5));
+ UNIT_ASSERT(copy.Get(12).second == 3);
+ UNIT_ASSERT(!memcmp(copy.Get(12).first, "RLD", 3));
copy.CopyFrom(buffer, TIntervalSet<i32>(0, 15));
- UNIT_ASSERT(copy.Get(0).second == 5);
- UNIT_ASSERT(!memcmp(copy.Get(0).first, "HELLO", 5));
- UNIT_ASSERT(copy.Get(5).second == 5);
- UNIT_ASSERT(!memcmp(copy.Get(5).first, "BRAVE", 5));
- }
+ UNIT_ASSERT(copy.Get(0).second == 5);
+ UNIT_ASSERT(!memcmp(copy.Get(0).first, "HELLO", 5));
+ UNIT_ASSERT(copy.Get(5).second == 5);
+ UNIT_ASSERT(!memcmp(copy.Get(5).first, "BRAVE", 5));
+ }
}
} // NKikimr
diff --git a/ydb/core/util/interval_set.h b/ydb/core/util/interval_set.h
index 68f6ea66589..9ca70106ad0 100644
--- a/ydb/core/util/interval_set.h
+++ b/ydb/core/util/interval_set.h
@@ -12,7 +12,7 @@
namespace NKikimr {
//
-// A set of non-intersecting non-adjoint non-empty intervals in form [begin, end) (end > begin)
+// A set of non-intersecting non-adjoint non-empty intervals in form [begin, end) (end > begin)
//
template <class T> struct TIntervalMap; // implemented as TMap
template <class T> struct TIntervalVec; // implemented as sorted TStackVec
@@ -33,10 +33,10 @@ struct TIntervalMap {
Y_VERIFY_DEBUG_S(begin < end, "begin# " << begin << " end# " << end);
EndForBegin[begin] = end;
}
-
+
TIntervalMap& operator=(const TIntervalMap<T>&) = default;
TIntervalMap& operator=(TIntervalMap<T>&&) = default;
-
+
void Add(const TIntervalMap<T>& b) {
*this |= b;
}
@@ -161,12 +161,12 @@ struct TIntervalMap {
}
}
return true;
- }
-
- explicit operator bool() const {
- return !IsEmpty();
- }
-
+ }
+
+ explicit operator bool() const {
+ return !IsEmpty();
+ }
+
template <class Y>
TIntervalMap<T> operator |(const Y& y) const {
TIntervalMap<T> res;
diff --git a/ydb/core/util/interval_set_ut.cpp b/ydb/core/util/interval_set_ut.cpp
index c1df7015fd1..4128e1c4495 100644
--- a/ydb/core/util/interval_set_ut.cpp
+++ b/ydb/core/util/interval_set_ut.cpp
@@ -136,20 +136,20 @@ public:
template <class TIntervals>
TIntervals MakeIntervalSet(ui64 n, ui32 len) {
TIntervals res;
- for (ui32 i = 0; i < len; ) {
- if (n >> i & 1) {
- const ui32 begin = i;
- while (i < len && n >> i & 1) {
- ++i;
- }
- res.Add(begin, i);
- } else {
- ++i;
- }
- }
- return res;
-}
-
+ for (ui32 i = 0; i < len; ) {
+ if (n >> i & 1) {
+ const ui32 begin = i;
+ while (i < len && n >> i & 1) {
+ ++i;
+ }
+ res.Add(begin, i);
+ } else {
+ ++i;
+ }
+ }
+ return res;
+}
+
#define MY_UNIT_TEST(N) \
template <class TIntervals, const char* TestName> \
struct TTestCase##N : public TCurrentTestCase { \
@@ -601,117 +601,117 @@ Y_UNIT_TEST_SUITE(TIntervalSetTest) {
}
MY_UNIT_TEST(Union) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
- for (ui64 j = 0; j < n; ++j) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
+ for (ui64 j = 0; j < n; ++j) {
const TIntervals a = MakeIntervalSet<TIntervals>(i, len);
const TIntervals b = MakeIntervalSet<TIntervals>(j, len);
const TIntervals res = a | b;
const TIntervals reference = MakeIntervalSet<TIntervals>(i | j, len);
- UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
- << res.ToString() << " reference# " << reference.ToString());
- }
- }
- }
-
+ UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
+ << res.ToString() << " reference# " << reference.ToString());
+ }
+ }
+ }
+
MY_UNIT_TEST(UnionInplace) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
- for (ui64 j = 0; j < n; ++j) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
+ for (ui64 j = 0; j < n; ++j) {
const TIntervals a = MakeIntervalSet<TIntervals>(i, len);
const TIntervals b = MakeIntervalSet<TIntervals>(j, len);
TIntervals res = a;
- res |= b;
+ res |= b;
const TIntervals reference = MakeIntervalSet<TIntervals>(i | j, len);
- UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
- << res.ToString() << " reference# " << reference.ToString());
- }
- }
- }
-
+ UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
+ << res.ToString() << " reference# " << reference.ToString());
+ }
+ }
+ }
+
MY_UNIT_TEST(UnionInplaceSelf) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
TIntervals res = MakeIntervalSet<TIntervals>(i, len);
TIntervals *other = &res;
- res |= *other;
+ res |= *other;
const TIntervals reference = MakeIntervalSet<TIntervals>(i, len);
- UNIT_ASSERT_EQUAL(res, reference);
- }
- }
-
+ UNIT_ASSERT_EQUAL(res, reference);
+ }
+ }
+
MY_UNIT_TEST(Intersection) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
- for (ui64 j = 0; j < n; ++j) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
+ for (ui64 j = 0; j < n; ++j) {
const TIntervals a = MakeIntervalSet<TIntervals>(i, len);
const TIntervals b = MakeIntervalSet<TIntervals>(j, len);
const TIntervals res = a & b;
const TIntervals reference = MakeIntervalSet<TIntervals>(i & j, len);
- UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
- << res.ToString() << " reference# " << reference.ToString());
- }
- }
- }
-
+ UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
+ << res.ToString() << " reference# " << reference.ToString());
+ }
+ }
+ }
+
MY_UNIT_TEST(IntersectionInplace) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
- for (ui64 j = 0; j < n; ++j) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
+ for (ui64 j = 0; j < n; ++j) {
const TIntervals a = MakeIntervalSet<TIntervals>(i, len);
const TIntervals b = MakeIntervalSet<TIntervals>(j, len);
TIntervals res = a;
- res &= b;
+ res &= b;
const TIntervals reference = MakeIntervalSet<TIntervals>(i & j, len);
- UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
- << res.ToString() << " reference# " << reference.ToString());
- }
- }
- }
-
+ UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
+ << res.ToString() << " reference# " << reference.ToString());
+ }
+ }
+ }
+
MY_UNIT_TEST(IntersectionInplaceSelf) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
TIntervals res = MakeIntervalSet<TIntervals>(i, len);
TIntervals *other = &res;
- res &= *other;
+ res &= *other;
const TIntervals reference = MakeIntervalSet<TIntervals>(i, len);
- UNIT_ASSERT_EQUAL(res, reference);
- }
- }
-
+ UNIT_ASSERT_EQUAL(res, reference);
+ }
+ }
+
MY_UNIT_TEST(Difference) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
- for (ui64 j = 0; j < n; ++j) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
+ for (ui64 j = 0; j < n; ++j) {
const TIntervals a = MakeIntervalSet<TIntervals>(i, len);
const TIntervals b = MakeIntervalSet<TIntervals>(j, len);
const TIntervals res = a - b;
const TIntervals reference = MakeIntervalSet<TIntervals>(i & ~j, len);
- UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
- << res.ToString() << " reference# " << reference.ToString());
- }
- }
- }
-
+ UNIT_ASSERT_EQUAL_C(res, reference, "a# " << a.ToString() << " b# " << b.ToString() << " res# "
+ << res.ToString() << " reference# " << reference.ToString());
+ }
+ }
+ }
+
MY_UNIT_TEST(DifferenceInplaceSelf) {
- ui32 len = 8;
- ui64 n = 1 << len;
- for (ui64 i = 0; i < n; ++i) {
+ ui32 len = 8;
+ ui64 n = 1 << len;
+ for (ui64 i = 0; i < n; ++i) {
TIntervals res = MakeIntervalSet<TIntervals>(i, len);
TIntervals *other = &res;
- res -= *other;
- UNIT_ASSERT(!res);
- }
- }
-
+ res -= *other;
+ UNIT_ASSERT(!res);
+ }
+ }
+
Y_UNIT_TEST(IntervalSetTestIterator) {
using TIntervals = TIntervalSet<i32>;
for (ui64 aBits = 0; aBits < 128; ++aBits) {
diff --git a/ydb/core/util/iterator.h b/ydb/core/util/iterator.h
index 63f03f0fa42..810f68db421 100644
--- a/ydb/core/util/iterator.h
+++ b/ydb/core/util/iterator.h
@@ -1,58 +1,58 @@
-#pragma once
-
-#include "defs.h"
-
+#pragma once
+
+#include "defs.h"
+
#include <util/generic/iterator_range.h>
-template<typename TDerived, typename TValue, typename TReference = TValue&, typename TDifference = ptrdiff_t>
-struct TIteratorFacade {
- TReference operator *() const {
- return static_cast<const TDerived&>(*this).Dereference();
- }
-
- TValue *operator ->() const {
- return &**this;
- }
-
- TDerived& operator ++() {
- TDerived& der = static_cast<TDerived&>(*this);
- der.MoveNext();
- return der;
- }
-
- TDerived operator++(int) {
- TDerived& der = static_cast<TDerived&>(*this);
- TDerived ret(der);
- der.MoveNext();
- return ret;
- }
-
- TDerived& operator --() {
- TDerived& der = static_cast<TDerived&>(*this);
- der.MovePrev();
- return der;
- }
-
- TDerived operator --(int) {
- TDerived& der = static_cast<TDerived&>(*this);
- TDerived ret(der);
- der.MovePrev();
- return ret;
- }
-
- TDifference operator -(const TIteratorFacade& other) const {
- return static_cast<const TDerived&>(other).DistanceTo(static_cast<const TDerived&>(*this));
- }
-
- template<typename T>
- bool operator ==(const T& other) const {
- const TDerived& der = static_cast<const TDerived&>(*this);
- return der.EqualTo(other);
- }
-
- template<typename T>
- bool operator !=(const T& other) const {
- return !operator ==(other);
- }
-};
-
+template<typename TDerived, typename TValue, typename TReference = TValue&, typename TDifference = ptrdiff_t>
+struct TIteratorFacade {
+ TReference operator *() const {
+ return static_cast<const TDerived&>(*this).Dereference();
+ }
+
+ TValue *operator ->() const {
+ return &**this;
+ }
+
+ TDerived& operator ++() {
+ TDerived& der = static_cast<TDerived&>(*this);
+ der.MoveNext();
+ return der;
+ }
+
+ TDerived operator++(int) {
+ TDerived& der = static_cast<TDerived&>(*this);
+ TDerived ret(der);
+ der.MoveNext();
+ return ret;
+ }
+
+ TDerived& operator --() {
+ TDerived& der = static_cast<TDerived&>(*this);
+ der.MovePrev();
+ return der;
+ }
+
+ TDerived operator --(int) {
+ TDerived& der = static_cast<TDerived&>(*this);
+ TDerived ret(der);
+ der.MovePrev();
+ return ret;
+ }
+
+ TDifference operator -(const TIteratorFacade& other) const {
+ return static_cast<const TDerived&>(other).DistanceTo(static_cast<const TDerived&>(*this));
+ }
+
+ template<typename T>
+ bool operator ==(const T& other) const {
+ const TDerived& der = static_cast<const TDerived&>(*this);
+ return der.EqualTo(other);
+ }
+
+ template<typename T>
+ bool operator !=(const T& other) const {
+ return !operator ==(other);
+ }
+};
+
diff --git a/ydb/core/util/lz4_data_generator.h b/ydb/core/util/lz4_data_generator.h
index d0fbdfe602e..7a6806a0770 100644
--- a/ydb/core/util/lz4_data_generator.h
+++ b/ydb/core/util/lz4_data_generator.h
@@ -1,5 +1,5 @@
#include <util/generic/string.h>
-#include <util/random/fast.h>
+#include <util/random/fast.h>
#include <contrib/libs/lz4/lz4.h>
@@ -16,23 +16,23 @@ inline TString GenDataForLZ4(const ui64 size, const ui64 seed = 0) {
return data;
}
-inline TString FastGenDataForLZ4(i64 size, ui64 seed) {
- TString data = TString::Uninitialized(size);
-
- TReallyFastRng32 rng(seed);
-
- constexpr size_t minRunLen = 32;
- constexpr size_t maxRunLen = 64;
- const size_t runLen = minRunLen + rng() % (maxRunLen - minRunLen + 1);
-
- char run[maxRunLen];
- std::generate(run, run + runLen, rng);
-
- for (char *ptr = data.Detach(); size > 0; ptr += runLen, size -= runLen) {
- memcpy(ptr, run, Min<size_t>(size, runLen));
- }
-
- return data;
-}
-
+inline TString FastGenDataForLZ4(i64 size, ui64 seed) {
+ TString data = TString::Uninitialized(size);
+
+ TReallyFastRng32 rng(seed);
+
+ constexpr size_t minRunLen = 32;
+ constexpr size_t maxRunLen = 64;
+ const size_t runLen = minRunLen + rng() % (maxRunLen - minRunLen + 1);
+
+ char run[maxRunLen];
+ std::generate(run, run + runLen, rng);
+
+ for (char *ptr = data.Detach(); size > 0; ptr += runLen, size -= runLen) {
+ memcpy(ptr, run, Min<size_t>(size, runLen));
+ }
+
+ return data;
}
+
+}
diff --git a/ydb/core/util/pb.h b/ydb/core/util/pb.h
index 81bf964f214..d0cc2a2b5db 100644
--- a/ydb/core/util/pb.h
+++ b/ydb/core/util/pb.h
@@ -52,13 +52,13 @@ bool MergeFromStringNoSizeLimit(TProto& proto, TArrayRef<const char> str) {
return proto.MergeFromCodedStream(&input) && input.ConsumedEntireMessage();
}
-inline TString SingleLineProto(const NProtoBuf::Message& message) {
- NProtoBuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString res;
- const bool success = p.PrintToString(message, &res);
- Y_VERIFY(success);
- return res;
-}
-
+inline TString SingleLineProto(const NProtoBuf::Message& message) {
+ NProtoBuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString res;
+ const bool success = p.PrintToString(message, &res);
+ Y_VERIFY(success);
+ return res;
}
+
+}
diff --git a/ydb/core/util/queue_inplace.h b/ydb/core/util/queue_inplace.h
index e0a5803e1e7..1b1ecda5880 100644
--- a/ydb/core/util/queue_inplace.h
+++ b/ydb/core/util/queue_inplace.h
@@ -54,10 +54,10 @@ public:
}
delete x;
}
-
- void operator ()(TQueueInplace<T, TSize> *x) const noexcept {
- Destroy(x);
- }
+
+ void operator ()(TQueueInplace<T, TSize> *x) const noexcept {
+ Destroy(x);
+ }
};
void Push(const T &x) noexcept {
@@ -75,19 +75,19 @@ public:
}
void Push(T &&x) noexcept {
- ++Size;
- if (WritePosition != TChunk::EntriesCount) {
- WriteTo->Entries[WritePosition] = std::move(x);
- ++WritePosition;
- } else {
- TChunk *next = new TChunk();
- next->Entries[0] = std::move(x);
- WriteTo->Next = next;
- WriteTo = next;
- WritePosition = 1;
- }
- }
-
+ ++Size;
+ if (WritePosition != TChunk::EntriesCount) {
+ WriteTo->Entries[WritePosition] = std::move(x);
+ ++WritePosition;
+ } else {
+ TChunk *next = new TChunk();
+ next->Entries[0] = std::move(x);
+ WriteTo->Next = next;
+ WriteTo = next;
+ WritePosition = 1;
+ }
+ }
+
T *Head() {
TChunk *head = ReadFrom;
if (ReadFrom == WriteTo && ReadPosition == WritePosition) {
diff --git a/ydb/core/util/single_thread_ic_mock.cpp b/ydb/core/util/single_thread_ic_mock.cpp
index ec5542adc72..5ddbb789125 100644
--- a/ydb/core/util/single_thread_ic_mock.cpp
+++ b/ydb/core/util/single_thread_ic_mock.cpp
@@ -1,452 +1,452 @@
-#include "single_thread_ic_mock.h"
-#include "testactorsys.h"
-#include "stlog.h"
-
-using namespace NActors;
-using namespace NKikimr;
-
-using TMock = TSingleThreadInterconnectMock;
-
-struct TMock::TNode {
- const ui32 NodeId;
- const ui64 BurstCapacityBytes;
- const ui64 BytesPerSecond;
- TInstant NextActionTimestamp;
-
- TNode(ui32 nodeId, ui64 burstCapacityBytes, ui64 bytesPerSecond)
- : NodeId(nodeId)
- , BurstCapacityBytes(burstCapacityBytes)
- , BytesPerSecond(bytesPerSecond)
- {}
-
- TInstant Enqueue(ui64 size, TInstant clock) {
- if (BytesPerSecond == Max<ui64>()) {
- return clock;
- }
- NextActionTimestamp = Max(clock - TDuration::MicroSeconds(BurstCapacityBytes * 1'000'000 / BytesPerSecond),
- NextActionTimestamp) + TDuration::MicroSeconds((size * 1'000'000 + BytesPerSecond - 1) / BytesPerSecond);
- return Max(NextActionTimestamp, clock);
- }
-};
-
-class TMock::TProxyActor : public TActor<TProxyActor> {
- friend class TSessionActor;
-
- const TString Prefix;
- TMock* const Mock;
- std::shared_ptr<TNode> Node;
- TProxyActor *Peer;
- const ui32 PeerNodeId;
- TIntrusivePtr<TInterconnectProxyCommon> Common;
- TSessionActor *SessionActor = nullptr;
- bool Working = false;
- std::deque<std::unique_ptr<IEventHandle>> PendingEvents;
- ui64 DropPendingEventsCookie = 0;
-
- enum {
- EvDropPendingEvents = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
-public:
- TProxyActor(TMock *mock, std::shared_ptr<TNode> node, TProxyActor *peer, ui32 peerNodeId,
- TIntrusivePtr<TInterconnectProxyCommon> common)
- : TActor(&TThis::StateFunc)
- , Prefix(TStringBuilder() << "Proxy[" << node->NodeId << ":" << peerNodeId << "] ")
- , Mock(mock)
- , Node(std::move(node))
- , Peer(peer)
- , PeerNodeId(peerNodeId)
- , Common(std::move(common))
- {
- if (Peer) {
- Peer->Peer = this;
- }
- }
-
- ~TProxyActor();
-
- void Registered(TActorSystem *as, const TActorId& parent) override {
- TActor::Registered(as, parent);
- Working = true;
- if (Peer && Peer->Working) {
- ProcessPendingEvents();
- Peer->ProcessPendingEvents();
- }
- }
-
- TSessionActor *GetSession() {
- if (!SessionActor && Working && Peer && Peer->Working) {
- Y_VERIFY(PendingEvents.empty());
- Y_VERIFY(Peer->PendingEvents.empty());
- CreateSession();
- Peer->CreateSession();
- }
- return SessionActor;
- }
-
- void CreateSession();
- void ForwardToSession(TAutoPtr<IEventHandle> ev);
-
- void DropSessionEvent(std::unique_ptr<IEventHandle> ev);
- void HandleDropPendingEvents(TAutoPtr<IEventHandle> ev);
- void ProcessPendingEvents();
-
- void ShutdownConnection();
- void DetachSessionActor();
-
- STRICT_STFUNC(StateFunc,
- fFunc(EvDropPendingEvents, HandleDropPendingEvents);
- fFunc(TEvInterconnect::EvForward, ForwardToSession);
- fFunc(TEvInterconnect::EvConnectNode, ForwardToSession);
- fFunc(TEvents::TSystem::Subscribe, ForwardToSession);
- fFunc(TEvents::TSystem::Unsubscribe, ForwardToSession);
- cFunc(TEvInterconnect::EvDisconnect, ShutdownConnection);
- )
-};
-
-class TMock::TSessionActor : public TActor<TSessionActor> {
- const TString Prefix;
- TProxyActor *Proxy;
- std::unordered_map<TActorId, ui64, THash<TActorId>> Subscribers;
-
- std::unordered_map<ui16, std::deque<std::unique_ptr<IEventHandle>>> Outbox;
- bool SendPending = false;
- TInstant NextSendTimestamp;
-
- std::deque<std::unique_ptr<IEventHandle>> Inbox;
- bool ReceivePending = false;
- TInstant NextReceiveTimestamp;
-
- enum {
- EvSend = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvReceive,
- };
-
-public:
- // The SessionActor exists when and only when there are two working peers connected together and both of them have
- // their respective sessions. That is, when one of these conditions break, we have to terminate both sessions of a
- // connection. There are also some other things to consider: session can be destroyed via dtor after proxy destruction,
- // so it can't access proxy's fields from its destruction path. It is peer proxy's responsibility to destroy both
- // sessions upon destruction.
-
- TSessionActor(TProxyActor *proxy)
- : TActor(&TThis::StateFunc)
- , Prefix(TStringBuilder() << "Session[" << proxy->Node->NodeId << ":" << proxy->PeerNodeId << "] ")
- , Proxy(proxy)
- {}
-
- ~TSessionActor() {
- if (Proxy) {
- Proxy->SessionActor = nullptr;
- }
- }
-
- // Shut down local part of this session.
- void ShutdownSession() {
- if (!Proxy) {
- return;
- }
-
- STLOG(PRI_DEBUG, INTERCONNECT_SESSION, STIM01, Prefix << "ShutdownSession", (SelfId, SelfId()));
-
- // notify all subscribers
- for (const auto& [actorId, cookie] : Subscribers) {
- auto ev = std::make_unique<TEvInterconnect::TEvNodeDisconnected>(Proxy->PeerNodeId);
- Proxy->Mock->TestActorSystem->Send(new IEventHandle(actorId, SelfId(), ev.release(), 0, cookie),
- Proxy->Node->NodeId);
- }
-
- // drop unsent messages
- for (auto& [_, queue] : Outbox) {
- for (auto& ev : queue) {
- Proxy->Mock->TestActorSystem->Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected).Release(),
- Proxy->Node->NodeId);
- }
- }
-
- // transit to self-destruction state
- Proxy->Mock->TestActorSystem->Send(new IEventHandle(TEvents::TSystem::Poison, 0, SelfId(), {}, nullptr, 0),
- Proxy->Node->NodeId);
- Become(&TThis::StateUndelivered); // do not handle further events
-
- // no more proxy connected to this actor
- Proxy = nullptr;
- }
-
- void StateUndelivered(STFUNC_SIG) {
- Y_UNUSED(ctx);
- if (ev->GetTypeRewrite() == TEvents::TSystem::Poison) {
- TActor::PassAway();
- } else {
- TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown));
- }
- }
-
- void PassAway() override {
- Proxy->ShutdownConnection();
- TActor::PassAway();
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void HandleForward(TAutoPtr<IEventHandle> ev) {
- STLOG(PRI_DEBUG, INTERCONNECT_SESSION, STIM02, Prefix << "HandleForward", (SelfId, SelfId()),
- (Type, ev->Type), (TypeName, Proxy->Mock->TestActorSystem->GetEventName(ev->Type)),
- (Sender, ev->Sender), (Recipient, ev->Recipient), (Flags, ev->Flags), (Cookie, ev->Cookie));
-
- if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
- Subscribe(ev->Sender, ev->Cookie);
- }
- if (SendPending) {
- const ui16 ch = ev->GetChannel();
- Outbox[ch].emplace_back(ev.Release());
- } else {
- ScheduleSendEvent(ev);
- HandleSend(ev);
- }
- }
-
- void HandleSend(TAutoPtr<IEventHandle> ev) {
- while (ev) {
- STLOG(PRI_TRACE, INTERCONNECT_SESSION, STIM03, Prefix << "HandleSend", (SelfId, SelfId()),
- (Type, ev->Type), (Sender, ev->Sender), (Recipient, ev->Recipient), (Flags, ev->Flags),
- (Cookie, ev->Cookie));
-
- const TInstant now = TActivationContext::Now();
- Y_VERIFY(now == NextSendTimestamp);
- Y_VERIFY(Proxy->Peer && Proxy->Peer->SessionActor);
- const_cast<TScopeId&>(ev->OriginScopeId) = Proxy->Common->LocalScopeId;
- Proxy->Peer->SessionActor->PutToInbox(ev);
-
- if (Outbox.empty()) {
- SendPending = false;
- break;
- } else {
- auto it = Outbox.begin();
- std::advance(it, RandomNumber(Outbox.size()));
- auto& q = it->second;
- ev = q.front().release();
- q.pop_front();
- if (q.empty()) {
- Outbox.erase(it);
- }
-
- ScheduleSendEvent(ev);
- }
- }
- }
-
- void ScheduleSendEvent(TAutoPtr<IEventHandle>& ev) {
- const TInstant now = TActivationContext::Now();
- NextSendTimestamp = Proxy->Node->Enqueue(ev->GetSize(), now);
- if (now < NextSendTimestamp) {
- ev->Rewrite(EvSend, SelfId());
- TActivationContext::Schedule(NextSendTimestamp, ev.Release());
- SendPending = true;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void PutToInbox(TAutoPtr<IEventHandle> ev) {
- if (ReceivePending) {
- Inbox.emplace_back(ev.Release());
- } else {
- ScheduleReceiveEvent(ev);
- HandleReceive(ev);
- }
- }
-
- void HandleReceive(TAutoPtr<IEventHandle> ev) {
- while (ev) {
- const TInstant now = TActivationContext::Now();
- Y_VERIFY(now == NextReceiveTimestamp);
-
- auto fw = std::make_unique<IEventHandle>(
- SelfId(),
- ev->Type,
- ev->Flags & ~IEventHandle::FlagForwardOnNondelivery,
- ev->Recipient,
- ev->Sender,
- ev->ReleaseChainBuffer(),
- ev->Cookie,
- ev->OriginScopeId,
- std::move(ev->TraceId)
- );
-
- STLOG(PRI_TRACE, INTERCONNECT_SESSION, STIM04, Prefix << "HandleReceive", (SelfId, SelfId()),
- (Type, fw->Type), (Sender, fw->Sender), (Recipient, fw->Recipient), (Flags, fw->Flags),
- (Cookie, ev->Cookie));
-
- auto& common = Proxy->Common;
- if (!common->EventFilter || common->EventFilter->CheckIncomingEvent(*fw, common->LocalScopeId)) {
- Proxy->Mock->TestActorSystem->Send(fw.release(), Proxy->Node->NodeId);
- }
-
- if (Inbox.empty()) {
- ReceivePending = false;
- break;
- } else {
- ev = Inbox.front().release();
- Inbox.pop_front();
- ScheduleReceiveEvent(ev);
- }
- }
- }
-
- void ScheduleReceiveEvent(TAutoPtr<IEventHandle>& ev) {
- const TInstant now = TActivationContext::Now();
- NextReceiveTimestamp = Proxy->Node->Enqueue(ev->GetSize(), now);
- if (now < NextReceiveTimestamp) {
- ev->Rewrite(EvReceive, SelfId());
- Proxy->Mock->TestActorSystem->Schedule(NextReceiveTimestamp, ev.Release(), nullptr, Proxy->Node->NodeId);
- ReceivePending = true;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void Handle(TEvInterconnect::TEvConnectNode::TPtr ev) {
- Subscribe(ev->Sender, ev->Cookie);
- }
-
- void Handle(TEvents::TEvSubscribe::TPtr ev) {
- Subscribe(ev->Sender, ev->Cookie);
- }
-
- void Subscribe(const TActorId& actorId, ui64 cookie) {
- Subscribers[actorId] = cookie;
- Send(actorId, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, cookie);
- }
-
- void Handle(TEvents::TEvUnsubscribe::TPtr ev) {
- Subscribers.erase(ev->Sender);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- STRICT_STFUNC(StateFunc,
- fFunc(TEvInterconnect::EvForward, HandleForward);
- fFunc(EvSend, HandleSend);
- fFunc(EvReceive, HandleReceive);
- hFunc(TEvInterconnect::TEvConnectNode, Handle);
- hFunc(TEvents::TEvSubscribe, Handle);
- hFunc(TEvents::TEvUnsubscribe, Handle);
- cFunc(TEvents::TSystem::Poison, PassAway);
- )
-};
-
-TMock::TProxyActor::~TProxyActor() {
- const auto it = Mock->Proxies.find({Node->NodeId, PeerNodeId});
- Y_VERIFY(it != Mock->Proxies.end());
- Y_VERIFY(it->second == this);
- Mock->Proxies.erase(it);
-
- if (Peer) {
- Peer->DetachSessionActor();
- Peer->Peer = nullptr;
- }
- DetachSessionActor();
-}
-
-void TMock::TProxyActor::CreateSession() {
- Y_VERIFY(SelfId());
- Y_VERIFY(Working);
- Y_VERIFY(!SessionActor);
- SessionActor = new TSessionActor(this);
- const TActorId self = SelfId();
- Mock->TestActorSystem->Register(SessionActor, self, self.PoolID(), self.Hint(), Node->NodeId);
-}
-
-void TMock::TProxyActor::ForwardToSession(TAutoPtr<IEventHandle> ev) {
- if (TSessionActor *session = GetSession()) {
- InvokeOtherActor(*session, &TSessionActor::Receive, ev, TActivationContext::ActorContextFor(session->SelfId()));
- } else {
- const bool first = PendingEvents.empty();
- PendingEvents.emplace_back(ev.Release());
- if (first) {
- TActivationContext::Schedule(TDuration::Seconds(5), new IEventHandle(EvDropPendingEvents, 0, SelfId(), {},
- nullptr, ++DropPendingEventsCookie));
- }
- }
-}
-
-void TMock::TProxyActor::DropSessionEvent(std::unique_ptr<IEventHandle> ev) {
- switch (ev->GetTypeRewrite()) {
- case TEvInterconnect::EvForward:
- if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
- Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
- }
- TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
- break;
-
- case TEvInterconnect::EvConnectNode:
- case TEvents::TSystem::Subscribe:
- Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
- break;
-
- case TEvents::TSystem::Unsubscribe:
- break;
-
- default:
- Y_FAIL();
- }
-}
-
-void TMock::TProxyActor::HandleDropPendingEvents(TAutoPtr<IEventHandle> ev) {
- if (ev->Cookie == DropPendingEventsCookie) {
- for (auto& ev : std::exchange(PendingEvents, {})) {
- DropSessionEvent(std::move(ev));
- }
- }
-}
-
-void TMock::TProxyActor::ProcessPendingEvents() {
- for (auto& ev : std::exchange(PendingEvents, {})) {
- TSessionActor *session = GetSession();
- Y_VERIFY(session);
- Mock->TestActorSystem->Send(ev.release(), Node->NodeId);
- }
-}
-
-void TMock::TProxyActor::ShutdownConnection() {
- Y_VERIFY(Peer && ((SessionActor && Peer->SessionActor) || (!SessionActor && !Peer->SessionActor)));
- DetachSessionActor();
- Peer->DetachSessionActor();
-}
-
-void TMock::TProxyActor::DetachSessionActor() {
- if (auto *p = std::exchange(SessionActor, nullptr)) {
- p->ShutdownSession();
- }
-}
-
-TMock::TSingleThreadInterconnectMock(ui64 burstCapacityBytes, ui64 bytesPerSecond,
- TTestActorSystem *tas)
- : BurstCapacityBytes(burstCapacityBytes)
- , BytesPerSecond(bytesPerSecond)
- , TestActorSystem(tas)
-{}
-
-TMock::~TSingleThreadInterconnectMock()
-{}
-
-std::unique_ptr<IActor> TMock::CreateProxyActor(ui32 nodeId, ui32 peerNodeId,
- TIntrusivePtr<TInterconnectProxyCommon> common) {
- Y_VERIFY(nodeId != peerNodeId);
-
- auto& ptr = Proxies[{nodeId, peerNodeId}];
- Y_VERIFY(!ptr); // no multiple proxies for the same direction are allowed
-
- auto& node = Nodes[nodeId];
- if (!node) {
- node = std::make_shared<TNode>(nodeId, BurstCapacityBytes, BytesPerSecond);
- }
-
- const auto it = Proxies.find({peerNodeId, nodeId});
- TProxyActor *peer = it != Proxies.end() ? it->second : nullptr;
-
- auto proxy = std::make_unique<TProxyActor>(this, node, peer, peerNodeId, std::move(common));
- ptr = proxy.get();
- return proxy;
-}
+#include "single_thread_ic_mock.h"
+#include "testactorsys.h"
+#include "stlog.h"
+
+using namespace NActors;
+using namespace NKikimr;
+
+using TMock = TSingleThreadInterconnectMock;
+
+struct TMock::TNode {
+ const ui32 NodeId;
+ const ui64 BurstCapacityBytes;
+ const ui64 BytesPerSecond;
+ TInstant NextActionTimestamp;
+
+ TNode(ui32 nodeId, ui64 burstCapacityBytes, ui64 bytesPerSecond)
+ : NodeId(nodeId)
+ , BurstCapacityBytes(burstCapacityBytes)
+ , BytesPerSecond(bytesPerSecond)
+ {}
+
+ TInstant Enqueue(ui64 size, TInstant clock) {
+ if (BytesPerSecond == Max<ui64>()) {
+ return clock;
+ }
+ NextActionTimestamp = Max(clock - TDuration::MicroSeconds(BurstCapacityBytes * 1'000'000 / BytesPerSecond),
+ NextActionTimestamp) + TDuration::MicroSeconds((size * 1'000'000 + BytesPerSecond - 1) / BytesPerSecond);
+ return Max(NextActionTimestamp, clock);
+ }
+};
+
+class TMock::TProxyActor : public TActor<TProxyActor> {
+ friend class TSessionActor;
+
+ const TString Prefix;
+ TMock* const Mock;
+ std::shared_ptr<TNode> Node;
+ TProxyActor *Peer;
+ const ui32 PeerNodeId;
+ TIntrusivePtr<TInterconnectProxyCommon> Common;
+ TSessionActor *SessionActor = nullptr;
+ bool Working = false;
+ std::deque<std::unique_ptr<IEventHandle>> PendingEvents;
+ ui64 DropPendingEventsCookie = 0;
+
+ enum {
+ EvDropPendingEvents = EventSpaceBegin(TEvents::ES_PRIVATE),
+ };
+
+public:
+ TProxyActor(TMock *mock, std::shared_ptr<TNode> node, TProxyActor *peer, ui32 peerNodeId,
+ TIntrusivePtr<TInterconnectProxyCommon> common)
+ : TActor(&TThis::StateFunc)
+ , Prefix(TStringBuilder() << "Proxy[" << node->NodeId << ":" << peerNodeId << "] ")
+ , Mock(mock)
+ , Node(std::move(node))
+ , Peer(peer)
+ , PeerNodeId(peerNodeId)
+ , Common(std::move(common))
+ {
+ if (Peer) {
+ Peer->Peer = this;
+ }
+ }
+
+ ~TProxyActor();
+
+ void Registered(TActorSystem *as, const TActorId& parent) override {
+ TActor::Registered(as, parent);
+ Working = true;
+ if (Peer && Peer->Working) {
+ ProcessPendingEvents();
+ Peer->ProcessPendingEvents();
+ }
+ }
+
+ TSessionActor *GetSession() {
+ if (!SessionActor && Working && Peer && Peer->Working) {
+ Y_VERIFY(PendingEvents.empty());
+ Y_VERIFY(Peer->PendingEvents.empty());
+ CreateSession();
+ Peer->CreateSession();
+ }
+ return SessionActor;
+ }
+
+ void CreateSession();
+ void ForwardToSession(TAutoPtr<IEventHandle> ev);
+
+ void DropSessionEvent(std::unique_ptr<IEventHandle> ev);
+ void HandleDropPendingEvents(TAutoPtr<IEventHandle> ev);
+ void ProcessPendingEvents();
+
+ void ShutdownConnection();
+ void DetachSessionActor();
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(EvDropPendingEvents, HandleDropPendingEvents);
+ fFunc(TEvInterconnect::EvForward, ForwardToSession);
+ fFunc(TEvInterconnect::EvConnectNode, ForwardToSession);
+ fFunc(TEvents::TSystem::Subscribe, ForwardToSession);
+ fFunc(TEvents::TSystem::Unsubscribe, ForwardToSession);
+ cFunc(TEvInterconnect::EvDisconnect, ShutdownConnection);
+ )
+};
+
+class TMock::TSessionActor : public TActor<TSessionActor> {
+ const TString Prefix;
+ TProxyActor *Proxy;
+ std::unordered_map<TActorId, ui64, THash<TActorId>> Subscribers;
+
+ std::unordered_map<ui16, std::deque<std::unique_ptr<IEventHandle>>> Outbox;
+ bool SendPending = false;
+ TInstant NextSendTimestamp;
+
+ std::deque<std::unique_ptr<IEventHandle>> Inbox;
+ bool ReceivePending = false;
+ TInstant NextReceiveTimestamp;
+
+ enum {
+ EvSend = EventSpaceBegin(TEvents::ES_PRIVATE),
+ EvReceive,
+ };
+
+public:
+ // The SessionActor exists when and only when there are two working peers connected together and both of them have
+ // their respective sessions. That is, when one of these conditions break, we have to terminate both sessions of a
+ // connection. There are also some other things to consider: session can be destroyed via dtor after proxy destruction,
+ // so it can't access proxy's fields from its destruction path. It is peer proxy's responsibility to destroy both
+ // sessions upon destruction.
+
+ TSessionActor(TProxyActor *proxy)
+ : TActor(&TThis::StateFunc)
+ , Prefix(TStringBuilder() << "Session[" << proxy->Node->NodeId << ":" << proxy->PeerNodeId << "] ")
+ , Proxy(proxy)
+ {}
+
+ ~TSessionActor() {
+ if (Proxy) {
+ Proxy->SessionActor = nullptr;
+ }
+ }
+
+ // Shut down local part of this session.
+ void ShutdownSession() {
+ if (!Proxy) {
+ return;
+ }
+
+ STLOG(PRI_DEBUG, INTERCONNECT_SESSION, STIM01, Prefix << "ShutdownSession", (SelfId, SelfId()));
+
+ // notify all subscribers
+ for (const auto& [actorId, cookie] : Subscribers) {
+ auto ev = std::make_unique<TEvInterconnect::TEvNodeDisconnected>(Proxy->PeerNodeId);
+ Proxy->Mock->TestActorSystem->Send(new IEventHandle(actorId, SelfId(), ev.release(), 0, cookie),
+ Proxy->Node->NodeId);
+ }
+
+ // drop unsent messages
+ for (auto& [_, queue] : Outbox) {
+ for (auto& ev : queue) {
+ Proxy->Mock->TestActorSystem->Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected).Release(),
+ Proxy->Node->NodeId);
+ }
+ }
+
+ // transit to self-destruction state
+ Proxy->Mock->TestActorSystem->Send(new IEventHandle(TEvents::TSystem::Poison, 0, SelfId(), {}, nullptr, 0),
+ Proxy->Node->NodeId);
+ Become(&TThis::StateUndelivered); // do not handle further events
+
+ // no more proxy connected to this actor
+ Proxy = nullptr;
+ }
+
+ void StateUndelivered(STFUNC_SIG) {
+ Y_UNUSED(ctx);
+ if (ev->GetTypeRewrite() == TEvents::TSystem::Poison) {
+ TActor::PassAway();
+ } else {
+ TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown));
+ }
+ }
+
+ void PassAway() override {
+ Proxy->ShutdownConnection();
+ TActor::PassAway();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void HandleForward(TAutoPtr<IEventHandle> ev) {
+ STLOG(PRI_DEBUG, INTERCONNECT_SESSION, STIM02, Prefix << "HandleForward", (SelfId, SelfId()),
+ (Type, ev->Type), (TypeName, Proxy->Mock->TestActorSystem->GetEventName(ev->Type)),
+ (Sender, ev->Sender), (Recipient, ev->Recipient), (Flags, ev->Flags), (Cookie, ev->Cookie));
+
+ if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
+ Subscribe(ev->Sender, ev->Cookie);
+ }
+ if (SendPending) {
+ const ui16 ch = ev->GetChannel();
+ Outbox[ch].emplace_back(ev.Release());
+ } else {
+ ScheduleSendEvent(ev);
+ HandleSend(ev);
+ }
+ }
+
+ void HandleSend(TAutoPtr<IEventHandle> ev) {
+ while (ev) {
+ STLOG(PRI_TRACE, INTERCONNECT_SESSION, STIM03, Prefix << "HandleSend", (SelfId, SelfId()),
+ (Type, ev->Type), (Sender, ev->Sender), (Recipient, ev->Recipient), (Flags, ev->Flags),
+ (Cookie, ev->Cookie));
+
+ const TInstant now = TActivationContext::Now();
+ Y_VERIFY(now == NextSendTimestamp);
+ Y_VERIFY(Proxy->Peer && Proxy->Peer->SessionActor);
+ const_cast<TScopeId&>(ev->OriginScopeId) = Proxy->Common->LocalScopeId;
+ Proxy->Peer->SessionActor->PutToInbox(ev);
+
+ if (Outbox.empty()) {
+ SendPending = false;
+ break;
+ } else {
+ auto it = Outbox.begin();
+ std::advance(it, RandomNumber(Outbox.size()));
+ auto& q = it->second;
+ ev = q.front().release();
+ q.pop_front();
+ if (q.empty()) {
+ Outbox.erase(it);
+ }
+
+ ScheduleSendEvent(ev);
+ }
+ }
+ }
+
+ void ScheduleSendEvent(TAutoPtr<IEventHandle>& ev) {
+ const TInstant now = TActivationContext::Now();
+ NextSendTimestamp = Proxy->Node->Enqueue(ev->GetSize(), now);
+ if (now < NextSendTimestamp) {
+ ev->Rewrite(EvSend, SelfId());
+ TActivationContext::Schedule(NextSendTimestamp, ev.Release());
+ SendPending = true;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void PutToInbox(TAutoPtr<IEventHandle> ev) {
+ if (ReceivePending) {
+ Inbox.emplace_back(ev.Release());
+ } else {
+ ScheduleReceiveEvent(ev);
+ HandleReceive(ev);
+ }
+ }
+
+ void HandleReceive(TAutoPtr<IEventHandle> ev) {
+ while (ev) {
+ const TInstant now = TActivationContext::Now();
+ Y_VERIFY(now == NextReceiveTimestamp);
+
+ auto fw = std::make_unique<IEventHandle>(
+ SelfId(),
+ ev->Type,
+ ev->Flags & ~IEventHandle::FlagForwardOnNondelivery,
+ ev->Recipient,
+ ev->Sender,
+ ev->ReleaseChainBuffer(),
+ ev->Cookie,
+ ev->OriginScopeId,
+ std::move(ev->TraceId)
+ );
+
+ STLOG(PRI_TRACE, INTERCONNECT_SESSION, STIM04, Prefix << "HandleReceive", (SelfId, SelfId()),
+ (Type, fw->Type), (Sender, fw->Sender), (Recipient, fw->Recipient), (Flags, fw->Flags),
+ (Cookie, ev->Cookie));
+
+ auto& common = Proxy->Common;
+ if (!common->EventFilter || common->EventFilter->CheckIncomingEvent(*fw, common->LocalScopeId)) {
+ Proxy->Mock->TestActorSystem->Send(fw.release(), Proxy->Node->NodeId);
+ }
+
+ if (Inbox.empty()) {
+ ReceivePending = false;
+ break;
+ } else {
+ ev = Inbox.front().release();
+ Inbox.pop_front();
+ ScheduleReceiveEvent(ev);
+ }
+ }
+ }
+
+ void ScheduleReceiveEvent(TAutoPtr<IEventHandle>& ev) {
+ const TInstant now = TActivationContext::Now();
+ NextReceiveTimestamp = Proxy->Node->Enqueue(ev->GetSize(), now);
+ if (now < NextReceiveTimestamp) {
+ ev->Rewrite(EvReceive, SelfId());
+ Proxy->Mock->TestActorSystem->Schedule(NextReceiveTimestamp, ev.Release(), nullptr, Proxy->Node->NodeId);
+ ReceivePending = true;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ void Handle(TEvInterconnect::TEvConnectNode::TPtr ev) {
+ Subscribe(ev->Sender, ev->Cookie);
+ }
+
+ void Handle(TEvents::TEvSubscribe::TPtr ev) {
+ Subscribe(ev->Sender, ev->Cookie);
+ }
+
+ void Subscribe(const TActorId& actorId, ui64 cookie) {
+ Subscribers[actorId] = cookie;
+ Send(actorId, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, cookie);
+ }
+
+ void Handle(TEvents::TEvUnsubscribe::TPtr ev) {
+ Subscribers.erase(ev->Sender);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ STRICT_STFUNC(StateFunc,
+ fFunc(TEvInterconnect::EvForward, HandleForward);
+ fFunc(EvSend, HandleSend);
+ fFunc(EvReceive, HandleReceive);
+ hFunc(TEvInterconnect::TEvConnectNode, Handle);
+ hFunc(TEvents::TEvSubscribe, Handle);
+ hFunc(TEvents::TEvUnsubscribe, Handle);
+ cFunc(TEvents::TSystem::Poison, PassAway);
+ )
+};
+
+TMock::TProxyActor::~TProxyActor() {
+ const auto it = Mock->Proxies.find({Node->NodeId, PeerNodeId});
+ Y_VERIFY(it != Mock->Proxies.end());
+ Y_VERIFY(it->second == this);
+ Mock->Proxies.erase(it);
+
+ if (Peer) {
+ Peer->DetachSessionActor();
+ Peer->Peer = nullptr;
+ }
+ DetachSessionActor();
+}
+
+void TMock::TProxyActor::CreateSession() {
+ Y_VERIFY(SelfId());
+ Y_VERIFY(Working);
+ Y_VERIFY(!SessionActor);
+ SessionActor = new TSessionActor(this);
+ const TActorId self = SelfId();
+ Mock->TestActorSystem->Register(SessionActor, self, self.PoolID(), self.Hint(), Node->NodeId);
+}
+
+void TMock::TProxyActor::ForwardToSession(TAutoPtr<IEventHandle> ev) {
+ if (TSessionActor *session = GetSession()) {
+ InvokeOtherActor(*session, &TSessionActor::Receive, ev, TActivationContext::ActorContextFor(session->SelfId()));
+ } else {
+ const bool first = PendingEvents.empty();
+ PendingEvents.emplace_back(ev.Release());
+ if (first) {
+ TActivationContext::Schedule(TDuration::Seconds(5), new IEventHandle(EvDropPendingEvents, 0, SelfId(), {},
+ nullptr, ++DropPendingEventsCookie));
+ }
+ }
+}
+
+void TMock::TProxyActor::DropSessionEvent(std::unique_ptr<IEventHandle> ev) {
+ switch (ev->GetTypeRewrite()) {
+ case TEvInterconnect::EvForward:
+ if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
+ Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
+ }
+ TActivationContext::Send(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::Disconnected));
+ break;
+
+ case TEvInterconnect::EvConnectNode:
+ case TEvents::TSystem::Subscribe:
+ Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(PeerNodeId), 0, ev->Cookie);
+ break;
+
+ case TEvents::TSystem::Unsubscribe:
+ break;
+
+ default:
+ Y_FAIL();
+ }
+}
+
+void TMock::TProxyActor::HandleDropPendingEvents(TAutoPtr<IEventHandle> ev) {
+ if (ev->Cookie == DropPendingEventsCookie) {
+ for (auto& ev : std::exchange(PendingEvents, {})) {
+ DropSessionEvent(std::move(ev));
+ }
+ }
+}
+
+void TMock::TProxyActor::ProcessPendingEvents() {
+ for (auto& ev : std::exchange(PendingEvents, {})) {
+ TSessionActor *session = GetSession();
+ Y_VERIFY(session);
+ Mock->TestActorSystem->Send(ev.release(), Node->NodeId);
+ }
+}
+
+void TMock::TProxyActor::ShutdownConnection() {
+ Y_VERIFY(Peer && ((SessionActor && Peer->SessionActor) || (!SessionActor && !Peer->SessionActor)));
+ DetachSessionActor();
+ Peer->DetachSessionActor();
+}
+
+void TMock::TProxyActor::DetachSessionActor() {
+ if (auto *p = std::exchange(SessionActor, nullptr)) {
+ p->ShutdownSession();
+ }
+}
+
+TMock::TSingleThreadInterconnectMock(ui64 burstCapacityBytes, ui64 bytesPerSecond,
+ TTestActorSystem *tas)
+ : BurstCapacityBytes(burstCapacityBytes)
+ , BytesPerSecond(bytesPerSecond)
+ , TestActorSystem(tas)
+{}
+
+TMock::~TSingleThreadInterconnectMock()
+{}
+
+std::unique_ptr<IActor> TMock::CreateProxyActor(ui32 nodeId, ui32 peerNodeId,
+ TIntrusivePtr<TInterconnectProxyCommon> common) {
+ Y_VERIFY(nodeId != peerNodeId);
+
+ auto& ptr = Proxies[{nodeId, peerNodeId}];
+ Y_VERIFY(!ptr); // no multiple proxies for the same direction are allowed
+
+ auto& node = Nodes[nodeId];
+ if (!node) {
+ node = std::make_shared<TNode>(nodeId, BurstCapacityBytes, BytesPerSecond);
+ }
+
+ const auto it = Proxies.find({peerNodeId, nodeId});
+ TProxyActor *peer = it != Proxies.end() ? it->second : nullptr;
+
+ auto proxy = std::make_unique<TProxyActor>(this, node, peer, peerNodeId, std::move(common));
+ ptr = proxy.get();
+ return proxy;
+}
diff --git a/ydb/core/util/single_thread_ic_mock.h b/ydb/core/util/single_thread_ic_mock.h
index a0423442d88..3774619d677 100644
--- a/ydb/core/util/single_thread_ic_mock.h
+++ b/ydb/core/util/single_thread_ic_mock.h
@@ -1,30 +1,30 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NKikimr {
-
- class TTestActorSystem;
-
- class TSingleThreadInterconnectMock {
- struct TNode;
-
- class TProxyActor;
- class TSessionActor;
-
- private:
- const ui64 BurstCapacityBytes;
- const ui64 BytesPerSecond;
- TTestActorSystem *TestActorSystem;
- std::unordered_map<ui32, std::shared_ptr<TNode>> Nodes;
- std::unordered_map<std::pair<ui32, ui32>, TProxyActor*, THash<std::pair<ui32, ui32>>> Proxies;
-
- public:
- TSingleThreadInterconnectMock(ui64 burstCapacityBytes, ui64 bytesPerSecond, TTestActorSystem *tas);
- ~TSingleThreadInterconnectMock();
-
- std::unique_ptr<NActors::IActor> CreateProxyActor(ui32 nodeId, ui32 peerNodeId,
- TIntrusivePtr<NActors::TInterconnectProxyCommon> common);
- };
-
-}
+#pragma once
+
+#include "defs.h"
+
+namespace NKikimr {
+
+ class TTestActorSystem;
+
+ class TSingleThreadInterconnectMock {
+ struct TNode;
+
+ class TProxyActor;
+ class TSessionActor;
+
+ private:
+ const ui64 BurstCapacityBytes;
+ const ui64 BytesPerSecond;
+ TTestActorSystem *TestActorSystem;
+ std::unordered_map<ui32, std::shared_ptr<TNode>> Nodes;
+ std::unordered_map<std::pair<ui32, ui32>, TProxyActor*, THash<std::pair<ui32, ui32>>> Proxies;
+
+ public:
+ TSingleThreadInterconnectMock(ui64 burstCapacityBytes, ui64 bytesPerSecond, TTestActorSystem *tas);
+ ~TSingleThreadInterconnectMock();
+
+ std::unique_ptr<NActors::IActor> CreateProxyActor(ui32 nodeId, ui32 peerNodeId,
+ TIntrusivePtr<NActors::TInterconnectProxyCommon> common);
+ };
+
+}
diff --git a/ydb/core/util/stlog.h b/ydb/core/util/stlog.h
index de6cea21310..930485ff1a6 100644
--- a/ydb/core/util/stlog.h
+++ b/ydb/core/util/stlog.h
@@ -1,228 +1,228 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/protos/services.pb.h>
-#include <library/cpp/actors/core/log.h>
+#include <library/cpp/actors/core/log.h>
#include <google/protobuf/text_format.h>
-
-// special hack for gcc
-static struct STLOG_PARAM_T {} STLOG_PARAM;
-
-namespace NKikimr::NStLog {
-
-#define STLOG_EXPAND(X) X
-
-#ifdef _MSC_VER
-#define STLOG_NARG(...) STLOG_NARG_S1(STLOG_NARG_WRAP(__VA_ARGS__))
-#define STLOG_NARG_WRAP(...) X,__VA_ARGS__
-#define STLOG_NARG_S1(...) STLOG_EXPAND(STLOG_NARG_IMPL(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
-#else
-#define STLOG_NARG(...) STLOG_NARG_IMPL(X,##__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
-#endif
-#define STLOG_NARG_IMPL(X,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,N,...) N
-
-#define STLOG_PASTE(A, B) A ## _ ## B
-
-#define STLOG_PARAM(NAME, VALUE) ::NKikimr::NStLog::TUnboundParam(#NAME) = VALUE
-
-#define STLOG_PARAMS(...) STLOG_PARAMS_S1(STLOG_NARG(__VA_ARGS__), __VA_ARGS__)
-#define STLOG_PARAMS_S1(N, ...) STLOG_EXPAND(STLOG_PASTE(STLOG_PARAMS, N)(__VA_ARGS__))
-
-#define STLOG_PARAMS_0()
-#define STLOG_PARAMS_1(KV) .AppendBoundParam(STLOG_PARAM KV)
-#define STLOG_PARAMS_2(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_1(__VA_ARGS__))
-#define STLOG_PARAMS_3(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_2(__VA_ARGS__))
-#define STLOG_PARAMS_4(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_3(__VA_ARGS__))
-#define STLOG_PARAMS_5(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_4(__VA_ARGS__))
-#define STLOG_PARAMS_6(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_5(__VA_ARGS__))
-#define STLOG_PARAMS_7(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_6(__VA_ARGS__))
-#define STLOG_PARAMS_8(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_7(__VA_ARGS__))
-#define STLOG_PARAMS_9(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_8(__VA_ARGS__))
-#define STLOG_PARAMS_10(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_9(__VA_ARGS__))
-#define STLOG_PARAMS_11(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_10(__VA_ARGS__))
-#define STLOG_PARAMS_12(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_11(__VA_ARGS__))
-#define STLOG_PARAMS_13(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_12(__VA_ARGS__))
-#define STLOG_PARAMS_14(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_13(__VA_ARGS__))
-#define STLOG_PARAMS_15(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_14(__VA_ARGS__))
-#define STLOG_PARAMS_16(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_15(__VA_ARGS__))
-
-#define STLOGX(CTX, PRIO, COMP, MARKER, TEXT, ...) \
- do { \
- auto getPrio = [&] { using namespace NActors::NLog; return (PRIO); }; \
- auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
- auto makeMessage = [&] { \
- struct MARKER {}; \
- using Tag = MARKER; \
- return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
- STLOG_PARAMS(__VA_ARGS__); \
- }; \
- LOG_LOG_S((CTX), getPrio(), getComp(), makeMessage()); \
- } while (false)
-
-#define STLOG(PRIO, COMP, MARKER, TEXT, ...) \
- do { \
- if (TActivationContext *ctxp = TlsActivationContext) { \
- auto getPrio = [&] { using namespace NActors::NLog; return (PRIO); }; \
- auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
- auto makeMessage = [&] { \
+
+// special hack for gcc
+static struct STLOG_PARAM_T {} STLOG_PARAM;
+
+namespace NKikimr::NStLog {
+
+#define STLOG_EXPAND(X) X
+
+#ifdef _MSC_VER
+#define STLOG_NARG(...) STLOG_NARG_S1(STLOG_NARG_WRAP(__VA_ARGS__))
+#define STLOG_NARG_WRAP(...) X,__VA_ARGS__
+#define STLOG_NARG_S1(...) STLOG_EXPAND(STLOG_NARG_IMPL(__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
+#else
+#define STLOG_NARG(...) STLOG_NARG_IMPL(X,##__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
+#endif
+#define STLOG_NARG_IMPL(X,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,N,...) N
+
+#define STLOG_PASTE(A, B) A ## _ ## B
+
+#define STLOG_PARAM(NAME, VALUE) ::NKikimr::NStLog::TUnboundParam(#NAME) = VALUE
+
+#define STLOG_PARAMS(...) STLOG_PARAMS_S1(STLOG_NARG(__VA_ARGS__), __VA_ARGS__)
+#define STLOG_PARAMS_S1(N, ...) STLOG_EXPAND(STLOG_PASTE(STLOG_PARAMS, N)(__VA_ARGS__))
+
+#define STLOG_PARAMS_0()
+#define STLOG_PARAMS_1(KV) .AppendBoundParam(STLOG_PARAM KV)
+#define STLOG_PARAMS_2(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_1(__VA_ARGS__))
+#define STLOG_PARAMS_3(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_2(__VA_ARGS__))
+#define STLOG_PARAMS_4(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_3(__VA_ARGS__))
+#define STLOG_PARAMS_5(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_4(__VA_ARGS__))
+#define STLOG_PARAMS_6(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_5(__VA_ARGS__))
+#define STLOG_PARAMS_7(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_6(__VA_ARGS__))
+#define STLOG_PARAMS_8(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_7(__VA_ARGS__))
+#define STLOG_PARAMS_9(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_8(__VA_ARGS__))
+#define STLOG_PARAMS_10(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_9(__VA_ARGS__))
+#define STLOG_PARAMS_11(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_10(__VA_ARGS__))
+#define STLOG_PARAMS_12(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_11(__VA_ARGS__))
+#define STLOG_PARAMS_13(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_12(__VA_ARGS__))
+#define STLOG_PARAMS_14(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_13(__VA_ARGS__))
+#define STLOG_PARAMS_15(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_14(__VA_ARGS__))
+#define STLOG_PARAMS_16(KV, ...) STLOG_PARAMS_1(KV) STLOG_EXPAND(STLOG_PARAMS_15(__VA_ARGS__))
+
+#define STLOGX(CTX, PRIO, COMP, MARKER, TEXT, ...) \
+ do { \
+ auto getPrio = [&] { using namespace NActors::NLog; return (PRIO); }; \
+ auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
+ auto makeMessage = [&] { \
+ struct MARKER {}; \
+ using Tag = MARKER; \
+ return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
+ STLOG_PARAMS(__VA_ARGS__); \
+ }; \
+ LOG_LOG_S((CTX), getPrio(), getComp(), makeMessage()); \
+ } while (false)
+
+#define STLOG(PRIO, COMP, MARKER, TEXT, ...) \
+ do { \
+ if (TActivationContext *ctxp = TlsActivationContext) { \
+ auto getPrio = [&] { using namespace NActors::NLog; return (PRIO); }; \
+ auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
+ auto makeMessage = [&] { \
struct MARKER {}; \
using Tag = MARKER; \
- return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
- STLOG_PARAMS(__VA_ARGS__); \
- }; \
- LOG_LOG_S(*ctxp, getPrio(), getComp(), makeMessage()); \
- } \
- } while (false)
-
-#define STLOG_DEBUG_FAIL(COMP, MARKER, TEXT, ...) \
- do { \
- if (TActivationContext *ctxp = TlsActivationContext) { \
- auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
- auto makeMessage = [&] { \
- struct MARKER {}; \
- using Tag = MARKER; \
- return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
- STLOG_PARAMS(__VA_ARGS__); \
- }; \
- Y_VERIFY_DEBUG_S(false, makeMessage()); \
- LOG_LOG_S(*ctxp, NLog::PRI_CRIT, getComp(), makeMessage()); \
- } \
- } while (false)
-
- template<typename T>
- class THasToStringMethod {
- // check the signature if it exists
- template<typename X> static constexpr typename std::is_same<decltype(&X::ToString), TString(X::*)()const>::type check(int);
- // in case when there is no such signature
- template<typename> static constexpr std::false_type check(...);
- public:
- static constexpr bool value = decltype(check<T>(0))::value;
- };
-
- template<typename Base, typename T>
- class TBoundParam : public Base {
- T Value;
-
- public:
- template<typename U>
- TBoundParam(const Base& base, U&& value)
- : Base(base)
- , Value(std::forward<U>(value))
- {}
-
- void WriteToStream(IOutputStream& s) const {
- Base::WriteToStream(s);
- s << "# ";
- OutputParam(s, Value);
- }
-
- private:
- template<typename TValue>
- static void OutputParam(IOutputStream& s, const std::optional<TValue>& value) {
- if (value) {
- OutputParam(s, *value);
- } else {
- s << "<null>";
- }
- }
-
- template<typename TValue>
- static void OutputParam(IOutputStream& s, const TValue& value) {
- if constexpr (google::protobuf::is_proto_enum<TValue>::value) {
- const google::protobuf::EnumDescriptor *e = google::protobuf::GetEnumDescriptor<TValue>();
- if (const auto *val = e->FindValueByNumber(value)) {
- s << val->name();
- } else {
- s << static_cast<int>(value);
- }
- } else if constexpr (std::is_same_v<TValue, bool>) {
- s << (value ? "true" : "false");
- } else if constexpr (std::is_base_of_v<google::protobuf::Message, TValue>) {
- google::protobuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString str;
- if (p.PrintToString(value, &str)) {
- s << "{" << str << "}";
- } else {
- s << "<error>";
- }
- } else if constexpr (THasToStringMethod<TValue>::value) {
- s << value.ToString();
- } else {
- s << value;
- }
- }
- };
-
- class TUnboundParam {
- const char *Name;
-
- public:
- TUnboundParam(const char *name)
- : Name(name)
- {}
-
- template<typename T>
- NKikimr::NStLog::TBoundParam<TUnboundParam, T> operator =(T&& value) {
- return {*this, std::forward<T>(value)};
- }
-
- void WriteToStream(IOutputStream& s) const {
- s << Name;
- }
- };
-
- template<typename Tag, typename... TParams>
- class TMessage {
- const char *File;
- int Line;
- const char *Marker;
- TString Text;
- std::tuple<TParams...> Params;
- static constexpr size_t NumParams = sizeof...(TParams);
-
- public:
- template<typename... TArgs>
- TMessage(const char *file, int line, const char *marker, TString text, std::tuple<TParams...>&& params = {})
- : File(file)
- , Line(line)
- , Marker(marker)
- , Text(std::move(text))
- , Params(std::move(params))
- {}
-
- template<typename Base, typename T>
- TMessage<Tag, TParams..., TBoundParam<Base, T>> AppendBoundParam(TBoundParam<Base, T>&& p) {
- return {File, Line, Marker, std::move(Text), std::tuple_cat(Params, std::make_tuple(std::move(p)))};
- }
-
- TMessage<Tag, TParams...> AppendBoundParam(const STLOG_PARAM_T&) {
- return std::move(*this);
- }
-
- void WriteToStream(IOutputStream& s) const {
- const char *p = strrchr(File, '/');
- p = p ? p + 1 : File;
- s << "{" << Marker << "@" << p << ":" << Line << "} " << Text;
- WriteParams<0>(s, nullptr);
- }
-
- private:
- template<size_t Index>
- void WriteParams(IOutputStream& s, std::enable_if_t<Index != NumParams>*) const {
- s << " ";
- std::get<Index>(Params).WriteToStream(s);
- WriteParams<Index + 1>(s, nullptr);
- }
-
- // out-of-range handler
- template<size_t Index>
- void WriteParams(IOutputStream&, ...) const {}
- };
-
-}
-
-template<typename Tag, typename... TParams>
-IOutputStream& operator <<(IOutputStream& s, const NKikimr::NStLog::TMessage<Tag, TParams...>& message) {
- message.WriteToStream(s);
- return s;
-}
+ return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
+ STLOG_PARAMS(__VA_ARGS__); \
+ }; \
+ LOG_LOG_S(*ctxp, getPrio(), getComp(), makeMessage()); \
+ } \
+ } while (false)
+
+#define STLOG_DEBUG_FAIL(COMP, MARKER, TEXT, ...) \
+ do { \
+ if (TActivationContext *ctxp = TlsActivationContext) { \
+ auto getComp = [&] { using namespace NKikimrServices; using namespace NActorsServices; return (COMP); }; \
+ auto makeMessage = [&] { \
+ struct MARKER {}; \
+ using Tag = MARKER; \
+ return ::NKikimr::NStLog::TMessage<Tag>(__FILE__, __LINE__, #MARKER, TStringBuilder() << TEXT) \
+ STLOG_PARAMS(__VA_ARGS__); \
+ }; \
+ Y_VERIFY_DEBUG_S(false, makeMessage()); \
+ LOG_LOG_S(*ctxp, NLog::PRI_CRIT, getComp(), makeMessage()); \
+ } \
+ } while (false)
+
+ template<typename T>
+ class THasToStringMethod {
+ // check the signature if it exists
+ template<typename X> static constexpr typename std::is_same<decltype(&X::ToString), TString(X::*)()const>::type check(int);
+ // in case when there is no such signature
+ template<typename> static constexpr std::false_type check(...);
+ public:
+ static constexpr bool value = decltype(check<T>(0))::value;
+ };
+
+ template<typename Base, typename T>
+ class TBoundParam : public Base {
+ T Value;
+
+ public:
+ template<typename U>
+ TBoundParam(const Base& base, U&& value)
+ : Base(base)
+ , Value(std::forward<U>(value))
+ {}
+
+ void WriteToStream(IOutputStream& s) const {
+ Base::WriteToStream(s);
+ s << "# ";
+ OutputParam(s, Value);
+ }
+
+ private:
+ template<typename TValue>
+ static void OutputParam(IOutputStream& s, const std::optional<TValue>& value) {
+ if (value) {
+ OutputParam(s, *value);
+ } else {
+ s << "<null>";
+ }
+ }
+
+ template<typename TValue>
+ static void OutputParam(IOutputStream& s, const TValue& value) {
+ if constexpr (google::protobuf::is_proto_enum<TValue>::value) {
+ const google::protobuf::EnumDescriptor *e = google::protobuf::GetEnumDescriptor<TValue>();
+ if (const auto *val = e->FindValueByNumber(value)) {
+ s << val->name();
+ } else {
+ s << static_cast<int>(value);
+ }
+ } else if constexpr (std::is_same_v<TValue, bool>) {
+ s << (value ? "true" : "false");
+ } else if constexpr (std::is_base_of_v<google::protobuf::Message, TValue>) {
+ google::protobuf::TextFormat::Printer p;
+ p.SetSingleLineMode(true);
+ TString str;
+ if (p.PrintToString(value, &str)) {
+ s << "{" << str << "}";
+ } else {
+ s << "<error>";
+ }
+ } else if constexpr (THasToStringMethod<TValue>::value) {
+ s << value.ToString();
+ } else {
+ s << value;
+ }
+ }
+ };
+
+ class TUnboundParam {
+ const char *Name;
+
+ public:
+ TUnboundParam(const char *name)
+ : Name(name)
+ {}
+
+ template<typename T>
+ NKikimr::NStLog::TBoundParam<TUnboundParam, T> operator =(T&& value) {
+ return {*this, std::forward<T>(value)};
+ }
+
+ void WriteToStream(IOutputStream& s) const {
+ s << Name;
+ }
+ };
+
+ template<typename Tag, typename... TParams>
+ class TMessage {
+ const char *File;
+ int Line;
+ const char *Marker;
+ TString Text;
+ std::tuple<TParams...> Params;
+ static constexpr size_t NumParams = sizeof...(TParams);
+
+ public:
+ template<typename... TArgs>
+ TMessage(const char *file, int line, const char *marker, TString text, std::tuple<TParams...>&& params = {})
+ : File(file)
+ , Line(line)
+ , Marker(marker)
+ , Text(std::move(text))
+ , Params(std::move(params))
+ {}
+
+ template<typename Base, typename T>
+ TMessage<Tag, TParams..., TBoundParam<Base, T>> AppendBoundParam(TBoundParam<Base, T>&& p) {
+ return {File, Line, Marker, std::move(Text), std::tuple_cat(Params, std::make_tuple(std::move(p)))};
+ }
+
+ TMessage<Tag, TParams...> AppendBoundParam(const STLOG_PARAM_T&) {
+ return std::move(*this);
+ }
+
+ void WriteToStream(IOutputStream& s) const {
+ const char *p = strrchr(File, '/');
+ p = p ? p + 1 : File;
+ s << "{" << Marker << "@" << p << ":" << Line << "} " << Text;
+ WriteParams<0>(s, nullptr);
+ }
+
+ private:
+ template<size_t Index>
+ void WriteParams(IOutputStream& s, std::enable_if_t<Index != NumParams>*) const {
+ s << " ";
+ std::get<Index>(Params).WriteToStream(s);
+ WriteParams<Index + 1>(s, nullptr);
+ }
+
+ // out-of-range handler
+ template<size_t Index>
+ void WriteParams(IOutputStream&, ...) const {}
+ };
+
+}
+
+template<typename Tag, typename... TParams>
+IOutputStream& operator <<(IOutputStream& s, const NKikimr::NStLog::TMessage<Tag, TParams...>& message) {
+ message.WriteToStream(s);
+ return s;
+}
diff --git a/ydb/core/util/testactorsys.cpp b/ydb/core/util/testactorsys.cpp
index 73d27bc9d92..f1cac9621ce 100644
--- a/ydb/core/util/testactorsys.cpp
+++ b/ydb/core/util/testactorsys.cpp
@@ -1,45 +1,45 @@
-#include "testactorsys.h"
+#include "testactorsys.h"
#include <ydb/core/tablet/bootstrapper.h>
#include <ydb/core/tx/scheme_board/replica.h>
#include <ydb/core/base/statestorage.h>
#include <ydb/core/base/statestorage_impl.h>
#include <ydb/core/base/tablet_resolver.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-
-namespace NKikimr {
-
-class TTestExecutorPool : public IExecutorPool {
- TTestActorSystem *Context;
- const ui32 NodeId;
-
-public:
- TTestExecutorPool(TTestActorSystem *context, ui32 nodeId)
- : IExecutorPool(0)
- , Context(context)
- , NodeId(nodeId)
- {}
-
+#include <library/cpp/actors/interconnect/interconnect.h>
+
+namespace NKikimr {
+
+class TTestExecutorPool : public IExecutorPool {
+ TTestActorSystem *Context;
+ const ui32 NodeId;
+
+public:
+ TTestExecutorPool(TTestActorSystem *context, ui32 nodeId)
+ : IExecutorPool(0)
+ , Context(context)
+ , NodeId(nodeId)
+ {}
+
ui32 GetReadyActivation(TWorkerContext& /*wctx*/, ui64 /*revolvingCounter*/) override {
- Y_FAIL();
- }
-
+ Y_FAIL();
+ }
+
void ReclaimMailbox(TMailboxType::EType /*mailboxType*/, ui32 /*hint*/, NActors::TWorkerId /*workerId*/, ui64 /*revolvingCounter*/) override {
- Y_FAIL();
- }
-
+ Y_FAIL();
+ }
+
void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, NActors::TWorkerId /*workerId*/) override {
- Context->Schedule(deadline, ev, cookie, NodeId);
- }
-
+ Context->Schedule(deadline, ev, cookie, NodeId);
+ }
+
void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, NActors::TWorkerId /*workerId*/) override {
- Context->Schedule(TInstant::FromValue(deadline.GetValue()), ev, cookie, NodeId);
- }
-
+ Context->Schedule(TInstant::FromValue(deadline.GetValue()), ev, cookie, NodeId);
+ }
+
void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, NActors::TWorkerId /*workerId*/) override {
- Context->Schedule(delta, ev, cookie, NodeId);
- }
-
- bool Send(TAutoPtr<IEventHandle>& ev) override {
+ Context->Schedule(delta, ev, cookie, NodeId);
+ }
+
+ bool Send(TAutoPtr<IEventHandle>& ev) override {
if (TlsActivationContext) {
const TActorContext& ctx = TActivationContext::AsActorContext();
IActor* sender = Context->GetActor(ctx.SelfID);
@@ -48,164 +48,164 @@ public:
ev = nullptr;
}
}
- return Context->Send(ev, NodeId);
- }
-
- void ScheduleActivation(ui32 /*activation*/) override {
- Y_FAIL();
- }
-
- void ScheduleActivationEx(ui32 /*activation*/, ui64 /*revolvingCounter*/) override {
- Y_FAIL();
- }
-
- TActorId Register(IActor* actor, TMailboxType::EType /*mailboxType*/, ui64 /*revolvingCounter*/, const TActorId& parentId) override {
- return Context->Register(actor, parentId, PoolId, std::nullopt, NodeId);
- }
-
- TActorId Register(IActor* actor, TMailboxHeader* /*mailbox*/, ui32 hint, const TActorId& parentId) override {
- return Context->Register(actor, parentId, PoolId, hint, NodeId);
- }
-
+ return Context->Send(ev, NodeId);
+ }
+
+ void ScheduleActivation(ui32 /*activation*/) override {
+ Y_FAIL();
+ }
+
+ void ScheduleActivationEx(ui32 /*activation*/, ui64 /*revolvingCounter*/) override {
+ Y_FAIL();
+ }
+
+ TActorId Register(IActor* actor, TMailboxType::EType /*mailboxType*/, ui64 /*revolvingCounter*/, const TActorId& parentId) override {
+ return Context->Register(actor, parentId, PoolId, std::nullopt, NodeId);
+ }
+
+ TActorId Register(IActor* actor, TMailboxHeader* /*mailbox*/, ui32 hint, const TActorId& parentId) override {
+ return Context->Register(actor, parentId, PoolId, hint, NodeId);
+ }
+
void Prepare(TActorSystem* /*actorSystem*/, NSchedulerQueue::TReader** /*scheduleReaders*/, ui32* /*scheduleSz*/) override {
- }
-
- void Start() override {
- }
-
- void PrepareStop() override {
- }
-
- void Shutdown() override {
- }
-
- bool Cleanup() override {
- return true;
- }
-
+ }
+
+ void Start() override {
+ }
+
+ void PrepareStop() override {
+ }
+
+ void Shutdown() override {
+ }
+
+ bool Cleanup() override {
+ return true;
+ }
+
TAffinity* Affinity() const override {
- Y_FAIL();
- }
-};
-
-static TActorId MakeBoardReplicaID(ui32 node, ui64 stateStorageGroup, ui32 replicaIndex) {
- char x[12] = {'s', 's', 'b'};
- x[3] = (char)stateStorageGroup;
- memcpy(x + 5, &replicaIndex, sizeof(ui32));
- return TActorId(node, TStringBuf(x, 12));
-}
-
-NTabletPipe::TClientConfig TTestActorSystem::GetPipeConfigWithRetries() {
- NTabletPipe::TClientConfig pipeConfig;
+ Y_FAIL();
+ }
+};
+
+static TActorId MakeBoardReplicaID(ui32 node, ui64 stateStorageGroup, ui32 replicaIndex) {
+ char x[12] = {'s', 's', 'b'};
+ x[3] = (char)stateStorageGroup;
+ memcpy(x + 5, &replicaIndex, sizeof(ui32));
+ return TActorId(node, TStringBuf(x, 12));
+}
+
+NTabletPipe::TClientConfig TTestActorSystem::GetPipeConfigWithRetries() {
+ NTabletPipe::TClientConfig pipeConfig;
pipeConfig.RetryPolicy = NTabletPipe::TClientRetryPolicy::WithRetries();
- return pipeConfig;
-}
-
-void TTestActorSystem::SendToPipe(ui64 tabletId, const TActorId& sender, IEventBase* payload, ui64 cookie, const NKikimr::NTabletPipe::TClientConfig& pipeConfig) {
- WrapInActorContext(sender, [&] { // perform action in sender's context
- const TActorId clientId = Register(NKikimr::NTabletPipe::CreateClient(sender, tabletId, pipeConfig));
- NTabletPipe::SendData(sender, clientId, payload, cookie);
- Send(new IEventHandle(clientId, sender, new NKikimr::TEvTabletPipe::TEvShutdown()));
- });
-}
-
+ return pipeConfig;
+}
+
+void TTestActorSystem::SendToPipe(ui64 tabletId, const TActorId& sender, IEventBase* payload, ui64 cookie, const NKikimr::NTabletPipe::TClientConfig& pipeConfig) {
+ WrapInActorContext(sender, [&] { // perform action in sender's context
+ const TActorId clientId = Register(NKikimr::NTabletPipe::CreateClient(sender, tabletId, pipeConfig));
+ NTabletPipe::SendData(sender, clientId, payload, cookie);
+ Send(new IEventHandle(clientId, sender, new NKikimr::TEvTabletPipe::TEvShutdown()));
+ });
+}
+
TTabletStorageInfo *TTestActorSystem::CreateTestTabletInfo(ui64 tabletId, TTabletTypes::EType tabletType, TBlobStorageGroupType::EErasureSpecies erasure, ui32 groupId) {
- auto x = std::make_unique<TTabletStorageInfo>();
-
- x->TabletID = tabletId;
- x->TabletType = tabletType;
- x->Channels.resize(4);
-
- for (ui64 channel = 0; channel < x->Channels.size(); ++channel) {
- x->Channels[channel].Channel = channel;
- x->Channels[channel].Type = TBlobStorageGroupType(erasure);
- x->Channels[channel].History.resize(1);
- x->Channels[channel].History[0].FromGeneration = 0;
- x->Channels[channel].History[0].GroupID = groupId;
- }
-
- return x.release();
-}
-
+ auto x = std::make_unique<TTabletStorageInfo>();
+
+ x->TabletID = tabletId;
+ x->TabletType = tabletType;
+ x->Channels.resize(4);
+
+ for (ui64 channel = 0; channel < x->Channels.size(); ++channel) {
+ x->Channels[channel].Channel = channel;
+ x->Channels[channel].Type = TBlobStorageGroupType(erasure);
+ x->Channels[channel].History.resize(1);
+ x->Channels[channel].History[0].FromGeneration = 0;
+ x->Channels[channel].History[0].GroupID = groupId;
+ }
+
+ return x.release();
+}
+
TActorId TTestActorSystem::CreateTestBootstrapper(TTabletStorageInfo *info, std::function<IActor*(TActorId, TTabletStorageInfo*)> op, ui32 nodeId) {
- auto bi = MakeIntrusive<TBootstrapperInfo>(new TTabletSetupInfo(op, TMailboxType::Simple, 0, TMailboxType::Simple, 0));
- return Register(CreateBootstrapper(info, bi.Get()), nodeId);
-}
-
-void TTestActorSystem::SetupTabletRuntime(bool isMirror3dc, ui32 stateStorageNodeId, ui32 targetNodeId) {
- auto setup = MakeIntrusive<TTableNameserverSetup>();
+ auto bi = MakeIntrusive<TBootstrapperInfo>(new TTabletSetupInfo(op, TMailboxType::Simple, 0, TMailboxType::Simple, 0));
+ return Register(CreateBootstrapper(info, bi.Get()), nodeId);
+}
+
+void TTestActorSystem::SetupTabletRuntime(bool isMirror3dc, ui32 stateStorageNodeId, ui32 targetNodeId) {
+ auto setup = MakeIntrusive<TTableNameserverSetup>();
ui32 nodeCountInDC = (MaxNodeId + 2) / 3;
- for (ui32 nodeId : GetNodes()) {
- const TString name = Sprintf("127.0.0.%u", nodeId);
+ for (ui32 nodeId : GetNodes()) {
+ const TString name = Sprintf("127.0.0.%u", nodeId);
ui32 dcNum = isMirror3dc ? ((nodeId + nodeCountInDC - 1) / nodeCountInDC) : 1;
- NActorsInterconnect::TNodeLocation location;
- location.SetDataCenter(ToString(dcNum));
- location.SetRack(ToString(nodeId));
- location.SetUnit(ToString(nodeId));
- setup->StaticNodeTable[nodeId] = {name, name, name, 19001, TNodeLocation(location)};
- }
-
- for (ui32 nodeId : GetNodes()) {
- if (!stateStorageNodeId) {
- stateStorageNodeId = nodeId;
- }
- if (targetNodeId == 0 || targetNodeId == nodeId) {
- SetupStateStorage(nodeId, stateStorageNodeId);
- SetupTabletResolver(nodeId);
- RegisterService(GetNameserviceActorId(), Register(CreateNameserverTable(setup), nodeId));
- }
- }
-}
-
-void TTestActorSystem::SetupStateStorage(ui32 nodeId, ui32 stateStorageNodeId) {
- auto *appData = GetAppData();
- for (const auto& [id, domain] : appData->DomainsInfo->Domains) {
- const ui64 stateStorageGroup = domain->DefaultStateStorageGroup;
- ui32 numReplicas = 3;
-
- auto process = [&](auto&& generateId, auto&& createReplica) {
- auto info = MakeIntrusive<TStateStorageInfo>();
- info->StateStorageGroup = stateStorageGroup;
- info->NToSelect = numReplicas;
- info->Rings.resize(numReplicas);
- for (ui32 i = 0; i < numReplicas; ++i) {
- info->Rings[i].Replicas.push_back(generateId(stateStorageNodeId, stateStorageGroup, i));
- }
- if (nodeId == stateStorageNodeId) {
- for (ui32 i = 0; i < numReplicas; ++i) {
- RegisterService(generateId(stateStorageNodeId, stateStorageGroup, i),
- Register(createReplica(info.Get(), i), nodeId));
- }
- }
- return info;
- };
-
- auto ss = process(MakeStateStorageReplicaID, CreateStateStorageReplica);
- auto b = process(MakeBoardReplicaID, CreateStateStorageBoardReplica);
- auto sb = process(MakeSchemeBoardReplicaID, CreateSchemeBoardReplica);
-
- RegisterService(MakeStateStorageProxyID(stateStorageGroup),
- Register(CreateStateStorageProxy(ss.Get(), b.Get(), sb.Get()), nodeId));
- }
-}
-
-void TTestActorSystem::SetupTabletResolver(ui32 nodeId) {
- RegisterService(MakeTabletResolverID(),
- Register(CreateTabletResolver(MakeIntrusive<TTabletResolverConfig>()), nodeId));
-}
-
-IExecutorPool *TTestActorSystem::CreateTestExecutorPool(ui32 nodeId) {
- return new TTestExecutorPool(this, nodeId);
-}
-
-thread_local TTestActorSystem *TTestActorSystem::CurrentTestActorSystem = nullptr;
-
-TIntrusivePtr<ITimeProvider> TTestActorSystem::CreateTimeProvider() {
- class TTestActorTimeProvider : public ITimeProvider {
- public:
- TInstant Now() override { return CurrentTestActorSystem->Clock; }
- };
- return MakeIntrusive<TTestActorTimeProvider>();
-}
-
-}
+ NActorsInterconnect::TNodeLocation location;
+ location.SetDataCenter(ToString(dcNum));
+ location.SetRack(ToString(nodeId));
+ location.SetUnit(ToString(nodeId));
+ setup->StaticNodeTable[nodeId] = {name, name, name, 19001, TNodeLocation(location)};
+ }
+
+ for (ui32 nodeId : GetNodes()) {
+ if (!stateStorageNodeId) {
+ stateStorageNodeId = nodeId;
+ }
+ if (targetNodeId == 0 || targetNodeId == nodeId) {
+ SetupStateStorage(nodeId, stateStorageNodeId);
+ SetupTabletResolver(nodeId);
+ RegisterService(GetNameserviceActorId(), Register(CreateNameserverTable(setup), nodeId));
+ }
+ }
+}
+
+void TTestActorSystem::SetupStateStorage(ui32 nodeId, ui32 stateStorageNodeId) {
+ auto *appData = GetAppData();
+ for (const auto& [id, domain] : appData->DomainsInfo->Domains) {
+ const ui64 stateStorageGroup = domain->DefaultStateStorageGroup;
+ ui32 numReplicas = 3;
+
+ auto process = [&](auto&& generateId, auto&& createReplica) {
+ auto info = MakeIntrusive<TStateStorageInfo>();
+ info->StateStorageGroup = stateStorageGroup;
+ info->NToSelect = numReplicas;
+ info->Rings.resize(numReplicas);
+ for (ui32 i = 0; i < numReplicas; ++i) {
+ info->Rings[i].Replicas.push_back(generateId(stateStorageNodeId, stateStorageGroup, i));
+ }
+ if (nodeId == stateStorageNodeId) {
+ for (ui32 i = 0; i < numReplicas; ++i) {
+ RegisterService(generateId(stateStorageNodeId, stateStorageGroup, i),
+ Register(createReplica(info.Get(), i), nodeId));
+ }
+ }
+ return info;
+ };
+
+ auto ss = process(MakeStateStorageReplicaID, CreateStateStorageReplica);
+ auto b = process(MakeBoardReplicaID, CreateStateStorageBoardReplica);
+ auto sb = process(MakeSchemeBoardReplicaID, CreateSchemeBoardReplica);
+
+ RegisterService(MakeStateStorageProxyID(stateStorageGroup),
+ Register(CreateStateStorageProxy(ss.Get(), b.Get(), sb.Get()), nodeId));
+ }
+}
+
+void TTestActorSystem::SetupTabletResolver(ui32 nodeId) {
+ RegisterService(MakeTabletResolverID(),
+ Register(CreateTabletResolver(MakeIntrusive<TTabletResolverConfig>()), nodeId));
+}
+
+IExecutorPool *TTestActorSystem::CreateTestExecutorPool(ui32 nodeId) {
+ return new TTestExecutorPool(this, nodeId);
+}
+
+thread_local TTestActorSystem *TTestActorSystem::CurrentTestActorSystem = nullptr;
+
+TIntrusivePtr<ITimeProvider> TTestActorSystem::CreateTimeProvider() {
+ class TTestActorTimeProvider : public ITimeProvider {
+ public:
+ TInstant Now() override { return CurrentTestActorSystem->Clock; }
+ };
+ return MakeIntrusive<TTestActorTimeProvider>();
+}
+
+}
diff --git a/ydb/core/util/testactorsys.h b/ydb/core/util/testactorsys.h
index ce6ad7be10d..dd19bd48de4 100644
--- a/ydb/core/util/testactorsys.h
+++ b/ydb/core/util/testactorsys.h
@@ -1,176 +1,176 @@
-#pragma once
-
-#include "defs.h"
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/mailbox.h>
-#include <library/cpp/actors/core/scheduler_queue.h>
-#include <library/cpp/actors/interconnect/interconnect_common.h>
+#pragma once
+
+#include "defs.h"
+
+#include <library/cpp/actors/core/actor.h>
+#include <library/cpp/actors/core/actorsystem.h>
+#include <library/cpp/actors/core/interconnect.h>
+#include <library/cpp/actors/core/mailbox.h>
+#include <library/cpp/actors/core/scheduler_queue.h>
+#include <library/cpp/actors/interconnect/interconnect_common.h>
#include <ydb/core/base/appdata.h>
#include <ydb/core/base/tablet.h>
#include <ydb/core/base/tablet_pipe.h>
-#include <util/system/env.h>
-
-#include "single_thread_ic_mock.h"
-
-namespace NKikimr {
-
-class TTestActorSystem {
- class TTestSchedulerThread : public ISchedulerThread {
- TTestActorSystem *Context;
- volatile ui64 *CurrentTimestampPtr = nullptr;
- volatile ui64 *CurrentMonotonicPtr = nullptr;
- std::vector<NSchedulerQueue::TReader*> Readers;
- const ui32 NodeId;
-
- public:
- TTestSchedulerThread(TTestActorSystem *context, ui32 nodeId)
- : Context(context)
- , NodeId(nodeId)
- {}
-
- void Prepare(TActorSystem* /*actorSystem*/, volatile ui64 *currentTimestamp, volatile ui64 *currentMonotonic) override {
- CurrentTimestampPtr = currentTimestamp;
- CurrentMonotonicPtr = currentMonotonic;
- }
-
+#include <util/system/env.h>
+
+#include "single_thread_ic_mock.h"
+
+namespace NKikimr {
+
+class TTestActorSystem {
+ class TTestSchedulerThread : public ISchedulerThread {
+ TTestActorSystem *Context;
+ volatile ui64 *CurrentTimestampPtr = nullptr;
+ volatile ui64 *CurrentMonotonicPtr = nullptr;
+ std::vector<NSchedulerQueue::TReader*> Readers;
+ const ui32 NodeId;
+
+ public:
+ TTestSchedulerThread(TTestActorSystem *context, ui32 nodeId)
+ : Context(context)
+ , NodeId(nodeId)
+ {}
+
+ void Prepare(TActorSystem* /*actorSystem*/, volatile ui64 *currentTimestamp, volatile ui64 *currentMonotonic) override {
+ CurrentTimestampPtr = currentTimestamp;
+ CurrentMonotonicPtr = currentMonotonic;
+ }
+
void PrepareSchedules(NSchedulerQueue::TReader **readers, ui32 scheduleReadersCount) override {
- Readers = {readers, readers + scheduleReadersCount};
- }
-
- void AdjustClock(TInstant clock) {
- *CurrentTimestampPtr = clock.MicroSeconds();
- *CurrentMonotonicPtr = clock.MicroSeconds();
- }
-
- bool TransferSchedule() {
- bool res = false;
- for (NSchedulerQueue::TReader *reader : Readers) {
- while (NSchedulerQueue::TEntry *e = reader->Pop()) {
- Context->Schedule(TInstant::MicroSeconds(e->InstantMicroseconds), e->Ev, e->Cookie, NodeId);
- res = true;
- }
- }
- return res;
- }
-
- void Start() override {}
- void PrepareStop() override {}
- void Stop() override {}
- };
-
- struct TScheduleItem {
- std::unique_ptr<IEventHandle> Event;
- ISchedulerCookie *Cookie;
- ui32 NodeId;
-
- TScheduleItem(TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId)
- : Event(ev.Release())
- , Cookie(cookie)
- , NodeId(nodeId)
- {}
- };
-
- struct TMailboxId : std::tuple<ui32, ui32, ui32> { // NodeId, PoolId, Hint
- TMailboxId(const TActorId& actorId)
- : TMailboxId(actorId.NodeId(), actorId.PoolID(), actorId.Hint())
- {}
-
- TMailboxId(ui32 nodeId, ui32 poolId, ui32 hint)
- : std::tuple<ui32, ui32, ui32>(nodeId, poolId, hint)
- {}
- };
-
- struct TPerNodeInfo {
- std::unique_ptr<TActorSystem> ActorSystem;
- std::unique_ptr<TMailboxTable> MailboxTable;
- std::unique_ptr<TExecutorThread> ExecutorThread;
- std::unordered_map<ui32, TActorId> InterconnectProxy;
- TTestSchedulerThread *SchedulerThread;
- ui32 NextHint = 1;
- };
-
- struct TMailboxInfo {
- TMailboxHeader Header{TMailboxType::Simple};
- ui64 ActorLocalId = 1;
- };
-
- const ui32 MaxNodeId;
- std::map<TInstant, std::deque<TScheduleItem>> ScheduleQ;
- TInstant Clock = TInstant::Zero();
- std::unordered_map<TMailboxId, TMailboxInfo, THash<std::tuple<ui32, ui32, ui32>>> Mailboxes;
- TProgramShouldContinue ProgramShouldContinue;
- TAppData AppData;
- TIntrusivePtr<NLog::TSettings> LoggerSettings_;
- TActorId CurrentRecipient;
- ui32 CurrentNodeId = 0;
- ui64 EventsProcessed = 0;
- std::unordered_map<ui32, TPerNodeInfo> PerNodeInfo;
- TSingleThreadInterconnectMock InterconnectMock;
- std::set<TActorId> LoggerActorIds;
-
- static thread_local TTestActorSystem *CurrentTestActorSystem;
-
- struct TEventProcessingStat {
- ui64 HitCount;
- TDuration TotalTime;
- };
- std::unordered_map<std::pair<TString, ui32>, TEventProcessingStat> EventProcessingStats;
- std::unordered_map<ui32, TString> EventName;
-
- struct TActorStats {
- ui64 Created = 0;
- ui64 Destroyed = 0;
-
- friend bool operator <(const TActorStats& x, const TActorStats& y) {
- return x.Created - x.Destroyed > y.Created - y.Destroyed;
- }
- };
- std::unordered_map<TString, TActorStats> ActorStats;
- std::unordered_map<IActor*, TString> ActorName;
-
- class TEdgeActor : public TActor<TEdgeActor> {
- std::unique_ptr<IEventHandle> *HandlePtr = nullptr;
- TString Tag;
-
- public:
- TEdgeActor(const char *file, int line)
- : TActor(&TThis::StateFunc)
- , Tag(TStringBuilder() << file << ":" << line)
- {}
-
- void WaitForEvent(std::unique_ptr<IEventHandle> *handlePtr) {
- Y_VERIFY(!HandlePtr);
- HandlePtr = handlePtr;
- }
-
- void StopWaitingForEvent() {
- Y_VERIFY(HandlePtr);
- HandlePtr = nullptr;
- }
-
- void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& /*ctx*/) {
- Y_VERIFY(HandlePtr, "event is not being captured by this actor Tag# %s", Tag.data());
- Y_VERIFY(!*HandlePtr);
- HandlePtr->reset(ev.Release());
- }
- };
-
-public:
- std::function<bool(ui32, IEventHandle&)> FilterFunction;
- IOutputStream *LogStream = &Cerr;
-
-public:
- TTestActorSystem(ui32 numNodes, NLog::EPriority defaultPrio = NLog::PRI_ERROR)
- : MaxNodeId(numNodes)
- , AppData(0, 0, 0, 0, {{"IC", 0}}, nullptr, nullptr, nullptr, &ProgramShouldContinue)
- , LoggerSettings_(MakeIntrusive<NLog::TSettings>(TActorId(0, "logger"), NKikimrServices::LOGGER, defaultPrio))
- , InterconnectMock(0, Max<ui64>(), this) // burst capacity (bytes), bytes per second
- {
- AppData.Counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
- AppData.DomainsInfo = MakeIntrusive<TDomainsInfo>();
+ Readers = {readers, readers + scheduleReadersCount};
+ }
+
+ void AdjustClock(TInstant clock) {
+ *CurrentTimestampPtr = clock.MicroSeconds();
+ *CurrentMonotonicPtr = clock.MicroSeconds();
+ }
+
+ bool TransferSchedule() {
+ bool res = false;
+ for (NSchedulerQueue::TReader *reader : Readers) {
+ while (NSchedulerQueue::TEntry *e = reader->Pop()) {
+ Context->Schedule(TInstant::MicroSeconds(e->InstantMicroseconds), e->Ev, e->Cookie, NodeId);
+ res = true;
+ }
+ }
+ return res;
+ }
+
+ void Start() override {}
+ void PrepareStop() override {}
+ void Stop() override {}
+ };
+
+ struct TScheduleItem {
+ std::unique_ptr<IEventHandle> Event;
+ ISchedulerCookie *Cookie;
+ ui32 NodeId;
+
+ TScheduleItem(TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId)
+ : Event(ev.Release())
+ , Cookie(cookie)
+ , NodeId(nodeId)
+ {}
+ };
+
+ struct TMailboxId : std::tuple<ui32, ui32, ui32> { // NodeId, PoolId, Hint
+ TMailboxId(const TActorId& actorId)
+ : TMailboxId(actorId.NodeId(), actorId.PoolID(), actorId.Hint())
+ {}
+
+ TMailboxId(ui32 nodeId, ui32 poolId, ui32 hint)
+ : std::tuple<ui32, ui32, ui32>(nodeId, poolId, hint)
+ {}
+ };
+
+ struct TPerNodeInfo {
+ std::unique_ptr<TActorSystem> ActorSystem;
+ std::unique_ptr<TMailboxTable> MailboxTable;
+ std::unique_ptr<TExecutorThread> ExecutorThread;
+ std::unordered_map<ui32, TActorId> InterconnectProxy;
+ TTestSchedulerThread *SchedulerThread;
+ ui32 NextHint = 1;
+ };
+
+ struct TMailboxInfo {
+ TMailboxHeader Header{TMailboxType::Simple};
+ ui64 ActorLocalId = 1;
+ };
+
+ const ui32 MaxNodeId;
+ std::map<TInstant, std::deque<TScheduleItem>> ScheduleQ;
+ TInstant Clock = TInstant::Zero();
+ std::unordered_map<TMailboxId, TMailboxInfo, THash<std::tuple<ui32, ui32, ui32>>> Mailboxes;
+ TProgramShouldContinue ProgramShouldContinue;
+ TAppData AppData;
+ TIntrusivePtr<NLog::TSettings> LoggerSettings_;
+ TActorId CurrentRecipient;
+ ui32 CurrentNodeId = 0;
+ ui64 EventsProcessed = 0;
+ std::unordered_map<ui32, TPerNodeInfo> PerNodeInfo;
+ TSingleThreadInterconnectMock InterconnectMock;
+ std::set<TActorId> LoggerActorIds;
+
+ static thread_local TTestActorSystem *CurrentTestActorSystem;
+
+ struct TEventProcessingStat {
+ ui64 HitCount;
+ TDuration TotalTime;
+ };
+ std::unordered_map<std::pair<TString, ui32>, TEventProcessingStat> EventProcessingStats;
+ std::unordered_map<ui32, TString> EventName;
+
+ struct TActorStats {
+ ui64 Created = 0;
+ ui64 Destroyed = 0;
+
+ friend bool operator <(const TActorStats& x, const TActorStats& y) {
+ return x.Created - x.Destroyed > y.Created - y.Destroyed;
+ }
+ };
+ std::unordered_map<TString, TActorStats> ActorStats;
+ std::unordered_map<IActor*, TString> ActorName;
+
+ class TEdgeActor : public TActor<TEdgeActor> {
+ std::unique_ptr<IEventHandle> *HandlePtr = nullptr;
+ TString Tag;
+
+ public:
+ TEdgeActor(const char *file, int line)
+ : TActor(&TThis::StateFunc)
+ , Tag(TStringBuilder() << file << ":" << line)
+ {}
+
+ void WaitForEvent(std::unique_ptr<IEventHandle> *handlePtr) {
+ Y_VERIFY(!HandlePtr);
+ HandlePtr = handlePtr;
+ }
+
+ void StopWaitingForEvent() {
+ Y_VERIFY(HandlePtr);
+ HandlePtr = nullptr;
+ }
+
+ void StateFunc(TAutoPtr<IEventHandle>& ev, const TActorContext& /*ctx*/) {
+ Y_VERIFY(HandlePtr, "event is not being captured by this actor Tag# %s", Tag.data());
+ Y_VERIFY(!*HandlePtr);
+ HandlePtr->reset(ev.Release());
+ }
+ };
+
+public:
+ std::function<bool(ui32, IEventHandle&)> FilterFunction;
+ IOutputStream *LogStream = &Cerr;
+
+public:
+ TTestActorSystem(ui32 numNodes, NLog::EPriority defaultPrio = NLog::PRI_ERROR)
+ : MaxNodeId(numNodes)
+ , AppData(0, 0, 0, 0, {{"IC", 0}}, nullptr, nullptr, nullptr, &ProgramShouldContinue)
+ , LoggerSettings_(MakeIntrusive<NLog::TSettings>(TActorId(0, "logger"), NKikimrServices::LOGGER, defaultPrio))
+ , InterconnectMock(0, Max<ui64>(), this) // burst capacity (bytes), bytes per second
+ {
+ AppData.Counters = MakeIntrusive<NMonitoring::TDynamicCounters>();
+ AppData.DomainsInfo = MakeIntrusive<TDomainsInfo>();
LoggerSettings_->Append(
NActorsServices::EServiceCommon_MIN,
NActorsServices::EServiceCommon_MAX,
@@ -178,526 +178,526 @@ public:
);
LoggerSettings_->Append(
NKikimrServices::EServiceKikimr_MIN,
- NKikimrServices::EServiceKikimr_MAX,
+ NKikimrServices::EServiceKikimr_MAX,
NKikimrServices::EServiceKikimr_Name
);
- for (ui32 i = 0; i < numNodes; ++i) {
- PerNodeInfo.emplace(i + 1, TPerNodeInfo());
- }
-
- Y_VERIFY(!CurrentTestActorSystem);
- CurrentTestActorSystem = this;
- }
-
- ~TTestActorSystem() {
- Y_VERIFY(CurrentTestActorSystem == this);
- CurrentTestActorSystem = nullptr;
- }
-
- static TIntrusivePtr<ITimeProvider> CreateTimeProvider();
-
- TAppData *GetAppData() {
- return &AppData;
- }
-
- void Start() {
- for (auto& [nodeId, info] : PerNodeInfo) {
- SetupNode(nodeId, info);
- }
- LoggerActorIds.insert(LoggerSettings_->LoggerActorId);
- for (auto& [nodeId, info] : PerNodeInfo) {
- StartNode(nodeId);
- }
- }
-
- void SetupNode(ui32 nodeId, TPerNodeInfo& info) {
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = nodeId;
- setup->ExecutorsCount = 1;
- info.SchedulerThread = new TTestSchedulerThread(this, nodeId);
- setup->Scheduler.Reset(info.SchedulerThread);
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
- IExecutorPool *pool = CreateTestExecutorPool(nodeId);
- setup->Executors[0].Reset(pool);
-
- // we create this actor for correct service lookup through ActorSystem
- setup->LocalServices.emplace_back(LoggerSettings_->LoggerActorId, TActorSetupCmd(
- new TEdgeActor(__FILE__, __LINE__), TMailboxType::Simple, 0));
-
- auto common = MakeIntrusive<TInterconnectProxyCommon>();
- auto& proxyActors = setup->Interconnect.ProxyActors;
- proxyActors.resize(MaxNodeId + 1);
- for (const auto& [peerNodeId, peerInfo] : PerNodeInfo) {
- if (peerNodeId != nodeId) {
- proxyActors[peerNodeId] = TActorSetupCmd(InterconnectMock.CreateProxyActor(nodeId, peerNodeId,
- common).release(), TMailboxType::Simple, 0);
- }
- }
-
- info.ActorSystem = std::make_unique<TActorSystem>(setup, &AppData, LoggerSettings_);
- info.MailboxTable = std::make_unique<TMailboxTable>();
- info.ExecutorThread = std::make_unique<TExecutorThread>(0, 0, info.ActorSystem.get(), pool,
- info.MailboxTable.get(), "TestExecutor");
- }
-
- void StartNode(ui32 nodeId) {
- TPerNodeInfo& info = PerNodeInfo.at(nodeId);
- CurrentNodeId = nodeId;
- info.ActorSystem->Start();
- LoggerActorIds.insert(info.ActorSystem->LookupLocalService(LoggerSettings_->LoggerActorId));
- CurrentNodeId = 0;
- }
-
- void StopNode(ui32 nodeId) {
- TPerNodeInfo& info = PerNodeInfo.at(nodeId);
- info.ActorSystem->Stop();
-
- for (;;) {
- // delete all mailboxes from this node (expecting that new one can be created during deletion)
- const TMailboxId from(nodeId, 0, 0);
- const TMailboxId to(nodeId + 1, 0, 0);
- bool found = false;
- for (auto it = Mailboxes.begin(); it != Mailboxes.end(); ) {
- if (from <= it->first && it->first < to) {
- TMailboxInfo& mbox = it->second;
- mbox.Header.ForEach([&](ui64 /*actorId*/, IActor *actor) { ActorName.erase(actor); });
- mbox.Header.CleanupActors();
- it = Mailboxes.erase(it);
- found = true;
- } else {
- ++it;
- }
- }
- if (found) {
- continue;
- }
-
- std::deque<TScheduleItem> deleteQueue;
- auto it = ScheduleQ.begin();
- while (it != ScheduleQ.end()) {
- auto& queue = it->second;
- bool found = false;
- for (auto& item : queue) {
- if (item.NodeId == nodeId) {
- found = true;
- break;
- }
- }
- if (found) {
- std::deque<TScheduleItem> newQueue;
- for (auto& item : queue) {
- (item.NodeId == nodeId ? deleteQueue : newQueue).push_back(std::move(item));
- }
- queue.swap(newQueue);
- it = queue.empty() ? ScheduleQ.erase(it) : std::next(it);
- } else {
- ++it;
- }
- }
- if (deleteQueue.empty()) {
- break;
- }
- }
-
- PerNodeInfo.erase(nodeId);
- SetupNode(nodeId, PerNodeInfo[nodeId]);
- }
-
- void Stop() {
- ProgramShouldContinue.ShouldStop();
- for (auto& [nodeId, info] : PerNodeInfo) {
- info.ActorSystem->Stop();
- }
- for (;;) {
- // exchange container to prevent side-effects while destroying actors (they may use actor system in dtors);
- // do this in cycle because actor destructor code may spawn more actors
- auto temp = std::exchange(Mailboxes, {});
- ActorName.clear();
- if (temp.empty()) {
- break;
- }
- temp.clear();
-
- auto temp1 = std::exchange(ScheduleQ, {});
- temp1.clear();
- }
- // dump event processing stats
- int dump;
- if (TryFromString(GetEnv("TESTACTORSYS_DUMP_TIMESTATS", "0"), dump) && dump) {
- std::vector<std::pair<TDuration, TString>> items;
- for (auto& [key, stats] : std::exchange(EventProcessingStats, {})) {
- const auto& [actorName, type] = key;
- items.emplace_back(stats.TotalTime, TStringBuilder() << actorName << "." << GetEventName(type)
- << " " << stats.TotalTime << " " << stats.HitCount);
- }
- std::sort(items.begin(), items.end());
- for (const auto& [key, value] : items) {
- Cerr << value << Endl;
- }
- }
- }
-
- TString GetEventName(ui32 type) const {
- const auto it = EventName.find(type);
- return it != EventName.end() ? it->second : Sprintf("0x%08" PRIx32, type);
- }
-
- void SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority) {
- TString explanation;
- int res = LoggerSettings_->SetLevel(priority, component, explanation);
- Y_VERIFY(!res, "failed to set log level: %s", explanation.data());
- }
-
- bool Send(IEventHandle *ev, ui32 nodeId = 0) {
- TAutoPtr<IEventHandle> wrapper(ev);
- return Send(wrapper, nodeId);
- }
-
- bool Send(TAutoPtr<IEventHandle>& ev, ui32 nodeId) {
- if (!ev) {
- return false;
- } else if (LoggerActorIds.count(ev->GetRecipientRewrite()) && ev->GetTypeRewrite() == NLog::TEvLog::EventType) {
- auto *msg = ev->CastAsLocal<NLog::TEvLog>();
- ui64 microsec = Clock.MicroSeconds();
- const unsigned frac = microsec % 1000000;
- microsec /= 1000000;
- const unsigned seconds = microsec % 60;
- microsec /= 60;
- const unsigned minutes = microsec % 60;
- microsec /= 60;
- const unsigned hours = microsec;
- TString clock = Sprintf("%02uh%02um%02u.%06us", hours, minutes, seconds, frac);
- *LogStream << (TStringBuilder() << msg->Stamp << " " << nodeId << " " << clock << " :"
- << LoggerSettings_->ComponentName(msg->Component) << " " << NLog::PriorityToString(msg->Level.ToPrio())
- << ": " << msg->Line << Endl);
- return true;
- }
-
- nodeId = nodeId ? nodeId : CurrentNodeId;
- Y_VERIFY(nodeId);
-
- // check if the target actor exists; we have to transform the event recipient early to keep behaviour of real
- // actor system here
- if (GetActor(TransformEvent(ev.Get(), nodeId))) {
- Schedule(Clock, ev, nullptr, nodeId);
- return true;
- } else {
- TAutoPtr<IEventHandle> wrapper(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown));
- Send(wrapper, nodeId);
- return false;
- }
- }
-
- IActor *GetActor(const TActorId& actorId, TMailboxHeader **header = nullptr) {
- if (const auto it = Mailboxes.find(actorId); it != Mailboxes.end()) {
- TMailboxInfo& mbox = it->second;
- if (header) {
- *header = &mbox.Header;
- }
- return mbox.Header.FindActor(actorId.LocalId());
- } else {
- return nullptr;
- }
- }
-
- void Schedule(TInstant ts, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId) {
- Y_VERIFY(ts >= Clock);
- nodeId = nodeId ? nodeId : CurrentNodeId;
- Y_VERIFY(nodeId);
- if (ev && ev->HasEvent() && ev->GetTypeRewrite() == ev->Type && !EventName.count(ev->Type)) {
- EventName.emplace(ev->Type, TypeName(*ev->GetBase()));
- }
- ScheduleQ[ts].emplace_back(ev, cookie, nodeId);
- }
-
- void Schedule(TDuration timeout, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId) {
- Schedule(Clock + timeout, ev, cookie, nodeId);
- }
-
- TActorId Register(IActor *actor, const TActorId& parentId = TActorId(), ui32 poolId = 0, std::optional<ui32> hint = std::nullopt,
- ui32 nodeId = 0) {
- // count stats
+ for (ui32 i = 0; i < numNodes; ++i) {
+ PerNodeInfo.emplace(i + 1, TPerNodeInfo());
+ }
+
+ Y_VERIFY(!CurrentTestActorSystem);
+ CurrentTestActorSystem = this;
+ }
+
+ ~TTestActorSystem() {
+ Y_VERIFY(CurrentTestActorSystem == this);
+ CurrentTestActorSystem = nullptr;
+ }
+
+ static TIntrusivePtr<ITimeProvider> CreateTimeProvider();
+
+ TAppData *GetAppData() {
+ return &AppData;
+ }
+
+ void Start() {
+ for (auto& [nodeId, info] : PerNodeInfo) {
+ SetupNode(nodeId, info);
+ }
+ LoggerActorIds.insert(LoggerSettings_->LoggerActorId);
+ for (auto& [nodeId, info] : PerNodeInfo) {
+ StartNode(nodeId);
+ }
+ }
+
+ void SetupNode(ui32 nodeId, TPerNodeInfo& info) {
+ auto setup = MakeHolder<TActorSystemSetup>();
+ setup->NodeId = nodeId;
+ setup->ExecutorsCount = 1;
+ info.SchedulerThread = new TTestSchedulerThread(this, nodeId);
+ setup->Scheduler.Reset(info.SchedulerThread);
+ setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
+ IExecutorPool *pool = CreateTestExecutorPool(nodeId);
+ setup->Executors[0].Reset(pool);
+
+ // we create this actor for correct service lookup through ActorSystem
+ setup->LocalServices.emplace_back(LoggerSettings_->LoggerActorId, TActorSetupCmd(
+ new TEdgeActor(__FILE__, __LINE__), TMailboxType::Simple, 0));
+
+ auto common = MakeIntrusive<TInterconnectProxyCommon>();
+ auto& proxyActors = setup->Interconnect.ProxyActors;
+ proxyActors.resize(MaxNodeId + 1);
+ for (const auto& [peerNodeId, peerInfo] : PerNodeInfo) {
+ if (peerNodeId != nodeId) {
+ proxyActors[peerNodeId] = TActorSetupCmd(InterconnectMock.CreateProxyActor(nodeId, peerNodeId,
+ common).release(), TMailboxType::Simple, 0);
+ }
+ }
+
+ info.ActorSystem = std::make_unique<TActorSystem>(setup, &AppData, LoggerSettings_);
+ info.MailboxTable = std::make_unique<TMailboxTable>();
+ info.ExecutorThread = std::make_unique<TExecutorThread>(0, 0, info.ActorSystem.get(), pool,
+ info.MailboxTable.get(), "TestExecutor");
+ }
+
+ void StartNode(ui32 nodeId) {
+ TPerNodeInfo& info = PerNodeInfo.at(nodeId);
+ CurrentNodeId = nodeId;
+ info.ActorSystem->Start();
+ LoggerActorIds.insert(info.ActorSystem->LookupLocalService(LoggerSettings_->LoggerActorId));
+ CurrentNodeId = 0;
+ }
+
+ void StopNode(ui32 nodeId) {
+ TPerNodeInfo& info = PerNodeInfo.at(nodeId);
+ info.ActorSystem->Stop();
+
+ for (;;) {
+ // delete all mailboxes from this node (expecting that new one can be created during deletion)
+ const TMailboxId from(nodeId, 0, 0);
+ const TMailboxId to(nodeId + 1, 0, 0);
+ bool found = false;
+ for (auto it = Mailboxes.begin(); it != Mailboxes.end(); ) {
+ if (from <= it->first && it->first < to) {
+ TMailboxInfo& mbox = it->second;
+ mbox.Header.ForEach([&](ui64 /*actorId*/, IActor *actor) { ActorName.erase(actor); });
+ mbox.Header.CleanupActors();
+ it = Mailboxes.erase(it);
+ found = true;
+ } else {
+ ++it;
+ }
+ }
+ if (found) {
+ continue;
+ }
+
+ std::deque<TScheduleItem> deleteQueue;
+ auto it = ScheduleQ.begin();
+ while (it != ScheduleQ.end()) {
+ auto& queue = it->second;
+ bool found = false;
+ for (auto& item : queue) {
+ if (item.NodeId == nodeId) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ std::deque<TScheduleItem> newQueue;
+ for (auto& item : queue) {
+ (item.NodeId == nodeId ? deleteQueue : newQueue).push_back(std::move(item));
+ }
+ queue.swap(newQueue);
+ it = queue.empty() ? ScheduleQ.erase(it) : std::next(it);
+ } else {
+ ++it;
+ }
+ }
+ if (deleteQueue.empty()) {
+ break;
+ }
+ }
+
+ PerNodeInfo.erase(nodeId);
+ SetupNode(nodeId, PerNodeInfo[nodeId]);
+ }
+
+ void Stop() {
+ ProgramShouldContinue.ShouldStop();
+ for (auto& [nodeId, info] : PerNodeInfo) {
+ info.ActorSystem->Stop();
+ }
+ for (;;) {
+ // exchange container to prevent side-effects while destroying actors (they may use actor system in dtors);
+ // do this in cycle because actor destructor code may spawn more actors
+ auto temp = std::exchange(Mailboxes, {});
+ ActorName.clear();
+ if (temp.empty()) {
+ break;
+ }
+ temp.clear();
+
+ auto temp1 = std::exchange(ScheduleQ, {});
+ temp1.clear();
+ }
+ // dump event processing stats
+ int dump;
+ if (TryFromString(GetEnv("TESTACTORSYS_DUMP_TIMESTATS", "0"), dump) && dump) {
+ std::vector<std::pair<TDuration, TString>> items;
+ for (auto& [key, stats] : std::exchange(EventProcessingStats, {})) {
+ const auto& [actorName, type] = key;
+ items.emplace_back(stats.TotalTime, TStringBuilder() << actorName << "." << GetEventName(type)
+ << " " << stats.TotalTime << " " << stats.HitCount);
+ }
+ std::sort(items.begin(), items.end());
+ for (const auto& [key, value] : items) {
+ Cerr << value << Endl;
+ }
+ }
+ }
+
+ TString GetEventName(ui32 type) const {
+ const auto it = EventName.find(type);
+ return it != EventName.end() ? it->second : Sprintf("0x%08" PRIx32, type);
+ }
+
+ void SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority) {
+ TString explanation;
+ int res = LoggerSettings_->SetLevel(priority, component, explanation);
+ Y_VERIFY(!res, "failed to set log level: %s", explanation.data());
+ }
+
+ bool Send(IEventHandle *ev, ui32 nodeId = 0) {
+ TAutoPtr<IEventHandle> wrapper(ev);
+ return Send(wrapper, nodeId);
+ }
+
+ bool Send(TAutoPtr<IEventHandle>& ev, ui32 nodeId) {
+ if (!ev) {
+ return false;
+ } else if (LoggerActorIds.count(ev->GetRecipientRewrite()) && ev->GetTypeRewrite() == NLog::TEvLog::EventType) {
+ auto *msg = ev->CastAsLocal<NLog::TEvLog>();
+ ui64 microsec = Clock.MicroSeconds();
+ const unsigned frac = microsec % 1000000;
+ microsec /= 1000000;
+ const unsigned seconds = microsec % 60;
+ microsec /= 60;
+ const unsigned minutes = microsec % 60;
+ microsec /= 60;
+ const unsigned hours = microsec;
+ TString clock = Sprintf("%02uh%02um%02u.%06us", hours, minutes, seconds, frac);
+ *LogStream << (TStringBuilder() << msg->Stamp << " " << nodeId << " " << clock << " :"
+ << LoggerSettings_->ComponentName(msg->Component) << " " << NLog::PriorityToString(msg->Level.ToPrio())
+ << ": " << msg->Line << Endl);
+ return true;
+ }
+
+ nodeId = nodeId ? nodeId : CurrentNodeId;
+ Y_VERIFY(nodeId);
+
+ // check if the target actor exists; we have to transform the event recipient early to keep behaviour of real
+ // actor system here
+ if (GetActor(TransformEvent(ev.Get(), nodeId))) {
+ Schedule(Clock, ev, nullptr, nodeId);
+ return true;
+ } else {
+ TAutoPtr<IEventHandle> wrapper(ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown));
+ Send(wrapper, nodeId);
+ return false;
+ }
+ }
+
+ IActor *GetActor(const TActorId& actorId, TMailboxHeader **header = nullptr) {
+ if (const auto it = Mailboxes.find(actorId); it != Mailboxes.end()) {
+ TMailboxInfo& mbox = it->second;
+ if (header) {
+ *header = &mbox.Header;
+ }
+ return mbox.Header.FindActor(actorId.LocalId());
+ } else {
+ return nullptr;
+ }
+ }
+
+ void Schedule(TInstant ts, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId) {
+ Y_VERIFY(ts >= Clock);
+ nodeId = nodeId ? nodeId : CurrentNodeId;
+ Y_VERIFY(nodeId);
+ if (ev && ev->HasEvent() && ev->GetTypeRewrite() == ev->Type && !EventName.count(ev->Type)) {
+ EventName.emplace(ev->Type, TypeName(*ev->GetBase()));
+ }
+ ScheduleQ[ts].emplace_back(ev, cookie, nodeId);
+ }
+
+ void Schedule(TDuration timeout, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, ui32 nodeId) {
+ Schedule(Clock + timeout, ev, cookie, nodeId);
+ }
+
+ TActorId Register(IActor *actor, const TActorId& parentId = TActorId(), ui32 poolId = 0, std::optional<ui32> hint = std::nullopt,
+ ui32 nodeId = 0) {
+ // count stats
TString name = TypeName(*actor);
- ++ActorStats[name].Created;
- const bool inserted = ActorName.emplace(actor, std::move(name)).second;
- Y_VERIFY(inserted);
-
- // specify node id if not provided
- nodeId = nodeId ? nodeId : CurrentNodeId;
- TPerNodeInfo *info = GetNode(nodeId);
-
- // allocate mailbox id if needed
- const ui32 mboxId = hint.value_or(info->NextHint);
- if (mboxId == info->NextHint) {
- ++info->NextHint;
- }
-
- // register actor in mailbox
- const auto& it = Mailboxes.try_emplace(TMailboxId(nodeId, poolId, mboxId)).first;
- TMailboxInfo& mbox = it->second;
- mbox.Header.AttachActor(mbox.ActorLocalId, actor);
-
- // generate actor id
- const TActorId actorId(nodeId, poolId, mbox.ActorLocalId, mboxId);
- ++mbox.ActorLocalId;
-
- // initialize actor in actor system
- DoActorInit(info->ActorSystem.get(), actor, actorId, parentId ? parentId : CurrentRecipient);
-
- return actorId;
- }
-
- TActorId Register(IActor *actor, ui32 nodeId, ui32 poolId = 0) {
- return Register(actor, {}, poolId, {}, nodeId);
- }
-
- void RegisterService(const TActorId& serviceId, const TActorId& actorId) {
- const ui32 nodeId = actorId.NodeId(); // only at the node with the actor
- GetNode(nodeId)->ActorSystem->RegisterLocalService(serviceId, actorId);
- }
-
- template<typename TCallback>
- void Sim(TCallback&& callback, std::function<void(IEventHandle&)> witness = {}) {
- bool progress = true;
-
- while (callback()) {
- Y_VERIFY(progress, "test actor system stalled -- no progress made"); // ensure we are doing progress
-
- // obtain event with least time
- std::optional<TScheduleItem> item;
- while (!ScheduleQ.empty()) {
- const auto it = ScheduleQ.begin();
- auto& [timestamp, items] = *it;
- Y_VERIFY(timestamp >= Clock || items.empty());
- if (items.empty()) {
- ScheduleQ.erase(it);
- } else {
- Clock = timestamp;
- item.emplace(std::move(items.front()));
- items.pop_front();
- break;
- }
- }
-
- progress = item.has_value();
- if (!item || (item->Cookie && !item->Cookie->Detach())) {
- continue;
- }
-
- std::unique_ptr<IEventHandle>& event = item->Event;
- if (witness) {
- witness(*event);
- }
- if (FilterFunction && !FilterFunction(item->NodeId, *event)) {
- continue;
- }
- WrapInActorContext(TransformEvent(event.get(), item->NodeId), [&](IActor *actor) {
- TAutoPtr<IEventHandle> ev(event.release());
-
- const ui32 type = ev->GetTypeRewrite();
-
- THPTimer timer;
- actor->Receive(ev, TActivationContext::AsActorContext());
- const TDuration timing = TDuration::Seconds(timer.Passed());
-
- const auto it = ActorName.find(actor);
- Y_VERIFY(it != ActorName.end(), "%p", actor);
-
- auto& stats = EventProcessingStats[std::make_pair(it->second, type)];
- ++stats.HitCount;
- stats.TotalTime += timing;
-
- ++EventsProcessed;
- });
- }
- }
-
- template<typename TCallback>
- void WrapInActorContext(TActorId actorId, TCallback&& callback) {
- const auto mboxIt = Mailboxes.find(actorId);
- if (mboxIt == Mailboxes.end()) {
- return;
- }
- TMailboxInfo& mbox = mboxIt->second;
- if (IActor *actor = mbox.Header.FindActor(actorId.LocalId())) {
- // obtain node info for this actor
- TPerNodeInfo *info = GetNode(actorId.NodeId());
-
- // adjust clock for correct operation
- info->SchedulerThread->AdjustClock(Clock);
-
- // allocate context and store its reference in TLS
- TActorContext ctx(mbox.Header, *info->ExecutorThread, GetCycleCountFast(), actorId);
- TlsActivationContext = &ctx;
- CurrentRecipient = actorId;
- CurrentNodeId = actorId.NodeId();
-
- // invoke the callback
- if constexpr (std::is_invocable_v<TCallback, IActor*>) {
- std::invoke(std::forward<TCallback>(callback), actor);
- } else {
- std::invoke(std::forward<TCallback>(callback));
- }
-
- // forget about the context
- TlsActivationContext = nullptr;
- CurrentRecipient = {};
- CurrentNodeId = 0;
-
- // read possibly updated schedule
- info->SchedulerThread->TransferSchedule();
-
- // remove destroyed actors from the mailbox
- for (const auto& actor : info->ExecutorThread->GetUnregistered()) {
- const TActorId& actorId = actor->SelfId();
- Y_VERIFY(TMailboxId(actorId) == mboxIt->first);
- const auto nameIt = ActorName.find(actor.Get());
- Y_VERIFY(nameIt != ActorName.end());
- ++ActorStats[nameIt->second].Destroyed;
- ActorName.erase(nameIt);
- }
-
- // terminate dead actors
- info->ExecutorThread->DropUnregistered();
-
- // drop the mailbox if no actors remain there
- if (mbox.Header.IsEmpty()) {
- Mailboxes.erase(mboxIt);
- }
- }
- }
-
- TActorId AllocateEdgeActor(ui32 nodeId, const char *file = "", int line = 0) {
- return Register(new TEdgeActor(file, line), TActorId(), 0, std::nullopt, nodeId);
- }
-
- std::unique_ptr<IEventHandle> WaitForEdgeActorEvent(const std::set<TActorId>& edgeActorIds) {
- std::unique_ptr<IEventHandle> res;
- std::vector<TEdgeActor*> edges;
- for (const TActorId& edgeActorId : edgeActorIds) {
- TEdgeActor *edge = dynamic_cast<TEdgeActor*>(GetActor(edgeActorId));
- Y_VERIFY(edge);
- edge->WaitForEvent(&res);
- edges.push_back(edge);
- }
- Sim([&] { return !res; });
- for (TEdgeActor *edge : edges) {
- edge->StopWaitingForEvent();
- }
- return res;
- }
-
- void DestroyActor(TActorId actorId) {
- // find per-node info for this actor
- TPerNodeInfo *info = GetNode(actorId.NodeId());
- Y_VERIFY(info);
-
- // find mailbox
- auto it = Mailboxes.find(actorId);
- Y_VERIFY(it != Mailboxes.end());
- TMailboxInfo& mbox = it->second;
-
- // update stats
- const auto nameIt = ActorName.find(mbox.Header.FindActor(actorId.LocalId()));
- Y_VERIFY(nameIt != ActorName.end());
- ++ActorStats[nameIt->second].Destroyed;
- ActorName.erase(nameIt);
-
- // unregister actor through the executor
- info->ExecutorThread->UnregisterActor(&mbox.Header, actorId.LocalId());
-
- // terminate unregistered actor
- info->ExecutorThread->DropUnregistered();
-
- // delete mailbox if empty
- if (mbox.Header.IsEmpty()) {
- Mailboxes.erase(actorId);
- }
- }
-
- std::set<ui32> GetNodes() const {
- std::set<ui32> res;
- for (const auto& [nodeId, info] : PerNodeInfo) {
- res.insert(nodeId);
- }
- return res;
- }
-
- ui32 GetNodeCount() const {
- return PerNodeInfo.size();
- }
-
- NLog::TSettings *LoggerSettings() const {
- return LoggerSettings_.Get();
- }
-
- void DumpActorCount(IOutputStream& s, const TString& prefix, const TString& suffix) {
- std::vector<std::pair<TString, TActorStats>> v(ActorStats.begin(), ActorStats.end());
- auto comp = [](const auto& x, const auto& y) {
- return x.second < y.second || (!(y.second < x.second) && x.first < y.first);
- };
- std::sort(v.begin(), v.end(), comp);
- size_t maxLen = 0;
- for (const auto& [name, stats] : v) {
- maxLen = Max(maxLen, name.length());
- }
- for (const auto& [name, stats] : v) {
- s << prefix << name;
- for (size_t i = name.length(); i < maxLen; ++i) {
- s << ' ';
- }
- s << " Created# " << stats.Created << " Destroyed# " << stats.Destroyed << " Alive# "
- << stats.Created - stats.Destroyed << suffix;
- }
- }
-
- TInstant GetClock() const { return Clock; }
- ui64 GetEventsProcessed() const { return EventsProcessed; }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // tablet-related utility functions
-
- void SetupTabletRuntime(bool isMirror3dc = false, ui32 stateStorageNodeId = 0, ui32 targetNodeId = 0);
- static NTabletPipe::TClientConfig GetPipeConfigWithRetries();
- void SendToPipe(ui64 tabletId, const TActorId& sender, IEventBase* payload, ui64 cookie, const NKikimr::NTabletPipe::TClientConfig& pipeConfig);
+ ++ActorStats[name].Created;
+ const bool inserted = ActorName.emplace(actor, std::move(name)).second;
+ Y_VERIFY(inserted);
+
+ // specify node id if not provided
+ nodeId = nodeId ? nodeId : CurrentNodeId;
+ TPerNodeInfo *info = GetNode(nodeId);
+
+ // allocate mailbox id if needed
+ const ui32 mboxId = hint.value_or(info->NextHint);
+ if (mboxId == info->NextHint) {
+ ++info->NextHint;
+ }
+
+ // register actor in mailbox
+ const auto& it = Mailboxes.try_emplace(TMailboxId(nodeId, poolId, mboxId)).first;
+ TMailboxInfo& mbox = it->second;
+ mbox.Header.AttachActor(mbox.ActorLocalId, actor);
+
+ // generate actor id
+ const TActorId actorId(nodeId, poolId, mbox.ActorLocalId, mboxId);
+ ++mbox.ActorLocalId;
+
+ // initialize actor in actor system
+ DoActorInit(info->ActorSystem.get(), actor, actorId, parentId ? parentId : CurrentRecipient);
+
+ return actorId;
+ }
+
+ TActorId Register(IActor *actor, ui32 nodeId, ui32 poolId = 0) {
+ return Register(actor, {}, poolId, {}, nodeId);
+ }
+
+ void RegisterService(const TActorId& serviceId, const TActorId& actorId) {
+ const ui32 nodeId = actorId.NodeId(); // only at the node with the actor
+ GetNode(nodeId)->ActorSystem->RegisterLocalService(serviceId, actorId);
+ }
+
+ template<typename TCallback>
+ void Sim(TCallback&& callback, std::function<void(IEventHandle&)> witness = {}) {
+ bool progress = true;
+
+ while (callback()) {
+ Y_VERIFY(progress, "test actor system stalled -- no progress made"); // ensure we are doing progress
+
+ // obtain event with least time
+ std::optional<TScheduleItem> item;
+ while (!ScheduleQ.empty()) {
+ const auto it = ScheduleQ.begin();
+ auto& [timestamp, items] = *it;
+ Y_VERIFY(timestamp >= Clock || items.empty());
+ if (items.empty()) {
+ ScheduleQ.erase(it);
+ } else {
+ Clock = timestamp;
+ item.emplace(std::move(items.front()));
+ items.pop_front();
+ break;
+ }
+ }
+
+ progress = item.has_value();
+ if (!item || (item->Cookie && !item->Cookie->Detach())) {
+ continue;
+ }
+
+ std::unique_ptr<IEventHandle>& event = item->Event;
+ if (witness) {
+ witness(*event);
+ }
+ if (FilterFunction && !FilterFunction(item->NodeId, *event)) {
+ continue;
+ }
+ WrapInActorContext(TransformEvent(event.get(), item->NodeId), [&](IActor *actor) {
+ TAutoPtr<IEventHandle> ev(event.release());
+
+ const ui32 type = ev->GetTypeRewrite();
+
+ THPTimer timer;
+ actor->Receive(ev, TActivationContext::AsActorContext());
+ const TDuration timing = TDuration::Seconds(timer.Passed());
+
+ const auto it = ActorName.find(actor);
+ Y_VERIFY(it != ActorName.end(), "%p", actor);
+
+ auto& stats = EventProcessingStats[std::make_pair(it->second, type)];
+ ++stats.HitCount;
+ stats.TotalTime += timing;
+
+ ++EventsProcessed;
+ });
+ }
+ }
+
+ template<typename TCallback>
+ void WrapInActorContext(TActorId actorId, TCallback&& callback) {
+ const auto mboxIt = Mailboxes.find(actorId);
+ if (mboxIt == Mailboxes.end()) {
+ return;
+ }
+ TMailboxInfo& mbox = mboxIt->second;
+ if (IActor *actor = mbox.Header.FindActor(actorId.LocalId())) {
+ // obtain node info for this actor
+ TPerNodeInfo *info = GetNode(actorId.NodeId());
+
+ // adjust clock for correct operation
+ info->SchedulerThread->AdjustClock(Clock);
+
+ // allocate context and store its reference in TLS
+ TActorContext ctx(mbox.Header, *info->ExecutorThread, GetCycleCountFast(), actorId);
+ TlsActivationContext = &ctx;
+ CurrentRecipient = actorId;
+ CurrentNodeId = actorId.NodeId();
+
+ // invoke the callback
+ if constexpr (std::is_invocable_v<TCallback, IActor*>) {
+ std::invoke(std::forward<TCallback>(callback), actor);
+ } else {
+ std::invoke(std::forward<TCallback>(callback));
+ }
+
+ // forget about the context
+ TlsActivationContext = nullptr;
+ CurrentRecipient = {};
+ CurrentNodeId = 0;
+
+ // read possibly updated schedule
+ info->SchedulerThread->TransferSchedule();
+
+ // remove destroyed actors from the mailbox
+ for (const auto& actor : info->ExecutorThread->GetUnregistered()) {
+ const TActorId& actorId = actor->SelfId();
+ Y_VERIFY(TMailboxId(actorId) == mboxIt->first);
+ const auto nameIt = ActorName.find(actor.Get());
+ Y_VERIFY(nameIt != ActorName.end());
+ ++ActorStats[nameIt->second].Destroyed;
+ ActorName.erase(nameIt);
+ }
+
+ // terminate dead actors
+ info->ExecutorThread->DropUnregistered();
+
+ // drop the mailbox if no actors remain there
+ if (mbox.Header.IsEmpty()) {
+ Mailboxes.erase(mboxIt);
+ }
+ }
+ }
+
+ TActorId AllocateEdgeActor(ui32 nodeId, const char *file = "", int line = 0) {
+ return Register(new TEdgeActor(file, line), TActorId(), 0, std::nullopt, nodeId);
+ }
+
+ std::unique_ptr<IEventHandle> WaitForEdgeActorEvent(const std::set<TActorId>& edgeActorIds) {
+ std::unique_ptr<IEventHandle> res;
+ std::vector<TEdgeActor*> edges;
+ for (const TActorId& edgeActorId : edgeActorIds) {
+ TEdgeActor *edge = dynamic_cast<TEdgeActor*>(GetActor(edgeActorId));
+ Y_VERIFY(edge);
+ edge->WaitForEvent(&res);
+ edges.push_back(edge);
+ }
+ Sim([&] { return !res; });
+ for (TEdgeActor *edge : edges) {
+ edge->StopWaitingForEvent();
+ }
+ return res;
+ }
+
+ void DestroyActor(TActorId actorId) {
+ // find per-node info for this actor
+ TPerNodeInfo *info = GetNode(actorId.NodeId());
+ Y_VERIFY(info);
+
+ // find mailbox
+ auto it = Mailboxes.find(actorId);
+ Y_VERIFY(it != Mailboxes.end());
+ TMailboxInfo& mbox = it->second;
+
+ // update stats
+ const auto nameIt = ActorName.find(mbox.Header.FindActor(actorId.LocalId()));
+ Y_VERIFY(nameIt != ActorName.end());
+ ++ActorStats[nameIt->second].Destroyed;
+ ActorName.erase(nameIt);
+
+ // unregister actor through the executor
+ info->ExecutorThread->UnregisterActor(&mbox.Header, actorId.LocalId());
+
+ // terminate unregistered actor
+ info->ExecutorThread->DropUnregistered();
+
+ // delete mailbox if empty
+ if (mbox.Header.IsEmpty()) {
+ Mailboxes.erase(actorId);
+ }
+ }
+
+ std::set<ui32> GetNodes() const {
+ std::set<ui32> res;
+ for (const auto& [nodeId, info] : PerNodeInfo) {
+ res.insert(nodeId);
+ }
+ return res;
+ }
+
+ ui32 GetNodeCount() const {
+ return PerNodeInfo.size();
+ }
+
+ NLog::TSettings *LoggerSettings() const {
+ return LoggerSettings_.Get();
+ }
+
+ void DumpActorCount(IOutputStream& s, const TString& prefix, const TString& suffix) {
+ std::vector<std::pair<TString, TActorStats>> v(ActorStats.begin(), ActorStats.end());
+ auto comp = [](const auto& x, const auto& y) {
+ return x.second < y.second || (!(y.second < x.second) && x.first < y.first);
+ };
+ std::sort(v.begin(), v.end(), comp);
+ size_t maxLen = 0;
+ for (const auto& [name, stats] : v) {
+ maxLen = Max(maxLen, name.length());
+ }
+ for (const auto& [name, stats] : v) {
+ s << prefix << name;
+ for (size_t i = name.length(); i < maxLen; ++i) {
+ s << ' ';
+ }
+ s << " Created# " << stats.Created << " Destroyed# " << stats.Destroyed << " Alive# "
+ << stats.Created - stats.Destroyed << suffix;
+ }
+ }
+
+ TInstant GetClock() const { return Clock; }
+ ui64 GetEventsProcessed() const { return EventsProcessed; }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // tablet-related utility functions
+
+ void SetupTabletRuntime(bool isMirror3dc = false, ui32 stateStorageNodeId = 0, ui32 targetNodeId = 0);
+ static NTabletPipe::TClientConfig GetPipeConfigWithRetries();
+ void SendToPipe(ui64 tabletId, const TActorId& sender, IEventBase* payload, ui64 cookie, const NKikimr::NTabletPipe::TClientConfig& pipeConfig);
static TTabletStorageInfo *CreateTestTabletInfo(ui64 tabletId, TTabletTypes::EType tabletType, TBlobStorageGroupType::EErasureSpecies erasure, ui32 groupId);
TActorId CreateTestBootstrapper(TTabletStorageInfo *info, std::function<IActor*(TActorId, TTabletStorageInfo*)> op, ui32 nodeId);
-
-private:
- void SetupStateStorage(ui32 nodeId, ui32 stateStorageNodeId);
- void SetupTabletResolver(ui32 nodeId);
-
- IExecutorPool *CreateTestExecutorPool(ui32 nodeId);
-
- TActorId TransformEvent(IEventHandle *ev, ui32 nodeId) {
- Y_VERIFY(nodeId);
- TActorId recip = ev->GetRecipientRewrite();
- if (recip.NodeId() && recip.NodeId() != nodeId) {
- Y_VERIFY(!ev->HasEvent() || ev->GetBase()->IsSerializable(), "event can't pass through interconnect");
- Y_VERIFY(ev->Recipient == recip, "original recipient actor id lost");
- recip = GetNode(nodeId)->ActorSystem->InterconnectProxy(recip.NodeId());
- ev->Rewrite(TEvInterconnect::EvForward, recip);
- } else if (recip.IsService()) {
- Y_VERIFY(!recip.NodeId() || recip.NodeId() == nodeId, "recipient node mismatch");
- recip = GetNode(nodeId)->ActorSystem->LookupLocalService(recip);
- ev->Rewrite(ev->GetTypeRewrite(), recip);
- }
- Y_VERIFY(!recip || (recip.NodeId() == nodeId && !recip.IsService()));
- return recip;
- }
-
- TPerNodeInfo *GetNode(ui32 nodeId) {
- const auto nodeIt = PerNodeInfo.find(nodeId);
- Y_VERIFY(nodeIt != PerNodeInfo.end());
- return &nodeIt->second;
- }
-};
-
-class TFakeSchedulerCookie : public ISchedulerCookie {
-public:
- bool Detach() noexcept override { delete this; return false; }
- bool DetachEvent() noexcept override { Y_FAIL(); }
- bool IsArmed() noexcept override { Y_FAIL(); }
-};
-
-} // NKikimr
+
+private:
+ void SetupStateStorage(ui32 nodeId, ui32 stateStorageNodeId);
+ void SetupTabletResolver(ui32 nodeId);
+
+ IExecutorPool *CreateTestExecutorPool(ui32 nodeId);
+
+ TActorId TransformEvent(IEventHandle *ev, ui32 nodeId) {
+ Y_VERIFY(nodeId);
+ TActorId recip = ev->GetRecipientRewrite();
+ if (recip.NodeId() && recip.NodeId() != nodeId) {
+ Y_VERIFY(!ev->HasEvent() || ev->GetBase()->IsSerializable(), "event can't pass through interconnect");
+ Y_VERIFY(ev->Recipient == recip, "original recipient actor id lost");
+ recip = GetNode(nodeId)->ActorSystem->InterconnectProxy(recip.NodeId());
+ ev->Rewrite(TEvInterconnect::EvForward, recip);
+ } else if (recip.IsService()) {
+ Y_VERIFY(!recip.NodeId() || recip.NodeId() == nodeId, "recipient node mismatch");
+ recip = GetNode(nodeId)->ActorSystem->LookupLocalService(recip);
+ ev->Rewrite(ev->GetTypeRewrite(), recip);
+ }
+ Y_VERIFY(!recip || (recip.NodeId() == nodeId && !recip.IsService()));
+ return recip;
+ }
+
+ TPerNodeInfo *GetNode(ui32 nodeId) {
+ const auto nodeIt = PerNodeInfo.find(nodeId);
+ Y_VERIFY(nodeIt != PerNodeInfo.end());
+ return &nodeIt->second;
+ }
+};
+
+class TFakeSchedulerCookie : public ISchedulerCookie {
+public:
+ bool Detach() noexcept override { delete this; return false; }
+ bool DetachEvent() noexcept override { Y_FAIL(); }
+ bool IsArmed() noexcept override { Y_FAIL(); }
+};
+
+} // NKikimr
diff --git a/ydb/core/util/throughput_meter.h b/ydb/core/util/throughput_meter.h
index 935dae21783..3974e696f98 100644
--- a/ydb/core/util/throughput_meter.h
+++ b/ydb/core/util/throughput_meter.h
@@ -1,75 +1,75 @@
-#pragma once
-
-#include "defs.h"
+#pragma once
+
+#include "defs.h"
#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NKikimr {
-
- class TThroughputMeter
- {
- const ui64 UpdateDivisionFactor;
- const ui64 WindowUpdateTimeoutNs;
+
+namespace NKikimr {
+
+ class TThroughputMeter
+ {
+ const ui64 UpdateDivisionFactor;
+ const ui64 WindowUpdateTimeoutNs;
TVector<std::pair<float, NMonitoring::TDynamicCounters::TCounterPtr>> Counters;
-
- ui64 CumTimeNs = 0;
- ui64 CumBytes = 0;
- THPTimer Timer;
- ui64 WindowNs = 0;
+
+ ui64 CumTimeNs = 0;
+ ui64 CumBytes = 0;
+ THPTimer Timer;
+ ui64 WindowNs = 0;
TVector<ui64> Histogram;
-
- public:
- TThroughputMeter(ui64 updateDivisionFactor, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
+
+ public:
+ TThroughputMeter(ui64 updateDivisionFactor, const TIntrusivePtr<NMonitoring::TDynamicCounters>& counters,
const TString& group, const TString& subgroup, const TString& name, const TVector<float>& thresholds,
- const TDuration& windowUpdateTimeout = TDuration::MilliSeconds(10))
- : UpdateDivisionFactor(updateDivisionFactor)
- , WindowUpdateTimeoutNs(windowUpdateTimeout.NanoSeconds())
- {
- TIntrusivePtr<NMonitoring::TDynamicCounters> histGroup =
- counters->GetSubgroup(group, subgroup)->GetSubgroup("sensor", name);
- for (float threshold : thresholds) {
- Counters.emplace_back(threshold, histGroup->GetNamedCounter("percentile", Sprintf("%.1f", threshold * 100)));
- }
- }
-
- void Count(ui64 bytes) {
- const i64 span = Max<i64>(0, Timer.PassedReset() * 1000000000);
-
- WindowNs += span;
- while (WindowNs >= WindowUpdateTimeoutNs) {
- const ui64 rate = CumTimeNs ? (1000000000 * CumBytes / CumTimeNs) : 0;
- Histogram.push_back(rate);
-
- if (UpdateDivisionFactor) {
- CumBytes /= UpdateDivisionFactor;
- CumTimeNs /= UpdateDivisionFactor;
- } else {
- CumBytes = 0;
- CumTimeNs = 0;
- }
-
- WindowNs -= WindowUpdateTimeoutNs;
- }
-
- // count passed bytes and time
- CumBytes += bytes;
- CumTimeNs += span;
- }
-
- void UpdateHistogram() {
- Count(0);
- std::sort(Histogram.begin(), Histogram.end());
- if (!Histogram) {
- Histogram.push_back(0);
- }
+ const TDuration& windowUpdateTimeout = TDuration::MilliSeconds(10))
+ : UpdateDivisionFactor(updateDivisionFactor)
+ , WindowUpdateTimeoutNs(windowUpdateTimeout.NanoSeconds())
+ {
+ TIntrusivePtr<NMonitoring::TDynamicCounters> histGroup =
+ counters->GetSubgroup(group, subgroup)->GetSubgroup("sensor", name);
+ for (float threshold : thresholds) {
+ Counters.emplace_back(threshold, histGroup->GetNamedCounter("percentile", Sprintf("%.1f", threshold * 100)));
+ }
+ }
+
+ void Count(ui64 bytes) {
+ const i64 span = Max<i64>(0, Timer.PassedReset() * 1000000000);
+
+ WindowNs += span;
+ while (WindowNs >= WindowUpdateTimeoutNs) {
+ const ui64 rate = CumTimeNs ? (1000000000 * CumBytes / CumTimeNs) : 0;
+ Histogram.push_back(rate);
+
+ if (UpdateDivisionFactor) {
+ CumBytes /= UpdateDivisionFactor;
+ CumTimeNs /= UpdateDivisionFactor;
+ } else {
+ CumBytes = 0;
+ CumTimeNs = 0;
+ }
+
+ WindowNs -= WindowUpdateTimeoutNs;
+ }
+
+ // count passed bytes and time
+ CumBytes += bytes;
+ CumTimeNs += span;
+ }
+
+ void UpdateHistogram() {
+ Count(0);
+ std::sort(Histogram.begin(), Histogram.end());
+ if (!Histogram) {
+ Histogram.push_back(0);
+ }
const size_t maxIndex = Histogram.size() - 1;
- for (const auto& p : Counters) {
- const float threshold = p.first;
- const auto& counter = p.second;
- const size_t index = Min<size_t>(maxIndex, maxIndex * threshold);
- *counter = Histogram[index];
- }
- Histogram.clear();
- }
- };
-
-} // NKikimr
+ for (const auto& p : Counters) {
+ const float threshold = p.first;
+ const auto& counter = p.second;
+ const size_t index = Min<size_t>(maxIndex, maxIndex * threshold);
+ *counter = Histogram[index];
+ }
+ Histogram.clear();
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/util/wrapped_value.h b/ydb/core/util/wrapped_value.h
index fd457febf9b..c3c6553e05a 100644
--- a/ydb/core/util/wrapped_value.h
+++ b/ydb/core/util/wrapped_value.h
@@ -1,27 +1,27 @@
-#pragma once
-
-namespace NKikimr {
-
- template<typename T, typename TDerived>
- class TWrappedValue {
- T Value;
-
- public:
- friend bool operator ==(const TDerived& x, const TDerived& y) { return x.Value == y.Value; }
- friend bool operator !=(const TDerived& x, const TDerived& y) { return x.Value != y.Value; }
- friend bool operator < (const TDerived& x, const TDerived& y) { return x.Value < y.Value; }
- friend bool operator <=(const TDerived& x, const TDerived& y) { return x.Value <= y.Value; }
- friend bool operator > (const TDerived& x, const TDerived& y) { return x.Value > y.Value; }
- friend bool operator >=(const TDerived& x, const TDerived& y) { return x.Value >= y.Value; }
-
- protected:
- TWrappedValue(const T& value)
- : Value(value)
- {}
-
- const T& GetValue() const {
- return Value;
- }
- };
-
-} // NKikimr
+#pragma once
+
+namespace NKikimr {
+
+ template<typename T, typename TDerived>
+ class TWrappedValue {
+ T Value;
+
+ public:
+ friend bool operator ==(const TDerived& x, const TDerived& y) { return x.Value == y.Value; }
+ friend bool operator !=(const TDerived& x, const TDerived& y) { return x.Value != y.Value; }
+ friend bool operator < (const TDerived& x, const TDerived& y) { return x.Value < y.Value; }
+ friend bool operator <=(const TDerived& x, const TDerived& y) { return x.Value <= y.Value; }
+ friend bool operator > (const TDerived& x, const TDerived& y) { return x.Value > y.Value; }
+ friend bool operator >=(const TDerived& x, const TDerived& y) { return x.Value >= y.Value; }
+
+ protected:
+ TWrappedValue(const T& value)
+ : Value(value)
+ {}
+
+ const T& GetValue() const {
+ return Value;
+ }
+ };
+
+} // NKikimr
diff --git a/ydb/core/util/ya.make b/ydb/core/util/ya.make
index 4f325d8fcbd..294da094648 100644
--- a/ydb/core/util/ya.make
+++ b/ydb/core/util/ya.make
@@ -20,8 +20,8 @@ SRCS(
failure_injection.cpp
failure_injection.h
fast_tls.cpp
- format.cpp
- format.h
+ format.cpp
+ format.h
fragmented_buffer.cpp
fragmented_buffer.h
hazard.cpp
@@ -42,12 +42,12 @@ SRCS(
queue_inplace.h
queue_oneone_inplace.h
simple_cache.h
- single_thread_ic_mock.cpp
- single_thread_ic_mock.h
- stlog.h
+ single_thread_ic_mock.cpp
+ single_thread_ic_mock.h
+ stlog.h
templates.h
- testactorsys.cpp
- testactorsys.h
+ testactorsys.cpp
+ testactorsys.h
text.cpp
text.h
time_series_vec.h
@@ -62,7 +62,7 @@ SRCS(
)
PEERDIR(
- library/cpp/actors/interconnect/mock
+ library/cpp/actors/interconnect/mock
library/cpp/actors/util
library/cpp/containers/stack_vector
library/cpp/html/escape
diff --git a/ydb/core/viewer/browse.h b/ydb/core/viewer/browse.h
index c5716f46a76..8c1f47a0df0 100644
--- a/ydb/core/viewer/browse.h
+++ b/ydb/core/viewer/browse.h
@@ -38,8 +38,8 @@ class TBrowse : public TActorBootstrapped<TBrowse> {
public:
IViewer::TBrowseContext BrowseContext;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TBrowse(const IViewer* viewer, const TActorId& owner, const TString& path, const TString& userToken)
@@ -391,8 +391,8 @@ protected:
THashSet<ui32> PDisks;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TBrowseTabletsCommon(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
diff --git a/ydb/core/viewer/browse_pq.h b/ydb/core/viewer/browse_pq.h
index 3e3b32a21e3..169581515be 100644
--- a/ydb/core/viewer/browse_pq.h
+++ b/ydb/core/viewer/browse_pq.h
@@ -24,8 +24,8 @@ class TBrowseRoot : public TActorBootstrapped<TBrowseRoot> {
TActorId Owner;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TBrowseRoot(const TActorId& owner, const IViewer::TBrowseContext&)
@@ -283,8 +283,8 @@ public:
class TBrowseConsumers : public TBrowseCommon {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TBrowseConsumers(const TActorId& owner, const IViewer::TBrowseContext& browseContext)
diff --git a/ydb/core/viewer/content/v2/storage.js b/ydb/core/viewer/content/v2/storage.js
index 1872e4916d7..0a5d8a427b0 100644
--- a/ydb/core/viewer/content/v2/storage.js
+++ b/ydb/core/viewer/content/v2/storage.js
@@ -374,7 +374,7 @@ Storage.prototype.updateFromStorage = function(update) {
}
if (pDisk && pDisk.AvailableSize && pDisk.TotalSize) {
usage = Math.max(usage, 1 - pDisk.AvailableSize / pDisk.TotalSize);
- if (!pDisk.State || (vDisk.Replicated === false && !vDisk.DonorMode) || isVDiskInErrorState(vDisk.VDiskState) === true) {
+ if (!pDisk.State || (vDisk.Replicated === false && !vDisk.DonorMode) || isVDiskInErrorState(vDisk.VDiskState) === true) {
missingDisks++;
}
} else {
diff --git a/ydb/core/viewer/content/v2/vdisk.js b/ydb/core/viewer/content/v2/vdisk.js
index 6a3e1af417b..1d0d8b9fcbe 100644
--- a/ydb/core/viewer/content/v2/vdisk.js
+++ b/ydb/core/viewer/content/v2/vdisk.js
@@ -130,11 +130,11 @@ VDisk.prototype.updateVDiskInfo = function(update) {
state += '<tr><td>FronQueues</td><td>' + this.FrontQueues + '</td></tr>';
severity = Math.max(severity, Math.min(4, this.getColorSeverity(this.FrontQueues)));
}
- dash = false;
- if (this.DonorMode === true) {
- state += '<tr><td>Donor</td><td>YES</td></tr>';
- dash = true;
- } else if (!this.Replicated) {
+ dash = false;
+ if (this.DonorMode === true) {
+ state += '<tr><td>Donor</td><td>YES</td></tr>';
+ dash = true;
+ } else if (!this.Replicated) {
state += '<tr><td>Replicated</td><td>NO</td></tr>';
if (severity === 1) {
severity = 2;
@@ -176,10 +176,10 @@ VDisk.prototype.updateVDiskInfo = function(update) {
state += '<tr><td>Write</td><td>' + bytesToSpeed(this.WriteThroughput) + '</td></tr>';
}
state += '</table>';
- if (dash) {
- background = 'linear-gradient(45deg, forestgreen, forestgreen 8px, transparent 8px, transparent 100%)';
- vDisk.css('background', background);
- }
+ if (dash) {
+ background = 'linear-gradient(45deg, forestgreen, forestgreen 8px, transparent 8px, transparent 100%)';
+ vDisk.css('background', background);
+ }
vDisk.css('background-color', color);
vDisk.attr('data-original-title', state);
this.color = color;
diff --git a/ydb/core/viewer/content/viewer.js b/ydb/core/viewer/content/viewer.js
index 1108f42278c..c86e716ba02 100644
--- a/ydb/core/viewer/content/viewer.js
+++ b/ydb/core/viewer/content/viewer.js
@@ -969,14 +969,14 @@ function pad2(val) {
}
}
-function pad4(val) {
- var len = String(val).length;
- for (var i = len; i < 4; i++) {
- val = "0" + val;
- }
- return val;
-}
-
+function pad4(val) {
+ var len = String(val).length;
+ for (var i = len; i < 4; i++) {
+ val = "0" + val;
+ }
+ return val;
+}
+
function pad9(val) {
var len = String(val).length;
for (var i = len; i < 9; i++) {
@@ -2224,14 +2224,14 @@ function refreshBSGroupInfo() {
var InterconnectHeight = 36;
-function getInterconnectUrl(node, peerNode) {
- return getBaseUrl(node) + "/actors/interconnect/peer" + pad4(peerNode);
-}
-
-function onInterconnectClick() {
- window.open(getInterconnectUrl(this.NodeId, this.PeerNodeId));
-}
-
+function getInterconnectUrl(node, peerNode) {
+ return getBaseUrl(node) + "/actors/interconnect/peer" + pad4(peerNode);
+}
+
+function onInterconnectClick() {
+ window.open(getInterconnectUrl(this.NodeId, this.PeerNodeId));
+}
+
function buildInterconnectMap(node, interconnect) {
if (NodesCount >= 64) {
var canvas = document.createElement("canvas");
@@ -2274,9 +2274,9 @@ function buildInterconnectMap(node, interconnect) {
interconnectcell.style.padding = "1px";
}
interconnectdiv.title = getNodeHost(j);
- interconnectdiv.NodeId = node.Id;
- interconnectdiv.PeerNodeId = j;
- interconnectdiv.addEventListener("click", onInterconnectClick, false);
+ interconnectdiv.NodeId = node.Id;
+ interconnectdiv.PeerNodeId = j;
+ interconnectdiv.addEventListener("click", onInterconnectClick, false);
interconnectcell.appendChild(interconnectdiv);
node.InterconnectCellDomElement[j] = interconnectdiv;
}
diff --git a/ydb/core/viewer/json_browse.h b/ydb/core/viewer/json_browse.h
index cba672826ee..131718edc7b 100644
--- a/ydb/core/viewer/json_browse.h
+++ b/ydb/core/viewer/json_browse.h
@@ -66,8 +66,8 @@ class TJsonBrowse : public TActorBootstrapped<TJsonBrowse> {
ui32 Responses = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonBrowse(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_bscontrollerinfo.h b/ydb/core/viewer/json_bscontrollerinfo.h
index 5df47ed5531..42a56ec5105 100644
--- a/ydb/core/viewer/json_bscontrollerinfo.h
+++ b/ydb/core/viewer/json_bscontrollerinfo.h
@@ -23,8 +23,8 @@ class TJsonBSControllerInfo : public TViewerPipeClient<TJsonBSControllerInfo> {
ui32 Timeout = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonBSControllerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_cluster.h b/ydb/core/viewer/json_cluster.h
index 36b5362a452..9126b33d391 100644
--- a/ydb/core/viewer/json_cluster.h
+++ b/ydb/core/viewer/json_cluster.h
@@ -36,8 +36,8 @@ class TJsonCluster : public TActorBootstrapped<TJsonCluster> {
bool Tablets = false;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonCluster(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/json_compute.h b/ydb/core/viewer/json_compute.h
index 980b8bfc1ec..426ad603107 100644
--- a/ydb/core/viewer/json_compute.h
+++ b/ydb/core/viewer/json_compute.h
@@ -93,9 +93,9 @@ public:
}
void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
+ for (const TNodeId nodeId : NodeIds) {
Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe);
- }
+ }
TBase::PassAway();
}
diff --git a/ydb/core/viewer/json_config.h b/ydb/core/viewer/json_config.h
index 7e501d5afbf..4c9aee4c54c 100644
--- a/ydb/core/viewer/json_config.h
+++ b/ydb/core/viewer/json_config.h
@@ -18,8 +18,8 @@ class TJsonConfig : public TActorBootstrapped<TJsonConfig> {
NMon::TEvHttpInfo::TPtr Event;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonConfig(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_content.h b/ydb/core/viewer/json_content.h
index 79b230f1288..641bb2bba08 100644
--- a/ydb/core/viewer/json_content.h
+++ b/ydb/core/viewer/json_content.h
@@ -25,8 +25,8 @@ class TJsonContent : public TActorBootstrapped<TJsonContent> {
TInstant BrowseStarted;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonContent(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/json_counters.h b/ydb/core/viewer/json_counters.h
index cac1e0885c4..0e5fb90d060 100644
--- a/ydb/core/viewer/json_counters.h
+++ b/ydb/core/viewer/json_counters.h
@@ -27,8 +27,8 @@ class TJsonCounters : public TActorBootstrapped<TJsonCounters> {
TMap<ui32, THolder<TEvWhiteboard::TEvBSGroupStateResponse>> BSGroupInfo;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
@@ -303,7 +303,7 @@ public:
}
}
- static TEvInterconnect::TNodeInfo totals(0, "", "cluster", "", 0, TNodeLocation());
+ static TEvInterconnect::TNodeInfo totals(0, "", "cluster", "", 0, TNodeLocation());
for (size_t p = 0; p < pDiskUserSpaceHistogram.size(); ++p) {
json << ",{\"labels\":{";
diff --git a/ydb/core/viewer/json_describe.h b/ydb/core/viewer/json_describe.h
index 05ef441f8f6..70fb026cabd 100644
--- a/ydb/core/viewer/json_describe.h
+++ b/ydb/core/viewer/json_describe.h
@@ -23,8 +23,8 @@ class TJsonDescribe : public TViewerPipeClient<TJsonDescribe> {
ui32 Timeout = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonDescribe(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_hiveinfo.h b/ydb/core/viewer/json_hiveinfo.h
index f4d04ddfaf6..a693ff7f177 100644
--- a/ydb/core/viewer/json_hiveinfo.h
+++ b/ydb/core/viewer/json_hiveinfo.h
@@ -24,8 +24,8 @@ class TJsonHiveInfo : public TViewerPipeClient<TJsonHiveInfo> {
TNodeId NodeId = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonHiveInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_hivestats.h b/ydb/core/viewer/json_hivestats.h
index 7f24693d635..6cd1ff202c6 100644
--- a/ydb/core/viewer/json_hivestats.h
+++ b/ydb/core/viewer/json_hivestats.h
@@ -23,8 +23,8 @@ class TJsonHiveStats : public TViewerPipeClient<TJsonHiveStats> {
ui32 Timeout = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonHiveStats(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_labeledcounters.h b/ydb/core/viewer/json_labeledcounters.h
index 6fce18b32b2..1f75ccee625 100644
--- a/ydb/core/viewer/json_labeledcounters.h
+++ b/ydb/core/viewer/json_labeledcounters.h
@@ -29,8 +29,8 @@ class TJsonLabeledCounters : public TActorBootstrapped<TJsonLabeledCounters> {
ui32 Timeout = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonLabeledCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_metainfo.h b/ydb/core/viewer/json_metainfo.h
index 54064d74037..475663256f4 100644
--- a/ydb/core/viewer/json_metainfo.h
+++ b/ydb/core/viewer/json_metainfo.h
@@ -37,8 +37,8 @@ class TJsonMetaInfo : public TActorBootstrapped<TJsonMetaInfo> {
std::unordered_multiset<TBrowseRequestKey> BrowseRequestsInFlight;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonMetaInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_netinfo.h b/ydb/core/viewer/json_netinfo.h
index 3d7c3835a0a..6f4e3f667a9 100644
--- a/ydb/core/viewer/json_netinfo.h
+++ b/ydb/core/viewer/json_netinfo.h
@@ -85,9 +85,9 @@ public:
}
void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
+ for (const TNodeId nodeId : NodeIds) {
Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
- }
+ }
TBase::PassAway();
}
diff --git a/ydb/core/viewer/json_nodelist.h b/ydb/core/viewer/json_nodelist.h
index 504ed152d8d..7e752778f6c 100644
--- a/ydb/core/viewer/json_nodelist.h
+++ b/ydb/core/viewer/json_nodelist.h
@@ -18,8 +18,8 @@ class TJsonNodeList : public TActorBootstrapped<TJsonNodeList> {
TAutoPtr<TEvInterconnect::TEvNodesInfo> NodesInfo;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonNodeList(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
@@ -62,15 +62,15 @@ public:
}
jsonNodeInfo["Address"] = nodeInfo.Address;
jsonNodeInfo["Port"] = nodeInfo.Port;
- if (nodeInfo.Location != TNodeLocation()) {
+ if (nodeInfo.Location != TNodeLocation()) {
NJson::TJsonValue& jsonPhysicalLocation = jsonNodeInfo["PhysicalLocation"];
- const auto& x = nodeInfo.Location.GetLegacyValue();
- jsonPhysicalLocation["DataCenter"] = x.DataCenter;
- jsonPhysicalLocation["Room"] = x.Room;
- jsonPhysicalLocation["Rack"] = x.Rack;
- jsonPhysicalLocation["Body"] = x.Body;
- jsonPhysicalLocation["DataCenterId"] = nodeInfo.Location.GetDataCenterId();
- jsonPhysicalLocation["Location"] = nodeInfo.Location.ToString();
+ const auto& x = nodeInfo.Location.GetLegacyValue();
+ jsonPhysicalLocation["DataCenter"] = x.DataCenter;
+ jsonPhysicalLocation["Room"] = x.Room;
+ jsonPhysicalLocation["Rack"] = x.Rack;
+ jsonPhysicalLocation["Body"] = x.Body;
+ jsonPhysicalLocation["DataCenterId"] = nodeInfo.Location.GetDataCenterId();
+ jsonPhysicalLocation["Location"] = nodeInfo.Location.ToString();
}
}
}
diff --git a/ydb/core/viewer/json_pqconsumerinfo.h b/ydb/core/viewer/json_pqconsumerinfo.h
index b98dfc26323..2feafa5c29a 100644
--- a/ydb/core/viewer/json_pqconsumerinfo.h
+++ b/ydb/core/viewer/json_pqconsumerinfo.h
@@ -29,8 +29,8 @@ class TJsonPQConsumerInfo : public TActorBootstrapped<TJsonPQConsumerInfo> {
ui32 Responses = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonPQConsumerInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_query.h b/ydb/core/viewer/json_query.h
index 600d8088e10..10698fdc004 100644
--- a/ydb/core/viewer/json_query.h
+++ b/ydb/core/viewer/json_query.h
@@ -32,8 +32,8 @@ class TJsonQuery : public TActorBootstrapped<TJsonQuery> {
TString Stats;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonQuery(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/json_storage.h b/ydb/core/viewer/json_storage.h
index 76e5d2f5e8b..06794e0c92a 100644
--- a/ydb/core/viewer/json_storage.h
+++ b/ydb/core/viewer/json_storage.h
@@ -61,8 +61,8 @@ class TJsonStorage : public TViewerPipeClient<TJsonStorage> {
EWith With = EWith::Everything;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonStorage(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/json_tabletcounters.h b/ydb/core/viewer/json_tabletcounters.h
index 7f399104410..2b0afb6b691 100644
--- a/ydb/core/viewer/json_tabletcounters.h
+++ b/ydb/core/viewer/json_tabletcounters.h
@@ -29,8 +29,8 @@ class TJsonTabletCounters : public TActorBootstrapped<TJsonTabletCounters> {
bool Aggregate = false;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonTabletCounters(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_tenantinfo.h b/ydb/core/viewer/json_tenantinfo.h
index 749422ba396..9218552aba2 100644
--- a/ydb/core/viewer/json_tenantinfo.h
+++ b/ydb/core/viewer/json_tenantinfo.h
@@ -45,8 +45,8 @@ class TJsonTenantInfo : public TViewerPipeClient<TJsonTenantInfo> {
NKikimrViewer::TTenantInfo Result;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonTenantInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
@@ -101,7 +101,7 @@ public:
}
void PassAway() override {
- for (const TNodeId nodeId : NodeIds) {
+ for (const TNodeId nodeId : NodeIds) {
Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
};
TBase::PassAway();
diff --git a/ydb/core/viewer/json_tenants.h b/ydb/core/viewer/json_tenants.h
index 762d5e3b436..ca3a3e93d04 100644
--- a/ydb/core/viewer/json_tenants.h
+++ b/ydb/core/viewer/json_tenants.h
@@ -26,8 +26,8 @@ class TJsonTenants : public TViewerPipeClient<TJsonTenants> {
THashMap<TString, NKikimrViewer::TTenant*> TenantIndex;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonTenants(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_topicinfo.h b/ydb/core/viewer/json_topicinfo.h
index cbf42ee7279..f3d6d74c6ce 100644
--- a/ydb/core/viewer/json_topicinfo.h
+++ b/ydb/core/viewer/json_topicinfo.h
@@ -25,8 +25,8 @@ class TJsonTopicInfo : public TActorBootstrapped<TJsonTopicInfo> {
ui32 Timeout = 0;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonTopicInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
diff --git a/ydb/core/viewer/json_wb_req.h b/ydb/core/viewer/json_wb_req.h
index f04c85688f4..a1bb73f94ce 100644
--- a/ydb/core/viewer/json_wb_req.h
+++ b/ydb/core/viewer/json_wb_req.h
@@ -61,8 +61,8 @@ protected:
TDuration RetryPeriod = TDuration::MilliSeconds(500);
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonWhiteboardRequest(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/json_whoami.h b/ydb/core/viewer/json_whoami.h
index b490a6930fc..f9ce8ece82f 100644
--- a/ydb/core/viewer/json_whoami.h
+++ b/ydb/core/viewer/json_whoami.h
@@ -18,8 +18,8 @@ class TJsonWhoAmI : public TActorBootstrapped<TJsonWhoAmI> {
NMon::TEvHttpInfo::TPtr Event;
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::VIEWER_HANDLER;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
}
TJsonWhoAmI(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
diff --git a/ydb/core/viewer/protos/viewer.proto b/ydb/core/viewer/protos/viewer.proto
index 9f6c822a89f..6659e208687 100644
--- a/ydb/core/viewer/protos/viewer.proto
+++ b/ydb/core/viewer/protos/viewer.proto
@@ -449,7 +449,7 @@ message TTabletStateInfo {
message TComputeNodeInfo {
uint64 StartTime = 1;
uint64 ChangeTime = 2;
- NKikimrWhiteboard.TSystemStateInfo.TLegacyNodeLocation SystemLocation = 3;
+ NKikimrWhiteboard.TSystemStateInfo.TLegacyNodeLocation SystemLocation = 3;
repeated double LoadAverage = 4;
uint32 NumberOfCpus = 5;
EFlag Overall = 6;
diff --git a/ydb/core/viewer/viewer.cpp b/ydb/core/viewer/viewer.cpp
index f1124115bf7..4f0d56341fc 100644
--- a/ydb/core/viewer/viewer.cpp
+++ b/ydb/core/viewer/viewer.cpp
@@ -125,8 +125,8 @@ void SetupDBVirtualHandlers(IViewer* viewer) {
class TViewer : public TActorBootstrapped<TViewer>, public IViewer {
public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::TABLET_MONITORING_PROXY;
}
TViewer(const TKikimrRunConfig &kikimrRunConfig)
@@ -571,22 +571,22 @@ NKikimrViewer::EFlag GetFlagFromUsage(double usage) {
NKikimrViewer::EFlag GetPDiskStateFlag(const NKikimrWhiteboard::TPDiskStateInfo& info) {
NKikimrViewer::EFlag flag = NKikimrViewer::EFlag::Grey;
switch (info.GetState()) {
- case NKikimrBlobStorage::TPDiskState::Normal:
+ case NKikimrBlobStorage::TPDiskState::Normal:
flag = NKikimrViewer::EFlag::Green;
break;
- case NKikimrBlobStorage::TPDiskState::Initial:
- case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
+ case NKikimrBlobStorage::TPDiskState::Initial:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatRead:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogRead:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogRead:
flag = NKikimrViewer::EFlag::Yellow;
break;
- case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
- case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
- case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
- case NKikimrBlobStorage::TPDiskState::OpenFileError:
+ case NKikimrBlobStorage::TPDiskState::InitialFormatReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialSysLogParseError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogReadError:
+ case NKikimrBlobStorage::TPDiskState::InitialCommonLogParseError:
+ case NKikimrBlobStorage::TPDiskState::CommonLoggerInitError:
+ case NKikimrBlobStorage::TPDiskState::OpenFileError:
flag = NKikimrViewer::EFlag::Red;
break;
default:
diff --git a/ydb/core/viewer/wb_group.h b/ydb/core/viewer/wb_group.h
index 9735d8f29ec..deeff2d51fd 100644
--- a/ydb/core/viewer/wb_group.h
+++ b/ydb/core/viewer/wb_group.h
@@ -170,13 +170,13 @@ public:
, Fields(fields)
{}
- TPartProtoKey(const TPartProtoKey& other)
- : Element(other.Element)
- , Fields(other.Fields)
- {
- *this = other;
- }
-
+ TPartProtoKey(const TPartProtoKey& other)
+ : Element(other.Element)
+ , Fields(other.Fields)
+ {
+ *this = other;
+ }
+
bool operator ==(const TPartProtoKey& other) const {
Y_VERIFY(Fields == other.Fields);
for (const FieldDescriptor* field : Fields) {
diff --git a/ydb/core/ydb_convert/table_description.cpp b/ydb/core/ydb_convert/table_description.cpp
index 0d10bb8450b..670536c75e3 100644
--- a/ydb/core/ydb_convert/table_description.cpp
+++ b/ydb/core/ydb_convert/table_description.cpp
@@ -32,7 +32,7 @@ void FillColumnDescriptionImpl(TYdbProto& out,
splitKeyType.MutableTuple()->AddElement();
}
- for (const auto& column : in.GetColumns()) {
+ for (const auto& column : in.GetColumns()) {
NYql::NProto::TypeIds protoType;
if (!NYql::NProto::TypeIds_Parse(column.GetType(), &protoType)) {
throw NYql::TErrorException(NKikimrIssues::TIssuesIds::DEFAULT_ERROR)
diff --git a/ydb/core/ydb_convert/ydb_convert.cpp b/ydb/core/ydb_convert/ydb_convert.cpp
index 11c804cff50..7392e159fbf 100644
--- a/ydb/core/ydb_convert/ydb_convert.cpp
+++ b/ydb/core/ydb_convert/ydb_convert.cpp
@@ -766,7 +766,7 @@ TACLAttrs ConvertYdbPermissionNameToACLAttrs(const TString& name) {
TVector<TString> ConvertACLMaskToYdbPermissionNames(ui32 mask) {
static const TVector<std::pair<ui32, TString>> maskByPower = CalcMaskByPower();
TVector<TString> result;
- for (const auto& pair : maskByPower) {
+ for (const auto& pair : maskByPower) {
if ((mask & pair.first ^ pair.first) == 0) {
result.push_back(pair.second);
mask &= ~pair.first;
diff --git a/ydb/core/ymq/actor/action.h b/ydb/core/ymq/actor/action.h
index 1801c98d68f..77e872aa92d 100644
--- a/ydb/core/ymq/actor/action.h
+++ b/ydb/core/ymq/actor/action.h
@@ -53,8 +53,8 @@ public:
DebugInfo->ActionActors.EraseKeyValue(RequestId_, this);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
static constexpr bool NeedQueueAttributes() { // override it in TDerived if needed
diff --git a/ydb/core/ymq/actor/executor.h b/ydb/core/ymq/actor/executor.h
index 5dd51c6da23..e131ce9c6c6 100644
--- a/ydb/core/ymq/actor/executor.h
+++ b/ydb/core/ymq/actor/executor.h
@@ -165,8 +165,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_EXECUTOR_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_EXECUTOR_ACTOR;
}
void SetQueryIdForLogging(EQueryId queryId) {
diff --git a/ydb/core/ymq/actor/fifo_cleanup.h b/ydb/core/ymq/actor/fifo_cleanup.h
index edf6040eec5..ac5c47300ee 100644
--- a/ydb/core/ymq/actor/fifo_cleanup.h
+++ b/ydb/core/ymq/actor/fifo_cleanup.h
@@ -19,8 +19,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_CLEANUP_BACKGROUND_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_CLEANUP_BACKGROUND_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/metering.cpp b/ydb/core/ymq/actor/metering.cpp
index 94ccef7eb01..87f656e5d74 100644
--- a/ydb/core/ymq/actor/metering.cpp
+++ b/ydb/core/ymq/actor/metering.cpp
@@ -243,8 +243,8 @@ public:
records << record.ToJsonSafe() << "\n";
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_METERING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_METERING_ACTOR;
}
void FlushProcessedRequestsAttributes() {
diff --git a/ydb/core/ymq/actor/migration.cpp b/ydb/core/ymq/actor/migration.cpp
index e547e975581..5bc65853757 100644
--- a/ydb/core/ymq/actor/migration.cpp
+++ b/ydb/core/ymq/actor/migration.cpp
@@ -28,8 +28,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_QUEUE_MIGRATION_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_QUEUE_MIGRATION_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/migration.h b/ydb/core/ymq/actor/migration.h
index 501ec050f3f..3cf825f8ddd 100644
--- a/ydb/core/ymq/actor/migration.h
+++ b/ydb/core/ymq/actor/migration.h
@@ -15,8 +15,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_QUEUE_MIGRATION_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_QUEUE_MIGRATION_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/ping.h b/ydb/core/ymq/actor/ping.h
index 830f7e10b8d..d74d6540a91 100644
--- a/ydb/core/ymq/actor/ping.h
+++ b/ydb/core/ymq/actor/ping.h
@@ -17,8 +17,8 @@ public:
{
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_PING_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_PING_ACTOR;
}
void Bootstrap() {
diff --git a/ydb/core/ymq/actor/proxy_actor.h b/ydb/core/ymq/actor/proxy_actor.h
index b553716bf06..37c42fc5b9f 100644
--- a/ydb/core/ymq/actor/proxy_actor.h
+++ b/ydb/core/ymq/actor/proxy_actor.h
@@ -50,8 +50,8 @@ public:
DebugInfo->ProxyActors.EraseKeyValue(RequestId_, this);
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_PROXY_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_PROXY_ACTOR;
}
// Watches request type and returns true if this type assumes proxying request to other queue leader node.
diff --git a/ydb/core/ymq/actor/proxy_service.h b/ydb/core/ymq/actor/proxy_service.h
index a3c991105fe..421d19fd841 100644
--- a/ydb/core/ymq/actor/proxy_service.h
+++ b/ydb/core/ymq/actor/proxy_service.h
@@ -60,8 +60,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_PROXY_SERVICE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_PROXY_SERVICE_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/purge.h b/ydb/core/ymq/actor/purge.h
index 2a16a5aa247..9d4f9177d39 100644
--- a/ydb/core/ymq/actor/purge.h
+++ b/ydb/core/ymq/actor/purge.h
@@ -32,8 +32,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_PURGE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_PURGE_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/queue_leader.h b/ydb/core/ymq/actor/queue_leader.h
index 3504e4ddb1a..c6306e00515 100644
--- a/ydb/core/ymq/actor/queue_leader.h
+++ b/ydb/core/ymq/actor/queue_leader.h
@@ -35,7 +35,7 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
return NKikimrServices::TActivity::SQS_QUEUE_LEADER_ACTOR;
}
diff --git a/ydb/core/ymq/actor/queue_schema.h b/ydb/core/ymq/actor/queue_schema.h
index 793ba1c06ad..c7c8d64e7de 100644
--- a/ydb/core/ymq/actor/queue_schema.h
+++ b/ydb/core/ymq/actor/queue_schema.h
@@ -86,8 +86,8 @@ public:
void PassAway() override;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
@@ -158,8 +158,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/retention.h b/ydb/core/ymq/actor/retention.h
index 724baddff3f..eee5f59075e 100644
--- a/ydb/core/ymq/actor/retention.h
+++ b/ydb/core/ymq/actor/retention.h
@@ -14,8 +14,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_RETENTION_BACKGROUND_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_RETENTION_BACKGROUND_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/schema.cpp b/ydb/core/ymq/actor/schema.cpp
index 20e84581fe5..9a6a046a615 100644
--- a/ydb/core/ymq/actor/schema.cpp
+++ b/ydb/core/ymq/actor/schema.cpp
@@ -525,8 +525,8 @@ public:
RequestQuoterTabletId();
}
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/schema.h b/ydb/core/ymq/actor/schema.h
index c88face921b..42d76b49ecf 100644
--- a/ydb/core/ymq/actor/schema.h
+++ b/ydb/core/ymq/actor/schema.h
@@ -57,8 +57,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
@@ -113,8 +113,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
@@ -157,8 +157,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_ACTOR;
}
private:
diff --git a/ydb/core/ymq/actor/service.h b/ydb/core/ymq/actor/service.h
index caf091c24b8..864f4bc3fcf 100644
--- a/ydb/core/ymq/actor/service.h
+++ b/ydb/core/ymq/actor/service.h
@@ -27,8 +27,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_SERVICE_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_SERVICE_ACTOR;
}
struct TUserInfo;
diff --git a/ydb/core/ymq/actor/user_settings_reader.h b/ydb/core/ymq/actor/user_settings_reader.h
index c85d6922e4a..3a8c4341ede 100644
--- a/ydb/core/ymq/actor/user_settings_reader.h
+++ b/ydb/core/ymq/actor/user_settings_reader.h
@@ -18,8 +18,8 @@ public:
void Bootstrap();
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::SQS_USER_SETTINGS_READER_ACTOR;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::SQS_USER_SETTINGS_READER_ACTOR;
}
private:
diff --git a/ydb/library/wilson/wilson_event.h b/ydb/library/wilson/wilson_event.h
index e092a2cd970..e945c61d0fa 100644
--- a/ydb/library/wilson/wilson_event.h
+++ b/ydb/library/wilson/wilson_event.h
@@ -1,2 +1,2 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/wilson/wilson_event.h>
diff --git a/ydb/library/wilson/wilson_trace.h b/ydb/library/wilson/wilson_trace.h
index 8c27c41fbdc..6ad5695c61e 100644
--- a/ydb/library/wilson/wilson_trace.h
+++ b/ydb/library/wilson/wilson_trace.h
@@ -1,2 +1,2 @@
-#pragma once
+#pragma once
#include <library/cpp/actors/wilson/wilson_trace.h>
diff --git a/ydb/library/wilson/ya.make b/ydb/library/wilson/ya.make
index e4daf898c7e..72314b3681c 100644
--- a/ydb/library/wilson/ya.make
+++ b/ydb/library/wilson/ya.make
@@ -1,8 +1,8 @@
-LIBRARY()
+LIBRARY()
PEERDIR(
library/cpp/actors/wilson
)
- OWNER(alexvru)
-END()
+ OWNER(alexvru)
+END()
diff --git a/ydb/library/yql/ast/yql_expr.cpp b/ydb/library/yql/ast/yql_expr.cpp
index 82f6c5812ac..6c5a241a2c3 100644
--- a/ydb/library/yql/ast/yql_expr.cpp
+++ b/ydb/library/yql/ast/yql_expr.cpp
@@ -2058,7 +2058,7 @@ EChangeState DoGetChanges(TExprNode* start, const TNodeOnNodeOwnedMap& replaces,
if (start->GetBloom() & 1ULL) {
bool maybe = false;
- for (const auto& repl : replaces) {
+ for (const auto& repl : replaces) {
if (repl.second && !repl.first->Dead()) {
if (TExprNode::Argument != repl.first->Type()) {
maybe = true;
diff --git a/ydb/library/yql/core/type_ann/type_ann_join.cpp b/ydb/library/yql/core/type_ann/type_ann_join.cpp
index 18516a8ab8b..fb550024e6e 100644
--- a/ydb/library/yql/core/type_ann/type_ann_join.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_join.cpp
@@ -344,7 +344,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- for (const auto& child : input->Child(3)->Children()) {
+ for (const auto& child : input->Child(3)->Children()) {
if (!GetFieldPosition(leftItemType, child->Content())) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(child->Pos()), TStringBuilder() << "Unknown key column: " << child->Content()));
return IGraphTransformer::TStatus::Error;
@@ -558,7 +558,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- for (const auto& child : input->Child(2)->Children()) {
+ for (const auto& child : input->Child(2)->Children()) {
if (!EnsureAtom(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -590,7 +590,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- for (const auto& child : input->Child(3)->Children()) {
+ for (const auto& child : input->Child(3)->Children()) {
if (!EnsureAtom(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -617,7 +617,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- for (const auto& child : input->Child(4)->Children()) {
+ for (const auto& child : input->Child(4)->Children()) {
if (!EnsureAtom(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -649,7 +649,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- for (const auto& child : input->Child(5)->Children()) {
+ for (const auto& child : input->Child(5)->Children()) {
if (!EnsureAtom(*child, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -665,7 +665,7 @@ namespace NTypeAnnImpl {
}
TSet<TStringBuf> seenOptions;
- for (const auto& child : input->Child(6)->Children()) {
+ for (const auto& child : input->Child(6)->Children()) {
if (!EnsureTupleMinSize(*child, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -747,7 +747,7 @@ namespace NTypeAnnImpl {
std::conditional_t<ByStruct, TVector<const TItemExprType*>, TVector<const TTypeAnnotationNode*>> resultItems;
resultItems.reserve(fullColumns.size());
- for (const auto& child : input->Child(2)->Children()) {
+ for (const auto& child : input->Child(2)->Children()) {
const auto pos = GetFieldPosition(inputItemType, child->Content());
auto inputColumnType = GetFieldType(inputItemType, *pos);
if (requiredColumns.contains(child->Content())) {
@@ -760,7 +760,7 @@ namespace NTypeAnnImpl {
resultItems.emplace_back(inputColumnType);
}
- for (const auto& child : input->Child(3)->Children()) {
+ for (const auto& child : input->Child(3)->Children()) {
const auto pos = GetFieldPosition(inputItemType, child->Content());
auto inputColumnType = GetFieldType(inputItemType, *pos);
if (requiredColumns.contains(child->Content())) {
diff --git a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
index f2b188ae47c..05a2c047b9c 100644
--- a/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
+++ b/ydb/library/yql/minikql/computation/mkql_computation_node_graph.cpp
@@ -7,7 +7,7 @@
#include <ydb/library/yql/minikql/mkql_terminator.h>
#include <ydb/library/yql/minikql/mkql_string_util.h>
#include <util/system/env.h>
-#include <util/system/mutex.h>
+#include <util/system/mutex.h>
#include <util/digest/city.h>
#ifndef MKQL_DISABLE_CODEGEN
diff --git a/ydb/library/yql/providers/common/udf_resolve/yql_udf_resolver_with_index.cpp b/ydb/library/yql/providers/common/udf_resolve/yql_udf_resolver_with_index.cpp
index ac43a629b50..936abe09a3e 100644
--- a/ydb/library/yql/providers/common/udf_resolve/yql_udf_resolver_with_index.cpp
+++ b/ydb/library/yql/providers/common/udf_resolve/yql_udf_resolver_with_index.cpp
@@ -14,7 +14,7 @@
#include <util/generic/set.h>
#include <util/generic/string.h>
#include <util/system/guard.h>
-#include <util/system/mutex.h>
+#include <util/system/mutex.h>
namespace NYql {
namespace NCommon {
diff --git a/ydb/library/yql/providers/dq/service/interconnect_helpers.cpp b/ydb/library/yql/providers/dq/service/interconnect_helpers.cpp
index bef368a961f..869ce5a4b75 100644
--- a/ydb/library/yql/providers/dq/service/interconnect_helpers.cpp
+++ b/ydb/library/yql/providers/dq/service/interconnect_helpers.cpp
@@ -120,7 +120,7 @@ namespace NYql::NDqs {
setup->MaxActivityType = maxActivityType;
YQL_LOG(DEBUG) << "Initializing local services";
- setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0));
+ setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0));
if (IActor* schedulerActor = CreateSchedulerActor(schedulerConfig)) {
TActorId schedulerActorId = MakeSchedulerActorId();
setup->LocalServices.emplace_back(schedulerActorId, TActorSetupCmd(schedulerActor, TMailboxType::ReadAsFilled, 0));
@@ -202,7 +202,7 @@ namespace NYql::NDqs {
setup->Interconnect.ProxyActors.resize(maxNodeId + 1);
for (ui32 id = 1; id <= maxNodeId; ++id) {
if (nodeId != id) {
- IActor* actor = new TInterconnectProxyTCP(id, icCommon);
+ IActor* actor = new TInterconnectProxyTCP(id, icCommon);
setup->Interconnect.ProxyActors[id] = TActorSetupCmd(actor, TMailboxType::ReadAsFilled, 0);
}
}
diff --git a/ydb/library/yql/sql/v0/context.cpp b/ydb/library/yql/sql/v0/context.cpp
index a3a9013f2b7..446fc840ca3 100644
--- a/ydb/library/yql/sql/v0/context.cpp
+++ b/ydb/library/yql/sql/v0/context.cpp
@@ -275,7 +275,7 @@ bool TContext::DeclareVariable(const TString& varName, const TNodePtr& typeNode)
}
bool TContext::AddExports(const TVector<TString>& symbols) {
- for (const auto& symbol: symbols) {
+ for (const auto& symbol: symbols) {
if (Exports.contains(symbol)) {
Error() << "Duplicate export symbol: " << symbol;
return false;
diff --git a/ydb/library/yql/sql/v0/node.cpp b/ydb/library/yql/sql/v0/node.cpp
index 57f0c6a561f..6de1a3f934b 100644
--- a/ydb/library/yql/sql/v0/node.cpp
+++ b/ydb/library/yql/sql/v0/node.cpp
@@ -762,7 +762,7 @@ bool TColumns::IsColumnPossible(TContext& ctx, const TString& name) {
if (ctx.SimpleColumns) {
return true;
}
- for (const auto& real: Real) {
+ for (const auto& real: Real) {
const auto pos = real.find_first_of("*");
if (pos == TString::npos) {
continue;
@@ -1428,7 +1428,7 @@ TNodePtr ISource::BuildAggregation(const TString& label) {
}
auto keysTuple = Y();
- for (const auto& key: GroupKeys) {
+ for (const auto& key: GroupKeys) {
keysTuple = L(keysTuple, BuildQuotedAtom(Pos, key));
}
@@ -1603,7 +1603,7 @@ TNodePtr ISource::BuildCalcOverWindow(TContext& ctx, const TString& label, const
return nullptr;
}
auto keysTuple = Y();
- for (const auto& key: partition.Partitions) {
+ for (const auto& key: partition.Partitions) {
keysTuple = L(keysTuple, AliasOrColumn(key, GetJoin()));
}
auto frames = Y();
@@ -2330,7 +2330,7 @@ public:
YQL_ENSURE(!Node, "TAccessNode::Clone: Node should not be initialized");
TVector<TIdPart> cloneIds;
cloneIds.reserve(Ids.size());
- for (const auto& id: Ids) {
+ for (const auto& id: Ids) {
cloneIds.emplace_back(id.Clone());
}
auto copy = new TAccessNode(Pos, cloneIds, IsLookup);
diff --git a/ydb/library/yql/sql/v0/select.cpp b/ydb/library/yql/sql/v0/select.cpp
index ef47023be15..328c0b6f30f 100644
--- a/ydb/library/yql/sql/v0/select.cpp
+++ b/ydb/library/yql/sql/v0/select.cpp
@@ -1916,7 +1916,7 @@ public:
Y_UNUSED(ctx);
hint = 0;
if (GroupByColumns.empty()) {
- for (const auto& groupByNode: GroupBy) {
+ for (const auto& groupByNode: GroupBy) {
auto namePtr = groupByNode->GetColumnName();
YQL_ENSURE(namePtr);
GroupByColumns.insert(*namePtr);
diff --git a/ydb/library/yql/sql/v0/sql.cpp b/ydb/library/yql/sql/v0/sql.cpp
index b028fc04398..c3b590e4f0b 100644
--- a/ydb/library/yql/sql/v0/sql.cpp
+++ b/ydb/library/yql/sql/v0/sql.cpp
@@ -2206,7 +2206,7 @@ TNodePtr TSqlExpression::SmartParenthesis(const TRule_smart_parenthesis& node) {
bool hasAliases = false;
bool hasUnnamed = false;
- for (const auto& expr: exprs) {
+ for (const auto& expr: exprs) {
if (expr->GetLabel()) {
hasAliases = true;
} else {
@@ -3138,7 +3138,7 @@ TSourcePtr TSqlSelect::SelectCore(const TRule_select_core& node, const TWriteSet
if (!clause.Build(node.GetBlock10().GetRule_group_by_clause1(), stream)) {
return nullptr;
}
- for (const auto& exprAlias: clause.Aliases()) {
+ for (const auto& exprAlias: clause.Aliases()) {
YQL_ENSURE(exprAlias.first == exprAlias.second->GetLabel());
groupByExpr.emplace_back(exprAlias.second);
}
@@ -3428,10 +3428,10 @@ THoppingWindowSpecPtr TGroupByClause::GetHoppingWindow() {
TVector<TNodePtr> TGroupByClause::MultiplyGroupingSets(const TVector<TNodePtr>& lhs, const TVector<TNodePtr>& rhs) const {
TVector<TNodePtr> content;
- for (const auto& leftNode: lhs) {
+ for (const auto& leftNode: lhs) {
auto leftPtr = leftNode->ContentListPtr();
YQL_ENSURE(leftPtr, "Unable to multiply grouping sets");
- for (const auto& rightNode: rhs) {
+ for (const auto& rightNode: rhs) {
TVector<TNodePtr> mulItem(leftPtr->begin(), leftPtr->end());
auto rightPtr = rightNode->ContentListPtr();
YQL_ENSURE(rightPtr, "Unable to multiply grouping sets");
diff --git a/ydb/library/yql/sql/v1/node.cpp b/ydb/library/yql/sql/v1/node.cpp
index 870bbd9cc7f..e158ebbd328 100644
--- a/ydb/library/yql/sql/v1/node.cpp
+++ b/ydb/library/yql/sql/v1/node.cpp
@@ -942,7 +942,7 @@ bool TColumns::IsColumnPossible(TContext& ctx, const TString& name) {
if (ctx.SimpleColumns) {
return true;
}
- for (const auto& real: Real) {
+ for (const auto& real: Real) {
const auto pos = real.find_first_of("*");
if (pos == TString::npos) {
continue;
@@ -1949,7 +1949,7 @@ TNodePtr ISource::BuildCalcOverWindow(TContext& ctx, const TString& label) {
frames = L(frames, callOnFrame);
auto keysTuple = Y();
- for (const auto& key: spec->Partitions) {
+ for (const auto& key: spec->Partitions) {
if (!dynamic_cast<TSessionWindow*>(key.Get())) {
keysTuple = L(keysTuple, AliasOrColumn(key, GetJoin()));
}
@@ -2855,7 +2855,7 @@ public:
YQL_ENSURE(!Node, "TAccessNode::Clone: Node should not be initialized");
TVector<TIdPart> cloneIds;
cloneIds.reserve(Ids.size());
- for (const auto& id: Ids) {
+ for (const auto& id: Ids) {
cloneIds.emplace_back(id.Clone());
}
auto copy = new TAccessNode(Pos, cloneIds, IsLookup);
diff --git a/ydb/library/yql/sql/v1/select.cpp b/ydb/library/yql/sql/v1/select.cpp
index 2841f05a5b5..888cfe62c44 100644
--- a/ydb/library/yql/sql/v1/select.cpp
+++ b/ydb/library/yql/sql/v1/select.cpp
@@ -2407,7 +2407,7 @@ public:
Y_UNUSED(ctx);
hint = 0;
if (GroupByColumns.empty()) {
- for (const auto& groupByNode: GroupBy) {
+ for (const auto& groupByNode: GroupBy) {
auto namePtr = groupByNode->GetColumnName();
YQL_ENSURE(namePtr);
GroupByColumns.insert(*namePtr);
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index ab5a8647885..17409e51cc8 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -5426,7 +5426,7 @@ TNodePtr TSqlExpression::SmartParenthesis(const TRule_smart_parenthesis& node) {
bool hasAliases = false;
bool hasUnnamed = false;
- for (const auto& expr: exprs) {
+ for (const auto& expr: exprs) {
if (expr->GetLabel()) {
hasAliases = true;
} else {
@@ -6620,7 +6620,7 @@ TSourcePtr TSqlSelect::SelectCore(const TRule_select_core& node, const TWriteSet
if (!clause.Build(node.GetBlock11().GetRule_group_by_clause1(), source->IsStream())) {
return nullptr;
}
- for (const auto& exprAlias: clause.Aliases()) {
+ for (const auto& exprAlias: clause.Aliases()) {
YQL_ENSURE(exprAlias.first == exprAlias.second->GetLabel());
groupByExpr.emplace_back(exprAlias.second);
}
@@ -7106,14 +7106,14 @@ bool TGroupByClause::IsCompactGroupBy() const {
TMaybe<TVector<TNodePtr>> TGroupByClause::MultiplyGroupingSets(const TVector<TNodePtr>& lhs, const TVector<TNodePtr>& rhs) const {
TVector<TNodePtr> content;
- for (const auto& leftNode: lhs) {
+ for (const auto& leftNode: lhs) {
auto leftPtr = leftNode->ContentListPtr();
if (!leftPtr) {
// TODO: shouldn't happen
Ctx.Error() << "Unable to multiply grouping sets";
return {};
}
- for (const auto& rightNode: rhs) {
+ for (const auto& rightNode: rhs) {
TVector<TNodePtr> mulItem(leftPtr->begin(), leftPtr->end());
auto rightPtr = rightNode->ContentListPtr();
if (!rightPtr) {
diff --git a/ydb/library/yql/utils/log/log.cpp b/ydb/library/yql/utils/log/log.cpp
index b62bfeb907a..5efa132088e 100644
--- a/ydb/library/yql/utils/log/log.cpp
+++ b/ydb/library/yql/utils/log/log.cpp
@@ -34,7 +34,7 @@ void WriteLocalTime(IOutputStream* out) {
out->Write(buf, sizeof(buf) - 1);
}
-class TLimitedLogBackend final : public TLogBackend {
+class TLimitedLogBackend final : public TLogBackend {
public:
TLimitedLogBackend(TAutoPtr<TLogBackend> b, TAtomic& flag, ui64 limit) noexcept
: Backend(b)
diff --git a/ydb/public/lib/base/msgbus.cpp b/ydb/public/lib/base/msgbus.cpp
index 3de18610988..feca8b770f1 100644
--- a/ydb/public/lib/base/msgbus.cpp
+++ b/ydb/public/lib/base/msgbus.cpp
@@ -8,10 +8,10 @@ void ExplainProposeTransactionStatus(ui32 status, TString& name, TString& descri
name = ToString(status);
description = "Unknown status";
- auto field = NKikimrClient::TResponse::descriptor()->FindFieldByNumber(
- NKikimrClient::TResponse::kProxyErrorCodeFieldNumber);
+ auto field = NKikimrClient::TResponse::descriptor()->FindFieldByNumber(
+ NKikimrClient::TResponse::kProxyErrorCodeFieldNumber);
- auto extension = field->options().GetExtension(NKikimrClient::EnumValueHint);
+ auto extension = field->options().GetExtension(NKikimrClient::EnumValueHint);
for (auto item : extension.GetHints()) {
if (status == item.GetValue()) {
@@ -26,10 +26,10 @@ void ExplainExecutionEngineStatus(ui32 status, TString& name, TString& descripti
name = ToString(status);
description = "Unknown status";
- auto field = NKikimrClient::TResponse::descriptor()->FindFieldByNumber(
- NKikimrClient::TResponse::kExecutionEngineStatusFieldNumber);
+ auto field = NKikimrClient::TResponse::descriptor()->FindFieldByNumber(
+ NKikimrClient::TResponse::kExecutionEngineStatusFieldNumber);
- auto extension = field->options().GetExtension(NKikimrClient::EnumValueHint);
+ auto extension = field->options().GetExtension(NKikimrClient::EnumValueHint);
for (auto item : extension.GetHints()) {
if (status == item.GetValue()) {
diff --git a/ydb/public/lib/base/msgbus.h b/ydb/public/lib/base/msgbus.h
index f11bd9771f1..cc0a501ceeb 100644
--- a/ydb/public/lib/base/msgbus.h
+++ b/ydb/public/lib/base/msgbus.h
@@ -49,8 +49,8 @@ enum {
MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST = 10435, // deprecated
MTYPE_CLIENT_OLD_FLAT_DESCRIBE_RESPONSE = 10436, // deprecated
MTYPE_CLIENT_CREATE_TABLET = 10437,
- MTYPE_CLIENT_LOAD_REQUEST = 10438,
- MTYPE_CLIENT_LOAD_RESPONSE = 10439,
+ MTYPE_CLIENT_LOAD_REQUEST = 10438,
+ MTYPE_CLIENT_LOAD_RESPONSE = 10439,
MTYPE_CLIENT_DIRECT_REQUEST_JOB_EXECUTION_STATUS = 10440, // deprecated
MTYPE_CLIENT_PERSQUEUE = 10441,
MTYPE_CLIENT_DB_SCHEMA = 10443,
@@ -61,13 +61,13 @@ enum {
MTYPE_CLIENT_KEYVALUE = 10448,
MTYPE_CLIENT_DB_BATCH = 10449,
MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST = 10450,
- MTYPE_CLIENT_LOCAL_SCHEME_TX = 10453,
- MTYPE_CLIENT_GET_REQUEST = 10454,
- MTYPE_CLIENT_GET_RESPONSE = 10455,
+ MTYPE_CLIENT_LOCAL_SCHEME_TX = 10453,
+ MTYPE_CLIENT_GET_REQUEST = 10454,
+ MTYPE_CLIENT_GET_RESPONSE = 10455,
MTYPE_CLIENT_DB_QUERY = 10456,
MTYPE_CLIENT_TABLET_COUNTERS_REQUEST = 10457,
MTYPE_CLIENT_CANCEL_BACKUP = 10458,
- MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST = 10459,
+ MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST = 10459,
MTYPE_CLIENT_DRAIN_NODE = 10460,
MTYPE_CLIENT_FILL_NODE = 10461,
MTYPE_CLIENT_RESOLVE_NODE = 10462,
@@ -83,56 +83,56 @@ enum {
MTYPE_CLIENT_STREAM_REQUEST = 10472,
MTYPE_CLIENT_S3_LISTING_REQUEST = 10474,
MTYPE_CLIENT_S3_LISTING_RESPONSE = 10475,
- MTYPE_CLIENT_INTERCONNECT_DEBUG = 10476,
+ MTYPE_CLIENT_INTERCONNECT_DEBUG = 10476,
MTYPE_CLIENT_CONSOLE_REQUEST = 10477,
MTYPE_CLIENT_CONSOLE_RESPONSE = 10478,
MTYPE_CLIENT_TENANT_SLOT_BROKER_REQUEST = 10479,
MTYPE_CLIENT_TENANT_SLOT_BROKER_RESPONSE = 10480,
- MTYPE_CLIENT_TEST_SHARD_CONTROL = 10481,
+ MTYPE_CLIENT_TEST_SHARD_CONTROL = 10481,
};
template <typename InstanceType, class TBufferRecord, int MType>
struct TBusMessage : NBus::TBusBufferMessage<TBufferRecord, MType> { NBus::TBusBufferBase* New() override { return new InstanceType; } };
// we had to define structs instead of typedef because we need to create real C++ type, so we could use RTTI names later in protocol registration
-struct TBusRequest : TBusMessage<TBusRequest, NKikimrClient::TRequest, MTYPE_CLIENT_REQUEST> {};
-struct TBusResponse : TBusMessage<TBusResponse, NKikimrClient::TResponse, MTYPE_CLIENT_RESPONSE> {};
-struct TBusFakeConfigDummy : TBusMessage<TBusFakeConfigDummy, NKikimrClient::TFakeConfigDummy, MTYPE_CLIENT_FAKE_CONFIGDUMMY> {};
-struct TBusSchemeInitRoot : TBusMessage<TBusSchemeInitRoot, NKikimrClient::TSchemeInitRoot, MTYPE_CLIENT_SCHEME_INITROOT> {};
-struct TBusBSAdm : TBusMessage<TBusBSAdm, NKikimrClient::TBSAdm, MTYPE_CLIENT_BSADM> {};
-struct TBusTypesRequest : TBusMessage<TBusTypesRequest, NKikimrClient::TTypeMetadataRequest, MTYPE_CLIENT_TYPES_REQUEST> {};
-struct TBusTypesResponse : TBusMessage<TBusTypesResponse, NKikimrClient::TTypeMetadataResponse, MTYPE_CLIENT_TYPES_RESPONSE> {};
-struct TBusHiveCreateTablet : TBusMessage<TBusHiveCreateTablet, NKikimrClient::THiveCreateTablet, MTYPE_CLIENT_HIVE_CREATE_TABLET> {};
-struct TBusOldHiveCreateTablet : TBusMessage<TBusOldHiveCreateTablet, NKikimrClient::THiveCreateTablet, MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET> {};
-struct TBusHiveCreateTabletResult : TBusMessage<TBusHiveCreateTabletResult, NKikimrClient::THiveCreateTabletResult, MTYPE_CLIENT_HIVE_CREATE_TABLET_RESULT> {};
-struct TBusLocalEnumerateTablets : TBusMessage<TBusLocalEnumerateTablets, NKikimrClient::TLocalEnumerateTablets, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS> {};
-struct TBusOldLocalEnumerateTablets : TBusMessage<TBusOldLocalEnumerateTablets, NKikimrClient::TLocalEnumerateTablets, MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS> {};
-struct TBusLocalEnumerateTabletsResult : TBusMessage<TBusLocalEnumerateTabletsResult, NKikimrClient::TLocalEnumerateTabletsResult, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS_RESULT> {};
-struct TBusKeyValue : TBusMessage<TBusKeyValue, NKikimrClient::TKeyValueRequest, MTYPE_CLIENT_KEYVALUE> {};
-struct TBusOldKeyValue : TBusMessage<TBusOldKeyValue, NKikimrClient::TKeyValueRequest, MTYPE_CLIENT_OLD_KEYVALUE> {};
-struct TBusKeyValueResponse : TBusMessage<TBusKeyValueResponse, NKikimrClient::TKeyValueResponse, MTYPE_CLIENT_KEYVALUE_RESPONSE> {};
-struct TBusPersQueue : TBusMessage<TBusPersQueue, NKikimrClient::TPersQueueRequest, MTYPE_CLIENT_PERSQUEUE> {};
-struct TBusMessageBusTraceRequest : TBusMessage<TBusMessageBusTraceRequest, NKikimrClient::TMessageBusTraceRequest, MTYPE_CLIENT_MESSAGE_BUS_TRACE> {};
-struct TBusMessageBusTraceStatus : TBusMessage<TBusMessageBusTraceStatus, NKikimrClient::TMessageBusTraceStatus, MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS> {};
-struct TBusTabletKillRequest : TBusMessage<TBusTabletKillRequest, NKikimrClient::TTabletKillRequest, MTYPE_CLIENT_TABLET_KILL_REQUEST> {};
-struct TBusTabletStateRequest : TBusMessage<TBusTabletStateRequest, NKikimrClient::TTabletStateRequest, MTYPE_CLIENT_TABLET_STATE_REQUEST> {};
+struct TBusRequest : TBusMessage<TBusRequest, NKikimrClient::TRequest, MTYPE_CLIENT_REQUEST> {};
+struct TBusResponse : TBusMessage<TBusResponse, NKikimrClient::TResponse, MTYPE_CLIENT_RESPONSE> {};
+struct TBusFakeConfigDummy : TBusMessage<TBusFakeConfigDummy, NKikimrClient::TFakeConfigDummy, MTYPE_CLIENT_FAKE_CONFIGDUMMY> {};
+struct TBusSchemeInitRoot : TBusMessage<TBusSchemeInitRoot, NKikimrClient::TSchemeInitRoot, MTYPE_CLIENT_SCHEME_INITROOT> {};
+struct TBusBSAdm : TBusMessage<TBusBSAdm, NKikimrClient::TBSAdm, MTYPE_CLIENT_BSADM> {};
+struct TBusTypesRequest : TBusMessage<TBusTypesRequest, NKikimrClient::TTypeMetadataRequest, MTYPE_CLIENT_TYPES_REQUEST> {};
+struct TBusTypesResponse : TBusMessage<TBusTypesResponse, NKikimrClient::TTypeMetadataResponse, MTYPE_CLIENT_TYPES_RESPONSE> {};
+struct TBusHiveCreateTablet : TBusMessage<TBusHiveCreateTablet, NKikimrClient::THiveCreateTablet, MTYPE_CLIENT_HIVE_CREATE_TABLET> {};
+struct TBusOldHiveCreateTablet : TBusMessage<TBusOldHiveCreateTablet, NKikimrClient::THiveCreateTablet, MTYPE_CLIENT_OLD_HIVE_CREATE_TABLET> {};
+struct TBusHiveCreateTabletResult : TBusMessage<TBusHiveCreateTabletResult, NKikimrClient::THiveCreateTabletResult, MTYPE_CLIENT_HIVE_CREATE_TABLET_RESULT> {};
+struct TBusLocalEnumerateTablets : TBusMessage<TBusLocalEnumerateTablets, NKikimrClient::TLocalEnumerateTablets, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS> {};
+struct TBusOldLocalEnumerateTablets : TBusMessage<TBusOldLocalEnumerateTablets, NKikimrClient::TLocalEnumerateTablets, MTYPE_CLIENT_OLD_LOCAL_ENUMERATE_TABLETS> {};
+struct TBusLocalEnumerateTabletsResult : TBusMessage<TBusLocalEnumerateTabletsResult, NKikimrClient::TLocalEnumerateTabletsResult, MTYPE_CLIENT_LOCAL_ENUMERATE_TABLETS_RESULT> {};
+struct TBusKeyValue : TBusMessage<TBusKeyValue, NKikimrClient::TKeyValueRequest, MTYPE_CLIENT_KEYVALUE> {};
+struct TBusOldKeyValue : TBusMessage<TBusOldKeyValue, NKikimrClient::TKeyValueRequest, MTYPE_CLIENT_OLD_KEYVALUE> {};
+struct TBusKeyValueResponse : TBusMessage<TBusKeyValueResponse, NKikimrClient::TKeyValueResponse, MTYPE_CLIENT_KEYVALUE_RESPONSE> {};
+struct TBusPersQueue : TBusMessage<TBusPersQueue, NKikimrClient::TPersQueueRequest, MTYPE_CLIENT_PERSQUEUE> {};
+struct TBusMessageBusTraceRequest : TBusMessage<TBusMessageBusTraceRequest, NKikimrClient::TMessageBusTraceRequest, MTYPE_CLIENT_MESSAGE_BUS_TRACE> {};
+struct TBusMessageBusTraceStatus : TBusMessage<TBusMessageBusTraceStatus, NKikimrClient::TMessageBusTraceStatus, MTYPE_CLIENT_MESSAGE_BUS_TRACE_STATUS> {};
+struct TBusTabletKillRequest : TBusMessage<TBusTabletKillRequest, NKikimrClient::TTabletKillRequest, MTYPE_CLIENT_TABLET_KILL_REQUEST> {};
+struct TBusTabletStateRequest : TBusMessage<TBusTabletStateRequest, NKikimrClient::TTabletStateRequest, MTYPE_CLIENT_TABLET_STATE_REQUEST> {};
struct TBusTabletCountersRequest : TBusMessage<TBusTabletCountersRequest, NKikimrClient::TTabletCountersRequest, MTYPE_CLIENT_TABLET_COUNTERS_REQUEST> {};
-struct TBusTabletLocalMKQL : TBusMessage<TBusTabletLocalMKQL, NKikimrClient::TLocalMKQL, MTYPE_CLIENT_LOCAL_MINIKQL> {};
-struct TBusTabletLocalSchemeTx : TBusMessage<TBusTabletLocalSchemeTx, NKikimrClient::TLocalSchemeTx, MTYPE_CLIENT_LOCAL_SCHEME_TX> {};
-struct TBusSchemeOperation : TBusMessage<TBusSchemeOperation, NKikimrClient::TSchemeOperation, MTYPE_CLIENT_FLAT_TX_REQUEST> {};
-struct TBusSchemeOperationStatus : TBusMessage<TBusSchemeOperationStatus, NKikimrClient::TSchemeOperationStatus, MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST> {};
-struct TBusSchemeDescribe : TBusMessage<TBusSchemeDescribe, NKikimrClient::TSchemeDescribe, MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST> {};
-struct TBusOldFlatDescribeRequest : TBusMessage<TBusOldFlatDescribeRequest, NKikimrClient::TSchemeDescribe, MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST> {};
-struct TBusOldFlatDescribeResponse : TBusMessage<TBusOldFlatDescribeResponse, NKikimrClient::TFlatDescribeResponse, MTYPE_CLIENT_OLD_FLAT_DESCRIBE_RESPONSE> {};
-struct TBusBsTestLoadRequest : TBusMessage<TBusBsTestLoadRequest, NKikimrClient::TBsTestLoadRequest, MTYPE_CLIENT_LOAD_REQUEST> {};
-struct TBusBsTestLoadResponse : TBusMessage<TBusBsTestLoadResponse, NKikimrClient::TBsTestLoadResponse, MTYPE_CLIENT_LOAD_RESPONSE> {};
-struct TBusBsGetRequest : TBusMessage<TBusBsGetRequest, NKikimrClient::TBsGetRequest, MTYPE_CLIENT_GET_REQUEST> {};
-struct TBusBsGetResponse : TBusMessage<TBusBsGetResponse, NKikimrClient::TBsGetResponse, MTYPE_CLIENT_GET_RESPONSE> {};
-struct TBusDbSchema : TBusMessage<TBusDbSchema, NKikimrClient::TJSON, MTYPE_CLIENT_DB_SCHEMA> {};
-struct TBusDbOperation : TBusMessage<TBusDbOperation, NKikimrClient::TJSON, MTYPE_CLIENT_DB_OPERATION> {};
-struct TBusDbResponse : TBusMessage<TBusDbResponse, NKikimrClient::TJSON, MTYPE_CLIENT_DB_RESPONSE> {};
-struct TBusDbBatch : TBusMessage<TBusDbBatch, NKikimrClient::TJSON, MTYPE_CLIENT_DB_BATCH> {};
-struct TBusBlobStorageConfigRequest : TBusMessage<TBusBlobStorageConfigRequest, NKikimrClient::TBlobStorageConfigRequest, MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST> {};
+struct TBusTabletLocalMKQL : TBusMessage<TBusTabletLocalMKQL, NKikimrClient::TLocalMKQL, MTYPE_CLIENT_LOCAL_MINIKQL> {};
+struct TBusTabletLocalSchemeTx : TBusMessage<TBusTabletLocalSchemeTx, NKikimrClient::TLocalSchemeTx, MTYPE_CLIENT_LOCAL_SCHEME_TX> {};
+struct TBusSchemeOperation : TBusMessage<TBusSchemeOperation, NKikimrClient::TSchemeOperation, MTYPE_CLIENT_FLAT_TX_REQUEST> {};
+struct TBusSchemeOperationStatus : TBusMessage<TBusSchemeOperationStatus, NKikimrClient::TSchemeOperationStatus, MTYPE_CLIENT_FLAT_TX_STATUS_REQUEST> {};
+struct TBusSchemeDescribe : TBusMessage<TBusSchemeDescribe, NKikimrClient::TSchemeDescribe, MTYPE_CLIENT_FLAT_DESCRIBE_REQUEST> {};
+struct TBusOldFlatDescribeRequest : TBusMessage<TBusOldFlatDescribeRequest, NKikimrClient::TSchemeDescribe, MTYPE_CLIENT_OLD_FLAT_DESCRIBE_REQUEST> {};
+struct TBusOldFlatDescribeResponse : TBusMessage<TBusOldFlatDescribeResponse, NKikimrClient::TFlatDescribeResponse, MTYPE_CLIENT_OLD_FLAT_DESCRIBE_RESPONSE> {};
+struct TBusBsTestLoadRequest : TBusMessage<TBusBsTestLoadRequest, NKikimrClient::TBsTestLoadRequest, MTYPE_CLIENT_LOAD_REQUEST> {};
+struct TBusBsTestLoadResponse : TBusMessage<TBusBsTestLoadResponse, NKikimrClient::TBsTestLoadResponse, MTYPE_CLIENT_LOAD_RESPONSE> {};
+struct TBusBsGetRequest : TBusMessage<TBusBsGetRequest, NKikimrClient::TBsGetRequest, MTYPE_CLIENT_GET_REQUEST> {};
+struct TBusBsGetResponse : TBusMessage<TBusBsGetResponse, NKikimrClient::TBsGetResponse, MTYPE_CLIENT_GET_RESPONSE> {};
+struct TBusDbSchema : TBusMessage<TBusDbSchema, NKikimrClient::TJSON, MTYPE_CLIENT_DB_SCHEMA> {};
+struct TBusDbOperation : TBusMessage<TBusDbOperation, NKikimrClient::TJSON, MTYPE_CLIENT_DB_OPERATION> {};
+struct TBusDbResponse : TBusMessage<TBusDbResponse, NKikimrClient::TJSON, MTYPE_CLIENT_DB_RESPONSE> {};
+struct TBusDbBatch : TBusMessage<TBusDbBatch, NKikimrClient::TJSON, MTYPE_CLIENT_DB_BATCH> {};
+struct TBusBlobStorageConfigRequest : TBusMessage<TBusBlobStorageConfigRequest, NKikimrClient::TBlobStorageConfigRequest, MTYPE_CLIENT_BLOB_STORAGE_CONFIG_REQUEST> {};
struct TBusDrainNode : TBusMessage<TBusDrainNode, NKikimrClient::TDrainNodeRequest, MTYPE_CLIENT_DRAIN_NODE> {};
struct TBusFillNode : TBusMessage<TBusFillNode, NKikimrClient::TFillNodeRequest, MTYPE_CLIENT_FILL_NODE> {};
struct TBusResolveNode : TBusMessage<TBusResolveNode, NKikimrClient::TResolveNodeRequest, MTYPE_CLIENT_RESOLVE_NODE> {};
@@ -147,10 +147,10 @@ struct TBusWhoAmI : TBusMessage<TBusWhoAmI, NKikimrClient::TWhoAmI, MTYPE_CLIENT
struct TBusStreamRequest : TBusMessage<TBusStreamRequest, NKikimrClient::TRequest, MTYPE_CLIENT_STREAM_REQUEST> {};
struct TBusS3ListingRequest : TBusMessage<TBusS3ListingRequest, NKikimrClient::TS3ListingRequest, MTYPE_CLIENT_S3_LISTING_REQUEST> {};
struct TBusS3ListingResponse : TBusMessage<TBusS3ListingResponse, NKikimrClient::TS3ListingResponse, MTYPE_CLIENT_S3_LISTING_RESPONSE> {};
-struct TBusInterconnectDebug : TBusMessage<TBusInterconnectDebug, NKikimrClient::TInterconnectDebug, MTYPE_CLIENT_INTERCONNECT_DEBUG> {};
+struct TBusInterconnectDebug : TBusMessage<TBusInterconnectDebug, NKikimrClient::TInterconnectDebug, MTYPE_CLIENT_INTERCONNECT_DEBUG> {};
struct TBusConsoleRequest : TBusMessage<TBusConsoleRequest, NKikimrClient::TConsoleRequest, MTYPE_CLIENT_CONSOLE_REQUEST> {};
struct TBusConsoleResponse : TBusMessage<TBusConsoleResponse, NKikimrClient::TConsoleResponse, MTYPE_CLIENT_CONSOLE_RESPONSE> {};
-struct TBusTestShardControlRequest : TBusMessage<TBusTestShardControlRequest, NKikimrClient::TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL> {};
+struct TBusTestShardControlRequest : TBusMessage<TBusTestShardControlRequest, NKikimrClient::TTestShardControlRequest, MTYPE_CLIENT_TEST_SHARD_CONTROL> {};
class TBusResponseStatus : public TBusResponse {
public:
@@ -216,20 +216,20 @@ public:
RegisterType(new TBusTabletCountersRequest);
RegisterType(new TBusTabletLocalMKQL);
RegisterType(new TBusTabletLocalSchemeTx);
- RegisterType(new TBusSchemeOperation);
- RegisterType(new TBusSchemeOperationStatus);
- RegisterType(new TBusSchemeDescribe);
+ RegisterType(new TBusSchemeOperation);
+ RegisterType(new TBusSchemeOperationStatus);
+ RegisterType(new TBusSchemeDescribe);
RegisterType(new TBusOldFlatDescribeRequest);
RegisterType(new TBusOldFlatDescribeResponse);
- RegisterType(new TBusBsTestLoadRequest);
- RegisterType(new TBusBsTestLoadResponse);
- RegisterType(new TBusBsGetRequest);
- RegisterType(new TBusBsGetResponse);
+ RegisterType(new TBusBsTestLoadRequest);
+ RegisterType(new TBusBsTestLoadResponse);
+ RegisterType(new TBusBsGetRequest);
+ RegisterType(new TBusBsGetResponse);
RegisterType(new TBusDbSchema);
RegisterType(new TBusDbOperation);
RegisterType(new TBusDbResponse);
RegisterType(new TBusDbBatch);
- RegisterType(new TBusBlobStorageConfigRequest);
+ RegisterType(new TBusBlobStorageConfigRequest);
RegisterType(new TBusDrainNode);
RegisterType(new TBusFillNode);
RegisterType(new TBusResolveNode);
@@ -242,10 +242,10 @@ public:
RegisterType(new TBusStreamRequest);
RegisterType(new TBusS3ListingRequest);
RegisterType(new TBusS3ListingResponse);
- RegisterType(new TBusInterconnectDebug);
+ RegisterType(new TBusInterconnectDebug);
RegisterType(new TBusConsoleRequest);
RegisterType(new TBusConsoleResponse);
- RegisterType(new TBusTestShardControlRequest);
+ RegisterType(new TBusTestShardControlRequest);
}
const static ui32 DefaultPort = 2134;
@@ -277,6 +277,6 @@ IMessageBusServer* CreateMsgBusTracingServer(
inline NActors::TActorId CreateMsgBusProxyId() {
return NActors::TActorId(0, "MsgBusProxy");
}
-
-}
+
}
+}
diff --git a/ydb/public/lib/deprecated/client/grpc_client.cpp b/ydb/public/lib/deprecated/client/grpc_client.cpp
index dbf808ef752..8ffb22ee3c4 100644
--- a/ydb/public/lib/deprecated/client/grpc_client.cpp
+++ b/ydb/public/lib/deprecated/client/grpc_client.cpp
@@ -1,17 +1,17 @@
-#include "grpc_client.h"
+#include "grpc_client.h"
#include <ydb/core/protos/grpc.grpc.pb.h>
-#include <util/system/thread.h>
-#include <util/system/mutex.h>
-#include <util/generic/maybe.h>
-#include <util/generic/queue.h>
+#include <util/system/thread.h>
+#include <util/system/mutex.h>
+#include <util/generic/maybe.h>
+#include <util/generic/queue.h>
#include <util/generic/set.h>
-#include <grpc++/grpc++.h>
-
-namespace NKikimr {
- namespace NGRpcProxy {
-
+#include <grpc++/grpc++.h>
+
+namespace NKikimr {
+ namespace NGRpcProxy {
+
class TGRpcClient::TImpl : ISimpleThread {
struct IProcessorBase {
virtual ~IProcessorBase() = default;
@@ -19,80 +19,80 @@ namespace NKikimr {
};
struct IRequestProcessor : public IProcessorBase
- {
- virtual void Finished() = 0;
- };
-
+ {
+ virtual void Finished() = 0;
+ };
+
struct IStreamRequestReadProcessor : public IProcessorBase
{
virtual void InvokeProcess() = 0;
virtual void InvokeFinish() = 0;
};
- public:
- using TStub = NKikimrClient::TGRpcServer::Stub;
-
- private:
- template<typename TRequest, typename TResponse>
- class TRequestProcessor
- : public IRequestProcessor
- {
- public:
- using TAsyncReaderPtr = std::unique_ptr<grpc::ClientAsyncResponseReader<TResponse>>;
- using TAsyncRequest = TAsyncReaderPtr (TStub::*)(grpc::ClientContext*, const TRequest&, grpc::CompletionQueue*);
-
- private:
- grpc::ClientContext Context;
- TAsyncReaderPtr Reader;
- TImpl *Impl;
- TAsyncRequest AsyncRequest;
- TRequest Params;
- const TCallback<TResponse> Callback;
- TResponse Reply;
- grpc::Status Status;
- bool Invoked = false;
-
- public:
- TRequestProcessor(TImpl *impl, TAsyncRequest asyncRequest, const TRequest& params,
- TCallback<TResponse>&& callback, const TMaybe<TDuration>& timeout)
- : Impl(impl)
- , AsyncRequest(asyncRequest)
- , Params(params)
- , Callback(std::move(callback))
- {
- if (timeout) {
- Context.set_deadline(std::chrono::system_clock::now() +
- std::chrono::microseconds(timeout->MicroSeconds()));
- }
- }
-
- ~TRequestProcessor() {
- if (!Invoked) {
+ public:
+ using TStub = NKikimrClient::TGRpcServer::Stub;
+
+ private:
+ template<typename TRequest, typename TResponse>
+ class TRequestProcessor
+ : public IRequestProcessor
+ {
+ public:
+ using TAsyncReaderPtr = std::unique_ptr<grpc::ClientAsyncResponseReader<TResponse>>;
+ using TAsyncRequest = TAsyncReaderPtr (TStub::*)(grpc::ClientContext*, const TRequest&, grpc::CompletionQueue*);
+
+ private:
+ grpc::ClientContext Context;
+ TAsyncReaderPtr Reader;
+ TImpl *Impl;
+ TAsyncRequest AsyncRequest;
+ TRequest Params;
+ const TCallback<TResponse> Callback;
+ TResponse Reply;
+ grpc::Status Status;
+ bool Invoked = false;
+
+ public:
+ TRequestProcessor(TImpl *impl, TAsyncRequest asyncRequest, const TRequest& params,
+ TCallback<TResponse>&& callback, const TMaybe<TDuration>& timeout)
+ : Impl(impl)
+ , AsyncRequest(asyncRequest)
+ , Params(params)
+ , Callback(std::move(callback))
+ {
+ if (timeout) {
+ Context.set_deadline(std::chrono::system_clock::now() +
+ std::chrono::microseconds(timeout->MicroSeconds()));
+ }
+ }
+
+ ~TRequestProcessor() {
+ if (!Invoked) {
TGrpcError error = {"request left unhandled", -1};
- Callback(&error, Reply);
- }
- }
-
- private:
- void Start() override {
- Reader = (Impl->Stub.*AsyncRequest)(&Context, Params, &Impl->CQ);
- Reader->Finish(&Reply, &Status, this);
- }
-
- void Finished() override {
- Y_VERIFY(!Invoked);
- Invoked = true;
-
- if (Status.ok()) {
- Callback(nullptr, Reply);
- } else {
- const auto& msg = Status.error_message();
+ Callback(&error, Reply);
+ }
+ }
+
+ private:
+ void Start() override {
+ Reader = (Impl->Stub.*AsyncRequest)(&Context, Params, &Impl->CQ);
+ Reader->Finish(&Reply, &Status, this);
+ }
+
+ void Finished() override {
+ Y_VERIFY(!Invoked);
+ Invoked = true;
+
+ if (Status.ok()) {
+ Callback(nullptr, Reply);
+ } else {
+ const auto& msg = Status.error_message();
TGrpcError error = {TString(msg.data(), msg.length()), Status.error_code()};
- Callback(&error, Reply);
- }
- }
- };
-
+ Callback(&error, Reply);
+ }
+ }
+ };
+
template<typename TRequest, typename TResponse>
class TStreamRequestProcessor
: public IStreamRequestReadProcessor
@@ -175,52 +175,52 @@ namespace NKikimr {
}
};
- private:
+ private:
std::shared_ptr<grpc::ChannelInterface> Channel;
- TStub Stub;
- grpc::CompletionQueue CQ;
- TMaybe<TDuration> Timeout;
- ui32 MaxInFlight = 0;
- ui32 InFlight = 0;
+ TStub Stub;
+ grpc::CompletionQueue CQ;
+ TMaybe<TDuration> Timeout;
+ ui32 MaxInFlight = 0;
+ ui32 InFlight = 0;
TQueue<THolder<IProcessorBase>> PendingQ;
- TMutex Mutex;
+ TMutex Mutex;
TSet<void*> StreamTags;
-
- public:
- TImpl(const TGRpcClientConfig& config)
+
+ public:
+ TImpl(const TGRpcClientConfig& config)
: Channel(NGrpc::CreateChannelInterface(config))
, Stub(Channel)
- , MaxInFlight(config.MaxInFlight)
- {
- if (config.Timeout != TDuration::Max()) {
- Timeout = config.Timeout;
- }
+ , MaxInFlight(config.MaxInFlight)
+ {
+ if (config.Timeout != TDuration::Max()) {
+ Timeout = config.Timeout;
+ }
ISimpleThread::Start();
- }
-
- ~TImpl() {
- CQ.Shutdown();
- Join();
- }
-
+ }
+
+ ~TImpl() {
+ CQ.Shutdown();
+ Join();
+ }
+
grpc_connectivity_state GetNetworkStatus() const {
return Channel->GetState(false);
- }
-
- template<typename TRequest, typename TResponse>
- void Issue(const TRequest& request, TCallback<TResponse>&& callback,
- typename TRequestProcessor<TRequest, TResponse>::TAsyncRequest asyncRequest) {
- auto processor = MakeHolder<TRequestProcessor<TRequest, TResponse>>(this, asyncRequest, request,
- std::move(callback), Timeout);
- with_lock (Mutex) {
- if (!MaxInFlight || InFlight < MaxInFlight) {
- Start(std::move(processor));
- } else {
- PendingQ.push(std::move(processor));
- }
- }
- }
-
+ }
+
+ template<typename TRequest, typename TResponse>
+ void Issue(const TRequest& request, TCallback<TResponse>&& callback,
+ typename TRequestProcessor<TRequest, TResponse>::TAsyncRequest asyncRequest) {
+ auto processor = MakeHolder<TRequestProcessor<TRequest, TResponse>>(this, asyncRequest, request,
+ std::move(callback), Timeout);
+ with_lock (Mutex) {
+ if (!MaxInFlight || InFlight < MaxInFlight) {
+ Start(std::move(processor));
+ } else {
+ PendingQ.push(std::move(processor));
+ }
+ }
+ }
+
template<typename TRequest, typename TResponse>
void IssueStream(const TRequest& request,
TSimpleCallback<TResponse>&& processCb,
@@ -250,14 +250,14 @@ namespace NKikimr {
}
}
- void *ThreadProc() override {
- for (;;) {
- void *tag;
- bool ok = false;
+ void *ThreadProc() override {
+ for (;;) {
+ void *tag;
+ bool ok = false;
bool finished = true;
- if (!CQ.Next(&tag, &ok)) {
- break;
- }
+ if (!CQ.Next(&tag, &ok)) {
+ break;
+ }
if (IsStreamTag(tag)) {
THolder<IStreamRequestReadProcessor> processor(static_cast<IStreamRequestReadProcessor*>(tag));
if (ok) {
@@ -276,33 +276,33 @@ namespace NKikimr {
}
if (finished) {
- with_lock (Mutex) {
- --InFlight;
- while (PendingQ && InFlight < MaxInFlight) {
- Start(std::move(PendingQ.front()));
- PendingQ.pop();
- }
- }
- }
- }
- return nullptr;
- }
-
+ with_lock (Mutex) {
+ --InFlight;
+ while (PendingQ && InFlight < MaxInFlight) {
+ Start(std::move(PendingQ.front()));
+ PendingQ.pop();
+ }
+ }
+ }
+ }
+ return nullptr;
+ }
+
void Start(THolder<IProcessorBase> &&processor) {
- processor->Start();
+ processor->Start();
Y_UNUSED(processor.Release());
- ++InFlight;
- }
- };
-
- TGRpcClient::TGRpcClient(const TGRpcClientConfig& config)
+ ++InFlight;
+ }
+ };
+
+ TGRpcClient::TGRpcClient(const TGRpcClientConfig& config)
: Config(config)
, Impl(new TImpl(Config))
- {}
-
- TGRpcClient::~TGRpcClient()
- {}
-
+ {}
+
+ TGRpcClient::~TGRpcClient()
+ {}
+
const TGRpcClientConfig& TGRpcClient::GetConfig() const {
return Config;
}
@@ -311,42 +311,42 @@ namespace NKikimr {
return Impl->GetNetworkStatus();
}
-#define IMPL_REQUEST(NAME, REQUEST, RESPONSE) \
- void TGRpcClient::NAME(const NKikimrClient::REQUEST& request, TCallback<NKikimrClient::RESPONSE> callback) { \
- Impl->Issue(request, std::move(callback), &TImpl::TStub::Async ## NAME); \
- }
-
- IMPL_REQUEST(Request, TRequest, TResponse)
- IMPL_REQUEST(SchemeOperation, TSchemeOperation, TResponse)
- IMPL_REQUEST(SchemeOperationStatus, TSchemeOperationStatus, TResponse)
- IMPL_REQUEST(SchemeDescribe, TSchemeDescribe, TResponse)
- IMPL_REQUEST(PersQueueRequest, TPersQueueRequest, TResponse)
- IMPL_REQUEST(SchemeInitRoot, TSchemeInitRoot, TResponse)
- IMPL_REQUEST(BSAdm, TBSAdm, TResponse)
- IMPL_REQUEST(BlobStorageConfig, TBlobStorageConfigRequest, TResponse)
+#define IMPL_REQUEST(NAME, REQUEST, RESPONSE) \
+ void TGRpcClient::NAME(const NKikimrClient::REQUEST& request, TCallback<NKikimrClient::RESPONSE> callback) { \
+ Impl->Issue(request, std::move(callback), &TImpl::TStub::Async ## NAME); \
+ }
+
+ IMPL_REQUEST(Request, TRequest, TResponse)
+ IMPL_REQUEST(SchemeOperation, TSchemeOperation, TResponse)
+ IMPL_REQUEST(SchemeOperationStatus, TSchemeOperationStatus, TResponse)
+ IMPL_REQUEST(SchemeDescribe, TSchemeDescribe, TResponse)
+ IMPL_REQUEST(PersQueueRequest, TPersQueueRequest, TResponse)
+ IMPL_REQUEST(SchemeInitRoot, TSchemeInitRoot, TResponse)
+ IMPL_REQUEST(BSAdm, TBSAdm, TResponse)
+ IMPL_REQUEST(BlobStorageConfig, TBlobStorageConfigRequest, TResponse)
IMPL_REQUEST(ResolveNode, TResolveNodeRequest, TResponse)
- IMPL_REQUEST(HiveCreateTablet, THiveCreateTablet, TResponse)
- IMPL_REQUEST(LocalEnumerateTablets, TLocalEnumerateTablets, TResponse)
- IMPL_REQUEST(KeyValue, TKeyValueRequest, TResponse)
+ IMPL_REQUEST(HiveCreateTablet, THiveCreateTablet, TResponse)
+ IMPL_REQUEST(LocalEnumerateTablets, TLocalEnumerateTablets, TResponse)
+ IMPL_REQUEST(KeyValue, TKeyValueRequest, TResponse)
IMPL_REQUEST(RegisterNode, TNodeRegistrationRequest, TNodeRegistrationResponse)
IMPL_REQUEST(CmsRequest, TCmsRequest, TCmsResponse)
IMPL_REQUEST(SqsRequest, TSqsRequest, TSqsResponse)
IMPL_REQUEST(S3Listing, TS3ListingRequest, TS3ListingResponse)
- IMPL_REQUEST(LocalMKQL, TLocalMKQL, TResponse)
- IMPL_REQUEST(LocalSchemeTx, TLocalSchemeTx, TResponse)
- IMPL_REQUEST(TabletKillRequest, TTabletKillRequest, TResponse)
- IMPL_REQUEST(InterconnectDebug, TInterconnectDebug, TResponse)
- IMPL_REQUEST(TabletStateRequest, TTabletStateRequest, TResponse)
- IMPL_REQUEST(BlobStorageLoadRequest, TBsTestLoadRequest, TResponse)
- IMPL_REQUEST(BlobStorageGetRequest, TBsGetRequest, TResponse)
- IMPL_REQUEST(DbSchema, TJSON, TJSON)
- IMPL_REQUEST(DbOperation, TJSON, TJSON)
- IMPL_REQUEST(DbBatch, TJSON, TJSON)
+ IMPL_REQUEST(LocalMKQL, TLocalMKQL, TResponse)
+ IMPL_REQUEST(LocalSchemeTx, TLocalSchemeTx, TResponse)
+ IMPL_REQUEST(TabletKillRequest, TTabletKillRequest, TResponse)
+ IMPL_REQUEST(InterconnectDebug, TInterconnectDebug, TResponse)
+ IMPL_REQUEST(TabletStateRequest, TTabletStateRequest, TResponse)
+ IMPL_REQUEST(BlobStorageLoadRequest, TBsTestLoadRequest, TResponse)
+ IMPL_REQUEST(BlobStorageGetRequest, TBsGetRequest, TResponse)
+ IMPL_REQUEST(DbSchema, TJSON, TJSON)
+ IMPL_REQUEST(DbOperation, TJSON, TJSON)
+ IMPL_REQUEST(DbBatch, TJSON, TJSON)
IMPL_REQUEST(ChooseProxy, TChooseProxyRequest, TResponse)
IMPL_REQUEST(ConsoleRequest, TConsoleRequest, TConsoleResponse)
IMPL_REQUEST(WhoAmI, TWhoAmI, TResponse)
IMPL_REQUEST(FillNode, TFillNodeRequest, TResponse)
IMPL_REQUEST(DrainNode, TDrainNodeRequest, TResponse)
-
- } // NGRpcProxy
-} // NKikimr
+
+ } // NGRpcProxy
+} // NKikimr
diff --git a/ydb/public/lib/deprecated/client/grpc_client.h b/ydb/public/lib/deprecated/client/grpc_client.h
index b0483a2646f..6dbcd6738d8 100644
--- a/ydb/public/lib/deprecated/client/grpc_client.h
+++ b/ydb/public/lib/deprecated/client/grpc_client.h
@@ -1,81 +1,81 @@
-#pragma once
-
+#pragma once
+
#include <ydb/core/protos/grpc.pb.h>
-#include <util/datetime/base.h>
+#include <util/datetime/base.h>
#include <library/cpp/grpc/client/grpc_common.h>
-
-namespace NKikimr {
- namespace NGRpcProxy {
-
+
+namespace NKikimr {
+ namespace NGRpcProxy {
+
using TGRpcClientConfig = NGrpc::TGRpcClientConfig;
-
+
using TGrpcError = std::pair<TString, int>;
- template<typename T>
+ template<typename T>
using TSimpleCallback = std::function<void (const T&)>;
template<typename T>
using TCallback = std::function<void (const TGrpcError*, const T&)>;
-
- using TResponseCallback = TCallback<NKikimrClient::TResponse>;
- using TJSONCallback = TCallback<NKikimrClient::TJSON>;
+
+ using TResponseCallback = TCallback<NKikimrClient::TResponse>;
+ using TJSONCallback = TCallback<NKikimrClient::TJSON>;
using TNodeRegistrationResponseCallback = TCallback<NKikimrClient::TNodeRegistrationResponse>;
using TCmsResponseCallback = TCallback<NKikimrClient::TCmsResponse>;
using TSqsResponseCallback = TCallback<NKikimrClient::TSqsResponse>;
using TS3ListingResponseCallback = TCallback<NKikimrClient::TS3ListingResponse>;
using TConsoleResponseCallback = TCallback<NKikimrClient::TConsoleResponse>;
-
+
using TFinishCallback = std::function<void (const TGrpcError*)>;
- class TGRpcClient {
+ class TGRpcClient {
TGRpcClientConfig Config;
- class TImpl;
- THolder<TImpl> Impl;
-
- public:
- TGRpcClient(const TGRpcClientConfig& config);
- ~TGRpcClient();
+ class TImpl;
+ THolder<TImpl> Impl;
+
+ public:
+ TGRpcClient(const TGRpcClientConfig& config);
+ ~TGRpcClient();
const TGRpcClientConfig& GetConfig() const;
grpc_connectivity_state GetNetworkStatus() const;
-
- // MiniKQL request, TResponseCallback callback (const NKikimrClient::DML& request)
- void Request(const NKikimrClient::TRequest& request, TResponseCallback callback);
+
+ // MiniKQL request, TResponseCallback callback (const NKikimrClient::DML& request)
+ void Request(const NKikimrClient::TRequest& request, TResponseCallback callback);
// ChooseProxy request
void ChooseProxy(const NKikimrClient::TChooseProxyRequest& request, TResponseCallback callback);
-
+
// Stream request
void StreamRequest(const NKikimrClient::TRequest& request, TSimpleCallback<NKikimrClient::TResponse> process, TFinishCallback finish);
- // DML transactions
- void SchemeOperation(const NKikimrClient::TSchemeOperation& request, TResponseCallback callback);
- // status polling for scheme transactions
- void SchemeOperationStatus(const NKikimrClient::TSchemeOperationStatus& request, TResponseCallback callback);
- // describe
- void SchemeDescribe(const NKikimrClient::TSchemeDescribe& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // PERSISTENT QUEUE CLIENT INTERFACE
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void PersQueueRequest(const NKikimrClient::TPersQueueRequest& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // ADMIN INTERNAL INTERFACE
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void SchemeInitRoot(const NKikimrClient::TSchemeInitRoot& request, TResponseCallback callback);
- void BSAdm(const NKikimrClient::TBSAdm& request, TResponseCallback callback);
- void BlobStorageConfig(const NKikimrClient::TBlobStorageConfigRequest& request, TResponseCallback callback);
-
+ // DML transactions
+ void SchemeOperation(const NKikimrClient::TSchemeOperation& request, TResponseCallback callback);
+ // status polling for scheme transactions
+ void SchemeOperationStatus(const NKikimrClient::TSchemeOperationStatus& request, TResponseCallback callback);
+ // describe
+ void SchemeDescribe(const NKikimrClient::TSchemeDescribe& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // PERSISTENT QUEUE CLIENT INTERFACE
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void PersQueueRequest(const NKikimrClient::TPersQueueRequest& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // ADMIN INTERNAL INTERFACE
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void SchemeInitRoot(const NKikimrClient::TSchemeInitRoot& request, TResponseCallback callback);
+ void BSAdm(const NKikimrClient::TBSAdm& request, TResponseCallback callback);
+ void BlobStorageConfig(const NKikimrClient::TBlobStorageConfigRequest& request, TResponseCallback callback);
+
void ResolveNode(const NKikimrClient::TResolveNodeRequest& request, TResponseCallback callback);
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // KV-TABLET INTERNAL INTERFACE
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void HiveCreateTablet(const NKikimrClient::THiveCreateTablet& request, TResponseCallback callback);
- void LocalEnumerateTablets(const NKikimrClient::TLocalEnumerateTablets& request, TResponseCallback callback);
- void KeyValue(const NKikimrClient::TKeyValueRequest& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // KV-TABLET INTERNAL INTERFACE
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void HiveCreateTablet(const NKikimrClient::THiveCreateTablet& request, TResponseCallback callback);
+ void LocalEnumerateTablets(const NKikimrClient::TLocalEnumerateTablets& request, TResponseCallback callback);
+ void KeyValue(const NKikimrClient::TKeyValueRequest& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
// DYNAMIC NODES INTERNAL INTERFACE
/////////////////////////////////////////////////////////////////////////////////////////////////
void RegisterNode(const NKikimrClient::TNodeRegistrationRequest& request, TNodeRegistrationResponseCallback callback);
@@ -101,35 +101,35 @@ namespace NKikimr {
void ConsoleRequest(const NKikimrClient::TConsoleRequest& request, TConsoleResponseCallback callback);
/////////////////////////////////////////////////////////////////////////////////////////////////
- // INTROSPECTION
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void LocalMKQL(const NKikimrClient::TLocalMKQL& request, TResponseCallback callback);
- void LocalSchemeTx(const NKikimrClient::TLocalSchemeTx& request, TResponseCallback callback);
- void TabletKillRequest(const NKikimrClient::TTabletKillRequest& request, TResponseCallback callback);
- void InterconnectDebug(const NKikimrClient::TInterconnectDebug& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // MONITORING
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void TabletStateRequest(const NKikimrClient::TTabletStateRequest& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // BLOBSTORAGE LOAD TEST
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void BlobStorageLoadRequest(const NKikimrClient::TBsTestLoadRequest& request, TResponseCallback callback);
- void BlobStorageGetRequest(const NKikimrClient::TBsGetRequest& request, TResponseCallback callback);
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // HTTP INTERFACE
- /////////////////////////////////////////////////////////////////////////////////////////////////
- void DbSchema(const NKikimrClient::TJSON& request, TJSONCallback callback);
- void DbOperation(const NKikimrClient::TJSON& request, TJSONCallback callback);
- void DbBatch(const NKikimrClient::TJSON& request, TJSONCallback callback);
+ // INTROSPECTION
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void LocalMKQL(const NKikimrClient::TLocalMKQL& request, TResponseCallback callback);
+ void LocalSchemeTx(const NKikimrClient::TLocalSchemeTx& request, TResponseCallback callback);
+ void TabletKillRequest(const NKikimrClient::TTabletKillRequest& request, TResponseCallback callback);
+ void InterconnectDebug(const NKikimrClient::TInterconnectDebug& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // MONITORING
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void TabletStateRequest(const NKikimrClient::TTabletStateRequest& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // BLOBSTORAGE LOAD TEST
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void BlobStorageLoadRequest(const NKikimrClient::TBsTestLoadRequest& request, TResponseCallback callback);
+ void BlobStorageGetRequest(const NKikimrClient::TBsGetRequest& request, TResponseCallback callback);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // HTTP INTERFACE
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ void DbSchema(const NKikimrClient::TJSON& request, TJSONCallback callback);
+ void DbOperation(const NKikimrClient::TJSON& request, TJSONCallback callback);
+ void DbBatch(const NKikimrClient::TJSON& request, TJSONCallback callback);
void WhoAmI(const NKikimrClient::TWhoAmI& request, TResponseCallback callback);
void FillNode(const NKikimrClient::TFillNodeRequest& request, TResponseCallback callback);
void DrainNode(const NKikimrClient::TDrainNodeRequest& request, TResponseCallback callback);
- };
-
- } // NGRpcProxy
-} // NKikimr
+ };
+
+ } // NGRpcProxy
+} // NKikimr
diff --git a/ydb/public/lib/deprecated/client/msgbus_client.cpp b/ydb/public/lib/deprecated/client/msgbus_client.cpp
index 4d5f2427ebd..03098e27633 100644
--- a/ydb/public/lib/deprecated/client/msgbus_client.cpp
+++ b/ydb/public/lib/deprecated/client/msgbus_client.cpp
@@ -204,7 +204,7 @@ const TMsgBusClientConfig& TMsgBusClient::GetConfig() {
return Config;
}
-EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *record) {
+EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *record) {
if (!record)
return EDataReqStatusExcerpt::Unknown;
diff --git a/ydb/public/lib/deprecated/client/msgbus_client.h b/ydb/public/lib/deprecated/client/msgbus_client.h
index 7d721946d8d..483ac72219d 100644
--- a/ydb/public/lib/deprecated/client/msgbus_client.h
+++ b/ydb/public/lib/deprecated/client/msgbus_client.h
@@ -40,7 +40,7 @@ public:
const TMsgBusClientConfig& GetConfig();
};
-EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *response);
+EDataReqStatusExcerpt ExtractDataRequestStatus(const NKikimrClient::TResponse *response);
} // NMsgBusProxy
diff --git a/ydb/public/lib/deprecated/kicli/dynamic_node.cpp b/ydb/public/lib/deprecated/kicli/dynamic_node.cpp
index f5095a622c4..7bf8dceca16 100644
--- a/ydb/public/lib/deprecated/kicli/dynamic_node.cpp
+++ b/ydb/public/lib/deprecated/kicli/dynamic_node.cpp
@@ -33,15 +33,15 @@ ui32 TRegistrationResult::GetNodeId() const
return Record().GetNodeId();
}
-NActors::TScopeId TRegistrationResult::GetScopeId() const
-{
- const auto& record = Record();
- if (record.HasScopeTabletId() && record.HasScopePathId()) {
- return {record.GetScopeTabletId(), record.GetScopePathId()};
- }
- return {};
-}
-
+NActors::TScopeId TRegistrationResult::GetScopeId() const
+{
+ const auto& record = Record();
+ if (record.HasScopeTabletId() && record.HasScopePathId()) {
+ return {record.GetScopeTabletId(), record.GetScopePathId()};
+ }
+ return {};
+}
+
TNodeRegistrant::TNodeRegistrant(TKikimr& kikimr)
: Kikimr(&kikimr)
{
@@ -53,11 +53,11 @@ TNodeRegistrant::SyncRegisterNode(const TString& domainPath,
ui16 port,
const TString& address,
const TString& resolveHost,
- const NActors::TNodeLocation& location,
- bool fixedNodeId,
- TMaybe<TString> path) const
+ const NActors::TNodeLocation& location,
+ bool fixedNodeId,
+ TMaybe<TString> path) const
{
- auto future = Kikimr->RegisterNode(domainPath, host, port, address, resolveHost, location, fixedNodeId, path);
+ auto future = Kikimr->RegisterNode(domainPath, host, port, address, resolveHost, location, fixedNodeId, path);
auto result = future.GetValue(TDuration::Max());
return TRegistrationResult(result);
}
diff --git a/ydb/public/lib/deprecated/kicli/error.cpp b/ydb/public/lib/deprecated/kicli/error.cpp
index 473a981f607..49d1161c3cf 100644
--- a/ydb/public/lib/deprecated/kicli/error.cpp
+++ b/ydb/public/lib/deprecated/kicli/error.cpp
@@ -288,7 +288,7 @@ TError::TError(const TResult& result)
Message = result.TransportErrorMessage;
} else {
if (result.Reply->GetHeader()->Type == NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
- const NKikimrClient::TResponse& response = result.GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& response = result.GetResult<NKikimrClient::TResponse>();
if (response.HasExecutionEngineStatus()
&& response.GetExecutionEngineStatus() != NKikimrMiniKQLEngine::Ok
&& response.GetExecutionEngineStatus() != NKikimrMiniKQLEngine::Unknown) {
diff --git a/ydb/public/lib/deprecated/kicli/kicli.h b/ydb/public/lib/deprecated/kicli/kicli.h
index 9dc472d2314..4df2352e8a3 100644
--- a/ydb/public/lib/deprecated/kicli/kicli.h
+++ b/ydb/public/lib/deprecated/kicli/kicli.h
@@ -336,10 +336,10 @@ public:
return *static_cast<T*>(Reply.Get());
}
- NBus::EMessageStatus GetTransportStatus() const {
- return TransportStatus;
- }
-
+ NBus::EMessageStatus GetTransportStatus() const {
+ return TransportStatus;
+ }
+
protected:
TResult(NBus::EMessageStatus transportStatus);
TResult(NBus::EMessageStatus transportStatus, const TString& message);
@@ -628,7 +628,7 @@ public:
TString GetErrorMessage() const;
ui32 GetNodeId() const;
- NActors::TScopeId GetScopeId() const;
+ NActors::TScopeId GetScopeId() const;
const NKikimrClient::TNodeRegistrationResponse& Record() const;
@@ -641,8 +641,8 @@ class TNodeRegistrant {
public:
TRegistrationResult SyncRegisterNode(const TString& domainPath, const TString& host, ui16 port,
const TString& address, const TString& resolveHost,
- const NActors::TNodeLocation& location,
- bool fixedNodeId = false, TMaybe<TString> path = {}) const;
+ const NActors::TNodeLocation& location,
+ bool fixedNodeId = false, TMaybe<TString> path = {}) const;
private:
TNodeRegistrant(TKikimr& kikimr);
@@ -775,9 +775,9 @@ public:
return ExecuteRequest(TAutoPtr<NBus::TBusMessage>(request));
}
- // execute general message bus request
- NThreading::TFuture<TResult> ExecuteRequest(TAutoPtr<NBus::TBusMessage> request);
-
+ // execute general message bus request
+ NThreading::TFuture<TResult> ExecuteRequest(TAutoPtr<NBus::TBusMessage> request);
+
protected:
NThreading::TFuture<TQueryResult> ExecuteQuery(const TTextQuery& query, const NKikimrMiniKQL::TParams& parameters);
NThreading::TFuture<TQueryResult> ExecuteQuery(const TTextQuery& query, const TString& parameters);
@@ -792,8 +792,8 @@ protected:
NBus::EMessageStatus ExecuteRequestInternal(NThreading::TPromise<TResult> promise, TAutoPtr<NBus::TBusMessage> request);
NThreading::TFuture<TResult> RegisterNode(const TString& domainPath, const TString& host, ui16 port,
const TString& address, const TString& resolveHost,
- const NActors::TNodeLocation& location,
- bool fixedNodeId, TMaybe<TString> path);
+ const NActors::TNodeLocation& location,
+ bool fixedNodeId, TMaybe<TString> path);
NThreading::TFuture<TResult> GetNodeConfig(ui32 nodeId,
const TString &host,
const TString &tenant,
diff --git a/ydb/public/lib/deprecated/kicli/kikimr.cpp b/ydb/public/lib/deprecated/kicli/kikimr.cpp
index 4156d72d4b3..6c0bd7c6d39 100644
--- a/ydb/public/lib/deprecated/kicli/kikimr.cpp
+++ b/ydb/public/lib/deprecated/kicli/kikimr.cpp
@@ -43,7 +43,7 @@ protected:
, Promise(promise)
, Request(request)
{}
-
+
bool operator <(const TQueueItem& other) const {
return Time > other.Time;
}
@@ -279,8 +279,8 @@ public:
return ExecuteGRpcRequest<NMsgBusProxy::TBusSqsRequest, NMsgBusProxy::TBusSqsResponse>(&NGRpcProxy::TGRpcClient::SqsRequest, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_S3_LISTING_REQUEST:
return ExecuteGRpcRequest<NMsgBusProxy::TBusS3ListingRequest, NMsgBusProxy::TBusS3ListingResponse>(&NGRpcProxy::TGRpcClient::S3Listing, promise, request);
- case NMsgBusProxy::MTYPE_CLIENT_INTERCONNECT_DEBUG:
- return ExecuteGRpcRequest<NMsgBusProxy::TBusInterconnectDebug>(&NGRpcProxy::TGRpcClient::InterconnectDebug, promise, request);
+ case NMsgBusProxy::MTYPE_CLIENT_INTERCONNECT_DEBUG:
+ return ExecuteGRpcRequest<NMsgBusProxy::TBusInterconnectDebug>(&NGRpcProxy::TGRpcClient::InterconnectDebug, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_CONSOLE_REQUEST:
return ExecuteGRpcRequest<NMsgBusProxy::TBusConsoleRequest, NMsgBusProxy::TBusConsoleResponse>(&NGRpcProxy::TGRpcClient::ConsoleRequest, promise, request);
case NMsgBusProxy::MTYPE_CLIENT_WHOAMI:
@@ -401,17 +401,17 @@ void TKikimr::TRetryQueue::QueueRequest(NThreading::TPromise<TResult> promise, T
TKikimr::TKikimr(const NMsgBusProxy::TMsgBusClientConfig& clientConfig, const TConnectionPolicy& policy)
: Impl(new TMsgBusImpl(clientConfig, policy))
{}
-
+
TKikimr::TKikimr(const NGRpcProxy::TGRpcClientConfig& clientConfig, const TConnectionPolicy& policy)
: Impl(new TGRpcImpl(clientConfig, policy))
{}
-
+
TString TKikimr::GetCurrentLocation() const {
return Impl->GetCurrentLocation();
}
TKikimr::~TKikimr() = default;
-
+
TTextQuery TKikimr::Query(const TString& program) {
return TTextQuery(*this, program);
}
@@ -500,7 +500,7 @@ NThreading::TFuture<TPrepareResult> TKikimr::PrepareQuery(const TTextQuery& quer
}
NThreading::TFuture<TResult> TKikimr::DescribeObject(const TSchemaObject& object) {
- TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
+ TAutoPtr<NMsgBusProxy::TBusSchemeDescribe> request(new NMsgBusProxy::TBusSchemeDescribe());
request->Record.SetPath(object.GetPath());
return ExecuteRequest(request.Release());
}
@@ -513,7 +513,7 @@ NThreading::TFuture<TResult> TKikimr::ModifySchema(const TModifyScheme& schema)
}
NThreading::TFuture<TResult> TKikimr::MakeDirectory(const TSchemaObject& object, const TString& name) {
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
modifyScheme->SetWorkingDir(object.GetPath());
@@ -526,7 +526,7 @@ NThreading::TFuture<TResult> TKikimr::MakeDirectory(const TSchemaObject& object,
NThreading::TFuture<TResult> TKikimr::CreateTable(TSchemaObject& object, const TString& name, const TVector<TColumn>& columns,
const TTablePartitionConfig* partitionConfig)
{
- TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
+ TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
request->Record.MutablePollOptions()->SetTimeout(POLLING_TIMEOUT);
auto* modifyScheme = request->Record.MutableTransaction()->MutableModifyScheme();
modifyScheme->SetWorkingDir(object.GetPath());
@@ -576,21 +576,21 @@ TNodeConfigurator TKikimr::GetNodeConfigurator()
NThreading::TFuture<TResult> TKikimr::RegisterNode(const TString& domainPath, const TString& host, ui16 port,
const TString& address, const TString& resolveHost,
- const NActors::TNodeLocation& location,
- bool fixedNodeId, TMaybe<TString> path)
+ const NActors::TNodeLocation& location,
+ bool fixedNodeId, TMaybe<TString> path)
{
TAutoPtr<NMsgBusProxy::TBusNodeRegistrationRequest> request = new NMsgBusProxy::TBusNodeRegistrationRequest;
request->Record.SetHost(host);
request->Record.SetPort(port);
request->Record.SetAddress(address);
request->Record.SetResolveHost(resolveHost);
- location.Serialize(request->Record.MutableLocation());
- location.GetLegacyValue().Serialize(request->Record.MutableLocation());
+ location.Serialize(request->Record.MutableLocation());
+ location.GetLegacyValue().Serialize(request->Record.MutableLocation());
request->Record.SetDomainPath(domainPath);
request->Record.SetFixedNodeId(fixedNodeId);
- if (path) {
- request->Record.SetPath(*path);
- }
+ if (path) {
+ request->Record.SetPath(*path);
+ }
return ExecuteRequest(request.Release());
}
diff --git a/ydb/public/lib/deprecated/kicli/result.cpp b/ydb/public/lib/deprecated/kicli/result.cpp
index 0f86ba4340a..771fd627e31 100644
--- a/ydb/public/lib/deprecated/kicli/result.cpp
+++ b/ydb/public/lib/deprecated/kicli/result.cpp
@@ -26,16 +26,16 @@ ui16 TResult::GetType() const {
return Reply == nullptr ? 0 : Reply.Get()->GetHeader()->Type;
}
-template <> const NKikimrClient::TResponse& TResult::GetResult<NKikimrClient::TResponse>() const {
+template <> const NKikimrClient::TResponse& TResult::GetResult<NKikimrClient::TResponse>() const {
Y_VERIFY(GetType() == NMsgBusProxy::MTYPE_CLIENT_RESPONSE, "Unexpected response type: %d", GetType());
return static_cast<NMsgBusProxy::TBusResponse*>(Reply.Get())->Record;
}
-template <> const NKikimrClient::TBsTestLoadResponse& TResult::GetResult<NKikimrClient::TBsTestLoadResponse>() const {
- Y_VERIFY(GetType() == NMsgBusProxy::MTYPE_CLIENT_LOAD_RESPONSE, "Unexpected response type: %d", GetType());
- return static_cast<NMsgBusProxy::TBusBsTestLoadResponse*>(Reply.Get())->Record;
-}
-
+template <> const NKikimrClient::TBsTestLoadResponse& TResult::GetResult<NKikimrClient::TBsTestLoadResponse>() const {
+ Y_VERIFY(GetType() == NMsgBusProxy::MTYPE_CLIENT_LOAD_RESPONSE, "Unexpected response type: %d", GetType());
+ return static_cast<NMsgBusProxy::TBusBsTestLoadResponse*>(Reply.Get())->Record;
+}
+
NMsgBusProxy::EResponseStatus TResult::GetStatus() const {
if (TransportStatus != NBus::MESSAGE_OK) {
switch (TransportStatus) {
@@ -65,7 +65,7 @@ NMsgBusProxy::EResponseStatus TResult::GetStatus() const {
};
} else
if (GetType() == NMsgBusProxy::MTYPE_CLIENT_RESPONSE) {
- return static_cast<NMsgBusProxy::EResponseStatus>(GetResult<NKikimrClient::TResponse>().GetStatus());
+ return static_cast<NMsgBusProxy::EResponseStatus>(GetResult<NKikimrClient::TResponse>().GetStatus());
} else
return NMsgBusProxy::MSTATUS_INTERNALERROR;
}
@@ -79,7 +79,7 @@ TQueryResult::TQueryResult(const TResult& result)
{}
TValue TQueryResult::GetValue() const {
- const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
Y_VERIFY(response.HasExecutionEngineEvaluatedResponse());
const auto& result = response.GetExecutionEngineEvaluatedResponse();
// TODO: type caching
@@ -287,7 +287,7 @@ TPrepareResult::TPrepareResult(const TResult& result, const TQuery& query)
{}
TPreparedQuery TPrepareResult::GetQuery() const {
- const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& response = GetResult<NKikimrClient::TResponse>();
Y_VERIFY(response.HasMiniKQLCompileResults());
const auto& compileResult = response.GetMiniKQLCompileResults();
Y_VERIFY(compileResult.HasCompiledProgram(), "Compile error (%" PRIu64 "): %" PRIu32 ":%" PRIu32 " %s",
diff --git a/ydb/public/lib/deprecated/kicli/schema.cpp b/ydb/public/lib/deprecated/kicli/schema.cpp
index d1ee0384f8b..8690d426046 100644
--- a/ydb/public/lib/deprecated/kicli/schema.cpp
+++ b/ydb/public/lib/deprecated/kicli/schema.cpp
@@ -215,7 +215,7 @@ TVector<TSchemaObject> TSchemaObject::GetChildren() const {
NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
TResult result = future.GetValue(TDuration::Max());
result.GetError().Throw();
- const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
TVector<TSchemaObject> children;
children.reserve(objects.GetPathDescription().ChildrenSize());
for (const auto& child : objects.GetPathDescription().GetChildren()) {
@@ -228,7 +228,7 @@ TVector<TColumn> TSchemaObject::GetColumns() const {
NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
TResult result = future.GetValue(TDuration::Max());
result.GetError().Throw();
- const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
Y_VERIFY(objects.GetPathDescription().HasTable());
const auto& table = objects.GetPathDescription().GetTable();
@@ -257,7 +257,7 @@ TSchemaObjectStats TSchemaObject::GetStats() const {
NThreading::TFuture<TResult> future = Kikimr.DescribeObject(*this);
TResult result = future.GetValue(TDuration::Max());
result.GetError().Throw();
- const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
+ const NKikimrClient::TResponse& objects = result.GetResult<NKikimrClient::TResponse>();
Y_VERIFY(objects.GetPathDescription().HasTable());
TSchemaObjectStats stats;
stats.PartitionsCount = objects.GetPathDescription().TablePartitionsSize();
diff --git a/ydb/public/lib/deprecated/kicli/ya.make b/ydb/public/lib/deprecated/kicli/ya.make
index d9aa54bc4cd..4e3353a7d85 100644
--- a/ydb/public/lib/deprecated/kicli/ya.make
+++ b/ydb/public/lib/deprecated/kicli/ya.make
@@ -21,7 +21,7 @@ SRCS(
PEERDIR(
contrib/libs/grpc
- library/cpp/actors/core
+ library/cpp/actors/core
library/cpp/threading/future
ydb/core/protos
ydb/library/aclib
diff --git a/ydb/services/kesus/grpc_service.cpp b/ydb/services/kesus/grpc_service.cpp
index c5826b66274..e21b97bf00d 100644
--- a/ydb/services/kesus/grpc_service.cpp
+++ b/ydb/services/kesus/grpc_service.cpp
@@ -41,8 +41,8 @@ public:
, Context(RequestEvent->GetStreamCtx())
{ }
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
- return NKikimrServices::TActivity::KESUS_REQ;
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::KESUS_REQ;
}
void Bootstrap(const TActorContext& ctx) {
diff --git a/ydb/services/persqueue_v1/grpc_pq_actor.h b/ydb/services/persqueue_v1/grpc_pq_actor.h
index 65c8aca1db2..94e2c7f29b0 100644
--- a/ydb/services/persqueue_v1/grpc_pq_actor.h
+++ b/ydb/services/persqueue_v1/grpc_pq_actor.h
@@ -468,7 +468,7 @@ public:
void Die(const NActors::TActorContext& ctx) override;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_WRITE; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_WRITE; }
private:
STFUNC(StateFunc) {
switch (ev->GetTypeRewrite()) {
@@ -752,7 +752,7 @@ public:
void Die(const NActors::TActorContext& ctx) override;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_READ; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_READ; }
struct TTopicCounters {
@@ -1082,7 +1082,7 @@ public:
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::PQ_META_REQUEST_PROCESSOR; }
bool HasCancelOperation() {
return false;
diff --git a/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp b/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
index 654edfcfcd4..2295a6133d6 100644
--- a/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
+++ b/ydb/services/persqueue_v1/grpc_pq_read_actor.cpp
@@ -114,7 +114,7 @@ public:
void Die(const NActors::TActorContext& ctx) override;
- static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_PARTITION; }
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FRONT_PQ_PARTITION; }
private:
STFUNC(StateFunc) {
switch (ev->GetTypeRewrite()) {
diff --git a/ydb/services/ydb/ydb_operation.cpp b/ydb/services/ydb/ydb_operation.cpp
index 602980027cb..087ec4b0314 100644
--- a/ydb/services/ydb/ydb_operation.cpp
+++ b/ydb/services/ydb/ydb_operation.cpp
@@ -32,7 +32,7 @@ void TGRpcOperationService::DecRequest() {
}
void TGRpcOperationService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
- auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
+ auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
#ifdef ADD_REQUEST
#error ADD_REQUEST macro already defined
#endif
diff --git a/ydb/services/ydb/ydb_scheme.cpp b/ydb/services/ydb/ydb_scheme.cpp
index ac339f54ab2..7cfdeba9861 100644
--- a/ydb/services/ydb/ydb_scheme.cpp
+++ b/ydb/services/ydb/ydb_scheme.cpp
@@ -33,7 +33,7 @@ void TGRpcYdbSchemeService::DecRequest() {
}
void TGRpcYdbSchemeService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
- auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
+ auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
#ifdef ADD_REQUEST
#error ADD_REQUEST macro already defined
diff --git a/ydb/services/ydb/ydb_table.cpp b/ydb/services/ydb/ydb_table.cpp
index 7189614b8e8..b001e6bd4a4 100644
--- a/ydb/services/ydb/ydb_table.cpp
+++ b/ydb/services/ydb/ydb_table.cpp
@@ -32,7 +32,7 @@ void TGRpcYdbTableService::DecRequest() {
}
void TGRpcYdbTableService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) {
- auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
+ auto getCounterBlock = CreateCounterCb(Counters_, ActorSystem_);
#ifdef ADD_REQUEST
#error ADD_REQUEST macro already defined
#endif
diff --git a/ydb/tests/library/common/protobuf.py b/ydb/tests/library/common/protobuf.py
index 9dc40653fa3..6f7835f27da 100644
--- a/ydb/tests/library/common/protobuf.py
+++ b/ydb/tests/library/common/protobuf.py
@@ -222,7 +222,7 @@ class TKeyValuePair(namedtuple('TKeyValuePair', ['key', 'value', 'size', 'creati
TCmdRename = namedtuple('TCmdRename', ['old_key', 'new_key'])
-class TSchemeDescribe(AbstractProtobufBuilder):
+class TSchemeDescribe(AbstractProtobufBuilder):
def __init__(self, path):
- super(TSchemeDescribe, self).__init__(msgbus.TSchemeDescribe())
+ super(TSchemeDescribe, self).__init__(msgbus.TSchemeDescribe())
self.protobuf.Path = path
diff --git a/ydb/tests/library/common/types.py b/ydb/tests/library/common/types.py
index 5ec564d65fa..4bbe51f8ec1 100644
--- a/ydb/tests/library/common/types.py
+++ b/ydb/tests/library/common/types.py
@@ -65,7 +65,7 @@ class Erasure(Enum):
STRIPE_3_2 = _erasure_type(id_=7, min_fail_domains=7, min_alive_replicas=5)
MIRROR_3_2 = _erasure_type(id_=8, min_fail_domains=5, min_alive_replicas=3)
MIRROR_3_DC = _erasure_type(id_=9, min_fail_domains=3, min_alive_replicas=3)
- MIRROR_3OF4 = _erasure_type(id_=18, min_fail_domains=8, min_alive_replicas=6)
+ MIRROR_3OF4 = _erasure_type(id_=18, min_fail_domains=8, min_alive_replicas=6)
def __init__(self, id_, min_fail_domains, min_alive_replicas):
self.__id = id_
diff --git a/ydb/tests/library/harness/kikimr_client.py b/ydb/tests/library/harness/kikimr_client.py
index d74383ae231..01b05f8a840 100644
--- a/ydb/tests/library/harness/kikimr_client.py
+++ b/ydb/tests/library/harness/kikimr_client.py
@@ -122,11 +122,11 @@ class KiKiMRMessageBusClient(object):
command.UpdateDriveStatus.Status = status
return self.send(request, 'BlobStorageConfig')
- def send_request(self, protobuf_request, method=None):
+ def send_request(self, protobuf_request, method=None):
return self.send(protobuf_request, method)
def send_and_poll_request(self, protobuf_request, method='SchemeOperation'):
- response = self.send_request(protobuf_request, method)
+ response = self.send_request(protobuf_request, method)
return self.__poll(response)
def __poll(self, flat_transaction_response):
@@ -134,11 +134,11 @@ class KiKiMRMessageBusClient(object):
return flat_transaction_response
return self.send_request(
- TSchemeOperationStatus(
+ TSchemeOperationStatus(
flat_transaction_response.FlatTxId.TxId,
flat_transaction_response.FlatTxId.SchemeShardTabletId
- ).protobuf,
- 'SchemeOperationStatus'
+ ).protobuf,
+ 'SchemeOperationStatus'
)
def bind_storage_pools(self, domain_name, spools):